Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(index.d.ts): types for aggregation pipeline stages #10971

Merged
merged 5 commits into from
Dec 5, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
300 changes: 284 additions & 16 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -746,9 +746,7 @@ declare module 'mongoose' {
interface Model<T, TQueryHelpers = {}, TMethods = {}, TVirtuals = {}> extends NodeJS.EventEmitter, AcceptsDiscriminator {
new(doc?: AnyKeys<T> & AnyObject, fields?: any | null, options?: boolean | AnyObject): EnforceDocument<T, TMethods, TVirtuals>;

aggregate<R = any>(pipeline?: any[], options?: Record<string, unknown>): Aggregate<Array<R>>;
aggregate<R = any>(pipeline: any[], cb: Function): Promise<Array<R>>;
aggregate<R = any>(pipeline: any[], options: Record<string, unknown>, cb: Function): Promise<Array<R>>;
aggregate<R = any>(pipeline?: PipelineStage<T>[], options?: mongodb.AggregateOptions, callback?: Callback<R[]>): Aggregate<Array<R>>;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change is incorrect, because we need to support the aggregate(pipeline, cb) syntax. Please add back aggregate<R = any>(pipeline: any[], cb: Function): Aggregate<Array<R>>;

Thanks for fixing the issue with returning Promise though, that is an issue in our type definitions.

Copy link
Contributor Author

@jeremyben jeremyben Nov 20, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will revert back the two params signature 👍 .


/** Base Mongoose instance the model uses. */
base: typeof mongoose;
Expand Down Expand Up @@ -2749,7 +2747,7 @@ declare module 'mongoose' {
* Appends a new $addFields operator to this aggregate pipeline.
* Requires MongoDB v3.4+ to work
*/
addFields(arg: any): this;
addFields(arg: PipelineStage.AddFields['$addFields']): this;

/** Sets the allowDiskUse option for the aggregation query (ignored for < 2.6.0) */
allowDiskUse(value: boolean): this;
Expand All @@ -2768,7 +2766,7 @@ declare module 'mongoose' {
collation(options: mongodb.CollationOptions): this;

/** Appends a new $count operator to this aggregate pipeline. */
count(countName: string): this;
count(countName: PipelineStage.Count['$count']): this;

/**
* Sets the cursor option for the aggregation query (ignored for < 2.6.0).
Expand All @@ -2782,13 +2780,13 @@ declare module 'mongoose' {
explain(callback?: Callback): Promise<any>;

/** Combines multiple aggregation pipelines. */
facet(options: any): this;
facet(options: PipelineStage.Facet['$facet']): this;

/** Appends new custom $graphLookup operator(s) to this aggregate pipeline, performing a recursive search on a collection. */
graphLookup(options: any): this;
graphLookup(options: PipelineStage.GraphLookup['$graphLookup']): this;

/** Appends new custom $group operator to this aggregate pipeline. */
group(arg: any): this;
group(arg: PipelineStage.Group['$group']): this;

/** Sets the hint option for the aggregation query (ignored for < 3.6.0) */
hint(value: Record<string, unknown> | string): this;
Expand All @@ -2797,16 +2795,16 @@ declare module 'mongoose' {
* Appends a new $limit operator to this aggregate pipeline.
* @param num maximum number of records to pass to the next stage
*/
limit(num: number): this;
limit(num: PipelineStage.Limit['$limit']): this;

/** Appends new custom $lookup operator to this aggregate pipeline. */
lookup(options: any): this;
lookup(options: PipelineStage.Lookup['$lookup']): this;

/**
* Appends a new custom $match operator to this aggregate pipeline.
* @param arg $match operator contents
*/
match(arg: any): this;
match(arg: PipelineStage.Match['$match']): this;

/**
* Binds this aggregate to a model.
Expand All @@ -2824,7 +2822,7 @@ declare module 'mongoose' {
pipeline(): any[];

/** Appends a new $project operator to this aggregate pipeline. */
project(arg: string | Object): this;
project(arg: PipelineStage.Project['$project']): this;

/** Sets the readPreference option for the aggregation query. */
read(pref: string | mongodb.ReadPreferenceMode, tags?: any[]): this;
Expand All @@ -2836,13 +2834,13 @@ declare module 'mongoose' {
redact(expression: any, thenExpr: string | any, elseExpr: string | any): this;

/** Appends a new $replaceRoot operator to this aggregate pipeline. */
replaceRoot(newRoot: object | string): this;
replaceRoot(newRoot: PipelineStage.ReplaceRoot['$replaceRoot'] | string): this;

/**
* Helper for [Atlas Text Search](https://docs.atlas.mongodb.com/reference/atlas-search/tutorial/)'s
* `$search` stage.
*/
search(options: any): this;
search(options: PipelineStage.Search['$search']): this;

/** Lets you set arbitrary options, for middleware or plugins. */
option(value: Record<string, unknown>): this;
Expand All @@ -2860,7 +2858,7 @@ declare module 'mongoose' {
skip(num: number): this;

/** Appends a new $sort operator to this aggregate pipeline. */
sort(arg: any): this;
sort(arg: PipelineStage.Sort['$sort']): this;

/** Provides promise for aggregate. */
then: Promise<R>['then'];
Expand All @@ -2872,7 +2870,7 @@ declare module 'mongoose' {
sortByCount(arg: string | any): this;

/** Appends new custom $unwind operator(s) to this aggregate pipeline. */
unwind(...args: any[]): this;
unwind(...args: PipelineStage.Unwind['$unwind'][]): this;
}

class AggregationCursor extends stream.Readable {
Expand Down Expand Up @@ -2912,6 +2910,276 @@ declare module 'mongoose' {
next(callback: Callback): void;
}

/**
* [Stages reference](https://docs.mongodb.com/manual/reference/operator/aggregation-pipeline/#aggregation-pipeline-stages)
*/
export type PipelineStage<T = any> =
| PipelineStage.AddFields
| PipelineStage.Bucket
| PipelineStage.BucketAuto
| PipelineStage.CollStats
| PipelineStage.Count
| PipelineStage.Facet
| PipelineStage.GeoNear<T>
| PipelineStage.GraphLookup<T>
| PipelineStage.Group
| PipelineStage.IndexStats
| PipelineStage.Limit
| PipelineStage.ListSessions
| PipelineStage.Lookup
| PipelineStage.Match<T>
| PipelineStage.Merge
| PipelineStage.Out
| PipelineStage.PlanCacheStats
| PipelineStage.Project
| PipelineStage.Redact
| PipelineStage.ReplaceRoot
| PipelineStage.ReplaceWith
| PipelineStage.Sample
| PipelineStage.Search
| PipelineStage.Set
| PipelineStage.SetWindowFields
| PipelineStage.Skip
| PipelineStage.Sort
| PipelineStage.SortByCount
| PipelineStage.UnionWith
| PipelineStage.Unset
| PipelineStage.Unwind

export namespace PipelineStage {
export interface AddFields {
/** [`$addFields` reference](https://docs.mongodb.com/manual/reference/operator/aggregation/addFields/) */
$addFields: Record<string, any>
}

export interface Bucket {
/** [`$bucket` reference](https://docs.mongodb.com/manual/reference/operator/aggregation/bucket/) */
$bucket: {
groupBy: any
boundaries: any[]
default?: any
output?: Record<string, { [op in AccumulatorOperator]?: any }>
}
}

export interface BucketAuto {
/** [`$bucketAuto` reference](https://docs.mongodb.com/manual/reference/operator/aggregation/bucketAuto/) */
$bucketAuto: {
groupBy: any
buckets: number
output?: Record<string, { [op in AccumulatorOperator]?: any }>
granularity?: 'R5' | 'R10' | 'R20' | 'R40' | 'R80' | '1-2-5' | 'E6' | 'E12' | 'E24' | 'E48' | 'E96' | 'E192' | 'POWERSOF2'
}
}

export interface CollStats {
/** [`$collStats` reference](https://docs.mongodb.com/manual/reference/operator/aggregation/collStats/) */
$collStats: {
latencyStats?: { histograms?: boolean }
storageStats?: { scale?: number }
count?: {}
queryExecStats?: {}
}
}

export interface Count {
/** [`$count` reference](https://docs.mongodb.com/manual/reference/operator/aggregation/count/) */
$count: string
}

export interface Facet {
/** [`$facet` reference](https://docs.mongodb.com/manual/reference/operator/aggregation/facet/) */
$facet: Record<
string,
Exclude<PipelineStage, PipelineStage.CollStats | PipelineStage.Facet | PipelineStage.GeoNear | PipelineStage.IndexStats | PipelineStage.Out | PipelineStage.Merge | PipelineStage.PlanCacheStats>[]
>
}

export interface GeoNear<T = any> {
/** [`$geoNear` reference](https://docs.mongodb.com/manual/reference/operator/aggregation/geoNear/) */
$geoNear: {
near: { type: 'Point'; coordinates: [number, number] } | [number, number]
distanceField: string
distanceMultiplier?: number
includeLocs?: string
key?: string
maxDistance?: number
minDistance?: number
query?: mongoose.FilterQuery<T>
spherical?: boolean
uniqueDocs?: boolean
}
}

export interface GraphLookup<T = any> {
/** [`$graphLookup` reference](https://docs.mongodb.com/manual/reference/operator/aggregation/graphLookup/) */
$graphLookup: {
from: string
startWith: any
connectFromField: string
connectToField: string
as: string
maxDepth?: number
depthField?: string
restrictSearchWithMatch?: mongoose.FilterQuery<T>
}
}

export interface Group {
/** [`$group` reference](https://docs.mongodb.com/manual/reference/operator/aggregation/group) */
$group: {
_id: any
[key: string]: { [op in AccumulatorOperator]?: any }
}
}

export interface IndexStats {
/** [`$indexStats` reference](https://docs.mongodb.com/manual/reference/operator/aggregation/indexStats/) */
$indexStats: {}
}

export interface Limit {
/** [`$limit` reference](https://docs.mongodb.com/manual/reference/operator/aggregation/limit/) */
$limit: number
}

export interface ListSessions {
/** [`$listSessions` reference](https://docs.mongodb.com/manual/reference/operator/aggregation/listSessions/) */
$listSessions: { users?: { user: string; db: string }[] } | { allUsers?: true }
}

export interface Lookup {
/** [`$lookup` reference](https://docs.mongodb.com/manual/reference/operator/aggregation/lookup/) */
$lookup: {
from: string
as: string
localField?: string
foreignField?: string
let?: Record<string, any>
pipeline?: Exclude<PipelineStage, PipelineStage.Merge | PipelineStage.Out | PipelineStage.Search>[]
}
}

export interface Match<T = any> {
/** [`$match` reference](https://docs.mongodb.com/manual/reference/operator/aggregation/match/) */
$match: mongoose.FilterQuery<T>
}

export interface Merge {
/** [`$merge` reference](https://docs.mongodb.com/manual/reference/operator/aggregation/merge/) */
$merge: {
into: string | { db: string; coll: string }
on?: string | string[]
let?: Record<string, any>
whenMatched?: 'replace' | 'keepExisting' | 'merge' | 'fail' | 'pipeline'
whenNotMatched?: 'insert' | 'discard' | 'fail'
}
}

export interface Out {
/** [`$out` reference](https://docs.mongodb.com/manual/reference/operator/aggregation/out/) */
$out: string | { db: string; coll: string }
}

export interface PlanCacheStats {
/** [`$planCacheStats` reference](https://docs.mongodb.com/manual/reference/operator/aggregation/planCacheStats/) */
$planCacheStats: {}
}

export interface Project {
/** [`$project` reference](https://docs.mongodb.com/manual/reference/operator/aggregation/project/) */
$project: { _id?: 0 | false; [field: string]: any }
}

export interface Redact {
/** [`$redact` reference](https://docs.mongodb.com/manual/reference/operator/aggregation/redact/) */
$redact: any
}

export interface ReplaceRoot {
/** [`$replaceRoot` reference](https://docs.mongodb.com/manual/reference/operator/aggregation/replaceRoot/) */
$replaceRoot: { newRoot: any }
}

export interface ReplaceWith {
/** [`$replaceWith` reference](https://docs.mongodb.com/manual/reference/operator/aggregation/replaceWith/) */
$replaceWith: any
}

export interface Sample {
/** [`$sample` reference](https://docs.mongodb.com/manual/reference/operator/aggregation/sample/) */
$sample: { size: number }
}

export interface Search {
/** [`$search` reference](https://docs.atlas.mongodb.com/reference/atlas-search/query-syntax/) */
$search: {
[key: string]: any
index?: string
highlight?: { path: string; maxCharsToExamine?: number; maxNumPassages?: number }
}
}

export interface Set {
/** [`$set` reference](https://docs.mongodb.com/manual/reference/operator/aggregation/set/) */
$set: Record<string, any>
}

export interface SetWindowFields {
/** [`$setWindowFields` reference](https://docs.mongodb.com/manual/reference/operator/aggregation/setWindowFields/) */
$setWindowFields: {
partitionBy?: any
sortBy?: Record<string, 1 | -1>
output: Record<
string,
{ [op in WindowOperator]?: any } & {
window?: {
documents?: [string | number, string | number]
range?: [string | number, string | number]
unit?: 'year' | 'quarter' | 'month' | 'week' | 'day' | 'hour' | 'minute' | 'second' | 'millisecond'
}
}
>
}
}

export interface Skip {
/** [`$skip` reference](https://docs.mongodb.com/manual/reference/operator/aggregation/skip/) */
$skip: number
}

export interface Sort {
/** [`$sort` reference](https://docs.mongodb.com/manual/reference/operator/aggregation/sort/) */
$sort: Record<string, 1 | -1 | { $meta: 'textScore' }>
}

export interface SortByCount {
/** [`$sortByCount` reference](https://docs.mongodb.com/manual/reference/operator/aggregation/sortByCount/) */
$sortByCount: any
}

export interface UnionWith {
/** [`$unionWith` reference](https://docs.mongodb.com/manual/reference/operator/aggregation/unionWith/) */
$unionWith:
| string
| { coll: string; pipeline?: Exclude<PipelineStage, PipelineStage.Out | PipelineStage.Merge> }
}

export interface Unset {
/** [`$unset` reference](https://docs.mongodb.com/manual/reference/operator/aggregation/unset/) */
$unset: string | string[]
}

export interface Unwind {
/** [`$unwind` reference](https://docs.mongodb.com/manual/reference/operator/aggregation/unwind/) */
$unwind: string | { path: string; includeArrayIndex?: string; preserveNullAndEmptyArrays?: boolean }
}

type AccumulatorOperator = '$accumulator' | '$addToSet' | '$avg' | '$count' | '$first' | '$last' | '$max' | '$mergeObjects' | '$min' | '$push' | '$stdDevPop' | '$stdDevSamp' | '$sum'

type WindowOperator = '$addToSet' | '$avg' | '$count' | '$covariancePop' | '$covarianceSamp' | '$derivative' | '$expMovingAvg' | '$integral' | '$max' | '$min' | '$push' | '$stdDevSamp' | '$stdDevPop' | '$sum' | '$first' | '$last' | '$shift' | '$denseRank' | '$documentNumber' | '$rank'
}

class SchemaType {
/** SchemaType constructor */
constructor(path: string, options?: AnyObject, instance?: string);
Expand Down