bun-query-builder 0.1.33 → 0.1.35
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/bin/cli.js +48 -6
- package/dist/client.d.ts +1 -0
- package/dist/config.d.ts +20 -0
- package/dist/src/index.js +47 -5
- package/package.json +1 -1
package/dist/bin/cli.js
CHANGED
|
@@ -11664,8 +11664,9 @@ async function getConfig() {
|
|
|
11664
11664
|
alias: "qb",
|
|
11665
11665
|
defaultConfig: defaultConfig4
|
|
11666
11666
|
});
|
|
11667
|
+
setConfig(_config);
|
|
11667
11668
|
}
|
|
11668
|
-
return
|
|
11669
|
+
return config5;
|
|
11669
11670
|
}
|
|
11670
11671
|
function setConfig(userConfig) {
|
|
11671
11672
|
if (userConfig.dialect && _lastConfiguredDialect && userConfig.dialect !== _lastConfiguredDialect) {
|
|
@@ -11972,6 +11973,43 @@ function createSQLiteSQL(filename) {
|
|
|
11972
11973
|
return Promise.reject(error);
|
|
11973
11974
|
}
|
|
11974
11975
|
};
|
|
11976
|
+
let txDepth = 0;
|
|
11977
|
+
sqlFunction.begin = async (fnOrName, maybeFn) => {
|
|
11978
|
+
const fn = typeof fnOrName === "function" ? fnOrName : maybeFn;
|
|
11979
|
+
if (typeof fn !== "function")
|
|
11980
|
+
throw new TypeError("[query-builder] sqlite begin(): a transaction callback is required");
|
|
11981
|
+
const isSavepoint = txDepth > 0;
|
|
11982
|
+
const spName = `qb_sp_${txDepth}`;
|
|
11983
|
+
if (isSavepoint)
|
|
11984
|
+
wrapper.run(`SAVEPOINT ${spName}`);
|
|
11985
|
+
else
|
|
11986
|
+
wrapper.run("BEGIN");
|
|
11987
|
+
txDepth++;
|
|
11988
|
+
try {
|
|
11989
|
+
const result = await fn(sqlFunction);
|
|
11990
|
+
txDepth--;
|
|
11991
|
+
if (isSavepoint)
|
|
11992
|
+
wrapper.run(`RELEASE SAVEPOINT ${spName}`);
|
|
11993
|
+
else
|
|
11994
|
+
wrapper.run("COMMIT");
|
|
11995
|
+
return result;
|
|
11996
|
+
} catch (err) {
|
|
11997
|
+
txDepth--;
|
|
11998
|
+
try {
|
|
11999
|
+
if (isSavepoint) {
|
|
12000
|
+
wrapper.run(`ROLLBACK TO SAVEPOINT ${spName}`);
|
|
12001
|
+
wrapper.run(`RELEASE SAVEPOINT ${spName}`);
|
|
12002
|
+
} else {
|
|
12003
|
+
wrapper.run("ROLLBACK");
|
|
12004
|
+
}
|
|
12005
|
+
} catch {}
|
|
12006
|
+
throw err;
|
|
12007
|
+
}
|
|
12008
|
+
};
|
|
12009
|
+
sqlFunction.savepoint = sqlFunction.begin;
|
|
12010
|
+
sqlFunction.beginDistributed = async () => {
|
|
12011
|
+
throw new Error("[query-builder] beginDistributed() (two-phase commit) is not supported on SQLite. Use begin()/transaction().");
|
|
12012
|
+
};
|
|
11975
12013
|
sqlFunction._wrapper = wrapper;
|
|
11976
12014
|
return sqlFunction;
|
|
11977
12015
|
}
|
|
@@ -15891,12 +15929,15 @@ function createQueryBuilder(state) {
|
|
|
15891
15929
|
async transaction(fn, options) {
|
|
15892
15930
|
const defaults = state?.txDefaults;
|
|
15893
15931
|
const opts = { ...defaults, ...options };
|
|
15932
|
+
const txConn = state?.sql ?? bunSql;
|
|
15933
|
+
const nested = state?.inTransaction === true;
|
|
15934
|
+
const txMethod = nested && typeof txConn?.savepoint === "function" ? "savepoint" : "begin";
|
|
15894
15935
|
const runWith = async (attempt2) => {
|
|
15895
15936
|
opts.logger?.({ type: "start", attempt: attempt2 });
|
|
15896
15937
|
const start = Date.now();
|
|
15897
|
-
return await
|
|
15898
|
-
const qb = createQueryBuilder({ sql: tx, meta, schema });
|
|
15899
|
-
if (opts?.isolation) {
|
|
15938
|
+
return await txConn[txMethod](async (tx) => {
|
|
15939
|
+
const qb = createQueryBuilder({ sql: tx, meta, schema, inTransaction: true });
|
|
15940
|
+
if (opts?.isolation && !nested) {
|
|
15900
15941
|
const level = opts.isolation;
|
|
15901
15942
|
const upper = level === "read committed" ? "READ COMMITTED" : level === "repeatable read" ? "REPEATABLE READ" : "SERIALIZABLE";
|
|
15902
15943
|
if (config5.dialect === "postgres") {
|
|
@@ -15961,7 +16002,8 @@ function createQueryBuilder(state) {
|
|
|
15961
16002
|
});
|
|
15962
16003
|
},
|
|
15963
16004
|
async beginDistributed(name, fn) {
|
|
15964
|
-
const
|
|
16005
|
+
const txConn = state?.sql ?? bunSql;
|
|
16006
|
+
const res = await txConn.beginDistributed(name, async (tx) => {
|
|
15965
16007
|
const qb = createQueryBuilder({ sql: tx, meta, schema });
|
|
15966
16008
|
return await fn(qb);
|
|
15967
16009
|
});
|
|
@@ -30111,7 +30153,7 @@ function getPrefix() {
|
|
|
30111
30153
|
}
|
|
30112
30154
|
var prefix = getPrefix();
|
|
30113
30155
|
// package.json
|
|
30114
|
-
var version2 = "0.1.
|
|
30156
|
+
var version2 = "0.1.35";
|
|
30115
30157
|
|
|
30116
30158
|
// bin/cli.ts
|
|
30117
30159
|
init_actions();
|
package/dist/client.d.ts
CHANGED
|
@@ -386,6 +386,7 @@ declare interface InternalState {
|
|
|
386
386
|
meta?: SchemaMeta
|
|
387
387
|
schema?: any
|
|
388
388
|
txDefaults?: TransactionOptions
|
|
389
|
+
inTransaction?: boolean
|
|
389
390
|
}
|
|
390
391
|
declare interface TxBackoff { baseMs?: number, maxMs?: number, factor?: number, jitter?: boolean }
|
|
391
392
|
declare interface TxLoggerEvent { type: 'start' | 'retry' | 'commit' | 'rollback' | 'error', attempt: number, error?: any, durationMs?: number }
|
package/dist/config.d.ts
CHANGED
|
@@ -10,6 +10,26 @@ export declare function getPlaceholder(index: number): string;
|
|
|
10
10
|
* MySQL/SQLite: ?, ?, ?
|
|
11
11
|
*/
|
|
12
12
|
export declare function getPlaceholders(count: number, startIndex?: number): string;
|
|
13
|
+
/**
|
|
14
|
+
* Load the query-builder config from a config file (`query-builder.config.ts`,
|
|
15
|
+
* `.config/query-builder.ts`, etc.) and environment variables via bunfig, then
|
|
16
|
+
* MERGE it into the live, process-wide `config` singleton so every reader
|
|
17
|
+
* (dialect dispatch, placeholders, soft-deletes, the model layer, …) sees it.
|
|
18
|
+
*
|
|
19
|
+
* Call this once at application boot if you keep configuration in a file:
|
|
20
|
+
*
|
|
21
|
+
* ```ts
|
|
22
|
+
* import { getConfig } from 'bun-query-builder'
|
|
23
|
+
* await getConfig() // applies query-builder.config.ts + env to the runtime
|
|
24
|
+
* ```
|
|
25
|
+
*
|
|
26
|
+
* It is intentionally explicit/async: the builder otherwise runs purely off the
|
|
27
|
+
* synchronous `config` singleton (defaults + any `setConfig`), which keeps
|
|
28
|
+
* `bun --compile` and test behavior deterministic — auto-loading a file in the
|
|
29
|
+
* background would make early queries race the load. Previously this wrote the
|
|
30
|
+
* loaded config to a private `_config` variable that nothing else read, so a
|
|
31
|
+
* config file silently never took effect; it now routes through `setConfig`.
|
|
32
|
+
*/
|
|
13
33
|
export declare function getConfig(): Promise<QueryBuilderConfig>;
|
|
14
34
|
export declare function setConfig(userConfig: Partial<QueryBuilderConfig>): void;
|
|
15
35
|
export declare const defaultConfig: QueryBuilderConfig;
|
package/dist/src/index.js
CHANGED
|
@@ -11664,8 +11664,9 @@ async function getConfig() {
|
|
|
11664
11664
|
alias: "qb",
|
|
11665
11665
|
defaultConfig: defaultConfig4
|
|
11666
11666
|
});
|
|
11667
|
+
setConfig(_config);
|
|
11667
11668
|
}
|
|
11668
|
-
return
|
|
11669
|
+
return config5;
|
|
11669
11670
|
}
|
|
11670
11671
|
function setConfig(userConfig) {
|
|
11671
11672
|
if (userConfig.dialect && _lastConfiguredDialect && userConfig.dialect !== _lastConfiguredDialect) {
|
|
@@ -11972,6 +11973,43 @@ function createSQLiteSQL(filename) {
|
|
|
11972
11973
|
return Promise.reject(error);
|
|
11973
11974
|
}
|
|
11974
11975
|
};
|
|
11976
|
+
let txDepth = 0;
|
|
11977
|
+
sqlFunction.begin = async (fnOrName, maybeFn) => {
|
|
11978
|
+
const fn = typeof fnOrName === "function" ? fnOrName : maybeFn;
|
|
11979
|
+
if (typeof fn !== "function")
|
|
11980
|
+
throw new TypeError("[query-builder] sqlite begin(): a transaction callback is required");
|
|
11981
|
+
const isSavepoint = txDepth > 0;
|
|
11982
|
+
const spName = `qb_sp_${txDepth}`;
|
|
11983
|
+
if (isSavepoint)
|
|
11984
|
+
wrapper.run(`SAVEPOINT ${spName}`);
|
|
11985
|
+
else
|
|
11986
|
+
wrapper.run("BEGIN");
|
|
11987
|
+
txDepth++;
|
|
11988
|
+
try {
|
|
11989
|
+
const result = await fn(sqlFunction);
|
|
11990
|
+
txDepth--;
|
|
11991
|
+
if (isSavepoint)
|
|
11992
|
+
wrapper.run(`RELEASE SAVEPOINT ${spName}`);
|
|
11993
|
+
else
|
|
11994
|
+
wrapper.run("COMMIT");
|
|
11995
|
+
return result;
|
|
11996
|
+
} catch (err) {
|
|
11997
|
+
txDepth--;
|
|
11998
|
+
try {
|
|
11999
|
+
if (isSavepoint) {
|
|
12000
|
+
wrapper.run(`ROLLBACK TO SAVEPOINT ${spName}`);
|
|
12001
|
+
wrapper.run(`RELEASE SAVEPOINT ${spName}`);
|
|
12002
|
+
} else {
|
|
12003
|
+
wrapper.run("ROLLBACK");
|
|
12004
|
+
}
|
|
12005
|
+
} catch {}
|
|
12006
|
+
throw err;
|
|
12007
|
+
}
|
|
12008
|
+
};
|
|
12009
|
+
sqlFunction.savepoint = sqlFunction.begin;
|
|
12010
|
+
sqlFunction.beginDistributed = async () => {
|
|
12011
|
+
throw new Error("[query-builder] beginDistributed() (two-phase commit) is not supported on SQLite. Use begin()/transaction().");
|
|
12012
|
+
};
|
|
11975
12013
|
sqlFunction._wrapper = wrapper;
|
|
11976
12014
|
return sqlFunction;
|
|
11977
12015
|
}
|
|
@@ -15891,12 +15929,15 @@ function createQueryBuilder(state) {
|
|
|
15891
15929
|
async transaction(fn, options) {
|
|
15892
15930
|
const defaults = state?.txDefaults;
|
|
15893
15931
|
const opts = { ...defaults, ...options };
|
|
15932
|
+
const txConn = state?.sql ?? bunSql;
|
|
15933
|
+
const nested = state?.inTransaction === true;
|
|
15934
|
+
const txMethod = nested && typeof txConn?.savepoint === "function" ? "savepoint" : "begin";
|
|
15894
15935
|
const runWith = async (attempt2) => {
|
|
15895
15936
|
opts.logger?.({ type: "start", attempt: attempt2 });
|
|
15896
15937
|
const start = Date.now();
|
|
15897
|
-
return await
|
|
15898
|
-
const qb = createQueryBuilder({ sql: tx, meta, schema });
|
|
15899
|
-
if (opts?.isolation) {
|
|
15938
|
+
return await txConn[txMethod](async (tx) => {
|
|
15939
|
+
const qb = createQueryBuilder({ sql: tx, meta, schema, inTransaction: true });
|
|
15940
|
+
if (opts?.isolation && !nested) {
|
|
15900
15941
|
const level = opts.isolation;
|
|
15901
15942
|
const upper = level === "read committed" ? "READ COMMITTED" : level === "repeatable read" ? "REPEATABLE READ" : "SERIALIZABLE";
|
|
15902
15943
|
if (config5.dialect === "postgres") {
|
|
@@ -15961,7 +16002,8 @@ function createQueryBuilder(state) {
|
|
|
15961
16002
|
});
|
|
15962
16003
|
},
|
|
15963
16004
|
async beginDistributed(name, fn) {
|
|
15964
|
-
const
|
|
16005
|
+
const txConn = state?.sql ?? bunSql;
|
|
16006
|
+
const res = await txConn.beginDistributed(name, async (tx) => {
|
|
15965
16007
|
const qb = createQueryBuilder({ sql: tx, meta, schema });
|
|
15966
16008
|
return await fn(qb);
|
|
15967
16009
|
});
|
package/package.json
CHANGED