turbine-orm 0.40.1 → 0.41.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 +22 -4
- package/dist/cjs/cli/config.js +3 -0
- package/dist/cjs/cli/index.js +179 -0
- package/dist/cjs/cli/prisma-report.js +216 -0
- package/dist/cjs/cli/prisma-resolve.js +335 -0
- package/dist/cjs/cli/prisma-schema.js +484 -0
- package/dist/cjs/client.js +1 -0
- package/dist/cjs/generate.js +279 -22
- package/dist/cjs/index.js +3 -2
- package/dist/cjs/introspect.js +203 -26
- package/dist/cjs/mssql.js +9 -10
- package/dist/cjs/mysql.js +3 -9
- package/dist/cjs/powdb-introspect.js +5 -10
- package/dist/cjs/powql.js +13 -0
- package/dist/cjs/prisma-compat.js +1147 -0
- package/dist/cjs/query/aggregates.js +67 -7
- package/dist/cjs/query/builder.js +388 -17
- package/dist/cjs/query/compound-unique.js +0 -0
- package/dist/cjs/query/relations.js +7 -5
- package/dist/cjs/query/warn-registry.js +98 -0
- package/dist/cjs/query/writes.js +13 -5
- package/dist/cjs/schema.js +47 -0
- package/dist/cjs/sqlite.js +4 -9
- package/dist/cli/config.d.ts +26 -0
- package/dist/cli/config.js +3 -0
- package/dist/cli/index.d.ts +11 -0
- package/dist/cli/index.js +180 -1
- package/dist/cli/prisma-report.d.ts +19 -0
- package/dist/cli/prisma-report.js +211 -0
- package/dist/cli/prisma-resolve.d.ts +87 -0
- package/dist/cli/prisma-resolve.js +330 -0
- package/dist/cli/prisma-schema.d.ts +116 -0
- package/dist/cli/prisma-schema.js +479 -0
- package/dist/cli/ui.d.ts +1 -1
- package/dist/client.d.ts +18 -2
- package/dist/client.js +1 -0
- package/dist/generate.d.ts +80 -1
- package/dist/generate.js +277 -25
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/introspect.d.ts +92 -2
- package/dist/introspect.js +198 -26
- package/dist/mssql.js +10 -11
- package/dist/mysql.js +4 -10
- package/dist/powdb-introspect.js +5 -10
- package/dist/powql.js +13 -0
- package/dist/prisma-compat.d.ts +281 -0
- package/dist/prisma-compat.js +1143 -0
- package/dist/query/aggregates.js +67 -7
- package/dist/query/builder.d.ts +77 -4
- package/dist/query/builder.js +390 -19
- package/dist/query/compound-unique.d.ts +49 -0
- package/dist/query/compound-unique.js +0 -0
- package/dist/query/deferred.d.ts +18 -0
- package/dist/query/relations.js +7 -5
- package/dist/query/types.d.ts +70 -9
- package/dist/query/warn-registry.d.ts +57 -0
- package/dist/query/warn-registry.js +92 -0
- package/dist/query/writes.js +13 -5
- package/dist/schema.d.ts +75 -0
- package/dist/schema.js +46 -0
- package/dist/sqlite.js +5 -10
- package/package.json +6 -1
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* turbine-orm/prisma-compat, a typed PrismaClient-surface adapter over a
|
|
3
|
+
* {@link TurbineClient}.
|
|
4
|
+
*
|
|
5
|
+
* This subpath lets a codebase that speaks Prisma's `db.model.findMany(...)`
|
|
6
|
+
* surface run on Turbine with minimal churn. It is a **pure TypeScript shim**:
|
|
7
|
+
* zero new runtime dependencies, never imported by Turbine core, and driven
|
|
8
|
+
* entirely by the {@link PrismaCompatMap} that `turbine migrate-from-prisma`
|
|
9
|
+
* emits (`prisma-map.ts`). Every Prisma model / field / relation / compound
|
|
10
|
+
* unique name in the map was resolved against live introspected metadata, so
|
|
11
|
+
* the adapter only ever translates names it can prove exist.
|
|
12
|
+
*
|
|
13
|
+
* ## What it does
|
|
14
|
+
*
|
|
15
|
+
* - **Model delegates** under both the Prisma model name (`compat.User`) and
|
|
16
|
+
* Prisma's client-property spelling with the first letter lowercased
|
|
17
|
+
* (`compat.user`, what generated Prisma call sites actually use),
|
|
18
|
+
* translating args recursively: `include`→`with`, `select` split into scalar
|
|
19
|
+
* selection + relations, field/relation renames both ways through the map,
|
|
20
|
+
* `take`/`skip`→`limit`/`offset`, cursor pagination, and compound-unique
|
|
21
|
+
* selectors (including custom `@@unique(name:)` names the core `findUnique`
|
|
22
|
+
* derivation cannot know).
|
|
23
|
+
* - **`$transaction`** in both forms: a callback (`$transaction(async (tx) => …)`)
|
|
24
|
+
* and Prisma's lazy array batching (`$transaction([a.create(...), b.update(...)])`)
|
|
25
|
+
* , the un-awaited delegate calls defer to Turbine's `build*()` methods and
|
|
26
|
+
* run atomically through the core batch `$transaction([...])` path.
|
|
27
|
+
* - **Raw SQL**: `$queryRaw` / `$executeRaw` tagged templates (with
|
|
28
|
+
* `Prisma.sql`-style nested-fragment flattening) and the `*Unsafe` variants.
|
|
29
|
+
* - **Result reshaping**: `_count` objects keyed back to Prisma relation names,
|
|
30
|
+
* and to-one relations surfaced as `object | null`.
|
|
31
|
+
*
|
|
32
|
+
* ## What it deliberately does NOT do (documented divergences)
|
|
33
|
+
*
|
|
34
|
+
* These cannot be faithfully translated and are not attempted; each throws or is
|
|
35
|
+
* documented rather than silently returning wrong data:
|
|
36
|
+
*
|
|
37
|
+
* - `$extends` / client extensions, `$use` with Prisma's middleware param shape.
|
|
38
|
+
* - `instanceof PrismaClientKnownRequestError`, `.meta`/message byte parity
|
|
39
|
+
* (opt into `prismaErrorCodes` for a `.code` like `P2002`, without pretending
|
|
40
|
+
* `instanceof` identity).
|
|
41
|
+
* - `Prisma.join` / `Prisma.raw` composition beyond plain fragment flattening.
|
|
42
|
+
* - Fluent relation chaining (`prisma.user.findUnique().posts()`).
|
|
43
|
+
* - Accelerate / Pulse / driver-adapter preview features, the Mongo API, and the
|
|
44
|
+
* `prisma migrate`/`db` CLI family (Turbine ships its own migrations).
|
|
45
|
+
* - **Inclusive bare cursors whose field is not the sort key**, see
|
|
46
|
+
* {@link translateCursor}. A bare Prisma cursor is inclusive; translating it
|
|
47
|
+
* correctly needs the anchor row's sort-key value. When the cursor field is
|
|
48
|
+
* the single `orderBy` field (or the cursor is the single-column PK with no
|
|
49
|
+
* `orderBy`) it compiles to a `gte`/`lte` keyset predicate; **otherwise it
|
|
50
|
+
* throws** an {@link UnsupportedFeatureError} rather than emit an off-by-one
|
|
51
|
+
* page. Pair the cursor with `skip: 1` (Prisma's idiom) for the exact
|
|
52
|
+
* exclusive-cursor + `offset` translation.
|
|
53
|
+
* - **Negative `take`** (take-from-end) and **`skip` on a nested relation
|
|
54
|
+
* include** throw, Turbine's `with` clause has no offset and no reverse-take.
|
|
55
|
+
*
|
|
56
|
+
* ## Type dependencies (0.41.0)
|
|
57
|
+
*
|
|
58
|
+
* - Field-name identity fast path pairs with the generator's
|
|
59
|
+
* `--keep-column-names` output (byte-shaped like a snake_case Prisma client).
|
|
60
|
+
* - Compound-unique default selectors are handled by the core
|
|
61
|
+
* `findUnique`-family derivation; this adapter only translates custom
|
|
62
|
+
* `@@unique(name:)` names on top.
|
|
63
|
+
* - To-one relations return `object | null` natively once the unique-FK hasOne
|
|
64
|
+
* introspection default is in effect (0.41.0). Until a schema is regenerated,
|
|
65
|
+
* the map's `cardinality: 'one'` still drives the first-element-or-null guard,
|
|
66
|
+
* so the surface is correct either way.
|
|
67
|
+
*
|
|
68
|
+
* @example
|
|
69
|
+
* ```ts
|
|
70
|
+
* import { TurbineClient } from 'turbine-orm';
|
|
71
|
+
* import { createPrismaCompatClient } from 'turbine-orm/prisma-compat';
|
|
72
|
+
* import { SCHEMA } from './generated/turbine/metadata.js';
|
|
73
|
+
* import { PRISMA_MAP } from './generated/turbine/prisma-map.js';
|
|
74
|
+
*
|
|
75
|
+
* const db = new TurbineClient({ connectionString: process.env.DATABASE_URL }, SCHEMA);
|
|
76
|
+
* const prisma = createPrismaCompatClient(db, PRISMA_MAP);
|
|
77
|
+
*
|
|
78
|
+
* const users = await prisma.User.findMany({
|
|
79
|
+
* where: { email: { contains: '@acme.com' } },
|
|
80
|
+
* include: { posts: { orderBy: { createdAt: 'desc' }, take: 5 } },
|
|
81
|
+
* });
|
|
82
|
+
* ```
|
|
83
|
+
*/
|
|
84
|
+
import type { TurbineClient } from './client.js';
|
|
85
|
+
import type { DeferredQuery } from './query/index.js';
|
|
86
|
+
import type { PrismaCompatMap, SchemaMetadata } from './schema.js';
|
|
87
|
+
/** A build-only query object with the `build*` methods the adapter drives. */
|
|
88
|
+
export interface CompatQueryInterface {
|
|
89
|
+
findMany(args?: Record<string, unknown>): Promise<unknown>;
|
|
90
|
+
findFirst(args?: Record<string, unknown>): Promise<unknown>;
|
|
91
|
+
findUnique(args: Record<string, unknown>): Promise<unknown>;
|
|
92
|
+
findFirstOrThrow(args?: Record<string, unknown>): Promise<unknown>;
|
|
93
|
+
findUniqueOrThrow(args: Record<string, unknown>): Promise<unknown>;
|
|
94
|
+
create(args: Record<string, unknown>): Promise<unknown>;
|
|
95
|
+
createMany(args: Record<string, unknown>): Promise<unknown[]>;
|
|
96
|
+
update(args: Record<string, unknown>): Promise<unknown>;
|
|
97
|
+
updateMany(args: Record<string, unknown>): Promise<{
|
|
98
|
+
count: number;
|
|
99
|
+
}>;
|
|
100
|
+
delete(args: Record<string, unknown>): Promise<unknown>;
|
|
101
|
+
deleteMany(args: Record<string, unknown>): Promise<{
|
|
102
|
+
count: number;
|
|
103
|
+
}>;
|
|
104
|
+
upsert(args: Record<string, unknown>): Promise<unknown>;
|
|
105
|
+
count(args?: Record<string, unknown>): Promise<number>;
|
|
106
|
+
aggregate(args: Record<string, unknown>): Promise<unknown>;
|
|
107
|
+
groupBy(args: Record<string, unknown>): Promise<unknown[]>;
|
|
108
|
+
buildFindMany(args?: Record<string, unknown>): DeferredQuery<unknown>;
|
|
109
|
+
buildFindFirst(args?: Record<string, unknown>): DeferredQuery<unknown>;
|
|
110
|
+
buildFindUnique(args: Record<string, unknown>): DeferredQuery<unknown>;
|
|
111
|
+
buildFindFirstOrThrow(args?: Record<string, unknown>): DeferredQuery<unknown>;
|
|
112
|
+
buildFindUniqueOrThrow(args: Record<string, unknown>): DeferredQuery<unknown>;
|
|
113
|
+
buildCreate(args: Record<string, unknown>): DeferredQuery<unknown>;
|
|
114
|
+
buildCreateMany(args: Record<string, unknown>): DeferredQuery<unknown[]>;
|
|
115
|
+
buildUpdate(args: Record<string, unknown>): DeferredQuery<unknown>;
|
|
116
|
+
buildUpdateMany(args: Record<string, unknown>): DeferredQuery<{
|
|
117
|
+
count: number;
|
|
118
|
+
}>;
|
|
119
|
+
buildDelete(args: Record<string, unknown>): DeferredQuery<unknown>;
|
|
120
|
+
buildDeleteMany(args: Record<string, unknown>): DeferredQuery<{
|
|
121
|
+
count: number;
|
|
122
|
+
}>;
|
|
123
|
+
buildUpsert(args: Record<string, unknown>): DeferredQuery<unknown>;
|
|
124
|
+
buildCount(args?: Record<string, unknown>): DeferredQuery<number>;
|
|
125
|
+
buildAggregate(args: Record<string, unknown>): DeferredQuery<unknown>;
|
|
126
|
+
buildGroupBy(args: Record<string, unknown>): DeferredQuery<unknown[]>;
|
|
127
|
+
}
|
|
128
|
+
/** A transaction-scoped client handed to a `$transaction(callback)`. */
|
|
129
|
+
export interface CompatTransactionClient {
|
|
130
|
+
table(name: string): CompatQueryInterface;
|
|
131
|
+
}
|
|
132
|
+
/** The minimal `TurbineClient` surface the adapter consumes. */
|
|
133
|
+
export interface CompatTurbineClient extends CompatTransactionClient {
|
|
134
|
+
readonly schema: SchemaMetadata;
|
|
135
|
+
$transaction<R>(fn: (tx: CompatTransactionClient) => Promise<R>, options?: unknown): Promise<R>;
|
|
136
|
+
$transaction(queries: readonly DeferredQuery<unknown>[]): Promise<unknown[]>;
|
|
137
|
+
}
|
|
138
|
+
declare const SQL_FRAGMENT: unique symbol;
|
|
139
|
+
/** A composable SQL fragment, the local stand-in for `Prisma.Sql`. */
|
|
140
|
+
export interface Sql {
|
|
141
|
+
/** Literal string segments; `strings.length === values.length + 1`. */
|
|
142
|
+
readonly strings: readonly string[];
|
|
143
|
+
/** Interpolated values, one between each pair of `strings`. */
|
|
144
|
+
readonly values: readonly unknown[];
|
|
145
|
+
readonly [SQL_FRAGMENT]: true;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* `Prisma`-compatible raw-SQL helpers, a minimal local implementation so
|
|
149
|
+
* migrated `Prisma.sql\`…\`` / `Prisma.join(...)` / `Prisma.raw(...)` calls keep
|
|
150
|
+
* composing. Fragments are flattened at execution time into a single
|
|
151
|
+
* parameterized statement (values become `$N`), so composition is injection-safe
|
|
152
|
+
* by construction.
|
|
153
|
+
*/
|
|
154
|
+
export declare const Prisma: {
|
|
155
|
+
/** Tagged-template fragment: `Prisma.sql\`id = ${id}\``. */
|
|
156
|
+
sql(strings: TemplateStringsArray, ...values: unknown[]): Sql;
|
|
157
|
+
/**
|
|
158
|
+
* Join fragments/values with a separator: `Prisma.join([1, 2, 3])` →
|
|
159
|
+
* `$1, $2, $3`. Each element that is not already a fragment becomes a bound
|
|
160
|
+
* value.
|
|
161
|
+
*/
|
|
162
|
+
join(items: readonly unknown[], separator?: string, prefix?: string, suffix?: string): Sql;
|
|
163
|
+
/**
|
|
164
|
+
* A raw, unparameterized SQL fragment. The string is spliced verbatim, never
|
|
165
|
+
* pass user input here (matches Prisma's `Prisma.raw` contract).
|
|
166
|
+
*/
|
|
167
|
+
raw(sql: string): Sql;
|
|
168
|
+
/** An empty fragment. */
|
|
169
|
+
empty: Sql;
|
|
170
|
+
};
|
|
171
|
+
/** Options for {@link createPrismaCompatClient}. */
|
|
172
|
+
export interface PrismaCompatOptions {
|
|
173
|
+
/**
|
|
174
|
+
* When `true`, every to-many `with` relation lacking an explicit `orderBy` is
|
|
175
|
+
* loaded ordered by the target table's primary key ascending (Prisma's
|
|
176
|
+
* relation rows come back in a stable order). This passes through to Turbine's
|
|
177
|
+
* core `stableRelationOrder` flag, it never re-walks the `with` tree. An
|
|
178
|
+
* explicit per-relation `orderBy` always wins. Default `false`.
|
|
179
|
+
*/
|
|
180
|
+
stablePkOrder?: boolean;
|
|
181
|
+
/**
|
|
182
|
+
* When `true`, thrown {@link TurbineError}s are decorated with a `.code` equal
|
|
183
|
+
* to the nearest Prisma error code (e.g. `P2002` for a unique violation),
|
|
184
|
+
* WITHOUT pretending `instanceof PrismaClientKnownRequestError`. Default
|
|
185
|
+
* `false` (Turbine's own `TURBINE_E0NN` codes are preserved untouched).
|
|
186
|
+
*/
|
|
187
|
+
prismaErrorCodes?: boolean;
|
|
188
|
+
}
|
|
189
|
+
/** Symbol under which a lazy delegate call exposes its batchable plan. */
|
|
190
|
+
export declare const COMPAT_DEFERRED: unique symbol;
|
|
191
|
+
/**
|
|
192
|
+
* The per-model type bundle a consumer supplies to type a model delegate.
|
|
193
|
+
* Populate `Row` (and optionally the arg shapes) from the generated entity
|
|
194
|
+
* types; unspecified members fall back to permissive shapes.
|
|
195
|
+
*/
|
|
196
|
+
export interface PrismaModelTypes {
|
|
197
|
+
Row: object;
|
|
198
|
+
Create?: object;
|
|
199
|
+
Update?: object;
|
|
200
|
+
Where?: object;
|
|
201
|
+
OrderBy?: object;
|
|
202
|
+
Select?: object;
|
|
203
|
+
Include?: object;
|
|
204
|
+
}
|
|
205
|
+
type Args = Record<string, unknown>;
|
|
206
|
+
/** A typed model delegate mirroring Prisma's `db.model.*` surface. */
|
|
207
|
+
export interface PrismaModelDelegate<M extends PrismaModelTypes> {
|
|
208
|
+
findMany(args?: Args): Promise<M['Row'][]>;
|
|
209
|
+
findFirst(args?: Args): Promise<M['Row'] | null>;
|
|
210
|
+
findUnique(args: Args): Promise<M['Row'] | null>;
|
|
211
|
+
findFirstOrThrow(args?: Args): Promise<M['Row']>;
|
|
212
|
+
findUniqueOrThrow(args: Args): Promise<M['Row']>;
|
|
213
|
+
create(args: Args): Promise<M['Row']>;
|
|
214
|
+
createMany(args: Args): Promise<{
|
|
215
|
+
count: number;
|
|
216
|
+
}>;
|
|
217
|
+
update(args: Args): Promise<M['Row']>;
|
|
218
|
+
updateMany(args: Args): Promise<{
|
|
219
|
+
count: number;
|
|
220
|
+
}>;
|
|
221
|
+
delete(args: Args): Promise<M['Row']>;
|
|
222
|
+
deleteMany(args?: Args): Promise<{
|
|
223
|
+
count: number;
|
|
224
|
+
}>;
|
|
225
|
+
upsert(args: Args): Promise<M['Row']>;
|
|
226
|
+
count(args?: Args): Promise<number>;
|
|
227
|
+
aggregate(args: Args): Promise<Record<string, unknown>>;
|
|
228
|
+
groupBy(args: Args): Promise<Record<string, unknown>[]>;
|
|
229
|
+
}
|
|
230
|
+
/** The client-level surface (`$transaction` / raw), added to the model map. */
|
|
231
|
+
export interface PrismaCompatClientBase<S extends Record<string, PrismaModelTypes> = Record<string, PrismaModelTypes>> {
|
|
232
|
+
$transaction<R>(fn: (tx: PrismaCompatTransactionClient<S>) => Promise<R>, options?: PrismaCompatTxOptions): Promise<R>;
|
|
233
|
+
$transaction<P extends readonly PromiseLike<unknown>[]>(promises: readonly [...P]): Promise<{
|
|
234
|
+
[K in keyof P]: Awaited<P[K]>;
|
|
235
|
+
}>;
|
|
236
|
+
$queryRaw<T = unknown>(strings: TemplateStringsArray, ...values: unknown[]): Promise<T[]>;
|
|
237
|
+
$queryRawUnsafe<T = unknown>(sql: string, ...params: unknown[]): Promise<T[]>;
|
|
238
|
+
$executeRaw(strings: TemplateStringsArray, ...values: unknown[]): Promise<number>;
|
|
239
|
+
$executeRawUnsafe(sql: string, ...params: unknown[]): Promise<number>;
|
|
240
|
+
$connect(): Promise<void>;
|
|
241
|
+
$disconnect(): Promise<void>;
|
|
242
|
+
}
|
|
243
|
+
/** Options accepted by the callback form of `$transaction`. */
|
|
244
|
+
export interface PrismaCompatTxOptions {
|
|
245
|
+
isolationLevel?: 'ReadUncommitted' | 'ReadCommitted' | 'RepeatableRead' | 'Serializable';
|
|
246
|
+
timeout?: number;
|
|
247
|
+
maxWait?: number;
|
|
248
|
+
}
|
|
249
|
+
/** The transaction-scoped client handed to a `$transaction(callback)`. */
|
|
250
|
+
export type PrismaCompatTransactionClient<S extends Record<string, PrismaModelTypes> = Record<string, PrismaModelTypes>> = {
|
|
251
|
+
[K in keyof S]: PrismaModelDelegate<S[K]>;
|
|
252
|
+
};
|
|
253
|
+
/**
|
|
254
|
+
* The full typed compat client: a model delegate per Prisma model name, plus the
|
|
255
|
+
* client-level `$transaction` / raw surface. Parameterize `S` with your
|
|
256
|
+
* generated entity types for full autocompletion.
|
|
257
|
+
*/
|
|
258
|
+
export type PrismaCompatClient<S extends Record<string, PrismaModelTypes> = Record<string, PrismaModelTypes>> = {
|
|
259
|
+
[K in keyof S]: PrismaModelDelegate<S[K]>;
|
|
260
|
+
} & {
|
|
261
|
+
[K in keyof S as Uncapitalize<K & string>]: PrismaModelDelegate<S[K]>;
|
|
262
|
+
} & PrismaCompatClientBase<S>;
|
|
263
|
+
/**
|
|
264
|
+
* Create a PrismaClient-surface adapter over a {@link TurbineClient}, driven by a
|
|
265
|
+
* {@link PrismaCompatMap} (the `prisma-map.ts` that `turbine
|
|
266
|
+
* migrate-from-prisma` emits).
|
|
267
|
+
*
|
|
268
|
+
* The returned object exposes a delegate per Prisma model name (by the map's
|
|
269
|
+
* keys) plus the client-level `$transaction` / `$queryRaw` / `$executeRaw`
|
|
270
|
+
* surface. Model and field names are translated through the map in both
|
|
271
|
+
* directions; when field names are identity (the `--keep-column-names` pairing)
|
|
272
|
+
* result rekeying is skipped entirely.
|
|
273
|
+
*
|
|
274
|
+
* @typeParam S - Per-model type bundles (from your generated entity types) for
|
|
275
|
+
* full autocompletion. Defaults to a permissive shape.
|
|
276
|
+
* @param client - The TurbineClient (or generated subclass / `turbineHttp` client).
|
|
277
|
+
* @param map - The resolved `PRISMA_MAP`.
|
|
278
|
+
* @param options - {@link PrismaCompatOptions}.
|
|
279
|
+
*/
|
|
280
|
+
export declare function createPrismaCompatClient<S extends Record<string, PrismaModelTypes> = Record<string, PrismaModelTypes>>(client: TurbineClient, map: PrismaCompatMap, options?: PrismaCompatOptions): PrismaCompatClient<S>;
|
|
281
|
+
export {};
|