diff --git a/src/bootstrap.ts b/src/bootstrap.ts index 7513077..5bedd6b 100644 --- a/src/bootstrap.ts +++ b/src/bootstrap.ts @@ -1,4 +1,4 @@ -import { getClientMode, installSecureFetch, secureUrl } from './secure-assets'; +import { configFileUrl, getClientMode, installSecureFetch } from './secure-assets'; installSecureFetch(); @@ -16,13 +16,43 @@ const setBootDebug = (message: string) => setBootDebug('boot: secure fetch installed'); +const deployBaseUrl = (): string => +{ + try + { + const loaderBase = (window as any).__nitroLoaderBase; + if(typeof loaderBase === 'string' && loaderBase.length) return new URL('..', loaderBase).toString(); + } + catch {} + + try + { + const moduleUrl = (import.meta as any).url; + if(typeof moduleUrl === 'string' && moduleUrl.length) return new URL('..', new URL('.', moduleUrl)).toString(); + } + catch {} + + try + { + const base = (import.meta as any).env?.BASE_URL; + if(typeof base === 'string' && base.length) + { + const trimmed = base.replace(/^\/+/, '').replace(/\/+$/, ''); + return trimmed ? `${ window.location.origin }/${ trimmed }/` : `${ window.location.origin }/`; + } + } + catch {} + + return `${ window.location.origin }/`; +}; + const loadClientMode = async () => { try { if((window as any).__nitroClientMode) return; - const url = new URL('configuration/client-mode.json', `${ window.location.origin }/`); + const url = new URL('configuration/client-mode.json', deployBaseUrl()); url.searchParams.set('v', Date.now().toString(36)); const response = await fetch(url.toString()); @@ -42,21 +72,13 @@ await loadClientMode(); const search = new URLSearchParams(window.location.search); const clientMode = getClientMode(); -const cacheBustUrl = (path: string): string => -{ - const url = new URL(path.replace(/^\/+/, ''), `${ window.location.origin }/`); - - url.searchParams.set('v', Date.now().toString(36)); - - return url.toString(); -}; (window as any).NitroSecureApiUrl = clientMode.apiBaseUrl || window.location.origin; (window as any).NitroClientMode = clientMode; (window as any).NitroConfig = { 'config.urls': [ - clientMode.secureAssetsEnabled ? secureUrl('config', 'renderer-config.json', true) : cacheBustUrl('configuration/renderer-config.json'), - clientMode.secureAssetsEnabled ? secureUrl('config', 'ui-config.json', true) : cacheBustUrl('configuration/ui-config.json') + configFileUrl('renderer-config.json', true), + configFileUrl('ui-config.json', true) ], 'sso.ticket': search.get('sso') || null, 'forward.type': search.get('room') ? 2 : -1, diff --git a/src/secure-assets.ts b/src/secure-assets.ts index 5cdfdc3..990f2f2 100644 --- a/src/secure-assets.ts +++ b/src/secure-assets.ts @@ -19,6 +19,36 @@ const CLIENT_MODE_DEFAULTS: NitroClientMode = { secureApiEnabled: true }; +const getDeployBaseUrl = (): string => +{ + try + { + const loaderBase = (window as any).__nitroLoaderBase; + if(typeof loaderBase === 'string' && loaderBase.length) return new URL('..', loaderBase).toString(); + } + catch {} + + try + { + const moduleUrl = (import.meta as any).url; + if(typeof moduleUrl === 'string' && moduleUrl.length) return new URL('..', new URL('.', moduleUrl)).toString(); + } + catch {} + + try + { + const base = (import.meta as any).env?.BASE_URL; + if(typeof base === 'string' && base.length) + { + const trimmed = base.replace(/^\/+/, '').replace(/\/+$/, ''); + return trimmed ? `${ window.location.origin }/${ trimmed }/` : `${ window.location.origin }/`; + } + } + catch {} + + return `${ window.location.origin }/`; +}; + const isDebugEnabled = (): boolean => { try @@ -204,7 +234,7 @@ const getPlainAssetBase = (kind: 'config' | 'gamedata'): string => if(typeof configured === 'string' && configured.length) return configured.endsWith('/') ? configured : `${ configured }/`; - if(kind === 'config') return `${ window.location.origin }/configuration/`; + if(kind === 'config') return new URL('configuration/', getDeployBaseUrl()).toString(); return `${ window.location.origin }/nitro/gamedata/`; }; @@ -226,7 +256,7 @@ export const secureUrl = (kind: 'config' | 'gamedata', file: string, cacheBust = { if(!getClientMode().secureAssetsEnabled) { - const plainUrl = new URL(file.replace(/^\/+/, ''), `${ window.location.origin }/`); + const plainUrl = new URL(file.replace(/^\/+/, ''), getPlainAssetBase(kind)); if(cacheBust) plainUrl.searchParams.set('v', Date.now().toString(36)); @@ -243,7 +273,7 @@ export const configFileUrl = (file: string, cacheBust = false): string => { if(getClientMode().secureAssetsEnabled) return secureUrl('config', file, cacheBust); - const plainUrl = new URL(`configuration/${ file.replace(/^\/+/, '') }`, `${ window.location.origin }/`); + const plainUrl = new URL(file.replace(/^\/+/, ''), getPlainAssetBase('config')); if(cacheBust) plainUrl.searchParams.set('v', Date.now().toString(36));