@stonecrop/schema 0.30.0 → 0.32.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 +10 -10
- package/dist/cli.js +194 -121
- package/dist/cli.js.map +1 -1
- package/dist/converter-CLwduvT_.js +2102 -0
- package/dist/converter-CLwduvT_.js.map +1 -0
- package/dist/flatten-Bx2cfvw3.js +37 -0
- package/dist/flatten-Bx2cfvw3.js.map +1 -0
- package/dist/index.js +123 -117
- package/dist/index.js.map +1 -1
- package/dist/record-BQOOi83C.js +134 -0
- package/dist/record-BQOOi83C.js.map +1 -0
- package/dist/record.js +2 -6
- package/dist/tsdoc-metadata.json +1 -1
- package/package.json +34 -18
- package/dist/flatten-C1MjkzFh.js +0 -10
- package/dist/flatten-C1MjkzFh.js.map +0 -1
- package/dist/record-Bc0lI9Rq.js +0 -61
- package/dist/record-Bc0lI9Rq.js.map +0 -1
- package/dist/record.js.map +0 -1
- package/dist/schema.tsbuildinfo +0 -1
- package/dist/src/badge.d.ts +0 -74
- package/dist/src/badge.d.ts.map +0 -1
- package/dist/src/badge.js +0 -158
- package/dist/src/cli.d.ts +0 -3
- package/dist/src/cli.d.ts.map +0 -1
- package/dist/src/cli.js +0 -292
- package/dist/src/column-schema.d.ts +0 -163
- package/dist/src/column-schema.d.ts.map +0 -1
- package/dist/src/column-schema.js +0 -0
- package/dist/src/component-meta.d.ts +0 -96
- package/dist/src/component-meta.d.ts.map +0 -1
- package/dist/src/component-meta.js +0 -88
- package/dist/src/converter/aggregate.d.ts +0 -127
- package/dist/src/converter/aggregate.d.ts.map +0 -1
- package/dist/src/converter/aggregate.js +0 -235
- package/dist/src/converter/authored.d.ts +0 -43
- package/dist/src/converter/authored.d.ts.map +0 -1
- package/dist/src/converter/authored.js +0 -52
- package/dist/src/converter/heuristics.d.ts +0 -60
- package/dist/src/converter/heuristics.d.ts.map +0 -1
- package/dist/src/converter/heuristics.js +0 -304
- package/dist/src/converter/index.d.ts +0 -51
- package/dist/src/converter/index.d.ts.map +0 -1
- package/dist/src/converter/index.js +0 -195
- package/dist/src/converter/merge.d.ts +0 -102
- package/dist/src/converter/merge.d.ts.map +0 -1
- package/dist/src/converter/merge.js +0 -136
- package/dist/src/converter/scalars.d.ts +0 -46
- package/dist/src/converter/scalars.d.ts.map +0 -1
- package/dist/src/converter/scalars.js +0 -83
- package/dist/src/converter/types.d.ts +0 -157
- package/dist/src/converter/types.d.ts.map +0 -1
- package/dist/src/converter/types.js +0 -5
- package/dist/src/doctype.d.ts +0 -516
- package/dist/src/doctype.d.ts.map +0 -1
- package/dist/src/doctype.js +0 -343
- package/dist/src/field.d.ts +0 -423
- package/dist/src/field.d.ts.map +0 -1
- package/dist/src/field.js +0 -378
- package/dist/src/flatten.d.ts +0 -29
- package/dist/src/flatten.d.ts.map +0 -1
- package/dist/src/flatten.js +0 -38
- package/dist/src/index.d.ts +0 -16
- package/dist/src/index.d.ts.map +0 -1
- package/dist/src/index.js +0 -20
- package/dist/src/mode.d.ts +0 -15
- package/dist/src/mode.d.ts.map +0 -1
- package/dist/src/mode.js +0 -0
- package/dist/src/naming.d.ts +0 -80
- package/dist/src/naming.d.ts.map +0 -1
- package/dist/src/naming.js +0 -106
- package/dist/src/record.d.ts +0 -29
- package/dist/src/record.d.ts.map +0 -1
- package/dist/src/record.js +0 -55
- package/dist/src/table.d.ts +0 -33
- package/dist/src/table.d.ts.map +0 -1
- package/dist/src/table.js +0 -25
- package/dist/src/validation.d.ts +0 -54
- package/dist/src/validation.d.ts.map +0 -1
- package/dist/src/validation.js +0 -60
- package/dist/validation-C9P__pRF.js +0 -994
- package/dist/validation-C9P__pRF.js.map +0 -1
|
@@ -1,163 +0,0 @@
|
|
|
1
|
-
import type { FieldOptions } from './field';
|
|
2
|
-
/**
|
|
3
|
-
* Authoring contract for doctype field declarations that can be rendered as table columns.
|
|
4
|
-
* Pass a `ColumnSchema[]` array to ATable's `:schema` prop; `schemaToColumns` converts it
|
|
5
|
-
* to `TableColumn[]` internally — callers working from a doctype schema never need to
|
|
6
|
-
* construct `TableColumn` directly.
|
|
7
|
-
*
|
|
8
|
-
* Notes on specific properties:
|
|
9
|
-
* - `align` uses an explicit string union rather than `CanvasTextAlign` — this package is
|
|
10
|
-
* used server-side by the CLI where browser DOM types are absent. The values are identical.
|
|
11
|
-
* - `format` is a serialized function string; the table store's `getFormattedValue` deserializes
|
|
12
|
-
* it via `Function(...)`. `TableColumn.format` widens this to also accept a live function.
|
|
13
|
-
* - `mask` is absent — it is function-typed only and cannot be serialized to JSON. It lives
|
|
14
|
-
* exclusively on `TableColumn`.
|
|
15
|
-
* - `modalComponent` is string-only — functions cannot appear in schema JSON. `TableColumn`
|
|
16
|
-
* widens this to also accept a factory function.
|
|
17
|
-
*
|
|
18
|
-
* @public
|
|
19
|
-
*/
|
|
20
|
-
export interface ColumnSchema {
|
|
21
|
-
/** Unique identifier for the field within its doctype. Maps to `name` on `TableColumn`. */
|
|
22
|
-
fieldname: string;
|
|
23
|
-
/**
|
|
24
|
-
* Rendering component (e.g. `'ATextInput'`, `'ANumericInput'`, `'ADate'`). Default cell
|
|
25
|
-
* formatting and filter widgets derive from its {@link ComponentCategory}.
|
|
26
|
-
*
|
|
27
|
-
* Optional here, unlike `ValueField.component`: absence is what marks an entry as non-scalar
|
|
28
|
-
* (a nested table or fieldset), which `schemaToColumns` excludes — it has no column equivalent.
|
|
29
|
-
*/
|
|
30
|
-
component?: string;
|
|
31
|
-
/**
|
|
32
|
-
* Target doctype slug — marks this column as a link. When set and no `cellComponent` is given,
|
|
33
|
-
* `schemaToColumns` copies it to `TableColumn.linkDoctype`, which ACell uses to resolve a bare
|
|
34
|
-
* id to display text.
|
|
35
|
-
*/
|
|
36
|
-
doctype?: string;
|
|
37
|
-
/**
|
|
38
|
-
* Human-readable column header. When absent, ATable assigns labels alphabetically
|
|
39
|
-
* (A, B, C, …).
|
|
40
|
-
*/
|
|
41
|
-
label?: string;
|
|
42
|
-
/** When `true`, the field is excluded from the derived columns by `schemaToColumns`. */
|
|
43
|
-
hidden?: boolean;
|
|
44
|
-
/**
|
|
45
|
-
* Horizontal text alignment for the column cell and header.
|
|
46
|
-
*
|
|
47
|
-
* @defaultValue 'center'
|
|
48
|
-
*/
|
|
49
|
-
align?: 'left' | 'right' | 'center' | 'start' | 'end';
|
|
50
|
-
/**
|
|
51
|
-
* Whether the column cell is editable in the table.
|
|
52
|
-
*
|
|
53
|
-
* @defaultValue false
|
|
54
|
-
*/
|
|
55
|
-
edit?: boolean;
|
|
56
|
-
/**
|
|
57
|
-
* CSS width of the column (e.g. `'20ch'`, `'200px'`).
|
|
58
|
-
*
|
|
59
|
-
* @defaultValue '40ch'
|
|
60
|
-
*/
|
|
61
|
-
width?: string;
|
|
62
|
-
/**
|
|
63
|
-
* When `true`, the column is pinned to the left side of the table.
|
|
64
|
-
*
|
|
65
|
-
* @defaultValue false
|
|
66
|
-
*/
|
|
67
|
-
pinned?: boolean;
|
|
68
|
-
/**
|
|
69
|
-
* When `true`, the column can be resized by dragging the header edge.
|
|
70
|
-
*
|
|
71
|
-
* @defaultValue false
|
|
72
|
-
*/
|
|
73
|
-
resizable?: boolean;
|
|
74
|
-
/**
|
|
75
|
-
* When `true`, clicking the column header sorts the table by this column.
|
|
76
|
-
*
|
|
77
|
-
* @defaultValue true
|
|
78
|
-
*/
|
|
79
|
-
sortable?: boolean;
|
|
80
|
-
/**
|
|
81
|
-
* When `true`, a filter control is rendered in the column header.
|
|
82
|
-
*
|
|
83
|
-
* @defaultValue true
|
|
84
|
-
*/
|
|
85
|
-
filterable?: boolean;
|
|
86
|
-
/**
|
|
87
|
-
* The type of filter control to render. When absent, a default is derived from the
|
|
88
|
-
* `component`'s {@link ComponentCategory} (`boolean` → `checkbox`, `date` → `date`,
|
|
89
|
-
* `datetime` → `dateRange`, `select` → `select`, `number` → `number`, everything else
|
|
90
|
-
* — including an unknown component — → `text`).
|
|
91
|
-
*/
|
|
92
|
-
filterType?: 'text' | 'select' | 'number' | 'date' | 'dateRange' | 'checkbox' | 'component';
|
|
93
|
-
/**
|
|
94
|
-
* Static option list for `filterType: 'select'`. When absent, options are derived from
|
|
95
|
-
* the unique values present in the column's rows.
|
|
96
|
-
*/
|
|
97
|
-
filterOptions?: any[];
|
|
98
|
-
/** Registered component name used when `filterType` is `'component'`. */
|
|
99
|
-
filterComponent?: string;
|
|
100
|
-
/**
|
|
101
|
-
* Registered component name rendered inside the table cell instead of the default display.
|
|
102
|
-
* When absent, the table renders the value as plain text in a `<td>`.
|
|
103
|
-
*/
|
|
104
|
-
cellComponent?: string;
|
|
105
|
-
/**
|
|
106
|
-
* Additional props passed to `cellComponent`.
|
|
107
|
-
*
|
|
108
|
-
* Only applicable when `cellComponent` is set.
|
|
109
|
-
*/
|
|
110
|
-
cellComponentProps?: Record<string, any>;
|
|
111
|
-
/**
|
|
112
|
-
* Registered component name rendered in the cell's modal editor. String-only — functions
|
|
113
|
-
* cannot appear in schema JSON. `TableColumn.modalComponent` widens this to also accept a
|
|
114
|
-
* factory function.
|
|
115
|
-
*
|
|
116
|
-
* The following props are automatically passed to the modal component:
|
|
117
|
-
* - `colIndex` — the column index of the current cell
|
|
118
|
-
* - `rowIndex` — the row index of the current cell
|
|
119
|
-
* - `store` — the table data store
|
|
120
|
-
*/
|
|
121
|
-
modalComponent?: string;
|
|
122
|
-
/**
|
|
123
|
-
* Extra props passed to `modalComponent` in addition to the standard cell props.
|
|
124
|
-
*
|
|
125
|
-
* Only applicable when `modalComponent` is set.
|
|
126
|
-
*/
|
|
127
|
-
modalComponentExtraProps?: Record<string, any>;
|
|
128
|
-
/**
|
|
129
|
-
* Type-specific field options — Select choices, badge maps, quantity/currency config, etc.
|
|
130
|
-
* Spreads through `schemaToColumns` to `TableColumn`.
|
|
131
|
-
*/
|
|
132
|
-
options?: FieldOptions;
|
|
133
|
-
/**
|
|
134
|
-
* Serialized function string used to format the cell value for display. Deserialized at
|
|
135
|
-
* render time by the table store's `getFormattedValue`. May return a plain string, HTML, or a
|
|
136
|
-
* {@link BadgeDescriptor}. `TableColumn.format` widens this to also accept a live function.
|
|
137
|
-
*/
|
|
138
|
-
format?: string;
|
|
139
|
-
/**
|
|
140
|
-
* When `true`, this column is treated as a Gantt bar column.
|
|
141
|
-
*
|
|
142
|
-
* Only applicable for Gantt tables.
|
|
143
|
-
*
|
|
144
|
-
* @defaultValue false
|
|
145
|
-
*/
|
|
146
|
-
isGantt?: boolean;
|
|
147
|
-
/**
|
|
148
|
-
* Registered component name used to render Gantt bars in this column.
|
|
149
|
-
*
|
|
150
|
-
* Only applicable for Gantt tables.
|
|
151
|
-
*
|
|
152
|
-
* @defaultValue 'AGanttCell'
|
|
153
|
-
*/
|
|
154
|
-
ganttComponent?: string;
|
|
155
|
-
/**
|
|
156
|
-
* Number of columns this Gantt bar spans across. When absent, the bar stretches to cover
|
|
157
|
-
* all non-pinned columns in the table.
|
|
158
|
-
*
|
|
159
|
-
* Only applicable for Gantt tables.
|
|
160
|
-
*/
|
|
161
|
-
colspan?: number;
|
|
162
|
-
}
|
|
163
|
-
//# sourceMappingURL=column-schema.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"column-schema.d.ts","sourceRoot":"","sources":["../../src/column-schema.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAE3C;;;;;;;;;;;;;;;;;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;;;OAGG;IACH,OAAO,CAAC,EAAE,YAAY,CAAA;IAEtB;;;;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"}
|
|
File without changes
|
|
@@ -1,96 +0,0 @@
|
|
|
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' | 'quantity' | 'currency';
|
|
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
|
|
@@ -1 +0,0 @@
|
|
|
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,GAAG,UAAU,GAAG,UAAU,CAAA;AAEtH;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAkBhE,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"}
|
|
@@ -1,88 +0,0 @@
|
|
|
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
|
-
ATextboxInput: '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
|
-
ASegmentedControl: 'select',
|
|
19
|
-
ACodeEditor: 'code',
|
|
20
|
-
AFormLink: 'link',
|
|
21
|
-
AFileAttach: 'attach',
|
|
22
|
-
AQuantityInput: 'quantity',
|
|
23
|
-
ACurrencyInput: 'currency',
|
|
24
|
-
};
|
|
25
|
-
/**
|
|
26
|
-
* Resolve a component's semantic category, or `undefined` for an unknown (custom) component —
|
|
27
|
-
* callers treat that as "no opinion" and use their own default.
|
|
28
|
-
* @public
|
|
29
|
-
*/
|
|
30
|
-
export function componentCategory(component) {
|
|
31
|
-
return component ? COMPONENT_CATEGORY[component] : undefined;
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* Canonical link component → expansion. Only components Stonecrop ships with appear here; an
|
|
35
|
-
* unmapped (custom) component has none, and callers treat that as `expand` — the behaviour that
|
|
36
|
-
* predates this map, so a custom component can never silently collapse a link to a picker.
|
|
37
|
-
* @public
|
|
38
|
-
*/
|
|
39
|
-
export const COMPONENT_LINK_EXPANSION = {
|
|
40
|
-
AFormLink: 'inline',
|
|
41
|
-
AForm: 'expand',
|
|
42
|
-
ATable: 'expand',
|
|
43
|
-
};
|
|
44
|
-
/**
|
|
45
|
-
* Resolve a component's link expansion, or `undefined` for an absent/unmapped component.
|
|
46
|
-
* @public
|
|
47
|
-
*/
|
|
48
|
-
export function componentLinkExpansion(component) {
|
|
49
|
-
return component ? COMPONENT_LINK_EXPANSION[component] : undefined;
|
|
50
|
-
}
|
|
51
|
-
/**
|
|
52
|
-
* Decide how a *declared* link (one with a `LinkDeclaration`) renders.
|
|
53
|
-
*
|
|
54
|
-
* Two independent axes: the **component** picks inline vs expand, and when expanding the
|
|
55
|
-
* **cardinality** picks record vs table (many → table). The declaration's component wins over the
|
|
56
|
-
* field's, matching the precedence the resolver already uses for the rendered component.
|
|
57
|
-
*
|
|
58
|
-
* This is the single definition of "does this link expand" — it is consumed by both the client
|
|
59
|
-
* resolver (which builds the nested schema) and the server column builder (which must still
|
|
60
|
-
* SELECT an `inline` link's FK column). Call it; never re-derive the rule at the call site, or
|
|
61
|
-
* the two will drift and the client will render a table for a column the server never selected.
|
|
62
|
-
*
|
|
63
|
-
* @param link - the link declaration (only `component` and `cardinality` are consulted)
|
|
64
|
-
* @param fieldComponent - the linked field's own `component`, used when the declaration names none
|
|
65
|
-
* @public
|
|
66
|
-
*/
|
|
67
|
-
export function resolveLinkRenderMode(link, fieldComponent) {
|
|
68
|
-
if (componentLinkExpansion(link.component ?? fieldComponent) === 'inline')
|
|
69
|
-
return 'inline';
|
|
70
|
-
return link.cardinality === 'noneOrMany' || link.cardinality === 'atLeastOne' ? 'table' : 'record';
|
|
71
|
-
}
|
|
72
|
-
/**
|
|
73
|
-
* Every component Stonecrop ships with that can render a value field, sorted by name.
|
|
74
|
-
*
|
|
75
|
-
* The union of the two maps above is the definition, not a copy of it: a shipped component either
|
|
76
|
-
* categorises a value ({@link COMPONENT_CATEGORY}) or is one of the link containers that has no
|
|
77
|
-
* value of its own ({@link COMPONENT_LINK_EXPANSION}'s `AForm`/`ATable`). `AFieldset` is absent by
|
|
78
|
-
* the same rule — it is a `kind: 'fieldset'` container, so it is never a value field's component.
|
|
79
|
-
*
|
|
80
|
-
* `component` is an **open** axis: any string is valid, and naming a custom component is how an app
|
|
81
|
-
* renders a field Stonecrop ships no widget for. This list is therefore the set to *suggest* to an
|
|
82
|
-
* author, and to check first-party data against — never a set to validate arbitrary input against.
|
|
83
|
-
*
|
|
84
|
-
* @public
|
|
85
|
-
*/
|
|
86
|
-
export const CANONICAL_COMPONENTS = [
|
|
87
|
-
...new Set([...Object.keys(COMPONENT_CATEGORY), ...Object.keys(COMPONENT_LINK_EXPANSION)]),
|
|
88
|
-
].toSorted();
|
|
@@ -1,127 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Aggregate doctype derivation.
|
|
3
|
-
*
|
|
4
|
-
* A table gets two generated doctypes: the entity itself, whose `fields` carry every column and
|
|
5
|
-
* which backs the record form, and an **aggregate** — the collection view over the same table.
|
|
6
|
-
* The aggregate starts with identity alone, because the useful default for a collection is the
|
|
7
|
-
* one column that lets a row be opened, not all forty. Widening it is curation, and curation
|
|
8
|
-
* survives regeneration (see `mergeIntrospectedDoctype`).
|
|
9
|
-
*
|
|
10
|
-
* The two are peers: each is a complete doctype with its own `name` and `slug`, and nothing here
|
|
11
|
-
* encodes a relationship between them. Deriving the aggregate's name from the entity's is a
|
|
12
|
-
* generated encoding, not a readable one — no consumer recovers the pair by parsing a slug.
|
|
13
|
-
*
|
|
14
|
-
* @packageDocumentation
|
|
15
|
-
*/
|
|
16
|
-
import type { ConvertedGraphQLDoctype } from './types';
|
|
17
|
-
/**
|
|
18
|
-
* The name an entity's aggregate doctype is generated under: the entity's name, pluralised.
|
|
19
|
-
*
|
|
20
|
-
* One definition, because the CLI writes the file under `toSlug` of this and any later caller
|
|
21
|
-
* (a scaffolder, a docs generator) must land on the same name or it silently addresses a
|
|
22
|
-
* different file.
|
|
23
|
-
*
|
|
24
|
-
* `pluralize` rather than appending `s`, because the irregulars are not rare in practice —
|
|
25
|
-
* measured against a consumer's 41 hand-authored aggregate doctypes, this rule reproduces every
|
|
26
|
-
* one of their names, slugs and filenames exactly, while `+ 's'` gets five wrong
|
|
27
|
-
* (`Currencys`, `JournalEntrys`, …).
|
|
28
|
-
*
|
|
29
|
-
* The rule is not total: an already-plural name pluralises to itself. Callers must handle that —
|
|
30
|
-
* see {@link buildAggregateDoctype}.
|
|
31
|
-
*
|
|
32
|
-
* @param doctypeName - the entity doctype's `name`
|
|
33
|
-
* @returns the aggregate doctype's `name`
|
|
34
|
-
* @public
|
|
35
|
-
*
|
|
36
|
-
* @example
|
|
37
|
-
* ```typescript
|
|
38
|
-
* aggregateDoctypeName('SalesOrder') // 'SalesOrders' -> slug 'sales-orders'
|
|
39
|
-
* ```
|
|
40
|
-
*/
|
|
41
|
-
export declare function aggregateDoctypeName(doctypeName: string): string;
|
|
42
|
-
/**
|
|
43
|
-
* Derive the aggregate doctype for a converted entity.
|
|
44
|
-
*
|
|
45
|
-
* Returns `undefined` when no identity column can be found — a natural-key table whose key the
|
|
46
|
-
* converter refuses to guess and whose author has not declared one, or a foreign PostGraphile
|
|
47
|
-
* endpoint that has left the Relay identifier occupying `id` (Stonecrop's own preset moves it to
|
|
48
|
-
* `nodeId`). That is deliberate: an aggregate with an empty `fields` array is a valid doctype that
|
|
49
|
-
* renders a table with no columns, which looks like a data problem rather than a generation one.
|
|
50
|
-
* Emitting nothing and saying so is the loud failure.
|
|
51
|
-
*
|
|
52
|
-
* Identity resolves the same way `getRecordIdField` resolves it — the declared `primaryKey`, then
|
|
53
|
-
* the conventional `id` — so an aggregate is always keyed on the column the client will later ask
|
|
54
|
-
* for. `declaredIdentity` overrides both: SDL cannot express which `UNIQUE` column is the key, so
|
|
55
|
-
* for a natural-key table the answer only exists in the authored file, and the caller that read it
|
|
56
|
-
* passes the fieldname back.
|
|
57
|
-
*
|
|
58
|
-
* @param doctype - a converted entity doctype, as returned by `convertGraphQLSchema`
|
|
59
|
-
* @param declaredIdentity - fieldname the authored doctype declares as its `primaryKey`, when the
|
|
60
|
-
* caller has read one. Must name a field the converter emitted; the caller checks that, because
|
|
61
|
-
* only it can say whether a missing one is a dropped column or a typo.
|
|
62
|
-
* @returns the aggregate doctype, or `undefined` when no identity column exists
|
|
63
|
-
* @public
|
|
64
|
-
*
|
|
65
|
-
* @example
|
|
66
|
-
* ```typescript
|
|
67
|
-
* const [order] = convertGraphQLSchema(sdl, { include: ['Order'] })
|
|
68
|
-
* const aggregate = buildAggregateDoctype(order)
|
|
69
|
-
* // { name: 'Orders', slug: 'orders', fields: [ the id field ] }
|
|
70
|
-
* ```
|
|
71
|
-
*/
|
|
72
|
-
export declare function buildAggregateDoctype(doctype: ConvertedGraphQLDoctype, declaredIdentity?: string): ConvertedGraphQLDoctype | undefined;
|
|
73
|
-
/**
|
|
74
|
-
* One file the generator will write, and what that file is verified against.
|
|
75
|
-
*
|
|
76
|
-
* `basis` exists because the two are not always the same document. An aggregate is written from
|
|
77
|
-
* its own one-field generation but verified against the **entity**, since its purpose is to carry
|
|
78
|
-
* fewer columns than the table — checking it against itself reports every curated column as one
|
|
79
|
-
* the table had dropped.
|
|
80
|
-
*
|
|
81
|
-
* @public
|
|
82
|
-
*/
|
|
83
|
-
export interface GenerationPlanEntry {
|
|
84
|
-
/** The doctype to write. */
|
|
85
|
-
generated: ConvertedGraphQLDoctype;
|
|
86
|
-
/** The doctype whose fields an existing file on disk is verified against. */
|
|
87
|
-
basis: ConvertedGraphQLDoctype;
|
|
88
|
-
/** Whether the file is a curated subset of `basis` — passed through to `MergeOptions.subset`. */
|
|
89
|
-
subset: boolean;
|
|
90
|
-
}
|
|
91
|
-
/** Options for {@link planGeneration}. @public */
|
|
92
|
-
export interface GenerationPlanOptions {
|
|
93
|
-
/** Emit only the entity doctypes, skipping their aggregates. Defaults to `false`. */
|
|
94
|
-
noAggregates?: boolean;
|
|
95
|
-
/** Called with an advisory message for each entity that yields no aggregate. */
|
|
96
|
-
onWarning?: (message: string) => void;
|
|
97
|
-
/**
|
|
98
|
-
* Identity the authored doctype on disk declares, keyed by doctype `name`.
|
|
99
|
-
*
|
|
100
|
-
* SDL cannot say which `UNIQUE` column is a table's key, so for a natural-key table the converter
|
|
101
|
-
* derives nothing and the answer exists only in the file. Without this the aggregate is
|
|
102
|
-
* unreachable: generation says "declare a primaryKey and re-run", and re-running after declaring
|
|
103
|
-
* one changes nothing, because planning never reads the file.
|
|
104
|
-
*
|
|
105
|
-
* Passed in rather than read here so this stays a pure function of its inputs; the CLI owns the
|
|
106
|
-
* IO. The plan is then a function of the schema *and* what is already on disk.
|
|
107
|
-
*/
|
|
108
|
-
identity?: Record<string, string>;
|
|
109
|
-
}
|
|
110
|
-
/**
|
|
111
|
-
* Expand converted entities into the set of doctype files to write.
|
|
112
|
-
*
|
|
113
|
-
* Each table yields two: the entity, whose fields carry every column and which backs the record
|
|
114
|
-
* form, and its aggregate — the collection view. They are written as peers, one file each, with
|
|
115
|
-
* no key relating them.
|
|
116
|
-
*
|
|
117
|
-
* Separate from the CLI because the pairing of a file to its verification basis is the part that
|
|
118
|
-
* is easy to get wrong and impossible to notice: getting it wrong does not throw, it just reports
|
|
119
|
-
* drift that is not there, forever.
|
|
120
|
-
*
|
|
121
|
-
* @param entities - `convertGraphQLSchema` output
|
|
122
|
-
* @param options - see {@link GenerationPlanOptions}
|
|
123
|
-
* @returns one entry per file to write
|
|
124
|
-
* @public
|
|
125
|
-
*/
|
|
126
|
-
export declare function planGeneration(entities: readonly ConvertedGraphQLDoctype[], options?: GenerationPlanOptions): GenerationPlanEntry[];
|
|
127
|
-
//# sourceMappingURL=aggregate.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"aggregate.d.ts","sourceRoot":"","sources":["../../../src/converter/aggregate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAQH,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,SAAS,CAAA;AAEtD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAEhE;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAgB,qBAAqB,CACpC,OAAO,EAAE,uBAAuB,EAChC,gBAAgB,CAAC,EAAE,MAAM,GACvB,uBAAuB,GAAG,SAAS,CAyBrC;AAkED;;;;;;;;;GASG;AACH,MAAM,WAAW,mBAAmB;IACnC,4BAA4B;IAC5B,SAAS,EAAE,uBAAuB,CAAA;IAClC,6EAA6E;IAC7E,KAAK,EAAE,uBAAuB,CAAA;IAC9B,iGAAiG;IACjG,MAAM,EAAE,OAAO,CAAA;CACf;AAED,kDAAkD;AAClD,MAAM,WAAW,qBAAqB;IACrC,qFAAqF;IACrF,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,gFAAgF;IAChF,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;IACrC;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CACjC;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,cAAc,CAC7B,QAAQ,EAAE,SAAS,uBAAuB,EAAE,EAC5C,OAAO,GAAE,qBAA0B,GACjC,mBAAmB,EAAE,CAmEvB"}
|