From 674d246b3ba6f67f8e5ba5953e3d2582b92f5db8 Mon Sep 17 00:00:00 2001 From: Irina Shestak Date: Tue, 12 May 2020 19:02:19 +0200 Subject: [PATCH] add eslint to cli-repl (#172) --- config/eslintrc.base.js | 3 + packages/cli-repl/.eslintignore | 2 + packages/cli-repl/.eslintrc.js | 1 + packages/cli-repl/bin/mongosh.js | 6 +- packages/cli-repl/package.json | 2 + packages/cli-repl/src/arg-mapper.ts | 2 +- packages/cli-repl/src/arg-parser.ts | 3 +- packages/cli-repl/src/cli-options.ts | 4 +- packages/cli-repl/src/cli-repl.spec.ts | 4 +- packages/cli-repl/src/cli-repl.ts | 59 +++--- packages/cli-repl/src/clr.ts | 2 +- packages/cli-repl/src/completer.spec.ts | 220 ++++++++++---------- packages/cli-repl/src/completer.ts | 39 ++-- packages/cli-repl/src/connect-info.spec.ts | 94 ++++----- packages/cli-repl/src/connect-info.ts | 19 +- packages/cli-repl/src/constants.ts | 4 +- packages/cli-repl/src/format-output.spec.ts | 35 ++-- packages/cli-repl/src/format-output.ts | 46 ++-- packages/cli-repl/src/index.ts | 4 +- packages/cli-repl/src/logger.ts | 37 ++-- packages/cli-repl/src/uri-generator.spec.ts | 10 +- packages/cli-repl/src/uri-generator.ts | 13 +- packages/cli-repl/test/e2e.spec.ts | 24 +-- packages/cli-repl/test/helpers.ts | 15 +- 24 files changed, 335 insertions(+), 313 deletions(-) create mode 100644 packages/cli-repl/.eslintignore create mode 100644 packages/cli-repl/.eslintrc.js diff --git a/config/eslintrc.base.js b/config/eslintrc.base.js index 853e52188..a38808cf1 100644 --- a/config/eslintrc.base.js +++ b/config/eslintrc.base.js @@ -13,8 +13,11 @@ module.exports = { ], rules: { 'object-curly-spacing': [2, 'always'], + 'no-empty-function': 0, 'valid-jsdoc': 0, 'react/sort-comp': 0, // does not seem work as expected with typescript + '@typescript-eslint/no-empty-function': 0, + '@typescript-eslint/no-use-before-define': 0, '@typescript-eslint/no-explicit-any': 0, '@typescript-eslint/no-var-requires': 0, // seems necessary to import less files '@typescript-eslint/no-unused-vars': 2, diff --git a/packages/cli-repl/.eslintignore b/packages/cli-repl/.eslintignore new file mode 100644 index 000000000..491fc3597 --- /dev/null +++ b/packages/cli-repl/.eslintignore @@ -0,0 +1,2 @@ +node_modules +lib diff --git a/packages/cli-repl/.eslintrc.js b/packages/cli-repl/.eslintrc.js new file mode 100644 index 000000000..4a958b44b --- /dev/null +++ b/packages/cli-repl/.eslintrc.js @@ -0,0 +1 @@ +module.exports = require('../../config/eslintrc.base'); diff --git a/packages/cli-repl/bin/mongosh.js b/packages/cli-repl/bin/mongosh.js index 16529c126..6c2858ac1 100755 --- a/packages/cli-repl/bin/mongosh.js +++ b/packages/cli-repl/bin/mongosh.js @@ -1,6 +1,6 @@ -#!/bin/sh -':' //; node --experimental-repl-await "$0" "$@" +#!/usr/bin/env node +/* eslint no-console: 0, no-new: 0*/ const { CliRepl, parseCliArgs, mapCliToDriver, generateUri, USAGE } = require('../lib'); process.title = 'mongosh'; @@ -18,7 +18,7 @@ try { const driverUri = generateUri(options); const appname = `${process.title} ${version}`; - new CliRepl(driverUri, {appname, ...driverOptions}, options); + new CliRepl(driverUri, { appname, ...driverOptions }, options); } } catch (e) { console.log(e.message); diff --git a/packages/cli-repl/package.json b/packages/cli-repl/package.json index ee4673838..60295d245 100644 --- a/packages/cli-repl/package.json +++ b/packages/cli-repl/package.json @@ -20,6 +20,8 @@ "start-async": "node --experimental-repl-await bin/mongosh.js start --async", "test": "mocha --timeout 15000 --colors -r ts-node/register \"./{src,test}/**/*.spec.ts\"", "test-ci": "mocha --timeout 15000 -r ts-node/register \"./{src,test}/**/*.spec.ts\"", + "lint": "eslint \"**/*.{js,ts,tsx}\"", + "check": "npm run lint", "prepublish": "npm run compile-ts" }, "license": "Apache-2.0", diff --git a/packages/cli-repl/src/arg-mapper.ts b/packages/cli-repl/src/arg-mapper.ts index 7c8caae64..c418bc19d 100644 --- a/packages/cli-repl/src/arg-mapper.ts +++ b/packages/cli-repl/src/arg-mapper.ts @@ -49,6 +49,6 @@ function mapCliToDriver(options: CliOptions): NodeOptions { } }); return nodeOptions; -}; +} export default mapCliToDriver; diff --git a/packages/cli-repl/src/arg-parser.ts b/packages/cli-repl/src/arg-parser.ts index 1dc1a25eb..11de7f400 100644 --- a/packages/cli-repl/src/arg-parser.ts +++ b/packages/cli-repl/src/arg-parser.ts @@ -3,7 +3,6 @@ import { USAGE } from './constants'; import i18n from '@mongosh/i18n'; import minimist from 'minimist'; import clr from './clr'; -import os from 'os'; /** * Unknown translation key. @@ -66,7 +65,7 @@ const OPTIONS = { p: 'password', u: 'username' }, - unknown: (parameter) => { + unknown: (parameter: string): boolean => { if (parameter === START) { return false; } diff --git a/packages/cli-repl/src/cli-options.ts b/packages/cli-repl/src/cli-options.ts index 74ac06067..7f149d732 100644 --- a/packages/cli-repl/src/cli-options.ts +++ b/packages/cli-repl/src/cli-options.ts @@ -1,7 +1,7 @@ /** * Valid options that can be parsed from the command line. */ -interface CliOptions { +export default interface CliOptions { _?: string[]; async?: boolean; authenticationDatabase?: string; @@ -44,5 +44,3 @@ interface CliOptions { verbose?: boolean; version?: boolean; } - -export default CliOptions; diff --git a/packages/cli-repl/src/cli-repl.spec.ts b/packages/cli-repl/src/cli-repl.spec.ts index de595fe70..9dbcbff4b 100644 --- a/packages/cli-repl/src/cli-repl.spec.ts +++ b/packages/cli-repl/src/cli-repl.spec.ts @@ -2,6 +2,8 @@ import { expect } from 'chai'; describe('cli-repl', () => { context('placeholder', () => { - it('passes', () => {}); + it('passes', () => { + expect(true).to.be.true; + }); }); }); diff --git a/packages/cli-repl/src/cli-repl.ts b/packages/cli-repl/src/cli-repl.ts index 6967b1338..fba581fb5 100644 --- a/packages/cli-repl/src/cli-repl.ts +++ b/packages/cli-repl/src/cli-repl.ts @@ -1,3 +1,5 @@ +/* eslint no-console: 0, no-sync: 0*/ + import { CliServiceProvider, NodeOptions } from '@mongosh/service-provider-server'; import formatOutput, { formatError } from './format-output'; import ShellEvaluator from '@mongosh/shell-evaluator'; @@ -103,46 +105,44 @@ class CliRepl { const version = this.buildInfo.version; this.repl = repl.start({ - prompt: `> `, + prompt: '> ', writer: this.writer, completer: completer.bind(null, version), }); const originalEval = util.promisify(this.repl.eval); - const customEval = async(input, context, filename, callback) => { + const customEval = async(input, context, filename, callback): Promise => { let result; - let err = null; try { result = await this.ShellEvaluator.customEval(originalEval, input, context, filename); } catch (err) { if (isRecoverableError(input)) { return callback(new Recoverable(err)); - } else { - result = err; } + result = err; } - callback (null, result) + callback(null, result); }; - // @ts-ignore - this.repl.eval = customEval; + (this.repl as any).eval = customEval; - const historyFile = path.join(this.mongoshDir, '.mongosh_repl_history'); + const historyFile = path.join(this.mongoshDir, '.mongosh_repl_history'); const redactInfo = this.options.redactInfo; + // eslint thinks we are redefining this.repl here, we are not. + // eslint-disable-next-line no-shadow this.repl.setupHistory(historyFile, function(err, repl) { - const warn = new MongoshWarning('Unable to set up history file. History will not be persisting in this session') + const warn = new MongoshWarning('Unable to set up history file. History will not be persisting in this session'); if (err) this.writer(warn); // repl.history is an array of previous commands. We need to hijack the // value we just typed, and shift it off the history array if the info is // sensitive. repl.on('flushHistory', function() { - // @ts-ignore - changeHistory(repl.history, redactInfo); - }) - }) + changeHistory((repl as any).history, redactInfo); + }); + }); this.repl.on('exit', () => { this.serviceProvider.close(true); @@ -183,7 +183,7 @@ class CliRepl { // error is thrown here for atlas and DataLake connections. // don't actually throw, as this is only used to log out non-genuine // mongodb connections - this.bus.emit('mongosh:error', e) + this.bus.emit('mongosh:error', e); return null; } } @@ -194,7 +194,7 @@ class CliRepl { createMongoshDir(): void { try { mkdirp.sync(this.mongoshDir); - } catch(e) { + } catch (e) { this.bus.emit('mongosh:error', e); throw e; } @@ -215,7 +215,7 @@ class CliRepl { try { fd = fs.openSync(configPath, 'wx'); this.userId = new ObjectId(Date.now()); - this.enableTelemetry = true ; + this.enableTelemetry = true; this.disableGreetingMessage = false; this.bus.emit('mongosh:new-user', this.userId, this.enableTelemetry); this.writeConfigFileSync(configPath); @@ -228,9 +228,8 @@ class CliRepl { this.bus.emit('mongosh:update-user', this.userId, this.enableTelemetry); return; } - this.bus.emit('mongosh:error', err) + this.bus.emit('mongosh:error', err); throw err; - } finally { if (fd !== undefined) fs.closeSync(fd); } @@ -254,16 +253,16 @@ class CliRepl { if (enabled) { return i18n.__('cli-repl.cli-repl.enabledTelemetry'); - } else { - return i18n.__('cli-repl.cli-repl.disabledTelemetry'); } + + return i18n.__('cli-repl.cli-repl.disabledTelemetry'); } /** write file sync given path and contents * - * @param {string} path - path to file + * @param {string} filePath - path to file */ - writeConfigFileSync(path: string): void { + writeConfigFileSync(filePath: string): void { const config = { userId: this.userId, enableTelemetry: this.enableTelemetry, @@ -271,9 +270,9 @@ class CliRepl { }; try { - fs.writeFileSync(path, JSON.stringify(config)); - } catch(err) { - this.bus.emit('mongosh:error', err) + fs.writeFileSync(filePath, JSON.stringify(config)); + } catch (err) { + this.bus.emit('mongosh:error', err); throw err; } } @@ -289,11 +288,11 @@ class CliRepl { this.bus.emit('mongosh:error', result); this.ShellEvaluator.revertState(); - return formatOutput({type: 'Error', value: result}); + return formatOutput({ type: 'Error', value: result }); } return formatOutput(result); - } + }; /** * The greeting for the shell. @@ -314,7 +313,7 @@ class CliRepl { isPasswordMissing(driverOptions: NodeOptions): boolean { return driverOptions.auth && driverOptions.auth.user && - !driverOptions.auth.password + !driverOptions.auth.password; } /** @@ -330,6 +329,8 @@ class CliRepl { replace: '*' }; read(readOptions, (error, password) => { + if (error) return console.log(formatError(error)); + driverOptions.auth.password = password; this.connect(driverUri, driverOptions); }); diff --git a/packages/cli-repl/src/clr.ts b/packages/cli-repl/src/clr.ts index bb9d6974d..7ec0203e1 100644 --- a/packages/cli-repl/src/clr.ts +++ b/packages/cli-repl/src/clr.ts @@ -1,5 +1,5 @@ import ansi from 'ansi-escape-sequences'; -export default function clr(text, style) { +export default function clr(text: string, style: any): string { return process.stdout.isTTY ? ansi.format(text, style) : text; } diff --git a/packages/cli-repl/src/completer.spec.ts b/packages/cli-repl/src/completer.spec.ts index 060c74a2a..a5cdedecb 100644 --- a/packages/cli-repl/src/completer.spec.ts +++ b/packages/cli-repl/src/completer.spec.ts @@ -67,8 +67,8 @@ describe('completer.completer', () => { it('returns all suggestions', () => { const i = 'db.shipwrecks.'; - const collComplete = Object.keys(shellSignatures.Collection.attributes) - const adjusted = collComplete.map(c => `${i}${c}`) + const collComplete = Object.keys(shellSignatures.Collection.attributes); + const adjusted = collComplete.map(c => `${i}${c}`); expect(completer('4.4.0', i)).to.deep.equal([adjusted, i]); }); @@ -98,8 +98,8 @@ describe('completer.completer', () => { it('returns all suggestions', () => { const i = 'db.shipwrecks.aggregate([{$sort: {feature_type: 1}}]).'; - const aggCursorComplete = Object.keys(shellSignatures.AggregationCursor.attributes) - const adjusted = aggCursorComplete.map(c => `${i}${c}`) + const aggCursorComplete = Object.keys(shellSignatures.AggregationCursor.attributes); + const adjusted = aggCursorComplete.map(c => `${i}${c}`); expect(completer('4.4.0', i)).to.deep.equal([adjusted, i]); }); @@ -125,7 +125,7 @@ describe('completer.completer', () => { const i = 'db.shipwrecks.aggregate([ { $so'; expect(completer('4.4.0', i)).to.deep.equal([ ['db.shipwrecks.aggregate([ { $sort', - 'db.shipwrecks.aggregate([ { $sortByCount'], i]); + 'db.shipwrecks.aggregate([ { $sortByCount'], i]); }); it('does not have a match', () => { @@ -144,51 +144,51 @@ describe('completer.completer', () => { it('returns all suggestions', () => { const i = 'db.shipwrecks.find({ '; expect(completer('4.4.0', i)[0]).to.include.members( - [ 'db.shipwrecks.find({ $all', - 'db.shipwrecks.find({ $and', - 'db.shipwrecks.find({ $bitsAllClear', - 'db.shipwrecks.find({ $bitsAllSet', - 'db.shipwrecks.find({ $bitsAnyClear', - 'db.shipwrecks.find({ $bitsAnySet', - 'db.shipwrecks.find({ $comment', - 'db.shipwrecks.find({ $elemMatch', - 'db.shipwrecks.find({ $eq', - 'db.shipwrecks.find({ $exists', - 'db.shipwrecks.find({ $expr', - 'db.shipwrecks.find({ $geoIntersects', - 'db.shipwrecks.find({ $geoWithin', - 'db.shipwrecks.find({ $gt', - 'db.shipwrecks.find({ $gte', - 'db.shipwrecks.find({ $in', - 'db.shipwrecks.find({ $jsonSchema', - 'db.shipwrecks.find({ $lt', - 'db.shipwrecks.find({ $lte', - 'db.shipwrecks.find({ $mod', - 'db.shipwrecks.find({ $ne', - 'db.shipwrecks.find({ $near', - 'db.shipwrecks.find({ $nearSphere', - 'db.shipwrecks.find({ $nin', - 'db.shipwrecks.find({ $not', - 'db.shipwrecks.find({ $nor', - 'db.shipwrecks.find({ $or', - 'db.shipwrecks.find({ $regex', - 'db.shipwrecks.find({ $size', - 'db.shipwrecks.find({ $slice', - 'db.shipwrecks.find({ $text', - 'db.shipwrecks.find({ $type', - 'db.shipwrecks.find({ $where', - 'db.shipwrecks.find({ Code', - 'db.shipwrecks.find({ ObjectId', - 'db.shipwrecks.find({ Binary', - 'db.shipwrecks.find({ DBRef', - 'db.shipwrecks.find({ Timestamp', - 'db.shipwrecks.find({ NumberInt', - 'db.shipwrecks.find({ NumberLong', - 'db.shipwrecks.find({ NumberDecimal', - 'db.shipwrecks.find({ MaxKey', - 'db.shipwrecks.find({ MinKey', - 'db.shipwrecks.find({ ISODate', - 'db.shipwrecks.find({ RegExp' ]); + [ 'db.shipwrecks.find({ $all', + 'db.shipwrecks.find({ $and', + 'db.shipwrecks.find({ $bitsAllClear', + 'db.shipwrecks.find({ $bitsAllSet', + 'db.shipwrecks.find({ $bitsAnyClear', + 'db.shipwrecks.find({ $bitsAnySet', + 'db.shipwrecks.find({ $comment', + 'db.shipwrecks.find({ $elemMatch', + 'db.shipwrecks.find({ $eq', + 'db.shipwrecks.find({ $exists', + 'db.shipwrecks.find({ $expr', + 'db.shipwrecks.find({ $geoIntersects', + 'db.shipwrecks.find({ $geoWithin', + 'db.shipwrecks.find({ $gt', + 'db.shipwrecks.find({ $gte', + 'db.shipwrecks.find({ $in', + 'db.shipwrecks.find({ $jsonSchema', + 'db.shipwrecks.find({ $lt', + 'db.shipwrecks.find({ $lte', + 'db.shipwrecks.find({ $mod', + 'db.shipwrecks.find({ $ne', + 'db.shipwrecks.find({ $near', + 'db.shipwrecks.find({ $nearSphere', + 'db.shipwrecks.find({ $nin', + 'db.shipwrecks.find({ $not', + 'db.shipwrecks.find({ $nor', + 'db.shipwrecks.find({ $or', + 'db.shipwrecks.find({ $regex', + 'db.shipwrecks.find({ $size', + 'db.shipwrecks.find({ $slice', + 'db.shipwrecks.find({ $text', + 'db.shipwrecks.find({ $type', + 'db.shipwrecks.find({ $where', + 'db.shipwrecks.find({ Code', + 'db.shipwrecks.find({ ObjectId', + 'db.shipwrecks.find({ Binary', + 'db.shipwrecks.find({ DBRef', + 'db.shipwrecks.find({ Timestamp', + 'db.shipwrecks.find({ NumberInt', + 'db.shipwrecks.find({ NumberLong', + 'db.shipwrecks.find({ NumberDecimal', + 'db.shipwrecks.find({ MaxKey', + 'db.shipwrecks.find({ MinKey', + 'db.shipwrecks.find({ ISODate', + 'db.shipwrecks.find({ RegExp' ]); }); it('has several matches', () => { @@ -225,38 +225,38 @@ describe('completer.completer', () => { const i = 'db.shipwrecks.find({feature_type: "Wrecks - Visible"}).'; const result = [ - 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).allowPartialResults', - 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).arrayAccess', - 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).batchSize', - 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).clone', - 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).close', - 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).collation', - 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).comment', - 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).count', - 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).explain', + 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).allowPartialResults', + 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).arrayAccess', + 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).batchSize', + 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).clone', + 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).close', + 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).collation', + 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).comment', + 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).count', + 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).explain', 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).forEach', - 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).hasNext', - 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).hint', - 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).isClosed', - 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).isExhausted', - 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).itcount', - 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).limit', - 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).map', - 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).max', - 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).maxTimeMS', - 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).min', - 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).next', - 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).noCursorTimeout', - 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).oplogReplay', - 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).projection', - 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).readPref', - 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).returnKey', - 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).size', - 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).skip', - 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).sort', - 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).tailable', - 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).toArray', - ] + 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).hasNext', + 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).hint', + 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).isClosed', + 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).isExhausted', + 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).itcount', + 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).limit', + 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).map', + 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).max', + 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).maxTimeMS', + 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).min', + 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).next', + 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).noCursorTimeout', + 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).oplogReplay', + 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).projection', + 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).readPref', + 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).returnKey', + 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).size', + 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).skip', + 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).sort', + 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).tailable', + 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).toArray', + ]; expect(completer('4.4.0', i)[0]).to.include.members(result); }); @@ -265,35 +265,35 @@ describe('completer.completer', () => { const i = 'db.shipwrecks.find({feature_type: "Wrecks - Visible"}).'; const result = [ - 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).addOption', - 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).allowPartialResults', - 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).arrayAccess', - 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).batchSize', - 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).clone', - 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).close', - 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).count', - 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).explain', - 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).forEach', - 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).hasNext', - 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).hint', - 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).isClosed', - 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).isExhausted', - 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).itcount', - 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).limit', - 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).map', - 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).max', - 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).maxTimeMS', - 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).min', - 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).next', - 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).noCursorTimeout', - 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).oplogReplay', - 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).projection', - 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).readPref', - 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).size', - 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).skip', - 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).sort', - 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).toArray', - ] + 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).addOption', + 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).allowPartialResults', + 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).arrayAccess', + 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).batchSize', + 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).clone', + 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).close', + 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).count', + 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).explain', + 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).forEach', + 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).hasNext', + 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).hint', + 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).isClosed', + 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).isExhausted', + 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).itcount', + 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).limit', + 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).map', + 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).max', + 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).maxTimeMS', + 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).min', + 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).next', + 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).noCursorTimeout', + 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).oplogReplay', + 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).projection', + 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).readPref', + 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).size', + 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).skip', + 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).sort', + 'db.shipwrecks.find({feature_type: \"Wrecks - Visible\"}).toArray', + ]; expect(completer('3.0.0', i)[0]).to.include.members(result); }); diff --git a/packages/cli-repl/src/completer.ts b/packages/cli-repl/src/completer.ts index 5c28dd406..6bda2e4ef 100644 --- a/packages/cli-repl/src/completer.ts +++ b/packages/cli-repl/src/completer.ts @@ -1,3 +1,5 @@ +/* eslint complexity: 0 */ + import { signatures as shellSignatures } from '@mongosh/shell-api'; import { shellApiSignature } from '@mongosh/shell-evaluator'; import semver from 'semver'; @@ -7,11 +9,11 @@ import { STAGE_OPERATORS, QUERY_OPERATORS, ACCUMULATORS, - BSON_TYPES } from 'mongodb-ace-autocompleter' + BSON_TYPES } from 'mongodb-ace-autocompleter'; const BASE_COMPLETIONS = EXPRESSION_OPERATORS.concat( CONVERSION_OPERATORS.concat(BSON_TYPES.concat(STAGE_OPERATORS) -)); + )); const MATCH_COMPLETIONS = QUERY_OPERATORS.concat(BSON_TYPES); @@ -33,16 +35,6 @@ const PROJECT = '$project'; */ const GROUP = '$group'; -/** - * The match operator. - */ -const MATCH = '$match'; - -/** - * The dollar const. - */ -const DOLLAR = '$'; - /** * Return complete suggestions given currently typed line * @@ -55,9 +47,8 @@ function completer(mdbVersion: string, line: string): [string[], string] { // check for contents of line with: const splitLine = line.split('.'); const firstLineEl = splitLine[0]; - const elToComplete = splitLine[splitLine.length-1]; + const elToComplete = splitLine[splitLine.length - 1]; - // suggest SHELLAPI commands if (splitLine.length <= 1) { // TODO: this should also explicitly suggest 'sh', 'rs', and 'db' strings const hits = filterShellAPI(mdbVersion, SHELL_COMPLETIONS, elToComplete); @@ -72,7 +63,7 @@ function completer(mdbVersion: string, line: string): [string[], string] { if (splitLine[2].includes('aggregate')) { const hits = filterShellAPI( mdbVersion, AGG_CURSOR_COMPLETIONS, elToComplete, splitLine); - return [hits.length ? hits: [], line]; + return [hits.length ? hits : [], line]; } // collection cursor completions const hits = filterShellAPI( @@ -92,16 +83,16 @@ function completer(mdbVersion: string, line: string): [string[], string] { expressions = MATCH_COMPLETIONS; } // split on {, as a stage/query will always follow an open curly brace - const splitQuery = line.split("{"); + const splitQuery = line.split('{'); const prefix = splitQuery.pop().trim(); const command = prefix !== '' ? line.split(prefix).shift() : line; const hits = filterQueries(mdbVersion, expressions, prefix, command); - return [hits.length ? hits: [], line] + return [hits.length ? hits : [], line]; } const hits = filterShellAPI( mdbVersion, COLL_COMPLETIONS, elToComplete, splitLine); - return [hits.length ? hits: [], line]; + return [hits.length ? hits : [], line]; } else if (firstLineEl.includes('sh')) { const hits = filterShellAPI( mdbVersion, SHARD_COMPLETE, elToComplete, splitLine); @@ -116,8 +107,8 @@ function completer(mdbVersion: string, line: string): [string[], string] { } // stage completions based on current stage string. -function getStageAccumulators(stage: string, mdbVersion: string) { - if (stage !== '') return [] ; +function getStageAccumulators(stage: string, mdbVersion: string): any { + if (stage !== '') return []; if (stage.includes(PROJECT)) { return ACCUMULATORS.filter(acc => { @@ -130,21 +121,21 @@ function getStageAccumulators(stage: string, mdbVersion: string) { } } -function filterQueries(mdbVersion: string, completions: any, prefix: string, split: string) { +function filterQueries(mdbVersion: string, completions: any, prefix: string, split: string): any { const hits = completions.filter((e) => { if (!e.name) return false; return e.name.startsWith(prefix) && semver.gte(mdbVersion, e.version); - }) + }); const adjusted = hits.map(h => `${split}${h.name}`); return adjusted; } -function filterShellAPI(mdbVersion: string, completions: object, prefix: string, split?: string[]) { +function filterShellAPI(mdbVersion: string, completions: object, prefix: string, split?: string[]): any { const hits = Object.keys(completions).filter((c) => { return c.startsWith(prefix) && semver.gte(mdbVersion, completions[c].serverVersions[0]) - && semver.lte(mdbVersion, completions[c].serverVersions[1]) + && semver.lte(mdbVersion, completions[c].serverVersions[1]); }); if (split) { diff --git a/packages/cli-repl/src/connect-info.spec.ts b/packages/cli-repl/src/connect-info.spec.ts index 1c1bbd8f2..8e600aa1b 100644 --- a/packages/cli-repl/src/connect-info.spec.ts +++ b/packages/cli-repl/src/connect-info.spec.ts @@ -3,59 +3,59 @@ import getConnectInfo from './connect-info'; describe('getConnectInfo', function() { const BUILD_INFO = { - 'version' : '3.2.0-rc2', - 'gitVersion' : '8a3acb42742182c5e314636041c2df368232bbc5', - 'modules' : [ - 'enterprise' - ], - 'allocator' : 'system', - 'javascriptEngine' : 'mozjs', - 'sysInfo' : 'deprecated', - 'versionArray' : [ - 3, - 2, - 0, - -48 - ], - 'openssl' : { - 'running' : 'OpenSSL 0.9.8zg 14 July 2015', - 'compiled' : 'OpenSSL 0.9.8y 5 Feb 2013' - }, - 'buildEnvironment' : { - 'distmod' : '', - 'distarch' : 'x86_64', - 'cc' : 'gcc: Apple LLVM version 5.1 (clang-503.0.40) (based on LLVM 3.4svn)', - 'ccflags' : '-fno-omit-frame-pointer -fPIC -fno-strict-aliasing -ggdb -pthread -Wall -Wsign-compare -Wno-unknown-pragmas -Winvalid-pch -Werror -O2 -Wno-unused-function -Wno-unused-private-field -Wno-deprecated-declarations -Wno-tautological-constant-out-of-range-compare -Wno-unused-const-variable -Wno-missing-braces -mmacosx-version-min=10.7 -fno-builtin-memcmp', - 'cxx' : 'g++: Apple LLVM version 5.1 (clang-503.0.40) (based on LLVM 3.4svn)', - 'cxxflags' : '-Wnon-virtual-dtor -Woverloaded-virtual -stdlib=libc++ -std=c++11', - 'linkflags' : '-fPIC -pthread -Wl,-bind_at_load -mmacosx-version-min=10.7 -stdlib=libc++ -fuse-ld=gold', - 'target_arch' : 'x86_64', - 'target_os' : 'osx' - }, - 'bits' : 64, - 'debug' : false, - 'maxBsonObjectSize' : 16777216, - 'storageEngines' : [ - 'devnull', - 'ephemeralForTest', - 'inMemory', - 'mmapv1', - 'wiredTiger' - ], - 'ok' : 1 + 'version': '3.2.0-rc2', + 'gitVersion': '8a3acb42742182c5e314636041c2df368232bbc5', + 'modules': [ + 'enterprise' + ], + 'allocator': 'system', + 'javascriptEngine': 'mozjs', + 'sysInfo': 'deprecated', + 'versionArray': [ + 3, + 2, + 0, + -48 + ], + 'openssl': { + 'running': 'OpenSSL 0.9.8zg 14 July 2015', + 'compiled': 'OpenSSL 0.9.8y 5 Feb 2013' + }, + 'buildEnvironment': { + 'distmod': '', + 'distarch': 'x86_64', + 'cc': 'gcc: Apple LLVM version 5.1 (clang-503.0.40) (based on LLVM 3.4svn)', + 'ccflags': '-fno-omit-frame-pointer -fPIC -fno-strict-aliasing -ggdb -pthread -Wall -Wsign-compare -Wno-unknown-pragmas -Winvalid-pch -Werror -O2 -Wno-unused-function -Wno-unused-private-field -Wno-deprecated-declarations -Wno-tautological-constant-out-of-range-compare -Wno-unused-const-variable -Wno-missing-braces -mmacosx-version-min=10.7 -fno-builtin-memcmp', + 'cxx': 'g++: Apple LLVM version 5.1 (clang-503.0.40) (based on LLVM 3.4svn)', + 'cxxflags': '-Wnon-virtual-dtor -Woverloaded-virtual -stdlib=libc++ -std=c++11', + 'linkflags': '-fPIC -pthread -Wl,-bind_at_load -mmacosx-version-min=10.7 -stdlib=libc++ -fuse-ld=gold', + 'target_arch': 'x86_64', + 'target_os': 'osx' + }, + 'bits': 64, + 'debug': false, + 'maxBsonObjectSize': 16777216, + 'storageEngines': [ + 'devnull', + 'ephemeralForTest', + 'inMemory', + 'mmapv1', + 'wiredTiger' + ], + 'ok': 1 }; const CMD_LINE_OPTS = { - 'argv' : [ + 'argv': [ '/opt/mongodb-osx-x86_64-enterprise-3.6.3/bin/mongod', '--dbpath=/Users/user/testdata' ], - 'parsed' : { - 'storage' : { - 'dbPath' : '/Users/user/testdata' + 'parsed': { + 'storage': { + 'dbPath': '/Users/user/testdata' } }, - 'ok' : 1 + 'ok': 1 }; const TOPOLOGY_WITH_CREDENTIALS = { @@ -84,7 +84,7 @@ describe('getConnectInfo', function() { isGenuine: true, serverName: 'mongodb', uri: ATLAS_URI - } + }; expect(getConnectInfo( ATLAS_URI, BUILD_INFO, @@ -104,7 +104,7 @@ describe('getConnectInfo', function() { isGenuine: true, serverName: 'mongodb', uri: ATLAS_URI - } + }; expect(getConnectInfo( ATLAS_URI, BUILD_INFO, diff --git a/packages/cli-repl/src/connect-info.ts b/packages/cli-repl/src/connect-info.ts index f5bcbddd9..1ac6aab3e 100644 --- a/packages/cli-repl/src/connect-info.ts +++ b/packages/cli-repl/src/connect-info.ts @@ -1,6 +1,19 @@ import getBuildInfo from 'mongodb-build-info'; -export default function getConnectInfo(uri: string, buildInfo: any, cmdLineOpts: any, topology: any) { +interface ConnectInfo { + isAtlas: boolean; + isLocalhost: boolean; + serverVersion: string; + isEnterprise: boolean; + uri: string; + authType?: string; + isDataLake: boolean; + dlVersion?: string; + isGenuine: boolean; + serverName: string; +} + +export default function getConnectInfo(uri: string, buildInfo: any, cmdLineOpts: any, topology: any): ConnectInfo { const { isGenuine, serverName } = getBuildInfo.getGenuineMongoDB(buildInfo, cmdLineOpts); const { isDataLake, dlVersion } = getBuildInfo.getDataLake(buildInfo); @@ -20,6 +33,6 @@ export default function getConnectInfo(uri: string, buildInfo: any, cmdLineOpts: isDataLake, dlVersion, isGenuine, - serverName - } + serverName + }; } diff --git a/packages/cli-repl/src/constants.ts b/packages/cli-repl/src/constants.ts index 585f38a16..7d7577f78 100644 --- a/packages/cli-repl/src/constants.ts +++ b/packages/cli-repl/src/constants.ts @@ -4,11 +4,11 @@ import clr from './clr'; export const TELEMETRY = ` ${i18n.__('cli-repl.cli-repl.telemetry')} ${i18n.__('cli-repl.cli-repl.disableTelemetry')}${clr('disableTelemetry()', 'bold')} ${i18n.__('cli-repl.cli-repl.command')} -` +`; export const MONGOSH_WIKI = ` ${i18n.__('cli-repl.cli-repl.wiki.info')} ${clr(i18n.__('cli-repl.cli-repl.wiki.link'), 'bold')} -` +`; export const USAGE = ` diff --git a/packages/cli-repl/src/format-output.spec.ts b/packages/cli-repl/src/format-output.spec.ts index 5b3698db9..4e67f4c32 100644 --- a/packages/cli-repl/src/format-output.spec.ts +++ b/packages/cli-repl/src/format-output.spec.ts @@ -1,26 +1,27 @@ +/* eslint no-control-regex: 0 */ import format from './format-output'; import { expect } from 'chai'; -function stripAnsiColors(str) { +function stripAnsiColors(str): string { return str.replace(/\x1B[[(?);]{0,2}(;?\d)*./g, ''); -}; +} describe('formatOutput', () => { context('when the result is a string', () => { it('returns the output', () => { - expect(format({value: 'test'})).to.equal('test'); + expect(format({ value: 'test' })).to.equal('test'); }); }); context('when the result is undefined', () => { it('returns the output', () => { - expect(format({value: undefined})).to.equal(''); + expect(format({ value: undefined })).to.equal(''); }); }); context('when the result is an object', () => { it('returns the inspection', () => { - expect(format({value: 2})).to.include('2'); + expect(format({ value: 2 })).to.include('2'); }); }); @@ -28,7 +29,7 @@ describe('formatOutput', () => { context('when the Cursor is not empty', () => { it('returns the inspection', () => { const output = stripAnsiColors(format({ - value: [{doc: 1}, {doc: 2}], + value: [{ doc: 1 }, { doc: 2 }], type: 'Cursor' })); @@ -53,7 +54,7 @@ describe('formatOutput', () => { context('when the CursorIterationResult is not empty', () => { it('returns the inspection', () => { const output = stripAnsiColors(format({ - value: [{doc: 1}, {doc: 2}], + value: [{ doc: 1 }, { doc: 2 }], type: 'CursorIterationResult' })); @@ -88,11 +89,11 @@ describe('formatOutput', () => { it('returns the help text', () => { const output = stripAnsiColors(format({ value: [ - { name: 'admin', sizeOnDisk: 45056, empty: false }, - { name: 'dxl', sizeOnDisk: 8192, empty: false }, - { name: 'supplies', sizeOnDisk: 2236416, empty: false }, - { name: 'test', sizeOnDisk: 5664768, empty: false }, - { name: 'test', sizeOnDisk: 599999768000, empty: false } + { name: 'admin', sizeOnDisk: 45056, empty: false }, + { name: 'dxl', sizeOnDisk: 8192, empty: false }, + { name: 'supplies', sizeOnDisk: 2236416, empty: false }, + { name: 'test', sizeOnDisk: 5664768, empty: false }, + { name: 'test', sizeOnDisk: 599999768000, empty: false } ], type: 'ShowDatabasesResult' })); @@ -132,8 +133,8 @@ describe('formatOutput', () => { help: 'Shell API', docs: 'https://docs.mongodb.com', attr: [{ - name: "show dbs", - description: "list available databases" + name: 'show dbs', + description: 'list available databases' }] }, type: 'Help' @@ -148,7 +149,7 @@ describe('formatOutput', () => { help: 'Shell API', docs: 'https://docs.mongodb.com', attr: [{ - description: "list available databases" + description: 'list available databases' }] }, type: 'Help' @@ -163,8 +164,8 @@ describe('formatOutput', () => { value: { help: 'Shell API', attr: [{ - name: "show dbs", - description: "list available databases" + name: 'show dbs', + description: 'list available databases' }] }, type: 'Help' diff --git a/packages/cli-repl/src/format-output.ts b/packages/cli-repl/src/format-output.ts index 4907536df..6ad794ac7 100644 --- a/packages/cli-repl/src/format-output.ts +++ b/packages/cli-repl/src/format-output.ts @@ -1,3 +1,5 @@ +/* eslint no-use-before-define: ["error", { "functions": false }] */ + import prettyBytes from 'pretty-bytes'; import textTable from 'text-table'; import i18n from '@mongosh/i18n'; @@ -5,8 +7,8 @@ import util from 'util'; import clr from './clr'; type EvaluationResult = { - value: any, - type?: string + value: any; + type?: string; }; /** @@ -21,7 +23,7 @@ type EvaluationResult = { * @returns {string} The output. */ export default function formatOutput(evaluationResult: EvaluationResult): string { - const {value, type} = evaluationResult; + const { value, type } = evaluationResult; if (type === 'Cursor') { return formatCursor(value); @@ -36,40 +38,40 @@ export default function formatOutput(evaluationResult: EvaluationResult): string } if (type === 'ShowDatabasesResult') { - return formatDatabases(value) + return formatDatabases(value); } if (type === 'ShowCollectionsResult') { - return formatCollections(value) + return formatCollections(value); } if (type === 'Error') { - return formatError(value) + return formatError(value); } return formatSimpleType(value); } -function formatSimpleType(output) { +function formatSimpleType(output): any { if (typeof output === 'string') return output; if (typeof output === 'undefined') return ''; return inspect(output); } -function formatCollections(output) { - return output.join('\n'); +function formatCollections(output): string { + return clr(output.join('\n'), 'bold'); } -function formatDatabases(output) { +function formatDatabases(output): string { const tableEntries = output.map( (db) => [clr(db.name, 'bold'), prettyBytes(db.sizeOnDisk)] - ) + ); return textTable(tableEntries, { align: ['l', 'r'] }); } -export function formatError(error) { +export function formatError(error): string { let result = ''; if (error.name) result += `\r${clr(error.name, ['bold', 'red'])}: `; if (error.message) result += error.message; @@ -79,7 +81,7 @@ export function formatError(error) { return result; } -function inspect(output) { +function inspect(output): any { return util.inspect(output, { showProxy: false, colors: true, @@ -87,7 +89,7 @@ function inspect(output) { }); } -function formatCursor(value) { +function formatCursor(value): any { if (!value.length) { return ''; } @@ -95,7 +97,7 @@ function formatCursor(value) { return inspect(value); } -function formatCursorIterationResult(value) { +function formatCursorIterationResult(value): any { if (!value.length) { return i18n.__('shell-api.classes.Cursor.iteration.no-cursor'); } @@ -103,34 +105,34 @@ function formatCursorIterationResult(value) { return inspect(value); } -function formatHelp(value) { +function formatHelp(value): string { // This is the spacing between arguments and description in mongosh --help. // Use this length for formatting consistency. const argLen = 47; let helpMenu = ''; if (value.help) { - helpMenu += `\n ${clr(`${value.help}:`, ['yellow', 'bold'])}\n\n` + helpMenu += `\n ${clr(`${value.help}:`, ['yellow', 'bold'])}\n\n`; } (value.attr || []).forEach((method) => { let formatted = ''; if (method.name && method.description) { formatted = ` ${method.name}`; - const extraSpaces = 47 - formatted.length; + const extraSpaces = argLen - formatted.length; formatted += `${' '.repeat(extraSpaces)}${method.description}`; } if (!method.name && method.description) { - formatted = ` ${method.description}` + formatted = ` ${method.description}`; } - if (formatted != '') { + if (formatted !== '') { helpMenu += `${formatted}\n`; } - }) + }); if (value.docs) { - helpMenu += `\n ${clr(i18n.__('cli-repl.args.moreInformation'), 'bold')} ${clr(value.docs, ['green', 'bold'])}` + helpMenu += `\n ${clr(i18n.__('cli-repl.args.moreInformation'), 'bold')} ${clr(value.docs, ['green', 'bold'])}`; } return helpMenu; diff --git a/packages/cli-repl/src/index.ts b/packages/cli-repl/src/index.ts index 8d43f5844..4ef3b539f 100644 --- a/packages/cli-repl/src/index.ts +++ b/packages/cli-repl/src/index.ts @@ -3,8 +3,8 @@ import redactPwd from './redact-pwd'; import parseCliArgs from './arg-parser'; import mapCliToDriver from './arg-mapper'; import generateUri from './uri-generator'; -import completer from './completer' -import clr from './clr' +import completer from './completer'; +import clr from './clr'; import { USAGE, TELEMETRY, MONGOSH_WIKI } from './constants'; export default CliRepl; diff --git a/packages/cli-repl/src/logger.ts b/packages/cli-repl/src/logger.ts index a14c78d78..a7f6b6d52 100644 --- a/packages/cli-repl/src/logger.ts +++ b/packages/cli-repl/src/logger.ts @@ -1,20 +1,21 @@ +/* eslint no-console:0, no-empty-function: 0 */ + import redactInfo from 'mongodb-redact'; import Analytics from 'analytics-node'; import redactPwd from './redact-pwd'; import { ObjectId } from 'bson'; import pino from 'pino'; import path from 'path'; -import os from 'os'; interface ApiEventArguments { pipeline?: any[]; query?: object; options?: object; - filter?: object; + filter?: object; } interface ApiEvent { - method?: string; + method?: string; class?: string; db?: string; coll?: string; @@ -47,7 +48,13 @@ interface ConnectEvent { serverName: string; } -export default function logger(bus: any, logDir: string) { +// set up a noop, in case we are not able to connect to segment. +function NoopAnalytics(): void {} + +NoopAnalytics.prototype.identify = function(): void {}; +NoopAnalytics.prototype.track = function(): void {}; + +export default function logger(bus: any, logDir: string): void { const sessionID = new ObjectId(Date.now()); const logDest = path.join(logDir, `${sessionID}_log`); const log = pino({ name: 'monogsh' }, pino.destination(logDest)); @@ -58,10 +65,10 @@ export default function logger(bus: any, logDir: string) { let analytics = new NoopAnalytics(); try { // this file gets written as a part of a release - log.warn(require('./analytics-config.js').SEGMENT_API_KEY) + log.warn(require('./analytics-config.js').SEGMENT_API_KEY); analytics = new Analytics(require('./analytics-config.js').SEGMENT_API_KEY); } catch (e) { - bus.emit('mongosh:error', e) + bus.emit('mongosh:error', e); } bus.on('mongosh:connect', function(args: ConnectEvent) { @@ -83,13 +90,13 @@ export default function logger(bus: any, logDir: string) { userId = id; telemetry = enableTelemetry; if (telemetry) analytics.identify({ userId }); - }) + }); bus.on('mongosh:update-user', function(id, enableTelemetry) { userId = id; telemetry = enableTelemetry; - log.info('mongosh:update-user', { enableTelemetry }) - }) + log.info('mongosh:update-user', { enableTelemetry }); + }); bus.on('mongosh:error', function(error: any) { @@ -143,14 +150,14 @@ export default function logger(bus: any, logDir: string) { }); bus.on('mongosh:setCtx', function(args) { - log.info('mongosh:setCtx') - }) + log.info('mongosh:setCtx', args); + }); bus.on('mongosh:api-call', function(args: ApiEvent) { log.info('mongosh:api-call', redactInfo(args)); // analytics properties to include if they are present in an api-call - let properties: ApiEvent = {}; + const properties: ApiEvent = {}; properties.arguments = {}; if (args.method) properties.method = args.method; if (args.class) properties.class = args.class; @@ -165,9 +172,3 @@ export default function logger(bus: any, logDir: string) { } }); } - -// set up a noop, in case we are not able to connect to segment. -function NoopAnalytics() {} - -NoopAnalytics.prototype.identify = function() {} -NoopAnalytics.prototype.track = function() {} diff --git a/packages/cli-repl/src/uri-generator.spec.ts b/packages/cli-repl/src/uri-generator.spec.ts index 0602b2b11..b4e54e3d2 100644 --- a/packages/cli-repl/src/uri-generator.spec.ts +++ b/packages/cli-repl/src/uri-generator.spec.ts @@ -3,7 +3,7 @@ import { expect } from 'chai'; describe('uri-generator.generate-uri', () => { context('when no arguments are provided', () => { - const options = { _: []}; + const options = { _: [] }; it('returns the default uri', () => { expect(generateUri(options)).to.equal('mongodb://127.0.0.1:27017'); @@ -13,7 +13,7 @@ describe('uri-generator.generate-uri', () => { context('when a full URI is provided', () => { context('when no additional options are provided', () => { const uri = 'mongodb://192.0.0.1:27018/foo'; - const options = { _: [ uri ]}; + const options = { _: [ uri ] }; it('returns the uri', () => { expect(generateUri(options)).to.equal(uri); @@ -44,7 +44,7 @@ describe('uri-generator.generate-uri', () => { context('when a URI is provided without a scheme', () => { context('when providing host', () => { const uri = '192.0.0.1'; - const options = { _: [ uri ]}; + const options = { _: [ uri ] }; it('returns the uri with the scheme', () => { expect(generateUri(options)).to.equal(`mongodb://${uri}:27017/test`); @@ -53,7 +53,7 @@ describe('uri-generator.generate-uri', () => { context('when providing host:port', () => { const uri = '192.0.0.1:27018'; - const options = { _: [ uri ]}; + const options = { _: [ uri ] }; it('returns the uri with the scheme', () => { expect(generateUri(options)).to.equal(`mongodb://${uri}/test`); @@ -71,7 +71,7 @@ describe('uri-generator.generate-uri', () => { context('when no additional options are provided', () => { const uri = '192.0.0.1:27018/foo'; - const options = { _: [ uri ]}; + const options = { _: [ uri ] }; it('returns the uri with the scheme', () => { expect(generateUri(options)).to.equal(`mongodb://${uri}`); diff --git a/packages/cli-repl/src/uri-generator.ts b/packages/cli-repl/src/uri-generator.ts index 9d7120a11..cdf766e4d 100644 --- a/packages/cli-repl/src/uri-generator.ts +++ b/packages/cli-repl/src/uri-generator.ts @@ -1,3 +1,5 @@ +/* eslint complexity: 0*/ + import i18n from '@mongosh/i18n'; import CliOptions from './cli-options'; @@ -23,13 +25,13 @@ const DEFAULT_PORT = '27017'; * GSSAPI options not supported as options in Node driver, * only in the URI. */ -const GSSAPI_HOST_NAME = 'gssapiHostName'; +// const GSSAPI_HOST_NAME = 'gssapiHostName'; /** * GSSAPI options not supported as options in Node driver, * only in the URI. */ -const GSSAPI_SERVICE_NAME = 'gssapiServiceName'; +// const GSSAPI_SERVICE_NAME = 'gssapiServiceName'; /** * Conflicting host/port message. @@ -46,7 +48,7 @@ const TEST = 'test'; * * @param {CliOptions} options - The options. */ -function validateConflicts(options: CliOptions) { +function validateConflicts(options: CliOptions): any { if (options.host || options.port) { throw new Error(i18n.__(CONFLICT)); } @@ -108,7 +110,10 @@ function generateUri(options: CliOptions): string { // the parts. const uriMatch = /^([A-Za-z0-9][A-Za-z0-9.-]+):?(\d+)?[\/]?(\S+)?$/gi; const parts = uriMatch.exec(uri); - let host = parts[1], port = parts[2], db = parts[3]; + + let host = parts[1]; + const port = parts[2]; + let db = parts[3]; // If there is no port and db, host becomes db if there is no // '.' in the string. (legacy shell behaviour) diff --git a/packages/cli-repl/test/e2e.spec.ts b/packages/cli-repl/test/e2e.spec.ts index 3f4a15ebf..0dc937cd3 100644 --- a/packages/cli-repl/test/e2e.spec.ts +++ b/packages/cli-repl/test/e2e.spec.ts @@ -26,7 +26,7 @@ describe('e2e', function() { let shell; let dbName; - beforeEach(async () => { + beforeEach(async() => { dbName = `test-${Date.now()}`; const connectionString = `mongodb://localhost:27018/${dbName}`; @@ -39,13 +39,13 @@ describe('e2e', function() { db = client.db(dbName); }); - afterEach(async () => { + afterEach(async() => { await db.dropDatabase(); client.close(); }); - it.skip('connects to the right database', async () => { + it.skip('connects to the right database', async() => { shell.stdio.stdin.write('db\n'); await eventually(() => { @@ -54,7 +54,7 @@ describe('e2e', function() { }); }); - it('throws multiline input with a single line string', async () => { + it('throws multiline input with a single line string', async() => { // this is an unterminated string constant and should throw, since it does // not pass: https://www.ecma-international.org/ecma-262/#sec-line-terminators shell.stdio.stdin.write('"this is a multi\nline string"\n'); @@ -64,7 +64,7 @@ describe('e2e', function() { }); }); - it('throws when a syntax error is encountered', async () => { + it('throws when a syntax error is encountered', async() => { shell.stdio.stdin.write('\n'); await eventually(() => { @@ -72,7 +72,7 @@ describe('e2e', function() { }); }); - it('runs an unterminated function', async () => { + it('runs an unterminated function', async() => { shell.stdio.stdin.write('function x () {\nconsole.log(\'y\')\n }\n'); await eventually(() => { @@ -80,7 +80,7 @@ describe('e2e', function() { }); }); - it('runs an unterminated function', async () => { + it('runs an unterminated function', async() => { shell.stdio.stdin.write('function x () {\n'); await eventually(() => { @@ -88,7 +88,7 @@ describe('e2e', function() { }); }); - it('runs help command', async () => { + it('runs help command', async() => { shell.stdio.stdin.write('help\n'); await eventually(() => { @@ -97,13 +97,13 @@ describe('e2e', function() { }); }); - it('allows to find documents', async () => { + it('allows to find documents', async() => { shell.stdio.stdin.write(`use ${dbName}\n`); await db.collection('test').insertMany([ - {doc: 1}, - {doc: 2}, - {doc: 3} + { doc: 1 }, + { doc: 2 }, + { doc: 3 } ]); shell.stdio.stdin.write('db.test.find()\n'); diff --git a/packages/cli-repl/test/helpers.ts b/packages/cli-repl/test/helpers.ts index da8fe79b0..dc427c916 100644 --- a/packages/cli-repl/test/helpers.ts +++ b/packages/cli-repl/test/helpers.ts @@ -2,7 +2,7 @@ import { spawn } from 'child_process'; import path from 'path'; import stripAnsi from 'strip-ansi'; -export async function eventually(fn, options: { frequency?: number, timeout?: number } = {}) { +export async function eventually(fn, options: { frequency?: number; timeout?: number } = {}): Promise { options = { frequency: 100, timeout: 10000, @@ -12,7 +12,7 @@ export async function eventually(fn, options: { frequency?: number, timeout?: nu let attempts = Math.round(options.timeout / options.frequency); let err; - while(attempts) { + while (attempts) { attempts--; try { @@ -30,7 +30,7 @@ export async function eventually(fn, options: { frequency?: number, timeout?: nu const openShells = []; -export function startShell(...args) { +export function startShell(...args): any { const execPath = path.resolve(__dirname, '..', 'bin', 'mongosh.js'); const shell = spawn('node', [execPath, ...args], { @@ -41,7 +41,7 @@ export function startShell(...args) { stdin: shell.stdin, stdout: '', stderr: '' - } + }; shell.stdout.on('data', (chunk) => { const plainChunk = stripAnsi(chunk.toString()); @@ -61,8 +61,9 @@ export function startShell(...args) { }; } -export function killOpenShells() { - while(openShells.length) { +export function killOpenShells(): any { + while (openShells.length) { openShells.pop().kill(); } -} \ No newline at end of file +} +