@querypanel/node-sdk 1.0.36 → 1.0.38

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.js CHANGED
@@ -525,7 +525,6 @@ function sanitize2(value) {
525
525
  }
526
526
 
527
527
  // src/core/client.ts
528
- import { createSign } from "crypto";
529
528
  var ApiClient = class {
530
529
  baseUrl;
531
530
  privateKey;
@@ -533,6 +532,7 @@ var ApiClient = class {
533
532
  defaultTenantId;
534
533
  additionalHeaders;
535
534
  fetchImpl;
535
+ cryptoKey = null;
536
536
  constructor(baseUrl, privateKey, organizationId, options) {
537
537
  if (!baseUrl) {
538
538
  throw new Error("Base URL is required");
@@ -648,6 +648,66 @@ var ApiClient = class {
648
648
  }
649
649
  return headers;
650
650
  }
651
+ /**
652
+ * Base64URL encode a string (works in both Node.js 18+ and Deno)
653
+ */
654
+ base64UrlEncode(str) {
655
+ const bytes = new TextEncoder().encode(str);
656
+ let binary = "";
657
+ const chunkSize = 8192;
658
+ for (let i = 0; i < bytes.length; i += chunkSize) {
659
+ const chunk = bytes.slice(i, i + chunkSize);
660
+ binary += String.fromCharCode(...chunk);
661
+ }
662
+ const base64 = btoa(binary);
663
+ return base64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, "");
664
+ }
665
+ /**
666
+ * Base64URL encode from Uint8Array (for binary data like signatures)
667
+ */
668
+ base64UrlEncodeBytes(bytes) {
669
+ let binary = "";
670
+ const chunkSize = 8192;
671
+ for (let i = 0; i < bytes.length; i += chunkSize) {
672
+ const chunk = bytes.slice(i, i + chunkSize);
673
+ binary += String.fromCharCode(...chunk);
674
+ }
675
+ const base64 = btoa(binary);
676
+ return base64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, "");
677
+ }
678
+ /**
679
+ * Import the private key into Web Crypto API format (cached after first import)
680
+ */
681
+ async getCryptoKey() {
682
+ if (this.cryptoKey) {
683
+ return this.cryptoKey;
684
+ }
685
+ this.cryptoKey = await crypto.subtle.importKey(
686
+ "pkcs8",
687
+ this.privateKeyToArrayBuffer(this.privateKey),
688
+ {
689
+ name: "RSASSA-PKCS1-v1_5",
690
+ hash: "SHA-256"
691
+ },
692
+ false,
693
+ ["sign"]
694
+ );
695
+ return this.cryptoKey;
696
+ }
697
+ /**
698
+ * Convert PEM private key to ArrayBuffer for Web Crypto API
699
+ */
700
+ privateKeyToArrayBuffer(pem) {
701
+ const pemHeader = "-----BEGIN PRIVATE KEY-----";
702
+ const pemFooter = "-----END PRIVATE KEY-----";
703
+ const pemContents = pem.replace(pemHeader, "").replace(pemFooter, "").replace(/\s/g, "");
704
+ const binaryString = atob(pemContents);
705
+ const bytes = new Uint8Array(binaryString.length);
706
+ for (let i = 0; i < binaryString.length; i++) {
707
+ bytes[i] = binaryString.charCodeAt(i);
708
+ }
709
+ return bytes.buffer;
710
+ }
651
711
  async generateJWT(tenantId, userId, scopes) {
652
712
  const header = {
653
713
  alg: "RS256",
@@ -659,19 +719,20 @@ var ApiClient = class {
659
719
  };
660
720
  if (userId) payload.userId = userId;
661
721
  if (scopes?.length) payload.scopes = scopes;
662
- const encodeJson = (obj) => {
663
- const json = JSON.stringify(obj);
664
- const base64 = Buffer.from(json).toString("base64");
665
- return base64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, "");
666
- };
667
- const encodedHeader = encodeJson(header);
668
- const encodedPayload = encodeJson(payload);
722
+ const encodedHeader = this.base64UrlEncode(JSON.stringify(header));
723
+ const encodedPayload = this.base64UrlEncode(JSON.stringify(payload));
669
724
  const data = `${encodedHeader}.${encodedPayload}`;
670
- const signer = createSign("RSA-SHA256");
671
- signer.update(data);
672
- signer.end();
673
- const signature = signer.sign(this.privateKey);
674
- const encodedSignature = signature.toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, "");
725
+ const key = await this.getCryptoKey();
726
+ const dataBytes = new TextEncoder().encode(data);
727
+ const signature = await crypto.subtle.sign(
728
+ {
729
+ name: "RSASSA-PKCS1-v1_5"
730
+ },
731
+ key,
732
+ dataBytes
733
+ );
734
+ const signatureBytes = new Uint8Array(signature);
735
+ const encodedSignature = this.base64UrlEncodeBytes(signatureBytes);
675
736
  return `${data}.${encodedSignature}`;
676
737
  }
677
738
  };
@@ -756,13 +817,19 @@ var QueryEngine = class {
756
817
  return sql;
757
818
  }
758
819
  const tenantField = metadata.tenantFieldName;
759
- const paramKey = tenantField;
760
- params[paramKey] = tenantId;
761
820
  const normalizedSql = sql.toLowerCase();
762
821
  if (normalizedSql.includes(tenantField.toLowerCase())) {
763
822
  return sql;
764
823
  }
765
- const tenantPredicate = metadata.dialect === "clickhouse" ? `${tenantField} = {${tenantField}:${metadata.tenantFieldType ?? "String"}}` : `${tenantField} = '${tenantId}'`;
824
+ let tenantPredicate;
825
+ if (metadata.dialect === "clickhouse") {
826
+ const paramKey = tenantField;
827
+ params[paramKey] = tenantId;
828
+ tenantPredicate = `${tenantField} = {${tenantField}:${metadata.tenantFieldType ?? "String"}}`;
829
+ } else {
830
+ const escapedId = tenantId.replace(/'/g, "''");
831
+ tenantPredicate = `${tenantField} = '${escapedId}'`;
832
+ }
766
833
  if (/\bwhere\b/i.test(sql)) {
767
834
  return sql.replace(
768
835
  /\bwhere\b/i,
@@ -996,7 +1063,6 @@ function resolveTenantId2(client, tenantId) {
996
1063
  }
997
1064
 
998
1065
  // src/routes/ingest.ts
999
- import { randomUUID } from "crypto";
1000
1066
  async function syncSchema(client, queryEngine, databaseName, options, signal) {
1001
1067
  const tenantId = resolveTenantId3(client, options.tenantId);
1002
1068
  const adapter = queryEngine.getDatabase(databaseName);
@@ -1008,7 +1074,7 @@ async function syncSchema(client, queryEngine, databaseName, options, signal) {
1008
1074
  if (options.forceReindex) {
1009
1075
  payload.force_reindex = true;
1010
1076
  }
1011
- const sessionId = randomUUID();
1077
+ const sessionId = crypto.randomUUID();
1012
1078
  const response = await client.post(
1013
1079
  "/ingest",
1014
1080
  payload,
@@ -1057,10 +1123,9 @@ function buildSchemaRequest(databaseName, adapter, introspection, metadata) {
1057
1123
  }
1058
1124
 
1059
1125
  // src/routes/query.ts
1060
- import { randomUUID as randomUUID2 } from "crypto";
1061
1126
  async function ask(client, queryEngine, question, options, signal) {
1062
1127
  const tenantId = resolveTenantId4(client, options.tenantId);
1063
- const sessionId = randomUUID2();
1128
+ const sessionId = crypto.randomUUID();
1064
1129
  const maxRetry = options.maxRetry ?? 0;
1065
1130
  let attempt = 0;
1066
1131
  let lastError = options.lastError;