@defra/forms-engine-plugin 4.14.4 → 4.16.0
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/assets-manifest.json +10 -1
- package/.public/javascripts/im-search-plugin.min.js +2 -0
- package/.public/javascripts/im-search-plugin.min.js.map +1 -0
- package/.public/javascripts/shared.min.js +1 -1
- package/.public/javascripts/shared.min.js.map +1 -1
- package/.public/javascripts/vendor/@defra.min.js +2 -0
- package/.public/javascripts/vendor/@defra.min.js.map +1 -0
- package/.public/javascripts/vendor/maplibre-gl.min.js +3 -0
- package/.public/javascripts/vendor/maplibre-gl.min.js.LICENSE.txt +4 -0
- package/.public/javascripts/vendor/maplibre-gl.min.js.map +1 -0
- package/.public/javascripts/vendor/preact.min.js +2 -0
- package/.public/javascripts/vendor/preact.min.js.map +1 -0
- package/.public/stylesheets/application.min.css +1 -1
- package/.public/stylesheets/application.min.css.map +1 -1
- package/.server/client/javascripts/geospatial-map.js +9 -4
- package/.server/client/javascripts/geospatial-map.js.map +1 -1
- package/.server/client/javascripts/map.js +18 -12
- package/.server/client/javascripts/map.js.map +1 -1
- package/.server/client/stylesheets/_prose.scss +19 -0
- package/.server/client/stylesheets/shared.scss +7 -0
- package/.server/server/forms/simple-form.yaml +19 -0
- package/.server/server/plugins/engine/components/NotificationBanner.d.ts +56 -0
- package/.server/server/plugins/engine/components/NotificationBanner.js +28 -0
- package/.server/server/plugins/engine/components/NotificationBanner.js.map +1 -0
- package/.server/server/plugins/engine/components/helpers/components.d.ts +1 -1
- package/.server/server/plugins/engine/components/helpers/components.js +3 -0
- package/.server/server/plugins/engine/components/helpers/components.js.map +1 -1
- package/.server/server/plugins/engine/components/index.d.ts +1 -0
- package/.server/server/plugins/engine/components/index.js +1 -0
- package/.server/server/plugins/engine/components/index.js.map +1 -1
- package/.server/server/plugins/engine/views/components/notificationbanner.html +15 -0
- package/.server/server/plugins/map/routes/index.d.ts +1 -2
- package/.server/server/plugins/map/routes/index.js +2 -32
- package/.server/server/plugins/map/routes/index.js.map +1 -1
- package/.server/server/plugins/map/service.d.ts +0 -7
- package/.server/server/plugins/map/service.js +0 -12
- package/.server/server/plugins/map/service.js.map +1 -1
- package/.server/server/plugins/map/service.test.js +0 -43
- package/.server/server/plugins/map/service.test.js.map +1 -1
- package/.server/server/plugins/nunjucks/filters/field.d.ts +1 -1
- package/package.json +2 -1
- package/src/client/javascripts/geospatial-map.js +9 -5
- package/src/client/javascripts/map.js +18 -13
- package/src/client/stylesheets/_prose.scss +19 -0
- package/src/client/stylesheets/shared.scss +7 -0
- package/src/server/forms/simple-form.yaml +19 -0
- package/src/server/plugins/engine/components/NotificationBanner.ts +32 -0
- package/src/server/plugins/engine/components/helpers/components.ts +5 -0
- package/src/server/plugins/engine/components/index.ts +1 -0
- package/src/server/plugins/engine/views/components/notificationbanner.html +15 -0
- package/src/server/plugins/map/routes/index.js +1 -37
- package/src/server/plugins/map/service.js +0 -13
- package/.server/server/plugins/map/test/__stubs__/nearest.d.ts +0 -37
- package/.server/server/plugins/map/test/__stubs__/nearest.js +0 -38
- package/.server/server/plugins/map/test/__stubs__/nearest.js.map +0 -1
- package/src/server/plugins/map/test/__stubs__/nearest.js +0 -46
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { type NotificationBannerComponent } from '@defra/forms-model';
|
|
2
|
+
import { ComponentBase } from '../../../../server/plugins/engine/components/ComponentBase.js';
|
|
3
|
+
export declare class NotificationBanner extends ComponentBase {
|
|
4
|
+
options: NotificationBannerComponent['options'];
|
|
5
|
+
content: NotificationBannerComponent['content'];
|
|
6
|
+
constructor(def: NotificationBannerComponent, props: ConstructorParameters<typeof ComponentBase>[1]);
|
|
7
|
+
getViewModel(): {
|
|
8
|
+
titleHtml: string;
|
|
9
|
+
content: string;
|
|
10
|
+
heading: string | undefined;
|
|
11
|
+
type: "success" | undefined;
|
|
12
|
+
label?: import("./types.js").Label;
|
|
13
|
+
id?: string;
|
|
14
|
+
name?: string;
|
|
15
|
+
value?: import("../types.js").FormValue;
|
|
16
|
+
hint?: {
|
|
17
|
+
id?: string;
|
|
18
|
+
text: string;
|
|
19
|
+
};
|
|
20
|
+
prefix?: import("./types.js").ComponentText;
|
|
21
|
+
suffix?: import("./types.js").ComponentText;
|
|
22
|
+
classes?: string;
|
|
23
|
+
condition?: string;
|
|
24
|
+
errors?: import("../types.js").FormSubmissionError[];
|
|
25
|
+
errorMessage?: {
|
|
26
|
+
text: string;
|
|
27
|
+
};
|
|
28
|
+
summaryHtml?: string;
|
|
29
|
+
html?: string;
|
|
30
|
+
attributes: {
|
|
31
|
+
autocomplete?: string;
|
|
32
|
+
maxlength?: number;
|
|
33
|
+
multiple?: string;
|
|
34
|
+
accept?: string;
|
|
35
|
+
inputmode?: string;
|
|
36
|
+
};
|
|
37
|
+
maxlength?: number;
|
|
38
|
+
maxwords?: number;
|
|
39
|
+
rows?: number;
|
|
40
|
+
items?: import("./types.js").ListItem[] | import("./types.js").DateInputItem[];
|
|
41
|
+
fieldset?: {
|
|
42
|
+
attributes?: string | Record<string, string>;
|
|
43
|
+
legend?: import("./types.js").Label;
|
|
44
|
+
};
|
|
45
|
+
formGroup?: {
|
|
46
|
+
classes?: string;
|
|
47
|
+
attributes?: string | Record<string, string>;
|
|
48
|
+
};
|
|
49
|
+
showFieldsetError?: boolean;
|
|
50
|
+
components?: import("./types.js").ComponentViewModel[];
|
|
51
|
+
upload?: {
|
|
52
|
+
count: number;
|
|
53
|
+
summaryList: import("../types.js").SummaryList;
|
|
54
|
+
};
|
|
55
|
+
};
|
|
56
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { ComponentBase } from "./ComponentBase.js";
|
|
2
|
+
export class NotificationBanner extends ComponentBase {
|
|
3
|
+
content;
|
|
4
|
+
constructor(def, props) {
|
|
5
|
+
super(def, props);
|
|
6
|
+
const {
|
|
7
|
+
content,
|
|
8
|
+
options
|
|
9
|
+
} = def;
|
|
10
|
+
this.content = content;
|
|
11
|
+
this.options = options;
|
|
12
|
+
}
|
|
13
|
+
getViewModel() {
|
|
14
|
+
const {
|
|
15
|
+
content,
|
|
16
|
+
title,
|
|
17
|
+
viewModel
|
|
18
|
+
} = this;
|
|
19
|
+
return {
|
|
20
|
+
...viewModel,
|
|
21
|
+
titleHtml: title,
|
|
22
|
+
content,
|
|
23
|
+
heading: this.options.heading,
|
|
24
|
+
type: this.options.type
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=NotificationBanner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NotificationBanner.js","names":["ComponentBase","NotificationBanner","content","constructor","def","props","options","getViewModel","title","viewModel","titleHtml","heading","type"],"sources":["../../../../../src/server/plugins/engine/components/NotificationBanner.ts"],"sourcesContent":["import { type NotificationBannerComponent } from '@defra/forms-model'\n\nimport { ComponentBase } from '~/src/server/plugins/engine/components/ComponentBase.js'\n\nexport class NotificationBanner extends ComponentBase {\n declare options: NotificationBannerComponent['options']\n content: NotificationBannerComponent['content']\n\n constructor(\n def: NotificationBannerComponent,\n props: ConstructorParameters<typeof ComponentBase>[1]\n ) {\n super(def, props)\n\n const { content, options } = def\n\n this.content = content\n this.options = options\n }\n\n getViewModel() {\n const { content, title, viewModel } = this\n\n return {\n ...viewModel,\n titleHtml: title,\n content,\n heading: this.options.heading,\n type: this.options.type\n }\n }\n}\n"],"mappings":"AAEA,SAASA,aAAa;AAEtB,OAAO,MAAMC,kBAAkB,SAASD,aAAa,CAAC;EAEpDE,OAAO;EAEPC,WAAWA,CACTC,GAAgC,EAChCC,KAAqD,EACrD;IACA,KAAK,CAACD,GAAG,EAAEC,KAAK,CAAC;IAEjB,MAAM;MAAEH,OAAO;MAAEI;IAAQ,CAAC,GAAGF,GAAG;IAEhC,IAAI,CAACF,OAAO,GAAGA,OAAO;IACtB,IAAI,CAACI,OAAO,GAAGA,OAAO;EACxB;EAEAC,YAAYA,CAAA,EAAG;IACb,MAAM;MAAEL,OAAO;MAAEM,KAAK;MAAEC;IAAU,CAAC,GAAG,IAAI;IAE1C,OAAO;MACL,GAAGA,SAAS;MACZC,SAAS,EAAEF,KAAK;MAChBN,OAAO;MACPS,OAAO,EAAE,IAAI,CAACL,OAAO,CAACK,OAAO;MAC7BC,IAAI,EAAE,IAAI,CAACN,OAAO,CAACM;IACrB,CAAC;EACH;AACF","ignoreList":[]}
|
|
@@ -5,7 +5,7 @@ import * as Components from '../../../../../server/plugins/engine/components/ind
|
|
|
5
5
|
import { type FormState } from '../../../../../server/plugins/engine/types.js';
|
|
6
6
|
export type Component = InstanceType<(typeof Components)[keyof typeof Components]>;
|
|
7
7
|
export type Field = InstanceType<typeof Components.AutocompleteField | typeof Components.RadiosField | typeof Components.YesNoField | typeof Components.CheckboxesField | typeof Components.DatePartsField | typeof Components.DeclarationField | 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 | typeof Components.HiddenField | typeof Components.PaymentField | typeof Components.GeospatialField>;
|
|
8
|
-
export type Guidance = InstanceType<typeof Components.Details> | InstanceType<typeof Components.Html> | InstanceType<typeof Components.Markdown> | InstanceType<typeof Components.InsetText> | InstanceType<typeof Components.List>;
|
|
8
|
+
export type Guidance = InstanceType<typeof Components.Details> | InstanceType<typeof Components.Html> | InstanceType<typeof Components.Markdown> | InstanceType<typeof Components.InsetText> | InstanceType<typeof Components.List> | InstanceType<typeof Components.NotificationBanner>;
|
|
9
9
|
export type ListField = InstanceType<typeof Components.AutocompleteField | typeof Components.CheckboxesField | typeof Components.RadiosField | typeof Components.SelectField | typeof Components.YesNoField>;
|
|
10
10
|
export declare const designerUrl: string;
|
|
11
11
|
export { markdown } from '../../../../../server/plugins/engine/components/markdownParser.js';
|
|
@@ -65,6 +65,9 @@ export function createComponent(def, options) {
|
|
|
65
65
|
case ComponentType.Markdown:
|
|
66
66
|
component = new Components.Markdown(def, options);
|
|
67
67
|
break;
|
|
68
|
+
case ComponentType.NotificationBanner:
|
|
69
|
+
component = new Components.NotificationBanner(def, options);
|
|
70
|
+
break;
|
|
68
71
|
case ComponentType.MultilineTextField:
|
|
69
72
|
component = new Components.MultilineTextField(def, options);
|
|
70
73
|
break;
|
|
@@ -1 +1 @@
|
|
|
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","DeclarationField","Details","EmailAddressField","Html","InsetText","List","Markdown","MultilineTextField","NumberField","TelephoneNumberField","TextField","UkAddressField","MonthYearField","FileUploadField","EastingNorthingField","OsGridRefField","NationalGridFieldNumberField","LatLongField","HiddenField","PaymentField","GeospatialField","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","features","getDisplayStringFromFormValue"],"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.DeclarationField\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 | typeof Components.HiddenField\n | typeof Components.PaymentField\n | typeof Components.GeospatialField\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.DeclarationField:\n component = new Components.DeclarationField(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 case ComponentType.HiddenField:\n component = new Components.HiddenField(def, options)\n break\n\n case ComponentType.PaymentField:\n component = new Components.PaymentField(def, options)\n break\n\n case ComponentType.GeospatialField:\n component = new Components.GeospatialField(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 } else if (field instanceof Components.GeospatialField) {\n const features = field.getFormValueFromState(state)\n const value = field.getDisplayStringFromFormValue(features)\n\n answerEscaped = value ? `${value}\\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","DeclarationField","Details","EmailAddressField","Html","InsetText","List","Markdown","NotificationBanner","MultilineTextField","NumberField","TelephoneNumberField","TextField","UkAddressField","MonthYearField","FileUploadField","EastingNorthingField","OsGridRefField","NationalGridFieldNumberField","LatLongField","HiddenField","PaymentField","GeospatialField","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","features","getDisplayStringFromFormValue"],"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.DeclarationField\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 | typeof Components.HiddenField\n | typeof Components.PaymentField\n | typeof Components.GeospatialField\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 | InstanceType<typeof Components.NotificationBanner>\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.DeclarationField:\n component = new Components.DeclarationField(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.NotificationBanner:\n component = new Components.NotificationBanner(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 case ComponentType.HiddenField:\n component = new Components.HiddenField(def, options)\n break\n\n case ComponentType.PaymentField:\n component = new Components.PaymentField(def, options)\n break\n\n case ComponentType.GeospatialField:\n component = new Components.GeospatialField(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 } else if (field instanceof Components.GeospatialField) {\n const features = field.getFormValueFromState(state)\n const value = field.getDisplayStringFromFormValue(features)\n\n answerEscaped = value ? `${value}\\n` : ''\n }\n\n return answerEscaped\n}\n"],"mappings":"AAAA,SAASA,aAAa,QAA2B,oBAAoB;AAErE,SAASC,MAAM;AAEf,SAASC,iBAAiB;AAC1B,SAASC,cAAc;AACvB,OAAO,KAAKC,UAAU;AACtB,SAASC,QAAQ;;AAGjB;;AAKA;;AA0BA;;AASA;;AASA,OAAO,MAAMC,WAAW,GAAGL,MAAM,CAACM,GAAG,CAAC,aAAa,CAAC;;AAEpD;AACA,SAASF,QAAQ;;AAEjB;AACA;AACA;AACA,OAAO,SAASG,gBAAgBA,CAC9BC,KAA0B,EACE;EAC5B,OAAO,CAAC,CAACA,KAAK,IAAIA,KAAK,CAACC,IAAI,KAAKC,SAAS,IAAIC,eAAe,CAACH,KAAK,CAACC,IAAI,CAAC;AAC3E;AAEA,OAAO,SAASE,eAAeA,CAC7BF,IAAoB,EACO;EAC3B,MAAMG,YAAY,GAAG,CACnBb,aAAa,CAACc,iBAAiB,EAC/Bd,aAAa,CAACe,eAAe,EAC7Bf,aAAa,CAACgB,WAAW,EACzBhB,aAAa,CAACiB,WAAW,EACzBjB,aAAa,CAACkB,UAAU,CACzB;EAED,OAAO,CAAC,CAACR,IAAI,IAAIG,YAAY,CAACM,QAAQ,CAACT,IAAI,CAAC;AAC9C;;AAEA;AACA;AACA;AACA,OAAO,SAASU,eAAeA,CAC7BC,GAAiB,EACjBC,OAAuD,EAC5C;EACX,IAAIC,SAAgC;EAEpC,QAAQF,GAAG,CAACX,IAAI;IACd,KAAKV,aAAa,CAACc,iBAAiB;MAClCS,SAAS,GAAG,IAAInB,UAAU,CAACU,iBAAiB,CAACO,GAAG,EAAEC,OAAO,CAAC;MAC1D;IAEF,KAAKtB,aAAa,CAACe,eAAe;MAChCQ,SAAS,GAAG,IAAInB,UAAU,CAACW,eAAe,CAACM,GAAG,EAAEC,OAAO,CAAC;MACxD;IAEF,KAAKtB,aAAa,CAACwB,cAAc;MAC/BD,SAAS,GAAG,IAAInB,UAAU,CAACoB,cAAc,CAACH,GAAG,EAAEC,OAAO,CAAC;MACvD;IAEF,KAAKtB,aAAa,CAACyB,gBAAgB;MACjCF,SAAS,GAAG,IAAInB,UAAU,CAACqB,gBAAgB,CAACJ,GAAG,EAAEC,OAAO,CAAC;MACzD;IAEF,KAAKtB,aAAa,CAAC0B,OAAO;MACxBH,SAAS,GAAG,IAAInB,UAAU,CAACsB,OAAO,CAACL,GAAG,EAAEC,OAAO,CAAC;MAChD;IAEF,KAAKtB,aAAa,CAAC2B,iBAAiB;MAClCJ,SAAS,GAAG,IAAInB,UAAU,CAACuB,iBAAiB,CAACN,GAAG,EAAEC,OAAO,CAAC;MAC1D;IAEF,KAAKtB,aAAa,CAAC4B,IAAI;MACrBL,SAAS,GAAG,IAAInB,UAAU,CAACwB,IAAI,CAACP,GAAG,EAAEC,OAAO,CAAC;MAC7C;IAEF,KAAKtB,aAAa,CAAC6B,SAAS;MAC1BN,SAAS,GAAG,IAAInB,UAAU,CAACyB,SAAS,CAACR,GAAG,EAAEC,OAAO,CAAC;MAClD;IAEF,KAAKtB,aAAa,CAAC8B,IAAI;MACrBP,SAAS,GAAG,IAAInB,UAAU,CAAC0B,IAAI,CAACT,GAAG,EAAEC,OAAO,CAAC;MAC7C;IAEF,KAAKtB,aAAa,CAAC+B,QAAQ;MACzBR,SAAS,GAAG,IAAInB,UAAU,CAAC2B,QAAQ,CAACV,GAAG,EAAEC,OAAO,CAAC;MACjD;IAEF,KAAKtB,aAAa,CAACgC,kBAAkB;MACnCT,SAAS,GAAG,IAAInB,UAAU,CAAC4B,kBAAkB,CAACX,GAAG,EAAEC,OAAO,CAAC;MAC3D;IAEF,KAAKtB,aAAa,CAACiC,kBAAkB;MACnCV,SAAS,GAAG,IAAInB,UAAU,CAAC6B,kBAAkB,CAACZ,GAAG,EAAEC,OAAO,CAAC;MAC3D;IAEF,KAAKtB,aAAa,CAACkC,WAAW;MAC5BX,SAAS,GAAG,IAAInB,UAAU,CAAC8B,WAAW,CAACb,GAAG,EAAEC,OAAO,CAAC;MACpD;IAEF,KAAKtB,aAAa,CAACgB,WAAW;MAC5BO,SAAS,GAAG,IAAInB,UAAU,CAACY,WAAW,CAACK,GAAG,EAAEC,OAAO,CAAC;MACpD;IAEF,KAAKtB,aAAa,CAACiB,WAAW;MAC5BM,SAAS,GAAG,IAAInB,UAAU,CAACa,WAAW,CAACI,GAAG,EAAEC,OAAO,CAAC;MACpD;IAEF,KAAKtB,aAAa,CAACmC,oBAAoB;MACrCZ,SAAS,GAAG,IAAInB,UAAU,CAAC+B,oBAAoB,CAACd,GAAG,EAAEC,OAAO,CAAC;MAC7D;IAEF,KAAKtB,aAAa,CAACoC,SAAS;MAC1Bb,SAAS,GAAG,IAAInB,UAAU,CAACgC,SAAS,CAACf,GAAG,EAAEC,OAAO,CAAC;MAClD;IAEF,KAAKtB,aAAa,CAACqC,cAAc;MAC/Bd,SAAS,GAAG,IAAInB,UAAU,CAACiC,cAAc,CAAChB,GAAG,EAAEC,OAAO,CAAC;MACvD;IAEF,KAAKtB,aAAa,CAACkB,UAAU;MAC3BK,SAAS,GAAG,IAAInB,UAAU,CAACc,UAAU,CAACG,GAAG,EAAEC,OAAO,CAAC;MACnD;IAEF,KAAKtB,aAAa,CAACsC,cAAc;MAC/Bf,SAAS,GAAG,IAAInB,UAAU,CAACkC,cAAc,CAACjB,GAAG,EAAEC,OAAO,CAAC;MACvD;IAEF,KAAKtB,aAAa,CAACuC,eAAe;MAChChB,SAAS,GAAG,IAAInB,UAAU,CAACmC,eAAe,CAAClB,GAAG,EAAEC,OAAO,CAAC;MACxD;IAEF,KAAKtB,aAAa,CAACwC,oBAAoB;MACrCjB,SAAS,GAAG,IAAInB,UAAU,CAACoC,oBAAoB,CAACnB,GAAG,EAAEC,OAAO,CAAC;MAC7D;IAEF,KAAKtB,aAAa,CAACyC,cAAc;MAC/BlB,SAAS,GAAG,IAAInB,UAAU,CAACqC,cAAc,CAACpB,GAAG,EAAEC,OAAO,CAAC;MACvD;IAEF,KAAKtB,aAAa,CAAC0C,4BAA4B;MAC7CnB,SAAS,GAAG,IAAInB,UAAU,CAACsC,4BAA4B,CAACrB,GAAG,EAAEC,OAAO,CAAC;MACrE;IAEF,KAAKtB,aAAa,CAAC2C,YAAY;MAC7BpB,SAAS,GAAG,IAAInB,UAAU,CAACuC,YAAY,CAACtB,GAAG,EAAEC,OAAO,CAAC;MACrD;IAEF,KAAKtB,aAAa,CAAC4C,WAAW;MAC5BrB,SAAS,GAAG,IAAInB,UAAU,CAACwC,WAAW,CAACvB,GAAG,EAAEC,OAAO,CAAC;MACpD;IAEF,KAAKtB,aAAa,CAAC6C,YAAY;MAC7BtB,SAAS,GAAG,IAAInB,UAAU,CAACyC,YAAY,CAACxB,GAAG,EAAEC,OAAO,CAAC;MACrD;IAEF,KAAKtB,aAAa,CAAC8C,eAAe;MAChCvB,SAAS,GAAG,IAAInB,UAAU,CAAC0C,eAAe,CAACzB,GAAG,EAAEC,OAAO,CAAC;MACxD;EACJ;EAEA,IAAI,OAAOC,SAAS,KAAK,WAAW,EAAE;IACpC,MAAM,IAAIwB,KAAK,CAAC,kBAAkB1B,GAAG,CAACX,IAAI,iBAAiB,CAAC;EAC9D;EAEA,OAAOa,SAAS;AAClB;;AAEA;AACA;AACA;AACA,OAAO,SAASyB,SAASA,CACvBvC,KAAY,EACZwC,KAAgB,EAChB3B,OAKC,GAAG;EAAE4B,MAAM,EAAE;AAAU,CAAC,EACzB;EACA;EACA,IAAI5B,OAAO,CAAC4B,MAAM,KAAK,OAAO,EAAE;IAC9B,OAAOC,iBAAiB,CAAC1C,KAAK,EAAEwC,KAAK,EAAE;MAAEC,MAAM,EAAE;IAAQ,CAAC,CAAC;EAC7D;;EAEA;EACA,IAAI5B,OAAO,CAAC4B,MAAM,KAAK,MAAM,EAAE;IAC7B,MAAME,OAAO,GAAG3C,KAAK,CAAC4C,wBAAwB,CAACJ,KAAK,CAAC;IACrD,OAAOG,OAAO,EAAEE,QAAQ,CAAC,CAAC,IAAI,EAAE;EAClC;;EAEA;EACA,IACE7C,KAAK,YAAYP,iBAAiB,IAClCO,KAAK,YAAYL,UAAU,CAAC6B,kBAAkB,IAC9CxB,KAAK,YAAYL,UAAU,CAACiC,cAAc,IAC1C5B,KAAK,YAAYL,UAAU,CAACoC,oBAAoB,IAChD/B,KAAK,YAAYL,UAAU,CAACuC,YAAY,EACxC;IACA,OAAOtC,QAAQ,CACZkD,KAAK,CAACJ,iBAAiB,CAAC1C,KAAK,EAAEwC,KAAK,CAAC,EAAE;MAAEO,KAAK,EAAE;IAAM,CAAC,CAAC,CACxDC,IAAI,CAAC,CAAC;EACX;;EAEA;EACA,OAAOhD,KAAK,CAACiD,yBAAyB,CAACT,KAAK,CAAC;AAC/C;;AAEA;AACA;AACA;AACA,OAAO,SAASE,iBAAiBA,CAC/B1C,KAAY,EACZwC,KAAgB,EAChB3B,OAIC,GAAG;EAAE4B,MAAM,EAAE;AAAU,CAAC,EACzB;EACA,MAAMS,MAAM,GAAGlD,KAAK,CAACiD,yBAAyB,CAACT,KAAK,CAAC;;EAErD;EACA,IAAIW,aAAa,GAAG,GAAGzD,cAAc,CAACwD,MAAM,CAAC,IAAI;EAEjD,IAAIlD,KAAK,YAAYL,UAAU,CAACmC,eAAe,EAAE;IAC/C,MAAMsB,KAAK,GAAGpD,KAAK,CAACqD,qBAAqB,CAACb,KAAK,CAAC;;IAEhD;IACA,IAAI,CAACY,KAAK,EAAEE,MAAM,EAAE;MAClB,OAAOH,aAAa;IACtB;IAEAA,aAAa,GAAG,GAAGzD,cAAc,CAACwD,MAAM,CAAC,OAAO;;IAEhD;IACAC,aAAa,IAAIC,KAAK,CACnBG,GAAG,CAAC,CAAC;MAAEC;IAAO,CAAC,KAAK;MACnB,MAAM;QAAEC;MAAK,CAAC,GAAGD,MAAM,CAACE,IAAI;MAC5B,MAAMC,QAAQ,GAAGjE,cAAc,CAAC+D,IAAI,CAACE,QAAQ,CAAC;MAC9C,OAAO,MAAMA,QAAQ,KAAK9D,WAAW,kBAAkB4D,IAAI,CAACG,MAAM,KAAK;IACzE,CAAC,CAAC,CACDC,IAAI,CAAC,EAAE,CAAC;EACb,CAAC,MAAM,IAAI7D,KAAK,YAAYP,iBAAiB,EAAE;IAC7C,MAAMqE,MAAM,GAAG,CAAC9D,KAAK,CAAC4C,wBAAwB,CAACJ,KAAK,CAAC,CAAC,CAACuB,IAAI,CAAC,CAAC;IAC7D,MAAMC,KAAK,GAAGhE,KAAK,CAACgE,KAAK,CAACC,MAAM,CAAC,CAAC;MAAEC;IAAM,CAAC,KAAKJ,MAAM,CAACpD,QAAQ,CAACwD,KAAK,CAAC,CAAC;;IAEvE;IACA,IAAI,CAACF,KAAK,CAACV,MAAM,EAAE;MACjB,OAAOH,aAAa;IACtB;IAEAA,aAAa,GAAG,EAAE;;IAElB;IACAA,aAAa,IAAIa,KAAK,CACnBT,GAAG,CAAEY,IAAI,IAAK;MACb,MAAMC,KAAK,GAAG1E,cAAc,CAACyE,IAAI,CAACE,IAAI,CAAC;MACvC,MAAMH,KAAK,GAAGxE,cAAc,CAAC,IAAIyE,IAAI,CAACD,KAAK,GAAG,CAAC;MAE/C,IAAII,IAAI,GAAGF,KAAK;;MAEhB;MACA,IAAIpE,KAAK,YAAYL,UAAU,CAACW,eAAe,EAAE;QAC/CgE,IAAI,GAAG,KAAKA,IAAI,EAAE;MACpB;;MAEA;MACA;MACA,OAAOzD,OAAO,CAAC4B,MAAM,KAAK,OAAO,IAC/B,GAAG0B,IAAI,CAACD,KAAK,EAAE,CAACK,WAAW,CAAC,CAAC,KAAKJ,IAAI,CAACE,IAAI,CAACE,WAAW,CAAC,CAAC,GACvD,GAAGD,IAAI,IAAIJ,KAAK,IAAI,GACpB,GAAGI,IAAI,IAAI;IACjB,CAAC,CAAC,CACDT,IAAI,CAAC,EAAE,CAAC;EACb,CAAC,MAAM,IAAI7D,KAAK,YAAYL,UAAU,CAAC6B,kBAAkB,EAAE;IACzD;IACA2B,aAAa,GAAGD,MAAM,CACnBsB,KAAK,CAAC,YAAY,CAAC,CACnBjB,GAAG,CAAC7D,cAAc,CAAC,CACnBmE,IAAI,CAAC,IAAI,CAAC,CACVY,MAAM,CAAC,IAAI,CAAC;EACjB,CAAC,MAAM,IAAIzE,KAAK,YAAYL,UAAU,CAACiC,cAAc,EAAE;IACrD;IACAuB,aAAa,GAAG,CAACnD,KAAK,CAAC4C,wBAAwB,CAACJ,KAAK,CAAC,IAAI,EAAE,EACzDe,GAAG,CAAC7D,cAAc,CAAC,CACnBmE,IAAI,CAAC,IAAI,CAAC,CACVY,MAAM,CAAC,IAAI,CAAC;EACjB,CAAC,MAAM,IACLzE,KAAK,YAAYL,UAAU,CAACoC,oBAAoB,IAChD/B,KAAK,YAAYL,UAAU,CAACuC,YAAY,EACxC;IACA,MAAMwC,YAAY,GAAG1E,KAAK,CAAC4C,wBAAwB,CAACJ,KAAK,CAAC;IAC1DW,aAAa,GAAGuB,YAAY,GAAG,GAAGA,YAAY,IAAI,GAAG,EAAE;EACzD,CAAC,MAAM,IAAI1E,KAAK,YAAYL,UAAU,CAAC0C,eAAe,EAAE;IACtD,MAAMsC,QAAQ,GAAG3E,KAAK,CAACqD,qBAAqB,CAACb,KAAK,CAAC;IACnD,MAAM0B,KAAK,GAAGlE,KAAK,CAAC4E,6BAA6B,CAACD,QAAQ,CAAC;IAE3DxB,aAAa,GAAGe,KAAK,GAAG,GAAGA,KAAK,IAAI,GAAG,EAAE;EAC3C;EAEA,OAAOf,aAAa;AACtB","ignoreList":[]}
|
|
@@ -14,6 +14,7 @@ export { Html } from '../../../../server/plugins/engine/components/Html.js';
|
|
|
14
14
|
export { InsetText } from '../../../../server/plugins/engine/components/InsetText.js';
|
|
15
15
|
export { List } from '../../../../server/plugins/engine/components/List.js';
|
|
16
16
|
export { Markdown } from '../../../../server/plugins/engine/components/Markdown.js';
|
|
17
|
+
export { NotificationBanner } from '../../../../server/plugins/engine/components/NotificationBanner.js';
|
|
17
18
|
export { MonthYearField } from '../../../../server/plugins/engine/components/MonthYearField.js';
|
|
18
19
|
export { MultilineTextField } from '../../../../server/plugins/engine/components/MultilineTextField.js';
|
|
19
20
|
export { NumberField } from '../../../../server/plugins/engine/components/NumberField.js';
|
|
@@ -15,6 +15,7 @@ export { Html } from "./Html.js";
|
|
|
15
15
|
export { InsetText } from "./InsetText.js";
|
|
16
16
|
export { List } from "./List.js";
|
|
17
17
|
export { Markdown } from "./Markdown.js";
|
|
18
|
+
export { NotificationBanner } from "./NotificationBanner.js";
|
|
18
19
|
export { MonthYearField } from "./MonthYearField.js";
|
|
19
20
|
export { MultilineTextField } from "./MultilineTextField.js";
|
|
20
21
|
export { NumberField } from "./NumberField.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["AutocompleteField","CheckboxesField","DatePartsField","DeclarationField","Details","EmailAddressField","FileUploadField","Html","InsetText","List","Markdown","MonthYearField","MultilineTextField","NumberField","RadiosField","SelectField","TelephoneNumberField","TextField","UkAddressField","YesNoField","EastingNorthingField","OsGridRefField","NationalGridFieldNumberField","LatLongField","HiddenField","PaymentField","GeospatialField"],"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 { DeclarationField } from '~/src/server/plugins/engine/components/DeclarationField.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'\nexport { HiddenField } from '~/src/server/plugins/engine/components/HiddenField.js'\nexport { PaymentField } from '~/src/server/plugins/engine/components/PaymentField.js'\nexport { GeospatialField } from '~/src/server/plugins/engine/components/GeospatialField.js'\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;;AAEA,SAASA,iBAAiB;AAC1B,SAASC,eAAe;AACxB,SAASC,cAAc;AACvB,SAASC,gBAAgB;AACzB,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;AACrB,SAASC,WAAW;AACpB,SAASC,YAAY;AACrB,SAASC,eAAe","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"index.js","names":["AutocompleteField","CheckboxesField","DatePartsField","DeclarationField","Details","EmailAddressField","FileUploadField","Html","InsetText","List","Markdown","NotificationBanner","MonthYearField","MultilineTextField","NumberField","RadiosField","SelectField","TelephoneNumberField","TextField","UkAddressField","YesNoField","EastingNorthingField","OsGridRefField","NationalGridFieldNumberField","LatLongField","HiddenField","PaymentField","GeospatialField"],"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 { DeclarationField } from '~/src/server/plugins/engine/components/DeclarationField.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 { NotificationBanner } from '~/src/server/plugins/engine/components/NotificationBanner.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'\nexport { HiddenField } from '~/src/server/plugins/engine/components/HiddenField.js'\nexport { PaymentField } from '~/src/server/plugins/engine/components/PaymentField.js'\nexport { GeospatialField } from '~/src/server/plugins/engine/components/GeospatialField.js'\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;;AAEA,SAASA,iBAAiB;AAC1B,SAASC,eAAe;AACxB,SAASC,cAAc;AACvB,SAASC,gBAAgB;AACzB,SAASC,OAAO;AAChB,SAASC,iBAAiB;AAC1B,SAASC,eAAe;AACxB,SAASC,IAAI;AACb,SAASC,SAAS;AAClB,SAASC,IAAI;AACb,SAASC,QAAQ;AACjB,SAASC,kBAAkB;AAC3B,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;AACrB,SAASC,WAAW;AACpB,SAASC,YAAY;AACrB,SAASC,eAAe","ignoreList":[]}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{% from "govuk/components/notification-banner/macro.njk" import govukNotificationBanner %}
|
|
2
|
+
|
|
3
|
+
{% macro NotificationBanner(component) %}
|
|
4
|
+
{%- set bannerHtml -%}
|
|
5
|
+
{%- if component.model.heading -%}
|
|
6
|
+
<div class="app-prose-notification-banner-scope">{{ component.model.heading | markdown | safe }}</div>
|
|
7
|
+
{%- endif -%}
|
|
8
|
+
<div class="app-prose-scope">{{ component.model.content | markdown | safe }}</div>
|
|
9
|
+
{%- endset -%}
|
|
10
|
+
{{ govukNotificationBanner({
|
|
11
|
+
titleHtml: component.model.titleHtml,
|
|
12
|
+
html: bannerHtml,
|
|
13
|
+
type: component.model.type
|
|
14
|
+
}) }}
|
|
15
|
+
{% endmacro %}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Gets the map support routes
|
|
3
3
|
* @param {MapConfiguration} options - ordnance survey names api key
|
|
4
4
|
*/
|
|
5
|
-
export function getRoutes(options: MapConfiguration): (ServerRoute<MapProxyGetRequestRefs> | ServerRoute<MapGeocodeGetRequestRefs> | ServerRoute<
|
|
5
|
+
export function getRoutes(options: MapConfiguration): (ServerRoute<MapProxyGetRequestRefs> | ServerRoute<MapGeocodeGetRequestRefs> | ServerRoute<GeospatialCountriesGetRequestRefs>)[];
|
|
6
6
|
/**
|
|
7
7
|
* @type {FeatureCollection}
|
|
8
8
|
*/
|
|
@@ -12,7 +12,6 @@ import type { MapConfiguration } from '../../../../server/plugins/map/types.js';
|
|
|
12
12
|
import type { MapProxyGetRequestRefs } from '../../../../server/plugins/map/types.js';
|
|
13
13
|
import type { ServerRoute } from '@hapi/hapi';
|
|
14
14
|
import type { MapGeocodeGetRequestRefs } from '../../../../server/plugins/map/types.js';
|
|
15
|
-
import type { MapReverseGeocodeGetRequestRefs } from '../../../../server/plugins/map/types.js';
|
|
16
15
|
import type { GeospatialCountriesGetRequestRefs } from '../../../../server/plugins/map/types.js';
|
|
17
16
|
import type { FeatureCollection } from 'geojson';
|
|
18
17
|
import Joi from 'joi';
|
|
@@ -4,7 +4,7 @@ import { GeospatialFieldOptionsCountryEnum } from '@defra/forms-model';
|
|
|
4
4
|
import { StatusCodes } from 'http-status-codes';
|
|
5
5
|
import Joi from 'joi';
|
|
6
6
|
import { getAccessToken } from "./get-os-token.js";
|
|
7
|
-
import { find
|
|
7
|
+
import { find } from "../service.js";
|
|
8
8
|
import { get, request as httpRequest } from "../../../services/httpService.js";
|
|
9
9
|
const filePath = resolve(import.meta.dirname, './vts/countries.geojson');
|
|
10
10
|
|
|
@@ -20,7 +20,7 @@ export const countrySchema = Joi.string().valid(...Object.values(GeospatialField
|
|
|
20
20
|
* @param {MapConfiguration} options - ordnance survey names api key
|
|
21
21
|
*/
|
|
22
22
|
export function getRoutes(options) {
|
|
23
|
-
return [mapStyleResourceRoutes(), mapProxyRoute(options), tileProxyRoute(options), geocodeProxyRoute(options),
|
|
23
|
+
return [mapStyleResourceRoutes(), mapProxyRoute(options), tileProxyRoute(options), geocodeProxyRoute(options), getGeospatialCountries()];
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
/**
|
|
@@ -134,36 +134,6 @@ function geocodeProxyRoute(options) {
|
|
|
134
134
|
};
|
|
135
135
|
}
|
|
136
136
|
|
|
137
|
-
/**
|
|
138
|
-
* Proxies ordnance survey reverse geocode requests from the front end to api.os.uk
|
|
139
|
-
* Used to find name from easting and northing points.
|
|
140
|
-
* N.B this endpoint is currently not used by the front end but will be soon in "maps V2"
|
|
141
|
-
* @param {MapConfiguration} options - the map options
|
|
142
|
-
* @returns {ServerRoute<MapReverseGeocodeGetRequestRefs>}
|
|
143
|
-
*/
|
|
144
|
-
function reverseGeocodeProxyRoute(options) {
|
|
145
|
-
return {
|
|
146
|
-
method: 'GET',
|
|
147
|
-
path: '/api/reverse-geocode-proxy',
|
|
148
|
-
async handler(request, _h) {
|
|
149
|
-
const {
|
|
150
|
-
query
|
|
151
|
-
} = request;
|
|
152
|
-
const data = await nearest(query.easting, query.northing, options.ordnanceSurveyApiKey);
|
|
153
|
-
return data;
|
|
154
|
-
},
|
|
155
|
-
options: {
|
|
156
|
-
auth: false,
|
|
157
|
-
validate: {
|
|
158
|
-
query: Joi.object().keys({
|
|
159
|
-
easting: Joi.number().required(),
|
|
160
|
-
northing: Joi.number().required()
|
|
161
|
-
}).required()
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
};
|
|
165
|
-
}
|
|
166
|
-
|
|
167
137
|
/**
|
|
168
138
|
* Resource routes to return sprites and glyphs
|
|
169
139
|
* @returns {ServerRoute<MapProxyGetRequestRefs>}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["fs","resolve","GeospatialFieldOptionsCountryEnum","StatusCodes","Joi","getAccessToken","find","nearest","get","request","httpRequest","filePath","import","meta","dirname","countries","JSON","parse","readFileSync","countrySchema","string","valid","Object","values","getRoutes","options","mapStyleResourceRoutes","mapProxyRoute","tileProxyRoute","geocodeProxyRoute","reverseGeocodeProxyRoute","getGeospatialCountries","method","path","handler","h","query","targetUrl","URL","decodeURIComponent","url","token","searchParams","set","proxyResponse","toString","headers","Authorization","buffer","payload","contentType","res","response","type","auth","validate","object","keys","required","optional","z","y","x","params","getBuffer","Accept","json","gunzip","statusCode","OK","valueOf","code","header","_h","data","ordnanceSurveyApiKey","easting","northing","number","directory","omit","only","features","filter","feature","id"],"sources":["../../../../../src/server/plugins/map/routes/index.js"],"sourcesContent":["import fs from 'node:fs'\nimport { resolve } from 'node:path'\n\nimport { GeospatialFieldOptionsCountryEnum } from '@defra/forms-model'\nimport { StatusCodes } from 'http-status-codes'\nimport Joi from 'joi'\n\nimport { getAccessToken } from '~/src/server/plugins/map/routes/get-os-token.js'\nimport { find, nearest } from '~/src/server/plugins/map/service.js'\nimport {\n get,\n request as httpRequest\n} from '~/src/server/services/httpService.js'\n\nconst filePath = resolve(import.meta.dirname, './vts/countries.geojson')\n\n/**\n * @type {FeatureCollection}\n */\n// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\nexport const countries = JSON.parse(fs.readFileSync(filePath, 'utf8'))\n\nexport const countrySchema = Joi.string().valid(\n ...Object.values(GeospatialFieldOptionsCountryEnum)\n)\n\n/**\n * Gets the map support routes\n * @param {MapConfiguration} options - ordnance survey names api key\n */\nexport function getRoutes(options) {\n return [\n mapStyleResourceRoutes(),\n mapProxyRoute(options),\n tileProxyRoute(options),\n geocodeProxyRoute(options),\n reverseGeocodeProxyRoute(options),\n getGeospatialCountries()\n ]\n}\n\n/**\n * Proxies ordnance survey requests from the front end to api.os.com\n * Used for the VTS map source by forwarding on the request\n * and adding the auth token and SRS (spatial reference system)\n * @param {MapConfiguration} options - the map options\n * @returns {ServerRoute<MapProxyGetRequestRefs>}\n */\nfunction mapProxyRoute(options) {\n return {\n method: 'GET',\n path: '/api/map-proxy',\n handler: async (request, h) => {\n const { query } = request\n const targetUrl = new URL(decodeURIComponent(query.url))\n const token = await getAccessToken(options)\n\n targetUrl.searchParams.set('srs', '3857')\n\n const proxyResponse = await httpRequest('get', targetUrl.toString(), {\n headers: {\n Authorization: `Bearer ${token}`\n }\n })\n const buffer = proxyResponse.payload\n const contentType = proxyResponse.res.headers['content-type']\n const response = h.response(buffer)\n\n if (contentType) {\n response.type(contentType)\n }\n\n return response\n },\n options: {\n auth: false,\n validate: {\n query: Joi.object()\n .keys({\n url: Joi.string().required()\n })\n .optional()\n }\n }\n }\n}\n\n/**\n * Proxies ordnance survey requests from the front end to api.os.uk\n * Used for VTS map tiles forwarding on the request and adding the auth token\n * @param {MapConfiguration} options - the map options\n * @returns {ServerRoute<MapProxyGetRequestRefs>}\n */\nfunction tileProxyRoute(options) {\n return {\n method: 'GET',\n path: '/api/tile/{z}/{y}/{x}.pbf',\n handler: async (request, h) => {\n const { z, y, x } = request.params\n const token = await getAccessToken(options)\n\n const url = `https://api.os.uk/maps/vector/v1/vts/tile/${z}/${y}/${x}.pbf?srs=3857`\n\n const getBuffer = /** @type {typeof get<Buffer>} */ (get)\n\n const { payload, res } = await getBuffer(url, {\n headers: {\n Authorization: `Bearer ${token}`,\n Accept: 'application/x-protobuf'\n },\n json: false,\n gunzip: true\n })\n\n if (res.statusCode && res.statusCode !== StatusCodes.OK.valueOf()) {\n return h.response('Tile fetch failed').code(res.statusCode)\n }\n\n return h\n .response(payload)\n .type('application/x-protobuf')\n .header('Cache-Control', 'public, max-age=86400')\n },\n options: {\n auth: false\n }\n }\n}\n\n/**\n * Proxies ordnance survey geocode requests from the front end to api.os.uk\n * Used for the gazzeteer address lookup to find name from query strings like postcode and place names\n * @param {MapConfiguration} options - the map options\n * @returns {ServerRoute<MapGeocodeGetRequestRefs>}\n */\nfunction geocodeProxyRoute(options) {\n return {\n method: 'GET',\n path: '/api/geocode-proxy',\n async handler(request, _h) {\n const { query } = request\n const data = await find(query.query, options.ordnanceSurveyApiKey)\n\n return data\n },\n options: {\n auth: false,\n validate: {\n query: Joi.object()\n .keys({\n query: Joi.string().required()\n })\n .required()\n }\n }\n }\n}\n\n/**\n * Proxies ordnance survey reverse geocode requests from the front end to api.os.uk\n * Used to find name from easting and northing points.\n * N.B this endpoint is currently not used by the front end but will be soon in \"maps V2\"\n * @param {MapConfiguration} options - the map options\n * @returns {ServerRoute<MapReverseGeocodeGetRequestRefs>}\n */\nfunction reverseGeocodeProxyRoute(options) {\n return {\n method: 'GET',\n path: '/api/reverse-geocode-proxy',\n async handler(request, _h) {\n const { query } = request\n const data = await nearest(\n query.easting,\n query.northing,\n options.ordnanceSurveyApiKey\n )\n\n return data\n },\n options: {\n auth: false,\n validate: {\n query: Joi.object()\n .keys({\n easting: Joi.number().required(),\n northing: Joi.number().required()\n })\n .required()\n }\n }\n }\n}\n\n/**\n * Resource routes to return sprites and glyphs\n * @returns {ServerRoute<MapProxyGetRequestRefs>}\n */\nfunction mapStyleResourceRoutes() {\n return {\n method: 'GET',\n path: '/api/maps/vts/{path*}',\n options: {\n auth: false,\n handler: {\n directory: {\n path: resolve(import.meta.dirname, './vts')\n }\n }\n }\n }\n}\n\n/**\n * Resource routes to return sprites and glyphs\n * @returns {ServerRoute<GeospatialCountriesGetRequestRefs>}\n */\nfunction getGeospatialCountries() {\n return {\n method: 'GET',\n path: '/api/maps/countries.geojson',\n handler: (request) => {\n const { omit, only } = request.query\n\n if (omit) {\n return {\n ...countries,\n features: countries.features.filter((feature) => feature.id !== omit)\n }\n }\n\n if (only) {\n return {\n ...countries,\n features: countries.features.filter((feature) => feature.id === only)\n }\n }\n\n return countries\n },\n options: {\n auth: false,\n validate: {\n query: Joi.object()\n .keys({\n omit: countrySchema.optional(),\n only: countrySchema.optional()\n })\n .optional()\n }\n }\n }\n}\n\n/**\n * @import { ServerRoute } from '@hapi/hapi'\n * @import { FeatureCollection } from 'geojson'\n * @import { MapConfiguration, MapProxyGetRequestRefs, MapGeocodeGetRequestRefs, MapReverseGeocodeGetRequestRefs, GeospatialCountriesGetRequestRefs } from '~/src/server/plugins/map/types.js'\n */\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"index.js","names":["fs","resolve","GeospatialFieldOptionsCountryEnum","StatusCodes","Joi","getAccessToken","find","get","request","httpRequest","filePath","import","meta","dirname","countries","JSON","parse","readFileSync","countrySchema","string","valid","Object","values","getRoutes","options","mapStyleResourceRoutes","mapProxyRoute","tileProxyRoute","geocodeProxyRoute","getGeospatialCountries","method","path","handler","h","query","targetUrl","URL","decodeURIComponent","url","token","searchParams","set","proxyResponse","toString","headers","Authorization","buffer","payload","contentType","res","response","type","auth","validate","object","keys","required","optional","z","y","x","params","getBuffer","Accept","json","gunzip","statusCode","OK","valueOf","code","header","_h","data","ordnanceSurveyApiKey","directory","omit","only","features","filter","feature","id"],"sources":["../../../../../src/server/plugins/map/routes/index.js"],"sourcesContent":["import fs from 'node:fs'\nimport { resolve } from 'node:path'\n\nimport { GeospatialFieldOptionsCountryEnum } from '@defra/forms-model'\nimport { StatusCodes } from 'http-status-codes'\nimport Joi from 'joi'\n\nimport { getAccessToken } from '~/src/server/plugins/map/routes/get-os-token.js'\nimport { find } from '~/src/server/plugins/map/service.js'\nimport {\n get,\n request as httpRequest\n} from '~/src/server/services/httpService.js'\n\nconst filePath = resolve(import.meta.dirname, './vts/countries.geojson')\n\n/**\n * @type {FeatureCollection}\n */\n// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\nexport const countries = JSON.parse(fs.readFileSync(filePath, 'utf8'))\n\nexport const countrySchema = Joi.string().valid(\n ...Object.values(GeospatialFieldOptionsCountryEnum)\n)\n\n/**\n * Gets the map support routes\n * @param {MapConfiguration} options - ordnance survey names api key\n */\nexport function getRoutes(options) {\n return [\n mapStyleResourceRoutes(),\n mapProxyRoute(options),\n tileProxyRoute(options),\n geocodeProxyRoute(options),\n getGeospatialCountries()\n ]\n}\n\n/**\n * Proxies ordnance survey requests from the front end to api.os.com\n * Used for the VTS map source by forwarding on the request\n * and adding the auth token and SRS (spatial reference system)\n * @param {MapConfiguration} options - the map options\n * @returns {ServerRoute<MapProxyGetRequestRefs>}\n */\nfunction mapProxyRoute(options) {\n return {\n method: 'GET',\n path: '/api/map-proxy',\n handler: async (request, h) => {\n const { query } = request\n const targetUrl = new URL(decodeURIComponent(query.url))\n const token = await getAccessToken(options)\n\n targetUrl.searchParams.set('srs', '3857')\n\n const proxyResponse = await httpRequest('get', targetUrl.toString(), {\n headers: {\n Authorization: `Bearer ${token}`\n }\n })\n const buffer = proxyResponse.payload\n const contentType = proxyResponse.res.headers['content-type']\n const response = h.response(buffer)\n\n if (contentType) {\n response.type(contentType)\n }\n\n return response\n },\n options: {\n auth: false,\n validate: {\n query: Joi.object()\n .keys({\n url: Joi.string().required()\n })\n .optional()\n }\n }\n }\n}\n\n/**\n * Proxies ordnance survey requests from the front end to api.os.uk\n * Used for VTS map tiles forwarding on the request and adding the auth token\n * @param {MapConfiguration} options - the map options\n * @returns {ServerRoute<MapProxyGetRequestRefs>}\n */\nfunction tileProxyRoute(options) {\n return {\n method: 'GET',\n path: '/api/tile/{z}/{y}/{x}.pbf',\n handler: async (request, h) => {\n const { z, y, x } = request.params\n const token = await getAccessToken(options)\n\n const url = `https://api.os.uk/maps/vector/v1/vts/tile/${z}/${y}/${x}.pbf?srs=3857`\n\n const getBuffer = /** @type {typeof get<Buffer>} */ (get)\n\n const { payload, res } = await getBuffer(url, {\n headers: {\n Authorization: `Bearer ${token}`,\n Accept: 'application/x-protobuf'\n },\n json: false,\n gunzip: true\n })\n\n if (res.statusCode && res.statusCode !== StatusCodes.OK.valueOf()) {\n return h.response('Tile fetch failed').code(res.statusCode)\n }\n\n return h\n .response(payload)\n .type('application/x-protobuf')\n .header('Cache-Control', 'public, max-age=86400')\n },\n options: {\n auth: false\n }\n }\n}\n\n/**\n * Proxies ordnance survey geocode requests from the front end to api.os.uk\n * Used for the gazzeteer address lookup to find name from query strings like postcode and place names\n * @param {MapConfiguration} options - the map options\n * @returns {ServerRoute<MapGeocodeGetRequestRefs>}\n */\nfunction geocodeProxyRoute(options) {\n return {\n method: 'GET',\n path: '/api/geocode-proxy',\n async handler(request, _h) {\n const { query } = request\n const data = await find(query.query, options.ordnanceSurveyApiKey)\n\n return data\n },\n options: {\n auth: false,\n validate: {\n query: Joi.object()\n .keys({\n query: Joi.string().required()\n })\n .required()\n }\n }\n }\n}\n\n/**\n * Resource routes to return sprites and glyphs\n * @returns {ServerRoute<MapProxyGetRequestRefs>}\n */\nfunction mapStyleResourceRoutes() {\n return {\n method: 'GET',\n path: '/api/maps/vts/{path*}',\n options: {\n auth: false,\n handler: {\n directory: {\n path: resolve(import.meta.dirname, './vts')\n }\n }\n }\n }\n}\n\n/**\n * Resource routes to return sprites and glyphs\n * @returns {ServerRoute<GeospatialCountriesGetRequestRefs>}\n */\nfunction getGeospatialCountries() {\n return {\n method: 'GET',\n path: '/api/maps/countries.geojson',\n handler: (request) => {\n const { omit, only } = request.query\n\n if (omit) {\n return {\n ...countries,\n features: countries.features.filter((feature) => feature.id !== omit)\n }\n }\n\n if (only) {\n return {\n ...countries,\n features: countries.features.filter((feature) => feature.id === only)\n }\n }\n\n return countries\n },\n options: {\n auth: false,\n validate: {\n query: Joi.object()\n .keys({\n omit: countrySchema.optional(),\n only: countrySchema.optional()\n })\n .optional()\n }\n }\n }\n}\n\n/**\n * @import { ServerRoute } from '@hapi/hapi'\n * @import { FeatureCollection } from 'geojson'\n * @import { MapConfiguration, MapProxyGetRequestRefs, MapGeocodeGetRequestRefs, MapReverseGeocodeGetRequestRefs, GeospatialCountriesGetRequestRefs } from '~/src/server/plugins/map/types.js'\n */\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -4,11 +4,4 @@
|
|
|
4
4
|
* @param {string} apiKey - the OS api key
|
|
5
5
|
*/
|
|
6
6
|
export function find(query: string, apiKey: string): Promise<OsNamesFindResponse>;
|
|
7
|
-
/**
|
|
8
|
-
* OS names search nearest by E/N
|
|
9
|
-
* @param {number} easting - the easting
|
|
10
|
-
* @param {number} northing - the northing
|
|
11
|
-
* @param {string} apiKey - the OS api key
|
|
12
|
-
*/
|
|
13
|
-
export function nearest(easting: number, northing: number, apiKey: string): Promise<OsNamesFindResponse>;
|
|
14
7
|
import type { OsNamesFindResponse } from '../../../server/plugins/map/types.js';
|
|
@@ -60,18 +60,6 @@ export async function find(query, apiKey) {
|
|
|
60
60
|
return getData(url, endpoint);
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
-
/**
|
|
64
|
-
* OS names search nearest by E/N
|
|
65
|
-
* @param {number} easting - the easting
|
|
66
|
-
* @param {number} northing - the northing
|
|
67
|
-
* @param {string} apiKey - the OS api key
|
|
68
|
-
*/
|
|
69
|
-
export async function nearest(easting, northing, apiKey) {
|
|
70
|
-
const endpoint = 'nearest';
|
|
71
|
-
const url = `https://api.os.uk/search/names/v1/nearest?key=${apiKey}&point=${easting},${northing}&radius=1000&fq=local_type:Airfield%20local_type:Airport%20local_type:Bus_Station%20local_type:Chemical_Works%20local_type:City%20local_type:Coach_Station%20local_type:Electricity_Distribution%20local_type:Electricity_Production%20local_type:Further_Education%20local_type:Gas_Distribution_or_Storage%20local_type:Hamlet%20local_type:Harbour%20local_type:Helicopter_Station%20local_type:Heliport%20local_type:Higher_or_University_Education%20local_type:Hill_Or_Mountain%20local_type:Hospice%20local_type:Hospital%20local_type:Medical_Care_Accommodation%20local_type:Named_Road%20local_type:Non_State_Primary_Education%20local_type:Non_State_Secondary_Education%20local_type:Other_Settlement%20local_type:Passenger_Ferry_Terminal%20local_type:Port_Consisting_of_Docks_and_Nautical_Berthing%20local_type:Postcode%20local_type:Primary_Education%20local_type:Railway_Station%20local_type:Road_User_Services%20local_type:Secondary_Education%20local_type:Section_Of_Named_Road%20local_type:Section_Of_Numbered_Road%20local_type:Special_Needs_Education%20local_type:Suburban_Area%20local_type:Town%20local_type:Urban_Greenspace%20local_type:Vehicular_Ferry_Terminal%20local_type:Vehicular_Rail_Terminal%20local_type:Village%20local_type:Waterfall%20`;
|
|
72
|
-
return getData(url, endpoint);
|
|
73
|
-
}
|
|
74
|
-
|
|
75
63
|
/**
|
|
76
64
|
* @import { OsNamesFindResponse, OsNamesFindResult } from '../../../server/plugins/map/types.js'
|
|
77
65
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service.js","names":["getErrorMessage","Boom","logger","getJson","empty","results","header","logErrorAndReturnEmpty","err","endpoint","boomData","isBoom","data","msg","payload","error","message","getData","url","getJsonByType","response","find","query","apiKey"
|
|
1
|
+
{"version":3,"file":"service.js","names":["getErrorMessage","Boom","logger","getJson","empty","results","header","logErrorAndReturnEmpty","err","endpoint","boomData","isBoom","data","msg","payload","error","message","getData","url","getJsonByType","response","find","query","apiKey"],"sources":["../../../../src/server/plugins/map/service.js"],"sourcesContent":["import { getErrorMessage } from '@defra/forms-model'\nimport Boom from '@hapi/boom'\n\nimport { logger } from '~/src/server/common/helpers/logging/logger.js'\nimport { getJson } from '~/src/server/services/httpService.js'\n\n/**\n * Returns an empty result set\n */\nfunction empty() {\n /** @type {OsNamesFindResult[]} */\n const results = []\n\n return /** @type {OsNamesFindResponse} */ ({ header: {}, results })\n}\n\n/**\n * Logs OS names errors\n * @param {unknown} err - the error\n * @param {string} endpoint - the OS api endpoint\n */\nfunction logErrorAndReturnEmpty(err, endpoint) {\n /** @type {{ payload?: { error?: { message?: string } } } | false} */\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const boomData = Boom.isBoom(err) && err.data\n const msg = `${getErrorMessage(err)} ${(boomData && boomData.payload?.error?.message) ?? ''}`\n\n logger.error(err, `Exception occured calling OS names ${endpoint} - ${msg}}`)\n\n return empty()\n}\n\n/**\n * Fetch data from OS names API\n * @param {string} url - the url to get address json data from\n * @param {string} endpoint - the url endpoint description for logging\n */\nasync function getData(url, endpoint) {\n const getJsonByType = /** @type {typeof getJson<OsNamesFindResponse>} */ (\n getJson\n )\n\n try {\n const response = await getJsonByType(url)\n\n if (response.error) {\n return logErrorAndReturnEmpty(response.error, endpoint)\n }\n\n const results = response.payload\n\n return results\n } catch (err) {\n return logErrorAndReturnEmpty(err, endpoint)\n }\n}\n\n/**\n * OS names search find by query\n * @param {string} query - the search term\n * @param {string} apiKey - the OS api key\n */\nexport async function find(query, apiKey) {\n const endpoint = 'find'\n const url = `https://api.os.uk/search/names/v1/find?key=${apiKey}&query=${query}&fq=local_type:postcode%20local_type:hamlet%20local_type:village%20local_type:town%20local_type:city%20local_type:other_settlement&maxresults=8`\n\n return getData(url, endpoint)\n}\n\n/**\n * @import { OsNamesFindResponse, OsNamesFindResult } from '~/src/server/plugins/map/types.js'\n */\n"],"mappings":"AAAA,SAASA,eAAe,QAAQ,oBAAoB;AACpD,OAAOC,IAAI,MAAM,YAAY;AAE7B,SAASC,MAAM;AACf,SAASC,OAAO;;AAEhB;AACA;AACA;AACA,SAASC,KAAKA,CAAA,EAAG;EACf;EACA,MAAMC,OAAO,GAAG,EAAE;EAElB,OAAO,kCAAoC;IAAEC,MAAM,EAAE,CAAC,CAAC;IAAED;EAAQ,CAAC;AACpE;;AAEA;AACA;AACA;AACA;AACA;AACA,SAASE,sBAAsBA,CAACC,GAAG,EAAEC,QAAQ,EAAE;EAC7C;EACA;EACA,MAAMC,QAAQ,GAAGT,IAAI,CAACU,MAAM,CAACH,GAAG,CAAC,IAAIA,GAAG,CAACI,IAAI;EAC7C,MAAMC,GAAG,GAAG,GAAGb,eAAe,CAACQ,GAAG,CAAC,IAAI,CAACE,QAAQ,IAAIA,QAAQ,CAACI,OAAO,EAAEC,KAAK,EAAEC,OAAO,KAAK,EAAE,EAAE;EAE7Fd,MAAM,CAACa,KAAK,CAACP,GAAG,EAAE,sCAAsCC,QAAQ,MAAMI,GAAG,GAAG,CAAC;EAE7E,OAAOT,KAAK,CAAC,CAAC;AAChB;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAea,OAAOA,CAACC,GAAG,EAAET,QAAQ,EAAE;EACpC,MAAMU,aAAa,GAAG;EACpBhB,OACD;EAED,IAAI;IACF,MAAMiB,QAAQ,GAAG,MAAMD,aAAa,CAACD,GAAG,CAAC;IAEzC,IAAIE,QAAQ,CAACL,KAAK,EAAE;MAClB,OAAOR,sBAAsB,CAACa,QAAQ,CAACL,KAAK,EAAEN,QAAQ,CAAC;IACzD;IAEA,MAAMJ,OAAO,GAAGe,QAAQ,CAACN,OAAO;IAEhC,OAAOT,OAAO;EAChB,CAAC,CAAC,OAAOG,GAAG,EAAE;IACZ,OAAOD,sBAAsB,CAACC,GAAG,EAAEC,QAAQ,CAAC;EAC9C;AACF;;AAEA;AACA;AACA;AACA;AACA;AACA,OAAO,eAAeY,IAAIA,CAACC,KAAK,EAAEC,MAAM,EAAE;EACxC,MAAMd,QAAQ,GAAG,MAAM;EACvB,MAAMS,GAAG,GAAG,8CAA8CK,MAAM,UAAUD,KAAK,iJAAiJ;EAEhO,OAAOL,OAAO,CAACC,GAAG,EAAET,QAAQ,CAAC;AAC/B;;AAEA;AACA;AACA","ignoreList":[]}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import Boom from '@hapi/boom';
|
|
2
2
|
import * as service from "./service.js";
|
|
3
3
|
import { result as findResult } from "./test/__stubs__/find.js";
|
|
4
|
-
import { result as nearestResult } from "./test/__stubs__/nearest.js";
|
|
5
4
|
import { getJson } from "../../services/httpService.js";
|
|
6
5
|
jest.mock("../../services/httpService.ts");
|
|
7
6
|
describe('Maps service', () => {
|
|
@@ -70,48 +69,6 @@ describe('Maps service', () => {
|
|
|
70
69
|
expect(results).toEqual([]);
|
|
71
70
|
});
|
|
72
71
|
});
|
|
73
|
-
describe('nearest', () => {
|
|
74
|
-
it('should return entries', async () => {
|
|
75
|
-
jest.mocked(getJson).mockResolvedValueOnce({
|
|
76
|
-
res: (/** @type {IncomingMessage} */{
|
|
77
|
-
statusCode: 200,
|
|
78
|
-
headers: {}
|
|
79
|
-
}),
|
|
80
|
-
payload: nearestResult,
|
|
81
|
-
error: undefined
|
|
82
|
-
});
|
|
83
|
-
const {
|
|
84
|
-
results
|
|
85
|
-
} = await service.nearest(700000, 1300000, 'apikey');
|
|
86
|
-
expect(results).toHaveLength(1);
|
|
87
|
-
expect(results.at(0)).toEqual({
|
|
88
|
-
GAZETTEER_ENTRY: {
|
|
89
|
-
ID: 'NW26XE',
|
|
90
|
-
NAMES_URI: 'http://data.ordnancesurvey.co.uk/id/postcodeunit/NW26XE',
|
|
91
|
-
NAME1: 'NW2 6XE',
|
|
92
|
-
TYPE: 'other',
|
|
93
|
-
LOCAL_TYPE: 'Postcode',
|
|
94
|
-
GEOMETRY_X: 523065,
|
|
95
|
-
GEOMETRY_Y: 185795,
|
|
96
|
-
MOST_DETAIL_VIEW_RES: 3500,
|
|
97
|
-
LEAST_DETAIL_VIEW_RES: 18000,
|
|
98
|
-
POPULATED_PLACE: 'London',
|
|
99
|
-
POPULATED_PLACE_URI: 'http://data.ordnancesurvey.co.uk/id/4000000074813508',
|
|
100
|
-
POPULATED_PLACE_TYPE: 'http://www.ordnancesurvey.co.uk/xml/codelists/localtype.xml#city',
|
|
101
|
-
DISTRICT_BOROUGH: 'Brent',
|
|
102
|
-
DISTRICT_BOROUGH_URI: 'http://data.ordnancesurvey.co.uk/id/7000000000011447',
|
|
103
|
-
DISTRICT_BOROUGH_TYPE: 'http://data.ordnancesurvey.co.uk/ontology/admingeo/LondonBorough',
|
|
104
|
-
COUNTY_UNITARY: 'Greater London',
|
|
105
|
-
COUNTY_UNITARY_URI: 'http://data.ordnancesurvey.co.uk/id/7000000000041441',
|
|
106
|
-
COUNTY_UNITARY_TYPE: 'http://data.ordnancesurvey.co.uk/ontology/admingeo/GreaterLondonAuthority',
|
|
107
|
-
REGION: 'London',
|
|
108
|
-
REGION_URI: 'http://data.ordnancesurvey.co.uk/id/7000000000041428',
|
|
109
|
-
COUNTRY: 'England',
|
|
110
|
-
COUNTRY_URI: 'http://data.ordnancesurvey.co.uk/id/country/england'
|
|
111
|
-
}
|
|
112
|
-
});
|
|
113
|
-
});
|
|
114
|
-
});
|
|
115
72
|
});
|
|
116
73
|
|
|
117
74
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service.test.js","names":["Boom","service","result","findResult","
|
|
1
|
+
{"version":3,"file":"service.test.js","names":["Boom","service","result","findResult","getJson","jest","mock","describe","it","mocked","mockResolvedValueOnce","res","statusCode","headers","payload","error","undefined","results","find","expect","toHaveLength","at","toEqual","GAZETTEER_ENTRY","ID","NAMES_URI","NAME1","TYPE","LOCAL_TYPE","GEOMETRY_X","GEOMETRY_Y","MOST_DETAIL_VIEW_RES","LEAST_DETAIL_VIEW_RES","POPULATED_PLACE","POPULATED_PLACE_URI","POPULATED_PLACE_TYPE","DISTRICT_BOROUGH","DISTRICT_BOROUGH_URI","DISTRICT_BOROUGH_TYPE","COUNTY_UNITARY","COUNTY_UNITARY_URI","COUNTY_UNITARY_TYPE","REGION","REGION_URI","COUNTRY","COUNTRY_URI","Error","mockRejectedValueOnce","badRequest"],"sources":["../../../../src/server/plugins/map/service.test.js"],"sourcesContent":["import Boom from '@hapi/boom'\n\nimport * as service from '~/src/server/plugins/map/service.js'\nimport { result as findResult } from '~/src/server/plugins/map/test/__stubs__/find.js'\nimport { getJson } from '~/src/server/services/httpService.js'\n\njest.mock('~/src/server/services/httpService.ts')\n\ndescribe('Maps service', () => {\n describe('find', () => {\n it('should return entires', async () => {\n jest.mocked(getJson).mockResolvedValueOnce({\n res: /** @type {IncomingMessage} */ ({\n statusCode: 200,\n headers: {}\n }),\n payload: findResult,\n error: undefined\n })\n\n const { results } = await service.find('NW1 6XE', 'apikey')\n\n expect(results).toHaveLength(8)\n expect(results.at(1)).toEqual({\n GAZETTEER_ENTRY: {\n ID: 'NW26XE',\n NAMES_URI: 'http://data.ordnancesurvey.co.uk/id/postcodeunit/NW26XE',\n NAME1: 'NW2 6XE',\n TYPE: 'other',\n LOCAL_TYPE: 'Postcode',\n GEOMETRY_X: 523065,\n GEOMETRY_Y: 185795,\n MOST_DETAIL_VIEW_RES: 3500,\n LEAST_DETAIL_VIEW_RES: 18000,\n POPULATED_PLACE: 'London',\n POPULATED_PLACE_URI:\n 'http://data.ordnancesurvey.co.uk/id/4000000074813508',\n POPULATED_PLACE_TYPE:\n 'http://www.ordnancesurvey.co.uk/xml/codelists/localtype.xml#city',\n DISTRICT_BOROUGH: 'Brent',\n DISTRICT_BOROUGH_URI:\n 'http://data.ordnancesurvey.co.uk/id/7000000000011447',\n DISTRICT_BOROUGH_TYPE:\n 'http://data.ordnancesurvey.co.uk/ontology/admingeo/LondonBorough',\n COUNTY_UNITARY: 'Greater London',\n COUNTY_UNITARY_URI:\n 'http://data.ordnancesurvey.co.uk/id/7000000000041441',\n COUNTY_UNITARY_TYPE:\n 'http://data.ordnancesurvey.co.uk/ontology/admingeo/GreaterLondonAuthority',\n REGION: 'London',\n REGION_URI: 'http://data.ordnancesurvey.co.uk/id/7000000000041428',\n COUNTRY: 'England',\n COUNTRY_URI: 'http://data.ordnancesurvey.co.uk/id/country/england'\n }\n })\n })\n\n it('should return an empty response when an error is encountered', async () => {\n jest.mocked(getJson).mockResolvedValueOnce({\n res: /** @type {IncomingMessage} */ ({\n statusCode: 300,\n headers: {}\n }),\n payload: undefined,\n error: new Error('Unknown error')\n })\n\n const { results } = await service.find('NW1 6XE', 'apikey')\n\n expect(results).toHaveLength(0)\n expect(results).toEqual([])\n })\n\n it('should return an empty response when a non 200 response is encountered', async () => {\n jest\n .mocked(getJson)\n .mockRejectedValueOnce(\n Boom.badRequest(\n 'OS API error',\n new Error('Invalid postcode segments')\n )\n )\n\n const { results } = await service.find('invalid postcode', 'apikey')\n\n expect(results).toHaveLength(0)\n expect(results).toEqual([])\n })\n })\n})\n\n/**\n * @import { IncomingMessage } from 'node:http'\n */\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -3,5 +3,5 @@
|
|
|
3
3
|
* @this {NunjucksContext}
|
|
4
4
|
* @param {string} name - The name of the component
|
|
5
5
|
*/
|
|
6
|
-
export function field(this: NunjucksContext, name: string): import("../../engine/components/TextField.js").TextField | import("../../engine/components/SelectField.js").SelectField | import("../../engine/components/RadiosField.js").RadiosField | import("../../engine/components/YesNoField.js").YesNoField | import("../../engine/components/CheckboxesField.js").CheckboxesField | import("../../engine/components/DatePartsField.js").DatePartsField | import("../../engine/components/DeclarationField.js").DeclarationField | import("../../engine/components/EastingNorthingField.js").EastingNorthingField | import("../../engine/components/EmailAddressField.js").EmailAddressField | import("../../engine/components/LatLongField.js").LatLongField | import("../../engine/components/MonthYearField.js").MonthYearField | import("../../engine/components/MultilineTextField.js").MultilineTextField | import("../../engine/components/NationalGridFieldNumberField.js").NationalGridFieldNumberField | import("../../engine/components/NumberField.js").NumberField | import("../../engine/components/OsGridRefField.js").OsGridRefField | import("../../engine/components/TelephoneNumberField.js").TelephoneNumberField | import("../../engine/components/UkAddressField.js").UkAddressField | import("../../engine/components/FileUploadField.js").FileUploadField | import("../../engine/components/HiddenField.js").HiddenField | import("../../engine/components/PaymentField.js").PaymentField | import("../../engine/components/GeospatialField.js").GeospatialField | import("../../engine/components/Details.js").Details | import("../../engine/components/Html.js").Html | import("../../engine/components/InsetText.js").InsetText | import("../../engine/components/List.js").List | import("../../engine/components/Markdown.js").Markdown | undefined;
|
|
6
|
+
export function field(this: NunjucksContext, name: string): import("../../engine/components/TextField.js").TextField | import("../../engine/components/SelectField.js").SelectField | import("../../engine/components/RadiosField.js").RadiosField | import("../../engine/components/YesNoField.js").YesNoField | import("../../engine/components/CheckboxesField.js").CheckboxesField | import("../../engine/components/DatePartsField.js").DatePartsField | import("../../engine/components/DeclarationField.js").DeclarationField | import("../../engine/components/EastingNorthingField.js").EastingNorthingField | import("../../engine/components/EmailAddressField.js").EmailAddressField | import("../../engine/components/LatLongField.js").LatLongField | import("../../engine/components/MonthYearField.js").MonthYearField | import("../../engine/components/MultilineTextField.js").MultilineTextField | import("../../engine/components/NationalGridFieldNumberField.js").NationalGridFieldNumberField | import("../../engine/components/NumberField.js").NumberField | import("../../engine/components/OsGridRefField.js").OsGridRefField | import("../../engine/components/TelephoneNumberField.js").TelephoneNumberField | import("../../engine/components/UkAddressField.js").UkAddressField | import("../../engine/components/FileUploadField.js").FileUploadField | import("../../engine/components/HiddenField.js").HiddenField | import("../../engine/components/PaymentField.js").PaymentField | import("../../engine/components/GeospatialField.js").GeospatialField | import("../../engine/components/Details.js").Details | import("../../engine/components/Html.js").Html | import("../../engine/components/InsetText.js").InsetText | import("../../engine/components/List.js").List | import("../../engine/components/Markdown.js").Markdown | import("../../engine/components/NotificationBanner.js").NotificationBanner | undefined;
|
|
7
7
|
import type { NunjucksContext } from '../../../../server/plugins/nunjucks/types.js';
|