@querypanel/node-sdk 1.3.3 → 1.3.6
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 +71 -19
- package/dist/index.cjs +574 -15
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +180 -5
- package/dist/index.d.ts +180 -5
- package/dist/index.js +573 -15
- package/dist/index.js.map +1 -1
- package/package.json +16 -3
package/README.md
CHANGED
|
@@ -1,13 +1,28 @@
|
|
|
1
1
|
# QueryPanel Node SDK
|
|
2
2
|
|
|
3
|
+
`@querypanel/node-sdk` is the headless, server-side SDK for [QueryPanel](https://querypanel.io) embedded analytics. Use it in your Node.js (18+), Bun, or Deno backend to mint RS256 tenant JWTs, sync your Postgres, Amazon Redshift, ClickHouse, or BigQuery schema, and turn natural-language questions into SQL (natural-language-to-SQL / text-to-SQL) for multi-tenant SaaS products. The generated SQL runs against your database through a client function you provide, so database credentials and query results stay on your servers. For chart generation the SDK sends column names and value types, not row values (see `anonymizeResults`).
|
|
4
|
+
|
|
5
|
+
- Docs: [querypanel.io/docs/node-sdk](https://querypanel.io/docs/node-sdk)
|
|
6
|
+
- Tenant isolation: [querypanel.io/docs/tenant-isolation](https://querypanel.io/docs/tenant-isolation)
|
|
7
|
+
- JWT setup: [querypanel.io/docs/jwt](https://querypanel.io/docs/jwt)
|
|
8
|
+
|
|
9
|
+
## When to use the Node SDK vs the React SDK
|
|
10
|
+
|
|
11
|
+
- **[React SDK](https://www.npmjs.com/package/@querypanel/react-sdk) (headful, start here for React apps):** `@querypanel/react-sdk` renders customer-facing dashboards with an AI assistant and per-tenant customization directly in your React tree, not an iframe ([why that matters](https://querypanel.io/blog/iframe-vs-native-react-embedded-analytics-2026)). It still needs this package on your server to mint the tenant JWT (`createJwt`).
|
|
12
|
+
- **Node SDK (this package, headless):** use it alone when you build your own UI and want `ask()` to return SQL, rows, and a chart spec from your API routes.
|
|
13
|
+
|
|
14
|
+
How it compares to other embedded analytics tools: [querypanel.io/compare](https://querypanel.io/compare).
|
|
15
|
+
|
|
16
|
+
## Overview
|
|
17
|
+
|
|
3
18
|
A TypeScript-first client for the QueryPanel Bun/Hono API. Its primary function is to **generate SQL from natural language**, but it also 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
19
|
|
|
5
20
|
## Installation
|
|
6
21
|
|
|
7
22
|
```bash
|
|
8
|
-
bun add @querypanel/sdk
|
|
23
|
+
bun add @querypanel/node-sdk
|
|
9
24
|
# or
|
|
10
|
-
npm install @querypanel/sdk
|
|
25
|
+
npm install @querypanel/node-sdk
|
|
11
26
|
```
|
|
12
27
|
|
|
13
28
|
> **Runtime:** Node.js 18+, Deno, or Bun. The SDK uses Web Crypto API for JWT signing and the native `fetch` API, making it compatible with modern JavaScript runtimes.
|
|
@@ -15,8 +30,9 @@ npm install @querypanel/sdk
|
|
|
15
30
|
## Quickstart
|
|
16
31
|
|
|
17
32
|
```ts
|
|
18
|
-
import { QueryPanelSdkAPI } from "@querypanel/sdk";
|
|
33
|
+
import { QueryPanelSdkAPI } from "@querypanel/node-sdk";
|
|
19
34
|
import { Pool } from "pg";
|
|
35
|
+
import { createClient } from "@clickhouse/client";
|
|
20
36
|
|
|
21
37
|
const qp = new QueryPanelSdkAPI(
|
|
22
38
|
process.env.QUERYPANEL_URL!,
|
|
@@ -42,21 +58,31 @@ const createPostgresClient = () => async (sql: string, params?: unknown[]) => {
|
|
|
42
58
|
}
|
|
43
59
|
};
|
|
44
60
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
"pg_demo",
|
|
49
|
-
|
|
61
|
+
// Attach PostgreSQL database using the SDK's PostgresAdapter
|
|
62
|
+
// The SDK will automatically handle tenant isolation when tenantFieldName is provided
|
|
63
|
+
qp.attachPostgres(
|
|
64
|
+
"pg_demo", // a unique identifier for QueryPanel
|
|
65
|
+
createPostgresClient(),
|
|
50
66
|
{
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
67
|
+
database: "pg_demo", // database name
|
|
68
|
+
description: "PostgreSQL demo database", // some description that QueryPanel can use
|
|
69
|
+
tenantFieldName: "tenant_id", // SDK will automatically filter by tenant_id
|
|
70
|
+
enforceTenantIsolation: true, // Ensures all queries include tenant_id filter
|
|
71
|
+
allowedTables: ["orders"], // Only sync 'orders' table - 'users' will be excluded
|
|
72
|
+
},
|
|
73
|
+
);
|
|
74
|
+
|
|
75
|
+
// Amazon Redshift speaks the Postgres wire protocol, so a pg-based client works.
|
|
76
|
+
// attachRedshift introspects via Redshift's svv_* views and generates Redshift SQL.
|
|
77
|
+
qp.attachRedshift("warehouse", createPostgresClient(), {
|
|
78
|
+
database: "dev",
|
|
79
|
+
tenantFieldName: "tenant_id",
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
const clickhouse = createClient({ url: process.env.CLICKHOUSE_URL });
|
|
57
83
|
|
|
58
84
|
qp.attachClickhouse(
|
|
59
|
-
"analytics", //
|
|
85
|
+
"analytics", // unique identifier for QueryPanel
|
|
60
86
|
(params) => clickhouse.query(params),
|
|
61
87
|
{
|
|
62
88
|
database: "analytics", // database name
|
|
@@ -100,6 +126,30 @@ await qp.syncSchema("analytics", {
|
|
|
100
126
|
|
|
101
127
|
Optionally limit the payload with `tables: ["orders"]`.
|
|
102
128
|
|
|
129
|
+
#### Large databases
|
|
130
|
+
|
|
131
|
+
`allowedTables` (and `tables`) accept `schema.*` to include every table in a schema on Postgres/Redshift, e.g. `["crm.*", "public.orders"]`. On ClickHouse and BigQuery the adapter is bound to one database/dataset, so `*` or `<database>.*` means "all tables".
|
|
132
|
+
|
|
133
|
+
Browse the catalog cheaply (no columns; not restricted by `allowedTables`) to build a table picker:
|
|
134
|
+
|
|
135
|
+
```ts
|
|
136
|
+
await qp.listSchemas("warehouse"); // [{ schema: "crm", tableCount: 12 }, ...]
|
|
137
|
+
await qp.listTables("warehouse", { schema: "crm", search: "user", limit: 100 });
|
|
138
|
+
// [{ schema: "crm", name: "users", type: "table" }, ...] (default limit 500, max 5000)
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
For schemas too large for a single request, `syncSchemaInBatches` uploads tables in batches (≤ `maxBatchDocs` docs, default 1000, and ≤ `maxBatchBytes`, default 2 MB) and embeds them batch by batch:
|
|
142
|
+
|
|
143
|
+
```ts
|
|
144
|
+
await qp.syncSchemaInBatches("warehouse", {
|
|
145
|
+
tenantId: "tenant_123",
|
|
146
|
+
maxColumns: 50_000, // throw SchemaTooLargeError before uploading if exceeded
|
|
147
|
+
onProgress: (e) => console.log(e.phase, e),
|
|
148
|
+
});
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
To spread the work across requests (e.g. serverless time limits), call `stageSchemaIngest` (introspect + upload + commit), then `embedSchemaIngestBatch(sessionId, i, ...)` for each batch, then `finalizeSchemaIngest(sessionId, ...)`.
|
|
152
|
+
|
|
103
153
|
### Custom system prompt (`systemPrompt`)
|
|
104
154
|
|
|
105
155
|
Pass `systemPrompt` on `ask()` to inject extra instructions for SQL generation. Use it when a **client** needs policies QueryPanel does not know about — retention windows, a max date range, excluded event types, and similar product rules. Look up that client’s config in your backend and pass it on every question.
|
|
@@ -143,7 +193,7 @@ const response = await qp.ask("Show order volume by week", {
|
|
|
143
193
|
If your UI only supports a subset of chart kinds (for example no area or scatter), set **`supportedChartTypes`** on the SDK constructor or on each `ask` / `modifyChart` call (`line`, `bar`, `column`, `area`, `scatter`, `pie`).
|
|
144
194
|
|
|
145
195
|
```ts
|
|
146
|
-
import { QueryPanelSdkAPI, ALL_VIZ_CHART_TYPES, type ChartType } from "@querypanel/sdk";
|
|
196
|
+
import { QueryPanelSdkAPI, ALL_VIZ_CHART_TYPES, type ChartType } from "@querypanel/node-sdk";
|
|
147
197
|
|
|
148
198
|
const allowed: ChartType[] = ["line", "bar", "column", "pie"];
|
|
149
199
|
|
|
@@ -512,7 +562,7 @@ The API accepts up to **100** UUIDs per request. Examples: `?ids=a&ids=b` or `?i
|
|
|
512
562
|
The SDK is fully compatible with Deno (including Supabase Edge Functions) thanks to its use of Web Crypto API for JWT signing. No additional configuration needed:
|
|
513
563
|
|
|
514
564
|
```ts
|
|
515
|
-
import { QueryPanelSdkAPI } from "https://esm.sh/@querypanel/sdk";
|
|
565
|
+
import { QueryPanelSdkAPI } from "https://esm.sh/@querypanel/node-sdk";
|
|
516
566
|
|
|
517
567
|
const qp = new QueryPanelSdkAPI(
|
|
518
568
|
Deno.env.get("QUERYPANEL_URL")!,
|
|
@@ -526,10 +576,12 @@ const response = await qp.ask("Show top products", {
|
|
|
526
576
|
});
|
|
527
577
|
```
|
|
528
578
|
|
|
579
|
+
BigQuery is attached the same way with `attachBigQuery(name, clientFn, options)`. Any other engine can be plugged in with `attachDatabase(name, adapter)` and your own `DatabaseAdapter` implementation.
|
|
580
|
+
|
|
529
581
|
## Building locally
|
|
530
582
|
|
|
531
583
|
```bash
|
|
532
|
-
cd node-sdk
|
|
584
|
+
cd admin/packages/node-sdk
|
|
533
585
|
bun install
|
|
534
586
|
bun run build
|
|
535
587
|
```
|
|
@@ -571,4 +623,4 @@ Without `maxRetry`, execution errors throw immediately (default behavior).
|
|
|
571
623
|
|
|
572
624
|
## Need more?
|
|
573
625
|
|
|
574
|
-
Open an issue or extend `
|
|
626
|
+
Open an issue or extend the SDK: the public class is in `src/index.ts` and each API route has a module under `src/routes/`. Pull requests are welcome for additional adapters, richer param coercion, or convenience helpers around charts/annotations.
|