@defra/forms-engine-plugin 5.0.0-alpha.3 → 5.0.0-alpha.31

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 (406) hide show
  1. package/.public/37c964ca545c240f010a.mjs +2 -0
  2. package/.public/37c964ca545c240f010a.mjs.LICENSE.txt +4 -0
  3. package/.public/assets-manifest.json +3 -0
  4. package/.public/javascripts/application.min.js +1 -1
  5. package/.public/javascripts/application.min.js.LICENSE.txt +7 -0
  6. package/.public/javascripts/application.min.js.map +1 -1
  7. package/.public/javascripts/shared.min.js +1 -1
  8. package/.public/javascripts/shared.min.js.LICENSE.txt +9 -0
  9. package/.public/javascripts/shared.min.js.map +1 -1
  10. package/.public/javascripts/vendor/@defra.min.js +1 -1
  11. package/.public/javascripts/vendor/@defra.min.js.map +1 -1
  12. package/.public/javascripts/vendor/maplibre-gl.min.js +1 -1
  13. package/.public/javascripts/vendor/maplibre-gl.min.js.LICENSE.txt +3 -3
  14. package/.public/javascripts/vendor/maplibre-gl.min.js.map +1 -1
  15. package/.public/stylesheets/application.min.css +1 -1
  16. package/.public/stylesheets/application.min.css.map +1 -1
  17. package/.server/client/javascripts/file-upload.js +6 -3
  18. package/.server/client/javascripts/file-upload.js.map +1 -1
  19. package/.server/client/javascripts/geospatial-map.d.ts +159 -5
  20. package/.server/client/javascripts/geospatial-map.js +161 -81
  21. package/.server/client/javascripts/geospatial-map.js.map +1 -1
  22. package/.server/client/javascripts/geospatial-map.test.js +152 -0
  23. package/.server/client/javascripts/geospatial-map.test.js.map +1 -0
  24. package/.server/client/javascripts/govuk.js +2 -1
  25. package/.server/client/javascripts/govuk.js.map +1 -1
  26. package/.server/client/javascripts/location-map.d.ts +44 -0
  27. package/.server/client/javascripts/location-map.js +55 -6
  28. package/.server/client/javascripts/location-map.js.map +1 -1
  29. package/.server/client/javascripts/map-constants.d.ts +3 -0
  30. package/.server/client/javascripts/map-constants.js +4 -0
  31. package/.server/client/javascripts/map-constants.js.map +1 -0
  32. package/.server/client/javascripts/map.d.ts +17 -4
  33. package/.server/client/javascripts/map.js +59 -6
  34. package/.server/client/javascripts/map.js.map +1 -1
  35. package/.server/client/javascripts/maps.d.ts +5 -0
  36. package/.server/client/javascripts/maps.js +6 -0
  37. package/.server/client/javascripts/maps.js.map +1 -0
  38. package/.server/client/javascripts/shared.d.ts +1 -4
  39. package/.server/client/javascripts/shared.js +1 -4
  40. package/.server/client/javascripts/shared.js.map +1 -1
  41. package/.server/client/javascripts/sssi-dataset.d.ts +18 -20
  42. package/.server/client/javascripts/sssi-dataset.js +37 -39
  43. package/.server/client/javascripts/sssi-dataset.js.map +1 -1
  44. package/.server/client/stylesheets/maps.scss +4 -0
  45. package/.server/client/stylesheets/shared.scss +1 -5
  46. package/.server/server/constants.d.ts +2 -0
  47. package/.server/server/constants.js +2 -0
  48. package/.server/server/constants.js.map +1 -1
  49. package/.server/server/forms/components.json +8 -0
  50. package/.server/server/forms/register-as-a-unicorn-breeder.yaml +4 -0
  51. package/.server/server/plugins/engine/__stubs__/definitions.d.ts +29 -0
  52. package/.server/server/plugins/engine/__stubs__/definitions.js +125 -0
  53. package/.server/server/plugins/engine/__stubs__/definitions.js.map +1 -0
  54. package/.server/server/plugins/engine/components/AutocompleteField.d.ts +8 -3
  55. package/.server/server/plugins/engine/components/AutocompleteField.js +17 -0
  56. package/.server/server/plugins/engine/components/AutocompleteField.js.map +1 -1
  57. package/.server/server/plugins/engine/components/CheckboxesField.d.ts +23 -2
  58. package/.server/server/plugins/engine/components/CheckboxesField.js +30 -5
  59. package/.server/server/plugins/engine/components/CheckboxesField.js.map +1 -1
  60. package/.server/server/plugins/engine/components/ComponentBase.d.ts +2 -1
  61. package/.server/server/plugins/engine/components/ComponentBase.js +2 -0
  62. package/.server/server/plugins/engine/components/ComponentBase.js.map +1 -1
  63. package/.server/server/plugins/engine/components/ComponentCollection.js +12 -7
  64. package/.server/server/plugins/engine/components/ComponentCollection.js.map +1 -1
  65. package/.server/server/plugins/engine/components/DatePartsField.d.ts +6 -3
  66. package/.server/server/plugins/engine/components/DatePartsField.js +12 -7
  67. package/.server/server/plugins/engine/components/DatePartsField.js.map +1 -1
  68. package/.server/server/plugins/engine/components/DeclarationField.d.ts +6 -3
  69. package/.server/server/plugins/engine/components/DeclarationField.js +6 -4
  70. package/.server/server/plugins/engine/components/DeclarationField.js.map +1 -1
  71. package/.server/server/plugins/engine/components/Details.d.ts +1 -0
  72. package/.server/server/plugins/engine/components/EastingNorthingField.d.ts +33 -2
  73. package/.server/server/plugins/engine/components/EastingNorthingField.js +110 -54
  74. package/.server/server/plugins/engine/components/EastingNorthingField.js.map +1 -1
  75. package/.server/server/plugins/engine/components/EmailAddressField.d.ts +4 -1
  76. package/.server/server/plugins/engine/components/EmailAddressField.js +2 -1
  77. package/.server/server/plugins/engine/components/EmailAddressField.js.map +1 -1
  78. package/.server/server/plugins/engine/components/FileUploadField.d.ts +23 -2
  79. package/.server/server/plugins/engine/components/FileUploadField.js +35 -3
  80. package/.server/server/plugins/engine/components/FileUploadField.js.map +1 -1
  81. package/.server/server/plugins/engine/components/FormComponent.d.ts +5 -1
  82. package/.server/server/plugins/engine/components/FormComponent.js +5 -2
  83. package/.server/server/plugins/engine/components/FormComponent.js.map +1 -1
  84. package/.server/server/plugins/engine/components/GeospatialField.d.ts +23 -0
  85. package/.server/server/plugins/engine/components/GeospatialField.js +33 -9
  86. package/.server/server/plugins/engine/components/GeospatialField.js.map +1 -1
  87. package/.server/server/plugins/engine/components/Html.d.ts +1 -0
  88. package/.server/server/plugins/engine/components/InsetText.d.ts +1 -0
  89. package/.server/server/plugins/engine/components/LatLongField.d.ts +32 -2
  90. package/.server/server/plugins/engine/components/LatLongField.js +85 -48
  91. package/.server/server/plugins/engine/components/LatLongField.js.map +1 -1
  92. package/.server/server/plugins/engine/components/List.d.ts +1 -0
  93. package/.server/server/plugins/engine/components/ListFormComponent.d.ts +3 -2
  94. package/.server/server/plugins/engine/components/ListFormComponent.js.map +1 -1
  95. package/.server/server/plugins/engine/components/LocationFieldBase.d.ts +8 -2
  96. package/.server/server/plugins/engine/components/LocationFieldBase.js +31 -7
  97. package/.server/server/plugins/engine/components/LocationFieldBase.js.map +1 -1
  98. package/.server/server/plugins/engine/components/LocationFieldHelpers.d.ts +12 -3
  99. package/.server/server/plugins/engine/components/LocationFieldHelpers.js +21 -13
  100. package/.server/server/plugins/engine/components/LocationFieldHelpers.js.map +1 -1
  101. package/.server/server/plugins/engine/components/Markdown.d.ts +1 -0
  102. package/.server/server/plugins/engine/components/Markdown.js +1 -1
  103. package/.server/server/plugins/engine/components/Markdown.js.map +1 -1
  104. package/.server/server/plugins/engine/components/MonthYearField.d.ts +5 -2
  105. package/.server/server/plugins/engine/components/MonthYearField.js +13 -9
  106. package/.server/server/plugins/engine/components/MonthYearField.js.map +1 -1
  107. package/.server/server/plugins/engine/components/MultilineTextField.d.ts +1 -0
  108. package/.server/server/plugins/engine/components/NationalGridFieldNumberField.d.ts +2 -1
  109. package/.server/server/plugins/engine/components/NationalGridFieldNumberField.js +4 -3
  110. package/.server/server/plugins/engine/components/NationalGridFieldNumberField.js.map +1 -1
  111. package/.server/server/plugins/engine/components/NotificationBanner.d.ts +1 -0
  112. package/.server/server/plugins/engine/components/NumberField.d.ts +5 -0
  113. package/.server/server/plugins/engine/components/NumberField.js +22 -0
  114. package/.server/server/plugins/engine/components/NumberField.js.map +1 -1
  115. package/.server/server/plugins/engine/components/OsGridRefField.d.ts +103 -1
  116. package/.server/server/plugins/engine/components/OsGridRefField.js +13 -3
  117. package/.server/server/plugins/engine/components/OsGridRefField.js.map +1 -1
  118. package/.server/server/plugins/engine/components/PaymentField.d.ts +2 -0
  119. package/.server/server/plugins/engine/components/PaymentField.js +9 -5
  120. package/.server/server/plugins/engine/components/PaymentField.js.map +1 -1
  121. package/.server/server/plugins/engine/components/SelectField.d.ts +1 -0
  122. package/.server/server/plugins/engine/components/SelectionControlField.d.ts +1 -0
  123. package/.server/server/plugins/engine/components/TelephoneNumberField.d.ts +1 -0
  124. package/.server/server/plugins/engine/components/TrackingField.d.ts +21 -0
  125. package/.server/server/plugins/engine/components/TrackingField.js +46 -0
  126. package/.server/server/plugins/engine/components/TrackingField.js.map +1 -0
  127. package/.server/server/plugins/engine/components/UkAddressField.d.ts +1 -0
  128. package/.server/server/plugins/engine/components/UkAddressField.js +23 -8
  129. package/.server/server/plugins/engine/components/UkAddressField.js.map +1 -1
  130. package/.server/server/plugins/engine/components/YesNoField.d.ts +3 -2
  131. package/.server/server/plugins/engine/components/YesNoField.js +22 -8
  132. package/.server/server/plugins/engine/components/YesNoField.js.map +1 -1
  133. package/.server/server/plugins/engine/components/helpers/components.d.ts +1 -1
  134. package/.server/server/plugins/engine/components/helpers/components.js +6 -3
  135. package/.server/server/plugins/engine/components/helpers/components.js.map +1 -1
  136. package/.server/server/plugins/engine/components/helpers/geospatial.d.ts +8 -1
  137. package/.server/server/plugins/engine/components/helpers/geospatial.js +58 -17
  138. package/.server/server/plugins/engine/components/helpers/geospatial.js.map +1 -1
  139. package/.server/server/plugins/engine/components/helpers/index.d.ts +21 -1
  140. package/.server/server/plugins/engine/components/helpers/index.js +45 -1
  141. package/.server/server/plugins/engine/components/helpers/index.js.map +1 -1
  142. package/.server/server/plugins/engine/components/index.d.ts +1 -0
  143. package/.server/server/plugins/engine/components/index.js +1 -0
  144. package/.server/server/plugins/engine/components/index.js.map +1 -1
  145. package/.server/server/plugins/engine/components/types.d.ts +1 -0
  146. package/.server/server/plugins/engine/components/types.js.map +1 -1
  147. package/.server/server/plugins/engine/errors.d.ts +49 -0
  148. package/.server/server/plugins/engine/errors.js +75 -0
  149. package/.server/server/plugins/engine/errors.js.map +1 -0
  150. package/.server/server/plugins/engine/form-availability.d.ts +3 -2
  151. package/.server/server/plugins/engine/form-availability.js +3 -2
  152. package/.server/server/plugins/engine/form-availability.js.map +1 -1
  153. package/.server/server/plugins/engine/form-context.js +2 -2
  154. package/.server/server/plugins/engine/form-context.js.map +1 -1
  155. package/.server/server/plugins/engine/helpers.d.ts +23 -2
  156. package/.server/server/plugins/engine/helpers.js +44 -5
  157. package/.server/server/plugins/engine/helpers.js.map +1 -1
  158. package/.server/server/plugins/engine/i18n/buildValidationMessages.d.ts +4 -1
  159. package/.server/server/plugins/engine/i18n/buildValidationMessages.js +31 -7
  160. package/.server/server/plugins/engine/i18n/buildValidationMessages.js.map +1 -1
  161. package/.server/server/plugins/engine/i18n/createFormTranslator.d.ts +4 -4
  162. package/.server/server/plugins/engine/i18n/createFormTranslator.js +27 -5
  163. package/.server/server/plugins/engine/i18n/createFormTranslator.js.map +1 -1
  164. package/.server/server/plugins/engine/i18n/extractBaseTranslations.d.ts +1 -1
  165. package/.server/server/plugins/engine/i18n/extractBaseTranslations.js +9 -0
  166. package/.server/server/plugins/engine/i18n/extractBaseTranslations.js.map +1 -1
  167. package/.server/server/plugins/engine/i18n/form.d.ts +13 -0
  168. package/.server/server/plugins/engine/i18n/form.js +35 -0
  169. package/.server/server/plugins/engine/i18n/form.js.map +1 -0
  170. package/.server/server/plugins/engine/i18n/languages.d.ts +10 -0
  171. package/.server/server/plugins/engine/i18n/languages.js +19 -0
  172. package/.server/server/plugins/engine/i18n/languages.js.map +1 -0
  173. package/.server/server/plugins/engine/i18n/translations/cy.json +176 -7
  174. package/.server/server/plugins/engine/i18n/translations/en-GB.json +110 -6
  175. package/.server/server/plugins/engine/i18n/types.d.ts +2 -0
  176. package/.server/server/plugins/engine/i18n/types.js.map +1 -1
  177. package/.server/server/plugins/engine/index.d.ts +4 -0
  178. package/.server/server/plugins/engine/index.js +4 -0
  179. package/.server/server/plugins/engine/index.js.map +1 -1
  180. package/.server/server/plugins/engine/models/FormModel.d.ts +0 -4
  181. package/.server/server/plugins/engine/models/FormModel.js +35 -23
  182. package/.server/server/plugins/engine/models/FormModel.js.map +1 -1
  183. package/.server/server/plugins/engine/models/SummaryViewModel.js +9 -4
  184. package/.server/server/plugins/engine/models/SummaryViewModel.js.map +1 -1
  185. package/.server/server/plugins/engine/models/types.d.ts +28 -1
  186. package/.server/server/plugins/engine/models/types.js.map +1 -1
  187. package/.server/server/plugins/engine/models/unavailable-view-model.d.ts +11 -2
  188. package/.server/server/plugins/engine/models/unavailable-view-model.js +23 -4
  189. package/.server/server/plugins/engine/models/unavailable-view-model.js.map +1 -1
  190. package/.server/server/plugins/engine/options.js +2 -1
  191. package/.server/server/plugins/engine/options.js.map +1 -1
  192. package/.server/server/plugins/engine/outputFormatters/adapter/v1.js +14 -6
  193. package/.server/server/plugins/engine/outputFormatters/adapter/v1.js.map +1 -1
  194. package/.server/server/plugins/engine/outputFormatters/human/v1.js +2 -1
  195. package/.server/server/plugins/engine/outputFormatters/human/v1.js.map +1 -1
  196. package/.server/server/plugins/engine/outputFormatters/machine/v2.d.ts +2 -0
  197. package/.server/server/plugins/engine/outputFormatters/machine/v2.js +2 -0
  198. package/.server/server/plugins/engine/outputFormatters/machine/v2.js.map +1 -1
  199. package/.server/server/plugins/engine/pageControllers/FileUploadPageController.d.ts +7 -1
  200. package/.server/server/plugins/engine/pageControllers/FileUploadPageController.js +56 -10
  201. package/.server/server/plugins/engine/pageControllers/FileUploadPageController.js.map +1 -1
  202. package/.server/server/plugins/engine/pageControllers/QuestionPageController.d.ts +1 -1
  203. package/.server/server/plugins/engine/pageControllers/QuestionPageController.js +2 -2
  204. package/.server/server/plugins/engine/pageControllers/QuestionPageController.js.map +1 -1
  205. package/.server/server/plugins/engine/pageControllers/RepeatPageController.js +3 -4
  206. package/.server/server/plugins/engine/pageControllers/RepeatPageController.js.map +1 -1
  207. package/.server/server/plugins/engine/pageControllers/SummaryPageController.js +10 -4
  208. package/.server/server/plugins/engine/pageControllers/SummaryPageController.js.map +1 -1
  209. package/.server/server/plugins/engine/pageControllers/helpers/pages.js +2 -1
  210. package/.server/server/plugins/engine/pageControllers/helpers/pages.js.map +1 -1
  211. package/.server/server/plugins/engine/pageControllers/helpers/submission.d.ts +35 -2
  212. package/.server/server/plugins/engine/pageControllers/helpers/submission.js +100 -3
  213. package/.server/server/plugins/engine/pageControllers/helpers/submission.js.map +1 -1
  214. package/.server/server/plugins/engine/pageControllers/validationOptions.d.ts +1 -1
  215. package/.server/server/plugins/engine/pageControllers/validationOptions.js +24 -3
  216. package/.server/server/plugins/engine/pageControllers/validationOptions.js.map +1 -1
  217. package/.server/server/plugins/engine/plugin.js +3 -0
  218. package/.server/server/plugins/engine/plugin.js.map +1 -1
  219. package/.server/server/plugins/engine/referenceNumbers.d.ts +1 -0
  220. package/.server/server/plugins/engine/referenceNumbers.js +1 -0
  221. package/.server/server/plugins/engine/referenceNumbers.js.map +1 -1
  222. package/.server/server/plugins/engine/routes/index.js +9 -4
  223. package/.server/server/plugins/engine/routes/index.js.map +1 -1
  224. package/.server/server/plugins/engine/types/enums.d.ts +3 -3
  225. package/.server/server/plugins/engine/types/enums.js +5 -4
  226. package/.server/server/plugins/engine/types/enums.js.map +1 -1
  227. package/.server/server/plugins/engine/types/schema.js +15 -4
  228. package/.server/server/plugins/engine/types/schema.js.map +1 -1
  229. package/.server/server/plugins/engine/types.d.ts +24 -2
  230. package/.server/server/plugins/engine/types.js.map +1 -1
  231. package/.server/server/plugins/engine/unavailable-response.js +5 -2
  232. package/.server/server/plugins/engine/unavailable-response.js.map +1 -1
  233. package/.server/server/plugins/engine/views/components/_location-field-base.html +4 -2
  234. package/.server/server/plugins/engine/views/components/fileuploadfield.html +1 -1
  235. package/.server/server/plugins/engine/views/components/geospatialfield.html +1 -0
  236. package/.server/server/plugins/engine/views/components/osgridreffield.html +4 -1
  237. package/.server/server/plugins/engine/views/components/trackingfield.html +3 -0
  238. package/.server/server/plugins/engine/views/components/ukaddressfield.html +1 -1
  239. package/.server/server/plugins/engine/views/file-upload.html +1 -1
  240. package/.server/server/plugins/engine/views/summary.html +1 -0
  241. package/.server/server/plugins/engine/views/unavailable.html +14 -11
  242. package/.server/server/plugins/map/routes/index.d.ts +4 -0
  243. package/.server/server/plugins/map/routes/index.js +12 -4
  244. package/.server/server/plugins/map/routes/index.js.map +1 -1
  245. package/.server/server/plugins/map/routes/index.test.js +7 -0
  246. package/.server/server/plugins/map/routes/index.test.js.map +1 -0
  247. package/.server/server/plugins/map/routes/vts/README.md +38 -0
  248. package/.server/server/plugins/map/routes/vts/countries-5dp.geojson +4 -0
  249. package/.server/server/plugins/map/routes/vts/countries.geojson +10 -39283
  250. package/.server/server/plugins/map/types.d.ts +24 -2
  251. package/.server/server/plugins/map/types.js +9 -2
  252. package/.server/server/plugins/map/types.js.map +1 -1
  253. package/.server/server/plugins/nunjucks/enviroment.test.js +11 -4
  254. package/.server/server/plugins/nunjucks/enviroment.test.js.map +1 -1
  255. package/.server/server/plugins/nunjucks/filters/applyUrlParam.d.ts +9 -0
  256. package/.server/server/plugins/nunjucks/filters/applyUrlParam.js +17 -0
  257. package/.server/server/plugins/nunjucks/filters/applyUrlParam.js.map +1 -0
  258. package/.server/server/plugins/nunjucks/filters/applyUrlParam.test.js +17 -0
  259. package/.server/server/plugins/nunjucks/filters/applyUrlParam.test.js.map +1 -0
  260. package/.server/server/plugins/nunjucks/filters/field.d.ts +1 -1
  261. package/.server/server/plugins/nunjucks/filters/index.d.ts +1 -0
  262. package/.server/server/plugins/nunjucks/filters/index.js +1 -0
  263. package/.server/server/plugins/nunjucks/filters/index.js.map +1 -1
  264. package/.server/server/plugins/payment/helper.d.ts +11 -1
  265. package/.server/server/plugins/payment/helper.js +18 -2
  266. package/.server/server/plugins/payment/helper.js.map +1 -1
  267. package/.server/server/plugins/payment/helper.test.js +2 -1
  268. package/.server/server/plugins/payment/helper.test.js.map +1 -1
  269. package/.server/server/plugins/payment/service.d.ts +2 -1
  270. package/.server/server/plugins/payment/service.js +5 -2
  271. package/.server/server/plugins/payment/service.js.map +1 -1
  272. package/.server/server/plugins/payment/service.test.js +7 -3
  273. package/.server/server/plugins/payment/service.test.js.map +1 -1
  274. package/.server/server/plugins/payment/types.d.ts +4 -0
  275. package/.server/server/plugins/payment/types.js +1 -0
  276. package/.server/server/plugins/payment/types.js.map +1 -1
  277. package/.server/server/plugins/postcode-lookup/models/index.d.ts +249 -3
  278. package/.server/server/plugins/postcode-lookup/models/index.js +103 -36
  279. package/.server/server/plugins/postcode-lookup/models/index.js.map +1 -1
  280. package/.server/server/plugins/postcode-lookup/routes/index.d.ts +15 -1
  281. package/.server/server/plugins/postcode-lookup/routes/index.js +64 -18
  282. package/.server/server/plugins/postcode-lookup/routes/index.js.map +1 -1
  283. package/.server/server/plugins/postcode-lookup/routes/index.test.js +84 -0
  284. package/.server/server/plugins/postcode-lookup/routes/index.test.js.map +1 -0
  285. package/.server/server/plugins/postcode-lookup/types.d.ts +12 -0
  286. package/.server/server/plugins/postcode-lookup/types.js +6 -1
  287. package/.server/server/plugins/postcode-lookup/types.js.map +1 -1
  288. package/.server/server/plugins/postcode-lookup/views/postcode-lookup-details.html +3 -3
  289. package/.server/server/utils/type-utils.d.ts +1 -2
  290. package/.server/server/utils/type-utils.js +0 -3
  291. package/.server/server/utils/type-utils.js.map +1 -1
  292. package/.server/server/utils/utils.d.ts +6 -0
  293. package/.server/server/utils/utils.js +18 -1
  294. package/.server/server/utils/utils.js.map +1 -1
  295. package/.server/server/utils/utils.test.js +21 -1
  296. package/.server/server/utils/utils.test.js.map +1 -1
  297. package/.server/typings/geodesy/index.d.js +2 -0
  298. package/.server/typings/geodesy/index.d.js.map +1 -0
  299. package/.server/typings/hapi/index.d.js.map +1 -1
  300. package/package.json +24 -9
  301. package/src/client/javascripts/file-upload.js +11 -3
  302. package/src/client/javascripts/geospatial-map.js +181 -86
  303. package/src/client/javascripts/govuk.js +2 -0
  304. package/src/client/javascripts/location-map.js +62 -6
  305. package/src/client/javascripts/map-constants.js +3 -0
  306. package/src/client/javascripts/map.js +66 -9
  307. package/src/client/javascripts/maps.js +5 -0
  308. package/src/client/javascripts/shared.js +1 -4
  309. package/src/client/javascripts/sssi-dataset.js +39 -41
  310. package/src/client/stylesheets/maps.scss +4 -0
  311. package/src/client/stylesheets/shared.scss +1 -5
  312. package/src/server/constants.js +2 -0
  313. package/src/server/forms/components.json +8 -0
  314. package/src/server/forms/register-as-a-unicorn-breeder.yaml +4 -0
  315. package/src/server/plugins/engine/__stubs__/definitions.ts +155 -0
  316. package/src/server/plugins/engine/components/AutocompleteField.ts +20 -0
  317. package/src/server/plugins/engine/components/CheckboxesField.ts +41 -8
  318. package/src/server/plugins/engine/components/ComponentBase.ts +6 -4
  319. package/src/server/plugins/engine/components/ComponentCollection.ts +17 -15
  320. package/src/server/plugins/engine/components/DatePartsField.ts +20 -9
  321. package/src/server/plugins/engine/components/DeclarationField.ts +10 -10
  322. package/src/server/plugins/engine/components/EastingNorthingField.ts +185 -89
  323. package/src/server/plugins/engine/components/EmailAddressField.ts +2 -1
  324. package/src/server/plugins/engine/components/FileUploadField.ts +46 -5
  325. package/src/server/plugins/engine/components/FormComponent.ts +6 -5
  326. package/src/server/plugins/engine/components/GeospatialField.ts +47 -9
  327. package/src/server/plugins/engine/components/LatLongField.ts +128 -58
  328. package/src/server/plugins/engine/components/ListFormComponent.ts +4 -4
  329. package/src/server/plugins/engine/components/LocationFieldBase.ts +41 -8
  330. package/src/server/plugins/engine/components/LocationFieldHelpers.ts +28 -14
  331. package/src/server/plugins/engine/components/Markdown.ts +2 -3
  332. package/src/server/plugins/engine/components/MonthYearField.ts +20 -15
  333. package/src/server/plugins/engine/components/NationalGridFieldNumberField.ts +9 -3
  334. package/src/server/plugins/engine/components/NumberField.ts +24 -0
  335. package/src/server/plugins/engine/components/OsGridRefField.ts +22 -3
  336. package/src/server/plugins/engine/components/PaymentField.ts +9 -4
  337. package/src/server/plugins/engine/components/TrackingField.ts +64 -0
  338. package/src/server/plugins/engine/components/UkAddressField.ts +30 -7
  339. package/src/server/plugins/engine/components/YesNoField.ts +27 -9
  340. package/src/server/plugins/engine/components/helpers/components.ts +8 -3
  341. package/src/server/plugins/engine/components/helpers/geospatial.ts +87 -24
  342. package/src/server/plugins/engine/components/helpers/index.ts +64 -1
  343. package/src/server/plugins/engine/components/index.ts +1 -0
  344. package/src/server/plugins/engine/components/types.ts +1 -0
  345. package/src/server/plugins/engine/errors.ts +78 -0
  346. package/src/server/plugins/engine/form-availability.ts +8 -2
  347. package/src/server/plugins/engine/form-context.ts +4 -2
  348. package/src/server/plugins/engine/helpers.ts +52 -5
  349. package/src/server/plugins/engine/i18n/buildValidationMessages.ts +16 -8
  350. package/src/server/plugins/engine/i18n/createFormTranslator.ts +43 -12
  351. package/src/server/plugins/engine/i18n/extractBaseTranslations.ts +7 -1
  352. package/src/server/plugins/engine/i18n/form.ts +54 -0
  353. package/src/server/plugins/engine/i18n/languages.ts +19 -0
  354. package/src/server/plugins/engine/i18n/translations/cy.json +176 -7
  355. package/src/server/plugins/engine/i18n/translations/en-GB.json +110 -6
  356. package/src/server/plugins/engine/i18n/types.ts +2 -0
  357. package/src/server/plugins/engine/index.ts +7 -0
  358. package/src/server/plugins/engine/models/FormModel.ts +46 -23
  359. package/src/server/plugins/engine/models/SummaryViewModel.ts +6 -5
  360. package/src/server/plugins/engine/models/types.ts +31 -0
  361. package/src/server/plugins/engine/models/unavailable-view-model.ts +26 -5
  362. package/src/server/plugins/engine/options.js +2 -1
  363. package/src/server/plugins/engine/outputFormatters/adapter/v1.ts +18 -7
  364. package/src/server/plugins/engine/outputFormatters/human/v1.ts +2 -1
  365. package/src/server/plugins/engine/outputFormatters/machine/v2.ts +3 -0
  366. package/src/server/plugins/engine/pageControllers/FileUploadPageController.ts +60 -9
  367. package/src/server/plugins/engine/pageControllers/QuestionPageController.ts +2 -2
  368. package/src/server/plugins/engine/pageControllers/RepeatPageController.ts +2 -2
  369. package/src/server/plugins/engine/pageControllers/SummaryPageController.ts +15 -4
  370. package/src/server/plugins/engine/pageControllers/helpers/pages.ts +2 -1
  371. package/src/server/plugins/engine/pageControllers/helpers/submission.ts +143 -4
  372. package/src/server/plugins/engine/pageControllers/validationOptions.ts +29 -4
  373. package/src/server/plugins/engine/plugin.ts +6 -0
  374. package/src/server/plugins/engine/referenceNumbers.ts +2 -0
  375. package/src/server/plugins/engine/routes/index.ts +9 -3
  376. package/src/server/plugins/engine/types/enums.ts +4 -3
  377. package/src/server/plugins/engine/types/schema.ts +22 -5
  378. package/src/server/plugins/engine/types.ts +28 -1
  379. package/src/server/plugins/engine/unavailable-response.ts +6 -2
  380. package/src/server/plugins/engine/views/components/_location-field-base.html +4 -2
  381. package/src/server/plugins/engine/views/components/fileuploadfield.html +1 -1
  382. package/src/server/plugins/engine/views/components/geospatialfield.html +1 -0
  383. package/src/server/plugins/engine/views/components/osgridreffield.html +4 -1
  384. package/src/server/plugins/engine/views/components/trackingfield.html +3 -0
  385. package/src/server/plugins/engine/views/components/ukaddressfield.html +1 -1
  386. package/src/server/plugins/engine/views/file-upload.html +1 -1
  387. package/src/server/plugins/engine/views/summary.html +1 -0
  388. package/src/server/plugins/engine/views/unavailable.html +14 -11
  389. package/src/server/plugins/map/routes/index.js +29 -4
  390. package/src/server/plugins/map/routes/vts/README.md +38 -0
  391. package/src/server/plugins/map/routes/vts/countries-5dp.geojson +4 -0
  392. package/src/server/plugins/map/routes/vts/countries.geojson +10 -39283
  393. package/src/server/plugins/map/types.js +9 -2
  394. package/src/server/plugins/nunjucks/filters/applyUrlParam.js +17 -0
  395. package/src/server/plugins/nunjucks/filters/index.js +1 -0
  396. package/src/server/plugins/payment/helper.js +22 -2
  397. package/src/server/plugins/payment/service.js +6 -2
  398. package/src/server/plugins/payment/types.js +1 -0
  399. package/src/server/plugins/postcode-lookup/models/index.js +91 -46
  400. package/src/server/plugins/postcode-lookup/routes/index.js +96 -24
  401. package/src/server/plugins/postcode-lookup/types.js +6 -1
  402. package/src/server/plugins/postcode-lookup/views/postcode-lookup-details.html +3 -3
  403. package/src/server/utils/type-utils.ts +1 -11
  404. package/src/server/utils/utils.js +19 -1
  405. package/src/typings/geodesy/index.d.ts +18 -0
  406. package/src/typings/hapi/index.d.ts +2 -0
@@ -8,6 +8,7 @@ import {
8
8
 
9
9
  import { type FormModel } from './models/index.js'
10
10
  import { validatePluginOptions } from './options.js'
11
+ import { generateUniqueReference } from './referenceNumbers.js'
11
12
  import { getRoutes as getFileUploadStatusRoutes } from './routes/file-upload.js'
12
13
  import { makeLoadFormPreHandler } from './routes/index.js'
13
14
  import { getRoutes as getPaymentRoutes } from './routes/payment.js'
@@ -37,6 +38,7 @@ export const plugin = {
37
38
  cache,
38
39
  saveAndExit,
39
40
  getLanguage,
41
+ generateReferenceNumber,
40
42
  nunjucks: nunjucksOptions,
41
43
  viewContext,
42
44
  preparePageEventRequestOptions,
@@ -80,6 +82,10 @@ export const plugin = {
80
82
  server.expose('cacheService', cacheService)
81
83
  server.expose('saveAndExit', saveAndExit)
82
84
  server.expose('getLanguage', getLanguage)
85
+ server.expose(
86
+ 'generateReferenceNumber',
87
+ generateReferenceNumber ?? generateUniqueReference
88
+ )
83
89
  server.expose('baseUrl', baseUrl)
84
90
  server.expose('services', services)
85
91
 
@@ -6,6 +6,8 @@ import {
6
6
  englishRecommendedTransformers
7
7
  } from 'obscenity'
8
8
 
9
+ export const DEFAULT_REFERENCE_NUMBER = 'XXX-XXX-XXX'
10
+
9
11
  /**
10
12
  * To prevent confusion to users reading the reference number, ambiguous letters and numbers are removed.
11
13
  * @param strCodes - array of binary input values
@@ -20,6 +20,7 @@ import {
20
20
  findPage,
21
21
  getCacheService,
22
22
  getPage,
23
+ getPluginOptions,
23
24
  getStartPath,
24
25
  proceed
25
26
  } from '../helpers.js'
@@ -28,7 +29,7 @@ import {
28
29
  checkSaveAndExitRepeater,
29
30
  copyNotYetValidatedState
30
31
  } from '../pageControllers/helpers/state.js'
31
- import { generateUniqueReference } from '../referenceNumbers.js'
32
+ import { DEFAULT_REFERENCE_NUMBER } from '../referenceNumbers.js'
32
33
  import * as defaultServices from '../services/index.js'
33
34
  import {
34
35
  type AnyFormRequest,
@@ -54,7 +55,7 @@ export async function redirectOrMakeHandler(
54
55
  context: FormContext
55
56
  ) => ResponseObject | Promise<ResponseObject>
56
57
  ) {
57
- const { app, params } = request
58
+ const { app, params, query } = request
58
59
  const { model } = app
59
60
 
60
61
  if (!model) {
@@ -74,7 +75,12 @@ export async function redirectOrMakeHandler(
74
75
  )
75
76
  }
76
77
 
77
- const referenceNumber = generateUniqueReference(prefix)
78
+ const isForce = 'force' in query
79
+ const { generateReferenceNumber } = getPluginOptions(request.server)
80
+ const referenceNumber = isForce
81
+ ? DEFAULT_REFERENCE_NUMBER
82
+ : await generateReferenceNumber(prefix)
83
+
78
84
  state = await page.mergeState(request, state, {
79
85
  $$__referenceNumber: referenceNumber
80
86
  })
@@ -10,6 +10,7 @@ export enum FileStatus {
10
10
  pending = 'pending'
11
11
  }
12
12
 
13
- export enum FormAdapterSubmissionSchemaVersion {
14
- V1 = 1
15
- }
13
+ // Changed from an enum to enforce numeric values
14
+ export const FormAdapterSubmissionSchemaVersion = {
15
+ V1: 1
16
+ } as const satisfies Record<string, number>
@@ -1,5 +1,6 @@
1
1
  import {
2
2
  FormStatus,
3
+ formSubmitConditionEvaluationSchema,
3
4
  formVersionMetadataSchema,
4
5
  idSchema,
5
6
  notificationEmailAddressSchema,
@@ -18,9 +19,9 @@ import {
18
19
 
19
20
  export const formAdapterSubmissionMessageMetaSchema =
20
21
  Joi.object<FormAdapterSubmissionMessageMeta>().keys({
21
- schemaVersion: Joi.string().valid(
22
- ...Object.values(FormAdapterSubmissionSchemaVersion)
23
- ),
22
+ schemaVersion: Joi.number()
23
+ .valid(...Object.values(FormAdapterSubmissionSchemaVersion))
24
+ .required(),
24
25
  timestamp: Joi.date().required(),
25
26
  referenceNumber: Joi.string().required(),
26
27
  formName: titleSchema,
@@ -37,7 +38,11 @@ export const formAdapterSubmissionMessageMetaSchema =
37
38
  .pattern(/^/, Joi.any())
38
39
  .unknown()
39
40
  .optional()
40
- .description('Custom properties for the message')
41
+ .description('Custom properties for the message'),
42
+ auth: Joi.object({
43
+ sub: Joi.string().required(),
44
+ issuer: Joi.string().required()
45
+ }).optional()
41
46
  })
42
47
 
43
48
  export const formAdapterSubmissionMessageDataSchema =
@@ -50,6 +55,7 @@ export const formAdapterSubmissionMessageDataSchema =
50
55
  reference: Joi.string().required(),
51
56
  amount: Joi.number().required(),
52
57
  description: Joi.string().required(),
58
+ descriptionInEng: Joi.string().optional(),
53
59
  createdAt: Joi.string().required()
54
60
  })
55
61
  .optional(),
@@ -79,5 +85,16 @@ export const formAdapterSubmissionMessagePayloadSchema =
79
85
  Joi.object<FormAdapterSubmissionMessagePayload>().keys({
80
86
  meta: formAdapterSubmissionMessageMetaSchema.required(),
81
87
  data: formAdapterSubmissionMessageDataSchema.required(),
82
- result: formAdapterSubmissionMessageResultSchema.required()
88
+ result: formAdapterSubmissionMessageResultSchema.required(),
89
+ // Optional so that messages published before this existed - which may
90
+ // still be in flight or sitting on a dead-letter queue - continue to
91
+ // validate. Consumers treat its absence as "resolve the recipients from
92
+ // the form definition yourself"
93
+ // This should be required at a later point in time.
94
+ conditionEvaluations: Joi.array()
95
+ .items(formSubmitConditionEvaluationSchema)
96
+ .optional()
97
+ .description(
98
+ 'Outcome of every condition in the form definition, evaluated against the final answers at submission'
99
+ )
83
100
  })
@@ -6,6 +6,7 @@ import {
6
6
  type List,
7
7
  type Page,
8
8
  type PaymentFieldComponent,
9
+ type SubmitConditionEvaluation,
9
10
  type UkAddressFieldComponent
10
11
  } from '@defra/forms-model'
11
12
  import {
@@ -245,11 +246,15 @@ export type FileUpload = {
245
246
  } & (
246
247
  | {
247
248
  fileStatus: FileStatus.complete | FileStatus.rejected | FileStatus.pending
249
+ errorCode?: string
248
250
  errorMessage?: string
251
+ errorParams?: Record<string, number | string | string[]>
249
252
  }
250
253
  | {
251
254
  fileStatus: FileStatus.complete
255
+ errorCode?: string
252
256
  errorMessage?: undefined
257
+ errorParams?: Record<string, number | string | string[]>
253
258
  }
254
259
  )
255
260
 
@@ -479,6 +484,10 @@ export type SaveAndExitHandler = (
479
484
 
480
485
  export type GetLanguageHandler = (query?: RequestQuery, yar?: Yar) => string
481
486
 
487
+ export type GenerateReferenceNumberHandler = (
488
+ prefix?: string
489
+ ) => Promise<string>
490
+
482
491
  export interface ExternalArgs {
483
492
  component: ComponentDef
484
493
  controller: QuestionPageController
@@ -519,13 +528,14 @@ export interface PluginOptions {
519
528
  preparePageEventRequestOptions?: PreparePageEventRequestOptions
520
529
  onRequest?: OnRequestCallback
521
530
  getLanguage?: GetLanguageHandler
531
+ generateReferenceNumber?: GenerateReferenceNumberHandler
522
532
  baseUrl: string // base URL of the application, protocol and hostname e.g. "https://myapp.com"
523
533
  ordnanceSurveyApiKey?: string
524
534
  ordnanceSurveyApiSecret?: string
525
535
  }
526
536
 
527
537
  export interface FormAdapterSubmissionMessageMeta {
528
- schemaVersion: FormAdapterSubmissionSchemaVersion
538
+ schemaVersion: (typeof FormAdapterSubmissionSchemaVersion)[keyof typeof FormAdapterSubmissionSchemaVersion]
529
539
  timestamp: Date
530
540
  referenceNumber: string
531
541
  formName: string
@@ -537,6 +547,10 @@ export interface FormAdapterSubmissionMessageMeta {
537
547
  versionMetadata?: FormVersionMetadata
538
548
  language?: string
539
549
  custom?: Record<string, unknown>
550
+ auth?: {
551
+ sub: string
552
+ issuer: string
553
+ }
540
554
  }
541
555
 
542
556
  export type FormAdapterSubmissionMessageMetaSerialised = Omit<
@@ -558,6 +572,7 @@ export interface FormAdapterPayment {
558
572
  reference: string
559
573
  amount: number
560
574
  description: string
575
+ descriptionInEng?: string
561
576
  createdAt: string
562
577
  }
563
578
 
@@ -602,6 +617,18 @@ export interface FormAdapterSubmissionMessagePayload {
602
617
  meta: FormAdapterSubmissionMessageMeta
603
618
  data: FormAdapterSubmissionMessageData
604
619
  result: FormAdapterSubmissionMessageResult
620
+
621
+ /**
622
+ * The outcome of every condition in the form definition, evaluated against
623
+ * the final answers at the point of submission.
624
+ *
625
+ * Always emitted, empty when there is nothing to report - a V1-engine form
626
+ * has no stable condition ids to record against. Optional only for
627
+ * backwards compatibility: a message published before this existed carries
628
+ * no evaluations at all, and consumers fall back to resolving the recipients
629
+ * from the form definition themselves.
630
+ */
631
+ conditionEvaluations?: SubmitConditionEvaluation[]
605
632
  }
606
633
 
607
634
  export interface FormAdapterSubmissionMessage extends FormAdapterSubmissionMessagePayload {
@@ -2,6 +2,8 @@ import { type Request, type ResponseToolkit, type Server } from '@hapi/hapi'
2
2
 
3
3
  import { isOfflineBoom } from './form-availability.js'
4
4
  import { unavailableViewModel } from './models/unavailable-view-model.js'
5
+ import { type AnyFormRequest } from './types.js'
6
+ import { resolveLanguage } from '../../utils/utils.js'
5
7
 
6
8
  /**
7
9
  * Registers a server-wide onPreResponse extension that intercepts the offline
@@ -17,10 +19,12 @@ export function registerUnavailableResponse(server: Server) {
17
19
  return h.continue
18
20
  }
19
21
 
20
- const { metadata } = response.data
22
+ const { metadata, definition } = response.data
23
+
24
+ const language = resolveLanguage(request as unknown as AnyFormRequest)
21
25
 
22
26
  return h
23
- .view('unavailable', unavailableViewModel(metadata))
27
+ .view('unavailable', unavailableViewModel(metadata, definition, language))
24
28
  .header('Cache-Control', 'no-store, no-cache, must-revalidate')
25
29
  .header('X-Robots-Tag', 'noindex, nofollow')
26
30
  .code(200)
@@ -61,7 +61,7 @@
61
61
  {% set detailsHtml %}
62
62
  {% if component.model.instructionText %}
63
63
  {{ govukDetails({
64
- summaryText: t('components.locationFieldBase.howToFind'),
64
+ summaryText: component.model.instructionSummary,
65
65
  html: component.model.instructionText | markdown | safe,
66
66
  classes: "govuk-!-margin-top-3"
67
67
  }) }}
@@ -70,8 +70,10 @@
70
70
 
71
71
  {% set hasErrors = showFieldsetError and component.model.errorMessage %}
72
72
 
73
- <div class="govuk-form-group app-location-field {{ "govuk-form-group--error" if hasErrors }}"
73
+ <div id="{{component.model.name}}" class="govuk-form-group app-location-field {{ "govuk-form-group--error" if hasErrors }}"
74
74
  data-locationtype="{{component.type | lower}}"
75
+ data-country="{{component.model.country}}"
76
+ data-lang="{{component.model.lang}}"
75
77
  data-maplayers="{{component.model.mapLayers}}">
76
78
  {{ govukFieldset({
77
79
  legend: {
@@ -3,7 +3,7 @@
3
3
  {% macro FileUploadField(component) %}
4
4
  {% set upload = component.model.upload %}
5
5
 
6
- <div id="uploadedFilesContainer">
6
+ <div id="uploadedFilesContainer" data-uploadinglabel="{{ upload.uploadingLabel }}">
7
7
  <h2 class="govuk-heading-m">{{ t('components.fileUploadField.uploadedFilesHeading') }}</h2>
8
8
  {% if upload.count %}
9
9
  <p class="govuk-body" role="alert">{{ t('components.fileUploadField.filesCount', { count: upload.count }) }}</p>
@@ -2,6 +2,7 @@
2
2
 
3
3
  {% macro GeospatialField(component) %}
4
4
  <div class="app-geospatial-field"
5
+ data-lang="{{component.model.lang}}"
5
6
  data-country="{{component.model.country}}"
6
7
  data-geometryTypes="{{component.model.geometryTypes}}"
7
8
  data-maplayers="{{component.model.mapLayers}}">
@@ -3,7 +3,10 @@
3
3
 
4
4
  {% macro OsGridRefField(component) %}
5
5
  {% set hasErrors = component.model.errorMessage %}
6
- <div class="govuk-form-group app-location-field {{ "govuk-form-group--error" if hasErrors }}" data-locationtype="{{component.type | lower}}">
6
+ <div class="govuk-form-group app-location-field {{ "govuk-form-group--error" if hasErrors }}"
7
+ data-locationtype="{{component.type | lower}}"
8
+ data-lang="{{component.model.lang}}"
9
+ data-maplayers="{{component.model.mapLayers}}">
7
10
  <div class="app-location-field-inputs">
8
11
  {{ TextField(component) }}
9
12
  </div>
@@ -0,0 +1,3 @@
1
+ {% macro TrackingField(component) %}
2
+ <input type="hidden" id="{{ component.model.name }}" name="{{ component.model.name }}" value="true" />
3
+ {% endmacro %}
@@ -61,7 +61,7 @@
61
61
  },
62
62
  classes: "govuk-button--secondary govuk-!-margin-right-1 govuk-!-margin-bottom-0"
63
63
  }) }}
64
- <p class="govuk-body govuk-!-margin-bottom-0">or <button class="govuk-link govuk-button--link govuk-!-margin-right-1 govuk-!-margin-bottom-0" name="action" value="external-{{component.model.name}}--step:manual">{{ t('components.addressField.enterManually') }}</button></p>
64
+ <p class="govuk-body govuk-!-margin-bottom-0">{{ t('common.or')}} <button class="govuk-link govuk-button--link govuk-!-margin-right-1 govuk-!-margin-bottom-0" name="action" value="external-{{component.model.name}}--step:manual">{{ t('components.addressField.enterManually') }}</button></p>
65
65
  </div>
66
66
  {# Include a line break if this is the last component #}
67
67
  {% if components[components.length - 1] == component %}
@@ -15,7 +15,7 @@
15
15
  {% if formAction %}
16
16
  {{ govukButton({
17
17
  text: t('pages.fileUpload.upload'),
18
- classes: "govuk-button--secondary upload-file-button",
18
+ classes: "govuk-button--secondary upload-file-button js-hidden",
19
19
  preventDoubleClick: true,
20
20
  disabled: context.isForceAccess
21
21
  }) }}
@@ -88,6 +88,7 @@
88
88
  When a better fix is implemented, this class can be removed and preventDoubleClick should be set back to true. #}
89
89
  {{ govukButton({
90
90
  text: submitButtonText,
91
+ classes: "prevent-multiple-clicks",
91
92
  name: "action",
92
93
  value: "send",
93
94
  preventDoubleClick: false
@@ -1,32 +1,35 @@
1
1
  {% extends baseLayoutPath %}
2
2
 
3
+ {% set t = context.translator.t %}
4
+ {% set tForm = context.translator.tForm %}
5
+
3
6
  {% block content %}
4
7
  <div class="govuk-grid-row">
5
8
  <div class="govuk-grid-column-two-thirds">
6
- <h1 class="govuk-heading-l">Sorry, this form is unavailable</h1>
7
- <p class="govuk-body">'{{ formTitle }}' is no longer available.</p>
8
- <h2 class="govuk-heading-m">Contact details for {{ organisationName }}</h2>
9
+ <h1 class="govuk-heading-l">{{ t('pages.formUnavailable.title') }}</h1>
10
+ <p class="govuk-body">{{ t('pages.formUnavailable.subHeading', { formTitle: formTitle }) }}</p>
11
+ <h2 class="govuk-heading-m">{{ t('pages.formUnavailable.contactDetailsHeading', { organisationName: organisationName }) }}</h2>
9
12
 
10
13
  {% if contact.phone %}
11
- <h3 class="govuk-heading-s">Telephone</h3>
14
+ <h3 class="govuk-heading-s">{{ t('pages.formUnavailable.telephone') }}</h3>
12
15
  <div class="app-prose-scope">
13
- {{ contact.phone | markdown(3) | safe }}
16
+ {{ tForm('contact.phone') | markdown(3) | safe }}
14
17
  </div>
15
- <p class="govuk-body"><a href="https://www.gov.uk/call-charges" class="govuk-link govuk-link--no-visited-state">Find out about call charges</a></p>
18
+ <p class="govuk-body"><a href="https://www.gov.uk/call-charges" class="govuk-link govuk-link--no-visited-state">{{ t('pages.formUnavailable.callCharges') }}</a></p>
16
19
  {% endif %}
17
20
 
18
21
  {% if contact.email %}
19
- <h3 class="govuk-heading-s">Email</h3>
22
+ <h3 class="govuk-heading-s">{{ t('pages.formUnavailable.email') }}</h3>
20
23
  <ul class="govuk-list">
21
- <li><a class="govuk-link govuk-link--no-visited-state" href="mailto:{{ contact.email.address }}">{{ contact.email.address }}</a></li>
22
- <li>{{ contact.email.responseTime }}</li>
24
+ <li><a class="govuk-link govuk-link--no-visited-state" href="mailto:{{ tForm('contact.email.address') }}">{{ tForm('contact.email.address') }}</a></li>
25
+ <li>{{ tForm('contact.email.responseTime') }}</li>
23
26
  </ul>
24
27
  {% endif %}
25
28
 
26
29
  {% if contact.online %}
27
- <h3 class="govuk-heading-s">Online contact form</h3>
30
+ <h3 class="govuk-heading-s">{{ t('pages.formUnavailable.onlineContactForm') }}</h3>
28
31
  <ul class="govuk-list">
29
- <li><a class="govuk-link govuk-link--no-visited-state" href="{{ contact.online.url }}">{{ contact.online.text }}</a></li>
32
+ <li><a class="govuk-link govuk-link--no-visited-state" href="{{ tForm('contact.online.url') }}">{{ tForm('contact.online.text') }}</a></li>
30
33
  </ul>
31
34
  {% endif %}
32
35
  </div>
@@ -7,18 +7,39 @@ import Joi from 'joi'
7
7
 
8
8
  import { getAccessToken } from './get-os-token.js'
9
9
  import { find } from '../service.js'
10
+ import { CountryMap } from '../types.js'
10
11
  import {
11
12
  get,
12
13
  request as httpRequest
13
14
  } from '../../../services/httpService.js'
14
15
 
15
- const filePath = resolve(import.meta.dirname, './vts/countries.geojson')
16
+ const countriesDisplayFilePath = resolve(
17
+ import.meta.dirname,
18
+ './vts/countries.geojson'
19
+ )
20
+ const countriesValidateFilePath = resolve(
21
+ import.meta.dirname,
22
+ './vts',
23
+ process.env.JEST_WORKER_ID === undefined
24
+ ? 'countries-5dp.geojson'
25
+ : 'countries.geojson'
26
+ )
16
27
 
17
28
  /**
18
29
  * @type {FeatureCollection}
19
30
  */
20
31
  // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
21
- export const countries = JSON.parse(fs.readFileSync(filePath, 'utf8'))
32
+ export const countries = JSON.parse(
33
+ fs.readFileSync(countriesDisplayFilePath, 'utf8')
34
+ )
35
+
36
+ /**
37
+ * @type {FeatureCollection}
38
+ */
39
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
40
+ export const countriesValidate = JSON.parse(
41
+ fs.readFileSync(countriesValidateFilePath, 'utf8')
42
+ )
22
43
 
23
44
  export const countrySchema = Joi.string().valid(
24
45
  ...Object.values(GeospatialFieldOptionsCountryEnum)
@@ -188,14 +209,18 @@ function getGeospatialCountries() {
188
209
  if (omit) {
189
210
  return {
190
211
  ...countries,
191
- features: countries.features.filter((feature) => feature.id !== omit)
212
+ features: countries.features.filter(
213
+ (feature) => feature.id !== CountryMap[omit]
214
+ )
192
215
  }
193
216
  }
194
217
 
195
218
  if (only) {
196
219
  return {
197
220
  ...countries,
198
- features: countries.features.filter((feature) => feature.id === only)
221
+ features: countries.features.filter(
222
+ (feature) => feature.id === CountryMap[only]
223
+ )
199
224
  }
200
225
  }
201
226
 
@@ -1,5 +1,43 @@
1
+ # VTS
2
+
1
3
  File in this directory are sourced from https://github.com/OrdnanceSurvey/OS-Vector-Tile-API-Stylesheets
2
4
 
3
5
  VTS_OUTDOOR_URL=https://raw.githubusercontent.com/OrdnanceSurvey/OS-Vector-Tile-API-Stylesheets/main/OS_VTS_3857_Outdoor.json
4
6
  VTS_DARK_URL=https://raw.githubusercontent.com/OrdnanceSurvey/OS-Vector-Tile-API-Stylesheets/main/OS_VTS_3857_Dark.json
5
7
  VTS_BLACK_AND_WHITE_URL=https://raw.githubusercontent.com/OrdnanceSurvey/OS-Vector-Tile-API-Stylesheets/main/OS_VTS_3857_Black_and_White.json
8
+
9
+ # Country boundaries
10
+
11
+ The [Office for National Statistics provides full-resolution boundaries](https://www.ons.gov.uk/methodology/geography/geographicalproducts/digitalboundaries) in two coastal forms.
12
+ We use "BFE" a full resolution — extent of the realm and generally extends to Mean Low Water rather than clipping at Mean High Water.
13
+
14
+ The latest version of the data is from 2025 and can be found at the following links:
15
+
16
+ https://geoportal.statistics.gov.uk/datasets/591803c2a3b94804a3d7895cc127d7c0_0/explore?location=50.529309%2C-4.098782%2C7
17
+
18
+ Download from: http://geoportal.statistics.gov.uk/ or https://geoportal.statistics.gov.uk/datasets/ons::countries-december-2025-boundaries-uk-bfe/about
19
+
20
+ The source data is for the 2025 revision is 179MB so needs to be reduced to allow rendering in a Web map and used for validation on the server. The downloaded file is named `boundaries-bfe.geojson`. `org2ogr` is used to produce two files:
21
+
22
+ ## Server-side validation (boundaries-bfe-5dp.geojson)
23
+
24
+ This is the full file but with coordinate precision reduced from 14 to 5 decimal places, resulting in a smaller file of 83.7MB.
25
+ This data is then used server-side to validate points, shapes and lines that include country restrictions.
26
+
27
+ `ogr2ogr --config OGR_GEOJSON_MAX_OBJ_SIZE 0 -f GeoJSON boundaries-bfe-5dp.geojson boundaries-bfe.geojson -lco COORDINATE_PRECISION=5`
28
+
29
+ ## Client-side display on map (boundaries-bfe-5dp.geojson)
30
+
31
+ To produce a file suitable for use in the map in the browser we use `ogr2ogr`'s `simplify` option.
32
+
33
+ `-simplify 0.001` uses the units of the input CRS. In EPSG:4326, that's degrees, not metres so a tolerance of 0.001° is roughly 111 metres north–south, which is quite a substantial simplification for coastal boundaries. For 0.001 to mean approximately one metre, we have to reproject to a suitable projected CRS (BNG, EPSG:27700) before simplifying:
34
+
35
+ The following command produces `boundaries-bng.geojson`, the source file reprojected to BNG.
36
+
37
+ `ogr2ogr --config OGR_GEOJSON_MAX_OBJ_SIZE 0 -f GeoJSON boundaries-bng.geojson boundaries-bfe.geojson -t_srs EPSG:27700`
38
+
39
+ We then use this to create a simplified dataset, `countries.geojson`, reprojected back in ESPG:4326:
40
+
41
+ `ogr2ogr --config OGR_GEOJSON_MAX_OBJ_SIZE 0 -f GeoJSON countries.geojson boundaries-bng.json -simplify 100 -t_srs EPSG:4326 -lco COORDINATE_PRECISION=5`
42
+
43
+ The result is a file of 940kB that is suitable to use in the web map.
@@ -0,0 +1,4 @@
1
+ [diffend] Oversized file quarantined before diffing.
2
+ name: package/src/server/plugins/map/routes/vts/countries-5dp.geojson
3
+ size: 83733031 bytes
4
+ sha256: 032725bc5cedcee3aeba36dc8bc6aa987343635c199f5fe723dc8b0478ae5954