@prisma/client-engine-runtime 6.6.0-dev.9 → 6.6.0-dev.90

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.js CHANGED
@@ -5,10 +5,6 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
6
  var __getProtoOf = Object.getPrototypeOf;
7
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __typeError = (msg) => {
9
- throw TypeError(msg);
10
- };
11
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
12
8
  var __export = (target, all) => {
13
9
  for (var name in all)
14
10
  __defProp(target, name, { get: all[name], enumerable: true });
@@ -30,130 +26,134 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
30
26
  mod
31
27
  ));
32
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
33
- var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
34
- var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
35
- var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
36
- var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
37
- var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
38
- var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
39
29
 
40
30
  // src/index.ts
41
31
  var index_exports = {};
42
32
  __export(index_exports, {
43
- IsolationLevel: () => IsolationLevel,
44
33
  QueryInterpreter: () => QueryInterpreter,
45
34
  TransactionManager: () => TransactionManager,
46
35
  TransactionManagerError: () => TransactionManagerError,
36
+ isPrismaValueGenerator: () => isPrismaValueGenerator,
47
37
  isPrismaValuePlaceholder: () => isPrismaValuePlaceholder
48
38
  });
49
39
  module.exports = __toCommonJS(index_exports);
50
40
 
51
- // src/QueryPlan.ts
52
- function isPrismaValuePlaceholder(value) {
53
- return typeof value === "object" && value !== null && value["prisma__type"] === "param";
54
- }
55
-
56
- // src/interpreter/renderQueryTemplate.ts
57
- var BEGIN_REPEAT = "/* prisma-comma-repeatable-start */";
58
- var END_REPEAT = "/* prisma-comma-repeatable-end */";
59
- function renderQueryTemplate({
60
- query,
61
- params
62
- }) {
63
- if (!query.includes(BEGIN_REPEAT)) {
64
- return { query, params };
41
+ // src/interpreter/generators.ts
42
+ var import_cuid = __toESM(require("@bugsnag/cuid"));
43
+ var import_cuid2 = require("@paralleldrive/cuid2");
44
+ var import_nanoid = require("nanoid");
45
+ var import_ulid = require("ulid");
46
+ var import_uuid = require("uuid");
47
+ var GeneratorRegistry = class {
48
+ #generators = {};
49
+ constructor() {
50
+ this.register("now", new NowGenerator());
51
+ this.register("uuid", new UuidGenerator());
52
+ this.register("cuid", new CuidGenerator());
53
+ this.register("ulid", new UlidGenerator());
54
+ this.register("nanoid", new NanoIdGenerator());
55
+ }
56
+ /**
57
+ * Returns a snapshot of the generator registry. It's 'frozen' in time at the moment of this
58
+ * method being called, meaning that the built-in time-based generators will always return
59
+ * the same value on repeated calls as long as the same snapshot is used.
60
+ */
61
+ snapshot() {
62
+ return Object.create(this.#generators, {
63
+ now: { value: new NowGenerator() }
64
+ });
65
+ }
66
+ /**
67
+ * Registers a new generator with the given name.
68
+ */
69
+ register(name, generator) {
70
+ this.#generators[name] = generator;
65
71
  }
66
- const flattenedParams = [];
67
- let lastParamId = 1;
68
- let result = "";
69
- let templatePos = 0;
70
- let state = 0 /* Normal */;
71
- let stateBeforeQuote = 0 /* Normal */;
72
- while (templatePos < query.length) {
73
- const nextChar = query[templatePos];
74
- if (state === 1 /* Quoted */ && nextChar !== '"') {
75
- result += nextChar;
76
- templatePos++;
77
- continue;
78
- }
79
- if (nextChar === '"') {
80
- if (state === 1 /* Quoted */) {
81
- state = stateBeforeQuote;
82
- } else {
83
- stateBeforeQuote = state;
84
- state = 1 /* Quoted */;
85
- }
86
- result += nextChar;
87
- templatePos++;
88
- continue;
89
- }
90
- if (query.slice(templatePos, templatePos + BEGIN_REPEAT.length) === BEGIN_REPEAT) {
91
- if (state === 2 /* Repeating */) {
92
- throw new Error("Nested repetition is not allowed");
93
- }
94
- state = 2 /* Repeating */;
95
- templatePos += BEGIN_REPEAT.length;
96
- result += "(";
97
- continue;
72
+ };
73
+ var NowGenerator = class {
74
+ #now = /* @__PURE__ */ new Date();
75
+ generate() {
76
+ return this.#now.toISOString();
77
+ }
78
+ };
79
+ var UuidGenerator = class {
80
+ generate(arg) {
81
+ if (arg === 4) {
82
+ return (0, import_uuid.v4)();
83
+ } else if (arg === 7) {
84
+ return (0, import_uuid.v7)();
85
+ } else {
86
+ throw new Error("Invalid UUID generator arguments");
98
87
  }
99
- if (query.slice(templatePos, templatePos + END_REPEAT.length) === END_REPEAT) {
100
- if (state === 0 /* Normal */) {
101
- throw new Error("Unmatched repetition end");
102
- }
103
- state = 0 /* Normal */;
104
- templatePos += END_REPEAT.length;
105
- result += ")";
106
- continue;
88
+ }
89
+ };
90
+ var CuidGenerator = class {
91
+ generate(arg) {
92
+ if (arg === 1) {
93
+ return (0, import_cuid.default)();
94
+ } else if (arg === 2) {
95
+ return (0, import_cuid2.createId)();
96
+ } else {
97
+ throw new Error("Invalid CUID generator arguments");
107
98
  }
108
- if (nextChar === "$") {
109
- const paramMatch = query.slice(templatePos + 1).match(/^\d+/);
110
- if (!paramMatch) {
111
- result += "$";
112
- templatePos++;
113
- continue;
114
- }
115
- templatePos += paramMatch[0].length + 1;
116
- const originalParamIdx = parseInt(paramMatch[0]);
117
- const paramValue = params[originalParamIdx - 1];
118
- switch (state) {
119
- case 0 /* Normal */: {
120
- flattenedParams.push(paramValue);
121
- result += `$${lastParamId++}`;
122
- break;
123
- }
124
- case 2 /* Repeating */: {
125
- const paramArray = Array.isArray(paramValue) ? paramValue : [paramValue];
126
- if (paramArray.length === 0) {
127
- result += "NULL";
128
- break;
129
- }
130
- paramArray.forEach((value, idx) => {
131
- flattenedParams.push(value);
132
- result += `$${lastParamId++}`;
133
- if (idx !== paramArray.length - 1) {
134
- result += ", ";
135
- }
136
- });
137
- break;
138
- }
139
- default: {
140
- throw new Error(`Unexpected state: ${state}`);
141
- }
142
- }
143
- continue;
99
+ }
100
+ };
101
+ var UlidGenerator = class {
102
+ generate() {
103
+ return (0, import_ulid.ulid)();
104
+ }
105
+ };
106
+ var NanoIdGenerator = class {
107
+ generate(arg) {
108
+ if (typeof arg === "number") {
109
+ return (0, import_nanoid.nanoid)(arg);
110
+ } else if (arg === void 0) {
111
+ return (0, import_nanoid.nanoid)();
112
+ } else {
113
+ throw new Error("Invalid Nanoid generator arguments");
144
114
  }
145
- result += nextChar;
146
- templatePos++;
147
115
  }
148
- return {
149
- query: result,
150
- params: flattenedParams
151
- };
116
+ };
117
+
118
+ // src/QueryPlan.ts
119
+ function isPrismaValuePlaceholder(value) {
120
+ return typeof value === "object" && value !== null && value["prisma__type"] === "param";
121
+ }
122
+ function isPrismaValueGenerator(value) {
123
+ return typeof value === "object" && value !== null && value["prisma__type"] === "generatorCall";
124
+ }
125
+
126
+ // src/utils.ts
127
+ function assertNever(_, message) {
128
+ throw new Error(message);
152
129
  }
153
130
 
154
131
  // src/interpreter/renderQuery.ts
155
- function renderQuery({ query, params }, scope) {
156
- const substitutedParams = params.map((param) => {
132
+ function renderQuery(dbQuery, scope, generators) {
133
+ const queryType = dbQuery.type;
134
+ switch (queryType) {
135
+ case "rawSql":
136
+ return renderRawSql(dbQuery.sql, substituteParams(dbQuery.params, scope, generators));
137
+ case "templateSql":
138
+ return renderTemplateSql(
139
+ dbQuery.fragments,
140
+ dbQuery.placeholderFormat,
141
+ substituteParams(dbQuery.params, scope, generators)
142
+ );
143
+ default:
144
+ assertNever(queryType, `Invalid query type`);
145
+ }
146
+ }
147
+ function substituteParams(params, scope, generators) {
148
+ return params.map((param) => {
149
+ if (isPrismaValueGenerator(param)) {
150
+ const { name, args } = param.prisma__value;
151
+ const generator = generators[name];
152
+ if (!generator) {
153
+ throw new Error(`Encountered an unknown generator '${name}'`);
154
+ }
155
+ return generator.generate(...args);
156
+ }
157
157
  if (!isPrismaValuePlaceholder(param)) {
158
158
  return param;
159
159
  }
@@ -163,11 +163,48 @@ function renderQuery({ query, params }, scope) {
163
163
  }
164
164
  return value;
165
165
  });
166
- const { query: renderedQuery, params: expandedParams } = renderQueryTemplate({ query, params: substitutedParams });
167
- const argTypes = expandedParams.map((param) => toArgType(param));
166
+ }
167
+ function renderTemplateSql(fragments, placeholderFormat, params) {
168
+ let paramIndex = 0;
169
+ let placeholderNumber = 1;
170
+ const flattenedParams = [];
171
+ const sql = fragments.map((fragment) => {
172
+ const fragmentType = fragment.type;
173
+ switch (fragmentType) {
174
+ case "parameter":
175
+ if (paramIndex >= params.length) {
176
+ throw new Error(`Malformed query template. Fragments attempt to read over ${params.length} parameters.`);
177
+ }
178
+ flattenedParams.push(params[paramIndex++]);
179
+ return formatPlaceholder(placeholderFormat, placeholderNumber++);
180
+ case "stringChunk":
181
+ return fragment.value;
182
+ case "parameterTuple": {
183
+ if (paramIndex >= params.length) {
184
+ throw new Error(`Malformed query template. Fragments attempt to read over ${params.length} parameters.`);
185
+ }
186
+ const paramValue = params[paramIndex++];
187
+ const paramArray = Array.isArray(paramValue) ? paramValue : [paramValue];
188
+ const placeholders = paramArray.length == 0 ? "NULL" : paramArray.map((value) => {
189
+ flattenedParams.push(value);
190
+ return formatPlaceholder(placeholderFormat, placeholderNumber++);
191
+ }).join(",");
192
+ return `(${placeholders})`;
193
+ }
194
+ default:
195
+ assertNever(fragmentType, "Invalid fragment type");
196
+ }
197
+ }).join("");
198
+ return renderRawSql(sql, flattenedParams);
199
+ }
200
+ function formatPlaceholder(placeholderFormat, placeholderNumber) {
201
+ return placeholderFormat.hasNumbering ? `${placeholderFormat.prefix}${placeholderNumber}` : placeholderFormat.prefix;
202
+ }
203
+ function renderRawSql(sql, params) {
204
+ const argTypes = params.map((param) => toArgType(param));
168
205
  return {
169
- sql: renderedQuery,
170
- args: expandedParams,
206
+ sql,
207
+ args: params,
171
208
  argTypes
172
209
  };
173
210
  }
@@ -236,24 +273,23 @@ function serialize(resultSet) {
236
273
  }
237
274
 
238
275
  // src/interpreter/QueryInterpreter.ts
239
- var _queryable, _placeholderValues, _onQuery, _QueryInterpreter_instances, withQueryEvent_fn;
240
276
  var QueryInterpreter = class {
241
- constructor({ queryable, placeholderValues, onQuery }) {
242
- __privateAdd(this, _QueryInterpreter_instances);
243
- __privateAdd(this, _queryable);
244
- __privateAdd(this, _placeholderValues);
245
- __privateAdd(this, _onQuery);
246
- __privateSet(this, _queryable, queryable);
247
- __privateSet(this, _placeholderValues, placeholderValues);
248
- __privateSet(this, _onQuery, onQuery);
249
- }
250
- async run(queryPlan) {
251
- return this.interpretNode(queryPlan, __privateGet(this, _placeholderValues));
252
- }
253
- async interpretNode(node, scope) {
277
+ #transactionManager;
278
+ #placeholderValues;
279
+ #onQuery;
280
+ #generators = new GeneratorRegistry();
281
+ constructor({ transactionManager, placeholderValues, onQuery }) {
282
+ this.#transactionManager = transactionManager;
283
+ this.#placeholderValues = placeholderValues;
284
+ this.#onQuery = onQuery;
285
+ }
286
+ async run(queryPlan, queryable) {
287
+ return this.interpretNode(queryPlan, queryable, this.#placeholderValues, this.#generators.snapshot());
288
+ }
289
+ async interpretNode(node, queryable, scope, generators) {
254
290
  switch (node.type) {
255
291
  case "seq": {
256
- const results = await Promise.all(node.args.map((arg) => this.interpretNode(arg, scope)));
292
+ const results = await Promise.all(node.args.map((arg) => this.interpretNode(arg, queryable, scope, generators)));
257
293
  return results[results.length - 1];
258
294
  }
259
295
  case "get": {
@@ -263,10 +299,10 @@ var QueryInterpreter = class {
263
299
  const nestedScope = Object.create(scope);
264
300
  await Promise.all(
265
301
  node.args.bindings.map(async (binding) => {
266
- nestedScope[binding.name] = await this.interpretNode(binding.expr, scope);
302
+ nestedScope[binding.name] = await this.interpretNode(binding.expr, queryable, scope, generators);
267
303
  })
268
304
  );
269
- return this.interpretNode(node.args.expr, nestedScope);
305
+ return this.interpretNode(node.args.expr, queryable, nestedScope, generators);
270
306
  }
271
307
  case "getFirstNonEmpty": {
272
308
  for (const name of node.args.names) {
@@ -278,41 +314,31 @@ var QueryInterpreter = class {
278
314
  return [];
279
315
  }
280
316
  case "concat": {
281
- const parts = await Promise.all(node.args.map((arg) => this.interpretNode(arg, scope)));
317
+ const parts = await Promise.all(node.args.map((arg) => this.interpretNode(arg, queryable, scope, generators)));
282
318
  return parts.reduce((acc, part) => acc.concat(asList(part)), []);
283
319
  }
284
320
  case "sum": {
285
- const parts = await Promise.all(node.args.map((arg) => this.interpretNode(arg, scope)));
321
+ const parts = await Promise.all(node.args.map((arg) => this.interpretNode(arg, queryable, scope, generators)));
286
322
  return parts.reduce((acc, part) => asNumber(acc) + asNumber(part));
287
323
  }
288
324
  case "execute": {
289
- const query = renderQuery(node.args, scope);
290
- return __privateMethod(this, _QueryInterpreter_instances, withQueryEvent_fn).call(this, query, async () => {
291
- const result = await __privateGet(this, _queryable).executeRaw(query);
292
- if (result.ok) {
293
- return result.value;
294
- } else {
295
- throw result.error;
296
- }
325
+ const query = renderQuery(node.args, scope, generators);
326
+ return this.#withQueryEvent(query, async () => {
327
+ return await queryable.executeRaw(query);
297
328
  });
298
329
  }
299
330
  case "query": {
300
- const query = renderQuery(node.args, scope);
301
- return __privateMethod(this, _QueryInterpreter_instances, withQueryEvent_fn).call(this, query, async () => {
302
- const result = await __privateGet(this, _queryable).queryRaw(query);
303
- if (result.ok) {
304
- return serialize(result.value);
305
- } else {
306
- throw result.error;
307
- }
331
+ const query = renderQuery(node.args, scope, generators);
332
+ return this.#withQueryEvent(query, async () => {
333
+ return serialize(await queryable.queryRaw(query));
308
334
  });
309
335
  }
310
336
  case "reverse": {
311
- const value = await this.interpretNode(node.args, scope);
337
+ const value = await this.interpretNode(node.args, queryable, scope, generators);
312
338
  return Array.isArray(value) ? value.reverse() : value;
313
339
  }
314
340
  case "unique": {
315
- const value = await this.interpretNode(node.args, scope);
341
+ const value = await this.interpretNode(node.args, queryable, scope, generators);
316
342
  if (!Array.isArray(value)) {
317
343
  return value;
318
344
  }
@@ -322,22 +348,22 @@ var QueryInterpreter = class {
322
348
  return value[0] ?? null;
323
349
  }
324
350
  case "required": {
325
- const value = await this.interpretNode(node.args, scope);
351
+ const value = await this.interpretNode(node.args, queryable, scope, generators);
326
352
  if (isEmpty(value)) {
327
353
  throw new Error("Required value is empty");
328
354
  }
329
355
  return value;
330
356
  }
331
357
  case "mapField": {
332
- const value = await this.interpretNode(node.args.records, scope);
358
+ const value = await this.interpretNode(node.args.records, queryable, scope, generators);
333
359
  return mapField(value, node.args.field);
334
360
  }
335
361
  case "join": {
336
- const parent = await this.interpretNode(node.args.parent, scope);
362
+ const parent = await this.interpretNode(node.args.parent, queryable, scope, generators);
337
363
  const children = await Promise.all(
338
364
  node.args.children.map(async (joinExpr) => ({
339
365
  joinExpr,
340
- childRecords: await this.interpretNode(joinExpr.child, scope)
366
+ childRecords: await this.interpretNode(joinExpr.child, queryable, scope, generators)
341
367
  }))
342
368
  );
343
369
  if (Array.isArray(parent)) {
@@ -348,30 +374,41 @@ var QueryInterpreter = class {
348
374
  }
349
375
  return attachChildrenToParent(asRecord(parent), children);
350
376
  }
377
+ case "transaction": {
378
+ if (!this.#transactionManager.enabled) {
379
+ return this.interpretNode(node.args, queryable, scope, generators);
380
+ }
381
+ const transactionManager = this.#transactionManager.manager;
382
+ const transactionInfo = await transactionManager.startTransaction();
383
+ const transaction = transactionManager.getTransaction(transactionInfo, "new");
384
+ try {
385
+ const value = await this.interpretNode(node.args, transaction, scope, generators);
386
+ await transactionManager.commitTransaction(transactionInfo.id);
387
+ return value;
388
+ } catch (e) {
389
+ await transactionManager.rollbackTransaction(transactionInfo.id);
390
+ throw e;
391
+ }
392
+ }
351
393
  default: {
352
394
  node;
353
395
  throw new Error(`Unexpected node type: ${node.type}`);
354
396
  }
355
397
  }
356
398
  }
357
- };
358
- _queryable = new WeakMap();
359
- _placeholderValues = new WeakMap();
360
- _onQuery = new WeakMap();
361
- _QueryInterpreter_instances = new WeakSet();
362
- withQueryEvent_fn = async function(query, execute) {
363
- var _a;
364
- const timestamp = /* @__PURE__ */ new Date();
365
- const startInstant = performance.now();
366
- const result = await execute();
367
- const endInstant = performance.now();
368
- (_a = __privateGet(this, _onQuery)) == null ? void 0 : _a.call(this, {
369
- timestamp,
370
- duration: endInstant - startInstant,
371
- query: query.sql,
372
- params: query.args
373
- });
374
- return result;
399
+ async #withQueryEvent(query, execute) {
400
+ const timestamp = /* @__PURE__ */ new Date();
401
+ const startInstant = performance.now();
402
+ const result = await execute();
403
+ const endInstant = performance.now();
404
+ this.#onQuery?.({
405
+ timestamp,
406
+ duration: endInstant - startInstant,
407
+ query: query.sql,
408
+ params: query.args
409
+ });
410
+ return result;
411
+ }
375
412
  };
376
413
  function isEmpty(value) {
377
414
  if (Array.isArray(value)) {
@@ -429,22 +466,16 @@ function childRecordMatchesParent(childRecord, parentRecord, joinExpr) {
429
466
  return true;
430
467
  }
431
468
 
432
- // src/transactionManager/Transaction.ts
433
- var IsolationLevel = /* @__PURE__ */ ((IsolationLevel2) => {
434
- IsolationLevel2["ReadUncommitted"] = "ReadUncommitted";
435
- IsolationLevel2["ReadCommitted"] = "ReadCommitted";
436
- IsolationLevel2["RepeatableRead"] = "RepeatableRead";
437
- IsolationLevel2["Snapshot"] = "Snapshot";
438
- IsolationLevel2["Serializable"] = "Serializable";
439
- return IsolationLevel2;
440
- })(IsolationLevel || {});
441
-
442
469
  // src/transactionManager/TransactionManager.ts
443
- var import_debug = __toESM(require("@prisma/debug"));
470
+ var import_debug = require("@prisma/debug");
444
471
 
445
- // src/utils.ts
446
- function assertNever(_, message) {
447
- throw new Error(message);
472
+ // src/crypto.ts
473
+ async function getCrypto() {
474
+ return globalThis.crypto ?? await import("node:crypto");
475
+ }
476
+ async function randomUUID() {
477
+ const crypto = await getCrypto();
478
+ return crypto.randomUUID();
448
479
  }
449
480
 
450
481
  // src/transactionManager/TransactionManagerErrors.ts
@@ -452,8 +483,8 @@ var TransactionManagerError = class extends Error {
452
483
  constructor(message, meta) {
453
484
  super("Transaction API error: " + message);
454
485
  this.meta = meta;
455
- __publicField(this, "code", "P2028");
456
486
  }
487
+ code = "P2028";
457
488
  };
458
489
  var TransactionDriverAdapterError = class extends TransactionManagerError {
459
490
  constructor(message, errorParams) {
@@ -503,35 +534,25 @@ var InvalidTransactionIsolationLevelError = class extends TransactionManagerErro
503
534
 
504
535
  // src/transactionManager/TransactionManager.ts
505
536
  var MAX_CLOSED_TRANSACTIONS = 100;
506
- var isolationLevelMap = {
507
- ReadUncommitted: "READ UNCOMMITTED",
508
- ReadCommitted: "READ COMMITTED",
509
- RepeatableRead: "REPEATABLE READ",
510
- Snapshot: "SNAPSHOT",
511
- Serializable: "SERIALIZABLE"
512
- };
513
- var debug = (0, import_debug.default)("prisma:client:transactionManager");
537
+ var debug = (0, import_debug.Debug)("prisma:client:transactionManager");
514
538
  var COMMIT_QUERY = () => ({ sql: "COMMIT", args: [], argTypes: [] });
515
539
  var ROLLBACK_QUERY = () => ({ sql: "ROLLBACK", args: [], argTypes: [] });
516
- var ISOLATION_LEVEL_QUERY = (isolationLevel) => ({
517
- sql: "SET TRANSACTION ISOLATION LEVEL " + isolationLevelMap[isolationLevel],
518
- args: [],
519
- argTypes: []
520
- });
521
540
  var TransactionManager = class {
522
- constructor({ driverAdapter }) {
523
- // The map of active transactions.
524
- __publicField(this, "transactions", /* @__PURE__ */ new Map());
525
- // List of last closed transactions. Max MAX_CLOSED_TRANSACTIONS entries.
526
- // Used to provide better error messages than a generic "transaction not found".
527
- __publicField(this, "closedTransactions", []);
528
- __publicField(this, "driverAdapter");
541
+ // The map of active transactions.
542
+ transactions = /* @__PURE__ */ new Map();
543
+ // List of last closed transactions. Max MAX_CLOSED_TRANSACTIONS entries.
544
+ // Used to provide better error messages than a generic "transaction not found".
545
+ closedTransactions = [];
546
+ driverAdapter;
547
+ transactionOptions;
548
+ constructor({ driverAdapter, transactionOptions }) {
529
549
  this.driverAdapter = driverAdapter;
550
+ this.transactionOptions = transactionOptions;
530
551
  }
531
552
  async startTransaction(options) {
532
- const validatedOptions = this.validateOptions(options);
553
+ const validatedOptions = options !== void 0 ? this.validateOptions(options) : this.transactionOptions;
533
554
  const transaction = {
534
- id: globalThis.crypto.randomUUID(),
555
+ id: await randomUUID(),
535
556
  status: "waiting",
536
557
  timer: void 0,
537
558
  timeout: validatedOptions.timeout,
@@ -540,28 +561,17 @@ var TransactionManager = class {
540
561
  };
541
562
  this.transactions.set(transaction.id, transaction);
542
563
  transaction.timer = this.startTransactionTimeout(transaction.id, validatedOptions.maxWait);
543
- const txContext = await this.driverAdapter.transactionContext();
544
- if (!txContext.ok)
564
+ let startedTransaction;
565
+ try {
566
+ startedTransaction = await this.driverAdapter.startTransaction(validatedOptions.isolationLevel);
567
+ } catch (error) {
545
568
  throw new TransactionDriverAdapterError("Failed to start transaction.", {
546
- driverAdapterError: txContext.error
569
+ driverAdapterError: error
547
570
  });
548
- if (this.requiresSettingIsolationLevelFirst() && validatedOptions.isolationLevel) {
549
- await txContext.value.executeRaw(ISOLATION_LEVEL_QUERY(validatedOptions.isolationLevel));
550
- }
551
- const startedTransaction = await txContext.value.startTransaction();
552
- if (!startedTransaction.ok)
553
- throw new TransactionDriverAdapterError("Failed to start transaction.", {
554
- driverAdapterError: startedTransaction.error
555
- });
556
- if (!startedTransaction.value.options.usePhantomQuery) {
557
- await startedTransaction.value.executeRaw({ sql: "BEGIN", args: [], argTypes: [] });
558
- if (!this.requiresSettingIsolationLevelFirst() && validatedOptions.isolationLevel) {
559
- await txContext.value.executeRaw(ISOLATION_LEVEL_QUERY(validatedOptions.isolationLevel));
560
- }
561
571
  }
562
572
  switch (transaction.status) {
563
573
  case "waiting":
564
- transaction.transaction = startedTransaction.value;
574
+ transaction.transaction = startedTransaction;
565
575
  clearTimeout(transaction.timer);
566
576
  transaction.timer = void 0;
567
577
  transaction.status = "running";
@@ -641,20 +651,24 @@ var TransactionManager = class {
641
651
  debug("Closing transaction.", { transactionId: tx.id, status });
642
652
  tx.status = status;
643
653
  if (tx.transaction && status === "committed") {
644
- const result = await tx.transaction.commit();
645
- if (!result.ok)
654
+ try {
655
+ await tx.transaction.commit();
656
+ } catch (error) {
646
657
  throw new TransactionDriverAdapterError("Failed to commit transaction.", {
647
- driverAdapterError: result.error
658
+ driverAdapterError: error
648
659
  });
660
+ }
649
661
  if (!tx.transaction.options.usePhantomQuery) {
650
662
  await tx.transaction.executeRaw(COMMIT_QUERY());
651
663
  }
652
664
  } else if (tx.transaction) {
653
- const result = await tx.transaction.rollback();
654
- if (!result.ok)
665
+ try {
666
+ await tx.transaction.rollback();
667
+ } catch (error) {
655
668
  throw new TransactionDriverAdapterError("Failed to rollback transaction.", {
656
- driverAdapterError: result.error
669
+ driverAdapterError: error
657
670
  });
671
+ }
658
672
  if (!tx.transaction.options.usePhantomQuery) {
659
673
  await tx.transaction.executeRaw(ROLLBACK_QUERY());
660
674
  }
@@ -670,25 +684,19 @@ var TransactionManager = class {
670
684
  validateOptions(options) {
671
685
  if (!options.timeout) throw new TransactionManagerError("timeout is required");
672
686
  if (!options.maxWait) throw new TransactionManagerError("maxWait is required");
673
- if (options.isolationLevel === "Snapshot" /* Snapshot */)
674
- throw new InvalidTransactionIsolationLevelError(options.isolationLevel);
675
- if (this.driverAdapter.provider === "sqlite" && options.isolationLevel && options.isolationLevel !== "Serializable" /* Serializable */)
676
- throw new InvalidTransactionIsolationLevelError(options.isolationLevel);
687
+ if (options.isolationLevel === "SNAPSHOT") throw new InvalidTransactionIsolationLevelError(options.isolationLevel);
677
688
  return {
678
689
  ...options,
679
690
  timeout: options.timeout,
680
691
  maxWait: options.maxWait
681
692
  };
682
693
  }
683
- requiresSettingIsolationLevelFirst() {
684
- return this.driverAdapter.provider === "mysql";
685
- }
686
694
  };
687
695
  // Annotate the CommonJS export names for ESM import in node:
688
696
  0 && (module.exports = {
689
- IsolationLevel,
690
697
  QueryInterpreter,
691
698
  TransactionManager,
692
699
  TransactionManagerError,
700
+ isPrismaValueGenerator,
693
701
  isPrismaValuePlaceholder
694
702
  });