@querypanel/node-sdk 1.0.23 → 1.0.25
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/README.md +46 -274
- package/dist/index.cjs +1471 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +468 -0
- package/dist/index.d.ts +468 -0
- package/dist/index.js +1443 -0
- package/dist/index.js.map +1 -0
- package/package.json +53 -43
- package/dist/cjs/adapters/clickhouse.d.ts +0 -48
- package/dist/cjs/adapters/clickhouse.d.ts.map +0 -1
- package/dist/cjs/adapters/clickhouse.js +0 -284
- package/dist/cjs/adapters/clickhouse.js.map +0 -1
- package/dist/cjs/adapters/introspection.spec.d.ts +0 -2
- package/dist/cjs/adapters/introspection.spec.d.ts.map +0 -1
- package/dist/cjs/adapters/introspection.spec.js +0 -192
- package/dist/cjs/adapters/introspection.spec.js.map +0 -1
- package/dist/cjs/adapters/postgres.d.ts +0 -46
- package/dist/cjs/adapters/postgres.d.ts.map +0 -1
- package/dist/cjs/adapters/postgres.js +0 -457
- package/dist/cjs/adapters/postgres.js.map +0 -1
- package/dist/cjs/adapters/postgres.spec.d.ts +0 -2
- package/dist/cjs/adapters/postgres.spec.d.ts.map +0 -1
- package/dist/cjs/adapters/postgres.spec.js +0 -37
- package/dist/cjs/adapters/postgres.spec.js.map +0 -1
- package/dist/cjs/adapters/types.d.ts +0 -38
- package/dist/cjs/adapters/types.d.ts.map +0 -1
- package/dist/cjs/adapters/types.js +0 -3
- package/dist/cjs/adapters/types.js.map +0 -1
- package/dist/cjs/anonymize.spec.d.ts +0 -2
- package/dist/cjs/anonymize.spec.d.ts.map +0 -1
- package/dist/cjs/anonymize.spec.js +0 -78
- package/dist/cjs/anonymize.spec.js.map +0 -1
- package/dist/cjs/clickhouseClient.spec.d.ts +0 -2
- package/dist/cjs/clickhouseClient.spec.d.ts.map +0 -1
- package/dist/cjs/clickhouseClient.spec.js +0 -286
- package/dist/cjs/clickhouseClient.spec.js.map +0 -1
- package/dist/cjs/connectors/base.d.ts +0 -14
- package/dist/cjs/connectors/base.d.ts.map +0 -1
- package/dist/cjs/connectors/base.js +0 -3
- package/dist/cjs/connectors/base.js.map +0 -1
- package/dist/cjs/connectors/clickhouse.d.ts +0 -35
- package/dist/cjs/connectors/clickhouse.d.ts.map +0 -1
- package/dist/cjs/connectors/clickhouse.js +0 -292
- package/dist/cjs/connectors/clickhouse.js.map +0 -1
- package/dist/cjs/index.d.ts +0 -498
- package/dist/cjs/index.d.ts.map +0 -1
- package/dist/cjs/index.js +0 -849
- package/dist/cjs/index.js.map +0 -1
- package/dist/cjs/index.test.d.ts +0 -2
- package/dist/cjs/index.test.d.ts.map +0 -1
- package/dist/cjs/index.test.js +0 -185
- package/dist/cjs/index.test.js.map +0 -1
- package/dist/cjs/introspectV3.d.ts +0 -45
- package/dist/cjs/introspectV3.d.ts.map +0 -1
- package/dist/cjs/introspectV3.js +0 -99
- package/dist/cjs/introspectV3.js.map +0 -1
- package/dist/cjs/multidb.spec.d.ts +0 -2
- package/dist/cjs/multidb.spec.d.ts.map +0 -1
- package/dist/cjs/multidb.spec.js +0 -76
- package/dist/cjs/multidb.spec.js.map +0 -1
- package/dist/cjs/package.json +0 -1
- package/dist/cjs/schema/types.d.ts +0 -73
- package/dist/cjs/schema/types.d.ts.map +0 -1
- package/dist/cjs/schema/types.js +0 -3
- package/dist/cjs/schema/types.js.map +0 -1
- package/dist/cjs/tenant-isolation.spec.d.ts +0 -2
- package/dist/cjs/tenant-isolation.spec.d.ts.map +0 -1
- package/dist/cjs/tenant-isolation.spec.js +0 -420
- package/dist/cjs/tenant-isolation.spec.js.map +0 -1
- package/dist/cjs/utils/clickhouse.d.ts +0 -9
- package/dist/cjs/utils/clickhouse.d.ts.map +0 -1
- package/dist/cjs/utils/clickhouse.js +0 -99
- package/dist/cjs/utils/clickhouse.js.map +0 -1
- package/dist/esm/adapters/clickhouse.d.ts +0 -48
- package/dist/esm/adapters/clickhouse.d.ts.map +0 -1
- package/dist/esm/adapters/clickhouse.js +0 -280
- package/dist/esm/adapters/clickhouse.js.map +0 -1
- package/dist/esm/adapters/introspection.spec.d.ts +0 -2
- package/dist/esm/adapters/introspection.spec.d.ts.map +0 -1
- package/dist/esm/adapters/introspection.spec.js +0 -190
- package/dist/esm/adapters/introspection.spec.js.map +0 -1
- package/dist/esm/adapters/postgres.d.ts +0 -46
- package/dist/esm/adapters/postgres.d.ts.map +0 -1
- package/dist/esm/adapters/postgres.js +0 -453
- package/dist/esm/adapters/postgres.js.map +0 -1
- package/dist/esm/adapters/postgres.spec.d.ts +0 -2
- package/dist/esm/adapters/postgres.spec.d.ts.map +0 -1
- package/dist/esm/adapters/postgres.spec.js +0 -35
- package/dist/esm/adapters/postgres.spec.js.map +0 -1
- package/dist/esm/adapters/types.d.ts +0 -38
- package/dist/esm/adapters/types.d.ts.map +0 -1
- package/dist/esm/adapters/types.js +0 -2
- package/dist/esm/adapters/types.js.map +0 -1
- package/dist/esm/anonymize.spec.d.ts +0 -2
- package/dist/esm/anonymize.spec.d.ts.map +0 -1
- package/dist/esm/anonymize.spec.js +0 -76
- package/dist/esm/anonymize.spec.js.map +0 -1
- package/dist/esm/clickhouseClient.spec.d.ts +0 -2
- package/dist/esm/clickhouseClient.spec.d.ts.map +0 -1
- package/dist/esm/clickhouseClient.spec.js +0 -281
- package/dist/esm/clickhouseClient.spec.js.map +0 -1
- package/dist/esm/connectors/base.d.ts +0 -14
- package/dist/esm/connectors/base.d.ts.map +0 -1
- package/dist/esm/connectors/base.js +0 -2
- package/dist/esm/connectors/base.js.map +0 -1
- package/dist/esm/connectors/clickhouse.d.ts +0 -35
- package/dist/esm/connectors/clickhouse.d.ts.map +0 -1
- package/dist/esm/connectors/clickhouse.js +0 -288
- package/dist/esm/connectors/clickhouse.js.map +0 -1
- package/dist/esm/index.d.ts +0 -498
- package/dist/esm/index.d.ts.map +0 -1
- package/dist/esm/index.js +0 -844
- package/dist/esm/index.js.map +0 -1
- package/dist/esm/index.test.d.ts +0 -2
- package/dist/esm/index.test.d.ts.map +0 -1
- package/dist/esm/index.test.js +0 -183
- package/dist/esm/index.test.js.map +0 -1
- package/dist/esm/introspectV3.d.ts +0 -45
- package/dist/esm/introspectV3.d.ts.map +0 -1
- package/dist/esm/introspectV3.js +0 -96
- package/dist/esm/introspectV3.js.map +0 -1
- package/dist/esm/multidb.spec.d.ts +0 -2
- package/dist/esm/multidb.spec.d.ts.map +0 -1
- package/dist/esm/multidb.spec.js +0 -74
- package/dist/esm/multidb.spec.js.map +0 -1
- package/dist/esm/schema/types.d.ts +0 -73
- package/dist/esm/schema/types.d.ts.map +0 -1
- package/dist/esm/schema/types.js +0 -2
- package/dist/esm/schema/types.js.map +0 -1
- package/dist/esm/tenant-isolation.spec.d.ts +0 -2
- package/dist/esm/tenant-isolation.spec.d.ts.map +0 -1
- package/dist/esm/tenant-isolation.spec.js +0 -418
- package/dist/esm/tenant-isolation.spec.js.map +0 -1
- package/dist/esm/utils/clickhouse.d.ts +0 -9
- package/dist/esm/utils/clickhouse.d.ts.map +0 -1
- package/dist/esm/utils/clickhouse.js +0 -92
- package/dist/esm/utils/clickhouse.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,323 +1,95 @@
|
|
|
1
1
|
# QueryPanel Node SDK
|
|
2
2
|
|
|
3
|
-
A
|
|
3
|
+
A TypeScript-first client for the QueryPanel Bun/Hono API. It signs JWTs with your service private key, syncs database schemas, enforces tenant isolation, and wraps every public route under `src/routes/` (query, ingest, charts, active charts, and knowledge base).
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
|
-
|
|
8
|
+
bun add @querypanel/sdk
|
|
9
|
+
# or
|
|
10
|
+
npm install @querypanel/sdk
|
|
9
11
|
```
|
|
10
12
|
|
|
11
|
-
|
|
12
|
-
- `@clickhouse/client` is a peer dependency for ClickHouse integrations.
|
|
13
|
+
> **Runtime:** Node.js 18+ (or Bun). The SDK relies on the native `fetch` API.
|
|
13
14
|
|
|
14
|
-
##
|
|
15
|
+
## Quickstart
|
|
15
16
|
|
|
16
17
|
```ts
|
|
17
|
-
import { QueryPanelSdkAPI } from "@querypanel/
|
|
18
|
-
import {
|
|
18
|
+
import { QueryPanelSdkAPI } from "@querypanel/sdk";
|
|
19
|
+
import { Pool } from "pg";
|
|
19
20
|
|
|
20
21
|
const qp = new QueryPanelSdkAPI(
|
|
21
22
|
process.env.QUERYPANEL_URL!,
|
|
22
|
-
process.env.
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
// Attach a ClickHouse database (use the SDK-supplied adapter)
|
|
26
|
-
const clickhouse = createClient({
|
|
27
|
-
url: process.env.CLICKHOUSE_URL!,
|
|
28
|
-
username: process.env.CLICKHOUSE_USER,
|
|
29
|
-
password: process.env.CLICKHOUSE_PASSWORD,
|
|
30
|
-
database: "analytics",
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
qp.attachClickhouse(
|
|
34
|
-
"analytics",
|
|
35
|
-
(params) => clickhouse.query(params),
|
|
23
|
+
process.env.PRIVATE_KEY!,
|
|
24
|
+
process.env.ORGANIZATION_ID!,
|
|
36
25
|
{
|
|
37
|
-
|
|
38
|
-
tenantFieldName: "customer_id", // Enable tenant isolation
|
|
39
|
-
tenantFieldType: "String", // ClickHouse type
|
|
26
|
+
defaultTenantId: process.env.DEFAULT_TENANT_ID,
|
|
40
27
|
},
|
|
41
28
|
);
|
|
42
29
|
|
|
43
|
-
|
|
44
|
-
const response = await qp.ask("Top countries by revenue", { tenantId: "tenant_123" });
|
|
45
|
-
console.log(response.sql); // Includes WHERE customer_id = {customer_id:String}
|
|
46
|
-
console.log(response.params); // { customer_id: "tenant_123", ... }
|
|
47
|
-
console.table(response.rows);
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
## Authentication modes
|
|
51
|
-
|
|
52
|
-
The constructor accepts either an already-signed JWT or a private key/organization pair for on-the-fly token generation:
|
|
53
|
-
|
|
54
|
-
```ts
|
|
55
|
-
// Mode 1: pass a pre-signed JWT for legacy integrations
|
|
56
|
-
const qpLegacy = new QueryPanelSdkAPI(baseUrl, signedJwt);
|
|
57
|
-
|
|
58
|
-
// Mode 2: provide an RSA private key and organization ID (recommended)
|
|
59
|
-
const qp = new QueryPanelSdkAPI(baseUrl, privateKeyPem, organizationId);
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
## V3 Bedrock Integration
|
|
63
|
-
|
|
64
|
-
The SDK provides methods to generate schema exports compatible with AWS Bedrock knowledge bases:
|
|
65
|
-
|
|
66
|
-
### introspectV3
|
|
67
|
-
|
|
68
|
-
Generate a simplified schema export format suitable for Bedrock ingestion:
|
|
69
|
-
|
|
70
|
-
```ts
|
|
71
|
-
const schema = await qp.introspectV3("analytics", {
|
|
72
|
-
tenantId: "tenant-123",
|
|
73
|
-
tables: ["orders", "customers"], // Optional: filter specific tables
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
// Output matches schema_export.json format
|
|
77
|
-
console.log(JSON.stringify(schema, null, 2));
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
### ingestSchemaV3
|
|
81
|
-
|
|
82
|
-
Introspect and ingest directly to Bedrock knowledge base:
|
|
30
|
+
const pool = new Pool({ connectionString: process.env.POSTGRES_URL });
|
|
83
31
|
|
|
84
|
-
|
|
85
|
-
const result = await qp.ingestSchemaV3("analytics", {
|
|
86
|
-
tenantId: "tenant-123",
|
|
87
|
-
tables: ["orders", "customers"], // Optional
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
console.log(`Ingested ${result.total_documents} documents`);
|
|
91
|
-
console.log(`Failed: ${result.failed.length}`);
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
The V3 format includes:
|
|
95
|
-
- Table overviews with column summaries and statistics
|
|
96
|
-
- Individual column metadata documents
|
|
97
|
-
- Foreign key relationships
|
|
98
|
-
- Primary key indicators
|
|
99
|
-
|
|
100
|
-
This data powers the Bedrock-backed `/v3/generate-sql` endpoint using Claude Haiku 4.5.
|
|
101
|
-
|
|
102
|
-
## Working with databases
|
|
103
|
-
|
|
104
|
-
Adapters mediate between the SDK and your data sources. Two helpers are bundled:
|
|
105
|
-
|
|
106
|
-
### ClickHouse
|
|
107
|
-
|
|
108
|
-
```ts
|
|
109
|
-
import {
|
|
110
|
-
ClickHouseAdapter,
|
|
111
|
-
type ClickHouseClientFn,
|
|
112
|
-
} from "@querypanel/node-sdk";
|
|
113
|
-
import { createClient } from "@clickhouse/client";
|
|
114
|
-
|
|
115
|
-
const clickhouseClient = createClient({ url: "https://ch.example.com", database: "analytics" });
|
|
116
|
-
const clickhouseFn: ClickHouseClientFn = (params) => clickhouseClient.query(params);
|
|
117
|
-
const clickhouseAdapter = new ClickHouseAdapter(clickhouseFn, { database: "analytics" });
|
|
118
|
-
|
|
119
|
-
// Optional introspection before attaching
|
|
120
|
-
const schema = await clickhouseAdapter.introspect();
|
|
121
|
-
console.log(schema.tables.map((t) => t.name));
|
|
122
|
-
|
|
123
|
-
qp.attachDatabase("analytics", clickhouseAdapter);
|
|
124
|
-
```
|
|
125
|
-
|
|
126
|
-
### Postgres
|
|
127
|
-
|
|
128
|
-
```ts
|
|
129
|
-
import { Pool } from "pg";
|
|
130
|
-
import {
|
|
131
|
-
PostgresAdapter,
|
|
132
|
-
type PostgresClientFn,
|
|
133
|
-
} from "@querypanel/node-sdk";
|
|
134
|
-
|
|
135
|
-
const pool = new Pool({ connectionString: process.env.DATABASE_URL });
|
|
136
|
-
const pgFn: PostgresClientFn = async (sql) => {
|
|
32
|
+
const createPostgresClient = () => async (sql: string, params?: unknown[]) => {
|
|
137
33
|
const client = await pool.connect();
|
|
138
34
|
try {
|
|
139
|
-
const result = await client.query(sql);
|
|
35
|
+
const result = await client.query(sql, params);
|
|
140
36
|
return {
|
|
141
37
|
rows: result.rows,
|
|
142
|
-
fields: result.fields.map((
|
|
38
|
+
fields: result.fields.map((field) => ({ name: field.name })),
|
|
143
39
|
};
|
|
144
40
|
} finally {
|
|
145
41
|
client.release();
|
|
146
42
|
}
|
|
147
43
|
};
|
|
148
44
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
45
|
+
qp.attachPostgres("analytics", createPostgresClient(), {
|
|
46
|
+
description: "Primary analytics warehouse",
|
|
47
|
+
tenantFieldName: "tenant_id",
|
|
152
48
|
});
|
|
153
49
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
## SDK helpers
|
|
165
|
-
|
|
166
|
-
Once at least one adapter is attached you can call:
|
|
167
|
-
|
|
168
|
-
- `ask(question, options)` – generate SQL, validate it, execute through the adapter, and retrieve a matching Vega-Lite chart spec.
|
|
169
|
-
- `train(payload, { tenantId, userId, scopes })` – submit curated glossary entries, metric docs, and gold SQL examples.
|
|
170
|
-
- `stats({ tenantId, userId, scopes })` – fetch ingestion statistics.
|
|
171
|
-
- Chart helpers: `listCharts`, `getChart`, `createChart`, `updateChart`, `deleteChart`, `listActiveCharts`, `getActiveChart`, `createActiveChart`, `updateActiveChart`, `deleteActiveChart`.
|
|
172
|
-
|
|
173
|
-
Every SDK call automatically attaches the correct authentication headers and forwards optional `tenantId`, `userId`, and `scopes` when provided.
|
|
174
|
-
|
|
175
|
-
### Using V3 SQL generation
|
|
50
|
+
qp.attachClickhouse(
|
|
51
|
+
"clicks",
|
|
52
|
+
(params) => clickhouse.query(params),
|
|
53
|
+
{
|
|
54
|
+
database: "analytics",
|
|
55
|
+
tenantFieldName: "customer_id",
|
|
56
|
+
tenantFieldType: "String",
|
|
57
|
+
},
|
|
58
|
+
);
|
|
176
59
|
|
|
177
|
-
|
|
60
|
+
await qp.syncSchema("analytics", { tenantId: "tenant_123" });
|
|
178
61
|
|
|
179
|
-
```ts
|
|
180
62
|
const response = await qp.ask("Top countries by revenue", {
|
|
181
63
|
tenantId: "tenant_123",
|
|
182
|
-
|
|
183
|
-
});
|
|
184
|
-
```
|
|
185
|
-
|
|
186
|
-
**Important**: The `useV3` flag controls both:
|
|
187
|
-
1. **SQL generation endpoint**: Uses `/v3/generate-sql` instead of `/v2/generate-sql`
|
|
188
|
-
2. **Schema introspection**: On first use, auto-syncs schema via `/v3/ingest` (Bedrock knowledge base) instead of `/v2/vectorize-schema` (pgvector)
|
|
189
|
-
|
|
190
|
-
Both endpoints support the same request/response format, making migration seamless.
|
|
191
|
-
|
|
192
|
-
### Manual sync control
|
|
193
|
-
|
|
194
|
-
By default, the SDK automatically syncs your database schema on the first `ask()` call. You can disable this and sync manually:
|
|
195
|
-
|
|
196
|
-
```ts
|
|
197
|
-
// Manual sync workflow
|
|
198
|
-
await qp.ingestSchemaV3("analytics", {
|
|
199
|
-
tenantId: "tenant_123",
|
|
200
|
-
tables: ["orders", "customers"], // Optional: sync specific tables
|
|
201
|
-
});
|
|
202
|
-
|
|
203
|
-
// Now ask questions with auto-sync disabled
|
|
204
|
-
const response = await qp.ask("Top revenue by country", {
|
|
205
|
-
tenantId: "tenant_123",
|
|
206
|
-
useV3: true,
|
|
207
|
-
disableAutoSync: true, // ⚠️ Requires manual sync first
|
|
208
|
-
});
|
|
209
|
-
```
|
|
210
|
-
|
|
211
|
-
**Why disable auto-sync?**
|
|
212
|
-
- 🎯 Control when schema updates happen
|
|
213
|
-
- ⚡ Faster `ask()` calls (no sync overhead)
|
|
214
|
-
- 💰 Reduce API calls to Bedrock
|
|
215
|
-
- 🔧 Better for production deployments (sync on app startup, not on every request)
|
|
216
|
-
|
|
217
|
-
**Recommended pattern for production:**
|
|
218
|
-
|
|
219
|
-
```ts
|
|
220
|
-
// On app startup (once)
|
|
221
|
-
await qp.ingestSchemaV3("analytics", { tenantId: "..." });
|
|
222
|
-
|
|
223
|
-
// In request handlers (many times)
|
|
224
|
-
app.post("/query", async (req, res) => {
|
|
225
|
-
const result = await qp.ask(req.body.question, {
|
|
226
|
-
tenantId: req.user.tenantId,
|
|
227
|
-
useV3: true,
|
|
228
|
-
disableAutoSync: true, // Already synced at startup
|
|
229
|
-
});
|
|
230
|
-
res.json(result);
|
|
231
|
-
});
|
|
232
|
-
```
|
|
233
|
-
|
|
234
|
-
## Multi-database support
|
|
235
|
-
|
|
236
|
-
The SDK keeps a registry of adapters. The first attached database becomes the default, but you can switch per request:
|
|
237
|
-
|
|
238
|
-
```ts
|
|
239
|
-
qp.attachPostgres("users", pgFn, { database: "users" });
|
|
240
|
-
qp.attachClickhouse("analytics", clickhouseFn);
|
|
241
|
-
|
|
242
|
-
await qp.ask("Top spenders", {
|
|
243
|
-
tenantId: "tenant_123",
|
|
244
|
-
database: "analytics", // override default database for this request
|
|
64
|
+
database: "analytics",
|
|
245
65
|
});
|
|
246
|
-
```
|
|
247
|
-
|
|
248
|
-
The `available_databases` array is forwarded to the `/v2/generate-sql` endpoint so the service can pick the right dialect when it suggests queries.
|
|
249
|
-
|
|
250
|
-
## Schema introspection
|
|
251
|
-
|
|
252
|
-
Both adapters can produce consistent metadata that matches `node-sdk/src/schema/types.ts`:
|
|
253
|
-
|
|
254
|
-
```ts
|
|
255
|
-
const snapshot = await pgAdapter.introspect({ tables: ["public.orders"] });
|
|
256
|
-
for (const table of snapshot.tables) {
|
|
257
|
-
console.log(table.name, table.columns.length);
|
|
258
|
-
}
|
|
259
|
-
```
|
|
260
66
|
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
Test V3 introspection locally without calling the API:
|
|
266
|
-
|
|
267
|
-
```bash
|
|
268
|
-
# Quick start
|
|
269
|
-
npm run introspect:local
|
|
270
|
-
|
|
271
|
-
# With custom database
|
|
272
|
-
CLICKHOUSE_URL=http://localhost:8123 \
|
|
273
|
-
CLICKHOUSE_DATABASE=analytics \
|
|
274
|
-
TENANT_ID=my-tenant \
|
|
275
|
-
npm run introspect:local
|
|
276
|
-
|
|
277
|
-
# Filter specific tables
|
|
278
|
-
TABLES="orders,customers" npm run introspect:local
|
|
67
|
+
console.log(response.sql);
|
|
68
|
+
console.log(response.params);
|
|
69
|
+
console.table(response.rows);
|
|
70
|
+
console.log(response.chart.vegaLiteSpec);
|
|
279
71
|
```
|
|
280
72
|
|
|
281
|
-
|
|
282
|
-
1. Review locally before ingestion
|
|
283
|
-
2. Upload manually via `/v3/ingest`
|
|
284
|
-
3. Use for testing and CI/CD
|
|
285
|
-
|
|
286
|
-
See `node-sdk/scripts/README.md` for full documentation.
|
|
287
|
-
|
|
288
|
-
## Testing and building
|
|
73
|
+
## Building locally
|
|
289
74
|
|
|
290
75
|
```bash
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
# build CommonJS and ESM artifacts
|
|
295
|
-
npm --prefix node-sdk run build
|
|
76
|
+
cd node-sdk
|
|
77
|
+
bun install
|
|
78
|
+
bun run build
|
|
296
79
|
```
|
|
297
80
|
|
|
298
|
-
|
|
81
|
+
This runs `tsup` which emits dual ESM/CJS bundles plus type declarations to `dist/`.
|
|
299
82
|
|
|
300
|
-
|
|
83
|
+
## Authentication model
|
|
301
84
|
|
|
302
|
-
|
|
303
|
-
- ✅ Validate that generated SQL includes tenant filters
|
|
304
|
-
- ✅ Auto-fix SQL missing tenant isolation by adding WHERE clauses
|
|
305
|
-
- ✅ Support ClickHouse typed parameters (`{customer_id:String}`)
|
|
306
|
-
|
|
307
|
-
```typescript
|
|
308
|
-
sdk.attachClickhouse('analytics', clickhouseFn, {
|
|
309
|
-
tenantFieldName: 'customer_id', // Required field in your schema
|
|
310
|
-
tenantFieldType: 'String', // ClickHouse type (String, UUID, Int64, etc.)
|
|
311
|
-
enforceTenantIsolation: true, // Default: true (auto-fix missing filters)
|
|
312
|
-
});
|
|
313
|
-
```
|
|
85
|
+
Every request is signed with `RS256` using the private key you pass to the constructor. The payload always includes `organizationId` and `tenantId`; `userId` and `scopes` are added when provided per call. If you still need service tokens or custom middleware, pass additional headers via the constructor.
|
|
314
86
|
|
|
315
|
-
|
|
87
|
+
## Error handling
|
|
316
88
|
|
|
317
|
-
|
|
89
|
+
- HTTP errors propagate as thrown `Error` instances that include `status` (and `details` when available).
|
|
90
|
+
- Schema ingestion failures are logged to `console.warn` during auto-sync, but you can call `syncSchema(..., { force: true })` to surface them directly.
|
|
91
|
+
- `ask()` raises immediately for guardrail/moderation errors because `/query` responds with 4xx/5xx.
|
|
318
92
|
|
|
319
|
-
|
|
320
|
-
- `SDK-API.md` – REST endpoint reference used by the SDK
|
|
321
|
-
- `MULTI_DATABASE.md` – Notes on attaching multiple adapters
|
|
93
|
+
## Need more?
|
|
322
94
|
|
|
323
|
-
|
|
95
|
+
Open an issue or extend `node-sdk/src/index.ts`—every route lives in one file. Pull requests are welcome for additional adapters, richer param coercion, or convenience helpers around charts/annotations.
|