@prisma/client-engine-runtime
Advanced tools
| export type QueryEvent = { | ||
| timestamp: Date; | ||
| query: string; | ||
| params: unknown[]; | ||
| duration: number; | ||
| }; |
+652
| var __typeError = (msg) => { | ||
| throw TypeError(msg); | ||
| }; | ||
| var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg); | ||
| var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj)); | ||
| 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); | ||
| var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value); | ||
| var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method); | ||
| // src/QueryPlan.ts | ||
| function isPrismaValuePlaceholder(value) { | ||
| return typeof value === "object" && value !== null && value["prisma__type"] === "param"; | ||
| } | ||
| // src/interpreter/renderQueryTemplate.ts | ||
| var BEGIN_REPEAT = "/* prisma-comma-repeatable-start */"; | ||
| var END_REPEAT = "/* prisma-comma-repeatable-end */"; | ||
| function renderQueryTemplate({ | ||
| query, | ||
| params | ||
| }) { | ||
| if (!query.includes(BEGIN_REPEAT)) { | ||
| return { query, params }; | ||
| } | ||
| const flattenedParams = []; | ||
| let lastParamId = 1; | ||
| let result = ""; | ||
| let templatePos = 0; | ||
| let state = 0 /* Normal */; | ||
| let stateBeforeQuote = 0 /* Normal */; | ||
| while (templatePos < query.length) { | ||
| const nextChar = query[templatePos]; | ||
| if (state === 1 /* Quoted */ && nextChar !== '"') { | ||
| result += nextChar; | ||
| templatePos++; | ||
| continue; | ||
| } | ||
| if (nextChar === '"') { | ||
| if (state === 1 /* Quoted */) { | ||
| state = stateBeforeQuote; | ||
| } else { | ||
| stateBeforeQuote = state; | ||
| state = 1 /* Quoted */; | ||
| } | ||
| result += nextChar; | ||
| templatePos++; | ||
| continue; | ||
| } | ||
| if (query.slice(templatePos, templatePos + BEGIN_REPEAT.length) === BEGIN_REPEAT) { | ||
| if (state === 2 /* Repeating */) { | ||
| throw new Error("Nested repetition is not allowed"); | ||
| } | ||
| state = 2 /* Repeating */; | ||
| templatePos += BEGIN_REPEAT.length; | ||
| result += "("; | ||
| continue; | ||
| } | ||
| if (query.slice(templatePos, templatePos + END_REPEAT.length) === END_REPEAT) { | ||
| if (state === 0 /* Normal */) { | ||
| throw new Error("Unmatched repetition end"); | ||
| } | ||
| state = 0 /* Normal */; | ||
| templatePos += END_REPEAT.length; | ||
| result += ")"; | ||
| continue; | ||
| } | ||
| if (nextChar === "$") { | ||
| const paramMatch = query.slice(templatePos + 1).match(/^\d+/); | ||
| if (!paramMatch) { | ||
| result += "$"; | ||
| templatePos++; | ||
| continue; | ||
| } | ||
| templatePos += paramMatch[0].length + 1; | ||
| const originalParamIdx = parseInt(paramMatch[0]); | ||
| const paramValue = params[originalParamIdx - 1]; | ||
| switch (state) { | ||
| case 0 /* Normal */: { | ||
| flattenedParams.push(paramValue); | ||
| result += `$${lastParamId++}`; | ||
| break; | ||
| } | ||
| case 2 /* Repeating */: { | ||
| const paramArray = Array.isArray(paramValue) ? paramValue : [paramValue]; | ||
| if (paramArray.length === 0) { | ||
| result += "NULL"; | ||
| break; | ||
| } | ||
| paramArray.forEach((value, idx) => { | ||
| flattenedParams.push(value); | ||
| result += `$${lastParamId++}`; | ||
| if (idx !== paramArray.length - 1) { | ||
| result += ", "; | ||
| } | ||
| }); | ||
| break; | ||
| } | ||
| default: { | ||
| throw new Error(`Unexpected state: ${state}`); | ||
| } | ||
| } | ||
| continue; | ||
| } | ||
| result += nextChar; | ||
| templatePos++; | ||
| } | ||
| return { | ||
| query: result, | ||
| params: flattenedParams | ||
| }; | ||
| } | ||
| // src/interpreter/renderQuery.ts | ||
| function renderQuery({ query, params }, scope) { | ||
| const substitutedParams = params.map((param) => { | ||
| if (!isPrismaValuePlaceholder(param)) { | ||
| return param; | ||
| } | ||
| const value = scope[param.prisma__value.name]; | ||
| if (value === void 0) { | ||
| throw new Error(`Missing value for query variable ${param.prisma__value.name}`); | ||
| } | ||
| return value; | ||
| }); | ||
| const { query: renderedQuery, params: expandedParams } = renderQueryTemplate({ query, params: substitutedParams }); | ||
| const argTypes = expandedParams.map((param) => toArgType(param)); | ||
| return { | ||
| sql: renderedQuery, | ||
| args: expandedParams, | ||
| argTypes | ||
| }; | ||
| } | ||
| function toArgType(value) { | ||
| if (value === null) { | ||
| return "Int32"; | ||
| } | ||
| if (typeof value === "string") { | ||
| return "Text"; | ||
| } | ||
| if (typeof value === "number") { | ||
| return "Numeric"; | ||
| } | ||
| if (typeof value === "boolean") { | ||
| return "Boolean"; | ||
| } | ||
| if (Array.isArray(value)) { | ||
| return "Array"; | ||
| } | ||
| if (isPrismaValuePlaceholder(value)) { | ||
| return placeholderTypeToArgType(value.prisma__value.type); | ||
| } | ||
| return "Json"; | ||
| } | ||
| function placeholderTypeToArgType(type) { | ||
| const typeMap = { | ||
| Any: "Json", | ||
| String: "Text", | ||
| Int: "Int32", | ||
| BigInt: "Int64", | ||
| Float: "Double", | ||
| Boolean: "Boolean", | ||
| Decimal: "Numeric", | ||
| Date: "DateTime", | ||
| Object: "Json", | ||
| Bytes: "Bytes", | ||
| Array: "Array" | ||
| }; | ||
| const mappedType = typeMap[type]; | ||
| if (!mappedType) { | ||
| throw new Error(`Unknown placeholder type: ${type}`); | ||
| } | ||
| return mappedType; | ||
| } | ||
| // src/interpreter/serialize.ts | ||
| function serialize(resultSet) { | ||
| return resultSet.rows.map( | ||
| (row) => row.reduce((acc, value, index) => { | ||
| const splitByDot = resultSet.columnNames[index].split("."); | ||
| let nested = acc; | ||
| for (let i = 0; i < splitByDot.length; i++) { | ||
| const key = splitByDot[i]; | ||
| if (i === splitByDot.length - 1) { | ||
| nested[key] = value; | ||
| } else { | ||
| if (nested[key] === void 0) { | ||
| nested[key] = {}; | ||
| } | ||
| nested = nested[key]; | ||
| } | ||
| } | ||
| return acc; | ||
| }, {}) | ||
| ); | ||
| } | ||
| // src/interpreter/QueryInterpreter.ts | ||
| var _queryable, _placeholderValues, _onQuery, _QueryInterpreter_instances, withQueryEvent_fn; | ||
| var QueryInterpreter = class { | ||
| constructor({ queryable, placeholderValues, onQuery }) { | ||
| __privateAdd(this, _QueryInterpreter_instances); | ||
| __privateAdd(this, _queryable); | ||
| __privateAdd(this, _placeholderValues); | ||
| __privateAdd(this, _onQuery); | ||
| __privateSet(this, _queryable, queryable); | ||
| __privateSet(this, _placeholderValues, placeholderValues); | ||
| __privateSet(this, _onQuery, onQuery); | ||
| } | ||
| async run(queryPlan) { | ||
| return this.interpretNode(queryPlan, __privateGet(this, _placeholderValues)); | ||
| } | ||
| async interpretNode(node, scope) { | ||
| switch (node.type) { | ||
| case "seq": { | ||
| const results = await Promise.all(node.args.map((arg) => this.interpretNode(arg, scope))); | ||
| return results[results.length - 1]; | ||
| } | ||
| case "get": { | ||
| return scope[node.args.name]; | ||
| } | ||
| case "let": { | ||
| const nestedScope = Object.create(scope); | ||
| await Promise.all( | ||
| node.args.bindings.map(async (binding) => { | ||
| nestedScope[binding.name] = await this.interpretNode(binding.expr, scope); | ||
| }) | ||
| ); | ||
| return this.interpretNode(node.args.expr, nestedScope); | ||
| } | ||
| case "getFirstNonEmpty": { | ||
| for (const name of node.args.names) { | ||
| const value = scope[name]; | ||
| if (!isEmpty(value)) { | ||
| return value; | ||
| } | ||
| } | ||
| return []; | ||
| } | ||
| case "concat": { | ||
| const parts = await Promise.all(node.args.map((arg) => this.interpretNode(arg, scope))); | ||
| return parts.reduce((acc, part) => acc.concat(asList(part)), []); | ||
| } | ||
| case "sum": { | ||
| const parts = await Promise.all(node.args.map((arg) => this.interpretNode(arg, scope))); | ||
| return parts.reduce((acc, part) => asNumber(acc) + asNumber(part)); | ||
| } | ||
| case "execute": { | ||
| const query = renderQuery(node.args, scope); | ||
| return __privateMethod(this, _QueryInterpreter_instances, withQueryEvent_fn).call(this, query, async () => { | ||
| const result = await __privateGet(this, _queryable).executeRaw(query); | ||
| if (result.ok) { | ||
| return result.value; | ||
| } else { | ||
| throw result.error; | ||
| } | ||
| }); | ||
| } | ||
| case "query": { | ||
| const query = renderQuery(node.args, scope); | ||
| return __privateMethod(this, _QueryInterpreter_instances, withQueryEvent_fn).call(this, query, async () => { | ||
| const result = await __privateGet(this, _queryable).queryRaw(query); | ||
| if (result.ok) { | ||
| return serialize(result.value); | ||
| } else { | ||
| throw result.error; | ||
| } | ||
| }); | ||
| } | ||
| case "reverse": { | ||
| const value = await this.interpretNode(node.args, scope); | ||
| return Array.isArray(value) ? value.reverse() : value; | ||
| } | ||
| case "unique": { | ||
| const value = await this.interpretNode(node.args, scope); | ||
| if (!Array.isArray(value)) { | ||
| return value; | ||
| } | ||
| if (value.length > 1) { | ||
| throw new Error(`Expected zero or one element, got ${value.length}`); | ||
| } | ||
| return value[0] ?? null; | ||
| } | ||
| case "required": { | ||
| const value = await this.interpretNode(node.args, scope); | ||
| if (isEmpty(value)) { | ||
| throw new Error("Required value is empty"); | ||
| } | ||
| return value; | ||
| } | ||
| case "mapField": { | ||
| const value = await this.interpretNode(node.args.records, scope); | ||
| return mapField(value, node.args.field); | ||
| } | ||
| case "join": { | ||
| const parent = await this.interpretNode(node.args.parent, scope); | ||
| const children = await Promise.all( | ||
| node.args.children.map(async (joinExpr) => ({ | ||
| joinExpr, | ||
| childRecords: await this.interpretNode(joinExpr.child, scope) | ||
| })) | ||
| ); | ||
| if (Array.isArray(parent)) { | ||
| for (const record of parent) { | ||
| attachChildrenToParent(asRecord(record), children); | ||
| } | ||
| return parent; | ||
| } | ||
| return attachChildrenToParent(asRecord(parent), children); | ||
| } | ||
| default: { | ||
| node; | ||
| throw new Error(`Unexpected node type: ${node.type}`); | ||
| } | ||
| } | ||
| } | ||
| }; | ||
| _queryable = new WeakMap(); | ||
| _placeholderValues = new WeakMap(); | ||
| _onQuery = new WeakMap(); | ||
| _QueryInterpreter_instances = new WeakSet(); | ||
| withQueryEvent_fn = async function(query, execute) { | ||
| var _a; | ||
| const timestamp = /* @__PURE__ */ new Date(); | ||
| const startInstant = performance.now(); | ||
| const result = await execute(); | ||
| const endInstant = performance.now(); | ||
| (_a = __privateGet(this, _onQuery)) == null ? void 0 : _a.call(this, { | ||
| timestamp, | ||
| duration: endInstant - startInstant, | ||
| query: query.sql, | ||
| params: query.args | ||
| }); | ||
| return result; | ||
| }; | ||
| function isEmpty(value) { | ||
| if (Array.isArray(value)) { | ||
| return value.length === 0; | ||
| } | ||
| return value == null; | ||
| } | ||
| function asList(value) { | ||
| return Array.isArray(value) ? value : [value]; | ||
| } | ||
| function asNumber(value) { | ||
| if (typeof value === "number") { | ||
| return value; | ||
| } | ||
| if (typeof value === "string") { | ||
| return Number(value); | ||
| } | ||
| throw new Error(`Expected number, got ${typeof value}`); | ||
| } | ||
| function asRecord(value) { | ||
| if (typeof value === "object" && value !== null) { | ||
| return value; | ||
| } | ||
| throw new Error(`Expected object, got ${typeof value}`); | ||
| } | ||
| function mapField(value, field) { | ||
| if (Array.isArray(value)) { | ||
| return value.map((element) => mapField(element, field)); | ||
| } | ||
| if (typeof value === "object" && value !== null) { | ||
| return value[field] ?? null; | ||
| } | ||
| return value; | ||
| } | ||
| function attachChildrenToParent(parentRecord, children) { | ||
| for (const { joinExpr, childRecords } of children) { | ||
| parentRecord[joinExpr.parentField] = filterChildRecords(childRecords, parentRecord, joinExpr); | ||
| } | ||
| return parentRecord; | ||
| } | ||
| function filterChildRecords(records, parentRecord, joinExpr) { | ||
| if (Array.isArray(records)) { | ||
| return records.filter((record) => childRecordMatchesParent(asRecord(record), parentRecord, joinExpr)); | ||
| } else { | ||
| const record = asRecord(records); | ||
| return childRecordMatchesParent(record, parentRecord, joinExpr) ? record : null; | ||
| } | ||
| } | ||
| function childRecordMatchesParent(childRecord, parentRecord, joinExpr) { | ||
| for (const [parentField, childField] of joinExpr.on) { | ||
| if (parentRecord[parentField] !== childRecord[childField]) { | ||
| return false; | ||
| } | ||
| } | ||
| return true; | ||
| } | ||
| // src/transactionManager/Transaction.ts | ||
| var IsolationLevel = /* @__PURE__ */ ((IsolationLevel2) => { | ||
| IsolationLevel2["ReadUncommitted"] = "ReadUncommitted"; | ||
| IsolationLevel2["ReadCommitted"] = "ReadCommitted"; | ||
| IsolationLevel2["RepeatableRead"] = "RepeatableRead"; | ||
| IsolationLevel2["Snapshot"] = "Snapshot"; | ||
| IsolationLevel2["Serializable"] = "Serializable"; | ||
| return IsolationLevel2; | ||
| })(IsolationLevel || {}); | ||
| // src/transactionManager/TransactionManager.ts | ||
| import crypto from "node:crypto"; | ||
| import Debug from "@prisma/debug"; | ||
| // src/utils.ts | ||
| function assertNever(_, message) { | ||
| throw new Error(message); | ||
| } | ||
| // src/transactionManager/TransactionManagerErrors.ts | ||
| var TransactionManagerError = class extends Error { | ||
| constructor(message, meta) { | ||
| super("Transaction API error: " + message); | ||
| this.meta = meta; | ||
| this.code = "P2028"; | ||
| } | ||
| }; | ||
| var TransactionDriverAdapterError = class extends TransactionManagerError { | ||
| constructor(message, errorParams) { | ||
| super(`Error from Driver Adapter: ${message}`, { ...errorParams.driverAdapterError }); | ||
| } | ||
| }; | ||
| var TransactionNotFoundError = class extends TransactionManagerError { | ||
| constructor() { | ||
| super( | ||
| "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." | ||
| ); | ||
| } | ||
| }; | ||
| var TransactionClosedError = class extends TransactionManagerError { | ||
| constructor(operation) { | ||
| super(`Transaction already closed: A ${operation} cannot be executed on a committed transaction`); | ||
| } | ||
| }; | ||
| var TransactionRolledBackError = class extends TransactionManagerError { | ||
| constructor(operation) { | ||
| super(`Transaction already closed: A ${operation} cannot be executed on a committed transaction`); | ||
| } | ||
| }; | ||
| var TransactionStartTimoutError = class extends TransactionManagerError { | ||
| constructor() { | ||
| super("Unable to start a transaction in the given time."); | ||
| } | ||
| }; | ||
| var TransactionExecutionTimeoutError = class extends TransactionManagerError { | ||
| constructor(operation, { timeout, timeTaken }) { | ||
| super( | ||
| `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`, | ||
| { operation, timeout, timeTaken } | ||
| ); | ||
| } | ||
| }; | ||
| var TransactionInternalConsistencyError = class extends TransactionManagerError { | ||
| constructor(message) { | ||
| super(`Internal Consistency Error: ${message}`); | ||
| } | ||
| }; | ||
| var InvalidTransactionIsolationLevelError = class extends TransactionManagerError { | ||
| constructor(isolationLevel) { | ||
| super(`Invalid isolation level: ${isolationLevel}`, { isolationLevel }); | ||
| } | ||
| }; | ||
| // src/transactionManager/TransactionManager.ts | ||
| var MAX_CLOSED_TRANSACTIONS = 100; | ||
| var isolationLevelMap = { | ||
| ReadUncommitted: "READ UNCOMMITTED", | ||
| ReadCommitted: "READ COMMITTED", | ||
| RepeatableRead: "REPEATABLE READ", | ||
| Snapshot: "SNAPSHOT", | ||
| Serializable: "SERIALIZABLE" | ||
| }; | ||
| var debug = Debug("prisma:client:transactionManager"); | ||
| var COMMIT_QUERY = () => ({ sql: "COMMIT", args: [], argTypes: [] }); | ||
| var ROLLBACK_QUERY = () => ({ sql: "ROLLBACK", args: [], argTypes: [] }); | ||
| var ISOLATION_LEVEL_QUERY = (isolationLevel) => ({ | ||
| sql: "SET TRANSACTION ISOLATION LEVEL " + isolationLevelMap[isolationLevel], | ||
| args: [], | ||
| argTypes: [] | ||
| }); | ||
| var TransactionManager = class { | ||
| constructor({ driverAdapter }) { | ||
| // The map of active transactions. | ||
| this.transactions = /* @__PURE__ */ new Map(); | ||
| // List of last closed transactions. Max MAX_CLOSED_TRANSACTIONS entries. | ||
| // Used to provide better error messages than a generic "transaction not found". | ||
| this.closedTransactions = []; | ||
| this.driverAdapter = driverAdapter; | ||
| } | ||
| async startTransaction(options) { | ||
| const validatedOptions = this.validateOptions(options); | ||
| const transaction = { | ||
| id: crypto.randomUUID(), | ||
| status: "waiting", | ||
| timer: void 0, | ||
| timeout: validatedOptions.timeout, | ||
| startedAt: Date.now(), | ||
| transaction: void 0 | ||
| }; | ||
| this.transactions.set(transaction.id, transaction); | ||
| transaction.timer = this.startTransactionTimeout(transaction.id, validatedOptions.maxWait); | ||
| const txContext = await this.driverAdapter.transactionContext(); | ||
| if (!txContext.ok) | ||
| throw new TransactionDriverAdapterError("Failed to start transaction.", { | ||
| driverAdapterError: txContext.error | ||
| }); | ||
| if (this.requiresSettingIsolationLevelFirst() && validatedOptions.isolationLevel) { | ||
| await txContext.value.executeRaw(ISOLATION_LEVEL_QUERY(validatedOptions.isolationLevel)); | ||
| } | ||
| const startedTransaction = await txContext.value.startTransaction(); | ||
| if (!startedTransaction.ok) | ||
| throw new TransactionDriverAdapterError("Failed to start transaction.", { | ||
| driverAdapterError: startedTransaction.error | ||
| }); | ||
| if (!startedTransaction.value.options.usePhantomQuery) { | ||
| await startedTransaction.value.executeRaw({ sql: "BEGIN", args: [], argTypes: [] }); | ||
| if (!this.requiresSettingIsolationLevelFirst() && validatedOptions.isolationLevel) { | ||
| await txContext.value.executeRaw(ISOLATION_LEVEL_QUERY(validatedOptions.isolationLevel)); | ||
| } | ||
| } | ||
| switch (transaction.status) { | ||
| case "waiting": | ||
| transaction.transaction = startedTransaction.value; | ||
| clearTimeout(transaction.timer); | ||
| transaction.timer = void 0; | ||
| transaction.status = "running"; | ||
| transaction.timer = this.startTransactionTimeout(transaction.id, validatedOptions.timeout); | ||
| return { id: transaction.id }; | ||
| case "timed_out": | ||
| throw new TransactionStartTimoutError(); | ||
| case "running": | ||
| case "committed": | ||
| case "rolled_back": | ||
| throw new TransactionInternalConsistencyError( | ||
| `Transaction in invalid state ${transaction.status} although it just finished startup.` | ||
| ); | ||
| default: | ||
| assertNever(transaction.status, "Unknown transaction status."); | ||
| } | ||
| } | ||
| async commitTransaction(transactionId) { | ||
| const txw = this.getActiveTransaction(transactionId, "commit"); | ||
| await this.closeTransaction(txw, "committed"); | ||
| } | ||
| async rollbackTransaction(transactionId) { | ||
| const txw = this.getActiveTransaction(transactionId, "rollback"); | ||
| await this.closeTransaction(txw, "rolled_back"); | ||
| } | ||
| getTransaction(txInfo, operation) { | ||
| const tx = this.getActiveTransaction(txInfo.id, operation); | ||
| if (!tx.transaction) throw new TransactionNotFoundError(); | ||
| return tx.transaction; | ||
| } | ||
| getActiveTransaction(transactionId, operation) { | ||
| const transaction = this.transactions.get(transactionId); | ||
| if (!transaction) { | ||
| const closedTransaction = this.closedTransactions.find((tx) => tx.id === transactionId); | ||
| if (closedTransaction) { | ||
| debug("Transaction already closed.", { transactionId, status: closedTransaction.status }); | ||
| switch (closedTransaction.status) { | ||
| case "waiting": | ||
| case "running": | ||
| throw new TransactionInternalConsistencyError("Active transaction found in closed transactions list."); | ||
| case "committed": | ||
| throw new TransactionClosedError(operation); | ||
| case "rolled_back": | ||
| throw new TransactionRolledBackError(operation); | ||
| case "timed_out": | ||
| throw new TransactionExecutionTimeoutError(operation, { | ||
| timeout: closedTransaction.timeout, | ||
| timeTaken: Date.now() - closedTransaction.startedAt | ||
| }); | ||
| } | ||
| } else { | ||
| debug(`Transaction not found.`, transactionId); | ||
| throw new TransactionNotFoundError(); | ||
| } | ||
| } | ||
| if (["committed", "rolled_back", "timed_out"].includes(transaction.status)) { | ||
| throw new TransactionInternalConsistencyError("Closed transaction found in active transactions map."); | ||
| } | ||
| return transaction; | ||
| } | ||
| async cancelAllTransactions() { | ||
| await Promise.allSettled([...this.transactions.values()].map((tx) => this.closeTransaction(tx, "rolled_back"))); | ||
| } | ||
| startTransactionTimeout(transactionId, timeout) { | ||
| const timeoutStartedAt = Date.now(); | ||
| return setTimeout(async () => { | ||
| debug("Transaction timed out.", { transactionId, timeoutStartedAt, timeout }); | ||
| const tx = this.transactions.get(transactionId); | ||
| if (tx && ["running", "waiting"].includes(tx.status)) { | ||
| await this.closeTransaction(tx, "timed_out"); | ||
| } else { | ||
| debug("Transaction already committed or rolled back when timeout happened.", transactionId); | ||
| } | ||
| }, timeout); | ||
| } | ||
| async closeTransaction(tx, status) { | ||
| debug("Closing transaction.", { transactionId: tx.id, status }); | ||
| tx.status = status; | ||
| if (tx.transaction && status === "committed") { | ||
| const result = await tx.transaction.commit(); | ||
| if (!result.ok) | ||
| throw new TransactionDriverAdapterError("Failed to commit transaction.", { | ||
| driverAdapterError: result.error | ||
| }); | ||
| if (!tx.transaction.options.usePhantomQuery) { | ||
| await tx.transaction.executeRaw(COMMIT_QUERY()); | ||
| } | ||
| } else if (tx.transaction) { | ||
| const result = await tx.transaction.rollback(); | ||
| if (!result.ok) | ||
| throw new TransactionDriverAdapterError("Failed to rollback transaction.", { | ||
| driverAdapterError: result.error | ||
| }); | ||
| if (!tx.transaction.options.usePhantomQuery) { | ||
| await tx.transaction.executeRaw(ROLLBACK_QUERY()); | ||
| } | ||
| } | ||
| clearTimeout(tx.timer); | ||
| tx.timer = void 0; | ||
| this.transactions.delete(tx.id); | ||
| this.closedTransactions.push(tx); | ||
| if (this.closedTransactions.length > MAX_CLOSED_TRANSACTIONS) { | ||
| this.closedTransactions.shift(); | ||
| } | ||
| } | ||
| validateOptions(options) { | ||
| if (!options.timeout) throw new TransactionManagerError("timeout is required"); | ||
| if (!options.maxWait) throw new TransactionManagerError("maxWait is required"); | ||
| if (options.isolationLevel === "Snapshot" /* Snapshot */) | ||
| throw new InvalidTransactionIsolationLevelError(options.isolationLevel); | ||
| if (this.driverAdapter.provider === "sqlite" && options.isolationLevel && options.isolationLevel !== "Serializable" /* Serializable */) | ||
| throw new InvalidTransactionIsolationLevelError(options.isolationLevel); | ||
| return { | ||
| ...options, | ||
| timeout: options.timeout, | ||
| maxWait: options.maxWait | ||
| }; | ||
| } | ||
| requiresSettingIsolationLevelFirst() { | ||
| return this.driverAdapter.provider === "mysql"; | ||
| } | ||
| }; | ||
| export { | ||
| IsolationLevel, | ||
| QueryInterpreter, | ||
| TransactionManager, | ||
| TransactionManagerError, | ||
| isPrismaValuePlaceholder | ||
| }; |
| import { Queryable } from '@prisma/driver-adapter-utils'; | ||
| import { QueryEvent } from '../events'; | ||
| import { QueryPlanNode } from '../QueryPlan'; | ||
| export type QueryInterpreterOptions = { | ||
| queryable: Queryable; | ||
| placeholderValues: Record<string, unknown>; | ||
| onQuery?: (event: QueryEvent) => void; | ||
| }; | ||
| export declare class QueryInterpreter { | ||
| #private; | ||
| constructor({ queryable, placeholderValues, onQuery }: QueryInterpreterOptions); | ||
| run(queryPlan: QueryPlanNode): Promise<unknown>; | ||
| private interpretNode; | ||
| } |
| import { Query } from '@prisma/driver-adapter-utils'; | ||
| import { QueryPlanDbQuery } from '../QueryPlan'; | ||
| import { ScopeBindings } from './scope'; | ||
| export declare function renderQuery({ query, params }: QueryPlanDbQuery, scope: ScopeBindings): Query; |
| import { Value } from './scope'; | ||
| /** | ||
| * A `QueryPlanDbQuery` in which all placeholders have been substituted with | ||
| * their values from the environment. | ||
| */ | ||
| export type QueryWithSubstitutedPlaceholders = { | ||
| query: string; | ||
| params: Value[]; | ||
| }; | ||
| export declare function renderQueryTemplate({ query, params, }: QueryWithSubstitutedPlaceholders): QueryWithSubstitutedPlaceholders; |
| export {}; |
| /** | ||
| * An object like a record from the database. | ||
| */ | ||
| export type PrismaObject = Record<string, unknown>; | ||
| /** | ||
| * The general type of values each node can evaluate to. | ||
| */ | ||
| export type Value = unknown; | ||
| /** | ||
| * Scope in which a query plan node is interpreted. The names may come | ||
| * from the query placeholders or from let bindings introduced in the query plan. | ||
| */ | ||
| export type ScopeBindings = Record<string, unknown>; |
| import type { ResultSet } from '@prisma/driver-adapter-utils'; | ||
| export declare function serialize(resultSet: ResultSet): Record<string, unknown>[]; |
| export {}; |
| export type PrismaValuePlaceholder = { | ||
| prisma__type: 'param'; | ||
| prisma__value: { | ||
| name: string; | ||
| type: string; | ||
| }; | ||
| }; | ||
| export declare function isPrismaValuePlaceholder(value: unknown): value is PrismaValuePlaceholder; | ||
| export type PrismaValue = string | boolean | number | PrismaValue[] | null | Record<string, unknown> | PrismaValuePlaceholder; | ||
| export type QueryPlanBinding = { | ||
| name: string; | ||
| expr: QueryPlanNode; | ||
| }; | ||
| export type QueryPlanDbQuery = { | ||
| query: string; | ||
| params: PrismaValue[]; | ||
| }; | ||
| export type JoinExpression = { | ||
| child: QueryPlanNode; | ||
| on: [left: string, right: string][]; | ||
| parentField: string; | ||
| }; | ||
| export type QueryPlanNode = { | ||
| type: 'seq'; | ||
| args: QueryPlanNode[]; | ||
| } | { | ||
| type: 'get'; | ||
| args: { | ||
| name: string; | ||
| }; | ||
| } | { | ||
| type: 'let'; | ||
| args: { | ||
| bindings: QueryPlanBinding[]; | ||
| expr: QueryPlanNode; | ||
| }; | ||
| } | { | ||
| type: 'getFirstNonEmpty'; | ||
| args: { | ||
| names: string[]; | ||
| }; | ||
| } | { | ||
| type: 'query'; | ||
| args: QueryPlanDbQuery; | ||
| } | { | ||
| type: 'execute'; | ||
| args: QueryPlanDbQuery; | ||
| } | { | ||
| type: 'reverse'; | ||
| args: QueryPlanNode; | ||
| } | { | ||
| type: 'sum'; | ||
| args: QueryPlanNode[]; | ||
| } | { | ||
| type: 'concat'; | ||
| args: QueryPlanNode[]; | ||
| } | { | ||
| type: 'unique'; | ||
| args: QueryPlanNode; | ||
| } | { | ||
| type: 'required'; | ||
| args: QueryPlanNode; | ||
| } | { | ||
| type: 'join'; | ||
| args: { | ||
| parent: QueryPlanNode; | ||
| children: JoinExpression[]; | ||
| }; | ||
| } | { | ||
| type: 'mapField'; | ||
| args: { | ||
| field: string; | ||
| records: QueryPlanNode; | ||
| }; | ||
| }; |
| export declare const enum IsolationLevel { | ||
| ReadUncommitted = "ReadUncommitted", | ||
| ReadCommitted = "ReadCommitted", | ||
| RepeatableRead = "RepeatableRead", | ||
| Snapshot = "Snapshot", | ||
| Serializable = "Serializable" | ||
| } | ||
| export type Options = { | ||
| maxWait?: number; | ||
| timeout?: number; | ||
| isolationLevel?: IsolationLevel; | ||
| }; | ||
| export type TransactionInfo = { | ||
| id: string; | ||
| }; |
| import { DriverAdapter, Transaction } from '@prisma/driver-adapter-utils'; | ||
| import { Options, TransactionInfo } from './Transaction'; | ||
| export declare class TransactionManager { | ||
| private transactions; | ||
| private closedTransactions; | ||
| private readonly driverAdapter; | ||
| constructor({ driverAdapter }: { | ||
| driverAdapter: DriverAdapter; | ||
| }); | ||
| startTransaction(options: Options): Promise<TransactionInfo>; | ||
| commitTransaction(transactionId: string): Promise<void>; | ||
| rollbackTransaction(transactionId: string): Promise<void>; | ||
| getTransaction(txInfo: TransactionInfo, operation: string): Transaction; | ||
| private getActiveTransaction; | ||
| cancelAllTransactions(): Promise<void>; | ||
| private startTransactionTimeout; | ||
| private closeTransaction; | ||
| private validateOptions; | ||
| private requiresSettingIsolationLevelFirst; | ||
| } |
| import { Error as DriverAdapterError } from '@prisma/driver-adapter-utils'; | ||
| export declare class TransactionManagerError extends Error { | ||
| meta?: Record<string, unknown> | undefined; | ||
| code: string; | ||
| constructor(message: string, meta?: Record<string, unknown> | undefined); | ||
| } | ||
| export declare class TransactionDriverAdapterError extends TransactionManagerError { | ||
| constructor(message: string, errorParams: { | ||
| driverAdapterError: DriverAdapterError; | ||
| }); | ||
| } | ||
| export declare class TransactionNotFoundError extends TransactionManagerError { | ||
| constructor(); | ||
| } | ||
| export declare class TransactionClosedError extends TransactionManagerError { | ||
| constructor(operation: string); | ||
| } | ||
| export declare class TransactionRolledBackError extends TransactionManagerError { | ||
| constructor(operation: string); | ||
| } | ||
| export declare class TransactionStartTimoutError extends TransactionManagerError { | ||
| constructor(); | ||
| } | ||
| export declare class TransactionExecutionTimeoutError extends TransactionManagerError { | ||
| constructor(operation: string, { timeout, timeTaken }: { | ||
| timeout: number; | ||
| timeTaken: number; | ||
| }); | ||
| } | ||
| export declare class TransactionInternalConsistencyError extends TransactionManagerError { | ||
| constructor(message: string); | ||
| } | ||
| export declare class InvalidTransactionIsolationLevelError extends TransactionManagerError { | ||
| constructor(isolationLevel: string); | ||
| } |
| export declare function assertNever(_: never, message: string): never; |
+21
-213
@@ -1,103 +0,6 @@ | ||
| /** | ||
| * Original `quaint::ValueType` enum tag from Prisma's `quaint`. | ||
| * Query arguments marked with this type are sanitized before being sent to the database. | ||
| * Notice while a query argument may be `null`, `ArgType` is guaranteed to be defined. | ||
| */ | ||
| declare type ArgType = 'Int32' | 'Int64' | 'Float' | 'Double' | 'Text' | 'Enum' | 'EnumArray' | 'Bytes' | 'Boolean' | 'Char' | 'Array' | 'Numeric' | 'Json' | 'Xml' | 'Uuid' | 'DateTime' | 'Date' | 'Time'; | ||
| import { DriverAdapter } from '@prisma/driver-adapter-utils'; | ||
| import { Queryable } from '@prisma/driver-adapter-utils'; | ||
| import { Transaction } from '@prisma/driver-adapter-utils'; | ||
| declare type ColumnType = (typeof ColumnTypeEnum)[keyof typeof ColumnTypeEnum]; | ||
| declare const ColumnTypeEnum: { | ||
| readonly Int32: 0; | ||
| readonly Int64: 1; | ||
| readonly Float: 2; | ||
| readonly Double: 3; | ||
| readonly Numeric: 4; | ||
| readonly Boolean: 5; | ||
| readonly Character: 6; | ||
| readonly Text: 7; | ||
| readonly Date: 8; | ||
| readonly Time: 9; | ||
| readonly DateTime: 10; | ||
| readonly Json: 11; | ||
| readonly Enum: 12; | ||
| readonly Bytes: 13; | ||
| readonly Set: 14; | ||
| readonly Uuid: 15; | ||
| readonly Int32Array: 64; | ||
| readonly Int64Array: 65; | ||
| readonly FloatArray: 66; | ||
| readonly DoubleArray: 67; | ||
| readonly NumericArray: 68; | ||
| readonly BooleanArray: 69; | ||
| readonly CharacterArray: 70; | ||
| readonly TextArray: 71; | ||
| readonly DateArray: 72; | ||
| readonly TimeArray: 73; | ||
| readonly DateTimeArray: 74; | ||
| readonly JsonArray: 75; | ||
| readonly EnumArray: 76; | ||
| readonly BytesArray: 77; | ||
| readonly UuidArray: 78; | ||
| readonly UnknownNumber: 128; | ||
| }; | ||
| declare type ConnectionInfo = { | ||
| schemaName?: string; | ||
| maxBindValues?: number; | ||
| }; | ||
| declare interface DriverAdapter extends Queryable { | ||
| /** | ||
| * Starts new transaction. | ||
| */ | ||
| transactionContext(): Promise<Result<TransactionContext>>; | ||
| /** | ||
| * Optional method that returns extra connection info | ||
| */ | ||
| getConnectionInfo?(): Result<ConnectionInfo>; | ||
| } | ||
| declare type Error_2 = { | ||
| kind: 'GenericJs'; | ||
| id: number; | ||
| } | { | ||
| kind: 'UnsupportedNativeDataType'; | ||
| type: string; | ||
| } | { | ||
| kind: 'postgres'; | ||
| code: string; | ||
| severity: string; | ||
| message: string; | ||
| detail: string | undefined; | ||
| column: string | undefined; | ||
| hint: string | undefined; | ||
| } | { | ||
| kind: 'mysql'; | ||
| code: number; | ||
| message: string; | ||
| state: string; | ||
| } | { | ||
| kind: 'sqlite'; | ||
| /** | ||
| * Sqlite extended error code: https://www.sqlite.org/rescode.html | ||
| */ | ||
| extendedCode: number; | ||
| message: string; | ||
| }; | ||
| declare type InteractiveTransactionInfo<Payload = unknown> = { | ||
| /** | ||
| * Transaction ID returned by the query engine. | ||
| */ | ||
| id: string; | ||
| /** | ||
| * Arbitrary payload the meaning of which depends on the `Engine` implementation. | ||
| * For example, `DataProxyEngine` needs to associate different API endpoints with transactions. | ||
| * In `LibraryEngine` and `BinaryEngine` it is currently not used. | ||
| */ | ||
| payload: Payload; | ||
| }; | ||
| export declare enum IsolationLevel { | ||
| export declare const enum IsolationLevel { | ||
| ReadUncommitted = "ReadUncommitted", | ||
@@ -118,10 +21,2 @@ ReadCommitted = "ReadCommitted", | ||
| declare const officialPrismaAdapters: readonly ["@prisma/adapter-planetscale", "@prisma/adapter-neon", "@prisma/adapter-libsql", "@prisma/adapter-d1", "@prisma/adapter-pg", "@prisma/adapter-pg-worker"]; | ||
| declare type Options = { | ||
| maxWait?: number; | ||
| timeout?: number; | ||
| isolationLevel?: IsolationLevel; | ||
| }; | ||
| export declare type PrismaValue = string | boolean | number | PrismaValue[] | null | Record<string, unknown> | PrismaValuePlaceholder; | ||
@@ -137,36 +32,7 @@ | ||
| declare type Provider = 'mysql' | 'postgres' | 'sqlite'; | ||
| declare type Query = { | ||
| sql: string; | ||
| args: Array<unknown>; | ||
| argTypes: Array<ArgType>; | ||
| }; | ||
| declare interface Queryable { | ||
| readonly provider: Provider; | ||
| readonly adapterName: (typeof officialPrismaAdapters)[number] | (string & {}); | ||
| /** | ||
| * Execute a query given as SQL, interpolating the given parameters, | ||
| * and returning the type-aware result set of the query. | ||
| * | ||
| * This is the preferred way of executing `SELECT` queries. | ||
| */ | ||
| queryRaw(params: Query): Promise<Result<ResultSet>>; | ||
| /** | ||
| * Execute a query given as SQL, interpolating the given parameters, | ||
| * and returning the number of affected rows. | ||
| * | ||
| * This is the preferred way of executing `INSERT`, `UPDATE`, `DELETE` queries, | ||
| * as well as transactional queries. | ||
| */ | ||
| executeRaw(params: Query): Promise<Result<number>>; | ||
| } | ||
| declare type QueryEvent = { | ||
| export declare type QueryEvent = { | ||
| timestamp: Date; | ||
| query: string; | ||
| params: string; | ||
| params: unknown[]; | ||
| duration: number; | ||
| target: string; | ||
| }; | ||
@@ -251,59 +117,4 @@ | ||
| declare type Result<T> = { | ||
| map<U>(fn: (value: T) => U): Result<U>; | ||
| flatMap<U>(fn: (value: T) => Result<U>): Result<U>; | ||
| } & ({ | ||
| readonly ok: true; | ||
| readonly value: T; | ||
| } | { | ||
| readonly ok: false; | ||
| readonly error: Error_2; | ||
| }); | ||
| declare interface ResultSet { | ||
| /** | ||
| * List of column types appearing in a database query, in the same order as `columnNames`. | ||
| * They are used within the Query Engine to convert values from JS to Quaint values. | ||
| */ | ||
| columnTypes: Array<ColumnType>; | ||
| /** | ||
| * List of column names appearing in a database query, in the same order as `columnTypes`. | ||
| */ | ||
| columnNames: Array<string>; | ||
| /** | ||
| * List of rows retrieved from a database query. | ||
| * Each row is a list of values, whose length matches `columnNames` and `columnTypes`. | ||
| */ | ||
| rows: Array<Array<unknown>>; | ||
| /** | ||
| * The last ID of an `INSERT` statement, if any. | ||
| * This is required for `AUTO_INCREMENT` columns in databases based on MySQL and SQLite. | ||
| */ | ||
| lastInsertId?: string; | ||
| } | ||
| declare interface Transaction extends Queryable { | ||
| /** | ||
| * Transaction options. | ||
| */ | ||
| readonly options: TransactionOptions; | ||
| /** | ||
| * Commit the transaction. | ||
| */ | ||
| commit(): Promise<Result<void>>; | ||
| /** | ||
| * Rolls back the transaction. | ||
| */ | ||
| rollback(): Promise<Result<void>>; | ||
| } | ||
| declare interface TransactionContext extends Queryable { | ||
| /** | ||
| * Starts new transaction. | ||
| */ | ||
| startTransaction(): Promise<Result<Transaction>>; | ||
| } | ||
| declare type TransactionHeaders = { | ||
| traceparent?: string; | ||
| export declare type TransactionInfo = { | ||
| id: string; | ||
| }; | ||
@@ -315,11 +126,9 @@ | ||
| private readonly driverAdapter; | ||
| private readonly clientVersion; | ||
| constructor({ driverAdapter, clientVersion }: { | ||
| constructor({ driverAdapter }: { | ||
| driverAdapter: DriverAdapter; | ||
| clientVersion: string; | ||
| }); | ||
| startTransaction(options: Tx.Options): Promise<Tx.InteractiveTransactionInfo<undefined>>; | ||
| startTransaction(options: TransactionOptions): Promise<TransactionInfo>; | ||
| commitTransaction(transactionId: string): Promise<void>; | ||
| rollbackTransaction(transactionId: string): Promise<void>; | ||
| getTransaction(txInfo: Tx.InteractiveTransactionInfo<unknown>, operation: string): Transaction; | ||
| getTransaction(txInfo: TransactionInfo, operation: string): Transaction; | ||
| private getActiveTransaction; | ||
@@ -333,15 +142,14 @@ cancelAllTransactions(): Promise<void>; | ||
| declare type TransactionOptions = { | ||
| usePhantomQuery: boolean; | ||
| export declare class TransactionManagerError extends Error { | ||
| meta?: Record<string, unknown> | undefined; | ||
| code: string; | ||
| constructor(message: string, meta?: Record<string, unknown> | undefined); | ||
| } | ||
| export declare type TransactionOptions = { | ||
| maxWait?: number; | ||
| timeout?: number; | ||
| isolationLevel?: IsolationLevel; | ||
| }; | ||
| declare namespace Tx { | ||
| export { | ||
| IsolationLevel, | ||
| Options, | ||
| InteractiveTransactionInfo, | ||
| TransactionHeaders | ||
| } | ||
| } | ||
| export { } |
+21
-213
@@ -1,103 +0,6 @@ | ||
| /** | ||
| * Original `quaint::ValueType` enum tag from Prisma's `quaint`. | ||
| * Query arguments marked with this type are sanitized before being sent to the database. | ||
| * Notice while a query argument may be `null`, `ArgType` is guaranteed to be defined. | ||
| */ | ||
| declare type ArgType = 'Int32' | 'Int64' | 'Float' | 'Double' | 'Text' | 'Enum' | 'EnumArray' | 'Bytes' | 'Boolean' | 'Char' | 'Array' | 'Numeric' | 'Json' | 'Xml' | 'Uuid' | 'DateTime' | 'Date' | 'Time'; | ||
| import { DriverAdapter } from '@prisma/driver-adapter-utils'; | ||
| import { Queryable } from '@prisma/driver-adapter-utils'; | ||
| import { Transaction } from '@prisma/driver-adapter-utils'; | ||
| declare type ColumnType = (typeof ColumnTypeEnum)[keyof typeof ColumnTypeEnum]; | ||
| declare const ColumnTypeEnum: { | ||
| readonly Int32: 0; | ||
| readonly Int64: 1; | ||
| readonly Float: 2; | ||
| readonly Double: 3; | ||
| readonly Numeric: 4; | ||
| readonly Boolean: 5; | ||
| readonly Character: 6; | ||
| readonly Text: 7; | ||
| readonly Date: 8; | ||
| readonly Time: 9; | ||
| readonly DateTime: 10; | ||
| readonly Json: 11; | ||
| readonly Enum: 12; | ||
| readonly Bytes: 13; | ||
| readonly Set: 14; | ||
| readonly Uuid: 15; | ||
| readonly Int32Array: 64; | ||
| readonly Int64Array: 65; | ||
| readonly FloatArray: 66; | ||
| readonly DoubleArray: 67; | ||
| readonly NumericArray: 68; | ||
| readonly BooleanArray: 69; | ||
| readonly CharacterArray: 70; | ||
| readonly TextArray: 71; | ||
| readonly DateArray: 72; | ||
| readonly TimeArray: 73; | ||
| readonly DateTimeArray: 74; | ||
| readonly JsonArray: 75; | ||
| readonly EnumArray: 76; | ||
| readonly BytesArray: 77; | ||
| readonly UuidArray: 78; | ||
| readonly UnknownNumber: 128; | ||
| }; | ||
| declare type ConnectionInfo = { | ||
| schemaName?: string; | ||
| maxBindValues?: number; | ||
| }; | ||
| declare interface DriverAdapter extends Queryable { | ||
| /** | ||
| * Starts new transaction. | ||
| */ | ||
| transactionContext(): Promise<Result<TransactionContext>>; | ||
| /** | ||
| * Optional method that returns extra connection info | ||
| */ | ||
| getConnectionInfo?(): Result<ConnectionInfo>; | ||
| } | ||
| declare type Error_2 = { | ||
| kind: 'GenericJs'; | ||
| id: number; | ||
| } | { | ||
| kind: 'UnsupportedNativeDataType'; | ||
| type: string; | ||
| } | { | ||
| kind: 'postgres'; | ||
| code: string; | ||
| severity: string; | ||
| message: string; | ||
| detail: string | undefined; | ||
| column: string | undefined; | ||
| hint: string | undefined; | ||
| } | { | ||
| kind: 'mysql'; | ||
| code: number; | ||
| message: string; | ||
| state: string; | ||
| } | { | ||
| kind: 'sqlite'; | ||
| /** | ||
| * Sqlite extended error code: https://www.sqlite.org/rescode.html | ||
| */ | ||
| extendedCode: number; | ||
| message: string; | ||
| }; | ||
| declare type InteractiveTransactionInfo<Payload = unknown> = { | ||
| /** | ||
| * Transaction ID returned by the query engine. | ||
| */ | ||
| id: string; | ||
| /** | ||
| * Arbitrary payload the meaning of which depends on the `Engine` implementation. | ||
| * For example, `DataProxyEngine` needs to associate different API endpoints with transactions. | ||
| * In `LibraryEngine` and `BinaryEngine` it is currently not used. | ||
| */ | ||
| payload: Payload; | ||
| }; | ||
| export declare enum IsolationLevel { | ||
| export declare const enum IsolationLevel { | ||
| ReadUncommitted = "ReadUncommitted", | ||
@@ -118,10 +21,2 @@ ReadCommitted = "ReadCommitted", | ||
| declare const officialPrismaAdapters: readonly ["@prisma/adapter-planetscale", "@prisma/adapter-neon", "@prisma/adapter-libsql", "@prisma/adapter-d1", "@prisma/adapter-pg", "@prisma/adapter-pg-worker"]; | ||
| declare type Options = { | ||
| maxWait?: number; | ||
| timeout?: number; | ||
| isolationLevel?: IsolationLevel; | ||
| }; | ||
| export declare type PrismaValue = string | boolean | number | PrismaValue[] | null | Record<string, unknown> | PrismaValuePlaceholder; | ||
@@ -137,36 +32,7 @@ | ||
| declare type Provider = 'mysql' | 'postgres' | 'sqlite'; | ||
| declare type Query = { | ||
| sql: string; | ||
| args: Array<unknown>; | ||
| argTypes: Array<ArgType>; | ||
| }; | ||
| declare interface Queryable { | ||
| readonly provider: Provider; | ||
| readonly adapterName: (typeof officialPrismaAdapters)[number] | (string & {}); | ||
| /** | ||
| * Execute a query given as SQL, interpolating the given parameters, | ||
| * and returning the type-aware result set of the query. | ||
| * | ||
| * This is the preferred way of executing `SELECT` queries. | ||
| */ | ||
| queryRaw(params: Query): Promise<Result<ResultSet>>; | ||
| /** | ||
| * Execute a query given as SQL, interpolating the given parameters, | ||
| * and returning the number of affected rows. | ||
| * | ||
| * This is the preferred way of executing `INSERT`, `UPDATE`, `DELETE` queries, | ||
| * as well as transactional queries. | ||
| */ | ||
| executeRaw(params: Query): Promise<Result<number>>; | ||
| } | ||
| declare type QueryEvent = { | ||
| export declare type QueryEvent = { | ||
| timestamp: Date; | ||
| query: string; | ||
| params: string; | ||
| params: unknown[]; | ||
| duration: number; | ||
| target: string; | ||
| }; | ||
@@ -251,59 +117,4 @@ | ||
| declare type Result<T> = { | ||
| map<U>(fn: (value: T) => U): Result<U>; | ||
| flatMap<U>(fn: (value: T) => Result<U>): Result<U>; | ||
| } & ({ | ||
| readonly ok: true; | ||
| readonly value: T; | ||
| } | { | ||
| readonly ok: false; | ||
| readonly error: Error_2; | ||
| }); | ||
| declare interface ResultSet { | ||
| /** | ||
| * List of column types appearing in a database query, in the same order as `columnNames`. | ||
| * They are used within the Query Engine to convert values from JS to Quaint values. | ||
| */ | ||
| columnTypes: Array<ColumnType>; | ||
| /** | ||
| * List of column names appearing in a database query, in the same order as `columnTypes`. | ||
| */ | ||
| columnNames: Array<string>; | ||
| /** | ||
| * List of rows retrieved from a database query. | ||
| * Each row is a list of values, whose length matches `columnNames` and `columnTypes`. | ||
| */ | ||
| rows: Array<Array<unknown>>; | ||
| /** | ||
| * The last ID of an `INSERT` statement, if any. | ||
| * This is required for `AUTO_INCREMENT` columns in databases based on MySQL and SQLite. | ||
| */ | ||
| lastInsertId?: string; | ||
| } | ||
| declare interface Transaction extends Queryable { | ||
| /** | ||
| * Transaction options. | ||
| */ | ||
| readonly options: TransactionOptions; | ||
| /** | ||
| * Commit the transaction. | ||
| */ | ||
| commit(): Promise<Result<void>>; | ||
| /** | ||
| * Rolls back the transaction. | ||
| */ | ||
| rollback(): Promise<Result<void>>; | ||
| } | ||
| declare interface TransactionContext extends Queryable { | ||
| /** | ||
| * Starts new transaction. | ||
| */ | ||
| startTransaction(): Promise<Result<Transaction>>; | ||
| } | ||
| declare type TransactionHeaders = { | ||
| traceparent?: string; | ||
| export declare type TransactionInfo = { | ||
| id: string; | ||
| }; | ||
@@ -315,11 +126,9 @@ | ||
| private readonly driverAdapter; | ||
| private readonly clientVersion; | ||
| constructor({ driverAdapter, clientVersion }: { | ||
| constructor({ driverAdapter }: { | ||
| driverAdapter: DriverAdapter; | ||
| clientVersion: string; | ||
| }); | ||
| startTransaction(options: Tx.Options): Promise<Tx.InteractiveTransactionInfo<undefined>>; | ||
| startTransaction(options: TransactionOptions): Promise<TransactionInfo>; | ||
| commitTransaction(transactionId: string): Promise<void>; | ||
| rollbackTransaction(transactionId: string): Promise<void>; | ||
| getTransaction(txInfo: Tx.InteractiveTransactionInfo<unknown>, operation: string): Transaction; | ||
| getTransaction(txInfo: TransactionInfo, operation: string): Transaction; | ||
| private getActiveTransaction; | ||
@@ -333,15 +142,14 @@ cancelAllTransactions(): Promise<void>; | ||
| declare type TransactionOptions = { | ||
| usePhantomQuery: boolean; | ||
| export declare class TransactionManagerError extends Error { | ||
| meta?: Record<string, unknown> | undefined; | ||
| code: string; | ||
| constructor(message: string, meta?: Record<string, unknown> | undefined); | ||
| } | ||
| export declare type TransactionOptions = { | ||
| maxWait?: number; | ||
| timeout?: number; | ||
| isolationLevel?: IsolationLevel; | ||
| }; | ||
| declare namespace Tx { | ||
| export { | ||
| IsolationLevel, | ||
| Options, | ||
| InteractiveTransactionInfo, | ||
| TransactionHeaders | ||
| } | ||
| } | ||
| export { } |
+100
-310
@@ -0,2 +1,8 @@ | ||
| "use strict"; | ||
| var __create = Object.create; | ||
| var __defProp = Object.defineProperty; | ||
| var __getOwnPropDesc = Object.getOwnPropertyDescriptor; | ||
| var __getOwnPropNames = Object.getOwnPropertyNames; | ||
| var __getProtoOf = Object.getPrototypeOf; | ||
| var __hasOwnProp = Object.prototype.hasOwnProperty; | ||
| var __typeError = (msg) => { | ||
@@ -9,2 +15,19 @@ throw TypeError(msg); | ||
| }; | ||
| var __copyProps = (to, from, except, desc) => { | ||
| if (from && typeof from === "object" || typeof from === "function") { | ||
| for (let key of __getOwnPropNames(from)) | ||
| if (!__hasOwnProp.call(to, key) && key !== except) | ||
| __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); | ||
| } | ||
| return to; | ||
| }; | ||
| var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( | ||
| // If the importer is in node compatibility mode or this is not an ESM | ||
| // file that has been converted to a CommonJS file using a Babel- | ||
| // compatible transform (i.e. "__esModule" has not been set), then set | ||
| // "default" to the CommonJS "module.exports" for node compatibility. | ||
| isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, | ||
| mod | ||
| )); | ||
| var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); | ||
| var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg); | ||
@@ -16,13 +39,14 @@ var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj)); | ||
| // src/runtime/core/engines/common/types/Transaction.ts | ||
| var IsolationLevel = /* @__PURE__ */ ((IsolationLevel2) => { | ||
| IsolationLevel2["ReadUncommitted"] = "ReadUncommitted"; | ||
| IsolationLevel2["ReadCommitted"] = "ReadCommitted"; | ||
| IsolationLevel2["RepeatableRead"] = "RepeatableRead"; | ||
| IsolationLevel2["Snapshot"] = "Snapshot"; | ||
| IsolationLevel2["Serializable"] = "Serializable"; | ||
| return IsolationLevel2; | ||
| })(IsolationLevel || {}); | ||
| // src/index.ts | ||
| var index_exports = {}; | ||
| __export(index_exports, { | ||
| IsolationLevel: () => IsolationLevel, | ||
| QueryInterpreter: () => QueryInterpreter, | ||
| TransactionManager: () => TransactionManager, | ||
| TransactionManagerError: () => TransactionManagerError, | ||
| isPrismaValuePlaceholder: () => isPrismaValuePlaceholder | ||
| }); | ||
| module.exports = __toCommonJS(index_exports); | ||
| // src/runtime/core/engines/client/QueryPlan.ts | ||
| // src/QueryPlan.ts | ||
| function isPrismaValuePlaceholder(value) { | ||
@@ -32,3 +56,3 @@ return typeof value === "object" && value !== null && value["prisma__type"] === "param"; | ||
| // src/runtime/core/engines/client/interpreter/renderQueryTemplate.ts | ||
| // src/interpreter/renderQueryTemplate.ts | ||
| var BEGIN_REPEAT = "/* prisma-comma-repeatable-start */"; | ||
@@ -131,3 +155,3 @@ var END_REPEAT = "/* prisma-comma-repeatable-end */"; | ||
| // src/runtime/core/engines/client/interpreter/renderQuery.ts | ||
| // src/interpreter/renderQuery.ts | ||
| function renderQuery({ query, params }, scope) { | ||
@@ -194,3 +218,3 @@ const substitutedParams = params.map((param) => { | ||
| // src/runtime/core/engines/client/interpreter/serializer.ts | ||
| // src/interpreter/serialize.ts | ||
| function serialize(resultSet) { | ||
@@ -217,3 +241,3 @@ return resultSet.rows.map( | ||
| // src/runtime/core/engines/client/interpreter/QueryInterpreter.ts | ||
| // src/interpreter/QueryInterpreter.ts | ||
| var _queryable, _placeholderValues, _onQuery, _QueryInterpreter_instances, withQueryEvent_fn; | ||
@@ -352,12 +376,3 @@ var QueryInterpreter = class { | ||
| query: query.sql, | ||
| // TODO: we should probably change the interface to contain a proper array in the next major version. | ||
| params: JSON.stringify(query.args), | ||
| // TODO: this field only exists for historical reasons as we grandfathered it from the time | ||
| // when we emitted `tracing` events to stdout in the engine unchanged, and then described | ||
| // them in the public API as TS types. Thus this field used to contain the name of the Rust | ||
| // module in which an event originated. When using library engine, which uses a different | ||
| // mechanism with a JavaScript callback for logs, it's normally just an empty string instead. | ||
| // This field is definitely not useful and should be removed from the public types (but it's | ||
| // technically a breaking change, even if a tiny and inconsequential one). | ||
| target: "QueryInterpreter" | ||
| params: query.args | ||
| }); | ||
@@ -422,250 +437,38 @@ return result; | ||
| // ../../node_modules/.pnpm/kleur@4.1.5/node_modules/kleur/colors.mjs | ||
| var colors_exports = {}; | ||
| __export(colors_exports, { | ||
| $: () => $, | ||
| bgBlack: () => bgBlack, | ||
| bgBlue: () => bgBlue, | ||
| bgCyan: () => bgCyan, | ||
| bgGreen: () => bgGreen, | ||
| bgMagenta: () => bgMagenta, | ||
| bgRed: () => bgRed, | ||
| bgWhite: () => bgWhite, | ||
| bgYellow: () => bgYellow, | ||
| black: () => black, | ||
| blue: () => blue, | ||
| bold: () => bold, | ||
| cyan: () => cyan, | ||
| dim: () => dim, | ||
| gray: () => gray, | ||
| green: () => green, | ||
| grey: () => grey, | ||
| hidden: () => hidden, | ||
| inverse: () => inverse, | ||
| italic: () => italic, | ||
| magenta: () => magenta, | ||
| red: () => red, | ||
| reset: () => reset, | ||
| strikethrough: () => strikethrough, | ||
| underline: () => underline, | ||
| white: () => white, | ||
| yellow: () => yellow | ||
| }); | ||
| var FORCE_COLOR; | ||
| var NODE_DISABLE_COLORS; | ||
| var NO_COLOR; | ||
| var TERM; | ||
| var isTTY = true; | ||
| if (typeof process !== "undefined") { | ||
| ({ FORCE_COLOR, NODE_DISABLE_COLORS, NO_COLOR, TERM } = process.env || {}); | ||
| isTTY = process.stdout && process.stdout.isTTY; | ||
| } | ||
| var $ = { | ||
| enabled: !NODE_DISABLE_COLORS && NO_COLOR == null && TERM !== "dumb" && (FORCE_COLOR != null && FORCE_COLOR !== "0" || isTTY) | ||
| }; | ||
| function init(x, y) { | ||
| let rgx = new RegExp(`\\x1b\\[${y}m`, "g"); | ||
| let open = `\x1B[${x}m`, close = `\x1B[${y}m`; | ||
| return function(txt) { | ||
| if (!$.enabled || txt == null) return txt; | ||
| return open + (!!~("" + txt).indexOf(close) ? txt.replace(rgx, close + open) : txt) + close; | ||
| }; | ||
| } | ||
| var reset = init(0, 0); | ||
| var bold = init(1, 22); | ||
| var dim = init(2, 22); | ||
| var italic = init(3, 23); | ||
| var underline = init(4, 24); | ||
| var inverse = init(7, 27); | ||
| var hidden = init(8, 28); | ||
| var strikethrough = init(9, 29); | ||
| var black = init(30, 39); | ||
| var red = init(31, 39); | ||
| var green = init(32, 39); | ||
| var yellow = init(33, 39); | ||
| var blue = init(34, 39); | ||
| var magenta = init(35, 39); | ||
| var cyan = init(36, 39); | ||
| var white = init(37, 39); | ||
| var gray = init(90, 39); | ||
| var grey = init(90, 39); | ||
| var bgBlack = init(40, 49); | ||
| var bgRed = init(41, 49); | ||
| var bgGreen = init(42, 49); | ||
| var bgYellow = init(43, 49); | ||
| var bgBlue = init(44, 49); | ||
| var bgMagenta = init(45, 49); | ||
| var bgCyan = init(46, 49); | ||
| var bgWhite = init(47, 49); | ||
| // src/transactionManager/Transaction.ts | ||
| var IsolationLevel = /* @__PURE__ */ ((IsolationLevel2) => { | ||
| IsolationLevel2["ReadUncommitted"] = "ReadUncommitted"; | ||
| IsolationLevel2["ReadCommitted"] = "ReadCommitted"; | ||
| IsolationLevel2["RepeatableRead"] = "RepeatableRead"; | ||
| IsolationLevel2["Snapshot"] = "Snapshot"; | ||
| IsolationLevel2["Serializable"] = "Serializable"; | ||
| return IsolationLevel2; | ||
| })(IsolationLevel || {}); | ||
| // ../debug/src/index.ts | ||
| var MAX_ARGS_HISTORY = 100; | ||
| var COLORS = ["green", "yellow", "blue", "magenta", "cyan", "red"]; | ||
| var argsHistory = []; | ||
| var lastTimestamp = Date.now(); | ||
| var lastColor = 0; | ||
| var processEnv = typeof process !== "undefined" ? process.env : {}; | ||
| globalThis.DEBUG ??= processEnv.DEBUG ?? ""; | ||
| globalThis.DEBUG_COLORS ??= processEnv.DEBUG_COLORS ? processEnv.DEBUG_COLORS === "true" : true; | ||
| var topProps = { | ||
| enable(namespace) { | ||
| if (typeof namespace === "string") { | ||
| globalThis.DEBUG = namespace; | ||
| } | ||
| }, | ||
| disable() { | ||
| const prev = globalThis.DEBUG; | ||
| globalThis.DEBUG = ""; | ||
| return prev; | ||
| }, | ||
| // this is the core logic to check if logging should happen or not | ||
| enabled(namespace) { | ||
| const listenedNamespaces = globalThis.DEBUG.split(",").map((s) => { | ||
| return s.replace(/[.+?^${}()|[\]\\]/g, "\\$&"); | ||
| }); | ||
| const isListened = listenedNamespaces.some((listenedNamespace) => { | ||
| if (listenedNamespace === "" || listenedNamespace[0] === "-") return false; | ||
| return namespace.match(RegExp(listenedNamespace.split("*").join(".*") + "$")); | ||
| }); | ||
| const isExcluded = listenedNamespaces.some((listenedNamespace) => { | ||
| if (listenedNamespace === "" || listenedNamespace[0] !== "-") return false; | ||
| return namespace.match(RegExp(listenedNamespace.slice(1).split("*").join(".*") + "$")); | ||
| }); | ||
| return isListened && !isExcluded; | ||
| }, | ||
| log: (...args) => { | ||
| const [namespace, format, ...rest] = args; | ||
| const logWithFormatting = console.warn ?? console.log; | ||
| logWithFormatting(`${namespace} ${format}`, ...rest); | ||
| }, | ||
| formatters: {} | ||
| // not implemented | ||
| }; | ||
| function debugCreate(namespace) { | ||
| const instanceProps = { | ||
| color: COLORS[lastColor++ % COLORS.length], | ||
| enabled: topProps.enabled(namespace), | ||
| namespace, | ||
| log: topProps.log, | ||
| extend: () => { | ||
| } | ||
| // not implemented | ||
| }; | ||
| const debugCall = (...args) => { | ||
| const { enabled, namespace: namespace2, color, log } = instanceProps; | ||
| if (args.length !== 0) { | ||
| argsHistory.push([namespace2, ...args]); | ||
| } | ||
| if (argsHistory.length > MAX_ARGS_HISTORY) { | ||
| argsHistory.shift(); | ||
| } | ||
| if (topProps.enabled(namespace2) || enabled) { | ||
| const stringArgs = args.map((arg) => { | ||
| if (typeof arg === "string") { | ||
| return arg; | ||
| } | ||
| return safeStringify(arg); | ||
| }); | ||
| const ms = `+${Date.now() - lastTimestamp}ms`; | ||
| lastTimestamp = Date.now(); | ||
| if (globalThis.DEBUG_COLORS) { | ||
| log(colors_exports[color](bold(namespace2)), ...stringArgs, colors_exports[color](ms)); | ||
| } else { | ||
| log(namespace2, ...stringArgs, ms); | ||
| } | ||
| } | ||
| }; | ||
| return new Proxy(debugCall, { | ||
| get: (_, prop) => instanceProps[prop], | ||
| set: (_, prop, value) => instanceProps[prop] = value | ||
| }); | ||
| } | ||
| var Debug = new Proxy(debugCreate, { | ||
| get: (_, prop) => topProps[prop], | ||
| set: (_, prop, value) => topProps[prop] = value | ||
| }); | ||
| function safeStringify(value, indent = 2) { | ||
| const cache = /* @__PURE__ */ new Set(); | ||
| return JSON.stringify( | ||
| value, | ||
| (key, value2) => { | ||
| if (typeof value2 === "object" && value2 !== null) { | ||
| if (cache.has(value2)) { | ||
| return `[Circular *]`; | ||
| } | ||
| cache.add(value2); | ||
| } else if (typeof value2 === "bigint") { | ||
| return value2.toString(); | ||
| } | ||
| return value2; | ||
| }, | ||
| indent | ||
| ); | ||
| } | ||
| var src_default = Debug; | ||
| // src/transactionManager/TransactionManager.ts | ||
| var import_node_crypto = __toESM(require("node:crypto")); | ||
| var import_debug = __toESM(require("@prisma/debug")); | ||
| // ../internals/src/utils/assertNever.ts | ||
| function assertNever(arg, errorMessage) { | ||
| throw new Error(errorMessage); | ||
| // src/utils.ts | ||
| function assertNever(_, message) { | ||
| throw new Error(message); | ||
| } | ||
| // ../internals/src/utils/setClassName.ts | ||
| function setClassName(classObject, name) { | ||
| Object.defineProperty(classObject, "name", { | ||
| value: name, | ||
| configurable: true | ||
| }); | ||
| } | ||
| // src/runtime/core/engines/client/transactionManager/TransactionManager.ts | ||
| import crypto from "crypto"; | ||
| // src/runtime/core/errors/PrismaClientKnownRequestError.ts | ||
| var PrismaClientKnownRequestError = class extends Error { | ||
| constructor(message, { code, clientVersion, meta, batchRequestIdx }) { | ||
| super(message); | ||
| this.name = "PrismaClientKnownRequestError"; | ||
| this.code = code; | ||
| this.clientVersion = clientVersion; | ||
| // src/transactionManager/TransactionManagerErrors.ts | ||
| var TransactionManagerError = class extends Error { | ||
| constructor(message, meta) { | ||
| super("Transaction API error: " + message); | ||
| this.meta = meta; | ||
| Object.defineProperty(this, "batchRequestIdx", { | ||
| value: batchRequestIdx, | ||
| enumerable: false, | ||
| writable: true | ||
| }); | ||
| this.code = "P2028"; | ||
| } | ||
| get [Symbol.toStringTag]() { | ||
| return "PrismaClientKnownRequestError"; | ||
| } | ||
| }; | ||
| setClassName(PrismaClientKnownRequestError, "PrismaClientKnownRequestError"); | ||
| // src/runtime/core/engines/client/transactionManager/TransactionManagerErrors.ts | ||
| var TransactionManagerError = class extends PrismaClientKnownRequestError { | ||
| constructor(message, { | ||
| clientVersion, | ||
| meta | ||
| }) { | ||
| super("Transaction API error: " + message, { | ||
| code: "P2028", | ||
| clientVersion, | ||
| meta | ||
| }); | ||
| } | ||
| }; | ||
| var TransactionDriverAdapterError = class extends TransactionManagerError { | ||
| constructor(message, errorParams) { | ||
| super(`Error from Driver Adapter: ${message}`, { | ||
| clientVersion: errorParams.clientVersion, | ||
| meta: { | ||
| ...errorParams.driverAdapterError | ||
| } | ||
| }); | ||
| super(`Error from Driver Adapter: ${message}`, { ...errorParams.driverAdapterError }); | ||
| } | ||
| }; | ||
| var TransactionNotFoundError = class extends TransactionManagerError { | ||
| constructor(errorParams) { | ||
| constructor() { | ||
| super( | ||
| "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.", | ||
| errorParams | ||
| "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." | ||
| ); | ||
@@ -675,21 +478,21 @@ } | ||
| var TransactionClosedError = class extends TransactionManagerError { | ||
| constructor(operation, errorParams) { | ||
| super(`Transaction already closed: A ${operation} cannot be executed on a committed transaction`, errorParams); | ||
| constructor(operation) { | ||
| super(`Transaction already closed: A ${operation} cannot be executed on a committed transaction`); | ||
| } | ||
| }; | ||
| var TransactionRolledBackError = class extends TransactionManagerError { | ||
| constructor(operation, errorParams) { | ||
| super(`Transaction already closed: A ${operation} cannot be executed on a committed transaction`, errorParams); | ||
| constructor(operation) { | ||
| super(`Transaction already closed: A ${operation} cannot be executed on a committed transaction`); | ||
| } | ||
| }; | ||
| var TransactionStartTimoutError = class extends TransactionManagerError { | ||
| constructor(errorParams) { | ||
| super("Unable to start a transaction in the given time.", errorParams); | ||
| constructor() { | ||
| super("Unable to start a transaction in the given time."); | ||
| } | ||
| }; | ||
| var TransactionExecutionTimeoutError = class extends TransactionManagerError { | ||
| constructor(operation, { clientVersion, timeout, timeTaken }) { | ||
| constructor(operation, { timeout, timeTaken }) { | ||
| super( | ||
| `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`, | ||
| { clientVersion } | ||
| { operation, timeout, timeTaken } | ||
| ); | ||
@@ -699,13 +502,13 @@ } | ||
| var TransactionInternalConsistencyError = class extends TransactionManagerError { | ||
| constructor(message, errorParams) { | ||
| super(`Internal Consistency Error: ${message}`, errorParams); | ||
| constructor(message) { | ||
| super(`Internal Consistency Error: ${message}`); | ||
| } | ||
| }; | ||
| var InvalidTransactionIsolationLevelError = class extends TransactionManagerError { | ||
| constructor(isolationLevel, errorParams) { | ||
| super(`Invalid isolation level: ${isolationLevel}`, errorParams); | ||
| constructor(isolationLevel) { | ||
| super(`Invalid isolation level: ${isolationLevel}`, { isolationLevel }); | ||
| } | ||
| }; | ||
| // src/runtime/core/engines/client/transactionManager/TransactionManager.ts | ||
| // src/transactionManager/TransactionManager.ts | ||
| var MAX_CLOSED_TRANSACTIONS = 100; | ||
@@ -719,3 +522,3 @@ var isolationLevelMap = { | ||
| }; | ||
| var debug = src_default("prisma:client:transactionManager"); | ||
| var debug = (0, import_debug.default)("prisma:client:transactionManager"); | ||
| var COMMIT_QUERY = () => ({ sql: "COMMIT", args: [], argTypes: [] }); | ||
@@ -729,3 +532,3 @@ var ROLLBACK_QUERY = () => ({ sql: "ROLLBACK", args: [], argTypes: [] }); | ||
| var TransactionManager = class { | ||
| constructor({ driverAdapter, clientVersion }) { | ||
| constructor({ driverAdapter }) { | ||
| // The map of active transactions. | ||
@@ -737,3 +540,2 @@ this.transactions = /* @__PURE__ */ new Map(); | ||
| this.driverAdapter = driverAdapter; | ||
| this.clientVersion = clientVersion; | ||
| } | ||
@@ -743,3 +545,3 @@ async startTransaction(options) { | ||
| const transaction = { | ||
| id: crypto.randomUUID(), | ||
| id: import_node_crypto.default.randomUUID(), | ||
| status: "waiting", | ||
@@ -756,4 +558,3 @@ timer: void 0, | ||
| throw new TransactionDriverAdapterError("Failed to start transaction.", { | ||
| driverAdapterError: txContext.error, | ||
| clientVersion: this.clientVersion | ||
| driverAdapterError: txContext.error | ||
| }); | ||
@@ -766,4 +567,3 @@ if (this.requiresSettingIsolationLevelFirst() && validatedOptions.isolationLevel) { | ||
| throw new TransactionDriverAdapterError("Failed to start transaction.", { | ||
| driverAdapterError: startedTransaction.error, | ||
| clientVersion: this.clientVersion | ||
| driverAdapterError: startedTransaction.error | ||
| }); | ||
@@ -783,5 +583,5 @@ if (!startedTransaction.value.options.usePhantomQuery) { | ||
| transaction.timer = this.startTransactionTimeout(transaction.id, validatedOptions.timeout); | ||
| return { id: transaction.id, payload: void 0 }; | ||
| return { id: transaction.id }; | ||
| case "timed_out": | ||
| throw new TransactionStartTimoutError({ clientVersion: this.clientVersion }); | ||
| throw new TransactionStartTimoutError(); | ||
| case "running": | ||
@@ -791,6 +591,3 @@ case "committed": | ||
| throw new TransactionInternalConsistencyError( | ||
| `Transaction in invalid state ${transaction.status} although it just finished startup.`, | ||
| { | ||
| clientVersion: this.clientVersion | ||
| } | ||
| `Transaction in invalid state ${transaction.status} although it just finished startup.` | ||
| ); | ||
@@ -811,3 +608,3 @@ default: | ||
| const tx = this.getActiveTransaction(txInfo.id, operation); | ||
| if (!tx.transaction) throw new TransactionNotFoundError({ clientVersion: this.clientVersion }); | ||
| if (!tx.transaction) throw new TransactionNotFoundError(); | ||
| return tx.transaction; | ||
@@ -824,14 +621,11 @@ } | ||
| case "running": | ||
| throw new TransactionInternalConsistencyError("Active transaction found in closed transactions list.", { | ||
| clientVersion: this.clientVersion | ||
| }); | ||
| throw new TransactionInternalConsistencyError("Active transaction found in closed transactions list."); | ||
| case "committed": | ||
| throw new TransactionClosedError(operation, { clientVersion: this.clientVersion }); | ||
| throw new TransactionClosedError(operation); | ||
| case "rolled_back": | ||
| throw new TransactionRolledBackError(operation, { clientVersion: this.clientVersion }); | ||
| throw new TransactionRolledBackError(operation); | ||
| case "timed_out": | ||
| throw new TransactionExecutionTimeoutError(operation, { | ||
| timeout: closedTransaction.timeout, | ||
| timeTaken: Date.now() - closedTransaction.startedAt, | ||
| clientVersion: this.clientVersion | ||
| timeTaken: Date.now() - closedTransaction.startedAt | ||
| }); | ||
@@ -841,9 +635,7 @@ } | ||
| debug(`Transaction not found.`, transactionId); | ||
| throw new TransactionNotFoundError({ clientVersion: this.clientVersion }); | ||
| throw new TransactionNotFoundError(); | ||
| } | ||
| } | ||
| if (["committed", "rolled_back", "timed_out"].includes(transaction.status)) { | ||
| throw new TransactionInternalConsistencyError("Closed transaction found in active transactions map.", { | ||
| clientVersion: this.clientVersion | ||
| }); | ||
| throw new TransactionInternalConsistencyError("Closed transaction found in active transactions map."); | ||
| } | ||
@@ -874,4 +666,3 @@ return transaction; | ||
| throw new TransactionDriverAdapterError("Failed to commit transaction.", { | ||
| driverAdapterError: result.error, | ||
| clientVersion: this.clientVersion | ||
| driverAdapterError: result.error | ||
| }); | ||
@@ -885,4 +676,3 @@ if (!tx.transaction.options.usePhantomQuery) { | ||
| throw new TransactionDriverAdapterError("Failed to rollback transaction.", { | ||
| driverAdapterError: result.error, | ||
| clientVersion: this.clientVersion | ||
| driverAdapterError: result.error | ||
| }); | ||
@@ -902,10 +692,8 @@ if (!tx.transaction.options.usePhantomQuery) { | ||
| validateOptions(options) { | ||
| if (!options.timeout) | ||
| throw new TransactionManagerError("timeout is required", { clientVersion: this.clientVersion }); | ||
| if (!options.maxWait) | ||
| throw new TransactionManagerError("maxWait is required", { clientVersion: this.clientVersion }); | ||
| if (!options.timeout) throw new TransactionManagerError("timeout is required"); | ||
| if (!options.maxWait) throw new TransactionManagerError("maxWait is required"); | ||
| if (options.isolationLevel === "Snapshot" /* Snapshot */) | ||
| throw new InvalidTransactionIsolationLevelError(options.isolationLevel, { clientVersion: this.clientVersion }); | ||
| throw new InvalidTransactionIsolationLevelError(options.isolationLevel); | ||
| if (this.driverAdapter.provider === "sqlite" && options.isolationLevel && options.isolationLevel !== "Serializable" /* Serializable */) | ||
| throw new InvalidTransactionIsolationLevelError(options.isolationLevel, { clientVersion: this.clientVersion }); | ||
| throw new InvalidTransactionIsolationLevelError(options.isolationLevel); | ||
| return { | ||
@@ -921,7 +709,9 @@ ...options, | ||
| }; | ||
| export { | ||
| // Annotate the CommonJS export names for ESM import in node: | ||
| 0 && (module.exports = { | ||
| IsolationLevel, | ||
| QueryInterpreter, | ||
| TransactionManager, | ||
| TransactionManagerError, | ||
| isPrismaValuePlaceholder | ||
| }; | ||
| }); |
+26
-4
| { | ||
| "name": "@prisma/client-engine-runtime", | ||
| "version": "6.4.0-dev.49", | ||
| "version": "6.4.0-dev.50", | ||
| "description": "This package is intended for Prisma's internal use", | ||
| "type": "module", | ||
| "main": "dist/index.js", | ||
| "module": "dist/index.mjs", | ||
| "types": "dist/index.d.ts", | ||
| "exports": { | ||
| ".": { | ||
| "require": { | ||
| "types": "./dist/index.d.ts", | ||
| "default": "./dist/index.js" | ||
| }, | ||
| "import": { | ||
| "types": "./dist/index.d.mts", | ||
| "default": "./dist/index.mjs" | ||
| } | ||
| } | ||
| }, | ||
| "repository": { | ||
@@ -14,3 +26,12 @@ "type": "git", | ||
| "license": "Apache-2.0", | ||
| "dependencies": {}, | ||
| "dependencies": { | ||
| "@prisma/debug": "6.4.0-dev.50", | ||
| "@prisma/driver-adapter-utils": "6.4.0-dev.50" | ||
| }, | ||
| "devDependencies": { | ||
| "@types/jest": "29.5.14", | ||
| "@types/node": "18.19.31", | ||
| "jest": "29.7.0", | ||
| "jest-junit": "16.0.0" | ||
| }, | ||
| "files": [ | ||
@@ -22,4 +43,5 @@ "dist" | ||
| "dev": "DEV=true tsx helpers/build.ts", | ||
| "build": "tsx helpers/build.ts" | ||
| "build": "tsx helpers/build.ts", | ||
| "test": "jest" | ||
| } | ||
| } |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
74274
18.66%21
250%1655
38.03%0
-100%2
Infinity%4
Infinity%1
Infinity%No
NaN+ Added
+ Added
+ Added