@prisma-next/family-mongo 0.5.0-dev.66 → 0.5.0-dev.68

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.
@@ -1 +1 @@
1
- {"version":3,"file":"control.d.mts","names":[],"sources":["../src/core/control-instance.ts","../src/core/control-descriptor.ts","../src/core/mongo-target-descriptor.ts"],"sourcesContent":[],"mappings":";;;;;UAoCiB,0BAAA,SACP,+BAA+B,gBACrC,kBAAkB,gBAClB;2CACuC;AAJ3C;AACyC,iBAuSzB,yBAAA,CAvSyB,aAAA,EAuSgB,YAvShB,CAAA,EAuS+B,0BAvS/B;;;cCd5B,uBAAuB,iCAAiC;;;;;;ADarE;;;;;;;AAG2B,cEZd,qBFYc,EEZS,0BFYT,CAAA,OAAA,EAAA,OAAA,EETzB,0BFSyB,CAAA"}
1
+ {"version":3,"file":"control.d.mts","names":[],"sources":["../src/core/control-instance.ts","../src/core/control-descriptor.ts","../src/core/mongo-target-descriptor.ts"],"mappings":";;;;;UAoCiB,0BAAA,SACP,qBAAA,UAA+B,aAAA,GACrC,iBAAA,CAAkB,aAAA,GAClB,uBAAA;EACF,gBAAA,CAAiB,YAAA,YAAwB,QAAA;AAAA;AAAA,iBAgU3B,yBAAA,CAA0B,aAAA,EAAe,YAAA,GAAe,0BAAA;;;cCjV3D,qBAAA,EAAuB,uBAAA,UAAiC,0BAAA;;;;;;ADarE;;;;;;;cETa,qBAAA,EAAuB,0BAAA,mBAGlC,0BAAA"}
package/dist/control.mjs CHANGED
@@ -7,7 +7,6 @@ import { verifyMongoSchema } from "@prisma-next/target-mongo/schema-verify";
7
7
  import { ifDefined } from "@prisma-next/utils/defined";
8
8
  import { MongoDriverImpl } from "@prisma-next/driver-mongo";
9
9
  import mongoTargetDescriptorMeta from "@prisma-next/target-mongo/pack";
10
-
11
10
  //#region src/core/schema-to-view.ts
12
11
  function mongoSchemaToView(schema) {
13
12
  const collectionNodes = schema.collections.map((collection) => collectionToSchemaNode(collection.name, collection));
@@ -99,7 +98,6 @@ function collectionToSchemaNode(name, collection) {
99
98
  ...ifDefined("children", children.length > 0 ? children : void 0)
100
99
  });
101
100
  }
102
-
103
101
  //#endregion
104
102
  //#region src/core/control-instance.ts
105
103
  function extractDb$1(driver) {
@@ -180,6 +178,14 @@ var MongoFamilyInstance = class {
180
178
  }
181
179
  });
182
180
  }
181
+ schemaVerifyAgainstSchema(options) {
182
+ return verifyMongoSchema({
183
+ contract: validateMongoContract(options.contract).contract,
184
+ schema: options.schema,
185
+ strict: options.strict,
186
+ frameworkComponents: options.frameworkComponents
187
+ });
188
+ }
183
189
  async sign(options) {
184
190
  const { driver, contract: rawContract, contractPath, configPath } = options;
185
191
  const startTime = Date.now();
@@ -243,6 +249,14 @@ var MongoFamilyInstance = class {
243
249
  if (options.space !== APP_SPACE_ID) throw new Error(`Mongo target does not yet support per-space contract markers. readMarker was called with space="${options.space}", but only "${APP_SPACE_ID}" is supported. Per-space marker support is tracked separately for Mongo and is not part of the SQL-family contract-spaces work.`);
244
250
  return readMarker(extractDb$1(options.driver));
245
251
  }
252
+ async readAllMarkers(options) {
253
+ const appMarker = await this.readMarker({
254
+ ...options,
255
+ space: APP_SPACE_ID
256
+ });
257
+ if (appMarker === null) return /* @__PURE__ */ new Map();
258
+ return new Map([[APP_SPACE_ID, appMarker]]);
259
+ }
246
260
  async introspect(options) {
247
261
  return introspectSchema(extractDb$1(options.driver));
248
262
  }
@@ -283,7 +297,6 @@ function buildVerifyResult(opts) {
283
297
  function createMongoFamilyInstance(_controlStack) {
284
298
  return new MongoFamilyInstance();
285
299
  }
286
-
287
300
  //#endregion
288
301
  //#region src/core/control-descriptor.ts
289
302
  var MongoFamilyDescriptor = class {
@@ -297,7 +310,6 @@ var MongoFamilyDescriptor = class {
297
310
  }
298
311
  };
299
312
  const mongoFamilyDescriptor = new MongoFamilyDescriptor();
300
-
301
313
  //#endregion
302
314
  //#region src/core/mongo-target-descriptor.ts
303
315
  /**
@@ -338,7 +350,7 @@ const mongoTargetDescriptor = {
338
350
  };
339
351
  }
340
352
  };
341
-
342
353
  //#endregion
343
354
  export { createMongoFamilyInstance, mongoFamilyDescriptor, mongoTargetDescriptor };
355
+
344
356
  //# sourceMappingURL=control.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"control.mjs","names":["children: SchemaTreeNode[]","options: string[]","validatorChildren: SchemaTreeNode[]","optLabels: string[]","extractDb","previousHashes: { storageHash?: string; profileHash?: string } | undefined","summary: string","mongoFamilyDescriptor: ControlFamilyDescriptor<'mongo', MongoControlFamilyInstance>","mongoTargetDescriptor: MigratableTargetDescriptor<\n 'mongo',\n 'mongo',\n MongoControlFamilyInstance\n>","cachedDeps: MongoRunnerDependencies | undefined"],"sources":["../src/core/schema-to-view.ts","../src/core/control-instance.ts","../src/core/control-descriptor.ts","../src/core/mongo-target-descriptor.ts"],"sourcesContent":["import type { CoreSchemaView } from '@prisma-next/framework-components/control';\nimport { SchemaTreeNode } from '@prisma-next/framework-components/control';\nimport type { MongoSchemaCollection, MongoSchemaIR } from '@prisma-next/mongo-schema-ir';\nimport { ifDefined } from '@prisma-next/utils/defined';\n\nexport function mongoSchemaToView(schema: MongoSchemaIR): CoreSchemaView {\n const collectionNodes = schema.collections.map((collection) =>\n collectionToSchemaNode(collection.name, collection),\n );\n\n return {\n root: new SchemaTreeNode({\n kind: 'root',\n id: 'mongo-schema',\n label: 'database',\n ...ifDefined('children', collectionNodes.length > 0 ? collectionNodes : undefined),\n }),\n };\n}\n\nfunction collectionToSchemaNode(name: string, collection: MongoSchemaCollection): SchemaTreeNode {\n const children: SchemaTreeNode[] = [];\n\n for (const index of collection.indexes) {\n const keysSummary = index.keys\n .map((k) => {\n if (k.direction === 1) return k.field;\n if (k.direction === -1) return `${k.field} desc`;\n return `${k.field} ${k.direction}`;\n })\n .join(', ');\n const prefix = index.unique ? 'unique index' : 'index';\n const options: string[] = [];\n if (index.sparse) options.push('sparse');\n if (index.expireAfterSeconds != null) options.push(`ttl: ${index.expireAfterSeconds}s`);\n if (index.partialFilterExpression) options.push('partial');\n const optsSuffix = options.length > 0 ? ` (${options.join(', ')})` : '';\n\n children.push(\n new SchemaTreeNode({\n kind: 'index',\n id: `index-${name}-${index.keys.map((k) => `${k.field}_${k.direction}`).join('_')}`,\n label: `${prefix} (${keysSummary})${optsSuffix}`,\n meta: {\n keys: index.keys,\n unique: index.unique,\n ...ifDefined('sparse', index.sparse || undefined),\n ...ifDefined('expireAfterSeconds', index.expireAfterSeconds ?? undefined),\n ...ifDefined('partialFilterExpression', index.partialFilterExpression ?? undefined),\n },\n }),\n );\n }\n\n if (collection.validator) {\n const validatorChildren: SchemaTreeNode[] = [];\n const jsonSchema = collection.validator.jsonSchema as Record<string, unknown>;\n const properties = jsonSchema['properties'] as\n | Record<string, Record<string, unknown>>\n | undefined;\n const required = new Set((jsonSchema['required'] as string[] | undefined) ?? []);\n\n if (properties) {\n for (const [propName, propDef] of Object.entries(properties)) {\n const bsonType = (propDef['bsonType'] as string) ?? 'unknown';\n const suffix = required.has(propName) ? ' (required)' : '';\n validatorChildren.push(\n new SchemaTreeNode({\n kind: 'field',\n id: `field-${name}-${propName}`,\n label: `${propName}: ${bsonType}${suffix}`,\n }),\n );\n }\n }\n\n children.push(\n new SchemaTreeNode({\n kind: 'field',\n id: `validator-${name}`,\n label: `validator (level: ${collection.validator.validationLevel}, action: ${collection.validator.validationAction})`,\n meta: {\n validationLevel: collection.validator.validationLevel,\n validationAction: collection.validator.validationAction,\n jsonSchema: collection.validator.jsonSchema,\n },\n ...ifDefined('children', validatorChildren.length > 0 ? validatorChildren : undefined),\n }),\n );\n }\n\n if (collection.options) {\n const opts = collection.options;\n const optLabels: string[] = [];\n if (opts.capped) optLabels.push('capped');\n if (opts.timeseries) optLabels.push('timeseries');\n if (opts.collation) optLabels.push('collation');\n if (opts.changeStreamPreAndPostImages) optLabels.push('changeStreamPreAndPostImages');\n if (opts.clusteredIndex) optLabels.push('clusteredIndex');\n\n if (optLabels.length > 0) {\n children.push(\n new SchemaTreeNode({\n kind: 'field',\n id: `options-${name}`,\n label: `options (${optLabels.join(', ')})`,\n meta: {\n ...ifDefined('capped', opts.capped ?? undefined),\n ...ifDefined('timeseries', opts.timeseries ?? undefined),\n ...ifDefined('collation', opts.collation ?? undefined),\n ...ifDefined(\n 'changeStreamPreAndPostImages',\n opts.changeStreamPreAndPostImages ?? undefined,\n ),\n ...ifDefined('clusteredIndex', opts.clusteredIndex ?? undefined),\n },\n }),\n );\n }\n }\n\n return new SchemaTreeNode({\n kind: 'collection',\n id: `collection-${name}`,\n label: `collection ${name}`,\n ...ifDefined('children', children.length > 0 ? children : undefined),\n });\n}\n","import { introspectSchema } from '@prisma-next/adapter-mongo/control';\nimport type { Contract, ContractMarkerRecord } from '@prisma-next/contract/types';\nimport type { TargetBoundComponentDescriptor } from '@prisma-next/framework-components/components';\nimport type {\n ControlDriverInstance,\n ControlFamilyInstance,\n ControlStack,\n CoreSchemaView,\n MigrationPlanOperation,\n OperationPreview,\n OperationPreviewCapable,\n SchemaViewCapable,\n SignDatabaseResult,\n VerifyDatabaseResult,\n VerifyDatabaseSchemaResult,\n} from '@prisma-next/framework-components/control';\nimport {\n APP_SPACE_ID,\n VERIFY_CODE_HASH_MISMATCH,\n VERIFY_CODE_MARKER_MISSING,\n VERIFY_CODE_TARGET_MISMATCH,\n} from '@prisma-next/framework-components/control';\nimport type { MongoContract } from '@prisma-next/mongo-contract';\nimport { validateMongoContract } from '@prisma-next/mongo-contract';\nimport type { MongoSchemaIR } from '@prisma-next/mongo-schema-ir';\nimport {\n formatMongoOperations,\n initMarker,\n readMarker,\n updateMarker,\n} from '@prisma-next/target-mongo/control';\nimport { verifyMongoSchema } from '@prisma-next/target-mongo/schema-verify';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport type { Db } from 'mongodb';\nimport { mongoSchemaToView } from './schema-to-view';\n\nexport interface MongoControlFamilyInstance\n extends ControlFamilyInstance<'mongo', MongoSchemaIR>,\n SchemaViewCapable<MongoSchemaIR>,\n OperationPreviewCapable {\n validateContract(contractJson: unknown): Contract;\n}\n\nfunction extractDb(driver: ControlDriverInstance<'mongo', string>): Db {\n const mongoDriver = driver as ControlDriverInstance<'mongo', string> & { db?: Db };\n if (!mongoDriver.db) {\n throw new Error(\n 'Mongo control driver does not expose a db property. ' +\n 'Use createMongoControlDriver() from @prisma-next/adapter-mongo/control.',\n );\n }\n return mongoDriver.db;\n}\n\nclass MongoFamilyInstance implements MongoControlFamilyInstance {\n readonly familyId = 'mongo' as const;\n\n validateContract(contractJson: unknown): Contract {\n const validated = validateMongoContract<MongoContract>(contractJson);\n // MongoContract and Contract share structure but are typed independently;\n // validateMongoContract guarantees the shape, so the double cast is safe.\n return validated.contract as unknown as Contract;\n }\n\n async verify(options: {\n readonly driver: ControlDriverInstance<'mongo', string>;\n readonly contract: unknown;\n readonly expectedTargetId: string;\n readonly contractPath: string;\n readonly configPath?: string;\n }): Promise<VerifyDatabaseResult> {\n const { driver, contract: rawContract, expectedTargetId, contractPath, configPath } = options;\n const startTime = Date.now();\n\n const validated = validateMongoContract<MongoContract>(rawContract);\n const contract = validated.contract;\n\n const contractStorageHash = contract.storage.storageHash;\n const contractProfileHash = contract.profileHash;\n const contractTarget = contract.target;\n\n const baseOpts = {\n contractStorageHash,\n contractProfileHash,\n expectedTargetId,\n contractPath,\n ...ifDefined('configPath', configPath),\n };\n\n if (contractTarget !== expectedTargetId) {\n return buildVerifyResult({\n ...baseOpts,\n ok: false,\n code: VERIFY_CODE_TARGET_MISMATCH,\n summary: 'Target mismatch',\n actualTargetId: contractTarget,\n totalTime: Date.now() - startTime,\n });\n }\n\n const db = extractDb(driver);\n const marker = await readMarker(db);\n\n if (!marker) {\n return buildVerifyResult({\n ...baseOpts,\n ok: false,\n code: VERIFY_CODE_MARKER_MISSING,\n summary: 'Marker missing',\n totalTime: Date.now() - startTime,\n });\n }\n\n if (marker.storageHash !== contractStorageHash) {\n return buildVerifyResult({\n ...baseOpts,\n ok: false,\n code: VERIFY_CODE_HASH_MISMATCH,\n summary: 'Hash mismatch',\n marker,\n totalTime: Date.now() - startTime,\n });\n }\n\n if (contractProfileHash && marker.profileHash !== contractProfileHash) {\n return buildVerifyResult({\n ...baseOpts,\n ok: false,\n code: VERIFY_CODE_HASH_MISMATCH,\n summary: 'Hash mismatch',\n marker,\n totalTime: Date.now() - startTime,\n });\n }\n\n return buildVerifyResult({\n ...baseOpts,\n ok: true,\n summary: 'Database matches contract',\n marker,\n totalTime: Date.now() - startTime,\n });\n }\n\n async schemaVerify(options: {\n readonly driver: ControlDriverInstance<'mongo', string>;\n readonly contract: unknown;\n readonly strict: boolean;\n readonly contractPath: string;\n readonly configPath?: string;\n readonly frameworkComponents: ReadonlyArray<TargetBoundComponentDescriptor<'mongo', string>>;\n }): Promise<VerifyDatabaseSchemaResult> {\n const { driver, contract: rawContract, strict, contractPath, configPath } = options;\n\n const validated = validateMongoContract<MongoContract>(rawContract);\n const contract = validated.contract;\n\n const db = extractDb(driver);\n const liveIR = await introspectSchema(db);\n\n return verifyMongoSchema({\n contract,\n schema: liveIR,\n strict,\n frameworkComponents: options.frameworkComponents,\n context: {\n contractPath,\n ...ifDefined('configPath', configPath),\n },\n });\n }\n\n async sign(options: {\n readonly driver: ControlDriverInstance<'mongo', string>;\n readonly contract: unknown;\n readonly contractPath: string;\n readonly configPath?: string;\n }): Promise<SignDatabaseResult> {\n const { driver, contract: rawContract, contractPath, configPath } = options;\n const startTime = Date.now();\n\n const validated = validateMongoContract<MongoContract>(rawContract);\n const contract = validated.contract;\n\n const contractStorageHash = contract.storage.storageHash;\n const contractProfileHash = contract.profileHash;\n\n const db = extractDb(driver);\n\n const existingMarker = await readMarker(db);\n\n let markerCreated = false;\n let markerUpdated = false;\n let previousHashes: { storageHash?: string; profileHash?: string } | undefined;\n\n if (!existingMarker) {\n await initMarker(db, {\n storageHash: contractStorageHash,\n profileHash: contractProfileHash,\n });\n markerCreated = true;\n } else {\n const storageHashMatches = existingMarker.storageHash === contractStorageHash;\n const profileHashMatches = existingMarker.profileHash === contractProfileHash;\n\n if (!storageHashMatches || !profileHashMatches) {\n previousHashes = {\n storageHash: existingMarker.storageHash,\n profileHash: existingMarker.profileHash,\n };\n const updated = await updateMarker(db, existingMarker.storageHash, {\n storageHash: contractStorageHash,\n profileHash: contractProfileHash,\n });\n if (!updated) {\n throw new Error('CAS conflict: marker was modified by another process during sign');\n }\n markerUpdated = true;\n }\n }\n\n let summary: string;\n if (markerCreated) {\n summary = 'Database signed (marker created)';\n } else if (markerUpdated) {\n summary = `Database signed (marker updated from ${previousHashes?.storageHash ?? 'unknown'})`;\n } else {\n summary = 'Database already signed with this contract';\n }\n\n return {\n ok: true,\n summary,\n contract: {\n storageHash: contractStorageHash,\n profileHash: contractProfileHash,\n },\n target: {\n expected: contract.target,\n actual: contract.target,\n },\n marker: {\n created: markerCreated,\n updated: markerUpdated,\n ...ifDefined('previous', previousHashes),\n },\n meta: {\n contractPath,\n ...ifDefined('configPath', configPath),\n },\n timings: {\n total: Date.now() - startTime,\n },\n };\n }\n\n async readMarker(options: {\n readonly driver: ControlDriverInstance<'mongo', string>;\n readonly space: string;\n }): Promise<ContractMarkerRecord | null> {\n if (options.space !== APP_SPACE_ID) {\n throw new Error(\n 'Mongo target does not yet support per-space contract markers. ' +\n `readMarker was called with space=\"${options.space}\", but only \"${APP_SPACE_ID}\" is supported. ` +\n 'Per-space marker support is tracked separately for Mongo and is not part of the SQL-family contract-spaces work.',\n );\n }\n const db = extractDb(options.driver);\n return readMarker(db);\n }\n\n async introspect(options: {\n readonly driver: ControlDriverInstance<'mongo', string>;\n readonly contract?: unknown;\n }): Promise<MongoSchemaIR> {\n const db = extractDb(options.driver);\n return introspectSchema(db);\n }\n\n toSchemaView(schema: MongoSchemaIR): CoreSchemaView {\n return mongoSchemaToView(schema);\n }\n\n toOperationPreview(operations: readonly MigrationPlanOperation[]): OperationPreview {\n return {\n statements: formatMongoOperations(operations).map((text) => ({\n text,\n language: 'mongodb-shell',\n })),\n };\n }\n}\n\nfunction buildVerifyResult(opts: {\n ok: boolean;\n code?: string;\n summary: string;\n contractStorageHash: string;\n contractProfileHash?: string;\n marker?: ContractMarkerRecord;\n expectedTargetId: string;\n actualTargetId?: string;\n contractPath: string;\n configPath?: string;\n totalTime: number;\n}): VerifyDatabaseResult {\n return {\n ok: opts.ok,\n ...ifDefined('code', opts.code),\n summary: opts.summary,\n contract: {\n storageHash: opts.contractStorageHash,\n ...ifDefined('profileHash', opts.contractProfileHash),\n },\n ...ifDefined(\n 'marker',\n opts.marker\n ? { storageHash: opts.marker.storageHash, profileHash: opts.marker.profileHash }\n : undefined,\n ),\n target: {\n expected: opts.expectedTargetId,\n ...ifDefined('actual', opts.actualTargetId),\n },\n meta: {\n contractPath: opts.contractPath,\n ...ifDefined('configPath', opts.configPath),\n },\n timings: { total: opts.totalTime },\n };\n}\n\nexport function createMongoFamilyInstance(_controlStack: ControlStack): MongoControlFamilyInstance {\n return new MongoFamilyInstance();\n}\n","import type {\n ControlFamilyDescriptor,\n ControlStack,\n} from '@prisma-next/framework-components/control';\nimport { mongoEmission } from '@prisma-next/mongo-emitter';\nimport { createMongoFamilyInstance, type MongoControlFamilyInstance } from './control-instance';\n\nclass MongoFamilyDescriptor\n implements ControlFamilyDescriptor<'mongo', MongoControlFamilyInstance>\n{\n readonly kind = 'family' as const;\n readonly id = 'mongo';\n readonly familyId = 'mongo' as const;\n readonly version = '0.0.1';\n readonly emission = mongoEmission;\n\n create<TTargetId extends string>(\n stack: ControlStack<'mongo', TTargetId>,\n ): MongoControlFamilyInstance {\n return createMongoFamilyInstance(stack);\n }\n}\n\nexport const mongoFamilyDescriptor: ControlFamilyDescriptor<'mongo', MongoControlFamilyInstance> =\n new MongoFamilyDescriptor();\n","import { createMongoRunnerDeps, extractDb } from '@prisma-next/adapter-mongo/control';\nimport type { Contract } from '@prisma-next/contract/types';\nimport { MongoDriverImpl } from '@prisma-next/driver-mongo';\nimport type {\n MigratableTargetDescriptor,\n MigrationRunner,\n} from '@prisma-next/framework-components/control';\nimport type { MongoContract } from '@prisma-next/mongo-contract';\nimport {\n contractToMongoSchemaIR,\n MongoMigrationPlanner,\n MongoMigrationRunner,\n type MongoRunnerDependencies,\n} from '@prisma-next/target-mongo/control';\nimport mongoTargetDescriptorMeta from '@prisma-next/target-mongo/pack';\nimport type { MongoControlFamilyInstance } from './control-instance';\n\n/**\n * `migration.ts` default-exports a `Migration` subclass whose `operations`\n * getter returns the ordered list of operations and whose `describe()`\n * returns the manifest identity metadata. `MongoMigrationPlanner.plan()`\n * returns a `MigrationPlanWithAuthoringSurface` that knows how to render\n * itself back to such a file; `MongoMigrationPlanner.emptyMigration()`\n * returns the same shape for `migration new`. Users run the scaffolded\n * `migration.ts` directly (via `node migration.ts`) to self-emit\n * `ops.json` and attest the `migrationHash`.\n */\nexport const mongoTargetDescriptor: MigratableTargetDescriptor<\n 'mongo',\n 'mongo',\n MongoControlFamilyInstance\n> = {\n ...mongoTargetDescriptorMeta,\n migrations: {\n createPlanner(_family: MongoControlFamilyInstance) {\n return new MongoMigrationPlanner();\n },\n createRunner(family: MongoControlFamilyInstance) {\n // Deps are bound to the first driver passed to execute() and cached for\n // subsequent calls. Callers must not change the driver between calls.\n let cachedDeps: MongoRunnerDependencies | undefined;\n const runner: MigrationRunner<'mongo', 'mongo'> = {\n async execute(options) {\n cachedDeps ??= createMongoRunnerDeps(\n options.driver,\n MongoDriverImpl.fromDb(extractDb(options.driver)),\n family,\n );\n const { driver: _, ...runnerOptions } = options;\n // The framework `MigrationRunner` interface types `destinationContract`\n // as `unknown`; the Mongo runner narrows to `MongoContract`. Validation\n // happens upstream — `migration apply` calls\n // `familyInstance.validateContract(migration.toContract)` before\n // routing the contract here (see\n // `packages/1-framework/3-tooling/cli/src/control-api/operations/migration-apply.ts`),\n // so this cast simply preserves the framework signature without\n // weakening the runner's typed surface or duplicating validation.\n return new MongoMigrationRunner(cachedDeps).execute({\n ...runnerOptions,\n destinationContract: runnerOptions.destinationContract as MongoContract,\n });\n },\n };\n return runner;\n },\n contractToSchema(contract: Contract | null) {\n return contractToMongoSchemaIR(contract as MongoContract | null);\n },\n },\n create() {\n return { familyId: 'mongo' as const, targetId: 'mongo' as const };\n },\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"control.mjs","names":["extractDb"],"sources":["../src/core/schema-to-view.ts","../src/core/control-instance.ts","../src/core/control-descriptor.ts","../src/core/mongo-target-descriptor.ts"],"sourcesContent":["import type { CoreSchemaView } from '@prisma-next/framework-components/control';\nimport { SchemaTreeNode } from '@prisma-next/framework-components/control';\nimport type { MongoSchemaCollection, MongoSchemaIR } from '@prisma-next/mongo-schema-ir';\nimport { ifDefined } from '@prisma-next/utils/defined';\n\nexport function mongoSchemaToView(schema: MongoSchemaIR): CoreSchemaView {\n const collectionNodes = schema.collections.map((collection) =>\n collectionToSchemaNode(collection.name, collection),\n );\n\n return {\n root: new SchemaTreeNode({\n kind: 'root',\n id: 'mongo-schema',\n label: 'database',\n ...ifDefined('children', collectionNodes.length > 0 ? collectionNodes : undefined),\n }),\n };\n}\n\nfunction collectionToSchemaNode(name: string, collection: MongoSchemaCollection): SchemaTreeNode {\n const children: SchemaTreeNode[] = [];\n\n for (const index of collection.indexes) {\n const keysSummary = index.keys\n .map((k) => {\n if (k.direction === 1) return k.field;\n if (k.direction === -1) return `${k.field} desc`;\n return `${k.field} ${k.direction}`;\n })\n .join(', ');\n const prefix = index.unique ? 'unique index' : 'index';\n const options: string[] = [];\n if (index.sparse) options.push('sparse');\n if (index.expireAfterSeconds != null) options.push(`ttl: ${index.expireAfterSeconds}s`);\n if (index.partialFilterExpression) options.push('partial');\n const optsSuffix = options.length > 0 ? ` (${options.join(', ')})` : '';\n\n children.push(\n new SchemaTreeNode({\n kind: 'index',\n id: `index-${name}-${index.keys.map((k) => `${k.field}_${k.direction}`).join('_')}`,\n label: `${prefix} (${keysSummary})${optsSuffix}`,\n meta: {\n keys: index.keys,\n unique: index.unique,\n ...ifDefined('sparse', index.sparse || undefined),\n ...ifDefined('expireAfterSeconds', index.expireAfterSeconds ?? undefined),\n ...ifDefined('partialFilterExpression', index.partialFilterExpression ?? undefined),\n },\n }),\n );\n }\n\n if (collection.validator) {\n const validatorChildren: SchemaTreeNode[] = [];\n const jsonSchema = collection.validator.jsonSchema as Record<string, unknown>;\n const properties = jsonSchema['properties'] as\n | Record<string, Record<string, unknown>>\n | undefined;\n const required = new Set((jsonSchema['required'] as string[] | undefined) ?? []);\n\n if (properties) {\n for (const [propName, propDef] of Object.entries(properties)) {\n const bsonType = (propDef['bsonType'] as string) ?? 'unknown';\n const suffix = required.has(propName) ? ' (required)' : '';\n validatorChildren.push(\n new SchemaTreeNode({\n kind: 'field',\n id: `field-${name}-${propName}`,\n label: `${propName}: ${bsonType}${suffix}`,\n }),\n );\n }\n }\n\n children.push(\n new SchemaTreeNode({\n kind: 'field',\n id: `validator-${name}`,\n label: `validator (level: ${collection.validator.validationLevel}, action: ${collection.validator.validationAction})`,\n meta: {\n validationLevel: collection.validator.validationLevel,\n validationAction: collection.validator.validationAction,\n jsonSchema: collection.validator.jsonSchema,\n },\n ...ifDefined('children', validatorChildren.length > 0 ? validatorChildren : undefined),\n }),\n );\n }\n\n if (collection.options) {\n const opts = collection.options;\n const optLabels: string[] = [];\n if (opts.capped) optLabels.push('capped');\n if (opts.timeseries) optLabels.push('timeseries');\n if (opts.collation) optLabels.push('collation');\n if (opts.changeStreamPreAndPostImages) optLabels.push('changeStreamPreAndPostImages');\n if (opts.clusteredIndex) optLabels.push('clusteredIndex');\n\n if (optLabels.length > 0) {\n children.push(\n new SchemaTreeNode({\n kind: 'field',\n id: `options-${name}`,\n label: `options (${optLabels.join(', ')})`,\n meta: {\n ...ifDefined('capped', opts.capped ?? undefined),\n ...ifDefined('timeseries', opts.timeseries ?? undefined),\n ...ifDefined('collation', opts.collation ?? undefined),\n ...ifDefined(\n 'changeStreamPreAndPostImages',\n opts.changeStreamPreAndPostImages ?? undefined,\n ),\n ...ifDefined('clusteredIndex', opts.clusteredIndex ?? undefined),\n },\n }),\n );\n }\n }\n\n return new SchemaTreeNode({\n kind: 'collection',\n id: `collection-${name}`,\n label: `collection ${name}`,\n ...ifDefined('children', children.length > 0 ? children : undefined),\n });\n}\n","import { introspectSchema } from '@prisma-next/adapter-mongo/control';\nimport type { Contract, ContractMarkerRecord } from '@prisma-next/contract/types';\nimport type { TargetBoundComponentDescriptor } from '@prisma-next/framework-components/components';\nimport type {\n ControlDriverInstance,\n ControlFamilyInstance,\n ControlStack,\n CoreSchemaView,\n MigrationPlanOperation,\n OperationPreview,\n OperationPreviewCapable,\n SchemaViewCapable,\n SignDatabaseResult,\n VerifyDatabaseResult,\n VerifyDatabaseSchemaResult,\n} from '@prisma-next/framework-components/control';\nimport {\n APP_SPACE_ID,\n VERIFY_CODE_HASH_MISMATCH,\n VERIFY_CODE_MARKER_MISSING,\n VERIFY_CODE_TARGET_MISMATCH,\n} from '@prisma-next/framework-components/control';\nimport type { MongoContract } from '@prisma-next/mongo-contract';\nimport { validateMongoContract } from '@prisma-next/mongo-contract';\nimport type { MongoSchemaIR } from '@prisma-next/mongo-schema-ir';\nimport {\n formatMongoOperations,\n initMarker,\n readMarker,\n updateMarker,\n} from '@prisma-next/target-mongo/control';\nimport { verifyMongoSchema } from '@prisma-next/target-mongo/schema-verify';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport type { Db } from 'mongodb';\nimport { mongoSchemaToView } from './schema-to-view';\n\nexport interface MongoControlFamilyInstance\n extends ControlFamilyInstance<'mongo', MongoSchemaIR>,\n SchemaViewCapable<MongoSchemaIR>,\n OperationPreviewCapable {\n validateContract(contractJson: unknown): Contract;\n}\n\nfunction extractDb(driver: ControlDriverInstance<'mongo', string>): Db {\n const mongoDriver = driver as ControlDriverInstance<'mongo', string> & { db?: Db };\n if (!mongoDriver.db) {\n throw new Error(\n 'Mongo control driver does not expose a db property. ' +\n 'Use createMongoControlDriver() from @prisma-next/adapter-mongo/control.',\n );\n }\n return mongoDriver.db;\n}\n\nclass MongoFamilyInstance implements MongoControlFamilyInstance {\n readonly familyId = 'mongo' as const;\n\n validateContract(contractJson: unknown): Contract {\n const validated = validateMongoContract<MongoContract>(contractJson);\n // MongoContract and Contract share structure but are typed independently;\n // validateMongoContract guarantees the shape, so the double cast is safe.\n return validated.contract as unknown as Contract;\n }\n\n async verify(options: {\n readonly driver: ControlDriverInstance<'mongo', string>;\n readonly contract: unknown;\n readonly expectedTargetId: string;\n readonly contractPath: string;\n readonly configPath?: string;\n }): Promise<VerifyDatabaseResult> {\n const { driver, contract: rawContract, expectedTargetId, contractPath, configPath } = options;\n const startTime = Date.now();\n\n const validated = validateMongoContract<MongoContract>(rawContract);\n const contract = validated.contract;\n\n const contractStorageHash = contract.storage.storageHash;\n const contractProfileHash = contract.profileHash;\n const contractTarget = contract.target;\n\n const baseOpts = {\n contractStorageHash,\n contractProfileHash,\n expectedTargetId,\n contractPath,\n ...ifDefined('configPath', configPath),\n };\n\n if (contractTarget !== expectedTargetId) {\n return buildVerifyResult({\n ...baseOpts,\n ok: false,\n code: VERIFY_CODE_TARGET_MISMATCH,\n summary: 'Target mismatch',\n actualTargetId: contractTarget,\n totalTime: Date.now() - startTime,\n });\n }\n\n const db = extractDb(driver);\n const marker = await readMarker(db);\n\n if (!marker) {\n return buildVerifyResult({\n ...baseOpts,\n ok: false,\n code: VERIFY_CODE_MARKER_MISSING,\n summary: 'Marker missing',\n totalTime: Date.now() - startTime,\n });\n }\n\n if (marker.storageHash !== contractStorageHash) {\n return buildVerifyResult({\n ...baseOpts,\n ok: false,\n code: VERIFY_CODE_HASH_MISMATCH,\n summary: 'Hash mismatch',\n marker,\n totalTime: Date.now() - startTime,\n });\n }\n\n if (contractProfileHash && marker.profileHash !== contractProfileHash) {\n return buildVerifyResult({\n ...baseOpts,\n ok: false,\n code: VERIFY_CODE_HASH_MISMATCH,\n summary: 'Hash mismatch',\n marker,\n totalTime: Date.now() - startTime,\n });\n }\n\n return buildVerifyResult({\n ...baseOpts,\n ok: true,\n summary: 'Database matches contract',\n marker,\n totalTime: Date.now() - startTime,\n });\n }\n\n async schemaVerify(options: {\n readonly driver: ControlDriverInstance<'mongo', string>;\n readonly contract: unknown;\n readonly strict: boolean;\n readonly contractPath: string;\n readonly configPath?: string;\n readonly frameworkComponents: ReadonlyArray<TargetBoundComponentDescriptor<'mongo', string>>;\n }): Promise<VerifyDatabaseSchemaResult> {\n const { driver, contract: rawContract, strict, contractPath, configPath } = options;\n\n const validated = validateMongoContract<MongoContract>(rawContract);\n const contract = validated.contract;\n\n const db = extractDb(driver);\n const liveIR = await introspectSchema(db);\n\n return verifyMongoSchema({\n contract,\n schema: liveIR,\n strict,\n frameworkComponents: options.frameworkComponents,\n context: {\n contractPath,\n ...ifDefined('configPath', configPath),\n },\n });\n }\n\n schemaVerifyAgainstSchema(options: {\n readonly contract: unknown;\n readonly schema: MongoSchemaIR;\n readonly strict: boolean;\n readonly frameworkComponents: ReadonlyArray<TargetBoundComponentDescriptor<'mongo', string>>;\n }): VerifyDatabaseSchemaResult {\n const validated = validateMongoContract<MongoContract>(options.contract);\n return verifyMongoSchema({\n contract: validated.contract,\n schema: options.schema,\n strict: options.strict,\n frameworkComponents: options.frameworkComponents,\n });\n }\n\n async sign(options: {\n readonly driver: ControlDriverInstance<'mongo', string>;\n readonly contract: unknown;\n readonly contractPath: string;\n readonly configPath?: string;\n }): Promise<SignDatabaseResult> {\n const { driver, contract: rawContract, contractPath, configPath } = options;\n const startTime = Date.now();\n\n const validated = validateMongoContract<MongoContract>(rawContract);\n const contract = validated.contract;\n\n const contractStorageHash = contract.storage.storageHash;\n const contractProfileHash = contract.profileHash;\n\n const db = extractDb(driver);\n\n const existingMarker = await readMarker(db);\n\n let markerCreated = false;\n let markerUpdated = false;\n let previousHashes: { storageHash?: string; profileHash?: string } | undefined;\n\n if (!existingMarker) {\n await initMarker(db, {\n storageHash: contractStorageHash,\n profileHash: contractProfileHash,\n });\n markerCreated = true;\n } else {\n const storageHashMatches = existingMarker.storageHash === contractStorageHash;\n const profileHashMatches = existingMarker.profileHash === contractProfileHash;\n\n if (!storageHashMatches || !profileHashMatches) {\n previousHashes = {\n storageHash: existingMarker.storageHash,\n profileHash: existingMarker.profileHash,\n };\n const updated = await updateMarker(db, existingMarker.storageHash, {\n storageHash: contractStorageHash,\n profileHash: contractProfileHash,\n });\n if (!updated) {\n throw new Error('CAS conflict: marker was modified by another process during sign');\n }\n markerUpdated = true;\n }\n }\n\n let summary: string;\n if (markerCreated) {\n summary = 'Database signed (marker created)';\n } else if (markerUpdated) {\n summary = `Database signed (marker updated from ${previousHashes?.storageHash ?? 'unknown'})`;\n } else {\n summary = 'Database already signed with this contract';\n }\n\n return {\n ok: true,\n summary,\n contract: {\n storageHash: contractStorageHash,\n profileHash: contractProfileHash,\n },\n target: {\n expected: contract.target,\n actual: contract.target,\n },\n marker: {\n created: markerCreated,\n updated: markerUpdated,\n ...ifDefined('previous', previousHashes),\n },\n meta: {\n contractPath,\n ...ifDefined('configPath', configPath),\n },\n timings: {\n total: Date.now() - startTime,\n },\n };\n }\n\n async readMarker(options: {\n readonly driver: ControlDriverInstance<'mongo', string>;\n readonly space: string;\n }): Promise<ContractMarkerRecord | null> {\n if (options.space !== APP_SPACE_ID) {\n throw new Error(\n 'Mongo target does not yet support per-space contract markers. ' +\n `readMarker was called with space=\"${options.space}\", but only \"${APP_SPACE_ID}\" is supported. ` +\n 'Per-space marker support is tracked separately for Mongo and is not part of the SQL-family contract-spaces work.',\n );\n }\n const db = extractDb(options.driver);\n return readMarker(db);\n }\n\n // Mongo does not yet participate in the per-space mechanism — the\n // `space` column was introduced in the SQL family's marker only.\n // The bridge: surface the single app marker keyed by APP_SPACE_ID so\n // the per-space verifier sees a coherent input shape; per-space mongo\n // support is a future extension.\n async readAllMarkers(options: {\n readonly driver: ControlDriverInstance<'mongo', string>;\n }): Promise<ReadonlyMap<string, ContractMarkerRecord>> {\n const appMarker = await this.readMarker({ ...options, space: APP_SPACE_ID });\n if (appMarker === null) return new Map();\n return new Map([[APP_SPACE_ID, appMarker]]);\n }\n\n async introspect(options: {\n readonly driver: ControlDriverInstance<'mongo', string>;\n readonly contract?: unknown;\n }): Promise<MongoSchemaIR> {\n const db = extractDb(options.driver);\n return introspectSchema(db);\n }\n\n toSchemaView(schema: MongoSchemaIR): CoreSchemaView {\n return mongoSchemaToView(schema);\n }\n\n toOperationPreview(operations: readonly MigrationPlanOperation[]): OperationPreview {\n return {\n statements: formatMongoOperations(operations).map((text) => ({\n text,\n language: 'mongodb-shell',\n })),\n };\n }\n}\n\nfunction buildVerifyResult(opts: {\n ok: boolean;\n code?: string;\n summary: string;\n contractStorageHash: string;\n contractProfileHash?: string;\n marker?: ContractMarkerRecord;\n expectedTargetId: string;\n actualTargetId?: string;\n contractPath: string;\n configPath?: string;\n totalTime: number;\n}): VerifyDatabaseResult {\n return {\n ok: opts.ok,\n ...ifDefined('code', opts.code),\n summary: opts.summary,\n contract: {\n storageHash: opts.contractStorageHash,\n ...ifDefined('profileHash', opts.contractProfileHash),\n },\n ...ifDefined(\n 'marker',\n opts.marker\n ? { storageHash: opts.marker.storageHash, profileHash: opts.marker.profileHash }\n : undefined,\n ),\n target: {\n expected: opts.expectedTargetId,\n ...ifDefined('actual', opts.actualTargetId),\n },\n meta: {\n contractPath: opts.contractPath,\n ...ifDefined('configPath', opts.configPath),\n },\n timings: { total: opts.totalTime },\n };\n}\n\nexport function createMongoFamilyInstance(_controlStack: ControlStack): MongoControlFamilyInstance {\n return new MongoFamilyInstance();\n}\n","import type {\n ControlFamilyDescriptor,\n ControlStack,\n} from '@prisma-next/framework-components/control';\nimport { mongoEmission } from '@prisma-next/mongo-emitter';\nimport { createMongoFamilyInstance, type MongoControlFamilyInstance } from './control-instance';\n\nclass MongoFamilyDescriptor\n implements ControlFamilyDescriptor<'mongo', MongoControlFamilyInstance>\n{\n readonly kind = 'family' as const;\n readonly id = 'mongo';\n readonly familyId = 'mongo' as const;\n readonly version = '0.0.1';\n readonly emission = mongoEmission;\n\n create<TTargetId extends string>(\n stack: ControlStack<'mongo', TTargetId>,\n ): MongoControlFamilyInstance {\n return createMongoFamilyInstance(stack);\n }\n}\n\nexport const mongoFamilyDescriptor: ControlFamilyDescriptor<'mongo', MongoControlFamilyInstance> =\n new MongoFamilyDescriptor();\n","import { createMongoRunnerDeps, extractDb } from '@prisma-next/adapter-mongo/control';\nimport type { Contract } from '@prisma-next/contract/types';\nimport { MongoDriverImpl } from '@prisma-next/driver-mongo';\nimport type {\n MigratableTargetDescriptor,\n MigrationRunner,\n} from '@prisma-next/framework-components/control';\nimport type { MongoContract } from '@prisma-next/mongo-contract';\nimport {\n contractToMongoSchemaIR,\n MongoMigrationPlanner,\n MongoMigrationRunner,\n type MongoRunnerDependencies,\n} from '@prisma-next/target-mongo/control';\nimport mongoTargetDescriptorMeta from '@prisma-next/target-mongo/pack';\nimport type { MongoControlFamilyInstance } from './control-instance';\n\n/**\n * `migration.ts` default-exports a `Migration` subclass whose `operations`\n * getter returns the ordered list of operations and whose `describe()`\n * returns the manifest identity metadata. `MongoMigrationPlanner.plan()`\n * returns a `MigrationPlanWithAuthoringSurface` that knows how to render\n * itself back to such a file; `MongoMigrationPlanner.emptyMigration()`\n * returns the same shape for `migration new`. Users run the scaffolded\n * `migration.ts` directly (via `node migration.ts`) to self-emit\n * `ops.json` and attest the `migrationHash`.\n */\nexport const mongoTargetDescriptor: MigratableTargetDescriptor<\n 'mongo',\n 'mongo',\n MongoControlFamilyInstance\n> = {\n ...mongoTargetDescriptorMeta,\n migrations: {\n createPlanner(_family: MongoControlFamilyInstance) {\n return new MongoMigrationPlanner();\n },\n createRunner(family: MongoControlFamilyInstance) {\n // Deps are bound to the first driver passed to execute() and cached for\n // subsequent calls. Callers must not change the driver between calls.\n let cachedDeps: MongoRunnerDependencies | undefined;\n const runner: MigrationRunner<'mongo', 'mongo'> = {\n async execute(options) {\n cachedDeps ??= createMongoRunnerDeps(\n options.driver,\n MongoDriverImpl.fromDb(extractDb(options.driver)),\n family,\n );\n const { driver: _, ...runnerOptions } = options;\n // The framework `MigrationRunner` interface types `destinationContract`\n // as `unknown`; the Mongo runner narrows to `MongoContract`. Validation\n // happens upstream — `migration apply` calls\n // `familyInstance.validateContract(migration.toContract)` before\n // routing the contract here (see\n // `packages/1-framework/3-tooling/cli/src/control-api/operations/migration-apply.ts`),\n // so this cast simply preserves the framework signature without\n // weakening the runner's typed surface or duplicating validation.\n return new MongoMigrationRunner(cachedDeps).execute({\n ...runnerOptions,\n destinationContract: runnerOptions.destinationContract as MongoContract,\n });\n },\n };\n return runner;\n },\n contractToSchema(contract: Contract | null) {\n return contractToMongoSchemaIR(contract as MongoContract | null);\n },\n },\n create() {\n return { familyId: 'mongo' as const, targetId: 'mongo' as const };\n },\n};\n"],"mappings":"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"}
@@ -2,7 +2,6 @@ import { Migration } from "@prisma-next/migration-tools/migration";
2
2
  import { AnyMongoMigrationOperation } from "@prisma-next/mongo-query-ast/control";
3
3
 
4
4
  //#region src/core/mongo-migration.d.ts
5
-
6
5
  /**
7
6
  * Family-owned base class for Mongo migrations.
8
7
  *
@@ -1 +1 @@
1
- {"version":3,"file":"migration.d.mts","names":[],"sources":["../src/core/mongo-migration.ts"],"sourcesContent":[],"mappings":";;;;;;;AAiBA;;;;;;;;;;;;uBAAsB,cAAA,SAAuB,UAAU"}
1
+ {"version":3,"file":"migration.d.mts","names":[],"sources":["../src/core/mongo-migration.ts"],"mappings":";;;;;;AAiBA;;;;;;;;;;;;uBAAsB,cAAA,SAAuB,SAAA,CAAU,0BAAA;EAAA,SAC5C,QAAA;AAAA"}
@@ -1,5 +1,4 @@
1
1
  import { Migration } from "@prisma-next/migration-tools/migration";
2
-
3
2
  //#region src/core/mongo-migration.ts
4
3
  /**
5
4
  * Family-owned base class for Mongo migrations.
@@ -18,7 +17,7 @@ import { Migration } from "@prisma-next/migration-tools/migration";
18
17
  var MongoMigration = class extends Migration {
19
18
  targetId = "mongo";
20
19
  };
21
-
22
20
  //#endregion
23
21
  export { MongoMigration as Migration };
22
+
24
23
  //# sourceMappingURL=migration.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"migration.mjs","names":[],"sources":["../src/core/mongo-migration.ts"],"sourcesContent":["import { Migration } from '@prisma-next/migration-tools/migration';\nimport type { AnyMongoMigrationOperation } from '@prisma-next/mongo-query-ast/control';\n\n/**\n * Family-owned base class for Mongo migrations.\n *\n * Provides the fixed `targetId = 'mongo'` so that user-authored migrations\n * and renderer-generated scaffolds (e.g. the output of\n * `renderCallsToTypeScript`) inherit it directly and don't have to re-declare\n * the abstract `targetId` member from `Migration`.\n *\n * The operation type parameter is `AnyMongoMigrationOperation` — the union\n * of DDL-shaped `MongoMigrationPlanOperation` and `MongoDataTransformOperation` —\n * so subclasses can return a mix of schema operations (e.g. `createIndex`,\n * `setValidation`) and data-transform operations (e.g. `dataTransform`).\n * Mirrors the generic parameter used by `PlannerProducedMongoMigration`.\n */\nexport abstract class MongoMigration extends Migration<AnyMongoMigrationOperation> {\n readonly targetId = 'mongo' as const;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AAiBA,IAAsB,iBAAtB,cAA6C,UAAsC;CACjF,AAAS,WAAW"}
1
+ {"version":3,"file":"migration.mjs","names":[],"sources":["../src/core/mongo-migration.ts"],"sourcesContent":["import { Migration } from '@prisma-next/migration-tools/migration';\nimport type { AnyMongoMigrationOperation } from '@prisma-next/mongo-query-ast/control';\n\n/**\n * Family-owned base class for Mongo migrations.\n *\n * Provides the fixed `targetId = 'mongo'` so that user-authored migrations\n * and renderer-generated scaffolds (e.g. the output of\n * `renderCallsToTypeScript`) inherit it directly and don't have to re-declare\n * the abstract `targetId` member from `Migration`.\n *\n * The operation type parameter is `AnyMongoMigrationOperation` — the union\n * of DDL-shaped `MongoMigrationPlanOperation` and `MongoDataTransformOperation` —\n * so subclasses can return a mix of schema operations (e.g. `createIndex`,\n * `setValidation`) and data-transform operations (e.g. `dataTransform`).\n * Mirrors the generic parameter used by `PlannerProducedMongoMigration`.\n */\nexport abstract class MongoMigration extends Migration<AnyMongoMigrationOperation> {\n readonly targetId = 'mongo' as const;\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAiBA,IAAsB,iBAAtB,cAA6C,UAAsC;CACjF,WAAoB"}
@@ -1 +1 @@
1
- {"version":3,"file":"pack.d.mts","names":[],"sources":["../src/exports/pack.ts"],"sourcesContent":[],"mappings":";cAAM;EAAA,SAAA,IAAA,EAAA,QAKI"}
1
+ {"version":3,"file":"pack.d.mts","names":[],"sources":["../src/exports/pack.ts"],"mappings":";cAAM,eAAA;EAAA"}
package/dist/pack.mjs CHANGED
@@ -5,8 +5,7 @@ const mongoFamilyPack = {
5
5
  familyId: "mongo",
6
6
  version: "0.0.1"
7
7
  };
8
- var pack_default = mongoFamilyPack;
9
-
10
8
  //#endregion
11
- export { pack_default as default };
9
+ export { mongoFamilyPack as default };
10
+
12
11
  //# sourceMappingURL=pack.mjs.map
package/dist/pack.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"pack.mjs","names":[],"sources":["../src/exports/pack.ts"],"sourcesContent":["const mongoFamilyPack = {\n kind: 'family',\n id: 'mongo',\n familyId: 'mongo',\n version: '0.0.1',\n} as const;\n\nexport default mongoFamilyPack;\n"],"mappings":";AAAA,MAAM,kBAAkB;CACtB,MAAM;CACN,IAAI;CACJ,UAAU;CACV,SAAS;CACV;AAED,mBAAe"}
1
+ {"version":3,"file":"pack.mjs","names":[],"sources":["../src/exports/pack.ts"],"sourcesContent":["const mongoFamilyPack = {\n kind: 'family',\n id: 'mongo',\n familyId: 'mongo',\n version: '0.0.1',\n} as const;\n\nexport default mongoFamilyPack;\n"],"mappings":";AAAA,MAAM,kBAAkB;CACtB,MAAM;CACN,IAAI;CACJ,UAAU;CACV,SAAS;CACV"}
@@ -1,3 +1,2 @@
1
1
  import { verifyMongoSchema } from "@prisma-next/target-mongo/schema-verify";
2
-
3
- export { verifyMongoSchema };
2
+ export { verifyMongoSchema };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@prisma-next/family-mongo",
3
- "version": "0.5.0-dev.66",
3
+ "version": "0.5.0-dev.68",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -8,27 +8,27 @@
8
8
  "dependencies": {
9
9
  "mongodb": "^6.16.0",
10
10
  "pathe": "^2.0.3",
11
- "@prisma-next/adapter-mongo": "0.5.0-dev.66",
12
- "@prisma-next/contract": "0.5.0-dev.66",
13
- "@prisma-next/emitter": "0.5.0-dev.66",
14
- "@prisma-next/driver-mongo": "0.5.0-dev.66",
15
- "@prisma-next/errors": "0.5.0-dev.66",
16
- "@prisma-next/framework-components": "0.5.0-dev.66",
17
- "@prisma-next/mongo-contract": "0.5.0-dev.66",
18
- "@prisma-next/mongo-emitter": "0.5.0-dev.66",
19
- "@prisma-next/mongo-query-ast": "0.5.0-dev.66",
20
- "@prisma-next/migration-tools": "0.5.0-dev.66",
21
- "@prisma-next/target-mongo": "0.5.0-dev.66",
22
- "@prisma-next/mongo-schema-ir": "0.5.0-dev.66",
23
- "@prisma-next/utils": "0.5.0-dev.66"
11
+ "@prisma-next/adapter-mongo": "0.5.0-dev.68",
12
+ "@prisma-next/driver-mongo": "0.5.0-dev.68",
13
+ "@prisma-next/contract": "0.5.0-dev.68",
14
+ "@prisma-next/emitter": "0.5.0-dev.68",
15
+ "@prisma-next/framework-components": "0.5.0-dev.68",
16
+ "@prisma-next/mongo-contract": "0.5.0-dev.68",
17
+ "@prisma-next/migration-tools": "0.5.0-dev.68",
18
+ "@prisma-next/mongo-emitter": "0.5.0-dev.68",
19
+ "@prisma-next/mongo-query-ast": "0.5.0-dev.68",
20
+ "@prisma-next/mongo-schema-ir": "0.5.0-dev.68",
21
+ "@prisma-next/target-mongo": "0.5.0-dev.68",
22
+ "@prisma-next/utils": "0.5.0-dev.68",
23
+ "@prisma-next/errors": "0.5.0-dev.68"
24
24
  },
25
25
  "devDependencies": {
26
- "tsdown": "0.18.4",
26
+ "tsdown": "0.22.0",
27
27
  "typescript": "5.9.3",
28
- "vitest": "4.0.17",
29
- "@prisma-next/mongo-contract-ts": "0.5.0-dev.66",
30
- "@prisma-next/tsdown": "0.0.0",
31
- "@prisma-next/tsconfig": "0.0.0"
28
+ "vitest": "4.1.5",
29
+ "@prisma-next/mongo-contract-ts": "0.5.0-dev.68",
30
+ "@prisma-next/tsconfig": "0.0.0",
31
+ "@prisma-next/tsdown": "0.0.0"
32
32
  },
33
33
  "files": [
34
34
  "dist",
@@ -170,6 +170,21 @@ class MongoFamilyInstance implements MongoControlFamilyInstance {
170
170
  });
171
171
  }
172
172
 
173
+ schemaVerifyAgainstSchema(options: {
174
+ readonly contract: unknown;
175
+ readonly schema: MongoSchemaIR;
176
+ readonly strict: boolean;
177
+ readonly frameworkComponents: ReadonlyArray<TargetBoundComponentDescriptor<'mongo', string>>;
178
+ }): VerifyDatabaseSchemaResult {
179
+ const validated = validateMongoContract<MongoContract>(options.contract);
180
+ return verifyMongoSchema({
181
+ contract: validated.contract,
182
+ schema: options.schema,
183
+ strict: options.strict,
184
+ frameworkComponents: options.frameworkComponents,
185
+ });
186
+ }
187
+
173
188
  async sign(options: {
174
189
  readonly driver: ControlDriverInstance<'mongo', string>;
175
190
  readonly contract: unknown;
@@ -269,6 +284,19 @@ class MongoFamilyInstance implements MongoControlFamilyInstance {
269
284
  return readMarker(db);
270
285
  }
271
286
 
287
+ // Mongo does not yet participate in the per-space mechanism — the
288
+ // `space` column was introduced in the SQL family's marker only.
289
+ // The bridge: surface the single app marker keyed by APP_SPACE_ID so
290
+ // the per-space verifier sees a coherent input shape; per-space mongo
291
+ // support is a future extension.
292
+ async readAllMarkers(options: {
293
+ readonly driver: ControlDriverInstance<'mongo', string>;
294
+ }): Promise<ReadonlyMap<string, ContractMarkerRecord>> {
295
+ const appMarker = await this.readMarker({ ...options, space: APP_SPACE_ID });
296
+ if (appMarker === null) return new Map();
297
+ return new Map([[APP_SPACE_ID, appMarker]]);
298
+ }
299
+
272
300
  async introspect(options: {
273
301
  readonly driver: ControlDriverInstance<'mongo', string>;
274
302
  readonly contract?: unknown;