@stonecrop/schema 0.13.7 → 0.13.9

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.
@@ -1,4 +1,7 @@
1
1
  import { z } from 'zod';
2
+ import type { ColumnSchema } from './column-schema';
3
+ import type { InteractionMode } from './mode';
4
+ import { TableViewConfig } from './table';
2
5
  /**
3
6
  * Field options - flexible bag for type-specific configuration.
4
7
  *
@@ -30,14 +33,99 @@ export declare const FieldValidation: z.ZodObject<{
30
33
  */
31
34
  export type FieldValidation = z.infer<typeof FieldValidation>;
32
35
  /**
33
- * Unified field metadata - the single source of truth for field definitions.
34
- * Works for both forms (AForm) and tables (ATable).
35
- *
36
- * Core principle: "Text" is "Text" regardless of rendering context.
37
- *
36
+ * 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.
38
+ * @public
39
+ */
40
+ export interface ValueField {
41
+ /** Discriminator — identifies this as a value-holding field */
42
+ kind: 'field';
43
+ /** Unique identifier for this field within its doctype */
44
+ 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
+ /** Human-readable label */
50
+ label?: string;
51
+ /** CSS width (e.g. `"40ch"`, `"200px"`) */
52
+ width?: string;
53
+ /** Text alignment */
54
+ align?: 'left' | 'center' | 'right' | 'start' | 'end';
55
+ /** Whether the field is editable in table cell context */
56
+ edit?: boolean;
57
+ /** Input mask pattern or serialized function */
58
+ mask?: string;
59
+ /** Per-field interaction mode override */
60
+ mode?: InteractionMode;
61
+ /** Type-specific options: Link target slug, Select choices, Decimal precision config, etc. */
62
+ options?: FieldOptions;
63
+ /** Whether the field is required */
64
+ required?: boolean;
65
+ /** Whether the field is read-only */
66
+ readOnly?: boolean;
67
+ /** Whether the field is hidden from the UI */
68
+ hidden?: boolean;
69
+ /** Default value for new records */
70
+ default?: unknown;
71
+ /** Validation configuration */
72
+ validation?: FieldValidation;
73
+ /** Cardinality for Link fields — authoritative value on LinkDeclaration takes precedence */
74
+ cardinality?: 'atMostOne' | 'one' | 'noneOrMany' | 'atLeastOne';
75
+ }
76
+ /**
77
+ * A layout container that groups other fields. Resolves to a nested AForm.
78
+ * @public
79
+ */
80
+ export interface FieldsetField {
81
+ /** Discriminator — identifies this as a fieldset container */
82
+ kind: 'fieldset';
83
+ /** Unique identifier for this fieldset within its doctype */
84
+ fieldname: string;
85
+ /** Vue component to render this fieldset. Defaults to `'AFieldset'` in resolveSchema. */
86
+ component?: string;
87
+ /** Human-readable label for the fieldset legend */
88
+ label?: string;
89
+ /** Whether the fieldset can be collapsed */
90
+ collapsible?: boolean;
91
+ /** Interaction mode for all children inside this fieldset */
92
+ mode?: InteractionMode;
93
+ /** Nested field definitions — resolved recursively by resolveSchema */
94
+ schema: DoctypeField[];
95
+ }
96
+ /**
97
+ * An inline table whose columns are defined directly in the schema (no linked doctype).
98
+ * Use when the table data does not warrant a separate doctype.
99
+ * @public
100
+ */
101
+ export interface TableField {
102
+ /** Discriminator — identifies this as an inline table */
103
+ kind: 'table';
104
+ /** Unique identifier for this table within its doctype */
105
+ fieldname: string;
106
+ /** Vue component to render this table. Defaults to `'ATable'` in resolveSchema. */
107
+ component?: string;
108
+ /** Human-readable label */
109
+ label?: string;
110
+ /** Column definitions — use ColumnSchema (fieldname key) from \@stonecrop/schema */
111
+ columns: ColumnSchema[];
112
+ /** View configuration — defaults to `{ view: 'list' }` in resolveSchema when absent */
113
+ config?: TableViewConfig;
114
+ /** Interaction mode for all cells inside this table */
115
+ mode?: InteractionMode;
116
+ }
117
+ /**
118
+ * Union of all authoring-time field variants.
119
+ * Use `kind` to discriminate: `'field'` | `'fieldset'` | `'table'`.
120
+ * @public
121
+ */
122
+ export type DoctypeField = ValueField | FieldsetField | TableField;
123
+ /**
124
+ * Zod runtime validation schema for ValueField.
38
125
  * @public
39
126
  */
40
- export declare const FieldMeta: z.ZodObject<{
127
+ export declare const ValueFieldSchema: z.ZodObject<{
128
+ kind: z.ZodLiteral<"field">;
41
129
  fieldname: z.ZodString;
42
130
  fieldtype: z.ZodString;
43
131
  component: z.ZodOptional<z.ZodString>;
@@ -45,34 +133,91 @@ export declare const FieldMeta: z.ZodObject<{
45
133
  width: z.ZodOptional<z.ZodString>;
46
134
  align: z.ZodOptional<z.ZodEnum<{
47
135
  left: "left";
48
- center: "center";
49
136
  right: "right";
137
+ center: "center";
50
138
  start: "start";
51
139
  end: "end";
52
140
  }>>;
141
+ edit: z.ZodOptional<z.ZodBoolean>;
142
+ mask: z.ZodOptional<z.ZodString>;
143
+ mode: z.ZodOptional<z.ZodEnum<{
144
+ edit: "edit";
145
+ read: "read";
146
+ display: "display";
147
+ }>>;
148
+ options: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>, z.ZodRecord<z.ZodString, z.ZodUnknown>]>>;
53
149
  required: z.ZodOptional<z.ZodBoolean>;
54
150
  readOnly: z.ZodOptional<z.ZodBoolean>;
55
- edit: z.ZodOptional<z.ZodBoolean>;
56
151
  hidden: z.ZodOptional<z.ZodBoolean>;
57
- value: z.ZodOptional<z.ZodUnknown>;
58
152
  default: z.ZodOptional<z.ZodUnknown>;
59
- options: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>, z.ZodRecord<z.ZodString, z.ZodUnknown>]>>;
153
+ validation: z.ZodOptional<z.ZodObject<{
154
+ /** Error message to display when validation fails */
155
+ errorMessage: z.ZodString;
156
+ }, z.core.$loose>>;
60
157
  cardinality: z.ZodOptional<z.ZodEnum<{
61
- one: "one";
62
158
  atMostOne: "atMostOne";
159
+ one: "one";
63
160
  noneOrMany: "noneOrMany";
64
161
  atLeastOne: "atLeastOne";
65
162
  }>>;
66
- mask: z.ZodOptional<z.ZodString>;
67
- validation: z.ZodOptional<z.ZodObject<{
68
- /** Error message to display when validation fails */
69
- errorMessage: z.ZodString;
163
+ }, z.core.$strip>;
164
+ /**
165
+ * Zod runtime validation schema for FieldsetField.
166
+ * Recursive — FieldsetField.schema is validated against DoctypeFieldSchema.
167
+ * @public
168
+ */
169
+ export declare const FieldsetFieldSchema: z.ZodObject<{
170
+ kind: z.ZodLiteral<"fieldset">;
171
+ fieldname: z.ZodString;
172
+ component: z.ZodOptional<z.ZodString>;
173
+ label: z.ZodOptional<z.ZodString>;
174
+ collapsible: z.ZodOptional<z.ZodBoolean>;
175
+ mode: z.ZodOptional<z.ZodEnum<{
176
+ edit: "edit";
177
+ read: "read";
178
+ display: "display";
179
+ }>>;
180
+ schema: z.ZodLazy<z.ZodArray<z.ZodType<DoctypeField, unknown, z.core.$ZodTypeInternals<DoctypeField, unknown>>>>;
181
+ }, z.core.$strip>;
182
+ /**
183
+ * Zod runtime validation schema for TableField.
184
+ * @public
185
+ */
186
+ export declare const TableFieldSchema: z.ZodObject<{
187
+ kind: z.ZodLiteral<"table">;
188
+ fieldname: z.ZodString;
189
+ component: z.ZodOptional<z.ZodString>;
190
+ label: z.ZodOptional<z.ZodString>;
191
+ columns: z.ZodArray<z.ZodObject<{
192
+ fieldname: z.ZodString;
70
193
  }, z.core.$loose>>;
71
- schema: z.ZodOptional<z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
194
+ config: z.ZodOptional<z.ZodObject<{
195
+ view: z.ZodOptional<z.ZodEnum<{
196
+ list: "list";
197
+ uncounted: "uncounted";
198
+ "list-expansion": "list-expansion";
199
+ tree: "tree";
200
+ gantt: "gantt";
201
+ "tree-gantt": "tree-gantt";
202
+ }>>;
203
+ fullWidth: z.ZodOptional<z.ZodBoolean>;
204
+ defaultTreeExpansion: z.ZodOptional<z.ZodEnum<{
205
+ root: "root";
206
+ branch: "branch";
207
+ leaf: "leaf";
208
+ }>>;
209
+ dependencyGraph: z.ZodOptional<z.ZodBoolean>;
210
+ }, z.core.$strip>>;
211
+ mode: z.ZodOptional<z.ZodEnum<{
212
+ edit: "edit";
213
+ read: "read";
214
+ display: "display";
215
+ }>>;
72
216
  }, z.core.$strip>;
73
217
  /**
74
- * Field metadata type inferred from Zod schema
218
+ * Zod runtime validation schema for the DoctypeField discriminated union.
219
+ * Validates all three field variants: `'field'`, `'fieldset'`, `'table'`.
75
220
  * @public
76
221
  */
77
- export type FieldMeta = z.infer<typeof FieldMeta>;
222
+ export declare const DoctypeFieldSchema: z.ZodType<DoctypeField, unknown, z.core.$ZodTypeInternals<DoctypeField, unknown>>;
78
223
  //# sourceMappingURL=field.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"field.d.ts","sourceRoot":"","sources":["../../src/field.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAIvB;;;;;;;;;;GAUG;AACH,eAAO,MAAM,YAAY,qGAStB,CAAA;AAEH;;;GAGG;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAA;AAEvD;;;GAGG;AACH,eAAO,MAAM,eAAe;IAE1B,qDAAqD;;iBAMpD,CAAA;AAEH;;;GAGG;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAA;AAE7D;;;;;;;GAOG;AACH,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAtBpB,qDAAqD;;;;iBAmHpD,CAAA;AAEH;;;GAGG;AACH,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,SAAS,CAAC,CAAA"}
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;AAEnD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,QAAQ,CAAA;AAC7C,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAEzC;;;;;;;;;;GAUG;AACH,eAAO,MAAM,YAAY,qGAStB,CAAA;AAEH;;;GAGG;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAA;AAEvD;;;GAGG;AACH,eAAO,MAAM,eAAe;IAE1B,qDAAqD;;iBAMpD,CAAA;AAEH;;;GAGG;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAA;AAM7D;;;;GAIG;AACH,MAAM,WAAW,UAAU;IAC1B,+DAA+D;IAC/D,IAAI,EAAE,OAAO,CAAA;IACb,0DAA0D;IAC1D,SAAS,EAAE,MAAM,CAAA;IACjB,gFAAgF;IAChF,SAAS,EAAE,MAAM,CAAA;IACjB,gFAAgF;IAChF,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,2BAA2B;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,2CAA2C;IAC3C,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,qBAAqB;IACrB,KAAK,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,OAAO,GAAG,OAAO,GAAG,KAAK,CAAA;IACrD,0DAA0D;IAC1D,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,gDAAgD;IAChD,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,0CAA0C;IAC1C,IAAI,CAAC,EAAE,eAAe,CAAA;IACtB,8FAA8F;IAC9F,OAAO,CAAC,EAAE,YAAY,CAAA;IACtB,oCAAoC;IACpC,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,qCAAqC;IACrC,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,8CAA8C;IAC9C,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,oCAAoC;IACpC,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,+BAA+B;IAC/B,UAAU,CAAC,EAAE,eAAe,CAAA;IAC5B,4FAA4F;IAC5F,WAAW,CAAC,EAAE,WAAW,GAAG,KAAK,GAAG,YAAY,GAAG,YAAY,CAAA;CAC/D;AAED;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC7B,8DAA8D;IAC9D,IAAI,EAAE,UAAU,CAAA;IAChB,6DAA6D;IAC7D,SAAS,EAAE,MAAM,CAAA;IACjB,yFAAyF;IACzF,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,mDAAmD;IACnD,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,4CAA4C;IAC5C,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,6DAA6D;IAC7D,IAAI,CAAC,EAAE,eAAe,CAAA;IACtB,uEAAuE;IACvE,MAAM,EAAE,YAAY,EAAE,CAAA;CACtB;AAED;;;;GAIG;AACH,MAAM,WAAW,UAAU;IAC1B,yDAAyD;IACzD,IAAI,EAAE,OAAO,CAAA;IACb,0DAA0D;IAC1D,SAAS,EAAE,MAAM,CAAA;IACjB,mFAAmF;IACnF,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,2BAA2B;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,oFAAoF;IACpF,OAAO,EAAE,YAAY,EAAE,CAAA;IACvB,uFAAuF;IACvF,MAAM,CAAC,EAAE,eAAe,CAAA;IACxB,uDAAuD;IACvD,IAAI,CAAC,EAAE,eAAe,CAAA;CACtB;AAED;;;;GAIG;AACH,MAAM,MAAM,YAAY,GAAG,UAAU,GAAG,aAAa,GAAG,UAAU,CAAA;AAkGlE;;;GAGG;AACH,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;QAlN3B,qDAAqD;;;;;;;;;iBAkNC,CAAA;AAExD;;;;GAIG;AACH,eAAO,MAAM,mBAAmB;;;;;;;;;;;;iBAA8B,CAAA;AAE9D;;;GAGG;AACH,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAA2B,CAAA;AAExD;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,mFAA6B,CAAA"}
package/dist/src/field.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import { z } from 'zod';
2
2
  import { StonecropFieldType } from './fieldtype';
3
+ import { TableViewConfig } from './table';
3
4
  /**
4
5
  * Field options - flexible bag for type-specific configuration.
5
6
  *
@@ -34,80 +35,115 @@ export const FieldValidation = z
34
35
  title: 'FieldValidation',
35
36
  description: 'Validation configuration for form fields',
36
37
  });
38
+ // ---------------------------------------------------------------------------
39
+ // Zod runtime validation schemas
40
+ // ---------------------------------------------------------------------------
37
41
  /**
38
- * Unified field metadata - the single source of truth for field definitions.
39
- * Works for both forms (AForm) and tables (ATable).
42
+ * Infers the `kind` discriminant from the structural properties of a raw field
43
+ * object, then injects it if absent. This allows authored JSON to omit `kind`
44
+ * entirely — authors write only `fieldtype`, `schema`, or `columns`.
40
45
  *
41
- * Core principle: "Text" is "Text" regardless of rendering context.
46
+ * Rules (applied in order):
47
+ * has `schema` → fieldset
48
+ * has `columns` → table
49
+ * otherwise → field (value-holding scalar or link)
42
50
  *
51
+ * Objects that already carry `kind` pass through unchanged (backward-compatible).
52
+ */
53
+ function injectKind(data) {
54
+ if (typeof data !== 'object' || data === null || Array.isArray(data))
55
+ return data;
56
+ // oxlint-disable-next-line typescript/no-unsafe-type-assertion -- safe: non-null, non-array object verified by guards above
57
+ const obj = data;
58
+ if ('kind' in obj)
59
+ return data;
60
+ if ('schema' in obj)
61
+ return { kind: 'fieldset', ...obj };
62
+ if ('columns' in obj)
63
+ return { kind: 'table', ...obj };
64
+ return { kind: 'field', ...obj };
65
+ }
66
+ function createDoctypeFieldSchemas() {
67
+ const ValueFieldSchema = z
68
+ .object({
69
+ kind: z.literal('field'),
70
+ fieldname: z.string().min(1),
71
+ fieldtype: StonecropFieldType,
72
+ component: z.string().optional(),
73
+ label: z.string().optional(),
74
+ width: z.string().optional(),
75
+ align: z.enum(['left', 'center', 'right', 'start', 'end']).optional(),
76
+ edit: z.boolean().optional(),
77
+ mask: z.string().optional(),
78
+ mode: z.enum(['edit', 'read', 'display']).optional(),
79
+ options: FieldOptions.optional(),
80
+ required: z.boolean().optional(),
81
+ readOnly: z.boolean().optional(),
82
+ hidden: z.boolean().optional(),
83
+ default: z.unknown().optional(),
84
+ validation: FieldValidation.optional(),
85
+ cardinality: z.enum(['atMostOne', 'one', 'noneOrMany', 'atLeastOne']).optional(),
86
+ })
87
+ .meta({ title: 'ValueField' });
88
+ const TableFieldSchema = z
89
+ .object({
90
+ kind: z.literal('table'),
91
+ fieldname: z.string().min(1),
92
+ component: z.string().optional(),
93
+ label: z.string().optional(),
94
+ // Validates that each column has fieldname; allows all other ColumnSchema properties
95
+ columns: z.array(z.object({ fieldname: z.string().min(1) }).passthrough()),
96
+ config: TableViewConfig.optional(),
97
+ mode: z.enum(['edit', 'read', 'display']).optional(),
98
+ })
99
+ .meta({ title: 'TableField' });
100
+ // DoctypeFieldSchema must be declared before FieldsetFieldSchema so the z.lazy
101
+ // callback can close over it. The placeholder is overwritten below; the callback
102
+ // only runs at parse time, after the real discriminated union is assigned.
103
+ // See: https://zod.dev/api?id=discriminated-unions#discriminated-unions
104
+ // oxlint-disable-next-line typescript/no-unsafe-type-assertion -- required by Zod's recursive schema pattern; z.never() placeholder is overwritten before any parse call
105
+ let DoctypeFieldSchema = z.never();
106
+ // FieldsetFieldSchema stays as a plain ZodObject (not z.ZodType<T>) so that
107
+ // z.discriminatedUnion can inspect its 'kind' discriminant property.
108
+ const FieldsetFieldSchema = z
109
+ .object({
110
+ kind: z.literal('fieldset'),
111
+ fieldname: z.string().min(1),
112
+ component: z.string().optional(),
113
+ label: z.string().optional(),
114
+ collapsible: z.boolean().optional(),
115
+ mode: z.enum(['edit', 'read', 'display']).optional(),
116
+ schema: z.lazy(() => DoctypeFieldSchema.array()),
117
+ })
118
+ .meta({ title: 'FieldsetField' });
119
+ const rawUnion = z.discriminatedUnion('kind', [ValueFieldSchema, FieldsetFieldSchema, TableFieldSchema]);
120
+ // Overwrite the placeholder with the preprocessed schema. Because z.lazy captures
121
+ // DoctypeFieldSchema by closure reference, the lazy callback in FieldsetFieldSchema
122
+ // will resolve to this preprocessed version — so nested fieldsets also inject `kind`.
123
+ // oxlint-disable-next-line typescript/no-unsafe-type-assertion -- ZodPipe output is DoctypeField; same pattern as the z.never() placeholder above
124
+ DoctypeFieldSchema = z.preprocess(injectKind, rawUnion);
125
+ return { ValueFieldSchema, TableFieldSchema, FieldsetFieldSchema, DoctypeFieldSchema };
126
+ }
127
+ const schemas = createDoctypeFieldSchemas();
128
+ /**
129
+ * Zod runtime validation schema for ValueField.
43
130
  * @public
44
131
  */
45
- export const FieldMeta = z
46
- .object({
47
- // === CORE (required) ===
48
- /** Unique identifier for the field within its doctype */
49
- fieldname: z.string().min(1),
50
- /** Semantic field type - determines behavior and default component */
51
- fieldtype: StonecropFieldType,
52
- // === COMPONENT (optional - derived from fieldtype when not specified) ===
53
- /** Vue component to render this field. If not specified, derived from TYPE_MAP */
54
- component: z.string().optional(),
55
- // === DISPLAY ===
56
- /** Human-readable label for the field */
57
- label: z.string().optional(),
58
- /** Width of the field (CSS value, e.g., "40ch", "200px") */
59
- width: z.string().optional(),
60
- /** Text alignment within the field */
61
- align: z.enum(['left', 'center', 'right', 'start', 'end']).optional(),
62
- // === BEHAVIOR ===
63
- /** Whether the field is required */
64
- required: z.boolean().optional(),
65
- /** Whether the field is read-only */
66
- readOnly: z.boolean().optional(),
67
- /** Whether the field is editable (for table cells) */
68
- edit: z.boolean().optional(),
69
- /** Whether the field is hidden from the UI */
70
- hidden: z.boolean().optional(),
71
- // === VALUE ===
72
- /** Current value of the field */
73
- value: z.unknown().optional(),
74
- /** Default value for new records */
75
- default: z.unknown().optional(),
76
- // === TYPE-SPECIFIC ===
77
- /**
78
- * Type-specific options:
79
- * - Link: target doctype slug ("customer")
80
- * - Doctype: child doctype slug ("sales-order-item")
81
- * - Select: choices array (["Draft", "Submitted"])
82
- * - Decimal: \{ precision, scale \}
83
- * - Code: \{ language \}
84
- */
85
- options: FieldOptions.optional(),
86
- /**
87
- * Cardinality for Doctype fields:
88
- * - 'one': exactly 1 (default)
89
- * - 'atMostOne': 0 or 1
90
- * - 'noneOrMany': 0 or more
91
- * - 'atLeastOne': 1 or more
92
- */
93
- cardinality: z.enum(['one', 'atMostOne', 'noneOrMany', 'atLeastOne']).optional(),
94
- /**
95
- * Input mask pattern. Accepts either a plain mask string or a stringified
96
- * arrow function that receives `locale` and returns a mask string.
97
- *
98
- * Plain pattern: `"##/##/####"`
99
- *
100
- * Function pattern: `"(locale) => locale === 'en-US' ? '(###) ###-####' : '####-######'"`
101
- */
102
- mask: z.string().optional(),
103
- // === VALIDATION ===
104
- /** Validation configuration */
105
- validation: FieldValidation.optional(),
106
- // === LAYOUT ===
107
- /** Nested field definitions for Fieldset containers — UI grouping only, no DB column */
108
- schema: z.array(z.record(z.string(), z.unknown())).optional(),
109
- })
110
- .meta({
111
- title: 'FieldMeta',
112
- description: 'Unified field metadata - the single source of truth for field definitions, works for both forms (AForm) and tables (ATable)',
113
- });
132
+ export const ValueFieldSchema = schemas.ValueFieldSchema;
133
+ /**
134
+ * Zod runtime validation schema for FieldsetField.
135
+ * Recursive — FieldsetField.schema is validated against DoctypeFieldSchema.
136
+ * @public
137
+ */
138
+ export const FieldsetFieldSchema = schemas.FieldsetFieldSchema;
139
+ /**
140
+ * Zod runtime validation schema for TableField.
141
+ * @public
142
+ */
143
+ export const TableFieldSchema = schemas.TableFieldSchema;
144
+ /**
145
+ * Zod runtime validation schema for the DoctypeField discriminated union.
146
+ * Validates all three field variants: `'field'`, `'fieldset'`, `'table'`.
147
+ * @public
148
+ */
149
+ export const DoctypeFieldSchema = schemas.DoctypeFieldSchema;
@@ -1,5 +1,8 @@
1
+ export type { InteractionMode } from './mode';
2
+ export { TableViewConfig } from './table';
1
3
  export { StonecropFieldType, BUILTIN_FIELD_TYPES, TYPE_MAP, getDefaultComponent, resolveComponent, isBuiltinFieldType, type BuiltinFieldType, type FieldTemplate, } from './fieldtype';
2
- export type { FieldMeta, FieldOptions, FieldValidation } from './field';
4
+ export type { DoctypeField, FieldOptions, FieldValidation, FieldsetField, TableField, ValueField } from './field';
5
+ export { DoctypeFieldSchema, FieldsetFieldSchema, TableFieldSchema, ValueFieldSchema } from './field';
3
6
  export type { ActionDefinition, Cardinality, CustomFetch, DataClient, DoctypeContext, DoctypeMeta, DoctypeRef, FetchStrategy, GetRecordOptions, GetRecordResult, GetRecordsOptions, LazyFetch, LinkDeclaration, SerializedFunction, SyncFetch, WorkflowMeta, } from './doctype';
4
7
  export { parseDoctype, parseField, validateDoctype, validateField, type ValidationError, type ValidationResult, } from './validation';
5
8
  export { buildScalarMap, classifyFieldType, convertGraphQLSchema, defaultIsEntityField, defaultIsEntityType, GQL_SCALAR_MAP, INTERNAL_SCALARS, WELL_KNOWN_SCALARS, type ConvertedGraphQLDoctype, type GraphQLConversionFieldMeta, type GraphQLConversionOptions, type IntrospectionSource, } from './converter';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AACA,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,SAAS,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAGvE,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,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"}
package/dist/src/index.js CHANGED
@@ -1,5 +1,8 @@
1
+ // Table authoring types
2
+ export { TableViewConfig } from './table';
1
3
  // Field types
2
4
  export { StonecropFieldType, BUILTIN_FIELD_TYPES, TYPE_MAP, getDefaultComponent, resolveComponent, isBuiltinFieldType, } from './fieldtype';
5
+ export { DoctypeFieldSchema, FieldsetFieldSchema, TableFieldSchema, ValueFieldSchema } from './field';
3
6
  // Validation helpers
4
7
  export { parseDoctype, parseField, validateDoctype, validateField, } from './validation';
5
8
  // GraphQL to Doctype conversion
@@ -1,4 +1,3 @@
1
- import { FieldMeta } from './field';
2
1
  import { DoctypeMeta } from './doctype';
3
2
  /**
4
3
  * Validation error with path information
@@ -21,7 +20,7 @@ export interface ValidationResult {
21
20
  errors: ValidationError[];
22
21
  }
23
22
  /**
24
- * Validate a field definition
23
+ * Validate a field definition against the DoctypeField discriminated union
25
24
  * @param data - Data to validate
26
25
  * @returns Validation result
27
26
  * @public
@@ -37,11 +36,11 @@ export declare function validateDoctype(data: unknown): ValidationResult;
37
36
  /**
38
37
  * Parse and validate a field, throwing on failure
39
38
  * @param data - Data to parse
40
- * @returns Validated FieldMeta
39
+ * @returns Validated DoctypeField
41
40
  * @throws ZodError if validation fails
42
41
  * @public
43
42
  */
44
- export declare function parseField(data: unknown): FieldMeta;
43
+ export declare function parseField(data: unknown): import('./field').DoctypeField;
45
44
  /**
46
45
  * Parse and validate a doctype, throwing on failure
47
46
  * @param data - Data to parse
@@ -50,6 +49,6 @@ export declare function parseField(data: unknown): FieldMeta;
50
49
  * @public
51
50
  */
52
51
  export declare function parseDoctype(data: unknown): DoctypeMeta;
53
- export type { FieldMeta } from './field';
52
+ export type { DoctypeField, ValueField, FieldsetField, TableField } from './field';
54
53
  export type { DoctypeMeta } from './doctype';
55
54
  //# sourceMappingURL=validation.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/validation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AACnC,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AAEvC;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC/B,mCAAmC;IACnC,IAAI,EAAE,WAAW,EAAE,CAAA;IAEnB,oBAAoB;IACpB,OAAO,EAAE,MAAM,CAAA;CACf;AAED;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAChC,gCAAgC;IAChC,OAAO,EAAE,OAAO,CAAA;IAEhB,mDAAmD;IACnD,MAAM,EAAE,eAAe,EAAE,CAAA;CACzB;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,OAAO,GAAG,gBAAgB,CAc7D;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,OAAO,GAAG,gBAAgB,CAc/D;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,OAAO,GAAG,SAAS,CAEnD;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,OAAO,GAAG,WAAW,CAEvD;AAGD,YAAY,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AACxC,YAAY,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA"}
1
+ {"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/validation.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AAEvC;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC/B,mCAAmC;IACnC,IAAI,EAAE,WAAW,EAAE,CAAA;IAEnB,oBAAoB;IACpB,OAAO,EAAE,MAAM,CAAA;CACf;AAED;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAChC,gCAAgC;IAChC,OAAO,EAAE,OAAO,CAAA;IAEhB,mDAAmD;IACnD,MAAM,EAAE,eAAe,EAAE,CAAA;CACzB;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,OAAO,GAAG,gBAAgB,CAc7D;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,OAAO,GAAG,gBAAgB,CAc/D;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,SAAS,EAAE,YAAY,CAExE;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,OAAO,GAAG,WAAW,CAEvD;AAGD,YAAY,EAAE,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAClF,YAAY,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA"}
@@ -1,13 +1,13 @@
1
- import { FieldMeta } from './field';
1
+ import { DoctypeFieldSchema } from './field';
2
2
  import { DoctypeMeta } from './doctype';
3
3
  /**
4
- * Validate a field definition
4
+ * Validate a field definition against the DoctypeField discriminated union
5
5
  * @param data - Data to validate
6
6
  * @returns Validation result
7
7
  * @public
8
8
  */
9
9
  export function validateField(data) {
10
- const result = FieldMeta.safeParse(data);
10
+ const result = DoctypeFieldSchema.safeParse(data);
11
11
  if (result.success) {
12
12
  return { success: true, errors: [] };
13
13
  }
@@ -41,12 +41,12 @@ export function validateDoctype(data) {
41
41
  /**
42
42
  * Parse and validate a field, throwing on failure
43
43
  * @param data - Data to parse
44
- * @returns Validated FieldMeta
44
+ * @returns Validated DoctypeField
45
45
  * @throws ZodError if validation fails
46
46
  * @public
47
47
  */
48
48
  export function parseField(data) {
49
- return FieldMeta.parse(data);
49
+ return DoctypeFieldSchema.parse(data);
50
50
  }
51
51
  /**
52
52
  * Parse and validate a doctype, throwing on failure
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stonecrop/schema",
3
- "version": "0.13.7",
3
+ "version": "0.13.9",
4
4
  "type": "module",
5
5
  "types": "./dist/schema.d.ts",
6
6
  "exports": {