import { A as ResolveRow, C as GroupedDocShape, D as NullableNumericField, E as NullableDocField, F as UnwoundShape, M as StringField, N as TypedAccumulatorExpr, O as NumericField, P as TypedAggExpr, S as GroupSpec, T as ModelToDocShape, _ as BooleanField, a as createFieldAccessor, b as DocShape, c as UpdaterResult, d as NestedDocShape, f as ObjectField, g as ArrayField, h as ValidPaths, i as ObjectExpression, j as SortSpec, k as ProjectedShape, l as ModelArrayField, m as ResolvePath, n as FieldAccessor, o as expr, p as PathCompletions, r as LeafExpression, s as TypedUpdateOp, t as Expression, u as ModelNestedShape, v as DateField, w as LiteralValue, x as ExtractDocShape, y as DocField } from "./field-accessor-BfujBG1Q.mjs"; import { AggregateCommand, AnyMongoCommand, DeleteManyCommand, DeleteOneCommand, DeleteResult, DeleteResult as DeleteResult$1, FindOneAndDeleteCommand, FindOneAndUpdateCommand, InsertManyCommand, InsertManyResult, InsertManyResult as InsertManyResult$1, InsertOneCommand, InsertOneResult, InsertOneResult as InsertOneResult$1, MongoAggAccumulator, MongoAggExpr, MongoDensifyRange, MongoFieldShape, MongoFillOutput, MongoFilterExpr, MongoPipelineStage, MongoQueryPlan, MongoResultShape, MongoUpdatePipelineStage, MongoWindowField, UpdateManyCommand, UpdateOneCommand, UpdateResult, UpdateResult as UpdateResult$1 } from "@prisma-next/mongo-query-ast/execution"; import { ContractField } from "@prisma-next/contract/types"; import { MongoValue } from "@prisma-next/mongo-value"; import { AnyMongoTypeMaps, ExtractMongoCodecTypes, MongoContract, MongoContractWithTypeMaps, MongoModelDefinition, MongoModelsMap, RootModelName } from "@prisma-next/mongo-contract"; //#region src/accumulator-helpers.d.ts declare const acc: { sum(expr: TypedAggExpr): TypedAccumulatorExpr; avg(expr: TypedAggExpr): TypedAccumulatorExpr; min(expr: TypedAggExpr): TypedAccumulatorExpr<{ readonly codecId: F["codecId"]; readonly nullable: true; }>; max(expr: TypedAggExpr): TypedAccumulatorExpr<{ readonly codecId: F["codecId"]; readonly nullable: true; }>; first(expr: TypedAggExpr): TypedAccumulatorExpr<{ readonly codecId: F["codecId"]; readonly nullable: true; }>; last(expr: TypedAggExpr): TypedAccumulatorExpr<{ readonly codecId: F["codecId"]; readonly nullable: true; }>; push(expr: TypedAggExpr): TypedAccumulatorExpr; addToSet(expr: TypedAggExpr): TypedAccumulatorExpr; count(): TypedAccumulatorExpr; stdDevPop(expr: TypedAggExpr): TypedAccumulatorExpr; stdDevSamp(expr: TypedAggExpr): TypedAccumulatorExpr; firstN(args: { input: TypedAggExpr; n: TypedAggExpr; }): TypedAccumulatorExpr; lastN(args: { input: TypedAggExpr; n: TypedAggExpr; }): TypedAccumulatorExpr; maxN(args: { input: TypedAggExpr; n: TypedAggExpr; }): TypedAccumulatorExpr; minN(args: { input: TypedAggExpr; n: TypedAggExpr; }): TypedAccumulatorExpr; top(args: { output: TypedAggExpr; sortBy: Readonly>; }): TypedAccumulatorExpr; bottom(args: { output: TypedAggExpr; sortBy: Readonly>; }): TypedAccumulatorExpr; topN(args: { output: TypedAggExpr; sortBy: Readonly>; n: TypedAggExpr; }): TypedAccumulatorExpr; bottomN(args: { output: TypedAggExpr; sortBy: Readonly>; n: TypedAggExpr; }): TypedAccumulatorExpr; }; //#endregion //#region src/lookup-builder.d.ts /** * Resolved foreign-model name for a contract root. Looks `RootName` up * through `TContract['roots']` and extracts the referenced model name * so it can be used as a `ModelName` index into `models`. Resolves to * `never` when the root is not present (this surface should never be * reachable through normal use because `from()` constrains its `R` * parameter to `keyof TContract['roots']`). */ type ModelOf = RootModelName; /** * Object returned by the user from the `on(...)` callback. Each side is * a `LeafExpression` produced by property access on the corresponding * `FieldAccessor` (`local._id`, `foreign.customerId`, etc.). Carrying * `LeafExpression` rather than the broader `TypedAggExpr` is what makes * non-leaf returns (e.g. `fn.toUpper(local._id)`) a compile-time error * without per-field operator gating — `LeafExpression` carries `_path`, * `TypedAggExpr` does not (see field-accessor.ts L47–L82). */ interface LookupOnResult { readonly local: LeafExpression; readonly foreign: LeafExpression; } /** * Marker brand on the captured spec returned by the `lookup(...)` * callback. The phantom `_brand` literal lets `PipelineChain.lookup` * accept the result of `from(...).on(...).as(...)` without exposing the * internal field shape to user code, and prevents accidental * construction of a malformed spec by hand. */ type LookupResultBrand = 'mongo-query-builder/lookup-result@1'; /** * Captured output of the inner `from(name).on(cb).as(name)` chain. The * contract is consumed by `PipelineChain.lookup` to construct the * `MongoLookupStage` (collection name comes from `models[ModelName] * .storage.collection`) and to thread `ModelArrayField` into * the resulting `Shape` so the resolver yields `Array`. * * Type parameters carry the foreign-root literal `RootName`, the * resolved foreign model name `ModelName`, and the `As` literal so * `PipelineChain.lookup`'s return type can encode the result-row * promotion precisely. */ interface LookupResult { readonly _brand: LookupResultBrand; readonly _root: RootName; readonly _model: ModelName; readonly _localField: string; readonly _foreignField: string; readonly _as: As; } /** * Builder returned by `from(name).on(cb)`. Carries the foreign root / * model literals plus the captured local / foreign paths, and exposes * `.as(name)` to finalise the spec with the user-chosen field name. */ interface LookupBuilderWithKey { as(name: As): LookupResult; } /** * Builder returned by `from(name)`. Carries the foreign root / model * literals and the local pipeline's `Shape` / nested shape so the * `on(...)` callback's `local` and `foreign` accessors are typed * narrowly. * * `on(cb)` runs the user's callback to capture the leaf paths and * returns a `LookupBuilderWithKey` that exposes `.as(name)`. */ interface LookupBuilder, RootName extends string, ModelName extends string> { on(cb: (local: FieldAccessor, foreign: ModelName extends keyof MongoModelsMap & string ? FieldAccessor, ModelNestedShape> : never) => LookupOnResult): LookupBuilderWithKey; } /** * Type of the `from` callable passed to `PipelineChain.lookup`'s outer * callback. The generic argument is inferred from a string-literal * argument (the same pattern as `mongoQuery(...).from('orders')`), * which grounds `RootName` into the returned `LookupBuilder` *before* * the inner `on(...)` callback is type-checked. This sequential * inference is what makes `foreign` resolve narrowly to the foreign * model's `FieldAccessor` (verified in the R1.5 spike — see spec § Open * Questions / Resolved decisions). */ type LookupFrom> = (name: RootName) => LookupBuilder>; //#endregion //#region src/markers.d.ts /** * Phantom capability markers for `PipelineChain`. * * `UpdateEnabled` — gates `.updateMany()` / `.updateOne()` no-arg form * (consume accumulated pipeline as an update-with-pipeline spec). * `FindAndModifyEnabled` — gates `.findOneAndUpdate(...)` / `.findOneAndDelete(...)` * (deconstruct pipeline into the wire command's filter/sort/skip slots). * `LeadingMatch` — internal marker tracking whether the chain is still * in its leading-`$match` prefix. Flips to `'past-leading'` * after the first non-`$match` stage, which lets * `match()` clear `UpdateEnabled` on second `$match` * stages that sit past the prefix (and would otherwise * fail at runtime inside `deconstructUpdateChain`). * * Each pipeline-stage method either preserves or clears these markers per * the marker table (and rationale per row) in * `docs/architecture docs/adrs/ADR 201 - State-machine pattern for typed DSL builders.md`. * * The markers exist only at the type level; nothing reads them at runtime. * Value literals are self-identifying so the slots are distinguishable in * hover tooltips and error messages (e.g. `'update-ok'` vs `'fam-ok'`). */ type UpdateEnabled = 'update-ok' | 'update-cleared'; type FindAndModifyEnabled = 'fam-ok' | 'fam-cleared'; type LeadingMatch = 'leading' | 'past-leading'; //#endregion //#region src/builder.d.ts interface PipelineChainState { readonly collection: string; readonly stages: ReadonlyArray; readonly storageHash: string; readonly modelName?: string; } /** * The pipeline state in the query-builder state machine. * * Reached from `CollectionHandle` or `FilteredCollection` after the first * pipeline-stage method call (or directly via `aggregate()` shortcuts). Holds * the accumulated `MongoPipelineStage[]` and exposes pipeline-stage methods, * the `merge`/`out` write terminals, and the `build`/`aggregate` read * terminals. * * Two phantom type parameters gate the conditional terminals: * * - `U extends UpdateEnabled` — when `'update-ok'`, the no-arg `updateMany()` / * `updateOne()` form is available (consume the chain as an * update-with-pipeline spec). Cleared by stages that produce content the * `update` AST cannot represent (e.g. `$group`, `$lookup`, `$limit`). * - `F extends FindAndModifyEnabled` — when `'fam-ok'`, the * `findOneAndUpdate(...)` / `findOneAndDelete(...)` terminals are * available. Cleared by stages incompatible with their wire-command slots * (`$limit`, `$group`, mutating stages, …). * * The marker semantics are encoded in the per-method return types — see the * marker table (and rationale per row) in * `docs/architecture docs/adrs/ADR 201 - State-machine pattern for typed DSL builders.md`. */ declare class PipelineChain, Shape extends DocShape, U extends UpdateEnabled = 'update-ok', F extends FindAndModifyEnabled = 'fam-ok', L extends LeadingMatch = 'leading', N extends NestedDocShape = Record> { #private; readonly __updateCompat: U; readonly __findAndModifyCompat: F; readonly __leadingMatch: L; constructor(contract: TContract, state: PipelineChainState); /** * `$match`. `FindAndModifyEnabled` is always preserved. `UpdateEnabled` is * preserved only while the chain is still in the leading-`$match` prefix * (`L = 'leading'`); a `$match` that follows any non-`$match` stage * transitions to `L = 'past-leading'` and clears `UpdateEnabled`, since * `deconstructUpdateChain` can only peel leading `$match` stages into the * wire-command filter. */ match(filter: MongoFilterExpr): PipelineChain; match(fn: (fields: FieldAccessor) => MongoFilterExpr): PipelineChain; /** * `$sort`. Clears `UpdateEnabled` (`update` has no per-document sort) but * preserves `FindAndModifyEnabled` (`findAndModify` has a `sort` slot). */ sort(spec: SortSpec): PipelineChain; /** * `$limit`. Clears both markers — `limit` is incompatible with the `update` * wire command, and `findAndModify` already implies single-document * semantics (so `.limit(...)` adds no meaning, only ambiguity). */ limit(n: number): PipelineChain; /** * `$skip`. Clears both markers — MongoDB's `findAndModify` wire command * has no `skip` slot, so `deconstructFindAndModifyChain` rejects any * `$skip` at runtime; keeping the marker `fam-cleared` makes the type * system reflect the same constraint (see ADR 201 marker table). */ skip(n: number): PipelineChain; sample(n: number): PipelineChain; /** * `$addFields`. Preserves `UpdateEnabled` (representable as * update-with-pipeline `$set`); clears `FindAndModifyEnabled` (no analogue * in the find-and-modify wire commands). The nested-path shape `N` is * preserved — newly added flat fields are reachable via property access * (`f.newField`) but do not themselves carry nested structure. */ addFields>>(fn: (fields: FieldAccessor) => NewFields): PipelineChain, U, 'fam-cleared', 'past-leading', N>; /** * `$lookup`. Clears both markers — joins are not representable in either * the `update` or `findAndModify` wire commands. The original document's * nested-path shape `N` is preserved (the lookup adds a sidecar array * field; existing keys are untouched). * * The single callback receives a `from` callable that grounds the * foreign-root literal sequentially before the inner `on(...)` * callback is type-checked — see `lookup-builder.ts`. The resulting * `Shape` gains the `As` key as a `ModelArrayField` so * `ResolveRow` produces `Array` (with concrete leaf * types) instead of the legacy `unknown[]`. */ lookup(fn: (from: LookupFrom) => LookupResult): PipelineChain>, 'update-cleared', 'fam-cleared', 'past-leading', N>; /** * `$project`. Preserves `UpdateEnabled` (representable as update-with-pipeline * `$project` / `$unset`); clears `FindAndModifyEnabled` (use `.project()` on * the result of `.build()` if both projection and find-and-modify are * needed — see spec). * * Resets the nested-path shape to `Record` — projection * fundamentally rewrites the document, so dot-paths into the *source* * document are no longer meaningful downstream. */ project(...keys: K[]): PipelineChain, U, 'fam-cleared', 'past-leading'>; project>>(fn: (fields: FieldAccessor) => Spec): PipelineChain, U, 'fam-cleared', 'past-leading'>; /** * `$unwind`. Clears both markers — array unrolling produces multiple output * documents per input, incompatible with both single-document update and * find-and-modify wire commands. The original `N` is preserved: unwind * replaces the unwound array slot with its element but leaves the rest * of the document structurally intact. */ unwind(field: K, options?: { preserveNullAndEmptyArrays?: boolean; }): PipelineChain, 'update-cleared', 'fam-cleared', 'past-leading', N>; /** * `$group`. Clears both markers — group output bears no relation to source * documents; neither `update` nor `findAndModify` can consume it. Nested * path shape is reset (the source document's path tree is gone). */ group(fn: (fields: FieldAccessor) => Spec): PipelineChain, 'update-cleared', 'fam-cleared', 'past-leading'>; /** * `$replaceRoot`. Preserves `UpdateEnabled` (representable as * update-with-pipeline `$replaceRoot`); clears `FindAndModifyEnabled`. * Nested path shape is reset — the replaced root has no relation to * the original document structure. */ replaceRoot(fn: (fields: FieldAccessor) => Expression | TypedAggExpr): PipelineChain; count(field: Field): PipelineChain, 'update-cleared', 'fam-cleared', 'past-leading'>; sortByCount(fn: (fields: FieldAccessor) => Expression | TypedAggExpr): PipelineChain; /** * `$redact`. Preserves `UpdateEnabled`; clears `FindAndModifyEnabled`. * Shape- and nested-path-preserving (the document tree is unchanged). */ redact(fn: (fields: FieldAccessor) => Expression | TypedAggExpr): PipelineChain; /** * `$out` write terminal. Materialises the pipeline output into * `collection` (optionally in `db`), replacing any prior contents. Unlike * the other pipeline-stage methods, this **terminates** the chain — it * returns a `MongoQueryPlan` rather than another `PipelineChain`, since * `$out` must be the final stage and there is nothing further to chain. * * Lane is `mongo-query` (matching all other terminals in this package) so * middleware can dispatch on intent without inspecting the command. * * The result row stream is empty (`unknown` row type) — the data lives * in the destination collection, not the response. */ out(collection: string, db?: string): MongoQueryPlan; /** * `$merge` write terminal. Streams the pipeline output into the target * collection per the supplied merge semantics (`whenMatched` / * `whenNotMatched`). Like `out()`, terminates the chain — `$merge` must * be the final stage. */ merge(options: { into: string | { db: string; coll: string; }; on?: string | ReadonlyArray; whenMatched?: string | ReadonlyArray; whenNotMatched?: string; }): MongoQueryPlan; unionWith(collection: string, pipeline?: ReadonlyArray): PipelineChain; bucket(options: { groupBy: MongoAggExpr; boundaries: ReadonlyArray; default_?: unknown; output?: Record; }): PipelineChain; bucketAuto(options: { groupBy: MongoAggExpr; buckets: number; output?: Record; granularity?: string; }): PipelineChain; geoNear(options: { near: unknown; distanceField: string; spherical?: boolean; maxDistance?: number; minDistance?: number; query?: MongoFilterExpr; key?: string; distanceMultiplier?: number; includeLocs?: string; }): PipelineChain; facet(facets: Record>): PipelineChain; graphLookup(options: { from: string; startWith: MongoAggExpr; connectFromField: string; connectToField: string; as: string; maxDepth?: number; depthField?: string; restrictSearchWithMatch?: MongoFilterExpr; }): PipelineChain; setWindowFields(options: { partitionBy?: MongoAggExpr; sortBy?: Record; output: Record; }): PipelineChain; densify(options: { field: string; partitionByFields?: ReadonlyArray; range: MongoDensifyRange; }): PipelineChain; fill(options: { partitionBy?: MongoAggExpr; partitionByFields?: ReadonlyArray; sortBy?: Record; output: Record; }): PipelineChain; search(config: Record, index?: string): PipelineChain; searchMeta(config: Record, index?: string): PipelineChain; vectorSearch(options: { index: string; path: string; queryVector: ReadonlyArray; numCandidates: number; limit: number; filter?: Record; }): PipelineChain; pipe(stage: MongoPipelineStage): PipelineChain; pipe(stage: MongoPipelineStage): PipelineChain; /** * No-arg `updateMany()`: deconstruct the chain into leading `$match` * stages (folded into the filter) and remaining stages (which must all * be valid pipeline-update stages). Available only when `U = 'update-ok'`. * * The optional callback parameter exists for subclass-override * compatibility with `FilteredCollection.updateMany(updaterFn)` — TS's * strict override check requires the parent's parameter to accept at * least what the child's signature does. A runtime guard throws if a * callback is actually passed on a bare `PipelineChain`. Note that * because nothing in the public surface transitions `U` from * `'update-cleared'` (the initial state on `CollectionHandle` / * `FilteredCollection`) back to `'update-ok'`, the no-arg form is * reachable only via explicit type casts in internal tests — the * callback-form "type hole" is therefore not reachable from user * code. See `docs/architecture docs/adrs/ADR 201 - State-machine * pattern for typed DSL builders.md` for the marker-transition table. */ updateMany(this: PipelineChain, updaterFn?: (fields: FieldAccessor) => UpdaterResult): MongoQueryPlan; /** * No-arg `updateOne()`: same as `updateMany()` but maps to a single-doc * update. Carries the same optional-callback/subclass-compat caveat * documented above — the callback form is reachable only via forced * casts in internal tests. */ updateOne(this: PipelineChain, updaterFn?: (fields: FieldAccessor) => UpdaterResult): MongoQueryPlan; /** * Find a single document matching the accumulated pipeline (which must * consist solely of leading `$match` stages followed by at most one * `$sort`) and apply `updaterFn`. Available only when * `FindAndModifyEnabled` is `'fam-ok'` — stages that clear the marker * (including `$skip`, which MongoDB's `findAndModify` has no slot for) * make this method invisible at the type level. * * The pipeline stages are deconstructed into the wire command's `filter` * and `sort` slots. If any non-deconstructable stage is present, a * runtime error is thrown as a defensive check (the type system should * prevent this). */ findOneAndUpdate(this: PipelineChain, updaterFn: (fields: FieldAccessor) => UpdaterResult, opts?: { readonly upsert?: boolean; readonly returnDocument?: 'before' | 'after'; }): MongoQueryPlan, TContract> | null, FindOneAndUpdateCommand>; /** * Find a single document matching the accumulated pipeline and delete it. * Same marker gating and deconstruction as `findOneAndUpdate`. */ findOneAndDelete(this: PipelineChain): MongoQueryPlan, TContract> | null, FindOneAndDeleteCommand>; /** * Materialise the chain as a `MongoQueryPlan` wrapping an `AggregateCommand`. */ build(): MongoQueryPlan, TContract>, AggregateCommand>; /** * Alias for `build()` — surfaces the read intent at the call site. */ aggregate(): MongoQueryPlan, TContract>, AggregateCommand>; } //#endregion //#region src/expression-helpers.d.ts declare function literal(value: string): TypedAggExpr; declare function literal(value: number): TypedAggExpr; declare function literal(value: boolean): TypedAggExpr; declare function literal(value: Date): TypedAggExpr; declare function literal(value: LiteralValue): TypedAggExpr; declare const fn: { add(...args: TypedAggExpr[]): TypedAggExpr; subtract(a: TypedAggExpr, b: TypedAggExpr): TypedAggExpr; multiply(...args: TypedAggExpr[]): TypedAggExpr; divide(a: TypedAggExpr, b: TypedAggExpr): TypedAggExpr; concat(...args: TypedAggExpr[]): TypedAggExpr; toLower(a: TypedAggExpr): TypedAggExpr; toUpper(a: TypedAggExpr): TypedAggExpr; size(a: TypedAggExpr): TypedAggExpr; cond(condition: MongoAggExpr, thenExpr: TypedAggExpr, elseExpr: TypedAggExpr): TypedAggExpr; literal: typeof literal; year(a: TypedAggExpr): TypedAggExpr; month(a: TypedAggExpr): TypedAggExpr; dayOfMonth(a: TypedAggExpr): TypedAggExpr; hour(a: TypedAggExpr): TypedAggExpr; minute(a: TypedAggExpr): TypedAggExpr; second(a: TypedAggExpr): TypedAggExpr; millisecond(a: TypedAggExpr): TypedAggExpr; dateToString(args: { date: TypedAggExpr; format?: TypedAggExpr; timezone?: TypedAggExpr; onNull?: TypedAggExpr; }): TypedAggExpr; dateFromString(args: { dateString: TypedAggExpr; format?: TypedAggExpr; timezone?: TypedAggExpr; onError?: TypedAggExpr; onNull?: TypedAggExpr; }): TypedAggExpr; dateDiff(args: { startDate: TypedAggExpr; endDate: TypedAggExpr; unit: TypedAggExpr; timezone?: TypedAggExpr; startOfWeek?: TypedAggExpr; }): TypedAggExpr; dateAdd(args: { startDate: TypedAggExpr; unit: TypedAggExpr; amount: TypedAggExpr; timezone?: TypedAggExpr; }): TypedAggExpr; dateSubtract(args: { startDate: TypedAggExpr; unit: TypedAggExpr; amount: TypedAggExpr; timezone?: TypedAggExpr; }): TypedAggExpr; dateTrunc(args: { date: TypedAggExpr; unit: TypedAggExpr; binSize?: TypedAggExpr; timezone?: TypedAggExpr; startOfWeek?: TypedAggExpr; }): TypedAggExpr; substr(str: TypedAggExpr, start: TypedAggExpr, length: TypedAggExpr): TypedAggExpr; substrBytes(str: TypedAggExpr, start: TypedAggExpr, count: TypedAggExpr): TypedAggExpr; trim(args: { input: TypedAggExpr; chars?: TypedAggExpr; }): TypedAggExpr; ltrim(args: { input: TypedAggExpr; chars?: TypedAggExpr; }): TypedAggExpr; rtrim(args: { input: TypedAggExpr; chars?: TypedAggExpr; }): TypedAggExpr; split(str: TypedAggExpr, delimiter: TypedAggExpr): TypedAggExpr; strLenCP(a: TypedAggExpr): TypedAggExpr; strLenBytes(a: TypedAggExpr): TypedAggExpr; regexMatch(args: { input: TypedAggExpr; regex: TypedAggExpr; options?: TypedAggExpr; }): TypedAggExpr; regexFind(args: { input: TypedAggExpr; regex: TypedAggExpr; options?: TypedAggExpr; }): TypedAggExpr; regexFindAll(args: { input: TypedAggExpr; regex: TypedAggExpr; options?: TypedAggExpr; }): TypedAggExpr; replaceOne(args: { input: TypedAggExpr; find: TypedAggExpr; replacement: TypedAggExpr; }): TypedAggExpr; replaceAll(args: { input: TypedAggExpr; find: TypedAggExpr; replacement: TypedAggExpr; }): TypedAggExpr; cmp(a: TypedAggExpr, b: TypedAggExpr): TypedAggExpr; eq(a: TypedAggExpr, b: TypedAggExpr): TypedAggExpr; ne(a: TypedAggExpr, b: TypedAggExpr): TypedAggExpr; gt(a: TypedAggExpr, b: TypedAggExpr): TypedAggExpr; gte(a: TypedAggExpr, b: TypedAggExpr): TypedAggExpr; lt(a: TypedAggExpr, b: TypedAggExpr): TypedAggExpr; lte(a: TypedAggExpr, b: TypedAggExpr): TypedAggExpr; arrayElemAt(arr: TypedAggExpr, idx: TypedAggExpr): TypedAggExpr; concatArrays(...args: TypedAggExpr[]): TypedAggExpr; firstElem(a: TypedAggExpr): TypedAggExpr; lastElem(a: TypedAggExpr): TypedAggExpr; isIn(elem: TypedAggExpr, arr: TypedAggExpr): TypedAggExpr; indexOfArray(arr: TypedAggExpr, value: TypedAggExpr, ...rest: TypedAggExpr[]): TypedAggExpr; isArray(a: TypedAggExpr): TypedAggExpr; reverseArray(a: TypedAggExpr): TypedAggExpr; slice(arr: TypedAggExpr, ...rest: TypedAggExpr[]): TypedAggExpr; zip(args: { inputs: TypedAggExpr[]; useLongestLength?: TypedAggExpr; defaults?: TypedAggExpr; }): TypedAggExpr; range(start: TypedAggExpr, end: TypedAggExpr, step: TypedAggExpr): TypedAggExpr; setUnion(...args: TypedAggExpr[]): TypedAggExpr; setIntersection(...args: TypedAggExpr[]): TypedAggExpr; setDifference(a: TypedAggExpr, b: TypedAggExpr): TypedAggExpr; setEquals(...args: TypedAggExpr[]): TypedAggExpr; setIsSubset(a: TypedAggExpr, b: TypedAggExpr): TypedAggExpr; anyElementTrue(a: TypedAggExpr): TypedAggExpr; allElementsTrue(a: TypedAggExpr): TypedAggExpr; typeOf(a: TypedAggExpr): TypedAggExpr; convert(args: { input: TypedAggExpr; to: TypedAggExpr; onError?: TypedAggExpr; onNull?: TypedAggExpr; }): TypedAggExpr; toInt(a: TypedAggExpr): TypedAggExpr; toLong(a: TypedAggExpr): TypedAggExpr; toDouble(a: TypedAggExpr): TypedAggExpr; toDecimal(a: TypedAggExpr): TypedAggExpr; toString_(a: TypedAggExpr): TypedAggExpr; toObjectId(a: TypedAggExpr): TypedAggExpr; toBool(a: TypedAggExpr): TypedAggExpr; toDate(a: TypedAggExpr): TypedAggExpr; objectToArray(a: TypedAggExpr): TypedAggExpr; arrayToObject(a: TypedAggExpr): TypedAggExpr; getField(args: { field: TypedAggExpr; input?: TypedAggExpr; }): TypedAggExpr; setField(args: { field: TypedAggExpr; input: TypedAggExpr; value: TypedAggExpr; }): TypedAggExpr; }; //#endregion //#region src/state-classes.d.ts /** * Root state of the query-builder state machine. Returned from * `mongoQuery(...).from(name)` and bound to a single collection. * * Inherits the entire pipeline-stage surface from `PipelineChain` (since an * empty `CollectionHandle` is observably an empty pipeline). Adds: * * - `match(...)` — overridden to transition to `FilteredCollection`, which * accumulates filters for eventual splatting into write/find-and-modify * wire commands. * - **Insert / unqualified-write methods** (M2): `insertOne`, `insertMany`, * `updateAll`, `deleteAll`. These live *only* here — the corresponding * methods are absent from `FilteredCollection`, so a caller cannot * accidentally produce an unqualified write by forgetting to `.match(...)` * later in the chain. Bodies land in M2. */ declare class CollectionHandle, ModelName extends keyof MongoModelsMap & string> extends PipelineChain, 'update-cleared', 'fam-cleared', 'leading', ModelNestedShape> { #private; constructor(ctx: BindingContext, modelName: ModelName); /** * Bound model name. Exposed so type tests can assert the binding without * flipping into a pipeline. Not part of the public-API contract. */ get _modelName(): ModelName; /** * Begin accumulating a filter. Transitions to `FilteredCollection`. * * Overrides `PipelineChain.match` (which appends another `$match` stage * and stays in the chain). The two implementations are semantically * equivalent for the read terminal — multiple `$match` stages AND-fold in * Mongo — but `FilteredCollection` makes the accumulated filter * addressable for the write/find-and-modify terminals landing in M2/M3. */ match(filter: MongoFilterExpr): FilteredCollection; match(fn: (fields: FieldAccessor, ModelNestedShape>) => MongoFilterExpr): FilteredCollection; /** * Insert a single document. Document fields are passed straight through to * the wire `InsertOneCommand` — codec normalisation happens at the * adapter/driver boundary, identically to the SQL builder (see Open Item * #14 confirmation in the design conversation). * * Returns a `MongoQueryPlan` whose row stream yields a * single result document with the server-assigned `insertedId`. */ insertOne(document: Record): MongoQueryPlan; /** * Insert a batch of documents. Order is preserved in the returned * `insertedIds` array. */ insertMany(documents: ReadonlyArray>): MongoQueryPlan; /** * Update *every* document in the collection. Lives only on * `CollectionHandle` — the corresponding method is intentionally absent * from `FilteredCollection` so a caller cannot accidentally produce an * unqualified write by forgetting to `.match(...)` first. Pair with * `.match(...).updateMany(...)` for the filtered case. */ updateAll(updaterFn: (fields: FieldAccessor, ModelNestedShape>) => UpdaterResult): MongoQueryPlan; /** * Delete *every* document in the collection. See `updateAll` for the * rationale around the unqualified-write surface being limited to this * state class. */ deleteAll(): MongoQueryPlan; /** * Insert-or-update the document matching `filterFn`. The filter is * mandatory (vs. `updateAll`'s tautological match) because an upsert * without a discriminating predicate would either match every existing * document or insert an indistinguishable new one. * * Maps to `UpdateOneCommand` with `upsert: true`. The driver inserts a * new document derived from the filter equality fields plus the update * spec when no match is found; otherwise updates the matched document. */ upsertOne(filterFn: (fields: FieldAccessor, ModelNestedShape>) => MongoFilterExpr, updaterFn: (fields: FieldAccessor, ModelNestedShape>) => UpdaterResult): MongoQueryPlan; } /** * State reached after one or more `.match(...)` calls on `CollectionHandle`. * * Inherits the pipeline-stage surface from `PipelineChain`, with the * accumulated filters baked in as a leading `$match` stage on the underlying * pipeline state. This means read-terminal output (`.aggregate()` / * `.build()`) and any subsequent pipeline-stage chain see the filtered * collection as input — the read story works through pure inheritance. * * Adds: * * - `match(...)` — pushes another `$match` stage *and* records the filter in * the accumulator, so the eventual write/find-and-modify terminal can * splat the AND-folded filter into the wire command's `filter` slot. * - **Filtered writes** (M2): `updateMany`, `updateOne`, `deleteMany`, * `deleteOne`, `upsertOne`. Stubbed in M1. (Upsert-many is an open * question in the spec — see TML-2267 — and is intentionally absent.) * - **Find-and-modify** (M3): `findOneAndUpdate`, `findOneAndDelete`. * Stubbed in M1. * * Notably *does not* expose `insertOne`/`insertMany`/`updateAll`/`deleteAll` * — those are insert or unqualified-write operations that are nonsense * after a filter has been applied. */ declare class FilteredCollection, ModelName extends keyof MongoModelsMap & string> extends PipelineChain, 'update-cleared', 'fam-cleared', 'leading', ModelNestedShape> { #private; constructor(ctx: BindingContext, modelName: ModelName, filters: ReadonlyArray); get _modelName(): ModelName; /** * Accumulated filter list. Exposed for the M2/M3 write/find-and-modify * terminals to splat into wire-command `filter` slots; not part of the * public-API contract. */ get _filters(): ReadonlyArray; /** * Append another filter to the accumulator. Returns a new * `FilteredCollection` whose underlying pipeline rebuilds the leading * `$match` from the AND-folded accumulator (rather than appending a * second `$match` stage), so the write/find-and-modify terminals see a * single authoritative filter expression. */ match(filter: MongoFilterExpr): FilteredCollection; match(fn: (fields: FieldAccessor, ModelNestedShape>) => MongoFilterExpr): FilteredCollection; /** * Update every matching document. `updaterFn` receives a `FieldAccessor` * and returns an array of `TypedUpdateOp` (e.g. `[f.amount.inc(1), * f.status.set('done')]`). Operators are folded into the wire-format * update spec by `foldUpdateOps`, which throws on operator+path * collisions. */ updateMany(updaterFn: (fields: FieldAccessor, ModelNestedShape>) => UpdaterResult): MongoQueryPlan; /** * Update at most one matching document. The driver picks the document * (typically the first one matched by the underlying scan); no ordering * guarantee is implied — chain `.sort(...)` and use the M3 * `.findOneAndUpdate(...)` terminal when ordering matters. */ updateOne(updaterFn: (fields: FieldAccessor, ModelNestedShape>) => UpdaterResult): MongoQueryPlan; /** * Delete every matching document. */ deleteMany(): MongoQueryPlan; /** * Delete at most one matching document. See the `updateOne` note about * driver-chosen victim selection. */ deleteOne(): MongoQueryPlan; /** * Insert-or-update against the accumulated filter. Maps to * `UpdateOneCommand` with `upsert: true`. Equivalent to * `CollectionHandle.upsertOne(f => filter, updaterFn)` but reuses the * already-accumulated `.match(...)` filter chain. */ upsertOne(updaterFn: (fields: FieldAccessor, ModelNestedShape>) => UpdaterResult): MongoQueryPlan; /** * Find a single matching document and apply `updaterFn` to it. * * `opts.upsert` (default `false`) toggles insert-on-miss behaviour. * `opts.returnDocument` (default `'after'`) controls whether the row * stream yields the document as it was before or after the update. */ findOneAndUpdate(updaterFn: (fields: FieldAccessor, ModelNestedShape>) => UpdaterResult, opts?: { readonly upsert?: boolean; readonly returnDocument?: 'before' | 'after'; }): MongoQueryPlan, ExtractMongoCodecTypes, TContract> | null, FindOneAndUpdateCommand>; /** * Find a single matching document and delete it. Returns the deleted * document via the row stream. */ findOneAndDelete(): MongoQueryPlan, ExtractMongoCodecTypes, TContract> | null, FindOneAndDeleteCommand>; } /** * Bound execution context shared across the three state classes. */ interface BindingContext> { readonly contract: TContract; readonly collection: string; readonly storageHash: string; } //#endregion //#region src/query.d.ts /** * Public entry point of the query builder. `mongoQuery(...).from(rootName)` * yields the root state of the three-state machine * (`CollectionHandle` → `FilteredCollection` → `PipelineChain`). * * `rawCommand(cmd)` is the escape hatch for cases the typed surface does * not cover (yet) — it accepts any `AnyMongoCommand` (typed CRUD or a * `RawMongoCommand` of `Document`s) and packages it into a `MongoQueryPlan` * with `lane: 'mongo-query'`. Row type is `unknown` because the runtime * cannot know what the caller's command yields. */ interface QueryRoot> { from(rootName: K): CollectionHandle>; rawCommand(command: C): MongoQueryPlan; } declare function mongoQuery>(options: { contractJson: unknown; }): QueryRoot; //#endregion //#region src/result-shape.d.ts declare function contractFieldToMongoFieldShape(field: ContractField): MongoFieldShape; declare function contractModelToMongoResultShape(model: MongoModelDefinition, options?: { readonly selection?: readonly string[]; readonly includeRelationNames?: readonly string[]; }): MongoResultShape; //#endregion export { type ArrayField, type BooleanField, CollectionHandle, type DateField, type DeleteResult, type DocField, type DocShape, type Expression, type ExtractDocShape, type FieldAccessor, FilteredCollection, type FindAndModifyEnabled, type GroupSpec, type GroupedDocShape, type InsertManyResult, type InsertOneResult, type LeafExpression, type LiteralValue, type LookupBuilder, type LookupBuilderWithKey, type LookupFrom, type LookupOnResult, type LookupResult, type ModelArrayField, type ModelNestedShape, type ModelOf, type ModelToDocShape, type NestedDocShape, type NullableDocField, type NullableNumericField, type NumericField, type ObjectExpression, type ObjectField, type PathCompletions, PipelineChain, type ProjectedShape, type QueryRoot, type ResolvePath, type ResolveRow, type SortSpec, type StringField, type TypedAccumulatorExpr, type TypedAggExpr, type TypedUpdateOp, type UnwoundShape, type UpdateEnabled, type UpdateResult, type UpdaterResult, type ValidPaths, acc, contractFieldToMongoFieldShape, contractModelToMongoResultShape, createFieldAccessor, expr, fn, mongoQuery }; //# sourceMappingURL=index.d.mts.map