@basemaps/lambda-tiler 6.34.0 → 6.35.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/CHANGELOG.md +28 -0
- package/build/__tests__/config.data.d.ts +2 -1
- package/build/__tests__/config.data.d.ts.map +1 -1
- package/build/__tests__/config.data.js +14 -1
- package/build/__tests__/config.data.js.map +1 -1
- package/build/__tests__/tile.style.json.test.js +17 -3
- package/build/__tests__/tile.style.json.test.js.map +1 -1
- package/build/__tests__/wmts.capability.test.js +17 -0
- package/build/__tests__/wmts.capability.test.js.map +1 -1
- package/build/arcgis/__tests__/arcgis.style.json.test.js +18 -15
- package/build/arcgis/__tests__/arcgis.style.json.test.js.map +1 -1
- package/build/arcgis/__tests__/vector.tiler.server.test.js +14 -7
- package/build/arcgis/__tests__/vector.tiler.server.test.js.map +1 -1
- package/build/arcgis/arcgis.style.json.d.ts.map +1 -1
- package/build/arcgis/arcgis.style.json.js +6 -4
- package/build/arcgis/arcgis.style.json.js.map +1 -1
- package/build/arcgis/vector.tile.server.d.ts.map +1 -1
- package/build/arcgis/vector.tile.server.js +4 -2
- package/build/arcgis/vector.tile.server.js.map +1 -1
- package/build/index.d.ts +1 -3
- package/build/index.d.ts.map +1 -1
- package/build/index.js +7 -8
- package/build/index.js.map +1 -1
- package/build/routes/__tests__/attribution.test.js +3 -2
- package/build/routes/__tests__/attribution.test.js.map +1 -1
- package/build/routes/__tests__/fonts.test.js +36 -7
- package/build/routes/__tests__/fonts.test.js.map +1 -1
- package/build/routes/__tests__/health.test.js +4 -2
- package/build/routes/__tests__/health.test.js.map +1 -1
- package/build/routes/__tests__/sprites.test.js +3 -4
- package/build/routes/__tests__/sprites.test.js.map +1 -1
- package/build/routes/__tests__/tile.json.test.js +24 -2
- package/build/routes/__tests__/tile.json.test.js.map +1 -1
- package/build/routes/__tests__/tile.style.json.test.js +58 -7
- package/build/routes/__tests__/tile.style.json.test.js.map +1 -1
- package/build/routes/__tests__/wmts.test.js +17 -14
- package/build/routes/__tests__/wmts.test.js.map +1 -1
- package/build/routes/__tests__/xyz.test.js +4 -2
- package/build/routes/__tests__/xyz.test.js.map +1 -1
- package/build/routes/attribution.d.ts.map +1 -1
- package/build/routes/attribution.js +20 -10
- package/build/routes/attribution.js.map +1 -1
- package/build/routes/config.d.ts +22 -0
- package/build/routes/config.d.ts.map +1 -0
- package/build/routes/config.js +63 -0
- package/build/routes/config.js.map +1 -0
- package/build/routes/health.d.ts.map +1 -1
- package/build/routes/health.js +3 -2
- package/build/routes/health.js.map +1 -1
- package/build/routes/imagery.d.ts.map +1 -1
- package/build/routes/imagery.js +3 -2
- package/build/routes/imagery.js.map +1 -1
- package/build/routes/tile.json.d.ts.map +1 -1
- package/build/routes/tile.json.js +7 -4
- package/build/routes/tile.json.js.map +1 -1
- package/build/routes/tile.style.json.d.ts +4 -3
- package/build/routes/tile.style.json.d.ts.map +1 -1
- package/build/routes/tile.style.json.js +53 -12
- package/build/routes/tile.style.json.js.map +1 -1
- package/build/routes/tile.wmts.d.ts.map +1 -1
- package/build/routes/tile.wmts.js +7 -4
- package/build/routes/tile.wmts.js.map +1 -1
- package/build/routes/tile.xyz.d.ts.map +1 -1
- package/build/routes/tile.xyz.js +4 -2
- package/build/routes/tile.xyz.js.map +1 -1
- package/build/routes/tile.xyz.raster.d.ts.map +1 -1
- package/build/routes/tile.xyz.raster.js +4 -2
- package/build/routes/tile.xyz.raster.js.map +1 -1
- package/build/util/__test__/config.loader.test.d.ts +2 -0
- package/build/util/__test__/config.loader.test.d.ts.map +1 -0
- package/build/util/__test__/config.loader.test.js +79 -0
- package/build/util/__test__/config.loader.test.js.map +1 -0
- package/build/util/assets.provider.d.ts +1 -4
- package/build/util/assets.provider.d.ts.map +1 -1
- package/build/util/assets.provider.js +23 -10
- package/build/util/assets.provider.js.map +1 -1
- package/build/util/config.cache.d.ts +3 -3
- package/build/util/config.cache.d.ts.map +1 -1
- package/build/util/config.cache.js +14 -15
- package/build/util/config.cache.js.map +1 -1
- package/build/util/config.loader.d.ts +10 -0
- package/build/util/config.loader.d.ts.map +1 -0
- package/build/util/config.loader.js +47 -0
- package/build/util/config.loader.js.map +1 -0
- package/build/wmts.capability.d.ts +3 -1
- package/build/wmts.capability.d.ts.map +1 -1
- package/build/wmts.capability.js +5 -15
- package/build/wmts.capability.js.map +1 -1
- package/dist/index.js +66 -66
- package/dist/node_modules/.package-lock.json +1 -1
- package/dist/package-lock.json +2 -2
- package/dist/package.json +1 -1
- package/package.json +8 -9
- package/src/__tests__/config.data.ts +25 -1
- package/src/__tests__/tile.style.json.test.ts +19 -3
- package/src/__tests__/wmts.capability.test.ts +21 -0
- package/src/arcgis/__tests__/arcgis.style.json.test.ts +21 -17
- package/src/arcgis/__tests__/vector.tiler.server.test.ts +17 -8
- package/src/arcgis/arcgis.style.json.ts +6 -4
- package/src/arcgis/vector.tile.server.ts +5 -2
- package/src/index.ts +9 -10
- package/src/routes/__tests__/attribution.test.ts +4 -2
- package/src/routes/__tests__/fonts.test.ts +44 -7
- package/src/routes/__tests__/health.test.ts +4 -2
- package/src/routes/__tests__/sprites.test.ts +3 -4
- package/src/routes/__tests__/tile.json.test.ts +30 -2
- package/src/routes/__tests__/tile.style.json.test.ts +68 -9
- package/src/routes/__tests__/wmts.test.ts +23 -17
- package/src/routes/__tests__/xyz.test.ts +4 -2
- package/src/routes/attribution.ts +23 -8
- package/src/routes/config.ts +83 -0
- package/src/routes/health.ts +4 -2
- package/src/routes/imagery.ts +3 -2
- package/src/routes/tile.json.ts +10 -4
- package/src/routes/tile.style.json.ts +58 -12
- package/src/routes/tile.wmts.ts +9 -4
- package/src/routes/tile.xyz.raster.ts +4 -2
- package/src/routes/tile.xyz.ts +5 -2
- package/src/util/__test__/config.loader.test.ts +116 -0
- package/src/util/assets.provider.ts +11 -12
- package/src/util/config.cache.ts +18 -18
- package/src/util/config.loader.ts +50 -0
- package/src/wmts.capability.ts +9 -15
- package/tsconfig.tsbuildinfo +1 -1
package/dist/package-lock.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@basemaps/lambda-tiler",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.35.0",
|
|
4
4
|
"lockfileVersion": 2,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@basemaps/lambda-tiler",
|
|
9
|
-
"version": "6.
|
|
9
|
+
"version": "6.35.0",
|
|
10
10
|
"license": "MIT",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"sharp": "0.30.7"
|
package/dist/package.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@basemaps/lambda-tiler",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.35.0",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "https://github.com/linz/basemaps.git",
|
|
@@ -22,17 +22,16 @@
|
|
|
22
22
|
"types": "./build/index.d.ts",
|
|
23
23
|
"license": "MIT",
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@basemaps/config": "^6.
|
|
25
|
+
"@basemaps/config": "^6.35.0",
|
|
26
26
|
"@basemaps/geo": "^6.32.1",
|
|
27
|
-
"@basemaps/
|
|
28
|
-
"@basemaps/
|
|
29
|
-
"@basemaps/tiler": "^6.
|
|
30
|
-
"@
|
|
31
|
-
"@chunkd/fs": "^8.4.0",
|
|
27
|
+
"@basemaps/shared": "^6.35.0",
|
|
28
|
+
"@basemaps/tiler": "^6.35.0",
|
|
29
|
+
"@basemaps/tiler-sharp": "^6.35.0",
|
|
30
|
+
"@chunkd/fs": "^8.5.1",
|
|
32
31
|
"@cogeotiff/core": "^7.0.0",
|
|
33
32
|
"@cotar/core": "^5.4.0",
|
|
34
33
|
"@linzjs/geojson": "^6.32.1",
|
|
35
|
-
"@linzjs/lambda": "^
|
|
34
|
+
"@linzjs/lambda": "^4.0.0",
|
|
36
35
|
"p-limit": "^4.0.0",
|
|
37
36
|
"path-to-regexp": "^6.1.0",
|
|
38
37
|
"pixelmatch": "^5.1.0",
|
|
@@ -59,5 +58,5 @@
|
|
|
59
58
|
"@types/sharp": "^0.30.3",
|
|
60
59
|
"pretty-json-log": "^1.0.0"
|
|
61
60
|
},
|
|
62
|
-
"gitHead": "
|
|
61
|
+
"gitHead": "dcebd7149ab318ea979b5d1ba34a9f82fc41b935"
|
|
63
62
|
}
|
|
@@ -1,5 +1,16 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
base58,
|
|
3
|
+
BaseConfig,
|
|
4
|
+
ConfigImagery,
|
|
5
|
+
ConfigProvider,
|
|
6
|
+
ConfigProviderMemory,
|
|
7
|
+
ConfigTileSetRaster,
|
|
8
|
+
ConfigTileSetVector,
|
|
9
|
+
TileSetType,
|
|
10
|
+
} from '@basemaps/config';
|
|
2
11
|
import { ImageFormat, VectorFormat } from '@basemaps/geo';
|
|
12
|
+
import { fsa } from '@basemaps/shared';
|
|
13
|
+
import { FsMemory } from '../routes/__tests__/memory.fs.js';
|
|
3
14
|
|
|
4
15
|
export const TileSetAerial: ConfigTileSetRaster = {
|
|
5
16
|
id: 'ts_aerial',
|
|
@@ -117,4 +128,17 @@ export class FakeData {
|
|
|
117
128
|
|
|
118
129
|
return tileSet;
|
|
119
130
|
}
|
|
131
|
+
|
|
132
|
+
static bundle(configs: BaseConfig[]): string {
|
|
133
|
+
const cfg = new ConfigProviderMemory();
|
|
134
|
+
for (const rec of configs) cfg.put(rec);
|
|
135
|
+
const output = cfg.toJson();
|
|
136
|
+
const fsMemory = new FsMemory();
|
|
137
|
+
|
|
138
|
+
const configPath = `memory://linz-basemaps/${output.hash}.json`;
|
|
139
|
+
fsMemory.files.set(configPath, Buffer.from(JSON.stringify(output)));
|
|
140
|
+
fsa.register(configPath, fsMemory);
|
|
141
|
+
|
|
142
|
+
return base58.encode(Buffer.from(configPath));
|
|
143
|
+
}
|
|
120
144
|
}
|
|
@@ -55,7 +55,7 @@ o.spec('TileStyleJson', () => {
|
|
|
55
55
|
|
|
56
56
|
o('should not destroy the original configuration', () => {
|
|
57
57
|
const apiKey = 'abc123';
|
|
58
|
-
const converted = convertStyleJson(baseStyleJson, apiKey);
|
|
58
|
+
const converted = convertStyleJson(baseStyleJson, apiKey, null);
|
|
59
59
|
|
|
60
60
|
o(converted.sources.vector).deepEquals({
|
|
61
61
|
type: 'vector',
|
|
@@ -68,7 +68,7 @@ o.spec('TileStyleJson', () => {
|
|
|
68
68
|
|
|
69
69
|
o(JSON.stringify(baseStyleJson).includes(apiKey)).equals(false);
|
|
70
70
|
|
|
71
|
-
const convertedB = convertStyleJson(baseStyleJson, '0x1234');
|
|
71
|
+
const convertedB = convertStyleJson(baseStyleJson, '0x1234', null);
|
|
72
72
|
o(convertedB.sources.vector).deepEquals({
|
|
73
73
|
type: 'vector',
|
|
74
74
|
url: 'https://tiles.test/v1/tiles/topographic/EPSG:3857/tile.json?api=0x1234',
|
|
@@ -85,11 +85,27 @@ o.spec('TileStyleJson', () => {
|
|
|
85
85
|
|
|
86
86
|
o('should convert relative glyphs and sprites', () => {
|
|
87
87
|
const apiKey = '0x9f9f';
|
|
88
|
-
const converted = convertStyleJson(baseStyleJson, apiKey);
|
|
88
|
+
const converted = convertStyleJson(baseStyleJson, apiKey, null);
|
|
89
89
|
o(converted.sprite).equals('https://tiles.test/v1/sprites');
|
|
90
90
|
o(converted.glyphs).equals('https://tiles.test/v1/glyphs');
|
|
91
91
|
|
|
92
92
|
o(JSON.stringify(baseStyleJson).includes(apiKey)).equals(false);
|
|
93
93
|
o(JSON.stringify(baseStyleJson).includes('?api=')).equals(false);
|
|
94
94
|
});
|
|
95
|
+
|
|
96
|
+
o('should convert with config', () => {
|
|
97
|
+
const apiKey = '0x9f9f';
|
|
98
|
+
const converted = convertStyleJson(baseStyleJson, apiKey, 'config.json');
|
|
99
|
+
o(converted.sprite).equals('https://tiles.test/v1/sprites?config=config.json');
|
|
100
|
+
o(converted.glyphs).equals('https://tiles.test/v1/glyphs?config=config.json');
|
|
101
|
+
|
|
102
|
+
o(converted.sources.vector).deepEquals({
|
|
103
|
+
type: 'vector',
|
|
104
|
+
url: 'https://tiles.test/v1/tiles/topographic/EPSG:3857/tile.json?api=0x9f9f&config=config.json',
|
|
105
|
+
});
|
|
106
|
+
o(converted.sources.raster).deepEquals({
|
|
107
|
+
type: 'raster',
|
|
108
|
+
tiles: ['https://tiles.test/v1/tiles/aerial/EPSG:3857/{z}/{x}/{y}.webp?api=0x9f9f&config=config.json'],
|
|
109
|
+
});
|
|
110
|
+
});
|
|
95
111
|
});
|
|
@@ -41,6 +41,27 @@ o.spec('WmtsCapabilities', () => {
|
|
|
41
41
|
);
|
|
42
42
|
});
|
|
43
43
|
|
|
44
|
+
o('should include config location', () => {
|
|
45
|
+
const wmts = new WmtsCapabilities({
|
|
46
|
+
httpBase: 'https://basemaps.test',
|
|
47
|
+
provider: Provider,
|
|
48
|
+
tileMatrix: [GoogleTms],
|
|
49
|
+
tileSet: TileSetAerial,
|
|
50
|
+
imagery: allImagery,
|
|
51
|
+
apiKey,
|
|
52
|
+
config: 's3://linz-basemaps/config.json',
|
|
53
|
+
formats: [ImageFormat.Avif],
|
|
54
|
+
isIndividualLayers: false,
|
|
55
|
+
}).toVNode();
|
|
56
|
+
|
|
57
|
+
const urls = tags(wmts, 'ResourceURL');
|
|
58
|
+
o(urls.length).equals(1);
|
|
59
|
+
o(urls[0].attrs.format).equals('image/avif');
|
|
60
|
+
o(urls[0].attrs.template).equals(
|
|
61
|
+
'https://basemaps.test/v1/tiles/aerial/{TileMatrixSet}/{TileMatrix}/{TileCol}/{TileRow}.avif?api=secret1234&config=s3%3A%2F%2Flinz-basemaps%2Fconfig.json',
|
|
62
|
+
);
|
|
63
|
+
});
|
|
64
|
+
|
|
44
65
|
o('should be seting encoding to utf-8', () => {
|
|
45
66
|
const xml = new WmtsCapabilities({
|
|
46
67
|
httpBase: 'https://basemaps.test',
|
|
@@ -1,33 +1,40 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { BaseConfig, ConfigProviderMemory, StyleJson } from '@basemaps/config';
|
|
2
2
|
import { Env } from '@basemaps/shared';
|
|
3
3
|
import o from 'ospec';
|
|
4
4
|
import { createSandbox } from 'sinon';
|
|
5
5
|
import { handler } from '../../index.js';
|
|
6
|
+
import { ConfigLoader } from '../../util/config.loader.js';
|
|
6
7
|
import { FakeData } from '../../__tests__/config.data.js';
|
|
7
8
|
import { Api, mockRequest, mockUrlRequest } from '../../__tests__/xyz.util.js';
|
|
8
9
|
|
|
9
|
-
o.spec('
|
|
10
|
+
o.spec('arcgis/stylejson', () => {
|
|
10
11
|
const host = 'https://tiles.test';
|
|
11
12
|
const sandbox = createSandbox();
|
|
13
|
+
const config = new ConfigProviderMemory();
|
|
12
14
|
|
|
13
15
|
o.before(() => {
|
|
14
16
|
process.env[Env.PublicUrlBase] = host;
|
|
15
17
|
});
|
|
16
|
-
|
|
18
|
+
|
|
19
|
+
o.beforeEach(() => {
|
|
20
|
+
sandbox.stub(ConfigLoader, 'getDefaultConfig').resolves(config);
|
|
21
|
+
config.objects.clear();
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
o.afterEach(() => {
|
|
25
|
+
sandbox.restore();
|
|
26
|
+
});
|
|
27
|
+
|
|
17
28
|
o('should not found tile set', async () => {
|
|
18
29
|
const request = mockRequest('/v1/arcgis/rest/services/topographic/VectorTileServer/root.json', 'get', Api.header);
|
|
19
30
|
|
|
20
|
-
sandbox.stub(Config.TileSet, 'get').resolves(null);
|
|
21
|
-
|
|
22
31
|
const res = await handler.router.handle(request);
|
|
23
32
|
o(res.status).equals(404);
|
|
24
33
|
});
|
|
25
34
|
|
|
26
35
|
o('should not found style', async () => {
|
|
27
36
|
const request = mockRequest('/v1/arcgis/rest/services/topographic/VectorTileServer/root.json', 'get', Api.header);
|
|
28
|
-
|
|
29
|
-
sandbox.stub(Config.TileSet, 'get').resolves(FakeData.tileSetVector('topographic'));
|
|
30
|
-
sandbox.stub(Config.Style, 'get').resolves(null);
|
|
37
|
+
config.put(FakeData.tileSetVector('topographic'));
|
|
31
38
|
|
|
32
39
|
const res = await handler.router.handle(request);
|
|
33
40
|
o(res.status).equals(404);
|
|
@@ -87,8 +94,8 @@ o.spec('v1/arcgis/rest/services/', () => {
|
|
|
87
94
|
o('should serve style json and remove the raster source and layers, then replace the vector url', async () => {
|
|
88
95
|
const request = mockRequest('/v1/arcgis/rest/services/topographic/VectorTileServer/root.json', 'get', Api.header);
|
|
89
96
|
|
|
90
|
-
|
|
91
|
-
|
|
97
|
+
config.put(FakeData.tileSetVector('topographic'));
|
|
98
|
+
config.put(fakeRecord);
|
|
92
99
|
|
|
93
100
|
const res = await handler.router.handle(request);
|
|
94
101
|
o(res.status).equals(200);
|
|
@@ -112,8 +119,8 @@ o.spec('v1/arcgis/rest/services/', () => {
|
|
|
112
119
|
o('should not found for raster tileset', async () => {
|
|
113
120
|
const request = mockRequest('/v1/arcgis/rest/services/raster/VectorTileServer/root.json', 'get', Api.header);
|
|
114
121
|
|
|
115
|
-
|
|
116
|
-
|
|
122
|
+
config.put(FakeData.tileSetRaster('raster'));
|
|
123
|
+
config.put(fakeRecord);
|
|
117
124
|
|
|
118
125
|
const res = await handler.router.handle(request);
|
|
119
126
|
o(res.status).equals(404);
|
|
@@ -126,11 +133,8 @@ o.spec('v1/arcgis/rest/services/', () => {
|
|
|
126
133
|
Api.header,
|
|
127
134
|
);
|
|
128
135
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
.stub(Config.Style, 'get')
|
|
132
|
-
.withArgs('st_topolite')
|
|
133
|
-
.resolves(fakeRecord as any);
|
|
136
|
+
config.put({ id: 'st_topolite', name: 'topographic', style: fakeStyle } as BaseConfig);
|
|
137
|
+
config.put(FakeData.tileSetVector('topographic'));
|
|
134
138
|
|
|
135
139
|
const res = await handler.router.handle(request);
|
|
136
140
|
o(res.status).equals(200);
|
|
@@ -1,31 +1,40 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ConfigProviderMemory } from '@basemaps/config';
|
|
2
2
|
import { Env } from '@basemaps/shared';
|
|
3
3
|
import o from 'ospec';
|
|
4
4
|
import { createSandbox } from 'sinon';
|
|
5
5
|
import { handler } from '../../index.js';
|
|
6
|
+
import { ConfigLoader } from '../../util/config.loader.js';
|
|
6
7
|
import { FakeData } from '../../__tests__/config.data.js';
|
|
7
8
|
import { Api, mockRequest, mockUrlRequest } from '../../__tests__/xyz.util.js';
|
|
8
9
|
|
|
9
|
-
o.spec('
|
|
10
|
+
o.spec('arcgis/VectorTileServer', () => {
|
|
10
11
|
const host = 'https://tiles.test';
|
|
11
12
|
const sandbox = createSandbox();
|
|
13
|
+
const config = new ConfigProviderMemory();
|
|
12
14
|
|
|
13
15
|
o.before(() => {
|
|
14
16
|
process.env[Env.PublicUrlBase] = host;
|
|
15
17
|
});
|
|
16
|
-
|
|
18
|
+
|
|
19
|
+
o.beforeEach(() => {
|
|
20
|
+
sandbox.stub(ConfigLoader, 'getDefaultConfig').resolves(config);
|
|
21
|
+
config.objects.clear();
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
o.afterEach(() => {
|
|
25
|
+
sandbox.restore();
|
|
26
|
+
});
|
|
27
|
+
|
|
17
28
|
o('should not found tile set', async () => {
|
|
18
29
|
const request = mockUrlRequest('/v1/arcgis/rest/services/topographic/VectorTileServer', 'f=json', Api.header);
|
|
19
30
|
|
|
20
|
-
sandbox.stub(Config.TileSet, 'get').resolves(null);
|
|
21
|
-
|
|
22
31
|
const res = await handler.router.handle(request);
|
|
23
32
|
o(res.status).equals(404);
|
|
24
33
|
});
|
|
25
34
|
o('should return the vector tile server', async () => {
|
|
26
35
|
const request = mockUrlRequest('/v1/arcgis/rest/services/topographic/VectorTileServer', 'f=json', Api.header);
|
|
27
36
|
|
|
28
|
-
|
|
37
|
+
config.put(FakeData.tileSetVector('topographic'));
|
|
29
38
|
|
|
30
39
|
const res = await handler.router.handle(request);
|
|
31
40
|
o(res.status).equals(200);
|
|
@@ -39,7 +48,7 @@ o.spec('v1/arcgis/rest/services/', () => {
|
|
|
39
48
|
o('should not return with no f=json query', async () => {
|
|
40
49
|
const request = mockRequest('/v1/arcgis/rest/services/topographic/VectorTileServer', 'get', Api.header);
|
|
41
50
|
|
|
42
|
-
|
|
51
|
+
config.put(FakeData.tileSetVector('topographic'));
|
|
43
52
|
|
|
44
53
|
const res = await handler.router.handle(request);
|
|
45
54
|
o(res.status).equals(404);
|
|
@@ -52,7 +61,7 @@ o.spec('v1/arcgis/rest/services/', () => {
|
|
|
52
61
|
'POST',
|
|
53
62
|
);
|
|
54
63
|
|
|
55
|
-
|
|
64
|
+
config.put(FakeData.tileSetVector('topographic'));
|
|
56
65
|
|
|
57
66
|
const res = await handler.router.handle(request);
|
|
58
67
|
o(res.status).equals(200);
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Sources, StyleJson, TileSetType } from '@basemaps/config';
|
|
2
2
|
import { Env, fsa } from '@basemaps/shared';
|
|
3
3
|
import { HttpHeader, LambdaHttpRequest, LambdaHttpResponse } from '@linzjs/lambda';
|
|
4
4
|
import { convertRelativeUrl } from '../routes/tile.style.json.js';
|
|
5
|
+
import { ConfigLoader } from '../util/config.loader.js';
|
|
5
6
|
import { Etag } from '../util/etag.js';
|
|
6
7
|
import { NotFound, NotModified } from '../util/response.js';
|
|
7
8
|
import { Validate } from '../util/validate.js';
|
|
@@ -54,15 +55,16 @@ function convertStyleJson(tileSet: string, style: StyleJson, apiKey: string): St
|
|
|
54
55
|
|
|
55
56
|
export async function arcgisStyleJsonGet(req: LambdaHttpRequest<StyleGet>): Promise<LambdaHttpResponse> {
|
|
56
57
|
const apiKey = Validate.apiKey(req);
|
|
57
|
-
const
|
|
58
|
+
const config = await ConfigLoader.load(req);
|
|
59
|
+
const tileSet = await config.TileSet.get(config.TileSet.id(req.params.tileSet));
|
|
58
60
|
if (tileSet?.type !== TileSetType.Vector) return NotFound();
|
|
59
61
|
|
|
60
62
|
const style = req.query.get('style');
|
|
61
63
|
const styleName = style ? style : 'topographic'; // Defalut to topographic style
|
|
62
64
|
|
|
63
65
|
// Get style Config from db
|
|
64
|
-
const dbId =
|
|
65
|
-
const styleConfig = await
|
|
66
|
+
const dbId = config.Style.id(styleName);
|
|
67
|
+
const styleConfig = await config.Style.get(dbId);
|
|
66
68
|
if (styleConfig == null) return NotFound();
|
|
67
69
|
|
|
68
70
|
// Prepare sources and add linz source
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { TileSetType } from '@basemaps/config';
|
|
2
2
|
import { GoogleTms } from '@basemaps/geo';
|
|
3
3
|
import { HttpHeader, LambdaHttpRequest, LambdaHttpResponse } from '@linzjs/lambda';
|
|
4
4
|
import { convertRelativeUrl } from '../routes/tile.style.json.js';
|
|
5
|
+
import { ConfigLoader } from '../util/config.loader.js';
|
|
5
6
|
import { NotFound } from '../util/response.js';
|
|
6
7
|
import { Validate } from '../util/validate.js';
|
|
7
8
|
|
|
@@ -16,7 +17,9 @@ export interface VectorTileServer {
|
|
|
16
17
|
}
|
|
17
18
|
|
|
18
19
|
export async function arcgisTileServerGet(req: LambdaHttpRequest<VectorTileServer>): Promise<LambdaHttpResponse> {
|
|
19
|
-
const
|
|
20
|
+
const config = await ConfigLoader.load(req);
|
|
21
|
+
|
|
22
|
+
const tileSet = await config.TileSet.get(config.TileSet.id(req.params.tileSet));
|
|
20
23
|
if (tileSet?.type !== TileSetType.Vector) return NotFound();
|
|
21
24
|
const apiKey = Validate.apiKey(req);
|
|
22
25
|
const f = req.query.get('f');
|
package/src/index.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { LogConfig } from '@basemaps/shared';
|
|
2
2
|
import { LambdaHttpResponse, lf } from '@linzjs/lambda';
|
|
3
3
|
import { arcgisInfoGet } from './arcgis/arcgis.info.js';
|
|
4
4
|
import { arcgisStyleJsonGet } from './arcgis/arcgis.style.json.js';
|
|
5
5
|
import { arcgisTileServerGet } from './arcgis/vector.tile.server.js';
|
|
6
6
|
import { tileAttributionGet } from './routes/attribution.js';
|
|
7
|
+
import { configImageryGet, configTileSetGet } from './routes/config.js';
|
|
7
8
|
import { fontGet, fontList } from './routes/fonts.js';
|
|
8
9
|
import { healthGet } from './routes/health.js';
|
|
9
10
|
import { imageryGet } from './routes/imagery.js';
|
|
@@ -14,29 +15,23 @@ import { styleJsonGet } from './routes/tile.style.json.js';
|
|
|
14
15
|
import { wmtsCapabilitiesGet } from './routes/tile.wmts.js';
|
|
15
16
|
import { tileXyzGet } from './routes/tile.xyz.js';
|
|
16
17
|
import { versionGet } from './routes/version.js';
|
|
17
|
-
import { assetProvider } from './util/assets.provider.js';
|
|
18
18
|
import { NotFound, OkResponse } from './util/response.js';
|
|
19
19
|
import { CoSources } from './util/source.cache.js';
|
|
20
20
|
import { St } from './util/source.tracer.js';
|
|
21
21
|
|
|
22
22
|
export const handler = lf.http(LogConfig.get());
|
|
23
23
|
|
|
24
|
+
/** If the request takes too long, respond with a 408 timeout when there is approx 1 second remaining */
|
|
25
|
+
handler.router.timeoutEarlyMs = 1_000;
|
|
26
|
+
|
|
24
27
|
handler.router.hook('request', (req) => {
|
|
25
28
|
req.set('name', 'LambdaTiler');
|
|
26
29
|
|
|
27
|
-
// Set the asset location for asset provider
|
|
28
|
-
const assetLocation = Env.get(Env.AssetLocation);
|
|
29
|
-
assetProvider.set(assetLocation);
|
|
30
|
-
|
|
31
30
|
// Reset the request tracing before every request
|
|
32
31
|
St.reset();
|
|
33
32
|
});
|
|
34
33
|
|
|
35
|
-
let totalRequests = 0;
|
|
36
34
|
handler.router.hook('response', (req, res) => {
|
|
37
|
-
totalRequests++;
|
|
38
|
-
req.set('requestsTotal', totalRequests); // Number of requests served by this lambda
|
|
39
|
-
|
|
40
35
|
if (St.requests.length > 0) {
|
|
41
36
|
// TODO this could be relaxed to every say 5% of requests if logging gets too verbose.
|
|
42
37
|
req.set('requests', St.requests.slice(0, 100)); // limit to 100 requests (some tiles need 100s of requests)
|
|
@@ -76,6 +71,10 @@ handler.router.get('/v1/version', versionGet);
|
|
|
76
71
|
// Image Metadata
|
|
77
72
|
handler.router.get('/v1/imagery/:imageryId/:fileName', imageryGet);
|
|
78
73
|
|
|
74
|
+
// Config
|
|
75
|
+
handler.router.get('/v1/config/:tileSet.json', configTileSetGet);
|
|
76
|
+
handler.router.get('/v1/config/:tileSet/:imageryId.json', configImageryGet);
|
|
77
|
+
|
|
79
78
|
// Sprites
|
|
80
79
|
handler.router.get('/v1/sprites/:spriteName', spriteGet);
|
|
81
80
|
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { Attribution } from '@basemaps/attribution';
|
|
2
|
-
import {
|
|
2
|
+
import { ConfigProviderMemory } from '@basemaps/config';
|
|
3
3
|
import { Nztm2000QuadTms } from '@basemaps/geo';
|
|
4
4
|
import { LogConfig } from '@basemaps/shared';
|
|
5
5
|
import { HttpHeader } from '@linzjs/lambda';
|
|
6
6
|
import o from 'ospec';
|
|
7
7
|
import sinon from 'sinon';
|
|
8
8
|
import { handler } from '../../index.js';
|
|
9
|
+
import { ConfigLoader } from '../../util/config.loader.js';
|
|
9
10
|
import { FakeData, Imagery2193, Imagery3857, Provider, TileSetAerial } from '../../__tests__/config.data.js';
|
|
10
11
|
import { mockUrlRequest } from '../../__tests__/xyz.util.js';
|
|
11
12
|
|
|
@@ -283,7 +284,8 @@ o.spec('/v1/attribution', () => {
|
|
|
283
284
|
|
|
284
285
|
o.beforeEach(() => {
|
|
285
286
|
LogConfig.get().level = 'silent';
|
|
286
|
-
|
|
287
|
+
sandbox.stub(ConfigLoader, 'getDefaultConfig').resolves(config);
|
|
288
|
+
|
|
287
289
|
config.objects.clear();
|
|
288
290
|
|
|
289
291
|
config.put(TileSetAerial);
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { base58, ConfigProviderMemory } from '@basemaps/config';
|
|
2
|
+
import { Env, getDefaultConfig } from '@basemaps/shared';
|
|
2
3
|
import { fsa } from '@chunkd/fs';
|
|
3
4
|
import o from 'ospec';
|
|
4
5
|
import { handler } from '../../index.js';
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
6
|
+
import { CachedConfig } from '../../util/config.cache.js';
|
|
7
|
+
import { CoSources } from '../../util/source.cache.js';
|
|
8
|
+
import { Api, mockRequest, mockUrlRequest } from '../../__tests__/xyz.util.js';
|
|
7
9
|
import { fontList } from '../fonts.js';
|
|
8
10
|
import { FsMemory } from './memory.fs.js';
|
|
9
11
|
|
|
@@ -15,12 +17,14 @@ o.spec('/v1/fonts', () => {
|
|
|
15
17
|
const assetLocation = process.env[Env.AssetLocation];
|
|
16
18
|
|
|
17
19
|
o.beforeEach(() => {
|
|
18
|
-
process.env[Env.AssetLocation] = 'memory://';
|
|
19
|
-
|
|
20
|
+
process.env[Env.AssetLocation] = 'memory://config';
|
|
21
|
+
getDefaultConfig().assets = 'memory://';
|
|
20
22
|
});
|
|
21
23
|
|
|
22
24
|
o.afterEach(() => {
|
|
23
|
-
|
|
25
|
+
getDefaultConfig().assets = assetLocation;
|
|
26
|
+
CachedConfig.cache.clear();
|
|
27
|
+
CoSources.cache.clear();
|
|
24
28
|
memory.files.clear();
|
|
25
29
|
});
|
|
26
30
|
|
|
@@ -64,8 +68,41 @@ o.spec('/v1/fonts', () => {
|
|
|
64
68
|
});
|
|
65
69
|
|
|
66
70
|
o('should return 404 if no asset location set', async () => {
|
|
67
|
-
|
|
71
|
+
getDefaultConfig().assets = undefined;
|
|
68
72
|
const res = await fontList(mockRequest('/v1/fonts.json'));
|
|
69
73
|
o(res.status).equals(404);
|
|
70
74
|
});
|
|
75
|
+
|
|
76
|
+
o('should get the correct utf8 font with default assets', async () => {
|
|
77
|
+
const cfgBundle = new ConfigProviderMemory();
|
|
78
|
+
await fsa.write('memory://linz-basemaps/bar.json', JSON.stringify(cfgBundle.toJson()));
|
|
79
|
+
await fsa.write('memory://config/fonts/🦄 🌈/0-255.pbf', Buffer.from(''));
|
|
80
|
+
|
|
81
|
+
const configLocation = base58.encode(Buffer.from('memory://linz-basemaps/bar.json'));
|
|
82
|
+
const res255 = await handler.router.handle(
|
|
83
|
+
mockUrlRequest('/v1/fonts/🦄 🌈/0-255.pbf', `?config=${configLocation}`, Api.header),
|
|
84
|
+
);
|
|
85
|
+
o(res255.status).equals(200);
|
|
86
|
+
o(res255.header('content-type')).equals('application/x-protobuf');
|
|
87
|
+
o(res255.header('content-encoding')).equals(undefined);
|
|
88
|
+
o(res255.header('etag')).notEquals(undefined);
|
|
89
|
+
o(res255.header('cache-control')).equals('public, max-age=604800, stale-while-revalidate=86400');
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
o('should get the correct utf8 font with config assets', async () => {
|
|
93
|
+
const cfgBundle = new ConfigProviderMemory();
|
|
94
|
+
cfgBundle.assets = 'memory://config/assets';
|
|
95
|
+
await fsa.write('memory://linz-basemaps/bar.json', JSON.stringify(cfgBundle.toJson()));
|
|
96
|
+
await fsa.write('memory://config/assets/fonts/🦄 🌈/0-255.pbf', Buffer.from(''));
|
|
97
|
+
|
|
98
|
+
const configLocation = base58.encode(Buffer.from('memory://linz-basemaps/bar.json'));
|
|
99
|
+
const res255 = await handler.router.handle(
|
|
100
|
+
mockUrlRequest('/v1/fonts/🦄 🌈/0-255.pbf', `?config=${configLocation}`, Api.header),
|
|
101
|
+
);
|
|
102
|
+
o(res255.status).equals(200);
|
|
103
|
+
o(res255.header('content-type')).equals('application/x-protobuf');
|
|
104
|
+
o(res255.header('content-encoding')).equals(undefined);
|
|
105
|
+
o(res255.header('etag')).notEquals(undefined);
|
|
106
|
+
o(res255.header('cache-control')).equals('public, max-age=604800, stale-while-revalidate=86400');
|
|
107
|
+
});
|
|
71
108
|
});
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ConfigProviderMemory } from '@basemaps/config';
|
|
2
2
|
import { LogConfig } from '@basemaps/shared';
|
|
3
3
|
import { LambdaAlbRequest, LambdaHttpRequest, LambdaHttpResponse } from '@linzjs/lambda';
|
|
4
4
|
import { Context } from 'aws-lambda';
|
|
5
5
|
import o from 'ospec';
|
|
6
6
|
import sinon from 'sinon';
|
|
7
|
+
import { ConfigLoader } from '../../util/config.loader.js';
|
|
7
8
|
import { FakeData } from '../../__tests__/config.data.js';
|
|
8
9
|
|
|
9
10
|
import { getTestBuffer, healthGet, TestTiles } from '../health.js';
|
|
@@ -29,11 +30,12 @@ o.spec('/v1/health', async () => {
|
|
|
29
30
|
const fakeTileSet = FakeData.tileSetRaster('health');
|
|
30
31
|
o.beforeEach(() => {
|
|
31
32
|
config.objects.clear();
|
|
32
|
-
|
|
33
|
+
sandbox.stub(ConfigLoader, 'getDefaultConfig').resolves(config);
|
|
33
34
|
config.put(fakeTileSet);
|
|
34
35
|
});
|
|
35
36
|
|
|
36
37
|
o.afterEach(() => {
|
|
38
|
+
config.objects.clear();
|
|
37
39
|
sandbox.restore();
|
|
38
40
|
});
|
|
39
41
|
|
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
import { Env } from '@basemaps/shared';
|
|
1
|
+
import { Env, getDefaultConfig } from '@basemaps/shared';
|
|
2
2
|
import { fsa } from '@chunkd/fs';
|
|
3
3
|
import o from 'ospec';
|
|
4
4
|
import { createSandbox } from 'sinon';
|
|
5
5
|
import { gunzipSync, gzipSync } from 'zlib';
|
|
6
6
|
import { handler } from '../../index.js';
|
|
7
|
-
import { assetProvider } from '../../util/assets.provider.js';
|
|
8
7
|
import { mockRequest } from '../../__tests__/xyz.util.js';
|
|
9
8
|
import { FsMemory } from './memory.fs.js';
|
|
10
9
|
|
|
@@ -18,11 +17,11 @@ o.spec('/v1/sprites', () => {
|
|
|
18
17
|
|
|
19
18
|
o.beforeEach(() => {
|
|
20
19
|
process.env[Env.AssetLocation] = 'memory://';
|
|
21
|
-
|
|
20
|
+
getDefaultConfig().assets = 'memory://';
|
|
22
21
|
});
|
|
23
22
|
|
|
24
23
|
o.afterEach(() => {
|
|
25
|
-
|
|
24
|
+
getDefaultConfig().assets = assetLocation;
|
|
26
25
|
memory.files.clear();
|
|
27
26
|
sandbox.restore();
|
|
28
27
|
});
|
|
@@ -1,23 +1,33 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { base58, ConfigProviderMemory } from '@basemaps/config';
|
|
2
2
|
import { Env } from '@basemaps/shared';
|
|
3
|
+
import { fsa } from '@chunkd/fs';
|
|
3
4
|
import o from 'ospec';
|
|
5
|
+
import sinon from 'sinon';
|
|
4
6
|
import { handler } from '../../index.js';
|
|
7
|
+
import { ConfigLoader } from '../../util/config.loader.js';
|
|
5
8
|
import { CoSources } from '../../util/source.cache.js';
|
|
6
9
|
import { FakeData } from '../../__tests__/config.data.js';
|
|
7
10
|
import { Api, mockRequest, mockUrlRequest } from '../../__tests__/xyz.util.js';
|
|
11
|
+
import { FsMemory } from './memory.fs.js';
|
|
8
12
|
|
|
9
13
|
o.spec('/v1/tiles/:tileSet/:tileMatrix/tile.json', () => {
|
|
10
14
|
const config = new ConfigProviderMemory();
|
|
15
|
+
const sandbox = sinon.createSandbox();
|
|
16
|
+
|
|
11
17
|
o.before(() => {
|
|
12
18
|
process.env[Env.PublicUrlBase] = 'https://tiles.test';
|
|
13
|
-
Config.setConfigProvider(config);
|
|
14
19
|
});
|
|
15
20
|
|
|
16
21
|
o.beforeEach(() => {
|
|
22
|
+
sandbox.stub(ConfigLoader, 'getDefaultConfig').resolves(config);
|
|
17
23
|
config.objects.clear();
|
|
18
24
|
CoSources.cache.clear();
|
|
19
25
|
});
|
|
20
26
|
|
|
27
|
+
o.afterEach(() => {
|
|
28
|
+
sandbox.restore();
|
|
29
|
+
});
|
|
30
|
+
|
|
21
31
|
o('should 404 if invalid url is given', async () => {
|
|
22
32
|
const request = mockRequest('/v1/tiles/tile.json', 'get', Api.header);
|
|
23
33
|
|
|
@@ -123,6 +133,24 @@ o.spec('/v1/tiles/:tileSet/:tileMatrix/tile.json', () => {
|
|
|
123
133
|
});
|
|
124
134
|
});
|
|
125
135
|
|
|
136
|
+
o('should load from config bundle', async () => {
|
|
137
|
+
const memoryFs = new FsMemory();
|
|
138
|
+
fsa.register('memory://', memoryFs);
|
|
139
|
+
const fakeTileSet = FakeData.tileSetRaster('🦄 🌈');
|
|
140
|
+
|
|
141
|
+
const cfgBundle = new ConfigProviderMemory();
|
|
142
|
+
cfgBundle.put(fakeTileSet);
|
|
143
|
+
memoryFs.write('memory://linz-basemaps/bar.json', JSON.stringify(cfgBundle.toJson()));
|
|
144
|
+
|
|
145
|
+
const configLocation = base58.encode(Buffer.from('memory://linz-basemaps/bar.json'));
|
|
146
|
+
const request = mockUrlRequest('/v1/tiles/🦄 🌈/NZTM2000Quad/tile.json', `?config=${configLocation}`, Api.header);
|
|
147
|
+
const res = await handler.router.handle(request);
|
|
148
|
+
o(res.status).equals(200);
|
|
149
|
+
|
|
150
|
+
const body = JSON.parse(Buffer.from(res.body, 'base64').toString());
|
|
151
|
+
o(body.tiles[0].includes(`config=${configLocation}`)).equals(true);
|
|
152
|
+
});
|
|
153
|
+
|
|
126
154
|
o('should serve convert zoom to tile matrix', async () => {
|
|
127
155
|
const fakeTileSet = FakeData.tileSetVector('fake-vector');
|
|
128
156
|
fakeTileSet.maxZoom = 15;
|