export const BACKEND_API_BASE_URLS = { production: "https://jr-shikoku-backend-api-v1.haruk.in", experimental: "https://jr-shikoku-backend-api-v1-beta.haruk.in", } as const; export const JR_DATA_SYSTEM_ENVS = { production_release: { label: "本番 / リリース", caption: "一般公開向け運用", baseUrl: "https://shikoku-railinfo.haruk.in", track: "production", uiVariant: "release", backendApiBaseUrl: BACKEND_API_BASE_URLS.production, }, production_beta: { label: "本番 / ベータ", caption: "UI検証向け運用", baseUrl: "https://nightly.shikoku-railinfo.haruk.in", track: "production", uiVariant: "beta", backendApiBaseUrl: BACKEND_API_BASE_URLS.production, }, experimental: { label: "実験 / 実験場", caption: "毎日リセットされる実験環境", baseUrl: "https://experimental.shikoku-railinfo.haruk.in", track: "experimental", uiVariant: "release", backendApiBaseUrl: BACKEND_API_BASE_URLS.experimental, }, } as const; export type JrDataSystemEnvironmentKey = keyof typeof JR_DATA_SYSTEM_ENVS; export const DEFAULT_JR_DATA_SYSTEM_ENV: JrDataSystemEnvironmentKey = "production_release"; export type JrDataSystemTrack = "production" | "experimental"; export type JrDataSystemUiVariant = "release" | "beta"; export const JR_DATA_SYSTEM_ENV_OPTIONS = ( Object.entries(JR_DATA_SYSTEM_ENVS) as [ JrDataSystemEnvironmentKey, (typeof JR_DATA_SYSTEM_ENVS)[JrDataSystemEnvironmentKey], ][] ).map(([key, value]) => ({ key, ...value, })); export const normalizeJrDataSystemEnvironment = ( value: unknown, ): JrDataSystemEnvironmentKey => { // Backward compatibility for legacy keys. if (value === "production") return "production_release"; if (value === "chatgpt" || value === "claude") return "production_beta"; if (typeof value === "string" && value in JR_DATA_SYSTEM_ENVS) { return value as JrDataSystemEnvironmentKey; } return DEFAULT_JR_DATA_SYSTEM_ENV; }; export const resolveJrDataSystemEnvironment = ( track: JrDataSystemTrack, uiVariant: JrDataSystemUiVariant, ): JrDataSystemEnvironmentKey => { if (track === "experimental") { return "experimental"; } return uiVariant === "beta" ? "production_beta" : "production_release"; }; export const getJrDataSystemTrack = ( environment: unknown, ): JrDataSystemTrack => { const envKey = normalizeJrDataSystemEnvironment(environment); return JR_DATA_SYSTEM_ENVS[envKey].track; }; export const getJrDataSystemUiVariant = ( environment: unknown, ): JrDataSystemUiVariant => { const envKey = normalizeJrDataSystemEnvironment(environment); return JR_DATA_SYSTEM_ENVS[envKey].uiVariant; }; export const getBackendApiBaseUrl = (environment: unknown): string => { const envKey = normalizeJrDataSystemEnvironment(environment); return JR_DATA_SYSTEM_ENVS[envKey].backendApiBaseUrl; }; export const rewriteBackendApiUrl = (url: string, environment: unknown): string => { if (typeof url !== "string" || url.length === 0) return url; const target = getBackendApiBaseUrl(environment); for (const base of Object.values(BACKEND_API_BASE_URLS)) { if (url.startsWith(base)) { return url.replace(base, target); } } return url; }; export const rewriteJrDataSystemUrl = ( uri: string, environment: unknown, ): string => { if (typeof uri !== "string" || uri.length === 0) { return uri; } const envKey = normalizeJrDataSystemEnvironment(environment); const targetBaseUrl = JR_DATA_SYSTEM_ENVS[envKey].baseUrl; const knownBaseUrls = [ "https://jr-shikoku-data-system.pages.dev", JR_DATA_SYSTEM_ENVS.production_release.baseUrl, JR_DATA_SYSTEM_ENVS.production_beta.baseUrl, JR_DATA_SYSTEM_ENVS.experimental.baseUrl, ]; for (const baseUrl of knownBaseUrls) { if (uri.startsWith(baseUrl)) { return uri.replace(baseUrl, targetBaseUrl); } } return uri; };