@defra/forms-engine-plugin 5.0.0-alpha.2 → 5.0.0-alpha.20

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 (339) hide show
  1. package/.public/javascripts/application.min.js +1 -1
  2. package/.public/javascripts/application.min.js.LICENSE.txt +7 -0
  3. package/.public/javascripts/application.min.js.map +1 -1
  4. package/.public/javascripts/shared.min.js +1 -1
  5. package/.public/javascripts/shared.min.js.LICENSE.txt +7 -0
  6. package/.public/javascripts/shared.min.js.map +1 -1
  7. package/.public/stylesheets/application.min.css.map +1 -1
  8. package/.server/client/javascripts/file-upload.js +6 -3
  9. package/.server/client/javascripts/file-upload.js.map +1 -1
  10. package/.server/client/javascripts/geospatial-map.d.ts +153 -5
  11. package/.server/client/javascripts/geospatial-map.js +157 -77
  12. package/.server/client/javascripts/geospatial-map.js.map +1 -1
  13. package/.server/client/javascripts/govuk.js +2 -1
  14. package/.server/client/javascripts/govuk.js.map +1 -1
  15. package/.server/client/javascripts/location-map.d.ts +44 -0
  16. package/.server/client/javascripts/location-map.js +54 -5
  17. package/.server/client/javascripts/location-map.js.map +1 -1
  18. package/.server/client/javascripts/map-constants.d.ts +3 -0
  19. package/.server/client/javascripts/map-constants.js +4 -0
  20. package/.server/client/javascripts/map-constants.js.map +1 -0
  21. package/.server/client/javascripts/map.d.ts +10 -0
  22. package/.server/client/javascripts/map.js +42 -0
  23. package/.server/client/javascripts/map.js.map +1 -1
  24. package/.server/client/javascripts/maps.d.ts +5 -0
  25. package/.server/client/javascripts/maps.js +6 -0
  26. package/.server/client/javascripts/maps.js.map +1 -0
  27. package/.server/client/javascripts/shared.d.ts +1 -4
  28. package/.server/client/javascripts/shared.js +1 -4
  29. package/.server/client/javascripts/shared.js.map +1 -1
  30. package/.server/client/javascripts/sssi-dataset.d.ts +18 -20
  31. package/.server/client/javascripts/sssi-dataset.js +37 -39
  32. package/.server/client/javascripts/sssi-dataset.js.map +1 -1
  33. package/.server/client/stylesheets/maps.scss +4 -0
  34. package/.server/client/stylesheets/shared.scss +1 -5
  35. package/.server/server/constants.d.ts +2 -0
  36. package/.server/server/constants.js +2 -0
  37. package/.server/server/constants.js.map +1 -1
  38. package/.server/server/plugins/engine/__stubs__/definitions.d.ts +29 -0
  39. package/.server/server/plugins/engine/__stubs__/definitions.js +125 -0
  40. package/.server/server/plugins/engine/__stubs__/definitions.js.map +1 -0
  41. package/.server/server/plugins/engine/components/AutocompleteField.d.ts +9 -3
  42. package/.server/server/plugins/engine/components/AutocompleteField.js +12 -0
  43. package/.server/server/plugins/engine/components/AutocompleteField.js.map +1 -1
  44. package/.server/server/plugins/engine/components/CheckboxesField.d.ts +21 -0
  45. package/.server/server/plugins/engine/components/CheckboxesField.js +30 -5
  46. package/.server/server/plugins/engine/components/CheckboxesField.js.map +1 -1
  47. package/.server/server/plugins/engine/components/ComponentBase.d.ts +1 -0
  48. package/.server/server/plugins/engine/components/ComponentBase.js +2 -0
  49. package/.server/server/plugins/engine/components/ComponentBase.js.map +1 -1
  50. package/.server/server/plugins/engine/components/ComponentCollection.js +11 -6
  51. package/.server/server/plugins/engine/components/ComponentCollection.js.map +1 -1
  52. package/.server/server/plugins/engine/components/DatePartsField.d.ts +6 -3
  53. package/.server/server/plugins/engine/components/DatePartsField.js +12 -7
  54. package/.server/server/plugins/engine/components/DatePartsField.js.map +1 -1
  55. package/.server/server/plugins/engine/components/DeclarationField.d.ts +5 -2
  56. package/.server/server/plugins/engine/components/DeclarationField.js +6 -4
  57. package/.server/server/plugins/engine/components/DeclarationField.js.map +1 -1
  58. package/.server/server/plugins/engine/components/Details.d.ts +1 -0
  59. package/.server/server/plugins/engine/components/EastingNorthingField.d.ts +33 -2
  60. package/.server/server/plugins/engine/components/EastingNorthingField.js +110 -54
  61. package/.server/server/plugins/engine/components/EastingNorthingField.js.map +1 -1
  62. package/.server/server/plugins/engine/components/EmailAddressField.d.ts +4 -1
  63. package/.server/server/plugins/engine/components/EmailAddressField.js +2 -1
  64. package/.server/server/plugins/engine/components/EmailAddressField.js.map +1 -1
  65. package/.server/server/plugins/engine/components/FileUploadField.d.ts +21 -0
  66. package/.server/server/plugins/engine/components/FileUploadField.js +35 -3
  67. package/.server/server/plugins/engine/components/FileUploadField.js.map +1 -1
  68. package/.server/server/plugins/engine/components/FormComponent.d.ts +5 -1
  69. package/.server/server/plugins/engine/components/FormComponent.js +5 -2
  70. package/.server/server/plugins/engine/components/FormComponent.js.map +1 -1
  71. package/.server/server/plugins/engine/components/GeospatialField.d.ts +23 -0
  72. package/.server/server/plugins/engine/components/GeospatialField.js +33 -9
  73. package/.server/server/plugins/engine/components/GeospatialField.js.map +1 -1
  74. package/.server/server/plugins/engine/components/Html.d.ts +1 -0
  75. package/.server/server/plugins/engine/components/InsetText.d.ts +1 -0
  76. package/.server/server/plugins/engine/components/LatLongField.d.ts +32 -2
  77. package/.server/server/plugins/engine/components/LatLongField.js +85 -48
  78. package/.server/server/plugins/engine/components/LatLongField.js.map +1 -1
  79. package/.server/server/plugins/engine/components/List.d.ts +1 -0
  80. package/.server/server/plugins/engine/components/ListFormComponent.d.ts +1 -0
  81. package/.server/server/plugins/engine/components/LocationFieldBase.d.ts +8 -2
  82. package/.server/server/plugins/engine/components/LocationFieldBase.js +25 -6
  83. package/.server/server/plugins/engine/components/LocationFieldBase.js.map +1 -1
  84. package/.server/server/plugins/engine/components/LocationFieldHelpers.d.ts +12 -3
  85. package/.server/server/plugins/engine/components/LocationFieldHelpers.js +21 -13
  86. package/.server/server/plugins/engine/components/LocationFieldHelpers.js.map +1 -1
  87. package/.server/server/plugins/engine/components/Markdown.d.ts +1 -0
  88. package/.server/server/plugins/engine/components/Markdown.js +1 -1
  89. package/.server/server/plugins/engine/components/Markdown.js.map +1 -1
  90. package/.server/server/plugins/engine/components/MonthYearField.d.ts +5 -2
  91. package/.server/server/plugins/engine/components/MonthYearField.js +13 -9
  92. package/.server/server/plugins/engine/components/MonthYearField.js.map +1 -1
  93. package/.server/server/plugins/engine/components/MultilineTextField.d.ts +1 -0
  94. package/.server/server/plugins/engine/components/NationalGridFieldNumberField.d.ts +2 -1
  95. package/.server/server/plugins/engine/components/NationalGridFieldNumberField.js +4 -3
  96. package/.server/server/plugins/engine/components/NationalGridFieldNumberField.js.map +1 -1
  97. package/.server/server/plugins/engine/components/NotificationBanner.d.ts +1 -0
  98. package/.server/server/plugins/engine/components/NumberField.d.ts +5 -0
  99. package/.server/server/plugins/engine/components/NumberField.js +16 -0
  100. package/.server/server/plugins/engine/components/NumberField.js.map +1 -1
  101. package/.server/server/plugins/engine/components/OsGridRefField.d.ts +103 -1
  102. package/.server/server/plugins/engine/components/OsGridRefField.js +13 -3
  103. package/.server/server/plugins/engine/components/OsGridRefField.js.map +1 -1
  104. package/.server/server/plugins/engine/components/PaymentField.d.ts +3 -0
  105. package/.server/server/plugins/engine/components/PaymentField.js +17 -6
  106. package/.server/server/plugins/engine/components/PaymentField.js.map +1 -1
  107. package/.server/server/plugins/engine/components/SelectField.d.ts +1 -0
  108. package/.server/server/plugins/engine/components/SelectionControlField.d.ts +1 -0
  109. package/.server/server/plugins/engine/components/TelephoneNumberField.d.ts +1 -0
  110. package/.server/server/plugins/engine/components/UkAddressField.d.ts +1 -0
  111. package/.server/server/plugins/engine/components/UkAddressField.js +23 -8
  112. package/.server/server/plugins/engine/components/UkAddressField.js.map +1 -1
  113. package/.server/server/plugins/engine/components/YesNoField.d.ts +5 -2
  114. package/.server/server/plugins/engine/components/YesNoField.js +17 -8
  115. package/.server/server/plugins/engine/components/YesNoField.js.map +1 -1
  116. package/.server/server/plugins/engine/components/helpers/components.js +3 -3
  117. package/.server/server/plugins/engine/components/helpers/components.js.map +1 -1
  118. package/.server/server/plugins/engine/components/helpers/geospatial.d.ts +8 -1
  119. package/.server/server/plugins/engine/components/helpers/geospatial.js +56 -15
  120. package/.server/server/plugins/engine/components/helpers/geospatial.js.map +1 -1
  121. package/.server/server/plugins/engine/components/helpers/index.d.ts +7 -0
  122. package/.server/server/plugins/engine/components/helpers/index.js +13 -1
  123. package/.server/server/plugins/engine/components/helpers/index.js.map +1 -1
  124. package/.server/server/plugins/engine/components/types.d.ts +1 -0
  125. package/.server/server/plugins/engine/components/types.js.map +1 -1
  126. package/.server/server/plugins/engine/errors.d.ts +49 -0
  127. package/.server/server/plugins/engine/errors.js +75 -0
  128. package/.server/server/plugins/engine/errors.js.map +1 -0
  129. package/.server/server/plugins/engine/form-availability.d.ts +3 -2
  130. package/.server/server/plugins/engine/form-availability.js +3 -2
  131. package/.server/server/plugins/engine/form-availability.js.map +1 -1
  132. package/.server/server/plugins/engine/form-context.js +2 -2
  133. package/.server/server/plugins/engine/form-context.js.map +1 -1
  134. package/.server/server/plugins/engine/helpers.d.ts +22 -2
  135. package/.server/server/plugins/engine/helpers.js +44 -5
  136. package/.server/server/plugins/engine/helpers.js.map +1 -1
  137. package/.server/server/plugins/engine/i18n/buildValidationMessages.d.ts +4 -1
  138. package/.server/server/plugins/engine/i18n/buildValidationMessages.js +31 -7
  139. package/.server/server/plugins/engine/i18n/buildValidationMessages.js.map +1 -1
  140. package/.server/server/plugins/engine/i18n/createFormTranslator.d.ts +4 -4
  141. package/.server/server/plugins/engine/i18n/createFormTranslator.js +33 -4
  142. package/.server/server/plugins/engine/i18n/createFormTranslator.js.map +1 -1
  143. package/.server/server/plugins/engine/i18n/extractBaseTranslations.d.ts +1 -1
  144. package/.server/server/plugins/engine/i18n/extractBaseTranslations.js +9 -0
  145. package/.server/server/plugins/engine/i18n/extractBaseTranslations.js.map +1 -1
  146. package/.server/server/plugins/engine/i18n/form.d.ts +13 -0
  147. package/.server/server/plugins/engine/i18n/form.js +35 -0
  148. package/.server/server/plugins/engine/i18n/form.js.map +1 -0
  149. package/.server/server/plugins/engine/i18n/languages.d.ts +10 -0
  150. package/.server/server/plugins/engine/i18n/languages.js +19 -0
  151. package/.server/server/plugins/engine/i18n/languages.js.map +1 -0
  152. package/.server/server/plugins/engine/i18n/translations/cy.json +192 -9
  153. package/.server/server/plugins/engine/i18n/translations/en-GB.json +125 -7
  154. package/.server/server/plugins/engine/i18n/types.d.ts +3 -0
  155. package/.server/server/plugins/engine/i18n/types.js.map +1 -1
  156. package/.server/server/plugins/engine/index.d.ts +4 -0
  157. package/.server/server/plugins/engine/index.js +4 -0
  158. package/.server/server/plugins/engine/index.js.map +1 -1
  159. package/.server/server/plugins/engine/models/FormModel.d.ts +0 -4
  160. package/.server/server/plugins/engine/models/FormModel.js +19 -17
  161. package/.server/server/plugins/engine/models/FormModel.js.map +1 -1
  162. package/.server/server/plugins/engine/models/SummaryViewModel.js +9 -4
  163. package/.server/server/plugins/engine/models/SummaryViewModel.js.map +1 -1
  164. package/.server/server/plugins/engine/models/unavailable-view-model.d.ts +11 -2
  165. package/.server/server/plugins/engine/models/unavailable-view-model.js +23 -4
  166. package/.server/server/plugins/engine/models/unavailable-view-model.js.map +1 -1
  167. package/.server/server/plugins/engine/outputFormatters/adapter/v1.js +3 -5
  168. package/.server/server/plugins/engine/outputFormatters/adapter/v1.js.map +1 -1
  169. package/.server/server/plugins/engine/outputFormatters/human/v1.js +2 -1
  170. package/.server/server/plugins/engine/outputFormatters/human/v1.js.map +1 -1
  171. package/.server/server/plugins/engine/outputFormatters/machine/v2.d.ts +2 -0
  172. package/.server/server/plugins/engine/outputFormatters/machine/v2.js +2 -0
  173. package/.server/server/plugins/engine/outputFormatters/machine/v2.js.map +1 -1
  174. package/.server/server/plugins/engine/pageControllers/FileUploadPageController.d.ts +7 -1
  175. package/.server/server/plugins/engine/pageControllers/FileUploadPageController.js +56 -10
  176. package/.server/server/plugins/engine/pageControllers/FileUploadPageController.js.map +1 -1
  177. package/.server/server/plugins/engine/pageControllers/QuestionPageController.d.ts +1 -1
  178. package/.server/server/plugins/engine/pageControllers/QuestionPageController.js +7 -3
  179. package/.server/server/plugins/engine/pageControllers/QuestionPageController.js.map +1 -1
  180. package/.server/server/plugins/engine/pageControllers/RepeatPageController.js +3 -4
  181. package/.server/server/plugins/engine/pageControllers/RepeatPageController.js.map +1 -1
  182. package/.server/server/plugins/engine/pageControllers/SummaryPageController.js +10 -4
  183. package/.server/server/plugins/engine/pageControllers/SummaryPageController.js.map +1 -1
  184. package/.server/server/plugins/engine/pageControllers/helpers/pages.js +2 -1
  185. package/.server/server/plugins/engine/pageControllers/helpers/pages.js.map +1 -1
  186. package/.server/server/plugins/engine/pageControllers/helpers/submission.d.ts +1 -1
  187. package/.server/server/plugins/engine/pageControllers/helpers/submission.js +3 -3
  188. package/.server/server/plugins/engine/pageControllers/helpers/submission.js.map +1 -1
  189. package/.server/server/plugins/engine/pageControllers/validationOptions.d.ts +1 -1
  190. package/.server/server/plugins/engine/pageControllers/validationOptions.js +24 -3
  191. package/.server/server/plugins/engine/pageControllers/validationOptions.js.map +1 -1
  192. package/.server/server/plugins/engine/types/schema.js +1 -0
  193. package/.server/server/plugins/engine/types/schema.js.map +1 -1
  194. package/.server/server/plugins/engine/types.d.ts +5 -0
  195. package/.server/server/plugins/engine/types.js.map +1 -1
  196. package/.server/server/plugins/engine/unavailable-response.js +5 -2
  197. package/.server/server/plugins/engine/unavailable-response.js.map +1 -1
  198. package/.server/server/plugins/engine/views/components/_location-field-base.html +4 -2
  199. package/.server/server/plugins/engine/views/components/fileuploadfield.html +1 -1
  200. package/.server/server/plugins/engine/views/components/geospatialfield.html +1 -0
  201. package/.server/server/plugins/engine/views/components/multilinetextfield.html +12 -1
  202. package/.server/server/plugins/engine/views/components/osgridreffield.html +4 -1
  203. package/.server/server/plugins/engine/views/components/paymentfield.html +1 -1
  204. package/.server/server/plugins/engine/views/components/ukaddressfield.html +1 -1
  205. package/.server/server/plugins/engine/views/file-upload.html +1 -1
  206. package/.server/server/plugins/engine/views/partials/preview-banner.html +3 -1
  207. package/.server/server/plugins/engine/views/unavailable.html +14 -11
  208. package/.server/server/plugins/nunjucks/filters/applyUrlParam.d.ts +9 -0
  209. package/.server/server/plugins/nunjucks/filters/applyUrlParam.js +17 -0
  210. package/.server/server/plugins/nunjucks/filters/applyUrlParam.js.map +1 -0
  211. package/.server/server/plugins/nunjucks/filters/applyUrlParam.test.js +17 -0
  212. package/.server/server/plugins/nunjucks/filters/applyUrlParam.test.js.map +1 -0
  213. package/.server/server/plugins/nunjucks/filters/field.d.ts +1 -1
  214. package/.server/server/plugins/nunjucks/filters/index.d.ts +1 -0
  215. package/.server/server/plugins/nunjucks/filters/index.js +1 -0
  216. package/.server/server/plugins/nunjucks/filters/index.js.map +1 -1
  217. package/.server/server/plugins/payment/helper.d.ts +11 -1
  218. package/.server/server/plugins/payment/helper.js +18 -2
  219. package/.server/server/plugins/payment/helper.js.map +1 -1
  220. package/.server/server/plugins/payment/helper.test.js +2 -1
  221. package/.server/server/plugins/payment/helper.test.js.map +1 -1
  222. package/.server/server/plugins/payment/service.d.ts +2 -1
  223. package/.server/server/plugins/payment/service.js +5 -2
  224. package/.server/server/plugins/payment/service.js.map +1 -1
  225. package/.server/server/plugins/payment/service.test.js +7 -3
  226. package/.server/server/plugins/payment/service.test.js.map +1 -1
  227. package/.server/server/plugins/payment/types.d.ts +4 -0
  228. package/.server/server/plugins/payment/types.js +1 -0
  229. package/.server/server/plugins/payment/types.js.map +1 -1
  230. package/.server/server/plugins/postcode-lookup/models/index.d.ts +249 -3
  231. package/.server/server/plugins/postcode-lookup/models/index.js +87 -33
  232. package/.server/server/plugins/postcode-lookup/models/index.js.map +1 -1
  233. package/.server/server/plugins/postcode-lookup/routes/index.d.ts +15 -1
  234. package/.server/server/plugins/postcode-lookup/routes/index.js +47 -15
  235. package/.server/server/plugins/postcode-lookup/routes/index.js.map +1 -1
  236. package/.server/server/plugins/postcode-lookup/routes/index.test.js +84 -0
  237. package/.server/server/plugins/postcode-lookup/routes/index.test.js.map +1 -0
  238. package/.server/server/plugins/postcode-lookup/types.d.ts +12 -0
  239. package/.server/server/plugins/postcode-lookup/types.js +6 -1
  240. package/.server/server/plugins/postcode-lookup/types.js.map +1 -1
  241. package/.server/server/plugins/postcode-lookup/views/postcode-lookup-details.html +3 -3
  242. package/.server/server/utils/type-utils.d.ts +1 -2
  243. package/.server/server/utils/type-utils.js +0 -3
  244. package/.server/server/utils/type-utils.js.map +1 -1
  245. package/.server/server/utils/utils.d.ts +6 -0
  246. package/.server/server/utils/utils.js +18 -1
  247. package/.server/server/utils/utils.js.map +1 -1
  248. package/.server/server/utils/utils.test.js +21 -1
  249. package/.server/server/utils/utils.test.js.map +1 -1
  250. package/package.json +20 -5
  251. package/src/client/javascripts/file-upload.js +11 -3
  252. package/src/client/javascripts/geospatial-map.js +176 -81
  253. package/src/client/javascripts/govuk.js +2 -0
  254. package/src/client/javascripts/location-map.js +60 -4
  255. package/src/client/javascripts/map-constants.js +3 -0
  256. package/src/client/javascripts/map.js +47 -0
  257. package/src/client/javascripts/maps.js +5 -0
  258. package/src/client/javascripts/shared.js +1 -4
  259. package/src/client/javascripts/sssi-dataset.js +39 -41
  260. package/src/client/stylesheets/maps.scss +4 -0
  261. package/src/client/stylesheets/shared.scss +1 -5
  262. package/src/server/constants.js +2 -0
  263. package/src/server/plugins/engine/__stubs__/definitions.ts +155 -0
  264. package/src/server/plugins/engine/components/AutocompleteField.ts +13 -0
  265. package/src/server/plugins/engine/components/CheckboxesField.ts +38 -5
  266. package/src/server/plugins/engine/components/ComponentBase.ts +2 -0
  267. package/src/server/plugins/engine/components/ComponentCollection.ts +16 -11
  268. package/src/server/plugins/engine/components/DatePartsField.ts +20 -9
  269. package/src/server/plugins/engine/components/DeclarationField.ts +7 -6
  270. package/src/server/plugins/engine/components/EastingNorthingField.ts +185 -89
  271. package/src/server/plugins/engine/components/EmailAddressField.ts +2 -1
  272. package/src/server/plugins/engine/components/FileUploadField.ts +44 -3
  273. package/src/server/plugins/engine/components/FormComponent.ts +6 -5
  274. package/src/server/plugins/engine/components/GeospatialField.ts +47 -9
  275. package/src/server/plugins/engine/components/LatLongField.ts +128 -58
  276. package/src/server/plugins/engine/components/LocationFieldBase.ts +30 -7
  277. package/src/server/plugins/engine/components/LocationFieldHelpers.ts +28 -14
  278. package/src/server/plugins/engine/components/Markdown.ts +2 -3
  279. package/src/server/plugins/engine/components/MonthYearField.ts +20 -15
  280. package/src/server/plugins/engine/components/NationalGridFieldNumberField.ts +9 -3
  281. package/src/server/plugins/engine/components/NumberField.ts +21 -1
  282. package/src/server/plugins/engine/components/OsGridRefField.ts +22 -3
  283. package/src/server/plugins/engine/components/PaymentField.ts +15 -5
  284. package/src/server/plugins/engine/components/UkAddressField.ts +30 -7
  285. package/src/server/plugins/engine/components/YesNoField.ts +17 -9
  286. package/src/server/plugins/engine/components/helpers/components.ts +3 -3
  287. package/src/server/plugins/engine/components/helpers/geospatial.ts +84 -21
  288. package/src/server/plugins/engine/components/helpers/index.ts +19 -0
  289. package/src/server/plugins/engine/components/types.ts +1 -0
  290. package/src/server/plugins/engine/errors.ts +78 -0
  291. package/src/server/plugins/engine/form-availability.ts +8 -2
  292. package/src/server/plugins/engine/form-context.ts +4 -2
  293. package/src/server/plugins/engine/helpers.ts +52 -5
  294. package/src/server/plugins/engine/i18n/buildValidationMessages.ts +16 -8
  295. package/src/server/plugins/engine/i18n/createFormTranslator.ts +62 -11
  296. package/src/server/plugins/engine/i18n/extractBaseTranslations.ts +7 -1
  297. package/src/server/plugins/engine/i18n/form.ts +54 -0
  298. package/src/server/plugins/engine/i18n/languages.ts +19 -0
  299. package/src/server/plugins/engine/i18n/translations/cy.json +192 -9
  300. package/src/server/plugins/engine/i18n/translations/en-GB.json +125 -7
  301. package/src/server/plugins/engine/i18n/types.ts +3 -0
  302. package/src/server/plugins/engine/index.ts +7 -0
  303. package/src/server/plugins/engine/models/FormModel.ts +21 -17
  304. package/src/server/plugins/engine/models/SummaryViewModel.ts +6 -5
  305. package/src/server/plugins/engine/models/unavailable-view-model.ts +26 -5
  306. package/src/server/plugins/engine/outputFormatters/adapter/v1.ts +3 -6
  307. package/src/server/plugins/engine/outputFormatters/human/v1.ts +2 -1
  308. package/src/server/plugins/engine/outputFormatters/machine/v2.ts +3 -0
  309. package/src/server/plugins/engine/pageControllers/FileUploadPageController.ts +60 -9
  310. package/src/server/plugins/engine/pageControllers/QuestionPageController.ts +10 -5
  311. package/src/server/plugins/engine/pageControllers/RepeatPageController.ts +2 -2
  312. package/src/server/plugins/engine/pageControllers/SummaryPageController.ts +15 -4
  313. package/src/server/plugins/engine/pageControllers/helpers/pages.ts +2 -1
  314. package/src/server/plugins/engine/pageControllers/helpers/submission.ts +6 -3
  315. package/src/server/plugins/engine/pageControllers/validationOptions.ts +29 -4
  316. package/src/server/plugins/engine/types/schema.ts +1 -0
  317. package/src/server/plugins/engine/types.ts +5 -0
  318. package/src/server/plugins/engine/unavailable-response.ts +6 -2
  319. package/src/server/plugins/engine/views/components/_location-field-base.html +4 -2
  320. package/src/server/plugins/engine/views/components/fileuploadfield.html +1 -1
  321. package/src/server/plugins/engine/views/components/geospatialfield.html +1 -0
  322. package/src/server/plugins/engine/views/components/multilinetextfield.html +12 -1
  323. package/src/server/plugins/engine/views/components/osgridreffield.html +4 -1
  324. package/src/server/plugins/engine/views/components/paymentfield.html +1 -1
  325. package/src/server/plugins/engine/views/components/ukaddressfield.html +1 -1
  326. package/src/server/plugins/engine/views/file-upload.html +1 -1
  327. package/src/server/plugins/engine/views/partials/preview-banner.html +3 -1
  328. package/src/server/plugins/engine/views/unavailable.html +14 -11
  329. package/src/server/plugins/nunjucks/filters/applyUrlParam.js +17 -0
  330. package/src/server/plugins/nunjucks/filters/index.js +1 -0
  331. package/src/server/plugins/payment/helper.js +22 -2
  332. package/src/server/plugins/payment/service.js +6 -2
  333. package/src/server/plugins/payment/types.js +1 -0
  334. package/src/server/plugins/postcode-lookup/models/index.js +75 -43
  335. package/src/server/plugins/postcode-lookup/routes/index.js +73 -16
  336. package/src/server/plugins/postcode-lookup/types.js +6 -1
  337. package/src/server/plugins/postcode-lookup/views/postcode-lookup-details.html +3 -3
  338. package/src/server/utils/type-utils.ts +1 -11
  339. package/src/server/utils/utils.js +19 -1
@@ -15,7 +15,11 @@ import {
15
15
  getLocationFieldViewModel
16
16
  } from './LocationFieldHelpers.js'
17
17
  import { NumberField } from './NumberField.js'
18
- import { createLowerFirstExpression } from './helpers/index.js'
18
+ import { getEastingNorthingCountryValidator } from './helpers/geospatial.js'
19
+ import {
20
+ createLowerFirstExpression,
21
+ getTranslatedLabel
22
+ } from './helpers/index.js'
19
23
  import {
20
24
  type EastingNorthingState,
21
25
  type RenderContext
@@ -31,7 +35,6 @@ import {
31
35
  type FormSubmissionError,
32
36
  type FormSubmissionState
33
37
  } from '../types.js'
34
- import { convertToLanguageMessages } from '../../../utils/type-utils.js'
35
38
 
36
39
  // British National Grid coordinate limits
37
40
  const DEFAULT_EASTING_MIN = 0
@@ -55,89 +58,18 @@ export class EastingNorthingField extends FormComponent {
55
58
 
56
59
  const isRequired = options.required !== false
57
60
 
58
- const eastingMin = schema?.easting?.min ?? DEFAULT_EASTING_MIN
59
- const eastingMax = schema?.easting?.max ?? DEFAULT_EASTING_MAX
60
- const northingMin = schema?.northing?.min ?? DEFAULT_NORTHING_MIN
61
- const northingMax = schema?.northing?.max ?? DEFAULT_NORTHING_MAX
62
-
63
- const fieldLabel = lowerFirst(this.label)
61
+ const { eastingMin, eastingMax, northingMin, northingMax } =
62
+ EastingNorthingField.getMinMax(schema)
64
63
 
65
- const eastingDigitsMessage = tPlugin(
66
- 'components.eastingNorthingField.eastingDigits',
67
- 'en-GB',
68
- { fieldLabel }
69
- )
70
- const northingDigitsMessage = tPlugin(
71
- 'components.eastingNorthingField.northingDigits',
72
- 'en-GB',
73
- { fieldLabel }
74
- )
75
-
76
- const customValidationMessages: LanguageMessages =
77
- convertToLanguageMessages({
78
- 'any.required': tPlugin(
79
- 'components.eastingNorthingField.eastingRequired',
80
- 'en-GB'
81
- ),
82
- 'number.base': tPlugin(
83
- 'components.eastingNorthingField.eastingRequired',
84
- 'en-GB'
85
- ),
86
- 'number.min': tPlugin(
87
- 'components.eastingNorthingField.eastingRange',
88
- 'en-GB',
89
- {
90
- fieldLabel,
91
- min: eastingMin,
92
- max: eastingMax
93
- }
94
- ),
95
- 'number.max': tPlugin(
96
- 'components.eastingNorthingField.eastingRange',
97
- 'en-GB',
98
- {
99
- fieldLabel,
100
- min: eastingMin,
101
- max: eastingMax
102
- }
103
- ),
104
- 'number.precision': eastingDigitsMessage,
105
- 'number.integer': eastingDigitsMessage,
106
- 'number.unsafe': eastingDigitsMessage
107
- })
108
-
109
- const northingValidationMessages: LanguageMessages =
110
- convertToLanguageMessages({
111
- 'any.required': tPlugin(
112
- 'components.eastingNorthingField.northingRequired',
113
- 'en-GB'
114
- ),
115
- 'number.base': tPlugin(
116
- 'components.eastingNorthingField.northingRequired',
117
- 'en-GB'
118
- ),
119
- 'number.min': tPlugin(
120
- 'components.eastingNorthingField.northingRange',
121
- 'en-GB',
122
- {
123
- fieldLabel,
124
- min: northingMin,
125
- max: northingMax
126
- }
127
- ),
128
- 'number.max': tPlugin(
129
- 'components.eastingNorthingField.northingRange',
130
- 'en-GB',
131
- {
132
- fieldLabel,
133
- min: northingMin,
134
- max: northingMax
135
- }
136
- ),
137
- 'number.precision': northingDigitsMessage,
138
- 'number.integer': northingDigitsMessage,
139
- 'number.unsafe': northingDigitsMessage
140
- })
64
+ const { eastingValidationMessages, northingValidationMessages } =
65
+ EastingNorthingField.buildErrorMessages(
66
+ this.label,
67
+ eastingMin,
68
+ eastingMax,
69
+ northingMin,
70
+ northingMax,
71
+ 'en-GB'
72
+ )
141
73
 
142
74
  this.collection = new ComponentCollection(
143
75
  [
@@ -154,7 +86,7 @@ export class EastingNorthingField extends FormComponent {
154
86
  required: isRequired,
155
87
  optionalText: true,
156
88
  classes: 'govuk-input--width-10',
157
- customValidationMessages
89
+ customValidationMessages: eastingValidationMessages
158
90
  }
159
91
  },
160
92
  {
@@ -181,6 +113,18 @@ export class EastingNorthingField extends FormComponent {
181
113
  )
182
114
 
183
115
  this.options = options
116
+
117
+ const country = options.countries?.at(0)
118
+
119
+ if (country) {
120
+ this.collection.formSchema = this.collection.formSchema.custom(
121
+ getEastingNorthingCountryValidator(this, country)
122
+ )
123
+ this.collection.stateSchema = this.collection.stateSchema.custom(
124
+ getEastingNorthingCountryValidator(this, country)
125
+ )
126
+ }
127
+
184
128
  this.formSchema = this.collection.formSchema
185
129
  this.stateSchema = this.collection.stateSchema
186
130
  }
@@ -192,14 +136,15 @@ export class EastingNorthingField extends FormComponent {
192
136
 
193
137
  getDisplayStringFromFormValue(
194
138
  value: EastingNorthingState | undefined,
195
- _translator: Translator
139
+ translator: Translator
196
140
  ): string {
197
141
  if (!value) {
198
142
  return ''
199
143
  }
200
144
 
201
- // CYA page format: <<eastingvalue, northingvalue>>
202
- return `${value.easting}, ${value.northing}`
145
+ const { t } = translator
146
+
147
+ return `${t('components.eastingNorthingField.easting')}: ${value.easting}\n${t('components.eastingNorthingField.northing')}: ${value.northing}`
203
148
  }
204
149
 
205
150
  getDisplayStringFromState(
@@ -218,7 +163,7 @@ export class EastingNorthingField extends FormComponent {
218
163
  return null
219
164
  }
220
165
 
221
- return `Easting: ${value.easting}\nNorthing: ${value.northing}`
166
+ return `${value.easting}, ${value.northing}`
222
167
  }
223
168
 
224
169
  getContextValueFromState(state: FormSubmissionState) {
@@ -232,6 +177,24 @@ export class EastingNorthingField extends FormComponent {
232
177
  return getLocationFieldViewModel(this, viewModel, context)
233
178
  }
234
179
 
180
+ getErrors(
181
+ translator: Translator,
182
+ errors?: FormSubmissionError[]
183
+ ): FormSubmissionError[] | undefined {
184
+ const fieldErrors = super.getErrors(translator, errors)
185
+
186
+ fieldErrors?.forEach((err) => {
187
+ if (err.context?.country) {
188
+ err.text = translator.t(
189
+ 'components.eastingNorthingField.wrongCountry',
190
+ { country: translator.t(`common.${err.context.country}`) }
191
+ )
192
+ }
193
+ })
194
+
195
+ return fieldErrors
196
+ }
197
+
235
198
  getViewErrors(
236
199
  translator: Translator,
237
200
  errors?: FormSubmissionError[]
@@ -244,6 +207,26 @@ export class EastingNorthingField extends FormComponent {
244
207
  return EastingNorthingField.isEastingNorthing(value)
245
208
  }
246
209
 
210
+ getValidationMessagesOverride(translator: Translator) {
211
+ const def = this.def as EastingNorthingFieldComponent
212
+ const translatedLabel = getTranslatedLabel(def, translator)
213
+ const { eastingMin, eastingMax, northingMin, northingMax } =
214
+ EastingNorthingField.getMinMax(def.schema)
215
+ const { eastingValidationMessages, northingValidationMessages } =
216
+ EastingNorthingField.buildErrorMessages(
217
+ translatedLabel,
218
+ eastingMin,
219
+ eastingMax,
220
+ northingMin,
221
+ northingMax,
222
+ translator.language
223
+ )
224
+ return {
225
+ [`${this.name}__easting`]: eastingValidationMessages,
226
+ [`${this.name}__northing`]: northingValidationMessages
227
+ }
228
+ }
229
+
247
230
  /**
248
231
  * For error preview page that shows all possible errors on a component
249
232
  */
@@ -309,4 +292,117 @@ export class EastingNorthingField extends FormComponent {
309
292
  NumberField.isNumber(value.northing)
310
293
  )
311
294
  }
295
+
296
+ static buildErrorMessages(
297
+ label: string,
298
+ eastingMin: number,
299
+ eastingMax: number,
300
+ northingMin: number,
301
+ northingMax: number,
302
+ language: string
303
+ ) {
304
+ const fieldLabel = lowerFirst(label)
305
+
306
+ const eastingDigitsMessage = tPlugin(
307
+ 'components.eastingNorthingField.eastingDigits',
308
+ language,
309
+ { fieldLabel }
310
+ )
311
+ const northingDigitsMessage = tPlugin(
312
+ 'components.eastingNorthingField.northingDigits',
313
+ language,
314
+ { fieldLabel }
315
+ )
316
+
317
+ const eastingValidationMessages: LanguageMessages = {
318
+ 'any.required': tPlugin(
319
+ 'components.eastingNorthingField.eastingRequired',
320
+ language
321
+ ),
322
+ 'number.base': tPlugin(
323
+ 'components.eastingNorthingField.eastingRequired',
324
+ language
325
+ ),
326
+ 'number.min': tPlugin(
327
+ 'components.eastingNorthingField.eastingRange',
328
+ language,
329
+ {
330
+ fieldLabel,
331
+ min: eastingMin,
332
+ max: eastingMax
333
+ }
334
+ ),
335
+ 'number.max': tPlugin(
336
+ 'components.eastingNorthingField.eastingRange',
337
+ language,
338
+ {
339
+ fieldLabel,
340
+ min: eastingMin,
341
+ max: eastingMax
342
+ }
343
+ ),
344
+ 'number.precision': eastingDigitsMessage,
345
+ 'number.integer': eastingDigitsMessage,
346
+ 'number.unsafe': eastingDigitsMessage
347
+ }
348
+
349
+ const northingValidationMessages: LanguageMessages = {
350
+ 'any.required': tPlugin(
351
+ 'components.eastingNorthingField.northingRequired',
352
+ language
353
+ ),
354
+ 'number.base': tPlugin(
355
+ 'components.eastingNorthingField.northingRequired',
356
+ language
357
+ ),
358
+ 'number.min': tPlugin(
359
+ 'components.eastingNorthingField.northingRange',
360
+ language,
361
+ {
362
+ fieldLabel,
363
+ min: northingMin,
364
+ max: northingMax
365
+ }
366
+ ),
367
+ 'number.max': tPlugin(
368
+ 'components.eastingNorthingField.northingRange',
369
+ language,
370
+ {
371
+ fieldLabel,
372
+ min: northingMin,
373
+ max: northingMax
374
+ }
375
+ ),
376
+ 'number.precision': northingDigitsMessage,
377
+ 'number.integer': northingDigitsMessage,
378
+ 'number.unsafe': northingDigitsMessage
379
+ }
380
+ return {
381
+ eastingValidationMessages,
382
+ northingValidationMessages
383
+ }
384
+ }
385
+
386
+ // Read schema values from def.schema with fallback defaults
387
+ static getMinMax(
388
+ schema:
389
+ | {
390
+ easting?: {
391
+ min?: number
392
+ max?: number
393
+ }
394
+ northing?: {
395
+ min?: number
396
+ max?: number
397
+ }
398
+ }
399
+ | undefined
400
+ ) {
401
+ return {
402
+ eastingMin: schema?.easting?.min ?? DEFAULT_EASTING_MIN,
403
+ eastingMax: schema?.easting?.max ?? DEFAULT_EASTING_MAX,
404
+ northingMin: schema?.northing?.min ?? DEFAULT_NORTHING_MIN,
405
+ northingMax: schema?.northing?.max ?? DEFAULT_NORTHING_MAX
406
+ }
407
+ }
312
408
  }
@@ -40,7 +40,8 @@ export class EmailAddressField extends FormComponent {
40
40
  formSchema = formSchema.messages({
41
41
  'any.required': message,
42
42
  'string.empty': message,
43
- 'string.email': message
43
+ 'string.email': message,
44
+ 'string.unicode': message
44
45
  })
45
46
  } else if (options.customValidationMessages) {
46
47
  formSchema = formSchema.messages(options.customValidationMessages)
@@ -5,11 +5,13 @@ import {
5
5
  import Boom from '@hapi/boom'
6
6
  import joi, { type ArraySchema } from 'joi'
7
7
 
8
+ import { EN_GB } from '../../../constants.js'
8
9
  import {
9
10
  FormComponent,
10
11
  isUploadState
11
12
  } from './FormComponent.js'
12
13
  import { type RenderContext } from './types.js'
14
+ import { t as tPlugin } from '../i18n/index.js'
13
15
  import { type Translator } from '../i18n/types.js'
14
16
  import { InvalidComponentStateError } from '../pageControllers/errors.js'
15
17
  import { messageTemplate } from '../pageControllers/validationOptions.js'
@@ -50,7 +52,9 @@ export const tempFileSchema = fileSchema.append({
50
52
  .string()
51
53
  .valid(FileStatus.complete, FileStatus.rejected, FileStatus.pending)
52
54
  .required(),
53
- errorMessage: joi.string().optional()
55
+ errorMessage: joi.string().optional(),
56
+ errorCode: joi.string().optional(),
57
+ errorParams: joi.any().optional()
54
58
  })
55
59
 
56
60
  export const formFileSchema = fileSchema.append({
@@ -109,6 +113,7 @@ export class FileUploadField extends FormComponent {
109
113
  declare schema: FileUploadFieldComponent['schema']
110
114
  declare formSchema: ArraySchema<FileState>
111
115
  declare stateSchema: ArraySchema<FileState>
116
+ declare limits: { min?: number; max?: number; length?: number }
112
117
 
113
118
  constructor(
114
119
  def: FileUploadFieldComponent,
@@ -128,20 +133,32 @@ export class FileUploadField extends FormComponent {
128
133
  formSchema = formSchema.optional()
129
134
  }
130
135
 
136
+ const limits: { min?: number; max?: number; length?: number } = {}
137
+
131
138
  if (typeof schema.length !== 'number') {
132
139
  if (typeof schema.max === 'number') {
133
140
  formSchema = formSchema.max(schema.max)
141
+ limits.max = schema.max
134
142
  }
135
143
 
136
144
  if (typeof schema.min === 'number') {
137
145
  formSchema = formSchema.min(schema.min)
146
+ limits.min = schema.min
138
147
  } else if (options.required !== false) {
139
148
  formSchema = formSchema.min(1)
149
+ limits.min = 1
140
150
  }
141
151
  } else {
142
152
  formSchema = formSchema.length(schema.length)
153
+ limits.length = schema.length
143
154
  }
144
155
 
156
+ this.limits = limits
157
+
158
+ formSchema = formSchema.messages(
159
+ FileUploadField.buildErrorMessages(EN_GB, limits)
160
+ )
161
+
145
162
  this.formSchema = formSchema.items(formItemSchema)
146
163
  this.stateSchema = formSchema
147
164
  .items(formItemSchema)
@@ -169,7 +186,7 @@ export class FileUploadField extends FormComponent {
169
186
  return ''
170
187
  }
171
188
 
172
- return translator.t('components.fileUploadField.filesCount', {
189
+ return translator.t('pages.summary.fileUpload', {
173
190
  count: files.length
174
191
  })
175
192
  }
@@ -244,7 +261,7 @@ export class FileUploadField extends FormComponent {
244
261
 
245
262
  items.push({
246
263
  href,
247
- text: 'Remove',
264
+ text: t('pages.fileUpload.remove'),
248
265
  classes: 'govuk-link--no-visited-state',
249
266
  attributes: { id: `${id}__${index}` },
250
267
  visuallyHiddenText: file.filename
@@ -300,6 +317,13 @@ export class FileUploadField extends FormComponent {
300
317
  return isUploadState(value)
301
318
  }
302
319
 
320
+ getValidationMessagesOverride(translator: Translator) {
321
+ const { language } = translator
322
+ return {
323
+ [this.name]: FileUploadField.buildErrorMessages(language, this.limits)
324
+ }
325
+ }
326
+
303
327
  /**
304
328
  * For error preview page that shows all possible errors on a component
305
329
  */
@@ -403,4 +427,21 @@ export class FileUploadField extends FormComponent {
403
427
  ]
404
428
  }
405
429
  }
430
+
431
+ static buildErrorMessages(
432
+ language: string,
433
+ limits: { min?: number; max?: number; length?: number } = {}
434
+ ) {
435
+ return {
436
+ 'array.min': tPlugin('validation.filesMin', language, {
437
+ count: limits.min ?? 1
438
+ }),
439
+ 'array.max': tPlugin('validation.filesMax', language, {
440
+ count: limits.max ?? 1
441
+ }),
442
+ 'array.length': tPlugin('validation.filesLength', language, {
443
+ count: limits.length ?? 1
444
+ })
445
+ }
446
+ }
406
447
  }
@@ -1,5 +1,4 @@
1
1
  import {
2
- type ComponentDef,
3
2
  type FormComponentsDef,
4
3
  type FormMetadata,
5
4
  type Item
@@ -158,10 +157,13 @@ export class FormComponent extends ComponentBase {
158
157
  * Override in composite fields to return translated Joi message overrides for
159
158
  * their sub-fields, applied at validation time so schema-level English messages
160
159
  * are replaced with the correct language. Return null to skip message patching.
160
+ * The return object may contain message overrides at component-level, or sub-field-level.
161
+ * This would allow different error message overrides per field within a collection e.g.
162
+ * for EastingNothingField
161
163
  */
162
164
  getValidationMessagesOverride(
163
165
  _translator: Translator
164
- ): LanguageMessages | null {
166
+ ): Record<string, LanguageMessages> | null {
165
167
  return null
166
168
  }
167
169
 
@@ -178,15 +180,14 @@ export class FormComponent extends ComponentBase {
178
180
  const isRequired = !('required' in options) || options.required !== false
179
181
  const hideOptional = 'optionalText' in options && options.optionalText
180
182
 
181
- const resolvedTitle =
182
- tComponent(this as unknown as ComponentDef, 'title') || title
183
+ const resolvedTitle = tComponent(this.def, 'title') || title
183
184
  const optionalTag =
184
185
  !isRequired && !hideOptional ? ` ${t('common.optional')}` : ''
185
186
  const label = `${resolvedTitle}${optionalTag}`
186
187
 
187
188
  if (hint) {
188
189
  viewModel.hint = {
189
- text: tComponent(this as unknown as ComponentDef, 'hint') || hint
190
+ text: tComponent(this.def, 'hint') || hint
190
191
  }
191
192
  }
192
193
 
@@ -1,14 +1,19 @@
1
1
  import { type GeospatialFieldComponent } from '@defra/forms-model'
2
2
  import { type ArraySchema } from 'joi'
3
3
 
4
+ import { EN_GB } from '../../../constants.js'
4
5
  import { type ComponentBase } from './ComponentBase.js'
5
6
  import {
6
7
  FormComponent,
7
8
  isGeospatialState
8
9
  } from './FormComponent.js'
9
10
  import { getMapLayers } from './LocationFieldHelpers.js'
10
- import { getGeospatialSchema } from './helpers/geospatial.js'
11
+ import {
12
+ determineLimits,
13
+ getGeospatialSchema
14
+ } from './helpers/geospatial.js'
11
15
  import { type RenderContext } from './types.js'
16
+ import { t as tPlugin } from '../i18n/index.js'
12
17
  import { type Translator } from '../i18n/types.js'
13
18
  import { messageTemplate } from '../pageControllers/validationOptions.js'
14
19
  import {
@@ -24,6 +29,7 @@ export class GeospatialField extends FormComponent {
24
29
  declare options: GeospatialFieldComponent['options']
25
30
  declare formSchema: ArraySchema<GeospatialState>
26
31
  declare stateSchema: ArraySchema<GeospatialState>
32
+ declare limits: { min?: number; max?: number; length?: number }
27
33
 
28
34
  constructor(
29
35
  def: GeospatialFieldComponent,
@@ -33,20 +39,24 @@ export class GeospatialField extends FormComponent {
33
39
 
34
40
  const { options } = def
35
41
 
36
- const formSchema = getGeospatialSchema(def).label(this.label).messages({
37
- 'array.min': messageTemplate.featuresMin,
38
- 'array.max': messageTemplate.featuresMax,
39
- 'array.length': messageTemplate.featuresLength
40
- })
42
+ let formSchema = getGeospatialSchema(def).label(this.label)
43
+
44
+ const isOptional = options.required === false
45
+ const limits = determineLimits(def, isOptional)
46
+
47
+ formSchema = formSchema.messages(
48
+ GeospatialField.buildErrorMessages(EN_GB, limits)
49
+ )
41
50
 
42
51
  this.formSchema = formSchema
43
52
  this.stateSchema = formSchema.default(null)
44
53
 
45
- if (options.required === false) {
54
+ if (isOptional) {
46
55
  this.stateSchema = this.stateSchema.allow(null)
47
56
  }
48
57
 
49
58
  this.options = options
59
+ this.limits = limits
50
60
  }
51
61
 
52
62
  getFormValueFromState(state: FormSubmissionState) {
@@ -101,6 +111,7 @@ export class GeospatialField extends FormComponent {
101
111
 
102
112
  return {
103
113
  ...viewModel,
114
+ lang: context.translator.language,
104
115
  country: this.options.countries?.at(0),
105
116
  geometryTypes: this.options.geometryTypes,
106
117
  mapLayers: getMapLayers(this),
@@ -125,7 +136,10 @@ export class GeospatialField extends FormComponent {
125
136
  err.href = `#description_${err.path[1]}`
126
137
  err.text = translator.t(
127
138
  'components.geospatialField.validation.wrongCountry',
128
- { count: Number(err.path[1]) + 1, country: err.context.country }
139
+ {
140
+ count: Number(err.path[1]) + 1,
141
+ country: translator.t(`common.${err.context.country}`)
142
+ }
129
143
  )
130
144
  }
131
145
  })
@@ -144,6 +158,13 @@ export class GeospatialField extends FormComponent {
144
158
  return isGeospatialState(value)
145
159
  }
146
160
 
161
+ getValidationMessagesOverride(translator: Translator) {
162
+ const { language } = translator
163
+ return {
164
+ [this.name]: GeospatialField.buildErrorMessages(language, this.limits)
165
+ }
166
+ }
167
+
147
168
  /**
148
169
  * For error preview page that shows all possible errors on a component
149
170
  */
@@ -164,11 +185,28 @@ export class GeospatialField extends FormComponent {
164
185
  { type: 'required', template: messageTemplate.selectRequired },
165
186
  {
166
187
  type: 'array.min',
167
- template: '{{#title}} must contain at least 1 items'
188
+ template: '{{#title}} must contain at least 1 item'
168
189
  },
169
190
  { type: 'object.invalidjson', template: messageTemplate.format }
170
191
  ],
171
192
  advancedSettingsErrors: []
172
193
  }
173
194
  }
195
+
196
+ static buildErrorMessages(
197
+ language: string,
198
+ limits: { min?: number; max?: number; length?: number } = {}
199
+ ) {
200
+ return {
201
+ 'array.min': tPlugin('validation.featuresMin', language, {
202
+ count: limits.min ?? 1
203
+ }),
204
+ 'array.max': tPlugin('validation.featuresMax', language, {
205
+ count: limits.max ?? 1
206
+ }),
207
+ 'array.length': tPlugin('validation.featuresLength', language, {
208
+ count: limits.length ?? 1
209
+ })
210
+ }
211
+ }
174
212
  }