@stonecrop/schema 0.13.12 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +38 -92
- package/dist/cli.js +6 -6
- package/dist/index-BzhZpuzA.js +556 -0
- package/dist/index-BzhZpuzA.js.map +1 -0
- package/dist/index-C1oC7Xwz.js +552 -0
- package/dist/index-C1oC7Xwz.js.map +1 -0
- package/dist/index-C8F23K8c.js +555 -0
- package/dist/index-C8F23K8c.js.map +1 -0
- package/dist/index-CD5wQNH-.js +516 -0
- package/dist/index-CD5wQNH-.js.map +1 -0
- package/dist/index-CMeexvC6.js +459 -0
- package/dist/index-CMeexvC6.js.map +1 -0
- package/dist/index-CX662Zb2.js +551 -0
- package/dist/index-CX662Zb2.js.map +1 -0
- package/dist/index-Cq_yfoqI.js +553 -0
- package/dist/index-Cq_yfoqI.js.map +1 -0
- package/dist/index-D68mWfHm.js +510 -0
- package/dist/index-D68mWfHm.js.map +1 -0
- package/dist/index-D8R5ppAg.js +529 -0
- package/dist/index-D8R5ppAg.js.map +1 -0
- package/dist/index-DCjAX4l-.js +516 -0
- package/dist/index-DCjAX4l-.js.map +1 -0
- package/dist/index-DE0b6fs6.js +515 -0
- package/dist/index-DE0b6fs6.js.map +1 -0
- package/dist/index-DIY_FLR2.js +516 -0
- package/dist/index-DIY_FLR2.js.map +1 -0
- package/dist/index-DT-NJBvW.js +510 -0
- package/dist/index-DT-NJBvW.js.map +1 -0
- package/dist/index-DYy5E1cU.js +508 -0
- package/dist/index-DYy5E1cU.js.map +1 -0
- package/dist/index-Dk593rMz.js +512 -0
- package/dist/index-Dk593rMz.js.map +1 -0
- package/dist/index-DpCFgELB.js +514 -0
- package/dist/index-DpCFgELB.js.map +1 -0
- package/dist/index-DyK5-0kh.js +514 -0
- package/dist/index-DyK5-0kh.js.map +1 -0
- package/dist/index-Vd0_gZjr.js +451 -0
- package/dist/index-Vd0_gZjr.js.map +1 -0
- package/dist/index-YP0m26Y5.js +555 -0
- package/dist/index-YP0m26Y5.js.map +1 -0
- package/dist/index-_3q9Bzka.js +512 -0
- package/dist/index-_3q9Bzka.js.map +1 -0
- package/dist/index-glU_Uw7z.js +543 -0
- package/dist/index-glU_Uw7z.js.map +1 -0
- package/dist/index-i0Uz8G2K.js +554 -0
- package/dist/index-i0Uz8G2K.js.map +1 -0
- package/dist/index-rozX0Luh.js +458 -0
- package/dist/index-rozX0Luh.js.map +1 -0
- package/dist/index.js +70 -31
- package/dist/index.js.map +1 -1
- package/dist/schema.d.ts +324 -88
- package/dist/src/column-schema.d.ts +17 -8
- package/dist/src/column-schema.d.ts.map +1 -1
- package/dist/src/component-meta.d.ts +96 -0
- package/dist/src/component-meta.d.ts.map +1 -0
- package/dist/src/component-meta.js +85 -0
- package/dist/src/converter/heuristics.d.ts.map +1 -1
- package/dist/src/converter/heuristics.js +6 -13
- package/dist/src/converter/index.d.ts +1 -1
- package/dist/src/converter/index.d.ts.map +1 -1
- package/dist/src/converter/index.js +9 -8
- package/dist/src/converter/scalars.d.ts +1 -1
- package/dist/src/converter/scalars.d.ts.map +1 -1
- package/dist/src/converter/scalars.js +23 -26
- package/dist/src/converter/types.d.ts +17 -8
- package/dist/src/converter/types.d.ts.map +1 -1
- package/dist/src/doctype.d.ts +127 -9
- package/dist/src/doctype.d.ts.map +1 -1
- package/dist/src/doctype.js +80 -7
- package/dist/src/field.d.ts +69 -12
- package/dist/src/field.d.ts.map +1 -1
- package/dist/src/field.js +45 -7
- package/dist/src/fieldtype.d.ts.map +1 -1
- package/dist/src/fieldtype.js +14 -13
- package/dist/src/index.d.ts +4 -3
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +7 -3
- package/package.json +1 -1
|
@@ -20,11 +20,19 @@ export interface ColumnSchema {
|
|
|
20
20
|
/** Unique identifier for the field within its doctype. Maps to `name` on `TableColumn`. */
|
|
21
21
|
fieldname: string;
|
|
22
22
|
/**
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
23
|
+
* Rendering component (e.g. `'ATextInput'`, `'ANumericInput'`, `'ADate'`). Default cell
|
|
24
|
+
* formatting and filter widgets derive from its {@link ComponentCategory}.
|
|
25
|
+
*
|
|
26
|
+
* Optional here, unlike `ValueField.component`: absence is what marks an entry as non-scalar
|
|
27
|
+
* (a nested table or fieldset), which `schemaToColumns` excludes — it has no column equivalent.
|
|
28
|
+
*/
|
|
29
|
+
component?: string;
|
|
30
|
+
/**
|
|
31
|
+
* Target doctype slug — marks this column as a link. When set and no `cellComponent` is given,
|
|
32
|
+
* `schemaToColumns` copies it to `TableColumn.linkDoctype`, which ACell uses to resolve a bare
|
|
33
|
+
* id to display text.
|
|
26
34
|
*/
|
|
27
|
-
|
|
35
|
+
doctype?: string;
|
|
28
36
|
/**
|
|
29
37
|
* Human-readable column header. When absent, ATable assigns labels alphabetically
|
|
30
38
|
* (A, B, C, …).
|
|
@@ -35,7 +43,7 @@ export interface ColumnSchema {
|
|
|
35
43
|
/**
|
|
36
44
|
* Horizontal text alignment for the column cell and header.
|
|
37
45
|
*
|
|
38
|
-
* @defaultValue '
|
|
46
|
+
* @defaultValue 'center'
|
|
39
47
|
*/
|
|
40
48
|
align?: 'left' | 'right' | 'center' | 'start' | 'end';
|
|
41
49
|
/**
|
|
@@ -75,9 +83,10 @@ export interface ColumnSchema {
|
|
|
75
83
|
*/
|
|
76
84
|
filterable?: boolean;
|
|
77
85
|
/**
|
|
78
|
-
* The type of filter control to render. When absent, a default is derived from
|
|
79
|
-
*
|
|
80
|
-
*
|
|
86
|
+
* The type of filter control to render. When absent, a default is derived from the
|
|
87
|
+
* `component`'s {@link ComponentCategory} (`boolean` → `checkbox`, `date` → `date`,
|
|
88
|
+
* `datetime` → `dateRange`, `select` → `select`, `number` → `number`, everything else
|
|
89
|
+
* — including an unknown component — → `text`).
|
|
81
90
|
*/
|
|
82
91
|
filterType?: 'text' | 'select' | 'number' | 'date' | 'dateRange' | 'checkbox' | 'component';
|
|
83
92
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"column-schema.d.ts","sourceRoot":"","sources":["../../src/column-schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,WAAW,YAAY;IAC5B,2FAA2F;IAC3F,SAAS,EAAE,MAAM,CAAA;IAEjB;;;;OAIG;IACH,
|
|
1
|
+
{"version":3,"file":"column-schema.d.ts","sourceRoot":"","sources":["../../src/column-schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,WAAW,YAAY;IAC5B,2FAA2F;IAC3F,SAAS,EAAE,MAAM,CAAA;IAEjB;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAElB;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAA;IAEhB;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAA;IAEd,wFAAwF;IACxF,MAAM,CAAC,EAAE,OAAO,CAAA;IAEhB;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,QAAQ,GAAG,OAAO,GAAG,KAAK,CAAA;IAErD;;;;OAIG;IACH,IAAI,CAAC,EAAE,OAAO,CAAA;IAEd;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,CAAA;IAEd;;;;OAIG;IACH,MAAM,CAAC,EAAE,OAAO,CAAA;IAEhB;;;;OAIG;IACH,SAAS,CAAC,EAAE,OAAO,CAAA;IAEnB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAA;IAElB;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAA;IAEpB;;;;;OAKG;IACH,UAAU,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAM,GAAG,WAAW,GAAG,UAAU,GAAG,WAAW,CAAA;IAE3F;;;OAGG;IACH,aAAa,CAAC,EAAE,GAAG,EAAE,CAAA;IAErB,yEAAyE;IACzE,eAAe,CAAC,EAAE,MAAM,CAAA;IAExB;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAA;IAEtB;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IAExC;;;;;;;;;OASG;IACH,cAAc,CAAC,EAAE,MAAM,CAAA;IAEvB;;;;OAIG;IACH,wBAAwB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IAE9C;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAA;IAEf;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;IAEjB;;;;;;OAMG;IACH,cAAc,CAAC,EAAE,MAAM,CAAA;IAEvB;;;;;OAKG;IACH,OAAO,CAAC,EAAE,MAAM,CAAA;CAChB"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Semantic category for a rendering component.
|
|
3
|
+
*
|
|
4
|
+
* `component` is the primary field axis, so the runtime consumers that need to know what a field
|
|
5
|
+
* *means* (atable cell formatting / filter widgets, record-default init) derive it from here. This
|
|
6
|
+
* is the single source of "what kind of value does this component render", keyed by the canonical
|
|
7
|
+
* registered component names — each consumer maps the category to its own concern (filter widget,
|
|
8
|
+
* default value, …).
|
|
9
|
+
*
|
|
10
|
+
* @public
|
|
11
|
+
*/
|
|
12
|
+
export type ComponentCategory = 'text' | 'number' | 'boolean' | 'date' | 'datetime' | 'select' | 'code' | 'link' | 'attach';
|
|
13
|
+
/**
|
|
14
|
+
* Canonical component → semantic category. Only the components Stonecrop ships with appear here;
|
|
15
|
+
* custom/unknown component names have no category and consumers fall back to their default.
|
|
16
|
+
* @public
|
|
17
|
+
*/
|
|
18
|
+
export declare const COMPONENT_CATEGORY: Record<string, ComponentCategory>;
|
|
19
|
+
/**
|
|
20
|
+
* Resolve a component's semantic category, or `undefined` for an unknown (custom) component —
|
|
21
|
+
* callers treat that as "no opinion" and use their own default.
|
|
22
|
+
* @public
|
|
23
|
+
*/
|
|
24
|
+
export declare function componentCategory(component?: string): ComponentCategory | undefined;
|
|
25
|
+
/**
|
|
26
|
+
* Whether a link component expands its target doctype, or renders the link inline.
|
|
27
|
+
*
|
|
28
|
+
* This is the *only* axis the component decides. It deliberately does not choose between an
|
|
29
|
+
* embedded record and an embedded table: `cardinality` states whether the value is a scalar or
|
|
30
|
+
* an array, which is a fact about the data rather than a rendering preference, so a component
|
|
31
|
+
* must not be able to override it (an `AForm` over a `noneOrMany` link would be handed an array
|
|
32
|
+
* it cannot render). Component names encode both axes — `AFormLink`/`ATableLink` are the inline
|
|
33
|
+
* pair, `AForm`/`ATable` the expanding pair — but only the inline/expand half is authoritative.
|
|
34
|
+
*
|
|
35
|
+
* @public
|
|
36
|
+
*/
|
|
37
|
+
export type LinkExpansion = 'inline' | 'expand';
|
|
38
|
+
/**
|
|
39
|
+
* Canonical link component → expansion. Only components Stonecrop ships with appear here; an
|
|
40
|
+
* unmapped (custom) component has none, and callers treat that as `expand` — the behaviour that
|
|
41
|
+
* predates this map, so a custom component can never silently collapse a link to a picker.
|
|
42
|
+
* @public
|
|
43
|
+
*/
|
|
44
|
+
export declare const COMPONENT_LINK_EXPANSION: Record<string, LinkExpansion>;
|
|
45
|
+
/**
|
|
46
|
+
* Resolve a component's link expansion, or `undefined` for an absent/unmapped component.
|
|
47
|
+
* @public
|
|
48
|
+
*/
|
|
49
|
+
export declare function componentLinkExpansion(component?: string): LinkExpansion | undefined;
|
|
50
|
+
/**
|
|
51
|
+
* How a link field renders.
|
|
52
|
+
*
|
|
53
|
+
* - `inline` — a scalar id-picker; the target is *not* expanded (the field keeps its own value
|
|
54
|
+
* and carries a `doctype` prop for async display-text resolution and navigation).
|
|
55
|
+
* - `record` — the target doctype is resolved and embedded as a nested form.
|
|
56
|
+
* - `table` — the target doctype is resolved and embedded as a child table.
|
|
57
|
+
*
|
|
58
|
+
* @public
|
|
59
|
+
*/
|
|
60
|
+
export type LinkRenderMode = 'inline' | 'record' | 'table';
|
|
61
|
+
/**
|
|
62
|
+
* Decide how a *declared* link (one with a `LinkDeclaration`) renders.
|
|
63
|
+
*
|
|
64
|
+
* Two independent axes: the **component** picks inline vs expand, and when expanding the
|
|
65
|
+
* **cardinality** picks record vs table (many → table). The declaration's component wins over the
|
|
66
|
+
* field's, matching the precedence the resolver already uses for the rendered component.
|
|
67
|
+
*
|
|
68
|
+
* This is the single definition of "does this link expand" — it is consumed by both the client
|
|
69
|
+
* resolver (which builds the nested schema) and the server column builder (which must still
|
|
70
|
+
* SELECT an `inline` link's FK column). Call it; never re-derive the rule at the call site, or
|
|
71
|
+
* the two will drift and the client will render a table for a column the server never selected.
|
|
72
|
+
*
|
|
73
|
+
* @param link - the link declaration (only `component` and `cardinality` are consulted)
|
|
74
|
+
* @param fieldComponent - the linked field's own `component`, used when the declaration names none
|
|
75
|
+
* @public
|
|
76
|
+
*/
|
|
77
|
+
export declare function resolveLinkRenderMode(link: {
|
|
78
|
+
component?: string;
|
|
79
|
+
cardinality?: string;
|
|
80
|
+
}, fieldComponent?: string): LinkRenderMode;
|
|
81
|
+
/**
|
|
82
|
+
* Every component Stonecrop ships with that can render a value field, sorted by name.
|
|
83
|
+
*
|
|
84
|
+
* The union of the two maps above is the definition, not a copy of it: a shipped component either
|
|
85
|
+
* categorises a value ({@link COMPONENT_CATEGORY}) or is one of the link containers that has no
|
|
86
|
+
* value of its own ({@link COMPONENT_LINK_EXPANSION}'s `AForm`/`ATable`). `AFieldset` is absent by
|
|
87
|
+
* the same rule — it is a `kind: 'fieldset'` container, so it is never a value field's component.
|
|
88
|
+
*
|
|
89
|
+
* `component` is an **open** axis: any string is valid, and naming a custom component is how an app
|
|
90
|
+
* renders a field Stonecrop ships no widget for. This list is therefore the set to *suggest* to an
|
|
91
|
+
* author, and to check first-party data against — never a set to validate arbitrary input against.
|
|
92
|
+
*
|
|
93
|
+
* @public
|
|
94
|
+
*/
|
|
95
|
+
export declare const CANONICAL_COMPONENTS: readonly string[];
|
|
96
|
+
//# sourceMappingURL=component-meta.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"component-meta.d.ts","sourceRoot":"","sources":["../../src/component-meta.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,MAAM,MAAM,iBAAiB,GAC5B,MAAM,GAAG,QAAQ,GAAG,SAAS,GAAG,MAAM,GAAG,UAAU,GAAG,QAAQ,GAAG,MAAM,GAAG,MAAM,GAAG,QAAQ,CAAA;AAE5F;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAehE,CAAA;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,iBAAiB,GAAG,SAAS,CAEnF;AAED;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,aAAa,GAAG,QAAQ,GAAG,QAAQ,CAAA;AAE/C;;;;;GAKG;AACH,eAAO,MAAM,wBAAwB,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAIlE,CAAA;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS,CAEpF;AAED;;;;;;;;;GASG;AACH,MAAM,MAAM,cAAc,GAAG,QAAQ,GAAG,QAAQ,GAAG,OAAO,CAAA;AAE1D;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,qBAAqB,CACpC,IAAI,EAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,EAClD,cAAc,CAAC,EAAE,MAAM,GACrB,cAAc,CAGhB;AAED;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,oBAAoB,EAAE,SAAS,MAAM,EAEtC,CAAA"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Canonical component → semantic category. Only the components Stonecrop ships with appear here;
|
|
3
|
+
* custom/unknown component names have no category and consumers fall back to their default.
|
|
4
|
+
* @public
|
|
5
|
+
*/
|
|
6
|
+
export const COMPONENT_CATEGORY = {
|
|
7
|
+
ATextInput: 'text',
|
|
8
|
+
ATextarea: 'text',
|
|
9
|
+
ANumericInput: 'number',
|
|
10
|
+
ACheckbox: 'boolean',
|
|
11
|
+
ADate: 'date',
|
|
12
|
+
ADatePicker: 'date',
|
|
13
|
+
ADateSelection: 'date',
|
|
14
|
+
ADateTime: 'datetime',
|
|
15
|
+
ADuration: 'text',
|
|
16
|
+
ADateRange: 'date',
|
|
17
|
+
ADropdown: 'select',
|
|
18
|
+
ACodeEditor: 'code',
|
|
19
|
+
AFormLink: 'link',
|
|
20
|
+
AFileAttach: 'attach',
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Resolve a component's semantic category, or `undefined` for an unknown (custom) component —
|
|
24
|
+
* callers treat that as "no opinion" and use their own default.
|
|
25
|
+
* @public
|
|
26
|
+
*/
|
|
27
|
+
export function componentCategory(component) {
|
|
28
|
+
return component ? COMPONENT_CATEGORY[component] : undefined;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Canonical link component → expansion. Only components Stonecrop ships with appear here; an
|
|
32
|
+
* unmapped (custom) component has none, and callers treat that as `expand` — the behaviour that
|
|
33
|
+
* predates this map, so a custom component can never silently collapse a link to a picker.
|
|
34
|
+
* @public
|
|
35
|
+
*/
|
|
36
|
+
export const COMPONENT_LINK_EXPANSION = {
|
|
37
|
+
AFormLink: 'inline',
|
|
38
|
+
AForm: 'expand',
|
|
39
|
+
ATable: 'expand',
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* Resolve a component's link expansion, or `undefined` for an absent/unmapped component.
|
|
43
|
+
* @public
|
|
44
|
+
*/
|
|
45
|
+
export function componentLinkExpansion(component) {
|
|
46
|
+
return component ? COMPONENT_LINK_EXPANSION[component] : undefined;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Decide how a *declared* link (one with a `LinkDeclaration`) renders.
|
|
50
|
+
*
|
|
51
|
+
* Two independent axes: the **component** picks inline vs expand, and when expanding the
|
|
52
|
+
* **cardinality** picks record vs table (many → table). The declaration's component wins over the
|
|
53
|
+
* field's, matching the precedence the resolver already uses for the rendered component.
|
|
54
|
+
*
|
|
55
|
+
* This is the single definition of "does this link expand" — it is consumed by both the client
|
|
56
|
+
* resolver (which builds the nested schema) and the server column builder (which must still
|
|
57
|
+
* SELECT an `inline` link's FK column). Call it; never re-derive the rule at the call site, or
|
|
58
|
+
* the two will drift and the client will render a table for a column the server never selected.
|
|
59
|
+
*
|
|
60
|
+
* @param link - the link declaration (only `component` and `cardinality` are consulted)
|
|
61
|
+
* @param fieldComponent - the linked field's own `component`, used when the declaration names none
|
|
62
|
+
* @public
|
|
63
|
+
*/
|
|
64
|
+
export function resolveLinkRenderMode(link, fieldComponent) {
|
|
65
|
+
if (componentLinkExpansion(link.component ?? fieldComponent) === 'inline')
|
|
66
|
+
return 'inline';
|
|
67
|
+
return link.cardinality === 'noneOrMany' || link.cardinality === 'atLeastOne' ? 'table' : 'record';
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Every component Stonecrop ships with that can render a value field, sorted by name.
|
|
71
|
+
*
|
|
72
|
+
* The union of the two maps above is the definition, not a copy of it: a shipped component either
|
|
73
|
+
* categorises a value ({@link COMPONENT_CATEGORY}) or is one of the link containers that has no
|
|
74
|
+
* value of its own ({@link COMPONENT_LINK_EXPANSION}'s `AForm`/`ATable`). `AFieldset` is absent by
|
|
75
|
+
* the same rule — it is a `kind: 'fieldset'` container, so it is never a value field's component.
|
|
76
|
+
*
|
|
77
|
+
* `component` is an **open** axis: any string is valid, and naming a custom component is how an app
|
|
78
|
+
* renders a field Stonecrop ships no widget for. This list is therefore the set to *suggest* to an
|
|
79
|
+
* author, and to check first-party data against — never a set to validate arbitrary input against.
|
|
80
|
+
*
|
|
81
|
+
* @public
|
|
82
|
+
*/
|
|
83
|
+
export const CANONICAL_COMPONENTS = [
|
|
84
|
+
...new Set([...Object.keys(COMPONENT_CATEGORY), ...Object.keys(COMPONENT_LINK_EXPANSION)]),
|
|
85
|
+
].toSorted();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"heuristics.d.ts","sourceRoot":"","sources":["../../../src/converter/heuristics.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAON,KAAK,iBAAiB,EACtB,KAAK,YAAY,EAGjB,MAAM,SAAS,CAAA;AAGhB,OAAO,KAAK,EAAE,0BAA0B,EAAE,wBAAwB,EAAE,MAAM,SAAS,CAAA;AA+BnF;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,iBAAiB,GAAG,OAAO,CA8BtF;AAQD;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CACnC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,EACtC,WAAW,EAAE,iBAAiB,GAC5B,OAAO,CAET;AAyED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,iBAAiB,CAChC,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,EACrC,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,EACxB,OAAO,GAAE,wBAA6B,GACpC,0BAA0B,
|
|
1
|
+
{"version":3,"file":"heuristics.d.ts","sourceRoot":"","sources":["../../../src/converter/heuristics.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAON,KAAK,iBAAiB,EACtB,KAAK,YAAY,EAGjB,MAAM,SAAS,CAAA;AAGhB,OAAO,KAAK,EAAE,0BAA0B,EAAE,wBAAwB,EAAE,MAAM,SAAS,CAAA;AA+BnF;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,iBAAiB,GAAG,OAAO,CA8BtF;AAQD;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CACnC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,EACtC,WAAW,EAAE,iBAAiB,GAC5B,OAAO,CAET;AAyED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,iBAAiB,CAChC,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,EACrC,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,EACxB,OAAO,GAAE,wBAA6B,GACpC,0BAA0B,CAkG5B"}
|
|
@@ -182,7 +182,6 @@ export function classifyFieldType(fieldName, field, entityTypes, options = {}) {
|
|
|
182
182
|
fieldname: fieldName,
|
|
183
183
|
label: camelToLabel(fieldName),
|
|
184
184
|
component: 'ATextInput',
|
|
185
|
-
fieldtype: 'Data',
|
|
186
185
|
};
|
|
187
186
|
if (required) {
|
|
188
187
|
base.required = true;
|
|
@@ -201,16 +200,14 @@ export function classifyFieldType(fieldName, field, entityTypes, options = {}) {
|
|
|
201
200
|
if (namedType.name === 'ID') {
|
|
202
201
|
const candidateTypeName = toPascalCase(fieldName);
|
|
203
202
|
if (entityTypes.has(candidateTypeName)) {
|
|
204
|
-
base.component = '
|
|
205
|
-
base.
|
|
206
|
-
base.options = toSlug(candidateTypeName);
|
|
203
|
+
base.component = 'AFormLink';
|
|
204
|
+
base.doctype = toSlug(candidateTypeName);
|
|
207
205
|
return base;
|
|
208
206
|
}
|
|
209
207
|
}
|
|
210
208
|
const template = scalarMap[namedType.name];
|
|
211
209
|
if (template) {
|
|
212
210
|
base.component = template.component;
|
|
213
|
-
base.fieldtype = template.fieldtype;
|
|
214
211
|
}
|
|
215
212
|
else {
|
|
216
213
|
// Unknown scalar — default to Data with unmapped marker
|
|
@@ -224,7 +221,6 @@ export function classifyFieldType(fieldName, field, entityTypes, options = {}) {
|
|
|
224
221
|
// 2. Enum types → Select
|
|
225
222
|
if (isEnumType(namedType)) {
|
|
226
223
|
base.component = 'ADropdown';
|
|
227
|
-
base.fieldtype = 'Select';
|
|
228
224
|
base.options = namedType.getValues().map(v => v.name);
|
|
229
225
|
return base;
|
|
230
226
|
}
|
|
@@ -232,9 +228,8 @@ export function classifyFieldType(fieldName, field, entityTypes, options = {}) {
|
|
|
232
228
|
if (isObjectType(namedType)) {
|
|
233
229
|
// 3. Direct reference to an entity type → Link
|
|
234
230
|
if (!isList && entityTypes.has(namedType.name)) {
|
|
235
|
-
base.component = '
|
|
236
|
-
base.
|
|
237
|
-
base.options = toSlug(namedType.name);
|
|
231
|
+
base.component = 'AFormLink';
|
|
232
|
+
base.doctype = toSlug(namedType.name);
|
|
238
233
|
return base;
|
|
239
234
|
}
|
|
240
235
|
// 4. Connection type → link (child table)
|
|
@@ -242,18 +237,16 @@ export function classifyFieldType(fieldName, field, entityTypes, options = {}) {
|
|
|
242
237
|
if (connectionNodeTypeName && entityTypes.has(connectionNodeTypeName)) {
|
|
243
238
|
base.component = 'ATable';
|
|
244
239
|
base._isLink = true;
|
|
245
|
-
base.
|
|
240
|
+
base.doctype = toSlug(connectionNodeTypeName);
|
|
246
241
|
base.cardinality = 'noneOrMany';
|
|
247
|
-
delete base.fieldtype;
|
|
248
242
|
return base;
|
|
249
243
|
}
|
|
250
244
|
// 5. List of entity type → link
|
|
251
245
|
if (isList && entityTypes.has(namedType.name)) {
|
|
252
246
|
base.component = 'ATable';
|
|
253
247
|
base._isLink = true;
|
|
254
|
-
base.
|
|
248
|
+
base.doctype = toSlug(namedType.name);
|
|
255
249
|
base.cardinality = 'noneOrMany';
|
|
256
|
-
delete base.fieldtype;
|
|
257
250
|
return base;
|
|
258
251
|
}
|
|
259
252
|
// Unknown object type — mark as unmapped
|
|
@@ -31,7 +31,7 @@ import type { IntrospectionSource, GraphQLConversionOptions, ConvertedGraphQLDoc
|
|
|
31
31
|
* // With PostGraphile custom scalars
|
|
32
32
|
* const doctypes = convertGraphQLSchema(introspection, {
|
|
33
33
|
* customScalars: {
|
|
34
|
-
* BigFloat: { component: '
|
|
34
|
+
* BigFloat: { component: 'ANumericInput' }
|
|
35
35
|
* }
|
|
36
36
|
* })
|
|
37
37
|
* ```
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/converter/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH,OAAO,KAAK,EAAE,mBAAmB,EAAE,wBAAwB,EAAE,uBAAuB,EAAE,MAAM,SAAS,CAAA;AAIrG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAgB,oBAAoB,CACnC,MAAM,EAAE,mBAAmB,EAC3B,OAAO,GAAE,wBAA6B,GACpC,uBAAuB,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/converter/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH,OAAO,KAAK,EAAE,mBAAmB,EAAE,wBAAwB,EAAE,uBAAuB,EAAE,MAAM,SAAS,CAAA;AAIrG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAgB,oBAAoB,CACnC,MAAM,EAAE,mBAAmB,EAC3B,OAAO,GAAE,wBAA6B,GACpC,uBAAuB,EAAE,CA+H3B;AAwBD,OAAO,EAAE,oBAAoB,IAAI,OAAO,EAAE,CAAA;AAG1C,YAAY,EACX,mBAAmB,EACnB,wBAAwB,EACxB,0BAA0B,EAC1B,uBAAuB,GACvB,MAAM,SAAS,CAAA;AAGhB,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAGhG,OAAO,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAA;AAG3F,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA"}
|
|
@@ -33,7 +33,7 @@ import { defaultIsEntityType, defaultIsEntityField, classifyFieldType } from './
|
|
|
33
33
|
* // With PostGraphile custom scalars
|
|
34
34
|
* const doctypes = convertGraphQLSchema(introspection, {
|
|
35
35
|
* customScalars: {
|
|
36
|
-
* BigFloat: { component: '
|
|
36
|
+
* BigFloat: { component: 'ANumericInput' }
|
|
37
37
|
* }
|
|
38
38
|
* })
|
|
39
39
|
* ```
|
|
@@ -99,7 +99,6 @@ export function convertGraphQLSchema(source, options = {}) {
|
|
|
99
99
|
fieldname: fieldName,
|
|
100
100
|
label: custom.label ?? fieldName,
|
|
101
101
|
component: custom.component ?? 'ATextInput',
|
|
102
|
-
fieldtype: custom.fieldtype ?? 'Data',
|
|
103
102
|
...custom,
|
|
104
103
|
};
|
|
105
104
|
}
|
|
@@ -116,28 +115,30 @@ export function convertGraphQLSchema(source, options = {}) {
|
|
|
116
115
|
const links = {};
|
|
117
116
|
const convertedFields = allClassifiedFields
|
|
118
117
|
.filter(field => {
|
|
119
|
-
if (field._isLink &&
|
|
118
|
+
if (field._isLink && field.doctype && field.cardinality) {
|
|
120
119
|
links[field.fieldname] = {
|
|
121
|
-
target: field.
|
|
120
|
+
target: field.doctype,
|
|
122
121
|
cardinality: field.cardinality,
|
|
123
122
|
};
|
|
124
123
|
return false;
|
|
125
124
|
}
|
|
126
125
|
return true;
|
|
127
126
|
})
|
|
128
|
-
// Clean up internal metadata unless requested
|
|
127
|
+
// Clean up internal metadata unless requested, and stamp provenance.
|
|
128
|
+
// Stamped last so every classification path (default, classifyField,
|
|
129
|
+
// typeOverrides) carries the marker — the docbuilder's identity lock
|
|
130
|
+
// keys off it, and an override must not be able to unset it.
|
|
129
131
|
.map(field => {
|
|
130
132
|
if (!options.includeUnmappedMeta) {
|
|
131
133
|
const { _graphqlType, _unmapped, _isLink, ...clean } = field;
|
|
132
|
-
return clean;
|
|
134
|
+
return Object.assign(clean, { source: 'introspected' });
|
|
133
135
|
}
|
|
134
136
|
const { _isLink, ...rest } = field;
|
|
135
|
-
return rest;
|
|
137
|
+
return Object.assign(rest, { source: 'introspected' });
|
|
136
138
|
});
|
|
137
139
|
const doctype = {
|
|
138
140
|
name: typeName,
|
|
139
141
|
slug: toSlug(typeName),
|
|
140
|
-
// oxlint-disable-next-line typescript/no-unsafe-type-assertion -- safe: heuristics always set a fieldtype default ('Data'); the optional fieldtype on GraphQLConversionFieldMeta is for intermediate processing, not because output fields lack fieldtype
|
|
141
142
|
fields: convertedFields,
|
|
142
143
|
};
|
|
143
144
|
if (Object.keys(links).length > 0) {
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
*
|
|
9
9
|
* @packageDocumentation
|
|
10
10
|
*/
|
|
11
|
-
import type { FieldTemplate } from '
|
|
11
|
+
import type { FieldTemplate } from './types';
|
|
12
12
|
/**
|
|
13
13
|
* Mapping from standard GraphQL scalar types to Stonecrop field types.
|
|
14
14
|
* These are defined by the GraphQL specification and are always available.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scalars.d.ts","sourceRoot":"","sources":["../../../src/converter/scalars.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"scalars.d.ts","sourceRoot":"","sources":["../../../src/converter/scalars.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AAE5C;;;;;GAKG;AACH,eAAO,MAAM,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAMxD,CAAA;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAuB5D,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,aAAsB,CAAA;AAEnD;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,aAAa,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAgBpH"}
|
|
@@ -15,11 +15,11 @@
|
|
|
15
15
|
* @public
|
|
16
16
|
*/
|
|
17
17
|
export const GQL_SCALAR_MAP = {
|
|
18
|
-
String: { component: 'ATextInput'
|
|
19
|
-
Int: { component: 'ANumericInput'
|
|
20
|
-
Float: { component: 'ANumericInput'
|
|
21
|
-
Boolean: { component: 'ACheckbox'
|
|
22
|
-
ID: { component: 'ATextInput'
|
|
18
|
+
String: { component: 'ATextInput' },
|
|
19
|
+
Int: { component: 'ANumericInput' },
|
|
20
|
+
Float: { component: 'ANumericInput' },
|
|
21
|
+
Boolean: { component: 'ACheckbox' },
|
|
22
|
+
ID: { component: 'ATextInput' },
|
|
23
23
|
};
|
|
24
24
|
/**
|
|
25
25
|
* Mapping from well-known custom GraphQL scalars to Stonecrop field types.
|
|
@@ -32,25 +32,25 @@ export const GQL_SCALAR_MAP = {
|
|
|
32
32
|
* @public
|
|
33
33
|
*/
|
|
34
34
|
export const WELL_KNOWN_SCALARS = {
|
|
35
|
-
// Arbitrary precision / large numbers
|
|
36
|
-
BigFloat: { component: '
|
|
37
|
-
BigDecimal: { component: '
|
|
38
|
-
Decimal: { component: '
|
|
39
|
-
BigInt: { component: 'ANumericInput'
|
|
40
|
-
Long: { component: 'ANumericInput'
|
|
35
|
+
// Arbitrary precision / large numbers — all numeric variants render with ANumericInput.
|
|
36
|
+
BigFloat: { component: 'ANumericInput' },
|
|
37
|
+
BigDecimal: { component: 'ANumericInput' },
|
|
38
|
+
Decimal: { component: 'ANumericInput' },
|
|
39
|
+
BigInt: { component: 'ANumericInput' },
|
|
40
|
+
Long: { component: 'ANumericInput' },
|
|
41
41
|
// Identifiers
|
|
42
|
-
UUID: { component: 'ATextInput'
|
|
43
|
-
// Date / Time
|
|
44
|
-
DateTime: { component: '
|
|
45
|
-
Datetime: { component: '
|
|
46
|
-
Date: { component: 'ADate'
|
|
47
|
-
Time: { component: '
|
|
48
|
-
Interval: { component: '
|
|
49
|
-
Duration: { component: '
|
|
42
|
+
UUID: { component: 'ATextInput' },
|
|
43
|
+
// Date / Time — no dedicated Time SFC exists; Time falls back to a plain text input.
|
|
44
|
+
DateTime: { component: 'ADateTime' },
|
|
45
|
+
Datetime: { component: 'ADateTime' },
|
|
46
|
+
Date: { component: 'ADate' },
|
|
47
|
+
Time: { component: 'ATextInput' },
|
|
48
|
+
Interval: { component: 'ADuration' },
|
|
49
|
+
Duration: { component: 'ADuration' },
|
|
50
50
|
// Structured data
|
|
51
|
-
JSON: { component: 'ACodeEditor'
|
|
52
|
-
JSONObject: { component: 'ACodeEditor'
|
|
53
|
-
JsonNode: { component: 'ACodeEditor'
|
|
51
|
+
JSON: { component: 'ACodeEditor' },
|
|
52
|
+
JSONObject: { component: 'ACodeEditor' },
|
|
53
|
+
JsonNode: { component: 'ACodeEditor' },
|
|
54
54
|
};
|
|
55
55
|
/**
|
|
56
56
|
* Set of scalar type names that are internal to GraphQL servers and should be skipped
|
|
@@ -76,10 +76,7 @@ export function buildScalarMap(customScalars) {
|
|
|
76
76
|
// Custom scalars override everything
|
|
77
77
|
if (customScalars) {
|
|
78
78
|
for (const [key, value] of Object.entries(customScalars)) {
|
|
79
|
-
merged[key] = {
|
|
80
|
-
component: value.component ?? 'ATextInput',
|
|
81
|
-
fieldtype: value.fieldtype ?? 'Data',
|
|
82
|
-
};
|
|
79
|
+
merged[key] = { component: value.component ?? 'ATextInput' };
|
|
83
80
|
}
|
|
84
81
|
}
|
|
85
82
|
return merged;
|
|
@@ -6,7 +6,18 @@
|
|
|
6
6
|
import type { IntrospectionQuery } from 'graphql';
|
|
7
7
|
import type { GraphQLObjectType, GraphQLField } from 'graphql';
|
|
8
8
|
import type { ValueField } from '../field';
|
|
9
|
-
|
|
9
|
+
/**
|
|
10
|
+
* The component a GraphQL scalar maps to.
|
|
11
|
+
*
|
|
12
|
+
* A one-property interface rather than a bare string so `customScalars` stays extensible: an
|
|
13
|
+
* override is a `Partial<FieldTemplate>`, and widening this later does not change that signature.
|
|
14
|
+
*
|
|
15
|
+
* @public
|
|
16
|
+
*/
|
|
17
|
+
export interface FieldTemplate {
|
|
18
|
+
/** The Vue component name to render fields of this scalar type (e.g. `'ATextInput'`). */
|
|
19
|
+
component: string;
|
|
20
|
+
}
|
|
10
21
|
/**
|
|
11
22
|
* Input source for the GraphQL schema converter.
|
|
12
23
|
* Accepts either a standard GraphQL introspection result or an SDL string.
|
|
@@ -46,22 +57,22 @@ export interface GraphQLConversionOptions {
|
|
|
46
57
|
* ```typescript
|
|
47
58
|
* {
|
|
48
59
|
* SalesOrder: {
|
|
49
|
-
* totalAmount: {
|
|
60
|
+
* totalAmount: { component: 'ANumericInput', align: 'right' }
|
|
50
61
|
* }
|
|
51
62
|
* }
|
|
52
63
|
* ```
|
|
53
64
|
*/
|
|
54
65
|
typeOverrides?: Record<string, Record<string, Omit<Partial<ValueField>, 'kind'>>>;
|
|
55
66
|
/**
|
|
56
|
-
* Map custom or non-standard GraphQL scalar types to
|
|
67
|
+
* Map custom or non-standard GraphQL scalar types to the component that renders them.
|
|
57
68
|
* Merged with the built-in scalar maps (GQL_SCALAR_MAP + WELL_KNOWN_SCALARS).
|
|
58
69
|
* User-provided entries take highest precedence.
|
|
59
70
|
*
|
|
60
71
|
* @example
|
|
61
72
|
* ```typescript
|
|
62
73
|
* {
|
|
63
|
-
* MyCustomMoney: { component: '
|
|
64
|
-
* PostGISPoint: { component: 'ATextInput'
|
|
74
|
+
* MyCustomMoney: { component: 'ANumericInput' },
|
|
75
|
+
* PostGISPoint: { component: 'ATextInput' }
|
|
65
76
|
* }
|
|
66
77
|
* ```
|
|
67
78
|
*/
|
|
@@ -114,9 +125,7 @@ export interface GraphQLConversionOptions {
|
|
|
114
125
|
*
|
|
115
126
|
* @public
|
|
116
127
|
*/
|
|
117
|
-
export interface GraphQLConversionFieldMeta extends
|
|
118
|
-
/** Semantic field type - optional for link fields which don't have a fieldtype */
|
|
119
|
-
fieldtype?: string;
|
|
128
|
+
export interface GraphQLConversionFieldMeta extends ValueField {
|
|
120
129
|
/** Original GraphQL type name (for debugging/reference) */
|
|
121
130
|
_graphqlType?: string;
|
|
122
131
|
/** Marks fields that couldn't be automatically mapped */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/converter/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAA;AACjD,OAAO,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAE9D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/converter/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAA;AACjD,OAAO,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAE9D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AAE1C;;;;;;;GAOG;AACH,MAAM,WAAW,aAAa;IAC7B,yFAAyF;IACzF,SAAS,EAAE,MAAM,CAAA;CACjB;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,mBAAmB,GAAG,kBAAkB,GAAG,MAAM,CAAA;AAE7D;;;;;GAKG;AACH,MAAM,WAAW,wBAAwB;IACxC;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;IAElB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;IAElB;;;;;;;;;;;;OAYG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAA;IAEjF;;;;;;;;;;;;OAYG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,aAAa,CAAC,CAAC,CAAA;IAEtD;;;;;;;;;;;OAWG;IACH,YAAY,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,iBAAiB,KAAK,OAAO,CAAA;IAErE;;;;;;;;;;OAUG;IACH,aAAa,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE,UAAU,EAAE,iBAAiB,KAAK,OAAO,CAAA;IAEpH;;;;;;;;;OASG;IACH,aAAa,CAAC,EAAE,CACf,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,EACrC,UAAU,EAAE,iBAAiB,KACzB,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC,GAAG,IAAI,CAAA;IAE7C;;;OAGG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAA;CAC7B;AAED;;;;;GAKG;AACH,MAAM,WAAW,0BAA2B,SAAQ,UAAU;IAC7D,2DAA2D;IAC3D,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,yDAAyD;IACzD,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,qEAAqE;IACrE,OAAO,CAAC,EAAE,OAAO,CAAA;CACjB;AAED;;;;GAIG;AACH,MAAM,WAAW,uBAAwB,SAAQ,IAAI,CAAC,WAAW,EAAE,QAAQ,CAAC;IAC3E,iGAAiG;IACjG,MAAM,EAAE,UAAU,EAAE,CAAA;IACpB,2DAA2D;IAC3D,gBAAgB,CAAC,EAAE,MAAM,CAAA;CACzB;AAGD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA"}
|