@defra/forms-engine-plugin 0.0.1
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/.browserslistrc +16 -0
- package/.editorconfig +9 -0
- package/.eslintrc.cjs +266 -0
- package/.github/dependabot.yml +85 -0
- package/.github/workflows/check-pull-request.yml +209 -0
- package/.github/workflows/pr-notifier.yml +98 -0
- package/.github/workflows/publish.yml +111 -0
- package/.husky/pre-commit +1 -0
- package/.lintstagedrc.js +4 -0
- package/.nvmrc +1 -0
- package/.prettierignore +8 -0
- package/.prettierrc.cjs +26 -0
- package/.server/client/javascripts/application.js +68 -0
- package/.server/client/javascripts/application.js.map +1 -0
- package/.server/client/javascripts/file-upload.js +292 -0
- package/.server/client/javascripts/file-upload.js.map +1 -0
- package/.server/client/stylesheets/_code.scss +33 -0
- package/.server/client/stylesheets/_govuk-frontend.scss +4 -0
- package/.server/client/stylesheets/_prose.scss +56 -0
- package/.server/client/stylesheets/_service-banner.scss +24 -0
- package/.server/client/stylesheets/_summary-list.scss +28 -0
- package/.server/client/stylesheets/_tag-env.scss +24 -0
- package/.server/client/stylesheets/application.scss +14 -0
- package/.server/common/cookies.js +55 -0
- package/.server/common/cookies.js.map +1 -0
- package/.server/common/cookies.test.js +15 -0
- package/.server/common/cookies.test.js.map +1 -0
- package/.server/common/types.js +6 -0
- package/.server/common/types.js.map +1 -0
- package/.server/config/index.js +241 -0
- package/.server/config/index.js.map +1 -0
- package/.server/index.js +25 -0
- package/.server/index.js.map +1 -0
- package/.server/server/common/helpers/logging/logger-options.js +44 -0
- package/.server/server/common/helpers/logging/logger-options.js.map +1 -0
- package/.server/server/common/helpers/logging/logger.js +6 -0
- package/.server/server/common/helpers/logging/logger.js.map +1 -0
- package/.server/server/common/helpers/logging/request-logger.js +7 -0
- package/.server/server/common/helpers/logging/request-logger.js.map +1 -0
- package/.server/server/common/helpers/logging/request-tracing.js +12 -0
- package/.server/server/common/helpers/logging/request-tracing.js.map +1 -0
- package/.server/server/common/helpers/redis-client.js +55 -0
- package/.server/server/common/helpers/redis-client.js.map +1 -0
- package/.server/server/constants.js +2 -0
- package/.server/server/constants.js.map +1 -0
- package/.server/server/forms/README.md +10 -0
- package/.server/server/forms/components.json +1015 -0
- package/.server/server/forms/report-a-terrorist.json +270 -0
- package/.server/server/forms/runner-components-test.json +365 -0
- package/.server/server/forms/test.json +581 -0
- package/.server/server/index.js +116 -0
- package/.server/server/index.js.map +1 -0
- package/.server/server/plugins/blankie.js +29 -0
- package/.server/server/plugins/blankie.js.map +1 -0
- package/.server/server/plugins/crumb.js +15 -0
- package/.server/server/plugins/crumb.js.map +1 -0
- package/.server/server/plugins/engine/README.md +87 -0
- package/.server/server/plugins/engine/components/AutocompleteField.js +37 -0
- package/.server/server/plugins/engine/components/AutocompleteField.js.map +1 -0
- package/.server/server/plugins/engine/components/CheckboxesField.js +79 -0
- package/.server/server/plugins/engine/components/CheckboxesField.js.map +1 -0
- package/.server/server/plugins/engine/components/ComponentBase.js +55 -0
- package/.server/server/plugins/engine/components/ComponentBase.js.map +1 -0
- package/.server/server/plugins/engine/components/ComponentCollection.js +198 -0
- package/.server/server/plugins/engine/components/ComponentCollection.js.map +1 -0
- package/.server/server/plugins/engine/components/DatePartsField.js +208 -0
- package/.server/server/plugins/engine/components/DatePartsField.js.map +1 -0
- package/.server/server/plugins/engine/components/Details.js +26 -0
- package/.server/server/plugins/engine/components/Details.js.map +1 -0
- package/.server/server/plugins/engine/components/EmailAddressField.js +40 -0
- package/.server/server/plugins/engine/components/EmailAddressField.js.map +1 -0
- package/.server/server/plugins/engine/components/FileUploadField.js +195 -0
- package/.server/server/plugins/engine/components/FileUploadField.js.map +1 -0
- package/.server/server/plugins/engine/components/FormComponent.js +210 -0
- package/.server/server/plugins/engine/components/FormComponent.js.map +1 -0
- package/.server/server/plugins/engine/components/Html.js +24 -0
- package/.server/server/plugins/engine/components/Html.js.map +1 -0
- package/.server/server/plugins/engine/components/InsetText.js +22 -0
- package/.server/server/plugins/engine/components/InsetText.js.map +1 -0
- package/.server/server/plugins/engine/components/List.js +65 -0
- package/.server/server/plugins/engine/components/List.js.map +1 -0
- package/.server/server/plugins/engine/components/ListFormComponent.js +87 -0
- package/.server/server/plugins/engine/components/ListFormComponent.js.map +1 -0
- package/.server/server/plugins/engine/components/MonthYearField.js +172 -0
- package/.server/server/plugins/engine/components/MonthYearField.js.map +1 -0
- package/.server/server/plugins/engine/components/MultilineTextField.js +115 -0
- package/.server/server/plugins/engine/components/MultilineTextField.js.map +1 -0
- package/.server/server/plugins/engine/components/NumberField.js +137 -0
- package/.server/server/plugins/engine/components/NumberField.js.map +1 -0
- package/.server/server/plugins/engine/components/RadiosField.js +18 -0
- package/.server/server/plugins/engine/components/RadiosField.js.map +1 -0
- package/.server/server/plugins/engine/components/SelectField.js +33 -0
- package/.server/server/plugins/engine/components/SelectField.js.map +1 -0
- package/.server/server/plugins/engine/components/SelectionControlField.js +43 -0
- package/.server/server/plugins/engine/components/SelectionControlField.js.map +1 -0
- package/.server/server/plugins/engine/components/TelephoneNumberField.js +43 -0
- package/.server/server/plugins/engine/components/TelephoneNumberField.js.map +1 -0
- package/.server/server/plugins/engine/components/TextField.js +63 -0
- package/.server/server/plugins/engine/components/TextField.js.map +1 -0
- package/.server/server/plugins/engine/components/UkAddressField.js +130 -0
- package/.server/server/plugins/engine/components/UkAddressField.js.map +1 -0
- package/.server/server/plugins/engine/components/YesNoField.js +28 -0
- package/.server/server/plugins/engine/components/YesNoField.js.map +1 -0
- package/.server/server/plugins/engine/components/constants.js +2 -0
- package/.server/server/plugins/engine/components/constants.js.map +1 -0
- package/.server/server/plugins/engine/components/helpers.js +219 -0
- package/.server/server/plugins/engine/components/helpers.js.map +1 -0
- package/.server/server/plugins/engine/components/index.js +25 -0
- package/.server/server/plugins/engine/components/index.js.map +1 -0
- package/.server/server/plugins/engine/components/types.js +2 -0
- package/.server/server/plugins/engine/components/types.js.map +1 -0
- package/.server/server/plugins/engine/configureEnginePlugin.js +44 -0
- package/.server/server/plugins/engine/configureEnginePlugin.js.map +1 -0
- package/.server/server/plugins/engine/helpers.js +268 -0
- package/.server/server/plugins/engine/helpers.js.map +1 -0
- package/.server/server/plugins/engine/index.js +6 -0
- package/.server/server/plugins/engine/index.js.map +1 -0
- package/.server/server/plugins/engine/models/FormModel.js +363 -0
- package/.server/server/plugins/engine/models/FormModel.js.map +1 -0
- package/.server/server/plugins/engine/models/RepeatingSummaryViewModel.js +2 -0
- package/.server/server/plugins/engine/models/RepeatingSummaryViewModel.js.map +1 -0
- package/.server/server/plugins/engine/models/Section.js +2 -0
- package/.server/server/plugins/engine/models/Section.js.map +1 -0
- package/.server/server/plugins/engine/models/SummaryViewModel.js +183 -0
- package/.server/server/plugins/engine/models/SummaryViewModel.js.map +1 -0
- package/.server/server/plugins/engine/models/index.js +3 -0
- package/.server/server/plugins/engine/models/index.js.map +1 -0
- package/.server/server/plugins/engine/models/types.js +2 -0
- package/.server/server/plugins/engine/models/types.js.map +1 -0
- package/.server/server/plugins/engine/outputFormatters/human/v1.js +44 -0
- package/.server/server/plugins/engine/outputFormatters/human/v1.js.map +1 -0
- package/.server/server/plugins/engine/outputFormatters/index.js +24 -0
- package/.server/server/plugins/engine/outputFormatters/index.js.map +1 -0
- package/.server/server/plugins/engine/outputFormatters/machine/v1.js +104 -0
- package/.server/server/plugins/engine/outputFormatters/machine/v1.js.map +1 -0
- package/.server/server/plugins/engine/outputFormatters/machine/v2.js +110 -0
- package/.server/server/plugins/engine/outputFormatters/machine/v2.js.map +1 -0
- package/.server/server/plugins/engine/pageControllers/FileUploadPageController.js +401 -0
- package/.server/server/plugins/engine/pageControllers/FileUploadPageController.js.map +1 -0
- package/.server/server/plugins/engine/pageControllers/PageController.js +133 -0
- package/.server/server/plugins/engine/pageControllers/PageController.js.map +1 -0
- package/.server/server/plugins/engine/pageControllers/QuestionPageController.js +482 -0
- package/.server/server/plugins/engine/pageControllers/QuestionPageController.js.map +1 -0
- package/.server/server/plugins/engine/pageControllers/README.md +28 -0
- package/.server/server/plugins/engine/pageControllers/RepeatPageController.js +372 -0
- package/.server/server/plugins/engine/pageControllers/RepeatPageController.js.map +1 -0
- package/.server/server/plugins/engine/pageControllers/StartPageController.js +16 -0
- package/.server/server/plugins/engine/pageControllers/StartPageController.js.map +1 -0
- package/.server/server/plugins/engine/pageControllers/StatusPageController.js +43 -0
- package/.server/server/plugins/engine/pageControllers/StatusPageController.js.map +1 -0
- package/.server/server/plugins/engine/pageControllers/SummaryPageController.js +195 -0
- package/.server/server/plugins/engine/pageControllers/SummaryPageController.js.map +1 -0
- package/.server/server/plugins/engine/pageControllers/TerminalPageController.js +8 -0
- package/.server/server/plugins/engine/pageControllers/TerminalPageController.js.map +1 -0
- package/.server/server/plugins/engine/pageControllers/helpers.js +69 -0
- package/.server/server/plugins/engine/pageControllers/helpers.js.map +1 -0
- package/.server/server/plugins/engine/pageControllers/index.js +10 -0
- package/.server/server/plugins/engine/pageControllers/index.js.map +1 -0
- package/.server/server/plugins/engine/pageControllers/validationOptions.js +78 -0
- package/.server/server/plugins/engine/pageControllers/validationOptions.js.map +1 -0
- package/.server/server/plugins/engine/plugin.js +562 -0
- package/.server/server/plugins/engine/plugin.js.map +1 -0
- package/.server/server/plugins/engine/services/formSubmissionService.js +39 -0
- package/.server/server/plugins/engine/services/formSubmissionService.js.map +1 -0
- package/.server/server/plugins/engine/services/formsService.js +41 -0
- package/.server/server/plugins/engine/services/formsService.js.map +1 -0
- package/.server/server/plugins/engine/services/formsService.test.js +71 -0
- package/.server/server/plugins/engine/services/formsService.test.js.map +1 -0
- package/.server/server/plugins/engine/services/index.js +4 -0
- package/.server/server/plugins/engine/services/index.js.map +1 -0
- package/.server/server/plugins/engine/services/notifyService.js +45 -0
- package/.server/server/plugins/engine/services/notifyService.js.map +1 -0
- package/.server/server/plugins/engine/services/uploadService.js +51 -0
- package/.server/server/plugins/engine/services/uploadService.js.map +1 -0
- package/.server/server/plugins/engine/types.js +53 -0
- package/.server/server/plugins/engine/types.js.map +1 -0
- package/.server/server/plugins/engine/views/components/autocompletefield.html +5 -0
- package/.server/server/plugins/engine/views/components/checkboxesfield.html +5 -0
- package/.server/server/plugins/engine/views/components/datepartsfield.html +5 -0
- package/.server/server/plugins/engine/views/components/details.html +6 -0
- package/.server/server/plugins/engine/views/components/emailaddressfield.html +5 -0
- package/.server/server/plugins/engine/views/components/fileuploadfield-key.html +8 -0
- package/.server/server/plugins/engine/views/components/fileuploadfield-value.html +3 -0
- package/.server/server/plugins/engine/views/components/fileuploadfield.html +24 -0
- package/.server/server/plugins/engine/views/components/html.html +3 -0
- package/.server/server/plugins/engine/views/components/insettext.html +7 -0
- package/.server/server/plugins/engine/views/components/list.html +36 -0
- package/.server/server/plugins/engine/views/components/monthyearfield.html +5 -0
- package/.server/server/plugins/engine/views/components/multilinetextfield.html +10 -0
- package/.server/server/plugins/engine/views/components/numberfield.html +5 -0
- package/.server/server/plugins/engine/views/components/radiosfield.html +5 -0
- package/.server/server/plugins/engine/views/components/selectfield.html +5 -0
- package/.server/server/plugins/engine/views/components/telephonenumberfield.html +5 -0
- package/.server/server/plugins/engine/views/components/textfield.html +5 -0
- package/.server/server/plugins/engine/views/components/ukaddressfield.html +25 -0
- package/.server/server/plugins/engine/views/components/yesnofield.html +5 -0
- package/.server/server/plugins/engine/views/file-upload.html +45 -0
- package/.server/server/plugins/engine/views/index.html +39 -0
- package/.server/server/plugins/engine/views/item-delete.html +56 -0
- package/.server/server/plugins/engine/views/partials/components.html +6 -0
- package/.server/server/plugins/engine/views/partials/conditional-components.html +3 -0
- package/.server/server/plugins/engine/views/partials/debug.html +44 -0
- package/.server/server/plugins/engine/views/partials/form.html +15 -0
- package/.server/server/plugins/engine/views/partials/heading.html +16 -0
- package/.server/server/plugins/engine/views/partials/preview-banner.html +32 -0
- package/.server/server/plugins/engine/views/partials/preview-banner.test.js +108 -0
- package/.server/server/plugins/engine/views/partials/preview-banner.test.js.map +1 -0
- package/.server/server/plugins/engine/views/partials/warn-missing-notification-email.html +10 -0
- package/.server/server/plugins/engine/views/repeat-list-summary.html +53 -0
- package/.server/server/plugins/errorPages.js +49 -0
- package/.server/server/plugins/errorPages.js.map +1 -0
- package/.server/server/plugins/nunjucks/context.js +79 -0
- package/.server/server/plugins/nunjucks/context.js.map +1 -0
- package/.server/server/plugins/nunjucks/context.test.js +134 -0
- package/.server/server/plugins/nunjucks/context.test.js.map +1 -0
- package/.server/server/plugins/nunjucks/enviroment.test.js +166 -0
- package/.server/server/plugins/nunjucks/enviroment.test.js.map +1 -0
- package/.server/server/plugins/nunjucks/environment.js +95 -0
- package/.server/server/plugins/nunjucks/environment.js.map +1 -0
- package/.server/server/plugins/nunjucks/filters/answer.js +26 -0
- package/.server/server/plugins/nunjucks/filters/answer.js.map +1 -0
- package/.server/server/plugins/nunjucks/filters/answer.test.js +70 -0
- package/.server/server/plugins/nunjucks/filters/answer.test.js.map +1 -0
- package/.server/server/plugins/nunjucks/filters/evaluate.js +22 -0
- package/.server/server/plugins/nunjucks/filters/evaluate.js.map +1 -0
- package/.server/server/plugins/nunjucks/filters/field.js +26 -0
- package/.server/server/plugins/nunjucks/filters/field.js.map +1 -0
- package/.server/server/plugins/nunjucks/filters/field.test.js +64 -0
- package/.server/server/plugins/nunjucks/filters/field.test.js.map +1 -0
- package/.server/server/plugins/nunjucks/filters/highlight.js +14 -0
- package/.server/server/plugins/nunjucks/filters/highlight.js.map +1 -0
- package/.server/server/plugins/nunjucks/filters/href.js +28 -0
- package/.server/server/plugins/nunjucks/filters/href.js.map +1 -0
- package/.server/server/plugins/nunjucks/filters/href.test.js +63 -0
- package/.server/server/plugins/nunjucks/filters/href.test.js.map +1 -0
- package/.server/server/plugins/nunjucks/filters/index.js +9 -0
- package/.server/server/plugins/nunjucks/filters/index.js.map +1 -0
- package/.server/server/plugins/nunjucks/filters/inspect.js +16 -0
- package/.server/server/plugins/nunjucks/filters/inspect.js.map +1 -0
- package/.server/server/plugins/nunjucks/filters/page.js +23 -0
- package/.server/server/plugins/nunjucks/filters/page.js.map +1 -0
- package/.server/server/plugins/nunjucks/filters/page.test.js +51 -0
- package/.server/server/plugins/nunjucks/filters/page.test.js.map +1 -0
- package/.server/server/plugins/nunjucks/index.js +4 -0
- package/.server/server/plugins/nunjucks/index.js.map +1 -0
- package/.server/server/plugins/nunjucks/plugin.js +38 -0
- package/.server/server/plugins/nunjucks/plugin.js.map +1 -0
- package/.server/server/plugins/nunjucks/render.js +41 -0
- package/.server/server/plugins/nunjucks/render.js.map +1 -0
- package/.server/server/plugins/nunjucks/types.js +41 -0
- package/.server/server/plugins/nunjucks/types.js.map +1 -0
- package/.server/server/plugins/pulse.js +8 -0
- package/.server/server/plugins/pulse.js.map +1 -0
- package/.server/server/plugins/router.js +169 -0
- package/.server/server/plugins/router.js.map +1 -0
- package/.server/server/plugins/session.js +28 -0
- package/.server/server/plugins/session.js.map +1 -0
- package/.server/server/routes/health.js +15 -0
- package/.server/server/routes/health.js.map +1 -0
- package/.server/server/routes/health.test.js +32 -0
- package/.server/server/routes/health.test.js.map +1 -0
- package/.server/server/routes/index.js +3 -0
- package/.server/server/routes/index.js.map +1 -0
- package/.server/server/routes/public.js +37 -0
- package/.server/server/routes/public.js.map +1 -0
- package/.server/server/routes/types.js +14 -0
- package/.server/server/routes/types.js.map +1 -0
- package/.server/server/schemas/index.js +15 -0
- package/.server/server/schemas/index.js.map +1 -0
- package/.server/server/secure-context.js +36 -0
- package/.server/server/secure-context.js.map +1 -0
- package/.server/server/services/cacheService.js +85 -0
- package/.server/server/services/cacheService.js.map +1 -0
- package/.server/server/services/httpService.js +44 -0
- package/.server/server/services/httpService.js.map +1 -0
- package/.server/server/services/httpService.test.js +504 -0
- package/.server/server/services/httpService.test.js.map +1 -0
- package/.server/server/services/index.js +2 -0
- package/.server/server/services/index.js.map +1 -0
- package/.server/server/types.js +2 -0
- package/.server/server/types.js.map +1 -0
- package/.server/server/utils/notify.js +40 -0
- package/.server/server/utils/notify.js.map +1 -0
- package/.server/server/utils/secure-context/get-trust-store-certs.js +7 -0
- package/.server/server/utils/secure-context/get-trust-store-certs.js.map +1 -0
- package/.server/server/utils/secure-context/get-trust-store-certs.test.js +14 -0
- package/.server/server/utils/secure-context/get-trust-store-certs.test.js.map +1 -0
- package/.server/server/utils/utils.js +20 -0
- package/.server/server/utils/utils.js.map +1 -0
- package/.server/server/utils/utils.test.js +49 -0
- package/.server/server/utils/utils.test.js.map +1 -0
- package/.server/server/views/404.html +16 -0
- package/.server/server/views/500.html +19 -0
- package/.server/server/views/components/debug/macro.njk +3 -0
- package/.server/server/views/components/debug/template.njk +13 -0
- package/.server/server/views/components/service-banner/macro.njk +3 -0
- package/.server/server/views/components/service-banner/template.njk +20 -0
- package/.server/server/views/components/service-banner/template.test.js +36 -0
- package/.server/server/views/components/service-banner/template.test.js.map +1 -0
- package/.server/server/views/components/tag-env/macro.njk +3 -0
- package/.server/server/views/components/tag-env/template.njk +30 -0
- package/.server/server/views/components/tag-env/template.test.js +59 -0
- package/.server/server/views/components/tag-env/template.test.js.map +1 -0
- package/.server/server/views/confirmation.html +19 -0
- package/.server/server/views/help/accessibility-statement.html +58 -0
- package/.server/server/views/help/cookie-preferences.html +57 -0
- package/.server/server/views/help/cookies.html +71 -0
- package/.server/server/views/help/get-support.html +37 -0
- package/.server/server/views/help/privacy-notice.html +68 -0
- package/.server/server/views/help/terms-and-conditions.html +83 -0
- package/.server/server/views/layout.html +199 -0
- package/.server/server/views/summary.html +50 -0
- package/.server/typings/hapi/index.d.js +2 -0
- package/.server/typings/hapi/index.d.js.map +1 -0
- package/.server/typings/hapi-tracing/index.d.js +2 -0
- package/.server/typings/hapi-tracing/index.d.js.map +1 -0
- package/.server/typings/index.d.js +2 -0
- package/.server/typings/index.d.js.map +1 -0
- package/.server/typings/joi/index.d.js +2 -0
- package/.server/typings/joi/index.d.js.map +1 -0
- package/Dockerfile +61 -0
- package/LICENCE +8 -0
- package/Procfile +1 -0
- package/README.md +87 -0
- package/babel.config.cjs +55 -0
- package/compose/aws.env +4 -0
- package/compose/start-localstack.sh +26 -0
- package/docker-compose.yaml +86 -0
- package/globals.d.ts +1 -0
- package/jest.config.cjs +54 -0
- package/jest.environment.js +4 -0
- package/jest.setup.cjs +14 -0
- package/package.json +163 -0
- package/postcss.config.js +26 -0
- package/sonar-project.properties +17 -0
- package/src/client/javascripts/application.js +87 -0
- package/src/client/javascripts/file-upload.js +386 -0
- package/src/client/stylesheets/_code.scss +33 -0
- package/src/client/stylesheets/_govuk-frontend.scss +4 -0
- package/src/client/stylesheets/_prose.scss +56 -0
- package/src/client/stylesheets/_service-banner.scss +24 -0
- package/src/client/stylesheets/_summary-list.scss +28 -0
- package/src/client/stylesheets/_tag-env.scss +24 -0
- package/src/client/stylesheets/application.scss +14 -0
- package/src/common/cookies.js +58 -0
- package/src/common/cookies.test.js +23 -0
- package/src/common/types.js +5 -0
- package/src/config/index.ts +271 -0
- package/src/index.ts +31 -0
- package/src/server/common/helpers/logging/logger-options.test.ts +50 -0
- package/src/server/common/helpers/logging/logger-options.ts +46 -0
- package/src/server/common/helpers/logging/logger.ts +7 -0
- package/src/server/common/helpers/logging/request-logger.ts +9 -0
- package/src/server/common/helpers/logging/request-tracing.js +10 -0
- package/src/server/common/helpers/redis-client.js +70 -0
- package/src/server/constants.js +1 -0
- package/src/server/forms/README.md +10 -0
- package/src/server/forms/components.json +1015 -0
- package/src/server/forms/report-a-terrorist.json +270 -0
- package/src/server/forms/runner-components-test.json +365 -0
- package/src/server/forms/test.json +581 -0
- package/src/server/index.test.ts +582 -0
- package/src/server/index.ts +140 -0
- package/src/server/plugins/blankie.test.ts +73 -0
- package/src/server/plugins/blankie.ts +48 -0
- package/src/server/plugins/crumb.ts +20 -0
- package/src/server/plugins/engine/README.md +87 -0
- package/src/server/plugins/engine/components/AutocompleteField.test.ts +294 -0
- package/src/server/plugins/engine/components/AutocompleteField.ts +49 -0
- package/src/server/plugins/engine/components/CheckboxesField.test.ts +379 -0
- package/src/server/plugins/engine/components/CheckboxesField.ts +106 -0
- package/src/server/plugins/engine/components/ComponentBase.ts +97 -0
- package/src/server/plugins/engine/components/ComponentCollection.ts +278 -0
- package/src/server/plugins/engine/components/DatePartsField.test.ts +822 -0
- package/src/server/plugins/engine/components/DatePartsField.ts +264 -0
- package/src/server/plugins/engine/components/Details.test.ts +49 -0
- package/src/server/plugins/engine/components/Details.ts +30 -0
- package/src/server/plugins/engine/components/EmailAddressField.test.ts +395 -0
- package/src/server/plugins/engine/components/EmailAddressField.ts +55 -0
- package/src/server/plugins/engine/components/FileUploadField.test.ts +778 -0
- package/src/server/plugins/engine/components/FileUploadField.ts +262 -0
- package/src/server/plugins/engine/components/FormComponent.ts +249 -0
- package/src/server/plugins/engine/components/Html.test.ts +48 -0
- package/src/server/plugins/engine/components/Html.ts +29 -0
- package/src/server/plugins/engine/components/InsetText.test.ts +48 -0
- package/src/server/plugins/engine/components/InsetText.ts +27 -0
- package/src/server/plugins/engine/components/List.test.ts +76 -0
- package/src/server/plugins/engine/components/List.ts +72 -0
- package/src/server/plugins/engine/components/ListFormComponent.ts +140 -0
- package/src/server/plugins/engine/components/MonthYearField.test.ts +567 -0
- package/src/server/plugins/engine/components/MonthYearField.ts +222 -0
- package/src/server/plugins/engine/components/MultilineTextField.test.ts +558 -0
- package/src/server/plugins/engine/components/MultilineTextField.ts +138 -0
- package/src/server/plugins/engine/components/NumberField.test.ts +701 -0
- package/src/server/plugins/engine/components/NumberField.ts +163 -0
- package/src/server/plugins/engine/components/RadiosField.test.ts +288 -0
- package/src/server/plugins/engine/components/RadiosField.ts +24 -0
- package/src/server/plugins/engine/components/SelectField.test.ts +288 -0
- package/src/server/plugins/engine/components/SelectField.ts +47 -0
- package/src/server/plugins/engine/components/SelectionControlField.ts +43 -0
- package/src/server/plugins/engine/components/TelephoneNumberField.test.ts +356 -0
- package/src/server/plugins/engine/components/TelephoneNumberField.ts +67 -0
- package/src/server/plugins/engine/components/TextField.test.ts +489 -0
- package/src/server/plugins/engine/components/TextField.ts +96 -0
- package/src/server/plugins/engine/components/UkAddressField.test.ts +623 -0
- package/src/server/plugins/engine/components/UkAddressField.ts +172 -0
- package/src/server/plugins/engine/components/YesNoField.test.ts +248 -0
- package/src/server/plugins/engine/components/YesNoField.ts +31 -0
- package/src/server/plugins/engine/components/constants.ts +1 -0
- package/src/server/plugins/engine/components/helpers.ts +330 -0
- package/src/server/plugins/engine/components/index.ts +24 -0
- package/src/server/plugins/engine/components/types.ts +117 -0
- package/src/server/plugins/engine/configureEnginePlugin.ts +47 -0
- package/src/server/plugins/engine/helpers.test.ts +791 -0
- package/src/server/plugins/engine/helpers.ts +379 -0
- package/src/server/plugins/engine/index.ts +7 -0
- package/src/server/plugins/engine/models/FormModel.test.ts +42 -0
- package/src/server/plugins/engine/models/FormModel.ts +443 -0
- package/src/server/plugins/engine/models/RepeatingSummaryViewModel.ts +0 -0
- package/src/server/plugins/engine/models/Section.ts +0 -0
- package/src/server/plugins/engine/models/SummaryViewModel.test.ts +209 -0
- package/src/server/plugins/engine/models/SummaryViewModel.ts +220 -0
- package/src/server/plugins/engine/models/index.ts +2 -0
- package/src/server/plugins/engine/models/types.ts +114 -0
- package/src/server/plugins/engine/outputFormatters/human/v1.test.ts +143 -0
- package/src/server/plugins/engine/outputFormatters/human/v1.ts +73 -0
- package/src/server/plugins/engine/outputFormatters/index.test.ts +17 -0
- package/src/server/plugins/engine/outputFormatters/index.ts +44 -0
- package/src/server/plugins/engine/outputFormatters/machine/v1.test.ts +229 -0
- package/src/server/plugins/engine/outputFormatters/machine/v1.ts +140 -0
- package/src/server/plugins/engine/outputFormatters/machine/v2.test.ts +229 -0
- package/src/server/plugins/engine/outputFormatters/machine/v2.ts +153 -0
- package/src/server/plugins/engine/pageControllers/FileUploadPageController.test.ts +1108 -0
- package/src/server/plugins/engine/pageControllers/FileUploadPageController.ts +446 -0
- package/src/server/plugins/engine/pageControllers/PageController.test.ts +205 -0
- package/src/server/plugins/engine/pageControllers/PageController.ts +176 -0
- package/src/server/plugins/engine/pageControllers/QuestionPageController.test.ts +1264 -0
- package/src/server/plugins/engine/pageControllers/QuestionPageController.ts +561 -0
- package/src/server/plugins/engine/pageControllers/README.md +28 -0
- package/src/server/plugins/engine/pageControllers/RepeatPageController.test.ts +264 -0
- package/src/server/plugins/engine/pageControllers/RepeatPageController.ts +458 -0
- package/src/server/plugins/engine/pageControllers/StartPageController.ts +18 -0
- package/src/server/plugins/engine/pageControllers/StatusPageController.ts +50 -0
- package/src/server/plugins/engine/pageControllers/SummaryPageController.ts +261 -0
- package/src/server/plugins/engine/pageControllers/TerminalController.test.ts +28 -0
- package/src/server/plugins/engine/pageControllers/TerminalPageController.ts +19 -0
- package/src/server/plugins/engine/pageControllers/helpers.test.ts +198 -0
- package/src/server/plugins/engine/pageControllers/helpers.ts +101 -0
- package/src/server/plugins/engine/pageControllers/index.ts +10 -0
- package/src/server/plugins/engine/pageControllers/validationOptions.ts +89 -0
- package/src/server/plugins/engine/plugin.ts +673 -0
- package/src/server/plugins/engine/services/formSubmissionService.js +46 -0
- package/src/server/plugins/engine/services/formsService.js +46 -0
- package/src/server/plugins/engine/services/formsService.test.js +90 -0
- package/src/server/plugins/engine/services/index.js +3 -0
- package/src/server/plugins/engine/services/notifyService.test.ts +132 -0
- package/src/server/plugins/engine/services/notifyService.ts +64 -0
- package/src/server/plugins/engine/services/uploadService.js +60 -0
- package/src/server/plugins/engine/types.ts +315 -0
- package/src/server/plugins/engine/views/components/autocompletefield.html +5 -0
- package/src/server/plugins/engine/views/components/checkboxesfield.html +5 -0
- package/src/server/plugins/engine/views/components/datepartsfield.html +5 -0
- package/src/server/plugins/engine/views/components/details.html +6 -0
- package/src/server/plugins/engine/views/components/emailaddressfield.html +5 -0
- package/src/server/plugins/engine/views/components/fileuploadfield-key.html +8 -0
- package/src/server/plugins/engine/views/components/fileuploadfield-value.html +3 -0
- package/src/server/plugins/engine/views/components/fileuploadfield.html +24 -0
- package/src/server/plugins/engine/views/components/html.html +3 -0
- package/src/server/plugins/engine/views/components/insettext.html +7 -0
- package/src/server/plugins/engine/views/components/list.html +36 -0
- package/src/server/plugins/engine/views/components/monthyearfield.html +5 -0
- package/src/server/plugins/engine/views/components/multilinetextfield.html +10 -0
- package/src/server/plugins/engine/views/components/numberfield.html +5 -0
- package/src/server/plugins/engine/views/components/radiosfield.html +5 -0
- package/src/server/plugins/engine/views/components/selectfield.html +5 -0
- package/src/server/plugins/engine/views/components/telephonenumberfield.html +5 -0
- package/src/server/plugins/engine/views/components/textfield.html +5 -0
- package/src/server/plugins/engine/views/components/ukaddressfield.html +25 -0
- package/src/server/plugins/engine/views/components/yesnofield.html +5 -0
- package/src/server/plugins/engine/views/file-upload.html +45 -0
- package/src/server/plugins/engine/views/index.html +39 -0
- package/src/server/plugins/engine/views/item-delete.html +56 -0
- package/src/server/plugins/engine/views/partials/components.html +6 -0
- package/src/server/plugins/engine/views/partials/conditional-components.html +3 -0
- package/src/server/plugins/engine/views/partials/debug.html +44 -0
- package/src/server/plugins/engine/views/partials/form.html +15 -0
- package/src/server/plugins/engine/views/partials/heading.html +16 -0
- package/src/server/plugins/engine/views/partials/preview-banner.html +32 -0
- package/src/server/plugins/engine/views/partials/preview-banner.test.js +122 -0
- package/src/server/plugins/engine/views/partials/warn-missing-notification-email.html +10 -0
- package/src/server/plugins/engine/views/repeat-list-summary.html +53 -0
- package/src/server/plugins/errorPages.ts +58 -0
- package/src/server/plugins/nunjucks/context.js +88 -0
- package/src/server/plugins/nunjucks/context.test.js +142 -0
- package/src/server/plugins/nunjucks/enviroment.test.js +201 -0
- package/src/server/plugins/nunjucks/environment.js +116 -0
- package/src/server/plugins/nunjucks/filters/answer.js +27 -0
- package/src/server/plugins/nunjucks/filters/answer.test.js +89 -0
- package/src/server/plugins/nunjucks/filters/evaluate.js +21 -0
- package/src/server/plugins/nunjucks/filters/field.js +28 -0
- package/src/server/plugins/nunjucks/filters/field.test.js +75 -0
- package/src/server/plugins/nunjucks/filters/highlight.js +11 -0
- package/src/server/plugins/nunjucks/filters/href.js +30 -0
- package/src/server/plugins/nunjucks/filters/href.test.js +80 -0
- package/src/server/plugins/nunjucks/filters/index.js +8 -0
- package/src/server/plugins/nunjucks/filters/inspect.js +15 -0
- package/src/server/plugins/nunjucks/filters/page.js +24 -0
- package/src/server/plugins/nunjucks/filters/page.test.js +65 -0
- package/src/server/plugins/nunjucks/index.js +3 -0
- package/src/server/plugins/nunjucks/plugin.js +40 -0
- package/src/server/plugins/nunjucks/render.js +42 -0
- package/src/server/plugins/nunjucks/types.js +40 -0
- package/src/server/plugins/pulse.ts +11 -0
- package/src/server/plugins/router.ts +201 -0
- package/src/server/plugins/session.ts +28 -0
- package/src/server/routes/health.js +13 -0
- package/src/server/routes/health.test.js +35 -0
- package/src/server/routes/index.test.ts +125 -0
- package/src/server/routes/index.ts +2 -0
- package/src/server/routes/public.ts +47 -0
- package/src/server/routes/types.ts +48 -0
- package/src/server/schemas/index.ts +34 -0
- package/src/server/secure-context.js +43 -0
- package/src/server/services/cacheService.test.ts +276 -0
- package/src/server/services/cacheService.ts +131 -0
- package/src/server/services/httpService.test.js +491 -0
- package/src/server/services/httpService.ts +50 -0
- package/src/server/services/index.ts +1 -0
- package/src/server/types.ts +54 -0
- package/src/server/utils/notify.test.ts +37 -0
- package/src/server/utils/notify.ts +50 -0
- package/src/server/utils/secure-context/get-trust-store-certs.js +11 -0
- package/src/server/utils/secure-context/get-trust-store-certs.test.js +19 -0
- package/src/server/utils/utils.js +24 -0
- package/src/server/utils/utils.test.js +54 -0
- package/src/server/views/404.html +16 -0
- package/src/server/views/500.html +19 -0
- package/src/server/views/components/debug/macro.njk +3 -0
- package/src/server/views/components/debug/template.njk +13 -0
- package/src/server/views/components/service-banner/macro.njk +3 -0
- package/src/server/views/components/service-banner/template.njk +20 -0
- package/src/server/views/components/service-banner/template.test.js +43 -0
- package/src/server/views/components/tag-env/macro.njk +3 -0
- package/src/server/views/components/tag-env/template.njk +30 -0
- package/src/server/views/components/tag-env/template.test.js +66 -0
- package/src/server/views/confirmation.html +19 -0
- package/src/server/views/help/accessibility-statement.html +58 -0
- package/src/server/views/help/cookie-preferences.html +57 -0
- package/src/server/views/help/cookies.html +71 -0
- package/src/server/views/help/get-support.html +37 -0
- package/src/server/views/help/privacy-notice.html +68 -0
- package/src/server/views/help/terms-and-conditions.html +83 -0
- package/src/server/views/layout.html +199 -0
- package/src/server/views/summary.html +50 -0
- package/src/typings/hapi/index.d.ts +95 -0
- package/src/typings/hapi-tracing/index.d.ts +6 -0
- package/src/typings/index.d.ts +3 -0
- package/src/typings/joi/index.d.ts +22 -0
- package/stylelint.config.js +10 -0
- package/test/client/javascripts/file-upload.test.js +1197 -0
- package/test/condition/checkboxes.test.js +112 -0
- package/test/condition/radios.test.js +112 -0
- package/test/condition/text.test.js +103 -0
- package/test/fixtures/assets-manifest.json +4 -0
- package/test/fixtures/form.js +86 -0
- package/test/fixtures/index.js +2 -0
- package/test/fixtures/list.js +92 -0
- package/test/form/cookies.test.js +338 -0
- package/test/form/csrf.test.js +87 -0
- package/test/form/definitions/basic.js +101 -0
- package/test/form/definitions/blank.js +10 -0
- package/test/form/definitions/checkboxes.json +88 -0
- package/test/form/definitions/components.json +452 -0
- package/test/form/definitions/conditional-reveal.js +140 -0
- package/test/form/definitions/conditions-basic.js +187 -0
- package/test/form/definitions/conditions-complex.js +338 -0
- package/test/form/definitions/conditions-dates.js +78 -0
- package/test/form/definitions/conditions-escaping.js +143 -0
- package/test/form/definitions/demo-cph-number.js +3099 -0
- package/test/form/definitions/feedback.json +45 -0
- package/test/form/definitions/fields-optional.js +402 -0
- package/test/form/definitions/fields-required.js +402 -0
- package/test/form/definitions/file-upload-basic.js +44 -0
- package/test/form/definitions/file-upload.js +66 -0
- package/test/form/definitions/minimal.js +39 -0
- package/test/form/definitions/phase-alpha.json +33 -0
- package/test/form/definitions/phase-default.json +26 -0
- package/test/form/definitions/radios.json +88 -0
- package/test/form/definitions/repeat-mixed.js +54 -0
- package/test/form/definitions/repeat.js +70 -0
- package/test/form/definitions/status.json +126 -0
- package/test/form/definitions/templates.js +183 -0
- package/test/form/definitions/test.json +581 -0
- package/test/form/definitions/text.json +75 -0
- package/test/form/definitions/titles.json +170 -0
- package/test/form/definitions.test.js +47 -0
- package/test/form/exit-page.test.js +210 -0
- package/test/form/feedback.test.js +68 -0
- package/test/form/fields-optional.test.js +237 -0
- package/test/form/fields-required.test.js +294 -0
- package/test/form/file-upload.test.js +313 -0
- package/test/form/govuk-notify.test.js +449 -0
- package/test/form/journey-basic.test.js +444 -0
- package/test/form/persist-files.test.js +227 -0
- package/test/form/phase-banner.test.js +71 -0
- package/test/form/repeat.test.js +628 -0
- package/test/form/summary-submission-email.test.js +95 -0
- package/test/form/template.test.js +288 -0
- package/test/form/titles.test.js +204 -0
- package/test/helpers/component-helpers.js +74 -0
- package/test/utils/get-cookie.js +42 -0
- package/test/utils/get-form-definitions.js +18 -0
- package/tmp.pdf +1 -0
- package/tsconfig.json +28 -0
- package/webpack.config.js +208 -0
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { ComponentType } from '@defra/forms-model';
|
|
2
|
+
import { ComponentCollection } from "./ComponentCollection.js";
|
|
3
|
+
import { FormComponent, isFormState } from "./FormComponent.js";
|
|
4
|
+
import { TextField } from "./TextField.js";
|
|
5
|
+
export class UkAddressField extends FormComponent {
|
|
6
|
+
constructor(def, props) {
|
|
7
|
+
super(def, props);
|
|
8
|
+
const {
|
|
9
|
+
name,
|
|
10
|
+
options
|
|
11
|
+
} = def;
|
|
12
|
+
const isRequired = options.required !== false;
|
|
13
|
+
const hideOptional = !!options.optionalText;
|
|
14
|
+
const hideTitle = !!options.hideTitle;
|
|
15
|
+
this.collection = new ComponentCollection([{
|
|
16
|
+
type: ComponentType.TextField,
|
|
17
|
+
name: `${name}__addressLine1`,
|
|
18
|
+
title: 'Address line 1',
|
|
19
|
+
schema: {
|
|
20
|
+
max: 100
|
|
21
|
+
},
|
|
22
|
+
options: {
|
|
23
|
+
autocomplete: 'address-line1',
|
|
24
|
+
required: isRequired,
|
|
25
|
+
optionalText: !isRequired && (hideOptional || !hideTitle)
|
|
26
|
+
}
|
|
27
|
+
}, {
|
|
28
|
+
type: ComponentType.TextField,
|
|
29
|
+
name: `${name}__addressLine2`,
|
|
30
|
+
title: 'Address line 2',
|
|
31
|
+
schema: {
|
|
32
|
+
max: 100
|
|
33
|
+
},
|
|
34
|
+
options: {
|
|
35
|
+
autocomplete: 'address-line2',
|
|
36
|
+
required: false,
|
|
37
|
+
optionalText: !isRequired && (hideOptional || !hideTitle)
|
|
38
|
+
}
|
|
39
|
+
}, {
|
|
40
|
+
type: ComponentType.TextField,
|
|
41
|
+
name: `${name}__town`,
|
|
42
|
+
title: 'Town or city',
|
|
43
|
+
schema: {
|
|
44
|
+
max: 100
|
|
45
|
+
},
|
|
46
|
+
options: {
|
|
47
|
+
autocomplete: 'address-level2',
|
|
48
|
+
classes: 'govuk-!-width-two-thirds',
|
|
49
|
+
required: isRequired,
|
|
50
|
+
optionalText: !isRequired && (hideOptional || !hideTitle)
|
|
51
|
+
}
|
|
52
|
+
}, {
|
|
53
|
+
type: ComponentType.TextField,
|
|
54
|
+
name: `${name}__postcode`,
|
|
55
|
+
title: 'Postcode',
|
|
56
|
+
schema: {
|
|
57
|
+
regex: '^[a-zA-Z]{1,2}\\d[a-zA-Z\\d]?\\s?\\d[a-zA-Z]{2}$'
|
|
58
|
+
},
|
|
59
|
+
options: {
|
|
60
|
+
autocomplete: 'postal-code',
|
|
61
|
+
classes: 'govuk-input--width-10',
|
|
62
|
+
required: isRequired,
|
|
63
|
+
optionalText: !isRequired && (hideOptional || !hideTitle)
|
|
64
|
+
}
|
|
65
|
+
}], {
|
|
66
|
+
...props,
|
|
67
|
+
parent: this
|
|
68
|
+
});
|
|
69
|
+
this.options = options;
|
|
70
|
+
this.formSchema = this.collection.formSchema;
|
|
71
|
+
this.stateSchema = this.collection.stateSchema;
|
|
72
|
+
}
|
|
73
|
+
getFormValueFromState(state) {
|
|
74
|
+
const value = super.getFormValueFromState(state);
|
|
75
|
+
return this.isState(value) ? value : undefined;
|
|
76
|
+
}
|
|
77
|
+
getDisplayStringFromState(state) {
|
|
78
|
+
return this.getContextValueFromState(state)?.join(', ') ?? '';
|
|
79
|
+
}
|
|
80
|
+
getContextValueFromState(state) {
|
|
81
|
+
const value = this.getFormValueFromState(state);
|
|
82
|
+
if (!value) {
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
return Object.values(value).filter(Boolean);
|
|
86
|
+
}
|
|
87
|
+
getViewModel(payload, errors) {
|
|
88
|
+
const {
|
|
89
|
+
collection,
|
|
90
|
+
name,
|
|
91
|
+
options
|
|
92
|
+
} = this;
|
|
93
|
+
const viewModel = super.getViewModel(payload, errors);
|
|
94
|
+
let {
|
|
95
|
+
components,
|
|
96
|
+
fieldset,
|
|
97
|
+
hint,
|
|
98
|
+
label
|
|
99
|
+
} = viewModel;
|
|
100
|
+
fieldset ??= {
|
|
101
|
+
legend: {
|
|
102
|
+
text: label.text,
|
|
103
|
+
/**
|
|
104
|
+
* For screen readers, only hide legend visually. This can be overridden
|
|
105
|
+
* by single component {@link QuestionPageController | `showTitle` handling}
|
|
106
|
+
*/
|
|
107
|
+
classes: options.hideTitle ? 'govuk-visually-hidden' : 'govuk-fieldset__legend--m'
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
if (hint) {
|
|
111
|
+
hint.id ??= `${name}-hint`;
|
|
112
|
+
fieldset.attributes ??= {
|
|
113
|
+
'aria-describedby': hint.id
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
components = collection.getViewModel(payload, errors);
|
|
117
|
+
return {
|
|
118
|
+
...viewModel,
|
|
119
|
+
fieldset,
|
|
120
|
+
components
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
isState(value) {
|
|
124
|
+
return UkAddressField.isUkAddress(value);
|
|
125
|
+
}
|
|
126
|
+
static isUkAddress(value) {
|
|
127
|
+
return isFormState(value) && TextField.isText(value.addressLine1) && TextField.isText(value.town) && TextField.isText(value.postcode);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
//# sourceMappingURL=UkAddressField.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"UkAddressField.js","names":["ComponentType","ComponentCollection","FormComponent","isFormState","TextField","UkAddressField","constructor","def","props","name","options","isRequired","required","hideOptional","optionalText","hideTitle","collection","type","title","schema","max","autocomplete","classes","regex","parent","formSchema","stateSchema","getFormValueFromState","state","value","isState","undefined","getDisplayStringFromState","getContextValueFromState","join","Object","values","filter","Boolean","getViewModel","payload","errors","viewModel","components","fieldset","hint","label","legend","text","id","attributes","isUkAddress","isText","addressLine1","town","postcode"],"sources":["../../../../../src/server/plugins/engine/components/UkAddressField.ts"],"sourcesContent":["import { ComponentType, type UkAddressFieldComponent } from '@defra/forms-model'\nimport { type ObjectSchema } from 'joi'\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 QuestionPageController } from '~/src/server/plugins/engine/pageControllers/QuestionPageController.js'\nimport {\n type FormPayload,\n type FormState,\n type FormStateValue,\n type FormSubmissionError,\n type FormSubmissionState\n} from '~/src/server/plugins/engine/types.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\n this.collection = new ComponentCollection(\n [\n {\n type: ComponentType.TextField,\n name: `${name}__addressLine1`,\n title: 'Address line 1',\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: 'Address line 2',\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: 'Town or city',\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}__postcode`,\n title: '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 getDisplayStringFromState(state: FormSubmissionState) {\n return this.getContextValueFromState(state)?.join(', ') ?? ''\n }\n\n getContextValueFromState(state: FormSubmissionState) {\n const value = this.getFormValueFromState(state)\n\n if (!value) {\n return null\n }\n\n return Object.values(value).filter(Boolean)\n }\n\n getViewModel(payload: FormPayload, errors?: FormSubmissionError[]) {\n const { collection, name, options } = this\n\n const viewModel = super.getViewModel(payload, errors)\n let { components, 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 components = collection.getViewModel(payload, errors)\n\n return {\n ...viewModel,\n fieldset,\n components\n }\n }\n\n isState(value?: FormStateValue | FormState): value is UkAddressState {\n return UkAddressField.isUkAddress(value)\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\nexport interface UkAddressState extends Record<string, string> {\n addressLine1: string\n addressLine2: string\n town: string\n postcode: string\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { SelectionControlField } from "./SelectionControlField.js";
|
|
2
|
+
import { addClassOptionIfNone } from "./helpers.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @description
|
|
6
|
+
* YesNoField is a radiosField with predefined values.
|
|
7
|
+
*/
|
|
8
|
+
export class YesNoField extends SelectionControlField {
|
|
9
|
+
constructor(def, props) {
|
|
10
|
+
super({
|
|
11
|
+
...def,
|
|
12
|
+
list: '__yesNo'
|
|
13
|
+
}, props);
|
|
14
|
+
const {
|
|
15
|
+
options
|
|
16
|
+
} = def;
|
|
17
|
+
let {
|
|
18
|
+
formSchema
|
|
19
|
+
} = this;
|
|
20
|
+
addClassOptionIfNone(options, 'govuk-radios--inline');
|
|
21
|
+
if (options.required === false) {
|
|
22
|
+
formSchema = formSchema.optional();
|
|
23
|
+
}
|
|
24
|
+
this.formSchema = formSchema;
|
|
25
|
+
this.options = options;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=YesNoField.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"YesNoField.js","names":["SelectionControlField","addClassOptionIfNone","YesNoField","constructor","def","props","list","options","formSchema","required","optional"],"sources":["../../../../../src/server/plugins/engine/components/YesNoField.ts"],"sourcesContent":["import { type YesNoFieldComponent } from '@defra/forms-model'\n\nimport { SelectionControlField } from '~/src/server/plugins/engine/components/SelectionControlField.js'\nimport { addClassOptionIfNone } from '~/src/server/plugins/engine/components/helpers.js'\n\n/**\n * @description\n * YesNoField is a radiosField with predefined values.\n */\nexport class YesNoField extends SelectionControlField {\n declare options: YesNoFieldComponent['options']\n\n constructor(\n def: YesNoFieldComponent,\n props: ConstructorParameters<typeof SelectionControlField>[1]\n ) {\n super({ ...def, list: '__yesNo' }, props)\n\n const { options } = def\n let { formSchema } = this\n\n addClassOptionIfNone(options, 'govuk-radios--inline')\n\n if (options.required === false) {\n formSchema = formSchema.optional()\n }\n\n this.formSchema = formSchema\n this.options = options\n }\n}\n"],"mappings":"AAEA,SAASA,qBAAqB;AAC9B,SAASC,oBAAoB;;AAE7B;AACA;AACA;AACA;AACA,OAAO,MAAMC,UAAU,SAASF,qBAAqB,CAAC;EAGpDG,WAAWA,CACTC,GAAwB,EACxBC,KAA6D,EAC7D;IACA,KAAK,CAAC;MAAE,GAAGD,GAAG;MAAEE,IAAI,EAAE;IAAU,CAAC,EAAED,KAAK,CAAC;IAEzC,MAAM;MAAEE;IAAQ,CAAC,GAAGH,GAAG;IACvB,IAAI;MAAEI;IAAW,CAAC,GAAG,IAAI;IAEzBP,oBAAoB,CAACM,OAAO,EAAE,sBAAsB,CAAC;IAErD,IAAIA,OAAO,CAACE,QAAQ,KAAK,KAAK,EAAE;MAC9BD,UAAU,GAAGA,UAAU,CAACE,QAAQ,CAAC,CAAC;IACpC;IAEA,IAAI,CAACF,UAAU,GAAGA,UAAU;IAC5B,IAAI,CAACD,OAAO,GAAGA,OAAO;EACxB;AACF","ignoreList":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.js","names":["optionalText"],"sources":["../../../../../src/server/plugins/engine/components/constants.ts"],"sourcesContent":["export const optionalText = ' (optional)'\n"],"mappings":"AAAA,OAAO,MAAMA,YAAY,GAAG,aAAa","ignoreList":[]}
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
import { ComponentType } from '@defra/forms-model';
|
|
2
|
+
import { Marked } from 'marked';
|
|
3
|
+
import { config } from "../../../../config/index.js";
|
|
4
|
+
import { ListFormComponent } from "./ListFormComponent.js";
|
|
5
|
+
import * as Components from "./index.js";
|
|
6
|
+
const designerUrl = config.get('designerUrl');
|
|
7
|
+
const markdown = new Marked({
|
|
8
|
+
breaks: true,
|
|
9
|
+
gfm: true,
|
|
10
|
+
/**
|
|
11
|
+
* Render paragraphs without `<p>` wrappers
|
|
12
|
+
* for check answers summary list `<dd>`
|
|
13
|
+
*/
|
|
14
|
+
extensions: [{
|
|
15
|
+
name: 'paragraph',
|
|
16
|
+
renderer({
|
|
17
|
+
tokens = []
|
|
18
|
+
}) {
|
|
19
|
+
const text = this.parser.parseInline(tokens);
|
|
20
|
+
return tokens.length > 1 ? `${text}<br>` : text;
|
|
21
|
+
}
|
|
22
|
+
}],
|
|
23
|
+
/**
|
|
24
|
+
* Restrict allowed Markdown tokens
|
|
25
|
+
*/
|
|
26
|
+
walkTokens(token) {
|
|
27
|
+
const tokens = ['br', 'escape', 'list', 'list_item', 'paragraph', 'space', 'text'];
|
|
28
|
+
if (!tokens.includes(token.type)) {
|
|
29
|
+
token.type = 'text';
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
// All component instances
|
|
35
|
+
|
|
36
|
+
// Field component instances only
|
|
37
|
+
|
|
38
|
+
// Guidance component instances only
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Create field instance for each {@link ComponentDef} type
|
|
42
|
+
*/
|
|
43
|
+
export function createComponent(def, options) {
|
|
44
|
+
let component;
|
|
45
|
+
switch (def.type) {
|
|
46
|
+
case ComponentType.AutocompleteField:
|
|
47
|
+
component = new Components.AutocompleteField(def, options);
|
|
48
|
+
break;
|
|
49
|
+
case ComponentType.CheckboxesField:
|
|
50
|
+
component = new Components.CheckboxesField(def, options);
|
|
51
|
+
break;
|
|
52
|
+
case ComponentType.DatePartsField:
|
|
53
|
+
component = new Components.DatePartsField(def, options);
|
|
54
|
+
break;
|
|
55
|
+
case ComponentType.Details:
|
|
56
|
+
component = new Components.Details(def, options);
|
|
57
|
+
break;
|
|
58
|
+
case ComponentType.EmailAddressField:
|
|
59
|
+
component = new Components.EmailAddressField(def, options);
|
|
60
|
+
break;
|
|
61
|
+
case ComponentType.Html:
|
|
62
|
+
component = new Components.Html(def, options);
|
|
63
|
+
break;
|
|
64
|
+
case ComponentType.InsetText:
|
|
65
|
+
component = new Components.InsetText(def, options);
|
|
66
|
+
break;
|
|
67
|
+
case ComponentType.List:
|
|
68
|
+
component = new Components.List(def, options);
|
|
69
|
+
break;
|
|
70
|
+
case ComponentType.MultilineTextField:
|
|
71
|
+
component = new Components.MultilineTextField(def, options);
|
|
72
|
+
break;
|
|
73
|
+
case ComponentType.NumberField:
|
|
74
|
+
component = new Components.NumberField(def, options);
|
|
75
|
+
break;
|
|
76
|
+
case ComponentType.RadiosField:
|
|
77
|
+
component = new Components.RadiosField(def, options);
|
|
78
|
+
break;
|
|
79
|
+
case ComponentType.SelectField:
|
|
80
|
+
component = new Components.SelectField(def, options);
|
|
81
|
+
break;
|
|
82
|
+
case ComponentType.TelephoneNumberField:
|
|
83
|
+
component = new Components.TelephoneNumberField(def, options);
|
|
84
|
+
break;
|
|
85
|
+
case ComponentType.TextField:
|
|
86
|
+
component = new Components.TextField(def, options);
|
|
87
|
+
break;
|
|
88
|
+
case ComponentType.UkAddressField:
|
|
89
|
+
component = new Components.UkAddressField(def, options);
|
|
90
|
+
break;
|
|
91
|
+
case ComponentType.YesNoField:
|
|
92
|
+
component = new Components.YesNoField(def, options);
|
|
93
|
+
break;
|
|
94
|
+
case ComponentType.MonthYearField:
|
|
95
|
+
component = new Components.MonthYearField(def, options);
|
|
96
|
+
break;
|
|
97
|
+
case ComponentType.FileUploadField:
|
|
98
|
+
component = new Components.FileUploadField(def, options);
|
|
99
|
+
break;
|
|
100
|
+
}
|
|
101
|
+
if (typeof component === 'undefined') {
|
|
102
|
+
throw new Error(`Component type ${def.type} does not exist`);
|
|
103
|
+
}
|
|
104
|
+
return component;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Get formatted answer for a field
|
|
109
|
+
*/
|
|
110
|
+
export function getAnswer(field, state, options = {
|
|
111
|
+
format: 'summary'
|
|
112
|
+
}) {
|
|
113
|
+
// Use escaped display text for GOV.UK Notify emails
|
|
114
|
+
if (options.format === 'email') {
|
|
115
|
+
return getAnswerMarkdown(field, state, {
|
|
116
|
+
format: 'email'
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// Use context value for submission data
|
|
121
|
+
if (options.format === 'data') {
|
|
122
|
+
const context = field.getContextValueFromState(state);
|
|
123
|
+
return context?.toString() ?? '';
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// Use display HTML for check answers summary (multi line)
|
|
127
|
+
if (field instanceof ListFormComponent || field instanceof Components.MultilineTextField || field instanceof Components.UkAddressField) {
|
|
128
|
+
return markdown.parse(getAnswerMarkdown(field, state), {
|
|
129
|
+
async: false
|
|
130
|
+
}).trim();
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// Use display text for check answers summary (single line)
|
|
134
|
+
return field.getDisplayStringFromState(state);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Get formatted answer for a field (Markdown only)
|
|
139
|
+
*/
|
|
140
|
+
export function getAnswerMarkdown(field, state, options = {
|
|
141
|
+
format: 'summary'
|
|
142
|
+
}) {
|
|
143
|
+
const answer = field.getDisplayStringFromState(state);
|
|
144
|
+
|
|
145
|
+
// Use escaped display text
|
|
146
|
+
let answerEscaped = `${escapeMarkdown(answer)}\n`;
|
|
147
|
+
if (field instanceof Components.FileUploadField) {
|
|
148
|
+
const files = field.getFormValueFromState(state);
|
|
149
|
+
|
|
150
|
+
// Skip empty files
|
|
151
|
+
if (!files?.length) {
|
|
152
|
+
return answerEscaped;
|
|
153
|
+
}
|
|
154
|
+
answerEscaped = `${escapeMarkdown(answer)}:\n\n`;
|
|
155
|
+
|
|
156
|
+
// Append bullet points
|
|
157
|
+
answerEscaped += files.map(({
|
|
158
|
+
status
|
|
159
|
+
}) => {
|
|
160
|
+
const {
|
|
161
|
+
file
|
|
162
|
+
} = status.form;
|
|
163
|
+
const filename = escapeMarkdown(file.filename);
|
|
164
|
+
return `* [${filename}](${designerUrl}/file-download/${file.fileId})\n`;
|
|
165
|
+
}).join('');
|
|
166
|
+
} else if (field instanceof ListFormComponent) {
|
|
167
|
+
const values = [field.getContextValueFromState(state)].flat();
|
|
168
|
+
const items = field.items.filter(({
|
|
169
|
+
value
|
|
170
|
+
}) => values.includes(value));
|
|
171
|
+
|
|
172
|
+
// Skip empty values
|
|
173
|
+
if (!items.length) {
|
|
174
|
+
return answerEscaped;
|
|
175
|
+
}
|
|
176
|
+
answerEscaped = '';
|
|
177
|
+
|
|
178
|
+
// Append bullet points
|
|
179
|
+
answerEscaped += items.map(item => {
|
|
180
|
+
const label = escapeMarkdown(item.text);
|
|
181
|
+
const value = escapeMarkdown(`(${item.value})`);
|
|
182
|
+
let line = label;
|
|
183
|
+
|
|
184
|
+
// Prepend bullet points for checkboxes only
|
|
185
|
+
if (field instanceof Components.CheckboxesField) {
|
|
186
|
+
line = `* ${line}`;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// Append raw values in parentheses
|
|
190
|
+
// e.g. `* None of the above (false)`
|
|
191
|
+
return options.format === 'email' && `${item.value}`.toLowerCase() !== item.text.toLowerCase() ? `${line} ${value}\n` : `${line}\n`;
|
|
192
|
+
}).join('');
|
|
193
|
+
} else if (field instanceof Components.MultilineTextField) {
|
|
194
|
+
// Preserve Multiline text new lines
|
|
195
|
+
answerEscaped = answer.split(/\r?\n/).map(escapeMarkdown).join('\n').concat('\n');
|
|
196
|
+
} else if (field instanceof Components.UkAddressField) {
|
|
197
|
+
// Format UK addresses into new lines
|
|
198
|
+
answerEscaped = (field.getContextValueFromState(state) ?? []).map(escapeMarkdown).join('\n').concat('\n');
|
|
199
|
+
}
|
|
200
|
+
return answerEscaped;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Prevent Markdown formatting
|
|
205
|
+
* @see {@link https://pandoc.org/chunkedhtml-demo/8.11-backslash-escapes.html}
|
|
206
|
+
*/
|
|
207
|
+
export function escapeMarkdown(answer) {
|
|
208
|
+
const punctuation = ['`', "'", '*', '_', '{', '}', '[', ']', '(', ')', '#', '+', '-', '.', '!'];
|
|
209
|
+
for (const character of punctuation) {
|
|
210
|
+
answer = answer.toString().replaceAll(character, `\\${character}`);
|
|
211
|
+
}
|
|
212
|
+
return answer;
|
|
213
|
+
}
|
|
214
|
+
export const addClassOptionIfNone = (options, className) => {
|
|
215
|
+
if (!options.classes) {
|
|
216
|
+
options.classes = className;
|
|
217
|
+
}
|
|
218
|
+
};
|
|
219
|
+
//# sourceMappingURL=helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.js","names":["ComponentType","Marked","config","ListFormComponent","Components","designerUrl","get","markdown","breaks","gfm","extensions","name","renderer","tokens","text","parser","parseInline","length","walkTokens","token","includes","type","createComponent","def","options","component","AutocompleteField","CheckboxesField","DatePartsField","Details","EmailAddressField","Html","InsetText","List","MultilineTextField","NumberField","RadiosField","SelectField","TelephoneNumberField","TextField","UkAddressField","YesNoField","MonthYearField","FileUploadField","Error","getAnswer","field","state","format","getAnswerMarkdown","context","getContextValueFromState","toString","parse","async","trim","getDisplayStringFromState","answer","answerEscaped","escapeMarkdown","files","getFormValueFromState","map","status","file","form","filename","fileId","join","values","flat","items","filter","value","item","label","line","toLowerCase","split","concat","punctuation","character","replaceAll","addClassOptionIfNone","className","classes"],"sources":["../../../../../src/server/plugins/engine/components/helpers.ts"],"sourcesContent":["import { ComponentType, type ComponentDef } from '@defra/forms-model'\nimport { Marked, type Token } from 'marked'\n\nimport { config } from '~/src/config/index.js'\nimport { type ComponentBase } from '~/src/server/plugins/engine/components/ComponentBase.js'\nimport { ListFormComponent } from '~/src/server/plugins/engine/components/ListFormComponent.js'\nimport * as Components from '~/src/server/plugins/engine/components/index.js'\nimport { type FormState } from '~/src/server/plugins/engine/types.js'\n\nconst designerUrl = config.get('designerUrl')\n\nconst markdown = new Marked({\n breaks: true,\n gfm: true,\n\n /**\n * Render paragraphs without `<p>` wrappers\n * for check answers summary list `<dd>`\n */\n extensions: [\n {\n name: 'paragraph',\n renderer({ tokens = [] }) {\n const text = this.parser.parseInline(tokens)\n return tokens.length > 1 ? `${text}<br>` : text\n }\n }\n ],\n\n /**\n * Restrict allowed Markdown tokens\n */\n walkTokens(token) {\n const tokens: Token['type'][] = [\n 'br',\n 'escape',\n 'list',\n 'list_item',\n 'paragraph',\n 'space',\n 'text'\n ]\n\n if (!tokens.includes(token.type)) {\n token.type = 'text'\n }\n }\n})\n\n// All component instances\nexport type Component = InstanceType<\n (typeof Components)[keyof typeof Components]\n>\n\n// Field component instances only\nexport type Field = InstanceType<\n | typeof Components.AutocompleteField\n | typeof Components.CheckboxesField\n | typeof Components.DatePartsField\n | typeof Components.EmailAddressField\n | typeof Components.MonthYearField\n | typeof Components.MultilineTextField\n | typeof Components.NumberField\n | typeof Components.SelectField\n | typeof Components.TelephoneNumberField\n | typeof Components.TextField\n | typeof Components.UkAddressField\n | typeof Components.FileUploadField\n>\n\n// Guidance component instances only\nexport type Guidance = InstanceType<\n | typeof Components.Details\n | typeof Components.Html\n | typeof Components.InsetText\n | typeof Components.List\n>\n\n/**\n * Create field instance for each {@link ComponentDef} type\n */\nexport function createComponent(\n def: ComponentDef,\n options: ConstructorParameters<typeof ComponentBase>[1]\n): Component {\n let component: Component | undefined\n\n switch (def.type) {\n case ComponentType.AutocompleteField:\n component = new Components.AutocompleteField(def, options)\n break\n\n case ComponentType.CheckboxesField:\n component = new Components.CheckboxesField(def, options)\n break\n\n case ComponentType.DatePartsField:\n component = new Components.DatePartsField(def, options)\n break\n\n case ComponentType.Details:\n component = new Components.Details(def, options)\n break\n\n case ComponentType.EmailAddressField:\n component = new Components.EmailAddressField(def, options)\n break\n\n case ComponentType.Html:\n component = new Components.Html(def, options)\n break\n\n case ComponentType.InsetText:\n component = new Components.InsetText(def, options)\n break\n\n case ComponentType.List:\n component = new Components.List(def, options)\n break\n\n case ComponentType.MultilineTextField:\n component = new Components.MultilineTextField(def, options)\n break\n\n case ComponentType.NumberField:\n component = new Components.NumberField(def, options)\n break\n\n case ComponentType.RadiosField:\n component = new Components.RadiosField(def, options)\n break\n\n case ComponentType.SelectField:\n component = new Components.SelectField(def, options)\n break\n\n case ComponentType.TelephoneNumberField:\n component = new Components.TelephoneNumberField(def, options)\n break\n\n case ComponentType.TextField:\n component = new Components.TextField(def, options)\n break\n\n case ComponentType.UkAddressField:\n component = new Components.UkAddressField(def, options)\n break\n\n case ComponentType.YesNoField:\n component = new Components.YesNoField(def, options)\n break\n\n case ComponentType.MonthYearField:\n component = new Components.MonthYearField(def, options)\n break\n\n case ComponentType.FileUploadField:\n component = new Components.FileUploadField(def, options)\n break\n }\n\n if (typeof component === 'undefined') {\n throw new Error(`Component type ${def.type} does not exist`)\n }\n\n return component\n}\n\n/**\n * Get formatted answer for a field\n */\nexport function getAnswer(\n field: Field,\n state: FormState,\n options: {\n format:\n | 'data' // Submission data\n | 'email' // GOV.UK Notify emails\n | 'summary' // Check answers summary\n } = { format: 'summary' }\n) {\n // Use escaped display text for GOV.UK Notify emails\n if (options.format === 'email') {\n return getAnswerMarkdown(field, state, { format: 'email' })\n }\n\n // Use context value for submission data\n if (options.format === 'data') {\n const context = field.getContextValueFromState(state)\n return context?.toString() ?? ''\n }\n\n // Use display HTML for check answers summary (multi line)\n if (\n field instanceof ListFormComponent ||\n field instanceof Components.MultilineTextField ||\n field instanceof Components.UkAddressField\n ) {\n return markdown\n .parse(getAnswerMarkdown(field, state), { async: false })\n .trim()\n }\n\n // Use display text for check answers summary (single line)\n return field.getDisplayStringFromState(state)\n}\n\n/**\n * Get formatted answer for a field (Markdown only)\n */\nexport function getAnswerMarkdown(\n field: Field,\n state: FormState,\n options: {\n format:\n | 'email' // GOV.UK Notify emails\n | 'summary' // Check answers summary\n } = { format: 'summary' }\n) {\n const answer = field.getDisplayStringFromState(state)\n\n // Use escaped display text\n let answerEscaped = `${escapeMarkdown(answer)}\\n`\n\n if (field instanceof Components.FileUploadField) {\n const files = field.getFormValueFromState(state)\n\n // Skip empty files\n if (!files?.length) {\n return answerEscaped\n }\n\n answerEscaped = `${escapeMarkdown(answer)}:\\n\\n`\n\n // Append bullet points\n answerEscaped += files\n .map(({ status }) => {\n const { file } = status.form\n const filename = escapeMarkdown(file.filename)\n return `* [${filename}](${designerUrl}/file-download/${file.fileId})\\n`\n })\n .join('')\n } else if (field instanceof ListFormComponent) {\n const values = [field.getContextValueFromState(state)].flat()\n const items = field.items.filter(({ value }) => values.includes(value))\n\n // Skip empty values\n if (!items.length) {\n return answerEscaped\n }\n\n answerEscaped = ''\n\n // Append bullet points\n answerEscaped += items\n .map((item) => {\n const label = escapeMarkdown(item.text)\n const value = escapeMarkdown(`(${item.value})`)\n\n let line = label\n\n // Prepend bullet points for checkboxes only\n if (field instanceof Components.CheckboxesField) {\n line = `* ${line}`\n }\n\n // Append raw values in parentheses\n // e.g. `* None of the above (false)`\n return options.format === 'email' &&\n `${item.value}`.toLowerCase() !== item.text.toLowerCase()\n ? `${line} ${value}\\n`\n : `${line}\\n`\n })\n .join('')\n } else if (field instanceof Components.MultilineTextField) {\n // Preserve Multiline text new lines\n answerEscaped = answer\n .split(/\\r?\\n/)\n .map(escapeMarkdown)\n .join('\\n')\n .concat('\\n')\n } else if (field instanceof Components.UkAddressField) {\n // Format UK addresses into new lines\n answerEscaped = (field.getContextValueFromState(state) ?? [])\n .map(escapeMarkdown)\n .join('\\n')\n .concat('\\n')\n }\n\n return answerEscaped\n}\n\n/**\n * Prevent Markdown formatting\n * @see {@link https://pandoc.org/chunkedhtml-demo/8.11-backslash-escapes.html}\n */\nexport function escapeMarkdown(answer: string) {\n const punctuation = [\n '`',\n \"'\",\n '*',\n '_',\n '{',\n '}',\n '[',\n ']',\n '(',\n ')',\n '#',\n '+',\n '-',\n '.',\n '!'\n ]\n\n for (const character of punctuation) {\n answer = answer.toString().replaceAll(character, `\\\\${character}`)\n }\n\n return answer\n}\n\nexport const addClassOptionIfNone = (\n options: Extract<ComponentDef, { options: { classes?: string } }>['options'],\n className: string\n) => {\n if (!options.classes) {\n options.classes = className\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* IMPORTANT: Exported Components must follow the naming convention implemented in {@link @defra/forms-model#ComponentType}
|
|
3
|
+
* In the Form JSON, components have a type property which is the name of the components, e.g. DatePartsField.
|
|
4
|
+
* Components are loaded in the ComponentsCollection constructor.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
export { AutocompleteField } from "./AutocompleteField.js";
|
|
8
|
+
export { CheckboxesField } from "./CheckboxesField.js";
|
|
9
|
+
export { DatePartsField } from "./DatePartsField.js";
|
|
10
|
+
export { Details } from "./Details.js";
|
|
11
|
+
export { EmailAddressField } from "./EmailAddressField.js";
|
|
12
|
+
export { Html } from "./Html.js";
|
|
13
|
+
export { InsetText } from "./InsetText.js";
|
|
14
|
+
export { List } from "./List.js";
|
|
15
|
+
export { MultilineTextField } from "./MultilineTextField.js";
|
|
16
|
+
export { NumberField } from "./NumberField.js";
|
|
17
|
+
export { RadiosField } from "./RadiosField.js";
|
|
18
|
+
export { SelectField } from "./SelectField.js";
|
|
19
|
+
export { TelephoneNumberField } from "./TelephoneNumberField.js";
|
|
20
|
+
export { TextField } from "./TextField.js";
|
|
21
|
+
export { UkAddressField } from "./UkAddressField.js";
|
|
22
|
+
export { YesNoField } from "./YesNoField.js";
|
|
23
|
+
export { MonthYearField } from "./MonthYearField.js";
|
|
24
|
+
export { FileUploadField } from "./FileUploadField.js";
|
|
25
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":["AutocompleteField","CheckboxesField","DatePartsField","Details","EmailAddressField","Html","InsetText","List","MultilineTextField","NumberField","RadiosField","SelectField","TelephoneNumberField","TextField","UkAddressField","YesNoField","MonthYearField","FileUploadField"],"sources":["../../../../../src/server/plugins/engine/components/index.ts"],"sourcesContent":["/**\n * IMPORTANT: Exported Components must follow the naming convention implemented in {@link @defra/forms-model#ComponentType}\n * In the Form JSON, components have a type property which is the name of the components, e.g. DatePartsField.\n * Components are loaded in the ComponentsCollection constructor.\n */\n\nexport { AutocompleteField } from '~/src/server/plugins/engine/components/AutocompleteField.js'\nexport { CheckboxesField } from '~/src/server/plugins/engine/components/CheckboxesField.js'\nexport { DatePartsField } from '~/src/server/plugins/engine/components/DatePartsField.js'\nexport { Details } from '~/src/server/plugins/engine/components/Details.js'\nexport { EmailAddressField } from '~/src/server/plugins/engine/components/EmailAddressField.js'\nexport { Html } from '~/src/server/plugins/engine/components/Html.js'\nexport { InsetText } from '~/src/server/plugins/engine/components/InsetText.js'\nexport { List } from '~/src/server/plugins/engine/components/List.js'\nexport { MultilineTextField } from '~/src/server/plugins/engine/components/MultilineTextField.js'\nexport { NumberField } from '~/src/server/plugins/engine/components/NumberField.js'\nexport { RadiosField } from '~/src/server/plugins/engine/components/RadiosField.js'\nexport { SelectField } from '~/src/server/plugins/engine/components/SelectField.js'\nexport { TelephoneNumberField } from '~/src/server/plugins/engine/components/TelephoneNumberField.js'\nexport { TextField } from '~/src/server/plugins/engine/components/TextField.js'\nexport { UkAddressField } from '~/src/server/plugins/engine/components/UkAddressField.js'\nexport { YesNoField } from '~/src/server/plugins/engine/components/YesNoField.js'\nexport { MonthYearField } from '~/src/server/plugins/engine/components/MonthYearField.js'\nexport { FileUploadField } from '~/src/server/plugins/engine/components/FileUploadField.js'\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;;AAEA,SAASA,iBAAiB;AAC1B,SAASC,eAAe;AACxB,SAASC,cAAc;AACvB,SAASC,OAAO;AAChB,SAASC,iBAAiB;AAC1B,SAASC,IAAI;AACb,SAASC,SAAS;AAClB,SAASC,IAAI;AACb,SAASC,kBAAkB;AAC3B,SAASC,WAAW;AACpB,SAASC,WAAW;AACpB,SAASC,WAAW;AACpB,SAASC,oBAAoB;AAC7B,SAASC,SAAS;AAClB,SAASC,cAAc;AACvB,SAASC,UAAU;AACnB,SAASC,cAAc;AACvB,SAASC,eAAe","ignoreList":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","names":[],"sources":["../../../../../src/server/plugins/engine/components/types.ts"],"sourcesContent":["import { type ComponentType, type Item } from '@defra/forms-model'\n\nimport {\n type FormSubmissionError,\n type FormValue,\n type SummaryList\n} from '~/src/server/plugins/engine/types.js'\n\nexport type ComponentText = {\n classes?: string\n attributes?: string | Record<string, string>\n} & (\n | {\n text: string\n html?: string\n }\n | {\n text?: string\n html: string\n }\n)\n\nexport interface Label {\n text: string\n classes?: string\n html?: string\n isPageHeading?: boolean\n}\n\nexport interface Content {\n title?: string\n text: string\n condition?: string\n}\n\nexport interface BackLink {\n text: string\n href: string\n}\n\nexport type ListItemLabel = Omit<Label, 'text' | 'isPageHeading'>\n\nexport interface ListItem {\n text?: string\n value?: Item['value']\n hint?: {\n id?: string\n text: string\n }\n checked?: boolean\n selected?: boolean\n label?: ListItemLabel\n condition?: string\n}\n\nexport interface DateInputItem {\n label?: Label\n type?: string\n id?: string\n name?: string\n value?: Item['value']\n classes?: string\n condition?: undefined\n}\n\nexport interface ViewModel extends Record<string, unknown> {\n label?: Label\n type?: string\n id?: string\n name?: string\n value?: FormValue\n hint?: {\n id?: string\n text: string\n }\n prefix?: ComponentText\n suffix?: ComponentText\n classes?: string\n condition?: string\n errors?: FormSubmissionError[]\n errorMessage?: {\n text: string\n }\n summaryHtml?: string\n html?: string\n attributes: {\n autocomplete?: string\n maxlength?: number\n multiple?: string\n accept?: string\n inputmode?: string\n }\n content?: Content | Content[] | string\n maxlength?: number\n maxwords?: number\n rows?: number\n items?: ListItem[] | DateInputItem[]\n fieldset?: {\n attributes?: string | Record<string, string>\n legend?: Label\n }\n formGroup?: {\n classes?: string\n attributes?: string | Record<string, string>\n }\n components?: ComponentViewModel[]\n upload?: {\n count: number\n summaryList: SummaryList\n }\n}\n\nexport interface ComponentViewModel {\n type: ComponentType\n isFormComponent: boolean\n model: ViewModel\n}\n"],"mappings":"","ignoreList":[]}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { join, parse } from 'node:path';
|
|
2
|
+
import { FormModel } from "./models/FormModel.js";
|
|
3
|
+
import { plugin } from "./plugin.js";
|
|
4
|
+
export const configureEnginePlugin = async ({
|
|
5
|
+
formFileName,
|
|
6
|
+
formFilePath,
|
|
7
|
+
services,
|
|
8
|
+
controllers
|
|
9
|
+
} = {}) => {
|
|
10
|
+
let model;
|
|
11
|
+
if (formFileName && formFilePath) {
|
|
12
|
+
const definition = await getForm(join(formFilePath, formFileName));
|
|
13
|
+
const {
|
|
14
|
+
name
|
|
15
|
+
} = parse(formFileName);
|
|
16
|
+
model = new FormModel(definition, {
|
|
17
|
+
basePath: name
|
|
18
|
+
}, services, controllers);
|
|
19
|
+
}
|
|
20
|
+
return {
|
|
21
|
+
plugin,
|
|
22
|
+
options: {
|
|
23
|
+
model,
|
|
24
|
+
services,
|
|
25
|
+
controllers
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
};
|
|
29
|
+
export async function getForm(importPath) {
|
|
30
|
+
const {
|
|
31
|
+
ext
|
|
32
|
+
} = parse(importPath);
|
|
33
|
+
const attributes = {
|
|
34
|
+
type: ext === '.json' ? 'json' : 'module'
|
|
35
|
+
};
|
|
36
|
+
const formImport = import(importPath, {
|
|
37
|
+
with: attributes
|
|
38
|
+
});
|
|
39
|
+
const {
|
|
40
|
+
default: definition
|
|
41
|
+
} = await formImport;
|
|
42
|
+
return definition;
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=configureEnginePlugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"configureEnginePlugin.js","names":["join","parse","FormModel","plugin","configureEnginePlugin","formFileName","formFilePath","services","controllers","model","definition","getForm","name","basePath","options","importPath","ext","attributes","type","formImport","with","default"],"sources":["../../../../src/server/plugins/engine/configureEnginePlugin.ts"],"sourcesContent":["import { join, parse } from 'node:path'\n\nimport { type FormDefinition } from '@defra/forms-model'\nimport { type ServerRegisterPluginObject } from '@hapi/hapi'\n\nimport { FormModel } from '~/src/server/plugins/engine/models/FormModel.js'\nimport {\n plugin,\n type PluginOptions\n} from '~/src/server/plugins/engine/plugin.js'\nimport { type RouteConfig } from '~/src/server/types.js'\n\nexport const configureEnginePlugin = async ({\n formFileName,\n formFilePath,\n services,\n controllers\n}: RouteConfig = {}): Promise<ServerRegisterPluginObject<PluginOptions>> => {\n let model: FormModel | undefined\n\n if (formFileName && formFilePath) {\n const definition = await getForm(join(formFilePath, formFileName))\n const { name } = parse(formFileName)\n\n model = new FormModel(definition, { basePath: name }, services, controllers)\n }\n\n return {\n plugin,\n options: { model, services, controllers }\n }\n}\n\nexport async function getForm(importPath: string) {\n const { ext } = parse(importPath)\n\n const attributes: ImportAttributes = {\n type: ext === '.json' ? 'json' : 'module'\n }\n\n const formImport = import(importPath, { with: attributes }) as Promise<{\n default: FormDefinition\n }>\n\n const { default: definition } = await formImport\n return definition\n}\n"],"mappings":"AAAA,SAASA,IAAI,EAAEC,KAAK,QAAQ,WAAW;AAKvC,SAASC,SAAS;AAClB,SACEC,MAAM;AAKR,OAAO,MAAMC,qBAAqB,GAAG,MAAAA,CAAO;EAC1CC,YAAY;EACZC,YAAY;EACZC,QAAQ;EACRC;AACW,CAAC,GAAG,CAAC,CAAC,KAAyD;EAC1E,IAAIC,KAA4B;EAEhC,IAAIJ,YAAY,IAAIC,YAAY,EAAE;IAChC,MAAMI,UAAU,GAAG,MAAMC,OAAO,CAACX,IAAI,CAACM,YAAY,EAAED,YAAY,CAAC,CAAC;IAClE,MAAM;MAAEO;IAAK,CAAC,GAAGX,KAAK,CAACI,YAAY,CAAC;IAEpCI,KAAK,GAAG,IAAIP,SAAS,CAACQ,UAAU,EAAE;MAAEG,QAAQ,EAAED;IAAK,CAAC,EAAEL,QAAQ,EAAEC,WAAW,CAAC;EAC9E;EAEA,OAAO;IACLL,MAAM;IACNW,OAAO,EAAE;MAAEL,KAAK;MAAEF,QAAQ;MAAEC;IAAY;EAC1C,CAAC;AACH,CAAC;AAED,OAAO,eAAeG,OAAOA,CAACI,UAAkB,EAAE;EAChD,MAAM;IAAEC;EAAI,CAAC,GAAGf,KAAK,CAACc,UAAU,CAAC;EAEjC,MAAME,UAA4B,GAAG;IACnCC,IAAI,EAAEF,GAAG,KAAK,OAAO,GAAG,MAAM,GAAG;EACnC,CAAC;EAED,MAAMG,UAAU,GAAG,MAAM,CAACJ,UAAU,EAAE;IAAEK,IAAI,EAAEH;EAAW,CAAC,CAExD;EAEF,MAAM;IAAEI,OAAO,EAAEX;EAAW,CAAC,GAAG,MAAMS,UAAU;EAChD,OAAOT,UAAU;AACnB","ignoreList":[]}
|