@defra/forms-engine-plugin 4.0.0 → 4.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.
Files changed (108) hide show
  1. package/.public/stylesheets/application.min.css +2 -2
  2. package/.public/stylesheets/application.min.css.map +1 -1
  3. package/.server/client/stylesheets/shared.scss +15 -0
  4. package/.server/config/index.d.ts +1 -0
  5. package/.server/config/index.js +7 -0
  6. package/.server/config/index.js.map +1 -1
  7. package/.server/index.js +6 -2
  8. package/.server/index.js.map +1 -1
  9. package/.server/server/constants.d.ts +2 -0
  10. package/.server/server/constants.js +2 -0
  11. package/.server/server/constants.js.map +1 -1
  12. package/.server/server/forms/components.json +7 -0
  13. package/.server/server/forms/register-as-a-unicorn-breeder.yaml +18 -2
  14. package/.server/server/plugins/engine/components/UkAddressField.d.ts +15 -9
  15. package/.server/server/plugins/engine/components/UkAddressField.js +67 -6
  16. package/.server/server/plugins/engine/components/UkAddressField.js.map +1 -1
  17. package/.server/server/plugins/engine/configureEnginePlugin.d.ts +1 -1
  18. package/.server/server/plugins/engine/configureEnginePlugin.js +6 -3
  19. package/.server/server/plugins/engine/configureEnginePlugin.js.map +1 -1
  20. package/.server/server/plugins/engine/models/FormModel.d.ts +2 -0
  21. package/.server/server/plugins/engine/models/FormModel.js +3 -1
  22. package/.server/server/plugins/engine/models/FormModel.js.map +1 -1
  23. package/.server/server/plugins/engine/options.js +2 -1
  24. package/.server/server/plugins/engine/options.js.map +1 -1
  25. package/.server/server/plugins/engine/pageControllers/QuestionPageController.d.ts +1 -0
  26. package/.server/server/plugins/engine/pageControllers/QuestionPageController.js +46 -3
  27. package/.server/server/plugins/engine/pageControllers/QuestionPageController.js.map +1 -1
  28. package/.server/server/plugins/engine/plugin.js +13 -1
  29. package/.server/server/plugins/engine/plugin.js.map +1 -1
  30. package/.server/server/plugins/engine/routes/index.js +41 -3
  31. package/.server/server/plugins/engine/routes/index.js.map +1 -1
  32. package/.server/server/plugins/engine/types.d.ts +19 -1
  33. package/.server/server/plugins/engine/types.js.map +1 -1
  34. package/.server/server/plugins/engine/validationHelpers.d.ts +15 -0
  35. package/.server/server/plugins/engine/validationHelpers.js +29 -0
  36. package/.server/server/plugins/engine/validationHelpers.js.map +1 -0
  37. package/.server/server/plugins/engine/views/components/ukaddressfield.html +50 -6
  38. package/.server/server/plugins/engine/vision.js +3 -1
  39. package/.server/server/plugins/engine/vision.js.map +1 -1
  40. package/.server/server/plugins/postcode-lookup/index.d.ts +8 -0
  41. package/.server/server/plugins/postcode-lookup/index.js +21 -0
  42. package/.server/server/plugins/postcode-lookup/index.js.map +1 -0
  43. package/.server/server/plugins/postcode-lookup/models/index.d.ts +255 -0
  44. package/.server/server/plugins/postcode-lookup/models/index.js +517 -0
  45. package/.server/server/plugins/postcode-lookup/models/index.js.map +1 -0
  46. package/.server/server/plugins/postcode-lookup/routes/index.d.ts +19 -0
  47. package/.server/server/plugins/postcode-lookup/routes/index.js +267 -0
  48. package/.server/server/plugins/postcode-lookup/routes/index.js.map +1 -0
  49. package/.server/server/plugins/postcode-lookup/service.d.ts +26 -0
  50. package/.server/server/plugins/postcode-lookup/service.js +148 -0
  51. package/.server/server/plugins/postcode-lookup/service.js.map +1 -0
  52. package/.server/server/plugins/postcode-lookup/service.test.js +144 -0
  53. package/.server/server/plugins/postcode-lookup/service.test.js.map +1 -0
  54. package/.server/server/plugins/postcode-lookup/test/__stubs__/postcode.d.ts +282 -0
  55. package/.server/server/plugins/postcode-lookup/test/__stubs__/postcode.js +370 -0
  56. package/.server/server/plugins/postcode-lookup/test/__stubs__/postcode.js.map +1 -0
  57. package/.server/server/plugins/postcode-lookup/test/__stubs__/query.d.ts +131 -0
  58. package/.server/server/plugins/postcode-lookup/test/__stubs__/query.js +195 -0
  59. package/.server/server/plugins/postcode-lookup/test/__stubs__/query.js.map +1 -0
  60. package/.server/server/plugins/postcode-lookup/test/__stubs__/uprn.d.ts +51 -0
  61. package/.server/server/plugins/postcode-lookup/test/__stubs__/uprn.js +52 -0
  62. package/.server/server/plugins/postcode-lookup/test/__stubs__/uprn.js.map +1 -0
  63. package/.server/server/plugins/postcode-lookup/types.d.ts +204 -0
  64. package/.server/server/plugins/postcode-lookup/types.js +144 -0
  65. package/.server/server/plugins/postcode-lookup/types.js.map +1 -0
  66. package/.server/server/plugins/postcode-lookup/views/postcode-lookup-details.html +83 -0
  67. package/.server/server/routes/types.d.ts +6 -1
  68. package/.server/server/routes/types.js +6 -0
  69. package/.server/server/routes/types.js.map +1 -1
  70. package/.server/server/schemas/index.js +1 -1
  71. package/.server/server/schemas/index.js.map +1 -1
  72. package/.server/server/types.d.ts +1 -0
  73. package/.server/server/types.js.map +1 -1
  74. package/package.json +2 -2
  75. package/src/client/stylesheets/shared.scss +15 -0
  76. package/src/config/index.ts +9 -1
  77. package/src/index.ts +5 -4
  78. package/src/server/constants.js +2 -0
  79. package/src/server/forms/components.json +7 -0
  80. package/src/server/forms/register-as-a-unicorn-breeder.yaml +18 -2
  81. package/src/server/plugins/engine/components/UkAddressField.test.ts +50 -27
  82. package/src/server/plugins/engine/components/UkAddressField.ts +91 -8
  83. package/src/server/plugins/engine/configureEnginePlugin.ts +5 -3
  84. package/src/server/plugins/engine/models/FormModel.ts +10 -2
  85. package/src/server/plugins/engine/options.js +2 -1
  86. package/src/server/plugins/engine/pageControllers/QuestionPageController.test.ts +1 -0
  87. package/src/server/plugins/engine/pageControllers/QuestionPageController.ts +69 -1
  88. package/src/server/plugins/engine/plugin.ts +13 -1
  89. package/src/server/plugins/engine/routes/index.test.ts +1 -0
  90. package/src/server/plugins/engine/routes/index.ts +71 -3
  91. package/src/server/plugins/engine/types.ts +21 -1
  92. package/src/server/plugins/engine/validationHelpers.ts +48 -0
  93. package/src/server/plugins/engine/views/components/ukaddressfield.html +50 -6
  94. package/src/server/plugins/engine/vision.ts +6 -0
  95. package/src/server/plugins/postcode-lookup/index.js +21 -0
  96. package/src/server/plugins/postcode-lookup/models/index.js +549 -0
  97. package/src/server/plugins/postcode-lookup/routes/index.js +258 -0
  98. package/src/server/plugins/postcode-lookup/service.js +188 -0
  99. package/src/server/plugins/postcode-lookup/service.test.js +177 -0
  100. package/src/server/plugins/postcode-lookup/test/__stubs__/postcode.js +382 -0
  101. package/src/server/plugins/postcode-lookup/test/__stubs__/query.js +200 -0
  102. package/src/server/plugins/postcode-lookup/test/__stubs__/uprn.js +53 -0
  103. package/src/server/plugins/postcode-lookup/types.js +143 -0
  104. package/src/server/plugins/postcode-lookup/views/postcode-lookup-details.html +83 -0
  105. package/src/server/postcode-lookup.test.ts +64 -0
  106. package/src/server/routes/types.ts +7 -1
  107. package/src/server/schemas/index.ts +5 -7
  108. package/src/server/types.ts +1 -0
@@ -0,0 +1,517 @@
1
+ import Joi from 'joi';
2
+ import * as service from "../service.js";
3
+ import { crumbSchema } from "../../../schemas/index.js";
4
+
5
+ // Field names/ids
6
+ const postcodeQueryFieldName = 'postcodeQuery';
7
+ const buildingNameQueryFieldName = 'buildingNameQuery';
8
+ const uprnFieldName = 'uprn';
9
+ const line1FieldName = 'addressLine1';
10
+ const line2FieldName = 'addressLine2';
11
+ const townFieldName = 'town';
12
+ const countyFieldName = 'county';
13
+ const postcodeFieldName = 'postcode';
14
+ const selectLabelText = 'Select an address';
15
+ const GOVUK_MARGIN_RIGHT_1 = 'govuk-!-margin-right-1';
16
+ export const steps = {
17
+ // Step 1: Postcode/building name input
18
+ details: 'details',
19
+ // Step 2: Select address
20
+ select: 'select',
21
+ // Step 3: Manual address
22
+ manual: 'manual'
23
+ };
24
+ export const JOURNEY_BASE_URL = '/postcode-lookup';
25
+
26
+ /**
27
+ * Build form errors
28
+ * @param {Error} [err]
29
+ */
30
+ function buildErrors(err) {
31
+ const hasErrors = Joi.isError(err) && err.details.length > 0;
32
+ if (!hasErrors) {
33
+ return {};
34
+ }
35
+
36
+ /**
37
+ * Get error by path
38
+ * @param {string} fieldName
39
+ */
40
+ const getError = fieldName => {
41
+ return err.details.find(item => item.path[0] === fieldName);
42
+ };
43
+ const postcodeQueryError = getError(postcodeQueryFieldName);
44
+ const buildingNameQueryError = getError(buildingNameQueryFieldName);
45
+ const uprnError = getError(uprnFieldName);
46
+ const line1Error = getError(line1FieldName);
47
+ const line2Error = getError(line2FieldName);
48
+ const townError = getError(townFieldName);
49
+ const countyError = getError(countyFieldName);
50
+ const postcodeError = getError(postcodeFieldName);
51
+
52
+ /**
53
+ * @type {{ text: string, href: string }[]}
54
+ */
55
+ const errors = [];
56
+
57
+ /**
58
+ * Push error
59
+ * @param {string} fieldName - the field name
60
+ * @param {ValidationErrorItem} [item] - the joi validation error
61
+ */
62
+ const pushError = (fieldName, item) => {
63
+ if (item) {
64
+ errors.push({
65
+ text: item.message,
66
+ href: `#${fieldName}`
67
+ });
68
+ }
69
+ };
70
+ pushError(postcodeQueryFieldName, postcodeQueryError);
71
+ pushError(buildingNameQueryFieldName, buildingNameQueryError);
72
+ pushError(uprnFieldName, uprnError);
73
+ pushError(line1FieldName, line1Error);
74
+ pushError(line2FieldName, line2Error);
75
+ pushError(townFieldName, townError);
76
+ pushError(countyFieldName, countyError);
77
+ pushError(postcodeFieldName, postcodeError);
78
+ return {
79
+ errors,
80
+ postcodeQueryError,
81
+ buildingNameQueryError,
82
+ uprnError,
83
+ line1Error,
84
+ line2Error,
85
+ townError,
86
+ countyError,
87
+ postcodeError
88
+ };
89
+ }
90
+
91
+ /**
92
+ * Search ordnance survey for addresses
93
+ * @param {string} postcodeQuery
94
+ * @param {string} buildingNameQuery
95
+ * @param {string} apiKey
96
+ */
97
+ async function getAddresses(postcodeQuery, buildingNameQuery, apiKey) {
98
+ const addresses = await service.search(postcodeQuery, buildingNameQuery, apiKey);
99
+ const addressCount = addresses.length;
100
+ const singleAddress = addressCount === 1 ? addresses.at(0) : undefined;
101
+ const hasAddresses = addressCount > 0;
102
+ const hasMultipleAddresses = addressCount > 1;
103
+ return {
104
+ hasAddresses,
105
+ hasMultipleAddresses,
106
+ singleAddress,
107
+ addresses,
108
+ addressCount
109
+ };
110
+ }
111
+
112
+ /**
113
+ * Get the details view fields
114
+ * @param {PostcodeLookupDetailsData | undefined} details
115
+ * @param {OptionalValidationErrorItem} postcodeQueryError
116
+ * @param {OptionalValidationErrorItem} buildingNameQueryError
117
+ */
118
+ function getDetailsFields(details, postcodeQueryError, buildingNameQueryError) {
119
+ return {
120
+ [postcodeQueryFieldName]: {
121
+ id: postcodeQueryFieldName,
122
+ name: postcodeQueryFieldName,
123
+ label: {
124
+ text: 'Postcode'
125
+ },
126
+ hint: {
127
+ text: 'For example, AA3 1AB'
128
+ },
129
+ value: details?.postcodeQuery,
130
+ errorMessage: postcodeQueryError && {
131
+ text: postcodeQueryError.message
132
+ }
133
+ },
134
+ [buildingNameQueryFieldName]: {
135
+ id: buildingNameQueryFieldName,
136
+ name: buildingNameQueryFieldName,
137
+ label: {
138
+ text: 'Building name or number (optional)'
139
+ },
140
+ hint: {
141
+ text: 'For example, 15 or Prospect Cottage'
142
+ },
143
+ value: details?.buildingNameQuery,
144
+ errorMessage: buildingNameQueryError && {
145
+ text: buildingNameQueryError.message
146
+ }
147
+ }
148
+ };
149
+ }
150
+
151
+ /**
152
+ * Get the select view fields
153
+ * @param {PostcodeLookupDetailsData} details
154
+ * @param {boolean} hasMultipleAddresses
155
+ * @param {Address | undefined} singleAddress
156
+ * @param {PostcodeLookupSelectPayload | undefined} payload
157
+ * @param {OptionalValidationErrorItem} uprnError
158
+ * @param {Address[]} addresses
159
+ */
160
+ function getSelectFields(details, hasMultipleAddresses, singleAddress, payload, uprnError, addresses) {
161
+ return {
162
+ [postcodeQueryFieldName]: {
163
+ id: postcodeQueryFieldName,
164
+ name: postcodeQueryFieldName,
165
+ type: 'hidden',
166
+ value: details.postcodeQuery
167
+ },
168
+ [buildingNameQueryFieldName]: {
169
+ id: buildingNameQueryFieldName,
170
+ name: buildingNameQueryFieldName,
171
+ type: 'hidden',
172
+ value: details.buildingNameQuery
173
+ },
174
+ [uprnFieldName]: {
175
+ id: uprnFieldName,
176
+ name: uprnFieldName,
177
+ label: hasMultipleAddresses ? {
178
+ text: selectLabelText
179
+ } : undefined,
180
+ value: singleAddress ? singleAddress.uprn : payload?.uprn,
181
+ errorMessage: uprnError && {
182
+ text: uprnError.message
183
+ },
184
+ items: hasMultipleAddresses ? [{
185
+ text: selectLabelText,
186
+ value: ''
187
+ }].concat(addresses.map(item => ({
188
+ text: item.formatted,
189
+ value: item.uprn
190
+ }))) : undefined,
191
+ type: singleAddress ? 'hidden' : undefined
192
+ }
193
+ };
194
+ }
195
+
196
+ /**
197
+ * Get the manual view fields
198
+ * @param {PostcodeLookupManualPayload | undefined} payload
199
+ * @param {OptionalValidationErrorItem} line1Error
200
+ * @param {OptionalValidationErrorItem} line2Error
201
+ * @param {OptionalValidationErrorItem} townError
202
+ * @param {OptionalValidationErrorItem} countyError
203
+ * @param {OptionalValidationErrorItem} postcodeError
204
+ */
205
+ function getManualFields(payload, line1Error, line2Error, townError, countyError, postcodeError) {
206
+ return {
207
+ [line1FieldName]: {
208
+ id: line1FieldName,
209
+ name: line1FieldName,
210
+ label: {
211
+ text: 'Address line 1'
212
+ },
213
+ value: payload?.addressLine1,
214
+ errorMessage: line1Error && {
215
+ text: line1Error.message
216
+ }
217
+ },
218
+ [line2FieldName]: {
219
+ id: line2FieldName,
220
+ name: line2FieldName,
221
+ label: {
222
+ text: 'Address line 2 (optional)'
223
+ },
224
+ value: payload?.addressLine2,
225
+ errorMessage: line2Error && {
226
+ text: line2Error.message
227
+ }
228
+ },
229
+ [townFieldName]: {
230
+ id: townFieldName,
231
+ name: townFieldName,
232
+ label: {
233
+ text: 'Town or city'
234
+ },
235
+ classes: 'govuk-!-width-two-thirds',
236
+ value: payload?.town,
237
+ errorMessage: townError && {
238
+ text: townError.message
239
+ }
240
+ },
241
+ [countyFieldName]: {
242
+ id: countyFieldName,
243
+ name: countyFieldName,
244
+ label: {
245
+ text: 'County (optional)'
246
+ },
247
+ value: payload?.county,
248
+ errorMessage: countyError && {
249
+ text: countyError.message
250
+ }
251
+ },
252
+ [postcodeFieldName]: {
253
+ id: postcodeFieldName,
254
+ name: postcodeFieldName,
255
+ label: {
256
+ text: 'Postcode'
257
+ },
258
+ classes: 'govuk-input--width-10',
259
+ value: payload?.postcode,
260
+ errorMessage: postcodeError && {
261
+ text: postcodeError.message
262
+ }
263
+ }
264
+ };
265
+ }
266
+ export const stepSchema = Joi.string().valid(...Object.keys(steps)).required();
267
+ const sharedPayloadSchemaKeys = {
268
+ crumb: crumbSchema,
269
+ step: stepSchema
270
+ };
271
+
272
+ /**
273
+ * Postcode lookup details form payload schema
274
+ * @type {ObjectSchema<PostcodeLookupDetailsPayload>}
275
+ */
276
+ export const detailsPayloadSchema = Joi.object().keys({
277
+ ...sharedPayloadSchemaKeys,
278
+ [postcodeQueryFieldName]: Joi.string().pattern(/^[a-zA-Z]{1,2}\d[a-zA-Z\d]?\s?\d[a-zA-Z]{2}$/).trim().required().messages({
279
+ 'string.pattern.base': 'Enter a valid postcode or enter an address manually',
280
+ '*': 'Enter a postcode'
281
+ }),
282
+ [buildingNameQueryFieldName]: Joi.string().trim().required().allow('').trim()
283
+ }).required();
284
+
285
+ /**
286
+ * Postcode lookup select form payload schema
287
+ * @type {ObjectSchema<PostcodeLookupSelectPayload>}
288
+ */
289
+ export const selectPayloadSchema = Joi.object().keys({
290
+ ...sharedPayloadSchemaKeys,
291
+ [uprnFieldName]: Joi.string().required().messages({
292
+ '*': selectLabelText
293
+ })
294
+ }).required();
295
+
296
+ /**
297
+ * Postcode lookup manual form payload schema
298
+ * @type {ObjectSchema<PostcodeLookupManualPayload>}
299
+ */
300
+ export const manualPayloadSchema = Joi.object().keys({
301
+ ...sharedPayloadSchemaKeys,
302
+ [line1FieldName]: Joi.string().trim().required().messages({
303
+ '*': 'Enter address line 1'
304
+ }),
305
+ [line2FieldName]: Joi.string().trim().allow('').required(),
306
+ [townFieldName]: Joi.string().trim().required().messages({
307
+ '*': 'Enter town or city'
308
+ }),
309
+ [countyFieldName]: Joi.string().trim().allow('').required(),
310
+ [postcodeFieldName]: Joi.string().trim().required().messages({
311
+ '*': 'Enter postcode'
312
+ })
313
+ }).required();
314
+
315
+ /**
316
+ * Get the postcode lookup href
317
+ * @param {string} [step] - the postcode lookup step
318
+ */
319
+ function getHref(step) {
320
+ const query = step ? `?step=${step}` : '';
321
+ return `${JOURNEY_BASE_URL}${query}`;
322
+ }
323
+
324
+ /**
325
+ * The postcode lookup details form view model
326
+ * @param {PostcodeLookupSessionData} data
327
+ * @param {PostcodeLookupDetailsData} [payload]
328
+ * @param {Error} [err]
329
+ */
330
+ export function detailsViewModel(data, payload, err) {
331
+ const {
332
+ componentTitle: pageTitle,
333
+ formName,
334
+ sourceUrl
335
+ } = data.initial;
336
+ const backLink = {
337
+ href: sourceUrl
338
+ };
339
+ const {
340
+ errors,
341
+ postcodeQueryError,
342
+ buildingNameQueryError
343
+ } = buildErrors(err);
344
+
345
+ // Model fields
346
+ const fields = getDetailsFields(payload ?? data.details, postcodeQueryError, buildingNameQueryError);
347
+
348
+ // Model buttons
349
+ const continueButton = {
350
+ text: 'Find address',
351
+ classes: GOVUK_MARGIN_RIGHT_1
352
+ };
353
+ const manualLink = {
354
+ text: 'enter address manually',
355
+ href: getHref(steps.manual)
356
+ };
357
+ return {
358
+ step: steps.details,
359
+ showTitle: true,
360
+ name: formName,
361
+ serviceUrl: sourceUrl,
362
+ pageTitle,
363
+ backLink,
364
+ errors,
365
+ fields,
366
+ buttons: {
367
+ continueButton,
368
+ manualLink
369
+ }
370
+ };
371
+ }
372
+
373
+ /**
374
+ * The postcode lookup select form view model
375
+ * @param {{ session: PostcodeLookupSessionData, apiKey: string }} data
376
+ * @param {PostcodeLookupSelectPayload} [payload]
377
+ * @param {Error} [err]
378
+ */
379
+ export async function selectViewModel(data, payload, err) {
380
+ const {
381
+ session,
382
+ apiKey
383
+ } = data;
384
+ const {
385
+ details,
386
+ initial
387
+ } = session;
388
+ const {
389
+ postcodeQuery,
390
+ buildingNameQuery
391
+ } = details;
392
+
393
+ // Search for addresses
394
+ const {
395
+ hasAddresses,
396
+ hasMultipleAddresses,
397
+ singleAddress,
398
+ addresses,
399
+ addressCount
400
+ } = await getAddresses(postcodeQuery, buildingNameQuery, apiKey);
401
+ const title = hasAddresses ? initial.componentTitle : 'No address found';
402
+ const formPath = initial.sourceUrl;
403
+ const href = getHref();
404
+ const backLink = {
405
+ href
406
+ };
407
+ const {
408
+ errors,
409
+ uprnError
410
+ } = buildErrors(err);
411
+
412
+ // Model fields
413
+ const fields = getSelectFields(details, hasMultipleAddresses, singleAddress, payload, uprnError, addresses);
414
+ const searchAgainLink = {
415
+ text: 'Search again',
416
+ href
417
+ };
418
+
419
+ // Model buttons
420
+ const continueButton = {
421
+ href: hasAddresses ? undefined : href,
422
+ text: hasAddresses ? 'Use this address' : 'Search again',
423
+ classes: GOVUK_MARGIN_RIGHT_1
424
+ };
425
+ const manualLink = {
426
+ text: 'enter address manually',
427
+ href: `${href}?step=${steps.manual}`
428
+ };
429
+ return {
430
+ step: steps.select,
431
+ showTitle: true,
432
+ name: title,
433
+ serviceUrl: formPath,
434
+ pageTitle: title,
435
+ backLink,
436
+ errors,
437
+ searchAgainLink,
438
+ fields,
439
+ details,
440
+ addressCount,
441
+ singleAddress,
442
+ hasAddresses,
443
+ hasMultipleAddresses,
444
+ buttons: {
445
+ continueButton,
446
+ manualLink
447
+ }
448
+ };
449
+ }
450
+
451
+ /**
452
+ * The postcode lookup manual form view model
453
+ * @param {PostcodeLookupSessionData} data
454
+ * @param {PostcodeLookupManualPayload} [payload]
455
+ * @param {Error} [err]
456
+ */
457
+ export function manualViewModel(data, payload, err) {
458
+ const {
459
+ componentTitle,
460
+ sourceUrl,
461
+ componentHint
462
+ } = data.initial;
463
+ const formPath = sourceUrl;
464
+ const href = getHref();
465
+ const backLink = {
466
+ href
467
+ };
468
+ const {
469
+ errors,
470
+ line1Error,
471
+ line2Error,
472
+ townError,
473
+ countyError,
474
+ postcodeError
475
+ } = buildErrors(err);
476
+
477
+ // Model hint
478
+ const hint = componentHint && {
479
+ text: componentHint
480
+ };
481
+
482
+ // Model fields
483
+ const fields = getManualFields(payload, line1Error, line2Error, townError, countyError, postcodeError);
484
+
485
+ // Model buttons
486
+ const continueButton = {
487
+ text: 'Use this address',
488
+ classes: GOVUK_MARGIN_RIGHT_1
489
+ };
490
+ const detailsLink = {
491
+ text: 'find an address instead',
492
+ href
493
+ };
494
+ return {
495
+ step: steps.manual,
496
+ showTitle: true,
497
+ name: componentTitle,
498
+ serviceUrl: formPath,
499
+ pageTitle: componentTitle,
500
+ backLink,
501
+ errors,
502
+ hint,
503
+ fields,
504
+ buttons: {
505
+ continueButton,
506
+ detailsLink
507
+ }
508
+ };
509
+ }
510
+
511
+ /** @typedef { ValidationErrorItem | undefined } OptionalValidationErrorItem */
512
+
513
+ /**
514
+ * @import { ObjectSchema, ValidationErrorItem } from 'joi'
515
+ * @import { Address, PostcodeLookupDetailsData, PostcodeLookupDetailsPayload, PostcodeLookupManualPayload, PostcodeLookupSelectPayload, PostcodeLookupSessionData } from '~/src/server/plugins/postcode-lookup/types.js'
516
+ */
517
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":["Joi","service","crumbSchema","postcodeQueryFieldName","buildingNameQueryFieldName","uprnFieldName","line1FieldName","line2FieldName","townFieldName","countyFieldName","postcodeFieldName","selectLabelText","GOVUK_MARGIN_RIGHT_1","steps","details","select","manual","JOURNEY_BASE_URL","buildErrors","err","hasErrors","isError","length","getError","fieldName","find","item","path","postcodeQueryError","buildingNameQueryError","uprnError","line1Error","line2Error","townError","countyError","postcodeError","errors","pushError","push","text","message","href","getAddresses","postcodeQuery","buildingNameQuery","apiKey","addresses","search","addressCount","singleAddress","at","undefined","hasAddresses","hasMultipleAddresses","getDetailsFields","id","name","label","hint","value","errorMessage","getSelectFields","payload","type","uprn","items","concat","map","formatted","getManualFields","addressLine1","addressLine2","classes","town","county","postcode","stepSchema","string","valid","Object","keys","required","sharedPayloadSchemaKeys","crumb","step","detailsPayloadSchema","object","pattern","trim","messages","allow","selectPayloadSchema","manualPayloadSchema","getHref","query","detailsViewModel","data","componentTitle","pageTitle","formName","sourceUrl","initial","backLink","fields","continueButton","manualLink","showTitle","serviceUrl","buttons","selectViewModel","session","title","formPath","searchAgainLink","manualViewModel","componentHint","detailsLink"],"sources":["../../../../../src/server/plugins/postcode-lookup/models/index.js"],"sourcesContent":["import Joi from 'joi'\n\nimport * as service from '~/src/server/plugins/postcode-lookup/service.js'\nimport { crumbSchema } from '~/src/server/schemas/index.js'\n\n// Field names/ids\nconst postcodeQueryFieldName = 'postcodeQuery'\nconst buildingNameQueryFieldName = 'buildingNameQuery'\nconst uprnFieldName = 'uprn'\n\nconst line1FieldName = 'addressLine1'\nconst line2FieldName = 'addressLine2'\nconst townFieldName = 'town'\nconst countyFieldName = 'county'\nconst postcodeFieldName = 'postcode'\n\nconst selectLabelText = 'Select an address'\n\nconst GOVUK_MARGIN_RIGHT_1 = 'govuk-!-margin-right-1'\n\nexport const steps = {\n // Step 1: Postcode/building name input\n details: 'details',\n // Step 2: Select address\n select: 'select',\n // Step 3: Manual address\n manual: 'manual'\n}\n\nexport const JOURNEY_BASE_URL = '/postcode-lookup'\n\n/**\n * Build form errors\n * @param {Error} [err]\n */\nfunction buildErrors(err) {\n const hasErrors = Joi.isError(err) && err.details.length > 0\n\n if (!hasErrors) {\n return {}\n }\n\n /**\n * Get error by path\n * @param {string} fieldName\n */\n const getError = (fieldName) => {\n return err.details.find((item) => item.path[0] === fieldName)\n }\n\n const postcodeQueryError = getError(postcodeQueryFieldName)\n const buildingNameQueryError = getError(buildingNameQueryFieldName)\n const uprnError = getError(uprnFieldName)\n const line1Error = getError(line1FieldName)\n const line2Error = getError(line2FieldName)\n const townError = getError(townFieldName)\n const countyError = getError(countyFieldName)\n const postcodeError = getError(postcodeFieldName)\n\n /**\n * @type {{ text: string, href: string }[]}\n */\n const errors = []\n\n /**\n * Push error\n * @param {string} fieldName - the field name\n * @param {ValidationErrorItem} [item] - the joi validation error\n */\n const pushError = (fieldName, item) => {\n if (item) {\n errors.push({\n text: item.message,\n href: `#${fieldName}`\n })\n }\n }\n\n pushError(postcodeQueryFieldName, postcodeQueryError)\n pushError(buildingNameQueryFieldName, buildingNameQueryError)\n pushError(uprnFieldName, uprnError)\n pushError(line1FieldName, line1Error)\n pushError(line2FieldName, line2Error)\n pushError(townFieldName, townError)\n pushError(countyFieldName, countyError)\n pushError(postcodeFieldName, postcodeError)\n\n return {\n errors,\n postcodeQueryError,\n buildingNameQueryError,\n uprnError,\n line1Error,\n line2Error,\n townError,\n countyError,\n postcodeError\n }\n}\n\n/**\n * Search ordnance survey for addresses\n * @param {string} postcodeQuery\n * @param {string} buildingNameQuery\n * @param {string} apiKey\n */\nasync function getAddresses(postcodeQuery, buildingNameQuery, apiKey) {\n const addresses = await service.search(\n postcodeQuery,\n buildingNameQuery,\n apiKey\n )\n const addressCount = addresses.length\n const singleAddress = addressCount === 1 ? addresses.at(0) : undefined\n const hasAddresses = addressCount > 0\n const hasMultipleAddresses = addressCount > 1\n\n return {\n hasAddresses,\n hasMultipleAddresses,\n singleAddress,\n addresses,\n addressCount\n }\n}\n\n/**\n * Get the details view fields\n * @param {PostcodeLookupDetailsData | undefined} details\n * @param {OptionalValidationErrorItem} postcodeQueryError\n * @param {OptionalValidationErrorItem} buildingNameQueryError\n */\nfunction getDetailsFields(details, postcodeQueryError, buildingNameQueryError) {\n return {\n [postcodeQueryFieldName]: {\n id: postcodeQueryFieldName,\n name: postcodeQueryFieldName,\n label: {\n text: 'Postcode'\n },\n hint: {\n text: 'For example, AA3 1AB'\n },\n value: details?.postcodeQuery,\n errorMessage: postcodeQueryError && { text: postcodeQueryError.message }\n },\n [buildingNameQueryFieldName]: {\n id: buildingNameQueryFieldName,\n name: buildingNameQueryFieldName,\n label: {\n text: 'Building name or number (optional)'\n },\n hint: {\n text: 'For example, 15 or Prospect Cottage'\n },\n value: details?.buildingNameQuery,\n errorMessage: buildingNameQueryError && {\n text: buildingNameQueryError.message\n }\n }\n }\n}\n\n/**\n * Get the select view fields\n * @param {PostcodeLookupDetailsData} details\n * @param {boolean} hasMultipleAddresses\n * @param {Address | undefined} singleAddress\n * @param {PostcodeLookupSelectPayload | undefined} payload\n * @param {OptionalValidationErrorItem} uprnError\n * @param {Address[]} addresses\n */\nfunction getSelectFields(\n details,\n hasMultipleAddresses,\n singleAddress,\n payload,\n uprnError,\n addresses\n) {\n return {\n [postcodeQueryFieldName]: {\n id: postcodeQueryFieldName,\n name: postcodeQueryFieldName,\n type: 'hidden',\n value: details.postcodeQuery\n },\n [buildingNameQueryFieldName]: {\n id: buildingNameQueryFieldName,\n name: buildingNameQueryFieldName,\n type: 'hidden',\n value: details.buildingNameQuery\n },\n [uprnFieldName]: {\n id: uprnFieldName,\n name: uprnFieldName,\n label: hasMultipleAddresses\n ? {\n text: selectLabelText\n }\n : undefined,\n value: singleAddress ? singleAddress.uprn : payload?.uprn,\n errorMessage: uprnError && { text: uprnError.message },\n items: hasMultipleAddresses\n ? [{ text: selectLabelText, value: '' }].concat(\n addresses.map((item) => ({\n text: item.formatted,\n value: item.uprn\n }))\n )\n : undefined,\n type: singleAddress ? 'hidden' : undefined\n }\n }\n}\n\n/**\n * Get the manual view fields\n * @param {PostcodeLookupManualPayload | undefined} payload\n * @param {OptionalValidationErrorItem} line1Error\n * @param {OptionalValidationErrorItem} line2Error\n * @param {OptionalValidationErrorItem} townError\n * @param {OptionalValidationErrorItem} countyError\n * @param {OptionalValidationErrorItem} postcodeError\n */\nfunction getManualFields(\n payload,\n line1Error,\n line2Error,\n townError,\n countyError,\n postcodeError\n) {\n return {\n [line1FieldName]: {\n id: line1FieldName,\n name: line1FieldName,\n label: {\n text: 'Address line 1'\n },\n value: payload?.addressLine1,\n errorMessage: line1Error && { text: line1Error.message }\n },\n [line2FieldName]: {\n id: line2FieldName,\n name: line2FieldName,\n label: {\n text: 'Address line 2 (optional)'\n },\n value: payload?.addressLine2,\n errorMessage: line2Error && { text: line2Error.message }\n },\n [townFieldName]: {\n id: townFieldName,\n name: townFieldName,\n label: {\n text: 'Town or city'\n },\n classes: 'govuk-!-width-two-thirds',\n value: payload?.town,\n errorMessage: townError && { text: townError.message }\n },\n [countyFieldName]: {\n id: countyFieldName,\n name: countyFieldName,\n label: {\n text: 'County (optional)'\n },\n value: payload?.county,\n errorMessage: countyError && { text: countyError.message }\n },\n [postcodeFieldName]: {\n id: postcodeFieldName,\n name: postcodeFieldName,\n label: {\n text: 'Postcode'\n },\n classes: 'govuk-input--width-10',\n value: payload?.postcode,\n errorMessage: postcodeError && { text: postcodeError.message }\n }\n }\n}\n\nexport const stepSchema = Joi.string()\n .valid(...Object.keys(steps))\n .required()\n\nconst sharedPayloadSchemaKeys = {\n crumb: crumbSchema,\n step: stepSchema\n}\n\n/**\n * Postcode lookup details form payload schema\n * @type {ObjectSchema<PostcodeLookupDetailsPayload>}\n */\nexport const detailsPayloadSchema = Joi.object()\n .keys({\n ...sharedPayloadSchemaKeys,\n [postcodeQueryFieldName]: Joi.string()\n .pattern(/^[a-zA-Z]{1,2}\\d[a-zA-Z\\d]?\\s?\\d[a-zA-Z]{2}$/)\n .trim()\n .required()\n .messages({\n 'string.pattern.base':\n 'Enter a valid postcode or enter an address manually',\n '*': 'Enter a postcode'\n }),\n [buildingNameQueryFieldName]: Joi.string()\n .trim()\n .required()\n .allow('')\n .trim()\n })\n .required()\n\n/**\n * Postcode lookup select form payload schema\n * @type {ObjectSchema<PostcodeLookupSelectPayload>}\n */\nexport const selectPayloadSchema = Joi.object()\n .keys({\n ...sharedPayloadSchemaKeys,\n [uprnFieldName]: Joi.string().required().messages({\n '*': selectLabelText\n })\n })\n .required()\n\n/**\n * Postcode lookup manual form payload schema\n * @type {ObjectSchema<PostcodeLookupManualPayload>}\n */\nexport const manualPayloadSchema = Joi.object()\n .keys({\n ...sharedPayloadSchemaKeys,\n [line1FieldName]: Joi.string().trim().required().messages({\n '*': 'Enter address line 1'\n }),\n [line2FieldName]: Joi.string().trim().allow('').required(),\n [townFieldName]: Joi.string().trim().required().messages({\n '*': 'Enter town or city'\n }),\n [countyFieldName]: Joi.string().trim().allow('').required(),\n [postcodeFieldName]: Joi.string().trim().required().messages({\n '*': 'Enter postcode'\n })\n })\n .required()\n\n/**\n * Get the postcode lookup href\n * @param {string} [step] - the postcode lookup step\n */\nfunction getHref(step) {\n const query = step ? `?step=${step}` : ''\n\n return `${JOURNEY_BASE_URL}${query}`\n}\n\n/**\n * The postcode lookup details form view model\n * @param {PostcodeLookupSessionData} data\n * @param {PostcodeLookupDetailsData} [payload]\n * @param {Error} [err]\n */\nexport function detailsViewModel(data, payload, err) {\n const { componentTitle: pageTitle, formName, sourceUrl } = data.initial\n\n const backLink = {\n href: sourceUrl\n }\n\n const { errors, postcodeQueryError, buildingNameQueryError } =\n buildErrors(err)\n\n // Model fields\n const fields = getDetailsFields(\n payload ?? data.details,\n postcodeQueryError,\n buildingNameQueryError\n )\n\n // Model buttons\n const continueButton = {\n text: 'Find address',\n classes: GOVUK_MARGIN_RIGHT_1\n }\n const manualLink = {\n text: 'enter address manually',\n href: getHref(steps.manual)\n }\n\n return {\n step: steps.details,\n showTitle: true,\n name: formName,\n serviceUrl: sourceUrl,\n pageTitle,\n backLink,\n errors,\n fields,\n buttons: { continueButton, manualLink }\n }\n}\n\n/**\n * The postcode lookup select form view model\n * @param {{ session: PostcodeLookupSessionData, apiKey: string }} data\n * @param {PostcodeLookupSelectPayload} [payload]\n * @param {Error} [err]\n */\nexport async function selectViewModel(data, payload, err) {\n const { session, apiKey } = data\n const { details, initial } = session\n const { postcodeQuery, buildingNameQuery } = details\n\n // Search for addresses\n const {\n hasAddresses,\n hasMultipleAddresses,\n singleAddress,\n addresses,\n addressCount\n } = await getAddresses(postcodeQuery, buildingNameQuery, apiKey)\n\n const title = hasAddresses ? initial.componentTitle : 'No address found'\n const formPath = initial.sourceUrl\n const href = getHref()\n\n const backLink = { href }\n\n const { errors, uprnError } = buildErrors(err)\n\n // Model fields\n const fields = getSelectFields(\n details,\n hasMultipleAddresses,\n singleAddress,\n payload,\n uprnError,\n addresses\n )\n\n const searchAgainLink = {\n text: 'Search again',\n href\n }\n\n // Model buttons\n const continueButton = {\n href: hasAddresses ? undefined : href,\n text: hasAddresses ? 'Use this address' : 'Search again',\n classes: GOVUK_MARGIN_RIGHT_1\n }\n const manualLink = {\n text: 'enter address manually',\n href: `${href}?step=${steps.manual}`\n }\n\n return {\n step: steps.select,\n showTitle: true,\n name: title,\n serviceUrl: formPath,\n pageTitle: title,\n backLink,\n errors,\n searchAgainLink,\n fields,\n details,\n addressCount,\n singleAddress,\n hasAddresses,\n hasMultipleAddresses,\n buttons: { continueButton, manualLink }\n }\n}\n\n/**\n * The postcode lookup manual form view model\n * @param {PostcodeLookupSessionData} data\n * @param {PostcodeLookupManualPayload} [payload]\n * @param {Error} [err]\n */\nexport function manualViewModel(data, payload, err) {\n const { componentTitle, sourceUrl, componentHint } = data.initial\n const formPath = sourceUrl\n const href = getHref()\n\n const backLink = {\n href\n }\n\n const {\n errors,\n line1Error,\n line2Error,\n townError,\n countyError,\n postcodeError\n } = buildErrors(err)\n\n // Model hint\n const hint = componentHint && {\n text: componentHint\n }\n\n // Model fields\n const fields = getManualFields(\n payload,\n line1Error,\n line2Error,\n townError,\n countyError,\n postcodeError\n )\n\n // Model buttons\n const continueButton = {\n text: 'Use this address',\n classes: GOVUK_MARGIN_RIGHT_1\n }\n const detailsLink = {\n text: 'find an address instead',\n href\n }\n\n return {\n step: steps.manual,\n showTitle: true,\n name: componentTitle,\n serviceUrl: formPath,\n pageTitle: componentTitle,\n backLink,\n errors,\n hint,\n fields,\n buttons: { continueButton, detailsLink }\n }\n}\n\n/** @typedef { ValidationErrorItem | undefined } OptionalValidationErrorItem */\n\n/**\n * @import { ObjectSchema, ValidationErrorItem } from 'joi'\n * @import { Address, PostcodeLookupDetailsData, PostcodeLookupDetailsPayload, PostcodeLookupManualPayload, PostcodeLookupSelectPayload, PostcodeLookupSessionData } from '~/src/server/plugins/postcode-lookup/types.js'\n */\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Initialises and dispatches the request to the postcode lookup journey
3
+ * @param {FormRequestPayload} request - the source page
4
+ * @param {FormResponseToolkit} h - the source page
5
+ * @param {PostcodeLookupDispatchData} initial - the source data
6
+ */
7
+ export function dispatch(request: FormRequestPayload, h: FormResponseToolkit, initial: PostcodeLookupDispatchData): import("@hapi/hapi").ResponseObject;
8
+ /**
9
+ * Gets the postcode lookup routes
10
+ * @param {PostcodeLookupConfiguration} options - ordnance survey api key
11
+ */
12
+ export function getRoutes(options: PostcodeLookupConfiguration): (ServerRoute<PostcodeLookupGetRequestRefs> | ServerRoute<PostcodeLookupPostRequestRefs>)[];
13
+ import type { FormRequestPayload } from '~/src/server/routes/types.js';
14
+ import type { FormResponseToolkit } from '~/src/server/routes/types.js';
15
+ import type { PostcodeLookupDispatchData } from '~/src/server/plugins/postcode-lookup/types.js';
16
+ import type { PostcodeLookupConfiguration } from '~/src/server/plugins/postcode-lookup/types.js';
17
+ import type { PostcodeLookupGetRequestRefs } from '~/src/server/plugins/postcode-lookup/types.js';
18
+ import type { ServerRoute } from '@hapi/hapi';
19
+ import type { PostcodeLookupPostRequestRefs } from '~/src/server/plugins/postcode-lookup/types.js';