@prisma-next/sql-runtime 0.3.0-pr.99.6 → 0.4.0-dev.1

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 (171) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +141 -24
  3. package/dist/exports-BO6Fl7yn.mjs +889 -0
  4. package/dist/exports-BO6Fl7yn.mjs.map +1 -0
  5. package/dist/index-n6z6trta.d.mts +186 -0
  6. package/dist/index-n6z6trta.d.mts.map +1 -0
  7. package/dist/index.d.mts +2 -0
  8. package/dist/index.mjs +3 -0
  9. package/dist/test/utils.d.mts +77 -0
  10. package/dist/test/utils.d.mts.map +1 -0
  11. package/dist/test/utils.mjs +221 -0
  12. package/dist/test/utils.mjs.map +1 -0
  13. package/package.json +26 -20
  14. package/src/codecs/decoding.ts +84 -3
  15. package/src/codecs/encoding.ts +5 -15
  16. package/src/codecs/json-schema-validation.ts +61 -0
  17. package/src/codecs/validation.ts +7 -6
  18. package/src/exports/index.ts +20 -9
  19. package/src/lower-sql-plan.ts +9 -9
  20. package/src/middleware/budgets.ts +256 -0
  21. package/src/middleware/lints.ts +192 -0
  22. package/src/middleware/sql-middleware.ts +26 -0
  23. package/src/sql-context.ts +357 -257
  24. package/src/sql-family-adapter.ts +17 -23
  25. package/src/sql-marker.ts +2 -2
  26. package/src/sql-runtime.ts +136 -61
  27. package/test/async-iterable-result.test.ts +42 -37
  28. package/test/budgets.test.ts +431 -0
  29. package/test/context.types.test-d.ts +18 -20
  30. package/test/execution-stack.test.ts +164 -0
  31. package/test/json-schema-validation.test.ts +571 -0
  32. package/test/lints.test.ts +159 -0
  33. package/test/mutation-default-generators.test.ts +254 -0
  34. package/test/parameterized-types.test.ts +181 -205
  35. package/test/sql-context.test.ts +301 -134
  36. package/test/sql-family-adapter.test.ts +37 -20
  37. package/test/sql-runtime.test.ts +261 -49
  38. package/test/utils.ts +101 -67
  39. package/dist/accelerate-EEKAFGN3-P6A6XJWJ.js +0 -137863
  40. package/dist/accelerate-EEKAFGN3-P6A6XJWJ.js.map +0 -1
  41. package/dist/amcheck-24VY6X5V.js +0 -13
  42. package/dist/amcheck-24VY6X5V.js.map +0 -1
  43. package/dist/bloom-VS74NLHT.js +0 -13
  44. package/dist/bloom-VS74NLHT.js.map +0 -1
  45. package/dist/btree_gin-WBC4EAAI.js +0 -13
  46. package/dist/btree_gin-WBC4EAAI.js.map +0 -1
  47. package/dist/btree_gist-UNC6QD3M.js +0 -13
  48. package/dist/btree_gist-UNC6QD3M.js.map +0 -1
  49. package/dist/chunk-3KTOEDFX.js +0 -49
  50. package/dist/chunk-3KTOEDFX.js.map +0 -1
  51. package/dist/chunk-47DZBRQC.js +0 -1280
  52. package/dist/chunk-47DZBRQC.js.map +0 -1
  53. package/dist/chunk-52N6AFZM.js +0 -133
  54. package/dist/chunk-52N6AFZM.js.map +0 -1
  55. package/dist/chunk-7D4SUZUM.js +0 -38
  56. package/dist/chunk-7D4SUZUM.js.map +0 -1
  57. package/dist/chunk-APA6GHYY.js +0 -537
  58. package/dist/chunk-APA6GHYY.js.map +0 -1
  59. package/dist/chunk-ECWIHLAT.js +0 -37
  60. package/dist/chunk-ECWIHLAT.js.map +0 -1
  61. package/dist/chunk-EI626SDC.js +0 -105
  62. package/dist/chunk-EI626SDC.js.map +0 -1
  63. package/dist/chunk-UKKOYUGL.js +0 -578
  64. package/dist/chunk-UKKOYUGL.js.map +0 -1
  65. package/dist/chunk-XPLNMXQV.js +0 -1537
  66. package/dist/chunk-XPLNMXQV.js.map +0 -1
  67. package/dist/citext-T7MXGUY7.js +0 -13
  68. package/dist/citext-T7MXGUY7.js.map +0 -1
  69. package/dist/client-5FENX6AW.js +0 -299
  70. package/dist/client-5FENX6AW.js.map +0 -1
  71. package/dist/cube-TFDQBZCI.js +0 -13
  72. package/dist/cube-TFDQBZCI.js.map +0 -1
  73. package/dist/dict_int-AEUOPGWP.js +0 -13
  74. package/dist/dict_int-AEUOPGWP.js.map +0 -1
  75. package/dist/dict_xsyn-DAAYX3FL.js +0 -13
  76. package/dist/dict_xsyn-DAAYX3FL.js.map +0 -1
  77. package/dist/dist-AQ3LWXOX.js +0 -570
  78. package/dist/dist-AQ3LWXOX.js.map +0 -1
  79. package/dist/dist-LBVX6BJW.js +0 -189
  80. package/dist/dist-LBVX6BJW.js.map +0 -1
  81. package/dist/dist-WLKUVDN2.js +0 -5127
  82. package/dist/dist-WLKUVDN2.js.map +0 -1
  83. package/dist/earthdistance-KIGTF4LE.js +0 -13
  84. package/dist/earthdistance-KIGTF4LE.js.map +0 -1
  85. package/dist/file_fdw-5N55UP6I.js +0 -13
  86. package/dist/file_fdw-5N55UP6I.js.map +0 -1
  87. package/dist/fuzzystrmatch-KN3YWBFP.js +0 -13
  88. package/dist/fuzzystrmatch-KN3YWBFP.js.map +0 -1
  89. package/dist/hstore-YX726NKN.js +0 -13
  90. package/dist/hstore-YX726NKN.js.map +0 -1
  91. package/dist/http-exception-FZY2H4OF.js +0 -8
  92. package/dist/http-exception-FZY2H4OF.js.map +0 -1
  93. package/dist/index.js +0 -30
  94. package/dist/index.js.map +0 -1
  95. package/dist/intarray-NKVXNO2D.js +0 -13
  96. package/dist/intarray-NKVXNO2D.js.map +0 -1
  97. package/dist/isn-FTEMJGEV.js +0 -13
  98. package/dist/isn-FTEMJGEV.js.map +0 -1
  99. package/dist/lo-DB7L4NGI.js +0 -13
  100. package/dist/lo-DB7L4NGI.js.map +0 -1
  101. package/dist/logger-WQ7SHNDD.js +0 -68
  102. package/dist/logger-WQ7SHNDD.js.map +0 -1
  103. package/dist/ltree-Z32TZT6W.js +0 -13
  104. package/dist/ltree-Z32TZT6W.js.map +0 -1
  105. package/dist/nodefs-NM46ACH7.js +0 -31
  106. package/dist/nodefs-NM46ACH7.js.map +0 -1
  107. package/dist/opfs-ahp-NJO33LVZ.js +0 -332
  108. package/dist/opfs-ahp-NJO33LVZ.js.map +0 -1
  109. package/dist/pageinspect-YP3IZR4X.js +0 -13
  110. package/dist/pageinspect-YP3IZR4X.js.map +0 -1
  111. package/dist/pg_buffercache-7TD5J2FB.js +0 -13
  112. package/dist/pg_buffercache-7TD5J2FB.js.map +0 -1
  113. package/dist/pg_dump-SG4KYBUB.js +0 -2492
  114. package/dist/pg_dump-SG4KYBUB.js.map +0 -1
  115. package/dist/pg_freespacemap-DZDNCPZK.js +0 -13
  116. package/dist/pg_freespacemap-DZDNCPZK.js.map +0 -1
  117. package/dist/pg_surgery-J2MUEWEP.js +0 -13
  118. package/dist/pg_surgery-J2MUEWEP.js.map +0 -1
  119. package/dist/pg_trgm-7VNQOYS6.js +0 -13
  120. package/dist/pg_trgm-7VNQOYS6.js.map +0 -1
  121. package/dist/pg_visibility-TTSIPHFL.js +0 -13
  122. package/dist/pg_visibility-TTSIPHFL.js.map +0 -1
  123. package/dist/pg_walinspect-KPFHSHRJ.js +0 -13
  124. package/dist/pg_walinspect-KPFHSHRJ.js.map +0 -1
  125. package/dist/proxy-signals-GUDAMDHV.js +0 -39
  126. package/dist/proxy-signals-GUDAMDHV.js.map +0 -1
  127. package/dist/seg-IYVDLE4O.js +0 -13
  128. package/dist/seg-IYVDLE4O.js.map +0 -1
  129. package/dist/src/codecs/decoding.d.ts +0 -4
  130. package/dist/src/codecs/decoding.d.ts.map +0 -1
  131. package/dist/src/codecs/encoding.d.ts +0 -5
  132. package/dist/src/codecs/encoding.d.ts.map +0 -1
  133. package/dist/src/codecs/validation.d.ts +0 -6
  134. package/dist/src/codecs/validation.d.ts.map +0 -1
  135. package/dist/src/exports/index.d.ts +0 -11
  136. package/dist/src/exports/index.d.ts.map +0 -1
  137. package/dist/src/index.d.ts +0 -2
  138. package/dist/src/index.d.ts.map +0 -1
  139. package/dist/src/lower-sql-plan.d.ts +0 -15
  140. package/dist/src/lower-sql-plan.d.ts.map +0 -1
  141. package/dist/src/sql-context.d.ts +0 -130
  142. package/dist/src/sql-context.d.ts.map +0 -1
  143. package/dist/src/sql-family-adapter.d.ts +0 -10
  144. package/dist/src/sql-family-adapter.d.ts.map +0 -1
  145. package/dist/src/sql-marker.d.ts +0 -22
  146. package/dist/src/sql-marker.d.ts.map +0 -1
  147. package/dist/src/sql-runtime.d.ts +0 -25
  148. package/dist/src/sql-runtime.d.ts.map +0 -1
  149. package/dist/tablefunc-EF4RCS7S.js +0 -13
  150. package/dist/tablefunc-EF4RCS7S.js.map +0 -1
  151. package/dist/tcn-3VT5BQYW.js +0 -13
  152. package/dist/tcn-3VT5BQYW.js.map +0 -1
  153. package/dist/test/utils.d.ts +0 -60
  154. package/dist/test/utils.d.ts.map +0 -1
  155. package/dist/test/utils.js +0 -24635
  156. package/dist/test/utils.js.map +0 -1
  157. package/dist/tiny-CW6F4GX6.js +0 -10
  158. package/dist/tiny-CW6F4GX6.js.map +0 -1
  159. package/dist/tsm_system_rows-ES7KNUQH.js +0 -13
  160. package/dist/tsm_system_rows-ES7KNUQH.js.map +0 -1
  161. package/dist/tsm_system_time-76WEIMBG.js +0 -13
  162. package/dist/tsm_system_time-76WEIMBG.js.map +0 -1
  163. package/dist/unaccent-7RYF3R64.js +0 -13
  164. package/dist/unaccent-7RYF3R64.js.map +0 -1
  165. package/dist/utility-Q5A254LJ-J4HTKZPT.js +0 -347
  166. package/dist/utility-Q5A254LJ-J4HTKZPT.js.map +0 -1
  167. package/dist/uuid_ossp-4ETE4FPE.js +0 -13
  168. package/dist/uuid_ossp-4ETE4FPE.js.map +0 -1
  169. package/dist/vector-74GPNV7V.js +0 -13
  170. package/dist/vector-74GPNV7V.js.map +0 -1
  171. package/src/index.ts +0 -1
@@ -1,28 +1,18 @@
1
- import type { ExecutionPlan } from '@prisma-next/contract/types';
2
- import type {
3
- MarkerReader,
4
- MarkerStatement,
5
- RuntimeFamilyAdapter,
6
- } from '@prisma-next/runtime-executor';
7
- import { runtimeError } from '@prisma-next/runtime-executor';
8
- import type { SqlContract, SqlStorage } from '@prisma-next/sql-contract/types';
9
- import { readContractMarker } from './sql-marker';
1
+ import type { Contract, ExecutionPlan } from '@prisma-next/contract/types';
2
+ import { runtimeError } from '@prisma-next/framework-components/runtime';
3
+ import type { MarkerReader, RuntimeFamilyAdapter } from '@prisma-next/runtime-executor';
4
+ import type { SqlStorage } from '@prisma-next/sql-contract/types';
5
+ import type { AdapterProfile } from '@prisma-next/sql-relational-core/ast';
10
6
 
11
- class SqlMarkerReader implements MarkerReader {
12
- readMarkerStatement(): MarkerStatement {
13
- return readContractMarker();
14
- }
15
- }
16
-
17
- export class SqlFamilyAdapter<TContract extends SqlContract<SqlStorage>>
7
+ export class SqlFamilyAdapter<TContract extends Contract<SqlStorage>>
18
8
  implements RuntimeFamilyAdapter<TContract>
19
9
  {
20
10
  readonly contract: TContract;
21
11
  readonly markerReader: MarkerReader;
22
12
 
23
- constructor(contract: TContract) {
13
+ constructor(contract: TContract, adapterProfile: AdapterProfile) {
24
14
  this.contract = contract;
25
- this.markerReader = new SqlMarkerReader();
15
+ this.markerReader = adapterProfile;
26
16
  }
27
17
 
28
18
  validatePlan(plan: ExecutionPlan, contract: TContract): void {
@@ -33,11 +23,15 @@ export class SqlFamilyAdapter<TContract extends SqlContract<SqlStorage>>
33
23
  });
34
24
  }
35
25
 
36
- if (plan.meta.coreHash !== contract.coreHash) {
37
- throw runtimeError('PLAN.HASH_MISMATCH', 'Plan core hash does not match runtime contract', {
38
- planCoreHash: plan.meta.coreHash,
39
- runtimeCoreHash: contract.coreHash,
40
- });
26
+ if (plan.meta.storageHash !== contract.storage.storageHash) {
27
+ throw runtimeError(
28
+ 'PLAN.HASH_MISMATCH',
29
+ 'Plan storage hash does not match runtime contract',
30
+ {
31
+ planStorageHash: plan.meta.storageHash,
32
+ runtimeStorageHash: contract.storage.storageHash,
33
+ },
34
+ );
41
35
  }
42
36
  }
43
37
  }
package/src/sql-marker.ts CHANGED
@@ -6,7 +6,7 @@ export interface SqlStatement {
6
6
  }
7
7
 
8
8
  export interface WriteMarkerInput {
9
- readonly coreHash: string;
9
+ readonly storageHash: string;
10
10
  readonly profileHash: string;
11
11
  readonly contractJson?: unknown;
12
12
  readonly canonicalVersion?: number;
@@ -57,7 +57,7 @@ export interface WriteContractMarkerStatements {
57
57
  export function writeContractMarker(input: WriteMarkerInput): WriteContractMarkerStatements {
58
58
  const baseParams: readonly unknown[] = [
59
59
  1,
60
- input.coreHash,
60
+ input.storageHash,
61
61
  input.profileHash,
62
62
  input.contractJson ?? null,
63
63
  input.canonicalVersion ?? null,
@@ -1,8 +1,12 @@
1
- import type { ExecutionPlan } from '@prisma-next/contract/types';
2
- import type { OperationRegistry } from '@prisma-next/operations';
1
+ import type { Contract, ExecutionPlan } from '@prisma-next/contract/types';
2
+ import type {
3
+ ExecutionStackInstance,
4
+ RuntimeDriverInstance,
5
+ } from '@prisma-next/framework-components/execution';
6
+ import { checkMiddlewareCompatibility } from '@prisma-next/framework-components/runtime';
3
7
  import type {
4
8
  Log,
5
- Plugin,
9
+ Middleware,
6
10
  RuntimeCore,
7
11
  RuntimeCoreOptions,
8
12
  RuntimeTelemetryEvent,
@@ -10,86 +14,118 @@ import type {
10
14
  TelemetryOutcome,
11
15
  } from '@prisma-next/runtime-executor';
12
16
  import { AsyncIterableResult, createRuntimeCore } from '@prisma-next/runtime-executor';
13
- import type { SqlContract, SqlStorage } from '@prisma-next/sql-contract/types';
17
+ import type { SqlStorage } from '@prisma-next/sql-contract/types';
14
18
  import type {
15
19
  Adapter,
20
+ AnyQueryAst,
16
21
  CodecRegistry,
17
22
  LoweredStatement,
18
- SelectAst,
19
23
  SqlDriver,
20
24
  } from '@prisma-next/sql-relational-core/ast';
21
25
  import type { SqlQueryPlan } from '@prisma-next/sql-relational-core/plan';
26
+ import type { JsonSchemaValidatorRegistry } from '@prisma-next/sql-relational-core/query-lane-context';
27
+ import { ifDefined } from '@prisma-next/utils/defined';
22
28
  import { decodeRow } from './codecs/decoding';
23
29
  import { encodeParams } from './codecs/encoding';
24
30
  import { validateCodecRegistryCompleteness } from './codecs/validation';
25
31
  import { lowerSqlPlan } from './lower-sql-plan';
26
- import type { RuntimeContext } from './sql-context';
32
+ import type {
33
+ ExecutionContext,
34
+ SqlRuntimeAdapterInstance,
35
+ SqlRuntimeExtensionInstance,
36
+ } from './sql-context';
27
37
  import { SqlFamilyAdapter } from './sql-family-adapter';
28
38
 
29
- export interface RuntimeOptions<
30
- TContract extends SqlContract<SqlStorage> = SqlContract<SqlStorage>,
39
+ export interface RuntimeOptions<TContract extends Contract<SqlStorage> = Contract<SqlStorage>> {
40
+ readonly context: ExecutionContext<TContract>;
41
+ readonly adapter: Adapter<AnyQueryAst, Contract<SqlStorage>, LoweredStatement>;
42
+ readonly driver: SqlDriver<unknown>;
43
+ readonly verify: RuntimeVerifyOptions;
44
+ readonly middleware?: readonly Middleware<TContract>[];
45
+ readonly mode?: 'strict' | 'permissive';
46
+ readonly log?: Log;
47
+ }
48
+
49
+ export interface CreateRuntimeOptions<
50
+ TContract extends Contract<SqlStorage> = Contract<SqlStorage>,
51
+ TTargetId extends string = string,
31
52
  > {
32
- readonly driver: SqlDriver;
53
+ readonly stackInstance: ExecutionStackInstance<
54
+ 'sql',
55
+ TTargetId,
56
+ SqlRuntimeAdapterInstance<TTargetId>,
57
+ RuntimeDriverInstance<'sql', TTargetId>,
58
+ SqlRuntimeExtensionInstance<TTargetId>
59
+ >;
60
+ readonly context: ExecutionContext<TContract>;
61
+ readonly driver: SqlDriver<unknown>;
33
62
  readonly verify: RuntimeVerifyOptions;
34
- readonly context: RuntimeContext<TContract>;
35
- readonly plugins?: readonly Plugin<
36
- TContract,
37
- Adapter<SelectAst, SqlContract<SqlStorage>, LoweredStatement>,
38
- SqlDriver
39
- >[];
63
+ readonly middleware?: readonly Middleware<TContract>[];
40
64
  readonly mode?: 'strict' | 'permissive';
41
65
  readonly log?: Log;
42
66
  }
43
67
 
44
- export interface Runtime {
68
+ export interface Runtime extends RuntimeQueryable {
69
+ connection(): Promise<RuntimeConnection>;
70
+ telemetry(): RuntimeTelemetryEvent | null;
71
+ close(): Promise<void>;
72
+ }
73
+
74
+ export interface RuntimeConnection extends RuntimeQueryable {
75
+ transaction(): Promise<RuntimeTransaction>;
76
+ release(): Promise<void>;
77
+ }
78
+
79
+ export interface RuntimeTransaction extends RuntimeQueryable {
80
+ commit(): Promise<void>;
81
+ rollback(): Promise<void>;
82
+ }
83
+
84
+ export interface RuntimeQueryable {
45
85
  execute<Row = Record<string, unknown>>(
46
86
  plan: ExecutionPlan<Row> | SqlQueryPlan<Row>,
47
87
  ): AsyncIterableResult<Row>;
48
- telemetry(): RuntimeTelemetryEvent | null;
49
- close(): Promise<void>;
50
- operations(): OperationRegistry;
88
+ }
89
+
90
+ interface CoreQueryable {
91
+ execute<Row = Record<string, unknown>>(plan: ExecutionPlan<Row>): AsyncIterableResult<Row>;
51
92
  }
52
93
 
53
94
  export type { RuntimeTelemetryEvent, RuntimeVerifyOptions, TelemetryOutcome };
54
95
 
55
- class SqlRuntimeImpl<TContract extends SqlContract<SqlStorage> = SqlContract<SqlStorage>>
96
+ class SqlRuntimeImpl<TContract extends Contract<SqlStorage> = Contract<SqlStorage>>
56
97
  implements Runtime
57
98
  {
58
- private readonly core: RuntimeCore<
59
- TContract,
60
- Adapter<SelectAst, SqlContract<SqlStorage>, LoweredStatement>,
61
- SqlDriver
62
- >;
99
+ private readonly core: RuntimeCore<TContract, SqlDriver<unknown>>;
63
100
  private readonly contract: TContract;
64
- private readonly context: RuntimeContext<TContract>;
101
+ private readonly adapter: Adapter<AnyQueryAst, Contract<SqlStorage>, LoweredStatement>;
65
102
  private readonly codecRegistry: CodecRegistry;
103
+ private readonly jsonSchemaValidators: JsonSchemaValidatorRegistry | undefined;
66
104
  private codecRegistryValidated: boolean;
67
105
 
68
106
  constructor(options: RuntimeOptions<TContract>) {
69
- const { context, driver, verify, plugins, mode, log } = options;
107
+ const { context, adapter, driver, verify, middleware, mode, log } = options;
70
108
  this.contract = context.contract;
71
- this.context = context;
109
+ this.adapter = adapter;
72
110
  this.codecRegistry = context.codecs;
111
+ this.jsonSchemaValidators = context.jsonSchemaValidators;
73
112
  this.codecRegistryValidated = false;
74
113
 
75
- const familyAdapter = new SqlFamilyAdapter(context.contract);
114
+ if (middleware) {
115
+ for (const mw of middleware) {
116
+ checkMiddlewareCompatibility(mw, 'sql', context.contract.target);
117
+ }
118
+ }
119
+
120
+ const familyAdapter = new SqlFamilyAdapter(context.contract, adapter.profile);
76
121
 
77
- const coreOptions: RuntimeCoreOptions<
78
- TContract,
79
- Adapter<SelectAst, SqlContract<SqlStorage>, LoweredStatement>,
80
- SqlDriver
81
- > = {
122
+ const coreOptions: RuntimeCoreOptions<TContract, SqlDriver<unknown>> = {
82
123
  familyAdapter,
83
124
  driver,
84
125
  verify,
85
- plugins: plugins as readonly Plugin<
86
- TContract,
87
- Adapter<SelectAst, SqlContract<SqlStorage>, LoweredStatement>,
88
- SqlDriver
89
- >[],
90
- ...(mode !== undefined ? { mode } : {}),
91
- ...(log !== undefined ? { log } : {}),
92
- operationRegistry: context.operations,
126
+ ...ifDefined('middleware', middleware),
127
+ ...ifDefined('mode', mode),
128
+ ...ifDefined('log', log),
93
129
  };
94
130
 
95
131
  this.core = createRuntimeCore(coreOptions);
@@ -100,27 +136,27 @@ class SqlRuntimeImpl<TContract extends SqlContract<SqlStorage> = SqlContract<Sql
100
136
  }
101
137
  }
102
138
 
103
- private ensureCodecRegistryValidated(contract: SqlContract<SqlStorage>): void {
139
+ private ensureCodecRegistryValidated(contract: Contract<SqlStorage>): void {
104
140
  if (!this.codecRegistryValidated) {
105
141
  validateCodecRegistryCompleteness(this.codecRegistry, contract);
106
142
  this.codecRegistryValidated = true;
107
143
  }
108
144
  }
109
145
 
110
- execute<Row = Record<string, unknown>>(
111
- plan: ExecutionPlan<Row> | SqlQueryPlan<Row>,
112
- ): AsyncIterableResult<Row> {
113
- this.ensureCodecRegistryValidated(this.contract);
114
-
115
- // Check if plan is SqlQueryPlan (has ast but no sql)
146
+ private toExecutionPlan<Row>(plan: ExecutionPlan<Row> | SqlQueryPlan<Row>): ExecutionPlan<Row> {
116
147
  const isSqlQueryPlan = (p: ExecutionPlan<Row> | SqlQueryPlan<Row>): p is SqlQueryPlan<Row> => {
117
148
  return 'ast' in p && !('sql' in p);
118
149
  };
119
150
 
120
- // Lower SqlQueryPlan to Plan if needed
121
- const executablePlan: ExecutionPlan<Row> = isSqlQueryPlan(plan)
122
- ? lowerSqlPlan(this.context, plan)
123
- : plan;
151
+ return isSqlQueryPlan(plan) ? lowerSqlPlan(this.adapter, this.contract, plan) : plan;
152
+ }
153
+
154
+ private executeAgainstQueryable<Row = Record<string, unknown>>(
155
+ plan: ExecutionPlan<Row> | SqlQueryPlan<Row>,
156
+ queryable: CoreQueryable,
157
+ ): AsyncIterableResult<Row> {
158
+ this.ensureCodecRegistryValidated(this.contract);
159
+ const executablePlan = this.toExecutionPlan(plan);
124
160
 
125
161
  const iterator = async function* (
126
162
  self: SqlRuntimeImpl<TContract>,
@@ -131,13 +167,14 @@ class SqlRuntimeImpl<TContract extends SqlContract<SqlStorage> = SqlContract<Sql
131
167
  params: encodedParams,
132
168
  };
133
169
 
134
- const coreIterator = self.core.execute(planWithEncodedParams);
170
+ const coreIterator = queryable.execute(planWithEncodedParams);
135
171
 
136
172
  for await (const rawRow of coreIterator) {
137
173
  const decodedRow = decodeRow(
138
174
  rawRow as Record<string, unknown>,
139
175
  executablePlan,
140
176
  self.codecRegistry,
177
+ self.jsonSchemaValidators,
141
178
  );
142
179
  yield decodedRow as Row;
143
180
  }
@@ -146,12 +183,40 @@ class SqlRuntimeImpl<TContract extends SqlContract<SqlStorage> = SqlContract<Sql
146
183
  return new AsyncIterableResult(iterator(this));
147
184
  }
148
185
 
149
- telemetry(): RuntimeTelemetryEvent | null {
150
- return this.core.telemetry();
186
+ execute<Row = Record<string, unknown>>(
187
+ plan: ExecutionPlan<Row> | SqlQueryPlan<Row>,
188
+ ): AsyncIterableResult<Row> {
189
+ return this.executeAgainstQueryable(plan, this.core);
151
190
  }
152
191
 
153
- operations(): OperationRegistry {
154
- return this.core.operations();
192
+ async connection(): Promise<RuntimeConnection> {
193
+ const coreConn = await this.core.connection();
194
+ const self = this;
195
+ const wrappedConnection: RuntimeConnection = {
196
+ async transaction(): Promise<RuntimeTransaction> {
197
+ const coreTx = await coreConn.transaction();
198
+ return {
199
+ commit: coreTx.commit.bind(coreTx),
200
+ rollback: coreTx.rollback.bind(coreTx),
201
+ execute<Row = Record<string, unknown>>(
202
+ plan: ExecutionPlan<Row> | SqlQueryPlan<Row>,
203
+ ): AsyncIterableResult<Row> {
204
+ return self.executeAgainstQueryable(plan, coreTx);
205
+ },
206
+ };
207
+ },
208
+ release: coreConn.release.bind(coreConn),
209
+ execute<Row = Record<string, unknown>>(
210
+ plan: ExecutionPlan<Row> | SqlQueryPlan<Row>,
211
+ ): AsyncIterableResult<Row> {
212
+ return self.executeAgainstQueryable(plan, coreConn);
213
+ },
214
+ };
215
+ return wrappedConnection;
216
+ }
217
+
218
+ telemetry(): RuntimeTelemetryEvent | null {
219
+ return this.core.telemetry();
155
220
  }
156
221
 
157
222
  close(): Promise<void> {
@@ -159,8 +224,18 @@ class SqlRuntimeImpl<TContract extends SqlContract<SqlStorage> = SqlContract<Sql
159
224
  }
160
225
  }
161
226
 
162
- export function createRuntime<TContract extends SqlContract<SqlStorage>>(
163
- options: RuntimeOptions<TContract>,
227
+ export function createRuntime<TContract extends Contract<SqlStorage>, TTargetId extends string>(
228
+ options: CreateRuntimeOptions<TContract, TTargetId>,
164
229
  ): Runtime {
165
- return new SqlRuntimeImpl(options);
230
+ const { stackInstance, context, driver, verify, middleware, mode, log } = options;
231
+
232
+ return new SqlRuntimeImpl({
233
+ context,
234
+ adapter: stackInstance.adapter,
235
+ driver,
236
+ verify,
237
+ ...ifDefined('middleware', middleware),
238
+ ...ifDefined('mode', mode),
239
+ ...ifDefined('log', log),
240
+ });
166
241
  }
@@ -1,10 +1,17 @@
1
1
  import type { ExecutionPlan } from '@prisma-next/contract/types';
2
+ import { instantiateExecutionStack } from '@prisma-next/framework-components/execution';
2
3
  import type { AsyncIterableResult } from '@prisma-next/runtime-executor';
3
4
  import { describe, expect, it } from 'vitest';
4
- import { createRuntime } from '../src/exports';
5
- import { createStubAdapter, createTestContext, createTestContract } from './utils';
5
+ import type { Runtime } from '../src/exports';
6
+ import { createRuntime, createSqlExecutionStack } from '../src/exports';
7
+ import {
8
+ createStubAdapter,
9
+ createTestAdapterDescriptor,
10
+ createTestContext,
11
+ createTestContract,
12
+ createTestTargetDescriptor,
13
+ } from './utils';
6
14
 
7
- // Mock driver that implements SqlDriver interface
8
15
  class MockDriver {
9
16
  private rows: ReadonlyArray<Record<string, unknown>> = [];
10
17
 
@@ -12,11 +19,10 @@ class MockDriver {
12
19
  this.rows = rows;
13
20
  }
14
21
 
15
- async query(
22
+ async query<Row = Record<string, unknown>>(
16
23
  _sql: string,
17
- _params: readonly unknown[],
18
- ): Promise<{ rows: ReadonlyArray<unknown> }> {
19
- // Return empty marker result for contract verification
24
+ _params?: readonly unknown[],
25
+ ): Promise<{ rows: ReadonlyArray<Row> }> {
20
26
  return { rows: [] };
21
27
  }
22
28
 
@@ -29,20 +35,19 @@ class MockDriver {
29
35
  }
30
36
  }
31
37
 
32
- async connect(): Promise<void> {
33
- // No-op
38
+ async acquireConnection(): Promise<never> {
39
+ throw new Error('Not implemented in mock');
34
40
  }
35
41
 
36
- async close(): Promise<void> {
37
- // No-op
38
- }
42
+ async connect(): Promise<void> {}
43
+
44
+ async close(): Promise<void> {}
39
45
  }
40
46
 
41
47
  const fixtureContract = createTestContract({
42
- schemaVersion: '1',
43
48
  targetFamily: 'sql',
44
49
  target: 'postgres',
45
- coreHash: 'test-hash',
50
+ storageHash: 'test-hash',
46
51
  profileHash: 'test-profile-hash',
47
52
  storage: {
48
53
  tables: {
@@ -58,24 +63,33 @@ const fixtureContract = createTestContract({
58
63
  },
59
64
  },
60
65
  models: {},
61
- relations: {},
62
- mappings: { codecTypes: {}, operationTypes: {} },
63
66
  });
64
67
 
68
+ function createTestRuntime(mockDriver: MockDriver): Runtime {
69
+ const adapter = createStubAdapter();
70
+ const stack = createSqlExecutionStack({
71
+ target: createTestTargetDescriptor(),
72
+ adapter: createTestAdapterDescriptor(adapter),
73
+ extensionPacks: [],
74
+ });
75
+ const stackInstance = instantiateExecutionStack(stack);
76
+ const context = createTestContext(fixtureContract, adapter);
77
+ return createRuntime({
78
+ stackInstance,
79
+ context,
80
+ driver: mockDriver,
81
+ verify: { mode: 'onFirstUse', requireMarker: false },
82
+ });
83
+ }
84
+
65
85
  describe('SqlRuntime AsyncIterableResult integration', () => {
66
86
  it('returns AsyncIterableResult from execute', async () => {
67
- const adapter = createStubAdapter();
68
87
  const driver = new MockDriver();
69
88
  driver.setRows([
70
89
  { id: 1, email: 'test1@example.com' },
71
90
  { id: 2, email: 'test2@example.com' },
72
91
  ]);
73
- const context = createTestContext(fixtureContract, adapter);
74
- const runtime = createRuntime({
75
- driver: driver as unknown as Parameters<typeof createRuntime>[0]['driver'],
76
- context,
77
- verify: { mode: 'onFirstUse', requireMarker: false },
78
- });
92
+ const runtime = createTestRuntime(driver);
79
93
 
80
94
  const plan: ExecutionPlan<{ id: number; email: string }> = {
81
95
  sql: 'SELECT id, email FROM "user" ORDER BY id',
@@ -83,7 +97,7 @@ describe('SqlRuntime AsyncIterableResult integration', () => {
83
97
  meta: {
84
98
  target: 'postgres',
85
99
  targetFamily: 'sql',
86
- coreHash: 'test-hash',
100
+ storageHash: 'test-hash',
87
101
  lane: 'sql',
88
102
  paramDescriptors: [],
89
103
  },
@@ -91,7 +105,6 @@ describe('SqlRuntime AsyncIterableResult integration', () => {
91
105
 
92
106
  const result = runtime.execute(plan);
93
107
 
94
- // Verify it's an AsyncIterableResult
95
108
  expect(result).toBeInstanceOf(Object);
96
109
  expect(typeof result.toArray).toBe('function');
97
110
  expect(typeof result[Symbol.asyncIterator]).toBe('function');
@@ -100,15 +113,9 @@ describe('SqlRuntime AsyncIterableResult integration', () => {
100
113
  });
101
114
 
102
115
  it('preserves type information', async () => {
103
- const adapter = createStubAdapter();
104
116
  const driver = new MockDriver();
105
117
  driver.setRows([{ id: 1, email: 'test@example.com' }]);
106
- const context = createTestContext(fixtureContract, adapter);
107
- const runtime = createRuntime({
108
- driver: driver as unknown as Parameters<typeof createRuntime>[0]['driver'],
109
- context,
110
- verify: { mode: 'onFirstUse', requireMarker: false },
111
- });
118
+ const runtime = createTestRuntime(driver);
112
119
 
113
120
  const plan: ExecutionPlan<{ id: number; email: string }> = {
114
121
  sql: 'SELECT id, email FROM "user" LIMIT 1',
@@ -116,7 +123,7 @@ describe('SqlRuntime AsyncIterableResult integration', () => {
116
123
  meta: {
117
124
  target: 'postgres',
118
125
  targetFamily: 'sql',
119
- coreHash: 'test-hash',
126
+ storageHash: 'test-hash',
120
127
  lane: 'sql',
121
128
  paramDescriptors: [],
122
129
  },
@@ -126,10 +133,8 @@ describe('SqlRuntime AsyncIterableResult integration', () => {
126
133
  const rows = await result.toArray();
127
134
 
128
135
  expect(rows.length).toBe(1);
129
- if (rows[0]) {
130
- expect(typeof rows[0].id).toBe('number');
131
- expect(typeof rows[0].email).toBe('string');
132
- }
136
+ expect(typeof rows[0]!.id).toBe('number');
137
+ expect(typeof rows[0]!.email).toBe('string');
133
138
 
134
139
  await runtime.close();
135
140
  });