joist-driver-bun-pg 2.3.0 → 2.4.0-next.2

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,96 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ let bun = require("bun");
3
+ let joist_core = require("joist-core");
4
+ //#region src/BunPgDriver.ts
5
+ const { getRuntimeConfig, cleanSql, generateOps } = joist_core.driverApi;
6
+ /** Incomplete Bun SQL driver; raw-query execution is not implemented. */
7
+ var BunPgDriver = class {
8
+ #idAssigner;
9
+ #sql;
10
+ constructor(_sql = bun.sql) {
11
+ this.#sql = _sql;
12
+ this.#idAssigner = new joist_core.SequenceIdAssigner((s) => this.#sql.unsafe(s));
13
+ }
14
+ executeFind(em, parsed, settings) {
15
+ throw new Error("Method not implemented.");
16
+ }
17
+ executeQuery(em, sql, bindings) {
18
+ throw new Error("BunPgDriver.executeQuery is not implemented; em.query and em.execute are unsupported.");
19
+ }
20
+ async transaction(em, fn) {
21
+ if (em.txn) return fn(em.txn);
22
+ else {
23
+ await (0, joist_core.driverBeforeBegin)(em, this.#sql);
24
+ const result = await this.#sql.begin(async (txn) => {
25
+ em.txn = txn;
26
+ try {
27
+ await (0, joist_core.driverAfterBegin)(em, txn);
28
+ const result = await fn(txn);
29
+ await (0, joist_core.driverBeforeCommit)(em, txn);
30
+ return result;
31
+ } finally {
32
+ em.txn = void 0;
33
+ }
34
+ });
35
+ await (0, joist_core.driverAfterCommit)(em, this.#sql);
36
+ return result;
37
+ }
38
+ }
39
+ assignNewIds(em, todos) {
40
+ throw new Error("Method not implemented.");
41
+ }
42
+ async flush(em, todos, joinRows) {
43
+ const sql = em.txn ?? (0, joist_core.fail)("Expected EntityManager.txn to be set");
44
+ await this.#idAssigner.assignNewIds(todos);
45
+ const ops = generateOps(todos);
46
+ await Promise.all([
47
+ ...ops.inserts.map((op) => batchInsert(sql, op)),
48
+ ...ops.updates.map((op) => batchUpdate(sql, op)),
49
+ ...ops.deletes.map((op) => batchDelete(sql, op))
50
+ ]);
51
+ }
52
+ get defaultPlugins() {
53
+ return {};
54
+ }
55
+ };
56
+ function batchInsert(txn, op) {
57
+ const { tableName, columns, columnValues } = op;
58
+ const { sql: cte, bindings } = (0, joist_core.buildCteSql)((0, joist_core.buildUnnestCte)("data", columns, columnValues));
59
+ return convertToSql(txn, cleanSql(`
60
+ ${cte}
61
+ INSERT INTO ${(0, joist_core.kq)(tableName)} (${columns.map((c) => (0, joist_core.kq)(c.columnName)).join(", ")})
62
+ SELECT * FROM data
63
+ `), bindings);
64
+ }
65
+ async function batchUpdate(txn, op) {
66
+ const { tableName, columns, columnValues, updatedAt } = op;
67
+ const { sql: cte, bindings } = (0, joist_core.buildCteSql)((0, joist_core.buildUnnestCte)("data", columns, columnValues));
68
+ const truncateToMills = !getRuntimeConfig().temporal;
69
+ const maybeUpdatedAt = updatedAt && truncateToMills ? ` AND date_trunc('milliseconds', ${(0, joist_core.kqDot)(tableName, updatedAt)}) = data.__original_updated_at` : updatedAt ? ` AND ${(0, joist_core.kqDot)(tableName, updatedAt)} = data.__original_updated_at` : "";
70
+ const results = await convertToSql(txn, `
71
+ ${cte}
72
+ UPDATE ${(0, joist_core.kq)(tableName)}
73
+ SET ${columns.filter((c) => c.columnName !== "id" && c.columnName !== "__original_updated_at").map((c) => `${(0, joist_core.kq)(c.columnName)} = data.${(0, joist_core.kq)(c.columnName)}`).join(", ")}
74
+ FROM data
75
+ WHERE ${(0, joist_core.kq)(tableName)}.id = data.id ${maybeUpdatedAt}
76
+ RETURNING ${(0, joist_core.kq)(tableName)}.id
77
+ `, bindings);
78
+ const ids = columnValues[0];
79
+ if (results.length !== ids.length) {
80
+ const updated = new Set(results.map((r) => r.id));
81
+ const missing = ids.filter((id) => !updated.has(id));
82
+ throw new Error(`Oplock failure for ${tableName} rows ${missing.join(", ")}`);
83
+ }
84
+ }
85
+ async function batchDelete(txn, op) {
86
+ const { tableName, ids } = op;
87
+ }
88
+ function convertToSql(sql, query, bindings) {
89
+ const fragments = query.split("?");
90
+ if (fragments.length - 1 !== bindings.length) throw new Error(`Mismatch between placeholders (${fragments.length - 1}) and bindings (${bindings.length})`);
91
+ return sql(Object.assign(fragments, { raw: fragments }), ...bindings);
92
+ }
93
+ //#endregion
94
+ exports.BunPgDriver = BunPgDriver;
95
+
96
+ //# sourceMappingURL=BunPgDriver.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BunPgDriver.cjs","names":["driverApi","#idAssigner","#sql","sql","SequenceIdAssigner","driverBeforeBegin","driverAfterBegin","driverBeforeCommit","driverAfterCommit","fail","buildCteSql","buildUnnestCte","kq","kqDot"],"sources":["../src/BunPgDriver.ts"],"sourcesContent":["import { type SQL, type SQLQuery, type TransactionSQL, sql } from \"bun\";\nimport {\n type Driver,\n type DriverQueryResult,\n type EntityManager,\n type IdAssigner,\n type JoinRowTodo,\n type ParsedFindQuery,\n SequenceIdAssigner,\n type Todo,\n buildCteSql,\n buildUnnestCte,\n driverAfterBegin,\n driverAfterCommit,\n driverApi,\n driverBeforeBegin,\n driverBeforeCommit,\n fail,\n kq,\n kqDot,\n} from \"joist-core\";\n\nconst { getRuntimeConfig, cleanSql, generateOps } = driverApi;\ntype DeleteOp = any;\ntype InsertOp = any;\ntype UpdateOp = any;\n\n/** Incomplete Bun SQL driver; raw-query execution is not implemented. */\nexport class BunPgDriver implements Driver<TransactionSQL> {\n readonly #idAssigner: IdAssigner;\n readonly #sql: SQL;\n\n constructor(_sql: SQL = sql) {\n this.#sql = _sql;\n this.#idAssigner = new SequenceIdAssigner((s) => this.#sql.unsafe(s));\n }\n\n executeFind(\n em: EntityManager,\n parsed: ParsedFindQuery,\n settings: { limit?: number; offset?: number },\n ): Promise<any[]> {\n throw new Error(\"Method not implemented.\");\n }\n\n executeQuery(em: EntityManager, sql: string, bindings: any[]): Promise<DriverQueryResult> {\n throw new Error(\"BunPgDriver.executeQuery is not implemented; em.query and em.execute are unsupported.\");\n }\n\n async transaction<T>(em: EntityManager, fn: (txn: TransactionSQL) => Promise<T>): Promise<T> {\n if (em.txn) {\n return fn(em.txn as TransactionSQL);\n } else {\n // This should be done on a reserved connection...\n await driverBeforeBegin(em, this.#sql);\n const result = await this.#sql.begin(async (txn) => {\n em.txn = txn;\n try {\n await driverAfterBegin(em, txn);\n const result = await fn(txn);\n await driverBeforeCommit(em, txn);\n return result;\n } finally {\n em.txn = undefined;\n }\n });\n await driverAfterCommit(em, this.#sql);\n return result;\n }\n }\n\n assignNewIds(em: EntityManager, todos: Record<string, Todo>): Promise<void> {\n throw new Error(\"Method not implemented.\");\n }\n\n async flush(em: EntityManager, todos: Record<string, Todo>, joinRows: Record<string, JoinRowTodo>): Promise<void> {\n const sql = (em.txn ?? fail(\"Expected EntityManager.txn to be set\")) as TransactionSQL;\n await this.#idAssigner.assignNewIds(todos);\n const ops = generateOps(todos);\n // Do INSERTs+UPDATEs first so that we avoid DELETE cascades invalidating oplocks\n // See https://github.com/joist-orm/joist-orm/issues/591\n await Promise.all([\n ...ops.inserts.map((op) => batchInsert(sql, op)),\n ...ops.updates.map((op) => batchUpdate(sql, op)),\n ...ops.deletes.map((op) => batchDelete(sql, op)),\n ]);\n }\n\n get defaultPlugins() {\n return {};\n }\n}\n\nfunction batchInsert(txn: TransactionSQL, op: InsertOp): Promise<unknown> {\n const { tableName, columns, columnValues } = op;\n const { sql: cte, bindings } = buildCteSql(buildUnnestCte(\"data\", columns, columnValues));\n const sql = cleanSql(`\n ${cte}\n INSERT INTO ${kq(tableName)} (${columns.map((c: any) => kq(c.columnName)).join(\", \")})\n SELECT * FROM data\n `);\n return convertToSql(txn, sql, bindings);\n}\n\nasync function batchUpdate(txn: TransactionSQL, op: UpdateOp): Promise<void> {\n const { tableName, columns, columnValues, updatedAt } = op;\n\n const { sql: cte, bindings } = buildCteSql(buildUnnestCte(\"data\", columns, columnValues));\n\n // JS Dates only have millisecond-level precision, so we may have dropped/lost accuracy when\n // reading Postgres's microsecond-level `timestamptz` values; using `date_trunc` \"downgrades\"\n // the pg data to match what we have in the JS Date.\n //\n // ...but Temporal's types don't have this flaw.\n const truncateToMills = !getRuntimeConfig().temporal;\n const maybeUpdatedAt =\n updatedAt && truncateToMills\n ? ` AND date_trunc('milliseconds', ${kqDot(tableName, updatedAt)}) = data.__original_updated_at`\n : updatedAt\n ? ` AND ${kqDot(tableName, updatedAt)} = data.__original_updated_at`\n : \"\";\n\n const sql = `\n ${cte}\n UPDATE ${kq(tableName)}\n SET ${columns\n .filter((c: any) => c.columnName !== \"id\" && c.columnName !== \"__original_updated_at\")\n .map((c: any) => `${kq(c.columnName)} = data.${kq(c.columnName)}`)\n .join(\", \")}\n FROM data\n WHERE ${kq(tableName)}.id = data.id ${maybeUpdatedAt}\n RETURNING ${kq(tableName)}.id\n `;\n\n const results = await convertToSql(txn, sql, bindings);\n\n const ids = columnValues[0]; // assume id is the 1st column\n if (results.length !== ids.length) {\n const updated = new Set(results.map((r: any) => r.id));\n const missing = ids.filter((id: any) => !updated.has(id));\n throw new Error(`Oplock failure for ${tableName} rows ${missing.join(\", \")}`);\n }\n}\n\nasync function batchDelete(txn: TransactionSQL, op: DeleteOp): Promise<void> {\n const { tableName, ids } = op;\n // await txn(tableName).del().whereIn(\"id\", ids);\n}\n\nfunction convertToSql(sql: TransactionSQL, query: string, bindings: readonly any[]): SQLQuery {\n // Split the query string by the placeholder character '?'\n const fragments = query.split(\"?\");\n if (fragments.length - 1 !== bindings.length) {\n throw new Error(`Mismatch between placeholders (${fragments.length - 1}) and bindings (${bindings.length})`);\n }\n // postgres.js does runtime detection of the `raw` property to determine if it's a template string\n const templateStrings = Object.assign(fragments, {\n raw: fragments,\n }) as unknown as TemplateStringsArray;\n return sql(templateStrings, ...bindings);\n}\n"],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import { SQL, TransactionSQL } from "bun";
2
+ import { Driver, DriverQueryResult, EntityManager, JoinRowTodo, ParsedFindQuery, Todo } from "joist-core";
3
+ //#region src/BunPgDriver.d.ts
4
+ /** Incomplete Bun SQL driver; raw-query execution is not implemented. */
5
+ declare class BunPgDriver implements Driver<TransactionSQL> {
6
+ #private;
7
+ constructor(_sql?: SQL);
8
+ executeFind(em: EntityManager, parsed: ParsedFindQuery, settings: {
9
+ limit?: number;
10
+ offset?: number;
11
+ }): Promise<any[]>;
12
+ executeQuery(em: EntityManager, sql: string, bindings: any[]): Promise<DriverQueryResult>;
13
+ transaction<T>(em: EntityManager, fn: (txn: TransactionSQL) => Promise<T>): Promise<T>;
14
+ assignNewIds(em: EntityManager, todos: Record<string, Todo>): Promise<void>;
15
+ flush(em: EntityManager, todos: Record<string, Todo>, joinRows: Record<string, JoinRowTodo>): Promise<void>;
16
+ get defaultPlugins(): {};
17
+ }
18
+ //#endregion
19
+ export { BunPgDriver };
20
+ //# sourceMappingURL=BunPgDriver.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BunPgDriver.d.cts","names":[],"sources":["../src/BunPgDriver.ts"],"mappings":";;;;cA4Ba,uBAAuB,OAAO;;EAIzC,YAAY,OAAM;EAKlB,YACE,IAAI,eACJ,QAAQ,iBACR;IAAY;IAAgB;MAC3B;EAIH,aAAa,IAAI,eAAe,aAAa,kBAAkB,QAAQ;EAIjE,YAAY,GAAG,IAAI,eAAe,KAAK,KAAK,mBAAmB,QAAQ,KAAK,QAAQ;EAsB1F,aAAa,IAAI,eAAe,OAAO,eAAe,QAAQ;EAIxD,MAAM,IAAI,eAAe,OAAO,eAAe,OAAO,UAAU,eAAe,eAAe;MAahG"}
@@ -0,0 +1,20 @@
1
+ import { SQL, TransactionSQL } from "bun";
2
+ import { Driver, DriverQueryResult, EntityManager, JoinRowTodo, ParsedFindQuery, Todo } from "joist-core";
3
+ //#region src/BunPgDriver.d.ts
4
+ /** Incomplete Bun SQL driver; raw-query execution is not implemented. */
5
+ declare class BunPgDriver implements Driver<TransactionSQL> {
6
+ #private;
7
+ constructor(_sql?: SQL);
8
+ executeFind(em: EntityManager, parsed: ParsedFindQuery, settings: {
9
+ limit?: number;
10
+ offset?: number;
11
+ }): Promise<any[]>;
12
+ executeQuery(em: EntityManager, sql: string, bindings: any[]): Promise<DriverQueryResult>;
13
+ transaction<T>(em: EntityManager, fn: (txn: TransactionSQL) => Promise<T>): Promise<T>;
14
+ assignNewIds(em: EntityManager, todos: Record<string, Todo>): Promise<void>;
15
+ flush(em: EntityManager, todos: Record<string, Todo>, joinRows: Record<string, JoinRowTodo>): Promise<void>;
16
+ get defaultPlugins(): {};
17
+ }
18
+ //#endregion
19
+ export { BunPgDriver };
20
+ //# sourceMappingURL=BunPgDriver.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BunPgDriver.d.mts","names":[],"sources":["../src/BunPgDriver.ts"],"mappings":";;;;cA4Ba,uBAAuB,OAAO;;EAIzC,YAAY,OAAM;EAKlB,YACE,IAAI,eACJ,QAAQ,iBACR;IAAY;IAAgB;MAC3B;EAIH,aAAa,IAAI,eAAe,aAAa,kBAAkB,QAAQ;EAIjE,YAAY,GAAG,IAAI,eAAe,KAAK,KAAK,mBAAmB,QAAQ,KAAK,QAAQ;EAsB1F,aAAa,IAAI,eAAe,OAAO,eAAe,QAAQ;EAIxD,MAAM,IAAI,eAAe,OAAO,eAAe,OAAO,UAAU,eAAe,eAAe;MAahG"}
@@ -1,122 +1,95 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.BunPgDriver = void 0;
4
- const bun_1 = require("bun");
5
- const joist_core_1 = require("joist-core");
6
- const { getRuntimeConfig, cleanSql, generateOps } = joist_core_1.driverApi;
7
- class BunPgDriver {
8
- #idAssigner;
9
- #sql;
10
- constructor(_sql = bun_1.sql) {
11
- this.#sql = _sql;
12
- this.#idAssigner = new joist_core_1.SequenceIdAssigner((s) => this.#sql.unsafe(s));
13
- }
14
- executeFind(em, parsed, settings) {
15
- throw new Error("Method not implemented.");
16
- }
17
- executeQuery(em, sql, bindings) {
18
- throw new Error("Method not implemented.");
19
- }
20
- async transaction(em, fn) {
21
- if (em.txn) {
22
- return fn(em.txn);
23
- }
24
- else {
25
- // This should be done on a reserved connection...
26
- await (0, joist_core_1.driverBeforeBegin)(em, this.#sql);
27
- const result = await this.#sql.begin(async (txn) => {
28
- em.txn = txn;
29
- try {
30
- await (0, joist_core_1.driverAfterBegin)(em, txn);
31
- const result = await fn(txn);
32
- await (0, joist_core_1.driverBeforeCommit)(em, txn);
33
- return result;
34
- }
35
- finally {
36
- em.txn = undefined;
37
- }
38
- });
39
- await (0, joist_core_1.driverAfterCommit)(em, this.#sql);
40
- return result;
41
- }
42
- }
43
- assignNewIds(em, todos) {
44
- throw new Error("Method not implemented.");
45
- }
46
- async flush(em, todos, joinRows) {
47
- const sql = (em.txn ?? (0, joist_core_1.fail)("Expected EntityManager.txn to be set"));
48
- await this.#idAssigner.assignNewIds(todos);
49
- const ops = generateOps(todos);
50
- // Do INSERTs+UPDATEs first so that we avoid DELETE cascades invalidating oplocks
51
- // See https://github.com/joist-orm/joist-orm/issues/591
52
- await Promise.all([
53
- ...ops.inserts.map((op) => batchInsert(sql, op)),
54
- ...ops.updates.map((op) => batchUpdate(sql, op)),
55
- ...ops.deletes.map((op) => batchDelete(sql, op)),
56
- ]);
57
- }
58
- get defaultPlugins() {
59
- return {};
60
- }
61
- }
62
- exports.BunPgDriver = BunPgDriver;
1
+ import { sql } from "bun";
2
+ import { SequenceIdAssigner, buildCteSql, buildUnnestCte, driverAfterBegin, driverAfterCommit, driverApi, driverBeforeBegin, driverBeforeCommit, fail, kq, kqDot } from "joist-core";
3
+ //#region src/BunPgDriver.ts
4
+ const { getRuntimeConfig, cleanSql, generateOps } = driverApi;
5
+ /** Incomplete Bun SQL driver; raw-query execution is not implemented. */
6
+ var BunPgDriver = class {
7
+ #idAssigner;
8
+ #sql;
9
+ constructor(_sql = sql) {
10
+ this.#sql = _sql;
11
+ this.#idAssigner = new SequenceIdAssigner((s) => this.#sql.unsafe(s));
12
+ }
13
+ executeFind(em, parsed, settings) {
14
+ throw new Error("Method not implemented.");
15
+ }
16
+ executeQuery(em, sql, bindings) {
17
+ throw new Error("BunPgDriver.executeQuery is not implemented; em.query and em.execute are unsupported.");
18
+ }
19
+ async transaction(em, fn) {
20
+ if (em.txn) return fn(em.txn);
21
+ else {
22
+ await driverBeforeBegin(em, this.#sql);
23
+ const result = await this.#sql.begin(async (txn) => {
24
+ em.txn = txn;
25
+ try {
26
+ await driverAfterBegin(em, txn);
27
+ const result = await fn(txn);
28
+ await driverBeforeCommit(em, txn);
29
+ return result;
30
+ } finally {
31
+ em.txn = void 0;
32
+ }
33
+ });
34
+ await driverAfterCommit(em, this.#sql);
35
+ return result;
36
+ }
37
+ }
38
+ assignNewIds(em, todos) {
39
+ throw new Error("Method not implemented.");
40
+ }
41
+ async flush(em, todos, joinRows) {
42
+ const sql = em.txn ?? fail("Expected EntityManager.txn to be set");
43
+ await this.#idAssigner.assignNewIds(todos);
44
+ const ops = generateOps(todos);
45
+ await Promise.all([
46
+ ...ops.inserts.map((op) => batchInsert(sql, op)),
47
+ ...ops.updates.map((op) => batchUpdate(sql, op)),
48
+ ...ops.deletes.map((op) => batchDelete(sql, op))
49
+ ]);
50
+ }
51
+ get defaultPlugins() {
52
+ return {};
53
+ }
54
+ };
63
55
  function batchInsert(txn, op) {
64
- const { tableName, columns, columnValues } = op;
65
- const { sql: cte, bindings } = (0, joist_core_1.buildCteSql)((0, joist_core_1.buildUnnestCte)("data", columns, columnValues));
66
- const sql = cleanSql(`
56
+ const { tableName, columns, columnValues } = op;
57
+ const { sql: cte, bindings } = buildCteSql(buildUnnestCte("data", columns, columnValues));
58
+ return convertToSql(txn, cleanSql(`
67
59
  ${cte}
68
- INSERT INTO ${(0, joist_core_1.kq)(tableName)} (${columns.map((c) => (0, joist_core_1.kq)(c.columnName)).join(", ")})
60
+ INSERT INTO ${kq(tableName)} (${columns.map((c) => kq(c.columnName)).join(", ")})
69
61
  SELECT * FROM data
70
- `);
71
- return convertToSql(txn, sql, bindings);
62
+ `), bindings);
72
63
  }
73
64
  async function batchUpdate(txn, op) {
74
- const { tableName, columns, columnValues, updatedAt } = op;
75
- const { sql: cte, bindings } = (0, joist_core_1.buildCteSql)((0, joist_core_1.buildUnnestCte)("data", columns, columnValues));
76
- // JS Dates only have millisecond-level precision, so we may have dropped/lost accuracy when
77
- // reading Postgres's microsecond-level `timestamptz` values; using `date_trunc` "downgrades"
78
- // the pg data to match what we have in the JS Date.
79
- //
80
- // ...but Temporal's types don't have this flaw.
81
- const truncateToMills = !getRuntimeConfig().temporal;
82
- const maybeUpdatedAt = updatedAt && truncateToMills
83
- ? ` AND date_trunc('milliseconds', ${(0, joist_core_1.kqDot)(tableName, updatedAt)}) = data.__original_updated_at`
84
- : updatedAt
85
- ? ` AND ${(0, joist_core_1.kqDot)(tableName, updatedAt)} = data.__original_updated_at`
86
- : "";
87
- const sql = `
65
+ const { tableName, columns, columnValues, updatedAt } = op;
66
+ const { sql: cte, bindings } = buildCteSql(buildUnnestCte("data", columns, columnValues));
67
+ const truncateToMills = !getRuntimeConfig().temporal;
68
+ const maybeUpdatedAt = updatedAt && truncateToMills ? ` AND date_trunc('milliseconds', ${kqDot(tableName, updatedAt)}) = data.__original_updated_at` : updatedAt ? ` AND ${kqDot(tableName, updatedAt)} = data.__original_updated_at` : "";
69
+ const results = await convertToSql(txn, `
88
70
  ${cte}
89
- UPDATE ${(0, joist_core_1.kq)(tableName)}
90
- SET ${columns
91
- .filter((c) => c.columnName !== "id" && c.columnName !== "__original_updated_at")
92
- .map((c) => `${(0, joist_core_1.kq)(c.columnName)} = data.${(0, joist_core_1.kq)(c.columnName)}`)
93
- .join(", ")}
71
+ UPDATE ${kq(tableName)}
72
+ SET ${columns.filter((c) => c.columnName !== "id" && c.columnName !== "__original_updated_at").map((c) => `${kq(c.columnName)} = data.${kq(c.columnName)}`).join(", ")}
94
73
  FROM data
95
- WHERE ${(0, joist_core_1.kq)(tableName)}.id = data.id ${maybeUpdatedAt}
96
- RETURNING ${(0, joist_core_1.kq)(tableName)}.id
97
- `;
98
- const results = await convertToSql(txn, sql, bindings);
99
- const ids = columnValues[0]; // assume id is the 1st column
100
- if (results.length !== ids.length) {
101
- const updated = new Set(results.map((r) => r.id));
102
- const missing = ids.filter((id) => !updated.has(id));
103
- throw new Error(`Oplock failure for ${tableName} rows ${missing.join(", ")}`);
104
- }
74
+ WHERE ${kq(tableName)}.id = data.id ${maybeUpdatedAt}
75
+ RETURNING ${kq(tableName)}.id
76
+ `, bindings);
77
+ const ids = columnValues[0];
78
+ if (results.length !== ids.length) {
79
+ const updated = new Set(results.map((r) => r.id));
80
+ const missing = ids.filter((id) => !updated.has(id));
81
+ throw new Error(`Oplock failure for ${tableName} rows ${missing.join(", ")}`);
82
+ }
105
83
  }
106
84
  async function batchDelete(txn, op) {
107
- const { tableName, ids } = op;
108
- // await txn(tableName).del().whereIn("id", ids);
85
+ const { tableName, ids } = op;
109
86
  }
110
87
  function convertToSql(sql, query, bindings) {
111
- // Split the query string by the placeholder character '?'
112
- const fragments = query.split("?");
113
- if (fragments.length - 1 !== bindings.length) {
114
- throw new Error(`Mismatch between placeholders (${fragments.length - 1}) and bindings (${bindings.length})`);
115
- }
116
- // postgres.js does runtime detection of the `raw` property to determine if it's a template string
117
- const templateStrings = Object.assign(fragments, {
118
- raw: fragments,
119
- });
120
- return sql(templateStrings, ...bindings);
88
+ const fragments = query.split("?");
89
+ if (fragments.length - 1 !== bindings.length) throw new Error(`Mismatch between placeholders (${fragments.length - 1}) and bindings (${bindings.length})`);
90
+ return sql(Object.assign(fragments, { raw: fragments }), ...bindings);
121
91
  }
92
+ //#endregion
93
+ export { BunPgDriver };
94
+
122
95
  //# sourceMappingURL=BunPgDriver.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"BunPgDriver.js","sourceRoot":"","sources":["../src/BunPgDriver.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"BunPgDriver.js","names":["#idAssigner","#sql"],"sources":["../src/BunPgDriver.ts"],"sourcesContent":["import { type SQL, type SQLQuery, type TransactionSQL, sql } from \"bun\";\nimport {\n type Driver,\n type DriverQueryResult,\n type EntityManager,\n type IdAssigner,\n type JoinRowTodo,\n type ParsedFindQuery,\n SequenceIdAssigner,\n type Todo,\n buildCteSql,\n buildUnnestCte,\n driverAfterBegin,\n driverAfterCommit,\n driverApi,\n driverBeforeBegin,\n driverBeforeCommit,\n fail,\n kq,\n kqDot,\n} from \"joist-core\";\n\nconst { getRuntimeConfig, cleanSql, generateOps } = driverApi;\ntype DeleteOp = any;\ntype InsertOp = any;\ntype UpdateOp = any;\n\n/** Incomplete Bun SQL driver; raw-query execution is not implemented. */\nexport class BunPgDriver implements Driver<TransactionSQL> {\n readonly #idAssigner: IdAssigner;\n readonly #sql: SQL;\n\n constructor(_sql: SQL = sql) {\n this.#sql = _sql;\n this.#idAssigner = new SequenceIdAssigner((s) => this.#sql.unsafe(s));\n }\n\n executeFind(\n em: EntityManager,\n parsed: ParsedFindQuery,\n settings: { limit?: number; offset?: number },\n ): Promise<any[]> {\n throw new Error(\"Method not implemented.\");\n }\n\n executeQuery(em: EntityManager, sql: string, bindings: any[]): Promise<DriverQueryResult> {\n throw new Error(\"BunPgDriver.executeQuery is not implemented; em.query and em.execute are unsupported.\");\n }\n\n async transaction<T>(em: EntityManager, fn: (txn: TransactionSQL) => Promise<T>): Promise<T> {\n if (em.txn) {\n return fn(em.txn as TransactionSQL);\n } else {\n // This should be done on a reserved connection...\n await driverBeforeBegin(em, this.#sql);\n const result = await this.#sql.begin(async (txn) => {\n em.txn = txn;\n try {\n await driverAfterBegin(em, txn);\n const result = await fn(txn);\n await driverBeforeCommit(em, txn);\n return result;\n } finally {\n em.txn = undefined;\n }\n });\n await driverAfterCommit(em, this.#sql);\n return result;\n }\n }\n\n assignNewIds(em: EntityManager, todos: Record<string, Todo>): Promise<void> {\n throw new Error(\"Method not implemented.\");\n }\n\n async flush(em: EntityManager, todos: Record<string, Todo>, joinRows: Record<string, JoinRowTodo>): Promise<void> {\n const sql = (em.txn ?? fail(\"Expected EntityManager.txn to be set\")) as TransactionSQL;\n await this.#idAssigner.assignNewIds(todos);\n const ops = generateOps(todos);\n // Do INSERTs+UPDATEs first so that we avoid DELETE cascades invalidating oplocks\n // See https://github.com/joist-orm/joist-orm/issues/591\n await Promise.all([\n ...ops.inserts.map((op) => batchInsert(sql, op)),\n ...ops.updates.map((op) => batchUpdate(sql, op)),\n ...ops.deletes.map((op) => batchDelete(sql, op)),\n ]);\n }\n\n get defaultPlugins() {\n return {};\n }\n}\n\nfunction batchInsert(txn: TransactionSQL, op: InsertOp): Promise<unknown> {\n const { tableName, columns, columnValues } = op;\n const { sql: cte, bindings } = buildCteSql(buildUnnestCte(\"data\", columns, columnValues));\n const sql = cleanSql(`\n ${cte}\n INSERT INTO ${kq(tableName)} (${columns.map((c: any) => kq(c.columnName)).join(\", \")})\n SELECT * FROM data\n `);\n return convertToSql(txn, sql, bindings);\n}\n\nasync function batchUpdate(txn: TransactionSQL, op: UpdateOp): Promise<void> {\n const { tableName, columns, columnValues, updatedAt } = op;\n\n const { sql: cte, bindings } = buildCteSql(buildUnnestCte(\"data\", columns, columnValues));\n\n // JS Dates only have millisecond-level precision, so we may have dropped/lost accuracy when\n // reading Postgres's microsecond-level `timestamptz` values; using `date_trunc` \"downgrades\"\n // the pg data to match what we have in the JS Date.\n //\n // ...but Temporal's types don't have this flaw.\n const truncateToMills = !getRuntimeConfig().temporal;\n const maybeUpdatedAt =\n updatedAt && truncateToMills\n ? ` AND date_trunc('milliseconds', ${kqDot(tableName, updatedAt)}) = data.__original_updated_at`\n : updatedAt\n ? ` AND ${kqDot(tableName, updatedAt)} = data.__original_updated_at`\n : \"\";\n\n const sql = `\n ${cte}\n UPDATE ${kq(tableName)}\n SET ${columns\n .filter((c: any) => c.columnName !== \"id\" && c.columnName !== \"__original_updated_at\")\n .map((c: any) => `${kq(c.columnName)} = data.${kq(c.columnName)}`)\n .join(\", \")}\n FROM data\n WHERE ${kq(tableName)}.id = data.id ${maybeUpdatedAt}\n RETURNING ${kq(tableName)}.id\n `;\n\n const results = await convertToSql(txn, sql, bindings);\n\n const ids = columnValues[0]; // assume id is the 1st column\n if (results.length !== ids.length) {\n const updated = new Set(results.map((r: any) => r.id));\n const missing = ids.filter((id: any) => !updated.has(id));\n throw new Error(`Oplock failure for ${tableName} rows ${missing.join(\", \")}`);\n }\n}\n\nasync function batchDelete(txn: TransactionSQL, op: DeleteOp): Promise<void> {\n const { tableName, ids } = op;\n // await txn(tableName).del().whereIn(\"id\", ids);\n}\n\nfunction convertToSql(sql: TransactionSQL, query: string, bindings: readonly any[]): SQLQuery {\n // Split the query string by the placeholder character '?'\n const fragments = query.split(\"?\");\n if (fragments.length - 1 !== bindings.length) {\n throw new Error(`Mismatch between placeholders (${fragments.length - 1}) and bindings (${bindings.length})`);\n }\n // postgres.js does runtime detection of the `raw` property to determine if it's a template string\n const templateStrings = Object.assign(fragments, {\n raw: fragments,\n }) as unknown as TemplateStringsArray;\n return sql(templateStrings, ...bindings);\n}\n"],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_BunPgDriver = require("./BunPgDriver.cjs");
3
+ exports.BunPgDriver = require_BunPgDriver.BunPgDriver;
@@ -0,0 +1,2 @@
1
+ import { BunPgDriver } from "./BunPgDriver.cjs";
2
+ export { BunPgDriver };
@@ -0,0 +1,2 @@
1
+ import { BunPgDriver } from "./BunPgDriver.mjs";
2
+ export { BunPgDriver };
package/build/index.js CHANGED
@@ -1,18 +1,2 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
- for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
- };
16
- Object.defineProperty(exports, "__esModule", { value: true });
17
- __exportStar(require("./BunPgDriver"), exports);
18
- //# sourceMappingURL=index.js.map
1
+ import { BunPgDriver } from "./BunPgDriver.js";
2
+ export { BunPgDriver };
package/package.json CHANGED
@@ -1,7 +1,8 @@
1
1
  {
2
2
  "name": "joist-driver-bun-pg",
3
- "version": "2.3.0",
3
+ "version": "2.4.0-next.2",
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",
@@ -10,24 +11,41 @@
10
11
  "engines": {
11
12
  "node": "^12.17.0 || ^13.10.0 || ^14 || >= 16.0.0 < 16.2.0 || >= 16.3.0"
12
13
  },
13
- "main": "build/index.js",
14
- "types": "build/index.d.ts",
15
- "scripts": {
16
- "format": "prettier --ignore-path ../../.prettierignore --write '{schema,migrations,src}/**/*.{ts,js,tsx,jsx,graphql}'"
14
+ "main": "build/index.cjs",
15
+ "module": "build/index.js",
16
+ "types": "build/index.d.mts",
17
+ "exports": {
18
+ ".": {
19
+ "bun": {
20
+ "types": "./build/index.d.mts",
21
+ "default": "./build/index.js"
22
+ },
23
+ "module-sync": {
24
+ "types": "./build/index.d.mts",
25
+ "default": "./build/index.js"
26
+ },
27
+ "import": {
28
+ "types": "./build/index.d.mts",
29
+ "default": "./build/index.js"
30
+ },
31
+ "require": {
32
+ "types": "./build/index.d.cts",
33
+ "default": "./build/index.cjs"
34
+ },
35
+ "default": "./build/index.js"
36
+ }
17
37
  },
18
38
  "files": [
19
39
  "build"
20
40
  ],
21
41
  "peerDependencies": {
22
- "joist-core": "2.3.0"
42
+ "joist-core": "2.4.0-next.2"
23
43
  },
24
44
  "dependencies": {
25
45
  "bun-types": "^1.3.14"
26
46
  },
27
47
  "devDependencies": {
28
- "prettier": "^3.8.4",
29
- "prettier-plugin-organize-imports": "^4.3.0",
30
48
  "tsconfig-paths": "^4.2.0",
31
- "typescript": "6.0.3"
49
+ "typescript": "7.0.2"
32
50
  }
33
51
  }
@@ -1,16 +0,0 @@
1
- import { SQL, type TransactionSQL } from "bun";
2
- import { Driver, EntityManager, JoinRowTodo, ParsedFindQuery, Todo } from "joist-core";
3
- export declare class BunPgDriver implements Driver<TransactionSQL> {
4
- #private;
5
- constructor(_sql?: SQL);
6
- executeFind(em: EntityManager, parsed: ParsedFindQuery, settings: {
7
- limit?: number;
8
- offset?: number;
9
- }): Promise<any[]>;
10
- executeQuery(em: EntityManager, sql: string, bindings: any[]): Promise<any[]>;
11
- transaction<T>(em: EntityManager, fn: (txn: TransactionSQL) => Promise<T>): Promise<T>;
12
- assignNewIds(em: EntityManager, todos: Record<string, Todo>): Promise<void>;
13
- flush(em: EntityManager, todos: Record<string, Todo>, joinRows: Record<string, JoinRowTodo>): Promise<void>;
14
- get defaultPlugins(): {};
15
- }
16
- //# sourceMappingURL=BunPgDriver.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"BunPgDriver.d.ts","sourceRoot":"","sources":["../src/BunPgDriver.ts"],"names":[],"mappings":"AAAA,OAAO,EAAO,GAAG,EAAiB,KAAK,cAAc,EAAE,MAAM,KAAK,CAAC;AACnE,OAAO,EAGL,MAAM,EAMN,aAAa,EAGb,WAAW,EAGX,eAAe,EAEf,IAAI,EACL,MAAM,YAAY,CAAC;AAOpB,qBAAa,WAAY,YAAW,MAAM,CAAC,cAAc,CAAC;;gBAI5C,IAAI,GAAE,GAAS;IAK3B,WAAW,CACT,EAAE,EAAE,aAAa,EACjB,MAAM,EAAE,eAAe,EACvB,QAAQ,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,GAC5C,OAAO,CAAC,GAAG,EAAE,CAAC;IAIjB,YAAY,CAAC,EAAE,EAAE,aAAa,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAIvE,WAAW,CAAC,CAAC,EAAE,EAAE,EAAE,aAAa,EAAE,EAAE,EAAE,CAAC,GAAG,EAAE,cAAc,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAsB5F,YAAY,CAAC,EAAE,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAIrE,KAAK,CAAC,EAAE,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAajH,IAAI,cAAc,OAEjB;CACF"}
package/build/index.d.ts DELETED
@@ -1,2 +0,0 @@
1
- export * from "./BunPgDriver";
2
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,gDAA8B"}