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.
@@ -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
- if (encodeCore) {
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
- if (encodeCore) {
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
- let rdb = tryGetSessionContext(context);
14990
- let transactionHandler = rdb.transactionHandler;
14991
-
14992
- if (sql.length < 18 && query.parameters.length === 0) {
14993
- if (sql === 'BEGIN TRANSACTION' || sql === 'BEGIN') {
14994
- if (transactionHandler)
14995
- return onCompleted(new Error('Already inside a transaction'), []);
14996
- beginTransaction(connection).then(_transactionHandler => {
14997
- rdb.transactionHandler = _transactionHandler;
14998
- onCompleted(null, []);
14999
- }, onCompleted);
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
- else if (sql === 'COMMIT') {
15003
- if (!transactionHandler)
15004
- return onCompleted(new Error('Cannot commit outside transaction'), []);
15005
- transactionHandler.resolve();
15006
- transactionHandler.promise.then(() => onCompleted(null, []), err => onCompleted(err, []));
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
- else if (sql === 'ROLLBACK') {
15010
- if (!transactionHandler)
15011
- return onCompleted(new Error('Cannot rollback outside transaction'), []);
15012
- transactionHandler.reject(new Error('__rollback__'));
15013
- transactionHandler.promise.then(null, (err) => {
15014
- if (err.message === '__rollback__')
15015
- onCompleted(null, []);
15016
- else
15017
- onCompleted(err, []);
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
- let result;
15024
- const _connection = transactionHandler?.tx || connection;
15025
- if (query.parameters.length === 0)
15026
- result = await _connection.unsafe(sql);
15027
- else
15028
- result = await _connection.unsafe(sql, query.parameters);
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 beginIsResolved = false;
15041
- let resolve;
15042
- let reject;
15065
+ let resolveCommit;
15066
+ let rejectRollback;
15043
15067
  let resolveBegin;
15044
15068
  let rejectBegin;
15045
15069
 
15046
- let sqlPromise = new Promise((res, rej) => {
15047
- resolve = res;
15048
- reject = rej;
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
- let beginPromise = new Promise((res,rej) => {
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
- connection.begin(async (tx) => {
15055
- beginIsResolved = true;
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: sqlPromise,
15061
- });
15062
- return sqlPromise;
15063
- }).then(null,
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
@@ -1,4 +1,6 @@
1
1
  ## Changelog
2
+ __4.7.12__
3
+ Bugfix: Bun Postgres: Race Condition After Transaction Commit [#133](https://github.com/alfateam/orange-orm/issues/133)
2
4
  __4.7.11__
3
5
  Support for bigint [#102](https://github.com/alfateam/orange-orm/issues/102)
4
6
  __4.7.10__
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "orange-orm",
3
- "version": "4.7.11",
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
+ }
@@ -0,0 +1,5 @@
1
+ function formatJSONIn(value) {
2
+ return `${value}::jsonb`;
3
+ }
4
+
5
+ module.exports = formatJSONIn;
@@ -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;
@@ -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
- let rdb = tryGetSessionContext(context);
13
- let transactionHandler = rdb.transactionHandler;
14
-
15
- if (sql.length < 18 && query.parameters.length === 0) {
16
- if (sql === 'BEGIN TRANSACTION' || sql === 'BEGIN') {
17
- if (transactionHandler)
18
- return onCompleted(new Error('Already inside a transaction'), []);
19
- beginTransaction(connection).then(_transactionHandler => {
20
- rdb.transactionHandler = _transactionHandler;
21
- onCompleted(null, []);
22
- }, onCompleted);
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
- else if (sql === 'COMMIT') {
26
- if (!transactionHandler)
27
- return onCompleted(new Error('Cannot commit outside transaction'), []);
28
- transactionHandler.resolve();
29
- transactionHandler.promise.then(() => onCompleted(null, []), err => onCompleted(err, []));
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
- else if (sql === 'ROLLBACK') {
33
- if (!transactionHandler)
34
- return onCompleted(new Error('Cannot rollback outside transaction'), []);
35
- transactionHandler.reject(new Error('__rollback__'));
36
- transactionHandler.promise.then(null, (err) => {
37
- if (err.message === '__rollback__')
38
- onCompleted(null, []);
39
- else
40
- onCompleted(err, []);
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
- let result;
47
- const _connection = transactionHandler?.tx || connection;
48
- if (query.parameters.length === 0)
49
- result = await _connection.unsafe(sql);
50
- else
51
- result = await _connection.unsafe(sql, query.parameters);
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 beginIsResolved = false;
64
- let resolve;
65
- let reject;
91
+ let resolveCommit;
92
+ let rejectRollback;
66
93
  let resolveBegin;
67
94
  let rejectBegin;
68
95
 
69
- let sqlPromise = new Promise((res, rej) => {
70
- resolve = res;
71
- reject = rej;
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
- let beginPromise = new Promise((res,rej) => {
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
- connection.begin(async (tx) => {
78
- beginIsResolved = true;
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: sqlPromise,
84
- });
85
- return sqlPromise;
86
- }).then(null,
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
- if (encodeCore) {
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) {
@@ -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
+ };