{"version":3,"file":"ir.mjs","names":[],"sources":["../src/core/ir/mongo-schema-verifier-base.ts"],"sourcesContent":["import type { ControlPolicy } from '@prisma-next/contract/types';\nimport { effectiveControlPolicy } from '@prisma-next/contract/types';\nimport type {\n  SchemaDiffIssue,\n  SchemaVerifier,\n  SchemaVerifyOptions,\n  SchemaVerifyResult,\n} from '@prisma-next/framework-components/control';\nimport type { Namespace } from '@prisma-next/framework-components/ir';\nimport { UNBOUND_NAMESPACE_ID } from '@prisma-next/framework-components/ir';\nimport type { MongoCollection, MongoStorage } from '@prisma-next/mongo-contract';\n\n/**\n * Mongo family `SchemaVerifier` abstract base. Commits the Mongo family\n * to namespace-keyed verification: the family-shared walk iterates\n * `storage.namespaces` in sorted order and dispatches per-namespace\n * through the protected `verifyNamespace` hook, then aggregates\n * target-extension issues from `verifyTargetExtensions`.\n *\n * Per-element diff work (collection / index / validator comparisons)\n * lives on the target inside `verifyNamespace`. The family's structural\n * commitment is \"verification is namespaced\"; the target's commitment is\n * \"verification of a given namespace's collections is the existing\n * diff/canonicalize pipeline\". The split keeps target-mongo's\n * introspection-side helpers (`contractToMongoSchemaIR`,\n * `canonicalizeSchemasForVerification`, `diffMongoSchemas`) in the target\n * layer where they belong, while the family base owns the iteration\n * scaffolding that makes namespaces a first-class verifier concept.\n *\n * Target-specific issue kinds (Atlas-only, future RLS-equivalents)\n * surface through `verifyTargetExtensions`; that hook returns the empty\n * list when no extensions exist over the Mongo family alphabet.\n */\nexport abstract class MongoSchemaVerifierBase<\n  TContract extends {\n    readonly storage: MongoStorage;\n    readonly defaultControlPolicy?: ControlPolicy;\n  },\n  TSchema,\n> implements SchemaVerifier<TContract, TSchema>\n{\n  verifySchema(options: SchemaVerifyOptions<TContract, TSchema>): SchemaVerifyResult {\n    const issues: SchemaDiffIssue[] = [];\n    issues.push(...this.verifyCommonMongoSchema(options));\n    issues.push(...this.verifyTargetExtensions(options));\n    return { ok: issues.length === 0, issues };\n  }\n\n  protected effectiveCollectionControlPolicy(\n    contract: TContract,\n    collection: MongoCollection | undefined,\n  ): ControlPolicy {\n    return effectiveControlPolicy(collection?.control, contract.defaultControlPolicy);\n  }\n\n  protected collectionControlPolicyForName(\n    contract: TContract,\n    collectionName: string,\n  ): ControlPolicy {\n    const namespace = contract.storage.namespaces[UNBOUND_NAMESPACE_ID];\n    const collection = namespace?.entries.collection?.[collectionName];\n    return this.effectiveCollectionControlPolicy(contract, collection);\n  }\n\n  protected verifyCommonMongoSchema(\n    options: SchemaVerifyOptions<TContract, TSchema>,\n  ): readonly SchemaDiffIssue[] {\n    const issues: SchemaDiffIssue[] = [];\n    const { namespaces } = options.contract.storage;\n    const namespaceIds = Object.keys(namespaces).sort();\n    for (const namespaceId of namespaceIds) {\n      const namespace = namespaces[namespaceId];\n      if (!namespace) continue;\n      issues.push(\n        ...this.verifyNamespace({\n          contract: options.contract,\n          schema: options.schema,\n          namespaceId,\n          namespace,\n        }),\n      );\n    }\n    return issues;\n  }\n\n  /**\n   * Per-namespace verification hook. Receives the namespace metadata plus\n   * the full contract + schema pair; the target's implementation owns the\n   * per-collection diff using its existing introspection-side helpers.\n   * Slice the schema by namespace at the call site (or compute the full\n   * diff once and dispatch per namespace) — the family base does not\n   * prescribe the per-namespace shape.\n   */\n  protected abstract verifyNamespace(options: {\n    readonly contract: TContract;\n    readonly schema: TSchema;\n    readonly namespaceId: string;\n    readonly namespace: Namespace;\n  }): readonly SchemaDiffIssue[];\n\n  /**\n   * Target-specific extensions — Atlas-only kinds, target-only\n   * namespace-mismatch issues that don't fit the family-shared walk.\n   * Returns the empty list when the target ships no extensions.\n   */\n  protected abstract verifyTargetExtensions(\n    options: SchemaVerifyOptions<TContract, TSchema>,\n  ): readonly SchemaDiffIssue[];\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAiCA,IAAsB,0BAAtB,MAOA;CACE,aAAa,SAAsE;EACjF,MAAM,SAA4B,CAAC;EACnC,OAAO,KAAK,GAAG,KAAK,wBAAwB,OAAO,CAAC;EACpD,OAAO,KAAK,GAAG,KAAK,uBAAuB,OAAO,CAAC;EACnD,OAAO;GAAE,IAAI,OAAO,WAAW;GAAG;EAAO;CAC3C;CAEA,iCACE,UACA,YACe;EACf,OAAO,uBAAuB,YAAY,SAAS,SAAS,oBAAoB;CAClF;CAEA,+BACE,UACA,gBACe;EAEf,MAAM,aADY,SAAS,QAAQ,WAAW,qBAClB,EAAE,QAAQ,aAAa;EACnD,OAAO,KAAK,iCAAiC,UAAU,UAAU;CACnE;CAEA,wBACE,SAC4B;EAC5B,MAAM,SAA4B,CAAC;EACnC,MAAM,EAAE,eAAe,QAAQ,SAAS;EACxC,MAAM,eAAe,OAAO,KAAK,UAAU,CAAC,CAAC,KAAK;EAClD,KAAK,MAAM,eAAe,cAAc;GACtC,MAAM,YAAY,WAAW;GAC7B,IAAI,CAAC,WAAW;GAChB,OAAO,KACL,GAAG,KAAK,gBAAgB;IACtB,UAAU,QAAQ;IAClB,QAAQ,QAAQ;IAChB;IACA;GACF,CAAC,CACH;EACF;EACA,OAAO;CACT;AAyBF"}