turbine-orm 0.52.0 → 0.53.0
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/cjs/client.js +152 -0
- package/dist/cjs/nested-write.js +51 -5
- package/dist/cjs/prisma-compat.d.ts +80 -2
- package/dist/cjs/prisma-compat.js +249 -74
- package/dist/cjs/query/aggregates.d.ts +33 -9
- package/dist/cjs/query/aggregates.js +180 -40
- package/dist/cjs/query/builder.d.ts +23 -2
- package/dist/cjs/query/builder.js +72 -45
- package/dist/cjs/query/types.d.ts +49 -24
- package/dist/cjs/query/utils.d.ts +30 -0
- package/dist/cjs/query/utils.js +35 -0
- package/dist/cjs/query/warn-registry.d.ts +7 -0
- package/dist/cjs/query/warn-registry.js +7 -0
- package/dist/cjs/query/writes.d.ts +5 -1
- package/dist/cjs/query/writes.js +31 -6
- package/dist/client.js +153 -1
- package/dist/nested-write.js +51 -5
- package/dist/prisma-compat.d.ts +80 -2
- package/dist/prisma-compat.js +249 -74
- package/dist/query/aggregates.d.ts +33 -9
- package/dist/query/aggregates.js +181 -41
- package/dist/query/builder.d.ts +23 -2
- package/dist/query/builder.js +74 -47
- package/dist/query/types.d.ts +49 -24
- package/dist/query/utils.d.ts +30 -0
- package/dist/query/utils.js +35 -1
- package/dist/query/warn-registry.d.ts +7 -0
- package/dist/query/warn-registry.js +7 -0
- package/dist/query/writes.d.ts +5 -1
- package/dist/query/writes.js +32 -7
- package/package.json +1 -1
package/dist/cjs/client.js
CHANGED
|
@@ -35,6 +35,7 @@ const observe_js_1 = require("./observe.js");
|
|
|
35
35
|
const pipeline_js_1 = require("./pipeline.js");
|
|
36
36
|
const index_js_1 = require("./query/index.js");
|
|
37
37
|
const utils_js_1 = require("./query/utils.js");
|
|
38
|
+
const warn_registry_js_1 = require("./query/warn-registry.js");
|
|
38
39
|
const realtime_js_1 = require("./realtime.js");
|
|
39
40
|
const typed_sql_js_1 = require("./typed-sql.js");
|
|
40
41
|
async function withRetry(fn, options) {
|
|
@@ -61,6 +62,154 @@ async function withRetry(fn, options) {
|
|
|
61
62
|
}
|
|
62
63
|
throw lastError;
|
|
63
64
|
}
|
|
65
|
+
// ---------------------------------------------------------------------------
|
|
66
|
+
// Unknown-config-key diagnostics
|
|
67
|
+
// ---------------------------------------------------------------------------
|
|
68
|
+
/**
|
|
69
|
+
* Every `TurbineConfig` key, as runtime data. TypeScript erases the interface,
|
|
70
|
+
* so the key set has to exist as a value; `Record<keyof TurbineConfig, true>`
|
|
71
|
+
* makes the compiler own it in BOTH directions: a field added to the interface
|
|
72
|
+
* fails typecheck until it is listed here, and a key listed here that is not a
|
|
73
|
+
* field fails as an excess property. So this can never drift into warning about
|
|
74
|
+
* a real option.
|
|
75
|
+
*/
|
|
76
|
+
const TURBINE_CONFIG_KEYS = {
|
|
77
|
+
pool: true,
|
|
78
|
+
connectionString: true,
|
|
79
|
+
host: true,
|
|
80
|
+
port: true,
|
|
81
|
+
database: true,
|
|
82
|
+
user: true,
|
|
83
|
+
password: true,
|
|
84
|
+
ssl: true,
|
|
85
|
+
poolSize: true,
|
|
86
|
+
idleTimeoutMs: true,
|
|
87
|
+
connectionTimeoutMs: true,
|
|
88
|
+
max: true,
|
|
89
|
+
idleTimeoutMillis: true,
|
|
90
|
+
connectionTimeoutMillis: true,
|
|
91
|
+
logging: true,
|
|
92
|
+
defaultLimit: true,
|
|
93
|
+
warnOnUnlimited: true,
|
|
94
|
+
utcTimestamps: true,
|
|
95
|
+
scopedConnect: true,
|
|
96
|
+
relationLoadStrategy: true,
|
|
97
|
+
stableRelationOrder: true,
|
|
98
|
+
implicitPkOrdering: true,
|
|
99
|
+
autoToOneJoinMaxRows: true,
|
|
100
|
+
autoRoundTripMs: true,
|
|
101
|
+
jsonEncoding: true,
|
|
102
|
+
errorMessages: true,
|
|
103
|
+
logQueryParams: true,
|
|
104
|
+
preparedStatements: true,
|
|
105
|
+
sqlCache: true,
|
|
106
|
+
sqlCacheSize: true,
|
|
107
|
+
dialect: true,
|
|
108
|
+
replicas: true,
|
|
109
|
+
globalFilters: true,
|
|
110
|
+
};
|
|
111
|
+
/**
|
|
112
|
+
* {@link TURBINE_CONFIG_KEYS} as a lookup. A `Set` rather than an `in` test on
|
|
113
|
+
* the record, so an inherited `Object.prototype` name (`toString`, `constructor`)
|
|
114
|
+
* is treated as the unknown key it is.
|
|
115
|
+
*/
|
|
116
|
+
const CONFIG_KEY_SET = new Set(Object.keys(TURBINE_CONFIG_KEYS));
|
|
117
|
+
/**
|
|
118
|
+
* Keys that are legitimately present on a config object but are not public
|
|
119
|
+
* `TurbineConfig` fields:
|
|
120
|
+
*
|
|
121
|
+
* - `queryInterfaceFactory`: the non-SQL-backend seam. `turbinePowDB` sets it
|
|
122
|
+
* through a cast so `table()` builds a `PowqlInterface`; it is `@internal`,
|
|
123
|
+
* deliberately absent from the public interface, and must not warn.
|
|
124
|
+
* - `schema`: `turbine.config.*` files carry a Postgres schema NAME for the
|
|
125
|
+
* CLI, and that same object is routinely spread into the client factory.
|
|
126
|
+
* The client ignores it (its schema metadata is the second argument), and
|
|
127
|
+
* shouting about a documented CLI field would be pure noise.
|
|
128
|
+
* - `url`: the connection-string spelling used by the CLI config and by the
|
|
129
|
+
* engine factories' first argument. Same story as `schema`.
|
|
130
|
+
*/
|
|
131
|
+
const NON_CONFIG_KEYS = new Set(['queryInterfaceFactory', 'schema', 'url']);
|
|
132
|
+
/** camelCase name → its lowercased words (`logQueryParams` → log, query, params). */
|
|
133
|
+
function camelWords(name) {
|
|
134
|
+
return name
|
|
135
|
+
.split(/(?=[A-Z])/)
|
|
136
|
+
.map((w) => w.toLowerCase())
|
|
137
|
+
.filter(Boolean);
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* The real config key `key` most likely meant, or null when nothing is close.
|
|
141
|
+
*
|
|
142
|
+
* {@link closestName} (the same helper the unknown-COLUMN message uses) decides
|
|
143
|
+
* first, so both diagnostics rank near-misses identically. It is bounded by edit
|
|
144
|
+
* distance, which covers typos but not the miss this warning exists for: a
|
|
145
|
+
* guessed name that omits a whole word. `logParams` is five edits from
|
|
146
|
+
* `logQueryParams`, past the bound, yet it names the same words in the same
|
|
147
|
+
* order, so a second pass accepts a candidate whose camelCase words CONTAIN the
|
|
148
|
+
* guess's words in order, preferring the one that adds fewest words.
|
|
149
|
+
*/
|
|
150
|
+
function suggestConfigKey(key) {
|
|
151
|
+
const direct = (0, utils_js_1.closestName)(key, CONFIG_KEY_SET);
|
|
152
|
+
if (direct)
|
|
153
|
+
return direct;
|
|
154
|
+
const wanted = camelWords(key);
|
|
155
|
+
if (wanted.length < 2)
|
|
156
|
+
return null;
|
|
157
|
+
let best = null;
|
|
158
|
+
let bestExtra = Number.POSITIVE_INFINITY;
|
|
159
|
+
for (const candidate of CONFIG_KEY_SET) {
|
|
160
|
+
const words = camelWords(candidate);
|
|
161
|
+
if (words.length <= wanted.length)
|
|
162
|
+
continue;
|
|
163
|
+
let i = 0;
|
|
164
|
+
for (const w of words)
|
|
165
|
+
if (w === wanted[i])
|
|
166
|
+
i++;
|
|
167
|
+
if (i !== wanted.length)
|
|
168
|
+
continue;
|
|
169
|
+
const extra = words.length - wanted.length;
|
|
170
|
+
if (extra < bestExtra) {
|
|
171
|
+
bestExtra = extra;
|
|
172
|
+
best = candidate;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
return best;
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Dev-mode notice for a key on the config object that is not part of the config
|
|
179
|
+
* surface.
|
|
180
|
+
*
|
|
181
|
+
* An unknown key is silently ignored (JavaScript objects have no schema), which
|
|
182
|
+
* makes a typo or a wrong guess indistinguishable from a broken feature: a
|
|
183
|
+
* caller who wants query parameters in `$on('query')` events and reaches for a
|
|
184
|
+
* plausible-sounding `logParams` sees nothing happen and concludes the feature
|
|
185
|
+
* does not work, rather than that the option is spelled `logQueryParams`.
|
|
186
|
+
*
|
|
187
|
+
* Deliberately a warning, never an error. An app compiled against a NEWER
|
|
188
|
+
* turbine that passes a key this version has not heard of must keep running,
|
|
189
|
+
* and the whole check is wrapped so that a hostile / exotic config object
|
|
190
|
+
* (a Proxy whose `ownKeys` throws) cannot take down the constructor either.
|
|
191
|
+
* Dev-only (`NODE_ENV !== 'production'`) and once per key per process, like the
|
|
192
|
+
* other advisory diagnostics.
|
|
193
|
+
*/
|
|
194
|
+
function warnUnknownConfigKeys(config) {
|
|
195
|
+
if (process.env.NODE_ENV === 'production')
|
|
196
|
+
return;
|
|
197
|
+
try {
|
|
198
|
+
for (const key of Object.keys(config)) {
|
|
199
|
+
if (CONFIG_KEY_SET.has(key) || NON_CONFIG_KEYS.has(key))
|
|
200
|
+
continue;
|
|
201
|
+
if (!(0, warn_registry_js_1.shouldWarnOnce)(warn_registry_js_1.WARN_NS.unknownConfigKey, key))
|
|
202
|
+
continue;
|
|
203
|
+
const suggestion = suggestConfigKey(key);
|
|
204
|
+
console.warn(`[turbine] Unknown option "${key}" in the config passed to TurbineClient, it is ignored.` +
|
|
205
|
+
(suggestion ? ` Did you mean "${suggestion}"?` : ''));
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
catch {
|
|
209
|
+
// Key enumeration is the only thing that can fail here, and a diagnostic
|
|
210
|
+
// must never be the reason a client fails to construct.
|
|
211
|
+
}
|
|
212
|
+
}
|
|
64
213
|
/** Maps isolation level names to SQL */
|
|
65
214
|
const ISOLATION_LEVELS = {
|
|
66
215
|
ReadUncommitted: 'READ UNCOMMITTED',
|
|
@@ -386,6 +535,9 @@ class TurbineClient {
|
|
|
386
535
|
}
|
|
387
536
|
break;
|
|
388
537
|
}
|
|
538
|
+
// Name any key on the config object that is not part of the config surface
|
|
539
|
+
// (dev only, once per key, never throws). See warnUnknownConfigKeys.
|
|
540
|
+
warnUnknownConfigKeys(config);
|
|
389
541
|
/**
|
|
390
542
|
* Parse int8 (bigint, OID 20) as JavaScript number instead of string.
|
|
391
543
|
* Safe for values up to Number.MAX_SAFE_INTEGER (9,007,199,254,740,991).
|
package/dist/cjs/nested-write.js
CHANGED
|
@@ -20,6 +20,7 @@ exports.createManyShapeRuns = createManyShapeRuns;
|
|
|
20
20
|
exports.executeNestedCreate = executeNestedCreate;
|
|
21
21
|
exports.executeNestedUpdate = executeNestedUpdate;
|
|
22
22
|
const errors_js_1 = require("./errors.js");
|
|
23
|
+
const utils_js_1 = require("./query/utils.js");
|
|
23
24
|
const schema_js_1 = require("./schema.js");
|
|
24
25
|
const MAX_DEPTH = 10;
|
|
25
26
|
const CREATE_ONLY_OPS = new Set(['create', 'connect', 'connectOrCreate']);
|
|
@@ -83,10 +84,50 @@ function injectForeignKey(childData, relation, parentRow, schema) {
|
|
|
83
84
|
const refCol = refs[i];
|
|
84
85
|
const refField = schema.tables[relation.from]?.reverseColumnMap[refCol] ?? refCol;
|
|
85
86
|
const fkField = childTable?.reverseColumnMap[fkCol] ?? fkCol;
|
|
86
|
-
result
|
|
87
|
+
assignByColumn(result, childTable, fkField, parentRow[refField]);
|
|
87
88
|
}
|
|
88
89
|
return result;
|
|
89
90
|
}
|
|
91
|
+
/**
|
|
92
|
+
* Set `field` on `target`, first dropping any OTHER key that names the SAME
|
|
93
|
+
* column.
|
|
94
|
+
*
|
|
95
|
+
* The engine always writes the canonical FIELD spelling, while a caller's own
|
|
96
|
+
* `data` may legally spell the same column its snake_case way (the write
|
|
97
|
+
* builders resolve both). Overwriting only the identical key left both in the
|
|
98
|
+
* object, and the INSERT/UPDATE then named one column twice, which PostgreSQL
|
|
99
|
+
* refuses (42701 "specified more than once"). Dropping the alias makes the
|
|
100
|
+
* column spelling behave exactly as the field spelling always did: the value the
|
|
101
|
+
* relation dictates wins.
|
|
102
|
+
*
|
|
103
|
+
* Only SCALAR keys are droppable. A relation is resolved to a column by the very
|
|
104
|
+
* same rule (nothing stops a schema from naming a relation the way a column is
|
|
105
|
+
* spelled), but a relation key carries a nested write rather than a value, so
|
|
106
|
+
* dropping it would discard the whole operation silently, a strictly worse
|
|
107
|
+
* outcome than the duplicate-column error this drop exists to prevent. The
|
|
108
|
+
* relation-shape test matches {@link splitData}, so a key routed to `relations`
|
|
109
|
+
* there is never treated as an alias here.
|
|
110
|
+
*/
|
|
111
|
+
function assignByColumn(target, meta, field, value) {
|
|
112
|
+
const column = meta && (0, utils_js_1.resolveColumnName)(meta, field);
|
|
113
|
+
if (column) {
|
|
114
|
+
for (const key of Object.keys(target)) {
|
|
115
|
+
if (key === field || isRelationEntry(meta, key, target[key]))
|
|
116
|
+
continue;
|
|
117
|
+
if ((0, utils_js_1.resolveColumnName)(meta, key) === column)
|
|
118
|
+
delete target[key];
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
target[field] = value;
|
|
122
|
+
}
|
|
123
|
+
/** Does `key` name a relation on `meta` AND carry a nested-write payload? */
|
|
124
|
+
function isRelationEntry(meta, key, value) {
|
|
125
|
+
return (Object.hasOwn(meta.relations, key) &&
|
|
126
|
+
value !== null &&
|
|
127
|
+
typeof value === 'object' &&
|
|
128
|
+
!Array.isArray(value) &&
|
|
129
|
+
!(value instanceof Date));
|
|
130
|
+
}
|
|
90
131
|
/**
|
|
91
132
|
* Split rows destined for `createMany` into CONTIGUOUS runs that each name the
|
|
92
133
|
* same fields.
|
|
@@ -749,10 +790,15 @@ async function executeNestedCreate(ctx, tableName, data, depth = 0, path = []) {
|
|
|
749
790
|
assertManyToManyOpsSupported(relName, rel, ops);
|
|
750
791
|
}
|
|
751
792
|
}
|
|
752
|
-
// Insert the parent row (scalars + resolved belongsTo foreign keys)
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
}
|
|
793
|
+
// Insert the parent row (scalars + resolved belongsTo foreign keys). The
|
|
794
|
+
// resolved keys win over a caller-supplied value for the same column under
|
|
795
|
+
// either spelling (see assignByColumn), so `{ authorId: 1, author: { connect } }`
|
|
796
|
+
// and `{ author_id: 1, author: { connect } }` both take the connected row.
|
|
797
|
+
const parentData = { ...scalars };
|
|
798
|
+
for (const [field, value] of Object.entries(belongsToFks)) {
|
|
799
|
+
assignByColumn(parentData, tableMeta, field, value);
|
|
800
|
+
}
|
|
801
|
+
const parentRow = (await ctx.tx.table(tableName).create({ data: parentData }));
|
|
756
802
|
// Process hasMany / hasOne relations, their FK lives on the CHILD, so they
|
|
757
803
|
// need the parent row to exist first.
|
|
758
804
|
for (const [relName, ops] of Object.entries(relations)) {
|
|
@@ -37,7 +37,15 @@
|
|
|
37
37
|
* These cannot be faithfully translated and are not attempted; each throws or is
|
|
38
38
|
* documented rather than silently returning wrong data:
|
|
39
39
|
*
|
|
40
|
-
* -
|
|
40
|
+
* - **`$extends` beyond `client` + `model`.** Client extensions ARE supported for
|
|
41
|
+
* those two components (plus the `Prisma.defineExtension` callback form), and
|
|
42
|
+
* return a new client whose delegates, `$transaction` and raw surface all
|
|
43
|
+
* survive. The `query` (interception) and `result` (computed fields)
|
|
44
|
+
* components, and any component this adapter does not recognize, throw an
|
|
45
|
+
* {@link UnsupportedFeatureError} naming the component AT `$extends` TIME
|
|
46
|
+
* rather than being accepted and quietly not applied.
|
|
47
|
+
* - `$use` with Prisma's middleware param shape (Turbine's own `client.$use` is
|
|
48
|
+
* the supported interception seam).
|
|
41
49
|
* - `instanceof PrismaClientKnownRequestError`, `.meta`/message byte parity
|
|
42
50
|
* (opt into `prismaErrorCodes` for a `.code` like `P2002`, without pretending
|
|
43
51
|
* `instanceof` identity).
|
|
@@ -197,6 +205,19 @@ export declare const Prisma: {
|
|
|
197
205
|
raw(sql: string): Sql;
|
|
198
206
|
/** An empty fragment. */
|
|
199
207
|
empty: Sql;
|
|
208
|
+
/**
|
|
209
|
+
* The extension context of `this` inside a client / model extension method.
|
|
210
|
+
* Turbine binds extension members directly onto the client and delegate
|
|
211
|
+
* objects, so the context IS `this`; the identity function exists so migrated
|
|
212
|
+
* `Prisma.getExtensionContext(this).$name` call sites keep working.
|
|
213
|
+
*/
|
|
214
|
+
getExtensionContext<T>(that: T): T;
|
|
215
|
+
/**
|
|
216
|
+
* Type-preserving passthrough for `Prisma.defineExtension(ext)`. Prisma uses
|
|
217
|
+
* it purely for inference; the value is returned unchanged, so both the object
|
|
218
|
+
* and the callback form reach `$extends` intact.
|
|
219
|
+
*/
|
|
220
|
+
defineExtension<E>(ext: E): E;
|
|
200
221
|
};
|
|
201
222
|
/** Options for {@link createPrismaCompatClient}. */
|
|
202
223
|
export interface PrismaCompatOptions {
|
|
@@ -269,12 +290,69 @@ export interface PrismaCompatRawSurface {
|
|
|
269
290
|
$executeRaw(strings: TemplateStringsArray, ...values: unknown[]): Promise<number>;
|
|
270
291
|
$executeRawUnsafe(sql: string, ...params: unknown[]): Promise<number>;
|
|
271
292
|
}
|
|
272
|
-
/**
|
|
293
|
+
/**
|
|
294
|
+
* A Prisma client extension, restricted to the two components this adapter can
|
|
295
|
+
* honour faithfully.
|
|
296
|
+
*
|
|
297
|
+
* `client` members land on the returned client; `model` members land on the
|
|
298
|
+
* named model's delegate (under BOTH spellings), with `$allModels` applying to
|
|
299
|
+
* every delegate. The `query` and `result` components are declared `never` so
|
|
300
|
+
* passing one is a compile error, and {@link PrismaCompatClient.$extends} also
|
|
301
|
+
* refuses them at runtime with an {@link UnsupportedFeatureError} naming the
|
|
302
|
+
* component: an extension that was accepted and then quietly not applied would
|
|
303
|
+
* be far worse than one that is refused.
|
|
304
|
+
*/
|
|
305
|
+
export interface PrismaCompatExtension {
|
|
306
|
+
/** Optional extension name, accepted and otherwise unused (as in Prisma). */
|
|
307
|
+
name?: string;
|
|
308
|
+
/** Extra client-level members, e.g. `{ $healthCheck() { … } }`. */
|
|
309
|
+
client?: Record<string, unknown>;
|
|
310
|
+
/** Extra delegate members per Prisma model name, plus `$allModels`. */
|
|
311
|
+
model?: Record<string, Record<string, unknown>>;
|
|
312
|
+
/** Not supported, see {@link PrismaCompatExtension}. */
|
|
313
|
+
query?: never;
|
|
314
|
+
/** Not supported, see {@link PrismaCompatExtension}. */
|
|
315
|
+
result?: never;
|
|
316
|
+
/** Any other component is refused at runtime by name. */
|
|
317
|
+
[component: string]: unknown;
|
|
318
|
+
}
|
|
319
|
+
/** Members an extension contributes to the delegate for Prisma model `K`. */
|
|
320
|
+
type ModelMembersOf<M, K extends string> = (K extends keyof M ? M[K] : unknown) & (Uncapitalize<K> extends keyof M ? M[Uncapitalize<K>] : unknown) & ('$allModels' extends keyof M ? M['$allModels'] : unknown);
|
|
321
|
+
type ExtraModelMembers<E, K extends string> = E extends {
|
|
322
|
+
model: infer M;
|
|
323
|
+
} ? ModelMembersOf<M, K> : unknown;
|
|
324
|
+
/**
|
|
325
|
+
* The client {@link PrismaCompatClient.$extends} returns: the same surface with
|
|
326
|
+
* the extension's `client` members on the client and its `model` members on
|
|
327
|
+
* every matching delegate (both spellings).
|
|
328
|
+
*/
|
|
329
|
+
export type PrismaCompatExtendedClient<S extends Record<string, PrismaModelTypes>, E> = {
|
|
330
|
+
[K in keyof S]: PrismaModelDelegate<S[K]> & ExtraModelMembers<E, K & string>;
|
|
331
|
+
} & {
|
|
332
|
+
[K in keyof S as Uncapitalize<K & string>]: PrismaModelDelegate<S[K]> & ExtraModelMembers<E, K & string>;
|
|
333
|
+
} & PrismaCompatClientBase<S> & (E extends {
|
|
334
|
+
client: infer C;
|
|
335
|
+
} ? C : unknown);
|
|
336
|
+
/** The client-level surface (`$transaction` / raw / `$extends`), added to the model map. */
|
|
273
337
|
export interface PrismaCompatClientBase<S extends Record<string, PrismaModelTypes> = Record<string, PrismaModelTypes>> extends PrismaCompatRawSurface {
|
|
274
338
|
$transaction<R>(fn: (tx: PrismaCompatTransactionClient<S>) => Promise<R>, options?: PrismaCompatTxOptions): Promise<R>;
|
|
275
339
|
$transaction<P extends readonly PromiseLike<unknown>[]>(promises: readonly [...P]): Promise<{
|
|
276
340
|
[K in keyof P]: Awaited<P[K]>;
|
|
277
341
|
}>;
|
|
342
|
+
/**
|
|
343
|
+
* Prisma's callback form (`Prisma.defineExtension((client) => …)`): the
|
|
344
|
+
* function is called with this client and its return value is the result,
|
|
345
|
+
* exactly as in Prisma. Declared first so a function argument never matches
|
|
346
|
+
* the all-optional object overload below.
|
|
347
|
+
*/
|
|
348
|
+
$extends<R>(extension: (client: PrismaCompatClient<S>) => R): R;
|
|
349
|
+
/**
|
|
350
|
+
* Extend the client with a {@link PrismaCompatExtension}. Returns a NEW client
|
|
351
|
+
* (this one is untouched) carrying the extension's `client` and `model`
|
|
352
|
+
* members; the returned client is itself extendable. `query` and `result`
|
|
353
|
+
* extensions throw, see {@link PrismaCompatExtension}.
|
|
354
|
+
*/
|
|
355
|
+
$extends<E extends PrismaCompatExtension>(extension: E): PrismaCompatExtendedClient<S, E>;
|
|
278
356
|
$connect(): Promise<void>;
|
|
279
357
|
$disconnect(): Promise<void>;
|
|
280
358
|
}
|