@querypanel/node-sdk 1.2.6 → 1.2.8

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/dist/index.cjs CHANGED
@@ -382,10 +382,15 @@ var ClickHouseAdapter = class {
382
382
  return;
383
383
  }
384
384
  const allowedSet = new Set(this.allowedTables);
385
- const tablePattern = /(?:FROM|JOIN)\s+(?:FINAL\s+)?(?:(?:[a-zA-Z_][a-zA-Z0-9_]*)\.)?(["'`]?[a-zA-Z_][a-zA-Z0-9_]*["'`]?)/gi;
385
+ const tablePattern = /\b(FROM|JOIN)\s+(?:FINAL\s+)?(?:(?:[a-zA-Z_][a-zA-Z0-9_]*)\.)?(["'`]?[a-zA-Z_][a-zA-Z0-9_]*["'`]?)/gi;
386
386
  const matches = sql.matchAll(tablePattern);
387
387
  for (const match of matches) {
388
- const table = match[1]?.replace(/["'`]/g, "");
388
+ const clause = match[1]?.toUpperCase();
389
+ const matchIndex = match.index ?? -1;
390
+ if (clause === "JOIN" && matchIndex >= 0 && isArrayJoinClause(sql, matchIndex)) {
391
+ continue;
392
+ }
393
+ const table = match[2]?.replace(/["'`]/g, "");
389
394
  if (table) {
390
395
  if (!allowedSet.has(table)) {
391
396
  throw new Error(
@@ -453,6 +458,11 @@ function normalizeTableFilter2(tables) {
453
458
  }
454
459
  return normalized;
455
460
  }
461
+ function isArrayJoinClause(sql, joinIndex) {
462
+ const beforeJoin = sql.slice(0, joinIndex);
463
+ const previousToken = beforeJoin.trim().split(/\s+/).pop()?.toUpperCase();
464
+ return previousToken === "ARRAY";
465
+ }
456
466
  function transformColumnRow(row) {
457
467
  const unwrappedType = unwrapTypeModifiers(row.type);
458
468
  const column = {
@@ -1832,7 +1842,6 @@ async function ask(client, queryEngine, question, options, signal) {
1832
1842
  let previousSql = options.previousSql;
1833
1843
  const queryEndpoint = options.pipeline === "v2" ? "/v2/query" : "/query";
1834
1844
  while (attempt <= maxRetry) {
1835
- console.log({ lastError, previousSql });
1836
1845
  const databaseName = options.database ?? queryEngine.getDefaultDatabase();
1837
1846
  const metadata = databaseName ? queryEngine.getDatabaseMetadata(databaseName) : void 0;
1838
1847
  let tenantSettings;
@@ -1855,7 +1864,8 @@ async function ask(client, queryEngine, question, options, signal) {
1855
1864
  ...databaseName ? { database: databaseName } : {},
1856
1865
  ...metadata?.dialect ? { dialect: metadata.dialect } : {},
1857
1866
  ...options.model?.trim() ? { model: options.model.trim() } : {},
1858
- ...options.pipeline === "v2" && options.systemPrompt?.trim() ? { system_prompt: options.systemPrompt.trim() } : {}
1867
+ ...options.pipeline === "v2" && options.systemPrompt?.trim() ? { system_prompt: options.systemPrompt.trim() } : {},
1868
+ debug: options.debug ?? false
1859
1869
  },
1860
1870
  tenantId,
1861
1871
  options.userId,
@@ -1976,9 +1986,14 @@ async function ask(client, queryEngine, question, options, signal) {
1976
1986
  }
1977
1987
  lastError = error instanceof Error ? error.message : String(error);
1978
1988
  previousSql = queryResponse.data.sql ?? previousSql;
1979
- console.warn(
1980
- `SQL execution failed (attempt ${attempt}/${maxRetry + 1}): ${lastError}. Retrying...`
1981
- );
1989
+ console.warn("SQL execution failed, retrying query generation", {
1990
+ attempt,
1991
+ maxAttempts: maxRetry + 1,
1992
+ error: lastError,
1993
+ sql: queryResponse.data.sql ?? null,
1994
+ paramMetadata,
1995
+ params: paramValues
1996
+ });
1982
1997
  }
1983
1998
  }
1984
1999
  throw new Error("Unexpected error in ask retry loop");
@@ -2204,7 +2219,8 @@ async function modifyChart(client, queryEngine, input, options, signal) {
2204
2219
  ...options?.maxRetry ? { max_retry: options.maxRetry } : {},
2205
2220
  ...tenantSettings ? { tenant_settings: tenantSettings } : {},
2206
2221
  ...databaseName ? { database: databaseName } : {},
2207
- ...metadata?.dialect ? { dialect: metadata.dialect } : {}
2222
+ ...metadata?.dialect ? { dialect: metadata.dialect } : {},
2223
+ debug: options?.debug ?? false
2208
2224
  },
2209
2225
  tenantId,
2210
2226
  options?.userId,
@@ -2585,7 +2601,7 @@ var QueryPanelSdkAPI = class _QueryPanelSdkAPI {
2585
2601
  * It handles the complete flow: SQL generation → validation → execution → chart generation.
2586
2602
  *
2587
2603
  * @param question - Natural language question (e.g., "Show revenue by country")
2588
- * @param options - Query options including tenantId, database, and retry settings
2604
+ * @param options - Query options including tenantId, database, retry settings, and optional `debug` for engineer-style rationale
2589
2605
  * @param signal - Optional AbortSignal for cancellation
2590
2606
  * @returns Response with SQL, executed data rows, and generated chart
2591
2607
  * @throws {Error} When SQL generation or execution fails after all retries