From c766c6be4629c402b19f21246766b20c074618d4 Mon Sep 17 00:00:00 2001 From: whitewater design Date: Wed, 27 Aug 2025 18:15:07 +0100 Subject: [PATCH 1/4] fix: DF-380 - Move factory methods into separate file to resolve component circular imports --- .../components/AutocompleteField.test.ts | 2 +- .../engine/components/CheckboxesField.test.ts | 2 +- .../engine/components/ComponentBase.ts | 2 +- .../engine/components/ComponentCollection.ts | 2 +- .../engine/components/DatePartsField.test.ts | 2 +- .../plugins/engine/components/Details.test.ts | 2 +- .../components/EmailAddressField.test.ts | 2 +- .../engine/components/FileUploadField.test.ts | 2 +- .../plugins/engine/components/Html.test.ts | 2 +- .../engine/components/InsetText.test.ts | 2 +- .../plugins/engine/components/List.test.ts | 2 +- .../engine/components/Markdown.test.ts | 2 +- .../engine/components/MonthYearField.test.ts | 2 +- .../components/MultilineTextField.test.ts | 2 +- .../engine/components/NumberField.test.ts | 2 +- .../engine/components/RadiosField.test.ts | 2 +- .../engine/components/SelectField.test.ts | 2 +- .../components/TelephoneNumberField.test.ts | 2 +- .../engine/components/TextField.test.ts | 2 +- .../engine/components/UkAddressField.test.ts | 2 +- .../engine/components/YesNoField.test.ts | 2 +- .../plugins/engine/components/factory.ts | 331 ++++++++++++++++++ .../plugins/engine/components/helpers.test.ts | 2 +- .../plugins/engine/components/helpers.ts | 331 +----------------- src/server/plugins/engine/helpers.ts | 2 +- src/server/plugins/engine/models/FormModel.ts | 2 +- .../plugins/engine/models/SummaryViewModel.ts | 2 +- src/server/plugins/engine/models/types.ts | 6 +- .../outputFormatters/adapter/v1.test.ts | 2 +- .../engine/outputFormatters/human/v1.ts | 6 +- .../outputFormatters/machine/v1.test.ts | 2 +- .../engine/outputFormatters/machine/v1.ts | 2 +- .../outputFormatters/machine/v2.test.ts | 2 +- .../pageControllers/SummaryPageController.ts | 2 +- src/server/plugins/engine/types.ts | 2 +- src/server/plugins/nunjucks/filters/answer.js | 4 +- .../plugins/nunjucks/filters/answer.test.js | 4 +- 37 files changed, 372 insertions(+), 372 deletions(-) create mode 100644 src/server/plugins/engine/components/factory.ts diff --git a/src/server/plugins/engine/components/AutocompleteField.test.ts b/src/server/plugins/engine/components/AutocompleteField.test.ts index 8c38e772d..1954a3cdc 100644 --- a/src/server/plugins/engine/components/AutocompleteField.test.ts +++ b/src/server/plugins/engine/components/AutocompleteField.test.ts @@ -9,7 +9,7 @@ import { ComponentCollection } from '~/src/server/plugins/engine/components/Comp import { getAnswer, type Field -} from '~/src/server/plugins/engine/components/helpers.js' +} from '~/src/server/plugins/engine/components/factory.js' import { FormModel } from '~/src/server/plugins/engine/models/FormModel.js' import { listNumber, diff --git a/src/server/plugins/engine/components/CheckboxesField.test.ts b/src/server/plugins/engine/components/CheckboxesField.test.ts index e4cbc675d..41f17d4a5 100644 --- a/src/server/plugins/engine/components/CheckboxesField.test.ts +++ b/src/server/plugins/engine/components/CheckboxesField.test.ts @@ -11,7 +11,7 @@ import { ComponentCollection } from '~/src/server/plugins/engine/components/Comp import { getAnswer, type Field -} from '~/src/server/plugins/engine/components/helpers.js' +} from '~/src/server/plugins/engine/components/factory.js' import { FormModel } from '~/src/server/plugins/engine/models/FormModel.js' import { listNumber, diff --git a/src/server/plugins/engine/components/ComponentBase.ts b/src/server/plugins/engine/components/ComponentBase.ts index a8c27eef1..f7407bbb2 100644 --- a/src/server/plugins/engine/components/ComponentBase.ts +++ b/src/server/plugins/engine/components/ComponentBase.ts @@ -9,7 +9,7 @@ import joi, { } from 'joi' import { type ComponentCollection } from '~/src/server/plugins/engine/components/ComponentCollection.js' -import { type Component } from '~/src/server/plugins/engine/components/helpers.js' +import { type Component } from '~/src/server/plugins/engine/components/factory.js' import { type ViewModel } from '~/src/server/plugins/engine/components/types.js' import { type FormModel } from '~/src/server/plugins/engine/models/index.js' import { type PageControllerClass } from '~/src/server/plugins/engine/pageControllers/helpers.js' diff --git a/src/server/plugins/engine/components/ComponentCollection.ts b/src/server/plugins/engine/components/ComponentCollection.ts index d09ee1230..27cbb0777 100644 --- a/src/server/plugins/engine/components/ComponentCollection.ts +++ b/src/server/plugins/engine/components/ComponentCollection.ts @@ -15,7 +15,7 @@ import { type Component, type Field, type Guidance -} from '~/src/server/plugins/engine/components/helpers.js' +} from '~/src/server/plugins/engine/components/factory.js' import { type ComponentViewModel } from '~/src/server/plugins/engine/components/types.js' import { getErrors } from '~/src/server/plugins/engine/helpers.js' import { type FormModel } from '~/src/server/plugins/engine/models/index.js' diff --git a/src/server/plugins/engine/components/DatePartsField.test.ts b/src/server/plugins/engine/components/DatePartsField.test.ts index 1d4145d73..05fd959b2 100644 --- a/src/server/plugins/engine/components/DatePartsField.test.ts +++ b/src/server/plugins/engine/components/DatePartsField.test.ts @@ -5,7 +5,7 @@ import { ComponentCollection } from '~/src/server/plugins/engine/components/Comp import { getAnswer, type Field -} from '~/src/server/plugins/engine/components/helpers.js' +} from '~/src/server/plugins/engine/components/factory.js' import { type DateInputItem } from '~/src/server/plugins/engine/components/types.js' import { FormModel } from '~/src/server/plugins/engine/models/FormModel.js' import { diff --git a/src/server/plugins/engine/components/Details.test.ts b/src/server/plugins/engine/components/Details.test.ts index 6d5a63813..9a35faf97 100644 --- a/src/server/plugins/engine/components/Details.test.ts +++ b/src/server/plugins/engine/components/Details.test.ts @@ -1,7 +1,7 @@ import { ComponentType, type DetailsComponent } from '@defra/forms-model' import { ComponentCollection } from '~/src/server/plugins/engine/components/ComponentCollection.js' -import { type Guidance } from '~/src/server/plugins/engine/components/helpers.js' +import { type Guidance } from '~/src/server/plugins/engine/components/factory.js' import { FormModel } from '~/src/server/plugins/engine/models/FormModel.js' import definition from '~/test/form/definitions/basic.js' diff --git a/src/server/plugins/engine/components/EmailAddressField.test.ts b/src/server/plugins/engine/components/EmailAddressField.test.ts index b9d12c269..0484bbf89 100644 --- a/src/server/plugins/engine/components/EmailAddressField.test.ts +++ b/src/server/plugins/engine/components/EmailAddressField.test.ts @@ -7,7 +7,7 @@ import { ComponentCollection } from '~/src/server/plugins/engine/components/Comp import { getAnswer, type Field -} from '~/src/server/plugins/engine/components/helpers.js' +} from '~/src/server/plugins/engine/components/factory.js' import { FormModel } from '~/src/server/plugins/engine/models/FormModel.js' import definition from '~/test/form/definitions/blank.js' import { getFormData, getFormState } from '~/test/helpers/component-helpers.js' diff --git a/src/server/plugins/engine/components/FileUploadField.test.ts b/src/server/plugins/engine/components/FileUploadField.test.ts index 5aa24bab0..8fb476c5c 100644 --- a/src/server/plugins/engine/components/FileUploadField.test.ts +++ b/src/server/plugins/engine/components/FileUploadField.test.ts @@ -8,7 +8,7 @@ import { tempItemSchema } from '~/src/server/plugins/engine/components/FileUploa import { getAnswer, type Field -} from '~/src/server/plugins/engine/components/helpers.js' +} from '~/src/server/plugins/engine/components/factory.js' import { FormModel } from '~/src/server/plugins/engine/models/FormModel.js' import { createPage, diff --git a/src/server/plugins/engine/components/Html.test.ts b/src/server/plugins/engine/components/Html.test.ts index bf63d07a6..f19fdaf83 100644 --- a/src/server/plugins/engine/components/Html.test.ts +++ b/src/server/plugins/engine/components/Html.test.ts @@ -1,7 +1,7 @@ import { ComponentType, type HtmlComponent } from '@defra/forms-model' import { ComponentCollection } from '~/src/server/plugins/engine/components/ComponentCollection.js' -import { type Guidance } from '~/src/server/plugins/engine/components/helpers.js' +import { type Guidance } from '~/src/server/plugins/engine/components/factory.js' import { FormModel } from '~/src/server/plugins/engine/models/FormModel.js' import definition from '~/test/form/definitions/basic.js' diff --git a/src/server/plugins/engine/components/InsetText.test.ts b/src/server/plugins/engine/components/InsetText.test.ts index 4d30be0c5..d7053a14a 100644 --- a/src/server/plugins/engine/components/InsetText.test.ts +++ b/src/server/plugins/engine/components/InsetText.test.ts @@ -1,7 +1,7 @@ import { ComponentType, type InsetTextComponent } from '@defra/forms-model' import { ComponentCollection } from '~/src/server/plugins/engine/components/ComponentCollection.js' -import { type Guidance } from '~/src/server/plugins/engine/components/helpers.js' +import { type Guidance } from '~/src/server/plugins/engine/components/factory.js' import { FormModel } from '~/src/server/plugins/engine/models/FormModel.js' import definition from '~/test/form/definitions/basic.js' diff --git a/src/server/plugins/engine/components/List.test.ts b/src/server/plugins/engine/components/List.test.ts index dd188ceaa..5346c232a 100644 --- a/src/server/plugins/engine/components/List.test.ts +++ b/src/server/plugins/engine/components/List.test.ts @@ -1,7 +1,7 @@ import { ComponentType, type ListComponent } from '@defra/forms-model' import { ComponentCollection } from '~/src/server/plugins/engine/components/ComponentCollection.js' -import { type Guidance } from '~/src/server/plugins/engine/components/helpers.js' +import { type Guidance } from '~/src/server/plugins/engine/components/factory.js' import { FormModel } from '~/src/server/plugins/engine/models/FormModel.js' import definition from '~/test/form/definitions/basic.js' diff --git a/src/server/plugins/engine/components/Markdown.test.ts b/src/server/plugins/engine/components/Markdown.test.ts index 6756e9bd2..7b61e9ff7 100644 --- a/src/server/plugins/engine/components/Markdown.test.ts +++ b/src/server/plugins/engine/components/Markdown.test.ts @@ -1,7 +1,7 @@ import { ComponentType, type MarkdownComponent } from '@defra/forms-model' import { ComponentCollection } from '~/src/server/plugins/engine/components/ComponentCollection.js' -import { type Guidance } from '~/src/server/plugins/engine/components/helpers.js' +import { type Guidance } from '~/src/server/plugins/engine/components/factory.js' import { FormModel } from '~/src/server/plugins/engine/models/FormModel.js' import definition from '~/test/form/definitions/basic.js' diff --git a/src/server/plugins/engine/components/MonthYearField.test.ts b/src/server/plugins/engine/components/MonthYearField.test.ts index a45716e03..cd7fc1346 100644 --- a/src/server/plugins/engine/components/MonthYearField.test.ts +++ b/src/server/plugins/engine/components/MonthYearField.test.ts @@ -5,7 +5,7 @@ import { ComponentCollection } from '~/src/server/plugins/engine/components/Comp import { getAnswer, type Field -} from '~/src/server/plugins/engine/components/helpers.js' +} from '~/src/server/plugins/engine/components/factory.js' import { type DateInputItem } from '~/src/server/plugins/engine/components/types.js' import { FormModel } from '~/src/server/plugins/engine/models/FormModel.js' import { diff --git a/src/server/plugins/engine/components/MultilineTextField.test.ts b/src/server/plugins/engine/components/MultilineTextField.test.ts index 092e37b35..452ce0324 100644 --- a/src/server/plugins/engine/components/MultilineTextField.test.ts +++ b/src/server/plugins/engine/components/MultilineTextField.test.ts @@ -8,7 +8,7 @@ import { MultilineTextField } from '~/src/server/plugins/engine/components/Multi import { getAnswer, type Field -} from '~/src/server/plugins/engine/components/helpers.js' +} from '~/src/server/plugins/engine/components/factory.js' import { FormModel } from '~/src/server/plugins/engine/models/FormModel.js' import definition from '~/test/form/definitions/blank.js' import { getFormData, getFormState } from '~/test/helpers/component-helpers.js' diff --git a/src/server/plugins/engine/components/NumberField.test.ts b/src/server/plugins/engine/components/NumberField.test.ts index afe6d5a70..6ae1d25e9 100644 --- a/src/server/plugins/engine/components/NumberField.test.ts +++ b/src/server/plugins/engine/components/NumberField.test.ts @@ -5,7 +5,7 @@ import { NumberField } from '~/src/server/plugins/engine/components/NumberField. import { getAnswer, type Field -} from '~/src/server/plugins/engine/components/helpers.js' +} from '~/src/server/plugins/engine/components/factory.js' import { FormModel } from '~/src/server/plugins/engine/models/FormModel.js' import definition from '~/test/form/definitions/blank.js' import { getFormData, getFormState } from '~/test/helpers/component-helpers.js' diff --git a/src/server/plugins/engine/components/RadiosField.test.ts b/src/server/plugins/engine/components/RadiosField.test.ts index d071cb3a8..f4526686a 100644 --- a/src/server/plugins/engine/components/RadiosField.test.ts +++ b/src/server/plugins/engine/components/RadiosField.test.ts @@ -6,7 +6,7 @@ import { RadiosField } from '~/src/server/plugins/engine/components/RadiosField. import { getAnswer, type Field -} from '~/src/server/plugins/engine/components/helpers.js' +} from '~/src/server/plugins/engine/components/factory.js' import { FormModel } from '~/src/server/plugins/engine/models/FormModel.js' import { listNumber, diff --git a/src/server/plugins/engine/components/SelectField.test.ts b/src/server/plugins/engine/components/SelectField.test.ts index 585ebbda8..5986fd9dd 100644 --- a/src/server/plugins/engine/components/SelectField.test.ts +++ b/src/server/plugins/engine/components/SelectField.test.ts @@ -6,7 +6,7 @@ import { SelectField } from '~/src/server/plugins/engine/components/SelectField. import { getAnswer, type Field -} from '~/src/server/plugins/engine/components/helpers.js' +} from '~/src/server/plugins/engine/components/factory.js' import { FormModel } from '~/src/server/plugins/engine/models/FormModel.js' import { listNumber, diff --git a/src/server/plugins/engine/components/TelephoneNumberField.test.ts b/src/server/plugins/engine/components/TelephoneNumberField.test.ts index 0c828e9a7..a6dd99124 100644 --- a/src/server/plugins/engine/components/TelephoneNumberField.test.ts +++ b/src/server/plugins/engine/components/TelephoneNumberField.test.ts @@ -7,7 +7,7 @@ import { ComponentCollection } from '~/src/server/plugins/engine/components/Comp import { getAnswer, type Field -} from '~/src/server/plugins/engine/components/helpers.js' +} from '~/src/server/plugins/engine/components/factory.js' import { FormModel } from '~/src/server/plugins/engine/models/FormModel.js' import definition from '~/test/form/definitions/blank.js' import { getFormData, getFormState } from '~/test/helpers/component-helpers.js' diff --git a/src/server/plugins/engine/components/TextField.test.ts b/src/server/plugins/engine/components/TextField.test.ts index f2c0bb26b..cf5b5f291 100644 --- a/src/server/plugins/engine/components/TextField.test.ts +++ b/src/server/plugins/engine/components/TextField.test.ts @@ -4,7 +4,7 @@ import { ComponentCollection } from '~/src/server/plugins/engine/components/Comp import { getAnswer, type Field -} from '~/src/server/plugins/engine/components/helpers.js' +} from '~/src/server/plugins/engine/components/factory.js' import { FormModel } from '~/src/server/plugins/engine/models/FormModel.js' import definition from '~/test/form/definitions/blank.js' import { getFormData, getFormState } from '~/test/helpers/component-helpers.js' diff --git a/src/server/plugins/engine/components/UkAddressField.test.ts b/src/server/plugins/engine/components/UkAddressField.test.ts index a00ba3690..d8fbe5fe2 100644 --- a/src/server/plugins/engine/components/UkAddressField.test.ts +++ b/src/server/plugins/engine/components/UkAddressField.test.ts @@ -9,7 +9,7 @@ import { UkAddressField } from '~/src/server/plugins/engine/components/UkAddress import { getAnswer, type Field -} from '~/src/server/plugins/engine/components/helpers.js' +} from '~/src/server/plugins/engine/components/factory.js' import { type ViewModel } from '~/src/server/plugins/engine/components/types.js' import { FormModel } from '~/src/server/plugins/engine/models/FormModel.js' import { diff --git a/src/server/plugins/engine/components/YesNoField.test.ts b/src/server/plugins/engine/components/YesNoField.test.ts index e00498d38..bd2aa44b8 100644 --- a/src/server/plugins/engine/components/YesNoField.test.ts +++ b/src/server/plugins/engine/components/YesNoField.test.ts @@ -4,7 +4,7 @@ import { ComponentCollection } from '~/src/server/plugins/engine/components/Comp import { getAnswer, type Field -} from '~/src/server/plugins/engine/components/helpers.js' +} from '~/src/server/plugins/engine/components/factory.js' import { FormModel } from '~/src/server/plugins/engine/models/FormModel.js' import { listYesNoExamples } from '~/test/fixtures/list.js' import definition from '~/test/form/definitions/blank.js' diff --git a/src/server/plugins/engine/components/factory.ts b/src/server/plugins/engine/components/factory.ts new file mode 100644 index 000000000..f84b75ccf --- /dev/null +++ b/src/server/plugins/engine/components/factory.ts @@ -0,0 +1,331 @@ +import { ComponentType, type ComponentDef } from '@defra/forms-model' +import { Marked, type Token } from 'marked' + +import { config } from '~/src/config/index.js' +import { type ComponentBase } from '~/src/server/plugins/engine/components/ComponentBase.js' +import { ListFormComponent } from '~/src/server/plugins/engine/components/ListFormComponent.js' +import { escapeMarkdown } from '~/src/server/plugins/engine/components/helpers.js' +import * as Components from '~/src/server/plugins/engine/components/index.js' +import { type FormState } from '~/src/server/plugins/engine/types.js' + +// All component instances +export type Component = InstanceType< + (typeof Components)[keyof typeof Components] +> + +// Field component instances only +export type Field = InstanceType< + | typeof Components.AutocompleteField + | typeof Components.RadiosField + | typeof Components.YesNoField + | typeof Components.CheckboxesField + | typeof Components.DatePartsField + | typeof Components.EmailAddressField + | typeof Components.MonthYearField + | typeof Components.MultilineTextField + | typeof Components.NumberField + | typeof Components.SelectField + | typeof Components.TelephoneNumberField + | typeof Components.TextField + | typeof Components.UkAddressField + | typeof Components.FileUploadField +> + +// Guidance component instances only +export type Guidance = InstanceType< + | typeof Components.Details + | typeof Components.Html + | typeof Components.Markdown + | typeof Components.InsetText + | typeof Components.List +> + +// List component instances only +export type ListField = InstanceType< + | typeof Components.AutocompleteField + | typeof Components.CheckboxesField + | typeof Components.RadiosField + | typeof Components.SelectField + | typeof Components.YesNoField +> + +export const designerUrl = config.get('designerUrl') + +export const markdown = new Marked({ + breaks: true, + gfm: true, + + /** + * Render paragraphs without `

` wrappers + * for check answers summary list `

` + */ + extensions: [ + { + name: 'paragraph', + renderer({ tokens = [] }) { + const text = this.parser.parseInline(tokens) + return tokens.length > 1 ? `${text}
` : text + } + } + ], + + /** + * Restrict allowed Markdown tokens + */ + walkTokens(token) { + const tokens: Token['type'][] = [ + 'br', + 'escape', + 'list', + 'list_item', + 'paragraph', + 'space', + 'text' + ] + + if (!tokens.includes(token.type)) { + token.type = 'text' + } + } +}) + +/** + * Filter known components with lists + */ +export function hasListFormField( + field?: Partial +): field is ListFormComponent { + return !!field && isListFieldType(field.type) +} + +export function isListFieldType( + type?: ComponentType +): type is ListField['type'] { + const allowedTypes = [ + ComponentType.AutocompleteField, + ComponentType.CheckboxesField, + ComponentType.RadiosField, + ComponentType.SelectField, + ComponentType.YesNoField + ] + + return !!type && allowedTypes.includes(type) +} + +/** + * Create field instance for each {@link ComponentDef} type + */ +export function createComponent( + def: ComponentDef, + options: ConstructorParameters[1] +): Component { + let component: Component | undefined + + switch (def.type) { + case ComponentType.AutocompleteField: + component = new Components.AutocompleteField(def, options) + break + + case ComponentType.CheckboxesField: + component = new Components.CheckboxesField(def, options) + break + + case ComponentType.DatePartsField: + component = new Components.DatePartsField(def, options) + break + + case ComponentType.Details: + component = new Components.Details(def, options) + break + + case ComponentType.EmailAddressField: + component = new Components.EmailAddressField(def, options) + break + + case ComponentType.Html: + component = new Components.Html(def, options) + break + + case ComponentType.InsetText: + component = new Components.InsetText(def, options) + break + + case ComponentType.List: + component = new Components.List(def, options) + break + + case ComponentType.Markdown: + component = new Components.Markdown(def, options) + break + + case ComponentType.MultilineTextField: + component = new Components.MultilineTextField(def, options) + break + + case ComponentType.NumberField: + component = new Components.NumberField(def, options) + break + + case ComponentType.RadiosField: + component = new Components.RadiosField(def, options) + break + + case ComponentType.SelectField: + component = new Components.SelectField(def, options) + break + + case ComponentType.TelephoneNumberField: + component = new Components.TelephoneNumberField(def, options) + break + + case ComponentType.TextField: + component = new Components.TextField(def, options) + break + + case ComponentType.UkAddressField: + component = new Components.UkAddressField(def, options) + break + + case ComponentType.YesNoField: + component = new Components.YesNoField(def, options) + break + + case ComponentType.MonthYearField: + component = new Components.MonthYearField(def, options) + break + + case ComponentType.FileUploadField: + component = new Components.FileUploadField(def, options) + break + } + + if (typeof component === 'undefined') { + throw new Error(`Component type ${def.type} does not exist`) + } + + return component +} + +/** + * Get formatted answer for a field + */ +export function getAnswer( + field: Field, + state: FormState, + options: { + format: + | 'data' // Submission data + | 'email' // GOV.UK Notify emails + | 'summary' // Check answers summary + } = { format: 'summary' } +) { + // Use escaped display text for GOV.UK Notify emails + if (options.format === 'email') { + return getAnswerMarkdown(field, state, { format: 'email' }) + } + + // Use context value for submission data + if (options.format === 'data') { + const context = field.getContextValueFromState(state) + return context?.toString() ?? '' + } + + // Use display HTML for check answers summary (multi line) + if ( + field instanceof ListFormComponent || + field instanceof Components.MultilineTextField || + field instanceof Components.UkAddressField + ) { + return markdown + .parse(getAnswerMarkdown(field, state), { async: false }) + .trim() + } + + // Use display text for check answers summary (single line) + return field.getDisplayStringFromState(state) +} + +/** + * Get formatted answer for a field (Markdown only) + */ +export function getAnswerMarkdown( + field: Field, + state: FormState, + options: { + format: + | 'email' // GOV.UK Notify emails + | 'summary' // Check answers summary + } = { format: 'summary' } +) { + const answer = field.getDisplayStringFromState(state) + + // Use escaped display text + let answerEscaped = `${escapeMarkdown(answer)}\n` + + if (field instanceof Components.FileUploadField) { + const files = field.getFormValueFromState(state) + + // Skip empty files + if (!files?.length) { + return answerEscaped + } + + answerEscaped = `${escapeMarkdown(answer)}:\n\n` + + // Append bullet points + answerEscaped += files + .map(({ status }) => { + const { file } = status.form + const filename = escapeMarkdown(file.filename) + return `* [${filename}](${designerUrl}/file-download/${file.fileId})\n` + }) + .join('') + } else if (field instanceof ListFormComponent) { + const values = [field.getContextValueFromState(state)].flat() + const items = field.items.filter(({ value }) => values.includes(value)) + + // Skip empty values + if (!items.length) { + return answerEscaped + } + + answerEscaped = '' + + // Append bullet points + answerEscaped += items + .map((item) => { + const label = escapeMarkdown(item.text) + const value = escapeMarkdown(`(${item.value})`) + + let line = label + + // Prepend bullet points for checkboxes only + if (field instanceof Components.CheckboxesField) { + line = `* ${line}` + } + + // Append raw values in parentheses + // e.g. `* None of the above (false)` + return options.format === 'email' && + `${item.value}`.toLowerCase() !== item.text.toLowerCase() + ? `${line} ${value}\n` + : `${line}\n` + }) + .join('') + } else if (field instanceof Components.MultilineTextField) { + // Preserve Multiline text new lines + answerEscaped = answer + .split(/\r?\n/) + .map(escapeMarkdown) + .join('\n') + .concat('\n') + } else if (field instanceof Components.UkAddressField) { + // Format UK addresses into new lines + answerEscaped = (field.getContextValueFromState(state) ?? []) + .map(escapeMarkdown) + .join('\n') + .concat('\n') + } + + return answerEscaped +} diff --git a/src/server/plugins/engine/components/helpers.test.ts b/src/server/plugins/engine/components/helpers.test.ts index 486286735..c8c2bee1d 100644 --- a/src/server/plugins/engine/components/helpers.test.ts +++ b/src/server/plugins/engine/components/helpers.test.ts @@ -1,7 +1,7 @@ import { type ComponentDef } from '@defra/forms-model' import { ComponentBase } from '~/src/server/plugins/engine/components/ComponentBase.js' -import { createComponent } from '~/src/server/plugins/engine/components/helpers.js' +import { createComponent } from '~/src/server/plugins/engine/components/factory.js' import { FormModel } from '~/src/server/plugins/engine/models/FormModel.js' import definition from '~/test/form/definitions/basic.js' diff --git a/src/server/plugins/engine/components/helpers.ts b/src/server/plugins/engine/components/helpers.ts index 49dbba3b9..83ec8d9d1 100644 --- a/src/server/plugins/engine/components/helpers.ts +++ b/src/server/plugins/engine/components/helpers.ts @@ -1,333 +1,4 @@ -import { ComponentType, type ComponentDef } from '@defra/forms-model' -import { Marked, type Token } from 'marked' - -import { config } from '~/src/config/index.js' -import { type ComponentBase } from '~/src/server/plugins/engine/components/ComponentBase.js' -import { ListFormComponent } from '~/src/server/plugins/engine/components/ListFormComponent.js' -import * as Components from '~/src/server/plugins/engine/components/index.js' -import { type FormState } from '~/src/server/plugins/engine/types.js' - -const designerUrl = config.get('designerUrl') - -const markdown = new Marked({ - breaks: true, - gfm: true, - - /** - * Render paragraphs without `

` wrappers - * for check answers summary list `

` - */ - extensions: [ - { - name: 'paragraph', - renderer({ tokens = [] }) { - const text = this.parser.parseInline(tokens) - return tokens.length > 1 ? `${text}
` : text - } - } - ], - - /** - * Restrict allowed Markdown tokens - */ - walkTokens(token) { - const tokens: Token['type'][] = [ - 'br', - 'escape', - 'list', - 'list_item', - 'paragraph', - 'space', - 'text' - ] - - if (!tokens.includes(token.type)) { - token.type = 'text' - } - } -}) - -// All component instances -export type Component = InstanceType< - (typeof Components)[keyof typeof Components] -> - -// Field component instances only -export type Field = InstanceType< - | typeof Components.AutocompleteField - | typeof Components.RadiosField - | typeof Components.YesNoField - | typeof Components.CheckboxesField - | typeof Components.DatePartsField - | typeof Components.EmailAddressField - | typeof Components.MonthYearField - | typeof Components.MultilineTextField - | typeof Components.NumberField - | typeof Components.SelectField - | typeof Components.TelephoneNumberField - | typeof Components.TextField - | typeof Components.UkAddressField - | typeof Components.FileUploadField -> - -// Guidance component instances only -export type Guidance = InstanceType< - | typeof Components.Details - | typeof Components.Html - | typeof Components.Markdown - | typeof Components.InsetText - | typeof Components.List -> - -// List component instances only -export type ListField = InstanceType< - | typeof Components.AutocompleteField - | typeof Components.CheckboxesField - | typeof Components.RadiosField - | typeof Components.SelectField - | typeof Components.YesNoField -> - -/** - * Filter known components with lists - */ -export function hasListFormField( - field?: Partial -): field is ListFormComponent { - return !!field && isListFieldType(field.type) -} - -export function isListFieldType( - type?: ComponentType -): type is ListField['type'] { - const allowedTypes = [ - ComponentType.AutocompleteField, - ComponentType.CheckboxesField, - ComponentType.RadiosField, - ComponentType.SelectField, - ComponentType.YesNoField - ] - - return !!type && allowedTypes.includes(type) -} - -/** - * Create field instance for each {@link ComponentDef} type - */ -export function createComponent( - def: ComponentDef, - options: ConstructorParameters[1] -): Component { - let component: Component | undefined - - switch (def.type) { - case ComponentType.AutocompleteField: - component = new Components.AutocompleteField(def, options) - break - - case ComponentType.CheckboxesField: - component = new Components.CheckboxesField(def, options) - break - - case ComponentType.DatePartsField: - component = new Components.DatePartsField(def, options) - break - - case ComponentType.Details: - component = new Components.Details(def, options) - break - - case ComponentType.EmailAddressField: - component = new Components.EmailAddressField(def, options) - break - - case ComponentType.Html: - component = new Components.Html(def, options) - break - - case ComponentType.InsetText: - component = new Components.InsetText(def, options) - break - - case ComponentType.List: - component = new Components.List(def, options) - break - - case ComponentType.Markdown: - component = new Components.Markdown(def, options) - break - - case ComponentType.MultilineTextField: - component = new Components.MultilineTextField(def, options) - break - - case ComponentType.NumberField: - component = new Components.NumberField(def, options) - break - - case ComponentType.RadiosField: - component = new Components.RadiosField(def, options) - break - - case ComponentType.SelectField: - component = new Components.SelectField(def, options) - break - - case ComponentType.TelephoneNumberField: - component = new Components.TelephoneNumberField(def, options) - break - - case ComponentType.TextField: - component = new Components.TextField(def, options) - break - - case ComponentType.UkAddressField: - component = new Components.UkAddressField(def, options) - break - - case ComponentType.YesNoField: - component = new Components.YesNoField(def, options) - break - - case ComponentType.MonthYearField: - component = new Components.MonthYearField(def, options) - break - - case ComponentType.FileUploadField: - component = new Components.FileUploadField(def, options) - break - } - - if (typeof component === 'undefined') { - throw new Error(`Component type ${def.type} does not exist`) - } - - return component -} - -/** - * Get formatted answer for a field - */ -export function getAnswer( - field: Field, - state: FormState, - options: { - format: - | 'data' // Submission data - | 'email' // GOV.UK Notify emails - | 'summary' // Check answers summary - } = { format: 'summary' } -) { - // Use escaped display text for GOV.UK Notify emails - if (options.format === 'email') { - return getAnswerMarkdown(field, state, { format: 'email' }) - } - - // Use context value for submission data - if (options.format === 'data') { - const context = field.getContextValueFromState(state) - return context?.toString() ?? '' - } - - // Use display HTML for check answers summary (multi line) - if ( - field instanceof ListFormComponent || - field instanceof Components.MultilineTextField || - field instanceof Components.UkAddressField - ) { - return markdown - .parse(getAnswerMarkdown(field, state), { async: false }) - .trim() - } - - // Use display text for check answers summary (single line) - return field.getDisplayStringFromState(state) -} - -/** - * Get formatted answer for a field (Markdown only) - */ -export function getAnswerMarkdown( - field: Field, - state: FormState, - options: { - format: - | 'email' // GOV.UK Notify emails - | 'summary' // Check answers summary - } = { format: 'summary' } -) { - const answer = field.getDisplayStringFromState(state) - - // Use escaped display text - let answerEscaped = `${escapeMarkdown(answer)}\n` - - if (field instanceof Components.FileUploadField) { - const files = field.getFormValueFromState(state) - - // Skip empty files - if (!files?.length) { - return answerEscaped - } - - answerEscaped = `${escapeMarkdown(answer)}:\n\n` - - // Append bullet points - answerEscaped += files - .map(({ status }) => { - const { file } = status.form - const filename = escapeMarkdown(file.filename) - return `* [${filename}](${designerUrl}/file-download/${file.fileId})\n` - }) - .join('') - } else if (field instanceof ListFormComponent) { - const values = [field.getContextValueFromState(state)].flat() - const items = field.items.filter(({ value }) => values.includes(value)) - - // Skip empty values - if (!items.length) { - return answerEscaped - } - - answerEscaped = '' - - // Append bullet points - answerEscaped += items - .map((item) => { - const label = escapeMarkdown(item.text) - const value = escapeMarkdown(`(${item.value})`) - - let line = label - - // Prepend bullet points for checkboxes only - if (field instanceof Components.CheckboxesField) { - line = `* ${line}` - } - - // Append raw values in parentheses - // e.g. `* None of the above (false)` - return options.format === 'email' && - `${item.value}`.toLowerCase() !== item.text.toLowerCase() - ? `${line} ${value}\n` - : `${line}\n` - }) - .join('') - } else if (field instanceof Components.MultilineTextField) { - // Preserve Multiline text new lines - answerEscaped = answer - .split(/\r?\n/) - .map(escapeMarkdown) - .join('\n') - .concat('\n') - } else if (field instanceof Components.UkAddressField) { - // Format UK addresses into new lines - answerEscaped = (field.getContextValueFromState(state) ?? []) - .map(escapeMarkdown) - .join('\n') - .concat('\n') - } - - return answerEscaped -} +import { type ComponentDef } from '@defra/forms-model' /** * Prevent Markdown formatting diff --git a/src/server/plugins/engine/helpers.ts b/src/server/plugins/engine/helpers.ts index 5feae0c8c..9682ade69 100644 --- a/src/server/plugins/engine/helpers.ts +++ b/src/server/plugins/engine/helpers.ts @@ -19,7 +19,7 @@ import { createLogger } from '~/src/server/common/helpers/logging/logger.js' import { getAnswer, type Field -} from '~/src/server/plugins/engine/components/helpers.js' +} from '~/src/server/plugins/engine/components/factory.js' import { type FormModel } from '~/src/server/plugins/engine/models/FormModel.js' import { type PageControllerClass } from '~/src/server/plugins/engine/pageControllers/helpers.js' import { diff --git a/src/server/plugins/engine/models/FormModel.ts b/src/server/plugins/engine/models/FormModel.ts index 5e0fb4263..a77889209 100644 --- a/src/server/plugins/engine/models/FormModel.ts +++ b/src/server/plugins/engine/models/FormModel.ts @@ -33,7 +33,7 @@ import {} from '~/src/server/plugins/engine/components/YesNoField.js' import { hasListFormField, type Component -} from '~/src/server/plugins/engine/components/helpers.js' +} from '~/src/server/plugins/engine/components/factory.js' import { todayAsDateOnly } from '~/src/server/plugins/engine/date-helper.js' import { findPage, diff --git a/src/server/plugins/engine/models/SummaryViewModel.ts b/src/server/plugins/engine/models/SummaryViewModel.ts index 6af914a90..5a50905d5 100644 --- a/src/server/plugins/engine/models/SummaryViewModel.ts +++ b/src/server/plugins/engine/models/SummaryViewModel.ts @@ -3,7 +3,7 @@ import { type Section } from '@defra/forms-model' import { getAnswer, type Field -} from '~/src/server/plugins/engine/components/helpers.js' +} from '~/src/server/plugins/engine/components/factory.js' import { type BackLink, type ComponentViewModel diff --git a/src/server/plugins/engine/models/types.ts b/src/server/plugins/engine/models/types.ts index 57d3a2b31..0baea6126 100644 --- a/src/server/plugins/engine/models/types.ts +++ b/src/server/plugins/engine/models/types.ts @@ -6,9 +6,9 @@ import { import { type Expression } from 'expr-eval' import { - type Field, - type getAnswer -} from '~/src/server/plugins/engine/components/helpers.js' + getAnswer, + type Field +} from '~/src/server/plugins/engine/components/factory.js' import { type RepeatPageController } from '~/src/server/plugins/engine/pageControllers/RepeatPageController.js' import { type PageControllerClass } from '~/src/server/plugins/engine/pageControllers/helpers.js' import { diff --git a/src/server/plugins/engine/outputFormatters/adapter/v1.test.ts b/src/server/plugins/engine/outputFormatters/adapter/v1.test.ts index f34609cac..afcf14469 100644 --- a/src/server/plugins/engine/outputFormatters/adapter/v1.test.ts +++ b/src/server/plugins/engine/outputFormatters/adapter/v1.test.ts @@ -1,7 +1,7 @@ import { type FormMetadata } from '@defra/forms-model' import { FileUploadField } from '~/src/server/plugins/engine/components/FileUploadField.js' -import { type Field } from '~/src/server/plugins/engine/components/helpers.js' +import { type Field } from '~/src/server/plugins/engine/components/factory.js' import { FormModel } from '~/src/server/plugins/engine/models/index.js' import { type DetailItem, diff --git a/src/server/plugins/engine/outputFormatters/human/v1.ts b/src/server/plugins/engine/outputFormatters/human/v1.ts index bd700a930..e65e69e8e 100644 --- a/src/server/plugins/engine/outputFormatters/human/v1.ts +++ b/src/server/plugins/engine/outputFormatters/human/v1.ts @@ -5,10 +5,8 @@ import { import { addDays, format as dateFormat } from 'date-fns' import { config } from '~/src/config/index.js' -import { - escapeMarkdown, - getAnswer -} from '~/src/server/plugins/engine/components/helpers.js' +import { getAnswer } from '~/src/server/plugins/engine/components/factory.js' +import { escapeMarkdown } from '~/src/server/plugins/engine/components/helpers.js' import { type checkFormStatus } from '~/src/server/plugins/engine/helpers.js' import { type FormModel } from '~/src/server/plugins/engine/models/index.js' import { type DetailItem } from '~/src/server/plugins/engine/models/types.js' diff --git a/src/server/plugins/engine/outputFormatters/machine/v1.test.ts b/src/server/plugins/engine/outputFormatters/machine/v1.test.ts index c1894e8b2..474ad27da 100644 --- a/src/server/plugins/engine/outputFormatters/machine/v1.test.ts +++ b/src/server/plugins/engine/outputFormatters/machine/v1.test.ts @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/no-unsafe-member-access */ import { FileUploadField } from '~/src/server/plugins/engine/components/FileUploadField.js' -import { type Field } from '~/src/server/plugins/engine/components/helpers.js' +import { type Field } from '~/src/server/plugins/engine/components/factory.js' import { FormModel } from '~/src/server/plugins/engine/models/index.js' import { type DetailItem, diff --git a/src/server/plugins/engine/outputFormatters/machine/v1.ts b/src/server/plugins/engine/outputFormatters/machine/v1.ts index 2098fce64..2ef841515 100644 --- a/src/server/plugins/engine/outputFormatters/machine/v1.ts +++ b/src/server/plugins/engine/outputFormatters/machine/v1.ts @@ -4,7 +4,7 @@ import { } from '@defra/forms-model' import { config } from '~/src/config/index.js' -import { getAnswer } from '~/src/server/plugins/engine/components/helpers.js' +import { getAnswer } from '~/src/server/plugins/engine/components/factory.js' import { FileUploadField } from '~/src/server/plugins/engine/components/index.js' import { type checkFormStatus } from '~/src/server/plugins/engine/helpers.js' import { type FormModel } from '~/src/server/plugins/engine/models/index.js' diff --git a/src/server/plugins/engine/outputFormatters/machine/v2.test.ts b/src/server/plugins/engine/outputFormatters/machine/v2.test.ts index d56f6871e..1f785b471 100644 --- a/src/server/plugins/engine/outputFormatters/machine/v2.test.ts +++ b/src/server/plugins/engine/outputFormatters/machine/v2.test.ts @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/no-unsafe-member-access */ import { FileUploadField } from '~/src/server/plugins/engine/components/FileUploadField.js' -import { type Field } from '~/src/server/plugins/engine/components/helpers.js' +import { type Field } from '~/src/server/plugins/engine/components/factory.js' import { FormModel } from '~/src/server/plugins/engine/models/index.js' import { type DetailItem, diff --git a/src/server/plugins/engine/pageControllers/SummaryPageController.ts b/src/server/plugins/engine/pageControllers/SummaryPageController.ts index 76e3d46fd..4d5fcaa0f 100644 --- a/src/server/plugins/engine/pageControllers/SummaryPageController.ts +++ b/src/server/plugins/engine/pageControllers/SummaryPageController.ts @@ -9,7 +9,7 @@ import { type ResponseToolkit, type RouteOptions } from '@hapi/hapi' import { ComponentCollection } from '~/src/server/plugins/engine/components/ComponentCollection.js' import { FileUploadField } from '~/src/server/plugins/engine/components/FileUploadField.js' -import { getAnswer } from '~/src/server/plugins/engine/components/helpers.js' +import { getAnswer } from '~/src/server/plugins/engine/components/factory.js' import { checkEmailAddressForLiveFormSubmission, checkFormStatus, diff --git a/src/server/plugins/engine/types.ts b/src/server/plugins/engine/types.ts index dbb5087d9..3077283d4 100644 --- a/src/server/plugins/engine/types.ts +++ b/src/server/plugins/engine/types.ts @@ -11,7 +11,7 @@ import { type PluginProperties, type Request } from '@hapi/hapi' import { type JoiExpression, type ValidationErrorItem } from 'joi' import { FormComponent } from '~/src/server/plugins/engine/components/FormComponent.js' -import { type Component } from '~/src/server/plugins/engine/components/helpers.js' +import { type Component } from '~/src/server/plugins/engine/components/factory.js' import { type BackLink, type ComponentText, diff --git a/src/server/plugins/nunjucks/filters/answer.js b/src/server/plugins/nunjucks/filters/answer.js index 3e0d0d18f..caa5ca898 100644 --- a/src/server/plugins/nunjucks/filters/answer.js +++ b/src/server/plugins/nunjucks/filters/answer.js @@ -1,4 +1,4 @@ -import { getAnswer } from '~/src/server/plugins/engine/components/helpers.js' +import { getAnswer } from '~/src/server/plugins/engine/components/factory.js' /** * Nunjucks filter to get the answer for a component @@ -23,5 +23,5 @@ export function answer(name) { /** * @import { NunjucksContext } from '~/src/server/plugins/nunjucks/types.js' - * @import { Field } from '~/src/server/plugins/engine/components/helpers.js' + * @import { Field } from '~/src/server/plugins/engine/components/factory.js' */ diff --git a/src/server/plugins/nunjucks/filters/answer.test.js b/src/server/plugins/nunjucks/filters/answer.test.js index a469b5f44..a98e7e763 100644 --- a/src/server/plugins/nunjucks/filters/answer.test.js +++ b/src/server/plugins/nunjucks/filters/answer.test.js @@ -1,7 +1,7 @@ -import { getAnswer } from '~/src/server/plugins/engine/components/helpers.js' +import { getAnswer } from '~/src/server/plugins/engine/components/factory.js' import { answer } from '~/src/server/plugins/nunjucks/filters/answer.js' -jest.mock('~/src/server/plugins/engine/components/helpers.ts', () => ({ +jest.mock('~/src/server/plugins/engine/components/factory.ts', () => ({ getAnswer: jest.fn() })) From c9bb20d2b2881c440a53073a8c8d60fefc09ace8 Mon Sep 17 00:00:00 2001 From: whitewater design Date: Wed, 27 Aug 2025 18:18:35 +0100 Subject: [PATCH 2/4] fix: DF-380 - Move factory methods into separate file to resolve page circular imports --- .../engine/components/ComponentBase.ts | 2 +- .../engine/components/ComponentCollection.ts | 2 +- .../engine/components/FileUploadField.test.ts | 2 +- src/server/plugins/engine/helpers.test.ts | 2 +- src/server/plugins/engine/helpers.ts | 2 +- src/server/plugins/engine/models/FormModel.ts | 2 +- .../engine/models/SummaryViewModel.test.ts | 2 +- .../plugins/engine/models/SummaryViewModel.ts | 2 +- src/server/plugins/engine/models/types.ts | 2 +- .../plugins/engine/pageControllers/factory.ts | 80 ++++++++++++++++++ .../engine/pageControllers/helpers.test.ts | 4 +- .../plugins/engine/pageControllers/helpers.ts | 81 ------------------- src/server/plugins/engine/routes/index.ts | 2 +- .../plugins/engine/routes/questions.test.ts | 2 +- src/server/plugins/engine/routes/questions.ts | 2 +- src/server/plugins/engine/types.ts | 2 +- 16 files changed, 95 insertions(+), 96 deletions(-) create mode 100644 src/server/plugins/engine/pageControllers/factory.ts diff --git a/src/server/plugins/engine/components/ComponentBase.ts b/src/server/plugins/engine/components/ComponentBase.ts index f7407bbb2..3c532f56a 100644 --- a/src/server/plugins/engine/components/ComponentBase.ts +++ b/src/server/plugins/engine/components/ComponentBase.ts @@ -12,7 +12,7 @@ import { type ComponentCollection } from '~/src/server/plugins/engine/components import { type Component } from '~/src/server/plugins/engine/components/factory.js' import { type ViewModel } from '~/src/server/plugins/engine/components/types.js' import { type FormModel } from '~/src/server/plugins/engine/models/index.js' -import { type PageControllerClass } from '~/src/server/plugins/engine/pageControllers/helpers.js' +import { type PageControllerClass } from '~/src/server/plugins/engine/pageControllers/factory.js' export class ComponentBase { page?: PageControllerClass diff --git a/src/server/plugins/engine/components/ComponentCollection.ts b/src/server/plugins/engine/components/ComponentCollection.ts index 27cbb0777..dd24b6d8d 100644 --- a/src/server/plugins/engine/components/ComponentCollection.ts +++ b/src/server/plugins/engine/components/ComponentCollection.ts @@ -19,7 +19,7 @@ import { import { type ComponentViewModel } from '~/src/server/plugins/engine/components/types.js' import { getErrors } from '~/src/server/plugins/engine/helpers.js' import { type FormModel } from '~/src/server/plugins/engine/models/index.js' -import { type PageControllerClass } from '~/src/server/plugins/engine/pageControllers/helpers.js' +import { type PageControllerClass } from '~/src/server/plugins/engine/pageControllers/factory.js' import { validationOptions as opts } from '~/src/server/plugins/engine/pageControllers/validationOptions.js' import { type FormPayload, diff --git a/src/server/plugins/engine/components/FileUploadField.test.ts b/src/server/plugins/engine/components/FileUploadField.test.ts index 8fb476c5c..9fb7a7c10 100644 --- a/src/server/plugins/engine/components/FileUploadField.test.ts +++ b/src/server/plugins/engine/components/FileUploadField.test.ts @@ -13,7 +13,7 @@ import { FormModel } from '~/src/server/plugins/engine/models/FormModel.js' import { createPage, type PageControllerClass -} from '~/src/server/plugins/engine/pageControllers/helpers.js' +} from '~/src/server/plugins/engine/pageControllers/factory.js' import { validationOptions as opts } from '~/src/server/plugins/engine/pageControllers/validationOptions.js' import { FileStatus, diff --git a/src/server/plugins/engine/helpers.test.ts b/src/server/plugins/engine/helpers.test.ts index 3fae71501..bb744b161 100644 --- a/src/server/plugins/engine/helpers.test.ts +++ b/src/server/plugins/engine/helpers.test.ts @@ -22,7 +22,7 @@ import { buildFormContextRequest } from '~/src/server/plugins/engine/pageControl import { createPage, type PageControllerClass -} from '~/src/server/plugins/engine/pageControllers/helpers.js' +} from '~/src/server/plugins/engine/pageControllers/factory.js' import { type FormContext, type FormContextRequest diff --git a/src/server/plugins/engine/helpers.ts b/src/server/plugins/engine/helpers.ts index 9682ade69..2922766bd 100644 --- a/src/server/plugins/engine/helpers.ts +++ b/src/server/plugins/engine/helpers.ts @@ -21,7 +21,7 @@ import { type Field } from '~/src/server/plugins/engine/components/factory.js' import { type FormModel } from '~/src/server/plugins/engine/models/FormModel.js' -import { type PageControllerClass } from '~/src/server/plugins/engine/pageControllers/helpers.js' +import { type PageControllerClass } from '~/src/server/plugins/engine/pageControllers/factory.js' import { type FormContext, type FormContextRequest, diff --git a/src/server/plugins/engine/models/FormModel.ts b/src/server/plugins/engine/models/FormModel.ts index a77889209..5cda64cfe 100644 --- a/src/server/plugins/engine/models/FormModel.ts +++ b/src/server/plugins/engine/models/FormModel.ts @@ -46,7 +46,7 @@ import { type PageController } from '~/src/server/plugins/engine/pageControllers import { createPage, type PageControllerClass -} from '~/src/server/plugins/engine/pageControllers/helpers.js' +} from '~/src/server/plugins/engine/pageControllers/factory.js' import { validationOptions as opts } from '~/src/server/plugins/engine/pageControllers/validationOptions.js' import * as defaultServices from '~/src/server/plugins/engine/services/index.js' import { diff --git a/src/server/plugins/engine/models/SummaryViewModel.test.ts b/src/server/plugins/engine/models/SummaryViewModel.test.ts index 32ac820c1..8f8e5c760 100644 --- a/src/server/plugins/engine/models/SummaryViewModel.test.ts +++ b/src/server/plugins/engine/models/SummaryViewModel.test.ts @@ -9,7 +9,7 @@ import { serverWithSaveAndReturn } from '~/src/server/plugins/engine/pageControl import { createPage, type PageControllerClass -} from '~/src/server/plugins/engine/pageControllers/helpers.js' +} from '~/src/server/plugins/engine/pageControllers/factory.js' import { type FormContext, type FormContextRequest, diff --git a/src/server/plugins/engine/models/SummaryViewModel.ts b/src/server/plugins/engine/models/SummaryViewModel.ts index 5a50905d5..8fe6ac1f8 100644 --- a/src/server/plugins/engine/models/SummaryViewModel.ts +++ b/src/server/plugins/engine/models/SummaryViewModel.ts @@ -20,7 +20,7 @@ import { type DetailItemRepeat } from '~/src/server/plugins/engine/models/types.js' import { RepeatPageController } from '~/src/server/plugins/engine/pageControllers/RepeatPageController.js' -import { type PageControllerClass } from '~/src/server/plugins/engine/pageControllers/helpers.js' +import { type PageControllerClass } from '~/src/server/plugins/engine/pageControllers/factory.js' import { validationOptions as opts } from '~/src/server/plugins/engine/pageControllers/validationOptions.js' import { type CheckAnswers, diff --git a/src/server/plugins/engine/models/types.ts b/src/server/plugins/engine/models/types.ts index 0baea6126..0cdf745ce 100644 --- a/src/server/plugins/engine/models/types.ts +++ b/src/server/plugins/engine/models/types.ts @@ -10,7 +10,7 @@ import { type Field } from '~/src/server/plugins/engine/components/factory.js' import { type RepeatPageController } from '~/src/server/plugins/engine/pageControllers/RepeatPageController.js' -import { type PageControllerClass } from '~/src/server/plugins/engine/pageControllers/helpers.js' +import { type PageControllerClass } from '~/src/server/plugins/engine/pageControllers/factory.js' import { type FormState, type FormSubmissionError diff --git a/src/server/plugins/engine/pageControllers/factory.ts b/src/server/plugins/engine/pageControllers/factory.ts new file mode 100644 index 000000000..a49389887 --- /dev/null +++ b/src/server/plugins/engine/pageControllers/factory.ts @@ -0,0 +1,80 @@ +import { + ControllerType, + controllerNameFromPath, + isControllerName, + type Page +} from '@defra/forms-model' + +import { type FormModel } from '~/src/server/plugins/engine/models/index.js' +import * as PageControllers from '~/src/server/plugins/engine/pageControllers/index.js' + +export function isPageController( + controllerName?: string | ControllerType +): controllerName is keyof typeof PageControllers { + return isControllerName(controllerName) && controllerName in PageControllers +} + +export type PageControllerClass = InstanceType +export type PageControllerType = + (typeof PageControllers)[keyof typeof PageControllers] + +/** + * Creates page instance for each {@link Page} type + */ +export function createPage(model: FormModel, pageDef: Page) { + const controllerName = controllerNameFromPath(pageDef.controller) + + if (!pageDef.controller) { + return new PageControllers.QuestionPageController(model, pageDef) + } + + // Patch legacy controllers + if (controllerName && pageDef.controller !== controllerName) { + pageDef.controller = controllerName + } + + let controller: PageControllerClass | undefined + + switch (pageDef.controller) { + case ControllerType.Start: + controller = new PageControllers.StartPageController(model, pageDef) + break + + case ControllerType.Page: + controller = new PageControllers.QuestionPageController(model, pageDef) + break + + case ControllerType.Terminal: + controller = new PageControllers.TerminalPageController(model, pageDef) + break + + case ControllerType.Summary: + controller = new PageControllers.SummaryPageController(model, pageDef) + break + + case ControllerType.Status: + controller = new PageControllers.StatusPageController(model, pageDef) + break + + case ControllerType.FileUpload: + controller = new PageControllers.FileUploadPageController(model, pageDef) + break + + case ControllerType.Repeat: + controller = new PageControllers.RepeatPageController(model, pageDef) + break + } + + if (typeof controller === 'undefined') { + if (model.controllers?.[pageDef.controller]) { + const Ctrl = model.controllers[pageDef.controller] + controller = new Ctrl(model, pageDef) as unknown as PageControllerClass // type assertion needed because TS can't verify custom controller structure + } + } + + if (typeof controller === 'undefined') { + throw new Error(`Page controller ${pageDef.controller} does not exist`) + } + + return controller +} diff --git a/src/server/plugins/engine/pageControllers/helpers.test.ts b/src/server/plugins/engine/pageControllers/helpers.test.ts index 52a0da64c..60f824067 100644 --- a/src/server/plugins/engine/pageControllers/helpers.test.ts +++ b/src/server/plugins/engine/pageControllers/helpers.test.ts @@ -10,10 +10,10 @@ import { FormModel } from '~/src/server/plugins/engine/models/FormModel.js' import { PageController } from '~/src/server/plugins/engine/pageControllers/PageController.js' import { createPage, - getProxyUrlForLocalDevelopment, isPageController, type PageControllerType -} from '~/src/server/plugins/engine/pageControllers/helpers.js' +} from '~/src/server/plugins/engine/pageControllers/factory.js' +import { getProxyUrlForLocalDevelopment } from '~/src/server/plugins/engine/pageControllers/helpers.js' import { FileUploadPageController, QuestionPageController, diff --git a/src/server/plugins/engine/pageControllers/helpers.ts b/src/server/plugins/engine/pageControllers/helpers.ts index 9dbc17466..e4f46857f 100644 --- a/src/server/plugins/engine/pageControllers/helpers.ts +++ b/src/server/plugins/engine/pageControllers/helpers.ts @@ -1,84 +1,3 @@ -import { - ControllerType, - controllerNameFromPath, - isControllerName, - type Page -} from '@defra/forms-model' - -import { type FormModel } from '~/src/server/plugins/engine/models/FormModel.js' -import * as PageControllers from '~/src/server/plugins/engine/pageControllers/index.js' - -export function isPageController( - controllerName?: string | ControllerType -): controllerName is keyof typeof PageControllers { - return isControllerName(controllerName) && controllerName in PageControllers -} - -export type PageControllerClass = InstanceType -export type PageControllerType = - (typeof PageControllers)[keyof typeof PageControllers] - -/** - * Creates page instance for each {@link Page} type - */ -export function createPage(model: FormModel, pageDef: Page) { - const controllerName = controllerNameFromPath(pageDef.controller) - - if (!pageDef.controller) { - return new PageControllers.QuestionPageController(model, pageDef) - } - - // Patch legacy controllers - if (controllerName && pageDef.controller !== controllerName) { - pageDef.controller = controllerName - } - - let controller: PageControllerClass | undefined - - switch (pageDef.controller) { - case ControllerType.Start: - controller = new PageControllers.StartPageController(model, pageDef) - break - - case ControllerType.Page: - controller = new PageControllers.QuestionPageController(model, pageDef) - break - - case ControllerType.Terminal: - controller = new PageControllers.TerminalPageController(model, pageDef) - break - - case ControllerType.Summary: - controller = new PageControllers.SummaryPageController(model, pageDef) - break - - case ControllerType.Status: - controller = new PageControllers.StatusPageController(model, pageDef) - break - - case ControllerType.FileUpload: - controller = new PageControllers.FileUploadPageController(model, pageDef) - break - - case ControllerType.Repeat: - controller = new PageControllers.RepeatPageController(model, pageDef) - break - } - - if (typeof controller === 'undefined') { - if (model.controllers?.[pageDef.controller]) { - const Ctrl = model.controllers[pageDef.controller] - controller = new Ctrl(model, pageDef) as unknown as PageControllerClass // type assertion needed because TS can't verify custom controller structure - } - } - - if (typeof controller === 'undefined') { - throw new Error(`Page controller ${pageDef.controller} does not exist`) - } - - return controller -} - /** * In local development environments, we sometimes need to rewrite the * CDP upload URL to work with CSP/CORS restrictions. diff --git a/src/server/plugins/engine/routes/index.ts b/src/server/plugins/engine/routes/index.ts index 25583bec1..4f7fee184 100644 --- a/src/server/plugins/engine/routes/index.ts +++ b/src/server/plugins/engine/routes/index.ts @@ -17,7 +17,7 @@ import { proceed } from '~/src/server/plugins/engine/helpers.js' import { FormModel } from '~/src/server/plugins/engine/models/index.js' -import { type PageControllerClass } from '~/src/server/plugins/engine/pageControllers/helpers.js' +import { type PageControllerClass } from '~/src/server/plugins/engine/pageControllers/factory.js' import { generateUniqueReference } from '~/src/server/plugins/engine/referenceNumbers.js' import * as defaultServices from '~/src/server/plugins/engine/services/index.js' import { diff --git a/src/server/plugins/engine/routes/questions.test.ts b/src/server/plugins/engine/routes/questions.test.ts index c48d9e6b3..b065e9f8f 100644 --- a/src/server/plugins/engine/routes/questions.test.ts +++ b/src/server/plugins/engine/routes/questions.test.ts @@ -4,7 +4,7 @@ import { type ResponseObject, type ResponseToolkit } from '@hapi/hapi' import nock from 'nock' import { type FormModel } from '~/src/server/plugins/engine/models/FormModel.js' -import { type PageControllerClass } from '~/src/server/plugins/engine/pageControllers/helpers.js' +import { type PageControllerClass } from '~/src/server/plugins/engine/pageControllers/factory.js' import { redirectOrMakeHandler } from '~/src/server/plugins/engine/routes/index.js' import { makeGetHandler, diff --git a/src/server/plugins/engine/routes/questions.ts b/src/server/plugins/engine/routes/questions.ts index 049074f8a..57849c4f9 100644 --- a/src/server/plugins/engine/routes/questions.ts +++ b/src/server/plugins/engine/routes/questions.ts @@ -19,7 +19,7 @@ import { } from '~/src/server/plugins/engine/models/index.js' import { format } from '~/src/server/plugins/engine/outputFormatters/machine/v1.js' import { getFormSubmissionData } from '~/src/server/plugins/engine/pageControllers/SummaryPageController.js' -import { type PageControllerClass } from '~/src/server/plugins/engine/pageControllers/helpers.js' +import { type PageControllerClass } from '~/src/server/plugins/engine/pageControllers/factory.js' import { dispatchHandler, redirectOrMakeHandler diff --git a/src/server/plugins/engine/types.ts b/src/server/plugins/engine/types.ts index 3077283d4..a130d17cb 100644 --- a/src/server/plugins/engine/types.ts +++ b/src/server/plugins/engine/types.ts @@ -20,7 +20,7 @@ import { import { type FormModel } from '~/src/server/plugins/engine/models/index.js' import { type RichFormValue } from '~/src/server/plugins/engine/outputFormatters/machine/v2.js' import { type PageController } from '~/src/server/plugins/engine/pageControllers/PageController.js' -import { type PageControllerClass } from '~/src/server/plugins/engine/pageControllers/helpers.js' +import { type PageControllerClass } from '~/src/server/plugins/engine/pageControllers/factory.js' import { type ViewContext } from '~/src/server/plugins/nunjucks/types.js' import { type FormAction, From 00670d87e5b7da799330db5e5ee1b49d5af1acb4 Mon Sep 17 00:00:00 2001 From: whitewater design Date: Thu, 28 Aug 2025 13:56:39 +0100 Subject: [PATCH 3/4] feat: DF-380 - Refactor following PR --- .../engine/components/AutocompleteField.test.ts | 2 +- .../plugins/engine/components/CheckboxesField.test.ts | 2 +- src/server/plugins/engine/components/ComponentBase.ts | 4 ++-- .../plugins/engine/components/ComponentCollection.ts | 4 ++-- .../plugins/engine/components/DatePartsField.test.ts | 2 +- src/server/plugins/engine/components/Details.test.ts | 2 +- .../engine/components/EmailAddressField.test.ts | 2 +- .../plugins/engine/components/FileUploadField.test.ts | 4 ++-- src/server/plugins/engine/components/Html.test.ts | 2 +- .../plugins/engine/components/InsetText.test.ts | 2 +- src/server/plugins/engine/components/List.test.ts | 2 +- src/server/plugins/engine/components/Markdown.test.ts | 2 +- .../plugins/engine/components/MonthYearField.test.ts | 2 +- .../engine/components/MultilineTextField.test.ts | 2 +- .../plugins/engine/components/NumberField.test.ts | 2 +- .../plugins/engine/components/RadiosField.test.ts | 2 +- .../plugins/engine/components/SelectField.test.ts | 2 +- .../engine/components/TelephoneNumberField.test.ts | 2 +- .../plugins/engine/components/TelephoneNumberField.ts | 2 +- .../plugins/engine/components/TextField.test.ts | 2 +- .../plugins/engine/components/UkAddressField.test.ts | 2 +- .../plugins/engine/components/YesNoField.test.ts | 2 +- src/server/plugins/engine/components/YesNoField.ts | 2 +- src/server/plugins/engine/components/helpers.test.ts | 2 +- .../components/{factory.ts => helpers/components.ts} | 2 +- .../components/{helpers.ts => helpers/index.ts} | 0 src/server/plugins/engine/helpers.test.ts | 2 +- src/server/plugins/engine/helpers.ts | 4 ++-- src/server/plugins/engine/models/FormModel.ts | 4 ++-- .../plugins/engine/models/SummaryViewModel.test.ts | 2 +- src/server/plugins/engine/models/SummaryViewModel.ts | 4 ++-- src/server/plugins/engine/models/types.ts | 4 ++-- .../engine/outputFormatters/adapter/v1.test.ts | 2 +- .../plugins/engine/outputFormatters/human/v1.ts | 4 ++-- .../engine/outputFormatters/machine/v1.test.ts | 2 +- .../plugins/engine/outputFormatters/machine/v1.ts | 2 +- .../engine/outputFormatters/machine/v2.test.ts | 2 +- .../pageControllers/FileUploadPageController.test.ts | 2 +- .../pageControllers/FileUploadPageController.ts | 2 +- .../engine/pageControllers/SummaryPageController.ts | 2 +- .../pageControllers/{ => helpers}/helpers.test.ts | 4 ++-- .../pageControllers/{helpers.ts => helpers/index.ts} | 0 .../pageControllers/{factory.ts => helpers/pages.ts} | 0 src/server/plugins/engine/routes/index.ts | 2 +- src/server/plugins/engine/routes/questions.test.ts | 2 +- src/server/plugins/engine/routes/questions.ts | 2 +- .../plugins/engine/services/notifyService.test.ts | 2 +- src/server/plugins/engine/services/notifyService.ts | 2 +- src/server/plugins/engine/types.ts | 6 +++--- src/server/plugins/nunjucks/filters/answer.js | 4 ++-- src/server/plugins/nunjucks/filters/answer.test.js | 11 +++++++---- 51 files changed, 66 insertions(+), 63 deletions(-) rename src/server/plugins/engine/components/{factory.ts => helpers/components.ts} (99%) rename src/server/plugins/engine/components/{helpers.ts => helpers/index.ts} (100%) rename src/server/plugins/engine/pageControllers/{ => helpers}/helpers.test.ts (98%) rename src/server/plugins/engine/pageControllers/{helpers.ts => helpers/index.ts} (100%) rename src/server/plugins/engine/pageControllers/{factory.ts => helpers/pages.ts} (100%) diff --git a/src/server/plugins/engine/components/AutocompleteField.test.ts b/src/server/plugins/engine/components/AutocompleteField.test.ts index 1954a3cdc..a94f0574d 100644 --- a/src/server/plugins/engine/components/AutocompleteField.test.ts +++ b/src/server/plugins/engine/components/AutocompleteField.test.ts @@ -9,7 +9,7 @@ import { ComponentCollection } from '~/src/server/plugins/engine/components/Comp import { getAnswer, type Field -} from '~/src/server/plugins/engine/components/factory.js' +} from '~/src/server/plugins/engine/components/helpers/components.js' import { FormModel } from '~/src/server/plugins/engine/models/FormModel.js' import { listNumber, diff --git a/src/server/plugins/engine/components/CheckboxesField.test.ts b/src/server/plugins/engine/components/CheckboxesField.test.ts index 41f17d4a5..9f304d174 100644 --- a/src/server/plugins/engine/components/CheckboxesField.test.ts +++ b/src/server/plugins/engine/components/CheckboxesField.test.ts @@ -11,7 +11,7 @@ import { ComponentCollection } from '~/src/server/plugins/engine/components/Comp import { getAnswer, type Field -} from '~/src/server/plugins/engine/components/factory.js' +} from '~/src/server/plugins/engine/components/helpers/components.js' import { FormModel } from '~/src/server/plugins/engine/models/FormModel.js' import { listNumber, diff --git a/src/server/plugins/engine/components/ComponentBase.ts b/src/server/plugins/engine/components/ComponentBase.ts index 3c532f56a..307583354 100644 --- a/src/server/plugins/engine/components/ComponentBase.ts +++ b/src/server/plugins/engine/components/ComponentBase.ts @@ -9,10 +9,10 @@ import joi, { } from 'joi' import { type ComponentCollection } from '~/src/server/plugins/engine/components/ComponentCollection.js' -import { type Component } from '~/src/server/plugins/engine/components/factory.js' +import { type Component } from '~/src/server/plugins/engine/components/helpers/components.js' import { type ViewModel } from '~/src/server/plugins/engine/components/types.js' import { type FormModel } from '~/src/server/plugins/engine/models/index.js' -import { type PageControllerClass } from '~/src/server/plugins/engine/pageControllers/factory.js' +import { type PageControllerClass } from '~/src/server/plugins/engine/pageControllers/helpers/pages.js' export class ComponentBase { page?: PageControllerClass diff --git a/src/server/plugins/engine/components/ComponentCollection.ts b/src/server/plugins/engine/components/ComponentCollection.ts index dd24b6d8d..faf8271ca 100644 --- a/src/server/plugins/engine/components/ComponentCollection.ts +++ b/src/server/plugins/engine/components/ComponentCollection.ts @@ -15,11 +15,11 @@ import { type Component, type Field, type Guidance -} from '~/src/server/plugins/engine/components/factory.js' +} from '~/src/server/plugins/engine/components/helpers/components.js' import { type ComponentViewModel } from '~/src/server/plugins/engine/components/types.js' import { getErrors } from '~/src/server/plugins/engine/helpers.js' import { type FormModel } from '~/src/server/plugins/engine/models/index.js' -import { type PageControllerClass } from '~/src/server/plugins/engine/pageControllers/factory.js' +import { type PageControllerClass } from '~/src/server/plugins/engine/pageControllers/helpers/pages.js' import { validationOptions as opts } from '~/src/server/plugins/engine/pageControllers/validationOptions.js' import { type FormPayload, diff --git a/src/server/plugins/engine/components/DatePartsField.test.ts b/src/server/plugins/engine/components/DatePartsField.test.ts index 05fd959b2..dc4fab8fc 100644 --- a/src/server/plugins/engine/components/DatePartsField.test.ts +++ b/src/server/plugins/engine/components/DatePartsField.test.ts @@ -5,7 +5,7 @@ import { ComponentCollection } from '~/src/server/plugins/engine/components/Comp import { getAnswer, type Field -} from '~/src/server/plugins/engine/components/factory.js' +} from '~/src/server/plugins/engine/components/helpers/components.js' import { type DateInputItem } from '~/src/server/plugins/engine/components/types.js' import { FormModel } from '~/src/server/plugins/engine/models/FormModel.js' import { diff --git a/src/server/plugins/engine/components/Details.test.ts b/src/server/plugins/engine/components/Details.test.ts index 9a35faf97..4d9c1a6a0 100644 --- a/src/server/plugins/engine/components/Details.test.ts +++ b/src/server/plugins/engine/components/Details.test.ts @@ -1,7 +1,7 @@ import { ComponentType, type DetailsComponent } from '@defra/forms-model' import { ComponentCollection } from '~/src/server/plugins/engine/components/ComponentCollection.js' -import { type Guidance } from '~/src/server/plugins/engine/components/factory.js' +import { type Guidance } from '~/src/server/plugins/engine/components/helpers/components.js' import { FormModel } from '~/src/server/plugins/engine/models/FormModel.js' import definition from '~/test/form/definitions/basic.js' diff --git a/src/server/plugins/engine/components/EmailAddressField.test.ts b/src/server/plugins/engine/components/EmailAddressField.test.ts index 0484bbf89..580c1bac9 100644 --- a/src/server/plugins/engine/components/EmailAddressField.test.ts +++ b/src/server/plugins/engine/components/EmailAddressField.test.ts @@ -7,7 +7,7 @@ import { ComponentCollection } from '~/src/server/plugins/engine/components/Comp import { getAnswer, type Field -} from '~/src/server/plugins/engine/components/factory.js' +} from '~/src/server/plugins/engine/components/helpers/components.js' import { FormModel } from '~/src/server/plugins/engine/models/FormModel.js' import definition from '~/test/form/definitions/blank.js' import { getFormData, getFormState } from '~/test/helpers/component-helpers.js' diff --git a/src/server/plugins/engine/components/FileUploadField.test.ts b/src/server/plugins/engine/components/FileUploadField.test.ts index 9fb7a7c10..5c16e7c00 100644 --- a/src/server/plugins/engine/components/FileUploadField.test.ts +++ b/src/server/plugins/engine/components/FileUploadField.test.ts @@ -8,12 +8,12 @@ import { tempItemSchema } from '~/src/server/plugins/engine/components/FileUploa import { getAnswer, type Field -} from '~/src/server/plugins/engine/components/factory.js' +} from '~/src/server/plugins/engine/components/helpers/components.js' import { FormModel } from '~/src/server/plugins/engine/models/FormModel.js' import { createPage, type PageControllerClass -} from '~/src/server/plugins/engine/pageControllers/factory.js' +} from '~/src/server/plugins/engine/pageControllers/helpers/pages.js' import { validationOptions as opts } from '~/src/server/plugins/engine/pageControllers/validationOptions.js' import { FileStatus, diff --git a/src/server/plugins/engine/components/Html.test.ts b/src/server/plugins/engine/components/Html.test.ts index f19fdaf83..321a6068c 100644 --- a/src/server/plugins/engine/components/Html.test.ts +++ b/src/server/plugins/engine/components/Html.test.ts @@ -1,7 +1,7 @@ import { ComponentType, type HtmlComponent } from '@defra/forms-model' import { ComponentCollection } from '~/src/server/plugins/engine/components/ComponentCollection.js' -import { type Guidance } from '~/src/server/plugins/engine/components/factory.js' +import { type Guidance } from '~/src/server/plugins/engine/components/helpers/components.js' import { FormModel } from '~/src/server/plugins/engine/models/FormModel.js' import definition from '~/test/form/definitions/basic.js' diff --git a/src/server/plugins/engine/components/InsetText.test.ts b/src/server/plugins/engine/components/InsetText.test.ts index d7053a14a..d0daae408 100644 --- a/src/server/plugins/engine/components/InsetText.test.ts +++ b/src/server/plugins/engine/components/InsetText.test.ts @@ -1,7 +1,7 @@ import { ComponentType, type InsetTextComponent } from '@defra/forms-model' import { ComponentCollection } from '~/src/server/plugins/engine/components/ComponentCollection.js' -import { type Guidance } from '~/src/server/plugins/engine/components/factory.js' +import { type Guidance } from '~/src/server/plugins/engine/components/helpers/components.js' import { FormModel } from '~/src/server/plugins/engine/models/FormModel.js' import definition from '~/test/form/definitions/basic.js' diff --git a/src/server/plugins/engine/components/List.test.ts b/src/server/plugins/engine/components/List.test.ts index 5346c232a..1e91e53e0 100644 --- a/src/server/plugins/engine/components/List.test.ts +++ b/src/server/plugins/engine/components/List.test.ts @@ -1,7 +1,7 @@ import { ComponentType, type ListComponent } from '@defra/forms-model' import { ComponentCollection } from '~/src/server/plugins/engine/components/ComponentCollection.js' -import { type Guidance } from '~/src/server/plugins/engine/components/factory.js' +import { type Guidance } from '~/src/server/plugins/engine/components/helpers/components.js' import { FormModel } from '~/src/server/plugins/engine/models/FormModel.js' import definition from '~/test/form/definitions/basic.js' diff --git a/src/server/plugins/engine/components/Markdown.test.ts b/src/server/plugins/engine/components/Markdown.test.ts index 7b61e9ff7..a5f5fd8ef 100644 --- a/src/server/plugins/engine/components/Markdown.test.ts +++ b/src/server/plugins/engine/components/Markdown.test.ts @@ -1,7 +1,7 @@ import { ComponentType, type MarkdownComponent } from '@defra/forms-model' import { ComponentCollection } from '~/src/server/plugins/engine/components/ComponentCollection.js' -import { type Guidance } from '~/src/server/plugins/engine/components/factory.js' +import { type Guidance } from '~/src/server/plugins/engine/components/helpers/components.js' import { FormModel } from '~/src/server/plugins/engine/models/FormModel.js' import definition from '~/test/form/definitions/basic.js' diff --git a/src/server/plugins/engine/components/MonthYearField.test.ts b/src/server/plugins/engine/components/MonthYearField.test.ts index cd7fc1346..7781fcdc8 100644 --- a/src/server/plugins/engine/components/MonthYearField.test.ts +++ b/src/server/plugins/engine/components/MonthYearField.test.ts @@ -5,7 +5,7 @@ import { ComponentCollection } from '~/src/server/plugins/engine/components/Comp import { getAnswer, type Field -} from '~/src/server/plugins/engine/components/factory.js' +} from '~/src/server/plugins/engine/components/helpers/components.js' import { type DateInputItem } from '~/src/server/plugins/engine/components/types.js' import { FormModel } from '~/src/server/plugins/engine/models/FormModel.js' import { diff --git a/src/server/plugins/engine/components/MultilineTextField.test.ts b/src/server/plugins/engine/components/MultilineTextField.test.ts index 452ce0324..f76358fc5 100644 --- a/src/server/plugins/engine/components/MultilineTextField.test.ts +++ b/src/server/plugins/engine/components/MultilineTextField.test.ts @@ -8,7 +8,7 @@ import { MultilineTextField } from '~/src/server/plugins/engine/components/Multi import { getAnswer, type Field -} from '~/src/server/plugins/engine/components/factory.js' +} from '~/src/server/plugins/engine/components/helpers/components.js' import { FormModel } from '~/src/server/plugins/engine/models/FormModel.js' import definition from '~/test/form/definitions/blank.js' import { getFormData, getFormState } from '~/test/helpers/component-helpers.js' diff --git a/src/server/plugins/engine/components/NumberField.test.ts b/src/server/plugins/engine/components/NumberField.test.ts index 6ae1d25e9..28b266df0 100644 --- a/src/server/plugins/engine/components/NumberField.test.ts +++ b/src/server/plugins/engine/components/NumberField.test.ts @@ -5,7 +5,7 @@ import { NumberField } from '~/src/server/plugins/engine/components/NumberField. import { getAnswer, type Field -} from '~/src/server/plugins/engine/components/factory.js' +} from '~/src/server/plugins/engine/components/helpers/components.js' import { FormModel } from '~/src/server/plugins/engine/models/FormModel.js' import definition from '~/test/form/definitions/blank.js' import { getFormData, getFormState } from '~/test/helpers/component-helpers.js' diff --git a/src/server/plugins/engine/components/RadiosField.test.ts b/src/server/plugins/engine/components/RadiosField.test.ts index f4526686a..8ccc0ff9f 100644 --- a/src/server/plugins/engine/components/RadiosField.test.ts +++ b/src/server/plugins/engine/components/RadiosField.test.ts @@ -6,7 +6,7 @@ import { RadiosField } from '~/src/server/plugins/engine/components/RadiosField. import { getAnswer, type Field -} from '~/src/server/plugins/engine/components/factory.js' +} from '~/src/server/plugins/engine/components/helpers/components.js' import { FormModel } from '~/src/server/plugins/engine/models/FormModel.js' import { listNumber, diff --git a/src/server/plugins/engine/components/SelectField.test.ts b/src/server/plugins/engine/components/SelectField.test.ts index 5986fd9dd..19dad941d 100644 --- a/src/server/plugins/engine/components/SelectField.test.ts +++ b/src/server/plugins/engine/components/SelectField.test.ts @@ -6,7 +6,7 @@ import { SelectField } from '~/src/server/plugins/engine/components/SelectField. import { getAnswer, type Field -} from '~/src/server/plugins/engine/components/factory.js' +} from '~/src/server/plugins/engine/components/helpers/components.js' import { FormModel } from '~/src/server/plugins/engine/models/FormModel.js' import { listNumber, diff --git a/src/server/plugins/engine/components/TelephoneNumberField.test.ts b/src/server/plugins/engine/components/TelephoneNumberField.test.ts index a6dd99124..8ac5863cd 100644 --- a/src/server/plugins/engine/components/TelephoneNumberField.test.ts +++ b/src/server/plugins/engine/components/TelephoneNumberField.test.ts @@ -7,7 +7,7 @@ import { ComponentCollection } from '~/src/server/plugins/engine/components/Comp import { getAnswer, type Field -} from '~/src/server/plugins/engine/components/factory.js' +} from '~/src/server/plugins/engine/components/helpers/components.js' import { FormModel } from '~/src/server/plugins/engine/models/FormModel.js' import definition from '~/test/form/definitions/blank.js' import { getFormData, getFormState } from '~/test/helpers/component-helpers.js' diff --git a/src/server/plugins/engine/components/TelephoneNumberField.ts b/src/server/plugins/engine/components/TelephoneNumberField.ts index 14f8b22fc..4f817bd51 100644 --- a/src/server/plugins/engine/components/TelephoneNumberField.ts +++ b/src/server/plugins/engine/components/TelephoneNumberField.ts @@ -2,7 +2,7 @@ import { type TelephoneNumberFieldComponent } from '@defra/forms-model' import joi, { type StringSchema } from 'joi' import { FormComponent } from '~/src/server/plugins/engine/components/FormComponent.js' -import { addClassOptionIfNone } from '~/src/server/plugins/engine/components/helpers.js' +import { addClassOptionIfNone } from '~/src/server/plugins/engine/components/helpers/index.js' import { messageTemplate } from '~/src/server/plugins/engine/pageControllers/validationOptions.js' import { type ErrorMessageTemplateList, diff --git a/src/server/plugins/engine/components/TextField.test.ts b/src/server/plugins/engine/components/TextField.test.ts index cf5b5f291..492e0fff5 100644 --- a/src/server/plugins/engine/components/TextField.test.ts +++ b/src/server/plugins/engine/components/TextField.test.ts @@ -4,7 +4,7 @@ import { ComponentCollection } from '~/src/server/plugins/engine/components/Comp import { getAnswer, type Field -} from '~/src/server/plugins/engine/components/factory.js' +} from '~/src/server/plugins/engine/components/helpers/components.js' import { FormModel } from '~/src/server/plugins/engine/models/FormModel.js' import definition from '~/test/form/definitions/blank.js' import { getFormData, getFormState } from '~/test/helpers/component-helpers.js' diff --git a/src/server/plugins/engine/components/UkAddressField.test.ts b/src/server/plugins/engine/components/UkAddressField.test.ts index d8fbe5fe2..784e19c68 100644 --- a/src/server/plugins/engine/components/UkAddressField.test.ts +++ b/src/server/plugins/engine/components/UkAddressField.test.ts @@ -9,7 +9,7 @@ import { UkAddressField } from '~/src/server/plugins/engine/components/UkAddress import { getAnswer, type Field -} from '~/src/server/plugins/engine/components/factory.js' +} from '~/src/server/plugins/engine/components/helpers/components.js' import { type ViewModel } from '~/src/server/plugins/engine/components/types.js' import { FormModel } from '~/src/server/plugins/engine/models/FormModel.js' import { diff --git a/src/server/plugins/engine/components/YesNoField.test.ts b/src/server/plugins/engine/components/YesNoField.test.ts index bd2aa44b8..1178c9f7a 100644 --- a/src/server/plugins/engine/components/YesNoField.test.ts +++ b/src/server/plugins/engine/components/YesNoField.test.ts @@ -4,7 +4,7 @@ import { ComponentCollection } from '~/src/server/plugins/engine/components/Comp import { getAnswer, type Field -} from '~/src/server/plugins/engine/components/factory.js' +} from '~/src/server/plugins/engine/components/helpers/components.js' import { FormModel } from '~/src/server/plugins/engine/models/FormModel.js' import { listYesNoExamples } from '~/test/fixtures/list.js' import definition from '~/test/form/definitions/blank.js' diff --git a/src/server/plugins/engine/components/YesNoField.ts b/src/server/plugins/engine/components/YesNoField.ts index 967c07179..598253d75 100644 --- a/src/server/plugins/engine/components/YesNoField.ts +++ b/src/server/plugins/engine/components/YesNoField.ts @@ -6,7 +6,7 @@ import { } from '@defra/forms-model' import { SelectionControlField } from '~/src/server/plugins/engine/components/SelectionControlField.js' -import { addClassOptionIfNone } from '~/src/server/plugins/engine/components/helpers.js' +import { addClassOptionIfNone } from '~/src/server/plugins/engine/components/helpers/index.js' import { messageTemplate } from '~/src/server/plugins/engine/pageControllers/validationOptions.js' import { type ErrorMessageTemplateList } from '~/src/server/plugins/engine/types.js' import { convertToLanguageMessages } from '~/src/server/utils/type-utils.js' diff --git a/src/server/plugins/engine/components/helpers.test.ts b/src/server/plugins/engine/components/helpers.test.ts index c8c2bee1d..a753bfabf 100644 --- a/src/server/plugins/engine/components/helpers.test.ts +++ b/src/server/plugins/engine/components/helpers.test.ts @@ -1,7 +1,7 @@ import { type ComponentDef } from '@defra/forms-model' import { ComponentBase } from '~/src/server/plugins/engine/components/ComponentBase.js' -import { createComponent } from '~/src/server/plugins/engine/components/factory.js' +import { createComponent } from '~/src/server/plugins/engine/components/helpers/components.js' import { FormModel } from '~/src/server/plugins/engine/models/FormModel.js' import definition from '~/test/form/definitions/basic.js' diff --git a/src/server/plugins/engine/components/factory.ts b/src/server/plugins/engine/components/helpers/components.ts similarity index 99% rename from src/server/plugins/engine/components/factory.ts rename to src/server/plugins/engine/components/helpers/components.ts index f84b75ccf..82fd6d210 100644 --- a/src/server/plugins/engine/components/factory.ts +++ b/src/server/plugins/engine/components/helpers/components.ts @@ -4,7 +4,7 @@ import { Marked, type Token } from 'marked' import { config } from '~/src/config/index.js' import { type ComponentBase } from '~/src/server/plugins/engine/components/ComponentBase.js' import { ListFormComponent } from '~/src/server/plugins/engine/components/ListFormComponent.js' -import { escapeMarkdown } from '~/src/server/plugins/engine/components/helpers.js' +import { escapeMarkdown } from '~/src/server/plugins/engine/components/helpers/index.js' import * as Components from '~/src/server/plugins/engine/components/index.js' import { type FormState } from '~/src/server/plugins/engine/types.js' diff --git a/src/server/plugins/engine/components/helpers.ts b/src/server/plugins/engine/components/helpers/index.ts similarity index 100% rename from src/server/plugins/engine/components/helpers.ts rename to src/server/plugins/engine/components/helpers/index.ts diff --git a/src/server/plugins/engine/helpers.test.ts b/src/server/plugins/engine/helpers.test.ts index bb744b161..632a431ca 100644 --- a/src/server/plugins/engine/helpers.test.ts +++ b/src/server/plugins/engine/helpers.test.ts @@ -22,7 +22,7 @@ import { buildFormContextRequest } from '~/src/server/plugins/engine/pageControl import { createPage, type PageControllerClass -} from '~/src/server/plugins/engine/pageControllers/factory.js' +} from '~/src/server/plugins/engine/pageControllers/helpers/pages.js' import { type FormContext, type FormContextRequest diff --git a/src/server/plugins/engine/helpers.ts b/src/server/plugins/engine/helpers.ts index 2922766bd..9f6ffed16 100644 --- a/src/server/plugins/engine/helpers.ts +++ b/src/server/plugins/engine/helpers.ts @@ -19,9 +19,9 @@ import { createLogger } from '~/src/server/common/helpers/logging/logger.js' import { getAnswer, type Field -} from '~/src/server/plugins/engine/components/factory.js' +} from '~/src/server/plugins/engine/components/helpers/components.js' import { type FormModel } from '~/src/server/plugins/engine/models/FormModel.js' -import { type PageControllerClass } from '~/src/server/plugins/engine/pageControllers/factory.js' +import { type PageControllerClass } from '~/src/server/plugins/engine/pageControllers/helpers/pages.js' import { type FormContext, type FormContextRequest, diff --git a/src/server/plugins/engine/models/FormModel.ts b/src/server/plugins/engine/models/FormModel.ts index 5cda64cfe..edf9576f0 100644 --- a/src/server/plugins/engine/models/FormModel.ts +++ b/src/server/plugins/engine/models/FormModel.ts @@ -33,7 +33,7 @@ import {} from '~/src/server/plugins/engine/components/YesNoField.js' import { hasListFormField, type Component -} from '~/src/server/plugins/engine/components/factory.js' +} from '~/src/server/plugins/engine/components/helpers/components.js' import { todayAsDateOnly } from '~/src/server/plugins/engine/date-helper.js' import { findPage, @@ -46,7 +46,7 @@ import { type PageController } from '~/src/server/plugins/engine/pageControllers import { createPage, type PageControllerClass -} from '~/src/server/plugins/engine/pageControllers/factory.js' +} from '~/src/server/plugins/engine/pageControllers/helpers/pages.js' import { validationOptions as opts } from '~/src/server/plugins/engine/pageControllers/validationOptions.js' import * as defaultServices from '~/src/server/plugins/engine/services/index.js' import { diff --git a/src/server/plugins/engine/models/SummaryViewModel.test.ts b/src/server/plugins/engine/models/SummaryViewModel.test.ts index 8f8e5c760..e5189dbd0 100644 --- a/src/server/plugins/engine/models/SummaryViewModel.test.ts +++ b/src/server/plugins/engine/models/SummaryViewModel.test.ts @@ -9,7 +9,7 @@ import { serverWithSaveAndReturn } from '~/src/server/plugins/engine/pageControl import { createPage, type PageControllerClass -} from '~/src/server/plugins/engine/pageControllers/factory.js' +} from '~/src/server/plugins/engine/pageControllers/helpers/pages.js' import { type FormContext, type FormContextRequest, diff --git a/src/server/plugins/engine/models/SummaryViewModel.ts b/src/server/plugins/engine/models/SummaryViewModel.ts index 8fe6ac1f8..1857b7fce 100644 --- a/src/server/plugins/engine/models/SummaryViewModel.ts +++ b/src/server/plugins/engine/models/SummaryViewModel.ts @@ -3,7 +3,7 @@ import { type Section } from '@defra/forms-model' import { getAnswer, type Field -} from '~/src/server/plugins/engine/components/factory.js' +} from '~/src/server/plugins/engine/components/helpers/components.js' import { type BackLink, type ComponentViewModel @@ -20,7 +20,7 @@ import { type DetailItemRepeat } from '~/src/server/plugins/engine/models/types.js' import { RepeatPageController } from '~/src/server/plugins/engine/pageControllers/RepeatPageController.js' -import { type PageControllerClass } from '~/src/server/plugins/engine/pageControllers/factory.js' +import { type PageControllerClass } from '~/src/server/plugins/engine/pageControllers/helpers/pages.js' import { validationOptions as opts } from '~/src/server/plugins/engine/pageControllers/validationOptions.js' import { type CheckAnswers, diff --git a/src/server/plugins/engine/models/types.ts b/src/server/plugins/engine/models/types.ts index 0cdf745ce..7f17c367a 100644 --- a/src/server/plugins/engine/models/types.ts +++ b/src/server/plugins/engine/models/types.ts @@ -8,9 +8,9 @@ import { type Expression } from 'expr-eval' import { getAnswer, type Field -} from '~/src/server/plugins/engine/components/factory.js' +} from '~/src/server/plugins/engine/components/helpers/components.js' import { type RepeatPageController } from '~/src/server/plugins/engine/pageControllers/RepeatPageController.js' -import { type PageControllerClass } from '~/src/server/plugins/engine/pageControllers/factory.js' +import { type PageControllerClass } from '~/src/server/plugins/engine/pageControllers/helpers/pages.js' import { type FormState, type FormSubmissionError diff --git a/src/server/plugins/engine/outputFormatters/adapter/v1.test.ts b/src/server/plugins/engine/outputFormatters/adapter/v1.test.ts index afcf14469..78dae0c90 100644 --- a/src/server/plugins/engine/outputFormatters/adapter/v1.test.ts +++ b/src/server/plugins/engine/outputFormatters/adapter/v1.test.ts @@ -1,7 +1,7 @@ import { type FormMetadata } from '@defra/forms-model' import { FileUploadField } from '~/src/server/plugins/engine/components/FileUploadField.js' -import { type Field } from '~/src/server/plugins/engine/components/factory.js' +import { type Field } from '~/src/server/plugins/engine/components/helpers/components.js' import { FormModel } from '~/src/server/plugins/engine/models/index.js' import { type DetailItem, diff --git a/src/server/plugins/engine/outputFormatters/human/v1.ts b/src/server/plugins/engine/outputFormatters/human/v1.ts index e65e69e8e..d83bcebc6 100644 --- a/src/server/plugins/engine/outputFormatters/human/v1.ts +++ b/src/server/plugins/engine/outputFormatters/human/v1.ts @@ -5,8 +5,8 @@ import { import { addDays, format as dateFormat } from 'date-fns' import { config } from '~/src/config/index.js' -import { getAnswer } from '~/src/server/plugins/engine/components/factory.js' -import { escapeMarkdown } from '~/src/server/plugins/engine/components/helpers.js' +import { getAnswer } from '~/src/server/plugins/engine/components/helpers/components.js' +import { escapeMarkdown } from '~/src/server/plugins/engine/components/helpers/index.js' import { type checkFormStatus } from '~/src/server/plugins/engine/helpers.js' import { type FormModel } from '~/src/server/plugins/engine/models/index.js' import { type DetailItem } from '~/src/server/plugins/engine/models/types.js' diff --git a/src/server/plugins/engine/outputFormatters/machine/v1.test.ts b/src/server/plugins/engine/outputFormatters/machine/v1.test.ts index 474ad27da..14ade7e6a 100644 --- a/src/server/plugins/engine/outputFormatters/machine/v1.test.ts +++ b/src/server/plugins/engine/outputFormatters/machine/v1.test.ts @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/no-unsafe-member-access */ import { FileUploadField } from '~/src/server/plugins/engine/components/FileUploadField.js' -import { type Field } from '~/src/server/plugins/engine/components/factory.js' +import { type Field } from '~/src/server/plugins/engine/components/helpers/components.js' import { FormModel } from '~/src/server/plugins/engine/models/index.js' import { type DetailItem, diff --git a/src/server/plugins/engine/outputFormatters/machine/v1.ts b/src/server/plugins/engine/outputFormatters/machine/v1.ts index 2ef841515..73907567e 100644 --- a/src/server/plugins/engine/outputFormatters/machine/v1.ts +++ b/src/server/plugins/engine/outputFormatters/machine/v1.ts @@ -4,7 +4,7 @@ import { } from '@defra/forms-model' import { config } from '~/src/config/index.js' -import { getAnswer } from '~/src/server/plugins/engine/components/factory.js' +import { getAnswer } from '~/src/server/plugins/engine/components/helpers/components.js' import { FileUploadField } from '~/src/server/plugins/engine/components/index.js' import { type checkFormStatus } from '~/src/server/plugins/engine/helpers.js' import { type FormModel } from '~/src/server/plugins/engine/models/index.js' diff --git a/src/server/plugins/engine/outputFormatters/machine/v2.test.ts b/src/server/plugins/engine/outputFormatters/machine/v2.test.ts index 1f785b471..cfd85ff89 100644 --- a/src/server/plugins/engine/outputFormatters/machine/v2.test.ts +++ b/src/server/plugins/engine/outputFormatters/machine/v2.test.ts @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/no-unsafe-member-access */ import { FileUploadField } from '~/src/server/plugins/engine/components/FileUploadField.js' -import { type Field } from '~/src/server/plugins/engine/components/factory.js' +import { type Field } from '~/src/server/plugins/engine/components/helpers/components.js' import { FormModel } from '~/src/server/plugins/engine/models/index.js' import { type DetailItem, diff --git a/src/server/plugins/engine/pageControllers/FileUploadPageController.test.ts b/src/server/plugins/engine/pageControllers/FileUploadPageController.test.ts index 9ce8f0fb0..b7249f584 100644 --- a/src/server/plugins/engine/pageControllers/FileUploadPageController.test.ts +++ b/src/server/plugins/engine/pageControllers/FileUploadPageController.test.ts @@ -15,7 +15,7 @@ import { } from '~/src/server/plugins/engine/pageControllers/FileUploadPageController.js' import { QuestionPageController } from '~/src/server/plugins/engine/pageControllers/QuestionPageController.js' import { serverWithSaveAndReturn } from '~/src/server/plugins/engine/pageControllers/__stubs__/server.js' -import * as pageHelpers from '~/src/server/plugins/engine/pageControllers/helpers.js' +import * as pageHelpers from '~/src/server/plugins/engine/pageControllers/helpers/index.js' import * as uploadService from '~/src/server/plugins/engine/services/uploadService.js' import { FileStatus, diff --git a/src/server/plugins/engine/pageControllers/FileUploadPageController.ts b/src/server/plugins/engine/pageControllers/FileUploadPageController.ts index ea3b37e8a..d361ccf14 100644 --- a/src/server/plugins/engine/pageControllers/FileUploadPageController.ts +++ b/src/server/plugins/engine/pageControllers/FileUploadPageController.ts @@ -15,7 +15,7 @@ import { } from '~/src/server/plugins/engine/helpers.js' import { type FormModel } from '~/src/server/plugins/engine/models/index.js' import { QuestionPageController } from '~/src/server/plugins/engine/pageControllers/QuestionPageController.js' -import { getProxyUrlForLocalDevelopment } from '~/src/server/plugins/engine/pageControllers/helpers.js' +import { getProxyUrlForLocalDevelopment } from '~/src/server/plugins/engine/pageControllers/helpers/index.js' import { getUploadStatus, initiateUpload diff --git a/src/server/plugins/engine/pageControllers/SummaryPageController.ts b/src/server/plugins/engine/pageControllers/SummaryPageController.ts index 4d5fcaa0f..23ad3ea00 100644 --- a/src/server/plugins/engine/pageControllers/SummaryPageController.ts +++ b/src/server/plugins/engine/pageControllers/SummaryPageController.ts @@ -9,7 +9,7 @@ import { type ResponseToolkit, type RouteOptions } from '@hapi/hapi' import { ComponentCollection } from '~/src/server/plugins/engine/components/ComponentCollection.js' import { FileUploadField } from '~/src/server/plugins/engine/components/FileUploadField.js' -import { getAnswer } from '~/src/server/plugins/engine/components/factory.js' +import { getAnswer } from '~/src/server/plugins/engine/components/helpers/components.js' import { checkEmailAddressForLiveFormSubmission, checkFormStatus, diff --git a/src/server/plugins/engine/pageControllers/helpers.test.ts b/src/server/plugins/engine/pageControllers/helpers/helpers.test.ts similarity index 98% rename from src/server/plugins/engine/pageControllers/helpers.test.ts rename to src/server/plugins/engine/pageControllers/helpers/helpers.test.ts index 60f824067..65d774708 100644 --- a/src/server/plugins/engine/pageControllers/helpers.test.ts +++ b/src/server/plugins/engine/pageControllers/helpers/helpers.test.ts @@ -8,12 +8,12 @@ import { import { FormModel } from '~/src/server/plugins/engine/models/FormModel.js' import { PageController } from '~/src/server/plugins/engine/pageControllers/PageController.js' +import { getProxyUrlForLocalDevelopment } from '~/src/server/plugins/engine/pageControllers/helpers/index.js' import { createPage, isPageController, type PageControllerType -} from '~/src/server/plugins/engine/pageControllers/factory.js' -import { getProxyUrlForLocalDevelopment } from '~/src/server/plugins/engine/pageControllers/helpers.js' +} from '~/src/server/plugins/engine/pageControllers/helpers/pages.js' import { FileUploadPageController, QuestionPageController, diff --git a/src/server/plugins/engine/pageControllers/helpers.ts b/src/server/plugins/engine/pageControllers/helpers/index.ts similarity index 100% rename from src/server/plugins/engine/pageControllers/helpers.ts rename to src/server/plugins/engine/pageControllers/helpers/index.ts diff --git a/src/server/plugins/engine/pageControllers/factory.ts b/src/server/plugins/engine/pageControllers/helpers/pages.ts similarity index 100% rename from src/server/plugins/engine/pageControllers/factory.ts rename to src/server/plugins/engine/pageControllers/helpers/pages.ts diff --git a/src/server/plugins/engine/routes/index.ts b/src/server/plugins/engine/routes/index.ts index 4f7fee184..dbefdd99d 100644 --- a/src/server/plugins/engine/routes/index.ts +++ b/src/server/plugins/engine/routes/index.ts @@ -17,7 +17,7 @@ import { proceed } from '~/src/server/plugins/engine/helpers.js' import { FormModel } from '~/src/server/plugins/engine/models/index.js' -import { type PageControllerClass } from '~/src/server/plugins/engine/pageControllers/factory.js' +import { type PageControllerClass } from '~/src/server/plugins/engine/pageControllers/helpers/pages.js' import { generateUniqueReference } from '~/src/server/plugins/engine/referenceNumbers.js' import * as defaultServices from '~/src/server/plugins/engine/services/index.js' import { diff --git a/src/server/plugins/engine/routes/questions.test.ts b/src/server/plugins/engine/routes/questions.test.ts index b065e9f8f..baf8d3f6f 100644 --- a/src/server/plugins/engine/routes/questions.test.ts +++ b/src/server/plugins/engine/routes/questions.test.ts @@ -4,7 +4,7 @@ import { type ResponseObject, type ResponseToolkit } from '@hapi/hapi' import nock from 'nock' import { type FormModel } from '~/src/server/plugins/engine/models/FormModel.js' -import { type PageControllerClass } from '~/src/server/plugins/engine/pageControllers/factory.js' +import { type PageControllerClass } from '~/src/server/plugins/engine/pageControllers/helpers/pages.js' import { redirectOrMakeHandler } from '~/src/server/plugins/engine/routes/index.js' import { makeGetHandler, diff --git a/src/server/plugins/engine/routes/questions.ts b/src/server/plugins/engine/routes/questions.ts index 57849c4f9..dc8d83dcd 100644 --- a/src/server/plugins/engine/routes/questions.ts +++ b/src/server/plugins/engine/routes/questions.ts @@ -19,7 +19,7 @@ import { } from '~/src/server/plugins/engine/models/index.js' import { format } from '~/src/server/plugins/engine/outputFormatters/machine/v1.js' import { getFormSubmissionData } from '~/src/server/plugins/engine/pageControllers/SummaryPageController.js' -import { type PageControllerClass } from '~/src/server/plugins/engine/pageControllers/factory.js' +import { type PageControllerClass } from '~/src/server/plugins/engine/pageControllers/helpers/pages.js' import { dispatchHandler, redirectOrMakeHandler diff --git a/src/server/plugins/engine/services/notifyService.test.ts b/src/server/plugins/engine/services/notifyService.test.ts index 720ce6d4d..e0a6d5285 100644 --- a/src/server/plugins/engine/services/notifyService.test.ts +++ b/src/server/plugins/engine/services/notifyService.test.ts @@ -1,6 +1,6 @@ import { type FormMetadata } from '@defra/forms-model' -import { escapeMarkdown } from '~/src/server/plugins/engine/components/helpers.js' +import { escapeMarkdown } from '~/src/server/plugins/engine/components/helpers/index.js' import { checkFormStatus } from '~/src/server/plugins/engine/helpers.js' import { type FormModel } from '~/src/server/plugins/engine/models/index.js' import { type DetailItem } from '~/src/server/plugins/engine/models/types.js' diff --git a/src/server/plugins/engine/services/notifyService.ts b/src/server/plugins/engine/services/notifyService.ts index 801c887b5..9774ce826 100644 --- a/src/server/plugins/engine/services/notifyService.ts +++ b/src/server/plugins/engine/services/notifyService.ts @@ -5,7 +5,7 @@ import { } from '@defra/forms-model' import { config } from '~/src/config/index.js' -import { escapeMarkdown } from '~/src/server/plugins/engine/components/helpers.js' +import { escapeMarkdown } from '~/src/server/plugins/engine/components/helpers/index.js' import { checkFormStatus } from '~/src/server/plugins/engine/helpers.js' import { type FormModel } from '~/src/server/plugins/engine/models/index.js' import { type DetailItem } from '~/src/server/plugins/engine/models/types.js' diff --git a/src/server/plugins/engine/types.ts b/src/server/plugins/engine/types.ts index a130d17cb..220d755f5 100644 --- a/src/server/plugins/engine/types.ts +++ b/src/server/plugins/engine/types.ts @@ -11,7 +11,7 @@ import { type PluginProperties, type Request } from '@hapi/hapi' import { type JoiExpression, type ValidationErrorItem } from 'joi' import { FormComponent } from '~/src/server/plugins/engine/components/FormComponent.js' -import { type Component } from '~/src/server/plugins/engine/components/factory.js' +import { type Component } from '~/src/server/plugins/engine/components/helpers/components.js' import { type BackLink, type ComponentText, @@ -20,7 +20,7 @@ import { import { type FormModel } from '~/src/server/plugins/engine/models/index.js' import { type RichFormValue } from '~/src/server/plugins/engine/outputFormatters/machine/v2.js' import { type PageController } from '~/src/server/plugins/engine/pageControllers/PageController.js' -import { type PageControllerClass } from '~/src/server/plugins/engine/pageControllers/factory.js' +import { type PageControllerClass } from '~/src/server/plugins/engine/pageControllers/helpers/pages.js' import { type ViewContext } from '~/src/server/plugins/nunjucks/types.js' import { type FormAction, @@ -403,7 +403,7 @@ export type FormAdapterSubmissionMessageMetaSerialised = Omit< FormAdapterSubmissionMessageMeta, 'schemaVersion' | 'timestamp' | 'status' > & { - schemaVersion: string + schemaVersion: number status: string timestamp: string } diff --git a/src/server/plugins/nunjucks/filters/answer.js b/src/server/plugins/nunjucks/filters/answer.js index caa5ca898..cb7b84f2f 100644 --- a/src/server/plugins/nunjucks/filters/answer.js +++ b/src/server/plugins/nunjucks/filters/answer.js @@ -1,4 +1,4 @@ -import { getAnswer } from '~/src/server/plugins/engine/components/factory.js' +import { getAnswer } from '~/src/server/plugins/engine/components/helpers/components.js' /** * Nunjucks filter to get the answer for a component @@ -23,5 +23,5 @@ export function answer(name) { /** * @import { NunjucksContext } from '~/src/server/plugins/nunjucks/types.js' - * @import { Field } from '~/src/server/plugins/engine/components/factory.js' + * @import { Field } from '~/src/server/plugins/engine/components/helpers/components.js' */ diff --git a/src/server/plugins/nunjucks/filters/answer.test.js b/src/server/plugins/nunjucks/filters/answer.test.js index a98e7e763..603e8024a 100644 --- a/src/server/plugins/nunjucks/filters/answer.test.js +++ b/src/server/plugins/nunjucks/filters/answer.test.js @@ -1,9 +1,12 @@ -import { getAnswer } from '~/src/server/plugins/engine/components/factory.js' +import { getAnswer } from '~/src/server/plugins/engine/components/helpers/components.js' import { answer } from '~/src/server/plugins/nunjucks/filters/answer.js' -jest.mock('~/src/server/plugins/engine/components/factory.ts', () => ({ - getAnswer: jest.fn() -})) +jest.mock( + '~/src/server/plugins/engine/components/helpers/components.ts', + () => ({ + getAnswer: jest.fn() + }) +) describe('answer Nunjucks filter', () => { /** @type { NunjucksContext } */ From fdf92a67f3ed9beb27c7f274078171a4aa284ee6 Mon Sep 17 00:00:00 2001 From: whitewater design Date: Thu, 28 Aug 2025 14:11:41 +0100 Subject: [PATCH 4/4] test: DF-380 - Move test --- .../plugins/engine/components/{ => helpers}/helpers.test.ts | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/server/plugins/engine/components/{ => helpers}/helpers.test.ts (100%) diff --git a/src/server/plugins/engine/components/helpers.test.ts b/src/server/plugins/engine/components/helpers/helpers.test.ts similarity index 100% rename from src/server/plugins/engine/components/helpers.test.ts rename to src/server/plugins/engine/components/helpers/helpers.test.ts