@defra/forms-model 3.0.456 → 3.0.457

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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "type": "object",
3
- "description": "Enhanced form definition schema for V2 payloads with auto-generated IDs",
3
+ "description": "Form definition schema for V2",
4
4
  "properties": {
5
5
  "engine": {
6
6
  "type": "string",
@@ -377,11 +377,11 @@
377
377
  },
378
378
  "pages": {
379
379
  "type": "array",
380
- "description": "Pages with auto-generated IDs for V2 forms",
380
+ "description": "Pages schema for V2 forms",
381
381
  "uniqueItems": true,
382
382
  "items": {
383
383
  "type": "object",
384
- "description": "Page schema for payload data with auto-generated IDs for pages and components",
384
+ "description": "Page schema for V2 forms",
385
385
  "properties": {
386
386
  "path": {
387
387
  "type": "string",
@@ -592,24 +592,24 @@
592
592
  "description": "Optional custom view template to use for rendering this page",
593
593
  "title": "View"
594
594
  },
595
- "title": {
596
- "type": "string",
597
- "description": "Page title with enhanced support for empty titles in V2",
598
- "title": "Title"
599
- },
600
595
  "id": {
601
596
  "type": "string",
602
- "description": "Auto-generated unique identifier for the page",
597
+ "description": "Unique identifier for the page",
603
598
  "format": "uuid",
604
599
  "title": "Id"
605
600
  },
601
+ "title": {
602
+ "type": "string",
603
+ "description": "Page title displayed at the top of the page (with support for empty titles in V2)",
604
+ "title": "Title"
605
+ },
606
606
  "components": {
607
607
  "type": "array",
608
- "description": "Components with auto-generated IDs",
608
+ "description": "Components schema for V2 forms",
609
609
  "uniqueItems": true,
610
610
  "items": {
611
611
  "type": "object",
612
- "description": "Enhanced component schema for V2 forms with auto-generated IDs",
612
+ "description": "Component schema for V2 forms",
613
613
  "properties": {
614
614
  "type": {
615
615
  "type": "string",
@@ -756,7 +756,7 @@
756
756
  },
757
757
  "id": {
758
758
  "type": "string",
759
- "description": "Auto-generated unique identifier for the component",
759
+ "description": "Unique identifier for the component",
760
760
  "format": "uuid",
761
761
  "title": "Id"
762
762
  }
@@ -781,11 +781,11 @@
781
781
  },
782
782
  "lists": {
783
783
  "type": "array",
784
- "description": "Lists with auto-generated IDs for V2 forms",
784
+ "description": "Lists schema for V2 forms",
785
785
  "uniqueItems": true,
786
786
  "items": {
787
787
  "type": "object",
788
- "description": "Enhanced list schema for V2 forms with auto-generated IDs",
788
+ "description": "List schema for V2 forms",
789
789
  "properties": {
790
790
  "name": {
791
791
  "type": "string",
@@ -1304,7 +1304,7 @@
1304
1304
  },
1305
1305
  "id": {
1306
1306
  "type": "string",
1307
- "description": "Auto-generated unique identifier for the list",
1307
+ "description": "Unique identifier for the list",
1308
1308
  "format": "uuid",
1309
1309
  "title": "Id"
1310
1310
  }
@@ -1504,6 +1504,6 @@
1504
1504
  }
1505
1505
  },
1506
1506
  "$schema": "http://json-schema.org/draft-07/schema#",
1507
- "title": "Form Definition V2 Payload Schema",
1508
- "$id": "@defra/forms-model/schemas/form-definition-v2-payload-schema.json"
1507
+ "title": "Form Definition V2 Schema",
1508
+ "$id": "@defra/forms-model/schemas/form-definition-v2-schema.json"
1509
1509
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "type": "object",
3
- "description": "Enhanced list schema for V2 forms with auto-generated IDs",
3
+ "description": "List schema for V2 forms",
4
4
  "properties": {
5
5
  "name": {
6
6
  "type": "string",
@@ -519,7 +519,7 @@
519
519
  },
520
520
  "id": {
521
521
  "type": "string",
522
- "description": "Auto-generated unique identifier for the list",
522
+ "description": "Unique identifier for the list",
523
523
  "format": "uuid",
524
524
  "title": "Id"
525
525
  }
@@ -1,13 +1,7 @@
1
1
  {
2
2
  "type": "object",
3
- "description": "Enhanced page schema for V2 forms with support for empty titles",
3
+ "description": "Page schema for V2 forms",
4
4
  "properties": {
5
- "id": {
6
- "type": "string",
7
- "description": "Unique identifier for the page",
8
- "format": "uuid",
9
- "title": "Id"
10
- },
11
5
  "path": {
12
6
  "type": "string",
13
7
  "description": "URL path for this page, must not be the reserved \"/status\" path",
@@ -29,172 +23,6 @@
29
23
  "description": "Custom controller class name for special page behavior",
30
24
  "title": "Controller"
31
25
  },
32
- "components": {
33
- "type": "array",
34
- "description": "UI components displayed on this page",
35
- "uniqueItems": true,
36
- "items": {
37
- "type": "object",
38
- "description": "Form component definition specifying UI element behavior",
39
- "properties": {
40
- "id": {
41
- "type": "string",
42
- "description": "Unique identifier for the component",
43
- "format": "uuid",
44
- "title": "Id"
45
- },
46
- "type": {
47
- "type": "string",
48
- "description": "Component type (TextField, RadioButtons, DateField, etc.)",
49
- "title": "Type"
50
- },
51
- "shortDescription": {
52
- "type": "string",
53
- "description": "Brief description of the component purpose",
54
- "title": "Short Description"
55
- },
56
- "name": {
57
- "type": [
58
- "array",
59
- "boolean",
60
- "number",
61
- "object",
62
- "string",
63
- "null"
64
- ],
65
- "oneOf": [
66
- {
67
- "type": "string",
68
- "description": "Name format for display-only components like HTML, Markdown, etc.",
69
- "pattern": "^[a-zA-Z]+$",
70
- "title": "Display Component Name"
71
- },
72
- {
73
- "type": "string",
74
- "description": "Name format for input components that collect user data.",
75
- "pattern": "^[a-zA-Z]+$",
76
- "title": "Input Component Name"
77
- }
78
- ],
79
- "title": "Name",
80
- "description": "The name value.",
81
- "oneOfTitles": [
82
- "Display Component Name",
83
- "Input Component Name"
84
- ]
85
- },
86
- "title": {
87
- "type": [
88
- "array",
89
- "boolean",
90
- "number",
91
- "object",
92
- "string",
93
- "null"
94
- ],
95
- "oneOf": [
96
- {
97
- "type": "string",
98
- "description": "Title format for display-only components.",
99
- "title": "Display Component Title"
100
- },
101
- {
102
- "type": "string",
103
- "description": "Title displayed above input components.",
104
- "title": "Input Component Title"
105
- }
106
- ],
107
- "title": "Title",
108
- "description": "The title value.",
109
- "oneOfTitles": [
110
- "Display Component Title",
111
- "Input Component Title"
112
- ]
113
- },
114
- "hint": {
115
- "type": "string",
116
- "description": "Additional guidance text displayed below the component title",
117
- "title": "Hint"
118
- },
119
- "options": {
120
- "type": "object",
121
- "description": "Component-specific configuration options",
122
- "default": {},
123
- "properties": {
124
- "rows": {
125
- "type": "number",
126
- "description": "Number of rows for textarea components",
127
- "title": "Rows"
128
- },
129
- "maxWords": {
130
- "type": "number",
131
- "description": "Maximum number of words allowed in text inputs",
132
- "title": "Max Words"
133
- },
134
- "maxDaysInPast": {
135
- "type": "number",
136
- "description": "Maximum days in the past allowed for date inputs",
137
- "title": "Max Days In Past"
138
- },
139
- "maxDaysInFuture": {
140
- "type": "number",
141
- "description": "Maximum days in the future allowed for date inputs",
142
- "title": "Max Days In Future"
143
- },
144
- "customValidationMessage": {
145
- "type": "string",
146
- "description": "Custom error message for validation failures",
147
- "title": "Custom Validation Message"
148
- },
149
- "customValidationMessages": {
150
- "type": "object",
151
- "description": "Custom error messages keyed by validation rule name",
152
- "properties": {},
153
- "additionalProperties": true,
154
- "title": "Custom Validation Messages"
155
- }
156
- },
157
- "additionalProperties": true,
158
- "title": "Options"
159
- },
160
- "schema": {
161
- "type": "object",
162
- "description": "Validation rules for the component",
163
- "default": {},
164
- "properties": {
165
- "min": {
166
- "type": "number",
167
- "description": "Minimum value or length for validation",
168
- "title": "Min"
169
- },
170
- "max": {
171
- "type": "number",
172
- "description": "Maximum value or length for validation",
173
- "title": "Max"
174
- },
175
- "length": {
176
- "type": "number",
177
- "description": "Exact length required for validation",
178
- "title": "Length"
179
- }
180
- },
181
- "additionalProperties": true,
182
- "title": "Schema"
183
- },
184
- "list": {
185
- "type": "string",
186
- "description": "Reference to a predefined list of options for select components",
187
- "title": "List"
188
- }
189
- },
190
- "required": [
191
- "type"
192
- ],
193
- "additionalProperties": true,
194
- "title": "Components Item"
195
- },
196
- "title": "Components"
197
- },
198
26
  "repeat": {
199
27
  "type": "object",
200
28
  "title": "Repeat Configuration",
@@ -383,10 +211,182 @@
383
211
  "description": "Optional custom view template to use for rendering this page",
384
212
  "title": "View"
385
213
  },
214
+ "id": {
215
+ "type": "string",
216
+ "description": "Unique identifier for the page",
217
+ "format": "uuid",
218
+ "title": "Id"
219
+ },
386
220
  "title": {
387
221
  "type": "string",
388
- "description": "Page title with enhanced support for empty titles in V2",
222
+ "description": "Page title displayed at the top of the page (with support for empty titles in V2)",
389
223
  "title": "Title"
224
+ },
225
+ "components": {
226
+ "type": "array",
227
+ "description": "Components schema for V2 forms",
228
+ "uniqueItems": true,
229
+ "items": {
230
+ "type": "object",
231
+ "description": "Component schema for V2 forms",
232
+ "properties": {
233
+ "type": {
234
+ "type": "string",
235
+ "description": "Component type (TextField, RadioButtons, DateField, etc.)",
236
+ "title": "Type"
237
+ },
238
+ "shortDescription": {
239
+ "type": "string",
240
+ "description": "Brief description of the component purpose",
241
+ "title": "Short Description"
242
+ },
243
+ "name": {
244
+ "type": [
245
+ "array",
246
+ "boolean",
247
+ "number",
248
+ "object",
249
+ "string",
250
+ "null"
251
+ ],
252
+ "oneOf": [
253
+ {
254
+ "type": "string",
255
+ "description": "Name format for display-only components like HTML, Markdown, etc.",
256
+ "pattern": "^[a-zA-Z]+$",
257
+ "title": "Display Component Name"
258
+ },
259
+ {
260
+ "type": "string",
261
+ "description": "Name format for input components that collect user data.",
262
+ "pattern": "^[a-zA-Z]+$",
263
+ "title": "Input Component Name"
264
+ }
265
+ ],
266
+ "title": "Name",
267
+ "description": "The name value.",
268
+ "oneOfTitles": [
269
+ "Display Component Name",
270
+ "Input Component Name"
271
+ ]
272
+ },
273
+ "title": {
274
+ "type": [
275
+ "array",
276
+ "boolean",
277
+ "number",
278
+ "object",
279
+ "string",
280
+ "null"
281
+ ],
282
+ "oneOf": [
283
+ {
284
+ "type": "string",
285
+ "description": "Title format for display-only components.",
286
+ "title": "Display Component Title"
287
+ },
288
+ {
289
+ "type": "string",
290
+ "description": "Title displayed above input components.",
291
+ "title": "Input Component Title"
292
+ }
293
+ ],
294
+ "title": "Title",
295
+ "description": "The title value.",
296
+ "oneOfTitles": [
297
+ "Display Component Title",
298
+ "Input Component Title"
299
+ ]
300
+ },
301
+ "hint": {
302
+ "type": "string",
303
+ "description": "Additional guidance text displayed below the component title",
304
+ "title": "Hint"
305
+ },
306
+ "options": {
307
+ "type": "object",
308
+ "description": "Component-specific configuration options",
309
+ "default": {},
310
+ "properties": {
311
+ "rows": {
312
+ "type": "number",
313
+ "description": "Number of rows for textarea components",
314
+ "title": "Rows"
315
+ },
316
+ "maxWords": {
317
+ "type": "number",
318
+ "description": "Maximum number of words allowed in text inputs",
319
+ "title": "Max Words"
320
+ },
321
+ "maxDaysInPast": {
322
+ "type": "number",
323
+ "description": "Maximum days in the past allowed for date inputs",
324
+ "title": "Max Days In Past"
325
+ },
326
+ "maxDaysInFuture": {
327
+ "type": "number",
328
+ "description": "Maximum days in the future allowed for date inputs",
329
+ "title": "Max Days In Future"
330
+ },
331
+ "customValidationMessage": {
332
+ "type": "string",
333
+ "description": "Custom error message for validation failures",
334
+ "title": "Custom Validation Message"
335
+ },
336
+ "customValidationMessages": {
337
+ "type": "object",
338
+ "description": "Custom error messages keyed by validation rule name",
339
+ "properties": {},
340
+ "additionalProperties": true,
341
+ "title": "Custom Validation Messages"
342
+ }
343
+ },
344
+ "additionalProperties": true,
345
+ "title": "Options"
346
+ },
347
+ "schema": {
348
+ "type": "object",
349
+ "description": "Validation rules for the component",
350
+ "default": {},
351
+ "properties": {
352
+ "min": {
353
+ "type": "number",
354
+ "description": "Minimum value or length for validation",
355
+ "title": "Min"
356
+ },
357
+ "max": {
358
+ "type": "number",
359
+ "description": "Maximum value or length for validation",
360
+ "title": "Max"
361
+ },
362
+ "length": {
363
+ "type": "number",
364
+ "description": "Exact length required for validation",
365
+ "title": "Length"
366
+ }
367
+ },
368
+ "additionalProperties": true,
369
+ "title": "Schema"
370
+ },
371
+ "list": {
372
+ "type": "string",
373
+ "description": "Reference to a predefined list of options for select components",
374
+ "title": "List"
375
+ },
376
+ "id": {
377
+ "type": "string",
378
+ "description": "Unique identifier for the component",
379
+ "format": "uuid",
380
+ "title": "Id"
381
+ }
382
+ },
383
+ "required": [
384
+ "type"
385
+ ],
386
+ "additionalProperties": true,
387
+ "title": "Components Item"
388
+ },
389
+ "title": "Components"
390
390
  }
391
391
  },
392
392
  "required": [
@@ -307,9 +307,9 @@ export const componentSchemaV2 = componentSchema
307
307
  .trim()
308
308
  .uuid()
309
309
  .default(() => uuidV4())
310
- .description('Auto-generated unique identifier for the component')
310
+ .description('Unique identifier for the component')
311
311
  })
312
- .description('Enhanced component schema for V2 forms with auto-generated IDs')
312
+ .description('Component schema for V2 forms')
313
313
 
314
314
  const nextSchema = Joi.object<Link>()
315
315
  .description('Navigation link defining where to go after completing a page')
@@ -477,32 +477,25 @@ export const pageSchema = Joi.object<Page>()
477
477
  */
478
478
  export const pageSchemaV2 = pageSchema
479
479
  .append({
480
- title: Joi.string()
481
- .trim()
482
- .allow('')
483
- .required()
484
- .description('Page title with enhanced support for empty titles in V2')
485
- })
486
- .description(
487
- 'Enhanced page schema for V2 forms with support for empty titles'
488
- )
489
-
490
- export const pageSchemaPayloadV2 = pageSchemaV2
491
- .keys({
492
480
  id: Joi.string()
493
481
  .trim()
494
482
  .uuid()
495
483
  .default(() => uuidV4())
496
- .description('Auto-generated unique identifier for the page'),
484
+ .description('Unique identifier for the page'),
485
+ title: Joi.string()
486
+ .trim()
487
+ .allow('')
488
+ .required()
489
+ .description(
490
+ 'Page title displayed at the top of the page (with support for empty titles in V2)'
491
+ ),
497
492
  components: Joi.array<ComponentDef>()
498
493
  .items(componentSchemaV2)
499
494
  .unique('name')
500
- .unique('id', { ignoreUndefined: true })
501
- .description('Components with auto-generated IDs')
495
+ .unique('id')
496
+ .description('Components schema for V2 forms')
502
497
  })
503
- .description(
504
- 'Page schema for payload data with auto-generated IDs for pages and components'
505
- )
498
+ .description('Page schema for V2 forms')
506
499
 
507
500
  const baseListItemSchema = Joi.object<Item>()
508
501
  .description('Base schema for list items with common properties')
@@ -605,7 +598,7 @@ export const listSchema = Joi.object<List>()
605
598
  })
606
599
 
607
600
  /**
608
- * v2 Joi schema for Lists
601
+ * V2 Joi schema for Lists
609
602
  */
610
603
  export const listSchemaV2 = listSchema
611
604
  .keys({
@@ -613,9 +606,9 @@ export const listSchemaV2 = listSchema
613
606
  .trim()
614
607
  .uuid()
615
608
  .default(() => uuidV4())
616
- .description('Auto-generated unique identifier for the list')
609
+ .description('Unique identifier for the list')
617
610
  })
618
- .description('Enhanced list schema for V2 forms with auto-generated IDs')
611
+ .description('List schema for V2 forms')
619
612
 
620
613
  const feedbackSchema = Joi.object<FormDefinition['feedback']>()
621
614
  .description('Feedback configuration for the form')
@@ -696,18 +689,9 @@ export const formDefinitionSchema = Joi.object<FormDefinition>()
696
689
  .description('Path of the first page to show when starting the form'),
697
690
  pages: Joi.array<Page>()
698
691
  .required()
699
- .when('engine', {
700
- is: 'V2',
701
- then: Joi.array<Page>()
702
- .items(pageSchemaV2)
703
- .description('Pages using V2 schema with enhanced features'),
704
- otherwise: Joi.array<Page>()
705
- .items(pageSchema)
706
- .description('Pages using standard V1 schema')
707
- })
708
- .unique('path')
709
- .unique('id', { ignoreUndefined: true })
710
- .description('All pages within the form'),
692
+ .items(pageSchema)
693
+ .description('Pages schema for V1 forms')
694
+ .unique('path'),
711
695
  sections: Joi.array<Section>()
712
696
  .items(sectionsSchema)
713
697
  .unique('name')
@@ -749,24 +733,22 @@ export const formDefinitionSchema = Joi.object<FormDefinition>()
749
733
  .description('Configuration for submission output format')
750
734
  })
751
735
 
752
- export const formDefinitionV2PayloadSchema = formDefinitionSchema
736
+ export const formDefinitionV2Schema = formDefinitionSchema
753
737
  .keys({
754
738
  pages: Joi.array<Page>()
755
- .items(pageSchemaPayloadV2)
739
+ .items(pageSchemaV2)
756
740
  .required()
757
741
  .unique('path')
758
- .unique('id', { ignoreUndefined: true })
759
- .description('Pages with auto-generated IDs for V2 forms'),
742
+ .unique('id')
743
+ .description('Pages schema for V2 forms'),
760
744
  lists: Joi.array<List>()
761
745
  .items(listSchemaV2)
762
746
  .unique('name')
763
747
  .unique('title')
764
- .unique('id', { ignoreUndefined: true })
765
- .description('Lists with auto-generated IDs for V2 forms')
748
+ .unique('id')
749
+ .description('Lists schema for V2 forms')
766
750
  })
767
- .description(
768
- 'Enhanced form definition schema for V2 payloads with auto-generated IDs'
769
- )
751
+ .description('Form definition schema for V2')
770
752
 
771
753
  // Maintain compatibility with legacy named export
772
754
  // E.g. `import { Schema } from '@defra/forms-model'`
@@ -1,8 +1,11 @@
1
- import { type PageRepeat } from '~/src/index.js'
1
+ import { type ControllerType, type Repeat } from '~/src/index.js'
2
2
 
3
- export type PatchPageFields = Partial<
4
- Pick<PageRepeat, 'title' | 'path' | 'controller' | 'repeat'>
5
- >
3
+ export interface PatchPageFields {
4
+ title?: string
5
+ path?: string
6
+ controller?: ControllerType | null
7
+ repeat?: Repeat
8
+ }
6
9
 
7
10
  export interface AddComponentQueryOptions {
8
11
  prepend?: boolean