{"version":3,"file":"index.mjs","names":[],"sources":["../../src/canonicalize.ts","../../src/index-equivalence.ts","../../src/schema-node.ts","../../src/schema-collection.ts","../../src/schema-collection-options.ts","../../src/schema-index.ts","../../src/schema-ir.ts","../../src/schema-validator.ts"],"sourcesContent":["export function canonicalize(obj: unknown): string {\n  if (obj === null) return 'null';\n  if (obj === undefined) return 'undefined';\n  if (typeof obj !== 'object') return JSON.stringify(obj);\n  if (Array.isArray(obj)) return `[${obj.map(canonicalize).join(',')}]`;\n  const record = obj as Record<string, unknown>;\n  const sorted = Object.keys(record).sort();\n  const entries = sorted.map((k) => `${JSON.stringify(k)}:${canonicalize(record[k])}`);\n  return `{${entries.join(',')}}`;\n}\n","import { canonicalize } from './canonicalize';\nimport type { MongoSchemaIndex } from './schema-index';\n\n/**\n * Key-order-sensitive structural comparison. For key-order-independent\n * comparison (e.g. lookup key construction), use {@link canonicalize}.\n */\nexport function deepEqual(a: unknown, b: unknown): boolean {\n  if (a === b) return true;\n  if (a === null || b === null) return false;\n  if (a === undefined || b === undefined) return false;\n  if (typeof a !== typeof b) return false;\n\n  if (Array.isArray(a)) {\n    if (!Array.isArray(b)) return false;\n    if (a.length !== b.length) return false;\n    for (let i = 0; i < a.length; i++) {\n      if (!deepEqual(a[i], b[i])) return false;\n    }\n    return true;\n  }\n\n  if (typeof a === 'object' && typeof b === 'object') {\n    const aObj = a as Record<string, unknown>;\n    const bObj = b as Record<string, unknown>;\n    const aKeys = Object.keys(aObj);\n    const bKeys = Object.keys(bObj);\n    if (aKeys.length !== bKeys.length) return false;\n    for (let i = 0; i < aKeys.length; i++) {\n      if (aKeys[i] !== bKeys[i]) return false;\n      const key = aKeys[i] as string;\n      if (!deepEqual(aObj[key], bObj[key])) return false;\n    }\n    return true;\n  }\n\n  return false;\n}\n\nexport function indexesEquivalent(a: MongoSchemaIndex, b: MongoSchemaIndex): boolean {\n  if (a.keys.length !== b.keys.length) return false;\n  for (let i = 0; i < a.keys.length; i++) {\n    const aKey = a.keys[i];\n    const bKey = b.keys[i];\n    if (!aKey || !bKey) return false;\n    if (aKey.field !== bKey.field) return false;\n    if (aKey.direction !== bKey.direction) return false;\n  }\n  if (a.unique !== b.unique) return false;\n  if (a.sparse !== b.sparse) return false;\n  if (a.expireAfterSeconds !== b.expireAfterSeconds) return false;\n  if (canonicalize(a.partialFilterExpression) !== canonicalize(b.partialFilterExpression))\n    return false;\n  if (canonicalize(a.wildcardProjection) !== canonicalize(b.wildcardProjection)) return false;\n  if (canonicalize(a.collation) !== canonicalize(b.collation)) return false;\n  if (canonicalize(a.weights) !== canonicalize(b.weights)) return false;\n  if (a.default_language !== b.default_language) return false;\n  if (a.language_override !== b.language_override) return false;\n  return true;\n}\n","import type { DiffableNode } from '@prisma-next/framework-components/control';\nimport { IRNodeBase } from '@prisma-next/framework-components/ir';\nimport type { MongoSchemaVisitor } from './visitor';\n\n/**\n * Every concrete Mongo schema-IR node also implements the framework's\n * `DiffableNode` interface, so a node can be carried as the `expected`/\n * `actual` payload of a `SchemaDiffIssue`. Mongo's own diff (`diffMongoSchemas`)\n * still hand-rolls its comparisons and never calls `isEqualTo`/`children` —\n * this conformance exists so an issue can carry the real collection/index/\n * validator/options node it concerns, not a coordinate string.\n *\n * Follow-up: `isEqualTo`/`children` are dead weight on every Mongo node\n * (nothing calls them). The honest fix is splitting `DiffableNode` into a\n * narrower \"issue payload\" bound (just `id`) that this class implements,\n * separate from the full walkable `DiffableNode` (`id` + `isEqualTo` +\n * `children`) the generic differ actually pairs and recurses over.\n */\nexport abstract class MongoSchemaIRNode extends IRNodeBase implements DiffableNode {\n  declare readonly kind: string;\n\n  abstract readonly id: string;\n  /** Per-node discriminant `DiffableNode` requires: collection / index / validator / collectionOptions / schema. */\n  abstract readonly nodeKind: string;\n  abstract accept<R>(visitor: MongoSchemaVisitor<R>): R;\n\n  constructor() {\n    super();\n    Object.defineProperty(this, 'kind', {\n      value: 'mongo-schema-ir',\n      writable: false,\n      enumerable: false,\n      configurable: false,\n    });\n  }\n\n  isEqualTo(other: DiffableNode): boolean {\n    return this.id === other.id;\n  }\n\n  children(): readonly DiffableNode[] {\n    return [];\n  }\n}\n","import { freezeNode } from '@prisma-next/framework-components/ir';\nimport type { MongoSchemaCollectionOptions } from './schema-collection-options';\nimport type { MongoSchemaIndex } from './schema-index';\nimport { MongoSchemaIRNode } from './schema-node';\nimport type { MongoSchemaValidator } from './schema-validator';\nimport type { MongoSchemaVisitor } from './visitor';\n\nexport interface MongoSchemaCollectionCtorOptions {\n  readonly name: string;\n  readonly indexes?: ReadonlyArray<MongoSchemaIndex>;\n  readonly validator?: MongoSchemaValidator;\n  readonly options?: MongoSchemaCollectionOptions;\n}\n\nexport class MongoSchemaCollection extends MongoSchemaIRNode {\n  readonly nodeKind = 'collection' as const;\n  readonly id: string;\n  readonly name: string;\n  readonly indexes: ReadonlyArray<MongoSchemaIndex>;\n  readonly validator?: MongoSchemaValidator | undefined;\n  readonly options?: MongoSchemaCollectionOptions | undefined;\n\n  constructor(options: MongoSchemaCollectionCtorOptions) {\n    super();\n    this.id = options.name;\n    this.name = options.name;\n    this.indexes = options.indexes ?? [];\n    this.validator = options.validator;\n    this.options = options.options;\n    freezeNode(this);\n  }\n\n  accept<R>(visitor: MongoSchemaVisitor<R>): R {\n    return visitor.collection(this);\n  }\n}\n","import { freezeNode } from '@prisma-next/framework-components/ir';\nimport type { CollationOptions } from '@prisma-next/mongo-value/mongodb-types';\nimport { MongoSchemaIRNode } from './schema-node';\nimport type { MongoSchemaVisitor } from './visitor';\n\nexport interface MongoSchemaCollectionOptionsInput {\n  readonly capped?: { size: number; max?: number };\n  readonly timeseries?: {\n    timeField: string;\n    metaField?: string;\n    granularity?: 'seconds' | 'minutes' | 'hours';\n  };\n  readonly collation?: CollationOptions;\n  readonly changeStreamPreAndPostImages?: { enabled: boolean };\n  readonly clusteredIndex?: { name?: string };\n}\n\nexport class MongoSchemaCollectionOptions extends MongoSchemaIRNode {\n  readonly nodeKind = 'collectionOptions' as const;\n  /** Fixed sentinel: at most one options node exists per collection. */\n  readonly id = 'options';\n  readonly capped?: { size: number; max?: number } | undefined;\n  readonly timeseries?:\n    | { timeField: string; metaField?: string; granularity?: 'seconds' | 'minutes' | 'hours' }\n    | undefined;\n  readonly collation?: CollationOptions | undefined;\n  readonly changeStreamPreAndPostImages?: { enabled: boolean } | undefined;\n  readonly clusteredIndex?: { name?: string } | undefined;\n\n  constructor(options: MongoSchemaCollectionOptionsInput) {\n    super();\n    this.capped = options.capped;\n    this.timeseries = options.timeseries;\n    this.collation = options.collation;\n    this.changeStreamPreAndPostImages = options.changeStreamPreAndPostImages;\n    this.clusteredIndex = options.clusteredIndex;\n    freezeNode(this);\n  }\n\n  accept<R>(visitor: MongoSchemaVisitor<R>): R {\n    return visitor.collectionOptions(this);\n  }\n}\n","import { freezeNode } from '@prisma-next/framework-components/ir';\nimport type { MongoIndexKey } from '@prisma-next/mongo-contract';\nimport type { CollationOptions } from '@prisma-next/mongo-value/mongodb-types';\nimport { MongoSchemaIRNode } from './schema-node';\nimport type { MongoSchemaVisitor } from './visitor';\n\nexport interface MongoSchemaIndexOptions {\n  readonly keys: ReadonlyArray<MongoIndexKey>;\n  readonly unique?: boolean | undefined;\n  readonly sparse?: boolean | undefined;\n  readonly expireAfterSeconds?: number | undefined;\n  readonly partialFilterExpression?: Record<string, unknown> | undefined;\n  readonly wildcardProjection?: Record<string, 0 | 1> | undefined;\n  readonly collation?: CollationOptions | undefined;\n  readonly weights?: Record<string, number> | undefined;\n  readonly default_language?: string | undefined;\n  readonly language_override?: string | undefined;\n}\n\nexport class MongoSchemaIndex extends MongoSchemaIRNode {\n  readonly nodeKind = 'index' as const;\n  readonly id: string;\n  readonly keys: ReadonlyArray<MongoIndexKey>;\n  readonly unique: boolean;\n  readonly sparse?: boolean | undefined;\n  readonly expireAfterSeconds?: number | undefined;\n  readonly partialFilterExpression?: Record<string, unknown> | undefined;\n  readonly wildcardProjection?: Record<string, 0 | 1> | undefined;\n  readonly collation?: CollationOptions | undefined;\n  readonly weights?: Record<string, number> | undefined;\n  readonly default_language?: string | undefined;\n  readonly language_override?: string | undefined;\n\n  constructor(options: MongoSchemaIndexOptions) {\n    super();\n    this.id = options.keys.map((k) => `${k.field}:${k.direction}`).join(',');\n    this.keys = options.keys;\n    this.unique = options.unique ?? false;\n    this.sparse = options.sparse;\n    this.expireAfterSeconds = options.expireAfterSeconds;\n    this.partialFilterExpression = options.partialFilterExpression;\n    this.wildcardProjection = options.wildcardProjection;\n    this.collation = options.collation;\n    this.weights = options.weights;\n    this.default_language = options.default_language;\n    this.language_override = options.language_override;\n    freezeNode(this);\n  }\n\n  accept<R>(visitor: MongoSchemaVisitor<R>): R {\n    return visitor.index(this);\n  }\n}\n","import { freezeNode } from '@prisma-next/framework-components/ir';\nimport type { MongoSchemaCollection } from './schema-collection';\nimport { MongoSchemaIRNode } from './schema-node';\nimport type { MongoSchemaVisitor } from './visitor';\n\nexport class MongoSchemaIR extends MongoSchemaIRNode {\n  readonly nodeKind = 'schema' as const;\n  /** Fixed sentinel: the schema is always the diff tree's single root. */\n  readonly id = 'schema';\n  readonly collections: ReadonlyArray<MongoSchemaCollection>;\n  readonly collectionNames: ReadonlyArray<string>;\n\n  private readonly _byName: Map<string, MongoSchemaCollection>;\n\n  constructor(collections: ReadonlyArray<MongoSchemaCollection>) {\n    super();\n    const sorted = [...collections].sort((a, b) => a.name.localeCompare(b.name));\n    this.collections = sorted;\n    this._byName = new Map(sorted.map((c) => [c.name, c]));\n    this.collectionNames = sorted.map((c) => c.name);\n    freezeNode(this);\n  }\n\n  accept<R>(visitor: MongoSchemaVisitor<R>): R {\n    return visitor.schema(this);\n  }\n\n  collection(name: string): MongoSchemaCollection | undefined {\n    return this._byName.get(name);\n  }\n}\n","import { freezeNode } from '@prisma-next/framework-components/ir';\nimport { MongoSchemaIRNode } from './schema-node';\nimport type { MongoSchemaVisitor } from './visitor';\n\nexport interface MongoSchemaValidatorOptions {\n  readonly jsonSchema: Record<string, unknown>;\n  readonly validationLevel: 'strict' | 'moderate';\n  readonly validationAction: 'error' | 'warn';\n}\n\nexport class MongoSchemaValidator extends MongoSchemaIRNode {\n  readonly nodeKind = 'validator' as const;\n  /** Fixed sentinel: at most one validator exists per collection. */\n  readonly id = 'validator';\n  readonly jsonSchema: Record<string, unknown>;\n  readonly validationLevel: 'strict' | 'moderate';\n  readonly validationAction: 'error' | 'warn';\n\n  constructor(options: MongoSchemaValidatorOptions) {\n    super();\n    this.jsonSchema = options.jsonSchema;\n    this.validationLevel = options.validationLevel;\n    this.validationAction = options.validationAction;\n    freezeNode(this);\n  }\n\n  accept<R>(visitor: MongoSchemaVisitor<R>): R {\n    return visitor.validator(this);\n  }\n}\n"],"mappings":"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"}