agent-sql 0.2.2 → 0.2.3

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.d.mts CHANGED
@@ -15,10 +15,10 @@ type WhereGuard = GuardCol & {
15
15
  };
16
16
  type OneOrTwoDots<S extends string> = S extends `${infer A}.${infer B}.${infer C}` ? A extends `${string}.${string}` ? never : B extends `${string}.${string}` ? never : C extends `${string}.${string}` ? never : S : S extends `${infer A}.${infer B}` ? A extends `${string}.${string}` ? never : B extends `${string}.${string}` ? never : S : never;
17
17
  type SchemaGuardKeys<T> = { [Table in keyof T & string]: `${Table}.${keyof T[Table] & string}` }[keyof T & string];
18
- declare function applyGuards(ast: SelectStatement, guards: WhereGuard[], limit?: number): Result<SelectStatement>;
18
+ declare function applyGuards(ast: SelectStatement, guards: WhereGuard[], limit: number): Result<SelectStatement>;
19
19
  //#endregion
20
20
  //#region src/output.d.ts
21
- declare function outputSql(ast: SelectStatement): string;
21
+ declare function outputSql(ast: SelectStatement, pretty?: boolean): string;
22
22
  //#endregion
23
23
  //#region src/parse.d.ts
24
24
  declare function parseSql(expr: string): Result<SelectStatement>;
@@ -27,22 +27,26 @@ declare function parseSql(expr: string): Result<SelectStatement>;
27
27
  declare function agentSql<S extends string>(sql: string, column: S & OneOrTwoDots<S>, value: GuardVal, {
28
28
  schema,
29
29
  limit,
30
+ pretty,
30
31
  db,
31
32
  allowExtraFunctions
32
33
  }?: {
33
34
  schema?: Schema;
34
35
  limit?: number;
36
+ pretty?: boolean;
35
37
  db?: DbType;
36
38
  allowExtraFunctions?: string[];
37
39
  }): string;
38
40
  declare function createAgentSql<T extends Schema, S extends SchemaGuardKeys<T>>(schema: T, guards: Record<S, GuardVal>, opts: {
39
41
  limit?: number;
42
+ pretty?: boolean;
40
43
  throws: false;
41
44
  db?: DbType;
42
45
  allowExtraFunctions?: string[];
43
46
  }): (expr: string) => Result<string>;
44
47
  declare function createAgentSql<T extends Schema, S extends SchemaGuardKeys<T>>(schema: T, guards: Record<S, GuardVal>, opts?: {
45
48
  limit?: number;
49
+ pretty?: boolean;
46
50
  throws?: true;
47
51
  db?: DbType;
48
52
  allowExtraFunctions?: string[];
package/dist/index.mjs CHANGED
@@ -36,6 +36,7 @@ function returnOrThrow(result, throws) {
36
36
  }
37
37
  //#endregion
38
38
  //#region src/functions.ts
39
+ const DEFAULT_DB = "postgres";
39
40
  const COMMON_FUNCTIONS = [
40
41
  "count",
41
42
  "sum",
@@ -779,22 +780,24 @@ function unreachable(x) {
779
780
  }
780
781
  //#endregion
781
782
  //#region src/output.ts
782
- function outputSql(ast) {
783
- return normaliseWhitespace(r(ast));
783
+ function outputSql(ast, pretty = false) {
784
+ const res = r(ast, pretty);
785
+ if (pretty) return res;
786
+ return normaliseWhitespace(res);
784
787
  }
785
788
  function normaliseWhitespace(s) {
786
789
  return s.replace(/\s+/g, " ").trim();
787
790
  }
788
- function r(node) {
791
+ function r(node, pretty = false) {
789
792
  if (node === null || node === void 0) return "";
790
793
  if (typeof node === "string") return node;
791
794
  if (typeof node === "number") return String(node);
792
795
  switch (node.type) {
793
- case "select": return handleSelect(node);
796
+ case "select": return handleSelect(node, pretty);
794
797
  case "select_from": return handleSelectFrom(node);
795
- case "join": return handleJoin(node);
798
+ case "join": return handleJoin(node, pretty);
796
799
  case "join_on":
797
- case "join_using": return handleJoinCondition(node);
800
+ case "join_using": return handleJoinCondition(node, pretty);
798
801
  case "table_ref": return handleTableRef(node);
799
802
  case "limit": return handleLimit(node);
800
803
  case "offset": return handleOffset(node);
@@ -822,7 +825,7 @@ function r(node) {
822
825
  case "case_expr": return handleCaseExpr(node);
823
826
  case "cast_expr": return handleCastExpr(node);
824
827
  case "where_value": return handleWhereValue(node);
825
- case "column": return handleColumn(node);
828
+ case "column": return handleColumn(node, pretty);
826
829
  case "column_expr": return handleColumnExpr(node);
827
830
  case "column_ref": return handleColumnRef(node);
828
831
  case "alias": return handleAlias(node);
@@ -830,23 +833,37 @@ function r(node) {
830
833
  default: return unreachable(node);
831
834
  }
832
835
  }
833
- function mapR(t) {
834
- return t.map((n) => r(n).trim()).join(", ");
836
+ function rMap(t, pretty = false, sep = ", ") {
837
+ return t.map((n) => r(n, pretty).trimEnd()).join(sep);
835
838
  }
836
- function handleSelect(node) {
837
- const joins = node.joins.map((j) => r(j)).join(" ");
838
- return `SELECT ${node.distinct ? `${r(node.distinct)} ` : ""}${mapR(node.columns)} ${r(node.from)} ${joins} ${r(node.where)} ${r(node.groupBy)} ${r(node.having)} ${r(node.orderBy)} ${r(node.limit)} ${r(node.offset)}`;
839
+ function handleSelect(node, pretty) {
840
+ const distinctStr = node.distinct ? `${r(node.distinct)} ` : "";
841
+ const colSep = pretty ? ",\n" : ", ";
842
+ const joinSep = pretty ? "\n" : " ";
843
+ const joiner = pretty ? "\n" : " ";
844
+ return [
845
+ "SELECT",
846
+ `${distinctStr}${rMap(node.columns, pretty, colSep)}`,
847
+ r(node.from),
848
+ rMap(node.joins, pretty, joinSep),
849
+ r(node.where),
850
+ r(node.groupBy),
851
+ r(node.having),
852
+ r(node.orderBy),
853
+ r(node.limit),
854
+ r(node.offset)
855
+ ].join(joiner);
839
856
  }
840
857
  function handleDistinct(_node) {
841
858
  return "DISTINCT";
842
859
  }
843
860
  function handleDistinctOn(node) {
844
- return `DISTINCT ON (${mapR(node.columns)})`;
861
+ return `DISTINCT ON (${rMap(node.columns)})`;
845
862
  }
846
863
  function handleSelectFrom(node) {
847
864
  return `FROM ${r(node.table)}`;
848
865
  }
849
- function handleJoin(node) {
866
+ function handleJoin(node, pretty) {
850
867
  const typeStr = {
851
868
  inner: "INNER JOIN",
852
869
  inner_outer: "INNER OUTER JOIN",
@@ -859,12 +876,13 @@ function handleJoin(node) {
859
876
  cross: "CROSS JOIN",
860
877
  natural: "NATURAL JOIN"
861
878
  };
862
- const cond = node.condition ? ` ${handleJoinCondition(node.condition)}` : "";
879
+ const cond = node.condition ? `${handleJoinCondition(node.condition, pretty)}` : "";
863
880
  return `${typeStr[node.joinType]} ${r(node.table)}${cond}`;
864
881
  }
865
- function handleJoinCondition(node) {
866
- if (node.type === "join_on") return `ON ${r(node.expr)}`;
867
- return `USING (${node.columns.join(", ")})`;
882
+ function handleJoinCondition(node, pretty) {
883
+ const prefix = pretty ? "\n " : " ";
884
+ if (node.type === "join_on") return `${prefix}ON ${r(node.expr)}`;
885
+ return `${prefix}USING (${node.columns.join(", ")})`;
868
886
  }
869
887
  function handleLimit(node) {
870
888
  return `LIMIT ${node.value}`;
@@ -873,13 +891,13 @@ function handleOffset(node) {
873
891
  return `OFFSET ${node.value}`;
874
892
  }
875
893
  function handleGroupBy(node) {
876
- return `GROUP BY ${mapR(node.items)}`;
894
+ return `GROUP BY ${rMap(node.items)}`;
877
895
  }
878
896
  function handleHaving(node) {
879
897
  return `HAVING ${r(node.expr)}`;
880
898
  }
881
899
  function handleOrderBy(node) {
882
- return `ORDER BY ${mapR(node.items)}`;
900
+ return `ORDER BY ${rMap(node.items)}`;
883
901
  }
884
902
  function handleOrderByItem(node) {
885
903
  const dir = node.direction ? ` ${node.direction.toUpperCase()}` : "";
@@ -914,7 +932,7 @@ function handleWhereBetween(node) {
914
932
  return `${r(node.expr)}${node.not ? " NOT" : ""} BETWEEN ${r(node.low)} AND ${r(node.high)}`;
915
933
  }
916
934
  function handleWhereIn(node) {
917
- return `${r(node.expr)}${node.not ? " NOT" : ""} IN (${mapR(node.list)})`;
935
+ return `${r(node.expr)}${node.not ? " NOT" : ""} IN (${rMap(node.list)})`;
918
936
  }
919
937
  function handleCaseExpr(node) {
920
938
  return `CASE${node.subject ? ` ${r(node.subject)}` : ""} ${node.whens.map((w) => `WHEN ${r(w.condition)} THEN ${r(w.result)}`).join(" ")}${node.else ? ` ELSE ${r(node.else)}` : ""} END`;
@@ -959,8 +977,8 @@ function handleWhereValue(node) {
959
977
  default: return unreachable(node);
960
978
  }
961
979
  }
962
- function handleColumn(node) {
963
- return `${r(node.expr)} ${r(node.alias)}`;
980
+ function handleColumn(node, pretty) {
981
+ return `${pretty ? " " : ""}${r(node.expr)} ${r(node.alias)}`;
964
982
  }
965
983
  function handleAlias(node) {
966
984
  return `AS ${node.name}`;
@@ -972,7 +990,7 @@ function handleColumnRef(node) {
972
990
  function handleFuncCall(node) {
973
991
  const { name, args } = node;
974
992
  if (args.kind === "wildcard") return `${name}(*)`;
975
- return `${name}(${args.distinct ? "DISTINCT " : ""}${mapR(args.args)})`;
993
+ return `${name}(${args.distinct ? "DISTINCT " : ""}${rMap(args.args)})`;
976
994
  }
977
995
  function handleColumnExpr(node) {
978
996
  switch (node.kind) {
@@ -985,7 +1003,7 @@ function handleColumnExpr(node) {
985
1003
  //#endregion
986
1004
  //#region src/guard.ts
987
1005
  const DEFAULT_LIMIT = 1e4;
988
- function applyGuards(ast, guards, limit = DEFAULT_LIMIT) {
1006
+ function applyGuards(ast, guards, limit) {
989
1007
  const ast2 = addWhereGuard(ast, guards);
990
1008
  if (!ast2.ok) return ast2;
991
1009
  return addLimitGuard(ast2.data, limit);
@@ -7186,21 +7204,23 @@ function parseSql(expr) {
7186
7204
  }
7187
7205
  //#endregion
7188
7206
  //#region src/index.ts
7189
- function agentSql(sql, column, value, { schema, limit, db = "postgres", allowExtraFunctions = [] } = {}) {
7207
+ function agentSql(sql, column, value, { schema, limit = DEFAULT_LIMIT, pretty = false, db = DEFAULT_DB, allowExtraFunctions = [] } = {}) {
7190
7208
  return privateAgentSql(sql, {
7191
7209
  guards: { [column]: value },
7192
7210
  schema,
7193
7211
  limit,
7212
+ pretty,
7194
7213
  db,
7195
7214
  allowExtraFunctions,
7196
7215
  throws: true
7197
7216
  });
7198
7217
  }
7199
- function createAgentSql(schema, guards, { limit, throws = true, db = "postgres", allowExtraFunctions = [] } = {}) {
7218
+ function createAgentSql(schema, guards, { limit = DEFAULT_LIMIT, pretty = false, db = DEFAULT_DB, allowExtraFunctions = [], throws = true } = {}) {
7200
7219
  return (expr) => throws ? privateAgentSql(expr, {
7201
7220
  guards,
7202
7221
  schema,
7203
7222
  limit,
7223
+ pretty,
7204
7224
  db,
7205
7225
  allowExtraFunctions,
7206
7226
  throws
@@ -7208,12 +7228,13 @@ function createAgentSql(schema, guards, { limit, throws = true, db = "postgres",
7208
7228
  guards,
7209
7229
  schema,
7210
7230
  limit,
7231
+ pretty,
7211
7232
  db,
7212
7233
  allowExtraFunctions,
7213
7234
  throws
7214
7235
  });
7215
7236
  }
7216
- function privateAgentSql(sql, { guards: guardsRaw, schema, limit, db, allowExtraFunctions, throws }) {
7237
+ function privateAgentSql(sql, { guards: guardsRaw, schema, limit, pretty, db, allowExtraFunctions, throws }) {
7217
7238
  const guards = resolveGuards(guardsRaw);
7218
7239
  if (!guards.ok) throw guards.error;
7219
7240
  const ast = parseSql(sql);
@@ -7224,7 +7245,7 @@ function privateAgentSql(sql, { guards: guardsRaw, schema, limit, db, allowExtra
7224
7245
  if (!ast3.ok) return returnOrThrow(ast3, throws);
7225
7246
  const san = applyGuards(ast3.data, guards.data, limit);
7226
7247
  if (!san.ok) return returnOrThrow(san, throws);
7227
- const res = outputSql(san.data);
7248
+ const res = outputSql(san.data, pretty);
7228
7249
  if (throws) return res;
7229
7250
  return Ok(res);
7230
7251
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-sql",
3
- "version": "0.2.2",
3
+ "version": "0.2.3",
4
4
  "description": "A starter for creating a TypeScript package.",
5
5
  "keywords": [
6
6
  "agent",