@deepagents/text2sql 6.1.2 → 7.0.0

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.
Files changed (38) hide show
  1. package/README.md +16 -1
  2. package/dist/index.js +1 -1
  3. package/dist/index.js.map +2 -2
  4. package/dist/lib/adapters/bigquery/index.js +87 -7
  5. package/dist/lib/adapters/bigquery/index.js.map +3 -3
  6. package/dist/lib/adapters/clickhouse/index.js +1 -1
  7. package/dist/lib/adapters/clickhouse/index.js.map +2 -2
  8. package/dist/lib/adapters/duckdb/duckdb-identifiers.d.ts +8 -0
  9. package/dist/lib/adapters/duckdb/duckdb-identifiers.d.ts.map +1 -0
  10. package/dist/lib/adapters/duckdb/duckdb.d.ts +40 -0
  11. package/dist/lib/adapters/duckdb/duckdb.d.ts.map +1 -0
  12. package/dist/lib/adapters/duckdb/duckdb.groundings.d.ts +58 -0
  13. package/dist/lib/adapters/duckdb/duckdb.groundings.d.ts.map +1 -0
  14. package/dist/lib/adapters/duckdb/duckdb.sql-policy.d.ts +8 -0
  15. package/dist/lib/adapters/duckdb/duckdb.sql-policy.d.ts.map +1 -0
  16. package/dist/lib/adapters/duckdb/index.d.ts +34 -0
  17. package/dist/lib/adapters/duckdb/index.d.ts.map +1 -0
  18. package/dist/lib/adapters/duckdb/index.js +1933 -0
  19. package/dist/lib/adapters/duckdb/index.js.map +7 -0
  20. package/dist/lib/adapters/mysql/index.js +87 -7
  21. package/dist/lib/adapters/mysql/index.js.map +3 -3
  22. package/dist/lib/adapters/parser-sql-policy.d.ts.map +1 -1
  23. package/dist/lib/adapters/postgres/index.js +87 -7
  24. package/dist/lib/adapters/postgres/index.js.map +3 -3
  25. package/dist/lib/adapters/postgres/postgres-parser-workaround.d.ts +8 -0
  26. package/dist/lib/adapters/postgres/postgres-parser-workaround.d.ts.map +1 -0
  27. package/dist/lib/adapters/posthog/index.js +1 -1
  28. package/dist/lib/adapters/posthog/index.js.map +2 -2
  29. package/dist/lib/adapters/spreadsheet/index.js +87 -7
  30. package/dist/lib/adapters/spreadsheet/index.js.map +3 -3
  31. package/dist/lib/adapters/sqlite/index.js +87 -7
  32. package/dist/lib/adapters/sqlite/index.js.map +3 -3
  33. package/dist/lib/adapters/sqlserver/index.js +87 -7
  34. package/dist/lib/adapters/sqlserver/index.js.map +3 -3
  35. package/dist/lib/agents/question.agent.d.ts.map +1 -1
  36. package/dist/lib/synthesis/extractors/base-contextual-extractor.d.ts.map +1 -1
  37. package/dist/lib/synthesis/index.js.map +2 -2
  38. package/package.json +18 -19
@@ -398,7 +398,7 @@ var Adapter = class {
398
398
  }
399
399
  }
400
400
  #decodeShellEscapes(sql) {
401
- return sql.replace(/\\n/g, "\n").replace(/\\t/g, " ").replace(/\\([().*])/g, "$1").replace(/\\(?=$)/gm, "");
401
+ return sql.replace(/\\n/g, "\n").replace(/\\t/g, " ").replace(/\\([().*$])/g, "$1").replace(/\\(?=$)/gm, "");
402
402
  }
403
403
  #cachedAllowedEntities = null;
404
404
  async #resolveScope() {
@@ -817,6 +817,71 @@ function buildScopeParseErrorPayload(sql, parserDialect, error) {
817
817
  };
818
818
  }
819
819
 
820
+ // packages/text2sql/src/lib/adapters/postgres/postgres-parser-workaround.ts
821
+ var TYPE_BEFORE_LITERAL = /(?<type>(?:pg_catalog\.)?[A-Za-z_][A-Za-z0-9_$]*(?:\s+(?:varying|precision))?(?:\s*\(\s*\d+(?:\s*,\s*\d+)?\s*\))?(?:\s+(?:with|without)\s+time\s+zone)?)\s*$/i;
822
+ var TIME_ZONE_SUFFIX = /^\s+time\s+zone\s+/i;
823
+ var TIME_BEFORE_SUFFIX = /(?<type>time(?:stamp)?(?:\s*\(\s*\d+\s*\))?)\s+(?<qualifier>with|without)$/i;
824
+ function recoverPostgresTypedLiteralParserGap(sql, error) {
825
+ const errorOffset = parserErrorOffset(error);
826
+ if (errorOffset === null) return null;
827
+ const prefix = sql.slice(0, errorOffset);
828
+ let literalStart = errorOffset;
829
+ let literalEnd = findLiteralEnd(sql, literalStart);
830
+ let typeMatch = TYPE_BEFORE_LITERAL.exec(prefix);
831
+ let type = typeMatch?.groups?.type;
832
+ if (literalEnd === null) {
833
+ const suffixMatch = TIME_ZONE_SUFFIX.exec(sql.slice(errorOffset));
834
+ typeMatch = TIME_BEFORE_SUFFIX.exec(prefix);
835
+ type = typeMatch?.groups?.type && typeMatch.groups.qualifier && suffixMatch ? `${typeMatch.groups.type} ${typeMatch.groups.qualifier} TIME ZONE` : void 0;
836
+ literalStart = errorOffset + (suffixMatch?.[0].length ?? 0);
837
+ literalEnd = findLiteralEnd(sql, literalStart);
838
+ }
839
+ if (!type || typeMatch?.index === void 0 || literalEnd === null)
840
+ return null;
841
+ return prefix.slice(0, typeMatch.index) + `CAST(${sql.slice(literalStart, literalEnd)} AS ${parserType(type)})` + sql.slice(literalEnd);
842
+ }
843
+ function parserErrorOffset(error) {
844
+ if (typeof error !== "object" || error === null) return null;
845
+ const location = Reflect.get(error, "location");
846
+ if (typeof location !== "object" || location === null) return null;
847
+ const start = Reflect.get(location, "start");
848
+ if (typeof start !== "object" || start === null) return null;
849
+ const offset = Reflect.get(start, "offset");
850
+ return typeof offset === "number" ? offset : null;
851
+ }
852
+ function findLiteralEnd(sql, start) {
853
+ if (sql[start] !== "'") {
854
+ const delimiter = /^\$(?:[A-Za-z_][A-Za-z0-9_]*)?\$/.exec(
855
+ sql.slice(start)
856
+ )?.[0];
857
+ if (!delimiter) return null;
858
+ const end = sql.indexOf(delimiter, start + delimiter.length);
859
+ return end === -1 ? null : end + delimiter.length;
860
+ }
861
+ let offset = start + 1;
862
+ while (offset < sql.length) {
863
+ if (sql[offset] === "\\") {
864
+ offset += 2;
865
+ continue;
866
+ }
867
+ if (sql[offset] !== "'") {
868
+ offset++;
869
+ continue;
870
+ }
871
+ if (sql[offset + 1] === "'") {
872
+ offset += 2;
873
+ continue;
874
+ }
875
+ return offset + 1;
876
+ }
877
+ return null;
878
+ }
879
+ function parserType(type) {
880
+ const unqualified = type.replace(/^pg_catalog\./i, "");
881
+ const timetz = /^timetz(\s*\([^)]*\))?$/i.exec(unqualified);
882
+ return timetz ? `TIME${timetz[1] ?? ""} WITH TIME ZONE` : unqualified;
883
+ }
884
+
820
885
  // packages/text2sql/src/lib/adapters/parser-sql-policy.ts
821
886
  var READ_ONLY_MESSAGE = "only SELECT or WITH queries allowed";
822
887
  var { Parser } = nodeSqlParser;
@@ -841,7 +906,7 @@ var ParserSqlPolicyAnalyzer = class {
841
906
  #readParsedStatements(sql) {
842
907
  for (const dialect of this.dialects) {
843
908
  try {
844
- return parseStatements(sql, dialect);
909
+ return this.#parseStatements(sql, dialect);
845
910
  } catch {
846
911
  }
847
912
  }
@@ -853,7 +918,7 @@ var ParserSqlPolicyAnalyzer = class {
853
918
  let lastDialect = this.dialects[0];
854
919
  for (const dialect of this.dialects) {
855
920
  try {
856
- references = extractBaseEntityReferences(sql, dialect);
921
+ references = extractBaseEntityReferences(this.#parseAst(sql, dialect));
857
922
  break;
858
923
  } catch (error) {
859
924
  lastDialect = dialect;
@@ -888,9 +953,25 @@ var ParserSqlPolicyAnalyzer = class {
888
953
  });
889
954
  return outOfScope.length === 0 ? null : buildOutOfScopePayload(sql, outOfScope, [...allowedEntities]);
890
955
  }
956
+ #parseStatements(sql, dialect) {
957
+ return parseStatements(this.#parseAst(sql, dialect));
958
+ }
959
+ #parseAst(sql, dialect) {
960
+ let parserSql = sql;
961
+ const attempted = /* @__PURE__ */ new Set([sql]);
962
+ while (true) {
963
+ try {
964
+ return parser.astify(parserSql, { database: dialect });
965
+ } catch (error) {
966
+ const recovered = dialect === "postgresql" ? recoverPostgresTypedLiteralParserGap(parserSql, error) : null;
967
+ if (!recovered || attempted.has(recovered)) throw error;
968
+ attempted.add(recovered);
969
+ parserSql = recovered;
970
+ }
971
+ }
972
+ }
891
973
  };
892
- function parseStatements(sql, dialect) {
893
- const ast = parser.astify(sql, { database: dialect });
974
+ function parseStatements(ast) {
894
975
  const statements = Array.isArray(ast) ? ast : [ast];
895
976
  return statements.filter(isAstLike);
896
977
  }
@@ -947,8 +1028,7 @@ function appendIdentifierParts(parts, value) {
947
1028
  ...value.toLowerCase().split(".").filter((part) => part.length > 0)
948
1029
  );
949
1030
  }
950
- function extractBaseEntityReferences(sql, dialect) {
951
- const ast = parser.astify(sql, { database: dialect });
1031
+ function extractBaseEntityReferences(ast) {
952
1032
  const state = {
953
1033
  cteNames: /* @__PURE__ */ new Set(),
954
1034
  references: /* @__PURE__ */ new Map()