@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
package/dist/doctype.js DELETED
@@ -1,152 +0,0 @@
1
- import { z } from 'zod';
2
- import { FieldMeta } from './field';
3
- /**
4
- * Cardinality for relationship links.
5
- * @public
6
- */
7
- export const Cardinality = z.enum(['atMostOne', 'one', 'noneOrMany', 'atLeastOne']).meta({
8
- title: 'Cardinality',
9
- description: 'Cardinality for relationship links between doctypes',
10
- });
11
- /**
12
- * Sync fetch strategy - data is fetched in the initial query.
13
- * @public
14
- */
15
- export const SyncFetch = z
16
- .object({
17
- /** Fetch method type */
18
- method: z.literal('sync'),
19
- /** Optional limit on number of records to fetch */
20
- limit: z.number().int().positive().optional(),
21
- })
22
- .meta({
23
- title: 'SyncFetch',
24
- description: 'Sync fetch strategy - data is fetched in the initial query',
25
- });
26
- /**
27
- * Lazy fetch strategy - data is fetched on demand in a separate query.
28
- * @public
29
- */
30
- export const LazyFetch = z
31
- .object({
32
- /** Fetch method type */
33
- method: z.literal('lazy'),
34
- })
35
- .meta({
36
- title: 'LazyFetch',
37
- description: 'Lazy fetch strategy - data is fetched on demand in a separate query',
38
- });
39
- /**
40
- * Custom fetch strategy - uses a custom handler function.
41
- * @public
42
- */
43
- export const CustomFetch = z
44
- .object({
45
- /** Fetch method type */
46
- method: z.literal('custom'),
47
- /** Serialized handler function to invoke */
48
- handler: z.string(),
49
- })
50
- .meta({
51
- title: 'CustomFetch',
52
- description: 'Custom fetch strategy - uses a custom handler function',
53
- });
54
- /**
55
- * Fetch strategy for link data loading.
56
- * - sync: fetched in the initial query
57
- * - lazy: fetched on demand in a separate query
58
- * - custom: uses a custom handler function
59
- * @public
60
- */
61
- export const FetchStrategy = z.discriminatedUnion('method', [SyncFetch, LazyFetch, CustomFetch]).meta({
62
- title: 'FetchStrategy',
63
- description: 'Fetch strategy for link data loading',
64
- });
65
- /**
66
- * Link declaration - describes a relationship from one doctype to another.
67
- * @public
68
- */
69
- export const LinkDeclaration = z
70
- .object({
71
- /** Target doctype slug */
72
- target: z.string().min(1),
73
- /** Cardinality of the relationship */
74
- cardinality: Cardinality,
75
- /** Backlink fieldname on the target doctype that points back to this link */
76
- backlink: z.string().optional(),
77
- /** Override default rendering component (AForm for 1:1, ATable for 1:many) */
78
- component: z.string().optional(),
79
- /** Fieldname of the corresponding Link field in the fields array */
80
- fieldname: z.string().min(1).optional(),
81
- /** Fetch strategy for loading nested data */
82
- fetch: FetchStrategy.optional(),
83
- /** Whether to block workflow actions until nested data is loaded (default: true) */
84
- blockWorkflows: z.boolean().optional(),
85
- })
86
- .meta({
87
- title: 'LinkDeclaration',
88
- description: 'Declares a relationship from one doctype to another',
89
- });
90
- /**
91
- * Action definition within a workflow
92
- * @public
93
- */
94
- export const ActionDefinition = z
95
- .object({
96
- /** Display label for the action */
97
- label: z.string().min(1),
98
- /** Handler function name or path */
99
- handler: z.string().min(1),
100
- /** Fields that must have values before action can execute */
101
- requiredFields: z.array(z.string()).optional(),
102
- /** Workflow states where this action is available */
103
- 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(),
108
- })
109
- .meta({
110
- title: 'ActionDefinition',
111
- description: 'Action definition within a workflow',
112
- });
113
- /**
114
- * Workflow metadata - states and actions for a doctype
115
- * @public
116
- */
117
- export const WorkflowMeta = z
118
- .object({
119
- /** List of workflow states */
120
- states: z.array(z.string()).optional(),
121
- /** Actions available in this workflow */
122
- actions: z.record(z.string(), ActionDefinition).optional(),
123
- })
124
- .meta({
125
- title: 'WorkflowMeta',
126
- description: 'Workflow metadata - states and actions for a doctype',
127
- });
128
- /**
129
- * Doctype metadata - complete definition of a doctype
130
- * @public
131
- */
132
- export const DoctypeMeta = z
133
- .object({
134
- /** Display name of the doctype */
135
- name: z.string().min(1),
136
- /** URL-friendly slug (kebab-case) */
137
- slug: z.string().min(1).optional(),
138
- /** Database table name */
139
- tableName: z.string().optional(),
140
- /** Field definitions (including link fields with fieldtype: 'Link') */
141
- fields: z.array(FieldMeta),
142
- /** Relationship links to other doctypes */
143
- links: z.record(z.string(), LinkDeclaration).optional(),
144
- /** Workflow configuration */
145
- workflow: WorkflowMeta.optional(),
146
- /** Parent doctype for inheritance */
147
- inherits: z.string().optional(),
148
- })
149
- .meta({
150
- title: 'DoctypeMeta',
151
- description: 'Doctype metadata - complete definition of a doctype',
152
- });
package/dist/field.js DELETED
@@ -1,110 +0,0 @@
1
- import { z } from 'zod';
2
- import { StonecropFieldType } from './fieldtype';
3
- /**
4
- * Field options - flexible bag for type-specific configuration.
5
- *
6
- * Usage by fieldtype:
7
- * - Link/Doctype: target doctype slug as string ("customer", "sales-order-item")
8
- * - Select: array of choices (["Draft", "Submitted", "Cancelled"])
9
- * - Decimal: config object (\{ precision: 10, scale: 2 \})
10
- * - Code: config object (\{ language: "python" \})
11
- *
12
- * @public
13
- */
14
- export const FieldOptions = z
15
- .union([
16
- z.string(), // Link/Doctype target: "customer"
17
- z.array(z.string()), // Select choices: ["A", "B", "C"]
18
- z.record(z.string(), z.unknown()), // Config: \{ precision: 10, scale: 2 \}
19
- ])
20
- .meta({
21
- title: 'FieldOptions',
22
- description: 'Field options - flexible bag for type-specific configuration',
23
- });
24
- /**
25
- * Validation configuration for form fields
26
- * @public
27
- */
28
- export const FieldValidation = z
29
- .looseObject({
30
- /** Error message to display when validation fails */
31
- errorMessage: z.string(),
32
- })
33
- .meta({
34
- title: 'FieldValidation',
35
- description: 'Validation configuration for form fields',
36
- });
37
- /**
38
- * Unified field metadata - the single source of truth for field definitions.
39
- * Works for both forms (AForm) and tables (ATable).
40
- *
41
- * Core principle: "Text" is "Text" regardless of rendering context.
42
- *
43
- * @public
44
- */
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
- })
107
- .meta({
108
- title: 'FieldMeta',
109
- description: 'Unified field metadata - the single source of truth for field definitions, works for both forms (AForm) and tables (ATable)',
110
- });
package/dist/fieldtype.js DELETED
@@ -1,97 +0,0 @@
1
- import { z } from 'zod';
2
- /**
3
- * The complete list of field types built into Stonecrop.
4
- * User apps can use any string as a fieldtype; this const is the exhaustive set of types
5
- * that Stonecrop provides default components for.
6
- * @public
7
- */
8
- export const BUILTIN_FIELD_TYPES = [
9
- 'Data', // Short text, varchar
10
- 'Text', // Long text
11
- 'Int', // Integer
12
- 'Float', // Floating point (IEEE 754)
13
- 'Decimal', // Arbitrary precision decimal
14
- 'Check', // Boolean/checkbox
15
- 'Date', // Date only
16
- 'Time', // Time only
17
- 'Datetime', // Date and time
18
- 'Duration', // Time interval
19
- 'DateRange', // Date range
20
- 'JSON', // JSON data
21
- 'Code', // Code/source (with syntax highlighting)
22
- 'Link', // Reference to another doctype
23
- 'Attach', // File attachment
24
- 'Currency', // Currency value
25
- 'Quantity', // Quantity with unit
26
- 'Select', // Dropdown selection
27
- ];
28
- /**
29
- * Stonecrop field type — any non-empty string is valid; Stonecrop provides default components
30
- * for the builtin types listed in {@link BUILTIN_FIELD_TYPES}. Custom fieldtypes are supported
31
- * by supplying an explicit `component` on the field definition.
32
- * @public
33
- */
34
- export const StonecropFieldType = z.string().min(1).meta({
35
- title: 'StonecropFieldType',
36
- description: 'Semantic field types for Stonecrop doctypes, consistent across forms and tables',
37
- });
38
- /**
39
- * Returns `true` when `fieldtype` is one of the builtin types Stonecrop ships with.
40
- * @public
41
- */
42
- export function isBuiltinFieldType(fieldtype) {
43
- return BUILTIN_FIELD_TYPES.includes(fieldtype);
44
- }
45
- /**
46
- * Mapping from builtin fieldtypes to their default Vue component.
47
- * Components can be overridden in the field definition.
48
- * @public
49
- */
50
- export const TYPE_MAP = {
51
- // Text
52
- Data: { component: 'ATextInput', fieldtype: 'Data' },
53
- Text: { component: 'ATextInput', fieldtype: 'Text' },
54
- // Numeric
55
- Int: { component: 'ANumericInput', fieldtype: 'Int' },
56
- Float: { component: 'ANumericInput', fieldtype: 'Float' },
57
- Decimal: { component: 'ADecimalInput', fieldtype: 'Decimal' },
58
- // Boolean
59
- Check: { component: 'ACheckbox', fieldtype: 'Check' },
60
- // Date/Time
61
- Date: { component: 'ADate', fieldtype: 'Date' },
62
- Time: { component: 'ATimeInput', fieldtype: 'Time' },
63
- Datetime: { component: 'ADatetimePicker', fieldtype: 'Datetime' },
64
- Duration: { component: 'ADurationInput', fieldtype: 'Duration' },
65
- DateRange: { component: 'ADateRangePicker', fieldtype: 'DateRange' },
66
- // Structured
67
- JSON: { component: 'ACodeEditor', fieldtype: 'JSON' },
68
- Code: { component: 'ACodeEditor', fieldtype: 'Code' },
69
- // Relational
70
- Link: { component: 'ALink', fieldtype: 'Link' },
71
- // Files
72
- Attach: { component: 'AFileAttach', fieldtype: 'Attach' },
73
- // Specialized
74
- Currency: { component: 'ACurrencyInput', fieldtype: 'Currency' },
75
- Quantity: { component: 'AQuantityInput', fieldtype: 'Quantity' },
76
- Select: { component: 'ADropdown', fieldtype: 'Select' },
77
- };
78
- /**
79
- * Get the default component for a builtin field type.
80
- * For an open-string fieldtype that may be custom, use {@link resolveComponent} instead.
81
- * @param fieldtype - A builtin field type
82
- * @returns The default component name
83
- * @public
84
- */
85
- export function getDefaultComponent(fieldtype) {
86
- return TYPE_MAP[fieldtype]?.component ?? 'ATextInput';
87
- }
88
- /**
89
- * Resolve the component name for any fieldtype string, falling back to `'ATextInput'`
90
- * for unknown custom types.
91
- * @param fieldtype - Any fieldtype string (builtin or custom)
92
- * @returns The component name to use for rendering
93
- * @public
94
- */
95
- export function resolveComponent(fieldtype) {
96
- return isBuiltinFieldType(fieldtype) ? getDefaultComponent(fieldtype) : 'ATextInput';
97
- }