Co-authored-by: Jason Woltje <jason@diversecanvas.com> Co-committed-by: Jason Woltje <jason@diversecanvas.com>
121 lines
4.0 KiB
TypeScript
121 lines
4.0 KiB
TypeScript
/**
|
|
* Centralized API Configuration
|
|
*
|
|
* This module provides a single source of truth for all API endpoints and URLs.
|
|
* All components should import from here instead of reading environment variables directly.
|
|
*
|
|
* Runtime config injection:
|
|
* - In production containers, NEXT_PUBLIC_* vars are baked at build time and cannot
|
|
* be overridden via Docker env vars. The root layout injects runtime values into
|
|
* `window.__MOSAIC_ENV__` via a synchronous <script>, which this module reads first.
|
|
*
|
|
* Environment Variables:
|
|
* - NEXT_PUBLIC_API_URL: The main API server URL (default: http://localhost:3001)
|
|
* - NEXT_PUBLIC_ORCHESTRATOR_URL: The orchestrator service URL (default: same as API URL)
|
|
* - NEXT_PUBLIC_AUTH_MODE: Auth mode for web app (`real` or `mock`)
|
|
* - If unset: development defaults to `mock`, production defaults to `real`
|
|
*/
|
|
|
|
/**
|
|
* Read an env variable, preferring runtime-injected values on the client.
|
|
*
|
|
* Execution order guarantees this works:
|
|
* 1. Root layout emits `<script>window.__MOSAIC_ENV__={…}</script>` synchronously.
|
|
* 2. Next.js hydrates, loading client modules that call this helper.
|
|
*/
|
|
function getEnv(name: string): string | undefined {
|
|
if (typeof window !== "undefined") {
|
|
const w = window as Window & { __MOSAIC_ENV__?: Record<string, string> };
|
|
if (w.__MOSAIC_ENV__?.[name]) {
|
|
return w.__MOSAIC_ENV__[name];
|
|
}
|
|
}
|
|
// Server-side or build-time fallback
|
|
return process.env[name];
|
|
}
|
|
|
|
/**
|
|
* Default API server URL for local development
|
|
*/
|
|
const DEFAULT_API_URL = "http://localhost:3001";
|
|
const DEFAULT_AUTH_MODE = process.env.NODE_ENV === "development" ? "mock" : "real";
|
|
|
|
const VALID_AUTH_MODES = ["real", "mock"] as const;
|
|
|
|
export type AuthMode = (typeof VALID_AUTH_MODES)[number];
|
|
|
|
/**
|
|
* Main API server URL
|
|
* Used for authentication, tasks, events, knowledge, and all core API calls
|
|
*/
|
|
export const API_BASE_URL = getEnv("NEXT_PUBLIC_API_URL") ?? DEFAULT_API_URL;
|
|
|
|
function resolveAuthMode(): AuthMode {
|
|
const rawMode = (getEnv("NEXT_PUBLIC_AUTH_MODE") ?? DEFAULT_AUTH_MODE).toLowerCase();
|
|
|
|
if (!VALID_AUTH_MODES.includes(rawMode as AuthMode)) {
|
|
throw new Error(
|
|
`Invalid NEXT_PUBLIC_AUTH_MODE "${rawMode}". Expected one of: ${VALID_AUTH_MODES.join(", ")}.`
|
|
);
|
|
}
|
|
|
|
if (rawMode === "mock" && process.env.NODE_ENV !== "development") {
|
|
throw new Error("NEXT_PUBLIC_AUTH_MODE=mock is only allowed when NODE_ENV=development.");
|
|
}
|
|
|
|
return rawMode as AuthMode;
|
|
}
|
|
|
|
/**
|
|
* Authentication mode for frontend runtime.
|
|
* - real: uses normal BetterAuth/Backend session flow
|
|
* - mock: local-only seeded mock user for FE development
|
|
*/
|
|
export const AUTH_MODE: AuthMode = resolveAuthMode();
|
|
|
|
/**
|
|
* Whether local mock auth mode is enabled.
|
|
*/
|
|
export const IS_MOCK_AUTH_MODE = AUTH_MODE === "mock";
|
|
|
|
/**
|
|
* Orchestrator service URL
|
|
* Used for agent management, task progress, and orchestration features
|
|
* Falls back to main API URL if not specified (they may run on the same server)
|
|
*/
|
|
export const ORCHESTRATOR_URL = getEnv("NEXT_PUBLIC_ORCHESTRATOR_URL") ?? API_BASE_URL;
|
|
|
|
/**
|
|
* Build a full API endpoint URL
|
|
* @param endpoint - The API endpoint path (should start with /)
|
|
* @returns The full URL for the endpoint
|
|
*/
|
|
export function buildApiUrl(endpoint: string): string {
|
|
return `${API_BASE_URL}${endpoint}`;
|
|
}
|
|
|
|
/**
|
|
* Build a full orchestrator endpoint URL
|
|
* @param endpoint - The orchestrator endpoint path (should start with /)
|
|
* @returns The full URL for the endpoint
|
|
*/
|
|
export function buildOrchestratorUrl(endpoint: string): string {
|
|
return `${ORCHESTRATOR_URL}${endpoint}`;
|
|
}
|
|
|
|
/**
|
|
* Configuration object for convenient access to all URLs
|
|
*/
|
|
export const apiConfig = {
|
|
/** Main API base URL */
|
|
baseUrl: API_BASE_URL,
|
|
/** Orchestrator service URL */
|
|
orchestratorUrl: ORCHESTRATOR_URL,
|
|
/** Authentication mode (`real` or `mock`) */
|
|
authMode: AUTH_MODE,
|
|
/** Build full API URL for an endpoint */
|
|
buildUrl: buildApiUrl,
|
|
/** Build full orchestrator URL for an endpoint */
|
|
buildOrchestratorUrl,
|
|
} as const;
|