@basemaps/lambda-tiler 6.34.0 → 6.36.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 +40 -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 +42 -9
- 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 +5 -11
- 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/fonts.js +1 -1
- package/build/routes/fonts.js.map +1 -1
- 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 +19 -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 +54 -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 +63 -63
- package/dist/node_modules/.package-lock.json +13 -10
- package/dist/node_modules/minimist/.eslintrc +54 -0
- package/dist/node_modules/minimist/.github/FUNDING.yml +12 -0
- package/dist/node_modules/minimist/.nycrc +14 -0
- package/dist/node_modules/minimist/CHANGELOG.md +212 -0
- package/dist/node_modules/minimist/{readme.markdown → README.md} +20 -1
- package/dist/node_modules/minimist/package.json +39 -9
- package/dist/node_modules/node-abi/abi_registry.json +8 -1
- package/dist/node_modules/node-abi/package.json +1 -1
- package/dist/node_modules/semver/classes/range.js +3 -0
- package/dist/node_modules/semver/index.js +81 -41
- package/dist/node_modules/semver/package.json +21 -10
- package/dist/package-lock.json +23 -20
- 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 +48 -11
- package/src/routes/__tests__/health.test.ts +4 -2
- package/src/routes/__tests__/sprites.test.ts +6 -11
- 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/fonts.ts +1 -1
- 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 +8 -12
- package/src/util/config.cache.ts +18 -18
- package/src/util/config.loader.ts +56 -0
- package/src/wmts.capability.ts +9 -15
- package/tsconfig.tsbuildinfo +1 -1
- package/dist/node_modules/minimist/.travis.yml +0 -8
|
@@ -1,26 +1,34 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { base58, ConfigProviderMemory } from '@basemaps/config';
|
|
2
|
+
import { getDefaultConfig } from '@basemaps/shared';
|
|
2
3
|
import { fsa } from '@chunkd/fs';
|
|
3
4
|
import o from 'ospec';
|
|
5
|
+
import { createSandbox } from 'sinon';
|
|
4
6
|
import { handler } from '../../index.js';
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
+
import { CachedConfig } from '../../util/config.cache.js';
|
|
8
|
+
import { ConfigLoader } from '../../util/config.loader.js';
|
|
9
|
+
import { CoSources } from '../../util/source.cache.js';
|
|
10
|
+
import { Api, mockRequest, mockUrlRequest } from '../../__tests__/xyz.util.js';
|
|
7
11
|
import { fontList } from '../fonts.js';
|
|
8
12
|
import { FsMemory } from './memory.fs.js';
|
|
9
13
|
|
|
10
14
|
o.spec('/v1/fonts', () => {
|
|
11
15
|
const memory = new FsMemory();
|
|
16
|
+
const sandbox = createSandbox();
|
|
17
|
+
const config = new ConfigProviderMemory();
|
|
18
|
+
|
|
12
19
|
o.before(() => {
|
|
13
20
|
fsa.register('memory://', memory);
|
|
14
21
|
});
|
|
15
|
-
const assetLocation = process.env[Env.AssetLocation];
|
|
16
22
|
|
|
17
23
|
o.beforeEach(() => {
|
|
18
|
-
|
|
19
|
-
|
|
24
|
+
config.assets = 'memory://';
|
|
25
|
+
sandbox.stub(ConfigLoader, 'getDefaultConfig').resolves(config);
|
|
20
26
|
});
|
|
21
27
|
|
|
22
28
|
o.afterEach(() => {
|
|
23
|
-
|
|
29
|
+
sandbox.restore();
|
|
30
|
+
CachedConfig.cache.clear();
|
|
31
|
+
CoSources.cache.clear();
|
|
24
32
|
memory.files.clear();
|
|
25
33
|
});
|
|
26
34
|
|
|
@@ -30,7 +38,7 @@ o.spec('/v1/fonts', () => {
|
|
|
30
38
|
});
|
|
31
39
|
|
|
32
40
|
o('should return a list of fonts found', async () => {
|
|
33
|
-
await fsa.write('memory://fonts.json', Buffer.from(JSON.stringify(['Roboto Black', 'Roboto Thin'])));
|
|
41
|
+
await fsa.write('memory://fonts/fonts.json', Buffer.from(JSON.stringify(['Roboto Black', 'Roboto Thin'])));
|
|
34
42
|
const res = await fontList(mockRequest('/v1/fonts.json'));
|
|
35
43
|
o(res.status).equals(200);
|
|
36
44
|
o(res.header('content-type')).equals('application/json');
|
|
@@ -40,7 +48,6 @@ o.spec('/v1/fonts', () => {
|
|
|
40
48
|
|
|
41
49
|
o('should get the correct font', async () => {
|
|
42
50
|
await fsa.write('memory://fonts/Roboto Thin/0-255.pbf', Buffer.from(''));
|
|
43
|
-
|
|
44
51
|
const res255 = await handler.router.handle(mockRequest('/v1/fonts/Roboto Thin/0-255.pbf'));
|
|
45
52
|
o(res255.status).equals(200);
|
|
46
53
|
o(res255.header('content-type')).equals('application/x-protobuf');
|
|
@@ -54,7 +61,6 @@ o.spec('/v1/fonts', () => {
|
|
|
54
61
|
|
|
55
62
|
o('should get the correct utf8 font', async () => {
|
|
56
63
|
await fsa.write('memory://fonts/🦄 🌈/0-255.pbf', Buffer.from(''));
|
|
57
|
-
|
|
58
64
|
const res255 = await handler.router.handle(mockRequest('/v1/fonts/🦄 🌈/0-255.pbf'));
|
|
59
65
|
o(res255.status).equals(200);
|
|
60
66
|
o(res255.header('content-type')).equals('application/x-protobuf');
|
|
@@ -64,8 +70,39 @@ o.spec('/v1/fonts', () => {
|
|
|
64
70
|
});
|
|
65
71
|
|
|
66
72
|
o('should return 404 if no asset location set', async () => {
|
|
67
|
-
|
|
73
|
+
getDefaultConfig().assets = undefined;
|
|
68
74
|
const res = await fontList(mockRequest('/v1/fonts.json'));
|
|
69
75
|
o(res.status).equals(404);
|
|
70
76
|
});
|
|
77
|
+
|
|
78
|
+
o('should get the correct utf8 font with default assets', async () => {
|
|
79
|
+
getDefaultConfig().assets = undefined;
|
|
80
|
+
sandbox
|
|
81
|
+
.stub(config.ConfigBundle, 'get')
|
|
82
|
+
.resolves({ id: 'cb_latest', name: 'latest', path: 'latest', hash: 'hash', assets: 'memory://' });
|
|
83
|
+
await fsa.write('memory://fonts/Roboto Thin/0-255.pbf', Buffer.from(''));
|
|
84
|
+
const res255 = await handler.router.handle(mockRequest('/v1/fonts/Roboto Thin/0-255.pbf'));
|
|
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,36 +1,31 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ConfigProviderMemory } from '@basemaps/config';
|
|
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 {
|
|
7
|
+
import { ConfigLoader } from '../../util/config.loader.js';
|
|
8
8
|
import { mockRequest } from '../../__tests__/xyz.util.js';
|
|
9
9
|
import { FsMemory } from './memory.fs.js';
|
|
10
10
|
|
|
11
11
|
o.spec('/v1/sprites', () => {
|
|
12
12
|
const memory = new FsMemory();
|
|
13
13
|
const sandbox = createSandbox();
|
|
14
|
+
const config = new ConfigProviderMemory();
|
|
15
|
+
|
|
14
16
|
o.before(() => {
|
|
15
17
|
fsa.register('memory://', memory);
|
|
16
18
|
});
|
|
17
|
-
const assetLocation = process.env[Env.AssetLocation];
|
|
18
19
|
|
|
19
20
|
o.beforeEach(() => {
|
|
20
|
-
|
|
21
|
-
|
|
21
|
+
config.assets = 'memory://';
|
|
22
|
+
sandbox.stub(ConfigLoader, 'getDefaultConfig').resolves(config);
|
|
22
23
|
});
|
|
23
24
|
|
|
24
25
|
o.afterEach(() => {
|
|
25
|
-
assetProvider.set(assetLocation);
|
|
26
26
|
memory.files.clear();
|
|
27
27
|
sandbox.restore();
|
|
28
28
|
});
|
|
29
|
-
o('should return 404 if no assets defined', async () => {
|
|
30
|
-
delete process.env[Env.AssetLocation];
|
|
31
|
-
const res404 = await handler.router.handle(mockRequest('/v1/sprites/topographic.json'));
|
|
32
|
-
o(res404.status).equals(404);
|
|
33
|
-
});
|
|
34
29
|
|
|
35
30
|
o('should fetch a json document', async () => {
|
|
36
31
|
await Promise.all([
|
|
@@ -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;
|
|
@@ -1,24 +1,29 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { 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 {
|
|
6
|
+
import { ConfigLoader } from '../../util/config.loader.js';
|
|
7
|
+
import { FakeData } from '../../__tests__/config.data.js';
|
|
8
|
+
import { Api, mockRequest, mockUrlRequest } from '../../__tests__/xyz.util.js';
|
|
7
9
|
|
|
8
10
|
o.spec('/v1/styles', () => {
|
|
9
11
|
const host = 'https://tiles.test';
|
|
12
|
+
const config = new ConfigProviderMemory();
|
|
10
13
|
const sandbox = createSandbox();
|
|
11
14
|
|
|
12
15
|
o.before(() => {
|
|
13
16
|
process.env[Env.PublicUrlBase] = host;
|
|
14
17
|
});
|
|
15
|
-
|
|
16
|
-
|
|
18
|
+
o.beforeEach(() => {
|
|
19
|
+
sandbox.stub(ConfigLoader, 'getDefaultConfig').resolves(config);
|
|
20
|
+
});
|
|
21
|
+
o.afterEach(() => {
|
|
22
|
+
sandbox.restore();
|
|
23
|
+
config.objects.clear();
|
|
24
|
+
});
|
|
17
25
|
o('should not found style json', async () => {
|
|
18
26
|
const request = mockRequest('/v1/tiles/topographic/Google/style/topographic.json', 'get', Api.header);
|
|
19
|
-
|
|
20
|
-
sandbox.stub(Config.Style, 'get').resolves(null);
|
|
21
|
-
|
|
22
27
|
const res = await handler.router.handle(request);
|
|
23
28
|
o(res.status).equals(404);
|
|
24
29
|
});
|
|
@@ -71,12 +76,12 @@ o.spec('/v1/styles', () => {
|
|
|
71
76
|
};
|
|
72
77
|
|
|
73
78
|
const fakeRecord = {
|
|
74
|
-
id: '
|
|
79
|
+
id: 'st_topographic',
|
|
75
80
|
name: 'topographic',
|
|
76
81
|
style: fakeStyle,
|
|
77
82
|
};
|
|
78
83
|
|
|
79
|
-
|
|
84
|
+
config.put(fakeRecord);
|
|
80
85
|
|
|
81
86
|
const res = await handler.router.handle(request);
|
|
82
87
|
o(res.status).equals(200);
|
|
@@ -102,4 +107,58 @@ o.spec('/v1/styles', () => {
|
|
|
102
107
|
|
|
103
108
|
o(JSON.parse(body)).deepEquals(fakeStyle);
|
|
104
109
|
});
|
|
110
|
+
|
|
111
|
+
o('should create raster styles', async () => {
|
|
112
|
+
const request = mockUrlRequest('/v1/styles/aerial.json', '', Api.header);
|
|
113
|
+
const tileSet = FakeData.tileSetRaster('aerial');
|
|
114
|
+
config.put(tileSet);
|
|
115
|
+
const res = await handler.router.handle(request);
|
|
116
|
+
o(res.status).equals(200);
|
|
117
|
+
|
|
118
|
+
const body = JSON.parse(Buffer.from(res.body, 'base64').toString());
|
|
119
|
+
|
|
120
|
+
o(body.version).equals(8);
|
|
121
|
+
o(body.sources['basemaps-aerial'].type).deepEquals('raster');
|
|
122
|
+
o(body.sources['basemaps-aerial'].tiles).deepEquals([
|
|
123
|
+
`https://tiles.test/v1/tiles/aerial/WebMercatorQuad/{z}/{x}/{y}.webp?api=${Api.key}`,
|
|
124
|
+
]);
|
|
125
|
+
o(body.sources['basemaps-aerial'].tileSize).deepEquals(256);
|
|
126
|
+
o(body.layers).deepEquals([{ id: 'basemaps-aerial', type: 'raster', source: 'basemaps-aerial' }]);
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
o('should support parameters', async () => {
|
|
130
|
+
const request = mockUrlRequest('/v1/styles/aerial.json', '?tileMatrix=NZTM2000Quad&format=jpg', Api.header);
|
|
131
|
+
const tileSet = FakeData.tileSetRaster('aerial');
|
|
132
|
+
config.put(tileSet);
|
|
133
|
+
const res = await handler.router.handle(request);
|
|
134
|
+
o(res.status).equals(200);
|
|
135
|
+
|
|
136
|
+
const body = JSON.parse(Buffer.from(res.body, 'base64').toString());
|
|
137
|
+
|
|
138
|
+
o(body.version).equals(8);
|
|
139
|
+
o(body.sources['basemaps-aerial'].type).deepEquals('raster');
|
|
140
|
+
o(body.sources['basemaps-aerial'].tiles).deepEquals([
|
|
141
|
+
`https://tiles.test/v1/tiles/aerial/NZTM2000Quad/{z}/{x}/{y}.jpeg?api=${Api.key}`,
|
|
142
|
+
]);
|
|
143
|
+
o(body.sources['basemaps-aerial'].tileSize).deepEquals(256);
|
|
144
|
+
o(body.layers).deepEquals([{ id: 'basemaps-aerial', type: 'raster', source: 'basemaps-aerial' }]);
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
o('should create raster styles from custom config', async () => {
|
|
148
|
+
const configId = FakeData.bundle([FakeData.tileSetRaster('aerial')]);
|
|
149
|
+
const request = mockUrlRequest('/v1/styles/aerial.json', `?config=${configId}`, Api.header);
|
|
150
|
+
|
|
151
|
+
const res = await handler.router.handle(request);
|
|
152
|
+
o(res.status).equals(200);
|
|
153
|
+
|
|
154
|
+
const body = JSON.parse(Buffer.from(res.body, 'base64').toString());
|
|
155
|
+
|
|
156
|
+
o(body.version).equals(8);
|
|
157
|
+
o(body.sources['basemaps-aerial'].type).deepEquals('raster');
|
|
158
|
+
o(body.sources['basemaps-aerial'].tiles).deepEquals([
|
|
159
|
+
`https://tiles.test/v1/tiles/aerial/WebMercatorQuad/{z}/{x}/{y}.webp?api=${Api.key}&config=${configId}`,
|
|
160
|
+
]);
|
|
161
|
+
o(body.sources['basemaps-aerial'].tileSize).deepEquals(256);
|
|
162
|
+
o(body.layers).deepEquals([{ id: 'basemaps-aerial', type: 'raster', source: 'basemaps-aerial' }]);
|
|
163
|
+
});
|
|
105
164
|
});
|
|
@@ -1,13 +1,21 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ConfigProviderMemory } from '@basemaps/config';
|
|
2
2
|
import o from 'ospec';
|
|
3
3
|
import { createSandbox } from 'sinon';
|
|
4
4
|
import { handler } from '../../index.js';
|
|
5
|
+
import { ConfigLoader } from '../../util/config.loader.js';
|
|
5
6
|
import { Imagery2193, Imagery3857, Provider, TileSetAerial } from '../../__tests__/config.data.js';
|
|
6
7
|
import { Api, mockUrlRequest } from '../../__tests__/xyz.util.js';
|
|
7
8
|
|
|
8
9
|
o.spec('WMTSRouting', () => {
|
|
9
10
|
const sandbox = createSandbox();
|
|
11
|
+
const config = new ConfigProviderMemory();
|
|
12
|
+
|
|
13
|
+
o.before(() => {
|
|
14
|
+
sandbox.stub(ConfigLoader, 'load').resolves(config);
|
|
15
|
+
});
|
|
16
|
+
|
|
10
17
|
o.afterEach(() => {
|
|
18
|
+
config.objects.clear();
|
|
11
19
|
sandbox.restore();
|
|
12
20
|
});
|
|
13
21
|
|
|
@@ -16,25 +24,17 @@ o.spec('WMTSRouting', () => {
|
|
|
16
24
|
imagery.set(Imagery3857.id, Imagery3857);
|
|
17
25
|
imagery.set(Imagery2193.id, Imagery2193);
|
|
18
26
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
27
|
+
config.put(TileSetAerial);
|
|
28
|
+
config.put(Imagery2193);
|
|
29
|
+
config.put(Imagery3857);
|
|
30
|
+
config.put(Provider);
|
|
22
31
|
|
|
23
|
-
const req = mockUrlRequest(
|
|
32
|
+
const req = mockUrlRequest(
|
|
33
|
+
'/v1/tiles/WMTSCapabilities.xml',
|
|
34
|
+
`format=png&api=${Api.key}&config=s3://linz-basemaps/config.json`,
|
|
35
|
+
);
|
|
24
36
|
const res = await handler.router.handle(req);
|
|
25
37
|
|
|
26
|
-
o(tileSetStub.calledOnce).equals(true);
|
|
27
|
-
o(tileSetStub.args[0][0]).equals('ts_aerial');
|
|
28
|
-
|
|
29
|
-
o(providerStub.calledOnce).equals(true);
|
|
30
|
-
o(providerStub.args[0][0]).equals('pv_linz');
|
|
31
|
-
|
|
32
|
-
o(imageryStub.calledOnce).equals(true);
|
|
33
|
-
o([...imageryStub.args[0][0].values()]).deepEquals([
|
|
34
|
-
'im_01FYWKATAEK2ZTJQ2PX44Y0XNT',
|
|
35
|
-
'im_01FYWKAJ86W9P7RWM1VB62KD0H',
|
|
36
|
-
]);
|
|
37
|
-
|
|
38
38
|
o(res.status).equals(200);
|
|
39
39
|
const lines = Buffer.from(res.body, 'base64').toString().split('\n');
|
|
40
40
|
|
|
@@ -46,5 +46,11 @@ o.spec('WMTSRouting', () => {
|
|
|
46
46
|
'<ows:Title>Google Maps Compatible for the World</ows:Title>',
|
|
47
47
|
'<ows:Title>LINZ NZTM2000 Map Tile Grid V2</ows:Title>',
|
|
48
48
|
]);
|
|
49
|
+
|
|
50
|
+
const resourceURLs = lines.filter((f) => f.includes('<ResourceURL')).map((f) => f.trim());
|
|
51
|
+
o(resourceURLs).deepEquals([
|
|
52
|
+
'<ResourceURL format="image/png" resourceType="tile" template="https://tiles.test/v1/tiles/aerial/{TileMatrixSet}/{TileMatrix}/{TileCol}/{TileRow}.png?api=d01f7w7rnhdzg0p7fyrc9v9ard1&config=Q5pC4UjWdtFLU1CYtLcRSmB49RekgDgMa5EGJnB2M" />',
|
|
53
|
+
'<ResourceURL format="image/png" resourceType="tile" template="https://tiles.test/v1/tiles/ōtorohanga-urban-2021-0.1m/{TileMatrixSet}/{TileMatrix}/{TileCol}/{TileRow}.png?api=d01f7w7rnhdzg0p7fyrc9v9ard1&config=Q5pC4UjWdtFLU1CYtLcRSmB49RekgDgMa5EGJnB2M" />',
|
|
54
|
+
]);
|
|
49
55
|
});
|
|
50
56
|
});
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ConfigProviderMemory } from '@basemaps/config';
|
|
2
2
|
import { LogConfig } from '@basemaps/shared';
|
|
3
3
|
import { round } from '@basemaps/test/build/rounding.js';
|
|
4
4
|
import o from 'ospec';
|
|
5
5
|
import sinon from 'sinon';
|
|
6
6
|
import { handler } from '../../index.js';
|
|
7
|
+
import { ConfigLoader } from '../../util/config.loader.js';
|
|
7
8
|
import { Etag } from '../../util/etag.js';
|
|
8
9
|
import { FakeData } from '../../__tests__/config.data.js';
|
|
9
10
|
import { Api, mockRequest } from '../../__tests__/xyz.util.js';
|
|
@@ -16,7 +17,7 @@ o.spec('/v1/tiles', () => {
|
|
|
16
17
|
|
|
17
18
|
o.beforeEach(() => {
|
|
18
19
|
LogConfig.get().level = 'silent';
|
|
19
|
-
|
|
20
|
+
sandbox.stub(ConfigLoader, 'getDefaultConfig').resolves(config);
|
|
20
21
|
config.objects.clear();
|
|
21
22
|
|
|
22
23
|
for (const tileSetName of TileSetNames) config.put(FakeData.tileSetRaster(tileSetName));
|
|
@@ -25,6 +26,7 @@ o.spec('/v1/tiles', () => {
|
|
|
25
26
|
});
|
|
26
27
|
|
|
27
28
|
o.afterEach(() => {
|
|
29
|
+
config.objects.clear();
|
|
28
30
|
sandbox.restore();
|
|
29
31
|
});
|
|
30
32
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ConfigTileSet, TileSetType } from '@basemaps/config';
|
|
1
|
+
import { ConfigProvider, ConfigTileSet, getAllImagery, TileSetType } from '@basemaps/config';
|
|
2
2
|
import {
|
|
3
3
|
AttributionCollection,
|
|
4
4
|
AttributionItem,
|
|
@@ -8,11 +8,13 @@ import {
|
|
|
8
8
|
NamedBounds,
|
|
9
9
|
Stac,
|
|
10
10
|
StacExtent,
|
|
11
|
+
StacProvider,
|
|
11
12
|
TileMatrixSet,
|
|
12
13
|
} from '@basemaps/geo';
|
|
13
|
-
import {
|
|
14
|
+
import { extractYearRangeFromName, Projection, titleizeImageryName } from '@basemaps/shared';
|
|
14
15
|
import { BBox, MultiPolygon, multiPolygonToWgs84, Pair, union, Wgs84 } from '@linzjs/geojson';
|
|
15
16
|
import { HttpHeader, LambdaHttpRequest, LambdaHttpResponse } from '@linzjs/lambda';
|
|
17
|
+
import { ConfigLoader } from '../util/config.loader.js';
|
|
16
18
|
|
|
17
19
|
import { Etag } from '../util/etag.js';
|
|
18
20
|
import { NotFound, NotModified } from '../util/response.js';
|
|
@@ -62,6 +64,11 @@ function createCoordinates(bbox: BBox, files: NamedBounds[], proj: Projection):
|
|
|
62
64
|
return multiPolygonToWgs84(coordinates, roundToWgs84);
|
|
63
65
|
}
|
|
64
66
|
|
|
67
|
+
function getHost(host: ConfigProvider | null): StacProvider[] | undefined {
|
|
68
|
+
if (host == null) return undefined;
|
|
69
|
+
return [{ name: host.serviceProvider.name, url: host.serviceProvider.site, roles: ['host'] }];
|
|
70
|
+
}
|
|
71
|
+
|
|
65
72
|
/**
|
|
66
73
|
* Build a Single File STAC for the given TileSet.
|
|
67
74
|
*
|
|
@@ -77,10 +84,10 @@ async function tileSetAttribution(
|
|
|
77
84
|
const cols: AttributionCollection[] = [];
|
|
78
85
|
const items: AttributionItem[] = [];
|
|
79
86
|
|
|
80
|
-
const
|
|
87
|
+
const config = await ConfigLoader.load(req);
|
|
88
|
+
const imagery = await getAllImagery(config, tileSet.layers, [tileMatrix.projection]);
|
|
81
89
|
|
|
82
|
-
const host = await
|
|
83
|
-
if (host == null) return null;
|
|
90
|
+
const host = await config.Provider.get(config.Provider.id('linz'));
|
|
84
91
|
|
|
85
92
|
for (const layer of tileSet.layers) {
|
|
86
93
|
const imgId = layer[proj.epsg.code];
|
|
@@ -91,7 +98,13 @@ async function tileSetAttribution(
|
|
|
91
98
|
const bbox = proj.boundsToWgs84BoundingBox(im.bounds).map(roundNumber) as BBox;
|
|
92
99
|
|
|
93
100
|
const years = extractYearRangeFromName(im.name);
|
|
94
|
-
if (years[0] === -1)
|
|
101
|
+
if (years[0] === -1) {
|
|
102
|
+
req.log.debug({ imagery: im.name }, 'Attribution:DefaultYear');
|
|
103
|
+
// Put it in the future so people know its a "fake" date
|
|
104
|
+
years[0] = new Date().getUTCFullYear() + 1;
|
|
105
|
+
years[1] = years[0] + 1;
|
|
106
|
+
}
|
|
107
|
+
|
|
95
108
|
const interval = [years.map((y) => `${y}-01-01T00:00:00Z`) as [string, string]];
|
|
96
109
|
|
|
97
110
|
const extent: StacExtent = { spatial: { bbox: [bbox] }, temporal: { interval } };
|
|
@@ -120,7 +133,7 @@ async function tileSetAttribution(
|
|
|
120
133
|
stac_version: Stac.Version,
|
|
121
134
|
license: Stac.License,
|
|
122
135
|
id: im.id,
|
|
123
|
-
providers:
|
|
136
|
+
providers: getHost(host),
|
|
124
137
|
title: im.title ?? titleizeImageryName(im.name),
|
|
125
138
|
description: 'No description',
|
|
126
139
|
extent,
|
|
@@ -159,8 +172,10 @@ export async function tileAttributionGet(req: LambdaHttpRequest<TileAttributionG
|
|
|
159
172
|
const tileMatrix = Validate.getTileMatrixSet(req.params.tileMatrix);
|
|
160
173
|
if (tileMatrix == null) throw new LambdaHttpResponse(404, 'Tile Matrix not found');
|
|
161
174
|
|
|
175
|
+
const config = await ConfigLoader.load(req);
|
|
176
|
+
|
|
162
177
|
req.timer.start('tileset:load');
|
|
163
|
-
const tileSet = await
|
|
178
|
+
const tileSet = await config.TileSet.get(config.TileSet.id(req.params.tileSet));
|
|
164
179
|
req.timer.end('tileset:load');
|
|
165
180
|
if (tileSet == null || tileSet.type === TileSetType.Vector) return NotFound();
|
|
166
181
|
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { standardizeLayerName } from '@basemaps/config';
|
|
2
|
+
import { GoogleTms, TileMatrixSets } from '@basemaps/geo';
|
|
3
|
+
import { HttpHeader, LambdaHttpRequest, LambdaHttpResponse } from '@linzjs/lambda';
|
|
4
|
+
import { ConfigLoader } from '../util/config.loader.js';
|
|
5
|
+
import { Etag } from '../util/etag.js';
|
|
6
|
+
import { NotFound, NotModified } from '../util/response.js';
|
|
7
|
+
|
|
8
|
+
async function sendJson(req: LambdaHttpRequest, toSend: unknown): Promise<LambdaHttpResponse> {
|
|
9
|
+
const data = Buffer.from(JSON.stringify(toSend));
|
|
10
|
+
|
|
11
|
+
const cacheKey = Etag.key(data);
|
|
12
|
+
if (Etag.isNotModified(req, cacheKey)) return NotModified();
|
|
13
|
+
|
|
14
|
+
const response = new LambdaHttpResponse(200, 'ok');
|
|
15
|
+
response.header(HttpHeader.ETag, cacheKey);
|
|
16
|
+
response.header(HttpHeader.CacheControl, 'no-store');
|
|
17
|
+
response.buffer(data, 'application/json');
|
|
18
|
+
req.set('bytes', data.byteLength);
|
|
19
|
+
return response;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
interface ConfigTileSetGet {
|
|
23
|
+
Params: {
|
|
24
|
+
tileSet: string;
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export async function configTileSetGet(req: LambdaHttpRequest<ConfigTileSetGet>): Promise<LambdaHttpResponse> {
|
|
29
|
+
const config = await ConfigLoader.load(req);
|
|
30
|
+
|
|
31
|
+
req.timer.start('tileset:load');
|
|
32
|
+
const tileSet = await config.TileSet.get(config.TileSet.id(req.params.tileSet));
|
|
33
|
+
req.timer.end('tileset:load');
|
|
34
|
+
if (tileSet == null) return NotFound();
|
|
35
|
+
|
|
36
|
+
return sendJson(req, tileSet);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
interface ConfigImageryGet {
|
|
40
|
+
Params: {
|
|
41
|
+
tileSet: string;
|
|
42
|
+
imageryId: string;
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Load the imagery configuration by either name or id
|
|
48
|
+
*
|
|
49
|
+
* @param req
|
|
50
|
+
* @returns
|
|
51
|
+
*/
|
|
52
|
+
export async function configImageryGet(req: LambdaHttpRequest<ConfigImageryGet>): Promise<LambdaHttpResponse> {
|
|
53
|
+
const config = await ConfigLoader.load(req);
|
|
54
|
+
|
|
55
|
+
req.timer.start('tileset:load');
|
|
56
|
+
const tileSet = await config.TileSet.get(config.TileSet.id(req.params.tileSet));
|
|
57
|
+
req.timer.end('tileset:load');
|
|
58
|
+
if (tileSet == null) return NotFound();
|
|
59
|
+
|
|
60
|
+
req.timer.start('imagery:load');
|
|
61
|
+
let imagery = await config.Imagery.get(config.Imagery.id(req.params.imageryId));
|
|
62
|
+
req.timer.end('imagery:load');
|
|
63
|
+
|
|
64
|
+
if (imagery == null) {
|
|
65
|
+
const imageryLayer = tileSet.layers.find(
|
|
66
|
+
(f) => f.name === req.params.imageryId || standardizeLayerName(f.name) === req.params.imageryId,
|
|
67
|
+
);
|
|
68
|
+
if (imageryLayer == null) return NotFound();
|
|
69
|
+
|
|
70
|
+
const tileMatrix = TileMatrixSets.find(req.query.get('tileMatrix') ?? GoogleTms.identifier);
|
|
71
|
+
if (tileMatrix == null) return NotFound();
|
|
72
|
+
|
|
73
|
+
const imageryId = imageryLayer[tileMatrix.projection.code];
|
|
74
|
+
if (imageryId == null) return NotFound();
|
|
75
|
+
|
|
76
|
+
req.timer.start('imagery:load:sub');
|
|
77
|
+
imagery = await config.Imagery.get(config.Imagery.id(imageryId));
|
|
78
|
+
req.timer.end('imagery:load:sub');
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if (imagery == null) return NotFound();
|
|
82
|
+
return sendJson(req, imagery);
|
|
83
|
+
}
|
package/src/routes/fonts.ts
CHANGED
|
@@ -12,5 +12,5 @@ export async function fontGet(req: LambdaHttpRequest<FontGet>): Promise<LambdaHt
|
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
export async function fontList(req: LambdaHttpRequest): Promise<LambdaHttpResponse> {
|
|
15
|
-
return assetProvider.serve(req, 'fonts.json', 'application/json');
|
|
15
|
+
return assetProvider.serve(req, path.join('fonts', 'fonts.json'), 'application/json');
|
|
16
16
|
}
|
package/src/routes/health.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ConfigTileSetRaster } from '@basemaps/config';
|
|
2
2
|
import { GoogleTms, ImageFormat, Nztm2000QuadTms } from '@basemaps/geo';
|
|
3
3
|
import { HttpHeader, LambdaHttpRequest, LambdaHttpResponse } from '@linzjs/lambda';
|
|
4
4
|
import * as fs from 'fs';
|
|
@@ -6,6 +6,7 @@ import * as path from 'path';
|
|
|
6
6
|
import PixelMatch from 'pixelmatch';
|
|
7
7
|
import Sharp from 'sharp';
|
|
8
8
|
import url from 'url';
|
|
9
|
+
import { ConfigLoader } from '../util/config.loader.js';
|
|
9
10
|
import { TileXyz } from '../util/validate.js';
|
|
10
11
|
import { TileXyzRaster } from './tile.xyz.raster.js';
|
|
11
12
|
|
|
@@ -53,7 +54,8 @@ export async function updateExpectedTile(test: TestTile, newTileData: Buffer, di
|
|
|
53
54
|
* @throws LambdaHttpResponse for failure health test
|
|
54
55
|
*/
|
|
55
56
|
export async function healthGet(req: LambdaHttpRequest): Promise<LambdaHttpResponse> {
|
|
56
|
-
const
|
|
57
|
+
const config = await ConfigLoader.load(req);
|
|
58
|
+
const tileSet = await config.TileSet.get(config.TileSet.id('health'));
|
|
57
59
|
if (tileSet == null) throw new LambdaHttpResponse(500, 'TileSet: "health" not found');
|
|
58
60
|
for (const test of TestTiles) {
|
|
59
61
|
// Get the parse response tile to raw buffer
|
package/src/routes/imagery.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { Config } from '@basemaps/config';
|
|
2
1
|
import { fsa } from '@basemaps/shared';
|
|
3
2
|
import { HttpHeader, LambdaHttpRequest, LambdaHttpResponse } from '@linzjs/lambda';
|
|
4
3
|
import { promisify } from 'util';
|
|
5
4
|
import { gzip } from 'zlib';
|
|
5
|
+
import { ConfigLoader } from '../util/config.loader.js';
|
|
6
6
|
import { isGzip } from '../util/cotar.serve.js';
|
|
7
7
|
import { Etag } from '../util/etag.js';
|
|
8
8
|
import { NotFound, NotModified } from '../util/response.js';
|
|
@@ -34,7 +34,8 @@ export async function imageryGet(req: LambdaHttpRequest<ImageryGet>): Promise<La
|
|
|
34
34
|
const requestedFile = req.params.fileName;
|
|
35
35
|
if (!isAllowedFile(requestedFile)) return NotFound();
|
|
36
36
|
|
|
37
|
-
const
|
|
37
|
+
const config = await ConfigLoader.load(req);
|
|
38
|
+
const imagery = await config.Imagery.get(config.Imagery.id(req.params.imageryId));
|
|
38
39
|
if (imagery == null) return NotFound();
|
|
39
40
|
|
|
40
41
|
const targetPath = fsa.join(imagery.uri, requestedFile);
|