@defra/forms-engine-plugin 4.0.41 → 4.0.43
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/application.min.js +1 -1
- package/.public/javascripts/application.min.js.map +1 -1
- package/.public/javascripts/shared.min.js +1 -1
- package/.public/javascripts/shared.min.js.map +1 -1
- package/.public/stylesheets/application.min.css +2 -2
- package/.public/stylesheets/application.min.css.map +1 -1
- package/.server/client/javascripts/location-map.d.ts +93 -0
- package/.server/client/javascripts/location-map.js +749 -0
- package/.server/client/javascripts/location-map.js.map +1 -0
- package/.server/client/javascripts/shared.d.ts +4 -0
- package/.server/client/javascripts/shared.js +5 -0
- package/.server/client/javascripts/shared.js.map +1 -1
- package/.server/client/stylesheets/_location-fields.scss +11 -0
- package/.server/client/stylesheets/application.scss +0 -1
- package/.server/client/stylesheets/shared.scss +1 -0
- package/.server/config/index.js +1 -1
- package/.server/config/index.js.map +1 -1
- package/.server/server/plugins/engine/configureEnginePlugin.d.ts +1 -1
- package/.server/server/plugins/engine/configureEnginePlugin.js +4 -2
- package/.server/server/plugins/engine/configureEnginePlugin.js.map +1 -1
- package/.server/server/plugins/engine/options.js +2 -1
- package/.server/server/plugins/engine/options.js.map +1 -1
- package/.server/server/plugins/engine/plugin.js +14 -1
- package/.server/server/plugins/engine/plugin.js.map +1 -1
- package/.server/server/plugins/engine/types.d.ts +1 -0
- package/.server/server/plugins/engine/types.js.map +1 -1
- package/.server/server/plugins/engine/views/components/_location-field-base.html +1 -1
- package/.server/server/plugins/engine/views/components/osgridreffield.html +4 -2
- package/.server/server/plugins/map/index.d.ts +7 -0
- package/.server/server/plugins/map/index.js +20 -0
- package/.server/server/plugins/map/index.js.map +1 -0
- package/.server/server/plugins/map/routes/get-os-token.d.ts +6 -0
- package/.server/server/plugins/map/routes/get-os-token.js +41 -0
- package/.server/server/plugins/map/routes/get-os-token.js.map +1 -0
- package/.server/server/plugins/map/routes/get-os-token.test.js +49 -0
- package/.server/server/plugins/map/routes/get-os-token.test.js.map +1 -0
- package/.server/server/plugins/map/routes/index.d.ts +10 -0
- package/.server/server/plugins/map/routes/index.js +172 -0
- package/.server/server/plugins/map/routes/index.js.map +1 -0
- package/.server/server/plugins/map/routes/vts/OS_VTS_3857/resources/sprites/dark.json +690 -0
- package/.server/server/plugins/map/routes/vts/OS_VTS_3857/resources/sprites/dark.png +0 -0
- package/.server/server/plugins/map/routes/vts/OS_VTS_3857/resources/sprites/dark@2x.json +690 -0
- package/.server/server/plugins/map/routes/vts/OS_VTS_3857/resources/sprites/dark@2x.png +0 -0
- package/.server/server/plugins/map/routes/vts/OS_VTS_3857/resources/sprites/greyscale.json +690 -0
- package/.server/server/plugins/map/routes/vts/OS_VTS_3857/resources/sprites/greyscale.png +0 -0
- package/.server/server/plugins/map/routes/vts/OS_VTS_3857/resources/sprites/greyscale@2x.json +690 -0
- package/.server/server/plugins/map/routes/vts/OS_VTS_3857/resources/sprites/greyscale@2x.png +0 -0
- package/.server/server/plugins/map/routes/vts/OS_VTS_3857/resources/sprites/sprite.json +690 -0
- package/.server/server/plugins/map/routes/vts/OS_VTS_3857/resources/sprites/sprite.png +0 -0
- package/.server/server/plugins/map/routes/vts/OS_VTS_3857/resources/sprites/sprite@2x.json +690 -0
- package/.server/server/plugins/map/routes/vts/OS_VTS_3857/resources/sprites/sprite@2x.png +0 -0
- package/.server/server/plugins/map/routes/vts/OS_VTS_3857_Black_and_White.json +7858 -0
- package/.server/server/plugins/map/routes/vts/OS_VTS_3857_Dark.json +7669 -0
- package/.server/server/plugins/map/routes/vts/OS_VTS_3857_Outdoor.json +7653 -0
- package/.server/server/plugins/map/routes/vts/README.md +5 -0
- package/.server/server/plugins/map/service.d.ts +14 -0
- package/.server/server/plugins/map/service.js +76 -0
- package/.server/server/plugins/map/service.js.map +1 -0
- package/.server/server/plugins/map/service.test.js +120 -0
- package/.server/server/plugins/map/service.test.js.map +1 -0
- package/.server/server/plugins/map/test/__stubs__/find.d.ts +3 -0
- package/.server/server/plugins/map/test/__stubs__/find.js +216 -0
- package/.server/server/plugins/map/test/__stubs__/find.js.map +1 -0
- package/.server/server/plugins/map/test/__stubs__/nearest.d.ts +37 -0
- package/.server/server/plugins/map/test/__stubs__/nearest.js +38 -0
- package/.server/server/plugins/map/test/__stubs__/nearest.js.map +1 -0
- package/.server/server/plugins/map/types.d.ts +233 -0
- package/.server/server/plugins/map/types.js +121 -0
- package/.server/server/plugins/map/types.js.map +1 -0
- package/.server/server/types.d.ts +1 -0
- package/.server/server/types.js.map +1 -1
- package/package.json +3 -1
- package/src/client/javascripts/location-map.js +774 -0
- package/src/client/javascripts/shared.js +4 -0
- package/src/client/stylesheets/_location-fields.scss +11 -0
- package/src/client/stylesheets/application.scss +0 -1
- package/src/client/stylesheets/shared.scss +1 -0
- package/src/config/index.ts +1 -1
- package/src/server/plugins/engine/configureEnginePlugin.ts +4 -2
- package/src/server/plugins/engine/options.js +2 -1
- package/src/server/plugins/engine/plugin.ts +14 -1
- package/src/server/plugins/engine/types.ts +1 -0
- package/src/server/plugins/engine/views/components/_location-field-base.html +1 -1
- package/src/server/plugins/engine/views/components/osgridreffield.html +4 -2
- package/src/server/plugins/map/index.js +19 -0
- package/src/server/plugins/map/routes/get-os-token.js +41 -0
- package/src/server/plugins/map/routes/get-os-token.test.js +55 -0
- package/src/server/plugins/map/routes/index.js +192 -0
- package/src/server/plugins/map/routes/vts/OS_VTS_3857/resources/sprites/dark.json +690 -0
- package/src/server/plugins/map/routes/vts/OS_VTS_3857/resources/sprites/dark.png +0 -0
- package/src/server/plugins/map/routes/vts/OS_VTS_3857/resources/sprites/dark@2x.json +690 -0
- package/src/server/plugins/map/routes/vts/OS_VTS_3857/resources/sprites/dark@2x.png +0 -0
- package/src/server/plugins/map/routes/vts/OS_VTS_3857/resources/sprites/greyscale.json +690 -0
- package/src/server/plugins/map/routes/vts/OS_VTS_3857/resources/sprites/greyscale.png +0 -0
- package/src/server/plugins/map/routes/vts/OS_VTS_3857/resources/sprites/greyscale@2x.json +690 -0
- package/src/server/plugins/map/routes/vts/OS_VTS_3857/resources/sprites/greyscale@2x.png +0 -0
- package/src/server/plugins/map/routes/vts/OS_VTS_3857/resources/sprites/sprite.json +690 -0
- package/src/server/plugins/map/routes/vts/OS_VTS_3857/resources/sprites/sprite.png +0 -0
- package/src/server/plugins/map/routes/vts/OS_VTS_3857/resources/sprites/sprite@2x.json +690 -0
- package/src/server/plugins/map/routes/vts/OS_VTS_3857/resources/sprites/sprite@2x.png +0 -0
- package/src/server/plugins/map/routes/vts/OS_VTS_3857_Black_and_White.json +7858 -0
- package/src/server/plugins/map/routes/vts/OS_VTS_3857_Dark.json +7669 -0
- package/src/server/plugins/map/routes/vts/OS_VTS_3857_Outdoor.json +7653 -0
- package/src/server/plugins/map/routes/vts/README.md +5 -0
- package/src/server/plugins/map/service.js +84 -0
- package/src/server/plugins/map/service.test.js +144 -0
- package/src/server/plugins/map/test/__stubs__/find.js +271 -0
- package/src/server/plugins/map/test/__stubs__/nearest.js +46 -0
- package/src/server/plugins/map/types.js +120 -0
- package/src/server/types.ts +1 -0
|
@@ -2,12 +2,16 @@ import { initAllAutocomplete as initAllAutocompleteImp } from '~/src/client/java
|
|
|
2
2
|
import { initFileUpload as initFileUploadImp } from '~/src/client/javascripts/file-upload.js'
|
|
3
3
|
import { initAllGovuk as initAllGovukImp } from '~/src/client/javascripts/govuk.js'
|
|
4
4
|
import { initPreviewCloseLink as initPreviewCloseLinkImp } from '~/src/client/javascripts/preview-close-link.js'
|
|
5
|
+
export { initMaps } from '~/src/client/javascripts/location-map.js'
|
|
5
6
|
|
|
6
7
|
export const initAllGovuk = initAllGovukImp
|
|
7
8
|
export const initAllAutocomplete = initAllAutocompleteImp
|
|
8
9
|
export const initFileUpload = initFileUploadImp
|
|
9
10
|
export const initPreviewCloseLink = initPreviewCloseLinkImp
|
|
10
11
|
|
|
12
|
+
/**
|
|
13
|
+
* Initialise all clientside components (but not maps as this will be an opt-in for now given the additional UMD assets that are required)
|
|
14
|
+
*/
|
|
11
15
|
export function initAll() {
|
|
12
16
|
initAllGovuk()
|
|
13
17
|
initAllAutocomplete()
|
|
@@ -3,3 +3,14 @@
|
|
|
3
3
|
.govuk-form-group .app-location-field-inputs .govuk-form-group {
|
|
4
4
|
margin-bottom: 0;
|
|
5
5
|
}
|
|
6
|
+
|
|
7
|
+
.map-container {
|
|
8
|
+
margin-top: 10px;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
// Hides the location instructions text when JS (maps) is available
|
|
12
|
+
.js-enabled .app-location-field {
|
|
13
|
+
details:last-child {
|
|
14
|
+
display: none;
|
|
15
|
+
}
|
|
16
|
+
}
|
package/src/config/index.ts
CHANGED
|
@@ -255,7 +255,7 @@ export const config = convict({
|
|
|
255
255
|
} as SchemaObj<string>,
|
|
256
256
|
|
|
257
257
|
ordnanceSurveyApiKey: {
|
|
258
|
-
doc: 'The ordnance survey api key
|
|
258
|
+
doc: 'The ordnance survey api key used by the postcode lookup and maps plugin',
|
|
259
259
|
format: String,
|
|
260
260
|
nullable: true,
|
|
261
261
|
default: undefined,
|
|
@@ -22,7 +22,8 @@ export const configureEnginePlugin = async (
|
|
|
22
22
|
preparePageEventRequestOptions,
|
|
23
23
|
onRequest,
|
|
24
24
|
saveAndExit,
|
|
25
|
-
ordnanceSurveyApiKey
|
|
25
|
+
ordnanceSurveyApiKey,
|
|
26
|
+
ordnanceSurveyApiSecret
|
|
26
27
|
}: RouteConfig = {},
|
|
27
28
|
cache?: CacheService
|
|
28
29
|
): Promise<{
|
|
@@ -65,7 +66,8 @@ export const configureEnginePlugin = async (
|
|
|
65
66
|
onRequest,
|
|
66
67
|
baseUrl: 'http://localhost:3009', // always runs locally
|
|
67
68
|
saveAndExit,
|
|
68
|
-
ordnanceSurveyApiKey
|
|
69
|
+
ordnanceSurveyApiKey,
|
|
70
|
+
ordnanceSurveyApiSecret
|
|
69
71
|
}
|
|
70
72
|
}
|
|
71
73
|
}
|
|
@@ -26,7 +26,8 @@ const pluginRegistrationOptionsSchema = Joi.object({
|
|
|
26
26
|
onRequest: Joi.function().optional(),
|
|
27
27
|
baseUrl: Joi.string().uri().required(),
|
|
28
28
|
saveAndExit: Joi.function().optional(),
|
|
29
|
-
ordnanceSurveyApiKey: Joi.string().optional()
|
|
29
|
+
ordnanceSurveyApiKey: Joi.string().optional(),
|
|
30
|
+
ordnanceSurveyApiSecret: Joi.string().optional()
|
|
30
31
|
})
|
|
31
32
|
|
|
32
33
|
/**
|
|
@@ -15,6 +15,7 @@ import { getRoutes as getRepeaterItemDeleteRoutes } from '~/src/server/plugins/e
|
|
|
15
15
|
import { getRoutes as getRepeaterSummaryRoutes } from '~/src/server/plugins/engine/routes/repeaters/summary.js'
|
|
16
16
|
import { type PluginOptions } from '~/src/server/plugins/engine/types.js'
|
|
17
17
|
import { registerVision } from '~/src/server/plugins/engine/vision.js'
|
|
18
|
+
import { mapPlugin } from '~/src/server/plugins/map/index.js'
|
|
18
19
|
import { postcodeLookupPlugin } from '~/src/server/plugins/postcode-lookup/index.js'
|
|
19
20
|
import {
|
|
20
21
|
type FormRequestPayloadRefs,
|
|
@@ -37,7 +38,8 @@ export const plugin = {
|
|
|
37
38
|
viewContext,
|
|
38
39
|
preparePageEventRequestOptions,
|
|
39
40
|
onRequest,
|
|
40
|
-
ordnanceSurveyApiKey
|
|
41
|
+
ordnanceSurveyApiKey,
|
|
42
|
+
ordnanceSurveyApiSecret
|
|
41
43
|
} = options
|
|
42
44
|
|
|
43
45
|
const cacheService =
|
|
@@ -57,6 +59,17 @@ export const plugin = {
|
|
|
57
59
|
})
|
|
58
60
|
}
|
|
59
61
|
|
|
62
|
+
// Register the maps plugin only if we have an OS api key & secret
|
|
63
|
+
if (ordnanceSurveyApiKey && ordnanceSurveyApiSecret) {
|
|
64
|
+
await server.register({
|
|
65
|
+
plugin: mapPlugin,
|
|
66
|
+
options: {
|
|
67
|
+
ordnanceSurveyApiKey,
|
|
68
|
+
ordnanceSurveyApiSecret
|
|
69
|
+
}
|
|
70
|
+
})
|
|
71
|
+
}
|
|
72
|
+
|
|
60
73
|
server.expose('baseLayoutPath', nunjucksOptions.baseLayoutPath)
|
|
61
74
|
server.expose('viewContext', viewContext)
|
|
62
75
|
server.expose('cacheService', cacheService)
|
|
@@ -423,6 +423,7 @@ export interface PluginOptions {
|
|
|
423
423
|
onRequest?: OnRequestCallback
|
|
424
424
|
baseUrl: string // base URL of the application, protocol and hostname e.g. "https://myapp.com"
|
|
425
425
|
ordnanceSurveyApiKey?: string
|
|
426
|
+
ordnanceSurveyApiSecret?: string
|
|
426
427
|
}
|
|
427
428
|
|
|
428
429
|
export interface FormAdapterSubmissionMessageMeta {
|
|
@@ -70,7 +70,7 @@
|
|
|
70
70
|
|
|
71
71
|
{% set hasErrors = showFieldsetError and component.model.errorMessage %}
|
|
72
72
|
|
|
73
|
-
<div class="govuk-form-group {{ "govuk-form-group--error" if hasErrors }}">
|
|
73
|
+
<div class="govuk-form-group app-location-field {{ "govuk-form-group--error" if hasErrors }}" data-locationtype="{{component.type | lower}}">
|
|
74
74
|
{{ govukFieldset({
|
|
75
75
|
legend: {
|
|
76
76
|
text: component.model.fieldset.legend.text,
|
|
@@ -3,8 +3,10 @@
|
|
|
3
3
|
|
|
4
4
|
{% macro OsGridRefField(component) %}
|
|
5
5
|
{% set hasErrors = component.model.errorMessage %}
|
|
6
|
-
<div class="govuk-form-group {{ "govuk-form-group--error" if hasErrors }}">
|
|
7
|
-
|
|
6
|
+
<div class="govuk-form-group app-location-field {{ "govuk-form-group--error" if hasErrors }}" data-locationtype="{{component.type | lower}}">
|
|
7
|
+
<div class="app-location-field-inputs">
|
|
8
|
+
{{ TextField(component) }}
|
|
9
|
+
</div>
|
|
8
10
|
|
|
9
11
|
{% if component.model.instructionText %}
|
|
10
12
|
{{ govukDetails({
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { getRoutes } from '~/src/server/plugins/map/routes/index.js'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @satisfies {NamedPlugin<MapConfiguration>}
|
|
5
|
+
*/
|
|
6
|
+
export const mapPlugin = {
|
|
7
|
+
name: '@defra/forms-engine-plugin/map',
|
|
8
|
+
dependencies: ['@hapi/inert'],
|
|
9
|
+
multiple: false,
|
|
10
|
+
register(server, options) {
|
|
11
|
+
// @ts-expect-error - Request typing
|
|
12
|
+
server.route(getRoutes(options))
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* @import { NamedPlugin } from '@hapi/hapi'
|
|
18
|
+
* @import { MapConfiguration } from '~/src/server/plugins/map/types.js'
|
|
19
|
+
*/
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { post } from '~/src/server/services/httpService.js'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @type {string}
|
|
5
|
+
*/
|
|
6
|
+
let cachedToken
|
|
7
|
+
let tokenExpiry = 0
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Get Ordnance Survey OAuth token
|
|
11
|
+
* @param {MapConfiguration} options - Ordnance survey map options
|
|
12
|
+
*/
|
|
13
|
+
export async function getAccessToken(options) {
|
|
14
|
+
const { ordnanceSurveyApiKey: key, ordnanceSurveyApiSecret: secret } = options
|
|
15
|
+
const now = Date.now()
|
|
16
|
+
|
|
17
|
+
if (cachedToken && now < tokenExpiry) {
|
|
18
|
+
return cachedToken
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const creds = `${key}:${secret}`
|
|
22
|
+
const result = await post('https://api.os.uk/oauth2/token/v1', {
|
|
23
|
+
headers: {
|
|
24
|
+
Authorization: `Basic ${btoa(creds)}`,
|
|
25
|
+
'Content-Type': 'application/x-www-form-urlencoded'
|
|
26
|
+
},
|
|
27
|
+
payload: 'grant_type=client_credentials',
|
|
28
|
+
json: true
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
const data = result.payload
|
|
32
|
+
|
|
33
|
+
cachedToken = data.access_token
|
|
34
|
+
tokenExpiry = now + (data.expires_in - 60) * 1000 // refresh early
|
|
35
|
+
|
|
36
|
+
return cachedToken
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* @import { MapConfiguration } from '~/src/server/plugins/map/types.js'
|
|
41
|
+
*/
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { getAccessToken } from '~/src/server/plugins/map/routes/get-os-token.js'
|
|
2
|
+
import { post } from '~/src/server/services/httpService.js'
|
|
3
|
+
|
|
4
|
+
jest.mock('~/src/server/services/httpService.ts')
|
|
5
|
+
|
|
6
|
+
describe('OS OAuth token', () => {
|
|
7
|
+
describe('getAccessToken', () => {
|
|
8
|
+
it('should get access token', async () => {
|
|
9
|
+
jest.mocked(post).mockResolvedValueOnce({
|
|
10
|
+
res: /** @type {IncomingMessage} */ ({
|
|
11
|
+
statusCode: 200,
|
|
12
|
+
headers: {}
|
|
13
|
+
}),
|
|
14
|
+
payload: {
|
|
15
|
+
access_token: 'access_token',
|
|
16
|
+
expires_in: '299',
|
|
17
|
+
issued_at: '1770036762387',
|
|
18
|
+
token_type: 'Bearer'
|
|
19
|
+
},
|
|
20
|
+
error: undefined
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
const token = await getAccessToken({
|
|
24
|
+
ordnanceSurveyApiKey: 'apikey',
|
|
25
|
+
ordnanceSurveyApiSecret: 'apisecret'
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
expect(token).toBe('access_token')
|
|
29
|
+
|
|
30
|
+
expect(post).toHaveBeenCalledWith('https://api.os.uk/oauth2/token/v1', {
|
|
31
|
+
headers: {
|
|
32
|
+
Authorization: `Basic ${btoa('apikey:apisecret')}`,
|
|
33
|
+
'Content-Type': 'application/x-www-form-urlencoded'
|
|
34
|
+
},
|
|
35
|
+
payload: 'grant_type=client_credentials',
|
|
36
|
+
json: true
|
|
37
|
+
})
|
|
38
|
+
expect(post).toHaveBeenCalledTimes(1)
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
it('should return an cached token', async () => {
|
|
42
|
+
const token = await getAccessToken({
|
|
43
|
+
ordnanceSurveyApiKey: 'apikey',
|
|
44
|
+
ordnanceSurveyApiSecret: 'apisecret'
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
expect(token).toBe('access_token')
|
|
48
|
+
expect(post).toHaveBeenCalledTimes(0)
|
|
49
|
+
})
|
|
50
|
+
})
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* @import { IncomingMessage } from 'node:http'
|
|
55
|
+
*/
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
import { resolve } from 'node:path'
|
|
2
|
+
|
|
3
|
+
import { StatusCodes } from 'http-status-codes'
|
|
4
|
+
import Joi from 'joi'
|
|
5
|
+
|
|
6
|
+
import { getAccessToken } from '~/src/server/plugins/map/routes/get-os-token.js'
|
|
7
|
+
import { find, nearest } from '~/src/server/plugins/map/service.js'
|
|
8
|
+
import {
|
|
9
|
+
get,
|
|
10
|
+
request as httpRequest
|
|
11
|
+
} from '~/src/server/services/httpService.js'
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Gets the map support routes
|
|
15
|
+
* @param {MapConfiguration} options - ordnance survey names api key
|
|
16
|
+
*/
|
|
17
|
+
export function getRoutes(options) {
|
|
18
|
+
return [
|
|
19
|
+
mapStyleResourceRoutes(),
|
|
20
|
+
mapProxyRoute(options),
|
|
21
|
+
tileProxyRoute(options),
|
|
22
|
+
geocodeProxyRoute(options),
|
|
23
|
+
reverseGeocodeProxyRoute(options)
|
|
24
|
+
]
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Proxies ordnance survey requests from the front end to api.os.com
|
|
29
|
+
* Used for the VTS map source by forwarding on the request
|
|
30
|
+
* and adding the auth token and SRS (spatial reference system)
|
|
31
|
+
* @param {MapConfiguration} options - the map options
|
|
32
|
+
* @returns {ServerRoute<MapProxyGetRequestRefs>}
|
|
33
|
+
*/
|
|
34
|
+
function mapProxyRoute(options) {
|
|
35
|
+
return {
|
|
36
|
+
method: 'GET',
|
|
37
|
+
path: '/api/map-proxy',
|
|
38
|
+
handler: async (request, h) => {
|
|
39
|
+
const { query } = request
|
|
40
|
+
const targetUrl = new URL(decodeURIComponent(query.url))
|
|
41
|
+
const token = await getAccessToken(options)
|
|
42
|
+
|
|
43
|
+
targetUrl.searchParams.set('srs', '3857')
|
|
44
|
+
|
|
45
|
+
const proxyResponse = await httpRequest('get', targetUrl.toString(), {
|
|
46
|
+
headers: {
|
|
47
|
+
Authorization: `Bearer ${token}`
|
|
48
|
+
}
|
|
49
|
+
})
|
|
50
|
+
const buffer = proxyResponse.payload
|
|
51
|
+
const contentType = proxyResponse.res.headers['content-type']
|
|
52
|
+
const response = h.response(buffer)
|
|
53
|
+
|
|
54
|
+
if (contentType) {
|
|
55
|
+
response.type(contentType)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return response
|
|
59
|
+
},
|
|
60
|
+
options: {
|
|
61
|
+
validate: {
|
|
62
|
+
query: Joi.object()
|
|
63
|
+
.keys({
|
|
64
|
+
url: Joi.string().required()
|
|
65
|
+
})
|
|
66
|
+
.optional()
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Proxies ordnance survey requests from the front end to api.os.uk
|
|
74
|
+
* Used for VTS map tiles forwarding on the request and adding the auth token
|
|
75
|
+
* @param {MapConfiguration} options - the map options
|
|
76
|
+
* @returns {ServerRoute<MapProxyGetRequestRefs>}
|
|
77
|
+
*/
|
|
78
|
+
function tileProxyRoute(options) {
|
|
79
|
+
return {
|
|
80
|
+
method: 'GET',
|
|
81
|
+
path: '/api/tile/{z}/{y}/{x}.pbf',
|
|
82
|
+
handler: async (request, h) => {
|
|
83
|
+
const { z, y, x } = request.params
|
|
84
|
+
const token = await getAccessToken(options)
|
|
85
|
+
|
|
86
|
+
const url = `https://api.os.uk/maps/vector/v1/vts/tile/${z}/${y}/${x}.pbf?srs=3857`
|
|
87
|
+
|
|
88
|
+
const { payload, res } = await get(url, {
|
|
89
|
+
headers: {
|
|
90
|
+
Authorization: `Bearer ${token}`,
|
|
91
|
+
Accept: 'application/x-protobuf'
|
|
92
|
+
},
|
|
93
|
+
json: false,
|
|
94
|
+
gunzip: true
|
|
95
|
+
})
|
|
96
|
+
|
|
97
|
+
if (res.statusCode && res.statusCode !== StatusCodes.OK.valueOf()) {
|
|
98
|
+
return h.response('Tile fetch failed').code(res.statusCode)
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return h
|
|
102
|
+
.response(payload)
|
|
103
|
+
.type('application/x-protobuf')
|
|
104
|
+
.header('Cache-Control', 'public, max-age=86400')
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Proxies ordnance survey geocode requests from the front end to api.os.uk
|
|
111
|
+
* Used for the gazzeteer address lookup to find name from query strings like postcode and place names
|
|
112
|
+
* @param {MapConfiguration} options - the map options
|
|
113
|
+
* @returns {ServerRoute<MapGeocodeGetRequestRefs>}
|
|
114
|
+
*/
|
|
115
|
+
function geocodeProxyRoute(options) {
|
|
116
|
+
return {
|
|
117
|
+
method: 'GET',
|
|
118
|
+
path: '/api/geocode-proxy',
|
|
119
|
+
async handler(request, _h) {
|
|
120
|
+
const { query } = request
|
|
121
|
+
const data = await find(query.query, options.ordnanceSurveyApiKey)
|
|
122
|
+
|
|
123
|
+
return data
|
|
124
|
+
},
|
|
125
|
+
options: {
|
|
126
|
+
validate: {
|
|
127
|
+
query: Joi.object()
|
|
128
|
+
.keys({
|
|
129
|
+
query: Joi.string().required()
|
|
130
|
+
})
|
|
131
|
+
.required()
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
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 { query } = request
|
|
150
|
+
const data = await nearest(
|
|
151
|
+
query.easting,
|
|
152
|
+
query.northing,
|
|
153
|
+
options.ordnanceSurveyApiKey
|
|
154
|
+
)
|
|
155
|
+
|
|
156
|
+
return data
|
|
157
|
+
},
|
|
158
|
+
options: {
|
|
159
|
+
validate: {
|
|
160
|
+
query: Joi.object()
|
|
161
|
+
.keys({
|
|
162
|
+
easting: Joi.number().required(),
|
|
163
|
+
northing: Joi.number().required()
|
|
164
|
+
})
|
|
165
|
+
.required()
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Resource routes to return sprites and glyphs
|
|
173
|
+
* @returns {ServerRoute<MapProxyGetRequestRefs>}
|
|
174
|
+
*/
|
|
175
|
+
function mapStyleResourceRoutes() {
|
|
176
|
+
return {
|
|
177
|
+
method: 'GET',
|
|
178
|
+
path: '/api/maps/vts/{path*}',
|
|
179
|
+
options: {
|
|
180
|
+
handler: {
|
|
181
|
+
directory: {
|
|
182
|
+
path: resolve(import.meta.dirname, './vts')
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* @import { ServerRoute } from '@hapi/hapi'
|
|
191
|
+
* @import { MapConfiguration, MapProxyGetRequestRefs, MapGeocodeGetRequestRefs, MapReverseGeocodeGetRequestRefs } from '~/src/server/plugins/map/types.js'
|
|
192
|
+
*/
|