Skip to content

feat: use placeholder mql types MONGOSH-2333 #2485

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

Merged
merged 6 commits into from
Jun 25, 2025
Merged
Show file tree
Hide file tree
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
5 changes: 3 additions & 2 deletions packages/shell-api/src/bulk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { asPrintable } from './enums';
import { assertArgsDefinedType, shallowClone } from './helpers';
import { BulkWriteResult } from './result';
import type { CollectionWithSchema } from './collection';
import type { MQLDocument, MQLQuery } from './mql-types';

@shellApiClassDefault
export class BulkFindOp extends ShellApiWithMongoClass {
Expand Down Expand Up @@ -202,14 +203,14 @@ export default class Bulk extends ShellApiWithMongoClass {

@returnType('BulkFindOp')
@apiVersions([1])
find(query: Document): BulkFindOp {
find(query: MQLQuery): BulkFindOp {
assertArgsDefinedType([query], [true], 'Bulk.find');
return new BulkFindOp(this._serviceProviderBulkOp.find(query), this);
}

@returnType('Bulk')
@apiVersions([1])
insert(document: Document): Bulk {
insert(document: MQLDocument): Bulk {
this._batchCounts.nInsertOps++;
assertArgsDefinedType([document], [true], 'Bulk.insert');
this._serviceProviderBulkOp.insert(document);
Expand Down
34 changes: 18 additions & 16 deletions packages/shell-api/src/collection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ import { HIDDEN_COMMANDS } from '@mongosh/history';
import PlanCache from './plan-cache';
import ChangeStreamCursor from './change-stream-cursor';
import { ShellApiErrors } from './error-codes';
import type { MQLDocument, MQLQuery, MQLPipeline } from './mql-types';

export type CollectionWithSchema<
M extends GenericServerSideSchema = GenericServerSideSchema,
Expand All @@ -116,6 +117,7 @@ export type CollectionWithSchema<
export class Collection<
M extends GenericServerSideSchema = GenericServerSideSchema,
D extends GenericDatabaseSchema = M[keyof M],
// eslint-disable-next-line @typescript-eslint/no-unused-vars
C extends GenericCollectionSchema = D[keyof D],
N extends StringKey<D> = StringKey<D>
> extends ShellApiWithMongoClass {
Expand Down Expand Up @@ -188,20 +190,20 @@ export class Collection<
* @returns {Promise} The promise of aggregation results.
*/
async aggregate(
pipeline: Document[],
pipeline: MQLPipeline,
options: AggregateOptions & { explain: ExplainVerbosityLike }
): Promise<Document>;
async aggregate(
pipeline: Document[],
pipeline: MQLPipeline,
options?: AggregateOptions
): Promise<AggregationCursor>;
async aggregate(...stages: Document[]): Promise<AggregationCursor>;
async aggregate(...stages: MQLPipeline): Promise<AggregationCursor>;
@returnsPromise
@returnType('AggregationCursor')
@apiVersions([1])
async aggregate(...args: unknown[]): Promise<AggregationCursor | Document> {
let options: AggregateOptions;
let pipeline: Document[];
let pipeline: MQLPipeline;
if (args.length === 0 || Array.isArray(args[0])) {
options = args[1] || {};
pipeline = (args[0] as Document[]) || [];
Expand Down Expand Up @@ -320,7 +322,7 @@ export class Collection<
@serverVersions(['4.0.3', ServerVersions.latest])
@apiVersions([1])
async countDocuments(
query?: Document,
query?: MQLQuery,
options: CountDocumentsOptions = {}
): Promise<number> {
this._emitCollectionApiCall('countDocuments', { query, options });
Expand Down Expand Up @@ -413,17 +415,17 @@ export class Collection<
* @returns {Array} The promise of the result.
*/
async distinct(field: string): Promise<Document>;
async distinct(field: string, query: Document): Promise<Document>;
async distinct(field: string, query: MQLQuery): Promise<Document>;
async distinct(
field: string,
query: Document,
query: MQLQuery,
options: DistinctOptions
): Promise<Document>;
@returnsPromise
@apiVersions([])
async distinct(
field: string,
query?: Document,
query?: MQLQuery,
options: DistinctOptions = {}
): Promise<Document> {
this._emitCollectionApiCall('distinct', { field, query, options });
Expand Down Expand Up @@ -476,7 +478,7 @@ export class Collection<
@apiVersions([1])
@returnsPromise
async find(
query?: Document,
query?: MQLQuery,
projection?: Document,
options: FindOptions = {}
): Promise<Cursor> {
Expand Down Expand Up @@ -560,10 +562,10 @@ export class Collection<
@returnType('Document')
@apiVersions([1])
async findOne(
query: Document = {},
query: MQLQuery = {},
projection?: Document,
options: FindOptions = {}
): Promise<C['schema'] | null> {
): Promise<MQLDocument | null> {
if (projection) {
options.projection = projection;
}
Expand Down Expand Up @@ -757,7 +759,7 @@ export class Collection<
@serverVersions([ServerVersions.earliest, '3.6.0'])
@apiVersions([1])
async insert(
docs: Document | Document[],
docs: MQLDocument | MQLDocument[],
options: BulkWriteOptions = {}
): Promise<InsertManyResult> {
await this._instanceState.printDeprecationWarning(
Expand Down Expand Up @@ -801,7 +803,7 @@ export class Collection<
@serverVersions(['3.2.0', ServerVersions.latest])
@apiVersions([1])
async insertMany(
docs: Document[],
docs: MQLDocument[],
options: BulkWriteOptions = {}
): Promise<InsertManyResult> {
assertArgsDefinedType([docs], [true], 'Collection.insertMany');
Expand Down Expand Up @@ -837,7 +839,7 @@ export class Collection<
@serverVersions(['3.2.0', ServerVersions.latest])
@apiVersions([1])
async insertOne(
doc: Document,
doc: MQLDocument,
options: InsertOneOptions = {}
): Promise<InsertOneResult> {
assertArgsDefinedType([doc], [true], 'Collection.insertOne');
Expand Down Expand Up @@ -893,7 +895,7 @@ export class Collection<
@serverVersions([ServerVersions.earliest, '3.2.0'])
@apiVersions([1])
async remove(
query: Document,
query: MQLQuery,
options: boolean | RemoveShellOptions = {}
): Promise<DeleteResult | Document> {
await this._instanceState.printDeprecationWarning(
Expand Down Expand Up @@ -2332,7 +2334,7 @@ export class Collection<
@apiVersions([1])
@returnsPromise
async watch(
pipeline: Document[] | ChangeStreamOptions = [],
pipeline: MQLPipeline | ChangeStreamOptions = [],
options: ChangeStreamOptions = {}
): Promise<ChangeStreamCursor> {
if (!Array.isArray(pipeline)) {
Expand Down
19 changes: 10 additions & 9 deletions packages/shell-api/src/database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ import type {
ExplainVerbosityLike,
AggregateOptions,
} from '@mongosh/service-provider-core';
import type { MQLPipeline } from './mql-types';

export type CollectionNamesWithTypes = {
name: string;
Expand Down Expand Up @@ -443,26 +444,26 @@ export class Database<
* @returns {Promise} The promise of aggregation results.
*/
async aggregate(
pipeline: Document[],
pipeline: MQLPipeline,
options: AggregateOptions & { explain: ExplainVerbosityLike }
): Promise<Document>;
async aggregate(
pipeline: Document[],
pipeline: MQLPipeline,
options?: AggregateOptions
): Promise<AggregationCursor>;
async aggregate(...stages: Document[]): Promise<AggregationCursor>;
async aggregate(...stages: MQLPipeline): Promise<AggregationCursor>;
@returnsPromise
@returnType('AggregationCursor')
@apiVersions([1])
async aggregate(...args: unknown[]): Promise<AggregationCursor | Document> {
let options: AggregateOptions;
let pipeline: Document[];
let pipeline: MQLPipeline;
if (args.length === 0 || Array.isArray(args[0])) {
options = args[1] || {};
pipeline = (args[0] as Document[]) || [];
pipeline = (args[0] as MQLPipeline) || [];
} else {
options = {};
pipeline = (args as Document[]) || [];
pipeline = (args as MQLPipeline) || [];
}

if ('background' in options) {
Expand Down Expand Up @@ -855,7 +856,7 @@ export class Database<
async createView(
name: string,
source: string,
pipeline: Document[],
pipeline: MQLPipeline,
options: CreateCollectionOptions = {}
): Promise<{ ok: number }> {
assertArgsDefinedType(
Expand Down Expand Up @@ -1085,7 +1086,7 @@ export class Database<
? { $all: opts, $ownOps: false }
: { $all: !!opts.$all, $ownOps: !!opts.$ownOps };

const pipeline: Document[] = [
const pipeline: MQLPipeline = [
{
$currentOp: {
allUsers: !legacyCurrentOpOptions.$ownOps,
Expand Down Expand Up @@ -1739,7 +1740,7 @@ export class Database<
@apiVersions([1])
@returnsPromise
async watch(
pipeline: Document[] | ChangeStreamOptions = [],
pipeline: MQLPipeline | ChangeStreamOptions = [],
options: ChangeStreamOptions = {}
): Promise<ChangeStreamCursor> {
if (!Array.isArray(pipeline)) {
Expand Down
27 changes: 14 additions & 13 deletions packages/shell-api/src/explainable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import type {
FindOneAndUpdateOptions,
FindOptions,
} from '@mongosh/service-provider-core';
import type { MQLDocument, MQLPipeline, MQLQuery } from './mql-types';

@shellApiClassDefault
export default class Explainable extends ShellApiWithMongoClass {
Expand Down Expand Up @@ -97,7 +98,7 @@ export default class Explainable extends ShellApiWithMongoClass {
@apiVersions([1])
@returnsPromise
async find(
query?: Document,
query?: MQLQuery,
projection?: Document,
options: FindOptions = {}
): Promise<ExplainableCursor> {
Expand All @@ -107,14 +108,14 @@ export default class Explainable extends ShellApiWithMongoClass {
return new ExplainableCursor(this._mongo, cursor, this._verbosity);
}

async aggregate(pipeline: Document[], options: Document): Promise<Document>;
async aggregate(...stages: Document[]): Promise<Document>;
async aggregate(pipeline: MQLPipeline, options: Document): Promise<Document>;
async aggregate(...stages: MQLPipeline): Promise<Document>;
@returnsPromise
@apiVersions([1])
async aggregate(...args: any[]): Promise<Document> {
this._emitExplainableApiCall('aggregate', { args });
let options: Document;
let pipeline: Document[];
let pipeline: MQLPipeline;
if (Array.isArray(args[0])) {
pipeline = args[0];
options = args[1] ?? {};
Expand Down Expand Up @@ -147,17 +148,17 @@ export default class Explainable extends ShellApiWithMongoClass {
}

async distinct(field: string): Promise<Document>;
async distinct(field: string, query: Document): Promise<Document>;
async distinct(field: string, query: MQLQuery): Promise<Document>;
async distinct(
field: string,
query: Document,
query: MQLQuery,
options: DistinctOptions
): Promise<Document>;
@returnsPromise
@apiVersions([1])
async distinct(
field: string,
query?: Document,
query?: MQLQuery,
options: DistinctOptions = {}
): Promise<Document> {
this._emitExplainableApiCall('distinct', { field, query, options });
Expand All @@ -182,7 +183,7 @@ export default class Explainable extends ShellApiWithMongoClass {
@returnsPromise
@apiVersions([1])
async findOneAndDelete(
filter: Document,
filter: MQLQuery,
options: FindOneAndDeleteOptions = {}
): Promise<Document | null> {
this._emitExplainableApiCall('findOneAndDelete', { filter, options });
Expand All @@ -195,8 +196,8 @@ export default class Explainable extends ShellApiWithMongoClass {
@returnsPromise
@apiVersions([1])
async findOneAndReplace(
filter: Document,
replacement: Document,
filter: MQLQuery,
replacement: MQLDocument,
options: FindAndModifyShellOptions<FindOneAndReplaceOptions> = {}
): Promise<Document> {
this._emitExplainableApiCall('findOneAndReplace', { filter, options });
Expand All @@ -209,8 +210,8 @@ export default class Explainable extends ShellApiWithMongoClass {
@returnsPromise
@apiVersions([1])
async findOneAndUpdate(
filter: Document,
update: Document,
filter: MQLQuery,
update: MQLDocument,
options: FindAndModifyShellOptions<FindOneAndUpdateOptions> = {}
): Promise<Document> {
this._emitExplainableApiCall('findOneAndUpdate', { filter, options });
Expand All @@ -223,7 +224,7 @@ export default class Explainable extends ShellApiWithMongoClass {
@returnsPromise
@apiVersions([1])
async remove(
query: Document,
query: MQLQuery,
options: boolean | RemoveShellOptions = {}
): Promise<Document> {
this._emitExplainableApiCall('remove', { query, options });
Expand Down
7 changes: 5 additions & 2 deletions packages/shell-api/src/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import type { AbstractCursor } from './abstract-cursor';
import type ChangeStreamCursor from './change-stream-cursor';
import type { ShellBson } from './shell-bson';
import { inspect } from 'util';
import type { MQLPipeline, MQLQuery } from './mql-types';

/**
* Helper method to adapt aggregation pipeline options.
Expand Down Expand Up @@ -882,7 +883,7 @@ export async function iterate(

// This is only used by collection.findAndModify() itself.
export type FindAndModifyMethodShellOptions = {
query: Document;
query: MQLQuery;
sort?: (
| FindOneAndDeleteOptions
| FindOneAndReplaceOptions
Expand Down Expand Up @@ -1111,7 +1112,9 @@ export function isValidCollectionName(name: string): boolean {
return !!name && !/[$\0]/.test(name);
}

export function shouldRunAggregationImmediately(pipeline: Document[]): boolean {
export function shouldRunAggregationImmediately(
pipeline: MQLPipeline
): boolean {
return pipeline.some((stage) =>
Object.keys(stage).some(
(stageName) => stageName === '$merge' || stageName === '$out'
Expand Down
3 changes: 2 additions & 1 deletion packages/shell-api/src/mongo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ import type { LogEntry } from './log-entry';
import { parseAnyLogEntry } from './log-entry';
import type { CollectionWithSchema } from './collection';
import type { ShellBson } from './shell-bson';
import type { MQLPipeline } from './mql-types';

/* Utility, inverse of Readonly<T> */
type Mutable<T> = {
Expand Down Expand Up @@ -845,7 +846,7 @@ export default class Mongo<
@apiVersions([1])
@returnsPromise
async watch(
pipeline: Document[] | ChangeStreamOptions = [],
pipeline: MQLPipeline | ChangeStreamOptions = [],
options: ChangeStreamOptions = {}
): Promise<ChangeStreamCursor> {
if (!Array.isArray(pipeline)) {
Expand Down
7 changes: 7 additions & 0 deletions packages/shell-api/src/mql-types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import type { Document } from '@mongosh/service-provider-core';

export type MQLQuery = Document;

export type MQLPipeline = Document[];

export type MQLDocument = Document;
Loading