{"version":3,"file":"index.mjs","names":["#contract","#state","#withStage","#writeTerminal","#writeMeta","#ctx","#modelName","#filters","#foldedFilter"],"sources":["../src/accumulator-helpers.ts","../src/lookup-builder.ts","../src/pipeline-result-shape.ts","../src/result-shape.ts","../src/builder.ts","../src/expression-helpers.ts","../src/state-classes.ts","../src/query.ts"],"sourcesContent":["import type { MongoAggExpr } from '@prisma-next/mongo-query-ast/execution';\nimport { MongoAggAccumulator, MongoAggLiteral } from '@prisma-next/mongo-query-ast/execution';\nimport type {\n  ArrayField,\n  DocField,\n  NullableNumericField,\n  NumericField,\n  TypedAccumulatorExpr,\n  TypedAggExpr,\n} from './types';\n\nfunction namedAccumulatorArgs(\n  args: Readonly<Record<string, TypedAggExpr<DocField> | undefined>>,\n): Record<string, MongoAggExpr> {\n  const result: Record<string, MongoAggExpr> = {};\n  for (const [key, val] of Object.entries(args)) {\n    if (val !== undefined) {\n      result[key] = val.node;\n    }\n  }\n  return result;\n}\n\nexport const acc = {\n  sum<F extends DocField>(expr: TypedAggExpr<F>): TypedAccumulatorExpr<F> {\n    return { _field: undefined as never, node: MongoAggAccumulator.sum(expr.node) };\n  },\n\n  avg(expr: TypedAggExpr<DocField>): TypedAccumulatorExpr<NullableNumericField> {\n    return { _field: undefined as never, node: MongoAggAccumulator.avg(expr.node) };\n  },\n\n  min<F extends DocField>(\n    expr: TypedAggExpr<F>,\n  ): TypedAccumulatorExpr<{ readonly codecId: F['codecId']; readonly nullable: true }> {\n    return { _field: undefined as never, node: MongoAggAccumulator.min(expr.node) };\n  },\n\n  max<F extends DocField>(\n    expr: TypedAggExpr<F>,\n  ): TypedAccumulatorExpr<{ readonly codecId: F['codecId']; readonly nullable: true }> {\n    return { _field: undefined as never, node: MongoAggAccumulator.max(expr.node) };\n  },\n\n  first<F extends DocField>(\n    expr: TypedAggExpr<F>,\n  ): TypedAccumulatorExpr<{ readonly codecId: F['codecId']; readonly nullable: true }> {\n    return { _field: undefined as never, node: MongoAggAccumulator.first(expr.node) };\n  },\n\n  last<F extends DocField>(\n    expr: TypedAggExpr<F>,\n  ): TypedAccumulatorExpr<{ readonly codecId: F['codecId']; readonly nullable: true }> {\n    return { _field: undefined as never, node: MongoAggAccumulator.last(expr.node) };\n  },\n\n  push(expr: TypedAggExpr<DocField>): TypedAccumulatorExpr<ArrayField> {\n    return { _field: undefined as never, node: MongoAggAccumulator.push(expr.node) };\n  },\n\n  addToSet(expr: TypedAggExpr<DocField>): TypedAccumulatorExpr<ArrayField> {\n    return { _field: undefined as never, node: MongoAggAccumulator.addToSet(expr.node) };\n  },\n\n  count(): TypedAccumulatorExpr<NumericField> {\n    return { _field: undefined as never, node: MongoAggAccumulator.count() };\n  },\n\n  stdDevPop(expr: TypedAggExpr<DocField>): TypedAccumulatorExpr<NullableNumericField> {\n    return { _field: undefined as never, node: MongoAggAccumulator.stdDevPop(expr.node) };\n  },\n\n  stdDevSamp(expr: TypedAggExpr<DocField>): TypedAccumulatorExpr<NullableNumericField> {\n    return { _field: undefined as never, node: MongoAggAccumulator.stdDevSamp(expr.node) };\n  },\n\n  firstN(args: {\n    input: TypedAggExpr<DocField>;\n    n: TypedAggExpr<NumericField>;\n  }): TypedAccumulatorExpr<ArrayField> {\n    return {\n      _field: undefined as never,\n      node: MongoAggAccumulator.of('$firstN', namedAccumulatorArgs(args)),\n    };\n  },\n\n  lastN(args: {\n    input: TypedAggExpr<DocField>;\n    n: TypedAggExpr<NumericField>;\n  }): TypedAccumulatorExpr<ArrayField> {\n    return {\n      _field: undefined as never,\n      node: MongoAggAccumulator.of('$lastN', namedAccumulatorArgs(args)),\n    };\n  },\n\n  maxN(args: {\n    input: TypedAggExpr<DocField>;\n    n: TypedAggExpr<NumericField>;\n  }): TypedAccumulatorExpr<ArrayField> {\n    return {\n      _field: undefined as never,\n      node: MongoAggAccumulator.of('$maxN', namedAccumulatorArgs(args)),\n    };\n  },\n\n  minN(args: {\n    input: TypedAggExpr<DocField>;\n    n: TypedAggExpr<NumericField>;\n  }): TypedAccumulatorExpr<ArrayField> {\n    return {\n      _field: undefined as never,\n      node: MongoAggAccumulator.of('$minN', namedAccumulatorArgs(args)),\n    };\n  },\n\n  top(args: {\n    output: TypedAggExpr<DocField>;\n    sortBy: Readonly<Record<string, 1 | -1>>;\n  }): TypedAccumulatorExpr<DocField> {\n    return {\n      _field: undefined as never,\n      node: MongoAggAccumulator.of('$top', {\n        output: args.output.node,\n        sortBy: MongoAggLiteral.of(args.sortBy),\n      }),\n    };\n  },\n\n  bottom(args: {\n    output: TypedAggExpr<DocField>;\n    sortBy: Readonly<Record<string, 1 | -1>>;\n  }): TypedAccumulatorExpr<DocField> {\n    return {\n      _field: undefined as never,\n      node: MongoAggAccumulator.of('$bottom', {\n        output: args.output.node,\n        sortBy: MongoAggLiteral.of(args.sortBy),\n      }),\n    };\n  },\n\n  topN(args: {\n    output: TypedAggExpr<DocField>;\n    sortBy: Readonly<Record<string, 1 | -1>>;\n    n: TypedAggExpr<NumericField>;\n  }): TypedAccumulatorExpr<ArrayField> {\n    return {\n      _field: undefined as never,\n      node: MongoAggAccumulator.of('$topN', {\n        output: args.output.node,\n        sortBy: MongoAggLiteral.of(args.sortBy),\n        n: args.n.node,\n      }),\n    };\n  },\n\n  bottomN(args: {\n    output: TypedAggExpr<DocField>;\n    sortBy: Readonly<Record<string, 1 | -1>>;\n    n: TypedAggExpr<NumericField>;\n  }): TypedAccumulatorExpr<ArrayField> {\n    return {\n      _field: undefined as never,\n      node: MongoAggAccumulator.of('$bottomN', {\n        output: args.output.node,\n        sortBy: MongoAggLiteral.of(args.sortBy),\n        n: args.n.node,\n      }),\n    };\n  },\n};\n","import { domainModelsAtDefaultNamespace } from '@prisma-next/contract/types';\nimport type {\n  MongoContract,\n  MongoModelDefinition,\n  MongoModelsMap,\n  RootModelName,\n} from '@prisma-next/mongo-contract';\nimport { createFieldAccessor, type FieldAccessor, type LeafExpression } from './field-accessor';\nimport type { ModelNestedShape } from './resolve-path';\nimport type { DocField, DocShape, ModelToDocShape } from './types';\n\n/**\n * Resolved foreign-model name for a contract root. Looks `RootName` up\n * through `TContract['roots']` and extracts the referenced model name\n * so it can be used as a `ModelName` index into `models`. Resolves to\n * `never` when the root is not present (this surface should never be\n * reachable through normal use because `from()` constrains its `R`\n * parameter to `keyof TContract['roots']`).\n */\nexport type ModelOf<\n  TContract extends MongoContract,\n  RootName extends keyof TContract['roots'] & string,\n> = RootModelName<TContract, RootName>;\n\n/**\n * Object returned by the user from the `on(...)` callback. Each side is\n * a `LeafExpression` produced by property access on the corresponding\n * `FieldAccessor` (`local._id`, `foreign.customerId`, etc.). Carrying\n * `LeafExpression` rather than the broader `TypedAggExpr` is what makes\n * non-leaf returns (e.g. `fn.toUpper(local._id)`) a compile-time error\n * without per-field operator gating — `LeafExpression` carries `_path`,\n * `TypedAggExpr` does not (see field-accessor.ts L47–L82).\n */\nexport interface LookupOnResult {\n  readonly local: LeafExpression<DocField>;\n  readonly foreign: LeafExpression<DocField>;\n}\n\n/**\n * Marker brand on the captured spec returned by the `lookup(...)`\n * callback. The phantom `_brand` literal lets `PipelineChain.lookup`\n * accept the result of `from(...).on(...).as(...)` without exposing the\n * internal field shape to user code, and prevents accidental\n * construction of a malformed spec by hand.\n */\nexport type LookupResultBrand = 'mongo-query-builder/lookup-result@1';\n\n/**\n * Captured output of the inner `from(name).on(cb).as(name)` chain. The\n * contract is consumed by `PipelineChain.lookup` to construct the\n * `MongoLookupStage` (collection name comes from `models[ModelName]\n * .storage.collection`) and to thread `ModelArrayField<ModelName>` into\n * the resulting `Shape` so the resolver yields `Array<ForeignRow>`.\n *\n * Type parameters carry the foreign-root literal `RootName`, the\n * resolved foreign model name `ModelName`, and the `As` literal so\n * `PipelineChain.lookup`'s return type can encode the result-row\n * promotion precisely.\n */\nexport interface LookupResult<\n  RootName extends string,\n  ModelName extends string,\n  As extends string,\n> {\n  readonly _brand: LookupResultBrand;\n  readonly _root: RootName;\n  readonly _model: ModelName;\n  readonly _localField: string;\n  readonly _foreignField: string;\n  readonly _as: As;\n}\n\n/**\n * Builder returned by `from(name).on(cb)`. Carries the foreign root /\n * model literals plus the captured local / foreign paths, and exposes\n * `.as(name)` to finalise the spec with the user-chosen field name.\n */\nexport interface LookupBuilderWithKey<RootName extends string, ModelName extends string> {\n  as<As extends string>(name: As): LookupResult<RootName, ModelName, As>;\n}\n\n/**\n * Builder returned by `from(name)`. Carries the foreign root / model\n * literals and the local pipeline's `Shape` / nested shape so the\n * `on(...)` callback's `local` and `foreign` accessors are typed\n * narrowly.\n *\n * `on(cb)` runs the user's callback to capture the leaf paths and\n * returns a `LookupBuilderWithKey` that exposes `.as(name)`.\n */\nexport interface LookupBuilder<\n  TContract extends MongoContract,\n  Shape extends DocShape,\n  Nested extends Record<string, DocField>,\n  RootName extends string,\n  ModelName extends string,\n> {\n  on(\n    cb: (\n      local: FieldAccessor<Shape, Nested>,\n      foreign: ModelName extends keyof MongoModelsMap<TContract> & string\n        ? FieldAccessor<\n            ModelToDocShape<TContract, ModelName>,\n            ModelNestedShape<TContract, ModelName>\n          >\n        : never,\n    ) => LookupOnResult,\n  ): LookupBuilderWithKey<RootName, ModelName>;\n}\n\n/**\n * Type of the `from` callable passed to `PipelineChain.lookup`'s outer\n * callback. The generic argument is inferred from a string-literal\n * argument (the same pattern as `mongoQuery<TC>(...).from('orders')`),\n * which grounds `RootName` into the returned `LookupBuilder` *before*\n * the inner `on(...)` callback is type-checked. This sequential\n * inference is what makes `foreign` resolve narrowly to the foreign\n * model's `FieldAccessor` (verified in the R1.5 spike — see spec § Open\n * Questions / Resolved decisions).\n */\nexport type LookupFrom<\n  TContract extends MongoContract,\n  Shape extends DocShape,\n  Nested extends Record<string, DocField>,\n> = <RootName extends keyof TContract['roots'] & string>(\n  name: RootName,\n) => LookupBuilder<TContract, Shape, Nested, RootName, ModelOf<TContract, RootName>>;\n\n/**\n * Construct the `from` callable for `PipelineChain.lookup`. The contract\n * is captured so `from(name)` can resolve `roots[name]` to the foreign\n * model name at runtime, look up the foreign collection name from\n * `models[modelName].storage.collection`, and assemble a `LookupResult`\n * for the outer `lookup` to consume.\n *\n * The `Shape`/`Nested` generics are erased at runtime — they exist only\n * to type the local accessor inside the user's `on(...)` callback. The\n * contract value at runtime carries the real model lookup table.\n */\nexport function createLookupFrom<\n  TContract extends MongoContract,\n  Shape extends DocShape,\n  Nested extends Record<string, DocField>,\n>(contract: TContract): LookupFrom<TContract, Shape, Nested> {\n  const callable = ((rootName) => {\n    const modelName = contract.roots[rootName]?.model;\n    if (!modelName) {\n      const validRoots = Object.keys(contract.roots).join(', ');\n      throw new Error(`lookup() unknown root: \"${rootName}\". Valid roots: ${validRoots}`);\n    }\n    const model = domainModelsAtDefaultNamespace(contract.domain)[modelName] as\n      | MongoModelDefinition\n      | undefined;\n    const foreignCollection = model?.storage?.collection ?? rootName;\n    return createLookupBuilder({\n      rootName,\n      modelName,\n      foreignCollection,\n    });\n    // The runtime callable accepts a single `string` and returns a\n    // generic `LookupBuilder`; the literal `RootName` / `ModelName`\n    // generics on `LookupFrom` are erased at runtime and re-asserted\n    // here so the surface contract is what the consumer actually sees.\n  }) as LookupFrom<TContract, Shape, Nested>;\n  return callable;\n}\n\ninterface LookupBuilderRuntimeState {\n  readonly rootName: string;\n  readonly modelName: string;\n  readonly foreignCollection: string;\n}\n\nfunction createLookupBuilder<\n  TContract extends MongoContract,\n  Shape extends DocShape,\n  Nested extends Record<string, DocField>,\n  RootName extends string,\n  ModelName extends string,\n>(state: LookupBuilderRuntimeState): LookupBuilder<TContract, Shape, Nested, RootName, ModelName> {\n  return {\n    on(cb) {\n      const localAccessor = createFieldAccessor<Shape, Nested>();\n      // Foreign accessor is built unparameterised at runtime — the codec\n      // metadata is type-only, and `_path` (the only thing we read off\n      // either side) is filled by property access regardless of the\n      // generic parameters. The narrow generic on the callback signature\n      // is what gives the user the foreign model's keys at compile time.\n      const foreignAccessor = createFieldAccessor<DocShape, Record<string, DocField>>();\n      const result = cb(localAccessor, foreignAccessor as Parameters<typeof cb>[1]);\n      assertLeafExpression(result.local, 'local');\n      assertLeafExpression(result.foreign, 'foreign');\n      return createLookupBuilderWithKey<RootName, ModelName>({\n        ...state,\n        localField: result.local._path,\n        foreignField: result.foreign._path,\n      });\n    },\n  };\n}\n\ninterface LookupBuilderWithKeyRuntimeState extends LookupBuilderRuntimeState {\n  readonly localField: string;\n  readonly foreignField: string;\n}\n\nfunction createLookupBuilderWithKey<RootName extends string, ModelName extends string>(\n  state: LookupBuilderWithKeyRuntimeState,\n): LookupBuilderWithKey<RootName, ModelName> {\n  return {\n    as<As extends string>(name: As): LookupResult<RootName, ModelName, As> {\n      return {\n        _brand: 'mongo-query-builder/lookup-result@1',\n        // The `RootName` / `ModelName` literal generics are erased at\n        // runtime; the runtime state holds the same strings as plain\n        // `string`. Re-brand so consumers (the lookup-stage builder)\n        // can read the literals back without a downstream cast.\n        _root: state.rootName as RootName,\n        _model: state.modelName as ModelName,\n        _localField: state.localField,\n        _foreignField: state.foreignField,\n        _as: name,\n      };\n    },\n  };\n}\n\n/**\n * Defensive runtime guard catching the case where a user returns a\n * non-`LeafExpression` from the `on(...)` callback (e.g. by casting\n * around the type system, or threading a value in from outside the\n * callback). Compile-time gating via `LookupOnResult`'s `LeafExpression`\n * type already rejects `fn.<op>(…)` returns at the type level — this\n * guard is the runtime backstop matching the defensive style of\n * `deconstructFindAndModifyChain` in builder.ts.\n */\nfunction assertLeafExpression(\n  value: LeafExpression<DocField>,\n  side: 'local' | 'foreign',\n): asserts value is LeafExpression<DocField> {\n  if (!value || typeof value._path !== 'string' || value._path.length === 0) {\n    throw new Error(\n      `lookup().on() ${side} side must return a leaf field reference (e.g. \\`${side}.<field>\\`). ` +\n        'Aggregation expressions and computed values are not supported.',\n    );\n  }\n}\n\n/**\n * Extract the runtime metadata from a `LookupResult` for `PipelineChain\n * .lookup` to construct the `MongoLookupStage`. The internal fields are\n * intentionally underscore-prefixed and brand-checked here so user code\n * cannot synthesise a fake spec; this is the single ingress point.\n */\nexport function extractLookupResult(\n  result: LookupResult<string, string, string>,\n  contract: MongoContract,\n): {\n  readonly foreignCollection: string;\n  readonly localField: string;\n  readonly foreignField: string;\n  readonly as: string;\n  readonly modelName: string;\n} {\n  if (result?._brand !== 'mongo-query-builder/lookup-result@1') {\n    throw new Error(\n      'lookup() callback must return the result of `from(name).on(cb).as(name)`. ' +\n        'Returning a hand-rolled options object is not supported.',\n    );\n  }\n  const model = domainModelsAtDefaultNamespace(contract.domain)[result._model] as\n    | MongoModelDefinition\n    | undefined;\n  const foreignCollection = model?.storage?.collection ?? result._root;\n  return {\n    foreignCollection,\n    localField: result._localField,\n    foreignField: result._foreignField,\n    as: result._as,\n    modelName: result._model,\n  };\n}\n","import type {\n  MongoAggExpr,\n  MongoFieldShape,\n  MongoPipelineStage,\n  MongoResultShape,\n} from '@prisma-next/mongo-query-ast/execution';\nimport {\n  freezeMongoResultShape,\n  MongoAddFieldsStage,\n  MongoAggFieldRef,\n  MongoProjectStage,\n} from '@prisma-next/mongo-query-ast/execution';\n\nconst identityStageKinds = new Set(['match', 'sort', 'limit', 'skip', 'sample', 'vectorSearch']);\n\nconst unknownShape: MongoFieldShape = { kind: 'unknown' as const };\n\nfunction fieldShapeAtPath(shape: MongoResultShape, path: string): MongoFieldShape {\n  if (shape.kind !== 'document' || path.includes('.')) {\n    return unknownShape;\n  }\n  return shape.fields[path] ?? unknownShape;\n}\n\nfunction shapeForExpr(currentShape: MongoResultShape, expr: MongoAggExpr): MongoFieldShape {\n  if (expr instanceof MongoAggFieldRef) {\n    return fieldShapeAtPath(currentShape, expr.path);\n  }\n  return unknownShape;\n}\n\nfunction resultShapeAfterProject(\n  currentShape: MongoResultShape,\n  stage: MongoProjectStage,\n): MongoResultShape {\n  if (currentShape.kind !== 'document') {\n    return { kind: 'unknown' as const };\n  }\n  const fields: Record<string, MongoFieldShape> = {};\n  for (const [key, value] of Object.entries(stage.projection)) {\n    if (value === 0) {\n      continue;\n    }\n    if (value === 1) {\n      fields[key] = currentShape.fields[key] ?? unknownShape;\n      continue;\n    }\n    fields[key] = shapeForExpr(currentShape, value);\n  }\n  if (!Object.hasOwn(stage.projection, '_id') && currentShape.fields['_id']) {\n    fields['_id'] = currentShape.fields['_id'];\n  }\n  return freezeMongoResultShape({ kind: 'document' as const, fields });\n}\n\nfunction resultShapeAfterAddFields(\n  currentShape: MongoResultShape,\n  stage: MongoAddFieldsStage,\n): MongoResultShape {\n  if (currentShape.kind !== 'document') {\n    return { kind: 'unknown' as const };\n  }\n  const fields: Record<string, MongoFieldShape> = { ...currentShape.fields };\n  for (const [key, expr] of Object.entries(stage.fields)) {\n    fields[key] = shapeForExpr(currentShape, expr);\n  }\n  return freezeMongoResultShape({ kind: 'document' as const, fields });\n}\n\nexport function computePipelineResultShape(\n  stages: ReadonlyArray<MongoPipelineStage>,\n  startShape: MongoResultShape,\n): MongoResultShape {\n  let shape = startShape;\n  for (const stage of stages) {\n    if (shape.kind === 'unknown') {\n      return { kind: 'unknown' as const };\n    }\n    if (identityStageKinds.has(stage.kind)) {\n      continue;\n    }\n    if (stage instanceof MongoProjectStage) {\n      shape = resultShapeAfterProject(shape, stage);\n      continue;\n    }\n    if (stage instanceof MongoAddFieldsStage) {\n      shape = resultShapeAfterAddFields(shape, stage);\n      continue;\n    }\n    return { kind: 'unknown' as const };\n  }\n  return shape;\n}\n","import type { ContractField } from '@prisma-next/contract/types';\nimport type { MongoModelDefinition } from '@prisma-next/mongo-contract';\nimport type { MongoFieldShape, MongoResultShape } from '@prisma-next/mongo-query-ast/execution';\nimport {\n  freezeMongoFieldShape,\n  freezeMongoResultShape,\n} from '@prisma-next/mongo-query-ast/execution';\n\nexport function contractFieldToMongoFieldShape(field: ContractField): MongoFieldShape {\n  const { type, nullable, many } = field;\n  if (type.kind === 'valueObject' || type.kind === 'union') {\n    return Object.freeze({ kind: 'unknown' as const });\n  }\n  if (type.kind !== 'scalar') {\n    return Object.freeze({ kind: 'unknown' as const });\n  }\n  if (field.dict === true) {\n    return Object.freeze({ kind: 'unknown' as const });\n  }\n  if (many === true) {\n    return freezeMongoFieldShape({\n      kind: 'array',\n      nullable,\n      element: { kind: 'leaf', codecId: type.codecId, nullable: false },\n    });\n  }\n  return freezeMongoFieldShape({\n    kind: 'leaf',\n    codecId: type.codecId,\n    nullable,\n  });\n}\n\nexport function contractModelToMongoResultShape(\n  model: MongoModelDefinition,\n  options?: {\n    readonly selection?: readonly string[];\n    readonly includeRelationNames?: readonly string[];\n  },\n): MongoResultShape {\n  const fields: Record<string, MongoFieldShape> = {};\n  for (const rel of options?.includeRelationNames ?? []) {\n    fields[rel] = Object.freeze({ kind: 'unknown' as const });\n  }\n  const modelFields = model.fields;\n  // An explicit empty selection is honored as-is (returns a document shape\n  // with no fields). Only the absence of a selection falls back to the model's\n  // full field set.\n  const keys = options?.selection !== undefined ? options.selection : Object.keys(modelFields);\n\n  for (const key of keys) {\n    if (Object.hasOwn(fields, key)) {\n      continue;\n    }\n    const cf = modelFields[key];\n    if (!cf) {\n      fields[key] = Object.freeze({ kind: 'unknown' as const });\n      continue;\n    }\n    fields[key] = contractFieldToMongoFieldShape(cf);\n  }\n  return freezeMongoResultShape({ kind: 'document', fields });\n}\n","import { domainModelsAtDefaultNamespace, type PlanMeta } from '@prisma-next/contract/types';\nimport type {\n  AnyMongoTypeMaps,\n  ExtractMongoCodecTypes,\n  MongoContract,\n  MongoContractWithTypeMaps,\n  MongoModelDefinition,\n} from '@prisma-next/mongo-contract';\nimport type {\n  MongoAggAccumulator,\n  MongoAggExpr,\n  MongoDensifyRange,\n  MongoFillOutput,\n  MongoFilterExpr,\n  MongoPipelineStage,\n  MongoProjectionValue,\n  MongoQueryPlan,\n  MongoResultShape,\n  MongoUpdatePipelineStage,\n  MongoWindowField,\n  UpdateResult,\n} from '@prisma-next/mongo-query-ast/execution';\nimport {\n  AggregateCommand,\n  FindOneAndDeleteCommand,\n  FindOneAndUpdateCommand,\n  MongoAddFieldsStage,\n  MongoAndExpr,\n  MongoBucketAutoStage,\n  MongoBucketStage,\n  MongoCountStage,\n  MongoDensifyStage,\n  MongoFacetStage,\n  MongoFillStage,\n  MongoGeoNearStage,\n  MongoGraphLookupStage,\n  MongoGroupStage,\n  MongoLimitStage,\n  MongoLookupStage,\n  MongoMatchStage,\n  MongoMergeStage,\n  MongoOutStage,\n  MongoProjectStage,\n  MongoRedactStage,\n  MongoReplaceRootStage,\n  MongoSampleStage,\n  MongoSearchMetaStage,\n  MongoSearchStage,\n  MongoSetWindowFieldsStage,\n  MongoSkipStage,\n  MongoSortByCountStage,\n  MongoSortStage,\n  MongoUnionWithStage,\n  MongoUnwindStage,\n  MongoVectorSearchStage,\n  UpdateManyCommand,\n  UpdateOneCommand,\n} from '@prisma-next/mongo-query-ast/execution';\nimport { castAs } from '@prisma-next/utils/casts';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport { createFieldAccessor, type Expression, type FieldAccessor } from './field-accessor';\nimport {\n  createLookupFrom,\n  extractLookupResult,\n  type LookupFrom,\n  type LookupResult,\n} from './lookup-builder';\nimport type { FindAndModifyEnabled, LeadingMatch, UpdateEnabled } from './markers';\nimport { computePipelineResultShape } from './pipeline-result-shape';\nimport type { ModelArrayField, NestedDocShape } from './resolve-path';\nimport { contractModelToMongoResultShape } from './result-shape';\nimport type {\n  DocField,\n  DocShape,\n  ExtractDocShape,\n  GroupedDocShape,\n  GroupSpec,\n  ProjectedShape,\n  ResolveRow,\n  SortSpec,\n  TypedAggExpr,\n  UnwoundShape,\n} from './types';\nimport { resolveUpdaterResult, type UpdaterResult } from './update-ops';\n\ninterface PipelineChainState {\n  readonly collection: string;\n  readonly stages: ReadonlyArray<MongoPipelineStage>;\n  readonly storageHash: string;\n  readonly modelName?: string;\n}\n\n/**\n * The pipeline state in the query-builder state machine.\n *\n * Reached from `CollectionHandle` or `FilteredCollection` after the first\n * pipeline-stage method call (or directly via `aggregate()` shortcuts). Holds\n * the accumulated `MongoPipelineStage[]` and exposes pipeline-stage methods,\n * the `merge`/`out` write terminals, and the `build`/`aggregate` read\n * terminals.\n *\n * Two phantom type parameters gate the conditional terminals:\n *\n *  - `U extends UpdateEnabled` — when `'update-ok'`, the no-arg `updateMany()` /\n *    `updateOne()` form is available (consume the chain as an\n *    update-with-pipeline spec). Cleared by stages that produce content the\n *    `update` AST cannot represent (e.g. `$group`, `$lookup`, `$limit`).\n *  - `F extends FindAndModifyEnabled` — when `'fam-ok'`, the\n *    `findOneAndUpdate(...)` / `findOneAndDelete(...)` terminals are\n *    available. Cleared by stages incompatible with their wire-command slots\n *    (`$limit`, `$group`, mutating stages, …).\n *\n * The marker semantics are encoded in the per-method return types — see the\n * marker table (and rationale per row) in\n * `docs/architecture docs/adrs/ADR 201 - State-machine pattern for typed DSL builders.md`.\n */\nexport class PipelineChain<\n  TContract extends MongoContractWithTypeMaps<MongoContract, AnyMongoTypeMaps>,\n  Shape extends DocShape,\n  U extends UpdateEnabled = 'update-ok',\n  F extends FindAndModifyEnabled = 'fam-ok',\n  L extends LeadingMatch = 'leading',\n  N extends NestedDocShape = Record<string, never>,\n> {\n  declare readonly __updateCompat: U;\n  declare readonly __findAndModifyCompat: F;\n  declare readonly __leadingMatch: L;\n\n  readonly #contract: TContract;\n  readonly #state: PipelineChainState;\n\n  constructor(contract: TContract, state: PipelineChainState) {\n    this.#contract = contract;\n    this.#state = state;\n  }\n\n  /**\n   * Internal helper that appends a pipeline stage and branches into a new\n   * state-type. The fifth type parameter `NewN` carries the nested-path\n   * shape forward. It defaults to `Record<string, never>` so stages that\n   * fundamentally rewrite the document (`$group`, `$project`,\n   * `$replaceRoot`, …) automatically disable the callable form of\n   * `FieldAccessor` downstream. Additive stages (`match`, `addFields`,\n   * `sort`, `lookup`, …) explicitly re-thread the current `N`.\n   */\n  #withStage<\n    NewShape extends DocShape,\n    NewU extends UpdateEnabled,\n    NewF extends FindAndModifyEnabled,\n    NewL extends LeadingMatch = 'past-leading',\n    NewN extends NestedDocShape = Record<string, never>,\n  >(stage: MongoPipelineStage): PipelineChain<TContract, NewShape, NewU, NewF, NewL, NewN> {\n    return new PipelineChain<TContract, NewShape, NewU, NewF, NewL, NewN>(this.#contract, {\n      ...this.#state,\n      stages: [...this.#state.stages, stage],\n    });\n  }\n\n  #writeMeta(): PlanMeta {\n    return {\n      target: 'mongo',\n      storageHash: this.#state.storageHash,\n      lane: 'mongo-query',\n    };\n  }\n\n  // --- Identity stages ---\n\n  /**\n   * `$match`. `FindAndModifyEnabled` is always preserved. `UpdateEnabled` is\n   * preserved only while the chain is still in the leading-`$match` prefix\n   * (`L = 'leading'`); a `$match` that follows any non-`$match` stage\n   * transitions to `L = 'past-leading'` and clears `UpdateEnabled`, since\n   * `deconstructUpdateChain` can only peel leading `$match` stages into the\n   * wire-command filter.\n   */\n  match(\n    filter: MongoFilterExpr,\n  ): PipelineChain<TContract, Shape, L extends 'leading' ? U : 'update-cleared', F, L, N>;\n  match(\n    fn: (fields: FieldAccessor<Shape, N>) => MongoFilterExpr,\n  ): PipelineChain<TContract, Shape, L extends 'leading' ? U : 'update-cleared', F, L, N>;\n  match(\n    filterOrFn: MongoFilterExpr | ((fields: FieldAccessor<Shape, N>) => MongoFilterExpr),\n  ): PipelineChain<TContract, Shape, L extends 'leading' ? U : 'update-cleared', F, L, N> {\n    const filter =\n      typeof filterOrFn === 'function' ? filterOrFn(createFieldAccessor<Shape, N>()) : filterOrFn;\n    return this.#withStage<Shape, L extends 'leading' ? U : 'update-cleared', F, L, N>(\n      new MongoMatchStage(filter),\n    );\n  }\n\n  /**\n   * `$sort`. Clears `UpdateEnabled` (`update` has no per-document sort) but\n   * preserves `FindAndModifyEnabled` (`findAndModify` has a `sort` slot).\n   */\n  sort(\n    spec: SortSpec<Shape>,\n  ): PipelineChain<TContract, Shape, 'update-cleared', F, 'past-leading', N> {\n    return this.#withStage<Shape, 'update-cleared', F, 'past-leading', N>(\n      new MongoSortStage(spec as Record<string, 1 | -1>),\n    );\n  }\n\n  /**\n   * `$limit`. Clears both markers — `limit` is incompatible with the `update`\n   * wire command, and `findAndModify` already implies single-document\n   * semantics (so `.limit(...)` adds no meaning, only ambiguity).\n   */\n  limit(\n    n: number,\n  ): PipelineChain<TContract, Shape, 'update-cleared', 'fam-cleared', 'past-leading', N> {\n    return this.#withStage<Shape, 'update-cleared', 'fam-cleared', 'past-leading', N>(\n      new MongoLimitStage(n),\n    );\n  }\n\n  /**\n   * `$skip`. Clears both markers — MongoDB's `findAndModify` wire command\n   * has no `skip` slot, so `deconstructFindAndModifyChain` rejects any\n   * `$skip` at runtime; keeping the marker `fam-cleared` makes the type\n   * system reflect the same constraint (see ADR 201 marker table).\n   */\n  skip(\n    n: number,\n  ): PipelineChain<TContract, Shape, 'update-cleared', 'fam-cleared', 'past-leading', N> {\n    return this.#withStage<Shape, 'update-cleared', 'fam-cleared', 'past-leading', N>(\n      new MongoSkipStage(n),\n    );\n  }\n\n  sample(\n    n: number,\n  ): PipelineChain<TContract, Shape, 'update-cleared', 'fam-cleared', 'past-leading', N> {\n    return this.#withStage<Shape, 'update-cleared', 'fam-cleared', 'past-leading', N>(\n      new MongoSampleStage(n),\n    );\n  }\n\n  // --- Additive stages ---\n\n  /**\n   * `$addFields`. Preserves `UpdateEnabled` (representable as\n   * update-with-pipeline `$set`); clears `FindAndModifyEnabled` (no analogue\n   * in the find-and-modify wire commands). The nested-path shape `N` is\n   * preserved — newly added flat fields are reachable via property access\n   * (`f.newField`) but do not themselves carry nested structure.\n   */\n  addFields<NewFields extends Record<string, TypedAggExpr<DocField>>>(\n    fn: (fields: FieldAccessor<Shape, N>) => NewFields,\n  ): PipelineChain<\n    TContract,\n    Shape & ExtractDocShape<NewFields>,\n    U,\n    'fam-cleared',\n    'past-leading',\n    N\n  > {\n    const accessor = createFieldAccessor<Shape, N>();\n    const newFields = fn(accessor);\n    const exprRecord: Record<string, MongoAggExpr> = {};\n    for (const [key, typed] of Object.entries(newFields)) {\n      exprRecord[key] = typed.node;\n    }\n    return this.#withStage<Shape & ExtractDocShape<NewFields>, U, 'fam-cleared', 'past-leading', N>(\n      new MongoAddFieldsStage(exprRecord),\n    );\n  }\n\n  /**\n   * `$lookup`. Clears both markers — joins are not representable in either\n   * the `update` or `findAndModify` wire commands. The original document's\n   * nested-path shape `N` is preserved (the lookup adds a sidecar array\n   * field; existing keys are untouched).\n   *\n   * The single callback receives a `from` callable that grounds the\n   * foreign-root literal sequentially before the inner `on(...)`\n   * callback is type-checked — see `lookup-builder.ts`. The resulting\n   * `Shape` gains the `As` key as a `ModelArrayField<ModelName>` so\n   * `ResolveRow` produces `Array<ForeignRow>` (with concrete leaf\n   * types) instead of the legacy `unknown[]`.\n   */\n  lookup<RootName extends string, ModelName extends string, As extends string>(\n    fn: (from: LookupFrom<TContract, Shape, N>) => LookupResult<RootName, ModelName, As>,\n  ): PipelineChain<\n    TContract,\n    Shape & Record<As, ModelArrayField<ModelName>>,\n    'update-cleared',\n    'fam-cleared',\n    'past-leading',\n    N\n  > {\n    const fromCallable = createLookupFrom<TContract, Shape, N>(this.#contract);\n    const result = fn(fromCallable);\n    const extracted = extractLookupResult(result, this.#contract);\n    return this.#withStage<\n      Shape & Record<As, ModelArrayField<ModelName>>,\n      'update-cleared',\n      'fam-cleared',\n      'past-leading',\n      N\n    >(\n      new MongoLookupStage({\n        from: extracted.foreignCollection,\n        localField: extracted.localField,\n        foreignField: extracted.foreignField,\n        as: extracted.as,\n      }),\n    );\n  }\n\n  // --- Narrowing stages ---\n\n  /**\n   * `$project`. Preserves `UpdateEnabled` (representable as update-with-pipeline\n   * `$project` / `$unset`); clears `FindAndModifyEnabled` (use `.project()` on\n   * the result of `.build()` if both projection and find-and-modify are\n   * needed — see spec).\n   *\n   * Resets the nested-path shape to `Record<string, never>` — projection\n   * fundamentally rewrites the document, so dot-paths into the *source*\n   * document are no longer meaningful downstream.\n   */\n  project<K extends keyof Shape & string>(\n    ...keys: K[]\n  ): PipelineChain<\n    TContract,\n    Pick<Shape, K | ('_id' extends keyof Shape ? '_id' : never)>,\n    U,\n    'fam-cleared',\n    'past-leading'\n  >;\n  project<Spec extends Record<string, 1 | TypedAggExpr<DocField>>>(\n    fn: (fields: FieldAccessor<Shape, N>) => Spec,\n  ): PipelineChain<TContract, ProjectedShape<Shape, Spec>, U, 'fam-cleared', 'past-leading'>;\n  project(\n    ...args: unknown[]\n  ): PipelineChain<TContract, DocShape, U, 'fam-cleared', 'past-leading'> {\n    if (args.length === 1 && typeof args[0] === 'function') {\n      const fn = args[0] as (\n        fields: FieldAccessor<Shape, N>,\n      ) => Record<string, 1 | TypedAggExpr<DocField>>;\n      const accessor = createFieldAccessor<Shape, N>();\n      const spec = fn(accessor);\n      const projection: Record<string, MongoProjectionValue> = {};\n      for (const [key, val] of Object.entries(spec)) {\n        projection[key] = val === 1 ? 1 : (val as TypedAggExpr<DocField>).node;\n      }\n      return this.#withStage(new MongoProjectStage(projection));\n    }\n    const keys = args as string[];\n    const projection: Record<string, 1> = {};\n    for (const key of keys) {\n      projection[key] = 1;\n    }\n    return this.#withStage(new MongoProjectStage(projection));\n  }\n\n  /**\n   * `$unwind`. Clears both markers — array unrolling produces multiple output\n   * documents per input, incompatible with both single-document update and\n   * find-and-modify wire commands. The original `N` is preserved: unwind\n   * replaces the unwound array slot with its element but leaves the rest\n   * of the document structurally intact.\n   */\n  unwind<K extends keyof Shape & string>(\n    field: K,\n    options?: { preserveNullAndEmptyArrays?: boolean },\n  ): PipelineChain<\n    TContract,\n    UnwoundShape<Shape, K>,\n    'update-cleared',\n    'fam-cleared',\n    'past-leading',\n    N\n  > {\n    return this.#withStage<\n      UnwoundShape<Shape, K>,\n      'update-cleared',\n      'fam-cleared',\n      'past-leading',\n      N\n    >(new MongoUnwindStage(`$${field}`, options?.preserveNullAndEmptyArrays ?? false));\n  }\n\n  // --- Replacement stages ---\n\n  /**\n   * `$group`. Clears both markers — group output bears no relation to source\n   * documents; neither `update` nor `findAndModify` can consume it. Nested\n   * path shape is reset (the source document's path tree is gone).\n   */\n  group<Spec extends GroupSpec>(\n    fn: (fields: FieldAccessor<Shape, N>) => Spec,\n  ): PipelineChain<\n    TContract,\n    GroupedDocShape<Spec>,\n    'update-cleared',\n    'fam-cleared',\n    'past-leading'\n  > {\n    const accessor = createFieldAccessor<Shape, N>();\n    const spec = fn(accessor);\n    const { _id: groupIdExpr, ...rest } = spec;\n    const groupId = groupIdExpr === null ? null : groupIdExpr.node;\n    const accumulators: Record<string, MongoAggAccumulator> = {};\n    for (const [key, typed] of Object.entries(rest)) {\n      if (typed === null) {\n        throw new Error(`group() field \"${key}\" must not be null. Only _id can be null.`);\n      }\n      if (typed.node.kind !== 'accumulator') {\n        throw new Error(\n          `group() field \"${key}\" must use an accumulator (e.g. acc.sum(), acc.count()). Got \"${typed.node.kind}\" expression.`,\n        );\n      }\n      accumulators[key] = typed.node as MongoAggAccumulator;\n    }\n    return this.#withStage<GroupedDocShape<Spec>, 'update-cleared', 'fam-cleared'>(\n      new MongoGroupStage(groupId, accumulators),\n    );\n  }\n\n  /**\n   * `$replaceRoot`. Preserves `UpdateEnabled` (representable as\n   * update-with-pipeline `$replaceRoot`); clears `FindAndModifyEnabled`.\n   * Nested path shape is reset — the replaced root has no relation to\n   * the original document structure.\n   */\n  replaceRoot<NewShape extends DocShape>(\n    fn: (fields: FieldAccessor<Shape, N>) => Expression<DocField> | TypedAggExpr<DocField>,\n  ): PipelineChain<TContract, NewShape, U, 'fam-cleared', 'past-leading'> {\n    const accessor = createFieldAccessor<Shape, N>();\n    const expr = fn(accessor);\n    return this.#withStage<NewShape, U, 'fam-cleared'>(new MongoReplaceRootStage(expr.node));\n  }\n\n  count<Field extends string>(\n    field: Field,\n  ): PipelineChain<\n    TContract,\n    Record<Field, { readonly codecId: 'mongo/double@1'; readonly nullable: false }>,\n    'update-cleared',\n    'fam-cleared',\n    'past-leading'\n  > {\n    return this.#withStage(new MongoCountStage(field));\n  }\n\n  sortByCount<F2 extends DocField>(\n    fn: (fields: FieldAccessor<Shape, N>) => Expression<F2> | TypedAggExpr<F2>,\n  ): PipelineChain<\n    TContract,\n    {\n      _id: F2;\n      count: { readonly codecId: 'mongo/double@1'; readonly nullable: false };\n    },\n    'update-cleared',\n    'fam-cleared',\n    'past-leading'\n  > {\n    const accessor = createFieldAccessor<Shape, N>();\n    const expr = fn(accessor);\n    return this.#withStage(new MongoSortByCountStage(expr.node));\n  }\n\n  // --- Filter stages ---\n\n  /**\n   * `$redact`. Preserves `UpdateEnabled`; clears `FindAndModifyEnabled`.\n   * Shape- and nested-path-preserving (the document tree is unchanged).\n   */\n  redact(\n    fn: (fields: FieldAccessor<Shape, N>) => Expression<DocField> | TypedAggExpr<DocField>,\n  ): PipelineChain<TContract, Shape, U, 'fam-cleared', 'past-leading', N> {\n    const accessor = createFieldAccessor<Shape, N>();\n    const expr = fn(accessor);\n    return this.#withStage<Shape, U, 'fam-cleared', 'past-leading', N>(\n      new MongoRedactStage(expr.node),\n    );\n  }\n\n  // --- Write terminals (output stages) ---\n\n  /**\n   * `$out` write terminal. Materialises the pipeline output into\n   * `collection` (optionally in `db`), replacing any prior contents. Unlike\n   * the other pipeline-stage methods, this **terminates** the chain — it\n   * returns a `MongoQueryPlan` rather than another `PipelineChain`, since\n   * `$out` must be the final stage and there is nothing further to chain.\n   *\n   * Lane is `mongo-query` (matching all other terminals in this package) so\n   * middleware can dispatch on intent without inspecting the command.\n   *\n   * The result row stream is empty (`unknown` row type) — the data lives\n   * in the destination collection, not the response.\n   */\n  out(collection: string, db?: string): MongoQueryPlan<unknown, AggregateCommand> {\n    return this.#writeTerminal(new MongoOutStage(collection, db));\n  }\n\n  /**\n   * `$merge` write terminal. Streams the pipeline output into the target\n   * collection per the supplied merge semantics (`whenMatched` /\n   * `whenNotMatched`). Like `out()`, terminates the chain — `$merge` must\n   * be the final stage.\n   */\n  merge(options: {\n    into: string | { db: string; coll: string };\n    on?: string | ReadonlyArray<string>;\n    whenMatched?: string | ReadonlyArray<MongoUpdatePipelineStage>;\n    whenNotMatched?: string;\n  }): MongoQueryPlan<unknown, AggregateCommand> {\n    return this.#writeTerminal(new MongoMergeStage(options));\n  }\n\n  #writeTerminal(stage: MongoPipelineStage): MongoQueryPlan<unknown, AggregateCommand> {\n    const pipeline = [...this.#state.stages, stage];\n    const command = new AggregateCommand(this.#state.collection, pipeline);\n    const meta: PlanMeta = {\n      target: 'mongo',\n      storageHash: this.#state.storageHash,\n      lane: 'mongo-query',\n    };\n    return { collection: this.#state.collection, command, meta };\n  }\n\n  // --- Union stages ---\n\n  unionWith(\n    collection: string,\n    pipeline?: ReadonlyArray<MongoPipelineStage>,\n  ): PipelineChain<TContract, Shape, 'update-cleared', 'fam-cleared', 'past-leading', N> {\n    return this.#withStage<Shape, 'update-cleared', 'fam-cleared', 'past-leading', N>(\n      new MongoUnionWithStage(collection, pipeline),\n    );\n  }\n\n  // --- Bucketing stages ---\n\n  bucket(options: {\n    groupBy: MongoAggExpr;\n    boundaries: ReadonlyArray<unknown>;\n    default_?: unknown;\n    output?: Record<string, MongoAggAccumulator>;\n  }): PipelineChain<TContract, DocShape, 'update-cleared', 'fam-cleared', 'past-leading'> {\n    return this.#withStage<DocShape, 'update-cleared', 'fam-cleared'>(\n      new MongoBucketStage(options),\n    );\n  }\n\n  bucketAuto(options: {\n    groupBy: MongoAggExpr;\n    buckets: number;\n    output?: Record<string, MongoAggAccumulator>;\n    granularity?: string;\n  }): PipelineChain<TContract, DocShape, 'update-cleared', 'fam-cleared', 'past-leading'> {\n    return this.#withStage<DocShape, 'update-cleared', 'fam-cleared'>(\n      new MongoBucketAutoStage(options),\n    );\n  }\n\n  // --- Geo stages ---\n\n  geoNear(options: {\n    near: unknown;\n    distanceField: string;\n    spherical?: boolean;\n    maxDistance?: number;\n    minDistance?: number;\n    query?: MongoFilterExpr;\n    key?: string;\n    distanceMultiplier?: number;\n    includeLocs?: string;\n  }): PipelineChain<TContract, DocShape, 'update-cleared', 'fam-cleared', 'past-leading'> {\n    return this.#withStage<DocShape, 'update-cleared', 'fam-cleared'>(\n      new MongoGeoNearStage(options),\n    );\n  }\n\n  // --- Multi-facet stages ---\n\n  facet(\n    facets: Record<string, ReadonlyArray<MongoPipelineStage>>,\n  ): PipelineChain<TContract, DocShape, 'update-cleared', 'fam-cleared', 'past-leading'> {\n    return this.#withStage<DocShape, 'update-cleared', 'fam-cleared'>(new MongoFacetStage(facets));\n  }\n\n  // --- Graph stages ---\n\n  graphLookup(options: {\n    from: string;\n    startWith: MongoAggExpr;\n    connectFromField: string;\n    connectToField: string;\n    as: string;\n    maxDepth?: number;\n    depthField?: string;\n    restrictSearchWithMatch?: MongoFilterExpr;\n  }): PipelineChain<TContract, DocShape, 'update-cleared', 'fam-cleared', 'past-leading'> {\n    return this.#withStage<DocShape, 'update-cleared', 'fam-cleared'>(\n      new MongoGraphLookupStage(options),\n    );\n  }\n\n  // --- Window stages ---\n\n  setWindowFields(options: {\n    partitionBy?: MongoAggExpr;\n    sortBy?: Record<string, 1 | -1>;\n    output: Record<string, MongoWindowField>;\n  }): PipelineChain<TContract, DocShape, 'update-cleared', 'fam-cleared', 'past-leading'> {\n    return this.#withStage<DocShape, 'update-cleared', 'fam-cleared'>(\n      new MongoSetWindowFieldsStage(options),\n    );\n  }\n\n  densify(options: {\n    field: string;\n    partitionByFields?: ReadonlyArray<string>;\n    range: MongoDensifyRange;\n  }): PipelineChain<TContract, Shape, 'update-cleared', 'fam-cleared', 'past-leading', N> {\n    return this.#withStage<Shape, 'update-cleared', 'fam-cleared', 'past-leading', N>(\n      new MongoDensifyStage(options),\n    );\n  }\n\n  fill(options: {\n    partitionBy?: MongoAggExpr;\n    partitionByFields?: ReadonlyArray<string>;\n    sortBy?: Record<string, 1 | -1>;\n    output: Record<string, MongoFillOutput>;\n  }): PipelineChain<TContract, Shape, 'update-cleared', 'fam-cleared', 'past-leading', N> {\n    return this.#withStage<Shape, 'update-cleared', 'fam-cleared', 'past-leading', N>(\n      new MongoFillStage(options),\n    );\n  }\n\n  // --- Search stages ---\n\n  search(\n    config: Record<string, unknown>,\n    index?: string,\n  ): PipelineChain<TContract, Shape, 'update-cleared', 'fam-cleared', 'past-leading', N> {\n    return this.#withStage<Shape, 'update-cleared', 'fam-cleared', 'past-leading', N>(\n      new MongoSearchStage(config, index),\n    );\n  }\n\n  searchMeta(\n    config: Record<string, unknown>,\n    index?: string,\n  ): PipelineChain<TContract, DocShape, 'update-cleared', 'fam-cleared', 'past-leading'> {\n    return this.#withStage<DocShape, 'update-cleared', 'fam-cleared'>(\n      new MongoSearchMetaStage(config, index),\n    );\n  }\n\n  vectorSearch(options: {\n    index: string;\n    path: string;\n    queryVector: ReadonlyArray<number>;\n    numCandidates: number;\n    limit: number;\n    filter?: Record<string, unknown>;\n  }): PipelineChain<TContract, Shape, 'update-cleared', 'fam-cleared', 'past-leading', N> {\n    return this.#withStage<Shape, 'update-cleared', 'fam-cleared', 'past-leading', N>(\n      new MongoVectorSearchStage(options),\n    );\n  }\n\n  // --- Escape hatch ---\n\n  pipe(\n    stage: MongoPipelineStage,\n  ): PipelineChain<TContract, Shape, 'update-cleared', 'fam-cleared', 'past-leading'>;\n  pipe<NewShape extends DocShape>(\n    stage: MongoPipelineStage,\n  ): PipelineChain<TContract, NewShape, 'update-cleared', 'fam-cleared', 'past-leading'>;\n  pipe<NewShape extends DocShape = Shape>(\n    stage: MongoPipelineStage,\n  ): PipelineChain<TContract, NewShape, 'update-cleared', 'fam-cleared', 'past-leading'> {\n    return this.#withStage<NewShape, 'update-cleared', 'fam-cleared'>(stage);\n  }\n\n  // --- Pipeline-style write terminals (UpdateEnabled-gated) ---\n\n  /**\n   * No-arg `updateMany()`: deconstruct the chain into leading `$match`\n   * stages (folded into the filter) and remaining stages (which must all\n   * be valid pipeline-update stages). Available only when `U = 'update-ok'`.\n   *\n   * The optional callback parameter exists for subclass-override\n   * compatibility with `FilteredCollection.updateMany(updaterFn)` — TS's\n   * strict override check requires the parent's parameter to accept at\n   * least what the child's signature does. A runtime guard throws if a\n   * callback is actually passed on a bare `PipelineChain`. Note that\n   * because nothing in the public surface transitions `U` from\n   * `'update-cleared'` (the initial state on `CollectionHandle` /\n   * `FilteredCollection`) back to `'update-ok'`, the no-arg form is\n   * reachable only via explicit type casts in internal tests — the\n   * callback-form \"type hole\" is therefore not reachable from user\n   * code. See `docs/architecture docs/adrs/ADR 201 - State-machine\n   * pattern for typed DSL builders.md` for the marker-transition table.\n   */\n  updateMany(\n    this: PipelineChain<TContract, Shape, 'update-ok', F, L, N>,\n    updaterFn?: (fields: FieldAccessor<Shape, N>) => UpdaterResult,\n  ): MongoQueryPlan<UpdateResult, UpdateManyCommand> {\n    if (updaterFn !== undefined) {\n      throw new Error(\n        'updateMany() on a PipelineChain expects no arguments — the chain itself is the update pipeline. ' +\n          'To update with an operator callback, call .updateMany(fn) on a FilteredCollection (i.e. after .match()).',\n      );\n    }\n    const { filter, updatePipeline } = deconstructUpdateChain(this.#state.stages);\n    const command = new UpdateManyCommand(this.#state.collection, filter, updatePipeline);\n    return { collection: this.#state.collection, command, meta: this.#writeMeta() };\n  }\n\n  /**\n   * No-arg `updateOne()`: same as `updateMany()` but maps to a single-doc\n   * update. Carries the same optional-callback/subclass-compat caveat\n   * documented above — the callback form is reachable only via forced\n   * casts in internal tests.\n   */\n  updateOne(\n    this: PipelineChain<TContract, Shape, 'update-ok', F, L, N>,\n    updaterFn?: (fields: FieldAccessor<Shape, N>) => UpdaterResult,\n  ): MongoQueryPlan<UpdateResult, UpdateOneCommand> {\n    if (updaterFn !== undefined) {\n      throw new Error(\n        'updateOne() on a PipelineChain expects no arguments — the chain itself is the update pipeline. ' +\n          'To update with an operator callback, call .updateOne(fn) on a FilteredCollection (i.e. after .match()).',\n      );\n    }\n    const { filter, updatePipeline } = deconstructUpdateChain(this.#state.stages);\n    const command = new UpdateOneCommand(this.#state.collection, filter, updatePipeline);\n    return { collection: this.#state.collection, command, meta: this.#writeMeta() };\n  }\n\n  // --- Find-and-modify terminals (marker-gated) ---\n\n  /**\n   * Find a single document matching the accumulated pipeline (which must\n   * consist solely of leading `$match` stages followed by at most one\n   * `$sort`) and apply `updaterFn`. Available only when\n   * `FindAndModifyEnabled` is `'fam-ok'` — stages that clear the marker\n   * (including `$skip`, which MongoDB's `findAndModify` has no slot for)\n   * make this method invisible at the type level.\n   *\n   * The pipeline stages are deconstructed into the wire command's `filter`\n   * and `sort` slots. If any non-deconstructable stage is present, a\n   * runtime error is thrown as a defensive check (the type system should\n   * prevent this).\n   */\n  findOneAndUpdate(\n    this: PipelineChain<TContract, Shape, U, 'fam-ok', L, N>,\n    updaterFn: (fields: FieldAccessor<Shape, N>) => UpdaterResult,\n    opts: { readonly upsert?: boolean; readonly returnDocument?: 'before' | 'after' } = {},\n  ): MongoQueryPlan<\n    ResolveRow<Shape, ExtractMongoCodecTypes<TContract>, TContract> | null,\n    FindOneAndUpdateCommand\n  > {\n    const { filter, sort } = deconstructFindAndModifyChain(this.#state.stages);\n    const accessor = createFieldAccessor<Shape, N>();\n    const items = updaterFn(accessor);\n    const update = resolveUpdaterResult(items);\n    const command = new FindOneAndUpdateCommand(\n      this.#state.collection,\n      filter,\n      update,\n      opts.upsert ?? false,\n      sort,\n      opts.returnDocument ?? 'after',\n    );\n    const meta: PlanMeta = {\n      target: 'mongo',\n      storageHash: this.#state.storageHash,\n      lane: 'mongo-query',\n    };\n    return { collection: this.#state.collection, command, meta };\n  }\n\n  /**\n   * Find a single document matching the accumulated pipeline and delete it.\n   * Same marker gating and deconstruction as `findOneAndUpdate`.\n   */\n  findOneAndDelete(\n    this: PipelineChain<TContract, Shape, U, 'fam-ok', L, N>,\n  ): MongoQueryPlan<\n    ResolveRow<Shape, ExtractMongoCodecTypes<TContract>, TContract> | null,\n    FindOneAndDeleteCommand\n  > {\n    const { filter, sort } = deconstructFindAndModifyChain(this.#state.stages);\n    const command = new FindOneAndDeleteCommand(this.#state.collection, filter, sort);\n    const meta: PlanMeta = {\n      target: 'mongo',\n      storageHash: this.#state.storageHash,\n      lane: 'mongo-query',\n    };\n    return { collection: this.#state.collection, command, meta };\n  }\n\n  // --- Read terminals ---\n\n  /**\n   * Materialise the chain as a `MongoQueryPlan` wrapping an `AggregateCommand`.\n   */\n  build(): MongoQueryPlan<\n    ResolveRow<Shape, ExtractMongoCodecTypes<TContract>, TContract>,\n    AggregateCommand\n  > {\n    const command = new AggregateCommand(this.#state.collection, this.#state.stages);\n    const meta: PlanMeta = {\n      target: 'mongo',\n      storageHash: this.#state.storageHash,\n      lane: 'mongo-query',\n    };\n    const modelName = this.#state.modelName;\n    const contractNarrow = this.#contract as MongoContract;\n    let resultShape: MongoResultShape | undefined;\n    if (modelName !== undefined) {\n      const model = castAs<MongoModelDefinition | undefined>(\n        domainModelsAtDefaultNamespace(contractNarrow.domain)[modelName],\n      );\n      resultShape = model\n        ? computePipelineResultShape(this.#state.stages, contractModelToMongoResultShape(model))\n        : { kind: 'unknown' as const };\n    }\n    return {\n      collection: this.#state.collection,\n      command,\n      meta,\n      ...ifDefined('resultShape', resultShape),\n    };\n  }\n\n  /**\n   * Alias for `build()` — surfaces the read intent at the call site.\n   */\n  aggregate(): MongoQueryPlan<\n    ResolveRow<Shape, ExtractMongoCodecTypes<TContract>, TContract>,\n    AggregateCommand\n  > {\n    return this.build();\n  }\n}\n\ninterface DeconstructedFindAndModify {\n  filter: MongoFilterExpr;\n  sort: Record<string, 1 | -1> | undefined;\n}\n\n/**\n * Walk the accumulated pipeline stages and extract the `filter` and `sort`\n * slots for a `findOneAndUpdate` / `findOneAndDelete` wire command.\n *\n * The helper accepts exactly the canonical shape `match+ -> sort?` and\n * nothing else:\n *\n *  - one or more `$match` stages (AND-folded into a single filter),\n *  - optionally followed by a single `$sort` stage.\n *\n * Anything else — a `$sort` before `$match`, multiple `$sort` stages, a\n * `$skip` stage, or any non-`$match`/`$sort` stage — is rejected with a\n * clear error. The type system already prevents most of these at compile\n * time via the `FindAndModifyEnabled` marker, but the runtime check\n * guards the escape hatches (e.g. `.pipe(...)`) and future marker gaps.\n *\n * `$skip` is rejected outright because MongoDB's `findAndModify` command\n * has no skip slot; a silently-dropped skip is a latent correctness bug\n * waiting to happen. (A02 removed skip from the typed AST for the same\n * reason.)\n */\nfunction deconstructFindAndModifyChain(\n  stages: ReadonlyArray<MongoPipelineStage>,\n): DeconstructedFindAndModify {\n  const matchFilters: MongoFilterExpr[] = [];\n  let sort: Record<string, 1 | -1> | undefined;\n  let seenNonMatch = false;\n\n  for (const stage of stages) {\n    if (stage instanceof MongoMatchStage) {\n      if (seenNonMatch) {\n        throw new Error(\n          'findOneAndUpdate/findOneAndDelete requires the canonical $match+ -> $sort? shape, ' +\n            'but a $match stage was found after a $sort. Re-order the chain so every .match() ' +\n            'call precedes the .sort() call.',\n        );\n      }\n      matchFilters.push(stage.filter);\n    } else if (stage instanceof MongoSortStage) {\n      if (sort !== undefined) {\n        throw new Error(\n          'findOneAndUpdate/findOneAndDelete accepts at most one $sort stage; drop the extra ' +\n            '.sort() call or combine the keys into a single sort spec.',\n        );\n      }\n      sort = { ...stage.sort };\n      seenNonMatch = true;\n    } else if (stage instanceof MongoSkipStage) {\n      throw new Error(\n        'findOneAndUpdate/findOneAndDelete does not support .skip() — MongoDB findAndModify ' +\n          'has no skip slot. Remove the .skip() call, or use .aggregate()/.build() if the ' +\n          'chain needs skip semantics.',\n      );\n    } else {\n      throw new Error(\n        'findOneAndUpdate/findOneAndDelete requires the canonical $match+ -> $sort? shape, ' +\n          `but encountered a '${stage.constructor.name}' stage. ` +\n          'This is likely a bug — the type system should have prevented this chain.',\n      );\n    }\n  }\n\n  if (matchFilters.length === 0) {\n    throw new Error('findOneAndUpdate/findOneAndDelete requires at least one .match() call.');\n  }\n  const first = matchFilters[0];\n  if (first === undefined) {\n    throw new Error('Unreachable: matchFilters.length > 0 but first is undefined');\n  }\n  const filter: MongoFilterExpr = matchFilters.length === 1 ? first : MongoAndExpr.of(matchFilters);\n\n  return { filter, sort };\n}\n\ninterface DeconstructedUpdate {\n  filter: MongoFilterExpr;\n  updatePipeline: ReadonlyArray<MongoUpdatePipelineStage>;\n}\n\n/**\n * Walk the accumulated pipeline stages: leading `$match` stages become the\n * filter, remaining stages must all be valid `MongoUpdatePipelineStage`\n * members (currently `$addFields`, `$project`, `$replaceRoot`).\n */\nfunction deconstructUpdateChain(stages: ReadonlyArray<MongoPipelineStage>): DeconstructedUpdate {\n  const matchFilters: MongoFilterExpr[] = [];\n  let boundary = 0;\n\n  for (const stage of stages) {\n    if (!(stage instanceof MongoMatchStage)) break;\n    matchFilters.push(stage.filter);\n    boundary++;\n  }\n\n  if (matchFilters.length === 0) {\n    throw new Error('No-arg updateMany/updateOne requires at least one .match() call.');\n  }\n\n  const remaining = stages.slice(boundary);\n  if (remaining.length === 0) {\n    throw new Error(\n      'No-arg updateMany/updateOne requires at least one pipeline-update stage ' +\n        '(e.g. .addFields(), .project(), .replaceRoot()) after the .match() stages.',\n    );\n  }\n\n  const updatePipeline: MongoUpdatePipelineStage[] = [];\n  for (const stage of remaining) {\n    if (\n      stage instanceof MongoAddFieldsStage ||\n      stage instanceof MongoProjectStage ||\n      stage instanceof MongoReplaceRootStage\n    ) {\n      updatePipeline.push(stage);\n    } else {\n      throw new Error(\n        `No-arg updateMany/updateOne: encountered non-update stage '${stage.constructor.name}' ` +\n          'after the leading $match stages. Only $addFields/$set, $project/$unset, ' +\n          'and $replaceRoot/$replaceWith stages are valid in an update pipeline.',\n      );\n    }\n  }\n\n  const first = matchFilters[0];\n  if (first === undefined) {\n    throw new Error('Unreachable: matchFilters.length > 0 but first is undefined');\n  }\n  const filter: MongoFilterExpr = matchFilters.length === 1 ? first : MongoAndExpr.of(matchFilters);\n\n  return { filter, updatePipeline };\n}\n","import type { MongoAggExpr } from '@prisma-next/mongo-query-ast/execution';\nimport {\n  MongoAggCond,\n  MongoAggLiteral,\n  MongoAggOperator,\n} from '@prisma-next/mongo-query-ast/execution';\nimport type {\n  ArrayField,\n  BooleanField,\n  DateField,\n  DocField,\n  LiteralValue,\n  NullableDocField,\n  NumericField,\n  StringField,\n  TypedAggExpr,\n} from './types';\n\n// ---------------------------------------------------------------------------\n// Internal factory helpers\n// ---------------------------------------------------------------------------\n\nfunction numericExpr(op: string, args: TypedAggExpr<DocField>[]): TypedAggExpr<NumericField> {\n  return {\n    _field: { codecId: 'mongo/double@1', nullable: false } as NumericField,\n    node: MongoAggOperator.of(\n      op,\n      args.map((a) => a.node),\n    ),\n  };\n}\n\nfunction numericUnaryExpr(op: string, arg: TypedAggExpr<DocField>): TypedAggExpr<NumericField> {\n  return {\n    _field: { codecId: 'mongo/double@1', nullable: false } as NumericField,\n    node: MongoAggOperator.of(op, arg.node),\n  };\n}\n\nfunction stringExpr(op: string, args: TypedAggExpr<DocField>[]): TypedAggExpr<StringField> {\n  return {\n    _field: { codecId: 'mongo/string@1', nullable: false } as StringField,\n    node: MongoAggOperator.of(\n      op,\n      args.map((a) => a.node),\n    ),\n  };\n}\n\nfunction stringUnaryExpr(op: string, arg: TypedAggExpr<DocField>): TypedAggExpr<StringField> {\n  return {\n    _field: { codecId: 'mongo/string@1', nullable: false } as StringField,\n    node: MongoAggOperator.of(op, arg.node),\n  };\n}\n\nfunction booleanExpr(op: string, args: TypedAggExpr<DocField>[]): TypedAggExpr<BooleanField> {\n  return {\n    _field: { codecId: 'mongo/bool@1', nullable: false } as BooleanField,\n    node: MongoAggOperator.of(\n      op,\n      args.map((a) => a.node),\n    ),\n  };\n}\n\nfunction booleanUnaryExpr(op: string, arg: TypedAggExpr<DocField>): TypedAggExpr<BooleanField> {\n  return {\n    _field: { codecId: 'mongo/bool@1', nullable: false } as BooleanField,\n    node: MongoAggOperator.of(op, arg.node),\n  };\n}\n\nfunction dateUnaryExpr(op: string, arg: TypedAggExpr<DocField>): TypedAggExpr<DateField> {\n  return {\n    _field: { codecId: 'mongo/date@1', nullable: false } as DateField,\n    node: MongoAggOperator.of(op, arg.node),\n  };\n}\n\nfunction arrayExpr(op: string, args: TypedAggExpr<DocField>[]): TypedAggExpr<ArrayField> {\n  return {\n    _field: { codecId: 'mongo/array@1', nullable: false } as ArrayField,\n    node: MongoAggOperator.of(\n      op,\n      args.map((a) => a.node),\n    ),\n  };\n}\n\nfunction arrayUnaryExpr(op: string, arg: TypedAggExpr<DocField>): TypedAggExpr<ArrayField> {\n  return {\n    _field: { codecId: 'mongo/array@1', nullable: false } as ArrayField,\n    node: MongoAggOperator.of(op, arg.node),\n  };\n}\n\nfunction docUnaryExpr(op: string, arg: TypedAggExpr<DocField>): TypedAggExpr<DocField> {\n  return {\n    _field: { codecId: arg._field.codecId, nullable: false },\n    node: MongoAggOperator.of(op, arg.node),\n  };\n}\n\nfunction namedArgsExpr<F extends DocField>(\n  op: string,\n  args: Readonly<Record<string, TypedAggExpr<DocField> | undefined>>,\n  _field: F,\n): TypedAggExpr<F> {\n  const nodeArgs: Record<string, MongoAggExpr> = {};\n  for (const [key, val] of Object.entries(args)) {\n    if (val !== undefined) {\n      nodeArgs[key] = val.node;\n    }\n  }\n  return { _field, node: MongoAggOperator.of(op, nodeArgs) };\n}\n\nconst NUMERIC: NumericField = { codecId: 'mongo/double@1', nullable: false } as NumericField;\nconst STRING: StringField = { codecId: 'mongo/string@1', nullable: false } as StringField;\nconst BOOLEAN: BooleanField = { codecId: 'mongo/bool@1', nullable: false } as BooleanField;\nconst DATE: DateField = { codecId: 'mongo/date@1', nullable: false } as DateField;\nconst ARRAY: ArrayField = { codecId: 'mongo/array@1', nullable: false } as ArrayField;\nconst DOC: DocField = { codecId: 'mongo/document@1', nullable: false };\n\nfunction literal(value: string): TypedAggExpr<StringField>;\nfunction literal(value: number): TypedAggExpr<NumericField>;\nfunction literal(value: boolean): TypedAggExpr<BooleanField>;\nfunction literal(value: Date): TypedAggExpr<DateField>;\nfunction literal<F extends DocField>(value: LiteralValue<F>): TypedAggExpr<F>;\nfunction literal(value: unknown): TypedAggExpr<DocField> {\n  return { _field: undefined as never, node: MongoAggLiteral.of(value) };\n}\n\n// ---------------------------------------------------------------------------\n// Public helpers\n// ---------------------------------------------------------------------------\n\nexport const fn = {\n  // -- Arithmetic (existing) ------------------------------------------------\n\n  add(...args: TypedAggExpr<DocField>[]): TypedAggExpr<NumericField> {\n    return numericExpr('$add', args);\n  },\n\n  subtract(a: TypedAggExpr<DocField>, b: TypedAggExpr<DocField>): TypedAggExpr<NumericField> {\n    return numericExpr('$subtract', [a, b]);\n  },\n\n  multiply(...args: TypedAggExpr<DocField>[]): TypedAggExpr<NumericField> {\n    return numericExpr('$multiply', args);\n  },\n\n  divide(a: TypedAggExpr<DocField>, b: TypedAggExpr<DocField>): TypedAggExpr<NumericField> {\n    return numericExpr('$divide', [a, b]);\n  },\n\n  // -- String (existing) ----------------------------------------------------\n\n  concat(...args: TypedAggExpr<DocField>[]): TypedAggExpr<StringField> {\n    return stringExpr('$concat', args);\n  },\n\n  toLower(a: TypedAggExpr<DocField>): TypedAggExpr<StringField> {\n    return stringUnaryExpr('$toLower', a);\n  },\n\n  toUpper(a: TypedAggExpr<DocField>): TypedAggExpr<StringField> {\n    return stringUnaryExpr('$toUpper', a);\n  },\n\n  // -- Size (existing) ------------------------------------------------------\n\n  size(a: TypedAggExpr<DocField>): TypedAggExpr<NumericField> {\n    return numericUnaryExpr('$size', a);\n  },\n\n  // -- Control flow (existing) ----------------------------------------------\n\n  cond<F extends DocField>(\n    condition: MongoAggExpr,\n    thenExpr: TypedAggExpr<F>,\n    elseExpr: TypedAggExpr<DocField>,\n  ): TypedAggExpr<F> {\n    return {\n      _field: thenExpr._field,\n      node: new MongoAggCond(condition, thenExpr.node, elseExpr.node),\n    };\n  },\n\n  literal,\n\n  // -- Date helpers ---------------------------------------------------------\n\n  year(a: TypedAggExpr<DocField>): TypedAggExpr<NumericField> {\n    return numericUnaryExpr('$year', a);\n  },\n  month(a: TypedAggExpr<DocField>): TypedAggExpr<NumericField> {\n    return numericUnaryExpr('$month', a);\n  },\n  dayOfMonth(a: TypedAggExpr<DocField>): TypedAggExpr<NumericField> {\n    return numericUnaryExpr('$dayOfMonth', a);\n  },\n  hour(a: TypedAggExpr<DocField>): TypedAggExpr<NumericField> {\n    return numericUnaryExpr('$hour', a);\n  },\n  minute(a: TypedAggExpr<DocField>): TypedAggExpr<NumericField> {\n    return numericUnaryExpr('$minute', a);\n  },\n  second(a: TypedAggExpr<DocField>): TypedAggExpr<NumericField> {\n    return numericUnaryExpr('$second', a);\n  },\n  millisecond(a: TypedAggExpr<DocField>): TypedAggExpr<NumericField> {\n    return numericUnaryExpr('$millisecond', a);\n  },\n  dateToString(args: {\n    date: TypedAggExpr<DateField>;\n    format?: TypedAggExpr<StringField>;\n    timezone?: TypedAggExpr<StringField>;\n    onNull?: TypedAggExpr<DocField>;\n  }): TypedAggExpr<StringField> {\n    return namedArgsExpr('$dateToString', args, STRING);\n  },\n  dateFromString(args: {\n    dateString: TypedAggExpr<StringField>;\n    format?: TypedAggExpr<StringField>;\n    timezone?: TypedAggExpr<StringField>;\n    onError?: TypedAggExpr<DocField>;\n    onNull?: TypedAggExpr<DocField>;\n  }): TypedAggExpr<DateField> {\n    return namedArgsExpr('$dateFromString', args, DATE);\n  },\n  dateDiff(args: {\n    startDate: TypedAggExpr<DateField>;\n    endDate: TypedAggExpr<DateField>;\n    unit: TypedAggExpr<StringField>;\n    timezone?: TypedAggExpr<StringField>;\n    startOfWeek?: TypedAggExpr<StringField>;\n  }): TypedAggExpr<NumericField> {\n    return namedArgsExpr('$dateDiff', args, NUMERIC);\n  },\n  dateAdd(args: {\n    startDate: TypedAggExpr<DateField>;\n    unit: TypedAggExpr<StringField>;\n    amount: TypedAggExpr<NumericField>;\n    timezone?: TypedAggExpr<StringField>;\n  }): TypedAggExpr<DateField> {\n    return namedArgsExpr('$dateAdd', args, DATE);\n  },\n  dateSubtract(args: {\n    startDate: TypedAggExpr<DateField>;\n    unit: TypedAggExpr<StringField>;\n    amount: TypedAggExpr<NumericField>;\n    timezone?: TypedAggExpr<StringField>;\n  }): TypedAggExpr<DateField> {\n    return namedArgsExpr('$dateSubtract', args, DATE);\n  },\n  dateTrunc(args: {\n    date: TypedAggExpr<DateField>;\n    unit: TypedAggExpr<StringField>;\n    binSize?: TypedAggExpr<NumericField>;\n    timezone?: TypedAggExpr<StringField>;\n    startOfWeek?: TypedAggExpr<StringField>;\n  }): TypedAggExpr<DateField> {\n    return namedArgsExpr('$dateTrunc', args, DATE);\n  },\n\n  // -- String helpers -------------------------------------------------------\n\n  substr(\n    str: TypedAggExpr<DocField>,\n    start: TypedAggExpr<DocField>,\n    length: TypedAggExpr<DocField>,\n  ): TypedAggExpr<StringField> {\n    return stringExpr('$substr', [str, start, length]);\n  },\n  substrBytes(\n    str: TypedAggExpr<DocField>,\n    start: TypedAggExpr<DocField>,\n    count: TypedAggExpr<DocField>,\n  ): TypedAggExpr<StringField> {\n    return stringExpr('$substrBytes', [str, start, count]);\n  },\n  trim(args: {\n    input: TypedAggExpr<StringField>;\n    chars?: TypedAggExpr<StringField>;\n  }): TypedAggExpr<StringField> {\n    return namedArgsExpr('$trim', args, STRING);\n  },\n  ltrim(args: {\n    input: TypedAggExpr<StringField>;\n    chars?: TypedAggExpr<StringField>;\n  }): TypedAggExpr<StringField> {\n    return namedArgsExpr('$ltrim', args, STRING);\n  },\n  rtrim(args: {\n    input: TypedAggExpr<StringField>;\n    chars?: TypedAggExpr<StringField>;\n  }): TypedAggExpr<StringField> {\n    return namedArgsExpr('$rtrim', args, STRING);\n  },\n  split(str: TypedAggExpr<DocField>, delimiter: TypedAggExpr<DocField>): TypedAggExpr<ArrayField> {\n    return arrayExpr('$split', [str, delimiter]);\n  },\n  strLenCP(a: TypedAggExpr<DocField>): TypedAggExpr<NumericField> {\n    return numericUnaryExpr('$strLenCP', a);\n  },\n  strLenBytes(a: TypedAggExpr<DocField>): TypedAggExpr<NumericField> {\n    return numericUnaryExpr('$strLenBytes', a);\n  },\n  regexMatch(args: {\n    input: TypedAggExpr<StringField>;\n    regex: TypedAggExpr<StringField>;\n    options?: TypedAggExpr<StringField>;\n  }): TypedAggExpr<BooleanField> {\n    return namedArgsExpr('$regexMatch', args, BOOLEAN);\n  },\n  regexFind(args: {\n    input: TypedAggExpr<StringField>;\n    regex: TypedAggExpr<StringField>;\n    options?: TypedAggExpr<StringField>;\n  }): TypedAggExpr<DocField> {\n    return namedArgsExpr('$regexFind', args, DOC);\n  },\n  regexFindAll(args: {\n    input: TypedAggExpr<StringField>;\n    regex: TypedAggExpr<StringField>;\n    options?: TypedAggExpr<StringField>;\n  }): TypedAggExpr<ArrayField> {\n    return namedArgsExpr('$regexFindAll', args, ARRAY);\n  },\n  replaceOne(args: {\n    input: TypedAggExpr<StringField>;\n    find: TypedAggExpr<StringField>;\n    replacement: TypedAggExpr<StringField>;\n  }): TypedAggExpr<StringField> {\n    return namedArgsExpr('$replaceOne', args, STRING);\n  },\n  replaceAll(args: {\n    input: TypedAggExpr<StringField>;\n    find: TypedAggExpr<StringField>;\n    replacement: TypedAggExpr<StringField>;\n  }): TypedAggExpr<StringField> {\n    return namedArgsExpr('$replaceAll', args, STRING);\n  },\n\n  // -- Comparison helpers ---------------------------------------------------\n\n  cmp(a: TypedAggExpr<DocField>, b: TypedAggExpr<DocField>): TypedAggExpr<NumericField> {\n    return numericExpr('$cmp', [a, b]);\n  },\n  eq(a: TypedAggExpr<DocField>, b: TypedAggExpr<DocField>): TypedAggExpr<BooleanField> {\n    return booleanExpr('$eq', [a, b]);\n  },\n  ne(a: TypedAggExpr<DocField>, b: TypedAggExpr<DocField>): TypedAggExpr<BooleanField> {\n    return booleanExpr('$ne', [a, b]);\n  },\n  gt(a: TypedAggExpr<DocField>, b: TypedAggExpr<DocField>): TypedAggExpr<BooleanField> {\n    return booleanExpr('$gt', [a, b]);\n  },\n  gte(a: TypedAggExpr<DocField>, b: TypedAggExpr<DocField>): TypedAggExpr<BooleanField> {\n    return booleanExpr('$gte', [a, b]);\n  },\n  lt(a: TypedAggExpr<DocField>, b: TypedAggExpr<DocField>): TypedAggExpr<BooleanField> {\n    return booleanExpr('$lt', [a, b]);\n  },\n  lte(a: TypedAggExpr<DocField>, b: TypedAggExpr<DocField>): TypedAggExpr<BooleanField> {\n    return booleanExpr('$lte', [a, b]);\n  },\n\n  // -- Array helpers --------------------------------------------------------\n\n  arrayElemAt(\n    arr: TypedAggExpr<DocField>,\n    idx: TypedAggExpr<DocField>,\n  ): TypedAggExpr<NullableDocField> {\n    return {\n      _field: { codecId: DOC.codecId, nullable: true },\n      node: MongoAggOperator.of('$arrayElemAt', [arr.node, idx.node]),\n    };\n  },\n  concatArrays(...args: TypedAggExpr<DocField>[]): TypedAggExpr<ArrayField> {\n    return arrayExpr('$concatArrays', args);\n  },\n  firstElem(a: TypedAggExpr<DocField>): TypedAggExpr<NullableDocField> {\n    return {\n      _field: { codecId: DOC.codecId, nullable: true },\n      node: MongoAggOperator.of('$first', a.node),\n    };\n  },\n  lastElem(a: TypedAggExpr<DocField>): TypedAggExpr<NullableDocField> {\n    return {\n      _field: { codecId: DOC.codecId, nullable: true },\n      node: MongoAggOperator.of('$last', a.node),\n    };\n  },\n  isIn(elem: TypedAggExpr<DocField>, arr: TypedAggExpr<DocField>): TypedAggExpr<BooleanField> {\n    return booleanExpr('$in', [elem, arr]);\n  },\n  indexOfArray(\n    arr: TypedAggExpr<DocField>,\n    value: TypedAggExpr<DocField>,\n    ...rest: TypedAggExpr<DocField>[]\n  ): TypedAggExpr<NumericField> {\n    return numericExpr('$indexOfArray', [arr, value, ...rest]);\n  },\n  isArray(a: TypedAggExpr<DocField>): TypedAggExpr<BooleanField> {\n    return booleanUnaryExpr('$isArray', a);\n  },\n  reverseArray(a: TypedAggExpr<DocField>): TypedAggExpr<ArrayField> {\n    return arrayUnaryExpr('$reverseArray', a);\n  },\n  slice(arr: TypedAggExpr<DocField>, ...rest: TypedAggExpr<DocField>[]): TypedAggExpr<ArrayField> {\n    return arrayExpr('$slice', [arr, ...rest]);\n  },\n  zip(args: {\n    inputs: TypedAggExpr<ArrayField>[];\n    useLongestLength?: TypedAggExpr<BooleanField>;\n    defaults?: TypedAggExpr<ArrayField>;\n  }): TypedAggExpr<ArrayField> {\n    const nodeArgs: Record<string, MongoAggExpr | ReadonlyArray<MongoAggExpr>> = {\n      inputs: args.inputs.map((a) => a.node),\n    };\n    if (args.useLongestLength) nodeArgs['useLongestLength'] = args.useLongestLength.node;\n    if (args.defaults) nodeArgs['defaults'] = args.defaults.node;\n    return { _field: ARRAY, node: MongoAggOperator.of('$zip', nodeArgs) };\n  },\n  range(\n    start: TypedAggExpr<DocField>,\n    end: TypedAggExpr<DocField>,\n    step: TypedAggExpr<DocField>,\n  ): TypedAggExpr<ArrayField> {\n    return arrayExpr('$range', [start, end, step]);\n  },\n\n  // -- Set helpers ----------------------------------------------------------\n\n  setUnion(...args: TypedAggExpr<DocField>[]): TypedAggExpr<ArrayField> {\n    return arrayExpr('$setUnion', args);\n  },\n  setIntersection(...args: TypedAggExpr<DocField>[]): TypedAggExpr<ArrayField> {\n    return arrayExpr('$setIntersection', args);\n  },\n  setDifference(a: TypedAggExpr<DocField>, b: TypedAggExpr<DocField>): TypedAggExpr<ArrayField> {\n    return arrayExpr('$setDifference', [a, b]);\n  },\n  setEquals(...args: TypedAggExpr<DocField>[]): TypedAggExpr<BooleanField> {\n    return booleanExpr('$setEquals', args);\n  },\n  setIsSubset(a: TypedAggExpr<DocField>, b: TypedAggExpr<DocField>): TypedAggExpr<BooleanField> {\n    return booleanExpr('$setIsSubset', [a, b]);\n  },\n  anyElementTrue(a: TypedAggExpr<DocField>): TypedAggExpr<BooleanField> {\n    return booleanUnaryExpr('$anyElementTrue', a);\n  },\n  allElementsTrue(a: TypedAggExpr<DocField>): TypedAggExpr<BooleanField> {\n    return booleanUnaryExpr('$allElementsTrue', a);\n  },\n\n  // -- Type helpers ---------------------------------------------------------\n\n  typeOf(a: TypedAggExpr<DocField>): TypedAggExpr<StringField> {\n    return stringUnaryExpr('$type', a);\n  },\n  convert(args: {\n    input: TypedAggExpr<DocField>;\n    to: TypedAggExpr<StringField | NumericField>;\n    onError?: TypedAggExpr<DocField>;\n    onNull?: TypedAggExpr<DocField>;\n  }): TypedAggExpr<DocField> {\n    return namedArgsExpr('$convert', args, DOC);\n  },\n  toInt(a: TypedAggExpr<DocField>): TypedAggExpr<NumericField> {\n    return numericUnaryExpr('$toInt', a);\n  },\n  toLong(a: TypedAggExpr<DocField>): TypedAggExpr<NumericField> {\n    return numericUnaryExpr('$toLong', a);\n  },\n  toDouble(a: TypedAggExpr<DocField>): TypedAggExpr<NumericField> {\n    return numericUnaryExpr('$toDouble', a);\n  },\n  toDecimal(a: TypedAggExpr<DocField>): TypedAggExpr<NumericField> {\n    return numericUnaryExpr('$toDecimal', a);\n  },\n  toString_(a: TypedAggExpr<DocField>): TypedAggExpr<StringField> {\n    return stringUnaryExpr('$toString', a);\n  },\n  toObjectId(a: TypedAggExpr<DocField>): TypedAggExpr<DocField> {\n    return docUnaryExpr('$toObjectId', a);\n  },\n  toBool(a: TypedAggExpr<DocField>): TypedAggExpr<BooleanField> {\n    return booleanUnaryExpr('$toBool', a);\n  },\n  toDate(a: TypedAggExpr<DocField>): TypedAggExpr<DateField> {\n    return dateUnaryExpr('$toDate', a);\n  },\n\n  // -- Object helpers -------------------------------------------------------\n\n  objectToArray(a: TypedAggExpr<DocField>): TypedAggExpr<ArrayField> {\n    return arrayUnaryExpr('$objectToArray', a);\n  },\n  arrayToObject(a: TypedAggExpr<DocField>): TypedAggExpr<DocField> {\n    return { _field: DOC, node: MongoAggOperator.of('$arrayToObject', a.node) };\n  },\n  getField(args: {\n    field: TypedAggExpr<StringField>;\n    input?: TypedAggExpr<DocField>;\n  }): TypedAggExpr<DocField> {\n    return namedArgsExpr('$getField', args, DOC);\n  },\n  setField(args: {\n    field: TypedAggExpr<StringField>;\n    input: TypedAggExpr<DocField>;\n    value: TypedAggExpr<DocField>;\n  }): TypedAggExpr<DocField> {\n    return namedArgsExpr('$setField', args, DOC);\n  },\n};\n","import { domainModelsAtDefaultNamespace, type PlanMeta } from '@prisma-next/contract/types';\nimport type {\n  AnyMongoTypeMaps,\n  ExtractMongoCodecTypes,\n  MongoContract,\n  MongoContractWithTypeMaps,\n  MongoModelDefinition,\n  MongoModelsMap,\n  RootModelName,\n} from '@prisma-next/mongo-contract';\nimport type {\n  DeleteResult,\n  InsertManyResult,\n  InsertOneResult,\n  MongoFilterExpr,\n  MongoQueryPlan,\n  MongoUpdateSpec,\n  UpdateResult,\n} from '@prisma-next/mongo-query-ast/execution';\nimport {\n  DeleteManyCommand,\n  DeleteOneCommand,\n  FindOneAndDeleteCommand,\n  FindOneAndUpdateCommand,\n  InsertManyCommand,\n  InsertOneCommand,\n  MongoAndExpr,\n  MongoExistsExpr,\n  MongoMatchStage,\n  UpdateManyCommand,\n  UpdateOneCommand,\n} from '@prisma-next/mongo-query-ast/execution';\nimport type { MongoValue } from '@prisma-next/mongo-value';\nimport { PipelineChain } from './builder';\nimport { createFieldAccessor, type FieldAccessor } from './field-accessor';\nimport type { ModelNestedShape, NestedDocShape } from './resolve-path';\nimport type { ModelToDocShape, ResolveRow } from './types';\nimport { resolveUpdaterResult, type UpdaterResult } from './update-ops';\n\n/**\n * \"Match-all\" filter used by the unqualified-write terminals\n * (`updateAll`/`deleteAll`). The canonical representation is still\n * undecided — `MongoAndExpr` with an empty conjunction and a dedicated\n * `MongoMatchAllExpr` node are both candidates. For now we use\n * `_id $exists: true`, which is trivially true on every document and\n * avoids introducing a new AST node before the wider question is\n * resolved. Centralised so the eventual switch is a one-line change.\n */\nfunction matchAllFilter(): MongoFilterExpr {\n  return MongoExistsExpr.exists('_id');\n}\n\n/**\n * Resolve an updater callback into a `MongoUpdateSpec` (either the folded\n * operator object or a pipeline-stage array). Centralised so all write\n * terminals share the same fold / dispatch semantics.\n */\nfunction resolveUpdaterCallback<\n  Shape extends ModelToDocShape<MongoContract, string>,\n  Nested extends NestedDocShape,\n>(updaterFn: (fields: FieldAccessor<Shape, Nested>) => UpdaterResult): MongoUpdateSpec {\n  const accessor = createFieldAccessor<Shape, Nested>();\n  const items = updaterFn(accessor);\n  return resolveUpdaterResult(items);\n}\n\n/**\n * Build the `PlanMeta` envelope shared by every write terminal in this\n * package. Lane is `mongo-query` (single lane for all query-builder terminals)\n * so middleware can dispatch on intent without inspecting the command.\n */\nfunction writeMeta(storageHash: string): PlanMeta {\n  return {\n    target: 'mongo',\n    storageHash,\n    lane: 'mongo-query',\n  };\n}\n\n/**\n * Root state of the query-builder state machine. Returned from\n * `mongoQuery(...).from(name)` and bound to a single collection.\n *\n * Inherits the entire pipeline-stage surface from `PipelineChain` (since an\n * empty `CollectionHandle` is observably an empty pipeline). Adds:\n *\n *  - `match(...)` — overridden to transition to `FilteredCollection`, which\n *    accumulates filters for eventual splatting into write/find-and-modify\n *    wire commands.\n *  - **Insert / unqualified-write methods** (M2): `insertOne`, `insertMany`,\n *    `updateAll`, `deleteAll`. These live *only* here — the corresponding\n *    methods are absent from `FilteredCollection`, so a caller cannot\n *    accidentally produce an unqualified write by forgetting to `.match(...)`\n *    later in the chain. Bodies land in M2.\n */\nexport class CollectionHandle<\n  TContract extends MongoContractWithTypeMaps<MongoContract, AnyMongoTypeMaps>,\n  ModelName extends keyof MongoModelsMap<TContract> & string,\n> extends PipelineChain<\n  TContract,\n  ModelToDocShape<TContract, ModelName>,\n  'update-cleared',\n  'fam-cleared',\n  'leading',\n  ModelNestedShape<TContract, ModelName>\n> {\n  readonly #ctx: BindingContext<TContract>;\n  readonly #modelName: ModelName;\n\n  constructor(ctx: BindingContext<TContract>, modelName: ModelName) {\n    super(ctx.contract, {\n      collection: ctx.collection,\n      stages: [],\n      storageHash: ctx.storageHash,\n      modelName: modelName as string,\n    });\n    this.#ctx = ctx;\n    this.#modelName = modelName;\n  }\n\n  /**\n   * Bound model name. Exposed so type tests can assert the binding without\n   * flipping into a pipeline. Not part of the public-API contract.\n   */\n  get _modelName(): ModelName {\n    return this.#modelName;\n  }\n\n  /**\n   * Begin accumulating a filter. Transitions to `FilteredCollection`.\n   *\n   * Overrides `PipelineChain.match` (which appends another `$match` stage\n   * and stays in the chain). The two implementations are semantically\n   * equivalent for the read terminal — multiple `$match` stages AND-fold in\n   * Mongo — but `FilteredCollection` makes the accumulated filter\n   * addressable for the write/find-and-modify terminals landing in M2/M3.\n   */\n  override match(filter: MongoFilterExpr): FilteredCollection<TContract, ModelName>;\n  override match(\n    fn: (\n      fields: FieldAccessor<\n        ModelToDocShape<TContract, ModelName>,\n        ModelNestedShape<TContract, ModelName>\n      >,\n    ) => MongoFilterExpr,\n  ): FilteredCollection<TContract, ModelName>;\n  override match(\n    filterOrFn:\n      | MongoFilterExpr\n      | ((\n          fields: FieldAccessor<\n            ModelToDocShape<TContract, ModelName>,\n            ModelNestedShape<TContract, ModelName>\n          >,\n        ) => MongoFilterExpr),\n  ): FilteredCollection<TContract, ModelName> {\n    const resolved =\n      typeof filterOrFn === 'function'\n        ? filterOrFn(\n            createFieldAccessor<\n              ModelToDocShape<TContract, ModelName>,\n              ModelNestedShape<TContract, ModelName>\n            >(),\n          )\n        : filterOrFn;\n    return new FilteredCollection<TContract, ModelName>(this.#ctx, this.#modelName, [resolved]);\n  }\n\n  // --- Inserts ---\n\n  /**\n   * Insert a single document. Document fields are passed straight through to\n   * the wire `InsertOneCommand` — codec normalisation happens at the\n   * adapter/driver boundary, identically to the SQL builder (see Open Item\n   * #14 confirmation in the design conversation).\n   *\n   * Returns a `MongoQueryPlan<InsertOneResult>` whose row stream yields a\n   * single result document with the server-assigned `insertedId`.\n   */\n  insertOne(\n    document: Record<string, MongoValue>,\n  ): MongoQueryPlan<InsertOneResult, InsertOneCommand> {\n    const command = new InsertOneCommand(this.#ctx.collection, document);\n    return {\n      collection: this.#ctx.collection,\n      command,\n      meta: writeMeta(this.#ctx.storageHash),\n    };\n  }\n\n  /**\n   * Insert a batch of documents. Order is preserved in the returned\n   * `insertedIds` array.\n   */\n  insertMany(\n    documents: ReadonlyArray<Record<string, MongoValue>>,\n  ): MongoQueryPlan<InsertManyResult, InsertManyCommand> {\n    if (documents.length === 0) {\n      throw new Error('insertMany() requires at least one document.');\n    }\n    const command = new InsertManyCommand(this.#ctx.collection, documents);\n    return {\n      collection: this.#ctx.collection,\n      command,\n      meta: writeMeta(this.#ctx.storageHash),\n    };\n  }\n\n  // --- Unqualified writes ---\n\n  /**\n   * Update *every* document in the collection. Lives only on\n   * `CollectionHandle` — the corresponding method is intentionally absent\n   * from `FilteredCollection` so a caller cannot accidentally produce an\n   * unqualified write by forgetting to `.match(...)` first. Pair with\n   * `.match(...).updateMany(...)` for the filtered case.\n   */\n  updateAll(\n    updaterFn: (\n      fields: FieldAccessor<\n        ModelToDocShape<TContract, ModelName>,\n        ModelNestedShape<TContract, ModelName>\n      >,\n    ) => UpdaterResult,\n  ): MongoQueryPlan<UpdateResult, UpdateManyCommand> {\n    const update = resolveUpdaterCallback<\n      ModelToDocShape<TContract, ModelName>,\n      ModelNestedShape<TContract, ModelName>\n    >(updaterFn);\n    const command = new UpdateManyCommand(this.#ctx.collection, matchAllFilter(), update);\n    return {\n      collection: this.#ctx.collection,\n      command,\n      meta: writeMeta(this.#ctx.storageHash),\n    };\n  }\n\n  /**\n   * Delete *every* document in the collection. See `updateAll` for the\n   * rationale around the unqualified-write surface being limited to this\n   * state class.\n   */\n  deleteAll(): MongoQueryPlan<DeleteResult, DeleteManyCommand> {\n    const command = new DeleteManyCommand(this.#ctx.collection, matchAllFilter());\n    return {\n      collection: this.#ctx.collection,\n      command,\n      meta: writeMeta(this.#ctx.storageHash),\n    };\n  }\n\n  // --- Upserts ---\n\n  /**\n   * Insert-or-update the document matching `filterFn`. The filter is\n   * mandatory (vs. `updateAll`'s tautological match) because an upsert\n   * without a discriminating predicate would either match every existing\n   * document or insert an indistinguishable new one.\n   *\n   * Maps to `UpdateOneCommand` with `upsert: true`. The driver inserts a\n   * new document derived from the filter equality fields plus the update\n   * spec when no match is found; otherwise updates the matched document.\n   */\n  upsertOne(\n    filterFn: (\n      fields: FieldAccessor<\n        ModelToDocShape<TContract, ModelName>,\n        ModelNestedShape<TContract, ModelName>\n      >,\n    ) => MongoFilterExpr,\n    updaterFn: (\n      fields: FieldAccessor<\n        ModelToDocShape<TContract, ModelName>,\n        ModelNestedShape<TContract, ModelName>\n      >,\n    ) => UpdaterResult,\n  ): MongoQueryPlan<UpdateResult, UpdateOneCommand> {\n    const accessor = createFieldAccessor<\n      ModelToDocShape<TContract, ModelName>,\n      ModelNestedShape<TContract, ModelName>\n    >();\n    const filter = filterFn(accessor);\n    const update = resolveUpdaterCallback<\n      ModelToDocShape<TContract, ModelName>,\n      ModelNestedShape<TContract, ModelName>\n    >(updaterFn);\n    const command = new UpdateOneCommand(this.#ctx.collection, filter, update, true);\n    return {\n      collection: this.#ctx.collection,\n      command,\n      meta: writeMeta(this.#ctx.storageHash),\n    };\n  }\n}\n\n/**\n * State reached after one or more `.match(...)` calls on `CollectionHandle`.\n *\n * Inherits the pipeline-stage surface from `PipelineChain`, with the\n * accumulated filters baked in as a leading `$match` stage on the underlying\n * pipeline state. This means read-terminal output (`.aggregate()` /\n * `.build()`) and any subsequent pipeline-stage chain see the filtered\n * collection as input — the read story works through pure inheritance.\n *\n * Adds:\n *\n *  - `match(...)` — pushes another `$match` stage *and* records the filter in\n *    the accumulator, so the eventual write/find-and-modify terminal can\n *    splat the AND-folded filter into the wire command's `filter` slot.\n *  - **Filtered writes** (M2): `updateMany`, `updateOne`, `deleteMany`,\n *    `deleteOne`, `upsertOne`. Stubbed in M1. (Upsert-many is an open\n *    question in the spec — see TML-2267 — and is intentionally absent.)\n *  - **Find-and-modify** (M3): `findOneAndUpdate`, `findOneAndDelete`.\n *    Stubbed in M1.\n *\n * Notably *does not* expose `insertOne`/`insertMany`/`updateAll`/`deleteAll`\n * — those are insert or unqualified-write operations that are nonsense\n * after a filter has been applied.\n */\nexport class FilteredCollection<\n  TContract extends MongoContractWithTypeMaps<MongoContract, AnyMongoTypeMaps>,\n  ModelName extends keyof MongoModelsMap<TContract> & string,\n> extends PipelineChain<\n  TContract,\n  ModelToDocShape<TContract, ModelName>,\n  'update-cleared',\n  'fam-cleared',\n  'leading',\n  ModelNestedShape<TContract, ModelName>\n> {\n  readonly #ctx: BindingContext<TContract>;\n  readonly #modelName: ModelName;\n  readonly #filters: ReadonlyArray<MongoFilterExpr>;\n\n  constructor(\n    ctx: BindingContext<TContract>,\n    modelName: ModelName,\n    filters: ReadonlyArray<MongoFilterExpr>,\n  ) {\n    if (filters.length === 0) {\n      throw new Error('FilteredCollection requires at least one accumulated filter');\n    }\n    const first = filters[0];\n    if (first === undefined) {\n      throw new Error('FilteredCollection: unreachable empty-filters branch');\n    }\n    const leading = filters.length === 1 ? first : foldAnd(filters);\n    super(ctx.contract, {\n      collection: ctx.collection,\n      stages: [new MongoMatchStage(leading)],\n      storageHash: ctx.storageHash,\n      modelName: modelName as string,\n    });\n    this.#ctx = ctx;\n    this.#modelName = modelName;\n    this.#filters = filters;\n  }\n\n  get _modelName(): ModelName {\n    return this.#modelName;\n  }\n\n  /**\n   * Accumulated filter list. Exposed for the M2/M3 write/find-and-modify\n   * terminals to splat into wire-command `filter` slots; not part of the\n   * public-API contract.\n   */\n  get _filters(): ReadonlyArray<MongoFilterExpr> {\n    return this.#filters;\n  }\n\n  /**\n   * Append another filter to the accumulator. Returns a new\n   * `FilteredCollection` whose underlying pipeline rebuilds the leading\n   * `$match` from the AND-folded accumulator (rather than appending a\n   * second `$match` stage), so the write/find-and-modify terminals see a\n   * single authoritative filter expression.\n   */\n  override match(filter: MongoFilterExpr): FilteredCollection<TContract, ModelName>;\n  override match(\n    fn: (\n      fields: FieldAccessor<\n        ModelToDocShape<TContract, ModelName>,\n        ModelNestedShape<TContract, ModelName>\n      >,\n    ) => MongoFilterExpr,\n  ): FilteredCollection<TContract, ModelName>;\n  override match(\n    filterOrFn:\n      | MongoFilterExpr\n      | ((\n          fields: FieldAccessor<\n            ModelToDocShape<TContract, ModelName>,\n            ModelNestedShape<TContract, ModelName>\n          >,\n        ) => MongoFilterExpr),\n  ): FilteredCollection<TContract, ModelName> {\n    const resolved =\n      typeof filterOrFn === 'function'\n        ? filterOrFn(\n            createFieldAccessor<\n              ModelToDocShape<TContract, ModelName>,\n              ModelNestedShape<TContract, ModelName>\n            >(),\n          )\n        : filterOrFn;\n    return new FilteredCollection<TContract, ModelName>(this.#ctx, this.#modelName, [\n      ...this.#filters,\n      resolved,\n    ]);\n  }\n\n  // --- Filtered writes ---\n\n  /**\n   * AND-fold the accumulated filters into a single `MongoFilterExpr` for\n   * splatting into a write/find-and-modify wire command's `filter` slot.\n   * Length-1 short-circuits to avoid a redundant `$and` wrapper.\n   */\n  #foldedFilter(): MongoFilterExpr {\n    const first = this.#filters[0];\n    if (first === undefined) {\n      throw new Error('FilteredCollection: invariant violated — empty filter accumulator');\n    }\n    return this.#filters.length === 1 ? first : foldAnd(this.#filters);\n  }\n\n  /**\n   * Update every matching document. `updaterFn` receives a `FieldAccessor`\n   * and returns an array of `TypedUpdateOp` (e.g. `[f.amount.inc(1),\n   * f.status.set('done')]`). Operators are folded into the wire-format\n   * update spec by `foldUpdateOps`, which throws on operator+path\n   * collisions.\n   */\n  override updateMany(\n    updaterFn: (\n      fields: FieldAccessor<\n        ModelToDocShape<TContract, ModelName>,\n        ModelNestedShape<TContract, ModelName>\n      >,\n    ) => UpdaterResult,\n  ): MongoQueryPlan<UpdateResult, UpdateManyCommand> {\n    const update = resolveUpdaterCallback<\n      ModelToDocShape<TContract, ModelName>,\n      ModelNestedShape<TContract, ModelName>\n    >(updaterFn);\n    const command = new UpdateManyCommand(this.#ctx.collection, this.#foldedFilter(), update);\n    return {\n      collection: this.#ctx.collection,\n      command,\n      meta: writeMeta(this.#ctx.storageHash),\n    };\n  }\n\n  /**\n   * Update at most one matching document. The driver picks the document\n   * (typically the first one matched by the underlying scan); no ordering\n   * guarantee is implied — chain `.sort(...)` and use the M3\n   * `.findOneAndUpdate(...)` terminal when ordering matters.\n   */\n  override updateOne(\n    updaterFn: (\n      fields: FieldAccessor<\n        ModelToDocShape<TContract, ModelName>,\n        ModelNestedShape<TContract, ModelName>\n      >,\n    ) => UpdaterResult,\n  ): MongoQueryPlan<UpdateResult, UpdateOneCommand> {\n    const update = resolveUpdaterCallback<\n      ModelToDocShape<TContract, ModelName>,\n      ModelNestedShape<TContract, ModelName>\n    >(updaterFn);\n    const command = new UpdateOneCommand(this.#ctx.collection, this.#foldedFilter(), update);\n    return {\n      collection: this.#ctx.collection,\n      command,\n      meta: writeMeta(this.#ctx.storageHash),\n    };\n  }\n\n  /**\n   * Delete every matching document.\n   */\n  deleteMany(): MongoQueryPlan<DeleteResult, DeleteManyCommand> {\n    const command = new DeleteManyCommand(this.#ctx.collection, this.#foldedFilter());\n    return {\n      collection: this.#ctx.collection,\n      command,\n      meta: writeMeta(this.#ctx.storageHash),\n    };\n  }\n\n  /**\n   * Delete at most one matching document. See the `updateOne` note about\n   * driver-chosen victim selection.\n   */\n  deleteOne(): MongoQueryPlan<DeleteResult, DeleteOneCommand> {\n    const command = new DeleteOneCommand(this.#ctx.collection, this.#foldedFilter());\n    return {\n      collection: this.#ctx.collection,\n      command,\n      meta: writeMeta(this.#ctx.storageHash),\n    };\n  }\n\n  // --- Upserts ---\n\n  /**\n   * Insert-or-update against the accumulated filter. Maps to\n   * `UpdateOneCommand` with `upsert: true`. Equivalent to\n   * `CollectionHandle.upsertOne(f => filter, updaterFn)` but reuses the\n   * already-accumulated `.match(...)` filter chain.\n   */\n  upsertOne(\n    updaterFn: (\n      fields: FieldAccessor<\n        ModelToDocShape<TContract, ModelName>,\n        ModelNestedShape<TContract, ModelName>\n      >,\n    ) => UpdaterResult,\n  ): MongoQueryPlan<UpdateResult, UpdateOneCommand> {\n    const update = resolveUpdaterCallback<\n      ModelToDocShape<TContract, ModelName>,\n      ModelNestedShape<TContract, ModelName>\n    >(updaterFn);\n    const command = new UpdateOneCommand(this.#ctx.collection, this.#foldedFilter(), update, true);\n    return {\n      collection: this.#ctx.collection,\n      command,\n      meta: writeMeta(this.#ctx.storageHash),\n    };\n  }\n\n  // --- Find-and-modify ---\n\n  /**\n   * Find a single matching document and apply `updaterFn` to it.\n   *\n   * `opts.upsert` (default `false`) toggles insert-on-miss behaviour.\n   * `opts.returnDocument` (default `'after'`) controls whether the row\n   * stream yields the document as it was before or after the update.\n   */\n  override findOneAndUpdate(\n    updaterFn: (\n      fields: FieldAccessor<\n        ModelToDocShape<TContract, ModelName>,\n        ModelNestedShape<TContract, ModelName>\n      >,\n    ) => UpdaterResult,\n    opts: { readonly upsert?: boolean; readonly returnDocument?: 'before' | 'after' } = {},\n  ): MongoQueryPlan<\n    ResolveRow<\n      ModelToDocShape<TContract, ModelName>,\n      ExtractMongoCodecTypes<TContract>,\n      TContract\n    > | null,\n    FindOneAndUpdateCommand\n  > {\n    const update = resolveUpdaterCallback<\n      ModelToDocShape<TContract, ModelName>,\n      ModelNestedShape<TContract, ModelName>\n    >(updaterFn);\n    const command = new FindOneAndUpdateCommand(\n      this.#ctx.collection,\n      this.#foldedFilter(),\n      update,\n      opts.upsert ?? false,\n      undefined,\n      opts.returnDocument ?? 'after',\n    );\n    return {\n      collection: this.#ctx.collection,\n      command,\n      meta: writeMeta(this.#ctx.storageHash),\n    };\n  }\n\n  /**\n   * Find a single matching document and delete it. Returns the deleted\n   * document via the row stream.\n   */\n  override findOneAndDelete(): MongoQueryPlan<\n    ResolveRow<\n      ModelToDocShape<TContract, ModelName>,\n      ExtractMongoCodecTypes<TContract>,\n      TContract\n    > | null,\n    FindOneAndDeleteCommand\n  > {\n    const command = new FindOneAndDeleteCommand(this.#ctx.collection, this.#foldedFilter());\n    return {\n      collection: this.#ctx.collection,\n      command,\n      meta: writeMeta(this.#ctx.storageHash),\n    };\n  }\n}\n\nfunction foldAnd(filters: ReadonlyArray<MongoFilterExpr>): MongoFilterExpr {\n  return MongoAndExpr.of(filters);\n}\n\n/**\n * Narrow a `MongoContractWithTypeMaps`-shaped value down to its underlying\n * `MongoContract` view. `MongoContractWithTypeMaps<C, ...>` is defined as\n * `C & { readonly [phantom]?: TTypeMaps }`, so every contract we accept is\n * structurally a `MongoContract` — the phantom is type-only. This helper\n * centralises that narrowing so callers don't reach for `as unknown as\n * MongoContract` double-casts.\n */\nexport function asMongoContract(\n  contract: MongoContractWithTypeMaps<MongoContract, AnyMongoTypeMaps>,\n): MongoContract {\n  return contract;\n}\n\n/**\n * Bound execution context shared across the three state classes.\n */\nexport interface BindingContext<\n  TContract extends MongoContractWithTypeMaps<MongoContract, AnyMongoTypeMaps>,\n> {\n  readonly contract: TContract;\n  readonly collection: string;\n  readonly storageHash: string;\n}\n\n/**\n * Construct a `CollectionHandle` from a validated contract + root name.\n * Used by `mongoQuery(...).from(name)` to enter the state machine.\n */\nexport function createCollectionHandle<\n  TContract extends MongoContractWithTypeMaps<MongoContract, AnyMongoTypeMaps>,\n  RootName extends keyof TContract['roots'] & string,\n>(\n  contract: TContract,\n  rootName: RootName,\n): CollectionHandle<TContract, RootModelName<TContract, RootName>> {\n  const c = asMongoContract(contract);\n  const modelName = c.roots[rootName]?.model;\n  if (!modelName) {\n    const validRoots = Object.keys(c.roots).join(', ');\n    throw new Error(`Unknown root: \"${rootName}\". Valid roots: ${validRoots}`);\n  }\n  const model = domainModelsAtDefaultNamespace(c.domain)[modelName] as\n    | MongoModelDefinition\n    | undefined;\n  if (!model) {\n    throw new Error(`Unknown model: \"${modelName}\" referenced by root \"${rootName}\".`);\n  }\n  const collectionName = model.storage.collection ?? rootName;\n  if (!c.storage?.storageHash) {\n    throw new Error(\n      'Contract is missing storage.storageHash. Pass a validated contract to mongoQuery().',\n    );\n  }\n  return new CollectionHandle(\n    {\n      contract,\n      collection: collectionName,\n      storageHash: String(c.storage.storageHash),\n    },\n    modelName as RootModelName<TContract, RootName>,\n  );\n}\n","import type { PlanMeta } from '@prisma-next/contract/types';\nimport type {\n  AnyMongoTypeMaps,\n  MongoContract,\n  MongoContractWithTypeMaps,\n  RootModelName,\n} from '@prisma-next/mongo-contract';\nimport type { AnyMongoCommand, MongoQueryPlan } from '@prisma-next/mongo-query-ast/execution';\nimport { blindCast } from '@prisma-next/utils/casts';\nimport { asMongoContract, type CollectionHandle, createCollectionHandle } from './state-classes';\n\n/**\n * Public entry point of the query builder. `mongoQuery(...).from(rootName)`\n * yields the root state of the three-state machine\n * (`CollectionHandle` → `FilteredCollection` → `PipelineChain`).\n *\n * `rawCommand(cmd)` is the escape hatch for cases the typed surface does\n * not cover (yet) — it accepts any `AnyMongoCommand` (typed CRUD or a\n * `RawMongoCommand` of `Document`s) and packages it into a `MongoQueryPlan`\n * with `lane: 'mongo-query'`. Row type is `unknown` because the runtime\n * cannot know what the caller's command yields.\n */\nexport interface QueryRoot<\n  TContract extends MongoContractWithTypeMaps<MongoContract, AnyMongoTypeMaps>,\n> {\n  from<K extends keyof TContract['roots'] & string>(\n    rootName: K,\n  ): CollectionHandle<TContract, RootModelName<TContract, K>>;\n  rawCommand<C extends AnyMongoCommand>(command: C): MongoQueryPlan<unknown, C>;\n}\n\nexport function mongoQuery<\n  TContract extends MongoContractWithTypeMaps<MongoContract, AnyMongoTypeMaps>,\n>(options: { contractJson: unknown }): QueryRoot<TContract> {\n  const contract = blindCast<\n    TContract,\n    'mongoQuery accepts validated contract JSON with domain.namespaces'\n  >(options.contractJson);\n  return {\n    from<K extends keyof TContract['roots'] & string>(rootName: K) {\n      return createCollectionHandle(contract, rootName);\n    },\n    rawCommand<C extends AnyMongoCommand>(command: C): MongoQueryPlan<unknown, C> {\n      const c = asMongoContract(contract);\n      const storageHash = c.storage?.storageHash;\n      if (!storageHash) {\n        throw new Error(\n          'Contract is missing storage.storageHash. Pass a validated contract to mongoQuery().',\n        );\n      }\n      const meta: PlanMeta = {\n        target: 'mongo',\n        storageHash: String(storageHash),\n        lane: 'mongo-query',\n      };\n      return { collection: command.collection, command, meta };\n    },\n  };\n}\n"],"mappings":"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"}