@querypanel/node-sdk 1.0.17 → 1.0.19

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.
Files changed (35) hide show
  1. package/dist/cjs/__tests__/ingest.test.d.ts +5 -0
  2. package/dist/cjs/__tests__/ingest.test.d.ts.map +1 -0
  3. package/dist/cjs/__tests__/ingest.test.js +95 -0
  4. package/dist/cjs/__tests__/ingest.test.js.map +1 -0
  5. package/dist/cjs/connectors/__tests__/clickhouse.introspect.test.d.ts +2 -0
  6. package/dist/cjs/connectors/__tests__/clickhouse.introspect.test.d.ts.map +1 -0
  7. package/dist/cjs/connectors/__tests__/clickhouse.introspect.test.js +119 -0
  8. package/dist/cjs/connectors/__tests__/clickhouse.introspect.test.js.map +1 -0
  9. package/dist/cjs/connectors/base.d.ts +2 -3
  10. package/dist/cjs/connectors/base.d.ts.map +1 -1
  11. package/dist/cjs/connectors/clickhouse.d.ts +28 -10
  12. package/dist/cjs/connectors/clickhouse.d.ts.map +1 -1
  13. package/dist/cjs/connectors/clickhouse.js +55 -77
  14. package/dist/cjs/connectors/clickhouse.js.map +1 -1
  15. package/dist/cjs/index.d.ts +26 -0
  16. package/dist/cjs/index.d.ts.map +1 -1
  17. package/dist/cjs/index.js +114 -5
  18. package/dist/cjs/index.js.map +1 -1
  19. package/dist/cjs/tenant-isolation.spec.d.ts +2 -0
  20. package/dist/cjs/tenant-isolation.spec.d.ts.map +1 -0
  21. package/dist/cjs/tenant-isolation.spec.js +366 -0
  22. package/dist/cjs/tenant-isolation.spec.js.map +1 -0
  23. package/dist/esm/connectors/clickhouse.d.ts +4 -4
  24. package/dist/esm/connectors/clickhouse.d.ts.map +1 -1
  25. package/dist/esm/connectors/clickhouse.js +25 -32
  26. package/dist/esm/connectors/clickhouse.js.map +1 -1
  27. package/dist/esm/index.d.ts +26 -0
  28. package/dist/esm/index.d.ts.map +1 -1
  29. package/dist/esm/index.js +114 -5
  30. package/dist/esm/index.js.map +1 -1
  31. package/dist/esm/tenant-isolation.spec.d.ts +2 -0
  32. package/dist/esm/tenant-isolation.spec.d.ts.map +1 -0
  33. package/dist/esm/tenant-isolation.spec.js +364 -0
  34. package/dist/esm/tenant-isolation.spec.js.map +1 -0
  35. package/package.json +1 -1
@@ -0,0 +1,5 @@
1
+ declare global {
2
+ var fetch: typeof globalThis.fetch;
3
+ }
4
+ export {};
5
+ //# sourceMappingURL=ingest.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ingest.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/ingest.test.ts"],"names":[],"mappings":"AAKA,OAAO,CAAC,MAAM,CAAC;IAEX,IAAI,KAAK,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;CACtC"}
@@ -0,0 +1,95 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const vitest_1 = require("vitest");
4
+ const index_js_1 = require("../index.js");
5
+ const noop = () => { };
6
+ class StubConnector {
7
+ constructor(introspection) {
8
+ this.introspection = introspection;
9
+ this.connect = vitest_1.vi.fn(async () => { });
10
+ this.close = vitest_1.vi.fn(async () => { });
11
+ this.executeQuery = vitest_1.vi.fn(async () => []);
12
+ this.introspect = vitest_1.vi.fn(async (_options) => this.introspection);
13
+ }
14
+ }
15
+ (0, vitest_1.describe)('Ingestion API', () => {
16
+ const originalFetch = globalThis.fetch;
17
+ const fakeResponse = {
18
+ ok: true,
19
+ status: 200,
20
+ text: async () => JSON.stringify({ message: 'ok', ingestedTables: 1 }),
21
+ };
22
+ let fetchMock;
23
+ (0, vitest_1.beforeEach)(() => {
24
+ fetchMock = vitest_1.vi.fn().mockResolvedValue(fakeResponse);
25
+ globalThis.fetch = fetchMock;
26
+ });
27
+ (0, vitest_1.afterEach)(() => {
28
+ fetchMock.mockReset();
29
+ if (originalFetch) {
30
+ globalThis.fetch = originalFetch;
31
+ }
32
+ else {
33
+ delete globalThis.fetch;
34
+ }
35
+ });
36
+ (0, vitest_1.it)('posts schema introspection payloads with merged metadata', async () => {
37
+ const sdk = new index_js_1.QueryPanelSdkAPI('https://example.com', 'token');
38
+ const introspection = {
39
+ db: { kind: 'clickhouse', name: 'analytics' },
40
+ tables: [],
41
+ introspectedAt: new Date().toISOString(),
42
+ metadata: { existing: true },
43
+ };
44
+ const response = await sdk.ingestSchema(introspection, {
45
+ tenantId: 'tenant-1',
46
+ metadata: { triggeredBy: 'test' },
47
+ });
48
+ (0, vitest_1.expect)(response).toMatchObject({ message: 'ok', ingestedTables: 1 });
49
+ (0, vitest_1.expect)(fetchMock).toHaveBeenCalledTimes(1);
50
+ const [url, init] = fetchMock.mock.calls[0];
51
+ (0, vitest_1.expect)(url).toBe('https://example.com/ingest/schema');
52
+ (0, vitest_1.expect)(init.method).toBe('POST');
53
+ (0, vitest_1.expect)(init.headers).toMatchObject({
54
+ Authorization: 'Bearer token',
55
+ 'Content-Type': 'application/json',
56
+ });
57
+ const body = JSON.parse(init.body);
58
+ (0, vitest_1.expect)(body.metadata).toEqual({ existing: true, triggeredBy: 'test' });
59
+ });
60
+ (0, vitest_1.it)('introspects via connector and closes connections by default', async () => {
61
+ const sdk = new index_js_1.QueryPanelSdkAPI('https://example.com', 'token');
62
+ const introspection = {
63
+ db: { kind: 'clickhouse', name: 'analytics' },
64
+ tables: [],
65
+ introspectedAt: new Date().toISOString(),
66
+ };
67
+ const connector = new StubConnector(introspection);
68
+ const response = await sdk.introspectAndIngest(connector, {
69
+ tenantId: 'tenant-1',
70
+ metadata: { flow: 'batch' },
71
+ tables: ['events'],
72
+ });
73
+ (0, vitest_1.expect)(response.message).toBe('ok');
74
+ (0, vitest_1.expect)(connector.connect).toHaveBeenCalledTimes(1);
75
+ (0, vitest_1.expect)(connector.introspect).toHaveBeenCalledWith({ tables: ['events'] });
76
+ (0, vitest_1.expect)(connector.close).toHaveBeenCalledTimes(1);
77
+ const [, init] = fetchMock.mock.calls[0];
78
+ const body = JSON.parse(init.body);
79
+ (0, vitest_1.expect)(body.metadata).toEqual({ flow: 'batch' });
80
+ });
81
+ (0, vitest_1.it)('respects keepConnectionOpen option', async () => {
82
+ const sdk = new index_js_1.QueryPanelSdkAPI('https://example.com', 'token');
83
+ const connector = new StubConnector({
84
+ db: { kind: 'clickhouse', name: 'analytics' },
85
+ tables: [],
86
+ introspectedAt: new Date().toISOString(),
87
+ });
88
+ await sdk.introspectAndIngest(connector, {
89
+ tenantId: 'tenant-1',
90
+ keepConnectionOpen: true,
91
+ });
92
+ (0, vitest_1.expect)(connector.close).not.toHaveBeenCalled();
93
+ });
94
+ });
95
+ //# sourceMappingURL=ingest.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ingest.test.js","sourceRoot":"","sources":["../../../src/__tests__/ingest.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=clickhouse.introspect.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clickhouse.introspect.test.d.ts","sourceRoot":"","sources":["../../../../src/connectors/__tests__/clickhouse.introspect.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,119 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const vitest_1 = require("vitest");
4
+ const clickhouse_js_1 = require("../clickhouse.js");
5
+ class StubResultSet {
6
+ constructor(payload) {
7
+ this.payload = payload;
8
+ }
9
+ async json() {
10
+ return this.payload;
11
+ }
12
+ }
13
+ class StubClickHouseClient {
14
+ constructor(responses) {
15
+ this.queries = [];
16
+ this.responses = responses;
17
+ }
18
+ async query(params) {
19
+ this.queries.push({ query: params.query, params: params.query_params });
20
+ const responseKey = params.query.includes('system.tables') ? 'tables' : 'columns';
21
+ const payload = this.responses.get(responseKey);
22
+ if (!payload) {
23
+ throw new Error(`No stub response registered for ${responseKey}`);
24
+ }
25
+ return new StubResultSet(payload);
26
+ }
27
+ async ping() {
28
+ return { success: true };
29
+ }
30
+ async close() { }
31
+ }
32
+ (0, vitest_1.describe)('ClickHouseConnector', () => {
33
+ (0, vitest_1.it)('introspects tables with large column counts', async () => {
34
+ const tableRows = [
35
+ {
36
+ name: 'events',
37
+ engine: 'MergeTree',
38
+ comment: 'User event stream',
39
+ total_rows: '424242',
40
+ total_bytes: '1024',
41
+ is_view: 0,
42
+ primary_key: 'tuple(event_id, occurred_at)',
43
+ sorting_key: 'tuple(occurred_at)',
44
+ },
45
+ ];
46
+ const columnRows = Array.from({ length: 120 }, (_, index) => ({
47
+ table: 'events',
48
+ name: `column_${index}`,
49
+ type: index % 2 === 0 ? 'Nullable(String)' : 'UInt32',
50
+ position: index + 1,
51
+ default_kind: index % 10 === 0 ? 'DEFAULT' : null,
52
+ default_expression: index % 10 === 0 ? `'value_${index}'` : null,
53
+ comment: index % 15 === 0 ? `Column ${index}` : null,
54
+ codec_expression: index % 20 === 0 ? 'ZSTD(3)' : null,
55
+ ttl_expression: null,
56
+ is_in_primary_key: index === 0 ? 1 : 0,
57
+ data_compressed_bytes: '128',
58
+ data_uncompressed_bytes: '256',
59
+ }));
60
+ const responses = new Map([
61
+ ['tables', tableRows],
62
+ ['columns', columnRows],
63
+ ]);
64
+ const stubClient = new StubClickHouseClient(responses);
65
+ const connector = new clickhouse_js_1.ClickHouseConnector({
66
+ database: 'analytics',
67
+ }, { client: stubClient });
68
+ const introspection = await connector.introspect();
69
+ (0, vitest_1.expect)(introspection.db).toEqual({ kind: 'clickhouse', name: 'analytics' });
70
+ (0, vitest_1.expect)(introspection.tables).toHaveLength(1);
71
+ const [table] = introspection.tables;
72
+ (0, vitest_1.expect)(table.name).toBe('events');
73
+ (0, vitest_1.expect)(table.columns).toHaveLength(120);
74
+ (0, vitest_1.expect)(table.columns[0]).toMatchObject({
75
+ name: 'column_0',
76
+ nullable: true,
77
+ type: 'String',
78
+ rawType: 'Nullable(String)',
79
+ defaultKind: 'DEFAULT',
80
+ defaultExpression: `'value_0'`,
81
+ statistics: { compressedBytes: 128, uncompressedBytes: 256 },
82
+ });
83
+ (0, vitest_1.expect)(table.columns.at(-1)).toMatchObject({
84
+ nullable: false,
85
+ type: 'UInt32',
86
+ });
87
+ (0, vitest_1.expect)(table.statistics).toEqual({ totalRows: 424242, totalBytes: 1024 });
88
+ (0, vitest_1.expect)(table.indexes).toEqual([
89
+ {
90
+ name: 'primary_key',
91
+ columns: ['event_id', 'occurred_at'],
92
+ unique: true,
93
+ type: 'PRIMARY KEY',
94
+ definition: 'tuple(event_id, occurred_at)',
95
+ },
96
+ ]);
97
+ (0, vitest_1.expect)(table.constraints[0]).toMatchObject({
98
+ type: 'PRIMARY KEY',
99
+ columns: ['event_id', 'occurred_at'],
100
+ });
101
+ (0, vitest_1.expect)(new Date(introspection.introspectedAt).toISOString()).toBe(introspection.introspectedAt);
102
+ (0, vitest_1.expect)(stubClient.queries).toHaveLength(2);
103
+ (0, vitest_1.expect)(stubClient.queries[0].params).toEqual({ db: 'analytics' });
104
+ });
105
+ (0, vitest_1.it)('applies table filters when provided', async () => {
106
+ const responses = new Map([
107
+ ['tables', [{ name: 'events', engine: 'MergeTree', is_view: 0 }]],
108
+ ['columns', [{ table: 'events', name: 'column_1', type: 'UInt64', position: 1 }]],
109
+ ]);
110
+ const stubClient = new StubClickHouseClient(responses);
111
+ const connector = new clickhouse_js_1.ClickHouseConnector({ database: 'analytics' }, { client: stubClient });
112
+ await connector.introspect({ tables: ['analytics.events', 'events'] });
113
+ (0, vitest_1.expect)(stubClient.queries).toHaveLength(2);
114
+ for (const query of stubClient.queries) {
115
+ (0, vitest_1.expect)(query.params).toEqual({ db: 'analytics', tables: ['events'] });
116
+ }
117
+ });
118
+ });
119
+ //# sourceMappingURL=clickhouse.introspect.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clickhouse.introspect.test.js","sourceRoot":"","sources":["../../../../src/connectors/__tests__/clickhouse.introspect.test.ts"],"names":[],"mappings":"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"}
@@ -1,13 +1,12 @@
1
- import type { DataFormat } from '@clickhouse/client';
2
1
  import type { IntrospectOptions, SchemaIntrospection } from '../schema/types.js';
3
2
  export interface QueryOptions {
4
3
  params?: Record<string, unknown>;
5
- format?: DataFormat;
4
+ format?: string;
6
5
  settings?: Record<string, unknown>;
7
6
  }
8
7
  export interface DatabaseConnector {
9
8
  connect(): Promise<void>;
10
- query<T = Record<string, unknown>>(sql: string, options?: QueryOptions): Promise<T[]>;
9
+ executeQuery<T = Record<string, unknown>>(query: string, options?: QueryOptions): Promise<T[]>;
11
10
  introspect(options?: IntrospectOptions): Promise<SchemaIntrospection>;
12
11
  close(): Promise<void>;
13
12
  }
@@ -1 +1 @@
1
- {"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../../src/connectors/base.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,KAAK,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAEjF,MAAM,WAAW,YAAY;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC;AAED,MAAM,WAAW,iBAAiB;IAC9B,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACzB,KAAK,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC;IACtF,UAAU,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAC;IACtE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1B"}
1
+ {"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../../src/connectors/base.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAEjF,MAAM,WAAW,YAAY;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC;AAED,MAAM,WAAW,iBAAiB;IAC9B,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACzB,YAAY,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC;IAC/F,UAAU,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAC;IACtE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1B"}
@@ -1,12 +1,30 @@
1
- import { type ClickHouseClient, type ClickHouseClientConfigOptions } from "@clickhouse/client";
2
- import type { IntrospectOptions, SchemaIntrospection } from "../schema/types.js";
3
- import type { DatabaseConnector, QueryOptions } from "./base.js";
1
+ import { type ClickHouseClientConfigOptions, type ClickHouseSettings } from '@clickhouse/client';
2
+ import type { IntrospectOptions, SchemaIntrospection } from '../schema/types.js';
3
+ import type { DatabaseConnector, QueryOptions } from './base.js';
4
+ interface ResultSetLike {
5
+ json<T = unknown>(): Promise<T>;
6
+ }
7
+ interface ClickHouseClientLike {
8
+ query(params: {
9
+ query: string;
10
+ format?: string;
11
+ query_params?: Record<string, unknown>;
12
+ clickhouse_settings?: ClickHouseSettings;
13
+ }): Promise<ResultSetLike>;
14
+ ping(): Promise<{
15
+ success: boolean;
16
+ error?: Error;
17
+ } | {
18
+ success?: boolean;
19
+ }>;
20
+ close(): Promise<void>;
21
+ }
4
22
  export interface ClickHouseConnectorConfig {
5
23
  /** Fully qualified ClickHouse URL. Overrides host/port/protocol when provided. */
6
24
  url?: string;
7
25
  host?: string;
8
26
  port?: number;
9
- protocol?: "http" | "https";
27
+ protocol?: 'http' | 'https';
10
28
  database: string;
11
29
  username?: string;
12
30
  password?: string;
@@ -15,21 +33,21 @@ export interface ClickHouseConnectorConfig {
15
33
  clientOptions?: Partial<ClickHouseClientConfigOptions>;
16
34
  }
17
35
  export interface ClickHouseConnectorOverrides {
18
- client?: ClickHouseClient;
19
- clientFactory?: () => ClickHouseClient;
36
+ client?: ClickHouseClientLike;
37
+ clientFactory?: () => ClickHouseClientLike;
20
38
  }
21
39
  export declare class ClickHouseConnector implements DatabaseConnector {
40
+ private client;
22
41
  private readonly config;
23
42
  private readonly overrides;
24
- private client;
25
- private readonly defaultFormat;
43
+ private defaultFormat;
26
44
  constructor(config: ClickHouseConnectorConfig, overrides?: ClickHouseConnectorOverrides);
27
45
  connect(): Promise<void>;
28
- query<T = Record<string, unknown>>(sql: string, options?: QueryOptions): Promise<T[]>;
46
+ executeQuery<T = Record<string, unknown>>(query: string, options?: QueryOptions): Promise<T[]>;
29
47
  introspect(options?: IntrospectOptions): Promise<SchemaIntrospection>;
30
48
  close(): Promise<void>;
31
49
  private ensureClient;
32
- private safePing;
33
50
  private buildClientConfig;
34
51
  }
52
+ export {};
35
53
  //# sourceMappingURL=clickhouse.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"clickhouse.d.ts","sourceRoot":"","sources":["../../../src/connectors/clickhouse.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,KAAK,gBAAgB,EACrB,KAAK,6BAA6B,EAIlC,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAEX,iBAAiB,EACjB,mBAAmB,EAEnB,MAAM,oBAAoB,CAAC;AAQ5B,OAAO,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAEjE,MAAM,WAAW,yBAAyB;IACzC,kFAAkF;IAClF,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC7C,aAAa,CAAC,EAAE,OAAO,CAAC,6BAA6B,CAAC,CAAC;CACvD;AAED,MAAM,WAAW,4BAA4B;IAC5C,MAAM,CAAC,EAAE,gBAAgB,CAAC;IAC1B,aAAa,CAAC,EAAE,MAAM,gBAAgB,CAAC;CACvC;AA4BD,qBAAa,mBAAoB,YAAW,iBAAiB;IAO3D,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAP3B,OAAO,CAAC,MAAM,CAA0B;IACxC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAEC;gBAGb,MAAM,EAAE,yBAAyB,EACjC,SAAS,GAAE,4BAAiC;IAKxD,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAIxB,KAAK,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACtC,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,YAAY,GACpB,OAAO,CAAC,CAAC,EAAE,CAAC;IAmCT,UAAU,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAyGrE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;YAMd,YAAY;YAcZ,QAAQ;IAYtB,OAAO,CAAC,iBAAiB;CAkCzB"}
1
+ {"version":3,"file":"clickhouse.d.ts","sourceRoot":"","sources":["../../../src/connectors/clickhouse.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,KAAK,6BAA6B,EAAE,KAAK,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAC/G,OAAO,KAAK,EAAgB,iBAAiB,EAAE,mBAAmB,EAAe,MAAM,oBAAoB,CAAC;AAE5G,OAAO,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAEjE,UAAU,aAAa;IACnB,IAAI,CAAC,CAAC,GAAG,OAAO,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC;CACnC;AAED,UAAU,oBAAoB;IAC1B,KAAK,CAAC,MAAM,EAAE;QACV,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACvC,mBAAmB,CAAC,EAAE,kBAAkB,CAAC;KAC5C,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;IAC3B,IAAI,IAAI,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,KAAK,CAAA;KAAE,GAAG;QAAE,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IAC7E,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1B;AAED,MAAM,WAAW,yBAAyB;IACtC,kFAAkF;IAClF,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC7C,aAAa,CAAC,EAAE,OAAO,CAAC,6BAA6B,CAAC,CAAC;CAC1D;AAED,MAAM,WAAW,4BAA4B;IACzC,MAAM,CAAC,EAAE,oBAAoB,CAAC;IAC9B,aAAa,CAAC,EAAE,MAAM,oBAAoB,CAAC;CAC9C;AA4BD,qBAAa,mBAAoB,YAAW,iBAAiB;IACzD,OAAO,CAAC,MAAM,CAA8B;IAC5C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA4B;IACnD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAoC;IAC9D,OAAO,CAAC,aAAa,CAAyB;gBAElC,MAAM,EAAE,yBAAyB,EAAE,SAAS,CAAC,EAAE,4BAA4B;IAQjF,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAIxB,YAAY,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC;IAsB9F,UAAU,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAqGrE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;YAMd,YAAY;IAY1B,OAAO,CAAC,iBAAiB;CA+B5B"}
@@ -4,38 +4,32 @@ exports.ClickHouseConnector = void 0;
4
4
  const client_1 = require("@clickhouse/client");
5
5
  const clickhouse_js_1 = require("../utils/clickhouse.js");
6
6
  class ClickHouseConnector {
7
- constructor(config, overrides = {}) {
7
+ constructor(config, overrides) {
8
+ this.overrides = {};
9
+ this.defaultFormat = 'JSONEachRow';
8
10
  this.config = config;
9
- this.overrides = overrides;
10
- this.defaultFormat = "JSONEachRow";
11
- this.client = overrides.client ?? null;
11
+ if (overrides) {
12
+ this.overrides = overrides;
13
+ }
14
+ this.client = overrides?.client ?? null;
12
15
  }
13
16
  async connect() {
14
17
  await this.ensureClient();
15
18
  }
16
- async query(sql, options) {
19
+ async executeQuery(query, options) {
17
20
  const client = await this.ensureClient();
18
- const params = {
19
- query: sql,
20
- };
21
21
  const format = options?.format ?? this.defaultFormat;
22
- if (format) {
23
- Object.assign(params, { format });
24
- }
25
- if (options?.params) {
26
- Object.assign(params, { query_params: options.params });
27
- }
28
- if (options?.settings) {
29
- Object.assign(params, {
30
- clickhouse_settings: options.settings,
31
- });
32
- }
33
- const result = await client.query(params);
22
+ const result = await client.query({
23
+ query,
24
+ format,
25
+ query_params: options?.params,
26
+ clickhouse_settings: options?.settings,
27
+ });
34
28
  const payload = await result.json();
35
29
  if (Array.isArray(payload)) {
36
30
  return payload;
37
31
  }
38
- if (payload && typeof payload === "object") {
32
+ if (payload && typeof payload === 'object') {
39
33
  const maybeData = payload.data;
40
34
  if (Array.isArray(maybeData)) {
41
35
  return maybeData;
@@ -52,42 +46,45 @@ class ClickHouseConnector {
52
46
  if (hasFilter) {
53
47
  queryParams.tables = allowTables;
54
48
  }
55
- const filterClause = hasFilter ? " AND name IN {tables:Array(String)}" : "";
56
- const tables = await this.query(`SELECT name, engine, comment, total_rows, total_bytes, is_view, primary_key, sorting_key
49
+ const filterClause = hasFilter ? ' AND name IN {tables:Array(String)}' : '';
50
+ const tables = await this.executeQuery(`SELECT name, engine, comment, total_rows, total_bytes, is_view, primary_key, sorting_key
57
51
  FROM system.tables
58
52
  WHERE database = {db:String}${filterClause}
59
53
  ORDER BY name`, { params: queryParams });
60
- const columnFilterClause = hasFilter
61
- ? " AND table IN {tables:Array(String)}"
62
- : "";
63
- const columns = await this.query(`SELECT table, name, type, position, default_kind, default_expression, comment,
54
+ const columnFilterClause = hasFilter ? ' AND table IN {tables:Array(String)}' : '';
55
+ const columns = await this.executeQuery(`SELECT table, name, type, position, default_kind, default_expression, comment,
64
56
  codec_expression, ttl_expression, is_in_primary_key,
65
57
  data_compressed_bytes, data_uncompressed_bytes
66
58
  FROM system.columns
67
59
  WHERE database = {db:String}${columnFilterClause}
68
60
  ORDER BY table, position`, { params: queryParams });
69
61
  const columnsByTable = new Map();
70
- for (const rawColumn of columns) {
71
- const list = columnsByTable.get(rawColumn.table) ?? [];
72
- list.push(transformColumnRow(rawColumn));
73
- columnsByTable.set(rawColumn.table, list);
62
+ for (const col of columns) {
63
+ const list = columnsByTable.get(col.table) ?? [];
64
+ list.push(transformColumnRow(col));
65
+ columnsByTable.set(col.table, list);
74
66
  }
75
67
  const tableSchemas = tables.map((table) => {
76
68
  const tableColumns = columnsByTable.get(table.name) ?? [];
77
69
  const primaryKeyColumns = (0, clickhouse_js_1.parseKeyExpression)(table.primary_key);
78
70
  const totalRows = toNumber(table.total_rows);
79
71
  const totalBytes = toNumber(table.total_bytes);
80
- for (const column of tableColumns) {
81
- column.isPrimaryKey =
82
- column.isPrimaryKey || primaryKeyColumns.includes(column.name);
72
+ let statistics;
73
+ if (totalRows !== undefined || totalBytes !== undefined) {
74
+ const s = {};
75
+ if (totalRows !== undefined)
76
+ s.totalRows = totalRows;
77
+ if (totalBytes !== undefined)
78
+ s.totalBytes = totalBytes;
79
+ statistics = s;
83
80
  }
84
81
  const indexes = primaryKeyColumns.length
85
82
  ? [
86
83
  {
87
- name: "primary_key",
84
+ name: 'primary_key',
88
85
  columns: primaryKeyColumns,
89
86
  unique: true,
90
- type: "PRIMARY KEY",
87
+ type: 'PRIMARY KEY',
91
88
  ...(table.primary_key ? { definition: table.primary_key } : {}),
92
89
  },
93
90
  ]
@@ -95,12 +92,15 @@ class ClickHouseConnector {
95
92
  const constraints = primaryKeyColumns.length
96
93
  ? [
97
94
  {
98
- name: "primary_key",
99
- type: "PRIMARY KEY",
95
+ name: 'primary_key',
96
+ type: 'PRIMARY KEY',
100
97
  columns: primaryKeyColumns,
101
98
  },
102
99
  ]
103
100
  : [];
101
+ for (const column of tableColumns) {
102
+ column.isPrimaryKey = column.isPrimaryKey || primaryKeyColumns.includes(column.name);
103
+ }
104
104
  const base = {
105
105
  name: table.name,
106
106
  schema: this.config.database,
@@ -114,7 +114,6 @@ class ClickHouseConnector {
114
114
  if (comment !== undefined) {
115
115
  base.comment = comment;
116
116
  }
117
- const statistics = buildTableStatistics(totalRows, totalBytes);
118
117
  if (statistics) {
119
118
  base.statistics = statistics;
120
119
  }
@@ -122,7 +121,7 @@ class ClickHouseConnector {
122
121
  });
123
122
  return {
124
123
  db: {
125
- kind: "clickhouse",
124
+ kind: 'clickhouse',
126
125
  name: this.config.database,
127
126
  },
128
127
  tables: tableSchemas,
@@ -139,35 +138,23 @@ class ClickHouseConnector {
139
138
  if (this.client) {
140
139
  return this.client;
141
140
  }
142
- this.client =
143
- this.overrides?.clientFactory?.() ??
144
- (0, client_1.createClient)(this.buildClientConfig());
145
- const pingResult = await this.safePing(this.client);
146
- if (pingResult && "success" in pingResult && pingResult.success === false) {
147
- throw pingResult.error ?? new Error("ClickHouse ping failed");
141
+ this.client = this.overrides?.clientFactory?.() ?? (0, client_1.createClient)(this.buildClientConfig());
142
+ const pingResult = await this.client.ping();
143
+ if ('success' in pingResult && pingResult.success === false) {
144
+ throw pingResult.error ?? new Error('ClickHouse ping failed');
148
145
  }
149
146
  return this.client;
150
147
  }
151
- async safePing(client) {
152
- try {
153
- return await client.ping();
154
- }
155
- catch (error) {
156
- await client.close();
157
- this.client = null;
158
- throw error;
159
- }
160
- }
161
148
  buildClientConfig() {
162
149
  const merged = {
163
- ...(this.config.clientOptions ?? {}),
150
+ ...this.config.clientOptions,
164
151
  };
165
152
  if (this.config.url) {
166
153
  merged.url = this.config.url;
167
154
  }
168
155
  else if (this.config.host) {
169
- const protocol = this.config.protocol ?? "https";
170
- const port = this.config.port ?? (protocol === "https" ? 8443 : 8123);
156
+ const protocol = this.config.protocol ?? 'https';
157
+ const port = this.config.port ?? (protocol === 'https' ? 8443 : 8123);
171
158
  merged.url = `${protocol}://${this.config.host}:${port}`;
172
159
  }
173
160
  merged.database = this.config.database;
@@ -201,7 +188,7 @@ function normalizeTableFilter(tables) {
201
188
  const trimmed = table.trim();
202
189
  if (!trimmed)
203
190
  continue;
204
- const parts = trimmed.split(".");
191
+ const parts = trimmed.split('.');
205
192
  const tableName = parts[parts.length - 1];
206
193
  if (!tableName || seen.has(tableName))
207
194
  continue;
@@ -224,6 +211,7 @@ function transformColumnRow(row) {
224
211
  isPrimaryKey: Boolean(toNumber(row.is_in_primary_key)),
225
212
  isForeignKey: false,
226
213
  };
214
+ // Always safe to set defined optional string properties
227
215
  column.rawType = row.type;
228
216
  const defaultKind = sanitize(row.default_kind);
229
217
  if (defaultKind !== undefined)
@@ -258,9 +246,9 @@ function transformColumnRow(row) {
258
246
  function toNumber(value) {
259
247
  if (value === null || value === undefined)
260
248
  return undefined;
261
- if (typeof value === "number")
249
+ if (typeof value === 'number')
262
250
  return value;
263
- const parsed = Number.parseFloat(String(value));
251
+ const parsed = Number.parseFloat(value);
264
252
  return Number.isNaN(parsed) ? undefined : parsed;
265
253
  }
266
254
  function sanitize(value) {
@@ -270,23 +258,13 @@ function sanitize(value) {
270
258
  return trimmed.length ? trimmed : undefined;
271
259
  }
272
260
  function asTableType(isView) {
273
- if (typeof isView === "number") {
274
- return isView > 0 ? "view" : "table";
261
+ if (typeof isView === 'number') {
262
+ return isView > 0 ? 'view' : 'table';
275
263
  }
276
- if (typeof isView === "string") {
264
+ if (typeof isView === 'string') {
277
265
  const normalized = isView.toLowerCase();
278
- return normalized === "1" || normalized === "true" ? "view" : "table";
266
+ return normalized === '1' || normalized === 'true' ? 'view' : 'table';
279
267
  }
280
- return "table";
281
- }
282
- function buildTableStatistics(totalRows, totalBytes) {
283
- if (totalRows === undefined && totalBytes === undefined)
284
- return undefined;
285
- const stats = {};
286
- if (totalRows !== undefined)
287
- stats.totalRows = totalRows;
288
- if (totalBytes !== undefined)
289
- stats.totalBytes = totalBytes;
290
- return stats;
268
+ return 'table';
291
269
  }
292
270
  //# sourceMappingURL=clickhouse.js.map