@kaelio/ktx 0.14.0 → 0.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/python/kaelio_ktx-0.16.0-py3-none-any.whl +0 -0
- package/assets/python/manifest.json +4 -4
- package/dist/.tsbuildinfo +1 -1
- package/dist/commands/setup-commands.js +2 -0
- package/dist/connection-drivers.d.ts +1 -1
- package/dist/connection-drivers.js +2 -0
- package/dist/connection.js +1 -0
- package/dist/connectors/athena/connector.d.ts +160 -0
- package/dist/connectors/athena/connector.js +378 -0
- package/dist/connectors/athena/dialect.d.ts +31 -0
- package/dist/connectors/athena/dialect.js +146 -0
- package/dist/connectors/athena/live-database-introspection.d.ts +10 -0
- package/dist/connectors/athena/live-database-introspection.js +24 -0
- package/dist/connectors/duckdb/connector.d.ts +60 -0
- package/dist/connectors/duckdb/connector.js +282 -0
- package/dist/connectors/duckdb/dialect.d.ts +31 -0
- package/dist/connectors/duckdb/dialect.js +155 -0
- package/dist/connectors/duckdb/federated-attach.js +7 -0
- package/dist/connectors/duckdb/federated-executor.js +7 -13
- package/dist/connectors/duckdb/live-database-introspection.d.ts +8 -0
- package/dist/connectors/duckdb/live-database-introspection.js +24 -0
- package/dist/connectors/shared/duckdb-json-safe.d.ts +3 -0
- package/dist/connectors/shared/duckdb-json-safe.js +12 -0
- package/dist/context/connections/connection-type-dialect.d.ts +2 -0
- package/dist/context/connections/connection-type-dialect.js +20 -0
- package/dist/context/connections/connection-type.d.ts +6 -15
- package/dist/context/connections/connection-type.js +1 -10
- package/dist/context/connections/dialects.js +4 -0
- package/dist/context/connections/drivers.js +38 -0
- package/dist/context/connections/federation.d.ts +1 -1
- package/dist/context/connections/federation.js +6 -5
- package/dist/context/connections/local-warehouse-descriptor.d.ts +1 -0
- package/dist/context/connections/local-warehouse-descriptor.js +10 -0
- package/dist/context/connections/project-sql-executor.d.ts +24 -0
- package/dist/context/connections/project-sql-executor.js +56 -0
- package/dist/context/connections/query-policy.d.ts +12 -0
- package/dist/context/connections/query-policy.js +46 -0
- package/dist/context/core/config-reference.js +11 -1
- package/dist/context/daemon/semantic-layer-compute.d.ts +16 -0
- package/dist/context/daemon/semantic-layer-compute.js +44 -2
- package/dist/context/ingest/adapters/looker/mapping.d.ts +1 -0
- package/dist/context/ingest/adapters/looker/mapping.js +3 -10
- package/dist/context/ingest/adapters/looker/types.d.ts +6 -15
- package/dist/context/ingest/adapters/metabase/mapping.d.ts +1 -0
- package/dist/context/ingest/adapters/metabase/mapping.js +1 -0
- package/dist/context/ingest/adapters/sigma/chunk.d.ts +6 -0
- package/dist/context/ingest/adapters/sigma/chunk.js +119 -0
- package/dist/context/ingest/adapters/sigma/client-port.d.ts +45 -0
- package/dist/context/ingest/adapters/sigma/client-port.js +1 -0
- package/dist/context/ingest/adapters/sigma/client.d.ts +33 -0
- package/dist/context/ingest/adapters/sigma/client.js +176 -0
- package/dist/context/ingest/adapters/sigma/detect.d.ts +1 -0
- package/dist/context/ingest/adapters/sigma/detect.js +23 -0
- package/dist/context/ingest/adapters/sigma/fetch.d.ts +14 -0
- package/dist/context/ingest/adapters/sigma/fetch.js +191 -0
- package/dist/context/ingest/adapters/sigma/local-sigma.adapter.d.ts +17 -0
- package/dist/context/ingest/adapters/sigma/local-sigma.adapter.js +41 -0
- package/dist/context/ingest/adapters/sigma/project.d.ts +8 -0
- package/dist/context/ingest/adapters/sigma/project.js +186 -0
- package/dist/context/ingest/adapters/sigma/sigma.adapter.d.ts +18 -0
- package/dist/context/ingest/adapters/sigma/sigma.adapter.js +43 -0
- package/dist/context/ingest/adapters/sigma/types.d.ts +80 -0
- package/dist/context/ingest/adapters/sigma/types.js +82 -0
- package/dist/context/ingest/local-adapters.d.ts +2 -1
- package/dist/context/ingest/local-adapters.js +22 -0
- package/dist/context/mcp/context-tools.js +1 -0
- package/dist/context/mcp/local-project-ports.d.ts +1 -1
- package/dist/context/mcp/local-project-ports.js +53 -51
- package/dist/context/project/config.d.ts +122 -0
- package/dist/context/project/driver-schemas.d.ts +61 -0
- package/dist/context/project/driver-schemas.js +47 -0
- package/dist/context/scan/local-scan.js +3 -1
- package/dist/context/scan/types.d.ts +1 -1
- package/dist/context/sl/local-query.js +23 -6
- package/dist/context/sl/semantic-layer.service.d.ts +0 -4
- package/dist/context/sl/semantic-layer.service.js +3 -20
- package/dist/context/sl/tools/sl-warehouse-validation.d.ts +1 -1
- package/dist/context/sl/tools/sl-warehouse-validation.js +2 -2
- package/dist/context/sl/types.d.ts +1 -0
- package/dist/context/sql-analysis/dialect-notes.d.ts +1 -1
- package/dist/context/sql-analysis/dialect-notes.js +3 -2
- package/dist/context/sql-analysis/dialect.js +1 -0
- package/dist/context/sql-analysis/dialects/athena.md +12 -0
- package/dist/context/sql-analysis/dialects/duckdb.md +10 -0
- package/dist/local-adapters.js +17 -0
- package/dist/public-ingest.js +1 -0
- package/dist/setup-databases.d.ts +1 -1
- package/dist/setup-databases.js +52 -2
- package/dist/setup-sources.d.ts +2 -1
- package/dist/setup-sources.js +84 -0
- package/dist/skills/sigma_ingest/SKILL.md +189 -0
- package/dist/sql.js +9 -14
- package/dist/status-project.js +2 -1
- package/dist/telemetry/events.d.ts +1 -1
- package/package.json +3 -1
- package/assets/python/kaelio_ktx-0.14.0-py3-none-any.whl +0 -0
|
@@ -7,6 +7,7 @@ import { type LookerMappingClient, type LookerTableIdentifierParser } from './ad
|
|
|
7
7
|
import type { LookerRuntimeClient } from './adapters/looker/fetch.js';
|
|
8
8
|
import type { MetabaseClientLogger } from './adapters/metabase/client.js';
|
|
9
9
|
import type { MetabaseFetchLogger } from './adapters/metabase/fetch.js';
|
|
10
|
+
import type { SigmaFetchLogger } from './adapters/sigma/fetch.js';
|
|
10
11
|
import type { NotionFetchLogger } from './adapters/notion/fetch.js';
|
|
11
12
|
import type { SourceAdapter } from './types.js';
|
|
12
13
|
export interface DefaultLocalIngestAdaptersOptions {
|
|
@@ -29,7 +30,7 @@ export interface DefaultLocalIngestAdaptersOptions {
|
|
|
29
30
|
};
|
|
30
31
|
logger?: LocalIngestOperationalLogger;
|
|
31
32
|
}
|
|
32
|
-
type LocalIngestOperationalLogger = MetabaseClientLogger & MetabaseFetchLogger & LookerClientLogger & NotionFetchLogger;
|
|
33
|
+
type LocalIngestOperationalLogger = MetabaseClientLogger & MetabaseFetchLogger & LookerClientLogger & NotionFetchLogger & SigmaFetchLogger;
|
|
33
34
|
export declare function createDefaultLocalIngestAdapters(project: KtxLocalProject, options?: DefaultLocalIngestAdaptersOptions): SourceAdapter[];
|
|
34
35
|
export declare function localPullConfigForAdapter(project: KtxLocalProject, adapter: SourceAdapter, connectionId: string, options?: DefaultLocalIngestAdaptersOptions): Promise<unknown>;
|
|
35
36
|
export {};
|
|
@@ -22,6 +22,7 @@ import { buildLookerPullConfigFromInputs, } from './adapters/looker/mapping.js';
|
|
|
22
22
|
import { LookmlSourceAdapter } from './adapters/lookml/lookml.adapter.js';
|
|
23
23
|
import { pullConfigFromIntegrationConfig } from './adapters/lookml/pull-config.js';
|
|
24
24
|
import { createLocalMetabaseSourceAdapter } from './adapters/metabase/local-metabase.adapter.js';
|
|
25
|
+
import { createLocalSigmaSourceAdapter } from './adapters/sigma/local-sigma.adapter.js';
|
|
25
26
|
import { MetricflowSourceAdapter } from './adapters/metricflow/metricflow.adapter.js';
|
|
26
27
|
import { pullConfigFromMetricflowIntegration } from './adapters/metricflow/pull-config.js';
|
|
27
28
|
import { LocalNotionRuntimeStore } from './adapters/notion/local-state-store.js';
|
|
@@ -51,6 +52,9 @@ export function createDefaultLocalIngestAdapters(project, options = {}) {
|
|
|
51
52
|
createLocalMetabaseSourceAdapter(project, {
|
|
52
53
|
...(options.logger ? { logger: options.logger } : {}),
|
|
53
54
|
}),
|
|
55
|
+
createLocalSigmaSourceAdapter(project, {
|
|
56
|
+
...(options.logger ? { logger: options.logger } : {}),
|
|
57
|
+
}),
|
|
54
58
|
new GdriveSourceAdapter(),
|
|
55
59
|
new LookerSourceAdapter({
|
|
56
60
|
clientFactory: {
|
|
@@ -183,6 +187,24 @@ export async function localPullConfigForAdapter(project, adapter, connectionId,
|
|
|
183
187
|
if (adapter.source === 'metabase') {
|
|
184
188
|
throw new Error('Metabase scheduled pulls fan out by mapping. Call runLocalMetabaseIngest() or use `ktx ingest <metabase-source-id>` from the CLI.');
|
|
185
189
|
}
|
|
190
|
+
if (adapter.source === 'sigma') {
|
|
191
|
+
const sigmaConn = project.config.connections[connectionId];
|
|
192
|
+
const connectionMappings = sigmaConn && 'connectionMappings' in sigmaConn && sigmaConn.connectionMappings != null
|
|
193
|
+
? sigmaConn.connectionMappings
|
|
194
|
+
: undefined;
|
|
195
|
+
const workbookFilter = sigmaConn && 'workbookFilter' in sigmaConn && sigmaConn.workbookFilter != null
|
|
196
|
+
? sigmaConn.workbookFilter
|
|
197
|
+
: undefined;
|
|
198
|
+
const dataModelFilter = sigmaConn && 'dataModelFilter' in sigmaConn && sigmaConn.dataModelFilter != null
|
|
199
|
+
? sigmaConn.dataModelFilter
|
|
200
|
+
: undefined;
|
|
201
|
+
return {
|
|
202
|
+
sigmaConnectionId: connectionId,
|
|
203
|
+
...(connectionMappings ? { connectionMappings } : {}),
|
|
204
|
+
...(workbookFilter ? { workbookFilter } : {}),
|
|
205
|
+
...(dataModelFilter ? { dataModelFilter } : {}),
|
|
206
|
+
};
|
|
207
|
+
}
|
|
186
208
|
const connection = project.config.connections[connectionId];
|
|
187
209
|
if (adapter.source === HISTORIC_SQL_SOURCE_KEY) {
|
|
188
210
|
if (options.historicSqlPullConfigOverride) {
|
|
@@ -171,6 +171,7 @@ const connectionListOutputSchema = z.object({
|
|
|
171
171
|
connectionType: z.string(),
|
|
172
172
|
members: z.array(z.string()).optional(),
|
|
173
173
|
hint: z.string().optional(),
|
|
174
|
+
queryPolicy: z.literal('semantic-layer-only').optional(),
|
|
174
175
|
})),
|
|
175
176
|
});
|
|
176
177
|
const wikiSearchOutputSchema = z.object({
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { KtxSqlQueryExecutorPort } from '../../context/connections/query-executor.js';
|
|
2
2
|
import type { KtxProjectConnectionConfig } from '../../context/project/config.js';
|
|
3
3
|
import type { KtxEmbeddingPort } from '../../context/core/embedding.js';
|
|
4
|
-
import type
|
|
4
|
+
import { type KtxSemanticLayerComputePort } from '../../context/daemon/semantic-layer-compute.js';
|
|
5
5
|
import type { KtxLocalProject } from '../../context/project/project.js';
|
|
6
6
|
import type { LocalScanMcpOptions } from '../../context/scan/local-scan.js';
|
|
7
7
|
import type { SqlAnalysisPort } from '../../context/sql-analysis/ports.js';
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { KtxExpectedError, KtxQueryError, isNativeProgrammingFault } from '../../errors.js';
|
|
2
2
|
import { isDatabaseDriver, normalizeConnectionDriver } from '../../connection-drivers.js';
|
|
3
3
|
import { sqlDialectNotes } from '../../context/sql-analysis/dialect-notes.js';
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import { resolveConfiguredConnection } from '../../context/connections/resolve-connection.js';
|
|
4
|
+
import { executeProjectRawSql } from '../../context/connections/project-sql-executor.js';
|
|
5
|
+
import { federatedConnectionListing } from '../../context/connections/federation.js';
|
|
6
|
+
import { projectAllowsRawSql, restrictedFederatedMemberIds } from '../../context/connections/query-policy.js';
|
|
8
7
|
import { localConnectionInfoFromConfig, } from '../../context/connections/local-warehouse-descriptor.js';
|
|
8
|
+
import { KtxDaemonComputeError } from '../../context/daemon/semantic-layer-compute.js';
|
|
9
9
|
import { createKtxEntityDetailsService } from '../../context/scan/entity-details.js';
|
|
10
10
|
import { createKtxDiscoverDataService } from '../../context/search/discover.js';
|
|
11
11
|
import { sqlAnalysisDialectForDriver } from '../../context/sql-analysis/dialect.js';
|
|
@@ -15,8 +15,26 @@ import { readLocalSlSource } from '../../context/sl/local-sl.js';
|
|
|
15
15
|
import { assertSafeConnectionId } from '../../context/sl/source-files.js';
|
|
16
16
|
import { assertConfiguredConnectionId } from '../../context/connections/configured-connections.js';
|
|
17
17
|
import { readLocalKnowledgePage, searchLocalKnowledgePages } from '../wiki/local-knowledge.js';
|
|
18
|
+
/**
|
|
19
|
+
* Reclassify a query-path failure. Warehouse/driver rejections and daemon
|
|
20
|
+
* input-rejections are caller-driven outcomes (KtxQueryError, kept out of Error
|
|
21
|
+
* Tracking while preserving the underlying diagnostics); native JS faults, daemon
|
|
22
|
+
* crashes, and already-expected errors propagate unchanged so genuine ktx bugs
|
|
23
|
+
* still reach Error Tracking.
|
|
24
|
+
*/
|
|
25
|
+
function throwClassifiedQueryError(error) {
|
|
26
|
+
if (error instanceof KtxDaemonComputeError) {
|
|
27
|
+
if (error.inputRejected) {
|
|
28
|
+
throw new KtxQueryError(error.detail, { cause: error });
|
|
29
|
+
}
|
|
30
|
+
throw error;
|
|
31
|
+
}
|
|
32
|
+
if (isNativeProgrammingFault(error) || error instanceof KtxExpectedError) {
|
|
33
|
+
throw error;
|
|
34
|
+
}
|
|
35
|
+
throw new KtxQueryError(error instanceof Error ? error.message : String(error), { cause: error });
|
|
36
|
+
}
|
|
18
37
|
async function executeValidatedReadOnlySql(project, options, input, onProgress) {
|
|
19
|
-
await onProgress?.({ progress: 0, message: 'Validating SQL' });
|
|
20
38
|
if (!options.sqlAnalysis) {
|
|
21
39
|
throw new Error('sql_execution requires parser-backed SQL validation.');
|
|
22
40
|
}
|
|
@@ -24,50 +42,22 @@ async function executeValidatedReadOnlySql(project, options, input, onProgress)
|
|
|
24
42
|
if (!createConnector) {
|
|
25
43
|
throw new Error('sql_execution requires a local scan connector factory.');
|
|
26
44
|
}
|
|
27
|
-
const
|
|
28
|
-
const connectionId = isFederated ? input.connectionId : assertSafeConnectionId(input.connectionId);
|
|
29
|
-
const connection = isFederated ? undefined : resolveConfiguredConnection(project.config, connectionId);
|
|
30
|
-
if (!isFederated) {
|
|
31
|
-
assertSqlQueryableConnection(connectionId, connection.driver);
|
|
32
|
-
}
|
|
33
|
-
const dialect = sqlAnalysisDialectForDriver(isFederated ? 'duckdb' : connection.driver);
|
|
34
|
-
const validation = await options.sqlAnalysis.validateReadOnly(input.sql, dialect);
|
|
35
|
-
if (!validation.ok) {
|
|
36
|
-
// A read-only guard rejecting the agent's SQL is an expected outcome, not a
|
|
37
|
-
// ktx fault: classify it so reportException keeps it out of Error Tracking.
|
|
38
|
-
throw new KtxQueryError(validation.error ?? 'SQL is not read-only.');
|
|
39
|
-
}
|
|
40
|
-
await onProgress?.({ progress: 0.3, message: 'Executing' });
|
|
41
|
-
const result = await executeProjectReadOnlySql({
|
|
45
|
+
const result = await executeProjectRawSql({
|
|
42
46
|
project,
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
sql: input.sql,
|
|
48
|
-
maxRows: input.maxRows,
|
|
49
|
-
},
|
|
47
|
+
connectionId: input.connectionId,
|
|
48
|
+
sql: input.sql,
|
|
49
|
+
maxRows: input.maxRows,
|
|
50
|
+
sqlAnalysis: options.sqlAnalysis,
|
|
50
51
|
createConnector,
|
|
51
52
|
runId: 'mcp-sql-execution',
|
|
52
|
-
|
|
53
|
-
// A warehouse/driver rejection (e.g. the agent's SQL failed to compile) is a
|
|
54
|
-
// surfaced operational outcome, not a ktx fault: mark it expected while
|
|
55
|
-
// preserving the warehouse's own diagnostics. A native JS error (TypeError,
|
|
56
|
-
// etc.) signals a bug in connector code — let it propagate unchanged so Error
|
|
57
|
-
// Tracking still sees it.
|
|
58
|
-
if (isNativeProgrammingFault(error) || error instanceof KtxExpectedError) {
|
|
59
|
-
throw error;
|
|
60
|
-
}
|
|
61
|
-
throw new KtxQueryError(error instanceof Error ? error.message : String(error), { cause: error });
|
|
53
|
+
onProgress,
|
|
62
54
|
});
|
|
63
|
-
|
|
55
|
+
return {
|
|
64
56
|
headers: result.headers,
|
|
65
57
|
...(result.headerTypes ? { headerTypes: result.headerTypes } : {}),
|
|
66
58
|
rows: result.rows,
|
|
67
59
|
rowCount: result.rowCount ?? result.rows.length,
|
|
68
60
|
};
|
|
69
|
-
await onProgress?.({ progress: 1, message: `Fetched ${response.rowCount} rows` });
|
|
70
|
-
return response;
|
|
71
61
|
}
|
|
72
62
|
/** @internal Resolves a connection's dialect SQL notes; throws KtxExpectedError for an unknown or non-SQL-warehouse connection. */
|
|
73
63
|
export function resolveDialectNotesForConnection(connectionId, connection) {
|
|
@@ -92,12 +82,16 @@ export function createLocalProjectMcpContextPorts(project, options) {
|
|
|
92
82
|
.sort((a, b) => a.id.localeCompare(b.id));
|
|
93
83
|
const federated = federatedConnectionListing(project.config.connections, project.projectDir);
|
|
94
84
|
if (federated) {
|
|
85
|
+
const restricted = restrictedFederatedMemberIds(project.config, project.projectDir);
|
|
95
86
|
configured.push({
|
|
96
87
|
id: federated.id,
|
|
97
88
|
name: federated.id,
|
|
98
89
|
connectionType: 'DUCKDB',
|
|
99
90
|
members: federated.members,
|
|
100
|
-
hint:
|
|
91
|
+
hint: restricted.length > 0
|
|
92
|
+
? `Federated SQL is disabled: member connection(s) ${restricted.join(', ')} have query_policy: semantic-layer-only.`
|
|
93
|
+
: federated.hint,
|
|
94
|
+
...(restricted.length > 0 ? { queryPolicy: 'semantic-layer-only' } : {}),
|
|
101
95
|
});
|
|
102
96
|
}
|
|
103
97
|
return configured;
|
|
@@ -158,15 +152,20 @@ export function createLocalProjectMcpContextPorts(project, options) {
|
|
|
158
152
|
if (!options.semanticLayerCompute) {
|
|
159
153
|
throw new Error('sl_query requires a semantic-layer query adapter.');
|
|
160
154
|
}
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
155
|
+
try {
|
|
156
|
+
return await compileLocalSlQuery(project, {
|
|
157
|
+
connectionId: input.connectionId,
|
|
158
|
+
query: input.query,
|
|
159
|
+
compute: options.semanticLayerCompute,
|
|
160
|
+
execute: Boolean(options.queryExecutor),
|
|
161
|
+
maxRows: input.query.limit,
|
|
162
|
+
queryExecutor: options.queryExecutor,
|
|
163
|
+
onProgress: executionOptions?.onProgress,
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
catch (error) {
|
|
167
|
+
throwClassifiedQueryError(error);
|
|
168
|
+
}
|
|
170
169
|
},
|
|
171
170
|
},
|
|
172
171
|
entityDetails: {
|
|
@@ -191,7 +190,10 @@ export function createLocalProjectMcpContextPorts(project, options) {
|
|
|
191
190
|
},
|
|
192
191
|
},
|
|
193
192
|
};
|
|
194
|
-
|
|
193
|
+
// Register sql_execution only when some connection can accept raw SQL; in
|
|
194
|
+
// mixed projects the tool stays and executeProjectRawSql rejects restricted
|
|
195
|
+
// connection ids at request time.
|
|
196
|
+
if (options.sqlAnalysis && options.localScan?.createConnector && projectAllowsRawSql(project.config)) {
|
|
195
197
|
ports.sqlExecution = {
|
|
196
198
|
async execute(input, executionOptions) {
|
|
197
199
|
return executeValidatedReadOnlySql(project, options, input, executionOptions?.onProgress);
|
|
@@ -109,36 +109,82 @@ declare const connectionSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
109
109
|
url: z.ZodOptional<z.ZodString>;
|
|
110
110
|
enabled_tables: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
111
111
|
query_timeout_ms: z.ZodOptional<z.ZodNumber>;
|
|
112
|
+
query_policy: z.ZodOptional<z.ZodEnum<{
|
|
113
|
+
"read-only-sql": "read-only-sql";
|
|
114
|
+
"semantic-layer-only": "semantic-layer-only";
|
|
115
|
+
}>>;
|
|
112
116
|
}, z.core.$loose>, z.ZodObject<{
|
|
113
117
|
driver: z.ZodLiteral<"mysql">;
|
|
114
118
|
url: z.ZodOptional<z.ZodString>;
|
|
115
119
|
enabled_tables: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
116
120
|
query_timeout_ms: z.ZodOptional<z.ZodNumber>;
|
|
121
|
+
query_policy: z.ZodOptional<z.ZodEnum<{
|
|
122
|
+
"read-only-sql": "read-only-sql";
|
|
123
|
+
"semantic-layer-only": "semantic-layer-only";
|
|
124
|
+
}>>;
|
|
117
125
|
}, z.core.$loose>, z.ZodObject<{
|
|
118
126
|
driver: z.ZodLiteral<"snowflake">;
|
|
119
127
|
url: z.ZodOptional<z.ZodString>;
|
|
120
128
|
enabled_tables: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
121
129
|
query_timeout_ms: z.ZodOptional<z.ZodNumber>;
|
|
130
|
+
query_policy: z.ZodOptional<z.ZodEnum<{
|
|
131
|
+
"read-only-sql": "read-only-sql";
|
|
132
|
+
"semantic-layer-only": "semantic-layer-only";
|
|
133
|
+
}>>;
|
|
122
134
|
}, z.core.$loose>, z.ZodObject<{
|
|
123
135
|
driver: z.ZodLiteral<"bigquery">;
|
|
124
136
|
url: z.ZodOptional<z.ZodString>;
|
|
125
137
|
enabled_tables: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
126
138
|
query_timeout_ms: z.ZodOptional<z.ZodNumber>;
|
|
139
|
+
query_policy: z.ZodOptional<z.ZodEnum<{
|
|
140
|
+
"read-only-sql": "read-only-sql";
|
|
141
|
+
"semantic-layer-only": "semantic-layer-only";
|
|
142
|
+
}>>;
|
|
127
143
|
}, z.core.$loose>, z.ZodObject<{
|
|
128
144
|
driver: z.ZodLiteral<"sqlite">;
|
|
129
145
|
url: z.ZodOptional<z.ZodString>;
|
|
130
146
|
enabled_tables: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
131
147
|
query_timeout_ms: z.ZodOptional<z.ZodNumber>;
|
|
148
|
+
query_policy: z.ZodOptional<z.ZodEnum<{
|
|
149
|
+
"read-only-sql": "read-only-sql";
|
|
150
|
+
"semantic-layer-only": "semantic-layer-only";
|
|
151
|
+
}>>;
|
|
152
|
+
}, z.core.$loose>, z.ZodObject<{
|
|
153
|
+
driver: z.ZodLiteral<"duckdb">;
|
|
154
|
+
url: z.ZodOptional<z.ZodString>;
|
|
155
|
+
enabled_tables: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
156
|
+
query_timeout_ms: z.ZodOptional<z.ZodNumber>;
|
|
157
|
+
query_policy: z.ZodOptional<z.ZodEnum<{
|
|
158
|
+
"read-only-sql": "read-only-sql";
|
|
159
|
+
"semantic-layer-only": "semantic-layer-only";
|
|
160
|
+
}>>;
|
|
132
161
|
}, z.core.$loose>, z.ZodObject<{
|
|
133
162
|
driver: z.ZodLiteral<"clickhouse">;
|
|
134
163
|
url: z.ZodOptional<z.ZodString>;
|
|
135
164
|
enabled_tables: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
136
165
|
query_timeout_ms: z.ZodOptional<z.ZodNumber>;
|
|
166
|
+
query_policy: z.ZodOptional<z.ZodEnum<{
|
|
167
|
+
"read-only-sql": "read-only-sql";
|
|
168
|
+
"semantic-layer-only": "semantic-layer-only";
|
|
169
|
+
}>>;
|
|
137
170
|
}, z.core.$loose>, z.ZodObject<{
|
|
138
171
|
driver: z.ZodLiteral<"sqlserver">;
|
|
139
172
|
url: z.ZodOptional<z.ZodString>;
|
|
140
173
|
enabled_tables: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
141
174
|
query_timeout_ms: z.ZodOptional<z.ZodNumber>;
|
|
175
|
+
query_policy: z.ZodOptional<z.ZodEnum<{
|
|
176
|
+
"read-only-sql": "read-only-sql";
|
|
177
|
+
"semantic-layer-only": "semantic-layer-only";
|
|
178
|
+
}>>;
|
|
179
|
+
}, z.core.$loose>, z.ZodObject<{
|
|
180
|
+
driver: z.ZodLiteral<"athena">;
|
|
181
|
+
url: z.ZodOptional<z.ZodString>;
|
|
182
|
+
enabled_tables: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
183
|
+
query_timeout_ms: z.ZodOptional<z.ZodNumber>;
|
|
184
|
+
query_policy: z.ZodOptional<z.ZodEnum<{
|
|
185
|
+
"read-only-sql": "read-only-sql";
|
|
186
|
+
"semantic-layer-only": "semantic-layer-only";
|
|
187
|
+
}>>;
|
|
142
188
|
}, z.core.$loose>, z.ZodObject<{
|
|
143
189
|
driver: z.ZodLiteral<"mongodb">;
|
|
144
190
|
url: z.ZodString;
|
|
@@ -223,6 +269,21 @@ declare const connectionSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
223
269
|
path: z.ZodOptional<z.ZodString>;
|
|
224
270
|
auth_token_ref: z.ZodOptional<z.ZodString>;
|
|
225
271
|
}, z.core.$loose>;
|
|
272
|
+
}, z.core.$loose>, z.ZodObject<{
|
|
273
|
+
driver: z.ZodLiteral<"sigma">;
|
|
274
|
+
api_url: z.ZodDefault<z.ZodString>;
|
|
275
|
+
client_id: z.ZodString;
|
|
276
|
+
client_secret: z.ZodOptional<z.ZodString>;
|
|
277
|
+
client_secret_ref: z.ZodOptional<z.ZodString>;
|
|
278
|
+
connectionMappings: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
279
|
+
workbookFilter: z.ZodOptional<z.ZodObject<{
|
|
280
|
+
includeArchived: z.ZodDefault<z.ZodBoolean>;
|
|
281
|
+
includeExplorations: z.ZodDefault<z.ZodBoolean>;
|
|
282
|
+
updatedSince: z.ZodOptional<z.ZodString>;
|
|
283
|
+
}, z.core.$strip>>;
|
|
284
|
+
dataModelFilter: z.ZodOptional<z.ZodObject<{
|
|
285
|
+
updatedSince: z.ZodOptional<z.ZodString>;
|
|
286
|
+
}, z.core.$strip>>;
|
|
226
287
|
}, z.core.$loose>], "driver">;
|
|
227
288
|
declare const ktxProjectConfigSchema: z.ZodObject<{
|
|
228
289
|
setup: z.ZodOptional<z.ZodObject<{
|
|
@@ -233,36 +294,82 @@ declare const ktxProjectConfigSchema: z.ZodObject<{
|
|
|
233
294
|
url: z.ZodOptional<z.ZodString>;
|
|
234
295
|
enabled_tables: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
235
296
|
query_timeout_ms: z.ZodOptional<z.ZodNumber>;
|
|
297
|
+
query_policy: z.ZodOptional<z.ZodEnum<{
|
|
298
|
+
"read-only-sql": "read-only-sql";
|
|
299
|
+
"semantic-layer-only": "semantic-layer-only";
|
|
300
|
+
}>>;
|
|
236
301
|
}, z.core.$loose>, z.ZodObject<{
|
|
237
302
|
driver: z.ZodLiteral<"mysql">;
|
|
238
303
|
url: z.ZodOptional<z.ZodString>;
|
|
239
304
|
enabled_tables: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
240
305
|
query_timeout_ms: z.ZodOptional<z.ZodNumber>;
|
|
306
|
+
query_policy: z.ZodOptional<z.ZodEnum<{
|
|
307
|
+
"read-only-sql": "read-only-sql";
|
|
308
|
+
"semantic-layer-only": "semantic-layer-only";
|
|
309
|
+
}>>;
|
|
241
310
|
}, z.core.$loose>, z.ZodObject<{
|
|
242
311
|
driver: z.ZodLiteral<"snowflake">;
|
|
243
312
|
url: z.ZodOptional<z.ZodString>;
|
|
244
313
|
enabled_tables: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
245
314
|
query_timeout_ms: z.ZodOptional<z.ZodNumber>;
|
|
315
|
+
query_policy: z.ZodOptional<z.ZodEnum<{
|
|
316
|
+
"read-only-sql": "read-only-sql";
|
|
317
|
+
"semantic-layer-only": "semantic-layer-only";
|
|
318
|
+
}>>;
|
|
246
319
|
}, z.core.$loose>, z.ZodObject<{
|
|
247
320
|
driver: z.ZodLiteral<"bigquery">;
|
|
248
321
|
url: z.ZodOptional<z.ZodString>;
|
|
249
322
|
enabled_tables: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
250
323
|
query_timeout_ms: z.ZodOptional<z.ZodNumber>;
|
|
324
|
+
query_policy: z.ZodOptional<z.ZodEnum<{
|
|
325
|
+
"read-only-sql": "read-only-sql";
|
|
326
|
+
"semantic-layer-only": "semantic-layer-only";
|
|
327
|
+
}>>;
|
|
251
328
|
}, z.core.$loose>, z.ZodObject<{
|
|
252
329
|
driver: z.ZodLiteral<"sqlite">;
|
|
253
330
|
url: z.ZodOptional<z.ZodString>;
|
|
254
331
|
enabled_tables: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
255
332
|
query_timeout_ms: z.ZodOptional<z.ZodNumber>;
|
|
333
|
+
query_policy: z.ZodOptional<z.ZodEnum<{
|
|
334
|
+
"read-only-sql": "read-only-sql";
|
|
335
|
+
"semantic-layer-only": "semantic-layer-only";
|
|
336
|
+
}>>;
|
|
337
|
+
}, z.core.$loose>, z.ZodObject<{
|
|
338
|
+
driver: z.ZodLiteral<"duckdb">;
|
|
339
|
+
url: z.ZodOptional<z.ZodString>;
|
|
340
|
+
enabled_tables: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
341
|
+
query_timeout_ms: z.ZodOptional<z.ZodNumber>;
|
|
342
|
+
query_policy: z.ZodOptional<z.ZodEnum<{
|
|
343
|
+
"read-only-sql": "read-only-sql";
|
|
344
|
+
"semantic-layer-only": "semantic-layer-only";
|
|
345
|
+
}>>;
|
|
256
346
|
}, z.core.$loose>, z.ZodObject<{
|
|
257
347
|
driver: z.ZodLiteral<"clickhouse">;
|
|
258
348
|
url: z.ZodOptional<z.ZodString>;
|
|
259
349
|
enabled_tables: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
260
350
|
query_timeout_ms: z.ZodOptional<z.ZodNumber>;
|
|
351
|
+
query_policy: z.ZodOptional<z.ZodEnum<{
|
|
352
|
+
"read-only-sql": "read-only-sql";
|
|
353
|
+
"semantic-layer-only": "semantic-layer-only";
|
|
354
|
+
}>>;
|
|
261
355
|
}, z.core.$loose>, z.ZodObject<{
|
|
262
356
|
driver: z.ZodLiteral<"sqlserver">;
|
|
263
357
|
url: z.ZodOptional<z.ZodString>;
|
|
264
358
|
enabled_tables: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
265
359
|
query_timeout_ms: z.ZodOptional<z.ZodNumber>;
|
|
360
|
+
query_policy: z.ZodOptional<z.ZodEnum<{
|
|
361
|
+
"read-only-sql": "read-only-sql";
|
|
362
|
+
"semantic-layer-only": "semantic-layer-only";
|
|
363
|
+
}>>;
|
|
364
|
+
}, z.core.$loose>, z.ZodObject<{
|
|
365
|
+
driver: z.ZodLiteral<"athena">;
|
|
366
|
+
url: z.ZodOptional<z.ZodString>;
|
|
367
|
+
enabled_tables: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
368
|
+
query_timeout_ms: z.ZodOptional<z.ZodNumber>;
|
|
369
|
+
query_policy: z.ZodOptional<z.ZodEnum<{
|
|
370
|
+
"read-only-sql": "read-only-sql";
|
|
371
|
+
"semantic-layer-only": "semantic-layer-only";
|
|
372
|
+
}>>;
|
|
266
373
|
}, z.core.$loose>, z.ZodObject<{
|
|
267
374
|
driver: z.ZodLiteral<"mongodb">;
|
|
268
375
|
url: z.ZodString;
|
|
@@ -347,6 +454,21 @@ declare const ktxProjectConfigSchema: z.ZodObject<{
|
|
|
347
454
|
path: z.ZodOptional<z.ZodString>;
|
|
348
455
|
auth_token_ref: z.ZodOptional<z.ZodString>;
|
|
349
456
|
}, z.core.$loose>;
|
|
457
|
+
}, z.core.$loose>, z.ZodObject<{
|
|
458
|
+
driver: z.ZodLiteral<"sigma">;
|
|
459
|
+
api_url: z.ZodDefault<z.ZodString>;
|
|
460
|
+
client_id: z.ZodString;
|
|
461
|
+
client_secret: z.ZodOptional<z.ZodString>;
|
|
462
|
+
client_secret_ref: z.ZodOptional<z.ZodString>;
|
|
463
|
+
connectionMappings: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
464
|
+
workbookFilter: z.ZodOptional<z.ZodObject<{
|
|
465
|
+
includeArchived: z.ZodDefault<z.ZodBoolean>;
|
|
466
|
+
includeExplorations: z.ZodDefault<z.ZodBoolean>;
|
|
467
|
+
updatedSince: z.ZodOptional<z.ZodString>;
|
|
468
|
+
}, z.core.$strip>>;
|
|
469
|
+
dataModelFilter: z.ZodOptional<z.ZodObject<{
|
|
470
|
+
updatedSince: z.ZodOptional<z.ZodString>;
|
|
471
|
+
}, z.core.$strip>>;
|
|
350
472
|
}, z.core.$loose>], "driver">>>;
|
|
351
473
|
storage: z.ZodPrefault<z.ZodObject<{
|
|
352
474
|
state: z.ZodDefault<z.ZodEnum<{
|
|
@@ -4,36 +4,82 @@ export declare const connectionConfigSchema: z.ZodDiscriminatedUnion<[z.ZodObjec
|
|
|
4
4
|
url: z.ZodOptional<z.ZodString>;
|
|
5
5
|
enabled_tables: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
6
6
|
query_timeout_ms: z.ZodOptional<z.ZodNumber>;
|
|
7
|
+
query_policy: z.ZodOptional<z.ZodEnum<{
|
|
8
|
+
"read-only-sql": "read-only-sql";
|
|
9
|
+
"semantic-layer-only": "semantic-layer-only";
|
|
10
|
+
}>>;
|
|
7
11
|
}, z.core.$loose>, z.ZodObject<{
|
|
8
12
|
driver: z.ZodLiteral<"mysql">;
|
|
9
13
|
url: z.ZodOptional<z.ZodString>;
|
|
10
14
|
enabled_tables: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
11
15
|
query_timeout_ms: z.ZodOptional<z.ZodNumber>;
|
|
16
|
+
query_policy: z.ZodOptional<z.ZodEnum<{
|
|
17
|
+
"read-only-sql": "read-only-sql";
|
|
18
|
+
"semantic-layer-only": "semantic-layer-only";
|
|
19
|
+
}>>;
|
|
12
20
|
}, z.core.$loose>, z.ZodObject<{
|
|
13
21
|
driver: z.ZodLiteral<"snowflake">;
|
|
14
22
|
url: z.ZodOptional<z.ZodString>;
|
|
15
23
|
enabled_tables: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
16
24
|
query_timeout_ms: z.ZodOptional<z.ZodNumber>;
|
|
25
|
+
query_policy: z.ZodOptional<z.ZodEnum<{
|
|
26
|
+
"read-only-sql": "read-only-sql";
|
|
27
|
+
"semantic-layer-only": "semantic-layer-only";
|
|
28
|
+
}>>;
|
|
17
29
|
}, z.core.$loose>, z.ZodObject<{
|
|
18
30
|
driver: z.ZodLiteral<"bigquery">;
|
|
19
31
|
url: z.ZodOptional<z.ZodString>;
|
|
20
32
|
enabled_tables: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
21
33
|
query_timeout_ms: z.ZodOptional<z.ZodNumber>;
|
|
34
|
+
query_policy: z.ZodOptional<z.ZodEnum<{
|
|
35
|
+
"read-only-sql": "read-only-sql";
|
|
36
|
+
"semantic-layer-only": "semantic-layer-only";
|
|
37
|
+
}>>;
|
|
22
38
|
}, z.core.$loose>, z.ZodObject<{
|
|
23
39
|
driver: z.ZodLiteral<"sqlite">;
|
|
24
40
|
url: z.ZodOptional<z.ZodString>;
|
|
25
41
|
enabled_tables: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
26
42
|
query_timeout_ms: z.ZodOptional<z.ZodNumber>;
|
|
43
|
+
query_policy: z.ZodOptional<z.ZodEnum<{
|
|
44
|
+
"read-only-sql": "read-only-sql";
|
|
45
|
+
"semantic-layer-only": "semantic-layer-only";
|
|
46
|
+
}>>;
|
|
47
|
+
}, z.core.$loose>, z.ZodObject<{
|
|
48
|
+
driver: z.ZodLiteral<"duckdb">;
|
|
49
|
+
url: z.ZodOptional<z.ZodString>;
|
|
50
|
+
enabled_tables: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
51
|
+
query_timeout_ms: z.ZodOptional<z.ZodNumber>;
|
|
52
|
+
query_policy: z.ZodOptional<z.ZodEnum<{
|
|
53
|
+
"read-only-sql": "read-only-sql";
|
|
54
|
+
"semantic-layer-only": "semantic-layer-only";
|
|
55
|
+
}>>;
|
|
27
56
|
}, z.core.$loose>, z.ZodObject<{
|
|
28
57
|
driver: z.ZodLiteral<"clickhouse">;
|
|
29
58
|
url: z.ZodOptional<z.ZodString>;
|
|
30
59
|
enabled_tables: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
31
60
|
query_timeout_ms: z.ZodOptional<z.ZodNumber>;
|
|
61
|
+
query_policy: z.ZodOptional<z.ZodEnum<{
|
|
62
|
+
"read-only-sql": "read-only-sql";
|
|
63
|
+
"semantic-layer-only": "semantic-layer-only";
|
|
64
|
+
}>>;
|
|
32
65
|
}, z.core.$loose>, z.ZodObject<{
|
|
33
66
|
driver: z.ZodLiteral<"sqlserver">;
|
|
34
67
|
url: z.ZodOptional<z.ZodString>;
|
|
35
68
|
enabled_tables: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
36
69
|
query_timeout_ms: z.ZodOptional<z.ZodNumber>;
|
|
70
|
+
query_policy: z.ZodOptional<z.ZodEnum<{
|
|
71
|
+
"read-only-sql": "read-only-sql";
|
|
72
|
+
"semantic-layer-only": "semantic-layer-only";
|
|
73
|
+
}>>;
|
|
74
|
+
}, z.core.$loose>, z.ZodObject<{
|
|
75
|
+
driver: z.ZodLiteral<"athena">;
|
|
76
|
+
url: z.ZodOptional<z.ZodString>;
|
|
77
|
+
enabled_tables: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
78
|
+
query_timeout_ms: z.ZodOptional<z.ZodNumber>;
|
|
79
|
+
query_policy: z.ZodOptional<z.ZodEnum<{
|
|
80
|
+
"read-only-sql": "read-only-sql";
|
|
81
|
+
"semantic-layer-only": "semantic-layer-only";
|
|
82
|
+
}>>;
|
|
37
83
|
}, z.core.$loose>, z.ZodObject<{
|
|
38
84
|
driver: z.ZodLiteral<"mongodb">;
|
|
39
85
|
url: z.ZodString;
|
|
@@ -118,4 +164,19 @@ export declare const connectionConfigSchema: z.ZodDiscriminatedUnion<[z.ZodObjec
|
|
|
118
164
|
path: z.ZodOptional<z.ZodString>;
|
|
119
165
|
auth_token_ref: z.ZodOptional<z.ZodString>;
|
|
120
166
|
}, z.core.$loose>;
|
|
167
|
+
}, z.core.$loose>, z.ZodObject<{
|
|
168
|
+
driver: z.ZodLiteral<"sigma">;
|
|
169
|
+
api_url: z.ZodDefault<z.ZodString>;
|
|
170
|
+
client_id: z.ZodString;
|
|
171
|
+
client_secret: z.ZodOptional<z.ZodString>;
|
|
172
|
+
client_secret_ref: z.ZodOptional<z.ZodString>;
|
|
173
|
+
connectionMappings: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
174
|
+
workbookFilter: z.ZodOptional<z.ZodObject<{
|
|
175
|
+
includeArchived: z.ZodDefault<z.ZodBoolean>;
|
|
176
|
+
includeExplorations: z.ZodDefault<z.ZodBoolean>;
|
|
177
|
+
updatedSince: z.ZodOptional<z.ZodString>;
|
|
178
|
+
}, z.core.$strip>>;
|
|
179
|
+
dataModelFilter: z.ZodOptional<z.ZodObject<{
|
|
180
|
+
updatedSince: z.ZodOptional<z.ZodString>;
|
|
181
|
+
}, z.core.$strip>>;
|
|
121
182
|
}, z.core.$loose>], "driver">;
|
|
@@ -6,8 +6,10 @@ const warehouseDrivers = [
|
|
|
6
6
|
'snowflake',
|
|
7
7
|
'bigquery',
|
|
8
8
|
'sqlite',
|
|
9
|
+
'duckdb',
|
|
9
10
|
'clickhouse',
|
|
10
11
|
'sqlserver',
|
|
12
|
+
'athena',
|
|
11
13
|
];
|
|
12
14
|
function warehouseConnectionSchema(driver) {
|
|
13
15
|
return z
|
|
@@ -28,6 +30,10 @@ function warehouseConnectionSchema(driver) {
|
|
|
28
30
|
.positive()
|
|
29
31
|
.optional()
|
|
30
32
|
.describe('Maximum execution time for a single read-only query, in milliseconds (default 30000). Enforced as a server-side statement timeout for remote engines and by SIGKILL-ing a forked query subprocess for in-process SQLite. A query exceeding it is cancelled and returns a "query exceeded Ns" error so the agent can revise.'),
|
|
33
|
+
query_policy: z
|
|
34
|
+
.enum(['read-only-sql', 'semantic-layer-only'])
|
|
35
|
+
.optional()
|
|
36
|
+
.describe('Agent-facing query authorship policy (default "read-only-sql"). "read-only-sql" allows parser-validated read-only SQL plus semantic-layer queries. "semantic-layer-only" rejects raw SQL on this connection (`ktx sql`, the sql_execution tool, and federated queries that include it) and restricts semantic-layer queries to measures predefined in the semantic-layer sources. ktx-internal scan and ingest queries are unaffected.'),
|
|
31
37
|
})
|
|
32
38
|
.describe(`${driver} warehouse connection. Additional driver-tunable fields (e.g. context.queryHistory) are accepted and passed through.`);
|
|
33
39
|
}
|
|
@@ -37,8 +43,10 @@ const warehouseConnectionSchemas = [
|
|
|
37
43
|
warehouseConnectionSchema('snowflake'),
|
|
38
44
|
warehouseConnectionSchema('bigquery'),
|
|
39
45
|
warehouseConnectionSchema('sqlite'),
|
|
46
|
+
warehouseConnectionSchema('duckdb'),
|
|
40
47
|
warehouseConnectionSchema('clickhouse'),
|
|
41
48
|
warehouseConnectionSchema('sqlserver'),
|
|
49
|
+
warehouseConnectionSchema('athena'),
|
|
42
50
|
];
|
|
43
51
|
const mongodbConnectionSchema = z
|
|
44
52
|
.looseObject({
|
|
@@ -218,6 +226,44 @@ const metricflowConnectionSchema = z
|
|
|
218
226
|
.describe('Nested MetricFlow configuration block.'),
|
|
219
227
|
})
|
|
220
228
|
.describe('MetricFlow / SL context-source connection.');
|
|
229
|
+
const sigmaConnectionSchema = z
|
|
230
|
+
.looseObject({
|
|
231
|
+
driver: z.literal('sigma'),
|
|
232
|
+
api_url: z
|
|
233
|
+
.string()
|
|
234
|
+
.url()
|
|
235
|
+
.default('https://api.sigmacomputing.com')
|
|
236
|
+
.describe('Sigma API base URL. Defaults to the GCP US endpoint; change for other regions.'),
|
|
237
|
+
client_id: z.string().min(1).describe('Sigma API client ID.'),
|
|
238
|
+
client_secret: z.string().min(1).optional().describe('Literal Sigma client secret. Prefer client_secret_ref.'),
|
|
239
|
+
client_secret_ref: z
|
|
240
|
+
.string()
|
|
241
|
+
.min(1)
|
|
242
|
+
.optional()
|
|
243
|
+
.describe('Reference to Sigma client secret (e.g. env:SIGMA_CLIENT_SECRET).'),
|
|
244
|
+
connectionMappings: z
|
|
245
|
+
.record(z.string(), z.string())
|
|
246
|
+
.optional()
|
|
247
|
+
.describe('Maps Sigma internal connection UUIDs to ktx warehouse connection IDs. ' +
|
|
248
|
+
'When set, projected semantic-layer sources land under the mapped warehouse connection ' +
|
|
249
|
+
'instead of the Sigma connection, enabling sl_validate. ' +
|
|
250
|
+
'Find UUIDs in data model specs under source.connectionId.'),
|
|
251
|
+
workbookFilter: z
|
|
252
|
+
.object({
|
|
253
|
+
includeArchived: z.boolean().default(false),
|
|
254
|
+
includeExplorations: z.boolean().default(false),
|
|
255
|
+
updatedSince: z.string().optional().describe('ISO 8601 date string. Only workbooks updated on or after this date are ingested.'),
|
|
256
|
+
})
|
|
257
|
+
.optional()
|
|
258
|
+
.describe('Filters applied when listing workbooks during ingest. Defaults exclude archived and exploration workbooks.'),
|
|
259
|
+
dataModelFilter: z
|
|
260
|
+
.object({
|
|
261
|
+
updatedSince: z.string().optional().describe('ISO 8601 date string. Only data models updated on or after this date are fetched.'),
|
|
262
|
+
})
|
|
263
|
+
.optional()
|
|
264
|
+
.describe('Filters applied when listing data models during ingest.'),
|
|
265
|
+
})
|
|
266
|
+
.describe('Sigma Computing API connection for ingesting data models.');
|
|
221
267
|
export const connectionConfigSchema = z.discriminatedUnion('driver', [
|
|
222
268
|
...warehouseConnectionSchemas,
|
|
223
269
|
mongodbConnectionSchema,
|
|
@@ -228,4 +274,5 @@ export const connectionConfigSchema = z.discriminatedUnion('driver', [
|
|
|
228
274
|
gdriveConnectionSchema,
|
|
229
275
|
dbtConnectionSchema,
|
|
230
276
|
metricflowConnectionSchema,
|
|
277
|
+
sigmaConnectionSchema,
|
|
231
278
|
]);
|
|
@@ -43,15 +43,17 @@ function normalizeDriver(driver) {
|
|
|
43
43
|
const normalized = (driver ?? '').toLowerCase();
|
|
44
44
|
if (normalized === 'postgres' ||
|
|
45
45
|
normalized === 'sqlite' ||
|
|
46
|
+
normalized === 'duckdb' ||
|
|
46
47
|
normalized === 'mysql' ||
|
|
47
48
|
normalized === 'clickhouse' ||
|
|
48
49
|
normalized === 'sqlserver' ||
|
|
49
50
|
normalized === 'bigquery' ||
|
|
50
51
|
normalized === 'snowflake' ||
|
|
52
|
+
normalized === 'athena' ||
|
|
51
53
|
normalized === 'mongodb') {
|
|
52
54
|
return normalized;
|
|
53
55
|
}
|
|
54
|
-
throw new Error(`Standalone ktx scan supports postgres/sqlite/mysql/clickhouse/sqlserver/bigquery/snowflake/mongodb in this phase, received "${driver ?? 'unknown'}"`);
|
|
56
|
+
throw new Error(`Standalone ktx scan supports postgres/sqlite/duckdb/mysql/clickhouse/sqlserver/bigquery/snowflake/athena/mongodb in this phase, received "${driver ?? 'unknown'}"`);
|
|
55
57
|
}
|
|
56
58
|
function tablePathCount(paths) {
|
|
57
59
|
return paths.filter((path) => path.startsWith('tables/') && path.endsWith('.json')).length;
|