Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
cfbafad
[Do Not Merge] PoC for shell-api autocomplete type definitions
addaleax Jan 24, 2024
0e17bc2
fixup: add index signature support
addaleax Jan 24, 2024
4d72278
fixup
addaleax Jan 24, 2024
6a931fa
Initial feature-flagged, draft new autocompleter.
lerouxb Mar 31, 2025
88edcd3
use the specified connection and db name
lerouxb Apr 2, 2025
70168e6
port some tests to autocomplete
lerouxb Apr 2, 2025
fd845e6
this one just worked
lerouxb Apr 2, 2025
b1ccc97
also just works
lerouxb Apr 2, 2025
7fecfac
use the new mongodb-schema
lerouxb Apr 4, 2025
256fc60
more bundled packages
lerouxb Apr 15, 2025
d81ff54
Merge branch 'main' into shell-api-ac-type-definitions
lerouxb Apr 15, 2025
198fb06
add rs, sh, sp generics
lerouxb Apr 17, 2025
59c04f3
fix tests
lerouxb Apr 17, 2025
3545fd8
hopefully fix the api export
lerouxb Apr 17, 2025
f34e213
something went wrong with the package-lock.json file
lerouxb Apr 17, 2025
51946ea
don't include the REPLACEME boilerplate which will be added on the ou…
lerouxb Apr 22, 2025
41a4560
workaround possible false positive error
lerouxb Apr 22, 2025
33ee0b5
no idea why it added that
lerouxb Apr 22, 2025
ae48313
we should probably run api-generate automatically
lerouxb Apr 22, 2025
880135f
add missing deps
lerouxb Apr 22, 2025
25240df
add the ShellApi and ShellBson globals to the shell api
lerouxb Apr 24, 2025
5511582
remove comment
lerouxb Apr 24, 2025
c6d8219
linebreak
lerouxb Apr 28, 2025
8f11992
add help comments to the extracted/generated shell-api
lerouxb Apr 28, 2025
e6833d1
Merge branch 'shell-api-ac-type-definitions-fork' into autocomplete2-…
lerouxb May 1, 2025
663e042
Merge branch 'use-new-autocomplete' into autocomplete2-demo
lerouxb May 2, 2025
1b2bb2d
strip node.js repl results for now
lerouxb May 2, 2025
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
Prev Previous commit
Next Next commit
fix tests
  • Loading branch information
lerouxb committed Apr 17, 2025
commit 59c04f30f1a6d94951ec94f99f172324eac639fd
4 changes: 2 additions & 2 deletions 4 packages/autocomplete/src/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@ describe('completer.completer', function () {

it('returns all suggestions', async function () {
const i = 'db.';
const attr = shellSignatures.Database.attributes as any;
const attr = shellSignatures.DatabaseImpl.attributes as any;
const dbComplete = Object.keys(attr);
const adjusted = dbComplete
.filter((c) => !attr[c].deprecated)
Expand Down Expand Up @@ -347,7 +347,7 @@ describe('completer.completer', function () {
it('returns all suggestions', async function () {
const i = 'db.shipwrecks.';
const collComplete = Object.keys(
shellSignatures.Collection.attributes as any
shellSignatures.CollectionImpl.attributes as any
);
const adjusted = collComplete
.filter(
Expand Down
4 changes: 2 additions & 2 deletions 4 packages/autocomplete/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,9 @@ async function completer(
): Promise<[string[], string, 'exclusive'] | [string[], string]> {
const SHELL_COMPLETIONS = shellSignatures.ShellApi
.attributes as TypeSignatureAttributes;
const COLL_COMPLETIONS = shellSignatures.Collection
const COLL_COMPLETIONS = shellSignatures.CollectionImpl
.attributes as TypeSignatureAttributes;
const DB_COMPLETIONS = shellSignatures.Database
const DB_COMPLETIONS = shellSignatures.DatabaseImpl
.attributes as TypeSignatureAttributes;
const AGG_CURSOR_COMPLETIONS = shellSignatures.AggregationCursor
.attributes as TypeSignatureAttributes;
Expand Down
10 changes: 5 additions & 5 deletions 10 packages/cli-repl/src/cli-repl.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1667,7 +1667,7 @@ describe('CliRepl', function () {
)
.flat();
expect(apiEvents).to.have.lengthOf(1);
expect(apiEvents[0].properties.class).to.equal('Database');
expect(apiEvents[0].properties.class).to.equal('DatabaseImpl');
expect(apiEvents[0].properties.method).to.equal(
'printShardingStatus'
);
Expand Down Expand Up @@ -1738,8 +1738,8 @@ describe('CliRepl', function () {
e.properties.count,
])
).to.deep.equal([
['Database', 'hello', 2],
['Database', 'hello', 1],
['DatabaseImpl', 'hello', 2],
['DatabaseImpl', 'hello', 1],
]);
});

Expand Down Expand Up @@ -2466,8 +2466,8 @@ describe('CliRepl', function () {
});

afterEach(async function () {
expect(output).not.to.include('Tab completion error');
expect(output).not.to.include(
expect(output, output).not.to.include('Tab completion error');
expect(output, output).not.to.include(
'listCollections requires authentication'
);
await cliRepl.mongoshRepl.close();
Expand Down
2 changes: 1 addition & 1 deletion 2 packages/cli-repl/src/mongosh-repl.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import { MongoshCommandFailed } from '@mongosh/errors';
import type { ServiceProvider } from '@mongosh/service-provider-core';
import { bson } from '@mongosh/service-provider-core';
import { ADMIN_DB } from '@mongosh/shell-api/lib/enums';
import { ADMIN_DB } from '../../shell-api/lib/enums';
import { CliUserConfig } from '@mongosh/types';
import { EventEmitter, once } from 'events';
import path from 'path';
Expand Down
10 changes: 10 additions & 0 deletions 10 packages/shell-api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,16 @@
"description": "MongoDB Shell API Classes Package",
"main": "lib/index.js",
"types": "lib/index.d.ts",
"exports": {
".": {
"default": "./lib/index.js",
"types": "./lib/index.d.ts"
},
"./api": {
"default": "./lib/api.js",
"types": "./lib/api.d.ts"
}
},
"config": {
"unsafe-perm": true
},
Expand Down
1 change: 1 addition & 0 deletions 1 packages/shell-api/src/aggregation-cursor.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ describe('AggregationCursor', function () {
type: 'function',
returnsPromise: false,
deprecated: false,
inherited: true,
returnType: 'AggregationCursor',
platforms: ALL_PLATFORMS,
topologies: ALL_TOPOLOGIES,
Expand Down
8 changes: 4 additions & 4 deletions 8 packages/shell-api/src/bulk.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import type { EventEmitter } from 'events';
import type { StubbedInstance } from 'ts-sinon';
import { stubInterface } from 'ts-sinon';
import Bulk, { BulkFindOp } from './bulk';
import Collection from './collection';
import { CollectionImpl } from './collection';
import { ALL_PLATFORMS, ALL_SERVER_VERSIONS, ALL_TOPOLOGIES } from './enums';
import { signatures, toShellResult } from './index';
import { BulkWriteResult } from './result';
Expand Down Expand Up @@ -57,7 +57,7 @@ describe('Bulk API', function () {
});
describe('Metadata', function () {
describe('toShellResult', function () {
const collection = stubInterface<Collection>();
const collection = stubInterface<CollectionImpl>();
const b = new Bulk(collection, {
batches: [1, 2, 3, 4],
} as any);
Expand All @@ -77,7 +77,7 @@ describe('Bulk API', function () {
['ordered', 'unordered'].forEach((t) => {
describe(t, function () {
describe('commands', function () {
let collection: Collection;
let collection: CollectionImpl;
let serviceProvider: StubbedInstance<ServiceProvider>;
let bulk: Bulk;
let bus: StubbedInstance<EventEmitter>;
Expand All @@ -101,7 +101,7 @@ describe('Bulk API', function () {
serviceProvider.runCommand.resolves({ ok: 1 });
instanceState = new ShellInstanceState(serviceProvider, bus);
const db = instanceState.currentDb;
collection = new Collection(db._mongo, db, 'coll1');
collection = new CollectionImpl(db._mongo, db, 'coll1');
innerStub = stubInterface<any>();
innerStub.batches = [
{ originalZeroIndex: 0 },
Expand Down
125 changes: 86 additions & 39 deletions 125 packages/shell-api/src/collection.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ import {
shellApiType,
ADMIN_DB,
} from './enums';
import Database from './database';
import { DatabaseImpl } from './database';
import Mongo from './mongo';
import Collection from './collection';
import { CollectionImpl } from './collection';
import ChangeStreamCursor from './change-stream-cursor';
import Explainable from './explainable';
import type {
Expand All @@ -33,24 +33,26 @@ import {
MongoshInvalidInputError,
MongoshRuntimeError,
} from '@mongosh/errors';
import type { StringKey } from './helpers';

const sinonChai = require('sinon-chai'); // weird with import

use(sinonChai);
describe('Collection', function () {
describe('help', function () {
const apiClass = new Collection({} as any, {} as any, 'name');
const apiClass = new CollectionImpl({} as any, {} as any, 'name');
it('calls help function', async function () {
expect((await toShellResult(apiClass.help())).type).to.equal('Help');
expect((await toShellResult(apiClass.help)).type).to.equal('Help');
});
});
describe('signatures', function () {
it('type', function () {
expect(signatures.Collection.type).to.equal('Collection');
// TODO: do we want the signatures to be CollectionImpl or Collection?
expect(signatures.CollectionImpl.type).to.equal('CollectionImpl');
});
it('attributes', function () {
expect(signatures.Collection.attributes?.aggregate).to.deep.equal({
expect(signatures.CollectionImpl.attributes?.aggregate).to.deep.equal({
type: 'function',
returnsPromise: true,
deprecated: false,
Expand All @@ -68,10 +70,14 @@ describe('Collection', function () {
describe('metadata', function () {
describe('toShellResult', function () {
const mongo = sinon.spy();
const db = new Database(mongo as any, 'myDB');
const coll = new Collection(mongo as any, db, 'myCollection');
const db = new DatabaseImpl(mongo as any, 'myDB');
const coll = new CollectionImpl(
mongo as any,
db._typeLaunder(),
'myCollection'
);
it('toShellResult', async function () {
expect((await toShellResult(coll)).type).to.equal('Collection');
expect((await toShellResult(coll)).type).to.equal('CollectionImpl');
expect((await toShellResult(coll)).printable).to.equal(
'myDB.myCollection'
);
Expand All @@ -80,21 +86,25 @@ describe('Collection', function () {
});
describe('.collections', function () {
it('allows to get a collection as property if is not one of the existing methods', function () {
const database = new Database(
const database = new DatabaseImpl(
{ _instanceState: { emitApiCallWithArgs: (): void => {} } } as any,
'db1'
);
const coll: any = new Collection({} as any, database, 'coll');
expect(coll.someCollection).to.have.instanceOf(Collection);
const coll: any = new CollectionImpl(
{} as any,
database._typeLaunder(),
'coll'
);
expect(coll.someCollection).to.have.instanceOf(CollectionImpl);
expect(coll.someCollection._name).to.equal('coll.someCollection');
});

it('reuses collections', function () {
const database: any = new Database(
const database: any = new DatabaseImpl(
{ _instanceState: { emitApiCallWithArgs: (): void => {} } } as any,
'db1'
);
const coll: any = new Collection({} as any, database, 'coll');
const coll: any = new CollectionImpl({} as any, database, 'coll');
expect(coll.someCollection).to.equal(
database.getCollection('coll.someCollection')
);
Expand All @@ -103,36 +113,47 @@ describe('Collection', function () {

it('does not return a collection starting with _', function () {
// this is the behaviour in the old shell
const database: any = new Database({} as any, 'db1');
const coll: any = new Collection({} as any, database, 'coll');
const database: any = new DatabaseImpl({} as any, 'db1');
const coll: any = new CollectionImpl({} as any, database, 'coll');
expect(coll._someProperty).to.equal(undefined);
});

it('does not return a collection for symbols', function () {
const database: any = new Database({} as any, 'db1');
const coll: any = new Collection({} as any, database, 'coll');
const database: any = new DatabaseImpl({} as any, 'db1');
const coll: any = new CollectionImpl({} as any, database, 'coll');
expect(coll[Symbol('someProperty')]).to.equal(undefined);
});

it('does not return a collection with invalid name', function () {
const database: any = new Database({} as any, 'db1');
const coll: any = new Collection({} as any, database, 'coll');
const database: any = new DatabaseImpl({} as any, 'db1');
const coll: any = new CollectionImpl({} as any, database, 'coll');
expect(coll.foo$bar).to.equal(undefined);
});

it('allows to access _name', function () {
const database: any = new Database({} as any, 'db1');
const coll: any = new Collection({} as any, database, 'coll');
const database: any = new DatabaseImpl({} as any, 'db1');
const coll: any = new CollectionImpl({} as any, database, 'coll');
expect(coll._name).to.equal('coll');
});
});
describe('commands', function () {
let mongo: Mongo;
type ServerSchema = {
db1: {
coll1: {
schema: {};
};
};
};
let mongo: Mongo<ServerSchema>;
let serviceProvider: StubbedInstance<ServiceProvider>;
let database: Database;
let database: DatabaseImpl<ServerSchema, ServerSchema['db1']>;
let bus: StubbedInstance<EventEmitter>;
let instanceState: ShellInstanceState;
let collection: Collection;
let collection: CollectionImpl<
ServerSchema,
ServerSchema['db1'],
ServerSchema['db1']['coll1']
>;

beforeEach(function () {
bus = stubInterface<EventEmitter>();
Expand All @@ -149,8 +170,15 @@ describe('Collection', function () {
undefined,
serviceProvider
);
database = new Database(mongo, 'db1');
collection = new Collection(mongo, database, 'coll1');
database = new DatabaseImpl<ServerSchema, ServerSchema['db1']>(
mongo,
'db1' as StringKey<ServerSchema>
);
collection = new CollectionImpl<
ServerSchema,
ServerSchema['db1'],
ServerSchema['db1']['coll1']
>(mongo, database._typeLaunder(), 'coll1');
});
describe('aggregate', function () {
let serviceProviderCursor: StubbedInstance<ServiceProviderAggregationCursor>;
Expand Down Expand Up @@ -2802,13 +2830,24 @@ describe('Collection', function () {
});

describe('fle2', function () {
let mongo1: Mongo;
let mongo2: Mongo;
type ServerSchema = {
db1: {
collfle2: {
schema: {};
};
};
};
let mongo1: Mongo<ServerSchema>;
let mongo2: Mongo<ServerSchema>;
let serviceProvider: StubbedInstance<ServiceProvider>;
let database: Database;
let database: DatabaseImpl<ServerSchema, ServerSchema['db1']>;
let bus: StubbedInstance<EventEmitter>;
let instanceState: ShellInstanceState;
let collection: Collection;
let collection: CollectionImpl<
ServerSchema,
ServerSchema['db1'],
ServerSchema['db1']['collfle2']
>;
let keyId: any[];
beforeEach(function () {
bus = stubInterface<EventEmitter>();
Expand All @@ -2821,7 +2860,8 @@ describe('Collection', function () {
keyId = [
{ $binary: { base64: 'oh3caogGQ4Sf34ugKnZ7Xw==', subType: '04' } },
];
mongo1 = new Mongo(

mongo1 = new Mongo<ServerSchema>(
instanceState,
undefined,
{
Expand All @@ -2836,8 +2876,15 @@ describe('Collection', function () {
undefined,
serviceProvider
);
database = new Database(mongo1, 'db1');
collection = new Collection(mongo1, database, 'collfle2');
database = new DatabaseImpl<ServerSchema, ServerSchema['db1']>(
mongo1,
'db1' as StringKey<ServerSchema>
);
collection = new CollectionImpl(
mongo1,
database._typeLaunder(),
'collfle2' as StringKey<ServerSchema['db1']>
);
mongo2 = new Mongo(
instanceState,
undefined,
Expand Down Expand Up @@ -2896,10 +2943,10 @@ describe('Collection', function () {
});
describe('with session', function () {
let serviceProvider: StubbedInstance<ServiceProvider>;
let collection: Collection;
let collection: CollectionImpl;
let internalSession: StubbedInstance<ServiceProviderSession>;
const exceptions: {
[key in keyof (typeof Collection)['prototype']]?: {
[key in keyof (typeof CollectionImpl)['prototype']]?: {
a?: any;
m?: string;
i?: number;
Expand Down Expand Up @@ -2961,7 +3008,7 @@ describe('Collection', function () {
getSearchIndexes: { i: 3 },
checkMetadataConsistency: { m: 'runCursorCommand', i: 2 },
};
const ignore: (keyof (typeof Collection)['prototype'])[] = [
const ignore: (keyof (typeof CollectionImpl)['prototype'])[] = [
'getShardDistribution',
'stats',
'isCapped',
Expand Down Expand Up @@ -3034,8 +3081,8 @@ describe('Collection', function () {
});
context('all commands that use the same command in sp', function () {
for (const method of (
Object.getOwnPropertyNames(Collection.prototype) as (string &
keyof (typeof Collection)['prototype'])[]
Object.getOwnPropertyNames(CollectionImpl.prototype) as (string &
keyof (typeof CollectionImpl)['prototype'])[]
).filter(
(k) =>
typeof k === 'string' &&
Expand All @@ -3045,7 +3092,7 @@ describe('Collection', function () {
if (
!method.startsWith('_') &&
!method.startsWith('print') &&
Collection.prototype[method].returnsPromise
CollectionImpl.prototype[method].returnsPromise
) {
it(`passes the session through for ${method}`, async function () {
try {
Expand Down
Loading
Loading
Morty Proxy This is a proxified and sanitized view of the page, visit original site.