Skip to content
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
9 changes: 6 additions & 3 deletions packages/autocomplete/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -179,8 +179,11 @@ describe('completer.completer', () => {

it('returns all suggestions', async() => {
const i = 'db.';
const dbComplete = Object.keys(shellSignatures.Database.attributes as any);
const adjusted = dbComplete.map(c => `${i}${c}`);
const attr = shellSignatures.Database.attributes as any;
const dbComplete = Object.keys(attr);
const adjusted = dbComplete
.filter(c => !attr[c].deprecated)
.map(c => `${i}${c}`);
expect(await completer(noParams, i)).to.deep.equal([adjusted, i]);
});

Expand Down Expand Up @@ -221,7 +224,7 @@ describe('completer.completer', () => {
it('returns all suggestions', async() => {
const i = 'db.shipwrecks.';
const collComplete = Object.keys(shellSignatures.Collection.attributes as any);
const adjusted = collComplete.filter(c => !['count', 'update', 'remove'].includes(c)).map(c => `${i}${c}`);
const adjusted = collComplete.filter(c => !['count', 'update', 'remove', 'insert', 'save'].includes(c)).map(c => `${i}${c}`);

expect(await completer(sharded440, i)).to.deep.equal([adjusted, i]);
});
Expand Down
42 changes: 28 additions & 14 deletions packages/autocomplete/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* eslint complexity: 0, camelcase: 0, no-nested-ternary: 0 */

import { signatures as shellSignatures, Topologies } from '@mongosh/shell-api';
import { signatures as shellSignatures, Topologies, TypeSignature } from '@mongosh/shell-api';
import semver from 'semver';
import {
CONVERSION_OPERATORS,
Expand All @@ -14,6 +14,8 @@ import {
ON_PREM
} from 'mongodb-ace-autocompleter';

type TypeSignatureAttributes = { [key: string]: TypeSignature };

export interface AutocompleteParameters {
topology: () => Topologies;
connectionInfo: () => undefined | {
Expand Down Expand Up @@ -49,13 +51,13 @@ const GROUP = '$group';
* @returns {array} Matching Completions, Current User Input.
*/
async function completer(params: AutocompleteParameters, line: string): Promise<[string[], string]> {
const SHELL_COMPLETIONS = shellSignatures.ShellApi.attributes;
const COLL_COMPLETIONS = shellSignatures.Collection.attributes;
const DB_COMPLETIONS = shellSignatures.Database.attributes;
const AGG_CURSOR_COMPLETIONS = shellSignatures.AggregationCursor.attributes;
const COLL_CURSOR_COMPLETIONS = shellSignatures.Cursor.attributes;
const RS_COMPLETIONS = shellSignatures.ReplicaSet.attributes;
const SHARD_COMPLETE = shellSignatures.Shard.attributes;
const SHELL_COMPLETIONS = shellSignatures.ShellApi.attributes as TypeSignatureAttributes;
const COLL_COMPLETIONS = shellSignatures.Collection.attributes as TypeSignatureAttributes;
const DB_COMPLETIONS = shellSignatures.Database.attributes as TypeSignatureAttributes;
const AGG_CURSOR_COMPLETIONS = shellSignatures.AggregationCursor.attributes as TypeSignatureAttributes;
const COLL_CURSOR_COMPLETIONS = shellSignatures.Cursor.attributes as TypeSignatureAttributes;
const RS_COMPLETIONS = shellSignatures.ReplicaSet.attributes as TypeSignatureAttributes;
const SHARD_COMPLETE = shellSignatures.Shard.attributes as TypeSignatureAttributes;

// keep initial line param intact to always return in return statement
// check for contents of line with:
Expand Down Expand Up @@ -174,17 +176,29 @@ function filterQueries(params: AutocompleteParameters, completions: any, prefix:
return hits.map(h => `${split}${h.name}`);
}

function filterShellAPI(params: AutocompleteParameters, completions: any, prefix: string, split?: string[]): string[] {
const hits: string[] = Object.keys(completions).filter((c: any) => {
function filterShellAPI(
params: AutocompleteParameters,
completions: { [key: string]: TypeSignature },
prefix: string,
split?: string[]): string[] {
const hits: string[] = Object.keys(completions).filter((c: string) => {
if (!c.startsWith(prefix)) return false;
if (completions[c].deprecated) return false;

const serverVersion = params.connectionInfo()?.server_version;
if (!serverVersion) return true;

const acceptableVersions = completions[c].serverVersions;
const isAcceptableVersion =
(semver.gte(serverVersion, completions[c].serverVersions[0]) &&
semver.lte(serverVersion, completions[c].serverVersions[1]));
!acceptableVersions ||
(semver.gte(serverVersion, acceptableVersions[0]) &&
semver.lte(serverVersion, acceptableVersions[1]));

const acceptableTopologies = completions[c].topologies;
const isAcceptableTopology =
!completions[c].topologies ||
completions[c].topologies.includes(params.topology());
!acceptableTopologies ||
acceptableTopologies.includes(params.topology());

return isAcceptableVersion && isAcceptableTopology;
});

Expand Down
1 change: 1 addition & 0 deletions packages/shell-api/src/aggregation-cursor.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ describe('AggregationCursor', () => {
expect(signatures.AggregationCursor.attributes.map).to.deep.equal({
type: 'function',
returnsPromise: false,
deprecated: false,
returnType: 'AggregationCursor',
platforms: ALL_PLATFORMS,
topologies: ALL_TOPOLOGIES,
Expand Down
2 changes: 2 additions & 0 deletions packages/shell-api/src/bulk.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ describe('Bulk API', () => {
expect(signatures.Bulk.attributes.find).to.deep.equal({
type: 'function',
returnsPromise: false,
deprecated: false,
returnType: 'BulkFindOp',
platforms: ALL_PLATFORMS,
topologies: ALL_TOPOLOGIES,
Expand Down Expand Up @@ -236,6 +237,7 @@ describe('Bulk API', () => {
expect(signatures.BulkFindOp.attributes.hint).to.deep.equal({
type: 'function',
returnsPromise: false,
deprecated: false,
returnType: 'BulkFindOp',
platforms: ALL_PLATFORMS,
topologies: ALL_TOPOLOGIES,
Expand Down
1 change: 1 addition & 0 deletions packages/shell-api/src/change-stream-cursor.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ describe('ChangeStreamCursor', () => {
expect(signatures.ChangeStreamCursor.attributes.next).to.deep.equal({
type: 'function',
returnsPromise: true,
deprecated: false,
returnType: { type: 'unknown', attributes: {} },
platforms: ALL_PLATFORMS,
topologies: ALL_TOPOLOGIES,
Expand Down
4 changes: 3 additions & 1 deletion packages/shell-api/src/change-stream-cursor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import {
returnsPromise,
returnType,
hasAsyncChild,
ShellApiClass
ShellApiClass,
deprecated
} from './decorators';
import {
ChangeStream,
Expand Down Expand Up @@ -58,6 +59,7 @@ export default class ChangeStreamCursor extends ShellApiClass {
}

@returnsPromise
@deprecated
async hasNext(): Promise<void> {
printWarning(
'If there are no documents in the batch, hasNext will block. Use tryNext if you want to check if there ' +
Expand Down
1 change: 1 addition & 0 deletions packages/shell-api/src/collection.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ describe('Collection', () => {
expect(signatures.Collection.attributes.aggregate).to.deep.equal({
type: 'function',
returnsPromise: true,
deprecated: false,
returnType: 'AggregationCursor',
platforms: ALL_PLATFORMS,
topologies: ALL_TOPOLOGIES,
Expand Down
9 changes: 8 additions & 1 deletion packages/shell-api/src/collection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ import {
serverVersions,
ShellApiClass,
shellApiClassDefault,
topologies
topologies,
deprecated
} from './decorators';
import { ADMIN_DB, asPrintable, namespaceInfo, ServerVersions, Topologies } from './enums';
import {
Expand Down Expand Up @@ -233,6 +234,7 @@ export default class Collection extends ShellApiClass {
* @returns {Integer} The promise of the count.
*/
@returnsPromise
@deprecated
@serverVersions([ServerVersions.earliest, '4.0.0'])
async count(query = {}, options: CountOptions = {}): Promise<number> {
this._emitCollectionApiCall(
Expand Down Expand Up @@ -592,6 +594,8 @@ export default class Collection extends ShellApiClass {
* @return {InsertManyResult}
*/
@returnsPromise
@deprecated
@serverVersions([ServerVersions.earliest, '3.6.0'])
async insert(docs: Document | Document[], options: BulkWriteOptions = {}): Promise<InsertManyResult> {
printDeprecationWarning(
'Collection.insert() is deprecated. Use insertOne, insertMany or bulkWrite.',
Expand Down Expand Up @@ -702,6 +706,7 @@ export default class Collection extends ShellApiClass {
* @return {Promise}
*/
@returnsPromise
@deprecated
@serverVersions([ServerVersions.earliest, '3.2.0'])
async remove(query: Document, options: boolean | RemoveShellOptions = {}): Promise<DeleteResult | Document> {
printDeprecationWarning(
Expand Down Expand Up @@ -730,6 +735,7 @@ export default class Collection extends ShellApiClass {
}

@returnsPromise
@deprecated
save(): Promise<void> {
throw new MongoshInvalidInputError('Collection.save() is deprecated. Use insertOne, insertMany, updateOne or updateMany.');
}
Expand Down Expand Up @@ -772,6 +778,7 @@ export default class Collection extends ShellApiClass {
}

@returnsPromise
@deprecated
@serverVersions([ServerVersions.earliest, '3.2.0'])
async update(filter: Document, update: Document, options: UpdateOptions & { multi?: boolean } = {}): Promise<UpdateResult | Document> {
printDeprecationWarning(
Expand Down
1 change: 1 addition & 0 deletions packages/shell-api/src/cursor.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ describe('Cursor', () => {
expect(signatures.Cursor.attributes.map).to.deep.equal({
type: 'function',
returnsPromise: false,
deprecated: false,
returnType: 'Cursor',
platforms: ALL_PLATFORMS,
topologies: ALL_TOPOLOGIES,
Expand Down
5 changes: 3 additions & 2 deletions packages/shell-api/src/cursor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ import {
serverVersions,
ShellApiClass,
shellApiClassDefault,
toShellResult
toShellResult,
deprecated
} from './decorators';
import {
ServerVersions,
Expand Down Expand Up @@ -75,7 +76,6 @@ export default class Cursor extends ShellApiClass {
if (optionFlagNumber === 4) {
throw new MongoshUnimplementedError('the slaveOk option is not supported.', CommonErrors.NotImplemented);
}

const optionFlag: CursorFlag | undefined = (CURSOR_FLAGS as any)[optionFlagNumber];

if (!optionFlag) {
Expand Down Expand Up @@ -340,6 +340,7 @@ export default class Cursor extends ShellApiClass {
return this;
}

@deprecated
@serverVersions([ServerVersions.earliest, '4.0.0'])
maxScan(): void {
throw new MongoshDeprecatedError(
Expand Down
1 change: 1 addition & 0 deletions packages/shell-api/src/database.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ describe('Database', () => {
expect(signatures.Database.attributes.aggregate).to.deep.equal({
type: 'function',
returnsPromise: true,
deprecated: false,
returnType: 'AggregationCursor',
platforms: ALL_PLATFORMS,
topologies: ALL_TOPOLOGIES,
Expand Down
7 changes: 6 additions & 1 deletion packages/shell-api/src/database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ import {
serverVersions,
ShellApiClass,
shellApiClassDefault,
topologies
topologies,
deprecated
} from './decorators';
import { ADMIN_DB, asPrintable, ServerVersions, Topologies } from './enums';
import {
Expand Down Expand Up @@ -1024,14 +1025,17 @@ export default class Database extends ShellApiClass {
return result.logComponentVerbosity;
}

@deprecated
cloneDatabase(): void {
throw new MongoshDeprecatedError('`cloneDatabase()` was removed because it was deprecated in MongoDB 4.0');
}

@deprecated
cloneCollection(): void {
throw new MongoshDeprecatedError('`cloneCollection()` was removed because it was deprecated in MongoDB 4.0');
}

@deprecated
copyDatabase(): void {
throw new MongoshDeprecatedError('`copyDatabase()` was removed because it was deprecated in MongoDB 4.0');
}
Expand Down Expand Up @@ -1248,6 +1252,7 @@ export default class Database extends ShellApiClass {
return new CommandResult('StatsResult', result);
}

@deprecated
@returnsPromise
async printSlaveReplicationInfo(): Promise<CommandResult> {
throw new MongoshDeprecatedError('Method deprecated, use db.printSecondaryReplicationInfo instead');
Expand Down
21 changes: 18 additions & 3 deletions packages/shell-api/src/decorators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,10 +133,13 @@ function wrapWithAddSourceToResult(fn: Function): Function {
return wrapper;
}

interface TypeSignature {
export interface TypeSignature {
type: string;
hasAsyncChild?: boolean;
serverVersions?: [ string, string ];
topologies?: Topologies[];
returnsPromise?: boolean;
deprecated?: boolean;
returnType?: string | TypeSignature;
attributes?: { [key: string]: TypeSignature };
}
Expand All @@ -156,13 +159,15 @@ type ClassSignature = {
type: string;
hasAsyncChild: boolean;
returnsPromise: boolean;
deprecated: boolean;
attributes: {
[methodName: string]: {
type: 'function';
serverVersions: [ string, string ];
topologies: Topologies[];
returnType: ClassSignature;
returnsPromise: boolean;
deprecated: boolean;
platforms: ReplPlatform[];
}
};
Expand All @@ -187,6 +192,7 @@ export function shellApiClassDefault(constructor: Function): void {
type: className,
hasAsyncChild: constructor.prototype.hasAsyncChild || false,
returnsPromise: constructor.prototype.returnsPromise || false,
deprecated: constructor.prototype.deprecated || false,
attributes: {}
};

Expand All @@ -209,6 +215,7 @@ export function shellApiClassDefault(constructor: Function): void {
method.topologies = method.topologies || ALL_TOPOLOGIES;
method.returnType = method.returnType || { type: 'unknown', attributes: {} };
method.returnsPromise = method.returnsPromise || false;
method.deprecated = method.deprecated || false;
method.platforms = method.platforms || ALL_PLATFORMS;

classSignature.attributes[propertyName] = {
Expand All @@ -217,6 +224,7 @@ export function shellApiClassDefault(constructor: Function): void {
topologies: method.topologies,
returnType: method.returnType,
returnsPromise: method.returnsPromise,
deprecated: method.deprecated,
platforms: method.platforms
};

Expand Down Expand Up @@ -262,6 +270,7 @@ export function shellApiClassDefault(constructor: Function): void {
topologies: method.topologies,
returnType: method.returnType,
returnsPromise: method.returnsPromise,
deprecated: method.deprecated,
platforms: method.platforms
};

Expand All @@ -284,7 +293,7 @@ export function shellApiClassDefault(constructor: Function): void {
}

export { signatures };
export function serverVersions(versionArray: any[]): Function {
export function serverVersions(versionArray: [ string, string ]): Function {
return function(
_target: any,
_propertyKey: string,
Expand All @@ -293,7 +302,10 @@ export function serverVersions(versionArray: any[]): Function {
descriptor.value.serverVersions = versionArray;
};
}
export function topologies(topologiesArray: any[]): Function {
export function deprecated(_target: any, _propertyKey: string, descriptor: PropertyDescriptor): void {
descriptor.value.deprecated = true;
}
export function topologies(topologiesArray: Topologies[]): Function {
return function(
_target: any,
_propertyKey: string,
Expand Down Expand Up @@ -323,6 +335,9 @@ export function hasAsyncChild(constructor: Function): void {
export function classReturnsPromise(constructor: Function): void {
constructor.prototype.returnsPromise = true;
}
export function classDeprecated(constructor: Function): void {
constructor.prototype.deprecated = true;
}
export function platforms(platformsArray: any[]): Function {
return function(
_target: any,
Expand Down
4 changes: 3 additions & 1 deletion packages/shell-api/src/deprecated.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import {
ShellApiClass,
shellApiClassDefault
shellApiClassDefault,
classDeprecated
} from './decorators';
import { asPrintable } from './enums';
import { MongoshDeprecatedError } from '@mongosh/errors';


@shellApiClassDefault
@classDeprecated
class DeprecatedClass extends ShellApiClass {
public name: string;
constructor(name: string, alternatives: Record<string, string> = {}) {
Expand Down
Loading