joist-knex 2.3.0-next.7 → 2.3.0-next.71

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.
@@ -0,0 +1,23 @@
1
+ //#region \0rolldown/runtime.js
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __copyProps = (to, from, except, desc) => {
9
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
10
+ key = keys[i];
11
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
12
+ get: ((k) => from[k]).bind(null, key),
13
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
14
+ });
15
+ }
16
+ return to;
17
+ };
18
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule || !__hasOwnProp.call(mod, "default") ? __defProp(target, "default", {
19
+ value: mod,
20
+ enumerable: true
21
+ }) : target, mod));
22
+ //#endregion
23
+ exports.__toESM = __toESM;
@@ -0,0 +1,77 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_utils = require("./utils.cjs");
3
+ let joist_core = require("joist-core");
4
+ require("knex");
5
+ //#region src/buildKnexQuery.ts
6
+ /** Transforms Joist's internal `ParsedFindQuery` AST into a Knex query builder. */
7
+ function buildKnexQuery(knex$1, parsed, settings) {
8
+ const { limit, offset } = settings;
9
+ const needsDistinct = parsed.tables.some((t) => t.join === "outer" && t.distinct !== false);
10
+ const asRaw = (t) => knex$1.raw(`${(0, joist_core.kq)(t.table)} as ${(0, joist_core.kq)(t.alias)}`);
11
+ const primary = parsed.tables.find((t) => t.join === "primary");
12
+ let query = knex$1.from(asRaw(primary));
13
+ parsed.selects.forEach((s, i) => {
14
+ const maybeDistinct = i === 0 && needsDistinct ? "distinct " : "";
15
+ if (typeof s === "string") query.select(knex$1.raw(`${maybeDistinct}${s}`));
16
+ else if ("sql" in s) query.select(knex$1.raw(`${maybeDistinct}${s.sql}`, s.bindings));
17
+ });
18
+ parsed.tables.forEach((t) => {
19
+ switch (t.join) {
20
+ case "inner":
21
+ query.join(asRaw(t), knex$1.raw(t.col1), knex$1.raw(t.col2));
22
+ break;
23
+ case "outer":
24
+ query.leftOuterJoin(asRaw(t), knex$1.raw(t.col1), knex$1.raw(t.col2));
25
+ break;
26
+ case "primary": break;
27
+ case "lateral":
28
+ const { sql, bindings } = buildKnexQuery(knex$1, t.query, {}).toSQL();
29
+ query.crossJoin(knex$1.raw(`lateral (${sql}) as ${(0, joist_core.kq)(t.alias)}`, bindings));
30
+ break;
31
+ case "cross":
32
+ query.crossJoin(asRaw(t));
33
+ break;
34
+ default: require_utils.assertNever(t);
35
+ }
36
+ });
37
+ if (parsed.condition) {
38
+ const subqueryRenderer = (q) => {
39
+ const { sql, bindings } = buildKnexQuery(knex$1, q, {}).toSQL();
40
+ return {
41
+ sql,
42
+ bindings
43
+ };
44
+ };
45
+ const where = joist_core.internals.buildWhereClause(parsed.condition, true, subqueryRenderer);
46
+ if (where) {
47
+ const [sql, bindings] = where;
48
+ query.whereRaw(sql, bindings);
49
+ }
50
+ }
51
+ parsed.orderBys && parsed.orderBys.forEach(({ alias, column, order }) => {
52
+ if (needsDistinct) query.select(knex$1.raw((0, joist_core.kqDot)(alias, column)));
53
+ query.orderBy(knex$1.raw((0, joist_core.kqDot)(alias, column)), order);
54
+ });
55
+ parsed.groupBys && parsed.groupBys.forEach((groupBy) => {
56
+ query.groupByRaw("expression" in groupBy ? groupBy.expression : (0, joist_core.kqDot)(groupBy.alias, groupBy.column));
57
+ });
58
+ if (parsed.ctes && parsed.ctes.length > 0) for (let i = 0; i < parsed.ctes.length; i++) {
59
+ const cte = parsed.ctes[i];
60
+ const args = [cte.alias];
61
+ if (cte.columns && cte.columns.length > 0) args.push(cte.columns.map((c) => c.columnName));
62
+ if (cte.query.kind === "raw") {
63
+ args.push(knex$1.raw(cte.query.sql));
64
+ if (cte.query.bindings) args.push(cte.query.bindings);
65
+ } else if (cte.query.kind === "ast") args.push(buildKnexQuery(knex$1, cte.query.query, {}));
66
+ else require_utils.assertNever(cte.query);
67
+ if (cte.recursive) query.withRecursive(...args);
68
+ else query.with(...args);
69
+ }
70
+ if (limit) query.limit(limit);
71
+ if (offset) query.offset(offset);
72
+ return query;
73
+ }
74
+ //#endregion
75
+ exports.buildKnexQuery = buildKnexQuery;
76
+
77
+ //# sourceMappingURL=buildKnexQuery.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"buildKnexQuery.cjs","names":["knex","kq","internals","kqDot"],"sources":["../src/buildKnexQuery.ts"],"sourcesContent":["import { type ParsedFindQuery, type ParsedTable, internals, kq, kqDot } from \"joist-core\";\nimport { type Knex } from \"knex\";\n\nimport { assertNever } from \"./utils.ts\";\n\n/** Transforms Joist's internal `ParsedFindQuery` AST into a Knex query builder. */\nexport function buildKnexQuery(\n knex: Knex,\n parsed: ParsedFindQuery,\n settings: { limit?: number; offset?: number },\n): Knex.QueryBuilder<{}, unknown[]> {\n const { limit, offset } = settings;\n\n // If we're doing o2m joins, add a `DISTINCT` clause to avoid duplicates\n const needsDistinct = parsed.tables.some((t) => t.join === \"outer\" && t.distinct !== false);\n\n // We need the `knex` param to call `knex.raw`\n const asRaw = (t: ParsedTable) => knex.raw(`${kq(t.table)} as ${kq(t.alias)}`);\n\n const primary = parsed.tables.find((t) => t.join === \"primary\")!;\n\n let query: Knex.QueryBuilder<any, any> = knex.from(asRaw(primary));\n\n parsed.selects.forEach((s, i) => {\n const maybeDistinct = i === 0 && needsDistinct ? \"distinct \" : \"\";\n if (typeof s === \"string\") {\n query.select(knex.raw(`${maybeDistinct}${s}`));\n } else if (\"sql\" in s) {\n query.select(knex.raw(`${maybeDistinct}${s.sql}`, s.bindings));\n }\n });\n\n parsed.tables.forEach((t) => {\n switch (t.join) {\n case \"inner\":\n query.join(asRaw(t), knex.raw(t.col1) as any, knex.raw(t.col2));\n break;\n case \"outer\":\n query.leftOuterJoin(asRaw(t), knex.raw(t.col1) as any, knex.raw(t.col2));\n break;\n case \"primary\":\n // ignore\n break;\n case \"lateral\":\n const { sql, bindings } = buildKnexQuery(knex, t.query, {}).toSQL();\n query.crossJoin(knex.raw(`lateral (${sql}) as ${kq(t.alias)}`, bindings));\n break;\n case \"cross\":\n query.crossJoin(asRaw(t));\n break;\n default:\n assertNever(t);\n }\n });\n\n if (parsed.condition) {\n const subqueryRenderer = (q: ParsedFindQuery) => {\n const { sql, bindings } = buildKnexQuery(knex, q, {}).toSQL();\n return { sql, bindings };\n };\n const where = internals.buildWhereClause(parsed.condition, true, subqueryRenderer);\n if (where) {\n const [sql, bindings] = where;\n query.whereRaw(sql, bindings);\n }\n }\n\n parsed.orderBys &&\n parsed.orderBys.forEach(({ alias, column, order }) => {\n // If we're doing \"select distinct\" for o2m joins, then all order bys must be selects\n if (needsDistinct) {\n query.select(knex.raw(kqDot(alias, column)));\n }\n query.orderBy(knex.raw(kqDot(alias, column)) as any, order);\n });\n\n parsed.groupBys &&\n parsed.groupBys.forEach((groupBy) => {\n query.groupByRaw(\"expression\" in groupBy ? groupBy.expression : kqDot(groupBy.alias, groupBy.column));\n });\n\n if (parsed.ctes && parsed.ctes.length > 0) {\n for (let i = 0; i < parsed.ctes.length; i++) {\n const cte = parsed.ctes[i];\n const args: Parameters<(typeof query)[\"with\"]> = [cte.alias] as any;\n if (cte.columns && cte.columns.length > 0) args.push(cte.columns.map((c) => c.columnName) as any);\n if (cte.query.kind === \"raw\") {\n args.push(knex.raw(cte.query.sql) as any);\n if (cte.query.bindings) args.push(cte.query.bindings as any);\n } else if (cte.query.kind === \"ast\") {\n args.push(buildKnexQuery(knex, cte.query.query, {}) as any);\n } else {\n assertNever(cte.query);\n }\n if (cte.recursive) {\n query.withRecursive(...args);\n } else {\n query.with(...args);\n }\n }\n }\n\n if (limit) query.limit(limit);\n if (offset) query.offset(offset);\n\n return query;\n}\n"],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import { ParsedFindQuery } from "joist-core";
2
+ import { Knex } from "knex";
3
+ //#region src/buildKnexQuery.d.ts
4
+ /** Transforms Joist's internal `ParsedFindQuery` AST into a Knex query builder. */
5
+ declare function buildKnexQuery(knex: Knex, parsed: ParsedFindQuery, settings: {
6
+ limit?: number;
7
+ offset?: number;
8
+ }): Knex.QueryBuilder<{}, unknown[]>;
9
+ //#endregion
10
+ export { buildKnexQuery };
11
+ //# sourceMappingURL=buildKnexQuery.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"buildKnexQuery.d.cts","names":[],"sources":["../src/buildKnexQuery.ts"],"mappings":";;;;iBAMgB,eACd,MAAM,MACN,QAAQ,iBACR;EAAY;EAAgB;IAC3B,KAAK"}
@@ -0,0 +1,11 @@
1
+ import { ParsedFindQuery } from "joist-core";
2
+ import { Knex } from "knex";
3
+ //#region src/buildKnexQuery.d.ts
4
+ /** Transforms Joist's internal `ParsedFindQuery` AST into a Knex query builder. */
5
+ declare function buildKnexQuery(knex: Knex, parsed: ParsedFindQuery, settings: {
6
+ limit?: number;
7
+ offset?: number;
8
+ }): Knex.QueryBuilder<{}, unknown[]>;
9
+ //#endregion
10
+ export { buildKnexQuery };
11
+ //# sourceMappingURL=buildKnexQuery.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"buildKnexQuery.d.mts","names":[],"sources":["../src/buildKnexQuery.ts"],"mappings":";;;;iBAMgB,eACd,MAAM,MACN,QAAQ,iBACR;EAAY;EAAgB;IAC3B,KAAK"}
@@ -1,100 +1,76 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.buildKnexQuery = buildKnexQuery;
4
- const joist_core_1 = require("joist-core");
5
- const utils_1 = require("./utils");
1
+ import { assertNever } from "./utils.js";
2
+ import { internals, kq, kqDot } from "joist-core";
3
+ import "knex";
4
+ //#region src/buildKnexQuery.ts
6
5
  /** Transforms Joist's internal `ParsedFindQuery` AST into a Knex query builder. */
7
6
  function buildKnexQuery(knex, parsed, settings) {
8
- const { limit, offset } = settings;
9
- // If we're doing o2m joins, add a `DISTINCT` clause to avoid duplicates
10
- const needsDistinct = parsed.tables.some((t) => t.join === "outer" && t.distinct !== false);
11
- // We need the `knex` param to call `knex.raw`
12
- const asRaw = (t) => knex.raw(`${(0, joist_core_1.kq)(t.table)} as ${(0, joist_core_1.kq)(t.alias)}`);
13
- const primary = parsed.tables.find((t) => t.join === "primary");
14
- let query = knex.from(asRaw(primary));
15
- parsed.selects.forEach((s, i) => {
16
- const maybeDistinct = i === 0 && needsDistinct ? "distinct " : "";
17
- if (typeof s === "string") {
18
- query.select(knex.raw(`${maybeDistinct}${s}`));
19
- }
20
- else if ("sql" in s) {
21
- query.select(knex.raw(`${maybeDistinct}${s.sql}`, s.bindings));
22
- }
23
- });
24
- parsed.tables.forEach((t) => {
25
- switch (t.join) {
26
- case "inner":
27
- query.join(asRaw(t), knex.raw(t.col1), knex.raw(t.col2));
28
- break;
29
- case "outer":
30
- query.leftOuterJoin(asRaw(t), knex.raw(t.col1), knex.raw(t.col2));
31
- break;
32
- case "primary":
33
- // ignore
34
- break;
35
- case "lateral":
36
- const { sql, bindings } = buildKnexQuery(knex, t.query, {}).toSQL();
37
- query.crossJoin(knex.raw(`lateral (${sql}) as ${(0, joist_core_1.kq)(t.alias)}`, bindings));
38
- break;
39
- case "cross":
40
- query.crossJoin(asRaw(t));
41
- break;
42
- default:
43
- (0, utils_1.assertNever)(t);
44
- }
45
- });
46
- if (parsed.condition) {
47
- const subqueryRenderer = (q) => {
48
- const { sql, bindings } = buildKnexQuery(knex, q, {}).toSQL();
49
- return { sql, bindings };
50
- };
51
- const where = joist_core_1.internals.buildWhereClause(parsed.condition, true, subqueryRenderer);
52
- if (where) {
53
- const [sql, bindings] = where;
54
- query.whereRaw(sql, bindings);
55
- }
56
- }
57
- parsed.orderBys &&
58
- parsed.orderBys.forEach(({ alias, column, order }) => {
59
- // If we're doing "select distinct" for o2m joins, then all order bys must be selects
60
- if (needsDistinct) {
61
- query.select(knex.raw((0, joist_core_1.kqDot)(alias, column)));
62
- }
63
- query.orderBy(knex.raw((0, joist_core_1.kqDot)(alias, column)), order);
64
- });
65
- parsed.groupBys &&
66
- parsed.groupBys.forEach((groupBy) => {
67
- query.groupByRaw("expression" in groupBy ? groupBy.expression : (0, joist_core_1.kqDot)(groupBy.alias, groupBy.column));
68
- });
69
- if (parsed.ctes && parsed.ctes.length > 0) {
70
- for (let i = 0; i < parsed.ctes.length; i++) {
71
- const cte = parsed.ctes[i];
72
- const args = [cte.alias];
73
- if (cte.columns && cte.columns.length > 0)
74
- args.push(cte.columns.map((c) => c.columnName));
75
- if (cte.query.kind === "raw") {
76
- args.push(knex.raw(cte.query.sql));
77
- if (cte.query.bindings)
78
- args.push(cte.query.bindings);
79
- }
80
- else if (cte.query.kind === "ast") {
81
- args.push(buildKnexQuery(knex, cte.query.query, {}));
82
- }
83
- else {
84
- (0, utils_1.assertNever)(cte.query);
85
- }
86
- if (cte.recursive) {
87
- query.withRecursive(...args);
88
- }
89
- else {
90
- query.with(...args);
91
- }
92
- }
93
- }
94
- if (limit)
95
- query.limit(limit);
96
- if (offset)
97
- query.offset(offset);
98
- return query;
7
+ const { limit, offset } = settings;
8
+ const needsDistinct = parsed.tables.some((t) => t.join === "outer" && t.distinct !== false);
9
+ const asRaw = (t) => knex.raw(`${kq(t.table)} as ${kq(t.alias)}`);
10
+ const primary = parsed.tables.find((t) => t.join === "primary");
11
+ let query = knex.from(asRaw(primary));
12
+ parsed.selects.forEach((s, i) => {
13
+ const maybeDistinct = i === 0 && needsDistinct ? "distinct " : "";
14
+ if (typeof s === "string") query.select(knex.raw(`${maybeDistinct}${s}`));
15
+ else if ("sql" in s) query.select(knex.raw(`${maybeDistinct}${s.sql}`, s.bindings));
16
+ });
17
+ parsed.tables.forEach((t) => {
18
+ switch (t.join) {
19
+ case "inner":
20
+ query.join(asRaw(t), knex.raw(t.col1), knex.raw(t.col2));
21
+ break;
22
+ case "outer":
23
+ query.leftOuterJoin(asRaw(t), knex.raw(t.col1), knex.raw(t.col2));
24
+ break;
25
+ case "primary": break;
26
+ case "lateral":
27
+ const { sql, bindings } = buildKnexQuery(knex, t.query, {}).toSQL();
28
+ query.crossJoin(knex.raw(`lateral (${sql}) as ${kq(t.alias)}`, bindings));
29
+ break;
30
+ case "cross":
31
+ query.crossJoin(asRaw(t));
32
+ break;
33
+ default: assertNever(t);
34
+ }
35
+ });
36
+ if (parsed.condition) {
37
+ const subqueryRenderer = (q) => {
38
+ const { sql, bindings } = buildKnexQuery(knex, q, {}).toSQL();
39
+ return {
40
+ sql,
41
+ bindings
42
+ };
43
+ };
44
+ const where = internals.buildWhereClause(parsed.condition, true, subqueryRenderer);
45
+ if (where) {
46
+ const [sql, bindings] = where;
47
+ query.whereRaw(sql, bindings);
48
+ }
49
+ }
50
+ parsed.orderBys && parsed.orderBys.forEach(({ alias, column, order }) => {
51
+ if (needsDistinct) query.select(knex.raw(kqDot(alias, column)));
52
+ query.orderBy(knex.raw(kqDot(alias, column)), order);
53
+ });
54
+ parsed.groupBys && parsed.groupBys.forEach((groupBy) => {
55
+ query.groupByRaw("expression" in groupBy ? groupBy.expression : kqDot(groupBy.alias, groupBy.column));
56
+ });
57
+ if (parsed.ctes && parsed.ctes.length > 0) for (let i = 0; i < parsed.ctes.length; i++) {
58
+ const cte = parsed.ctes[i];
59
+ const args = [cte.alias];
60
+ if (cte.columns && cte.columns.length > 0) args.push(cte.columns.map((c) => c.columnName));
61
+ if (cte.query.kind === "raw") {
62
+ args.push(knex.raw(cte.query.sql));
63
+ if (cte.query.bindings) args.push(cte.query.bindings);
64
+ } else if (cte.query.kind === "ast") args.push(buildKnexQuery(knex, cte.query.query, {}));
65
+ else assertNever(cte.query);
66
+ if (cte.recursive) query.withRecursive(...args);
67
+ else query.with(...args);
68
+ }
69
+ if (limit) query.limit(limit);
70
+ if (offset) query.offset(offset);
71
+ return query;
99
72
  }
73
+ //#endregion
74
+ export { buildKnexQuery };
75
+
100
76
  //# sourceMappingURL=buildKnexQuery.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"buildKnexQuery.js","sourceRoot":"","sources":["../src/buildKnexQuery.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"buildKnexQuery.js","names":[],"sources":["../src/buildKnexQuery.ts"],"sourcesContent":["import { type ParsedFindQuery, type ParsedTable, internals, kq, kqDot } from \"joist-core\";\nimport { type Knex } from \"knex\";\n\nimport { assertNever } from \"./utils.ts\";\n\n/** Transforms Joist's internal `ParsedFindQuery` AST into a Knex query builder. */\nexport function buildKnexQuery(\n knex: Knex,\n parsed: ParsedFindQuery,\n settings: { limit?: number; offset?: number },\n): Knex.QueryBuilder<{}, unknown[]> {\n const { limit, offset } = settings;\n\n // If we're doing o2m joins, add a `DISTINCT` clause to avoid duplicates\n const needsDistinct = parsed.tables.some((t) => t.join === \"outer\" && t.distinct !== false);\n\n // We need the `knex` param to call `knex.raw`\n const asRaw = (t: ParsedTable) => knex.raw(`${kq(t.table)} as ${kq(t.alias)}`);\n\n const primary = parsed.tables.find((t) => t.join === \"primary\")!;\n\n let query: Knex.QueryBuilder<any, any> = knex.from(asRaw(primary));\n\n parsed.selects.forEach((s, i) => {\n const maybeDistinct = i === 0 && needsDistinct ? \"distinct \" : \"\";\n if (typeof s === \"string\") {\n query.select(knex.raw(`${maybeDistinct}${s}`));\n } else if (\"sql\" in s) {\n query.select(knex.raw(`${maybeDistinct}${s.sql}`, s.bindings));\n }\n });\n\n parsed.tables.forEach((t) => {\n switch (t.join) {\n case \"inner\":\n query.join(asRaw(t), knex.raw(t.col1) as any, knex.raw(t.col2));\n break;\n case \"outer\":\n query.leftOuterJoin(asRaw(t), knex.raw(t.col1) as any, knex.raw(t.col2));\n break;\n case \"primary\":\n // ignore\n break;\n case \"lateral\":\n const { sql, bindings } = buildKnexQuery(knex, t.query, {}).toSQL();\n query.crossJoin(knex.raw(`lateral (${sql}) as ${kq(t.alias)}`, bindings));\n break;\n case \"cross\":\n query.crossJoin(asRaw(t));\n break;\n default:\n assertNever(t);\n }\n });\n\n if (parsed.condition) {\n const subqueryRenderer = (q: ParsedFindQuery) => {\n const { sql, bindings } = buildKnexQuery(knex, q, {}).toSQL();\n return { sql, bindings };\n };\n const where = internals.buildWhereClause(parsed.condition, true, subqueryRenderer);\n if (where) {\n const [sql, bindings] = where;\n query.whereRaw(sql, bindings);\n }\n }\n\n parsed.orderBys &&\n parsed.orderBys.forEach(({ alias, column, order }) => {\n // If we're doing \"select distinct\" for o2m joins, then all order bys must be selects\n if (needsDistinct) {\n query.select(knex.raw(kqDot(alias, column)));\n }\n query.orderBy(knex.raw(kqDot(alias, column)) as any, order);\n });\n\n parsed.groupBys &&\n parsed.groupBys.forEach((groupBy) => {\n query.groupByRaw(\"expression\" in groupBy ? groupBy.expression : kqDot(groupBy.alias, groupBy.column));\n });\n\n if (parsed.ctes && parsed.ctes.length > 0) {\n for (let i = 0; i < parsed.ctes.length; i++) {\n const cte = parsed.ctes[i];\n const args: Parameters<(typeof query)[\"with\"]> = [cte.alias] as any;\n if (cte.columns && cte.columns.length > 0) args.push(cte.columns.map((c) => c.columnName) as any);\n if (cte.query.kind === \"raw\") {\n args.push(knex.raw(cte.query.sql) as any);\n if (cte.query.bindings) args.push(cte.query.bindings as any);\n } else if (cte.query.kind === \"ast\") {\n args.push(buildKnexQuery(knex, cte.query.query, {}) as any);\n } else {\n assertNever(cte.query);\n }\n if (cte.recursive) {\n query.withRecursive(...args);\n } else {\n query.with(...args);\n }\n }\n }\n\n if (limit) query.limit(limit);\n if (offset) query.offset(offset);\n\n return query;\n}\n"],"mappings":"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"}
@@ -0,0 +1,90 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_runtime = require("./_virtual/_rolldown/runtime.cjs");
3
+ const require_buildKnexQuery = require("./buildKnexQuery.cjs");
4
+ let joist_core = require("joist-core");
5
+ let knex = require("knex");
6
+ knex = require_runtime.__toESM(knex, 1);
7
+ let pg = require("pg");
8
+ pg = require_runtime.__toESM(pg, 1);
9
+ //#region src/index.ts
10
+ const { knex: baseCreateKnex } = knex.default;
11
+ /**
12
+ * Builds the Knex queries from `em.find`-style parameters.
13
+ *
14
+ * This is useful for the "last 5%" of SQL queries that require SQL features that `em.find`
15
+ * itself doesn't support, i.e. primarily aggregation, but also complicated joins. etc.
16
+ *
17
+ * You can also `buildQuery` to get the regular `em.find` niceties around great join syntax,
18
+ * join pruning, inline conditions, etc., but then take the `QueryBuilder` that it produces
19
+ * and "muck with it". I.e. add different order bys, group bys, etc.
20
+ *
21
+ * The Knex API is actually well-suited for this, as it provides structure-aware methods like
22
+ * `clearOrder`, `clearSelect`, etc. that mean you can munge the initial query without any
23
+ * complicated string parsing.
24
+ *
25
+ * @param knex The Knex instance to use for building the query.
26
+ * @param type The primary entity type that `filter` is based on.
27
+ * @param filter[keepAliases] Marks specific aliases to keep in the query, even if they are not used
28
+ * by any selects or conditions, i.e. because you plan on adding your own joins/conditions
29
+ * against the `QueryBuilder` directly.
30
+ * @param filter[pruneJoins] Disables removing any unused joins, i.e. because you plan on adding your
31
+ * own joins/conditions against the `QueryBuilder` directly.
32
+ * @param filter[allowMultipleLeftJoins] Allows multiple fanout LEFT JOINs when Joist cannot express
33
+ * an alias condition as EXISTS.
34
+ * @param filter[optimizeJoinsToExists] Disables rewriting collection joins into EXISTS, i.e. because
35
+ * you plan on adding selects/grouping against collection aliases after Joist builds the query.
36
+ */
37
+ function buildQuery(knex$2, type, filter) {
38
+ const meta = (0, joist_core.getMetadata)(type);
39
+ const { where, conditions, orderBy, limit, offset, pruneJoins = true, keepAliases = [], allowMultipleLeftJoins = false, optimizeJoinsToExists = true, softDeletes = "exclude" } = filter;
40
+ const parsed = (0, joist_core.parseFindQuery)(meta, where, {
41
+ conditions,
42
+ orderBy,
43
+ keepAliases,
44
+ softDeletes
45
+ });
46
+ (0, joist_core.optimizeCollectionJoins)(parsed, {
47
+ allowMultipleLeftJoins,
48
+ optimizeJoinsToExists,
49
+ pruneJoins,
50
+ keepAliases
51
+ });
52
+ return require_buildKnexQuery.buildKnexQuery(knex$2, parsed, {
53
+ limit,
54
+ offset
55
+ });
56
+ }
57
+ /**
58
+ * Creates a Knex instance that delegates to an existing pg Pool or PoolClient
59
+ * instead of managing its own internal connection pool.
60
+ *
61
+ * When given a `pg.Pool`, each knex query acquires a connection from the pool and
62
+ * releases it when the query completes.
63
+ *
64
+ * When given a `pg.PoolClient`, all knex queries run on that specific client. This
65
+ * is useful when the client has an open transaction (via `BEGIN`) — the knex queries
66
+ * will participate in that transaction and be affected by `COMMIT`/`ROLLBACK`.
67
+ *
68
+ * The returned Knex instance has no internal pool, so there is no need to call
69
+ * `.destroy()` on it — the caller owns the Pool/PoolClient lifecycle.
70
+ */
71
+ function createKnex(poolOrClient) {
72
+ const knex$3 = baseCreateKnex({
73
+ client: "pg",
74
+ connection: {},
75
+ pool: { max: 0 }
76
+ });
77
+ if (poolOrClient instanceof pg.default.Pool) {
78
+ knex$3.client.acquireConnection = () => poolOrClient.connect();
79
+ knex$3.client.releaseConnection = (conn) => conn.release();
80
+ } else {
81
+ knex$3.client.acquireConnection = () => poolOrClient;
82
+ knex$3.client.releaseConnection = () => {};
83
+ }
84
+ return knex$3;
85
+ }
86
+ //#endregion
87
+ exports.buildQuery = buildQuery;
88
+ exports.createKnex = createKnex;
89
+
90
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs","names":["getMetadata","parseFindQuery","buildKnexQuery","knex"],"sources":["../src/index.ts"],"sourcesContent":["import {\n type Entity,\n type FilterAndSettings,\n type MaybeAbstractEntityConstructor,\n getMetadata,\n optimizeCollectionJoins,\n parseFindQuery,\n} from \"joist-core\";\nimport knex, { type Knex } from \"knex\";\nimport pg from \"pg\";\n\nimport { buildKnexQuery } from \"./buildKnexQuery.ts\";\n\nconst { knex: baseCreateKnex } = knex;\n\n/**\n * Builds the Knex queries from `em.find`-style parameters.\n *\n * This is useful for the \"last 5%\" of SQL queries that require SQL features that `em.find`\n * itself doesn't support, i.e. primarily aggregation, but also complicated joins. etc.\n *\n * You can also `buildQuery` to get the regular `em.find` niceties around great join syntax,\n * join pruning, inline conditions, etc., but then take the `QueryBuilder` that it produces\n * and \"muck with it\". I.e. add different order bys, group bys, etc.\n *\n * The Knex API is actually well-suited for this, as it provides structure-aware methods like\n * `clearOrder`, `clearSelect`, etc. that mean you can munge the initial query without any\n * complicated string parsing.\n *\n * @param knex The Knex instance to use for building the query.\n * @param type The primary entity type that `filter` is based on.\n * @param filter[keepAliases] Marks specific aliases to keep in the query, even if they are not used\n * by any selects or conditions, i.e. because you plan on adding your own joins/conditions\n * against the `QueryBuilder` directly.\n * @param filter[pruneJoins] Disables removing any unused joins, i.e. because you plan on adding your\n * own joins/conditions against the `QueryBuilder` directly.\n * @param filter[allowMultipleLeftJoins] Allows multiple fanout LEFT JOINs when Joist cannot express\n * an alias condition as EXISTS.\n * @param filter[optimizeJoinsToExists] Disables rewriting collection joins into EXISTS, i.e. because\n * you plan on adding selects/grouping against collection aliases after Joist builds the query.\n */\nexport function buildQuery<T extends Entity>(\n knex: Knex,\n type: MaybeAbstractEntityConstructor<T>,\n filter: FilterAndSettings<T> & {\n pruneJoins?: boolean;\n keepAliases?: string[];\n allowMultipleLeftJoins?: boolean;\n optimizeJoinsToExists?: boolean;\n },\n): Knex.QueryBuilder<{}, unknown[]> {\n const meta = getMetadata(type);\n const {\n where,\n conditions,\n orderBy,\n limit,\n offset,\n pruneJoins = true,\n keepAliases = [],\n allowMultipleLeftJoins = false,\n optimizeJoinsToExists = true,\n softDeletes = \"exclude\",\n } = filter;\n const parsed = parseFindQuery(meta, where, {\n conditions,\n orderBy,\n keepAliases,\n softDeletes,\n });\n optimizeCollectionJoins(parsed, { allowMultipleLeftJoins, optimizeJoinsToExists, pruneJoins, keepAliases });\n return buildKnexQuery(knex, parsed, { limit, offset });\n}\n\n/**\n * Creates a Knex instance that delegates to an existing pg Pool or PoolClient\n * instead of managing its own internal connection pool.\n *\n * When given a `pg.Pool`, each knex query acquires a connection from the pool and\n * releases it when the query completes.\n *\n * When given a `pg.PoolClient`, all knex queries run on that specific client. This\n * is useful when the client has an open transaction (via `BEGIN`) — the knex queries\n * will participate in that transaction and be affected by `COMMIT`/`ROLLBACK`.\n *\n * The returned Knex instance has no internal pool, so there is no need to call\n * `.destroy()` on it — the caller owns the Pool/PoolClient lifecycle.\n */\nexport function createKnex(poolOrClient: pg.Pool | pg.PoolClient): Knex {\n const knex = baseCreateKnex({ client: \"pg\", connection: {}, pool: { max: 0 } });\n if (poolOrClient instanceof pg.Pool) {\n knex.client.acquireConnection = () => poolOrClient.connect();\n knex.client.releaseConnection = (conn: pg.PoolClient) => conn.release();\n } else {\n knex.client.acquireConnection = () => poolOrClient;\n knex.client.releaseConnection = () => {};\n }\n return knex;\n}\n"],"mappings":";;;;;;;;;AAaA,MAAM,EAAE,MAAM,mBAAmB,KAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4BjC,SAAgB,WACd,QACA,MACA,QAMkC;CAClC,MAAM,QAAA,GAAOA,WAAAA,YAAAA,CAAY,IAAI;CAC7B,MAAM,EACJ,OACA,YACA,SACA,OACA,QACA,aAAa,MACb,cAAc,CAAC,GACf,yBAAyB,OACzB,wBAAwB,MACxB,cAAc,cACZ;CACJ,MAAM,UAAA,GAASC,WAAAA,eAAAA,CAAe,MAAM,OAAO;EACzC;EACA;EACA;EACA;CACF,CAAC;CACD,CAAA,GAAA,WAAA,wBAAA,CAAwB,QAAQ;EAAE;EAAwB;EAAuB;EAAY;CAAY,CAAC;CAC1G,OAAOC,uBAAAA,eAAeC,QAAM,QAAQ;EAAE;EAAO;CAAO,CAAC;AACvD;;;;;;;;;;;;;;;AAgBA,SAAgB,WAAW,cAA6C;CACtE,MAAMA,SAAO,eAAe;EAAE,QAAQ;EAAM,YAAY,CAAC;EAAG,MAAM,EAAE,KAAK,EAAE;CAAE,CAAC;CAC9E,IAAI,wBAAwB,GAAA,QAAG,MAAM;EACnC,OAAK,OAAO,0BAA0B,aAAa,QAAQ;EAC3D,OAAK,OAAO,qBAAqB,SAAwB,KAAK,QAAQ;CACxE,OAAO;EACL,OAAK,OAAO,0BAA0B;EACtC,OAAK,OAAO,0BAA0B,CAAC;CACzC;CACA,OAAOA;AACT"}
@@ -1,6 +1,7 @@
1
1
  import { Entity, FilterAndSettings, MaybeAbstractEntityConstructor } from "joist-core";
2
2
  import { Knex } from "knex";
3
3
  import pg from "pg";
4
+ //#region src/index.d.ts
4
5
  /**
5
6
  * Builds the Knex queries from `em.find`-style parameters.
6
7
  *
@@ -27,11 +28,11 @@ import pg from "pg";
27
28
  * @param filter[optimizeJoinsToExists] Disables rewriting collection joins into EXISTS, i.e. because
28
29
  * you plan on adding selects/grouping against collection aliases after Joist builds the query.
29
30
  */
30
- export declare function buildQuery<T extends Entity>(knex: Knex, type: MaybeAbstractEntityConstructor<T>, filter: FilterAndSettings<T> & {
31
- pruneJoins?: boolean;
32
- keepAliases?: string[];
33
- allowMultipleLeftJoins?: boolean;
34
- optimizeJoinsToExists?: boolean;
31
+ declare function buildQuery<T extends Entity>(knex: Knex, type: MaybeAbstractEntityConstructor<T>, filter: FilterAndSettings<T> & {
32
+ pruneJoins?: boolean;
33
+ keepAliases?: string[];
34
+ allowMultipleLeftJoins?: boolean;
35
+ optimizeJoinsToExists?: boolean;
35
36
  }): Knex.QueryBuilder<{}, unknown[]>;
36
37
  /**
37
38
  * Creates a Knex instance that delegates to an existing pg Pool or PoolClient
@@ -47,5 +48,7 @@ export declare function buildQuery<T extends Entity>(knex: Knex, type: MaybeAbst
47
48
  * The returned Knex instance has no internal pool, so there is no need to call
48
49
  * `.destroy()` on it — the caller owns the Pool/PoolClient lifecycle.
49
50
  */
50
- export declare function createKnex(poolOrClient: pg.Pool | pg.PoolClient): Knex;
51
- //# sourceMappingURL=index.d.ts.map
51
+ declare function createKnex(poolOrClient: pg.Pool | pg.PoolClient): Knex;
52
+ //#endregion
53
+ export { buildQuery, createKnex };
54
+ //# sourceMappingURL=index.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.cts","names":[],"sources":["../src/index.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAyCgB,WAAW,UAAU,QACnC,MAAM,MACN,MAAM,+BAA+B,IACrC,QAAQ,kBAAkB;EACxB;EACA;EACA;EACA;IAED,KAAK;;;;;;;;;;;;;;;iBAsCQ,WAAW,cAAc,GAAG,OAAO,GAAG,aAAa"}
@@ -0,0 +1,54 @@
1
+ import { Entity, FilterAndSettings, MaybeAbstractEntityConstructor } from "joist-core";
2
+ import { Knex } from "knex";
3
+ import pg from "pg";
4
+ //#region src/index.d.ts
5
+ /**
6
+ * Builds the Knex queries from `em.find`-style parameters.
7
+ *
8
+ * This is useful for the "last 5%" of SQL queries that require SQL features that `em.find`
9
+ * itself doesn't support, i.e. primarily aggregation, but also complicated joins. etc.
10
+ *
11
+ * You can also `buildQuery` to get the regular `em.find` niceties around great join syntax,
12
+ * join pruning, inline conditions, etc., but then take the `QueryBuilder` that it produces
13
+ * and "muck with it". I.e. add different order bys, group bys, etc.
14
+ *
15
+ * The Knex API is actually well-suited for this, as it provides structure-aware methods like
16
+ * `clearOrder`, `clearSelect`, etc. that mean you can munge the initial query without any
17
+ * complicated string parsing.
18
+ *
19
+ * @param knex The Knex instance to use for building the query.
20
+ * @param type The primary entity type that `filter` is based on.
21
+ * @param filter[keepAliases] Marks specific aliases to keep in the query, even if they are not used
22
+ * by any selects or conditions, i.e. because you plan on adding your own joins/conditions
23
+ * against the `QueryBuilder` directly.
24
+ * @param filter[pruneJoins] Disables removing any unused joins, i.e. because you plan on adding your
25
+ * own joins/conditions against the `QueryBuilder` directly.
26
+ * @param filter[allowMultipleLeftJoins] Allows multiple fanout LEFT JOINs when Joist cannot express
27
+ * an alias condition as EXISTS.
28
+ * @param filter[optimizeJoinsToExists] Disables rewriting collection joins into EXISTS, i.e. because
29
+ * you plan on adding selects/grouping against collection aliases after Joist builds the query.
30
+ */
31
+ declare function buildQuery<T extends Entity>(knex: Knex, type: MaybeAbstractEntityConstructor<T>, filter: FilterAndSettings<T> & {
32
+ pruneJoins?: boolean;
33
+ keepAliases?: string[];
34
+ allowMultipleLeftJoins?: boolean;
35
+ optimizeJoinsToExists?: boolean;
36
+ }): Knex.QueryBuilder<{}, unknown[]>;
37
+ /**
38
+ * Creates a Knex instance that delegates to an existing pg Pool or PoolClient
39
+ * instead of managing its own internal connection pool.
40
+ *
41
+ * When given a `pg.Pool`, each knex query acquires a connection from the pool and
42
+ * releases it when the query completes.
43
+ *
44
+ * When given a `pg.PoolClient`, all knex queries run on that specific client. This
45
+ * is useful when the client has an open transaction (via `BEGIN`) — the knex queries
46
+ * will participate in that transaction and be affected by `COMMIT`/`ROLLBACK`.
47
+ *
48
+ * The returned Knex instance has no internal pool, so there is no need to call
49
+ * `.destroy()` on it — the caller owns the Pool/PoolClient lifecycle.
50
+ */
51
+ declare function createKnex(poolOrClient: pg.Pool | pg.PoolClient): Knex;
52
+ //#endregion
53
+ export { buildQuery, createKnex };
54
+ //# sourceMappingURL=index.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/index.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAyCgB,WAAW,UAAU,QACnC,MAAM,MACN,MAAM,+BAA+B,IACrC,QAAQ,kBAAkB;EACxB;EACA;EACA;EACA;IAED,KAAK;;;;;;;;;;;;;;;iBAsCQ,WAAW,cAAc,GAAG,OAAO,GAAG,aAAa"}
package/build/index.js CHANGED
@@ -1,76 +1,85 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.buildQuery = buildQuery;
7
- exports.createKnex = createKnex;
8
- const joist_core_1 = require("joist-core");
9
- const knex_1 = require("knex");
10
- const pg_1 = __importDefault(require("pg"));
11
- const buildKnexQuery_1 = require("./buildKnexQuery");
1
+ import { buildKnexQuery } from "./buildKnexQuery.js";
2
+ import { getMetadata, optimizeCollectionJoins, parseFindQuery } from "joist-core";
3
+ import knex from "knex";
4
+ import pg from "pg";
5
+ //#region src/index.ts
6
+ const { knex: baseCreateKnex } = knex;
12
7
  /**
13
- * Builds the Knex queries from `em.find`-style parameters.
14
- *
15
- * This is useful for the "last 5%" of SQL queries that require SQL features that `em.find`
16
- * itself doesn't support, i.e. primarily aggregation, but also complicated joins. etc.
17
- *
18
- * You can also `buildQuery` to get the regular `em.find` niceties around great join syntax,
19
- * join pruning, inline conditions, etc., but then take the `QueryBuilder` that it produces
20
- * and "muck with it". I.e. add different order bys, group bys, etc.
21
- *
22
- * The Knex API is actually well-suited for this, as it provides structure-aware methods like
23
- * `clearOrder`, `clearSelect`, etc. that mean you can munge the initial query without any
24
- * complicated string parsing.
25
- *
26
- * @param knex The Knex instance to use for building the query.
27
- * @param type The primary entity type that `filter` is based on.
28
- * @param filter[keepAliases] Marks specific aliases to keep in the query, even if they are not used
29
- * by any selects or conditions, i.e. because you plan on adding your own joins/conditions
30
- * against the `QueryBuilder` directly.
31
- * @param filter[pruneJoins] Disables removing any unused joins, i.e. because you plan on adding your
32
- * own joins/conditions against the `QueryBuilder` directly.
33
- * @param filter[allowMultipleLeftJoins] Allows multiple fanout LEFT JOINs when Joist cannot express
34
- * an alias condition as EXISTS.
35
- * @param filter[optimizeJoinsToExists] Disables rewriting collection joins into EXISTS, i.e. because
36
- * you plan on adding selects/grouping against collection aliases after Joist builds the query.
37
- */
8
+ * Builds the Knex queries from `em.find`-style parameters.
9
+ *
10
+ * This is useful for the "last 5%" of SQL queries that require SQL features that `em.find`
11
+ * itself doesn't support, i.e. primarily aggregation, but also complicated joins. etc.
12
+ *
13
+ * You can also `buildQuery` to get the regular `em.find` niceties around great join syntax,
14
+ * join pruning, inline conditions, etc., but then take the `QueryBuilder` that it produces
15
+ * and "muck with it". I.e. add different order bys, group bys, etc.
16
+ *
17
+ * The Knex API is actually well-suited for this, as it provides structure-aware methods like
18
+ * `clearOrder`, `clearSelect`, etc. that mean you can munge the initial query without any
19
+ * complicated string parsing.
20
+ *
21
+ * @param knex The Knex instance to use for building the query.
22
+ * @param type The primary entity type that `filter` is based on.
23
+ * @param filter[keepAliases] Marks specific aliases to keep in the query, even if they are not used
24
+ * by any selects or conditions, i.e. because you plan on adding your own joins/conditions
25
+ * against the `QueryBuilder` directly.
26
+ * @param filter[pruneJoins] Disables removing any unused joins, i.e. because you plan on adding your
27
+ * own joins/conditions against the `QueryBuilder` directly.
28
+ * @param filter[allowMultipleLeftJoins] Allows multiple fanout LEFT JOINs when Joist cannot express
29
+ * an alias condition as EXISTS.
30
+ * @param filter[optimizeJoinsToExists] Disables rewriting collection joins into EXISTS, i.e. because
31
+ * you plan on adding selects/grouping against collection aliases after Joist builds the query.
32
+ */
38
33
  function buildQuery(knex, type, filter) {
39
- const meta = (0, joist_core_1.getMetadata)(type);
40
- const { where, conditions, orderBy, limit, offset, pruneJoins = true, keepAliases = [], allowMultipleLeftJoins = false, optimizeJoinsToExists = true, softDeletes = "exclude", } = filter;
41
- const parsed = (0, joist_core_1.parseFindQuery)(meta, where, {
42
- conditions,
43
- orderBy,
44
- keepAliases,
45
- softDeletes,
46
- });
47
- (0, joist_core_1.optimizeCollectionJoins)(parsed, { allowMultipleLeftJoins, optimizeJoinsToExists, pruneJoins, keepAliases });
48
- return (0, buildKnexQuery_1.buildKnexQuery)(knex, parsed, { limit, offset });
34
+ const meta = getMetadata(type);
35
+ const { where, conditions, orderBy, limit, offset, pruneJoins = true, keepAliases = [], allowMultipleLeftJoins = false, optimizeJoinsToExists = true, softDeletes = "exclude" } = filter;
36
+ const parsed = parseFindQuery(meta, where, {
37
+ conditions,
38
+ orderBy,
39
+ keepAliases,
40
+ softDeletes
41
+ });
42
+ optimizeCollectionJoins(parsed, {
43
+ allowMultipleLeftJoins,
44
+ optimizeJoinsToExists,
45
+ pruneJoins,
46
+ keepAliases
47
+ });
48
+ return buildKnexQuery(knex, parsed, {
49
+ limit,
50
+ offset
51
+ });
49
52
  }
50
53
  /**
51
- * Creates a Knex instance that delegates to an existing pg Pool or PoolClient
52
- * instead of managing its own internal connection pool.
53
- *
54
- * When given a `pg.Pool`, each knex query acquires a connection from the pool and
55
- * releases it when the query completes.
56
- *
57
- * When given a `pg.PoolClient`, all knex queries run on that specific client. This
58
- * is useful when the client has an open transaction (via `BEGIN`) — the knex queries
59
- * will participate in that transaction and be affected by `COMMIT`/`ROLLBACK`.
60
- *
61
- * The returned Knex instance has no internal pool, so there is no need to call
62
- * `.destroy()` on it — the caller owns the Pool/PoolClient lifecycle.
63
- */
54
+ * Creates a Knex instance that delegates to an existing pg Pool or PoolClient
55
+ * instead of managing its own internal connection pool.
56
+ *
57
+ * When given a `pg.Pool`, each knex query acquires a connection from the pool and
58
+ * releases it when the query completes.
59
+ *
60
+ * When given a `pg.PoolClient`, all knex queries run on that specific client. This
61
+ * is useful when the client has an open transaction (via `BEGIN`) — the knex queries
62
+ * will participate in that transaction and be affected by `COMMIT`/`ROLLBACK`.
63
+ *
64
+ * The returned Knex instance has no internal pool, so there is no need to call
65
+ * `.destroy()` on it — the caller owns the Pool/PoolClient lifecycle.
66
+ */
64
67
  function createKnex(poolOrClient) {
65
- const knex = (0, knex_1.knex)({ client: "pg", connection: {}, pool: { max: 0 } });
66
- if (poolOrClient instanceof pg_1.default.Pool) {
67
- knex.client.acquireConnection = () => poolOrClient.connect();
68
- knex.client.releaseConnection = (conn) => conn.release();
69
- }
70
- else {
71
- knex.client.acquireConnection = () => poolOrClient;
72
- knex.client.releaseConnection = () => { };
73
- }
74
- return knex;
68
+ const knex = baseCreateKnex({
69
+ client: "pg",
70
+ connection: {},
71
+ pool: { max: 0 }
72
+ });
73
+ if (poolOrClient instanceof pg.Pool) {
74
+ knex.client.acquireConnection = () => poolOrClient.connect();
75
+ knex.client.releaseConnection = (conn) => conn.release();
76
+ } else {
77
+ knex.client.acquireConnection = () => poolOrClient;
78
+ knex.client.releaseConnection = () => {};
79
+ }
80
+ return knex;
75
81
  }
82
+ //#endregion
83
+ export { buildQuery, createKnex };
84
+
76
85
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;AAsCA,gCA+BC;AAgBD,gCAUC;AA/FD,2CAOoB;AACpB,+BAAoD;AACpD,4CAAoB;AACpB,qDAAkD;AAElD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,SAAgB,UAAU,CACxB,IAAU,EACV,IAAuC,EACvC,MAKC;IAED,MAAM,IAAI,GAAG,IAAA,wBAAW,EAAC,IAAI,CAAC,CAAC;IAC/B,MAAM,EACJ,KAAK,EACL,UAAU,EACV,OAAO,EACP,KAAK,EACL,MAAM,EACN,UAAU,GAAG,IAAI,EACjB,WAAW,GAAG,EAAE,EAChB,sBAAsB,GAAG,KAAK,EAC9B,qBAAqB,GAAG,IAAI,EAC5B,WAAW,GAAG,SAAS,GACxB,GAAG,MAAM,CAAC;IACX,MAAM,MAAM,GAAG,IAAA,2BAAc,EAAC,IAAI,EAAE,KAAK,EAAE;QACzC,UAAU;QACV,OAAO;QACP,WAAW;QACX,WAAW;KACZ,CAAC,CAAC;IACH,IAAA,oCAAuB,EAAC,MAAM,EAAE,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,UAAU,EAAE,WAAW,EAAE,CAAC,CAAC;IAC5G,OAAO,IAAA,+BAAc,EAAC,IAAI,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;AACzD,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,SAAgB,UAAU,CAAC,YAAqC;IAC9D,MAAM,IAAI,GAAG,IAAA,WAAc,EAAC,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;IAChF,IAAI,YAAY,YAAY,YAAE,CAAC,IAAI,EAAE,CAAC;QACpC,IAAI,CAAC,MAAM,CAAC,iBAAiB,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,CAAC;QAC7D,IAAI,CAAC,MAAM,CAAC,iBAAiB,GAAG,CAAC,IAAmB,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;IAC1E,CAAC;SAAM,CAAC;QACN,IAAI,CAAC,MAAM,CAAC,iBAAiB,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC;QACnD,IAAI,CAAC,MAAM,CAAC,iBAAiB,GAAG,GAAG,EAAE,GAAE,CAAC,CAAC;IAC3C,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["import {\n type Entity,\n type FilterAndSettings,\n type MaybeAbstractEntityConstructor,\n getMetadata,\n optimizeCollectionJoins,\n parseFindQuery,\n} from \"joist-core\";\nimport knex, { type Knex } from \"knex\";\nimport pg from \"pg\";\n\nimport { buildKnexQuery } from \"./buildKnexQuery.ts\";\n\nconst { knex: baseCreateKnex } = knex;\n\n/**\n * Builds the Knex queries from `em.find`-style parameters.\n *\n * This is useful for the \"last 5%\" of SQL queries that require SQL features that `em.find`\n * itself doesn't support, i.e. primarily aggregation, but also complicated joins. etc.\n *\n * You can also `buildQuery` to get the regular `em.find` niceties around great join syntax,\n * join pruning, inline conditions, etc., but then take the `QueryBuilder` that it produces\n * and \"muck with it\". I.e. add different order bys, group bys, etc.\n *\n * The Knex API is actually well-suited for this, as it provides structure-aware methods like\n * `clearOrder`, `clearSelect`, etc. that mean you can munge the initial query without any\n * complicated string parsing.\n *\n * @param knex The Knex instance to use for building the query.\n * @param type The primary entity type that `filter` is based on.\n * @param filter[keepAliases] Marks specific aliases to keep in the query, even if they are not used\n * by any selects or conditions, i.e. because you plan on adding your own joins/conditions\n * against the `QueryBuilder` directly.\n * @param filter[pruneJoins] Disables removing any unused joins, i.e. because you plan on adding your\n * own joins/conditions against the `QueryBuilder` directly.\n * @param filter[allowMultipleLeftJoins] Allows multiple fanout LEFT JOINs when Joist cannot express\n * an alias condition as EXISTS.\n * @param filter[optimizeJoinsToExists] Disables rewriting collection joins into EXISTS, i.e. because\n * you plan on adding selects/grouping against collection aliases after Joist builds the query.\n */\nexport function buildQuery<T extends Entity>(\n knex: Knex,\n type: MaybeAbstractEntityConstructor<T>,\n filter: FilterAndSettings<T> & {\n pruneJoins?: boolean;\n keepAliases?: string[];\n allowMultipleLeftJoins?: boolean;\n optimizeJoinsToExists?: boolean;\n },\n): Knex.QueryBuilder<{}, unknown[]> {\n const meta = getMetadata(type);\n const {\n where,\n conditions,\n orderBy,\n limit,\n offset,\n pruneJoins = true,\n keepAliases = [],\n allowMultipleLeftJoins = false,\n optimizeJoinsToExists = true,\n softDeletes = \"exclude\",\n } = filter;\n const parsed = parseFindQuery(meta, where, {\n conditions,\n orderBy,\n keepAliases,\n softDeletes,\n });\n optimizeCollectionJoins(parsed, { allowMultipleLeftJoins, optimizeJoinsToExists, pruneJoins, keepAliases });\n return buildKnexQuery(knex, parsed, { limit, offset });\n}\n\n/**\n * Creates a Knex instance that delegates to an existing pg Pool or PoolClient\n * instead of managing its own internal connection pool.\n *\n * When given a `pg.Pool`, each knex query acquires a connection from the pool and\n * releases it when the query completes.\n *\n * When given a `pg.PoolClient`, all knex queries run on that specific client. This\n * is useful when the client has an open transaction (via `BEGIN`) — the knex queries\n * will participate in that transaction and be affected by `COMMIT`/`ROLLBACK`.\n *\n * The returned Knex instance has no internal pool, so there is no need to call\n * `.destroy()` on it — the caller owns the Pool/PoolClient lifecycle.\n */\nexport function createKnex(poolOrClient: pg.Pool | pg.PoolClient): Knex {\n const knex = baseCreateKnex({ client: \"pg\", connection: {}, pool: { max: 0 } });\n if (poolOrClient instanceof pg.Pool) {\n knex.client.acquireConnection = () => poolOrClient.connect();\n knex.client.releaseConnection = (conn: pg.PoolClient) => conn.release();\n } else {\n knex.client.acquireConnection = () => poolOrClient;\n knex.client.releaseConnection = () => {};\n }\n return knex;\n}\n"],"mappings":";;;;;AAaA,MAAM,EAAE,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4BjC,SAAgB,WACd,MACA,MACA,QAMkC;CAClC,MAAM,OAAO,YAAY,IAAI;CAC7B,MAAM,EACJ,OACA,YACA,SACA,OACA,QACA,aAAa,MACb,cAAc,CAAC,GACf,yBAAyB,OACzB,wBAAwB,MACxB,cAAc,cACZ;CACJ,MAAM,SAAS,eAAe,MAAM,OAAO;EACzC;EACA;EACA;EACA;CACF,CAAC;CACD,wBAAwB,QAAQ;EAAE;EAAwB;EAAuB;EAAY;CAAY,CAAC;CAC1G,OAAO,eAAe,MAAM,QAAQ;EAAE;EAAO;CAAO,CAAC;AACvD;;;;;;;;;;;;;;;AAgBA,SAAgB,WAAW,cAA6C;CACtE,MAAM,OAAO,eAAe;EAAE,QAAQ;EAAM,YAAY,CAAC;EAAG,MAAM,EAAE,KAAK,EAAE;CAAE,CAAC;CAC9E,IAAI,wBAAwB,GAAG,MAAM;EACnC,KAAK,OAAO,0BAA0B,aAAa,QAAQ;EAC3D,KAAK,OAAO,qBAAqB,SAAwB,KAAK,QAAQ;CACxE,OAAO;EACL,KAAK,OAAO,0BAA0B;EACtC,KAAK,OAAO,0BAA0B,CAAC;CACzC;CACA,OAAO;AACT"}
@@ -0,0 +1,9 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ //#region src/utils.ts
3
+ function assertNever(x) {
4
+ throw new Error("Unexpected object: " + x);
5
+ }
6
+ //#endregion
7
+ exports.assertNever = assertNever;
8
+
9
+ //# sourceMappingURL=utils.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.cjs","names":[],"sources":["../src/utils.ts"],"sourcesContent":["export function assertNever(x: never): never {\n throw new Error(\"Unexpected object: \" + x);\n}\n"],"mappings":";;AAAA,SAAgB,YAAY,GAAiB;CAC3C,MAAM,IAAI,MAAM,wBAAwB,CAAC;AAC3C"}
@@ -0,0 +1,5 @@
1
+ //#region src/utils.d.ts
2
+ declare function assertNever(x: never): never;
3
+ //#endregion
4
+ export { assertNever };
5
+ //# sourceMappingURL=utils.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.cts","names":[],"sources":["../src/utils.ts"],"mappings":";iBAAgB,YAAY"}
@@ -0,0 +1,5 @@
1
+ //#region src/utils.d.ts
2
+ declare function assertNever(x: never): never;
3
+ //#endregion
4
+ export { assertNever };
5
+ //# sourceMappingURL=utils.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.mts","names":[],"sources":["../src/utils.ts"],"mappings":";iBAAgB,YAAY"}
package/build/utils.js CHANGED
@@ -1,7 +1,8 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.assertNever = assertNever;
1
+ //#region src/utils.ts
4
2
  function assertNever(x) {
5
- throw new Error("Unexpected object: " + x);
3
+ throw new Error("Unexpected object: " + x);
6
4
  }
5
+ //#endregion
6
+ export { assertNever };
7
+
7
8
  //# sourceMappingURL=utils.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":";;AAAA,kCAEC;AAFD,SAAgB,WAAW,CAAC,CAAQ;IAClC,MAAM,IAAI,KAAK,CAAC,qBAAqB,GAAG,CAAC,CAAC,CAAC;AAC7C,CAAC"}
1
+ {"version":3,"file":"utils.js","names":[],"sources":["../src/utils.ts"],"sourcesContent":["export function assertNever(x: never): never {\n throw new Error(\"Unexpected object: \" + x);\n}\n"],"mappings":";AAAA,SAAgB,YAAY,GAAiB;CAC3C,MAAM,IAAI,MAAM,wBAAwB,CAAC;AAC3C"}
package/package.json CHANGED
@@ -1,35 +1,52 @@
1
1
  {
2
2
  "name": "joist-knex",
3
- "version": "2.3.0-next.7",
3
+ "version": "2.3.0-next.71",
4
4
  "license": "MIT",
5
+ "type": "module",
5
6
  "repository": {
6
7
  "type": "git",
7
8
  "url": "https://github.com/joist-orm/joist-orm.git",
8
9
  "directory": "packages/knex"
9
10
  },
10
- "main": "build/index.js",
11
- "types": "build/index.d.ts",
12
- "scripts": {
13
- "format": "prettier --ignore-path ../../.prettierignore --write '{schema,migrations,src}/**/*.{ts,js,tsx,jsx,graphql}'"
11
+ "main": "build/index.cjs",
12
+ "module": "build/index.js",
13
+ "types": "build/index.d.mts",
14
+ "exports": {
15
+ ".": {
16
+ "bun": {
17
+ "types": "./build/index.d.mts",
18
+ "default": "./build/index.js"
19
+ },
20
+ "module-sync": {
21
+ "types": "./build/index.d.mts",
22
+ "default": "./build/index.js"
23
+ },
24
+ "import": {
25
+ "types": "./build/index.d.mts",
26
+ "default": "./build/index.js"
27
+ },
28
+ "require": {
29
+ "types": "./build/index.d.cts",
30
+ "default": "./build/index.cjs"
31
+ },
32
+ "default": "./build/index.js"
33
+ }
14
34
  },
15
35
  "files": [
16
36
  "build"
17
37
  ],
18
38
  "peerDependencies": {
19
- "joist-core": "2.3.0-next.7",
39
+ "joist-core": "2.3.0-next.71",
20
40
  "knex": "^3.1.0",
21
- "pg": "^8.22.0"
41
+ "pg": "^8.23.0"
22
42
  },
23
43
  "devDependencies": {
24
- "@swc/core": "^1.15.43",
44
+ "@swc/core": "^1.16.1",
25
45
  "@swc/jest": "^0.2.39",
26
46
  "@types/jest": "^30.0.0",
27
- "@types/node": "^26.0.1",
47
+ "@types/node": "^26.2.0",
28
48
  "jest": "30.4.2",
29
- "prettier": "^3.8.4",
30
- "prettier-plugin-organize-imports": "^4.3.0",
31
- "ts-node-dev": "^2.0.0",
32
49
  "tsconfig-paths": "^4.2.0",
33
- "typescript": "6.0.3"
50
+ "typescript": "7.0.2"
34
51
  }
35
52
  }
@@ -1,9 +0,0 @@
1
- import { ParsedFindQuery } from "joist-core";
2
- import { Knex } from "knex";
3
- import QueryBuilder = Knex.QueryBuilder;
4
- /** Transforms Joist's internal `ParsedFindQuery` AST into a Knex query builder. */
5
- export declare function buildKnexQuery(knex: Knex, parsed: ParsedFindQuery, settings: {
6
- limit?: number;
7
- offset?: number;
8
- }): QueryBuilder<{}, unknown[]>;
9
- //# sourceMappingURL=buildKnexQuery.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"buildKnexQuery.d.ts","sourceRoot":"","sources":["../src/buildKnexQuery.ts"],"names":[],"mappings":"AAAA,OAAO,EAAwB,eAAe,EAAe,MAAM,YAAY,CAAC;AAChF,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE5B,OAAO,YAAY,GAAG,IAAI,CAAC,YAAY,CAAC;AAExC,mFAAmF;AACnF,wBAAgB,cAAc,CAC5B,IAAI,EAAE,IAAI,EACV,MAAM,EAAE,eAAe,EACvB,QAAQ,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GAC5C,YAAY,CAAC,EAAE,EAAE,OAAO,EAAE,CAAC,CAgG7B"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,MAAM,EACN,iBAAiB,EAEjB,8BAA8B,EAG/B,MAAM,YAAY,CAAC;AACpB,OAAO,EAA0B,IAAI,EAAE,MAAM,MAAM,CAAC;AACpD,OAAO,EAAE,MAAM,IAAI,CAAC;AAGpB;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,UAAU,CAAC,CAAC,SAAS,MAAM,EACzC,IAAI,EAAE,IAAI,EACV,IAAI,EAAE,8BAA8B,CAAC,CAAC,CAAC,EACvC,MAAM,EAAE,iBAAiB,CAAC,CAAC,CAAC,GAAG;IAC7B,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,qBAAqB,CAAC,EAAE,OAAO,CAAC;CACjC,GACA,IAAI,CAAC,YAAY,CAAC,EAAE,EAAE,OAAO,EAAE,CAAC,CAsBlC;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,UAAU,CAAC,YAAY,EAAE,EAAE,CAAC,IAAI,GAAG,EAAE,CAAC,UAAU,GAAG,IAAI,CAUtE"}
package/build/utils.d.ts DELETED
@@ -1,2 +0,0 @@
1
- export declare function assertNever(x: never): never;
2
- //# sourceMappingURL=utils.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,wBAAgB,WAAW,CAAC,CAAC,EAAE,KAAK,GAAG,KAAK,CAE3C"}