@carthooks/arcubase-cli 0.1.2 → 0.1.4

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 (106) hide show
  1. package/bundle/arcubase-admin.mjs +1238 -16
  2. package/bundle/arcubase.mjs +1238 -16
  3. package/dist/bin/arcubase-admin.js +0 -0
  4. package/dist/bin/arcubase.js +0 -0
  5. package/dist/runtime/command_registry.d.ts +8 -0
  6. package/dist/runtime/command_registry.d.ts.map +1 -1
  7. package/dist/runtime/command_registry.js +35 -0
  8. package/dist/runtime/entity_save_schema.d.ts +15 -0
  9. package/dist/runtime/entity_save_schema.d.ts.map +1 -0
  10. package/dist/runtime/entity_save_schema.js +641 -0
  11. package/dist/runtime/errors.d.ts +11 -0
  12. package/dist/runtime/errors.d.ts.map +1 -1
  13. package/dist/runtime/execute.d.ts.map +1 -1
  14. package/dist/runtime/execute.js +294 -12
  15. package/dist/runtime/upload.d.ts +13 -0
  16. package/dist/runtime/upload.d.ts.map +1 -0
  17. package/dist/runtime/upload.js +148 -0
  18. package/dist/runtime/zod_registry.d.ts +6 -0
  19. package/dist/runtime/zod_registry.d.ts.map +1 -1
  20. package/dist/runtime/zod_registry.js +136 -0
  21. package/dist/tests/command_registry.test.js +5 -0
  22. package/dist/tests/entity_save_schema.test.d.ts +2 -0
  23. package/dist/tests/entity_save_schema.test.d.ts.map +1 -0
  24. package/dist/tests/entity_save_schema.test.js +221 -0
  25. package/dist/tests/execute_validation.test.js +603 -0
  26. package/dist/tests/help.test.js +49 -0
  27. package/dist/tests/upload.test.d.ts +2 -0
  28. package/dist/tests/upload.test.d.ts.map +1 -0
  29. package/dist/tests/upload.test.js +107 -0
  30. package/package.json +1 -1
  31. package/sdk-dist/docs/runtime-reference/README.md +187 -0
  32. package/sdk-dist/docs/runtime-reference/entity-schema/README.md +120 -0
  33. package/sdk-dist/docs/runtime-reference/entity-schema/address.md +34 -0
  34. package/sdk-dist/docs/runtime-reference/entity-schema/boolean.md +37 -0
  35. package/sdk-dist/docs/runtime-reference/entity-schema/button.md +47 -0
  36. package/sdk-dist/docs/runtime-reference/entity-schema/checkbox.md +61 -0
  37. package/sdk-dist/docs/runtime-reference/entity-schema/datasets.md +35 -0
  38. package/sdk-dist/docs/runtime-reference/entity-schema/datetime.md +40 -0
  39. package/sdk-dist/docs/runtime-reference/entity-schema/department.md +33 -0
  40. package/sdk-dist/docs/runtime-reference/entity-schema/departments.md +34 -0
  41. package/sdk-dist/docs/runtime-reference/entity-schema/divider.md +39 -0
  42. package/sdk-dist/docs/runtime-reference/entity-schema/file.md +53 -0
  43. package/sdk-dist/docs/runtime-reference/entity-schema/formula.md +44 -0
  44. package/sdk-dist/docs/runtime-reference/entity-schema/image.md +52 -0
  45. package/sdk-dist/docs/runtime-reference/entity-schema/linkto.md +67 -0
  46. package/sdk-dist/docs/runtime-reference/entity-schema/location.md +32 -0
  47. package/sdk-dist/docs/runtime-reference/entity-schema/lookup.md +41 -0
  48. package/sdk-dist/docs/runtime-reference/entity-schema/member.md +37 -0
  49. package/sdk-dist/docs/runtime-reference/entity-schema/members.md +31 -0
  50. package/sdk-dist/docs/runtime-reference/entity-schema/number.md +70 -0
  51. package/sdk-dist/docs/runtime-reference/entity-schema/query.md +50 -0
  52. package/sdk-dist/docs/runtime-reference/entity-schema/radio.md +53 -0
  53. package/sdk-dist/docs/runtime-reference/entity-schema/relation.md +55 -0
  54. package/sdk-dist/docs/runtime-reference/entity-schema/relationfield.md +38 -0
  55. package/sdk-dist/docs/runtime-reference/entity-schema/rollup.md +54 -0
  56. package/sdk-dist/docs/runtime-reference/entity-schema/select.md +63 -0
  57. package/sdk-dist/docs/runtime-reference/entity-schema/selects.md +51 -0
  58. package/sdk-dist/docs/runtime-reference/entity-schema/serialnumber.md +48 -0
  59. package/sdk-dist/docs/runtime-reference/entity-schema/signature.md +31 -0
  60. package/sdk-dist/docs/runtime-reference/entity-schema/status.md +70 -0
  61. package/sdk-dist/docs/runtime-reference/entity-schema/subform.md +74 -0
  62. package/sdk-dist/docs/runtime-reference/entity-schema/tags.md +19 -0
  63. package/sdk-dist/docs/runtime-reference/entity-schema/text.md +76 -0
  64. package/sdk-dist/docs/runtime-reference/entity-schema/textarea.md +47 -0
  65. package/sdk-dist/docs/runtime-reference/entity-schema/workflow_status.md +17 -0
  66. package/sdk-dist/docs/runtime-reference/entity-schema.md +197 -0
  67. package/sdk-dist/docs/runtime-reference/examples/README.md +51 -0
  68. package/sdk-dist/docs/runtime-reference/examples/crm-01/README.md +20 -0
  69. package/sdk-dist/docs/runtime-reference/examples/mes-01/README.md +21 -0
  70. package/sdk-dist/docs/runtime-reference/examples/oms-01/README.md +183 -0
  71. package/sdk-dist/docs/runtime-reference/examples/oms-01/app-overview.md +79 -0
  72. package/sdk-dist/docs/runtime-reference/examples/oms-01/create-app.json +3 -0
  73. package/sdk-dist/docs/runtime-reference/examples/oms-01/goods-receipt.create-entity.json +3 -0
  74. package/sdk-dist/docs/runtime-reference/examples/oms-01/goods-receipt.schema.json +159 -0
  75. package/sdk-dist/docs/runtime-reference/examples/oms-01/item-master.create-entity.json +3 -0
  76. package/sdk-dist/docs/runtime-reference/examples/oms-01/item-master.schema.json +179 -0
  77. package/sdk-dist/docs/runtime-reference/examples/oms-01/picking-list.create-entity.json +3 -0
  78. package/sdk-dist/docs/runtime-reference/examples/oms-01/picking-list.schema.json +168 -0
  79. package/sdk-dist/docs/runtime-reference/examples/oms-01/purchase-order.create-entity.json +3 -0
  80. package/sdk-dist/docs/runtime-reference/examples/oms-01/purchase-order.schema.json +417 -0
  81. package/sdk-dist/docs/runtime-reference/examples/oms-01/sales-order.bulk-update.json +22 -0
  82. package/sdk-dist/docs/runtime-reference/examples/oms-01/sales-order.create-entity.json +3 -0
  83. package/sdk-dist/docs/runtime-reference/examples/oms-01/sales-order.query.json +10 -0
  84. package/sdk-dist/docs/runtime-reference/examples/oms-01/sales-order.row.insert.json +28 -0
  85. package/sdk-dist/docs/runtime-reference/examples/oms-01/sales-order.schema.json +398 -0
  86. package/sdk-dist/docs/runtime-reference/examples/oms-01/sales-order.selection.condition.json +13 -0
  87. package/sdk-dist/docs/runtime-reference/examples/oms-01/sales-order.selection.ids.json +7 -0
  88. package/sdk-dist/docs/runtime-reference/examples/oms-01/stock-issue.create-entity.json +3 -0
  89. package/sdk-dist/docs/runtime-reference/examples/oms-01/stock-issue.schema.json +137 -0
  90. package/sdk-dist/docs/runtime-reference/examples/wms-01/README.md +21 -0
  91. package/sdk-dist/docs/runtime-reference/row-crud.md +188 -0
  92. package/sdk-dist/docs/runtime-reference/search-and-bulk-actions.md +494 -0
  93. package/sdk-dist/docs/runtime-reference/table-lifecycle.md +135 -0
  94. package/sdk-dist/docs/runtime-reference/uploads.md +106 -0
  95. package/sdk-dist/docs/runtime-reference/workflow/README.md +19 -0
  96. package/src/runtime/command_registry.ts +47 -0
  97. package/src/runtime/entity_save_schema.ts +708 -0
  98. package/src/runtime/errors.ts +12 -0
  99. package/src/runtime/execute.ts +367 -12
  100. package/src/runtime/upload.ts +196 -0
  101. package/src/runtime/zod_registry.ts +156 -0
  102. package/src/tests/command_registry.test.ts +6 -0
  103. package/src/tests/entity_save_schema.test.ts +236 -0
  104. package/src/tests/execute_validation.test.ts +781 -0
  105. package/src/tests/help.test.ts +60 -0
  106. package/src/tests/upload.test.ts +133 -0
@@ -0,0 +1,641 @@
1
+ import { z } from 'zod';
2
+ import { EntityOptionsSchema, EntitySerialUpdaterVOSchema } from '../generated/zod_registry.generated.js';
3
+ const simpleFieldTypes = [
4
+ 'text',
5
+ 'textarea',
6
+ 'number',
7
+ 'datetime',
8
+ 'boolean',
9
+ 'button',
10
+ 'address',
11
+ 'datasets',
12
+ 'department',
13
+ 'departments',
14
+ 'divider',
15
+ 'file',
16
+ 'image',
17
+ 'location',
18
+ 'member',
19
+ 'members',
20
+ 'signature',
21
+ 'tags',
22
+ 'workflow_status',
23
+ 'mobile',
24
+ ];
25
+ const enumFieldTypes = ['select', 'selects', 'radio', 'checkbox', 'status'];
26
+ const relationFieldTypes = ['linkto', 'relation', 'query'];
27
+ const strictFieldTypes = new Set([
28
+ ...simpleFieldTypes,
29
+ ...enumFieldTypes,
30
+ ...relationFieldTypes,
31
+ 'formula',
32
+ 'lookup',
33
+ 'relationfield',
34
+ 'rollup',
35
+ 'serialnumber',
36
+ 'subform',
37
+ ]);
38
+ const relationTypeSchema = z.union([z.literal('entity'), z.literal('aggregation')]);
39
+ const linkModeSchema = z.union([z.literal('manual'), z.literal('auto')]);
40
+ const linkStructureSchema = z.union([z.literal('single'), z.literal('multiple')]);
41
+ const enumItemSchema = z.object({
42
+ key: z.union([z.number(), z.string()]).optional(),
43
+ value: z.string().min(1),
44
+ }).passthrough();
45
+ const statusItemSchema = z.object({
46
+ key: z.union([z.number(), z.string()]).optional(),
47
+ code: z.union([z.number(), z.string()]),
48
+ value: z.string().min(1),
49
+ }).passthrough();
50
+ const sortConfigSchema = z.object({
51
+ column: z.string().min(1),
52
+ order: z.union([z.literal('asc'), z.literal('desc')]),
53
+ }).strict();
54
+ const relationOptionsSchema = z.object({
55
+ entity_id: z.number().int().positive(),
56
+ app_id: z.number().int().positive(),
57
+ type: relationTypeSchema,
58
+ show_fields: z.array(z.number().int().positive()).optional(),
59
+ condition: z.record(z.string(), z.any()).optional(),
60
+ sorts: z.array(sortConfigSchema).optional(),
61
+ queryFields: z.array(z.number().int().positive()).optional(),
62
+ subform_id: z.number().int().positive().optional(),
63
+ }).strict();
64
+ const lookupRelationSchema = z.object({
65
+ local_linkto_field_id: z.number().int().min(1001),
66
+ target_field_id: z.number().int().min(1001),
67
+ target_field_type: z.string().min(1),
68
+ }).strict();
69
+ const relationFieldRelationSchema = z.object({
70
+ app_id: z.number().int().positive(),
71
+ entity_id: z.number().int().positive(),
72
+ type: relationTypeSchema.optional(),
73
+ show_fields: z.array(z.number().int().positive()).optional(),
74
+ condition: z.record(z.string(), z.any()).optional(),
75
+ sorts: z.array(sortConfigSchema).optional(),
76
+ queryFields: z.array(z.number().int().positive()).optional(),
77
+ subform_id: z.number().int().positive().optional(),
78
+ }).strict();
79
+ const formulaSchema = z.object({
80
+ code: z.string().min(1),
81
+ jsonlogic: z.record(z.string(), z.any()),
82
+ }).strict();
83
+ const serialPartBuildinStringSchema = z.object({
84
+ mode: z.literal('buildin'),
85
+ type: z.literal('string'),
86
+ options: z.object({
87
+ value: z.string(),
88
+ }).strict(),
89
+ }).strict();
90
+ const serialPartBuildinDateSchema = z.object({
91
+ mode: z.literal('buildin'),
92
+ type: z.literal('date'),
93
+ options: z.object({
94
+ format: z.string().optional(),
95
+ perdefined: z.boolean().optional(),
96
+ perdefinedFormat: z.string().optional(),
97
+ }).strict().refine((value) => Boolean(value.format || value.perdefinedFormat), {
98
+ message: 'date serial part requires format or perdefinedFormat',
99
+ }),
100
+ }).strict();
101
+ const serialPartBuildinSerialSchema = z.object({
102
+ mode: z.literal('buildin'),
103
+ type: z.literal('serial'),
104
+ options: z.object({
105
+ length: z.number().int().min(1),
106
+ lenfixed: z.boolean().optional(),
107
+ random: z.boolean().optional(),
108
+ reset: z.string().optional(),
109
+ }).strict(),
110
+ }).strict();
111
+ const serialPartFieldSchema = z.object({
112
+ mode: z.literal('field'),
113
+ field_id: z.number().int().min(1001),
114
+ }).passthrough();
115
+ const serialPartSchema = z.union([
116
+ serialPartBuildinStringSchema,
117
+ serialPartBuildinDateSchema,
118
+ serialPartBuildinSerialSchema,
119
+ serialPartFieldSchema,
120
+ ]);
121
+ const fieldCommonShape = {
122
+ id: z.number().int().min(1001),
123
+ label: z.string().min(1),
124
+ required: z.boolean(),
125
+ unique: z.boolean(),
126
+ editable: z.boolean(),
127
+ visible: z.boolean(),
128
+ show_label: z.boolean(),
129
+ scannable: z.boolean(),
130
+ default_value_mode: z.number(),
131
+ description: z.string(),
132
+ value: z.any(),
133
+ number_decimal: z.number().int().min(0),
134
+ depends: z.array(z.number().int().min(1001)),
135
+ key: z.string(),
136
+ code_index: z.boolean(),
137
+ transfers: z.array(z.any()).nullable(),
138
+ };
139
+ function isRecord(value) {
140
+ return Boolean(value) && typeof value === 'object' && !Array.isArray(value);
141
+ }
142
+ function cloneJSON(value) {
143
+ return JSON.parse(JSON.stringify(value));
144
+ }
145
+ function makeSimpleFieldSchema(type) {
146
+ return z.object({
147
+ ...fieldCommonShape,
148
+ type: z.literal(type),
149
+ options: z.record(z.string(), z.any()).nullable(),
150
+ children: z.null(),
151
+ }).strict();
152
+ }
153
+ function makeEnumFieldSchema(type) {
154
+ const itemSchema = type === 'status' ? statusItemSchema : enumItemSchema;
155
+ return z.object({
156
+ ...fieldCommonShape,
157
+ type: z.literal(type),
158
+ options: z.object({
159
+ options: z.object({
160
+ items: z.array(itemSchema).min(1),
161
+ }).passthrough(),
162
+ }).passthrough(),
163
+ children: z.null(),
164
+ }).strict();
165
+ }
166
+ const simpleFieldSchemas = simpleFieldTypes.map((type) => makeSimpleFieldSchema(type));
167
+ const enumFieldSchemas = enumFieldTypes.map((type) => makeEnumFieldSchema(type));
168
+ const formulaFieldSchema = z.object({
169
+ ...fieldCommonShape,
170
+ type: z.literal('formula'),
171
+ options: z.object({
172
+ formula: formulaSchema,
173
+ }).passthrough(),
174
+ children: z.null(),
175
+ }).strict();
176
+ const relationFieldSchemas = relationFieldTypes.map((type) => z.object({
177
+ ...fieldCommonShape,
178
+ type: z.literal(type),
179
+ options: z.object({
180
+ relation: relationOptionsSchema,
181
+ mode: linkModeSchema.optional(),
182
+ structure: linkStructureSchema.optional(),
183
+ multiple: z.boolean().optional(),
184
+ backfill: z.array(z.object({
185
+ id: z.number().int().min(1001),
186
+ local_id: z.number().int().min(1001),
187
+ }).strict()).optional(),
188
+ addValue: z.boolean().optional(),
189
+ placeholder: z.string().optional(),
190
+ }).passthrough(),
191
+ children: z.null(),
192
+ }).strict());
193
+ const lookupFieldSchema = z.object({
194
+ ...fieldCommonShape,
195
+ type: z.literal('lookup'),
196
+ options: z.object({
197
+ relation: lookupRelationSchema,
198
+ }).passthrough(),
199
+ children: z.null(),
200
+ }).strict();
201
+ const relationFieldFieldSchema = z.object({
202
+ ...fieldCommonShape,
203
+ type: z.literal('relationfield'),
204
+ options: z.object({
205
+ relation: relationFieldRelationSchema,
206
+ }).passthrough(),
207
+ children: z.null(),
208
+ }).strict();
209
+ const rollupFieldSchema = z.object({
210
+ ...fieldCommonShape,
211
+ type: z.literal('rollup'),
212
+ options: z.object({
213
+ relation: lookupRelationSchema,
214
+ aggregation_formula: formulaSchema,
215
+ }).passthrough(),
216
+ children: z.null(),
217
+ }).strict();
218
+ const serialNumberFieldSchema = z.object({
219
+ ...fieldCommonShape,
220
+ type: z.literal('serialnumber'),
221
+ options: z.object({
222
+ parts: z.array(serialPartSchema).min(1),
223
+ }).passthrough(),
224
+ children: z.null(),
225
+ }).strict();
226
+ const genericFieldSchema = z.object({
227
+ ...fieldCommonShape,
228
+ type: z.string().min(1).refine((value) => !strictFieldTypes.has(value), {
229
+ message: 'known field type must use dedicated schema',
230
+ }),
231
+ options: z.record(z.string(), z.any()).nullable(),
232
+ children: z.null(),
233
+ }).strict();
234
+ const baseFieldSchemaVariants = [
235
+ ...simpleFieldSchemas,
236
+ ...enumFieldSchemas,
237
+ ...relationFieldSchemas,
238
+ formulaFieldSchema,
239
+ lookupFieldSchema,
240
+ relationFieldFieldSchema,
241
+ rollupFieldSchema,
242
+ serialNumberFieldSchema,
243
+ genericFieldSchema,
244
+ ];
245
+ export const BaseFieldSchema = z.union(baseFieldSchemaVariants);
246
+ export const SubformFieldSchema = z.lazy(() => z.object({
247
+ ...fieldCommonShape,
248
+ type: z.literal('subform'),
249
+ options: z.record(z.string(), z.any()).nullable(),
250
+ children: z.array(BaseFieldSchema),
251
+ layout: z.array(z.array(z.number().int().min(1001))).optional(),
252
+ }).strict());
253
+ export const FieldVOSchema = z.lazy(() => z.union([
254
+ SubformFieldSchema,
255
+ BaseFieldSchema,
256
+ ]));
257
+ function normalizeEntitySaveInput(value) {
258
+ if (!isRecord(value)) {
259
+ return value;
260
+ }
261
+ const entity = cloneJSON(value);
262
+ if (entity.layout === null) {
263
+ entity.layout = [];
264
+ }
265
+ if (entity.current_serial === null) {
266
+ delete entity.current_serial;
267
+ }
268
+ if (isRecord(entity.options)) {
269
+ if (entity.options.Buttons === null) {
270
+ entity.options.Buttons = [];
271
+ }
272
+ if (entity.options.CustomActions === null) {
273
+ entity.options.CustomActions = [];
274
+ }
275
+ if (entity.options.FrontendEvents === null) {
276
+ entity.options.FrontendEvents = [];
277
+ }
278
+ if (entity.options.misc === null) {
279
+ entity.options.misc = {};
280
+ }
281
+ if (isRecord(entity.options.TitleFormat)) {
282
+ if (entity.options.TitleFormat.Fields === null) {
283
+ entity.options.TitleFormat.Fields = [];
284
+ }
285
+ if (entity.options.TitleFormat.Parts === null) {
286
+ entity.options.TitleFormat.Parts = [];
287
+ }
288
+ }
289
+ }
290
+ return entity;
291
+ }
292
+ function collectAllFieldIds(fields) {
293
+ const out = [];
294
+ for (const field of fields) {
295
+ out.push(field.id);
296
+ if (field.type === 'subform' && Array.isArray(field.children)) {
297
+ for (const child of field.children) {
298
+ out.push(child.id);
299
+ }
300
+ }
301
+ }
302
+ return out;
303
+ }
304
+ function collectTopLevelFieldIds(fields) {
305
+ return fields.map((field) => field.id);
306
+ }
307
+ function extractFormulaFieldIds(value) {
308
+ if (!value || typeof value !== 'string')
309
+ return [];
310
+ const ids = [...value.matchAll(/:(\d+)\]\]/g)].map((match) => Number(match[1]));
311
+ return ids.filter((id) => Number.isInteger(id) && id > 0);
312
+ }
313
+ const EntitySaveReqVOBaseSchema = z.object({
314
+ app_id: z.number().optional(),
315
+ current_serial: EntitySerialUpdaterVOSchema.optional(),
316
+ field_id_seq: z.number().int(),
317
+ fields: z.array(FieldVOSchema),
318
+ id: z.number().optional(),
319
+ layout: z.array(z.array(z.number().int().min(1001))).optional(),
320
+ name: z.string().optional(),
321
+ options: EntityOptionsSchema.optional(),
322
+ prototypes: z.array(z.number()).optional(),
323
+ schema_version: z.number().optional(),
324
+ workflow_enabled: z.boolean().optional(),
325
+ }).strict().superRefine((entity, ctx) => {
326
+ const fields = entity.fields;
327
+ const topLevelIds = new Set(collectTopLevelFieldIds(fields));
328
+ const allIds = collectAllFieldIds(fields);
329
+ const allIdSet = new Set();
330
+ for (const id of allIds) {
331
+ if (allIdSet.has(id)) {
332
+ ctx.addIssue({
333
+ code: z.ZodIssueCode.custom,
334
+ path: ['fields'],
335
+ message: `duplicate field id: ${id}`,
336
+ });
337
+ }
338
+ allIdSet.add(id);
339
+ }
340
+ const maxFieldId = allIds.length > 0 ? Math.max(...allIds) : 1000;
341
+ if (entity.field_id_seq <= maxFieldId) {
342
+ ctx.addIssue({
343
+ code: z.ZodIssueCode.custom,
344
+ path: ['field_id_seq'],
345
+ message: `field_id_seq must be greater than max field id ${maxFieldId}`,
346
+ });
347
+ }
348
+ for (const [rowIndex, row] of (entity.layout ?? []).entries()) {
349
+ for (const [colIndex, fieldId] of row.entries()) {
350
+ if (!topLevelIds.has(fieldId)) {
351
+ ctx.addIssue({
352
+ code: z.ZodIssueCode.custom,
353
+ path: ['layout', rowIndex, colIndex],
354
+ message: `layout references unknown top-level field id ${fieldId}`,
355
+ });
356
+ }
357
+ }
358
+ }
359
+ for (const [fieldIndex, field] of fields.entries()) {
360
+ if (field.type !== 'subform' && field.children !== null) {
361
+ ctx.addIssue({
362
+ code: z.ZodIssueCode.custom,
363
+ path: ['fields', fieldIndex, 'children'],
364
+ message: 'only subform field can define children',
365
+ });
366
+ }
367
+ if (field.type === 'subform') {
368
+ const childIds = new Set((field.children ?? []).map((child) => child.id));
369
+ for (const [rowIndex, row] of (field.layout ?? []).entries()) {
370
+ for (const [colIndex, fieldId] of row.entries()) {
371
+ if (!childIds.has(fieldId)) {
372
+ ctx.addIssue({
373
+ code: z.ZodIssueCode.custom,
374
+ path: ['fields', fieldIndex, 'layout', rowIndex, colIndex],
375
+ message: `subform layout references non-child field id ${fieldId}`,
376
+ });
377
+ }
378
+ }
379
+ }
380
+ }
381
+ if (field.type === 'lookup' || field.type === 'rollup') {
382
+ const localLinktoFieldId = field.options?.relation?.local_linkto_field_id;
383
+ if (typeof localLinktoFieldId === 'number') {
384
+ const target = fields.find((item) => item.id === localLinktoFieldId);
385
+ if (!target || target.type !== 'linkto') {
386
+ ctx.addIssue({
387
+ code: z.ZodIssueCode.custom,
388
+ path: ['fields', fieldIndex, 'options', 'relation', 'local_linkto_field_id'],
389
+ message: 'local_linkto_field_id must reference a linkto field',
390
+ });
391
+ }
392
+ }
393
+ }
394
+ if (field.type === 'formula' || field.type === 'rollup') {
395
+ const formulaCode = field.type === 'formula'
396
+ ? field.options?.formula?.code
397
+ : field.options?.aggregation_formula?.code;
398
+ for (const referencedFieldId of extractFormulaFieldIds(formulaCode)) {
399
+ if (!allIdSet.has(referencedFieldId)) {
400
+ ctx.addIssue({
401
+ code: z.ZodIssueCode.custom,
402
+ path: ['fields', fieldIndex, 'options'],
403
+ message: `formula references unknown field id ${referencedFieldId}`,
404
+ });
405
+ }
406
+ }
407
+ }
408
+ }
409
+ });
410
+ export const EntitySaveReqVOSchemaOverride = z.preprocess(normalizeEntitySaveInput, EntitySaveReqVOBaseSchema);
411
+ const queryOrderSchema = z.object({
412
+ column: z.string().min(1),
413
+ order: z.string().min(1),
414
+ }).strict();
415
+ export const AppCreateByTenantsReqVOSchemaOverride = z.object({
416
+ icon_color: z.string().optional(),
417
+ icon_name: z.string().optional(),
418
+ name: z.string().min(1).max(20),
419
+ }).strict();
420
+ export const EntityQueryReqVOSchemaOverride = z.object({
421
+ limit: z.number().int().positive().optional(),
422
+ offset: z.number().int().min(0).optional(),
423
+ policy_id: z.string().optional(),
424
+ search: z.record(z.string(), z.any()).optional(),
425
+ sorts: z.array(queryOrderSchema).optional(),
426
+ view_mode: z.string().optional(),
427
+ viewMode: z.never().optional(),
428
+ withSubForm: z.boolean().optional(),
429
+ }).strict();
430
+ export const InsertReqVOSchemaOverride = z.object({
431
+ policy_id: z.string().optional(),
432
+ fields: z.record(z.string(), z.any()),
433
+ }).strict().superRefine((body, ctx) => {
434
+ for (const key of Object.keys(body.fields ?? {})) {
435
+ if (!/^\d+$/.test(key)) {
436
+ ctx.addIssue({
437
+ code: z.ZodIssueCode.custom,
438
+ path: ['fields', key],
439
+ message: 'row fields must use numeric field ids as keys',
440
+ });
441
+ }
442
+ }
443
+ });
444
+ export const EntityUpdateReqVOSchemaOverride = z.object({
445
+ changed_fields: z.array(z.number().int().positive()).min(1),
446
+ data: z.record(z.string(), z.any()),
447
+ policy_id: z.string().optional(),
448
+ tags: z.array(z.string()).optional(),
449
+ fields: z.never().optional(),
450
+ }).strict().superRefine((body, ctx) => {
451
+ const dataFieldIds = new Set();
452
+ for (const key of Object.keys(body.data ?? {})) {
453
+ if (!/^\d+$/.test(key)) {
454
+ ctx.addIssue({
455
+ code: z.ZodIssueCode.custom,
456
+ path: ['data', key],
457
+ message: 'row data must use numeric field ids as keys',
458
+ });
459
+ continue;
460
+ }
461
+ dataFieldIds.add(Number(key));
462
+ }
463
+ for (const [index, fieldId] of body.changed_fields.entries()) {
464
+ if (!dataFieldIds.has(fieldId)) {
465
+ ctx.addIssue({
466
+ code: z.ZodIssueCode.custom,
467
+ path: ['changed_fields', index],
468
+ message: `changed_fields references ${fieldId}, but data does not contain that field id`,
469
+ });
470
+ }
471
+ }
472
+ });
473
+ const entitySelectionSortSchema = z.object({
474
+ column: z.string().min(1),
475
+ order: z.string().min(1),
476
+ }).strict();
477
+ const entitySelectionIdsSchema = z.object({
478
+ type: z.literal('ids'),
479
+ ids: z.array(z.number().int().positive()).min(1),
480
+ length: z.number().int().positive().optional(),
481
+ sorts: z.array(entitySelectionSortSchema).optional(),
482
+ condition: z.record(z.string(), z.any()).optional(),
483
+ }).strict().superRefine((selection, ctx) => {
484
+ if (selection.length !== undefined && selection.length !== selection.ids.length) {
485
+ ctx.addIssue({
486
+ code: z.ZodIssueCode.custom,
487
+ path: ['length'],
488
+ message: 'length must match ids.length when provided',
489
+ });
490
+ }
491
+ });
492
+ const entitySelectionConditionSchema = z.object({
493
+ type: z.literal('condition'),
494
+ length: z.number().int().positive(),
495
+ condition: z.record(z.string(), z.any()).superRefine((condition, ctx) => {
496
+ if (!Object.keys(condition).length) {
497
+ ctx.addIssue({
498
+ code: z.ZodIssueCode.custom,
499
+ message: 'condition selection requires a non-empty condition object',
500
+ });
501
+ return;
502
+ }
503
+ if (condition.selectAll !== true) {
504
+ ctx.addIssue({
505
+ code: z.ZodIssueCode.custom,
506
+ path: ['selectAll'],
507
+ message: 'condition selection must set selectAll to true',
508
+ });
509
+ }
510
+ const filterKeys = Object.keys(condition).filter((key) => key !== 'selectAll');
511
+ if (filterKeys.length === 0) {
512
+ return;
513
+ }
514
+ const hasSupportedQueryKey = filterKeys.some((key) => key === 'q' || key === 'tab' || key.startsWith('filter_'));
515
+ if (!hasSupportedQueryKey) {
516
+ ctx.addIssue({
517
+ code: z.ZodIssueCode.custom,
518
+ message: 'condition selection extra keys must use q, tab, or filter_*',
519
+ });
520
+ }
521
+ }),
522
+ sorts: z.array(entitySelectionSortSchema).optional(),
523
+ ids: z.array(z.number().int().positive()).optional(),
524
+ }).strict();
525
+ const entitySelectionAllSchema = z.object({
526
+ type: z.literal('all'),
527
+ length: z.number().int().positive().optional(),
528
+ ids: z.array(z.number().int().positive()).optional(),
529
+ condition: z.record(z.string(), z.any()).optional(),
530
+ sorts: z.array(entitySelectionSortSchema).optional(),
531
+ }).strict();
532
+ const entitySelectionSchema = z.union([
533
+ entitySelectionIdsSchema,
534
+ entitySelectionConditionSchema,
535
+ entitySelectionAllSchema,
536
+ ]);
537
+ const entitySelectionLooseSchema = z.union([
538
+ entitySelectionSchema,
539
+ entitySelectionAllSchema,
540
+ ]);
541
+ export const EntitySelectionActionReqVOSchemaOverride = z.lazy(() => z.object({
542
+ limit: z.number().int().positive().optional(),
543
+ offset: z.number().int().min(0).optional(),
544
+ policy_id: z.string().optional(),
545
+ selection: entitySelectionSchema,
546
+ }).strict());
547
+ const bulkUpdateActionSchema = z.object({
548
+ type: z.string().min(1),
549
+ value: z.any().optional(),
550
+ text_search: z.string().optional(),
551
+ text_replace: z.string().optional(),
552
+ text_append: z.string().optional(),
553
+ text_prepend: z.string().optional(),
554
+ number_add: z.number().optional(),
555
+ number_mul: z.number().optional(),
556
+ number_sub: z.number().optional(),
557
+ datetime_add: z.number().optional(),
558
+ datetime_sub: z.number().optional(),
559
+ }).strict().superRefine((action, ctx) => {
560
+ switch (action.type) {
561
+ case 'set':
562
+ if (!('value' in action)) {
563
+ ctx.addIssue({ code: z.ZodIssueCode.custom, path: ['value'], message: 'set action requires value' });
564
+ }
565
+ break;
566
+ case 'text_replace':
567
+ if (!action.text_search) {
568
+ ctx.addIssue({ code: z.ZodIssueCode.custom, path: ['text_search'], message: 'text_replace requires text_search' });
569
+ }
570
+ if (!action.text_replace) {
571
+ ctx.addIssue({ code: z.ZodIssueCode.custom, path: ['text_replace'], message: 'text_replace requires text_replace' });
572
+ }
573
+ break;
574
+ case 'text_append':
575
+ if (!action.text_append) {
576
+ ctx.addIssue({ code: z.ZodIssueCode.custom, path: ['text_append'], message: 'text_append requires text_append' });
577
+ }
578
+ break;
579
+ case 'text_prepend':
580
+ if (!action.text_prepend) {
581
+ ctx.addIssue({ code: z.ZodIssueCode.custom, path: ['text_prepend'], message: 'text_prepend requires text_prepend' });
582
+ }
583
+ break;
584
+ case 'number_add':
585
+ if (typeof action.number_add !== 'number') {
586
+ ctx.addIssue({ code: z.ZodIssueCode.custom, path: ['number_add'], message: 'number_add requires number_add' });
587
+ }
588
+ break;
589
+ case 'number_sub':
590
+ if (typeof action.number_sub !== 'number') {
591
+ ctx.addIssue({ code: z.ZodIssueCode.custom, path: ['number_sub'], message: 'number_sub requires number_sub' });
592
+ }
593
+ break;
594
+ case 'number_mul':
595
+ if (typeof action.number_mul !== 'number') {
596
+ ctx.addIssue({ code: z.ZodIssueCode.custom, path: ['number_mul'], message: 'number_mul requires number_mul' });
597
+ }
598
+ break;
599
+ case 'datetime_add':
600
+ if (typeof action.datetime_add !== 'number') {
601
+ ctx.addIssue({ code: z.ZodIssueCode.custom, path: ['datetime_add'], message: 'datetime_add requires datetime_add' });
602
+ }
603
+ break;
604
+ case 'datetime_sub':
605
+ if (typeof action.datetime_sub !== 'number') {
606
+ ctx.addIssue({ code: z.ZodIssueCode.custom, path: ['datetime_sub'], message: 'datetime_sub requires datetime_sub' });
607
+ }
608
+ break;
609
+ case 'datetime_now':
610
+ case 'formula':
611
+ break;
612
+ default:
613
+ ctx.addIssue({ code: z.ZodIssueCode.custom, path: ['type'], message: `unsupported bulk update action type: ${action.type}` });
614
+ }
615
+ });
616
+ export const EntityBulkUpdateReqVOSchemaOverride = z.object({
617
+ policy_id: z.string().optional(),
618
+ selection: entitySelectionSchema,
619
+ fields: z.array(z.object({
620
+ id: z.number().int().min(1001),
621
+ action: bulkUpdateActionSchema,
622
+ }).strict()).min(1),
623
+ }).strict();
624
+ export const EntityTagsSelectionReqVOSchemaOverride = z.object({
625
+ policy_id: z.string(),
626
+ selection: entitySelectionSchema,
627
+ }).strict();
628
+ export const EntityTagsBatchReqVOSchemaOverride = z.object({
629
+ policy_id: z.string(),
630
+ selection: entitySelectionSchema,
631
+ tag_names: z.array(z.string().min(1)).min(1),
632
+ }).strict();
633
+ export const EntityInvokeBatchOperatorReqVOSchemaOverride = z.object({
634
+ id: z.string().min(1),
635
+ data: z.object({
636
+ action_id: z.string().min(1),
637
+ policy_id: z.string().optional(),
638
+ selection: entitySelectionLooseSchema,
639
+ }).strict(),
640
+ params: z.record(z.string(), z.any()).optional(),
641
+ }).strict();
@@ -6,12 +6,23 @@ export type CLITSTypeHint = {
6
6
  symbol: string;
7
7
  file: string;
8
8
  };
9
+ export type CLIDocHint = {
10
+ title: string;
11
+ file: string;
12
+ };
9
13
  export type CLIErrorDetails = {
10
14
  operation?: string;
11
15
  requestType?: string;
12
16
  issues?: CLIValidationIssue[];
13
17
  tsHints?: CLITSTypeHint[];
18
+ docHints?: CLIDocHint[];
14
19
  reason?: string;
20
+ hint?: string;
21
+ endpoint?: string;
22
+ method?: string;
23
+ traceId?: string;
24
+ upstreamError?: unknown;
25
+ suggestions?: string[];
15
26
  };
16
27
  export declare class CLIError extends Error {
17
28
  readonly code: string;
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/runtime/errors.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,kBAAkB,GAAG;IAC/B,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;CAChB,CAAA;AAED,MAAM,MAAM,aAAa,GAAG;IAC1B,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;CACb,CAAA;AAED,MAAM,MAAM,eAAe,GAAG;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,MAAM,CAAC,EAAE,kBAAkB,EAAE,CAAA;IAC7B,OAAO,CAAC,EAAE,aAAa,EAAE,CAAA;IACzB,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB,CAAA;AAED,qBAAa,QAAS,SAAQ,KAAK;IACjC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,OAAO,CAAC,EAAE,eAAe,CAAA;gBAEtB,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,SAAI,EAAE,OAAO,CAAC,EAAE,eAAe;IAQlF,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;CASlC"}
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/runtime/errors.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,kBAAkB,GAAG;IAC/B,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;CAChB,CAAA;AAED,MAAM,MAAM,aAAa,GAAG;IAC1B,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;CACb,CAAA;AAED,MAAM,MAAM,UAAU,GAAG;IACvB,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;CACb,CAAA;AAED,MAAM,MAAM,eAAe,GAAG;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,MAAM,CAAC,EAAE,kBAAkB,EAAE,CAAA;IAC7B,OAAO,CAAC,EAAE,aAAa,EAAE,CAAA;IACzB,QAAQ,CAAC,EAAE,UAAU,EAAE,CAAA;IACvB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAA;CACvB,CAAA;AAED,qBAAa,QAAS,SAAQ,KAAK;IACjC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,OAAO,CAAC,EAAE,eAAe,CAAA;gBAEtB,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,SAAI,EAAE,OAAO,CAAC,EAAE,eAAe;IAQlF,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;CASlC"}
@@ -1 +1 @@
1
- {"version":3,"file":"execute.d.ts","sourceRoot":"","sources":["../../src/runtime/execute.ts"],"names":[],"mappings":"AACA,OAAO,EAAkB,KAAK,UAAU,EAAE,MAAM,UAAU,CAAA;AAG1D,OAAO,EAAgD,KAAK,YAAY,EAAE,MAAM,uBAAuB,CAAA;AAIvG,MAAM,MAAM,uBAAuB,GAAG;IACpC,KAAK,EAAE,YAAY,CAAA;IACnB,WAAW,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACtC,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;IAChB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,SAAS,EAAE,SAAS,MAAM,EAAE,CAAA;IAC5B,WAAW,EAAE,SAAS,MAAM,EAAE,CAAA;CAC/B,CAAA;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,YAAY,GAAG,MAAM,CAQ1D;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAWhF;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAatG;AA8CD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,uBAAuB,CActH;AAED,wBAAsB,UAAU,CAAC,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,GAAE,UAAkC,EAAE,SAAS,GAAE,OAAO,KAAa,GAAG,OAAO,CAAC,GAAG,CAAC,CAyF5J"}
1
+ {"version":3,"file":"execute.d.ts","sourceRoot":"","sources":["../../src/runtime/execute.ts"],"names":[],"mappings":"AACA,OAAO,EAAkB,KAAK,UAAU,EAAE,MAAM,UAAU,CAAA;AAG1D,OAAO,EAAwE,KAAK,YAAY,EAAE,MAAM,uBAAuB,CAAA;AAK/H,MAAM,MAAM,uBAAuB,GAAG;IACpC,KAAK,EAAE,YAAY,CAAA;IACnB,WAAW,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACtC,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;IAChB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,SAAS,EAAE,SAAS,MAAM,EAAE,CAAA;IAC5B,WAAW,EAAE,SAAS,MAAM,EAAE,CAAA;CAC/B,CAAA;AAYD,wBAAgB,cAAc,CAAC,KAAK,EAAE,YAAY,GAAG,MAAM,CAa1D;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAehF;AAcD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CA6BtG;AA8RD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,uBAAuB,CActH;AAED,wBAAsB,UAAU,CAAC,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,CAAC,EAAE,UAAU,EAAE,SAAS,GAAE,OAAO,KAAa,GAAG,OAAO,CAAC,GAAG,CAAC,CA4JrI"}