@defra/forms-engine-plugin 5.0.0-alpha.11 → 5.0.0-alpha.13
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/javascripts/shared.min.js +1 -1
- package/.public/javascripts/shared.min.js.map +1 -1
- package/.server/client/javascripts/geospatial-map.d.ts +153 -5
- package/.server/client/javascripts/geospatial-map.js +147 -46
- package/.server/client/javascripts/geospatial-map.js.map +1 -1
- package/.server/client/javascripts/location-map.d.ts +38 -0
- package/.server/client/javascripts/location-map.js +42 -2
- 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 +4 -0
- package/.server/client/javascripts/map.js +5 -0
- package/.server/client/javascripts/map.js.map +1 -1
- 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/CheckboxesField.d.ts +20 -2
- package/.server/server/plugins/engine/components/CheckboxesField.js +24 -12
- package/.server/server/plugins/engine/components/CheckboxesField.js.map +1 -1
- package/.server/server/plugins/engine/components/EastingNorthingField.d.ts +4 -0
- package/.server/server/plugins/engine/components/EastingNorthingField.js +1 -1
- package/.server/server/plugins/engine/components/EastingNorthingField.js.map +1 -1
- package/.server/server/plugins/engine/components/FileUploadField.d.ts +10 -1
- package/.server/server/plugins/engine/components/FileUploadField.js +18 -6
- package/.server/server/plugins/engine/components/FileUploadField.js.map +1 -1
- package/.server/server/plugins/engine/components/GeospatialField.d.ts +22 -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/LatLongField.d.ts +4 -0
- package/.server/server/plugins/engine/components/LocationFieldBase.js +7 -1
- package/.server/server/plugins/engine/components/LocationFieldBase.js.map +1 -1
- package/.server/server/plugins/engine/components/LocationFieldHelpers.d.ts +4 -0
- package/.server/server/plugins/engine/components/LocationFieldHelpers.js +9 -2
- package/.server/server/plugins/engine/components/LocationFieldHelpers.js.map +1 -1
- package/.server/server/plugins/engine/components/helpers/components.js +2 -1
- package/.server/server/plugins/engine/components/helpers/components.js.map +1 -1
- package/.server/server/plugins/engine/components/helpers/geospatial.d.ts +5 -0
- package/.server/server/plugins/engine/components/helpers/geospatial.js +25 -16
- package/.server/server/plugins/engine/components/helpers/geospatial.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/i18n/buildValidationMessages.d.ts +1 -1
- package/.server/server/plugins/engine/i18n/buildValidationMessages.js +30 -9
- package/.server/server/plugins/engine/i18n/buildValidationMessages.js.map +1 -1
- package/.server/server/plugins/engine/i18n/translations/cy.json +117 -11
- package/.server/server/plugins/engine/i18n/translations/en-GB.json +80 -11
- package/.server/server/plugins/engine/i18n/types.d.ts +1 -0
- package/.server/server/plugins/engine/i18n/types.js.map +1 -1
- package/.server/server/plugins/engine/models/FormModel.js +10 -2
- package/.server/server/plugins/engine/models/FormModel.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/pageControllers/helpers/pages.js +2 -1
- package/.server/server/plugins/engine/pageControllers/helpers/pages.js.map +1 -1
- package/.server/server/plugins/engine/pageControllers/validationOptions.d.ts +1 -1
- package/.server/server/plugins/engine/pageControllers/validationOptions.js +1 -1
- package/.server/server/plugins/engine/pageControllers/validationOptions.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 +2 -1
- package/.server/server/plugins/engine/views/components/geospatialfield.html +1 -0
- package/.server/server/plugins/engine/views/components/osgridreffield.html +3 -1
- package/.server/server/plugins/engine/views/unavailable.html +14 -11
- package/package.json +1 -1
- package/src/client/javascripts/geospatial-map.js +169 -47
- package/src/client/javascripts/location-map.js +50 -2
- package/src/client/javascripts/map-constants.js +3 -0
- package/src/client/javascripts/map.js +5 -0
- package/src/server/plugins/engine/__stubs__/definitions.ts +155 -0
- package/src/server/plugins/engine/components/CheckboxesField.ts +34 -13
- package/src/server/plugins/engine/components/EastingNorthingField.ts +1 -1
- package/src/server/plugins/engine/components/FileUploadField.ts +26 -6
- package/src/server/plugins/engine/components/GeospatialField.ts +44 -11
- package/src/server/plugins/engine/components/LocationFieldBase.ts +7 -1
- package/src/server/plugins/engine/components/LocationFieldHelpers.ts +9 -2
- package/src/server/plugins/engine/components/helpers/components.ts +2 -1
- package/src/server/plugins/engine/components/helpers/geospatial.ts +32 -22
- 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/i18n/buildValidationMessages.ts +15 -10
- package/src/server/plugins/engine/i18n/translations/cy.json +117 -11
- package/src/server/plugins/engine/i18n/translations/en-GB.json +80 -11
- package/src/server/plugins/engine/i18n/types.ts +1 -0
- package/src/server/plugins/engine/models/FormModel.ts +12 -2
- package/src/server/plugins/engine/models/unavailable-view-model.ts +26 -5
- package/src/server/plugins/engine/pageControllers/helpers/pages.ts +2 -1
- package/src/server/plugins/engine/pageControllers/validationOptions.ts +2 -2
- package/src/server/plugins/engine/unavailable-response.ts +6 -2
- package/src/server/plugins/engine/views/components/_location-field-base.html +2 -1
- package/src/server/plugins/engine/views/components/geospatialfield.html +1 -0
- package/src/server/plugins/engine/views/components/osgridreffield.html +3 -1
- package/src/server/plugins/engine/views/unavailable.html +14 -11
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FormModel.js","names":["ComponentType","ConditionsModel","ControllerPath","ControllerType","SchemaVersion","convertConditionWrapperFromV2","formDefinitionSchema","formDefinitionV2Schema","generateConditionAlias","hasComponents","hasComponentsEvenIfNoNext","hasRepeater","isConditionWrapperV2","yesNoListId","yesNoListName","add","format","Parser","joi","logger","EN_GB","hasListFormField","todayAsDateOnly","findPage","getError","getPage","loadFormTranslations","createTranslator","extractBaseTranslations","createFormI18nInstance","getAvailableLanguages","createPage","validationOptions","opts","defaultServices","FormAction","merge","FormModel","engine","schemaVersion","def","lists","sections","name","formId","values","basePath","ordnanceSurveyApiKey","conditions","pages","services","i18nInstance","controllers","pageDefMap","listDefMap","listDefIdMap","componentDefMap","componentDefIdMap","pageMap","componentMap","constructor","options","schema","V1","warn","result","validate","abortEarly","error","structuredClone","value","baseTranslations","push","id","title","type","items","text","moreThanOnePaymentQuestion","Error","Map","map","page","path","list","filter","flatMap","components","component","forEach","conditionDef","condition","makeCondition","pageDef","some","controller","Status","collection","language","metadata","translations","makeFilteredSchema","relevantPages","object","required","concat","stateSchema","parser","operators","logical","Object","assign","functions","dateForComparison","timePeriod","timeUnit","displayName","expr","toConditionExpression","fn","evaluationState","ctx","toConditionContext","evaluate","context","conditionId","propertyName","V2","defineProperty","get","from","parse","toExpression","getList","nameOrId","find","getSection","section","getFormContext","request","state","errors","translator","query","currentPath","startPath","getStartPath","isForceAccess","relevantState","payload","getFormDataFromState","paths","data","referenceNumber","getReferenceNumber","languages","validateFormPayload","nextPage","initialiseContext","assignEvaluationState","assignRelevantState","pageStateIsInvalid","getNextPath","validateFormState","assignPaths","emptyState","freeze","getContextValueFromState","key","keys","listFields","fields","field","undefined","YesNoField","hasOptionalItems","item","length","fieldStateIsInvalid","validValues","fieldState","getFormValueFromState","isInvalid","isArray","Array","every","includes","t","href","getComponentById","componentId","getListById","listId","getConditionById","numOfPaymentFields","comp","PaymentField","action","getFormParams","Validate","startsWith","External","update","CheckboxesField","formState","getStateFromValidForm","previousPages","relevantPage","model","stripUnknown","errorsState","details","$$__referenceNumber"],"sources":["../../../../../src/server/plugins/engine/models/FormModel.ts"],"sourcesContent":["import {\n ComponentType,\n ConditionsModel,\n ControllerPath,\n ControllerType,\n SchemaVersion,\n convertConditionWrapperFromV2,\n formDefinitionSchema,\n formDefinitionV2Schema,\n generateConditionAlias,\n hasComponents,\n hasComponentsEvenIfNoNext,\n hasRepeater,\n isConditionWrapperV2,\n yesNoListId,\n yesNoListName,\n type ComponentDef,\n type ConditionWrapper,\n type ConditionWrapperV2,\n type ConditionsModelData,\n type DateUnits,\n type Engine,\n type FormDefinition,\n type List,\n type Page,\n type Section\n} from '@defra/forms-model'\nimport { add, format } from 'date-fns'\nimport { Parser, type Value } from 'expr-eval-fork'\nimport { type i18n } from 'i18next'\nimport joi from 'joi'\n\nimport { logger } from '~/src/server/common/helpers/logging/logger.js'\nimport { EN_GB } from '~/src/server/constants.js'\nimport { type ListFormComponent } from '~/src/server/plugins/engine/components/ListFormComponent.js'\nimport {} from '~/src/server/plugins/engine/components/YesNoField.js'\nimport {\n hasListFormField,\n type Component\n} from '~/src/server/plugins/engine/components/helpers/components.js'\nimport { todayAsDateOnly } from '~/src/server/plugins/engine/date-helper.js'\nimport {\n findPage,\n getError,\n getPage\n} from '~/src/server/plugins/engine/helpers.js'\nimport { loadFormTranslations } from '~/src/server/plugins/engine/i18n/createFormTranslator.js'\nimport { createTranslator } from '~/src/server/plugins/engine/i18n/createTranslator.js'\nimport { extractBaseTranslations } from '~/src/server/plugins/engine/i18n/extractBaseTranslations.js'\nimport { createFormI18nInstance } from '~/src/server/plugins/engine/i18n/index.js'\nimport { getAvailableLanguages } from '~/src/server/plugins/engine/i18n/languages.js'\nimport { type Translator } from '~/src/server/plugins/engine/i18n/types.js'\nimport { type ExecutableCondition } from '~/src/server/plugins/engine/models/types.js'\nimport { type PageController } from '~/src/server/plugins/engine/pageControllers/PageController.js'\nimport {\n createPage,\n type PageControllerClass\n} from '~/src/server/plugins/engine/pageControllers/helpers/pages.js'\nimport { validationOptions as opts } from '~/src/server/plugins/engine/pageControllers/validationOptions.js'\nimport * as defaultServices from '~/src/server/plugins/engine/services/index.js'\nimport {\n type FormContext,\n type FormContextRequest,\n type FormState,\n type FormSubmissionError,\n type FormSubmissionState\n} from '~/src/server/plugins/engine/types.js'\nimport { FormAction } from '~/src/server/routes/types.js'\nimport { merge } from '~/src/server/services/cacheService.js'\nimport { type Services } from '~/src/server/types.js'\n\nexport class FormModel {\n /** The runtime engine that should be used */\n engine?: Engine\n\n schemaVersion: SchemaVersion\n\n /** the entire form JSON as an object */\n def: FormDefinition\n\n lists: FormDefinition['lists']\n sections: FormDefinition['sections'] = []\n name: string\n formId: string\n values: FormDefinition\n basePath: string\n ordnanceSurveyApiKey?: string\n conditions: Partial<Record<string, ExecutableCondition>>\n pages: PageControllerClass[]\n services: Services\n private readonly i18nInstance: i18n\n\n controllers?: Record<string, typeof PageController>\n pageDefMap: Map<string, Page>\n\n listDefMap: Map<string, List>\n listDefIdMap: Map<string, List>\n\n componentDefMap: Map<string, ComponentDef>\n componentDefIdMap: Map<string, ComponentDef>\n\n pageMap: Map<string, PageControllerClass>\n componentMap: Map<string, Component>\n\n constructor(\n def: typeof this.def,\n options: {\n basePath: string\n ordnanceSurveyApiKey?: string\n formId?: string\n },\n services: Services = defaultServices,\n controllers?: Record<string, typeof PageController>\n ) {\n let schema = formDefinitionV2Schema\n\n if (!def.schema || def.schema === SchemaVersion.V1) {\n logger.warn(\n `[DEPRECATION NOTICE] Form \"${def.name}\" constructed with legacy V1 schema. See https://defra.github.io/forms-engine-plugin/schemas/form-definition-schema.html.`\n )\n schema = formDefinitionSchema\n }\n\n const result = schema.validate(def, { abortEarly: false })\n\n if (result.error) {\n throw result.error\n }\n\n // Make a clone of the shallow copy returned\n // by joi so as not to change the source data.\n def = structuredClone(result.value)\n\n const baseTranslations = extractBaseTranslations(def)\n this.i18nInstance = createFormI18nInstance(baseTranslations)\n loadFormTranslations(def, this.i18nInstance)\n\n // Add default lists. Yes/No text stored as i18n key constants so they\n // resolve to the user's language at render time via the translator.\n def.lists.push({\n id: def.schema === SchemaVersion.V1 ? yesNoListName : yesNoListId,\n name: '__yesNo',\n title: 'Yes/No',\n type: 'boolean',\n items: [\n {\n id: '02900d42-83d1-4c72-a719-c4e8228952fa',\n text: 'components.yesNoField.yes',\n value: true\n },\n {\n id: 'f39000eb-c51b-4019-8f82-bbda0423f04d',\n text: 'components.yesNoField.no',\n value: false\n }\n ]\n })\n\n this.engine = def.engine\n this.schemaVersion = def.schema ?? SchemaVersion.V1\n this.def = def\n this.lists = def.lists\n this.sections = def.sections\n this.name = def.name ?? ''\n this.formId = options.formId ?? ''\n this.values = result.value\n this.basePath = options.basePath\n this.ordnanceSurveyApiKey = options.ordnanceSurveyApiKey\n this.conditions = {}\n this.services = services\n this.controllers = controllers\n\n // Assert that there is only one payment question (if any)\n if (this.moreThanOnePaymentQuestion()) {\n throw new Error(\n 'Invalid form definition: Only one payment question is allowed per form'\n )\n }\n\n this.pageDefMap = new Map(def.pages.map((page) => [page.path, page]))\n this.listDefMap = new Map(def.lists.map((list) => [list.name, list]))\n this.listDefIdMap = new Map(\n def.lists\n .filter((list) => list.id) // Skip lists without an ID\n // eslint-disable-next-line @typescript-eslint/non-nullable-type-assertion-style\n .map((list) => [list.id as string, list])\n )\n this.componentDefMap = new Map(\n def.pages\n .filter(hasComponents)\n .flatMap((page) =>\n page.components.map((component) => [component.name, component])\n )\n )\n this.componentDefIdMap = new Map(\n def.pages.filter(hasComponents).flatMap((page) =>\n page.components\n .filter((component) => component.id) // Skip components without an ID\n .map((component) => {\n // eslint-disable-next-line @typescript-eslint/non-nullable-type-assertion-style\n return [component.id as string, component]\n })\n )\n )\n\n def.conditions.forEach((conditionDef) => {\n const condition = this.makeCondition(\n isConditionWrapperV2(conditionDef)\n ? convertConditionWrapperFromV2(conditionDef, this)\n : conditionDef\n )\n this.conditions[condition.name] = condition\n })\n\n this.pages = def.pages.map((pageDef) => createPage(this, pageDef))\n\n if (\n !def.pages.some(\n ({ controller }) =>\n // Check for user-provided status page (optional)\n controller === ControllerType.Status\n )\n ) {\n this.pages.push(\n createPage(this, {\n title: 'pages.confirmation.formSubmitted',\n path: ControllerPath.Status,\n controller: ControllerType.Status\n })\n )\n }\n\n this.pageMap = new Map(this.pages.map((page) => [page.path, page]))\n this.componentMap = new Map(\n this.pages.flatMap((page) =>\n page.collection.components.map((component) => [\n component.name,\n component\n ])\n )\n )\n }\n\n /** Returns a scoped translator pair for the given language. */\n createTranslator(language = EN_GB): Translator {\n // @ts-expect-error - dynamic language lookup\n if (!this.def.metadata?.translations?.[language]) {\n // If not translations defined in the FormDefinition, always default to English\n language = EN_GB\n }\n return createTranslator(this.i18nInstance, language)\n }\n\n /**\n * build the entire model schema from individual pages/sections and filter out answers\n * for pages which are no longer accessible due to an answer that has been changed\n */\n makeFilteredSchema(relevantPages: PageControllerClass[]) {\n // Build the entire model schema\n // from the individual pages/sections\n let schema = joi.object<FormSubmissionState>().required()\n\n relevantPages.forEach((page) => {\n schema = schema.concat(page.collection.stateSchema)\n })\n\n return schema\n }\n\n /**\n * Instantiates a Condition based on {@link ConditionWrapper}\n * @param condition\n */\n makeCondition(condition: ConditionWrapper): ExecutableCondition {\n const parser = new Parser({\n operators: {\n logical: true\n }\n })\n\n Object.assign(parser.functions, {\n dateForComparison(timePeriod: number, timeUnit: DateUnits) {\n // The time element must be stripped (hence using startOfDay() which has no time element),\n // then formatted as YYYY-MM-DD otherwise we can hit time element and BST issues giving the\n // wrong date to compare against.\n // Do not use .toISOString() to format the date as that introduces BST errors.\n return format(\n add(todayAsDateOnly(), { [timeUnit]: timePeriod }),\n 'yyyy-MM-dd'\n )\n }\n })\n\n const { name, displayName, value } = condition\n const expr = this.toConditionExpression(value, parser)\n\n const fn = (evaluationState: FormState) => {\n const ctx = this.toConditionContext(evaluationState, this.conditions)\n try {\n return expr.evaluate(ctx) as boolean\n } catch {\n return false\n }\n }\n\n return {\n name,\n displayName,\n value,\n expr,\n fn\n }\n }\n\n toConditionContext(\n evaluationState: FormState,\n conditions: Partial<Record<string, ExecutableCondition>>\n ) {\n const context = { ...evaluationState }\n\n for (const conditionId in conditions) {\n const propertyName =\n this.schemaVersion === SchemaVersion.V2\n ? generateConditionAlias(conditionId)\n : conditionId\n\n Object.defineProperty(context, propertyName, {\n get() {\n return conditions[conditionId]?.fn(evaluationState)\n }\n })\n }\n\n return context as Extract<Value, Record<string, Value>>\n }\n\n toConditionExpression(value: ConditionsModelData, parser: Parser) {\n const conditions = ConditionsModel.from(value)\n return parser.parse(conditions.toExpression())\n }\n\n getList(nameOrId: string): List | undefined {\n return this.schemaVersion === SchemaVersion.V1\n ? this.lists.find((list) => list.name === nameOrId)\n : this.lists.find((list) => list.id === nameOrId)\n }\n\n getSection(nameOrId: string): Section | undefined {\n return this.schemaVersion === SchemaVersion.V1\n ? this.sections.find((section) => section.name === nameOrId)\n : this.sections.find((section) => section.id === nameOrId)\n }\n\n /**\n * Form context for the current page\n */\n getFormContext(\n request: FormContextRequest,\n state: FormSubmissionState,\n errors?: FormSubmissionError[],\n translator?: Translator\n ): FormContext {\n const { query } = request\n\n const page = getPage(this, request)\n\n // Determine form paths\n const currentPath = page.path\n const startPath = page.getStartPath()\n\n // Preview URL direct access is allowed\n const isForceAccess = 'force' in query\n\n let context: FormContext = {\n evaluationState: {},\n relevantState: {},\n relevantPages: [],\n payload: page.getFormDataFromState(request, state),\n state,\n paths: [],\n errors,\n isForceAccess,\n data: {},\n pageDefMap: this.pageDefMap,\n listDefMap: this.listDefMap,\n componentDefMap: this.componentDefMap,\n pageMap: this.pageMap,\n componentMap: this.componentMap,\n referenceNumber: getReferenceNumber(state),\n languages: getAvailableLanguages(this.def),\n translator\n }\n\n // Validate current page\n context = validateFormPayload(request, page, context, translator)\n\n // Find start page\n let nextPage = findPage(this, startPath)\n\n this.initialiseContext(context)\n\n // Walk form pages from start\n while (nextPage) {\n // Add page to context\n context.relevantPages.push(nextPage)\n\n this.assignEvaluationState(context, nextPage)\n\n this.assignRelevantState(context, nextPage)\n\n // Stop at current page\n if (\n this.pageStateIsInvalid(context, nextPage, translator) ||\n nextPage.path === currentPath\n ) {\n break\n }\n\n // Apply conditions to determine next page\n nextPage = findPage(this, nextPage.getNextPath(context))\n }\n\n // Validate form state\n context = validateFormState(request, page, context)\n\n // Add paths for navigation\n this.assignPaths(context)\n\n return context\n }\n\n private initialiseContext(context: FormContext) {\n // Initialise `evaluationState` for all keys using empty state.\n // This is because the current condition evaluation library (eval-expr)\n // will throw if an expression uses a key that is undefined.\n const emptyState = Object.freeze({})\n\n for (const page of this.pages) {\n const { collection, pageDef } = page\n\n if (!hasRepeater(pageDef)) {\n Object.assign(\n context.evaluationState,\n collection.getContextValueFromState(emptyState)\n )\n }\n }\n }\n\n private assignEvaluationState(\n context: FormContext,\n page: PageControllerClass\n ) {\n const { collection, pageDef } = page\n // Skip evaluation state for repeater pages\n\n if (!hasRepeater(pageDef)) {\n Object.assign(\n context.evaluationState,\n collection.getContextValueFromState(context.state)\n )\n }\n }\n\n private assignRelevantState(context: FormContext, page: PageControllerClass) {\n // Copy relevant state by expected keys\n for (const key of page.keys) {\n if (typeof context.state[key] !== 'undefined') {\n context.relevantState[key] = context.state[key]\n }\n }\n }\n\n private pageStateIsInvalid(\n context: FormContext,\n page: PageControllerClass,\n translator?: Translator\n ) {\n // Get any list-bound fields on the page\n const listFields = page.collection.fields.filter(hasListFormField)\n\n // For each list field that is bound to a list that contains any conditional items,\n // we need to check any answers are still valid. Do this by evaluating the conditions\n // and ensuring any current answers are all included in the set of valid answers\n for (const field of listFields) {\n const list = field.list\n\n // Filter out YesNo as they can't be conditional\n if (list !== undefined && field.type !== ComponentType.YesNoField) {\n const hasOptionalItems =\n list.items.filter((item) => item.condition).length > 0\n\n if (hasOptionalItems) {\n return this.fieldStateIsInvalid(context, field, list, translator)\n }\n }\n }\n }\n\n private fieldStateIsInvalid(\n context: FormContext,\n field: ListFormComponent,\n list: List,\n translator?: Translator\n ) {\n const { evaluationState, state } = context\n\n const validValues = list.items\n .filter((item) =>\n item.condition\n ? this.conditions[item.condition]?.fn(evaluationState)\n : true\n )\n .map((item) => item.value)\n\n // Get the field state\n const fieldState = field.getFormValueFromState(state)\n\n if (fieldState !== undefined) {\n let isInvalid = false\n const isArray = Array.isArray(fieldState)\n\n // Check if any saved state value(s) are still valid\n // and return true if any are invalid\n if (isArray) {\n isInvalid = !fieldState.every((item) => validValues.includes(item))\n } else {\n isInvalid = !validValues.includes(fieldState)\n }\n\n if (isInvalid) {\n context.errors ??= []\n\n const text = (translator ?? this.createTranslator('en-GB')).t(\n 'errors.optionsMismatch'\n )\n\n context.errors.push({\n text,\n name: field.name,\n href: `#${field.name}`,\n path: [`#${field.name}`]\n })\n }\n\n return isInvalid\n }\n }\n\n private assignPaths(context: FormContext) {\n for (const { keys, path } of context.relevantPages) {\n context.paths.push(path)\n\n // Stop at page with errors\n if (\n context.errors?.some(({ name, path }) => {\n return keys.includes(name) || keys.some((key) => path.includes(key))\n })\n ) {\n break\n }\n }\n }\n\n getComponentById(componentId: string): ComponentDef | undefined {\n return this.componentDefIdMap.get(componentId)\n }\n\n getListById(listId: string): List | undefined {\n return this.listDefIdMap.get(listId)\n }\n\n /**\n * Returns a condition by its ID. O(n) lookup time.\n * @param conditionId\n * @returns\n */\n getConditionById(conditionId: string): ConditionWrapperV2 | undefined {\n return this.def.conditions\n .filter(isConditionWrapperV2)\n .find((condition) => condition.id === conditionId)\n }\n\n /**\n * Checks that only one payment field exists (if any payments fields exist)\n */\n moreThanOnePaymentQuestion() {\n const numOfPaymentFields = this.def.pages\n .flatMap((page) =>\n hasComponentsEvenIfNoNext(page) ? page.components : []\n )\n .filter((comp) => comp.type === ComponentType.PaymentField).length\n return numOfPaymentFields > 1\n }\n}\n\n/**\n * Validate current page only\n */\nfunction validateFormPayload(\n request: FormContextRequest,\n page: PageControllerClass,\n context: FormContext,\n translator?: Translator\n): FormContext {\n const { collection } = page\n const { payload, state } = context\n\n const { action } = page.getFormParams(request)\n\n // Skip validation GET requests or other actions\n if (\n !request.payload ||\n (action &&\n action !== FormAction.Validate &&\n !action.startsWith(FormAction.External))\n ) {\n return context\n }\n\n // For checkbox fields missing in the payload (i.e. unchecked),\n // explicitly set their value to undefined so that any previously\n // stored value is cleared and required field validation is enforced.\n const update = { ...request.payload }\n collection.fields.forEach((field) => {\n if (\n field.type === ComponentType.CheckboxesField &&\n !(field.name in update)\n ) {\n update[field.name] = undefined\n }\n })\n\n const { value, errors } = collection.validate(\n { ...payload, ...update },\n translator\n )\n\n // Add sanitised payload (ready to save)\n const formState = page.getStateFromValidForm(request, state, value)\n\n return {\n ...context,\n payload: merge(payload, value),\n state: merge(state, formState),\n errors\n }\n}\n\n/**\n * Validate entire form state\n */\nfunction validateFormState(\n request: FormContextRequest,\n page: PageControllerClass,\n context: FormContext\n): FormContext {\n const { errors = [], relevantPages, relevantState } = context\n\n // Exclude current page\n const previousPages = relevantPages.filter(\n (relevantPage) => relevantPage !== page\n )\n\n // Validate relevant state\n const { error } = page.model\n .makeFilteredSchema(previousPages)\n .validate(relevantState, { ...opts, stripUnknown: true })\n\n // Add relevant state errors\n if (error) {\n const errorsState = error.details.map((item) => getError(EN_GB, item))\n return { ...context, errors: errors.concat(errorsState) }\n }\n\n return context\n}\n\nfunction getReferenceNumber(state: FormSubmissionState): string {\n if (\n !state.$$__referenceNumber ||\n typeof state.$$__referenceNumber !== 'string'\n ) {\n throw Error('Reference number not found in form state')\n }\n\n return state.$$__referenceNumber\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"FormModel.js","names":["ComponentType","ConditionsModel","ControllerPath","ControllerType","SchemaVersion","convertConditionWrapperFromV2","formDefinitionSchema","formDefinitionV2Schema","generateConditionAlias","hasComponents","hasComponentsEvenIfNoNext","hasRepeater","isConditionWrapperV2","yesNoListId","yesNoListName","add","format","Parser","joi","logger","EN_GB","hasListFormField","todayAsDateOnly","ConditionBuildError","SchemaValidationError","findPage","getError","getPage","loadFormTranslations","createTranslator","extractBaseTranslations","createFormI18nInstance","getAvailableLanguages","createPage","validationOptions","opts","defaultServices","FormAction","merge","FormModel","engine","schemaVersion","def","lists","sections","name","formId","values","basePath","ordnanceSurveyApiKey","conditions","pages","services","i18nInstance","controllers","pageDefMap","listDefMap","listDefIdMap","componentDefMap","componentDefIdMap","pageMap","componentMap","constructor","options","schema","V1","warn","result","validate","abortEarly","error","structuredClone","value","baseTranslations","push","id","title","type","items","text","moreThanOnePaymentQuestion","Error","Map","map","page","path","list","filter","flatMap","components","component","forEach","conditionDef","condition","makeCondition","pageDef","some","controller","Status","collection","language","metadata","translations","makeFilteredSchema","relevantPages","object","required","concat","stateSchema","parser","operators","logical","Object","assign","functions","dateForComparison","timePeriod","timeUnit","displayName","expr","toConditionExpression","cause","fn","evaluationState","ctx","toConditionContext","evaluate","context","conditionId","propertyName","V2","defineProperty","get","from","parse","toExpression","getList","nameOrId","find","getSection","section","getFormContext","request","state","errors","translator","query","currentPath","startPath","getStartPath","isForceAccess","relevantState","payload","getFormDataFromState","paths","data","referenceNumber","getReferenceNumber","languages","validateFormPayload","nextPage","initialiseContext","assignEvaluationState","assignRelevantState","pageStateIsInvalid","getNextPath","validateFormState","assignPaths","emptyState","freeze","getContextValueFromState","key","keys","listFields","fields","field","undefined","YesNoField","hasOptionalItems","item","length","fieldStateIsInvalid","validValues","fieldState","getFormValueFromState","isInvalid","isArray","Array","every","includes","t","href","getComponentById","componentId","getListById","listId","getConditionById","numOfPaymentFields","comp","PaymentField","action","getFormParams","Validate","startsWith","External","update","CheckboxesField","formState","getStateFromValidForm","previousPages","relevantPage","model","stripUnknown","errorsState","details","$$__referenceNumber"],"sources":["../../../../../src/server/plugins/engine/models/FormModel.ts"],"sourcesContent":["import {\n ComponentType,\n ConditionsModel,\n ControllerPath,\n ControllerType,\n SchemaVersion,\n convertConditionWrapperFromV2,\n formDefinitionSchema,\n formDefinitionV2Schema,\n generateConditionAlias,\n hasComponents,\n hasComponentsEvenIfNoNext,\n hasRepeater,\n isConditionWrapperV2,\n yesNoListId,\n yesNoListName,\n type ComponentDef,\n type ConditionWrapper,\n type ConditionWrapperV2,\n type ConditionsModelData,\n type DateUnits,\n type Engine,\n type FormDefinition,\n type List,\n type Page,\n type Section\n} from '@defra/forms-model'\nimport { add, format } from 'date-fns'\nimport { Parser, type Value } from 'expr-eval-fork'\nimport { type i18n } from 'i18next'\nimport joi from 'joi'\n\nimport { logger } from '~/src/server/common/helpers/logging/logger.js'\nimport { EN_GB } from '~/src/server/constants.js'\nimport { type ListFormComponent } from '~/src/server/plugins/engine/components/ListFormComponent.js'\nimport {} from '~/src/server/plugins/engine/components/YesNoField.js'\nimport {\n hasListFormField,\n type Component\n} from '~/src/server/plugins/engine/components/helpers/components.js'\nimport { todayAsDateOnly } from '~/src/server/plugins/engine/date-helper.js'\nimport {\n ConditionBuildError,\n SchemaValidationError\n} from '~/src/server/plugins/engine/errors.js'\nimport {\n findPage,\n getError,\n getPage\n} from '~/src/server/plugins/engine/helpers.js'\nimport { loadFormTranslations } from '~/src/server/plugins/engine/i18n/createFormTranslator.js'\nimport { createTranslator } from '~/src/server/plugins/engine/i18n/createTranslator.js'\nimport { extractBaseTranslations } from '~/src/server/plugins/engine/i18n/extractBaseTranslations.js'\nimport { createFormI18nInstance } from '~/src/server/plugins/engine/i18n/index.js'\nimport { getAvailableLanguages } from '~/src/server/plugins/engine/i18n/languages.js'\nimport { type Translator } from '~/src/server/plugins/engine/i18n/types.js'\nimport { type ExecutableCondition } from '~/src/server/plugins/engine/models/types.js'\nimport { type PageController } from '~/src/server/plugins/engine/pageControllers/PageController.js'\nimport {\n createPage,\n type PageControllerClass\n} from '~/src/server/plugins/engine/pageControllers/helpers/pages.js'\nimport { validationOptions as opts } from '~/src/server/plugins/engine/pageControllers/validationOptions.js'\nimport * as defaultServices from '~/src/server/plugins/engine/services/index.js'\nimport {\n type FormContext,\n type FormContextRequest,\n type FormState,\n type FormSubmissionError,\n type FormSubmissionState\n} from '~/src/server/plugins/engine/types.js'\nimport { FormAction } from '~/src/server/routes/types.js'\nimport { merge } from '~/src/server/services/cacheService.js'\nimport { type Services } from '~/src/server/types.js'\n\nexport class FormModel {\n /** The runtime engine that should be used */\n engine?: Engine\n\n schemaVersion: SchemaVersion\n\n /** the entire form JSON as an object */\n def: FormDefinition\n\n lists: FormDefinition['lists']\n sections: FormDefinition['sections'] = []\n name: string\n formId: string\n values: FormDefinition\n basePath: string\n ordnanceSurveyApiKey?: string\n conditions: Partial<Record<string, ExecutableCondition>>\n pages: PageControllerClass[]\n services: Services\n private readonly i18nInstance: i18n\n\n controllers?: Record<string, typeof PageController>\n pageDefMap: Map<string, Page>\n\n listDefMap: Map<string, List>\n listDefIdMap: Map<string, List>\n\n componentDefMap: Map<string, ComponentDef>\n componentDefIdMap: Map<string, ComponentDef>\n\n pageMap: Map<string, PageControllerClass>\n componentMap: Map<string, Component>\n\n constructor(\n def: typeof this.def,\n options: {\n basePath: string\n ordnanceSurveyApiKey?: string\n formId?: string\n },\n services: Services = defaultServices,\n controllers?: Record<string, typeof PageController>\n ) {\n let schema = formDefinitionV2Schema\n\n if (!def.schema || def.schema === SchemaVersion.V1) {\n logger.warn(\n `[DEPRECATION NOTICE] Form \"${def.name}\" constructed with legacy V1 schema. See https://defra.github.io/forms-engine-plugin/schemas/form-definition-schema.html.`\n )\n schema = formDefinitionSchema\n }\n\n const result = schema.validate(def, { abortEarly: false })\n\n if (result.error) {\n throw new SchemaValidationError(result.error)\n }\n\n // Make a clone of the shallow copy returned\n // by joi so as not to change the source data.\n def = structuredClone(result.value)\n\n const baseTranslations = extractBaseTranslations(def)\n this.i18nInstance = createFormI18nInstance(baseTranslations)\n loadFormTranslations(def, this.i18nInstance)\n\n // Add default lists. Yes/No text stored as i18n key constants so they\n // resolve to the user's language at render time via the translator.\n def.lists.push({\n id: def.schema === SchemaVersion.V1 ? yesNoListName : yesNoListId,\n name: '__yesNo',\n title: 'Yes/No',\n type: 'boolean',\n items: [\n {\n id: '02900d42-83d1-4c72-a719-c4e8228952fa',\n text: 'components.yesNoField.yes',\n value: true\n },\n {\n id: 'f39000eb-c51b-4019-8f82-bbda0423f04d',\n text: 'components.yesNoField.no',\n value: false\n }\n ]\n })\n\n this.engine = def.engine\n this.schemaVersion = def.schema ?? SchemaVersion.V1\n this.def = def\n this.lists = def.lists\n this.sections = def.sections\n this.name = def.name ?? ''\n this.formId = options.formId ?? ''\n this.values = result.value\n this.basePath = options.basePath\n this.ordnanceSurveyApiKey = options.ordnanceSurveyApiKey\n this.conditions = {}\n this.services = services\n this.controllers = controllers\n\n // Assert that there is only one payment question (if any)\n if (this.moreThanOnePaymentQuestion()) {\n throw new Error(\n 'Invalid form definition: Only one payment question is allowed per form'\n )\n }\n\n this.pageDefMap = new Map(def.pages.map((page) => [page.path, page]))\n this.listDefMap = new Map(def.lists.map((list) => [list.name, list]))\n this.listDefIdMap = new Map(\n def.lists\n .filter((list) => list.id) // Skip lists without an ID\n // eslint-disable-next-line @typescript-eslint/non-nullable-type-assertion-style\n .map((list) => [list.id as string, list])\n )\n this.componentDefMap = new Map(\n def.pages\n .filter(hasComponents)\n .flatMap((page) =>\n page.components.map((component) => [component.name, component])\n )\n )\n this.componentDefIdMap = new Map(\n def.pages.filter(hasComponents).flatMap((page) =>\n page.components\n .filter((component) => component.id) // Skip components without an ID\n .map((component) => {\n // eslint-disable-next-line @typescript-eslint/non-nullable-type-assertion-style\n return [component.id as string, component]\n })\n )\n )\n\n def.conditions.forEach((conditionDef) => {\n const condition = this.makeCondition(\n isConditionWrapperV2(conditionDef)\n ? convertConditionWrapperFromV2(conditionDef, this)\n : conditionDef\n )\n this.conditions[condition.name] = condition\n })\n\n this.pages = def.pages.map((pageDef) => createPage(this, pageDef))\n\n if (\n !def.pages.some(\n ({ controller }) =>\n // Check for user-provided status page (optional)\n controller === ControllerType.Status\n )\n ) {\n this.pages.push(\n createPage(this, {\n title: 'pages.confirmation.formSubmitted',\n path: ControllerPath.Status,\n controller: ControllerType.Status\n })\n )\n }\n\n this.pageMap = new Map(this.pages.map((page) => [page.path, page]))\n this.componentMap = new Map(\n this.pages.flatMap((page) =>\n page.collection.components.map((component) => [\n component.name,\n component\n ])\n )\n )\n }\n\n /** Returns a scoped translator pair for the given language. */\n createTranslator(language = EN_GB): Translator {\n // @ts-expect-error - dynamic language lookup\n if (!this.def.metadata?.translations?.[language]) {\n // If not translations defined in the FormDefinition, always default to English\n language = EN_GB\n }\n return createTranslator(this.i18nInstance, language)\n }\n\n /**\n * build the entire model schema from individual pages/sections and filter out answers\n * for pages which are no longer accessible due to an answer that has been changed\n */\n makeFilteredSchema(relevantPages: PageControllerClass[]) {\n // Build the entire model schema\n // from the individual pages/sections\n let schema = joi.object<FormSubmissionState>().required()\n\n relevantPages.forEach((page) => {\n schema = schema.concat(page.collection.stateSchema)\n })\n\n return schema\n }\n\n /**\n * Instantiates a Condition based on {@link ConditionWrapper}\n * @param condition\n */\n makeCondition(condition: ConditionWrapper): ExecutableCondition {\n const parser = new Parser({\n operators: {\n logical: true\n }\n })\n\n Object.assign(parser.functions, {\n dateForComparison(timePeriod: number, timeUnit: DateUnits) {\n // The time element must be stripped (hence using startOfDay() which has no time element),\n // then formatted as YYYY-MM-DD otherwise we can hit time element and BST issues giving the\n // wrong date to compare against.\n // Do not use .toISOString() to format the date as that introduces BST errors.\n return format(\n add(todayAsDateOnly(), { [timeUnit]: timePeriod }),\n 'yyyy-MM-dd'\n )\n }\n })\n\n const { name, displayName, value } = condition\n\n let expr\n try {\n expr = this.toConditionExpression(value, parser)\n } catch (cause) {\n throw new ConditionBuildError(displayName, { cause })\n }\n\n const fn = (evaluationState: FormState) => {\n const ctx = this.toConditionContext(evaluationState, this.conditions)\n try {\n return expr.evaluate(ctx) as boolean\n } catch {\n return false\n }\n }\n\n return {\n name,\n displayName,\n value,\n expr,\n fn\n }\n }\n\n toConditionContext(\n evaluationState: FormState,\n conditions: Partial<Record<string, ExecutableCondition>>\n ) {\n const context = { ...evaluationState }\n\n for (const conditionId in conditions) {\n const propertyName =\n this.schemaVersion === SchemaVersion.V2\n ? generateConditionAlias(conditionId)\n : conditionId\n\n Object.defineProperty(context, propertyName, {\n get() {\n return conditions[conditionId]?.fn(evaluationState)\n }\n })\n }\n\n return context as Extract<Value, Record<string, Value>>\n }\n\n toConditionExpression(value: ConditionsModelData, parser: Parser) {\n const conditions = ConditionsModel.from(value)\n return parser.parse(conditions.toExpression())\n }\n\n getList(nameOrId: string): List | undefined {\n return this.schemaVersion === SchemaVersion.V1\n ? this.lists.find((list) => list.name === nameOrId)\n : this.lists.find((list) => list.id === nameOrId)\n }\n\n getSection(nameOrId: string): Section | undefined {\n return this.schemaVersion === SchemaVersion.V1\n ? this.sections.find((section) => section.name === nameOrId)\n : this.sections.find((section) => section.id === nameOrId)\n }\n\n /**\n * Form context for the current page\n */\n getFormContext(\n request: FormContextRequest,\n state: FormSubmissionState,\n errors?: FormSubmissionError[],\n translator?: Translator\n ): FormContext {\n const { query } = request\n\n const page = getPage(this, request)\n\n // Determine form paths\n const currentPath = page.path\n const startPath = page.getStartPath()\n\n // Preview URL direct access is allowed\n const isForceAccess = 'force' in query\n\n let context: FormContext = {\n evaluationState: {},\n relevantState: {},\n relevantPages: [],\n payload: page.getFormDataFromState(request, state),\n state,\n paths: [],\n errors,\n isForceAccess,\n data: {},\n pageDefMap: this.pageDefMap,\n listDefMap: this.listDefMap,\n componentDefMap: this.componentDefMap,\n pageMap: this.pageMap,\n componentMap: this.componentMap,\n referenceNumber: getReferenceNumber(state),\n languages: getAvailableLanguages(this.def),\n translator\n }\n\n // Validate current page\n context = validateFormPayload(request, page, context, translator)\n\n // Find start page\n let nextPage = findPage(this, startPath)\n\n this.initialiseContext(context)\n\n // Walk form pages from start\n while (nextPage) {\n // Add page to context\n context.relevantPages.push(nextPage)\n\n this.assignEvaluationState(context, nextPage)\n\n this.assignRelevantState(context, nextPage)\n\n // Stop at current page\n if (\n this.pageStateIsInvalid(context, nextPage, translator) ||\n nextPage.path === currentPath\n ) {\n break\n }\n\n // Apply conditions to determine next page\n nextPage = findPage(this, nextPage.getNextPath(context))\n }\n\n // Validate form state\n context = validateFormState(request, page, context)\n\n // Add paths for navigation\n this.assignPaths(context)\n\n return context\n }\n\n private initialiseContext(context: FormContext) {\n // Initialise `evaluationState` for all keys using empty state.\n // This is because the current condition evaluation library (eval-expr)\n // will throw if an expression uses a key that is undefined.\n const emptyState = Object.freeze({})\n\n for (const page of this.pages) {\n const { collection, pageDef } = page\n\n if (!hasRepeater(pageDef)) {\n Object.assign(\n context.evaluationState,\n collection.getContextValueFromState(emptyState)\n )\n }\n }\n }\n\n private assignEvaluationState(\n context: FormContext,\n page: PageControllerClass\n ) {\n const { collection, pageDef } = page\n // Skip evaluation state for repeater pages\n\n if (!hasRepeater(pageDef)) {\n Object.assign(\n context.evaluationState,\n collection.getContextValueFromState(context.state)\n )\n }\n }\n\n private assignRelevantState(context: FormContext, page: PageControllerClass) {\n // Copy relevant state by expected keys\n for (const key of page.keys) {\n if (typeof context.state[key] !== 'undefined') {\n context.relevantState[key] = context.state[key]\n }\n }\n }\n\n private pageStateIsInvalid(\n context: FormContext,\n page: PageControllerClass,\n translator?: Translator\n ) {\n // Get any list-bound fields on the page\n const listFields = page.collection.fields.filter(hasListFormField)\n\n // For each list field that is bound to a list that contains any conditional items,\n // we need to check any answers are still valid. Do this by evaluating the conditions\n // and ensuring any current answers are all included in the set of valid answers\n for (const field of listFields) {\n const list = field.list\n\n // Filter out YesNo as they can't be conditional\n if (list !== undefined && field.type !== ComponentType.YesNoField) {\n const hasOptionalItems =\n list.items.filter((item) => item.condition).length > 0\n\n if (hasOptionalItems) {\n return this.fieldStateIsInvalid(context, field, list, translator)\n }\n }\n }\n }\n\n private fieldStateIsInvalid(\n context: FormContext,\n field: ListFormComponent,\n list: List,\n translator?: Translator\n ) {\n const { evaluationState, state } = context\n\n const validValues = list.items\n .filter((item) =>\n item.condition\n ? this.conditions[item.condition]?.fn(evaluationState)\n : true\n )\n .map((item) => item.value)\n\n // Get the field state\n const fieldState = field.getFormValueFromState(state)\n\n if (fieldState !== undefined) {\n let isInvalid = false\n const isArray = Array.isArray(fieldState)\n\n // Check if any saved state value(s) are still valid\n // and return true if any are invalid\n if (isArray) {\n isInvalid = !fieldState.every((item) => validValues.includes(item))\n } else {\n isInvalid = !validValues.includes(fieldState)\n }\n\n if (isInvalid) {\n context.errors ??= []\n\n const text = (translator ?? this.createTranslator('en-GB')).t(\n 'errors.optionsMismatch'\n )\n\n context.errors.push({\n text,\n name: field.name,\n href: `#${field.name}`,\n path: [`#${field.name}`]\n })\n }\n\n return isInvalid\n }\n }\n\n private assignPaths(context: FormContext) {\n for (const { keys, path } of context.relevantPages) {\n context.paths.push(path)\n\n // Stop at page with errors\n if (\n context.errors?.some(({ name, path }) => {\n return keys.includes(name) || keys.some((key) => path.includes(key))\n })\n ) {\n break\n }\n }\n }\n\n getComponentById(componentId: string): ComponentDef | undefined {\n return this.componentDefIdMap.get(componentId)\n }\n\n getListById(listId: string): List | undefined {\n return this.listDefIdMap.get(listId)\n }\n\n /**\n * Returns a condition by its ID. O(n) lookup time.\n * @param conditionId\n * @returns\n */\n getConditionById(conditionId: string): ConditionWrapperV2 | undefined {\n return this.def.conditions\n .filter(isConditionWrapperV2)\n .find((condition) => condition.id === conditionId)\n }\n\n /**\n * Checks that only one payment field exists (if any payments fields exist)\n */\n moreThanOnePaymentQuestion() {\n const numOfPaymentFields = this.def.pages\n .flatMap((page) =>\n hasComponentsEvenIfNoNext(page) ? page.components : []\n )\n .filter((comp) => comp.type === ComponentType.PaymentField).length\n return numOfPaymentFields > 1\n }\n}\n\n/**\n * Validate current page only\n */\nfunction validateFormPayload(\n request: FormContextRequest,\n page: PageControllerClass,\n context: FormContext,\n translator?: Translator\n): FormContext {\n const { collection } = page\n const { payload, state } = context\n\n const { action } = page.getFormParams(request)\n\n // Skip validation GET requests or other actions\n if (\n !request.payload ||\n (action &&\n action !== FormAction.Validate &&\n !action.startsWith(FormAction.External))\n ) {\n return context\n }\n\n // For checkbox fields missing in the payload (i.e. unchecked),\n // explicitly set their value to undefined so that any previously\n // stored value is cleared and required field validation is enforced.\n const update = { ...request.payload }\n collection.fields.forEach((field) => {\n if (\n field.type === ComponentType.CheckboxesField &&\n !(field.name in update)\n ) {\n update[field.name] = undefined\n }\n })\n\n const { value, errors } = collection.validate(\n { ...payload, ...update },\n translator\n )\n\n // Add sanitised payload (ready to save)\n const formState = page.getStateFromValidForm(request, state, value)\n\n return {\n ...context,\n payload: merge(payload, value),\n state: merge(state, formState),\n errors\n }\n}\n\n/**\n * Validate entire form state\n */\nfunction validateFormState(\n request: FormContextRequest,\n page: PageControllerClass,\n context: FormContext\n): FormContext {\n const { errors = [], relevantPages, relevantState } = context\n\n // Exclude current page\n const previousPages = relevantPages.filter(\n (relevantPage) => relevantPage !== page\n )\n\n // Validate relevant state\n const { error } = page.model\n .makeFilteredSchema(previousPages)\n .validate(relevantState, { ...opts, stripUnknown: true })\n\n // Add relevant state errors\n if (error) {\n const errorsState = error.details.map((item) => getError(EN_GB, item))\n return { ...context, errors: errors.concat(errorsState) }\n }\n\n return context\n}\n\nfunction getReferenceNumber(state: FormSubmissionState): string {\n if (\n !state.$$__referenceNumber ||\n typeof state.$$__referenceNumber !== 'string'\n ) {\n throw Error('Reference number not found in form state')\n }\n\n return state.$$__referenceNumber\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -1,8 +1,17 @@
|
|
|
1
|
-
import { type FormMetadata, type FormMetadataContact } from '@defra/forms-model';
|
|
1
|
+
import { type FormDefinition, type FormMetadata, type FormMetadataContact } from '@defra/forms-model';
|
|
2
|
+
import { type Translator } from '../../../../server/plugins/engine/types/index.js';
|
|
2
3
|
export interface UnavailableViewModel {
|
|
3
4
|
pageTitle: string;
|
|
4
5
|
formTitle: string;
|
|
5
6
|
organisationName: string;
|
|
6
7
|
contact?: FormMetadataContact;
|
|
8
|
+
context: {
|
|
9
|
+
translator: Translator;
|
|
10
|
+
};
|
|
11
|
+
language: string;
|
|
12
|
+
languages: {
|
|
13
|
+
code: string;
|
|
14
|
+
name: string;
|
|
15
|
+
}[];
|
|
7
16
|
}
|
|
8
|
-
export declare function unavailableViewModel(metadata: FormMetadata): UnavailableViewModel;
|
|
17
|
+
export declare function unavailableViewModel(metadata: FormMetadata, definition: FormDefinition | undefined, language: string): UnavailableViewModel;
|
|
@@ -1,9 +1,28 @@
|
|
|
1
|
-
|
|
1
|
+
import { createFormTranslator } from "../i18n/createFormTranslator.js";
|
|
2
|
+
import { getAvailableLanguages } from "../i18n/languages.js";
|
|
3
|
+
export function unavailableViewModel(metadata, definition, language) {
|
|
4
|
+
const translator = createFormTranslator(metadata, definition, language);
|
|
5
|
+
const {
|
|
6
|
+
t,
|
|
7
|
+
tForm
|
|
8
|
+
} = translator;
|
|
2
9
|
return {
|
|
3
|
-
pageTitle: '
|
|
4
|
-
formTitle: metadata.title,
|
|
10
|
+
pageTitle: t('pages.formUnavailable.title'),
|
|
11
|
+
formTitle: tForm('title') || metadata.title,
|
|
5
12
|
organisationName: metadata.organisation,
|
|
6
|
-
contact: metadata.contact
|
|
13
|
+
contact: metadata.contact,
|
|
14
|
+
context: {
|
|
15
|
+
translator
|
|
16
|
+
},
|
|
17
|
+
language,
|
|
18
|
+
// Always get Welsh and English
|
|
19
|
+
languages: getAvailableLanguages({
|
|
20
|
+
metadata: {
|
|
21
|
+
translations: {
|
|
22
|
+
cy: {}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
})
|
|
7
26
|
};
|
|
8
27
|
}
|
|
9
28
|
//# sourceMappingURL=unavailable-view-model.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"unavailable-view-model.js","names":["unavailableViewModel","metadata","pageTitle","formTitle","title","organisationName","organisation","contact"],"sources":["../../../../../src/server/plugins/engine/models/unavailable-view-model.ts"],"sourcesContent":["import { type FormMetadata
|
|
1
|
+
{"version":3,"file":"unavailable-view-model.js","names":["createFormTranslator","getAvailableLanguages","unavailableViewModel","metadata","definition","language","translator","t","tForm","pageTitle","formTitle","title","organisationName","organisation","contact","context","languages","translations","cy"],"sources":["../../../../../src/server/plugins/engine/models/unavailable-view-model.ts"],"sourcesContent":["import {\n type FormDefinition,\n type FormMetadata,\n type FormMetadataContact\n} from '@defra/forms-model'\n\nimport { createFormTranslator } from '~/src/server/plugins/engine/i18n/createFormTranslator.js'\nimport { getAvailableLanguages } from '~/src/server/plugins/engine/i18n/languages.js'\nimport { type Translator } from '~/src/server/plugins/engine/types/index.js'\n\nexport interface UnavailableViewModel {\n pageTitle: string\n formTitle: string\n organisationName: string\n contact?: FormMetadataContact\n context: { translator: Translator }\n language: string\n languages: { code: string; name: string }[]\n}\n\nexport function unavailableViewModel(\n metadata: FormMetadata,\n definition: FormDefinition | undefined,\n language: string\n): UnavailableViewModel {\n const translator = createFormTranslator(metadata, definition, language)\n const { t, tForm } = translator\n return {\n pageTitle: t('pages.formUnavailable.title'),\n formTitle: tForm('title') || metadata.title,\n organisationName: metadata.organisation,\n contact: metadata.contact,\n context: { translator },\n language,\n // Always get Welsh and English\n languages: getAvailableLanguages({\n metadata: { translations: { cy: {} } }\n } as unknown as FormDefinition)\n }\n}\n"],"mappings":"AAMA,SAASA,oBAAoB;AAC7B,SAASC,qBAAqB;AAa9B,OAAO,SAASC,oBAAoBA,CAClCC,QAAsB,EACtBC,UAAsC,EACtCC,QAAgB,EACM;EACtB,MAAMC,UAAU,GAAGN,oBAAoB,CAACG,QAAQ,EAAEC,UAAU,EAAEC,QAAQ,CAAC;EACvE,MAAM;IAAEE,CAAC;IAAEC;EAAM,CAAC,GAAGF,UAAU;EAC/B,OAAO;IACLG,SAAS,EAAEF,CAAC,CAAC,6BAA6B,CAAC;IAC3CG,SAAS,EAAEF,KAAK,CAAC,OAAO,CAAC,IAAIL,QAAQ,CAACQ,KAAK;IAC3CC,gBAAgB,EAAET,QAAQ,CAACU,YAAY;IACvCC,OAAO,EAAEX,QAAQ,CAACW,OAAO;IACzBC,OAAO,EAAE;MAAET;IAAW,CAAC;IACvBD,QAAQ;IACR;IACAW,SAAS,EAAEf,qBAAqB,CAAC;MAC/BE,QAAQ,EAAE;QAAEc,YAAY,EAAE;UAAEC,EAAE,EAAE,CAAC;QAAE;MAAE;IACvC,CAA8B;EAChC,CAAC;AACH","ignoreList":[]}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ControllerType, controllerNameFromPath } from '@defra/forms-model';
|
|
2
|
+
import { UnknownPageControllerError } from "../../errors.js";
|
|
2
3
|
import * as PageControllers from "../index.js";
|
|
3
4
|
/**
|
|
4
5
|
* Creates page instance for each {@link Page} type
|
|
@@ -44,7 +45,7 @@ export function createPage(model, pageDef) {
|
|
|
44
45
|
}
|
|
45
46
|
}
|
|
46
47
|
if (typeof controller === 'undefined') {
|
|
47
|
-
throw new
|
|
48
|
+
throw new UnknownPageControllerError(pageDef.controller);
|
|
48
49
|
}
|
|
49
50
|
return controller;
|
|
50
51
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pages.js","names":["ControllerType","controllerNameFromPath","PageControllers","createPage","model","pageDef","controllerName","controller","QuestionPageController","Start","StartPageController","Page","Terminal","TerminalPageController","Summary","SummaryPageController","Status","StatusPageController","FileUpload","FileUploadPageController","Repeat","RepeatPageController","controllers","Ctrl"
|
|
1
|
+
{"version":3,"file":"pages.js","names":["ControllerType","controllerNameFromPath","UnknownPageControllerError","PageControllers","createPage","model","pageDef","controllerName","controller","QuestionPageController","Start","StartPageController","Page","Terminal","TerminalPageController","Summary","SummaryPageController","Status","StatusPageController","FileUpload","FileUploadPageController","Repeat","RepeatPageController","controllers","Ctrl"],"sources":["../../../../../../src/server/plugins/engine/pageControllers/helpers/pages.ts"],"sourcesContent":["import {\n ControllerType,\n controllerNameFromPath,\n type Page\n} from '@defra/forms-model'\n\nimport { UnknownPageControllerError } from '~/src/server/plugins/engine/errors.js'\nimport { type FormModel } from '~/src/server/plugins/engine/models/index.js'\nimport * as PageControllers from '~/src/server/plugins/engine/pageControllers/index.js'\n\nexport type PageControllerClass = InstanceType<PageControllerType>\nexport type PageControllerType =\n (typeof PageControllers)[keyof typeof PageControllers]\n\n/**\n * Creates page instance for each {@link Page} type\n */\nexport function createPage(model: FormModel, pageDef: Page) {\n const controllerName = controllerNameFromPath(pageDef.controller)\n\n if (!pageDef.controller) {\n return new PageControllers.QuestionPageController(model, pageDef)\n }\n\n // Patch legacy controllers\n if (controllerName && pageDef.controller !== controllerName) {\n pageDef.controller = controllerName\n }\n\n let controller: PageControllerClass | undefined\n\n switch (pageDef.controller) {\n case ControllerType.Start:\n controller = new PageControllers.StartPageController(model, pageDef)\n break\n\n case ControllerType.Page:\n controller = new PageControllers.QuestionPageController(model, pageDef)\n break\n\n case ControllerType.Terminal:\n controller = new PageControllers.TerminalPageController(model, pageDef)\n break\n\n case ControllerType.Summary:\n controller = new PageControllers.SummaryPageController(model, pageDef)\n break\n\n case ControllerType.Status:\n controller = new PageControllers.StatusPageController(model, pageDef)\n break\n\n case ControllerType.FileUpload:\n controller = new PageControllers.FileUploadPageController(model, pageDef)\n break\n\n case ControllerType.Repeat:\n controller = new PageControllers.RepeatPageController(model, pageDef)\n break\n }\n\n if (typeof controller === 'undefined') {\n if (model.controllers?.[pageDef.controller]) {\n const Ctrl = model.controllers[pageDef.controller]\n controller = new Ctrl(model, pageDef) as unknown as PageControllerClass // type assertion needed because TS can't verify custom controller structure\n }\n }\n\n if (typeof controller === 'undefined') {\n throw new UnknownPageControllerError(pageDef.controller)\n }\n\n return controller\n}\n"],"mappings":"AAAA,SACEA,cAAc,EACdC,sBAAsB,QAEjB,oBAAoB;AAE3B,SAASC,0BAA0B;AAEnC,OAAO,KAAKC,eAAe;AAM3B;AACA;AACA;AACA,OAAO,SAASC,UAAUA,CAACC,KAAgB,EAAEC,OAAa,EAAE;EAC1D,MAAMC,cAAc,GAAGN,sBAAsB,CAACK,OAAO,CAACE,UAAU,CAAC;EAEjE,IAAI,CAACF,OAAO,CAACE,UAAU,EAAE;IACvB,OAAO,IAAIL,eAAe,CAACM,sBAAsB,CAACJ,KAAK,EAAEC,OAAO,CAAC;EACnE;;EAEA;EACA,IAAIC,cAAc,IAAID,OAAO,CAACE,UAAU,KAAKD,cAAc,EAAE;IAC3DD,OAAO,CAACE,UAAU,GAAGD,cAAc;EACrC;EAEA,IAAIC,UAA2C;EAE/C,QAAQF,OAAO,CAACE,UAAU;IACxB,KAAKR,cAAc,CAACU,KAAK;MACvBF,UAAU,GAAG,IAAIL,eAAe,CAACQ,mBAAmB,CAACN,KAAK,EAAEC,OAAO,CAAC;MACpE;IAEF,KAAKN,cAAc,CAACY,IAAI;MACtBJ,UAAU,GAAG,IAAIL,eAAe,CAACM,sBAAsB,CAACJ,KAAK,EAAEC,OAAO,CAAC;MACvE;IAEF,KAAKN,cAAc,CAACa,QAAQ;MAC1BL,UAAU,GAAG,IAAIL,eAAe,CAACW,sBAAsB,CAACT,KAAK,EAAEC,OAAO,CAAC;MACvE;IAEF,KAAKN,cAAc,CAACe,OAAO;MACzBP,UAAU,GAAG,IAAIL,eAAe,CAACa,qBAAqB,CAACX,KAAK,EAAEC,OAAO,CAAC;MACtE;IAEF,KAAKN,cAAc,CAACiB,MAAM;MACxBT,UAAU,GAAG,IAAIL,eAAe,CAACe,oBAAoB,CAACb,KAAK,EAAEC,OAAO,CAAC;MACrE;IAEF,KAAKN,cAAc,CAACmB,UAAU;MAC5BX,UAAU,GAAG,IAAIL,eAAe,CAACiB,wBAAwB,CAACf,KAAK,EAAEC,OAAO,CAAC;MACzE;IAEF,KAAKN,cAAc,CAACqB,MAAM;MACxBb,UAAU,GAAG,IAAIL,eAAe,CAACmB,oBAAoB,CAACjB,KAAK,EAAEC,OAAO,CAAC;MACrE;EACJ;EAEA,IAAI,OAAOE,UAAU,KAAK,WAAW,EAAE;IACrC,IAAIH,KAAK,CAACkB,WAAW,GAAGjB,OAAO,CAACE,UAAU,CAAC,EAAE;MAC3C,MAAMgB,IAAI,GAAGnB,KAAK,CAACkB,WAAW,CAACjB,OAAO,CAACE,UAAU,CAAC;MAClDA,UAAU,GAAG,IAAIgB,IAAI,CAACnB,KAAK,EAAEC,OAAO,CAAmC,EAAC;IAC1E;EACF;EAEA,IAAI,OAAOE,UAAU,KAAK,WAAW,EAAE;IACrC,MAAM,IAAIN,0BAA0B,CAACI,OAAO,CAACE,UAAU,CAAC;EAC1D;EAEA,OAAOA,UAAU;AACnB","ignoreList":[]}
|
|
@@ -9,5 +9,5 @@ export declare const opts: ReferenceOptions;
|
|
|
9
9
|
export declare const messageTemplate: ValidationMessages;
|
|
10
10
|
export declare const messages: LanguageMessagesExt;
|
|
11
11
|
export declare const messagesPre: LanguageMessages;
|
|
12
|
-
export declare function buildLanguageMessages(t: (key: string) => string): LanguageMessages;
|
|
12
|
+
export declare function buildLanguageMessages(t: (key: string, options?: Record<string, unknown>) => string): LanguageMessages;
|
|
13
13
|
export declare const validationOptions: ValidationOptions;
|
|
@@ -14,7 +14,7 @@ export const opts = {
|
|
|
14
14
|
* Components that have not yet been migrated to use model.validationMessages still
|
|
15
15
|
* import messageTemplate directly and get the English version.
|
|
16
16
|
*/
|
|
17
|
-
export const messageTemplate = buildValidationMessages(key => t(key, 'en-GB'));
|
|
17
|
+
export const messageTemplate = buildValidationMessages((key, options) => t(key, 'en-GB', options));
|
|
18
18
|
export const messages = {
|
|
19
19
|
'string.base': messageTemplate.required,
|
|
20
20
|
'string.min': messageTemplate.min,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validationOptions.js","names":["lowerFirstPreserveProperNouns","buildValidationMessages","t","opts","functions","lowerFirst","messageTemplate","key","messages","required","min","max","format","unicode","pattern","maxWords","number","numberPrecision","numberInteger","numberMin","numberMax","objectRequired","objectMissing","selectRequired","dateFormat","dateMin","dateMax","arrayMin","arrayMax","arrayLength","featuresMin","featuresMax","featuresLength","filesMin","filesMax","filesLength","messagesPre","buildLanguageMessages","vm","validationOptions","abortEarly","errors","wrap","array","label"],"sources":["../../../../../src/server/plugins/engine/pageControllers/validationOptions.ts"],"sourcesContent":["// Declaration above is needed for: https://github.com/hapijs/joi/issues/3064\n\nimport {\n type LanguageMessages,\n type LanguageMessagesExt,\n type ReferenceOptions,\n type ValidationOptions\n} from 'joi'\n\nimport { lowerFirstPreserveProperNouns } from '~/src/server/plugins/engine/components/helpers/index.js'\nimport {\n buildValidationMessages,\n type ValidationMessages\n} from '~/src/server/plugins/engine/i18n/buildValidationMessages.js'\nimport { t } from '~/src/server/plugins/engine/i18n/index.js'\n\nexport const opts = {\n functions: {\n lowerFirst: lowerFirstPreserveProperNouns\n }\n} as ReferenceOptions\n\n/**\n * Module-level English message templates — built via the same factory used per-form.\n * Components that have not yet been migrated to use model.validationMessages still\n * import messageTemplate directly and get the English version.\n */\nexport const messageTemplate: ValidationMessages = buildValidationMessages(\n (key) => t(key, 'en-GB')\n)\n\nexport const messages: LanguageMessagesExt = {\n 'string.base': messageTemplate.required,\n 'string.min': messageTemplate.min,\n 'string.empty': messageTemplate.required,\n 'string.max': messageTemplate.max,\n 'string.email': messageTemplate.format,\n 'string.unicode': messageTemplate.unicode,\n 'string.pattern.base': messageTemplate.pattern,\n 'string.maxWords': messageTemplate.maxWords,\n\n 'number.base': messageTemplate.number,\n 'number.precision': messageTemplate.numberPrecision,\n 'number.integer': messageTemplate.numberInteger,\n 'number.unsafe': messageTemplate.format,\n 'number.min': messageTemplate.numberMin,\n 'number.max': messageTemplate.numberMax,\n\n 'object.required': messageTemplate.objectRequired,\n 'object.and': messageTemplate.objectMissing,\n\n 'any.only': messageTemplate.selectRequired,\n 'any.required': messageTemplate.selectRequired,\n 'any.empty': messageTemplate.required,\n\n 'date.base': messageTemplate.dateFormat,\n 'date.format': messageTemplate.dateFormat,\n 'date.min': messageTemplate.dateMin,\n 'date.max': messageTemplate.dateMax,\n\n 'array.min': messageTemplate.arrayMin,\n 'array.max': messageTemplate.arrayMax,\n 'array.length': messageTemplate.arrayLength,\n\n 'features.min': messageTemplate.featuresMin,\n 'features.max': messageTemplate.featuresMax,\n 'features.length': messageTemplate.featuresLength,\n\n 'files.min': messageTemplate.filesMin,\n 'files.max': messageTemplate.filesMax,\n 'filees.length': messageTemplate.filesLength,\n\n 'object.invalidjson': messageTemplate.format,\n\n 'phoneNumber.invalid': messageTemplate.format\n}\n\nexport const messagesPre: LanguageMessages =\n messages as unknown as LanguageMessages\n\nexport function buildLanguageMessages(\n t: (key: string) => string\n): LanguageMessages {\n const vm = buildValidationMessages(t)\n return {\n 'string.base': vm.required,\n 'string.min': vm.min,\n 'string.empty': vm.required,\n 'string.max': vm.max,\n 'string.email': vm.format,\n 'string.pattern.base': vm.pattern,\n 'string.maxWords': vm.maxWords,\n 'string.unicode': vm.unicode,\n 'number.base': vm.number,\n 'number.precision': vm.numberPrecision,\n 'number.integer': vm.numberInteger,\n 'number.unsafe': vm.format,\n 'number.min': vm.numberMin,\n 'number.max': vm.numberMax,\n 'object.required': vm.objectRequired,\n 'object.and': vm.objectMissing,\n 'any.only': vm.selectRequired,\n 'any.required': vm.selectRequired,\n 'any.empty': vm.required,\n 'date.base': vm.dateFormat,\n 'date.format': vm.dateFormat,\n 'date.min': vm.dateMin,\n 'date.max': vm.dateMax,\n 'array.min': vm.arrayMin,\n 'array.max': vm.arrayMax,\n 'array.length': vm.arrayLength,\n 'features.min': vm.featuresMin,\n 'features.max': vm.featuresMax,\n 'features.length': vm.featuresLength,\n 'files.min': vm.filesMin,\n 'files.max': vm.filesMax,\n 'files.length': vm.filesLength,\n 'object.invalidjson': vm.format,\n 'phoneNumber.invalid': vm.format\n } as unknown as LanguageMessages\n}\n\nexport const validationOptions: ValidationOptions = {\n abortEarly: false,\n messages: messagesPre,\n errors: {\n wrap: {\n array: false,\n label: false\n }\n }\n}\n"],"mappings":"AAAA;;AASA,SAASA,6BAA6B;AACtC,SACEC,uBAAuB;AAGzB,SAASC,CAAC;AAEV,OAAO,MAAMC,IAAI,GAAG;EAClBC,SAAS,EAAE;IACTC,UAAU,EAAEL;EACd;AACF,CAAqB;;AAErB;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMM,eAAmC,GAAGL,uBAAuB,
|
|
1
|
+
{"version":3,"file":"validationOptions.js","names":["lowerFirstPreserveProperNouns","buildValidationMessages","t","opts","functions","lowerFirst","messageTemplate","key","options","messages","required","min","max","format","unicode","pattern","maxWords","number","numberPrecision","numberInteger","numberMin","numberMax","objectRequired","objectMissing","selectRequired","dateFormat","dateMin","dateMax","arrayMin","arrayMax","arrayLength","featuresMin","featuresMax","featuresLength","filesMin","filesMax","filesLength","messagesPre","buildLanguageMessages","vm","validationOptions","abortEarly","errors","wrap","array","label"],"sources":["../../../../../src/server/plugins/engine/pageControllers/validationOptions.ts"],"sourcesContent":["// Declaration above is needed for: https://github.com/hapijs/joi/issues/3064\n\nimport {\n type LanguageMessages,\n type LanguageMessagesExt,\n type ReferenceOptions,\n type ValidationOptions\n} from 'joi'\n\nimport { lowerFirstPreserveProperNouns } from '~/src/server/plugins/engine/components/helpers/index.js'\nimport {\n buildValidationMessages,\n type ValidationMessages\n} from '~/src/server/plugins/engine/i18n/buildValidationMessages.js'\nimport { t } from '~/src/server/plugins/engine/i18n/index.js'\n\nexport const opts = {\n functions: {\n lowerFirst: lowerFirstPreserveProperNouns\n }\n} as ReferenceOptions\n\n/**\n * Module-level English message templates — built via the same factory used per-form.\n * Components that have not yet been migrated to use model.validationMessages still\n * import messageTemplate directly and get the English version.\n */\nexport const messageTemplate: ValidationMessages = buildValidationMessages(\n (key, options) => t(key, 'en-GB', options)\n)\n\nexport const messages: LanguageMessagesExt = {\n 'string.base': messageTemplate.required,\n 'string.min': messageTemplate.min,\n 'string.empty': messageTemplate.required,\n 'string.max': messageTemplate.max,\n 'string.email': messageTemplate.format,\n 'string.unicode': messageTemplate.unicode,\n 'string.pattern.base': messageTemplate.pattern,\n 'string.maxWords': messageTemplate.maxWords,\n\n 'number.base': messageTemplate.number,\n 'number.precision': messageTemplate.numberPrecision,\n 'number.integer': messageTemplate.numberInteger,\n 'number.unsafe': messageTemplate.format,\n 'number.min': messageTemplate.numberMin,\n 'number.max': messageTemplate.numberMax,\n\n 'object.required': messageTemplate.objectRequired,\n 'object.and': messageTemplate.objectMissing,\n\n 'any.only': messageTemplate.selectRequired,\n 'any.required': messageTemplate.selectRequired,\n 'any.empty': messageTemplate.required,\n\n 'date.base': messageTemplate.dateFormat,\n 'date.format': messageTemplate.dateFormat,\n 'date.min': messageTemplate.dateMin,\n 'date.max': messageTemplate.dateMax,\n\n 'array.min': messageTemplate.arrayMin,\n 'array.max': messageTemplate.arrayMax,\n 'array.length': messageTemplate.arrayLength,\n\n 'features.min': messageTemplate.featuresMin,\n 'features.max': messageTemplate.featuresMax,\n 'features.length': messageTemplate.featuresLength,\n\n 'files.min': messageTemplate.filesMin,\n 'files.max': messageTemplate.filesMax,\n 'filees.length': messageTemplate.filesLength,\n\n 'object.invalidjson': messageTemplate.format,\n\n 'phoneNumber.invalid': messageTemplate.format\n}\n\nexport const messagesPre: LanguageMessages =\n messages as unknown as LanguageMessages\n\nexport function buildLanguageMessages(\n t: (key: string, options?: Record<string, unknown>) => string\n): LanguageMessages {\n const vm = buildValidationMessages(t)\n return {\n 'string.base': vm.required,\n 'string.min': vm.min,\n 'string.empty': vm.required,\n 'string.max': vm.max,\n 'string.email': vm.format,\n 'string.pattern.base': vm.pattern,\n 'string.maxWords': vm.maxWords,\n 'string.unicode': vm.unicode,\n 'number.base': vm.number,\n 'number.precision': vm.numberPrecision,\n 'number.integer': vm.numberInteger,\n 'number.unsafe': vm.format,\n 'number.min': vm.numberMin,\n 'number.max': vm.numberMax,\n 'object.required': vm.objectRequired,\n 'object.and': vm.objectMissing,\n 'any.only': vm.selectRequired,\n 'any.required': vm.selectRequired,\n 'any.empty': vm.required,\n 'date.base': vm.dateFormat,\n 'date.format': vm.dateFormat,\n 'date.min': vm.dateMin,\n 'date.max': vm.dateMax,\n 'array.min': vm.arrayMin,\n 'array.max': vm.arrayMax,\n 'array.length': vm.arrayLength,\n 'features.min': vm.featuresMin,\n 'features.max': vm.featuresMax,\n 'features.length': vm.featuresLength,\n 'files.min': vm.filesMin,\n 'files.max': vm.filesMax,\n 'files.length': vm.filesLength,\n 'object.invalidjson': vm.format,\n 'phoneNumber.invalid': vm.format\n } as unknown as LanguageMessages\n}\n\nexport const validationOptions: ValidationOptions = {\n abortEarly: false,\n messages: messagesPre,\n errors: {\n wrap: {\n array: false,\n label: false\n }\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { isOfflineBoom } from "./form-availability.js";
|
|
2
2
|
import { unavailableViewModel } from "./models/unavailable-view-model.js";
|
|
3
|
+
import { resolveLanguage } from "../../utils/utils.js";
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* Registers a server-wide onPreResponse extension that intercepts the offline
|
|
@@ -15,9 +16,11 @@ export function registerUnavailableResponse(server) {
|
|
|
15
16
|
return h.continue;
|
|
16
17
|
}
|
|
17
18
|
const {
|
|
18
|
-
metadata
|
|
19
|
+
metadata,
|
|
20
|
+
definition
|
|
19
21
|
} = response.data;
|
|
20
|
-
|
|
22
|
+
const language = resolveLanguage(request);
|
|
23
|
+
return h.view('unavailable', unavailableViewModel(metadata, definition, language)).header('Cache-Control', 'no-store, no-cache, must-revalidate').header('X-Robots-Tag', 'noindex, nofollow').code(200).takeover();
|
|
21
24
|
});
|
|
22
25
|
}
|
|
23
26
|
//# sourceMappingURL=unavailable-response.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"unavailable-response.js","names":["isOfflineBoom","unavailableViewModel","registerUnavailableResponse","server","ext","request","h","response","continue","metadata","data","view","header","code","takeover"],"sources":["../../../../src/server/plugins/engine/unavailable-response.ts"],"sourcesContent":["import { type Request, type ResponseToolkit, type Server } from '@hapi/hapi'\n\nimport { isOfflineBoom } from '~/src/server/plugins/engine/form-availability.js'\nimport { unavailableViewModel } from '~/src/server/plugins/engine/models/unavailable-view-model.js'\n\n/**\n * Registers a server-wide onPreResponse extension that intercepts the offline\n * Boom thrown and renders the unavailable view.\n *\n * Must be registered after the engine's routes so it sees their responses,\n * but before any global error-page handler that would re-shape Boom errors.\n */\nexport function registerUnavailableResponse(server: Server) {\n server.ext('onPreResponse', (request: Request, h: ResponseToolkit) => {\n const response = request.response\n if (!isOfflineBoom(response)) {\n return h.continue\n }\n\n const { metadata } = response.data\n\n return h\n .view('unavailable', unavailableViewModel(metadata))\n .header('Cache-Control', 'no-store, no-cache, must-revalidate')\n .header('X-Robots-Tag', 'noindex, nofollow')\n .code(200)\n .takeover()\n })\n}\n"],"mappings":"AAEA,SAASA,aAAa;AACtB,SAASC,oBAAoB;;
|
|
1
|
+
{"version":3,"file":"unavailable-response.js","names":["isOfflineBoom","unavailableViewModel","resolveLanguage","registerUnavailableResponse","server","ext","request","h","response","continue","metadata","definition","data","language","view","header","code","takeover"],"sources":["../../../../src/server/plugins/engine/unavailable-response.ts"],"sourcesContent":["import { type Request, type ResponseToolkit, type Server } from '@hapi/hapi'\n\nimport { isOfflineBoom } from '~/src/server/plugins/engine/form-availability.js'\nimport { unavailableViewModel } from '~/src/server/plugins/engine/models/unavailable-view-model.js'\nimport { type AnyFormRequest } from '~/src/server/plugins/engine/types.js'\nimport { resolveLanguage } from '~/src/server/utils/utils.js'\n\n/**\n * Registers a server-wide onPreResponse extension that intercepts the offline\n * Boom thrown and renders the unavailable view.\n *\n * Must be registered after the engine's routes so it sees their responses,\n * but before any global error-page handler that would re-shape Boom errors.\n */\nexport function registerUnavailableResponse(server: Server) {\n server.ext('onPreResponse', (request: Request, h: ResponseToolkit) => {\n const response = request.response\n if (!isOfflineBoom(response)) {\n return h.continue\n }\n\n const { metadata, definition } = response.data\n\n const language = resolveLanguage(request as unknown as AnyFormRequest)\n\n return h\n .view('unavailable', unavailableViewModel(metadata, definition, language))\n .header('Cache-Control', 'no-store, no-cache, must-revalidate')\n .header('X-Robots-Tag', 'noindex, nofollow')\n .code(200)\n .takeover()\n })\n}\n"],"mappings":"AAEA,SAASA,aAAa;AACtB,SAASC,oBAAoB;AAE7B,SAASC,eAAe;;AAExB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,2BAA2BA,CAACC,MAAc,EAAE;EAC1DA,MAAM,CAACC,GAAG,CAAC,eAAe,EAAE,CAACC,OAAgB,EAAEC,CAAkB,KAAK;IACpE,MAAMC,QAAQ,GAAGF,OAAO,CAACE,QAAQ;IACjC,IAAI,CAACR,aAAa,CAACQ,QAAQ,CAAC,EAAE;MAC5B,OAAOD,CAAC,CAACE,QAAQ;IACnB;IAEA,MAAM;MAAEC,QAAQ;MAAEC;IAAW,CAAC,GAAGH,QAAQ,CAACI,IAAI;IAE9C,MAAMC,QAAQ,GAAGX,eAAe,CAACI,OAAoC,CAAC;IAEtE,OAAOC,CAAC,CACLO,IAAI,CAAC,aAAa,EAAEb,oBAAoB,CAACS,QAAQ,EAAEC,UAAU,EAAEE,QAAQ,CAAC,CAAC,CACzEE,MAAM,CAAC,eAAe,EAAE,qCAAqC,CAAC,CAC9DA,MAAM,CAAC,cAAc,EAAE,mBAAmB,CAAC,CAC3CC,IAAI,CAAC,GAAG,CAAC,CACTC,QAAQ,CAAC,CAAC;EACf,CAAC,CAAC;AACJ","ignoreList":[]}
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
{% set detailsHtml %}
|
|
62
62
|
{% if component.model.instructionText %}
|
|
63
63
|
{{ govukDetails({
|
|
64
|
-
summaryText:
|
|
64
|
+
summaryText: component.model.instructionSummary,
|
|
65
65
|
html: component.model.instructionText | markdown | safe,
|
|
66
66
|
classes: "govuk-!-margin-top-3"
|
|
67
67
|
}) }}
|
|
@@ -73,6 +73,7 @@
|
|
|
73
73
|
<div id="{{component.model.name}}" class="govuk-form-group app-location-field {{ "govuk-form-group--error" if hasErrors }}"
|
|
74
74
|
data-locationtype="{{component.type | lower}}"
|
|
75
75
|
data-country="{{component.model.country}}"
|
|
76
|
+
data-lang="{{component.model.lang}}"
|
|
76
77
|
data-maplayers="{{component.model.mapLayers}}">
|
|
77
78
|
{{ govukFieldset({
|
|
78
79
|
legend: {
|
|
@@ -3,7 +3,9 @@
|
|
|
3
3
|
|
|
4
4
|
{% macro OsGridRefField(component) %}
|
|
5
5
|
{% set hasErrors = component.model.errorMessage %}
|
|
6
|
-
<div class="govuk-form-group app-location-field {{ "govuk-form-group--error" if hasErrors }}"
|
|
6
|
+
<div class="govuk-form-group app-location-field {{ "govuk-form-group--error" if hasErrors }}"
|
|
7
|
+
data-locationtype="{{component.type | lower}}"
|
|
8
|
+
data-lang="{{component.model.lang}}">
|
|
7
9
|
<div class="app-location-field-inputs">
|
|
8
10
|
{{ TextField(component) }}
|
|
9
11
|
</div>
|
|
@@ -1,32 +1,35 @@
|
|
|
1
1
|
{% extends baseLayoutPath %}
|
|
2
2
|
|
|
3
|
+
{% set t = context.translator.t %}
|
|
4
|
+
{% set tForm = context.translator.tForm %}
|
|
5
|
+
|
|
3
6
|
{% block content %}
|
|
4
7
|
<div class="govuk-grid-row">
|
|
5
8
|
<div class="govuk-grid-column-two-thirds">
|
|
6
|
-
<h1 class="govuk-heading-l">
|
|
7
|
-
<p class="govuk-body">
|
|
8
|
-
<h2 class="govuk-heading-m">
|
|
9
|
+
<h1 class="govuk-heading-l">{{ t('pages.formUnavailable.title') }}</h1>
|
|
10
|
+
<p class="govuk-body">{{ t('pages.formUnavailable.subHeading', { formTitle: formTitle }) }}</p>
|
|
11
|
+
<h2 class="govuk-heading-m">{{ t('pages.formUnavailable.contactDetailsHeading', { organisationName: organisationName }) }}</h2>
|
|
9
12
|
|
|
10
13
|
{% if contact.phone %}
|
|
11
|
-
<h3 class="govuk-heading-s">
|
|
14
|
+
<h3 class="govuk-heading-s">{{ t('pages.formUnavailable.telephone') }}</h3>
|
|
12
15
|
<div class="app-prose-scope">
|
|
13
|
-
{{ contact.phone | markdown(3) | safe }}
|
|
16
|
+
{{ tForm('contact.phone') | markdown(3) | safe }}
|
|
14
17
|
</div>
|
|
15
|
-
<p class="govuk-body"><a href="https://www.gov.uk/call-charges" class="govuk-link govuk-link--no-visited-state">
|
|
18
|
+
<p class="govuk-body"><a href="https://www.gov.uk/call-charges" class="govuk-link govuk-link--no-visited-state">{{ t('pages.formUnavailable.callCharges') }}</a></p>
|
|
16
19
|
{% endif %}
|
|
17
20
|
|
|
18
21
|
{% if contact.email %}
|
|
19
|
-
<h3 class="govuk-heading-s">
|
|
22
|
+
<h3 class="govuk-heading-s">{{ t('pages.formUnavailable.email') }}</h3>
|
|
20
23
|
<ul class="govuk-list">
|
|
21
|
-
<li><a class="govuk-link govuk-link--no-visited-state" href="mailto:{{ contact.email.address }}">{{ contact.email.address }}</a></li>
|
|
22
|
-
<li>{{ contact.email.responseTime }}</li>
|
|
24
|
+
<li><a class="govuk-link govuk-link--no-visited-state" href="mailto:{{ tForm('contact.email.address') }}">{{ tForm('contact.email.address') }}</a></li>
|
|
25
|
+
<li>{{ tForm('contact.email.responseTime') }}</li>
|
|
23
26
|
</ul>
|
|
24
27
|
{% endif %}
|
|
25
28
|
|
|
26
29
|
{% if contact.online %}
|
|
27
|
-
<h3 class="govuk-heading-s">
|
|
30
|
+
<h3 class="govuk-heading-s">{{ t('pages.formUnavailable.onlineContactForm') }}</h3>
|
|
28
31
|
<ul class="govuk-list">
|
|
29
|
-
<li><a class="govuk-link govuk-link--no-visited-state" href="{{ contact.online.url }}">{{ contact.online.text }}</a></li>
|
|
32
|
+
<li><a class="govuk-link govuk-link--no-visited-state" href="{{ tForm('contact.online.url') }}">{{ tForm('contact.online.text') }}</a></li>
|
|
30
33
|
</ul>
|
|
31
34
|
{% endif %}
|
|
32
35
|
</div>
|