@defra/forms-engine-plugin 4.0.5 → 4.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.public/stylesheets/application.min.css +2 -2
- package/.public/stylesheets/application.min.css.map +1 -1
- package/.server/client/stylesheets/_location-input.scss +60 -0
- package/.server/client/stylesheets/application.scss +1 -6
- package/.server/client/stylesheets/shared.scss +8 -0
- package/.server/server/forms/register-as-a-unicorn-breeder.yaml +28 -0
- package/.server/server/plugins/engine/components/ComponentBase.d.ts +1 -1
- package/.server/server/plugins/engine/components/ComponentBase.js.map +1 -1
- package/.server/server/plugins/engine/components/EastingNorthingField.d.ts +121 -0
- package/.server/server/plugins/engine/components/EastingNorthingField.js +166 -0
- package/.server/server/plugins/engine/components/EastingNorthingField.js.map +1 -0
- package/.server/server/plugins/engine/components/LatLongField.d.ts +121 -0
- package/.server/server/plugins/engine/components/LatLongField.js +164 -0
- package/.server/server/plugins/engine/components/LatLongField.js.map +1 -0
- package/.server/server/plugins/engine/components/LocationFieldBase.d.ts +134 -0
- package/.server/server/plugins/engine/components/LocationFieldBase.js +85 -0
- package/.server/server/plugins/engine/components/LocationFieldBase.js.map +1 -0
- package/.server/server/plugins/engine/components/LocationFieldHelpers.d.ts +108 -0
- package/.server/server/plugins/engine/components/LocationFieldHelpers.js +96 -0
- package/.server/server/plugins/engine/components/LocationFieldHelpers.js.map +1 -0
- package/.server/server/plugins/engine/components/NationalGridFieldNumberField.d.ts +19 -0
- package/.server/server/plugins/engine/components/NationalGridFieldNumberField.js +40 -0
- package/.server/server/plugins/engine/components/NationalGridFieldNumberField.js.map +1 -0
- package/.server/server/plugins/engine/components/OsGridRefField.d.ts +19 -0
- package/.server/server/plugins/engine/components/OsGridRefField.js +56 -0
- package/.server/server/plugins/engine/components/OsGridRefField.js.map +1 -0
- package/.server/server/plugins/engine/components/helpers/components.d.ts +3 -4
- package/.server/server/plugins/engine/components/helpers/components.js +21 -29
- package/.server/server/plugins/engine/components/helpers/components.js.map +1 -1
- package/.server/server/plugins/engine/components/index.d.ts +4 -0
- package/.server/server/plugins/engine/components/index.js +4 -0
- package/.server/server/plugins/engine/components/index.js.map +1 -1
- package/.server/server/plugins/engine/components/markdownParser.d.ts +2 -0
- package/.server/server/plugins/engine/components/markdownParser.js +28 -0
- package/.server/server/plugins/engine/components/markdownParser.js.map +1 -0
- package/.server/server/plugins/engine/components/types.d.ts +10 -0
- package/.server/server/plugins/engine/components/types.js.map +1 -1
- package/.server/server/plugins/engine/pageControllers/helpers/pages.js +7 -0
- package/.server/server/plugins/engine/pageControllers/helpers/pages.js.map +1 -1
- package/.server/server/plugins/engine/types/index.d.ts +1 -1
- package/.server/server/plugins/engine/types/index.js.map +1 -1
- package/.server/server/plugins/engine/types.d.ts +2 -2
- package/.server/server/plugins/engine/types.js.map +1 -1
- package/.server/server/plugins/engine/views/components/_location-field-base.html +53 -0
- package/.server/server/plugins/engine/views/components/eastingnorthingfield.html +5 -0
- package/.server/server/plugins/engine/views/components/latlongfield.html +5 -0
- package/.server/server/plugins/engine/views/components/nationalgridfieldnumberfield.html +13 -0
- package/.server/server/plugins/engine/views/components/osgridreffield.html +13 -0
- package/.server/server/plugins/nunjucks/filters/field.d.ts +1 -1
- package/package.json +3 -3
- package/src/client/stylesheets/_location-input.scss +60 -0
- package/src/client/stylesheets/application.scss +1 -6
- package/src/client/stylesheets/shared.scss +8 -0
- package/src/server/forms/register-as-a-unicorn-breeder.yaml +28 -0
- package/src/server/plugins/engine/components/ComponentBase.ts +1 -1
- package/src/server/plugins/engine/components/EastingNorthingField.test.ts +665 -0
- package/src/server/plugins/engine/components/EastingNorthingField.ts +224 -0
- package/src/server/plugins/engine/components/LatLongField.test.ts +700 -0
- package/src/server/plugins/engine/components/LatLongField.ts +213 -0
- package/src/server/plugins/engine/components/LocationFieldBase.test.ts +253 -0
- package/src/server/plugins/engine/components/LocationFieldBase.ts +152 -0
- package/src/server/plugins/engine/components/LocationFieldHelpers.test.ts +338 -0
- package/src/server/plugins/engine/components/LocationFieldHelpers.ts +123 -0
- package/src/server/plugins/engine/components/NationalGridFieldNumberField.test.ts +438 -0
- package/src/server/plugins/engine/components/NationalGridFieldNumberField.ts +52 -0
- package/src/server/plugins/engine/components/OsGridRefField.test.ts +469 -0
- package/src/server/plugins/engine/components/OsGridRefField.ts +71 -0
- package/src/server/plugins/engine/components/helpers/components.test.ts +270 -0
- package/src/server/plugins/engine/components/helpers/components.ts +39 -47
- package/src/server/plugins/engine/components/helpers/helpers.test.ts +71 -1
- package/src/server/plugins/engine/components/index.ts +4 -0
- package/src/server/plugins/engine/components/markdownParser.ts +40 -0
- package/src/server/plugins/engine/components/types.ts +14 -0
- package/src/server/plugins/engine/outputFormatters/adapter/v1.location.test.ts +356 -0
- package/src/server/plugins/engine/pageControllers/helpers/helpers.test.ts +4 -0
- package/src/server/plugins/engine/pageControllers/helpers/pages.ts +8 -0
- package/src/server/plugins/engine/types/index.ts +2 -0
- package/src/server/plugins/engine/types.ts +4 -0
- package/src/server/plugins/engine/views/components/_location-field-base.html +53 -0
- package/src/server/plugins/engine/views/components/eastingnorthingfield.html +5 -0
- package/src/server/plugins/engine/views/components/latlongfield.html +5 -0
- package/src/server/plugins/engine/views/components/nationalgridfieldnumberfield.html +13 -0
- package/src/server/plugins/engine/views/components/osgridreffield.html +13 -0
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { LocationFieldBase } from "./LocationFieldBase.js";
|
|
2
|
+
export class NationalGridFieldNumberField extends LocationFieldBase {
|
|
3
|
+
getValidationConfig() {
|
|
4
|
+
return {
|
|
5
|
+
// Pattern allows spaces and commas in the input since custom validation will clean them
|
|
6
|
+
pattern: /^[A-Z]{2}[\d\s,]*$/i,
|
|
7
|
+
patternErrorMessage: `Enter a valid National Grid field number for ${this.title} like NG 1234 5678`,
|
|
8
|
+
customValidation: (value, helpers) => {
|
|
9
|
+
// Strip spaces and commas for validation
|
|
10
|
+
const cleanValue = value.replace(/[\s,]/g, '');
|
|
11
|
+
|
|
12
|
+
// Check if it matches the exact pattern after cleaning
|
|
13
|
+
if (!/^[A-Z]{2}\d{8}$/i.test(cleanValue)) {
|
|
14
|
+
return helpers.error('string.pattern.base');
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// Format with spaces per GDS guidance: NG 1234 5678
|
|
18
|
+
const letters = cleanValue.substring(0, 2);
|
|
19
|
+
const numbers = cleanValue.substring(2);
|
|
20
|
+
const formattedValue = `${letters} ${numbers.substring(0, 4)} ${numbers.substring(4)}`;
|
|
21
|
+
return formattedValue;
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
getErrorTemplates() {
|
|
26
|
+
return [{
|
|
27
|
+
type: 'pattern',
|
|
28
|
+
template: 'Enter a valid National Grid field number for [short description] like NG 1234 5678'
|
|
29
|
+
}];
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Static version of getAllPossibleErrors that doesn't require a component instance.
|
|
34
|
+
*/
|
|
35
|
+
static getAllPossibleErrors() {
|
|
36
|
+
const instance = Object.create(NationalGridFieldNumberField.prototype);
|
|
37
|
+
return instance.getAllPossibleErrors();
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=NationalGridFieldNumberField.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NationalGridFieldNumberField.js","names":["LocationFieldBase","NationalGridFieldNumberField","getValidationConfig","pattern","patternErrorMessage","title","customValidation","value","helpers","cleanValue","replace","test","error","letters","substring","numbers","formattedValue","getErrorTemplates","type","template","getAllPossibleErrors","instance","Object","create","prototype"],"sources":["../../../../../src/server/plugins/engine/components/NationalGridFieldNumberField.ts"],"sourcesContent":["import { type NationalGridFieldNumberFieldComponent } from '@defra/forms-model'\nimport type joi from 'joi'\n\nimport { LocationFieldBase } from '~/src/server/plugins/engine/components/LocationFieldBase.js'\n\nexport class NationalGridFieldNumberField extends LocationFieldBase {\n declare options: NationalGridFieldNumberFieldComponent['options']\n\n protected getValidationConfig() {\n return {\n // Pattern allows spaces and commas in the input since custom validation will clean them\n pattern: /^[A-Z]{2}[\\d\\s,]*$/i,\n patternErrorMessage: `Enter a valid National Grid field number for ${this.title} like NG 1234 5678`,\n customValidation: (value: string, helpers: joi.CustomHelpers) => {\n // Strip spaces and commas for validation\n const cleanValue = value.replace(/[\\s,]/g, '')\n\n // Check if it matches the exact pattern after cleaning\n if (!/^[A-Z]{2}\\d{8}$/i.test(cleanValue)) {\n return helpers.error('string.pattern.base')\n }\n\n // Format with spaces per GDS guidance: NG 1234 5678\n const letters = cleanValue.substring(0, 2)\n const numbers = cleanValue.substring(2)\n const formattedValue = `${letters} ${numbers.substring(0, 4)} ${numbers.substring(4)}`\n\n return formattedValue\n }\n }\n }\n\n protected getErrorTemplates() {\n return [\n {\n type: 'pattern',\n template:\n 'Enter a valid National Grid field number for [short description] like NG 1234 5678'\n }\n ]\n }\n\n /**\n * Static version of getAllPossibleErrors that doesn't require a component instance.\n */\n static getAllPossibleErrors() {\n const instance = Object.create(\n NationalGridFieldNumberField.prototype\n ) as NationalGridFieldNumberField\n return instance.getAllPossibleErrors()\n }\n}\n"],"mappings":"AAGA,SAASA,iBAAiB;AAE1B,OAAO,MAAMC,4BAA4B,SAASD,iBAAiB,CAAC;EAGxDE,mBAAmBA,CAAA,EAAG;IAC9B,OAAO;MACL;MACAC,OAAO,EAAE,qBAAqB;MAC9BC,mBAAmB,EAAE,gDAAgD,IAAI,CAACC,KAAK,oBAAoB;MACnGC,gBAAgB,EAAEA,CAACC,KAAa,EAAEC,OAA0B,KAAK;QAC/D;QACA,MAAMC,UAAU,GAAGF,KAAK,CAACG,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC;;QAE9C;QACA,IAAI,CAAC,kBAAkB,CAACC,IAAI,CAACF,UAAU,CAAC,EAAE;UACxC,OAAOD,OAAO,CAACI,KAAK,CAAC,qBAAqB,CAAC;QAC7C;;QAEA;QACA,MAAMC,OAAO,GAAGJ,UAAU,CAACK,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC;QAC1C,MAAMC,OAAO,GAAGN,UAAU,CAACK,SAAS,CAAC,CAAC,CAAC;QACvC,MAAME,cAAc,GAAG,GAAGH,OAAO,IAAIE,OAAO,CAACD,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,IAAIC,OAAO,CAACD,SAAS,CAAC,CAAC,CAAC,EAAE;QAEtF,OAAOE,cAAc;MACvB;IACF,CAAC;EACH;EAEUC,iBAAiBA,CAAA,EAAG;IAC5B,OAAO,CACL;MACEC,IAAI,EAAE,SAAS;MACfC,QAAQ,EACN;IACJ,CAAC,CACF;EACH;;EAEA;AACF;AACA;EACE,OAAOC,oBAAoBA,CAAA,EAAG;IAC5B,MAAMC,QAAQ,GAAGC,MAAM,CAACC,MAAM,CAC5BtB,4BAA4B,CAACuB,SAC/B,CAAiC;IACjC,OAAOH,QAAQ,CAACD,oBAAoB,CAAC,CAAC;EACxC;AACF","ignoreList":[]}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type OsGridRefFieldComponent } from '@defra/forms-model';
|
|
2
|
+
import type joi from 'joi';
|
|
3
|
+
import { LocationFieldBase } from '~/src/server/plugins/engine/components/LocationFieldBase.js';
|
|
4
|
+
export declare class OsGridRefField extends LocationFieldBase {
|
|
5
|
+
options: OsGridRefFieldComponent['options'];
|
|
6
|
+
protected getValidationConfig(): {
|
|
7
|
+
pattern: RegExp;
|
|
8
|
+
patternErrorMessage: string;
|
|
9
|
+
customValidation: (value: string, helpers: joi.CustomHelpers) => string | joi.ErrorReport;
|
|
10
|
+
};
|
|
11
|
+
protected getErrorTemplates(): {
|
|
12
|
+
type: string;
|
|
13
|
+
template: string;
|
|
14
|
+
}[];
|
|
15
|
+
/**
|
|
16
|
+
* Static version of getAllPossibleErrors that doesn't require a component instance.
|
|
17
|
+
*/
|
|
18
|
+
static getAllPossibleErrors(): import("../types.js").ErrorMessageTemplateList;
|
|
19
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { LocationFieldBase } from "./LocationFieldBase.js";
|
|
2
|
+
export class OsGridRefField extends LocationFieldBase {
|
|
3
|
+
getValidationConfig() {
|
|
4
|
+
// Regex for OS grid references and parcel IDs
|
|
5
|
+
// Validates specific valid OS grid letter combinations with:
|
|
6
|
+
// - 6 digits (e.g., SD865005 or SD 865 005)
|
|
7
|
+
// - 8 digits in 2 blocks of 4 (parcel ID) e.g., ST 6789 6789
|
|
8
|
+
// - 10 digits in 2 blocks of 5 (OS grid reference) e.g., SO 12345 12345
|
|
9
|
+
const osGridPattern = /^(?:[sn][a-hj-z]|[to][abfglmqrvw]|h[l-z]|j[lmqrvw])\s?(?:\d{3}\s?\d{3}|\d{4}\s?\d{4}|\d{5}\s?\d{5})$/i;
|
|
10
|
+
|
|
11
|
+
// More permissive pattern for initial validation (allows spaces to be cleaned)
|
|
12
|
+
const initialPattern = /^[A-Za-z]{2}[\d\s]*$/;
|
|
13
|
+
return {
|
|
14
|
+
pattern: initialPattern,
|
|
15
|
+
patternErrorMessage: `Enter a valid OS grid reference for ${this.title} like TQ123456`,
|
|
16
|
+
customValidation: (value, helpers) => {
|
|
17
|
+
// Strip spaces from the input for processing
|
|
18
|
+
const cleanValue = value.replace(/\s/g, '');
|
|
19
|
+
const letters = cleanValue.substring(0, 2);
|
|
20
|
+
const numbers = cleanValue.substring(2);
|
|
21
|
+
|
|
22
|
+
// Validate number length
|
|
23
|
+
if (numbers.length !== 6 && numbers.length !== 8 && numbers.length !== 10) {
|
|
24
|
+
return helpers.error('string.pattern.base');
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Format with spaces: XX 123 456, XX 1234 5678, or XX 12345 67890
|
|
28
|
+
const halfLength = numbers.length / 2;
|
|
29
|
+
const formattedValue = `${letters} ${numbers.substring(0, halfLength)} ${numbers.substring(halfLength)}`;
|
|
30
|
+
|
|
31
|
+
// Validate the formatted value against the OS grid pattern
|
|
32
|
+
if (!osGridPattern.test(formattedValue)) {
|
|
33
|
+
return helpers.error('string.pattern.base');
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Return formatted value with spaces per GDS guidance
|
|
37
|
+
return formattedValue;
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
getErrorTemplates() {
|
|
42
|
+
return [{
|
|
43
|
+
type: 'pattern',
|
|
44
|
+
template: 'Enter a valid OS grid reference for [short description] like TQ123456'
|
|
45
|
+
}];
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Static version of getAllPossibleErrors that doesn't require a component instance.
|
|
50
|
+
*/
|
|
51
|
+
static getAllPossibleErrors() {
|
|
52
|
+
const instance = Object.create(OsGridRefField.prototype);
|
|
53
|
+
return instance.getAllPossibleErrors();
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=OsGridRefField.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OsGridRefField.js","names":["LocationFieldBase","OsGridRefField","getValidationConfig","osGridPattern","initialPattern","pattern","patternErrorMessage","title","customValidation","value","helpers","cleanValue","replace","letters","substring","numbers","length","error","halfLength","formattedValue","test","getErrorTemplates","type","template","getAllPossibleErrors","instance","Object","create","prototype"],"sources":["../../../../../src/server/plugins/engine/components/OsGridRefField.ts"],"sourcesContent":["import { type OsGridRefFieldComponent } from '@defra/forms-model'\nimport type joi from 'joi'\n\nimport { LocationFieldBase } from '~/src/server/plugins/engine/components/LocationFieldBase.js'\n\nexport class OsGridRefField extends LocationFieldBase {\n declare options: OsGridRefFieldComponent['options']\n\n protected getValidationConfig() {\n // Regex for OS grid references and parcel IDs\n // Validates specific valid OS grid letter combinations with:\n // - 6 digits (e.g., SD865005 or SD 865 005)\n // - 8 digits in 2 blocks of 4 (parcel ID) e.g., ST 6789 6789\n // - 10 digits in 2 blocks of 5 (OS grid reference) e.g., SO 12345 12345\n const osGridPattern =\n /^(?:[sn][a-hj-z]|[to][abfglmqrvw]|h[l-z]|j[lmqrvw])\\s?(?:\\d{3}\\s?\\d{3}|\\d{4}\\s?\\d{4}|\\d{5}\\s?\\d{5})$/i\n\n // More permissive pattern for initial validation (allows spaces to be cleaned)\n const initialPattern = /^[A-Za-z]{2}[\\d\\s]*$/\n\n return {\n pattern: initialPattern,\n patternErrorMessage: `Enter a valid OS grid reference for ${this.title} like TQ123456`,\n customValidation: (value: string, helpers: joi.CustomHelpers) => {\n // Strip spaces from the input for processing\n const cleanValue = value.replace(/\\s/g, '')\n const letters = cleanValue.substring(0, 2)\n const numbers = cleanValue.substring(2)\n\n // Validate number length\n if (\n numbers.length !== 6 &&\n numbers.length !== 8 &&\n numbers.length !== 10\n ) {\n return helpers.error('string.pattern.base')\n }\n\n // Format with spaces: XX 123 456, XX 1234 5678, or XX 12345 67890\n const halfLength = numbers.length / 2\n const formattedValue = `${letters} ${numbers.substring(0, halfLength)} ${numbers.substring(halfLength)}`\n\n // Validate the formatted value against the OS grid pattern\n if (!osGridPattern.test(formattedValue)) {\n return helpers.error('string.pattern.base')\n }\n\n // Return formatted value with spaces per GDS guidance\n return formattedValue\n }\n }\n }\n\n protected getErrorTemplates() {\n return [\n {\n type: 'pattern',\n template:\n 'Enter a valid OS grid reference for [short description] like TQ123456'\n }\n ]\n }\n\n /**\n * Static version of getAllPossibleErrors that doesn't require a component instance.\n */\n static getAllPossibleErrors() {\n const instance = Object.create(OsGridRefField.prototype) as OsGridRefField\n return instance.getAllPossibleErrors()\n }\n}\n"],"mappings":"AAGA,SAASA,iBAAiB;AAE1B,OAAO,MAAMC,cAAc,SAASD,iBAAiB,CAAC;EAG1CE,mBAAmBA,CAAA,EAAG;IAC9B;IACA;IACA;IACA;IACA;IACA,MAAMC,aAAa,GACjB,uGAAuG;;IAEzG;IACA,MAAMC,cAAc,GAAG,sBAAsB;IAE7C,OAAO;MACLC,OAAO,EAAED,cAAc;MACvBE,mBAAmB,EAAE,uCAAuC,IAAI,CAACC,KAAK,gBAAgB;MACtFC,gBAAgB,EAAEA,CAACC,KAAa,EAAEC,OAA0B,KAAK;QAC/D;QACA,MAAMC,UAAU,GAAGF,KAAK,CAACG,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC;QAC3C,MAAMC,OAAO,GAAGF,UAAU,CAACG,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC;QAC1C,MAAMC,OAAO,GAAGJ,UAAU,CAACG,SAAS,CAAC,CAAC,CAAC;;QAEvC;QACA,IACEC,OAAO,CAACC,MAAM,KAAK,CAAC,IACpBD,OAAO,CAACC,MAAM,KAAK,CAAC,IACpBD,OAAO,CAACC,MAAM,KAAK,EAAE,EACrB;UACA,OAAON,OAAO,CAACO,KAAK,CAAC,qBAAqB,CAAC;QAC7C;;QAEA;QACA,MAAMC,UAAU,GAAGH,OAAO,CAACC,MAAM,GAAG,CAAC;QACrC,MAAMG,cAAc,GAAG,GAAGN,OAAO,IAAIE,OAAO,CAACD,SAAS,CAAC,CAAC,EAAEI,UAAU,CAAC,IAAIH,OAAO,CAACD,SAAS,CAACI,UAAU,CAAC,EAAE;;QAExG;QACA,IAAI,CAACf,aAAa,CAACiB,IAAI,CAACD,cAAc,CAAC,EAAE;UACvC,OAAOT,OAAO,CAACO,KAAK,CAAC,qBAAqB,CAAC;QAC7C;;QAEA;QACA,OAAOE,cAAc;MACvB;IACF,CAAC;EACH;EAEUE,iBAAiBA,CAAA,EAAG;IAC5B,OAAO,CACL;MACEC,IAAI,EAAE,SAAS;MACfC,QAAQ,EACN;IACJ,CAAC,CACF;EACH;;EAEA;AACF;AACA;EACE,OAAOC,oBAAoBA,CAAA,EAAG;IAC5B,MAAMC,QAAQ,GAAGC,MAAM,CAACC,MAAM,CAAC1B,cAAc,CAAC2B,SAAS,CAAmB;IAC1E,OAAOH,QAAQ,CAACD,oBAAoB,CAAC,CAAC;EACxC;AACF","ignoreList":[]}
|
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
import { ComponentType, type ComponentDef } from '@defra/forms-model';
|
|
2
|
-
import { Marked } from 'marked';
|
|
3
2
|
import { type ComponentBase } from '~/src/server/plugins/engine/components/ComponentBase.js';
|
|
4
3
|
import { ListFormComponent } from '~/src/server/plugins/engine/components/ListFormComponent.js';
|
|
5
4
|
import * as Components from '~/src/server/plugins/engine/components/index.js';
|
|
6
5
|
import { type FormState } from '~/src/server/plugins/engine/types.js';
|
|
7
6
|
export type Component = InstanceType<(typeof Components)[keyof typeof Components]>;
|
|
8
|
-
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>;
|
|
9
|
-
export type Guidance = InstanceType<typeof Components.Details | typeof Components.Html | typeof Components.Markdown | typeof Components.InsetText | typeof Components.List>;
|
|
7
|
+
export type Field = InstanceType<typeof Components.AutocompleteField | typeof Components.RadiosField | typeof Components.YesNoField | typeof Components.CheckboxesField | typeof Components.DatePartsField | typeof Components.EastingNorthingField | typeof Components.EmailAddressField | typeof Components.LatLongField | typeof Components.MonthYearField | typeof Components.MultilineTextField | typeof Components.NationalGridFieldNumberField | typeof Components.NumberField | typeof Components.OsGridRefField | typeof Components.SelectField | typeof Components.TelephoneNumberField | typeof Components.TextField | typeof Components.UkAddressField | typeof Components.FileUploadField>;
|
|
8
|
+
export type Guidance = InstanceType<typeof Components.Details> | InstanceType<typeof Components.Html> | InstanceType<typeof Components.Markdown> | InstanceType<typeof Components.InsetText> | InstanceType<typeof Components.List>;
|
|
10
9
|
export type ListField = InstanceType<typeof Components.AutocompleteField | typeof Components.CheckboxesField | typeof Components.RadiosField | typeof Components.SelectField | typeof Components.YesNoField>;
|
|
11
10
|
export declare const designerUrl: string;
|
|
12
|
-
export
|
|
11
|
+
export { markdown } from '~/src/server/plugins/engine/components/markdownParser.js';
|
|
13
12
|
/**
|
|
14
13
|
* Filter known components with lists
|
|
15
14
|
*/
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { ComponentType } from '@defra/forms-model';
|
|
2
|
-
import { Marked } from 'marked';
|
|
3
2
|
import { config } from "../../../../../config/index.js";
|
|
4
3
|
import { ListFormComponent } from "../ListFormComponent.js";
|
|
5
4
|
import { escapeMarkdown } from "./index.js";
|
|
6
5
|
import * as Components from "../index.js";
|
|
6
|
+
import { markdown } from "../markdownParser.js";
|
|
7
7
|
|
|
8
8
|
// All component instances
|
|
9
9
|
|
|
@@ -14,38 +14,15 @@ import * as Components from "../index.js";
|
|
|
14
14
|
// List component instances only
|
|
15
15
|
|
|
16
16
|
export const designerUrl = config.get('designerUrl');
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Render paragraphs without `<p>` wrappers
|
|
22
|
-
* for check answers summary list `<dd>`
|
|
23
|
-
*/
|
|
24
|
-
extensions: [{
|
|
25
|
-
name: 'paragraph',
|
|
26
|
-
renderer({
|
|
27
|
-
tokens = []
|
|
28
|
-
}) {
|
|
29
|
-
const text = this.parser.parseInline(tokens);
|
|
30
|
-
return tokens.length > 1 ? `${text}<br>` : text;
|
|
31
|
-
}
|
|
32
|
-
}],
|
|
33
|
-
/**
|
|
34
|
-
* Restrict allowed Markdown tokens
|
|
35
|
-
*/
|
|
36
|
-
walkTokens(token) {
|
|
37
|
-
const tokens = ['br', 'escape', 'list', 'list_item', 'paragraph', 'space', 'text'];
|
|
38
|
-
if (!tokens.includes(token.type)) {
|
|
39
|
-
token.type = 'text';
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
});
|
|
17
|
+
|
|
18
|
+
// Re-export markdown from its own module to avoid circular dependencies
|
|
19
|
+
export { markdown } from "../markdownParser.js";
|
|
43
20
|
|
|
44
21
|
/**
|
|
45
22
|
* Filter known components with lists
|
|
46
23
|
*/
|
|
47
24
|
export function hasListFormField(field) {
|
|
48
|
-
return !!field && isListFieldType(field.type);
|
|
25
|
+
return !!field && field.type !== undefined && isListFieldType(field.type);
|
|
49
26
|
}
|
|
50
27
|
export function isListFieldType(type) {
|
|
51
28
|
const allowedTypes = [ComponentType.AutocompleteField, ComponentType.CheckboxesField, ComponentType.RadiosField, ComponentType.SelectField, ComponentType.YesNoField];
|
|
@@ -115,6 +92,18 @@ export function createComponent(def, options) {
|
|
|
115
92
|
case ComponentType.FileUploadField:
|
|
116
93
|
component = new Components.FileUploadField(def, options);
|
|
117
94
|
break;
|
|
95
|
+
case ComponentType.EastingNorthingField:
|
|
96
|
+
component = new Components.EastingNorthingField(def, options);
|
|
97
|
+
break;
|
|
98
|
+
case ComponentType.OsGridRefField:
|
|
99
|
+
component = new Components.OsGridRefField(def, options);
|
|
100
|
+
break;
|
|
101
|
+
case ComponentType.NationalGridFieldNumberField:
|
|
102
|
+
component = new Components.NationalGridFieldNumberField(def, options);
|
|
103
|
+
break;
|
|
104
|
+
case ComponentType.LatLongField:
|
|
105
|
+
component = new Components.LatLongField(def, options);
|
|
106
|
+
break;
|
|
118
107
|
}
|
|
119
108
|
if (typeof component === 'undefined') {
|
|
120
109
|
throw new Error(`Component type ${def.type} does not exist`);
|
|
@@ -142,7 +131,7 @@ export function getAnswer(field, state, options = {
|
|
|
142
131
|
}
|
|
143
132
|
|
|
144
133
|
// Use display HTML for check answers summary (multi line)
|
|
145
|
-
if (field instanceof ListFormComponent || field instanceof Components.MultilineTextField || field instanceof Components.UkAddressField) {
|
|
134
|
+
if (field instanceof ListFormComponent || field instanceof Components.MultilineTextField || field instanceof Components.UkAddressField || field instanceof Components.EastingNorthingField || field instanceof Components.LatLongField) {
|
|
146
135
|
return markdown.parse(getAnswerMarkdown(field, state), {
|
|
147
136
|
async: false
|
|
148
137
|
}).trim();
|
|
@@ -214,6 +203,9 @@ export function getAnswerMarkdown(field, state, options = {
|
|
|
214
203
|
} else if (field instanceof Components.UkAddressField) {
|
|
215
204
|
// Format UK addresses into new lines
|
|
216
205
|
answerEscaped = (field.getContextValueFromState(state) ?? []).map(escapeMarkdown).join('\n').concat('\n');
|
|
206
|
+
} else if (field instanceof Components.EastingNorthingField || field instanceof Components.LatLongField) {
|
|
207
|
+
const contextValue = field.getContextValueFromState(state);
|
|
208
|
+
answerEscaped = contextValue ? `${contextValue}\n` : '';
|
|
217
209
|
}
|
|
218
210
|
return answerEscaped;
|
|
219
211
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"components.js","names":["ComponentType","Marked","config","ListFormComponent","escapeMarkdown","Components","designerUrl","get","markdown","breaks","gfm","extensions","name","renderer","tokens","text","parser","parseInline","length","walkTokens","token","includes","type","hasListFormField","field","isListFieldType","allowedTypes","AutocompleteField","CheckboxesField","RadiosField","SelectField","YesNoField","createComponent","def","options","component","DatePartsField","Details","EmailAddressField","Html","InsetText","List","Markdown","MultilineTextField","NumberField","TelephoneNumberField","TextField","UkAddressField","MonthYearField","FileUploadField","Error","getAnswer","state","format","getAnswerMarkdown","context","getContextValueFromState","toString","parse","async","trim","getDisplayStringFromState","answer","answerEscaped","files","getFormValueFromState","map","status","file","form","filename","fileId","join","values","flat","items","filter","value","item","label","line","toLowerCase","split","concat"],"sources":["../../../../../../src/server/plugins/engine/components/helpers/components.ts"],"sourcesContent":["import { ComponentType, type ComponentDef } from '@defra/forms-model'\nimport { Marked, type Token } from 'marked'\n\nimport { config } from '~/src/config/index.js'\nimport { type ComponentBase } from '~/src/server/plugins/engine/components/ComponentBase.js'\nimport { ListFormComponent } from '~/src/server/plugins/engine/components/ListFormComponent.js'\nimport { escapeMarkdown } from '~/src/server/plugins/engine/components/helpers/index.js'\nimport * as Components from '~/src/server/plugins/engine/components/index.js'\nimport { type FormState } from '~/src/server/plugins/engine/types.js'\n\n// All component instances\nexport type Component = InstanceType<\n (typeof Components)[keyof typeof Components]\n>\n\n// Field component instances only\nexport type Field = InstanceType<\n | typeof Components.AutocompleteField\n | typeof Components.RadiosField\n | typeof Components.YesNoField\n | typeof Components.CheckboxesField\n | typeof Components.DatePartsField\n | typeof Components.EmailAddressField\n | typeof Components.MonthYearField\n | typeof Components.MultilineTextField\n | typeof Components.NumberField\n | typeof Components.SelectField\n | typeof Components.TelephoneNumberField\n | typeof Components.TextField\n | typeof Components.UkAddressField\n | typeof Components.FileUploadField\n>\n\n// Guidance component instances only\nexport type Guidance = InstanceType<\n | typeof Components.Details\n | typeof Components.Html\n | typeof Components.Markdown\n | typeof Components.InsetText\n | typeof Components.List\n>\n\n// List component instances only\nexport type ListField = InstanceType<\n | typeof Components.AutocompleteField\n | typeof Components.CheckboxesField\n | typeof Components.RadiosField\n | typeof Components.SelectField\n | typeof Components.YesNoField\n>\n\nexport const designerUrl = config.get('designerUrl')\n\nexport const markdown = new Marked({\n breaks: true,\n gfm: true,\n\n /**\n * Render paragraphs without `<p>` wrappers\n * for check answers summary list `<dd>`\n */\n extensions: [\n {\n name: 'paragraph',\n renderer({ tokens = [] }) {\n const text = this.parser.parseInline(tokens)\n return tokens.length > 1 ? `${text}<br>` : text\n }\n }\n ],\n\n /**\n * Restrict allowed Markdown tokens\n */\n walkTokens(token) {\n const tokens: Token['type'][] = [\n 'br',\n 'escape',\n 'list',\n 'list_item',\n 'paragraph',\n 'space',\n 'text'\n ]\n\n if (!tokens.includes(token.type)) {\n token.type = 'text'\n }\n }\n})\n\n/**\n * Filter known components with lists\n */\nexport function hasListFormField(\n field?: Partial<Component>\n): field is ListFormComponent {\n return !!field && isListFieldType(field.type)\n}\n\nexport function isListFieldType(\n type?: ComponentType\n): type is ListField['type'] {\n const allowedTypes = [\n ComponentType.AutocompleteField,\n ComponentType.CheckboxesField,\n ComponentType.RadiosField,\n ComponentType.SelectField,\n ComponentType.YesNoField\n ]\n\n return !!type && allowedTypes.includes(type)\n}\n\n/**\n * Create field instance for each {@link ComponentDef} type\n */\nexport function createComponent(\n def: ComponentDef,\n options: ConstructorParameters<typeof ComponentBase>[1]\n): Component {\n let component: Component | undefined\n\n switch (def.type) {\n case ComponentType.AutocompleteField:\n component = new Components.AutocompleteField(def, options)\n break\n\n case ComponentType.CheckboxesField:\n component = new Components.CheckboxesField(def, options)\n break\n\n case ComponentType.DatePartsField:\n component = new Components.DatePartsField(def, options)\n break\n\n case ComponentType.Details:\n component = new Components.Details(def, options)\n break\n\n case ComponentType.EmailAddressField:\n component = new Components.EmailAddressField(def, options)\n break\n\n case ComponentType.Html:\n component = new Components.Html(def, options)\n break\n\n case ComponentType.InsetText:\n component = new Components.InsetText(def, options)\n break\n\n case ComponentType.List:\n component = new Components.List(def, options)\n break\n\n case ComponentType.Markdown:\n component = new Components.Markdown(def, options)\n break\n\n case ComponentType.MultilineTextField:\n component = new Components.MultilineTextField(def, options)\n break\n\n case ComponentType.NumberField:\n component = new Components.NumberField(def, options)\n break\n\n case ComponentType.RadiosField:\n component = new Components.RadiosField(def, options)\n break\n\n case ComponentType.SelectField:\n component = new Components.SelectField(def, options)\n break\n\n case ComponentType.TelephoneNumberField:\n component = new Components.TelephoneNumberField(def, options)\n break\n\n case ComponentType.TextField:\n component = new Components.TextField(def, options)\n break\n\n case ComponentType.UkAddressField:\n component = new Components.UkAddressField(def, options)\n break\n\n case ComponentType.YesNoField:\n component = new Components.YesNoField(def, options)\n break\n\n case ComponentType.MonthYearField:\n component = new Components.MonthYearField(def, options)\n break\n\n case ComponentType.FileUploadField:\n component = new Components.FileUploadField(def, options)\n break\n }\n\n if (typeof component === 'undefined') {\n throw new Error(`Component type ${def.type} does not exist`)\n }\n\n return component\n}\n\n/**\n * Get formatted answer for a field\n */\nexport function getAnswer(\n field: Field,\n state: FormState,\n options: {\n format:\n | 'data' // Submission data\n | 'email' // GOV.UK Notify emails\n | 'summary' // Check answers summary\n } = { format: 'summary' }\n) {\n // Use escaped display text for GOV.UK Notify emails\n if (options.format === 'email') {\n return getAnswerMarkdown(field, state, { format: 'email' })\n }\n\n // Use context value for submission data\n if (options.format === 'data') {\n const context = field.getContextValueFromState(state)\n return context?.toString() ?? ''\n }\n\n // Use display HTML for check answers summary (multi line)\n if (\n field instanceof ListFormComponent ||\n field instanceof Components.MultilineTextField ||\n field instanceof Components.UkAddressField\n ) {\n return markdown\n .parse(getAnswerMarkdown(field, state), { async: false })\n .trim()\n }\n\n // Use display text for check answers summary (single line)\n return field.getDisplayStringFromState(state)\n}\n\n/**\n * Get formatted answer for a field (Markdown only)\n */\nexport function getAnswerMarkdown(\n field: Field,\n state: FormState,\n options: {\n format:\n | 'email' // GOV.UK Notify emails\n | 'summary' // Check answers summary\n } = { format: 'summary' }\n) {\n const answer = field.getDisplayStringFromState(state)\n\n // Use escaped display text\n let answerEscaped = `${escapeMarkdown(answer)}\\n`\n\n if (field instanceof Components.FileUploadField) {\n const files = field.getFormValueFromState(state)\n\n // Skip empty files\n if (!files?.length) {\n return answerEscaped\n }\n\n answerEscaped = `${escapeMarkdown(answer)}:\\n\\n`\n\n // Append bullet points\n answerEscaped += files\n .map(({ status }) => {\n const { file } = status.form\n const filename = escapeMarkdown(file.filename)\n return `* [${filename}](${designerUrl}/file-download/${file.fileId})\\n`\n })\n .join('')\n } else if (field instanceof ListFormComponent) {\n const values = [field.getContextValueFromState(state)].flat()\n const items = field.items.filter(({ value }) => values.includes(value))\n\n // Skip empty values\n if (!items.length) {\n return answerEscaped\n }\n\n answerEscaped = ''\n\n // Append bullet points\n answerEscaped += items\n .map((item) => {\n const label = escapeMarkdown(item.text)\n const value = escapeMarkdown(`(${item.value})`)\n\n let line = label\n\n // Prepend bullet points for checkboxes only\n if (field instanceof Components.CheckboxesField) {\n line = `* ${line}`\n }\n\n // Append raw values in parentheses\n // e.g. `* None of the above (false)`\n return options.format === 'email' &&\n `${item.value}`.toLowerCase() !== item.text.toLowerCase()\n ? `${line} ${value}\\n`\n : `${line}\\n`\n })\n .join('')\n } else if (field instanceof Components.MultilineTextField) {\n // Preserve Multiline text new lines\n answerEscaped = answer\n .split(/(?:\\r?\\n)+/)\n .map(escapeMarkdown)\n .join('\\n')\n .concat('\\n')\n } else if (field instanceof Components.UkAddressField) {\n // Format UK addresses into new lines\n answerEscaped = (field.getContextValueFromState(state) ?? [])\n .map(escapeMarkdown)\n .join('\\n')\n .concat('\\n')\n }\n\n return answerEscaped\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"components.js","names":["ComponentType","config","ListFormComponent","escapeMarkdown","Components","markdown","designerUrl","get","hasListFormField","field","type","undefined","isListFieldType","allowedTypes","AutocompleteField","CheckboxesField","RadiosField","SelectField","YesNoField","includes","createComponent","def","options","component","DatePartsField","Details","EmailAddressField","Html","InsetText","List","Markdown","MultilineTextField","NumberField","TelephoneNumberField","TextField","UkAddressField","MonthYearField","FileUploadField","EastingNorthingField","OsGridRefField","NationalGridFieldNumberField","LatLongField","Error","getAnswer","state","format","getAnswerMarkdown","context","getContextValueFromState","toString","parse","async","trim","getDisplayStringFromState","answer","answerEscaped","files","getFormValueFromState","length","map","status","file","form","filename","fileId","join","values","flat","items","filter","value","item","label","text","line","toLowerCase","split","concat","contextValue"],"sources":["../../../../../../src/server/plugins/engine/components/helpers/components.ts"],"sourcesContent":["import { ComponentType, type ComponentDef } from '@defra/forms-model'\n\nimport { config } from '~/src/config/index.js'\nimport { type ComponentBase } from '~/src/server/plugins/engine/components/ComponentBase.js'\nimport { ListFormComponent } from '~/src/server/plugins/engine/components/ListFormComponent.js'\nimport { escapeMarkdown } from '~/src/server/plugins/engine/components/helpers/index.js'\nimport * as Components from '~/src/server/plugins/engine/components/index.js'\nimport { markdown } from '~/src/server/plugins/engine/components/markdownParser.js'\nimport { type FormState } from '~/src/server/plugins/engine/types.js'\n\n// All component instances\nexport type Component = InstanceType<\n (typeof Components)[keyof typeof Components]\n>\n\n// Field component instances only\nexport type Field = InstanceType<\n | typeof Components.AutocompleteField\n | typeof Components.RadiosField\n | typeof Components.YesNoField\n | typeof Components.CheckboxesField\n | typeof Components.DatePartsField\n | typeof Components.EastingNorthingField\n | typeof Components.EmailAddressField\n | typeof Components.LatLongField\n | typeof Components.MonthYearField\n | typeof Components.MultilineTextField\n | typeof Components.NationalGridFieldNumberField\n | typeof Components.NumberField\n | typeof Components.OsGridRefField\n | typeof Components.SelectField\n | typeof Components.TelephoneNumberField\n | typeof Components.TextField\n | typeof Components.UkAddressField\n | typeof Components.FileUploadField\n>\n\n// Guidance component instances only\nexport type Guidance =\n | InstanceType<typeof Components.Details>\n | InstanceType<typeof Components.Html>\n | InstanceType<typeof Components.Markdown>\n | InstanceType<typeof Components.InsetText>\n | InstanceType<typeof Components.List>\n\n// List component instances only\nexport type ListField = InstanceType<\n | typeof Components.AutocompleteField\n | typeof Components.CheckboxesField\n | typeof Components.RadiosField\n | typeof Components.SelectField\n | typeof Components.YesNoField\n>\n\nexport const designerUrl = config.get('designerUrl')\n\n// Re-export markdown from its own module to avoid circular dependencies\nexport { markdown } from '~/src/server/plugins/engine/components/markdownParser.js'\n\n/**\n * Filter known components with lists\n */\nexport function hasListFormField(\n field?: Partial<Component>\n): field is ListFormComponent {\n return !!field && field.type !== undefined && isListFieldType(field.type)\n}\n\nexport function isListFieldType(\n type?: ComponentType\n): type is ListField['type'] {\n const allowedTypes = [\n ComponentType.AutocompleteField,\n ComponentType.CheckboxesField,\n ComponentType.RadiosField,\n ComponentType.SelectField,\n ComponentType.YesNoField\n ]\n\n return !!type && allowedTypes.includes(type)\n}\n\n/**\n * Create field instance for each {@link ComponentDef} type\n */\nexport function createComponent(\n def: ComponentDef,\n options: ConstructorParameters<typeof ComponentBase>[1]\n): Component {\n let component: Component | undefined\n\n switch (def.type) {\n case ComponentType.AutocompleteField:\n component = new Components.AutocompleteField(def, options)\n break\n\n case ComponentType.CheckboxesField:\n component = new Components.CheckboxesField(def, options)\n break\n\n case ComponentType.DatePartsField:\n component = new Components.DatePartsField(def, options)\n break\n\n case ComponentType.Details:\n component = new Components.Details(def, options)\n break\n\n case ComponentType.EmailAddressField:\n component = new Components.EmailAddressField(def, options)\n break\n\n case ComponentType.Html:\n component = new Components.Html(def, options)\n break\n\n case ComponentType.InsetText:\n component = new Components.InsetText(def, options)\n break\n\n case ComponentType.List:\n component = new Components.List(def, options)\n break\n\n case ComponentType.Markdown:\n component = new Components.Markdown(def, options)\n break\n\n case ComponentType.MultilineTextField:\n component = new Components.MultilineTextField(def, options)\n break\n\n case ComponentType.NumberField:\n component = new Components.NumberField(def, options)\n break\n\n case ComponentType.RadiosField:\n component = new Components.RadiosField(def, options)\n break\n\n case ComponentType.SelectField:\n component = new Components.SelectField(def, options)\n break\n\n case ComponentType.TelephoneNumberField:\n component = new Components.TelephoneNumberField(def, options)\n break\n\n case ComponentType.TextField:\n component = new Components.TextField(def, options)\n break\n\n case ComponentType.UkAddressField:\n component = new Components.UkAddressField(def, options)\n break\n\n case ComponentType.YesNoField:\n component = new Components.YesNoField(def, options)\n break\n\n case ComponentType.MonthYearField:\n component = new Components.MonthYearField(def, options)\n break\n\n case ComponentType.FileUploadField:\n component = new Components.FileUploadField(def, options)\n break\n\n case ComponentType.EastingNorthingField:\n component = new Components.EastingNorthingField(def, options)\n break\n\n case ComponentType.OsGridRefField:\n component = new Components.OsGridRefField(def, options)\n break\n\n case ComponentType.NationalGridFieldNumberField:\n component = new Components.NationalGridFieldNumberField(def, options)\n break\n\n case ComponentType.LatLongField:\n component = new Components.LatLongField(def, options)\n break\n }\n\n if (typeof component === 'undefined') {\n throw new Error(`Component type ${def.type} does not exist`)\n }\n\n return component\n}\n\n/**\n * Get formatted answer for a field\n */\nexport function getAnswer(\n field: Field,\n state: FormState,\n options: {\n format:\n | 'data' // Submission data\n | 'email' // GOV.UK Notify emails\n | 'summary' // Check answers summary\n } = { format: 'summary' }\n) {\n // Use escaped display text for GOV.UK Notify emails\n if (options.format === 'email') {\n return getAnswerMarkdown(field, state, { format: 'email' })\n }\n\n // Use context value for submission data\n if (options.format === 'data') {\n const context = field.getContextValueFromState(state)\n return context?.toString() ?? ''\n }\n\n // Use display HTML for check answers summary (multi line)\n if (\n field instanceof ListFormComponent ||\n field instanceof Components.MultilineTextField ||\n field instanceof Components.UkAddressField ||\n field instanceof Components.EastingNorthingField ||\n field instanceof Components.LatLongField\n ) {\n return markdown\n .parse(getAnswerMarkdown(field, state), { async: false })\n .trim()\n }\n\n // Use display text for check answers summary (single line)\n return field.getDisplayStringFromState(state)\n}\n\n/**\n * Get formatted answer for a field (Markdown only)\n */\nexport function getAnswerMarkdown(\n field: Field,\n state: FormState,\n options: {\n format:\n | 'email' // GOV.UK Notify emails\n | 'summary' // Check answers summary\n } = { format: 'summary' }\n) {\n const answer = field.getDisplayStringFromState(state)\n\n // Use escaped display text\n let answerEscaped = `${escapeMarkdown(answer)}\\n`\n\n if (field instanceof Components.FileUploadField) {\n const files = field.getFormValueFromState(state)\n\n // Skip empty files\n if (!files?.length) {\n return answerEscaped\n }\n\n answerEscaped = `${escapeMarkdown(answer)}:\\n\\n`\n\n // Append bullet points\n answerEscaped += files\n .map(({ status }) => {\n const { file } = status.form\n const filename = escapeMarkdown(file.filename)\n return `* [${filename}](${designerUrl}/file-download/${file.fileId})\\n`\n })\n .join('')\n } else if (field instanceof ListFormComponent) {\n const values = [field.getContextValueFromState(state)].flat()\n const items = field.items.filter(({ value }) => values.includes(value))\n\n // Skip empty values\n if (!items.length) {\n return answerEscaped\n }\n\n answerEscaped = ''\n\n // Append bullet points\n answerEscaped += items\n .map((item) => {\n const label = escapeMarkdown(item.text)\n const value = escapeMarkdown(`(${item.value})`)\n\n let line = label\n\n // Prepend bullet points for checkboxes only\n if (field instanceof Components.CheckboxesField) {\n line = `* ${line}`\n }\n\n // Append raw values in parentheses\n // e.g. `* None of the above (false)`\n return options.format === 'email' &&\n `${item.value}`.toLowerCase() !== item.text.toLowerCase()\n ? `${line} ${value}\\n`\n : `${line}\\n`\n })\n .join('')\n } else if (field instanceof Components.MultilineTextField) {\n // Preserve Multiline text new lines\n answerEscaped = answer\n .split(/(?:\\r?\\n)+/)\n .map(escapeMarkdown)\n .join('\\n')\n .concat('\\n')\n } else if (field instanceof Components.UkAddressField) {\n // Format UK addresses into new lines\n answerEscaped = (field.getContextValueFromState(state) ?? [])\n .map(escapeMarkdown)\n .join('\\n')\n .concat('\\n')\n } else if (\n field instanceof Components.EastingNorthingField ||\n field instanceof Components.LatLongField\n ) {\n const contextValue = field.getContextValueFromState(state)\n answerEscaped = contextValue ? `${contextValue}\\n` : ''\n }\n\n return answerEscaped\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -22,3 +22,7 @@ export { TelephoneNumberField } from '~/src/server/plugins/engine/components/Tel
|
|
|
22
22
|
export { TextField } from '~/src/server/plugins/engine/components/TextField.js';
|
|
23
23
|
export { UkAddressField } from '~/src/server/plugins/engine/components/UkAddressField.js';
|
|
24
24
|
export { YesNoField } from '~/src/server/plugins/engine/components/YesNoField.js';
|
|
25
|
+
export { EastingNorthingField } from '~/src/server/plugins/engine/components/EastingNorthingField.js';
|
|
26
|
+
export { OsGridRefField } from '~/src/server/plugins/engine/components/OsGridRefField.js';
|
|
27
|
+
export { NationalGridFieldNumberField } from '~/src/server/plugins/engine/components/NationalGridFieldNumberField.js';
|
|
28
|
+
export { LatLongField } from '~/src/server/plugins/engine/components/LatLongField.js';
|
|
@@ -23,4 +23,8 @@ export { TelephoneNumberField } from "./TelephoneNumberField.js";
|
|
|
23
23
|
export { TextField } from "./TextField.js";
|
|
24
24
|
export { UkAddressField } from "./UkAddressField.js";
|
|
25
25
|
export { YesNoField } from "./YesNoField.js";
|
|
26
|
+
export { EastingNorthingField } from "./EastingNorthingField.js";
|
|
27
|
+
export { OsGridRefField } from "./OsGridRefField.js";
|
|
28
|
+
export { NationalGridFieldNumberField } from "./NationalGridFieldNumberField.js";
|
|
29
|
+
export { LatLongField } from "./LatLongField.js";
|
|
26
30
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["AutocompleteField","CheckboxesField","DatePartsField","Details","EmailAddressField","FileUploadField","Html","InsetText","List","Markdown","MonthYearField","MultilineTextField","NumberField","RadiosField","SelectField","TelephoneNumberField","TextField","UkAddressField","YesNoField"],"sources":["../../../../../src/server/plugins/engine/components/index.ts"],"sourcesContent":["/**\n * IMPORTANT: Exported Components must follow the naming convention implemented in {@link @defra/forms-model#ComponentType}\n * In the Form JSON, components have a type property which is the name of the components, e.g. DatePartsField.\n * Components are loaded in the ComponentsCollection constructor.\n */\n\nexport { AutocompleteField } from '~/src/server/plugins/engine/components/AutocompleteField.js'\nexport { CheckboxesField } from '~/src/server/plugins/engine/components/CheckboxesField.js'\nexport { DatePartsField } from '~/src/server/plugins/engine/components/DatePartsField.js'\nexport { Details } from '~/src/server/plugins/engine/components/Details.js'\nexport { EmailAddressField } from '~/src/server/plugins/engine/components/EmailAddressField.js'\nexport { FileUploadField } from '~/src/server/plugins/engine/components/FileUploadField.js'\nexport { Html } from '~/src/server/plugins/engine/components/Html.js'\nexport { InsetText } from '~/src/server/plugins/engine/components/InsetText.js'\nexport { List } from '~/src/server/plugins/engine/components/List.js'\nexport { Markdown } from '~/src/server/plugins/engine/components/Markdown.js'\nexport { MonthYearField } from '~/src/server/plugins/engine/components/MonthYearField.js'\nexport { MultilineTextField } from '~/src/server/plugins/engine/components/MultilineTextField.js'\nexport { NumberField } from '~/src/server/plugins/engine/components/NumberField.js'\nexport { RadiosField } from '~/src/server/plugins/engine/components/RadiosField.js'\nexport { SelectField } from '~/src/server/plugins/engine/components/SelectField.js'\nexport { TelephoneNumberField } from '~/src/server/plugins/engine/components/TelephoneNumberField.js'\nexport { TextField } from '~/src/server/plugins/engine/components/TextField.js'\nexport { UkAddressField } from '~/src/server/plugins/engine/components/UkAddressField.js'\nexport { YesNoField } from '~/src/server/plugins/engine/components/YesNoField.js'\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;;AAEA,SAASA,iBAAiB;AAC1B,SAASC,eAAe;AACxB,SAASC,cAAc;AACvB,SAASC,OAAO;AAChB,SAASC,iBAAiB;AAC1B,SAASC,eAAe;AACxB,SAASC,IAAI;AACb,SAASC,SAAS;AAClB,SAASC,IAAI;AACb,SAASC,QAAQ;AACjB,SAASC,cAAc;AACvB,SAASC,kBAAkB;AAC3B,SAASC,WAAW;AACpB,SAASC,WAAW;AACpB,SAASC,WAAW;AACpB,SAASC,oBAAoB;AAC7B,SAASC,SAAS;AAClB,SAASC,cAAc;AACvB,SAASC,UAAU","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"index.js","names":["AutocompleteField","CheckboxesField","DatePartsField","Details","EmailAddressField","FileUploadField","Html","InsetText","List","Markdown","MonthYearField","MultilineTextField","NumberField","RadiosField","SelectField","TelephoneNumberField","TextField","UkAddressField","YesNoField","EastingNorthingField","OsGridRefField","NationalGridFieldNumberField","LatLongField"],"sources":["../../../../../src/server/plugins/engine/components/index.ts"],"sourcesContent":["/**\n * IMPORTANT: Exported Components must follow the naming convention implemented in {@link @defra/forms-model#ComponentType}\n * In the Form JSON, components have a type property which is the name of the components, e.g. DatePartsField.\n * Components are loaded in the ComponentsCollection constructor.\n */\n\nexport { AutocompleteField } from '~/src/server/plugins/engine/components/AutocompleteField.js'\nexport { CheckboxesField } from '~/src/server/plugins/engine/components/CheckboxesField.js'\nexport { DatePartsField } from '~/src/server/plugins/engine/components/DatePartsField.js'\nexport { Details } from '~/src/server/plugins/engine/components/Details.js'\nexport { EmailAddressField } from '~/src/server/plugins/engine/components/EmailAddressField.js'\nexport { FileUploadField } from '~/src/server/plugins/engine/components/FileUploadField.js'\nexport { Html } from '~/src/server/plugins/engine/components/Html.js'\nexport { InsetText } from '~/src/server/plugins/engine/components/InsetText.js'\nexport { List } from '~/src/server/plugins/engine/components/List.js'\nexport { Markdown } from '~/src/server/plugins/engine/components/Markdown.js'\nexport { MonthYearField } from '~/src/server/plugins/engine/components/MonthYearField.js'\nexport { MultilineTextField } from '~/src/server/plugins/engine/components/MultilineTextField.js'\nexport { NumberField } from '~/src/server/plugins/engine/components/NumberField.js'\nexport { RadiosField } from '~/src/server/plugins/engine/components/RadiosField.js'\nexport { SelectField } from '~/src/server/plugins/engine/components/SelectField.js'\nexport { TelephoneNumberField } from '~/src/server/plugins/engine/components/TelephoneNumberField.js'\nexport { TextField } from '~/src/server/plugins/engine/components/TextField.js'\nexport { UkAddressField } from '~/src/server/plugins/engine/components/UkAddressField.js'\nexport { YesNoField } from '~/src/server/plugins/engine/components/YesNoField.js'\nexport { EastingNorthingField } from '~/src/server/plugins/engine/components/EastingNorthingField.js'\nexport { OsGridRefField } from '~/src/server/plugins/engine/components/OsGridRefField.js'\nexport { NationalGridFieldNumberField } from '~/src/server/plugins/engine/components/NationalGridFieldNumberField.js'\nexport { LatLongField } from '~/src/server/plugins/engine/components/LatLongField.js'\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;;AAEA,SAASA,iBAAiB;AAC1B,SAASC,eAAe;AACxB,SAASC,cAAc;AACvB,SAASC,OAAO;AAChB,SAASC,iBAAiB;AAC1B,SAASC,eAAe;AACxB,SAASC,IAAI;AACb,SAASC,SAAS;AAClB,SAASC,IAAI;AACb,SAASC,QAAQ;AACjB,SAASC,cAAc;AACvB,SAASC,kBAAkB;AAC3B,SAASC,WAAW;AACpB,SAASC,WAAW;AACpB,SAASC,WAAW;AACpB,SAASC,oBAAoB;AAC7B,SAASC,SAAS;AAClB,SAASC,cAAc;AACvB,SAASC,UAAU;AACnB,SAASC,oBAAoB;AAC7B,SAASC,cAAc;AACvB,SAASC,4BAA4B;AACrC,SAASC,YAAY","ignoreList":[]}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Marked } from 'marked';
|
|
2
|
+
export const markdown = new Marked({
|
|
3
|
+
breaks: true,
|
|
4
|
+
gfm: true,
|
|
5
|
+
/**
|
|
6
|
+
* Render paragraphs without `<p>` wrappers
|
|
7
|
+
* for check answers summary list `<dd>`
|
|
8
|
+
*/
|
|
9
|
+
extensions: [{
|
|
10
|
+
name: 'paragraph',
|
|
11
|
+
renderer({
|
|
12
|
+
tokens = []
|
|
13
|
+
}) {
|
|
14
|
+
const text = this.parser.parseInline(tokens);
|
|
15
|
+
return tokens.length > 1 ? `${text}<br>` : text;
|
|
16
|
+
}
|
|
17
|
+
}],
|
|
18
|
+
/**
|
|
19
|
+
* Restrict allowed Markdown tokens
|
|
20
|
+
*/
|
|
21
|
+
walkTokens(token) {
|
|
22
|
+
const tokens = ['br', 'escape', 'link', 'list', 'list_item', 'paragraph', 'space', 'text'];
|
|
23
|
+
if (!tokens.includes(token.type)) {
|
|
24
|
+
token.type = 'text';
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
//# sourceMappingURL=markdownParser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markdownParser.js","names":["Marked","markdown","breaks","gfm","extensions","name","renderer","tokens","text","parser","parseInline","length","walkTokens","token","includes","type"],"sources":["../../../../../src/server/plugins/engine/components/markdownParser.ts"],"sourcesContent":["import { Marked, type Token } from 'marked'\n\nexport const markdown = new Marked({\n breaks: true,\n gfm: true,\n\n /**\n * Render paragraphs without `<p>` wrappers\n * for check answers summary list `<dd>`\n */\n extensions: [\n {\n name: 'paragraph',\n renderer({ tokens = [] }) {\n const text = this.parser.parseInline(tokens)\n return tokens.length > 1 ? `${text}<br>` : text\n }\n }\n ],\n\n /**\n * Restrict allowed Markdown tokens\n */\n walkTokens(token) {\n const tokens: Token['type'][] = [\n 'br',\n 'escape',\n 'link',\n 'list',\n 'list_item',\n 'paragraph',\n 'space',\n 'text'\n ]\n\n if (!tokens.includes(token.type)) {\n token.type = 'text'\n }\n }\n})\n"],"mappings":"AAAA,SAASA,MAAM,QAAoB,QAAQ;AAE3C,OAAO,MAAMC,QAAQ,GAAG,IAAID,MAAM,CAAC;EACjCE,MAAM,EAAE,IAAI;EACZC,GAAG,EAAE,IAAI;EAET;AACF;AACA;AACA;EACEC,UAAU,EAAE,CACV;IACEC,IAAI,EAAE,WAAW;IACjBC,QAAQA,CAAC;MAAEC,MAAM,GAAG;IAAG,CAAC,EAAE;MACxB,MAAMC,IAAI,GAAG,IAAI,CAACC,MAAM,CAACC,WAAW,CAACH,MAAM,CAAC;MAC5C,OAAOA,MAAM,CAACI,MAAM,GAAG,CAAC,GAAG,GAAGH,IAAI,MAAM,GAAGA,IAAI;IACjD;EACF,CAAC,CACF;EAED;AACF;AACA;EACEI,UAAUA,CAACC,KAAK,EAAE;IAChB,MAAMN,MAAuB,GAAG,CAC9B,IAAI,EACJ,QAAQ,EACR,MAAM,EACN,MAAM,EACN,WAAW,EACX,WAAW,EACX,OAAO,EACP,MAAM,CACP;IAED,IAAI,CAACA,MAAM,CAACO,QAAQ,CAACD,KAAK,CAACE,IAAI,CAAC,EAAE;MAChCF,KAAK,CAACE,IAAI,GAAG,MAAM;IACrB;EACF;AACF,CAAC,CAAC","ignoreList":[]}
|
|
@@ -45,6 +45,8 @@ export interface DateInputItem {
|
|
|
45
45
|
name?: string;
|
|
46
46
|
value?: Item['value'];
|
|
47
47
|
classes?: string;
|
|
48
|
+
prefix?: ComponentText;
|
|
49
|
+
suffix?: ComponentText;
|
|
48
50
|
condition?: undefined;
|
|
49
51
|
}
|
|
50
52
|
export interface ViewModel extends Record<string, unknown> {
|
|
@@ -107,3 +109,11 @@ export interface MonthYearState extends Record<string, number> {
|
|
|
107
109
|
month: number;
|
|
108
110
|
year: number;
|
|
109
111
|
}
|
|
112
|
+
export interface EastingNorthingState extends Record<string, number> {
|
|
113
|
+
easting: number;
|
|
114
|
+
northing: number;
|
|
115
|
+
}
|
|
116
|
+
export interface LatLongState extends Record<string, number> {
|
|
117
|
+
latitude: number;
|
|
118
|
+
longitude: number;
|
|
119
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","names":[],"sources":["../../../../../src/server/plugins/engine/components/types.ts"],"sourcesContent":["import { type ComponentType, type Item } from '@defra/forms-model'\n\nimport {\n type FormSubmissionError,\n type FormValue,\n type SummaryList\n} from '~/src/server/plugins/engine/types.js'\n\nexport type ComponentText = {\n classes?: string\n attributes?: string | Record<string, string>\n} & (\n | {\n text: string\n html?: string\n }\n | {\n text?: string\n html: string\n }\n)\n\nexport interface Label {\n text: string\n classes?: string\n html?: string\n isPageHeading?: boolean\n}\n\nexport interface Content {\n title?: string\n text: string\n condition?: string\n}\n\nexport interface BackLink {\n text: string\n href: string\n}\n\nexport type ListItemLabel = Omit<Label, 'text' | 'isPageHeading'>\n\nexport interface ListItem {\n text?: string\n value?: Item['value']\n hint?: {\n id?: string\n text: string\n }\n checked?: boolean\n selected?: boolean\n label?: ListItemLabel\n condition?: string\n}\n\nexport interface DateInputItem {\n label?: Label\n type?: string\n id?: string\n name?: string\n value?: Item['value']\n classes?: string\n condition?: undefined\n}\n\nexport interface ViewModel extends Record<string, unknown> {\n label?: Label\n type?: string\n id?: string\n name?: string\n value?: FormValue\n hint?: {\n id?: string\n text: string\n }\n prefix?: ComponentText\n suffix?: ComponentText\n classes?: string\n condition?: string\n errors?: FormSubmissionError[]\n errorMessage?: {\n text: string\n }\n summaryHtml?: string\n html?: string\n attributes: {\n autocomplete?: string\n maxlength?: number\n multiple?: string\n accept?: string\n inputmode?: string\n }\n content?: Content | Content[] | string\n maxlength?: number\n maxwords?: number\n rows?: number\n items?: ListItem[] | DateInputItem[]\n fieldset?: {\n attributes?: string | Record<string, string>\n legend?: Label\n }\n formGroup?: {\n classes?: string\n attributes?: string | Record<string, string>\n }\n components?: ComponentViewModel[]\n upload?: {\n count: number\n summaryList: SummaryList\n }\n}\n\nexport interface ComponentViewModel {\n type: ComponentType\n isFormComponent: boolean\n model: ViewModel\n}\n\nexport interface DatePartsState extends Record<string, number> {\n day: number\n month: number\n year: number\n}\n\nexport interface MonthYearState extends Record<string, number> {\n month: number\n year: number\n}\n"],"mappings":"","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"types.js","names":[],"sources":["../../../../../src/server/plugins/engine/components/types.ts"],"sourcesContent":["import { type ComponentType, type Item } from '@defra/forms-model'\n\nimport {\n type FormSubmissionError,\n type FormValue,\n type SummaryList\n} from '~/src/server/plugins/engine/types.js'\n\nexport type ComponentText = {\n classes?: string\n attributes?: string | Record<string, string>\n} & (\n | {\n text: string\n html?: string\n }\n | {\n text?: string\n html: string\n }\n)\n\nexport interface Label {\n text: string\n classes?: string\n html?: string\n isPageHeading?: boolean\n}\n\nexport interface Content {\n title?: string\n text: string\n condition?: string\n}\n\nexport interface BackLink {\n text: string\n href: string\n}\n\nexport type ListItemLabel = Omit<Label, 'text' | 'isPageHeading'>\n\nexport interface ListItem {\n text?: string\n value?: Item['value']\n hint?: {\n id?: string\n text: string\n }\n checked?: boolean\n selected?: boolean\n label?: ListItemLabel\n condition?: string\n}\n\nexport interface DateInputItem {\n label?: Label\n type?: string\n id?: string\n name?: string\n value?: Item['value']\n classes?: string\n // Prefix/suffix are used by location fields (e.g., LatLong, EastingNorthing) for units like \"°\"\n // but not by date fields. This interface is reused by both component types.\n prefix?: ComponentText\n suffix?: ComponentText\n condition?: undefined\n}\n\nexport interface ViewModel extends Record<string, unknown> {\n label?: Label\n type?: string\n id?: string\n name?: string\n value?: FormValue\n hint?: {\n id?: string\n text: string\n }\n prefix?: ComponentText\n suffix?: ComponentText\n classes?: string\n condition?: string\n errors?: FormSubmissionError[]\n errorMessage?: {\n text: string\n }\n summaryHtml?: string\n html?: string\n attributes: {\n autocomplete?: string\n maxlength?: number\n multiple?: string\n accept?: string\n inputmode?: string\n }\n content?: Content | Content[] | string\n maxlength?: number\n maxwords?: number\n rows?: number\n items?: ListItem[] | DateInputItem[]\n fieldset?: {\n attributes?: string | Record<string, string>\n legend?: Label\n }\n formGroup?: {\n classes?: string\n attributes?: string | Record<string, string>\n }\n components?: ComponentViewModel[]\n upload?: {\n count: number\n summaryList: SummaryList\n }\n}\n\nexport interface ComponentViewModel {\n type: ComponentType\n isFormComponent: boolean\n model: ViewModel\n}\n\nexport interface DatePartsState extends Record<string, number> {\n day: number\n month: number\n year: number\n}\n\nexport interface MonthYearState extends Record<string, number> {\n month: number\n year: number\n}\n\nexport interface EastingNorthingState extends Record<string, number> {\n easting: number\n northing: number\n}\n\nexport interface LatLongState extends Record<string, number> {\n latitude: number\n longitude: number\n}\n"],"mappings":"","ignoreList":[]}
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { ControllerType, controllerNameFromPath, isControllerName } from '@defra/forms-model';
|
|
2
2
|
import * as PageControllers from "../index.js";
|
|
3
3
|
export function isPageController(controllerName) {
|
|
4
|
+
// Handle SummaryWithConfirmationEmail as it uses SummaryPageController
|
|
5
|
+
if (controllerName === ControllerType.SummaryWithConfirmationEmail) {
|
|
6
|
+
return true;
|
|
7
|
+
}
|
|
4
8
|
return isControllerName(controllerName) && controllerName in PageControllers;
|
|
5
9
|
}
|
|
6
10
|
/**
|
|
@@ -30,6 +34,9 @@ export function createPage(model, pageDef) {
|
|
|
30
34
|
case ControllerType.Summary:
|
|
31
35
|
controller = new PageControllers.SummaryPageController(model, pageDef);
|
|
32
36
|
break;
|
|
37
|
+
case ControllerType.SummaryWithConfirmationEmail:
|
|
38
|
+
controller = new PageControllers.SummaryPageController(model, pageDef);
|
|
39
|
+
break;
|
|
33
40
|
case ControllerType.Status:
|
|
34
41
|
controller = new PageControllers.StatusPageController(model, pageDef);
|
|
35
42
|
break;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pages.js","names":["ControllerType","controllerNameFromPath","isControllerName","PageControllers","isPageController","controllerName","createPage","model","pageDef","controller","QuestionPageController","Start","StartPageController","Page","Terminal","TerminalPageController","Summary","SummaryPageController","Status","StatusPageController","FileUpload","FileUploadPageController","Repeat","RepeatPageController","controllers","Ctrl","Error"],"sources":["../../../../../../src/server/plugins/engine/pageControllers/helpers/pages.ts"],"sourcesContent":["import {\n ControllerType,\n controllerNameFromPath,\n isControllerName,\n type Page\n} from '@defra/forms-model'\n\nimport { type FormModel } from '~/src/server/plugins/engine/models/index.js'\nimport * as PageControllers from '~/src/server/plugins/engine/pageControllers/index.js'\n\nexport function isPageController(\n controllerName?: string | ControllerType\n): controllerName is keyof typeof PageControllers {\n return isControllerName(controllerName) && controllerName in PageControllers\n}\n\nexport type PageControllerClass = InstanceType<PageControllerType>\nexport type PageControllerType =\n (typeof PageControllers)[keyof typeof PageControllers]\n\n/**\n * Creates page instance for each {@link Page} type\n */\nexport function createPage(model: FormModel, pageDef: Page) {\n const controllerName = controllerNameFromPath(pageDef.controller)\n\n if (!pageDef.controller) {\n return new PageControllers.QuestionPageController(model, pageDef)\n }\n\n // Patch legacy controllers\n if (controllerName && pageDef.controller !== controllerName) {\n pageDef.controller = controllerName\n }\n\n let controller: PageControllerClass | undefined\n\n switch (pageDef.controller) {\n case ControllerType.Start:\n controller = new PageControllers.StartPageController(model, pageDef)\n break\n\n case ControllerType.Page:\n controller = new PageControllers.QuestionPageController(model, pageDef)\n break\n\n case ControllerType.Terminal:\n controller = new PageControllers.TerminalPageController(model, pageDef)\n break\n\n case ControllerType.Summary:\n controller = new PageControllers.SummaryPageController(model, pageDef)\n break\n\n case ControllerType.Status:\n controller = new PageControllers.StatusPageController(model, pageDef)\n break\n\n case ControllerType.FileUpload:\n controller = new PageControllers.FileUploadPageController(model, pageDef)\n break\n\n case ControllerType.Repeat:\n controller = new PageControllers.RepeatPageController(model, pageDef)\n break\n }\n\n if (typeof controller === 'undefined') {\n if (model.controllers?.[pageDef.controller]) {\n const Ctrl = model.controllers[pageDef.controller]\n controller = new Ctrl(model, pageDef) as unknown as PageControllerClass // type assertion needed because TS can't verify custom controller structure\n }\n }\n\n if (typeof controller === 'undefined') {\n throw new Error(`Page controller ${pageDef.controller} does not exist`)\n }\n\n return controller\n}\n"],"mappings":"AAAA,SACEA,cAAc,EACdC,sBAAsB,EACtBC,gBAAgB,QAEX,oBAAoB;AAG3B,OAAO,KAAKC,eAAe;AAE3B,OAAO,SAASC,gBAAgBA,CAC9BC,cAAwC,EACQ;EAChD,
|
|
1
|
+
{"version":3,"file":"pages.js","names":["ControllerType","controllerNameFromPath","isControllerName","PageControllers","isPageController","controllerName","SummaryWithConfirmationEmail","createPage","model","pageDef","controller","QuestionPageController","Start","StartPageController","Page","Terminal","TerminalPageController","Summary","SummaryPageController","Status","StatusPageController","FileUpload","FileUploadPageController","Repeat","RepeatPageController","controllers","Ctrl","Error"],"sources":["../../../../../../src/server/plugins/engine/pageControllers/helpers/pages.ts"],"sourcesContent":["import {\n ControllerType,\n controllerNameFromPath,\n isControllerName,\n type Page\n} from '@defra/forms-model'\n\nimport { type FormModel } from '~/src/server/plugins/engine/models/index.js'\nimport * as PageControllers from '~/src/server/plugins/engine/pageControllers/index.js'\n\nexport function isPageController(\n controllerName?: string | ControllerType\n): controllerName is keyof typeof PageControllers {\n // Handle SummaryWithConfirmationEmail as it uses SummaryPageController\n if (controllerName === ControllerType.SummaryWithConfirmationEmail) {\n return true\n }\n return isControllerName(controllerName) && controllerName in PageControllers\n}\n\nexport type PageControllerClass = InstanceType<PageControllerType>\nexport type PageControllerType =\n (typeof PageControllers)[keyof typeof PageControllers]\n\n/**\n * Creates page instance for each {@link Page} type\n */\nexport function createPage(model: FormModel, pageDef: Page) {\n const controllerName = controllerNameFromPath(pageDef.controller)\n\n if (!pageDef.controller) {\n return new PageControllers.QuestionPageController(model, pageDef)\n }\n\n // Patch legacy controllers\n if (controllerName && pageDef.controller !== controllerName) {\n pageDef.controller = controllerName\n }\n\n let controller: PageControllerClass | undefined\n\n switch (pageDef.controller) {\n case ControllerType.Start:\n controller = new PageControllers.StartPageController(model, pageDef)\n break\n\n case ControllerType.Page:\n controller = new PageControllers.QuestionPageController(model, pageDef)\n break\n\n case ControllerType.Terminal:\n controller = new PageControllers.TerminalPageController(model, pageDef)\n break\n\n case ControllerType.Summary:\n controller = new PageControllers.SummaryPageController(model, pageDef)\n break\n\n case ControllerType.SummaryWithConfirmationEmail:\n controller = new PageControllers.SummaryPageController(model, pageDef)\n break\n\n case ControllerType.Status:\n controller = new PageControllers.StatusPageController(model, pageDef)\n break\n\n case ControllerType.FileUpload:\n controller = new PageControllers.FileUploadPageController(model, pageDef)\n break\n\n case ControllerType.Repeat:\n controller = new PageControllers.RepeatPageController(model, pageDef)\n break\n }\n\n if (typeof controller === 'undefined') {\n if (model.controllers?.[pageDef.controller]) {\n const Ctrl = model.controllers[pageDef.controller]\n controller = new Ctrl(model, pageDef) as unknown as PageControllerClass // type assertion needed because TS can't verify custom controller structure\n }\n }\n\n if (typeof controller === 'undefined') {\n throw new Error(`Page controller ${pageDef.controller} does not exist`)\n }\n\n return controller\n}\n"],"mappings":"AAAA,SACEA,cAAc,EACdC,sBAAsB,EACtBC,gBAAgB,QAEX,oBAAoB;AAG3B,OAAO,KAAKC,eAAe;AAE3B,OAAO,SAASC,gBAAgBA,CAC9BC,cAAwC,EACQ;EAChD;EACA,IAAIA,cAAc,KAAKL,cAAc,CAACM,4BAA4B,EAAE;IAClE,OAAO,IAAI;EACb;EACA,OAAOJ,gBAAgB,CAACG,cAAc,CAAC,IAAIA,cAAc,IAAIF,eAAe;AAC9E;AAMA;AACA;AACA;AACA,OAAO,SAASI,UAAUA,CAACC,KAAgB,EAAEC,OAAa,EAAE;EAC1D,MAAMJ,cAAc,GAAGJ,sBAAsB,CAACQ,OAAO,CAACC,UAAU,CAAC;EAEjE,IAAI,CAACD,OAAO,CAACC,UAAU,EAAE;IACvB,OAAO,IAAIP,eAAe,CAACQ,sBAAsB,CAACH,KAAK,EAAEC,OAAO,CAAC;EACnE;;EAEA;EACA,IAAIJ,cAAc,IAAII,OAAO,CAACC,UAAU,KAAKL,cAAc,EAAE;IAC3DI,OAAO,CAACC,UAAU,GAAGL,cAAc;EACrC;EAEA,IAAIK,UAA2C;EAE/C,QAAQD,OAAO,CAACC,UAAU;IACxB,KAAKV,cAAc,CAACY,KAAK;MACvBF,UAAU,GAAG,IAAIP,eAAe,CAACU,mBAAmB,CAACL,KAAK,EAAEC,OAAO,CAAC;MACpE;IAEF,KAAKT,cAAc,CAACc,IAAI;MACtBJ,UAAU,GAAG,IAAIP,eAAe,CAACQ,sBAAsB,CAACH,KAAK,EAAEC,OAAO,CAAC;MACvE;IAEF,KAAKT,cAAc,CAACe,QAAQ;MAC1BL,UAAU,GAAG,IAAIP,eAAe,CAACa,sBAAsB,CAACR,KAAK,EAAEC,OAAO,CAAC;MACvE;IAEF,KAAKT,cAAc,CAACiB,OAAO;MACzBP,UAAU,GAAG,IAAIP,eAAe,CAACe,qBAAqB,CAACV,KAAK,EAAEC,OAAO,CAAC;MACtE;IAEF,KAAKT,cAAc,CAACM,4BAA4B;MAC9CI,UAAU,GAAG,IAAIP,eAAe,CAACe,qBAAqB,CAACV,KAAK,EAAEC,OAAO,CAAC;MACtE;IAEF,KAAKT,cAAc,CAACmB,MAAM;MACxBT,UAAU,GAAG,IAAIP,eAAe,CAACiB,oBAAoB,CAACZ,KAAK,EAAEC,OAAO,CAAC;MACrE;IAEF,KAAKT,cAAc,CAACqB,UAAU;MAC5BX,UAAU,GAAG,IAAIP,eAAe,CAACmB,wBAAwB,CAACd,KAAK,EAAEC,OAAO,CAAC;MACzE;IAEF,KAAKT,cAAc,CAACuB,MAAM;MACxBb,UAAU,GAAG,IAAIP,eAAe,CAACqB,oBAAoB,CAAChB,KAAK,EAAEC,OAAO,CAAC;MACrE;EACJ;EAEA,IAAI,OAAOC,UAAU,KAAK,WAAW,EAAE;IACrC,IAAIF,KAAK,CAACiB,WAAW,GAAGhB,OAAO,CAACC,UAAU,CAAC,EAAE;MAC3C,MAAMgB,IAAI,GAAGlB,KAAK,CAACiB,WAAW,CAAChB,OAAO,CAACC,UAAU,CAAC;MAClDA,UAAU,GAAG,IAAIgB,IAAI,CAAClB,KAAK,EAAEC,OAAO,CAAmC,EAAC;IAC1E;EACF;EAEA,IAAI,OAAOC,UAAU,KAAK,WAAW,EAAE;IACrC,MAAM,IAAIiB,KAAK,CAAC,mBAAmBlB,OAAO,CAACC,UAAU,iBAAiB,CAAC;EACzE;EAEA,OAAOA,UAAU;AACnB","ignoreList":[]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export type { AnyFormRequest, AnyRequest, CheckAnswers, ErrorMessageTemplate, ErrorMessageTemplateList, FeaturedFormPageViewModel, FileState, FilterFunction, FormAdapterSubmissionMessage, FormAdapterSubmissionMessageData, FormAdapterSubmissionMessageMeta, FormAdapterSubmissionMessageMetaSerialised, FormAdapterSubmissionMessagePayload, FormAdapterSubmissionService, FormContext, FormContextRequest, FormPageViewModel, FormPayload, FormPayloadParams, FormState, FormStateValue, FormSubmissionError, FormSubmissionState, FormValidationResult, FormValue, GlobalFunction, ItemDeletePageViewModel, OnRequestCallback, PageViewModel, PageViewModelBase, PluginOptions, PreparePageEventRequestOptions, RepeatItemState, RepeatListState, RepeaterSummaryPageViewModel, SummaryList, SummaryListAction, SummaryListRow, TempFileState, UploadInitiateResponse, UploadStatusFileResponse, UploadStatusResponse } from '~/src/server/plugins/engine/types.js';
|
|
2
2
|
export { FileStatus, UploadStatus } from '~/src/server/plugins/engine/types.js';
|
|
3
3
|
export type { Detail, DetailItem, DetailItemBase, DetailItemField, DetailItemRepeat, ExecutableCondition } from '~/src/server/plugins/engine/models/types.js';
|
|
4
|
-
export type { BackLink, ComponentText, ComponentViewModel, Content, DateInputItem, DatePartsState, Label, ListItem, ListItemLabel, MonthYearState, ViewModel } from '~/src/server/plugins/engine/components/types.js';
|
|
4
|
+
export type { BackLink, ComponentText, ComponentViewModel, Content, DateInputItem, DatePartsState, EastingNorthingState, Label, LatLongState, ListItem, ListItemLabel, MonthYearState, ViewModel } from '~/src/server/plugins/engine/components/types.js';
|
|
5
5
|
export type { UkAddressState } from '~/src/server/plugins/engine/components/UkAddressField.js';
|
|
6
6
|
export type { FormParams, FormQuery, FormRequest, FormRequestPayload, FormRequestPayloadRefs, FormRequestRefs, FormResponseToolkit } from '~/src/server/routes/types.js';
|
|
7
7
|
export { FormAction, FormStatus } from '~/src/server/routes/types.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["FileStatus","UploadStatus","FormAction","FormStatus","FormAdapterSubmissionSchemaVersion"],"sources":["../../../../../src/server/plugins/engine/types/index.ts"],"sourcesContent":["export type {\n AnyFormRequest,\n AnyRequest,\n CheckAnswers,\n ErrorMessageTemplate,\n ErrorMessageTemplateList,\n FeaturedFormPageViewModel,\n FileState,\n FilterFunction,\n FormAdapterSubmissionMessage,\n FormAdapterSubmissionMessageData,\n FormAdapterSubmissionMessageMeta,\n FormAdapterSubmissionMessageMetaSerialised,\n FormAdapterSubmissionMessagePayload,\n FormAdapterSubmissionService,\n FormContext,\n FormContextRequest,\n FormPageViewModel,\n FormPayload,\n FormPayloadParams,\n FormState,\n FormStateValue,\n FormSubmissionError,\n FormSubmissionState,\n FormValidationResult,\n FormValue,\n GlobalFunction,\n ItemDeletePageViewModel,\n OnRequestCallback,\n PageViewModel,\n PageViewModelBase,\n PluginOptions,\n PreparePageEventRequestOptions,\n RepeatItemState,\n RepeatListState,\n RepeaterSummaryPageViewModel,\n SummaryList,\n SummaryListAction,\n SummaryListRow,\n TempFileState,\n UploadInitiateResponse,\n UploadStatusFileResponse,\n UploadStatusResponse\n} from '~/src/server/plugins/engine/types.js'\n\nexport { FileStatus, UploadStatus } from '~/src/server/plugins/engine/types.js'\n\nexport type {\n Detail,\n DetailItem,\n DetailItemBase,\n DetailItemField,\n DetailItemRepeat,\n ExecutableCondition\n} from '~/src/server/plugins/engine/models/types.js'\n\nexport type {\n BackLink,\n ComponentText,\n ComponentViewModel,\n Content,\n DateInputItem,\n DatePartsState,\n Label,\n ListItem,\n ListItemLabel,\n MonthYearState,\n ViewModel\n} from '~/src/server/plugins/engine/components/types.js'\n\nexport type { UkAddressState } from '~/src/server/plugins/engine/components/UkAddressField.js'\n\nexport type {\n FormParams,\n FormQuery,\n FormRequest,\n FormRequestPayload,\n FormRequestPayloadRefs,\n FormRequestRefs,\n FormResponseToolkit\n} from '~/src/server/routes/types.js'\n\nexport { FormAction, FormStatus } from '~/src/server/routes/types.js'\n\nexport type {\n FormSubmissionService,\n FormsService,\n OutputService,\n RouteConfig,\n Services\n} from '~/src/server/types.js'\n\nexport * from '~/src/server/plugins/engine/types/schema.js'\nexport { FormAdapterSubmissionSchemaVersion } from '~/src/server/plugins/engine/types/enums.js'\n"],"mappings":"AA6CA,SAASA,UAAU,EAAEC,YAAY;
|
|
1
|
+
{"version":3,"file":"index.js","names":["FileStatus","UploadStatus","FormAction","FormStatus","FormAdapterSubmissionSchemaVersion"],"sources":["../../../../../src/server/plugins/engine/types/index.ts"],"sourcesContent":["export type {\n AnyFormRequest,\n AnyRequest,\n CheckAnswers,\n ErrorMessageTemplate,\n ErrorMessageTemplateList,\n FeaturedFormPageViewModel,\n FileState,\n FilterFunction,\n FormAdapterSubmissionMessage,\n FormAdapterSubmissionMessageData,\n FormAdapterSubmissionMessageMeta,\n FormAdapterSubmissionMessageMetaSerialised,\n FormAdapterSubmissionMessagePayload,\n FormAdapterSubmissionService,\n FormContext,\n FormContextRequest,\n FormPageViewModel,\n FormPayload,\n FormPayloadParams,\n FormState,\n FormStateValue,\n FormSubmissionError,\n FormSubmissionState,\n FormValidationResult,\n FormValue,\n GlobalFunction,\n ItemDeletePageViewModel,\n OnRequestCallback,\n PageViewModel,\n PageViewModelBase,\n PluginOptions,\n PreparePageEventRequestOptions,\n RepeatItemState,\n RepeatListState,\n RepeaterSummaryPageViewModel,\n SummaryList,\n SummaryListAction,\n SummaryListRow,\n TempFileState,\n UploadInitiateResponse,\n UploadStatusFileResponse,\n UploadStatusResponse\n} from '~/src/server/plugins/engine/types.js'\n\nexport { FileStatus, UploadStatus } from '~/src/server/plugins/engine/types.js'\n\nexport type {\n Detail,\n DetailItem,\n DetailItemBase,\n DetailItemField,\n DetailItemRepeat,\n ExecutableCondition\n} from '~/src/server/plugins/engine/models/types.js'\n\nexport type {\n BackLink,\n ComponentText,\n ComponentViewModel,\n Content,\n DateInputItem,\n DatePartsState,\n EastingNorthingState,\n Label,\n LatLongState,\n ListItem,\n ListItemLabel,\n MonthYearState,\n ViewModel\n} from '~/src/server/plugins/engine/components/types.js'\n\nexport type { UkAddressState } from '~/src/server/plugins/engine/components/UkAddressField.js'\n\nexport type {\n FormParams,\n FormQuery,\n FormRequest,\n FormRequestPayload,\n FormRequestPayloadRefs,\n FormRequestRefs,\n FormResponseToolkit\n} from '~/src/server/routes/types.js'\n\nexport { FormAction, FormStatus } from '~/src/server/routes/types.js'\n\nexport type {\n FormSubmissionService,\n FormsService,\n OutputService,\n RouteConfig,\n Services\n} from '~/src/server/types.js'\n\nexport * from '~/src/server/plugins/engine/types/schema.js'\nexport { FormAdapterSubmissionSchemaVersion } from '~/src/server/plugins/engine/types/enums.js'\n"],"mappings":"AA6CA,SAASA,UAAU,EAAEC,YAAY;AAuCjC,SAASC,UAAU,EAAEC,UAAU;AAU/B;AACA,SAASC,kCAAkC","ignoreList":[]}
|
|
@@ -4,7 +4,7 @@ import { type JoiExpression, type ValidationErrorItem } from 'joi';
|
|
|
4
4
|
import { type UkAddressState } from '~/src/server/plugins/engine/components/UkAddressField.js';
|
|
5
5
|
import { type Component } from '~/src/server/plugins/engine/components/helpers/components.js';
|
|
6
6
|
import { type FileUploadField } from '~/src/server/plugins/engine/components/index.js';
|
|
7
|
-
import { type BackLink, type ComponentText, type ComponentViewModel, type DatePartsState, type MonthYearState } from '~/src/server/plugins/engine/components/types.js';
|
|
7
|
+
import { type BackLink, type ComponentText, type ComponentViewModel, type DatePartsState, type EastingNorthingState, type LatLongState, type MonthYearState } from '~/src/server/plugins/engine/components/types.js';
|
|
8
8
|
import { type FormModel } from '~/src/server/plugins/engine/models/index.js';
|
|
9
9
|
import { type DetailItemField } from '~/src/server/plugins/engine/models/types.js';
|
|
10
10
|
import { type PageController } from '~/src/server/plugins/engine/pageControllers/PageController.js';
|
|
@@ -334,7 +334,7 @@ export interface FormAdapterSubmissionMessageResult {
|
|
|
334
334
|
export type FileUploadFieldDetailitem = Omit<DetailItemField, 'field'> & {
|
|
335
335
|
field: FileUploadField;
|
|
336
336
|
};
|
|
337
|
-
export type RichFormValue = FormValue | FormPayload | DatePartsState | MonthYearState | UkAddressState;
|
|
337
|
+
export type RichFormValue = FormValue | FormPayload | DatePartsState | MonthYearState | UkAddressState | EastingNorthingState | LatLongState;
|
|
338
338
|
export interface FormAdapterSubmissionMessageData {
|
|
339
339
|
main: Record<string, RichFormValue | null>;
|
|
340
340
|
repeaters: Record<string, Record<string, RichFormValue>[]>;
|