@prisma-next/family-sql 0.1.0-pr.64.2 → 0.1.0-pr.65.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.
@@ -0,0 +1,62 @@
1
+ // src/core/assembly.ts
2
+ import { createOperationRegistry } from "@prisma-next/operations";
3
+ function assembleOperationRegistry(descriptors, convertOperationManifest) {
4
+ const registry = createOperationRegistry();
5
+ for (const descriptor of descriptors) {
6
+ const operations = descriptor.operations ?? [];
7
+ for (const operationManifest of operations) {
8
+ const signature = convertOperationManifest(operationManifest);
9
+ registry.register(signature);
10
+ }
11
+ }
12
+ return registry;
13
+ }
14
+ function extractCodecTypeImports(descriptors) {
15
+ const imports = [];
16
+ for (const descriptor of descriptors) {
17
+ const types = descriptor.types;
18
+ const codecTypes = types?.codecTypes;
19
+ if (codecTypes?.import) {
20
+ imports.push(codecTypes.import);
21
+ }
22
+ }
23
+ return imports;
24
+ }
25
+ function extractOperationTypeImports(descriptors) {
26
+ const imports = [];
27
+ for (const descriptor of descriptors) {
28
+ const types = descriptor.types;
29
+ const operationTypes = types?.operationTypes;
30
+ if (operationTypes?.import) {
31
+ imports.push(operationTypes.import);
32
+ }
33
+ }
34
+ return imports;
35
+ }
36
+ function extractExtensionIds(adapter, target, extensions) {
37
+ const ids = [];
38
+ const seen = /* @__PURE__ */ new Set();
39
+ if (!seen.has(adapter.id)) {
40
+ ids.push(adapter.id);
41
+ seen.add(adapter.id);
42
+ }
43
+ if (!seen.has(target.id)) {
44
+ ids.push(target.id);
45
+ seen.add(target.id);
46
+ }
47
+ for (const ext of extensions) {
48
+ if (!seen.has(ext.id)) {
49
+ ids.push(ext.id);
50
+ seen.add(ext.id);
51
+ }
52
+ }
53
+ return ids;
54
+ }
55
+
56
+ export {
57
+ assembleOperationRegistry,
58
+ extractCodecTypeImports,
59
+ extractOperationTypeImports,
60
+ extractExtensionIds
61
+ };
62
+ //# sourceMappingURL=chunk-PVUVID3J.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/core/assembly.ts"],"sourcesContent":["import type { OperationManifest } from '@prisma-next/contract/pack-manifest-types';\nimport type { TypesImportSpec } from '@prisma-next/contract/types';\nimport type {\n ControlAdapterDescriptor,\n ControlExtensionDescriptor,\n ControlTargetDescriptor,\n} from '@prisma-next/core-control-plane/types';\nimport type { OperationRegistry, OperationSignature } from '@prisma-next/operations';\nimport { createOperationRegistry } from '@prisma-next/operations';\n\n/**\n * Assembles an operation registry from descriptors (adapter, target, extensions).\n * Loops over descriptors, extracts operations, converts them using the provided\n * conversion function, and registers them in a new registry.\n */\nexport function assembleOperationRegistry(\n descriptors: ReadonlyArray<\n | ControlTargetDescriptor<'sql', string>\n | ControlAdapterDescriptor<'sql', string>\n | ControlExtensionDescriptor<'sql', string>\n >,\n convertOperationManifest: (manifest: OperationManifest) => OperationSignature,\n): OperationRegistry {\n const registry = createOperationRegistry();\n\n for (const descriptor of descriptors) {\n const operations = descriptor.operations ?? [];\n for (const operationManifest of operations as ReadonlyArray<OperationManifest>) {\n const signature = convertOperationManifest(operationManifest);\n registry.register(signature);\n }\n }\n\n return registry;\n}\n\n/**\n * Extracts codec type imports from descriptors for contract.d.ts generation.\n */\nexport function extractCodecTypeImports(\n descriptors: ReadonlyArray<\n | ControlTargetDescriptor<'sql', string>\n | ControlAdapterDescriptor<'sql', string>\n | ControlExtensionDescriptor<'sql', string>\n >,\n): ReadonlyArray<TypesImportSpec> {\n const imports: TypesImportSpec[] = [];\n\n for (const descriptor of descriptors) {\n const types = descriptor.types;\n const codecTypes = types?.codecTypes;\n if (codecTypes?.import) {\n imports.push(codecTypes.import);\n }\n }\n\n return imports;\n}\n\n/**\n * Extracts operation type imports from descriptors for contract.d.ts generation.\n */\nexport function extractOperationTypeImports(\n descriptors: ReadonlyArray<\n | ControlTargetDescriptor<'sql', string>\n | ControlAdapterDescriptor<'sql', string>\n | ControlExtensionDescriptor<'sql', string>\n >,\n): ReadonlyArray<TypesImportSpec> {\n const imports: TypesImportSpec[] = [];\n\n for (const descriptor of descriptors) {\n const types = descriptor.types;\n const operationTypes = types?.operationTypes;\n if (operationTypes?.import) {\n imports.push(operationTypes.import);\n }\n }\n\n return imports;\n}\n\n/**\n * Extracts extension IDs from descriptors in deterministic order:\n * [adapter.id, target.id, ...extensions.map(e => e.id)]\n * Deduplicates while preserving stable order.\n */\nexport function extractExtensionIds(\n adapter: ControlAdapterDescriptor<'sql', string>,\n target: ControlTargetDescriptor<'sql', string>,\n extensions: ReadonlyArray<ControlExtensionDescriptor<'sql', string>>,\n): ReadonlyArray<string> {\n const ids: string[] = [];\n const seen = new Set<string>();\n\n // Add adapter first\n if (!seen.has(adapter.id)) {\n ids.push(adapter.id);\n seen.add(adapter.id);\n }\n\n // Add target second\n if (!seen.has(target.id)) {\n ids.push(target.id);\n seen.add(target.id);\n }\n\n // Add extensions in order\n for (const ext of extensions) {\n if (!seen.has(ext.id)) {\n ids.push(ext.id);\n seen.add(ext.id);\n }\n }\n\n return ids;\n}\n"],"mappings":";AAQA,SAAS,+BAA+B;AAOjC,SAAS,0BACd,aAKA,0BACmB;AACnB,QAAM,WAAW,wBAAwB;AAEzC,aAAW,cAAc,aAAa;AACpC,UAAM,aAAa,WAAW,cAAc,CAAC;AAC7C,eAAW,qBAAqB,YAAgD;AAC9E,YAAM,YAAY,yBAAyB,iBAAiB;AAC5D,eAAS,SAAS,SAAS;AAAA,IAC7B;AAAA,EACF;AAEA,SAAO;AACT;AAKO,SAAS,wBACd,aAKgC;AAChC,QAAM,UAA6B,CAAC;AAEpC,aAAW,cAAc,aAAa;AACpC,UAAM,QAAQ,WAAW;AACzB,UAAM,aAAa,OAAO;AAC1B,QAAI,YAAY,QAAQ;AACtB,cAAQ,KAAK,WAAW,MAAM;AAAA,IAChC;AAAA,EACF;AAEA,SAAO;AACT;AAKO,SAAS,4BACd,aAKgC;AAChC,QAAM,UAA6B,CAAC;AAEpC,aAAW,cAAc,aAAa;AACpC,UAAM,QAAQ,WAAW;AACzB,UAAM,iBAAiB,OAAO;AAC9B,QAAI,gBAAgB,QAAQ;AAC1B,cAAQ,KAAK,eAAe,MAAM;AAAA,IACpC;AAAA,EACF;AAEA,SAAO;AACT;AAOO,SAAS,oBACd,SACA,QACA,YACuB;AACvB,QAAM,MAAgB,CAAC;AACvB,QAAM,OAAO,oBAAI,IAAY;AAG7B,MAAI,CAAC,KAAK,IAAI,QAAQ,EAAE,GAAG;AACzB,QAAI,KAAK,QAAQ,EAAE;AACnB,SAAK,IAAI,QAAQ,EAAE;AAAA,EACrB;AAGA,MAAI,CAAC,KAAK,IAAI,OAAO,EAAE,GAAG;AACxB,QAAI,KAAK,OAAO,EAAE;AAClB,SAAK,IAAI,OAAO,EAAE;AAAA,EACpB;AAGA,aAAW,OAAO,YAAY;AAC5B,QAAI,CAAC,KAAK,IAAI,IAAI,EAAE,GAAG;AACrB,UAAI,KAAK,IAAI,EAAE;AACf,WAAK,IAAI,IAAI,EAAE;AAAA,IACjB;AAAA,EACF;AAEA,SAAO;AACT;","names":[]}
@@ -1,5 +1,4 @@
1
1
  import { OperationRegistry } from '@prisma-next/operations';
2
- import { ExtensionPackManifest } from '@prisma-next/contract/pack-manifest-types';
3
2
  import { ControlFamilyDescriptor, ControlAdapterDescriptor, ControlDriverDescriptor, ControlExtensionDescriptor, MigrationOperationPolicy } from '@prisma-next/core-control-plane/types';
4
3
  export { MigrationOperationClass, MigrationOperationPolicy, MigrationPlan, MigrationPlanOperation, MigrationPlanner, MigrationPlannerConflict, MigrationPlannerResult, TargetMigrationsCapability } from '@prisma-next/core-control-plane/types';
5
4
  import { SqlControlAdapter } from './control-adapter.js';
@@ -111,7 +110,7 @@ declare class SqlFamilyDescriptor implements ControlFamilyDescriptor<'sql', SqlC
111
110
  readonly kind: "family";
112
111
  readonly id = "sql";
113
112
  readonly familyId: "sql";
114
- readonly manifest: ExtensionPackManifest;
113
+ readonly version = "0.0.1";
115
114
  readonly hook: {
116
115
  readonly id: "sql";
117
116
  readonly validateTypes: (ir: ContractIR, _ctx: ValidationContext) => void;
@@ -1,21 +1,531 @@
1
1
  import {
2
- createSqlFamilyInstance
3
- } from "./chunk-RVUPZUZP.js";
4
- import "./chunk-C3GKWCKA.js";
5
- import "./chunk-UKUAX2QM.js";
2
+ collectSupportedCodecTypeIds,
3
+ readMarker
4
+ } from "./chunk-C3GKWCKA.js";
5
+ import {
6
+ assembleOperationRegistry,
7
+ extractCodecTypeImports,
8
+ extractExtensionIds,
9
+ extractOperationTypeImports
10
+ } from "./chunk-PVUVID3J.js";
11
+ import {
12
+ verifySqlSchema
13
+ } from "./chunk-UKUAX2QM.js";
6
14
 
7
15
  // src/core/descriptor.ts
16
+ import { sqlTargetFamilyHook as sqlTargetFamilyHook2 } from "@prisma-next/sql-contract-emitter";
17
+
18
+ // src/core/instance.ts
19
+ import { emit } from "@prisma-next/core-control-plane/emission";
8
20
  import { sqlTargetFamilyHook } from "@prisma-next/sql-contract-emitter";
9
- var sqlFamilyManifest = {
10
- id: "sql",
11
- version: "0.0.1"
12
- };
21
+ import { validateContract } from "@prisma-next/sql-contract-ts/contract";
22
+ import {
23
+ ensureSchemaStatement,
24
+ ensureTableStatement,
25
+ writeContractMarker
26
+ } from "@prisma-next/sql-runtime";
27
+ import { ifDefined } from "@prisma-next/utils/defined";
28
+ function convertOperationManifest(manifest) {
29
+ return {
30
+ forTypeId: manifest.for,
31
+ method: manifest.method,
32
+ args: manifest.args.map((arg) => {
33
+ if (arg.kind === "typeId") {
34
+ if (!arg.type) {
35
+ throw new Error("typeId arg must have type property");
36
+ }
37
+ return { kind: "typeId", type: arg.type };
38
+ }
39
+ if (arg.kind === "param") {
40
+ return { kind: "param" };
41
+ }
42
+ if (arg.kind === "literal") {
43
+ return { kind: "literal" };
44
+ }
45
+ throw new Error(`Invalid arg kind: ${arg.kind}`);
46
+ }),
47
+ returns: (() => {
48
+ if (manifest.returns.kind === "typeId") {
49
+ return { kind: "typeId", type: manifest.returns.type };
50
+ }
51
+ if (manifest.returns.kind === "builtin") {
52
+ return {
53
+ kind: "builtin",
54
+ type: manifest.returns.type
55
+ };
56
+ }
57
+ throw new Error(`Invalid return kind: ${manifest.returns.kind}`);
58
+ })(),
59
+ lowering: {
60
+ targetFamily: "sql",
61
+ strategy: manifest.lowering.strategy,
62
+ template: manifest.lowering.template
63
+ },
64
+ ...manifest.capabilities ? { capabilities: manifest.capabilities } : {}
65
+ };
66
+ }
67
+ function extractCodecTypeIdsFromContract(contract) {
68
+ const typeIds = /* @__PURE__ */ new Set();
69
+ if (typeof contract === "object" && contract !== null && "storage" in contract && typeof contract.storage === "object" && contract.storage !== null && "tables" in contract.storage) {
70
+ const storage = contract.storage;
71
+ if (storage.tables && typeof storage.tables === "object") {
72
+ for (const table of Object.values(storage.tables)) {
73
+ if (typeof table === "object" && table !== null && "columns" in table && typeof table.columns === "object" && table.columns !== null) {
74
+ const columns = table.columns;
75
+ for (const column of Object.values(columns)) {
76
+ if (column && typeof column === "object" && "codecId" in column && typeof column.codecId === "string") {
77
+ typeIds.add(column.codecId);
78
+ }
79
+ }
80
+ }
81
+ }
82
+ }
83
+ }
84
+ return Array.from(typeIds).sort();
85
+ }
86
+ function createVerifyResult(options) {
87
+ const contract = {
88
+ coreHash: options.contractCoreHash
89
+ };
90
+ if (options.contractProfileHash) {
91
+ contract.profileHash = options.contractProfileHash;
92
+ }
93
+ const target = {
94
+ expected: options.expectedTargetId
95
+ };
96
+ if (options.actualTargetId) {
97
+ target.actual = options.actualTargetId;
98
+ }
99
+ const meta = {
100
+ contractPath: options.contractPath
101
+ };
102
+ if (options.configPath) {
103
+ meta.configPath = options.configPath;
104
+ }
105
+ const result = {
106
+ ok: options.ok,
107
+ summary: options.summary,
108
+ contract,
109
+ target,
110
+ meta,
111
+ timings: {
112
+ total: options.totalTime
113
+ }
114
+ };
115
+ if (options.code) {
116
+ result.code = options.code;
117
+ }
118
+ if (options.marker) {
119
+ result.marker = {
120
+ coreHash: options.marker.coreHash,
121
+ profileHash: options.marker.profileHash
122
+ };
123
+ }
124
+ if (options.missingCodecs) {
125
+ result.missingCodecs = options.missingCodecs;
126
+ }
127
+ if (options.codecCoverageSkipped) {
128
+ result.codecCoverageSkipped = options.codecCoverageSkipped;
129
+ }
130
+ return result;
131
+ }
132
+ function buildSqlTypeMetadataRegistry(options) {
133
+ const { target, adapter, extensions } = options;
134
+ const registry = /* @__PURE__ */ new Map();
135
+ const targetId = adapter.targetId;
136
+ const descriptors = [target, adapter, ...extensions];
137
+ for (const descriptor of descriptors) {
138
+ const types = descriptor.types;
139
+ const storageTypes = types?.storage;
140
+ if (!storageTypes) {
141
+ continue;
142
+ }
143
+ for (const storageType of storageTypes) {
144
+ if (storageType.familyId === "sql" && storageType.targetId === targetId) {
145
+ registry.set(storageType.typeId, {
146
+ typeId: storageType.typeId,
147
+ familyId: "sql",
148
+ targetId: storageType.targetId,
149
+ ...storageType.nativeType !== void 0 ? { nativeType: storageType.nativeType } : {}
150
+ });
151
+ }
152
+ }
153
+ }
154
+ return registry;
155
+ }
156
+ function createSqlFamilyInstance(options) {
157
+ const { target, adapter, extensions } = options;
158
+ const descriptors = [target, adapter, ...extensions];
159
+ const operationRegistry = assembleOperationRegistry(descriptors, convertOperationManifest);
160
+ const codecTypeImports = extractCodecTypeImports(descriptors);
161
+ const operationTypeImports = extractOperationTypeImports(descriptors);
162
+ const extensionIds = extractExtensionIds(adapter, target, extensions);
163
+ const typeMetadataRegistry = buildSqlTypeMetadataRegistry({ target, adapter, extensions });
164
+ function stripMappings(contract) {
165
+ if (typeof contract === "object" && contract !== null && "mappings" in contract) {
166
+ const { mappings: _mappings, ...contractIR } = contract;
167
+ return contractIR;
168
+ }
169
+ return contract;
170
+ }
171
+ return {
172
+ familyId: "sql",
173
+ operationRegistry,
174
+ codecTypeImports,
175
+ operationTypeImports,
176
+ extensionIds,
177
+ typeMetadataRegistry,
178
+ validateContractIR(contractJson) {
179
+ const validated = validateContract(contractJson);
180
+ const { mappings: _mappings, ...contractIR } = validated;
181
+ return contractIR;
182
+ },
183
+ async verify(verifyOptions) {
184
+ const { driver, contractIR, expectedTargetId, contractPath, configPath } = verifyOptions;
185
+ const startTime = Date.now();
186
+ if (typeof contractIR !== "object" || contractIR === null || !("coreHash" in contractIR) || !("target" in contractIR) || typeof contractIR.coreHash !== "string" || typeof contractIR.target !== "string") {
187
+ throw new Error("Contract is missing required fields: coreHash or target");
188
+ }
189
+ const contractCoreHash = contractIR.coreHash;
190
+ const contractProfileHash = "profileHash" in contractIR && typeof contractIR.profileHash === "string" ? contractIR.profileHash : void 0;
191
+ const contractTarget = contractIR.target;
192
+ const marker = await readMarker(driver);
193
+ let missingCodecs;
194
+ let codecCoverageSkipped = false;
195
+ const supportedTypeIds = collectSupportedCodecTypeIds([
196
+ adapter,
197
+ target,
198
+ ...extensions
199
+ ]);
200
+ if (supportedTypeIds.length === 0) {
201
+ codecCoverageSkipped = true;
202
+ } else {
203
+ const supportedSet = new Set(supportedTypeIds);
204
+ const usedTypeIds = extractCodecTypeIdsFromContract(contractIR);
205
+ const missing = usedTypeIds.filter((id) => !supportedSet.has(id));
206
+ if (missing.length > 0) {
207
+ missingCodecs = missing;
208
+ }
209
+ }
210
+ if (!marker) {
211
+ const totalTime2 = Date.now() - startTime;
212
+ return createVerifyResult({
213
+ ok: false,
214
+ code: "PN-RTM-3001",
215
+ summary: "Marker missing",
216
+ contractCoreHash,
217
+ expectedTargetId,
218
+ contractPath,
219
+ totalTime: totalTime2,
220
+ ...contractProfileHash ? { contractProfileHash } : {},
221
+ ...missingCodecs ? { missingCodecs } : {},
222
+ ...codecCoverageSkipped ? { codecCoverageSkipped } : {},
223
+ ...configPath ? { configPath } : {}
224
+ });
225
+ }
226
+ if (contractTarget !== expectedTargetId) {
227
+ const totalTime2 = Date.now() - startTime;
228
+ return createVerifyResult({
229
+ ok: false,
230
+ code: "PN-RTM-3003",
231
+ summary: "Target mismatch",
232
+ contractCoreHash,
233
+ marker,
234
+ expectedTargetId,
235
+ actualTargetId: contractTarget,
236
+ contractPath,
237
+ totalTime: totalTime2,
238
+ ...contractProfileHash ? { contractProfileHash } : {},
239
+ ...missingCodecs ? { missingCodecs } : {},
240
+ ...codecCoverageSkipped ? { codecCoverageSkipped } : {},
241
+ ...configPath ? { configPath } : {}
242
+ });
243
+ }
244
+ if (marker.coreHash !== contractCoreHash) {
245
+ const totalTime2 = Date.now() - startTime;
246
+ return createVerifyResult({
247
+ ok: false,
248
+ code: "PN-RTM-3002",
249
+ summary: "Hash mismatch",
250
+ contractCoreHash,
251
+ marker,
252
+ expectedTargetId,
253
+ contractPath,
254
+ totalTime: totalTime2,
255
+ ...contractProfileHash ? { contractProfileHash } : {},
256
+ ...missingCodecs ? { missingCodecs } : {},
257
+ ...codecCoverageSkipped ? { codecCoverageSkipped } : {},
258
+ ...configPath ? { configPath } : {}
259
+ });
260
+ }
261
+ if (contractProfileHash && marker.profileHash !== contractProfileHash) {
262
+ const totalTime2 = Date.now() - startTime;
263
+ return createVerifyResult({
264
+ ok: false,
265
+ code: "PN-RTM-3002",
266
+ summary: "Hash mismatch",
267
+ contractCoreHash,
268
+ contractProfileHash,
269
+ marker,
270
+ expectedTargetId,
271
+ contractPath,
272
+ totalTime: totalTime2,
273
+ ...missingCodecs ? { missingCodecs } : {},
274
+ ...codecCoverageSkipped ? { codecCoverageSkipped } : {},
275
+ ...configPath ? { configPath } : {}
276
+ });
277
+ }
278
+ const totalTime = Date.now() - startTime;
279
+ return createVerifyResult({
280
+ ok: true,
281
+ summary: "Database matches contract",
282
+ contractCoreHash,
283
+ marker,
284
+ expectedTargetId,
285
+ contractPath,
286
+ totalTime,
287
+ ...contractProfileHash ? { contractProfileHash } : {},
288
+ ...missingCodecs ? { missingCodecs } : {},
289
+ ...codecCoverageSkipped ? { codecCoverageSkipped } : {},
290
+ ...configPath ? { configPath } : {}
291
+ });
292
+ },
293
+ async schemaVerify(options2) {
294
+ const { driver, contractIR, strict, context, frameworkComponents } = options2;
295
+ const contract = validateContract(contractIR);
296
+ const controlAdapter = adapter.create();
297
+ const schemaIR = await controlAdapter.introspect(driver, contractIR);
298
+ return verifySqlSchema({
299
+ contract,
300
+ schema: schemaIR,
301
+ strict,
302
+ ...ifDefined("context", context),
303
+ typeMetadataRegistry,
304
+ frameworkComponents
305
+ });
306
+ },
307
+ async sign(options2) {
308
+ const { driver, contractIR, contractPath, configPath } = options2;
309
+ const startTime = Date.now();
310
+ const contract = validateContract(contractIR);
311
+ const contractCoreHash = contract.coreHash;
312
+ const contractProfileHash = "profileHash" in contract && typeof contract.profileHash === "string" ? contract.profileHash : contractCoreHash;
313
+ const contractTarget = contract.target;
314
+ await driver.query(ensureSchemaStatement.sql, ensureSchemaStatement.params);
315
+ await driver.query(ensureTableStatement.sql, ensureTableStatement.params);
316
+ const existingMarker = await readMarker(driver);
317
+ let markerCreated = false;
318
+ let markerUpdated = false;
319
+ let previousHashes;
320
+ if (!existingMarker) {
321
+ const write = writeContractMarker({
322
+ coreHash: contractCoreHash,
323
+ profileHash: contractProfileHash,
324
+ contractJson: contractIR,
325
+ canonicalVersion: 1
326
+ });
327
+ await driver.query(write.insert.sql, write.insert.params);
328
+ markerCreated = true;
329
+ } else {
330
+ const existingCoreHash = existingMarker.coreHash;
331
+ const existingProfileHash = existingMarker.profileHash;
332
+ const coreHashMatches = existingCoreHash === contractCoreHash;
333
+ const profileHashMatches = existingProfileHash === contractProfileHash;
334
+ if (!coreHashMatches || !profileHashMatches) {
335
+ previousHashes = {
336
+ coreHash: existingCoreHash,
337
+ profileHash: existingProfileHash
338
+ };
339
+ const write = writeContractMarker({
340
+ coreHash: contractCoreHash,
341
+ profileHash: contractProfileHash,
342
+ contractJson: contractIR,
343
+ canonicalVersion: existingMarker.canonicalVersion ?? 1
344
+ });
345
+ await driver.query(write.update.sql, write.update.params);
346
+ markerUpdated = true;
347
+ }
348
+ }
349
+ let summary;
350
+ if (markerCreated) {
351
+ summary = "Database signed (marker created)";
352
+ } else if (markerUpdated) {
353
+ summary = `Database signed (marker updated from ${previousHashes?.coreHash ?? "unknown"})`;
354
+ } else {
355
+ summary = "Database already signed with this contract";
356
+ }
357
+ const totalTime = Date.now() - startTime;
358
+ return {
359
+ ok: true,
360
+ summary,
361
+ contract: {
362
+ coreHash: contractCoreHash,
363
+ profileHash: contractProfileHash
364
+ },
365
+ target: {
366
+ expected: contractTarget,
367
+ actual: contractTarget
368
+ },
369
+ marker: {
370
+ created: markerCreated,
371
+ updated: markerUpdated,
372
+ ...previousHashes ? { previous: previousHashes } : {}
373
+ },
374
+ meta: {
375
+ contractPath,
376
+ ...configPath ? { configPath } : {}
377
+ },
378
+ timings: {
379
+ total: totalTime
380
+ }
381
+ };
382
+ },
383
+ async readMarker(options2) {
384
+ return readMarker(options2.driver);
385
+ },
386
+ async introspect(options2) {
387
+ const { driver, contractIR } = options2;
388
+ const controlAdapter = adapter.create();
389
+ return controlAdapter.introspect(driver, contractIR);
390
+ },
391
+ toSchemaView(schema) {
392
+ const rootLabel = "contract";
393
+ const tableNodes = Object.entries(schema.tables).map(
394
+ ([tableName, table]) => {
395
+ const children = [];
396
+ const columnNodes = [];
397
+ for (const [columnName, column] of Object.entries(table.columns)) {
398
+ const nullableText = column.nullable ? "(nullable)" : "(not nullable)";
399
+ const typeDisplay = column.nativeType;
400
+ const label = `${columnName}: ${typeDisplay} ${nullableText}`;
401
+ columnNodes.push({
402
+ kind: "field",
403
+ id: `column-${tableName}-${columnName}`,
404
+ label,
405
+ meta: {
406
+ nativeType: column.nativeType,
407
+ nullable: column.nullable
408
+ }
409
+ });
410
+ }
411
+ if (columnNodes.length > 0) {
412
+ children.push({
413
+ kind: "collection",
414
+ id: `columns-${tableName}`,
415
+ label: "columns",
416
+ children: columnNodes
417
+ });
418
+ }
419
+ if (table.primaryKey) {
420
+ const pkColumns = table.primaryKey.columns.join(", ");
421
+ children.push({
422
+ kind: "index",
423
+ id: `primary-key-${tableName}`,
424
+ label: `primary key: ${pkColumns}`,
425
+ meta: {
426
+ columns: table.primaryKey.columns,
427
+ ...table.primaryKey.name ? { name: table.primaryKey.name } : {}
428
+ }
429
+ });
430
+ }
431
+ for (const unique of table.uniques) {
432
+ const name = unique.name ?? `${tableName}_${unique.columns.join("_")}_unique`;
433
+ const label = `unique ${name}`;
434
+ children.push({
435
+ kind: "index",
436
+ id: `unique-${tableName}-${name}`,
437
+ label,
438
+ meta: {
439
+ columns: unique.columns,
440
+ unique: true
441
+ }
442
+ });
443
+ }
444
+ for (const index of table.indexes) {
445
+ const name = index.name ?? `${tableName}_${index.columns.join("_")}_idx`;
446
+ const label = index.unique ? `unique index ${name}` : `index ${name}`;
447
+ children.push({
448
+ kind: "index",
449
+ id: `index-${tableName}-${name}`,
450
+ label,
451
+ meta: {
452
+ columns: index.columns,
453
+ unique: index.unique
454
+ }
455
+ });
456
+ }
457
+ const tableMeta = {};
458
+ if (table.primaryKey) {
459
+ tableMeta["primaryKey"] = table.primaryKey.columns;
460
+ if (table.primaryKey.name) {
461
+ tableMeta["primaryKeyName"] = table.primaryKey.name;
462
+ }
463
+ }
464
+ if (table.foreignKeys.length > 0) {
465
+ tableMeta["foreignKeys"] = table.foreignKeys.map((fk) => ({
466
+ columns: fk.columns,
467
+ referencedTable: fk.referencedTable,
468
+ referencedColumns: fk.referencedColumns,
469
+ ...fk.name ? { name: fk.name } : {}
470
+ }));
471
+ }
472
+ const node = {
473
+ kind: "entity",
474
+ id: `table-${tableName}`,
475
+ label: `table ${tableName}`,
476
+ ...Object.keys(tableMeta).length > 0 ? { meta: tableMeta } : {},
477
+ ...children.length > 0 ? { children } : {}
478
+ };
479
+ return node;
480
+ }
481
+ );
482
+ const extensionNodes = schema.extensions.map((extName) => ({
483
+ kind: "extension",
484
+ id: `extension-${extName}`,
485
+ label: `${extName} extension is enabled`
486
+ }));
487
+ const rootChildren = [...tableNodes, ...extensionNodes];
488
+ const rootNode = {
489
+ kind: "root",
490
+ id: "sql-schema",
491
+ label: rootLabel,
492
+ ...rootChildren.length > 0 ? { children: rootChildren } : {}
493
+ };
494
+ return {
495
+ root: rootNode
496
+ };
497
+ },
498
+ async emitContract({ contractIR }) {
499
+ const contractWithoutMappings = stripMappings(contractIR);
500
+ const validatedIR = this.validateContractIR(contractWithoutMappings);
501
+ const result = await emit(
502
+ validatedIR,
503
+ {
504
+ outputDir: "",
505
+ operationRegistry,
506
+ codecTypeImports,
507
+ operationTypeImports,
508
+ extensionIds
509
+ },
510
+ sqlTargetFamilyHook
511
+ );
512
+ return {
513
+ contractJson: result.contractJson,
514
+ contractDts: result.contractDts,
515
+ coreHash: result.coreHash,
516
+ profileHash: result.profileHash
517
+ };
518
+ }
519
+ };
520
+ }
521
+
522
+ // src/core/descriptor.ts
13
523
  var SqlFamilyDescriptor = class {
14
524
  kind = "family";
15
525
  id = "sql";
16
526
  familyId = "sql";
17
- manifest = sqlFamilyManifest;
18
- hook = sqlTargetFamilyHook;
527
+ version = "0.0.1";
528
+ hook = sqlTargetFamilyHook2;
19
529
  create(options) {
20
530
  return createSqlFamilyInstance({
21
531
  target: options.target,