@defra/forms-model 3.0.493 → 3.0.495
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/dist/module/form/form-definition/index.js +17 -15
- package/dist/module/form/form-definition/index.js.map +1 -1
- package/dist/module/form/form-manager/errors.js +73 -0
- package/dist/module/form/form-manager/errors.js.map +1 -0
- package/dist/module/form/form-manager/types.js +1 -23
- package/dist/module/form/form-manager/types.js.map +1 -1
- package/dist/module/pages/helpers.js +19 -1
- package/dist/module/pages/helpers.js.map +1 -1
- package/dist/module/pages/index.js +1 -1
- package/dist/module/pages/index.js.map +1 -1
- package/dist/types/form/form-definition/index.d.ts.map +1 -1
- package/dist/types/form/form-manager/errors.d.ts +12 -0
- package/dist/types/form/form-manager/errors.d.ts.map +1 -0
- package/dist/types/form/form-manager/types.d.ts +1 -4
- package/dist/types/form/form-manager/types.d.ts.map +1 -1
- package/dist/types/pages/helpers.d.ts +6 -0
- package/dist/types/pages/helpers.d.ts.map +1 -1
- package/dist/types/pages/index.d.ts +1 -1
- package/dist/types/pages/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/form/form-definition/index.ts +64 -11
- package/src/form/form-manager/errors.ts +107 -0
- package/src/form/form-manager/types.ts +1 -26
- package/src/pages/helpers.ts +20 -1
- package/src/pages/index.ts +1 -0
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import type Joi from 'joi'
|
|
2
|
+
import { type ValidationError } from 'joi'
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
FormDefinitionError,
|
|
6
|
+
FormDefinitionErrorType,
|
|
7
|
+
formDefinitionErrors,
|
|
8
|
+
type FormDefinitionErrorCause
|
|
9
|
+
} from '~/src/form/form-manager/types.js'
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Checks and applies an `errorType` and also an `errorCode` for known errors
|
|
13
|
+
*/
|
|
14
|
+
export const checkErrors = (
|
|
15
|
+
formErrors: FormDefinitionError | FormDefinitionError[]
|
|
16
|
+
) => {
|
|
17
|
+
const possibleErrors = Array.isArray(formErrors) ? formErrors : [formErrors]
|
|
18
|
+
|
|
19
|
+
return function (errors: Joi.ErrorReport[]) {
|
|
20
|
+
errors.forEach((err) => {
|
|
21
|
+
if (err.local.errorType) {
|
|
22
|
+
return
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
for (const formError of possibleErrors) {
|
|
26
|
+
const errorDetails = formDefinitionErrors[formError]
|
|
27
|
+
|
|
28
|
+
// Joi's `context.key` will be the index for arrays
|
|
29
|
+
// in which case use the path, otherwise use the key
|
|
30
|
+
const keyMatch =
|
|
31
|
+
typeof err.local.key === 'number' ? err.local.path : err.local.key
|
|
32
|
+
|
|
33
|
+
if (
|
|
34
|
+
errorDetails.type === FormDefinitionErrorType.Unique &&
|
|
35
|
+
err.code === 'array.unique' &&
|
|
36
|
+
keyMatch === errorDetails.key
|
|
37
|
+
) {
|
|
38
|
+
err.local.errorCode = formError
|
|
39
|
+
err.local.errorType = FormDefinitionErrorType.Unique
|
|
40
|
+
return
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (
|
|
44
|
+
errorDetails.type === FormDefinitionErrorType.Ref &&
|
|
45
|
+
err.code === 'any.only' &&
|
|
46
|
+
keyMatch === errorDetails.key
|
|
47
|
+
) {
|
|
48
|
+
err.local.errorCode = formError
|
|
49
|
+
err.local.errorType = FormDefinitionErrorType.Ref
|
|
50
|
+
return
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
err.local.errorType = FormDefinitionErrorType.Type
|
|
54
|
+
}
|
|
55
|
+
})
|
|
56
|
+
return errors
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Get the custom errors from a form definition joi validation error
|
|
62
|
+
*/
|
|
63
|
+
export function getErrors(
|
|
64
|
+
validationError: ValidationError | undefined
|
|
65
|
+
): FormDefinitionErrorCause[] {
|
|
66
|
+
return (
|
|
67
|
+
validationError?.details.map((detail) => {
|
|
68
|
+
if (
|
|
69
|
+
detail.context?.errorType === FormDefinitionErrorType.Unique &&
|
|
70
|
+
detail.context.errorCode
|
|
71
|
+
) {
|
|
72
|
+
return {
|
|
73
|
+
id: /** @type {FormDefinitionError} */ detail.context.errorCode,
|
|
74
|
+
type: FormDefinitionErrorType.Unique,
|
|
75
|
+
message: detail.message,
|
|
76
|
+
detail: {
|
|
77
|
+
path: detail.path,
|
|
78
|
+
pos: detail.context.pos,
|
|
79
|
+
dupePos: detail.context.dupePos
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (
|
|
85
|
+
detail.context?.errorType === FormDefinitionErrorType.Ref &&
|
|
86
|
+
detail.context.errorCode
|
|
87
|
+
) {
|
|
88
|
+
return {
|
|
89
|
+
id: /** @type {FormDefinitionError} */ detail.context.errorCode,
|
|
90
|
+
type: FormDefinitionErrorType.Ref,
|
|
91
|
+
message: detail.message,
|
|
92
|
+
detail: {
|
|
93
|
+
path: detail.path
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// Catch all others
|
|
99
|
+
return {
|
|
100
|
+
id: FormDefinitionError.Other,
|
|
101
|
+
type: FormDefinitionErrorType.Type,
|
|
102
|
+
message: detail.message,
|
|
103
|
+
detail: detail.context
|
|
104
|
+
}
|
|
105
|
+
}) ?? []
|
|
106
|
+
)
|
|
107
|
+
}
|
|
@@ -23,8 +23,8 @@ export enum FormDefinitionErrorType {
|
|
|
23
23
|
|
|
24
24
|
// Enum for errors that can exist in a form definition
|
|
25
25
|
export enum FormDefinitionError {
|
|
26
|
-
UniquePagePath = 'unique_page_path',
|
|
27
26
|
UniquePageId = 'unique_page_id',
|
|
27
|
+
UniquePagePath = 'unique_page_path',
|
|
28
28
|
UniquePageComponentId = 'unique_page_component_id',
|
|
29
29
|
UniquePageComponentName = 'unique_page_component_name',
|
|
30
30
|
UniqueSectionName = 'unique_section_name',
|
|
@@ -46,11 +46,7 @@ export enum FormDefinitionError {
|
|
|
46
46
|
Other = 'other'
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
-
export const N = Symbol('AnyNumber')
|
|
50
|
-
|
|
51
|
-
export type ErrorMatchPath = (string | typeof N)[]
|
|
52
49
|
export interface ErrorMatchValue {
|
|
53
|
-
path: ErrorMatchPath
|
|
54
50
|
key: string
|
|
55
51
|
type: FormDefinitionErrorType
|
|
56
52
|
}
|
|
@@ -60,107 +56,86 @@ export type FormDefinitionErrors = Record<FormDefinitionError, ErrorMatchValue>
|
|
|
60
56
|
// The errors that can exist in the form definition
|
|
61
57
|
export const formDefinitionErrors: FormDefinitionErrors = {
|
|
62
58
|
[FormDefinitionError.UniquePagePath]: {
|
|
63
|
-
path: ['pages', N],
|
|
64
59
|
key: 'path',
|
|
65
60
|
type: FormDefinitionErrorType.Unique
|
|
66
61
|
},
|
|
67
62
|
[FormDefinitionError.UniquePageId]: {
|
|
68
|
-
path: ['pages', N],
|
|
69
63
|
key: 'id',
|
|
70
64
|
type: FormDefinitionErrorType.Unique
|
|
71
65
|
},
|
|
72
66
|
[FormDefinitionError.UniquePageComponentId]: {
|
|
73
|
-
path: ['pages', N, 'components', N],
|
|
74
67
|
key: 'id',
|
|
75
68
|
type: FormDefinitionErrorType.Unique
|
|
76
69
|
},
|
|
77
70
|
[FormDefinitionError.UniquePageComponentName]: {
|
|
78
|
-
path: ['pages', N, 'components', N],
|
|
79
71
|
key: 'name',
|
|
80
72
|
type: FormDefinitionErrorType.Unique
|
|
81
73
|
},
|
|
82
74
|
[FormDefinitionError.UniqueSectionName]: {
|
|
83
|
-
path: ['sections', N],
|
|
84
75
|
key: 'name',
|
|
85
76
|
type: FormDefinitionErrorType.Unique
|
|
86
77
|
},
|
|
87
78
|
[FormDefinitionError.UniqueSectionTitle]: {
|
|
88
|
-
path: ['sections', N],
|
|
89
79
|
key: 'title',
|
|
90
80
|
type: FormDefinitionErrorType.Unique
|
|
91
81
|
},
|
|
92
82
|
[FormDefinitionError.UniqueListId]: {
|
|
93
|
-
path: ['lists', N],
|
|
94
83
|
key: 'id',
|
|
95
84
|
type: FormDefinitionErrorType.Unique
|
|
96
85
|
},
|
|
97
86
|
[FormDefinitionError.UniqueListTitle]: {
|
|
98
|
-
path: ['lists', N],
|
|
99
87
|
key: 'title',
|
|
100
88
|
type: FormDefinitionErrorType.Unique
|
|
101
89
|
},
|
|
102
90
|
[FormDefinitionError.UniqueListName]: {
|
|
103
|
-
path: ['lists', N],
|
|
104
91
|
key: 'name',
|
|
105
92
|
type: FormDefinitionErrorType.Unique
|
|
106
93
|
},
|
|
107
94
|
[FormDefinitionError.UniqueConditionDisplayName]: {
|
|
108
|
-
path: ['conditions', N],
|
|
109
95
|
key: 'displayName',
|
|
110
96
|
type: FormDefinitionErrorType.Unique
|
|
111
97
|
},
|
|
112
98
|
[FormDefinitionError.UniqueConditionId]: {
|
|
113
|
-
path: ['conditions', N],
|
|
114
99
|
key: 'id',
|
|
115
100
|
type: FormDefinitionErrorType.Unique
|
|
116
101
|
},
|
|
117
102
|
[FormDefinitionError.UniqueListItemId]: {
|
|
118
|
-
path: ['lists', N, 'items', N],
|
|
119
103
|
key: 'id',
|
|
120
104
|
type: FormDefinitionErrorType.Unique
|
|
121
105
|
},
|
|
122
106
|
[FormDefinitionError.UniqueListItemText]: {
|
|
123
|
-
path: ['lists', N, 'items', N],
|
|
124
107
|
key: 'text',
|
|
125
108
|
type: FormDefinitionErrorType.Unique
|
|
126
109
|
},
|
|
127
110
|
[FormDefinitionError.UniqueListItemValue]: {
|
|
128
|
-
path: ['lists', N, 'items', N],
|
|
129
111
|
key: 'value',
|
|
130
112
|
type: FormDefinitionErrorType.Unique
|
|
131
113
|
},
|
|
132
114
|
[FormDefinitionError.RefPageCondition]: {
|
|
133
|
-
path: ['pages', N, 'condition'],
|
|
134
115
|
key: 'condition',
|
|
135
116
|
type: FormDefinitionErrorType.Ref
|
|
136
117
|
},
|
|
137
118
|
[FormDefinitionError.RefConditionComponentId]: {
|
|
138
|
-
path: ['conditions', N, 'items', N, 'componentId'],
|
|
139
119
|
key: 'componentId',
|
|
140
120
|
type: FormDefinitionErrorType.Ref
|
|
141
121
|
},
|
|
142
122
|
[FormDefinitionError.RefConditionListId]: {
|
|
143
|
-
path: ['conditions', N, 'items', N, 'value', 'listId'],
|
|
144
123
|
key: 'listId',
|
|
145
124
|
type: FormDefinitionErrorType.Ref
|
|
146
125
|
},
|
|
147
126
|
[FormDefinitionError.RefConditionItemId]: {
|
|
148
|
-
path: ['conditions', N, 'items', N, 'value', 'itemId'],
|
|
149
127
|
key: 'itemId',
|
|
150
128
|
type: FormDefinitionErrorType.Ref
|
|
151
129
|
},
|
|
152
130
|
[FormDefinitionError.RefConditionConditionId]: {
|
|
153
|
-
path: ['conditions', N, 'items', N, 'conditionId'],
|
|
154
131
|
key: 'conditionId',
|
|
155
132
|
type: FormDefinitionErrorType.Ref
|
|
156
133
|
},
|
|
157
134
|
[FormDefinitionError.RefPageComponentList]: {
|
|
158
|
-
path: ['pages', N, 'components', N, 'list'],
|
|
159
135
|
key: 'list',
|
|
160
136
|
type: FormDefinitionErrorType.Ref
|
|
161
137
|
},
|
|
162
138
|
[FormDefinitionError.Other]: {
|
|
163
|
-
path: [],
|
|
164
139
|
key: '',
|
|
165
140
|
type: FormDefinitionErrorType.Type
|
|
166
141
|
}
|
package/src/pages/helpers.ts
CHANGED
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
type PageQuestion,
|
|
7
7
|
type PageRepeat
|
|
8
8
|
} from '~/src/form/form-definition/types.js'
|
|
9
|
-
import { ComponentType } from '~/src/index.js'
|
|
9
|
+
import { ComponentType, hasFormField } from '~/src/index.js'
|
|
10
10
|
import {
|
|
11
11
|
ControllerNames,
|
|
12
12
|
ControllerTypes
|
|
@@ -153,3 +153,22 @@ export function omitFileUploadComponent(page: Page | undefined): boolean {
|
|
|
153
153
|
}
|
|
154
154
|
return false
|
|
155
155
|
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Gets page title, or title of first question (if no page title set)
|
|
159
|
+
* @param {Page} page
|
|
160
|
+
* @returns {string}
|
|
161
|
+
*/
|
|
162
|
+
export function getPageTitle(page: Page) {
|
|
163
|
+
if (page.title !== '') {
|
|
164
|
+
return page.title
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
if (hasComponentsEvenIfNoNext(page)) {
|
|
168
|
+
const firstComp = page.components.find(hasFormField)
|
|
169
|
+
if (firstComp) {
|
|
170
|
+
return firstComp.title
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
return 'Page title unknown'
|
|
174
|
+
}
|