@defra/forms-model 3.0.430 → 3.0.432
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.
- package/README.md +163 -1
- package/dist/module/common/pagination/index.js +2 -2
- package/dist/module/common/pagination/index.js.map +1 -1
- package/dist/module/common/search/index.js +4 -4
- package/dist/module/common/search/index.js.map +1 -1
- package/dist/module/common/sorting/index.js +2 -2
- package/dist/module/common/sorting/index.js.map +1 -1
- package/dist/module/form/form-definition/index.js +156 -156
- package/dist/module/form/form-definition/index.js.map +1 -1
- package/dist/module/form/form-editor/index.js +42 -42
- package/dist/module/form/form-editor/index.js.map +1 -1
- package/dist/module/form/form-manager/index.js +3 -3
- package/dist/module/form/form-manager/index.js.map +1 -1
- package/dist/module/form/form-metadata/index.js +34 -34
- package/dist/module/form/form-metadata/index.js.map +1 -1
- package/dist/module/form/form-submission/index.js +13 -13
- package/dist/module/form/form-submission/index.js.map +1 -1
- package/dist/module/types/joi-to-json.d.js +2 -0
- package/dist/module/types/joi-to-json.d.js.map +1 -0
- package/dist/types/common/pagination/index.d.ts.map +1 -1
- package/dist/types/common/search/index.d.ts.map +1 -1
- package/dist/types/common/sorting/index.d.ts.map +1 -1
- package/dist/types/form/form-definition/index.d.ts.map +1 -1
- package/dist/types/form/form-editor/index.d.ts +12 -12
- package/dist/types/form/form-editor/index.d.ts.map +1 -1
- package/dist/types/form/form-manager/index.d.ts.map +1 -1
- package/dist/types/form/form-metadata/index.d.ts.map +1 -1
- package/dist/types/form/form-submission/index.d.ts.map +1 -1
- package/package.json +6 -4
- package/schemas/component-schema-v2.json +162 -0
- package/schemas/component-schema.json +162 -0
- package/schemas/date-sub-schema.json +11 -0
- package/schemas/form-definition-schema.json +1876 -0
- package/schemas/form-definition-v2-payload-schema.json +1459 -0
- package/schemas/form-editor-input-check-answers-setting-schema.json +18 -0
- package/schemas/form-editor-input-page-schema.json +41 -0
- package/schemas/form-editor-input-page-settings-schema.json +28 -0
- package/schemas/form-editor-input-question-schema.json +38 -0
- package/schemas/form-metadata-author-schema.json +24 -0
- package/schemas/form-metadata-contact-schema.json +61 -0
- package/schemas/form-metadata-email-schema.json +25 -0
- package/schemas/form-metadata-input-schema.json +127 -0
- package/schemas/form-metadata-online-schema.json +25 -0
- package/schemas/form-metadata-schema.json +340 -0
- package/schemas/form-metadata-state-schema.json +72 -0
- package/schemas/form-submit-payload-schema.json +124 -0
- package/schemas/form-submit-record-schema.json +30 -0
- package/schemas/form-submit-recordset-schema.json +62 -0
- package/schemas/list-schema-v2.json +486 -0
- package/schemas/list-schema.json +486 -0
- package/schemas/max-future-schema.json +8 -0
- package/schemas/max-length-schema.json +8 -0
- package/schemas/max-past-schema.json +8 -0
- package/schemas/max-schema.json +7 -0
- package/schemas/min-length-schema.json +8 -0
- package/schemas/min-schema.json +7 -0
- package/schemas/page-schema-payload-v2.json +400 -0
- package/schemas/page-schema-v2.json +400 -0
- package/schemas/page-schema.json +400 -0
- package/schemas/page-type-schema.json +11 -0
- package/schemas/pagination-options-schema.json +27 -0
- package/schemas/patch-page-schema.json +26 -0
- package/schemas/query-options-schema.json +94 -0
- package/schemas/question-schema.json +7 -0
- package/schemas/question-type-full-schema.json +22 -0
- package/schemas/question-type-schema.json +20 -0
- package/schemas/search-options-schema.json +59 -0
- package/schemas/sorting-options-schema.json +28 -0
- package/schemas/written-answer-sub-schema.json +12 -0
- package/src/common/pagination/index.ts +8 -1
- package/src/common/search/index.ts +17 -3
- package/src/common/sorting/index.ts +8 -2
- package/src/form/form-definition/index.ts +567 -238
- package/src/form/form-editor/index.ts +202 -29
- package/src/form/form-manager/index.ts +11 -2
- package/src/form/form-metadata/index.ts +118 -40
- package/src/form/form-submission/index.ts +33 -10
- package/src/types/joi-to-json.d.ts +15 -0
@@ -17,6 +17,8 @@ export enum QuestionTypeSubGroup {
|
|
17
17
|
export const pageTypeSchema = Joi.string()
|
18
18
|
.required()
|
19
19
|
.valid('question', 'guidance')
|
20
|
+
.description('Type of page - either a question page or guidance page')
|
21
|
+
|
20
22
|
export const questionTypeSchema = Joi.string()
|
21
23
|
.required()
|
22
24
|
.valid(
|
@@ -32,6 +34,7 @@ export const questionTypeSchema = Joi.string()
|
|
32
34
|
ComponentType.RadiosField,
|
33
35
|
ComponentType.AutocompleteField
|
34
36
|
)
|
37
|
+
.description('The high-level type of question, including grouped types')
|
35
38
|
|
36
39
|
export const questionTypeFullSchema = Joi.string()
|
37
40
|
.required()
|
@@ -50,6 +53,7 @@ export const questionTypeFullSchema = Joi.string()
|
|
50
53
|
ComponentType.RadiosField,
|
51
54
|
ComponentType.AutocompleteField
|
52
55
|
)
|
56
|
+
.description('The specific component type to use for this question')
|
53
57
|
|
54
58
|
export const writtenAnswerSubSchema = Joi.string()
|
55
59
|
.required()
|
@@ -58,6 +62,8 @@ export const writtenAnswerSubSchema = Joi.string()
|
|
58
62
|
ComponentType.MultilineTextField,
|
59
63
|
ComponentType.NumberField
|
60
64
|
)
|
65
|
+
.description('Subtype for written answer questions')
|
66
|
+
|
61
67
|
export const dateSubSchema = Joi.string()
|
62
68
|
.required()
|
63
69
|
.valid(ComponentType.DatePartsField, ComponentType.MonthYearField)
|
@@ -69,60 +75,221 @@ export const listSubSchema = Joi.string()
|
|
69
75
|
ComponentType.RadiosField,
|
70
76
|
ComponentType.AutocompleteField
|
71
77
|
)
|
78
|
+
.description('Subtype for date-related questions')
|
79
|
+
|
80
|
+
export const nameSchema = Joi.string()
|
81
|
+
.trim()
|
82
|
+
.required()
|
83
|
+
.description('Unique identifier for the field')
|
84
|
+
|
85
|
+
export const questionSchema = Joi.string()
|
86
|
+
.trim()
|
87
|
+
.required()
|
88
|
+
.description('The question text displayed to the user')
|
89
|
+
|
90
|
+
export const hintTextSchema = Joi.string()
|
91
|
+
.trim()
|
92
|
+
.optional()
|
93
|
+
.allow('')
|
94
|
+
.description('Optional guidance text displayed below the question')
|
72
95
|
|
73
|
-
export const nameSchema = Joi.string().trim().required()
|
74
|
-
export const questionSchema = Joi.string().trim().required()
|
75
|
-
export const hintTextSchema = Joi.string().trim().optional().allow('')
|
76
96
|
export const questionOptionalSchema = Joi.string()
|
77
97
|
.trim()
|
78
98
|
.optional()
|
79
99
|
.valid('', 'true')
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
export const
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
export const
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
100
|
+
.description(
|
101
|
+
'Indicates whether a question is optional. Empty string or "true" values are accepted.'
|
102
|
+
)
|
103
|
+
|
104
|
+
export const exactFilesSchema = Joi.number()
|
105
|
+
.empty('')
|
106
|
+
.integer()
|
107
|
+
.min(1)
|
108
|
+
.max(25)
|
109
|
+
.description(
|
110
|
+
'Specifies the exact number of files required for upload. Must be between 1 and 25.'
|
111
|
+
)
|
112
|
+
|
113
|
+
export const minFilesSchema = Joi.number()
|
114
|
+
.empty('')
|
115
|
+
.integer()
|
116
|
+
.min(0)
|
117
|
+
.max(25)
|
118
|
+
.description(
|
119
|
+
'Minimum number of files required for upload. Must be between 0 and 25.'
|
120
|
+
)
|
121
|
+
|
122
|
+
export const maxFilesSchema = Joi.number()
|
123
|
+
.empty('')
|
124
|
+
.integer()
|
125
|
+
.min(1)
|
126
|
+
.max(25)
|
127
|
+
.description(
|
128
|
+
'Maximum number of files allowed for upload. Must be between 1 and 25.'
|
129
|
+
)
|
130
|
+
|
101
131
|
export const fileTypesSchema = Joi.array()
|
102
132
|
.items(Joi.string())
|
103
133
|
.single()
|
104
134
|
.empty(null)
|
105
135
|
.default([])
|
136
|
+
.description(
|
137
|
+
'Array of allowed file types. Can be provided as a single value or an array.'
|
138
|
+
)
|
139
|
+
|
106
140
|
export const documentTypesSchema = Joi.array()
|
107
141
|
.items(Joi.string())
|
108
142
|
.single()
|
109
143
|
.empty(null)
|
110
144
|
.default([])
|
145
|
+
.description(
|
146
|
+
'Array of allowed document types. Can be provided as a single value or an array.'
|
147
|
+
)
|
148
|
+
|
111
149
|
export const imageTypesSchema = Joi.array()
|
112
150
|
.items(Joi.string())
|
113
151
|
.single()
|
114
152
|
.empty(null)
|
115
153
|
.default([])
|
154
|
+
.description(
|
155
|
+
'Array of allowed image types. Can be provided as a single value or an array.'
|
156
|
+
)
|
157
|
+
|
116
158
|
export const tabularDataTypesSchema = Joi.array()
|
117
159
|
.items(Joi.string())
|
118
160
|
.single()
|
119
161
|
.empty(null)
|
120
162
|
.default([])
|
121
|
-
export const enhancedActionSchema = Joi.string()
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
163
|
+
export const enhancedActionSchema = Joi.string()
|
164
|
+
.trim()
|
165
|
+
.optional()
|
166
|
+
.allow('')
|
167
|
+
.description('Action field that can include enhanced functionality')
|
168
|
+
|
169
|
+
export const radioIdSchema = Joi.string()
|
170
|
+
.trim()
|
171
|
+
.optional()
|
172
|
+
.allow('')
|
173
|
+
.description('Unique identifier for radio options')
|
174
|
+
|
175
|
+
export const radioLabelSchema = Joi.string()
|
176
|
+
.trim()
|
177
|
+
.required()
|
178
|
+
.description('The visible text shown next to radio options')
|
179
|
+
|
180
|
+
export const radioHintSchema = Joi.string()
|
181
|
+
.trim()
|
182
|
+
.optional()
|
183
|
+
.allow('')
|
184
|
+
.description(
|
185
|
+
'Optional hint text displayed with radio buttons to provide additional guidance'
|
186
|
+
)
|
187
|
+
|
188
|
+
export const radioValueSchema = Joi.string()
|
189
|
+
.trim()
|
190
|
+
.optional()
|
191
|
+
.allow('')
|
192
|
+
.description(
|
193
|
+
'Array of allowed tabular data types. Can be provided as a single value or an array.'
|
194
|
+
)
|
195
|
+
|
196
|
+
export const shortDescriptionSchema = Joi.string()
|
197
|
+
.trim()
|
198
|
+
.required()
|
199
|
+
.description('Brief description of the question for internal use')
|
200
|
+
|
201
|
+
export const pageHeadingAndGuidanceSchema = Joi.string()
|
202
|
+
.trim()
|
203
|
+
.optional()
|
204
|
+
.description('Combined heading and guidance for the page')
|
205
|
+
|
206
|
+
export const pageHeadingSchema = Joi.string()
|
207
|
+
.trim()
|
208
|
+
.required()
|
209
|
+
.description('Main heading displayed at the top of the page')
|
210
|
+
|
211
|
+
export const guidanceTextSchema = Joi.string()
|
212
|
+
.trim()
|
213
|
+
.description('Guidance text to assist users in completing the page')
|
214
|
+
|
215
|
+
export const needDeclarationSchema = Joi.string()
|
216
|
+
.trim()
|
217
|
+
.required()
|
218
|
+
.description('Whether a declaration is needed')
|
219
|
+
|
220
|
+
export const declarationTextSchema = Joi.string()
|
221
|
+
.trim()
|
222
|
+
.required()
|
223
|
+
.description('Text of the declaration that users must agree to')
|
224
|
+
|
225
|
+
export const minSchema = Joi.number()
|
226
|
+
.empty('')
|
227
|
+
.integer()
|
228
|
+
.description('Minimum value for numeric inputs')
|
229
|
+
|
230
|
+
export const maxSchema = Joi.number()
|
231
|
+
.empty('')
|
232
|
+
.integer()
|
233
|
+
.description('Maximum value for numeric inputs')
|
234
|
+
|
235
|
+
export const minLengthSchema = Joi.number()
|
236
|
+
.empty('')
|
237
|
+
.integer()
|
238
|
+
.min(1)
|
239
|
+
.description('Minimum character length for text inputs')
|
240
|
+
|
241
|
+
export const maxLengthSchema = Joi.number()
|
242
|
+
.empty('')
|
243
|
+
.integer()
|
244
|
+
.min(1)
|
245
|
+
.description('Maximum character length for text inputs')
|
246
|
+
|
247
|
+
export const maxFutureSchema = Joi.number()
|
248
|
+
.empty('')
|
249
|
+
.integer()
|
250
|
+
.min(1)
|
251
|
+
.description('Maximum days in the future allowed for date inputs')
|
252
|
+
|
253
|
+
export const maxPastSchema = Joi.number()
|
254
|
+
.empty('')
|
255
|
+
.integer()
|
256
|
+
.min(1)
|
257
|
+
.description('Maximum days in the past allowed for date inputs')
|
258
|
+
|
259
|
+
export const precisionSchema = Joi.number()
|
260
|
+
.empty('')
|
261
|
+
.integer()
|
262
|
+
.min(1)
|
263
|
+
.description('Decimal precision for numeric inputs')
|
264
|
+
|
265
|
+
export const prefixSchema = Joi.string()
|
266
|
+
.trim()
|
267
|
+
.optional()
|
268
|
+
.allow('')
|
269
|
+
.description('Text to display before the input (e.g., £)')
|
270
|
+
|
271
|
+
export const regexSchema = Joi.string()
|
272
|
+
.optional()
|
273
|
+
.allow('')
|
274
|
+
.description('Regular expression pattern for validation')
|
275
|
+
|
276
|
+
export const rowsSchema = Joi.number()
|
277
|
+
.empty('')
|
278
|
+
.integer()
|
279
|
+
.min(1)
|
280
|
+
.description('Number of rows for multiline text fields')
|
281
|
+
|
282
|
+
export const suffixSchema = Joi.string()
|
283
|
+
.trim()
|
284
|
+
.optional()
|
285
|
+
.allow('')
|
286
|
+
.description('Text to display after the input (e.g., kg)')
|
287
|
+
|
288
|
+
export const classesSchema = Joi.string()
|
289
|
+
.trim()
|
290
|
+
.optional()
|
291
|
+
.allow('')
|
292
|
+
.description('Custom CSS classes to apply to the component')
|
126
293
|
|
127
294
|
export const questionDetailsFullSchema = {
|
128
295
|
classesSchema,
|
@@ -169,6 +336,7 @@ export const formEditorInputPageKeys = {
|
|
169
336
|
export const formEditorInputPageSchema = Joi.object<FormEditorInputPage>()
|
170
337
|
.keys(formEditorInputPageKeys)
|
171
338
|
.required()
|
339
|
+
.description('Input schema for creating a new page in the form editor')
|
172
340
|
|
173
341
|
export const formEditorInputheckAnswersSettingsKeys = {
|
174
342
|
declarationText: shortDescriptionSchema
|
@@ -182,6 +350,7 @@ export const formEditorInputCheckAnswersSettingSchema =
|
|
182
350
|
Joi.object<FormEditorInputCheckAnswersSettings>()
|
183
351
|
.keys(formEditorInputheckAnswersSettingsKeys)
|
184
352
|
.required()
|
353
|
+
.description('Configuration for the check-answers page')
|
185
354
|
|
186
355
|
export const formEditorInputQuestionKeys = {
|
187
356
|
question: questionSchema,
|
@@ -198,6 +367,9 @@ export const formEditorInputQuestionSchema =
|
|
198
367
|
Joi.object<FormEditorInputQuestion>()
|
199
368
|
.keys(formEditorInputQuestionKeys)
|
200
369
|
.required()
|
370
|
+
.description(
|
371
|
+
'Input schema for creating or updating a question in the form editor'
|
372
|
+
)
|
201
373
|
|
202
374
|
export const formEditorInputPageSettingsKeys = {
|
203
375
|
pageHeadingAndGuidance: pageHeadingAndGuidanceSchema,
|
@@ -213,3 +385,4 @@ export const formEditorInputPageSettingsSchema =
|
|
213
385
|
Joi.object<FormEditorInputPageSettings>()
|
214
386
|
.keys(formEditorInputPageSettingsKeys)
|
215
387
|
.required()
|
388
|
+
.description('Settings for page content and display in the form editor')
|
@@ -5,8 +5,17 @@ import { pageSchema } from '~/src/index.js'
|
|
5
5
|
|
6
6
|
export const patchPageSchema = Joi.object<PatchPageFields>()
|
7
7
|
.keys({
|
8
|
-
title: pageSchema
|
9
|
-
|
8
|
+
title: pageSchema
|
9
|
+
.extract('title')
|
10
|
+
.optional()
|
11
|
+
.description('New title to set for the page'),
|
12
|
+
path: pageSchema
|
13
|
+
.extract('path')
|
14
|
+
.optional()
|
15
|
+
.description('New URL path to set for the page')
|
10
16
|
})
|
11
17
|
.required()
|
12
18
|
.min(1)
|
19
|
+
.description(
|
20
|
+
'Schema for partially updating a page, requiring at least one field to be provided'
|
21
|
+
)
|
@@ -22,30 +22,63 @@ export const organisations = [
|
|
22
22
|
'Veterinary Medicines Directorate – VMD'
|
23
23
|
]
|
24
24
|
|
25
|
-
export const idSchema = Joi.string()
|
26
|
-
|
25
|
+
export const idSchema = Joi.string()
|
26
|
+
.hex()
|
27
|
+
.length(24)
|
28
|
+
.required()
|
29
|
+
.description(
|
30
|
+
'Unique identifier for the form, 24-character hexadecimal string'
|
31
|
+
)
|
32
|
+
|
33
|
+
export const titleSchema = Joi.string()
|
34
|
+
.max(250)
|
35
|
+
.trim()
|
36
|
+
.required()
|
37
|
+
.description('Title of the form, displayed to users')
|
38
|
+
|
27
39
|
export const slugSchema = Joi.string()
|
28
40
|
.pattern(/^[a-z0-9-]+$/, { name: 'letters, numbers and hyphens only' })
|
29
41
|
.required()
|
42
|
+
.description('URL-friendly identifier used in form paths')
|
30
43
|
|
31
44
|
export const organisationSchema = Joi.string()
|
32
45
|
.valid(...organisations)
|
33
46
|
.required()
|
47
|
+
.description('Defra organisation responsible for the form')
|
48
|
+
|
49
|
+
export const teamNameSchema = Joi.string()
|
50
|
+
.max(100)
|
51
|
+
.trim()
|
52
|
+
.required()
|
53
|
+
.description('Name of the team responsible for the form')
|
34
54
|
|
35
|
-
export const teamNameSchema = Joi.string().max(100).trim().required()
|
36
55
|
export const teamEmailSchema = Joi.string()
|
37
56
|
.email({ tlds: { allow: ['uk'] } })
|
38
57
|
.trim()
|
39
58
|
.required()
|
59
|
+
.description('Contact email for the team responsible for the form')
|
60
|
+
|
61
|
+
export const phoneSchema = Joi.string()
|
62
|
+
.trim()
|
63
|
+
.description('Phone number for form-related inquiries')
|
64
|
+
|
65
|
+
export const emailAddressSchema = Joi.string()
|
66
|
+
.email()
|
67
|
+
.trim()
|
68
|
+
.required()
|
69
|
+
.description('Email address for form-related inquiries')
|
40
70
|
|
41
|
-
export const
|
71
|
+
export const emailResponseTimeSchema = Joi.string()
|
72
|
+
.trim()
|
73
|
+
.required()
|
74
|
+
.description('Expected response time for email inquiries')
|
42
75
|
|
43
|
-
export const
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
76
|
+
export const emailSchema = Joi.object<FormMetadataContactEmail>()
|
77
|
+
.keys({
|
78
|
+
address: emailAddressSchema,
|
79
|
+
responseTime: emailResponseTimeSchema
|
80
|
+
})
|
81
|
+
.description('Email contact details including response expectations')
|
49
82
|
|
50
83
|
export const onlineUrlSchema = Joi.string()
|
51
84
|
.uri({
|
@@ -53,34 +86,61 @@ export const onlineUrlSchema = Joi.string()
|
|
53
86
|
})
|
54
87
|
.trim()
|
55
88
|
.required()
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
89
|
+
.description('URL for online contact method')
|
90
|
+
|
91
|
+
export const onlineTextSchema = Joi.string()
|
92
|
+
.trim()
|
93
|
+
.required()
|
94
|
+
.description('Descriptive text for the online contact link')
|
61
95
|
|
62
|
-
export const
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
})
|
96
|
+
export const onlineSchema = Joi.object<FormMetadataContactOnline>()
|
97
|
+
.keys({
|
98
|
+
url: onlineUrlSchema,
|
99
|
+
text: onlineTextSchema
|
100
|
+
})
|
101
|
+
.description('Online contact details with URL and descriptive text')
|
67
102
|
|
68
|
-
export const
|
103
|
+
export const contactSchema = Joi.object<FormMetadataContact>()
|
104
|
+
.keys({
|
105
|
+
phone: phoneSchema,
|
106
|
+
email: emailSchema,
|
107
|
+
online: onlineSchema
|
108
|
+
})
|
109
|
+
.description('Complete contact information for form-related inquiries')
|
110
|
+
|
111
|
+
export const submissionGuidanceSchema = Joi.string()
|
112
|
+
.trim()
|
113
|
+
.description('Guidance text shown to users when submitting the form')
|
69
114
|
|
70
115
|
export const privacyNoticeUrlSchema = Joi.string()
|
71
116
|
.uri({
|
72
117
|
scheme: ['http', 'https']
|
73
118
|
})
|
74
119
|
.trim()
|
120
|
+
.description('URL to the privacy notice for this form')
|
75
121
|
|
76
122
|
export const notificationEmailAddressSchema = Joi.string()
|
77
123
|
.email({ tlds: { allow: ['uk'] } })
|
78
124
|
.trim()
|
79
125
|
.pattern(/\.gov\.uk$|\.org\.uk$/)
|
126
|
+
.description(
|
127
|
+
'Email address to receive form submission notifications, must be a .gov.uk or .org.uk address'
|
128
|
+
)
|
129
|
+
|
130
|
+
export const authoredAtSchema = Joi.date()
|
131
|
+
.iso()
|
132
|
+
.required()
|
133
|
+
.description('ISO format timestamp of when an action occurred')
|
80
134
|
|
81
|
-
export const
|
82
|
-
|
83
|
-
|
135
|
+
export const authorIdSchema = Joi.string()
|
136
|
+
.trim()
|
137
|
+
.required()
|
138
|
+
.description('Unique identifier for the author')
|
139
|
+
|
140
|
+
export const authorDisplayNameSchema = Joi.string()
|
141
|
+
.trim()
|
142
|
+
.required()
|
143
|
+
.description('Human-readable name of the author')
|
84
144
|
|
85
145
|
export const formMetadataInputKeys = {
|
86
146
|
title: titleSchema,
|
@@ -100,6 +160,7 @@ export const formMetadataInputKeys = {
|
|
100
160
|
export const formMetadataInputSchema = Joi.object<FormMetadataInput>()
|
101
161
|
.keys(formMetadataInputKeys)
|
102
162
|
.required()
|
163
|
+
.description('Input data for creating or updating form metadata')
|
103
164
|
|
104
165
|
/**
|
105
166
|
* Joi schema for `FormMetadataAuthor` interface
|
@@ -111,29 +172,46 @@ export const formMetadataAuthorSchema = Joi.object<FormMetadataAuthor>()
|
|
111
172
|
displayName: authorDisplayNameSchema
|
112
173
|
})
|
113
174
|
.required()
|
175
|
+
.description('Information about the author of a form or form change')
|
114
176
|
|
115
177
|
/**
|
116
178
|
* Joi schema for `FormMetadataState` interface
|
117
179
|
* @see {@link FormMetadataState}
|
118
180
|
*/
|
119
|
-
export const formMetadataStateSchema = Joi.object<FormMetadataState>()
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
181
|
+
export const formMetadataStateSchema = Joi.object<FormMetadataState>()
|
182
|
+
.keys({
|
183
|
+
createdAt: authoredAtSchema.description(
|
184
|
+
'When this version was first created'
|
185
|
+
),
|
186
|
+
createdBy: formMetadataAuthorSchema.description('Who created this version'),
|
187
|
+
updatedAt: authoredAtSchema.description(
|
188
|
+
'When this version was last updated'
|
189
|
+
),
|
190
|
+
updatedBy: formMetadataAuthorSchema.description(
|
191
|
+
'Who last updated this version'
|
192
|
+
)
|
193
|
+
})
|
194
|
+
.description('Metadata about a specific version state (draft or live)')
|
125
195
|
|
126
196
|
/**
|
127
197
|
* Joi schema for `FormMetadata` interface
|
128
198
|
* @see {@link FormMetadata}
|
129
199
|
*/
|
130
|
-
export const formMetadataSchema = formMetadataInputSchema
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
200
|
+
export const formMetadataSchema = formMetadataInputSchema
|
201
|
+
.append<FormMetadata>({
|
202
|
+
id: idSchema,
|
203
|
+
slug: slugSchema,
|
204
|
+
draft: formMetadataStateSchema.description(
|
205
|
+
'Metadata for the draft version'
|
206
|
+
),
|
207
|
+
live: formMetadataStateSchema.description(
|
208
|
+
'Metadata for the published version'
|
209
|
+
),
|
210
|
+
createdAt: authoredAtSchema.description('When the form was first created'),
|
211
|
+
createdBy: formMetadataAuthorSchema.description('Who created the form'),
|
212
|
+
updatedAt: authoredAtSchema.description('When the form was last updated'),
|
213
|
+
updatedBy: formMetadataAuthorSchema.description('Who last updated the form')
|
214
|
+
})
|
215
|
+
.description(
|
216
|
+
'Complete metadata for a form, including version information and authoring details'
|
217
|
+
)
|
@@ -11,22 +11,36 @@ import {
|
|
11
11
|
* @see {@link SubmitRecord}
|
12
12
|
*/
|
13
13
|
export const formSubmitRecordSchema = Joi.object<SubmitRecord>({
|
14
|
-
name: Joi.string()
|
15
|
-
|
16
|
-
|
17
|
-
|
14
|
+
name: Joi.string()
|
15
|
+
.required()
|
16
|
+
.description('Field identifier matching the component name'),
|
17
|
+
title: Joi.string()
|
18
|
+
.required()
|
19
|
+
.description('Human-readable label for the field'),
|
20
|
+
value: Joi.string()
|
21
|
+
.required()
|
22
|
+
.allow('')
|
23
|
+
.description('User-submitted value for the field, may be empty')
|
24
|
+
}).description('Individual field value in a form submission')
|
18
25
|
|
19
26
|
/**
|
20
27
|
* Joi schema for `SubmitRecordset` interface
|
21
28
|
* @see {@link SubmitRecordset}
|
22
29
|
*/
|
23
30
|
export const formSubmitRecordsetSchema = Joi.object<SubmitRecordset>({
|
24
|
-
name: Joi.string()
|
25
|
-
|
31
|
+
name: Joi.string()
|
32
|
+
.required()
|
33
|
+
.description('Identifier for the repeatable section'),
|
34
|
+
title: Joi.string()
|
35
|
+
.required()
|
36
|
+
.description('Human-readable title for the repeatable section'),
|
26
37
|
value: Joi.array<SubmitRecord[]>()
|
27
38
|
.items(Joi.array<SubmitRecord>().items(formSubmitRecordSchema).required())
|
28
39
|
.required()
|
29
|
-
|
40
|
+
.description(
|
41
|
+
'Array of record arrays, each representing a repeated instance'
|
42
|
+
)
|
43
|
+
}).description('Collection of repeated field values from a repeatable section')
|
30
44
|
|
31
45
|
/**
|
32
46
|
* Joi schema for `SubmitPayload` interface
|
@@ -34,11 +48,20 @@ export const formSubmitRecordsetSchema = Joi.object<SubmitRecordset>({
|
|
34
48
|
*/
|
35
49
|
export const formSubmitPayloadSchema = Joi.object<SubmitPayload>()
|
36
50
|
.keys({
|
37
|
-
retrievalKey: Joi.string()
|
38
|
-
|
39
|
-
|
51
|
+
retrievalKey: Joi.string()
|
52
|
+
.required()
|
53
|
+
.description('Unique key to retrieve this submission later'),
|
54
|
+
sessionId: Joi.string()
|
55
|
+
.required()
|
56
|
+
.description('User session identifier for tracking and security'),
|
57
|
+
main: Joi.array<SubmitRecord>()
|
58
|
+
.items(formSubmitRecordSchema)
|
59
|
+
.required()
|
60
|
+
.description('Main (non-repeating) field values from the form'),
|
40
61
|
repeaters: Joi.array<SubmitRecordset>()
|
41
62
|
.items(formSubmitRecordsetSchema)
|
42
63
|
.required()
|
64
|
+
.description('Repeatable section values from the form')
|
43
65
|
})
|
44
66
|
.required()
|
67
|
+
.description('Complete form submission payload structure with all form data')
|
@@ -0,0 +1,15 @@
|
|
1
|
+
declare module 'joi-to-json' {
|
2
|
+
import { type Schema } from 'joi'
|
3
|
+
|
4
|
+
/**
|
5
|
+
* Converts a Joi schema to a JSON Schema
|
6
|
+
*/
|
7
|
+
function parse(
|
8
|
+
joiSchema: Schema,
|
9
|
+
type?: string,
|
10
|
+
definitions?: object,
|
11
|
+
parserOptions?: object
|
12
|
+
): object
|
13
|
+
|
14
|
+
export = parse
|
15
|
+
}
|