orange-orm 4.7.11 → 4.7.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.browser.mjs +4 -6
- package/dist/index.mjs +126 -62
- package/docs/changelog.md +2 -0
- package/package.json +6 -2
- package/src/bunPg/formatJSONIn.js +5 -0
- package/src/bunPg/newTransaction.js +2 -0
- package/src/bunPg/wrapQuery.js +108 -57
- package/src/table/column/json/newEncode.js +4 -6
- package/vitest.config.js +17 -0
package/dist/index.browser.mjs
CHANGED
|
@@ -4591,6 +4591,7 @@ function requireNewEncode$7 () {
|
|
|
4591
4591
|
hasRequiredNewEncode$7 = 1;
|
|
4592
4592
|
var newPara = requireNewParameterized();
|
|
4593
4593
|
var purify = requirePurify$5();
|
|
4594
|
+
var getSessionContext = requireGetSessionContext();
|
|
4594
4595
|
var getSessionSingleton = requireGetSessionSingleton();
|
|
4595
4596
|
|
|
4596
4597
|
function _new(column) {
|
|
@@ -4602,13 +4603,10 @@ function requireNewEncode$7 () {
|
|
|
4602
4603
|
return newPara('null');
|
|
4603
4604
|
return newPara('\'' + column.dbNull + '\'');
|
|
4604
4605
|
}
|
|
4606
|
+
var ctx = getSessionContext(context);
|
|
4605
4607
|
var encodeCore = getSessionSingleton(context, 'encodeJSON') || ((v) => v);
|
|
4606
|
-
|
|
4607
|
-
|
|
4608
|
-
value = encodeCore(value);
|
|
4609
|
-
}
|
|
4610
|
-
return newPara('?', [value]);
|
|
4611
|
-
|
|
4608
|
+
var formatIn = ctx.formatJSONIn;
|
|
4609
|
+
return newPara(formatIn ? formatIn('?') : '?', [encodeCore(value)]);
|
|
4612
4610
|
};
|
|
4613
4611
|
|
|
4614
4612
|
encode.unsafe = function(context, candidate) {
|
package/dist/index.mjs
CHANGED
|
@@ -4592,6 +4592,7 @@ function requireNewEncode$7 () {
|
|
|
4592
4592
|
hasRequiredNewEncode$7 = 1;
|
|
4593
4593
|
var newPara = requireNewParameterized();
|
|
4594
4594
|
var purify = requirePurify$5();
|
|
4595
|
+
var getSessionContext = requireGetSessionContext();
|
|
4595
4596
|
var getSessionSingleton = requireGetSessionSingleton();
|
|
4596
4597
|
|
|
4597
4598
|
function _new(column) {
|
|
@@ -4603,13 +4604,10 @@ function requireNewEncode$7 () {
|
|
|
4603
4604
|
return newPara('null');
|
|
4604
4605
|
return newPara('\'' + column.dbNull + '\'');
|
|
4605
4606
|
}
|
|
4607
|
+
var ctx = getSessionContext(context);
|
|
4606
4608
|
var encodeCore = getSessionSingleton(context, 'encodeJSON') || ((v) => v);
|
|
4607
|
-
|
|
4608
|
-
|
|
4609
|
-
value = encodeCore(value);
|
|
4610
|
-
}
|
|
4611
|
-
return newPara('?', [value]);
|
|
4612
|
-
|
|
4609
|
+
var formatIn = ctx.formatJSONIn;
|
|
4610
|
+
return newPara(formatIn ? formatIn('?') : '?', [encodeCore(value)]);
|
|
4613
4611
|
};
|
|
4614
4612
|
|
|
4615
4613
|
encode.unsafe = function(context, candidate) {
|
|
@@ -14975,6 +14973,7 @@ var hasRequiredWrapQuery$8;
|
|
|
14975
14973
|
function requireWrapQuery$8 () {
|
|
14976
14974
|
if (hasRequiredWrapQuery$8) return wrapQuery_1$8;
|
|
14977
14975
|
hasRequiredWrapQuery$8 = 1;
|
|
14976
|
+
|
|
14978
14977
|
const log = requireLog();
|
|
14979
14978
|
const replaceParamChar = requireReplaceParamChar$1();
|
|
14980
14979
|
const tryGetSessionContext = requireTryGetSessionContext();
|
|
@@ -14986,87 +14985,136 @@ function requireWrapQuery$8 () {
|
|
|
14986
14985
|
try {
|
|
14987
14986
|
log.emitQuery({ sql: query.sql(), parameters: query.parameters });
|
|
14988
14987
|
const sql = replaceParamChar(query, query.parameters);
|
|
14989
|
-
|
|
14990
|
-
|
|
14991
|
-
|
|
14992
|
-
|
|
14993
|
-
|
|
14994
|
-
|
|
14995
|
-
|
|
14996
|
-
|
|
14997
|
-
|
|
14998
|
-
|
|
14999
|
-
|
|
14988
|
+
const params = Array.isArray(query.parameters) ? query.parameters : [];
|
|
14989
|
+
|
|
14990
|
+
const rdb = tryGetSessionContext(context);
|
|
14991
|
+
let th = rdb.transactionHandler;
|
|
14992
|
+
|
|
14993
|
+
// --- tx control (short statements, no params) ---
|
|
14994
|
+
if (sql.length < 18 && params.length === 0) {
|
|
14995
|
+
const cmd = sql.trim().toUpperCase();
|
|
14996
|
+
|
|
14997
|
+
if (cmd === 'BEGIN' || cmd === 'BEGIN TRANSACTION') {
|
|
14998
|
+
if (th && !th.closing) return onCompleted(new Error('Already inside a transaction'), []);
|
|
14999
|
+
beginTransaction(connection).then(
|
|
15000
|
+
(_th) => {
|
|
15001
|
+
rdb.transactionHandler = _th;
|
|
15002
|
+
onCompleted(null, []);
|
|
15003
|
+
},
|
|
15004
|
+
(err) => onCompleted(err, [])
|
|
15005
|
+
);
|
|
15000
15006
|
return;
|
|
15001
15007
|
}
|
|
15002
|
-
|
|
15003
|
-
|
|
15004
|
-
|
|
15005
|
-
|
|
15006
|
-
|
|
15008
|
+
|
|
15009
|
+
if (cmd === 'COMMIT') {
|
|
15010
|
+
if (!th) return onCompleted(new Error('Cannot commit outside transaction'), []);
|
|
15011
|
+
try {
|
|
15012
|
+
th.closing = true; // mark tx as closing; don’t reuse
|
|
15013
|
+
th.resolve(); // resolve the *inner* control promise -> triggers commit
|
|
15014
|
+
// IMPORTANT: wait for the *outer* promise (commit finished on the wire)
|
|
15015
|
+
await th.settled;
|
|
15016
|
+
th.closed = true;
|
|
15017
|
+
rdb.transactionHandler = undefined;
|
|
15018
|
+
onCompleted(null, []);
|
|
15019
|
+
} catch (e) {
|
|
15020
|
+
th.closed = true;
|
|
15021
|
+
rdb.transactionHandler = undefined;
|
|
15022
|
+
onCompleted(e, []);
|
|
15023
|
+
}
|
|
15007
15024
|
return;
|
|
15008
15025
|
}
|
|
15009
|
-
|
|
15010
|
-
|
|
15011
|
-
|
|
15012
|
-
|
|
15013
|
-
|
|
15014
|
-
|
|
15015
|
-
|
|
15016
|
-
|
|
15017
|
-
|
|
15018
|
-
|
|
15026
|
+
|
|
15027
|
+
if (cmd === 'ROLLBACK') {
|
|
15028
|
+
if (!th) return onCompleted(new Error('Cannot rollback outside transaction'), []);
|
|
15029
|
+
try {
|
|
15030
|
+
th.closing = true;
|
|
15031
|
+
th.reject(new Error('__rollback__')); // reject inner promise -> triggers rollback
|
|
15032
|
+
// Wait for outer promise to settle (rollback finished)
|
|
15033
|
+
try {
|
|
15034
|
+
await th.settled;
|
|
15035
|
+
} catch (e) {
|
|
15036
|
+
// connection.begin() rejects on rollback; that’s expected
|
|
15037
|
+
if (e?.message !== '__rollback__') throw e;
|
|
15038
|
+
}
|
|
15039
|
+
th.closed = true;
|
|
15040
|
+
rdb.transactionHandler = undefined;
|
|
15041
|
+
onCompleted(null, []);
|
|
15042
|
+
} catch (e) {
|
|
15043
|
+
th.closed = true;
|
|
15044
|
+
rdb.transactionHandler = undefined;
|
|
15045
|
+
onCompleted(e, []);
|
|
15046
|
+
}
|
|
15019
15047
|
return;
|
|
15020
15048
|
}
|
|
15021
15049
|
}
|
|
15022
15050
|
|
|
15023
|
-
|
|
15024
|
-
const
|
|
15025
|
-
|
|
15026
|
-
|
|
15027
|
-
|
|
15028
|
-
|
|
15051
|
+
// --- regular query ---
|
|
15052
|
+
const conn = th && th.tx && !th.closing ? th.tx : connection;
|
|
15053
|
+
const result = params.length === 0
|
|
15054
|
+
? await conn.unsafe(sql)
|
|
15055
|
+
: await conn.unsafe(sql, params);
|
|
15056
|
+
|
|
15029
15057
|
onCompleted(null, result);
|
|
15030
|
-
}
|
|
15031
|
-
catch (e) {
|
|
15058
|
+
} catch (e) {
|
|
15032
15059
|
onCompleted(e);
|
|
15033
15060
|
}
|
|
15034
15061
|
}
|
|
15035
|
-
|
|
15036
15062
|
}
|
|
15037
15063
|
|
|
15038
15064
|
function beginTransaction(connection) {
|
|
15039
|
-
|
|
15040
|
-
let
|
|
15041
|
-
let resolve;
|
|
15042
|
-
let reject;
|
|
15065
|
+
let resolveCommit;
|
|
15066
|
+
let rejectRollback;
|
|
15043
15067
|
let resolveBegin;
|
|
15044
15068
|
let rejectBegin;
|
|
15045
15069
|
|
|
15046
|
-
|
|
15047
|
-
|
|
15048
|
-
|
|
15070
|
+
// This promise is controlled by our code: resolve() -> COMMIT, reject() -> ROLLBACK
|
|
15071
|
+
const controlPromise = new Promise((res, rej) => {
|
|
15072
|
+
resolveCommit = res;
|
|
15073
|
+
rejectRollback = rej;
|
|
15049
15074
|
});
|
|
15050
|
-
|
|
15075
|
+
|
|
15076
|
+
// We resolve this when Bun gives us the tx object
|
|
15077
|
+
const beginPromise = new Promise((res, rej) => {
|
|
15051
15078
|
resolveBegin = res;
|
|
15052
15079
|
rejectBegin = rej;
|
|
15053
15080
|
});
|
|
15054
|
-
|
|
15055
|
-
|
|
15081
|
+
|
|
15082
|
+
// Start the transaction
|
|
15083
|
+
const settled = connection.begin(async (tx) => {
|
|
15084
|
+
// hand back the handler
|
|
15056
15085
|
resolveBegin({
|
|
15057
15086
|
tx,
|
|
15058
|
-
resolve,
|
|
15059
|
-
reject,
|
|
15060
|
-
promise:
|
|
15061
|
-
|
|
15062
|
-
|
|
15063
|
-
|
|
15064
|
-
e => {
|
|
15065
|
-
if (!beginIsResolved)
|
|
15066
|
-
rejectBegin(e);
|
|
15067
|
-
if (e?.message !== '__rollback__')
|
|
15068
|
-
throw e;
|
|
15087
|
+
resolve: resolveCommit, // call to request COMMIT
|
|
15088
|
+
reject: rejectRollback, // call to request ROLLBACK
|
|
15089
|
+
promise: controlPromise, // (inner) resolves/rejects when we signal commit/rollback
|
|
15090
|
+
settled: null, // will be set to the outer promise below
|
|
15091
|
+
closing: false,
|
|
15092
|
+
closed: false,
|
|
15069
15093
|
});
|
|
15094
|
+
// keep tx open until caller resolves/rejects controlPromise
|
|
15095
|
+
return controlPromise;
|
|
15096
|
+
})
|
|
15097
|
+
.then(
|
|
15098
|
+
() => { /* commit finished */ },
|
|
15099
|
+
(e) => {
|
|
15100
|
+
// rollback or begin failure — propagate only non-sentinel errors
|
|
15101
|
+
if (e?.message !== '__rollback__') throw e;
|
|
15102
|
+
}
|
|
15103
|
+
);
|
|
15104
|
+
|
|
15105
|
+
// Attach the outer promise to the handler once it exists
|
|
15106
|
+
settled.then(null, () => {}); // keep microtasks rolling
|
|
15107
|
+
beginPromise.then(
|
|
15108
|
+
(handler) => { handler.settled = settled; },
|
|
15109
|
+
() => {}
|
|
15110
|
+
);
|
|
15111
|
+
|
|
15112
|
+
// Ensure beginPromise rejects if connection.begin() fails before callback runs
|
|
15113
|
+
settled.catch((e) => {
|
|
15114
|
+
// If callback never ran, resolveBegin is still undefined; reject beginPromise
|
|
15115
|
+
if (!resolveBegin) rejectBegin?.(e);
|
|
15116
|
+
});
|
|
15117
|
+
|
|
15070
15118
|
return beginPromise;
|
|
15071
15119
|
}
|
|
15072
15120
|
|
|
@@ -15074,6 +15122,20 @@ function requireWrapQuery$8 () {
|
|
|
15074
15122
|
return wrapQuery_1$8;
|
|
15075
15123
|
}
|
|
15076
15124
|
|
|
15125
|
+
var formatJSONIn_1;
|
|
15126
|
+
var hasRequiredFormatJSONIn;
|
|
15127
|
+
|
|
15128
|
+
function requireFormatJSONIn () {
|
|
15129
|
+
if (hasRequiredFormatJSONIn) return formatJSONIn_1;
|
|
15130
|
+
hasRequiredFormatJSONIn = 1;
|
|
15131
|
+
function formatJSONIn(value) {
|
|
15132
|
+
return `${value}::jsonb`;
|
|
15133
|
+
}
|
|
15134
|
+
|
|
15135
|
+
formatJSONIn_1 = formatJSONIn;
|
|
15136
|
+
return formatJSONIn_1;
|
|
15137
|
+
}
|
|
15138
|
+
|
|
15077
15139
|
var encodeJSON;
|
|
15078
15140
|
var hasRequiredEncodeJSON;
|
|
15079
15141
|
|
|
@@ -15112,6 +15174,7 @@ function requireNewTransaction$9 () {
|
|
|
15112
15174
|
var selectForUpdateSql = requireSelectForUpdateSql$4();
|
|
15113
15175
|
var limitAndOffset = requireLimitAndOffset$4();
|
|
15114
15176
|
var formatDateOut = requireFormatDateOut$3();
|
|
15177
|
+
var formatJSONIn = requireFormatJSONIn();
|
|
15115
15178
|
var encodeJSON = requireEncodeJSON();
|
|
15116
15179
|
var insertSql = requireInsertSql$4();
|
|
15117
15180
|
var insert = requireInsert$4();
|
|
@@ -15128,6 +15191,7 @@ function requireNewTransaction$9 () {
|
|
|
15128
15191
|
rdb.encodeDate = encodeDate;
|
|
15129
15192
|
rdb.encodeBinary = encodeBinary;
|
|
15130
15193
|
rdb.decodeBinary = decodeBinary;
|
|
15194
|
+
rdb.formatJSONIn = formatJSONIn;
|
|
15131
15195
|
rdb.encodeJSON = encodeJSON;
|
|
15132
15196
|
rdb.formatDateOut = formatDateOut;
|
|
15133
15197
|
rdb.deleteFromSql = deleteFromSql;
|
package/docs/changelog.md
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "orange-orm",
|
|
3
|
-
"version": "4.7.
|
|
3
|
+
"version": "4.7.12",
|
|
4
4
|
"main": "./src/index.js",
|
|
5
5
|
"module": "./dist/index.mjs",
|
|
6
6
|
"browser": "./dist/index.browser.mjs",
|
|
@@ -50,6 +50,10 @@
|
|
|
50
50
|
},
|
|
51
51
|
"scripts": {
|
|
52
52
|
"test": "vitest run --threads=false",
|
|
53
|
+
"test:bun": "bun test --timeout=30000 ./tests/*.bun.test.js",
|
|
54
|
+
"test:deno": "deno test --allow-all --unstable *.deno.test.js",
|
|
55
|
+
"test:all": "echo 'Running Node.js tests...' && npm run test:node && echo 'Running Bun tests...' && npm run test:bun && echo 'Running Deno tests...' && npm run test:deno && echo 'All tests completed!'",
|
|
56
|
+
"test:all:parallel": "concurrently \"npm:test:node\" \"npm:test:bun\" \"npm:test:deno\"",
|
|
53
57
|
"coverage": "vitest run --coverage.enabled --coverage.reporter='text-summary' --threads=false",
|
|
54
58
|
"testw": "vitest --threads=false update",
|
|
55
59
|
"tscheck": "tsc ./src/index.d.ts --module commonjs --target es2022 --noEmit true --strict true --esModuleInterop true",
|
|
@@ -158,4 +162,4 @@
|
|
|
158
162
|
"undef": true,
|
|
159
163
|
"node": true
|
|
160
164
|
}
|
|
161
|
-
}
|
|
165
|
+
}
|
|
@@ -6,6 +6,7 @@ var deleteFromSql = require('../pg/deleteFromSql');
|
|
|
6
6
|
var selectForUpdateSql = require('../pg/selectForUpdateSql');
|
|
7
7
|
var limitAndOffset = require('../pg/limitAndOffset');
|
|
8
8
|
var formatDateOut = require('../pg/formatDateOut');
|
|
9
|
+
var formatJSONIn = require('./formatJSONIn');
|
|
9
10
|
var encodeJSON = require('../pg/encodeJSON');
|
|
10
11
|
var insertSql = require('../pg/insertSql');
|
|
11
12
|
var insert = require('../pg/insert');
|
|
@@ -22,6 +23,7 @@ function newResolveTransaction(domain, pool, { readonly = false } = {}) {
|
|
|
22
23
|
rdb.encodeDate = encodeDate;
|
|
23
24
|
rdb.encodeBinary = encodeBinary;
|
|
24
25
|
rdb.decodeBinary = decodeBinary;
|
|
26
|
+
rdb.formatJSONIn = formatJSONIn;
|
|
25
27
|
rdb.encodeJSON = encodeJSON;
|
|
26
28
|
rdb.formatDateOut = formatDateOut;
|
|
27
29
|
rdb.deleteFromSql = deleteFromSql;
|
package/src/bunPg/wrapQuery.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
1
3
|
const log = require('../table/log');
|
|
2
4
|
const replaceParamChar = require('../pg/replaceParamChar');
|
|
3
5
|
const tryGetSessionContext = require('../table/tryGetSessionContext');
|
|
@@ -9,88 +11,137 @@ function wrapQuery(context, connection) {
|
|
|
9
11
|
try {
|
|
10
12
|
log.emitQuery({ sql: query.sql(), parameters: query.parameters });
|
|
11
13
|
const sql = replaceParamChar(query, query.parameters);
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
14
|
+
const params = Array.isArray(query.parameters) ? query.parameters : [];
|
|
15
|
+
|
|
16
|
+
const rdb = tryGetSessionContext(context);
|
|
17
|
+
let th = rdb.transactionHandler;
|
|
18
|
+
|
|
19
|
+
// --- tx control (short statements, no params) ---
|
|
20
|
+
if (sql.length < 18 && params.length === 0) {
|
|
21
|
+
const cmd = sql.trim().toUpperCase();
|
|
22
|
+
|
|
23
|
+
if (cmd === 'BEGIN' || cmd === 'BEGIN TRANSACTION') {
|
|
24
|
+
if (th && !th.closing) return onCompleted(new Error('Already inside a transaction'), []);
|
|
25
|
+
beginTransaction(connection).then(
|
|
26
|
+
(_th) => {
|
|
27
|
+
rdb.transactionHandler = _th;
|
|
28
|
+
onCompleted(null, []);
|
|
29
|
+
},
|
|
30
|
+
(err) => onCompleted(err, [])
|
|
31
|
+
);
|
|
23
32
|
return;
|
|
24
33
|
}
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
34
|
+
|
|
35
|
+
if (cmd === 'COMMIT') {
|
|
36
|
+
if (!th) return onCompleted(new Error('Cannot commit outside transaction'), []);
|
|
37
|
+
try {
|
|
38
|
+
th.closing = true; // mark tx as closing; don’t reuse
|
|
39
|
+
th.resolve(); // resolve the *inner* control promise -> triggers commit
|
|
40
|
+
// IMPORTANT: wait for the *outer* promise (commit finished on the wire)
|
|
41
|
+
await th.settled;
|
|
42
|
+
th.closed = true;
|
|
43
|
+
rdb.transactionHandler = undefined;
|
|
44
|
+
onCompleted(null, []);
|
|
45
|
+
} catch (e) {
|
|
46
|
+
th.closed = true;
|
|
47
|
+
rdb.transactionHandler = undefined;
|
|
48
|
+
onCompleted(e, []);
|
|
49
|
+
}
|
|
30
50
|
return;
|
|
31
51
|
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
52
|
+
|
|
53
|
+
if (cmd === 'ROLLBACK') {
|
|
54
|
+
if (!th) return onCompleted(new Error('Cannot rollback outside transaction'), []);
|
|
55
|
+
try {
|
|
56
|
+
th.closing = true;
|
|
57
|
+
th.reject(new Error('__rollback__')); // reject inner promise -> triggers rollback
|
|
58
|
+
// Wait for outer promise to settle (rollback finished)
|
|
59
|
+
try {
|
|
60
|
+
await th.settled;
|
|
61
|
+
} catch (e) {
|
|
62
|
+
// connection.begin() rejects on rollback; that’s expected
|
|
63
|
+
if (e?.message !== '__rollback__') throw e;
|
|
64
|
+
}
|
|
65
|
+
th.closed = true;
|
|
66
|
+
rdb.transactionHandler = undefined;
|
|
67
|
+
onCompleted(null, []);
|
|
68
|
+
} catch (e) {
|
|
69
|
+
th.closed = true;
|
|
70
|
+
rdb.transactionHandler = undefined;
|
|
71
|
+
onCompleted(e, []);
|
|
72
|
+
}
|
|
42
73
|
return;
|
|
43
74
|
}
|
|
44
75
|
}
|
|
45
76
|
|
|
46
|
-
|
|
47
|
-
const
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
77
|
+
// --- regular query ---
|
|
78
|
+
const conn = th && th.tx && !th.closing ? th.tx : connection;
|
|
79
|
+
const result = params.length === 0
|
|
80
|
+
? await conn.unsafe(sql)
|
|
81
|
+
: await conn.unsafe(sql, params);
|
|
82
|
+
|
|
52
83
|
onCompleted(null, result);
|
|
53
|
-
}
|
|
54
|
-
catch (e) {
|
|
84
|
+
} catch (e) {
|
|
55
85
|
onCompleted(e);
|
|
56
86
|
}
|
|
57
87
|
}
|
|
58
|
-
|
|
59
88
|
}
|
|
60
89
|
|
|
61
90
|
function beginTransaction(connection) {
|
|
62
|
-
|
|
63
|
-
let
|
|
64
|
-
let resolve;
|
|
65
|
-
let reject;
|
|
91
|
+
let resolveCommit;
|
|
92
|
+
let rejectRollback;
|
|
66
93
|
let resolveBegin;
|
|
67
94
|
let rejectBegin;
|
|
68
95
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
96
|
+
// This promise is controlled by our code: resolve() -> COMMIT, reject() -> ROLLBACK
|
|
97
|
+
const controlPromise = new Promise((res, rej) => {
|
|
98
|
+
resolveCommit = res;
|
|
99
|
+
rejectRollback = rej;
|
|
72
100
|
});
|
|
73
|
-
|
|
101
|
+
|
|
102
|
+
// We resolve this when Bun gives us the tx object
|
|
103
|
+
const beginPromise = new Promise((res, rej) => {
|
|
74
104
|
resolveBegin = res;
|
|
75
105
|
rejectBegin = rej;
|
|
76
106
|
});
|
|
77
|
-
|
|
78
|
-
|
|
107
|
+
|
|
108
|
+
// Start the transaction
|
|
109
|
+
const settled = connection.begin(async (tx) => {
|
|
110
|
+
// hand back the handler
|
|
79
111
|
resolveBegin({
|
|
80
112
|
tx,
|
|
81
|
-
resolve,
|
|
82
|
-
reject,
|
|
83
|
-
promise:
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
e => {
|
|
88
|
-
if (!beginIsResolved)
|
|
89
|
-
rejectBegin(e);
|
|
90
|
-
if (e?.message !== '__rollback__')
|
|
91
|
-
throw e;
|
|
113
|
+
resolve: resolveCommit, // call to request COMMIT
|
|
114
|
+
reject: rejectRollback, // call to request ROLLBACK
|
|
115
|
+
promise: controlPromise, // (inner) resolves/rejects when we signal commit/rollback
|
|
116
|
+
settled: null, // will be set to the outer promise below
|
|
117
|
+
closing: false,
|
|
118
|
+
closed: false,
|
|
92
119
|
});
|
|
120
|
+
// keep tx open until caller resolves/rejects controlPromise
|
|
121
|
+
return controlPromise;
|
|
122
|
+
})
|
|
123
|
+
.then(
|
|
124
|
+
() => { /* commit finished */ },
|
|
125
|
+
(e) => {
|
|
126
|
+
// rollback or begin failure — propagate only non-sentinel errors
|
|
127
|
+
if (e?.message !== '__rollback__') throw e;
|
|
128
|
+
}
|
|
129
|
+
);
|
|
130
|
+
|
|
131
|
+
// Attach the outer promise to the handler once it exists
|
|
132
|
+
settled.then(null, () => {}); // keep microtasks rolling
|
|
133
|
+
beginPromise.then(
|
|
134
|
+
(handler) => { handler.settled = settled; },
|
|
135
|
+
() => {}
|
|
136
|
+
);
|
|
137
|
+
|
|
138
|
+
// Ensure beginPromise rejects if connection.begin() fails before callback runs
|
|
139
|
+
settled.catch((e) => {
|
|
140
|
+
// If callback never ran, resolveBegin is still undefined; reject beginPromise
|
|
141
|
+
if (!resolveBegin) rejectBegin?.(e);
|
|
142
|
+
});
|
|
143
|
+
|
|
93
144
|
return beginPromise;
|
|
94
145
|
}
|
|
95
146
|
|
|
96
|
-
module.exports = wrapQuery;
|
|
147
|
+
module.exports = wrapQuery;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
var newPara = require('../../query/newParameterized');
|
|
2
2
|
var purify = require('./purify');
|
|
3
|
+
var getSessionContext = require('../../getSessionContext');
|
|
3
4
|
var getSessionSingleton = require('../../getSessionSingleton');
|
|
4
5
|
|
|
5
6
|
function _new(column) {
|
|
@@ -11,13 +12,10 @@ function _new(column) {
|
|
|
11
12
|
return newPara('null');
|
|
12
13
|
return newPara('\'' + column.dbNull + '\'');
|
|
13
14
|
}
|
|
15
|
+
var ctx = getSessionContext(context);
|
|
14
16
|
var encodeCore = getSessionSingleton(context, 'encodeJSON') || ((v) => v);
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
value = encodeCore(value);
|
|
18
|
-
}
|
|
19
|
-
return newPara('?', [value]);
|
|
20
|
-
|
|
17
|
+
var formatIn = ctx.formatJSONIn;
|
|
18
|
+
return newPara(formatIn ? formatIn('?') : '?', [encodeCore(value)]);
|
|
21
19
|
};
|
|
22
20
|
|
|
23
21
|
encode.unsafe = function(context, candidate) {
|
package/vitest.config.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// vitest.config.js
|
|
2
|
+
/** @type {import('vitest').UserConfig} */
|
|
3
|
+
module.exports = {
|
|
4
|
+
test: {
|
|
5
|
+
// Copied baseline excludes (since configDefaults is ESM-only)
|
|
6
|
+
exclude: [
|
|
7
|
+
'**/node_modules/**',
|
|
8
|
+
'**/dist/**',
|
|
9
|
+
'**/cypress/**',
|
|
10
|
+
'**/.{idea,git,cache}/**',
|
|
11
|
+
'**/coverage/**',
|
|
12
|
+
'**/*.deno.test.js',
|
|
13
|
+
'**/*.bun.test.js',
|
|
14
|
+
],
|
|
15
|
+
threads: false,
|
|
16
|
+
},
|
|
17
|
+
};
|