@vertesia/common 1.5.0-dev.20260717.131047Z → 1.5.0-dev.20260725.083715Z

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 (123) hide show
  1. package/lib/apps.d.ts +184 -48
  2. package/lib/apps.d.ts.map +1 -1
  3. package/lib/apps.js +21 -9
  4. package/lib/apps.js.map +1 -1
  5. package/lib/audit-trail.d.ts +61 -1
  6. package/lib/audit-trail.d.ts.map +1 -1
  7. package/lib/audit-trail.js +15 -0
  8. package/lib/audit-trail.js.map +1 -1
  9. package/lib/environment.d.ts +2 -0
  10. package/lib/environment.d.ts.map +1 -1
  11. package/lib/environment.js.map +1 -1
  12. package/lib/index.d.ts +7 -0
  13. package/lib/index.d.ts.map +1 -1
  14. package/lib/index.js +7 -0
  15. package/lib/index.js.map +1 -1
  16. package/lib/interaction.d.ts +77 -1
  17. package/lib/interaction.d.ts.map +1 -1
  18. package/lib/interaction.js +48 -0
  19. package/lib/interaction.js.map +1 -1
  20. package/lib/platform-event.d.ts +37 -3
  21. package/lib/platform-event.d.ts.map +1 -1
  22. package/lib/platform-event.js.map +1 -1
  23. package/lib/project.d.ts +119 -20
  24. package/lib/project.d.ts.map +1 -1
  25. package/lib/project.js +65 -0
  26. package/lib/project.js.map +1 -1
  27. package/lib/query.d.ts +6 -0
  28. package/lib/query.d.ts.map +1 -1
  29. package/lib/refs.d.ts +1 -0
  30. package/lib/refs.d.ts.map +1 -1
  31. package/lib/schema-for-extraction.d.ts +21 -0
  32. package/lib/schema-for-extraction.d.ts.map +1 -0
  33. package/lib/schema-for-extraction.js +205 -0
  34. package/lib/schema-for-extraction.js.map +1 -0
  35. package/lib/store/agent-run.d.ts +23 -1
  36. package/lib/store/agent-run.d.ts.map +1 -1
  37. package/lib/store/conversation-state.d.ts +3 -1
  38. package/lib/store/conversation-state.d.ts.map +1 -1
  39. package/lib/store/conversation-state.js.map +1 -1
  40. package/lib/store/doc-analyzer.d.ts +10 -67
  41. package/lib/store/doc-analyzer.d.ts.map +1 -1
  42. package/lib/store/dsl-workflow.d.ts +1 -0
  43. package/lib/store/dsl-workflow.d.ts.map +1 -1
  44. package/lib/store/dsl-workflow.js.map +1 -1
  45. package/lib/store/grounded-extraction.d.ts +146 -0
  46. package/lib/store/grounded-extraction.d.ts.map +1 -0
  47. package/lib/store/grounded-extraction.js +8 -0
  48. package/lib/store/grounded-extraction.js.map +1 -0
  49. package/lib/store/index.d.ts +1 -0
  50. package/lib/store/index.d.ts.map +1 -1
  51. package/lib/store/index.js +1 -0
  52. package/lib/store/index.js.map +1 -1
  53. package/lib/store/store.d.ts +314 -1
  54. package/lib/store/store.d.ts.map +1 -1
  55. package/lib/store/store.js +451 -0
  56. package/lib/store/store.js.map +1 -1
  57. package/lib/store/workflow.d.ts +8 -1
  58. package/lib/store/workflow.d.ts.map +1 -1
  59. package/lib/store/workflow.js +5 -0
  60. package/lib/store/workflow.js.map +1 -1
  61. package/lib/user.d.ts +14 -0
  62. package/lib/user.d.ts.map +1 -1
  63. package/lib/user.js +31 -0
  64. package/lib/user.js.map +1 -1
  65. package/lib/vertesia-common.js +2 -2
  66. package/lib/vertesia-common.js.map +1 -1
  67. package/lib/view-configuration-validation.d.ts +15 -0
  68. package/lib/view-configuration-validation.d.ts.map +1 -0
  69. package/lib/view-configuration-validation.js +63 -0
  70. package/lib/view-configuration-validation.js.map +1 -0
  71. package/lib/view-query-validation.d.ts +13 -0
  72. package/lib/view-query-validation.d.ts.map +1 -0
  73. package/lib/view-query-validation.js +266 -0
  74. package/lib/view-query-validation.js.map +1 -0
  75. package/lib/view-validation-helpers.d.ts +15 -0
  76. package/lib/view-validation-helpers.d.ts.map +1 -0
  77. package/lib/view-validation-helpers.js +25 -0
  78. package/lib/view-validation-helpers.js.map +1 -0
  79. package/lib/views-schema.d.ts +1992 -0
  80. package/lib/views-schema.d.ts.map +1 -0
  81. package/lib/views-schema.js +674 -0
  82. package/lib/views-schema.js.map +1 -0
  83. package/lib/views-validation.d.ts +21 -0
  84. package/lib/views-validation.d.ts.map +1 -0
  85. package/lib/views-validation.js +164 -0
  86. package/lib/views-validation.js.map +1 -0
  87. package/lib/views.d.ts +381 -0
  88. package/lib/views.d.ts.map +1 -0
  89. package/lib/views.js +41 -0
  90. package/lib/views.js.map +1 -0
  91. package/package.json +5 -5
  92. package/src/agent-resources.test.ts +100 -0
  93. package/src/apps.test.ts +9 -1
  94. package/src/apps.ts +220 -73
  95. package/src/audit-trail.ts +83 -0
  96. package/src/environment.ts +2 -0
  97. package/src/index.ts +12 -0
  98. package/src/interaction.ts +135 -1
  99. package/src/platform-event.ts +39 -2
  100. package/src/project.test.ts +44 -0
  101. package/src/project.ts +205 -22
  102. package/src/query.ts +6 -0
  103. package/src/refs.ts +1 -0
  104. package/src/schema-for-extraction.test.ts +191 -0
  105. package/src/schema-for-extraction.ts +231 -0
  106. package/src/store/agent-run.ts +29 -0
  107. package/src/store/content-type-editing.test.ts +17 -0
  108. package/src/store/conversation-state.ts +4 -1
  109. package/src/store/doc-analyzer.ts +10 -76
  110. package/src/store/dsl-workflow.ts +1 -0
  111. package/src/store/grounded-extraction.ts +154 -0
  112. package/src/store/index.ts +1 -0
  113. package/src/store/store.ts +800 -1
  114. package/src/store/workflow.ts +12 -0
  115. package/src/user.ts +46 -0
  116. package/src/view-configuration-validation.ts +74 -0
  117. package/src/view-query-validation.test.ts +21 -0
  118. package/src/view-query-validation.ts +319 -0
  119. package/src/view-validation-helpers.ts +28 -0
  120. package/src/views-schema.test.ts +364 -0
  121. package/src/views-schema.ts +689 -0
  122. package/src/views-validation.ts +234 -0
  123. package/src/views.ts +484 -0
@@ -0,0 +1,689 @@
1
+ import type { JSONSchema } from './json-schema.js';
2
+ import {
3
+ ELASTICSEARCH_FIELD_PATH_PATTERN_SOURCE,
4
+ VIEW_CONFIGURATION_ID_PATTERN_SOURCE,
5
+ } from './view-validation-helpers.js';
6
+ import { VIEW_RESULT_FIELD_FORMATS, VIEW_SEARCH_FIELD_TYPES } from './views.js';
7
+
8
+ export const VIEW_EXPERIENCE_CONFIGURATION_JSON_SCHEMA_ID =
9
+ 'https://schemas.vertesia.com/view-experience.v1.schema.json';
10
+ export const PERSISTED_VIEW_EXPERIENCE_CONFIGURATION_JSON_SCHEMA_ID =
11
+ 'https://schemas.vertesia.com/persisted-view-experience.v1.schema.json';
12
+
13
+ /**
14
+ * Canonical structural schema for reusable inline and app-contributed View configuration.
15
+ *
16
+ * Cross-reference rules such as unique navigation ids and valid default display
17
+ * references are enforced by validateViewConfiguration().
18
+ */
19
+ export const ViewExperienceConfigurationJsonSchema = {
20
+ $id: VIEW_EXPERIENCE_CONFIGURATION_JSON_SCHEMA_ID,
21
+ type: 'object',
22
+ title: 'View Experience',
23
+ description:
24
+ 'A reusable content navigation and search experience. Save it through /api/v1/views, then render it at /view/<id>.',
25
+ properties: {
26
+ name: {
27
+ type: 'string',
28
+ minLength: 1,
29
+ maxLength: 120,
30
+ description: 'Human-readable View name.',
31
+ },
32
+ description: {
33
+ type: 'string',
34
+ maxLength: 4000,
35
+ description: 'Purpose and intended audience of this View.',
36
+ },
37
+ enabled: {
38
+ type: 'boolean',
39
+ description: 'Whether the View may be executed.',
40
+ },
41
+ layout: {
42
+ $ref: '#/$defs/layout',
43
+ },
44
+ scope: {
45
+ $ref: '#/$defs/scope',
46
+ },
47
+ navigation: {
48
+ type: 'array',
49
+ maxItems: 20,
50
+ description: 'Ordered facets or hierarchies used to browse the scoped content.',
51
+ items: {
52
+ oneOf: [
53
+ { $ref: '#/$defs/locationNavigation' },
54
+ { $ref: '#/$defs/collectionNavigation' },
55
+ { $ref: '#/$defs/termsNavigation' },
56
+ { $ref: '#/$defs/hierarchyNavigation' },
57
+ { $ref: '#/$defs/rangeNavigation' },
58
+ ],
59
+ },
60
+ },
61
+ search: {
62
+ $ref: '#/$defs/search',
63
+ },
64
+ results: {
65
+ $ref: '#/$defs/results',
66
+ },
67
+ },
68
+ required: ['name'],
69
+ additionalProperties: false,
70
+ $defs: {
71
+ configurationId: {
72
+ type: 'string',
73
+ minLength: 1,
74
+ maxLength: 64,
75
+ pattern: VIEW_CONFIGURATION_ID_PATTERN_SOURCE,
76
+ description: 'Stable id starting with a letter and containing letters, numbers, underscores, or hyphens.',
77
+ },
78
+ fieldName: {
79
+ type: 'string',
80
+ minLength: 1,
81
+ maxLength: 160,
82
+ pattern: ELASTICSEARCH_FIELD_PATH_PATTERN_SOURCE,
83
+ description: 'Dot-separated Elasticsearch field name.',
84
+ },
85
+ stringArray: {
86
+ type: 'array',
87
+ maxItems: 100,
88
+ items: {
89
+ type: 'string',
90
+ minLength: 1,
91
+ },
92
+ },
93
+ layout: {
94
+ type: 'object',
95
+ description: 'Overall browsing layout.',
96
+ properties: {
97
+ mode: {
98
+ type: 'string',
99
+ enum: ['browse', 'worklist'],
100
+ description: 'Browse emphasizes discovery; worklist emphasizes case-style task handling.',
101
+ },
102
+ navigation_position: {
103
+ type: 'string',
104
+ enum: ['sidebar', 'top'],
105
+ description: 'Where navigation widgets appear.',
106
+ },
107
+ },
108
+ required: [],
109
+ additionalProperties: false,
110
+ },
111
+ scope: {
112
+ type: 'object',
113
+ description: 'Hard boundary applied to every search and navigation query.',
114
+ properties: {
115
+ type_ids: {
116
+ $ref: '#/$defs/stringArray',
117
+ description: 'Content type ids included in the View.',
118
+ },
119
+ locations: {
120
+ $ref: '#/$defs/stringArray',
121
+ description: 'Absolute content location roots included in the View.',
122
+ },
123
+ collection_ids: {
124
+ $ref: '#/$defs/stringArray',
125
+ description: 'Collection ids included in the View.',
126
+ },
127
+ include_collection_descendants: {
128
+ type: 'boolean',
129
+ description: 'Include descendants of scoped collections.',
130
+ },
131
+ fixed_filter: {
132
+ type: 'object',
133
+ description:
134
+ 'Elasticsearch query clause always applied by the runtime. Script-like and unsafe clauses are rejected.',
135
+ required: [],
136
+ additionalProperties: true,
137
+ },
138
+ head_only: {
139
+ type: 'boolean',
140
+ description: 'Return only current head revisions.',
141
+ },
142
+ },
143
+ required: [],
144
+ additionalProperties: false,
145
+ },
146
+ locationNavigation: {
147
+ type: 'object',
148
+ title: 'Location hierarchy',
149
+ description: 'Browse the hierarchical content location path.',
150
+ properties: {
151
+ id: { $ref: '#/$defs/configurationId' },
152
+ label: { type: 'string', minLength: 1, maxLength: 120 },
153
+ source: { const: 'location' },
154
+ presentation: { type: 'string', enum: ['tree', 'list', 'select', 'chips'] },
155
+ multi_select: { type: 'boolean' },
156
+ order: { type: 'integer' },
157
+ renderer: { type: 'string', minLength: 1, maxLength: 120 },
158
+ roots: {
159
+ type: 'array',
160
+ maxItems: 50,
161
+ items: { type: 'string', pattern: '^/' },
162
+ description: 'Absolute location roots shown by the hierarchy.',
163
+ },
164
+ depth: {
165
+ type: 'integer',
166
+ minimum: 1,
167
+ maximum: 20,
168
+ },
169
+ },
170
+ required: ['id', 'label', 'source'],
171
+ additionalProperties: false,
172
+ },
173
+ collectionNavigation: {
174
+ type: 'object',
175
+ title: 'Collection hierarchy',
176
+ description: 'Browse collection membership and optionally collection descendants.',
177
+ properties: {
178
+ id: { $ref: '#/$defs/configurationId' },
179
+ label: { type: 'string', minLength: 1, maxLength: 120 },
180
+ source: { const: 'collection' },
181
+ presentation: { type: 'string', enum: ['tree', 'list', 'select', 'chips'] },
182
+ multi_select: { type: 'boolean' },
183
+ order: { type: 'integer' },
184
+ renderer: { type: 'string', minLength: 1, maxLength: 120 },
185
+ roots: {
186
+ type: 'array',
187
+ maxItems: 50,
188
+ items: { type: 'string', minLength: 1 },
189
+ },
190
+ include_descendants: {
191
+ type: 'boolean',
192
+ },
193
+ },
194
+ required: ['id', 'label', 'source'],
195
+ additionalProperties: false,
196
+ },
197
+ termsNavigation: {
198
+ type: 'object',
199
+ title: 'Property facet',
200
+ description: 'Bucket a keyword-like property such as brand.',
201
+ properties: {
202
+ id: { $ref: '#/$defs/configurationId' },
203
+ label: { type: 'string', minLength: 1, maxLength: 120 },
204
+ source: { const: 'terms' },
205
+ presentation: { type: 'string', enum: ['tree', 'list', 'select', 'chips'] },
206
+ multi_select: { type: 'boolean' },
207
+ order: { type: 'integer' },
208
+ renderer: { type: 'string', minLength: 1, maxLength: 120 },
209
+ field: { $ref: '#/$defs/fieldName' },
210
+ size: {
211
+ type: 'integer',
212
+ minimum: 1,
213
+ maximum: 500,
214
+ },
215
+ sort: {
216
+ type: 'string',
217
+ enum: ['count', 'label'],
218
+ },
219
+ },
220
+ required: ['id', 'label', 'source', 'field'],
221
+ additionalProperties: false,
222
+ },
223
+ hierarchyLevel: {
224
+ type: 'object',
225
+ title: 'Property hierarchy level',
226
+ description: 'One mapped property in a drill-down hierarchy.',
227
+ properties: {
228
+ id: { $ref: '#/$defs/configurationId' },
229
+ label: { type: 'string', minLength: 1, maxLength: 120 },
230
+ field: { $ref: '#/$defs/fieldName' },
231
+ size: {
232
+ type: 'integer',
233
+ minimum: 1,
234
+ maximum: 500,
235
+ },
236
+ sort: {
237
+ type: 'string',
238
+ enum: ['count', 'label'],
239
+ },
240
+ },
241
+ required: ['id', 'label', 'field'],
242
+ additionalProperties: false,
243
+ },
244
+ hierarchyNavigation: {
245
+ type: 'object',
246
+ title: 'Property hierarchy',
247
+ description: 'Drill down through mapped properties such as State, then City.',
248
+ properties: {
249
+ id: { $ref: '#/$defs/configurationId' },
250
+ label: { type: 'string', minLength: 1, maxLength: 120 },
251
+ source: { const: 'hierarchy' },
252
+ presentation: { type: 'string', enum: ['tree', 'list', 'select', 'chips'] },
253
+ multi_select: { const: false },
254
+ order: { type: 'integer' },
255
+ renderer: { type: 'string', minLength: 1, maxLength: 120 },
256
+ levels: {
257
+ type: 'array',
258
+ minItems: 2,
259
+ maxItems: 10,
260
+ items: { $ref: '#/$defs/hierarchyLevel' },
261
+ },
262
+ },
263
+ required: ['id', 'label', 'source', 'levels'],
264
+ additionalProperties: false,
265
+ },
266
+ rangeDefinition: {
267
+ type: 'object',
268
+ properties: {
269
+ id: { $ref: '#/$defs/configurationId' },
270
+ label: { type: 'string', minLength: 1, maxLength: 120 },
271
+ from: { type: 'number' },
272
+ to: { type: 'number' },
273
+ },
274
+ required: ['id', 'label'],
275
+ additionalProperties: false,
276
+ anyOf: [{ required: ['from'] }, { required: ['to'] }],
277
+ },
278
+ rangeNavigation: {
279
+ type: 'object',
280
+ title: 'Numeric range facet',
281
+ description: 'Bucket a numeric property such as project_size into authored ranges.',
282
+ properties: {
283
+ id: { $ref: '#/$defs/configurationId' },
284
+ label: { type: 'string', minLength: 1, maxLength: 120 },
285
+ source: { const: 'range' },
286
+ presentation: { type: 'string', enum: ['tree', 'list', 'select', 'chips'] },
287
+ multi_select: { type: 'boolean' },
288
+ order: { type: 'integer' },
289
+ renderer: { type: 'string', minLength: 1, maxLength: 120 },
290
+ field: { $ref: '#/$defs/fieldName' },
291
+ ranges: {
292
+ type: 'array',
293
+ minItems: 1,
294
+ items: { $ref: '#/$defs/rangeDefinition' },
295
+ },
296
+ },
297
+ required: ['id', 'label', 'source', 'field', 'ranges'],
298
+ additionalProperties: false,
299
+ },
300
+ keyTerm: {
301
+ type: 'object',
302
+ description: 'A URL-serializable structured search input.',
303
+ properties: {
304
+ id: { $ref: '#/$defs/configurationId' },
305
+ label: { type: 'string', minLength: 1, maxLength: 120 },
306
+ field: { $ref: '#/$defs/fieldName' },
307
+ type: {
308
+ type: 'string',
309
+ enum: [...VIEW_SEARCH_FIELD_TYPES],
310
+ },
311
+ multiple: { type: 'boolean' },
312
+ operator: {
313
+ type: 'string',
314
+ enum: ['match', 'term', 'range'],
315
+ },
316
+ },
317
+ required: ['id', 'label', 'type'],
318
+ additionalProperties: false,
319
+ },
320
+ searchField: {
321
+ type: 'object',
322
+ description:
323
+ 'A mapped Elasticsearch field available to query planning and deterministic full-text fallback.',
324
+ properties: {
325
+ field: { $ref: '#/$defs/fieldName' },
326
+ description: {
327
+ type: 'string',
328
+ minLength: 1,
329
+ maxLength: 500,
330
+ description: 'Semantic meaning of the field for query planners.',
331
+ },
332
+ type: {
333
+ type: 'string',
334
+ enum: [...VIEW_SEARCH_FIELD_TYPES],
335
+ description: 'Mapping hint used only when the active index does not expose the field type.',
336
+ },
337
+ mode: {
338
+ type: 'string',
339
+ enum: ['auto', 'full_text', 'exact'],
340
+ description:
341
+ 'Whether the field supports scoring text queries, structured exact queries, or mapping-derived behavior.',
342
+ },
343
+ boost: {
344
+ type: 'number',
345
+ minimum: 0.1,
346
+ maximum: 20,
347
+ description: 'Relative boost when the field participates in multi-field text search.',
348
+ },
349
+ },
350
+ required: ['field'],
351
+ additionalProperties: false,
352
+ },
353
+ interactionConfig: {
354
+ type: 'object',
355
+ description:
356
+ 'One execution configuration for the agentic search model. Set environment and/or model to override project defaults.',
357
+ properties: {
358
+ id: { type: 'string' },
359
+ environment: { type: 'string' },
360
+ model: { type: 'string' },
361
+ do_validate: { type: 'boolean' },
362
+ run_data: { type: 'string' },
363
+ configMode: { type: 'string' },
364
+ model_options: {
365
+ type: 'object',
366
+ required: [],
367
+ additionalProperties: true,
368
+ },
369
+ prompt_cache_key: { type: 'string' },
370
+ prompt_cache_schema_suffix: { type: 'boolean' },
371
+ http_timeout: {
372
+ type: 'object',
373
+ required: [],
374
+ additionalProperties: true,
375
+ },
376
+ },
377
+ required: [],
378
+ additionalProperties: true,
379
+ },
380
+ agenticSearch: {
381
+ type: 'object',
382
+ description:
383
+ 'Agentic query planning configuration. The default interaction is sys:ContentSearchAgent and it emits secured Elasticsearch DSL.',
384
+ properties: {
385
+ interaction: {
386
+ type: 'string',
387
+ maxLength: 200,
388
+ description: 'Interaction id. Defaults to sys:ContentSearchAgent.',
389
+ },
390
+ config: { $ref: '#/$defs/interactionConfig' },
391
+ instructions: {
392
+ type: 'string',
393
+ maxLength: 4000,
394
+ description: 'Domain-specific guidance for translating natural language into Elasticsearch DSL.',
395
+ },
396
+ mode: {
397
+ type: 'string',
398
+ enum: ['query'],
399
+ description: 'Generate and validate an Elasticsearch query before execution.',
400
+ },
401
+ timeout_ms: {
402
+ type: 'integer',
403
+ minimum: 1000,
404
+ maximum: 60000,
405
+ },
406
+ minimum_confidence: {
407
+ type: 'number',
408
+ minimum: 0,
409
+ maximum: 1,
410
+ },
411
+ },
412
+ required: [],
413
+ additionalProperties: false,
414
+ },
415
+ search: {
416
+ type: 'object',
417
+ description: 'Text and structured search configuration.',
418
+ properties: {
419
+ renderer: {
420
+ type: 'string',
421
+ maxLength: 120,
422
+ description: 'Optional app-registered search renderer name.',
423
+ },
424
+ mode: {
425
+ type: 'string',
426
+ enum: ['deterministic', 'agentic'],
427
+ },
428
+ placeholder: {
429
+ type: 'string',
430
+ maxLength: 240,
431
+ },
432
+ fields: {
433
+ type: 'array',
434
+ maxItems: 50,
435
+ items: { $ref: '#/$defs/searchField' },
436
+ description:
437
+ 'Fields disclosed to query planning. Text-capable entries also define deterministic fallback search.',
438
+ },
439
+ key_terms: {
440
+ type: 'array',
441
+ maxItems: 50,
442
+ items: { $ref: '#/$defs/keyTerm' },
443
+ },
444
+ agentic: { $ref: '#/$defs/agenticSearch' },
445
+ },
446
+ required: [],
447
+ additionalProperties: false,
448
+ },
449
+ resultField: {
450
+ type: 'object',
451
+ properties: {
452
+ field: { $ref: '#/$defs/fieldName' },
453
+ label: { type: 'string', maxLength: 120 },
454
+ format: {
455
+ type: 'string',
456
+ enum: [...VIEW_RESULT_FIELD_FORMATS],
457
+ },
458
+ fallback: { type: 'string', maxLength: 240 },
459
+ },
460
+ required: ['field'],
461
+ additionalProperties: false,
462
+ },
463
+ resultMedia: {
464
+ type: 'object',
465
+ properties: {
466
+ source: {
467
+ type: 'string',
468
+ enum: ['content_thumbnail', 'property', 'type_icon'],
469
+ },
470
+ field: { $ref: '#/$defs/fieldName' },
471
+ fit: {
472
+ type: 'string',
473
+ enum: ['cover', 'contain'],
474
+ },
475
+ fallback: {
476
+ type: 'string',
477
+ enum: ['type_icon', 'placeholder', 'none'],
478
+ },
479
+ },
480
+ required: ['source'],
481
+ additionalProperties: false,
482
+ },
483
+ resultFieldArray: {
484
+ type: 'array',
485
+ items: { $ref: '#/$defs/resultField' },
486
+ },
487
+ listDisplay: {
488
+ type: 'object',
489
+ properties: {
490
+ id: { $ref: '#/$defs/configurationId' },
491
+ label: { type: 'string', minLength: 1, maxLength: 120 },
492
+ renderer: { type: 'string', minLength: 1, maxLength: 120 },
493
+ page_size: { type: 'integer', minimum: 1, maximum: 200 },
494
+ type: { const: 'list' },
495
+ title: { $ref: '#/$defs/resultField' },
496
+ subtitle: { $ref: '#/$defs/resultFieldArray' },
497
+ description: { $ref: '#/$defs/resultField' },
498
+ media: { $ref: '#/$defs/resultMedia' },
499
+ badges: { $ref: '#/$defs/resultFieldArray' },
500
+ },
501
+ required: ['id', 'label', 'type', 'title'],
502
+ additionalProperties: false,
503
+ },
504
+ tableColumn: {
505
+ type: 'object',
506
+ properties: {
507
+ field: { $ref: '#/$defs/fieldName' },
508
+ label: { type: 'string', maxLength: 120 },
509
+ format: {
510
+ type: 'string',
511
+ enum: [...VIEW_RESULT_FIELD_FORMATS],
512
+ },
513
+ fallback: { type: 'string', maxLength: 240 },
514
+ width: { type: 'integer', minimum: 40, maximum: 2000 },
515
+ sortable: { type: 'boolean' },
516
+ sort_option: { $ref: '#/$defs/configurationId' },
517
+ },
518
+ required: ['field'],
519
+ additionalProperties: false,
520
+ },
521
+ tableDisplay: {
522
+ type: 'object',
523
+ properties: {
524
+ id: { $ref: '#/$defs/configurationId' },
525
+ label: { type: 'string', minLength: 1, maxLength: 120 },
526
+ renderer: { type: 'string', minLength: 1, maxLength: 120 },
527
+ page_size: { type: 'integer', minimum: 1, maximum: 200 },
528
+ type: { const: 'table' },
529
+ columns: {
530
+ type: 'array',
531
+ minItems: 1,
532
+ items: { $ref: '#/$defs/tableColumn' },
533
+ },
534
+ },
535
+ required: ['id', 'label', 'type', 'columns'],
536
+ additionalProperties: false,
537
+ },
538
+ cardsDisplay: {
539
+ type: 'object',
540
+ properties: {
541
+ id: { $ref: '#/$defs/configurationId' },
542
+ label: { type: 'string', minLength: 1, maxLength: 120 },
543
+ renderer: { type: 'string', minLength: 1, maxLength: 120 },
544
+ page_size: { type: 'integer', minimum: 1, maximum: 200 },
545
+ type: { const: 'cards' },
546
+ title: { $ref: '#/$defs/resultField' },
547
+ description: { $ref: '#/$defs/resultField' },
548
+ media: { $ref: '#/$defs/resultMedia' },
549
+ fields: { $ref: '#/$defs/resultFieldArray' },
550
+ badges: { $ref: '#/$defs/resultFieldArray' },
551
+ columns: { type: 'integer', enum: [2, 3, 4, 5, 6] },
552
+ },
553
+ required: ['id', 'label', 'type', 'title'],
554
+ additionalProperties: false,
555
+ },
556
+ galleryDisplay: {
557
+ type: 'object',
558
+ properties: {
559
+ id: { $ref: '#/$defs/configurationId' },
560
+ label: { type: 'string', minLength: 1, maxLength: 120 },
561
+ renderer: { type: 'string', minLength: 1, maxLength: 120 },
562
+ page_size: { type: 'integer', minimum: 1, maximum: 200 },
563
+ type: { const: 'gallery' },
564
+ media: { $ref: '#/$defs/resultMedia' },
565
+ title: { $ref: '#/$defs/resultField' },
566
+ caption: { $ref: '#/$defs/resultFieldArray' },
567
+ columns: { type: 'integer', enum: [2, 3, 4, 5, 6] },
568
+ },
569
+ required: ['id', 'label', 'type', 'media', 'title'],
570
+ additionalProperties: false,
571
+ },
572
+ boardCard: {
573
+ type: 'object',
574
+ properties: {
575
+ title: { $ref: '#/$defs/resultField' },
576
+ description: { $ref: '#/$defs/resultField' },
577
+ media: { $ref: '#/$defs/resultMedia' },
578
+ fields: { $ref: '#/$defs/resultFieldArray' },
579
+ badges: { $ref: '#/$defs/resultFieldArray' },
580
+ },
581
+ required: ['title'],
582
+ additionalProperties: false,
583
+ },
584
+ boardColumn: {
585
+ type: 'object',
586
+ properties: {
587
+ value: { type: 'string', minLength: 1 },
588
+ label: { type: 'string', minLength: 1, maxLength: 120 },
589
+ order: { type: 'integer' },
590
+ },
591
+ required: ['value', 'label'],
592
+ additionalProperties: false,
593
+ },
594
+ boardDisplay: {
595
+ type: 'object',
596
+ properties: {
597
+ id: { $ref: '#/$defs/configurationId' },
598
+ label: { type: 'string', minLength: 1, maxLength: 120 },
599
+ renderer: { type: 'string', minLength: 1, maxLength: 120 },
600
+ page_size: { type: 'integer', minimum: 1, maximum: 200 },
601
+ type: { const: 'board' },
602
+ group_by: { $ref: '#/$defs/fieldName' },
603
+ columns: {
604
+ type: 'array',
605
+ items: { $ref: '#/$defs/boardColumn' },
606
+ },
607
+ card: { $ref: '#/$defs/boardCard' },
608
+ },
609
+ required: ['id', 'label', 'type', 'group_by', 'card'],
610
+ additionalProperties: false,
611
+ },
612
+ display: {
613
+ oneOf: [
614
+ { $ref: '#/$defs/listDisplay' },
615
+ { $ref: '#/$defs/tableDisplay' },
616
+ { $ref: '#/$defs/cardsDisplay' },
617
+ { $ref: '#/$defs/galleryDisplay' },
618
+ { $ref: '#/$defs/boardDisplay' },
619
+ ],
620
+ },
621
+ sortClause: {
622
+ type: 'object',
623
+ properties: {
624
+ field: { $ref: '#/$defs/fieldName' },
625
+ order: {
626
+ type: 'string',
627
+ enum: ['asc', 'desc'],
628
+ },
629
+ },
630
+ required: ['field', 'order'],
631
+ additionalProperties: false,
632
+ },
633
+ sortOption: {
634
+ type: 'object',
635
+ properties: {
636
+ id: { $ref: '#/$defs/configurationId' },
637
+ label: { type: 'string', minLength: 1, maxLength: 120 },
638
+ sort: {
639
+ type: 'array',
640
+ minItems: 1,
641
+ items: { $ref: '#/$defs/sortClause' },
642
+ },
643
+ },
644
+ required: ['id', 'label', 'sort'],
645
+ additionalProperties: false,
646
+ },
647
+ results: {
648
+ type: 'object',
649
+ description: 'Built-in or app-rendered visual result layouts.',
650
+ properties: {
651
+ default_display: { $ref: '#/$defs/configurationId' },
652
+ allow_display_switch: { type: 'boolean' },
653
+ displays: {
654
+ type: 'array',
655
+ minItems: 1,
656
+ maxItems: 10,
657
+ items: { $ref: '#/$defs/display' },
658
+ },
659
+ default_sort: { $ref: '#/$defs/configurationId' },
660
+ sort_options: {
661
+ type: 'array',
662
+ items: { $ref: '#/$defs/sortOption' },
663
+ },
664
+ },
665
+ required: ['default_display', 'displays'],
666
+ additionalProperties: false,
667
+ },
668
+ },
669
+ } satisfies JSONSchema;
670
+
671
+ /**
672
+ * Structural schema for project-scoped Views saved through the Views API.
673
+ *
674
+ * App-contributed and inline View definitions use the reusable base schema,
675
+ * while persisted resources additionally document their purpose.
676
+ */
677
+ export const PersistedViewExperienceConfigurationJsonSchema = {
678
+ ...ViewExperienceConfigurationJsonSchema,
679
+ $id: PERSISTED_VIEW_EXPERIENCE_CONFIGURATION_JSON_SCHEMA_ID,
680
+ title: 'Persisted View Experience',
681
+ properties: {
682
+ ...ViewExperienceConfigurationJsonSchema.properties,
683
+ description: {
684
+ ...ViewExperienceConfigurationJsonSchema.properties.description,
685
+ minLength: 1,
686
+ },
687
+ },
688
+ required: ['name', 'description'],
689
+ } satisfies JSONSchema;