@querypanel/node-sdk 1.2.2 → 1.2.4
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 +25 -0
- package/dist/index.cjs +120 -36
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +34 -1
- package/dist/index.d.ts +34 -1
- package/dist/index.js +119 -36
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -93,6 +93,31 @@ const response = await qp.ask("Revenue by product", {
|
|
|
93
93
|
});
|
|
94
94
|
```
|
|
95
95
|
|
|
96
|
+
### Restricting VizSpec chart types
|
|
97
|
+
|
|
98
|
+
If your UI only supports a subset of VizSpec chart kinds (for example no area or scatter), set **`supportedChartTypes`** on the SDK constructor or on each `ask` / `modifyChart` call. The API’s `/vizspec` step then steers generation toward allowed types only (`line`, `bar`, `column`, `area`, `scatter`, `pie`). This applies whenever you use **`chartType: "vizspec"`** (including the default v2 flow after SQL runs).
|
|
99
|
+
|
|
100
|
+
```ts
|
|
101
|
+
import { QueryPanelSdkAPI, ALL_VIZ_CHART_TYPES, type ChartType } from "@querypanel/sdk";
|
|
102
|
+
|
|
103
|
+
const allowed: ChartType[] = ["line", "bar", "column", "pie"];
|
|
104
|
+
|
|
105
|
+
const qp = new QueryPanelSdkAPI(url, privateKey, workspaceId, {
|
|
106
|
+
supportedChartTypes: allowed,
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
// Or per request:
|
|
110
|
+
await qp.ask("Revenue by month", {
|
|
111
|
+
tenantId: "t1",
|
|
112
|
+
database: "analytics",
|
|
113
|
+
chartType: "vizspec",
|
|
114
|
+
pipeline: "v2",
|
|
115
|
+
supportedChartTypes: allowed,
|
|
116
|
+
});
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Use `ALL_VIZ_CHART_TYPES` when you need the full list (for example to derive `allowed` with `.filter(...)`).
|
|
120
|
+
|
|
96
121
|
## Session History & Context-Aware Queries
|
|
97
122
|
|
|
98
123
|
The SDK can link related questions into a session so follow-ups like “filter that to Europe” use prior context. The backend generates a QueryPanel session ID for every query and returns it in the response so you can reuse it.
|
package/dist/index.cjs
CHANGED
|
@@ -30,6 +30,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
30
30
|
// src/index.ts
|
|
31
31
|
var index_exports = {};
|
|
32
32
|
__export(index_exports, {
|
|
33
|
+
ALL_VIZ_CHART_TYPES: () => ALL_VIZ_CHART_TYPES,
|
|
33
34
|
BigQueryAdapter: () => BigQueryAdapter,
|
|
34
35
|
CallbackApiClient: () => CallbackApiClient,
|
|
35
36
|
ClickHouseAdapter: () => ClickHouseAdapter,
|
|
@@ -57,12 +58,6 @@ var BigQueryAdapter = class {
|
|
|
57
58
|
);
|
|
58
59
|
}
|
|
59
60
|
}
|
|
60
|
-
projectId;
|
|
61
|
-
datasetProjectId;
|
|
62
|
-
defaultDataset;
|
|
63
|
-
databaseName;
|
|
64
|
-
kind;
|
|
65
|
-
allowedTables;
|
|
66
61
|
async execute(sql, params) {
|
|
67
62
|
if (this.allowedTables) {
|
|
68
63
|
this.validateQueryTables(sql);
|
|
@@ -293,10 +288,6 @@ var ClickHouseAdapter = class {
|
|
|
293
288
|
this.allowedTables = normalizeTableFilter2(options.allowedTables);
|
|
294
289
|
}
|
|
295
290
|
}
|
|
296
|
-
databaseName;
|
|
297
|
-
defaultFormat;
|
|
298
|
-
kind;
|
|
299
|
-
allowedTables;
|
|
300
291
|
async execute(sql, params) {
|
|
301
292
|
if (this.allowedTables) {
|
|
302
293
|
this.validateQueryTables(sql);
|
|
@@ -509,10 +500,6 @@ var PostgresAdapter = class {
|
|
|
509
500
|
);
|
|
510
501
|
}
|
|
511
502
|
}
|
|
512
|
-
databaseName;
|
|
513
|
-
defaultSchema;
|
|
514
|
-
kind;
|
|
515
|
-
allowedTables;
|
|
516
503
|
async execute(sql, params) {
|
|
517
504
|
if (this.allowedTables) {
|
|
518
505
|
this.validateQueryTables(sql);
|
|
@@ -753,14 +740,8 @@ function sanitize2(value) {
|
|
|
753
740
|
// src/core/client.ts
|
|
754
741
|
var import_node_crypto = __toESM(require("crypto"), 1);
|
|
755
742
|
var ApiClient = class {
|
|
756
|
-
baseUrl;
|
|
757
|
-
privateKey;
|
|
758
|
-
organizationId;
|
|
759
|
-
defaultTenantId;
|
|
760
|
-
additionalHeaders;
|
|
761
|
-
fetchImpl;
|
|
762
|
-
cryptoKey = null;
|
|
763
743
|
constructor(baseUrl, privateKey, organizationId, options) {
|
|
744
|
+
this.cryptoKey = null;
|
|
764
745
|
if (!baseUrl) {
|
|
765
746
|
throw new Error("Base URL is required");
|
|
766
747
|
}
|
|
@@ -1006,8 +987,6 @@ var ApiClient = class {
|
|
|
1006
987
|
|
|
1007
988
|
// src/core/callback-client.ts
|
|
1008
989
|
var CallbackApiClient = class {
|
|
1009
|
-
requestHandler;
|
|
1010
|
-
defaultTenantId;
|
|
1011
990
|
constructor(requestHandler, options) {
|
|
1012
991
|
this.requestHandler = requestHandler;
|
|
1013
992
|
this.defaultTenantId = options?.defaultTenantId;
|
|
@@ -1111,9 +1090,10 @@ var CallbackApiClient = class {
|
|
|
1111
1090
|
|
|
1112
1091
|
// src/core/query-engine.ts
|
|
1113
1092
|
var QueryEngine = class {
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1093
|
+
constructor() {
|
|
1094
|
+
this.databases = /* @__PURE__ */ new Map();
|
|
1095
|
+
this.databaseMetadata = /* @__PURE__ */ new Map();
|
|
1096
|
+
}
|
|
1117
1097
|
attachDatabase(name, adapter, metadata) {
|
|
1118
1098
|
this.databases.set(name, adapter);
|
|
1119
1099
|
this.databaseMetadata.set(name, metadata);
|
|
@@ -1433,7 +1413,7 @@ async function listActiveCharts(client, queryEngine, options, signal) {
|
|
|
1433
1413
|
params.set("limit", `${options.pagination.limit}`);
|
|
1434
1414
|
if (options?.sortBy) params.set("sort_by", options.sortBy);
|
|
1435
1415
|
if (options?.sortDir) params.set("sort_dir", options.sortDir);
|
|
1436
|
-
if (options?.title) params.set("
|
|
1416
|
+
if (options?.title) params.set("title", options.title);
|
|
1437
1417
|
if (options?.userFilter) params.set("user_id", options.userFilter);
|
|
1438
1418
|
if (options?.createdFrom) params.set("created_from", options.createdFrom);
|
|
1439
1419
|
if (options?.createdTo) params.set("created_to", options.createdTo);
|
|
@@ -1462,6 +1442,60 @@ async function listActiveCharts(client, queryEngine, options, signal) {
|
|
|
1462
1442
|
}
|
|
1463
1443
|
return response;
|
|
1464
1444
|
}
|
|
1445
|
+
async function listAllActiveCharts(client, queryEngine, options, signal) {
|
|
1446
|
+
const tenantId = resolveTenantId2(client, options?.tenantId);
|
|
1447
|
+
const response = await client.get(
|
|
1448
|
+
"/active-charts/all",
|
|
1449
|
+
tenantId,
|
|
1450
|
+
options?.userId,
|
|
1451
|
+
options?.scopes,
|
|
1452
|
+
signal
|
|
1453
|
+
);
|
|
1454
|
+
if (options?.withData) {
|
|
1455
|
+
response.data = await Promise.all(
|
|
1456
|
+
response.data.map(async (active) => ({
|
|
1457
|
+
...active,
|
|
1458
|
+
chart: active.chart ? await getChart(
|
|
1459
|
+
client,
|
|
1460
|
+
queryEngine,
|
|
1461
|
+
active.chart_id,
|
|
1462
|
+
options,
|
|
1463
|
+
signal
|
|
1464
|
+
) : null
|
|
1465
|
+
}))
|
|
1466
|
+
);
|
|
1467
|
+
}
|
|
1468
|
+
return response.data;
|
|
1469
|
+
}
|
|
1470
|
+
async function getActiveChartsByIds(client, queryEngine, ids, options, signal) {
|
|
1471
|
+
const tenantId = resolveTenantId2(client, options?.tenantId);
|
|
1472
|
+
const params = new URLSearchParams();
|
|
1473
|
+
for (const id of ids) {
|
|
1474
|
+
params.append("ids", id);
|
|
1475
|
+
}
|
|
1476
|
+
const response = await client.get(
|
|
1477
|
+
`/active-charts/bulk${params.toString() ? `?${params.toString()}` : ""}`,
|
|
1478
|
+
tenantId,
|
|
1479
|
+
options?.userId,
|
|
1480
|
+
options?.scopes,
|
|
1481
|
+
signal
|
|
1482
|
+
);
|
|
1483
|
+
if (options?.withData) {
|
|
1484
|
+
response.data = await Promise.all(
|
|
1485
|
+
response.data.map(async (active) => ({
|
|
1486
|
+
...active,
|
|
1487
|
+
chart: active.chart ? await getChart(
|
|
1488
|
+
client,
|
|
1489
|
+
queryEngine,
|
|
1490
|
+
active.chart_id,
|
|
1491
|
+
options,
|
|
1492
|
+
signal
|
|
1493
|
+
) : null
|
|
1494
|
+
}))
|
|
1495
|
+
);
|
|
1496
|
+
}
|
|
1497
|
+
return response;
|
|
1498
|
+
}
|
|
1465
1499
|
async function getActiveChart(client, queryEngine, id, options, signal) {
|
|
1466
1500
|
const tenantId = resolveTenantId2(client, options?.tenantId);
|
|
1467
1501
|
const active = await client.get(
|
|
@@ -1819,7 +1853,10 @@ async function ask(client, queryEngine, question, options, signal) {
|
|
|
1819
1853
|
fields: execution.fields,
|
|
1820
1854
|
rows: anonymizeResults(rows),
|
|
1821
1855
|
max_retries: options.chartMaxRetries ?? 3,
|
|
1822
|
-
query_id: queryResponse.data.queryId
|
|
1856
|
+
query_id: queryResponse.data.queryId,
|
|
1857
|
+
...options.supportedChartTypes?.length ? {
|
|
1858
|
+
supported_chart_types: options.supportedChartTypes
|
|
1859
|
+
} : {}
|
|
1823
1860
|
},
|
|
1824
1861
|
tenantId,
|
|
1825
1862
|
options.userId,
|
|
@@ -2160,7 +2197,8 @@ async function modifyChart(client, queryEngine, input, options, signal) {
|
|
|
2160
2197
|
max_retries: options?.chartMaxRetries ?? 3,
|
|
2161
2198
|
query_id: queryId,
|
|
2162
2199
|
// Include viz hints for the chart generator
|
|
2163
|
-
...hasVizMods ? { encoding_hints: vizHintsForChart } : {}
|
|
2200
|
+
...hasVizMods ? { encoding_hints: vizHintsForChart } : {},
|
|
2201
|
+
...options?.supportedChartTypes?.length ? { supported_chart_types: options.supportedChartTypes } : {}
|
|
2164
2202
|
},
|
|
2165
2203
|
tenantId,
|
|
2166
2204
|
options?.userId,
|
|
@@ -2307,7 +2345,8 @@ async function generateVizSpec(client, input, options, signal) {
|
|
|
2307
2345
|
rows: input.rows,
|
|
2308
2346
|
max_retries: options?.maxRetries ?? input.max_retries ?? 3,
|
|
2309
2347
|
query_id: input.query_id,
|
|
2310
|
-
encoding_hints: input.encoding_hints
|
|
2348
|
+
encoding_hints: input.encoding_hints,
|
|
2349
|
+
...input.supported_chart_types?.length ? { supported_chart_types: input.supported_chart_types } : {}
|
|
2311
2350
|
},
|
|
2312
2351
|
tenantId,
|
|
2313
2352
|
options?.userId,
|
|
@@ -2327,10 +2366,18 @@ function resolveTenantId8(client, tenantId) {
|
|
|
2327
2366
|
return resolved;
|
|
2328
2367
|
}
|
|
2329
2368
|
|
|
2369
|
+
// src/types/vizspec.ts
|
|
2370
|
+
var ALL_VIZ_CHART_TYPES = [
|
|
2371
|
+
"line",
|
|
2372
|
+
"bar",
|
|
2373
|
+
"column",
|
|
2374
|
+
"area",
|
|
2375
|
+
"scatter",
|
|
2376
|
+
"pie"
|
|
2377
|
+
];
|
|
2378
|
+
|
|
2330
2379
|
// src/index.ts
|
|
2331
2380
|
var QueryPanelSdkAPI = class _QueryPanelSdkAPI {
|
|
2332
|
-
client;
|
|
2333
|
-
queryEngine;
|
|
2334
2381
|
/**
|
|
2335
2382
|
* @param workspaceId - Workspace UUID (same value as your org in the dashboard). Passed to the API as JWT claim `organizationId`.
|
|
2336
2383
|
*/
|
|
@@ -2348,6 +2395,7 @@ var QueryPanelSdkAPI = class _QueryPanelSdkAPI {
|
|
|
2348
2395
|
});
|
|
2349
2396
|
}
|
|
2350
2397
|
this.queryEngine = new QueryEngine();
|
|
2398
|
+
this.supportedChartTypes = options?.supportedChartTypes;
|
|
2351
2399
|
}
|
|
2352
2400
|
/**
|
|
2353
2401
|
* Create an SDK instance that uses a request callback instead of HTTP.
|
|
@@ -2384,7 +2432,10 @@ var QueryPanelSdkAPI = class _QueryPanelSdkAPI {
|
|
|
2384
2432
|
const api = new CallbackApiClient(requestHandler, {
|
|
2385
2433
|
defaultTenantId: options?.defaultTenantId
|
|
2386
2434
|
});
|
|
2387
|
-
return new _QueryPanelSdkAPI("", "", workspaceId, {
|
|
2435
|
+
return new _QueryPanelSdkAPI("", "", workspaceId, {
|
|
2436
|
+
api,
|
|
2437
|
+
supportedChartTypes: options?.supportedChartTypes
|
|
2438
|
+
});
|
|
2388
2439
|
}
|
|
2389
2440
|
// Database attachment methods
|
|
2390
2441
|
attachClickhouse(name, clientFn, options) {
|
|
@@ -2508,7 +2559,10 @@ var QueryPanelSdkAPI = class _QueryPanelSdkAPI {
|
|
|
2508
2559
|
this.client,
|
|
2509
2560
|
this.queryEngine,
|
|
2510
2561
|
question,
|
|
2511
|
-
|
|
2562
|
+
{
|
|
2563
|
+
...options,
|
|
2564
|
+
supportedChartTypes: options.supportedChartTypes ?? this.supportedChartTypes
|
|
2565
|
+
},
|
|
2512
2566
|
signal
|
|
2513
2567
|
);
|
|
2514
2568
|
}
|
|
@@ -2580,7 +2634,10 @@ var QueryPanelSdkAPI = class _QueryPanelSdkAPI {
|
|
|
2580
2634
|
async generateVizSpec(input, options, signal) {
|
|
2581
2635
|
return await generateVizSpec(
|
|
2582
2636
|
this.client,
|
|
2583
|
-
|
|
2637
|
+
{
|
|
2638
|
+
...input,
|
|
2639
|
+
supported_chart_types: input.supported_chart_types ?? this.supportedChartTypes
|
|
2640
|
+
},
|
|
2584
2641
|
options,
|
|
2585
2642
|
signal
|
|
2586
2643
|
);
|
|
@@ -2648,7 +2705,10 @@ var QueryPanelSdkAPI = class _QueryPanelSdkAPI {
|
|
|
2648
2705
|
this.client,
|
|
2649
2706
|
this.queryEngine,
|
|
2650
2707
|
input,
|
|
2651
|
-
options
|
|
2708
|
+
options ? {
|
|
2709
|
+
...options,
|
|
2710
|
+
supportedChartTypes: options.supportedChartTypes ?? this.supportedChartTypes
|
|
2711
|
+
} : this.supportedChartTypes ? { supportedChartTypes: this.supportedChartTypes } : void 0,
|
|
2652
2712
|
signal
|
|
2653
2713
|
);
|
|
2654
2714
|
}
|
|
@@ -2927,6 +2987,29 @@ var QueryPanelSdkAPI = class _QueryPanelSdkAPI {
|
|
|
2927
2987
|
signal
|
|
2928
2988
|
);
|
|
2929
2989
|
}
|
|
2990
|
+
/**
|
|
2991
|
+
* Lists all active charts without pagination.
|
|
2992
|
+
*/
|
|
2993
|
+
async listAllActiveCharts(options, signal) {
|
|
2994
|
+
return await listAllActiveCharts(
|
|
2995
|
+
this.client,
|
|
2996
|
+
this.queryEngine,
|
|
2997
|
+
options,
|
|
2998
|
+
signal
|
|
2999
|
+
);
|
|
3000
|
+
}
|
|
3001
|
+
/**
|
|
3002
|
+
* Bulk gets active charts by IDs.
|
|
3003
|
+
*/
|
|
3004
|
+
async getActiveChartsByIds(ids, options, signal) {
|
|
3005
|
+
return await getActiveChartsByIds(
|
|
3006
|
+
this.client,
|
|
3007
|
+
this.queryEngine,
|
|
3008
|
+
ids,
|
|
3009
|
+
options,
|
|
3010
|
+
signal
|
|
3011
|
+
);
|
|
3012
|
+
}
|
|
2930
3013
|
/**
|
|
2931
3014
|
* Retrieves a single active chart by ID.
|
|
2932
3015
|
*
|
|
@@ -3287,6 +3370,7 @@ var QueryPanelSdkAPI = class _QueryPanelSdkAPI {
|
|
|
3287
3370
|
};
|
|
3288
3371
|
// Annotate the CommonJS export names for ESM import in node:
|
|
3289
3372
|
0 && (module.exports = {
|
|
3373
|
+
ALL_VIZ_CHART_TYPES,
|
|
3290
3374
|
BigQueryAdapter,
|
|
3291
3375
|
CallbackApiClient,
|
|
3292
3376
|
ClickHouseAdapter,
|