@defra/forms-engine-plugin 4.13.0 → 4.14.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/javascripts/shared.min.js +1 -1
- package/.public/javascripts/shared.min.js.map +1 -1
- package/.server/client/javascripts/geospatial-map.d.ts +14 -0
- package/.server/client/javascripts/geospatial-map.js +161 -70
- package/.server/client/javascripts/geospatial-map.js.map +1 -1
- package/.server/client/javascripts/map.d.ts +6 -0
- package/.server/client/javascripts/map.js +5 -0
- package/.server/client/javascripts/map.js.map +1 -1
- package/.server/client/javascripts/utils.d.ts +7 -0
- package/.server/client/javascripts/utils.js +21 -0
- package/.server/client/javascripts/utils.js.map +1 -0
- package/.server/server/forms/simple-form.yaml +9 -0
- package/.server/server/plugins/engine/components/GeospatialField.d.ts +1 -0
- package/.server/server/plugins/engine/components/GeospatialField.js +9 -5
- package/.server/server/plugins/engine/components/GeospatialField.js.map +1 -1
- package/.server/server/plugins/engine/components/helpers/geospatial.d.ts +2 -2
- package/.server/server/plugins/engine/components/helpers/geospatial.js +32 -5
- package/.server/server/plugins/engine/components/helpers/geospatial.js.map +1 -1
- package/.server/server/plugins/engine/components/helpers/geospatial.test.js +37 -6
- package/.server/server/plugins/engine/components/helpers/geospatial.test.js.map +1 -1
- package/.server/server/plugins/engine/pageControllers/validationOptions.js +4 -1
- package/.server/server/plugins/engine/pageControllers/validationOptions.js.map +1 -1
- package/.server/server/plugins/engine/views/components/geospatialfield.html +1 -1
- package/package.json +2 -2
- package/src/client/javascripts/geospatial-map.js +159 -53
- package/src/client/javascripts/map.js +5 -0
- package/src/client/javascripts/utils.js +23 -0
- package/src/server/forms/simple-form.yaml +9 -0
- package/src/server/plugins/engine/components/GeospatialField.ts +11 -7
- package/src/server/plugins/engine/components/helpers/geospatial.ts +49 -11
- package/src/server/plugins/engine/pageControllers/validationOptions.ts +4 -1
- package/src/server/plugins/engine/views/components/geospatialfield.html +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"map.js","names":["centroid","OsGridRef","LatLon","processGeospatial","processLocation","DEFAULT_LAT","DEFAULT_LONG","COMPANY_SYMBOL_CODE","defaultData","VTS_OUTDOOR_URL","VTS_DARK_URL","VTS_BLACK_AND_WHITE_URL","VTS_AERIAL_URL","latLongToEastingNorthing","lat","long","point","toOsGrid","eastingNorthingToLatLong","easting","northing","latLong","toLatLon","latitude","longitude","latLongToOsGridRef","toString","osGridRefToLatLong","osGridRef","parse","getCoordinateGridRef","feature","geometry","type","coordinates","getCentroidGridRef","centre","defaultConfig","zoom","center","EVENTS","mapReady","interactMarkerChange","drawReady","drawCreated","drawEdited","drawCancelled","formSubmitFactory","buttons","onFormSubmit","e","submitter","HTMLButtonElement","includes","preventDefault","initMaps","config","assetPath","apiPath","data","locations","document","querySelectorAll","geospatials","length","form","closest","Array","from","addEventListener","forEach","location","index","geospatial","makeTileRequestTransformer","transformTileRequest","url","resourceType","startsWith","replace","window","origin","headers","encodeURIComponent","spritesPath","path","substring","createMap","mapId","initConfig","mapsConfig","logoAltText","defra","interactPlugin","markerColor","outdoor","dark","interactionModes","multiSelect","map","InteractiveMap","enableFullscreen","autoColorScheme","mapProvider","maplibreProvider","reverseGeocodeProvider","openNamesProvider","behaviour","minZoom","maxZoom","containerHeight","enableZoomControls","transformRequest","plugins","mapStylesPlugin","mapStyles","id","label","thumbnail","logo","attribution","String","fromCodePoint","Date","getFullYear","backgroundColor","mapColorScheme","appColorScheme","searchPlugin","osNamesURL","width","showMarker","scaleBarPlugin","units","centerMap","addMarker","flyTo","essential"],"sources":["../../../src/client/javascripts/map.js"],"sourcesContent":["import { centroid } from '@turf/centroid'\n// @ts-expect-error - no types\nimport OsGridRef, { LatLon } from 'geodesy/osgridref.js'\n\nimport { processGeospatial } from '~/src/client/javascripts/geospatial-map.js'\nimport { processLocation } from '~/src/client/javascripts/location-map.js'\n\n// Center of UK\nconst DEFAULT_LAT = 53.825564\nconst DEFAULT_LONG = -2.421975\nconst COMPANY_SYMBOL_CODE = 169\n\nconst defaultData = {\n VTS_OUTDOOR_URL: '/api/maps/vts/OS_VTS_3857_Outdoor.json',\n VTS_DARK_URL: '/api/maps/vts/OS_VTS_3857_Dark.json',\n VTS_BLACK_AND_WHITE_URL: '/api/maps/vts/OS_VTS_3857_Black_and_White.json',\n VTS_AERIAL_URL: '/api/maps/vts/esri-aerial.json'\n}\n\n/**\n * Converts lat long to easting and northing\n * @param {object} param\n * @param {number} param.lat\n * @param {number} param.long\n * @returns {{ easting: number, northing: number }}\n */\nexport function latLongToEastingNorthing({ lat, long }) {\n const point = new LatLon(lat, long)\n\n return point.toOsGrid()\n}\n\n/**\n * Converts easting and northing to lat long\n * @param {object} param\n * @param {number} param.easting\n * @param {number} param.northing\n * @returns {{ lat: number, long: number }}\n */\nexport function eastingNorthingToLatLong({ easting, northing }) {\n const point = new OsGridRef(easting, northing)\n const latLong = point.toLatLon()\n\n return { lat: latLong.latitude, long: latLong.longitude }\n}\n\n/**\n * Converts lat long to an ordnance survey grid reference\n * @param {object} param\n * @param {number} param.lat\n * @param {number} param.long\n * @returns {string}\n */\nexport function latLongToOsGridRef({ lat, long }) {\n const point = new LatLon(lat, long)\n\n return point.toOsGrid().toString()\n}\n\n/**\n * Converts an ordnance survey grid reference to lat long\n * @param {string} osGridRef\n * @returns {{ lat: number, long: number }}\n */\nexport function osGridRefToLatLong(osGridRef) {\n const point = OsGridRef.parse(osGridRef)\n const latLong = point.toLatLon()\n\n return { lat: latLong.latitude, long: latLong.longitude }\n}\n\n/**\n * Get the grid ref from the first coordinate of a long/lat feature\n * @param {Feature} feature\n */\nexport function getCoordinateGridRef(feature) {\n if (feature.geometry.type === 'Point') {\n const [long, lat] = feature.geometry.coordinates\n const point = new LatLon(lat, long)\n\n return point.toOsGrid().toString()\n } else if (feature.geometry.type === 'LineString') {\n const [long, lat] = feature.geometry.coordinates[0]\n const point = new LatLon(lat, long)\n\n return point.toOsGrid().toString()\n } else {\n const [long, lat] = feature.geometry.coordinates[0][0]\n const point = new LatLon(lat, long)\n\n return point.toOsGrid().toString()\n }\n}\n\n/**\n * Get the centroid grid ref from a long/lat feature\n * @param {Feature} feature\n */\nexport function getCentroidGridRef(feature) {\n if (feature.geometry.type === 'Point') {\n const [long, lat] = feature.geometry.coordinates\n const point = new LatLon(lat, long)\n\n return point.toOsGrid().toString()\n } else {\n const centre = centroid(feature)\n const [long, lat] = centre.geometry.coordinates\n const point = new LatLon(lat, long)\n\n return point.toOsGrid().toString()\n }\n}\n\n/** @type {InteractiveMapInitConfig} */\nexport const defaultConfig = {\n zoom: '6',\n center: [DEFAULT_LONG, DEFAULT_LAT]\n}\n\nexport const EVENTS = {\n mapReady: 'map:ready',\n interactMarkerChange: 'interact:markerchange',\n drawReady: 'draw:ready',\n drawCreated: 'draw:created',\n drawEdited: 'draw:edited',\n drawCancelled: 'draw:cancelled'\n}\n\n/**\n * Make a form submit handler that only allows submissions from allowed buttons\n * @param {HTMLButtonElement[]} buttons - the form buttons to allow submissions\n */\nexport function formSubmitFactory(buttons) {\n /**\n * The submit handler\n * @param {SubmitEvent} e\n */\n const onFormSubmit = function (e) {\n if (\n !(e.submitter instanceof HTMLButtonElement) ||\n !buttons.includes(e.submitter)\n ) {\n e.preventDefault()\n }\n }\n\n return onFormSubmit\n}\n\n/**\n * Initialise location maps\n * @param {Partial<MapsEnvironmentConfig>} config - the map configuration\n */\nexport function initMaps(config = {}) {\n const {\n assetPath = '/assets',\n apiPath = '/form/api',\n data = defaultData\n } = config\n const locations = document.querySelectorAll('.app-location-field')\n const geospatials = document.querySelectorAll('.app-geospatial-field')\n\n // TODO: Fix this in `interactive-map`\n // If there are location components on the page fix up the main form submit\n // handler so it doesn't fire when using the integrated map search feature\n if (locations.length) {\n const form = locations[0].closest('form')\n\n if (form === null) {\n return\n }\n\n const buttons = Array.from(form.querySelectorAll('button'))\n form.addEventListener('submit', formSubmitFactory(buttons), false)\n }\n\n if (geospatials.length) {\n const form = geospatials[0].closest('form')\n\n if (form === null) {\n return\n }\n\n const buttons = Array.from(form.querySelectorAll('button'))\n form.addEventListener('submit', formSubmitFactory(buttons), false)\n }\n\n locations.forEach((location, index) => {\n processLocation({ assetPath, apiPath, data }, location, index)\n })\n\n geospatials.forEach((geospatial, index) => {\n processGeospatial({ assetPath, apiPath, data }, geospatial, index)\n })\n}\n\n/**\n * OS API request proxy factory\n * @param {string} apiPath - the root API path\n */\nexport function makeTileRequestTransformer(apiPath) {\n /**\n * Proxy OS API requests via our server\n * @param {string} url - the request URL\n * @param {string} resourceType - the resource type\n */\n return function transformTileRequest(url, resourceType) {\n if (url.startsWith('https://api.os.uk')) {\n if (resourceType === 'Tile') {\n return {\n url: url.replace(\n 'https://api.os.uk/maps/vector/v1/vts',\n `${window.location.origin}${apiPath}`\n ),\n headers: {}\n }\n }\n\n if (resourceType !== 'Style') {\n return {\n url: `${apiPath}/map-proxy?url=${encodeURIComponent(url)}`,\n headers: {}\n }\n }\n }\n\n const spritesPath =\n 'https://raw.githubusercontent.com/OrdnanceSurvey/OS-Vector-Tile-API-Stylesheets/main'\n\n // Proxy sprite requests\n if (url.startsWith(spritesPath)) {\n const path = url.substring(spritesPath.length)\n return {\n url: `${apiPath}/maps/vts${path}`,\n headers: {}\n }\n }\n\n return { url, headers: {} }\n }\n}\n\n/**\n * Create a Defra map instance\n * @param {string} mapId - the map id\n * @param {InteractiveMapInitConfig} initConfig - the map initial configuration\n * @param {MapsEnvironmentConfig} mapsConfig - the map environment params\n */\nexport function createMap(mapId, initConfig, mapsConfig) {\n const { assetPath, apiPath, data = defaultData } = mapsConfig\n const logoAltText = 'Ordnance survey logo'\n\n // @ts-expect-error - Defra namespace currently comes from UMD support files\n const defra = window.defra\n\n const interactPlugin = defra.interactPlugin({\n markerColor: { outdoor: '#ff0000', dark: '#00ff00' },\n interactionModes: ['placeMarker'],\n multiSelect: false\n })\n\n /** @type {InteractiveMap} */\n const map = new defra.InteractiveMap(mapId, {\n enableFullscreen: true,\n autoColorScheme: false,\n mapProvider: defra.maplibreProvider(),\n reverseGeocodeProvider: defra.openNamesProvider({\n url: `${apiPath}/reverse-geocode-proxy?easting={easting}&northing={northing}`\n }),\n behaviour: 'inline',\n minZoom: 6,\n maxZoom: 18,\n containerHeight: '400px',\n enableZoomControls: true,\n transformRequest: makeTileRequestTransformer(apiPath),\n ...initConfig,\n plugins: [\n defra.mapStylesPlugin({\n mapStyles: [\n {\n id: 'outdoor',\n label: 'Outdoor',\n url: data.VTS_OUTDOOR_URL,\n thumbnail: `${assetPath}/interactive-map/assets/images/outdoor-map-thumb.jpg`,\n logo: `${assetPath}/interactive-map/assets/images/os-logo.svg`,\n logoAltText,\n attribution: `Contains OS data ${String.fromCodePoint(COMPANY_SYMBOL_CODE)} Crown copyright and database rights ${new Date().getFullYear()}`,\n backgroundColor: '#f5f5f0'\n },\n {\n id: 'dark',\n label: 'Dark',\n url: data.VTS_DARK_URL,\n mapColorScheme: 'dark',\n appColorScheme: 'dark',\n thumbnail: `${assetPath}/interactive-map/assets/images/dark-map-thumb.jpg`,\n logo: `${assetPath}/interactive-map/assets/images/os-logo-white.svg`,\n logoAltText,\n attribution: `Contains OS data ${String.fromCodePoint(COMPANY_SYMBOL_CODE)} Crown copyright and database rights ${new Date().getFullYear()}`\n },\n {\n id: 'black-and-white',\n label: 'Black/White',\n url: data.VTS_BLACK_AND_WHITE_URL,\n thumbnail: `${assetPath}/interactive-map/assets/images/black-and-white-map-thumb.jpg`,\n logo: `${assetPath}/interactive-map/assets/images/os-logo-black.svg`,\n logoAltText,\n attribution: `Contains OS data ${String.fromCodePoint(COMPANY_SYMBOL_CODE)} Crown copyright and database rights ${new Date().getFullYear()}`\n },\n {\n id: 'aerial',\n label: 'Aerial',\n url: data.VTS_AERIAL_URL,\n thumbnail: `${assetPath}/interactive-map/assets/images/aerial-map-thumb.jpg`,\n logo: `${assetPath}/interactive-map/assets/images/esri-logo.png`,\n logoAltText: 'Powered by Esri',\n attribution: `Tiles ${String.fromCodePoint(COMPANY_SYMBOL_CODE)} Esri — Source: Esri, Maxar, Earthstar Geographics, and the GIS User Community ${new Date().getFullYear()}`\n }\n ]\n }),\n interactPlugin,\n defra.searchPlugin({\n osNamesURL: `${apiPath}/geocode-proxy?query={query}`,\n width: '300px',\n showMarker: false\n }),\n defra.scaleBarPlugin({\n units: 'metric'\n }),\n ...(initConfig.plugins ?? [])\n ]\n })\n\n return { map, interactPlugin }\n}\n\n/**\n * Updates the marker position and moves the map view port the new location\n * @param {InteractiveMap} map - the map component instance (of InteractiveMap)\n * @param {MapLibreMap} mapProvider - the map provider instance (of MapLibreMap)\n * @param {MapCenter} center - the point\n */\nexport function centerMap(map, mapProvider, center) {\n // Move the 'location' marker to the new point\n map.addMarker('location', center)\n\n // Pan & zoom the map to the new valid location\n mapProvider.flyTo({\n center,\n zoom: 14,\n essential: true\n })\n}\n\n/**\n * @typedef {object} InteractiveMap - an instance of a InteractiveMap\n * @property {Function} on - register callback listeners to map events\n * @property {Function} addPanel - adds a new panel to the map\n * @property {Function} addMarker - adds/updates a marker\n * @property {Function} removeMarker - removes a marker\n * @property {Function} addButton - adds/updates a button\n * @property {Function} toggleButtonState - toggle the state of a button\n */\n\n/**\n * @typedef {object} MapLibreMap\n * @property {Function} flyTo - pans/zooms to a new location\n * @property {Function} fitBounds - fits the my to the new bounds\n */\n\n/**\n * @typedef {[number, number]} MapCenter - Map center point as [long, lat]\n */\n\n/**\n * @typedef {object} InteractiveMapInitConfig - additional config that can be provided to InteractiveMap\n * @property {string} zoom - the zoom level of the map\n * @property {MapCenter} center - the center point of the map\n * @property {{ id: string, coords: MapCenter }[]} [markers] - the markers to add to the map\n * @property {any[]} [plugins] - additional plugins\n */\n\n/**\n * @typedef {object} TileData\n * @property {string} VTS_OUTDOOR_URL - the outdoor tile URL\n * @property {string} VTS_DARK_URL - the dark tile URL\n * @property {string} VTS_BLACK_AND_WHITE_URL - the black and white tile URL\n * @property {string} VTS_AERIAL_URL - the aerial tile URL\n */\n\n/**\n * @typedef {object} MapsEnvironmentConfig\n * @property {string} assetPath - the root asset path\n * @property {string} apiPath - the root API path\n * @property {TileData} data - the tile data config\n */\n\n/**\n * @import { Feature } from '~/src/server/plugins/engine/types.js'\n */\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"map.js","names":["centroid","OsGridRef","LatLon","processGeospatial","processLocation","DEFAULT_LAT","DEFAULT_LONG","COMPANY_SYMBOL_CODE","defaultData","VTS_OUTDOOR_URL","VTS_DARK_URL","VTS_BLACK_AND_WHITE_URL","VTS_AERIAL_URL","latLongToEastingNorthing","lat","long","point","toOsGrid","eastingNorthingToLatLong","easting","northing","latLong","toLatLon","latitude","longitude","latLongToOsGridRef","toString","osGridRefToLatLong","osGridRef","parse","getCoordinateGridRef","feature","geometry","type","coordinates","getCentroidGridRef","centre","defaultConfig","zoom","center","EVENTS","mapReady","interactMarkerChange","drawReady","drawCreated","drawEdited","drawCancelled","formSubmitFactory","buttons","onFormSubmit","e","submitter","HTMLButtonElement","includes","preventDefault","initMaps","config","assetPath","apiPath","data","locations","document","querySelectorAll","geospatials","length","form","closest","Array","from","addEventListener","forEach","location","index","geospatial","makeTileRequestTransformer","transformTileRequest","url","resourceType","startsWith","replace","window","origin","headers","encodeURIComponent","spritesPath","path","substring","createMap","mapId","initConfig","mapsConfig","logoAltText","defra","interactPlugin","markerColor","outdoor","dark","interactionModes","multiSelect","map","InteractiveMap","enableFullscreen","autoColorScheme","mapProvider","maplibreProvider","reverseGeocodeProvider","openNamesProvider","behaviour","minZoom","maxZoom","containerHeight","enableZoomControls","transformRequest","plugins","mapStylesPlugin","mapStyles","id","label","thumbnail","logo","attribution","String","fromCodePoint","Date","getFullYear","backgroundColor","mapColorScheme","appColorScheme","searchPlugin","osNamesURL","width","showMarker","scaleBarPlugin","units","centerMap","addMarker","flyTo","essential"],"sources":["../../../src/client/javascripts/map.js"],"sourcesContent":["import { centroid } from '@turf/centroid'\n// @ts-expect-error - no types\nimport OsGridRef, { LatLon } from 'geodesy/osgridref.js'\n\nimport { processGeospatial } from '~/src/client/javascripts/geospatial-map.js'\nimport { processLocation } from '~/src/client/javascripts/location-map.js'\n\n// Center of UK\nconst DEFAULT_LAT = 53.825564\nconst DEFAULT_LONG = -2.421975\nconst COMPANY_SYMBOL_CODE = 169\n\nconst defaultData = {\n VTS_OUTDOOR_URL: '/api/maps/vts/OS_VTS_3857_Outdoor.json',\n VTS_DARK_URL: '/api/maps/vts/OS_VTS_3857_Dark.json',\n VTS_BLACK_AND_WHITE_URL: '/api/maps/vts/OS_VTS_3857_Black_and_White.json',\n VTS_AERIAL_URL: '/api/maps/vts/esri-aerial.json'\n}\n\n/**\n * Converts lat long to easting and northing\n * @param {object} param\n * @param {number} param.lat\n * @param {number} param.long\n * @returns {{ easting: number, northing: number }}\n */\nexport function latLongToEastingNorthing({ lat, long }) {\n const point = new LatLon(lat, long)\n\n return point.toOsGrid()\n}\n\n/**\n * Converts easting and northing to lat long\n * @param {object} param\n * @param {number} param.easting\n * @param {number} param.northing\n * @returns {{ lat: number, long: number }}\n */\nexport function eastingNorthingToLatLong({ easting, northing }) {\n const point = new OsGridRef(easting, northing)\n const latLong = point.toLatLon()\n\n return { lat: latLong.latitude, long: latLong.longitude }\n}\n\n/**\n * Converts lat long to an ordnance survey grid reference\n * @param {object} param\n * @param {number} param.lat\n * @param {number} param.long\n * @returns {string}\n */\nexport function latLongToOsGridRef({ lat, long }) {\n const point = new LatLon(lat, long)\n\n return point.toOsGrid().toString()\n}\n\n/**\n * Converts an ordnance survey grid reference to lat long\n * @param {string} osGridRef\n * @returns {{ lat: number, long: number }}\n */\nexport function osGridRefToLatLong(osGridRef) {\n const point = OsGridRef.parse(osGridRef)\n const latLong = point.toLatLon()\n\n return { lat: latLong.latitude, long: latLong.longitude }\n}\n\n/**\n * Get the grid ref from the first coordinate of a long/lat feature\n * @param {Feature} feature\n */\nexport function getCoordinateGridRef(feature) {\n if (feature.geometry.type === 'Point') {\n const [long, lat] = feature.geometry.coordinates\n const point = new LatLon(lat, long)\n\n return point.toOsGrid().toString()\n } else if (feature.geometry.type === 'LineString') {\n const [long, lat] = feature.geometry.coordinates[0]\n const point = new LatLon(lat, long)\n\n return point.toOsGrid().toString()\n } else {\n const [long, lat] = feature.geometry.coordinates[0][0]\n const point = new LatLon(lat, long)\n\n return point.toOsGrid().toString()\n }\n}\n\n/**\n * Get the centroid grid ref from a long/lat feature\n * @param {Feature} feature\n */\nexport function getCentroidGridRef(feature) {\n if (feature.geometry.type === 'Point') {\n const [long, lat] = feature.geometry.coordinates\n const point = new LatLon(lat, long)\n\n return point.toOsGrid().toString()\n } else {\n const centre = centroid(feature)\n const [long, lat] = centre.geometry.coordinates\n const point = new LatLon(lat, long)\n\n return point.toOsGrid().toString()\n }\n}\n\n/** @type {InteractiveMapInitConfig} */\nexport const defaultConfig = {\n zoom: '6',\n center: [DEFAULT_LONG, DEFAULT_LAT]\n}\n\nexport const EVENTS = {\n mapReady: 'map:ready',\n interactMarkerChange: 'interact:markerchange',\n drawReady: 'draw:ready',\n drawCreated: 'draw:created',\n drawEdited: 'draw:edited',\n drawCancelled: 'draw:cancelled'\n}\n\n/**\n * Make a form submit handler that only allows submissions from allowed buttons\n * @param {HTMLButtonElement[]} buttons - the form buttons to allow submissions\n */\nexport function formSubmitFactory(buttons) {\n /**\n * The submit handler\n * @param {SubmitEvent} e\n */\n const onFormSubmit = function (e) {\n if (\n !(e.submitter instanceof HTMLButtonElement) ||\n !buttons.includes(e.submitter)\n ) {\n e.preventDefault()\n }\n }\n\n return onFormSubmit\n}\n\n/**\n * Initialise location maps\n * @param {Partial<MapsEnvironmentConfig>} config - the map configuration\n */\nexport function initMaps(config = {}) {\n const {\n assetPath = '/assets',\n apiPath = '/form/api',\n data = defaultData\n } = config\n const locations = document.querySelectorAll('.app-location-field')\n const geospatials = document.querySelectorAll('.app-geospatial-field')\n\n // TODO: Fix this in `interactive-map`\n // If there are location components on the page fix up the main form submit\n // handler so it doesn't fire when using the integrated map search feature\n if (locations.length) {\n const form = locations[0].closest('form')\n\n if (form === null) {\n return\n }\n\n const buttons = Array.from(form.querySelectorAll('button'))\n form.addEventListener('submit', formSubmitFactory(buttons), false)\n }\n\n if (geospatials.length) {\n const form = geospatials[0].closest('form')\n\n if (form === null) {\n return\n }\n\n const buttons = Array.from(form.querySelectorAll('button'))\n form.addEventListener('submit', formSubmitFactory(buttons), false)\n }\n\n locations.forEach((location, index) => {\n processLocation({ assetPath, apiPath, data }, location, index)\n })\n\n geospatials.forEach((geospatial, index) => {\n processGeospatial({ assetPath, apiPath, data }, geospatial, index)\n })\n}\n\n/**\n * OS API request proxy factory\n * @param {string} apiPath - the root API path\n */\nexport function makeTileRequestTransformer(apiPath) {\n /**\n * Proxy OS API requests via our server\n * @param {string} url - the request URL\n * @param {string} resourceType - the resource type\n */\n return function transformTileRequest(url, resourceType) {\n if (url.startsWith('https://api.os.uk')) {\n if (resourceType === 'Tile') {\n return {\n url: url.replace(\n 'https://api.os.uk/maps/vector/v1/vts',\n `${window.location.origin}${apiPath}`\n ),\n headers: {}\n }\n }\n\n if (resourceType !== 'Style') {\n return {\n url: `${apiPath}/map-proxy?url=${encodeURIComponent(url)}`,\n headers: {}\n }\n }\n }\n\n const spritesPath =\n 'https://raw.githubusercontent.com/OrdnanceSurvey/OS-Vector-Tile-API-Stylesheets/main'\n\n // Proxy sprite requests\n if (url.startsWith(spritesPath)) {\n const path = url.substring(spritesPath.length)\n return {\n url: `${apiPath}/maps/vts${path}`,\n headers: {}\n }\n }\n\n return { url, headers: {} }\n }\n}\n\n/**\n * Create a Defra map instance\n * @param {string} mapId - the map id\n * @param {InteractiveMapInitConfig} initConfig - the map initial configuration\n * @param {MapsEnvironmentConfig} mapsConfig - the map environment params\n */\nexport function createMap(mapId, initConfig, mapsConfig) {\n const { assetPath, apiPath, data = defaultData } = mapsConfig\n const logoAltText = 'Ordnance survey logo'\n\n // @ts-expect-error - Defra namespace currently comes from UMD support files\n const defra = window.defra\n\n const interactPlugin = defra.interactPlugin({\n markerColor: { outdoor: '#ff0000', dark: '#00ff00' },\n interactionModes: ['placeMarker'],\n multiSelect: false\n })\n\n /** @type {InteractiveMap} */\n const map = new defra.InteractiveMap(mapId, {\n enableFullscreen: true,\n autoColorScheme: false,\n mapProvider: defra.maplibreProvider(),\n reverseGeocodeProvider: defra.openNamesProvider({\n url: `${apiPath}/reverse-geocode-proxy?easting={easting}&northing={northing}`\n }),\n behaviour: 'inline',\n minZoom: 6,\n maxZoom: 18,\n containerHeight: '400px',\n enableZoomControls: true,\n transformRequest: makeTileRequestTransformer(apiPath),\n ...initConfig,\n plugins: [\n defra.mapStylesPlugin({\n mapStyles: [\n {\n id: 'outdoor',\n label: 'Outdoor',\n url: data.VTS_OUTDOOR_URL,\n thumbnail: `${assetPath}/interactive-map/assets/images/outdoor-map-thumb.jpg`,\n logo: `${assetPath}/interactive-map/assets/images/os-logo.svg`,\n logoAltText,\n attribution: `Contains OS data ${String.fromCodePoint(COMPANY_SYMBOL_CODE)} Crown copyright and database rights ${new Date().getFullYear()}`,\n backgroundColor: '#f5f5f0'\n },\n {\n id: 'dark',\n label: 'Dark',\n url: data.VTS_DARK_URL,\n mapColorScheme: 'dark',\n appColorScheme: 'dark',\n thumbnail: `${assetPath}/interactive-map/assets/images/dark-map-thumb.jpg`,\n logo: `${assetPath}/interactive-map/assets/images/os-logo-white.svg`,\n logoAltText,\n attribution: `Contains OS data ${String.fromCodePoint(COMPANY_SYMBOL_CODE)} Crown copyright and database rights ${new Date().getFullYear()}`\n },\n {\n id: 'black-and-white',\n label: 'Black/White',\n url: data.VTS_BLACK_AND_WHITE_URL,\n thumbnail: `${assetPath}/interactive-map/assets/images/black-and-white-map-thumb.jpg`,\n logo: `${assetPath}/interactive-map/assets/images/os-logo-black.svg`,\n logoAltText,\n attribution: `Contains OS data ${String.fromCodePoint(COMPANY_SYMBOL_CODE)} Crown copyright and database rights ${new Date().getFullYear()}`\n },\n {\n id: 'aerial',\n label: 'Aerial',\n url: data.VTS_AERIAL_URL,\n thumbnail: `${assetPath}/interactive-map/assets/images/aerial-map-thumb.jpg`,\n logo: `${assetPath}/interactive-map/assets/images/esri-logo.png`,\n logoAltText: 'Powered by Esri',\n attribution: `Tiles ${String.fromCodePoint(COMPANY_SYMBOL_CODE)} Esri — Source: Esri, Maxar, Earthstar Geographics, and the GIS User Community ${new Date().getFullYear()}`\n }\n ]\n }),\n interactPlugin,\n defra.searchPlugin({\n osNamesURL: `${apiPath}/geocode-proxy?query={query}`,\n width: '300px',\n showMarker: false\n }),\n defra.scaleBarPlugin({\n units: 'metric'\n }),\n ...(initConfig.plugins ?? [])\n ]\n })\n\n return { map, interactPlugin }\n}\n\n/**\n * Updates the marker position and moves the map view port the new location\n * @param {InteractiveMap} map - the map component instance (of InteractiveMap)\n * @param {MapLibreMap} mapProvider - the map provider instance (of MapLibreMap)\n * @param {MapCenter} center - the point\n */\nexport function centerMap(map, mapProvider, center) {\n // Move the 'location' marker to the new point\n map.addMarker('location', center)\n\n // Pan & zoom the map to the new valid location\n mapProvider.flyTo({\n center,\n zoom: 14,\n essential: true\n })\n}\n\n/**\n * @typedef {object} InteractiveMap - an instance of a InteractiveMap\n * @property {Function} on - register callback listeners to map events\n * @property {Function} addPanel - adds a new panel to the map\n * @property {Function} addMarker - adds/updates a marker\n * @property {Function} removeMarker - removes a marker\n * @property {Function} addButton - adds/updates a button\n * @property {Function} toggleButtonState - toggle the state of a button\n */\n\n/**\n * @typedef {object} MapLibreMap\n * @property {Function} flyTo - pans/zooms to a new location\n * @property {Function} fitBounds - fits the my to the new bounds\n */\n\n/**\n * @typedef {[number, number]} MapCenter - Map center point as [long, lat]\n */\n\n/**\n * @typedef {object} InteractiveMapInitConfig - additional config that can be provided to InteractiveMap\n * @property {string} zoom - the zoom level of the map\n * @property {MapCenter} center - the center point of the map\n * @property {{ id: string, coords: MapCenter }[]} [markers] - the markers to add to the map\n * @property {any[]} [plugins] - additional plugins\n */\n\n/**\n * @typedef {object} TileData\n * @property {string} VTS_OUTDOOR_URL - the outdoor tile URL\n * @property {string} VTS_DARK_URL - the dark tile URL\n * @property {string} VTS_BLACK_AND_WHITE_URL - the black and white tile URL\n * @property {string} VTS_AERIAL_URL - the aerial tile URL\n */\n\n/**\n * @typedef {object} MapsEnvironmentConfig\n * @property {string} assetPath - the root asset path\n * @property {string} apiPath - the root API path\n * @property {TileData} data - the tile data config\n */\n\n/**\n * @typedef {object} UIManagerOptions\n * @property {string} [geometryTypes] - the CSV list of geometry types that a user can create\n */\n\n/**\n * @import { Feature } from '~/src/server/plugins/engine/types.js'\n */\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Builds a text representation of a list in the form 'a, b, c, d or e'
|
|
3
|
+
* @param {string[]} items
|
|
4
|
+
* @param {string} separator
|
|
5
|
+
* @param {string} lastSpearator
|
|
6
|
+
*/
|
|
7
|
+
export function formatDelimtedList(items: string[], separator: string, lastSpearator: string): string;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Builds a text representation of a list in the form 'a, b, c, d or e'
|
|
3
|
+
* @param {string[]} items
|
|
4
|
+
* @param {string} separator
|
|
5
|
+
* @param {string} lastSpearator
|
|
6
|
+
*/
|
|
7
|
+
export function formatDelimtedList(items, separator, lastSpearator) {
|
|
8
|
+
if (items.length === 0) {
|
|
9
|
+
return '';
|
|
10
|
+
}
|
|
11
|
+
if (items.length === 1) {
|
|
12
|
+
return items[0];
|
|
13
|
+
}
|
|
14
|
+
if (items.length === 2) {
|
|
15
|
+
return `${items[0]} ${lastSpearator} ${items[1]}`;
|
|
16
|
+
}
|
|
17
|
+
const last = items.pop();
|
|
18
|
+
const separatorAndSpace = `${separator} `;
|
|
19
|
+
return `${items.join(separatorAndSpace)} ${lastSpearator} ${last}`;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","names":["formatDelimtedList","items","separator","lastSpearator","length","last","pop","separatorAndSpace","join"],"sources":["../../../src/client/javascripts/utils.js"],"sourcesContent":["/**\n * Builds a text representation of a list in the form 'a, b, c, d or e'\n * @param {string[]} items\n * @param {string} separator\n * @param {string} lastSpearator\n */\nexport function formatDelimtedList(items, separator, lastSpearator) {\n if (items.length === 0) {\n return ''\n }\n\n if (items.length === 1) {\n return items[0]\n }\n\n if (items.length === 2) {\n return `${items[0]} ${lastSpearator} ${items[1]}`\n }\n\n const last = items.pop()\n const separatorAndSpace = `${separator} `\n return `${items.join(separatorAndSpace)} ${lastSpearator} ${last}`\n}\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASA,kBAAkBA,CAACC,KAAK,EAAEC,SAAS,EAAEC,aAAa,EAAE;EAClE,IAAIF,KAAK,CAACG,MAAM,KAAK,CAAC,EAAE;IACtB,OAAO,EAAE;EACX;EAEA,IAAIH,KAAK,CAACG,MAAM,KAAK,CAAC,EAAE;IACtB,OAAOH,KAAK,CAAC,CAAC,CAAC;EACjB;EAEA,IAAIA,KAAK,CAACG,MAAM,KAAK,CAAC,EAAE;IACtB,OAAO,GAAGH,KAAK,CAAC,CAAC,CAAC,IAAIE,aAAa,IAAIF,KAAK,CAAC,CAAC,CAAC,EAAE;EACnD;EAEA,MAAMI,IAAI,GAAGJ,KAAK,CAACK,GAAG,CAAC,CAAC;EACxB,MAAMC,iBAAiB,GAAG,GAAGL,SAAS,GAAG;EACzC,OAAO,GAAGD,KAAK,CAACO,IAAI,CAACD,iBAAiB,CAAC,IAAIJ,aAAa,IAAIE,IAAI,EAAE;AACpE","ignoreList":[]}
|
|
@@ -25,6 +25,15 @@ pages:
|
|
|
25
25
|
required: true
|
|
26
26
|
schema: {}
|
|
27
27
|
id: b68df7f1-d4f4-4c17-83c8-402f584906c9
|
|
28
|
+
- type: GeospatialField
|
|
29
|
+
title: Where do you live?
|
|
30
|
+
name: applicantLocation
|
|
31
|
+
shortDescription: Your location
|
|
32
|
+
hint: ''
|
|
33
|
+
options:
|
|
34
|
+
required: true
|
|
35
|
+
schema: {}
|
|
36
|
+
id: e18116e0-7c3e-416a-af42-6f229017c5b1
|
|
28
37
|
next: []
|
|
29
38
|
id: 622a35ec-3795-418a-81f3-a45746959045
|
|
30
39
|
- title: Upload a copy of your passport
|
|
@@ -16,6 +16,7 @@ export declare class GeospatialField extends FormComponent {
|
|
|
16
16
|
getContextValueFromState(state: FormSubmissionState): string[] | null;
|
|
17
17
|
getViewModel(payload: FormPayload, errors?: FormSubmissionError[]): {
|
|
18
18
|
country: import("@defra/forms-model").GeospatialFieldOptionsCountry | undefined;
|
|
19
|
+
geometryTypes: import("@defra/forms-model").GeospatialFieldGeometryTypesEnum[] | undefined;
|
|
19
20
|
value: string;
|
|
20
21
|
label: {
|
|
21
22
|
text: string;
|
|
@@ -7,13 +7,16 @@ export class GeospatialField extends FormComponent {
|
|
|
7
7
|
const {
|
|
8
8
|
options
|
|
9
9
|
} = def;
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
}
|
|
10
|
+
const formSchema = getGeospatialSchema(def).label(this.label).messages({
|
|
11
|
+
'array.min': messageTemplate.featuresMin,
|
|
12
|
+
'array.max': messageTemplate.featuresMax,
|
|
13
|
+
'array.length': messageTemplate.featuresLength
|
|
14
|
+
});
|
|
15
15
|
this.formSchema = formSchema;
|
|
16
16
|
this.stateSchema = formSchema.default(null);
|
|
17
|
+
if (options.required === false) {
|
|
18
|
+
this.stateSchema = this.stateSchema.allow(null);
|
|
19
|
+
}
|
|
17
20
|
this.options = options;
|
|
18
21
|
}
|
|
19
22
|
getFormValueFromState(state) {
|
|
@@ -51,6 +54,7 @@ export class GeospatialField extends FormComponent {
|
|
|
51
54
|
return {
|
|
52
55
|
...viewModel,
|
|
53
56
|
country: this.options.countries?.at(0),
|
|
57
|
+
geometryTypes: this.options.geometryTypes,
|
|
54
58
|
value
|
|
55
59
|
};
|
|
56
60
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GeospatialField.js","names":["FormComponent","isGeospatialState","getGeospatialSchema","messageTemplate","GeospatialField","constructor","def","props","options","formSchema","
|
|
1
|
+
{"version":3,"file":"GeospatialField.js","names":["FormComponent","isGeospatialState","getGeospatialSchema","messageTemplate","GeospatialField","constructor","def","props","options","formSchema","label","messages","featuresMin","featuresMax","featuresLength","stateSchema","default","required","allow","getFormValueFromState","state","name","getFormValue","value","isValue","undefined","getDisplayStringFromFormValue","features","length","unit","getDisplayStringFromState","getContextValueFromFormValue","map","id","getContextValueFromState","getViewModel","payload","errors","viewModel","JSON","stringify","country","countries","at","geometryTypes","getErrors","fieldErrors","forEach","err","href","path","text","Number","context","getViewErrors","getAllPossibleErrors","staticErrors","advancedSettingsErrors","baseErrors","type","template","selectRequired","format"],"sources":["../../../../../src/server/plugins/engine/components/GeospatialField.ts"],"sourcesContent":["import { type GeospatialFieldComponent } from '@defra/forms-model'\nimport { type ArraySchema } from 'joi'\n\nimport { type ComponentBase } from '~/src/server/plugins/engine/components/ComponentBase.js'\nimport {\n FormComponent,\n isGeospatialState\n} from '~/src/server/plugins/engine/components/FormComponent.js'\nimport { getGeospatialSchema } from '~/src/server/plugins/engine/components/helpers/geospatial.js'\nimport { messageTemplate } from '~/src/server/plugins/engine/pageControllers/validationOptions.js'\nimport {\n type ErrorMessageTemplateList,\n type FormPayload,\n type FormState,\n type FormStateValue,\n type FormSubmissionError,\n type FormSubmissionState,\n type GeospatialState\n} from '~/src/server/plugins/engine/types.js'\n\nexport class GeospatialField extends FormComponent {\n declare options: GeospatialFieldComponent['options']\n declare formSchema: ArraySchema<GeospatialState>\n declare stateSchema: ArraySchema<GeospatialState>\n\n constructor(\n def: GeospatialFieldComponent,\n props: ConstructorParameters<typeof ComponentBase>[1]\n ) {\n super(def, props)\n\n const { options } = def\n\n const formSchema = getGeospatialSchema(def)\n .label(this.label)\n .messages({\n 'array.min': messageTemplate.featuresMin as string,\n 'array.max': messageTemplate.featuresMax as string,\n 'array.length': messageTemplate.featuresLength as string\n })\n\n this.formSchema = formSchema\n this.stateSchema = formSchema.default(null)\n\n if (options.required === false) {\n this.stateSchema = this.stateSchema.allow(null)\n }\n\n this.options = options\n }\n\n getFormValueFromState(state: FormSubmissionState) {\n const { name } = this\n return this.getFormValue(state[name])\n }\n\n getFormValue(value?: FormStateValue | FormState) {\n return this.isValue(value) ? value : undefined\n }\n\n getDisplayStringFromFormValue(features: GeospatialState | undefined): string {\n if (!features?.length) {\n return ''\n }\n\n const unit = features.length === 1 ? 'location' : 'locations'\n\n return `Added ${features.length} ${unit}`\n }\n\n getDisplayStringFromState(state: FormSubmissionState) {\n const features = this.getFormValueFromState(state)\n\n return this.getDisplayStringFromFormValue(features)\n }\n\n getContextValueFromFormValue(\n features: GeospatialState | undefined\n ): string[] | null {\n return features?.map(({ id }) => id) ?? null\n }\n\n getContextValueFromState(state: FormSubmissionState) {\n const features = this.getFormValueFromState(state)\n\n return this.getContextValueFromFormValue(features)\n }\n\n getViewModel(payload: FormPayload, errors?: FormSubmissionError[]) {\n const viewModel = super.getViewModel(payload, errors)\n const value =\n typeof viewModel.value === 'string'\n ? viewModel.value\n : JSON.stringify(viewModel.value, null, 2)\n\n return {\n ...viewModel,\n country: this.options.countries?.at(0),\n geometryTypes: this.options.geometryTypes,\n value\n }\n }\n\n getErrors(errors?: FormSubmissionError[]): FormSubmissionError[] | undefined {\n const fieldErrors = super.getErrors(errors)\n\n fieldErrors?.forEach((err) => {\n if (err.name === 'description') {\n err.href = `#description_${err.path[1]}`\n err.text = `Enter description for location ${Number(err.path[1]) + 1}`\n } else if (typeof err.name === 'number' && err.context?.country) {\n err.href = `#description_${err.path[1]}`\n err.text = `Location ${Number(err.path[1]) + 1} must be in ${err.context.country}`\n }\n })\n\n return fieldErrors\n }\n\n getViewErrors(\n errors?: FormSubmissionError[]\n ): FormSubmissionError[] | undefined {\n return this.getErrors(errors)\n }\n\n isValue(value?: FormStateValue | FormState): value is GeospatialState {\n return isGeospatialState(value)\n }\n\n /**\n * For error preview page that shows all possible errors on a component\n */\n getAllPossibleErrors(): ErrorMessageTemplateList {\n const staticErrors = GeospatialField.getAllPossibleErrors()\n return {\n ...staticErrors,\n advancedSettingsErrors: [...staticErrors.advancedSettingsErrors]\n }\n }\n\n /**\n * Static version of getAllPossibleErrors that doesn't require a component instance.\n */\n static getAllPossibleErrors(): ErrorMessageTemplateList {\n return {\n baseErrors: [\n { type: 'required', template: messageTemplate.selectRequired },\n {\n type: 'array.min',\n template: '{{#title}} must contain at least 1 items'\n },\n { type: 'object.invalidjson', template: messageTemplate.format }\n ],\n advancedSettingsErrors: []\n }\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type GeospatialFieldComponent } from '@defra/forms-model';
|
|
2
2
|
import JoiBase from 'joi';
|
|
3
3
|
import { type Feature } from '../../../../../server/plugins/engine/types.js';
|
|
4
|
-
export declare function getGeospatialSchema(
|
|
4
|
+
export declare function getGeospatialSchema(def: GeospatialFieldComponent): JoiBase.ArraySchema<Feature[]>;
|
|
5
5
|
/**
|
|
6
6
|
* @import { CustomHelpers } from 'joi'
|
|
7
7
|
*/
|
|
@@ -19,7 +19,8 @@ const Joi = JoiBase.extend({
|
|
|
19
19
|
from: 'string',
|
|
20
20
|
method(value, helpers) {
|
|
21
21
|
if (typeof value === 'string') {
|
|
22
|
-
|
|
22
|
+
const trimmed = value.trim();
|
|
23
|
+
if (trimmed === '' || trimmed === '[]') {
|
|
23
24
|
return {
|
|
24
25
|
value: undefined
|
|
25
26
|
};
|
|
@@ -72,10 +73,36 @@ const featureSchema = Joi.object().keys({
|
|
|
72
73
|
properties: featurePropertiesSchema,
|
|
73
74
|
geometry: featureGeometrySchema
|
|
74
75
|
});
|
|
75
|
-
|
|
76
|
-
|
|
76
|
+
function applySchemaConstraints(schema, def) {
|
|
77
|
+
const {
|
|
78
|
+
options,
|
|
79
|
+
schema: constraints
|
|
80
|
+
} = def;
|
|
81
|
+
const isOptional = options.required === false;
|
|
82
|
+
if (typeof constraints?.length === 'number') {
|
|
83
|
+
schema = schema.length(constraints.length);
|
|
84
|
+
} else {
|
|
85
|
+
if (typeof constraints?.min === 'number') {
|
|
86
|
+
schema = schema.min(constraints.min);
|
|
87
|
+
} else if (!isOptional) {
|
|
88
|
+
schema = schema.min(1);
|
|
89
|
+
}
|
|
90
|
+
schema = schema.max(typeof constraints?.max === 'number' ? constraints.max : 50);
|
|
91
|
+
}
|
|
92
|
+
if (isOptional) {
|
|
93
|
+
schema = schema.optional();
|
|
94
|
+
} else {
|
|
95
|
+
schema = schema.required();
|
|
96
|
+
}
|
|
97
|
+
return schema;
|
|
98
|
+
}
|
|
99
|
+
export function getGeospatialSchema(def) {
|
|
100
|
+
const {
|
|
101
|
+
options = {}
|
|
102
|
+
} = def;
|
|
103
|
+
const country = options.countries?.at(0);
|
|
77
104
|
if (!country) {
|
|
78
|
-
return
|
|
105
|
+
return applySchemaConstraints(Joi.array().items(featureSchema).unique('id'), def);
|
|
79
106
|
}
|
|
80
107
|
const validateCountryBounds = (value, helpers) => {
|
|
81
108
|
const countryFeature = countries.features.find(feature => feature.id === country);
|
|
@@ -93,7 +120,7 @@ export function getGeospatialSchema(country) {
|
|
|
93
120
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
94
121
|
return value;
|
|
95
122
|
};
|
|
96
|
-
return Joi.array().items(featureSchema.custom(validateCountryBounds)).unique('id')
|
|
123
|
+
return applySchemaConstraints(Joi.array().items(featureSchema.custom(validateCountryBounds)).unique('id'), def);
|
|
97
124
|
}
|
|
98
125
|
|
|
99
126
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"geospatial.js","names":["GeospatialFieldOptionsCountryEnum","Bourne","booleanWithin","JoiBase","countries","countriesDesc","England","NorthernIreland","Scotland","Wales","Joi","extend","type","base","array","messages","coerce","from","method","value","helpers","trim","undefined","parse","result","errors","error","coordinatesSchema","items","number","required","featurePropertiesSchema","object","keys","description","string","coordinateGridReference","centroidGridReference","featureGeometrySchema","valid","coordinates","when","switch","is","then","min","featureSchema","id","properties","geometry","geospatialSchema","unique","getGeospatialSchema","country","validateCountryBounds","countryFeature","features","find","feature","custom"],"sources":["../../../../../../src/server/plugins/engine/components/helpers/geospatial.ts"],"sourcesContent":["import {\n GeospatialFieldOptionsCountryEnum,\n type GeospatialFieldOptionsCountry\n} from '@defra/forms-model'\nimport Bourne from '@hapi/bourne'\nimport { booleanWithin } from '@turf/boolean-within'\nimport JoiBase, { type CustomValidator } from 'joi'\n\nimport {\n type Coordinates,\n type Feature,\n type FeatureProperties,\n type Geometry\n} from '~/src/server/plugins/engine/types.js'\nimport { countries } from '~/src/server/plugins/map/routes/index.js'\n\nconst countriesDesc: Record<GeospatialFieldOptionsCountryEnum, string> = {\n [GeospatialFieldOptionsCountryEnum.England]: 'England',\n [GeospatialFieldOptionsCountryEnum.NorthernIreland]: 'Northern Ireland',\n [GeospatialFieldOptionsCountryEnum.Scotland]: 'Scotland',\n [GeospatialFieldOptionsCountryEnum.Wales]: 'Wales'\n}\n\nconst Joi = JoiBase.extend({\n type: 'array',\n base: JoiBase.array(),\n messages: {\n 'object.invalidjson': '{{#label}} must be a valid json array string'\n },\n coerce: {\n from: 'string',\n method(value, helpers) {\n if (typeof value === 'string') {\n if (value.trim() === '') {\n return {\n value: undefined\n }\n }\n\n try {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n return { value: Bourne.parse(value) }\n } catch {\n const result = {\n value,\n errors: [helpers.error('object.invalidjson')]\n }\n\n return result\n }\n } else {\n return {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n value\n }\n }\n }\n }\n}) as JoiBase.Root\n\nconst coordinatesSchema = Joi.array<Coordinates[]>()\n .items(Joi.number().required(), Joi.number().required())\n .required()\n\nconst featurePropertiesSchema = Joi.object<FeatureProperties>()\n .keys({\n description: Joi.string().required(),\n coordinateGridReference: Joi.string().required(),\n centroidGridReference: Joi.string().required()\n })\n .required()\n\nconst featureGeometrySchema = Joi.object<Geometry>().keys({\n type: Joi.string().valid('Point', 'LineString', 'Polygon').required(),\n coordinates: Joi.array()\n .when('type', {\n switch: [\n { is: 'Point', then: coordinatesSchema },\n {\n is: 'LineString',\n then: Joi.array().items(coordinatesSchema).min(2)\n },\n {\n is: 'Polygon',\n then: Joi.array().items(Joi.array().items(coordinatesSchema).min(3))\n }\n ]\n })\n .required()\n})\n\nconst featureSchema = Joi.object<Feature>().keys({\n id: Joi.string().required(),\n type: Joi.string().valid('Feature').required(),\n properties: featurePropertiesSchema,\n geometry: featureGeometrySchema\n})\n\nconst geospatialSchema = Joi.array<Feature[]>()\n .items(featureSchema)\n .unique('id')\n .required()\n\nexport function getGeospatialSchema(country?: GeospatialFieldOptionsCountry) {\n if (!country) {\n return geospatialSchema\n }\n\n const validateCountryBounds: CustomValidator = (value, helpers) => {\n const countryFeature = countries.features.find(\n (feature) => feature.id === country\n )\n\n if (!countryFeature) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n return value\n }\n\n const result = booleanWithin(value as Geometry | Feature, countryFeature)\n\n if (!result) {\n return helpers.error('any.custom', {\n country: countriesDesc[country as GeospatialFieldOptionsCountryEnum]\n })\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n return value\n }\n\n return Joi.array<Feature[]>()\n .items(featureSchema.custom(validateCountryBounds))\n .unique('id')\n .required()\n}\n\n/**\n * @import { CustomHelpers } from 'joi'\n */\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"geospatial.js","names":["GeospatialFieldOptionsCountryEnum","Bourne","booleanWithin","JoiBase","countries","countriesDesc","England","NorthernIreland","Scotland","Wales","Joi","extend","type","base","array","messages","coerce","from","method","value","helpers","trimmed","trim","undefined","parse","result","errors","error","coordinatesSchema","items","number","required","featurePropertiesSchema","object","keys","description","string","coordinateGridReference","centroidGridReference","featureGeometrySchema","valid","coordinates","when","switch","is","then","min","featureSchema","id","properties","geometry","applySchemaConstraints","schema","def","options","constraints","isOptional","length","max","optional","getGeospatialSchema","country","at","unique","validateCountryBounds","countryFeature","features","find","feature","custom"],"sources":["../../../../../../src/server/plugins/engine/components/helpers/geospatial.ts"],"sourcesContent":["import {\n GeospatialFieldOptionsCountryEnum,\n type GeospatialFieldComponent,\n type GeospatialFieldOptionsCountry\n} from '@defra/forms-model'\nimport Bourne from '@hapi/bourne'\nimport { booleanWithin } from '@turf/boolean-within'\nimport JoiBase, { type CustomValidator } from 'joi'\n\nimport {\n type Coordinates,\n type Feature,\n type FeatureProperties,\n type Geometry\n} from '~/src/server/plugins/engine/types.js'\nimport { countries } from '~/src/server/plugins/map/routes/index.js'\n\nconst countriesDesc: Record<GeospatialFieldOptionsCountryEnum, string> = {\n [GeospatialFieldOptionsCountryEnum.England]: 'England',\n [GeospatialFieldOptionsCountryEnum.NorthernIreland]: 'Northern Ireland',\n [GeospatialFieldOptionsCountryEnum.Scotland]: 'Scotland',\n [GeospatialFieldOptionsCountryEnum.Wales]: 'Wales'\n}\n\nconst Joi = JoiBase.extend({\n type: 'array',\n base: JoiBase.array(),\n messages: {\n 'object.invalidjson': '{{#label}} must be a valid json array string'\n },\n coerce: {\n from: 'string',\n method(value, helpers) {\n if (typeof value === 'string') {\n const trimmed = value.trim()\n if (trimmed === '' || trimmed === '[]') {\n return {\n value: undefined\n }\n }\n\n try {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n return { value: Bourne.parse(value) }\n } catch {\n const result = {\n value,\n errors: [helpers.error('object.invalidjson')]\n }\n\n return result\n }\n } else {\n return {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n value\n }\n }\n }\n }\n}) as JoiBase.Root\n\nconst coordinatesSchema = Joi.array<Coordinates[]>()\n .items(Joi.number().required(), Joi.number().required())\n .required()\n\nconst featurePropertiesSchema = Joi.object<FeatureProperties>()\n .keys({\n description: Joi.string().required(),\n coordinateGridReference: Joi.string().required(),\n centroidGridReference: Joi.string().required()\n })\n .required()\n\nconst featureGeometrySchema = Joi.object<Geometry>().keys({\n type: Joi.string().valid('Point', 'LineString', 'Polygon').required(),\n coordinates: Joi.array()\n .when('type', {\n switch: [\n { is: 'Point', then: coordinatesSchema },\n {\n is: 'LineString',\n then: Joi.array().items(coordinatesSchema).min(2)\n },\n {\n is: 'Polygon',\n then: Joi.array().items(Joi.array().items(coordinatesSchema).min(3))\n }\n ]\n })\n .required()\n})\n\nconst featureSchema = Joi.object<Feature>().keys({\n id: Joi.string().required(),\n type: Joi.string().valid('Feature').required(),\n properties: featurePropertiesSchema,\n geometry: featureGeometrySchema\n})\n\nfunction applySchemaConstraints(\n schema: JoiBase.ArraySchema<Feature[]>,\n def: GeospatialFieldComponent\n) {\n const { options, schema: constraints } = def\n const isOptional = options.required === false\n\n if (typeof constraints?.length === 'number') {\n schema = schema.length(constraints.length)\n } else {\n if (typeof constraints?.min === 'number') {\n schema = schema.min(constraints.min)\n } else if (!isOptional) {\n schema = schema.min(1)\n }\n\n schema = schema.max(\n typeof constraints?.max === 'number' ? constraints.max : 50\n )\n }\n\n if (isOptional) {\n schema = schema.optional()\n } else {\n schema = schema.required()\n }\n\n return schema\n}\n\nexport function getGeospatialSchema(\n def: GeospatialFieldComponent\n): JoiBase.ArraySchema<Feature[]> {\n const { options = {} } = def\n const country: GeospatialFieldOptionsCountry | undefined =\n options.countries?.at(0)\n\n if (!country) {\n return applySchemaConstraints(\n Joi.array<Feature[]>().items(featureSchema).unique('id'),\n def\n )\n }\n\n const validateCountryBounds: CustomValidator = (value, helpers) => {\n const countryFeature = countries.features.find(\n (feature) => feature.id === country\n )\n\n if (!countryFeature) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n return value\n }\n\n const result = booleanWithin(value as Geometry | Feature, countryFeature)\n\n if (!result) {\n return helpers.error('any.custom', {\n country: countriesDesc[country as GeospatialFieldOptionsCountryEnum]\n })\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n return value\n }\n\n return applySchemaConstraints(\n Joi.array<Feature[]>()\n .items(featureSchema.custom(validateCountryBounds))\n .unique('id'),\n def\n )\n}\n\n/**\n * @import { CustomHelpers } from 'joi'\n */\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -1,7 +1,17 @@
|
|
|
1
|
-
import { GeospatialFieldOptionsCountryEnum } from '@defra/forms-model';
|
|
1
|
+
import { ComponentType, GeospatialFieldOptionsCountryEnum } from '@defra/forms-model';
|
|
2
2
|
import { validState } from "./__stubs__/geospatial.js";
|
|
3
3
|
import { getGeospatialSchema } from "./geospatial.js";
|
|
4
|
-
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @type {import('@defra/forms-model').GeospatialFieldComponent}
|
|
7
|
+
*/
|
|
8
|
+
const geospatialComponent = {
|
|
9
|
+
name: 'geospatial',
|
|
10
|
+
title: 'Geospatial',
|
|
11
|
+
type: ComponentType.GeospatialField,
|
|
12
|
+
options: {}
|
|
13
|
+
};
|
|
14
|
+
const geospatialSchema = getGeospatialSchema(geospatialComponent);
|
|
5
15
|
describe('Geospatial validation helpers', () => {
|
|
6
16
|
test('it should not have errors for valid geojson object', () => {
|
|
7
17
|
const result = geospatialSchema.validate(validState);
|
|
@@ -27,8 +37,19 @@ describe('Geospatial validation helpers', () => {
|
|
|
27
37
|
});
|
|
28
38
|
test('it should validate an empty array', () => {
|
|
29
39
|
const result = geospatialSchema.validate('[]');
|
|
40
|
+
expect(result.error).toBeDefined();
|
|
41
|
+
expect(result.value).toBeUndefined();
|
|
42
|
+
});
|
|
43
|
+
test('it should validate an empty array when optional', () => {
|
|
44
|
+
const schema = getGeospatialSchema({
|
|
45
|
+
...geospatialComponent,
|
|
46
|
+
options: {
|
|
47
|
+
required: false
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
const result = schema.validate('[]');
|
|
30
51
|
expect(result.error).toBeUndefined();
|
|
31
|
-
expect(result.value).
|
|
52
|
+
expect(result.value).toBeUndefined();
|
|
32
53
|
});
|
|
33
54
|
test('it should not validate an empty object', () => {
|
|
34
55
|
const result = geospatialSchema.validate('{}');
|
|
@@ -41,21 +62,31 @@ describe('Geospatial validation helpers', () => {
|
|
|
41
62
|
expect(result.value).toBeUndefined();
|
|
42
63
|
});
|
|
43
64
|
test('it should be valid inside country bounds', () => {
|
|
44
|
-
const schema = getGeospatialSchema(
|
|
65
|
+
const schema = getGeospatialSchema({
|
|
66
|
+
...geospatialComponent,
|
|
67
|
+
options: {
|
|
68
|
+
countries: [GeospatialFieldOptionsCountryEnum.England]
|
|
69
|
+
}
|
|
70
|
+
});
|
|
45
71
|
expect(schema.validate(validState).error).toBeUndefined();
|
|
46
72
|
expect(schema.validate(validState.slice(1)).error).toBeUndefined();
|
|
47
73
|
expect(schema.validate(validState.slice(2)).error).toBeUndefined();
|
|
48
74
|
expect(schema.validate(validState.slice(3)).error).toBeUndefined();
|
|
49
75
|
});
|
|
50
76
|
test('it should be invalid outside country bounds', () => {
|
|
51
|
-
const schema = getGeospatialSchema(
|
|
77
|
+
const schema = getGeospatialSchema({
|
|
78
|
+
...geospatialComponent,
|
|
79
|
+
options: {
|
|
80
|
+
countries: [GeospatialFieldOptionsCountryEnum.Scotland]
|
|
81
|
+
}
|
|
82
|
+
});
|
|
52
83
|
expect(schema.validate(validState).error).toBeDefined();
|
|
53
84
|
expect(schema.validate(validState.slice(1)).error).toBeDefined();
|
|
54
85
|
expect(schema.validate(validState.slice(2)).error).toBeDefined();
|
|
55
86
|
expect(schema.validate(validState.slice(3)).error).toBeDefined();
|
|
56
87
|
});
|
|
57
88
|
test('it should be valid with no country bounds', () => {
|
|
58
|
-
const schema = getGeospatialSchema();
|
|
89
|
+
const schema = getGeospatialSchema(geospatialComponent);
|
|
59
90
|
expect(schema.validate(validState).error).toBeUndefined();
|
|
60
91
|
});
|
|
61
92
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"geospatial.test.js","names":["GeospatialFieldOptionsCountryEnum","validState","getGeospatialSchema","geospatialSchema","describe","test","result","validate","expect","error","toBeUndefined","value","toBeDefined","toHaveLength","JSON","stringify","toBe","
|
|
1
|
+
{"version":3,"file":"geospatial.test.js","names":["ComponentType","GeospatialFieldOptionsCountryEnum","validState","getGeospatialSchema","geospatialComponent","name","title","type","GeospatialField","options","geospatialSchema","describe","test","result","validate","expect","error","toBeUndefined","value","toBeDefined","toHaveLength","JSON","stringify","toBe","schema","required","countries","England","slice","Scotland"],"sources":["../../../../../../src/server/plugins/engine/components/helpers/geospatial.test.js"],"sourcesContent":["import {\n ComponentType,\n GeospatialFieldOptionsCountryEnum\n} from '@defra/forms-model'\n\nimport { validState } from '~/src/server/plugins/engine/components/helpers/__stubs__/geospatial.js'\nimport { getGeospatialSchema } from '~/src/server/plugins/engine/components/helpers/geospatial.js'\n\n/**\n * @type {import('@defra/forms-model').GeospatialFieldComponent}\n */\nconst geospatialComponent = {\n name: 'geospatial',\n title: 'Geospatial',\n type: ComponentType.GeospatialField,\n options: {}\n}\n\nconst geospatialSchema = getGeospatialSchema(geospatialComponent)\n\ndescribe('Geospatial validation helpers', () => {\n test('it should not have errors for valid geojson object', () => {\n const result = geospatialSchema.validate(validState)\n\n expect(result.error).toBeUndefined()\n expect(result.value).toBeDefined()\n expect(result.value).toHaveLength(4)\n })\n\n test('it should not have errors for valid geojson string', () => {\n const result = geospatialSchema.validate(JSON.stringify(validState))\n\n expect(result.error).toBeUndefined()\n expect(result.value).toBeDefined()\n expect(result.value).toHaveLength(4)\n })\n\n test('it should have errors for invalid json string', () => {\n const result = geospatialSchema.validate('{')\n\n expect(result.error).toBeDefined()\n expect(result.value).toBe('{')\n })\n\n test('it should have errors for invalid geojson string', () => {\n const result = geospatialSchema.validate('[')\n\n expect(result.error).toBeDefined()\n expect(result.value).toBe('[')\n })\n\n test('it should validate an empty array', () => {\n const result = geospatialSchema.validate('[]')\n\n expect(result.error).toBeDefined()\n expect(result.value).toBeUndefined()\n })\n\n test('it should validate an empty array when optional', () => {\n const schema = getGeospatialSchema({\n ...geospatialComponent,\n options: { required: false }\n })\n const result = schema.validate('[]')\n\n expect(result.error).toBeUndefined()\n expect(result.value).toBeUndefined()\n })\n\n test('it should not validate an empty object', () => {\n const result = geospatialSchema.validate('{}')\n\n expect(result.error).toBeDefined()\n expect(result.value).toBeUndefined()\n })\n\n test('it should validate an empty string', () => {\n const result = geospatialSchema.validate('')\n\n expect(result.error).toBeDefined()\n expect(result.value).toBeUndefined()\n })\n\n test('it should be valid inside country bounds', () => {\n const schema = getGeospatialSchema({\n ...geospatialComponent,\n options: { countries: [GeospatialFieldOptionsCountryEnum.England] }\n })\n\n expect(schema.validate(validState).error).toBeUndefined()\n expect(schema.validate(validState.slice(1)).error).toBeUndefined()\n expect(schema.validate(validState.slice(2)).error).toBeUndefined()\n expect(schema.validate(validState.slice(3)).error).toBeUndefined()\n })\n\n test('it should be invalid outside country bounds', () => {\n const schema = getGeospatialSchema({\n ...geospatialComponent,\n options: { countries: [GeospatialFieldOptionsCountryEnum.Scotland] }\n })\n\n expect(schema.validate(validState).error).toBeDefined()\n expect(schema.validate(validState.slice(1)).error).toBeDefined()\n expect(schema.validate(validState.slice(2)).error).toBeDefined()\n expect(schema.validate(validState.slice(3)).error).toBeDefined()\n })\n\n test('it should be valid with no country bounds', () => {\n const schema = getGeospatialSchema(geospatialComponent)\n\n expect(schema.validate(validState).error).toBeUndefined()\n })\n})\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -37,7 +37,10 @@ export const messageTemplate = {
|
|
|
37
37
|
dateMax: '{{#title}} must be the same as or before {{#limit}}',
|
|
38
38
|
arrayMin: 'Select at least {{#limit}} options from the list',
|
|
39
39
|
arrayMax: 'Only {{#limit}} can be selected from the list',
|
|
40
|
-
arrayLength: 'Select only {{#limit}} options from the list'
|
|
40
|
+
arrayLength: 'Select only {{#limit}} options from the list',
|
|
41
|
+
featuresMin: 'Define at least {{#limit}} features',
|
|
42
|
+
featuresMax: 'Only {{#limit}} features can be defined',
|
|
43
|
+
featuresLength: 'Define exactly {{#limit}} features'
|
|
41
44
|
};
|
|
42
45
|
export const messages = {
|
|
43
46
|
'string.base': messageTemplate.required,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validationOptions.js","names":["joi","lowerFirstPreserveProperNouns","opts","functions","lowerFirst","messageTemplate","declarationRequired","expression","required","selectRequired","selectYesNoRequired","max","min","minMax","pattern","format","unicode","number","numberPrecision","numberInteger","numberMin","numberMax","maxWords","objectRequired","objectMissing","dateFormat","dateMin","dateMax","arrayMin","arrayMax","arrayLength","messages","messagesPre","validationOptions","abortEarly","errors","wrap","array","label"],"sources":["../../../../../src/server/plugins/engine/pageControllers/validationOptions.ts"],"sourcesContent":["// Declaration above is needed for: https://github.com/hapijs/joi/issues/3064\n\nimport joi, {\n type JoiExpression,\n type LanguageMessages,\n type LanguageMessagesExt,\n type ReferenceOptions,\n type ValidationOptions\n} from 'joi'\n\nimport { lowerFirstPreserveProperNouns } from '~/src/server/plugins/engine/components/helpers/index.js'\n\nconst opts = {\n functions: {\n lowerFirst: lowerFirstPreserveProperNouns\n }\n} as ReferenceOptions\n\n/**\n * see @link https://joi.dev/api/?v=17.4.2#template-syntax for template syntax\n */\nexport const messageTemplate: Record<string, JoiExpression> = {\n declarationRequired: joi.expression(\n 'You must confirm you understand and agree with the {{lowerFirst(#label)}} to continue',\n opts\n ) as JoiExpression,\n required: joi.expression(\n 'Enter {{lowerFirst(#label)}}',\n opts\n ) as JoiExpression,\n selectRequired: joi.expression(\n 'Select {{lowerFirst(#label)}}',\n opts\n ) as JoiExpression,\n selectYesNoRequired: '{{#label}} - select yes or no',\n max: '{{#label}} must be {{#limit}} characters or less',\n min: '{{#label}} must be {{#limit}} characters or more',\n minMax: '{{#label}} must be between {{#min}} and {{#max}} characters',\n pattern: joi.expression(\n 'Enter a valid {{lowerFirst(#label)}}',\n opts\n ) as JoiExpression,\n format: joi.expression(\n 'Enter {{lowerFirst(#label)}} in the correct format',\n opts\n ) as JoiExpression,\n unicode: '{{#label}} includes invalid characters, for example, long dashes',\n number: '{{#label}} must be a number',\n numberPrecision: '{{#label}} must have {{#limit}} or fewer decimal places',\n numberInteger: '{{#label}} must be a whole number',\n numberMin: '{{#label}} must be {{#limit}} or higher',\n numberMax: '{{#label}} must be {{#limit}} or lower',\n maxWords: '{{#label}} must be {{#limit}} words or fewer',\n\n // Nested fields use component title\n\n objectRequired: joi.expression('Enter {{#label}}', opts) as JoiExpression,\n objectMissing: joi.expression(\n '{{#title}} must include a {{lowerFirst(#label)}}',\n opts\n ) as JoiExpression,\n dateFormat: '{{#title}} must be a real date',\n dateMin: '{{#title}} must be the same as or after {{#limit}}',\n dateMax: '{{#title}} must be the same as or before {{#limit}}',\n arrayMin: 'Select at least {{#limit}} options from the list',\n arrayMax: 'Only {{#limit}} can be selected from the list',\n arrayLength: 'Select only {{#limit}} options from the list'\n}\n\nexport const messages: LanguageMessagesExt = {\n 'string.base': messageTemplate.required,\n 'string.min': messageTemplate.min,\n 'string.empty': messageTemplate.required,\n 'string.max': messageTemplate.max,\n 'string.email': messageTemplate.format,\n 'string.unicode': messageTemplate.unicode,\n 'string.pattern.base': messageTemplate.pattern,\n 'string.maxWords': messageTemplate.maxWords,\n\n 'number.base': messageTemplate.number,\n 'number.precision': messageTemplate.numberPrecision,\n 'number.integer': messageTemplate.numberInteger,\n 'number.unsafe': messageTemplate.format,\n 'number.min': messageTemplate.numberMin,\n 'number.max': messageTemplate.numberMax,\n\n 'object.required': messageTemplate.objectRequired,\n 'object.and': messageTemplate.objectMissing,\n\n 'any.only': messageTemplate.selectRequired,\n 'any.required': messageTemplate.selectRequired,\n 'any.empty': messageTemplate.required,\n\n 'date.base': messageTemplate.dateFormat,\n 'date.format': messageTemplate.dateFormat,\n 'date.min': messageTemplate.dateMin,\n 'date.max': messageTemplate.dateMax,\n\n 'object.invalidjson': messageTemplate.format\n}\n\nexport const messagesPre: LanguageMessages =\n messages as unknown as LanguageMessages\n\nexport const validationOptions: ValidationOptions = {\n abortEarly: false,\n messages: messagesPre,\n errors: {\n wrap: {\n array: false,\n label: false\n }\n }\n}\n"],"mappings":"AAAA;;AAEA,OAAOA,GAAG,MAMH,KAAK;AAEZ,SAASC,6BAA6B;AAEtC,MAAMC,IAAI,GAAG;EACXC,SAAS,EAAE;IACTC,UAAU,EAAEH;EACd;AACF,CAAqB;;AAErB;AACA;AACA;AACA,OAAO,MAAMI,eAA8C,GAAG;EAC5DC,mBAAmB,EAAEN,GAAG,CAACO,UAAU,CACjC,uFAAuF,EACvFL,IACF,CAAkB;EAClBM,QAAQ,EAAER,GAAG,CAACO,UAAU,CACtB,8BAA8B,EAC9BL,IACF,CAAkB;EAClBO,cAAc,EAAET,GAAG,CAACO,UAAU,CAC5B,+BAA+B,EAC/BL,IACF,CAAkB;EAClBQ,mBAAmB,EAAE,+BAA+B;EACpDC,GAAG,EAAE,kDAAkD;EACvDC,GAAG,EAAE,kDAAkD;EACvDC,MAAM,EAAE,6DAA6D;EACrEC,OAAO,EAAEd,GAAG,CAACO,UAAU,CACrB,sCAAsC,EACtCL,IACF,CAAkB;EAClBa,MAAM,EAAEf,GAAG,CAACO,UAAU,CACpB,oDAAoD,EACpDL,IACF,CAAkB;EAClBc,OAAO,EAAE,kEAAkE;EAC3EC,MAAM,EAAE,6BAA6B;EACrCC,eAAe,EAAE,yDAAyD;EAC1EC,aAAa,EAAE,mCAAmC;EAClDC,SAAS,EAAE,yCAAyC;EACpDC,SAAS,EAAE,wCAAwC;EACnDC,QAAQ,EAAE,8CAA8C;EAExD;;EAEAC,cAAc,EAAEvB,GAAG,CAACO,UAAU,CAAC,kBAAkB,EAAEL,IAAI,CAAkB;EACzEsB,aAAa,EAAExB,GAAG,CAACO,UAAU,CAC3B,kDAAkD,EAClDL,IACF,CAAkB;EAClBuB,UAAU,EAAE,gCAAgC;EAC5CC,OAAO,EAAE,oDAAoD;EAC7DC,OAAO,EAAE,qDAAqD;EAC9DC,QAAQ,EAAE,kDAAkD;EAC5DC,QAAQ,EAAE,+CAA+C;EACzDC,WAAW,EAAE;
|
|
1
|
+
{"version":3,"file":"validationOptions.js","names":["joi","lowerFirstPreserveProperNouns","opts","functions","lowerFirst","messageTemplate","declarationRequired","expression","required","selectRequired","selectYesNoRequired","max","min","minMax","pattern","format","unicode","number","numberPrecision","numberInteger","numberMin","numberMax","maxWords","objectRequired","objectMissing","dateFormat","dateMin","dateMax","arrayMin","arrayMax","arrayLength","featuresMin","featuresMax","featuresLength","messages","messagesPre","validationOptions","abortEarly","errors","wrap","array","label"],"sources":["../../../../../src/server/plugins/engine/pageControllers/validationOptions.ts"],"sourcesContent":["// Declaration above is needed for: https://github.com/hapijs/joi/issues/3064\n\nimport joi, {\n type JoiExpression,\n type LanguageMessages,\n type LanguageMessagesExt,\n type ReferenceOptions,\n type ValidationOptions\n} from 'joi'\n\nimport { lowerFirstPreserveProperNouns } from '~/src/server/plugins/engine/components/helpers/index.js'\n\nconst opts = {\n functions: {\n lowerFirst: lowerFirstPreserveProperNouns\n }\n} as ReferenceOptions\n\n/**\n * see @link https://joi.dev/api/?v=17.4.2#template-syntax for template syntax\n */\nexport const messageTemplate: Record<string, JoiExpression> = {\n declarationRequired: joi.expression(\n 'You must confirm you understand and agree with the {{lowerFirst(#label)}} to continue',\n opts\n ) as JoiExpression,\n required: joi.expression(\n 'Enter {{lowerFirst(#label)}}',\n opts\n ) as JoiExpression,\n selectRequired: joi.expression(\n 'Select {{lowerFirst(#label)}}',\n opts\n ) as JoiExpression,\n selectYesNoRequired: '{{#label}} - select yes or no',\n max: '{{#label}} must be {{#limit}} characters or less',\n min: '{{#label}} must be {{#limit}} characters or more',\n minMax: '{{#label}} must be between {{#min}} and {{#max}} characters',\n pattern: joi.expression(\n 'Enter a valid {{lowerFirst(#label)}}',\n opts\n ) as JoiExpression,\n format: joi.expression(\n 'Enter {{lowerFirst(#label)}} in the correct format',\n opts\n ) as JoiExpression,\n unicode: '{{#label}} includes invalid characters, for example, long dashes',\n number: '{{#label}} must be a number',\n numberPrecision: '{{#label}} must have {{#limit}} or fewer decimal places',\n numberInteger: '{{#label}} must be a whole number',\n numberMin: '{{#label}} must be {{#limit}} or higher',\n numberMax: '{{#label}} must be {{#limit}} or lower',\n maxWords: '{{#label}} must be {{#limit}} words or fewer',\n\n // Nested fields use component title\n\n objectRequired: joi.expression('Enter {{#label}}', opts) as JoiExpression,\n objectMissing: joi.expression(\n '{{#title}} must include a {{lowerFirst(#label)}}',\n opts\n ) as JoiExpression,\n dateFormat: '{{#title}} must be a real date',\n dateMin: '{{#title}} must be the same as or after {{#limit}}',\n dateMax: '{{#title}} must be the same as or before {{#limit}}',\n arrayMin: 'Select at least {{#limit}} options from the list',\n arrayMax: 'Only {{#limit}} can be selected from the list',\n arrayLength: 'Select only {{#limit}} options from the list',\n featuresMin: 'Define at least {{#limit}} features',\n featuresMax: 'Only {{#limit}} features can be defined',\n featuresLength: 'Define exactly {{#limit}} features'\n}\n\nexport const messages: LanguageMessagesExt = {\n 'string.base': messageTemplate.required,\n 'string.min': messageTemplate.min,\n 'string.empty': messageTemplate.required,\n 'string.max': messageTemplate.max,\n 'string.email': messageTemplate.format,\n 'string.unicode': messageTemplate.unicode,\n 'string.pattern.base': messageTemplate.pattern,\n 'string.maxWords': messageTemplate.maxWords,\n\n 'number.base': messageTemplate.number,\n 'number.precision': messageTemplate.numberPrecision,\n 'number.integer': messageTemplate.numberInteger,\n 'number.unsafe': messageTemplate.format,\n 'number.min': messageTemplate.numberMin,\n 'number.max': messageTemplate.numberMax,\n\n 'object.required': messageTemplate.objectRequired,\n 'object.and': messageTemplate.objectMissing,\n\n 'any.only': messageTemplate.selectRequired,\n 'any.required': messageTemplate.selectRequired,\n 'any.empty': messageTemplate.required,\n\n 'date.base': messageTemplate.dateFormat,\n 'date.format': messageTemplate.dateFormat,\n 'date.min': messageTemplate.dateMin,\n 'date.max': messageTemplate.dateMax,\n\n 'object.invalidjson': messageTemplate.format\n}\n\nexport const messagesPre: LanguageMessages =\n messages as unknown as LanguageMessages\n\nexport const validationOptions: ValidationOptions = {\n abortEarly: false,\n messages: messagesPre,\n errors: {\n wrap: {\n array: false,\n label: false\n }\n }\n}\n"],"mappings":"AAAA;;AAEA,OAAOA,GAAG,MAMH,KAAK;AAEZ,SAASC,6BAA6B;AAEtC,MAAMC,IAAI,GAAG;EACXC,SAAS,EAAE;IACTC,UAAU,EAAEH;EACd;AACF,CAAqB;;AAErB;AACA;AACA;AACA,OAAO,MAAMI,eAA8C,GAAG;EAC5DC,mBAAmB,EAAEN,GAAG,CAACO,UAAU,CACjC,uFAAuF,EACvFL,IACF,CAAkB;EAClBM,QAAQ,EAAER,GAAG,CAACO,UAAU,CACtB,8BAA8B,EAC9BL,IACF,CAAkB;EAClBO,cAAc,EAAET,GAAG,CAACO,UAAU,CAC5B,+BAA+B,EAC/BL,IACF,CAAkB;EAClBQ,mBAAmB,EAAE,+BAA+B;EACpDC,GAAG,EAAE,kDAAkD;EACvDC,GAAG,EAAE,kDAAkD;EACvDC,MAAM,EAAE,6DAA6D;EACrEC,OAAO,EAAEd,GAAG,CAACO,UAAU,CACrB,sCAAsC,EACtCL,IACF,CAAkB;EAClBa,MAAM,EAAEf,GAAG,CAACO,UAAU,CACpB,oDAAoD,EACpDL,IACF,CAAkB;EAClBc,OAAO,EAAE,kEAAkE;EAC3EC,MAAM,EAAE,6BAA6B;EACrCC,eAAe,EAAE,yDAAyD;EAC1EC,aAAa,EAAE,mCAAmC;EAClDC,SAAS,EAAE,yCAAyC;EACpDC,SAAS,EAAE,wCAAwC;EACnDC,QAAQ,EAAE,8CAA8C;EAExD;;EAEAC,cAAc,EAAEvB,GAAG,CAACO,UAAU,CAAC,kBAAkB,EAAEL,IAAI,CAAkB;EACzEsB,aAAa,EAAExB,GAAG,CAACO,UAAU,CAC3B,kDAAkD,EAClDL,IACF,CAAkB;EAClBuB,UAAU,EAAE,gCAAgC;EAC5CC,OAAO,EAAE,oDAAoD;EAC7DC,OAAO,EAAE,qDAAqD;EAC9DC,QAAQ,EAAE,kDAAkD;EAC5DC,QAAQ,EAAE,+CAA+C;EACzDC,WAAW,EAAE,8CAA8C;EAC3DC,WAAW,EAAE,qCAAqC;EAClDC,WAAW,EAAE,yCAAyC;EACtDC,cAAc,EAAE;AAClB,CAAC;AAED,OAAO,MAAMC,QAA6B,GAAG;EAC3C,aAAa,EAAE7B,eAAe,CAACG,QAAQ;EACvC,YAAY,EAAEH,eAAe,CAACO,GAAG;EACjC,cAAc,EAAEP,eAAe,CAACG,QAAQ;EACxC,YAAY,EAAEH,eAAe,CAACM,GAAG;EACjC,cAAc,EAAEN,eAAe,CAACU,MAAM;EACtC,gBAAgB,EAAEV,eAAe,CAACW,OAAO;EACzC,qBAAqB,EAAEX,eAAe,CAACS,OAAO;EAC9C,iBAAiB,EAAET,eAAe,CAACiB,QAAQ;EAE3C,aAAa,EAAEjB,eAAe,CAACY,MAAM;EACrC,kBAAkB,EAAEZ,eAAe,CAACa,eAAe;EACnD,gBAAgB,EAAEb,eAAe,CAACc,aAAa;EAC/C,eAAe,EAAEd,eAAe,CAACU,MAAM;EACvC,YAAY,EAAEV,eAAe,CAACe,SAAS;EACvC,YAAY,EAAEf,eAAe,CAACgB,SAAS;EAEvC,iBAAiB,EAAEhB,eAAe,CAACkB,cAAc;EACjD,YAAY,EAAElB,eAAe,CAACmB,aAAa;EAE3C,UAAU,EAAEnB,eAAe,CAACI,cAAc;EAC1C,cAAc,EAAEJ,eAAe,CAACI,cAAc;EAC9C,WAAW,EAAEJ,eAAe,CAACG,QAAQ;EAErC,WAAW,EAAEH,eAAe,CAACoB,UAAU;EACvC,aAAa,EAAEpB,eAAe,CAACoB,UAAU;EACzC,UAAU,EAAEpB,eAAe,CAACqB,OAAO;EACnC,UAAU,EAAErB,eAAe,CAACsB,OAAO;EAEnC,oBAAoB,EAAEtB,eAAe,CAACU;AACxC,CAAC;AAED,OAAO,MAAMoB,WAA6B,GACxCD,QAAuC;AAEzC,OAAO,MAAME,iBAAoC,GAAG;EAClDC,UAAU,EAAE,KAAK;EACjBH,QAAQ,EAAEC,WAAW;EACrBG,MAAM,EAAE;IACNC,IAAI,EAAE;MACJC,KAAK,EAAE,KAAK;MACZC,KAAK,EAAE;IACT;EACF;AACF,CAAC","ignoreList":[]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{% from "govuk/components/textarea/macro.njk" import govukTextarea %}
|
|
2
2
|
|
|
3
3
|
{% macro GeospatialField(component) %}
|
|
4
|
-
<div class="app-geospatial-field" data-country="{{component.model.country}}">
|
|
4
|
+
<div class="app-geospatial-field" data-country="{{component.model.country}}" data-geometryTypes="{{component.model.geometryTypes}}">
|
|
5
5
|
{{ govukTextarea(component.model) }}
|
|
6
6
|
</div>
|
|
7
7
|
{% endmacro %}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@defra/forms-engine-plugin",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.14.0",
|
|
4
4
|
"description": "Defra forms engine",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -87,7 +87,7 @@
|
|
|
87
87
|
},
|
|
88
88
|
"license": "SEE LICENSE IN LICENSE",
|
|
89
89
|
"dependencies": {
|
|
90
|
-
"@defra/forms-model": "^3.0.
|
|
90
|
+
"@defra/forms-model": "^3.0.668",
|
|
91
91
|
"@defra/hapi-tracing": "^1.29.0",
|
|
92
92
|
"@defra/interactive-map": "^0.0.22-alpha",
|
|
93
93
|
"@elastic/ecs-pino-format": "^1.5.0",
|