skillhub/web/base-path-config.ts
philsun 34f244e7a4 feat(web): support configurable base-path deployment
Signed-off-by: philsun <xinyi.sun@daocloud.io>
2026-08-05 12:50:26 +08:00

46 lines
1.4 KiB
TypeScript

const BASE_PATH_PATTERN = /^\/[A-Za-z0-9._~/-]+\/$/
// First path segments reserved by the SkillHub server's own Nginx locations
// (see web/nginx.conf.template). A base path starting with any of these would
// generate a `location ^~ /<seg>/` that shadows the server route and break the
// app. Kept in sync with the runtime, release-config, and Helm checks.
const RESERVED_FIRST_SEGMENTS = new Set([
'api',
'oauth2',
'login',
'assets',
'registry',
'nginx-health',
'.well-known',
'runtime-config.js',
])
/**
* Validates the Vite base path before it is embedded into generated asset URLs.
* Only same-origin, normalized URL paths are allowed.
*/
export function validateBasePath(value: string): string {
if (value === '/') {
return value
}
const segments = value.split('/').filter(Boolean)
const hasDotSegment = segments.some((segment) => segment === '.' || segment === '..')
if (
!BASE_PATH_PATTERN.test(value)
|| value.includes('//')
|| hasDotSegment
) {
throw new Error(
`VITE_BASE_PATH must be '/' or a normalized root-relative path ending with '/': ${value}`,
)
}
if (RESERVED_FIRST_SEGMENTS.has(segments[0])) {
throw new Error(
`VITE_BASE_PATH must not start with a segment reserved by the SkillHub server (${segments[0]}); it would shadow the server's own Nginx location: ${value}`,
)
}
return value
}