@defra/forms-engine-plugin 3.0.0 → 3.0.1
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/.server/server/plugins/engine/models/FormModel.d.ts +2 -0
- package/.server/server/plugins/engine/models/FormModel.js +4 -1
- package/.server/server/plugins/engine/models/FormModel.js.map +1 -1
- package/.server/server/plugins/engine/outputFormatters/adapter/v1.d.ts +4 -0
- package/.server/server/plugins/engine/outputFormatters/adapter/v1.js +25 -0
- package/.server/server/plugins/engine/outputFormatters/adapter/v1.js.map +1 -1
- package/.server/server/plugins/engine/outputFormatters/machine/v2.js +7 -6
- package/.server/server/plugins/engine/outputFormatters/machine/v2.js.map +1 -1
- package/.server/server/plugins/engine/routes/index.js +3 -1
- package/.server/server/plugins/engine/routes/index.js.map +1 -1
- package/.server/server/plugins/engine/types/schema.js +3 -2
- package/.server/server/plugins/engine/types/schema.js.map +1 -1
- package/.server/server/plugins/engine/types.d.ts +3 -1
- package/.server/server/plugins/engine/types.js.map +1 -1
- package/package.json +2 -2
- package/src/server/plugins/engine/models/FormModel.test.ts +64 -0
- package/src/server/plugins/engine/models/FormModel.ts +5 -2
- package/src/server/plugins/engine/outputFormatters/adapter/v1.test.ts +446 -13
- package/src/server/plugins/engine/outputFormatters/adapter/v1.ts +37 -0
- package/src/server/plugins/engine/outputFormatters/machine/v2.ts +8 -6
- package/src/server/plugins/engine/routes/index.ts +3 -1
- package/src/server/plugins/engine/types/schema.test.ts +40 -0
- package/src/server/plugins/engine/types/schema.ts +3 -1
- package/src/server/plugins/engine/types.ts +3 -0
|
@@ -40,6 +40,11 @@ export function format(
|
|
|
40
40
|
|
|
41
41
|
const transformedData = v2DataParsed.data
|
|
42
42
|
|
|
43
|
+
const versionMetadata = getVersionMetadata(
|
|
44
|
+
context.submittedVersionNumber,
|
|
45
|
+
formMetadata
|
|
46
|
+
)
|
|
47
|
+
|
|
43
48
|
const meta: FormAdapterSubmissionMessageMeta = {
|
|
44
49
|
schemaVersion: FormAdapterSubmissionSchemaVersion.V1,
|
|
45
50
|
timestamp: new Date(),
|
|
@@ -51,6 +56,10 @@ export function format(
|
|
|
51
56
|
isPreview: formStatus.isPreview,
|
|
52
57
|
notificationEmail: formMetadata?.notificationEmail ?? ''
|
|
53
58
|
}
|
|
59
|
+
|
|
60
|
+
if (versionMetadata) {
|
|
61
|
+
meta.versionMetadata = versionMetadata
|
|
62
|
+
}
|
|
54
63
|
const data: FormAdapterSubmissionMessageData = transformedData
|
|
55
64
|
|
|
56
65
|
const result: FormAdapterSubmissionMessageResult = {
|
|
@@ -66,6 +75,34 @@ export function format(
|
|
|
66
75
|
return JSON.stringify(payload)
|
|
67
76
|
}
|
|
68
77
|
|
|
78
|
+
export function getVersionMetadata(
|
|
79
|
+
submittedVersionNumber: number | undefined,
|
|
80
|
+
formMetadata?: FormMetadata
|
|
81
|
+
): { versionNumber: number; createdAt: Date } | undefined {
|
|
82
|
+
if (!formMetadata?.versions?.length) {
|
|
83
|
+
return undefined
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (submittedVersionNumber !== undefined) {
|
|
87
|
+
const submittedVersion = formMetadata.versions.find(
|
|
88
|
+
(v) => v.versionNumber === submittedVersionNumber
|
|
89
|
+
)
|
|
90
|
+
if (submittedVersion) {
|
|
91
|
+
return {
|
|
92
|
+
versionNumber: submittedVersion.versionNumber,
|
|
93
|
+
createdAt: submittedVersion.createdAt
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// fallback to first available version
|
|
99
|
+
const firstVersion = formMetadata.versions[0]
|
|
100
|
+
return {
|
|
101
|
+
versionNumber: firstVersion.versionNumber,
|
|
102
|
+
createdAt: firstVersion.createdAt
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
69
106
|
function extractCsvFiles(
|
|
70
107
|
submitResponse: SubmitResponsePayload
|
|
71
108
|
): FormAdapterSubmissionMessageResult['files'] {
|
|
@@ -29,13 +29,15 @@ export function format(
|
|
|
29
29
|
|
|
30
30
|
const categorisedData = categoriseData(items)
|
|
31
31
|
|
|
32
|
+
const meta: Record<string, unknown> = {
|
|
33
|
+
schemaVersion: '2',
|
|
34
|
+
timestamp: now.toISOString(),
|
|
35
|
+
definition: model.def,
|
|
36
|
+
referenceNumber: context.referenceNumber
|
|
37
|
+
}
|
|
38
|
+
|
|
32
39
|
const data = {
|
|
33
|
-
meta
|
|
34
|
-
schemaVersion: '2',
|
|
35
|
-
timestamp: now.toISOString(),
|
|
36
|
-
definition: model.def,
|
|
37
|
-
referenceNumber: context.referenceNumber
|
|
38
|
-
},
|
|
40
|
+
meta,
|
|
39
41
|
data: categorisedData
|
|
40
42
|
}
|
|
41
43
|
|
|
@@ -151,10 +151,12 @@ export function makeLoadFormPreHandler(server: Server, options: PluginOptions) {
|
|
|
151
151
|
: `${prefix}/${slug}`
|
|
152
152
|
).substring(1)
|
|
153
153
|
|
|
154
|
+
const versionNumber = metadata.versions?.[0]?.versionNumber
|
|
155
|
+
|
|
154
156
|
// Construct the form model
|
|
155
157
|
const model = new FormModel(
|
|
156
158
|
definition,
|
|
157
|
-
{ basePath },
|
|
159
|
+
{ basePath, versionNumber },
|
|
158
160
|
services,
|
|
159
161
|
controllers
|
|
160
162
|
)
|
|
@@ -156,5 +156,45 @@ describe('Schema validation', () => {
|
|
|
156
156
|
formAdapterSubmissionMessagePayloadSchema.validate(payloadWithoutData)
|
|
157
157
|
expect(error).toBeDefined()
|
|
158
158
|
})
|
|
159
|
+
|
|
160
|
+
it('should validate payload with versionMetadata', () => {
|
|
161
|
+
const payloadWithVersion = {
|
|
162
|
+
...validPayload,
|
|
163
|
+
meta: {
|
|
164
|
+
...validPayload.meta,
|
|
165
|
+
versionMetadata: {
|
|
166
|
+
versionNumber: 19,
|
|
167
|
+
createdAt: new Date('2025-09-08T09:28:15.576Z')
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
const { error } =
|
|
172
|
+
formAdapterSubmissionMessagePayloadSchema.validate(payloadWithVersion)
|
|
173
|
+
expect(error).toBeUndefined()
|
|
174
|
+
})
|
|
175
|
+
|
|
176
|
+
it('should validate payload without versionMetadata', () => {
|
|
177
|
+
const { error } =
|
|
178
|
+
formAdapterSubmissionMessagePayloadSchema.validate(validPayload)
|
|
179
|
+
expect(error).toBeUndefined()
|
|
180
|
+
})
|
|
181
|
+
|
|
182
|
+
it('should reject invalid versionMetadata', () => {
|
|
183
|
+
const payloadWithInvalidVersion = {
|
|
184
|
+
...validPayload,
|
|
185
|
+
meta: {
|
|
186
|
+
...validPayload.meta,
|
|
187
|
+
versionMetadata: {
|
|
188
|
+
versionNumber: 'not-a-number', // Invalid - should be number
|
|
189
|
+
createdAt: new Date('2025-09-08T09:28:15.576Z')
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
const { error } = formAdapterSubmissionMessagePayloadSchema.validate(
|
|
194
|
+
payloadWithInvalidVersion
|
|
195
|
+
)
|
|
196
|
+
expect(error).toBeDefined()
|
|
197
|
+
expect(error?.message).toContain('must be a number')
|
|
198
|
+
})
|
|
159
199
|
})
|
|
160
200
|
})
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
FormStatus,
|
|
3
|
+
formVersionMetadataSchema,
|
|
3
4
|
idSchema,
|
|
4
5
|
notificationEmailAddressSchema,
|
|
5
6
|
slugSchema,
|
|
@@ -29,7 +30,8 @@ export const formAdapterSubmissionMessageMetaSchema =
|
|
|
29
30
|
.valid(...Object.values(FormStatus))
|
|
30
31
|
.required(),
|
|
31
32
|
isPreview: Joi.boolean().required(),
|
|
32
|
-
notificationEmail: notificationEmailAddressSchema.required()
|
|
33
|
+
notificationEmail: notificationEmailAddressSchema.required(),
|
|
34
|
+
versionMetadata: formVersionMetadataSchema.optional()
|
|
33
35
|
})
|
|
34
36
|
|
|
35
37
|
export const formAdapterSubmissionMessageDataSchema =
|
|
@@ -3,6 +3,7 @@ import {
|
|
|
3
3
|
type Event,
|
|
4
4
|
type FormDefinition,
|
|
5
5
|
type FormMetadata,
|
|
6
|
+
type FormVersionMetadata,
|
|
6
7
|
type Item,
|
|
7
8
|
type List,
|
|
8
9
|
type Page
|
|
@@ -179,6 +180,7 @@ export interface FormContext {
|
|
|
179
180
|
pageMap: Map<string, PageControllerClass>
|
|
180
181
|
componentMap: Map<string, Component>
|
|
181
182
|
referenceNumber: string
|
|
183
|
+
submittedVersionNumber?: number
|
|
182
184
|
}
|
|
183
185
|
|
|
184
186
|
export type FormContextRequest = (
|
|
@@ -405,6 +407,7 @@ export interface FormAdapterSubmissionMessageMeta {
|
|
|
405
407
|
status: FormStatus
|
|
406
408
|
isPreview: boolean
|
|
407
409
|
notificationEmail: string
|
|
410
|
+
versionMetadata?: FormVersionMetadata
|
|
408
411
|
}
|
|
409
412
|
|
|
410
413
|
export type FormAdapterSubmissionMessageMetaSerialised = Omit<
|