@defra/forms-engine-plugin 5.0.0-alpha.3 → 5.0.0-alpha.30
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.public/37c964ca545c240f010a.mjs +2 -0
- package/.public/37c964ca545c240f010a.mjs.LICENSE.txt +4 -0
- package/.public/assets-manifest.json +3 -0
- package/.public/javascripts/application.min.js +1 -1
- package/.public/javascripts/application.min.js.LICENSE.txt +7 -0
- package/.public/javascripts/application.min.js.map +1 -1
- package/.public/javascripts/shared.min.js +1 -1
- package/.public/javascripts/shared.min.js.LICENSE.txt +9 -0
- package/.public/javascripts/shared.min.js.map +1 -1
- package/.public/javascripts/vendor/@defra.min.js +1 -1
- package/.public/javascripts/vendor/@defra.min.js.map +1 -1
- package/.public/javascripts/vendor/maplibre-gl.min.js +1 -1
- package/.public/javascripts/vendor/maplibre-gl.min.js.LICENSE.txt +3 -3
- package/.public/javascripts/vendor/maplibre-gl.min.js.map +1 -1
- package/.public/stylesheets/application.min.css +1 -1
- package/.public/stylesheets/application.min.css.map +1 -1
- package/.server/client/javascripts/file-upload.js +6 -3
- package/.server/client/javascripts/file-upload.js.map +1 -1
- package/.server/client/javascripts/geospatial-map.d.ts +159 -5
- package/.server/client/javascripts/geospatial-map.js +161 -81
- package/.server/client/javascripts/geospatial-map.js.map +1 -1
- package/.server/client/javascripts/geospatial-map.test.js +152 -0
- package/.server/client/javascripts/geospatial-map.test.js.map +1 -0
- package/.server/client/javascripts/govuk.js +2 -1
- package/.server/client/javascripts/govuk.js.map +1 -1
- package/.server/client/javascripts/location-map.d.ts +44 -0
- package/.server/client/javascripts/location-map.js +55 -6
- package/.server/client/javascripts/location-map.js.map +1 -1
- package/.server/client/javascripts/map-constants.d.ts +3 -0
- package/.server/client/javascripts/map-constants.js +4 -0
- package/.server/client/javascripts/map-constants.js.map +1 -0
- package/.server/client/javascripts/map.d.ts +17 -4
- package/.server/client/javascripts/map.js +59 -6
- package/.server/client/javascripts/map.js.map +1 -1
- package/.server/client/javascripts/maps.d.ts +5 -0
- package/.server/client/javascripts/maps.js +6 -0
- package/.server/client/javascripts/maps.js.map +1 -0
- package/.server/client/javascripts/shared.d.ts +1 -4
- package/.server/client/javascripts/shared.js +1 -4
- package/.server/client/javascripts/shared.js.map +1 -1
- package/.server/client/javascripts/sssi-dataset.d.ts +18 -20
- package/.server/client/javascripts/sssi-dataset.js +37 -39
- package/.server/client/javascripts/sssi-dataset.js.map +1 -1
- package/.server/client/stylesheets/maps.scss +4 -0
- package/.server/client/stylesheets/shared.scss +1 -5
- package/.server/server/constants.d.ts +2 -0
- package/.server/server/constants.js +2 -0
- package/.server/server/constants.js.map +1 -1
- package/.server/server/forms/components.json +8 -0
- package/.server/server/forms/register-as-a-unicorn-breeder.yaml +4 -0
- package/.server/server/plugins/engine/__stubs__/definitions.d.ts +29 -0
- package/.server/server/plugins/engine/__stubs__/definitions.js +125 -0
- package/.server/server/plugins/engine/__stubs__/definitions.js.map +1 -0
- package/.server/server/plugins/engine/components/AutocompleteField.d.ts +8 -3
- package/.server/server/plugins/engine/components/AutocompleteField.js +17 -0
- package/.server/server/plugins/engine/components/AutocompleteField.js.map +1 -1
- package/.server/server/plugins/engine/components/CheckboxesField.d.ts +23 -2
- package/.server/server/plugins/engine/components/CheckboxesField.js +30 -5
- package/.server/server/plugins/engine/components/CheckboxesField.js.map +1 -1
- package/.server/server/plugins/engine/components/ComponentBase.d.ts +2 -1
- package/.server/server/plugins/engine/components/ComponentBase.js +2 -0
- package/.server/server/plugins/engine/components/ComponentBase.js.map +1 -1
- package/.server/server/plugins/engine/components/ComponentCollection.js +12 -7
- package/.server/server/plugins/engine/components/ComponentCollection.js.map +1 -1
- package/.server/server/plugins/engine/components/DatePartsField.d.ts +6 -3
- package/.server/server/plugins/engine/components/DatePartsField.js +12 -7
- package/.server/server/plugins/engine/components/DatePartsField.js.map +1 -1
- package/.server/server/plugins/engine/components/DeclarationField.d.ts +6 -3
- package/.server/server/plugins/engine/components/DeclarationField.js +6 -4
- package/.server/server/plugins/engine/components/DeclarationField.js.map +1 -1
- package/.server/server/plugins/engine/components/Details.d.ts +1 -0
- package/.server/server/plugins/engine/components/EastingNorthingField.d.ts +33 -2
- package/.server/server/plugins/engine/components/EastingNorthingField.js +110 -54
- package/.server/server/plugins/engine/components/EastingNorthingField.js.map +1 -1
- package/.server/server/plugins/engine/components/EmailAddressField.d.ts +4 -1
- package/.server/server/plugins/engine/components/EmailAddressField.js +2 -1
- package/.server/server/plugins/engine/components/EmailAddressField.js.map +1 -1
- package/.server/server/plugins/engine/components/FileUploadField.d.ts +23 -2
- package/.server/server/plugins/engine/components/FileUploadField.js +35 -3
- package/.server/server/plugins/engine/components/FileUploadField.js.map +1 -1
- package/.server/server/plugins/engine/components/FormComponent.d.ts +5 -1
- package/.server/server/plugins/engine/components/FormComponent.js +5 -2
- package/.server/server/plugins/engine/components/FormComponent.js.map +1 -1
- package/.server/server/plugins/engine/components/GeospatialField.d.ts +23 -0
- package/.server/server/plugins/engine/components/GeospatialField.js +33 -9
- package/.server/server/plugins/engine/components/GeospatialField.js.map +1 -1
- package/.server/server/plugins/engine/components/Html.d.ts +1 -0
- package/.server/server/plugins/engine/components/InsetText.d.ts +1 -0
- package/.server/server/plugins/engine/components/LatLongField.d.ts +32 -2
- package/.server/server/plugins/engine/components/LatLongField.js +85 -48
- package/.server/server/plugins/engine/components/LatLongField.js.map +1 -1
- package/.server/server/plugins/engine/components/List.d.ts +1 -0
- package/.server/server/plugins/engine/components/ListFormComponent.d.ts +3 -2
- package/.server/server/plugins/engine/components/ListFormComponent.js.map +1 -1
- package/.server/server/plugins/engine/components/LocationFieldBase.d.ts +8 -2
- package/.server/server/plugins/engine/components/LocationFieldBase.js +31 -7
- package/.server/server/plugins/engine/components/LocationFieldBase.js.map +1 -1
- package/.server/server/plugins/engine/components/LocationFieldHelpers.d.ts +12 -3
- package/.server/server/plugins/engine/components/LocationFieldHelpers.js +21 -13
- package/.server/server/plugins/engine/components/LocationFieldHelpers.js.map +1 -1
- package/.server/server/plugins/engine/components/Markdown.d.ts +1 -0
- package/.server/server/plugins/engine/components/Markdown.js +1 -1
- package/.server/server/plugins/engine/components/Markdown.js.map +1 -1
- package/.server/server/plugins/engine/components/MonthYearField.d.ts +5 -2
- package/.server/server/plugins/engine/components/MonthYearField.js +13 -9
- package/.server/server/plugins/engine/components/MonthYearField.js.map +1 -1
- package/.server/server/plugins/engine/components/MultilineTextField.d.ts +1 -0
- package/.server/server/plugins/engine/components/NationalGridFieldNumberField.d.ts +2 -1
- package/.server/server/plugins/engine/components/NationalGridFieldNumberField.js +4 -3
- package/.server/server/plugins/engine/components/NationalGridFieldNumberField.js.map +1 -1
- package/.server/server/plugins/engine/components/NotificationBanner.d.ts +1 -0
- package/.server/server/plugins/engine/components/NumberField.d.ts +5 -0
- package/.server/server/plugins/engine/components/NumberField.js +22 -0
- package/.server/server/plugins/engine/components/NumberField.js.map +1 -1
- package/.server/server/plugins/engine/components/OsGridRefField.d.ts +103 -1
- package/.server/server/plugins/engine/components/OsGridRefField.js +13 -3
- package/.server/server/plugins/engine/components/OsGridRefField.js.map +1 -1
- package/.server/server/plugins/engine/components/PaymentField.d.ts +2 -0
- package/.server/server/plugins/engine/components/PaymentField.js +9 -5
- package/.server/server/plugins/engine/components/PaymentField.js.map +1 -1
- package/.server/server/plugins/engine/components/SelectField.d.ts +1 -0
- package/.server/server/plugins/engine/components/SelectionControlField.d.ts +1 -0
- package/.server/server/plugins/engine/components/TelephoneNumberField.d.ts +1 -0
- package/.server/server/plugins/engine/components/TrackingField.d.ts +21 -0
- package/.server/server/plugins/engine/components/TrackingField.js +46 -0
- package/.server/server/plugins/engine/components/TrackingField.js.map +1 -0
- package/.server/server/plugins/engine/components/UkAddressField.d.ts +1 -0
- package/.server/server/plugins/engine/components/UkAddressField.js +23 -8
- package/.server/server/plugins/engine/components/UkAddressField.js.map +1 -1
- package/.server/server/plugins/engine/components/YesNoField.d.ts +3 -2
- package/.server/server/plugins/engine/components/YesNoField.js +22 -8
- package/.server/server/plugins/engine/components/YesNoField.js.map +1 -1
- package/.server/server/plugins/engine/components/helpers/components.d.ts +1 -1
- package/.server/server/plugins/engine/components/helpers/components.js +6 -3
- package/.server/server/plugins/engine/components/helpers/components.js.map +1 -1
- package/.server/server/plugins/engine/components/helpers/geospatial.d.ts +8 -1
- package/.server/server/plugins/engine/components/helpers/geospatial.js +58 -17
- package/.server/server/plugins/engine/components/helpers/geospatial.js.map +1 -1
- package/.server/server/plugins/engine/components/helpers/index.d.ts +21 -1
- package/.server/server/plugins/engine/components/helpers/index.js +45 -1
- package/.server/server/plugins/engine/components/helpers/index.js.map +1 -1
- package/.server/server/plugins/engine/components/index.d.ts +1 -0
- package/.server/server/plugins/engine/components/index.js +1 -0
- package/.server/server/plugins/engine/components/index.js.map +1 -1
- package/.server/server/plugins/engine/components/types.d.ts +1 -0
- package/.server/server/plugins/engine/components/types.js.map +1 -1
- package/.server/server/plugins/engine/errors.d.ts +49 -0
- package/.server/server/plugins/engine/errors.js +75 -0
- package/.server/server/plugins/engine/errors.js.map +1 -0
- package/.server/server/plugins/engine/form-availability.d.ts +3 -2
- package/.server/server/plugins/engine/form-availability.js +3 -2
- package/.server/server/plugins/engine/form-availability.js.map +1 -1
- package/.server/server/plugins/engine/form-context.js +2 -2
- package/.server/server/plugins/engine/form-context.js.map +1 -1
- package/.server/server/plugins/engine/helpers.d.ts +23 -2
- package/.server/server/plugins/engine/helpers.js +44 -5
- package/.server/server/plugins/engine/helpers.js.map +1 -1
- package/.server/server/plugins/engine/i18n/buildValidationMessages.d.ts +4 -1
- package/.server/server/plugins/engine/i18n/buildValidationMessages.js +31 -7
- package/.server/server/plugins/engine/i18n/buildValidationMessages.js.map +1 -1
- package/.server/server/plugins/engine/i18n/createFormTranslator.d.ts +4 -4
- package/.server/server/plugins/engine/i18n/createFormTranslator.js +27 -5
- package/.server/server/plugins/engine/i18n/createFormTranslator.js.map +1 -1
- package/.server/server/plugins/engine/i18n/extractBaseTranslations.d.ts +1 -1
- package/.server/server/plugins/engine/i18n/extractBaseTranslations.js +9 -0
- package/.server/server/plugins/engine/i18n/extractBaseTranslations.js.map +1 -1
- package/.server/server/plugins/engine/i18n/form.d.ts +13 -0
- package/.server/server/plugins/engine/i18n/form.js +35 -0
- package/.server/server/plugins/engine/i18n/form.js.map +1 -0
- package/.server/server/plugins/engine/i18n/languages.d.ts +10 -0
- package/.server/server/plugins/engine/i18n/languages.js +19 -0
- package/.server/server/plugins/engine/i18n/languages.js.map +1 -0
- package/.server/server/plugins/engine/i18n/translations/cy.json +176 -7
- package/.server/server/plugins/engine/i18n/translations/en-GB.json +110 -6
- package/.server/server/plugins/engine/i18n/types.d.ts +2 -0
- package/.server/server/plugins/engine/i18n/types.js.map +1 -1
- package/.server/server/plugins/engine/index.d.ts +4 -0
- package/.server/server/plugins/engine/index.js +4 -0
- package/.server/server/plugins/engine/index.js.map +1 -1
- package/.server/server/plugins/engine/models/FormModel.d.ts +0 -4
- package/.server/server/plugins/engine/models/FormModel.js +35 -23
- package/.server/server/plugins/engine/models/FormModel.js.map +1 -1
- package/.server/server/plugins/engine/models/SummaryViewModel.js +9 -4
- package/.server/server/plugins/engine/models/SummaryViewModel.js.map +1 -1
- package/.server/server/plugins/engine/models/types.d.ts +28 -1
- package/.server/server/plugins/engine/models/types.js.map +1 -1
- package/.server/server/plugins/engine/models/unavailable-view-model.d.ts +11 -2
- package/.server/server/plugins/engine/models/unavailable-view-model.js +23 -4
- package/.server/server/plugins/engine/models/unavailable-view-model.js.map +1 -1
- package/.server/server/plugins/engine/options.js +2 -1
- package/.server/server/plugins/engine/options.js.map +1 -1
- package/.server/server/plugins/engine/outputFormatters/adapter/v1.js +14 -6
- package/.server/server/plugins/engine/outputFormatters/adapter/v1.js.map +1 -1
- package/.server/server/plugins/engine/outputFormatters/human/v1.js +2 -1
- package/.server/server/plugins/engine/outputFormatters/human/v1.js.map +1 -1
- package/.server/server/plugins/engine/outputFormatters/machine/v2.d.ts +2 -0
- package/.server/server/plugins/engine/outputFormatters/machine/v2.js +2 -0
- package/.server/server/plugins/engine/outputFormatters/machine/v2.js.map +1 -1
- package/.server/server/plugins/engine/pageControllers/FileUploadPageController.d.ts +7 -1
- package/.server/server/plugins/engine/pageControllers/FileUploadPageController.js +56 -10
- package/.server/server/plugins/engine/pageControllers/FileUploadPageController.js.map +1 -1
- package/.server/server/plugins/engine/pageControllers/QuestionPageController.d.ts +1 -1
- package/.server/server/plugins/engine/pageControllers/QuestionPageController.js +2 -2
- package/.server/server/plugins/engine/pageControllers/QuestionPageController.js.map +1 -1
- package/.server/server/plugins/engine/pageControllers/RepeatPageController.js +3 -4
- package/.server/server/plugins/engine/pageControllers/RepeatPageController.js.map +1 -1
- package/.server/server/plugins/engine/pageControllers/SummaryPageController.js +10 -4
- package/.server/server/plugins/engine/pageControllers/SummaryPageController.js.map +1 -1
- package/.server/server/plugins/engine/pageControllers/helpers/pages.js +2 -1
- package/.server/server/plugins/engine/pageControllers/helpers/pages.js.map +1 -1
- package/.server/server/plugins/engine/pageControllers/helpers/submission.d.ts +35 -2
- package/.server/server/plugins/engine/pageControllers/helpers/submission.js +100 -3
- package/.server/server/plugins/engine/pageControllers/helpers/submission.js.map +1 -1
- package/.server/server/plugins/engine/pageControllers/validationOptions.d.ts +1 -1
- package/.server/server/plugins/engine/pageControllers/validationOptions.js +24 -3
- package/.server/server/plugins/engine/pageControllers/validationOptions.js.map +1 -1
- package/.server/server/plugins/engine/plugin.js +3 -0
- package/.server/server/plugins/engine/plugin.js.map +1 -1
- package/.server/server/plugins/engine/referenceNumbers.d.ts +1 -0
- package/.server/server/plugins/engine/referenceNumbers.js +1 -0
- package/.server/server/plugins/engine/referenceNumbers.js.map +1 -1
- package/.server/server/plugins/engine/routes/index.js +9 -4
- package/.server/server/plugins/engine/routes/index.js.map +1 -1
- package/.server/server/plugins/engine/types/enums.d.ts +3 -3
- package/.server/server/plugins/engine/types/enums.js +5 -4
- package/.server/server/plugins/engine/types/enums.js.map +1 -1
- package/.server/server/plugins/engine/types/schema.js +15 -4
- package/.server/server/plugins/engine/types/schema.js.map +1 -1
- package/.server/server/plugins/engine/types.d.ts +24 -2
- package/.server/server/plugins/engine/types.js.map +1 -1
- package/.server/server/plugins/engine/unavailable-response.js +5 -2
- package/.server/server/plugins/engine/unavailable-response.js.map +1 -1
- package/.server/server/plugins/engine/views/components/_location-field-base.html +4 -2
- package/.server/server/plugins/engine/views/components/fileuploadfield.html +1 -1
- package/.server/server/plugins/engine/views/components/geospatialfield.html +1 -0
- package/.server/server/plugins/engine/views/components/osgridreffield.html +4 -1
- package/.server/server/plugins/engine/views/components/trackingfield.html +3 -0
- package/.server/server/plugins/engine/views/components/ukaddressfield.html +1 -1
- package/.server/server/plugins/engine/views/file-upload.html +1 -1
- package/.server/server/plugins/engine/views/summary.html +1 -0
- package/.server/server/plugins/engine/views/unavailable.html +14 -11
- package/.server/server/plugins/map/routes/index.d.ts +4 -0
- package/.server/server/plugins/map/routes/index.js +12 -4
- package/.server/server/plugins/map/routes/index.js.map +1 -1
- package/.server/server/plugins/map/routes/index.test.js +7 -0
- package/.server/server/plugins/map/routes/index.test.js.map +1 -0
- package/.server/server/plugins/map/routes/vts/README.md +38 -0
- package/.server/server/plugins/map/routes/vts/countries-5dp.geojson +4 -0
- package/.server/server/plugins/map/routes/vts/countries.geojson +10 -39283
- package/.server/server/plugins/map/types.d.ts +24 -2
- package/.server/server/plugins/map/types.js +9 -2
- package/.server/server/plugins/map/types.js.map +1 -1
- package/.server/server/plugins/nunjucks/enviroment.test.js +11 -4
- package/.server/server/plugins/nunjucks/enviroment.test.js.map +1 -1
- package/.server/server/plugins/nunjucks/filters/applyUrlParam.d.ts +9 -0
- package/.server/server/plugins/nunjucks/filters/applyUrlParam.js +17 -0
- package/.server/server/plugins/nunjucks/filters/applyUrlParam.js.map +1 -0
- package/.server/server/plugins/nunjucks/filters/applyUrlParam.test.js +17 -0
- package/.server/server/plugins/nunjucks/filters/applyUrlParam.test.js.map +1 -0
- package/.server/server/plugins/nunjucks/filters/field.d.ts +1 -1
- package/.server/server/plugins/nunjucks/filters/index.d.ts +1 -0
- package/.server/server/plugins/nunjucks/filters/index.js +1 -0
- package/.server/server/plugins/nunjucks/filters/index.js.map +1 -1
- package/.server/server/plugins/payment/helper.d.ts +11 -1
- package/.server/server/plugins/payment/helper.js +18 -2
- package/.server/server/plugins/payment/helper.js.map +1 -1
- package/.server/server/plugins/payment/helper.test.js +2 -1
- package/.server/server/plugins/payment/helper.test.js.map +1 -1
- package/.server/server/plugins/payment/service.d.ts +2 -1
- package/.server/server/plugins/payment/service.js +5 -2
- package/.server/server/plugins/payment/service.js.map +1 -1
- package/.server/server/plugins/payment/service.test.js +7 -3
- package/.server/server/plugins/payment/service.test.js.map +1 -1
- package/.server/server/plugins/payment/types.d.ts +4 -0
- package/.server/server/plugins/payment/types.js +1 -0
- package/.server/server/plugins/payment/types.js.map +1 -1
- package/.server/server/plugins/postcode-lookup/models/index.d.ts +249 -3
- package/.server/server/plugins/postcode-lookup/models/index.js +103 -36
- package/.server/server/plugins/postcode-lookup/models/index.js.map +1 -1
- package/.server/server/plugins/postcode-lookup/routes/index.d.ts +15 -1
- package/.server/server/plugins/postcode-lookup/routes/index.js +64 -18
- package/.server/server/plugins/postcode-lookup/routes/index.js.map +1 -1
- package/.server/server/plugins/postcode-lookup/routes/index.test.js +84 -0
- package/.server/server/plugins/postcode-lookup/routes/index.test.js.map +1 -0
- package/.server/server/plugins/postcode-lookup/types.d.ts +12 -0
- package/.server/server/plugins/postcode-lookup/types.js +6 -1
- package/.server/server/plugins/postcode-lookup/types.js.map +1 -1
- package/.server/server/plugins/postcode-lookup/views/postcode-lookup-details.html +3 -3
- package/.server/server/utils/type-utils.d.ts +1 -2
- package/.server/server/utils/type-utils.js +0 -3
- package/.server/server/utils/type-utils.js.map +1 -1
- package/.server/server/utils/utils.d.ts +6 -0
- package/.server/server/utils/utils.js +18 -1
- package/.server/server/utils/utils.js.map +1 -1
- package/.server/server/utils/utils.test.js +21 -1
- package/.server/server/utils/utils.test.js.map +1 -1
- package/.server/typings/geodesy/index.d.js +2 -0
- package/.server/typings/geodesy/index.d.js.map +1 -0
- package/.server/typings/hapi/index.d.js.map +1 -1
- package/package.json +24 -9
- package/src/client/javascripts/file-upload.js +11 -3
- package/src/client/javascripts/geospatial-map.js +181 -86
- package/src/client/javascripts/govuk.js +2 -0
- package/src/client/javascripts/location-map.js +62 -6
- package/src/client/javascripts/map-constants.js +3 -0
- package/src/client/javascripts/map.js +66 -9
- package/src/client/javascripts/maps.js +5 -0
- package/src/client/javascripts/shared.js +1 -4
- package/src/client/javascripts/sssi-dataset.js +39 -41
- package/src/client/stylesheets/maps.scss +4 -0
- package/src/client/stylesheets/shared.scss +1 -5
- package/src/server/constants.js +2 -0
- package/src/server/forms/components.json +8 -0
- package/src/server/forms/register-as-a-unicorn-breeder.yaml +4 -0
- package/src/server/plugins/engine/__stubs__/definitions.ts +155 -0
- package/src/server/plugins/engine/components/AutocompleteField.ts +20 -0
- package/src/server/plugins/engine/components/CheckboxesField.ts +41 -8
- package/src/server/plugins/engine/components/ComponentBase.ts +6 -4
- package/src/server/plugins/engine/components/ComponentCollection.ts +17 -15
- package/src/server/plugins/engine/components/DatePartsField.ts +20 -9
- package/src/server/plugins/engine/components/DeclarationField.ts +10 -10
- package/src/server/plugins/engine/components/EastingNorthingField.ts +185 -89
- package/src/server/plugins/engine/components/EmailAddressField.ts +2 -1
- package/src/server/plugins/engine/components/FileUploadField.ts +46 -5
- package/src/server/plugins/engine/components/FormComponent.ts +6 -5
- package/src/server/plugins/engine/components/GeospatialField.ts +47 -9
- package/src/server/plugins/engine/components/LatLongField.ts +128 -58
- package/src/server/plugins/engine/components/ListFormComponent.ts +4 -4
- package/src/server/plugins/engine/components/LocationFieldBase.ts +41 -8
- package/src/server/plugins/engine/components/LocationFieldHelpers.ts +28 -14
- package/src/server/plugins/engine/components/Markdown.ts +2 -3
- package/src/server/plugins/engine/components/MonthYearField.ts +20 -15
- package/src/server/plugins/engine/components/NationalGridFieldNumberField.ts +9 -3
- package/src/server/plugins/engine/components/NumberField.ts +24 -0
- package/src/server/plugins/engine/components/OsGridRefField.ts +22 -3
- package/src/server/plugins/engine/components/PaymentField.ts +9 -4
- package/src/server/plugins/engine/components/TrackingField.ts +64 -0
- package/src/server/plugins/engine/components/UkAddressField.ts +30 -7
- package/src/server/plugins/engine/components/YesNoField.ts +27 -9
- package/src/server/plugins/engine/components/helpers/components.ts +8 -3
- package/src/server/plugins/engine/components/helpers/geospatial.ts +87 -24
- package/src/server/plugins/engine/components/helpers/index.ts +64 -1
- package/src/server/plugins/engine/components/index.ts +1 -0
- package/src/server/plugins/engine/components/types.ts +1 -0
- package/src/server/plugins/engine/errors.ts +78 -0
- package/src/server/plugins/engine/form-availability.ts +8 -2
- package/src/server/plugins/engine/form-context.ts +4 -2
- package/src/server/plugins/engine/helpers.ts +52 -5
- package/src/server/plugins/engine/i18n/buildValidationMessages.ts +16 -8
- package/src/server/plugins/engine/i18n/createFormTranslator.ts +43 -12
- package/src/server/plugins/engine/i18n/extractBaseTranslations.ts +7 -1
- package/src/server/plugins/engine/i18n/form.ts +54 -0
- package/src/server/plugins/engine/i18n/languages.ts +19 -0
- package/src/server/plugins/engine/i18n/translations/cy.json +176 -7
- package/src/server/plugins/engine/i18n/translations/en-GB.json +110 -6
- package/src/server/plugins/engine/i18n/types.ts +2 -0
- package/src/server/plugins/engine/index.ts +7 -0
- package/src/server/plugins/engine/models/FormModel.ts +46 -23
- package/src/server/plugins/engine/models/SummaryViewModel.ts +6 -5
- package/src/server/plugins/engine/models/types.ts +31 -0
- package/src/server/plugins/engine/models/unavailable-view-model.ts +26 -5
- package/src/server/plugins/engine/options.js +2 -1
- package/src/server/plugins/engine/outputFormatters/adapter/v1.ts +18 -7
- package/src/server/plugins/engine/outputFormatters/human/v1.ts +2 -1
- package/src/server/plugins/engine/outputFormatters/machine/v2.ts +3 -0
- package/src/server/plugins/engine/pageControllers/FileUploadPageController.ts +60 -9
- package/src/server/plugins/engine/pageControllers/QuestionPageController.ts +2 -2
- package/src/server/plugins/engine/pageControllers/RepeatPageController.ts +2 -2
- package/src/server/plugins/engine/pageControllers/SummaryPageController.ts +15 -4
- package/src/server/plugins/engine/pageControllers/helpers/pages.ts +2 -1
- package/src/server/plugins/engine/pageControllers/helpers/submission.ts +143 -4
- package/src/server/plugins/engine/pageControllers/validationOptions.ts +29 -4
- package/src/server/plugins/engine/plugin.ts +6 -0
- package/src/server/plugins/engine/referenceNumbers.ts +2 -0
- package/src/server/plugins/engine/routes/index.ts +9 -3
- package/src/server/plugins/engine/types/enums.ts +4 -3
- package/src/server/plugins/engine/types/schema.ts +22 -5
- package/src/server/plugins/engine/types.ts +28 -1
- package/src/server/plugins/engine/unavailable-response.ts +6 -2
- package/src/server/plugins/engine/views/components/_location-field-base.html +4 -2
- package/src/server/plugins/engine/views/components/fileuploadfield.html +1 -1
- package/src/server/plugins/engine/views/components/geospatialfield.html +1 -0
- package/src/server/plugins/engine/views/components/osgridreffield.html +4 -1
- package/src/server/plugins/engine/views/components/trackingfield.html +3 -0
- package/src/server/plugins/engine/views/components/ukaddressfield.html +1 -1
- package/src/server/plugins/engine/views/file-upload.html +1 -1
- package/src/server/plugins/engine/views/summary.html +1 -0
- package/src/server/plugins/engine/views/unavailable.html +14 -11
- package/src/server/plugins/map/routes/index.js +29 -4
- package/src/server/plugins/map/routes/vts/README.md +38 -0
- package/src/server/plugins/map/routes/vts/countries-5dp.geojson +4 -0
- package/src/server/plugins/map/routes/vts/countries.geojson +10 -39283
- package/src/server/plugins/map/types.js +9 -2
- package/src/server/plugins/nunjucks/filters/applyUrlParam.js +17 -0
- package/src/server/plugins/nunjucks/filters/index.js +1 -0
- package/src/server/plugins/payment/helper.js +22 -2
- package/src/server/plugins/payment/service.js +6 -2
- package/src/server/plugins/payment/types.js +1 -0
- package/src/server/plugins/postcode-lookup/models/index.js +91 -46
- package/src/server/plugins/postcode-lookup/routes/index.js +96 -24
- package/src/server/plugins/postcode-lookup/types.js +6 -1
- package/src/server/plugins/postcode-lookup/views/postcode-lookup-details.html +3 -3
- package/src/server/utils/type-utils.ts +1 -11
- package/src/server/utils/utils.js +19 -1
- package/src/typings/geodesy/index.d.ts +18 -0
- package/src/typings/hapi/index.d.ts +2 -0
|
@@ -1,8 +1,18 @@
|
|
|
1
|
+
import { EN_GB } from "../../../constants.js";
|
|
1
2
|
import { LocationFieldBase } from "./LocationFieldBase.js";
|
|
3
|
+
import { getMapLayers } from "./LocationFieldHelpers.js";
|
|
2
4
|
import { createLowerFirstExpression } from "./helpers/index.js";
|
|
3
5
|
import { t } from "../i18n/index.js";
|
|
4
6
|
export class OsGridRefField extends LocationFieldBase {
|
|
5
|
-
|
|
7
|
+
getViewModel(context) {
|
|
8
|
+
const viewModel = super.getViewModel(context);
|
|
9
|
+
Object.assign(viewModel, {
|
|
10
|
+
lang: context.translator.language,
|
|
11
|
+
mapLayers: getMapLayers(this)
|
|
12
|
+
});
|
|
13
|
+
return viewModel;
|
|
14
|
+
}
|
|
15
|
+
getValidationConfig(translator) {
|
|
6
16
|
// Regex for OS national grid references (NGR)
|
|
7
17
|
// Validates specific valid OS grid letter combinations with:
|
|
8
18
|
// - 2 letters & 6 digits in 2 blocks of 3 e.g. ST 678 678
|
|
@@ -12,8 +22,8 @@ export class OsGridRefField extends LocationFieldBase {
|
|
|
12
22
|
const pattern = /^((([sS]|[nN])[a-hA-Hj-zJ-Z])|(([tT]|[oO])[abfglmqrvwABFGLMQRVW])|([hH][l-zL-Z])|([jJ][lmqrvwLMQRVW]))\s?(([0-9]{3})\s?([0-9]{3})|([0-9]{4})\s?([0-9]{4})|([0-9]{5})\s?([0-9]{5}))$/;
|
|
13
23
|
return {
|
|
14
24
|
pattern,
|
|
15
|
-
patternErrorMessage: createLowerFirstExpression(t('components.osGridRefField.pattern'
|
|
16
|
-
requiredMessage: createLowerFirstExpression(t('components.osGridRefField.required'
|
|
25
|
+
patternErrorMessage: createLowerFirstExpression(translator ? translator.t('components.osGridRefField.pattern') : t('components.osGridRefField.pattern', EN_GB)),
|
|
26
|
+
requiredMessage: createLowerFirstExpression(translator ? translator.t('components.osGridRefField.required') : t('components.osGridRefField.required', EN_GB))
|
|
17
27
|
};
|
|
18
28
|
}
|
|
19
29
|
getErrorTemplates() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OsGridRefField.js","names":["LocationFieldBase","createLowerFirstExpression","t","OsGridRefField","getValidationConfig","pattern","patternErrorMessage","requiredMessage","getErrorTemplates","type","template","getAllPossibleErrors","baseErrors","advancedSettingsErrors"],"sources":["../../../../../src/server/plugins/engine/components/OsGridRefField.ts"],"sourcesContent":["import { type OsGridRefFieldComponent } from '@defra/forms-model'\n\nimport { LocationFieldBase } from '~/src/server/plugins/engine/components/LocationFieldBase.js'\nimport { createLowerFirstExpression } from '~/src/server/plugins/engine/components/helpers/index.js'\nimport { t } from '~/src/server/plugins/engine/i18n/index.js'\nimport { type ErrorMessageTemplateList } from '~/src/server/plugins/engine/types.js'\n\nexport class OsGridRefField extends LocationFieldBase {\n declare options: OsGridRefFieldComponent['options']\n\n protected getValidationConfig() {\n // Regex for OS national grid references (NGR)\n // Validates specific valid OS grid letter combinations with:\n // - 2 letters & 6 digits in 2 blocks of 3 e.g. ST 678 678\n // - 2 letters & 8 digits in 2 blocks of 4 e.g. ST 6789 6789\n // - 2 letters & 10 digits in 2 blocks of 5 e.g. SO 12345 12345\n // Optional spaces between each block\n const pattern =\n /^((([sS]|[nN])[a-hA-Hj-zJ-Z])|(([tT]|[oO])[abfglmqrvwABFGLMQRVW])|([hH][l-zL-Z])|([jJ][lmqrvwLMQRVW]))\\s?(([0-9]{3})\\s?([0-9]{3})|([0-9]{4})\\s?([0-9]{4})|([0-9]{5})\\s?([0-9]{5}))$/\n\n return {\n pattern,\n patternErrorMessage: createLowerFirstExpression(\n t('components.osGridRefField.pattern'
|
|
1
|
+
{"version":3,"file":"OsGridRefField.js","names":["EN_GB","LocationFieldBase","getMapLayers","createLowerFirstExpression","t","OsGridRefField","getViewModel","context","viewModel","Object","assign","lang","translator","language","mapLayers","getValidationConfig","pattern","patternErrorMessage","requiredMessage","getErrorTemplates","type","template","getAllPossibleErrors","baseErrors","advancedSettingsErrors"],"sources":["../../../../../src/server/plugins/engine/components/OsGridRefField.ts"],"sourcesContent":["import { type OsGridRefFieldComponent } from '@defra/forms-model'\n\nimport { EN_GB } from '~/src/server/constants.js'\nimport { LocationFieldBase } from '~/src/server/plugins/engine/components/LocationFieldBase.js'\nimport { getMapLayers } from '~/src/server/plugins/engine/components/LocationFieldHelpers.js'\nimport { createLowerFirstExpression } from '~/src/server/plugins/engine/components/helpers/index.js'\nimport { type RenderContext } from '~/src/server/plugins/engine/components/types.js'\nimport { t } from '~/src/server/plugins/engine/i18n/index.js'\nimport { type Translator } from '~/src/server/plugins/engine/types/index.js'\nimport { type ErrorMessageTemplateList } from '~/src/server/plugins/engine/types.js'\n\nexport class OsGridRefField extends LocationFieldBase {\n declare options: OsGridRefFieldComponent['options']\n\n getViewModel(context: RenderContext) {\n const viewModel = super.getViewModel(context)\n\n Object.assign(viewModel, {\n lang: context.translator.language,\n mapLayers: getMapLayers(this)\n })\n\n return viewModel\n }\n\n protected getValidationConfig(translator: Translator | undefined) {\n // Regex for OS national grid references (NGR)\n // Validates specific valid OS grid letter combinations with:\n // - 2 letters & 6 digits in 2 blocks of 3 e.g. ST 678 678\n // - 2 letters & 8 digits in 2 blocks of 4 e.g. ST 6789 6789\n // - 2 letters & 10 digits in 2 blocks of 5 e.g. SO 12345 12345\n // Optional spaces between each block\n const pattern =\n /^((([sS]|[nN])[a-hA-Hj-zJ-Z])|(([tT]|[oO])[abfglmqrvwABFGLMQRVW])|([hH][l-zL-Z])|([jJ][lmqrvwLMQRVW]))\\s?(([0-9]{3})\\s?([0-9]{3})|([0-9]{4})\\s?([0-9]{4})|([0-9]{5})\\s?([0-9]{5}))$/\n\n return {\n pattern,\n patternErrorMessage: createLowerFirstExpression(\n translator\n ? translator.t('components.osGridRefField.pattern')\n : t('components.osGridRefField.pattern', EN_GB)\n ),\n requiredMessage: createLowerFirstExpression(\n translator\n ? translator.t('components.osGridRefField.required')\n : t('components.osGridRefField.required', EN_GB)\n )\n }\n }\n\n protected getErrorTemplates() {\n return [\n {\n type: 'pattern',\n template: createLowerFirstExpression(\n t('components.osGridRefField.pattern', 'en-GB')\n )\n }\n ]\n }\n\n /**\n * Static version of getAllPossibleErrors that doesn't require a component instance.\n */\n static getAllPossibleErrors(): ErrorMessageTemplateList {\n return {\n baseErrors: [\n {\n type: 'required',\n template: createLowerFirstExpression(\n t('components.osGridRefField.required', 'en-GB')\n )\n },\n {\n type: 'pattern',\n template: createLowerFirstExpression(\n t('components.osGridRefField.pattern', 'en-GB')\n )\n }\n ],\n advancedSettingsErrors: []\n }\n }\n}\n"],"mappings":"AAEA,SAASA,KAAK;AACd,SAASC,iBAAiB;AAC1B,SAASC,YAAY;AACrB,SAASC,0BAA0B;AAEnC,SAASC,CAAC;AAIV,OAAO,MAAMC,cAAc,SAASJ,iBAAiB,CAAC;EAGpDK,YAAYA,CAACC,OAAsB,EAAE;IACnC,MAAMC,SAAS,GAAG,KAAK,CAACF,YAAY,CAACC,OAAO,CAAC;IAE7CE,MAAM,CAACC,MAAM,CAACF,SAAS,EAAE;MACvBG,IAAI,EAAEJ,OAAO,CAACK,UAAU,CAACC,QAAQ;MACjCC,SAAS,EAAEZ,YAAY,CAAC,IAAI;IAC9B,CAAC,CAAC;IAEF,OAAOM,SAAS;EAClB;EAEUO,mBAAmBA,CAACH,UAAkC,EAAE;IAChE;IACA;IACA;IACA;IACA;IACA;IACA,MAAMI,OAAO,GACX,qLAAqL;IAEvL,OAAO;MACLA,OAAO;MACPC,mBAAmB,EAAEd,0BAA0B,CAC7CS,UAAU,GACNA,UAAU,CAACR,CAAC,CAAC,mCAAmC,CAAC,GACjDA,CAAC,CAAC,mCAAmC,EAAEJ,KAAK,CAClD,CAAC;MACDkB,eAAe,EAAEf,0BAA0B,CACzCS,UAAU,GACNA,UAAU,CAACR,CAAC,CAAC,oCAAoC,CAAC,GAClDA,CAAC,CAAC,oCAAoC,EAAEJ,KAAK,CACnD;IACF,CAAC;EACH;EAEUmB,iBAAiBA,CAAA,EAAG;IAC5B,OAAO,CACL;MACEC,IAAI,EAAE,SAAS;MACfC,QAAQ,EAAElB,0BAA0B,CAClCC,CAAC,CAAC,mCAAmC,EAAE,OAAO,CAChD;IACF,CAAC,CACF;EACH;;EAEA;AACF;AACA;EACE,OAAOkB,oBAAoBA,CAAA,EAA6B;IACtD,OAAO;MACLC,UAAU,EAAE,CACV;QACEH,IAAI,EAAE,UAAU;QAChBC,QAAQ,EAAElB,0BAA0B,CAClCC,CAAC,CAAC,oCAAoC,EAAE,OAAO,CACjD;MACF,CAAC,EACD;QACEgB,IAAI,EAAE,SAAS;QACfC,QAAQ,EAAElB,0BAA0B,CAClCC,CAAC,CAAC,mCAAmC,EAAE,OAAO,CAChD;MACF,CAAC,CACF;MACDoB,sBAAsB,EAAE;IAC1B,CAAC;EACH;AACF","ignoreList":[]}
|
|
@@ -69,6 +69,7 @@ export declare class PaymentField extends FormComponent {
|
|
|
69
69
|
upload?: {
|
|
70
70
|
count: number;
|
|
71
71
|
summaryList: import("../../../../server/plugins/engine/types.js").SummaryList;
|
|
72
|
+
uploadingLabel?: string;
|
|
72
73
|
};
|
|
73
74
|
};
|
|
74
75
|
/**
|
|
@@ -123,6 +124,7 @@ export interface PaymentSessionData {
|
|
|
123
124
|
reference: string;
|
|
124
125
|
amount: number;
|
|
125
126
|
description: string;
|
|
127
|
+
descriptionInEng?: string;
|
|
126
128
|
paymentId: string;
|
|
127
129
|
componentName: string;
|
|
128
130
|
returnUrl: string;
|
|
@@ -19,6 +19,7 @@ export class PaymentField extends FormComponent {
|
|
|
19
19
|
reference: joi.string().required(),
|
|
20
20
|
amount: joi.number().required(),
|
|
21
21
|
description: joi.string().required(),
|
|
22
|
+
descriptionInEng: joi.string().optional(),
|
|
22
23
|
uuid: joi.string().uuid().required(),
|
|
23
24
|
formId: joi.string().required(),
|
|
24
25
|
isLivePayment: joi.boolean().required(),
|
|
@@ -164,10 +165,11 @@ export class PaymentField extends FormComponent {
|
|
|
164
165
|
const {
|
|
165
166
|
model
|
|
166
167
|
} = args.controller;
|
|
167
|
-
const language = resolveLanguage(request);
|
|
168
168
|
const {
|
|
169
|
-
|
|
170
|
-
|
|
169
|
+
language,
|
|
170
|
+
t,
|
|
171
|
+
tComponent
|
|
172
|
+
} = model.createTranslator(resolveLanguage(request));
|
|
171
173
|
const state = await args.controller.getState(request);
|
|
172
174
|
const {
|
|
173
175
|
baseUrl
|
|
@@ -189,7 +191,7 @@ export class PaymentField extends FormComponent {
|
|
|
189
191
|
if (resolvedAmount === 0) {
|
|
190
192
|
return h.redirect(summaryUrl).code(StatusCodes.SEE_OTHER);
|
|
191
193
|
}
|
|
192
|
-
const description = options.description;
|
|
194
|
+
const description = tComponent(args.component, 'paymentDescription') || options.description;
|
|
193
195
|
const slug = `/${model.basePath}`;
|
|
194
196
|
const payCallbackUrl = `${baseUrl}/payment-callback?uuid=${uuid}`;
|
|
195
197
|
const paymentPageUrl = args.sourceUrl;
|
|
@@ -201,7 +203,8 @@ export class PaymentField extends FormComponent {
|
|
|
201
203
|
const amountInPence = Math.round(resolvedAmount * 100);
|
|
202
204
|
const payment = await paymentService.createPayment(amountInPence, description, payCallbackUrl, reference, isLivePayment, {
|
|
203
205
|
formId,
|
|
204
|
-
slug
|
|
206
|
+
slug,
|
|
207
|
+
language
|
|
205
208
|
}, prefilledEmail);
|
|
206
209
|
if (!payment) {
|
|
207
210
|
const message = isLivePayment ? t('components.paymentField.cannotTakePayment') : t('components.paymentField.testApiKey');
|
|
@@ -215,6 +218,7 @@ export class PaymentField extends FormComponent {
|
|
|
215
218
|
reference,
|
|
216
219
|
amount: resolvedAmount,
|
|
217
220
|
description,
|
|
221
|
+
descriptionInEng: options.description,
|
|
218
222
|
paymentId: payment.paymentId,
|
|
219
223
|
componentName,
|
|
220
224
|
returnUrl: summaryUrl,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PaymentField.js","names":["randomUUID","StatusCodes","joi","logger","COMPONENT_STATE_ERROR","FormComponent","createError","getPluginOptions","PaymentErrorTypes","PaymentPreAuthError","PaymentSubmissionError","createPaymentService","formatCurrency","resolveLanguage","PaymentField","isAppendageStateSingleObject","constructor","def","props","options","paymentStateSchema","object","paymentId","string","required","reference","amount","number","description","uuid","formId","isLivePayment","boolean","preAuth","status","valid","createdAt","isoDate","unknown","label","formSchema","stateSchema","getPaymentStateFromState","state","value","name","isPaymentState","undefined","getDisplayStringFromState","_translator","getViewModel","context","payload","viewModel","translator","tComponent","paymentState","Array","isArray","isState","getFormValue","getContextValueFromState","getAllPossibleErrors","baseErrors","type","template","advancedSettingsErrors","resolveAmount","model","conditionalAmounts","length","condition","conditions","warn","fn","dispatcher","request","h","args","componentName","component","controller","language","t","createTranslator","getState","baseUrl","server","summaryUrl","basePath","existingPaymentState","redirect","code","SEE_OTHER","isLive","isPreview","formsService","services","paymentService","$$__referenceNumber","resolvedAmount","slug","payCallbackUrl","paymentPageUrl","sourceUrl","prefilledEmail","userConfirmationEmail","userConfirmationEmailAddress","amountInPence","Math","round","payment","createPayment","message","govukError","yar","flash","url","pathname","search","sessionData","returnUrl","failureUrl","set","paymentUrl","onSubmit","_metadata","PaymentIncomplete","capture","getPaymentStatus","checkPaymentAmount","markPaymentCaptured","PaymentExpired","captured","capturePayment","updatedState","Date","toISOString","page","currentState","mergeState"],"sources":["../../../../../src/server/plugins/engine/components/PaymentField.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto'\n\nimport {\n type FormMetadata,\n type PaymentFieldComponent\n} from '@defra/forms-model'\nimport { StatusCodes } from 'http-status-codes'\nimport joi, { type ObjectSchema } from 'joi'\n\nimport { logger } from '~/src/server/common/helpers/logging/logger.js'\nimport { COMPONENT_STATE_ERROR } from '~/src/server/constants.js'\nimport { FormComponent } from '~/src/server/plugins/engine/components/FormComponent.js'\nimport { type PaymentState } from '~/src/server/plugins/engine/components/PaymentField.types.js'\nimport { type RenderContext } from '~/src/server/plugins/engine/components/types.js'\nimport {\n createError,\n getPluginOptions\n} from '~/src/server/plugins/engine/helpers.js'\nimport { type Translator } from '~/src/server/plugins/engine/i18n/types.js'\nimport { type FormModel } from '~/src/server/plugins/engine/models/index.js'\nimport {\n PaymentErrorTypes,\n PaymentPreAuthError,\n PaymentSubmissionError\n} from '~/src/server/plugins/engine/pageControllers/errors.js'\nimport {\n type FormContext,\n type FormRequestPayload,\n type FormResponseToolkit\n} from '~/src/server/plugins/engine/types/index.js'\nimport {\n type ErrorMessageTemplateList,\n type FormState,\n type FormStateValue,\n type FormSubmissionState,\n type PaymentExternalArgs\n} from '~/src/server/plugins/engine/types.js'\nimport {\n createPaymentService,\n formatCurrency\n} from '~/src/server/plugins/payment/helper.js'\nimport { resolveLanguage } from '~/src/server/utils/utils.js'\n\nexport class PaymentField extends FormComponent {\n declare options: PaymentFieldComponent['options']\n declare formSchema: ObjectSchema\n declare stateSchema: ObjectSchema\n declare def: PaymentFieldComponent\n isAppendageStateSingleObject = true\n\n constructor(\n def: PaymentFieldComponent,\n props: ConstructorParameters<typeof FormComponent>[1]\n ) {\n super(def, props)\n\n this.options = def.options\n this.def = def\n\n const paymentStateSchema = joi\n .object({\n paymentId: joi.string().required(),\n reference: joi.string().required(),\n amount: joi.number().required(),\n description: joi.string().required(),\n uuid: joi.string().uuid().required(),\n formId: joi.string().required(),\n isLivePayment: joi.boolean().required(),\n preAuth: joi\n .object({\n status: joi\n .string()\n .valid('success', 'failed', 'started')\n .required(),\n createdAt: joi.string().isoDate().required()\n })\n .required()\n })\n .unknown(true)\n .label(this.label)\n\n this.formSchema = paymentStateSchema\n // 'required()' forces the payment page to be invalid until we have valid payment state\n // i.e. the user will automatically be directed back to the payment page\n // if they attempt to access future pages when no payment entered yet\n this.stateSchema = paymentStateSchema.required()\n }\n\n /**\n * Gets the PaymentState from form submission state\n */\n getPaymentStateFromState(\n state: FormSubmissionState\n ): PaymentState | undefined {\n const value = state[this.name]\n return this.isPaymentState(value) ? value : undefined\n }\n\n getDisplayStringFromState(\n state: FormSubmissionState,\n _translator: Translator\n ): string {\n const value = this.getPaymentStateFromState(state)\n\n if (!value) {\n return ''\n }\n\n return `${formatCurrency(value.amount)} - ${value.description}`\n }\n\n getViewModel(context: RenderContext) {\n const { payload } = context\n const viewModel = super.getViewModel(context)\n const { translator } = context\n const { tComponent } = translator\n\n // Payload is pre-populated from state if a payment has already been made\n const paymentState = this.isPaymentState(payload[this.name] as unknown)\n ? (payload[this.name] as unknown as PaymentState)\n : undefined\n\n // Use payment state amount if pre-authorized, otherwise use default.\n // The page controller overrides this with the resolved conditional amount\n // using the full form state (which getViewModel doesn't have access to).\n const amount = paymentState?.amount ?? this.options.amount\n\n return {\n ...viewModel,\n amount: formatCurrency(amount),\n description:\n tComponent(this.def, 'paymentDescription') || this.options.description,\n paymentState\n }\n }\n\n /**\n * Type guard to check if value is PaymentState\n */\n isPaymentState(value: unknown): value is PaymentState {\n return PaymentField.isPaymentState(value)\n }\n\n /**\n * Static type guard to check if value is PaymentState\n */\n static isPaymentState(value: unknown): value is PaymentState {\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n return false\n }\n\n const state = value as PaymentState\n return (\n typeof state.paymentId === 'string' &&\n typeof state.amount === 'number' &&\n typeof state.description === 'string'\n )\n }\n\n /**\n * Override base isState to validate PaymentState\n */\n isState(value?: FormStateValue | FormState): value is FormState {\n return this.isPaymentState(value)\n }\n\n getFormValue(value?: FormStateValue | FormState) {\n return this.isPaymentState(value)\n ? (value as unknown as NonNullable<FormStateValue>)\n : undefined\n }\n\n getContextValueFromState(state: FormSubmissionState) {\n return this.isPaymentState(state)\n ? `Reference: ${state.reference}\\nAmount: ${formatCurrency(state.amount)}`\n : ''\n }\n\n /**\n * For error preview page that shows all possible errors on a component\n */\n getAllPossibleErrors(): ErrorMessageTemplateList {\n return PaymentField.getAllPossibleErrors()\n }\n\n /**\n * Static version of getAllPossibleErrors that doesn't require a component instance.\n */\n static getAllPossibleErrors(): ErrorMessageTemplateList {\n return {\n baseErrors: [\n {\n type: 'paymentRequired',\n template: 'Complete the payment to continue'\n }\n ],\n advancedSettingsErrors: []\n }\n }\n\n /**\n * Resolves the payment amount from conditional amounts configuration.\n * Evaluates conditions in order; first true condition wins.\n * Falls back to the default options.amount.\n */\n static resolveAmount(\n options: PaymentFieldComponent['options'],\n model: FormModel,\n state: FormState\n ): number {\n const { conditionalAmounts } = options\n\n if (!conditionalAmounts?.length) {\n return options.amount\n }\n\n for (const { condition, amount } of conditionalAmounts) {\n if (!model.conditions[condition]) {\n logger.warn(\n `[payment] Condition '${condition}' not found in form conditions. Skipping.`\n )\n continue\n }\n if (model.conditions[condition].fn(state)) {\n return amount\n }\n }\n\n return options.amount\n }\n\n /**\n * Dispatcher for external redirect to GOV.UK Pay\n */\n static async dispatcher(\n request: FormRequestPayload,\n h: FormResponseToolkit,\n args: PaymentExternalArgs\n ): Promise<unknown> {\n const { options, name: componentName } = args.component\n const { model } = args.controller\n const language = resolveLanguage(request)\n const { t } = model.createTranslator(language)\n const state = await args.controller.getState(request)\n const { baseUrl } = getPluginOptions(request.server)\n const summaryUrl = `${baseUrl}/${model.basePath}/summary`\n\n const existingPaymentState = state[componentName]\n if (\n PaymentField.isPaymentState(existingPaymentState) &&\n existingPaymentState.preAuth?.status === 'success'\n ) {\n return h.redirect(summaryUrl).code(StatusCodes.SEE_OTHER)\n }\n\n const isLivePayment = args.isLive && !args.isPreview\n const formId = args.controller.model.formId\n const formsService = model.services.formsService\n const paymentService = await createPaymentService(\n isLivePayment,\n formId,\n formsService\n )\n\n const uuid = randomUUID()\n\n const reference = state.$$__referenceNumber as string\n const resolvedAmount = PaymentField.resolveAmount(options, model, state)\n\n // Zero-amount safety net (page skip should prevent this, but defensive)\n if (resolvedAmount === 0) {\n return h.redirect(summaryUrl).code(StatusCodes.SEE_OTHER)\n }\n\n const description = options.description\n\n const slug = `/${model.basePath}`\n\n const payCallbackUrl = `${baseUrl}/payment-callback?uuid=${uuid}`\n const paymentPageUrl = args.sourceUrl\n\n let prefilledEmail: string | undefined\n const userConfirmationEmail = state.userConfirmationEmailAddress\n if (typeof userConfirmationEmail === 'string' && userConfirmationEmail) {\n prefilledEmail = userConfirmationEmail\n }\n\n const amountInPence = Math.round(resolvedAmount * 100)\n const payment = await paymentService.createPayment(\n amountInPence,\n description,\n payCallbackUrl,\n reference,\n isLivePayment,\n { formId, slug },\n prefilledEmail\n )\n\n if (!payment) {\n const message = isLivePayment\n ? t('components.paymentField.cannotTakePayment')\n : t('components.paymentField.testApiKey')\n const govukError = createError(componentName, message)\n request.yar.flash(COMPONENT_STATE_ERROR, govukError, true)\n return h\n .redirect(`${request.url.pathname}${request.url.search}`)\n .code(StatusCodes.SEE_OTHER)\n }\n\n const sessionData: PaymentSessionData = {\n uuid,\n formId,\n reference,\n amount: resolvedAmount,\n description,\n paymentId: payment.paymentId,\n componentName,\n returnUrl: summaryUrl,\n failureUrl: paymentPageUrl,\n isLivePayment\n }\n\n request.yar.set(`payment-${uuid}`, sessionData)\n\n return h.redirect(payment.paymentUrl).code(StatusCodes.SEE_OTHER)\n }\n\n /**\n * Called on form submission to capture the payment\n * @see https://docs.payments.service.gov.uk/delayed_capture/#delay-taking-a-payment\n */\n async onSubmit(\n request: FormRequestPayload,\n _metadata: FormMetadata,\n context: FormContext\n ): Promise<void> {\n const language = resolveLanguage(request)\n const { t } = this.model.createTranslator(language)\n\n // Zero-amount bypass — no capture needed\n const resolvedAmount = PaymentField.resolveAmount(\n this.options,\n this.model,\n context.state\n )\n if (resolvedAmount === 0) {\n return\n }\n\n const paymentState = this.getPaymentStateFromState(context.state)\n\n if (!paymentState) {\n throw new PaymentPreAuthError(\n this,\n t('components.paymentField.completePayment'),\n true,\n PaymentErrorTypes.PaymentIncomplete\n )\n }\n\n if (paymentState.capture?.status === 'success') {\n return\n }\n\n const { paymentId, isLivePayment, formId } = paymentState\n const formsService = this.model.services.formsService\n const paymentService = await createPaymentService(\n isLivePayment,\n formId,\n formsService\n )\n\n /**\n * @see https://docs.payments.service.gov.uk/api_reference/#payment-status-lifecycle\n */\n const status = await paymentService.getPaymentStatus(\n paymentId,\n isLivePayment\n )\n\n PaymentSubmissionError.checkPaymentAmount(\n status.amount,\n resolvedAmount,\n this,\n t\n )\n\n if (status.state.status === 'success') {\n await this.markPaymentCaptured(request, paymentState)\n return\n }\n\n if (status.state.status !== 'capturable') {\n throw new PaymentPreAuthError(\n this,\n t('components.paymentField.paymentExpired'),\n true,\n PaymentErrorTypes.PaymentExpired\n )\n }\n\n const captured = await paymentService.capturePayment(\n paymentId,\n status.amount\n )\n\n if (!captured) {\n throw new PaymentPreAuthError(\n this,\n t('components.paymentField.submissionFailed'),\n false\n )\n }\n\n await this.markPaymentCaptured(request, paymentState)\n }\n\n /**\n * Updates payment state to mark capture as successful\n * This ensures we don't try to re-capture on submission retry\n */\n private async markPaymentCaptured(\n request: FormRequestPayload,\n paymentState: PaymentState\n ): Promise<void> {\n const updatedState: PaymentState = {\n ...paymentState,\n capture: {\n status: 'success',\n createdAt: new Date().toISOString()\n }\n }\n\n if (this.page) {\n const currentState = await this.page.getState(request)\n await this.page.mergeState(request, currentState, {\n [this.name]: updatedState\n })\n }\n }\n}\n\n/**\n * Session data stored when dispatching to GOV.UK Pay\n */\nexport interface PaymentSessionData {\n uuid: string\n formId: string\n reference: string\n amount: number\n description: string\n paymentId: string\n componentName: string\n returnUrl: string\n failureUrl: string\n isLivePayment: boolean\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"PaymentField.js","names":["randomUUID","StatusCodes","joi","logger","COMPONENT_STATE_ERROR","FormComponent","createError","getPluginOptions","PaymentErrorTypes","PaymentPreAuthError","PaymentSubmissionError","createPaymentService","formatCurrency","resolveLanguage","PaymentField","isAppendageStateSingleObject","constructor","def","props","options","paymentStateSchema","object","paymentId","string","required","reference","amount","number","description","descriptionInEng","optional","uuid","formId","isLivePayment","boolean","preAuth","status","valid","createdAt","isoDate","unknown","label","formSchema","stateSchema","getPaymentStateFromState","state","value","name","isPaymentState","undefined","getDisplayStringFromState","_translator","getViewModel","context","payload","viewModel","translator","tComponent","paymentState","Array","isArray","isState","getFormValue","getContextValueFromState","getAllPossibleErrors","baseErrors","type","template","advancedSettingsErrors","resolveAmount","model","conditionalAmounts","length","condition","conditions","warn","fn","dispatcher","request","h","args","componentName","component","controller","language","t","createTranslator","getState","baseUrl","server","summaryUrl","basePath","existingPaymentState","redirect","code","SEE_OTHER","isLive","isPreview","formsService","services","paymentService","$$__referenceNumber","resolvedAmount","slug","payCallbackUrl","paymentPageUrl","sourceUrl","prefilledEmail","userConfirmationEmail","userConfirmationEmailAddress","amountInPence","Math","round","payment","createPayment","message","govukError","yar","flash","url","pathname","search","sessionData","returnUrl","failureUrl","set","paymentUrl","onSubmit","_metadata","PaymentIncomplete","capture","getPaymentStatus","checkPaymentAmount","markPaymentCaptured","PaymentExpired","captured","capturePayment","updatedState","Date","toISOString","page","currentState","mergeState"],"sources":["../../../../../src/server/plugins/engine/components/PaymentField.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto'\n\nimport {\n type FormMetadata,\n type PaymentFieldComponent\n} from '@defra/forms-model'\nimport { StatusCodes } from 'http-status-codes'\nimport joi, { type ObjectSchema } from 'joi'\n\nimport { logger } from '~/src/server/common/helpers/logging/logger.js'\nimport { COMPONENT_STATE_ERROR } from '~/src/server/constants.js'\nimport { FormComponent } from '~/src/server/plugins/engine/components/FormComponent.js'\nimport { type PaymentState } from '~/src/server/plugins/engine/components/PaymentField.types.js'\nimport { type RenderContext } from '~/src/server/plugins/engine/components/types.js'\nimport {\n createError,\n getPluginOptions\n} from '~/src/server/plugins/engine/helpers.js'\nimport { type Translator } from '~/src/server/plugins/engine/i18n/types.js'\nimport { type FormModel } from '~/src/server/plugins/engine/models/index.js'\nimport {\n PaymentErrorTypes,\n PaymentPreAuthError,\n PaymentSubmissionError\n} from '~/src/server/plugins/engine/pageControllers/errors.js'\nimport {\n type FormContext,\n type FormRequestPayload,\n type FormResponseToolkit\n} from '~/src/server/plugins/engine/types/index.js'\nimport {\n type ErrorMessageTemplateList,\n type FormState,\n type FormStateValue,\n type FormSubmissionState,\n type PaymentExternalArgs\n} from '~/src/server/plugins/engine/types.js'\nimport {\n createPaymentService,\n formatCurrency\n} from '~/src/server/plugins/payment/helper.js'\nimport { resolveLanguage } from '~/src/server/utils/utils.js'\n\nexport class PaymentField extends FormComponent {\n declare options: PaymentFieldComponent['options']\n declare formSchema: ObjectSchema\n declare stateSchema: ObjectSchema\n declare def: PaymentFieldComponent\n isAppendageStateSingleObject = true\n\n constructor(\n def: PaymentFieldComponent,\n props: ConstructorParameters<typeof FormComponent>[1]\n ) {\n super(def, props)\n\n this.options = def.options\n this.def = def\n\n const paymentStateSchema = joi\n .object({\n paymentId: joi.string().required(),\n reference: joi.string().required(),\n amount: joi.number().required(),\n description: joi.string().required(),\n descriptionInEng: joi.string().optional(),\n uuid: joi.string().uuid().required(),\n formId: joi.string().required(),\n isLivePayment: joi.boolean().required(),\n preAuth: joi\n .object({\n status: joi\n .string()\n .valid('success', 'failed', 'started')\n .required(),\n createdAt: joi.string().isoDate().required()\n })\n .required()\n })\n .unknown(true)\n .label(this.label)\n\n this.formSchema = paymentStateSchema\n // 'required()' forces the payment page to be invalid until we have valid payment state\n // i.e. the user will automatically be directed back to the payment page\n // if they attempt to access future pages when no payment entered yet\n this.stateSchema = paymentStateSchema.required()\n }\n\n /**\n * Gets the PaymentState from form submission state\n */\n getPaymentStateFromState(\n state: FormSubmissionState\n ): PaymentState | undefined {\n const value = state[this.name]\n return this.isPaymentState(value) ? value : undefined\n }\n\n getDisplayStringFromState(\n state: FormSubmissionState,\n _translator: Translator\n ): string {\n const value = this.getPaymentStateFromState(state)\n\n if (!value) {\n return ''\n }\n\n return `${formatCurrency(value.amount)} - ${value.description}`\n }\n\n getViewModel(context: RenderContext) {\n const { payload } = context\n const viewModel = super.getViewModel(context)\n const { translator } = context\n const { tComponent } = translator\n\n // Payload is pre-populated from state if a payment has already been made\n const paymentState = this.isPaymentState(payload[this.name] as unknown)\n ? (payload[this.name] as unknown as PaymentState)\n : undefined\n\n // Use payment state amount if pre-authorized, otherwise use default.\n // The page controller overrides this with the resolved conditional amount\n // using the full form state (which getViewModel doesn't have access to).\n const amount = paymentState?.amount ?? this.options.amount\n\n return {\n ...viewModel,\n amount: formatCurrency(amount),\n description:\n tComponent(this.def, 'paymentDescription') || this.options.description,\n paymentState\n }\n }\n\n /**\n * Type guard to check if value is PaymentState\n */\n isPaymentState(value: unknown): value is PaymentState {\n return PaymentField.isPaymentState(value)\n }\n\n /**\n * Static type guard to check if value is PaymentState\n */\n static isPaymentState(value: unknown): value is PaymentState {\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n return false\n }\n\n const state = value as PaymentState\n return (\n typeof state.paymentId === 'string' &&\n typeof state.amount === 'number' &&\n typeof state.description === 'string'\n )\n }\n\n /**\n * Override base isState to validate PaymentState\n */\n isState(value?: FormStateValue | FormState): value is FormState {\n return this.isPaymentState(value)\n }\n\n getFormValue(value?: FormStateValue | FormState) {\n return this.isPaymentState(value)\n ? (value as unknown as NonNullable<FormStateValue>)\n : undefined\n }\n\n getContextValueFromState(state: FormSubmissionState) {\n return this.isPaymentState(state)\n ? `Reference: ${state.reference}\\nAmount: ${formatCurrency(state.amount)}`\n : ''\n }\n\n /**\n * For error preview page that shows all possible errors on a component\n */\n getAllPossibleErrors(): ErrorMessageTemplateList {\n return PaymentField.getAllPossibleErrors()\n }\n\n /**\n * Static version of getAllPossibleErrors that doesn't require a component instance.\n */\n static getAllPossibleErrors(): ErrorMessageTemplateList {\n return {\n baseErrors: [\n {\n type: 'paymentRequired',\n template: 'Complete the payment to continue'\n }\n ],\n advancedSettingsErrors: []\n }\n }\n\n /**\n * Resolves the payment amount from conditional amounts configuration.\n * Evaluates conditions in order; first true condition wins.\n * Falls back to the default options.amount.\n */\n static resolveAmount(\n options: PaymentFieldComponent['options'],\n model: FormModel,\n state: FormState\n ): number {\n const { conditionalAmounts } = options\n\n if (!conditionalAmounts?.length) {\n return options.amount\n }\n\n for (const { condition, amount } of conditionalAmounts) {\n if (!model.conditions[condition]) {\n logger.warn(\n `[payment] Condition '${condition}' not found in form conditions. Skipping.`\n )\n continue\n }\n if (model.conditions[condition].fn(state)) {\n return amount\n }\n }\n\n return options.amount\n }\n\n /**\n * Dispatcher for external redirect to GOV.UK Pay\n */\n static async dispatcher(\n request: FormRequestPayload,\n h: FormResponseToolkit,\n args: PaymentExternalArgs\n ): Promise<unknown> {\n const { options, name: componentName } = args.component\n const { model } = args.controller\n const { language, t, tComponent } = model.createTranslator(\n resolveLanguage(request)\n )\n const state = await args.controller.getState(request)\n const { baseUrl } = getPluginOptions(request.server)\n const summaryUrl = `${baseUrl}/${model.basePath}/summary`\n\n const existingPaymentState = state[componentName]\n if (\n PaymentField.isPaymentState(existingPaymentState) &&\n existingPaymentState.preAuth?.status === 'success'\n ) {\n return h.redirect(summaryUrl).code(StatusCodes.SEE_OTHER)\n }\n\n const isLivePayment = args.isLive && !args.isPreview\n const formId = args.controller.model.formId\n const formsService = model.services.formsService\n const paymentService = await createPaymentService(\n isLivePayment,\n formId,\n formsService\n )\n\n const uuid = randomUUID()\n\n const reference = state.$$__referenceNumber as string\n const resolvedAmount = PaymentField.resolveAmount(options, model, state)\n\n // Zero-amount safety net (page skip should prevent this, but defensive)\n if (resolvedAmount === 0) {\n return h.redirect(summaryUrl).code(StatusCodes.SEE_OTHER)\n }\n\n const description =\n tComponent(args.component, 'paymentDescription') || options.description\n\n const slug = `/${model.basePath}`\n\n const payCallbackUrl = `${baseUrl}/payment-callback?uuid=${uuid}`\n const paymentPageUrl = args.sourceUrl\n\n let prefilledEmail: string | undefined\n const userConfirmationEmail = state.userConfirmationEmailAddress\n if (typeof userConfirmationEmail === 'string' && userConfirmationEmail) {\n prefilledEmail = userConfirmationEmail\n }\n\n const amountInPence = Math.round(resolvedAmount * 100)\n const payment = await paymentService.createPayment(\n amountInPence,\n description,\n payCallbackUrl,\n reference,\n isLivePayment,\n { formId, slug, language },\n prefilledEmail\n )\n\n if (!payment) {\n const message = isLivePayment\n ? t('components.paymentField.cannotTakePayment')\n : t('components.paymentField.testApiKey')\n const govukError = createError(componentName, message)\n request.yar.flash(COMPONENT_STATE_ERROR, govukError, true)\n return h\n .redirect(`${request.url.pathname}${request.url.search}`)\n .code(StatusCodes.SEE_OTHER)\n }\n\n const sessionData: PaymentSessionData = {\n uuid,\n formId,\n reference,\n amount: resolvedAmount,\n description,\n descriptionInEng: options.description,\n paymentId: payment.paymentId,\n componentName,\n returnUrl: summaryUrl,\n failureUrl: paymentPageUrl,\n isLivePayment\n }\n\n request.yar.set(`payment-${uuid}`, sessionData)\n\n return h.redirect(payment.paymentUrl).code(StatusCodes.SEE_OTHER)\n }\n\n /**\n * Called on form submission to capture the payment\n * @see https://docs.payments.service.gov.uk/delayed_capture/#delay-taking-a-payment\n */\n async onSubmit(\n request: FormRequestPayload,\n _metadata: FormMetadata,\n context: FormContext\n ): Promise<void> {\n const language = resolveLanguage(request)\n const { t } = this.model.createTranslator(language)\n\n // Zero-amount bypass — no capture needed\n const resolvedAmount = PaymentField.resolveAmount(\n this.options,\n this.model,\n context.state\n )\n if (resolvedAmount === 0) {\n return\n }\n\n const paymentState = this.getPaymentStateFromState(context.state)\n\n if (!paymentState) {\n throw new PaymentPreAuthError(\n this,\n t('components.paymentField.completePayment'),\n true,\n PaymentErrorTypes.PaymentIncomplete\n )\n }\n\n if (paymentState.capture?.status === 'success') {\n return\n }\n\n const { paymentId, isLivePayment, formId } = paymentState\n const formsService = this.model.services.formsService\n const paymentService = await createPaymentService(\n isLivePayment,\n formId,\n formsService\n )\n\n /**\n * @see https://docs.payments.service.gov.uk/api_reference/#payment-status-lifecycle\n */\n const status = await paymentService.getPaymentStatus(\n paymentId,\n isLivePayment\n )\n\n PaymentSubmissionError.checkPaymentAmount(\n status.amount,\n resolvedAmount,\n this,\n t\n )\n\n if (status.state.status === 'success') {\n await this.markPaymentCaptured(request, paymentState)\n return\n }\n\n if (status.state.status !== 'capturable') {\n throw new PaymentPreAuthError(\n this,\n t('components.paymentField.paymentExpired'),\n true,\n PaymentErrorTypes.PaymentExpired\n )\n }\n\n const captured = await paymentService.capturePayment(\n paymentId,\n status.amount\n )\n\n if (!captured) {\n throw new PaymentPreAuthError(\n this,\n t('components.paymentField.submissionFailed'),\n false\n )\n }\n\n await this.markPaymentCaptured(request, paymentState)\n }\n\n /**\n * Updates payment state to mark capture as successful\n * This ensures we don't try to re-capture on submission retry\n */\n private async markPaymentCaptured(\n request: FormRequestPayload,\n paymentState: PaymentState\n ): Promise<void> {\n const updatedState: PaymentState = {\n ...paymentState,\n capture: {\n status: 'success',\n createdAt: new Date().toISOString()\n }\n }\n\n if (this.page) {\n const currentState = await this.page.getState(request)\n await this.page.mergeState(request, currentState, {\n [this.name]: updatedState\n })\n }\n }\n}\n\n/**\n * Session data stored when dispatching to GOV.UK Pay\n */\nexport interface PaymentSessionData {\n uuid: string\n formId: string\n reference: string\n amount: number\n description: string\n descriptionInEng?: string\n paymentId: string\n componentName: string\n returnUrl: string\n failureUrl: string\n isLivePayment: boolean\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { type TrackingFieldComponent } from '@defra/forms-model';
|
|
2
|
+
import { type BooleanSchema } from 'joi';
|
|
3
|
+
import { FormComponent } from '../../../../server/plugins/engine/components/FormComponent.js';
|
|
4
|
+
import { type ErrorMessageTemplateList, type FormState, type FormStateValue, type FormSubmissionState } from '../../../../server/plugins/engine/types.js';
|
|
5
|
+
export declare class TrackingField extends FormComponent {
|
|
6
|
+
formSchema: BooleanSchema;
|
|
7
|
+
stateSchema: BooleanSchema;
|
|
8
|
+
options: TrackingFieldComponent['options'];
|
|
9
|
+
constructor(def: TrackingFieldComponent, props: ConstructorParameters<typeof FormComponent>[1]);
|
|
10
|
+
getFormValueFromState(state: FormSubmissionState): NonNullable<FormStateValue> | undefined;
|
|
11
|
+
isValue(value?: FormStateValue | FormState): value is true;
|
|
12
|
+
/**
|
|
13
|
+
* For error preview page that shows all possible errors on a component
|
|
14
|
+
*/
|
|
15
|
+
getAllPossibleErrors(): ErrorMessageTemplateList;
|
|
16
|
+
static isTracking(value?: FormStateValue | FormState): value is true;
|
|
17
|
+
/**
|
|
18
|
+
* Static version of getAllPossibleErrors that doesn't require a component instance.
|
|
19
|
+
*/
|
|
20
|
+
static getAllPossibleErrors(): ErrorMessageTemplateList;
|
|
21
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import joi from 'joi';
|
|
2
|
+
import { FormComponent, isFormValue } from "./FormComponent.js";
|
|
3
|
+
import { messageTemplate } from "../pageControllers/validationOptions.js";
|
|
4
|
+
export class TrackingField extends FormComponent {
|
|
5
|
+
constructor(def, props) {
|
|
6
|
+
super(def, props);
|
|
7
|
+
const formSchema = joi.boolean().valid(true).label(this.label).required();
|
|
8
|
+
this.formSchema = formSchema.default(false);
|
|
9
|
+
this.stateSchema = formSchema.default(null).allow(null);
|
|
10
|
+
this.schema = {};
|
|
11
|
+
this.options = {};
|
|
12
|
+
}
|
|
13
|
+
getFormValueFromState(state) {
|
|
14
|
+
const {
|
|
15
|
+
name
|
|
16
|
+
} = this;
|
|
17
|
+
return this.getFormValue(state[name]);
|
|
18
|
+
}
|
|
19
|
+
isValue(value) {
|
|
20
|
+
return TrackingField.isTracking(value);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* For error preview page that shows all possible errors on a component
|
|
25
|
+
*/
|
|
26
|
+
getAllPossibleErrors() {
|
|
27
|
+
return TrackingField.getAllPossibleErrors();
|
|
28
|
+
}
|
|
29
|
+
static isTracking(value) {
|
|
30
|
+
return isFormValue(value) && typeof value === 'boolean';
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Static version of getAllPossibleErrors that doesn't require a component instance.
|
|
35
|
+
*/
|
|
36
|
+
static getAllPossibleErrors() {
|
|
37
|
+
return {
|
|
38
|
+
baseErrors: [{
|
|
39
|
+
type: 'required',
|
|
40
|
+
template: messageTemplate.required
|
|
41
|
+
}],
|
|
42
|
+
advancedSettingsErrors: []
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=TrackingField.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TrackingField.js","names":["joi","FormComponent","isFormValue","messageTemplate","TrackingField","constructor","def","props","formSchema","boolean","valid","label","required","default","stateSchema","allow","schema","options","getFormValueFromState","state","name","getFormValue","isValue","value","isTracking","getAllPossibleErrors","baseErrors","type","template","advancedSettingsErrors"],"sources":["../../../../../src/server/plugins/engine/components/TrackingField.ts"],"sourcesContent":["import { type TrackingFieldComponent } from '@defra/forms-model'\nimport joi, { type BooleanSchema } from 'joi'\n\nimport {\n FormComponent,\n isFormValue\n} from '~/src/server/plugins/engine/components/FormComponent.js'\nimport { messageTemplate } from '~/src/server/plugins/engine/pageControllers/validationOptions.js'\nimport {\n type ErrorMessageTemplateList,\n type FormState,\n type FormStateValue,\n type FormSubmissionState\n} from '~/src/server/plugins/engine/types.js'\n\nexport class TrackingField extends FormComponent {\n declare formSchema: BooleanSchema\n declare stateSchema: BooleanSchema\n declare options: TrackingFieldComponent['options']\n\n constructor(\n def: TrackingFieldComponent,\n props: ConstructorParameters<typeof FormComponent>[1]\n ) {\n super(def, props)\n\n const formSchema = joi.boolean().valid(true).label(this.label).required()\n\n this.formSchema = formSchema.default(false)\n this.stateSchema = formSchema.default(null).allow(null)\n this.schema = {}\n this.options = {}\n }\n\n getFormValueFromState(state: FormSubmissionState) {\n const { name } = this\n return this.getFormValue(state[name])\n }\n\n isValue(value?: FormStateValue | FormState): value is true {\n return TrackingField.isTracking(value)\n }\n\n /**\n * For error preview page that shows all possible errors on a component\n */\n getAllPossibleErrors(): ErrorMessageTemplateList {\n return TrackingField.getAllPossibleErrors()\n }\n\n static isTracking(value?: FormStateValue | FormState): value is true {\n return isFormValue(value) && typeof value === 'boolean'\n }\n\n /**\n * Static version of getAllPossibleErrors that doesn't require a component instance.\n */\n static getAllPossibleErrors(): ErrorMessageTemplateList {\n return {\n baseErrors: [{ type: 'required', template: messageTemplate.required }],\n advancedSettingsErrors: []\n }\n }\n}\n"],"mappings":"AACA,OAAOA,GAAG,MAA8B,KAAK;AAE7C,SACEC,aAAa,EACbC,WAAW;AAEb,SAASC,eAAe;AAQxB,OAAO,MAAMC,aAAa,SAASH,aAAa,CAAC;EAK/CI,WAAWA,CACTC,GAA2B,EAC3BC,KAAqD,EACrD;IACA,KAAK,CAACD,GAAG,EAAEC,KAAK,CAAC;IAEjB,MAAMC,UAAU,GAAGR,GAAG,CAACS,OAAO,CAAC,CAAC,CAACC,KAAK,CAAC,IAAI,CAAC,CAACC,KAAK,CAAC,IAAI,CAACA,KAAK,CAAC,CAACC,QAAQ,CAAC,CAAC;IAEzE,IAAI,CAACJ,UAAU,GAAGA,UAAU,CAACK,OAAO,CAAC,KAAK,CAAC;IAC3C,IAAI,CAACC,WAAW,GAAGN,UAAU,CAACK,OAAO,CAAC,IAAI,CAAC,CAACE,KAAK,CAAC,IAAI,CAAC;IACvD,IAAI,CAACC,MAAM,GAAG,CAAC,CAAC;IAChB,IAAI,CAACC,OAAO,GAAG,CAAC,CAAC;EACnB;EAEAC,qBAAqBA,CAACC,KAA0B,EAAE;IAChD,MAAM;MAAEC;IAAK,CAAC,GAAG,IAAI;IACrB,OAAO,IAAI,CAACC,YAAY,CAACF,KAAK,CAACC,IAAI,CAAC,CAAC;EACvC;EAEAE,OAAOA,CAACC,KAAkC,EAAiB;IACzD,OAAOnB,aAAa,CAACoB,UAAU,CAACD,KAAK,CAAC;EACxC;;EAEA;AACF;AACA;EACEE,oBAAoBA,CAAA,EAA6B;IAC/C,OAAOrB,aAAa,CAACqB,oBAAoB,CAAC,CAAC;EAC7C;EAEA,OAAOD,UAAUA,CAACD,KAAkC,EAAiB;IACnE,OAAOrB,WAAW,CAACqB,KAAK,CAAC,IAAI,OAAOA,KAAK,KAAK,SAAS;EACzD;;EAEA;AACF;AACA;EACE,OAAOE,oBAAoBA,CAAA,EAA6B;IACtD,OAAO;MACLC,UAAU,EAAE,CAAC;QAAEC,IAAI,EAAE,UAAU;QAAEC,QAAQ,EAAEzB,eAAe,CAACS;MAAS,CAAC,CAAC;MACtEiB,sBAAsB,EAAE;IAC1B,CAAC;EACH;AACF","ignoreList":[]}
|
|
@@ -69,6 +69,7 @@ export declare class UkAddressField extends FormComponent {
|
|
|
69
69
|
upload?: {
|
|
70
70
|
count: number;
|
|
71
71
|
summaryList: import("../../../../server/plugins/engine/types.js").SummaryList;
|
|
72
|
+
uploadingLabel?: string;
|
|
72
73
|
};
|
|
73
74
|
};
|
|
74
75
|
isState(value?: FormStateValue | FormState): value is UkAddressState;
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import { ComponentType } from '@defra/forms-model';
|
|
1
|
+
import { ComponentType, FormStatus } from '@defra/forms-model';
|
|
2
2
|
import lowerFirst from 'lodash/lowerFirst.js';
|
|
3
3
|
import { ComponentCollection } from "./ComponentCollection.js";
|
|
4
4
|
import { FormComponent, isFormState } from "./FormComponent.js";
|
|
5
5
|
import { TextField } from "./TextField.js";
|
|
6
|
+
import { getCachedPluginTranslator } from "../i18n/form.js";
|
|
7
|
+
import { getAvailableLanguages } from "../i18n/languages.js";
|
|
6
8
|
import { dispatch } from "../../postcode-lookup/routes/index.js";
|
|
7
9
|
import { resolveLanguage } from "../../../utils/utils.js";
|
|
8
10
|
export class UkAddressField extends FormComponent {
|
|
@@ -164,7 +166,7 @@ export class UkAddressField extends FormComponent {
|
|
|
164
166
|
text: label.text,
|
|
165
167
|
/**
|
|
166
168
|
* For screen readers, only hide legend visually. This can be overridden
|
|
167
|
-
* by single component
|
|
169
|
+
* by single component (see QuestionPageController and showTitle handling)
|
|
168
170
|
*/
|
|
169
171
|
classes: options.hideTitle ? 'govuk-visually-hidden' : 'govuk-fieldset__legend--m'
|
|
170
172
|
}
|
|
@@ -235,22 +237,35 @@ export class UkAddressField extends FormComponent {
|
|
|
235
237
|
static isUkAddress(value) {
|
|
236
238
|
return isFormState(value) && TextField.isText(value.addressLine1) && TextField.isText(value.town) && TextField.isText(value.postcode);
|
|
237
239
|
}
|
|
238
|
-
|
|
239
|
-
// eslint-disable-next-line @typescript-eslint/require-await
|
|
240
240
|
static async dispatcher(request, h, args) {
|
|
241
241
|
const {
|
|
242
242
|
controller,
|
|
243
243
|
component
|
|
244
244
|
} = args;
|
|
245
245
|
const language = resolveLanguage(request);
|
|
246
|
+
const availableLanguages = getAvailableLanguages(controller.model.def);
|
|
247
|
+
const languages = availableLanguages.length ? {
|
|
248
|
+
languages: availableLanguages
|
|
249
|
+
} : {};
|
|
250
|
+
const translator = await getCachedPluginTranslator(request, {
|
|
251
|
+
id: controller.model.formId
|
|
252
|
+
}, args.isLive ? FormStatus.Live : FormStatus.Draft, language);
|
|
253
|
+
const {
|
|
254
|
+
tComponent,
|
|
255
|
+
tForm
|
|
256
|
+
} = translator;
|
|
246
257
|
return dispatch(request, h, {
|
|
247
|
-
formName:
|
|
258
|
+
formName: tForm('title'),
|
|
259
|
+
formId: controller.model.formId,
|
|
260
|
+
formStatus: args.isLive ? FormStatus.Live : FormStatus.Draft,
|
|
261
|
+
componentId: component.id ?? 'unknown',
|
|
248
262
|
componentName: component.name,
|
|
249
|
-
componentHint: component
|
|
250
|
-
componentTitle: component
|
|
263
|
+
componentHint: tComponent(component, 'hint'),
|
|
264
|
+
componentTitle: tComponent(component, 'title') || controller.title,
|
|
251
265
|
step: args.actionArgs.step,
|
|
252
266
|
sourceUrl: args.sourceUrl,
|
|
253
|
-
language
|
|
267
|
+
language,
|
|
268
|
+
...languages
|
|
254
269
|
});
|
|
255
270
|
}
|
|
256
271
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UkAddressField.js","names":["ComponentType","lowerFirst","ComponentCollection","FormComponent","isFormState","TextField","dispatch","resolveLanguage","UkAddressField","constructor","def","props","name","options","isRequired","required","hideOptional","optionalText","hideTitle","collection","type","title","schema","classes","max","autocomplete","regex","parent","formSchema","stateSchema","getFormValueFromState","state","value","isState","undefined","getContextValueFromFormValue","Object","entries","filter","key","Boolean","map","getContextValueFromState","getDisplayStringFromFormValue","_translator","join","getDisplayStringFromState","translator","getViewErrors","errors","t","uniqueErrors","getErrors","error","index","self","findIndex","err","shouldUsePostcodeLookup","length","label","path","href","text","shortDescription","getViewModel","context","payload","viewModel","fieldset","hint","legend","id","attributes","components","uprn","at","Error","model","formGroup","usePostcodeLookup","isUkAddress","getAllPossibleErrors","ordnanceSurveyApiKey","baseErrors","template","advancedSettingsErrors","isText","addressLine1","town","postcode","dispatcher","request","h","args","controller","component","language","formName","componentName","componentHint","componentTitle","step","actionArgs","sourceUrl"],"sources":["../../../../../src/server/plugins/engine/components/UkAddressField.ts"],"sourcesContent":["import { ComponentType, type UkAddressFieldComponent } from '@defra/forms-model'\nimport { type ObjectSchema } from 'joi'\nimport lowerFirst from 'lodash/lowerFirst.js'\n\nimport { ComponentCollection } from '~/src/server/plugins/engine/components/ComponentCollection.js'\nimport {\n FormComponent,\n isFormState\n} from '~/src/server/plugins/engine/components/FormComponent.js'\nimport { TextField } from '~/src/server/plugins/engine/components/TextField.js'\nimport { type RenderContext } from '~/src/server/plugins/engine/components/types.js'\nimport { type Translator } from '~/src/server/plugins/engine/i18n/types.js'\nimport {\n type FormRequestPayload,\n type FormResponseToolkit\n} from '~/src/server/plugins/engine/types/index.js'\nimport {\n type ErrorMessageTemplateList,\n type FormPayload,\n type FormState,\n type FormStateValue,\n type FormSubmissionError,\n type FormSubmissionState,\n type PostcodeLookupExternalArgs\n} from '~/src/server/plugins/engine/types.js'\nimport { dispatch } from '~/src/server/plugins/postcode-lookup/routes/index.js'\nimport { resolveLanguage } from '~/src/server/utils/utils.js'\n\nexport class UkAddressField extends FormComponent {\n declare options: UkAddressFieldComponent['options']\n declare formSchema: ObjectSchema<FormPayload>\n declare stateSchema: ObjectSchema<FormState>\n declare collection: ComponentCollection\n\n constructor(\n def: UkAddressFieldComponent,\n props: ConstructorParameters<typeof FormComponent>[1]\n ) {\n super(def, props)\n\n const { name, options } = def\n\n const isRequired = options.required !== false\n const hideOptional = !!options.optionalText\n const hideTitle = !!options.hideTitle\n this.collection = new ComponentCollection(\n [\n {\n type: ComponentType.TextField,\n name: `${name}__uprn`,\n title: 'components.addressField.uprn',\n schema: {},\n options: {\n required: false,\n classes: 'hidden'\n }\n },\n {\n type: ComponentType.TextField,\n name: `${name}__addressLine1`,\n title: 'components.addressField.line1',\n schema: { max: 100 },\n options: {\n autocomplete: 'address-line1',\n required: isRequired,\n optionalText: !isRequired && (hideOptional || !hideTitle)\n }\n },\n {\n type: ComponentType.TextField,\n name: `${name}__addressLine2`,\n title: 'components.addressField.line2',\n schema: { max: 100 },\n options: {\n autocomplete: 'address-line2',\n required: false,\n optionalText: !isRequired && (hideOptional || !hideTitle)\n }\n },\n {\n type: ComponentType.TextField,\n name: `${name}__town`,\n title: 'components.addressField.town',\n schema: { max: 100 },\n options: {\n autocomplete: 'address-level2',\n classes: 'govuk-!-width-two-thirds',\n required: isRequired,\n optionalText: !isRequired && (hideOptional || !hideTitle)\n }\n },\n {\n type: ComponentType.TextField,\n name: `${name}__county`,\n title: 'components.addressField.county',\n schema: { max: 100 },\n options: {\n autocomplete: 'address-level1',\n required: false,\n optionalText: !isRequired && (hideOptional || !hideTitle)\n }\n },\n {\n type: ComponentType.TextField,\n name: `${name}__postcode`,\n title: 'components.addressField.postcode',\n schema: {\n regex: '^[a-zA-Z]{1,2}\\\\d[a-zA-Z\\\\d]?\\\\s?\\\\d[a-zA-Z]{2}$'\n },\n options: {\n autocomplete: 'postal-code',\n classes: 'govuk-input--width-10',\n required: isRequired,\n optionalText: !isRequired && (hideOptional || !hideTitle)\n }\n }\n ],\n { ...props, parent: this }\n )\n\n this.options = options\n this.formSchema = this.collection.formSchema\n this.stateSchema = this.collection.stateSchema\n }\n\n getFormValueFromState(state: FormSubmissionState) {\n const value = super.getFormValueFromState(state)\n return this.isState(value) ? value : undefined\n }\n\n getContextValueFromFormValue(value: UkAddressState | undefined) {\n if (!value) {\n return null\n }\n\n return Object.entries(value)\n .filter(([key, value]) => key !== 'uprn' && Boolean(value))\n .map(([, value]) => value)\n }\n\n getContextValueFromState(state: FormSubmissionState) {\n const value = this.getFormValueFromState(state)\n\n return this.getContextValueFromFormValue(value)\n }\n\n getDisplayStringFromFormValue(\n value: UkAddressState | undefined,\n _translator: Translator\n ): string {\n return this.getContextValueFromFormValue(value)?.join(', ') ?? ''\n }\n\n getDisplayStringFromState(\n state: FormSubmissionState,\n translator: Translator\n ) {\n const value = this.getFormValueFromState(state)\n\n return this.getDisplayStringFromFormValue(value, translator)\n }\n\n /**\n * Returns one error per child field\n */\n getViewErrors(\n translator: Translator,\n errors?: FormSubmissionError[]\n ): FormSubmissionError[] | undefined {\n const { t } = translator\n\n const uniqueErrors = this.getErrors(translator, errors)?.filter(\n (error, index, self) =>\n index === self.findIndex((err) => err.name === error.name)\n )\n\n // When using postcode lookup, the address fields are hidden\n // so we replace any individual validation messages with a single one\n if (this.shouldUsePostcodeLookup() && uniqueErrors?.length) {\n const { name, label } = this\n\n return [\n {\n name,\n path: [name],\n href: `#${name}`,\n text: t('components.addressField.enterAddress', {\n shortDescription: lowerFirst(label)\n })\n }\n ]\n }\n\n return uniqueErrors\n }\n\n getViewModel(context: RenderContext) {\n const { payload, translator } = context\n const { collection, name, options } = this\n\n const viewModel = super.getViewModel(context)\n let { fieldset, hint, label } = viewModel\n\n fieldset ??= {\n legend: {\n text: label.text,\n\n /**\n * For screen readers, only hide legend visually. This can be overridden\n * by single component {@link QuestionPageController | `showTitle` handling}\n */\n classes: options.hideTitle\n ? 'govuk-visually-hidden'\n : 'govuk-fieldset__legend--m'\n }\n }\n\n if (hint) {\n hint.id ??= `${name}-hint`\n fieldset.attributes ??= {\n 'aria-describedby': hint.id\n }\n }\n\n const components = collection.getViewModel(context)\n\n // Hide UPRN\n const uprn = components.at(0)\n\n if (!uprn) {\n throw new Error('No UPRN')\n }\n\n uprn.model.formGroup = { classes: 'app-hidden' }\n\n // Postcode lookup\n const usePostcodeLookup = this.shouldUsePostcodeLookup()\n\n const value = usePostcodeLookup\n ? this.getDisplayStringFromState(payload, translator)\n : undefined\n\n return {\n ...viewModel,\n value,\n fieldset,\n components,\n usePostcodeLookup\n }\n }\n\n isState(value?: FormStateValue | FormState): value is UkAddressState {\n return UkAddressField.isUkAddress(value)\n }\n\n /**\n * For error preview page that shows all possible errors on a component\n */\n getAllPossibleErrors(): ErrorMessageTemplateList {\n return UkAddressField.getAllPossibleErrors()\n }\n\n private shouldUsePostcodeLookup() {\n return !!(this.options.usePostcodeLookup && this.model.ordnanceSurveyApiKey)\n }\n\n /**\n * Static version of getAllPossibleErrors that doesn't require a component instance.\n */\n static getAllPossibleErrors(): ErrorMessageTemplateList {\n return {\n baseErrors: [\n { type: 'required', template: 'Enter address line 1' },\n { type: 'required', template: 'Enter town or city' },\n { type: 'required', template: 'Enter postcode' },\n { type: 'format', template: 'Enter valid postcode' }\n ],\n advancedSettingsErrors: []\n }\n }\n\n static isUkAddress(\n value?: FormStateValue | FormState\n ): value is UkAddressState {\n return (\n isFormState(value) &&\n TextField.isText(value.addressLine1) &&\n TextField.isText(value.town) &&\n TextField.isText(value.postcode)\n )\n }\n\n // eslint-disable-next-line @typescript-eslint/require-await\n static async dispatcher(\n request: FormRequestPayload,\n h: FormResponseToolkit,\n args: PostcodeLookupExternalArgs\n ) {\n const { controller, component } = args\n const language = resolveLanguage(request)\n\n return dispatch(request, h, {\n formName: controller.model.name,\n componentName: component.name,\n componentHint: component.hint,\n componentTitle: component.title || controller.title,\n step: args.actionArgs.step,\n sourceUrl: args.sourceUrl,\n language\n })\n }\n}\n\nexport interface UkAddressState extends Record<string, string> {\n uprn: string\n addressLine1: string\n addressLine2: string\n town: string\n county: string\n postcode: string\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"UkAddressField.js","names":["ComponentType","FormStatus","lowerFirst","ComponentCollection","FormComponent","isFormState","TextField","getCachedPluginTranslator","getAvailableLanguages","dispatch","resolveLanguage","UkAddressField","constructor","def","props","name","options","isRequired","required","hideOptional","optionalText","hideTitle","collection","type","title","schema","classes","max","autocomplete","regex","parent","formSchema","stateSchema","getFormValueFromState","state","value","isState","undefined","getContextValueFromFormValue","Object","entries","filter","key","Boolean","map","getContextValueFromState","getDisplayStringFromFormValue","_translator","join","getDisplayStringFromState","translator","getViewErrors","errors","t","uniqueErrors","getErrors","error","index","self","findIndex","err","shouldUsePostcodeLookup","length","label","path","href","text","shortDescription","getViewModel","context","payload","viewModel","fieldset","hint","legend","id","attributes","components","uprn","at","Error","model","formGroup","usePostcodeLookup","isUkAddress","getAllPossibleErrors","ordnanceSurveyApiKey","baseErrors","template","advancedSettingsErrors","isText","addressLine1","town","postcode","dispatcher","request","h","args","controller","component","language","availableLanguages","languages","formId","isLive","Live","Draft","tComponent","tForm","formName","formStatus","componentId","componentName","componentHint","componentTitle","step","actionArgs","sourceUrl"],"sources":["../../../../../src/server/plugins/engine/components/UkAddressField.ts"],"sourcesContent":["import {\n ComponentType,\n FormStatus,\n type FormMetadata,\n type UkAddressFieldComponent\n} from '@defra/forms-model'\nimport { type ObjectSchema } from 'joi'\nimport lowerFirst from 'lodash/lowerFirst.js'\n\nimport { ComponentCollection } from '~/src/server/plugins/engine/components/ComponentCollection.js'\nimport {\n FormComponent,\n isFormState\n} from '~/src/server/plugins/engine/components/FormComponent.js'\nimport { TextField } from '~/src/server/plugins/engine/components/TextField.js'\nimport { type RenderContext } from '~/src/server/plugins/engine/components/types.js'\nimport { getCachedPluginTranslator } from '~/src/server/plugins/engine/i18n/form.js'\nimport { getAvailableLanguages } from '~/src/server/plugins/engine/i18n/languages.js'\nimport { type Translator } from '~/src/server/plugins/engine/i18n/types.js'\nimport {\n type FormRequestPayload,\n type FormResponseToolkit\n} from '~/src/server/plugins/engine/types/index.js'\nimport {\n type ErrorMessageTemplateList,\n type FormPayload,\n type FormState,\n type FormStateValue,\n type FormSubmissionError,\n type FormSubmissionState,\n type PostcodeLookupExternalArgs\n} from '~/src/server/plugins/engine/types.js'\nimport { dispatch } from '~/src/server/plugins/postcode-lookup/routes/index.js'\nimport { resolveLanguage } from '~/src/server/utils/utils.js'\n\nexport class UkAddressField extends FormComponent {\n declare options: UkAddressFieldComponent['options']\n declare formSchema: ObjectSchema<FormPayload>\n declare stateSchema: ObjectSchema<FormState>\n declare collection: ComponentCollection\n\n constructor(\n def: UkAddressFieldComponent,\n props: ConstructorParameters<typeof FormComponent>[1]\n ) {\n super(def, props)\n\n const { name, options } = def\n\n const isRequired = options.required !== false\n const hideOptional = !!options.optionalText\n const hideTitle = !!options.hideTitle\n this.collection = new ComponentCollection(\n [\n {\n type: ComponentType.TextField,\n name: `${name}__uprn`,\n title: 'components.addressField.uprn',\n schema: {},\n options: {\n required: false,\n classes: 'hidden'\n }\n },\n {\n type: ComponentType.TextField,\n name: `${name}__addressLine1`,\n title: 'components.addressField.line1',\n schema: { max: 100 },\n options: {\n autocomplete: 'address-line1',\n required: isRequired,\n optionalText: !isRequired && (hideOptional || !hideTitle)\n }\n },\n {\n type: ComponentType.TextField,\n name: `${name}__addressLine2`,\n title: 'components.addressField.line2',\n schema: { max: 100 },\n options: {\n autocomplete: 'address-line2',\n required: false,\n optionalText: !isRequired && (hideOptional || !hideTitle)\n }\n },\n {\n type: ComponentType.TextField,\n name: `${name}__town`,\n title: 'components.addressField.town',\n schema: { max: 100 },\n options: {\n autocomplete: 'address-level2',\n classes: 'govuk-!-width-two-thirds',\n required: isRequired,\n optionalText: !isRequired && (hideOptional || !hideTitle)\n }\n },\n {\n type: ComponentType.TextField,\n name: `${name}__county`,\n title: 'components.addressField.county',\n schema: { max: 100 },\n options: {\n autocomplete: 'address-level1',\n required: false,\n optionalText: !isRequired && (hideOptional || !hideTitle)\n }\n },\n {\n type: ComponentType.TextField,\n name: `${name}__postcode`,\n title: 'components.addressField.postcode',\n schema: {\n regex: '^[a-zA-Z]{1,2}\\\\d[a-zA-Z\\\\d]?\\\\s?\\\\d[a-zA-Z]{2}$'\n },\n options: {\n autocomplete: 'postal-code',\n classes: 'govuk-input--width-10',\n required: isRequired,\n optionalText: !isRequired && (hideOptional || !hideTitle)\n }\n }\n ],\n { ...props, parent: this }\n )\n\n this.options = options\n this.formSchema = this.collection.formSchema\n this.stateSchema = this.collection.stateSchema\n }\n\n getFormValueFromState(state: FormSubmissionState) {\n const value = super.getFormValueFromState(state)\n return this.isState(value) ? value : undefined\n }\n\n getContextValueFromFormValue(value: UkAddressState | undefined) {\n if (!value) {\n return null\n }\n\n return Object.entries(value)\n .filter(([key, value]) => key !== 'uprn' && Boolean(value))\n .map(([, value]) => value)\n }\n\n getContextValueFromState(state: FormSubmissionState) {\n const value = this.getFormValueFromState(state)\n\n return this.getContextValueFromFormValue(value)\n }\n\n getDisplayStringFromFormValue(\n value: UkAddressState | undefined,\n _translator: Translator\n ): string {\n return this.getContextValueFromFormValue(value)?.join(', ') ?? ''\n }\n\n getDisplayStringFromState(\n state: FormSubmissionState,\n translator: Translator\n ) {\n const value = this.getFormValueFromState(state)\n\n return this.getDisplayStringFromFormValue(value, translator)\n }\n\n /**\n * Returns one error per child field\n */\n getViewErrors(\n translator: Translator,\n errors?: FormSubmissionError[]\n ): FormSubmissionError[] | undefined {\n const { t } = translator\n\n const uniqueErrors = this.getErrors(translator, errors)?.filter(\n (error, index, self) =>\n index === self.findIndex((err) => err.name === error.name)\n )\n\n // When using postcode lookup, the address fields are hidden\n // so we replace any individual validation messages with a single one\n if (this.shouldUsePostcodeLookup() && uniqueErrors?.length) {\n const { name, label } = this\n\n return [\n {\n name,\n path: [name],\n href: `#${name}`,\n text: t('components.addressField.enterAddress', {\n shortDescription: lowerFirst(label)\n })\n }\n ]\n }\n\n return uniqueErrors\n }\n\n getViewModel(context: RenderContext) {\n const { payload, translator } = context\n const { collection, name, options } = this\n\n const viewModel = super.getViewModel(context)\n let { fieldset, hint, label } = viewModel\n\n fieldset ??= {\n legend: {\n text: label.text,\n\n /**\n * For screen readers, only hide legend visually. This can be overridden\n * by single component (see QuestionPageController and showTitle handling)\n */\n classes: options.hideTitle\n ? 'govuk-visually-hidden'\n : 'govuk-fieldset__legend--m'\n }\n }\n\n if (hint) {\n hint.id ??= `${name}-hint`\n fieldset.attributes ??= {\n 'aria-describedby': hint.id\n }\n }\n\n const components = collection.getViewModel(context)\n\n // Hide UPRN\n const uprn = components.at(0)\n\n if (!uprn) {\n throw new Error('No UPRN')\n }\n\n uprn.model.formGroup = { classes: 'app-hidden' }\n\n // Postcode lookup\n const usePostcodeLookup = this.shouldUsePostcodeLookup()\n\n const value = usePostcodeLookup\n ? this.getDisplayStringFromState(payload, translator)\n : undefined\n\n return {\n ...viewModel,\n value,\n fieldset,\n components,\n usePostcodeLookup\n }\n }\n\n isState(value?: FormStateValue | FormState): value is UkAddressState {\n return UkAddressField.isUkAddress(value)\n }\n\n /**\n * For error preview page that shows all possible errors on a component\n */\n getAllPossibleErrors(): ErrorMessageTemplateList {\n return UkAddressField.getAllPossibleErrors()\n }\n\n private shouldUsePostcodeLookup() {\n return !!(this.options.usePostcodeLookup && this.model.ordnanceSurveyApiKey)\n }\n\n /**\n * Static version of getAllPossibleErrors that doesn't require a component instance.\n */\n static getAllPossibleErrors(): ErrorMessageTemplateList {\n return {\n baseErrors: [\n { type: 'required', template: 'Enter address line 1' },\n { type: 'required', template: 'Enter town or city' },\n { type: 'required', template: 'Enter postcode' },\n { type: 'format', template: 'Enter valid postcode' }\n ],\n advancedSettingsErrors: []\n }\n }\n\n static isUkAddress(\n value?: FormStateValue | FormState\n ): value is UkAddressState {\n return (\n isFormState(value) &&\n TextField.isText(value.addressLine1) &&\n TextField.isText(value.town) &&\n TextField.isText(value.postcode)\n )\n }\n\n static async dispatcher(\n request: FormRequestPayload,\n h: FormResponseToolkit,\n args: PostcodeLookupExternalArgs\n ) {\n const { controller, component } = args\n const language = resolveLanguage(request)\n\n const availableLanguages = getAvailableLanguages(controller.model.def)\n const languages = availableLanguages.length\n ? { languages: availableLanguages }\n : {}\n\n const translator = await getCachedPluginTranslator(\n request,\n { id: controller.model.formId } as unknown as FormMetadata,\n args.isLive ? FormStatus.Live : FormStatus.Draft,\n language\n )\n const { tComponent, tForm } = translator\n\n return dispatch(request, h, {\n formName: tForm('title'),\n formId: controller.model.formId,\n formStatus: args.isLive ? FormStatus.Live : FormStatus.Draft,\n componentId: component.id ?? 'unknown',\n componentName: component.name,\n componentHint: tComponent(component, 'hint'),\n componentTitle: tComponent(component, 'title') || controller.title,\n step: args.actionArgs.step,\n sourceUrl: args.sourceUrl,\n language,\n ...languages\n })\n }\n}\n\nexport interface UkAddressState extends Record<string, string> {\n uprn: string\n addressLine1: string\n addressLine2: string\n town: string\n county: string\n postcode: string\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { type YesNoFieldComponent } from '@defra/forms-model';
|
|
2
|
-
import { type LanguageMessages } from 'joi';
|
|
3
2
|
import { SelectionControlField } from '../../../../server/plugins/engine/components/SelectionControlField.js';
|
|
4
3
|
import { type Translator } from '../../../../server/plugins/engine/i18n/types.js';
|
|
5
4
|
import { type ErrorMessageTemplateList } from '../../../../server/plugins/engine/types.js';
|
|
@@ -10,7 +9,9 @@ import { type ErrorMessageTemplateList } from '../../../../server/plugins/engine
|
|
|
10
9
|
export declare class YesNoField extends SelectionControlField {
|
|
11
10
|
options: YesNoFieldComponent['options'];
|
|
12
11
|
constructor(def: YesNoFieldComponent, props: ConstructorParameters<typeof SelectionControlField>[1]);
|
|
13
|
-
getValidationMessagesOverride(translator: Translator):
|
|
12
|
+
getValidationMessagesOverride(translator: Translator): {
|
|
13
|
+
[x: string]: import("joi").LanguageMessages;
|
|
14
|
+
};
|
|
14
15
|
/**
|
|
15
16
|
* For error preview page that shows all possible errors on a component
|
|
16
17
|
*/
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import { SchemaVersion, yesNoListId, yesNoListName } from '@defra/forms-model';
|
|
2
2
|
import { SelectionControlField } from "./SelectionControlField.js";
|
|
3
|
-
import { addClassOptionIfNone } from "./helpers/index.js";
|
|
3
|
+
import { addClassOptionIfNone, withCustomValidationOverrides } from "./helpers/index.js";
|
|
4
4
|
import { buildValidationMessages } from "../i18n/buildValidationMessages.js";
|
|
5
5
|
import { messageTemplate } from "../pageControllers/validationOptions.js";
|
|
6
|
-
import { convertToLanguageMessages } from "../../../utils/type-utils.js";
|
|
7
|
-
|
|
8
6
|
/**
|
|
9
7
|
* @description
|
|
10
8
|
* YesNoField is a radiosField with predefined values.
|
|
@@ -25,19 +23,35 @@ export class YesNoField extends SelectionControlField {
|
|
|
25
23
|
if (options.required === false) {
|
|
26
24
|
formSchema = formSchema.optional();
|
|
27
25
|
}
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
26
|
+
if (options.customValidationMessage) {
|
|
27
|
+
const message = options.customValidationMessage;
|
|
28
|
+
formSchema = formSchema.messages({
|
|
29
|
+
'any.required': message
|
|
30
|
+
});
|
|
31
|
+
} else if (options.customValidationMessages) {
|
|
32
|
+
formSchema = formSchema.messages(options.customValidationMessages);
|
|
33
|
+
} else {
|
|
34
|
+
formSchema = formSchema.messages({
|
|
35
|
+
'any.required': messageTemplate.selectYesNoRequired
|
|
36
|
+
});
|
|
37
|
+
}
|
|
31
38
|
this.formSchema = formSchema;
|
|
32
39
|
this.options = options;
|
|
33
40
|
}
|
|
34
41
|
getValidationMessagesOverride(translator) {
|
|
42
|
+
const {
|
|
43
|
+
customValidationMessage,
|
|
44
|
+
customValidationMessages
|
|
45
|
+
} = this.options;
|
|
35
46
|
const {
|
|
36
47
|
selectYesNoRequired
|
|
37
48
|
} = buildValidationMessages(translator.t);
|
|
38
|
-
|
|
49
|
+
const defaults = {
|
|
39
50
|
'any.required': selectYesNoRequired
|
|
40
|
-
}
|
|
51
|
+
};
|
|
52
|
+
return {
|
|
53
|
+
[this.name]: withCustomValidationOverrides(defaults, customValidationMessage, customValidationMessages)
|
|
54
|
+
};
|
|
41
55
|
}
|
|
42
56
|
|
|
43
57
|
/**
|