@prisma-next/sql-relational-core 0.3.0-dev.1 → 0.3.0-dev.10

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.
Files changed (95) hide show
  1. package/README.md +1 -1
  2. package/dist/ast/adapter-types.d.ts +28 -0
  3. package/dist/ast/adapter-types.d.ts.map +1 -0
  4. package/dist/{query-lane-context-BhOMmb_K.d.ts → ast/codec-types.d.ts} +14 -31
  5. package/dist/ast/codec-types.d.ts.map +1 -0
  6. package/dist/ast/common.d.ts +7 -0
  7. package/dist/ast/common.d.ts.map +1 -0
  8. package/dist/ast/delete.d.ts +8 -0
  9. package/dist/ast/delete.d.ts.map +1 -0
  10. package/dist/ast/driver-types.d.ts +20 -0
  11. package/dist/ast/driver-types.d.ts.map +1 -0
  12. package/dist/ast/insert.d.ts +8 -0
  13. package/dist/ast/insert.d.ts.map +1 -0
  14. package/dist/ast/join.d.ts +6 -0
  15. package/dist/ast/join.d.ts.map +1 -0
  16. package/dist/ast/order.d.ts +6 -0
  17. package/dist/ast/order.d.ts.map +1 -0
  18. package/dist/ast/predicate.d.ts +4 -0
  19. package/dist/ast/predicate.d.ts.map +1 -0
  20. package/dist/ast/select.d.ts +18 -0
  21. package/dist/ast/select.d.ts.map +1 -0
  22. package/dist/{plan-D0OG5qzy.d.ts → ast/types.d.ts} +23 -47
  23. package/dist/ast/types.d.ts.map +1 -0
  24. package/dist/ast/update.d.ts +9 -0
  25. package/dist/ast/update.d.ts.map +1 -0
  26. package/dist/ast/util.d.ts +2 -0
  27. package/dist/ast/util.d.ts.map +1 -0
  28. package/dist/errors.d.ts +2 -0
  29. package/dist/errors.d.ts.map +1 -0
  30. package/dist/exports/ast.d.ts +14 -119
  31. package/dist/exports/ast.d.ts.map +1 -0
  32. package/dist/exports/errors.d.ts +2 -1
  33. package/dist/exports/errors.d.ts.map +1 -0
  34. package/dist/exports/guards.d.ts +2 -63
  35. package/dist/exports/guards.d.ts.map +1 -0
  36. package/dist/exports/operations-registry.d.ts +2 -13
  37. package/dist/exports/operations-registry.d.ts.map +1 -0
  38. package/dist/exports/param.d.ts +3 -14
  39. package/dist/exports/param.d.ts.map +1 -0
  40. package/dist/exports/plan.d.ts +2 -5
  41. package/dist/exports/plan.d.ts.map +1 -0
  42. package/dist/exports/query-lane-context.d.ts +2 -4
  43. package/dist/exports/query-lane-context.d.ts.map +1 -0
  44. package/dist/exports/schema.d.ts +3 -69
  45. package/dist/exports/schema.d.ts.map +1 -0
  46. package/dist/exports/types.d.ts +2 -335
  47. package/dist/exports/types.d.ts.map +1 -0
  48. package/dist/index.d.ts +9 -13
  49. package/dist/index.d.ts.map +1 -0
  50. package/dist/operations-registry.d.ts +5 -0
  51. package/dist/operations-registry.d.ts.map +1 -0
  52. package/dist/param.d.ts +4 -0
  53. package/dist/param.d.ts.map +1 -0
  54. package/dist/plan.d.ts +23 -0
  55. package/dist/plan.d.ts.map +1 -0
  56. package/dist/query-lane-context.d.ts +16 -0
  57. package/dist/query-lane-context.d.ts.map +1 -0
  58. package/dist/schema.d.ts +63 -0
  59. package/dist/schema.d.ts.map +1 -0
  60. package/dist/types.d.ts +332 -0
  61. package/dist/types.d.ts.map +1 -0
  62. package/dist/utils/guards.d.ts +55 -0
  63. package/dist/utils/guards.d.ts.map +1 -0
  64. package/package.json +14 -14
  65. package/src/ast/adapter-types.ts +36 -0
  66. package/src/ast/codec-types.ts +375 -0
  67. package/src/ast/common.ts +36 -0
  68. package/src/ast/delete.ts +17 -0
  69. package/src/ast/driver-types.ts +25 -0
  70. package/src/ast/insert.ts +17 -0
  71. package/src/ast/join.ts +54 -0
  72. package/src/ast/order.ts +11 -0
  73. package/src/ast/predicate.ts +30 -0
  74. package/src/ast/select.ts +39 -0
  75. package/src/ast/types.ts +133 -0
  76. package/src/ast/update.ts +19 -0
  77. package/src/ast/util.ts +9 -0
  78. package/src/errors.ts +1 -0
  79. package/src/exports/ast.ts +13 -0
  80. package/src/exports/errors.ts +1 -0
  81. package/src/exports/guards.ts +10 -0
  82. package/src/exports/operations-registry.ts +1 -0
  83. package/src/exports/param.ts +2 -0
  84. package/src/exports/plan.ts +1 -0
  85. package/src/exports/query-lane-context.ts +1 -0
  86. package/src/exports/schema.ts +6 -0
  87. package/src/exports/types.ts +1 -0
  88. package/src/index.ts +8 -0
  89. package/src/operations-registry.ts +237 -0
  90. package/src/param.ts +15 -0
  91. package/src/plan.ts +39 -0
  92. package/src/query-lane-context.ts +18 -0
  93. package/src/schema.ts +373 -0
  94. package/src/types.ts +547 -0
  95. package/src/utils/guards.ts +123 -0
package/src/types.ts ADDED
@@ -0,0 +1,547 @@
1
+ import type {
2
+ ResultType as CoreResultType,
3
+ ExecutionPlan,
4
+ PlanRefs,
5
+ } from '@prisma-next/contract/types';
6
+ import type { ArgSpec, ReturnSpec } from '@prisma-next/operations';
7
+ import type { SqlContract, SqlStorage, StorageColumn } from '@prisma-next/sql-contract/types';
8
+ import type { SqlLoweringSpec } from '@prisma-next/sql-operations';
9
+ import type {
10
+ BinaryOp,
11
+ ColumnRef,
12
+ Direction,
13
+ OperationExpr,
14
+ ParamRef,
15
+ QueryAst,
16
+ } from './ast/types';
17
+ import type { SqlQueryPlan } from './plan';
18
+ import type { QueryLaneContext } from './query-lane-context';
19
+
20
+ export interface ParamPlaceholder {
21
+ readonly kind: 'param-placeholder';
22
+ readonly name: string;
23
+ }
24
+
25
+ export interface OrderBuilder<
26
+ ColumnName extends string = string,
27
+ ColumnMeta extends StorageColumn = StorageColumn,
28
+ JsType = unknown,
29
+ > {
30
+ readonly kind: 'order';
31
+ readonly expr: ColumnBuilder<ColumnName, ColumnMeta, JsType> | OperationExpr;
32
+ readonly dir: Direction;
33
+ }
34
+
35
+ /**
36
+ * Creates an OrderBuilder for use in orderBy clauses.
37
+ */
38
+ export function createOrderBuilder(
39
+ expr: AnyColumnBuilder | OperationExpr,
40
+ dir: Direction,
41
+ ): AnyOrderBuilder {
42
+ return { kind: 'order', expr, dir } as AnyOrderBuilder;
43
+ }
44
+
45
+ /**
46
+ * ColumnBuilder with optional operation methods based on the column's typeId.
47
+ * When Operations is provided and the column's typeId matches, operation methods are included.
48
+ */
49
+ export type ColumnBuilder<
50
+ ColumnName extends string = string,
51
+ ColumnMeta extends StorageColumn = StorageColumn,
52
+ JsType = unknown,
53
+ Operations extends OperationTypes = Record<string, never>,
54
+ > = {
55
+ readonly kind: 'column';
56
+ readonly table: string;
57
+ readonly column: ColumnName;
58
+ readonly columnMeta: ColumnMeta;
59
+ eq(value: ParamPlaceholder | AnyColumnBuilderBase): BinaryBuilder<ColumnName, ColumnMeta, JsType>;
60
+ neq(
61
+ value: ParamPlaceholder | AnyColumnBuilderBase,
62
+ ): BinaryBuilder<ColumnName, ColumnMeta, JsType>;
63
+ gt(value: ParamPlaceholder | AnyColumnBuilderBase): BinaryBuilder<ColumnName, ColumnMeta, JsType>;
64
+ lt(value: ParamPlaceholder | AnyColumnBuilderBase): BinaryBuilder<ColumnName, ColumnMeta, JsType>;
65
+ gte(
66
+ value: ParamPlaceholder | AnyColumnBuilderBase,
67
+ ): BinaryBuilder<ColumnName, ColumnMeta, JsType>;
68
+ lte(
69
+ value: ParamPlaceholder | AnyColumnBuilderBase,
70
+ ): BinaryBuilder<ColumnName, ColumnMeta, JsType>;
71
+ asc(): OrderBuilder<ColumnName, ColumnMeta, JsType>;
72
+ desc(): OrderBuilder<ColumnName, ColumnMeta, JsType>;
73
+ // Helper property for type extraction (not used at runtime)
74
+ readonly __jsType: JsType;
75
+ } & (ColumnMeta['codecId'] extends string
76
+ ? ColumnMeta['codecId'] extends keyof Operations
77
+ ? OperationMethods<
78
+ OperationsForTypeId<ColumnMeta['codecId'] & string, Operations>,
79
+ ColumnName,
80
+ StorageColumn,
81
+ JsType
82
+ >
83
+ : Record<string, never>
84
+ : Record<string, never>);
85
+
86
+ export interface BinaryBuilder<
87
+ ColumnName extends string = string,
88
+ ColumnMeta extends StorageColumn = StorageColumn,
89
+ JsType = unknown,
90
+ > {
91
+ readonly kind: 'binary';
92
+ readonly op: BinaryOp;
93
+ readonly left: ColumnBuilder<ColumnName, ColumnMeta, JsType> | OperationExpr;
94
+ readonly right: ParamPlaceholder | AnyColumnBuilderBase;
95
+ }
96
+
97
+ // Helper aliases for usage sites where the specific column parameters are irrelevant
98
+ // Accepts any ColumnBuilder regardless of its Operations parameter
99
+ // Note: We use `any` here because TypeScript's variance rules don't allow us to express
100
+ // "any type that extends OperationTypes" in a way that works for assignment.
101
+ // Contract-specific OperationTypes (e.g., PgVectorOperationTypes) are not assignable
102
+ // to the base OperationTypes in generic parameter position, even though they extend it structurally.
103
+ // Helper type that accepts any ColumnBuilder regardless of its generic parameters
104
+ // This is needed because conditional types in ColumnBuilder create incompatible intersection types
105
+ // when Operations differs, even though structurally they're compatible
106
+ export type AnyColumnBuilderBase = {
107
+ readonly kind: 'column';
108
+ readonly table: string;
109
+ readonly column: string;
110
+ readonly columnMeta: StorageColumn;
111
+ eq(value: ParamPlaceholder | AnyColumnBuilderBase): AnyBinaryBuilder;
112
+ neq(value: ParamPlaceholder | AnyColumnBuilderBase): AnyBinaryBuilder;
113
+ gt(value: ParamPlaceholder | AnyColumnBuilderBase): AnyBinaryBuilder;
114
+ lt(value: ParamPlaceholder | AnyColumnBuilderBase): AnyBinaryBuilder;
115
+ gte(value: ParamPlaceholder | AnyColumnBuilderBase): AnyBinaryBuilder;
116
+ lte(value: ParamPlaceholder | AnyColumnBuilderBase): AnyBinaryBuilder;
117
+ asc(): AnyOrderBuilder;
118
+ desc(): AnyOrderBuilder;
119
+ readonly __jsType: unknown;
120
+ // Allow any operation methods (from conditional type)
121
+ readonly [key: string]: unknown;
122
+ };
123
+
124
+ export type AnyColumnBuilder =
125
+ | ColumnBuilder<
126
+ string,
127
+ StorageColumn,
128
+ unknown,
129
+ // biome-ignore lint/suspicious/noExplicitAny: AnyColumnBuilder must accept column builders with any operation types
130
+ any
131
+ >
132
+ | AnyColumnBuilderBase;
133
+ export type AnyBinaryBuilder = BinaryBuilder<string, StorageColumn, unknown>;
134
+ export type AnyOrderBuilder = OrderBuilder<string, StorageColumn, unknown>;
135
+
136
+ export function isColumnBuilder(value: unknown): value is AnyColumnBuilder {
137
+ return (
138
+ typeof value === 'object' &&
139
+ value !== null &&
140
+ 'kind' in value &&
141
+ (value as { kind: unknown }).kind === 'column'
142
+ );
143
+ }
144
+
145
+ export interface JoinOnBuilder {
146
+ eqCol(left: AnyColumnBuilder, right: AnyColumnBuilder): JoinOnPredicate;
147
+ }
148
+
149
+ export interface JoinOnPredicate {
150
+ readonly kind: 'join-on';
151
+ readonly left: AnyColumnBuilder;
152
+ readonly right: AnyColumnBuilder;
153
+ }
154
+
155
+ export type Expr = ColumnRef | ParamRef;
156
+
157
+ /**
158
+ * Helper type to extract codec output type from CodecTypes.
159
+ * Returns never if the codecId is not found in CodecTypes.
160
+ */
161
+ type ExtractCodecOutputType<
162
+ CodecId extends string,
163
+ CodecTypes extends Record<string, { readonly output: unknown }>,
164
+ > = CodecId extends keyof CodecTypes
165
+ ? CodecTypes[CodecId] extends { readonly output: infer Output }
166
+ ? Output
167
+ : never
168
+ : never;
169
+
170
+ /**
171
+ * Type-level operation signature.
172
+ * Represents an operation at the type level, similar to OperationSignature at runtime.
173
+ */
174
+ export type OperationTypeSignature = {
175
+ readonly args: ReadonlyArray<ArgSpec>;
176
+ readonly returns: ReturnSpec;
177
+ readonly lowering: SqlLoweringSpec;
178
+ readonly capabilities?: ReadonlyArray<string>;
179
+ };
180
+
181
+ /**
182
+ * Type-level operation registry.
183
+ * Maps typeId → operations, where operations is a record of method name → operation signature.
184
+ *
185
+ * Example:
186
+ * ```typescript
187
+ * type MyOperations: OperationTypes = {
188
+ * 'pg/vector@1': {
189
+ * cosineDistance: {
190
+ * args: [{ kind: 'typeId'; type: 'pg/vector@1' }];
191
+ * returns: { kind: 'builtin'; type: 'number' };
192
+ * lowering: { targetFamily: 'sql'; strategy: 'function'; template: '...' };
193
+ * };
194
+ * };
195
+ * };
196
+ * ```
197
+ */
198
+ export type OperationTypes = Record<string, Record<string, OperationTypeSignature>>;
199
+
200
+ /**
201
+ * CodecTypes represents a map of typeId to codec definitions.
202
+ * Each codec definition must have an `output` property indicating the JavaScript type.
203
+ *
204
+ * Example:
205
+ * ```typescript
206
+ * type MyCodecTypes: CodecTypes = {
207
+ * 'pg/int4@1': { output: number };
208
+ * 'pg/text@1': { output: string };
209
+ * };
210
+ * ```
211
+ */
212
+ export type CodecTypes = Record<string, { readonly output: unknown }>;
213
+
214
+ /**
215
+ * Extracts operations for a given typeId from the operation registry.
216
+ * Returns an empty record if the typeId is not found.
217
+ *
218
+ * @example
219
+ * ```typescript
220
+ * type Ops = OperationsForTypeId<'pg/vector@1', MyOperations>;
221
+ * // Ops = { cosineDistance: { ... }, l2Distance: { ... } }
222
+ * ```
223
+ */
224
+ export type OperationsForTypeId<
225
+ TypeId extends string,
226
+ Operations extends OperationTypes,
227
+ > = Operations extends Record<string, never>
228
+ ? Record<string, never>
229
+ : TypeId extends keyof Operations
230
+ ? Operations[TypeId]
231
+ : Record<string, never>;
232
+
233
+ /**
234
+ * Maps operation signatures to method signatures on ColumnBuilder.
235
+ * Each operation becomes a method that returns a ColumnBuilder or BinaryBuilder
236
+ * based on the return type.
237
+ */
238
+ type OperationMethods<
239
+ Ops extends Record<string, OperationTypeSignature>,
240
+ ColumnName extends string,
241
+ ColumnMeta extends StorageColumn,
242
+ JsType,
243
+ > = {
244
+ [K in keyof Ops]: Ops[K] extends OperationTypeSignature
245
+ ? (
246
+ ...args: OperationArgs<Ops[K]['args']>
247
+ ) => OperationReturn<Ops[K]['returns'], ColumnName, ColumnMeta, JsType>
248
+ : never;
249
+ };
250
+
251
+ /**
252
+ * Maps operation argument specs to TypeScript argument types.
253
+ * - typeId args: ColumnBuilder (accepts base columns or operation results)
254
+ * - param args: ParamPlaceholder
255
+ * - literal args: unknown (could be more specific in future)
256
+ */
257
+ type OperationArgs<Args extends ReadonlyArray<ArgSpec>> = Args extends readonly [
258
+ infer First,
259
+ ...infer Rest,
260
+ ]
261
+ ? First extends ArgSpec
262
+ ? [ArgToType<First>, ...(Rest extends ReadonlyArray<ArgSpec> ? OperationArgs<Rest> : [])]
263
+ : []
264
+ : [];
265
+
266
+ type ArgToType<Arg extends ArgSpec> = Arg extends { kind: 'typeId' }
267
+ ? AnyColumnBuilder
268
+ : Arg extends { kind: 'param' }
269
+ ? ParamPlaceholder
270
+ : Arg extends { kind: 'literal' }
271
+ ? unknown
272
+ : never;
273
+
274
+ /**
275
+ * Maps operation return spec to return type.
276
+ * - builtin types: ColumnBuilder with appropriate JsType (matches runtime behavior)
277
+ * - typeId types: ColumnBuilder (for now, could be more specific in future)
278
+ */
279
+ type OperationReturn<
280
+ Returns extends ReturnSpec,
281
+ ColumnName extends string,
282
+ ColumnMeta extends StorageColumn,
283
+ _JsType,
284
+ > = Returns extends { kind: 'builtin'; type: infer T }
285
+ ? T extends 'number'
286
+ ? ColumnBuilder<ColumnName, ColumnMeta, number>
287
+ : T extends 'boolean'
288
+ ? ColumnBuilder<ColumnName, ColumnMeta, boolean>
289
+ : T extends 'string'
290
+ ? ColumnBuilder<ColumnName, ColumnMeta, string>
291
+ : ColumnBuilder<ColumnName, ColumnMeta, unknown>
292
+ : Returns extends { kind: 'typeId' }
293
+ ? AnyColumnBuilder
294
+ : ColumnBuilder<ColumnName, ColumnMeta, unknown>;
295
+
296
+ /**
297
+ * Computes JavaScript type for a column at column creation time.
298
+ *
299
+ * Type inference:
300
+ * - Read columnMeta.codecId as typeId string literal
301
+ * - Look up CodecTypes[typeId].output
302
+ * - Apply nullability: nullable ? Output | null : Output
303
+ */
304
+ type ColumnMetaTypeId<ColumnMeta> = ColumnMeta extends { codecId: infer CodecId extends string }
305
+ ? CodecId
306
+ : ColumnMeta extends { type: infer TypeId extends string }
307
+ ? TypeId
308
+ : never;
309
+
310
+ export type ComputeColumnJsType<
311
+ _Contract extends SqlContract<SqlStorage>,
312
+ _TableName extends string,
313
+ _ColumnName extends string,
314
+ ColumnMeta extends StorageColumn,
315
+ CodecTypes extends Record<string, { readonly output: unknown }>,
316
+ > = ColumnMeta extends { nullable: infer Nullable }
317
+ ? ColumnMetaTypeId<ColumnMeta> extends infer TypeId
318
+ ? TypeId extends string
319
+ ? ExtractCodecOutputType<TypeId, CodecTypes> extends infer CodecOutput
320
+ ? [CodecOutput] extends [never]
321
+ ? unknown // Codec not found in CodecTypes
322
+ : Nullable extends true
323
+ ? CodecOutput | null
324
+ : CodecOutput
325
+ : unknown
326
+ : unknown
327
+ : unknown
328
+ : unknown;
329
+
330
+ /**
331
+ * Infers Row type from a projection object.
332
+ * Maps Record<string, ColumnBuilder> to Record<string, JSType>
333
+ *
334
+ * Extracts the pre-computed JsType from each ColumnBuilder in the projection.
335
+ */
336
+ /**
337
+ * Extracts the inferred JsType carried by a ColumnBuilder.
338
+ */
339
+ type ExtractJsTypeFromColumnBuilder<CB extends AnyColumnBuilder> = CB extends ColumnBuilder<
340
+ infer _ColumnName extends string,
341
+ infer _ColumnMeta extends StorageColumn,
342
+ infer JsType,
343
+ infer _Ops
344
+ >
345
+ ? JsType
346
+ : never;
347
+
348
+ export type InferProjectionRow<P extends Record<string, AnyColumnBuilder>> = {
349
+ [K in keyof P]: ExtractJsTypeFromColumnBuilder<P[K]>;
350
+ };
351
+
352
+ /**
353
+ * Nested projection type - allows recursive nesting of ColumnBuilder or nested objects.
354
+ */
355
+ export type NestedProjection = Record<
356
+ string,
357
+ | AnyColumnBuilder
358
+ | Record<
359
+ string,
360
+ | AnyColumnBuilder
361
+ | Record<
362
+ string,
363
+ AnyColumnBuilder | Record<string, AnyColumnBuilder | Record<string, AnyColumnBuilder>>
364
+ >
365
+ >
366
+ >;
367
+
368
+ /**
369
+ * Helper type to extract include type from Includes map.
370
+ * Returns the value type if K is a key of Includes, otherwise returns unknown.
371
+ */
372
+ type ExtractIncludeType<
373
+ K extends string,
374
+ Includes extends Record<string, unknown>,
375
+ > = K extends keyof Includes ? Includes[K] : unknown;
376
+
377
+ /**
378
+ * Infers Row type from a nested projection object.
379
+ * Recursively maps Record<string, ColumnBuilder | boolean | NestedProjection> to nested object types.
380
+ *
381
+ * Extracts the pre-computed JsType from each ColumnBuilder at leaves.
382
+ * When a value is `true`, it represents an include reference and infers `Array<ChildShape>`
383
+ * by looking up the include alias in the Includes type map.
384
+ */
385
+ export type InferNestedProjectionRow<
386
+ P extends Record<string, AnyColumnBuilder | boolean | NestedProjection>,
387
+ CodecTypes extends Record<string, { readonly output: unknown }> = Record<string, never>,
388
+ Includes extends Record<string, unknown> = Record<string, never>,
389
+ > = {
390
+ [K in keyof P]: P[K] extends AnyColumnBuilder
391
+ ? ExtractJsTypeFromColumnBuilder<P[K]>
392
+ : P[K] extends true
393
+ ? Array<ExtractIncludeType<K & string, Includes>> // Include reference - infers Array<ChildShape> from Includes map
394
+ : P[K] extends NestedProjection
395
+ ? InferNestedProjectionRow<P[K], CodecTypes, Includes>
396
+ : never;
397
+ };
398
+
399
+ /**
400
+ * Infers Row type from a tuple of ColumnBuilders used in returning() clause.
401
+ * Extracts column name and JsType from each ColumnBuilder and creates a Record.
402
+ */
403
+ export type InferReturningRow<Columns extends readonly AnyColumnBuilder[]> =
404
+ Columns extends readonly [infer First, ...infer Rest]
405
+ ? First extends ColumnBuilder<
406
+ infer Name,
407
+ infer _Meta,
408
+ infer JsType,
409
+ infer _Ops extends OperationTypes
410
+ >
411
+ ? Name extends string
412
+ ? Rest extends readonly AnyColumnBuilder[]
413
+ ? { [K in Name]: JsType } & InferReturningRow<Rest>
414
+ : { [K in Name]: JsType }
415
+ : never
416
+ : never
417
+ : Record<string, never>;
418
+
419
+ /**
420
+ * Utility type to check if a contract has the required capabilities for includeMany.
421
+ * Requires both `lateral` and `jsonAgg` to be `true` in the contract's capabilities for the target.
422
+ * Capabilities are nested by target: `{ [target]: { lateral: true, jsonAgg: true } }`
423
+ */
424
+ export type HasIncludeManyCapabilities<TContract extends SqlContract<SqlStorage>> =
425
+ TContract extends { capabilities: infer C; target: infer T }
426
+ ? T extends string
427
+ ? C extends Record<string, Record<string, boolean>>
428
+ ? C extends { [K in T]: infer TargetCaps }
429
+ ? TargetCaps extends { lateral: true; jsonAgg: true }
430
+ ? true
431
+ : false
432
+ : false
433
+ : false
434
+ : false
435
+ : false;
436
+
437
+ /**
438
+ * SQL-specific Plan type that refines the ast field to use QueryAst.
439
+ * This is the type used by SQL query builders.
440
+ */
441
+ export type SqlPlan<Row = unknown> = ExecutionPlan<Row, QueryAst>;
442
+
443
+ /**
444
+ * Helper types for extracting contract structure.
445
+ */
446
+ export type TablesOf<TContract> = TContract extends {
447
+ storage: { tables: infer U };
448
+ }
449
+ ? U
450
+ : never;
451
+
452
+ export type TableKey<TContract> = Extract<keyof TablesOf<TContract>, string>;
453
+
454
+ // Common types for contract.d.ts generation (SQL-specific)
455
+ // These types are used by emitted contract.d.ts files to provide type-safe DSL/ORM types
456
+
457
+ /**
458
+ * Unique symbol for metadata property to avoid collisions with user-defined properties
459
+ */
460
+ export declare const META: unique symbol;
461
+
462
+ /**
463
+ * Extracts metadata from a type that has a META property
464
+ */
465
+ export type Meta<T extends { [META]: unknown }> = T[typeof META];
466
+
467
+ /**
468
+ * Metadata interface for table definitions
469
+ */
470
+ export interface TableMetadata<Name extends string> {
471
+ name: Name;
472
+ }
473
+
474
+ /**
475
+ * Metadata interface for model definitions
476
+ */
477
+ export interface ModelMetadata<Name extends string> {
478
+ name: Name;
479
+ }
480
+
481
+ /**
482
+ * Base interface for table definitions with metadata
483
+ * Used in contract.d.ts to define storage-level table types
484
+ */
485
+ export interface TableDef<Name extends string> {
486
+ readonly [META]: TableMetadata<Name>;
487
+ }
488
+
489
+ /**
490
+ * Base interface for model definitions with metadata
491
+ * Used in contract.d.ts to define application-level model types
492
+ */
493
+ export interface ModelDef<Name extends string> {
494
+ readonly [META]: ModelMetadata<Name>;
495
+ }
496
+
497
+ export type ColumnsOf<
498
+ TContract,
499
+ K extends TableKey<TContract>,
500
+ > = K extends keyof TablesOf<TContract>
501
+ ? TablesOf<TContract>[K] extends { columns: infer C }
502
+ ? C
503
+ : never
504
+ : never;
505
+
506
+ export interface RawTemplateOptions {
507
+ readonly refs?: PlanRefs;
508
+ readonly annotations?: Record<string, unknown>;
509
+ readonly projection?: ReadonlyArray<string>;
510
+ }
511
+
512
+ export interface RawFunctionOptions extends RawTemplateOptions {
513
+ readonly params: ReadonlyArray<unknown>;
514
+ }
515
+
516
+ export type RawTemplateFactory = (
517
+ strings: TemplateStringsArray,
518
+ ...values: readonly unknown[]
519
+ ) => ExecutionPlan;
520
+
521
+ export interface RawFactory extends RawTemplateFactory {
522
+ (text: string, options: RawFunctionOptions): ExecutionPlan;
523
+ with(options: RawTemplateOptions): RawTemplateFactory;
524
+ }
525
+
526
+ export type { RuntimeError } from '@prisma-next/plan';
527
+
528
+ export interface BuildParamsMap {
529
+ readonly [name: string]: unknown;
530
+ }
531
+
532
+ export interface BuildOptions {
533
+ readonly params?: BuildParamsMap;
534
+ }
535
+
536
+ export interface SqlBuilderOptions<
537
+ TContract extends SqlContract<SqlStorage> = SqlContract<SqlStorage>,
538
+ > {
539
+ readonly context: QueryLaneContext<TContract>;
540
+ }
541
+
542
+ /**
543
+ * SQL-specific ResultType that works with both Plan and SqlQueryPlan.
544
+ * This extends the core ResultType to also handle SqlQueryPlan.
545
+ * Example: `type Row = ResultType<typeof plan>`
546
+ */
547
+ export type ResultType<P> = P extends SqlQueryPlan<infer R> ? R : CoreResultType<P>;
@@ -0,0 +1,123 @@
1
+ import type { StorageColumn } from '@prisma-next/sql-contract/types';
2
+ import type { ColumnRef, LiteralExpr, OperationExpr, ParamRef } from '../ast/types';
3
+ import type { AnyColumnBuilder, ParamPlaceholder } from '../types';
4
+
5
+ /**
6
+ * Helper to extract columnMeta from a ColumnBuilder.
7
+ * Returns StorageColumn if present, undefined otherwise.
8
+ * AnyColumnBuilder is a union that includes types with columnMeta property,
9
+ * so we can safely access it after checking for existence.
10
+ */
11
+ export function getColumnMeta(expr: AnyColumnBuilder): StorageColumn | undefined {
12
+ // AnyColumnBuilder includes AnyColumnBuilderBase which has columnMeta: StorageColumn
13
+ // and ColumnBuilder which has columnMeta: ColumnMeta extends StorageColumn
14
+ // TypeScript should narrow the type after the 'in' check
15
+ if ('columnMeta' in expr) {
16
+ return expr.columnMeta;
17
+ }
18
+ return undefined;
19
+ }
20
+
21
+ /**
22
+ * Type predicate to check if a value is a ParamPlaceholder.
23
+ */
24
+ export function isParamPlaceholder(value: unknown): value is ParamPlaceholder {
25
+ return (
26
+ typeof value === 'object' &&
27
+ value !== null &&
28
+ 'kind' in value &&
29
+ (value as { kind: unknown }).kind === 'param-placeholder' &&
30
+ 'name' in value &&
31
+ typeof (value as { name: unknown }).name === 'string'
32
+ );
33
+ }
34
+
35
+ /**
36
+ * Recursively extracts the base ColumnRef from an OperationExpr.
37
+ * If the expression is already a ColumnRef, it is returned directly.
38
+ */
39
+ export function extractBaseColumnRef(expr: ColumnRef | OperationExpr): ColumnRef {
40
+ if (expr.kind === 'col') {
41
+ return expr;
42
+ }
43
+ return extractBaseColumnRef(expr.self);
44
+ }
45
+
46
+ /**
47
+ * Recursively collects all ColumnRef nodes from an expression tree.
48
+ * Handles nested OperationExpr structures by traversing both self and args.
49
+ */
50
+ export function collectColumnRefs(
51
+ expr: ColumnRef | ParamRef | LiteralExpr | OperationExpr,
52
+ ): ColumnRef[] {
53
+ if (expr.kind === 'col') {
54
+ return [expr];
55
+ }
56
+ if (expr.kind === 'operation') {
57
+ const refs: ColumnRef[] = collectColumnRefs(expr.self);
58
+ for (const arg of expr.args) {
59
+ refs.push(...collectColumnRefs(arg));
60
+ }
61
+ return refs;
62
+ }
63
+ return [];
64
+ }
65
+
66
+ /**
67
+ * Type predicate to check if an expression is an OperationExpr.
68
+ */
69
+ export function isOperationExpr(expr: AnyColumnBuilder | OperationExpr): expr is OperationExpr {
70
+ return typeof expr === 'object' && expr !== null && 'kind' in expr && expr.kind === 'operation';
71
+ }
72
+
73
+ /**
74
+ * Helper to extract table and column from a ColumnBuilder or OperationExpr.
75
+ * For OperationExpr, recursively unwraps to find the base ColumnRef.
76
+ */
77
+ export function getColumnInfo(expr: AnyColumnBuilder | OperationExpr): {
78
+ table: string;
79
+ column: string;
80
+ } {
81
+ if (isOperationExpr(expr)) {
82
+ const baseCol = extractBaseColumnRef(expr);
83
+ return { table: baseCol.table, column: baseCol.column };
84
+ }
85
+ // expr is ColumnBuilder - TypeScript can't narrow properly
86
+ const colBuilder = expr as unknown as { table: string; column: string };
87
+ return { table: colBuilder.table, column: colBuilder.column };
88
+ }
89
+
90
+ /**
91
+ * Type predicate to check if a value is a ColumnBuilder.
92
+ */
93
+ export function isColumnBuilder(value: unknown): value is AnyColumnBuilder {
94
+ return (
95
+ typeof value === 'object' &&
96
+ value !== null &&
97
+ 'kind' in value &&
98
+ (value as { kind: unknown }).kind === 'column'
99
+ );
100
+ }
101
+
102
+ /**
103
+ * Extracts and returns an OperationExpr from a builder.
104
+ * Returns the OperationExpr if the builder is an OperationExpr or has an _operationExpr property,
105
+ * otherwise returns undefined.
106
+ *
107
+ * @design-note: This function accesses the hidden `_operationExpr` property, which is a code smell.
108
+ * The issue is that `executeOperation()` in relational-core returns a ColumnBuilder-shaped object
109
+ * with a hidden `_operationExpr` property, creating coupling between lanes and relational-core
110
+ * implementation details. A cleaner design would be to have operation results be a separate
111
+ * type (e.g., `OperationResultBuilder`) that properly represents expression nodes rather than
112
+ * pretending to be a ColumnBuilder. This would require refactoring the operation execution
113
+ * system in relational-core to return proper expression types.
114
+ */
115
+ export function getOperationExpr(
116
+ builder: AnyColumnBuilder | OperationExpr,
117
+ ): OperationExpr | undefined {
118
+ if (isOperationExpr(builder)) {
119
+ return builder;
120
+ }
121
+ const builderWithExpr = builder as unknown as { _operationExpr?: OperationExpr };
122
+ return builderWithExpr._operationExpr;
123
+ }