@prisma-next/sql-relational-core 0.3.0-dev.5 → 0.3.0-dev.50

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 (173) hide show
  1. package/README.md +18 -2
  2. package/dist/errors-7_V3El9I.mjs +3 -0
  3. package/dist/errors-DVufq9PT.d.mts +2 -0
  4. package/dist/exports/ast.d.mts +192 -0
  5. package/dist/exports/ast.d.mts.map +1 -0
  6. package/dist/exports/ast.mjs +361 -0
  7. package/dist/exports/ast.mjs.map +1 -0
  8. package/dist/exports/errors.d.mts +2 -0
  9. package/dist/exports/errors.mjs +3 -0
  10. package/dist/exports/guards.d.mts +5 -0
  11. package/dist/exports/guards.mjs +3 -0
  12. package/dist/exports/operations-registry.d.mts +5 -0
  13. package/dist/exports/operations-registry.mjs +3 -0
  14. package/dist/exports/param.d.mts +5 -0
  15. package/dist/exports/param.mjs +3 -0
  16. package/dist/exports/plan.d.mts +2 -0
  17. package/dist/exports/plan.mjs +17 -0
  18. package/dist/exports/plan.mjs.map +1 -0
  19. package/dist/exports/query-lane-context.d.mts +2 -0
  20. package/dist/exports/query-lane-context.mjs +1 -0
  21. package/dist/exports/schema.d.mts +5 -0
  22. package/dist/exports/schema.mjs +4 -0
  23. package/dist/exports/types.d.mts +4 -0
  24. package/dist/exports/types.mjs +3 -0
  25. package/dist/exports/utils/guards.d.mts +5 -0
  26. package/dist/exports/utils/guards.mjs +4 -0
  27. package/dist/guards-0ycyntYX.mjs +132 -0
  28. package/dist/guards-0ycyntYX.mjs.map +1 -0
  29. package/dist/guards-DCCpAlOL.d.mts +87 -0
  30. package/dist/guards-DCCpAlOL.d.mts.map +1 -0
  31. package/dist/index.d.mts +12 -0
  32. package/dist/index.mjs +12 -0
  33. package/dist/operations-registry-DPZ5aElH.mjs +152 -0
  34. package/dist/operations-registry-DPZ5aElH.mjs.map +1 -0
  35. package/dist/operations-registry-wVEaiLyt.d.mts +9 -0
  36. package/dist/operations-registry-wVEaiLyt.d.mts.map +1 -0
  37. package/dist/param-C4n0OW59.d.mts +8 -0
  38. package/dist/param-C4n0OW59.d.mts.map +1 -0
  39. package/dist/param-DMU3OWfI.mjs +14 -0
  40. package/dist/param-DMU3OWfI.mjs.map +1 -0
  41. package/dist/plan-BhSWuTfw.d.mts +194 -0
  42. package/dist/plan-BhSWuTfw.d.mts.map +1 -0
  43. package/dist/query-lane-context-CgkPuKaR.d.mts +259 -0
  44. package/dist/query-lane-context-CgkPuKaR.d.mts.map +1 -0
  45. package/dist/schema-Bi5p4aAc.mjs +175 -0
  46. package/dist/schema-Bi5p4aAc.mjs.map +1 -0
  47. package/dist/schema-CgrEMqEd.d.mts +86 -0
  48. package/dist/schema-CgrEMqEd.d.mts.map +1 -0
  49. package/dist/types-CEUzDuDC.d.mts +447 -0
  50. package/dist/types-CEUzDuDC.d.mts.map +1 -0
  51. package/dist/types-Cdi4Whda.mjs +18 -0
  52. package/dist/types-Cdi4Whda.mjs.map +1 -0
  53. package/package.json +39 -56
  54. package/src/ast/codec-types.ts +77 -8
  55. package/src/ast/delete.ts +2 -2
  56. package/src/ast/driver-types.ts +20 -3
  57. package/src/ast/predicate.ts +14 -4
  58. package/src/ast/select.ts +4 -3
  59. package/src/ast/sql-codecs.ts +67 -0
  60. package/src/ast/types.ts +89 -19
  61. package/src/ast/update.ts +2 -2
  62. package/src/exports/ast.ts +1 -0
  63. package/src/exports/guards.ts +5 -0
  64. package/src/exports/utils/guards.ts +1 -0
  65. package/src/operations-registry.ts +112 -73
  66. package/src/query-lane-context.ts +77 -1
  67. package/src/schema.ts +91 -33
  68. package/src/types.ts +327 -75
  69. package/src/utils/guards.ts +88 -18
  70. package/dist/ast/adapter-types.d.ts +0 -28
  71. package/dist/ast/adapter-types.d.ts.map +0 -1
  72. package/dist/ast/codec-types.d.ts +0 -141
  73. package/dist/ast/codec-types.d.ts.map +0 -1
  74. package/dist/ast/common.d.ts +0 -7
  75. package/dist/ast/common.d.ts.map +0 -1
  76. package/dist/ast/delete.d.ts +0 -8
  77. package/dist/ast/delete.d.ts.map +0 -1
  78. package/dist/ast/driver-types.d.ts +0 -20
  79. package/dist/ast/driver-types.d.ts.map +0 -1
  80. package/dist/ast/insert.d.ts +0 -8
  81. package/dist/ast/insert.d.ts.map +0 -1
  82. package/dist/ast/join.d.ts +0 -6
  83. package/dist/ast/join.d.ts.map +0 -1
  84. package/dist/ast/order.d.ts +0 -6
  85. package/dist/ast/order.d.ts.map +0 -1
  86. package/dist/ast/predicate.d.ts +0 -4
  87. package/dist/ast/predicate.d.ts.map +0 -1
  88. package/dist/ast/select.d.ts +0 -18
  89. package/dist/ast/select.d.ts.map +0 -1
  90. package/dist/ast/types.d.ts +0 -118
  91. package/dist/ast/types.d.ts.map +0 -1
  92. package/dist/ast/update.d.ts +0 -9
  93. package/dist/ast/update.d.ts.map +0 -1
  94. package/dist/ast/util.d.ts +0 -2
  95. package/dist/ast/util.d.ts.map +0 -1
  96. package/dist/chunk-2F7DSEOU.js +0 -8
  97. package/dist/chunk-2F7DSEOU.js.map +0 -1
  98. package/dist/chunk-36WJWNHT.js +0 -1
  99. package/dist/chunk-36WJWNHT.js.map +0 -1
  100. package/dist/chunk-5N34PNVZ.js +0 -62
  101. package/dist/chunk-5N34PNVZ.js.map +0 -1
  102. package/dist/chunk-7I3EMQID.js +0 -16
  103. package/dist/chunk-7I3EMQID.js.map +0 -1
  104. package/dist/chunk-CBTYMOX2.js +0 -152
  105. package/dist/chunk-CBTYMOX2.js.map +0 -1
  106. package/dist/chunk-G52ENULI.js +0 -1
  107. package/dist/chunk-G52ENULI.js.map +0 -1
  108. package/dist/chunk-KYSP7L5C.js +0 -16
  109. package/dist/chunk-KYSP7L5C.js.map +0 -1
  110. package/dist/chunk-M23L3JHG.js +0 -159
  111. package/dist/chunk-M23L3JHG.js.map +0 -1
  112. package/dist/chunk-MM74SVJ4.js +0 -13
  113. package/dist/chunk-MM74SVJ4.js.map +0 -1
  114. package/dist/chunk-U7AXAUJA.js +0 -1
  115. package/dist/chunk-U7AXAUJA.js.map +0 -1
  116. package/dist/chunk-WZBPVEZI.js +0 -320
  117. package/dist/chunk-WZBPVEZI.js.map +0 -1
  118. package/dist/errors.d.ts +0 -2
  119. package/dist/errors.d.ts.map +0 -1
  120. package/dist/exports/ast.d.ts +0 -14
  121. package/dist/exports/ast.d.ts.map +0 -1
  122. package/dist/exports/ast.js +0 -46
  123. package/dist/exports/ast.js.map +0 -1
  124. package/dist/exports/errors.d.ts +0 -2
  125. package/dist/exports/errors.d.ts.map +0 -1
  126. package/dist/exports/errors.js +0 -9
  127. package/dist/exports/errors.js.map +0 -1
  128. package/dist/exports/guards.d.ts +0 -2
  129. package/dist/exports/guards.d.ts.map +0 -1
  130. package/dist/exports/guards.js +0 -21
  131. package/dist/exports/guards.js.map +0 -1
  132. package/dist/exports/operations-registry.d.ts +0 -2
  133. package/dist/exports/operations-registry.d.ts.map +0 -1
  134. package/dist/exports/operations-registry.js +0 -9
  135. package/dist/exports/operations-registry.js.map +0 -1
  136. package/dist/exports/param.d.ts +0 -3
  137. package/dist/exports/param.d.ts.map +0 -1
  138. package/dist/exports/param.js +0 -7
  139. package/dist/exports/param.js.map +0 -1
  140. package/dist/exports/plan.d.ts +0 -2
  141. package/dist/exports/plan.d.ts.map +0 -1
  142. package/dist/exports/plan.js +0 -7
  143. package/dist/exports/plan.js.map +0 -1
  144. package/dist/exports/query-lane-context.d.ts +0 -2
  145. package/dist/exports/query-lane-context.d.ts.map +0 -1
  146. package/dist/exports/query-lane-context.js +0 -2
  147. package/dist/exports/query-lane-context.js.map +0 -1
  148. package/dist/exports/schema.d.ts +0 -3
  149. package/dist/exports/schema.d.ts.map +0 -1
  150. package/dist/exports/schema.js +0 -14
  151. package/dist/exports/schema.js.map +0 -1
  152. package/dist/exports/types.d.ts +0 -2
  153. package/dist/exports/types.d.ts.map +0 -1
  154. package/dist/exports/types.js +0 -10
  155. package/dist/exports/types.js.map +0 -1
  156. package/dist/index.d.ts +0 -9
  157. package/dist/index.d.ts.map +0 -1
  158. package/dist/index.js +0 -81
  159. package/dist/index.js.map +0 -1
  160. package/dist/operations-registry.d.ts +0 -5
  161. package/dist/operations-registry.d.ts.map +0 -1
  162. package/dist/param.d.ts +0 -4
  163. package/dist/param.d.ts.map +0 -1
  164. package/dist/plan.d.ts +0 -23
  165. package/dist/plan.d.ts.map +0 -1
  166. package/dist/query-lane-context.d.ts +0 -16
  167. package/dist/query-lane-context.d.ts.map +0 -1
  168. package/dist/schema.d.ts +0 -63
  169. package/dist/schema.d.ts.map +0 -1
  170. package/dist/types.d.ts +0 -332
  171. package/dist/types.d.ts.map +0 -1
  172. package/dist/utils/guards.d.ts +0 -55
  173. package/dist/utils/guards.d.ts.map +0 -1
package/package.json CHANGED
@@ -1,79 +1,62 @@
1
1
  {
2
2
  "name": "@prisma-next/sql-relational-core",
3
- "version": "0.3.0-dev.5",
3
+ "version": "0.3.0-dev.50",
4
4
  "type": "module",
5
5
  "sideEffects": false,
6
6
  "description": "Schema and column builders, operation attachment, and AST types for Prisma Next",
7
7
  "dependencies": {
8
+ "arktype": "^2.1.29",
8
9
  "ts-toolbelt": "^9.6.0",
9
- "@prisma-next/contract": "0.3.0-dev.5",
10
- "@prisma-next/operations": "0.3.0-dev.5",
11
- "@prisma-next/plan": "0.3.0-dev.5",
12
- "@prisma-next/sql-contract": "0.3.0-dev.5",
13
- "@prisma-next/sql-operations": "0.3.0-dev.5"
10
+ "@prisma-next/contract": "0.3.0-dev.50",
11
+ "@prisma-next/operations": "0.3.0-dev.50",
12
+ "@prisma-next/sql-contract": "0.3.0-dev.50",
13
+ "@prisma-next/plan": "0.3.0-dev.50",
14
+ "@prisma-next/sql-operations": "0.3.0-dev.50",
15
+ "@prisma-next/utils": "0.3.0-dev.50"
14
16
  },
15
17
  "devDependencies": {
16
- "@vitest/coverage-v8": "4.0.16",
17
- "tsup": "8.5.1",
18
+ "tsdown": "0.18.4",
18
19
  "typescript": "5.9.3",
19
- "vitest": "4.0.16",
20
- "@prisma-next/sql-contract-ts": "0.3.0-dev.5",
21
- "@prisma-next/test-utils": "0.0.1"
20
+ "vitest": "4.0.17",
21
+ "@prisma-next/sql-contract-ts": "0.3.0-dev.50",
22
+ "@prisma-next/test-utils": "0.0.1",
23
+ "@prisma-next/tsconfig": "0.0.0",
24
+ "@prisma-next/tsdown": "0.0.0"
22
25
  },
23
26
  "files": [
24
27
  "dist",
25
28
  "src"
26
29
  ],
27
30
  "exports": {
28
- ".": {
29
- "types": "./dist/index.d.ts",
30
- "import": "./dist/index.js"
31
- },
32
- "./schema": {
33
- "types": "./dist/exports/schema.d.ts",
34
- "import": "./dist/exports/schema.js"
35
- },
36
- "./param": {
37
- "types": "./dist/exports/param.d.ts",
38
- "import": "./dist/exports/param.js"
39
- },
40
- "./types": {
41
- "types": "./dist/exports/types.d.ts",
42
- "import": "./dist/exports/types.js"
43
- },
44
- "./operations-registry": {
45
- "types": "./dist/exports/operations-registry.d.ts",
46
- "import": "./dist/exports/operations-registry.js"
47
- },
48
- "./errors": {
49
- "types": "./dist/exports/errors.d.ts",
50
- "import": "./dist/exports/errors.js"
51
- },
52
- "./ast": {
53
- "types": "./dist/exports/ast.d.ts",
54
- "import": "./dist/exports/ast.js"
55
- },
56
- "./plan": {
57
- "types": "./dist/exports/plan.d.ts",
58
- "import": "./dist/exports/plan.js"
59
- },
60
- "./query-lane-context": {
61
- "types": "./dist/exports/query-lane-context.d.ts",
62
- "import": "./dist/exports/query-lane-context.js"
63
- },
64
- "./utils/guards": {
65
- "types": "./dist/exports/guards.d.ts",
66
- "import": "./dist/exports/guards.js"
67
- }
31
+ ".": "./dist/index.mjs",
32
+ "./ast": "./dist/exports/ast.mjs",
33
+ "./errors": "./dist/exports/errors.mjs",
34
+ "./guards": "./dist/exports/guards.mjs",
35
+ "./operations-registry": "./dist/exports/operations-registry.mjs",
36
+ "./param": "./dist/exports/param.mjs",
37
+ "./plan": "./dist/exports/plan.mjs",
38
+ "./query-lane-context": "./dist/exports/query-lane-context.mjs",
39
+ "./schema": "./dist/exports/schema.mjs",
40
+ "./types": "./dist/exports/types.mjs",
41
+ "./utils/guards": "./dist/exports/utils/guards.mjs",
42
+ "./package.json": "./package.json"
43
+ },
44
+ "main": "./dist/index.mjs",
45
+ "module": "./dist/index.mjs",
46
+ "types": "./dist/index.d.mts",
47
+ "repository": {
48
+ "type": "git",
49
+ "url": "https://github.com/prisma/prisma-next.git",
50
+ "directory": "packages/2-sql/4-lanes/relational-core"
68
51
  },
69
52
  "scripts": {
70
- "build": "tsup --config tsup.config.ts && tsc --project tsconfig.build.json",
53
+ "build": "tsdown",
71
54
  "test": "vitest run",
72
55
  "test:coverage": "vitest run --coverage",
73
56
  "typecheck": "tsc --project tsconfig.json --noEmit",
74
- "lint": "biome check . --config-path ../../../../biome.json --error-on-warnings",
75
- "lint:fix": "biome check --write . --config-path ../../../../biome.json",
76
- "lint:fix:unsafe": "biome check --write --unsafe . --config-path ../../../../biome.json",
77
- "clean": "node ../../../../scripts/clean.mjs"
57
+ "lint": "biome check . --error-on-warnings",
58
+ "lint:fix": "biome check --write .",
59
+ "lint:fix:unsafe": "biome check --write --unsafe .",
60
+ "clean": "rm -rf dist dist-tsc dist-tsc-prod coverage .tmp-output"
78
61
  }
79
62
  }
@@ -1,5 +1,32 @@
1
+ import { ifDefined } from '@prisma-next/utils/defined';
2
+ import type { Type } from 'arktype';
1
3
  import type { O } from 'ts-toolbelt';
2
4
 
5
+ /**
6
+ * Descriptor for parameterized codecs that require type parameter validation.
7
+ * Shared between adapter (compile-time) and runtime layers to avoid duplication.
8
+ *
9
+ * @template TParams - The shape of the type parameters (e.g., `{ length: number }`)
10
+ * @template THelper - The type returned by the optional `init` hook
11
+ */
12
+ export interface CodecParamsDescriptor<TParams = Record<string, unknown>, THelper = unknown> {
13
+ /** The codec ID this descriptor applies to (e.g., 'pg/vector@1') */
14
+ readonly codecId: string;
15
+
16
+ /**
17
+ * Arktype schema for validating typeParams.
18
+ * Used to validate both storage.types entries and inline column typeParams.
19
+ */
20
+ readonly paramsSchema: Type<TParams>;
21
+
22
+ /**
23
+ * Optional init hook called during runtime context creation.
24
+ * Receives validated params and returns a helper object to be stored in context.types.
25
+ * If not provided, the validated params are stored directly.
26
+ */
27
+ readonly init?: (params: TParams) => THelper;
28
+ }
29
+
3
30
  /**
4
31
  * Codec metadata for database-specific type information.
5
32
  * Used for schema introspection and verification.
@@ -20,7 +47,13 @@ export interface CodecMeta {
20
47
  * Codecs are pure, synchronous functions with no side effects or IO.
21
48
  * They provide deterministic conversion between database wire types and JS values.
22
49
  */
23
- export interface Codec<Id extends string = string, TWire = unknown, TJs = unknown> {
50
+ export interface Codec<
51
+ Id extends string = string,
52
+ TWire = unknown,
53
+ TJs = unknown,
54
+ TParams = Record<string, unknown>,
55
+ THelper = unknown,
56
+ > {
24
57
  /**
25
58
  * Namespaced codec identifier in format 'namespace/name@version'
26
59
  * Examples: 'pg/text@1', 'pg/uuid@1', 'pg/timestamptz@1'
@@ -39,6 +72,31 @@ export interface Codec<Id extends string = string, TWire = unknown, TJs = unknow
39
72
  */
40
73
  readonly meta?: CodecMeta;
41
74
 
75
+ /**
76
+ * Optional params schema for parameterized codecs.
77
+ * If provided, typeParams are validated against this schema.
78
+ */
79
+ readonly paramsSchema?: Type<TParams>;
80
+
81
+ /**
82
+ * Optional init hook for building runtime helper state from validated params.
83
+ *
84
+ * Useful when parameterized types need derived data at runtime, for example:
85
+ * - normalize typeParams into a stable helper shape consumed by lanes/adapters
86
+ * - precompute reusable values once during context creation
87
+ * - avoid repeating typeParams parsing logic during query execution
88
+ *
89
+ * Example:
90
+ * { length: 255 } -> { kind: 'variable', maxLength: 255 }
91
+ *
92
+ * **Convention for JSON/JSONB codecs**: When the helper includes a `validate`
93
+ * property of type `JsonSchemaValidateFn`, the runtime will use it to enforce
94
+ * JSON Schema conformance during encoding and decoding. The property is
95
+ * discovered via duck typing (`helper?.validate`) for flexibility across
96
+ * different codec types.
97
+ */
98
+ readonly init?: (params: TParams) => THelper;
99
+
42
100
  /**
43
101
  * Decode a wire value (from database) to JavaScript type.
44
102
  * Must be synchronous and pure (no side effects).
@@ -157,17 +215,27 @@ class CodecRegistryImpl implements CodecRegistry {
157
215
  /**
158
216
  * Codec factory - creates a codec with typeId and encode/decode functions.
159
217
  */
160
- export function codec<Id extends string, TWire, TJs>(config: {
218
+ export function codec<
219
+ Id extends string,
220
+ TWire,
221
+ TJs,
222
+ TParams = Record<string, unknown>,
223
+ THelper = unknown,
224
+ >(config: {
161
225
  typeId: Id;
162
226
  targetTypes: readonly string[];
163
227
  encode: (value: TJs) => TWire;
164
228
  decode: (wire: TWire) => TJs;
165
229
  meta?: CodecMeta;
166
- }): Codec<Id, TWire, TJs> {
230
+ paramsSchema?: Type<TParams>;
231
+ init?: (params: TParams) => THelper;
232
+ }): Codec<Id, TWire, TJs, TParams, THelper> {
167
233
  return {
168
234
  id: config.typeId,
169
235
  targetTypes: config.targetTypes,
170
- ...(config.meta ? { meta: config.meta } : {}),
236
+ ...ifDefined('meta', config.meta),
237
+ ...ifDefined('paramsSchema', config.paramsSchema),
238
+ ...ifDefined('init', config.init),
171
239
  encode: config.encode,
172
240
  decode: config.decode,
173
241
  };
@@ -176,11 +244,12 @@ export function codec<Id extends string, TWire, TJs>(config: {
176
244
  /**
177
245
  * Type helpers to extract codec types.
178
246
  */
179
- export type CodecId<T> = T extends Codec<infer Id, unknown, unknown>
180
- ? Id
181
- : T extends { readonly id: infer Id }
247
+ export type CodecId<T> =
248
+ T extends Codec<infer Id, unknown, unknown>
182
249
  ? Id
183
- : never;
250
+ : T extends { readonly id: infer Id }
251
+ ? Id
252
+ : never;
184
253
  export type CodecInput<T> = T extends Codec<string, unknown, infer JsT> ? JsT : never;
185
254
  export type CodecOutput<T> = T extends Codec<string, unknown, infer JsT> ? JsT : never;
186
255
 
package/src/ast/delete.ts CHANGED
@@ -1,9 +1,9 @@
1
- import type { BinaryExpr, ColumnRef, DeleteAst, TableRef } from './types';
1
+ import type { ColumnRef, DeleteAst, TableRef, WhereExpr } from './types';
2
2
  import { compact } from './util';
3
3
 
4
4
  export interface CreateDeleteAstOptions {
5
5
  readonly table: TableRef;
6
- readonly where: BinaryExpr;
6
+ readonly where: WhereExpr;
7
7
  readonly returning?: ReadonlyArray<ColumnRef>;
8
8
  }
9
9
 
@@ -13,13 +13,30 @@ export interface SqlExplainResult<Row = Record<string, unknown>> {
13
13
  readonly rows: ReadonlyArray<Row>;
14
14
  }
15
15
 
16
- export interface SqlDriver {
17
- connect(): Promise<void>;
16
+ export type SqlDriverState = 'unbound' | 'connected' | 'closed';
17
+
18
+ export interface SqlDriver<TBinding = void> extends SqlQueryable {
19
+ readonly state?: SqlDriverState;
20
+ connect(binding: TBinding): Promise<void>;
21
+ acquireConnection(): Promise<SqlConnection>;
22
+ close(): Promise<void>;
23
+ }
24
+
25
+ export interface SqlConnection extends SqlQueryable {
26
+ beginTransaction(): Promise<SqlTransaction>;
27
+ release(): Promise<void>;
28
+ }
29
+
30
+ export interface SqlTransaction extends SqlQueryable {
31
+ commit(): Promise<void>;
32
+ rollback(): Promise<void>;
33
+ }
34
+
35
+ export interface SqlQueryable {
18
36
  execute<Row = Record<string, unknown>>(request: SqlExecuteRequest): AsyncIterable<Row>;
19
37
  explain?(request: SqlExecuteRequest): Promise<SqlExplainResult>;
20
38
  query<Row = Record<string, unknown>>(
21
39
  sql: string,
22
40
  params?: readonly unknown[],
23
41
  ): Promise<SqlQueryResult<Row>>;
24
- close(): Promise<void>;
25
42
  }
@@ -1,17 +1,19 @@
1
1
  import type {
2
2
  BinaryExpr,
3
3
  BinaryOp,
4
- ColumnRef,
5
4
  ExistsExpr,
6
- OperationExpr,
5
+ Expression,
6
+ ListLiteralExpr,
7
+ LiteralExpr,
8
+ NullCheckExpr,
7
9
  ParamRef,
8
10
  SelectAst,
9
11
  } from './types';
10
12
 
11
13
  export function createBinaryExpr(
12
14
  op: BinaryOp,
13
- left: ColumnRef | OperationExpr,
14
- right: ColumnRef | ParamRef,
15
+ left: Expression,
16
+ right: Expression | ParamRef | LiteralExpr | ListLiteralExpr,
15
17
  ): BinaryExpr {
16
18
  return {
17
19
  kind: 'bin',
@@ -28,3 +30,11 @@ export function createExistsExpr(not: boolean, subquery: SelectAst): ExistsExpr
28
30
  subquery,
29
31
  };
30
32
  }
33
+
34
+ export function createNullCheckExpr(expr: Expression, isNull: boolean): NullCheckExpr {
35
+ return {
36
+ kind: 'nullCheck',
37
+ expr,
38
+ isNull,
39
+ };
40
+ }
package/src/ast/select.ts CHANGED
@@ -1,14 +1,13 @@
1
1
  import type {
2
- BinaryExpr,
3
2
  ColumnRef,
4
3
  Direction,
5
- ExistsExpr,
6
4
  IncludeAst,
7
5
  IncludeRef,
8
6
  JoinAst,
9
7
  OperationExpr,
10
8
  SelectAst,
11
9
  TableRef,
10
+ WhereExpr,
12
11
  } from './types';
13
12
  import { compact } from './util';
14
13
 
@@ -20,9 +19,10 @@ export interface CreateSelectAstOptions {
20
19
  alias: string;
21
20
  expr: ColumnRef | IncludeRef | OperationExpr;
22
21
  }>;
23
- readonly where?: BinaryExpr | ExistsExpr;
22
+ readonly where?: WhereExpr;
24
23
  readonly orderBy?: ReadonlyArray<{ expr: ColumnRef | OperationExpr; dir: Direction }>;
25
24
  readonly limit?: number;
25
+ readonly selectAllIntent?: { table?: string };
26
26
  }
27
27
 
28
28
  export function createSelectAst(options: CreateSelectAstOptions): SelectAst {
@@ -35,5 +35,6 @@ export function createSelectAst(options: CreateSelectAstOptions): SelectAst {
35
35
  where: options.where,
36
36
  orderBy: options.orderBy,
37
37
  limit: options.limit,
38
+ selectAllIntent: options.selectAllIntent,
38
39
  }) as SelectAst;
39
40
  }
@@ -0,0 +1,67 @@
1
+ import { type as arktype } from 'arktype';
2
+ import { codec, defineCodecs } from './codec-types';
3
+
4
+ export const SQL_CHAR_CODEC_ID = 'sql/char@1' as const;
5
+ export const SQL_VARCHAR_CODEC_ID = 'sql/varchar@1' as const;
6
+ export const SQL_INT_CODEC_ID = 'sql/int@1' as const;
7
+ export const SQL_FLOAT_CODEC_ID = 'sql/float@1' as const;
8
+
9
+ const lengthParamsSchema = arktype({
10
+ length: 'number.integer > 0',
11
+ });
12
+
13
+ type LengthTypeHelper = {
14
+ readonly kind: 'fixed' | 'variable';
15
+ readonly maxLength: number;
16
+ };
17
+
18
+ function createLengthTypeHelper(
19
+ kind: LengthTypeHelper['kind'],
20
+ ): (params: Record<string, unknown>) => LengthTypeHelper {
21
+ return (params) => ({
22
+ kind,
23
+ maxLength: params['length'] as number,
24
+ });
25
+ }
26
+
27
+ const sqlCharCodec = codec<typeof SQL_CHAR_CODEC_ID, string, string>({
28
+ typeId: SQL_CHAR_CODEC_ID,
29
+ targetTypes: ['char'],
30
+ encode: (value: string): string => value,
31
+ decode: (wire: string): string => wire.trimEnd(),
32
+ paramsSchema: lengthParamsSchema,
33
+ init: createLengthTypeHelper('fixed'),
34
+ });
35
+
36
+ const sqlVarcharCodec = codec<typeof SQL_VARCHAR_CODEC_ID, string, string>({
37
+ typeId: SQL_VARCHAR_CODEC_ID,
38
+ targetTypes: ['varchar'],
39
+ encode: (value: string): string => value,
40
+ decode: (wire: string): string => wire,
41
+ paramsSchema: lengthParamsSchema,
42
+ init: createLengthTypeHelper('variable'),
43
+ });
44
+
45
+ const sqlIntCodec = codec<typeof SQL_INT_CODEC_ID, number, number>({
46
+ typeId: SQL_INT_CODEC_ID,
47
+ targetTypes: ['int'],
48
+ encode: (value) => value,
49
+ decode: (wire) => wire,
50
+ });
51
+
52
+ const sqlFloatCodec = codec<typeof SQL_FLOAT_CODEC_ID, number, number>({
53
+ typeId: SQL_FLOAT_CODEC_ID,
54
+ targetTypes: ['float'],
55
+ encode: (value) => value,
56
+ decode: (wire) => wire,
57
+ });
58
+
59
+ const codecs = defineCodecs()
60
+ .add('char', sqlCharCodec)
61
+ .add('varchar', sqlVarcharCodec)
62
+ .add('int', sqlIntCodec)
63
+ .add('float', sqlFloatCodec);
64
+
65
+ export const sqlCodecDefinitions = codecs.codecDefinitions;
66
+ export const sqlDataTypes = codecs.dataTypes;
67
+ export type SqlCodecTypes = typeof codecs.CodecTypes;
package/src/ast/types.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import type { ParamDescriptor } from '@prisma-next/contract/types';
1
2
  import type { ReturnSpec } from '@prisma-next/operations';
2
3
  import type { SqlLoweringSpec } from '@prisma-next/sql-operations';
3
4
 
@@ -32,23 +33,62 @@ export interface OperationExpr {
32
33
  readonly kind: 'operation';
33
34
  readonly method: string;
34
35
  readonly forTypeId: string;
35
- readonly self: ColumnRef | OperationExpr;
36
- readonly args: ReadonlyArray<ColumnRef | ParamRef | LiteralExpr | OperationExpr>;
36
+ readonly self: Expression;
37
+ readonly args: ReadonlyArray<Expression | ParamRef | LiteralExpr>;
37
38
  readonly returns: ReturnSpec;
38
39
  readonly lowering: SqlLoweringSpec;
39
40
  }
40
41
 
41
- export function isOperationExpr(expr: ColumnRef | OperationExpr): expr is OperationExpr {
42
+ /**
43
+ * Unified expression type - the canonical AST representation for column references
44
+ * and operation expressions. This is what all builders convert to via toExpr().
45
+ */
46
+ export type Expression = ColumnRef | OperationExpr;
47
+
48
+ /**
49
+ * Interface for any builder that can produce an Expression.
50
+ * Implemented by ColumnBuilder and ExpressionBuilder.
51
+ */
52
+ export interface ExpressionSource {
53
+ toExpr(): Expression;
54
+ }
55
+
56
+ export function isOperationExpr(expr: Expression): expr is OperationExpr {
42
57
  return expr.kind === 'operation';
43
58
  }
44
59
 
45
- export type BinaryOp = 'eq' | 'neq' | 'gt' | 'lt' | 'gte' | 'lte';
60
+ export type BinaryOp =
61
+ | 'eq'
62
+ | 'neq'
63
+ | 'gt'
64
+ | 'lt'
65
+ | 'gte'
66
+ | 'lte'
67
+ | 'like'
68
+ | 'ilike'
69
+ | 'in'
70
+ | 'notIn';
46
71
 
47
72
  export interface BinaryExpr {
48
73
  readonly kind: 'bin';
49
74
  readonly op: BinaryOp;
50
- readonly left: ColumnRef | OperationExpr;
51
- readonly right: ColumnRef | ParamRef;
75
+ readonly left: Expression;
76
+ readonly right: Expression | ParamRef | LiteralExpr | ListLiteralExpr;
77
+ }
78
+
79
+ export interface ListLiteralExpr {
80
+ readonly kind: 'listLiteral';
81
+ readonly values: ReadonlyArray<ParamRef | LiteralExpr>;
82
+ }
83
+
84
+ export interface AndExpr {
85
+ readonly kind: 'and';
86
+ readonly exprs: ReadonlyArray<WhereExpr>;
87
+ }
88
+
89
+ export interface OrExpr {
90
+ readonly kind: 'or';
91
+ readonly exprs: ReadonlyArray<WhereExpr>;
52
92
  }
53
93
 
54
94
  export interface ExistsExpr {
@@ -57,11 +97,40 @@ export interface ExistsExpr {
57
97
  readonly subquery: SelectAst;
58
98
  }
59
99
 
60
- export type JoinOnExpr = {
61
- readonly kind: 'eqCol';
62
- readonly left: ColumnRef;
63
- readonly right: ColumnRef;
64
- };
100
+ /**
101
+ * Unary expression for IS NULL / IS NOT NULL checks.
102
+ * Used in WHERE clauses to check for null values.
103
+ */
104
+ export interface NullCheckExpr {
105
+ readonly kind: 'nullCheck';
106
+ readonly expr: Expression;
107
+ readonly isNull: boolean;
108
+ }
109
+
110
+ /**
111
+ * Union type for WHERE clause expressions.
112
+ */
113
+ export type WhereExpr = BinaryExpr | ExistsExpr | NullCheckExpr | AndExpr | OrExpr;
114
+
115
+ export interface BoundWhereExpr {
116
+ readonly expr: WhereExpr;
117
+ readonly params: readonly unknown[];
118
+ readonly paramDescriptors: ReadonlyArray<ParamDescriptor>;
119
+ }
120
+
121
+ export interface ToWhereExpr {
122
+ toWhereExpr(): BoundWhereExpr;
123
+ }
124
+
125
+ export type WhereArg = WhereExpr | ToWhereExpr;
126
+
127
+ export type JoinOnExpr =
128
+ | {
129
+ readonly kind: 'eqCol';
130
+ readonly left: ColumnRef;
131
+ readonly right: ColumnRef;
132
+ }
133
+ | WhereExpr;
65
134
 
66
135
  export interface JoinAst {
67
136
  readonly kind: 'join';
@@ -81,10 +150,10 @@ export interface IncludeAst {
81
150
  readonly child: {
82
151
  readonly table: TableRef;
83
152
  readonly on: JoinOnExpr;
84
- readonly where?: BinaryExpr | ExistsExpr;
85
- readonly orderBy?: ReadonlyArray<{ expr: ColumnRef | OperationExpr; dir: Direction }>;
153
+ readonly where?: WhereExpr;
154
+ readonly orderBy?: ReadonlyArray<{ expr: Expression; dir: Direction }>;
86
155
  readonly limit?: number;
87
- readonly project: ReadonlyArray<{ alias: string; expr: ColumnRef | OperationExpr }>;
156
+ readonly project: ReadonlyArray<{ alias: string; expr: Expression }>;
88
157
  };
89
158
  }
90
159
 
@@ -95,11 +164,12 @@ export interface SelectAst {
95
164
  readonly includes?: ReadonlyArray<IncludeAst>;
96
165
  readonly project: ReadonlyArray<{
97
166
  alias: string;
98
- expr: ColumnRef | IncludeRef | OperationExpr | LiteralExpr;
167
+ expr: Expression | IncludeRef | LiteralExpr;
99
168
  }>;
100
- readonly where?: BinaryExpr | ExistsExpr;
101
- readonly orderBy?: ReadonlyArray<{ expr: ColumnRef | OperationExpr; dir: Direction }>;
169
+ readonly where?: WhereExpr;
170
+ readonly orderBy?: ReadonlyArray<{ expr: Expression; dir: Direction }>;
102
171
  readonly limit?: number;
172
+ readonly selectAllIntent?: { table?: string };
103
173
  }
104
174
 
105
175
  export interface InsertAst {
@@ -113,14 +183,14 @@ export interface UpdateAst {
113
183
  readonly kind: 'update';
114
184
  readonly table: TableRef;
115
185
  readonly set: Record<string, ColumnRef | ParamRef>;
116
- readonly where: BinaryExpr;
186
+ readonly where?: WhereExpr;
117
187
  readonly returning?: ReadonlyArray<ColumnRef>;
118
188
  }
119
189
 
120
190
  export interface DeleteAst {
121
191
  readonly kind: 'delete';
122
192
  readonly table: TableRef;
123
- readonly where: BinaryExpr;
193
+ readonly where?: WhereExpr;
124
194
  readonly returning?: ReadonlyArray<ColumnRef>;
125
195
  }
126
196
 
package/src/ast/update.ts CHANGED
@@ -1,10 +1,10 @@
1
- import type { BinaryExpr, ColumnRef, ParamRef, TableRef, UpdateAst } from './types';
1
+ import type { ColumnRef, ParamRef, TableRef, UpdateAst, WhereExpr } from './types';
2
2
  import { compact } from './util';
3
3
 
4
4
  export interface CreateUpdateAstOptions {
5
5
  readonly table: TableRef;
6
6
  readonly set: Record<string, ColumnRef | ParamRef>;
7
- readonly where: BinaryExpr;
7
+ readonly where?: WhereExpr;
8
8
  readonly returning?: ReadonlyArray<ColumnRef>;
9
9
  }
10
10
 
@@ -8,6 +8,7 @@ export * from '../ast/join';
8
8
  export * from '../ast/order';
9
9
  export * from '../ast/predicate';
10
10
  export * from '../ast/select';
11
+ export * from '../ast/sql-codecs';
11
12
  export * from '../ast/types';
12
13
  export * from '../ast/update';
13
14
  export * from '../ast/util';
@@ -1,10 +1,15 @@
1
1
  export {
2
2
  collectColumnRefs,
3
+ expressionFromSource,
3
4
  extractBaseColumnRef,
4
5
  getColumnInfo,
5
6
  getColumnMeta,
6
7
  getOperationExpr,
7
8
  isColumnBuilder,
9
+ isExpressionBuilder,
10
+ isExpressionSource,
8
11
  isOperationExpr,
9
12
  isParamPlaceholder,
13
+ isValueSource,
14
+ toExpression,
10
15
  } from '../utils/guards';
@@ -0,0 +1 @@
1
+ export * from '../guards';