@prisma/client-engine-runtime 6.4.0-dev.24

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 ADDED
@@ -0,0 +1,838 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __typeError = (msg) => {
3
+ throw TypeError(msg);
4
+ };
5
+ var __export = (target, all) => {
6
+ for (var name in all)
7
+ __defProp(target, name, { get: all[name], enumerable: true });
8
+ };
9
+ var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
10
+ var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
11
+ 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);
12
+ var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
13
+ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
14
+
15
+ // src/runtime/core/engines/common/types/Transaction.ts
16
+ var IsolationLevel = /* @__PURE__ */ ((IsolationLevel2) => {
17
+ IsolationLevel2["ReadUncommitted"] = "ReadUncommitted";
18
+ IsolationLevel2["ReadCommitted"] = "ReadCommitted";
19
+ IsolationLevel2["RepeatableRead"] = "RepeatableRead";
20
+ IsolationLevel2["Snapshot"] = "Snapshot";
21
+ IsolationLevel2["Serializable"] = "Serializable";
22
+ return IsolationLevel2;
23
+ })(IsolationLevel || {});
24
+
25
+ // src/runtime/core/engines/client/QueryPlan.ts
26
+ function isPrismaValuePlaceholder(value) {
27
+ return typeof value === "object" && value !== null && value["prisma__type"] === "param";
28
+ }
29
+
30
+ // src/runtime/core/engines/client/interpreter/renderQueryTemplate.ts
31
+ var BEGIN_REPEAT = "/* prisma-comma-repeatable-start */";
32
+ var END_REPEAT = "/* prisma-comma-repeatable-end */";
33
+ function renderQueryTemplate({
34
+ query,
35
+ params
36
+ }) {
37
+ const flattened = [];
38
+ let lastParamId = 1;
39
+ let result = "";
40
+ let templatePos = 0;
41
+ while (templatePos < query.length) {
42
+ if (query.slice(templatePos, templatePos + BEGIN_REPEAT.length) === BEGIN_REPEAT) {
43
+ templatePos += BEGIN_REPEAT.length;
44
+ result += "(";
45
+ const paramNum = parseInt(query.slice(templatePos).match(/^\$(\d+)/)?.[1] ?? "0");
46
+ const arrParam = params[paramNum - 1];
47
+ const expanded = arrParam.map((_, idx) => "$" + (lastParamId + idx)).join(", ");
48
+ result += expanded;
49
+ flattened.push(...arrParam);
50
+ lastParamId += arrParam.length;
51
+ templatePos += query.slice(templatePos).indexOf(END_REPEAT) + END_REPEAT.length;
52
+ result += ")";
53
+ } else if (query[templatePos] === "$") {
54
+ const paramMatch = query.slice(templatePos + 1).match(/^\d+/);
55
+ if (paramMatch) {
56
+ const paramNum = parseInt(paramMatch[0]);
57
+ const paramValue = params[paramNum - 1];
58
+ if (!Array.isArray(paramValue)) {
59
+ result += "$" + lastParamId;
60
+ flattened.push(paramValue);
61
+ lastParamId++;
62
+ templatePos += paramMatch[0].length + 1;
63
+ }
64
+ } else {
65
+ result += query[templatePos];
66
+ templatePos++;
67
+ }
68
+ } else {
69
+ result += query[templatePos];
70
+ templatePos++;
71
+ }
72
+ }
73
+ return {
74
+ query: result,
75
+ params: flattened
76
+ };
77
+ }
78
+
79
+ // src/runtime/core/engines/client/interpreter/renderQuery.ts
80
+ function renderQuery({ query, params }, scope) {
81
+ const substitutedParams = params.map((param) => {
82
+ if (!isPrismaValuePlaceholder(param)) {
83
+ return param;
84
+ }
85
+ const value = scope[param.prisma__value.name];
86
+ if (value === void 0) {
87
+ throw new Error(`Missing value for query variable ${param.prisma__value.name}`);
88
+ }
89
+ return value;
90
+ });
91
+ const { query: renderedQuery, params: expandedParams } = renderQueryTemplate({ query, params: substitutedParams });
92
+ const argTypes = expandedParams.map((param) => toArgType(param));
93
+ return {
94
+ sql: renderedQuery,
95
+ args: expandedParams,
96
+ argTypes
97
+ };
98
+ }
99
+ function toArgType(value) {
100
+ if (value === null) {
101
+ return "Int32";
102
+ }
103
+ if (typeof value === "string") {
104
+ return "Text";
105
+ }
106
+ if (typeof value === "number") {
107
+ return "Numeric";
108
+ }
109
+ if (typeof value === "boolean") {
110
+ return "Boolean";
111
+ }
112
+ if (Array.isArray(value)) {
113
+ return "Array";
114
+ }
115
+ if (isPrismaValuePlaceholder(value)) {
116
+ return placeholderTypeToArgType(value.prisma__value.type);
117
+ }
118
+ return "Json";
119
+ }
120
+ function placeholderTypeToArgType(type) {
121
+ const typeMap = {
122
+ Any: "Json",
123
+ String: "Text",
124
+ Int: "Int32",
125
+ BigInt: "Int64",
126
+ Float: "Double",
127
+ Boolean: "Boolean",
128
+ Decimal: "Numeric",
129
+ Date: "DateTime",
130
+ Object: "Json",
131
+ Bytes: "Bytes",
132
+ Array: "Array"
133
+ };
134
+ const mappedType = typeMap[type];
135
+ if (!mappedType) {
136
+ throw new Error(`Unknown placeholder type: ${type}`);
137
+ }
138
+ return mappedType;
139
+ }
140
+
141
+ // src/runtime/core/engines/client/interpreter/serializer.ts
142
+ function serialize(resultSet) {
143
+ return resultSet.rows.map(
144
+ (row) => row.reduce((acc, value, index) => {
145
+ acc[resultSet.columnNames[index]] = value;
146
+ return acc;
147
+ }, {})
148
+ );
149
+ }
150
+
151
+ // src/runtime/core/engines/client/interpreter/QueryInterpreter.ts
152
+ var _queryable, _placeholderValues, _onQuery, _QueryInterpreter_instances, withQueryEvent_fn;
153
+ var QueryInterpreter = class {
154
+ constructor({ queryable, placeholderValues, onQuery }) {
155
+ __privateAdd(this, _QueryInterpreter_instances);
156
+ __privateAdd(this, _queryable);
157
+ __privateAdd(this, _placeholderValues);
158
+ __privateAdd(this, _onQuery);
159
+ __privateSet(this, _queryable, queryable);
160
+ __privateSet(this, _placeholderValues, placeholderValues);
161
+ __privateSet(this, _onQuery, onQuery);
162
+ }
163
+ async run(queryPlan) {
164
+ return this.interpretNode(queryPlan, __privateGet(this, _placeholderValues));
165
+ }
166
+ async interpretNode(node, scope) {
167
+ switch (node.type) {
168
+ case "seq": {
169
+ const results = await Promise.all(node.args.map((arg) => this.interpretNode(arg, scope)));
170
+ return results[results.length - 1];
171
+ }
172
+ case "get": {
173
+ return scope[node.args.name];
174
+ }
175
+ case "let": {
176
+ const nestedScope = Object.create(scope);
177
+ await Promise.all(
178
+ node.args.bindings.map(async (binding) => {
179
+ nestedScope[binding.name] = await this.interpretNode(binding.expr, scope);
180
+ })
181
+ );
182
+ return this.interpretNode(node.args.expr, nestedScope);
183
+ }
184
+ case "getFirstNonEmpty": {
185
+ for (const name of node.args.names) {
186
+ const value = scope[name];
187
+ if (!isEmpty(value)) {
188
+ return value;
189
+ }
190
+ }
191
+ return [];
192
+ }
193
+ case "concat": {
194
+ const parts = await Promise.all(node.args.map((arg) => this.interpretNode(arg, scope)));
195
+ return parts.reduce((acc, part) => acc.concat(asList(part)), []);
196
+ }
197
+ case "sum": {
198
+ const parts = await Promise.all(node.args.map((arg) => this.interpretNode(arg, scope)));
199
+ return parts.reduce((acc, part) => asNumber(acc) + asNumber(part));
200
+ }
201
+ case "execute": {
202
+ const query = renderQuery(node.args, scope);
203
+ return __privateMethod(this, _QueryInterpreter_instances, withQueryEvent_fn).call(this, query, async () => {
204
+ const result = await __privateGet(this, _queryable).executeRaw(query);
205
+ if (result.ok) {
206
+ return result.value;
207
+ } else {
208
+ throw result.error;
209
+ }
210
+ });
211
+ }
212
+ case "query": {
213
+ const query = renderQuery(node.args, scope);
214
+ return __privateMethod(this, _QueryInterpreter_instances, withQueryEvent_fn).call(this, query, async () => {
215
+ const result = await __privateGet(this, _queryable).queryRaw(query);
216
+ if (result.ok) {
217
+ return serialize(result.value);
218
+ } else {
219
+ throw result.error;
220
+ }
221
+ });
222
+ }
223
+ case "reverse": {
224
+ const value = await this.interpretNode(node.args, scope);
225
+ return Array.isArray(value) ? value.reverse() : value;
226
+ }
227
+ case "unique": {
228
+ const value = await this.interpretNode(node.args, scope);
229
+ if (!Array.isArray(value)) {
230
+ return value;
231
+ }
232
+ if (value.length !== 1) {
233
+ throw new Error(`Expected exactly one element, got ${value.length}`);
234
+ }
235
+ return value[0];
236
+ }
237
+ case "required": {
238
+ const value = await this.interpretNode(node.args, scope);
239
+ if (isEmpty(value)) {
240
+ throw new Error("Required value is empty");
241
+ }
242
+ return value;
243
+ }
244
+ case "mapField": {
245
+ const value = await this.interpretNode(node.args.records, scope);
246
+ return mapField(value, node.args.field);
247
+ }
248
+ case "join": {
249
+ const parent = await this.interpretNode(node.args.parent, scope);
250
+ const children = await Promise.all(
251
+ node.args.children.map(async (joinExpr) => ({
252
+ joinExpr,
253
+ childRecords: await this.interpretNode(joinExpr.child, scope)
254
+ }))
255
+ );
256
+ if (Array.isArray(parent)) {
257
+ for (const record of parent) {
258
+ attachChildrenToParent(asRecord(record), children);
259
+ }
260
+ return parent;
261
+ }
262
+ return attachChildrenToParent(asRecord(parent), children);
263
+ }
264
+ default: {
265
+ node;
266
+ throw new Error(`Unexpected node type: ${node.type}`);
267
+ }
268
+ }
269
+ }
270
+ };
271
+ _queryable = new WeakMap();
272
+ _placeholderValues = new WeakMap();
273
+ _onQuery = new WeakMap();
274
+ _QueryInterpreter_instances = new WeakSet();
275
+ withQueryEvent_fn = async function(query, execute) {
276
+ var _a;
277
+ const timestamp = /* @__PURE__ */ new Date();
278
+ const startInstant = performance.now();
279
+ const result = await execute();
280
+ const endInstant = performance.now();
281
+ (_a = __privateGet(this, _onQuery)) == null ? void 0 : _a.call(this, {
282
+ timestamp,
283
+ duration: endInstant - startInstant,
284
+ query: query.sql,
285
+ // TODO: we should probably change the interface to contain a proper array in the next major version.
286
+ params: JSON.stringify(query.args),
287
+ // TODO: this field only exists for historical reasons as we grandfathered it from the time
288
+ // when we emitted `tracing` events to stdout in the engine unchanged, and then described
289
+ // them in the public API as TS types. Thus this field used to contain the name of the Rust
290
+ // module in which an event originated. When using library engine, which uses a different
291
+ // mechanism with a JavaScript callback for logs, it's normally just an empty string instead.
292
+ // This field is definitely not useful and should be removed from the public types (but it's
293
+ // technically a breaking change, even if a tiny and inconsequential one).
294
+ target: "QueryInterpreter"
295
+ });
296
+ return result;
297
+ };
298
+ function isEmpty(value) {
299
+ if (Array.isArray(value)) {
300
+ return value.length === 0;
301
+ }
302
+ return value == null;
303
+ }
304
+ function asList(value) {
305
+ return Array.isArray(value) ? value : [value];
306
+ }
307
+ function asNumber(value) {
308
+ if (typeof value === "number") {
309
+ return value;
310
+ }
311
+ if (typeof value === "string") {
312
+ return Number(value);
313
+ }
314
+ throw new Error(`Expected number, got ${typeof value}`);
315
+ }
316
+ function asRecord(value) {
317
+ if (typeof value === "object" && value !== null) {
318
+ return value;
319
+ }
320
+ throw new Error(`Expected object, got ${typeof value}`);
321
+ }
322
+ function mapField(value, field) {
323
+ if (Array.isArray(value)) {
324
+ return value.map((element) => mapField(element, field));
325
+ }
326
+ if (typeof value === "object" && value !== null) {
327
+ return value[field] ?? null;
328
+ }
329
+ return value;
330
+ }
331
+ function attachChildrenToParent(parentRecord, children) {
332
+ for (const { joinExpr, childRecords } of children) {
333
+ parentRecord[joinExpr.parentField] = filterChildRecords(childRecords, parentRecord, joinExpr);
334
+ }
335
+ return parentRecord;
336
+ }
337
+ function filterChildRecords(records, parentRecord, joinExpr) {
338
+ if (Array.isArray(records)) {
339
+ return records.filter((record) => childRecordMatchesParent(asRecord(record), parentRecord, joinExpr));
340
+ } else {
341
+ const record = asRecord(records);
342
+ return childRecordMatchesParent(record, parentRecord, joinExpr) ? record : null;
343
+ }
344
+ }
345
+ function childRecordMatchesParent(childRecord, parentRecord, joinExpr) {
346
+ for (const [parentField, childField] of joinExpr.on) {
347
+ if (parentRecord[parentField] !== childRecord[childField]) {
348
+ return false;
349
+ }
350
+ }
351
+ return true;
352
+ }
353
+
354
+ // ../../node_modules/.pnpm/kleur@4.1.5/node_modules/kleur/colors.mjs
355
+ var colors_exports = {};
356
+ __export(colors_exports, {
357
+ $: () => $,
358
+ bgBlack: () => bgBlack,
359
+ bgBlue: () => bgBlue,
360
+ bgCyan: () => bgCyan,
361
+ bgGreen: () => bgGreen,
362
+ bgMagenta: () => bgMagenta,
363
+ bgRed: () => bgRed,
364
+ bgWhite: () => bgWhite,
365
+ bgYellow: () => bgYellow,
366
+ black: () => black,
367
+ blue: () => blue,
368
+ bold: () => bold,
369
+ cyan: () => cyan,
370
+ dim: () => dim,
371
+ gray: () => gray,
372
+ green: () => green,
373
+ grey: () => grey,
374
+ hidden: () => hidden,
375
+ inverse: () => inverse,
376
+ italic: () => italic,
377
+ magenta: () => magenta,
378
+ red: () => red,
379
+ reset: () => reset,
380
+ strikethrough: () => strikethrough,
381
+ underline: () => underline,
382
+ white: () => white,
383
+ yellow: () => yellow
384
+ });
385
+ var FORCE_COLOR;
386
+ var NODE_DISABLE_COLORS;
387
+ var NO_COLOR;
388
+ var TERM;
389
+ var isTTY = true;
390
+ if (typeof process !== "undefined") {
391
+ ({ FORCE_COLOR, NODE_DISABLE_COLORS, NO_COLOR, TERM } = process.env || {});
392
+ isTTY = process.stdout && process.stdout.isTTY;
393
+ }
394
+ var $ = {
395
+ enabled: !NODE_DISABLE_COLORS && NO_COLOR == null && TERM !== "dumb" && (FORCE_COLOR != null && FORCE_COLOR !== "0" || isTTY)
396
+ };
397
+ function init(x, y) {
398
+ let rgx = new RegExp(`\\x1b\\[${y}m`, "g");
399
+ let open = `\x1B[${x}m`, close = `\x1B[${y}m`;
400
+ return function(txt) {
401
+ if (!$.enabled || txt == null) return txt;
402
+ return open + (!!~("" + txt).indexOf(close) ? txt.replace(rgx, close + open) : txt) + close;
403
+ };
404
+ }
405
+ var reset = init(0, 0);
406
+ var bold = init(1, 22);
407
+ var dim = init(2, 22);
408
+ var italic = init(3, 23);
409
+ var underline = init(4, 24);
410
+ var inverse = init(7, 27);
411
+ var hidden = init(8, 28);
412
+ var strikethrough = init(9, 29);
413
+ var black = init(30, 39);
414
+ var red = init(31, 39);
415
+ var green = init(32, 39);
416
+ var yellow = init(33, 39);
417
+ var blue = init(34, 39);
418
+ var magenta = init(35, 39);
419
+ var cyan = init(36, 39);
420
+ var white = init(37, 39);
421
+ var gray = init(90, 39);
422
+ var grey = init(90, 39);
423
+ var bgBlack = init(40, 49);
424
+ var bgRed = init(41, 49);
425
+ var bgGreen = init(42, 49);
426
+ var bgYellow = init(43, 49);
427
+ var bgBlue = init(44, 49);
428
+ var bgMagenta = init(45, 49);
429
+ var bgCyan = init(46, 49);
430
+ var bgWhite = init(47, 49);
431
+
432
+ // ../debug/src/index.ts
433
+ var MAX_ARGS_HISTORY = 100;
434
+ var COLORS = ["green", "yellow", "blue", "magenta", "cyan", "red"];
435
+ var argsHistory = [];
436
+ var lastTimestamp = Date.now();
437
+ var lastColor = 0;
438
+ var processEnv = typeof process !== "undefined" ? process.env : {};
439
+ globalThis.DEBUG ??= processEnv.DEBUG ?? "";
440
+ globalThis.DEBUG_COLORS ??= processEnv.DEBUG_COLORS ? processEnv.DEBUG_COLORS === "true" : true;
441
+ var topProps = {
442
+ enable(namespace) {
443
+ if (typeof namespace === "string") {
444
+ globalThis.DEBUG = namespace;
445
+ }
446
+ },
447
+ disable() {
448
+ const prev = globalThis.DEBUG;
449
+ globalThis.DEBUG = "";
450
+ return prev;
451
+ },
452
+ // this is the core logic to check if logging should happen or not
453
+ enabled(namespace) {
454
+ const listenedNamespaces = globalThis.DEBUG.split(",").map((s) => {
455
+ return s.replace(/[.+?^${}()|[\]\\]/g, "\\$&");
456
+ });
457
+ const isListened = listenedNamespaces.some((listenedNamespace) => {
458
+ if (listenedNamespace === "" || listenedNamespace[0] === "-") return false;
459
+ return namespace.match(RegExp(listenedNamespace.split("*").join(".*") + "$"));
460
+ });
461
+ const isExcluded = listenedNamespaces.some((listenedNamespace) => {
462
+ if (listenedNamespace === "" || listenedNamespace[0] !== "-") return false;
463
+ return namespace.match(RegExp(listenedNamespace.slice(1).split("*").join(".*") + "$"));
464
+ });
465
+ return isListened && !isExcluded;
466
+ },
467
+ log: (...args) => {
468
+ const [namespace, format, ...rest] = args;
469
+ const logWithFormatting = console.warn ?? console.log;
470
+ logWithFormatting(`${namespace} ${format}`, ...rest);
471
+ },
472
+ formatters: {}
473
+ // not implemented
474
+ };
475
+ function debugCreate(namespace) {
476
+ const instanceProps = {
477
+ color: COLORS[lastColor++ % COLORS.length],
478
+ enabled: topProps.enabled(namespace),
479
+ namespace,
480
+ log: topProps.log,
481
+ extend: () => {
482
+ }
483
+ // not implemented
484
+ };
485
+ const debugCall = (...args) => {
486
+ const { enabled, namespace: namespace2, color, log } = instanceProps;
487
+ if (args.length !== 0) {
488
+ argsHistory.push([namespace2, ...args]);
489
+ }
490
+ if (argsHistory.length > MAX_ARGS_HISTORY) {
491
+ argsHistory.shift();
492
+ }
493
+ if (topProps.enabled(namespace2) || enabled) {
494
+ const stringArgs = args.map((arg) => {
495
+ if (typeof arg === "string") {
496
+ return arg;
497
+ }
498
+ return safeStringify(arg);
499
+ });
500
+ const ms = `+${Date.now() - lastTimestamp}ms`;
501
+ lastTimestamp = Date.now();
502
+ if (globalThis.DEBUG_COLORS) {
503
+ log(colors_exports[color](bold(namespace2)), ...stringArgs, colors_exports[color](ms));
504
+ } else {
505
+ log(namespace2, ...stringArgs, ms);
506
+ }
507
+ }
508
+ };
509
+ return new Proxy(debugCall, {
510
+ get: (_, prop) => instanceProps[prop],
511
+ set: (_, prop, value) => instanceProps[prop] = value
512
+ });
513
+ }
514
+ var Debug = new Proxy(debugCreate, {
515
+ get: (_, prop) => topProps[prop],
516
+ set: (_, prop, value) => topProps[prop] = value
517
+ });
518
+ function safeStringify(value, indent = 2) {
519
+ const cache = /* @__PURE__ */ new Set();
520
+ return JSON.stringify(
521
+ value,
522
+ (key, value2) => {
523
+ if (typeof value2 === "object" && value2 !== null) {
524
+ if (cache.has(value2)) {
525
+ return `[Circular *]`;
526
+ }
527
+ cache.add(value2);
528
+ } else if (typeof value2 === "bigint") {
529
+ return value2.toString();
530
+ }
531
+ return value2;
532
+ },
533
+ indent
534
+ );
535
+ }
536
+ var src_default = Debug;
537
+
538
+ // ../internals/src/utils/assertNever.ts
539
+ function assertNever(arg, errorMessage) {
540
+ throw new Error(errorMessage);
541
+ }
542
+
543
+ // ../internals/src/utils/setClassName.ts
544
+ function setClassName(classObject, name) {
545
+ Object.defineProperty(classObject, "name", {
546
+ value: name,
547
+ configurable: true
548
+ });
549
+ }
550
+
551
+ // src/runtime/core/engines/client/transactionManager/TransactionManager.ts
552
+ import crypto from "crypto";
553
+
554
+ // src/runtime/core/errors/PrismaClientKnownRequestError.ts
555
+ var PrismaClientKnownRequestError = class extends Error {
556
+ constructor(message, { code, clientVersion, meta, batchRequestIdx }) {
557
+ super(message);
558
+ this.name = "PrismaClientKnownRequestError";
559
+ this.code = code;
560
+ this.clientVersion = clientVersion;
561
+ this.meta = meta;
562
+ Object.defineProperty(this, "batchRequestIdx", {
563
+ value: batchRequestIdx,
564
+ enumerable: false,
565
+ writable: true
566
+ });
567
+ }
568
+ get [Symbol.toStringTag]() {
569
+ return "PrismaClientKnownRequestError";
570
+ }
571
+ };
572
+ setClassName(PrismaClientKnownRequestError, "PrismaClientKnownRequestError");
573
+
574
+ // src/runtime/core/engines/client/transactionManager/TransactionManagerErrors.ts
575
+ var TransactionManagerError = class extends PrismaClientKnownRequestError {
576
+ constructor(message, {
577
+ clientVersion,
578
+ meta
579
+ }) {
580
+ super("Transaction API error: " + message, {
581
+ code: "P2028",
582
+ clientVersion,
583
+ meta
584
+ });
585
+ }
586
+ };
587
+ var TransactionDriverAdapterError = class extends TransactionManagerError {
588
+ constructor(message, errorParams) {
589
+ super(`Error from Driver Adapter: ${message}`, {
590
+ clientVersion: errorParams.clientVersion,
591
+ meta: {
592
+ ...errorParams.driverAdapterError
593
+ }
594
+ });
595
+ }
596
+ };
597
+ var TransactionNotFoundError = class extends TransactionManagerError {
598
+ constructor(errorParams) {
599
+ super(
600
+ "Transaction not found. Transaction ID is invalid, refers to an old closed transaction Prisma doesn't have information about anymore, or was obtained before disconnecting.",
601
+ errorParams
602
+ );
603
+ }
604
+ };
605
+ var TransactionClosedError = class extends TransactionManagerError {
606
+ constructor(operation, errorParams) {
607
+ super(`Transaction already closed: A ${operation} cannot be executed on a committed transaction`, errorParams);
608
+ }
609
+ };
610
+ var TransactionRolledBackError = class extends TransactionManagerError {
611
+ constructor(operation, errorParams) {
612
+ super(`Transaction already closed: A ${operation} cannot be executed on a committed transaction`, errorParams);
613
+ }
614
+ };
615
+ var TransactionStartTimoutError = class extends TransactionManagerError {
616
+ constructor(errorParams) {
617
+ super("Unable to start a transaction in the given time.", errorParams);
618
+ }
619
+ };
620
+ var TransactionExecutionTimeoutError = class extends TransactionManagerError {
621
+ constructor(operation, { clientVersion, timeout, timeTaken }) {
622
+ super(
623
+ `A ${operation} cannot be executed on an expired transaction. The timeout for this transaction was ${timeout} ms, however ${timeTaken} ms passed since the start of the transaction. Consider increasing the interactive transaction timeout or doing less work in the transaction`,
624
+ { clientVersion }
625
+ );
626
+ }
627
+ };
628
+ var TransactionInternalConsistencyError = class extends TransactionManagerError {
629
+ constructor(message, errorParams) {
630
+ super(`Internal Consistency Error: ${message}`, errorParams);
631
+ }
632
+ };
633
+ var InvalidTransactionIsolationLevelError = class extends TransactionManagerError {
634
+ constructor(isolationLevel, errorParams) {
635
+ super(`Invalid isolation level: ${isolationLevel}`, errorParams);
636
+ }
637
+ };
638
+
639
+ // src/runtime/core/engines/client/transactionManager/TransactionManager.ts
640
+ var MAX_CLOSED_TRANSACTIONS = 100;
641
+ var isolationLevelMap = {
642
+ ReadUncommitted: "READ UNCOMMITTED",
643
+ ReadCommitted: "READ COMMITTED",
644
+ RepeatableRead: "REPEATABLE READ",
645
+ Snapshot: "SNAPSHOT",
646
+ Serializable: "SERIALIZABLE"
647
+ };
648
+ var debug = src_default("prisma:client:transactionManager");
649
+ var COMMIT_QUERY = () => ({ sql: "COMMIT", args: [], argTypes: [] });
650
+ var ROLLBACK_QUERY = () => ({ sql: "ROLLBACK", args: [], argTypes: [] });
651
+ var ISOLATION_LEVEL_QUERY = (isolationLevel) => ({
652
+ sql: "SET TRANSACTION ISOLATION LEVEL " + isolationLevelMap[isolationLevel],
653
+ args: [],
654
+ argTypes: []
655
+ });
656
+ var TransactionManager = class {
657
+ constructor({ driverAdapter, clientVersion }) {
658
+ // The map of active transactions.
659
+ this.transactions = /* @__PURE__ */ new Map();
660
+ // List of last closed transactions. Max MAX_CLOSED_TRANSACTIONS entries.
661
+ // Used to provide better error messages than a generic "transaction not found".
662
+ this.closedTransactions = [];
663
+ this.driverAdapter = driverAdapter;
664
+ this.clientVersion = clientVersion;
665
+ }
666
+ async startTransaction(options) {
667
+ const validatedOptions = this.validateOptions(options);
668
+ const transaction = {
669
+ id: crypto.randomUUID(),
670
+ status: "waiting",
671
+ timer: void 0,
672
+ timeout: validatedOptions.timeout,
673
+ startedAt: Date.now(),
674
+ transaction: void 0
675
+ };
676
+ this.transactions.set(transaction.id, transaction);
677
+ transaction.timer = this.startTransactionTimeout(transaction.id, validatedOptions.maxWait);
678
+ const txContext = await this.driverAdapter.transactionContext();
679
+ if (!txContext.ok)
680
+ throw new TransactionDriverAdapterError("Failed to start transaction.", {
681
+ driverAdapterError: txContext.error,
682
+ clientVersion: this.clientVersion
683
+ });
684
+ if (this.requiresSettingIsolationLevelFirst() && validatedOptions.isolationLevel) {
685
+ await txContext.value.executeRaw(ISOLATION_LEVEL_QUERY(validatedOptions.isolationLevel));
686
+ }
687
+ const startedTransaction = await txContext.value.startTransaction();
688
+ if (!startedTransaction.ok)
689
+ throw new TransactionDriverAdapterError("Failed to start transaction.", {
690
+ driverAdapterError: startedTransaction.error,
691
+ clientVersion: this.clientVersion
692
+ });
693
+ if (!startedTransaction.value.options.usePhantomQuery) {
694
+ await startedTransaction.value.executeRaw({ sql: "BEGIN", args: [], argTypes: [] });
695
+ if (!this.requiresSettingIsolationLevelFirst() && validatedOptions.isolationLevel) {
696
+ await txContext.value.executeRaw(ISOLATION_LEVEL_QUERY(validatedOptions.isolationLevel));
697
+ }
698
+ }
699
+ switch (transaction.status) {
700
+ case "waiting":
701
+ transaction.transaction = startedTransaction.value;
702
+ clearTimeout(transaction.timer);
703
+ transaction.timer = void 0;
704
+ transaction.status = "running";
705
+ transaction.timer = this.startTransactionTimeout(transaction.id, validatedOptions.timeout);
706
+ return { id: transaction.id, payload: void 0 };
707
+ case "timed_out":
708
+ throw new TransactionStartTimoutError({ clientVersion: this.clientVersion });
709
+ case "running":
710
+ case "committed":
711
+ case "rolled_back":
712
+ throw new TransactionInternalConsistencyError(
713
+ `Transaction in invalid state ${transaction.status} although it just finished startup.`,
714
+ {
715
+ clientVersion: this.clientVersion
716
+ }
717
+ );
718
+ default:
719
+ assertNever(transaction.status, "Unknown transaction status.");
720
+ }
721
+ }
722
+ async commitTransaction(transactionId) {
723
+ const txw = this.getActiveTransaction(transactionId, "commit");
724
+ await this.closeTransaction(txw, "committed");
725
+ }
726
+ async rollbackTransaction(transactionId) {
727
+ const txw = this.getActiveTransaction(transactionId, "rollback");
728
+ await this.closeTransaction(txw, "rolled_back");
729
+ }
730
+ getTransaction(txInfo, operation) {
731
+ const tx = this.getActiveTransaction(txInfo.id, operation);
732
+ if (!tx.transaction) throw new TransactionNotFoundError({ clientVersion: this.clientVersion });
733
+ return tx.transaction;
734
+ }
735
+ getActiveTransaction(transactionId, operation) {
736
+ const transaction = this.transactions.get(transactionId);
737
+ if (!transaction) {
738
+ const closedTransaction = this.closedTransactions.find((tx) => tx.id === transactionId);
739
+ if (closedTransaction) {
740
+ debug("Transaction already closed.", { transactionId, status: closedTransaction.status });
741
+ switch (closedTransaction.status) {
742
+ case "waiting":
743
+ case "running":
744
+ throw new TransactionInternalConsistencyError("Active transaction found in closed transactions list.", {
745
+ clientVersion: this.clientVersion
746
+ });
747
+ case "committed":
748
+ throw new TransactionClosedError(operation, { clientVersion: this.clientVersion });
749
+ case "rolled_back":
750
+ throw new TransactionRolledBackError(operation, { clientVersion: this.clientVersion });
751
+ case "timed_out":
752
+ throw new TransactionExecutionTimeoutError(operation, {
753
+ timeout: closedTransaction.timeout,
754
+ timeTaken: Date.now() - closedTransaction.startedAt,
755
+ clientVersion: this.clientVersion
756
+ });
757
+ }
758
+ } else {
759
+ debug(`Transaction not found.`, transactionId);
760
+ throw new TransactionNotFoundError({ clientVersion: this.clientVersion });
761
+ }
762
+ }
763
+ if (["committed", "rolled_back", "timed_out"].includes(transaction.status)) {
764
+ throw new TransactionInternalConsistencyError("Closed transaction found in active transactions map.", {
765
+ clientVersion: this.clientVersion
766
+ });
767
+ }
768
+ return transaction;
769
+ }
770
+ startTransactionTimeout(transactionId, timeout) {
771
+ const timeoutStartedAt = Date.now();
772
+ return setTimeout(async () => {
773
+ debug("Transaction timed out.", { transactionId, timeoutStartedAt, timeout });
774
+ const tx = this.transactions.get(transactionId);
775
+ if (tx && ["running", "waiting"].includes(tx.status)) {
776
+ await this.closeTransaction(tx, "timed_out");
777
+ } else {
778
+ debug("Transaction already committed or rolled back when timeout happened.", transactionId);
779
+ }
780
+ }, timeout);
781
+ }
782
+ async closeTransaction(tx, status) {
783
+ debug("Closing transaction.", { transactionId: tx.id, status });
784
+ tx.status = status;
785
+ if (tx.transaction && status === "committed") {
786
+ const result = await tx.transaction.commit();
787
+ if (!result.ok)
788
+ throw new TransactionDriverAdapterError("Failed to commit transaction.", {
789
+ driverAdapterError: result.error,
790
+ clientVersion: this.clientVersion
791
+ });
792
+ if (!tx.transaction.options.usePhantomQuery) {
793
+ await tx.transaction.executeRaw(COMMIT_QUERY());
794
+ }
795
+ } else if (tx.transaction) {
796
+ const result = await tx.transaction.rollback();
797
+ if (!result.ok)
798
+ throw new TransactionDriverAdapterError("Failed to rollback transaction.", {
799
+ driverAdapterError: result.error,
800
+ clientVersion: this.clientVersion
801
+ });
802
+ if (!tx.transaction.options.usePhantomQuery) {
803
+ await tx.transaction.executeRaw(ROLLBACK_QUERY());
804
+ }
805
+ }
806
+ clearTimeout(tx.timer);
807
+ tx.timer = void 0;
808
+ this.transactions.delete(tx.id);
809
+ this.closedTransactions.push(tx);
810
+ if (this.closedTransactions.length > MAX_CLOSED_TRANSACTIONS) {
811
+ this.closedTransactions.shift();
812
+ }
813
+ }
814
+ validateOptions(options) {
815
+ if (!options.timeout)
816
+ throw new TransactionManagerError("timeout is required", { clientVersion: this.clientVersion });
817
+ if (!options.maxWait)
818
+ throw new TransactionManagerError("maxWait is required", { clientVersion: this.clientVersion });
819
+ if (options.isolationLevel === "Snapshot" /* Snapshot */)
820
+ throw new InvalidTransactionIsolationLevelError(options.isolationLevel, { clientVersion: this.clientVersion });
821
+ if (this.driverAdapter.provider === "sqlite" && options.isolationLevel && options.isolationLevel !== "Serializable" /* Serializable */)
822
+ throw new InvalidTransactionIsolationLevelError(options.isolationLevel, { clientVersion: this.clientVersion });
823
+ return {
824
+ ...options,
825
+ timeout: options.timeout,
826
+ maxWait: options.maxWait
827
+ };
828
+ }
829
+ requiresSettingIsolationLevelFirst() {
830
+ return this.driverAdapter.provider === "mysql";
831
+ }
832
+ };
833
+ export {
834
+ IsolationLevel,
835
+ QueryInterpreter,
836
+ TransactionManager,
837
+ isPrismaValuePlaceholder
838
+ };