@basemaps/lambda-tiler 7.0.0 → 7.1.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.
Files changed (242) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/build/__tests__/config.data.d.ts +0 -1
  3. package/build/__tests__/config.data.js +2 -6
  4. package/build/__tests__/config.data.js.map +1 -1
  5. package/build/__tests__/index.test.d.ts +0 -1
  6. package/build/__tests__/index.test.js +28 -27
  7. package/build/__tests__/index.test.js.map +1 -1
  8. package/build/__tests__/tile.style.json.test.d.ts +0 -1
  9. package/build/__tests__/tile.style.json.test.js +38 -37
  10. package/build/__tests__/tile.style.json.test.js.map +1 -1
  11. package/build/__tests__/wmts.capability.test.d.ts +0 -1
  12. package/build/__tests__/wmts.capability.test.js +111 -122
  13. package/build/__tests__/wmts.capability.test.js.map +1 -1
  14. package/build/__tests__/xyz.util.d.ts +0 -1
  15. package/build/cli/render.preview.d.ts +0 -1
  16. package/build/cli/render.preview.js +13 -9
  17. package/build/cli/render.preview.js.map +1 -1
  18. package/build/cli/render.tile.d.ts +0 -1
  19. package/build/cli/render.tile.js +25 -17
  20. package/build/cli/render.tile.js.map +1 -1
  21. package/build/index.d.ts +0 -1
  22. package/build/index.js +24 -20
  23. package/build/index.js.map +1 -1
  24. package/build/routes/__tests__/attribution.test.d.ts +0 -1
  25. package/build/routes/__tests__/attribution.test.js +38 -37
  26. package/build/routes/__tests__/attribution.test.js.map +1 -1
  27. package/build/routes/__tests__/fonts.test.d.ts +0 -1
  28. package/build/routes/__tests__/fonts.test.js +61 -63
  29. package/build/routes/__tests__/fonts.test.js.map +1 -1
  30. package/build/routes/__tests__/health.test.d.ts +0 -1
  31. package/build/routes/__tests__/health.test.js +16 -16
  32. package/build/routes/__tests__/health.test.js.map +1 -1
  33. package/build/routes/__tests__/imagery.test.d.ts +0 -1
  34. package/build/routes/__tests__/imagery.test.js +10 -9
  35. package/build/routes/__tests__/imagery.test.js.map +1 -1
  36. package/build/routes/__tests__/memory.fs.d.ts +2 -3
  37. package/build/routes/__tests__/preview.index.test.d.ts +0 -1
  38. package/build/routes/__tests__/preview.index.test.js +88 -42
  39. package/build/routes/__tests__/preview.index.test.js.map +1 -1
  40. package/build/routes/__tests__/sprites.test.d.ts +0 -1
  41. package/build/routes/__tests__/sprites.test.js +34 -34
  42. package/build/routes/__tests__/sprites.test.js.map +1 -1
  43. package/build/routes/__tests__/tile.json.test.d.ts +0 -1
  44. package/build/routes/__tests__/tile.json.test.js +45 -51
  45. package/build/routes/__tests__/tile.json.test.js.map +1 -1
  46. package/build/routes/__tests__/tile.style.json.test.d.ts +0 -1
  47. package/build/routes/__tests__/tile.style.json.test.js +49 -50
  48. package/build/routes/__tests__/tile.style.json.test.js.map +1 -1
  49. package/build/routes/__tests__/wmts.test.d.ts +0 -1
  50. package/build/routes/__tests__/wmts.test.js +27 -20
  51. package/build/routes/__tests__/wmts.test.js.map +1 -1
  52. package/build/routes/__tests__/xyz.test.d.ts +0 -1
  53. package/build/routes/__tests__/xyz.test.js +97 -49
  54. package/build/routes/__tests__/xyz.test.js.map +1 -1
  55. package/build/routes/attribution.d.ts +1 -1
  56. package/build/routes/attribution.js +4 -5
  57. package/build/routes/attribution.js.map +1 -1
  58. package/build/routes/config.d.ts +0 -1
  59. package/build/routes/config.js +1 -2
  60. package/build/routes/config.js.map +1 -1
  61. package/build/routes/fonts.d.ts +0 -1
  62. package/build/routes/fonts.js +2 -3
  63. package/build/routes/fonts.js.map +1 -1
  64. package/build/routes/health.d.ts +1 -2
  65. package/build/routes/health.js +5 -15
  66. package/build/routes/health.js.map +1 -1
  67. package/build/routes/imagery.d.ts +0 -1
  68. package/build/routes/imagery.js +1 -1
  69. package/build/routes/imagery.js.map +1 -1
  70. package/build/routes/ping.d.ts +0 -1
  71. package/build/routes/ping.js +1 -1
  72. package/build/routes/ping.js.map +1 -1
  73. package/build/routes/preview.d.ts +6 -5
  74. package/build/routes/preview.index.d.ts +0 -1
  75. package/build/routes/preview.index.js +6 -5
  76. package/build/routes/preview.index.js.map +1 -1
  77. package/build/routes/preview.js +35 -10
  78. package/build/routes/preview.js.map +1 -1
  79. package/build/routes/sprites.d.ts +0 -1
  80. package/build/routes/sprites.js +2 -4
  81. package/build/routes/sprites.js.map +1 -1
  82. package/build/routes/tile.json.d.ts +0 -1
  83. package/build/routes/tile.json.js +10 -5
  84. package/build/routes/tile.json.js.map +1 -1
  85. package/build/routes/tile.style.json.d.ts +1 -1
  86. package/build/routes/tile.style.json.js +79 -16
  87. package/build/routes/tile.style.json.js.map +1 -1
  88. package/build/routes/tile.wmts.d.ts +0 -1
  89. package/build/routes/tile.wmts.js +8 -9
  90. package/build/routes/tile.wmts.js.map +1 -1
  91. package/build/routes/tile.xyz.d.ts +0 -1
  92. package/build/routes/tile.xyz.js.map +1 -1
  93. package/build/routes/tile.xyz.raster.d.ts +7 -8
  94. package/build/routes/tile.xyz.raster.js +17 -13
  95. package/build/routes/tile.xyz.raster.js.map +1 -1
  96. package/build/routes/tile.xyz.vector.d.ts +0 -1
  97. package/build/routes/tile.xyz.vector.js +4 -3
  98. package/build/routes/tile.xyz.vector.js.map +1 -1
  99. package/build/routes/version.d.ts +0 -1
  100. package/build/routes/version.js +3 -4
  101. package/build/routes/version.js.map +1 -1
  102. package/build/util/__test__/config.loader.test.d.ts +0 -1
  103. package/build/util/__test__/config.loader.test.js +35 -34
  104. package/build/util/__test__/config.loader.test.js.map +1 -1
  105. package/build/util/__test__/filter.test.d.ts +0 -1
  106. package/build/util/__test__/filter.test.js +17 -16
  107. package/build/util/__test__/filter.test.js.map +1 -1
  108. package/build/util/__test__/validate.test.d.ts +0 -1
  109. package/build/util/__test__/validate.test.js +26 -43
  110. package/build/util/__test__/validate.test.js.map +1 -1
  111. package/build/util/assets.provider.d.ts +5 -5
  112. package/build/util/assets.provider.js +8 -8
  113. package/build/util/assets.provider.js.map +1 -1
  114. package/build/util/config.cache.d.ts +2 -2
  115. package/build/util/config.cache.js +14 -3
  116. package/build/util/config.cache.js.map +1 -1
  117. package/build/util/config.loader.d.ts +0 -1
  118. package/build/util/config.loader.js +11 -12
  119. package/build/util/config.loader.js.map +1 -1
  120. package/build/util/cotar.serve.d.ts +3 -3
  121. package/build/util/cotar.serve.js +2 -2
  122. package/build/util/cotar.serve.js.map +1 -1
  123. package/build/util/etag.d.ts +0 -1
  124. package/build/util/etag.js.map +1 -1
  125. package/build/util/filter.d.ts +0 -1
  126. package/build/util/filter.js +4 -5
  127. package/build/util/filter.js.map +1 -1
  128. package/build/util/response.d.ts +0 -1
  129. package/build/util/source.cache.d.ts +8 -9
  130. package/build/util/source.cache.js +27 -24
  131. package/build/util/source.cache.js.map +1 -1
  132. package/build/util/swapping.lru.d.ts +0 -1
  133. package/build/util/swapping.lru.js +48 -7
  134. package/build/util/swapping.lru.js.map +1 -1
  135. package/build/util/validate.d.ts +17 -5
  136. package/build/util/validate.js +51 -15
  137. package/build/util/validate.js.map +1 -1
  138. package/build/wmts.capability.d.ts +1 -2
  139. package/build/wmts.capability.js +81 -12
  140. package/build/wmts.capability.js.map +1 -1
  141. package/bundle.sh +2 -2
  142. package/package.json +16 -18
  143. package/scripts/create.deployment.package.mjs +4 -11
  144. package/src/__tests__/config.data.ts +2 -6
  145. package/src/__tests__/index.test.ts +29 -27
  146. package/src/__tests__/tile.style.json.test.ts +40 -37
  147. package/src/__tests__/wmts.capability.test.ts +139 -120
  148. package/src/cli/render.preview.ts +14 -9
  149. package/src/cli/render.tile.ts +27 -18
  150. package/src/index.ts +28 -23
  151. package/src/routes/__tests__/attribution.test.ts +40 -37
  152. package/src/routes/__tests__/fonts.test.ts +68 -64
  153. package/src/routes/__tests__/health.test.ts +18 -17
  154. package/src/routes/__tests__/imagery.test.ts +11 -9
  155. package/src/routes/__tests__/preview.index.test.ts +114 -40
  156. package/src/routes/__tests__/sprites.test.ts +39 -34
  157. package/src/routes/__tests__/tile.json.test.ts +41 -39
  158. package/src/routes/__tests__/tile.style.json.test.ts +49 -46
  159. package/src/routes/__tests__/wmts.test.ts +28 -20
  160. package/src/routes/__tests__/xyz.test.ts +134 -55
  161. package/src/routes/attribution.ts +2 -2
  162. package/src/routes/config.ts +1 -0
  163. package/src/routes/fonts.ts +3 -3
  164. package/src/routes/health.ts +7 -13
  165. package/src/routes/imagery.ts +2 -1
  166. package/src/routes/ping.ts +1 -1
  167. package/src/routes/preview.index.ts +9 -5
  168. package/src/routes/preview.ts +44 -15
  169. package/src/routes/sprites.ts +4 -5
  170. package/src/routes/tile.json.ts +9 -2
  171. package/src/routes/tile.style.json.ts +89 -13
  172. package/src/routes/tile.wmts.ts +4 -3
  173. package/src/routes/tile.xyz.raster.ts +26 -22
  174. package/src/routes/tile.xyz.ts +1 -0
  175. package/src/routes/tile.xyz.vector.ts +5 -3
  176. package/src/routes/version.ts +3 -3
  177. package/src/util/__test__/config.loader.test.ts +38 -34
  178. package/src/util/__test__/filter.test.ts +19 -16
  179. package/src/util/__test__/validate.test.ts +28 -43
  180. package/src/util/assets.provider.ts +10 -9
  181. package/src/util/config.cache.ts +4 -3
  182. package/src/util/config.loader.ts +13 -13
  183. package/src/util/cotar.serve.ts +3 -2
  184. package/src/util/source.cache.ts +15 -26
  185. package/src/util/validate.ts +61 -14
  186. package/src/wmts.capability.ts +3 -3
  187. package/tsconfig.json +1 -0
  188. package/tsconfig.tsbuildinfo +1 -1
  189. package/build/__tests__/config.data.d.ts.map +0 -1
  190. package/build/__tests__/index.test.d.ts.map +0 -1
  191. package/build/__tests__/tile.style.json.test.d.ts.map +0 -1
  192. package/build/__tests__/wmts.capability.test.d.ts.map +0 -1
  193. package/build/__tests__/xyz.util.d.ts.map +0 -1
  194. package/build/cli/render.preview.d.ts.map +0 -1
  195. package/build/cli/render.tile.d.ts.map +0 -1
  196. package/build/index.d.ts.map +0 -1
  197. package/build/routes/__tests__/attribution.test.d.ts.map +0 -1
  198. package/build/routes/__tests__/fonts.test.d.ts.map +0 -1
  199. package/build/routes/__tests__/health.test.d.ts.map +0 -1
  200. package/build/routes/__tests__/imagery.test.d.ts.map +0 -1
  201. package/build/routes/__tests__/memory.fs.d.ts.map +0 -1
  202. package/build/routes/__tests__/preview.index.test.d.ts.map +0 -1
  203. package/build/routes/__tests__/sprites.test.d.ts.map +0 -1
  204. package/build/routes/__tests__/tile.json.test.d.ts.map +0 -1
  205. package/build/routes/__tests__/tile.style.json.test.d.ts.map +0 -1
  206. package/build/routes/__tests__/wmts.test.d.ts.map +0 -1
  207. package/build/routes/__tests__/xyz.test.d.ts.map +0 -1
  208. package/build/routes/attribution.d.ts.map +0 -1
  209. package/build/routes/config.d.ts.map +0 -1
  210. package/build/routes/fonts.d.ts.map +0 -1
  211. package/build/routes/health.d.ts.map +0 -1
  212. package/build/routes/imagery.d.ts.map +0 -1
  213. package/build/routes/ping.d.ts.map +0 -1
  214. package/build/routes/preview.d.ts.map +0 -1
  215. package/build/routes/preview.index.d.ts.map +0 -1
  216. package/build/routes/sprites.d.ts.map +0 -1
  217. package/build/routes/tile.json.d.ts.map +0 -1
  218. package/build/routes/tile.style.json.d.ts.map +0 -1
  219. package/build/routes/tile.wmts.d.ts.map +0 -1
  220. package/build/routes/tile.xyz.d.ts.map +0 -1
  221. package/build/routes/tile.xyz.raster.d.ts.map +0 -1
  222. package/build/routes/tile.xyz.vector.d.ts.map +0 -1
  223. package/build/routes/version.d.ts.map +0 -1
  224. package/build/util/__test__/config.loader.test.d.ts.map +0 -1
  225. package/build/util/__test__/filter.test.d.ts.map +0 -1
  226. package/build/util/__test__/validate.test.d.ts.map +0 -1
  227. package/build/util/assets.provider.d.ts.map +0 -1
  228. package/build/util/config.cache.d.ts.map +0 -1
  229. package/build/util/config.loader.d.ts.map +0 -1
  230. package/build/util/cotar.serve.d.ts.map +0 -1
  231. package/build/util/etag.d.ts.map +0 -1
  232. package/build/util/filter.d.ts.map +0 -1
  233. package/build/util/response.d.ts.map +0 -1
  234. package/build/util/source.cache.d.ts.map +0 -1
  235. package/build/util/source.tracer.d.ts +0 -18
  236. package/build/util/source.tracer.d.ts.map +0 -1
  237. package/build/util/source.tracer.js +0 -26
  238. package/build/util/source.tracer.js.map +0 -1
  239. package/build/util/swapping.lru.d.ts.map +0 -1
  240. package/build/util/validate.d.ts.map +0 -1
  241. package/build/wmts.capability.d.ts.map +0 -1
  242. package/src/util/source.tracer.ts +0 -38
@@ -1,92 +1,96 @@
1
+ import assert from 'node:assert';
2
+ import { afterEach, before, beforeEach, describe, it } from 'node:test';
3
+
1
4
  import { base58, ConfigProviderMemory } from '@basemaps/config';
2
5
  import { fsa } from '@basemaps/shared';
6
+ import { FsMemory } from '@chunkd/fs';
3
7
  import { LambdaHttpResponse } from '@linzjs/lambda';
4
- import o from 'ospec';
5
8
  import { createSandbox } from 'sinon';
6
- import { FsMemory } from '@chunkd/source-memory';
9
+
7
10
  import { FakeData } from '../../__tests__/config.data.js';
8
11
  import { Api, mockRequest, mockUrlRequest } from '../../__tests__/xyz.util.js';
9
12
  import { CachedConfig } from '../config.cache.js';
10
13
  import { ConfigLoader } from '../config.loader.js';
11
14
 
12
- o.spec('ConfigLoader', () => {
15
+ describe('ConfigLoader', () => {
13
16
  const memory = new FsMemory();
14
17
  const config = new ConfigProviderMemory();
15
18
  const sandbox = createSandbox();
16
19
 
17
- o.before(() => {
20
+ before(() => {
18
21
  fsa.register('memory://', memory);
19
22
  });
20
23
 
21
- o.beforeEach(() => {
24
+ beforeEach(() => {
22
25
  sandbox.stub(ConfigLoader, 'getDefaultConfig').resolves(config);
23
26
  });
24
27
 
25
- o.afterEach(() => {
28
+ afterEach(() => {
26
29
  sandbox.restore();
27
30
  config.objects.clear();
28
31
  memory.files.clear();
29
32
  CachedConfig.cache.clear();
30
33
  });
31
34
 
32
- o('should return default config', async () => {
35
+ it('should return default config', async () => {
33
36
  const provider = await ConfigLoader.load(mockRequest('/v1/fonts.json'));
34
- o(provider).deepEquals(config);
37
+ assert.deepEqual(provider, config);
35
38
  });
36
39
 
37
- o('should Not working with wrong config url', async () => {
40
+ it('should Not working with wrong config url', async () => {
38
41
  const error = await ConfigLoader.load(
39
42
  mockUrlRequest('/v1/tiles/🦄 🌈/NZTM2000Quad/tile.json', `?config=notapath`, Api.header),
40
43
  )
41
44
  .then(() => null)
42
45
  .catch((e) => e);
43
46
 
44
- o(error instanceof LambdaHttpResponse).equals(true);
45
- o((error as LambdaHttpResponse).status).equals(400);
46
- o((error as LambdaHttpResponse).statusDescription).equals('Invalid config location');
47
+ assert.equal(error instanceof LambdaHttpResponse, true);
48
+ assert.equal((error as LambdaHttpResponse).status, 400);
49
+ assert.equal((error as LambdaHttpResponse).statusDescription, 'Invalid configuration location protocol:file:');
47
50
  });
48
51
 
49
- o('should Not working with wrong protocol', async () => {
52
+ it('should Not working with wrong protocol', async () => {
50
53
  const error = await ConfigLoader.load(
51
54
  mockUrlRequest('/v1/tiles/🦄 🌈/NZTM2000Quad/tile.json', `?config=memory1://linz-basemaps/config`, Api.header),
52
55
  )
53
56
  .then(() => null)
54
57
  .catch((e) => e);
55
58
 
56
- o(error instanceof LambdaHttpResponse).equals(true);
57
- o((error as LambdaHttpResponse).status).equals(400);
58
- o((error as LambdaHttpResponse).statusDescription).equals('Invalid configuration location protocol:memory1');
59
+ assert.equal(error instanceof LambdaHttpResponse, true);
60
+ assert.equal((error as LambdaHttpResponse).status, 400);
61
+ assert.equal((error as LambdaHttpResponse).statusDescription, 'Invalid configuration location protocol:memory1:');
59
62
  });
60
63
 
61
- o('should Not working with wrong s3 bucket', async () => {
64
+ it('should Not working with wrong s3 bucket', async () => {
62
65
  const error = await ConfigLoader.load(
63
66
  mockUrlRequest('/v1/tiles/🦄 🌈/NZTM2000Quad/tile.json', `?config=s3://wrong-bucket/config`, Api.header),
64
67
  )
65
68
  .then(() => null)
66
69
  .catch((e) => e);
67
70
 
68
- o(error instanceof LambdaHttpResponse).equals(true);
69
- o((error as LambdaHttpResponse).status).equals(400);
70
- o((error as LambdaHttpResponse).statusDescription).equals(
71
+ assert.equal(error instanceof LambdaHttpResponse, true);
72
+ assert.equal((error as LambdaHttpResponse).status, 400);
73
+ assert.equal(
74
+ (error as LambdaHttpResponse).statusDescription,
71
75
  'Bucket: "wrong-bucket" is not a allowed bucket location',
72
76
  );
73
77
  });
74
78
 
75
- const location = 'memory://linz-basemaps/config.json';
79
+ const location = new URL('memory://linz-basemaps/config.json');
76
80
 
77
- o('should Not working with no file in the path', async () => {
81
+ it('should Not working with no file in the path', async () => {
78
82
  const error = await ConfigLoader.load(
79
83
  mockUrlRequest('/v1/tiles/🦄 🌈/NZTM2000Quad/tile.json', `?config=${location}`, Api.header),
80
84
  )
81
85
  .then(() => null)
82
86
  .catch((e) => e);
83
87
 
84
- o(error instanceof LambdaHttpResponse).equals(true);
85
- o((error as LambdaHttpResponse).status).equals(400);
86
- o((error as LambdaHttpResponse).statusDescription).equals(`Invalid config location at ${location}`);
88
+ assert.equal(error instanceof LambdaHttpResponse, true);
89
+ assert.equal((error as LambdaHttpResponse).status, 400);
90
+ assert.equal((error as LambdaHttpResponse).statusDescription, `Invalid config location at ${location}`);
87
91
  });
88
92
 
89
- o('should get expected config file', async () => {
93
+ it('should get expected config file', async () => {
90
94
  const expectedConfig = new ConfigProviderMemory();
91
95
  expectedConfig.put(FakeData.tileSetRaster('aerial'));
92
96
  await fsa.write(location, Buffer.from(JSON.stringify(expectedConfig.toJson())));
@@ -95,10 +99,10 @@ o.spec('ConfigLoader', () => {
95
99
  mockUrlRequest('/v1/tiles/🦄 🌈/NZTM2000Quad/tile.json', `?config=${location}`, Api.header),
96
100
  );
97
101
 
98
- o(await provider.Imagery.get('aerial')).deepEquals(await expectedConfig.Imagery.get('aerial'));
102
+ assert.deepEqual(await provider.Imagery.get('aerial'), await expectedConfig.Imagery.get('aerial'));
99
103
  });
100
104
 
101
- o('should get expected config file with base58 location', async () => {
105
+ it('should get expected config file with base58 location', async () => {
102
106
  const expectedConfig = new ConfigProviderMemory();
103
107
  expectedConfig.put(FakeData.tileSetVector('topographic'));
104
108
  await fsa.write(location, Buffer.from(JSON.stringify(expectedConfig.toJson())));
@@ -106,24 +110,24 @@ o.spec('ConfigLoader', () => {
106
110
  const provider = await ConfigLoader.load(
107
111
  mockUrlRequest(
108
112
  '/v1/tiles/🦄 🌈/NZTM2000Quad/tile.json',
109
- `?config=${base58.encode(Buffer.from(location))}`,
113
+ `?config=${base58.encode(Buffer.from(location.href))}`,
110
114
  Api.header,
111
115
  ),
112
116
  );
113
117
 
114
- o(await provider.Imagery.get('topographic')).deepEquals(await expectedConfig.Imagery.get('topographic'));
118
+ assert.deepEqual(await provider.Imagery.get('topographic'), await expectedConfig.Imagery.get('topographic'));
115
119
  });
116
120
 
117
121
  const deletedLocation = 'memory://linz-basemaps/config-deleted.json';
118
- o('should Error 400 if config file not exists', async () => {
122
+ it('should Error 400 if config file not exists', async () => {
119
123
  const error = await ConfigLoader.load(
120
124
  mockUrlRequest('/v1/tiles/🦄 🌈/NZTM2000Quad/tile.json', `?config=${deletedLocation}`, Api.header),
121
125
  )
122
126
  .then(() => null)
123
127
  .catch((e) => e);
124
128
 
125
- o(error instanceof LambdaHttpResponse).equals(true);
126
- o((error as LambdaHttpResponse).status).equals(400);
127
- o((error as LambdaHttpResponse).statusDescription).equals(`Invalid config location at ${deletedLocation}`);
129
+ assert.equal(error instanceof LambdaHttpResponse, true);
130
+ assert.equal((error as LambdaHttpResponse).status, 400);
131
+ assert.equal((error as LambdaHttpResponse).statusDescription, `Invalid config location at ${deletedLocation}`);
128
132
  });
129
133
  });
@@ -1,9 +1,12 @@
1
+ import assert from 'node:assert';
2
+ import { describe, it } from 'node:test';
3
+
1
4
  import { ConfigLayer } from '@basemaps/config';
2
- import o from 'ospec';
5
+
3
6
  import { mockUrlRequest } from '../../__tests__/xyz.util.js';
4
7
  import { filterLayers } from '../filter.js';
5
8
 
6
- o.spec('filterLayers', () => {
9
+ describe('filterLayers', () => {
7
10
  const sourceLayers: ConfigLayer[] = [
8
11
  {
9
12
  name: 'waikato-0_625m-snc12836-2004',
@@ -23,38 +26,38 @@ o.spec('filterLayers', () => {
23
26
  },
24
27
  ];
25
28
 
26
- o('should not filter with empty parameters', () => {
29
+ it('should not filter with empty parameters', () => {
27
30
  const layers = filterLayers(mockUrlRequest('/foo/bar,js'), sourceLayers);
28
- o(layers).deepEquals(sourceLayers);
31
+ assert.deepEqual(layers, sourceLayers);
29
32
  });
30
33
 
31
- o('should filter date[after]', () => {
34
+ it('should filter date[after]', () => {
32
35
  const dateAfter = '2003-12-31T23:59:59.999';
33
36
  const layers = filterLayers(mockUrlRequest('/foo/bar,js', `?date[after]=${dateAfter}`), sourceLayers);
34
- o(layers).deepEquals([sourceLayers[0]]);
37
+ assert.deepEqual(layers, [sourceLayers[0]]);
35
38
  });
36
39
 
37
- o('should filter date[before]', () => {
40
+ it('should filter date[before]', () => {
38
41
  const dateBefore = '2003-01-01T00:00:00.000Z';
39
42
  const layers = filterLayers(mockUrlRequest('/foo/bar,js', `?date[before]=${dateBefore}`), sourceLayers);
40
- o(layers).deepEquals(sourceLayers.slice(1));
43
+ assert.deepEqual(layers, sourceLayers.slice(1));
41
44
  });
42
45
 
43
- o('should filter date[before] in between years', () => {
46
+ it('should filter date[before] in between years', () => {
44
47
  const dateBefore = '2026-01-01T00:00:00.000Z';
45
48
  const layer = [{ name: '', title: 'Waikato 0.625m SNC12836 (2020-2028)' }];
46
49
  const layers = filterLayers(mockUrlRequest('/foo/bar,js', `?date[before]=${dateBefore}`), layer);
47
- o(layers).deepEquals(layer);
50
+ assert.deepEqual(layers, layer);
48
51
  });
49
52
 
50
- o('should filter date[after] in between years', () => {
53
+ it('should filter date[after] in between years', () => {
51
54
  const dateAfter = '2026-12-31T23:59:59.999Z';
52
55
  const layer = [{ name: '', title: 'Waikato 0.625m SNC12836 (2020-2028)' }];
53
56
  const layers = filterLayers(mockUrlRequest('/foo/bar,js', `?date[after]=${dateAfter}`), layer);
54
- o(layers).deepEquals(layer);
57
+ assert.deepEqual(layers, layer);
55
58
  });
56
59
 
57
- o('should filter date[after] and date[before] in between years', () => {
60
+ it('should filter date[after] and date[before] in between years', () => {
58
61
  const dateAfter = '2026-12-31T23:59:59.999Z';
59
62
  const dateBefore = '2028-01-01T00:00:00.000Z';
60
63
 
@@ -63,10 +66,10 @@ o.spec('filterLayers', () => {
63
66
  mockUrlRequest('/foo/bar,js', `?date[after]=${dateAfter}&date[before]=${dateBefore}`),
64
67
  layer,
65
68
  );
66
- o(layers).deepEquals(layer);
69
+ assert.deepEqual(layers, layer);
67
70
  });
68
71
 
69
- o('should filter date[after] and date[before] in between years with single year', () => {
72
+ it('should filter date[after] and date[before] in between years with single year', () => {
70
73
  const dateAfter = '2026-12-31T23:59:59.999Z';
71
74
  const dateBefore = '2028-01-01T00:00:00.000Z';
72
75
 
@@ -75,6 +78,6 @@ o.spec('filterLayers', () => {
75
78
  mockUrlRequest('/foo/bar,js', `?date[after]=${dateAfter}&date[before]=${dateBefore}`),
76
79
  layer,
77
80
  );
78
- o(layers).deepEquals(layer);
81
+ assert.deepEqual(layers, layer);
79
82
  });
80
83
  });
@@ -1,74 +1,59 @@
1
- import { GoogleTms, ImageFormat, Nztm2000QuadTms, Nztm2000Tms, VectorFormat } from '@basemaps/geo';
2
- import o from 'ospec';
1
+ import assert from 'node:assert';
2
+ import { describe, it } from 'node:test';
3
+
4
+ import { GoogleTms, Nztm2000QuadTms, Nztm2000Tms } from '@basemaps/geo';
5
+
3
6
  import { mockUrlRequest } from '../../__tests__/xyz.util.js';
4
7
  import { Validate } from '../validate.js';
5
8
 
6
- o.spec('GetImageFormats', () => {
7
- o('should parse all formats', () => {
9
+ describe('GetImageFormats', () => {
10
+ it('should parse all formats', () => {
8
11
  const req = mockUrlRequest('/v1/blank', 'format=png&format=jpeg');
9
12
  const formats = Validate.getRequestedFormats(req);
10
- o(formats).deepEquals([ImageFormat.Png, ImageFormat.Jpeg]);
13
+ assert.deepEqual(formats, ['png', 'jpeg']);
11
14
  });
12
15
 
13
- o('should ignore bad formats', () => {
16
+ it('should ignore bad formats', () => {
14
17
  const req = mockUrlRequest('/v1/blank', 'format=fake&format=mvt');
15
18
  const formats = Validate.getRequestedFormats(req);
16
- o(formats).equals(null);
19
+ assert.equal(formats, null);
17
20
  });
18
21
 
19
- o('should de-dupe formats', () => {
22
+ it('should de-dupe formats', () => {
20
23
  const req = mockUrlRequest('/v1/blank', 'format=png&format=jpeg&format=png&format=jpeg&format=png&format=jpeg');
21
24
  const formats = Validate.getRequestedFormats(req);
22
- o(formats).deepEquals([ImageFormat.Png, ImageFormat.Jpeg]);
25
+ assert.deepEqual(formats, ['png', 'jpeg']);
23
26
  });
24
27
 
25
- o('should support "tileFormat" Alias all formats', () => {
28
+ it('should support "tileFormat" Alias all formats', () => {
26
29
  const req = mockUrlRequest('/v1/blank', 'tileFormat=png&format=jpeg');
27
30
  const formats = Validate.getRequestedFormats(req);
28
- o(formats).deepEquals([ImageFormat.Jpeg, ImageFormat.Png]);
31
+ assert.deepEqual(formats, ['jpeg', 'png']);
29
32
  });
30
33
 
31
- o('should not duplicate "tileFormat" alias all formats', () => {
34
+ it('should not duplicate "tileFormat" alias all formats', () => {
32
35
  const req = mockUrlRequest('/v1/blank', 'tileFormat=jpeg&format=jpeg');
33
36
  const formats = Validate.getRequestedFormats(req);
34
- o(formats).deepEquals([ImageFormat.Jpeg]);
37
+ assert.deepEqual(formats, ['jpeg']);
35
38
  });
36
39
  });
37
40
 
38
- o.spec('getTileMatrixSet', () => {
39
- o('should lookup epsg codes', () => {
40
- o(Validate.getTileMatrixSet('EPSG:3857')?.identifier).equals(GoogleTms.identifier);
41
- o(Validate.getTileMatrixSet('EPSG:2193')?.identifier).equals(Nztm2000Tms.identifier);
41
+ describe('getTileMatrixSet', () => {
42
+ it('should lookup epsg codes', () => {
43
+ assert.equal(Validate.getTileMatrixSet('EPSG:3857')?.identifier, GoogleTms.identifier);
44
+ assert.equal(Validate.getTileMatrixSet('EPSG:2193')?.identifier, Nztm2000Tms.identifier);
42
45
 
43
- o(Validate.getTileMatrixSet('3857')?.identifier).equals(GoogleTms.identifier);
44
- o(Validate.getTileMatrixSet('2193')?.identifier).equals(Nztm2000Tms.identifier);
46
+ assert.equal(Validate.getTileMatrixSet('3857')?.identifier, GoogleTms.identifier);
47
+ assert.equal(Validate.getTileMatrixSet('2193')?.identifier, Nztm2000Tms.identifier);
45
48
  });
46
49
 
47
- o('should lookup by identifier', () => {
48
- o(Validate.getTileMatrixSet('WebMercatorQuad')?.identifier).equals(GoogleTms.identifier);
49
- o(Validate.getTileMatrixSet('NZTM2000Quad')?.identifier).equals(Nztm2000QuadTms.identifier);
50
- o(Validate.getTileMatrixSet('Nztm2000')?.identifier).equals(Nztm2000Tms.identifier);
50
+ it('should lookup by identifier', () => {
51
+ assert.equal(Validate.getTileMatrixSet('WebMercatorQuad')?.identifier, GoogleTms.identifier);
52
+ assert.equal(Validate.getTileMatrixSet('NZTM2000Quad')?.identifier, Nztm2000QuadTms.identifier);
53
+ assert.equal(Validate.getTileMatrixSet('Nztm2000')?.identifier, Nztm2000Tms.identifier);
51
54
  });
52
55
 
53
- o('should be case sensitive', () => {
54
- o(Validate.getTileMatrixSet('Nztm2000Quad')?.identifier).equals(undefined);
56
+ it('should be case sensitive', () => {
57
+ assert.equal(Validate.getTileMatrixSet('Nztm2000Quad')?.identifier, undefined);
55
58
  });
56
59
  });
57
-
58
- o.spec('getTileFormat', () => {
59
- for (const ext of Object.values(ImageFormat)) {
60
- o('should support image format:' + ext, () => {
61
- o(Validate.getTileFormat(ext)).equals(ext);
62
- });
63
- }
64
-
65
- o('should support vector format: mvt', () => {
66
- o(Validate.getTileFormat('pbf')).equals(VectorFormat.MapboxVectorTiles);
67
- });
68
-
69
- for (const fmt of ['FAKE', /* 'JPEG' // TODO should this be case sensitive ,*/ 'mvt', 'json']) {
70
- o('should not support format:' + fmt, () => {
71
- o(Validate.getTileFormat(fmt)).equals(null);
72
- });
73
- }
74
- });
@@ -1,5 +1,6 @@
1
- import { fsa } from '@chunkd/fs';
2
- import { LambdaHttpResponse, LambdaHttpRequest, HttpHeader } from '@linzjs/lambda';
1
+ import { fsa } from '@basemaps/shared';
2
+ import { HttpHeader, LambdaHttpRequest, LambdaHttpResponse } from '@linzjs/lambda';
3
+
3
4
  import { ConfigLoader } from './config.loader.js';
4
5
  import { isGzip } from './cotar.serve.js';
5
6
  import { Etag } from './etag.js';
@@ -16,21 +17,21 @@ export class AssetProvider {
16
17
  * s3://linz-basemaps/assets/assets-b4ff211a.tar.co # Remote Cotar
17
18
  */
18
19
 
19
- async get(path: string, fileName: string): Promise<Buffer | null> {
20
+ async get(url: URL, fileName: string): Promise<Buffer | null> {
20
21
  // get assets file from cotar
21
- if (path.endsWith('.tar.co')) return await this.getFromCotar(path, fileName);
22
+ if (url.pathname.endsWith('.tar.co')) return await this.getFromCotar(url, fileName);
22
23
 
23
24
  // get assets file for directory
24
25
  try {
25
- const filePath = fsa.join(path, fileName);
26
+ const filePath = new URL(fileName, url);
26
27
  return await fsa.read(filePath);
27
- } catch (e: any) {
28
- if (e.code === 404) return null;
28
+ } catch (e) {
29
+ if ((e as { code: number })?.code === 404) return null;
29
30
  throw e;
30
31
  }
31
32
  }
32
33
 
33
- async getFromCotar(path: string, fileName: string): Promise<Buffer | null> {
34
+ async getFromCotar(path: URL, fileName: string): Promise<Buffer | null> {
34
35
  const cotar = await CoSources.getCotar(path);
35
36
  const data = await cotar.get(fileName);
36
37
  return data ? Buffer.from(data) : data;
@@ -47,7 +48,7 @@ export class AssetProvider {
47
48
  const config = await ConfigLoader.load(req);
48
49
  if (config == null) return NotFound();
49
50
  if (config.assets == null) return NotFound();
50
- const buf = await assetProvider.get(config.assets, file);
51
+ const buf = await assetProvider.get(fsa.toUrl(config.assets), file);
51
52
  if (buf == null) return NotFound();
52
53
  const cacheKey = Etag.key(buf);
53
54
  if (Etag.isNotModified(req, cacheKey)) return NotModified();
@@ -1,5 +1,6 @@
1
1
  import { ConfigBundled, ConfigProviderMemory } from '@basemaps/config';
2
2
  import { fsa } from '@basemaps/shared';
3
+
3
4
  import { SwappingLru } from './swapping.lru.js';
4
5
 
5
6
  class LruConfig {
@@ -31,14 +32,14 @@ export class ConfigCache {
31
32
  this.cache = new SwappingLru<LruConfig>(maxSize);
32
33
  }
33
34
 
34
- get(location: string): Promise<ConfigProviderMemory | null> {
35
- const existing = this.cache.get(location)?.configProvider;
35
+ get(location: URL): Promise<ConfigProviderMemory | null> {
36
+ const existing = this.cache.get(location.href)?.configProvider;
36
37
  if (existing != null) return existing;
37
38
  const configJson = fsa.readJson<ConfigBundled>(location).catch(() => {
38
39
  return null;
39
40
  });
40
41
  const config = new LruConfig(configJson);
41
- this.cache.set(location, config);
42
+ this.cache.set(location.href, config);
42
43
  return config.configProvider;
43
44
  }
44
45
  }
@@ -1,11 +1,11 @@
1
1
  import { base58, BasemapsConfigProvider, isBase58 } from '@basemaps/config';
2
+ import { fsa, getDefaultConfig } from '@basemaps/shared';
2
3
  import { LambdaHttpResponse } from '@linzjs/lambda';
3
- import { parseUri } from '@chunkd/core';
4
4
  import { LambdaHttpRequest } from '@linzjs/lambda';
5
+
5
6
  import { CachedConfig } from './config.cache.js';
6
- import { getDefaultConfig } from '@basemaps/shared';
7
7
 
8
- // FIXME load this from process.env COG BUCKETS?
8
+ // TODO load this from process.env COG BUCKETS?
9
9
  const SafeBuckets = new Set([
10
10
  'linz-workflows-scratch',
11
11
  'linz-workflow-artifacts',
@@ -13,7 +13,8 @@ const SafeBuckets = new Set([
13
13
  'linz-basemaps-staging',
14
14
  'linz-basemaps-scratch',
15
15
  ]);
16
- const SafeProtocols = new Set(['s3', 'memory']);
16
+
17
+ const SafeProtocols = new Set([new URL('s3://foo').protocol, new URL('memory://foo.json').protocol]);
17
18
 
18
19
  export class ConfigLoader {
19
20
  /** Exposed for testing */
@@ -39,20 +40,19 @@ export class ConfigLoader {
39
40
  if (rawLocation == null) return this.getDefaultConfig();
40
41
 
41
42
  const configLocation = isBase58(rawLocation) ? Buffer.from(base58.decode(rawLocation)).toString() : rawLocation;
43
+ const configUrl = fsa.toUrl(configLocation);
42
44
 
43
- const r = parseUri(configLocation);
44
-
45
- if (r == null) throw new LambdaHttpResponse(400, 'Invalid config location');
46
- if (!SafeProtocols.has(r.protocol)) {
47
- throw new LambdaHttpResponse(400, `Invalid configuration location protocol:${r.protocol}`);
45
+ if (configUrl == null) throw new LambdaHttpResponse(400, 'Invalid config location');
46
+ if (!SafeProtocols.has(configUrl.protocol)) {
47
+ throw new LambdaHttpResponse(400, `Invalid configuration location protocol:${configUrl.protocol}`);
48
48
  }
49
- if (!SafeBuckets.has(r.bucket)) {
50
- throw new LambdaHttpResponse(400, `Bucket: "${r.bucket}" is not a allowed bucket location`);
49
+ if (!SafeBuckets.has(configUrl.hostname)) {
50
+ throw new LambdaHttpResponse(400, `Bucket: "${configUrl.hostname}" is not a allowed bucket location`);
51
51
  }
52
52
 
53
- req.set('config', configLocation);
53
+ req.set('config', configUrl.href);
54
54
  req.timer.start('config:load');
55
- return CachedConfig.get(configLocation).then((f) => {
55
+ return CachedConfig.get(configUrl).then((f) => {
56
56
  req.timer.end('config:load');
57
57
  if (f == null) throw new LambdaHttpResponse(400, `Invalid config location at ${configLocation}`);
58
58
  return f;
@@ -1,4 +1,5 @@
1
1
  import { HttpHeader, LambdaHttpRequest, LambdaHttpResponse } from '@linzjs/lambda';
2
+
2
3
  import { Etag } from './etag.js';
3
4
  import { NotFound, NotModified } from './response.js';
4
5
  import { CoSources } from './source.cache.js';
@@ -12,11 +13,11 @@ import { CoSources } from './source.cache.js';
12
13
  */
13
14
  export async function serveFromCotar(
14
15
  req: LambdaHttpRequest,
15
- cotarPath: string,
16
+ url: URL,
16
17
  assetPath: string,
17
18
  contentType: string,
18
19
  ): Promise<LambdaHttpResponse> {
19
- const cotar = await CoSources.getCotar(cotarPath);
20
+ const cotar = await CoSources.getCotar(url);
20
21
  if (cotar == null) return NotFound();
21
22
  const fileData = await cotar.get(assetPath);
22
23
  if (fileData == null) return NotFound();
@@ -1,8 +1,5 @@
1
- import { fsa } from '@basemaps/shared';
2
- import { ChunkSourceBase } from '@chunkd/core';
3
- import { CogTiff } from '@cogeotiff/core';
4
- import { Cotar } from '@cotar/core';
5
- import { St } from './source.tracer.js';
1
+ import { Cotar, fsa, Tiff } from '@basemaps/shared';
2
+
6
3
  import { SwappingLru } from './swapping.lru.js';
7
4
 
8
5
  export type LruStrut = LruStrutCotar | LruStrutCog;
@@ -15,8 +12,8 @@ export interface LruStrutCotar {
15
12
 
16
13
  export interface LruStrutCog {
17
14
  type: 'cog';
18
- value: Promise<CogTiff>;
19
- _value?: CogTiff;
15
+ value: Promise<Tiff>;
16
+ _value?: Tiff;
20
17
  }
21
18
 
22
19
  class LruStrutObj<T extends LruStrut> {
@@ -26,11 +23,7 @@ class LruStrutObj<T extends LruStrut> {
26
23
  if (this.ob._value == null) this.ob.value.then((c) => (this.ob._value = c));
27
24
  }
28
25
 
29
- get size(): number {
30
- const val = this.ob._value;
31
- if (val == null) return 0;
32
- return val.source.chunkSize * (val.source as ChunkSourceBase).chunks.size;
33
- }
26
+ size = 1;
34
27
  }
35
28
 
36
29
  export class SourceCache {
@@ -39,34 +32,30 @@ export class SourceCache {
39
32
  this.cache = new SwappingLru<LruStrutObj<LruStrut>>(maxSize);
40
33
  }
41
34
 
42
- getCog(location: string): Promise<CogTiff> {
43
- const existing = this.cache.get(location)?.ob;
35
+ getCog(location: URL): Promise<Tiff> {
36
+ const existing = this.cache.get(location.href)?.ob;
44
37
 
45
38
  if (existing != null) {
46
39
  if (existing.type === 'cog') return existing.value;
47
40
  throw new Error(`Existing object of type: ${existing.type} made for location: ${location}`);
48
41
  }
49
- const source = fsa.source(location);
50
- St.trace(source);
51
- const value = CogTiff.create(source);
52
- this.cache.set(location, new LruStrutObj({ type: 'cog', value }));
42
+ const value = Tiff.create(fsa.source(location));
43
+ this.cache.set(location.href, new LruStrutObj({ type: 'cog', value }));
53
44
  return value;
54
45
  }
55
46
 
56
- getCotar(location: string): Promise<Cotar> {
57
- const existing = this.cache.get(location)?.ob;
47
+ getCotar(location: URL): Promise<Cotar> {
48
+ const existing = this.cache.get(location.href)?.ob;
58
49
 
59
50
  if (existing != null) {
60
51
  if (existing.type === 'cotar') return existing.value as Promise<Cotar>;
61
52
  throw new Error(`Existing object of type: ${existing.type} made for location: ${location}`);
62
53
  }
63
- const source = fsa.source(location);
64
- St.trace(source);
65
- const value = Cotar.fromTar(source);
66
- this.cache.set(location, new LruStrutObj({ type: 'cotar', value }));
54
+ const value = Cotar.fromTar(fsa.source(location));
55
+ this.cache.set(location.href, new LruStrutObj({ type: 'cotar', value }));
67
56
  return value;
68
57
  }
69
58
  }
70
59
 
71
- /** Approx ~1.4GB 2x~700MB caches */
72
- export const CoSources = new SourceCache(700 * 1000 * 1000);
60
+ /** Cache the last 5,000 tiff/tar files accessed, generally it is only <100KB of memory used per tiff file so approx 50MB of cache */
61
+ export const CoSources = new SourceCache(5000);