@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
@@ -1,225 +0,0 @@
1
- /**
2
- * Map StonecropFieldType to JSON Schema type
3
- */
4
- function fieldtypeToJSONSchema(fieldtype) {
5
- const typeMap = {
6
- Data: { type: 'string' },
7
- Text: { type: 'string' },
8
- Int: { type: 'integer' },
9
- Float: { type: 'number' },
10
- Decimal: { type: 'number' },
11
- Check: { type: 'boolean' },
12
- Date: { type: 'string', format: 'date' },
13
- Time: { type: 'string', format: 'time' },
14
- Datetime: { type: 'string', format: 'date-time' },
15
- Duration: { type: 'string' },
16
- DateRange: { type: 'object', properties: { start: { type: 'string', format: 'date' }, end: { type: 'string', format: 'date' } } },
17
- JSON: { type: 'object', additionalProperties: true },
18
- Code: { type: 'string' },
19
- Link: { type: 'string', description: 'Reference to another doctype' },
20
- Doctype: { type: 'array', items: { type: 'object' }, description: 'Child doctype records' },
21
- Attach: { type: 'string', format: 'uri', description: 'File attachment URL' },
22
- Currency: { type: 'number', description: 'Currency value' },
23
- Quantity: { type: 'number', description: 'Quantity with unit' },
24
- Select: { type: 'string' },
25
- };
26
- return typeMap[fieldtype] ?? { type: 'string' };
27
- }
28
- /**
29
- * Convert FieldOptions to JSON Schema additions
30
- */
31
- function fieldOptionsToJSONSchema(options, fieldtype) {
32
- const schema = {};
33
- if (fieldtype === 'Select' && Array.isArray(options)) {
34
- schema.enum = options;
35
- }
36
- if (fieldtype === 'Link' && typeof options === 'string') {
37
- schema.description = `Reference to ${options} doctype`;
38
- }
39
- if (fieldtype === 'Doctype' && typeof options === 'string') {
40
- schema.description = `Child records from ${options} doctype`;
41
- schema.items = { type: 'object', description: `${options} record` };
42
- }
43
- if (typeof options === 'object' && !Array.isArray(options)) {
44
- if (fieldtype === 'Decimal' && 'precision' in options && 'scale' in options) {
45
- const precision = options.precision;
46
- const scale = options.scale;
47
- schema.description = `Decimal(${precision}, ${scale})`;
48
- }
49
- if (fieldtype === 'Code' && 'language' in options) {
50
- schema.description = `Code snippet (${options.language})`;
51
- }
52
- }
53
- return schema;
54
- }
55
- /**
56
- * Convert a FieldMeta to JSON Schema
57
- */
58
- function fieldToJSONSchema(field) {
59
- const baseSchema = fieldtypeToJSONSchema(field.fieldtype);
60
- const optionsSchema = field.options ? fieldOptionsToJSONSchema(field.options, field.fieldtype) : {};
61
- const schema = {
62
- ...baseSchema,
63
- ...optionsSchema,
64
- };
65
- if (field.label) {
66
- schema.title = field.label;
67
- }
68
- if (field.default !== undefined) {
69
- schema.default = field.default;
70
- }
71
- if (field.hidden) {
72
- schema['x-hidden'] = true;
73
- }
74
- if (field.readOnly) {
75
- schema.readOnly = true;
76
- }
77
- if (field.width) {
78
- schema['x-width'] = field.width;
79
- }
80
- if (field.align) {
81
- schema['x-align'] = field.align;
82
- }
83
- return schema;
84
- }
85
- /**
86
- * Convert a DoctypeMeta to JSON Schema
87
- *
88
- * @param doctype - The doctype definition to convert
89
- * @returns JSON Schema representation of the doctype
90
- *
91
- * @example
92
- * ```typescript
93
- * import { DoctypeMeta, toJSONSchema } from '@stonecrop/schema'
94
- *
95
- * const taskDoctype = DoctypeMeta.parse({
96
- * name: 'Task',
97
- * fields: [
98
- * { fieldname: 'title', fieldtype: 'Data', required: true },
99
- * { fieldname: 'status', fieldtype: 'Select', options: ['Open', 'Closed'] }
100
- * ]
101
- * })
102
- *
103
- * const jsonSchema = toJSONSchema(taskDoctype)
104
- * // => {
105
- * // schema: { type: 'object', properties: { title: {...}, status: {...} }, required: ['title'] },
106
- * // meta: { name: 'Task' }
107
- * // }
108
- * ```
109
- *
110
- * @public
111
- */
112
- export function toJSONSchema(doctype) {
113
- const properties = {};
114
- const required = [];
115
- for (const field of doctype.fields) {
116
- properties[field.fieldname] = fieldToJSONSchema(field);
117
- if (field.required) {
118
- required.push(field.fieldname);
119
- }
120
- }
121
- const schema = {
122
- $schema: 'https://json-schema.org/draft/2020-12/schema',
123
- type: 'object',
124
- properties,
125
- title: doctype.name,
126
- };
127
- if (required.length > 0) {
128
- schema.required = required;
129
- }
130
- if (doctype.slug) {
131
- schema['x-slug'] = doctype.slug;
132
- }
133
- if (doctype.tableName) {
134
- schema['x-tableName'] = doctype.tableName;
135
- }
136
- const result = {
137
- schema,
138
- meta: {
139
- name: doctype.name,
140
- slug: doctype.slug,
141
- tableName: doctype.tableName,
142
- inherits: doctype.inherits,
143
- listDoctype: doctype.listDoctype,
144
- parentDoctype: doctype.parentDoctype,
145
- },
146
- };
147
- if (doctype.workflow) {
148
- result.workflow = {
149
- states: doctype.workflow.states,
150
- actions: doctype.workflow.actions ? workflowActionsToJSON(doctype.workflow.actions) : undefined,
151
- };
152
- }
153
- return result;
154
- }
155
- /**
156
- * Convert workflow actions to JSON Schema friendly format
157
- */
158
- function workflowActionsToJSON(actions) {
159
- const result = {};
160
- for (const [name, action] of Object.entries(actions)) {
161
- result[name] = {
162
- label: action.label,
163
- handler: action.handler,
164
- requiredFields: action.requiredFields,
165
- allowedStates: action.allowedStates,
166
- confirm: action.confirm,
167
- args: action.args,
168
- };
169
- }
170
- return result;
171
- }
172
- /**
173
- * Generate a collection of JSON Schemas from multiple doctypes
174
- *
175
- * @param doctypes - Array of doctype definitions
176
- * @returns Map of doctype name to JSON Schema
177
- *
178
- * @example
179
- * ```typescript
180
- * import { DoctypeMeta, toSchemasCollection } from '@stonecrop/schema'
181
- *
182
- * const doctypes = [
183
- * DoctypeMeta.parse({ name: 'Task', fields: [...] }),
184
- * DoctypeMeta.parse({ name: 'Customer', fields: [...] }),
185
- * ]
186
- *
187
- * const collection = toSchemasCollection(doctypes)
188
- * // => { Task: {...}, Customer: {...} }
189
- * ```
190
- *
191
- * @public
192
- */
193
- export function toSchemasCollection(doctypes) {
194
- const collection = {};
195
- for (const doctype of doctypes) {
196
- collection[doctype.name] = toJSONSchema(doctype);
197
- }
198
- return collection;
199
- }
200
- /**
201
- * Generate OpenAPI schema components from doctypes
202
- *
203
- * @param doctypes - Array of doctype definitions
204
- * @returns OpenAPI 3.1 compatible components object
205
- *
206
- * @example
207
- * ```typescript
208
- * import { DoctypeMeta, toOpenAPIComponents } from '@stonecrop/schema'
209
- *
210
- * const doctypes = [DoctypeMeta.parse({ name: 'Task', fields: [...] })]
211
- *
212
- * const components = toOpenAPIComponents(doctypes)
213
- * // => { schemas: { Task: {...} } }
214
- * ```
215
- *
216
- * @public
217
- */
218
- export function toOpenAPIComponents(doctypes) {
219
- const schemas = {};
220
- for (const doctype of doctypes) {
221
- const { schema } = toJSONSchema(doctype);
222
- schemas[doctype.name] = schema;
223
- }
224
- return { schemas };
225
- }
package/dist/naming.js DELETED
@@ -1,106 +0,0 @@
1
- /**
2
- * Naming Convention Utilities
3
- * Converts between various naming conventions (snake_case, camelCase, PascalCase, kebab-case)
4
- * @packageDocumentation
5
- */
6
- /**
7
- * Converts snake_case to camelCase
8
- * @param snakeCase - Snake case string
9
- * @returns Camel case string
10
- * @public
11
- * @example
12
- * ```typescript
13
- * snakeToCamel('user_email') // 'userEmail'
14
- * snakeToCamel('created_at') // 'createdAt'
15
- * ```
16
- */
17
- export function snakeToCamel(snakeCase) {
18
- return snakeCase.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase());
19
- }
20
- /**
21
- * Converts camelCase to snake_case
22
- * @param camelCase - Camel case string
23
- * @returns Snake case string
24
- * @public
25
- * @example
26
- * ```typescript
27
- * camelToSnake('userEmail') // 'user_email'
28
- * camelToSnake('createdAt') // 'created_at'
29
- * ```
30
- */
31
- export function camelToSnake(camelCase) {
32
- return camelCase.replace(/[A-Z]/g, letter => `_${letter.toLowerCase()}`);
33
- }
34
- /**
35
- * Converts snake_case to Title Case label
36
- * @param snakeCase - Snake case string
37
- * @returns Title case label
38
- * @public
39
- * @example
40
- * ```typescript
41
- * snakeToLabel('user_email') // 'User Email'
42
- * snakeToLabel('first_name') // 'First Name'
43
- * ```
44
- */
45
- export function snakeToLabel(snakeCase) {
46
- return snakeCase
47
- .split('_')
48
- .map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
49
- .join(' ');
50
- }
51
- /**
52
- * Converts camelCase to Title Case label
53
- * @param camelCase - Camel case string
54
- * @returns Title case label
55
- * @public
56
- * @example
57
- * ```typescript
58
- * camelToLabel('userEmail') // 'User Email'
59
- * camelToLabel('firstName') // 'First Name'
60
- * ```
61
- */
62
- export function camelToLabel(camelCase) {
63
- const withSpaces = camelCase.replace(/([A-Z])/g, ' $1').trim();
64
- return withSpaces.charAt(0).toUpperCase() + withSpaces.slice(1);
65
- }
66
- /**
67
- * Convert table name to PascalCase doctype name
68
- * @param tableName - SQL table name (snake_case)
69
- * @returns PascalCase name
70
- * @public
71
- */
72
- export function toPascalCase(tableName) {
73
- return tableName
74
- .split(/[-_\s]+/)
75
- .map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
76
- .join('');
77
- }
78
- /**
79
- * Convert to kebab-case slug
80
- * @param name - Name to convert
81
- * @returns kebab-case slug
82
- * @public
83
- */
84
- export function toSlug(name) {
85
- return name
86
- .replace(/([a-z])([A-Z])/g, '$1-$2')
87
- .replace(/[\s_]+/g, '-')
88
- .toLowerCase();
89
- }
90
- /**
91
- * Convert PascalCase to snake_case (e.g., for deriving table names from type names)
92
- * @param pascal - PascalCase string
93
- * @returns snake_case string
94
- * @public
95
- * @example
96
- * ```typescript
97
- * pascalToSnake('SalesOrder') // 'sales_order'
98
- * pascalToSnake('SalesOrderItem') // 'sales_order_item'
99
- * ```
100
- */
101
- export function pascalToSnake(pascal) {
102
- return pascal
103
- .replace(/([a-z])([A-Z])/g, '$1_$2')
104
- .replace(/[\s-]+/g, '_')
105
- .toLowerCase();
106
- }
@@ -1,63 +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 declare const BUILTIN_FIELD_TYPES: readonly ["Data", "Text", "Int", "Float", "Decimal", "Check", "Date", "Time", "Datetime", "Duration", "DateRange", "JSON", "Code", "Link", "Attach", "Currency", "Quantity", "Select", "PrimaryKey", "Fieldset", "Display"];
9
- /**
10
- * Union of all builtin fieldtype string literals.
11
- * @public
12
- */
13
- export type BuiltinFieldType = (typeof BUILTIN_FIELD_TYPES)[number];
14
- /**
15
- * Stonecrop field type — any non-empty string is valid; Stonecrop provides default components
16
- * for the builtin types listed in {@link BUILTIN_FIELD_TYPES}. Custom fieldtypes are supported
17
- * by supplying an explicit `component` on the field definition.
18
- * @public
19
- */
20
- export declare const StonecropFieldType: z.ZodString;
21
- /**
22
- * Returns `true` when `fieldtype` is one of the builtin types Stonecrop ships with.
23
- * @public
24
- */
25
- export declare function isBuiltinFieldType(fieldtype: string): fieldtype is BuiltinFieldType;
26
- /**
27
- * Field template for TYPE_MAP entries.
28
- * Defines the default component and semantic field type for a field.
29
- * @public
30
- */
31
- export interface FieldTemplate {
32
- /**
33
- * The Vue component name to render this field (e.g., 'ATextInput', 'ADropdown')
34
- */
35
- component: string;
36
- /**
37
- * The semantic field type (e.g., 'Data', 'Int', 'Select')
38
- */
39
- fieldtype: BuiltinFieldType;
40
- }
41
- /**
42
- * Mapping from builtin fieldtypes to their default Vue component.
43
- * Components can be overridden in the field definition.
44
- * @public
45
- */
46
- export declare const TYPE_MAP: Record<BuiltinFieldType, FieldTemplate>;
47
- /**
48
- * Get the default component for a builtin field type.
49
- * For an open-string fieldtype that may be custom, use {@link resolveComponent} instead.
50
- * @param fieldtype - A builtin field type
51
- * @returns The default component name
52
- * @public
53
- */
54
- export declare function getDefaultComponent(fieldtype: BuiltinFieldType): string;
55
- /**
56
- * Resolve the component name for any fieldtype string, falling back to `'ATextInput'`
57
- * for unknown custom types.
58
- * @param fieldtype - Any fieldtype string (builtin or custom)
59
- * @returns The component name to use for rendering
60
- * @public
61
- */
62
- export declare function resolveComponent(fieldtype: string): string;
63
- //# sourceMappingURL=fieldtype.d.ts.map
@@ -1 +0,0 @@
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,CAyC5D,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"}
@@ -1,105 +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
- 'PrimaryKey', // Primary key field — used by the middleware to identify the record's PK column
28
- 'Fieldset', // UI grouping container — no DB column; children are flat columns
29
- 'Display', // Computed/read-only field — no DB column; excluded from SQL SELECT
30
- ];
31
- /**
32
- * Stonecrop field type — any non-empty string is valid; Stonecrop provides default components
33
- * for the builtin types listed in {@link BUILTIN_FIELD_TYPES}. Custom fieldtypes are supported
34
- * by supplying an explicit `component` on the field definition.
35
- * @public
36
- */
37
- export const StonecropFieldType = z.string().min(1).meta({
38
- title: 'StonecropFieldType',
39
- description: 'Semantic field types for Stonecrop doctypes, consistent across forms and tables',
40
- });
41
- /**
42
- * Returns `true` when `fieldtype` is one of the builtin types Stonecrop ships with.
43
- * @public
44
- */
45
- export function isBuiltinFieldType(fieldtype) {
46
- return BUILTIN_FIELD_TYPES.includes(fieldtype);
47
- }
48
- /**
49
- * Mapping from builtin fieldtypes to their default Vue component.
50
- * Components can be overridden in the field definition.
51
- * @public
52
- */
53
- export const TYPE_MAP = {
54
- // Text
55
- Data: { component: 'ATextInput', fieldtype: 'Data' },
56
- Text: { component: 'ATextInput', fieldtype: 'Text' },
57
- // Numeric
58
- Int: { component: 'ANumericInput', fieldtype: 'Int' },
59
- Float: { component: 'ANumericInput', fieldtype: 'Float' },
60
- Decimal: { component: 'ADecimalInput', fieldtype: 'Decimal' },
61
- // Boolean
62
- Check: { component: 'ACheckbox', fieldtype: 'Check' },
63
- // Date/Time
64
- Date: { component: 'ADate', fieldtype: 'Date' },
65
- Time: { component: 'ATimeInput', fieldtype: 'Time' },
66
- Datetime: { component: 'ADatetimePicker', fieldtype: 'Datetime' },
67
- Duration: { component: 'ADurationInput', fieldtype: 'Duration' },
68
- DateRange: { component: 'ADateRangePicker', fieldtype: 'DateRange' },
69
- // Structured
70
- JSON: { component: 'ACodeEditor', fieldtype: 'JSON' },
71
- Code: { component: 'ACodeEditor', fieldtype: 'Code' },
72
- // Relational
73
- Link: { component: 'ALink', fieldtype: 'Link' },
74
- // Files
75
- Attach: { component: 'AFileAttach', fieldtype: 'Attach' },
76
- // Specialized
77
- Currency: { component: 'ACurrencyInput', fieldtype: 'Currency' },
78
- Quantity: { component: 'AQuantityInput', fieldtype: 'Quantity' },
79
- Select: { component: 'ADropdown', fieldtype: 'Select' },
80
- // Identity — PK fields are typically hidden; no interactive component is needed
81
- PrimaryKey: { component: 'ATextInput', fieldtype: 'PrimaryKey' },
82
- // Layout — UI grouping containers and computed fields with no backing DB column
83
- Fieldset: { component: 'AFieldset', fieldtype: 'Fieldset' },
84
- Display: { component: 'ATextInput', fieldtype: 'Display' },
85
- };
86
- /**
87
- * Get the default component for a builtin field type.
88
- * For an open-string fieldtype that may be custom, use {@link resolveComponent} instead.
89
- * @param fieldtype - A builtin field type
90
- * @returns The default component name
91
- * @public
92
- */
93
- export function getDefaultComponent(fieldtype) {
94
- return TYPE_MAP[fieldtype]?.component ?? 'ATextInput';
95
- }
96
- /**
97
- * Resolve the component name for any fieldtype string, falling back to `'ATextInput'`
98
- * for unknown custom types.
99
- * @param fieldtype - Any fieldtype string (builtin or custom)
100
- * @returns The component name to use for rendering
101
- * @public
102
- */
103
- export function resolveComponent(fieldtype) {
104
- return isBuiltinFieldType(fieldtype) ? getDefaultComponent(fieldtype) : 'ATextInput';
105
- }
@@ -1,95 +0,0 @@
1
- import type { DoctypeMeta } from './doctype';
2
- /**
3
- * JSON Schema representation for a doctype
4
- * @public
5
- */
6
- export interface DoctypeJSONSchema {
7
- /** JSON Schema for the doctype structure */
8
- schema: Record<string, unknown>;
9
- /** Metadata from the doctype definition */
10
- meta: {
11
- name: string;
12
- slug?: string;
13
- tableName?: string;
14
- inherits?: string;
15
- listDoctype?: string;
16
- parentDoctype?: string;
17
- };
18
- /** Workflow metadata if present */
19
- workflow?: {
20
- states?: string[];
21
- actions?: Record<string, Record<string, unknown>>;
22
- };
23
- }
24
- /**
25
- * Convert a DoctypeMeta to JSON Schema
26
- *
27
- * @param doctype - The doctype definition to convert
28
- * @returns JSON Schema representation of the doctype
29
- *
30
- * @example
31
- * ```typescript
32
- * import { DoctypeMeta, toJSONSchema } from '@stonecrop/schema'
33
- *
34
- * const taskDoctype = DoctypeMeta.parse({
35
- * name: 'Task',
36
- * fields: [
37
- * { fieldname: 'title', fieldtype: 'Data', required: true },
38
- * { fieldname: 'status', fieldtype: 'Select', options: ['Open', 'Closed'] }
39
- * ]
40
- * })
41
- *
42
- * const jsonSchema = toJSONSchema(taskDoctype)
43
- * // => {
44
- * // schema: { type: 'object', properties: { title: {...}, status: {...} }, required: ['title'] },
45
- * // meta: { name: 'Task' }
46
- * // }
47
- * ```
48
- *
49
- * @public
50
- */
51
- export declare function toJSONSchema(doctype: DoctypeMeta): DoctypeJSONSchema;
52
- /**
53
- * Generate a collection of JSON Schemas from multiple doctypes
54
- *
55
- * @param doctypes - Array of doctype definitions
56
- * @returns Map of doctype name to JSON Schema
57
- *
58
- * @example
59
- * ```typescript
60
- * import { DoctypeMeta, toSchemasCollection } from '@stonecrop/schema'
61
- *
62
- * const doctypes = [
63
- * DoctypeMeta.parse({ name: 'Task', fields: [...] }),
64
- * DoctypeMeta.parse({ name: 'Customer', fields: [...] }),
65
- * ]
66
- *
67
- * const collection = toSchemasCollection(doctypes)
68
- * // => { Task: {...}, Customer: {...} }
69
- * ```
70
- *
71
- * @public
72
- */
73
- export declare function toSchemasCollection(doctypes: DoctypeMeta[]): Record<string, DoctypeJSONSchema>;
74
- /**
75
- * Generate OpenAPI schema components from doctypes
76
- *
77
- * @param doctypes - Array of doctype definitions
78
- * @returns OpenAPI 3.1 compatible components object
79
- *
80
- * @example
81
- * ```typescript
82
- * import { DoctypeMeta, toOpenAPIComponents } from '@stonecrop/schema'
83
- *
84
- * const doctypes = [DoctypeMeta.parse({ name: 'Task', fields: [...] })]
85
- *
86
- * const components = toOpenAPIComponents(doctypes)
87
- * // => { schemas: { Task: {...} } }
88
- * ```
89
- *
90
- * @public
91
- */
92
- export declare function toOpenAPIComponents(doctypes: DoctypeMeta[]): {
93
- schemas: Record<string, Record<string, unknown>>;
94
- };
95
- //# sourceMappingURL=jsonschema.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"jsonschema.d.ts","sourceRoot":"","sources":["../../src/jsonschema.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAkC,MAAM,WAAW,CAAA;AAI5E;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IACjC,4CAA4C;IAC5C,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAE/B,2CAA2C;IAC3C,IAAI,EAAE;QACL,IAAI,EAAE,MAAM,CAAA;QACZ,IAAI,CAAC,EAAE,MAAM,CAAA;QACb,SAAS,CAAC,EAAE,MAAM,CAAA;QAClB,QAAQ,CAAC,EAAE,MAAM,CAAA;QACjB,WAAW,CAAC,EAAE,MAAM,CAAA;QACpB,aAAa,CAAC,EAAE,MAAM,CAAA;KACtB,CAAA;IAED,mCAAmC;IACnC,QAAQ,CAAC,EAAE;QACV,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;QACjB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAA;KACjD,CAAA;CACD;AAuGD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,WAAW,GAAG,iBAAiB,CAmDpE;AAsBD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,WAAW,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAQ9F;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,WAAW,EAAE,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAA;CAAE,CASjH"}
@@ -1,66 +0,0 @@
1
- /**
2
- * Minimal field shape representing the intersection of form field properties
3
- * (fieldname, hidden, etc.) and table column properties (cellComponent, pinned, format, etc.)
4
- * so that a doctype's fields array can be passed directly to table components without
5
- * requiring callers to pre-build TableColumn objects.
6
- *
7
- * Notes on specific properties:
8
- * - `align` uses an explicit string union rather than CanvasTextAlign — this
9
- * package is used server-side by the CLI where browser DOM types are absent.
10
- * - `format` is a serialized function string; the table store's getFormattedValue
11
- * already handles typeof format === 'string' via Function(...).
12
- * - `mask` is intentionally omitted — ACell has mask commented out as a TODO
13
- * and TableColumn.mask is function-typed only; including it here would create
14
- * an incompatible type.
15
- * - `modalComponent` is string-only (no function variant) — functions cannot
16
- * appear in schema JSON.
17
- *
18
- * @public
19
- */
20
- export interface ColumnSchema {
21
- /** Unique identifier for the field within its doctype. Maps to `name` on `TableColumn`. */
22
- fieldname: string;
23
- /** Semantic field type (e.g. `'Data'`, `'Int'`, `'Date'`, `'Check'`). Fields without a `fieldtype` are treated as non-scalar (nested table/fieldset) and excluded by `schemaToColumns`. */
24
- fieldtype?: string;
25
- /** Human-readable column header. */
26
- label?: string;
27
- /** When `true`, the field is excluded from the derived columns by `schemaToColumns`. */
28
- hidden?: boolean;
29
- /** Horizontal text alignment for the column cell and header. */
30
- align?: 'left' | 'right' | 'center' | 'start' | 'end';
31
- /** Whether the column cell is editable in the table. */
32
- edit?: boolean;
33
- /** CSS width of the column (e.g. `'20ch'`, `'200px'`). */
34
- width?: string;
35
- /** When `true`, the column is pinned to the left side of the table. */
36
- pinned?: boolean;
37
- /** When `true`, the column can be resized by dragging the header edge. */
38
- resizable?: boolean;
39
- /** When `true`, clicking the column header sorts the table by this column. */
40
- sortable?: boolean;
41
- /** When `true`, a filter control is rendered in the column header. */
42
- filterable?: boolean;
43
- /** The type of filter control to render. Defaults are derived from `fieldtype` when absent. */
44
- filterType?: 'text' | 'select' | 'number' | 'date' | 'dateRange' | 'checkbox' | 'component';
45
- /** Static option list for `filterType: 'select'`. When absent, options are derived from unique row values. */
46
- filterOptions?: any[];
47
- /** Registered component name used when `filterType` is `'component'`. */
48
- filterComponent?: string;
49
- /** Registered component name rendered inside the table cell instead of the default display. */
50
- cellComponent?: string;
51
- /** Props passed to `cellComponent`. */
52
- cellComponentProps?: Record<string, any>;
53
- /** Registered component name rendered in the cell's modal editor. String-only — functions cannot appear in schema JSON. */
54
- modalComponent?: string;
55
- /** Extra props passed to `modalComponent` in addition to the standard cell props. */
56
- modalComponentExtraProps?: Record<string, any>;
57
- /** Serialized function string used to format the cell value for display. Deserialized at render time by the table store's `getFormattedValue`. */
58
- format?: string;
59
- /** When `true`, this column is treated as a Gantt bar column. */
60
- isGantt?: boolean;
61
- /** Registered component name used to render Gantt bars in this column. */
62
- ganttComponent?: string;
63
- /** Number of columns this cell spans in the table layout. */
64
- colspan?: number;
65
- }
66
- //# sourceMappingURL=schema-field.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"schema-field.d.ts","sourceRoot":"","sources":["../../src/schema-field.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,WAAW,YAAY;IAC5B,2FAA2F;IAC3F,SAAS,EAAE,MAAM,CAAA;IACjB,2LAA2L;IAC3L,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,oCAAoC;IACpC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,wFAAwF;IACxF,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,gEAAgE;IAChE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,QAAQ,GAAG,OAAO,GAAG,KAAK,CAAA;IACrD,wDAAwD;IACxD,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,0DAA0D;IAC1D,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,uEAAuE;IACvE,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,0EAA0E;IAC1E,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,8EAA8E;IAC9E,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,sEAAsE;IACtE,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,+FAA+F;IAC/F,UAAU,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAM,GAAG,WAAW,GAAG,UAAU,GAAG,WAAW,CAAA;IAC3F,8GAA8G;IAC9G,aAAa,CAAC,EAAE,GAAG,EAAE,CAAA;IACrB,yEAAyE;IACzE,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,+FAA+F;IAC/F,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,uCAAuC;IACvC,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IACxC,2HAA2H;IAC3H,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,qFAAqF;IACrF,wBAAwB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IAC9C,kJAAkJ;IAClJ,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,iEAAiE;IACjE,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,0EAA0E;IAC1E,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,6DAA6D;IAC7D,OAAO,CAAC,EAAE,MAAM,CAAA;CAChB"}
File without changes