diff --git a/lib/server.js b/lib/server.js index 877d4d2..cf6adbc 100644 --- a/lib/server.js +++ b/lib/server.js @@ -75,13 +75,12 @@ export function createServer({ base = '/' } = {}) { base, }) .get('/style.json', async (request, reader) => { - const baseUrl = new URL(base, request.url) + const baseUrl = new URL('.', request.url) const style = await reader.getStyle(baseUrl.href) return json(style) }) - .get('*', async (request, reader) => { - const url = new URL(request.url) - const path = decodeURIComponent(url.pathname.slice(base.length - 1)) + .get(':path+', async (request, reader) => { + const path = decodeURIComponent(request.params.path) const resource = await reader.getResource(path) return resourceResponse(resource) }) diff --git a/test/server.js b/test/server.js index a949b14..fb9bd94 100644 --- a/test/server.js +++ b/test/server.js @@ -115,3 +115,65 @@ test('server with base path', async () => { const style = await response.json() assert(validateStyle(style), 'style is valid') }) + +test('server with parameter in base path', async () => { + const filepath = fileURLToPath( + new URL('./fixtures/demotiles-z2.smp', import.meta.url), + ) + const reader = new Reader(filepath) + const server = createServer({ base: '/maps/:mapId/' }) + const response = await server.fetch( + new Request('http://example.com/maps/45b4fcabc49c/style.json'), + reader, + ) + assert.equal(response.status, 200) + const style = await response.json() + assert(validateStyle(style), 'style is valid') + + { + assert(typeof style.glyphs === 'string') + const glyphUrl = replaceVariables(style.glyphs, { + fontstack: 'Open Sans Semibold', + range: '0-255', + }) + assert(glyphUrl.startsWith('http://example.com/maps/45b4fcabc49c/')) + const response = await server.fetch(new Request(glyphUrl), reader) + assert.equal(response.status, 200) + assert.equal(response.headers.get('content-type'), 'application/x-protobuf') + assert.equal(response.headers.get('content-encoding'), 'gzip') + assert(response.headers.get('content-length')) + + assert.equal( + (await response.arrayBuffer()).byteLength, + Number(response.headers.get('content-length')), + 'Content-Length header is correct', + ) + } + + { + const tileSource = Object.values(style.sources).find( + (source) => source.type === 'vector', + ) + assert(tileSource?.tiles) + const tileUrl = replaceVariables(tileSource.tiles[0], { + z: 0, + x: 0, + y: 0, + }) + assert(tileUrl.startsWith('http://example.com/maps/45b4fcabc49c/')) + const response = await server.fetch(new Request(tileUrl), reader) + assert.equal(response.status, 200) + assert.equal( + response.headers.get('content-type'), + 'application/vnd.mapbox-vector-tile', + ) + assert.equal(response.headers.get('content-encoding'), 'gzip') + assert(response.headers.get('content-length')) + + assert.equal( + (await response.arrayBuffer()).byteLength, + Number(response.headers.get('content-length')), + 'Content-Length header is correct', + ) + } +})