@abeedoo/radish-schemas 1.7.7

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.
@@ -0,0 +1,761 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "$id": "https://radish.dev/schemas/types.schema.json",
4
+ "title": "Radish Blueprint (Data Layer)",
5
+ "type": "object",
6
+ "required": [
7
+ "version",
8
+ "entities"
9
+ ],
10
+ "additionalProperties": false,
11
+ "properties": {
12
+ "version": {
13
+ "type": "integer",
14
+ "minimum": 1
15
+ },
16
+ "defaults": {
17
+ "type": "object",
18
+ "additionalProperties": false,
19
+ "properties": {
20
+ "owned": {
21
+ "type": "boolean"
22
+ },
23
+ "timestamps": {
24
+ "type": "boolean"
25
+ },
26
+ "adminRole": {
27
+ "type": "string"
28
+ }
29
+ }
30
+ },
31
+ "entities": {
32
+ "type": "object",
33
+ "minProperties": 1,
34
+ "patternProperties": {
35
+ "^[A-Z][A-Za-z0-9_]*$": {
36
+ "type": "object",
37
+ "required": [
38
+ "plural",
39
+ "fields"
40
+ ],
41
+ "additionalProperties": false,
42
+ "properties": {
43
+ "entityId": {
44
+ "type": "string"
45
+ },
46
+ "label": {
47
+ "type": "string"
48
+ },
49
+ "description": {
50
+ "type": "string"
51
+ },
52
+ "plural": {
53
+ "type": "string",
54
+ "minLength": 1
55
+ },
56
+ "ownership": {
57
+ "type": "string",
58
+ "enum": ["user", "system", "tenant"],
59
+ "default": "user"
60
+ },
61
+ "extends": {
62
+ "type": "string",
63
+ "description": "Base type to extend from. Can be EntityBase, SystemEntityBase, ContentBase, or another entity name.",
64
+ "pattern": "^([A-Z][A-Za-z0-9_]*|EntityBase|SystemEntityBase|ContentBase)$"
65
+ },
66
+ "scope": {
67
+ "type": "object",
68
+ "description": "Scoped access control. Two modes: through-entity (check ownership of a related entity) or direct-match (match a user field against the record's field).",
69
+ "required": ["field"],
70
+ "additionalProperties": false,
71
+ "properties": {
72
+ "field": {
73
+ "type": "string",
74
+ "description": "Field on this entity to match against (e.g., 'orgId', 'appId')"
75
+ },
76
+ "through": {
77
+ "type": "string",
78
+ "description": "Related entity model to check ownership through (e.g., 'App'). Used for through-entity mode."
79
+ },
80
+ "ownerField": {
81
+ "type": "string",
82
+ "default": "ownerId",
83
+ "description": "Field on the related entity that identifies the owner"
84
+ },
85
+ "matchUserField": {
86
+ "type": "string",
87
+ "description": "Field on the User to match against record's field directly (e.g., 'orgIds'). Supports array match. Used for direct-match / multi-tenant mode."
88
+ }
89
+ }
90
+ },
91
+ "search": {
92
+ "type": "object",
93
+ "description": "Search index configuration for this entity. Generates search adapters and typed search index classes.",
94
+ "required": ["enabled"],
95
+ "additionalProperties": false,
96
+ "properties": {
97
+ "enabled": {
98
+ "type": "boolean",
99
+ "description": "Enable search indexing for this entity"
100
+ },
101
+ "engine": {
102
+ "type": "string",
103
+ "enum": ["typesense", "elastic", "opensearch", "meilisearch", "mongoAtlas"],
104
+ "description": "Search engine to use"
105
+ },
106
+ "indexName": {
107
+ "type": "string",
108
+ "description": "Name of the search index (defaults to entity plural)"
109
+ },
110
+ "fields": {
111
+ "type": "object",
112
+ "description": "Field classifications for search behavior",
113
+ "additionalProperties": false,
114
+ "properties": {
115
+ "searchable": {
116
+ "type": "array",
117
+ "items": { "type": "string" },
118
+ "description": "Fields included in full-text search queries"
119
+ },
120
+ "filterable": {
121
+ "type": "array",
122
+ "items": { "type": "string" },
123
+ "description": "Fields available as filter criteria"
124
+ },
125
+ "sortable": {
126
+ "type": "array",
127
+ "items": { "type": "string" },
128
+ "description": "Fields available for sort ordering"
129
+ },
130
+ "facetable": {
131
+ "type": "array",
132
+ "items": { "type": "string" },
133
+ "description": "Fields available as faceted navigation"
134
+ }
135
+ }
136
+ },
137
+ "sync": {
138
+ "type": "string",
139
+ "enum": ["inline", "background"],
140
+ "description": "Sync mode: inline (immediate) or background (via jobs)"
141
+ },
142
+ "vector": {
143
+ "type": "object",
144
+ "description": "Vector/embedding search configuration",
145
+ "additionalProperties": false,
146
+ "properties": {
147
+ "enabled": {
148
+ "type": "boolean",
149
+ "description": "Enable vector search for this entity"
150
+ },
151
+ "sourceFields": {
152
+ "type": "array",
153
+ "items": { "type": "string" },
154
+ "description": "Fields to generate embeddings from"
155
+ }
156
+ }
157
+ }
158
+ }
159
+ },
160
+ "collation": {
161
+ "type": "object",
162
+ "description": "MongoDB collation settings for this collection",
163
+ "additionalProperties": false,
164
+ "properties": {
165
+ "locale": {
166
+ "type": "string",
167
+ "description": "The ICU locale identifier (e.g., 'en', 'en_US', 'fr')",
168
+ "default": "en"
169
+ },
170
+ "strength": {
171
+ "type": "integer",
172
+ "description": "Comparison level: 1=primary(base chars), 2=secondary(+diacritics), 3=tertiary(+case)",
173
+ "minimum": 1,
174
+ "maximum": 5,
175
+ "default": 2
176
+ },
177
+ "numericOrdering": {
178
+ "type": "boolean",
179
+ "description": "Compare numeric strings as numbers (e.g., '10' > '2')",
180
+ "default": true
181
+ },
182
+ "caseLevel": {
183
+ "type": "boolean",
184
+ "description": "Include case comparison at strength 1 or 2"
185
+ },
186
+ "caseFirst": {
187
+ "type": "string",
188
+ "enum": ["upper", "lower", "off"],
189
+ "description": "Sort order of case: 'upper' first, 'lower' first, or 'off'"
190
+ },
191
+ "normalization": {
192
+ "type": "boolean",
193
+ "description": "Check text normalization"
194
+ },
195
+ "backwards": {
196
+ "type": "boolean",
197
+ "description": "Compare diacritics from back to front"
198
+ },
199
+ "alternate": {
200
+ "type": "string",
201
+ "enum": ["non-ignorable", "shifted"],
202
+ "description": "Treatment of whitespace and punctuation"
203
+ },
204
+ "maxVariable": {
205
+ "type": "string",
206
+ "enum": ["punct", "space"],
207
+ "description": "Characters considered ignorable when alternate='shifted'"
208
+ }
209
+ }
210
+ },
211
+ "fields": {
212
+ "type": "object",
213
+ "minProperties": 1,
214
+ "patternProperties": {
215
+ "^[a-zA-Z_][a-zA-Z0-9_]*$": {
216
+ "type": "object",
217
+ "required": [
218
+ "type"
219
+ ],
220
+ "additionalProperties": false,
221
+ "properties": {
222
+ "type": {
223
+ "type": "string",
224
+ "enum": [
225
+ "string",
226
+ "int",
227
+ "float",
228
+ "boolean",
229
+ "any",
230
+ "url",
231
+ "isoDate",
232
+ "objectId",
233
+ "enum",
234
+ "object",
235
+ "string[]",
236
+ "int[]",
237
+ "float[]",
238
+ "boolean[]",
239
+ "objectId[]",
240
+ "url[]",
241
+ "array",
242
+ "secretKey",
243
+ "encryptedKey"
244
+ ]
245
+ },
246
+ "required": {
247
+ "type": "boolean"
248
+ },
249
+ "optional": {
250
+ "type": "boolean"
251
+ },
252
+ "unique": {
253
+ "type": "boolean"
254
+ },
255
+ "index": {
256
+ "type": "boolean"
257
+ },
258
+ "default": {},
259
+ "allowedMacros": {
260
+ "type": "array",
261
+ "items": {
262
+ "type": "string",
263
+ "enum": [
264
+ "UUID",
265
+ "NOW",
266
+ "TIMESTAMP",
267
+ "TODAY",
268
+ "USER_ID"
269
+ ]
270
+ }
271
+ },
272
+ "values": {
273
+ "type": "array",
274
+ "items": {
275
+ "oneOf": [
276
+ {
277
+ "type": "string",
278
+ "description": "Legacy simple enum format"
279
+ },
280
+ {
281
+ "type": "object",
282
+ "description": "Enhanced enum format with key-label pairs",
283
+ "required": ["key"],
284
+ "additionalProperties": false,
285
+ "properties": {
286
+ "key": {
287
+ "type": "string"
288
+ },
289
+ "label": {
290
+ "type": "string"
291
+ }
292
+ }
293
+ }
294
+ ]
295
+ }
296
+ },
297
+ "search": {
298
+ "type": "boolean"
299
+ },
300
+ "trackChanges": {
301
+ "type": "boolean",
302
+ "description": "Enable detailed field-level change tracking with metadata (change reason, approvals, etc.)"
303
+ },
304
+ "ref": {
305
+ "type": "string"
306
+ },
307
+ "label": {
308
+ "type": "string"
309
+ },
310
+ "description": {
311
+ "type": "string"
312
+ },
313
+ "lastChars": {
314
+ "type": "integer",
315
+ "minimum": 0,
316
+ "maximum": 20,
317
+ "default": 4
318
+ },
319
+ "fields": {
320
+ "type": "object",
321
+ "patternProperties": {
322
+ "^[a-zA-Z_][a-zA-Z0-9_]*$": {
323
+ "$ref": "#/definitions/field"
324
+ }
325
+ },
326
+ "additionalProperties": false
327
+ },
328
+ "items": {
329
+ "$ref": "#/definitions/field"
330
+ },
331
+ "internal": {
332
+ "type": "boolean",
333
+ "default": false
334
+ },
335
+ "select": {
336
+ "type": "boolean",
337
+ "default": true
338
+ },
339
+ "secret": {
340
+ "type": "string",
341
+ "enum": [
342
+ "hash",
343
+ "encrypt"
344
+ ]
345
+ },
346
+ "hash": {
347
+ "type": "object",
348
+ "properties": {
349
+ "algo": {
350
+ "type": "string",
351
+ "enum": [
352
+ "argon2id",
353
+ "bcrypt"
354
+ ],
355
+ "default": "argon2id"
356
+ },
357
+ "params": {
358
+ "type": "object",
359
+ "additionalProperties": true
360
+ }
361
+ },
362
+ "required": [
363
+ "algo"
364
+ ],
365
+ "additionalProperties": true
366
+ },
367
+ "expose": {
368
+ "type": "object",
369
+ "properties": {
370
+ "contracts": {
371
+ "type": "boolean"
372
+ },
373
+ "create": {
374
+ "type": "boolean"
375
+ },
376
+ "update": {
377
+ "type": "boolean"
378
+ },
379
+ "read": {
380
+ "type": "boolean"
381
+ }
382
+ },
383
+ "additionalProperties": false
384
+ },
385
+ "access": {
386
+ "type": "object",
387
+ "description": "Field-level access control. Restricts which roles can read or write this field.",
388
+ "additionalProperties": false,
389
+ "properties": {
390
+ "read": {
391
+ "type": "array",
392
+ "items": { "type": "string" },
393
+ "description": "Roles that can read this field. If omitted, visible to anyone with entity access."
394
+ },
395
+ "write": {
396
+ "type": "array",
397
+ "items": { "type": "string" },
398
+ "description": "Roles that can write this field. If omitted, writable by anyone with entity write access."
399
+ }
400
+ }
401
+ }
402
+ },
403
+ "allOf": [
404
+ {
405
+ "if": {
406
+ "properties": {
407
+ "type": {
408
+ "const": "enum"
409
+ }
410
+ },
411
+ "required": [
412
+ "type"
413
+ ]
414
+ },
415
+ "then": {
416
+ "required": [
417
+ "values"
418
+ ]
419
+ }
420
+ },
421
+ {
422
+ "if": {
423
+ "properties": {
424
+ "type": {
425
+ "const": "object"
426
+ }
427
+ },
428
+ "required": [
429
+ "type"
430
+ ]
431
+ },
432
+ "then": {
433
+ "required": [
434
+ "fields"
435
+ ]
436
+ }
437
+ },
438
+ {
439
+ "if": {
440
+ "properties": {
441
+ "type": {
442
+ "const": "array"
443
+ }
444
+ },
445
+ "required": [
446
+ "type"
447
+ ]
448
+ },
449
+ "then": {
450
+ "required": [
451
+ "items"
452
+ ]
453
+ }
454
+ },
455
+ {
456
+ "if": {
457
+ "properties": {
458
+ "type": {
459
+ "const": "objectId"
460
+ }
461
+ },
462
+ "required": [
463
+ "type"
464
+ ]
465
+ },
466
+ "then": {
467
+ "properties": {
468
+ "ref": {
469
+ "type": "string"
470
+ }
471
+ }
472
+ }
473
+ },
474
+ {
475
+ "if": {
476
+ "properties": {
477
+ "type": {
478
+ "const": "objectId[]"
479
+ }
480
+ },
481
+ "required": [
482
+ "type"
483
+ ]
484
+ },
485
+ "then": {
486
+ "properties": {
487
+ "ref": {
488
+ "type": "string"
489
+ }
490
+ }
491
+ }
492
+ }
493
+ ]
494
+ }
495
+ },
496
+ "additionalProperties": false
497
+ },
498
+ "versioning": {
499
+ "type": "string",
500
+ "enum": ["full", "simple"],
501
+ "description": "Enable versioning: 'full' = complete snapshots with revert capability, 'simple' = lightweight audit log"
502
+ },
503
+ "filters": {
504
+ "type": "array",
505
+ "items": {
506
+ "type": "string"
507
+ }
508
+ },
509
+ "indexes": {
510
+ "type": "array",
511
+ "items": {
512
+ "type": "object",
513
+ "required": [
514
+ "fields"
515
+ ],
516
+ "additionalProperties": false,
517
+ "properties": {
518
+ "fields": {
519
+ "type": "array",
520
+ "items": {
521
+ "type": "string"
522
+ },
523
+ "minItems": 1
524
+ },
525
+ "unique": {
526
+ "type": "boolean"
527
+ },
528
+ "sparse": {
529
+ "type": "boolean"
530
+ },
531
+ "name": {
532
+ "type": "string"
533
+ }
534
+ }
535
+ }
536
+ },
537
+ "virtualFilters": {
538
+ "type": "object",
539
+ "patternProperties": {
540
+ "^[a-zA-Z_][a-zA-Z0-9_]*$": {
541
+ "type": "object",
542
+ "required": [
543
+ "type"
544
+ ],
545
+ "additionalProperties": false,
546
+ "properties": {
547
+ "type": {
548
+ "type": "string",
549
+ "enum": [
550
+ "string",
551
+ "int",
552
+ "float",
553
+ "boolean",
554
+ "any",
555
+ "url",
556
+ "isoDate",
557
+ "objectId",
558
+ "enum",
559
+ "object",
560
+ "string[]",
561
+ "int[]",
562
+ "float[]",
563
+ "boolean[]",
564
+ "objectId[]",
565
+ "url[]",
566
+ "array",
567
+ "secretKey",
568
+ "encryptedKey"
569
+ ]
570
+ },
571
+ "default": {}
572
+ }
573
+ }
574
+ },
575
+ "additionalProperties": false
576
+ }
577
+ }
578
+ }
579
+ },
580
+ "additionalProperties": false
581
+ }
582
+ },
583
+ "definitions": {
584
+ "field": {
585
+ "type": "object",
586
+ "required": [
587
+ "type"
588
+ ],
589
+ "additionalProperties": false,
590
+ "properties": {
591
+ "type": {
592
+ "type": "string",
593
+ "enum": [
594
+ "string",
595
+ "int",
596
+ "float",
597
+ "boolean",
598
+ "any",
599
+ "url",
600
+ "isoDate",
601
+ "objectId",
602
+ "enum",
603
+ "object",
604
+ "string[]",
605
+ "int[]",
606
+ "float[]",
607
+ "boolean[]",
608
+ "objectId[]",
609
+ "array"
610
+ ]
611
+ },
612
+ "required": {
613
+ "type": "boolean"
614
+ },
615
+ "optional": {
616
+ "type": "boolean"
617
+ },
618
+ "unique": {
619
+ "type": "boolean"
620
+ },
621
+ "index": {
622
+ "type": "boolean"
623
+ },
624
+ "default": {},
625
+ "allowedMacros": {
626
+ "type": "array",
627
+ "items": {
628
+ "type": "string",
629
+ "enum": [
630
+ "UUID",
631
+ "NOW",
632
+ "TIMESTAMP",
633
+ "TODAY",
634
+ "USER_ID"
635
+ ]
636
+ }
637
+ },
638
+ "values": {
639
+ "type": "array",
640
+ "items": {
641
+ "oneOf": [
642
+ {
643
+ "type": "string",
644
+ "description": "Legacy simple enum format"
645
+ },
646
+ {
647
+ "type": "object",
648
+ "description": "Enhanced enum format with key-label pairs",
649
+ "required": ["key"],
650
+ "additionalProperties": false,
651
+ "properties": {
652
+ "key": {
653
+ "type": "string"
654
+ },
655
+ "label": {
656
+ "type": "string"
657
+ }
658
+ }
659
+ }
660
+ ]
661
+ }
662
+ },
663
+ "search": {
664
+ "type": "boolean"
665
+ },
666
+ "ref": {
667
+ "type": "string"
668
+ },
669
+ "label": {
670
+ "type": "string"
671
+ },
672
+ "description": {
673
+ "type": "string"
674
+ },
675
+ "fields": {
676
+ "type": "object",
677
+ "patternProperties": {
678
+ "^[a-zA-Z_][a-zA-Z0-9_]*$": {
679
+ "$ref": "#/definitions/field"
680
+ }
681
+ },
682
+ "additionalProperties": false
683
+ },
684
+ "items": {
685
+ "$ref": "#/definitions/field"
686
+ },
687
+ "internal": {
688
+ "type": "boolean",
689
+ "default": false
690
+ },
691
+ "select": {
692
+ "type": "boolean",
693
+ "default": true
694
+ },
695
+ "secret": {
696
+ "type": "string",
697
+ "enum": [
698
+ "hash",
699
+ "encrypt"
700
+ ]
701
+ },
702
+ "hash": {
703
+ "type": "object",
704
+ "properties": {
705
+ "algo": {
706
+ "type": "string",
707
+ "enum": [
708
+ "argon2id",
709
+ "bcrypt"
710
+ ],
711
+ "default": "argon2id"
712
+ },
713
+ "params": {
714
+ "type": "object",
715
+ "additionalProperties": true
716
+ }
717
+ },
718
+ "required": [
719
+ "algo"
720
+ ],
721
+ "additionalProperties": true
722
+ },
723
+ "expose": {
724
+ "type": "object",
725
+ "properties": {
726
+ "contracts": {
727
+ "type": "boolean"
728
+ },
729
+ "create": {
730
+ "type": "boolean"
731
+ },
732
+ "update": {
733
+ "type": "boolean"
734
+ },
735
+ "read": {
736
+ "type": "boolean"
737
+ }
738
+ },
739
+ "additionalProperties": false
740
+ },
741
+ "access": {
742
+ "type": "object",
743
+ "description": "Field-level access control. Restricts which roles can read or write this field.",
744
+ "additionalProperties": false,
745
+ "properties": {
746
+ "read": {
747
+ "type": "array",
748
+ "items": { "type": "string" },
749
+ "description": "Roles that can read this field. If omitted, visible to anyone with entity access."
750
+ },
751
+ "write": {
752
+ "type": "array",
753
+ "items": { "type": "string" },
754
+ "description": "Roles that can write this field. If omitted, writable by anyone with entity write access."
755
+ }
756
+ }
757
+ }
758
+ }
759
+ }
760
+ }
761
+ }