mission-control/lib/config/sites.ts

99 lines
3.2 KiB
TypeScript

type SiteUrlKey =
| "missionControl"
| "ganttBoard"
| "blogBackup"
| "gitea"
| "github"
| "vercel"
| "supabase"
| "google"
| "googleCalendar"
| "googleCalendarSettings";
const DEFAULT_SITE_URLS: Record<SiteUrlKey, string> = {
missionControl: "https://mission-control-rho-pink.vercel.app",
ganttBoard: "https://gantt-board.vercel.app",
blogBackup: "https://blog-backup-two.vercel.app",
gitea: "http://192.168.1.128:3000",
github: "https://github.com",
vercel: "https://vercel.com",
supabase: "https://supabase.com",
google: "https://google.com",
googleCalendar: "https://calendar.google.com",
googleCalendarSettings: "https://calendar.google.com/calendar/u/0/r/settings",
};
const ENV_SITE_URLS: Partial<Record<SiteUrlKey, string | undefined>> = {
missionControl: process.env.NEXT_PUBLIC_MISSION_CONTROL_URL,
ganttBoard: process.env.NEXT_PUBLIC_GANTT_BOARD_URL,
blogBackup: process.env.NEXT_PUBLIC_BLOG_BACKUP_URL,
gitea: process.env.NEXT_PUBLIC_GITEA_URL,
github: process.env.NEXT_PUBLIC_GITHUB_URL,
vercel: process.env.NEXT_PUBLIC_VERCEL_URL,
supabase: process.env.NEXT_PUBLIC_SUPABASE_SITE_URL,
google: process.env.NEXT_PUBLIC_GOOGLE_URL,
googleCalendar: process.env.NEXT_PUBLIC_GOOGLE_CALENDAR_URL,
googleCalendarSettings: process.env.NEXT_PUBLIC_GOOGLE_CALENDAR_SETTINGS_URL,
};
function normalizeBaseUrl(value: string, fallback: string): string {
try {
const normalized = new URL(value.trim()).toString();
return normalized.endsWith("/") ? normalized.slice(0, -1) : normalized;
} catch {
return fallback;
}
}
const configuredSiteUrls = Object.entries(DEFAULT_SITE_URLS).reduce(
(acc, [key, fallback]) => {
const envValue = ENV_SITE_URLS[key as SiteUrlKey];
acc[key as SiteUrlKey] = normalizeBaseUrl(envValue || fallback, fallback);
return acc;
},
{} as Record<SiteUrlKey, string>,
);
export const siteUrls = Object.freeze(configuredSiteUrls);
function toUrl(base: string, path = ""): string {
if (!path) return base;
const normalizedPath = path.startsWith("/") ? path : `/${path}`;
return `${base}${normalizedPath}`;
}
function toUrlWithQuery(
base: string,
path: string,
params: Record<string, string | undefined>,
): string {
const query = new URLSearchParams();
for (const [key, value] of Object.entries(params)) {
if (value) query.set(key, value);
}
const queryString = query.toString();
return queryString ? `${toUrl(base, path)}?${queryString}` : toUrl(base, path);
}
export function getGanttTaskUrl(taskId: string): string {
return toUrl(siteUrls.ganttBoard, `/tasks/${encodeURIComponent(taskId)}`);
}
export function getGanttProjectUrl(projectId: string): string {
return toUrl(siteUrls.ganttBoard, `/projects/${encodeURIComponent(projectId)}`);
}
export function getGanttSprintUrl(sprintId: string): string {
return toUrl(siteUrls.ganttBoard, `/sprints/${encodeURIComponent(sprintId)}`);
}
export function getGanttTasksUrl(params?: Record<string, string | undefined>): string {
return params
? toUrlWithQuery(siteUrls.ganttBoard, "/tasks", params)
: toUrl(siteUrls.ganttBoard, "/tasks");
}
export function getMissionControlDocumentsUrl(): string {
return toUrl(siteUrls.missionControl, "/documents");
}