turbine-orm 0.65.0 → 0.66.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/README.md +34 -32
- package/dist/adapters/cockroachdb.js +21 -3
- package/dist/adapters/index.d.ts +15 -0
- package/dist/adapters/yugabytedb.js +20 -3
- package/dist/cjs/adapters/cockroachdb.js +21 -3
- package/dist/cjs/adapters/index.d.ts +15 -0
- package/dist/cjs/adapters/yugabytedb.js +20 -3
- package/dist/cjs/cli/destructive.d.ts +18 -4
- package/dist/cjs/cli/destructive.js +230 -122
- package/dist/cjs/cli/index.d.ts +21 -4
- package/dist/cjs/cli/index.js +119 -22
- package/dist/cjs/cli/mcp.d.ts +28 -8
- package/dist/cjs/cli/mcp.js +170 -127
- package/dist/cjs/cli/migrate.d.ts +134 -13
- package/dist/cjs/cli/migrate.js +349 -241
- package/dist/cjs/cli/pii-predicate-guard.d.ts +112 -0
- package/dist/cjs/cli/pii-predicate-guard.js +390 -0
- package/dist/cjs/cli/prisma-resolve.js +75 -4
- package/dist/cjs/cli/prisma-schema.d.ts +17 -1
- package/dist/cjs/cli/prisma-schema.js +83 -17
- package/dist/cjs/cli/sql-statements.d.ts +125 -0
- package/dist/cjs/cli/sql-statements.js +378 -0
- package/dist/cjs/cli/studio.js +49 -118
- package/dist/cjs/cli/ui.d.ts +1 -1
- package/dist/cjs/client.d.ts +43 -0
- package/dist/cjs/client.js +125 -6
- package/dist/cjs/dialect.d.ts +123 -0
- package/dist/cjs/dialect.js +33 -0
- package/dist/cjs/errors.d.ts +74 -1
- package/dist/cjs/errors.js +239 -25
- package/dist/cjs/index-advisor.d.ts +33 -1
- package/dist/cjs/index-advisor.js +32 -1
- package/dist/cjs/introspect.d.ts +48 -0
- package/dist/cjs/introspect.js +222 -91
- package/dist/cjs/mssql.js +43 -1
- package/dist/cjs/mysql.d.ts +5 -2
- package/dist/cjs/mysql.js +202 -17
- package/dist/cjs/nested-write.js +6 -1
- package/dist/cjs/pipeline-submittable.js +17 -3
- package/dist/cjs/pipeline.js +75 -9
- package/dist/cjs/powdb.d.ts +23 -0
- package/dist/cjs/powdb.js +33 -1
- package/dist/cjs/powql.d.ts +61 -9
- package/dist/cjs/powql.js +186 -49
- package/dist/cjs/prisma-compat.js +160 -41
- package/dist/cjs/query/aggregates.d.ts +1 -1
- package/dist/cjs/query/aggregates.js +80 -18
- package/dist/cjs/query/batched-loader.d.ts +10 -0
- package/dist/cjs/query/batched-loader.js +268 -7
- package/dist/cjs/query/builder.d.ts +73 -0
- package/dist/cjs/query/builder.js +225 -28
- package/dist/cjs/query/filters.d.ts +162 -0
- package/dist/cjs/query/filters.js +250 -1
- package/dist/cjs/query/relations.d.ts +10 -10
- package/dist/cjs/query/relations.js +93 -12
- package/dist/cjs/query/types.d.ts +14 -1
- package/dist/cjs/query/utils.d.ts +146 -2
- package/dist/cjs/query/utils.js +210 -4
- package/dist/cjs/query/warn-registry.d.ts +10 -0
- package/dist/cjs/query/warn-registry.js +10 -0
- package/dist/cjs/query/where-compile.d.ts +30 -0
- package/dist/cjs/query/where-compile.js +41 -0
- package/dist/cjs/query/where.d.ts +128 -13
- package/dist/cjs/query/where.js +215 -77
- package/dist/cjs/query/writes.d.ts +1 -1
- package/dist/cjs/query/writes.js +39 -15
- package/dist/cjs/schema-builder.d.ts +2 -1
- package/dist/cjs/schema-sql.d.ts +94 -4
- package/dist/cjs/schema-sql.js +506 -30
- package/dist/cjs/schema.d.ts +3 -1
- package/dist/cjs/sqlite.d.ts +6 -0
- package/dist/cjs/sqlite.js +151 -10
- package/dist/cjs/typed-sql.d.ts +29 -1
- package/dist/cjs/typed-sql.js +30 -12
- package/dist/cli/destructive.d.ts +18 -4
- package/dist/cli/destructive.js +229 -121
- package/dist/cli/index.d.ts +21 -4
- package/dist/cli/index.js +120 -24
- package/dist/cli/mcp.d.ts +28 -8
- package/dist/cli/mcp.js +172 -129
- package/dist/cli/migrate.d.ts +134 -13
- package/dist/cli/migrate.js +347 -238
- package/dist/cli/pii-predicate-guard.d.ts +112 -0
- package/dist/cli/pii-predicate-guard.js +386 -0
- package/dist/cli/prisma-resolve.js +75 -4
- package/dist/cli/prisma-schema.d.ts +17 -1
- package/dist/cli/prisma-schema.js +83 -17
- package/dist/cli/sql-statements.d.ts +125 -0
- package/dist/cli/sql-statements.js +373 -0
- package/dist/cli/studio.js +49 -118
- package/dist/cli/ui.d.ts +1 -1
- package/dist/client.d.ts +43 -0
- package/dist/client.js +126 -7
- package/dist/dialect.d.ts +123 -0
- package/dist/dialect.js +33 -0
- package/dist/errors.d.ts +74 -1
- package/dist/errors.js +228 -19
- package/dist/index-advisor.d.ts +33 -1
- package/dist/index-advisor.js +31 -1
- package/dist/introspect.d.ts +48 -0
- package/dist/introspect.js +221 -91
- package/dist/mssql.js +44 -2
- package/dist/mysql.d.ts +5 -2
- package/dist/mysql.js +203 -18
- package/dist/nested-write.js +7 -2
- package/dist/pipeline-submittable.js +18 -4
- package/dist/pipeline.js +76 -10
- package/dist/powdb.d.ts +23 -0
- package/dist/powdb.js +33 -2
- package/dist/powql.d.ts +61 -9
- package/dist/powql.js +187 -50
- package/dist/prisma-compat.js +160 -41
- package/dist/query/aggregates.d.ts +1 -1
- package/dist/query/aggregates.js +82 -20
- package/dist/query/batched-loader.d.ts +10 -0
- package/dist/query/batched-loader.js +270 -9
- package/dist/query/builder.d.ts +73 -0
- package/dist/query/builder.js +226 -30
- package/dist/query/filters.d.ts +162 -0
- package/dist/query/filters.js +246 -1
- package/dist/query/relations.d.ts +10 -10
- package/dist/query/relations.js +94 -14
- package/dist/query/types.d.ts +14 -1
- package/dist/query/utils.d.ts +146 -2
- package/dist/query/utils.js +204 -3
- package/dist/query/warn-registry.d.ts +10 -0
- package/dist/query/warn-registry.js +10 -0
- package/dist/query/where-compile.d.ts +30 -0
- package/dist/query/where-compile.js +40 -1
- package/dist/query/where.d.ts +128 -13
- package/dist/query/where.js +216 -80
- package/dist/query/writes.d.ts +1 -1
- package/dist/query/writes.js +40 -16
- package/dist/schema-builder.d.ts +2 -1
- package/dist/schema-sql.d.ts +94 -4
- package/dist/schema-sql.js +505 -30
- package/dist/schema.d.ts +3 -1
- package/dist/sqlite.d.ts +6 -0
- package/dist/sqlite.js +151 -10
- package/dist/typed-sql.d.ts +29 -1
- package/dist/typed-sql.js +30 -12
- package/package.json +6 -4
package/dist/cjs/dialect.d.ts
CHANGED
|
@@ -220,6 +220,51 @@ export interface LimitOffsetInput {
|
|
|
220
220
|
/** Whether the outer SELECT already carries an ORDER BY (so none must be injected). */
|
|
221
221
|
hasOrderBy: boolean;
|
|
222
222
|
}
|
|
223
|
+
/**
|
|
224
|
+
* Inputs for {@link Dialect.buildPartitionLimit}, the per-correlation-key row
|
|
225
|
+
* bound the batched relation loader pushes into its follow-up query.
|
|
226
|
+
*
|
|
227
|
+
* The follow-up is one flat `WHERE fk = ANY($1)` over EVERY parent's children,
|
|
228
|
+
* so a trailing `LIMIT n` would cap the TOTAL rather than the per-parent count.
|
|
229
|
+
* A window function is the portable-in-shape way to say "at most n rows per
|
|
230
|
+
* key": rank inside the partition, then keep the ranks at or below the bound.
|
|
231
|
+
*
|
|
232
|
+
* The loader hands over the compiled child SELECT and the pieces it cannot
|
|
233
|
+
* spell engine-independently; the dialect owns the SQL text (and its aliases),
|
|
234
|
+
* exactly like {@link buildLimitOffset} and {@link buildRelationSubquery}.
|
|
235
|
+
*/
|
|
236
|
+
export interface PartitionLimitInput {
|
|
237
|
+
/** The compiled child SELECT, to be wrapped as a derived table. */
|
|
238
|
+
innerSql: string;
|
|
239
|
+
/** RAW (unquoted) correlation column to partition by. */
|
|
240
|
+
partitionColumn: string;
|
|
241
|
+
/**
|
|
242
|
+
* The window's (and the outer result's) ordering, as RAW column names.
|
|
243
|
+
*
|
|
244
|
+
* NEVER EMPTY, and never a partial order: the loader only asks for this
|
|
245
|
+
* rewrite when the relation's `orderBy` covers a NOT NULL unique key of the
|
|
246
|
+
* target table, so no two rows of a partition can tie. That precondition is
|
|
247
|
+
* the whole licence for the rewrite. The join plan takes its `limit` with a
|
|
248
|
+
* per-parent `ORDER BY … LIMIT n` and this takes it with a rank over one flat
|
|
249
|
+
* result, and where ties exist the two are each free to keep different rows,
|
|
250
|
+
* which was measured happening (see `partitionOrderBy` in
|
|
251
|
+
* query/batched-loader.ts). Anything short of a total order therefore keeps
|
|
252
|
+
* the client-side slice instead of arriving here.
|
|
253
|
+
*/
|
|
254
|
+
orderBy: readonly {
|
|
255
|
+
column: string;
|
|
256
|
+
direction: 'ASC' | 'DESC';
|
|
257
|
+
nulls?: 'FIRST' | 'LAST';
|
|
258
|
+
}[];
|
|
259
|
+
/** SQL-ready placeholder for the bound (`$3`, `?`, …). */
|
|
260
|
+
limitPlaceholder: string;
|
|
261
|
+
/**
|
|
262
|
+
* RAW name of the rank column the wrapper adds. It is part of the projection
|
|
263
|
+
* (`SELECT <outer>.*`), so the CALLER must remove it from each raw row before
|
|
264
|
+
* parsing, or it would surface as an extra field on every child entity.
|
|
265
|
+
*/
|
|
266
|
+
rankColumn: string;
|
|
267
|
+
}
|
|
223
268
|
/**
|
|
224
269
|
* Everything an engine needs to OVERRIDE nested-relation subquery generation, for
|
|
225
270
|
* dialects whose JSON-aggregation shape is fundamentally different from PostgreSQL's
|
|
@@ -345,6 +390,37 @@ export interface Dialect {
|
|
|
345
390
|
readonly supportsUpsertUpdateWhere?: boolean;
|
|
346
391
|
/** Whether this dialect/engine supports pgvector distance ops (KNN / distance WHERE). */
|
|
347
392
|
readonly supportsVector: boolean;
|
|
393
|
+
/**
|
|
394
|
+
* Whether this dialect/engine can actually answer JSON CONTAINMENT, i.e. the
|
|
395
|
+
* pathless `{ contains }` and `{ equals }` JSON filters that compile through
|
|
396
|
+
* {@link buildJsonContains}.
|
|
397
|
+
*
|
|
398
|
+
* A capability flag rather than a per-operand hook, because the answer turned
|
|
399
|
+
* out not to vary by operand. SQLite emulates containment as
|
|
400
|
+
* `EXISTS (SELECT 1 FROM json_each(col) WHERE value = $1)` while the param is
|
|
401
|
+
* bound as JSON TEXT, and `json_each.value` yields the DECODED SQL value, so
|
|
402
|
+
* the comparison is between two different encodings and never holds. Measured
|
|
403
|
+
* against a real in-process SQLite, every operand type returned zero rows:
|
|
404
|
+
*
|
|
405
|
+
* stored filter PG SQLite
|
|
406
|
+
* ["gold"] contains: 'gold' match none ('gold' = '"gold"')
|
|
407
|
+
* [1] contains: 1 match none (INTEGER 1 = TEXT '1')
|
|
408
|
+
* {"a":1,"t":"gold"} contains: { a: 1 } match none (no structural walk)
|
|
409
|
+
*
|
|
410
|
+
* So the feature has never worked on that engine at all, and refusing it
|
|
411
|
+
* removes nothing that functioned. Fewer-rows-with-no-error is the exact
|
|
412
|
+
* degrade the capability contract exists to convert into a refusal.
|
|
413
|
+
*
|
|
414
|
+
* Repairing it rather than refusing it is possible and deliberately not done
|
|
415
|
+
* here: `json_each` exposes a `type` column ('text' / 'integer' / 'real' /
|
|
416
|
+
* 'true' / 'false' / 'null'), so a faithful scalar test is
|
|
417
|
+
* `type = $1 AND value IS $2`. That is a param-COUNT change on a path whose
|
|
418
|
+
* build and collect sides must stay in lockstep, which is a different change
|
|
419
|
+
* from this one. Until then the flag is honest and the error names the
|
|
420
|
+
* alternative that is exact today (`{ path: [...], equals }`, which compiles
|
|
421
|
+
* to `json_extract`).
|
|
422
|
+
*/
|
|
423
|
+
readonly supportsJsonContains: boolean;
|
|
348
424
|
/**
|
|
349
425
|
* Whether this dialect/engine supports the PostgreSQL full-text `search`
|
|
350
426
|
* filter (`to_tsvector(...) @@ to_tsquery(...)`). Optional: absent is treated
|
|
@@ -454,6 +530,28 @@ export interface Dialect {
|
|
|
454
530
|
readonly supportsILike: boolean;
|
|
455
531
|
/** Build a case-insensitive LIKE equivalent. */
|
|
456
532
|
buildInsensitiveLike(column: string, paramRef: string): string;
|
|
533
|
+
/**
|
|
534
|
+
* Escape the LIKE metacharacters of this engine in a bound `contains` /
|
|
535
|
+
* `startsWith` / `endsWith` / `stringContains` operand. Optional: when a
|
|
536
|
+
* dialect omits it the shared {@link escapeLike} is used, which escapes the
|
|
537
|
+
* SQL-standard set (`\`, `%`, `_`) and pairs with the `ESCAPE '\'` clause the
|
|
538
|
+
* builders always emit.
|
|
539
|
+
*
|
|
540
|
+
* It exists because the standard set is not the whole set everywhere:
|
|
541
|
+
* T-SQL's `LIKE` also treats `[` as opening a character CLASS, so
|
|
542
|
+
* `{ contains: '[draft]' }` becomes "contains any one of d, r, a, f, t" on
|
|
543
|
+
* SQL Server, a silently over-broad predicate on an engine where every other
|
|
544
|
+
* dialect agrees the value is a literal. That is not injection (the operand
|
|
545
|
+
* is still bound), but it is a wrong answer, and the difference is a property
|
|
546
|
+
* of the ENGINE's pattern grammar, not of the SQL text, which is why it is a
|
|
547
|
+
* dialect hook rather than a branch in the where builder.
|
|
548
|
+
*
|
|
549
|
+
* Whatever a dialect returns MUST be escaped for the same `ESCAPE '\'`
|
|
550
|
+
* clause, i.e. a backslash prefix, and MUST be identical on the SQL-build and
|
|
551
|
+
* the cache-hit param-collect paths (both call this one hook, so they cannot
|
|
552
|
+
* drift).
|
|
553
|
+
*/
|
|
554
|
+
escapeLikePattern?(value: string): string;
|
|
457
555
|
/** JSON operator support level for this dialect. */
|
|
458
556
|
readonly jsonPathSupport: 'native' | 'function' | 'limited';
|
|
459
557
|
/** Build a JSON containment check. */
|
|
@@ -601,6 +699,31 @@ export interface Dialect {
|
|
|
601
699
|
* param-push-ordering contract the override must honor.
|
|
602
700
|
*/
|
|
603
701
|
buildRelationSubquery?(ctx: RelationSubqueryContext): string;
|
|
702
|
+
/**
|
|
703
|
+
* Bound a batched relation follow-up to at most N rows per correlation key,
|
|
704
|
+
* by wrapping the compiled child SELECT in a `ROW_NUMBER() OVER (PARTITION
|
|
705
|
+
* BY …)` filter. See {@link PartitionLimitInput} for why a trailing `LIMIT`
|
|
706
|
+
* cannot express this.
|
|
707
|
+
*
|
|
708
|
+
* OPTIONAL, and absent means "no pushdown": the batched loader then fetches
|
|
709
|
+
* every matching child and applies the per-relation `limit` client-side, the
|
|
710
|
+
* behaviour every engine had before this hook existed. That fallback is
|
|
711
|
+
* correct but unbounded in bytes over the wire (200 parents x ~505 children
|
|
712
|
+
* with `limit: 3` measured 101,000 rows fetched to keep 600, +52.9 MB peak
|
|
713
|
+
* heap against +0.5 MB for the join plan), which is why PostgreSQL
|
|
714
|
+
* implements it. Only PostgreSQL does in this release; the other engines keep
|
|
715
|
+
* the client-side slice, so their emitted SQL is byte-identical to before.
|
|
716
|
+
*
|
|
717
|
+
* The client-side slice is NOT removed when a dialect implements this: it
|
|
718
|
+
* stays as the belt-and-braces bound, and is a no-op once the engine has
|
|
719
|
+
* already limited each partition. It is also still the whole mechanism for
|
|
720
|
+
* any relation whose `orderBy` does not TOTALLY order the target table, on
|
|
721
|
+
* every engine including this one: a rewrite that reaches here has to return
|
|
722
|
+
* the same rows the join plan's per-parent `ORDER BY … LIMIT n` returns, and
|
|
723
|
+
* with ties present neither plan's choice is forced. See
|
|
724
|
+
* {@link PartitionLimitInput.orderBy}.
|
|
725
|
+
*/
|
|
726
|
+
buildPartitionLimit?(input: PartitionLimitInput): string;
|
|
604
727
|
}
|
|
605
728
|
export interface DialectIntrospector {
|
|
606
729
|
introspect(options: IntrospectOptions): Promise<SchemaMetadata>;
|
package/dist/cjs/dialect.js
CHANGED
|
@@ -56,6 +56,7 @@ exports.postgresDialect = {
|
|
|
56
56
|
nullJsonLiteral: 'NULL',
|
|
57
57
|
aggSupportsInlineOrderBy: true,
|
|
58
58
|
supportsVector: true,
|
|
59
|
+
supportsJsonContains: true,
|
|
59
60
|
supportsFullTextSearch: true,
|
|
60
61
|
supportsArrayColumns: true,
|
|
61
62
|
supportsListenNotify: true,
|
|
@@ -294,6 +295,38 @@ exports.postgresDialect = {
|
|
|
294
295
|
params: [name, value],
|
|
295
296
|
};
|
|
296
297
|
},
|
|
298
|
+
buildPartitionLimit(input) {
|
|
299
|
+
// Two wrapper levels, and both are needed: `ROW_NUMBER()` is a window
|
|
300
|
+
// function, so it cannot appear in the same WHERE that filters on it.
|
|
301
|
+
// Aliases are deliberately not in the `t<n>` family the relation builder
|
|
302
|
+
// allocates, so a future caller that wraps a query carrying those aliases
|
|
303
|
+
// cannot shadow one.
|
|
304
|
+
const inner = this.quoteIdentifier('turbine_pl_src');
|
|
305
|
+
const outer = this.quoteIdentifier('turbine_pl_rank');
|
|
306
|
+
const rank = this.quoteIdentifier(input.rankColumn);
|
|
307
|
+
const order = (ref) => input.orderBy
|
|
308
|
+
.map((o) => `${ref}.${this.quoteIdentifier(o.column)} ${o.direction}${o.nulls ? ` NULLS ${o.nulls}` : ''}`)
|
|
309
|
+
.join(', ');
|
|
310
|
+
// The empty-list branches are defensive only: the loader never asks for
|
|
311
|
+
// this rewrite without a total order (see the note on
|
|
312
|
+
// `PartitionLimitInput.orderBy`). An unordered window numbers each
|
|
313
|
+
// partition arbitrarily, and so does the join plan's ORDER-BY-less
|
|
314
|
+
// per-parent `LIMIT`, but they are different plans over different row sets
|
|
315
|
+
// and were measured choosing differently, so that shape keeps the loader's
|
|
316
|
+
// client-side slice rather than arriving here.
|
|
317
|
+
const windowOrder = input.orderBy.length > 0 ? ` ORDER BY ${order(inner)}` : '';
|
|
318
|
+
// The OUTER ordering is not cosmetic: the loader buckets children in result
|
|
319
|
+
// order, so without re-applying it here the relation array would come back
|
|
320
|
+
// in whatever order the rank filter happened to emit. It agrees with the
|
|
321
|
+
// window's own ordering by construction, since both are this one list and
|
|
322
|
+
// that list admits no ties, so the outer sort cannot pick a different order
|
|
323
|
+
// among the ranked rows than the rank did.
|
|
324
|
+
const outerOrder = input.orderBy.length > 0 ? ` ORDER BY ${order(outer)}` : '';
|
|
325
|
+
return (`SELECT ${outer}.* FROM (SELECT ${inner}.*, ROW_NUMBER() OVER (PARTITION BY ` +
|
|
326
|
+
`${inner}.${this.quoteIdentifier(input.partitionColumn)}${windowOrder}) AS ${rank} ` +
|
|
327
|
+
`FROM (${input.innerSql}) AS ${inner}) AS ${outer} ` +
|
|
328
|
+
`WHERE ${outer}.${rank} <= ${input.limitPlaceholder}${outerOrder}`);
|
|
329
|
+
},
|
|
297
330
|
async *openStream(connection, sql, params, batchSize, opts) {
|
|
298
331
|
// Cursors require a single connection inside a transaction: BEGIN → DECLARE
|
|
299
332
|
// … NO SCROLL CURSOR FOR → FETCH n (loop) → CLOSE → COMMIT; ROLLBACK on
|
package/dist/cjs/errors.d.ts
CHANGED
|
@@ -47,6 +47,40 @@ export declare class TurbineError extends Error {
|
|
|
47
47
|
* with `{ errorMessages: 'verbose' }`.
|
|
48
48
|
*/
|
|
49
49
|
export type ErrorMessageMode = 'safe' | 'verbose';
|
|
50
|
+
/**
|
|
51
|
+
* Register a client's configured mode and report whether per-operation scoping
|
|
52
|
+
* is now required.
|
|
53
|
+
*
|
|
54
|
+
* The gate is DIVERGENCE, not "has a client been built": while every client in
|
|
55
|
+
* the process agrees (the overwhelmingly common case, including every
|
|
56
|
+
* single-client app), the module default is already the right answer for all of
|
|
57
|
+
* them and no scope has to be established, so the query path pays exactly
|
|
58
|
+
* nothing. The moment two clients disagree, every client starts scoping, which
|
|
59
|
+
* is why this is read per call rather than latched per client.
|
|
60
|
+
*
|
|
61
|
+
* @internal Used by TurbineClient; not part of the public surface.
|
|
62
|
+
*/
|
|
63
|
+
export declare function registerClientErrorMessageMode(mode: ErrorMessageMode): void;
|
|
64
|
+
/**
|
|
65
|
+
* Whether any two clients in this process have registered different modes, so
|
|
66
|
+
* the module default can no longer speak for all of them.
|
|
67
|
+
*
|
|
68
|
+
* @internal
|
|
69
|
+
*/
|
|
70
|
+
export declare function errorMessageModesDiverged(): boolean;
|
|
71
|
+
/**
|
|
72
|
+
* Run `fn` with `mode` in force for everything it does, awaits included.
|
|
73
|
+
*
|
|
74
|
+
* Establishing the scope around the call (rather than threading a mode
|
|
75
|
+
* parameter into every error constructor) is what makes this reachable at all:
|
|
76
|
+
* the mode-sensitive errors are built deep inside the query executor, the write
|
|
77
|
+
* builders and the nested-write engine, none of which are handed the client.
|
|
78
|
+
* The async context is captured when the operation's promise chain is created
|
|
79
|
+
* INSIDE this call, so every continuation of it resolves the same mode.
|
|
80
|
+
*
|
|
81
|
+
* @internal
|
|
82
|
+
*/
|
|
83
|
+
export declare function runWithErrorMessageMode<R>(mode: ErrorMessageMode, fn: () => R): R;
|
|
50
84
|
/**
|
|
51
85
|
* Set the global NotFoundError message mode. Called from the TurbineClient
|
|
52
86
|
* constructor when `TurbineConfig.errorMessages` is provided.
|
|
@@ -70,7 +104,14 @@ export type ErrorMessageMode = 'safe' | 'verbose';
|
|
|
70
104
|
* leak, not as a log-scrubbing boundary.
|
|
71
105
|
*/
|
|
72
106
|
export declare function setErrorMessageMode(mode: ErrorMessageMode): void;
|
|
73
|
-
/**
|
|
107
|
+
/**
|
|
108
|
+
* Returns the NotFoundError message mode in effect right now.
|
|
109
|
+
*
|
|
110
|
+
* Called inside an operation issued through a client whose mode differs from
|
|
111
|
+
* another client's in the same process, that is THAT client's mode; anywhere
|
|
112
|
+
* else it is the process default {@link setErrorMessageMode} last set, which is
|
|
113
|
+
* what it has always returned. Exported for tests.
|
|
114
|
+
*/
|
|
74
115
|
export declare function getErrorMessageMode(): ErrorMessageMode;
|
|
75
116
|
/**
|
|
76
117
|
* The marker left where a driver `detail` string was removed in 'safe' mode.
|
|
@@ -78,6 +119,17 @@ export declare function getErrorMessageMode(): ErrorMessageMode;
|
|
|
78
119
|
* assertions can match on it without hardcoding the wording.
|
|
79
120
|
*/
|
|
80
121
|
export declare const REDACTED_DETAIL = "[redacted by turbine errorMessages:\"safe\"]";
|
|
122
|
+
/**
|
|
123
|
+
* Mark a driver error as carrying row values in its `message` (see
|
|
124
|
+
* {@link VALUE_BEARING_MESSAGE}). Called by the engine error augmenters for the
|
|
125
|
+
* exact driver codes whose message grammar embeds a value; every other code is
|
|
126
|
+
* left alone so nothing is withheld that did not need to be.
|
|
127
|
+
*
|
|
128
|
+
* Non-enumerable so the flag itself never shows up in a serialized error, and
|
|
129
|
+
* best-effort so a frozen or exotic driver error cannot turn a constraint
|
|
130
|
+
* violation into a TypeError.
|
|
131
|
+
*/
|
|
132
|
+
export declare function markValueBearingMessage<T>(err: T): T;
|
|
81
133
|
/**
|
|
82
134
|
* Render a user-supplied `where` / `connect` target for a "no row found" error
|
|
83
135
|
* message, honoring the global {@link ErrorMessageMode}. In 'safe' mode (the
|
|
@@ -168,6 +220,27 @@ export declare class ConnectionError extends TurbineError {
|
|
|
168
220
|
sqlstate?: string;
|
|
169
221
|
});
|
|
170
222
|
}
|
|
223
|
+
/**
|
|
224
|
+
* The message for "this engine's connection string could not be parsed".
|
|
225
|
+
*
|
|
226
|
+
* The one rule it exists to enforce: NEVER echo the value. A DSN carries a
|
|
227
|
+
* password, and the trigger for this error is a MALFORMED DSN, which is exactly
|
|
228
|
+
* when someone pastes the failure into a bug report, a CI log, or an error
|
|
229
|
+
* tracker. No redaction written against the URL grammar can be trusted on a
|
|
230
|
+
* string that just failed to parse as a URL, so the only safe amount of it to
|
|
231
|
+
* include is none: not the password, not the host, not a prefix.
|
|
232
|
+
*
|
|
233
|
+
* This mirrors the Postgres path (`assertUsableConnectionString` in client.ts),
|
|
234
|
+
* which reached the same conclusion first and stated the same reason; the
|
|
235
|
+
* engines used to interpolate the raw string instead, so SECURITY.md's claim of
|
|
236
|
+
* redaction "in all CLI error output" was true for one engine out of four.
|
|
237
|
+
* Shared rather than copied so the three engines cannot drift back apart.
|
|
238
|
+
*
|
|
239
|
+
* @param engine the human engine label ("MySQL", "SQL Server", "PowDB").
|
|
240
|
+
* @param example a well-formed connection string for that engine, with a
|
|
241
|
+
* placeholder password. Never derived from the caller's value.
|
|
242
|
+
*/
|
|
243
|
+
export declare function malformedConnectionStringMessage(engine: string, example: string): string;
|
|
171
244
|
/** Thrown when a relation reference is invalid */
|
|
172
245
|
export declare class RelationError extends TurbineError {
|
|
173
246
|
constructor(message: string);
|