@stonecrop/schema 0.13.14 → 0.15.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.
Files changed (141) hide show
  1. package/README.md +38 -92
  2. package/dist/cli.js +6 -6
  3. package/dist/index-rozX0Luh.js +458 -0
  4. package/dist/index-rozX0Luh.js.map +1 -0
  5. package/dist/index.js +70 -31
  6. package/dist/index.js.map +1 -1
  7. package/dist/schema.d.ts +324 -88
  8. package/dist/src/column-schema.d.ts +17 -8
  9. package/dist/src/column-schema.d.ts.map +1 -1
  10. package/dist/src/component-meta.d.ts +96 -0
  11. package/dist/src/component-meta.d.ts.map +1 -0
  12. package/dist/src/component-meta.js +85 -0
  13. package/dist/src/converter/heuristics.d.ts.map +1 -1
  14. package/dist/src/converter/heuristics.js +6 -13
  15. package/dist/src/converter/index.d.ts +1 -1
  16. package/dist/src/converter/index.d.ts.map +1 -1
  17. package/dist/src/converter/index.js +9 -8
  18. package/dist/src/converter/scalars.d.ts +1 -1
  19. package/dist/src/converter/scalars.d.ts.map +1 -1
  20. package/dist/src/converter/scalars.js +23 -26
  21. package/dist/src/converter/types.d.ts +17 -8
  22. package/dist/src/converter/types.d.ts.map +1 -1
  23. package/dist/src/doctype.d.ts +127 -9
  24. package/dist/src/doctype.d.ts.map +1 -1
  25. package/dist/src/doctype.js +80 -7
  26. package/dist/src/field.d.ts +69 -12
  27. package/dist/src/field.d.ts.map +1 -1
  28. package/dist/src/field.js +45 -7
  29. package/dist/src/index.d.ts +4 -3
  30. package/dist/src/index.d.ts.map +1 -1
  31. package/dist/src/index.js +7 -3
  32. package/package.json +14 -9
  33. package/dist/cli.cjs +0 -41
  34. package/dist/cli.cjs.map +0 -1
  35. package/dist/converter/heuristics.js +0 -258
  36. package/dist/converter/index.js +0 -181
  37. package/dist/converter/scalars.js +0 -86
  38. package/dist/converter/types.js +0 -5
  39. package/dist/converter-CYNFRwPg.js +0 -512
  40. package/dist/converter-CYNFRwPg.js.map +0 -1
  41. package/dist/converter-DNwpowpq.js +0 -459
  42. package/dist/converter-DNwpowpq.js.map +0 -1
  43. package/dist/doctype.js +0 -152
  44. package/dist/field.js +0 -110
  45. package/dist/fieldtype.js +0 -97
  46. package/dist/index--rNo7Kel.js +0 -494
  47. package/dist/index--rNo7Kel.js.map +0 -1
  48. package/dist/index-0qWNlDQ5.js +0 -450
  49. package/dist/index-0qWNlDQ5.js.map +0 -1
  50. package/dist/index-2UVTfbcY.js +0 -448
  51. package/dist/index-2UVTfbcY.js.map +0 -1
  52. package/dist/index-9QjWZ_PC.js +0 -449
  53. package/dist/index-9QjWZ_PC.js.map +0 -1
  54. package/dist/index-BCADNO5M.js +0 -449
  55. package/dist/index-BCADNO5M.js.map +0 -1
  56. package/dist/index-BJjSlCSo.js +0 -496
  57. package/dist/index-BJjSlCSo.js.map +0 -1
  58. package/dist/index-BRQJGVFR.js +0 -453
  59. package/dist/index-BRQJGVFR.js.map +0 -1
  60. package/dist/index-BatnoC-J.js +0 -429
  61. package/dist/index-BatnoC-J.js.map +0 -1
  62. package/dist/index-BbG7Mzvg.js +0 -495
  63. package/dist/index-BbG7Mzvg.js.map +0 -1
  64. package/dist/index-BdCmYHg0.js +0 -493
  65. package/dist/index-BdCmYHg0.js.map +0 -1
  66. package/dist/index-BhMd2_xl.js +0 -454
  67. package/dist/index-BhMd2_xl.js.map +0 -1
  68. package/dist/index-C5ANE_rn.js +0 -501
  69. package/dist/index-C5ANE_rn.js.map +0 -1
  70. package/dist/index-CLc5mUMQ.js +0 -478
  71. package/dist/index-CLc5mUMQ.js.map +0 -1
  72. package/dist/index-COrltkHl.js +0 -401
  73. package/dist/index-COrltkHl.js.map +0 -1
  74. package/dist/index-Cu-6609R.js +0 -493
  75. package/dist/index-Cu-6609R.js.map +0 -1
  76. package/dist/index-CvN9xK1B.js +0 -453
  77. package/dist/index-CvN9xK1B.js.map +0 -1
  78. package/dist/index-CzoRIy1-.js +0 -408
  79. package/dist/index-CzoRIy1-.js.map +0 -1
  80. package/dist/index-D66L9JNw.js +0 -506
  81. package/dist/index-D66L9JNw.js.map +0 -1
  82. package/dist/index-D68mWfHm.js +0 -510
  83. package/dist/index-D68mWfHm.js.map +0 -1
  84. package/dist/index-D6Up-BP5.js +0 -435
  85. package/dist/index-D6Up-BP5.js.map +0 -1
  86. package/dist/index-D9qPYlSk.js +0 -491
  87. package/dist/index-D9qPYlSk.js.map +0 -1
  88. package/dist/index-DEkR-1RC.js +0 -496
  89. package/dist/index-DEkR-1RC.js.map +0 -1
  90. package/dist/index-DIY_FLR2.js +0 -516
  91. package/dist/index-DIY_FLR2.js.map +0 -1
  92. package/dist/index-DIb_Z0wI.js +0 -476
  93. package/dist/index-DIb_Z0wI.js.map +0 -1
  94. package/dist/index-DNROIEMe.js +0 -449
  95. package/dist/index-DNROIEMe.js.map +0 -1
  96. package/dist/index-DT-NJBvW.js +0 -510
  97. package/dist/index-DT-NJBvW.js.map +0 -1
  98. package/dist/index-DUFcQC-H.js +0 -449
  99. package/dist/index-DUFcQC-H.js.map +0 -1
  100. package/dist/index-DVVTsJNb.js +0 -495
  101. package/dist/index-DVVTsJNb.js.map +0 -1
  102. package/dist/index-DYy5E1cU.js +0 -508
  103. package/dist/index-DYy5E1cU.js.map +0 -1
  104. package/dist/index-DdC5tpt-.js +0 -488
  105. package/dist/index-DdC5tpt-.js.map +0 -1
  106. package/dist/index-Dk593rMz.js +0 -512
  107. package/dist/index-Dk593rMz.js.map +0 -1
  108. package/dist/index-DmD8vmuB.js +0 -449
  109. package/dist/index-DmD8vmuB.js.map +0 -1
  110. package/dist/index-DpCFgELB.js +0 -514
  111. package/dist/index-DpCFgELB.js.map +0 -1
  112. package/dist/index-DqxTn6jG.js +0 -488
  113. package/dist/index-DqxTn6jG.js.map +0 -1
  114. package/dist/index-DyK5-0kh.js +0 -514
  115. package/dist/index-DyK5-0kh.js.map +0 -1
  116. package/dist/index-XSSAHj8g.js +0 -495
  117. package/dist/index-XSSAHj8g.js.map +0 -1
  118. package/dist/index-XZZbfFxT.js +0 -434
  119. package/dist/index-XZZbfFxT.js.map +0 -1
  120. package/dist/index-_3q9Bzka.js +0 -512
  121. package/dist/index-_3q9Bzka.js.map +0 -1
  122. package/dist/index-aeXXzPET.cjs +0 -2
  123. package/dist/index-aeXXzPET.cjs.map +0 -1
  124. package/dist/index-neVkjlgB.js +0 -446
  125. package/dist/index-neVkjlgB.js.map +0 -1
  126. package/dist/index-xdlVWldg.js +0 -408
  127. package/dist/index-xdlVWldg.js.map +0 -1
  128. package/dist/index.cjs +0 -2
  129. package/dist/index.cjs.map +0 -1
  130. package/dist/jsonschema.js +0 -225
  131. package/dist/naming.js +0 -106
  132. package/dist/src/fieldtype.d.ts +0 -63
  133. package/dist/src/fieldtype.d.ts.map +0 -1
  134. package/dist/src/fieldtype.js +0 -105
  135. package/dist/src/jsonschema.d.ts +0 -95
  136. package/dist/src/jsonschema.d.ts.map +0 -1
  137. package/dist/src/schema-field.d.ts +0 -66
  138. package/dist/src/schema-field.d.ts.map +0 -1
  139. package/dist/src/schema-field.js +0 -0
  140. package/dist/src/tsdoc-metadata.json +0 -11
  141. package/dist/validation.js +0 -60
@@ -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
- confirm: z.ZodOptional<z.ZodBoolean>;
123
- args: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
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
- confirm: z.ZodOptional<z.ZodBoolean>;
142
- args: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
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
- confirm: z.ZodOptional<z.ZodBoolean>;
188
- args: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
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":"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"}
1
+ {"version":3,"file":"doctype.d.ts","sourceRoot":"","sources":["../../src/doctype.ts"],"names":[],"mappings":"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"}
@@ -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
- /** Whether to show a confirmation dialog */
105
- confirm: z.boolean().optional(),
106
- /** Additional arguments for the action */
107
- args: z.record(z.string(), z.unknown()).optional(),
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 (including link fields with fieldtype: 'Link') */
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(),
@@ -5,15 +5,18 @@ import { TableViewConfig } from './table';
5
5
  /**
6
6
  * Field options - flexible bag for type-specific configuration.
7
7
  *
8
- * Usage by fieldtype:
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.ZodString, z.ZodArray<z.ZodString>, z.ZodRecord<z.ZodString, z.ZodUnknown>]>;
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. `fieldtype` determines the default component and behavior.
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
- /** Semantic field type — determines behavior and default rendering component */
46
- fieldtype: string;
47
- /** Vue component to render this field. Derived from `fieldtype` when absent. */
48
- component?: string;
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: Link target slug, Select choices, Decimal precision config, etc. */
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
- fieldtype: z.ZodString;
131
- component: z.ZodOptional<z.ZodString>;
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.ZodString, z.ZodArray<z.ZodString>, z.ZodRecord<z.ZodString, z.ZodUnknown>]>>;
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.
@@ -1 +1 @@
1
- {"version":3,"file":"field.d.ts","sourceRoot":"","sources":["../../src/field.ts"],"names":[],"mappings":"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"}
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 by fieldtype:
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 — authors write only `fieldtype`, `schema`, or `columns`.
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
- fieldtype: StonecropFieldType,
72
- component: z.string().optional(),
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,9 +1,10 @@
1
1
  export type { InteractionMode } from './mode';
2
2
  export { TableViewConfig } from './table';
3
- export { StonecropFieldType, BUILTIN_FIELD_TYPES, TYPE_MAP, getDefaultComponent, resolveComponent, isBuiltinFieldType, type BuiltinFieldType, type FieldTemplate, } from './fieldtype';
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 type { ActionDefinition, Cardinality, CustomFetch, DataClient, DoctypeContext, DoctypeMeta, DoctypeRef, FetchStrategy, GetRecordOptions, GetRecordResult, GetRecordsOptions, LazyFetch, LinkDeclaration, SerializedFunction, SyncFetch, WorkflowMeta, } from './doctype';
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';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AACA,YAAY,EAAE,eAAe,EAAE,MAAM,QAAQ,CAAA;AAG7C,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAGzC,OAAO,EACN,kBAAkB,EAClB,mBAAmB,EACnB,QAAQ,EACR,mBAAmB,EACnB,gBAAgB,EAChB,kBAAkB,EAClB,KAAK,gBAAgB,EACrB,KAAK,aAAa,GAClB,MAAM,aAAa,CAAA;AAGpB,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,eAAe,EAAE,aAAa,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AACjH,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAA;AAGrG,YAAY,EACX,gBAAgB,EAChB,WAAW,EACX,WAAW,EACX,UAAU,EACV,cAAc,EACd,WAAW,EACX,UAAU,EACV,aAAa,EACb,gBAAgB,EAChB,eAAe,EACf,iBAAiB,EACjB,SAAS,EACT,eAAe,EACf,kBAAkB,EAClB,SAAS,EACT,YAAY,GACZ,MAAM,WAAW,CAAA;AAGlB,OAAO,EACN,YAAY,EACZ,UAAU,EACV,eAAe,EACf,aAAa,EACb,KAAK,eAAe,EACpB,KAAK,gBAAgB,GACrB,MAAM,cAAc,CAAA;AAGrB,OAAO,EACN,cAAc,EACd,iBAAiB,EACjB,oBAAoB,EACpB,oBAAoB,EACpB,mBAAmB,EACnB,cAAc,EACd,gBAAgB,EAChB,kBAAkB,EAClB,KAAK,uBAAuB,EAC5B,KAAK,0BAA0B,EAC/B,KAAK,wBAAwB,EAC7B,KAAK,mBAAmB,GACxB,MAAM,aAAa,CAAA;AAGpB,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AAGtH,YAAY,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AACA,YAAY,EAAE,eAAe,EAAE,MAAM,QAAQ,CAAA;AAG7C,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAGzC,OAAO,EACN,oBAAoB,EACpB,kBAAkB,EAClB,wBAAwB,EACxB,iBAAiB,EACjB,sBAAsB,EACtB,qBAAqB,EACrB,KAAK,iBAAiB,EACtB,KAAK,aAAa,EAClB,KAAK,cAAc,GACnB,MAAM,kBAAkB,CAAA;AAGzB,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,eAAe,EAAE,aAAa,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AACjH,OAAO,EACN,kBAAkB,EAClB,mBAAmB,EACnB,kBAAkB,EAClB,gBAAgB,EAChB,gBAAgB,GAChB,MAAM,SAAS,CAAA;AAKhB,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,cAAc,EAAE,YAAY,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAA;AACrH,YAAY,EACX,WAAW,EACX,WAAW,EACX,UAAU,EACV,cAAc,EACd,WAAW,EACX,UAAU,EACV,aAAa,EACb,gBAAgB,EAChB,eAAe,EACf,iBAAiB,EACjB,SAAS,EACT,eAAe,EACf,kBAAkB,EAClB,SAAS,GACT,MAAM,WAAW,CAAA;AAGlB,OAAO,EACN,YAAY,EACZ,UAAU,EACV,eAAe,EACf,aAAa,EACb,KAAK,eAAe,EACpB,KAAK,gBAAgB,GACrB,MAAM,cAAc,CAAA;AAGrB,OAAO,EACN,cAAc,EACd,iBAAiB,EACjB,oBAAoB,EACpB,oBAAoB,EACpB,mBAAmB,EACnB,cAAc,EACd,gBAAgB,EAChB,kBAAkB,EAClB,KAAK,uBAAuB,EAC5B,KAAK,0BAA0B,EAC/B,KAAK,wBAAwB,EAC7B,KAAK,mBAAmB,GACxB,MAAM,aAAa,CAAA;AAGpB,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AAGtH,YAAY,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA"}
package/dist/src/index.js CHANGED
@@ -1,8 +1,12 @@
1
1
  // Table authoring types
2
2
  export { TableViewConfig } from './table';
3
- // Field types
4
- export { StonecropFieldType, BUILTIN_FIELD_TYPES, TYPE_MAP, getDefaultComponent, resolveComponent, isBuiltinFieldType, } from './fieldtype';
5
- export { DoctypeFieldSchema, FieldsetFieldSchema, TableFieldSchema, ValueFieldSchema } from './field';
3
+ // Component → semantic category — the single source of "what kind of value does this component render"
4
+ export { CANONICAL_COMPONENTS, COMPONENT_CATEGORY, COMPONENT_LINK_EXPANSION, componentCategory, componentLinkExpansion, resolveLinkRenderMode, } from './component-meta';
5
+ export { DoctypeFieldSchema, FieldsetFieldSchema, normalizeFieldKind, TableFieldSchema, ValueFieldSchema, } from './field';
6
+ // Doctype schema
7
+ // ActionDefinition and WorkflowMeta are exported as values (Zod schemas) so consumers can use
8
+ // .safeParse(), .shape, etc. at runtime. TypeScript types are inferred from the same exports.
9
+ export { ActionDefinition, TriggerDefinition, WorkflowLayout, WorkflowMeta, isActionAllowedInState } from './doctype';
6
10
  // Validation helpers
7
11
  export { parseDoctype, parseField, validateDoctype, validateField, } from './validation';
8
12
  // GraphQL to Doctype conversion