@defra/forms-engine-plugin 1.0.0 → 1.0.2
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/README.md +56 -0
- package/.server/server/plugins/engine/configureEnginePlugin.d.ts +2 -1
- package/.server/server/plugins/engine/configureEnginePlugin.js +1 -1
- package/.server/server/plugins/engine/configureEnginePlugin.js.map +1 -1
- package/.server/server/plugins/engine/plugin.d.ts +2 -27
- package/.server/server/plugins/engine/plugin.js +17 -594
- package/.server/server/plugins/engine/plugin.js.map +1 -1
- package/.server/server/plugins/engine/registrationOptions.d.ts +1 -0
- package/.server/server/plugins/engine/registrationOptions.js +2 -0
- package/.server/server/plugins/engine/registrationOptions.js.map +1 -0
- package/.server/server/plugins/engine/routes/file-upload.d.ts +4 -0
- package/.server/server/plugins/engine/routes/file-upload.js +41 -0
- package/.server/server/plugins/engine/routes/file-upload.js.map +1 -0
- package/.server/server/plugins/engine/routes/index.d.ts +7 -0
- package/.server/server/plugins/engine/routes/index.js +141 -0
- package/.server/server/plugins/engine/routes/index.js.map +1 -0
- package/.server/server/plugins/engine/routes/questions.d.ts +3 -0
- package/.server/server/plugins/engine/routes/questions.js +168 -0
- package/.server/server/plugins/engine/routes/questions.js.map +1 -0
- package/.server/server/plugins/engine/routes/repeaters/item-delete.d.ts +3 -0
- package/.server/server/plugins/engine/routes/repeaters/item-delete.js +106 -0
- package/.server/server/plugins/engine/routes/repeaters/item-delete.js.map +1 -0
- package/.server/server/plugins/engine/routes/repeaters/summary.d.ts +3 -0
- package/.server/server/plugins/engine/routes/repeaters/summary.js +98 -0
- package/.server/server/plugins/engine/routes/repeaters/summary.js.map +1 -0
- package/.server/server/plugins/engine/types.d.ts +19 -1
- package/.server/server/plugins/engine/types.js.map +1 -1
- package/.server/server/plugins/engine/vision.d.ts +12 -0
- package/.server/server/plugins/engine/vision.js +55 -0
- package/.server/server/plugins/engine/vision.js.map +1 -0
- package/.server/server/services/cacheService.d.ts +12 -3
- package/.server/server/services/cacheService.js +35 -8
- package/.server/server/services/cacheService.js.map +1 -1
- package/package.json +3 -3
- package/src/server/plugins/engine/README.md +56 -0
- package/src/server/plugins/engine/configureEnginePlugin.ts +3 -5
- package/src/server/plugins/engine/plugin.ts +35 -765
- package/src/server/plugins/engine/registrationOptions.ts +0 -0
- package/src/server/plugins/engine/routes/file-upload.ts +54 -0
- package/src/server/plugins/engine/routes/index.ts +187 -0
- package/src/server/plugins/engine/routes/questions.ts +208 -0
- package/src/server/plugins/engine/routes/repeaters/item-delete.ts +157 -0
- package/src/server/plugins/engine/routes/repeaters/summary.ts +137 -0
- package/src/server/plugins/engine/types.ts +26 -1
- package/src/server/plugins/engine/vision.ts +95 -0
- package/src/server/services/cacheService.test.ts +98 -2
- package/src/server/services/cacheService.ts +57 -8
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { slugSchema } from '@defra/forms-model';
|
|
2
|
+
import Boom from '@hapi/boom';
|
|
3
|
+
import Joi from 'joi';
|
|
4
|
+
import { FileUploadPageController } from "../../pageControllers/FileUploadPageController.js";
|
|
5
|
+
import { RepeatPageController } from "../../pageControllers/RepeatPageController.js";
|
|
6
|
+
import { redirectOrMakeHandler } from "../index.js";
|
|
7
|
+
import { actionSchema, confirmSchema, crumbSchema, itemIdSchema, pathSchema, stateSchema } from "../../../../schemas/index.js";
|
|
8
|
+
|
|
9
|
+
// Item delete GET route
|
|
10
|
+
function getHandler(request, h) {
|
|
11
|
+
const {
|
|
12
|
+
params
|
|
13
|
+
} = request;
|
|
14
|
+
return redirectOrMakeHandler(request, h, (page, context) => {
|
|
15
|
+
if (!(page instanceof RepeatPageController || page instanceof FileUploadPageController)) {
|
|
16
|
+
throw Boom.notFound(`No page found for /${params.path}`);
|
|
17
|
+
}
|
|
18
|
+
return page.makeGetItemDeleteRouteHandler()(request, context, h);
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
function postHandler(request, h) {
|
|
22
|
+
const {
|
|
23
|
+
params
|
|
24
|
+
} = request;
|
|
25
|
+
return redirectOrMakeHandler(request, h, (page, context) => {
|
|
26
|
+
const {
|
|
27
|
+
isForceAccess
|
|
28
|
+
} = context;
|
|
29
|
+
if (isForceAccess || !(page instanceof RepeatPageController || page instanceof FileUploadPageController)) {
|
|
30
|
+
throw Boom.notFound(`No page found for /${params.path}`);
|
|
31
|
+
}
|
|
32
|
+
return page.makePostItemDeleteRouteHandler()(request, context, h);
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
export function getRoutes(getRouteOptions, postRouteOptions) {
|
|
36
|
+
return [{
|
|
37
|
+
method: 'get',
|
|
38
|
+
path: '/{slug}/{path}/{itemId}/confirm-delete',
|
|
39
|
+
handler: getHandler,
|
|
40
|
+
options: {
|
|
41
|
+
...getRouteOptions,
|
|
42
|
+
validate: {
|
|
43
|
+
params: Joi.object().keys({
|
|
44
|
+
slug: slugSchema,
|
|
45
|
+
path: pathSchema,
|
|
46
|
+
itemId: itemIdSchema
|
|
47
|
+
})
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}, {
|
|
51
|
+
method: 'get',
|
|
52
|
+
path: '/preview/{state}/{slug}/{path}/{itemId}/confirm-delete',
|
|
53
|
+
handler: getHandler,
|
|
54
|
+
options: {
|
|
55
|
+
...getRouteOptions,
|
|
56
|
+
validate: {
|
|
57
|
+
params: Joi.object().keys({
|
|
58
|
+
state: stateSchema,
|
|
59
|
+
slug: slugSchema,
|
|
60
|
+
path: pathSchema,
|
|
61
|
+
itemId: itemIdSchema
|
|
62
|
+
})
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}, {
|
|
66
|
+
method: 'post',
|
|
67
|
+
path: '/{slug}/{path}/{itemId}/confirm-delete',
|
|
68
|
+
handler: postHandler,
|
|
69
|
+
options: {
|
|
70
|
+
...postRouteOptions,
|
|
71
|
+
validate: {
|
|
72
|
+
params: Joi.object().keys({
|
|
73
|
+
slug: slugSchema,
|
|
74
|
+
path: pathSchema,
|
|
75
|
+
itemId: itemIdSchema
|
|
76
|
+
}),
|
|
77
|
+
payload: Joi.object().keys({
|
|
78
|
+
crumb: crumbSchema,
|
|
79
|
+
action: actionSchema,
|
|
80
|
+
confirm: confirmSchema
|
|
81
|
+
}).required()
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}, {
|
|
85
|
+
method: 'post',
|
|
86
|
+
path: '/preview/{state}/{slug}/{path}/{itemId}/confirm-delete',
|
|
87
|
+
handler: postHandler,
|
|
88
|
+
options: {
|
|
89
|
+
...postRouteOptions,
|
|
90
|
+
validate: {
|
|
91
|
+
params: Joi.object().keys({
|
|
92
|
+
state: stateSchema,
|
|
93
|
+
slug: slugSchema,
|
|
94
|
+
path: pathSchema,
|
|
95
|
+
itemId: itemIdSchema
|
|
96
|
+
}),
|
|
97
|
+
payload: Joi.object().keys({
|
|
98
|
+
crumb: crumbSchema,
|
|
99
|
+
action: actionSchema,
|
|
100
|
+
confirm: confirmSchema
|
|
101
|
+
}).required()
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}];
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=item-delete.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"item-delete.js","names":["slugSchema","Boom","Joi","FileUploadPageController","RepeatPageController","redirectOrMakeHandler","actionSchema","confirmSchema","crumbSchema","itemIdSchema","pathSchema","stateSchema","getHandler","request","h","params","page","context","notFound","path","makeGetItemDeleteRouteHandler","postHandler","isForceAccess","makePostItemDeleteRouteHandler","getRoutes","getRouteOptions","postRouteOptions","method","handler","options","validate","object","keys","slug","itemId","state","payload","crumb","action","confirm","required"],"sources":["../../../../../../src/server/plugins/engine/routes/repeaters/item-delete.ts"],"sourcesContent":["import { slugSchema } from '@defra/forms-model'\nimport Boom from '@hapi/boom'\nimport {\n type ResponseToolkit,\n type RouteOptions,\n type ServerRoute\n} from '@hapi/hapi'\nimport Joi from 'joi'\n\nimport { FileUploadPageController } from '~/src/server/plugins/engine/pageControllers/FileUploadPageController.js'\nimport { RepeatPageController } from '~/src/server/plugins/engine/pageControllers/RepeatPageController.js'\nimport { redirectOrMakeHandler } from '~/src/server/plugins/engine/routes/index.js'\nimport {\n type FormRequest,\n type FormRequestPayload,\n type FormRequestPayloadRefs,\n type FormRequestRefs\n} from '~/src/server/routes/types.js'\nimport {\n actionSchema,\n confirmSchema,\n crumbSchema,\n itemIdSchema,\n pathSchema,\n stateSchema\n} from '~/src/server/schemas/index.js'\n\n// Item delete GET route\nfunction getHandler(\n request: FormRequest,\n h: Pick<ResponseToolkit, 'redirect' | 'view'>\n) {\n const { params } = request\n\n return redirectOrMakeHandler(request, h, (page, context) => {\n if (\n !(\n page instanceof RepeatPageController ||\n page instanceof FileUploadPageController\n )\n ) {\n throw Boom.notFound(`No page found for /${params.path}`)\n }\n\n return page.makeGetItemDeleteRouteHandler()(request, context, h)\n })\n}\n\nfunction postHandler(\n request: FormRequestPayload,\n h: Pick<ResponseToolkit, 'redirect' | 'view'>\n) {\n const { params } = request\n\n return redirectOrMakeHandler(request, h, (page, context) => {\n const { isForceAccess } = context\n\n if (\n isForceAccess ||\n !(\n page instanceof RepeatPageController ||\n page instanceof FileUploadPageController\n )\n ) {\n throw Boom.notFound(`No page found for /${params.path}`)\n }\n\n return page.makePostItemDeleteRouteHandler()(request, context, h)\n })\n}\n\nexport function getRoutes(\n getRouteOptions: RouteOptions<FormRequestRefs>,\n postRouteOptions: RouteOptions<FormRequestPayloadRefs>\n): (ServerRoute<FormRequestRefs> | ServerRoute<FormRequestPayloadRefs>)[] {\n return [\n {\n method: 'get',\n path: '/{slug}/{path}/{itemId}/confirm-delete',\n handler: getHandler,\n options: {\n ...getRouteOptions,\n validate: {\n params: Joi.object().keys({\n slug: slugSchema,\n path: pathSchema,\n itemId: itemIdSchema\n })\n }\n }\n },\n\n {\n method: 'get',\n path: '/preview/{state}/{slug}/{path}/{itemId}/confirm-delete',\n handler: getHandler,\n options: {\n ...getRouteOptions,\n validate: {\n params: Joi.object().keys({\n state: stateSchema,\n slug: slugSchema,\n path: pathSchema,\n itemId: itemIdSchema\n })\n }\n }\n },\n\n {\n method: 'post',\n path: '/{slug}/{path}/{itemId}/confirm-delete',\n handler: postHandler,\n options: {\n ...postRouteOptions,\n validate: {\n params: Joi.object().keys({\n slug: slugSchema,\n path: pathSchema,\n itemId: itemIdSchema\n }),\n payload: Joi.object()\n .keys({\n crumb: crumbSchema,\n action: actionSchema,\n confirm: confirmSchema\n })\n .required()\n }\n }\n },\n\n {\n method: 'post',\n path: '/preview/{state}/{slug}/{path}/{itemId}/confirm-delete',\n handler: postHandler,\n options: {\n ...postRouteOptions,\n validate: {\n params: Joi.object().keys({\n state: stateSchema,\n slug: slugSchema,\n path: pathSchema,\n itemId: itemIdSchema\n }),\n payload: Joi.object()\n .keys({\n crumb: crumbSchema,\n action: actionSchema,\n confirm: confirmSchema\n })\n .required()\n }\n }\n }\n ]\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { type RouteOptions, type ServerRoute } from '@hapi/hapi';
|
|
2
|
+
import { type FormRequestPayloadRefs, type FormRequestRefs } from '~/src/server/routes/types.js';
|
|
3
|
+
export declare function getRoutes(getRouteOptions: RouteOptions<FormRequestRefs>, postRouteOptions: RouteOptions<FormRequestPayloadRefs>): (ServerRoute<FormRequestRefs> | ServerRoute<FormRequestPayloadRefs>)[];
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
// List summary GET route
|
|
2
|
+
import { slugSchema } from '@defra/forms-model';
|
|
3
|
+
import Boom from '@hapi/boom';
|
|
4
|
+
import Joi from 'joi';
|
|
5
|
+
import { RepeatPageController } from "../../pageControllers/RepeatPageController.js";
|
|
6
|
+
import { redirectOrMakeHandler } from "../index.js";
|
|
7
|
+
import { actionSchema, crumbSchema, pathSchema, stateSchema } from "../../../../schemas/index.js";
|
|
8
|
+
function getHandler(request, h) {
|
|
9
|
+
const {
|
|
10
|
+
params
|
|
11
|
+
} = request;
|
|
12
|
+
return redirectOrMakeHandler(request, h, (page, context) => {
|
|
13
|
+
if (!(page instanceof RepeatPageController)) {
|
|
14
|
+
throw Boom.notFound(`No repeater page found for /${params.path}`);
|
|
15
|
+
}
|
|
16
|
+
return page.makeGetListSummaryRouteHandler()(request, context, h);
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
function postHandler(request, h) {
|
|
20
|
+
const {
|
|
21
|
+
params
|
|
22
|
+
} = request;
|
|
23
|
+
return redirectOrMakeHandler(request, h, (page, context) => {
|
|
24
|
+
const {
|
|
25
|
+
isForceAccess
|
|
26
|
+
} = context;
|
|
27
|
+
if (isForceAccess || !(page instanceof RepeatPageController)) {
|
|
28
|
+
throw Boom.notFound(`No repeater page found for /${params.path}`);
|
|
29
|
+
}
|
|
30
|
+
return page.makePostListSummaryRouteHandler()(request, context, h);
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
export function getRoutes(getRouteOptions, postRouteOptions) {
|
|
34
|
+
return [{
|
|
35
|
+
method: 'get',
|
|
36
|
+
path: '/{slug}/{path}/summary',
|
|
37
|
+
handler: getHandler,
|
|
38
|
+
options: {
|
|
39
|
+
...getRouteOptions,
|
|
40
|
+
validate: {
|
|
41
|
+
params: Joi.object().keys({
|
|
42
|
+
slug: slugSchema,
|
|
43
|
+
path: pathSchema
|
|
44
|
+
})
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}, {
|
|
48
|
+
method: 'get',
|
|
49
|
+
path: '/preview/{state}/{slug}/{path}/summary',
|
|
50
|
+
handler: getHandler,
|
|
51
|
+
options: {
|
|
52
|
+
...getRouteOptions,
|
|
53
|
+
validate: {
|
|
54
|
+
params: Joi.object().keys({
|
|
55
|
+
state: stateSchema,
|
|
56
|
+
slug: slugSchema,
|
|
57
|
+
path: pathSchema
|
|
58
|
+
})
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}, {
|
|
62
|
+
method: 'post',
|
|
63
|
+
path: '/{slug}/{path}/summary',
|
|
64
|
+
handler: postHandler,
|
|
65
|
+
options: {
|
|
66
|
+
...postRouteOptions,
|
|
67
|
+
validate: {
|
|
68
|
+
params: Joi.object().keys({
|
|
69
|
+
slug: slugSchema,
|
|
70
|
+
path: pathSchema
|
|
71
|
+
}),
|
|
72
|
+
payload: Joi.object().keys({
|
|
73
|
+
crumb: crumbSchema,
|
|
74
|
+
action: actionSchema
|
|
75
|
+
}).required()
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}, {
|
|
79
|
+
method: 'post',
|
|
80
|
+
path: '/preview/{state}/{slug}/{path}/summary',
|
|
81
|
+
handler: postHandler,
|
|
82
|
+
options: {
|
|
83
|
+
...postRouteOptions,
|
|
84
|
+
validate: {
|
|
85
|
+
params: Joi.object().keys({
|
|
86
|
+
state: stateSchema,
|
|
87
|
+
slug: slugSchema,
|
|
88
|
+
path: pathSchema
|
|
89
|
+
}),
|
|
90
|
+
payload: Joi.object().keys({
|
|
91
|
+
crumb: crumbSchema,
|
|
92
|
+
action: actionSchema
|
|
93
|
+
}).required()
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}];
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=summary.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"summary.js","names":["slugSchema","Boom","Joi","RepeatPageController","redirectOrMakeHandler","actionSchema","crumbSchema","pathSchema","stateSchema","getHandler","request","h","params","page","context","notFound","path","makeGetListSummaryRouteHandler","postHandler","isForceAccess","makePostListSummaryRouteHandler","getRoutes","getRouteOptions","postRouteOptions","method","handler","options","validate","object","keys","slug","state","payload","crumb","action","required"],"sources":["../../../../../../src/server/plugins/engine/routes/repeaters/summary.ts"],"sourcesContent":["// List summary GET route\nimport { slugSchema } from '@defra/forms-model'\nimport Boom from '@hapi/boom'\nimport {\n type ResponseToolkit,\n type RouteOptions,\n type ServerRoute\n} from '@hapi/hapi'\nimport Joi from 'joi'\n\nimport { RepeatPageController } from '~/src/server/plugins/engine/pageControllers/RepeatPageController.js'\nimport { redirectOrMakeHandler } from '~/src/server/plugins/engine/routes/index.js'\nimport {\n type FormRequest,\n type FormRequestPayload,\n type FormRequestPayloadRefs,\n type FormRequestRefs\n} from '~/src/server/routes/types.js'\nimport {\n actionSchema,\n crumbSchema,\n pathSchema,\n stateSchema\n} from '~/src/server/schemas/index.js'\n\nfunction getHandler(\n request: FormRequest,\n h: Pick<ResponseToolkit, 'redirect' | 'view'>\n) {\n const { params } = request\n\n return redirectOrMakeHandler(request, h, (page, context) => {\n if (!(page instanceof RepeatPageController)) {\n throw Boom.notFound(`No repeater page found for /${params.path}`)\n }\n\n return page.makeGetListSummaryRouteHandler()(request, context, h)\n })\n}\n\nfunction postHandler(\n request: FormRequestPayload,\n h: Pick<ResponseToolkit, 'redirect' | 'view'>\n) {\n const { params } = request\n\n return redirectOrMakeHandler(request, h, (page, context) => {\n const { isForceAccess } = context\n\n if (isForceAccess || !(page instanceof RepeatPageController)) {\n throw Boom.notFound(`No repeater page found for /${params.path}`)\n }\n\n return page.makePostListSummaryRouteHandler()(request, context, h)\n })\n}\n\nexport function getRoutes(\n getRouteOptions: RouteOptions<FormRequestRefs>,\n postRouteOptions: RouteOptions<FormRequestPayloadRefs>\n): (ServerRoute<FormRequestRefs> | ServerRoute<FormRequestPayloadRefs>)[] {\n return [\n {\n method: 'get',\n path: '/{slug}/{path}/summary',\n handler: getHandler,\n options: {\n ...getRouteOptions,\n validate: {\n params: Joi.object().keys({\n slug: slugSchema,\n path: pathSchema\n })\n }\n }\n },\n\n {\n method: 'get',\n path: '/preview/{state}/{slug}/{path}/summary',\n handler: getHandler,\n options: {\n ...getRouteOptions,\n validate: {\n params: Joi.object().keys({\n state: stateSchema,\n slug: slugSchema,\n path: pathSchema\n })\n }\n }\n },\n\n {\n method: 'post',\n path: '/{slug}/{path}/summary',\n handler: postHandler,\n options: {\n ...postRouteOptions,\n validate: {\n params: Joi.object().keys({\n slug: slugSchema,\n path: pathSchema\n }),\n payload: Joi.object()\n .keys({\n crumb: crumbSchema,\n action: actionSchema\n })\n .required()\n }\n }\n },\n\n {\n method: 'post',\n path: '/preview/{state}/{slug}/{path}/summary',\n handler: postHandler,\n options: {\n ...postRouteOptions,\n validate: {\n params: Joi.object().keys({\n state: stateSchema,\n slug: slugSchema,\n path: pathSchema\n }),\n payload: Joi.object()\n .keys({\n crumb: crumbSchema,\n action: actionSchema\n })\n .required()\n }\n }\n }\n ]\n}\n"],"mappings":"AAAA;AACA,SAASA,UAAU,QAAQ,oBAAoB;AAC/C,OAAOC,IAAI,MAAM,YAAY;AAM7B,OAAOC,GAAG,MAAM,KAAK;AAErB,SAASC,oBAAoB;AAC7B,SAASC,qBAAqB;AAO9B,SACEC,YAAY,EACZC,WAAW,EACXC,UAAU,EACVC,WAAW;AAGb,SAASC,UAAUA,CACjBC,OAAoB,EACpBC,CAA6C,EAC7C;EACA,MAAM;IAAEC;EAAO,CAAC,GAAGF,OAAO;EAE1B,OAAON,qBAAqB,CAACM,OAAO,EAAEC,CAAC,EAAE,CAACE,IAAI,EAAEC,OAAO,KAAK;IAC1D,IAAI,EAAED,IAAI,YAAYV,oBAAoB,CAAC,EAAE;MAC3C,MAAMF,IAAI,CAACc,QAAQ,CAAC,+BAA+BH,MAAM,CAACI,IAAI,EAAE,CAAC;IACnE;IAEA,OAAOH,IAAI,CAACI,8BAA8B,CAAC,CAAC,CAACP,OAAO,EAAEI,OAAO,EAAEH,CAAC,CAAC;EACnE,CAAC,CAAC;AACJ;AAEA,SAASO,WAAWA,CAClBR,OAA2B,EAC3BC,CAA6C,EAC7C;EACA,MAAM;IAAEC;EAAO,CAAC,GAAGF,OAAO;EAE1B,OAAON,qBAAqB,CAACM,OAAO,EAAEC,CAAC,EAAE,CAACE,IAAI,EAAEC,OAAO,KAAK;IAC1D,MAAM;MAAEK;IAAc,CAAC,GAAGL,OAAO;IAEjC,IAAIK,aAAa,IAAI,EAAEN,IAAI,YAAYV,oBAAoB,CAAC,EAAE;MAC5D,MAAMF,IAAI,CAACc,QAAQ,CAAC,+BAA+BH,MAAM,CAACI,IAAI,EAAE,CAAC;IACnE;IAEA,OAAOH,IAAI,CAACO,+BAA+B,CAAC,CAAC,CAACV,OAAO,EAAEI,OAAO,EAAEH,CAAC,CAAC;EACpE,CAAC,CAAC;AACJ;AAEA,OAAO,SAASU,SAASA,CACvBC,eAA8C,EAC9CC,gBAAsD,EACkB;EACxE,OAAO,CACL;IACEC,MAAM,EAAE,KAAK;IACbR,IAAI,EAAE,wBAAwB;IAC9BS,OAAO,EAAEhB,UAAU;IACnBiB,OAAO,EAAE;MACP,GAAGJ,eAAe;MAClBK,QAAQ,EAAE;QACRf,MAAM,EAAEV,GAAG,CAAC0B,MAAM,CAAC,CAAC,CAACC,IAAI,CAAC;UACxBC,IAAI,EAAE9B,UAAU;UAChBgB,IAAI,EAAET;QACR,CAAC;MACH;IACF;EACF,CAAC,EAED;IACEiB,MAAM,EAAE,KAAK;IACbR,IAAI,EAAE,wCAAwC;IAC9CS,OAAO,EAAEhB,UAAU;IACnBiB,OAAO,EAAE;MACP,GAAGJ,eAAe;MAClBK,QAAQ,EAAE;QACRf,MAAM,EAAEV,GAAG,CAAC0B,MAAM,CAAC,CAAC,CAACC,IAAI,CAAC;UACxBE,KAAK,EAAEvB,WAAW;UAClBsB,IAAI,EAAE9B,UAAU;UAChBgB,IAAI,EAAET;QACR,CAAC;MACH;IACF;EACF,CAAC,EAED;IACEiB,MAAM,EAAE,MAAM;IACdR,IAAI,EAAE,wBAAwB;IAC9BS,OAAO,EAAEP,WAAW;IACpBQ,OAAO,EAAE;MACP,GAAGH,gBAAgB;MACnBI,QAAQ,EAAE;QACRf,MAAM,EAAEV,GAAG,CAAC0B,MAAM,CAAC,CAAC,CAACC,IAAI,CAAC;UACxBC,IAAI,EAAE9B,UAAU;UAChBgB,IAAI,EAAET;QACR,CAAC,CAAC;QACFyB,OAAO,EAAE9B,GAAG,CAAC0B,MAAM,CAAC,CAAC,CAClBC,IAAI,CAAC;UACJI,KAAK,EAAE3B,WAAW;UAClB4B,MAAM,EAAE7B;QACV,CAAC,CAAC,CACD8B,QAAQ,CAAC;MACd;IACF;EACF,CAAC,EAED;IACEX,MAAM,EAAE,MAAM;IACdR,IAAI,EAAE,wCAAwC;IAC9CS,OAAO,EAAEP,WAAW;IACpBQ,OAAO,EAAE;MACP,GAAGH,gBAAgB;MACnBI,QAAQ,EAAE;QACRf,MAAM,EAAEV,GAAG,CAAC0B,MAAM,CAAC,CAAC,CAACC,IAAI,CAAC;UACxBE,KAAK,EAAEvB,WAAW;UAClBsB,IAAI,EAAE9B,UAAU;UAChBgB,IAAI,EAAET;QACR,CAAC,CAAC;QACFyB,OAAO,EAAE9B,GAAG,CAAC0B,MAAM,CAAC,CAAC,CAClBC,IAAI,CAAC;UACJI,KAAK,EAAE3B,WAAW;UAClB4B,MAAM,EAAE7B;QACV,CAAC,CAAC,CACD8B,QAAQ,CAAC;MACd;IACF;EACF,CAAC,CACF;AACH","ignoreList":[]}
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import { type ComponentDef, type Item, type List, type Page } from '@defra/forms-model';
|
|
2
|
+
import { type PluginProperties, type Request } from '@hapi/hapi';
|
|
2
3
|
import { type JoiExpression, type ValidationErrorItem } from 'joi';
|
|
3
4
|
import { type Component } from '~/src/server/plugins/engine/components/helpers.js';
|
|
4
5
|
import { type BackLink, type ComponentText, type ComponentViewModel } from '~/src/server/plugins/engine/components/types.js';
|
|
6
|
+
import { type FormModel } from '~/src/server/plugins/engine/models/index.js';
|
|
5
7
|
import { type PageController } from '~/src/server/plugins/engine/pageControllers/PageController.js';
|
|
6
8
|
import { type PageControllerClass } from '~/src/server/plugins/engine/pageControllers/helpers.js';
|
|
7
9
|
import { type ViewContext } from '~/src/server/plugins/nunjucks/types.js';
|
|
8
|
-
import { type FormAction, type FormRequest } from '~/src/server/routes/types.js';
|
|
10
|
+
import { type FormAction, type FormRequest, type FormRequestPayload } from '~/src/server/routes/types.js';
|
|
11
|
+
import { type Services } from '~/src/server/types.js';
|
|
9
12
|
/**
|
|
10
13
|
* Form submission state stores the following in Redis:
|
|
11
14
|
* Props containing user's submitted values as `{ [inputId]: value }` or as `{ [sectionName]: { [inputName]: value } }`
|
|
@@ -254,3 +257,18 @@ export interface ErrorMessageTemplateList {
|
|
|
254
257
|
baseErrors: ErrorMessageTemplate[];
|
|
255
258
|
advancedSettingsErrors: ErrorMessageTemplate[];
|
|
256
259
|
}
|
|
260
|
+
export interface PluginOptions {
|
|
261
|
+
model?: FormModel;
|
|
262
|
+
services?: Services;
|
|
263
|
+
controllers?: Record<string, typeof PageController>;
|
|
264
|
+
cacheName?: string;
|
|
265
|
+
filters?: Record<string, FilterFunction>;
|
|
266
|
+
keyGenerator?: (request: Request | FormRequest | FormRequestPayload) => string;
|
|
267
|
+
sessionHydrator?: (request: Request | FormRequest | FormRequestPayload) => Promise<FormSubmissionState>;
|
|
268
|
+
pluginPath?: string;
|
|
269
|
+
nunjucks: {
|
|
270
|
+
baseLayoutPath: string;
|
|
271
|
+
paths: string[];
|
|
272
|
+
};
|
|
273
|
+
viewContext: PluginProperties['forms-engine-plugin']['viewContext'];
|
|
274
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","names":["UploadStatus","FileStatus"],"sources":["../../../../src/server/plugins/engine/types.ts"],"sourcesContent":["import {\n type ComponentDef,\n type Item,\n type List,\n type Page\n} from '@defra/forms-model'\nimport { type JoiExpression, type ValidationErrorItem } from 'joi'\n\nimport { FormComponent } from '~/src/server/plugins/engine/components/FormComponent.js'\nimport { type Component } from '~/src/server/plugins/engine/components/helpers.js'\nimport {\n type BackLink,\n type ComponentText,\n type ComponentViewModel\n} from '~/src/server/plugins/engine/components/types.js'\nimport { type PageController } from '~/src/server/plugins/engine/pageControllers/PageController.js'\nimport { type PageControllerClass } from '~/src/server/plugins/engine/pageControllers/helpers.js'\nimport { type ViewContext } from '~/src/server/plugins/nunjucks/types.js'\nimport {
|
|
1
|
+
{"version":3,"file":"types.js","names":["UploadStatus","FileStatus"],"sources":["../../../../src/server/plugins/engine/types.ts"],"sourcesContent":["import {\n type ComponentDef,\n type Item,\n type List,\n type Page\n} from '@defra/forms-model'\nimport { type PluginProperties, type Request } from '@hapi/hapi'\nimport { type JoiExpression, type ValidationErrorItem } from 'joi'\n\nimport { FormComponent } from '~/src/server/plugins/engine/components/FormComponent.js'\nimport { type Component } from '~/src/server/plugins/engine/components/helpers.js'\nimport {\n type BackLink,\n type ComponentText,\n type ComponentViewModel\n} from '~/src/server/plugins/engine/components/types.js'\nimport { type FormModel } from '~/src/server/plugins/engine/models/index.js'\nimport { type PageController } from '~/src/server/plugins/engine/pageControllers/PageController.js'\nimport { type PageControllerClass } from '~/src/server/plugins/engine/pageControllers/helpers.js'\nimport { type ViewContext } from '~/src/server/plugins/nunjucks/types.js'\nimport {\n type FormAction,\n type FormRequest,\n type FormRequestPayload\n} from '~/src/server/routes/types.js'\nimport { type Services } from '~/src/server/types.js'\n\n/**\n * Form submission state stores the following in Redis:\n * Props containing user's submitted values as `{ [inputId]: value }` or as `{ [sectionName]: { [inputName]: value } }`\n * a) . e.g:\n * ```ts\n * {\n * _C9PRHmsgt: 'Ben',\n * WfLk9McjzX: 'Music',\n * IK7jkUFCBL: 'Royal Academy of Music'\n * }\n * ```\n *\n * b)\n * ```ts\n * {\n * checkBeforeYouStart: { ukPassport: true },\n * applicantDetails: {\n * numberOfApplicants: 1,\n * phoneNumber: '77777777',\n * emailAddress: 'aaa@aaa.com'\n * },\n * applicantOneDetails: {\n * firstName: 'a',\n * middleName: 'a',\n * lastName: 'a',\n * address: { addressLine1: 'a', addressLine2: 'a', town: 'a', postcode: 'a' }\n * }\n * }\n * ```\n */\n\n/**\n * Form submission state\n */\nexport type FormSubmissionState = {\n upload?: Record<string, TempFileState>\n} & FormState\n\nexport interface FormSubmissionError\n extends Pick<ValidationErrorItem, 'context' | 'path'> {\n href: string // e.g: '#dateField__day'\n name: string // e.g: 'dateField__day'\n text: string // e.g: 'Date field must be a real date'\n}\n\nexport interface FormParams {\n action?: FormAction\n confirm?: true\n crumb?: string\n itemId?: string\n}\n\n/**\n * Form POST for question pages\n * (after Joi has converted value types)\n */\nexport type FormPayload = FormParams & Partial<Record<string, FormValue>>\n\nexport type FormValue =\n | Item['value']\n | Item['value'][]\n | UploadState\n | RepeatListState\n | undefined\n\nexport type FormState = Partial<Record<string, FormStateValue>>\nexport type FormStateValue = Exclude<FormValue, undefined> | null\n\nexport interface FormValidationResult<\n ValueType extends FormPayload | FormSubmissionState\n> {\n value: ValueType\n errors: FormSubmissionError[] | undefined\n}\n\nexport interface FormContext {\n /**\n * Evaluation form state only (filtered by visited paths),\n * with values formatted for condition evaluation using\n * {@link FormComponent.getContextValueFromState}\n */\n evaluationState: FormState\n\n /**\n * Relevant form state only (filtered by visited paths)\n */\n relevantState: FormState\n\n /**\n * Relevant pages only (filtered by visited paths)\n */\n relevantPages: PageControllerClass[]\n\n /**\n * Form submission payload (single page)\n */\n payload: FormPayload\n\n /**\n * Form submission state (entire form)\n */\n state: FormSubmissionState\n\n /**\n * Validation errors (entire form)\n */\n errors?: FormSubmissionError[]\n\n /**\n * Visited paths evaluated from form state\n */\n paths: string[]\n\n /**\n * Preview URL direct access is allowed\n */\n isForceAccess: boolean\n\n /**\n * Miscellaneous extra data from event responses\n */\n data: object\n\n pageDefMap: Map<string, Page>\n listDefMap: Map<string, List>\n componentDefMap: Map<string, ComponentDef>\n pageMap: Map<string, PageControllerClass>\n componentMap: Map<string, Component>\n referenceNumber: string\n}\n\nexport type FormContextRequest = (\n | {\n method: 'get'\n payload?: undefined\n }\n | {\n method: 'post'\n payload: FormPayload\n }\n | {\n method: FormRequest['method']\n payload?: object | undefined\n }\n) &\n Pick<FormRequest, 'app' | 'method' | 'params' | 'path' | 'query' | 'url'>\n\nexport interface UploadInitiateResponse {\n uploadId: string\n uploadUrl: string\n statusUrl: string\n}\n\nexport enum UploadStatus {\n initiated = 'initiated',\n pending = 'pending',\n ready = 'ready'\n}\n\nexport enum FileStatus {\n complete = 'complete',\n rejected = 'rejected',\n pending = 'pending'\n}\n\nexport type UploadState = FileState[]\n\nexport type FileUpload = {\n fileId: string\n filename: string\n contentLength: number\n} & (\n | {\n fileStatus: FileStatus.complete | FileStatus.rejected | FileStatus.pending\n errorMessage?: string\n }\n | {\n fileStatus: FileStatus.complete\n errorMessage?: undefined\n }\n)\n\nexport interface FileUploadMetadata {\n retrievalKey: string\n}\n\nexport type UploadStatusResponse =\n | {\n uploadStatus: UploadStatus.initiated\n metadata: FileUploadMetadata\n form: { file?: undefined }\n }\n | {\n uploadStatus: UploadStatus.pending | UploadStatus.ready\n metadata: FileUploadMetadata\n form: { file: FileUpload }\n numberOfRejectedFiles?: number\n }\n | {\n uploadStatus: UploadStatus.ready\n metadata: FileUploadMetadata\n form: { file: FileUpload }\n numberOfRejectedFiles: 0\n }\n\nexport type UploadStatusFileResponse = Exclude<\n UploadStatusResponse,\n { uploadStatus: UploadStatus.initiated }\n>\n\nexport interface FileState {\n uploadId: string\n status: UploadStatusFileResponse\n}\n\nexport interface TempFileState {\n upload?: UploadInitiateResponse\n files: UploadState\n}\n\nexport interface RepeatItemState extends FormPayload {\n itemId: string\n}\n\nexport type RepeatListState = RepeatItemState[]\n\nexport interface CheckAnswers {\n title?: ComponentText\n summaryList: SummaryList\n}\n\nexport interface SummaryList {\n classes?: string\n rows: SummaryListRow[]\n}\n\nexport interface SummaryListRow {\n key: ComponentText\n value: ComponentText\n actions?: { items: SummaryListAction[] }\n}\n\nexport type SummaryListAction = ComponentText & {\n href: string\n visuallyHiddenText: string\n}\n\nexport interface PageViewModelBase extends Partial<ViewContext> {\n page: PageController\n name?: string\n pageTitle: string\n sectionTitle?: string\n showTitle: boolean\n isStartPage: boolean\n backLink?: BackLink\n feedbackLink?: string\n serviceUrl: string\n phaseTag?: string\n}\n\nexport interface ItemDeletePageViewModel extends PageViewModelBase {\n context: FormContext\n itemTitle: string\n confirmation?: ComponentText\n buttonConfirm: ComponentText\n buttonCancel: ComponentText\n}\n\nexport interface FormPageViewModel extends PageViewModelBase {\n components: ComponentViewModel[]\n context: FormContext\n errors?: FormSubmissionError[]\n hasMissingNotificationEmail?: boolean\n}\n\nexport interface RepeaterSummaryPageViewModel extends PageViewModelBase {\n context: FormContext\n errors?: FormSubmissionError[]\n checkAnswers: CheckAnswers[]\n repeatTitle: string\n}\n\nexport interface FeaturedFormPageViewModel extends FormPageViewModel {\n formAction?: string\n formComponent: ComponentViewModel\n componentsBefore: ComponentViewModel[]\n uploadId: string | undefined\n proxyUrl: string | null\n}\n\nexport type PageViewModel =\n | PageViewModelBase\n | ItemDeletePageViewModel\n | FormPageViewModel\n | RepeaterSummaryPageViewModel\n | FeaturedFormPageViewModel\n\nexport type FilterFunction = (value: unknown) => unknown\nexport interface ErrorMessageTemplate {\n type: string\n template: JoiExpression\n}\n\nexport interface ErrorMessageTemplateList {\n baseErrors: ErrorMessageTemplate[]\n advancedSettingsErrors: ErrorMessageTemplate[]\n}\n\nexport interface PluginOptions {\n model?: FormModel\n services?: Services\n controllers?: Record<string, typeof PageController>\n cacheName?: string\n filters?: Record<string, FilterFunction>\n keyGenerator?: (request: Request | FormRequest | FormRequestPayload) => string\n sessionHydrator?: (\n request: Request | FormRequest | FormRequestPayload\n ) => Promise<FormSubmissionState>\n pluginPath?: string\n nunjucks: {\n baseLayoutPath: string\n paths: string[]\n }\n viewContext: PluginProperties['forms-engine-plugin']['viewContext']\n}\n"],"mappings":"AA2BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAmBA;AACA;AACA;AACA;;AAkGA,WAAYA,YAAY,0BAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAA,OAAZA,YAAY;AAAA;AAMxB,WAAYC,UAAU,0BAAVA,UAAU;EAAVA,UAAU;EAAVA,UAAU;EAAVA,UAAU;EAAA,OAAVA,UAAU;AAAA","ignoreList":[]}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type Server } from '@hapi/hapi';
|
|
2
|
+
import { type Environment } from 'nunjucks';
|
|
3
|
+
import { type PluginOptions } from '~/src/server/plugins/engine/types.js';
|
|
4
|
+
export declare function registerVision(server: Server, pluginOptions: PluginOptions): Promise<void>;
|
|
5
|
+
interface CompileOptions {
|
|
6
|
+
environment: Environment;
|
|
7
|
+
}
|
|
8
|
+
export interface EngineConfigurationObject {
|
|
9
|
+
compileOptions: CompileOptions;
|
|
10
|
+
}
|
|
11
|
+
export declare function findPackageRoot(): string;
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { existsSync } from 'fs';
|
|
2
|
+
import { dirname, join } from 'path';
|
|
3
|
+
import { fileURLToPath } from 'url';
|
|
4
|
+
import vision from '@hapi/vision';
|
|
5
|
+
import nunjucks from 'nunjucks';
|
|
6
|
+
import resolvePkg from 'resolve';
|
|
7
|
+
import { VIEW_PATH, context, prepareNunjucksEnvironment } from "./index.js";
|
|
8
|
+
export async function registerVision(server, pluginOptions) {
|
|
9
|
+
const packageRoot = findPackageRoot();
|
|
10
|
+
const govukFrontendPath = dirname(resolvePkg.sync('govuk-frontend/package.json'));
|
|
11
|
+
const viewPathResolved = join(packageRoot, VIEW_PATH);
|
|
12
|
+
const paths = [...pluginOptions.nunjucks.paths, viewPathResolved, join(govukFrontendPath, 'dist')];
|
|
13
|
+
await server.register({
|
|
14
|
+
plugin: vision,
|
|
15
|
+
options: {
|
|
16
|
+
engines: {
|
|
17
|
+
html: {
|
|
18
|
+
compile: (path, compileOptions) => {
|
|
19
|
+
const template = nunjucks.compile(path, compileOptions.environment);
|
|
20
|
+
return context => {
|
|
21
|
+
return template.render(context);
|
|
22
|
+
};
|
|
23
|
+
},
|
|
24
|
+
prepare: (options, next) => {
|
|
25
|
+
// Nunjucks also needs an additional path configuration
|
|
26
|
+
// to use the templates and macros from `govuk-frontend`
|
|
27
|
+
const environment = nunjucks.configure(paths);
|
|
28
|
+
|
|
29
|
+
// Applies custom filters and globals for nunjucks
|
|
30
|
+
// that are required by the `forms-engine-plugin`
|
|
31
|
+
prepareNunjucksEnvironment(environment, pluginOptions.filters);
|
|
32
|
+
options.compileOptions.environment = environment;
|
|
33
|
+
next();
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
path: paths,
|
|
38
|
+
// Provides global context used with all templates
|
|
39
|
+
context
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
export function findPackageRoot() {
|
|
44
|
+
const currentFileName = fileURLToPath(import.meta.url);
|
|
45
|
+
const currentDirectoryName = dirname(currentFileName);
|
|
46
|
+
let dir = currentDirectoryName;
|
|
47
|
+
while (dir !== '/') {
|
|
48
|
+
if (existsSync(join(dir, 'package.json'))) {
|
|
49
|
+
return dir;
|
|
50
|
+
}
|
|
51
|
+
dir = dirname(dir);
|
|
52
|
+
}
|
|
53
|
+
throw new Error('package.json not found in parent directories');
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=vision.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vision.js","names":["existsSync","dirname","join","fileURLToPath","vision","nunjucks","resolvePkg","VIEW_PATH","context","prepareNunjucksEnvironment","registerVision","server","pluginOptions","packageRoot","findPackageRoot","govukFrontendPath","sync","viewPathResolved","paths","register","plugin","options","engines","html","compile","path","compileOptions","template","environment","render","prepare","next","configure","filters","currentFileName","import","meta","url","currentDirectoryName","dir","Error"],"sources":["../../../../src/server/plugins/engine/vision.ts"],"sourcesContent":["import { existsSync } from 'fs'\nimport { dirname, join } from 'path'\nimport { fileURLToPath } from 'url'\n\nimport { type Server } from '@hapi/hapi'\nimport vision from '@hapi/vision'\nimport nunjucks, { type Environment } from 'nunjucks'\nimport resolvePkg from 'resolve'\n\nimport {\n VIEW_PATH,\n context,\n prepareNunjucksEnvironment\n} from '~/src/server/plugins/engine/index.js'\nimport { type PluginOptions } from '~/src/server/plugins/engine/types.js'\n\nexport async function registerVision(\n server: Server,\n pluginOptions: PluginOptions\n) {\n const packageRoot = findPackageRoot()\n const govukFrontendPath = dirname(\n resolvePkg.sync('govuk-frontend/package.json')\n )\n\n const viewPathResolved = join(packageRoot, VIEW_PATH)\n\n const paths = [\n ...pluginOptions.nunjucks.paths,\n viewPathResolved,\n join(govukFrontendPath, 'dist')\n ]\n\n await server.register({\n plugin: vision,\n options: {\n engines: {\n html: {\n compile: (\n path: string,\n compileOptions: { environment: Environment }\n ) => {\n const template = nunjucks.compile(path, compileOptions.environment)\n\n return (context: object | undefined) => {\n return template.render(context)\n }\n },\n prepare: (\n options: EngineConfigurationObject,\n next: (err?: Error) => void\n ) => {\n // Nunjucks also needs an additional path configuration\n // to use the templates and macros from `govuk-frontend`\n const environment = nunjucks.configure(paths)\n\n // Applies custom filters and globals for nunjucks\n // that are required by the `forms-engine-plugin`\n prepareNunjucksEnvironment(environment, pluginOptions.filters)\n\n options.compileOptions.environment = environment\n\n next()\n }\n }\n },\n path: paths,\n // Provides global context used with all templates\n context\n }\n })\n}\n\ninterface CompileOptions {\n environment: Environment\n}\n\nexport interface EngineConfigurationObject {\n compileOptions: CompileOptions\n}\n\nexport function findPackageRoot() {\n const currentFileName = fileURLToPath(import.meta.url)\n const currentDirectoryName = dirname(currentFileName)\n\n let dir = currentDirectoryName\n while (dir !== '/') {\n if (existsSync(join(dir, 'package.json'))) {\n return dir\n }\n dir = dirname(dir)\n }\n\n throw new Error('package.json not found in parent directories')\n}\n"],"mappings":"AAAA,SAASA,UAAU,QAAQ,IAAI;AAC/B,SAASC,OAAO,EAAEC,IAAI,QAAQ,MAAM;AACpC,SAASC,aAAa,QAAQ,KAAK;AAGnC,OAAOC,MAAM,MAAM,cAAc;AACjC,OAAOC,QAAQ,MAA4B,UAAU;AACrD,OAAOC,UAAU,MAAM,SAAS;AAEhC,SACEC,SAAS,EACTC,OAAO,EACPC,0BAA0B;AAI5B,OAAO,eAAeC,cAAcA,CAClCC,MAAc,EACdC,aAA4B,EAC5B;EACA,MAAMC,WAAW,GAAGC,eAAe,CAAC,CAAC;EACrC,MAAMC,iBAAiB,GAAGd,OAAO,CAC/BK,UAAU,CAACU,IAAI,CAAC,6BAA6B,CAC/C,CAAC;EAED,MAAMC,gBAAgB,GAAGf,IAAI,CAACW,WAAW,EAAEN,SAAS,CAAC;EAErD,MAAMW,KAAK,GAAG,CACZ,GAAGN,aAAa,CAACP,QAAQ,CAACa,KAAK,EAC/BD,gBAAgB,EAChBf,IAAI,CAACa,iBAAiB,EAAE,MAAM,CAAC,CAChC;EAED,MAAMJ,MAAM,CAACQ,QAAQ,CAAC;IACpBC,MAAM,EAAEhB,MAAM;IACdiB,OAAO,EAAE;MACPC,OAAO,EAAE;QACPC,IAAI,EAAE;UACJC,OAAO,EAAEA,CACPC,IAAY,EACZC,cAA4C,KACzC;YACH,MAAMC,QAAQ,GAAGtB,QAAQ,CAACmB,OAAO,CAACC,IAAI,EAAEC,cAAc,CAACE,WAAW,CAAC;YAEnE,OAAQpB,OAA2B,IAAK;cACtC,OAAOmB,QAAQ,CAACE,MAAM,CAACrB,OAAO,CAAC;YACjC,CAAC;UACH,CAAC;UACDsB,OAAO,EAAEA,CACPT,OAAkC,EAClCU,IAA2B,KACxB;YACH;YACA;YACA,MAAMH,WAAW,GAAGvB,QAAQ,CAAC2B,SAAS,CAACd,KAAK,CAAC;;YAE7C;YACA;YACAT,0BAA0B,CAACmB,WAAW,EAAEhB,aAAa,CAACqB,OAAO,CAAC;YAE9DZ,OAAO,CAACK,cAAc,CAACE,WAAW,GAAGA,WAAW;YAEhDG,IAAI,CAAC,CAAC;UACR;QACF;MACF,CAAC;MACDN,IAAI,EAAEP,KAAK;MACX;MACAV;IACF;EACF,CAAC,CAAC;AACJ;AAUA,OAAO,SAASM,eAAeA,CAAA,EAAG;EAChC,MAAMoB,eAAe,GAAG/B,aAAa,CAACgC,MAAM,CAACC,IAAI,CAACC,GAAG,CAAC;EACtD,MAAMC,oBAAoB,GAAGrC,OAAO,CAACiC,eAAe,CAAC;EAErD,IAAIK,GAAG,GAAGD,oBAAoB;EAC9B,OAAOC,GAAG,KAAK,GAAG,EAAE;IAClB,IAAIvC,UAAU,CAACE,IAAI,CAACqC,GAAG,EAAE,cAAc,CAAC,CAAC,EAAE;MACzC,OAAOA,GAAG;IACZ;IACAA,GAAG,GAAGtC,OAAO,CAACsC,GAAG,CAAC;EACpB;EAEA,MAAM,IAAIC,KAAK,CAAC,8CAA8C,CAAC;AACjE","ignoreList":[]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type Request, type Server } from '@hapi/hapi';
|
|
2
2
|
import { type FormPayload, type FormState, type FormSubmissionError, type FormSubmissionState } from '~/src/server/plugins/engine/types.js';
|
|
3
3
|
import { type FormRequest, type FormRequestPayload } from '~/src/server/routes/types.js';
|
|
4
|
-
declare enum ADDITIONAL_IDENTIFIER {
|
|
4
|
+
export declare enum ADDITIONAL_IDENTIFIER {
|
|
5
5
|
Confirmation = ":confirmation"
|
|
6
6
|
}
|
|
7
7
|
export declare class CacheService {
|
|
@@ -12,8 +12,17 @@ export declare class CacheService {
|
|
|
12
12
|
cache: string | undefined;
|
|
13
13
|
segment: string;
|
|
14
14
|
}>;
|
|
15
|
+
generateKey?: (request: Request | FormRequest | FormRequestPayload) => string;
|
|
16
|
+
customFetcher?: (request: Request | FormRequest | FormRequestPayload) => Promise<FormSubmissionState | null>;
|
|
15
17
|
logger: Server['logger'];
|
|
16
|
-
constructor(server
|
|
18
|
+
constructor({ server, cacheName, options }: {
|
|
19
|
+
server: Server;
|
|
20
|
+
cacheName?: string;
|
|
21
|
+
options?: {
|
|
22
|
+
keyGenerator?: (request: Request | FormRequest | FormRequestPayload) => string;
|
|
23
|
+
sessionHydrator?: (request: Request | FormRequest | FormRequestPayload) => Promise<FormSubmissionState | null>;
|
|
24
|
+
};
|
|
25
|
+
});
|
|
17
26
|
getState(request: Request | FormRequest | FormRequestPayload): Promise<FormSubmissionState>;
|
|
18
27
|
setState(request: FormRequest | FormRequestPayload, state: FormSubmissionState): Promise<FormSubmissionState>;
|
|
19
28
|
getConfirmationState(request: FormRequest | FormRequestPayload): Promise<{
|
|
@@ -29,6 +38,7 @@ export declare class CacheService {
|
|
|
29
38
|
setFlash(request: FormRequest | FormRequestPayload, message: {
|
|
30
39
|
errors: FormSubmissionError[];
|
|
31
40
|
}): void;
|
|
41
|
+
private defaultKeyGenerator;
|
|
32
42
|
/**
|
|
33
43
|
* The key used to store user session data against.
|
|
34
44
|
* If there are multiple forms on the same runner instance, for example `form-a` and `form-a-feedback` this will prevent CacheService from clearing data from `form-a` if a user gave feedback before they finished `form-a`
|
|
@@ -46,4 +56,3 @@ export declare class CacheService {
|
|
|
46
56
|
* 2. Overwrites arrays
|
|
47
57
|
*/
|
|
48
58
|
export declare function merge<StateType extends FormState | FormPayload>(state: StateType, update: object): StateType;
|
|
49
|
-
export {};
|
|
@@ -1,20 +1,32 @@
|
|
|
1
1
|
import * as Hoek from '@hapi/hoek';
|
|
2
2
|
import { config } from "../../config/index.js";
|
|
3
3
|
const partition = 'cache';
|
|
4
|
-
|
|
4
|
+
export let ADDITIONAL_IDENTIFIER = /*#__PURE__*/function (ADDITIONAL_IDENTIFIER) {
|
|
5
5
|
ADDITIONAL_IDENTIFIER["Confirmation"] = ":confirmation";
|
|
6
6
|
return ADDITIONAL_IDENTIFIER;
|
|
7
|
-
}(
|
|
7
|
+
}({});
|
|
8
8
|
export class CacheService {
|
|
9
9
|
/**
|
|
10
10
|
* This service is responsible for getting, storing or deleting a user's session data in the cache. This service has been registered by {@link createServer}
|
|
11
11
|
*/
|
|
12
12
|
cache;
|
|
13
|
+
generateKey;
|
|
14
|
+
customFetcher;
|
|
13
15
|
logger;
|
|
14
|
-
constructor(
|
|
16
|
+
constructor({
|
|
17
|
+
server,
|
|
18
|
+
cacheName,
|
|
19
|
+
options
|
|
20
|
+
}) {
|
|
21
|
+
const {
|
|
22
|
+
keyGenerator,
|
|
23
|
+
sessionHydrator
|
|
24
|
+
} = options ?? {};
|
|
15
25
|
if (!cacheName) {
|
|
16
26
|
server.log('warn', 'You are using the default hapi cache. Please provide a cache name in plugin registration options.');
|
|
17
27
|
}
|
|
28
|
+
this.generateKey = keyGenerator ?? this.defaultKeyGenerator.bind(this);
|
|
29
|
+
this.customFetcher = sessionHydrator ?? undefined;
|
|
18
30
|
this.cache = server.cache({
|
|
19
31
|
cache: cacheName,
|
|
20
32
|
segment: 'formSubmission'
|
|
@@ -22,7 +34,16 @@ export class CacheService {
|
|
|
22
34
|
this.logger = server.logger;
|
|
23
35
|
}
|
|
24
36
|
async getState(request) {
|
|
25
|
-
|
|
37
|
+
let cached = await this.cache.get(this.Key(request));
|
|
38
|
+
|
|
39
|
+
// If nothing in Redis, attempt to rehydrate from backend DB
|
|
40
|
+
if (!cached && this.customFetcher) {
|
|
41
|
+
const rehydrated = await this.customFetcher(request);
|
|
42
|
+
if (rehydrated != null) {
|
|
43
|
+
await this.cache.set(this.Key(request), rehydrated, config.get('sessionTimeout'));
|
|
44
|
+
cached = await this.getState(request);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
26
47
|
return cached ?? {};
|
|
27
48
|
}
|
|
28
49
|
async setState(request, state) {
|
|
@@ -57,6 +78,14 @@ export class CacheService {
|
|
|
57
78
|
const key = this.Key(request);
|
|
58
79
|
request.yar.flash(key.id, message);
|
|
59
80
|
}
|
|
81
|
+
defaultKeyGenerator(request) {
|
|
82
|
+
if (!request.yar.id) {
|
|
83
|
+
throw new Error('No session ID found');
|
|
84
|
+
}
|
|
85
|
+
const state = request.params.state ?? '';
|
|
86
|
+
const slug = request.params.slug ?? '';
|
|
87
|
+
return `${request.yar.id}:${state}:${slug}:`;
|
|
88
|
+
}
|
|
60
89
|
|
|
61
90
|
/**
|
|
62
91
|
* The key used to store user session data against.
|
|
@@ -65,12 +94,10 @@ export class CacheService {
|
|
|
65
94
|
* @param additionalIdentifier - appended to the id
|
|
66
95
|
*/
|
|
67
96
|
Key(request, additionalIdentifier) {
|
|
68
|
-
|
|
69
|
-
throw Error('No session ID found');
|
|
70
|
-
}
|
|
97
|
+
const baseKey = this.generateKey ? this.generateKey(request) : this.defaultKeyGenerator(request);
|
|
71
98
|
return {
|
|
72
99
|
segment: partition,
|
|
73
|
-
id: `${
|
|
100
|
+
id: `${baseKey}${additionalIdentifier ?? ''}`
|
|
74
101
|
};
|
|
75
102
|
}
|
|
76
103
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cacheService.js","names":["Hoek","config","partition","ADDITIONAL_IDENTIFIER","CacheService","cache","logger","constructor","server","cacheName","log","segment","getState","request","cached","get","Key","setState","state","key","ttl","
|
|
1
|
+
{"version":3,"file":"cacheService.js","names":["Hoek","config","partition","ADDITIONAL_IDENTIFIER","CacheService","cache","generateKey","customFetcher","logger","constructor","server","cacheName","options","keyGenerator","sessionHydrator","log","defaultKeyGenerator","bind","undefined","segment","getState","request","cached","get","Key","rehydrated","set","setState","state","key","ttl","getConfirmationState","Confirmation","value","setConfirmationState","confirmationState","clearState","yar","id","drop","getFlash","messages","flash","Array","isArray","length","at","setFlash","message","Error","params","slug","additionalIdentifier","baseKey","merge","update","mergeArrays"],"sources":["../../../src/server/services/cacheService.ts"],"sourcesContent":["import { type Request, type Server } from '@hapi/hapi'\nimport * as Hoek from '@hapi/hoek'\n\nimport { config } from '~/src/config/index.js'\nimport { type createServer } from '~/src/server/index.js'\nimport {\n type FormPayload,\n type FormState,\n type FormSubmissionError,\n type FormSubmissionState\n} from '~/src/server/plugins/engine/types.js'\nimport {\n type FormRequest,\n type FormRequestPayload\n} from '~/src/server/routes/types.js'\n\nconst partition = 'cache'\n\nexport enum ADDITIONAL_IDENTIFIER {\n Confirmation = ':confirmation'\n}\n\nexport class CacheService {\n /**\n * This service is responsible for getting, storing or deleting a user's session data in the cache. This service has been registered by {@link createServer}\n */\n cache\n generateKey?: (request: Request | FormRequest | FormRequestPayload) => string\n customFetcher?: (\n request: Request | FormRequest | FormRequestPayload\n ) => Promise<FormSubmissionState | null>\n\n logger: Server['logger']\n\n constructor({\n server,\n cacheName,\n options\n }: {\n server: Server\n cacheName?: string\n options?: {\n keyGenerator?: (\n request: Request | FormRequest | FormRequestPayload\n ) => string\n sessionHydrator?: (\n request: Request | FormRequest | FormRequestPayload\n ) => Promise<FormSubmissionState | null>\n }\n }) {\n const { keyGenerator, sessionHydrator } = options ?? {}\n if (!cacheName) {\n server.log(\n 'warn',\n 'You are using the default hapi cache. Please provide a cache name in plugin registration options.'\n )\n }\n this.generateKey = keyGenerator ?? this.defaultKeyGenerator.bind(this)\n this.customFetcher = sessionHydrator ?? undefined\n this.cache = server.cache({ cache: cacheName, segment: 'formSubmission' })\n this.logger = server.logger\n }\n\n async getState(\n request: Request | FormRequest | FormRequestPayload\n ): Promise<FormSubmissionState> {\n let cached = await this.cache.get(this.Key(request))\n\n // If nothing in Redis, attempt to rehydrate from backend DB\n if (!cached && this.customFetcher) {\n const rehydrated = await this.customFetcher(request)\n\n if (rehydrated != null) {\n await this.cache.set(\n this.Key(request),\n rehydrated,\n config.get('sessionTimeout')\n )\n cached = await this.getState(request)\n }\n }\n\n return cached ?? {}\n }\n\n async setState(\n request: FormRequest | FormRequestPayload,\n state: FormSubmissionState\n ) {\n const key = this.Key(request)\n const ttl = config.get('sessionTimeout')\n\n await this.cache.set(key, state, ttl)\n return this.getState(request)\n }\n\n async getConfirmationState(\n request: FormRequest | FormRequestPayload\n ): Promise<{ confirmed?: true }> {\n const key = this.Key(request, ADDITIONAL_IDENTIFIER.Confirmation)\n const value = await this.cache.get(key)\n\n return value ?? {}\n }\n\n async setConfirmationState(\n request: FormRequest | FormRequestPayload,\n confirmationState: { confirmed?: true }\n ) {\n const key = this.Key(request, ADDITIONAL_IDENTIFIER.Confirmation)\n const ttl = config.get('confirmationSessionTimeout')\n\n return this.cache.set(key, confirmationState, ttl)\n }\n\n async clearState(request: FormRequest | FormRequestPayload) {\n if (request.yar.id) {\n await this.cache.drop(this.Key(request))\n }\n }\n\n getFlash(\n request: FormRequest | FormRequestPayload\n ): { errors: FormSubmissionError[] } | undefined {\n const key = this.Key(request)\n const messages = request.yar.flash(key.id)\n\n if (Array.isArray(messages) && messages.length) {\n return messages.at(0) as { errors: FormSubmissionError[] }\n }\n }\n\n setFlash(\n request: FormRequest | FormRequestPayload,\n message: { errors: FormSubmissionError[] }\n ) {\n const key = this.Key(request)\n\n request.yar.flash(key.id, message)\n }\n\n private defaultKeyGenerator(\n request: Request | FormRequest | FormRequestPayload\n ): string {\n if (!request.yar.id) {\n throw new Error('No session ID found')\n }\n\n const state = request.params.state ?? ''\n const slug = request.params.slug ?? ''\n return `${request.yar.id}:${state}:${slug}:`\n }\n\n /**\n * The key used to store user session data against.\n * If there are multiple forms on the same runner instance, for example `form-a` and `form-a-feedback` this will prevent CacheService from clearing data from `form-a` if a user gave feedback before they finished `form-a`\n * @param request - hapi request object\n * @param additionalIdentifier - appended to the id\n */\n Key(\n request: Request | FormRequest | FormRequestPayload,\n additionalIdentifier?: ADDITIONAL_IDENTIFIER\n ) {\n const baseKey = this.generateKey\n ? this.generateKey(request)\n : this.defaultKeyGenerator(request)\n\n return {\n segment: partition,\n id: `${baseKey}${additionalIdentifier ?? ''}`\n }\n }\n}\n\n/**\n * State merge helper\n * 1. Merges objects (form fields)\n * 2. Overwrites arrays\n */\nexport function merge<StateType extends FormState | FormPayload>(\n state: StateType,\n update: object\n): StateType {\n return Hoek.merge(state, update, {\n mergeArrays: false\n })\n}\n"],"mappings":"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","ignoreList":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@defra/forms-engine-plugin",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "Defra forms engine",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
},
|
|
56
56
|
"repository": {
|
|
57
57
|
"type": "git",
|
|
58
|
-
"url": "https://github.com/DEFRA/forms-engine-plugin"
|
|
58
|
+
"url": "git+https://github.com/DEFRA/forms-engine-plugin.git"
|
|
59
59
|
},
|
|
60
60
|
"engines": {
|
|
61
61
|
"node": "^22.11.0",
|
|
@@ -106,7 +106,7 @@
|
|
|
106
106
|
"pino-pretty": "^13.0.0",
|
|
107
107
|
"proxy-agent": "^6.5.0",
|
|
108
108
|
"resolve": "^1.22.10",
|
|
109
|
-
"yaml": "^2.
|
|
109
|
+
"yaml": "^2.8.0"
|
|
110
110
|
},
|
|
111
111
|
"devDependencies": {
|
|
112
112
|
"@babel/cli": "^7.28.0",
|