@prisma-next/family-sql 0.3.0-dev.12 → 0.3.0-dev.123
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/LICENSE +201 -0
- package/README.md +34 -7
- package/dist/assembly-Dzumaba1.mjs +159 -0
- package/dist/assembly-Dzumaba1.mjs.map +1 -0
- package/dist/control-adapter.d.mts +60 -0
- package/dist/control-adapter.d.mts.map +1 -0
- package/dist/control-adapter.mjs +1 -0
- package/dist/control-instance-BKuHINR7.d.mts +411 -0
- package/dist/control-instance-BKuHINR7.d.mts.map +1 -0
- package/dist/control.d.mts +128 -0
- package/dist/control.d.mts.map +1 -0
- package/dist/control.mjs +683 -0
- package/dist/control.mjs.map +1 -0
- package/dist/runtime.d.mts +27 -0
- package/dist/runtime.d.mts.map +1 -0
- package/dist/runtime.mjs +38 -0
- package/dist/runtime.mjs.map +1 -0
- package/dist/schema-verify.d.mts +48 -0
- package/dist/schema-verify.d.mts.map +1 -0
- package/dist/schema-verify.mjs +4 -0
- package/dist/test-utils.d.mts +2 -0
- package/dist/test-utils.mjs +3 -0
- package/dist/verify-BfMETJcM.mjs +108 -0
- package/dist/verify-BfMETJcM.mjs.map +1 -0
- package/dist/verify-sql-schema-C3Pit9o4.mjs +1085 -0
- package/dist/verify-sql-schema-C3Pit9o4.mjs.map +1 -0
- package/dist/verify-sql-schema-DhHnkpPa.d.mts +67 -0
- package/dist/verify-sql-schema-DhHnkpPa.d.mts.map +1 -0
- package/dist/verify.d.mts +31 -0
- package/dist/verify.d.mts.map +1 -0
- package/dist/verify.mjs +3 -0
- package/package.json +35 -46
- package/src/core/assembly.ts +265 -59
- package/src/core/control-adapter.ts +15 -0
- package/src/core/{descriptor.ts → control-descriptor.ts} +15 -11
- package/src/core/{instance.ts → control-instance.ts} +106 -248
- package/src/core/migrations/contract-to-schema-ir.ts +265 -0
- package/src/core/migrations/types.ts +193 -168
- package/src/core/runtime-descriptor.ts +19 -41
- package/src/core/runtime-instance.ts +11 -133
- package/src/core/schema-verify/verify-helpers.ts +201 -105
- package/src/core/schema-verify/verify-sql-schema.ts +918 -413
- package/src/core/verify.ts +4 -13
- package/src/exports/control.ts +29 -6
- package/src/exports/runtime.ts +2 -6
- package/src/exports/schema-verify.ts +10 -2
- package/src/exports/test-utils.ts +1 -1
- package/dist/chunk-BHEGVBY7.js +0 -772
- package/dist/chunk-BHEGVBY7.js.map +0 -1
- package/dist/chunk-SQ2VWYDV.js +0 -589
- package/dist/chunk-SQ2VWYDV.js.map +0 -1
- package/dist/chunk-SU7LN2UH.js +0 -96
- package/dist/chunk-SU7LN2UH.js.map +0 -1
- package/dist/core/assembly.d.ts +0 -25
- package/dist/core/assembly.d.ts.map +0 -1
- package/dist/core/control-adapter.d.ts +0 -42
- package/dist/core/control-adapter.d.ts.map +0 -1
- package/dist/core/descriptor.d.ts +0 -24
- package/dist/core/descriptor.d.ts.map +0 -1
- package/dist/core/instance.d.ts +0 -140
- package/dist/core/instance.d.ts.map +0 -1
- package/dist/core/migrations/plan-helpers.d.ts +0 -20
- package/dist/core/migrations/plan-helpers.d.ts.map +0 -1
- package/dist/core/migrations/policies.d.ts +0 -6
- package/dist/core/migrations/policies.d.ts.map +0 -1
- package/dist/core/migrations/types.d.ts +0 -280
- package/dist/core/migrations/types.d.ts.map +0 -1
- package/dist/core/runtime-descriptor.d.ts +0 -19
- package/dist/core/runtime-descriptor.d.ts.map +0 -1
- package/dist/core/runtime-instance.d.ts +0 -54
- package/dist/core/runtime-instance.d.ts.map +0 -1
- package/dist/core/schema-verify/verify-helpers.d.ts +0 -50
- package/dist/core/schema-verify/verify-helpers.d.ts.map +0 -1
- package/dist/core/schema-verify/verify-sql-schema.d.ts +0 -45
- package/dist/core/schema-verify/verify-sql-schema.d.ts.map +0 -1
- package/dist/core/verify.d.ts +0 -39
- package/dist/core/verify.d.ts.map +0 -1
- package/dist/exports/control-adapter.d.ts +0 -2
- package/dist/exports/control-adapter.d.ts.map +0 -1
- package/dist/exports/control-adapter.js +0 -1
- package/dist/exports/control-adapter.js.map +0 -1
- package/dist/exports/control.d.ts +0 -13
- package/dist/exports/control.d.ts.map +0 -1
- package/dist/exports/control.js +0 -149
- package/dist/exports/control.js.map +0 -1
- package/dist/exports/runtime.d.ts +0 -8
- package/dist/exports/runtime.d.ts.map +0 -1
- package/dist/exports/runtime.js +0 -64
- package/dist/exports/runtime.js.map +0 -1
- package/dist/exports/schema-verify.d.ts +0 -11
- package/dist/exports/schema-verify.d.ts.map +0 -1
- package/dist/exports/schema-verify.js +0 -11
- package/dist/exports/schema-verify.js.map +0 -1
- package/dist/exports/test-utils.d.ts +0 -7
- package/dist/exports/test-utils.d.ts.map +0 -1
- package/dist/exports/test-utils.js +0 -17
- package/dist/exports/test-utils.js.map +0 -1
- package/dist/exports/verify.d.ts +0 -2
- package/dist/exports/verify.d.ts.map +0 -1
- package/dist/exports/verify.js +0 -11
- package/dist/exports/verify.js.map +0 -1
|
@@ -1,15 +1,14 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {
|
|
2
|
+
TargetBoundComponentDescriptor,
|
|
3
|
+
TargetDescriptor,
|
|
4
|
+
} from '@prisma-next/contract/framework-components';
|
|
2
5
|
import type { ContractIR } from '@prisma-next/contract/ir';
|
|
3
|
-
import type { OperationManifest } from '@prisma-next/contract/pack-manifest-types';
|
|
4
6
|
import type { ContractMarkerRecord, TypesImportSpec } from '@prisma-next/contract/types';
|
|
5
7
|
import { emit } from '@prisma-next/core-control-plane/emission';
|
|
6
8
|
import type { CoreSchemaView, SchemaTreeNode } from '@prisma-next/core-control-plane/schema-view';
|
|
7
9
|
import type {
|
|
8
|
-
ControlAdapterDescriptor,
|
|
9
10
|
ControlDriverInstance,
|
|
10
|
-
ControlExtensionDescriptor,
|
|
11
11
|
ControlFamilyInstance,
|
|
12
|
-
ControlTargetDescriptor,
|
|
13
12
|
EmitContractResult,
|
|
14
13
|
OperationContext,
|
|
15
14
|
SignDatabaseResult,
|
|
@@ -18,14 +17,14 @@ import type {
|
|
|
18
17
|
} from '@prisma-next/core-control-plane/types';
|
|
19
18
|
import type { OperationRegistry } from '@prisma-next/operations';
|
|
20
19
|
import type { SqlContract, SqlStorage } from '@prisma-next/sql-contract/types';
|
|
20
|
+
import { validateContract } from '@prisma-next/sql-contract/validate';
|
|
21
21
|
import { sqlTargetFamilyHook } from '@prisma-next/sql-contract-emitter';
|
|
22
|
-
import { validateContract } from '@prisma-next/sql-contract-ts/contract';
|
|
23
|
-
import type { SqlOperationSignature } from '@prisma-next/sql-operations';
|
|
24
22
|
import {
|
|
25
23
|
ensureSchemaStatement,
|
|
26
24
|
ensureTableStatement,
|
|
27
25
|
writeContractMarker,
|
|
28
26
|
} from '@prisma-next/sql-runtime';
|
|
27
|
+
import { defaultIndexName } from '@prisma-next/sql-schema-ir/naming';
|
|
29
28
|
import type { SqlSchemaIR, SqlTableIR } from '@prisma-next/sql-schema-ir/types';
|
|
30
29
|
import { ifDefined } from '@prisma-next/utils/defined';
|
|
31
30
|
import {
|
|
@@ -33,59 +32,19 @@ import {
|
|
|
33
32
|
extractCodecTypeImports,
|
|
34
33
|
extractExtensionIds,
|
|
35
34
|
extractOperationTypeImports,
|
|
35
|
+
extractParameterizedRenderers,
|
|
36
|
+
extractParameterizedTypeImports,
|
|
37
|
+
extractQueryOperationTypeImports,
|
|
38
|
+
type SqlControlDescriptorWithContributions,
|
|
36
39
|
} from './assembly';
|
|
37
40
|
import type { SqlControlAdapter } from './control-adapter';
|
|
41
|
+
import type {
|
|
42
|
+
SqlControlAdapterDescriptor,
|
|
43
|
+
SqlControlExtensionDescriptor,
|
|
44
|
+
} from './migrations/types';
|
|
38
45
|
import { verifySqlSchema } from './schema-verify/verify-sql-schema';
|
|
39
46
|
import { collectSupportedCodecTypeIds, readMarker } from './verify';
|
|
40
47
|
|
|
41
|
-
/**
|
|
42
|
-
* Converts an OperationManifest (descriptor declarative data) to a SqlOperationSignature.
|
|
43
|
-
* This is SQL-family-specific conversion logic used by instance creation and test utilities.
|
|
44
|
-
*/
|
|
45
|
-
export function convertOperationManifest(manifest: OperationManifest): SqlOperationSignature {
|
|
46
|
-
return {
|
|
47
|
-
forTypeId: manifest.for,
|
|
48
|
-
method: manifest.method,
|
|
49
|
-
args: manifest.args.map((arg: OperationManifest['args'][number]) => {
|
|
50
|
-
if (arg.kind === 'typeId') {
|
|
51
|
-
if (!arg.type) {
|
|
52
|
-
throw new Error('typeId arg must have type property');
|
|
53
|
-
}
|
|
54
|
-
return { kind: 'typeId' as const, type: arg.type };
|
|
55
|
-
}
|
|
56
|
-
if (arg.kind === 'param') {
|
|
57
|
-
return { kind: 'param' as const };
|
|
58
|
-
}
|
|
59
|
-
if (arg.kind === 'literal') {
|
|
60
|
-
return { kind: 'literal' as const };
|
|
61
|
-
}
|
|
62
|
-
throw new Error(`Invalid arg kind: ${(arg as { kind: unknown }).kind}`);
|
|
63
|
-
}),
|
|
64
|
-
returns: (() => {
|
|
65
|
-
if (manifest.returns.kind === 'typeId') {
|
|
66
|
-
return { kind: 'typeId' as const, type: manifest.returns.type };
|
|
67
|
-
}
|
|
68
|
-
if (manifest.returns.kind === 'builtin') {
|
|
69
|
-
return {
|
|
70
|
-
kind: 'builtin' as const,
|
|
71
|
-
type: manifest.returns.type as 'number' | 'boolean' | 'string',
|
|
72
|
-
};
|
|
73
|
-
}
|
|
74
|
-
throw new Error(`Invalid return kind: ${(manifest.returns as { kind: unknown }).kind}`);
|
|
75
|
-
})(),
|
|
76
|
-
lowering: {
|
|
77
|
-
targetFamily: 'sql',
|
|
78
|
-
strategy: manifest.lowering.strategy,
|
|
79
|
-
template: manifest.lowering.template,
|
|
80
|
-
},
|
|
81
|
-
...(manifest.capabilities ? { capabilities: manifest.capabilities } : {}),
|
|
82
|
-
};
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* Extracts codec type IDs used in contract storage tables.
|
|
87
|
-
* Uses type guards to safely access SQL-specific structure without importing SQL types.
|
|
88
|
-
*/
|
|
89
48
|
function extractCodecTypeIdsFromContract(contract: unknown): readonly string[] {
|
|
90
49
|
const typeIds = new Set<string>();
|
|
91
50
|
|
|
@@ -127,14 +86,11 @@ function extractCodecTypeIdsFromContract(contract: unknown): readonly string[] {
|
|
|
127
86
|
return Array.from(typeIds).sort();
|
|
128
87
|
}
|
|
129
88
|
|
|
130
|
-
/**
|
|
131
|
-
* Creates a VerifyDatabaseResult object with common structure.
|
|
132
|
-
*/
|
|
133
89
|
function createVerifyResult(options: {
|
|
134
90
|
ok: boolean;
|
|
135
91
|
code?: string;
|
|
136
92
|
summary: string;
|
|
137
|
-
|
|
93
|
+
contractStorageHash: string;
|
|
138
94
|
contractProfileHash?: string;
|
|
139
95
|
marker?: ContractMarkerRecord;
|
|
140
96
|
expectedTargetId: string;
|
|
@@ -145,8 +101,8 @@ function createVerifyResult(options: {
|
|
|
145
101
|
contractPath: string;
|
|
146
102
|
totalTime: number;
|
|
147
103
|
}): VerifyDatabaseResult {
|
|
148
|
-
const contract: {
|
|
149
|
-
|
|
104
|
+
const contract: { storageHash: string; profileHash?: string } = {
|
|
105
|
+
storageHash: options.contractStorageHash,
|
|
150
106
|
};
|
|
151
107
|
if (options.contractProfileHash) {
|
|
152
108
|
contract.profileHash = options.contractProfileHash;
|
|
@@ -182,8 +138,8 @@ function createVerifyResult(options: {
|
|
|
182
138
|
}
|
|
183
139
|
|
|
184
140
|
if (options.marker) {
|
|
185
|
-
(result as { marker?: {
|
|
186
|
-
|
|
141
|
+
(result as { marker?: { storageHash: string; profileHash: string } }).marker = {
|
|
142
|
+
storageHash: options.marker.storageHash,
|
|
187
143
|
profileHash: options.marker.profileHash,
|
|
188
144
|
};
|
|
189
145
|
}
|
|
@@ -200,10 +156,6 @@ function createVerifyResult(options: {
|
|
|
200
156
|
return result;
|
|
201
157
|
}
|
|
202
158
|
|
|
203
|
-
/**
|
|
204
|
-
* Type metadata for SQL storage types.
|
|
205
|
-
* Maps contract storage type IDs to native database types.
|
|
206
|
-
*/
|
|
207
159
|
interface SqlTypeMetadata {
|
|
208
160
|
readonly typeId: string;
|
|
209
161
|
readonly familyId: 'sql';
|
|
@@ -211,15 +163,8 @@ interface SqlTypeMetadata {
|
|
|
211
163
|
readonly nativeType?: string;
|
|
212
164
|
}
|
|
213
165
|
|
|
214
|
-
/**
|
|
215
|
-
* Registry mapping type IDs to their metadata.
|
|
216
|
-
* Keyed by contract storage type ID (e.g., 'pg/int4@1').
|
|
217
|
-
*/
|
|
218
166
|
type SqlTypeMetadataRegistry = Map<string, SqlTypeMetadata>;
|
|
219
167
|
|
|
220
|
-
/**
|
|
221
|
-
* State fields for SQL family instance that hold assembly data.
|
|
222
|
-
*/
|
|
223
168
|
interface SqlFamilyInstanceState {
|
|
224
169
|
readonly operationRegistry: OperationRegistry;
|
|
225
170
|
readonly codecTypeImports: ReadonlyArray<TypesImportSpec>;
|
|
@@ -228,9 +173,6 @@ interface SqlFamilyInstanceState {
|
|
|
228
173
|
readonly typeMetadataRegistry: SqlTypeMetadataRegistry;
|
|
229
174
|
}
|
|
230
175
|
|
|
231
|
-
/**
|
|
232
|
-
* Options for schema verification.
|
|
233
|
-
*/
|
|
234
176
|
export interface SchemaVerifyOptions {
|
|
235
177
|
readonly driver: ControlDriverInstance<'sql', string>;
|
|
236
178
|
readonly contractIR: unknown;
|
|
@@ -243,23 +185,11 @@ export interface SchemaVerifyOptions {
|
|
|
243
185
|
readonly frameworkComponents: ReadonlyArray<TargetBoundComponentDescriptor<'sql', string>>;
|
|
244
186
|
}
|
|
245
187
|
|
|
246
|
-
/**
|
|
247
|
-
* SQL control family instance interface.
|
|
248
|
-
* Extends ControlFamilyInstance with SQL-specific domain actions.
|
|
249
|
-
*/
|
|
250
188
|
export interface SqlControlFamilyInstance
|
|
251
189
|
extends ControlFamilyInstance<'sql'>,
|
|
252
190
|
SqlFamilyInstanceState {
|
|
253
|
-
/**
|
|
254
|
-
* Validates a contract JSON and returns a validated ContractIR (without mappings).
|
|
255
|
-
* Mappings are runtime-only and should not be part of ContractIR.
|
|
256
|
-
*/
|
|
257
191
|
validateContractIR(contractJson: unknown): ContractIR;
|
|
258
192
|
|
|
259
|
-
/**
|
|
260
|
-
* Verifies the database marker against the contract.
|
|
261
|
-
* Compares target, coreHash, and profileHash.
|
|
262
|
-
*/
|
|
263
193
|
verify(options: {
|
|
264
194
|
readonly driver: ControlDriverInstance<'sql', string>;
|
|
265
195
|
readonly contractIR: unknown;
|
|
@@ -268,17 +198,8 @@ export interface SqlControlFamilyInstance
|
|
|
268
198
|
readonly configPath?: string;
|
|
269
199
|
}): Promise<VerifyDatabaseResult>;
|
|
270
200
|
|
|
271
|
-
/**
|
|
272
|
-
* Verifies the database schema against the contract.
|
|
273
|
-
* Compares contract requirements against live database schema.
|
|
274
|
-
*/
|
|
275
201
|
schemaVerify(options: SchemaVerifyOptions): Promise<VerifyDatabaseSchemaResult>;
|
|
276
202
|
|
|
277
|
-
/**
|
|
278
|
-
* Signs the database with the contract marker.
|
|
279
|
-
* Writes or updates the contract marker if schema verification passes.
|
|
280
|
-
* This operation is idempotent - if the marker already matches, no changes are made.
|
|
281
|
-
*/
|
|
282
203
|
sign(options: {
|
|
283
204
|
readonly driver: ControlDriverInstance<'sql', string>;
|
|
284
205
|
readonly contractIR: unknown;
|
|
@@ -286,51 +207,25 @@ export interface SqlControlFamilyInstance
|
|
|
286
207
|
readonly configPath?: string;
|
|
287
208
|
}): Promise<SignDatabaseResult>;
|
|
288
209
|
|
|
289
|
-
/**
|
|
290
|
-
* Introspects the database schema and returns a family-specific schema IR.
|
|
291
|
-
*
|
|
292
|
-
* This is a read-only operation that returns a snapshot of the live database schema.
|
|
293
|
-
* The method is family-owned and delegates to target/adapter-specific introspectors
|
|
294
|
-
* to perform the actual schema introspection.
|
|
295
|
-
*
|
|
296
|
-
* @param options - Introspection options
|
|
297
|
-
* @param options.driver - Control plane driver for database connection
|
|
298
|
-
* @param options.contractIR - Optional contract IR for contract-guided introspection.
|
|
299
|
-
* When provided, families may use it for filtering, optimization, or validation
|
|
300
|
-
* during introspection. The contract IR does not change the meaning of "what exists"
|
|
301
|
-
* in the database - it only guides how introspection is performed.
|
|
302
|
-
* @returns Promise resolving to the family-specific Schema IR (e.g., `SqlSchemaIR` for SQL).
|
|
303
|
-
* The IR represents the complete schema snapshot at the time of introspection.
|
|
304
|
-
*/
|
|
305
210
|
introspect(options: {
|
|
306
211
|
readonly driver: ControlDriverInstance<'sql', string>;
|
|
307
212
|
readonly contractIR?: unknown;
|
|
308
213
|
}): Promise<SqlSchemaIR>;
|
|
309
214
|
|
|
310
|
-
/**
|
|
311
|
-
* Projects a SQL Schema IR into a core schema view for CLI visualization.
|
|
312
|
-
* Converts SqlSchemaIR (tables, columns, indexes, extensions) into a tree structure.
|
|
313
|
-
*/
|
|
314
215
|
toSchemaView(schema: SqlSchemaIR): CoreSchemaView;
|
|
315
216
|
|
|
316
|
-
/**
|
|
317
|
-
* Emits contract JSON and DTS as strings.
|
|
318
|
-
* Uses the instance's preassembled state (operation registry, type imports, extension IDs).
|
|
319
|
-
* Handles stripping mappings and validation internally.
|
|
320
|
-
*/
|
|
321
217
|
emitContract(options: { readonly contractIR: ContractIR | unknown }): Promise<EmitContractResult>;
|
|
322
218
|
}
|
|
323
219
|
|
|
324
|
-
/**
|
|
325
|
-
* SQL family instance type.
|
|
326
|
-
* Maintains backward compatibility with FamilyInstance while implementing SqlControlFamilyInstance.
|
|
327
|
-
*/
|
|
328
220
|
export type SqlFamilyInstance = SqlControlFamilyInstance;
|
|
329
221
|
|
|
330
222
|
interface CreateSqlFamilyInstanceOptions<TTargetId extends string> {
|
|
331
|
-
readonly target:
|
|
332
|
-
|
|
333
|
-
|
|
223
|
+
readonly target: TargetDescriptor<'sql', TTargetId> &
|
|
224
|
+
SqlControlDescriptorWithContributions &
|
|
225
|
+
DescriptorWithStorageTypes;
|
|
226
|
+
readonly adapter: SqlControlAdapterDescriptor<TTargetId> & DescriptorWithStorageTypes;
|
|
227
|
+
readonly extensionPacks: readonly (SqlControlExtensionDescriptor<TTargetId> &
|
|
228
|
+
DescriptorWithStorageTypes)[];
|
|
334
229
|
}
|
|
335
230
|
|
|
336
231
|
function isSqlControlAdapter<TTargetId extends string>(
|
|
@@ -344,28 +239,32 @@ function isSqlControlAdapter<TTargetId extends string>(
|
|
|
344
239
|
);
|
|
345
240
|
}
|
|
346
241
|
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
242
|
+
interface DescriptorWithStorageTypes {
|
|
243
|
+
readonly targetId?: string | undefined;
|
|
244
|
+
readonly types?:
|
|
245
|
+
| {
|
|
246
|
+
readonly storage?:
|
|
247
|
+
| ReadonlyArray<{
|
|
248
|
+
readonly typeId: string;
|
|
249
|
+
readonly familyId: string;
|
|
250
|
+
readonly targetId: string;
|
|
251
|
+
readonly nativeType?: string | undefined;
|
|
252
|
+
}>
|
|
253
|
+
| undefined;
|
|
254
|
+
}
|
|
255
|
+
| undefined;
|
|
256
|
+
}
|
|
257
|
+
|
|
354
258
|
function buildSqlTypeMetadataRegistry(options: {
|
|
355
|
-
readonly target:
|
|
356
|
-
readonly adapter:
|
|
357
|
-
readonly extensionPacks: readonly
|
|
259
|
+
readonly target: DescriptorWithStorageTypes;
|
|
260
|
+
readonly adapter: DescriptorWithStorageTypes & { readonly targetId: string };
|
|
261
|
+
readonly extensionPacks: readonly DescriptorWithStorageTypes[];
|
|
358
262
|
}): SqlTypeMetadataRegistry {
|
|
359
263
|
const { target, adapter, extensionPacks: extensions } = options;
|
|
360
264
|
const registry = new Map<string, SqlTypeMetadata>();
|
|
361
|
-
|
|
362
|
-
// Get targetId from adapter (they should match)
|
|
363
265
|
const targetId = adapter.targetId;
|
|
364
|
-
|
|
365
|
-
// Collect descriptors to iterate over
|
|
366
266
|
const descriptors = [target, adapter, ...extensions];
|
|
367
267
|
|
|
368
|
-
// Iterate over each descriptor's types
|
|
369
268
|
for (const descriptor of descriptors) {
|
|
370
269
|
const types = descriptor.types;
|
|
371
270
|
const storageTypes = types?.storage;
|
|
@@ -374,11 +273,8 @@ function buildSqlTypeMetadataRegistry(options: {
|
|
|
374
273
|
continue;
|
|
375
274
|
}
|
|
376
275
|
|
|
377
|
-
// Filter for SQL family and matching targetId
|
|
378
276
|
for (const storageType of storageTypes) {
|
|
379
277
|
if (storageType.familyId === 'sql' && storageType.targetId === targetId) {
|
|
380
|
-
// Use existing entry if present, otherwise create new one
|
|
381
|
-
// Later entries (extensions) can override earlier ones (adapter/target)
|
|
382
278
|
registry.set(storageType.typeId, {
|
|
383
279
|
typeId: storageType.typeId,
|
|
384
280
|
familyId: 'sql',
|
|
@@ -392,36 +288,28 @@ function buildSqlTypeMetadataRegistry(options: {
|
|
|
392
288
|
return registry;
|
|
393
289
|
}
|
|
394
290
|
|
|
395
|
-
/**
|
|
396
|
-
* Creates a SQL family instance for control-plane operations.
|
|
397
|
-
*/
|
|
398
291
|
export function createSqlFamilyInstance<TTargetId extends string>(
|
|
399
292
|
options: CreateSqlFamilyInstanceOptions<TTargetId>,
|
|
400
293
|
): SqlFamilyInstance {
|
|
401
294
|
const { target, adapter, extensionPacks: extensions = [] } = options;
|
|
402
295
|
|
|
403
|
-
|
|
404
|
-
// Assembly functions only use manifest and id, so we can pass Control*Descriptor types directly
|
|
405
|
-
const descriptors = [target, adapter, ...extensions];
|
|
296
|
+
const descriptors: SqlControlDescriptorWithContributions[] = [target, adapter, ...extensions];
|
|
406
297
|
|
|
407
|
-
|
|
408
|
-
const operationRegistry = assembleOperationRegistry(descriptors, convertOperationManifest);
|
|
298
|
+
const operationRegistry = assembleOperationRegistry(descriptors);
|
|
409
299
|
const codecTypeImports = extractCodecTypeImports(descriptors);
|
|
410
300
|
const operationTypeImports = extractOperationTypeImports(descriptors);
|
|
301
|
+
const queryOperationTypeImports = extractQueryOperationTypeImports(descriptors);
|
|
411
302
|
const extensionIds = extractExtensionIds(adapter, target, extensions);
|
|
303
|
+
const parameterizedRenderers = extractParameterizedRenderers(descriptors);
|
|
304
|
+
const parameterizedTypeImports = extractParameterizedTypeImports(descriptors);
|
|
412
305
|
|
|
413
|
-
// Build type metadata registry from manifests
|
|
414
306
|
const typeMetadataRegistry = buildSqlTypeMetadataRegistry({
|
|
415
307
|
target,
|
|
416
308
|
adapter,
|
|
417
309
|
extensionPacks: extensions,
|
|
418
310
|
});
|
|
419
311
|
|
|
420
|
-
/**
|
|
421
|
-
* Strips mappings from a contract (mappings are runtime-only).
|
|
422
|
-
*/
|
|
423
312
|
function stripMappings(contract: unknown): unknown {
|
|
424
|
-
// Type guard to check if contract has mappings
|
|
425
313
|
if (typeof contract === 'object' && contract !== null && 'mappings' in contract) {
|
|
426
314
|
const { mappings: _mappings, ...contractIR } = contract as {
|
|
427
315
|
mappings?: unknown;
|
|
@@ -432,6 +320,13 @@ export function createSqlFamilyInstance<TTargetId extends string>(
|
|
|
432
320
|
return contract;
|
|
433
321
|
}
|
|
434
322
|
|
|
323
|
+
function normalizeProviderContractIR(contract: unknown): ContractIR {
|
|
324
|
+
const contractWithoutMappings = stripMappings(contract);
|
|
325
|
+
const validated = validateContract<SqlContract<SqlStorage>>(contractWithoutMappings);
|
|
326
|
+
const { mappings: _mappings, ...contractIR } = validated;
|
|
327
|
+
return contractIR as ContractIR;
|
|
328
|
+
}
|
|
329
|
+
|
|
435
330
|
return {
|
|
436
331
|
familyId: 'sql',
|
|
437
332
|
operationRegistry,
|
|
@@ -441,12 +336,7 @@ export function createSqlFamilyInstance<TTargetId extends string>(
|
|
|
441
336
|
typeMetadataRegistry,
|
|
442
337
|
|
|
443
338
|
validateContractIR(contractJson: unknown): ContractIR {
|
|
444
|
-
|
|
445
|
-
const validated = validateContract<SqlContract<SqlStorage>>(contractJson);
|
|
446
|
-
// Strip mappings before returning ContractIR (mappings are runtime-only)
|
|
447
|
-
// The validated contract has all required ContractIR properties
|
|
448
|
-
const { mappings: _mappings, ...contractIR } = validated;
|
|
449
|
-
return contractIR as ContractIR;
|
|
339
|
+
return normalizeProviderContractIR(contractJson);
|
|
450
340
|
},
|
|
451
341
|
|
|
452
342
|
async verify(verifyOptions: {
|
|
@@ -459,40 +349,30 @@ export function createSqlFamilyInstance<TTargetId extends string>(
|
|
|
459
349
|
const { driver, contractIR, expectedTargetId, contractPath, configPath } = verifyOptions;
|
|
460
350
|
const startTime = Date.now();
|
|
461
351
|
|
|
462
|
-
// Type guard to ensure contract has required properties
|
|
463
352
|
if (
|
|
464
353
|
typeof contractIR !== 'object' ||
|
|
465
354
|
contractIR === null ||
|
|
466
|
-
!('
|
|
355
|
+
!('storageHash' in contractIR) ||
|
|
467
356
|
!('target' in contractIR) ||
|
|
468
|
-
typeof contractIR.
|
|
357
|
+
typeof contractIR.storageHash !== 'string' ||
|
|
469
358
|
typeof contractIR.target !== 'string'
|
|
470
359
|
) {
|
|
471
|
-
throw new Error('Contract is missing required fields:
|
|
360
|
+
throw new Error('Contract is missing required fields: storageHash or target');
|
|
472
361
|
}
|
|
473
362
|
|
|
474
|
-
|
|
475
|
-
const contractCoreHash = contractIR.coreHash;
|
|
363
|
+
const contractStorageHash = contractIR.storageHash;
|
|
476
364
|
const contractProfileHash =
|
|
477
365
|
'profileHash' in contractIR && typeof contractIR.profileHash === 'string'
|
|
478
366
|
? contractIR.profileHash
|
|
479
367
|
: undefined;
|
|
480
368
|
const contractTarget = contractIR.target;
|
|
481
369
|
|
|
482
|
-
// Read marker from database
|
|
483
370
|
const marker = await readMarker(driver);
|
|
484
371
|
|
|
485
|
-
// Compute codec coverage (optional)
|
|
486
372
|
let missingCodecs: readonly string[] | undefined;
|
|
487
373
|
let codecCoverageSkipped = false;
|
|
488
|
-
const supportedTypeIds = collectSupportedCodecTypeIds
|
|
489
|
-
adapter,
|
|
490
|
-
target,
|
|
491
|
-
...extensions,
|
|
492
|
-
]);
|
|
374
|
+
const supportedTypeIds = collectSupportedCodecTypeIds([adapter, target, ...extensions]);
|
|
493
375
|
if (supportedTypeIds.length === 0) {
|
|
494
|
-
// Helper is present but returns empty (MVP behavior)
|
|
495
|
-
// Coverage check is skipped - missingCodecs remains undefined
|
|
496
376
|
codecCoverageSkipped = true;
|
|
497
377
|
} else {
|
|
498
378
|
const supportedSet = new Set(supportedTypeIds);
|
|
@@ -503,14 +383,13 @@ export function createSqlFamilyInstance<TTargetId extends string>(
|
|
|
503
383
|
}
|
|
504
384
|
}
|
|
505
385
|
|
|
506
|
-
// Check marker presence
|
|
507
386
|
if (!marker) {
|
|
508
387
|
const totalTime = Date.now() - startTime;
|
|
509
388
|
return createVerifyResult({
|
|
510
389
|
ok: false,
|
|
511
|
-
code: 'PN-
|
|
390
|
+
code: 'PN-RUN-3001',
|
|
512
391
|
summary: 'Marker missing',
|
|
513
|
-
|
|
392
|
+
contractStorageHash,
|
|
514
393
|
expectedTargetId,
|
|
515
394
|
contractPath,
|
|
516
395
|
totalTime,
|
|
@@ -521,14 +400,13 @@ export function createSqlFamilyInstance<TTargetId extends string>(
|
|
|
521
400
|
});
|
|
522
401
|
}
|
|
523
402
|
|
|
524
|
-
// Compare target
|
|
525
403
|
if (contractTarget !== expectedTargetId) {
|
|
526
404
|
const totalTime = Date.now() - startTime;
|
|
527
405
|
return createVerifyResult({
|
|
528
406
|
ok: false,
|
|
529
|
-
code: 'PN-
|
|
407
|
+
code: 'PN-RUN-3003',
|
|
530
408
|
summary: 'Target mismatch',
|
|
531
|
-
|
|
409
|
+
contractStorageHash,
|
|
532
410
|
marker,
|
|
533
411
|
expectedTargetId,
|
|
534
412
|
actualTargetId: contractTarget,
|
|
@@ -541,14 +419,13 @@ export function createSqlFamilyInstance<TTargetId extends string>(
|
|
|
541
419
|
});
|
|
542
420
|
}
|
|
543
421
|
|
|
544
|
-
|
|
545
|
-
if (marker.coreHash !== contractCoreHash) {
|
|
422
|
+
if (marker.storageHash !== contractStorageHash) {
|
|
546
423
|
const totalTime = Date.now() - startTime;
|
|
547
424
|
return createVerifyResult({
|
|
548
425
|
ok: false,
|
|
549
|
-
code: 'PN-
|
|
426
|
+
code: 'PN-RUN-3002',
|
|
550
427
|
summary: 'Hash mismatch',
|
|
551
|
-
|
|
428
|
+
contractStorageHash,
|
|
552
429
|
marker,
|
|
553
430
|
expectedTargetId,
|
|
554
431
|
contractPath,
|
|
@@ -560,14 +437,13 @@ export function createSqlFamilyInstance<TTargetId extends string>(
|
|
|
560
437
|
});
|
|
561
438
|
}
|
|
562
439
|
|
|
563
|
-
// Compare profile hash if present
|
|
564
440
|
if (contractProfileHash && marker.profileHash !== contractProfileHash) {
|
|
565
441
|
const totalTime = Date.now() - startTime;
|
|
566
442
|
return createVerifyResult({
|
|
567
443
|
ok: false,
|
|
568
|
-
code: 'PN-
|
|
444
|
+
code: 'PN-RUN-3002',
|
|
569
445
|
summary: 'Hash mismatch',
|
|
570
|
-
|
|
446
|
+
contractStorageHash,
|
|
571
447
|
contractProfileHash,
|
|
572
448
|
marker,
|
|
573
449
|
expectedTargetId,
|
|
@@ -579,12 +455,11 @@ export function createSqlFamilyInstance<TTargetId extends string>(
|
|
|
579
455
|
});
|
|
580
456
|
}
|
|
581
457
|
|
|
582
|
-
// Success - all checks passed
|
|
583
458
|
const totalTime = Date.now() - startTime;
|
|
584
459
|
return createVerifyResult({
|
|
585
460
|
ok: true,
|
|
586
461
|
summary: 'Database matches contract',
|
|
587
|
-
|
|
462
|
+
contractStorageHash,
|
|
588
463
|
marker,
|
|
589
464
|
expectedTargetId,
|
|
590
465
|
contractPath,
|
|
@@ -599,17 +474,14 @@ export function createSqlFamilyInstance<TTargetId extends string>(
|
|
|
599
474
|
async schemaVerify(options: SchemaVerifyOptions): Promise<VerifyDatabaseSchemaResult> {
|
|
600
475
|
const { driver, contractIR, strict, context, frameworkComponents } = options;
|
|
601
476
|
|
|
602
|
-
// Validate contractIR as SqlContract<SqlStorage>
|
|
603
477
|
const contract = validateContract<SqlContract<SqlStorage>>(contractIR);
|
|
604
478
|
|
|
605
|
-
// Introspect live schema (DB I/O)
|
|
606
479
|
const controlAdapter = adapter.create();
|
|
607
480
|
if (!isSqlControlAdapter(controlAdapter)) {
|
|
608
481
|
throw new Error('Adapter does not implement SqlControlAdapter.introspect()');
|
|
609
482
|
}
|
|
610
483
|
const schemaIR = await controlAdapter.introspect(driver, contractIR);
|
|
611
484
|
|
|
612
|
-
// Pure verification (no I/O) - delegates to extracted pure function
|
|
613
485
|
return verifySqlSchema({
|
|
614
486
|
contract,
|
|
615
487
|
schema: schemaIR,
|
|
@@ -617,6 +489,9 @@ export function createSqlFamilyInstance<TTargetId extends string>(
|
|
|
617
489
|
...ifDefined('context', context),
|
|
618
490
|
typeMetadataRegistry,
|
|
619
491
|
frameworkComponents,
|
|
492
|
+
// Wire up target-specific normalizers if available
|
|
493
|
+
...ifDefined('normalizeDefault', controlAdapter.normalizeDefault),
|
|
494
|
+
...ifDefined('normalizeNativeType', controlAdapter.normalizeNativeType),
|
|
620
495
|
});
|
|
621
496
|
},
|
|
622
497
|
async sign(options: {
|
|
@@ -628,33 +503,27 @@ export function createSqlFamilyInstance<TTargetId extends string>(
|
|
|
628
503
|
const { driver, contractIR, contractPath, configPath } = options;
|
|
629
504
|
const startTime = Date.now();
|
|
630
505
|
|
|
631
|
-
// Validate contractIR as SqlContract<SqlStorage>
|
|
632
506
|
const contract = validateContract<SqlContract<SqlStorage>>(contractIR);
|
|
633
507
|
|
|
634
|
-
|
|
635
|
-
const contractCoreHash = contract.coreHash;
|
|
508
|
+
const contractStorageHash = contract.storageHash;
|
|
636
509
|
const contractProfileHash =
|
|
637
510
|
'profileHash' in contract && typeof contract.profileHash === 'string'
|
|
638
511
|
? contract.profileHash
|
|
639
|
-
:
|
|
512
|
+
: contractStorageHash;
|
|
640
513
|
const contractTarget = contract.target;
|
|
641
514
|
|
|
642
|
-
// Ensure marker schema and table exist
|
|
643
515
|
await driver.query(ensureSchemaStatement.sql, ensureSchemaStatement.params);
|
|
644
516
|
await driver.query(ensureTableStatement.sql, ensureTableStatement.params);
|
|
645
517
|
|
|
646
|
-
// Read existing marker
|
|
647
518
|
const existingMarker = await readMarker(driver);
|
|
648
519
|
|
|
649
|
-
// Determine if we need to write/update marker
|
|
650
520
|
let markerCreated = false;
|
|
651
521
|
let markerUpdated = false;
|
|
652
|
-
let previousHashes: {
|
|
522
|
+
let previousHashes: { storageHash?: string; profileHash?: string } | undefined;
|
|
653
523
|
|
|
654
524
|
if (!existingMarker) {
|
|
655
|
-
// No marker exists - insert new one
|
|
656
525
|
const write = writeContractMarker({
|
|
657
|
-
|
|
526
|
+
storageHash: contractStorageHash,
|
|
658
527
|
profileHash: contractProfileHash,
|
|
659
528
|
contractJson: contractIR,
|
|
660
529
|
canonicalVersion: 1,
|
|
@@ -662,22 +531,19 @@ export function createSqlFamilyInstance<TTargetId extends string>(
|
|
|
662
531
|
await driver.query(write.insert.sql, write.insert.params);
|
|
663
532
|
markerCreated = true;
|
|
664
533
|
} else {
|
|
665
|
-
|
|
666
|
-
const existingCoreHash = existingMarker.coreHash;
|
|
534
|
+
const existingStorageHash = existingMarker.storageHash;
|
|
667
535
|
const existingProfileHash = existingMarker.profileHash;
|
|
668
536
|
|
|
669
|
-
|
|
670
|
-
const coreHashMatches = existingCoreHash === contractCoreHash;
|
|
537
|
+
const storageHashMatches = existingStorageHash === contractStorageHash;
|
|
671
538
|
const profileHashMatches = existingProfileHash === contractProfileHash;
|
|
672
539
|
|
|
673
|
-
if (!
|
|
674
|
-
// Hashes differ - update marker and capture previous hashes for output
|
|
540
|
+
if (!storageHashMatches || !profileHashMatches) {
|
|
675
541
|
previousHashes = {
|
|
676
|
-
|
|
542
|
+
storageHash: existingStorageHash,
|
|
677
543
|
profileHash: existingProfileHash,
|
|
678
544
|
};
|
|
679
545
|
const write = writeContractMarker({
|
|
680
|
-
|
|
546
|
+
storageHash: contractStorageHash,
|
|
681
547
|
profileHash: contractProfileHash,
|
|
682
548
|
contractJson: contractIR,
|
|
683
549
|
canonicalVersion: existingMarker.canonicalVersion ?? 1,
|
|
@@ -685,15 +551,13 @@ export function createSqlFamilyInstance<TTargetId extends string>(
|
|
|
685
551
|
await driver.query(write.update.sql, write.update.params);
|
|
686
552
|
markerUpdated = true;
|
|
687
553
|
}
|
|
688
|
-
// If hashes match, no-op (idempotent) - previousHashes remains undefined
|
|
689
554
|
}
|
|
690
555
|
|
|
691
|
-
// Build summary message
|
|
692
556
|
let summary: string;
|
|
693
557
|
if (markerCreated) {
|
|
694
558
|
summary = 'Database signed (marker created)';
|
|
695
559
|
} else if (markerUpdated) {
|
|
696
|
-
summary = `Database signed (marker updated from ${previousHashes?.
|
|
560
|
+
summary = `Database signed (marker updated from ${previousHashes?.storageHash ?? 'unknown'})`;
|
|
697
561
|
} else {
|
|
698
562
|
summary = 'Database already signed with this contract';
|
|
699
563
|
}
|
|
@@ -704,7 +568,7 @@ export function createSqlFamilyInstance<TTargetId extends string>(
|
|
|
704
568
|
ok: true,
|
|
705
569
|
summary,
|
|
706
570
|
contract: {
|
|
707
|
-
|
|
571
|
+
storageHash: contractStorageHash,
|
|
708
572
|
profileHash: contractProfileHash,
|
|
709
573
|
},
|
|
710
574
|
target: {
|
|
@@ -746,18 +610,15 @@ export function createSqlFamilyInstance<TTargetId extends string>(
|
|
|
746
610
|
toSchemaView(schema: SqlSchemaIR): CoreSchemaView {
|
|
747
611
|
const rootLabel = 'contract';
|
|
748
612
|
|
|
749
|
-
// Build table nodes
|
|
750
613
|
const tableNodes: readonly SchemaTreeNode[] = Object.entries(schema.tables).map(
|
|
751
614
|
([tableName, table]: [string, SqlTableIR]) => {
|
|
752
615
|
const children: SchemaTreeNode[] = [];
|
|
753
616
|
|
|
754
|
-
// Add column nodes grouped under "columns"
|
|
755
617
|
const columnNodes: SchemaTreeNode[] = [];
|
|
756
618
|
for (const [columnName, column] of Object.entries(table.columns)) {
|
|
757
|
-
const nullableText = column.nullable ? '(nullable)' : '(not nullable)';
|
|
758
|
-
// Always display nativeType for introspection (database state)
|
|
759
619
|
const typeDisplay = column.nativeType;
|
|
760
|
-
const
|
|
620
|
+
const nullability = column.nullable ? 'nullable' : 'not nullable';
|
|
621
|
+
const label = `${columnName}: ${typeDisplay} (${nullability})`;
|
|
761
622
|
columnNodes.push({
|
|
762
623
|
kind: 'field',
|
|
763
624
|
id: `column-${tableName}-${columnName}`,
|
|
@@ -765,11 +626,11 @@ export function createSqlFamilyInstance<TTargetId extends string>(
|
|
|
765
626
|
meta: {
|
|
766
627
|
nativeType: column.nativeType,
|
|
767
628
|
nullable: column.nullable,
|
|
629
|
+
...ifDefined('default', column.default),
|
|
768
630
|
},
|
|
769
631
|
});
|
|
770
632
|
}
|
|
771
633
|
|
|
772
|
-
// Add "columns" grouping node if there are columns
|
|
773
634
|
if (columnNodes.length > 0) {
|
|
774
635
|
children.push({
|
|
775
636
|
kind: 'collection',
|
|
@@ -779,7 +640,6 @@ export function createSqlFamilyInstance<TTargetId extends string>(
|
|
|
779
640
|
});
|
|
780
641
|
}
|
|
781
642
|
|
|
782
|
-
// Add primary key node if present
|
|
783
643
|
if (table.primaryKey) {
|
|
784
644
|
const pkColumns = table.primaryKey.columns.join(', ');
|
|
785
645
|
children.push({
|
|
@@ -793,7 +653,6 @@ export function createSqlFamilyInstance<TTargetId extends string>(
|
|
|
793
653
|
});
|
|
794
654
|
}
|
|
795
655
|
|
|
796
|
-
// Add unique constraint nodes
|
|
797
656
|
for (const unique of table.uniques) {
|
|
798
657
|
const name = unique.name ?? `${tableName}_${unique.columns.join('_')}_unique`;
|
|
799
658
|
const label = `unique ${name}`;
|
|
@@ -808,9 +667,8 @@ export function createSqlFamilyInstance<TTargetId extends string>(
|
|
|
808
667
|
});
|
|
809
668
|
}
|
|
810
669
|
|
|
811
|
-
// Add index nodes
|
|
812
670
|
for (const index of table.indexes) {
|
|
813
|
-
const name = index.name ??
|
|
671
|
+
const name = index.name ?? defaultIndexName(tableName, index.columns);
|
|
814
672
|
const label = index.unique ? `unique index ${name}` : `index ${name}`;
|
|
815
673
|
children.push({
|
|
816
674
|
kind: 'index',
|
|
@@ -823,7 +681,6 @@ export function createSqlFamilyInstance<TTargetId extends string>(
|
|
|
823
681
|
});
|
|
824
682
|
}
|
|
825
683
|
|
|
826
|
-
// Build table meta
|
|
827
684
|
const tableMeta: Record<string, unknown> = {};
|
|
828
685
|
if (table.primaryKey) {
|
|
829
686
|
tableMeta['primaryKey'] = table.primaryKey.columns;
|
|
@@ -851,15 +708,16 @@ export function createSqlFamilyInstance<TTargetId extends string>(
|
|
|
851
708
|
},
|
|
852
709
|
);
|
|
853
710
|
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
711
|
+
const dependencyNodes: readonly SchemaTreeNode[] = schema.dependencies.map((dep) => {
|
|
712
|
+
const shortName = dep.id.split('.').pop() ?? dep.id;
|
|
713
|
+
return {
|
|
714
|
+
kind: 'dependency',
|
|
715
|
+
id: `dependency-${dep.id}`,
|
|
716
|
+
label: `${shortName} dependency is installed`,
|
|
717
|
+
};
|
|
718
|
+
});
|
|
860
719
|
|
|
861
|
-
|
|
862
|
-
const rootChildren = [...tableNodes, ...extensionNodes];
|
|
720
|
+
const rootChildren = [...tableNodes, ...dependencyNodes];
|
|
863
721
|
|
|
864
722
|
const rootNode: SchemaTreeNode = {
|
|
865
723
|
kind: 'root',
|
|
@@ -874,20 +732,19 @@ export function createSqlFamilyInstance<TTargetId extends string>(
|
|
|
874
732
|
},
|
|
875
733
|
|
|
876
734
|
async emitContract({ contractIR }): Promise<EmitContractResult> {
|
|
877
|
-
|
|
878
|
-
const contractWithoutMappings = stripMappings(contractIR);
|
|
879
|
-
|
|
880
|
-
// Validate and normalize the contract
|
|
881
|
-
const validatedIR = this.validateContractIR(contractWithoutMappings);
|
|
735
|
+
const normalizedIR = normalizeProviderContractIR(contractIR);
|
|
882
736
|
|
|
883
737
|
const result = await emit(
|
|
884
|
-
|
|
738
|
+
normalizedIR,
|
|
885
739
|
{
|
|
886
740
|
outputDir: '',
|
|
887
741
|
operationRegistry,
|
|
888
742
|
codecTypeImports,
|
|
889
743
|
operationTypeImports,
|
|
744
|
+
queryOperationTypeImports,
|
|
890
745
|
extensionIds,
|
|
746
|
+
parameterizedRenderers,
|
|
747
|
+
parameterizedTypeImports,
|
|
891
748
|
},
|
|
892
749
|
sqlTargetFamilyHook,
|
|
893
750
|
);
|
|
@@ -895,7 +752,8 @@ export function createSqlFamilyInstance<TTargetId extends string>(
|
|
|
895
752
|
return {
|
|
896
753
|
contractJson: result.contractJson,
|
|
897
754
|
contractDts: result.contractDts,
|
|
898
|
-
|
|
755
|
+
storageHash: result.storageHash,
|
|
756
|
+
...(result.executionHash ? { executionHash: result.executionHash } : {}),
|
|
899
757
|
profileHash: result.profileHash,
|
|
900
758
|
};
|
|
901
759
|
},
|