@stonecrop/schema 0.13.14 → 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-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-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-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
package/dist/src/doctype.d.ts
CHANGED
|
@@ -116,17 +116,87 @@ export type LinkDeclaration = z.infer<typeof LinkDeclaration>;
|
|
|
116
116
|
*/
|
|
117
117
|
export declare const ActionDefinition: z.ZodObject<{
|
|
118
118
|
label: z.ZodString;
|
|
119
|
-
handler: z.ZodString;
|
|
120
119
|
requiredFields: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
121
120
|
allowedStates: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
122
|
-
|
|
123
|
-
|
|
121
|
+
nextState: z.ZodOptional<z.ZodString>;
|
|
122
|
+
stateless: z.ZodOptional<z.ZodBoolean>;
|
|
123
|
+
selfTransition: z.ZodOptional<z.ZodBoolean>;
|
|
124
|
+
clientHandler: z.ZodOptional<z.ZodString>;
|
|
124
125
|
}, z.core.$strip>;
|
|
125
126
|
/**
|
|
126
127
|
* Action definition type inferred from Zod schema
|
|
127
128
|
* @public
|
|
128
129
|
*/
|
|
129
130
|
export type ActionDefinition = z.infer<typeof ActionDefinition>;
|
|
131
|
+
/**
|
|
132
|
+
* Reactive field-validation trigger — advisory, client-side only.
|
|
133
|
+
*
|
|
134
|
+
* A Trigger is a docbuilder-authored validator: when any field in `on` is edited, its
|
|
135
|
+
* `clientHandler` runs (client-side, no rollback) and may flag a field inline to block save
|
|
136
|
+
* in the UI. It is deliberately a **sibling** to {@link (ActionDefinition:type)}, not a member of it —
|
|
137
|
+
* a reactive validator is not a user-invoked action, so it lives in the `triggers` map on
|
|
138
|
+
* {@link (WorkflowMeta:type)} and never appears to action readers (transition/command dropdowns, the FSM graph).
|
|
139
|
+
*
|
|
140
|
+
* The two bindings are independent: `on` is the fire-set (which fields' edits run it), while the
|
|
141
|
+
* `setError(field, msg)` call inside `clientHandler` chooses which field displays the error.
|
|
142
|
+
* @public
|
|
143
|
+
*/
|
|
144
|
+
export declare const TriggerDefinition: z.ZodObject<{
|
|
145
|
+
label: z.ZodOptional<z.ZodString>;
|
|
146
|
+
on: z.ZodArray<z.ZodString>;
|
|
147
|
+
clientHandler: z.ZodString;
|
|
148
|
+
}, z.core.$strip>;
|
|
149
|
+
/**
|
|
150
|
+
* Trigger definition type inferred from Zod schema
|
|
151
|
+
* @public
|
|
152
|
+
*/
|
|
153
|
+
export type TriggerDefinition = z.infer<typeof TriggerDefinition>;
|
|
154
|
+
/**
|
|
155
|
+
* Whether a workflow action may run from `currentState`.
|
|
156
|
+
*
|
|
157
|
+
* Single source of truth for the "is this action available here" rule, shared by
|
|
158
|
+
* the frontend (`getAvailableTransitions`) and the server-side dispatch guard so
|
|
159
|
+
* the two can never disagree. Empty or absent `allowedStates` means the action is
|
|
160
|
+
* available in ALL states — a plain `allowedStates.includes(currentState)` would
|
|
161
|
+
* wrongly block such actions everywhere.
|
|
162
|
+
*
|
|
163
|
+
* @public
|
|
164
|
+
*/
|
|
165
|
+
export declare function isActionAllowedInState(action: {
|
|
166
|
+
allowedStates?: string[] | null;
|
|
167
|
+
}, currentState: string): boolean;
|
|
168
|
+
/**
|
|
169
|
+
* DocBuilder graph layout — node positions for the workflow-state graph, keyed by state name.
|
|
170
|
+
* Pure authoring view-state: persisted in the doctype JSON so an author's manual arrangement
|
|
171
|
+
* survives reloads, but — exactly like {@link (WorkflowMeta:type)}'s `triggers` — it is client-only
|
|
172
|
+
* and never mirrored into the runtime GraphQL SDL (see the WorkflowMeta type in the host SDLs, which
|
|
173
|
+
* expose only `states`/`actions`). The shape mirrors VueFlow's node fields; `position` is the node's
|
|
174
|
+
* canvas coordinate and `targetPosition`/`sourcePosition` are the handle sides.
|
|
175
|
+
* @public
|
|
176
|
+
*/
|
|
177
|
+
export declare const WorkflowLayout: z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
178
|
+
position: z.ZodOptional<z.ZodObject<{
|
|
179
|
+
x: z.ZodNumber;
|
|
180
|
+
y: z.ZodNumber;
|
|
181
|
+
}, z.core.$strip>>;
|
|
182
|
+
targetPosition: z.ZodOptional<z.ZodEnum<{
|
|
183
|
+
left: "left";
|
|
184
|
+
right: "right";
|
|
185
|
+
top: "top";
|
|
186
|
+
bottom: "bottom";
|
|
187
|
+
}>>;
|
|
188
|
+
sourcePosition: z.ZodOptional<z.ZodEnum<{
|
|
189
|
+
left: "left";
|
|
190
|
+
right: "right";
|
|
191
|
+
top: "top";
|
|
192
|
+
bottom: "bottom";
|
|
193
|
+
}>>;
|
|
194
|
+
}, z.core.$strip>>;
|
|
195
|
+
/**
|
|
196
|
+
* Workflow layout type inferred from Zod schema
|
|
197
|
+
* @public
|
|
198
|
+
*/
|
|
199
|
+
export type WorkflowLayout = z.infer<typeof WorkflowLayout>;
|
|
130
200
|
/**
|
|
131
201
|
* Workflow metadata - states and actions for a doctype
|
|
132
202
|
* @public
|
|
@@ -135,11 +205,35 @@ export declare const WorkflowMeta: z.ZodObject<{
|
|
|
135
205
|
states: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
136
206
|
actions: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
137
207
|
label: z.ZodString;
|
|
138
|
-
handler: z.ZodString;
|
|
139
208
|
requiredFields: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
140
209
|
allowedStates: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
141
|
-
|
|
142
|
-
|
|
210
|
+
nextState: z.ZodOptional<z.ZodString>;
|
|
211
|
+
stateless: z.ZodOptional<z.ZodBoolean>;
|
|
212
|
+
selfTransition: z.ZodOptional<z.ZodBoolean>;
|
|
213
|
+
clientHandler: z.ZodOptional<z.ZodString>;
|
|
214
|
+
}, z.core.$strip>>>;
|
|
215
|
+
triggers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
216
|
+
label: z.ZodOptional<z.ZodString>;
|
|
217
|
+
on: z.ZodArray<z.ZodString>;
|
|
218
|
+
clientHandler: z.ZodString;
|
|
219
|
+
}, z.core.$strip>>>;
|
|
220
|
+
layout: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
221
|
+
position: z.ZodOptional<z.ZodObject<{
|
|
222
|
+
x: z.ZodNumber;
|
|
223
|
+
y: z.ZodNumber;
|
|
224
|
+
}, z.core.$strip>>;
|
|
225
|
+
targetPosition: z.ZodOptional<z.ZodEnum<{
|
|
226
|
+
left: "left";
|
|
227
|
+
right: "right";
|
|
228
|
+
top: "top";
|
|
229
|
+
bottom: "bottom";
|
|
230
|
+
}>>;
|
|
231
|
+
sourcePosition: z.ZodOptional<z.ZodEnum<{
|
|
232
|
+
left: "left";
|
|
233
|
+
right: "right";
|
|
234
|
+
top: "top";
|
|
235
|
+
bottom: "bottom";
|
|
236
|
+
}>>;
|
|
143
237
|
}, z.core.$strip>>>;
|
|
144
238
|
}, z.core.$strip>;
|
|
145
239
|
/**
|
|
@@ -181,11 +275,35 @@ export declare const DoctypeMeta: z.ZodObject<{
|
|
|
181
275
|
states: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
182
276
|
actions: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
183
277
|
label: z.ZodString;
|
|
184
|
-
handler: z.ZodString;
|
|
185
278
|
requiredFields: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
186
279
|
allowedStates: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
187
|
-
|
|
188
|
-
|
|
280
|
+
nextState: z.ZodOptional<z.ZodString>;
|
|
281
|
+
stateless: z.ZodOptional<z.ZodBoolean>;
|
|
282
|
+
selfTransition: z.ZodOptional<z.ZodBoolean>;
|
|
283
|
+
clientHandler: z.ZodOptional<z.ZodString>;
|
|
284
|
+
}, z.core.$strip>>>;
|
|
285
|
+
triggers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
286
|
+
label: z.ZodOptional<z.ZodString>;
|
|
287
|
+
on: z.ZodArray<z.ZodString>;
|
|
288
|
+
clientHandler: z.ZodString;
|
|
289
|
+
}, z.core.$strip>>>;
|
|
290
|
+
layout: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
291
|
+
position: z.ZodOptional<z.ZodObject<{
|
|
292
|
+
x: z.ZodNumber;
|
|
293
|
+
y: z.ZodNumber;
|
|
294
|
+
}, z.core.$strip>>;
|
|
295
|
+
targetPosition: z.ZodOptional<z.ZodEnum<{
|
|
296
|
+
left: "left";
|
|
297
|
+
right: "right";
|
|
298
|
+
top: "top";
|
|
299
|
+
bottom: "bottom";
|
|
300
|
+
}>>;
|
|
301
|
+
sourcePosition: z.ZodOptional<z.ZodEnum<{
|
|
302
|
+
left: "left";
|
|
303
|
+
right: "right";
|
|
304
|
+
top: "top";
|
|
305
|
+
bottom: "bottom";
|
|
306
|
+
}>>;
|
|
189
307
|
}, z.core.$strip>>>;
|
|
190
308
|
}, z.core.$strip>>;
|
|
191
309
|
inherits: z.ZodOptional<z.ZodString>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"doctype.d.ts","sourceRoot":"","sources":["../../src/doctype.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAIvB;;;GAGG;AACH,eAAO,MAAM,WAAW;;;;;EAGtB,CAAA;AAEF;;;GAGG;AACH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAA;AAErD;;;;GAIG;AACH,MAAM,MAAM,kBAAkB,GAAG,MAAM,CAAA;AAEvC;;;GAGG;AACH,eAAO,MAAM,SAAS;;;iBAUnB,CAAA;AAEH;;;GAGG;AACH,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,SAAS,CAAC,CAAA;AAEjD;;;GAGG;AACH,eAAO,MAAM,SAAS;;iBAQnB,CAAA;AAEH;;;GAGG;AACH,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,SAAS,CAAC,CAAA;AAEjD;;;GAGG;AACH,eAAO,MAAM,WAAW;;;iBAUrB,CAAA;AAEH;;;GAGG;AACH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAA;AAErD;;;;;;GAMG;AACH,eAAO,MAAM,aAAa;;;;;;;;6BAGxB,CAAA;AAEF;;;GAGG;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAA;AAEzD;;;GAGG;AACH,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;iBA0BzB,CAAA;AAEH;;;GAGG;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAA;AAE7D;;;GAGG;AACH,eAAO,MAAM,gBAAgB
|
|
1
|
+
{"version":3,"file":"doctype.d.ts","sourceRoot":"","sources":["../../src/doctype.ts"],"names":[],"mappings":"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"}
|
package/dist/src/doctype.js
CHANGED
|
@@ -95,21 +95,86 @@ export const ActionDefinition = z
|
|
|
95
95
|
.object({
|
|
96
96
|
/** Display label for the action */
|
|
97
97
|
label: z.string().min(1),
|
|
98
|
-
/** Handler function name or path */
|
|
99
|
-
handler: z.string().min(1),
|
|
100
98
|
/** Fields that must have values before action can execute */
|
|
101
99
|
requiredFields: z.array(z.string()).optional(),
|
|
102
100
|
/** Workflow states where this action is available */
|
|
103
101
|
allowedStates: z.array(z.string()).optional(),
|
|
104
|
-
/**
|
|
105
|
-
|
|
106
|
-
/**
|
|
107
|
-
|
|
102
|
+
/** The state the record transitions to after this action executes */
|
|
103
|
+
nextState: z.string().optional(),
|
|
104
|
+
/** True for stateless command actions with no workflow effect at all (print, email, etc.) */
|
|
105
|
+
stateless: z.boolean().optional(),
|
|
106
|
+
/**
|
|
107
|
+
* True for an internal self-transition: the action runs within the current state without
|
|
108
|
+
* advancing the workflow (e.g. `save`, which mutates record data but stays put). Scoped by
|
|
109
|
+
* `allowedStates`, rendered as a self-loop in the graph, and has no `nextState`. Distinct from
|
|
110
|
+
* `stateless` (which has no workflow presence at all): a self-transition is graph-owned and,
|
|
111
|
+
* unlike a stateless command, persists record data on dispatch.
|
|
112
|
+
*/
|
|
113
|
+
selfTransition: z.boolean().optional(),
|
|
114
|
+
/** JS function body stored as a string; executed client-side via AsyncFunction with injected API surface */
|
|
115
|
+
clientHandler: z.string().optional(),
|
|
108
116
|
})
|
|
109
117
|
.meta({
|
|
110
118
|
title: 'ActionDefinition',
|
|
111
119
|
description: 'Action definition within a workflow',
|
|
112
120
|
});
|
|
121
|
+
/**
|
|
122
|
+
* Reactive field-validation trigger — advisory, client-side only.
|
|
123
|
+
*
|
|
124
|
+
* A Trigger is a docbuilder-authored validator: when any field in `on` is edited, its
|
|
125
|
+
* `clientHandler` runs (client-side, no rollback) and may flag a field inline to block save
|
|
126
|
+
* in the UI. It is deliberately a **sibling** to {@link (ActionDefinition:type)}, not a member of it —
|
|
127
|
+
* a reactive validator is not a user-invoked action, so it lives in the `triggers` map on
|
|
128
|
+
* {@link (WorkflowMeta:type)} and never appears to action readers (transition/command dropdowns, the FSM graph).
|
|
129
|
+
*
|
|
130
|
+
* The two bindings are independent: `on` is the fire-set (which fields' edits run it), while the
|
|
131
|
+
* `setError(field, msg)` call inside `clientHandler` chooses which field displays the error.
|
|
132
|
+
* @public
|
|
133
|
+
*/
|
|
134
|
+
export const TriggerDefinition = z
|
|
135
|
+
.object({
|
|
136
|
+
/** Optional display label; the map key is the trigger's identity */
|
|
137
|
+
label: z.string().optional(),
|
|
138
|
+
/** Fieldnames whose edits fire this trigger (fires when any listed field changes) */
|
|
139
|
+
on: z.array(z.string()),
|
|
140
|
+
/** JS function body stored as a string; run client-side with `{ record, value, setError }`. Advisory. */
|
|
141
|
+
clientHandler: z.string(),
|
|
142
|
+
})
|
|
143
|
+
.meta({
|
|
144
|
+
title: 'TriggerDefinition',
|
|
145
|
+
description: 'Reactive field-validation trigger — advisory client-side',
|
|
146
|
+
});
|
|
147
|
+
/**
|
|
148
|
+
* Whether a workflow action may run from `currentState`.
|
|
149
|
+
*
|
|
150
|
+
* Single source of truth for the "is this action available here" rule, shared by
|
|
151
|
+
* the frontend (`getAvailableTransitions`) and the server-side dispatch guard so
|
|
152
|
+
* the two can never disagree. Empty or absent `allowedStates` means the action is
|
|
153
|
+
* available in ALL states — a plain `allowedStates.includes(currentState)` would
|
|
154
|
+
* wrongly block such actions everywhere.
|
|
155
|
+
*
|
|
156
|
+
* @public
|
|
157
|
+
*/
|
|
158
|
+
export function isActionAllowedInState(action, currentState) {
|
|
159
|
+
const allowedStates = action.allowedStates;
|
|
160
|
+
if (!allowedStates || allowedStates.length === 0)
|
|
161
|
+
return true;
|
|
162
|
+
return allowedStates.includes(currentState);
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* DocBuilder graph layout — node positions for the workflow-state graph, keyed by state name.
|
|
166
|
+
* Pure authoring view-state: persisted in the doctype JSON so an author's manual arrangement
|
|
167
|
+
* survives reloads, but — exactly like {@link (WorkflowMeta:type)}'s `triggers` — it is client-only
|
|
168
|
+
* and never mirrored into the runtime GraphQL SDL (see the WorkflowMeta type in the host SDLs, which
|
|
169
|
+
* expose only `states`/`actions`). The shape mirrors VueFlow's node fields; `position` is the node's
|
|
170
|
+
* canvas coordinate and `targetPosition`/`sourcePosition` are the handle sides.
|
|
171
|
+
* @public
|
|
172
|
+
*/
|
|
173
|
+
export const WorkflowLayout = z.record(z.string(), z.object({
|
|
174
|
+
position: z.object({ x: z.number(), y: z.number() }).optional(),
|
|
175
|
+
targetPosition: z.enum(['left', 'top', 'right', 'bottom']).optional(),
|
|
176
|
+
sourcePosition: z.enum(['left', 'top', 'right', 'bottom']).optional(),
|
|
177
|
+
}));
|
|
113
178
|
/**
|
|
114
179
|
* Workflow metadata - states and actions for a doctype
|
|
115
180
|
* @public
|
|
@@ -120,6 +185,14 @@ export const WorkflowMeta = z
|
|
|
120
185
|
states: z.array(z.string()).optional(),
|
|
121
186
|
/** Actions available in this workflow */
|
|
122
187
|
actions: z.record(z.string(), ActionDefinition).optional(),
|
|
188
|
+
/** Reactive field-validation triggers (advisory, client-side), keyed by trigger name */
|
|
189
|
+
triggers: z.record(z.string(), TriggerDefinition).optional(),
|
|
190
|
+
/**
|
|
191
|
+
* DocBuilder node positions keyed by state name — authoring view-state. Persisted here so a
|
|
192
|
+
* doctype author's manual graph arrangement survives reloads; like `triggers`, it is client-only
|
|
193
|
+
* and never enters the runtime GraphQL SDL. See {@link (WorkflowLayout:variable)}.
|
|
194
|
+
*/
|
|
195
|
+
layout: WorkflowLayout.optional(),
|
|
123
196
|
})
|
|
124
197
|
.meta({
|
|
125
198
|
title: 'WorkflowMeta',
|
|
@@ -135,7 +208,7 @@ export const DoctypeMeta = z
|
|
|
135
208
|
name: z.string().min(1),
|
|
136
209
|
/** URL-friendly slug (kebab-case) */
|
|
137
210
|
slug: z.string().min(1).optional(),
|
|
138
|
-
/** Field definitions (
|
|
211
|
+
/** Field definitions (a link field is one carrying `doctype`) */
|
|
139
212
|
fields: z.array(DoctypeFieldSchema),
|
|
140
213
|
/** Relationship links to other doctypes */
|
|
141
214
|
links: z.record(z.string(), LinkDeclaration).optional(),
|
package/dist/src/field.d.ts
CHANGED
|
@@ -5,15 +5,18 @@ import { TableViewConfig } from './table';
|
|
|
5
5
|
/**
|
|
6
6
|
* Field options - flexible bag for type-specific configuration.
|
|
7
7
|
*
|
|
8
|
-
* Usage
|
|
9
|
-
* - Link/Doctype: target doctype slug as string ("customer", "sales-order-item")
|
|
8
|
+
* Usage:
|
|
10
9
|
* - Select: array of choices (["Draft", "Submitted", "Cancelled"])
|
|
11
10
|
* - Decimal: config object (\{ precision: 10, scale: 2 \})
|
|
12
11
|
* - Code: config object (\{ language: "python" \})
|
|
13
12
|
*
|
|
13
|
+
* Deliberately *not* a bare string: a string once meant "link target", which made the value's
|
|
14
|
+
* shape encode its meaning. That job belongs to `ValueField.doctype`, leaving this a plain
|
|
15
|
+
* choices-or-config bag.
|
|
16
|
+
*
|
|
14
17
|
* @public
|
|
15
18
|
*/
|
|
16
|
-
export declare const FieldOptions: z.ZodUnion<readonly [z.
|
|
19
|
+
export declare const FieldOptions: z.ZodUnion<readonly [z.ZodArray<z.ZodString>, z.ZodRecord<z.ZodString, z.ZodUnknown>]>;
|
|
17
20
|
/**
|
|
18
21
|
* Field options type inferred from Zod schema
|
|
19
22
|
* @public
|
|
@@ -34,7 +37,8 @@ export declare const FieldValidation: z.ZodObject<{
|
|
|
34
37
|
export type FieldValidation = z.infer<typeof FieldValidation>;
|
|
35
38
|
/**
|
|
36
39
|
* A field that holds a scalar value, a link to another record, or a select choice.
|
|
37
|
-
* The most common kind of field. `
|
|
40
|
+
* The most common kind of field. `component` determines how it renders; the attributes below
|
|
41
|
+
* carry everything else that is not a rendering concern.
|
|
38
42
|
* @public
|
|
39
43
|
*/
|
|
40
44
|
export interface ValueField {
|
|
@@ -42,10 +46,29 @@ export interface ValueField {
|
|
|
42
46
|
kind: 'field';
|
|
43
47
|
/** Unique identifier for this field within its doctype */
|
|
44
48
|
fieldname: string;
|
|
45
|
-
/**
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
+
/**
|
|
50
|
+
* Vue component that renders this field — the primary (and only) rendering axis. Required:
|
|
51
|
+
* there is nothing left to derive it from, and a field without one has nothing to render it.
|
|
52
|
+
* Any string is valid; naming a custom component is how an app renders a field Stonecrop
|
|
53
|
+
* ships no widget for. See `CANONICAL_COMPONENTS` for the set Stonecrop provides.
|
|
54
|
+
*/
|
|
55
|
+
component: string;
|
|
56
|
+
/** True for the field that identifies the record's primary-key column. */
|
|
57
|
+
primaryKey?: boolean;
|
|
58
|
+
/** True for a computed/display field with no backing DB column — excluded from SQL SELECT. */
|
|
59
|
+
computed?: boolean;
|
|
60
|
+
/** Editor language for code fields (e.g. `'json'`, `'typescript'`) — the only thing distinguishing
|
|
61
|
+
* a JSON editor from a code editor, since both render with `ACodeEditor`. */
|
|
62
|
+
language?: string;
|
|
63
|
+
/**
|
|
64
|
+
* Target doctype slug. Presence is what makes a field a link.
|
|
65
|
+
*
|
|
66
|
+
* How it renders is decided by `component`, not by this: `AFormLink` renders an
|
|
67
|
+
* inline id-picker, while `AForm`/`ATable` expand the target (see `linkRenderMode`). Expansion
|
|
68
|
+
* metadata — backlink, fetch strategy, authoritative cardinality — lives in the doctype's
|
|
69
|
+
* `links` map, which is additive and never required for a plain foreign key.
|
|
70
|
+
*/
|
|
71
|
+
doctype?: string;
|
|
49
72
|
/** Human-readable label */
|
|
50
73
|
label?: string;
|
|
51
74
|
/** CSS width (e.g. `"40ch"`, `"200px"`) */
|
|
@@ -56,9 +79,14 @@ export interface ValueField {
|
|
|
56
79
|
edit?: boolean;
|
|
57
80
|
/** Input mask pattern or serialized function */
|
|
58
81
|
mask?: string;
|
|
82
|
+
/** Serialized `(value) => string` function for display formatting — distinct from `mask` (input).
|
|
83
|
+
* Spreads through `schemaToColumns` to `ColumnSchema.format`; deserialized at render time by
|
|
84
|
+
* ATable's `getFormattedValue`. */
|
|
85
|
+
format?: string;
|
|
59
86
|
/** Per-field interaction mode override */
|
|
60
87
|
mode?: InteractionMode;
|
|
61
|
-
/** Type-specific options:
|
|
88
|
+
/** Type-specific options: Select choices, Decimal precision config, etc. A link's target is not
|
|
89
|
+
* here — it is `doctype`. */
|
|
62
90
|
options?: FieldOptions;
|
|
63
91
|
/** Whether the field is required */
|
|
64
92
|
required?: boolean;
|
|
@@ -72,6 +100,14 @@ export interface ValueField {
|
|
|
72
100
|
validation?: FieldValidation;
|
|
73
101
|
/** Cardinality for Link fields — authoritative value on LinkDeclaration takes precedence */
|
|
74
102
|
cardinality?: 'atMostOne' | 'one' | 'noneOrMany' | 'atLeastOne';
|
|
103
|
+
/**
|
|
104
|
+
* Provenance marker — stamped only by the GraphQL converter; absence means hand-authored.
|
|
105
|
+
* When present, the docbuilder freezes the field's identity set (`fieldname`, `primaryKey`,
|
|
106
|
+
* `required`, `options`, `cardinality`, `doctype`), since `fieldname` is the GraphQL/column
|
|
107
|
+
* binding and `doctype` is the FK's target. `component` is deliberately **not** frozen: it
|
|
108
|
+
* chooses the widget, which is an authoring decision the database has no opinion about.
|
|
109
|
+
*/
|
|
110
|
+
source?: 'introspected';
|
|
75
111
|
}
|
|
76
112
|
/**
|
|
77
113
|
* A layout container that groups other fields. Resolves to a nested AForm.
|
|
@@ -120,6 +156,22 @@ export interface TableField {
|
|
|
120
156
|
* @public
|
|
121
157
|
*/
|
|
122
158
|
export type DoctypeField = ValueField | FieldsetField | TableField;
|
|
159
|
+
/**
|
|
160
|
+
* Recursively injects the `kind` discriminant into a raw field object and, for fieldsets,
|
|
161
|
+
* into each of its nested `schema` children — mirroring exactly what Zod's `preprocess`
|
|
162
|
+
* does at every level of the discriminated union.
|
|
163
|
+
*
|
|
164
|
+
* Table `columns` are {@link ColumnSchema} entries, not `DoctypeField`s, so they are left
|
|
165
|
+
* untouched — the Zod table schema validates them with a plain passthrough and never injects
|
|
166
|
+
* `kind` there either.
|
|
167
|
+
*
|
|
168
|
+
* Needed because `Doctype.fromObject` constructs a Doctype without running Zod, yet the
|
|
169
|
+
* registry's `resolveFields` gates link and fieldset handling on `field.kind`. Without this,
|
|
170
|
+
* a JSON-authored link resolves to a flat scalar and a fieldset's children are dropped.
|
|
171
|
+
*
|
|
172
|
+
* @public
|
|
173
|
+
*/
|
|
174
|
+
export declare function normalizeFieldKind(field: unknown): unknown;
|
|
123
175
|
/**
|
|
124
176
|
* Zod runtime validation schema for ValueField.
|
|
125
177
|
* @public
|
|
@@ -127,8 +179,11 @@ export type DoctypeField = ValueField | FieldsetField | TableField;
|
|
|
127
179
|
export declare const ValueFieldSchema: z.ZodObject<{
|
|
128
180
|
kind: z.ZodLiteral<"field">;
|
|
129
181
|
fieldname: z.ZodString;
|
|
130
|
-
|
|
131
|
-
|
|
182
|
+
component: z.ZodString;
|
|
183
|
+
primaryKey: z.ZodOptional<z.ZodBoolean>;
|
|
184
|
+
computed: z.ZodOptional<z.ZodBoolean>;
|
|
185
|
+
language: z.ZodOptional<z.ZodString>;
|
|
186
|
+
doctype: z.ZodOptional<z.ZodString>;
|
|
132
187
|
label: z.ZodOptional<z.ZodString>;
|
|
133
188
|
width: z.ZodOptional<z.ZodString>;
|
|
134
189
|
align: z.ZodOptional<z.ZodEnum<{
|
|
@@ -140,12 +195,13 @@ export declare const ValueFieldSchema: z.ZodObject<{
|
|
|
140
195
|
}>>;
|
|
141
196
|
edit: z.ZodOptional<z.ZodBoolean>;
|
|
142
197
|
mask: z.ZodOptional<z.ZodString>;
|
|
198
|
+
format: z.ZodOptional<z.ZodString>;
|
|
143
199
|
mode: z.ZodOptional<z.ZodEnum<{
|
|
144
200
|
edit: "edit";
|
|
145
201
|
read: "read";
|
|
146
202
|
display: "display";
|
|
147
203
|
}>>;
|
|
148
|
-
options: z.ZodOptional<z.ZodUnion<readonly [z.
|
|
204
|
+
options: z.ZodOptional<z.ZodUnion<readonly [z.ZodArray<z.ZodString>, z.ZodRecord<z.ZodString, z.ZodUnknown>]>>;
|
|
149
205
|
required: z.ZodOptional<z.ZodBoolean>;
|
|
150
206
|
readOnly: z.ZodOptional<z.ZodBoolean>;
|
|
151
207
|
hidden: z.ZodOptional<z.ZodBoolean>;
|
|
@@ -160,6 +216,7 @@ export declare const ValueFieldSchema: z.ZodObject<{
|
|
|
160
216
|
noneOrMany: "noneOrMany";
|
|
161
217
|
atLeastOne: "atLeastOne";
|
|
162
218
|
}>>;
|
|
219
|
+
source: z.ZodOptional<z.ZodLiteral<"introspected">>;
|
|
163
220
|
}, z.core.$strip>;
|
|
164
221
|
/**
|
|
165
222
|
* Zod runtime validation schema for FieldsetField.
|
package/dist/src/field.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"field.d.ts","sourceRoot":"","sources":["../../src/field.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;
|
|
1
|
+
{"version":3,"file":"field.d.ts","sourceRoot":"","sources":["../../src/field.ts"],"names":[],"mappings":"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"}
|
package/dist/src/field.js
CHANGED
|
@@ -1,20 +1,21 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import { StonecropFieldType } from './fieldtype';
|
|
3
2
|
import { TableViewConfig } from './table';
|
|
4
3
|
/**
|
|
5
4
|
* Field options - flexible bag for type-specific configuration.
|
|
6
5
|
*
|
|
7
|
-
* Usage
|
|
8
|
-
* - Link/Doctype: target doctype slug as string ("customer", "sales-order-item")
|
|
6
|
+
* Usage:
|
|
9
7
|
* - Select: array of choices (["Draft", "Submitted", "Cancelled"])
|
|
10
8
|
* - Decimal: config object (\{ precision: 10, scale: 2 \})
|
|
11
9
|
* - Code: config object (\{ language: "python" \})
|
|
12
10
|
*
|
|
11
|
+
* Deliberately *not* a bare string: a string once meant "link target", which made the value's
|
|
12
|
+
* shape encode its meaning. That job belongs to `ValueField.doctype`, leaving this a plain
|
|
13
|
+
* choices-or-config bag.
|
|
14
|
+
*
|
|
13
15
|
* @public
|
|
14
16
|
*/
|
|
15
17
|
export const FieldOptions = z
|
|
16
18
|
.union([
|
|
17
|
-
z.string(), // Link/Doctype target: "customer"
|
|
18
19
|
z.array(z.string()), // Select choices: ["A", "B", "C"]
|
|
19
20
|
z.record(z.string(), z.unknown()), // Config: \{ precision: 10, scale: 2 \}
|
|
20
21
|
])
|
|
@@ -41,7 +42,8 @@ export const FieldValidation = z
|
|
|
41
42
|
/**
|
|
42
43
|
* Infers the `kind` discriminant from the structural properties of a raw field
|
|
43
44
|
* object, then injects it if absent. This allows authored JSON to omit `kind`
|
|
44
|
-
* entirely —
|
|
45
|
+
* entirely — a `schema` key means fieldset, `columns` means table, anything else
|
|
46
|
+
* is a value field.
|
|
45
47
|
*
|
|
46
48
|
* Rules (applied in order):
|
|
47
49
|
* has `schema` → fieldset
|
|
@@ -49,6 +51,11 @@ export const FieldValidation = z
|
|
|
49
51
|
* otherwise → field (value-holding scalar or link)
|
|
50
52
|
*
|
|
51
53
|
* Objects that already carry `kind` pass through unchanged (backward-compatible).
|
|
54
|
+
*
|
|
55
|
+
* Single-node only. Zod applies this at every level of the discriminated union (via the
|
|
56
|
+
* `z.lazy` in the fieldset schema), so nested fieldset children are normalized during a
|
|
57
|
+
* parse. Callers that bypass Zod — notably `Doctype.fromObject` — must use the exported
|
|
58
|
+
* {@link normalizeFieldKind} instead, which replicates that recursion.
|
|
52
59
|
*/
|
|
53
60
|
function injectKind(data) {
|
|
54
61
|
if (typeof data !== 'object' || data === null || Array.isArray(data))
|
|
@@ -63,18 +70,48 @@ function injectKind(data) {
|
|
|
63
70
|
return { kind: 'table', ...obj };
|
|
64
71
|
return { kind: 'field', ...obj };
|
|
65
72
|
}
|
|
73
|
+
/**
|
|
74
|
+
* Recursively injects the `kind` discriminant into a raw field object and, for fieldsets,
|
|
75
|
+
* into each of its nested `schema` children — mirroring exactly what Zod's `preprocess`
|
|
76
|
+
* does at every level of the discriminated union.
|
|
77
|
+
*
|
|
78
|
+
* Table `columns` are {@link ColumnSchema} entries, not `DoctypeField`s, so they are left
|
|
79
|
+
* untouched — the Zod table schema validates them with a plain passthrough and never injects
|
|
80
|
+
* `kind` there either.
|
|
81
|
+
*
|
|
82
|
+
* Needed because `Doctype.fromObject` constructs a Doctype without running Zod, yet the
|
|
83
|
+
* registry's `resolveFields` gates link and fieldset handling on `field.kind`. Without this,
|
|
84
|
+
* a JSON-authored link resolves to a flat scalar and a fieldset's children are dropped.
|
|
85
|
+
*
|
|
86
|
+
* @public
|
|
87
|
+
*/
|
|
88
|
+
export function normalizeFieldKind(field) {
|
|
89
|
+
const injected = injectKind(field);
|
|
90
|
+
if (typeof injected !== 'object' || injected === null)
|
|
91
|
+
return injected;
|
|
92
|
+
// oxlint-disable-next-line typescript/no-unsafe-type-assertion -- injectKind returns a non-null object for object input; guarded above
|
|
93
|
+
const obj = injected;
|
|
94
|
+
if (obj.kind === 'fieldset' && Array.isArray(obj.schema)) {
|
|
95
|
+
return { ...obj, schema: obj.schema.map(normalizeFieldKind) };
|
|
96
|
+
}
|
|
97
|
+
return injected;
|
|
98
|
+
}
|
|
66
99
|
function createDoctypeFieldSchemas() {
|
|
67
100
|
const ValueFieldSchema = z
|
|
68
101
|
.object({
|
|
69
102
|
kind: z.literal('field'),
|
|
70
103
|
fieldname: z.string().min(1),
|
|
71
|
-
|
|
72
|
-
|
|
104
|
+
component: z.string().min(1),
|
|
105
|
+
primaryKey: z.boolean().optional(),
|
|
106
|
+
computed: z.boolean().optional(),
|
|
107
|
+
language: z.string().optional(),
|
|
108
|
+
doctype: z.string().min(1).optional(),
|
|
73
109
|
label: z.string().optional(),
|
|
74
110
|
width: z.string().optional(),
|
|
75
111
|
align: z.enum(['left', 'center', 'right', 'start', 'end']).optional(),
|
|
76
112
|
edit: z.boolean().optional(),
|
|
77
113
|
mask: z.string().optional(),
|
|
114
|
+
format: z.string().optional(),
|
|
78
115
|
mode: z.enum(['edit', 'read', 'display']).optional(),
|
|
79
116
|
options: FieldOptions.optional(),
|
|
80
117
|
required: z.boolean().optional(),
|
|
@@ -83,6 +120,7 @@ function createDoctypeFieldSchemas() {
|
|
|
83
120
|
default: z.unknown().optional(),
|
|
84
121
|
validation: FieldValidation.optional(),
|
|
85
122
|
cardinality: z.enum(['atMostOne', 'one', 'noneOrMany', 'atLeastOne']).optional(),
|
|
123
|
+
source: z.literal('introspected').optional(),
|
|
86
124
|
})
|
|
87
125
|
.meta({ title: 'ValueField' });
|
|
88
126
|
const TableFieldSchema = z
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fieldtype.d.ts","sourceRoot":"","sources":["../../src/fieldtype.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,6NAsBtB,CAAA;AAEV;;;GAGG;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,mBAAmB,CAAC,CAAC,MAAM,CAAC,CAAA;AAEnE;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,aAG7B,CAAA;AAEF;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,IAAI,gBAAgB,CAEnF;AAED;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC7B;;OAEG;IACH,SAAS,EAAE,MAAM,CAAA;IACjB;;OAEG;IACH,SAAS,EAAE,gBAAgB,CAAA;CAC3B;AAED;;;;GAIG;AACH,eAAO,MAAM,QAAQ,EAAE,MAAM,CAAC,gBAAgB,EAAE,aAAa,
|
|
1
|
+
{"version":3,"file":"fieldtype.d.ts","sourceRoot":"","sources":["../../src/fieldtype.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,6NAsBtB,CAAA;AAEV;;;GAGG;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,mBAAmB,CAAC,CAAC,MAAM,CAAC,CAAA;AAEnE;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,aAG7B,CAAA;AAEF;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,IAAI,gBAAgB,CAEnF;AAED;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC7B;;OAEG;IACH,SAAS,EAAE,MAAM,CAAA;IACjB;;OAEG;IACH,SAAS,EAAE,gBAAgB,CAAA;CAC3B;AAED;;;;GAIG;AACH,eAAO,MAAM,QAAQ,EAAE,MAAM,CAAC,gBAAgB,EAAE,aAAa,CA0C5D,CAAA;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,gBAAgB,GAAG,MAAM,CAEvE;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAE1D"}
|
package/dist/src/fieldtype.js
CHANGED
|
@@ -53,29 +53,30 @@ export function isBuiltinFieldType(fieldtype) {
|
|
|
53
53
|
export const TYPE_MAP = {
|
|
54
54
|
// Text
|
|
55
55
|
Data: { component: 'ATextInput', fieldtype: 'Data' },
|
|
56
|
-
Text: { component: '
|
|
57
|
-
// Numeric
|
|
56
|
+
Text: { component: 'ATextarea', fieldtype: 'Text' },
|
|
57
|
+
// Numeric — all numeric variants render with ANumericInput; display differences (currency,
|
|
58
|
+
// precision, unit) are carried by `format`/`mask`, not a distinct component.
|
|
58
59
|
Int: { component: 'ANumericInput', fieldtype: 'Int' },
|
|
59
60
|
Float: { component: 'ANumericInput', fieldtype: 'Float' },
|
|
60
|
-
Decimal: { component: '
|
|
61
|
+
Decimal: { component: 'ANumericInput', fieldtype: 'Decimal' },
|
|
61
62
|
// Boolean
|
|
62
63
|
Check: { component: 'ACheckbox', fieldtype: 'Check' },
|
|
63
|
-
// Date/Time
|
|
64
|
+
// Date/Time — no dedicated Time SFC exists; Time falls back to a plain text input.
|
|
64
65
|
Date: { component: 'ADate', fieldtype: 'Date' },
|
|
65
|
-
Time: { component: '
|
|
66
|
-
Datetime: { component: '
|
|
67
|
-
Duration: { component: '
|
|
68
|
-
DateRange: { component: '
|
|
69
|
-
// Structured
|
|
66
|
+
Time: { component: 'ATextInput', fieldtype: 'Time' },
|
|
67
|
+
Datetime: { component: 'ADateTime', fieldtype: 'Datetime' },
|
|
68
|
+
Duration: { component: 'ADuration', fieldtype: 'Duration' },
|
|
69
|
+
DateRange: { component: 'ADateRange', fieldtype: 'DateRange' },
|
|
70
|
+
// Structured — JSON vs Code is disambiguated by the field's `language`, not the component.
|
|
70
71
|
JSON: { component: 'ACodeEditor', fieldtype: 'JSON' },
|
|
71
72
|
Code: { component: 'ACodeEditor', fieldtype: 'Code' },
|
|
72
73
|
// Relational
|
|
73
|
-
Link: { component: '
|
|
74
|
+
Link: { component: 'AFormLink', fieldtype: 'Link' },
|
|
74
75
|
// Files
|
|
75
76
|
Attach: { component: 'AFileAttach', fieldtype: 'Attach' },
|
|
76
|
-
// Specialized
|
|
77
|
-
Currency: { component: '
|
|
78
|
-
Quantity: { component: '
|
|
77
|
+
// Specialized — Currency/Quantity are numeric with a display format.
|
|
78
|
+
Currency: { component: 'ANumericInput', fieldtype: 'Currency' },
|
|
79
|
+
Quantity: { component: 'ANumericInput', fieldtype: 'Quantity' },
|
|
79
80
|
Select: { component: 'ADropdown', fieldtype: 'Select' },
|
|
80
81
|
// Identity — PK fields are typically hidden; no interactive component is needed
|
|
81
82
|
PrimaryKey: { component: 'ATextInput', fieldtype: 'PrimaryKey' },
|
package/dist/src/index.d.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
export type { InteractionMode } from './mode';
|
|
2
2
|
export { TableViewConfig } from './table';
|
|
3
|
-
export {
|
|
3
|
+
export { CANONICAL_COMPONENTS, COMPONENT_CATEGORY, COMPONENT_LINK_EXPANSION, componentCategory, componentLinkExpansion, resolveLinkRenderMode, type ComponentCategory, type LinkExpansion, type LinkRenderMode, } from './component-meta';
|
|
4
4
|
export type { DoctypeField, FieldOptions, FieldValidation, FieldsetField, TableField, ValueField } from './field';
|
|
5
|
-
export { DoctypeFieldSchema, FieldsetFieldSchema, TableFieldSchema, ValueFieldSchema } from './field';
|
|
6
|
-
export
|
|
5
|
+
export { DoctypeFieldSchema, FieldsetFieldSchema, normalizeFieldKind, TableFieldSchema, ValueFieldSchema, } from './field';
|
|
6
|
+
export { ActionDefinition, TriggerDefinition, WorkflowLayout, WorkflowMeta, isActionAllowedInState } from './doctype';
|
|
7
|
+
export type { Cardinality, CustomFetch, DataClient, DoctypeContext, DoctypeMeta, DoctypeRef, FetchStrategy, GetRecordOptions, GetRecordResult, GetRecordsOptions, LazyFetch, LinkDeclaration, SerializedFunction, SyncFetch, } from './doctype';
|
|
7
8
|
export { parseDoctype, parseField, validateDoctype, validateField, type ValidationError, type ValidationResult, } from './validation';
|
|
8
9
|
export { buildScalarMap, classifyFieldType, convertGraphQLSchema, defaultIsEntityField, defaultIsEntityType, GQL_SCALAR_MAP, INTERNAL_SCALARS, WELL_KNOWN_SCALARS, type ConvertedGraphQLDoctype, type GraphQLConversionFieldMeta, type GraphQLConversionOptions, type IntrospectionSource, } from './converter';
|
|
9
10
|
export { toSlug, toPascalCase, pascalToSnake, snakeToCamel, camelToSnake, snakeToLabel, camelToLabel } from './naming';
|