feat: initialize governed datasources module

This commit is contained in:
2026-07-28 12:43:02 +02:00
commit 1cb6228442
37 changed files with 5910 additions and 0 deletions
+231
View File
@@ -0,0 +1,231 @@
import {
apiFetch,
type ApiSettings
} from "@govoplan/core-webui";
export type DatasourceMode = "live" | "cached" | "static";
export type DatasourceShape = "tabular" | "document" | "binary" | "directory" | "stream";
export type DatasourceField = {
name: string;
data_type: string;
nullable: boolean;
};
export type Datasource = {
ref: string;
source_name: string;
name: string;
description?: string | null;
kind: string;
mode: DatasourceMode;
shape: DatasourceShape;
status: string;
provider?: string | null;
provider_ref?: string | null;
schema: DatasourceField[];
schema_version: string;
fingerprint: string;
current_materialization_ref?: string | null;
row_count?: number | null;
byte_count?: number | null;
updated_at?: string | null;
capabilities: string[];
provenance: Record<string, unknown>;
metadata: Record<string, unknown>;
};
export type DatasourceMaterialization = {
ref: string;
datasource_ref: string;
revision: number;
state: string;
fingerprint: string;
schema: DatasourceField[];
row_count?: number | null;
byte_count?: number | null;
frozen_at?: string | null;
frozen_label?: string | null;
source_timestamp?: string | null;
created_at?: string | null;
provenance: Record<string, unknown>;
metadata: Record<string, unknown>;
};
export type DatasourceStage = {
ref: string;
name: string;
source_name: string;
kind: string;
mode: "static" | "cached";
shape: DatasourceShape;
state: string;
target_datasource_ref?: string | null;
fingerprint: string;
schema: DatasourceField[];
row_count?: number | null;
byte_count?: number | null;
validation: Record<string, unknown>;
created_at?: string | null;
promoted_at?: string | null;
promoted_materialization_ref?: string | null;
provenance: Record<string, unknown>;
metadata: Record<string, unknown>;
};
export type DatasourceOrigin = {
ref: string;
source_name: string;
name: string;
description?: string | null;
kind: string;
shape: DatasourceShape;
supported_modes: DatasourceMode[];
provider: string;
schema: DatasourceField[];
schema_version: string;
fingerprint: string;
row_count?: number | null;
byte_count?: number | null;
updated_at?: string | null;
capabilities: string[];
metadata: Record<string, unknown>;
};
export type DatasourcePreview = {
datasource: Datasource;
rows: Record<string, unknown>[];
total_rows: number;
truncated: boolean;
materialization?: DatasourceMaterialization | null;
};
export async function listDatasources(
settings: ApiSettings,
query = ""
): Promise<Datasource[]> {
const suffix = query.trim() ? `?query=${encodeURIComponent(query.trim())}` : "";
const response = await apiFetch<{ datasources: Datasource[] }>(
settings,
`/api/v1/datasources${suffix}`
);
return response.datasources;
}
export async function listDatasourceStages(
settings: ApiSettings
): Promise<DatasourceStage[]> {
const response = await apiFetch<{ stages: DatasourceStage[] }>(
settings,
"/api/v1/datasources/stages"
);
return response.stages;
}
export async function listDatasourceOrigins(
settings: ApiSettings
): Promise<{ available: boolean; origins: DatasourceOrigin[] }> {
return apiFetch(settings, "/api/v1/datasources/origins");
}
export async function listDatasourceMaterializations(
settings: ApiSettings,
datasourceRef: string
): Promise<DatasourceMaterialization[]> {
const response = await apiFetch<{ materializations: DatasourceMaterialization[] }>(
settings,
`/api/v1/datasources/${refId(datasourceRef)}/materializations`
);
return response.materializations;
}
export function previewDatasource(
settings: ApiSettings,
datasourceRef: string,
consistency: "current" | "live" | "frozen" = "current"
): Promise<DatasourcePreview> {
return apiFetch(
settings,
`/api/v1/datasources/${refId(datasourceRef)}/preview?limit=100&consistency=${consistency}`
);
}
export function createDatasourceStage(
settings: ApiSettings,
payload: {
name: string;
source_name: string;
description?: string | null;
mode: "static" | "cached";
target_datasource_ref?: string | null;
} & (
{ format: "json"; rows: Record<string, unknown>[] }
| { format: "csv"; csv_text: string; delimiter: string }
)
): Promise<DatasourceStage> {
return apiFetch(settings, "/api/v1/datasources/stages", {
method: "POST",
body: JSON.stringify(payload)
});
}
export function promoteDatasourceStage(
settings: ApiSettings,
stageRef: string,
payload: { freeze?: boolean; frozen_label?: string | null } = {}
): Promise<{ datasource: Datasource; materialization: DatasourceMaterialization }> {
return apiFetch(settings, `/api/v1/datasources/stages/${refId(stageRef)}/promote`, {
method: "POST",
body: JSON.stringify(payload)
});
}
export function registerDatasourceOrigin(
settings: ApiSettings,
payload: {
origin_ref: string;
name: string;
source_name: string;
mode: "live" | "cached";
description?: string | null;
}
): Promise<Datasource> {
return apiFetch(settings, "/api/v1/datasources/origins/register", {
method: "POST",
body: JSON.stringify(payload)
});
}
export function refreshDatasource(
settings: ApiSettings,
datasourceRef: string
): Promise<{ datasource: Datasource; materialization: DatasourceMaterialization }> {
return apiFetch(settings, `/api/v1/datasources/${refId(datasourceRef)}/refresh`, {
method: "POST"
});
}
export function freezeDatasource(
settings: ApiSettings,
datasourceRef: string,
label: string
): Promise<DatasourceMaterialization> {
return apiFetch(settings, `/api/v1/datasources/${refId(datasourceRef)}/freeze`, {
method: "POST",
body: JSON.stringify({ label: label.trim() || null })
});
}
export function retireDatasource(
settings: ApiSettings,
datasourceRef: string
): Promise<{ retired: boolean; datasource_ref: string }> {
return apiFetch(settings, `/api/v1/datasources/${refId(datasourceRef)}`, {
method: "DELETE"
});
}
function refId(ref: string): string {
const separator = ref.indexOf(":");
return encodeURIComponent(separator >= 0 ? ref.slice(separator + 1) : ref);
}