@defra/forms-engine-plugin 0.1.10 → 0.1.11
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/.public/stylesheets/application.min.css +1 -1
- package/.public/stylesheets/application.min.css.map +1 -1
- package/.server/client/stylesheets/application.scss +10 -0
- package/.server/config/index.js +3 -14
- package/.server/config/index.js.map +1 -1
- package/.server/server/devserver/dxt-devtool-baselayout.html +71 -0
- package/.server/server/forms/register-as-a-unicorn-breeder.json +393 -0
- package/.server/server/forms/register-as-a-unicorn-breeder.yaml +251 -0
- package/.server/server/index.js +11 -16
- package/.server/server/index.js.map +1 -1
- package/.server/server/plugins/engine/configureEnginePlugin.js +16 -2
- package/.server/server/plugins/engine/configureEnginePlugin.js.map +1 -1
- package/.server/server/plugins/engine/plugin.js +27 -16
- package/.server/server/plugins/engine/plugin.js.map +1 -1
- package/.server/server/plugins/engine/services/formsService.js +15 -29
- package/.server/server/plugins/engine/services/formsService.js.map +1 -1
- package/.server/server/plugins/engine/services/localFormsService.js +52 -0
- package/.server/server/plugins/engine/services/localFormsService.js.map +1 -0
- package/.server/server/plugins/engine/views/confirmation.html +1 -1
- package/.server/server/plugins/engine/views/file-upload.html +1 -1
- package/.server/server/plugins/engine/views/index.html +1 -1
- package/.server/server/plugins/engine/views/item-delete.html +1 -1
- package/.server/server/plugins/engine/views/repeat-list-summary.html +1 -1
- package/.server/server/plugins/engine/views/summary.html +1 -1
- package/.server/server/plugins/errorPages.js +4 -26
- package/.server/server/plugins/errorPages.js.map +1 -1
- package/.server/server/plugins/nunjucks/context.js +37 -28
- package/.server/server/plugins/nunjucks/context.js.map +1 -1
- package/.server/server/plugins/nunjucks/context.test.js +23 -28
- package/.server/server/plugins/nunjucks/context.test.js.map +1 -1
- package/.server/server/plugins/nunjucks/types.js +3 -4
- package/.server/server/plugins/nunjucks/types.js.map +1 -1
- package/.server/server/routes/index.js +0 -1
- package/.server/server/routes/index.js.map +1 -1
- package/.server/typings/hapi/index.d.js.map +1 -1
- package/package.json +2 -1
- package/src/client/stylesheets/application.scss +10 -0
- package/src/config/index.ts +4 -17
- package/src/server/devserver/dxt-devtool-baselayout.html +71 -0
- package/src/server/forms/register-as-a-unicorn-breeder.json +393 -0
- package/src/server/forms/register-as-a-unicorn-breeder.yaml +251 -0
- package/src/server/index.test.ts +4 -37
- package/src/server/index.ts +13 -16
- package/src/server/plugins/engine/configureEnginePlugin.ts +19 -1
- package/src/server/plugins/engine/plugin.ts +43 -17
- package/src/server/plugins/engine/services/formsService.js +17 -35
- package/src/server/plugins/engine/services/localFormsService.js +49 -0
- package/src/server/plugins/engine/views/confirmation.html +1 -1
- package/src/server/plugins/engine/views/file-upload.html +1 -1
- package/src/server/plugins/engine/views/index.html +1 -1
- package/src/server/plugins/engine/views/item-delete.html +1 -1
- package/src/server/plugins/engine/views/repeat-list-summary.html +1 -1
- package/src/server/plugins/engine/views/summary.html +1 -1
- package/src/server/plugins/errorPages.ts +4 -26
- package/src/server/plugins/nunjucks/context.js +41 -31
- package/src/server/plugins/nunjucks/context.test.js +24 -27
- package/src/server/plugins/nunjucks/types.js +3 -4
- package/src/server/routes/index.ts +0 -1
- package/src/typings/hapi/index.d.ts +3 -9
- package/.server/common/cookies.js +0 -55
- package/.server/common/cookies.js.map +0 -1
- package/.server/common/cookies.test.js +0 -15
- package/.server/common/cookies.test.js.map +0 -1
- package/.server/common/types.js +0 -6
- package/.server/common/types.js.map +0 -1
- package/.server/server/forms/README.md +0 -10
- package/.server/server/forms/report-a-terrorist.json +0 -270
- package/.server/server/forms/runner-components-test.json +0 -365
- package/.server/server/forms/test.json +0 -581
- package/.server/server/forms/test.yaml +0 -363
- package/.server/server/plugins/blankie.js +0 -29
- package/.server/server/plugins/blankie.js.map +0 -1
- package/.server/server/plugins/engine/services/formsService.test.js +0 -71
- package/.server/server/plugins/engine/services/formsService.test.js.map +0 -1
- package/.server/server/plugins/engine/views/layout.html +0 -199
- package/.server/server/plugins/router.js +0 -169
- package/.server/server/plugins/router.js.map +0 -1
- package/.server/server/routes/health.js +0 -15
- package/.server/server/routes/health.js.map +0 -1
- package/.server/server/routes/health.test.js +0 -32
- package/.server/server/routes/health.test.js.map +0 -1
- package/.server/server/utils/file-form-service.test.js +0 -52
- package/.server/server/utils/file-form-service.test.js.map +0 -1
- package/.server/server/views/404.html +0 -16
- package/.server/server/views/500.html +0 -19
- package/.server/server/views/help/accessibility-statement.html +0 -58
- package/.server/server/views/help/cookie-preferences.html +0 -57
- package/.server/server/views/help/cookies.html +0 -71
- package/.server/server/views/help/get-support.html +0 -37
- package/.server/server/views/help/privacy-notice.html +0 -68
- package/.server/server/views/help/terms-and-conditions.html +0 -83
- package/src/common/cookies.js +0 -58
- package/src/common/cookies.test.js +0 -23
- package/src/common/types.js +0 -5
- package/src/server/forms/README.md +0 -10
- package/src/server/forms/report-a-terrorist.json +0 -270
- package/src/server/forms/runner-components-test.json +0 -365
- package/src/server/forms/test.json +0 -581
- package/src/server/forms/test.yaml +0 -363
- package/src/server/plugins/blankie.test.ts +0 -73
- package/src/server/plugins/blankie.ts +0 -48
- package/src/server/plugins/engine/services/formsService.test.js +0 -90
- package/src/server/plugins/engine/views/layout.html +0 -199
- package/src/server/plugins/router.ts +0 -201
- package/src/server/routes/health.js +0 -13
- package/src/server/routes/health.test.js +0 -35
- package/src/server/routes/index.test.ts +0 -125
- package/src/server/utils/file-form-service.test.js +0 -79
- package/src/server/views/404.html +0 -16
- package/src/server/views/500.html +0 -19
- package/src/server/views/help/accessibility-statement.html +0 -58
- package/src/server/views/help/cookie-preferences.html +0 -57
- package/src/server/views/help/cookies.html +0 -71
- package/src/server/views/help/get-support.html +0 -37
- package/src/server/views/help/privacy-notice.html +0 -68
- package/src/server/views/help/terms-and-conditions.html +0 -83
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Register as a unicorn breeder
|
|
3
|
+
pages:
|
|
4
|
+
- path: '/whats-your-name'
|
|
5
|
+
title: What's your name?
|
|
6
|
+
components:
|
|
7
|
+
- type: TextField
|
|
8
|
+
name: textField
|
|
9
|
+
title: Name
|
|
10
|
+
hint:
|
|
11
|
+
This is a single line text box. We use it to ask for information that's
|
|
12
|
+
likely to be 1 sentence
|
|
13
|
+
options:
|
|
14
|
+
required: true
|
|
15
|
+
schema: {}
|
|
16
|
+
next:
|
|
17
|
+
- path: '/whats-your-email-address'
|
|
18
|
+
section: section
|
|
19
|
+
- title: Summary
|
|
20
|
+
path: '/summary'
|
|
21
|
+
controller: './pages/summary.js'
|
|
22
|
+
components: []
|
|
23
|
+
next: []
|
|
24
|
+
- path: '/whats-your-email-address'
|
|
25
|
+
title: What's your email address?
|
|
26
|
+
components:
|
|
27
|
+
- name: MaTzaT
|
|
28
|
+
options:
|
|
29
|
+
required: true
|
|
30
|
+
type: EmailAddressField
|
|
31
|
+
title: Email adress
|
|
32
|
+
schema: {}
|
|
33
|
+
hint: This is an email address. An email address must contain an at sign @
|
|
34
|
+
next:
|
|
35
|
+
- path: '/whats-your-phone-number'
|
|
36
|
+
section: section
|
|
37
|
+
- path: '/whats-your-phone-number'
|
|
38
|
+
title: What's your phone number?
|
|
39
|
+
components:
|
|
40
|
+
- name: BdKgCe
|
|
41
|
+
options:
|
|
42
|
+
required: true
|
|
43
|
+
type: TelephoneNumberField
|
|
44
|
+
title: Phone number
|
|
45
|
+
schema: {}
|
|
46
|
+
hint:
|
|
47
|
+
This is a telephone number. This field can only contain numbers and the
|
|
48
|
+
+ symbol
|
|
49
|
+
next:
|
|
50
|
+
- path: '/whats-your-address'
|
|
51
|
+
section: section
|
|
52
|
+
- path: '/whats-your-address'
|
|
53
|
+
title: What's your address?
|
|
54
|
+
components:
|
|
55
|
+
- name: wZLWPy
|
|
56
|
+
options:
|
|
57
|
+
required: true
|
|
58
|
+
type: UkAddressField
|
|
59
|
+
title: Address
|
|
60
|
+
schema: {}
|
|
61
|
+
hint: This is a UK address. Users must enter address line 1, town and a postcode
|
|
62
|
+
next:
|
|
63
|
+
- path: '/do-you-want-your-unicorn-breeder-certificate-sent-to-this-address'
|
|
64
|
+
section: section
|
|
65
|
+
- path: '/do-you-want-your-unicorn-breeder-certificate-sent-to-this-address'
|
|
66
|
+
title: Do you want your unicorn breeder certificate sent to this address?
|
|
67
|
+
components:
|
|
68
|
+
- name: dBfuID
|
|
69
|
+
options: {}
|
|
70
|
+
type: YesNoField
|
|
71
|
+
title: Send certificate to same address
|
|
72
|
+
schema: {}
|
|
73
|
+
hint:
|
|
74
|
+
This is a yes or no question. We can branch to different questions based
|
|
75
|
+
on the answer
|
|
76
|
+
values:
|
|
77
|
+
type: listRef
|
|
78
|
+
next:
|
|
79
|
+
- path: '/what-address-do-you-want-the-certificate-sent-to'
|
|
80
|
+
condition: oyGPwP
|
|
81
|
+
- path: '/when-does-your-unicorn-insurance-policy-start'
|
|
82
|
+
condition: ''
|
|
83
|
+
section: section
|
|
84
|
+
- path: '/what-address-do-you-want-the-certificate-sent-to'
|
|
85
|
+
title: What address do you want the certificate sent to?
|
|
86
|
+
components:
|
|
87
|
+
- name: AegFro
|
|
88
|
+
options: {}
|
|
89
|
+
type: UkAddressField
|
|
90
|
+
title: Address to send certificate
|
|
91
|
+
schema: {}
|
|
92
|
+
hint:
|
|
93
|
+
This is a simple branch to an extra question - it's shown to users who select
|
|
94
|
+
'no' when asked if this is the address where the certificate should be sent
|
|
95
|
+
next:
|
|
96
|
+
- path: '/when-does-your-unicorn-insurance-policy-start'
|
|
97
|
+
section: section
|
|
98
|
+
- title: When does your unicorn insurance policy start?
|
|
99
|
+
path: '/when-does-your-unicorn-insurance-policy-start'
|
|
100
|
+
section: Regnsa
|
|
101
|
+
next:
|
|
102
|
+
- path: '/upload-your-insurance-certificate'
|
|
103
|
+
components:
|
|
104
|
+
- name: mjAccr
|
|
105
|
+
options: {}
|
|
106
|
+
type: DatePartsField
|
|
107
|
+
title: Unicorn insurance policy start date
|
|
108
|
+
schema: {}
|
|
109
|
+
hint:
|
|
110
|
+
This is a date. We can add custom validation to the field based on your
|
|
111
|
+
requirements. For example, the date entered must be before or after a certain
|
|
112
|
+
date
|
|
113
|
+
- title: How many unicorns do you expect to breed each year?
|
|
114
|
+
path: '/how-many-unicorns-do-you-expect-to-breed-each-year'
|
|
115
|
+
section: susaYr
|
|
116
|
+
next:
|
|
117
|
+
- path: '/what-type-of-unicorns-will-you-breed'
|
|
118
|
+
components:
|
|
119
|
+
- name: aitzzV
|
|
120
|
+
options: {}
|
|
121
|
+
type: RadiosField
|
|
122
|
+
list: IeFOkf
|
|
123
|
+
title: Number of unicorns
|
|
124
|
+
schema: {}
|
|
125
|
+
hint: This is a radio button. Users can only select one option from the list
|
|
126
|
+
values:
|
|
127
|
+
type: listRef
|
|
128
|
+
- title: What type of unicorns will you breed?
|
|
129
|
+
path: '/what-type-of-unicorns-will-you-breed'
|
|
130
|
+
section: susaYr
|
|
131
|
+
next:
|
|
132
|
+
- path: '/where-will-you-keep-the-unicorns'
|
|
133
|
+
components:
|
|
134
|
+
- name: DyfjJC
|
|
135
|
+
options: {}
|
|
136
|
+
type: CheckboxesField
|
|
137
|
+
list: fXiZrL
|
|
138
|
+
title: Type of unicorn
|
|
139
|
+
schema: {}
|
|
140
|
+
hint: This is a check box. Users can select more than one option
|
|
141
|
+
values:
|
|
142
|
+
type: listRef
|
|
143
|
+
- title: Where will you keep the unicorns?
|
|
144
|
+
path: '/where-will-you-keep-the-unicorns'
|
|
145
|
+
section: susaYr
|
|
146
|
+
next:
|
|
147
|
+
- path: '/how-many-members-of-staff-will-look-after-the-unicorns'
|
|
148
|
+
components:
|
|
149
|
+
- name: bClCvo
|
|
150
|
+
options: {}
|
|
151
|
+
schema: {}
|
|
152
|
+
type: MultilineTextField
|
|
153
|
+
title: Where you keep the unicorn
|
|
154
|
+
hint:
|
|
155
|
+
This is a multi-line text box. We use it when you expect the response to
|
|
156
|
+
be more than 1 sentence long
|
|
157
|
+
- title: How many members of staff will look after the unicorns?
|
|
158
|
+
path: '/how-many-members-of-staff-will-look-after-the-unicorns'
|
|
159
|
+
section: susaYr
|
|
160
|
+
next:
|
|
161
|
+
- path: '/summary'
|
|
162
|
+
components:
|
|
163
|
+
- name: zhJMaM
|
|
164
|
+
options:
|
|
165
|
+
classes: govuk-!-width-one-quarter
|
|
166
|
+
type: NumberField
|
|
167
|
+
title: Number of staff
|
|
168
|
+
schema: {}
|
|
169
|
+
hint:
|
|
170
|
+
This is a number field. The answer must be a number. We can use custom validation
|
|
171
|
+
to set decimal places, minimum and maximum values
|
|
172
|
+
- title: Upload your insurance certificate
|
|
173
|
+
path: '/upload-your-insurance-certificate'
|
|
174
|
+
controller: FileUploadPageController
|
|
175
|
+
section: Regnsa
|
|
176
|
+
next:
|
|
177
|
+
- path: '/how-many-unicorns-do-you-expect-to-breed-each-year'
|
|
178
|
+
components:
|
|
179
|
+
- name: dLzALM
|
|
180
|
+
title: Documents
|
|
181
|
+
type: FileUploadField
|
|
182
|
+
hint: We can specify the format and number of uploaded files
|
|
183
|
+
options:
|
|
184
|
+
required: false
|
|
185
|
+
schema:
|
|
186
|
+
min: 1
|
|
187
|
+
max: 3
|
|
188
|
+
conditions:
|
|
189
|
+
- displayName: Address is different
|
|
190
|
+
name: IrVmYz
|
|
191
|
+
value:
|
|
192
|
+
name: Address is different
|
|
193
|
+
conditions:
|
|
194
|
+
- field:
|
|
195
|
+
name: dBfuID
|
|
196
|
+
type: YesNoField
|
|
197
|
+
display: 'Contact details: Send certificate to same address'
|
|
198
|
+
operator: is
|
|
199
|
+
value:
|
|
200
|
+
type: Value
|
|
201
|
+
value: 'false'
|
|
202
|
+
display: 'false'
|
|
203
|
+
- displayName: Address is not the same
|
|
204
|
+
name: oyGPwP
|
|
205
|
+
value:
|
|
206
|
+
name: Address is not the same
|
|
207
|
+
conditions:
|
|
208
|
+
- field:
|
|
209
|
+
name: dBfuID
|
|
210
|
+
type: YesNoField
|
|
211
|
+
display: 'Contact details: Send certificate to same address'
|
|
212
|
+
operator: is
|
|
213
|
+
value:
|
|
214
|
+
type: Value
|
|
215
|
+
value: 'false'
|
|
216
|
+
display: 'No'
|
|
217
|
+
sections:
|
|
218
|
+
- name: section
|
|
219
|
+
title: Contact details
|
|
220
|
+
hideTitle: false
|
|
221
|
+
- title: Unicorn details
|
|
222
|
+
name: susaYr
|
|
223
|
+
hideTitle: false
|
|
224
|
+
- title: Insurance details
|
|
225
|
+
name: Regnsa
|
|
226
|
+
hideTitle: false
|
|
227
|
+
lists:
|
|
228
|
+
- title: number of unicorns
|
|
229
|
+
name: IeFOkf
|
|
230
|
+
type: string
|
|
231
|
+
items:
|
|
232
|
+
- text: 1 to 5
|
|
233
|
+
value: 1 to 5
|
|
234
|
+
- text: 6 to 10
|
|
235
|
+
value: 6 to 10
|
|
236
|
+
- text: 11 or more
|
|
237
|
+
value: 11 or more
|
|
238
|
+
- title: Type of unicorn
|
|
239
|
+
name: fXiZrL
|
|
240
|
+
type: string
|
|
241
|
+
items:
|
|
242
|
+
- text: Flying
|
|
243
|
+
value: Flying
|
|
244
|
+
- text: Fire breathing
|
|
245
|
+
value: Fire breathing
|
|
246
|
+
- text: Aquatic
|
|
247
|
+
value: Aquatic
|
|
248
|
+
- text: Rainbow
|
|
249
|
+
value: Rainbow
|
|
250
|
+
outputEmail: defraforms@defra.gov.uk
|
|
251
|
+
startPage: '/whats-your-name'
|
package/.server/server/index.js
CHANGED
|
@@ -10,14 +10,13 @@ import { config } from "../config/index.js";
|
|
|
10
10
|
import { requestLogger } from "./common/helpers/logging/request-logger.js";
|
|
11
11
|
import { requestTracing } from "./common/helpers/logging/request-tracing.js";
|
|
12
12
|
import { buildRedisClient } from "./common/helpers/redis-client.js";
|
|
13
|
-
import { configureBlankiePlugin } from "./plugins/blankie.js";
|
|
14
13
|
import { configureCrumbPlugin } from "./plugins/crumb.js";
|
|
15
|
-
import { configureEnginePlugin } from "./plugins/engine/
|
|
14
|
+
import { configureEnginePlugin } from "./plugins/engine/configureEnginePlugin.js";
|
|
16
15
|
import pluginErrorPages from "./plugins/errorPages.js";
|
|
17
16
|
import { plugin as pluginViews } from "./plugins/nunjucks/index.js";
|
|
18
17
|
import pluginPulse from "./plugins/pulse.js";
|
|
19
|
-
import pluginRouter from "./plugins/router.js";
|
|
20
18
|
import pluginSession from "./plugins/session.js";
|
|
19
|
+
import { publicRoutes } from "./routes/index.js";
|
|
21
20
|
import { prepareSecureContext } from "./secure-context.js";
|
|
22
21
|
const proxyAgent = new ProxyAgent();
|
|
23
22
|
Wreck.agents = {
|
|
@@ -66,14 +65,12 @@ export async function createServer(routeConfig) {
|
|
|
66
65
|
if (config.get('isProduction')) {
|
|
67
66
|
prepareSecureContext(server);
|
|
68
67
|
}
|
|
69
|
-
const pluginEngine = await configureEnginePlugin(routeConfig);
|
|
70
68
|
const pluginCrumb = configureCrumbPlugin(routeConfig);
|
|
71
|
-
const
|
|
69
|
+
const pluginEngine = await configureEnginePlugin(routeConfig);
|
|
72
70
|
await server.register(pluginSession);
|
|
73
71
|
await server.register(pluginPulse);
|
|
74
72
|
await server.register(inert);
|
|
75
73
|
await server.register(Scooter);
|
|
76
|
-
await server.register(pluginBlankie);
|
|
77
74
|
await server.register(pluginCrumb);
|
|
78
75
|
server.ext('onPreResponse', (request, h) => {
|
|
79
76
|
const {
|
|
@@ -94,19 +91,17 @@ export async function createServer(routeConfig) {
|
|
|
94
91
|
});
|
|
95
92
|
await server.register(pluginViews);
|
|
96
93
|
await server.register(pluginEngine);
|
|
97
|
-
await server.register(
|
|
94
|
+
await server.register({
|
|
95
|
+
plugin: {
|
|
96
|
+
name: 'router',
|
|
97
|
+
register: server => {
|
|
98
|
+
server.route(publicRoutes);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
});
|
|
98
102
|
await server.register(pluginErrorPages);
|
|
99
103
|
await server.register(blipp);
|
|
100
104
|
await server.register(requestTracing);
|
|
101
|
-
server.state('cookieConsent', {
|
|
102
|
-
ttl: 365 * 24 * 60 * 60 * 1000,
|
|
103
|
-
// 1 year in ms
|
|
104
|
-
clearInvalid: true,
|
|
105
|
-
isHttpOnly: false,
|
|
106
|
-
isSecure: config.get('isProduction'),
|
|
107
|
-
path: '/',
|
|
108
|
-
encoding: 'none' // handle this inside the application so we can share frontend/backend cookie modification
|
|
109
|
-
});
|
|
110
105
|
return server;
|
|
111
106
|
}
|
|
112
107
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["Engine","CatboxMemory","CatboxRedis","hapi","inert","Scooter","Wreck","blipp","ProxyAgent","config","requestLogger","requestTracing","buildRedisClient","
|
|
1
|
+
{"version":3,"file":"index.js","names":["Engine","CatboxMemory","CatboxRedis","hapi","inert","Scooter","Wreck","blipp","ProxyAgent","config","requestLogger","requestTracing","buildRedisClient","configureCrumbPlugin","configureEnginePlugin","pluginErrorPages","plugin","pluginViews","pluginPulse","pluginSession","publicRoutes","prepareSecureContext","proxyAgent","agents","https","http","httpsAllowUnauthorized","serverOptions","debug","request","get","port","router","stripTrailingSlash","routes","validate","options","abortEarly","security","hsts","maxAge","includeSubDomains","preload","xss","noSniff","xframe","cache","name","engine","client","createServer","routeConfig","server","register","pluginCrumb","pluginEngine","ext","h","response","continue","header","path","startsWith","route"],"sources":["../../src/server/index.ts"],"sourcesContent":["import { Engine as CatboxMemory } from '@hapi/catbox-memory'\nimport { Engine as CatboxRedis } from '@hapi/catbox-redis'\nimport hapi, {\n type Request,\n type ResponseToolkit,\n type ServerOptions\n} from '@hapi/hapi'\nimport inert from '@hapi/inert'\nimport Scooter from '@hapi/scooter'\nimport Wreck from '@hapi/wreck'\nimport blipp from 'blipp'\nimport { ProxyAgent } from 'proxy-agent'\n\nimport { config } from '~/src/config/index.js'\nimport { requestLogger } from '~/src/server/common/helpers/logging/request-logger.js'\nimport { requestTracing } from '~/src/server/common/helpers/logging/request-tracing.js'\nimport { buildRedisClient } from '~/src/server/common/helpers/redis-client.js'\nimport { configureCrumbPlugin } from '~/src/server/plugins/crumb.js'\nimport { configureEnginePlugin } from '~/src/server/plugins/engine/configureEnginePlugin.js'\nimport pluginErrorPages from '~/src/server/plugins/errorPages.js'\nimport { plugin as pluginViews } from '~/src/server/plugins/nunjucks/index.js'\nimport pluginPulse from '~/src/server/plugins/pulse.js'\nimport pluginSession from '~/src/server/plugins/session.js'\nimport { publicRoutes } from '~/src/server/routes/index.js'\nimport { prepareSecureContext } from '~/src/server/secure-context.js'\nimport { type RouteConfig } from '~/src/server/types.js'\n\nconst proxyAgent = new ProxyAgent()\n\nWreck.agents = {\n https: proxyAgent,\n http: proxyAgent,\n httpsAllowUnauthorized: proxyAgent\n}\n\nconst serverOptions = (): ServerOptions => {\n const serverOptions: ServerOptions = {\n debug: { request: [`${config.get('isDevelopment')}`] },\n port: config.get('port'),\n router: {\n stripTrailingSlash: true\n },\n routes: {\n validate: {\n options: {\n abortEarly: false\n }\n },\n security: {\n hsts: {\n maxAge: 31536000,\n includeSubDomains: true,\n preload: false\n },\n xss: 'enabled',\n noSniff: true,\n xframe: true\n }\n },\n cache: [\n {\n name: 'session',\n engine: config.get('isTest')\n ? new CatboxMemory()\n : new CatboxRedis({\n client: buildRedisClient()\n })\n }\n ]\n }\n\n return serverOptions\n}\n\nexport async function createServer(routeConfig?: RouteConfig) {\n const server = hapi.server(serverOptions())\n\n await server.register(requestLogger)\n\n if (config.get('isProduction')) {\n prepareSecureContext(server)\n }\n\n const pluginCrumb = configureCrumbPlugin(routeConfig)\n const pluginEngine = await configureEnginePlugin(routeConfig)\n\n await server.register(pluginSession)\n await server.register(pluginPulse)\n await server.register(inert)\n await server.register(Scooter)\n await server.register(pluginCrumb)\n\n server.ext('onPreResponse', (request: Request, h: ResponseToolkit) => {\n const { response } = request\n\n if ('isBoom' in response) {\n return h.continue\n }\n\n // Prevent search engine indexing\n response.header('x-robots-tag', 'noindex, nofollow')\n\n // Disable cache to ensure back/foward navigation updates progress\n if (\n !request.path.startsWith('/javascripts/') &&\n !request.path.startsWith('/stylesheets/') &&\n !request.path.startsWith('/assets/')\n ) {\n response.header('cache-control', 'no-store')\n }\n\n return h.continue\n })\n\n await server.register(pluginViews)\n await server.register(pluginEngine)\n\n await server.register({\n plugin: {\n name: 'router',\n register: (server) => {\n server.route(publicRoutes)\n }\n }\n })\n\n await server.register(pluginErrorPages)\n await server.register(blipp)\n await server.register(requestTracing)\n\n return server\n}\n"],"mappings":"AAAA,SAASA,MAAM,IAAIC,YAAY,QAAQ,qBAAqB;AAC5D,SAASD,MAAM,IAAIE,WAAW,QAAQ,oBAAoB;AAC1D,OAAOC,IAAI,MAIJ,YAAY;AACnB,OAAOC,KAAK,MAAM,aAAa;AAC/B,OAAOC,OAAO,MAAM,eAAe;AACnC,OAAOC,KAAK,MAAM,aAAa;AAC/B,OAAOC,KAAK,MAAM,OAAO;AACzB,SAASC,UAAU,QAAQ,aAAa;AAExC,SAASC,MAAM;AACf,SAASC,aAAa;AACtB,SAASC,cAAc;AACvB,SAASC,gBAAgB;AACzB,SAASC,oBAAoB;AAC7B,SAASC,qBAAqB;AAC9B,OAAOC,gBAAgB;AACvB,SAASC,MAAM,IAAIC,WAAW;AAC9B,OAAOC,WAAW;AAClB,OAAOC,aAAa;AACpB,SAASC,YAAY;AACrB,SAASC,oBAAoB;AAG7B,MAAMC,UAAU,GAAG,IAAId,UAAU,CAAC,CAAC;AAEnCF,KAAK,CAACiB,MAAM,GAAG;EACbC,KAAK,EAAEF,UAAU;EACjBG,IAAI,EAAEH,UAAU;EAChBI,sBAAsB,EAAEJ;AAC1B,CAAC;AAED,MAAMK,aAAa,GAAGA,CAAA,KAAqB;EACzC,MAAMA,aAA4B,GAAG;IACnCC,KAAK,EAAE;MAAEC,OAAO,EAAE,CAAC,GAAGpB,MAAM,CAACqB,GAAG,CAAC,eAAe,CAAC,EAAE;IAAE,CAAC;IACtDC,IAAI,EAAEtB,MAAM,CAACqB,GAAG,CAAC,MAAM,CAAC;IACxBE,MAAM,EAAE;MACNC,kBAAkB,EAAE;IACtB,CAAC;IACDC,MAAM,EAAE;MACNC,QAAQ,EAAE;QACRC,OAAO,EAAE;UACPC,UAAU,EAAE;QACd;MACF,CAAC;MACDC,QAAQ,EAAE;QACRC,IAAI,EAAE;UACJC,MAAM,EAAE,QAAQ;UAChBC,iBAAiB,EAAE,IAAI;UACvBC,OAAO,EAAE;QACX,CAAC;QACDC,GAAG,EAAE,SAAS;QACdC,OAAO,EAAE,IAAI;QACbC,MAAM,EAAE;MACV;IACF,CAAC;IACDC,KAAK,EAAE,CACL;MACEC,IAAI,EAAE,SAAS;MACfC,MAAM,EAAEvC,MAAM,CAACqB,GAAG,CAAC,QAAQ,CAAC,GACxB,IAAI7B,YAAY,CAAC,CAAC,GAClB,IAAIC,WAAW,CAAC;QACd+C,MAAM,EAAErC,gBAAgB,CAAC;MAC3B,CAAC;IACP,CAAC;EAEL,CAAC;EAED,OAAOe,aAAa;AACtB,CAAC;AAED,OAAO,eAAeuB,YAAYA,CAACC,WAAyB,EAAE;EAC5D,MAAMC,MAAM,GAAGjD,IAAI,CAACiD,MAAM,CAACzB,aAAa,CAAC,CAAC,CAAC;EAE3C,MAAMyB,MAAM,CAACC,QAAQ,CAAC3C,aAAa,CAAC;EAEpC,IAAID,MAAM,CAACqB,GAAG,CAAC,cAAc,CAAC,EAAE;IAC9BT,oBAAoB,CAAC+B,MAAM,CAAC;EAC9B;EAEA,MAAME,WAAW,GAAGzC,oBAAoB,CAACsC,WAAW,CAAC;EACrD,MAAMI,YAAY,GAAG,MAAMzC,qBAAqB,CAACqC,WAAW,CAAC;EAE7D,MAAMC,MAAM,CAACC,QAAQ,CAAClC,aAAa,CAAC;EACpC,MAAMiC,MAAM,CAACC,QAAQ,CAACnC,WAAW,CAAC;EAClC,MAAMkC,MAAM,CAACC,QAAQ,CAACjD,KAAK,CAAC;EAC5B,MAAMgD,MAAM,CAACC,QAAQ,CAAChD,OAAO,CAAC;EAC9B,MAAM+C,MAAM,CAACC,QAAQ,CAACC,WAAW,CAAC;EAElCF,MAAM,CAACI,GAAG,CAAC,eAAe,EAAE,CAAC3B,OAAgB,EAAE4B,CAAkB,KAAK;IACpE,MAAM;MAAEC;IAAS,CAAC,GAAG7B,OAAO;IAE5B,IAAI,QAAQ,IAAI6B,QAAQ,EAAE;MACxB,OAAOD,CAAC,CAACE,QAAQ;IACnB;;IAEA;IACAD,QAAQ,CAACE,MAAM,CAAC,cAAc,EAAE,mBAAmB,CAAC;;IAEpD;IACA,IACE,CAAC/B,OAAO,CAACgC,IAAI,CAACC,UAAU,CAAC,eAAe,CAAC,IACzC,CAACjC,OAAO,CAACgC,IAAI,CAACC,UAAU,CAAC,eAAe,CAAC,IACzC,CAACjC,OAAO,CAACgC,IAAI,CAACC,UAAU,CAAC,UAAU,CAAC,EACpC;MACAJ,QAAQ,CAACE,MAAM,CAAC,eAAe,EAAE,UAAU,CAAC;IAC9C;IAEA,OAAOH,CAAC,CAACE,QAAQ;EACnB,CAAC,CAAC;EAEF,MAAMP,MAAM,CAACC,QAAQ,CAACpC,WAAW,CAAC;EAClC,MAAMmC,MAAM,CAACC,QAAQ,CAACE,YAAY,CAAC;EAEnC,MAAMH,MAAM,CAACC,QAAQ,CAAC;IACpBrC,MAAM,EAAE;MACN+B,IAAI,EAAE,QAAQ;MACdM,QAAQ,EAAGD,MAAM,IAAK;QACpBA,MAAM,CAACW,KAAK,CAAC3C,YAAY,CAAC;MAC5B;IACF;EACF,CAAC,CAAC;EAEF,MAAMgC,MAAM,CAACC,QAAQ,CAACtC,gBAAgB,CAAC;EACvC,MAAMqC,MAAM,CAACC,QAAQ,CAAC9C,KAAK,CAAC;EAC5B,MAAM6C,MAAM,CAACC,QAAQ,CAAC1C,cAAc,CAAC;EAErC,OAAOyC,MAAM;AACf","ignoreList":[]}
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { join, parse } from 'node:path';
|
|
2
2
|
import { FormModel } from "./models/FormModel.js";
|
|
3
3
|
import { plugin } from "./plugin.js";
|
|
4
|
+
import { findPackageRoot } from "./plugin.js";
|
|
5
|
+
import * as defaultServices from "./services/index.js";
|
|
6
|
+
import { formsService } from "./services/localFormsService.js";
|
|
7
|
+
import { devtoolContext } from "../nunjucks/context.js";
|
|
4
8
|
export const configureEnginePlugin = async ({
|
|
5
9
|
formFileName,
|
|
6
10
|
formFilePath,
|
|
@@ -21,8 +25,18 @@ export const configureEnginePlugin = async ({
|
|
|
21
25
|
plugin,
|
|
22
26
|
options: {
|
|
23
27
|
model,
|
|
24
|
-
services
|
|
25
|
-
|
|
28
|
+
services: services ?? {
|
|
29
|
+
// services for testing, else use the disk loader option for running this service locally
|
|
30
|
+
...defaultServices,
|
|
31
|
+
formsService: await formsService()
|
|
32
|
+
},
|
|
33
|
+
controllers,
|
|
34
|
+
cacheName: 'session',
|
|
35
|
+
nunjucks: {
|
|
36
|
+
baseLayoutPath: 'dxt-devtool-baselayout.html',
|
|
37
|
+
paths: [join(findPackageRoot(), 'src/server/devserver')] // custom layout to make it really clear this is not the same as the runner
|
|
38
|
+
},
|
|
39
|
+
viewContext: devtoolContext
|
|
26
40
|
}
|
|
27
41
|
};
|
|
28
42
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"configureEnginePlugin.js","names":["join","parse","FormModel","plugin","configureEnginePlugin","formFileName","formFilePath","services","controllers","model","definition","getForm","name","basePath","options","importPath","ext","attributes","type","formImport","with","default"],"sources":["../../../../src/server/plugins/engine/configureEnginePlugin.ts"],"sourcesContent":["import { join, parse } from 'node:path'\n\nimport { type FormDefinition } from '@defra/forms-model'\nimport { type ServerRegisterPluginObject } from '@hapi/hapi'\n\nimport { FormModel } from '~/src/server/plugins/engine/models/FormModel.js'\nimport {\n plugin,\n type PluginOptions\n} from '~/src/server/plugins/engine/plugin.js'\nimport { type RouteConfig } from '~/src/server/types.js'\n\nexport const configureEnginePlugin = async ({\n formFileName,\n formFilePath,\n services,\n controllers\n}: RouteConfig = {}): Promise<ServerRegisterPluginObject<PluginOptions>> => {\n let model: FormModel | undefined\n\n if (formFileName && formFilePath) {\n const definition = await getForm(join(formFilePath, formFileName))\n const { name } = parse(formFileName)\n\n model = new FormModel(definition, { basePath: name }, services, controllers)\n }\n\n return {\n plugin,\n options: {
|
|
1
|
+
{"version":3,"file":"configureEnginePlugin.js","names":["join","parse","FormModel","plugin","findPackageRoot","defaultServices","formsService","devtoolContext","configureEnginePlugin","formFileName","formFilePath","services","controllers","model","definition","getForm","name","basePath","options","cacheName","nunjucks","baseLayoutPath","paths","viewContext","importPath","ext","attributes","type","formImport","with","default"],"sources":["../../../../src/server/plugins/engine/configureEnginePlugin.ts"],"sourcesContent":["import { join, parse } from 'node:path'\n\nimport { type FormDefinition } from '@defra/forms-model'\nimport { type ServerRegisterPluginObject } from '@hapi/hapi'\n\nimport { FormModel } from '~/src/server/plugins/engine/models/FormModel.js'\nimport {\n plugin,\n type PluginOptions\n} from '~/src/server/plugins/engine/plugin.js'\nimport { findPackageRoot } from '~/src/server/plugins/engine/plugin.js'\nimport * as defaultServices from '~/src/server/plugins/engine/services/index.js'\nimport { formsService } from '~/src/server/plugins/engine/services/localFormsService.js'\nimport { devtoolContext } from '~/src/server/plugins/nunjucks/context.js'\nimport { type RouteConfig } from '~/src/server/types.js'\n\nexport const configureEnginePlugin = async ({\n formFileName,\n formFilePath,\n services,\n controllers\n}: RouteConfig = {}): Promise<ServerRegisterPluginObject<PluginOptions>> => {\n let model: FormModel | undefined\n\n if (formFileName && formFilePath) {\n const definition = await getForm(join(formFilePath, formFileName))\n const { name } = parse(formFileName)\n\n model = new FormModel(definition, { basePath: name }, services, controllers)\n }\n\n return {\n plugin,\n options: {\n model,\n services: services ?? {\n // services for testing, else use the disk loader option for running this service locally\n ...defaultServices,\n formsService: await formsService()\n },\n controllers,\n cacheName: 'session',\n nunjucks: {\n baseLayoutPath: 'dxt-devtool-baselayout.html',\n paths: [join(findPackageRoot(), 'src/server/devserver')] // custom layout to make it really clear this is not the same as the runner\n },\n viewContext: devtoolContext\n }\n }\n}\n\nexport async function getForm(importPath: string) {\n const { ext } = parse(importPath)\n\n const attributes: ImportAttributes = {\n type: ext === '.json' ? 'json' : 'module'\n }\n\n const formImport = import(importPath, { with: attributes }) as Promise<{\n default: FormDefinition\n }>\n\n const { default: definition } = await formImport\n return definition\n}\n"],"mappings":"AAAA,SAASA,IAAI,EAAEC,KAAK,QAAQ,WAAW;AAKvC,SAASC,SAAS;AAClB,SACEC,MAAM;AAGR,SAASC,eAAe;AACxB,OAAO,KAAKC,eAAe;AAC3B,SAASC,YAAY;AACrB,SAASC,cAAc;AAGvB,OAAO,MAAMC,qBAAqB,GAAG,MAAAA,CAAO;EAC1CC,YAAY;EACZC,YAAY;EACZC,QAAQ;EACRC;AACW,CAAC,GAAG,CAAC,CAAC,KAAyD;EAC1E,IAAIC,KAA4B;EAEhC,IAAIJ,YAAY,IAAIC,YAAY,EAAE;IAChC,MAAMI,UAAU,GAAG,MAAMC,OAAO,CAACf,IAAI,CAACU,YAAY,EAAED,YAAY,CAAC,CAAC;IAClE,MAAM;MAAEO;IAAK,CAAC,GAAGf,KAAK,CAACQ,YAAY,CAAC;IAEpCI,KAAK,GAAG,IAAIX,SAAS,CAACY,UAAU,EAAE;MAAEG,QAAQ,EAAED;IAAK,CAAC,EAAEL,QAAQ,EAAEC,WAAW,CAAC;EAC9E;EAEA,OAAO;IACLT,MAAM;IACNe,OAAO,EAAE;MACPL,KAAK;MACLF,QAAQ,EAAEA,QAAQ,IAAI;QACpB;QACA,GAAGN,eAAe;QAClBC,YAAY,EAAE,MAAMA,YAAY,CAAC;MACnC,CAAC;MACDM,WAAW;MACXO,SAAS,EAAE,SAAS;MACpBC,QAAQ,EAAE;QACRC,cAAc,EAAE,6BAA6B;QAC7CC,KAAK,EAAE,CAACtB,IAAI,CAACI,eAAe,CAAC,CAAC,EAAE,sBAAsB,CAAC,CAAC,CAAC;MAC3D,CAAC;MACDmB,WAAW,EAAEhB;IACf;EACF,CAAC;AACH,CAAC;AAED,OAAO,eAAeQ,OAAOA,CAACS,UAAkB,EAAE;EAChD,MAAM;IAAEC;EAAI,CAAC,GAAGxB,KAAK,CAACuB,UAAU,CAAC;EAEjC,MAAME,UAA4B,GAAG;IACnCC,IAAI,EAAEF,GAAG,KAAK,OAAO,GAAG,MAAM,GAAG;EACnC,CAAC;EAED,MAAMG,UAAU,GAAG,MAAM,CAACJ,UAAU,EAAE;IAAEK,IAAI,EAAEH;EAAW,CAAC,CAExD;EAEF,MAAM;IAAEI,OAAO,EAAEhB;EAAW,CAAC,GAAG,MAAMc,UAAU;EAChD,OAAOd,UAAU;AACnB","ignoreList":[]}
|
|
@@ -1,12 +1,16 @@
|
|
|
1
|
+
import { existsSync } from 'fs';
|
|
2
|
+
import { dirname, join } from 'path';
|
|
3
|
+
import { fileURLToPath } from 'url';
|
|
1
4
|
import { hasFormComponents, slugSchema } from '@defra/forms-model';
|
|
2
5
|
import Boom from '@hapi/boom';
|
|
3
6
|
import vision from '@hapi/vision';
|
|
4
7
|
import { isEqual } from 'date-fns';
|
|
5
8
|
import Joi from 'joi';
|
|
6
9
|
import nunjucks from 'nunjucks';
|
|
10
|
+
import resolvePkg from 'resolve';
|
|
7
11
|
import { PREVIEW_PATH_PREFIX } from "../../constants.js";
|
|
8
12
|
import { checkEmailAddressForLiveFormSubmission, checkFormStatus, findPage, getCacheService, getPage, getStartPath, normalisePath, proceed, redirectPath } from "./helpers.js";
|
|
9
|
-
import {
|
|
13
|
+
import { VIEW_PATH, context, prepareNunjucksEnvironment } from "./index.js";
|
|
10
14
|
import { FormModel, SummaryViewModel } from "./models/index.js";
|
|
11
15
|
import { format } from "./outputFormatters/machine/v1.js";
|
|
12
16
|
import { FileUploadPageController } from "./pageControllers/FileUploadPageController.js";
|
|
@@ -18,6 +22,18 @@ import { getUploadStatus } from "./services/uploadService.js";
|
|
|
18
22
|
import { actionSchema, confirmSchema, crumbSchema, itemIdSchema, pathSchema, stateSchema } from "../../schemas/index.js";
|
|
19
23
|
import * as httpService from "../../services/httpService.js";
|
|
20
24
|
import { CacheService } from "../../services/index.js";
|
|
25
|
+
export function findPackageRoot() {
|
|
26
|
+
const currentFileName = fileURLToPath(import.meta.url);
|
|
27
|
+
const currentDirectoryName = dirname(currentFileName);
|
|
28
|
+
let dir = currentDirectoryName;
|
|
29
|
+
while (dir !== '/') {
|
|
30
|
+
if (existsSync(join(dir, 'package.json'))) {
|
|
31
|
+
return dir;
|
|
32
|
+
}
|
|
33
|
+
dir = dirname(dir);
|
|
34
|
+
}
|
|
35
|
+
throw new Error('package.json not found in parent directories');
|
|
36
|
+
}
|
|
21
37
|
export const plugin = {
|
|
22
38
|
name: '@defra/forms-engine-plugin',
|
|
23
39
|
dependencies: ['@hapi/crumb', '@hapi/yar', 'hapi-pino'],
|
|
@@ -28,25 +44,18 @@ export const plugin = {
|
|
|
28
44
|
services = defaultServices,
|
|
29
45
|
controllers,
|
|
30
46
|
cacheName,
|
|
31
|
-
viewPaths,
|
|
32
47
|
filters,
|
|
33
|
-
|
|
48
|
+
nunjucks: nunjucksOptions,
|
|
49
|
+
viewContext
|
|
34
50
|
} = options;
|
|
35
51
|
const {
|
|
36
52
|
formsService
|
|
37
53
|
} = services;
|
|
38
54
|
const cacheService = new CacheService(server, cacheName);
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
const path = [`${pluginPath}/${VIEW_PATH}`, VIEW_PATH];
|
|
44
|
-
|
|
45
|
-
// Include any additional user provided view paths so our internal views engine
|
|
46
|
-
// can find any files they provide from the consumer side if using custom `page.view`s
|
|
47
|
-
if (Array.isArray(viewPaths) && viewPaths.length) {
|
|
48
|
-
path.push(...viewPaths);
|
|
49
|
-
}
|
|
55
|
+
const packageRoot = findPackageRoot();
|
|
56
|
+
const govukFrontendPath = dirname(resolvePkg.sync('govuk-frontend/package.json'));
|
|
57
|
+
const viewPathResolved = join(packageRoot, VIEW_PATH);
|
|
58
|
+
const paths = [...nunjucksOptions.paths, viewPathResolved, join(govukFrontendPath, 'dist')];
|
|
50
59
|
await server.register({
|
|
51
60
|
plugin: vision,
|
|
52
61
|
options: {
|
|
@@ -61,7 +70,7 @@ export const plugin = {
|
|
|
61
70
|
prepare: (options, next) => {
|
|
62
71
|
// Nunjucks also needs an additional path configuration
|
|
63
72
|
// to use the templates and macros from `govuk-frontend`
|
|
64
|
-
const environment = nunjucks.configure(
|
|
73
|
+
const environment = nunjucks.configure(paths);
|
|
65
74
|
|
|
66
75
|
// Applies custom filters and globals for nunjucks
|
|
67
76
|
// that are required by the `forms-engine-plugin`
|
|
@@ -71,11 +80,13 @@ export const plugin = {
|
|
|
71
80
|
}
|
|
72
81
|
}
|
|
73
82
|
},
|
|
74
|
-
path,
|
|
83
|
+
path: paths,
|
|
75
84
|
// Provides global context used with all templates
|
|
76
85
|
context
|
|
77
86
|
}
|
|
78
87
|
});
|
|
88
|
+
server.expose('baseLayoutPath', nunjucksOptions.baseLayoutPath);
|
|
89
|
+
server.expose('viewContext', viewContext);
|
|
79
90
|
server.expose('cacheService', cacheService);
|
|
80
91
|
server.app.model = model;
|
|
81
92
|
|