diff --git a/README.md b/README.md
index 046e35a..597376d 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,13 @@
Signal K Node server plugin to provide chart metadata, such as name, description and location of the actual chart tile data.
-Supports both v1 and v2 Signal K resources api paths.
+Chart metadata is derived from the following supported chart file types:
+- MBTiles _(.mbtiles)_
+- TMS _(tilemapresource.xml and tiles)_
+
+Additionally, chart metadata can be entered via the plugin configuration for other chart sources and types _(e.g. WMS, WMTS, S-57 tiles and tilejson)_.
+
+Chart metadata is made available to both v1 and v2 Signal K `resources` api paths.
| Server Version | API | Path |
|--- |--- |--- |
@@ -10,44 +16,57 @@ Supports both v1 and v2 Signal K resources api paths.
| 2.x.x | v2 | `/signalk/v2/api/resources/charts` |
-_Note: v2 resource paths will only be made available on Signal K server >= v2._
+_Note: Version 2 resource paths will only be made available on Signal K server v2.0.0 and later_
-### Usage
+## Usage
-1. Install "Signal K Charts" plugin from Signal K Appstore
+1. Install `@signalk/signalk-charts` from the Signal K Server Appstore
-2. Configure plugin in **Plugin Config**
+2. Configure the plugin in the Admin UI _(**Server -> Plugin Config -> Signal K Charts**)_
-- Add "Chart paths" which are the paths to the folders where chart files are stored. Defaults to `${signalk-configuration-path}/charts`
+3. Activate the plugin
+Chart metadata will then be available to client apps via the resources api `/resources/charts` for example:
+- [Freeboard SK](https://www.npmjs.com/package/@signalk/freeboard-sk)
+- [Tuktuk Chart Plotter](https://www.npmjs.com/package/tuktuk-chart-plotter)
-3. Add "Chart paths" in plugin configuration. Defaults to `${signalk-configuration-path}/charts`
-
+## Configuration
-4. Put charts into selected paths
+### Local Chart Files
-5. Add optional online chart providers
+If you are using chart files stored on the Signal K Server you will need to add the locations where the chart files are stored so the plugin can generate the chart metadata.
-
+Do this by adding "Chart paths" and providing the path to each folder on the Signal K Server where chart files are stored. _(Defaults to `${signalk-configuration-path}/charts`)_
+
+When chart files are added to the folder(s) they will be processed by the plugin and the chart metadata will be available.
-_WMS example:_
+### Online chart providers
-
+If your chart source is not local to the Signal K Server you can add "Online Chart Providers" and enter the required charts metadata for the source.
-6. Activate plugin
+You will need to provide the following information:
+1. A chart name for client applications to display
+2. The URL to the chart source
+3. Select the chart image format
+4. The minimum and maximum zoom levels where chart data is available.
+
+You can also provide a description detailing the chart content.
+
+
+
+For WMS & WMTS sources you can specify the layers you wish to display.
+
+
-7. Use one of the client apps supporting Signal K charts, for example:
-- [Freeboard SK](https://www.npmjs.com/package/@signalk/freeboard-sk)
-- [Tuktuk Chart Plotter](https://www.npmjs.com/package/tuktuk-chart-plotter)
### Supported chart formats
-- [MBTiles](https://github.com/mapbox/mbtiles-spec) file
+- [MBTiles](https://github.com/mapbox/mbtiles-spec) files
- Directory with cached [TMS](https://wiki.osgeo.org/wiki/Tile_Map_Service_Specification) tiles and `tilemapresource.xml`
- Directory with XYZ tiles and `metadata.json`
- Online [TMS](https://wiki.osgeo.org/wiki/Tile_Map_Service_Specification)
@@ -57,13 +76,41 @@ Publicly available MBTiles charts can be found from:
- [Finnish Transport Agency nautical charts](https://github.com/vokkim/rannikkokartat-mbtiles)
- [Signal K World Coastline Map](https://github.com/netAction/signalk-world-coastline-map), download [MBTiles release](https://github.com/netAction/signalk-world-coastline-map/releases/download/v1.0/signalk-world-coastline-map-database.tgz)
+
+---
+
### API
Plugin adds support for `/resources/charts` endpoints described in [Signal K specification](http://signalk.org/specification/1.0.0/doc/otherBranches.html#resourcescharts):
-- `GET /signalk/v1/api/resources/charts/` returns metadata for all available charts
-- `GET /signalk/v1/api/resources/charts/${identifier}/` returns metadata for selected chart
-- `GET /signalk/v1/api/resources/charts/${identifier}/${z}/${x}/${y}` returns a single tile for selected offline chart. As charts-plugin isn't proxy, online charts is not available via this request. You should look the metadata to find proper request.
+- List available charts
+
+```bash
+# v1 API
+GET /signalk/v1/api/resources/charts/`
+
+# v2 API
+GET /signalk/v2/api/resources/charts/`
+```
+
+- Return metadata for selected chart
+
+```bash
+# v1 API
+GET /signalk/v1/api/resources/charts/${identifier}`
+
+# v2 API
+GET /signalk/v2/api/resources/charts/${identifier}`
+```
+
+#### Chart Tiles
+Chart tiles are retrieved using the url defined in the chart metadata.
+
+For local chart files located in the Chart Path(s) defined in the plugin configuration, the url will be:
+
+```bash
+/signalk/chart-tiles/${identifier}/${z}/${x}/${y}
+```
License
-------
diff --git a/package.json b/package.json
index 6c7e308..bf3e4aa 100644
--- a/package.json
+++ b/package.json
@@ -32,10 +32,9 @@
"dependencies": {
"@mapbox/mbtiles": "^0.12.1",
"@signalk/server-api": "^2.0.0-beta.3",
- "baconjs": "1.0.1",
"bluebird": "3.5.1",
"lodash": "^4.17.11",
- "xml2js": "0.4.19"
+ "xml2js": "^0.6.2"
},
"repository": {
"type": "git",
@@ -47,12 +46,12 @@
"@types/node": "^18.14.4",
"@typescript-eslint/eslint-plugin": "^5.52.0",
"@typescript-eslint/parser": "^5.52.0",
- "body-parser": "1.18.2",
+ "body-parser": "^1.18.2",
"chai": "4.1.2",
"chai-http": "^4.2.1",
"eslint": "^8.34.0",
"eslint-config-prettier": "^8.6.0",
- "express": "4.19.2",
+ "express": "^4.19.2",
"mocha": "5.0.0",
"prettier": "^2.8.4",
"typescript": "^4.5.4"
diff --git a/src/charts.ts b/src/charts.ts
index 1ae32c9..0351311 100644
--- a/src/charts.ts
+++ b/src/charts.ts
@@ -80,13 +80,13 @@ function openMbtilesFile(file: string, filename: string) {
type: 'tilelayer',
scale: parseInt(res.metadata.scale) || 250000,
v1: {
- tilemapUrl: `~basePath~/charts/${identifier}/{z}/{x}/{y}`,
+ tilemapUrl: `~tilePath~/${identifier}/{z}/{x}/{y}`,
chartLayers: res.metadata.vector_layers
? parseVectorLayers(res.metadata.vector_layers)
: []
},
v2: {
- url: `~basePath~/charts/${identifier}/{z}/{x}/{y}`,
+ url: `~tilePath~/${identifier}/{z}/{x}/{y}`,
layers: res.metadata.vector_layers
? parseVectorLayers(res.metadata.vector_layers)
: []
@@ -133,11 +133,11 @@ function directoryToMapInfo(file: string, identifier: string) {
;(info._fileFormat = 'directory'),
(info._filePath = file),
(info.v1 = {
- tilemapUrl: `~basePath~/charts/${identifier}/{z}/{x}/{y}`,
+ tilemapUrl: `~tilePath~/${identifier}/{z}/{x}/{y}`,
chartLayers: []
})
info.v2 = {
- url: `~basePath~/charts/${identifier}/{z}/{x}/{y}`,
+ url: `~tilePath~/${identifier}/{z}/{x}/{y}`,
layers: []
}
diff --git a/src/constants.ts b/src/constants.ts
deleted file mode 100644
index e3cd161..0000000
--- a/src/constants.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-export const apiRoutePrefix = {
- 1: '/signalk/v1/api/resources',
- 2: '/signalk/v2/api/resources'
-}
diff --git a/src/index.ts b/src/index.ts
index e76d479..6c403e2 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -1,35 +1,27 @@
import * as bluebird from 'bluebird'
import path from 'path'
-import fs from 'fs'
+import fs, { FSWatcher } from 'fs'
import * as _ from 'lodash'
import { findCharts } from './charts'
-import { apiRoutePrefix } from './constants'
import { ChartProvider, OnlineChartProvider } from './types'
import { Request, Response, Application } from 'express'
import { OutgoingHttpHeaders } from 'http'
import {
Plugin,
- PluginServerApp,
+ ServerAPI,
ResourceProviderRegistry
} from '@signalk/server-api'
-const MIN_ZOOM = 1
-const MAX_ZOOM = 24
-
interface Config {
chartPaths: string[]
onlineChartProviders: OnlineChartProvider[]
+ accessToken: string
}
interface ChartProviderApp
- extends PluginServerApp,
+ extends ServerAPI,
ResourceProviderRegistry,
Application {
- statusMessage?: () => string
- error: (msg: string) => void
- debug: (...msg: unknown[]) => void
- setPluginStatus: (pluginId: string, status?: string) => void
- setPluginError: (pluginId: string, status?: string) => void
config: {
ssl: boolean
configPath: string
@@ -38,16 +30,21 @@ interface ChartProviderApp
}
}
+const MIN_ZOOM = 1
+const MAX_ZOOM = 24
+const chartTilesPath = '/signalk/chart-tiles'
+let chartPaths: Array
+let onlineProviders = {}
+let lastWatchEvent: number | undefined
+const watchers: Array = []
+
module.exports = (app: ChartProviderApp): Plugin => {
- let chartProviders: { [key: string]: ChartProvider } = {}
- let pluginStarted = false
- let props: Config = {
- chartPaths: [],
- onlineChartProviders: []
- }
+ let _chartProviders: { [key: string]: ChartProvider } = {}
const configBasePath = app.config.configPath
const defaultChartsPath = path.join(configBasePath, '/charts')
- const serverMajorVersion = app.config.version ? parseInt(app.config.version.split('.')[0]) : '1'
+ const serverMajorVersion = app.config.version
+ ? parseInt(app.config.version.split('.')[0])
+ : '1'
ensureDirectoryExists(defaultChartsPath)
// ******** REQUIRED PLUGIN DEFINITION *******
@@ -99,7 +96,14 @@ module.exports = (app: ChartProviderApp): Plugin => {
type: 'string',
title: 'Map source / server type',
default: 'tilelayer',
- enum: ['tilelayer', 'S-57', 'WMS', 'WMTS', 'mapstyleJSON', 'tileJSON'],
+ enum: [
+ 'tilelayer',
+ 'S-57',
+ 'WMS',
+ 'WMTS',
+ 'mapboxstyle',
+ 'tilejson'
+ ],
description:
'Map data source type served by the supplied url. (Use tilelayer for xyz / tms tile sources.)'
},
@@ -147,25 +151,27 @@ module.exports = (app: ChartProviderApp): Plugin => {
name: 'Signal K Charts',
schema: () => CONFIG_SCHEMA,
uiSchema: () => CONFIG_UISCHEMA,
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- start: (settings: any) => {
- return doStartup(settings) // return required for tests
+ start: (config: object) => {
+ return doStartup(config as Config) // return required for tests
},
stop: () => {
+ watchers.forEach((w) => w.close())
app.setPluginStatus('stopped')
}
}
- const doStartup = (config: Config) => {
- app.debug('** loaded config: ', config)
- props = { ...config }
+ const doStartup = async (config: Config) => {
+ app.debug(`** loaded config: ${config}`)
- const chartPaths = _.isEmpty(props.chartPaths)
+ registerRoutes()
+ app.setPluginStatus('Started')
+
+ chartPaths = _.isEmpty(config.chartPaths)
? [defaultChartsPath]
- : resolveUniqueChartPaths(props.chartPaths, configBasePath)
+ : resolveUniqueChartPaths(config.chartPaths, configBasePath)
- const onlineProviders = _.reduce(
- props.onlineChartProviders,
+ onlineProviders = _.reduce(
+ config.onlineChartProviders,
(result: { [key: string]: object }, data) => {
const provider = convertOnlineProviderConfig(data)
result[provider.identifier] = provider
@@ -173,59 +179,87 @@ module.exports = (app: ChartProviderApp): Plugin => {
},
{}
)
+
+ chartPaths.forEach((p) => {
+ app.debug(`watching folder.. ${p}`)
+ watchers.push(fs.watch(p, 'utf8', () => handleWatchEvent()))
+ })
+
app.debug(
`Start charts plugin. Chart paths: ${chartPaths.join(
', '
)}, online charts: ${Object.keys(onlineProviders).length}`
)
- // Do not register routes if plugin has been started once already
- pluginStarted === false && registerRoutes()
- pluginStarted = true
- const urlBase = `${app.config.ssl ? 'https' : 'http'}://localhost:${
- 'getExternalPort' in app.config ? app.config.getExternalPort() : 3000
- }`
- app.debug('**urlBase**', urlBase)
- app.setPluginStatus('Started')
+ return loadCharts()
+ }
+
+ // Load chart files
+ const loadCharts = async () => {
+ app.debug(`Loading Charts....`)
- const loadProviders = bluebird
- .mapSeries(chartPaths, (chartPath: string) => findCharts(chartPath))
- .then((list: ChartProvider[]) =>
- _.reduce(list, (result, charts) => _.merge({}, result, charts), {})
+ try {
+ const plist = await bluebird.mapSeries(chartPaths, (chartPath: string) =>
+ findCharts(chartPath)
+ )
+ const charts = _.reduce(
+ plist,
+ (result, charts) => _.merge({}, result, charts),
+ {}
)
+ app.debug(
+ `Chart plugin: Found ${
+ _.keys(charts).length
+ } charts from ${chartPaths.join(', ')}.`
+ )
+ _chartProviders = _.merge({}, charts, onlineProviders)
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ } catch (e: any) {
+ console.error(`Error loading chart providers`, e.message)
+ _chartProviders = {}
+ app.setPluginError(`Error loading chart providers`)
+ }
+ }
- return loadProviders
- .then((charts: { [key: string]: ChartProvider }) => {
- app.debug(
- `Chart plugin: Found ${
- _.keys(charts).length
- } charts from ${chartPaths.join(', ')}.`
- )
- chartProviders = _.merge({}, charts, onlineProviders)
- })
- .catch((e: Error) => {
- console.error(`Error loading chart providers`, e.message)
- chartProviders = {}
- app.setPluginError(`Error loading chart providers`)
- })
+ const refreshProviders = async () => {
+ const td = Date.now() - (lastWatchEvent as number)
+ app.debug(`last watch event time elapsed = ${td}`)
+ if (lastWatchEvent && td > 5000) {
+ app.debug(`Reloading Charts...`)
+ lastWatchEvent = undefined
+ await loadCharts()
+ }
+ }
+
+ const getChartProviders = async (): Promise<{
+ [id: string]: ChartProvider
+ }> => {
+ await refreshProviders()
+ return _chartProviders
+ }
+
+ const handleWatchEvent = () => {
+ lastWatchEvent = Date.now()
}
const registerRoutes = () => {
app.debug('** Registering API paths **')
+ app.debug(`** Registering map tile path (${chartTilesPath} **`)
app.get(
- `/signalk/:version(v[1-2])/api/resources/charts/:identifier/:z([0-9]*)/:x([0-9]*)/:y([0-9]*)`,
+ `${chartTilesPath}/:identifier/:z([0-9]*)/:x([0-9]*)/:y([0-9]*)`,
async (req: Request, res: Response) => {
const { identifier, z, x, y } = req.params
- const provider = chartProviders[identifier]
- if (!provider) {
+ const providers = await getChartProviders()
+ if (!providers[identifier]) {
return res.sendStatus(404)
}
- switch (provider._fileFormat) {
+
+ switch (providers[identifier]._fileFormat) {
case 'directory':
return serveTileFromFilesystem(
res,
- provider,
+ providers[identifier],
parseInt(z),
parseInt(x),
parseInt(y)
@@ -233,14 +267,14 @@ module.exports = (app: ChartProviderApp): Plugin => {
case 'mbtiles':
return serveTileFromMbtiles(
res,
- provider,
+ providers[identifier],
parseInt(z),
parseInt(x),
parseInt(y)
)
default:
console.log(
- `Unknown chart provider fileformat ${provider._fileFormat}`
+ `Unknown chart provider fileformat ${providers[identifier]._fileFormat}`
)
res.status(500).send()
}
@@ -250,24 +284,28 @@ module.exports = (app: ChartProviderApp): Plugin => {
app.debug('** Registering v1 API paths **')
app.get(
- apiRoutePrefix[1] + '/charts/:identifier',
- (req: Request, res: Response) => {
+ '/signalk/v1/api/resources/charts/:identifier',
+ async (req: Request, res: Response) => {
const { identifier } = req.params
- const provider = chartProviders[identifier]
- if (provider) {
- return res.json(sanitizeProvider(provider))
+ const providers = await getChartProviders()
+ if (providers[identifier]) {
+ return res.json(sanitizeProvider(providers[identifier]))
} else {
return res.status(404).send('Not found')
}
}
)
- app.get(apiRoutePrefix[1] + '/charts', (req: Request, res: Response) => {
- const sanitized = _.mapValues(chartProviders, (provider) =>
- sanitizeProvider(provider)
- )
- res.json(sanitized)
- })
+ app.get(
+ '/signalk/v1/api/resources/charts',
+ async (req: Request, res: Response) => {
+ const providers = await getChartProviders()
+ const sanitized = _.mapValues(providers, (provider) =>
+ sanitizeProvider(provider)
+ )
+ res.json(sanitized)
+ }
+ )
// v2 routes
if (serverMajorVersion === 2) {
@@ -283,21 +321,22 @@ module.exports = (app: ChartProviderApp): Plugin => {
app.registerResourceProvider({
type: 'charts',
methods: {
- listResources: (params: {
+ listResources: async (params: {
[key: string]: number | string | object | null
}) => {
- app.debug(`** listResources()`, params)
+ app.debug(`** listResources() ${params}`)
+ const providers = await getChartProviders()
return Promise.resolve(
- _.mapValues(chartProviders, (provider) =>
+ _.mapValues(providers, (provider) =>
sanitizeProvider(provider, 2)
)
)
},
- getResource: (id: string) => {
- app.debug(`** getResource()`, id)
- const provider = chartProviders[id]
- if (provider) {
- return Promise.resolve(sanitizeProvider(provider, 2))
+ getResource: async (id: string) => {
+ app.debug(`** getResource() ${id}`)
+ const providers = await getChartProviders()
+ if (providers[id]) {
+ return Promise.resolve(sanitizeProvider(providers[id], 2))
} else {
throw new Error('Chart not found!')
}
@@ -364,10 +403,12 @@ const sanitizeProvider = (provider: ChartProvider, version = 1) => {
let v
if (version === 1) {
v = _.merge({}, provider.v1)
- v.tilemapUrl = v.tilemapUrl.replace('~basePath~', apiRoutePrefix[1])
- } else if (version === 2) {
+ v.tilemapUrl = v.tilemapUrl
+ ? v.tilemapUrl.replace('~tilePath~', chartTilesPath)
+ : ''
+ } else {
v = _.merge({}, provider.v2)
- v.url = v.url ? v.url.replace('~basePath~', apiRoutePrefix[2]) : ''
+ v.url = v.url ? v.url.replace('~tilePath~', chartTilesPath) : ''
}
provider = _.omit(provider, [
'_filePath',
diff --git a/src/types.ts b/src/types.ts
index dd3e7da..f133bfb 100644
--- a/src/types.ts
+++ b/src/types.ts
@@ -1,4 +1,10 @@
-type MapSourceType = 'tilelayer' | 'S-57' | 'WMS' | 'WMTS' | 'mapstyleJSON' | 'tileJSON'
+type MapSourceType =
+ | 'tilelayer'
+ | 'S-57'
+ | 'WMS'
+ | 'WMTS'
+ | 'mapboxstyle'
+ | 'tilejson'
export interface ChartProvider {
_fileFormat?: 'mbtiles' | 'directory'
@@ -13,11 +19,11 @@ export interface ChartProvider {
scale: number
v1?: {
tilemapUrl: string
- chartLayers: string[]
+ chartLayers?: string[]
}
v2?: {
url: string
- layers: string[]
+ layers?: string[]
}
bounds?: number[]
minzoom?: number
diff --git a/test/expected-charts.json b/test/expected-charts.json
index 5c8b180..7434814 100644
--- a/test/expected-charts.json
+++ b/test/expected-charts.json
@@ -14,7 +14,7 @@
"minzoom": 3,
"name": "MBTILES_19",
"scale": 250000,
- "tilemapUrl": "/signalk/v1/api/resources/charts/test/{z}/{x}/{y}",
+ "tilemapUrl": "/signalk/chart-tiles/test/{z}/{x}/{y}",
"type": "tilelayer"
},
"tms-tiles": {
@@ -32,7 +32,7 @@
"minzoom": 4,
"name": "Översikt Svenska Sjökort",
"scale": 4000000,
- "tilemapUrl": "/signalk/v1/api/resources/charts/tms-tiles/{z}/{x}/{y}",
+ "tilemapUrl": "/signalk/chart-tiles/tms-tiles/{z}/{x}/{y}",
"type": "tilelayer"
},
"unpacked-tiles": {
@@ -50,7 +50,7 @@
"minzoom": 3,
"name": "NOAA MBTiles test file",
"scale": 250000,
- "tilemapUrl": "/signalk/v1/api/resources/charts/unpacked-tiles/{z}/{x}/{y}",
+ "tilemapUrl": "/signalk/chart-tiles/unpacked-tiles/{z}/{x}/{y}",
"type": "tilelayer"
}
}
\ No newline at end of file
diff --git a/test/plugin-test.js b/test/plugin-test.js
index f9bcfa5..00bc8b6 100644
--- a/test/plugin-test.js
+++ b/test/plugin-test.js
@@ -109,7 +109,8 @@ describe('GET /resources/charts', () => {
})
-describe('GET /resources/charts/:identifier/:z/:x/:y', () => {
+
+describe('GET /signalk/chart-tiles/:identifier/:z/:x/:y', () => {
let plugin
let testServer
beforeEach(() =>
@@ -119,11 +120,14 @@ describe('GET /resources/charts/:identifier/:z/:x/:y', () => {
testServer = server
})
)
- afterEach(done => testServer.close(() => done()))
+ afterEach(done => {
+ plugin.stop()
+ testServer.close(() => done())
+ })
it('returns correct tile from MBTiles file', () => {
return plugin.start({})
- .then(() => get(testServer, '/signalk/v1/api/resources/charts/test/4/5/6'))
+ .then(() => get(testServer, '/signalk/chart-tiles/test/4/5/6'))
.then(response => {
// unpacked-tiles contains same tiles as the test.mbtiles file
expectTileResponse(response, 'charts/unpacked-tiles/4/5/6.png', 'image/png')
@@ -133,7 +137,7 @@ describe('GET /resources/charts/:identifier/:z/:x/:y', () => {
it('returns correct tile from directory', () => {
const expectedTile = fs.readFileSync(path.resolve(__dirname, 'charts/unpacked-tiles/4/4/6.png'))
return plugin.start({})
- .then(() => get(testServer, '/signalk/v1/api/resources/charts/unpacked-tiles/4/4/6'))
+ .then(() => get(testServer, '/signalk/chart-tiles/unpacked-tiles/4/4/6'))
.then(response => {
expectTileResponse(response, 'charts/unpacked-tiles/4/4/6.png', 'image/png')
})
@@ -143,7 +147,7 @@ describe('GET /resources/charts/:identifier/:z/:x/:y', () => {
const expectedTile = fs.readFileSync(path.resolve(__dirname, 'charts/tms-tiles/5/17/21.png'))
// Y-coordinate flipped
return plugin.start({})
- .then(() => get(testServer, '/signalk/v1/api/resources/charts/tms-tiles/5/17/10'))
+ .then(() => get(testServer, '/signalk/chart-tiles/tms-tiles/5/17/10'))
.then(response => {
expectTileResponse(response, 'charts/tms-tiles/5/17/21.png', 'image/png')
})
@@ -151,7 +155,7 @@ describe('GET /resources/charts/:identifier/:z/:x/:y', () => {
it('returns 404 for missing tile', () => {
return plugin.start({})
- .then(() => get(testServer, '/signalk/v1/api/resources/charts/tms-tiles/5/55/10'))
+ .then(() => get(testServer, '/signalk/chart-tiles/tms-tiles/5/55/10'))
.catch(e => e.response)
.then(response => {
expect(response.status).to.equal(404)
@@ -160,7 +164,7 @@ describe('GET /resources/charts/:identifier/:z/:x/:y', () => {
it('returns 404 for wrong chart identifier', () => {
return plugin.start({})
- .then(() => get(testServer, '/signalk/v1/api/resources/charts/foo/4/4/6'))
+ .then(() => get(testServer, '/signalk/chart-tiles/foo/4/4/6'))
.catch(e => e.response)
.then(response => {
expect(response.status).to.equal(404)
diff --git a/tsconfig.json b/tsconfig.json
index 8987f83..b16c5ef 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -1,6 +1,6 @@
{
"compilerOptions": {
- "target": "es6",
+ "target": "ES2022",
"module": "commonjs",
"outDir": "./plugin",
"esModuleInterop": true,
@@ -21,7 +21,7 @@
"ignoreCompilerErrors": true,
"excludePrivate": true,
"excludeNotExported": true,
- "target": "ES5",
+ "target": "ES2022",
"moduleResolution": "node",
"preserveConstEnums": true,
"stripInternal": true,