feat: initialize governed datasources module
This commit is contained in:
@@ -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);
|
||||
}
|
||||
Reference in New Issue
Block a user