From f49b9abb814ccc733eae6946c3d068c01556ff41 Mon Sep 17 00:00:00 2001 From: Jake Turner Date: Fri, 23 Jan 2026 22:13:03 +0000 Subject: [PATCH] fix(Maps): static path resolution --- admin/app/services/map_service.ts | 37 +++++++++++++++++++------- admin/providers/map_static_provider.ts | 2 +- admin/start/routes.ts | 3 +-- 3 files changed, 30 insertions(+), 12 deletions(-) diff --git a/admin/app/services/map_service.ts b/admin/app/services/map_service.ts index 1799417..1e0a8e6 100644 --- a/admin/app/services/map_service.ts +++ b/admin/app/services/map_service.ts @@ -238,10 +238,7 @@ export class MapService implements IMapService { const regions = (await this.listRegions()).files const sources = this.generateSourcesArray(regions) - const localUrl = env.get('URL') - const withProtocol = localUrl.startsWith('http') ? localUrl : `http://${localUrl}` - const baseUrlPath = urlJoin(this.mapStoragePath, this.basemapsAssetsDir) - const baseUrl = new URL(baseUrlPath, withProtocol).toString() + const baseUrl = this.getPublicFileBaseUrl(this.basemapsAssetsDir) const styles = await this.generateStylesFile( rawStyles, @@ -317,17 +314,14 @@ export class MapService implements IMapService { } private generateSourcesArray(regions: FileEntry[]): BaseStylesFile['sources'][] { - const localUrl = env.get('URL') const sources: BaseStylesFile['sources'][] = [] + const baseUrl = this.getPublicFileBaseUrl('pmtiles') for (const region of regions) { if (region.type === 'file' && region.name.endsWith('.pmtiles')) { const regionName = region.name.replace('.pmtiles', '') const source: BaseStylesFile['sources'] = {} - const sourceUrl = new URL( - urlJoin(this.mapStoragePath, 'pmtiles', region.name), - localUrl.startsWith('http') ? localUrl : `http://${localUrl}` - ).toString() + const sourceUrl = urlJoin(baseUrl, region.name) source[regionName] = { type: 'vector', @@ -388,4 +382,29 @@ export class MapService implements IMapService { await deleteFileIfExists(fullPath) } + + /* + * Gets the appropriate public URL for a map asset depending on environment + */ + private getPublicFileBaseUrl(childPath: string): string { + function getHost() { + try { + const localUrlRaw = env.get('URL') + if (!localUrlRaw) return 'localhost' + + const localUrl = new URL(localUrlRaw) + return localUrl.host + } catch (error) { + return 'localhost' + } + } + + const host = getHost() + const withProtocol = host.startsWith('http') ? host : `http://${host}` + const baseUrlPath = + process.env.NODE_ENV === 'production' ? childPath : urlJoin(this.mapStoragePath, childPath) + + const baseUrl = new URL(baseUrlPath, withProtocol).toString() + return baseUrl + } } diff --git a/admin/providers/map_static_provider.ts b/admin/providers/map_static_provider.ts index 07a0e2c..4878de2 100644 --- a/admin/providers/map_static_provider.ts +++ b/admin/providers/map_static_provider.ts @@ -18,7 +18,7 @@ export default class MapStaticProvider { register() { this.app.container.singleton(MapsStaticMiddleware, () => { const path = join(process.cwd(), '/storage/maps') - logger.debug(`Maps static files will be served from ${path}`) + logger.info(`Maps static files will be served from ${path}`) const config = this.app.config.get('static', defineConfig({})) return new MapsStaticMiddleware(path, config) }) diff --git a/admin/start/routes.ts b/admin/start/routes.ts index ac16800..1bb0d91 100644 --- a/admin/start/routes.ts +++ b/admin/start/routes.ts @@ -24,6 +24,7 @@ transmit.registerRoutes() router.get('/', [HomeController, 'index']) router.get('/home', [HomeController, 'home']) router.on('/about').renderInertia('about') +router.get('/maps', [MapsController, 'index']) router.get('/easy-setup', [EasySetupController, 'index']) router.get('/easy-setup/complete', [EasySetupController, 'complete']) @@ -55,8 +56,6 @@ router }) .prefix('/docs') -router.get('/maps', [MapsController, 'index']) - router .group(() => { router.get('/regions', [MapsController, 'listRegions'])