154 lines
5.2 KiB
TypeScript
154 lines
5.2 KiB
TypeScript
/**
|
|
* Shared utilities for the Settings page.
|
|
* Centralises constants, URL helpers, normalisation functions and validation
|
|
* helpers that are consumed by +page.svelte and EnvironmentsTab.svelte.
|
|
*/
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Constants
|
|
// ---------------------------------------------------------------------------
|
|
|
|
export const SETTINGS_TABS = [
|
|
"environments",
|
|
"connections",
|
|
"logging",
|
|
"git",
|
|
"llm",
|
|
"migration",
|
|
"storage",
|
|
"features",
|
|
"reports",
|
|
"automation",
|
|
"languages",
|
|
"system",
|
|
] as const;
|
|
|
|
export type SettingsTab = typeof SETTINGS_TABS[number];
|
|
|
|
interface LlmPrompts {
|
|
documentation_prompt: string;
|
|
git_commit_prompt: string;
|
|
}
|
|
|
|
interface LlmProviderBindings {
|
|
documentation: string;
|
|
git_commit: string;
|
|
}
|
|
|
|
interface LlmSettings {
|
|
prompts?: Partial<LlmPrompts>;
|
|
provider_bindings?: Partial<LlmProviderBindings>;
|
|
[key: string]: unknown;
|
|
}
|
|
|
|
export const DEFAULT_LLM_PROMPTS: LlmPrompts = {
|
|
documentation_prompt:
|
|
'Generate professional documentation for the following dataset and its columns.\nDataset: {dataset_name}\nColumns: {columns_json}\n\nProvide the documentation in JSON format:\n{\n \"dataset_description\": \"General description of the dataset\",\n \"column_descriptions\": [\n {\n \"name\": \"column_name\",\n \"description\": \"Generated description\"\n }\n ]\n}',
|
|
git_commit_prompt:
|
|
'Generate a concise and professional git commit message based on the following diff and recent history.\nUse Conventional Commits format (e.g., feat: ..., fix: ..., docs: ...).\n\nRecent History:\n{history}\n\nDiff:\n{diff}\n\nCommit Message:',
|
|
};
|
|
|
|
export const DEFAULT_LLM_PROVIDER_BINDINGS: LlmProviderBindings = {
|
|
documentation: "",
|
|
git_commit: "",
|
|
};
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// URL tab helpers
|
|
// ---------------------------------------------------------------------------
|
|
|
|
/**
|
|
* Read the current settings tab from the URL hash fragment.
|
|
* Falls back to "environments" when the hash is missing or invalid.
|
|
*/
|
|
export function readTabFromUrl(): string {
|
|
const hash = typeof window !== "undefined" ? window.location.hash : "";
|
|
const tab = hash.replace(/^#\/?settings\//, "") || "";
|
|
return normalizeTab(tab) || "environments";
|
|
}
|
|
|
|
/**
|
|
* Write the active settings tab to the URL hash fragment so it survives
|
|
* browser refreshes and can be linked to directly.
|
|
*/
|
|
export function writeTabToUrl(tab: string): void {
|
|
if (typeof window === "undefined") return;
|
|
const normalized = normalizeTab(tab);
|
|
if (normalized) {
|
|
window.location.hash = `/settings/${normalized}`;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Normalise an arbitrary tab identifier to a valid tab key, or return null
|
|
* when the identifier does not match any known tab.
|
|
*/
|
|
export function normalizeTab(tab: string): string | null {
|
|
if (!tab || typeof tab !== "string") return null;
|
|
const candidate = tab.trim().toLowerCase();
|
|
return SETTINGS_TABS.includes(candidate as SettingsTab) ? candidate : null;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// LLM helpers
|
|
// ---------------------------------------------------------------------------
|
|
|
|
/**
|
|
* Merge incoming LLM settings with the default prompts and bindings so that
|
|
* individual fields are never accidentally set to `undefined`.
|
|
*/
|
|
export function normalizeLlmSettings(llm: LlmSettings | null | undefined): LlmSettings {
|
|
if (!llm || typeof llm !== "object") {
|
|
return {
|
|
prompts: { ...DEFAULT_LLM_PROMPTS },
|
|
provider_bindings: { ...DEFAULT_LLM_PROVIDER_BINDINGS },
|
|
};
|
|
}
|
|
return {
|
|
...llm,
|
|
prompts: { ...DEFAULT_LLM_PROMPTS, ...llm.prompts },
|
|
provider_bindings: {
|
|
...DEFAULT_LLM_PROVIDER_BINDINGS,
|
|
...llm.provider_bindings,
|
|
},
|
|
};
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Environment helpers
|
|
// ---------------------------------------------------------------------------
|
|
|
|
/**
|
|
* Strip trailing slashes and the `/api/v1` suffix from a Superset base URL,
|
|
* auto-prepend https:// if no scheme is present,
|
|
* returning a clean base URL suitable for constructing dashboard links.
|
|
*/
|
|
export function normalizeSupersetBaseUrl(rawUrl: string): string | null {
|
|
let baseUrl = String(rawUrl || "").trim().replace(/\/+$/, "");
|
|
if (!baseUrl) return null;
|
|
if (baseUrl.endsWith("/api/v1")) {
|
|
baseUrl = baseUrl.slice(0, -"/api/v1".length);
|
|
}
|
|
// Auto-prepend https:// if no scheme is present
|
|
if (baseUrl && !/^https?:\/\//i.test(baseUrl)) {
|
|
baseUrl = `https://${baseUrl}`;
|
|
}
|
|
return baseUrl;
|
|
}
|
|
|
|
/**
|
|
* Classify an environment's deployment stage from its `name` or `url`.
|
|
* Returns one of: `"PROD"`, `"PREPROD"`, or `"DEV"`.
|
|
*/
|
|
export function resolveEnvStage(env: { name?: string; url?: string } | null | undefined): string {
|
|
if (!env) return "DEV";
|
|
const needle = ((env.name || "") + " " + (env.url || "")).toLowerCase();
|
|
if (/prod(uction)?/.test(needle) && !/preprod/.test(needle)) return "PROD";
|
|
if (/preprod|staging|stage/.test(needle)) return "PREPROD";
|
|
return "DEV";
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Connection draft helper
|
|
// ---------------------------------------------------------------------------
|