@defra/forms-engine-plugin 4.22.0 → 5.0.0-alpha

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 (309) hide show
  1. package/.server/server/forms/register-as-a-unicorn-breeder.yaml +0 -14
  2. package/.server/server/forms/simple-form.yaml +106 -3
  3. package/.server/server/plugins/engine/components/AutocompleteField.d.ts +11 -11
  4. package/.server/server/plugins/engine/components/AutocompleteField.js +2 -2
  5. package/.server/server/plugins/engine/components/AutocompleteField.js.map +1 -1
  6. package/.server/server/plugins/engine/components/CheckboxesField.d.ts +3 -2
  7. package/.server/server/plugins/engine/components/CheckboxesField.js +4 -9
  8. package/.server/server/plugins/engine/components/CheckboxesField.js.map +1 -1
  9. package/.server/server/plugins/engine/components/ComponentCollection.d.ts +8 -7
  10. package/.server/server/plugins/engine/components/ComponentCollection.js +106 -51
  11. package/.server/server/plugins/engine/components/ComponentCollection.js.map +1 -1
  12. package/.server/server/plugins/engine/components/DatePartsField.d.ts +8 -6
  13. package/.server/server/plugins/engine/components/DatePartsField.js +27 -9
  14. package/.server/server/plugins/engine/components/DatePartsField.js.map +1 -1
  15. package/.server/server/plugins/engine/components/DeclarationField.d.ts +13 -11
  16. package/.server/server/plugins/engine/components/DeclarationField.js +31 -9
  17. package/.server/server/plugins/engine/components/DeclarationField.js.map +1 -1
  18. package/.server/server/plugins/engine/components/EastingNorthingField.d.ts +6 -5
  19. package/.server/server/plugins/engine/components/EastingNorthingField.js +42 -22
  20. package/.server/server/plugins/engine/components/EastingNorthingField.js.map +1 -1
  21. package/.server/server/plugins/engine/components/EmailAddressField.d.ts +11 -14
  22. package/.server/server/plugins/engine/components/EmailAddressField.js +2 -2
  23. package/.server/server/plugins/engine/components/EmailAddressField.js.map +1 -1
  24. package/.server/server/plugins/engine/components/FileUploadField.d.ts +14 -12
  25. package/.server/server/plugins/engine/components/FileUploadField.js +22 -12
  26. package/.server/server/plugins/engine/components/FileUploadField.js.map +1 -1
  27. package/.server/server/plugins/engine/components/FormComponent.d.ts +21 -12
  28. package/.server/server/plugins/engine/components/FormComponent.js +33 -14
  29. package/.server/server/plugins/engine/components/FormComponent.js.map +1 -1
  30. package/.server/server/plugins/engine/components/GeospatialField.d.ts +14 -12
  31. package/.server/server/plugins/engine/components/GeospatialField.js +19 -13
  32. package/.server/server/plugins/engine/components/GeospatialField.js.map +1 -1
  33. package/.server/server/plugins/engine/components/LatLongField.d.ts +6 -5
  34. package/.server/server/plugins/engine/components/LatLongField.js +32 -20
  35. package/.server/server/plugins/engine/components/LatLongField.js.map +1 -1
  36. package/.server/server/plugins/engine/components/ListFormComponent.d.ts +7 -6
  37. package/.server/server/plugins/engine/components/ListFormComponent.js +19 -7
  38. package/.server/server/plugins/engine/components/ListFormComponent.js.map +1 -1
  39. package/.server/server/plugins/engine/components/LocationFieldBase.d.ts +17 -16
  40. package/.server/server/plugins/engine/components/LocationFieldBase.js +2 -2
  41. package/.server/server/plugins/engine/components/LocationFieldBase.js.map +1 -1
  42. package/.server/server/plugins/engine/components/LocationFieldHelpers.d.ts +3 -3
  43. package/.server/server/plugins/engine/components/LocationFieldHelpers.js +2 -2
  44. package/.server/server/plugins/engine/components/LocationFieldHelpers.js.map +1 -1
  45. package/.server/server/plugins/engine/components/Markdown.d.ts +8 -7
  46. package/.server/server/plugins/engine/components/Markdown.js +5 -2
  47. package/.server/server/plugins/engine/components/Markdown.js.map +1 -1
  48. package/.server/server/plugins/engine/components/MonthYearField.d.ts +9 -7
  49. package/.server/server/plugins/engine/components/MonthYearField.js +26 -8
  50. package/.server/server/plugins/engine/components/MonthYearField.js.map +1 -1
  51. package/.server/server/plugins/engine/components/MultilineTextField.d.ts +10 -9
  52. package/.server/server/plugins/engine/components/MultilineTextField.js +2 -2
  53. package/.server/server/plugins/engine/components/MultilineTextField.js.map +1 -1
  54. package/.server/server/plugins/engine/components/NationalGridFieldNumberField.d.ts +2 -1
  55. package/.server/server/plugins/engine/components/NationalGridFieldNumberField.js +14 -6
  56. package/.server/server/plugins/engine/components/NationalGridFieldNumberField.js.map +1 -1
  57. package/.server/server/plugins/engine/components/NumberField.d.ts +10 -9
  58. package/.server/server/plugins/engine/components/NumberField.js +2 -2
  59. package/.server/server/plugins/engine/components/NumberField.js.map +1 -1
  60. package/.server/server/plugins/engine/components/OsGridRefField.d.ts +2 -1
  61. package/.server/server/plugins/engine/components/OsGridRefField.js +14 -6
  62. package/.server/server/plugins/engine/components/OsGridRefField.js.map +1 -1
  63. package/.server/server/plugins/engine/components/PaymentField.d.ts +12 -10
  64. package/.server/server/plugins/engine/components/PaymentField.js +21 -8
  65. package/.server/server/plugins/engine/components/PaymentField.js.map +1 -1
  66. package/.server/server/plugins/engine/components/SelectField.d.ts +11 -11
  67. package/.server/server/plugins/engine/components/SelectField.js +2 -2
  68. package/.server/server/plugins/engine/components/SelectField.js.map +1 -1
  69. package/.server/server/plugins/engine/components/SelectionControlField.d.ts +4 -4
  70. package/.server/server/plugins/engine/components/SelectionControlField.js +2 -2
  71. package/.server/server/plugins/engine/components/SelectionControlField.js.map +1 -1
  72. package/.server/server/plugins/engine/components/TelephoneNumberField.d.ts +10 -9
  73. package/.server/server/plugins/engine/components/TelephoneNumberField.js +2 -2
  74. package/.server/server/plugins/engine/components/TelephoneNumberField.js.map +1 -1
  75. package/.server/server/plugins/engine/components/UkAddressField.d.ts +12 -10
  76. package/.server/server/plugins/engine/components/UkAddressField.js +29 -17
  77. package/.server/server/plugins/engine/components/UkAddressField.js.map +1 -1
  78. package/.server/server/plugins/engine/components/YesNoField.d.ts +3 -0
  79. package/.server/server/plugins/engine/components/YesNoField.js +9 -0
  80. package/.server/server/plugins/engine/components/YesNoField.js.map +1 -1
  81. package/.server/server/plugins/engine/components/helpers/components.d.ts +3 -2
  82. package/.server/server/plugins/engine/components/helpers/components.js +11 -8
  83. package/.server/server/plugins/engine/components/helpers/components.js.map +1 -1
  84. package/.server/server/plugins/engine/components/types.d.ts +8 -1
  85. package/.server/server/plugins/engine/components/types.js.map +1 -1
  86. package/.server/server/plugins/engine/configureEnginePlugin.js +8 -1
  87. package/.server/server/plugins/engine/configureEnginePlugin.js.map +1 -1
  88. package/.server/server/plugins/engine/form-context.d.ts +1 -0
  89. package/.server/server/plugins/engine/form-context.js +4 -2
  90. package/.server/server/plugins/engine/form-context.js.map +1 -1
  91. package/.server/server/plugins/engine/helpers.d.ts +1 -1
  92. package/.server/server/plugins/engine/helpers.js +8 -13
  93. package/.server/server/plugins/engine/helpers.js.map +1 -1
  94. package/.server/server/plugins/engine/i18n/buildValidationMessages.d.ts +39 -0
  95. package/.server/server/plugins/engine/i18n/buildValidationMessages.js +50 -0
  96. package/.server/server/plugins/engine/i18n/buildValidationMessages.js.map +1 -0
  97. package/.server/server/plugins/engine/i18n/createFormTranslator.d.ts +5 -0
  98. package/.server/server/plugins/engine/i18n/createFormTranslator.js +18 -0
  99. package/.server/server/plugins/engine/i18n/createFormTranslator.js.map +1 -0
  100. package/.server/server/plugins/engine/i18n/createTranslator.d.ts +9 -0
  101. package/.server/server/plugins/engine/i18n/createTranslator.js +51 -0
  102. package/.server/server/plugins/engine/i18n/createTranslator.js.map +1 -0
  103. package/.server/server/plugins/engine/i18n/extractBaseTranslations.d.ts +5 -0
  104. package/.server/server/plugins/engine/i18n/extractBaseTranslations.js +57 -0
  105. package/.server/server/plugins/engine/i18n/extractBaseTranslations.js.map +1 -0
  106. package/.server/server/plugins/engine/i18n/index.d.ts +18 -0
  107. package/.server/server/plugins/engine/i18n/index.js +71 -0
  108. package/.server/server/plugins/engine/i18n/index.js.map +1 -0
  109. package/.server/server/plugins/engine/i18n/translations/cy.json +271 -0
  110. package/.server/server/plugins/engine/i18n/translations/en-GB.json +271 -0
  111. package/.server/server/plugins/engine/i18n/types.d.ts +41 -0
  112. package/.server/server/plugins/engine/i18n/types.js +2 -0
  113. package/.server/server/plugins/engine/i18n/types.js.map +1 -0
  114. package/.server/server/plugins/engine/index.js +3 -2
  115. package/.server/server/plugins/engine/index.js.map +1 -1
  116. package/.server/server/plugins/engine/models/FormModel.d.ts +9 -1
  117. package/.server/server/plugins/engine/models/FormModel.js +44 -18
  118. package/.server/server/plugins/engine/models/FormModel.js.map +1 -1
  119. package/.server/server/plugins/engine/models/SummaryViewModel.d.ts +5 -2
  120. package/.server/server/plugins/engine/models/SummaryViewModel.js +44 -18
  121. package/.server/server/plugins/engine/models/SummaryViewModel.js.map +1 -1
  122. package/.server/server/plugins/engine/options.js +2 -1
  123. package/.server/server/plugins/engine/options.js.map +1 -1
  124. package/.server/server/plugins/engine/outputFormatters/adapter/v1.js +4 -0
  125. package/.server/server/plugins/engine/outputFormatters/adapter/v1.js.map +1 -1
  126. package/.server/server/plugins/engine/outputFormatters/human/v1.js +2 -1
  127. package/.server/server/plugins/engine/outputFormatters/human/v1.js.map +1 -1
  128. package/.server/server/plugins/engine/outputFormatters/machine/v1.js +7 -6
  129. package/.server/server/plugins/engine/outputFormatters/machine/v1.js.map +1 -1
  130. package/.server/server/plugins/engine/pageControllers/FileUploadPageController.d.ts +2 -1
  131. package/.server/server/plugins/engine/pageControllers/FileUploadPageController.js +6 -3
  132. package/.server/server/plugins/engine/pageControllers/FileUploadPageController.js.map +1 -1
  133. package/.server/server/plugins/engine/pageControllers/PageController.d.ts +3 -1
  134. package/.server/server/plugins/engine/pageControllers/PageController.js +11 -1
  135. package/.server/server/plugins/engine/pageControllers/PageController.js.map +1 -1
  136. package/.server/server/plugins/engine/pageControllers/QuestionPageController.d.ts +4 -2
  137. package/.server/server/plugins/engine/pageControllers/QuestionPageController.js +52 -21
  138. package/.server/server/plugins/engine/pageControllers/QuestionPageController.js.map +1 -1
  139. package/.server/server/plugins/engine/pageControllers/RepeatPageController.d.ts +3 -2
  140. package/.server/server/plugins/engine/pageControllers/RepeatPageController.js +63 -26
  141. package/.server/server/plugins/engine/pageControllers/RepeatPageController.js.map +1 -1
  142. package/.server/server/plugins/engine/pageControllers/StartPageController.d.ts +3 -1
  143. package/.server/server/plugins/engine/pageControllers/StartPageController.js +2 -2
  144. package/.server/server/plugins/engine/pageControllers/StartPageController.js.map +1 -1
  145. package/.server/server/plugins/engine/pageControllers/StatusPageController.js +12 -2
  146. package/.server/server/plugins/engine/pageControllers/StatusPageController.js.map +1 -1
  147. package/.server/server/plugins/engine/pageControllers/SummaryPageController.d.ts +4 -3
  148. package/.server/server/plugins/engine/pageControllers/SummaryPageController.js +45 -28
  149. package/.server/server/plugins/engine/pageControllers/SummaryPageController.js.map +1 -1
  150. package/.server/server/plugins/engine/pageControllers/__stubs__/translator.d.ts +2 -0
  151. package/.server/server/plugins/engine/pageControllers/__stubs__/translator.js +24 -0
  152. package/.server/server/plugins/engine/pageControllers/__stubs__/translator.js.map +1 -0
  153. package/.server/server/plugins/engine/pageControllers/errors.d.ts +1 -1
  154. package/.server/server/plugins/engine/pageControllers/errors.js +3 -2
  155. package/.server/server/plugins/engine/pageControllers/errors.js.map +1 -1
  156. package/.server/server/plugins/engine/pageControllers/helpers/submission.d.ts +3 -2
  157. package/.server/server/plugins/engine/pageControllers/helpers/submission.js +4 -4
  158. package/.server/server/plugins/engine/pageControllers/helpers/submission.js.map +1 -1
  159. package/.server/server/plugins/engine/pageControllers/validationOptions.d.ts +7 -3
  160. package/.server/server/plugins/engine/pageControllers/validationOptions.js +34 -33
  161. package/.server/server/plugins/engine/pageControllers/validationOptions.js.map +1 -1
  162. package/.server/server/plugins/engine/plugin.js +2 -0
  163. package/.server/server/plugins/engine/plugin.js.map +1 -1
  164. package/.server/server/plugins/engine/routes/index.js +4 -1
  165. package/.server/server/plugins/engine/routes/index.js.map +1 -1
  166. package/.server/server/plugins/engine/routes/questions.js +5 -2
  167. package/.server/server/plugins/engine/routes/questions.js.map +1 -1
  168. package/.server/server/plugins/engine/types/index.d.ts +1 -0
  169. package/.server/server/plugins/engine/types/index.js.map +1 -1
  170. package/.server/server/plugins/engine/types/schema.js +1 -0
  171. package/.server/server/plugins/engine/types/schema.js.map +1 -1
  172. package/.server/server/plugins/engine/types.d.ts +12 -1
  173. package/.server/server/plugins/engine/types.js.map +1 -1
  174. package/.server/server/plugins/engine/views/components/_location-field-base.html +1 -1
  175. package/.server/server/plugins/engine/views/components/fileuploadfield.html +3 -3
  176. package/.server/server/plugins/engine/views/components/nationalgridfieldnumberfield.html +1 -1
  177. package/.server/server/plugins/engine/views/components/osgridreffield.html +1 -1
  178. package/.server/server/plugins/engine/views/components/paymentfield.html +8 -8
  179. package/.server/server/plugins/engine/views/components/ukaddressfield.html +4 -4
  180. package/.server/server/plugins/engine/views/confirmation.html +4 -4
  181. package/.server/server/plugins/engine/views/exit.html +4 -4
  182. package/.server/server/plugins/engine/views/file-upload.html +3 -3
  183. package/.server/server/plugins/engine/views/index.html +3 -3
  184. package/.server/server/plugins/engine/views/item-delete.html +1 -1
  185. package/.server/server/plugins/engine/views/partials/form.html +3 -3
  186. package/.server/server/plugins/engine/views/partials/preview-banner.html +4 -4
  187. package/.server/server/plugins/engine/views/partials/warn-missing-notification-email.html +4 -5
  188. package/.server/server/plugins/engine/views/repeat-list-summary.html +4 -4
  189. package/.server/server/plugins/engine/views/summary.html +14 -7
  190. package/.server/server/plugins/nunjucks/enviroment.test.js +10 -0
  191. package/.server/server/plugins/nunjucks/enviroment.test.js.map +1 -1
  192. package/.server/server/plugins/nunjucks/environment.d.ts +8 -0
  193. package/.server/server/plugins/nunjucks/environment.js +13 -0
  194. package/.server/server/plugins/nunjucks/environment.js.map +1 -1
  195. package/.server/server/plugins/nunjucks/filters/answer.js +9 -1
  196. package/.server/server/plugins/nunjucks/filters/answer.js.map +1 -1
  197. package/.server/server/plugins/nunjucks/filters/answer.test.js +13 -2
  198. package/.server/server/plugins/nunjucks/filters/answer.test.js.map +1 -1
  199. package/.server/server/plugins/nunjucks/filters/field.d.ts +1 -1
  200. package/.server/server/plugins/postcode-lookup/models/index.d.ts +24 -19
  201. package/.server/server/plugins/postcode-lookup/models/index.js +83 -76
  202. package/.server/server/plugins/postcode-lookup/models/index.js.map +1 -1
  203. package/.server/server/plugins/postcode-lookup/routes/index.js +7 -13
  204. package/.server/server/plugins/postcode-lookup/routes/index.js.map +1 -1
  205. package/.server/server/plugins/postcode-lookup/types.d.ts +1 -0
  206. package/.server/server/plugins/postcode-lookup/types.js +1 -0
  207. package/.server/server/plugins/postcode-lookup/types.js.map +1 -1
  208. package/.server/server/plugins/postcode-lookup/views/postcode-lookup-details.html +3 -3
  209. package/.server/server/types.d.ts +2 -1
  210. package/.server/server/types.js.map +1 -1
  211. package/.server/server/utils/utils.d.ts +5 -0
  212. package/.server/server/utils/utils.js +16 -0
  213. package/.server/server/utils/utils.js.map +1 -1
  214. package/.server/typings/hapi/index.d.js.map +1 -1
  215. package/package.json +3 -2
  216. package/src/server/forms/register-as-a-unicorn-breeder.yaml +0 -14
  217. package/src/server/forms/simple-form.yaml +106 -3
  218. package/src/server/plugins/engine/components/AutocompleteField.ts +3 -6
  219. package/src/server/plugins/engine/components/CheckboxesField.ts +12 -11
  220. package/src/server/plugins/engine/components/ComponentCollection.ts +143 -61
  221. package/src/server/plugins/engine/components/DatePartsField.ts +33 -11
  222. package/src/server/plugins/engine/components/DeclarationField.ts +37 -14
  223. package/src/server/plugins/engine/components/EastingNorthingField.ts +83 -22
  224. package/src/server/plugins/engine/components/EmailAddressField.ts +4 -7
  225. package/src/server/plugins/engine/components/FileUploadField.ts +28 -22
  226. package/src/server/plugins/engine/components/FormComponent.ts +49 -12
  227. package/src/server/plugins/engine/components/GeospatialField.ts +36 -21
  228. package/src/server/plugins/engine/components/LatLongField.ts +52 -21
  229. package/src/server/plugins/engine/components/ListFormComponent.ts +26 -10
  230. package/src/server/plugins/engine/components/LocationFieldBase.ts +5 -8
  231. package/src/server/plugins/engine/components/LocationFieldHelpers.ts +3 -3
  232. package/src/server/plugins/engine/components/Markdown.ts +7 -3
  233. package/src/server/plugins/engine/components/MonthYearField.ts +32 -10
  234. package/src/server/plugins/engine/components/MultilineTextField.ts +5 -8
  235. package/src/server/plugins/engine/components/NationalGridFieldNumberField.ts +25 -11
  236. package/src/server/plugins/engine/components/NumberField.ts +3 -4
  237. package/src/server/plugins/engine/components/OsGridRefField.ts +25 -9
  238. package/src/server/plugins/engine/components/PaymentField.ts +22 -12
  239. package/src/server/plugins/engine/components/SelectField.ts +3 -6
  240. package/src/server/plugins/engine/components/SelectionControlField.ts +7 -8
  241. package/src/server/plugins/engine/components/TelephoneNumberField.ts +4 -7
  242. package/src/server/plugins/engine/components/UkAddressField.ts +33 -18
  243. package/src/server/plugins/engine/components/YesNoField.ts +10 -0
  244. package/src/server/plugins/engine/components/helpers/components.ts +13 -6
  245. package/src/server/plugins/engine/components/types.ts +9 -0
  246. package/src/server/plugins/engine/configureEnginePlugin.ts +12 -1
  247. package/src/server/plugins/engine/form-context.ts +8 -2
  248. package/src/server/plugins/engine/helpers.ts +10 -18
  249. package/src/server/plugins/engine/i18n/buildValidationMessages.ts +69 -0
  250. package/src/server/plugins/engine/i18n/createFormTranslator.ts +33 -0
  251. package/src/server/plugins/engine/i18n/createTranslator.ts +61 -0
  252. package/src/server/plugins/engine/i18n/extractBaseTranslations.ts +61 -0
  253. package/src/server/plugins/engine/i18n/index.ts +80 -0
  254. package/src/server/plugins/engine/i18n/translations/cy.json +271 -0
  255. package/src/server/plugins/engine/i18n/translations/en-GB.json +271 -0
  256. package/src/server/plugins/engine/i18n/types.ts +62 -0
  257. package/src/server/plugins/engine/index.ts +4 -2
  258. package/src/server/plugins/engine/models/FormModel.ts +59 -23
  259. package/src/server/plugins/engine/models/SummaryViewModel.ts +68 -25
  260. package/src/server/plugins/engine/options.js +2 -1
  261. package/src/server/plugins/engine/outputFormatters/adapter/v1.ts +5 -0
  262. package/src/server/plugins/engine/outputFormatters/human/v1.ts +2 -3
  263. package/src/server/plugins/engine/outputFormatters/machine/v1.ts +9 -8
  264. package/src/server/plugins/engine/pageControllers/FileUploadPageController.ts +7 -3
  265. package/src/server/plugins/engine/pageControllers/PageController.ts +12 -1
  266. package/src/server/plugins/engine/pageControllers/QuestionPageController.ts +53 -21
  267. package/src/server/plugins/engine/pageControllers/RepeatPageController.ts +66 -29
  268. package/src/server/plugins/engine/pageControllers/StartPageController.ts +7 -2
  269. package/src/server/plugins/engine/pageControllers/StatusPageController.ts +10 -2
  270. package/src/server/plugins/engine/pageControllers/SummaryPageController.ts +53 -24
  271. package/src/server/plugins/engine/pageControllers/__stubs__/translator.ts +28 -0
  272. package/src/server/plugins/engine/pageControllers/errors.ts +4 -2
  273. package/src/server/plugins/engine/pageControllers/helpers/submission.ts +11 -4
  274. package/src/server/plugins/engine/pageControllers/validationOptions.ts +43 -53
  275. package/src/server/plugins/engine/plugin.ts +2 -0
  276. package/src/server/plugins/engine/routes/index.ts +9 -1
  277. package/src/server/plugins/engine/routes/questions.ts +5 -1
  278. package/src/server/plugins/engine/types/index.ts +5 -0
  279. package/src/server/plugins/engine/types/schema.ts +1 -0
  280. package/src/server/plugins/engine/types.ts +10 -0
  281. package/src/server/plugins/engine/views/components/_location-field-base.html +1 -1
  282. package/src/server/plugins/engine/views/components/fileuploadfield.html +3 -3
  283. package/src/server/plugins/engine/views/components/nationalgridfieldnumberfield.html +1 -1
  284. package/src/server/plugins/engine/views/components/osgridreffield.html +1 -1
  285. package/src/server/plugins/engine/views/components/paymentfield.html +8 -8
  286. package/src/server/plugins/engine/views/components/ukaddressfield.html +4 -4
  287. package/src/server/plugins/engine/views/confirmation.html +4 -4
  288. package/src/server/plugins/engine/views/exit.html +4 -4
  289. package/src/server/plugins/engine/views/file-upload.html +3 -3
  290. package/src/server/plugins/engine/views/index.html +3 -3
  291. package/src/server/plugins/engine/views/item-delete.html +1 -1
  292. package/src/server/plugins/engine/views/partials/form.html +3 -3
  293. package/src/server/plugins/engine/views/partials/preview-banner.html +4 -4
  294. package/src/server/plugins/engine/views/partials/warn-missing-notification-email.html +4 -5
  295. package/src/server/plugins/engine/views/repeat-list-summary.html +4 -4
  296. package/src/server/plugins/engine/views/summary.html +14 -7
  297. package/src/server/plugins/nunjucks/environment.js +14 -0
  298. package/src/server/plugins/nunjucks/filters/answer.js +12 -1
  299. package/src/server/plugins/postcode-lookup/models/index.js +144 -87
  300. package/src/server/plugins/postcode-lookup/routes/index.js +13 -16
  301. package/src/server/plugins/postcode-lookup/types.js +1 -0
  302. package/src/server/plugins/postcode-lookup/views/postcode-lookup-details.html +3 -3
  303. package/src/server/types.ts +2 -0
  304. package/src/server/utils/utils.js +14 -0
  305. package/src/typings/hapi/index.d.ts +1 -0
  306. package/.server/server/plugins/engine/components/constants.d.ts +0 -1
  307. package/.server/server/plugins/engine/components/constants.js +0 -2
  308. package/.server/server/plugins/engine/components/constants.js.map +0 -1
  309. package/src/server/plugins/engine/components/constants.ts +0 -1
@@ -6,6 +6,7 @@ import resolvePkg from 'resolve'
6
6
 
7
7
  import { config } from '../../../config/index.js'
8
8
  import { evaluateTemplate } from '../engine/helpers.js'
9
+ import { t as i18nT } from '../engine/i18n/index.js'
9
10
  import * as filters from './filters/index.js'
10
11
 
11
12
  const govukFrontendPath = dirname(
@@ -115,6 +116,19 @@ export function govukRebrand() {
115
116
 
116
117
  environment.addGlobal('govukRebrand', govukRebrand())
117
118
 
119
+ /**
120
+ * Global t() function — en-GB fallback for templates not wired to a specific language.
121
+ * Per-request page controllers override this by passing t in their view model.
122
+ * @param {string} key
123
+ * @param {Record<string, unknown>} [opts]
124
+ * @returns {string}
125
+ */
126
+ export function tGlobal(key, opts) {
127
+ return i18nT(key, 'en-GB', opts)
128
+ }
129
+
130
+ environment.addGlobal('t', tGlobal)
131
+
118
132
  /**
119
133
  * @import { NunjucksContext } from './types.js'
120
134
  * @import { FormSubmissionError } from '../engine/types.js'
@@ -18,7 +18,18 @@ export function answer(name) {
18
18
  return undefined
19
19
  }
20
20
 
21
- return getAnswer(/** @type {Field} */ (component), context.relevantState)
21
+ const field = /** @type {Field} */ (component)
22
+ const { translator } = context
23
+
24
+ // Fallback if no translator in the context
25
+ return getAnswer(
26
+ field,
27
+ context.relevantState,
28
+ translator ?? field.model.createTranslator(),
29
+ {
30
+ format: 'summary'
31
+ }
32
+ )
22
33
  }
23
34
 
24
35
  /**
@@ -1,5 +1,6 @@
1
1
  import Joi from 'joi'
2
2
 
3
+ import { t as i18nT } from '../../engine/i18n/index.js'
3
4
  import * as service from '../service.js'
4
5
  import { crumbSchema } from '../../../schemas/index.js'
5
6
 
@@ -14,8 +15,6 @@ const townFieldName = 'town'
14
15
  const countyFieldName = 'county'
15
16
  const postcodeFieldName = 'postcode'
16
17
 
17
- const selectLabelText = 'Select an address'
18
-
19
18
  const GOVUK_MARGIN_RIGHT_1 = 'govuk-!-margin-right-1'
20
19
 
21
20
  export const steps = {
@@ -129,17 +128,23 @@ async function getAddresses(postcodeQuery, buildingNameQuery, apiKey) {
129
128
  * @param {PostcodeLookupDetailsData | undefined} details
130
129
  * @param {OptionalValidationErrorItem} postcodeQueryError
131
130
  * @param {OptionalValidationErrorItem} buildingNameQueryError
131
+ * @param {string} language
132
132
  */
133
- function getDetailsFields(details, postcodeQueryError, buildingNameQueryError) {
133
+ function getDetailsFields(
134
+ details,
135
+ postcodeQueryError,
136
+ buildingNameQueryError,
137
+ language
138
+ ) {
134
139
  return {
135
140
  [postcodeQueryFieldName]: {
136
141
  id: postcodeQueryFieldName,
137
142
  name: postcodeQueryFieldName,
138
143
  label: {
139
- text: 'Postcode'
144
+ text: i18nT('postcodeLookup.postcodeLabel', language)
140
145
  },
141
146
  hint: {
142
- text: 'For example, AA3 1AB'
147
+ text: i18nT('postcodeLookup.postcodeHint', language)
143
148
  },
144
149
  value: details?.postcodeQuery,
145
150
  errorMessage: postcodeQueryError && { text: postcodeQueryError.message }
@@ -148,10 +153,10 @@ function getDetailsFields(details, postcodeQueryError, buildingNameQueryError) {
148
153
  id: buildingNameQueryFieldName,
149
154
  name: buildingNameQueryFieldName,
150
155
  label: {
151
- text: 'Building name or number (optional)'
156
+ text: i18nT('postcodeLookup.buildingNameLabel', language)
152
157
  },
153
158
  hint: {
154
- text: 'For example, 15 or Prospect Cottage'
159
+ text: i18nT('postcodeLookup.buildingNameHint', language)
155
160
  },
156
161
  value: details?.buildingNameQuery,
157
162
  errorMessage: buildingNameQueryError && {
@@ -169,6 +174,7 @@ function getDetailsFields(details, postcodeQueryError, buildingNameQueryError) {
169
174
  * @param {PostcodeLookupSelectPayload | undefined} payload
170
175
  * @param {OptionalValidationErrorItem} uprnError
171
176
  * @param {Address[]} addresses
177
+ * @param {string} language
172
178
  */
173
179
  function getSelectFields(
174
180
  details,
@@ -176,8 +182,11 @@ function getSelectFields(
176
182
  singleAddress,
177
183
  payload,
178
184
  uprnError,
179
- addresses
185
+ addresses,
186
+ language
180
187
  ) {
188
+ const selectAddressText = i18nT('postcodeLookup.selectAddress', language)
189
+
181
190
  return {
182
191
  [postcodeQueryFieldName]: {
183
192
  id: postcodeQueryFieldName,
@@ -196,13 +205,13 @@ function getSelectFields(
196
205
  name: uprnFieldName,
197
206
  label: hasMultipleAddresses
198
207
  ? {
199
- text: selectLabelText
208
+ text: selectAddressText
200
209
  }
201
210
  : undefined,
202
211
  value: singleAddress ? singleAddress.uprn : payload?.uprn,
203
212
  errorMessage: uprnError && { text: uprnError.message },
204
213
  items: hasMultipleAddresses
205
- ? [{ text: selectLabelText, value: '' }].concat(
214
+ ? [{ text: selectAddressText, value: '' }].concat(
206
215
  addresses.map((item) => ({
207
216
  text: item.formatted,
208
217
  value: item.uprn
@@ -222,6 +231,7 @@ function getSelectFields(
222
231
  * @param {OptionalValidationErrorItem} townError
223
232
  * @param {OptionalValidationErrorItem} countyError
224
233
  * @param {OptionalValidationErrorItem} postcodeError
234
+ * @param {string} language
225
235
  */
226
236
  function getManualFields(
227
237
  payload,
@@ -229,14 +239,15 @@ function getManualFields(
229
239
  line2Error,
230
240
  townError,
231
241
  countyError,
232
- postcodeError
242
+ postcodeError,
243
+ language
233
244
  ) {
234
245
  return {
235
246
  [line1FieldName]: {
236
247
  id: line1FieldName,
237
248
  name: line1FieldName,
238
249
  label: {
239
- text: 'Address line 1'
250
+ text: i18nT('postcodeLookup.addressLine1Label', language)
240
251
  },
241
252
  value: payload?.addressLine1,
242
253
  errorMessage: line1Error && { text: line1Error.message }
@@ -245,7 +256,7 @@ function getManualFields(
245
256
  id: line2FieldName,
246
257
  name: line2FieldName,
247
258
  label: {
248
- text: 'Address line 2 (optional)'
259
+ text: i18nT('postcodeLookup.addressLine2Label', language)
249
260
  },
250
261
  value: payload?.addressLine2,
251
262
  errorMessage: line2Error && { text: line2Error.message }
@@ -254,7 +265,7 @@ function getManualFields(
254
265
  id: townFieldName,
255
266
  name: townFieldName,
256
267
  label: {
257
- text: 'Town or city'
268
+ text: i18nT('postcodeLookup.townLabel', language)
258
269
  },
259
270
  classes: 'govuk-!-width-two-thirds',
260
271
  value: payload?.town,
@@ -264,7 +275,7 @@ function getManualFields(
264
275
  id: countyFieldName,
265
276
  name: countyFieldName,
266
277
  label: {
267
- text: 'County (optional)'
278
+ text: i18nT('postcodeLookup.countyLabel', language)
268
279
  },
269
280
  value: payload?.county,
270
281
  errorMessage: countyError && { text: countyError.message }
@@ -273,7 +284,7 @@ function getManualFields(
273
284
  id: postcodeFieldName,
274
285
  name: postcodeFieldName,
275
286
  label: {
276
- text: 'Postcode'
287
+ text: i18nT('postcodeLookup.postcodeLabel', language)
277
288
  },
278
289
  classes: 'govuk-input--width-10',
279
290
  value: payload?.postcode,
@@ -293,66 +304,91 @@ const sharedPayloadSchemaKeys = {
293
304
 
294
305
  /**
295
306
  * Postcode lookup details form payload schema
296
- * @type {ObjectSchema<PostcodeLookupDetailsPayload>}
307
+ * @param {string} [language]
308
+ * @returns {ObjectSchema<PostcodeLookupDetailsPayload>}
297
309
  */
298
- export const detailsPayloadSchema = Joi.object()
299
- .keys({
300
- ...sharedPayloadSchemaKeys,
301
- [postcodeQueryFieldName]: Joi.string()
302
- .pattern(/^[a-zA-Z]{1,2}\d[a-zA-Z\d]?\s?\d[a-zA-Z]{2}$/)
303
- .trim()
304
- .required()
305
- .messages({
306
- 'string.pattern.base':
307
- 'Enter a valid postcode or enter an address manually',
308
- '*': 'Enter a postcode'
309
- }),
310
- [buildingNameQueryFieldName]: Joi.string()
311
- .trim()
312
- .required()
313
- .allow('')
314
- .trim()
315
- })
316
- .required()
310
+ export function createDetailsPayloadSchema(language = 'en-GB') {
311
+ return Joi.object()
312
+ .keys({
313
+ ...sharedPayloadSchemaKeys,
314
+ [postcodeQueryFieldName]: Joi.string()
315
+ .pattern(/^[a-zA-Z]{1,2}\d[a-zA-Z\d]?\s?\d[a-zA-Z]{2}$/)
316
+ .trim()
317
+ .required()
318
+ .messages({
319
+ 'string.pattern.base': i18nT(
320
+ 'postcodeLookup.validation.invalidPostcode',
321
+ language
322
+ ),
323
+ '*': i18nT('postcodeLookup.validation.requiredPostcode', language)
324
+ }),
325
+ [buildingNameQueryFieldName]: Joi.string()
326
+ .trim()
327
+ .required()
328
+ .allow('')
329
+ .trim()
330
+ })
331
+ .required()
332
+ }
317
333
 
318
334
  /**
319
335
  * Postcode lookup select form payload schema
320
- * @type {ObjectSchema<PostcodeLookupSelectPayload>}
336
+ * @param {string} [language]
337
+ * @returns {ObjectSchema<PostcodeLookupSelectPayload>}
321
338
  */
322
- export const selectPayloadSchema = Joi.object()
323
- .keys({
324
- ...sharedPayloadSchemaKeys,
325
- [uprnFieldName]: Joi.string().required().messages({
326
- '*': selectLabelText
339
+ export function createSelectPayloadSchema(language = 'en-GB') {
340
+ return Joi.object()
341
+ .keys({
342
+ ...sharedPayloadSchemaKeys,
343
+ [uprnFieldName]: Joi.string()
344
+ .required()
345
+ .messages({
346
+ '*': i18nT('postcodeLookup.validation.selectAddress', language)
347
+ })
327
348
  })
328
- })
329
- .required()
349
+ .required()
350
+ }
330
351
 
331
352
  /**
332
353
  * Postcode lookup manual form payload schema
333
- * @type {ObjectSchema<PostcodeLookupManualPayload>}
354
+ * @param {string} [language]
355
+ * @returns {ObjectSchema<PostcodeLookupManualPayload>}
334
356
  */
335
- export const manualPayloadSchema = Joi.object()
336
- .keys({
337
- ...sharedPayloadSchemaKeys,
338
- [line1FieldName]: Joi.string().trim().required().messages({
339
- '*': 'Enter address line 1'
340
- }),
341
- [line2FieldName]: Joi.string().trim().allow('').required(),
342
- [townFieldName]: Joi.string().trim().required().messages({
343
- '*': 'Enter town or city'
344
- }),
345
- [countyFieldName]: Joi.string().trim().allow('').required(),
346
- [postcodeFieldName]: Joi.string()
347
- .pattern(/^[a-zA-Z]{1,2}\d[a-zA-Z\d]?\s?\d[a-zA-Z]{2}$/)
348
- .trim()
349
- .required()
350
- .messages({
351
- 'string.pattern.base': 'Enter a valid postcode',
352
- '*': 'Enter postcode'
353
- })
354
- })
355
- .required()
357
+ export function createManualPayloadSchema(language = 'en-GB') {
358
+ return Joi.object()
359
+ .keys({
360
+ ...sharedPayloadSchemaKeys,
361
+ [line1FieldName]: Joi.string()
362
+ .trim()
363
+ .required()
364
+ .messages({
365
+ '*': i18nT('postcodeLookup.validation.requiredAddressLine1', language)
366
+ }),
367
+ [line2FieldName]: Joi.string().trim().allow('').required(),
368
+ [townFieldName]: Joi.string()
369
+ .trim()
370
+ .required()
371
+ .messages({
372
+ '*': i18nT('postcodeLookup.validation.requiredTown', language)
373
+ }),
374
+ [countyFieldName]: Joi.string().trim().allow('').required(),
375
+ [postcodeFieldName]: Joi.string()
376
+ .pattern(/^[a-zA-Z]{1,2}\d[a-zA-Z\d]?\s?\d[a-zA-Z]{2}$/)
377
+ .trim()
378
+ .required()
379
+ .messages({
380
+ 'string.pattern.base': i18nT(
381
+ 'postcodeLookup.validation.invalidManualPostcode',
382
+ language
383
+ ),
384
+ '*': i18nT(
385
+ 'postcodeLookup.validation.requiredManualPostcode',
386
+ language
387
+ )
388
+ })
389
+ })
390
+ .required()
391
+ }
356
392
 
357
393
  /**
358
394
  * Get the postcode lookup href
@@ -371,7 +407,12 @@ function getHref(step) {
371
407
  * @param {Error} [err]
372
408
  */
373
409
  export function detailsViewModel(data, payload, err) {
374
- const { componentTitle: pageTitle, formName, sourceUrl } = data.initial
410
+ const {
411
+ componentTitle: pageTitle,
412
+ formName,
413
+ sourceUrl,
414
+ language = 'en-GB'
415
+ } = data.initial
375
416
 
376
417
  const backLink = {
377
418
  href: sourceUrl
@@ -380,20 +421,19 @@ export function detailsViewModel(data, payload, err) {
380
421
  const { errors, postcodeQueryError, buildingNameQueryError } =
381
422
  buildErrors(err)
382
423
 
383
- // Model fields
384
424
  const fields = getDetailsFields(
385
425
  payload ?? data.details,
386
426
  postcodeQueryError,
387
- buildingNameQueryError
427
+ buildingNameQueryError,
428
+ language
388
429
  )
389
430
 
390
- // Model buttons
391
431
  const continueButton = {
392
- text: 'Find address',
432
+ text: i18nT('postcodeLookup.findAddress', language),
393
433
  classes: GOVUK_MARGIN_RIGHT_1
394
434
  }
395
435
  const manualLink = {
396
- text: 'enter address manually',
436
+ text: i18nT('postcodeLookup.enterManually', language),
397
437
  href: getHref(steps.manual)
398
438
  }
399
439
 
@@ -420,8 +460,8 @@ export async function selectViewModel(data, payload, err) {
420
460
  const { session, apiKey } = data
421
461
  const { details, initial } = session
422
462
  const { postcodeQuery, buildingNameQuery } = details
463
+ const language = initial.language ?? 'en-GB'
423
464
 
424
- // Search for addresses
425
465
  const {
426
466
  hasAddresses,
427
467
  hasMultipleAddresses,
@@ -430,7 +470,9 @@ export async function selectViewModel(data, payload, err) {
430
470
  addressCount
431
471
  } = await getAddresses(postcodeQuery, buildingNameQuery, apiKey)
432
472
 
433
- const title = hasAddresses ? initial.componentTitle : 'No address found'
473
+ const title = hasAddresses
474
+ ? initial.componentTitle
475
+ : i18nT('postcodeLookup.noAddressFoundTitle', language)
434
476
  const formPath = initial.sourceUrl
435
477
  const href = getHref()
436
478
 
@@ -438,32 +480,42 @@ export async function selectViewModel(data, payload, err) {
438
480
 
439
481
  const { errors, uprnError } = buildErrors(err)
440
482
 
441
- // Model fields
442
483
  const fields = getSelectFields(
443
484
  details,
444
485
  hasMultipleAddresses,
445
486
  singleAddress,
446
487
  payload,
447
488
  uprnError,
448
- addresses
489
+ addresses,
490
+ language
449
491
  )
450
492
 
493
+ const searchAgainText = i18nT('postcodeLookup.searchAgain', language)
494
+
451
495
  const searchAgainLink = {
452
- text: 'Search again',
496
+ text: searchAgainText,
453
497
  href
454
498
  }
455
499
 
456
- // Model buttons
457
500
  const continueButton = {
458
501
  href: hasAddresses ? undefined : href,
459
- text: hasAddresses ? 'Use this address' : 'Search again',
502
+ text: hasAddresses
503
+ ? i18nT('postcodeLookup.useThisAddress', language)
504
+ : searchAgainText,
460
505
  classes: GOVUK_MARGIN_RIGHT_1
461
506
  }
462
507
  const manualLink = {
463
- text: 'enter address manually',
508
+ text: i18nT('postcodeLookup.enterManually', language),
464
509
  href: `${href}?step=${steps.manual}`
465
510
  }
466
511
 
512
+ const addressesFoundText = hasAddresses
513
+ ? i18nT('postcodeLookup.addressFound', language, { count: addressCount })
514
+ : undefined
515
+ const noAddressFoundText = !hasAddresses
516
+ ? i18nT('postcodeLookup.noAddressFoundBody', language)
517
+ : undefined
518
+
467
519
  return {
468
520
  step: steps.select,
469
521
  showTitle: true,
@@ -479,6 +531,8 @@ export async function selectViewModel(data, payload, err) {
479
531
  singleAddress,
480
532
  hasAddresses,
481
533
  hasMultipleAddresses,
534
+ addressesFoundText,
535
+ noAddressFoundText,
482
536
  buttons: { continueButton, manualLink }
483
537
  }
484
538
  }
@@ -490,7 +544,12 @@ export async function selectViewModel(data, payload, err) {
490
544
  * @param {Error} [err]
491
545
  */
492
546
  export function manualViewModel(data, payload, err) {
493
- const { componentTitle, sourceUrl, componentHint } = data.initial
547
+ const {
548
+ componentTitle,
549
+ sourceUrl,
550
+ componentHint,
551
+ language = 'en-GB'
552
+ } = data.initial
494
553
  const formPath = sourceUrl
495
554
  const href = getHref()
496
555
 
@@ -507,28 +566,26 @@ export function manualViewModel(data, payload, err) {
507
566
  postcodeError
508
567
  } = buildErrors(err)
509
568
 
510
- // Model hint
511
569
  const hint = componentHint && {
512
570
  text: componentHint
513
571
  }
514
572
 
515
- // Model fields
516
573
  const fields = getManualFields(
517
574
  payload,
518
575
  line1Error,
519
576
  line2Error,
520
577
  townError,
521
578
  countyError,
522
- postcodeError
579
+ postcodeError,
580
+ language
523
581
  )
524
582
 
525
- // Model buttons
526
583
  const continueButton = {
527
- text: 'Use this address',
584
+ text: i18nT('postcodeLookup.useThisAddress', language),
528
585
  classes: GOVUK_MARGIN_RIGHT_1
529
586
  }
530
587
  const detailsLink = {
531
- text: 'find an address instead',
588
+ text: i18nT('postcodeLookup.findAnAddressInstead', language),
532
589
  href
533
590
  }
534
591
 
@@ -5,11 +5,11 @@ import Joi from 'joi'
5
5
  import { EXTERNAL_STATE_APPENDAGE } from '../../../constants.js'
6
6
  import {
7
7
  JOURNEY_BASE_URL,
8
- detailsPayloadSchema,
8
+ createDetailsPayloadSchema,
9
+ createManualPayloadSchema,
10
+ createSelectPayloadSchema,
9
11
  detailsViewModel,
10
- manualPayloadSchema,
11
12
  manualViewModel,
12
- selectPayloadSchema,
13
13
  selectViewModel,
14
14
  stepSchema,
15
15
  steps
@@ -172,12 +172,10 @@ function postRoute(options) {
172
172
  async function detailsPostHandler(request, h, options) {
173
173
  const session = getSessionState(request)
174
174
  const { ordnanceSurveyApiKey: apiKey } = options
175
-
176
- /** @type {{ value: PostcodeLookupDetailsPayload, error?: import('joi').ValidationError }} */
177
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
178
- const { value: details, error } = detailsPayloadSchema.validate(
179
- request.payload
180
- )
175
+ const language = session.initial.language ?? 'en-GB'
176
+ const { value: details, error } = createDetailsPayloadSchema(
177
+ language
178
+ ).validate(request.payload)
181
179
 
182
180
  let model
183
181
 
@@ -207,10 +205,10 @@ async function detailsPostHandler(request, h, options) {
207
205
  async function selectPostHandler(request, h, options) {
208
206
  const session = getSessionState(request)
209
207
  const { ordnanceSurveyApiKey: apiKey } = options
210
-
211
- /** @type {{ value: PostcodeLookupSelectPayload, error?: import('joi').ValidationError }} */
212
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
213
- const { value: select, error } = selectPayloadSchema.validate(request.payload)
208
+ const language = session.initial.language ?? 'en-GB'
209
+ const { value: select, error } = createSelectPayloadSchema(language).validate(
210
+ request.payload
211
+ )
214
212
 
215
213
  if (error) {
216
214
  const model = await selectViewModel({ session, apiKey }, select, error)
@@ -239,10 +237,9 @@ async function selectPostHandler(request, h, options) {
239
237
  */
240
238
  function manualPostHandler(request, h) {
241
239
  const session = getSessionState(request)
240
+ const language = session.initial.language ?? 'en-GB'
242
241
 
243
- /** @type {{ value: PostcodeLookupManualPayload, error?: import('joi').ValidationError }} */
244
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
245
- const { value: manual, error } = manualPayloadSchema.validate(
242
+ const { value: manual, error } = createManualPayloadSchema(language).validate(
246
243
  request.payload,
247
244
  {
248
245
  abortEarly: false
@@ -19,6 +19,7 @@
19
19
  * componentTitle: string,
20
20
  * componentHint?: string
21
21
  * step?: string
22
+ * language?: string
22
23
  * }} PostcodeLookupDispatchData
23
24
  */
24
25
 
@@ -13,7 +13,7 @@
13
13
  <div class="govuk-grid-column-two-thirds">
14
14
  {% if errors %}
15
15
  {{ govukErrorSummary({
16
- titleText: "There is a problem",
16
+ titleText: t('errors.title'),
17
17
  errorList: errors
18
18
  }) }}
19
19
  {% endif %}
@@ -38,7 +38,7 @@
38
38
 
39
39
  {% if hasAddresses %}
40
40
  <p class="govuk-body">
41
- {{addressCount}} address{{ "es" if hasMultipleAddresses }} found for {{ detailsHtml | safe }}. <a href="{{ searchAgainLink.href }}" class="govuk-link govuk-link--no-visited-state">{{ searchAgainLink.text }}</a>
41
+ {{ addressesFoundText }} {{ detailsHtml | safe }}. <a href="{{ searchAgainLink.href }}" class="govuk-link govuk-link--no-visited-state">{{ searchAgainLink.text }}</a>
42
42
  </p>
43
43
  {% endif %}
44
44
 
@@ -53,7 +53,7 @@
53
53
  }) }}
54
54
  {% else %}
55
55
  <!-- No addresses found - show try again -->
56
- <p class="govuk-body">We could not find an address that matches {{ detailsHtml | safe }}.</p>
56
+ <p class="govuk-body">{{ noAddressFoundText }} {{ detailsHtml | safe }}.</p>
57
57
  {% endif %}
58
58
  {% case "manual" %}
59
59
  <!-- Postcode lookup manual entry -->
@@ -11,6 +11,7 @@ import { type DetailItem } from './plugins/engine/models/types.js'
11
11
  import { type PageController } from './plugins/engine/pageControllers/PageController.js'
12
12
  import {
13
13
  type FormContext,
14
+ type GetLanguageHandler,
14
15
  type OnRequestCallback,
15
16
  type PluginOptions,
16
17
  type PreparePageEventRequestOptions
@@ -59,6 +60,7 @@ export interface RouteConfig {
59
60
  cacheServiceCreator?: (server: Server) => CacheService
60
61
  ordnanceSurveyApiKey?: string
61
62
  ordnanceSurveyApiSecret?: string
63
+ getLanguage?: GetLanguageHandler
62
64
  }
63
65
 
64
66
  export interface OutputService {
@@ -2,6 +2,7 @@ import { getTraceId } from '@defra/hapi-tracing'
2
2
  import Joi from 'joi'
3
3
 
4
4
  import { config } from '../../config/index.js'
5
+ import { getPluginOptions } from '../plugins/engine/helpers.js'
5
6
 
6
7
  /**
7
8
  * Returns a set of headers to use in an HTTP request, merging them with any existing headers in options.
@@ -33,3 +34,16 @@ export function isValidUUID(str) {
33
34
  const { error } = Joi.string().uuid().validate(str)
34
35
  return error === undefined
35
36
  }
37
+
38
+ /**
39
+ * @param {AnyFormRequest} request
40
+ */
41
+ export function resolveLanguage(request) {
42
+ const { getLanguage } = getPluginOptions(request.server)
43
+ return getLanguage?.(request.query, request.yar) ?? 'en-GB'
44
+ }
45
+
46
+ /**
47
+ * @import { FormMetadata } from '@defra/forms-model'
48
+ * @import { AnyFormRequest } from '../plugins/engine/types.js'
49
+ */
@@ -38,6 +38,7 @@ declare module '@hapi/hapi' {
38
38
  request: AnyFormRequest | null
39
39
  ) => Record<string, unknown> | Promise<Record<string, unknown>>
40
40
  saveAndExit?: PluginOptions['saveAndExit']
41
+ getLanguage?: PluginOptions['getLanguage']
41
42
  baseUrl: string
42
43
  services: PluginOptions['services']
43
44
  }
@@ -1 +0,0 @@
1
- export declare const optionalText = " (optional)";
@@ -1,2 +0,0 @@
1
- export const optionalText = ' (optional)';
2
- //# sourceMappingURL=constants.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"constants.js","names":["optionalText"],"sources":["../../../../../src/server/plugins/engine/components/constants.ts"],"sourcesContent":["export const optionalText = ' (optional)'\n"],"mappings":"AAAA,OAAO,MAAMA,YAAY,GAAG,aAAa","ignoreList":[]}
@@ -1 +0,0 @@
1
- export const optionalText = ' (optional)'