@querypanel/node-sdk 1.0.7 → 1.0.9

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 (82) hide show
  1. package/README.md +174 -0
  2. package/dist/cjs/adapters/clickhouse.d.ts +36 -0
  3. package/dist/cjs/adapters/clickhouse.d.ts.map +1 -0
  4. package/dist/cjs/adapters/clickhouse.js +256 -0
  5. package/dist/cjs/adapters/clickhouse.js.map +1 -0
  6. package/dist/cjs/adapters/introspection.spec.d.ts +2 -0
  7. package/dist/cjs/adapters/introspection.spec.d.ts.map +1 -0
  8. package/dist/cjs/adapters/introspection.spec.js +201 -0
  9. package/dist/cjs/adapters/introspection.spec.js.map +1 -0
  10. package/dist/cjs/adapters/postgres.d.ts +29 -0
  11. package/dist/cjs/adapters/postgres.d.ts.map +1 -0
  12. package/dist/cjs/adapters/postgres.js +384 -0
  13. package/dist/cjs/adapters/postgres.js.map +1 -0
  14. package/dist/cjs/adapters/types.d.ts +34 -0
  15. package/dist/cjs/adapters/types.d.ts.map +1 -0
  16. package/dist/cjs/adapters/types.js +3 -0
  17. package/dist/cjs/adapters/types.js.map +1 -0
  18. package/dist/cjs/anonymize.spec.d.ts +2 -0
  19. package/dist/cjs/anonymize.spec.d.ts.map +1 -0
  20. package/dist/cjs/anonymize.spec.js +80 -0
  21. package/dist/cjs/anonymize.spec.js.map +1 -0
  22. package/dist/cjs/clickhouseClient.spec.d.ts +2 -0
  23. package/dist/cjs/clickhouseClient.spec.d.ts.map +1 -0
  24. package/dist/cjs/clickhouseClient.spec.js +286 -0
  25. package/dist/cjs/clickhouseClient.spec.js.map +1 -0
  26. package/dist/cjs/connectors/clickhouse.d.ts +4 -4
  27. package/dist/cjs/connectors/clickhouse.d.ts.map +1 -1
  28. package/dist/cjs/connectors/clickhouse.js +30 -23
  29. package/dist/cjs/connectors/clickhouse.js.map +1 -1
  30. package/dist/cjs/index.d.ts +69 -5
  31. package/dist/cjs/index.d.ts.map +1 -1
  32. package/dist/cjs/index.js +257 -50
  33. package/dist/cjs/index.js.map +1 -1
  34. package/dist/cjs/index.test.d.ts +2 -0
  35. package/dist/cjs/index.test.d.ts.map +1 -0
  36. package/dist/cjs/index.test.js +112 -0
  37. package/dist/cjs/index.test.js.map +1 -0
  38. package/dist/cjs/multidb.spec.d.ts +2 -0
  39. package/dist/cjs/multidb.spec.d.ts.map +1 -0
  40. package/dist/cjs/multidb.spec.js +76 -0
  41. package/dist/cjs/multidb.spec.js.map +1 -0
  42. package/dist/esm/adapters/clickhouse.d.ts +36 -0
  43. package/dist/esm/adapters/clickhouse.d.ts.map +1 -0
  44. package/dist/esm/adapters/clickhouse.js +252 -0
  45. package/dist/esm/adapters/clickhouse.js.map +1 -0
  46. package/dist/esm/adapters/introspection.spec.d.ts +2 -0
  47. package/dist/esm/adapters/introspection.spec.d.ts.map +1 -0
  48. package/dist/esm/adapters/introspection.spec.js +199 -0
  49. package/dist/esm/adapters/introspection.spec.js.map +1 -0
  50. package/dist/esm/adapters/postgres.d.ts +29 -0
  51. package/dist/esm/adapters/postgres.d.ts.map +1 -0
  52. package/dist/esm/adapters/postgres.js +380 -0
  53. package/dist/esm/adapters/postgres.js.map +1 -0
  54. package/dist/esm/adapters/types.d.ts +34 -0
  55. package/dist/esm/adapters/types.d.ts.map +1 -0
  56. package/dist/esm/adapters/types.js +2 -0
  57. package/dist/esm/adapters/types.js.map +1 -0
  58. package/dist/esm/anonymize.spec.d.ts +2 -0
  59. package/dist/esm/anonymize.spec.d.ts.map +1 -0
  60. package/dist/esm/anonymize.spec.js +78 -0
  61. package/dist/esm/anonymize.spec.js.map +1 -0
  62. package/dist/esm/clickhouseClient.spec.d.ts +2 -0
  63. package/dist/esm/clickhouseClient.spec.d.ts.map +1 -0
  64. package/dist/esm/clickhouseClient.spec.js +281 -0
  65. package/dist/esm/clickhouseClient.spec.js.map +1 -0
  66. package/dist/esm/connectors/clickhouse.d.ts +4 -4
  67. package/dist/esm/connectors/clickhouse.d.ts.map +1 -1
  68. package/dist/esm/connectors/clickhouse.js +32 -25
  69. package/dist/esm/connectors/clickhouse.js.map +1 -1
  70. package/dist/esm/index.d.ts +69 -5
  71. package/dist/esm/index.d.ts.map +1 -1
  72. package/dist/esm/index.js +256 -50
  73. package/dist/esm/index.js.map +1 -1
  74. package/dist/esm/index.test.d.ts +2 -0
  75. package/dist/esm/index.test.d.ts.map +1 -0
  76. package/dist/esm/index.test.js +110 -0
  77. package/dist/esm/index.test.js.map +1 -0
  78. package/dist/esm/multidb.spec.d.ts +2 -0
  79. package/dist/esm/multidb.spec.d.ts.map +1 -0
  80. package/dist/esm/multidb.spec.js +74 -0
  81. package/dist/esm/multidb.spec.js.map +1 -0
  82. package/package.json +5 -2
@@ -0,0 +1,34 @@
1
+ import type { IntrospectOptions, SchemaIntrospection } from "../schema/types.js";
2
+ export type DatabaseDialect = "clickhouse" | "postgres" | "mysql";
3
+ export interface DatabaseExecutionResult {
4
+ fields: string[];
5
+ rows: Array<Record<string, unknown>>;
6
+ }
7
+ /**
8
+ * Database adapter interface for abstracting database-specific operations.
9
+ * Allows the SDK to work with multiple database types.
10
+ */
11
+ export interface DatabaseAdapter {
12
+ /**
13
+ * Execute a SQL query and return results
14
+ */
15
+ execute(sql: string): Promise<DatabaseExecutionResult>;
16
+ /**
17
+ * Validate SQL query (e.g., using EXPLAIN)
18
+ * Throws an error if the SQL is invalid
19
+ */
20
+ validate(sql: string): Promise<void>;
21
+ /**
22
+ * Introspect database schema metadata
23
+ */
24
+ introspect(options?: IntrospectOptions): Promise<SchemaIntrospection>;
25
+ /**
26
+ * Get the database dialect/type
27
+ */
28
+ getDialect(): DatabaseDialect;
29
+ /**
30
+ * Optional: Close/cleanup database connection
31
+ */
32
+ close?(): Promise<void>;
33
+ }
34
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/adapters/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,iBAAiB,EACjB,mBAAmB,EACpB,MAAM,oBAAoB,CAAC;AAE5B,MAAM,MAAM,eAAe,GAAG,YAAY,GAAG,UAAU,GAAG,OAAO,CAAC;AAElE,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CACtC;AAED;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B;;OAEG;IACH,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,uBAAuB,CAAC,CAAC;IAEvD;;;OAGG;IACH,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAErC;;OAEG;IACH,UAAU,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAC;IAEtE;;OAEG;IACH,UAAU,IAAI,eAAe,CAAC;IAE9B;;OAEG;IACH,KAAK,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACzB"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/adapters/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=anonymize.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anonymize.spec.d.ts","sourceRoot":"","sources":["../../src/anonymize.spec.ts"],"names":[],"mappings":""}
@@ -0,0 +1,78 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { anonymizeResults } from "./index.js";
3
+ describe("anonymizeResults", () => {
4
+ it("anonymizes numeric values", () => {
5
+ const input = [
6
+ { year: 2025, transactionSum: 1000 },
7
+ { year: 2024, transactionSum: 2000 },
8
+ ];
9
+ const result = anonymizeResults(input);
10
+ expect(result).toEqual([
11
+ { year: "number", transactionSum: "number" },
12
+ { year: "number", transactionSum: "number" },
13
+ ]);
14
+ });
15
+ it("anonymizes mixed types", () => {
16
+ const input = [
17
+ {
18
+ id: 1,
19
+ name: "John Doe",
20
+ active: true,
21
+ score: 95.5,
22
+ metadata: null,
23
+ tags: ["admin", "user"],
24
+ },
25
+ ];
26
+ const result = anonymizeResults(input);
27
+ expect(result).toEqual([
28
+ {
29
+ id: "number",
30
+ name: "string",
31
+ active: "boolean",
32
+ score: "number",
33
+ metadata: "null",
34
+ tags: "array",
35
+ },
36
+ ]);
37
+ });
38
+ it("handles empty arrays", () => {
39
+ const result = anonymizeResults([]);
40
+ expect(result).toEqual([]);
41
+ });
42
+ it("handles objects with nested structures", () => {
43
+ const input = [
44
+ {
45
+ user: { name: "Alice" },
46
+ count: 42,
47
+ },
48
+ ];
49
+ const result = anonymizeResults(input);
50
+ expect(result).toEqual([
51
+ {
52
+ user: "object",
53
+ count: "number",
54
+ },
55
+ ]);
56
+ });
57
+ it("preserves column structure across multiple rows", () => {
58
+ const input = [
59
+ { col1: "value1", col2: 100, col3: true },
60
+ { col1: "value2", col2: 200, col3: false },
61
+ { col1: "value3", col2: 300, col3: true },
62
+ ];
63
+ const result = anonymizeResults(input);
64
+ expect(result).toEqual([
65
+ { col1: "string", col2: "number", col3: "boolean" },
66
+ { col1: "string", col2: "number", col3: "boolean" },
67
+ { col1: "string", col2: "number", col3: "boolean" },
68
+ ]);
69
+ });
70
+ it("handles undefined values", () => {
71
+ const input = [{ defined: 123, undefined: undefined }];
72
+ const result = anonymizeResults(input);
73
+ expect(result).toEqual([
74
+ { defined: "number", undefined: "undefined" },
75
+ ]);
76
+ });
77
+ });
78
+ //# sourceMappingURL=anonymize.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anonymize.spec.js","sourceRoot":"","sources":["../../src/anonymize.spec.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=clickhouseClient.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clickhouseClient.spec.d.ts","sourceRoot":"","sources":["../../src/clickhouseClient.spec.ts"],"names":[],"mappings":""}
@@ -0,0 +1,281 @@
1
+ import duckdb from "duckdb";
2
+ import { afterAll, beforeAll, describe, expect, it } from "vitest";
3
+ import { QueryPanelSdkAPI } from "./index.js";
4
+ // @ts-expect-error
5
+ globalThis.fetch = async (input, _init) => {
6
+ const url = String(input);
7
+ if (url.endsWith("/v2/active-charts")) {
8
+ return {
9
+ ok: true,
10
+ status: 200,
11
+ text: async () => JSON.stringify({
12
+ data: [
13
+ {
14
+ id: "ac1",
15
+ chart_id: "1",
16
+ order: 1,
17
+ meta: null,
18
+ organization_id: null,
19
+ tenant_id: null,
20
+ user_id: null,
21
+ created_at: null,
22
+ updated_at: null,
23
+ },
24
+ ],
25
+ pagination: {
26
+ page: 1,
27
+ limit: 10,
28
+ total: 1,
29
+ totalPages: 1,
30
+ hasNext: false,
31
+ hasPrev: false,
32
+ },
33
+ }),
34
+ };
35
+ }
36
+ if (/\/v2\/charts\/[^/]+$/.test(url)) {
37
+ return {
38
+ ok: true,
39
+ status: 200,
40
+ text: async () => JSON.stringify({
41
+ id: "1",
42
+ title: "Single",
43
+ description: null,
44
+ sql: "SELECT id, value FROM demo ORDER BY id",
45
+ vega_lite_spec: { mark: "point" },
46
+ query_id: null,
47
+ organization_id: null,
48
+ tenant_id: null,
49
+ user_id: null,
50
+ created_at: null,
51
+ updated_at: null,
52
+ }),
53
+ };
54
+ }
55
+ if (url.endsWith("/v2/charts")) {
56
+ return {
57
+ ok: true,
58
+ status: 200,
59
+ text: async () => JSON.stringify({
60
+ data: [
61
+ {
62
+ id: "1",
63
+ title: "Demo",
64
+ description: null,
65
+ sql: "SELECT id, value FROM demo ORDER BY id",
66
+ vega_lite_spec: { mark: "bar" },
67
+ query_id: null,
68
+ organization_id: null,
69
+ tenant_id: null,
70
+ user_id: null,
71
+ created_at: null,
72
+ updated_at: null,
73
+ },
74
+ ],
75
+ pagination: {
76
+ page: 1,
77
+ limit: 10,
78
+ total: 1,
79
+ totalPages: 1,
80
+ hasNext: false,
81
+ hasPrev: false,
82
+ },
83
+ }),
84
+ };
85
+ }
86
+ if (url.endsWith("/v2/generate-sql")) {
87
+ return {
88
+ ok: true,
89
+ status: 200,
90
+ text: async () => JSON.stringify({
91
+ sql: "SELECT id as x, value as y FROM demo ORDER BY id",
92
+ rationale: "ok",
93
+ context: [],
94
+ }),
95
+ };
96
+ }
97
+ if (url.endsWith("/v2/generate-chart")) {
98
+ return {
99
+ ok: true,
100
+ status: 200,
101
+ text: async () => JSON.stringify({ vegaLiteSpec: { mark: "line" }, notes: null }),
102
+ };
103
+ }
104
+ if (/\/v2\/active-charts\/[^/]+$/.test(url)) {
105
+ const id = url.split("/").pop();
106
+ if (id === "ac1") {
107
+ return {
108
+ ok: true,
109
+ status: 200,
110
+ text: async () => JSON.stringify({
111
+ id: "ac1",
112
+ chart_id: "1",
113
+ order: 1,
114
+ meta: null,
115
+ organization_id: null,
116
+ tenant_id: null,
117
+ user_id: null,
118
+ created_at: null,
119
+ updated_at: null,
120
+ }),
121
+ };
122
+ }
123
+ if (id === "ac2") {
124
+ return {
125
+ ok: true,
126
+ status: 200,
127
+ text: async () => JSON.stringify({
128
+ id: "ac2",
129
+ chart_id: "1",
130
+ order: 1,
131
+ meta: null,
132
+ organization_id: null,
133
+ tenant_id: null,
134
+ user_id: null,
135
+ created_at: null,
136
+ updated_at: null,
137
+ chart: {
138
+ id: "1",
139
+ title: "Nested",
140
+ description: null,
141
+ sql: "SELECT id, value FROM demo ORDER BY id",
142
+ vega_lite_spec: { mark: "square" },
143
+ query_id: null,
144
+ organization_id: null,
145
+ tenant_id: null,
146
+ user_id: null,
147
+ created_at: null,
148
+ updated_at: null,
149
+ },
150
+ }),
151
+ };
152
+ }
153
+ }
154
+ // other endpoints not used in this test
155
+ return { ok: false, status: 404, text: async () => "" };
156
+ };
157
+ // Helper to create an in-memory DuckDB connection and run queries
158
+ function createDuckDb() {
159
+ const db = new duckdb.Database(":memory:");
160
+ const conn = db.connect();
161
+ return { db, conn };
162
+ }
163
+ describe("attachClickhouseClient", () => {
164
+ let conn;
165
+ let clickhouseClientFn;
166
+ beforeAll(async () => {
167
+ ({ conn } = createDuckDb());
168
+ clickhouseClientFn = async ({ query }) => {
169
+ const rows = await new Promise((resolve, reject) => {
170
+ conn.all(query, (err, result) => {
171
+ if (err)
172
+ return reject(err);
173
+ resolve(result);
174
+ });
175
+ });
176
+ const result = {
177
+ json: async () => rows,
178
+ };
179
+ return result;
180
+ };
181
+ await new Promise((resolve, reject) => {
182
+ conn.run("CREATE TABLE demo(id INTEGER, value VARCHAR)", (err) => {
183
+ if (err)
184
+ return reject(err);
185
+ conn.run("INSERT INTO demo VALUES (1, 'a'), (2, 'b')", (err2) => {
186
+ if (err2)
187
+ return reject(err2);
188
+ resolve();
189
+ });
190
+ });
191
+ });
192
+ });
193
+ afterAll(() => {
194
+ try {
195
+ conn.close();
196
+ }
197
+ catch { }
198
+ });
199
+ it("returns values from runDataOnCLient when listing charts", async () => {
200
+ const sdk = new QueryPanelSdkAPI("http://api", "test-token");
201
+ sdk.attachClickhouseClient(clickhouseClientFn);
202
+ const result = await sdk.listCharts({ tenantId: "t1" });
203
+ expect(result.data.length).toBe(1);
204
+ const chart = result.data[0];
205
+ expect(chart.vega_lite_spec?.data?.values).toEqual([
206
+ { id: 1, value: "a" },
207
+ { id: 2, value: "b" },
208
+ ]);
209
+ });
210
+ it("hydrates data when getting a single chart", async () => {
211
+ const sdk = new QueryPanelSdkAPI("http://api", "test-token");
212
+ sdk.attachClickhouseClient(clickhouseClientFn);
213
+ const chart = await sdk.getChart("1", { tenantId: "t1" });
214
+ expect(chart.id).toBe("1");
215
+ expect(chart.vega_lite_spec?.data?.values).toEqual([
216
+ { id: 1, value: "a" },
217
+ { id: 2, value: "b" },
218
+ ]);
219
+ });
220
+ it("lists active charts without data when withdata=false", async () => {
221
+ const sdk = new QueryPanelSdkAPI("http://api", "test-token");
222
+ sdk.attachClickhouseClient(clickhouseClientFn);
223
+ const result = await sdk.listActiveCharts({
224
+ tenantId: "t1",
225
+ withdata: false,
226
+ });
227
+ expect(result.data.length).toBe(1);
228
+ const firstNoData = result.data[0];
229
+ if (!firstNoData)
230
+ throw new Error("missing active chart");
231
+ expect(firstNoData.chart).toBeUndefined();
232
+ });
233
+ it("lists active charts with data when withdata=true", async () => {
234
+ const sdk = new QueryPanelSdkAPI("http://api", "test-token");
235
+ sdk.attachClickhouseClient(clickhouseClientFn);
236
+ const result = await sdk.listActiveCharts({
237
+ tenantId: "t1",
238
+ withdata: true,
239
+ });
240
+ expect(result.data.length).toBe(1);
241
+ const firstWithData = result.data[0];
242
+ if (!firstWithData || !firstWithData.chart)
243
+ throw new Error("missing hydrated active chart");
244
+ expect(Boolean(firstWithData.chart)).toBe(true);
245
+ expect(firstWithData.chart.vega_lite_spec?.data?.values).toEqual([
246
+ { id: 1, value: "a" },
247
+ { id: 2, value: "b" },
248
+ ]);
249
+ });
250
+ it("gets active chart without nested chart unchanged", async () => {
251
+ const sdk = new QueryPanelSdkAPI("http://api", "test-token");
252
+ sdk.attachClickhouseClient(clickhouseClientFn);
253
+ const ac = await sdk.getActiveChart("ac1", { tenantId: "t1" });
254
+ expect(ac.id).toBe("ac1");
255
+ expect("chart" in ac ? ac.chart : undefined).toBeUndefined();
256
+ });
257
+ it("gets active chart with nested chart hydrated", async () => {
258
+ const sdk = new QueryPanelSdkAPI("http://api", "test-token");
259
+ sdk.attachClickhouseClient(clickhouseClientFn);
260
+ const ac = await sdk.getActiveChart("ac2", { tenantId: "t1" });
261
+ if (!ac.chart)
262
+ throw new Error("expected nested chart");
263
+ expect(ac.chart.vega_lite_spec?.data?.values).toEqual([
264
+ { id: 1, value: "a" },
265
+ { id: 2, value: "b" },
266
+ ]);
267
+ });
268
+ it("works with ask() by executing SQL against DuckDB", async () => {
269
+ const sdk = new QueryPanelSdkAPI("http://api", "test-token");
270
+ sdk.attachClickhouseClient(clickhouseClientFn);
271
+ const result = await sdk.ask("q", { tenantId: "t1" });
272
+ expect(result.sql).toContain("SELECT id as x, value as y");
273
+ expect(result.fields).toEqual(["x", "y"]);
274
+ expect(result.rows).toEqual([
275
+ { x: 1, y: "a" },
276
+ { x: 2, y: "b" },
277
+ ]);
278
+ expect(result.chart.vegaLiteSpec).toMatchObject({ mark: "line" });
279
+ });
280
+ });
281
+ //# sourceMappingURL=clickhouseClient.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clickhouseClient.spec.js","sourceRoot":"","sources":["../../src/clickhouseClient.spec.ts"],"names":[],"mappings":"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"}
@@ -1,12 +1,12 @@
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 ClickHouseClient, type ClickHouseClientConfigOptions } from "@clickhouse/client";
2
+ import type { IntrospectOptions, SchemaIntrospection } from "../schema/types.js";
3
+ import type { DatabaseConnector, QueryOptions } from "./base.js";
4
4
  export interface ClickHouseConnectorConfig {
5
5
  /** Fully qualified ClickHouse URL. Overrides host/port/protocol when provided. */
6
6
  url?: string;
7
7
  host?: string;
8
8
  port?: number;
9
- protocol?: 'http' | 'https';
9
+ protocol?: "http" | "https";
10
10
  database: string;
11
11
  username?: string;
12
12
  password?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"clickhouse.d.ts","sourceRoot":"","sources":["../../../src/connectors/clickhouse.ts"],"names":[],"mappings":"AAAA,OAAO,EAEH,KAAK,gBAAgB,EACrB,KAAK,6BAA6B,EAGrC,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,iBAAiB,EAAE,mBAAmB,EAA6B,MAAM,oBAAoB,CAAC;AAQ5G,OAAO,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAEjE,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,gBAAgB,CAAC;IAC1B,aAAa,CAAC,EAAE,MAAM,gBAAgB,CAAC;CAC1C;AA4BD,qBAAa,mBAAoB,YAAW,iBAAiB;IAKrD,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAL9B,OAAO,CAAC,MAAM,CAA0B;IACxC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAqE;gBAG9E,MAAM,EAAE,yBAAyB,EACjC,SAAS,GAAE,4BAAiC;IAK3D,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAIxB,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;IAiCrF,UAAU,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAsGrE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;YAMd,YAAY;YAYZ,QAAQ;IAUtB,OAAO,CAAC,iBAAiB;CAkC5B"}
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,10 +1,10 @@
1
- import { createClient, } from '@clickhouse/client';
2
- import { extractFixedStringLength, extractPrecisionScale, isNullableType, parseKeyExpression, unwrapTypeModifiers, } from '../utils/clickhouse.js';
1
+ import { createClient, } from "@clickhouse/client";
2
+ import { extractFixedStringLength, extractPrecisionScale, isNullableType, parseKeyExpression, unwrapTypeModifiers, } from "../utils/clickhouse.js";
3
3
  export class ClickHouseConnector {
4
4
  constructor(config, overrides = {}) {
5
5
  this.config = config;
6
6
  this.overrides = overrides;
7
- this.defaultFormat = 'JSONEachRow';
7
+ this.defaultFormat = "JSONEachRow";
8
8
  this.client = overrides.client ?? null;
9
9
  }
10
10
  async connect() {
@@ -23,14 +23,16 @@ export class ClickHouseConnector {
23
23
  Object.assign(params, { query_params: options.params });
24
24
  }
25
25
  if (options?.settings) {
26
- Object.assign(params, { clickhouse_settings: options.settings });
26
+ Object.assign(params, {
27
+ clickhouse_settings: options.settings,
28
+ });
27
29
  }
28
30
  const result = await client.query(params);
29
31
  const payload = await result.json();
30
32
  if (Array.isArray(payload)) {
31
33
  return payload;
32
34
  }
33
- if (payload && typeof payload === 'object') {
35
+ if (payload && typeof payload === "object") {
34
36
  const maybeData = payload.data;
35
37
  if (Array.isArray(maybeData)) {
36
38
  return maybeData;
@@ -47,12 +49,14 @@ export class ClickHouseConnector {
47
49
  if (hasFilter) {
48
50
  queryParams.tables = allowTables;
49
51
  }
50
- const filterClause = hasFilter ? ' AND name IN {tables:Array(String)}' : '';
52
+ const filterClause = hasFilter ? " AND name IN {tables:Array(String)}" : "";
51
53
  const tables = await this.query(`SELECT name, engine, comment, total_rows, total_bytes, is_view, primary_key, sorting_key
52
54
  FROM system.tables
53
55
  WHERE database = {db:String}${filterClause}
54
56
  ORDER BY name`, { params: queryParams });
55
- const columnFilterClause = hasFilter ? ' AND table IN {tables:Array(String)}' : '';
57
+ const columnFilterClause = hasFilter
58
+ ? " AND table IN {tables:Array(String)}"
59
+ : "";
56
60
  const columns = await this.query(`SELECT table, name, type, position, default_kind, default_expression, comment,
57
61
  codec_expression, ttl_expression, is_in_primary_key,
58
62
  data_compressed_bytes, data_uncompressed_bytes
@@ -71,15 +75,16 @@ export class ClickHouseConnector {
71
75
  const totalRows = toNumber(table.total_rows);
72
76
  const totalBytes = toNumber(table.total_bytes);
73
77
  for (const column of tableColumns) {
74
- column.isPrimaryKey = column.isPrimaryKey || primaryKeyColumns.includes(column.name);
78
+ column.isPrimaryKey =
79
+ column.isPrimaryKey || primaryKeyColumns.includes(column.name);
75
80
  }
76
81
  const indexes = primaryKeyColumns.length
77
82
  ? [
78
83
  {
79
- name: 'primary_key',
84
+ name: "primary_key",
80
85
  columns: primaryKeyColumns,
81
86
  unique: true,
82
- type: 'PRIMARY KEY',
87
+ type: "PRIMARY KEY",
83
88
  ...(table.primary_key ? { definition: table.primary_key } : {}),
84
89
  },
85
90
  ]
@@ -87,8 +92,8 @@ export class ClickHouseConnector {
87
92
  const constraints = primaryKeyColumns.length
88
93
  ? [
89
94
  {
90
- name: 'primary_key',
91
- type: 'PRIMARY KEY',
95
+ name: "primary_key",
96
+ type: "PRIMARY KEY",
92
97
  columns: primaryKeyColumns,
93
98
  },
94
99
  ]
@@ -114,7 +119,7 @@ export class ClickHouseConnector {
114
119
  });
115
120
  return {
116
121
  db: {
117
- kind: 'clickhouse',
122
+ kind: "clickhouse",
118
123
  name: this.config.database,
119
124
  },
120
125
  tables: tableSchemas,
@@ -131,10 +136,12 @@ export class ClickHouseConnector {
131
136
  if (this.client) {
132
137
  return this.client;
133
138
  }
134
- this.client = this.overrides?.clientFactory?.() ?? createClient(this.buildClientConfig());
139
+ this.client =
140
+ this.overrides?.clientFactory?.() ??
141
+ createClient(this.buildClientConfig());
135
142
  const pingResult = await this.safePing(this.client);
136
- if (pingResult && 'success' in pingResult && pingResult.success === false) {
137
- throw pingResult.error ?? new Error('ClickHouse ping failed');
143
+ if (pingResult && "success" in pingResult && pingResult.success === false) {
144
+ throw pingResult.error ?? new Error("ClickHouse ping failed");
138
145
  }
139
146
  return this.client;
140
147
  }
@@ -156,8 +163,8 @@ export class ClickHouseConnector {
156
163
  merged.url = this.config.url;
157
164
  }
158
165
  else if (this.config.host) {
159
- const protocol = this.config.protocol ?? 'https';
160
- const port = this.config.port ?? (protocol === 'https' ? 8443 : 8123);
166
+ const protocol = this.config.protocol ?? "https";
167
+ const port = this.config.port ?? (protocol === "https" ? 8443 : 8123);
161
168
  merged.url = `${protocol}://${this.config.host}:${port}`;
162
169
  }
163
170
  merged.database = this.config.database;
@@ -190,7 +197,7 @@ function normalizeTableFilter(tables) {
190
197
  const trimmed = table.trim();
191
198
  if (!trimmed)
192
199
  continue;
193
- const parts = trimmed.split('.');
200
+ const parts = trimmed.split(".");
194
201
  const tableName = parts[parts.length - 1];
195
202
  if (!tableName || seen.has(tableName))
196
203
  continue;
@@ -247,7 +254,7 @@ function transformColumnRow(row) {
247
254
  function toNumber(value) {
248
255
  if (value === null || value === undefined)
249
256
  return undefined;
250
- if (typeof value === 'number')
257
+ if (typeof value === "number")
251
258
  return value;
252
259
  const parsed = Number.parseFloat(String(value));
253
260
  return Number.isNaN(parsed) ? undefined : parsed;
@@ -259,14 +266,14 @@ function sanitize(value) {
259
266
  return trimmed.length ? trimmed : undefined;
260
267
  }
261
268
  function asTableType(isView) {
262
- if (typeof isView === 'number') {
263
- return isView > 0 ? 'view' : 'table';
269
+ if (typeof isView === "number") {
270
+ return isView > 0 ? "view" : "table";
264
271
  }
265
- if (typeof isView === 'string') {
272
+ if (typeof isView === "string") {
266
273
  const normalized = isView.toLowerCase();
267
- return normalized === '1' || normalized === 'true' ? 'view' : 'table';
274
+ return normalized === "1" || normalized === "true" ? "view" : "table";
268
275
  }
269
- return 'table';
276
+ return "table";
270
277
  }
271
278
  function buildTableStatistics(totalRows, totalBytes) {
272
279
  if (totalRows === undefined && totalBytes === undefined)