betterstart-cli 0.0.95 → 0.0.96

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 (31) hide show
  1. package/dist/assets/adapters/next/integrations/_shared/actions/object-key.ts +16 -0
  2. package/dist/assets/adapters/next/integrations/r2/actions/r2.ts +2 -10
  3. package/dist/assets/adapters/next/integrations/r2/integration.ts +4 -0
  4. package/dist/assets/adapters/next/integrations/railway-bucket/actions/railway-bucket.ts +2 -10
  5. package/dist/assets/adapters/next/integrations/railway-bucket/integration.ts +4 -0
  6. package/dist/assets/adapters/next/integrations/vercel-blob/actions/vercel-blob.ts +2 -10
  7. package/dist/assets/adapters/next/integrations/vercel-blob/integration.ts +4 -0
  8. package/dist/assets/adapters/next/templates/init/api/upload-route.ts +37 -13
  9. package/dist/assets/adapters/next/templates/init/hooks/content-editor/use-color-highlight.ts +10 -64
  10. package/dist/assets/adapters/next/templates/init/hooks/content-editor/use-content-editor-source-mode.tsx +11 -4
  11. package/dist/assets/adapters/next/templates/init/lib/actions/audit/get-audit-logs.ts +1 -9
  12. package/dist/assets/adapters/next/templates/init/lib/actions/media/create-media.ts +6 -6
  13. package/dist/assets/adapters/next/templates/init/lib/actions/media/update-media.ts +5 -5
  14. package/dist/assets/adapters/next/templates/init/lib/actions/webhooks/get-webhook-deliveries.ts +1 -10
  15. package/dist/assets/adapters/next/templates/init/lib/actions/webhooks/get-webhooks.ts +1 -10
  16. package/dist/assets/adapters/next/templates/init/pages/settings/forms/forms-settings-page-content.tsx +1 -1
  17. package/dist/assets/adapters/next/templates/init/utils/date/date.ts +15 -0
  18. package/dist/assets/adapters/next/templates/init/utils/editor/content-editor.ts +98 -25
  19. package/dist/assets/adapters/next/templates/init/utils/editor/markdown.ts +5 -2
  20. package/dist/assets/shared-assets/react-admin/custom/content-editor/selection-bubble-menu.tsx +2 -2
  21. package/dist/assets/shared-assets/react-admin/custom/content-editor/source-mode.tsx +4 -2
  22. package/dist/assets/shared-assets/react-admin/custom/media-field.tsx +2 -2
  23. package/dist/assets/shared-assets/react-admin/schema.json +1143 -876
  24. package/dist/{chunk-3CLINNJL.js → chunk-LGZBMR7E.js} +33 -9
  25. package/dist/chunk-LGZBMR7E.js.map +1 -0
  26. package/dist/cli.js +2338 -2872
  27. package/dist/cli.js.map +1 -1
  28. package/dist/{template-reader-PVN53GS7.js → template-reader-WRTNGRZV.js} +2 -2
  29. package/package.json +1 -1
  30. package/dist/chunk-3CLINNJL.js.map +0 -1
  31. /package/dist/{template-reader-PVN53GS7.js.map → template-reader-WRTNGRZV.js.map} +0 -0
@@ -4,7 +4,7 @@
4
4
  "title": "BetterStart Schema Definition",
5
5
  "description": "JSON Schema for validating custom schema files (courses.json, testimonials.json, instructors.json, events.json, etc.)",
6
6
  "type": "object",
7
- "required": ["name", "label"],
7
+ "required": ["type", "name", "label"],
8
8
  "additionalProperties": false,
9
9
  "properties": {
10
10
  "$schema": {
@@ -112,12 +112,16 @@
112
112
  "mailchimp": {
113
113
  "description": "Form-only: enable Mailchimp audience subscription on submit. Pass true to use the email field automatically, or { emailField: '<name>' } to specify a different source.",
114
114
  "oneOf": [
115
- { "type": "boolean" },
115
+ {
116
+ "type": "boolean"
117
+ },
116
118
  {
117
119
  "type": "object",
118
120
  "additionalProperties": false,
119
121
  "properties": {
120
- "emailField": { "type": "string" }
122
+ "emailField": {
123
+ "type": "string"
124
+ }
121
125
  }
122
126
  }
123
127
  ]
@@ -134,12 +138,18 @@
134
138
  "type": "string",
135
139
  "pattern": "^[a-zA-Z][a-zA-Z0-9]*$"
136
140
  },
137
- "label": { "type": "string" },
138
- "description": { "type": "string" },
141
+ "label": {
142
+ "type": "string"
143
+ },
144
+ "description": {
145
+ "type": "string"
146
+ },
139
147
  "fields": {
140
148
  "type": "array",
141
149
  "minItems": 1,
142
- "items": { "$ref": "#/$defs/field" }
150
+ "items": {
151
+ "$ref": "#/$defs/field"
152
+ }
143
153
  }
144
154
  }
145
155
  },
@@ -147,74 +157,37 @@
147
157
  }
148
158
  },
149
159
  "$defs": {
150
- "field": {
160
+ "actions": {
151
161
  "type": "object",
152
- "description": "A field definition",
153
- "oneOf": [
154
- {
155
- "$ref": "#/$defs/uuidField"
156
- },
157
- {
158
- "$ref": "#/$defs/stringField"
159
- },
160
- {
161
- "$ref": "#/$defs/textField"
162
- },
163
- {
164
- "$ref": "#/$defs/markdownField"
165
- },
166
- {
167
- "$ref": "#/$defs/richtextField"
168
- },
169
- {
170
- "$ref": "#/$defs/imageField"
171
- },
172
- {
173
- "$ref": "#/$defs/dateField"
174
- },
175
- {
176
- "$ref": "#/$defs/booleanField"
177
- },
178
- {
179
- "$ref": "#/$defs/timestampField"
180
- },
181
- {
182
- "$ref": "#/$defs/numberField"
183
- },
184
- {
185
- "$ref": "#/$defs/decimalField"
186
- },
187
- {
188
- "$ref": "#/$defs/selectField"
189
- },
190
- {
191
- "$ref": "#/$defs/listField"
192
- },
193
- {
194
- "$ref": "#/$defs/groupField"
195
- },
196
- {
197
- "$ref": "#/$defs/sectionField"
198
- },
199
- {
200
- "$ref": "#/$defs/tabsField"
201
- },
202
- {
203
- "$ref": "#/$defs/relationshipField"
162
+ "description": "CRUD action configuration",
163
+ "additionalProperties": false,
164
+ "properties": {
165
+ "draft": {
166
+ "type": "boolean",
167
+ "description": "Enable draft/publish workflow",
168
+ "default": false
204
169
  },
205
- {
206
- "$ref": "#/$defs/separatorField"
170
+ "create": {
171
+ "type": "boolean",
172
+ "description": "Enable create action",
173
+ "default": true
207
174
  },
208
- {
209
- "$ref": "#/$defs/videoField"
175
+ "edit": {
176
+ "type": "boolean",
177
+ "description": "Enable edit action",
178
+ "default": true
210
179
  },
211
- {
212
- "$ref": "#/$defs/mediaField"
180
+ "delete": {
181
+ "type": "boolean",
182
+ "description": "Enable delete action",
183
+ "default": true
213
184
  },
214
- {
215
- "$ref": "#/$defs/galleryField"
185
+ "export": {
186
+ "type": "boolean",
187
+ "description": "Form-only: surface a CSV export action for submissions.",
188
+ "default": false
216
189
  }
217
- ]
190
+ }
218
191
  },
219
192
  "baseFieldProperties": {
220
193
  "type": "object",
@@ -245,58 +218,90 @@
245
218
  }
246
219
  }
247
220
  },
248
- "dependsOnCondition": {
221
+ "booleanField": {
249
222
  "type": "object",
250
- "description": "For cascading fields - specifies which sibling field(s) this field depends on",
223
+ "description": "Toggle/checkbox field",
224
+ "required": ["name", "type"],
251
225
  "additionalProperties": false,
252
226
  "properties": {
253
- "repo": {
254
- "type": "string",
255
- "description": "Name of the repo field for branch/directory selectors"
227
+ "name": {
228
+ "type": "string"
256
229
  },
257
- "branch": {
258
- "type": "string",
259
- "description": "Name of the branch field for directory selectors"
230
+ "type": {
231
+ "const": "boolean"
260
232
  },
261
- "directory": {
262
- "type": "string",
263
- "description": "Name of the directory field for chapters loader"
233
+ "label": {
234
+ "type": "string"
235
+ },
236
+ "required": {
237
+ "type": "boolean"
238
+ },
239
+ "default": {
240
+ "type": "boolean"
241
+ },
242
+ "defaultValueFrom": {
243
+ "$ref": "#/$defs/defaultValueFrom"
244
+ },
245
+ "hint": {
246
+ "type": "string"
247
+ },
248
+ "hidden": {
249
+ "type": "boolean",
250
+ "description": "Whether this field is hidden from the form UI but still exists in the database"
251
+ },
252
+ "height": {
253
+ "enum": ["auto", "fill"],
254
+ "default": "auto",
255
+ "description": "Generated field height behavior: auto size or fill remaining flexible space."
264
256
  }
265
257
  }
266
258
  },
267
- "showWhenCondition": {
259
+ "column": {
268
260
  "type": "object",
269
- "description": "Conditional visibility based on sibling field value",
270
- "required": ["field", "value"],
261
+ "description": "Table column definition for list views",
262
+ "required": ["accessorKey", "header"],
271
263
  "additionalProperties": false,
272
264
  "properties": {
273
- "field": {
265
+ "accessorKey": {
274
266
  "type": "string",
275
- "description": "Name of the sibling field to watch"
267
+ "description": "Field name to access data from"
276
268
  },
277
- "value": {
278
- "oneOf": [
279
- {
280
- "type": "boolean"
281
- },
282
- {
283
- "type": "string"
284
- },
285
- {
286
- "type": "number"
287
- }
288
- ],
289
- "description": "Value that makes this field visible"
269
+ "header": {
270
+ "type": "string",
271
+ "description": "Column header text"
272
+ },
273
+ "type": {
274
+ "type": "string",
275
+ "description": "Column display type",
276
+ "enum": ["image", "avatar", "text", "badge", "date", "email", "number", "link"]
277
+ },
278
+ "sortable": {
279
+ "type": "boolean",
280
+ "description": "Whether the column is sortable",
281
+ "default": false
282
+ },
283
+ "size": {
284
+ "type": "string",
285
+ "description": "Default table column width preset",
286
+ "enum": ["sm", "default", "lg", "xl"],
287
+ "default": "default"
288
+ },
289
+ "format": {
290
+ "type": "string",
291
+ "description": "Display format (e.g., 'currency' for numbers)",
292
+ "enum": ["currency", "percentage"]
293
+ },
294
+ "align": {
295
+ "type": "string",
296
+ "description": "Column text alignment",
297
+ "enum": ["left", "center", "right"],
298
+ "default": "left"
290
299
  }
291
300
  }
292
301
  },
293
- "defaultValueFrom": {
294
- "type": "string",
295
- "description": "Name of another field in the same schema to copy into this field when this field has no initial value and has not been edited away from the copied default."
296
- },
297
- "uuidField": {
302
+ "dateField": {
298
303
  "type": "object",
299
- "description": "UUID primary key field",
304
+ "description": "Date picker field",
300
305
  "required": ["name", "type"],
301
306
  "additionalProperties": false,
302
307
  "properties": {
@@ -304,12 +309,26 @@
304
309
  "type": "string"
305
310
  },
306
311
  "type": {
307
- "const": "uuid"
312
+ "const": "date"
308
313
  },
309
- "primaryKey": {
314
+ "label": {
315
+ "type": "string"
316
+ },
317
+ "required": {
318
+ "type": "boolean"
319
+ },
320
+ "default": {
321
+ "type": "string"
322
+ },
323
+ "defaultValueFrom": {
324
+ "$ref": "#/$defs/defaultValueFrom"
325
+ },
326
+ "hint": {
327
+ "type": "string"
328
+ },
329
+ "hidden": {
310
330
  "type": "boolean",
311
- "description": "Whether this is the primary key",
312
- "default": true
331
+ "description": "Whether this field is hidden from the form UI but still exists in the database"
313
332
  },
314
333
  "height": {
315
334
  "enum": ["auto", "fill"],
@@ -318,9 +337,9 @@
318
337
  }
319
338
  }
320
339
  },
321
- "stringField": {
340
+ "decimalField": {
322
341
  "type": "object",
323
- "description": "Single-line text input field",
342
+ "description": "Decimal number field (for prices, percentages, etc.)",
324
343
  "required": ["name", "type"],
325
344
  "additionalProperties": false,
326
345
  "properties": {
@@ -328,7 +347,7 @@
328
347
  "type": "string"
329
348
  },
330
349
  "type": {
331
- "const": "string"
350
+ "const": "decimal"
332
351
  },
333
352
  "label": {
334
353
  "type": "string"
@@ -336,36 +355,40 @@
336
355
  "required": {
337
356
  "type": "boolean"
338
357
  },
339
- "length": {
358
+ "format": {
359
+ "type": "string",
360
+ "description": "Display format",
361
+ "enum": ["currency", "percentage", "plain"]
362
+ },
363
+ "precision": {
340
364
  "type": "integer",
341
- "description": "Maximum character length",
365
+ "description": "Total number of digits",
342
366
  "minimum": 1,
343
- "maximum": 65535
367
+ "maximum": 65
368
+ },
369
+ "scale": {
370
+ "type": "integer",
371
+ "description": "Number of decimal places",
372
+ "minimum": 0,
373
+ "maximum": 30
344
374
  },
345
375
  "hint": {
346
376
  "type": "string"
347
377
  },
348
378
  "placeholder": {
349
379
  "type": "string",
350
- "description": "Placeholder text displayed in the input field"
380
+ "description": "Placeholder text displayed in the decimal input"
351
381
  },
352
382
  "default": {
353
- "type": "string"
383
+ "type": "number"
354
384
  },
355
385
  "defaultValueFrom": {
356
386
  "$ref": "#/$defs/defaultValueFrom"
357
387
  },
358
- "hasIcon": {
359
- "type": "boolean",
360
- "description": "Whether this field has an associated icon picker"
361
- },
362
388
  "hidden": {
363
389
  "type": "boolean",
364
390
  "description": "Whether this field is hidden from the form UI but still exists in the database"
365
391
  },
366
- "showWhen": {
367
- "$ref": "#/$defs/showWhenCondition"
368
- },
369
392
  "height": {
370
393
  "enum": ["auto", "fill"],
371
394
  "default": "auto",
@@ -373,106 +396,32 @@
373
396
  }
374
397
  }
375
398
  },
376
- "textField": {
377
- "type": "object",
378
- "description": "Multi-line text area field",
379
- "required": ["name", "type"],
380
- "additionalProperties": false,
381
- "properties": {
382
- "name": {
383
- "type": "string"
384
- },
385
- "type": {
386
- "const": "text"
387
- },
388
- "label": {
389
- "type": "string"
390
- },
391
- "required": {
392
- "type": "boolean"
393
- },
394
- "length": {
395
- "type": "integer",
396
- "description": "Maximum character length",
397
- "minimum": 1
398
- },
399
- "hint": {
400
- "type": "string"
401
- },
402
- "placeholder": {
403
- "type": "string",
404
- "description": "Placeholder text displayed in the text area"
405
- },
406
- "default": {
407
- "type": "string"
408
- },
409
- "defaultValueFrom": {
410
- "$ref": "#/$defs/defaultValueFrom"
411
- },
412
- "hidden": {
413
- "type": "boolean",
414
- "description": "Whether this field is hidden from the form UI but still exists in the database"
415
- },
416
- "showWhen": {
417
- "$ref": "#/$defs/showWhenCondition"
418
- },
419
- "height": {
420
- "enum": ["auto", "fill"],
421
- "default": "auto",
422
- "description": "Generated field height behavior: auto size or fill remaining flexible space."
423
- }
424
- }
399
+ "defaultValueFrom": {
400
+ "type": "string",
401
+ "description": "Name of another field in the same schema to copy into this field when this field has no initial value and has not been edited away from the copied default."
425
402
  },
426
- "markdownField": {
403
+ "dependsOnCondition": {
427
404
  "type": "object",
428
- "description": "Rich text editor with markdown support",
429
- "required": ["name", "type"],
405
+ "description": "For cascading fields - specifies which sibling field(s) this field depends on",
430
406
  "additionalProperties": false,
431
407
  "properties": {
432
- "name": {
433
- "type": "string"
434
- },
435
- "type": {
436
- "const": "markdown"
437
- },
438
- "label": {
439
- "type": "string"
440
- },
441
- "required": {
442
- "type": "boolean"
443
- },
444
- "hint": {
445
- "type": "string"
446
- },
447
- "placeholder": {
408
+ "repo": {
448
409
  "type": "string",
449
- "description": "Placeholder text displayed in the markdown editor"
410
+ "description": "Name of the repo field for branch/directory selectors"
450
411
  },
451
- "output": {
412
+ "branch": {
452
413
  "type": "string",
453
- "description": "Output format 'html' adds a pre-rendered HTML column alongside the markdown source",
454
- "enum": ["html", "markdown"]
455
- },
456
- "defaultValueFrom": {
457
- "$ref": "#/$defs/defaultValueFrom"
458
- },
459
- "hidden": {
460
- "type": "boolean",
461
- "description": "Whether this field is hidden from the form UI but still exists in the database"
462
- },
463
- "showWhen": {
464
- "$ref": "#/$defs/showWhenCondition"
414
+ "description": "Name of the branch field for directory selectors"
465
415
  },
466
- "height": {
467
- "enum": ["auto", "fill"],
468
- "default": "auto",
469
- "description": "Generated field height behavior: auto size or fill remaining flexible space."
416
+ "directory": {
417
+ "type": "string",
418
+ "description": "Name of the directory field for chapters loader"
470
419
  }
471
420
  }
472
421
  },
473
- "richtextField": {
422
+ "emailField": {
474
423
  "type": "object",
475
- "description": "WYSIWYG rich text editor with markdown storage",
424
+ "description": "Email input field, stored as VARCHAR",
476
425
  "required": ["name", "type"],
477
426
  "additionalProperties": false,
478
427
  "properties": {
@@ -480,7 +429,7 @@
480
429
  "type": "string"
481
430
  },
482
431
  "type": {
483
- "const": "richtext"
432
+ "const": "email"
484
433
  },
485
434
  "label": {
486
435
  "type": "string"
@@ -488,21 +437,29 @@
488
437
  "required": {
489
438
  "type": "boolean"
490
439
  },
440
+ "length": {
441
+ "type": "integer",
442
+ "description": "Maximum character length",
443
+ "minimum": 1,
444
+ "maximum": 65535
445
+ },
491
446
  "hint": {
492
447
  "type": "string"
493
448
  },
494
449
  "placeholder": {
495
450
  "type": "string",
496
- "description": "Placeholder text displayed in the rich text editor"
451
+ "description": "Placeholder text displayed in the input field"
497
452
  },
498
- "output": {
499
- "type": "string",
500
- "description": "Output format — 'html' adds a pre-rendered HTML column alongside the markdown source",
501
- "enum": ["html", "markdown"]
453
+ "default": {
454
+ "type": "string"
502
455
  },
503
456
  "defaultValueFrom": {
504
457
  "$ref": "#/$defs/defaultValueFrom"
505
458
  },
459
+ "hasIcon": {
460
+ "type": "boolean",
461
+ "description": "Whether this field has an associated icon picker"
462
+ },
506
463
  "hidden": {
507
464
  "type": "boolean",
508
465
  "description": "Whether this field is hidden from the form UI but still exists in the database"
@@ -517,124 +474,232 @@
517
474
  }
518
475
  }
519
476
  },
520
- "imageField": {
477
+ "field": {
521
478
  "type": "object",
522
- "description": "Image upload field",
523
- "required": ["name", "type"],
524
- "additionalProperties": false,
525
- "properties": {
526
- "name": {
527
- "type": "string"
479
+ "description": "A field definition",
480
+ "oneOf": [
481
+ {
482
+ "$ref": "#/$defs/uuidField"
528
483
  },
529
- "type": {
530
- "const": "image"
484
+ {
485
+ "$ref": "#/$defs/stringField"
531
486
  },
532
- "label": {
533
- "type": "string"
487
+ {
488
+ "$ref": "#/$defs/emailField"
534
489
  },
535
- "required": {
536
- "type": "boolean"
490
+ {
491
+ "$ref": "#/$defs/varcharField"
537
492
  },
538
- "length": {
539
- "type": "integer",
540
- "description": "Maximum URL length"
493
+ {
494
+ "$ref": "#/$defs/textField"
541
495
  },
542
- "hint": {
543
- "type": "string"
496
+ {
497
+ "$ref": "#/$defs/markdownField"
544
498
  },
545
- "defaultValueFrom": {
546
- "$ref": "#/$defs/defaultValueFrom"
499
+ {
500
+ "$ref": "#/$defs/richtextField"
547
501
  },
548
- "hidden": {
549
- "type": "boolean",
550
- "description": "Whether this field is hidden from the form UI but still exists in the database"
502
+ {
503
+ "$ref": "#/$defs/imageField"
551
504
  },
552
- "height": {
553
- "enum": ["auto", "fill"],
554
- "default": "auto",
555
- "description": "Generated field height behavior: auto size or fill remaining flexible space."
556
- }
557
- }
558
- },
559
- "dateField": {
560
- "type": "object",
561
- "description": "Date picker field",
562
- "required": ["name", "type"],
563
- "additionalProperties": false,
564
- "properties": {
565
- "name": {
566
- "type": "string"
505
+ {
506
+ "$ref": "#/$defs/iconField"
567
507
  },
568
- "type": {
569
- "const": "date"
508
+ {
509
+ "$ref": "#/$defs/dateField"
570
510
  },
571
- "label": {
572
- "type": "string"
511
+ {
512
+ "$ref": "#/$defs/booleanField"
573
513
  },
574
- "required": {
575
- "type": "boolean"
514
+ {
515
+ "$ref": "#/$defs/timestampField"
576
516
  },
577
- "default": {
578
- "type": "string"
517
+ {
518
+ "$ref": "#/$defs/timeField"
579
519
  },
580
- "defaultValueFrom": {
581
- "$ref": "#/$defs/defaultValueFrom"
520
+ {
521
+ "$ref": "#/$defs/numberField"
582
522
  },
583
- "hint": {
584
- "type": "string"
523
+ {
524
+ "$ref": "#/$defs/decimalField"
585
525
  },
586
- "hidden": {
587
- "type": "boolean",
588
- "description": "Whether this field is hidden from the form UI but still exists in the database"
526
+ {
527
+ "$ref": "#/$defs/selectField"
589
528
  },
590
- "height": {
591
- "enum": ["auto", "fill"],
592
- "default": "auto",
593
- "description": "Generated field height behavior: auto size or fill remaining flexible space."
594
- }
595
- }
596
- },
597
- "booleanField": {
598
- "type": "object",
599
- "description": "Toggle/checkbox field",
600
- "required": ["name", "type"],
601
- "additionalProperties": false,
602
- "properties": {
603
- "name": {
604
- "type": "string"
529
+ {
530
+ "$ref": "#/$defs/listField"
605
531
  },
606
- "type": {
607
- "const": "boolean"
532
+ {
533
+ "$ref": "#/$defs/groupField"
608
534
  },
609
- "label": {
610
- "type": "string"
535
+ {
536
+ "$ref": "#/$defs/sectionField"
611
537
  },
612
- "required": {
613
- "type": "boolean"
538
+ {
539
+ "$ref": "#/$defs/tabsField"
614
540
  },
615
- "default": {
616
- "type": "boolean"
541
+ {
542
+ "$ref": "#/$defs/relationshipField"
617
543
  },
618
- "defaultValueFrom": {
619
- "$ref": "#/$defs/defaultValueFrom"
544
+ {
545
+ "$ref": "#/$defs/separatorField"
620
546
  },
621
- "hint": {
622
- "type": "string"
547
+ {
548
+ "$ref": "#/$defs/videoField"
623
549
  },
624
- "hidden": {
625
- "type": "boolean",
626
- "description": "Whether this field is hidden from the form UI but still exists in the database"
550
+ {
551
+ "$ref": "#/$defs/mediaField"
627
552
  },
628
- "height": {
629
- "enum": ["auto", "fill"],
630
- "default": "auto",
631
- "description": "Generated field height behavior: auto size or fill remaining flexible space."
553
+ {
554
+ "$ref": "#/$defs/galleryField"
632
555
  }
556
+ ]
557
+ },
558
+ "fieldArrayWithCreatableSelect": {
559
+ "type": "array",
560
+ "contains": {
561
+ "$ref": "#/$defs/fieldWithCreatableSelect"
633
562
  }
634
563
  },
635
- "timestampField": {
564
+ "fieldArrayWithTitle": {
565
+ "type": "array",
566
+ "contains": {
567
+ "$ref": "#/$defs/fieldWithTitle"
568
+ }
569
+ },
570
+ "fieldWithCreatableSelect": {
636
571
  "type": "object",
637
- "description": "Timestamp field (typically auto-generated)",
572
+ "anyOf": [
573
+ {
574
+ "properties": {
575
+ "type": {
576
+ "const": "select"
577
+ },
578
+ "creatable": {
579
+ "const": true
580
+ }
581
+ },
582
+ "required": ["type", "creatable"]
583
+ },
584
+ {
585
+ "properties": {
586
+ "fields": {
587
+ "$ref": "#/$defs/fieldArrayWithCreatableSelect"
588
+ }
589
+ },
590
+ "required": ["fields"]
591
+ },
592
+ {
593
+ "properties": {
594
+ "tabs": {
595
+ "type": "array",
596
+ "contains": {
597
+ "$ref": "#/$defs/tabWithCreatableSelect"
598
+ }
599
+ }
600
+ },
601
+ "required": ["tabs"]
602
+ }
603
+ ]
604
+ },
605
+ "fieldWithTitle": {
606
+ "type": "object",
607
+ "anyOf": [
608
+ {
609
+ "properties": {
610
+ "name": {
611
+ "const": "title"
612
+ },
613
+ "type": {
614
+ "enum": ["string", "varchar", "text"]
615
+ }
616
+ },
617
+ "required": ["name", "type"]
618
+ },
619
+ {
620
+ "properties": {
621
+ "type": {
622
+ "enum": ["group", "section"]
623
+ },
624
+ "fields": {
625
+ "$ref": "#/$defs/fieldArrayWithTitle"
626
+ }
627
+ },
628
+ "required": ["type", "fields"]
629
+ },
630
+ {
631
+ "properties": {
632
+ "tabs": {
633
+ "type": "array",
634
+ "contains": {
635
+ "$ref": "#/$defs/tabWithTitle"
636
+ }
637
+ }
638
+ },
639
+ "required": ["tabs"]
640
+ }
641
+ ]
642
+ },
643
+ "filter": {
644
+ "type": "object",
645
+ "description": "Filter definition for admin tables",
646
+ "required": ["field", "label"],
647
+ "additionalProperties": false,
648
+ "properties": {
649
+ "key": {
650
+ "type": "string",
651
+ "description": "Optional query param key for this filter. Defaults to the field name."
652
+ },
653
+ "field": {
654
+ "type": "string",
655
+ "description": "Field name to filter by"
656
+ },
657
+ "label": {
658
+ "type": "string",
659
+ "description": "Label for the filter dropdown"
660
+ },
661
+ "type": {
662
+ "type": "string",
663
+ "description": "Filter type",
664
+ "enum": ["select", "boolean"],
665
+ "default": "select"
666
+ },
667
+ "source": {
668
+ "type": "string",
669
+ "description": "Where select filter options come from",
670
+ "enum": ["distinct", "static"]
671
+ },
672
+ "options": {
673
+ "type": "array",
674
+ "description": "Static options for select filters",
675
+ "items": {
676
+ "type": "object",
677
+ "required": ["label", "value"],
678
+ "additionalProperties": false,
679
+ "properties": {
680
+ "label": {
681
+ "type": "string",
682
+ "description": "Option label shown in the filter UI"
683
+ },
684
+ "value": {
685
+ "type": "string",
686
+ "description": "Option value sent to the backend filter"
687
+ }
688
+ }
689
+ }
690
+ }
691
+ }
692
+ },
693
+ "filters": {
694
+ "type": "array",
695
+ "description": "Filter configuration for admin tables",
696
+ "items": {
697
+ "$ref": "#/$defs/filter"
698
+ }
699
+ },
700
+ "galleryField": {
701
+ "type": "object",
702
+ "description": "Multi-select media gallery field storing an array of media IDs with drag-to-reorder",
638
703
  "required": ["name", "type"],
639
704
  "additionalProperties": false,
640
705
  "properties": {
@@ -642,7 +707,7 @@
642
707
  "type": "string"
643
708
  },
644
709
  "type": {
645
- "const": "timestamp"
710
+ "const": "gallery"
646
711
  },
647
712
  "label": {
648
713
  "type": "string"
@@ -650,9 +715,17 @@
650
715
  "required": {
651
716
  "type": "boolean"
652
717
  },
718
+ "hint": {
719
+ "type": "string"
720
+ },
653
721
  "defaultValueFrom": {
654
722
  "$ref": "#/$defs/defaultValueFrom"
655
723
  },
724
+ "maxItems": {
725
+ "type": "integer",
726
+ "minimum": 1,
727
+ "description": "Maximum number of media items"
728
+ },
656
729
  "hidden": {
657
730
  "type": "boolean",
658
731
  "description": "Whether this field is hidden from the form UI but still exists in the database"
@@ -664,9 +737,45 @@
664
737
  }
665
738
  }
666
739
  },
667
- "numberField": {
740
+ "groupField": {
668
741
  "type": "object",
669
- "description": "Integer number input field",
742
+ "description": "Group of fields displayed together",
743
+ "required": ["name", "type", "fields"],
744
+ "additionalProperties": false,
745
+ "properties": {
746
+ "name": {
747
+ "type": "string"
748
+ },
749
+ "type": {
750
+ "const": "group"
751
+ },
752
+ "label": {
753
+ "type": "string"
754
+ },
755
+ "columns": {
756
+ "type": "integer",
757
+ "description": "Number of columns for layout",
758
+ "minimum": 1,
759
+ "maximum": 4
760
+ },
761
+ "fields": {
762
+ "type": "array",
763
+ "description": "Nested field definitions",
764
+ "items": {
765
+ "$ref": "#/$defs/field"
766
+ },
767
+ "minItems": 1
768
+ },
769
+ "height": {
770
+ "enum": ["auto", "fill"],
771
+ "default": "auto",
772
+ "description": "Generated field height behavior: auto size or fill remaining flexible space."
773
+ }
774
+ }
775
+ },
776
+ "iconField": {
777
+ "type": "object",
778
+ "description": "Lucide icon picker field, stored as VARCHAR",
670
779
  "required": ["name", "type"],
671
780
  "additionalProperties": false,
672
781
  "properties": {
@@ -674,7 +783,7 @@
674
783
  "type": "string"
675
784
  },
676
785
  "type": {
677
- "const": "number"
786
+ "const": "icon"
678
787
  },
679
788
  "label": {
680
789
  "type": "string"
@@ -682,29 +791,36 @@
682
791
  "required": {
683
792
  "type": "boolean"
684
793
  },
685
- "default": {
686
- "type": "integer"
687
- },
688
- "defaultValueFrom": {
689
- "$ref": "#/$defs/defaultValueFrom"
794
+ "length": {
795
+ "type": "integer",
796
+ "description": "Maximum character length",
797
+ "minimum": 1,
798
+ "maximum": 65535
690
799
  },
691
800
  "hint": {
692
801
  "type": "string"
693
802
  },
694
803
  "placeholder": {
695
804
  "type": "string",
696
- "description": "Placeholder text displayed in the number input"
805
+ "description": "Placeholder text displayed in the input field"
697
806
  },
698
- "min": {
699
- "type": "integer"
807
+ "default": {
808
+ "type": "string"
700
809
  },
701
- "max": {
702
- "type": "integer"
810
+ "defaultValueFrom": {
811
+ "$ref": "#/$defs/defaultValueFrom"
812
+ },
813
+ "hasIcon": {
814
+ "type": "boolean",
815
+ "description": "Whether this field has an associated icon picker"
703
816
  },
704
817
  "hidden": {
705
818
  "type": "boolean",
706
819
  "description": "Whether this field is hidden from the form UI but still exists in the database"
707
820
  },
821
+ "showWhen": {
822
+ "$ref": "#/$defs/showWhenCondition"
823
+ },
708
824
  "height": {
709
825
  "enum": ["auto", "fill"],
710
826
  "default": "auto",
@@ -712,9 +828,9 @@
712
828
  }
713
829
  }
714
830
  },
715
- "decimalField": {
831
+ "imageField": {
716
832
  "type": "object",
717
- "description": "Decimal number field (for prices, percentages, etc.)",
833
+ "description": "Image upload field",
718
834
  "required": ["name", "type"],
719
835
  "additionalProperties": false,
720
836
  "properties": {
@@ -722,7 +838,7 @@
722
838
  "type": "string"
723
839
  },
724
840
  "type": {
725
- "const": "decimal"
841
+ "const": "image"
726
842
  },
727
843
  "label": {
728
844
  "type": "string"
@@ -730,33 +846,13 @@
730
846
  "required": {
731
847
  "type": "boolean"
732
848
  },
733
- "format": {
734
- "type": "string",
735
- "description": "Display format",
736
- "enum": ["currency", "percentage", "plain"]
737
- },
738
- "precision": {
739
- "type": "integer",
740
- "description": "Total number of digits",
741
- "minimum": 1,
742
- "maximum": 65
743
- },
744
- "scale": {
849
+ "length": {
745
850
  "type": "integer",
746
- "description": "Number of decimal places",
747
- "minimum": 0,
748
- "maximum": 30
851
+ "description": "Maximum URL length"
749
852
  },
750
853
  "hint": {
751
854
  "type": "string"
752
855
  },
753
- "placeholder": {
754
- "type": "string",
755
- "description": "Placeholder text displayed in the decimal input"
756
- },
757
- "default": {
758
- "type": "number"
759
- },
760
856
  "defaultValueFrom": {
761
857
  "$ref": "#/$defs/defaultValueFrom"
762
858
  },
@@ -771,9 +867,9 @@
771
867
  }
772
868
  }
773
869
  },
774
- "selectField": {
870
+ "listField": {
775
871
  "type": "object",
776
- "description": "Dropdown select field",
872
+ "description": "Repeatable list of items with nested fields",
777
873
  "required": ["name", "type"],
778
874
  "additionalProperties": false,
779
875
  "properties": {
@@ -781,114 +877,7 @@
781
877
  "type": "string"
782
878
  },
783
879
  "type": {
784
- "const": "select"
785
- },
786
- "label": {
787
- "type": "string"
788
- },
789
- "required": {
790
- "type": "boolean"
791
- },
792
- "hint": {
793
- "type": "string"
794
- },
795
- "placeholder": {
796
- "type": "string",
797
- "description": "Placeholder text displayed in the select trigger"
798
- },
799
- "options": {
800
- "type": "array",
801
- "description": "Available options for the select",
802
- "items": {
803
- "type": "object",
804
- "required": ["label", "value"],
805
- "additionalProperties": false,
806
- "properties": {
807
- "label": {
808
- "type": "string",
809
- "description": "Display label"
810
- },
811
- "value": {
812
- "type": "string",
813
- "description": "Value stored in database"
814
- }
815
- }
816
- },
817
- "minItems": 1
818
- },
819
- "default": {
820
- "oneOf": [
821
- {
822
- "type": "string"
823
- },
824
- {
825
- "type": "array",
826
- "items": {
827
- "type": "string"
828
- }
829
- }
830
- ]
831
- },
832
- "defaultValueFrom": {
833
- "$ref": "#/$defs/defaultValueFrom"
834
- },
835
- "creatable": {
836
- "type": "boolean",
837
- "description": "Allow admins to create field-scoped options from the generated form"
838
- },
839
- "multiple": {
840
- "type": "boolean",
841
- "description": "Allow multiple selected option values"
842
- },
843
- "previewLimit": {
844
- "type": "integer",
845
- "minimum": 1,
846
- "description": "Number of selected labels shown before collapsing the rest into a count badge"
847
- },
848
- "hidden": {
849
- "type": "boolean",
850
- "description": "Whether this field is hidden from the form UI but still exists in the database"
851
- },
852
- "height": {
853
- "enum": ["auto", "fill"],
854
- "default": "auto",
855
- "description": "Generated field height behavior: auto size or fill remaining flexible space."
856
- }
857
- },
858
- "allOf": [
859
- {
860
- "if": {
861
- "properties": {
862
- "multiple": {
863
- "const": true
864
- }
865
- },
866
- "required": ["multiple"]
867
- },
868
- "else": {
869
- "properties": {
870
- "default": {
871
- "type": "string"
872
- }
873
- },
874
- "not": {
875
- "required": ["previewLimit"]
876
- }
877
- }
878
- }
879
- ]
880
- },
881
- "listField": {
882
- "type": "object",
883
- "description": "Repeatable list of items with nested fields",
884
- "required": ["name", "type"],
885
- "additionalProperties": false,
886
- "properties": {
887
- "name": {
888
- "type": "string"
889
- },
890
- "type": {
891
- "const": "list"
880
+ "const": "list"
892
881
  },
893
882
  "label": {
894
883
  "type": "string"
@@ -933,9 +922,9 @@
933
922
  }
934
923
  }
935
924
  },
936
- "simpleListItem": {
925
+ "markdownField": {
937
926
  "type": "object",
938
- "description": "Simple list item definition",
927
+ "description": "Rich text editor with markdown support",
939
928
  "required": ["name", "type"],
940
929
  "additionalProperties": false,
941
930
  "properties": {
@@ -943,7 +932,7 @@
943
932
  "type": "string"
944
933
  },
945
934
  "type": {
946
- "type": "string"
935
+ "const": "markdown"
947
936
  },
948
937
  "label": {
949
938
  "type": "string"
@@ -951,39 +940,66 @@
951
940
  "required": {
952
941
  "type": "boolean"
953
942
  },
954
- "length": {
955
- "type": "integer"
943
+ "hint": {
944
+ "type": "string"
945
+ },
946
+ "placeholder": {
947
+ "type": "string",
948
+ "description": "Placeholder text displayed in the markdown editor"
949
+ },
950
+ "output": {
951
+ "type": "string",
952
+ "description": "Output format \u2014 'html' adds a pre-rendered HTML column alongside the markdown source",
953
+ "enum": ["html", "markdown"]
954
+ },
955
+ "defaultValueFrom": {
956
+ "$ref": "#/$defs/defaultValueFrom"
957
+ },
958
+ "hidden": {
959
+ "type": "boolean",
960
+ "description": "Whether this field is hidden from the form UI but still exists in the database"
961
+ },
962
+ "showWhen": {
963
+ "$ref": "#/$defs/showWhenCondition"
964
+ },
965
+ "height": {
966
+ "enum": ["auto", "fill"],
967
+ "default": "auto",
968
+ "description": "Generated field height behavior: auto size or fill remaining flexible space."
956
969
  }
957
970
  }
958
971
  },
959
- "groupField": {
972
+ "mediaField": {
960
973
  "type": "object",
961
- "description": "Group of fields displayed together",
962
- "required": ["name", "type", "fields"],
974
+ "description": "Media upload field supporting both images and videos",
975
+ "required": ["name", "type"],
963
976
  "additionalProperties": false,
964
977
  "properties": {
965
978
  "name": {
966
979
  "type": "string"
967
980
  },
968
981
  "type": {
969
- "const": "group"
982
+ "const": "media"
970
983
  },
971
984
  "label": {
972
985
  "type": "string"
973
986
  },
974
- "columns": {
987
+ "required": {
988
+ "type": "boolean"
989
+ },
990
+ "hint": {
991
+ "type": "string"
992
+ },
993
+ "defaultValueFrom": {
994
+ "$ref": "#/$defs/defaultValueFrom"
995
+ },
996
+ "maxSizeInMB": {
975
997
  "type": "integer",
976
- "description": "Number of columns for layout",
977
- "minimum": 1,
978
- "maximum": 4
998
+ "description": "Maximum file size in megabytes"
979
999
  },
980
- "fields": {
981
- "type": "array",
982
- "description": "Nested field definitions",
983
- "items": {
984
- "$ref": "#/$defs/field"
985
- },
986
- "minItems": 1
1000
+ "hidden": {
1001
+ "type": "boolean",
1002
+ "description": "Whether this field is hidden from the form UI but still exists in the database"
987
1003
  },
988
1004
  "height": {
989
1005
  "enum": ["auto", "fill"],
@@ -992,25 +1008,46 @@
992
1008
  }
993
1009
  }
994
1010
  },
995
- "tabsField": {
1011
+ "numberField": {
996
1012
  "type": "object",
997
- "description": "Tabbed interface for organizing fields",
998
- "required": ["name", "type", "tabs"],
1013
+ "description": "Integer number input field",
1014
+ "required": ["name", "type"],
999
1015
  "additionalProperties": false,
1000
1016
  "properties": {
1001
1017
  "name": {
1002
1018
  "type": "string"
1003
1019
  },
1004
1020
  "type": {
1005
- "const": "tabs"
1021
+ "const": "number"
1006
1022
  },
1007
- "tabs": {
1008
- "type": "array",
1009
- "description": "Tab definitions",
1010
- "items": {
1011
- "$ref": "#/$defs/tab"
1012
- },
1013
- "minItems": 1
1023
+ "label": {
1024
+ "type": "string"
1025
+ },
1026
+ "required": {
1027
+ "type": "boolean"
1028
+ },
1029
+ "default": {
1030
+ "type": "integer"
1031
+ },
1032
+ "defaultValueFrom": {
1033
+ "$ref": "#/$defs/defaultValueFrom"
1034
+ },
1035
+ "hint": {
1036
+ "type": "string"
1037
+ },
1038
+ "placeholder": {
1039
+ "type": "string",
1040
+ "description": "Placeholder text displayed in the number input"
1041
+ },
1042
+ "min": {
1043
+ "type": "integer"
1044
+ },
1045
+ "max": {
1046
+ "type": "integer"
1047
+ },
1048
+ "hidden": {
1049
+ "type": "boolean",
1050
+ "description": "Whether this field is hidden from the form UI but still exists in the database"
1014
1051
  },
1015
1052
  "height": {
1016
1053
  "enum": ["auto", "fill"],
@@ -1066,32 +1103,9 @@
1066
1103
  }
1067
1104
  }
1068
1105
  },
1069
- "separatorField": {
1070
- "type": "object",
1071
- "description": "Visual separator between form fields",
1072
- "required": ["type"],
1073
- "additionalProperties": false,
1074
- "properties": {
1075
- "name": {
1076
- "type": "string"
1077
- },
1078
- "type": {
1079
- "const": "separator"
1080
- },
1081
- "label": {
1082
- "type": "string",
1083
- "description": "Optional label to display with the separator"
1084
- },
1085
- "height": {
1086
- "enum": ["auto", "fill"],
1087
- "default": "auto",
1088
- "description": "Generated field height behavior: auto size or fill remaining flexible space."
1089
- }
1090
- }
1091
- },
1092
- "videoField": {
1106
+ "richtextField": {
1093
1107
  "type": "object",
1094
- "description": "Video upload field",
1108
+ "description": "WYSIWYG rich text editor with markdown storage",
1095
1109
  "required": ["name", "type"],
1096
1110
  "additionalProperties": false,
1097
1111
  "properties": {
@@ -1099,7 +1113,7 @@
1099
1113
  "type": "string"
1100
1114
  },
1101
1115
  "type": {
1102
- "const": "video"
1116
+ "const": "richtext"
1103
1117
  },
1104
1118
  "label": {
1105
1119
  "type": "string"
@@ -1110,17 +1124,25 @@
1110
1124
  "hint": {
1111
1125
  "type": "string"
1112
1126
  },
1127
+ "placeholder": {
1128
+ "type": "string",
1129
+ "description": "Placeholder text displayed in the rich text editor"
1130
+ },
1131
+ "output": {
1132
+ "type": "string",
1133
+ "description": "Output format \u2014 'html' adds a pre-rendered HTML column alongside the markdown source",
1134
+ "enum": ["html", "markdown"]
1135
+ },
1113
1136
  "defaultValueFrom": {
1114
1137
  "$ref": "#/$defs/defaultValueFrom"
1115
1138
  },
1116
- "maxSizeInMB": {
1117
- "type": "integer",
1118
- "description": "Maximum file size in megabytes"
1119
- },
1120
1139
  "hidden": {
1121
1140
  "type": "boolean",
1122
1141
  "description": "Whether this field is hidden from the form UI but still exists in the database"
1123
1142
  },
1143
+ "showWhen": {
1144
+ "$ref": "#/$defs/showWhenCondition"
1145
+ },
1124
1146
  "height": {
1125
1147
  "enum": ["auto", "fill"],
1126
1148
  "default": "auto",
@@ -1128,37 +1150,60 @@
1128
1150
  }
1129
1151
  }
1130
1152
  },
1131
- "mediaField": {
1153
+ "search": {
1132
1154
  "type": "object",
1133
- "description": "Media upload field supporting both images and videos",
1134
- "required": ["name", "type"],
1155
+ "description": "Backend search configuration for admin tables",
1156
+ "additionalProperties": false,
1157
+ "required": ["fields"],
1158
+ "properties": {
1159
+ "fields": {
1160
+ "type": "array",
1161
+ "description": "Array of field names to search across (should be text-type columns like string, text, varchar)",
1162
+ "items": {
1163
+ "type": "string",
1164
+ "description": "Field name to include in search"
1165
+ },
1166
+ "minItems": 1
1167
+ }
1168
+ }
1169
+ },
1170
+ "sectionField": {
1171
+ "type": "object",
1172
+ "description": "Section of fields displayed together. Top-level sidebar sections render as separate cards.",
1173
+ "required": ["name", "type", "fields"],
1135
1174
  "additionalProperties": false,
1136
1175
  "properties": {
1137
1176
  "name": {
1138
1177
  "type": "string"
1139
1178
  },
1140
1179
  "type": {
1141
- "const": "media"
1180
+ "const": "section"
1142
1181
  },
1143
1182
  "label": {
1144
1183
  "type": "string"
1145
1184
  },
1146
- "required": {
1147
- "type": "boolean"
1185
+ "description": {
1186
+ "type": "string"
1148
1187
  },
1149
1188
  "hint": {
1150
1189
  "type": "string"
1151
1190
  },
1152
- "defaultValueFrom": {
1153
- "$ref": "#/$defs/defaultValueFrom"
1191
+ "heading": {
1192
+ "$ref": "#/$defs/sectionHeading"
1154
1193
  },
1155
- "maxSizeInMB": {
1194
+ "columns": {
1156
1195
  "type": "integer",
1157
- "description": "Maximum file size in megabytes"
1196
+ "description": "Number of columns for layout",
1197
+ "minimum": 1,
1198
+ "maximum": 4
1158
1199
  },
1159
- "hidden": {
1160
- "type": "boolean",
1161
- "description": "Whether this field is hidden from the form UI but still exists in the database"
1200
+ "fields": {
1201
+ "type": "array",
1202
+ "description": "Nested field definitions",
1203
+ "items": {
1204
+ "$ref": "#/$defs/field"
1205
+ },
1206
+ "minItems": 1
1162
1207
  },
1163
1208
  "height": {
1164
1209
  "enum": ["auto", "fill"],
@@ -1167,9 +1212,25 @@
1167
1212
  }
1168
1213
  }
1169
1214
  },
1170
- "galleryField": {
1215
+ "sectionHeading": {
1171
1216
  "type": "object",
1172
- "description": "Multi-select media gallery field storing an array of media IDs with drag-to-reorder",
1217
+ "description": "Optional card heading rendered for sidebar section cards.",
1218
+ "required": ["title"],
1219
+ "additionalProperties": false,
1220
+ "properties": {
1221
+ "title": {
1222
+ "type": "string",
1223
+ "description": "Heading text rendered in the section card header."
1224
+ },
1225
+ "icon": {
1226
+ "type": "string",
1227
+ "description": "Lucide icon name rendered before the heading title, for example bolt or globe."
1228
+ }
1229
+ }
1230
+ },
1231
+ "selectField": {
1232
+ "type": "object",
1233
+ "description": "Dropdown select field",
1173
1234
  "required": ["name", "type"],
1174
1235
  "additionalProperties": false,
1175
1236
  "properties": {
@@ -1177,7 +1238,7 @@
1177
1238
  "type": "string"
1178
1239
  },
1179
1240
  "type": {
1180
- "const": "gallery"
1241
+ "const": "select"
1181
1242
  },
1182
1243
  "label": {
1183
1244
  "type": "string"
@@ -1188,13 +1249,58 @@
1188
1249
  "hint": {
1189
1250
  "type": "string"
1190
1251
  },
1252
+ "placeholder": {
1253
+ "type": "string",
1254
+ "description": "Placeholder text displayed in the select trigger"
1255
+ },
1256
+ "options": {
1257
+ "type": "array",
1258
+ "description": "Available options for the select",
1259
+ "items": {
1260
+ "type": "object",
1261
+ "required": ["label", "value"],
1262
+ "additionalProperties": false,
1263
+ "properties": {
1264
+ "label": {
1265
+ "type": "string",
1266
+ "description": "Display label"
1267
+ },
1268
+ "value": {
1269
+ "type": "string",
1270
+ "description": "Value stored in database"
1271
+ }
1272
+ }
1273
+ },
1274
+ "minItems": 1
1275
+ },
1276
+ "default": {
1277
+ "oneOf": [
1278
+ {
1279
+ "type": "string"
1280
+ },
1281
+ {
1282
+ "type": "array",
1283
+ "items": {
1284
+ "type": "string"
1285
+ }
1286
+ }
1287
+ ]
1288
+ },
1191
1289
  "defaultValueFrom": {
1192
1290
  "$ref": "#/$defs/defaultValueFrom"
1193
1291
  },
1194
- "maxItems": {
1292
+ "creatable": {
1293
+ "type": "boolean",
1294
+ "description": "Allow admins to create field-scoped options from the generated form"
1295
+ },
1296
+ "multiple": {
1297
+ "type": "boolean",
1298
+ "description": "Allow multiple selected option values"
1299
+ },
1300
+ "previewLimit": {
1195
1301
  "type": "integer",
1196
1302
  "minimum": 1,
1197
- "description": "Maximum number of media items"
1303
+ "description": "Number of selected labels shown before collapsing the rest into a count badge"
1198
1304
  },
1199
1305
  "hidden": {
1200
1306
  "type": "boolean",
@@ -1205,283 +1311,329 @@
1205
1311
  "default": "auto",
1206
1312
  "description": "Generated field height behavior: auto size or fill remaining flexible space."
1207
1313
  }
1208
- }
1314
+ },
1315
+ "allOf": [
1316
+ {
1317
+ "if": {
1318
+ "properties": {
1319
+ "multiple": {
1320
+ "const": true
1321
+ }
1322
+ },
1323
+ "required": ["multiple"]
1324
+ },
1325
+ "else": {
1326
+ "properties": {
1327
+ "default": {
1328
+ "type": "string"
1329
+ }
1330
+ },
1331
+ "not": {
1332
+ "required": ["previewLimit"]
1333
+ }
1334
+ }
1335
+ }
1336
+ ]
1209
1337
  },
1210
- "tab": {
1338
+ "separatorField": {
1211
1339
  "type": "object",
1212
- "description": "A single tab containing fields",
1213
- "required": ["name", "label"],
1340
+ "description": "Visual separator between form fields",
1341
+ "required": ["type"],
1214
1342
  "additionalProperties": false,
1215
1343
  "properties": {
1216
1344
  "name": {
1217
- "type": "string",
1218
- "description": "Tab identifier"
1345
+ "type": "string"
1346
+ },
1347
+ "type": {
1348
+ "const": "separator"
1219
1349
  },
1220
1350
  "label": {
1221
1351
  "type": "string",
1222
- "description": "Tab display label"
1352
+ "description": "Optional label to display with the separator"
1353
+ },
1354
+ "height": {
1355
+ "enum": ["auto", "fill"],
1356
+ "default": "auto",
1357
+ "description": "Generated field height behavior: auto size or fill remaining flexible space."
1358
+ }
1359
+ }
1360
+ },
1361
+ "showWhenCondition": {
1362
+ "type": "object",
1363
+ "description": "Conditional visibility based on sibling field value",
1364
+ "required": ["field", "value"],
1365
+ "additionalProperties": false,
1366
+ "properties": {
1367
+ "field": {
1368
+ "type": "string",
1369
+ "description": "Name of the sibling field to watch"
1370
+ },
1371
+ "value": {
1372
+ "oneOf": [
1373
+ {
1374
+ "type": "boolean"
1375
+ },
1376
+ {
1377
+ "type": "string"
1378
+ },
1379
+ {
1380
+ "type": "number"
1381
+ }
1382
+ ],
1383
+ "description": "Value that makes this field visible"
1384
+ }
1385
+ }
1386
+ },
1387
+ "simpleListItem": {
1388
+ "type": "object",
1389
+ "description": "Simple list item definition",
1390
+ "required": ["name", "type"],
1391
+ "additionalProperties": false,
1392
+ "properties": {
1393
+ "name": {
1394
+ "type": "string"
1395
+ },
1396
+ "type": {
1397
+ "type": "string"
1398
+ },
1399
+ "label": {
1400
+ "type": "string"
1401
+ },
1402
+ "required": {
1403
+ "type": "boolean"
1223
1404
  },
1405
+ "length": {
1406
+ "type": "integer"
1407
+ }
1408
+ }
1409
+ },
1410
+ "slotArea": {
1411
+ "type": "object",
1412
+ "description": "A named layout area containing generated form fields.",
1413
+ "required": ["fields"],
1414
+ "additionalProperties": false,
1415
+ "properties": {
1224
1416
  "fields": {
1225
1417
  "type": "array",
1226
- "description": "Fields within this tab",
1418
+ "description": "Fields rendered in this layout area.",
1227
1419
  "items": {
1228
1420
  "$ref": "#/$defs/field"
1229
1421
  },
1230
1422
  "minItems": 1
1423
+ }
1424
+ }
1425
+ },
1426
+ "slotLayout": {
1427
+ "type": "object",
1428
+ "description": "Main/sidebar layout groups for an entity edit form or tab panel.",
1429
+ "additionalProperties": false,
1430
+ "properties": {
1431
+ "main": {
1432
+ "$ref": "#/$defs/slotArea"
1231
1433
  },
1232
- "slot": {
1233
- "$ref": "#/$defs/slotLayout",
1234
- "description": "Tab-scoped main/sidebar layout. Sidebar fields render only while this tab is active."
1434
+ "sidebar": {
1435
+ "$ref": "#/$defs/slotArea"
1235
1436
  }
1236
1437
  },
1237
- "oneOf": [
1438
+ "anyOf": [
1238
1439
  {
1239
- "required": ["fields"],
1240
- "not": {
1241
- "required": ["slot"]
1242
- }
1440
+ "required": ["main"]
1243
1441
  },
1244
1442
  {
1245
- "required": ["slot"],
1246
- "not": {
1247
- "required": ["fields"]
1248
- }
1443
+ "required": ["sidebar"]
1249
1444
  }
1250
1445
  ]
1251
1446
  },
1252
- "column": {
1447
+ "slotLayoutWithCreatableSelect": {
1253
1448
  "type": "object",
1254
- "description": "Table column definition for list views",
1255
- "required": ["accessorKey", "header"],
1256
- "additionalProperties": false,
1257
- "properties": {
1258
- "accessorKey": {
1259
- "type": "string",
1260
- "description": "Field name to access data from"
1261
- },
1262
- "header": {
1263
- "type": "string",
1264
- "description": "Column header text"
1265
- },
1266
- "type": {
1267
- "type": "string",
1268
- "description": "Column display type",
1269
- "enum": ["image", "avatar", "text", "badge", "date", "email", "number", "link"]
1270
- },
1271
- "sortable": {
1272
- "type": "boolean",
1273
- "description": "Whether the column is sortable",
1274
- "default": false
1275
- },
1276
- "size": {
1277
- "type": "string",
1278
- "description": "Default table column width preset",
1279
- "enum": ["sm", "default", "lg", "xl"],
1280
- "default": "default"
1281
- },
1282
- "format": {
1283
- "type": "string",
1284
- "description": "Display format (e.g., 'currency' for numbers)",
1285
- "enum": ["currency", "percentage"]
1449
+ "anyOf": [
1450
+ {
1451
+ "properties": {
1452
+ "main": {
1453
+ "properties": {
1454
+ "fields": {
1455
+ "$ref": "#/$defs/fieldArrayWithCreatableSelect"
1456
+ }
1457
+ },
1458
+ "required": ["fields"]
1459
+ }
1460
+ },
1461
+ "required": ["main"]
1286
1462
  },
1287
- "align": {
1288
- "type": "string",
1289
- "description": "Column text alignment",
1290
- "enum": ["left", "center", "right"],
1291
- "default": "left"
1463
+ {
1464
+ "properties": {
1465
+ "sidebar": {
1466
+ "properties": {
1467
+ "fields": {
1468
+ "$ref": "#/$defs/fieldArrayWithCreatableSelect"
1469
+ }
1470
+ },
1471
+ "required": ["fields"]
1472
+ }
1473
+ },
1474
+ "required": ["sidebar"]
1292
1475
  }
1293
- }
1476
+ ]
1294
1477
  },
1295
- "actions": {
1478
+ "slotLayoutWithTitle": {
1296
1479
  "type": "object",
1297
- "description": "CRUD action configuration",
1298
- "additionalProperties": false,
1299
- "properties": {
1300
- "draft": {
1301
- "type": "boolean",
1302
- "description": "Enable draft/publish workflow",
1303
- "default": false
1304
- },
1305
- "create": {
1306
- "type": "boolean",
1307
- "description": "Enable create action",
1308
- "default": true
1309
- },
1310
- "edit": {
1311
- "type": "boolean",
1312
- "description": "Enable edit action",
1313
- "default": true
1314
- },
1315
- "delete": {
1316
- "type": "boolean",
1317
- "description": "Enable delete action",
1318
- "default": true
1480
+ "anyOf": [
1481
+ {
1482
+ "properties": {
1483
+ "main": {
1484
+ "properties": {
1485
+ "fields": {
1486
+ "$ref": "#/$defs/fieldArrayWithTitle"
1487
+ }
1488
+ },
1489
+ "required": ["fields"]
1490
+ }
1491
+ },
1492
+ "required": ["main"]
1319
1493
  },
1320
- "export": {
1321
- "type": "boolean",
1322
- "description": "Form-only: surface a CSV export action for submissions.",
1323
- "default": false
1494
+ {
1495
+ "properties": {
1496
+ "sidebar": {
1497
+ "properties": {
1498
+ "fields": {
1499
+ "$ref": "#/$defs/fieldArrayWithTitle"
1500
+ }
1501
+ },
1502
+ "required": ["fields"]
1503
+ }
1504
+ },
1505
+ "required": ["sidebar"]
1324
1506
  }
1325
- }
1507
+ ]
1326
1508
  },
1327
- "search": {
1509
+ "stepWithTitle": {
1328
1510
  "type": "object",
1329
- "description": "Backend search configuration for admin tables",
1330
- "additionalProperties": false,
1331
- "required": ["fields"],
1332
1511
  "properties": {
1333
1512
  "fields": {
1334
- "type": "array",
1335
- "description": "Array of field names to search across (should be text-type columns like string, text, varchar)",
1336
- "items": {
1337
- "type": "string",
1338
- "description": "Field name to include in search"
1339
- },
1340
- "minItems": 1
1513
+ "$ref": "#/$defs/fieldArrayWithTitle"
1341
1514
  }
1342
- }
1343
- },
1344
- "filters": {
1345
- "type": "array",
1346
- "description": "Filter configuration for admin tables",
1347
- "items": {
1348
- "$ref": "#/$defs/filter"
1349
- }
1515
+ },
1516
+ "required": ["fields"]
1350
1517
  },
1351
- "filter": {
1518
+ "stringField": {
1352
1519
  "type": "object",
1353
- "description": "Filter definition for admin tables",
1354
- "required": ["field", "label"],
1520
+ "description": "Single-line text input field",
1521
+ "required": ["name", "type"],
1355
1522
  "additionalProperties": false,
1356
1523
  "properties": {
1357
- "key": {
1358
- "type": "string",
1359
- "description": "Optional query param key for this filter. Defaults to the field name."
1524
+ "name": {
1525
+ "type": "string"
1360
1526
  },
1361
- "field": {
1362
- "type": "string",
1363
- "description": "Field name to filter by"
1527
+ "type": {
1528
+ "const": "string"
1364
1529
  },
1365
1530
  "label": {
1366
- "type": "string",
1367
- "description": "Label for the filter dropdown"
1531
+ "type": "string"
1368
1532
  },
1369
- "type": {
1370
- "type": "string",
1371
- "description": "Filter type",
1372
- "enum": ["select", "boolean"],
1373
- "default": "select"
1533
+ "required": {
1534
+ "type": "boolean"
1374
1535
  },
1375
- "source": {
1536
+ "length": {
1537
+ "type": "integer",
1538
+ "description": "Maximum character length",
1539
+ "minimum": 1,
1540
+ "maximum": 65535
1541
+ },
1542
+ "hint": {
1543
+ "type": "string"
1544
+ },
1545
+ "placeholder": {
1376
1546
  "type": "string",
1377
- "description": "Where select filter options come from",
1378
- "enum": ["distinct", "static"]
1547
+ "description": "Placeholder text displayed in the input field"
1379
1548
  },
1380
- "options": {
1381
- "type": "array",
1382
- "description": "Static options for select filters",
1383
- "items": {
1384
- "type": "object",
1385
- "required": ["label", "value"],
1386
- "additionalProperties": false,
1387
- "properties": {
1388
- "label": {
1389
- "type": "string",
1390
- "description": "Option label shown in the filter UI"
1391
- },
1392
- "value": {
1393
- "type": "string",
1394
- "description": "Option value sent to the backend filter"
1395
- }
1396
- }
1397
- }
1549
+ "default": {
1550
+ "type": "string"
1551
+ },
1552
+ "defaultValueFrom": {
1553
+ "$ref": "#/$defs/defaultValueFrom"
1554
+ },
1555
+ "hasIcon": {
1556
+ "type": "boolean",
1557
+ "description": "Whether this field has an associated icon picker"
1558
+ },
1559
+ "hidden": {
1560
+ "type": "boolean",
1561
+ "description": "Whether this field is hidden from the form UI but still exists in the database"
1562
+ },
1563
+ "showWhen": {
1564
+ "$ref": "#/$defs/showWhenCondition"
1565
+ },
1566
+ "height": {
1567
+ "enum": ["auto", "fill"],
1568
+ "default": "auto",
1569
+ "description": "Generated field height behavior: auto size or fill remaining flexible space."
1398
1570
  }
1399
1571
  }
1400
1572
  },
1401
- "slotLayout": {
1573
+ "tab": {
1402
1574
  "type": "object",
1403
- "description": "Main/sidebar layout groups for an entity edit form or tab panel.",
1575
+ "description": "A single tab containing fields",
1576
+ "required": ["name", "label"],
1404
1577
  "additionalProperties": false,
1405
1578
  "properties": {
1406
- "main": {
1407
- "$ref": "#/$defs/slotArea"
1579
+ "name": {
1580
+ "type": "string",
1581
+ "description": "Tab identifier"
1408
1582
  },
1409
- "sidebar": {
1410
- "$ref": "#/$defs/slotArea"
1411
- }
1412
- },
1413
- "anyOf": [
1414
- {
1415
- "required": ["main"]
1583
+ "label": {
1584
+ "type": "string",
1585
+ "description": "Tab display label"
1586
+ },
1587
+ "icon": {
1588
+ "type": "string",
1589
+ "description": "Lucide icon name rendered before the tab label"
1416
1590
  },
1417
- {
1418
- "required": ["sidebar"]
1419
- }
1420
- ]
1421
- },
1422
- "slotArea": {
1423
- "type": "object",
1424
- "description": "A named layout area containing generated form fields.",
1425
- "required": ["fields"],
1426
- "additionalProperties": false,
1427
- "properties": {
1428
1591
  "fields": {
1429
1592
  "type": "array",
1430
- "description": "Fields rendered in this layout area.",
1593
+ "description": "Fields within this tab",
1431
1594
  "items": {
1432
1595
  "$ref": "#/$defs/field"
1433
1596
  },
1434
1597
  "minItems": 1
1598
+ },
1599
+ "slot": {
1600
+ "$ref": "#/$defs/slotLayout",
1601
+ "description": "Tab-scoped main/sidebar layout. Sidebar fields render only while this tab is active."
1435
1602
  }
1436
- }
1437
- },
1438
- "fieldArrayWithCreatableSelect": {
1439
- "type": "array",
1440
- "contains": {
1441
- "$ref": "#/$defs/fieldWithCreatableSelect"
1442
- }
1443
- },
1444
- "fieldArrayWithTitle": {
1445
- "type": "array",
1446
- "contains": {
1447
- "$ref": "#/$defs/fieldWithTitle"
1448
- }
1603
+ },
1604
+ "oneOf": [
1605
+ {
1606
+ "required": ["fields"],
1607
+ "not": {
1608
+ "required": ["slot"]
1609
+ }
1610
+ },
1611
+ {
1612
+ "required": ["slot"],
1613
+ "not": {
1614
+ "required": ["fields"]
1615
+ }
1616
+ }
1617
+ ]
1449
1618
  },
1450
- "fieldWithTitle": {
1619
+ "tabWithCreatableSelect": {
1451
1620
  "type": "object",
1452
1621
  "anyOf": [
1453
1622
  {
1454
1623
  "properties": {
1455
- "name": {
1456
- "const": "title"
1457
- },
1458
- "type": {
1459
- "enum": ["string", "varchar", "text"]
1460
- }
1461
- },
1462
- "required": ["name", "type"]
1463
- },
1464
- {
1465
- "properties": {
1466
- "type": {
1467
- "enum": ["group", "section"]
1468
- },
1469
1624
  "fields": {
1470
- "$ref": "#/$defs/fieldArrayWithTitle"
1625
+ "$ref": "#/$defs/fieldArrayWithCreatableSelect"
1471
1626
  }
1472
1627
  },
1473
- "required": ["type", "fields"]
1628
+ "required": ["fields"]
1474
1629
  },
1475
1630
  {
1476
1631
  "properties": {
1477
- "tabs": {
1478
- "type": "array",
1479
- "contains": {
1480
- "$ref": "#/$defs/tabWithTitle"
1481
- }
1632
+ "slot": {
1633
+ "$ref": "#/$defs/slotLayoutWithCreatableSelect"
1482
1634
  }
1483
1635
  },
1484
- "required": ["tabs"]
1636
+ "required": ["slot"]
1485
1637
  }
1486
1638
  ]
1487
1639
  },
@@ -1506,186 +1658,280 @@
1506
1658
  }
1507
1659
  ]
1508
1660
  },
1509
- "slotLayoutWithTitle": {
1661
+ "tabsField": {
1510
1662
  "type": "object",
1511
- "anyOf": [
1512
- {
1513
- "properties": {
1514
- "main": {
1515
- "properties": {
1516
- "fields": {
1517
- "$ref": "#/$defs/fieldArrayWithTitle"
1518
- }
1519
- },
1520
- "required": ["fields"]
1521
- }
1663
+ "description": "Tabbed interface for organizing fields",
1664
+ "required": ["name", "type", "tabs"],
1665
+ "additionalProperties": false,
1666
+ "properties": {
1667
+ "name": {
1668
+ "type": "string"
1669
+ },
1670
+ "type": {
1671
+ "const": "tabs"
1672
+ },
1673
+ "tabs": {
1674
+ "type": "array",
1675
+ "description": "Tab definitions",
1676
+ "items": {
1677
+ "$ref": "#/$defs/tab"
1522
1678
  },
1523
- "required": ["main"]
1679
+ "minItems": 1
1680
+ },
1681
+ "height": {
1682
+ "enum": ["auto", "fill"],
1683
+ "default": "auto",
1684
+ "description": "Generated field height behavior: auto size or fill remaining flexible space."
1685
+ }
1686
+ }
1687
+ },
1688
+ "textField": {
1689
+ "type": "object",
1690
+ "description": "Multi-line text area field",
1691
+ "required": ["name", "type"],
1692
+ "additionalProperties": false,
1693
+ "properties": {
1694
+ "name": {
1695
+ "type": "string"
1696
+ },
1697
+ "type": {
1698
+ "const": "text"
1699
+ },
1700
+ "label": {
1701
+ "type": "string"
1702
+ },
1703
+ "required": {
1704
+ "type": "boolean"
1705
+ },
1706
+ "length": {
1707
+ "type": "integer",
1708
+ "description": "Maximum character length",
1709
+ "minimum": 1
1710
+ },
1711
+ "hint": {
1712
+ "type": "string"
1713
+ },
1714
+ "placeholder": {
1715
+ "type": "string",
1716
+ "description": "Placeholder text displayed in the text area"
1717
+ },
1718
+ "default": {
1719
+ "type": "string"
1720
+ },
1721
+ "defaultValueFrom": {
1722
+ "$ref": "#/$defs/defaultValueFrom"
1723
+ },
1724
+ "hidden": {
1725
+ "type": "boolean",
1726
+ "description": "Whether this field is hidden from the form UI but still exists in the database"
1727
+ },
1728
+ "showWhen": {
1729
+ "$ref": "#/$defs/showWhenCondition"
1730
+ },
1731
+ "height": {
1732
+ "enum": ["auto", "fill"],
1733
+ "default": "auto",
1734
+ "description": "Generated field height behavior: auto size or fill remaining flexible space."
1735
+ }
1736
+ }
1737
+ },
1738
+ "timeField": {
1739
+ "type": "object",
1740
+ "description": "Time-of-day input field, stored as VARCHAR",
1741
+ "required": ["name", "type"],
1742
+ "additionalProperties": false,
1743
+ "properties": {
1744
+ "name": {
1745
+ "type": "string"
1746
+ },
1747
+ "type": {
1748
+ "const": "time"
1749
+ },
1750
+ "label": {
1751
+ "type": "string"
1752
+ },
1753
+ "required": {
1754
+ "type": "boolean"
1755
+ },
1756
+ "length": {
1757
+ "type": "integer",
1758
+ "description": "Maximum character length",
1759
+ "minimum": 1,
1760
+ "maximum": 65535
1761
+ },
1762
+ "hint": {
1763
+ "type": "string"
1764
+ },
1765
+ "placeholder": {
1766
+ "type": "string",
1767
+ "description": "Placeholder text displayed in the input field"
1768
+ },
1769
+ "default": {
1770
+ "type": "string"
1524
1771
  },
1525
- {
1526
- "properties": {
1527
- "sidebar": {
1528
- "properties": {
1529
- "fields": {
1530
- "$ref": "#/$defs/fieldArrayWithTitle"
1531
- }
1532
- },
1533
- "required": ["fields"]
1534
- }
1535
- },
1536
- "required": ["sidebar"]
1772
+ "defaultValueFrom": {
1773
+ "$ref": "#/$defs/defaultValueFrom"
1774
+ },
1775
+ "hasIcon": {
1776
+ "type": "boolean",
1777
+ "description": "Whether this field has an associated icon picker"
1778
+ },
1779
+ "hidden": {
1780
+ "type": "boolean",
1781
+ "description": "Whether this field is hidden from the form UI but still exists in the database"
1782
+ },
1783
+ "showWhen": {
1784
+ "$ref": "#/$defs/showWhenCondition"
1785
+ },
1786
+ "height": {
1787
+ "enum": ["auto", "fill"],
1788
+ "default": "auto",
1789
+ "description": "Generated field height behavior: auto size or fill remaining flexible space."
1537
1790
  }
1538
- ]
1791
+ }
1539
1792
  },
1540
- "stepWithTitle": {
1793
+ "timestampField": {
1541
1794
  "type": "object",
1795
+ "description": "Timestamp field (typically auto-generated)",
1796
+ "required": ["name", "type"],
1797
+ "additionalProperties": false,
1542
1798
  "properties": {
1543
- "fields": {
1544
- "$ref": "#/$defs/fieldArrayWithTitle"
1545
- }
1546
- },
1547
- "required": ["fields"]
1548
- },
1549
- "fieldWithCreatableSelect": {
1550
- "type": "object",
1551
- "anyOf": [
1552
- {
1553
- "properties": {
1554
- "type": {
1555
- "const": "select"
1556
- },
1557
- "creatable": {
1558
- "const": true
1559
- }
1560
- },
1561
- "required": ["type", "creatable"]
1799
+ "name": {
1800
+ "type": "string"
1562
1801
  },
1563
- {
1564
- "properties": {
1565
- "fields": {
1566
- "$ref": "#/$defs/fieldArrayWithCreatableSelect"
1567
- }
1568
- },
1569
- "required": ["fields"]
1802
+ "type": {
1803
+ "const": "timestamp"
1570
1804
  },
1571
- {
1572
- "properties": {
1573
- "tabs": {
1574
- "type": "array",
1575
- "contains": {
1576
- "$ref": "#/$defs/tabWithCreatableSelect"
1577
- }
1578
- }
1579
- },
1580
- "required": ["tabs"]
1581
- }
1582
- ]
1583
- },
1584
- "tabWithCreatableSelect": {
1585
- "type": "object",
1586
- "anyOf": [
1587
- {
1588
- "properties": {
1589
- "fields": {
1590
- "$ref": "#/$defs/fieldArrayWithCreatableSelect"
1591
- }
1592
- },
1593
- "required": ["fields"]
1805
+ "label": {
1806
+ "type": "string"
1594
1807
  },
1595
- {
1596
- "properties": {
1597
- "slot": {
1598
- "$ref": "#/$defs/slotLayoutWithCreatableSelect"
1599
- }
1600
- },
1601
- "required": ["slot"]
1808
+ "required": {
1809
+ "type": "boolean"
1810
+ },
1811
+ "defaultValueFrom": {
1812
+ "$ref": "#/$defs/defaultValueFrom"
1813
+ },
1814
+ "hidden": {
1815
+ "type": "boolean",
1816
+ "description": "Whether this field is hidden from the form UI but still exists in the database"
1817
+ },
1818
+ "height": {
1819
+ "enum": ["auto", "fill"],
1820
+ "default": "auto",
1821
+ "description": "Generated field height behavior: auto size or fill remaining flexible space."
1602
1822
  }
1603
- ]
1823
+ }
1604
1824
  },
1605
- "slotLayoutWithCreatableSelect": {
1825
+ "uuidField": {
1606
1826
  "type": "object",
1607
- "anyOf": [
1608
- {
1609
- "properties": {
1610
- "main": {
1611
- "properties": {
1612
- "fields": {
1613
- "$ref": "#/$defs/fieldArrayWithCreatableSelect"
1614
- }
1615
- },
1616
- "required": ["fields"]
1617
- }
1618
- },
1619
- "required": ["main"]
1827
+ "description": "UUID primary key field",
1828
+ "required": ["name", "type"],
1829
+ "additionalProperties": false,
1830
+ "properties": {
1831
+ "name": {
1832
+ "type": "string"
1620
1833
  },
1621
- {
1622
- "properties": {
1623
- "sidebar": {
1624
- "properties": {
1625
- "fields": {
1626
- "$ref": "#/$defs/fieldArrayWithCreatableSelect"
1627
- }
1628
- },
1629
- "required": ["fields"]
1630
- }
1631
- },
1632
- "required": ["sidebar"]
1834
+ "type": {
1835
+ "const": "uuid"
1836
+ },
1837
+ "primaryKey": {
1838
+ "type": "boolean",
1839
+ "description": "Whether this is the primary key",
1840
+ "default": true
1841
+ },
1842
+ "height": {
1843
+ "enum": ["auto", "fill"],
1844
+ "default": "auto",
1845
+ "description": "Generated field height behavior: auto size or fill remaining flexible space."
1633
1846
  }
1634
- ]
1847
+ }
1635
1848
  },
1636
- "sectionHeading": {
1849
+ "varcharField": {
1637
1850
  "type": "object",
1638
- "description": "Optional card heading rendered for sidebar section cards.",
1639
- "required": ["title"],
1851
+ "description": "Fixed-length text input field",
1852
+ "required": ["name", "type"],
1640
1853
  "additionalProperties": false,
1641
1854
  "properties": {
1642
- "title": {
1643
- "type": "string",
1644
- "description": "Heading text rendered in the section card header."
1855
+ "name": {
1856
+ "type": "string"
1645
1857
  },
1646
- "icon": {
1858
+ "type": {
1859
+ "const": "varchar"
1860
+ },
1861
+ "label": {
1862
+ "type": "string"
1863
+ },
1864
+ "required": {
1865
+ "type": "boolean"
1866
+ },
1867
+ "length": {
1868
+ "type": "integer",
1869
+ "description": "Maximum character length",
1870
+ "minimum": 1,
1871
+ "maximum": 65535
1872
+ },
1873
+ "hint": {
1874
+ "type": "string"
1875
+ },
1876
+ "placeholder": {
1647
1877
  "type": "string",
1648
- "description": "Lucide icon name rendered before the heading title, for example bolt or globe."
1878
+ "description": "Placeholder text displayed in the input field"
1879
+ },
1880
+ "default": {
1881
+ "type": "string"
1882
+ },
1883
+ "defaultValueFrom": {
1884
+ "$ref": "#/$defs/defaultValueFrom"
1885
+ },
1886
+ "hasIcon": {
1887
+ "type": "boolean",
1888
+ "description": "Whether this field has an associated icon picker"
1889
+ },
1890
+ "hidden": {
1891
+ "type": "boolean",
1892
+ "description": "Whether this field is hidden from the form UI but still exists in the database"
1893
+ },
1894
+ "showWhen": {
1895
+ "$ref": "#/$defs/showWhenCondition"
1896
+ },
1897
+ "height": {
1898
+ "enum": ["auto", "fill"],
1899
+ "default": "auto",
1900
+ "description": "Generated field height behavior: auto size or fill remaining flexible space."
1649
1901
  }
1650
1902
  }
1651
1903
  },
1652
- "sectionField": {
1904
+ "videoField": {
1653
1905
  "type": "object",
1654
- "description": "Section of fields displayed together. Top-level sidebar sections render as separate cards.",
1655
- "required": ["name", "type", "fields"],
1906
+ "description": "Video upload field",
1907
+ "required": ["name", "type"],
1656
1908
  "additionalProperties": false,
1657
1909
  "properties": {
1658
1910
  "name": {
1659
1911
  "type": "string"
1660
1912
  },
1661
1913
  "type": {
1662
- "const": "section"
1914
+ "const": "video"
1663
1915
  },
1664
1916
  "label": {
1665
1917
  "type": "string"
1666
1918
  },
1667
- "description": {
1668
- "type": "string"
1919
+ "required": {
1920
+ "type": "boolean"
1669
1921
  },
1670
1922
  "hint": {
1671
1923
  "type": "string"
1672
1924
  },
1673
- "heading": {
1674
- "$ref": "#/$defs/sectionHeading"
1925
+ "defaultValueFrom": {
1926
+ "$ref": "#/$defs/defaultValueFrom"
1675
1927
  },
1676
- "columns": {
1928
+ "maxSizeInMB": {
1677
1929
  "type": "integer",
1678
- "description": "Number of columns for layout",
1679
- "minimum": 1,
1680
- "maximum": 4
1930
+ "description": "Maximum file size in megabytes"
1681
1931
  },
1682
- "fields": {
1683
- "type": "array",
1684
- "description": "Nested field definitions",
1685
- "items": {
1686
- "$ref": "#/$defs/field"
1687
- },
1688
- "minItems": 1
1932
+ "hidden": {
1933
+ "type": "boolean",
1934
+ "description": "Whether this field is hidden from the form UI but still exists in the database"
1689
1935
  },
1690
1936
  "height": {
1691
1937
  "enum": ["auto", "fill"],
@@ -1699,19 +1945,40 @@
1699
1945
  {
1700
1946
  "required": ["fields"],
1701
1947
  "not": {
1702
- "anyOf": [{ "required": ["slot"] }, { "required": ["steps"] }]
1948
+ "anyOf": [
1949
+ {
1950
+ "required": ["slot"]
1951
+ },
1952
+ {
1953
+ "required": ["steps"]
1954
+ }
1955
+ ]
1703
1956
  }
1704
1957
  },
1705
1958
  {
1706
1959
  "required": ["slot"],
1707
1960
  "not": {
1708
- "anyOf": [{ "required": ["fields"] }, { "required": ["steps"] }]
1961
+ "anyOf": [
1962
+ {
1963
+ "required": ["fields"]
1964
+ },
1965
+ {
1966
+ "required": ["steps"]
1967
+ }
1968
+ ]
1709
1969
  }
1710
1970
  },
1711
1971
  {
1712
1972
  "required": ["steps"],
1713
1973
  "not": {
1714
- "anyOf": [{ "required": ["fields"] }, { "required": ["slot"] }]
1974
+ "anyOf": [
1975
+ {
1976
+ "required": ["fields"]
1977
+ },
1978
+ {
1979
+ "required": ["slot"]
1980
+ }
1981
+ ]
1715
1982
  }
1716
1983
  }
1717
1984
  ],