sluice-orm 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.txt +373 -0
- package/README.md +191 -0
- package/dist/index.cjs +977 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +2444 -0
- package/dist/index.d.ts +2444 -0
- package/dist/index.js +911 -0
- package/dist/index.js.map +1 -0
- package/package.json +86 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/accumulator-utils.ts","../src/builder.ts","../src/migrate.ts","../src/runtime-utils.ts","../src/sluice-stages.ts","../src/crud/updates/stages/index.ts","../src/registry.ts"],"sourcesContent":["// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\nexport const functionToString = (fn: Function): string => {\n const fnStr = fn.toString();\n\n if (!fnStr.includes(\"=>\")) return fnStr;\n\n // Handles: (x, y) => ..., x => ..., (x) => ...\n const paramMatch = /^(?:\\(([^)]*)\\)|(\\w+))\\s*=>/.exec(fnStr);\n if (!paramMatch) throw new Error(`Cannot parse arrow function parameters: ${fnStr}`);\n\n const params = paramMatch[1] ?? paramMatch[2];\n\n const arrowIndex = fnStr.indexOf(\"=>\");\n const body = fnStr.slice(arrowIndex + 2).trim();\n\n // Check if body is wrapped in braces or is an expression\n const hasBlock = body.startsWith(\"{\");\n return hasBlock ? `function(${params}) ${body}` : `function(${params}) { return ${body}; }`;\n};\n\nexport type TypedAccumulator<\n InitFn extends (...args: any[]) => any,\n AccArgs extends readonly unknown[],\n Result = ReturnType<InitFn>,\n> = {\n init: InitFn;\n initArgs: Parameters<InitFn>;\n accumulate: (state: ReturnType<InitFn>, ...args: [...AccArgs]) => ReturnType<InitFn>;\n accumulateArgs: Readonly<{ [K in keyof AccArgs]: string }>;\n merge: (state1: ReturnType<InitFn>, state2: ReturnType<InitFn>) => ReturnType<InitFn>;\n finalize?: (state: ReturnType<InitFn>) => Result;\n lang: \"js\";\n};\n\nexport const resolveAccumulator = <\n InitFn extends (...args: any[]) => any,\n AccArgs extends readonly unknown[],\n Result,\n>(\n config: TypedAccumulator<InitFn, AccArgs, Result>,\n) => {\n const result = {\n init: functionToString(config.init),\n initArgs: config.initArgs,\n accumulate: functionToString(config.accumulate),\n accumulateArgs: config.accumulateArgs,\n merge: functionToString(config.merge),\n lang: config.lang,\n };\n\n return config.finalize ? { ...result, finalize: functionToString(config.finalize) } : result;\n};\n","/* eslint-disable @typescript-eslint/unified-signatures */\nimport { type Decimal128, ObjectId } from \"mongodb\";\n\nimport { resolveAccumulator, type TypedAccumulator } from \"./accumulator-utils.js\";\nimport type { PathType } from \"./paths.js\";\nimport type { PipelineBuilder } from \"./pipeline-types.js\";\n// Type imports for proper operator typing\nimport type {\n AccumulatorArgInput,\n AccumulatorArgInputs,\n AccumulatorExprArg,\n ArrayArg,\n ArrayArgInput,\n ArrayIn,\n BooleanArg,\n BooleanArgInput,\n CallbackOnlyError,\n DateArg,\n DateArgInput,\n DeepSpecInput,\n DeepSpecResolve,\n ElemType,\n ExprArg,\n ExprArgInput,\n ExprArgInputs,\n NumericArg,\n NumericArgInput,\n ResolveType,\n StringArg,\n StringArgInput,\n TimeUnit,\n ValidMatchFilterWithBuilder,\n WindowSpec,\n} from \"./sluice.js\";\nimport type {\n Dict,\n MergeWithIndexOverride,\n ShallowMergeObjectsOverride,\n SimplifyWritable,\n} from \"./type-utils.js\";\n\ntype Stage = Dict<unknown>;\ntype RuntimeAgg = { stages?: Stage[] } & Dict<unknown>;\n\ntype BuilderMode = \"expression\" | \"accumulator\";\n\n// ==========================================\n// Helper Types for Proper Return Typing\n// ==========================================\n\n// Map ResolveType over a tuple\ntype ResolveTypes<C, T extends unknown[]> = { [K in keyof T]: ResolveType<C, T[K]> };\n\ntype DeepObjectExpr<C> =\n | ExprArg<C>\n | { [K in string]: DeepObjectExpr<C> }\n | readonly DeepObjectExpr<C>[];\n\ntype DeepObjectInput<C, T> =\n T extends ExprArg<C> ? ExprArgInput<C, T>\n : T extends readonly (infer E)[] ? readonly DeepObjectInput<C, E>[]\n : T extends object ? { [K in keyof T]: DeepObjectInput<C, T[K]> }\n : T;\n\ntype DeepObjectResolve<C, T> =\n T extends Ret<any, infer R> ? R\n : T extends ExprArg<C> ? ResolveType<C, T>\n : T extends readonly (infer E)[] ? DeepObjectResolve<C, E>[]\n : T extends object ? { [K in keyof T]: DeepObjectResolve<C, T[K]> }\n : T;\n\n// Extract object type from arrayToObject input: {k: K, v: V}[] => Record<K, V>\n// Use [K] extends [string] to prevent distributive conditional type over union K\ntype ArrayToObjectResult<Elem> =\n Elem extends { k: infer K; v: infer V } ?\n [K] extends [string] ?\n Record<K, V>\n : Dict<unknown>\n : Dict<unknown>;\n\n// ==========================================\n// DRY Operator Type Patterns\n// ==========================================\n\n// Unary operators: single argument in, specific type out\ntype UnaryNumericOp<C> = <const T extends NumericArg<C>>(\n arg: T & NumericArgInput<C, T>,\n) => Ret<C, number>;\n\ntype BinaryNumericOp<C> = <const L extends NumericArg<C>, const R extends NumericArg<C>>(\n left: L & NumericArgInput<C, L>,\n right: R & NumericArgInput<C, R>,\n) => Ret<C, number>;\n\ntype UnaryStringToNumber<C> = <const T extends StringArg<C>>(\n exp: StringArgInput<C, T>,\n) => Ret<C, number>;\n\ntype UnaryStringToString<C> = <const T extends StringArg<C>>(\n exp: StringArgInput<C, T>,\n) => Ret<C, string>;\n\ntype BinaryStringToNumber<C> = <const L extends StringArg<C>, const R extends StringArg<C>>(\n left: StringArgInput<C, L>,\n right: StringArgInput<C, R>,\n) => Ret<C, -1 | 0 | 1>;\n\ntype UnaryDateToNumber<C> = <const T extends DateArg<C>>(\n exp: T & DateArgInput<C, T>,\n) => Ret<C, number>;\n\ntype UnaryArrayToBool<C> = <const T extends ArrayArg<C>>(\n exp: T & ArrayArgInput<C, T>,\n) => Ret<C, boolean>;\n\ntype UnaryTypeConversion<C, Output> = <const T extends ExprArg<C>>(\n exp: ExprArgInput<C, T>,\n) => Ret<C, NullishResult<C, T, Output>>;\n\ntype HasNullish<T> = [Extract<T, null | undefined>] extends [never] ? false : true;\ntype NullishResult<C, T, Output> =\n HasNullish<ResolveType<C, T>> extends true ? Output | null : Output;\ntype NullishResultFromArgs<C, T extends readonly ExprArg<C>[], Output> =\n HasNullish<ResolveType<C, T[number]>> extends true ? Output | null : Output;\n\ntype ConvertTo = \"double\" | \"string\" | \"objectId\" | \"bool\" | \"date\" | \"int\" | \"long\" | \"decimal\";\n\ntype ConvertOutput<To extends ConvertTo> =\n To extends \"double\" | \"int\" ? number\n : To extends \"long\" ? number\n : To extends \"decimal\" ? Decimal128\n : To extends \"string\" ? string\n : To extends \"bool\" ? boolean\n : To extends \"objectId\" ? ObjectId\n : Date;\n\ntype BinaryArrayOp<C> = <const A extends ArrayArg<C>, const B extends ArrayArg<C>>(\n left: A & ArrayArgInput<C, A>,\n right: B & ArrayArgInput<C, B>,\n) => Ret<C, boolean>;\n\ntype UnaryArrayToNumber<C> = <const T extends ArrayArg<C>>(\n exp: T & ArrayArgInput<C, T>,\n) => Ret<C, number>;\n\n// Comparison operator type (complex pattern shared by eq, gt, gte, lt, lte, ne)\ntype ComparisonOp<C> = <\n const L extends ExprArg<C>,\n const R extends CompatibleArg<C, ResolveType<C, L>>,\n>(\n left: L extends `$${infer Rest}` ?\n Rest extends `$${string}` ? L\n : L extends AnyPathFieldRef<C> ? L\n : never\n : L,\n right: R extends `$${infer Rest}` ?\n Rest extends `$${string}` ? R\n : ResolveType<C, R> extends ResolveType<C, L> ? R\n : never\n : R,\n) => Ret<C, boolean>;\n\n// Varargs operators\ntype VarargsBooleanOp<C> = <const T extends BooleanArg<C>[]>(\n ...args: { [K in keyof T]: T[K] & BooleanArgInput<C, T[K]> }\n) => Ret<C, boolean>;\n\ntype VarargsNumericOp<C> = <const T extends NumericArg<C>[]>(\n ...args: T extends readonly NumericArg<C>[] ? T : never\n) => Ret<C, number>;\n\ntype NumericArgs<C> = readonly [NumericArg<C>, NumericArg<C>, ...NumericArg<C>[]];\ntype NumericArgsInput<C, T extends readonly NumericArg<C>[]> = {\n [K in keyof T]: NumericArgInput<C, T[K]>;\n};\ntype AddOp<C> = {\n <const T extends NumericArgs<C>>(...args: NumericArgsInput<C, T>): Ret<C, number>;\n <const D extends DateArg<C>, const T extends readonly [NumericArg<C>, ...NumericArg<C>[]]>(\n date: DateArgInput<C, D>,\n ...args: NumericArgsInput<C, T>\n ): Ret<C, Date>;\n <const T extends readonly [NumericArg<C>, ...NumericArg<C>[]], const D extends DateArg<C>>(\n ...args: [...NumericArgsInput<C, T>, DateArgInput<C, D>]\n ): Ret<C, Date>;\n};\n\ntype SubtractOp<C> = {\n <const L extends DateArg<C>, const R extends DateArg<C>>(\n left: DateArgInput<C, L>,\n right: DateArgInput<C, R>,\n ): Ret<C, number>;\n <const L extends DateArg<C>, const R extends NumericArg<C>>(\n left: DateArgInput<C, L>,\n right: NumericArgInput<C, R>,\n ): Ret<C, Date>;\n <const L extends NumericArg<C>, const R extends NumericArg<C>>(\n left: NumericArgInput<C, L>,\n right: NumericArgInput<C, R>,\n ): Ret<C, number>;\n};\n\ntype SortPath<C> = PathType<C> | `_id.${string}`;\ntype SortBySpec<C> =\n | Partial<Record<SortPath<C>, 1 | -1>>\n | { $meta: \"textScore\" | \"searchScore\" }\n | (Partial<Record<SortPath<C>, 1 | -1>> & { $meta: \"textScore\" | \"searchScore\" });\n\ntype ArrayLiteral<C> = readonly ExprArg<C>[] | ExprArg<C>[];\n\n// Get first non-nil type from tuple (for ifNull)\ntype FirstNotNil<T extends unknown[]> =\n T extends [infer First, ...infer Rest] ?\n First extends null | undefined ?\n FirstNotNil<Rest>\n : First\n : never;\n\n// Detect if a type has a string index signature\ntype MergeTwo<A, B> =\n [A] extends [null | undefined] ? B\n : [B] extends [null | undefined] ? A\n : MergeWithIndexOverride<A, B>;\n\n// Merge multiple objects (for mergeObjects varargs)\ntype MergeObjects<C, Objs extends unknown[], Acc = null> =\n Objs extends [infer First, ...infer Rest] ?\n MergeObjects<C, Rest, MergeTwo<ResolveType<C, First>, Acc>>\n : Acc;\n\ntype MergeVars<C, Vars extends Dict<unknown>> =\n C extends { $vars: infer Existing extends Dict<unknown> } ?\n SimplifyWritable<Omit<C, \"$vars\"> & { $vars: SimplifyWritable<Existing & Vars> }>\n : SimplifyWritable<C & { $vars: Vars }>;\n\ntype ResolveVarSpec<C, V extends Dict<ExprArg<C>>> = {\n [K in keyof V]: ResolveType<C, V[K]>;\n};\n\n// Augmented contexts for array iterators (map, filter, reduce)\ntype ContextWithThis<C, ThisType, As extends string | undefined = undefined> =\n As extends string ? MergeVars<SimplifyWritable<C & { $this: ThisType }>, Record<As, ThisType>>\n : SimplifyWritable<C & { $this: ThisType }>;\ntype ContextWithThisAndValue<C, ThisType, ValueType> = SimplifyWritable<\n C & { $this: ThisType; $value: ValueType }\n>;\n\n// Concatenate string literal types\ntype ConcatStrings<T extends readonly unknown[]> =\n T extends readonly [infer First, ...infer Rest] ?\n First extends string ?\n Rest extends readonly string[] ?\n `${First}${ConcatStrings<Rest>}`\n : string\n : string\n : \"\";\n\n// Compatible argument type for comparison operators\ntype CompatibleArg<C, T> =\n [T] extends [unknown] ?\n [unknown] extends [T] ?\n ExprArg<C>\n : CompatibleArgKnown<C, T>\n : CompatibleArgKnown<C, T>;\n\ntype CompatibleArgKnown<C, T> =\n | Ret<C, T>\n | `$$${string}`\n | (T extends boolean ? BooleanArg<C>\n : T extends number ? NumericArg<C>\n : T extends string ? `$${string}` | Ret<C, string> | `$$${string}`\n : T extends Date ? DateArg<C>\n : never)\n | (T extends boolean ? boolean\n : T extends number ? number\n : T extends string ? string & {}\n : T extends Date ? Date\n : T extends null | undefined ? null | undefined\n : never)\n | (T extends (infer E)[] ? CompatibleArg<C, E> | ArrayArg<C> : never);\n\n// Generic path field ref\ntype AnyPathFieldRef<C> = `$${string}`;\n\nexport type RuntimeValue =\n | number\n | string\n | boolean\n | null\n | undefined\n | Date\n | ObjectId\n | RegExp\n | Ret<never, RuntimeValue>\n | readonly RuntimeValue[]\n | Readonly<{ [key: string]: RuntimeValue }>;\n\n// Ret as a class for instanceof support\nexport class Ret<out Context = unknown, T = unknown> {\n readonly __context!: Context;\n readonly __type!: SimplifyWritable<T>;\n readonly __tag = \"Ret\" as const;\n\n constructor(\n readonly __fn: unknown,\n readonly __minVersion = \"\",\n ) {}\n}\n\ntype AnyRet = Ret<never, never>;\n\nexport class BaseBuilder<C, Mode extends BuilderMode = \"expression\"> {\n // Helper to resolve nested callbacks and values\n _resolve(value: unknown): unknown {\n const _foo = value as RuntimeValue | ((builder: BaseBuilder<C>) => unknown);\n if (_foo instanceof Ret) return this._resolve(_foo.__fn);\n if (typeof _foo === \"function\") return this._resolve(_foo(this));\n if (Array.isArray(_foo)) return _foo.map(item => this._resolve(item));\n if (_foo instanceof Date) return _foo;\n if (_foo instanceof ObjectId) return _foo;\n if (_foo instanceof RegExp) return _foo;\n if (typeof _foo !== \"object\" || _foo === null) return _foo;\n\n return Object.entries(_foo).reduce((acc, [k, v]) => ({ ...acc, [k]: this._resolve(v) }), {});\n }\n\n // Identity: single argument passed through\n protected id =\n (op: string) =>\n (arg: unknown): AnyRet =>\n new Ret({ [`$${op}`]: this._resolve(arg) });\n\n // Varargs: multiple arguments as array\n protected varargs =\n (op: string) =>\n (...args: unknown[]): AnyRet =>\n new Ret({ [`$${op}`]: args.map(arg => this._resolve(arg)) });\n\n // Flexible: 1 arg -> raw value, >1 args -> array (for operators that are both unary accumulators and variadic expressions)\n protected flexible =\n (op: string) =>\n (...args: unknown[]): AnyRet =>\n new Ret({\n [`$${op}`]: args.length === 1 ? this._resolve(args[0]) : args.map(this._resolve.bind(this)),\n });\n\n // Options: single object argument\n protected options =\n (op: string) =>\n (options: unknown): AnyRet =>\n new Ret({ [`$${op}`]: this._resolve(options) });\n\n // Nullary: no arguments\n protected nullary = (op: string) => (): AnyRet => new Ret({ [`$${op}`]: {} });\n\n // Pipeline builder for $facet and sub-pipelines\n pipe: PipelineBuilder<C> = ((...stages: ((agg: RuntimeAgg) => RuntimeAgg)[]) =>\n stages.reduce((agg: RuntimeAgg, stageFn) => stageFn(agg), {\n stages: [],\n })) as unknown as PipelineBuilder<C>;\n\n // Query helper for $match array element filters\n elemMatch = <const E>(filter: ($: ExprBuilder<E>) => ValidMatchFilterWithBuilder<E>) => ({\n $elemMatch: filter(new ExprBuilder<E>()),\n });\n\n // ==========================================\n // Arithmetic Operators\n // ==========================================\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/add/\n add: AddOp<C> = this.varargs(\"add\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/subtract/\n subtract: SubtractOp<C> = this.varargs(\"subtract\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/multiply/\n multiply: VarargsNumericOp<C> = this.varargs(\"multiply\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/divide/\n divide: BinaryNumericOp<C> = this.varargs(\"divide\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/mod/\n mod: BinaryNumericOp<C> = this.varargs(\"mod\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/abs/\n abs: UnaryNumericOp<C> = this.id(\"abs\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/ceil/\n ceil: UnaryNumericOp<C> = this.id(\"ceil\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/floor/\n floor: UnaryNumericOp<C> = this.id(\"floor\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/ln/\n ln: UnaryNumericOp<C> = this.id(\"ln\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/log/\n log: BinaryNumericOp<C> = this.varargs(\"log\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/log10/\n log10: UnaryNumericOp<C> = this.id(\"log10\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/pow/\n pow: BinaryNumericOp<C> = this.varargs(\"pow\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/sqrt/\n sqrt: UnaryNumericOp<C> = this.id(\"sqrt\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/trunc/\n trunc: <const T extends NumericArg<C>, const P extends NumericArg<C>>(\n num: T & NumericArgInput<C, T>,\n place?: P & NumericArgInput<C, P>,\n ) => Ret<C, number> = (num, place) =>\n place !== undefined ? this.varargs(\"trunc\")(num, place) : this.options(\"trunc\")(num);\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/round/\n round: <const T extends NumericArg<C>, const P extends NumericArg<C>>(\n num: T & NumericArgInput<C, T>,\n place?: P & NumericArgInput<C, P>,\n ) => Ret<C, number> = (num, place) =>\n place !== undefined ? this.varargs(\"round\")(num, place) : this.options(\"round\")(num);\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/exp/\n exp: UnaryNumericOp<C> = this.id(\"exp\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/rand/\n rand: () => Ret<C, number> = this.nullary(\"rand\");\n\n // ==========================================\n // Array Operators\n // ==========================================\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/arrayElemAt/\n arrayElemAt: <const A extends ArrayArg<C>, const I extends NumericArg<C>>(\n array: A & ArrayArgInput<C, A>,\n index: I & NumericArgInput<C, I>,\n ) => Ret<C, ElemType<ResolveType<C, A>>> = this.varargs(\"arrayElemAt\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/arrayToObject/\n arrayToObject: <const T extends ArrayArg<C>>(\n exp: T & ArrayArgInput<C, T>,\n ) => Ret<C, ArrayToObjectResult<ElemType<ResolveType<C, T>>>> = this.id(\"arrayToObject\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/concatArrays/\n concatArrays: <const T extends ArrayArg<C>[]>(\n ...args: { [K in keyof T]: T[K] & ArrayArgInput<C, T[K]> }\n ) => Ret<C, ElemType<ResolveType<C, T[number]>>[]> = this.varargs(\"concatArrays\");\n\n /** Selects a subset of array elements that match a condition.\n * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/filter/ */\n filter: {\n <\n const I extends ArrayArg<C>,\n const As extends string | undefined = undefined,\n const L extends NumericArg<C> = NumericArg<C>,\n >(options: {\n input: I & ArrayArgInput<C, I>;\n cond: (\n $: BaseBuilder<ContextWithThis<C, ElemType<ResolveType<C, I>>, As>>,\n ) => BooleanArg<ContextWithThis<C, ElemType<ResolveType<C, I>>, As>>;\n as?: As;\n limit?: L & NumericArgInput<C, L>;\n }): Ret<C, ResolveType<C, I>>;\n <\n const I extends ArrayArg<C>,\n const As extends string | undefined = undefined,\n const B extends BooleanArg<ContextWithThis<C, ElemType<ResolveType<C, I>>, As>> = BooleanArg<\n ContextWithThis<C, ElemType<ResolveType<C, I>>, As>\n >,\n const L extends NumericArg<C> = NumericArg<C>,\n >(options: {\n input: I & ArrayArgInput<C, I>;\n cond: B;\n as?: As;\n limit?: L & NumericArgInput<C, L>;\n }): Ret<C, CallbackOnlyError<\"filter\">>;\n } = this.options(\"filter\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/first/\n first: <const T extends AccumulatorExprArg<C>>(\n exp: AccumulatorArgInput<C, T>,\n ) => Ret<\n C,\n Mode extends \"accumulator\" ? ResolveType<C, T>\n : ResolveType<C, T> extends readonly (infer E)[] ? E | null\n : ResolveType<C, T> | null\n > = this.id(\"first\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/in/\n in: <const V extends ExprArg<C>, const A extends ArrayArg<C>>(\n value: ExprArgInput<C, V>,\n array: A & ArrayArgInput<C, A>,\n ) => Ret<C, boolean> = this.varargs(\"in\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/indexOfArray/\n indexOfArray: <\n const A extends ArrayArg<C>,\n const S extends ExprArg<C>,\n const N extends NumericArg<C>,\n >(options: {\n array: A & ArrayArgInput<C, A>;\n search: ExprArgInput<C, S>;\n start?: N & NumericArgInput<C, N>;\n end?: N & NumericArgInput<C, N>;\n }) => Ret<C, number> = this.options(\"indexOfArray\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/isArray/\n isArray: <const T extends ExprArg<C>>(exp: ExprArgInput<C, T>) => Ret<C, boolean> =\n this.id(\"isArray\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/last/\n last: <const T extends AccumulatorExprArg<C>>(\n exp: AccumulatorArgInput<C, T>,\n ) => Ret<\n C,\n Mode extends \"accumulator\" ? ResolveType<C, T>\n : ResolveType<C, T> extends readonly (infer E)[] ? E | null\n : ResolveType<C, T> | null\n > = this.id(\"last\");\n\n /** Applies an expression to each element of an array and returns the results.\n * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/map/ */\n map: {\n <\n const A extends ArrayArg<C>,\n const As extends string | undefined = undefined,\n const R extends DeepObjectExpr<ContextWithThis<C, ElemType<ResolveType<C, A>>, As>> =\n DeepObjectExpr<ContextWithThis<C, ElemType<ResolveType<C, A>>, As>>,\n >(options: {\n input: A & ArrayArgInput<C, A>;\n as?: As;\n in: ($: BaseBuilder<ContextWithThis<C, ElemType<ResolveType<C, A>>, As>>) => R;\n }): Ret<C, DeepObjectResolve<ContextWithThis<C, ElemType<ResolveType<C, A>>, As>, R>[]>;\n <\n const A extends ArrayArg<C>,\n const As extends string | undefined = undefined,\n const R extends DeepObjectExpr<ContextWithThis<C, ElemType<ResolveType<C, A>>, As>> =\n DeepObjectExpr<ContextWithThis<C, ElemType<ResolveType<C, A>>, As>>,\n >(options: {\n input: A & ArrayArgInput<C, A>;\n as?: As;\n in: DeepObjectInput<ContextWithThis<C, ElemType<ResolveType<C, A>>, As>, R>;\n }): Ret<C, DeepObjectResolve<ContextWithThis<C, ElemType<ResolveType<C, A>>, As>, R>[]>;\n } = this.options(\"map\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/maxN/\n maxN: <const T extends ArrayArg<C>, const N extends NumericArg<C>>(options: {\n input: T & ArrayArgInput<C, T>;\n n: N & NumericArgInput<C, N>;\n }) => Ret<C, Mode extends \"accumulator\" ? ResolveType<C, T>[] : ResolveType<C, T>> =\n this.options(\"maxN\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/minN/\n minN: <const T extends ArrayArg<C>, const N extends NumericArg<C>>(options: {\n input: T & ArrayArgInput<C, T>;\n n: N & NumericArgInput<C, N>;\n }) => Ret<C, Mode extends \"accumulator\" ? ResolveType<C, T>[] : ResolveType<C, T>> =\n this.options(\"minN\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/firstN/\n firstN: <const T extends ArrayArg<C>, const N extends NumericArg<C>>(options: {\n input: T & ArrayArgInput<C, T>;\n n: N & NumericArgInput<C, N>;\n }) => Ret<C, Mode extends \"accumulator\" ? ResolveType<C, T>[] : ResolveType<C, T>> =\n this.options(\"firstN\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/lastN/\n lastN: <const T extends ArrayArg<C>, const N extends NumericArg<C>>(options: {\n input: T & ArrayArgInput<C, T>;\n n: N & NumericArgInput<C, N>;\n }) => Ret<C, Mode extends \"accumulator\" ? ResolveType<C, T>[] : ResolveType<C, T>> =\n this.options(\"lastN\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/objectToArray/\n objectToArray: <const T extends ExprArg<C>>(\n expression: ExprArgInput<C, T>,\n ) => Ret<C, { k: string; v: ResolveType<C, T> extends Dict<infer V> ? V : unknown }[]> =\n this.id(\"objectToArray\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/range/\n range: <\n const S extends NumericArg<C>,\n const E extends NumericArg<C>,\n const St extends NumericArg<C> = never,\n >(\n start: S & NumericArgInput<C, S>,\n end: E & NumericArgInput<C, E>,\n step?: St & NumericArgInput<C, St>,\n ) => Ret<C, number[]> = (start, end, step) =>\n step !== undefined ?\n this.varargs(\"range\")(start, end, step)\n : this.varargs(\"range\")(start, end);\n\n /** Applies an expression to each element of an array, accumulating into a single value.\n * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/reduce/ */\n reduce: {\n <\n const A extends ArrayArg<C>,\n const Init extends ExprArg<C> | ArrayIn<C>,\n const R extends Exclude<\n ExprArg<ContextWithThisAndValue<C, ElemType<ResolveType<C, A>>, ResolveType<C, Init>>>,\n string\n >,\n >(options: {\n input: A & ArrayArgInput<C, A>;\n initialValue: Init;\n in: (\n $: BaseBuilder<\n ContextWithThisAndValue<C, ElemType<ResolveType<C, A>>, ResolveType<C, Init>>\n >,\n ) => R;\n }): Ret<\n C,\n ResolveType<ContextWithThisAndValue<C, ElemType<ResolveType<C, A>>, ResolveType<C, Init>>, R>\n >;\n <const A extends ArrayArg<C>, const Init extends ExprArg<C> | ArrayIn<C>, const R>(options: {\n input: A & ArrayArgInput<C, A>;\n initialValue: Init;\n in: R;\n }): Ret<C, CallbackOnlyError<\"reduce\">>;\n } = this.options(\"reduce\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/reverseArray/\n reverseArray: <const T extends ArrayArg<C>>(\n exp: T & ArrayArgInput<C, T>,\n ) => Ret<C, ResolveType<C, T>> = this.id(\"reverseArray\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/size/\n size: UnaryArrayToNumber<C> = this.id(\"size\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/slice/\n slice: <const A extends ArrayArg<C>, const N extends NumericArg<C>>(\n array: A & ArrayArgInput<C, A>,\n n: N & NumericArgInput<C, N>,\n position?: N & NumericArgInput<C, N>,\n ) => Ret<C, ResolveType<C, A>> = (array, n, position) =>\n position !== undefined ?\n this.varargs(\"slice\")(array, n, position)\n : this.varargs(\"slice\")(array, n);\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/sortArray/\n sortArray: <const T extends { input: ArrayArg<C>; sortBy: Dict<1 | -1> | 1 | -1 }>(\n options: T & { input: T[\"input\"] & ArrayArgInput<C, T[\"input\"]> },\n ) => Ret<C, ResolveType<C, T[\"input\"]>> = this.options(\"sortArray\");\n // zip with proper tuple typing\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/zip/\n zip: {\n <const T extends readonly ArrayArg<C>[]>(options: {\n inputs: readonly [...T];\n useLongestLength: true;\n defaults: Readonly<{ [K in keyof T]: ElemType<ResolveType<C, T[K]>> }>;\n }): Ret<C, { -readonly [K in keyof T]: ElemType<ResolveType<C, T[K]>> }[]>;\n <const T extends readonly ArrayArg<C>[]>(options: {\n inputs: readonly [...T];\n useLongestLength: true;\n defaults?: Readonly<{ [K in keyof T]?: ElemType<ResolveType<C, T[K]>> }>;\n }): Ret<C, { -readonly [K in keyof T]: ElemType<ResolveType<C, T[K]>> | null }[]>;\n <const T extends readonly ArrayArg<C>[]>(options: {\n inputs: readonly [...T];\n useLongestLength?: false;\n defaults?: never;\n }): Ret<C, { -readonly [K in keyof T]: ElemType<ResolveType<C, T[K]>> }[]>;\n } = this.options(\"zip\");\n\n // ==========================================\n // Comparison Operators\n // ==========================================\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/cmp/\n cmp: <const T extends ExprArg<C>>(\n left: ExprArgInput<C, T>,\n right: ExprArgInput<C, T>,\n ) => Ret<C, -1 | 0 | 1> = this.varargs(\"cmp\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/eq/\n eq: ComparisonOp<C> = this.varargs(\"eq\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/gt/\n gt: ComparisonOp<C> = this.varargs(\"gt\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/gte/\n gte: ComparisonOp<C> = this.varargs(\"gte\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/lt/\n lt: ComparisonOp<C> = this.varargs(\"lt\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/lte/\n lte: ComparisonOp<C> = this.varargs(\"lte\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/ne/\n ne: ComparisonOp<C> = this.varargs(\"ne\");\n\n // Boolean operators (fully typed from ExprBuilder)\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/and/\n and: VarargsBooleanOp<C> = this.varargs(\"and\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/or/\n or: VarargsBooleanOp<C> = this.varargs(\"or\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/nor/\n nor: VarargsBooleanOp<C> = this.varargs(\"nor\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/not/\n not: <const T extends ExprArg<C>>(exp: ExprArgInput<C, T>) => Ret<C, boolean> = this.id(\"not\");\n\n // Conditional operators (fully typed from ExprBuilder)\n /** Evaluates a boolean expression and returns one of two values.\n * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/cond/ */\n cond: <\n const B extends BooleanArg<C>,\n const T extends ExprArg<C>,\n const E extends ExprArg<C>,\n >(options: {\n if: B & BooleanArgInput<C, B>;\n then: T & ExprArgInput<C, T>;\n else: E & ExprArgInput<C, E>;\n }) => Ret<C, ResolveType<C, T> | ResolveType<C, E>> = this.options(\"cond\");\n\n /** Returns the first non-null/non-missing expression (null coalescing).\n * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/ifNull/ */\n ifNull: <const T extends ExprArg<C>[]>(\n ...args: { [K in keyof T]: T[K] & ExprArgInput<C, T[K]> }\n ) => Ret<C, FirstNotNil<ResolveTypes<C, T>>> = this.varargs(\"ifNull\");\n\n /** Evaluates a series of case expressions, returning the value of the first match.\n * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/switch/ */\n switch: <\n const Br extends readonly { case: BooleanArg<C>; then: ExprArg<C> }[],\n const D extends ExprArg<C>,\n >(options: {\n branches: Br;\n default: D;\n }) => Ret<C, ResolveType<C, Br[number][\"then\"]> | ResolveType<C, D>> = this.options(\"switch\");\n\n // String operators (fully typed from ExprBuilder)\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/concat/\n concat: <const T extends StringArg<C>[]>(\n ...args: { [K in keyof T]: StringArgInput<C, T[K]> }\n ) => Ret<C, ConcatStrings<{ [K in keyof T]: ResolveType<C, T[K]> }>> = this.varargs(\"concat\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/indexOfBytes/\n indexOfBytes: <\n const S extends StringArg<C>,\n const Sub extends StringArg<C>,\n const N extends NumericArg<C>,\n >(\n string: StringArgInput<C, S>,\n substring: StringArgInput<C, Sub>,\n start?: N & NumericArgInput<C, N>,\n end?: N & NumericArgInput<C, N>,\n ) => Ret<C, number> = (string, substring, start, end) => {\n const args: unknown[] = [string, substring];\n if (start !== undefined) args.push(start);\n if (end !== undefined) args.push(end);\n return this.varargs(\"indexOfBytes\")(...args);\n };\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/indexOfCP/\n indexOfCP: <\n const S extends StringArg<C>,\n const Sub extends StringArg<C>,\n const N extends NumericArg<C>,\n >(\n string: StringArgInput<C, S>,\n substring: StringArgInput<C, Sub>,\n start?: N & NumericArgInput<C, N>,\n end?: N & NumericArgInput<C, N>,\n ) => Ret<C, number> = (string, substring, start, end) => {\n const args: unknown[] = [string, substring];\n if (start !== undefined) args.push(start);\n if (end !== undefined) args.push(end);\n return this.varargs(\"indexOfCP\")(...args);\n };\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/ltrim/\n ltrim: <const T extends StringArg<C>>(options: {\n input: StringArgInput<C, T>;\n chars?: StringArgInput<C, StringArg<C>>;\n }) => Ret<C, string> = this.options(\"ltrim\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/regexFind/\n regexFind: <const T extends StringArg<C>>(options: {\n input: StringArgInput<C, T>;\n regex: StringArgInput<C, StringArg<C>> | RegExp;\n options?: StringArgInput<C, StringArg<C>>;\n }) => Ret<C, { match: string; idx: number; captures: string[] } | null> =\n this.options(\"regexFind\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/regexFindAll/\n regexFindAll: <const T extends StringArg<C>>(options: {\n input: StringArgInput<C, T>;\n regex: StringArgInput<C, StringArg<C>> | RegExp;\n options?: StringArgInput<C, StringArg<C>>;\n }) => Ret<C, { match: string; idx: number; captures: string[] }[]> = this.options(\"regexFindAll\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/regexMatch/\n regexMatch: <const T extends StringArg<C>>(options: {\n input: StringArgInput<C, T>;\n regex: StringArgInput<C, StringArg<C>> | RegExp;\n options?: StringArgInput<C, StringArg<C>>;\n }) => Ret<C, boolean> = this.options(\"regexMatch\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/replaceAll/\n replaceAll: <const T extends StringArg<C>>(options: {\n input: StringArgInput<C, T>;\n find: StringArgInput<C, StringArg<C>>;\n replacement: StringArgInput<C, StringArg<C>>;\n }) => Ret<C, string> = this.options(\"replaceAll\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/replaceOne/\n replaceOne: <const T extends StringArg<C>>(options: {\n input: StringArgInput<C, T>;\n find: StringArgInput<C, StringArg<C>>;\n replacement: StringArgInput<C, StringArg<C>>;\n }) => Ret<C, string> = this.options(\"replaceOne\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/rtrim/\n rtrim: <const T extends StringArg<C>>(options: {\n input: StringArgInput<C, T>;\n chars?: StringArgInput<C, StringArg<C>>;\n }) => Ret<C, string> = this.options(\"rtrim\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/split/\n split: <const S extends StringArg<C>, const D extends StringArg<C>>(\n string: StringArgInput<C, S>,\n delimiter: StringArgInput<C, D>,\n ) => Ret<C, string[]> = this.varargs(\"split\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/strcasecmp/\n strcasecmp: BinaryStringToNumber<C> = this.varargs(\"strcasecmp\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/strLenBytes/\n strLenBytes: UnaryStringToNumber<C> = this.id(\"strLenBytes\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/strLenCP/\n strLenCP: UnaryStringToNumber<C> = this.id(\"strLenCP\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/substr/\n substr: <const S extends StringArg<C>, const N extends NumericArg<C>>(\n string: StringArgInput<C, S>,\n start: (N & NumericArgInput<C, N>) | number,\n length: (N & NumericArgInput<C, N>) | number,\n ) => Ret<C, string> = this.varargs(\"substr\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/substrBytes/\n substrBytes: <const S extends StringArg<C>, const N extends NumericArg<C>>(\n string: StringArgInput<C, S>,\n start: N & NumericArgInput<C, N>,\n length: N & NumericArgInput<C, N>,\n ) => Ret<C, string> = this.varargs(\"substrBytes\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/substrCP/\n substrCP: <const S extends StringArg<C>, const N extends NumericArg<C>>(\n string: StringArgInput<C, S>,\n start: N & NumericArgInput<C, N>,\n length: N & NumericArgInput<C, N>,\n ) => Ret<C, string> = this.varargs(\"substrCP\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/toLower/\n toLower: UnaryStringToString<C> = this.id(\"toLower\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/toUpper/\n toUpper: UnaryStringToString<C> = this.id(\"toUpper\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/trim/\n trim: <const T extends StringArg<C>>(options: {\n input: StringArgInput<C, T>;\n chars?: StringArgInput<C, StringArg<C>>;\n }) => Ret<C, string> = this.options(\"trim\");\n\n // Set operators (fully typed from ExprBuilder)\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/allElementsTrue/\n allElementsTrue: UnaryArrayToBool<C> = this.id(\"allElementsTrue\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/anyElementTrue/\n anyElementTrue: UnaryArrayToBool<C> = this.id(\"anyElementTrue\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/setDifference/\n setDifference: <const A extends ArrayArg<C>, const B extends ArrayArg<C>>(\n left: A & ArrayArgInput<C, A>,\n right: B & ArrayArgInput<C, B>,\n ) => Ret<C, ElemType<ResolveType<C, A>>[]> = this.varargs(\"setDifference\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/setEquals/\n setEquals: <const T extends ArrayArg<C>[]>(\n ...args: { [K in keyof T]: T[K] & ArrayArgInput<C, T[K]> }\n ) => Ret<C, boolean> = this.varargs(\"setEquals\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/setIntersection/\n setIntersection: <const T extends ArrayArg<C>[]>(\n ...args: { [K in keyof T]: T[K] & ArrayArgInput<C, T[K]> }\n ) => Ret<C, ElemType<ResolveType<C, T[number]>>[]> = this.varargs(\"setIntersection\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/setIsSubset/\n setIsSubset: BinaryArrayOp<C> = this.varargs(\"setIsSubset\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/setUnion/\n setUnion: <const T extends (ArrayArg<C> | ArrayLiteral<C>)[]>(\n ...args: T\n ) => Ret<C, ElemType<ResolveType<C, T[number]>>[]> = this.varargs(\"setUnion\");\n\n // Date operators (fully typed from ExprBuilder)\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/dateAdd/\n dateAdd: <const T extends DateArg<C>, const N extends NumericArg<C>>(options: {\n startDate: T & DateArgInput<C, T>;\n unit: string;\n amount: N & NumericArgInput<C, N>;\n timezone?: StringArg<C>;\n }) => Ret<C, Date> = this.options(\"dateAdd\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/dateDiff/\n dateDiff: <const S extends DateArg<C>, const E extends DateArg<C>>(options: {\n startDate: S & DateArgInput<C, S>;\n endDate: E & DateArgInput<C, E>;\n unit: string;\n timezone?: StringArg<C>;\n startOfWeek?: string;\n }) => Ret<C, number> = this.options(\"dateDiff\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/dateFromParts/\n dateFromParts: <const T>(opts: T) => Ret<C, Date> = this.options(\"dateFromParts\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/dateFromString/\n dateFromString: <const D extends StringArg<C>>(options: {\n dateString: D;\n format?: StringArg<C>;\n timezone?: StringArg<C>;\n onError?: ExprArgInput<C, ExprArg<C>>;\n onNull?: ExprArgInput<C, ExprArg<C>>;\n }) => Ret<C, Date> = this.options(\"dateFromString\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/dateSubtract/\n dateSubtract: <const T extends DateArg<C>, const N extends NumericArg<C>>(options: {\n startDate: T & DateArgInput<C, T>;\n unit: string;\n amount: N & NumericArgInput<C, N>;\n timezone?: StringArg<C>;\n }) => Ret<C, Date> = this.options(\"dateSubtract\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/dateToParts/\n dateToParts: <\n const T extends DateArg<C>,\n const I extends boolean | undefined = undefined,\n >(options: {\n date: T & DateArgInput<C, T>;\n timezone?: StringArg<C>;\n iso8601?: I;\n }) => Ret<\n C,\n I extends true ?\n {\n isoWeekYear: number;\n isoWeek: number;\n isoDayOfWeek: number;\n hour: number;\n minute: number;\n second: number;\n millisecond: number;\n }\n : {\n year: number;\n month: number;\n day: number;\n hour: number;\n minute: number;\n second: number;\n millisecond: number;\n }\n > = this.options(\"dateToParts\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/dateToString/\n dateToString: <const T extends DateArg<C>>(options: {\n date: T & DateArgInput<C, T>;\n format?: StringArg<C>;\n timezone?: StringArg<C>;\n onNull?: ExprArgInput<C, ExprArg<C>>;\n }) => Ret<C, string> = this.options(\"dateToString\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/dateTrunc/\n dateTrunc: <const T extends DateArg<C>, const N extends NumericArg<C>>(options: {\n date: T & DateArgInput<C, T>;\n unit: string;\n binSize?: N & NumericArgInput<C, N>;\n timezone?: StringArg<C>;\n startOfWeek?: string;\n }) => Ret<C, Date> = this.options(\"dateTrunc\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/dayOfMonth/\n dayOfMonth: UnaryDateToNumber<C> = this.id(\"dayOfMonth\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/dayOfWeek/\n dayOfWeek: UnaryDateToNumber<C> = this.id(\"dayOfWeek\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/dayOfYear/\n dayOfYear: UnaryDateToNumber<C> = this.id(\"dayOfYear\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/hour/\n hour: UnaryDateToNumber<C> = this.id(\"hour\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/isoDayOfWeek/\n isoDayOfWeek: UnaryDateToNumber<C> = this.id(\"isoDayOfWeek\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/isoWeek/\n isoWeek: UnaryDateToNumber<C> = this.id(\"isoWeek\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/isoWeekYear/\n isoWeekYear: UnaryDateToNumber<C> = this.id(\"isoWeekYear\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/millisecond/\n millisecond: UnaryDateToNumber<C> = this.id(\"millisecond\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/minute/\n minute: UnaryDateToNumber<C> = this.id(\"minute\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/month/\n month: UnaryDateToNumber<C> = this.id(\"month\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/second/\n second: UnaryDateToNumber<C> = this.id(\"second\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/week/\n week: UnaryDateToNumber<C> = this.id(\"week\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/year/\n year: UnaryDateToNumber<C> = this.id(\"year\");\n\n // Type conversion operators (fully typed from ExprBuilder)\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/convert/\n convert: {\n <const I extends ExprArg<C>, const To extends ConvertTo, const ON extends ExprArg<C>>(options: {\n input: ExprArgInput<C, I>;\n to: To;\n onError?: ExprArgInput<C, ExprArg<C>>;\n onNull: ExprArgInput<C, ON>;\n }): Ret<C, ConvertOutput<To> | ResolveType<C, ON>>;\n <const I extends ExprArg<C>, const To extends ConvertTo>(options: {\n input: ExprArgInput<C, I>;\n to: To;\n onError?: ExprArgInput<C, ExprArg<C>>;\n onNull?: undefined;\n }): Ret<C, NullishResult<C, I, ConvertOutput<To>>>;\n } = this.options(\"convert\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/isNumber/\n isNumber: UnaryTypeConversion<C, boolean> = this.id(\"isNumber\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/toBool/\n toBool: UnaryTypeConversion<C, boolean> = this.id(\"toBool\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/toDate/\n toDate: UnaryTypeConversion<C, Date> = this.id(\"toDate\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/toDecimal/\n toDecimal: UnaryTypeConversion<C, Decimal128> = this.id(\"toDecimal\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/toDouble/\n toDouble: UnaryTypeConversion<C, number> = this.id(\"toDouble\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/toInt/\n toInt: UnaryTypeConversion<C, number> = this.id(\"toInt\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/toLong/\n toLong: UnaryTypeConversion<C, number> = this.id(\"toLong\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/toObjectId/\n toObjectId: UnaryTypeConversion<C, ObjectId> = this.id(\"toObjectId\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/toString/\n toString: UnaryTypeConversion<C, string> = this.id(\"toString\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/type/\n type: <const T extends ExprArg<C>>(\n exp: ExprArgInput<C, T>,\n ) => Ret<\n C,\n | \"double\"\n | \"string\"\n | \"object\"\n | \"array\"\n | \"binData\"\n | \"undefined\"\n | \"objectId\"\n | \"bool\"\n | \"date\"\n | \"null\"\n | \"regex\"\n | \"dbPointer\"\n | \"javascript\"\n | \"javascriptWithScope\"\n | \"symbol\"\n | \"int\"\n | \"timestamp\"\n | \"long\"\n | \"decimal\"\n | \"missing\"\n | \"minKey\"\n | \"maxKey\"\n > = this.id(\"type\");\n\n // Object operators (properly typed from ExprBuilder)\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/getField/\n getField: <const F extends string, const I extends ExprArg<C> = never>(\n options: F | { field: F; input?: ExprArgInput<C, I> },\n ) => Ret<\n C,\n [I] extends [never] ?\n F extends keyof C ?\n C[F]\n : never\n : F extends keyof ResolveType<C, I> ? ResolveType<C, I>[F]\n : never\n > = options =>\n typeof options === \"string\" ? this.id(\"getField\")(options) : this.options(\"getField\")(options);\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/mergeObjects/\n mergeObjects: {\n // Overload for DeepSpecInput (mix of field refs and object literals)\n <const T extends [DeepSpecInput<C, any>, ...DeepSpecInput<C, any>[]]>(\n ...args: T\n ): Ret<C, MergeObjects<C, T>>;\n // Overload for Dict<ExprArgInput> with ShallowMergeObjects\n <const T extends Dict<ExprArgInput<C, any>>[]>(\n ...args: T\n ): Ret<\n C,\n ShallowMergeObjectsOverride<{\n [I in keyof T]: { [K in keyof T[I]]: T[I][K] extends Ret<any, infer U> ? U : T[I][K] };\n }>\n >;\n // Original overload for ExprArg\n <const T extends [ExprArg<C>, ...ExprArg<C>[]]>(\n ...args: ExprArgInputs<C, T>\n ): Ret<C, MergeObjects<C, T>>;\n } = this.flexible(\"mergeObjects\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/setField/\n setField: <\n const F extends string,\n const I extends ExprArg<C>,\n const V extends ExprArg<C>,\n >(options: {\n field: F;\n input: ExprArgInput<C, I>;\n value: ExprArgInput<C, V>;\n }) => Ret<C, ResolveType<C, I> & Record<F, ResolveType<C, V>>> = this.options(\"setField\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/unsetField/\n unsetField: <const F extends string, const I extends ExprArg<C>>(options: {\n field: F;\n input: ExprArgInput<C, I>;\n }) => Ret<C, Omit<ResolveType<C, I>, F>> = this.options(\"unsetField\");\n\n // Variable operators (fully typed from ExprBuilder)\n /** Binds variables for use within a scoped expression.\n * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/let/ */\n let: <\n const V extends Dict<ExprArg<C>>,\n const I extends ExprArg<MergeVars<C, ResolveVarSpec<C, V>>>,\n >(options: {\n vars: { [K in keyof V]: ExprArgInput<C, V[K]> };\n in: ($: BaseBuilder<MergeVars<C, ResolveVarSpec<C, V>>>) => I;\n }) => Ret<C, ResolveType<MergeVars<C, ResolveVarSpec<C, V>>, I>> = this.options(\"let\");\n\n // Literal operator (fully typed from ExprBuilder)\n /** Returns a value without parsing — prevents field path or operator interpretation.\n * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/literal/ */\n literal: <const T>(value: T) => Ret<C, T> = this.id(\"literal\");\n\n // Misc operators (fully typed from ExprBuilder)\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/meta/\n meta: <const T extends \"textScore\" | \"searchScore\" | \"searchHighlights\" | \"indexKey\">(\n metaType: T,\n ) => Ret<\n C,\n T extends \"textScore\" | \"searchScore\" ? number\n : T extends \"searchHighlights\" ?\n { path: string; texts: { value: string; type: \"text\" | \"hit\" }[] }[]\n : T extends \"indexKey\" ? Dict<string>\n : never\n > = this.id(\"meta\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/sampleRate/\n sampleRate: <const T extends NumericArg<C>>(rate: T & NumericArgInput<C, T>) => Ret<C, boolean> =\n this.id(\"sampleRate\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/binarySize/\n binarySize: UnaryTypeConversion<C, number> = this.id(\"binarySize\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/bsonSize/\n bsonSize: UnaryTypeConversion<C, number> = this.id(\"bsonSize\");\n\n // Bitwise operators (fully typed from ExprBuilder)\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/bitAnd/\n bitAnd: VarargsNumericOp<C> = this.varargs(\"bitAnd\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/bitOr/\n bitOr: VarargsNumericOp<C> = this.varargs(\"bitOr\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/bitXor/\n bitXor: VarargsNumericOp<C> = this.varargs(\"bitXor\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/bitNot/\n bitNot: UnaryNumericOp<C> = this.id(\"bitNot\");\n // Trigonometric operators (fully typed from ExprBuilder)\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/sin/\n sin: UnaryNumericOp<C> = this.id(\"sin\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/cos/\n cos: UnaryNumericOp<C> = this.id(\"cos\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/tan/\n tan: UnaryNumericOp<C> = this.id(\"tan\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/asin/\n asin: UnaryNumericOp<C> = this.id(\"asin\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/acos/\n acos: UnaryNumericOp<C> = this.id(\"acos\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/atan/\n atan: UnaryNumericOp<C> = this.id(\"atan\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/atan2/\n atan2: BinaryNumericOp<C> = this.varargs(\"atan2\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/asinh/\n asinh: UnaryNumericOp<C> = this.id(\"asinh\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/acosh/\n acosh: UnaryNumericOp<C> = this.id(\"acosh\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/atanh/\n atanh: UnaryNumericOp<C> = this.id(\"atanh\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/sinh/\n sinh: UnaryNumericOp<C> = this.id(\"sinh\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/cosh/\n cosh: UnaryNumericOp<C> = this.id(\"cosh\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/tanh/\n tanh: UnaryNumericOp<C> = this.id(\"tanh\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/degreesToRadians/\n degreesToRadians: UnaryNumericOp<C> = this.id(\"degreesToRadians\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/radiansToDegrees/\n radiansToDegrees: UnaryNumericOp<C> = this.id(\"radiansToDegrees\");\n\n // Dual-context operators (work as both expressions and accumulators)\n // These use AccumulatorExprArg to reject bare strings — use \"$field\" not \"field\"\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/sum/\n sum: {\n <const T extends AccumulatorExprArg<C>>(exp: AccumulatorArgInput<C, T>): Ret<C, number>;\n <const T extends AccumulatorExprArg<C>[]>(...args: AccumulatorArgInputs<C, T>): Ret<C, number>;\n } = this.flexible(\"sum\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/avg/\n avg: {\n <const T extends AccumulatorExprArg<C>>(\n exp: AccumulatorArgInput<C, T>,\n ): Ret<C, NullishResult<C, T, number>>;\n <const T extends AccumulatorExprArg<C>[]>(\n ...args: AccumulatorArgInputs<C, T>\n ): Ret<C, NullishResultFromArgs<C, T, number>>;\n } = this.flexible(\"avg\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/max/\n max: {\n <const T extends AccumulatorExprArg<C>>(\n exp: AccumulatorArgInput<C, T>,\n ): Ret<C, ResolveType<C, T>>;\n <const T extends AccumulatorExprArg<C>[]>(\n ...args: AccumulatorArgInputs<C, T>\n ): Ret<C, ResolveType<C, T[number]>>;\n } = this.flexible(\"max\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/min/\n min: {\n <const T extends AccumulatorExprArg<C>>(\n exp: AccumulatorArgInput<C, T>,\n ): Ret<C, ResolveType<C, T>>;\n <const T extends AccumulatorExprArg<C>[]>(\n ...args: AccumulatorArgInputs<C, T>\n ): Ret<C, ResolveType<C, T[number]>>;\n } = this.flexible(\"min\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/stdDevPop/\n stdDevPop: {\n <const T extends AccumulatorExprArg<C>>(\n exp: AccumulatorArgInput<C, T>,\n ): Ret<C, NullishResult<C, T, number>>;\n <const T extends AccumulatorExprArg<C>[]>(\n ...args: AccumulatorArgInputs<C, T>\n ): Ret<C, NullishResultFromArgs<C, T, number>>;\n } = this.flexible(\"stdDevPop\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/stdDevSamp/\n stdDevSamp: {\n <const T extends AccumulatorExprArg<C>>(\n exp: AccumulatorArgInput<C, T>,\n ): Ret<C, NullishResult<C, T, number>>;\n <const T extends AccumulatorExprArg<C>[]>(\n ...args: AccumulatorArgInputs<C, T>\n ): Ret<C, NullishResultFromArgs<C, T, number>>;\n } = this.flexible(\"stdDevSamp\");\n}\n\n/**\n * Expression builder providing type-safe access to all MongoDB aggregation operators.\n *\n * Passed as `$` in stage callbacks (e.g., `$project($ => ...)`, `$match($ => ...)`).\n * Exposes arithmetic, string, array, date, conditional, and comparison operators\n * that mirror the MongoDB aggregation expression language with full type inference.\n */\nexport class ExprBuilder<C> extends BaseBuilder<C> {\n /** Include this field in `$project` output (equivalent to `1`). */\n readonly include = 1 as const;\n /** Exclude this field from `$project` output (equivalent to `0`). */\n readonly exclude = 0 as const;\n}\n\n// Accumulator Builder: Expression operators + accumulator operators\nexport class AccumulatorBuilder<C> extends BaseBuilder<C, \"accumulator\"> {\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/addToSet/\n addToSet: <const T extends ExprArg<C>>(exp: ExprArgInput<C, T>) => Ret<C, ResolveType<C, T>[]> =\n this.id(\"addToSet\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/count-accumulator/\n count: <const T extends Dict<never>>(options: T) => Ret<C, number> = this.options(\"count\");\n\n // push with overloads for object literal vs single expression\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/push/\n push: <const T>(exp: T & DeepSpecInput<C, T>) => Ret<C, DeepSpecResolve<C, T>[]> =\n this.id(\"push\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/bottom/\n bottom: <const TOutput extends ExprArg<C>, const TSort extends SortBySpec<C>>(options: {\n output: ExprArgInput<C, TOutput>;\n sortBy: TSort;\n }) => Ret<C, ResolveType<C, TOutput>> = this.options(\"bottom\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/bottomN/\n bottomN: <\n const TOutput extends ExprArg<C>,\n const TSort extends SortBySpec<C>,\n const N extends NumericArg<C>,\n >(options: {\n output: ExprArgInput<C, TOutput>;\n sortBy: TSort;\n n: N & NumericArgInput<C, N>;\n }) => Ret<C, ResolveType<C, TOutput>[]> = this.options(\"bottomN\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/top/\n top: <const T extends SortBySpec<C>, const O extends ExprArg<C>>(options: {\n output: ExprArgInput<C, O>;\n sortBy: T;\n }) => Ret<C, ResolveType<C, O>> = this.options(\"top\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/topN/\n topN: <\n const T extends SortBySpec<C>,\n const N extends NumericArg<C>,\n const O extends ExprArg<C>,\n >(options: {\n output: ExprArgInput<C, O>;\n sortBy: T;\n n: N & NumericArgInput<C, N>;\n }) => Ret<C, ResolveType<C, O>[]> = this.options(\"topN\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/accumulator/\n accumulator: {\n <\n const InitFn extends (...args: any[]) => any,\n const AccExprs extends readonly ExprArg<C>[],\n const Result,\n >(\n options: TypedAccumulator<\n InitFn,\n { [K in keyof AccExprs]: ResolveType<C, AccExprs[K]> },\n Result\n > &\n Omit<\n TypedAccumulator<InitFn, { [K in keyof AccExprs]: ResolveType<C, AccExprs[K]> }, Result>,\n \"accumulate\" | \"accumulateArgs\"\n > & {\n accumulate: (\n state: ReturnType<InitFn>,\n ...args: { [K in keyof AccExprs]: ResolveType<C, AccExprs[K]> }\n ) => ReturnType<InitFn>;\n accumulateArgs: readonly [...AccExprs] & {\n [K in keyof AccExprs]: ExprArgInput<C, AccExprs[K]>;\n };\n finalize: (state: ReturnType<InitFn>) => Result;\n },\n ): Ret<C, Result>;\n <InitFn extends (...args: any[]) => any, AccArgs extends readonly unknown[], Result>(\n options: TypedAccumulator<InitFn, AccArgs, Result> & {\n finalize: (state: ReturnType<InitFn>) => Result;\n },\n ): Ret<C, Result>;\n <InitFn extends (...args: any[]) => any, AccExprs extends readonly ExprArg<C>[]>(\n options: TypedAccumulator<\n InitFn,\n { [K in keyof AccExprs]: ResolveType<C, AccExprs[K]> },\n ReturnType<InitFn>\n > &\n Omit<\n TypedAccumulator<\n InitFn,\n { [K in keyof AccExprs]: ResolveType<C, AccExprs[K]> },\n ReturnType<InitFn>\n >,\n \"accumulate\" | \"accumulateArgs\"\n > & {\n accumulate: (\n state: ReturnType<InitFn>,\n ...args: { [K in keyof AccExprs]: ResolveType<C, AccExprs[K]> }\n ) => ReturnType<InitFn>;\n accumulateArgs: readonly [...AccExprs] & {\n [K in keyof AccExprs]: ExprArgInput<C, AccExprs[K]>;\n };\n finalize?: undefined;\n },\n ): Ret<C, ReturnType<InitFn>>;\n <InitFn extends (...args: any[]) => any, AccArgs extends readonly unknown[]>(\n options: TypedAccumulator<InitFn, AccArgs, ReturnType<InitFn>> & {\n finalize?: undefined;\n },\n ): Ret<C, ReturnType<InitFn>>;\n } = (options: TypedAccumulator<any, any, any>) =>\n this.options(\"accumulator\")(resolveAccumulator(options));\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/median/\n median: <const T extends NumericArg<C>>(options: {\n input: T & NumericArgInput<C, T>;\n method?: \"approximate\";\n }) => Ret<C, number> = this.options(\"median\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/percentile/\n percentile: <const T extends NumericArg<C>, const P extends readonly number[]>(options: {\n input: T & NumericArgInput<C, T>;\n p: P;\n method?: \"approximate\";\n }) => Ret<C, { [K in keyof P]: number }> = this.options(\"percentile\");\n}\n\n// Window Builder: Accumulator operators + window operators\nexport class WindowBuilder<C> extends AccumulatorBuilder<C> {\n // Window-specific operators (properly typed from ExprBuilder)\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/denseRank/\n denseRank: () => Ret<C, number> = this.nullary(\"denseRank\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/covariancePop/\n covariancePop: <const X extends NumericArg<C>, const Y extends NumericArg<C>>(\n x: X & NumericArgInput<C, X>,\n y: Y & NumericArgInput<C, Y>,\n ) => Ret<C, number | null> = this.varargs(\"covariancePop\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/covarianceSamp/\n covarianceSamp: <const X extends NumericArg<C>, const Y extends NumericArg<C>>(\n x: X & NumericArgInput<C, X>,\n y: Y & NumericArgInput<C, Y>,\n ) => Ret<C, number | null> = this.varargs(\"covarianceSamp\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/derivative/\n derivative: <const T extends NumericArg<C>>(options: {\n input: T & NumericArgInput<C, T>;\n unit?: TimeUnit;\n window?: WindowSpec;\n }) => Ret<C, number> = options => {\n const resolved = this._resolve(options) as Dict<unknown>;\n if (\"window\" in resolved) {\n const { window, ...operatorArgs } = resolved;\n return new Ret({ $derivative: operatorArgs, window });\n }\n return new Ret({ $derivative: resolved });\n };\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/documentNumber/\n documentNumber: () => Ret<C, number> = this.nullary(\"documentNumber\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/expMovingAvg/\n expMovingAvg: <const T extends NumericArg<C>>(options: {\n input: T & NumericArgInput<C, T>;\n N?: NumericArg<C>;\n alpha?: NumericArg<C>;\n window?: WindowSpec;\n }) => Ret<C, number> = options => {\n const resolved = this._resolve(options) as Dict<unknown>;\n if (\"window\" in resolved) {\n const { window, ...operatorArgs } = resolved;\n return new Ret({ $expMovingAvg: operatorArgs, window });\n }\n return new Ret({ $expMovingAvg: resolved });\n };\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/integral/\n integral: <const T extends NumericArg<C>>(options: {\n input: T & NumericArgInput<C, T>;\n unit?: TimeUnit;\n window?: WindowSpec;\n }) => Ret<C, number> = options => {\n const resolved = this._resolve(options) as Dict<unknown>;\n if (\"window\" in resolved) {\n const { window, ...operatorArgs } = resolved;\n return new Ret({ $integral: operatorArgs, window });\n }\n return new Ret({ $integral: resolved });\n };\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/linearFill/\n linearFill: <const T extends ExprArg<C>>(exp: ExprArgInput<C, T>) => Ret<C, ResolveType<C, T>> =\n this.id(\"linearFill\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/locf/\n locf: <const T extends ExprArg<C>>(exp: ExprArgInput<C, T>) => Ret<C, ResolveType<C, T>> =\n this.id(\"locf\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/percentRank/\n percentRank: () => Ret<C, number> = this.nullary(\"percentRank\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/rank/\n rank: () => Ret<C, number> = this.nullary(\"rank\");\n\n // https://www.mongodb.com/docs/manual/reference/operator/aggregation/shift/\n shift: <const T extends ExprArg<C>, const B extends NumericArg<C>>(options: {\n output: ExprArgInput<C, T>;\n by: B & NumericArgInput<C, B>;\n default?: ExprArgInput<C, ExprArg<C>>;\n }) => Ret<C, ResolveType<C, T>> = this.options(\"shift\");\n}\n","/**\n * Migration tool — type-safe collection schema migrations via update pipelines.\n *\n * Usage:\n * const migration = migrate<OldUser, NewUser>();\n * const pipeline = migration.pipe(\n * $set({ newField: \"default\" }),\n * $unset(\"deprecatedField\"),\n * );\n * // pipeline is only valid if the output matches NewUser\n * await collection.updateMany(() => ({}), $ => pipeline).execute();\n */\n\nimport type { Agg, MigrationPipelineBuilder, TypedPipeline } from \"./pipeline-types.js\";\nimport type { SimplifyWritable } from \"./type-utils.js\";\n\n// Re-export for consumers\nexport type { MigrationPipelineBuilder } from \"./pipeline-types.js\";\n\n/**\n * MigrationOperators — the migration context with pipe and stage references.\n */\nexport type MigrationOperators<TFrom, TTo> = {\n pipe: MigrationPipelineBuilder<TFrom, TTo>;\n};\n\n/**\n * Creates a type-safe migration pipeline builder.\n *\n * The pipeline starts from TFrom (source schema) and validates that the\n * final output is assignable to TTo (target schema).\n *\n * Only update-allowed stages ($set, $unset, $addFields, $project,\n * $replaceRoot, $replaceWith) are accepted.\n *\n * @example\n * ```ts\n * type OldUser = { _id: ObjectId; name: string; age: number };\n * type NewUser = { _id: ObjectId; name: string; age: number; email: string };\n *\n * const m = migrate<OldUser, NewUser>();\n * const pipeline = m.pipe(\n * $set({ email: \"unknown@example.com\" }),\n * );\n * // ✅ compiles — output matches NewUser\n *\n * const bad = m.pipe(\n * $unset(\"age\"),\n * );\n * // ❌ error — output { _id, name } doesn't match NewUser\n * ```\n */\nexport const migrate = <TFrom, TTo>(): MigrationOperators<\n SimplifyWritable<TFrom>,\n SimplifyWritable<TTo>\n> => {\n const pipe = (\n ...stages: ((agg: Agg<unknown, unknown>) => Agg<unknown, unknown>)[]\n ): TypedPipeline<TFrom, unknown> => {\n const fakeAgg: Agg<TFrom, unknown> = {\n _in: undefined as never,\n _current: undefined as never,\n stages: [] as object[],\n pipe: undefined as never,\n toList: undefined as never,\n toMQL: undefined as never,\n };\n // eslint-disable-next-line @typescript-eslint/prefer-reduce-type-parameter\n const result = stages.reduce((agg, stage) => stage(agg), fakeAgg as Agg<unknown, unknown>);\n return {\n __pipelineIn: undefined as unknown as TFrom,\n __pipelineOut: undefined as unknown,\n stages: result.stages,\n };\n };\n\n return {\n pipe: pipe as unknown as MigrationPipelineBuilder<\n SimplifyWritable<TFrom>,\n SimplifyWritable<TTo>\n >,\n };\n};\n","import { ObjectId } from \"mongodb\";\n\nimport { ExprBuilder, Ret, type RuntimeValue } from \"./builder.js\";\nimport type { Dict } from \"./type-utils.js\";\n\ntype Stage = Dict<unknown>;\ntype RuntimeAgg = { stages?: Stage[] } & Dict<unknown>;\n\n// Deep unwrap Ret objects to get runtime values\nexport const unwrapRet = (value: unknown): unknown => {\n const _foo = value as RuntimeValue;\n if (_foo instanceof Ret) return unwrapRet(_foo.__fn);\n if (Array.isArray(_foo)) return _foo.map(unwrapRet);\n if (_foo instanceof Date) return _foo;\n if (_foo instanceof ObjectId) return _foo;\n if (_foo instanceof RegExp) return _foo;\n if (typeof _foo !== \"object\" || _foo === null) return _foo;\n\n return Object.entries(_foo).reduce((acc, [k, v]) => ({ ...acc, [k]: unwrapRet(v) }), {});\n};\n\ntype StageSpec<C> = unknown | ((builder: ExprBuilder<C>) => unknown);\n\nexport const resolveStage = <C>(stage: StageSpec<C>): unknown =>\n unwrapRet(typeof stage === \"function\" ? stage(new ExprBuilder<C>()) : stage);\n\nexport const pushStage =\n <TOptions>(fn: (options: TOptions) => Stage) =>\n (options: TOptions) =>\n (agg: RuntimeAgg): RuntimeAgg => ({ ...agg, stages: [...(agg.stages ?? []), fn(options)] });\n","/* eslint-disable @typescript-eslint/unified-signatures */\n/* eslint-disable @typescript-eslint/no-empty-object-type */\n// ==========================================\n// Pipeline Stages - All $stage declarations\n// ==========================================\nimport type { ChangeStreamDocument, Document, ObjectId } from \"mongodb\";\nimport type { GreaterThan, IsAny, IsUnknown, Simplify } from \"type-fest\";\n\nimport { AccumulatorBuilder, WindowBuilder } from \"./builder.js\";\nimport type { ArrayRootPath, ComparablePath, PathType } from \"./paths.js\";\nimport { pushStage, resolveStage, unwrapRet } from \"./runtime-utils.js\";\nimport {\n type Agg,\n type CallbackOnlyError,\n type Collection,\n type CollectionType,\n type ExprBuilder as ExprBuilder,\n type ExpressionIn,\n type ForeignType,\n type NumericIn,\n type ResolveSpec,\n type ResolveType,\n type Ret,\n type SmartAnyPathFieldRef,\n type TimeUnit,\n type TypedPipeline,\n type UpdateStageFunction,\n type ValidExpressionValue,\n type ValidMatchFilterWithBuilder,\n} from \"./sluice.js\";\nimport type { OpaqueError } from \"./type-errors.js\";\nimport type { __, AnyDict, Dict } from \"./type-utils.js\";\n\ntype RuntimeAgg = { stages?: Dict<unknown>[] } & Dict<unknown>;\n\ntype DotPathToObject<Path extends string, Value> =\n Path extends `${infer Head}.${infer Tail}` ? { [K in Head]: DotPathToObject<Tail, Value> }\n : { [K in Path]: Value };\n\ntype DeepMerge<A, B> =\n A extends object ?\n B extends object ?\n {\n [K in keyof A | keyof B]: K extends keyof B ?\n K extends keyof A ?\n DeepMerge<A[K], B[K]>\n : B[K]\n : K extends keyof A ? A[K]\n : never;\n }\n : A | B\n : A | B;\n\n// ==========================================\n// Stage Helper Types\n// ==========================================\n\ntype ValidateSpec<C, Spec> = {\n [K in keyof Spec]: Spec[K] extends 0 | 1 ? Spec[K]\n : Spec[K] extends Ret<any, any> ? Spec[K]\n : ValidExpressionValue<C, Spec[K]>;\n};\n\ntype ProjectSpec<C> =\n | ({ [K in keyof C & string]?: 1 } & { _id?: 0 | 1 } & Dict<ExpressionIn<C> | Ret<C>>)\n | ({ [K in keyof C & string]?: 0 } & { _id?: 0 | 1 } & Dict<ExpressionIn<C> | Ret<C>>)\n | (Dict<ExpressionIn<C> | Ret<C>> & { _id?: 0 | 1 });\n\ntype HasKey<Spec, K, V> = { [P in keyof Spec]: Spec[P] extends V ? true : false }[keyof Spec];\ntype OnlyIdMixed<Spec> =\n HasKey<Spec, any, 1> extends true ?\n HasKey<Spec, any, 0> extends true ?\n keyof Spec & string extends \"_id\" | `_${string}` ?\n true\n : false\n : true\n : true;\n\ntype ValidateProjectRules<Spec> =\n OnlyIdMixed<Spec> extends true ? Spec\n : CallbackOnlyError<\"$project cannot mix inclusion (1) and exclusion (0) except for _id\">;\n\ntype ProjectIdResult<C, Spec> =\n Spec extends { _id: 0 } ? {}\n : Spec extends { _id: 1 } ?\n C extends { _id: infer Id } ?\n { _id: Id }\n : OpaqueError<\"$project field does not exist: _id\">\n : C extends { _id: infer Id } ? { _id: Id }\n : {};\n\ntype ProjectResult<C, Spec> = Simplify<\n ProjectIdResult<C, Spec> & {\n [K in Exclude<keyof Spec, \"_id\">]: Spec[K] extends 1 ?\n K extends keyof C ?\n C[K]\n : OpaqueError<`$project field does not exist: ${K & string}`>\n : Spec[K] extends 0 ? never\n : ResolveType<C, Spec[K]>;\n }\n>;\n\n// ==========================================\n// Window Function Types\n// ==========================================\n\ntype WindowBoundary = \"unbounded\" | \"current\" | number;\ntype WindowDef = {\n documents?: [WindowBoundary, WindowBoundary];\n range?: [WindowBoundary, WindowBoundary];\n unit?: TimeUnit;\n};\n\ntype AccumulatorOp<C, T = ExpressionIn<C>> = { window?: WindowDef } & (\n | { $sum: T }\n | { $avg: T }\n | { $min: T }\n | { $max: T }\n | { $first: T }\n | { $last: T }\n | { $count: Dict<never> }\n | { $push: T }\n | { $addToSet: T }\n);\n\ntype WindowOperatorSpec<C> =\n | AccumulatorOp<C>\n | Ret<C, any>\n | { $rank: Dict<never> }\n | { $denseRank: Dict<never> }\n | { $documentNumber: Dict<never> }\n | { $percentRank: Dict<never> }\n | { $shift: { output: ExpressionIn<C>; by: number; default?: ExpressionIn<C> } }\n | { $expMovingAvg: { input: ExpressionIn<C>; N?: number; alpha?: number } }\n | { $linearFill: ExpressionIn<C> }\n | { $derivative: { input: ExpressionIn<C>; unit?: TimeUnit }; window: WindowDef }\n | { $integral: { input: ExpressionIn<C>; unit?: TimeUnit } };\n\ntype HasNullish<T> = [Extract<T, null | undefined>] extends [never] ? false : true;\ntype NullishResult<C, T, Output> =\n HasNullish<ResolveType<C, T>> extends true ? Output | null : Output;\n\ntype WindowOperatorResult<C, Op> =\n Op extends Ret<C, infer T> ? T\n : Op extends { $sum: NumericIn<C> } ? number\n : Op extends { $avg: infer A } ? NullishResult<C, A, number>\n : Op extends { $min: ExpressionIn<C> } ? ResolveType<C, Op[\"$min\"]> | null\n : Op extends { $max: ExpressionIn<C> } ? ResolveType<C, Op[\"$max\"]> | null\n : Op extends { $first: ExpressionIn<C> } ? ResolveType<C, Op[\"$first\"]>\n : Op extends { $last: ExpressionIn<C> } ? ResolveType<C, Op[\"$last\"]>\n : Op extends { $count: Dict<never> } ? number\n : Op extends { $push: ExpressionIn<C> } ? ResolveType<C, Op[\"$push\"]>[]\n : Op extends { $addToSet: ExpressionIn<C> } ? ResolveType<C, Op[\"$addToSet\"]>[]\n : Op extends { $rank: Dict<never> } ? number\n : Op extends { $denseRank: Dict<never> } ? number\n : Op extends { $documentNumber: Dict<never> } ? number\n : Op extends { $percentRank: Dict<never> } ? number\n : Op extends { $shift: { output: infer Output; default?: infer Default } } ?\n Default extends ExpressionIn<C> ?\n ResolveType<C, Output> | ResolveType<C, Default>\n : ResolveType<C, Output> | null\n : Op extends { $expMovingAvg: any } ? number | null\n : Op extends { $linearFill: ExpressionIn<C> } ? ResolveType<C, Op[\"$linearFill\"]> | null\n : Op extends { $derivative: any } ? number | null\n : Op extends { $integral: any } ? number | null\n : unknown; // ToDo - use never or error type\n\ntype SortBySpec<C> = Partial<Record<keyof C & string, 1 | -1>>;\ntype SortBySingle<C> = { [K in keyof C & string]: { [P in K]: 1 | -1 } }[keyof C & string];\ntype SortPath<C> = ComparablePath<C> | \"_id\" | `_id.${string}`;\ntype SortValue = 1 | -1 | { $meta: \"textScore\" | \"searchScore\" };\ntype SortSpec<C> =\n | Partial<Record<SortPath<C>, SortValue>>\n | { $meta: \"textScore\" | \"searchScore\" }\n | (Partial<Record<SortPath<C>, SortValue>> & { $meta: \"textScore\" | \"searchScore\" });\n\ntype SortByHasDate<C, S> =\n [S] extends [undefined] ? false\n : true extends (\n {\n [K in keyof S]: K extends keyof C ?\n C[K] extends Date ?\n true\n : false\n : false;\n }[keyof S]\n ) ?\n true\n : false;\n\ntype HasRangeWindowWithoutUnit<Output> =\n true extends (\n {\n [K in keyof Output]: Output[K] extends { window: { range: any } } ?\n Output[K] extends { window: { unit: any } } ?\n false\n : true\n : false;\n }[keyof Output]\n ) ?\n true\n : false;\n\n// Check if output contains rank-based operators that require sortBy\ntype RequiresSortBy<C, Output extends Dict<WindowOperatorSpec<C>>> =\n true extends (\n {\n [K in keyof Output]: Output[K] extends (\n { $rank: any } | { $denseRank: any } | { $percentRank: any }\n ) ?\n true\n : false;\n }[keyof Output]\n ) ?\n true\n : false;\n\ntype RemoveNever<T> = { [K in keyof T as T[K] extends never ? never : K]: T[K] };\n\n// UnwindResult - transform array field to its element type\ntype UnwindPath<T extends string> = T extends `$${infer Field}` ? Field : never;\ntype UnwindElement<T> =\n T extends readonly (infer E)[] ? E\n : T extends (infer E)[] ? E\n : T;\ntype UnwindResult<C, P extends string> = {\n [K in keyof C]: K extends UnwindPath<P> ? UnwindElement<C[K]> : C[K];\n};\n\ntype UnwindResultWithPreserve<C, P extends string, Preserve extends boolean | undefined> = {\n [K in keyof C]: K extends UnwindPath<P> ?\n Preserve extends true ?\n UnwindElement<C[K]> | null | undefined\n : UnwindElement<C[K]>\n : C[K];\n};\n\n// IndexStats result type\ntype IndexStatsResult = {\n name: string;\n key: Dict<number>;\n host: string;\n accesses: { ops: number; since: Date };\n shard?: string;\n spec?: AnyDict;\n};\n\n// SortByCount result type\ntype SortByCountResult<T> = { _id: T; count: number };\n\n// $unset result - remove specified fields\ntype UnsetResult<C, Fields extends string[]> = Omit<C, Fields[number]>;\n\ntype CollectionOf<T> =\n T extends Collection ? T\n : T extends { coll: infer C } ?\n C extends Collection ?\n C\n : never\n : never;\n\ntype CollectionConstraint<C, TTarget extends Collection> =\n C extends CollectionType<TTarget> ? {} : CallbackOnlyError<\"Collection type mismatch\">;\n\ntype MergeIntoConstraint<C, TInto extends Collection> = CollectionConstraint<C, TInto>;\ntype OutIntoConstraint<C, T> = CollectionConstraint<C, CollectionOf<T>>;\n\n// Helper to validate that a record doesn't contain raw MongoDB operators\ntype ValidateNoRawOperators<T extends Dict<any>> = {\n [K in keyof T]: T[K] extends { readonly __context: any; readonly __type: any } ? T[K]\n : T[K] extends { [key: `$${string}`]: any } ?\n OpaqueError<\"Invalid MongoDB operator object - use builder API instead (e.g., $.sum(...))\">\n : T[K];\n};\n\n// Type for accumulator expressions in $bucket output\n// Enforce sortBy requirement for rank-based operators\ntype WindowFieldsOptions<\n C,\n T extends {\n partitionBy?: ExpressionIn<C> | Dict<ExpressionIn<C> | Ret<C>> | Ret<C>;\n sortBy?: SortBySpec<C>;\n output: Dict<WindowOperatorSpec<C>>;\n },\n> =\n SortByHasDate<C, T[\"sortBy\"]> extends true ?\n HasRangeWindowWithoutUnit<T[\"output\"]> extends true ?\n OpaqueError<\"$setWindowFields range window with date sortBy requires unit\"> & T\n : RequiresSortBy<C, T[\"output\"]> extends true ? T & { sortBy: SortBySingle<C> }\n : T\n : RequiresSortBy<C, T[\"output\"]> extends true ? T & { sortBy: SortBySingle<C> }\n : T;\n\n// ReplaceRootScalar: validated field refs (no bare strings), expressions, system vars\ntype ReplaceRootScalar<C> = SmartAnyPathFieldRef<C> | Ret<C> | \"$$ROOT\" | \"$$CURRENT\";\n\ntype ReplaceRootValue<C> = ReplaceRootScalar<C> | { [K in string]: ReplaceRootValue<C> };\n\ntype ReplaceRootResolved<C, R> =\n R extends \"$$ROOT\" | \"$$CURRENT\" ? C\n : R extends Ret<any, infer T> ? T\n : R extends object ? ResolveSpec<C, R>\n : ResolveType<C, R>;\n\ntype IsStrictlyAscending<T extends readonly number[]> =\n T extends (\n readonly [infer A extends number, infer B extends number, ...infer Rest extends number[]]\n ) ?\n number extends A | B ? true\n : GreaterThan<B, A> extends false ? false\n : IsStrictlyAscending<[B, ...Rest]>\n : true;\n\ntype AscendingBoundaries<T extends readonly number[]> =\n IsStrictlyAscending<T> extends true ? T\n : OpaqueError<\"$bucket boundaries must be strictly increasing\">;\n\n// ==========================================\n// Stage Declarations\n// ==========================================\n\n/** Adds new fields to documents. Alias for `$set`.\n * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/addFields/ */\nexport const $addFields = pushStage(fieldsBuilder => ({\n $addFields: resolveStage(fieldsBuilder),\n})) as unknown as <C, const T>(\n fieldsBuilder: ($: ExprBuilder<Simplify<C>>) => T,\n) => UpdateStageFunction<C, Simplify<C & ResolveSpec<C, T>>>;\n\n/** Groups documents into discrete buckets by a specified expression and boundaries.\n * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/bucket/ */\nexport const $bucket = pushStage((options: any) => {\n const resolved = resolveStage(options) as { output?: unknown } & Dict<unknown>;\n if (resolved.output && typeof options.output === \"function\") {\n // resolveStage handles the top level, but for bucket output specifically,\n // if options is an object, resolveStage returns it as is (if not function).\n // EXCEPT resolveStage doesn't deep resolve properties.\n // I need to resolve 'output' property if it is a function.\n resolved.output = resolveStage(options.output);\n }\n return { $bucket: resolved };\n}) as unknown as {\n // Overload 1: With callback-based output (full accumulator support)\n <\n C,\n const B extends readonly number[],\n const D extends string | number = never,\n const O extends AnyDict = Dict<never>,\n >(options: {\n groupBy: ExpressionIn<C>;\n boundaries: B & AscendingBoundaries<B>;\n default?: D;\n output: ($: AccumulatorBuilder<Simplify<C>>) => O & ValidateNoRawOperators<O>;\n }): <TIn>(agg: Agg<TIn, C>) => Agg<TIn, { _id: B[number] | D } & ResolveSpec<C, O>>;\n // Overload 2: No output (produces only _id and count)\n <C, const B extends readonly number[], const D extends string | number = never>(options: {\n groupBy: ExpressionIn<C>;\n boundaries: B & AscendingBoundaries<B>;\n default?: D;\n }): <TIn>(agg: Agg<TIn, C>) => Agg<TIn, { _id: B[number] | D; count: number }>;\n};\n\n/** Automatically groups documents into a specified number of buckets.\n * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/bucketAuto/ */\nexport const $bucketAuto = pushStage(options => ({\n $bucketAuto: resolveStage(options),\n})) as unknown as <\n C,\n const G extends ExpressionIn<C>,\n const O extends Dict<ExpressionIn<C>> | undefined = undefined,\n>(options: {\n groupBy: G;\n buckets: number;\n output?: O;\n granularity?:\n | \"R5\"\n | \"R10\"\n | \"R20\"\n | \"R40\"\n | \"R80\"\n | \"1-2-5\"\n | \"E6\"\n | \"E12\"\n | \"E24\"\n | \"E48\"\n | \"E96\"\n | \"E192\"\n | \"POWERSOF2\";\n}) => <TIn>(agg: Agg<TIn, C>) => Agg<\n TIn,\n {\n _id: { min: ResolveType<C, G>; max: ResolveType<C, G> };\n count: number;\n } & (O extends AnyDict ? { [K in keyof O]: ResolveType<C, O[K]> } : {})\n>;\n\n/** Returns statistics about the collection (latency, storage, count, query exec stats).\n * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/collStats/ */\nexport const $collStats = pushStage(options => ({\n $collStats: resolveStage(options),\n})) as unknown as {\n <\n C,\n const T extends {\n latencyStats?: { histograms?: boolean };\n storageStats?: { scale?: number };\n count: Dict<never>;\n queryExecStats?: Dict<never>;\n },\n >(\n options: T,\n ): <TIn>(agg: Agg<TIn, C>) => Agg<\n TIn,\n {\n ns: string;\n localTime: Date;\n } & (T extends { latencyStats: any } ?\n { latencyStats: { reads: Dict<number>; writes: Dict<number>; commands: Dict<number> } }\n : { latencyStats?: { reads: Dict<number>; writes: Dict<number>; commands: Dict<number> } }) &\n (T extends { storageStats: any } ?\n { storageStats: { size: number; count: number; avgObjSize: number; storageSize: number } }\n : {\n storageStats?: { size: number; count: number; avgObjSize: number; storageSize: number };\n }) & { count: number } & (T extends { queryExecStats: any } ?\n { queryExecStats: Dict<number> }\n : { queryExecStats?: Dict<number> })\n >;\n <\n C,\n const T extends {\n latencyStats?: { histograms?: boolean };\n storageStats?: { scale?: number };\n count?: Dict<never>;\n queryExecStats?: Dict<never>;\n },\n >(\n options: T,\n ): <TIn>(agg: Agg<TIn, C>) => Agg<\n TIn,\n {\n ns: string;\n localTime: Date;\n } & (T extends { latencyStats: any } ?\n { latencyStats: { reads: Dict<number>; writes: Dict<number>; commands: Dict<number> } }\n : { latencyStats?: { reads: Dict<number>; writes: Dict<number>; commands: Dict<number> } }) &\n (T extends { storageStats: any } ?\n { storageStats: { size: number; count: number; avgObjSize: number; storageSize: number } }\n : {\n storageStats?: { size: number; count: number; avgObjSize: number; storageSize: number };\n }) & { count?: number } & (T extends { queryExecStats: any } ?\n { queryExecStats: Dict<number> }\n : { queryExecStats?: Dict<number> })\n >;\n};\n\n/** Replaces the input documents with a count of the documents at this stage.\n * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/count/ */\nexport const $count = pushStage(field => ({ $count: field })) as unknown as <\n C,\n const T extends string,\n>(\n field: T,\n) => <TIn>(agg: Agg<TIn, C>) => Agg<TIn, { [K in T]: number }>;\n\n/** Creates new documents in a sequence of documents where gaps exist.\n * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/densify/ */\nexport const $densify = pushStage(options => ({ $densify: resolveStage(options) })) as unknown as <\n C,\n const T extends {\n field: keyof C & string;\n partitionByFields?: (keyof C & string)[];\n range: {\n step: number;\n unit?: TimeUnit;\n bounds: \"full\" | \"partition\" | [__, __];\n };\n },\n>(\n options: NoInfer<T>,\n) => <TIn>(agg: Agg<TIn, C>) => Agg<TIn, C>;\n\n/** Returns literal documents from input values (no collection required).\n * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/documents/ */\nexport const $documents = ((documents: __[]) => ({\n stages: [{ $documents: documents }],\n})) as unknown as <const T extends readonly Dict<unknown>[]>(\n documents: T,\n) => Agg<T[number], T[number]>;\n\n/** Processes multiple aggregation pipelines on the same input documents in a single stage.\n * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/facet/ */\nexport const $facet = pushStage(pipelines => {\n const facetSpec = resolveStage(pipelines) as Dict<unknown>;\n const transformedSpec: any = {};\n for (const [key, val] of Object.entries(facetSpec)) {\n if ((val as any).stages) {\n transformedSpec[key] = (val as any).stages;\n } else if (Array.isArray(val)) {\n transformedSpec[key] = val;\n } else {\n transformedSpec[key] = val; // fallback\n }\n }\n return { $facet: transformedSpec };\n}) as unknown as <C, const T extends Dict<TypedPipeline<C, __>>>(\n pipelines: ($: ExprBuilder<Simplify<C>>) => T,\n) => <TIn>(agg: Agg<TIn, C>) => Agg<\n TIn,\n {\n [K in keyof T]: T[K] extends TypedPipeline<any, infer R> ? R[]\n : T[K] extends readonly [...any[], (agg: any) => Agg<any, infer R>] ? R[]\n : __[];\n }\n>;\n\n/** Populates null and missing field values using linear interpolation or last-observed carry-forward.\n * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/fill/ */\nexport const $fill = pushStage(options => ({ $fill: resolveStage(options) })) as unknown as <\n C,\n const T extends {\n partitionBy?: ExpressionIn<C>;\n partitionByFields?: (keyof C & string)[];\n sortBy: SortBySpec<C>;\n output: { [K in keyof C]?: { method: \"linear\" | \"locf\" } | { value: ExpressionIn<C> } };\n },\n>(\n options: T,\n) => <TIn>(agg: Agg<TIn, C>) => Agg<TIn, C>;\n\n/** Returns documents ordered by proximity to a geospatial point.\n * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/geoNear/ */\nexport const $geoNear = pushStage(options => ({ $geoNear: resolveStage(options) })) as unknown as <\n C,\n const TDistanceField extends string,\n const TIncludeLocs extends string | undefined = undefined,\n>(options: {\n near: { type: \"Point\"; coordinates: [number, number] };\n distanceField: TDistanceField;\n spherical?: boolean;\n maxDistance?: number;\n minDistance?: number;\n query?: AnyDict;\n distanceMultiplier?: number;\n includeLocs?: TIncludeLocs;\n uniqueDocs?: boolean;\n key?: string;\n}) => <TIn>(\n agg: Agg<TIn, C>,\n) => Agg<\n TIn,\n C &\n DeepMerge<\n DotPathToObject<TDistanceField, number>,\n TIncludeLocs extends string ?\n DotPathToObject<TIncludeLocs, { type: \"Point\"; coordinates: [number, number] }>\n : {}\n >\n>;\n\n/** Performs a recursive search on a collection following references between documents.\n * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/graphLookup/ */\nexport const $graphLookup = pushStage(\n (options: {\n from: Collection;\n startWith: unknown;\n connectFromField: string;\n connectToField: string;\n as: string;\n maxDepth?: number;\n depthField?: string;\n restrictSearchWithMatch?: AnyDict;\n }) => ({\n $graphLookup: {\n ...(resolveStage(options) as Dict<unknown>),\n from: options.from.__collectionName,\n },\n }),\n) as unknown as <\n C,\n const TFrom extends Collection,\n const TAs extends string,\n const TDF extends string | undefined = undefined,\n>(options: {\n from: TFrom;\n startWith: ExpressionIn<C>;\n connectFromField: keyof ForeignType<TFrom> & string;\n connectToField: keyof ForeignType<TFrom> & string;\n as: TAs;\n maxDepth?: number;\n depthField?: TDF;\n restrictSearchWithMatch?: AnyDict;\n}) => <TIn>(\n agg: Agg<TIn, C>,\n) => Agg<TIn, C & Record<TAs, (ForeignType<TFrom> & Record<TDF & string, number>)[]>>;\n\n// GroupIdSpec - _id can be null, a field ref, a Ret expression, or a compound object of field refs / expressions\ntype GroupIdSpec<C> = ExpressionIn<C> | Ret<C> | null | Dict<ExpressionIn<C> | Ret<C>>;\n\ntype ValidateGroupOutput<C, T extends { _id: GroupIdSpec<C> }> = {\n [K in keyof T]: K extends \"_id\" ? T[K]\n : T[K] extends Ret<C, any> ? T[K]\n : OpaqueError<\"Invalid $group output - use builder API (e.g., $.sum(...))\">;\n};\n\n/** Groups documents by a specified expression and applies accumulator expressions.\n * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/group/ */\nexport const $group = pushStage(spec => ({\n $group: unwrapRet(typeof spec === \"function\" ? spec(new AccumulatorBuilder<unknown>()) : spec),\n})) as unknown as <C, const T extends { _id: GroupIdSpec<C> }>(\n spec: ($: AccumulatorBuilder<Simplify<C>>) => ValidateGroupOutput<C, T>,\n) => <TIn>(agg: Agg<TIn, C>) => Agg<TIn, ResolveSpec<C, T>>;\n\n/** Returns statistics about index usage for the collection.\n * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/indexStats/ */\nexport const $indexStats = pushStage(() => ({ $indexStats: {} })) as unknown as <C>() => <TIn>(\n agg: Agg<TIn, C>,\n) => Agg<TIn, IndexStatsResult>;\n\n/** Limits the number of documents passed to the next stage.\n * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/limit/ */\nexport const $limit = pushStage(n => ({ $limit: n })) as unknown as <C, const T extends number>(\n n: T,\n) => <TIn>(agg: Agg<TIn, C>) => Agg<TIn, C>;\n\ntype LetToContext<C, Let extends Dict<ExpressionIn<C>>> = {\n [K in keyof Let as `$${K & string}`]: ResolveType<C, Let[K]>;\n};\n\ntype StripLookupVars<T> = {\n [K in keyof T as K extends `$${string}` ? never : K]: T[K];\n};\n\n// Helper: Augment foreign context with let vars if provided\ntype LookupContext<TFrom extends Collection, C, TLet extends Dict<ExpressionIn<C>> | undefined> =\n TLet extends Dict<ExpressionIn<C>> ? ForeignType<TFrom> & LetToContext<C, TLet>\n : ForeignType<TFrom>;\n\n/** Performs a left outer join with another collection.\n * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/lookup/ */\nexport const $lookup = pushStage((options: { from: Collection } & Dict<unknown>) => {\n const spec: Dict<unknown> & { from: string; pipeline?: unknown } = {\n ...options,\n from: options.from.__collectionName,\n };\n if (typeof spec.pipeline === \"function\") {\n spec.pipeline = resolveStage(spec.pipeline);\n }\n if (spec.pipeline && typeof spec.pipeline === \"object\" && \"stages\" in spec.pipeline) {\n const pipeline = spec.pipeline as { stages?: unknown };\n if (typeof pipeline.stages !== \"undefined\") {\n spec.pipeline = pipeline.stages;\n }\n }\n return { $lookup: spec };\n}) as unknown as {\n // Callback-based pipeline (typed): $ => $.pipe($match(...), $project(...))\n <\n C,\n TFrom extends Collection,\n const TAs extends string,\n const TLet extends Dict<ExpressionIn<C>> | undefined = undefined,\n TPipelineOut = ForeignType<TFrom>,\n >(options: {\n from: TFrom;\n localField?: PathType<C>;\n foreignField?: PathType<ForeignType<TFrom>>;\n let?: TLet;\n pipeline?: (\n $: ExprBuilder<LookupContext<TFrom, C, TLet>>,\n ) => TypedPipeline<LookupContext<TFrom, C, TLet>, TPipelineOut>;\n as: TAs;\n }): <TIn>(\n agg: Agg<TIn, C>,\n ) => Agg<TIn, Simplify<C & Record<TAs, StripLookupVars<TPipelineOut>[]>>>;\n // Array of raw objects (rejected - use callback form)\n <C, TFrom extends Collection, const TAs extends string>(options: {\n from: TFrom;\n localField?: PathType<C>;\n foreignField?: PathType<ForeignType<TFrom>>;\n pipeline: readonly object[];\n as: TAs;\n }): <TIn>(agg: Agg<TIn, C>) => Agg<TIn, CallbackOnlyError<\"$lookup.pipeline\">>;\n};\n\n/** Filters documents to pass only those that match the specified conditions.\n * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/match/ */\nexport const $match = pushStage(filter => ({ $match: resolveStage(filter) })) as unknown as <\n C,\n const R extends NoInfer<ValidMatchFilterWithBuilder<C>>,\n>(\n filter: ($: ExprBuilder<Simplify<C>>) => R,\n) => <TIn>(agg: Agg<TIn, C>) => Agg<TIn, C>;\n\n/** Writes pipeline results to a collection, merging with existing documents. Terminal stage.\n * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/merge/ */\nexport const $merge = pushStage((options: { into: Collection } & Dict<unknown>) => ({\n $merge: {\n ...(resolveStage(options) as Dict<unknown>),\n into: options.into.__collectionName,\n },\n})) as unknown as <\n C,\n const T extends {\n into: Collection;\n on?: (keyof C & string) | readonly (keyof C & string)[];\n let?: Dict<ExpressionIn<C>>;\n whenMatched?: \"replace\" | \"keepExisting\" | \"merge\" | \"fail\" | readonly AnyDict[];\n whenNotMatched?: \"insert\" | \"discard\" | \"fail\";\n },\n>(\n options: T & MergeIntoConstraint<C, T[\"into\"]>,\n) => <TIn>(agg: Agg<TIn, C>) => Agg<TIn, never>; // $merge is terminal - no documents flow out\n\n/** Writes pipeline results to a collection, replacing existing content. Terminal stage.\n * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/out/ */\nexport const $out = pushStage(options => {\n const resolved = resolveStage(options) as Collection | { db: string; coll: Collection };\n\n if (\"coll\" in resolved) {\n return { $out: { db: resolved.db, coll: resolved.coll.__collectionName } };\n }\n\n return { $out: resolved.__collectionName };\n}) as unknown as <C, const T extends Collection | { db: string; coll: Collection }>(\n options: T & OutIntoConstraint<C, T>,\n) => <TIn>(agg: Agg<TIn, C>) => Agg<TIn, never>; // $out is terminal - no documents flow out\n\n/** Reshapes documents by including, excluding, or computing new fields.\n * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/project/ */\nexport const $project = pushStage(spec => ({ $project: resolveStage(spec) })) as unknown as <\n C,\n const T extends Dict<0 | 1 | ExpressionIn<C> | Ret<C>>,\n>(\n spec: ($: ExprBuilder<Simplify<C>>) => ValidateProjectRules<ValidateSpec<C, T>>,\n) => UpdateStageFunction<C, RemoveNever<ProjectResult<C, T>>>;\n\n/** Restricts document content based on access-control expressions ($$DESCEND, $$PRUNE, $$KEEP).\n * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/redact/ */\nexport const $redact = pushStage(expression => ({\n $redact: resolveStage(expression),\n})) as unknown as {\n // Overload 1: Callback returning redact action\n <C>(\n expression: ($: ExprBuilder<Simplify<C>>) => Ret<C, \"$$DESCEND\" | \"$$PRUNE\" | \"$$KEEP\">,\n ): <TIn>(agg: Agg<TIn, C>) => Agg<TIn, C>;\n // Overload 2: Literal or expression value\n <\n C,\n const T extends \"$$DESCEND\" | \"$$PRUNE\" | \"$$KEEP\" | Ret<C, \"$$DESCEND\" | \"$$PRUNE\" | \"$$KEEP\">,\n >(\n expression: T,\n ): <TIn>(agg: Agg<TIn, C>) => Agg<TIn, C>;\n};\n\n/** Replaces the input document with the specified document (via `newRoot`).\n * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/replaceRoot/ */\nexport const $replaceRoot = pushStage((options: unknown) => {\n const resolved = resolveStage(options);\n // If resolved value has 'newRoot' property, use it as-is (options overloads)\n // Otherwise, wrap it in newRoot (expression overloads)\n const spec =\n resolved !== null && typeof resolved === \"object\" && \"newRoot\" in resolved ?\n resolved\n : { newRoot: resolved };\n return { $replaceRoot: spec };\n}) as unknown as {\n <C, const T extends { newRoot: ReplaceRootValue<C> }>(\n options: T,\n ): UpdateStageFunction<C, ReplaceRootResolved<C, T[\"newRoot\"]>>;\n <C, const T extends { newRoot: ReplaceRootValue<Simplify<C>> }>(\n options: ($: ExprBuilder<Simplify<C>>) => T,\n ): UpdateStageFunction<C, ReplaceRootResolved<C, T[\"newRoot\"]>>;\n <C, const T extends ReplaceRootValue<C>>(\n expression: T,\n ): UpdateStageFunction<C, ReplaceRootResolved<C, T>>;\n <C, const T extends ReplaceRootValue<Simplify<C>>>(\n expression: ($: ExprBuilder<Simplify<C>>) => T,\n ): UpdateStageFunction<C, ReplaceRootResolved<C, T>>;\n};\n\n/** Replaces the input document with the specified expression. Shorthand for `$replaceRoot`.\n * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/replaceWith/ */\nexport const $replaceWith = pushStage(expression => ({\n $replaceWith: resolveStage(expression),\n})) as unknown as {\n <C, const T extends ReplaceRootValue<C>>(\n expression: T,\n ): UpdateStageFunction<C, ReplaceRootResolved<C, T>>;\n <C, const T extends ReplaceRootValue<Simplify<C>>>(\n expression: ($: ExprBuilder<Simplify<C>>) => T,\n ): UpdateStageFunction<C, ReplaceRootResolved<C, T>>;\n};\n\n/** Randomly selects the specified number of documents from input.\n * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/sample/ */\nexport const $sample = pushStage(options => ({ $sample: resolveStage(options) })) as unknown as <\n C,\n const T extends number,\n>(options: {\n size: T;\n}) => <TIn>(agg: Agg<TIn, C>) => Agg<TIn, C>;\n\n/** Adds new fields to documents. Alias for `$addFields`.\n * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/set/ */\nexport const $set = pushStage(fields => ({ $set: resolveStage(fields) })) as unknown as {\n <C, const T extends Dict<ExpressionIn<C> | Ret<C>>>(\n fields: NoInfer<T>,\n ): UpdateStageFunction<C, Simplify<C & { [K in keyof T]: ResolveType<C, T[K]> }>>;\n <C, const T extends Dict<ExpressionIn<Simplify<C>> | Ret<Simplify<C>>>>(\n fields: ($: ExprBuilder<Simplify<C>>) => T,\n ): UpdateStageFunction<C, Simplify<C & { [K in keyof T]: ResolveType<C, T[K]> }>>;\n};\n\n/** Performs window function calculations across a specified span of documents.\n * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/setWindowFields/ */\nexport const $setWindowFields = pushStage(options => ({\n $setWindowFields: unwrapRet(\n typeof options === \"function\" ? options(new WindowBuilder<unknown>()) : options,\n ),\n})) as unknown as <\n C,\n const T extends {\n partitionBy?: ExpressionIn<C> | Dict<ExpressionIn<C> | Ret<C>> | Ret<C>;\n sortBy?: SortBySpec<C>;\n output: Dict<WindowOperatorSpec<C>>;\n },\n>(\n options: ($: WindowBuilder<Simplify<C>>) => WindowFieldsOptions<C, T>,\n) => <TIn>(\n agg: Agg<TIn, C>,\n) => Agg<TIn, C & { [K in keyof T[\"output\"]]: WindowOperatorResult<C, T[\"output\"][K]> }>;\n\n/** Skips the first N documents.\n * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/skip/ */\nexport const $skip = pushStage(n => ({ $skip: n })) as unknown as <C, const T extends number>(\n n: T,\n) => <TIn>(agg: Agg<TIn, C>) => Agg<TIn, C>;\n\n/** Sorts all input documents and returns them in the specified order.\n * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/sort/ */\nexport const $sort = pushStage(spec => ({ $sort: resolveStage(spec) })) as unknown as <C>(\n spec: SortSpec<C>,\n) => <TIn>(agg: Agg<TIn, C>) => Agg<TIn, C>;\n\n/** Groups documents by an expression and sorts by count.\n * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/sortByCount/ */\nexport const $sortByCount = pushStage(expression => ({\n $sortByCount: resolveStage(expression),\n})) as unknown as <C, const T extends ExpressionIn<C>>(\n expression: T,\n) => <TIn>(agg: Agg<TIn, C>) => Agg<TIn, SortByCountResult<ResolveType<C, T>>>;\n\n/** Combines pipeline results from another collection into the current pipeline.\n * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/unionWith/ */\nexport const $unionWith = pushStage((options: { coll: Collection } & Dict<unknown>) => {\n const spec: Dict<unknown> & { coll: string; pipeline?: unknown } = {\n ...options,\n coll: options.coll.__collectionName,\n };\n if (typeof spec.pipeline === \"function\") {\n spec.pipeline = resolveStage(spec.pipeline);\n }\n if (spec.pipeline && typeof spec.pipeline === \"object\" && \"stages\" in spec.pipeline) {\n const pipeline = spec.pipeline as { stages?: unknown };\n if (typeof pipeline.stages !== \"undefined\") {\n spec.pipeline = pipeline.stages;\n }\n }\n return { $unionWith: spec };\n}) as unknown as <\n C,\n const T extends {\n coll: Collection;\n pipeline?:\n | TypedPipeline<ForeignType<T[\"coll\"]>, __>\n | readonly ((agg: Agg<ForeignType<T[\"coll\"]>, ForeignType<T[\"coll\"]>>) => any)[];\n },\n>(\n options: T,\n) => <TIn>(agg: Agg<TIn, C>) => Agg<TIn, C | ForeignType<T[\"coll\"]>>;\n\n/** Removes specified fields from documents.\n * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/unset/ */\nexport const $unset = ((...fields: unknown[]) =>\n (agg: RuntimeAgg) => ({\n ...agg,\n stages: [...(agg.stages ?? []), { $unset: fields.length === 1 ? fields[0] : fields }],\n })) as unknown as <C, const T extends readonly (keyof C & string)[]>(\n ...fields: T\n) => UpdateStageFunction<C, UnsetResult<C, T extends readonly string[] ? [...T] : never>>;\n\n/** Deconstructs an array field, outputting one document per array element.\n * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/unwind/ */\nexport const $unwind = pushStage(pathOrOptions => ({\n $unwind: resolveStage(pathOrOptions),\n})) as unknown as {\n // Simple string path overload\n <C, const P extends `$${ArrayRootPath<C>}`>(\n path: P,\n ): <TIn>(agg: Agg<TIn, C>) => Agg<TIn, UnwindResult<C, P>>;\n\n // Options object overload\n <\n C,\n const P extends `$${ArrayRootPath<C>}`,\n const TPreserve extends boolean | undefined = undefined,\n const TIndexField extends string | undefined = undefined,\n >(options: {\n path: P;\n includeArrayIndex?: TIndexField;\n preserveNullAndEmptyArrays?: TPreserve;\n }): <TIn>(\n agg: Agg<TIn, C>,\n ) => Agg<\n TIn,\n UnwindResultWithPreserve<C, P, TPreserve> &\n (TIndexField extends string ? Record<TIndexField, number> : {})\n >;\n};\n\n// ==========================================\n// Missing Stages Implementation\n// ==========================================\n\ntype SanitizeAny<T> =\n IsAny<T> extends true ? never\n : IsUnknown<T> extends true ? never\n : T extends Date ? T\n : T extends readonly (infer E)[] ? readonly SanitizeAny<E>[]\n : T extends object ? { [K in keyof T]: SanitizeAny<T[K]> }\n : T;\n\ntype ChangeStreamDocumentSafe<T extends Document> = SanitizeAny<ChangeStreamDocument<T>>;\n\n/** Opens a change stream cursor on a collection. Must be the first stage.\n * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/changeStream/ */\nexport const $changeStream = pushStage(options => ({\n $changeStream: resolveStage(options),\n})) as unknown as <\n C extends Document,\n const T extends {\n allChangesForCluster?: boolean;\n fullDocument?: \"default\" | \"required\" | \"updateLookup\" | \"whenAvailable\";\n fullDocumentBeforeChange?: \"off\" | \"whenAvailable\" | \"required\";\n resumeAfter?: AnyDict;\n startAfter?: AnyDict;\n startAtOperationTime?: Date;\n showExpandedEvents?: boolean;\n },\n>(\n options: NoInfer<T>,\n) => <TIn>(agg: Agg<TIn, C>) => Agg<TIn, Simplify<ChangeStreamDocumentSafe<C>>>;\n\n/** Returns information on active and queued operations. For `db.aggregate()` only.\n * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/currentOp/ */\nexport const $currentOp = pushStage(options => ({\n $currentOp: resolveStage(options),\n})) as unknown as <\n C,\n const T extends {\n allUsers?: boolean;\n idleConnections?: boolean;\n idleCursors?: boolean;\n idleSessions?: boolean;\n localOps?: boolean;\n },\n>(\n options: NoInfer<T>,\n) => <TIn>(agg: Agg<TIn, C>) => Agg<\n TIn,\n {\n host: string;\n desc: string;\n connectionId: number;\n client: string;\n appName?: string;\n clientMetadata?: AnyDict;\n active: boolean;\n currentOpTime: Date;\n opid: number;\n secs_running: number;\n microsecs_running: number;\n op: string;\n ns: string;\n command: AnyDict;\n planSummary?: string;\n cursor?: { cursorId: number; createdDate: Date; lastAccessDate: Date };\n lsid?: { id: ObjectId; uid: string };\n transaction?: AnyDict;\n locking?: AnyDict;\n waitingForLock?: boolean;\n msg?: string;\n progress?: { done: number; total: number };\n killPending?: boolean;\n numYields?: number;\n dataThroughputLastSecond?: number;\n dataThroughputAverage?: number;\n }\n>;\n\n/** Lists sessions cached in memory by the `mongod` or `mongos` instance.\n * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/listLocalSessions/ */\nexport declare const $listLocalSessions: <\n C,\n const T extends {\n allUsers?: boolean;\n users?: { user: string; db: string }[];\n },\n>(\n options: NoInfer<T>,\n) => <TIn>(agg: Agg<TIn, C>) => Agg<\n TIn,\n {\n _id: { id: ObjectId; uid: string };\n lastUse: Date;\n user?: { user: string; db: string };\n client?: string;\n connections?: number;\n activeTransactions?: AnyDict;\n }\n>;\n\n/** Lists all sessions stored in the `system.sessions` collection.\n * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/listSessions/ */\nexport declare const $listSessions: <\n C,\n const T extends {\n allUsers?: boolean;\n users?: { user: string; db: string }[];\n },\n>(\n options: NoInfer<T>,\n) => <TIn>(agg: Agg<TIn, C>) => Agg<\n TIn,\n {\n _id: { id: ObjectId; uid: string };\n lastUse: Date;\n user?: { user: string; db: string };\n client?: string;\n connections?: number;\n activeTransactions?: AnyDict;\n }\n>;\n\n/** Returns plan cache information for a collection.\n * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/planCacheStats/ */\nexport declare const $planCacheStats: <C>() => <TIn>(agg: Agg<TIn, C>) => Agg<\n TIn,\n {\n version: string;\n created: Date;\n planCacheKey: string;\n queryHash: string;\n planCacheKeyWithQueryHash: string;\n isActive: boolean;\n works: number;\n timeOfCreation: Date;\n timeOfCreationMicros: number;\n lastSeenDate: Date;\n lastSeenDateMicros: number;\n creationExecStats?: AnyDict;\n cachedPlan?: AnyDict;\n winningPlan?: AnyDict;\n candidatePlans?: AnyDict[];\n }\n>;\n\n/** Returns data distribution information for sharded collections.\n * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/shardedDataDistribution/ */\nexport declare const $shardedDataDistribution: <C>() => <TIn>(agg: Agg<TIn, C>) => Agg<\n TIn,\n {\n ns: string;\n shards: Record<\n string,\n {\n numOrphanedDocs: number;\n numOwnedDocuments: number;\n ownedSizeBytes: number;\n orphanedSizeBytes: number;\n }\n >;\n numShards: number;\n collections: Record<\n string,\n {\n numOrphanedDocs: number;\n numOwnedDocuments: number;\n ownedSizeBytes: number;\n orphanedSizeBytes: number;\n }\n >;\n totalSizeBytes: number;\n totalOrphanedSizeBytes: number;\n totalOwnedSizeBytes: number;\n totalNumOrphanedDocs: number;\n totalNumOwnedDocuments: number;\n }\n>;\n\n// Atlas-only stages (commented out as not available in standard MongoDB)\n// export declare const $search: <C, const T extends { ... }> => ...\n// export declare const $searchMeta: <C, const T extends { ... }> => ...\n// export declare const $vectorSearch: <C, const T extends { ... }> => ...\n","/**\n * Update pipeline stages - unified with aggregation pipeline stages\n *\n * All stages are imported from sluice-stages.ts for single source of truth.\n * Update pipelines use the exact same StageFunction types as aggregation pipelines.\n */\n\nimport type {\n TypedPipeline,\n UpdatePipelineBuilder,\n UpdateStageFunction,\n} from \"../../../pipeline-types.js\";\nimport type { Agg } from \"../../../sluice.js\";\nimport {\n $addFields,\n $project,\n $replaceRoot,\n $replaceWith,\n $set,\n $unset,\n} from \"../../../sluice-stages.js\";\n\n/**\n * Type for the context-aware update operators passed as `$` to update pipeline callbacks.\n *\n * Members are named without the `$` prefix so callback usage reads naturally:\n * `$ => $.pipe($.set(...), $.unset(...))`\n */\nexport type UpdateOperators<C> = {\n set: typeof $set;\n unset: typeof $unset;\n replaceRoot: typeof $replaceRoot;\n replaceWith: typeof $replaceWith;\n addFields: typeof $addFields;\n project: typeof $project;\n pipe: UpdatePipelineBuilder<C>;\n};\n\n/**\n * Callback type for update pipelines that receives context-aware operators\n */\nexport type UpdatePipelineCallback<C> = ($: UpdateOperators<C>) => TypedPipeline<C, unknown>;\n\n/**\n * Creates context-aware update pipeline operators for a collection type.\n * Used internally by `updateOne`/`updateMany` to build the `$` callback context.\n */\nexport const update = <C>(): UpdateOperators<C> => {\n const pipe = (...stages: UpdateStageFunction<unknown, unknown>[]): TypedPipeline<C, unknown> => {\n const fakeAgg: Agg<C, unknown> = {\n _in: undefined as never,\n _current: undefined as never,\n stages: [] as object[],\n pipe: undefined as never,\n toList: undefined as never,\n toMQL: undefined as never,\n };\n const result = stages.reduce((agg, stage) => stage(agg), fakeAgg);\n return {\n __pipelineIn: undefined as unknown as C,\n __pipelineOut: undefined as unknown,\n stages: result.stages,\n };\n };\n\n return {\n set: $set,\n unset: $unset,\n replaceRoot: $replaceRoot,\n replaceWith: $replaceWith,\n addFields: $addFields,\n project: $project,\n pipe: pipe as unknown as UpdatePipelineBuilder<C>,\n };\n};\n","import type {\n AnyBulkWriteOperation,\n BulkWriteOptions,\n Collection as MongoCollection,\n CountDocumentsOptions,\n Db,\n Document,\n Filter,\n FindOneAndDeleteOptions,\n FindOneAndReplaceOptions,\n FindOneAndUpdateOptions,\n FindOneOptions,\n ReplaceOptions,\n Sort,\n UpdateOptions,\n} from \"mongodb\";\n\nimport type { CrudCollection, FindOptions } from \"./crud.js\";\nimport { update } from \"./crud/updates/stages/index.js\";\nimport type { AggregateBuilder } from \"./pipeline-types.js\";\nimport type { Dict, SimplifyWritable } from \"./type-utils.js\";\n\n// ==========================================\n// Schema-Agnostic Interface\n// ==========================================\n\n/**\n * A schema-like object from which a document TypeScript type can be extracted.\n *\n * Compatible with:\n * - **Zod**: `z.object({ name: z.string() })` → inferred via `_output`\n * - **Effect Schema**: `Schema.Struct({ name: Schema.String })` → inferred via `Type`\n * - **Plain type marker**: `{ Type: MyType }` for manual schemas\n *\n * @example\n * ```ts\n * import { z } from \"zod\";\n * const UserSchema = z.object({ name: z.string(), age: z.number() });\n * const reg = registry(\"8.0\", { users: UserSchema });\n * ```\n */\nexport type SchemaLike =\n | { readonly Type: Dict<unknown> } // Effect Schema\n | { readonly _output: Dict<unknown> } // Zod\n | { readonly [schemaTypeKey]: Dict<unknown> }; // Custom adapter\n\ndeclare const schemaTypeKey: unique symbol;\n\n/** Extract the inferred document type from a SchemaLike */\nexport type InferSchema<S extends SchemaLike> =\n S extends { readonly Type: infer T extends Dict<unknown> } ? T\n : S extends { readonly _output: infer T extends Dict<unknown> } ? T\n : S extends { readonly [schemaTypeKey]: infer T extends Dict<unknown> } ? T\n : Dict<unknown>;\n\ntype MongoVersions = [\"4.2\", \"4.4\", \"5.0\", \"5.1\", \"6.0\", \"6.1\", \"7.0\", \"7.1\", \"8.0\"];\n\n/**\n * Collection type that carries both name and schema information\n * Used for type-safe collection references in $lookup, $unionWith, etc.\n */\nexport type Collection<\n TName extends string = string,\n TSchema extends Dict<unknown> = Dict<unknown>,\n> = {\n readonly __collectionName: TName;\n readonly __collectionType: SimplifyWritable<TSchema>;\n};\n\nexport type CollectionType<T extends Collection> = T[\"__collectionType\"];\n\nexport type BoundCollection<TName extends string, TSchema extends Dict<unknown>> = Collection<\n TName,\n TSchema\n> & {\n aggregate: AggregateBuilder<SimplifyWritable<TSchema>>;\n} & CrudCollection<SimplifyWritable<TSchema>>;\n\n// ==========================================\n// CRUD Runtime Implementation\n// ==========================================\n\n/**\n * Creates CRUD methods for a collection - no proxies, direct implementation\n */\nfunction createCrudMethods<T extends Document>(mongoCol: MongoCollection<T>): CrudCollection<T> {\n // Helper to extract filter from callback - runtime only, types handled by interface\n const extractFilter = (filterFn: unknown): Filter<T> => {\n if (!filterFn) return {} as Filter<T>;\n // The callback returns a MongoDB filter document directly\n return (filterFn as ($: unknown) => unknown)({}) as Filter<T>;\n };\n\n return {\n find: ((filterFn?: unknown, options?: FindOptions<T>) => ({\n _filter: filterFn ? extractFilter(filterFn) : undefined,\n _options: options,\n toList: () => {\n const filter = filterFn ? extractFilter(filterFn) : {};\n let cursor = mongoCol.find(filter as Filter<T>);\n if (options?.sort) cursor = cursor.sort(options.sort as Sort);\n if (options?.skip) cursor = cursor.skip(options.skip);\n if (options?.limit) cursor = cursor.limit(options.limit);\n if (options?.projection) cursor = cursor.project(options.projection);\n if (options?.hint) cursor = cursor.hint(options.hint as string);\n if (options?.maxTimeMS) cursor = cursor.maxTimeMS(options.maxTimeMS);\n if (options?.collation) cursor = cursor.collation(options.collation);\n if (options?.comment) cursor = cursor.comment(options.comment);\n return cursor.toArray() as unknown as Promise<T[]>;\n },\n toOne: async () => {\n const filter = filterFn ? extractFilter(filterFn) : {};\n return mongoCol.findOne(\n filter as Filter<T>,\n options as FindOneOptions,\n ) as unknown as Promise<T | null>;\n },\n })) as CrudCollection<T>[\"find\"],\n\n findOne: ((filterFn?: unknown, options?: FindOptions<T>) => ({\n _filter: filterFn ? extractFilter(filterFn) : undefined,\n _options: options,\n toList: async () => {\n const doc = await mongoCol.findOne(\n filterFn ? extractFilter(filterFn) : ({} as Filter<T>),\n options as FindOneOptions,\n );\n return doc ? [doc as T] : [];\n },\n toOne: () =>\n mongoCol.findOne(\n filterFn ? extractFilter(filterFn) : ({} as Filter<T>),\n options as FindOneOptions,\n ) as unknown as Promise<T | null>,\n })) as CrudCollection<T>[\"findOne\"],\n\n insertOne: doc => ({\n _doc: doc,\n execute: () => mongoCol.insertOne(doc as never),\n }),\n\n insertMany: docs => ({\n _docs: docs,\n execute: () => mongoCol.insertMany(docs as never[]),\n }),\n\n updateOne: ((\n filterFn: unknown,\n updateArg: unknown,\n options?: { upsert?: boolean; hint?: unknown; arrayFilters?: unknown },\n ) => {\n const filter = extractFilter(filterFn);\n // Resolve the update: callback returns TypedPipeline, or update spec object\n const updateDoc =\n typeof updateArg === \"function\" ?\n // Callback form: invoke with operators, get stages from TypedPipeline\n (updateArg(update()) as { stages: readonly object[] }).stages\n : updateArg;\n\n return {\n _filter: filter,\n _update: updateDoc,\n _options: options,\n execute: () => mongoCol.updateOne(filter, updateDoc as Document, options as UpdateOptions),\n };\n }) as CrudCollection<T>[\"updateOne\"],\n\n updateMany: ((\n filterFn: unknown,\n updateArg: unknown,\n options?: { upsert?: boolean; hint?: unknown; arrayFilters?: unknown },\n ) => {\n const filter = extractFilter(filterFn);\n // Resolve the update: callback returns TypedPipeline, or update spec object\n const updateDoc =\n typeof updateArg === \"function\" ?\n // Callback form: invoke with operators, get stages from TypedPipeline\n (updateArg(update()) as { stages: readonly object[] }).stages\n : updateArg;\n\n return {\n _filter: filter,\n _update: updateDoc,\n _options: options,\n execute: () => mongoCol.updateMany(filter, updateDoc as Document, options as UpdateOptions),\n };\n }) as CrudCollection<T>[\"updateMany\"],\n\n replaceOne: ((filterFn: unknown, replacement: T, options?: unknown) => ({\n _filter: extractFilter(filterFn),\n _replacement: replacement,\n _options: options,\n execute: () =>\n mongoCol.replaceOne(\n extractFilter(filterFn),\n replacement as never,\n options as ReplaceOptions,\n ),\n })) as CrudCollection<T>[\"replaceOne\"],\n\n deleteOne: ((filterFn: unknown) => ({\n _filter: extractFilter(filterFn),\n execute: () => mongoCol.deleteOne(extractFilter(filterFn)),\n })) as CrudCollection<T>[\"deleteOne\"],\n\n deleteMany: ((filterFn: unknown) => ({\n _filter: extractFilter(filterFn),\n execute: () => mongoCol.deleteMany(extractFilter(filterFn)),\n })) as CrudCollection<T>[\"deleteMany\"],\n\n findOneAndDelete: ((\n filterFn: unknown,\n options?: {\n sort?: unknown;\n projection?: unknown;\n returnDocument?: string;\n hint?: unknown;\n collation?: unknown;\n maxTimeMS?: number;\n comment?: string;\n },\n ) => ({\n _filter: extractFilter(filterFn),\n execute: () =>\n mongoCol\n .findOneAndDelete(extractFilter(filterFn), options as FindOneAndDeleteOptions)\n .then(r => r as T | null),\n })) as CrudCollection<T>[\"findOneAndDelete\"],\n\n findOneAndReplace: ((\n filterFn: unknown,\n replacement: T,\n options?: {\n sort?: unknown;\n projection?: unknown;\n upsert?: boolean;\n returnDocument?: string;\n hint?: unknown;\n collation?: unknown;\n maxTimeMS?: number;\n comment?: string;\n },\n ) => ({\n _filter: extractFilter(filterFn),\n _replacement: replacement,\n execute: () =>\n mongoCol\n .findOneAndReplace(\n extractFilter(filterFn),\n replacement as never,\n options as FindOneAndReplaceOptions,\n )\n .then(r => r as T | null),\n })) as CrudCollection<T>[\"findOneAndReplace\"],\n\n findOneAndUpdate: ((\n filterFn: unknown,\n updateArg: unknown,\n options?: {\n sort?: unknown;\n projection?: unknown;\n upsert?: boolean;\n returnDocument?: string;\n arrayFilters?: unknown;\n hint?: unknown;\n collation?: unknown;\n maxTimeMS?: number;\n comment?: string;\n },\n ) => ({\n _filter: extractFilter(filterFn),\n _update: updateArg,\n execute: () =>\n mongoCol\n .findOneAndUpdate(\n extractFilter(filterFn),\n updateArg as Document,\n options as FindOneAndUpdateOptions,\n )\n .then(r => r as T | null),\n })) as CrudCollection<T>[\"findOneAndUpdate\"],\n\n countDocuments: ((\n filterFn?: unknown,\n options?: {\n limit?: number;\n skip?: number;\n maxTimeMS?: number;\n hint?: unknown;\n collation?: unknown;\n comment?: string;\n },\n ) => ({\n execute: () =>\n mongoCol.countDocuments(\n filterFn ? extractFilter(filterFn) : {},\n options as CountDocumentsOptions,\n ),\n })) as CrudCollection<T>[\"countDocuments\"],\n\n estimatedDocumentCount: () => ({\n execute: () => mongoCol.estimatedDocumentCount(),\n }),\n\n distinct: ((field: string, filterFn?: unknown) => ({\n execute: () =>\n mongoCol.distinct(field, filterFn ? extractFilter(filterFn) : ({} as Filter<T>)),\n })) as CrudCollection<T>[\"distinct\"],\n\n bulkWrite: ((operations: readonly unknown[], options?: { ordered?: boolean }) => ({\n _operations: operations,\n execute: () =>\n mongoCol.bulkWrite(operations as AnyBulkWriteOperation<T>[], options as BulkWriteOptions),\n })) as unknown as CrudCollection<T>[\"bulkWrite\"],\n };\n}\n\n// ==========================================\n// Collection Helper Function\n// ==========================================\n\n/**\n * Creates a bound collection with type-safe aggregate and CRUD methods.\n *\n * Wraps a MongoDB native collection with schema-aware operations.\n * Typically called indirectly via {@link registry} rather than directly.\n *\n * @example\n * ```ts\n * const users = collection(\"users\", userSchema, db.collection(\"users\"));\n * const result = await users.aggregate($match($ => ({ age: $.gte(18) }))).toList();\n * ```\n */\nexport const collection = <TName extends string, TSchema extends SchemaLike>(\n name: TName,\n _schema: TSchema,\n mongoCol: MongoCollection<SimplifyWritable<InferSchema<TSchema>>>,\n): BoundCollection<TName, InferSchema<TSchema>> => {\n const col: Collection<TName, InferSchema<TSchema>> = {\n __collectionName: name,\n __collectionType: {} as SimplifyWritable<InferSchema<TSchema>>,\n };\n\n const crud = createCrudMethods(mongoCol);\n\n return Object.assign(col, {\n aggregate: ((...stages: unknown[]) => {\n let agg = { collectionName: name, stages: [] };\n for (const s of stages) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-function-type\n agg = (s as Function)(agg);\n }\n \n return {\n ...agg,\n // eslint-disable-next-line custom/aggregate-must-tolist\n toList: () => mongoCol.aggregate(agg.stages as Document[]).toArray(),\n toMQL: () => JSON.stringify(agg.stages, null, 2),\n };\n }) as unknown as AggregateBuilder<SimplifyWritable<InferSchema<TSchema>>>,\n ...crud,\n });\n};\n\n// ==========================================\n// Registry Function\n// ==========================================\n\n/**\n * Creates a type-safe registry of MongoDB collections from schema definitions.\n *\n * Returns a factory that binds schemas to a `Db` instance, producing\n * collections with fully-typed aggregation pipelines and CRUD operations.\n *\n * @example\n * ```ts\n * const db = registry(\"8.0\", {\n * users: userSchema,\n * orders: orderSchema,\n * })(client.db(\"mydb\"));\n *\n * const result = await db.users.aggregate(\n * $match($ => ({ active: true })),\n * $project($ => ({ name: 1 })),\n * ).toList();\n * ```\n */\nexport const registry =\n <const TMap extends Dict<SchemaLike>, const TVersion extends MongoVersions[number]>(\n version: TVersion, // For later on when we have to deal with version-specific features\n schemas: { [K in keyof TMap]: TMap[K] },\n ) =>\n (client: Db): { [K in keyof TMap]: BoundCollection<K & string, InferSchema<TMap[K]>> } => {\n const bind = <TName extends string, TSchema extends SchemaLike>(\n name: TName,\n schema: TSchema,\n ): BoundCollection<TName, InferSchema<TSchema>> =>\n collection(name, schema, client.collection<SimplifyWritable<InferSchema<TSchema>>>(name));\n\n return Object.fromEntries(\n Object.entries(schemas).map(([name, schema]) => [name, bind(name, schema)]),\n ) as unknown as { [K in keyof TMap]: BoundCollection<K & string, InferSchema<TMap[K]>> };\n };\n"],"mappings":";;;;;AACO,IAAM,mBAAmB,CAAC,OAAyB;AACxD,QAAM,QAAQ,GAAG,SAAS;AAE1B,MAAI,CAAC,MAAM,SAAS,IAAI,EAAG,QAAO;AAGlC,QAAM,aAAa,8BAA8B,KAAK,KAAK;AAC3D,MAAI,CAAC,WAAY,OAAM,IAAI,MAAM,2CAA2C,KAAK,EAAE;AAEnF,QAAM,SAAS,WAAW,CAAC,KAAK,WAAW,CAAC;AAE5C,QAAM,aAAa,MAAM,QAAQ,IAAI;AACrC,QAAM,OAAO,MAAM,MAAM,aAAa,CAAC,EAAE,KAAK;AAG9C,QAAM,WAAW,KAAK,WAAW,GAAG;AACpC,SAAO,WAAW,YAAY,MAAM,KAAK,IAAI,KAAK,YAAY,MAAM,cAAc,IAAI;AACxF;AAgBO,IAAM,qBAAqB,CAKhC,WACG;AACH,QAAM,SAAS;AAAA,IACb,MAAM,iBAAiB,OAAO,IAAI;AAAA,IAClC,UAAU,OAAO;AAAA,IACjB,YAAY,iBAAiB,OAAO,UAAU;AAAA,IAC9C,gBAAgB,OAAO;AAAA,IACvB,OAAO,iBAAiB,OAAO,KAAK;AAAA,IACpC,MAAM,OAAO;AAAA,EACf;AAEA,SAAO,OAAO,WAAW,EAAE,GAAG,QAAQ,UAAU,iBAAiB,OAAO,QAAQ,EAAE,IAAI;AACxF;;;AClDA,SAA0B,gBAAgB;AAwSnC,IAAM,MAAN,MAA8C;AAAA,EAKnD,YACW,MACA,eAAe,IACxB;AAFS;AACA;AANX,wBAAS;AACT,wBAAS;AACT,wBAAS,SAAQ;AAAA,EAKd;AACL;AAIO,IAAM,cAAN,MAA8D;AAAA,EAA9D;AAgBL;AAAA,wBAAU,MACR,CAAC,OACD,CAAC,QACC,IAAI,IAAI,EAAE,CAAC,IAAI,EAAE,EAAE,GAAG,KAAK,SAAS,GAAG,EAAE,CAAC;AAG9C;AAAA,wBAAU,WACR,CAAC,OACD,IAAI,SACF,IAAI,IAAI,EAAE,CAAC,IAAI,EAAE,EAAE,GAAG,KAAK,IAAI,SAAO,KAAK,SAAS,GAAG,CAAC,EAAE,CAAC;AAG/D;AAAA,wBAAU,YACR,CAAC,OACD,IAAI,SACF,IAAI,IAAI;AAAA,MACN,CAAC,IAAI,EAAE,EAAE,GAAG,KAAK,WAAW,IAAI,KAAK,SAAS,KAAK,CAAC,CAAC,IAAI,KAAK,IAAI,KAAK,SAAS,KAAK,IAAI,CAAC;AAAA,IAC5F,CAAC;AAGL;AAAA,wBAAU,WACR,CAAC,OACD,CAAC,YACC,IAAI,IAAI,EAAE,CAAC,IAAI,EAAE,EAAE,GAAG,KAAK,SAAS,OAAO,EAAE,CAAC;AAGlD;AAAA,wBAAU,WAAU,CAAC,OAAe,MAAc,IAAI,IAAI,EAAE,CAAC,IAAI,EAAE,EAAE,GAAG,CAAC,EAAE,CAAC;AAG5E;AAAA,iCAA4B,IAAI,WAC9B,OAAO,OAAO,CAAC,KAAiB,YAAY,QAAQ,GAAG,GAAG;AAAA,MACxD,QAAQ,CAAC;AAAA,IACX,CAAC;AAGH;AAAA,qCAAY,CAAU,YAAmE;AAAA,MACvF,YAAY,OAAO,IAAI,YAAe,CAAC;AAAA,IACzC;AAOA;AAAA;AAAA;AAAA;AAAA,+BAAgB,KAAK,QAAQ,KAAK;AAGlC;AAAA,oCAA0B,KAAK,QAAQ,UAAU;AAGjD;AAAA,oCAAgC,KAAK,QAAQ,UAAU;AAGvD;AAAA,kCAA6B,KAAK,QAAQ,QAAQ;AAGlD;AAAA,+BAA0B,KAAK,QAAQ,KAAK;AAG5C;AAAA,+BAAyB,KAAK,GAAG,KAAK;AAGtC;AAAA,gCAA0B,KAAK,GAAG,MAAM;AAGxC;AAAA,iCAA2B,KAAK,GAAG,OAAO;AAG1C;AAAA,8BAAwB,KAAK,GAAG,IAAI;AAGpC;AAAA,+BAA0B,KAAK,QAAQ,KAAK;AAG5C;AAAA,iCAA2B,KAAK,GAAG,OAAO;AAG1C;AAAA,+BAA0B,KAAK,QAAQ,KAAK;AAG5C;AAAA,gCAA0B,KAAK,GAAG,MAAM;AAGxC;AAAA,iCAGsB,CAAC,KAAK,UAC1B,UAAU,SAAY,KAAK,QAAQ,OAAO,EAAE,KAAK,KAAK,IAAI,KAAK,QAAQ,OAAO,EAAE,GAAG;AAGrF;AAAA,iCAGsB,CAAC,KAAK,UAC1B,UAAU,SAAY,KAAK,QAAQ,OAAO,EAAE,KAAK,KAAK,IAAI,KAAK,QAAQ,OAAO,EAAE,GAAG;AAGrF;AAAA,+BAAyB,KAAK,GAAG,KAAK;AAGtC;AAAA,gCAA6B,KAAK,QAAQ,MAAM;AAOhD;AAAA;AAAA;AAAA;AAAA,uCAG2C,KAAK,QAAQ,aAAa;AAGrE;AAAA,yCAEgE,KAAK,GAAG,eAAe;AAGvF;AAAA,wCAEqD,KAAK,QAAQ,cAAc;AAIhF;AAAA;AAAA,kCA0BI,KAAK,QAAQ,QAAQ;AAGzB;AAAA,iCAOI,KAAK,GAAG,OAAO;AAGnB;AAAA,8BAGuB,KAAK,QAAQ,IAAI;AAGxC;AAAA,wCASuB,KAAK,QAAQ,cAAc;AAGlD;AAAA,mCACE,KAAK,GAAG,SAAS;AAGnB;AAAA,gCAOI,KAAK,GAAG,MAAM;AAIlB;AAAA;AAAA,+BAqBI,KAAK,QAAQ,KAAK;AAGtB;AAAA,gCAIE,KAAK,QAAQ,MAAM;AAGrB;AAAA,gCAIE,KAAK,QAAQ,MAAM;AAGrB;AAAA,kCAIE,KAAK,QAAQ,QAAQ;AAGvB;AAAA,iCAIE,KAAK,QAAQ,OAAO;AAGtB;AAAA,yCAGE,KAAK,GAAG,eAAe;AAGzB;AAAA,iCAQwB,CAAC,OAAO,KAAK,SACnC,SAAS,SACP,KAAK,QAAQ,OAAO,EAAE,OAAO,KAAK,IAAI,IACtC,KAAK,QAAQ,OAAO,EAAE,OAAO,GAAG;AAIpC;AAAA;AAAA,kCAyBI,KAAK,QAAQ,QAAQ;AAGzB;AAAA,wCAEiC,KAAK,GAAG,cAAc;AAGvD;AAAA,gCAA8B,KAAK,GAAG,MAAM;AAG5C;AAAA,iCAIiC,CAAC,OAAO,GAAG,aAC1C,aAAa,SACX,KAAK,QAAQ,OAAO,EAAE,OAAO,GAAG,QAAQ,IACxC,KAAK,QAAQ,OAAO,EAAE,OAAO,CAAC;AAGlC;AAAA,qCAE0C,KAAK,QAAQ,WAAW;AAGlE;AAAA;AAAA,+BAgBI,KAAK,QAAQ,KAAK;AAOtB;AAAA;AAAA;AAAA;AAAA,+BAG0B,KAAK,QAAQ,KAAK;AAG5C;AAAA,8BAAsB,KAAK,QAAQ,IAAI;AAGvC;AAAA,8BAAsB,KAAK,QAAQ,IAAI;AAGvC;AAAA,+BAAuB,KAAK,QAAQ,KAAK;AAGzC;AAAA,8BAAsB,KAAK,QAAQ,IAAI;AAGvC;AAAA,+BAAuB,KAAK,QAAQ,KAAK;AAGzC;AAAA,8BAAsB,KAAK,QAAQ,IAAI;AAIvC;AAAA;AAAA,+BAA2B,KAAK,QAAQ,KAAK;AAG7C;AAAA,8BAA0B,KAAK,QAAQ,IAAI;AAG3C;AAAA,+BAA2B,KAAK,QAAQ,KAAK;AAG7C;AAAA,+BAAgF,KAAK,GAAG,KAAK;AAK7F;AAAA;AAAA;AAAA,gCAQsD,KAAK,QAAQ,MAAM;AAIzE;AAAA;AAAA,kCAE+C,KAAK,QAAQ,QAAQ;AAIpE;AAAA;AAAA,kCAMuE,KAAK,QAAQ,QAAQ;AAI5F;AAAA;AAAA,kCAEuE,KAAK,QAAQ,QAAQ;AAG5F;AAAA,wCASsB,CAAC,QAAQ,WAAW,OAAO,QAAQ;AACvD,YAAM,OAAkB,CAAC,QAAQ,SAAS;AAC1C,UAAI,UAAU,OAAW,MAAK,KAAK,KAAK;AACxC,UAAI,QAAQ,OAAW,MAAK,KAAK,GAAG;AACpC,aAAO,KAAK,QAAQ,cAAc,EAAE,GAAG,IAAI;AAAA,IAC7C;AAGA;AAAA,qCASsB,CAAC,QAAQ,WAAW,OAAO,QAAQ;AACvD,YAAM,OAAkB,CAAC,QAAQ,SAAS;AAC1C,UAAI,UAAU,OAAW,MAAK,KAAK,KAAK;AACxC,UAAI,QAAQ,OAAW,MAAK,KAAK,GAAG;AACpC,aAAO,KAAK,QAAQ,WAAW,EAAE,GAAG,IAAI;AAAA,IAC1C;AAGA;AAAA,iCAGuB,KAAK,QAAQ,OAAO;AAG3C;AAAA,qCAKE,KAAK,QAAQ,WAAW;AAG1B;AAAA,wCAIqE,KAAK,QAAQ,cAAc;AAGhG;AAAA,sCAIwB,KAAK,QAAQ,YAAY;AAGjD;AAAA,sCAIuB,KAAK,QAAQ,YAAY;AAGhD;AAAA,sCAIuB,KAAK,QAAQ,YAAY;AAGhD;AAAA,iCAGuB,KAAK,QAAQ,OAAO;AAG3C;AAAA,iCAGwB,KAAK,QAAQ,OAAO;AAG5C;AAAA,sCAAsC,KAAK,QAAQ,YAAY;AAG/D;AAAA,uCAAsC,KAAK,GAAG,aAAa;AAG3D;AAAA,oCAAmC,KAAK,GAAG,UAAU;AAGrD;AAAA,kCAIsB,KAAK,QAAQ,QAAQ;AAG3C;AAAA,uCAIsB,KAAK,QAAQ,aAAa;AAGhD;AAAA,oCAIsB,KAAK,QAAQ,UAAU;AAG7C;AAAA,mCAAkC,KAAK,GAAG,SAAS;AAGnD;AAAA,mCAAkC,KAAK,GAAG,SAAS;AAGnD;AAAA,gCAGuB,KAAK,QAAQ,MAAM;AAI1C;AAAA;AAAA,2CAAuC,KAAK,GAAG,iBAAiB;AAGhE;AAAA,0CAAsC,KAAK,GAAG,gBAAgB;AAG9D;AAAA,yCAG6C,KAAK,QAAQ,eAAe;AAGzE;AAAA,qCAEuB,KAAK,QAAQ,WAAW;AAG/C;AAAA,2CAEqD,KAAK,QAAQ,iBAAiB;AAGnF;AAAA,uCAAgC,KAAK,QAAQ,aAAa;AAG1D;AAAA,oCAEqD,KAAK,QAAQ,UAAU;AAI5E;AAAA;AAAA,mCAKqB,KAAK,QAAQ,SAAS;AAG3C;AAAA,oCAMuB,KAAK,QAAQ,UAAU;AAG9C;AAAA,yCAAoD,KAAK,QAAQ,eAAe;AAGhF;AAAA,0CAMqB,KAAK,QAAQ,gBAAgB;AAGlD;AAAA,wCAKqB,KAAK,QAAQ,cAAc;AAGhD;AAAA,uCA4BI,KAAK,QAAQ,aAAa;AAG9B;AAAA,wCAKuB,KAAK,QAAQ,cAAc;AAGlD;AAAA,qCAMqB,KAAK,QAAQ,WAAW;AAG7C;AAAA,sCAAmC,KAAK,GAAG,YAAY;AAGvD;AAAA,qCAAkC,KAAK,GAAG,WAAW;AAGrD;AAAA,qCAAkC,KAAK,GAAG,WAAW;AAGrD;AAAA,gCAA6B,KAAK,GAAG,MAAM;AAG3C;AAAA,wCAAqC,KAAK,GAAG,cAAc;AAG3D;AAAA,mCAAgC,KAAK,GAAG,SAAS;AAGjD;AAAA,uCAAoC,KAAK,GAAG,aAAa;AAGzD;AAAA,uCAAoC,KAAK,GAAG,aAAa;AAGzD;AAAA,kCAA+B,KAAK,GAAG,QAAQ;AAG/C;AAAA,iCAA8B,KAAK,GAAG,OAAO;AAG7C;AAAA,kCAA+B,KAAK,GAAG,QAAQ;AAG/C;AAAA,gCAA6B,KAAK,GAAG,MAAM;AAG3C;AAAA,gCAA6B,KAAK,GAAG,MAAM;AAI3C;AAAA;AAAA,mCAaI,KAAK,QAAQ,SAAS;AAG1B;AAAA,oCAA4C,KAAK,GAAG,UAAU;AAG9D;AAAA,kCAA0C,KAAK,GAAG,QAAQ;AAG1D;AAAA,kCAAuC,KAAK,GAAG,QAAQ;AAGvD;AAAA,qCAAgD,KAAK,GAAG,WAAW;AAGnE;AAAA,oCAA2C,KAAK,GAAG,UAAU;AAG7D;AAAA,iCAAwC,KAAK,GAAG,OAAO;AAGvD;AAAA,kCAAyC,KAAK,GAAG,QAAQ;AAGzD;AAAA,sCAA+C,KAAK,GAAG,YAAY;AAGnE;AAAA,oCAA2C,KAAK,GAAG,UAAU;AAG7D;AAAA,gCA0BI,KAAK,GAAG,MAAM;AAIlB;AAAA;AAAA,oCAUI,aACF,OAAO,YAAY,WAAW,KAAK,GAAG,UAAU,EAAE,OAAO,IAAI,KAAK,QAAQ,UAAU,EAAE,OAAO;AAG/F;AAAA,wCAkBI,KAAK,SAAS,cAAc;AAGhC;AAAA,oCAQiE,KAAK,QAAQ,UAAU;AAGxF;AAAA,sCAG2C,KAAK,QAAQ,YAAY;AAKpE;AAAA;AAAA;AAAA,+BAMmE,KAAK,QAAQ,KAAK;AAKrF;AAAA;AAAA;AAAA,mCAA4C,KAAK,GAAG,SAAS;AAI7D;AAAA;AAAA,gCASI,KAAK,GAAG,MAAM;AAGlB;AAAA,sCACE,KAAK,GAAG,YAAY;AAGtB;AAAA,sCAA6C,KAAK,GAAG,YAAY;AAGjE;AAAA,oCAA2C,KAAK,GAAG,UAAU;AAI7D;AAAA;AAAA,kCAA8B,KAAK,QAAQ,QAAQ;AAGnD;AAAA,iCAA6B,KAAK,QAAQ,OAAO;AAGjD;AAAA,kCAA8B,KAAK,QAAQ,QAAQ;AAGnD;AAAA,kCAA4B,KAAK,GAAG,QAAQ;AAG5C;AAAA;AAAA,+BAAyB,KAAK,GAAG,KAAK;AAGtC;AAAA,+BAAyB,KAAK,GAAG,KAAK;AAGtC;AAAA,+BAAyB,KAAK,GAAG,KAAK;AAGtC;AAAA,gCAA0B,KAAK,GAAG,MAAM;AAGxC;AAAA,gCAA0B,KAAK,GAAG,MAAM;AAGxC;AAAA,gCAA0B,KAAK,GAAG,MAAM;AAGxC;AAAA,iCAA4B,KAAK,QAAQ,OAAO;AAGhD;AAAA,iCAA2B,KAAK,GAAG,OAAO;AAG1C;AAAA,iCAA2B,KAAK,GAAG,OAAO;AAG1C;AAAA,iCAA2B,KAAK,GAAG,OAAO;AAG1C;AAAA,gCAA0B,KAAK,GAAG,MAAM;AAGxC;AAAA,gCAA0B,KAAK,GAAG,MAAM;AAGxC;AAAA,gCAA0B,KAAK,GAAG,MAAM;AAGxC;AAAA,4CAAsC,KAAK,GAAG,kBAAkB;AAGhE;AAAA,4CAAsC,KAAK,GAAG,kBAAkB;AAKhE;AAAA;AAAA;AAAA,+BAGI,KAAK,SAAS,KAAK;AAGvB;AAAA,+BAOI,KAAK,SAAS,KAAK;AAGvB;AAAA,+BAOI,KAAK,SAAS,KAAK;AAGvB;AAAA,+BAOI,KAAK,SAAS,KAAK;AAGvB;AAAA,qCAOI,KAAK,SAAS,WAAW;AAG7B;AAAA,sCAOI,KAAK,SAAS,YAAY;AAAA;AAAA;AAAA,EAj+B9B,SAAS,OAAyB;AAChC,UAAM,OAAO;AACb,QAAI,gBAAgB,IAAK,QAAO,KAAK,SAAS,KAAK,IAAI;AACvD,QAAI,OAAO,SAAS,WAAY,QAAO,KAAK,SAAS,KAAK,IAAI,CAAC;AAC/D,QAAI,MAAM,QAAQ,IAAI,EAAG,QAAO,KAAK,IAAI,UAAQ,KAAK,SAAS,IAAI,CAAC;AACpE,QAAI,gBAAgB,KAAM,QAAO;AACjC,QAAI,gBAAgB,SAAU,QAAO;AACrC,QAAI,gBAAgB,OAAQ,QAAO;AACnC,QAAI,OAAO,SAAS,YAAY,SAAS,KAAM,QAAO;AAEtD,WAAO,OAAO,QAAQ,IAAI,EAAE,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,KAAK,CAAC,CAAC,GAAG,KAAK,SAAS,CAAC,EAAE,IAAI,CAAC,CAAC;AAAA,EAC7F;AAu9BF;AASO,IAAM,cAAN,cAA6B,YAAe;AAAA,EAA5C;AAAA;AAEL;AAAA,wBAAS,WAAU;AAEnB;AAAA,wBAAS,WAAU;AAAA;AACrB;AAGO,IAAM,qBAAN,cAAoC,YAA8B;AAAA,EAAlE;AAAA;AAEL;AAAA,oCACE,KAAK,GAAG,UAAU;AAGpB;AAAA,iCAAqE,KAAK,QAAQ,OAAO;AAIzF;AAAA;AAAA,gCACE,KAAK,GAAG,MAAM;AAGhB;AAAA,kCAGwC,KAAK,QAAQ,QAAQ;AAG7D;AAAA,mCAQ0C,KAAK,QAAQ,SAAS;AAGhE;AAAA,+BAGkC,KAAK,QAAQ,KAAK;AAGpD;AAAA,gCAQoC,KAAK,QAAQ,MAAM;AAGvD;AAAA,uCA2DI,CAAC,YACH,KAAK,QAAQ,aAAa,EAAE,mBAAmB,OAAO,CAAC;AAGzD;AAAA,kCAGuB,KAAK,QAAQ,QAAQ;AAG5C;AAAA,sCAI2C,KAAK,QAAQ,YAAY;AAAA;AACtE;AAGO,IAAM,gBAAN,cAA+B,mBAAsB;AAAA,EAArD;AAAA;AAGL;AAAA;AAAA,qCAAkC,KAAK,QAAQ,WAAW;AAG1D;AAAA,yCAG6B,KAAK,QAAQ,eAAe;AAGzD;AAAA,0CAG6B,KAAK,QAAQ,gBAAgB;AAG1D;AAAA,sCAIuB,aAAW;AAChC,YAAM,WAAW,KAAK,SAAS,OAAO;AACtC,UAAI,YAAY,UAAU;AACxB,cAAM,EAAE,QAAQ,GAAG,aAAa,IAAI;AACpC,eAAO,IAAI,IAAI,EAAE,aAAa,cAAc,OAAO,CAAC;AAAA,MACtD;AACA,aAAO,IAAI,IAAI,EAAE,aAAa,SAAS,CAAC;AAAA,IAC1C;AAGA;AAAA,0CAAuC,KAAK,QAAQ,gBAAgB;AAGpE;AAAA,wCAKuB,aAAW;AAChC,YAAM,WAAW,KAAK,SAAS,OAAO;AACtC,UAAI,YAAY,UAAU;AACxB,cAAM,EAAE,QAAQ,GAAG,aAAa,IAAI;AACpC,eAAO,IAAI,IAAI,EAAE,eAAe,cAAc,OAAO,CAAC;AAAA,MACxD;AACA,aAAO,IAAI,IAAI,EAAE,eAAe,SAAS,CAAC;AAAA,IAC5C;AAGA;AAAA,oCAIuB,aAAW;AAChC,YAAM,WAAW,KAAK,SAAS,OAAO;AACtC,UAAI,YAAY,UAAU;AACxB,cAAM,EAAE,QAAQ,GAAG,aAAa,IAAI;AACpC,eAAO,IAAI,IAAI,EAAE,WAAW,cAAc,OAAO,CAAC;AAAA,MACpD;AACA,aAAO,IAAI,IAAI,EAAE,WAAW,SAAS,CAAC;AAAA,IACxC;AAGA;AAAA,sCACE,KAAK,GAAG,YAAY;AAGtB;AAAA,gCACE,KAAK,GAAG,MAAM;AAGhB;AAAA,uCAAoC,KAAK,QAAQ,aAAa;AAG9D;AAAA,gCAA6B,KAAK,QAAQ,MAAM;AAGhD;AAAA,iCAIkC,KAAK,QAAQ,OAAO;AAAA;AACxD;;;ACv8CO,IAAM,UAAU,MAGlB;AACH,QAAM,OAAO,IACR,WAC+B;AAClC,UAAM,UAA+B;AAAA,MACnC,KAAK;AAAA,MACL,UAAU;AAAA,MACV,QAAQ,CAAC;AAAA,MACT,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAEA,UAAM,SAAS,OAAO,OAAO,CAAC,KAAK,UAAU,MAAM,GAAG,GAAG,OAAgC;AACzF,WAAO;AAAA,MACL,cAAc;AAAA,MACd,eAAe;AAAA,MACf,QAAQ,OAAO;AAAA,IACjB;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,EAIF;AACF;;;AClFA,SAAS,YAAAA,iBAAgB;AASlB,IAAM,YAAY,CAAC,UAA4B;AACpD,QAAM,OAAO;AACb,MAAI,gBAAgB,IAAK,QAAO,UAAU,KAAK,IAAI;AACnD,MAAI,MAAM,QAAQ,IAAI,EAAG,QAAO,KAAK,IAAI,SAAS;AAClD,MAAI,gBAAgB,KAAM,QAAO;AACjC,MAAI,gBAAgBC,UAAU,QAAO;AACrC,MAAI,gBAAgB,OAAQ,QAAO;AACnC,MAAI,OAAO,SAAS,YAAY,SAAS,KAAM,QAAO;AAEtD,SAAO,OAAO,QAAQ,IAAI,EAAE,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,KAAK,CAAC,CAAC,GAAG,UAAU,CAAC,EAAE,IAAI,CAAC,CAAC;AACzF;AAIO,IAAM,eAAe,CAAI,UAC9B,UAAU,OAAO,UAAU,aAAa,MAAM,IAAI,YAAe,CAAC,IAAI,KAAK;AAEtE,IAAM,YACX,CAAW,OACX,CAAC,YACD,CAAC,SAAiC,EAAE,GAAG,KAAK,QAAQ,CAAC,GAAI,IAAI,UAAU,CAAC,GAAI,GAAG,OAAO,CAAC,EAAE;;;ACsSpF,IAAM,aAAa,UAAU,oBAAkB;AAAA,EACpD,YAAY,aAAa,aAAa;AACxC,EAAE;AAMK,IAAM,UAAU,UAAU,CAAC,YAAiB;AACjD,QAAM,WAAW,aAAa,OAAO;AACrC,MAAI,SAAS,UAAU,OAAO,QAAQ,WAAW,YAAY;AAK3D,aAAS,SAAS,aAAa,QAAQ,MAAM;AAAA,EAC/C;AACA,SAAO,EAAE,SAAS,SAAS;AAC7B,CAAC;AAuBM,IAAM,cAAc,UAAU,cAAY;AAAA,EAC/C,aAAa,aAAa,OAAO;AACnC,EAAE;AAgCK,IAAM,aAAa,UAAU,cAAY;AAAA,EAC9C,YAAY,aAAa,OAAO;AAClC,EAAE;AAyDK,IAAM,SAAS,UAAU,YAAU,EAAE,QAAQ,MAAM,EAAE;AASrD,IAAM,WAAW,UAAU,cAAY,EAAE,UAAU,aAAa,OAAO,EAAE,EAAE;AAiB3E,IAAM,cAAc,CAAC,eAAqB;AAAA,EAC/C,QAAQ,CAAC,EAAE,YAAY,UAAU,CAAC;AACpC;AAMO,IAAM,SAAS,UAAU,eAAa;AAC3C,QAAM,YAAY,aAAa,SAAS;AACxC,QAAM,kBAAuB,CAAC;AAC9B,aAAW,CAAC,KAAK,GAAG,KAAK,OAAO,QAAQ,SAAS,GAAG;AAClD,QAAK,IAAY,QAAQ;AACvB,sBAAgB,GAAG,IAAK,IAAY;AAAA,IACtC,WAAW,MAAM,QAAQ,GAAG,GAAG;AAC7B,sBAAgB,GAAG,IAAI;AAAA,IACzB,OAAO;AACL,sBAAgB,GAAG,IAAI;AAAA,IACzB;AAAA,EACF;AACA,SAAO,EAAE,QAAQ,gBAAgB;AACnC,CAAC;AAaM,IAAM,QAAQ,UAAU,cAAY,EAAE,OAAO,aAAa,OAAO,EAAE,EAAE;AAcrE,IAAM,WAAW,UAAU,cAAY,EAAE,UAAU,aAAa,OAAO,EAAE,EAAE;AA8B3E,IAAM,eAAe;AAAA,EAC1B,CAAC,aASM;AAAA,IACL,cAAc;AAAA,MACZ,GAAI,aAAa,OAAO;AAAA,MACxB,MAAM,QAAQ,KAAK;AAAA,IACrB;AAAA,EACF;AACF;AA6BO,IAAM,SAAS,UAAU,WAAS;AAAA,EACvC,QAAQ,UAAU,OAAO,SAAS,aAAa,KAAK,IAAI,mBAA4B,CAAC,IAAI,IAAI;AAC/F,EAAE;AAMK,IAAM,cAAc,UAAU,OAAO,EAAE,aAAa,CAAC,EAAE,EAAE;AAMzD,IAAM,SAAS,UAAU,QAAM,EAAE,QAAQ,EAAE,EAAE;AAmB7C,IAAM,UAAU,UAAU,CAAC,YAAkD;AAClF,QAAM,OAA6D;AAAA,IACjE,GAAG;AAAA,IACH,MAAM,QAAQ,KAAK;AAAA,EACrB;AACA,MAAI,OAAO,KAAK,aAAa,YAAY;AACvC,SAAK,WAAW,aAAa,KAAK,QAAQ;AAAA,EAC5C;AACA,MAAI,KAAK,YAAY,OAAO,KAAK,aAAa,YAAY,YAAY,KAAK,UAAU;AACnF,UAAM,WAAW,KAAK;AACtB,QAAI,OAAO,SAAS,WAAW,aAAa;AAC1C,WAAK,WAAW,SAAS;AAAA,IAC3B;AAAA,EACF;AACA,SAAO,EAAE,SAAS,KAAK;AACzB,CAAC;AAgCM,IAAM,SAAS,UAAU,aAAW,EAAE,QAAQ,aAAa,MAAM,EAAE,EAAE;AASrE,IAAM,SAAS,UAAU,CAAC,aAAmD;AAAA,EAClF,QAAQ;AAAA,IACN,GAAI,aAAa,OAAO;AAAA,IACxB,MAAM,QAAQ,KAAK;AAAA,EACrB;AACF,EAAE;AAeK,IAAM,OAAO,UAAU,aAAW;AACvC,QAAM,WAAW,aAAa,OAAO;AAErC,MAAI,UAAU,UAAU;AACtB,WAAO,EAAE,MAAM,EAAE,IAAI,SAAS,IAAI,MAAM,SAAS,KAAK,iBAAiB,EAAE;AAAA,EAC3E;AAEA,SAAO,EAAE,MAAM,SAAS,iBAAiB;AAC3C,CAAC;AAMM,IAAM,WAAW,UAAU,WAAS,EAAE,UAAU,aAAa,IAAI,EAAE,EAAE;AASrE,IAAM,UAAU,UAAU,iBAAe;AAAA,EAC9C,SAAS,aAAa,UAAU;AAClC,EAAE;AAgBK,IAAM,eAAe,UAAU,CAAC,YAAqB;AAC1D,QAAM,WAAW,aAAa,OAAO;AAGrC,QAAM,OACJ,aAAa,QAAQ,OAAO,aAAa,YAAY,aAAa,WAChE,WACA,EAAE,SAAS,SAAS;AACxB,SAAO,EAAE,cAAc,KAAK;AAC9B,CAAC;AAiBM,IAAM,eAAe,UAAU,iBAAe;AAAA,EACnD,cAAc,aAAa,UAAU;AACvC,EAAE;AAWK,IAAM,UAAU,UAAU,cAAY,EAAE,SAAS,aAAa,OAAO,EAAE,EAAE;AASzE,IAAM,OAAO,UAAU,aAAW,EAAE,MAAM,aAAa,MAAM,EAAE,EAAE;AAWjE,IAAM,mBAAmB,UAAU,cAAY;AAAA,EACpD,kBAAkB;AAAA,IAChB,OAAO,YAAY,aAAa,QAAQ,IAAI,cAAuB,CAAC,IAAI;AAAA,EAC1E;AACF,EAAE;AAeK,IAAM,QAAQ,UAAU,QAAM,EAAE,OAAO,EAAE,EAAE;AAM3C,IAAM,QAAQ,UAAU,WAAS,EAAE,OAAO,aAAa,IAAI,EAAE,EAAE;AAM/D,IAAM,eAAe,UAAU,iBAAe;AAAA,EACnD,cAAc,aAAa,UAAU;AACvC,EAAE;AAMK,IAAM,aAAa,UAAU,CAAC,YAAkD;AACrF,QAAM,OAA6D;AAAA,IACjE,GAAG;AAAA,IACH,MAAM,QAAQ,KAAK;AAAA,EACrB;AACA,MAAI,OAAO,KAAK,aAAa,YAAY;AACvC,SAAK,WAAW,aAAa,KAAK,QAAQ;AAAA,EAC5C;AACA,MAAI,KAAK,YAAY,OAAO,KAAK,aAAa,YAAY,YAAY,KAAK,UAAU;AACnF,UAAM,WAAW,KAAK;AACtB,QAAI,OAAO,SAAS,WAAW,aAAa;AAC1C,WAAK,WAAW,SAAS;AAAA,IAC3B;AAAA,EACF;AACA,SAAO,EAAE,YAAY,KAAK;AAC5B,CAAC;AAcM,IAAM,UAAU,IAAI,WACzB,CAAC,SAAqB;AAAA,EACpB,GAAG;AAAA,EACH,QAAQ,CAAC,GAAI,IAAI,UAAU,CAAC,GAAI,EAAE,QAAQ,OAAO,WAAW,IAAI,OAAO,CAAC,IAAI,OAAO,CAAC;AACtF;AAMK,IAAM,UAAU,UAAU,oBAAkB;AAAA,EACjD,SAAS,aAAa,aAAa;AACrC,EAAE;AAyCK,IAAM,gBAAgB,UAAU,cAAY;AAAA,EACjD,eAAe,aAAa,OAAO;AACrC,EAAE;AAiBK,IAAM,aAAa,UAAU,cAAY;AAAA,EAC9C,YAAY,aAAa,OAAO;AAClC,EAAE;;;AC94BK,IAAM,SAAS,MAA6B;AACjD,QAAM,OAAO,IAAI,WAA+E;AAC9F,UAAM,UAA2B;AAAA,MAC/B,KAAK;AAAA,MACL,UAAU;AAAA,MACV,QAAQ,CAAC;AAAA,MACT,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AACA,UAAM,SAAS,OAAO,OAAO,CAAC,KAAK,UAAU,MAAM,GAAG,GAAG,OAAO;AAChE,WAAO;AAAA,MACL,cAAc;AAAA,MACd,eAAe;AAAA,MACf,QAAQ,OAAO;AAAA,IACjB;AAAA,EACF;AAEA,SAAO;AAAA,IACL,KAAK;AAAA,IACL,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa;AAAA,IACb,WAAW;AAAA,IACX,SAAS;AAAA,IACT;AAAA,EACF;AACF;;;ACWA,SAAS,kBAAsC,UAAiD;AAE9F,QAAM,gBAAgB,CAAC,aAAiC;AACtD,QAAI,CAAC,SAAU,QAAO,CAAC;AAEvB,WAAQ,SAAqC,CAAC,CAAC;AAAA,EACjD;AAEA,SAAO;AAAA,IACL,OAAO,CAAC,UAAoB,aAA8B;AAAA,MACxD,SAAS,WAAW,cAAc,QAAQ,IAAI;AAAA,MAC9C,UAAU;AAAA,MACV,QAAQ,MAAM;AACZ,cAAM,SAAS,WAAW,cAAc,QAAQ,IAAI,CAAC;AACrD,YAAI,SAAS,SAAS,KAAK,MAAmB;AAC9C,YAAI,SAAS,KAAM,UAAS,OAAO,KAAK,QAAQ,IAAY;AAC5D,YAAI,SAAS,KAAM,UAAS,OAAO,KAAK,QAAQ,IAAI;AACpD,YAAI,SAAS,MAAO,UAAS,OAAO,MAAM,QAAQ,KAAK;AACvD,YAAI,SAAS,WAAY,UAAS,OAAO,QAAQ,QAAQ,UAAU;AACnE,YAAI,SAAS,KAAM,UAAS,OAAO,KAAK,QAAQ,IAAc;AAC9D,YAAI,SAAS,UAAW,UAAS,OAAO,UAAU,QAAQ,SAAS;AACnE,YAAI,SAAS,UAAW,UAAS,OAAO,UAAU,QAAQ,SAAS;AACnE,YAAI,SAAS,QAAS,UAAS,OAAO,QAAQ,QAAQ,OAAO;AAC7D,eAAO,OAAO,QAAQ;AAAA,MACxB;AAAA,MACA,OAAO,YAAY;AACjB,cAAM,SAAS,WAAW,cAAc,QAAQ,IAAI,CAAC;AACrD,eAAO,SAAS;AAAA,UACd;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,IAEA,UAAU,CAAC,UAAoB,aAA8B;AAAA,MAC3D,SAAS,WAAW,cAAc,QAAQ,IAAI;AAAA,MAC9C,UAAU;AAAA,MACV,QAAQ,YAAY;AAClB,cAAM,MAAM,MAAM,SAAS;AAAA,UACzB,WAAW,cAAc,QAAQ,IAAK,CAAC;AAAA,UACvC;AAAA,QACF;AACA,eAAO,MAAM,CAAC,GAAQ,IAAI,CAAC;AAAA,MAC7B;AAAA,MACA,OAAO,MACL,SAAS;AAAA,QACP,WAAW,cAAc,QAAQ,IAAK,CAAC;AAAA,QACvC;AAAA,MACF;AAAA,IACJ;AAAA,IAEA,WAAW,UAAQ;AAAA,MACjB,MAAM;AAAA,MACN,SAAS,MAAM,SAAS,UAAU,GAAY;AAAA,IAChD;AAAA,IAEA,YAAY,WAAS;AAAA,MACnB,OAAO;AAAA,MACP,SAAS,MAAM,SAAS,WAAW,IAAe;AAAA,IACpD;AAAA,IAEA,YAAY,CACV,UACA,WACA,YACG;AACH,YAAM,SAAS,cAAc,QAAQ;AAErC,YAAM,YACJ,OAAO,cAAc;AAAA;AAAA,QAElB,UAAU,OAAO,CAAC,EAAoC;AAAA,UACvD;AAEJ,aAAO;AAAA,QACL,SAAS;AAAA,QACT,SAAS;AAAA,QACT,UAAU;AAAA,QACV,SAAS,MAAM,SAAS,UAAU,QAAQ,WAAuB,OAAwB;AAAA,MAC3F;AAAA,IACF;AAAA,IAEA,aAAa,CACX,UACA,WACA,YACG;AACH,YAAM,SAAS,cAAc,QAAQ;AAErC,YAAM,YACJ,OAAO,cAAc;AAAA;AAAA,QAElB,UAAU,OAAO,CAAC,EAAoC;AAAA,UACvD;AAEJ,aAAO;AAAA,QACL,SAAS;AAAA,QACT,SAAS;AAAA,QACT,UAAU;AAAA,QACV,SAAS,MAAM,SAAS,WAAW,QAAQ,WAAuB,OAAwB;AAAA,MAC5F;AAAA,IACF;AAAA,IAEA,aAAa,CAAC,UAAmB,aAAgB,aAAuB;AAAA,MACtE,SAAS,cAAc,QAAQ;AAAA,MAC/B,cAAc;AAAA,MACd,UAAU;AAAA,MACV,SAAS,MACP,SAAS;AAAA,QACP,cAAc,QAAQ;AAAA,QACtB;AAAA,QACA;AAAA,MACF;AAAA,IACJ;AAAA,IAEA,YAAY,CAAC,cAAuB;AAAA,MAClC,SAAS,cAAc,QAAQ;AAAA,MAC/B,SAAS,MAAM,SAAS,UAAU,cAAc,QAAQ,CAAC;AAAA,IAC3D;AAAA,IAEA,aAAa,CAAC,cAAuB;AAAA,MACnC,SAAS,cAAc,QAAQ;AAAA,MAC/B,SAAS,MAAM,SAAS,WAAW,cAAc,QAAQ,CAAC;AAAA,IAC5D;AAAA,IAEA,mBAAmB,CACjB,UACA,aASI;AAAA,MACJ,SAAS,cAAc,QAAQ;AAAA,MAC/B,SAAS,MACP,SACG,iBAAiB,cAAc,QAAQ,GAAG,OAAkC,EAC5E,KAAK,OAAK,CAAa;AAAA,IAC9B;AAAA,IAEA,oBAAoB,CAClB,UACA,aACA,aAUI;AAAA,MACJ,SAAS,cAAc,QAAQ;AAAA,MAC/B,cAAc;AAAA,MACd,SAAS,MACP,SACG;AAAA,QACC,cAAc,QAAQ;AAAA,QACtB;AAAA,QACA;AAAA,MACF,EACC,KAAK,OAAK,CAAa;AAAA,IAC9B;AAAA,IAEA,mBAAmB,CACjB,UACA,WACA,aAWI;AAAA,MACJ,SAAS,cAAc,QAAQ;AAAA,MAC/B,SAAS;AAAA,MACT,SAAS,MACP,SACG;AAAA,QACC,cAAc,QAAQ;AAAA,QACtB;AAAA,QACA;AAAA,MACF,EACC,KAAK,OAAK,CAAa;AAAA,IAC9B;AAAA,IAEA,iBAAiB,CACf,UACA,aAQI;AAAA,MACJ,SAAS,MACP,SAAS;AAAA,QACP,WAAW,cAAc,QAAQ,IAAI,CAAC;AAAA,QACtC;AAAA,MACF;AAAA,IACJ;AAAA,IAEA,wBAAwB,OAAO;AAAA,MAC7B,SAAS,MAAM,SAAS,uBAAuB;AAAA,IACjD;AAAA,IAEA,WAAW,CAAC,OAAe,cAAwB;AAAA,MACjD,SAAS,MACP,SAAS,SAAS,OAAO,WAAW,cAAc,QAAQ,IAAK,CAAC,CAAe;AAAA,IACnF;AAAA,IAEA,YAAY,CAAC,YAAgC,aAAqC;AAAA,MAChF,aAAa;AAAA,MACb,SAAS,MACP,SAAS,UAAU,YAA0C,OAA2B;AAAA,IAC5F;AAAA,EACF;AACF;AAkBO,IAAM,aAAa,CACxB,MACA,SACA,aACiD;AACjD,QAAM,MAA+C;AAAA,IACnD,kBAAkB;AAAA,IAClB,kBAAkB,CAAC;AAAA,EACrB;AAEA,QAAM,OAAO,kBAAkB,QAAQ;AAEvC,SAAO,OAAO,OAAO,KAAK;AAAA,IACxB,YAAY,IAAI,WAAsB;AACpC,UAAI,MAAM,EAAE,gBAAgB,MAAM,QAAQ,CAAC,EAAE;AAC7C,iBAAW,KAAK,QAAQ;AAEtB,cAAO,EAAe,GAAG;AAAA,MAC3B;AAEA,aAAO;AAAA,QACL,GAAG;AAAA;AAAA,QAEH,QAAQ,MAAM,SAAS,UAAU,IAAI,MAAoB,EAAE,QAAQ;AAAA,QACnE,OAAO,MAAM,KAAK,UAAU,IAAI,QAAQ,MAAM,CAAC;AAAA,MACjD;AAAA,IACF;AAAA,IACA,GAAG;AAAA,EACL,CAAC;AACH;AAyBO,IAAM,WACX,CACE,SACA,YAEF,CAAC,WAAyF;AACxF,QAAM,OAAO,CACX,MACA,WAEA,WAAW,MAAM,QAAQ,OAAO,WAAmD,IAAI,CAAC;AAE1F,SAAO,OAAO;AAAA,IACZ,OAAO,QAAQ,OAAO,EAAE,IAAI,CAAC,CAAC,MAAM,MAAM,MAAM,CAAC,MAAM,KAAK,MAAM,MAAM,CAAC,CAAC;AAAA,EAC5E;AACF;","names":["ObjectId","ObjectId"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "sluice-orm",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "A type-safe MongoDB query library where return types are inferred from queries.",
|
|
5
|
+
"author": {
|
|
6
|
+
"name": "DrTtnk"
|
|
7
|
+
},
|
|
8
|
+
"main": "dist/index.cjs",
|
|
9
|
+
"module": "dist/index.js",
|
|
10
|
+
"types": "dist/index.d.ts",
|
|
11
|
+
"type": "module",
|
|
12
|
+
"exports": {
|
|
13
|
+
".": {
|
|
14
|
+
"types": "./dist/index.d.ts",
|
|
15
|
+
"import": "./dist/index.js",
|
|
16
|
+
"require": "./dist/index.cjs"
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
"scripts": {
|
|
20
|
+
"build": "tsup",
|
|
21
|
+
"type-check": "tsc --noEmit",
|
|
22
|
+
"build:ci": "./scripts/build.sh",
|
|
23
|
+
"release": "./scripts/release.sh",
|
|
24
|
+
"prepublishOnly": "npm run test:types",
|
|
25
|
+
"test:types": "npm run type-check -- --project tsconfig.test.json && tsd --files 'test/**/*.test-d.ts'",
|
|
26
|
+
"test:runtime": "vitest run --config vitest.config.ts",
|
|
27
|
+
"test": "npm-run-all --continue-on-error format test:types test:runtime",
|
|
28
|
+
"lint": "eslint src test --fix",
|
|
29
|
+
"format": "prettier --write src test ./package.json ./tsd.json"
|
|
30
|
+
},
|
|
31
|
+
"files": [
|
|
32
|
+
"dist"
|
|
33
|
+
],
|
|
34
|
+
"keywords": [
|
|
35
|
+
"mongodb",
|
|
36
|
+
"typescript",
|
|
37
|
+
"typesafe",
|
|
38
|
+
"aggregation",
|
|
39
|
+
"pipeline",
|
|
40
|
+
"query",
|
|
41
|
+
"inference"
|
|
42
|
+
],
|
|
43
|
+
"license": "MPL-2.0",
|
|
44
|
+
"repository": {
|
|
45
|
+
"type": "git",
|
|
46
|
+
"url": "git+https://github.com/DrTtnk/sluice-orm.git"
|
|
47
|
+
},
|
|
48
|
+
"homepage": "https://github.com/DrTtnk/sluice-orm#readme",
|
|
49
|
+
"bugs": {
|
|
50
|
+
"url": "https://github.com/DrTtnk/sluice-orm/issues"
|
|
51
|
+
},
|
|
52
|
+
"dependencies": {
|
|
53
|
+
"mongodb": "^6.18.0"
|
|
54
|
+
},
|
|
55
|
+
"peerDependencies": {
|
|
56
|
+
"effect": "^3.19.14",
|
|
57
|
+
"json-schema-to-typescript": "^10.1.5",
|
|
58
|
+
"zod": "^4.0.0"
|
|
59
|
+
},
|
|
60
|
+
"peerDependenciesMeta": {
|
|
61
|
+
"effect": {
|
|
62
|
+
"optional": true
|
|
63
|
+
},
|
|
64
|
+
"zod": {
|
|
65
|
+
"optional": true
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
"devDependencies": {
|
|
69
|
+
"@effect/schema": "^0.75.5",
|
|
70
|
+
"@testcontainers/mongodb": "^11.11.0",
|
|
71
|
+
"@typescript/analyze-trace": "^0.10.1",
|
|
72
|
+
"effect": "^3.19.14",
|
|
73
|
+
"eslint": "^9.33.0",
|
|
74
|
+
"eslint-plugin-simple-import-sort": "^12.1.1",
|
|
75
|
+
"eslint-plugin-unused-imports": "^4.3.0",
|
|
76
|
+
"husky": "^9.1.7",
|
|
77
|
+
"npm-run-all": "^4.1.5",
|
|
78
|
+
"prettier": "^3.6.2",
|
|
79
|
+
"tsd": "^0.33.0",
|
|
80
|
+
"tsup": "^8.5.1",
|
|
81
|
+
"type-fest": "^5.4.1",
|
|
82
|
+
"typescript": "^5.9.2",
|
|
83
|
+
"typescript-eslint": "^8.53.0",
|
|
84
|
+
"vitest": "^4.0.17"
|
|
85
|
+
}
|
|
86
|
+
}
|