{"version":3,"file":"contract-free.mjs","names":["#collection","#stages","#filters","#name"],"sources":["../../src/contract-free/collection.ts"],"sourcesContent":["import {\n  CreateCollectionCommand,\n  type CreateCollectionOptions,\n  CreateIndexCommand,\n  type CreateIndexOptions,\n  type MongoIndexKey,\n} from '@prisma-next/mongo-query-ast/control';\nimport {\n  AggregateCommand,\n  FindOneAndUpdateCommand,\n  InsertOneCommand,\n  MongoAndExpr,\n  type MongoFilterExpr,\n  MongoLimitStage,\n  MongoMatchStage,\n  type MongoPipelineStage,\n  MongoSortStage,\n  type MongoUpdatePipelineStage,\n} from '@prisma-next/mongo-query-ast/execution';\nimport type { MongoValue } from '@prisma-next/mongo-value';\nimport { createFieldAccessor, type FieldAccessor } from '../field-accessor';\nimport type { DocShape } from '../types';\nimport { resolveUpdaterResult, type UpdaterResult } from '../update-ops';\n\n/**\n * Fold an array of filter expressions into a single `MongoFilterExpr`. Length-1\n * short-circuits to avoid a redundant `$and` wrapper; the call site never writes\n * `MongoAndExpr.of([...])` directly.\n */\nfunction foldFilters(filters: ReadonlyArray<MongoFilterExpr>): MongoFilterExpr {\n  const first = filters[0];\n  if (first === undefined) {\n    throw new Error('foldFilters: invariant violated — empty filter list');\n  }\n  return filters.length === 1 ? first : MongoAndExpr.of(filters);\n}\n\n/**\n * Fluent aggregate chain. Accumulates `$match` / `$sort` / `$limit` stages and\n * produces an `AggregateCommand` via `.build()`.\n *\n * Instances are immutable — each stage method returns a new chain.\n */\nexport class AggregateChain<Shape extends DocShape> {\n  readonly #collection: string;\n  readonly #stages: ReadonlyArray<MongoPipelineStage>;\n\n  constructor(collection: string, stages: ReadonlyArray<MongoPipelineStage>) {\n    this.#collection = collection;\n    this.#stages = stages;\n  }\n\n  match(filterFn: (fields: FieldAccessor<Shape>) => MongoFilterExpr): AggregateChain<Shape> {\n    const f = createFieldAccessor<Shape>();\n    const filter = filterFn(f);\n    return new AggregateChain<Shape>(this.#collection, [\n      ...this.#stages,\n      new MongoMatchStage(filter),\n    ]);\n  }\n\n  sort(spec: Record<string, 1 | -1>): AggregateChain<Shape> {\n    return new AggregateChain<Shape>(this.#collection, [...this.#stages, new MongoSortStage(spec)]);\n  }\n\n  limit(n: number): AggregateChain<Shape> {\n    return new AggregateChain<Shape>(this.#collection, [...this.#stages, new MongoLimitStage(n)]);\n  }\n\n  build(): AggregateCommand {\n    return new AggregateCommand(this.#collection, this.#stages);\n  }\n}\n\n/**\n * Fluent find-and-modify chain. Holds an accumulated list of filter expressions\n * (AND-folded into the wire command's `filter` slot) and exposes\n * `.findOneAndUpdate(...)` as the only terminal.\n *\n * Multiple `.match()` calls AND-fold internally — `MongoAndExpr.of` never\n * appears at the call site.\n *\n * Instances are immutable — `.match()` returns a new `FilteredBuilder`.\n */\nexport class FilteredBuilder<Shape extends DocShape> {\n  readonly #collection: string;\n  readonly #filters: ReadonlyArray<MongoFilterExpr>;\n\n  constructor(collection: string, filters: ReadonlyArray<MongoFilterExpr>) {\n    if (filters.length === 0) {\n      throw new Error('FilteredBuilder requires at least one filter');\n    }\n    this.#collection = collection;\n    this.#filters = filters;\n  }\n\n  match(filterFn: (fields: FieldAccessor<Shape>) => MongoFilterExpr): FilteredBuilder<Shape> {\n    const f = createFieldAccessor<Shape>();\n    const filter = filterFn(f);\n    return new FilteredBuilder<Shape>(this.#collection, [...this.#filters, filter]);\n  }\n\n  findOneAndUpdate(\n    updaterFn: (fields: FieldAccessor<Shape>) => UpdaterResult,\n    opts: { readonly upsert?: boolean; readonly returnDocument?: 'before' | 'after' } = {},\n  ): FindOneAndUpdateCommand {\n    const filter = foldFilters(this.#filters);\n    const f = createFieldAccessor<Shape>();\n    const items = updaterFn(f);\n    const update = resolveUpdaterResult(items);\n    return new FindOneAndUpdateCommand(\n      this.#collection,\n      filter,\n      update,\n      opts.upsert ?? false,\n      undefined,\n      opts.returnDocument ?? 'after',\n    );\n  }\n}\n\n/**\n * Contract-free fluent Mongo collection builder. Produces the canonical\n * `AggregateCommand` / `InsertOneCommand` / `FindOneAndUpdateCommand` command\n * nodes without any contract coupling — parameterised by an explicit `DocShape`\n * instead of a `MongoContract`.\n *\n * Mirrors SQL's `table(source, schema)` → `TableHandle` in spirit: a top-level\n * entry point that exposes fluent query chains from which call sites never write\n * `new MongoMatchStage(...)`, `MongoAndExpr.of([...])`, or `new AggregateCommand(...)`.\n *\n * ```ts\n * const markerLedger = collection<MarkerLedgerDocShape>('_prisma_migrations');\n *\n * // aggregate\n * markerLedger.aggregate().match(f => f._id.eq(space)).limit(1).build();\n *\n * // insertOne\n * markerLedger.insertOne({ _id: space, space, storageHash });\n *\n * // findOneAndUpdate (CAS)\n * markerLedger.match(f => f._id.eq(space)).match(f => f.storageHash.eq(expectedFrom))\n *   .findOneAndUpdate(f => [f.stage.set({ storageHash: newHash })], { upsert: false });\n * ```\n */\nexport interface CollectionBuilder<Shape extends DocShape> {\n  aggregate(): AggregateChain<Shape>;\n  insertOne(document: Record<string, MongoValue>): InsertOneCommand;\n  match(filterFn: (fields: FieldAccessor<Shape>) => MongoFilterExpr): FilteredBuilder<Shape>;\n  createCollection(options?: CreateCollectionOptions): CreateCollectionCommand;\n  createIndex(keys: ReadonlyArray<MongoIndexKey>, options?: CreateIndexOptions): CreateIndexCommand;\n}\n\nclass CollectionBuilderImpl<Shape extends DocShape> implements CollectionBuilder<Shape> {\n  readonly #name: string;\n\n  constructor(name: string) {\n    this.#name = name;\n  }\n\n  aggregate(): AggregateChain<Shape> {\n    return new AggregateChain<Shape>(this.#name, []);\n  }\n\n  insertOne(document: Record<string, MongoValue>): InsertOneCommand {\n    return new InsertOneCommand(this.#name, document);\n  }\n\n  match(filterFn: (fields: FieldAccessor<Shape>) => MongoFilterExpr): FilteredBuilder<Shape> {\n    const f = createFieldAccessor<Shape>();\n    const filter = filterFn(f);\n    return new FilteredBuilder<Shape>(this.#name, [filter]);\n  }\n\n  createCollection(options?: CreateCollectionOptions): CreateCollectionCommand {\n    return new CreateCollectionCommand(this.#name, options);\n  }\n\n  createIndex(\n    keys: ReadonlyArray<MongoIndexKey>,\n    options?: CreateIndexOptions,\n  ): CreateIndexCommand {\n    return new CreateIndexCommand(this.#name, keys, options);\n  }\n}\n\n/**\n * Declare a contract-free collection builder parameterised by a `DocShape`.\n * The collection name is bound once; field access reuses `createFieldAccessor`\n * so the shape is typed at every call site without a contract.\n *\n * @param name The MongoDB collection name (e.g. `'_prisma_migrations'`)\n */\nexport function collection<Shape extends DocShape>(name: string): CollectionBuilder<Shape> {\n  return new CollectionBuilderImpl<Shape>(name);\n}\n\nexport type { MongoUpdatePipelineStage };\n"],"mappings":";;;;;;;;;AA6BA,SAAS,YAAY,SAA0D;CAC7E,MAAM,QAAQ,QAAQ;CACtB,IAAI,UAAU,KAAA,GACZ,MAAM,IAAI,MAAM,qDAAqD;CAEvE,OAAO,QAAQ,WAAW,IAAI,QAAQ,aAAa,GAAG,OAAO;AAC/D;;;;;;;AAQA,IAAa,iBAAb,MAAa,eAAuC;CAClD;CACA;CAEA,YAAY,YAAoB,QAA2C;EACzE,KAAKA,cAAc;EACnB,KAAKC,UAAU;CACjB;CAEA,MAAM,UAAoF;EAExF,MAAM,SAAS,SADL,oBACc,CAAC;EACzB,OAAO,IAAI,eAAsB,KAAKD,aAAa,CACjD,GAAG,KAAKC,SACR,IAAI,gBAAgB,MAAM,CAC5B,CAAC;CACH;CAEA,KAAK,MAAqD;EACxD,OAAO,IAAI,eAAsB,KAAKD,aAAa,CAAC,GAAG,KAAKC,SAAS,IAAI,eAAe,IAAI,CAAC,CAAC;CAChG;CAEA,MAAM,GAAkC;EACtC,OAAO,IAAI,eAAsB,KAAKD,aAAa,CAAC,GAAG,KAAKC,SAAS,IAAI,gBAAgB,CAAC,CAAC,CAAC;CAC9F;CAEA,QAA0B;EACxB,OAAO,IAAI,iBAAiB,KAAKD,aAAa,KAAKC,OAAO;CAC5D;AACF;;;;;;;;;;;AAYA,IAAa,kBAAb,MAAa,gBAAwC;CACnD;CACA;CAEA,YAAY,YAAoB,SAAyC;EACvE,IAAI,QAAQ,WAAW,GACrB,MAAM,IAAI,MAAM,8CAA8C;EAEhE,KAAKD,cAAc;EACnB,KAAKE,WAAW;CAClB;CAEA,MAAM,UAAqF;EAEzF,MAAM,SAAS,SADL,oBACc,CAAC;EACzB,OAAO,IAAI,gBAAuB,KAAKF,aAAa,CAAC,GAAG,KAAKE,UAAU,MAAM,CAAC;CAChF;CAEA,iBACE,WACA,OAAoF,CAAC,GAC5D;EACzB,MAAM,SAAS,YAAY,KAAKA,QAAQ;EAGxC,MAAM,SAAS,qBADD,UADJ,oBACc,CACgB,CAAC;EACzC,OAAO,IAAI,wBACT,KAAKF,aACL,QACA,QACA,KAAK,UAAU,OACf,KAAA,GACA,KAAK,kBAAkB,OACzB;CACF;AACF;AAkCA,IAAM,wBAAN,MAAwF;CACtF;CAEA,YAAY,MAAc;EACxB,KAAKG,QAAQ;CACf;CAEA,YAAmC;EACjC,OAAO,IAAI,eAAsB,KAAKA,OAAO,CAAC,CAAC;CACjD;CAEA,UAAU,UAAwD;EAChE,OAAO,IAAI,iBAAiB,KAAKA,OAAO,QAAQ;CAClD;CAEA,MAAM,UAAqF;EAEzF,MAAM,SAAS,SADL,oBACc,CAAC;EACzB,OAAO,IAAI,gBAAuB,KAAKA,OAAO,CAAC,MAAM,CAAC;CACxD;CAEA,iBAAiB,SAA4D;EAC3E,OAAO,IAAI,wBAAwB,KAAKA,OAAO,OAAO;CACxD;CAEA,YACE,MACA,SACoB;EACpB,OAAO,IAAI,mBAAmB,KAAKA,OAAO,MAAM,OAAO;CACzD;AACF;;;;;;;;AASA,SAAgB,WAAmC,MAAwC;CACzF,OAAO,IAAI,sBAA6B,IAAI;AAC9C"}