@prisma/client-engine-runtime 6.6.0-dev.8 → 6.6.0-dev.80
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/QueryPlan.d.ts +28 -2
- package/dist/crypto.d.ts +1 -0
- package/dist/index.d.mts +39 -17
- package/dist/index.d.ts +39 -17
- package/dist/index.js +222 -232
- package/dist/index.mjs +219 -231
- package/dist/interpreter/QueryInterpreter.d.ts +2 -2
- package/dist/interpreter/generators.d.ts +21 -0
- package/dist/interpreter/renderQuery.d.ts +3 -2
- package/dist/interpreter/renderQuery.test.d.ts +1 -0
- package/dist/transactionManager/Transaction.d.ts +1 -7
- package/dist/transactionManager/TransactionManager.d.ts +3 -4
- package/package.json +9 -4
- package/dist/interpreter/renderQueryTemplate.d.ts +0 -10
- /package/dist/interpreter/{renderQueryTemplate.test.d.ts → generators.test.d.ts} +0 -0
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/
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
var
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
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
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
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
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
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
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
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
|
-
|
|
149
|
-
|
|
150
|
-
|
|
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(
|
|
156
|
-
const
|
|
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
|
-
|
|
167
|
-
|
|
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
|
|
170
|
-
args:
|
|
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 {
|
|
277
|
+
#queryable;
|
|
278
|
+
#placeholderValues;
|
|
279
|
+
#onQuery;
|
|
280
|
+
#generators = new GeneratorRegistry();
|
|
241
281
|
constructor({ queryable, placeholderValues, onQuery }) {
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
__privateAdd(this, _onQuery);
|
|
246
|
-
__privateSet(this, _queryable, queryable);
|
|
247
|
-
__privateSet(this, _placeholderValues, placeholderValues);
|
|
248
|
-
__privateSet(this, _onQuery, onQuery);
|
|
282
|
+
this.#queryable = queryable;
|
|
283
|
+
this.#placeholderValues = placeholderValues;
|
|
284
|
+
this.#onQuery = onQuery;
|
|
249
285
|
}
|
|
250
286
|
async run(queryPlan) {
|
|
251
|
-
return this.interpretNode(queryPlan,
|
|
287
|
+
return this.interpretNode(queryPlan, this.#placeholderValues, this.#generators.snapshot());
|
|
252
288
|
}
|
|
253
|
-
async interpretNode(node, scope) {
|
|
289
|
+
async interpretNode(node, 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, 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, scope, generators);
|
|
267
303
|
})
|
|
268
304
|
);
|
|
269
|
-
return this.interpretNode(node.args.expr, nestedScope);
|
|
305
|
+
return this.interpretNode(node.args.expr, 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, 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, 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
|
|
291
|
-
|
|
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 this.#queryable.executeRaw(query);
|
|
297
328
|
});
|
|
298
329
|
}
|
|
299
330
|
case "query": {
|
|
300
|
-
const query = renderQuery(node.args, scope);
|
|
301
|
-
return
|
|
302
|
-
|
|
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 this.#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, 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, 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, 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, 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, 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, scope, generators)
|
|
341
367
|
}))
|
|
342
368
|
);
|
|
343
369
|
if (Array.isArray(parent)) {
|
|
@@ -354,24 +380,19 @@ var QueryInterpreter = class {
|
|
|
354
380
|
}
|
|
355
381
|
}
|
|
356
382
|
}
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
duration: endInstant - startInstant,
|
|
371
|
-
query: query.sql,
|
|
372
|
-
params: query.args
|
|
373
|
-
});
|
|
374
|
-
return result;
|
|
383
|
+
async #withQueryEvent(query, execute) {
|
|
384
|
+
const timestamp = /* @__PURE__ */ new Date();
|
|
385
|
+
const startInstant = performance.now();
|
|
386
|
+
const result = await execute();
|
|
387
|
+
const endInstant = performance.now();
|
|
388
|
+
this.#onQuery?.({
|
|
389
|
+
timestamp,
|
|
390
|
+
duration: endInstant - startInstant,
|
|
391
|
+
query: query.sql,
|
|
392
|
+
params: query.args
|
|
393
|
+
});
|
|
394
|
+
return result;
|
|
395
|
+
}
|
|
375
396
|
};
|
|
376
397
|
function isEmpty(value) {
|
|
377
398
|
if (Array.isArray(value)) {
|
|
@@ -429,22 +450,16 @@ function childRecordMatchesParent(childRecord, parentRecord, joinExpr) {
|
|
|
429
450
|
return true;
|
|
430
451
|
}
|
|
431
452
|
|
|
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
453
|
// src/transactionManager/TransactionManager.ts
|
|
443
454
|
var import_debug = __toESM(require("@prisma/debug"));
|
|
444
455
|
|
|
445
|
-
// src/
|
|
446
|
-
function
|
|
447
|
-
|
|
456
|
+
// src/crypto.ts
|
|
457
|
+
async function getCrypto() {
|
|
458
|
+
return globalThis.crypto ?? await import("node:crypto");
|
|
459
|
+
}
|
|
460
|
+
async function randomUUID() {
|
|
461
|
+
const crypto = await getCrypto();
|
|
462
|
+
return crypto.randomUUID();
|
|
448
463
|
}
|
|
449
464
|
|
|
450
465
|
// src/transactionManager/TransactionManagerErrors.ts
|
|
@@ -452,8 +467,8 @@ var TransactionManagerError = class extends Error {
|
|
|
452
467
|
constructor(message, meta) {
|
|
453
468
|
super("Transaction API error: " + message);
|
|
454
469
|
this.meta = meta;
|
|
455
|
-
__publicField(this, "code", "P2028");
|
|
456
470
|
}
|
|
471
|
+
code = "P2028";
|
|
457
472
|
};
|
|
458
473
|
var TransactionDriverAdapterError = class extends TransactionManagerError {
|
|
459
474
|
constructor(message, errorParams) {
|
|
@@ -503,35 +518,23 @@ var InvalidTransactionIsolationLevelError = class extends TransactionManagerErro
|
|
|
503
518
|
|
|
504
519
|
// src/transactionManager/TransactionManager.ts
|
|
505
520
|
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
521
|
var debug = (0, import_debug.default)("prisma:client:transactionManager");
|
|
514
522
|
var COMMIT_QUERY = () => ({ sql: "COMMIT", args: [], argTypes: [] });
|
|
515
523
|
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
524
|
var TransactionManager = class {
|
|
525
|
+
// The map of active transactions.
|
|
526
|
+
transactions = /* @__PURE__ */ new Map();
|
|
527
|
+
// List of last closed transactions. Max MAX_CLOSED_TRANSACTIONS entries.
|
|
528
|
+
// Used to provide better error messages than a generic "transaction not found".
|
|
529
|
+
closedTransactions = [];
|
|
530
|
+
driverAdapter;
|
|
522
531
|
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");
|
|
529
532
|
this.driverAdapter = driverAdapter;
|
|
530
533
|
}
|
|
531
534
|
async startTransaction(options) {
|
|
532
535
|
const validatedOptions = this.validateOptions(options);
|
|
533
536
|
const transaction = {
|
|
534
|
-
id:
|
|
537
|
+
id: await randomUUID(),
|
|
535
538
|
status: "waiting",
|
|
536
539
|
timer: void 0,
|
|
537
540
|
timeout: validatedOptions.timeout,
|
|
@@ -540,28 +543,17 @@ var TransactionManager = class {
|
|
|
540
543
|
};
|
|
541
544
|
this.transactions.set(transaction.id, transaction);
|
|
542
545
|
transaction.timer = this.startTransactionTimeout(transaction.id, validatedOptions.maxWait);
|
|
543
|
-
|
|
544
|
-
|
|
546
|
+
let startedTransaction;
|
|
547
|
+
try {
|
|
548
|
+
startedTransaction = await this.driverAdapter.startTransaction(validatedOptions.isolationLevel);
|
|
549
|
+
} catch (error) {
|
|
545
550
|
throw new TransactionDriverAdapterError("Failed to start transaction.", {
|
|
546
|
-
driverAdapterError:
|
|
551
|
+
driverAdapterError: error
|
|
547
552
|
});
|
|
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
553
|
}
|
|
562
554
|
switch (transaction.status) {
|
|
563
555
|
case "waiting":
|
|
564
|
-
transaction.transaction = startedTransaction
|
|
556
|
+
transaction.transaction = startedTransaction;
|
|
565
557
|
clearTimeout(transaction.timer);
|
|
566
558
|
transaction.timer = void 0;
|
|
567
559
|
transaction.status = "running";
|
|
@@ -641,20 +633,24 @@ var TransactionManager = class {
|
|
|
641
633
|
debug("Closing transaction.", { transactionId: tx.id, status });
|
|
642
634
|
tx.status = status;
|
|
643
635
|
if (tx.transaction && status === "committed") {
|
|
644
|
-
|
|
645
|
-
|
|
636
|
+
try {
|
|
637
|
+
await tx.transaction.commit();
|
|
638
|
+
} catch (error) {
|
|
646
639
|
throw new TransactionDriverAdapterError("Failed to commit transaction.", {
|
|
647
|
-
driverAdapterError:
|
|
640
|
+
driverAdapterError: error
|
|
648
641
|
});
|
|
642
|
+
}
|
|
649
643
|
if (!tx.transaction.options.usePhantomQuery) {
|
|
650
644
|
await tx.transaction.executeRaw(COMMIT_QUERY());
|
|
651
645
|
}
|
|
652
646
|
} else if (tx.transaction) {
|
|
653
|
-
|
|
654
|
-
|
|
647
|
+
try {
|
|
648
|
+
await tx.transaction.rollback();
|
|
649
|
+
} catch (error) {
|
|
655
650
|
throw new TransactionDriverAdapterError("Failed to rollback transaction.", {
|
|
656
|
-
driverAdapterError:
|
|
651
|
+
driverAdapterError: error
|
|
657
652
|
});
|
|
653
|
+
}
|
|
658
654
|
if (!tx.transaction.options.usePhantomQuery) {
|
|
659
655
|
await tx.transaction.executeRaw(ROLLBACK_QUERY());
|
|
660
656
|
}
|
|
@@ -670,25 +666,19 @@ var TransactionManager = class {
|
|
|
670
666
|
validateOptions(options) {
|
|
671
667
|
if (!options.timeout) throw new TransactionManagerError("timeout is required");
|
|
672
668
|
if (!options.maxWait) throw new TransactionManagerError("maxWait is required");
|
|
673
|
-
if (options.isolationLevel === "
|
|
674
|
-
throw new InvalidTransactionIsolationLevelError(options.isolationLevel);
|
|
675
|
-
if (this.driverAdapter.provider === "sqlite" && options.isolationLevel && options.isolationLevel !== "Serializable" /* Serializable */)
|
|
676
|
-
throw new InvalidTransactionIsolationLevelError(options.isolationLevel);
|
|
669
|
+
if (options.isolationLevel === "SNAPSHOT") throw new InvalidTransactionIsolationLevelError(options.isolationLevel);
|
|
677
670
|
return {
|
|
678
671
|
...options,
|
|
679
672
|
timeout: options.timeout,
|
|
680
673
|
maxWait: options.maxWait
|
|
681
674
|
};
|
|
682
675
|
}
|
|
683
|
-
requiresSettingIsolationLevelFirst() {
|
|
684
|
-
return this.driverAdapter.provider === "mysql";
|
|
685
|
-
}
|
|
686
676
|
};
|
|
687
677
|
// Annotate the CommonJS export names for ESM import in node:
|
|
688
678
|
0 && (module.exports = {
|
|
689
|
-
IsolationLevel,
|
|
690
679
|
QueryInterpreter,
|
|
691
680
|
TransactionManager,
|
|
692
681
|
TransactionManagerError,
|
|
682
|
+
isPrismaValueGenerator,
|
|
693
683
|
isPrismaValuePlaceholder
|
|
694
684
|
});
|