@querypanel/node-sdk 1.0.40 → 1.0.42
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 +16 -8
- package/dist/index.cjs +40 -11
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +28 -9
- package/dist/index.js.map +1 -1
- package/package.json +71 -71
package/dist/index.js
CHANGED
|
@@ -309,8 +309,9 @@ var PostgresAdapter = class {
|
|
|
309
309
|
const allowedSet = new Set(
|
|
310
310
|
this.allowedTables.map((t) => tableKey(t.schema, t.table))
|
|
311
311
|
);
|
|
312
|
+
const neutralizedSql = sql.replace(/EXTRACT\s*\([^)]*FROM\s+[^)]+\)/gi, "EXTRACT(/*neutralized*/)").replace(/SUBSTRING\s*\([^)]*FROM\s+[^)]+\)/gi, "SUBSTRING(/*neutralized*/)").replace(/TRIM\s*\([^)]*FROM\s+[^)]+\)/gi, "TRIM(/*neutralized*/)").replace(/POSITION\s*\([^)]*FROM\s+[^)]+\)/gi, "POSITION(/*neutralized*/)");
|
|
312
313
|
const tablePattern = /(?:FROM|JOIN)\s+(?:ONLY\s+)?(?:([a-zA-Z_][a-zA-Z0-9_]*)\.)?(["']?[a-zA-Z_][a-zA-Z0-9_]*["']?)/gi;
|
|
313
|
-
const matches =
|
|
314
|
+
const matches = neutralizedSql.matchAll(tablePattern);
|
|
314
315
|
for (const match of matches) {
|
|
315
316
|
const schema = match[1] ?? this.defaultSchema;
|
|
316
317
|
const table = match[2]?.replace(/['"]/g, "");
|
|
@@ -525,6 +526,7 @@ function sanitize2(value) {
|
|
|
525
526
|
}
|
|
526
527
|
|
|
527
528
|
// src/core/client.ts
|
|
529
|
+
import crypto from "crypto";
|
|
528
530
|
var ApiClient = class {
|
|
529
531
|
baseUrl;
|
|
530
532
|
privateKey;
|
|
@@ -1063,6 +1065,7 @@ function resolveTenantId2(client, tenantId) {
|
|
|
1063
1065
|
}
|
|
1064
1066
|
|
|
1065
1067
|
// src/routes/ingest.ts
|
|
1068
|
+
import crypto2 from "crypto";
|
|
1066
1069
|
async function syncSchema(client, queryEngine, databaseName, options, signal) {
|
|
1067
1070
|
const tenantId = resolveTenantId3(client, options.tenantId);
|
|
1068
1071
|
const adapter = queryEngine.getDatabase(databaseName);
|
|
@@ -1074,7 +1077,7 @@ async function syncSchema(client, queryEngine, databaseName, options, signal) {
|
|
|
1074
1077
|
if (options.forceReindex) {
|
|
1075
1078
|
payload.force_reindex = true;
|
|
1076
1079
|
}
|
|
1077
|
-
const sessionId =
|
|
1080
|
+
const sessionId = crypto2.randomUUID();
|
|
1078
1081
|
const response = await client.post(
|
|
1079
1082
|
"/ingest",
|
|
1080
1083
|
payload,
|
|
@@ -1123,22 +1126,36 @@ function buildSchemaRequest(databaseName, adapter, introspection, metadata) {
|
|
|
1123
1126
|
}
|
|
1124
1127
|
|
|
1125
1128
|
// src/routes/query.ts
|
|
1129
|
+
import crypto3 from "crypto";
|
|
1126
1130
|
async function ask(client, queryEngine, question, options, signal) {
|
|
1127
1131
|
const tenantId = resolveTenantId4(client, options.tenantId);
|
|
1128
|
-
const sessionId =
|
|
1132
|
+
const sessionId = crypto3.randomUUID();
|
|
1129
1133
|
const maxRetry = options.maxRetry ?? 0;
|
|
1130
1134
|
let attempt = 0;
|
|
1131
1135
|
let lastError = options.lastError;
|
|
1132
1136
|
let previousSql = options.previousSql;
|
|
1133
1137
|
while (attempt <= maxRetry) {
|
|
1134
1138
|
console.log({ lastError, previousSql });
|
|
1139
|
+
const databaseName = options.database ?? queryEngine.getDefaultDatabase();
|
|
1140
|
+
const metadata = databaseName ? queryEngine.getDatabaseMetadata(databaseName) : void 0;
|
|
1141
|
+
let tenantSettings;
|
|
1142
|
+
if (metadata?.tenantFieldName) {
|
|
1143
|
+
tenantSettings = {
|
|
1144
|
+
tenantFieldName: metadata.tenantFieldName,
|
|
1145
|
+
tenantFieldType: metadata.tenantFieldType,
|
|
1146
|
+
enforceTenantIsolation: metadata.enforceTenantIsolation
|
|
1147
|
+
};
|
|
1148
|
+
}
|
|
1135
1149
|
const queryResponse = await client.post(
|
|
1136
1150
|
"/query",
|
|
1137
1151
|
{
|
|
1138
1152
|
question,
|
|
1139
1153
|
...lastError ? { last_error: lastError } : {},
|
|
1140
1154
|
...previousSql ? { previous_sql: previousSql } : {},
|
|
1141
|
-
...options.maxRetry ? { max_retry: options.maxRetry } : {}
|
|
1155
|
+
...options.maxRetry ? { max_retry: options.maxRetry } : {},
|
|
1156
|
+
...tenantSettings ? { tenant_settings: tenantSettings } : {},
|
|
1157
|
+
...databaseName ? { database: databaseName } : {},
|
|
1158
|
+
...metadata?.dialect ? { dialect: metadata.dialect } : {}
|
|
1142
1159
|
},
|
|
1143
1160
|
tenantId,
|
|
1144
1161
|
options.userId,
|
|
@@ -1146,8 +1163,8 @@ async function ask(client, queryEngine, question, options, signal) {
|
|
|
1146
1163
|
signal,
|
|
1147
1164
|
sessionId
|
|
1148
1165
|
);
|
|
1149
|
-
const
|
|
1150
|
-
if (!
|
|
1166
|
+
const dbName = queryResponse.database ?? options.database ?? queryEngine.getDefaultDatabase();
|
|
1167
|
+
if (!dbName) {
|
|
1151
1168
|
throw new Error(
|
|
1152
1169
|
"No database attached. Call attachPostgres/attachClickhouse first."
|
|
1153
1170
|
);
|
|
@@ -1158,7 +1175,7 @@ async function ask(client, queryEngine, question, options, signal) {
|
|
|
1158
1175
|
const execution = await queryEngine.validateAndExecute(
|
|
1159
1176
|
queryResponse.sql,
|
|
1160
1177
|
paramValues,
|
|
1161
|
-
|
|
1178
|
+
dbName,
|
|
1162
1179
|
tenantId
|
|
1163
1180
|
);
|
|
1164
1181
|
const rows = execution.rows ?? [];
|
|
@@ -1231,7 +1248,7 @@ async function ask(client, queryEngine, question, options, signal) {
|
|
|
1231
1248
|
chart,
|
|
1232
1249
|
context: queryResponse.context,
|
|
1233
1250
|
attempts: attempt + 1,
|
|
1234
|
-
target_db:
|
|
1251
|
+
target_db: dbName
|
|
1235
1252
|
};
|
|
1236
1253
|
} catch (error) {
|
|
1237
1254
|
attempt++;
|
|
@@ -1270,9 +1287,10 @@ function anonymizeResults(rows) {
|
|
|
1270
1287
|
}
|
|
1271
1288
|
|
|
1272
1289
|
// src/routes/vizspec.ts
|
|
1290
|
+
import crypto4 from "crypto";
|
|
1273
1291
|
async function generateVizSpec(client, input, options, signal) {
|
|
1274
1292
|
const tenantId = resolveTenantId5(client, options?.tenantId);
|
|
1275
|
-
const sessionId =
|
|
1293
|
+
const sessionId = crypto4.randomUUID();
|
|
1276
1294
|
const response = await client.post(
|
|
1277
1295
|
"/vizspec",
|
|
1278
1296
|
{
|
|
@@ -1332,6 +1350,7 @@ var QueryPanelSdkAPI = class {
|
|
|
1332
1350
|
description: options?.description,
|
|
1333
1351
|
tags: options?.tags,
|
|
1334
1352
|
tenantFieldName: options?.tenantFieldName,
|
|
1353
|
+
tenantFieldType: options?.tenantFieldType ?? "String",
|
|
1335
1354
|
enforceTenantIsolation: options?.tenantFieldName ? options?.enforceTenantIsolation ?? true : void 0
|
|
1336
1355
|
};
|
|
1337
1356
|
this.queryEngine.attachDatabase(name, adapter, metadata);
|