zinkee 0.1.7 → 0.1.8
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.
- package/.claude/settings.local.json +3 -1
- package/README.md +36 -16
- package/dist/index.js +975 -147
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/commands/schemas.test.ts +93 -6
- package/src/index.test.ts +10 -5
- package/src/utils/examples.test.ts +44 -8
- package/src/utils/examples.ts +447 -66
- package/src/utils/schema-fields.ts +571 -86
|
@@ -10,7 +10,13 @@ export type SchemaFieldTypeKey =
|
|
|
10
10
|
| "reference"
|
|
11
11
|
| "formula"
|
|
12
12
|
| "member"
|
|
13
|
-
| "autoincremental"
|
|
13
|
+
| "autoincremental"
|
|
14
|
+
| "schedule";
|
|
15
|
+
|
|
16
|
+
export interface SchemaFieldExamplePayload {
|
|
17
|
+
name: string;
|
|
18
|
+
payload: JsonObject;
|
|
19
|
+
}
|
|
14
20
|
|
|
15
21
|
export interface SchemaFieldTypeDefinition {
|
|
16
22
|
key: SchemaFieldTypeKey;
|
|
@@ -18,7 +24,7 @@ export interface SchemaFieldTypeDefinition {
|
|
|
18
24
|
aliases: readonly string[];
|
|
19
25
|
description: string;
|
|
20
26
|
rawShape: string;
|
|
21
|
-
|
|
27
|
+
examplePayloads: readonly SchemaFieldExamplePayload[];
|
|
22
28
|
}
|
|
23
29
|
|
|
24
30
|
function isJsonObject(value: unknown): value is JsonObject {
|
|
@@ -55,12 +61,37 @@ const fieldTypeDefinitions = [
|
|
|
55
61
|
aliases: ["text", "TextField"],
|
|
56
62
|
description: "Plain text field.",
|
|
57
63
|
rawShape:
|
|
58
|
-
'{"type":"
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
+
'{"type":"TextField","slug":"name","label":"Name","config":{"textType":"NORMAL"}}',
|
|
65
|
+
examplePayloads: [
|
|
66
|
+
{
|
|
67
|
+
name: "Text field (normal)",
|
|
68
|
+
payload: {
|
|
69
|
+
type: "TextField",
|
|
70
|
+
slug: "customer-name",
|
|
71
|
+
label: "Customer Name",
|
|
72
|
+
required: true,
|
|
73
|
+
config: {
|
|
74
|
+
textType: "NORMAL",
|
|
75
|
+
defaultValue: null,
|
|
76
|
+
conditionalFormatting: [],
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
name: "Text field (long)",
|
|
82
|
+
payload: {
|
|
83
|
+
type: "TextField",
|
|
84
|
+
slug: "customer-notes",
|
|
85
|
+
label: "Customer Notes",
|
|
86
|
+
required: false,
|
|
87
|
+
config: {
|
|
88
|
+
textType: "LONG",
|
|
89
|
+
defaultValue: "Add internal notes here...",
|
|
90
|
+
conditionalFormatting: [],
|
|
91
|
+
},
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
],
|
|
64
95
|
},
|
|
65
96
|
{
|
|
66
97
|
key: "number",
|
|
@@ -68,23 +99,125 @@ const fieldTypeDefinitions = [
|
|
|
68
99
|
aliases: ["number", "NumberField"],
|
|
69
100
|
description: "Numeric field.",
|
|
70
101
|
rawShape:
|
|
71
|
-
'{"type":"
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
102
|
+
'{"type":"NumberField","slug":"quantity","label":"Quantity","config":{"defaultValue":"0","formatOptions":{"format":"number","decimals":0,"thousandsSeparator":false}}}',
|
|
103
|
+
examplePayloads: [
|
|
104
|
+
{
|
|
105
|
+
name: "Number field (plain integer)",
|
|
106
|
+
payload: {
|
|
107
|
+
type: "NumberField",
|
|
108
|
+
slug: "quantity",
|
|
109
|
+
label: "Quantity",
|
|
110
|
+
required: false,
|
|
111
|
+
config: {
|
|
112
|
+
defaultValue: "0",
|
|
113
|
+
formatOptions: {
|
|
114
|
+
format: "number",
|
|
115
|
+
decimals: 0,
|
|
116
|
+
thousandsSeparator: false,
|
|
117
|
+
},
|
|
118
|
+
conditionalFormatting: [],
|
|
119
|
+
},
|
|
85
120
|
},
|
|
86
121
|
},
|
|
87
|
-
|
|
122
|
+
{
|
|
123
|
+
name: "Number field (decimal with thousands)",
|
|
124
|
+
payload: {
|
|
125
|
+
type: "NumberField",
|
|
126
|
+
slug: "weight",
|
|
127
|
+
label: "Weight (kg)",
|
|
128
|
+
required: false,
|
|
129
|
+
config: {
|
|
130
|
+
defaultValue: "0",
|
|
131
|
+
formatOptions: {
|
|
132
|
+
format: "number",
|
|
133
|
+
decimals: 2,
|
|
134
|
+
thousandsSeparator: true,
|
|
135
|
+
negativesInRed: false,
|
|
136
|
+
},
|
|
137
|
+
conditionalFormatting: [],
|
|
138
|
+
},
|
|
139
|
+
},
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
name: "Number field (currency € prefix)",
|
|
143
|
+
payload: {
|
|
144
|
+
type: "NumberField",
|
|
145
|
+
slug: "amount-eur",
|
|
146
|
+
label: "Amount (EUR)",
|
|
147
|
+
required: false,
|
|
148
|
+
config: {
|
|
149
|
+
defaultValue: "0",
|
|
150
|
+
formatOptions: {
|
|
151
|
+
format: "currency",
|
|
152
|
+
decimals: 2,
|
|
153
|
+
negativesInRed: true,
|
|
154
|
+
thousandsSeparator: true,
|
|
155
|
+
symbolEnabled: true,
|
|
156
|
+
symbolPosition: "before",
|
|
157
|
+
symbolValue: "€",
|
|
158
|
+
},
|
|
159
|
+
conditionalFormatting: [],
|
|
160
|
+
},
|
|
161
|
+
},
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
name: "Number field (currency $ suffix)",
|
|
165
|
+
payload: {
|
|
166
|
+
type: "NumberField",
|
|
167
|
+
slug: "amount-usd",
|
|
168
|
+
label: "Amount (USD)",
|
|
169
|
+
required: false,
|
|
170
|
+
config: {
|
|
171
|
+
defaultValue: "0",
|
|
172
|
+
formatOptions: {
|
|
173
|
+
format: "currency",
|
|
174
|
+
decimals: 2,
|
|
175
|
+
negativesInRed: false,
|
|
176
|
+
thousandsSeparator: true,
|
|
177
|
+
symbolEnabled: true,
|
|
178
|
+
symbolPosition: "right",
|
|
179
|
+
symbolValue: " $",
|
|
180
|
+
},
|
|
181
|
+
conditionalFormatting: [],
|
|
182
|
+
},
|
|
183
|
+
},
|
|
184
|
+
},
|
|
185
|
+
{
|
|
186
|
+
name: "Number field (percentage)",
|
|
187
|
+
payload: {
|
|
188
|
+
type: "NumberField",
|
|
189
|
+
slug: "discount-rate",
|
|
190
|
+
label: "Discount Rate",
|
|
191
|
+
required: false,
|
|
192
|
+
config: {
|
|
193
|
+
defaultValue: "0",
|
|
194
|
+
formatOptions: {
|
|
195
|
+
format: "percentage",
|
|
196
|
+
decimals: 1,
|
|
197
|
+
negativesInRed: true,
|
|
198
|
+
},
|
|
199
|
+
conditionalFormatting: [],
|
|
200
|
+
},
|
|
201
|
+
},
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
name: "Number field (duration HH:MM)",
|
|
205
|
+
payload: {
|
|
206
|
+
type: "NumberField",
|
|
207
|
+
slug: "tracked-time",
|
|
208
|
+
label: "Tracked Time",
|
|
209
|
+
required: false,
|
|
210
|
+
config: {
|
|
211
|
+
defaultValue: "0",
|
|
212
|
+
formatOptions: {
|
|
213
|
+
format: "duration",
|
|
214
|
+
durationFormat: "HH:MM",
|
|
215
|
+
},
|
|
216
|
+
conditionalFormatting: [],
|
|
217
|
+
},
|
|
218
|
+
},
|
|
219
|
+
},
|
|
220
|
+
],
|
|
88
221
|
},
|
|
89
222
|
{
|
|
90
223
|
key: "date",
|
|
@@ -92,12 +225,63 @@ const fieldTypeDefinitions = [
|
|
|
92
225
|
aliases: ["date", "DateField"],
|
|
93
226
|
description: "Date or datetime field.",
|
|
94
227
|
rawShape:
|
|
95
|
-
'{"type":"
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
228
|
+
'{"type":"DateField","slug":"due-date","label":"Due Date","config":{"formatOptions":{"format":"date","dateFormat":"YYYY-MM-DD","showTime":false}}}',
|
|
229
|
+
examplePayloads: [
|
|
230
|
+
{
|
|
231
|
+
name: "Date field (date only)",
|
|
232
|
+
payload: {
|
|
233
|
+
type: "DateField",
|
|
234
|
+
slug: "birth-date",
|
|
235
|
+
label: "Birth Date",
|
|
236
|
+
required: false,
|
|
237
|
+
config: {
|
|
238
|
+
defaultValue: null,
|
|
239
|
+
formatOptions: {
|
|
240
|
+
format: "date",
|
|
241
|
+
dateFormat: "YYYY-MM-DD",
|
|
242
|
+
showTime: false,
|
|
243
|
+
},
|
|
244
|
+
conditionalFormatting: [],
|
|
245
|
+
},
|
|
246
|
+
},
|
|
247
|
+
},
|
|
248
|
+
{
|
|
249
|
+
name: "Date field (datetime EU)",
|
|
250
|
+
payload: {
|
|
251
|
+
type: "DateField",
|
|
252
|
+
slug: "due-date",
|
|
253
|
+
label: "Due Date",
|
|
254
|
+
required: false,
|
|
255
|
+
config: {
|
|
256
|
+
defaultValue: null,
|
|
257
|
+
formatOptions: {
|
|
258
|
+
format: "datetime",
|
|
259
|
+
dateFormat: "DD/MM/YYYY",
|
|
260
|
+
showTime: true,
|
|
261
|
+
},
|
|
262
|
+
conditionalFormatting: [],
|
|
263
|
+
},
|
|
264
|
+
},
|
|
265
|
+
},
|
|
266
|
+
{
|
|
267
|
+
name: "Date field (datetime US)",
|
|
268
|
+
payload: {
|
|
269
|
+
type: "DateField",
|
|
270
|
+
slug: "appointment-at",
|
|
271
|
+
label: "Appointment",
|
|
272
|
+
required: false,
|
|
273
|
+
config: {
|
|
274
|
+
defaultValue: null,
|
|
275
|
+
formatOptions: {
|
|
276
|
+
format: "datetime",
|
|
277
|
+
dateFormat: "MM/DD/YYYY",
|
|
278
|
+
showTime: true,
|
|
279
|
+
},
|
|
280
|
+
conditionalFormatting: [],
|
|
281
|
+
},
|
|
282
|
+
},
|
|
283
|
+
},
|
|
284
|
+
],
|
|
101
285
|
},
|
|
102
286
|
{
|
|
103
287
|
key: "option",
|
|
@@ -105,26 +289,85 @@ const fieldTypeDefinitions = [
|
|
|
105
289
|
aliases: ["option", "OptionField"],
|
|
106
290
|
description: "Dropdown/select field with options.",
|
|
107
291
|
rawShape:
|
|
108
|
-
'{"type":"
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
292
|
+
'{"type":"OptionField","slug":"status","label":"Status","config":{"options":[{"id":1,"name":"Open","color":"default"},{"id":2,"name":"Closed","color":"success"}]}}',
|
|
293
|
+
examplePayloads: [
|
|
294
|
+
{
|
|
295
|
+
name: "Option field (select dropdown)",
|
|
296
|
+
payload: {
|
|
297
|
+
type: "OptionField",
|
|
298
|
+
slug: "priority",
|
|
299
|
+
label: "Priority",
|
|
300
|
+
required: false,
|
|
301
|
+
config: {
|
|
302
|
+
options: [
|
|
303
|
+
{ id: 1, name: "Low", color: "default" },
|
|
304
|
+
{ id: 2, name: "Medium", color: "warning" },
|
|
305
|
+
{ id: 3, name: "High", color: "danger" },
|
|
306
|
+
],
|
|
307
|
+
defaultValue: 1,
|
|
308
|
+
conditionalFormatting: [],
|
|
309
|
+
buttonConfig: null,
|
|
119
310
|
},
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
311
|
+
},
|
|
312
|
+
},
|
|
313
|
+
{
|
|
314
|
+
name: "Option field (button cycle)",
|
|
315
|
+
payload: {
|
|
316
|
+
type: "OptionField",
|
|
317
|
+
slug: "stage",
|
|
318
|
+
label: "Stage",
|
|
319
|
+
required: false,
|
|
320
|
+
config: {
|
|
321
|
+
options: [
|
|
322
|
+
{ id: 1, name: "To Do", color: "default" },
|
|
323
|
+
{ id: 2, name: "Doing", color: "warning" },
|
|
324
|
+
{ id: 3, name: "Done", color: "success" },
|
|
325
|
+
],
|
|
326
|
+
defaultValue: 1,
|
|
327
|
+
conditionalFormatting: [],
|
|
328
|
+
buttonConfig: {
|
|
329
|
+
displayMode: "button",
|
|
330
|
+
buttonBehavior: {
|
|
331
|
+
mode: "cycle",
|
|
332
|
+
cycleOrder: [1, 2, 3],
|
|
333
|
+
requireConfirmation: false,
|
|
334
|
+
lockAfterSelection: false,
|
|
335
|
+
allowReselect: true,
|
|
336
|
+
},
|
|
337
|
+
},
|
|
124
338
|
},
|
|
125
|
-
|
|
339
|
+
},
|
|
126
340
|
},
|
|
127
|
-
|
|
341
|
+
{
|
|
342
|
+
name: "Option field (button dropdown w/ confirm)",
|
|
343
|
+
payload: {
|
|
344
|
+
type: "OptionField",
|
|
345
|
+
slug: "status",
|
|
346
|
+
label: "Status",
|
|
347
|
+
required: false,
|
|
348
|
+
config: {
|
|
349
|
+
options: [
|
|
350
|
+
{ id: 1, name: "Open", color: "default" },
|
|
351
|
+
{ id: 2, name: "In Progress", color: "warning" },
|
|
352
|
+
{ id: 3, name: "Done", color: "success" },
|
|
353
|
+
],
|
|
354
|
+
defaultValue: 1,
|
|
355
|
+
conditionalFormatting: [],
|
|
356
|
+
buttonConfig: {
|
|
357
|
+
displayMode: "button",
|
|
358
|
+
buttonBehavior: {
|
|
359
|
+
mode: "dropdown",
|
|
360
|
+
requireConfirmation: true,
|
|
361
|
+
confirmationMessage: "Confirm status change",
|
|
362
|
+
useFixedLabel: true,
|
|
363
|
+
buttonLabel: "Set status",
|
|
364
|
+
allowReselect: true,
|
|
365
|
+
},
|
|
366
|
+
},
|
|
367
|
+
},
|
|
368
|
+
},
|
|
369
|
+
},
|
|
370
|
+
],
|
|
128
371
|
},
|
|
129
372
|
{
|
|
130
373
|
key: "file",
|
|
@@ -132,12 +375,19 @@ const fieldTypeDefinitions = [
|
|
|
132
375
|
aliases: ["file", "FileField"],
|
|
133
376
|
description: "File attachment field.",
|
|
134
377
|
rawShape:
|
|
135
|
-
'{"type":"
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
378
|
+
'{"type":"FileField","slug":"attachment","label":"Attachment","config":{}}',
|
|
379
|
+
examplePayloads: [
|
|
380
|
+
{
|
|
381
|
+
name: "File field",
|
|
382
|
+
payload: {
|
|
383
|
+
type: "FileField",
|
|
384
|
+
slug: "attachment",
|
|
385
|
+
label: "Attachment",
|
|
386
|
+
required: false,
|
|
387
|
+
config: {},
|
|
388
|
+
},
|
|
389
|
+
},
|
|
390
|
+
],
|
|
141
391
|
},
|
|
142
392
|
{
|
|
143
393
|
key: "reference",
|
|
@@ -145,17 +395,54 @@ const fieldTypeDefinitions = [
|
|
|
145
395
|
aliases: ["reference", "ReferenceField"],
|
|
146
396
|
description: "Reference to another schema.",
|
|
147
397
|
rawShape:
|
|
148
|
-
'{"type":"
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
398
|
+
'{"type":"ReferenceField","slug":"company-ref","label":"Company","config":{"targetSchema":"<schema-uuid>","targetDisplayField":"<field-uuid>"}}',
|
|
399
|
+
examplePayloads: [
|
|
400
|
+
{
|
|
401
|
+
name: "Reference field (minimal)",
|
|
402
|
+
payload: {
|
|
403
|
+
type: "ReferenceField",
|
|
404
|
+
slug: "company-ref",
|
|
405
|
+
label: "Company",
|
|
406
|
+
required: false,
|
|
407
|
+
config: {
|
|
408
|
+
targetSchema: "5223cbc8-8c6c-4694-93bc-dd176364df9b",
|
|
409
|
+
targetDisplayField: "c60b8526-5835-4c9f-aecd-9a16c7704a34",
|
|
410
|
+
},
|
|
411
|
+
},
|
|
157
412
|
},
|
|
158
|
-
|
|
413
|
+
{
|
|
414
|
+
name: "Reference field (restrict + filter + description)",
|
|
415
|
+
payload: {
|
|
416
|
+
type: "ReferenceField",
|
|
417
|
+
slug: "customer-ref",
|
|
418
|
+
label: "Customer",
|
|
419
|
+
required: false,
|
|
420
|
+
config: {
|
|
421
|
+
targetSchema: "5223cbc8-8c6c-4694-93bc-dd176364df9b",
|
|
422
|
+
targetDisplayField: "c60b8526-5835-4c9f-aecd-9a16c7704a34",
|
|
423
|
+
deleteBehavior: "RESTRICT",
|
|
424
|
+
defaultValue: "8ad602a1-f6e3-43f6-9ab2-f1c5afc99621::Ref A",
|
|
425
|
+
filterFields: [
|
|
426
|
+
{
|
|
427
|
+
fatherField: "c60b8526-5835-4c9f-aecd-9a16c7704a34",
|
|
428
|
+
currentField: "45c5da96-0dc2-4cc1-ba61-7660a9c6da32",
|
|
429
|
+
comparison: "EQUAL",
|
|
430
|
+
value: null,
|
|
431
|
+
},
|
|
432
|
+
],
|
|
433
|
+
descriptionFields: [
|
|
434
|
+
{
|
|
435
|
+
id: "c52efe3f-2825-4c60-a7e3-34dd4c1ce043",
|
|
436
|
+
fieldType: "NumberField",
|
|
437
|
+
options: null,
|
|
438
|
+
format: "number",
|
|
439
|
+
},
|
|
440
|
+
],
|
|
441
|
+
conditionalFormatting: [],
|
|
442
|
+
},
|
|
443
|
+
},
|
|
444
|
+
},
|
|
445
|
+
],
|
|
159
446
|
},
|
|
160
447
|
{
|
|
161
448
|
key: "formula",
|
|
@@ -163,15 +450,79 @@ const fieldTypeDefinitions = [
|
|
|
163
450
|
aliases: ["formula", "FormulaField"],
|
|
164
451
|
description: "Calculated field from a formula.",
|
|
165
452
|
rawShape:
|
|
166
|
-
'{"type":"
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
453
|
+
'{"type":"FormulaField","slug":"formula-summary","label":"Formula Summary","config":{"formulaText":"concat(firstName, \' \', lastName)","uiFormatKind":"none"}}',
|
|
454
|
+
examplePayloads: [
|
|
455
|
+
{
|
|
456
|
+
name: "Formula field (none)",
|
|
457
|
+
payload: {
|
|
458
|
+
type: "FormulaField",
|
|
459
|
+
slug: "formula-summary",
|
|
460
|
+
label: "Formula Summary",
|
|
461
|
+
required: false,
|
|
462
|
+
config: {
|
|
463
|
+
formulaText: "concat(firstName, ' ', lastName)",
|
|
464
|
+
uiFormatKind: "none",
|
|
465
|
+
status: "ACTIVE",
|
|
466
|
+
conditionalFormatting: [],
|
|
467
|
+
},
|
|
468
|
+
},
|
|
173
469
|
},
|
|
174
|
-
|
|
470
|
+
{
|
|
471
|
+
name: "Formula field (number)",
|
|
472
|
+
payload: {
|
|
473
|
+
type: "FormulaField",
|
|
474
|
+
slug: "formula-total",
|
|
475
|
+
label: "Formula Total",
|
|
476
|
+
required: false,
|
|
477
|
+
config: {
|
|
478
|
+
formulaText: "amount * 1.21",
|
|
479
|
+
uiFormatKind: "number",
|
|
480
|
+
status: "ACTIVE",
|
|
481
|
+
numberFormatOptions: {
|
|
482
|
+
format: "number",
|
|
483
|
+
decimals: 2,
|
|
484
|
+
thousandsSeparator: true,
|
|
485
|
+
},
|
|
486
|
+
conditionalFormatting: [],
|
|
487
|
+
},
|
|
488
|
+
},
|
|
489
|
+
},
|
|
490
|
+
{
|
|
491
|
+
name: "Formula field (date)",
|
|
492
|
+
payload: {
|
|
493
|
+
type: "FormulaField",
|
|
494
|
+
slug: "formula-deadline",
|
|
495
|
+
label: "Computed Deadline",
|
|
496
|
+
required: false,
|
|
497
|
+
config: {
|
|
498
|
+
formulaText: "addDays(startDate, 7)",
|
|
499
|
+
uiFormatKind: "date",
|
|
500
|
+
status: "ACTIVE",
|
|
501
|
+
dateFormatOptions: {
|
|
502
|
+
format: "date",
|
|
503
|
+
dateFormat: "DD/MM/YYYY",
|
|
504
|
+
showTime: false,
|
|
505
|
+
},
|
|
506
|
+
conditionalFormatting: [],
|
|
507
|
+
},
|
|
508
|
+
},
|
|
509
|
+
},
|
|
510
|
+
{
|
|
511
|
+
name: "Formula field (member)",
|
|
512
|
+
payload: {
|
|
513
|
+
type: "FormulaField",
|
|
514
|
+
slug: "formula-assignee",
|
|
515
|
+
label: "Computed Assignee",
|
|
516
|
+
required: false,
|
|
517
|
+
config: {
|
|
518
|
+
formulaText: "manager",
|
|
519
|
+
uiFormatKind: "member",
|
|
520
|
+
status: "ACTIVE",
|
|
521
|
+
conditionalFormatting: [],
|
|
522
|
+
},
|
|
523
|
+
},
|
|
524
|
+
},
|
|
525
|
+
],
|
|
175
526
|
},
|
|
176
527
|
{
|
|
177
528
|
key: "member",
|
|
@@ -179,15 +530,22 @@ const fieldTypeDefinitions = [
|
|
|
179
530
|
aliases: ["member", "MemberField"],
|
|
180
531
|
description: "Workspace member field.",
|
|
181
532
|
rawShape:
|
|
182
|
-
'{"type":"
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
533
|
+
'{"type":"MemberField","slug":"owner","label":"Owner","config":{"defaultValue":null}}',
|
|
534
|
+
examplePayloads: [
|
|
535
|
+
{
|
|
536
|
+
name: "Member field",
|
|
537
|
+
payload: {
|
|
538
|
+
type: "MemberField",
|
|
539
|
+
slug: "owner",
|
|
540
|
+
label: "Owner",
|
|
541
|
+
required: false,
|
|
542
|
+
config: {
|
|
543
|
+
defaultValue: null,
|
|
544
|
+
conditionalFormatting: [],
|
|
545
|
+
},
|
|
546
|
+
},
|
|
189
547
|
},
|
|
190
|
-
|
|
548
|
+
],
|
|
191
549
|
},
|
|
192
550
|
{
|
|
193
551
|
key: "autoincremental",
|
|
@@ -200,15 +558,76 @@ const fieldTypeDefinitions = [
|
|
|
200
558
|
],
|
|
201
559
|
description: "Auto-generated incremental counter.",
|
|
202
560
|
rawShape:
|
|
203
|
-
'{"type":"
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
561
|
+
'{"type":"AutoIncrementalField","slug":"order-number","label":"Order Number","config":{"segmentedByFieldId":null}}',
|
|
562
|
+
examplePayloads: [
|
|
563
|
+
{
|
|
564
|
+
name: "Autoincremental (global counter)",
|
|
565
|
+
payload: {
|
|
566
|
+
type: "AutoIncrementalField",
|
|
567
|
+
slug: "order-number",
|
|
568
|
+
label: "Order Number",
|
|
569
|
+
required: false,
|
|
570
|
+
config: {
|
|
571
|
+
segmentedByFieldId: null,
|
|
572
|
+
conditionalFormatting: [],
|
|
573
|
+
},
|
|
574
|
+
},
|
|
210
575
|
},
|
|
211
|
-
|
|
576
|
+
{
|
|
577
|
+
name: "Autoincremental (segmented)",
|
|
578
|
+
payload: {
|
|
579
|
+
type: "AutoIncrementalField",
|
|
580
|
+
slug: "sequence-code",
|
|
581
|
+
label: "Sequence Code",
|
|
582
|
+
required: false,
|
|
583
|
+
config: {
|
|
584
|
+
segmentedByFieldId: "45c5da96-0dc2-4cc1-ba61-7660a9c6da32",
|
|
585
|
+
conditionalFormatting: [],
|
|
586
|
+
},
|
|
587
|
+
},
|
|
588
|
+
},
|
|
589
|
+
],
|
|
590
|
+
},
|
|
591
|
+
{
|
|
592
|
+
key: "schedule",
|
|
593
|
+
className: "ScheduleField",
|
|
594
|
+
aliases: ["schedule", "ScheduleField"],
|
|
595
|
+
description:
|
|
596
|
+
"Recurrence/schedule field bound to a number reference and a date period (frequency: monthly or daily).",
|
|
597
|
+
rawShape:
|
|
598
|
+
'{"type":"ScheduleField","slug":"recurrence","label":"Recurrence","config":{"referenceField":"<number-field-uuid>","beginningPeriodField":"<date-field-uuid>","endingPeriodField":"<date-field-uuid>","frequency":"monthly"}}',
|
|
599
|
+
examplePayloads: [
|
|
600
|
+
{
|
|
601
|
+
name: "Schedule field (monthly)",
|
|
602
|
+
payload: {
|
|
603
|
+
type: "ScheduleField",
|
|
604
|
+
slug: "monthly-recurrence",
|
|
605
|
+
label: "Monthly Recurrence",
|
|
606
|
+
required: false,
|
|
607
|
+
config: {
|
|
608
|
+
referenceField: "c52efe3f-2825-4c60-a7e3-34dd4c1ce043",
|
|
609
|
+
beginningPeriodField: "d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90",
|
|
610
|
+
endingPeriodField: "d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90",
|
|
611
|
+
frequency: "monthly",
|
|
612
|
+
},
|
|
613
|
+
},
|
|
614
|
+
},
|
|
615
|
+
{
|
|
616
|
+
name: "Schedule field (daily)",
|
|
617
|
+
payload: {
|
|
618
|
+
type: "ScheduleField",
|
|
619
|
+
slug: "daily-recurrence",
|
|
620
|
+
label: "Daily Recurrence",
|
|
621
|
+
required: false,
|
|
622
|
+
config: {
|
|
623
|
+
referenceField: "c52efe3f-2825-4c60-a7e3-34dd4c1ce043",
|
|
624
|
+
beginningPeriodField: "d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90",
|
|
625
|
+
endingPeriodField: "d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90",
|
|
626
|
+
frequency: "daily",
|
|
627
|
+
},
|
|
628
|
+
},
|
|
629
|
+
},
|
|
630
|
+
],
|
|
212
631
|
},
|
|
213
632
|
] as const satisfies readonly SchemaFieldTypeDefinition[];
|
|
214
633
|
|
|
@@ -397,6 +816,70 @@ function normalizeReferencePayload(input: JsonObject): JsonObject {
|
|
|
397
816
|
return normalized;
|
|
398
817
|
}
|
|
399
818
|
|
|
819
|
+
const scheduleAllowedFrequencies = new Set(["monthly", "daily"]);
|
|
820
|
+
|
|
821
|
+
function normalizeSchedulePayload(input: JsonObject): JsonObject {
|
|
822
|
+
const additionalProperties = toJsonObject(input.additionalProperties) ?? {};
|
|
823
|
+
const config = toJsonObject(input.config) ?? {};
|
|
824
|
+
const referenceField =
|
|
825
|
+
config.referenceField ?? input.referenceField ?? additionalProperties.referenceField;
|
|
826
|
+
const beginningPeriodField =
|
|
827
|
+
config.beginningPeriodField ??
|
|
828
|
+
input.beginningPeriodField ??
|
|
829
|
+
additionalProperties.beginningPeriodField;
|
|
830
|
+
const endingPeriodField =
|
|
831
|
+
config.endingPeriodField ??
|
|
832
|
+
input.endingPeriodField ??
|
|
833
|
+
additionalProperties.endingPeriodField;
|
|
834
|
+
const frequency =
|
|
835
|
+
config.frequency ?? input.frequency ?? additionalProperties.frequency;
|
|
836
|
+
|
|
837
|
+
const {
|
|
838
|
+
referenceField: _referenceField,
|
|
839
|
+
beginningPeriodField: _beginningPeriodField,
|
|
840
|
+
endingPeriodField: _endingPeriodField,
|
|
841
|
+
frequency: _frequency,
|
|
842
|
+
additionalProperties: _additionalProperties,
|
|
843
|
+
...rest
|
|
844
|
+
} = input;
|
|
845
|
+
|
|
846
|
+
const normalized: JsonObject = {
|
|
847
|
+
...rest,
|
|
848
|
+
config: {
|
|
849
|
+
...config,
|
|
850
|
+
...(referenceField !== undefined ? { referenceField } : {}),
|
|
851
|
+
...(beginningPeriodField !== undefined ? { beginningPeriodField } : {}),
|
|
852
|
+
...(endingPeriodField !== undefined ? { endingPeriodField } : {}),
|
|
853
|
+
...(frequency !== undefined ? { frequency } : {}),
|
|
854
|
+
},
|
|
855
|
+
};
|
|
856
|
+
|
|
857
|
+
const normalizedConfig = toJsonObject(normalized.config) ?? {};
|
|
858
|
+
const definition = resolveSchemaFieldType("schedule")!;
|
|
859
|
+
|
|
860
|
+
if (
|
|
861
|
+
!toStringValue(normalizedConfig.referenceField) ||
|
|
862
|
+
!toStringValue(normalizedConfig.beginningPeriodField) ||
|
|
863
|
+
!toStringValue(normalizedConfig.endingPeriodField) ||
|
|
864
|
+
!toStringValue(normalizedConfig.frequency)
|
|
865
|
+
) {
|
|
866
|
+
throw new CliError(
|
|
867
|
+
"invalid_cli_usage",
|
|
868
|
+
`Schedule fields require "referenceField", "beginningPeriodField", "endingPeriodField" and "frequency". Expected raw shape: ${definition.rawShape}`,
|
|
869
|
+
);
|
|
870
|
+
}
|
|
871
|
+
|
|
872
|
+
const frequencyValue = toStringValue(normalizedConfig.frequency)!;
|
|
873
|
+
if (!scheduleAllowedFrequencies.has(frequencyValue)) {
|
|
874
|
+
throw new CliError(
|
|
875
|
+
"invalid_cli_usage",
|
|
876
|
+
`Schedule "frequency" must be "monthly" or "daily" (received "${frequencyValue}").`,
|
|
877
|
+
);
|
|
878
|
+
}
|
|
879
|
+
|
|
880
|
+
return normalized;
|
|
881
|
+
}
|
|
882
|
+
|
|
400
883
|
function normalizeFormulaPayload(input: JsonObject): JsonObject {
|
|
401
884
|
const { status: _status, ...rest } = input;
|
|
402
885
|
const rawAdditionalProperties = toJsonObject(input.additionalProperties);
|
|
@@ -465,6 +948,8 @@ export function normalizeSchemaFieldCreatePayload(input: JsonObject): JsonObject
|
|
|
465
948
|
return normalizeReferencePayload(normalizedWithType);
|
|
466
949
|
case "formula":
|
|
467
950
|
return normalizeFormulaPayload(normalizedWithType);
|
|
951
|
+
case "schedule":
|
|
952
|
+
return normalizeSchedulePayload(normalizedWithType);
|
|
468
953
|
case "autoincremental": {
|
|
469
954
|
const config = toJsonObject(normalizedWithType.config) ?? {};
|
|
470
955
|
const segmentedByFieldId =
|