@defra/forms-model 3.0.431 → 3.0.433

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 (70) hide show
  1. package/dist/module/form/form-definition/index.js +2 -1
  2. package/dist/module/form/form-definition/index.js.map +1 -1
  3. package/dist/module/form/form-definition/types.js.map +1 -1
  4. package/dist/module/form/form-editor/index.js +107 -0
  5. package/dist/module/form/form-editor/index.js.map +1 -1
  6. package/dist/module/form/form-editor/types.js.map +1 -1
  7. package/dist/module/form/form-manager/index.js +1 -1
  8. package/dist/module/form/form-manager/index.js.map +1 -1
  9. package/dist/types/form/form-definition/index.d.ts.map +1 -1
  10. package/dist/types/form/form-definition/types.d.ts +1 -0
  11. package/dist/types/form/form-definition/types.d.ts.map +1 -1
  12. package/dist/types/form/form-editor/index.d.ts +21 -1
  13. package/dist/types/form/form-editor/index.d.ts.map +1 -1
  14. package/dist/types/form/form-editor/types.d.ts +8 -2
  15. package/dist/types/form/form-editor/types.d.ts.map +1 -1
  16. package/dist/types/form/form-manager/index.d.ts +1 -1
  17. package/dist/types/form/form-manager/index.d.ts.map +1 -1
  18. package/package.json +1 -1
  19. package/schemas/component-schema-v2.json +162 -0
  20. package/schemas/component-schema.json +162 -0
  21. package/schemas/date-sub-schema.json +11 -0
  22. package/schemas/form-definition-schema.json +1886 -0
  23. package/schemas/form-definition-v2-payload-schema.json +1469 -0
  24. package/schemas/form-editor-input-check-answers-setting-schema.json +18 -0
  25. package/schemas/form-editor-input-page-schema.json +41 -0
  26. package/schemas/form-editor-input-page-settings-schema.json +28 -0
  27. package/schemas/form-editor-input-question-schema.json +38 -0
  28. package/schemas/form-metadata-author-schema.json +24 -0
  29. package/schemas/form-metadata-contact-schema.json +61 -0
  30. package/schemas/form-metadata-email-schema.json +25 -0
  31. package/schemas/form-metadata-input-schema.json +127 -0
  32. package/schemas/form-metadata-online-schema.json +25 -0
  33. package/schemas/form-metadata-schema.json +340 -0
  34. package/schemas/form-metadata-state-schema.json +72 -0
  35. package/schemas/form-submit-payload-schema.json +124 -0
  36. package/schemas/form-submit-record-schema.json +30 -0
  37. package/schemas/form-submit-recordset-schema.json +62 -0
  38. package/schemas/list-schema-v2.json +496 -0
  39. package/schemas/list-schema.json +496 -0
  40. package/schemas/max-future-schema.json +8 -0
  41. package/schemas/max-length-schema.json +8 -0
  42. package/schemas/max-past-schema.json +8 -0
  43. package/schemas/max-schema.json +7 -0
  44. package/schemas/min-length-schema.json +8 -0
  45. package/schemas/min-schema.json +7 -0
  46. package/schemas/page-schema-payload-v2.json +400 -0
  47. package/schemas/page-schema-v2.json +400 -0
  48. package/schemas/page-schema.json +400 -0
  49. package/schemas/page-type-schema.json +11 -0
  50. package/schemas/pagination-options-schema.json +27 -0
  51. package/schemas/patch-page-schema.json +26 -0
  52. package/schemas/query-options-schema.json +94 -0
  53. package/schemas/question-schema.json +7 -0
  54. package/schemas/question-type-full-schema.json +22 -0
  55. package/schemas/question-type-schema.json +20 -0
  56. package/schemas/search-options-schema.json +59 -0
  57. package/schemas/sorting-options-schema.json +28 -0
  58. package/schemas/written-answer-sub-schema.json +12 -0
  59. package/src/form/form-definition/index.ts +5 -1
  60. package/src/form/form-definition/types.ts +1 -0
  61. package/src/form/form-editor/index.ts +147 -1
  62. package/src/form/form-editor/types.ts +19 -2
  63. package/src/form/form-manager/index.ts +1 -1
  64. package/scripts/generate-schemas.js +0 -238
  65. package/scripts/schema-modules/constants.js +0 -39
  66. package/scripts/schema-modules/schema-processors.js +0 -109
  67. package/scripts/schema-modules/schema-simplifiers.js +0 -351
  68. package/scripts/schema-modules/title-processors.js +0 -327
  69. package/scripts/schema-modules/types.js +0 -21
  70. package/scripts/schema-modules/utils.js +0 -41
@@ -0,0 +1,28 @@
1
+ {
2
+ "type": "object",
3
+ "properties": {
4
+ "sortBy": {
5
+ "type": "string",
6
+ "description": "Field to sort results by",
7
+ "enum": [
8
+ "updatedAt",
9
+ "title"
10
+ ],
11
+ "title": "Sort By"
12
+ },
13
+ "order": {
14
+ "type": "string",
15
+ "description": "Sort order (ascending or descending)",
16
+ "enum": [
17
+ "asc",
18
+ "desc"
19
+ ],
20
+ "title": "Order"
21
+ }
22
+ },
23
+ "additionalProperties": false,
24
+ "$schema": "http://json-schema.org/draft-07/schema#",
25
+ "title": "Sorting Options Schema",
26
+ "description": "JSON Schema for validating Sorting Options Schema in Defra forms",
27
+ "$id": "@defra/forms-model/schemas/sorting-options-schema.json"
28
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "type": "string",
3
+ "description": "Subtype for written answer questions",
4
+ "enum": [
5
+ "TextField",
6
+ "MultilineTextField",
7
+ "NumberField"
8
+ ],
9
+ "$schema": "http://json-schema.org/draft-07/schema#",
10
+ "title": "Written Answer Sub Schema",
11
+ "$id": "@defra/forms-model/schemas/written-answer-sub-schema.json"
12
+ }
@@ -479,7 +479,11 @@ const baseListItemSchema = Joi.object<Item>()
479
479
  condition: Joi.string()
480
480
  .allow('')
481
481
  .optional()
482
- .description('Condition that determines if this item is shown')
482
+ .description('Condition that determines if this item is shown'),
483
+ hint: Joi.string()
484
+ .allow('')
485
+ .optional()
486
+ .description('Optional hint text to be shown on list item')
483
487
  })
484
488
 
485
489
  const stringListItemSchema = baseListItemSchema
@@ -124,6 +124,7 @@ export interface Item {
124
124
  description?: string
125
125
  conditional?: { components: ComponentDef[] }
126
126
  condition?: string
127
+ hint?: string
127
128
  }
128
129
 
129
130
  export interface List {
@@ -1,4 +1,4 @@
1
- import Joi from 'joi'
1
+ import Joi, { type ArraySchema, type GetRuleOptions } from 'joi'
2
2
 
3
3
  import { ComponentType } from '~/src/components/enums.js'
4
4
  import {
@@ -291,7 +291,153 @@ export const classesSchema = Joi.string()
291
291
  .allow('')
292
292
  .description('Custom CSS classes to apply to the component')
293
293
 
294
+ type GenericRuleOptions<K extends string, T> = Omit<GetRuleOptions, 'args'> & {
295
+ args: Record<K, T>
296
+ }
297
+
298
+ interface DSLSchema<TSchema = Record<string, unknown>[]>
299
+ extends ArraySchema<TSchema> {
300
+ rowSeparator: (rowSep: string | RegExp) => DSLSchema<TSchema>
301
+ row: (rowSep: string | RegExp) => DSLSchema<TSchema>
302
+ colSeparator: (colSep: string | RegExp) => DSLSchema<TSchema>
303
+ col: (colSep: string | RegExp) => DSLSchema<TSchema>
304
+ keys: (keys: string[]) => DSLSchema<TSchema>
305
+ }
306
+
307
+ interface CustomValidator extends Joi.Root {
308
+ dsv<TSchema>(): DSLSchema<TSchema>
309
+ }
310
+
311
+ export const customValidator = Joi.extend((joi: Joi.Root) => {
312
+ return {
313
+ type: 'dsv',
314
+ base: joi.array(),
315
+ messages: {
316
+ 'dsv.invalid': 'Invalid parse string'
317
+ },
318
+ coerce: {
319
+ from: 'string',
320
+ method(value: string, helpers) {
321
+ try {
322
+ // Only called when prefs.convert is true
323
+ // Rules
324
+ const rowSeparatorRule = helpers.schema.$_getRule('rowSeparator') as
325
+ | undefined
326
+ | GenericRuleOptions<'rowSeparator', string | RegExp>
327
+ const colSeparatorRule = helpers.schema.$_getRule('colSeparator') as
328
+ | undefined
329
+ | GenericRuleOptions<'colSeparator', string | RegExp>
330
+ const keysRule = helpers.schema.$_getRule('keys') as
331
+ | undefined
332
+ | GenericRuleOptions<'keys', string[]>
333
+
334
+ // Rows
335
+ const rowSeparator = rowSeparatorRule?.args.rowSeparator ?? /\r?\n/
336
+ const rows = value
337
+ .split(rowSeparator)
338
+ .map((v) => v.trim())
339
+ .filter(Boolean)
340
+
341
+ // Columns
342
+ const colSeparator = colSeparatorRule?.args.colSeparator ?? ','
343
+ const keys = keysRule?.args.keys ?? ['key', 'value']
344
+
345
+ const coercedValue = rows.map((row) => {
346
+ return row
347
+ .split(colSeparator)
348
+ .reduce<Record<string, string>>((acc, col, idx) => {
349
+ return {
350
+ ...acc,
351
+ [keys[idx]]: col.trim()
352
+ }
353
+ }, {})
354
+ })
355
+ return { value: coercedValue }
356
+ } catch (_err) {
357
+ // eslint-disable-next-line no-console
358
+ console.error(_err)
359
+ return { value, errors: [helpers.error('dsv.invalid')] }
360
+ }
361
+ }
362
+ },
363
+ rules: {
364
+ rowSeparator: {
365
+ convert: true,
366
+ alias: 'row',
367
+ method(rowSeparator: string) {
368
+ return this.$_addRule({
369
+ name: 'rowSeparator',
370
+ args: { rowSeparator }
371
+ })
372
+ },
373
+ args: [
374
+ {
375
+ name: 'rowSeparator',
376
+ ref: true,
377
+ assert: (value) =>
378
+ typeof value === 'string' || value instanceof RegExp,
379
+ message: 'must be a string or regex'
380
+ }
381
+ ]
382
+ },
383
+ colSeparator: {
384
+ convert: true,
385
+ alias: 'col',
386
+ method(colSeparator: string) {
387
+ return this.$_addRule({
388
+ name: 'colSeparator',
389
+ args: { colSeparator }
390
+ })
391
+ },
392
+ args: [
393
+ {
394
+ name: 'colSeparator',
395
+ ref: true,
396
+ assert: (value) =>
397
+ typeof value === 'string' || value instanceof RegExp,
398
+ message: 'must be a string or regex'
399
+ }
400
+ ]
401
+ },
402
+ keys: {
403
+ convert: true,
404
+ method(keys: string[]) {
405
+ return this.$_addRule({ name: 'keys', args: { keys } })
406
+ },
407
+ args: [
408
+ {
409
+ name: 'keys',
410
+ ref: true,
411
+ assert: (value) =>
412
+ Array.isArray(value) && value.every((k) => typeof k === 'string'),
413
+ message: 'must be an array of strings'
414
+ }
415
+ ]
416
+ }
417
+ }
418
+ }
419
+ }) as CustomValidator
420
+
421
+ export const autoCompleteOptionsSchema = customValidator
422
+ .dsv<{ text: string; value: string }>()
423
+ .row(/\r?\n/)
424
+ .col(':')
425
+ .keys(['text', 'value'])
426
+ .items(
427
+ customValidator.object({
428
+ text: customValidator.string().min(1).disallow('').required(),
429
+ value: customValidator
430
+ .string()
431
+ .default((parent: { text: string; value?: string }) => parent.text)
432
+ .min(1)
433
+ .disallow('')
434
+ })
435
+ )
436
+ .min(1)
437
+ .required()
438
+
294
439
  export const questionDetailsFullSchema = {
440
+ autoCompleteOptionsSchema,
295
441
  classesSchema,
296
442
  documentTypesSchema,
297
443
  enhancedActionSchema,
@@ -1,4 +1,5 @@
1
1
  import { type ComponentDef } from '~/src/components/types.js'
2
+ import { type Item } from '~/src/index.js'
2
3
 
3
4
  /**
4
5
  * Interface for `FormEditor` Joi schema
@@ -203,6 +204,8 @@ export interface FormEditor {
203
204
  * The value of the radio item
204
205
  */
205
206
  radioValue: string
207
+
208
+ autoCompleteOptions: Item[]
206
209
  }
207
210
 
208
211
  export type FormEditorInputPage = Pick<
@@ -242,6 +245,7 @@ export type FormEditorInputQuestion = Pick<
242
245
  | 'documentTypes'
243
246
  | 'imageTypes'
244
247
  | 'tabularDataTypes'
248
+ | 'autoCompleteOptions'
245
249
  | 'enhancedAction'
246
250
  | 'radioId'
247
251
  | 'radioLabel'
@@ -296,9 +300,14 @@ export interface GovukField {
296
300
  fieldset?: {
297
301
  legend?: { text?: string; isPageHeading?: boolean; classes?: string }
298
302
  }
299
- value?: string | boolean | number | string[]
303
+ value?: string | boolean | number | string[] | Item[]
300
304
  classes?: string
301
- label?: { text?: string; html?: string; classes?: string }
305
+ label?: {
306
+ text?: string
307
+ html?: string
308
+ classes?: string
309
+ isPageHeading?: boolean
310
+ }
302
311
  hint?: { text?: string; html?: string; classes?: string }
303
312
  items?: { text?: string; value?: string; checked?: boolean }[]
304
313
  rows?: number
@@ -316,9 +325,17 @@ export interface FormEditorGovukField {
316
325
  imageTypes?: GovukField
317
326
  tabularDataTypes?: GovukField
318
327
  radiosOrCheckboxes?: GovukField
328
+ autoCompleteOptions?: GovukField
319
329
  errorMessage?: { text: string }
320
330
  }
321
331
 
332
+ export type FormEditorGovukFieldBase = Omit<
333
+ FormEditorGovukField,
334
+ 'errorMessage'
335
+ >
336
+
337
+ export type FormEditorGovukFieldBaseKeys = keyof FormEditorGovukFieldBase
338
+
322
339
  export interface FormEditorCheckbox {
323
340
  text?: string
324
341
  hint?: {
@@ -1,7 +1,7 @@
1
1
  import Joi from 'joi'
2
2
 
3
+ import { pageSchema } from '~/src/form/form-definition/index.js'
3
4
  import { type PatchPageFields } from '~/src/form/form-manager/types.js'
4
- import { pageSchema } from '~/src/index.js'
5
5
 
6
6
  export const patchPageSchema = Joi.object<PatchPageFields>()
7
7
  .keys({
@@ -1,238 +0,0 @@
1
- import fs from 'fs'
2
- import path from 'path'
3
- import parse from 'joi-to-json'
4
-
5
- import { schemasDir } from './schema-modules/constants.js'
6
- import { ensureDirectoryExists, toTitleCase } from './schema-modules/utils.js'
7
- import { addTitles } from './schema-modules/title-processors.js'
8
- import { simplifyForDocs } from './schema-modules/schema-simplifiers.js'
9
-
10
- /**
11
- * Cleans the schemas directory by removing all existing JSON files
12
- * @returns {number} Number of files cleaned
13
- */
14
- export function cleanSchemaDirectory() {
15
- console.log('Cleaning existing schema files...')
16
- const existingFiles = fs
17
- .readdirSync(schemasDir)
18
- .filter((file) => file.endsWith('.json'))
19
-
20
- for (const file of existingFiles) {
21
- fs.unlinkSync(path.join(schemasDir, file))
22
- }
23
-
24
- console.log(`Cleaned ${existingFiles.length} existing schema files`)
25
- return existingFiles.length
26
- }
27
-
28
- /**
29
- * Gets the schema map that defines which files should be generated
30
- * @returns {Record<string, string>} Schema map with filename-to-schema-export mapping
31
- */
32
- export function getSchemaMap() {
33
- return {
34
- // Form definition schemas
35
- 'form-definition-schema': 'formDefinitionSchema',
36
- 'form-definition-v2-payload-schema': 'formDefinitionV2PayloadSchema',
37
-
38
- // Component schemas
39
- 'component-schema': 'componentSchema',
40
- 'component-schema-v2': 'componentSchemaV2',
41
-
42
- // Page schemas
43
- 'page-schema': 'pageSchema',
44
- 'page-schema-v2': 'pageSchemaV2',
45
- 'page-schema-payload-v2': 'pageSchemaPayloadV2',
46
-
47
- // List schemas
48
- 'list-schema': 'listSchema',
49
- 'list-schema-v2': 'listSchemaV2',
50
-
51
- // Form metadata schemas
52
- 'form-metadata-schema': 'formMetadataSchema',
53
- 'form-metadata-author-schema': 'formMetadataAuthorSchema',
54
- 'form-metadata-input-schema': 'formMetadataInputSchema',
55
- 'form-metadata-state-schema': 'formMetadataStateSchema',
56
-
57
- // Form metadata field schemas
58
- 'form-metadata-contact-schema': 'contactSchema',
59
- 'form-metadata-email-schema': 'emailSchema',
60
- 'form-metadata-online-schema': 'onlineSchema',
61
-
62
- // Form editor schemas
63
- 'form-editor-input-page-schema': 'formEditorInputPageSchema',
64
- 'form-editor-input-check-answers-setting-schema':
65
- 'formEditorInputCheckAnswersSettingSchema',
66
- 'form-editor-input-question-schema': 'formEditorInputQuestionSchema',
67
- 'form-editor-input-page-settings-schema':
68
- 'formEditorInputPageSettingsSchema',
69
-
70
- // Form editor field schemas
71
- 'page-type-schema': 'pageTypeSchema',
72
- 'question-type-schema': 'questionTypeSchema',
73
- 'question-type-full-schema': 'questionTypeFullSchema',
74
- 'written-answer-sub-schema': 'writtenAnswerSubSchema',
75
- 'date-sub-schema': 'dateSubSchema',
76
-
77
- // Form submission schemas
78
- 'form-submit-payload-schema': 'formSubmitPayloadSchema',
79
- 'form-submit-record-schema': 'formSubmitRecordSchema',
80
- 'form-submit-recordset-schema': 'formSubmitRecordsetSchema',
81
-
82
- // Form manager schemas
83
- 'patch-page-schema': 'patchPageSchema',
84
-
85
- // Section schemas
86
- 'question-schema': 'questionSchema',
87
-
88
- // Validation schemas
89
- 'min-schema': 'minSchema',
90
- 'max-schema': 'maxSchema',
91
- 'min-length-schema': 'minLengthSchema',
92
- 'max-length-schema': 'maxLengthSchema',
93
- 'max-future-schema': 'maxFutureSchema',
94
- 'max-past-schema': 'maxPastSchema',
95
-
96
- // Common schemas
97
- 'search-options-schema': 'searchOptionsSchema',
98
- 'query-options-schema': 'queryOptionsSchema',
99
- 'pagination-options-schema': 'paginationOptionsSchema',
100
- 'sorting-options-schema': 'sortingOptionsSchema'
101
- }
102
- }
103
-
104
- /**
105
- * Process a single schema and create its JSON Schema file
106
- * @param {string} fileName - Output file name
107
- * @param {string} schemaName - Schema export name in the model
108
- * @param {Record<string, unknown>} model - The loaded model containing schemas
109
- * @returns {boolean} Whether processing was successful
110
- */
111
- export function processSchema(fileName, schemaName, model) {
112
- try {
113
- /** @type {unknown} */
114
- const joiSchema = model[schemaName]
115
-
116
- if (!joiSchema) {
117
- return false
118
- }
119
-
120
- /** @type {import('./schema-modules/types.js').SchemaObject} */
121
- let jsonSchema = parse(
122
- /** @type {Schema} */ (joiSchema),
123
- 'json',
124
- {},
125
- {
126
- includeSchemaDialect: true,
127
- includeDescriptions: true
128
- }
129
- )
130
-
131
- const title = toTitleCase(fileName)
132
- if (!jsonSchema.title) {
133
- jsonSchema.title = title
134
- }
135
- if (!jsonSchema.description) {
136
- jsonSchema.description = `JSON Schema for validating ${title} in Defra forms`
137
- }
138
-
139
- if (!jsonSchema.$id) {
140
- jsonSchema.$id = `@defra/forms-model/schemas/${fileName}.json`
141
- }
142
-
143
- addTitles(jsonSchema, '')
144
-
145
- jsonSchema = simplifyForDocs(jsonSchema, '')
146
-
147
- const outputPath = path.join(schemasDir, `${fileName}.json`)
148
- fs.writeFileSync(outputPath, JSON.stringify(jsonSchema, null, 2))
149
- return true
150
- } catch (/** @type {unknown} */ err) {
151
- const error = err instanceof Error ? err : new Error(String(err))
152
- console.error(`✗ Failed to process ${fileName}: ${error.message}`)
153
- return false
154
- }
155
- }
156
-
157
- /**
158
- * Loads the model with all schemas
159
- * @returns {Promise<Record<string, unknown>>} Loaded model
160
- */
161
- async function loadModelSchemas() {
162
- console.log('Loading model schemas...')
163
- return import('../dist/module/index.js')
164
- }
165
-
166
- /**
167
- * Processes all schemas and generates JSON Schema files
168
- * @param {Record<string, unknown>} model - The loaded model containing schemas
169
- * @returns {{ successCount: number, errorCount: number }} Object containing success and error counts
170
- */
171
- export function processAllSchemas(model) {
172
- const schemaMap = getSchemaMap()
173
- let successCount = 0
174
- let errorCount = 0
175
-
176
- for (const [fileName, schemaName] of Object.entries(schemaMap)) {
177
- const success = processSchema(fileName, schemaName, model)
178
-
179
- if (success) {
180
- successCount++
181
- } else {
182
- errorCount++
183
- }
184
- }
185
-
186
- return { successCount, errorCount }
187
- }
188
-
189
- /**
190
- * Generates schema files from Joi schemas
191
- */
192
- export async function generateSchemas() {
193
- try {
194
- const model = await loadModelSchemas()
195
-
196
- ensureDirectoryExists(schemasDir)
197
-
198
- cleanSchemaDirectory()
199
-
200
- const { successCount, errorCount } = processAllSchemas(model)
201
-
202
- console.log('\nSchema generation complete!')
203
- console.log(`✓ Successfully generated ${successCount} schemas`)
204
- if (errorCount > 0) {
205
- console.log(`✗ Failed to generate ${errorCount} schemas`)
206
- }
207
-
208
- return { successCount, errorCount }
209
- } catch (err) {
210
- const error = err instanceof Error ? err : new Error(String(err))
211
- console.error(`\n✗ Schema generation failed: ${error.message}`)
212
- throw error
213
- }
214
- }
215
-
216
- // Only run when executed directly, not when imported as a module
217
- if (import.meta.url === `file://${process.argv[1]}`) {
218
- ;(async () => {
219
- try {
220
- await generateSchemas()
221
- } catch (err) {
222
- console.error('Schema generation failed:', err)
223
- throw err
224
- }
225
- })().catch((err) => {
226
- console.error('Unhandled error:', err)
227
- // eslint-disable-next-line no-process-exit
228
- process.exit(1)
229
- })
230
- }
231
-
232
- /**
233
- * @import { Schema } from 'joi'
234
- */
235
-
236
- /**
237
- * @import { SchemaObject } from './schema-modules/types.js'
238
- */
@@ -1,39 +0,0 @@
1
- import path from 'path'
2
- import { fileURLToPath } from 'url'
3
-
4
- export const currentDirname = path.dirname(fileURLToPath(import.meta.url))
5
- export const schemasDir = path.resolve(currentDirname, '../../schemas')
6
-
7
- /**
8
- * Condition type constants
9
- */
10
- export const CONDITION_TYPES = {
11
- DEFINITION: 'Condition Definition',
12
- REFERENCE: 'Condition Reference',
13
- NESTED_GROUP: 'Nested Condition Group'
14
- }
15
-
16
- /**
17
- * Value type constants
18
- */
19
- export const VALUE_TYPES = {
20
- STATIC: 'Static Value',
21
- RELATIVE_DATE: 'Relative Date Value'
22
- }
23
-
24
- /**
25
- * Common description constants
26
- */
27
- export const DESCRIPTIONS = {
28
- NESTED_CONDITION_GROUP:
29
- 'A nested group of conditions that allows building complex logical expressions with multiple levels.'
30
- }
31
-
32
- /**
33
- * Path segment constants
34
- */
35
- export const PATH_SEGMENTS = {
36
- CONDITIONS: 'conditions',
37
- ITEMS: 'items',
38
- PROPERTIES: 'properties'
39
- }
@@ -1,109 +0,0 @@
1
- import { CONDITION_TYPES, DESCRIPTIONS, VALUE_TYPES } from './constants.js'
2
-
3
- /**
4
- * Fixes titles for condition items in anyOfTitles
5
- * @param {SchemaObject} obj - Schema to process
6
- * @returns {boolean} True if changes were made
7
- */
8
- export function fixConditionItems(obj) {
9
- if (!obj.anyOfTitles?.includes('Conditions Item Variant 3')) {
10
- return false
11
- }
12
-
13
- const EXPECTED_CONDITION_TYPES_COUNT = 3
14
-
15
- obj.anyOfTitles = [
16
- CONDITION_TYPES.DEFINITION,
17
- CONDITION_TYPES.REFERENCE,
18
- CONDITION_TYPES.NESTED_GROUP
19
- ]
20
-
21
- if (obj.anyOf?.length === EXPECTED_CONDITION_TYPES_COUNT) {
22
- if (obj.anyOf[0].properties?.field) {
23
- obj.anyOf[0].title = CONDITION_TYPES.DEFINITION
24
- }
25
- if (obj.anyOf[1].properties?.conditionName) {
26
- obj.anyOf[1].title = CONDITION_TYPES.REFERENCE
27
- }
28
- if (obj.anyOf[2].$ref?.includes('conditionGroupSchema')) {
29
- obj.anyOf[2].title = CONDITION_TYPES.NESTED_GROUP
30
- obj.anyOf[2].description = DESCRIPTIONS.NESTED_CONDITION_GROUP
31
- }
32
- }
33
- return true
34
- }
35
-
36
- /**
37
- * Fixes titles for value objects in anyOfTitles
38
- * @param {SchemaObject} obj - Schema to process
39
- * @returns {boolean} True if changes were made
40
- */
41
- export function fixValueObjects(obj) {
42
- if (
43
- obj.anyOfTitles?.length !== 2 ||
44
- obj.anyOfTitles[0] !== 'Value (object)' ||
45
- obj.anyOfTitles[1] !== 'Value (object)'
46
- ) {
47
- return false
48
- }
49
-
50
- obj.anyOfTitles = [VALUE_TYPES.STATIC, VALUE_TYPES.RELATIVE_DATE]
51
-
52
- if (obj.anyOf?.length === 2) {
53
- if (obj.anyOf[0].properties?.value) {
54
- obj.anyOf[0].title = VALUE_TYPES.STATIC
55
- }
56
- if (obj.anyOf[1].properties?.period) {
57
- obj.anyOf[1].title = VALUE_TYPES.RELATIVE_DATE
58
- }
59
- }
60
-
61
- return true
62
- }
63
-
64
- /**
65
- * Processes the anyOfTitles array in an object
66
- * @param {SchemaObject} obj - Schema to process
67
- */
68
- export function processAnyOfTitles(obj) {
69
- if (!obj || typeof obj !== 'object') {
70
- return
71
- }
72
-
73
- if (!Array.isArray(obj.anyOfTitles)) {
74
- return
75
- }
76
-
77
- if (!fixConditionItems(obj)) {
78
- fixValueObjects(obj)
79
- }
80
- }
81
-
82
- /**
83
- * Recursively fixes all condition titles and anyOfTitles throughout the schema
84
- * regardless of their nesting level
85
- * @param {SchemaObject} obj - The schema or subschema to fix
86
- */
87
- export function fixConditionTitles(obj) {
88
- if (!obj || typeof obj !== 'object') {
89
- return
90
- }
91
-
92
- processAnyOfTitles(obj)
93
-
94
- if (obj.title === 'Conditions Item Variant 3') {
95
- obj.title = CONDITION_TYPES.NESTED_GROUP
96
- obj.description = DESCRIPTIONS.NESTED_CONDITION_GROUP
97
- }
98
-
99
- Object.keys(obj).forEach((key) => {
100
- const value = obj[key]
101
- if (value && typeof value === 'object') {
102
- fixConditionTitles(value)
103
- }
104
- })
105
- }
106
-
107
- /**
108
- * @import { SchemaObject } from './types.js'
109
- */