Page Menu
Home
Sealhub
Search
Configure Global Search
Log In
Files
F10361466
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
26 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/src/component-arguments/component-argument.ts b/src/component-arguments/component-argument.ts
index a690992..e2f60fa 100644
--- a/src/component-arguments/component-argument.ts
+++ b/src/component-arguments/component-argument.ts
@@ -1,93 +1,100 @@
-import { JDDContext, Table, TableData } from "../index.js";
+import { JDDContext, Structured, Table, TableData } from "../index.js";
import { List } from "./list.js";
export type ExtractStructuredComponentArgumentsParsed<C> = {
[property in keyof C]: ExtractParsed<C[property]>;
};
export type ExtractStructuredComponentArgumentsStorage<C> = {
[property in keyof C]: ExtractStorage<C[property]>;
};
export type ExtractStructuredComponentArgumentsReceived<C> = {
[property in keyof C]: ExtractReceived<C[property]>;
};
-export type ExtractParsed<C> = C extends List<infer T>
+// eslint-disable-next-line @typescript-eslint/no-explicit-any
+export type ExtractParsed<C> = C extends List<infer T, any>
? T[]
+ : C extends Structured<infer TT3>
+ ? {
+ [property in keyof TT3]: ExtractParsed<TT3[property]>;
+ }
: // eslint-disable-next-line @typescript-eslint/no-explicit-any
C extends ComponentArgument<infer T2, any, any>
? T2
: C extends Table<infer TT1, infer TT2>
? TableData<TT1, TT2>
: never;
export type ExtractStorage<C> = C extends ComponentArgument<infer _, infer T>
? T
: never;
export type ExtractReceived<C> = C extends ComponentArgument<
infer _,
infer __,
infer T
>
? T
: never;
export abstract class ComponentArgument<
ParsedType,
StorageType = ParsedType,
ReceivedDataType = StorageType
> {
public example_values: ParsedType[] = [];
public parent_argument: ComponentArgument<unknown> | null = null;
abstract getTypeName(): string;
abstract getEmptyValue(): ParsedType;
abstract countWords(value: ParsedType): number;
+
+ // returns the component argument instance, the remaining path elements, and the values for that component argument
abstract getSubArgument(
- key: string,
+ path: string[],
value: ParsedType
- ): ComponentArgument<unknown> | null;
+ ): readonly [ComponentArgument<unknown> | null, string[], unknown];
// Received - what we get on the server side when receiveing the request
// Parsed - the useful form of the value, ready for processing
// Storage - how it's represented when storing in a JSON form
// Formdata - how it's represented when it needs to be sent to the server
abstract receivedToParsed(
context: JDDContext,
value: ReceivedDataType
): Promise<ParsedType | ParsedType[]>;
abstract parsedToStorage(
context: JDDContext,
value: ParsedType
): Promise<StorageType>;
abstract storageToParsed(
context: JDDContext,
value: StorageType
): Promise<ParsedType>;
getExampleValue(_context: JDDContext): Promise<ParsedType> | ParsedType {
return this.example_values[
Math.floor(this.example_values.length * Math.random())
];
}
setExampleValues(values: ParsedType[]): this {
this.example_values = values;
return this;
}
hasParent(type: string) {
let parent = this.parent_argument;
while (parent) {
if (parent.getTypeName() == type) {
return true;
}
parent = parent.parent_argument;
}
return false;
}
}
diff --git a/src/component-arguments/file.ts b/src/component-arguments/file.ts
index 1555cc9..bb694f3 100644
--- a/src/component-arguments/file.ts
+++ b/src/component-arguments/file.ts
@@ -1,81 +1,81 @@
import { JDDContext } from "../index.js";
import { ComponentArgument } from "./component-argument.js";
import { FilePointer } from "@sealcode/file-manager";
type FileReceivedType = {
old: FilePointer | null;
new: FilePointer[] | FilePointer | null;
};
type FileFormDataType = {
old: string | null;
new?: unknown; // the browser will take care of setting a value to thag attribute via html input, we don't need to model this
};
export class File extends ComponentArgument<
FilePointer | null,
string | null,
FileReceivedType
> {
constructor() {
super();
}
getTypeName() {
return "file";
}
getEmptyValue() {
return null;
}
getSubArgument() {
- return null;
+ return <const>[null, [] as string[], null];
}
async getExampleValue(_context: JDDContext): Promise<FilePointer | null> {
return null;
}
countWords(): number {
return 0;
}
async receivedToParsed(_context: JDDContext, value: FileReceivedType) {
if (value.new && Array.isArray(value.new)) {
if (value.new.length == 0) {
return value.old || null;
} else if (value.new.length == 1) {
await value.new[0].save(true);
return value.new[0];
} else {
await Promise.all(value.new.map((f) => f.save(true)));
return value.new;
}
} else {
return value.old || null;
}
}
async parsedToStorage(_context: JDDContext, value: FilePointer | null) {
if (!value) {
return null;
}
await value.save(true);
return value.token;
}
async storageToParsed(
context: JDDContext,
value: string | null
): Promise<FilePointer | null> {
return value ? context.file_manager.fromToken(value) : null;
}
async parsedToFormData(
_context: JDDContext,
value: FilePointer | null
): Promise<FileFormDataType> {
return { old: value?.token || null };
}
}
diff --git a/src/component-arguments/list.ts b/src/component-arguments/list.ts
index 5ed4382..96d41a7 100644
--- a/src/component-arguments/list.ts
+++ b/src/component-arguments/list.ts
@@ -1,90 +1,96 @@
import { is, predicates } from "@sealcode/ts-predicates";
import { MaybePromise } from "../utils/util-types.js";
import { ComponentArgument } from "./component-argument.js";
import { ContainerArgument } from "./container-argument.js";
import { JDDContext } from "../jdd-context.js";
-export class List<T> extends ContainerArgument<T[], unknown, unknown> {
+export class List<
+ ParsedType,
+ T extends ComponentArgument<ParsedType, unknown, unknown>
+> extends ContainerArgument<ParsedType[], unknown, unknown> {
constructor(
- public item_type: ComponentArgument<T, unknown, unknown>,
+ public item_type: ComponentArgument<ParsedType, unknown, unknown>,
public example_count: number | null = null
) {
super();
item_type.parent_argument = this;
}
getTypeName() {
return "list";
}
getEmptyValue() {
return [];
}
- getSubArgument(key: string) {
- if (isNaN(parseInt(key))) {
- return null;
+ getSubArgument([key, ...rest]: string[], value: unknown[]) {
+ const parsed_key = parseInt(key);
+ if (isNaN(parsed_key)) {
+ return <const>[null, [] as string[], null];
}
- return this.item_type;
+ return <const>[this.item_type, rest, value[parsed_key]];
}
getExampleCount() {
if (this.example_count === null) {
return Math.floor(Math.random() * 5);
} else {
return this.example_count;
}
}
- async getExampleValue(context: JDDContext): Promise<T[]> {
+ async getExampleValue(context: JDDContext): Promise<ParsedType[]> {
if (this.example_values.length) {
return super.getExampleValue(context);
} else {
const count = this.getExampleCount();
- const result = [] as Array<MaybePromise<T>>;
+ const result = [] as Array<MaybePromise<ParsedType>>;
for (let i = 0; i < count; i++) {
result.push(
- this.item_type.getExampleValue(context) as Promise<T>
+ this.item_type.getExampleValue(
+ context
+ ) as Promise<ParsedType>
);
}
return await Promise.all(result);
}
}
- countWords(value: Array<T>): number {
+ countWords(value: Array<ParsedType>): number {
return value.reduce(
(acc, item) => acc + this.item_type.countWords(item),
0
);
}
async processAllSubarguments(
_context: JDDContext,
values: unknown,
processing_function: (
argument: ComponentArgument<unknown>,
value: unknown
) => Promise<unknown>
): Promise<T[] | null> {
if (
!is(values, predicates.array(predicates.object)) &&
!is(values, predicates.object)
) {
throw new Error(`Not a list or object: ${values as string}`);
}
const values_array = Array.isArray(values)
? values
: Object.values(values);
let array_result = (await Promise.all(
values_array.map(async (value) => {
const result = await processing_function(this.item_type, value);
return result;
})
)) as Array<T | T[] | null>;
if (this.item_type.getTypeName() != "list") {
array_result = array_result.flat() as T[];
}
const result = array_result.filter((e) => e !== null) as T[];
return result;
}
}
diff --git a/src/component-arguments/string-based-argument.ts b/src/component-arguments/string-based-argument.ts
index 29f4c8c..385bf98 100644
--- a/src/component-arguments/string-based-argument.ts
+++ b/src/component-arguments/string-based-argument.ts
@@ -1,26 +1,26 @@
import { JDDContext } from "../jdd-context.js";
import { ComponentArgument } from "./component-argument.js";
export abstract class StringBasedArgument<
T extends string
> extends ComponentArgument<T> {
async receivedToParsed(_: JDDContext, value: T) {
return value;
}
async parsedToStorage(_: JDDContext, value: T) {
return value;
}
async storageToParsed(_: JDDContext, value: T) {
return value;
}
async parsedToFormData(_: JDDContext, value: T) {
return value;
}
getSubArgument() {
- return null;
+ return <const>[null, [] as string[], null];
}
}
diff --git a/src/component-arguments/structured.test.ts b/src/component-arguments/structured.test.ts
index 3c76294..b4e1122 100644
--- a/src/component-arguments/structured.test.ts
+++ b/src/component-arguments/structured.test.ts
@@ -1,36 +1,37 @@
import { ExtractParsed } from "./component-argument.js";
import { List } from "./list.js";
import { ShortText } from "./short-text.js";
import { Structured } from "./structured.js";
describe("structured argument", () => {
it("properly extracts parsed type", () => {
const args = new Structured({
value: new ShortText().setExampleValues([""]),
tags: new List(new ShortText()).setExampleValues([["okazja"]]),
});
const values = {
value: "test",
tags: ["tag1", "tag2"],
} as ExtractParsed<typeof args>;
+
values.tags.map((tag) => tag.padStart(10)); // if the types are OK, this will typecheck OK
});
it("properly extracts parsed type within a list", () => {
const arg = new List(
new Structured({
value: new ShortText().setExampleValues([""]),
tags: new List(new ShortText()).setExampleValues([["okazja"]]),
})
);
const values = [
{
value: "test",
tags: ["tag1", "tag2"],
},
] as ExtractParsed<typeof arg>;
values[0].tags.map((tag) => tag.padStart(10)); // if the types are OK, this will typecheck OK
});
});
diff --git a/src/component-arguments/structured.ts b/src/component-arguments/structured.ts
index 07be295..ccea54c 100644
--- a/src/component-arguments/structured.ts
+++ b/src/component-arguments/structured.ts
@@ -1,137 +1,144 @@
import { is, predicates } from "@sealcode/ts-predicates";
import { JDDContext } from "../index.js";
import {
ComponentArgument,
ExtractParsed,
ExtractStorage,
} from "./component-argument.js";
import { ContainerArgument } from "./container-argument.js";
export class Structured<
T extends Record<string, ComponentArgument<unknown>>
> extends ContainerArgument<
{
[property in keyof T]: ExtractParsed<T[property]>;
},
{
[property in keyof T]: ExtractStorage<T[property]>;
}
> {
constructor(public structure: T) {
super();
Object.values(structure).forEach((arg) => (arg.parent_argument = this));
}
getTypeName() {
return "structured";
}
- getSubArgument(key: string) {
- return this.structure[key] || null;
+ getSubArgument(
+ [key, ...rest]: string[],
+ value: {
+ [property in keyof T]: ExtractParsed<T[property]>;
+ }
+ ): readonly [ComponentArgument<any> | null, string[], unknown] {
+ return <const>[this.structure[key] || null, rest, value[key]];
}
countWords(value: {
[property in keyof T]: ExtractParsed<T[property]>;
}): number {
return Object.entries(value).reduce((acc, [key, val]) => {
if (!this.structure[key]) {
console.warn(`Key ${key} doesn't exist in structured argument`);
return acc + 0;
}
return acc + this.structure[key].countWords(val);
}, 0);
}
- getEmptyValue() {
+ getEmptyValue(): {
+ [property in keyof T]: ExtractParsed<T[property]>;
+ } {
return Object.fromEntries(
Object.entries(this.structure).map(([name, arg]) => [
name,
arg.getEmptyValue(),
])
) as {
[property in keyof T]: ExtractParsed<T[property]>;
};
}
async getExampleValue(context: JDDContext) {
return Object.fromEntries(
await Promise.all(
Object.entries(this.structure).map(async ([name, arg]) => [
name,
await arg.getExampleValue(context),
])
)
) as {
[property in keyof T]: ExtractParsed<T[property]>;
};
}
async processAllSubarguments<
SingleObject extends {
[property in keyof T]: ExtractParsed<T[property]>;
}
>(
_context: JDDContext,
input: unknown,
processing_function: (
argument: ComponentArgument<unknown>,
value: unknown
) => Promise<unknown>
): Promise<SingleObject | SingleObject[] | null> {
if (!is(input, predicates.object)) {
throw new Error(`Not an object: ${input as string}`);
}
const result: Record<string, unknown> = {};
await Promise.all(
Object.entries(input).map(async ([obj_key, obj_value]) => {
const nested_arg_type: ComponentArgument<unknown> =
this.structure[obj_key];
if (!nested_arg_type) {
return [obj_key, null];
}
const new_value = await processing_function(
nested_arg_type,
obj_value
);
result[obj_key] = new_value;
})
);
// if we're in a list and any of the values return an array, we will multiply the object
if (this.hasParent("list")) {
const keys_with_unexpected_arrays = Object.entries(result)
.filter(([key, value]) => {
const nested_arg_type: ComponentArgument<unknown> =
this.structure[key];
return (
nested_arg_type.getTypeName() !== "list" &&
Array.isArray(value)
);
})
.map(([key]) => key);
if (keys_with_unexpected_arrays.length > 1) {
throw new Error(
"Multiplying on more than one field at the same time is not implemented yet"
);
}
if (keys_with_unexpected_arrays.length == 1) {
const key = keys_with_unexpected_arrays[0];
const old_result = result;
const array = old_result[key];
if (!Array.isArray(array)) {
throw new Error("expected an array");
}
return array.map((value: unknown) => ({
...old_result,
[key]: value,
})) as SingleObject[];
} else {
return result as SingleObject;
}
} else {
return result as SingleObject;
}
}
}
diff --git a/src/component-arguments/table.ts b/src/component-arguments/table.ts
index 6338f35..9c4e78c 100644
--- a/src/component-arguments/table.ts
+++ b/src/component-arguments/table.ts
@@ -1,209 +1,226 @@
import { hasShape, predicates } from "@sealcode/ts-predicates";
import { JDDContext } from "../index.js";
import { ComponentArgument } from "./component-argument.js";
import { ContainerArgument } from "./container-argument.js";
type TableHeader<HeaderType> = { type: "header"; header_content: HeaderType };
type TableRegularRow<CellType> = { type: "row"; cells: CellType[] };
export type TableRow<CellType, HeaderType> =
| TableHeader<HeaderType>
| TableRegularRow<CellType>;
export type TableData<CellType, HeaderType> = {
rows: TableRow<CellType, HeaderType>[];
};
export function isTableHeader(x: unknown): x is TableHeader<unknown> {
return hasShape(
{
type: predicates.const("header"),
header_content: predicates.unknown,
},
x
);
}
export function isTableRegularRow<CellType = unknown>(
x: unknown
): x is TableRegularRow<CellType> {
return hasShape(
{
type: predicates.const("row"),
cells: predicates.array(predicates.unknown),
},
x
);
}
export function isTableData<CellType = unknown, HeaderType = unknown>(
x: unknown
): x is TableData<CellType, HeaderType> {
return hasShape(
{
rows: predicates.array(predicates.object),
},
x
);
}
export class Table<CellType, HeaderType> extends ContainerArgument<
TableData<CellType, HeaderType>
> {
constructor(
public header_type: ComponentArgument<HeaderType, unknown, unknown>,
public cell_type: ComponentArgument<CellType, unknown, unknown>
) {
super();
cell_type.parent_argument = this;
header_type.parent_argument = this;
}
- getSubArgument(key: string, value: TableData<CellType, HeaderType>) {
+ getSubArgument(
+ [_, key, ...rest]: string[],
+ value: TableData<CellType, HeaderType>
+ ) {
+ console.log("table.ts:66", { key, rest, value });
if (isNaN(parseInt(key))) {
- return null;
+ return <const>[null, [] as string[], null];
}
const key_n = parseInt(key);
const row = value.rows[key_n];
if (!row) {
- return null;
+ return <const>[null, [] as string[], null];
} else if (row.type == "header") {
- return this.header_type;
+ return <const>[this.header_type, rest, row.header_content];
} else {
- return this.cell_type;
+ let cell_index = rest.shift();
+ if (cell_index == "cells") {
+ cell_index = rest.shift();
+ }
+ if (!cell_index) {
+ throw new Error("Missing cell index");
+ }
+ const parsed_cell_index = parseInt(cell_index);
+ if (isNaN(parsed_cell_index)) {
+ throw new Error(
+ `Cell index should be a number, got: ${cell_index}`
+ );
+ }
+ return <const>[this.cell_type, rest, row.cells[parsed_cell_index]];
}
}
getTypeName() {
return "table";
}
getEmptyValue() {
return {
rows: [
{
type: <const>"header",
header_content: this.header_type.getEmptyValue(),
},
{
type: <const>"row",
cells: [this.cell_type.getEmptyValue()],
},
],
};
}
async getExampleValue(context: JDDContext) {
const rows = Math.round(Math.random() * 5);
const columns = Math.round(Math.random() * 5);
const result: TableData<CellType, HeaderType> = {
rows: [
{
type: "header",
header_content: await this.header_type.getExampleValue(
context
),
},
],
};
for (let i = 0; i < rows; i++) {
const cells: CellType[] = [];
for (let j = 0; j < columns; j++) {
// eslint-disable-next-line no-await-in-loop
cells.push(await this.cell_type.getExampleValue(context));
}
result.rows.push({ type: "row", cells });
}
return result;
}
countWords(value: TableData<CellType, HeaderType>): number {
let result = 0;
for (let i = 0; i < value.rows.length; i++) {
const row = value.rows[i];
if (isTableHeader(row)) {
result += this.header_type.countWords(row.header_content);
} else {
for (let j = 0; j < row.cells.length; j++) {
result += this.cell_type.countWords(row.cells[j]);
}
}
}
return result;
}
async processAllSubarguments(
context: JDDContext,
input: unknown,
processing_function: (
argument: ComponentArgument<unknown>,
value: unknown
) => Promise<unknown>
) {
if (!hasShape({ rows: predicates.array(predicates.object) }, input)) {
return { rows: [] };
} else {
const result: TableData<CellType, HeaderType> = { rows: [] };
const row_promises = input.rows.map(async (row, row_index) => {
let new_row: TableRow<CellType, HeaderType>;
if (hasShape({ header_content: predicates.unknown }, row)) {
let header_content = (await processing_function(
this.header_type,
row.header_content
)) as HeaderType | HeaderType[] | null;
if (Array.isArray(header_content)) {
header_content = header_content[0];
}
if (header_content == null) {
header_content = this.header_type.getEmptyValue();
}
new_row = {
type: "header",
header_content,
};
result.rows[row_index] = new_row;
} else if (
hasShape(
{ cells: predicates.array(predicates.unknown) },
row
)
) {
new_row = {
type: "row",
cells: await Promise.all(
row.cells.map(async (cell) => {
const value = (await processing_function(
this.cell_type,
cell
)) as CellType | CellType[] | null;
if (value === null) {
return this.cell_type.getEmptyValue();
} else if (Array.isArray(value)) {
return value[0];
} else {
return value;
}
})
),
};
result.rows[row_index] = new_row;
}
});
await Promise.all(row_promises);
return result;
}
}
getColumnsCount(value: TableData<CellType, HeaderType>) {
return (
(
(
value.rows.filter((row) => row.type == "row")[0] as
| TableRegularRow<CellType>
| undefined
)?.cells || []
).length || 1
);
}
}
diff --git a/src/component.test.ts b/src/component.test.ts
new file mode 100644
index 0000000..553eb7b
--- /dev/null
+++ b/src/component.test.ts
@@ -0,0 +1,49 @@
+import assert from "assert";
+import { Table } from "./component-arguments/table.js";
+import { Component } from "./component.js";
+import { List, ShortText, Structured } from "./index.js";
+
+describe("component class", () => {
+ describe("getSubArgument", () => {
+ it("traverses argument path that includes a table", () => {
+ const args = {
+ table: new Table(
+ new Structured({ title: new ShortText() }),
+ new Structured({ tags: new List(new ShortText()) })
+ ),
+ };
+ const component = new (class extends Component<typeof args> {
+ getArguments() {
+ return args;
+ }
+ toHTML() {
+ return "";
+ }
+ })();
+
+ const arg = component.getArgumentAtPath(
+ "table/rows/2/cells/0/tags".split("/"),
+ {
+ table: {
+ rows: [
+ {
+ type: "header",
+ header_content: { title: "hehe" },
+ },
+ {
+ type: "header",
+ header_content: { title: "hehe2" },
+ },
+ {
+ type: "row",
+ cells: [{ tags: ["tag1", "tag2"] }],
+ },
+ ],
+ },
+ }
+ );
+ console.log(arg);
+ assert(arg instanceof List);
+ });
+ });
+});
diff --git a/src/component.ts b/src/component.ts
index 868d138..a35a7a2 100644
--- a/src/component.ts
+++ b/src/component.ts
@@ -1,146 +1,153 @@
import { FlatTemplatable } from "tempstream";
import {
ComponentArgument,
ExtractStructuredComponentArgumentsParsed,
ExtractStructuredComponentArgumentsReceived,
ExtractStructuredComponentArgumentsStorage,
JDDContext,
} from "./index.js";
export interface ComponentConstructor<
A extends Record<string, ComponentArgument<unknown>> = Record<
string,
ComponentArgument<unknown>
>
> {
new (): Component<A>;
}
export type EarlyAsset = (
| { type: "script" | "style"; url: string; integrity?: string }
| { type: "script" | "style"; content: string }
) & { identity: string }; // identity key will be used for deduplication
export abstract class Component<
ArgumentsT extends Record<string, ComponentArgument<unknown>> = Record<
string,
ComponentArgument<unknown>
>
> {
abstract getArguments(): ArgumentsT;
abstract toHTML(
args: ExtractStructuredComponentArgumentsParsed<ArgumentsT>,
context: JDDContext
): FlatTemplatable;
async getEarlyAssets(
_args: ExtractStructuredComponentArgumentsParsed<ArgumentsT>,
_context: JDDContext
): Promise<EarlyAsset[]> {
return [];
}
countWords(args: Record<string, unknown>): number {
return Object.entries(args).reduce((acc, [arg_name, value]) => {
const arg = this.getArguments()[arg_name];
if (!arg) {
console.warn(
`Arguemnt ${arg_name} was not found in the component`
);
return acc + 0;
}
return acc + arg.countWords(value);
}, 0);
}
async getExampleValues(
context: JDDContext
): Promise<ExtractStructuredComponentArgumentsParsed<ArgumentsT>> {
return Object.fromEntries(
await Promise.all(
Object.entries(this.getArguments()).map(
async ([key, value]) => [
key,
await value.getExampleValue(context),
]
)
)
) as ExtractStructuredComponentArgumentsParsed<ArgumentsT>;
}
async convertReceivedValuesToParsed(
context: JDDContext,
values: ExtractStructuredComponentArgumentsReceived<ArgumentsT>
): Promise<ExtractStructuredComponentArgumentsParsed<ArgumentsT>> {
const args = this.getArguments();
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
return Object.fromEntries(
await Promise.all(
Object.entries(values).map(async ([key, value]) => {
return [
key,
await args[key].receivedToParsed(context, value),
];
})
)
);
}
async convertParsedToStorage(
context: JDDContext,
values: ExtractStructuredComponentArgumentsParsed<ArgumentsT>
): Promise<ExtractStructuredComponentArgumentsStorage<ArgumentsT>> {
const args = this.getArguments();
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
return Object.fromEntries(
await Promise.all(
Object.entries(values).map(async ([key, value]) => {
return [
key,
await args[key].parsedToStorage(context, value),
];
})
)
);
}
async convertStorageToParsed(
context: JDDContext,
values: ExtractStructuredComponentArgumentsStorage<ArgumentsT>
): Promise<ExtractStructuredComponentArgumentsParsed<ArgumentsT>> {
const args = this.getArguments();
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
return Object.fromEntries(
await Promise.all(
Object.entries(values).map(async ([key, value]) => {
return [
key,
await args[key].storageToParsed(context, value),
];
})
)
);
}
getArgumentAtPath(
argument_path: string[],
values: ExtractStructuredComponentArgumentsParsed<ArgumentsT>
): ComponentArgument<unknown> | null {
+ console.log("component.ts:129", argument_path);
argument_path = [...argument_path];
if (argument_path.length == 0) {
return null;
}
+ const arg_name = argument_path.shift() as string;
let argument: ComponentArgument<unknown> | null =
- this.getArguments()[argument_path.shift() as string];
+ this.getArguments()[arg_name];
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
+ values = values[arg_name] as any;
if (argument_path.length == 0) {
return argument;
}
do {
- argument = argument.getSubArgument(
- argument_path.shift() as string,
+ console.log("component.ts:139", argument_path);
+ // the getSubArgument method can consume as many keys from the path as it wants
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
+ [argument, argument_path, values] = argument.getSubArgument(
+ argument_path,
values
- );
+ ) as any;
} while (argument_path.length && argument !== null);
return argument;
}
}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sat, Nov 8, 13:59 (12 h, 3 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1034644
Default Alt Text
(26 KB)
Attached To
Mode
rJDD jdd
Attached
Detach File
Event Timeline
Log In to Comment