From 8c155baaca39dc78c5a3a63ff1bdd53b58f343e0 Mon Sep 17 00:00:00 2001 From: Jordan Harband Date: Thu, 13 Apr 2023 16:20:26 -0700 Subject: [PATCH] [eslint] tighten up rules --- .eslintrc | 95 ++++++- config/typescript.js | 4 +- memo-parser/index.js | 4 +- resolvers/node/index.js | 9 +- resolvers/node/test/packageMains.js | 1 - resolvers/node/test/paths.js | 2 - resolvers/webpack/index.js | 20 +- .../config-extensions/webpack.config.babel.js | 4 +- resolvers/webpack/test/extensions.js | 1 - resolvers/webpack/test/fallback.js | 1 - resolvers/webpack/test/loaders.js | 1 - resolvers/webpack/test/packageMains.js | 1 - resolvers/webpack/test/root.js | 1 - scripts/testAll.js | 4 +- src/ExportMap.js | 254 +++++++++--------- src/core/importType.js | 18 +- src/core/packagePath.js | 1 - src/core/staticRequire.js | 14 +- src/index.js | 28 +- src/rules/consistent-type-specifier-style.js | 36 +-- src/rules/default.js | 10 +- src/rules/dynamic-import-chunkname.js | 3 +- src/rules/export.js | 40 +-- src/rules/exports-last.js | 6 +- src/rules/extensions.js | 18 +- src/rules/first.js | 35 +-- src/rules/group-exports.js | 10 +- src/rules/imports-first.js | 7 +- src/rules/max-dependencies.js | 32 ++- src/rules/named.js | 8 +- src/rules/namespace.js | 68 ++--- src/rules/newline-after-import.js | 35 +-- src/rules/no-absolute-path.js | 6 +- src/rules/no-amd.js | 13 +- src/rules/no-anonymous-default-export.js | 6 +- src/rules/no-commonjs.js | 46 ++-- src/rules/no-cycle.js | 44 +-- src/rules/no-default-export.js | 2 +- src/rules/no-deprecated.js | 75 +++--- src/rules/no-duplicates.js | 65 +++-- src/rules/no-dynamic-require.js | 20 +- src/rules/no-empty-named-blocks.js | 21 +- src/rules/no-extraneous-dependencies.js | 94 +++---- src/rules/no-import-module-exports.js | 21 +- src/rules/no-internal-modules.js | 34 +-- src/rules/no-mutable-exports.js | 4 +- src/rules/no-named-as-default-member.js | 105 ++++---- src/rules/no-named-as-default.js | 18 +- src/rules/no-named-default.js | 2 +- src/rules/no-named-export.js | 2 +- src/rules/no-namespace.js | 23 +- src/rules/no-nodejs-modules.js | 2 +- src/rules/no-relative-packages.js | 2 +- src/rules/no-relative-parent-imports.js | 7 +- src/rules/no-restricted-paths.js | 20 +- src/rules/no-unassigned-import.js | 37 +-- src/rules/no-unused-modules.js | 117 ++++---- src/rules/no-useless-path-segments.js | 4 +- src/rules/no-webpack-loader-syntax.js | 4 +- src/rules/order.js | 101 ++++--- src/rules/prefer-default-export.js | 24 +- tests/src/cli.js | 14 +- tests/src/core/getExports.js | 55 ++-- tests/src/core/hash.js | 2 +- tests/src/core/parse.js | 16 +- tests/src/core/resolve.js | 207 ++++++++------ tests/src/package.js | 6 +- tests/src/rules/dynamic-import-chunkname.js | 2 +- tests/src/rules/export.js | 2 - tests/src/rules/exports-last.js | 2 +- tests/src/rules/extensions.js | 25 +- tests/src/rules/first.js | 2 +- tests/src/rules/named.js | 16 +- tests/src/rules/namespace.js | 69 ++--- tests/src/rules/newline-after-import.js | 50 ++-- tests/src/rules/no-commonjs.js | 16 +- tests/src/rules/no-cycle.js | 4 +- tests/src/rules/no-deprecated.js | 13 +- tests/src/rules/no-duplicates.js | 24 +- tests/src/rules/no-dynamic-require.js | 14 +- tests/src/rules/no-empty-named-blocks.js | 3 +- tests/src/rules/no-extraneous-dependencies.js | 26 +- tests/src/rules/no-import-module-exports.js | 3 +- tests/src/rules/no-named-as-default-member.js | 25 +- tests/src/rules/no-nodejs-modules.js | 4 +- tests/src/rules/no-relative-parent-imports.js | 2 +- tests/src/rules/no-restricted-paths.js | 5 +- tests/src/rules/no-unassigned-import.js | 30 +-- tests/src/rules/no-unresolved.js | 23 +- tests/src/rules/no-unused-modules.js | 7 +- tests/src/rules/no-webpack-loader-syntax.js | 8 +- tests/src/rules/order.js | 182 ++++++------- tests/src/rules/prefer-default-export.js | 6 +- tests/src/utils.js | 12 +- utils/ModuleCache.js | 7 +- utils/declaredScope.js | 5 +- utils/hash.js | 11 +- utils/ignore.js | 7 +- utils/module-require.js | 1 + utils/moduleVisitor.js | 88 +++--- utils/parse.js | 16 +- utils/pkgUp.js | 9 +- utils/readPkgUp.js | 9 +- utils/resolve.js | 53 ++-- utils/unambiguous.js | 3 +- utils/visit.js | 1 + 106 files changed, 1405 insertions(+), 1370 deletions(-) diff --git a/.eslintrc b/.eslintrc index 1c41cb71b..709a47448 100644 --- a/.eslintrc +++ b/.eslintrc @@ -12,12 +12,18 @@ "env": { "node": true, "es6": true, + "es2017": true, }, "parserOptions": { "sourceType": "module", "ecmaVersion": 2020, }, "rules": { + "arrow-body-style": [2, "as-needed"], + "arrow-parens": [2, "always"], + "arrow-spacing": [2, { "before": true, "after": true }], + "block-spacing": [2, "always"], + "brace-style": [2, "1tbs", { "allowSingleLine": true }], "comma-dangle": ["error", { "arrays": "always-multiline", "objects": "always-multiline", @@ -25,12 +31,47 @@ "exports": "always-multiline", "functions": "always-multiline", }], + "comma-spacing": [2, { "before": false, "after": true }], "comma-style": [2, "last"], - "curly": [2, "multi-line"], + "computed-property-spacing": [2, "never"], + "curly": [2, "all"], + "default-case": [2, { "commentPattern": "(?:)" }], + "default-case-last": [2], + "default-param-last": [2], + "dot-location": [2, "property"], + "dot-notation": [2, { "allowKeywords": true, "allowPattern": "throws" }], "eol-last": [2, "always"], "eqeqeq": [2, "allow-null"], - "func-call-spacing": 2, - "indent": [2, 2], + "for-direction": [2], + "function-call-argument-newline": [2, "consistent"], + "func-call-spacing": [2, "never"], + "implicit-arrow-linebreak": [2, "beside"], + "indent": [2, 2, { + "SwitchCase": 1, + "VariableDeclarator": 1, + "outerIIFEBody": 1, + "FunctionDeclaration": { + "parameters": 1, + "body": 1 + }, + "FunctionExpression": { + "parameters": 1, + "body": 1 + }, + "CallExpression": { + "arguments": 1 + }, + "ArrayExpression": 1, + "ObjectExpression": 1, + "ImportDeclaration": 1, + "flatTernaryExpressions": false, + }], + "jsx-quotes": [2, "prefer-double"], + "key-spacing": [2, { + "beforeColon": false, + "afterColon": true, + "mode": "strict", + }], "keyword-spacing": ["error", { "before": true, "after": true, @@ -40,27 +81,68 @@ "case": { "after": true } } }], + "linebreak-style": [2, "unix"], + "lines-around-directive": [2, { + "before": "always", + "after": "always", + }], "max-len": 0, + "new-parens": 2, + "no-array-constructor": 2, + "no-compare-neg-zero": 2, "no-cond-assign": [2, "always"], + "no-extra-parens": 2, + "no-multiple-empty-lines": [2, { "max": 1, "maxEOF": 1, "maxBOF": 0 }], "no-return-assign": [2, "always"], + "no-trailing-spaces": 2, "no-var": 2, "object-curly-spacing": [2, "always"], "object-shorthand": ["error", "always", { "ignoreConstructors": false, - "avoidQuotes": true, + "avoidQuotes": false, + "avoidExplicitReturnArrows": true, }], "one-var": [2, "never"], + "operator-linebreak": [2, "none", { + "overrides": { + "?": "before", + ":": "before", + "&&": "before", + "||": "before", + }, + }], "prefer-const": 2, + "prefer-object-spread": 2, + "prefer-rest-params": 2, + "prefer-template": 2, + "quote-props": [2, "as-needed", { "keywords": false }], "quotes": [2, "single", { "allowTemplateLiterals": true, "avoidEscape": true, }], + "rest-spread-spacing": [2, "never"], "semi": [2, "always"], + "semi-spacing": [2, { "before": false, "after": true }], + "semi-style": [2, "last"], + "space-before-blocks": [2, { "functions": "always", "keywords": "always", "classes": "always" }], "space-before-function-paren": ["error", { "anonymous": "always", "named": "never", "asyncArrow": "always", }], + "space-in-parens": [2, "never"], + "space-infix-ops": [2], + "space-unary-ops": [2, { "words": true, "nonwords": false }], + "switch-colon-spacing": [2, { "after": true, "before": false }], + "template-curly-spacing": [2, "never"], + "template-tag-spacing": [2, "never"], + "unicode-bom": [2, "never"], + "use-isnan": [2, { "enforceForSwitchCase": true }], + "valid-typeof": [2], + "wrap-iife": [2, "outside", { "functionPrototypeMethods": true }], + "wrap-regex": [2], + "yield-star-spacing": [2, { "before": false, "after": true }], + "yoda": [2, "never", { "exceptRange": true, "onlyEquality": false }], "eslint-plugin/consistent-output": [ "error", @@ -116,6 +198,9 @@ "files": "resolvers/webpack/**", "rules": { "no-console": 1, + "prefer-template": 0, + "prefer-object-spread": 0, + "prefer-rest-params": 0, }, "env": { "es6": true, @@ -143,6 +228,8 @@ "exports": "always-multiline", "functions": "never" }], + "prefer-object-spread": "off", + "prefer-template": "off", "no-console": 1, }, }, diff --git a/config/typescript.js b/config/typescript.js index ed03fb3f6..9fd789dbf 100644 --- a/config/typescript.js +++ b/config/typescript.js @@ -16,8 +16,8 @@ module.exports = { '@typescript-eslint/parser': ['.ts', '.tsx'], }, 'import/resolver': { - 'node': { - 'extensions': allExtensions, + node: { + extensions: allExtensions, }, }, }, diff --git a/memo-parser/index.js b/memo-parser/index.js index de558ffa3..7868b7e95 100644 --- a/memo-parser/index.js +++ b/memo-parser/index.js @@ -17,7 +17,7 @@ const parserOptions = { }; exports.parse = function parse(content, options) { - options = Object.assign({}, options, parserOptions); + options = { ...options, ...parserOptions }; if (!options.filePath) { throw new Error('no file path provided!'); @@ -30,7 +30,7 @@ exports.parse = function parse(content, options) { const key = keyHash.digest('hex'); let ast = cache.get(key); - if (ast != null) return ast; + if (ast != null) { return ast; } const realParser = moduleRequire(options.parser); diff --git a/resolvers/node/index.js b/resolvers/node/index.js index ac478ef02..d382bca43 100644 --- a/resolvers/node/index.js +++ b/resolvers/node/index.js @@ -29,17 +29,14 @@ exports.resolve = function (source, file, config) { }; function opts(file, config, packageFilter) { - return Object.assign({ - // more closely matches Node (#333) + return { // more closely matches Node (#333) // plus 'mjs' for native modules! (#939) extensions: ['.mjs', '.js', '.json', '.node'], - }, - config, - { + ...config, // path.resolve will handle paths relative to CWD basedir: path.dirname(path.resolve(file)), packageFilter, - }); + }; } function identity(x) { return x; } diff --git a/resolvers/node/test/packageMains.js b/resolvers/node/test/packageMains.js index caac6221c..170b10e1a 100644 --- a/resolvers/node/test/packageMains.js +++ b/resolvers/node/test/packageMains.js @@ -8,7 +8,6 @@ const resolver = require('../'); const file = path.join(__dirname, 'package-mains', 'dummy.js'); - describe('packageMains', function () { it('captures module', function () { expect(resolver.resolve('./module', file)).property('path') diff --git a/resolvers/node/test/paths.js b/resolvers/node/test/paths.js index 1c42b4616..e6ffdafcd 100644 --- a/resolvers/node/test/paths.js +++ b/resolvers/node/test/paths.js @@ -11,7 +11,6 @@ describe('paths', function () { }); }); - describe('core', function () { it('returns found, but null path, for core Node modules', function () { const resolved = node.resolve('fs', './test/file.js'); @@ -20,7 +19,6 @@ describe('core', function () { }); }); - describe('default options', function () { it('finds .json files', function () { diff --git a/resolvers/webpack/index.js b/resolvers/webpack/index.js index b569d5322..8eb2db5ad 100644 --- a/resolvers/webpack/index.js +++ b/resolvers/webpack/index.js @@ -75,7 +75,7 @@ exports.resolve = function (source, file, settings) { if (!configPath || !path.isAbsolute(configPath)) { // if not, find ancestral package.json and use its directory as base for the path packageDir = findRoot(path.resolve(file)); - if (!packageDir) throw new Error('package not found above ' + file); + if (!packageDir) { throw new Error('package not found above ' + file); } } configPath = findConfigPath(configPath, packageDir); @@ -108,7 +108,7 @@ exports.resolve = function (source, file, settings) { } if (Array.isArray(webpackConfig)) { - webpackConfig = webpackConfig.map(cfg => { + webpackConfig = webpackConfig.map((cfg) => { if (typeof cfg === 'function') { return cfg(env, argv); } @@ -284,16 +284,15 @@ function createWebpack1ResolveSync(webpackRequire, resolveConfig, plugins) { new ResultSymlinkPlugin(), ); - const resolvePlugins = []; // support webpack.ResolverPlugin if (plugins) { plugins.forEach(function (plugin) { if ( - plugin.constructor && - plugin.constructor.name === 'ResolverPlugin' && - Array.isArray(plugin.plugins) + plugin.constructor + && plugin.constructor.name === 'ResolverPlugin' + && Array.isArray(plugin.plugins) ) { resolvePlugins.push.apply(resolvePlugins, plugin.plugins); } @@ -324,10 +323,10 @@ function makeRootPlugin(ModulesInRootPlugin, name, root) { /* eslint-enable */ function findExternal(source, externals, context, resolveSync) { - if (!externals) return false; + if (!externals) { return false; } // string match - if (typeof externals === 'string') return (source === externals); + if (typeof externals === 'string') { return source === externals; } // array: recurse if (Array.isArray(externals)) { @@ -384,8 +383,8 @@ function findExternal(source, externals, context, resolveSync) { // else, vanilla object for (const key in externals) { - if (!has(externals, key)) continue; - if (source === key) return true; + if (!has(externals, key)) { continue; } + if (source === key) { return true; } } return false; } @@ -396,7 +395,6 @@ function findConfigPath(configPath, packageDir) { }); let extension; - if (configPath) { // extensions is not reused below, so safe to mutate it here. extensions.reverse(); diff --git a/resolvers/webpack/test/config-extensions/webpack.config.babel.js b/resolvers/webpack/test/config-extensions/webpack.config.babel.js index a63434f9b..c8b3cd578 100644 --- a/resolvers/webpack/test/config-extensions/webpack.config.babel.js +++ b/resolvers/webpack/test/config-extensions/webpack.config.babel.js @@ -3,7 +3,7 @@ import path from 'path'; export default { resolve: { alias: { - 'foo': path.join(__dirname, 'some', 'goofy', 'path', 'foo.js'), + foo: path.join(__dirname, 'some', 'goofy', 'path', 'foo.js'), }, modules: [ path.join(__dirname, 'src'), @@ -17,7 +17,7 @@ export default { }, externals: [ - { 'jquery': 'jQuery' }, + { jquery: 'jQuery' }, 'bootstrap', ], }; diff --git a/resolvers/webpack/test/extensions.js b/resolvers/webpack/test/extensions.js index c028f5c91..096df7728 100644 --- a/resolvers/webpack/test/extensions.js +++ b/resolvers/webpack/test/extensions.js @@ -6,7 +6,6 @@ const path = require('path'); const resolve = require('../index').resolve; - const file = path.join(__dirname, 'files', 'dummy.js'); const extensions = path.join(__dirname, 'custom-extensions', 'dummy.js'); diff --git a/resolvers/webpack/test/fallback.js b/resolvers/webpack/test/fallback.js index 87c15eecd..b164209e1 100644 --- a/resolvers/webpack/test/fallback.js +++ b/resolvers/webpack/test/fallback.js @@ -6,7 +6,6 @@ const path = require('path'); const resolve = require('../index').resolve; - const file = path.join(__dirname, 'files', 'src', 'dummy.js'); describe('fallback', function () { diff --git a/resolvers/webpack/test/loaders.js b/resolvers/webpack/test/loaders.js index 6b5604592..e250894a5 100644 --- a/resolvers/webpack/test/loaders.js +++ b/resolvers/webpack/test/loaders.js @@ -6,7 +6,6 @@ const path = require('path'); const resolve = require('../index').resolve; - const file = path.join(__dirname, 'files', 'dummy.js'); describe('inline loader syntax', function () { diff --git a/resolvers/webpack/test/packageMains.js b/resolvers/webpack/test/packageMains.js index fef3dde07..d3ddad9da 100644 --- a/resolvers/webpack/test/packageMains.js +++ b/resolvers/webpack/test/packageMains.js @@ -8,7 +8,6 @@ const resolver = require('../'); const file = path.join(__dirname, 'package-mains', 'dummy.js'); - describe('packageMains', function () { it('captures module', function () { diff --git a/resolvers/webpack/test/root.js b/resolvers/webpack/test/root.js index 154dbeef9..194bb8fc8 100644 --- a/resolvers/webpack/test/root.js +++ b/resolvers/webpack/test/root.js @@ -6,7 +6,6 @@ const path = require('path'); const resolve = require('../index').resolve; - const file = path.join(__dirname, 'files', 'src', 'dummy.js'); const webpackDir = path.join(__dirname, 'different-package-location'); diff --git a/scripts/testAll.js b/scripts/testAll.js index fc30b1ac7..0e4a12c68 100644 --- a/scripts/testAll.js +++ b/scripts/testAll.js @@ -10,11 +10,11 @@ const spawnOptions = { spawnSync( npmPath, ['test'], - Object.assign({ cwd: __dirname }, spawnOptions)); + { cwd: __dirname, ...spawnOptions }); for (const resolverDir of resolverDirectories) { spawnSync( npmPath, ['test'], - Object.assign({ cwd: resolverDir }, spawnOptions)); + { cwd: resolverDir, ...spawnOptions }); } diff --git a/src/ExportMap.js b/src/ExportMap.js index d31375c83..cd5bad56c 100644 --- a/src/ExportMap.js +++ b/src/ExportMap.js @@ -53,10 +53,10 @@ export default class ExportMap { get size() { let size = this.namespace.size + this.reexports.size; - this.dependencies.forEach(dep => { + this.dependencies.forEach((dep) => { const d = dep(); // CJS / ignored dependencies won't exist (#717) - if (d == null) return; + if (d == null) { return; } size += d.size; }); return size; @@ -70,8 +70,8 @@ export default class ExportMap { * @return {Boolean} true if `name` is exported by this module. */ has(name) { - if (this.namespace.has(name)) return true; - if (this.reexports.has(name)) return true; + if (this.namespace.has(name)) { return true; } + if (this.reexports.has(name)) { return true; } // default exports must be explicitly re-exported (#328) if (name !== 'default') { @@ -79,9 +79,9 @@ export default class ExportMap { const innerMap = dep(); // todo: report as unresolved? - if (!innerMap) continue; + if (!innerMap) { continue; } - if (innerMap.has(name)) return true; + if (innerMap.has(name)) { return true; } } } @@ -94,14 +94,14 @@ export default class ExportMap { * @return {{ found: boolean, path: ExportMap[] }} */ hasDeep(name) { - if (this.namespace.has(name)) return { found: true, path: [this] }; + if (this.namespace.has(name)) { return { found: true, path: [this] }; } if (this.reexports.has(name)) { const reexports = this.reexports.get(name); const imported = reexports.getImport(); // if import is ignored, return explicit 'null' - if (imported == null) return { found: true, path: [this] }; + if (imported == null) { return { found: true, path: [this] }; } // safeguard against cycles, only if name matches if (imported.path === this.path && reexports.local === name) { @@ -114,17 +114,16 @@ export default class ExportMap { return deep; } - // default exports must be explicitly re-exported (#328) if (name !== 'default') { for (const dep of this.dependencies) { const innerMap = dep(); - if (innerMap == null) return { found: true, path: [this] }; + if (innerMap == null) { return { found: true, path: [this] }; } // todo: report as unresolved? - if (!innerMap) continue; + if (!innerMap) { continue; } // safeguard against cycles - if (innerMap.path === this.path) continue; + if (innerMap.path === this.path) { continue; } const innerValue = innerMap.hasDeep(name); if (innerValue.found) { @@ -138,17 +137,17 @@ export default class ExportMap { } get(name) { - if (this.namespace.has(name)) return this.namespace.get(name); + if (this.namespace.has(name)) { return this.namespace.get(name); } if (this.reexports.has(name)) { const reexports = this.reexports.get(name); const imported = reexports.getImport(); // if import is ignored, return explicit 'null' - if (imported == null) return null; + if (imported == null) { return null; } // safeguard against cycles, only if name matches - if (imported.path === this.path && reexports.local === name) return undefined; + if (imported.path === this.path && reexports.local === name) { return undefined; } return imported.get(reexports.local); } @@ -158,13 +157,13 @@ export default class ExportMap { for (const dep of this.dependencies) { const innerMap = dep(); // todo: report as unresolved? - if (!innerMap) continue; + if (!innerMap) { continue; } // safeguard against cycles - if (innerMap.path === this.path) continue; + if (innerMap.path === this.path) { continue; } const innerValue = innerMap.get(name); - if (innerValue !== undefined) return innerValue; + if (innerValue !== undefined) { return innerValue; } } } @@ -172,8 +171,7 @@ export default class ExportMap { } forEach(callback, thisArg) { - this.namespace.forEach((v, n) => - callback.call(thisArg, v, n, this)); + this.namespace.forEach((v, n) => { callback.call(thisArg, v, n, this); }); this.reexports.forEach((reexports, name) => { const reexported = reexports.getImport(); @@ -181,25 +179,28 @@ export default class ExportMap { callback.call(thisArg, reexported && reexported.get(reexports.local), name, this); }); - this.dependencies.forEach(dep => { + this.dependencies.forEach((dep) => { const d = dep(); // CJS / ignored dependencies won't exist (#717) - if (d == null) return; + if (d == null) { return; } - d.forEach((v, n) => - n !== 'default' && callback.call(thisArg, v, n, this)); + d.forEach((v, n) => { + if (n !== 'default') { + callback.call(thisArg, v, n, this); + } + }); }); } // todo: keys, values, entries? reportErrors(context, declaration) { + const msg = this.errors + .map((e) => `${e.message} (${e.lineNumber}:${e.column})`) + .join(', '); context.report({ node: declaration.source, - message: `Parse errors in imported module '${declaration.source.value}': ` + - `${this.errors - .map(e => `${e.message} (${e.lineNumber}:${e.column})`) - .join(', ')}`, + message: `Parse errors in imported module '${declaration.source.value}': ${msg}`, }); } } @@ -211,7 +212,7 @@ function captureDoc(source, docStyleParsers, ...nodes) { const metadata = {}; // 'some' short-circuits on first 'true' - nodes.some(n => { + nodes.some((n) => { try { let leadingComments; @@ -223,7 +224,7 @@ function captureDoc(source, docStyleParsers, ...nodes) { leadingComments = source.getCommentsBefore(n); } - if (!leadingComments || leadingComments.length === 0) return false; + if (!leadingComments || leadingComments.length === 0) { return false; } for (const name in docStyleParsers) { const doc = docStyleParsers[name](leadingComments); @@ -255,9 +256,9 @@ function captureJsDoc(comments) { let doc; // capture XSDoc - comments.forEach(comment => { + comments.forEach((comment) => { // skip non-block comments - if (comment.type !== 'Block') return; + if (comment.type !== 'Block') { return; } try { doc = doctrine.parse(comment.value, { unwrap: true }); } catch (err) { @@ -276,7 +277,7 @@ function captureTomDoc(comments) { const lines = []; for (let i = 0; i < comments.length; i++) { const comment = comments[i]; - if (comment.value.match(/^\s*$/)) break; + if (comment.value.match(/^\s*$/)) { break; } lines.push(comment.value.trim()); } @@ -297,7 +298,7 @@ const supportedImportTypes = new Set(['ImportDefaultSpecifier', 'ImportNamespace ExportMap.get = function (source, context) { const path = resolve(source, context); - if (path == null) return null; + if (path == null) { return null; } return ExportMap.for(childContext(path, context)); }; @@ -309,7 +310,7 @@ ExportMap.for = function (context) { let exportMap = exportCache.get(cacheKey); // return cached ignore - if (exportMap === null) return null; + if (exportMap === null) { return null; } const stats = fs.statSync(path); if (exportMap != null) { @@ -358,7 +359,6 @@ ExportMap.for = function (context) { return exportMap; }; - ExportMap.parse = function (path, content, context) { const m = new ExportMap(path); const isEsModuleInteropTrue = isEsModuleInterop(); @@ -416,21 +416,21 @@ ExportMap.parse = function (path, content, context) { }); const unambiguouslyESM = unambiguous.isModule(ast); - if (!unambiguouslyESM && !hasDynamicImports) return null; + if (!unambiguouslyESM && !hasDynamicImports) { return null; } - const docstyle = (context.settings && context.settings['import/docstyle']) || ['jsdoc']; + const docstyle = context.settings && context.settings['import/docstyle'] || ['jsdoc']; const docStyleParsers = {}; - docstyle.forEach(style => { + docstyle.forEach((style) => { docStyleParsers[style] = availableDocStyleParsers[style]; }); // attempt to collect module doc if (ast.comments) { - ast.comments.some(c => { - if (c.type !== 'Block') return false; + ast.comments.some((c) => { + if (c.type !== 'Block') { return false; } try { const doc = doctrine.parse(c.value, { unwrap: true }); - if (doc.tags.some(t => t.title === 'module')) { + if (doc.tags.some((t) => t.title === 'module')) { m.doc = doc; return true; } @@ -447,12 +447,12 @@ ExportMap.parse = function (path, content, context) { function resolveImport(value) { const rp = remotePath(value); - if (rp == null) return null; + if (rp == null) { return null; } return ExportMap.for(childContext(rp, context)); } function getNamespace(identifier) { - if (!namespaces.has(identifier.name)) return; + if (!namespaces.has(identifier.name)) { return; } return function () { return resolveImport(namespaces.get(identifier.name)); @@ -474,27 +474,27 @@ ExportMap.parse = function (path, content, context) { let local; switch (s.type) { - case 'ExportDefaultSpecifier': - if (!nsource) return; - local = 'default'; - break; - case 'ExportNamespaceSpecifier': - m.namespace.set(s.exported.name, Object.defineProperty(exportMeta, 'namespace', { - get() { return resolveImport(nsource); }, - })); - return; - case 'ExportAllDeclaration': - m.namespace.set(s.exported.name || s.exported.value, addNamespace(exportMeta, s.source.value)); - return; - case 'ExportSpecifier': - if (!n.source) { - m.namespace.set(s.exported.name || s.exported.value, addNamespace(exportMeta, s.local)); + case 'ExportDefaultSpecifier': + if (!nsource) { return; } + local = 'default'; + break; + case 'ExportNamespaceSpecifier': + m.namespace.set(s.exported.name, Object.defineProperty(exportMeta, 'namespace', { + get() { return resolveImport(nsource); }, + })); return; - } + case 'ExportAllDeclaration': + m.namespace.set(s.exported.name || s.exported.value, addNamespace(exportMeta, s.source.value)); + return; + case 'ExportSpecifier': + if (!n.source) { + m.namespace.set(s.exported.name || s.exported.value, addNamespace(exportMeta, s.local)); + return; + } // else falls through - default: - local = s.local.name; - break; + default: + local = s.local.name; + break; } // todo: JSDoc @@ -508,7 +508,7 @@ ExportMap.parse = function (path, content, context) { // shouldn't be considered to be just importing types let specifiersOnlyImportingTypes = n.specifiers.length > 0; const importedSpecifiers = new Set(); - n.specifiers.forEach(specifier => { + n.specifiers.forEach((specifier) => { if (specifier.type === 'ImportSpecifier') { importedSpecifiers.add(specifier.imported.name || specifier.imported.value); } else if (supportedImportTypes.has(specifier.type)) { @@ -523,10 +523,10 @@ ExportMap.parse = function (path, content, context) { } function captureDependency({ source }, isOnlyImportingTypes, importedSpecifiers = new Set()) { - if (source == null) return null; + if (source == null) { return null; } const p = remotePath(source.value); - if (p == null) return null; + if (p == null) { return null; } const declarationMetadata = { // capturing actual node reference holds full AST in memory! @@ -550,9 +550,7 @@ ExportMap.parse = function (path, content, context) { function readTsConfig(context) { const tsConfigInfo = tsConfigLoader({ - cwd: - (context.parserOptions && context.parserOptions.tsconfigRootDir) || - process.cwd(), + cwd: context.parserOptions && context.parserOptions.tsconfigRootDir || process.cwd(), getEnv: (key) => process.env[key], }); try { @@ -599,7 +597,7 @@ ExportMap.parse = function (path, content, context) { if (n.type === 'ExportAllDeclaration') { const getter = captureDependency(n, n.exportKind === 'type'); - if (getter) m.dependencies.add(getter); + if (getter) { m.dependencies.add(getter); } if (n.exported) { processSpecifier(n, n.exported, m); } @@ -610,7 +608,7 @@ ExportMap.parse = function (path, content, context) { if (n.type === 'ImportDeclaration') { captureDependencyWithSpecifiers(n); - const ns = n.specifiers.find(s => s.type === 'ImportNamespaceSpecifier'); + const ns = n.specifiers.find((s) => s.type === 'ImportNamespaceSpecifier'); if (ns) { namespaces.set(ns.local.name, n.source.value); } @@ -623,24 +621,28 @@ ExportMap.parse = function (path, content, context) { // capture declaration if (n.declaration != null) { switch (n.declaration.type) { - case 'FunctionDeclaration': - case 'ClassDeclaration': - case 'TypeAlias': // flowtype with babel-eslint parser - case 'InterfaceDeclaration': - case 'DeclareFunction': - case 'TSDeclareFunction': - case 'TSEnumDeclaration': - case 'TSTypeAliasDeclaration': - case 'TSInterfaceDeclaration': - case 'TSAbstractClassDeclaration': - case 'TSModuleDeclaration': - m.namespace.set(n.declaration.id.name, captureDoc(source, docStyleParsers, n)); - break; - case 'VariableDeclaration': - n.declaration.declarations.forEach((d) => - recursivePatternCapture(d.id, - id => m.namespace.set(id.name, captureDoc(source, docStyleParsers, d, n)))); - break; + case 'FunctionDeclaration': + case 'ClassDeclaration': + case 'TypeAlias': // flowtype with babel-eslint parser + case 'InterfaceDeclaration': + case 'DeclareFunction': + case 'TSDeclareFunction': + case 'TSEnumDeclaration': + case 'TSTypeAliasDeclaration': + case 'TSInterfaceDeclaration': + case 'TSAbstractClassDeclaration': + case 'TSModuleDeclaration': + m.namespace.set(n.declaration.id.name, captureDoc(source, docStyleParsers, n)); + break; + case 'VariableDeclaration': + n.declaration.declarations.forEach((d) => { + recursivePatternCapture( + d.id, + (id) => m.namespace.set(id.name, captureDoc(source, docStyleParsers, d, n)), + ); + }); + break; + default: } } @@ -656,7 +658,7 @@ ExportMap.parse = function (path, content, context) { if (includes(exports, n.type)) { const exportedName = n.type === 'TSNamespaceExportDeclaration' ? (n.id || n.name).name - : (n.expression && n.expression.name || (n.expression.id && n.expression.id.name) || null); + : n.expression && n.expression.name || n.expression.id && n.expression.id.name || null; const declTypes = [ 'VariableDeclaration', 'ClassDeclaration', @@ -668,7 +670,7 @@ ExportMap.parse = function (path, content, context) { 'TSModuleDeclaration', ]; const exportedDecls = ast.body.filter(({ type, id, declarations }) => includes(declTypes, type) && ( - (id && id.name === exportedName) || (declarations && declarations.find((d) => d.id.name === exportedName)) + id && id.name === exportedName || declarations && declarations.find((d) => d.id.name === exportedName) )); if (exportedDecls.length === 0) { // Export is not referencing any local declaration, must be re-exporting @@ -689,18 +691,17 @@ ExportMap.parse = function (path, content, context) { decl.body.body.forEach((moduleBlockNode) => { // Export-assignment exports all members in the namespace, // explicitly exported or not. - const namespaceDecl = moduleBlockNode.type === 'ExportNamedDeclaration' ? - moduleBlockNode.declaration : - moduleBlockNode; + const namespaceDecl = moduleBlockNode.type === 'ExportNamedDeclaration' + ? moduleBlockNode.declaration + : moduleBlockNode; if (!namespaceDecl) { // TypeScript can check this for us; we needn't } else if (namespaceDecl.type === 'VariableDeclaration') { - namespaceDecl.declarations.forEach((d) => - recursivePatternCapture(d.id, (id) => m.namespace.set( - id.name, - captureDoc(source, docStyleParsers, decl, namespaceDecl, moduleBlockNode), - )), + namespaceDecl.declarations.forEach((d) => recursivePatternCapture(d.id, (id) => m.namespace.set( + id.name, + captureDoc(source, docStyleParsers, decl, namespaceDecl, moduleBlockNode), + )), ); } else { m.namespace.set( @@ -740,7 +741,6 @@ function thunkFor(p, context) { return () => ExportMap.for(childContext(p, context)); } - /** * Traverse a pattern/identifier node, calling 'callback' * for each leaf identifier. @@ -750,34 +750,35 @@ function thunkFor(p, context) { */ export function recursivePatternCapture(pattern, callback) { switch (pattern.type) { - case 'Identifier': // base case - callback(pattern); - break; - - case 'ObjectPattern': - pattern.properties.forEach(p => { - if (p.type === 'ExperimentalRestProperty' || p.type === 'RestElement') { - callback(p.argument); - return; - } - recursivePatternCapture(p.value, callback); - }); - break; + case 'Identifier': // base case + callback(pattern); + break; - case 'ArrayPattern': - pattern.elements.forEach((element) => { - if (element == null) return; - if (element.type === 'ExperimentalRestProperty' || element.type === 'RestElement') { - callback(element.argument); - return; - } - recursivePatternCapture(element, callback); - }); - break; + case 'ObjectPattern': + pattern.properties.forEach((p) => { + if (p.type === 'ExperimentalRestProperty' || p.type === 'RestElement') { + callback(p.argument); + return; + } + recursivePatternCapture(p.value, callback); + }); + break; - case 'AssignmentPattern': - callback(pattern.left); - break; + case 'ArrayPattern': + pattern.elements.forEach((element) => { + if (element == null) { return; } + if (element.type === 'ExperimentalRestProperty' || element.type === 'RestElement') { + callback(element.argument); + return; + } + recursivePatternCapture(element, callback); + }); + break; + + case 'AssignmentPattern': + callback(pattern.left); + break; + default: } } @@ -811,7 +812,6 @@ function childContext(path, context) { }; } - /** * sometimes legacy support isn't _that_ hard... right? */ diff --git a/src/core/importType.js b/src/core/importType.js index ebdb306bc..6a37d1bb1 100644 --- a/src/core/importType.js +++ b/src/core/importType.js @@ -14,7 +14,7 @@ function baseModule(name) { } function isInternalRegexMatch(name, settings) { - const internalScope = (settings && settings['import/internal-regex']); + const internalScope = settings && settings['import/internal-regex']; return internalScope && new RegExp(internalScope).test(name); } @@ -24,21 +24,21 @@ export function isAbsolute(name) { // path is defined only when a resolver resolves to a non-standard path export function isBuiltIn(name, settings, path) { - if (path || !name) return false; + if (path || !name) { return false; } const base = baseModule(name); - const extras = (settings && settings['import/core-modules']) || []; + const extras = settings && settings['import/core-modules'] || []; return isCoreModule(base) || extras.indexOf(base) > -1; } export function isExternalModule(name, path, context) { - if (arguments.length < 3) { + if (arguments.length < 3) { throw new TypeError('isExternalModule: name, path, and context are all required'); } return (isModule(name) || isScoped(name)) && typeTest(name, context, path) === 'external'; } export function isExternalModuleMain(name, path, context) { - if (arguments.length < 3) { + if (arguments.length < 3) { throw new TypeError('isExternalModule: name, path, and context are all required'); } return isModuleMain(name) && typeTest(name, context, path) === 'external'; @@ -65,7 +65,7 @@ export function isScopedMain(name) { } function isRelativeToParent(name) { - return /^\.\.$|^\.\.[\\/]/.test(name); + return (/^\.\.$|^\.\.[\\/]/).test(name); } const indexFiles = ['.', './', './index', './index.js']; @@ -74,7 +74,7 @@ function isIndex(name) { } function isRelativeToSibling(name) { - return /^\.[\\/]/.test(name); + return (/^\.[\\/]/).test(name); } function isExternalPath(path, context) { @@ -89,7 +89,7 @@ function isExternalPath(path, context) { return true; } - const folders = (settings && settings['import/external-module-folders']) || ['node_modules']; + const folders = settings && settings['import/external-module-folders'] || ['node_modules']; return folders.some((folder) => { const folderPath = nodeResolve(packagePath, folder); const relativePath = relative(folderPath, path); @@ -109,7 +109,7 @@ function isExternalLookingName(name) { return isModule(name) || isScoped(name); } -function typeTest(name, context, path ) { +function typeTest(name, context, path) { const { settings } = context; if (isInternalRegexMatch(name, settings)) { return 'internal'; } if (isAbsolute(name, settings, path)) { return 'absolute'; } diff --git a/src/core/packagePath.js b/src/core/packagePath.js index 2b5a2d41e..1a7a28f4b 100644 --- a/src/core/packagePath.js +++ b/src/core/packagePath.js @@ -2,7 +2,6 @@ import { dirname } from 'path'; import pkgUp from 'eslint-module-utils/pkgUp'; import readPkgUp from 'eslint-module-utils/readPkgUp'; - export function getContextPackagePath(context) { return getFilePackagePath(context.getPhysicalFilename ? context.getPhysicalFilename() : context.getFilename()); } diff --git a/src/core/staticRequire.js b/src/core/staticRequire.js index 502d39317..88b5000c8 100644 --- a/src/core/staticRequire.js +++ b/src/core/staticRequire.js @@ -1,10 +1,10 @@ // todo: merge with module visitor export default function isStaticRequire(node) { - return node && - node.callee && - node.callee.type === 'Identifier' && - node.callee.name === 'require' && - node.arguments.length === 1 && - node.arguments[0].type === 'Literal' && - typeof node.arguments[0].value === 'string'; + return node + && node.callee + && node.callee.type === 'Identifier' + && node.callee.name === 'require' + && node.arguments.length === 1 + && node.arguments[0].type === 'Literal' + && typeof node.arguments[0].value === 'string'; } diff --git a/src/index.js b/src/index.js index 15f98d96f..feafba900 100644 --- a/src/index.js +++ b/src/index.js @@ -1,12 +1,12 @@ export const rules = { 'no-unresolved': require('./rules/no-unresolved'), - 'named': require('./rules/named'), - 'default': require('./rules/default'), - 'namespace': require('./rules/namespace'), + named: require('./rules/named'), + default: require('./rules/default'), + namespace: require('./rules/namespace'), 'no-namespace': require('./rules/no-namespace'), - 'export': require('./rules/export'), + export: require('./rules/export'), 'no-mutable-exports': require('./rules/no-mutable-exports'), - 'extensions': require('./rules/extensions'), + extensions: require('./rules/extensions'), 'no-restricted-paths': require('./rules/no-restricted-paths'), 'no-internal-modules': require('./rules/no-internal-modules'), 'group-exports': require('./rules/group-exports'), @@ -25,19 +25,19 @@ export const rules = { 'no-commonjs': require('./rules/no-commonjs'), 'no-amd': require('./rules/no-amd'), 'no-duplicates': require('./rules/no-duplicates'), - 'first': require('./rules/first'), + first: require('./rules/first'), 'max-dependencies': require('./rules/max-dependencies'), 'no-extraneous-dependencies': require('./rules/no-extraneous-dependencies'), 'no-absolute-path': require('./rules/no-absolute-path'), 'no-nodejs-modules': require('./rules/no-nodejs-modules'), 'no-webpack-loader-syntax': require('./rules/no-webpack-loader-syntax'), - 'order': require('./rules/order'), + order: require('./rules/order'), 'newline-after-import': require('./rules/newline-after-import'), 'prefer-default-export': require('./rules/prefer-default-export'), 'no-default-export': require('./rules/no-default-export'), 'no-named-export': require('./rules/no-named-export'), 'no-dynamic-require': require('./rules/no-dynamic-require'), - 'unambiguous': require('./rules/unambiguous'), + unambiguous: require('./rules/unambiguous'), 'no-unassigned-import': require('./rules/no-unassigned-import'), 'no-useless-path-segments': require('./rules/no-useless-path-segments'), 'dynamic-import-chunkname': require('./rules/dynamic-import-chunkname'), @@ -55,17 +55,17 @@ export const rules = { }; export const configs = { - 'recommended': require('../config/recommended'), + recommended: require('../config/recommended'), - 'errors': require('../config/errors'), - 'warnings': require('../config/warnings'), + errors: require('../config/errors'), + warnings: require('../config/warnings'), // shhhh... work in progress "secret" rules 'stage-0': require('../config/stage-0'), // useful stuff for folks using various environments - 'react': require('../config/react'), + react: require('../config/react'), 'react-native': require('../config/react-native'), - 'electron': require('../config/electron'), - 'typescript': require('../config/typescript'), + electron: require('../config/electron'), + typescript: require('../config/typescript'), }; diff --git a/src/rules/consistent-type-specifier-style.js b/src/rules/consistent-type-specifier-style.js index bb8fdf849..9119976b1 100644 --- a/src/rules/consistent-type-specifier-style.js +++ b/src/rules/consistent-type-specifier-style.js @@ -26,7 +26,7 @@ function getImportText( return ''; } - const names = specifiers.map(s => { + const names = specifiers.map((s) => { if (s.imported.name === s.local.name) { return s.imported.name; } @@ -67,12 +67,14 @@ module.exports = { if ( // no specifiers (import type {} from '') have no specifiers to mark as inline - node.specifiers.length === 0 || - (node.specifiers.length === 1 && - // default imports are both "inline" and "top-level" - (node.specifiers[0].type === 'ImportDefaultSpecifier' || - // namespace imports are both "inline" and "top-level" - node.specifiers[0].type === 'ImportNamespaceSpecifier')) + node.specifiers.length === 0 + || node.specifiers.length === 1 + // default imports are both "inline" and "top-level" + && ( + node.specifiers[0].type === 'ImportDefaultSpecifier' + // namespace imports are both "inline" and "top-level" + || node.specifiers[0].type === 'ImportNamespaceSpecifier' + ) ) { return; } @@ -101,15 +103,17 @@ module.exports = { ImportDeclaration(node) { if ( // already top-level is valid - node.importKind === 'type' || - node.importKind === 'typeof' || + node.importKind === 'type' + || node.importKind === 'typeof' // no specifiers (import {} from '') cannot have inline - so is valid - node.specifiers.length === 0 || - (node.specifiers.length === 1 && - // default imports are both "inline" and "top-level" - (node.specifiers[0].type === 'ImportDefaultSpecifier' || - // namespace imports are both "inline" and "top-level" - node.specifiers[0].type === 'ImportNamespaceSpecifier')) + || node.specifiers.length === 0 + || node.specifiers.length === 1 + // default imports are both "inline" and "top-level" + && ( + node.specifiers[0].type === 'ImportDefaultSpecifier' + // namespace imports are both "inline" and "top-level" + || node.specifiers[0].type === 'ImportNamespaceSpecifier' + ) ) { return; } @@ -195,7 +199,7 @@ module.exports = { const comma = sourceCode.getTokenAfter(defaultSpecifier, isComma); const closingBrace = sourceCode.getTokenAfter( node.specifiers[node.specifiers.length - 1], - token => token.type === 'Punctuator' && token.value === '}', + (token) => token.type === 'Punctuator' && token.value === '}', ); fixes.push(fixer.removeRange([ comma.range[0], diff --git a/src/rules/default.js b/src/rules/default.js index 6ca918ef6..f6b786020 100644 --- a/src/rules/default.js +++ b/src/rules/default.js @@ -17,12 +17,12 @@ module.exports = { function checkDefault(specifierType, node) { const defaultSpecifier = node.specifiers.find( - specifier => specifier.type === specifierType, + (specifier) => specifier.type === specifierType, ); - if (!defaultSpecifier) return; + if (!defaultSpecifier) { return; } const imports = Exports.get(node.source.value, context); - if (imports == null) return; + if (imports == null) { return; } if (imports.errors.length) { imports.reportErrors(context, node); @@ -35,8 +35,8 @@ module.exports = { } return { - 'ImportDeclaration': checkDefault.bind(null, 'ImportDefaultSpecifier'), - 'ExportNamedDeclaration': checkDefault.bind(null, 'ExportDefaultSpecifier'), + ImportDeclaration: checkDefault.bind(null, 'ImportDefaultSpecifier'), + ExportNamedDeclaration: checkDefault.bind(null, 'ExportDefaultSpecifier'), }; }, }; diff --git a/src/rules/dynamic-import-chunkname.js b/src/rules/dynamic-import-chunkname.js index 87a8523da..96ceff2e1 100644 --- a/src/rules/dynamic-import-chunkname.js +++ b/src/rules/dynamic-import-chunkname.js @@ -72,8 +72,7 @@ module.exports = { try { // just like webpack itself does vm.runInNewContext(`(function() {return {${comment.value}}})()`); - } - catch (error) { + } catch (error) { context.report({ node, message: `dynamic imports require a "webpack" comment with valid syntax`, diff --git a/src/rules/export.js b/src/rules/export.js index 92583bdd8..c540f1e3c 100644 --- a/src/rules/export.js +++ b/src/rules/export.js @@ -38,19 +38,20 @@ const tsTypePrefix = 'type:'; function isTypescriptFunctionOverloads(nodes) { const nodesArr = Array.from(nodes); - const idents = flatMap(nodesArr, (node) => ( - node.declaration && ( + const idents = flatMap( + nodesArr, + (node) => node.declaration && ( node.declaration.type === 'TSDeclareFunction' // eslint 6+ || node.declaration.type === 'TSEmptyBodyFunctionDeclaration' // eslint 4-5 ) ? node.declaration.id.name - : [] - )); + : [], + ); if (new Set(idents).size !== idents.length) { return true; } - const types = new Set(nodesArr.map(node => node.parent.type)); + const types = new Set(nodesArr.map((node) => node.parent.type)); if (!types.has('TSDeclareFunction')) { return false; } @@ -73,17 +74,17 @@ function isTypescriptFunctionOverloads(nodes) { * @returns {boolean} */ function isTypescriptNamespaceMerging(nodes) { - const types = new Set(Array.from(nodes, node => node.parent.type)); + const types = new Set(Array.from(nodes, (node) => node.parent.type)); const noNamespaceNodes = Array.from(nodes).filter((node) => node.parent.type !== 'TSModuleDeclaration'); return types.has('TSModuleDeclaration') && ( types.size === 1 // Merging with functions - || (types.size === 2 && (types.has('FunctionDeclaration') || types.has('TSDeclareFunction'))) - || (types.size === 3 && types.has('FunctionDeclaration') && types.has('TSDeclareFunction')) + || types.size === 2 && (types.has('FunctionDeclaration') || types.has('TSDeclareFunction')) + || types.size === 3 && types.has('FunctionDeclaration') && types.has('TSDeclareFunction') // Merging with classes or enums - || (types.size === 2 && (types.has('ClassDeclaration') || types.has('TSEnumDeclaration')) && noNamespaceNodes.length === 1) + || types.size === 2 && (types.has('ClassDeclaration') || types.has('TSEnumDeclaration')) && noNamespaceNodes.length === 1 ); } @@ -99,7 +100,7 @@ function isTypescriptNamespaceMerging(nodes) { * @returns {boolean} */ function shouldSkipTypescriptNamespace(node, nodes) { - const types = new Set(Array.from(nodes, node => node.parent.type)); + const types = new Set(Array.from(nodes, (node) => node.parent.type)); return !isTypescriptNamespaceMerging(nodes) && node.parent.type === 'TSModuleDeclaration' @@ -166,7 +167,7 @@ module.exports = { }, ExportNamedDeclaration(node) { - if (node.declaration == null) return; + if (node.declaration == null) { return; } const parent = getParent(node); // support for old TypeScript versions @@ -185,20 +186,19 @@ module.exports = { if (node.declaration.declarations != null) { for (const declaration of node.declaration.declarations) { - recursivePatternCapture(declaration.id, v => - addNamed(v.name, v, parent, isTypeVariableDecl)); + recursivePatternCapture(declaration.id, (v) => { addNamed(v.name, v, parent, isTypeVariableDecl); }); } } }, ExportAllDeclaration(node) { - if (node.source == null) return; // not sure if this is ever true + if (node.source == null) { return; } // not sure if this is ever true // `export * as X from 'path'` does not conflict - if (node.exported && node.exported.name) return; + if (node.exported && node.exported.name) { return; } const remoteExports = ExportMap.get(node.source.value, context); - if (remoteExports == null) return; + if (remoteExports == null) { return; } if (remoteExports.errors.length) { remoteExports.reportErrors(context, node); @@ -223,15 +223,15 @@ module.exports = { } }, - 'Program:exit': function () { + 'Program:exit'() { for (const [, named] of namespace) { for (const [name, nodes] of named) { - if (nodes.size <= 1) continue; + if (nodes.size <= 1) { continue; } - if (isTypescriptFunctionOverloads(nodes) || isTypescriptNamespaceMerging(nodes)) continue; + if (isTypescriptFunctionOverloads(nodes) || isTypescriptNamespaceMerging(nodes)) { continue; } for (const node of nodes) { - if (shouldSkipTypescriptNamespace(node, nodes)) continue; + if (shouldSkipTypescriptNamespace(node, nodes)) { continue; } if (name === 'default') { context.report(node, 'Multiple default exports.'); diff --git a/src/rules/exports-last.js b/src/rules/exports-last.js index ed77758d2..c4ed97e22 100644 --- a/src/rules/exports-last.js +++ b/src/rules/exports-last.js @@ -1,9 +1,9 @@ import docsUrl from '../docsUrl'; function isNonExportStatement({ type }) { - return type !== 'ExportDefaultDeclaration' && - type !== 'ExportNamedDeclaration' && - type !== 'ExportAllDeclaration'; + return type !== 'ExportDefaultDeclaration' + && type !== 'ExportNamedDeclaration' + && type !== 'ExportAllDeclaration'; } module.exports = { diff --git a/src/rules/extensions.js b/src/rules/extensions.js index 7d026c787..50debc6c8 100644 --- a/src/rules/extensions.js +++ b/src/rules/extensions.js @@ -13,8 +13,8 @@ const patternProperties = { const properties = { type: 'object', properties: { - 'pattern': patternProperties, - 'ignorePackages': { type: 'boolean' }, + pattern: patternProperties, + ignorePackages: { type: 'boolean' }, }, }; @@ -26,7 +26,7 @@ function buildProperties(context) { ignorePackages: false, }; - context.options.forEach(obj => { + context.options.forEach((obj) => { // If this is a string, set defaultConfig to its value if (typeof obj === 'string') { @@ -132,25 +132,25 @@ module.exports = { function isExternalRootModule(file) { const slashCount = file.split('/').length - 1; - if (slashCount === 0) return true; - if (isScoped(file) && slashCount <= 1) return true; + if (slashCount === 0) { return true; } + if (isScoped(file) && slashCount <= 1) { return true; } return false; } function checkFileExtension(source, node) { // bail if the declaration doesn't have a source, e.g. "export { foo };", or if it's only partially typed like in an editor - if (!source || !source.value) return; + if (!source || !source.value) { return; } const importPathWithQueryString = source.value; // don't enforce anything on builtins - if (isBuiltIn(importPathWithQueryString, context.settings)) return; + if (isBuiltIn(importPathWithQueryString, context.settings)) { return; } const importPath = importPathWithQueryString.replace(/\?(.*)$/, ''); // don't enforce in root external packages as they may have names with `.js`. // Like `import Decimal from decimal.js`) - if (isExternalRootModule(importPath)) return; + if (isExternalRootModule(importPath)) { return; } const resolvedPath = resolve(importPath, context); @@ -167,7 +167,7 @@ module.exports = { if (!extension || !importPath.endsWith(`.${extension}`)) { // ignore type-only imports and exports - if (node.importKind === 'type' || node.exportKind === 'type') return; + if (node.importKind === 'type' || node.exportKind === 'type') { return; } const extensionRequired = isUseOfExtensionRequired(extension, isPackage); const extensionForbidden = isUseOfExtensionForbidden(extension); if (extensionRequired && !extensionForbidden) { diff --git a/src/rules/first.js b/src/rules/first.js index ebead6cf2..f8cc273a3 100644 --- a/src/rules/first.js +++ b/src/rules/first.js @@ -25,13 +25,13 @@ module.exports = { create(context) { function isPossibleDirective(node) { - return node.type === 'ExpressionStatement' && - node.expression.type === 'Literal' && - typeof node.expression.value === 'string'; + return node.type === 'ExpressionStatement' + && node.expression.type === 'Literal' + && typeof node.expression.value === 'string'; } return { - 'Program': function (n) { + Program(n) { const body = n.body; if (!body) { return; @@ -56,7 +56,7 @@ module.exports = { if (node.type === 'ImportDeclaration' || node.type === 'TSImportEqualsDeclaration') { if (absoluteFirst) { - if (/^\./.test(getImportValue(node))) { + if ((/^\./).test(getImportValue(node))) { anyRelative = true; } else if (anyRelative) { context.report({ @@ -67,7 +67,7 @@ module.exports = { } if (nonImportCount > 0) { for (const variable of context.getDeclaredVariables(node)) { - if (!shouldSort) break; + if (!shouldSort) { break; } const references = variable.references; if (references.length) { for (const reference of references) { @@ -90,7 +90,7 @@ module.exports = { nonImportCount++; } }); - if (!errorInfos.length) return; + if (!errorInfos.length) { return; } errorInfos.forEach(function (errorInfo, index) { const node = errorInfo.node; const infos = { @@ -112,26 +112,27 @@ module.exports = { const nodeSourceCode = String.prototype.slice.apply( originSourceCode, _errorInfo.range, ); - if (/\S/.test(nodeSourceCode[0])) { - return '\n' + nodeSourceCode; + if ((/\S/).test(nodeSourceCode[0])) { + return `\n${nodeSourceCode}`; } return nodeSourceCode; }).join(''); let insertFixer = null; let replaceSourceCode = ''; if (!lastLegalImp) { - insertSourceCode = - insertSourceCode.trim() + insertSourceCode.match(/^(\s+)/)[0]; + insertSourceCode = insertSourceCode.trim() + insertSourceCode.match(/^(\s+)/)[0]; } - insertFixer = lastLegalImp ? - fixer.insertTextAfter(lastLegalImp, insertSourceCode) : - fixer.insertTextBefore(body[0], insertSourceCode); + insertFixer = lastLegalImp + ? fixer.insertTextAfter(lastLegalImp, insertSourceCode) + : fixer.insertTextBefore(body[0], insertSourceCode); + const fixers = [insertFixer].concat(removeFixers); - fixers.forEach(function (computedFixer, i) { - replaceSourceCode += (originSourceCode.slice( + fixers.forEach((computedFixer, i) => { + replaceSourceCode += originSourceCode.slice( fixers[i - 1] ? fixers[i - 1].range[1] : 0, computedFixer.range[0], - ) + computedFixer.text); + ) + computedFixer.text; }); + return fixer.replaceTextRange(range, replaceSourceCode); }; } diff --git a/src/rules/group-exports.js b/src/rules/group-exports.js index 63af9d914..7978130d3 100644 --- a/src/rules/group-exports.js +++ b/src/rules/group-exports.js @@ -98,7 +98,7 @@ function create(context) { 'Program:exit': function onExit() { // Report multiple `export` declarations (ES2015 modules) if (nodes.modules.set.size > 1) { - nodes.modules.set.forEach(node => { + nodes.modules.set.forEach((node) => { context.report({ node, message: errors[node.type], @@ -108,7 +108,7 @@ function create(context) { // Report multiple `aggregated exports` from the same module (ES2015 modules) flat(values(nodes.modules.sources) - .filter(nodesWithSource => Array.isArray(nodesWithSource) && nodesWithSource.length > 1)) + .filter((nodesWithSource) => Array.isArray(nodesWithSource) && nodesWithSource.length > 1)) .forEach((node) => { context.report({ node, @@ -118,7 +118,7 @@ function create(context) { // Report multiple `export type` declarations (FLOW ES2015 modules) if (nodes.types.set.size > 1) { - nodes.types.set.forEach(node => { + nodes.types.set.forEach((node) => { context.report({ node, message: errors[node.type], @@ -128,7 +128,7 @@ function create(context) { // Report multiple `aggregated type exports` from the same module (FLOW ES2015 modules) flat(values(nodes.types.sources) - .filter(nodesWithSource => Array.isArray(nodesWithSource) && nodesWithSource.length > 1)) + .filter((nodesWithSource) => Array.isArray(nodesWithSource) && nodesWithSource.length > 1)) .forEach((node) => { context.report({ node, @@ -138,7 +138,7 @@ function create(context) { // Report multiple `module.exports` assignments (CommonJS) if (nodes.commonjs.set.size > 1) { - nodes.commonjs.set.forEach(node => { + nodes.commonjs.set.forEach((node) => { context.report({ node, message: errors[node.type], diff --git a/src/rules/imports-first.js b/src/rules/imports-first.js index 07bb4633d..966367e99 100644 --- a/src/rules/imports-first.js +++ b/src/rules/imports-first.js @@ -2,13 +2,14 @@ import docsUrl from '../docsUrl'; const first = require('./first'); -const newMeta = Object.assign({}, first.meta, { +const newMeta = { + ...first.meta, deprecated: true, docs: { category: 'Style guide', description: 'Replaced by `import/first`.', url: docsUrl('imports-first', '7b25c1cb95ee18acc1531002fd343e1e6031f9ed'), }, -}); +}; -module.exports = Object.assign({}, first, { meta: newMeta }); +module.exports = { ...first, meta: newMeta }; diff --git a/src/rules/max-dependencies.js b/src/rules/max-dependencies.js index 95f34176f..488e90618 100644 --- a/src/rules/max-dependencies.js +++ b/src/rules/max-dependencies.js @@ -24,17 +24,17 @@ module.exports = { schema: [ { - 'type': 'object', - 'properties': { - 'max': { 'type': 'number' }, - 'ignoreTypeImports': { 'type': 'boolean' }, + type: 'object', + properties: { + max: { type: 'number' }, + ignoreTypeImports: { type: 'boolean' }, }, - 'additionalProperties': false, + additionalProperties: false, }, ], }, - create: context => { + create(context) { const { ignoreTypeImports = DEFAULT_IGNORE_TYPE_IMPORTS, } = context.options[0] || {}; @@ -42,15 +42,19 @@ module.exports = { const dependencies = new Set(); // keep track of dependencies let lastNode; // keep track of the last node to report on - return Object.assign({ - 'Program:exit': function () { + return { + 'Program:exit'() { countDependencies(dependencies, lastNode, context); }, - }, moduleVisitor((source, { importKind }) => { - if (importKind !== TYPE_IMPORT || !ignoreTypeImports) { - dependencies.add(source.value); - } - lastNode = source; - }, { commonjs: true })); + ...moduleVisitor( + (source, { importKind }) => { + if (importKind !== TYPE_IMPORT || !ignoreTypeImports) { + dependencies.add(source.value); + } + lastNode = source; + }, + { commonjs: true }, + ), + }; }, }; diff --git a/src/rules/named.js b/src/rules/named.js index 050f83505..e7fe4e4dc 100644 --- a/src/rules/named.js +++ b/src/rules/named.js @@ -67,12 +67,12 @@ module.exports = { if (!deepLookup.found) { if (deepLookup.path.length > 1) { const deepPath = deepLookup.path - .map(i => path.relative(path.dirname(context.getPhysicalFilename ? context.getPhysicalFilename() : context.getFilename()), i.path)) + .map((i) => path.relative(path.dirname(context.getPhysicalFilename ? context.getPhysicalFilename() : context.getFilename()), i.path)) .join(' -> '); context.report(im[key], `${name} not found via ${deepPath}`); } else { - context.report(im[key], name + ' not found in \'' + node.source.value + '\''); + context.report(im[key], `${name} not found in '${node.source.value}'`); } } }); @@ -121,12 +121,12 @@ module.exports = { if (!deepLookup.found) { if (deepLookup.path.length > 1) { const deepPath = deepLookup.path - .map(i => path.relative(path.dirname(context.getFilename()), i.path)) + .map((i) => path.relative(path.dirname(context.getFilename()), i.path)) .join(' -> '); context.report(im.key, `${im.key.name} not found via ${deepPath}`); } else { - context.report(im.key, im.key.name + ' not found in \'' + source.value + '\''); + context.report(im.key, `${im.key.name} not found in '${source.value}'`); } } }); diff --git a/src/rules/namespace.js b/src/rules/namespace.js index 3b6019da8..77a3ea907 100644 --- a/src/rules/namespace.js +++ b/src/rules/namespace.js @@ -4,12 +4,12 @@ import importDeclaration from '../importDeclaration'; import docsUrl from '../docsUrl'; function processBodyStatement(context, namespaces, declaration) { - if (declaration.type !== 'ImportDeclaration') return; + if (declaration.type !== 'ImportDeclaration') { return; } - if (declaration.specifiers.length === 0) return; + if (declaration.specifiers.length === 0) { return; } const imports = Exports.get(declaration.source.value, context); - if (imports == null) return null; + if (imports == null) { return null; } if (imports.errors.length > 0) { imports.reportErrors(context, declaration); @@ -18,25 +18,26 @@ function processBodyStatement(context, namespaces, declaration) { declaration.specifiers.forEach((specifier) => { switch (specifier.type) { - case 'ImportNamespaceSpecifier': - if (!imports.size) { - context.report( - specifier, - `No exported names found in module '${declaration.source.value}'.`, + case 'ImportNamespaceSpecifier': + if (!imports.size) { + context.report( + specifier, + `No exported names found in module '${declaration.source.value}'.`, + ); + } + namespaces.set(specifier.local.name, imports); + break; + case 'ImportDefaultSpecifier': + case 'ImportSpecifier': { + const meta = imports.get( + // default to 'default' for default https://i.imgur.com/nj6qAWy.jpg + specifier.imported ? specifier.imported.name || specifier.imported.value : 'default', ); + if (!meta || !meta.namespace) { break; } + namespaces.set(specifier.local.name, meta.namespace); + break; } - namespaces.set(specifier.local.name, imports); - break; - case 'ImportDefaultSpecifier': - case 'ImportSpecifier': { - const meta = imports.get( - // default to 'default' for default https://i.imgur.com/nj6qAWy.jpg - specifier.imported ? (specifier.imported.name || specifier.imported.value) : 'default', - ); - if (!meta || !meta.namespace) { break; } - namespaces.set(specifier.local.name, meta.namespace); - break; - } + default: } }); } @@ -66,7 +67,6 @@ module.exports = { }, create: function namespaceRule(context) { - // read options const { allowComputed = false, @@ -81,7 +81,7 @@ module.exports = { return { // pick up all imports at body entry time, to properly respect hoisting Program({ body }) { - body.forEach(x => processBodyStatement(context, namespaces, x)); + body.forEach((x) => { processBodyStatement(context, namespaces, x); }); }, // same as above, but does not add names to local map @@ -89,7 +89,7 @@ module.exports = { const declaration = importDeclaration(context); const imports = Exports.get(declaration.source.value, context); - if (imports == null) return null; + if (imports == null) { return null; } if (imports.errors.length) { imports.reportErrors(context, declaration); @@ -107,9 +107,9 @@ module.exports = { // todo: check for possible redefinition MemberExpression(dereference) { - if (dereference.object.type !== 'Identifier') return; - if (!namespaces.has(dereference.object.name)) return; - if (declaredScope(context, dereference.object.name) !== 'module') return; + if (dereference.object.type !== 'Identifier') { return; } + if (!namespaces.has(dereference.object.name)) { return; } + if (declaredScope(context, dereference.object.name) !== 'module') { return; } if (dereference.parent.type === 'AssignmentExpression' && dereference.parent.left === dereference) { context.report( @@ -142,7 +142,7 @@ module.exports = { } const exported = namespace.get(dereference.property.name); - if (exported == null) return; + if (exported == null) { return; } // stash and pop namepath.push(dereference.property.name); @@ -152,18 +152,18 @@ module.exports = { }, VariableDeclarator({ id, init }) { - if (init == null) return; - if (init.type !== 'Identifier') return; - if (!namespaces.has(init.name)) return; + if (init == null) { return; } + if (init.type !== 'Identifier') { return; } + if (!namespaces.has(init.name)) { return; } // check for redefinition in intermediate scopes - if (declaredScope(context, init.name) !== 'module') return; + if (declaredScope(context, init.name) !== 'module') { return; } // DFS traverse child namespaces function testKey(pattern, namespace, path = [init.name]) { - if (!(namespace instanceof Exports)) return; + if (!(namespace instanceof Exports)) { return; } - if (pattern.type !== 'ObjectPattern') return; + if (pattern.type !== 'ObjectPattern') { return; } for (const property of pattern.properties) { if ( @@ -204,7 +204,7 @@ module.exports = { }, JSXMemberExpression({ object, property }) { - if (!namespaces.has(object.name)) return; + if (!namespaces.has(object.name)) { return; } const namespace = namespaces.get(object.name); if (!namespace.has(property.name)) { context.report({ diff --git a/src/rules/newline-after-import.js b/src/rules/newline-after-import.js index 36678bfc4..c63bb21b2 100644 --- a/src/rules/newline-after-import.js +++ b/src/rules/newline-after-import.js @@ -63,22 +63,22 @@ module.exports = { fixable: 'whitespace', schema: [ { - 'type': 'object', - 'properties': { - 'count': { - 'type': 'integer', - 'minimum': 1, + type: 'object', + properties: { + count: { + type: 'integer', + minimum: 1, }, - 'considerComments': { 'type': 'boolean' }, + considerComments: { type: 'boolean' }, }, - 'additionalProperties': false, + additionalProperties: false, }, ], }, create(context) { let level = 0; const requireCalls = []; - const options = Object.assign({ count: 1, considerComments: false }, context.options[0]); + const options = { count: 1, considerComments: false, ...context.options[0] }; function checkForNewLine(node, nextNode, type) { if (isExportDefaultClass(nextNode) || isExportNameClass(nextNode)) { @@ -107,7 +107,7 @@ module.exports = { column, }, message: `Expected ${options.count} empty line${options.count > 1 ? 's' : ''} after ${type} statement not followed by another ${type}.`, - fix: fixer => fixer.insertTextAfter( + fix: (fixer) => fixer.insertTextAfter( node, '\n'.repeat(EXPECTED_LINE_DIFFERENCE - lineDifference), ), @@ -132,7 +132,7 @@ module.exports = { column, }, message: `Expected ${options.count} empty line${options.count > 1 ? 's' : ''} after import statement not followed by another import.`, - fix: fixer => fixer.insertTextAfter( + fix: (fixer) => fixer.insertTextAfter( node, '\n'.repeat(EXPECTED_LINE_DIFFERENCE - lineDifference), ), @@ -155,10 +155,9 @@ module.exports = { let nextComment; if (typeof parent.comments !== 'undefined' && options.considerComments) { - nextComment = parent.comments.find(o => o.loc.start.line === endLine + 1); + nextComment = parent.comments.find((o) => o.loc.start.line === endLine + 1); } - // skip "export import"s if (node.type === 'TSImportEqualsDeclaration' && node.isExport) { return; @@ -179,12 +178,12 @@ module.exports = { requireCalls.push(node); } }, - 'Program:exit': function () { + 'Program:exit'() { log('exit processing for', context.getPhysicalFilename ? context.getPhysicalFilename() : context.getFilename()); const scopeBody = getScopeBody(context.getScope()); log('got scope:', scopeBody); - requireCalls.forEach(function (node, index) { + requireCalls.forEach((node, index) => { const nodePosition = findNodeIndexInScopeBody(scopeBody, node); log('node position in scope:', nodePosition); @@ -196,8 +195,12 @@ module.exports = { return; } - if (nextStatement && - (!nextRequireCall || !containsNodeOrEqual(nextStatement, nextRequireCall))) { + if ( + nextStatement && ( + !nextRequireCall + || !containsNodeOrEqual(nextStatement, nextRequireCall) + ) + ) { checkForNewLine(statementWithRequireCall, nextStatement, 'require'); } diff --git a/src/rules/no-absolute-path.js b/src/rules/no-absolute-path.js index 19dae6b6f..a5498ec76 100644 --- a/src/rules/no-absolute-path.js +++ b/src/rules/no-absolute-path.js @@ -21,12 +21,12 @@ module.exports = { context.report({ node: source, message: 'Do not import modules using an absolute path', - fix: fixer => { + fix(fixer) { const resolvedContext = context.getPhysicalFilename ? context.getPhysicalFilename() : context.getFilename(); // node.js and web imports work with posix style paths ("/") let relativePath = path.posix.relative(path.dirname(resolvedContext), source.value); if (!relativePath.startsWith('.')) { - relativePath = './' + relativePath; + relativePath = `./${relativePath}`; } return fixer.replaceText(source, JSON.stringify(relativePath)); }, @@ -34,7 +34,7 @@ module.exports = { } } - const options = Object.assign({ esmodule: true, commonjs: true }, context.options[0]); + const options = { esmodule: true, commonjs: true, ...context.options[0] }; return moduleVisitor(reportIfAbsolute, options); }, }; diff --git a/src/rules/no-amd.js b/src/rules/no-amd.js index 90359cd5f..5edfe3e69 100644 --- a/src/rules/no-amd.js +++ b/src/rules/no-amd.js @@ -22,18 +22,17 @@ module.exports = { create(context) { return { - 'CallExpression': function (node) { - if (context.getScope().type !== 'module') return; + CallExpression(node) { + if (context.getScope().type !== 'module') { return; } - if (node.callee.type !== 'Identifier') return; - if (node.callee.name !== 'require' && - node.callee.name !== 'define') return; + if (node.callee.type !== 'Identifier') { return; } + if (node.callee.name !== 'require' && node.callee.name !== 'define') { return; } // todo: capture define((require, module, exports) => {}) form? - if (node.arguments.length !== 2) return; + if (node.arguments.length !== 2) { return; } const modules = node.arguments[0]; - if (modules.type !== 'ArrayExpression') return; + if (modules.type !== 'ArrayExpression') { return; } // todo: check second arg type? (identifier or callback) diff --git a/src/rules/no-anonymous-default-export.js b/src/rules/no-anonymous-default-export.js index d9edcc2b3..80950d550 100644 --- a/src/rules/no-anonymous-default-export.js +++ b/src/rules/no-anonymous-default-export.js @@ -88,16 +88,16 @@ module.exports = { { type: 'object', properties: schemaProperties, - 'additionalProperties': false, + additionalProperties: false, }, ], }, create(context) { - const options = Object.assign({}, defaults, context.options[0]); + const options = { ...defaults, ...context.options[0] }; return { - 'ExportDefaultDeclaration': (node) => { + ExportDefaultDeclaration(node) { const def = defs[node.declaration.type]; // Recognized node type and allowed by configuration, diff --git a/src/rules/no-commonjs.js b/src/rules/no-commonjs.js index 7a35fc8a0..dde509222 100644 --- a/src/rules/no-commonjs.js +++ b/src/rules/no-commonjs.js @@ -16,9 +16,9 @@ function normalizeLegacyOptions(options) { } function allowPrimitive(node, options) { - if (!options.allowPrimitiveModules) return false; - if (node.parent.type !== 'AssignmentExpression') return false; - return (node.parent.right.type !== 'ObjectExpression'); + if (!options.allowPrimitiveModules) { return false; } + if (node.parent.type !== 'AssignmentExpression') { return false; } + return node.parent.right.type !== 'ObjectExpression'; } function allowRequire(node, options) { @@ -40,14 +40,16 @@ function isConditional(node) { || node.type === 'TryStatement' || node.type === 'LogicalExpression' || node.type === 'ConditionalExpression' - ) return true; - if (node.parent) return isConditional(node.parent); + ) { + return true; + } + if (node.parent) { return isConditional(node.parent); } return false; } function isLiteralString(node) { - return (node.type === 'Literal' && typeof node.value === 'string') || - (node.type === 'TemplateLiteral' && node.expressions.length === 0); + return node.type === 'Literal' && typeof node.value === 'string' + || node.type === 'TemplateLiteral' && node.expressions.length === 0; } //------------------------------------------------------------------------------ @@ -58,9 +60,9 @@ const schemaString = { enum: ['allow-primitive-modules'] }; const schemaObject = { type: 'object', properties: { - allowPrimitiveModules: { 'type': 'boolean' }, - allowRequire: { 'type': 'boolean' }, - allowConditionalRequire: { 'type': 'boolean' }, + allowPrimitiveModules: { type: 'boolean' }, + allowRequire: { type: 'boolean' }, + allowConditionalRequire: { type: 'boolean' }, }, additionalProperties: false, }; @@ -95,11 +97,11 @@ module.exports = { return { - 'MemberExpression': function (node) { + MemberExpression(node) { // module.exports if (node.object.name === 'module' && node.property.name === 'exports') { - if (allowPrimitive(node, options)) return; + if (allowPrimitive(node, options)) { return; } context.report({ node, message: EXPORT_MESSAGE }); } @@ -107,25 +109,25 @@ module.exports = { if (node.object.name === 'exports') { const isInScope = context.getScope() .variables - .some(variable => variable.name === 'exports'); - if (! isInScope) { + .some((variable) => variable.name === 'exports'); + if (!isInScope) { context.report({ node, message: EXPORT_MESSAGE }); } } }, - 'CallExpression': function (call) { - if (!validateScope(context.getScope())) return; + CallExpression(call) { + if (!validateScope(context.getScope())) { return; } - if (call.callee.type !== 'Identifier') return; - if (call.callee.name !== 'require') return; + if (call.callee.type !== 'Identifier') { return; } + if (call.callee.name !== 'require') { return; } - if (call.arguments.length !== 1) return; - if (!isLiteralString(call.arguments[0])) return; + if (call.arguments.length !== 1) { return; } + if (!isLiteralString(call.arguments[0])) { return; } - if (allowRequire(call, options)) return; + if (allowRequire(call, options)) { return; } - if (allowConditionalRequire(call, options) && isConditional(call.parent)) return; + if (allowConditionalRequire(call, options) && isConditional(call.parent)) { return; } // keeping it simple: all 1-string-arg `require` calls are reported context.report({ diff --git a/src/rules/no-cycle.js b/src/rules/no-cycle.js index e12a81cea..5b9d8c070 100644 --- a/src/rules/no-cycle.js +++ b/src/rules/no-cycle.js @@ -48,7 +48,7 @@ module.exports = { create(context) { const myPath = context.getPhysicalFilename ? context.getPhysicalFilename() : context.getFilename(); - if (myPath === '') return {}; // can't cycle-check a non-file + if (myPath === '') { return {}; } // can't cycle-check a non-file const options = context.options[0] || {}; const maxDepth = typeof options.maxDepth === 'number' ? options.maxDepth : Infinity; @@ -62,20 +62,23 @@ module.exports = { if (ignoreModule(sourceNode.value)) { return; // ignore external modules } - if (options.allowUnsafeDynamicCyclicDependency && ( - // Ignore `import()` - importer.type === 'ImportExpression' || - // `require()` calls are always checked (if possible) - (importer.type === 'CallExpression' && importer.callee.name !== 'require'))) { + if ( + options.allowUnsafeDynamicCyclicDependency && ( + // Ignore `import()` + importer.type === 'ImportExpression' + // `require()` calls are always checked (if possible) + || importer.type === 'CallExpression' && importer.callee.name !== 'require' + ) + ) { return; // cycle via dynamic import allowed by config } if ( importer.type === 'ImportDeclaration' && ( // import type { Foo } (TS and Flow) - importer.importKind === 'type' || + importer.importKind === 'type' // import { type Foo } (Flow) - importer.specifiers.every(({ importKind }) => importKind === 'type') + || importer.specifiers.every(({ importKind }) => importKind === 'type') ) ) { return; // ignore type imports @@ -91,25 +94,24 @@ module.exports = { return; // no-self-import territory } - const untraversed = [{ mget: () => imported, route:[] }]; + const untraversed = [{ mget: () => imported, route: [] }]; function detectCycle({ mget, route }) { const m = mget(); - if (m == null) return; - if (traversed.has(m.path)) return; + if (m == null) { return; } + if (traversed.has(m.path)) { return; } traversed.add(m.path); for (const [path, { getter, declarations }] of m.imports) { - if (traversed.has(path)) continue; - const toTraverse = [...declarations].filter(({ source, isOnlyImportingTypes }) => - !ignoreModule(source.value) && + if (traversed.has(path)) { continue; } + const toTraverse = [...declarations].filter(({ source, isOnlyImportingTypes }) => !ignoreModule(source.value) // Ignore only type imports - !isOnlyImportingTypes, + && !isOnlyImportingTypes, ); /* If cyclic dependency is allowed via dynamic import, skip checking if any module is imported dynamically */ - if (options.allowUnsafeDynamicCyclicDependency && toTraverse.some(d => d.dynamic)) return; + if (options.allowUnsafeDynamicCyclicDependency && toTraverse.some((d) => d.dynamic)) { return; } /* Only report as a cycle if there are any import declarations that are considered by @@ -121,7 +123,7 @@ module.exports = { b.ts: import type { Bar } from './a' */ - if (path === myPath && toTraverse.length > 0) return true; + if (path === myPath && toTraverse.length > 0) { return true; } if (route.length + 1 < maxDepth) { for (const { source } of toTraverse) { untraversed.push({ mget: getter, route: route.concat(source) }); @@ -133,9 +135,9 @@ module.exports = { while (untraversed.length > 0) { const next = untraversed.shift(); // bfs! if (detectCycle(next)) { - const message = (next.route.length > 0 + const message = next.route.length > 0 ? `Dependency cycle via ${routeString(next.route)}` - : 'Dependency cycle detected.'); + : 'Dependency cycle detected.'; context.report(importer, message); return; } @@ -143,7 +145,7 @@ module.exports = { } return Object.assign(moduleVisitor(checkSourceValue, context.options[0]), { - 'Program:exit': () => { + 'Program:exit'() { traversed.clear(); }, }); @@ -151,5 +153,5 @@ module.exports = { }; function routeString(route) { - return route.map(s => `${s.value}:${s.loc.start.line}`).join('=>'); + return route.map((s) => `${s.value}:${s.loc.start.line}`).join('=>'); } diff --git a/src/rules/no-default-export.js b/src/rules/no-default-export.js index 5fc8c40e4..6e5a53748 100644 --- a/src/rules/no-default-export.js +++ b/src/rules/no-default-export.js @@ -27,7 +27,7 @@ module.exports = { }, ExportNamedDeclaration(node) { - node.specifiers.filter(specifier => (specifier.exported.name || specifier.exported.value) === 'default').forEach(specifier => { + node.specifiers.filter((specifier) => (specifier.exported.name || specifier.exported.value) === 'default').forEach((specifier) => { const { loc } = context.getSourceCode().getFirstTokens(node)[1] || {}; if (specifier.type === 'ExportDefaultSpecifier') { context.report({ node, message: preferNamed, loc }); diff --git a/src/rules/no-deprecated.js b/src/rules/no-deprecated.js index 7a35a8e67..06eeff8ea 100644 --- a/src/rules/no-deprecated.js +++ b/src/rules/no-deprecated.js @@ -3,13 +3,13 @@ import Exports from '../ExportMap'; import docsUrl from '../docsUrl'; function message(deprecation) { - return 'Deprecated' + (deprecation.description ? ': ' + deprecation.description : '.'); + return `Deprecated${deprecation.description ? `: ${deprecation.description}` : '.'}`; } function getDeprecation(metadata) { - if (!metadata || !metadata.doc) return; + if (!metadata || !metadata.doc) { return; } - return metadata.doc.tags.find(t => t.title === 'deprecated'); + return metadata.doc.tags.find((t) => t.title === 'deprecated'); } module.exports = { @@ -28,13 +28,13 @@ module.exports = { const namespaces = new Map(); function checkSpecifiers(node) { - if (node.type !== 'ImportDeclaration') return; - if (node.source == null) return; // local export, ignore + if (node.type !== 'ImportDeclaration') { return; } + if (node.source == null) { return; } // local export, ignore const imports = Exports.get(node.source.value, context); - if (imports == null) return; + if (imports == null) { return; } - const moduleDeprecation = imports.doc && imports.doc.tags.find(t => t.title === 'deprecated'); + const moduleDeprecation = imports.doc && imports.doc.tags.find((t) => t.title === 'deprecated'); if (moduleDeprecation) { context.report({ node, message: message(moduleDeprecation) }); } @@ -48,35 +48,34 @@ module.exports = { let imported; let local; switch (im.type) { + case 'ImportNamespaceSpecifier': { + if (!imports.size) { return; } + namespaces.set(im.local.name, imports); + return; + } - case 'ImportNamespaceSpecifier':{ - if (!imports.size) return; - namespaces.set(im.local.name, imports); - return; - } - - case 'ImportDefaultSpecifier': - imported = 'default'; - local = im.local.name; - break; + case 'ImportDefaultSpecifier': + imported = 'default'; + local = im.local.name; + break; - case 'ImportSpecifier': - imported = im.imported.name; - local = im.local.name; - break; + case 'ImportSpecifier': + imported = im.imported.name; + local = im.local.name; + break; - default: return; // can't handle this one + default: return; // can't handle this one } // unknown thing can't be deprecated const exported = imports.get(imported); - if (exported == null) return; + if (exported == null) { return; } // capture import of deep namespace - if (exported.namespace) namespaces.set(local, exported.namespace); + if (exported.namespace) { namespaces.set(local, exported.namespace); } const deprecation = getDeprecation(imports.get(imported)); - if (!deprecation) return; + if (!deprecation) { return; } context.report({ node: im, message: message(deprecation) }); @@ -86,44 +85,42 @@ module.exports = { } return { - 'Program': ({ body }) => body.forEach(checkSpecifiers), + Program: ({ body }) => body.forEach(checkSpecifiers), - 'Identifier': function (node) { + Identifier(node) { if (node.parent.type === 'MemberExpression' && node.parent.property === node) { return; // handled by MemberExpression } // ignore specifier identifiers - if (node.parent.type.slice(0, 6) === 'Import') return; + if (node.parent.type.slice(0, 6) === 'Import') { return; } - if (!deprecated.has(node.name)) return; + if (!deprecated.has(node.name)) { return; } - if (declaredScope(context, node.name) !== 'module') return; + if (declaredScope(context, node.name) !== 'module') { return; } context.report({ node, message: message(deprecated.get(node.name)), }); }, - 'MemberExpression': function (dereference) { - if (dereference.object.type !== 'Identifier') return; - if (!namespaces.has(dereference.object.name)) return; + MemberExpression(dereference) { + if (dereference.object.type !== 'Identifier') { return; } + if (!namespaces.has(dereference.object.name)) { return; } - if (declaredScope(context, dereference.object.name) !== 'module') return; + if (declaredScope(context, dereference.object.name) !== 'module') { return; } // go deep let namespace = namespaces.get(dereference.object.name); const namepath = [dereference.object.name]; // while property is namespace and parent is member expression, keep validating - while (namespace instanceof Exports && - dereference.type === 'MemberExpression') { - + while (namespace instanceof Exports && dereference.type === 'MemberExpression') { // ignore computed parts for now - if (dereference.computed) return; + if (dereference.computed) { return; } const metadata = namespace.get(dereference.property.name); - if (!metadata) break; + if (!metadata) { break; } const deprecation = getDeprecation(metadata); if (deprecation) { diff --git a/src/rules/no-duplicates.js b/src/rules/no-duplicates.js index 15515e675..76bf187b2 100644 --- a/src/rules/no-duplicates.js +++ b/src/rules/no-duplicates.js @@ -62,16 +62,16 @@ function getFix(first, rest, sourceCode, context) { // Leave it to the user to handle comments. Also skip `import * as ns from // './foo'` imports, since they cannot be merged into another import. - const restWithoutComments = rest.filter(node => !( - hasProblematicComments(node, sourceCode) || - hasNamespace(node) + const restWithoutComments = rest.filter((node) => !( + hasProblematicComments(node, sourceCode) + || hasNamespace(node) )); const specifiers = restWithoutComments - .map(node => { + .map((node) => { const tokens = sourceCode.getTokens(node); - const openBrace = tokens.find(token => isPunctuator(token, '{')); - const closeBrace = tokens.find(token => isPunctuator(token, '}')); + const openBrace = tokens.find((token) => isPunctuator(token, '{')); + const closeBrace = tokens.find((token) => isPunctuator(token, '}')); if (openBrace == null || closeBrace == null) { return undefined; @@ -85,10 +85,9 @@ function getFix(first, rest, sourceCode, context) { }) .filter(Boolean); - const unnecessaryImports = restWithoutComments.filter(node => - !hasSpecifiers(node) && - !hasNamespace(node) && - !specifiers.some(specifier => specifier.importNode === node), + const unnecessaryImports = restWithoutComments.filter((node) => !hasSpecifiers(node) + && !hasNamespace(node) + && !specifiers.some((specifier) => specifier.importNode === node), ); const shouldAddDefault = getDefaultImportName(first) == null && defaultImportNames.size === 1; @@ -99,16 +98,14 @@ function getFix(first, rest, sourceCode, context) { return undefined; } - return fixer => { + return (fixer) => { const tokens = sourceCode.getTokens(first); - const openBrace = tokens.find(token => isPunctuator(token, '{')); - const closeBrace = tokens.find(token => isPunctuator(token, '}')); + const openBrace = tokens.find((token) => isPunctuator(token, '{')); + const closeBrace = tokens.find((token) => isPunctuator(token, '}')); const firstToken = sourceCode.getFirstToken(first); const [defaultImportName] = defaultImportNames; - const firstHasTrailingComma = - closeBrace != null && - isPunctuator(sourceCode.getTokenBefore(closeBrace), ','); + const firstHasTrailingComma = closeBrace != null && isPunctuator(sourceCode.getTokenBefore(closeBrace), ','); const firstIsEmpty = !hasSpecifiers(first); const firstExistingIdentifiers = firstIsEmpty ? new Set() @@ -214,21 +211,21 @@ function isPunctuator(node, value) { // Get the name of the default import of `node`, if any. function getDefaultImportName(node) { const defaultSpecifier = node.specifiers - .find(specifier => specifier.type === 'ImportDefaultSpecifier'); + .find((specifier) => specifier.type === 'ImportDefaultSpecifier'); return defaultSpecifier != null ? defaultSpecifier.local.name : undefined; } // Checks whether `node` has a namespace import. function hasNamespace(node) { const specifiers = node.specifiers - .filter(specifier => specifier.type === 'ImportNamespaceSpecifier'); + .filter((specifier) => specifier.type === 'ImportNamespaceSpecifier'); return specifiers.length > 0; } // Checks whether `node` has any non-default specifiers. function hasSpecifiers(node) { const specifiers = node.specifiers - .filter(specifier => specifier.type === 'ImportSpecifier'); + .filter((specifier) => specifier.type === 'ImportSpecifier'); return specifiers.length > 0; } @@ -236,9 +233,9 @@ function hasSpecifiers(node) { // duplicate imports, so skip imports with comments when autofixing. function hasProblematicComments(node, sourceCode) { return ( - hasCommentBefore(node, sourceCode) || - hasCommentAfter(node, sourceCode) || - hasCommentInsideNonSpecifiers(node, sourceCode) + hasCommentBefore(node, sourceCode) + || hasCommentAfter(node, sourceCode) + || hasCommentInsideNonSpecifiers(node, sourceCode) ); } @@ -246,29 +243,29 @@ function hasProblematicComments(node, sourceCode) { // the same line as `node` (starts). function hasCommentBefore(node, sourceCode) { return sourceCode.getCommentsBefore(node) - .some(comment => comment.loc.end.line >= node.loc.start.line - 1); + .some((comment) => comment.loc.end.line >= node.loc.start.line - 1); } // Checks whether `node` has a comment (that starts) on the same line as `node` // (ends). function hasCommentAfter(node, sourceCode) { return sourceCode.getCommentsAfter(node) - .some(comment => comment.loc.start.line === node.loc.end.line); + .some((comment) => comment.loc.start.line === node.loc.end.line); } // Checks whether `node` has any comments _inside,_ except inside the `{...}` // part (if any). function hasCommentInsideNonSpecifiers(node, sourceCode) { const tokens = sourceCode.getTokens(node); - const openBraceIndex = tokens.findIndex(token => isPunctuator(token, '{')); - const closeBraceIndex = tokens.findIndex(token => isPunctuator(token, '}')); + const openBraceIndex = tokens.findIndex((token) => isPunctuator(token, '{')); + const closeBraceIndex = tokens.findIndex((token) => isPunctuator(token, '}')); // Slice away the first token, since we're no looking for comments _before_ // `node` (only inside). If there's a `{...}` part, look for comments before // the `{`, but not before the `}` (hence the `+1`s). const someTokens = openBraceIndex >= 0 && closeBraceIndex >= 0 ? tokens.slice(1, openBraceIndex + 1).concat(tokens.slice(closeBraceIndex + 1)) : tokens.slice(1); - return someTokens.some(token => sourceCode.getCommentsBefore(token).length > 0); + return someTokens.some((token) => sourceCode.getCommentsBefore(token).length > 0); } module.exports = { @@ -298,16 +295,16 @@ module.exports = { create(context) { // Prepare the resolver from options. - const considerQueryStringOption = context.options[0] && - context.options[0]['considerQueryString']; - const defaultResolver = sourcePath => resolve(sourcePath, context) || sourcePath; - const resolver = considerQueryStringOption ? (sourcePath => { + const considerQueryStringOption = context.options[0] + && context.options[0].considerQueryString; + const defaultResolver = (sourcePath) => resolve(sourcePath, context) || sourcePath; + const resolver = considerQueryStringOption ? (sourcePath) => { const parts = sourcePath.match(/^([^?]*)\?(.*)$/); if (!parts) { return defaultResolver(sourcePath); } - return defaultResolver(parts[1]) + '?' + parts[2]; - }) : defaultResolver; + return `${defaultResolver(parts[1])}?${parts[2]}`; + } : defaultResolver; const moduleMaps = new Map(); @@ -344,7 +341,7 @@ module.exports = { } }, - 'Program:exit': function () { + 'Program:exit'() { for (const map of moduleMaps.values()) { checkImports(map.imported, context); checkImports(map.nsImported, context); diff --git a/src/rules/no-dynamic-require.js b/src/rules/no-dynamic-require.js index f334adec6..f8b369a70 100644 --- a/src/rules/no-dynamic-require.js +++ b/src/rules/no-dynamic-require.js @@ -1,22 +1,22 @@ import docsUrl from '../docsUrl'; function isRequire(node) { - return node && - node.callee && - node.callee.type === 'Identifier' && - node.callee.name === 'require' && - node.arguments.length >= 1; + return node + && node.callee + && node.callee.type === 'Identifier' + && node.callee.name === 'require' + && node.arguments.length >= 1; } function isDynamicImport(node) { - return node && - node.callee && - node.callee.type === 'Import'; + return node + && node.callee + && node.callee.type === 'Import'; } function isStaticValue(arg) { - return arg.type === 'Literal' || - (arg.type === 'TemplateLiteral' && arg.expressions.length === 0); + return arg.type === 'Literal' + || arg.type === 'TemplateLiteral' && arg.expressions.length === 0; } const dynamicImportErrorMessage = 'Calls to import() should use string literals'; diff --git a/src/rules/no-empty-named-blocks.js b/src/rules/no-empty-named-blocks.js index 25567b08f..3ec1501b8 100644 --- a/src/rules/no-empty-named-blocks.js +++ b/src/rules/no-empty-named-blocks.js @@ -8,7 +8,7 @@ function getEmptyBlockRange(tokens, index) { const end = nextToken.range[1]; // Remove block tokens and the previous comma - if (prevToken.value === ','|| prevToken.value === 'type' || prevToken.value === 'typeof') { + if (prevToken.value === ',' || prevToken.value === 'type' || prevToken.value === 'typeof') { start = prevToken.range[0]; } @@ -33,15 +33,13 @@ module.exports = { return { ImportDeclaration(node) { - if (!node.specifiers.some(x => x.type === 'ImportSpecifier')) { + if (!node.specifiers.some((x) => x.type === 'ImportSpecifier')) { importsWithoutNameds.push(node); } }, - 'Program:exit': function (program) { - const importsTokens = importsWithoutNameds.map((node) => { - return [node, program.tokens.filter(x => x.range[0] >= node.range[0] && x.range[1] <= node.range[1])]; - }); + 'Program:exit'(program) { + const importsTokens = importsWithoutNameds.map((node) => [node, program.tokens.filter((x) => x.range[0] >= node.range[0] && x.range[1] <= node.range[1])]); importsTokens.forEach(([node, tokens]) => { tokens.forEach((token) => { @@ -49,12 +47,11 @@ module.exports = { const nextToken = program.tokens[idx + 1]; if (nextToken && token.value === '{' && nextToken.value === '}') { - const hasOtherIdentifiers = tokens.some((token) => ( - token.type === 'Identifier' + const hasOtherIdentifiers = tokens.some((token) => token.type === 'Identifier' && token.value !== 'from' && token.value !== 'type' - && token.value !== 'typeof' - )); + && token.value !== 'typeof', + ); // If it has no other identifiers it's the only thing in the import, so we can either remove the import // completely or transform it in a side-effects only import @@ -76,8 +73,8 @@ module.exports = { // Remove the empty block and the 'from' token, leaving the import only for its side // effects, e.g. `import 'mod'` const sourceCode = context.getSourceCode(); - const fromToken = program.tokens.find(t => t.value === 'from'); - const importToken = program.tokens.find(t => t.value === 'import'); + const fromToken = program.tokens.find((t) => t.value === 'from'); + const importToken = program.tokens.find((t) => t.value === 'import'); const hasSpaceAfterFrom = sourceCode.isSpaceBetween(fromToken, sourceCode.getTokenAfter(fromToken)); const hasSpaceAfterImport = sourceCode.isSpaceBetween(importToken, sourceCode.getTokenAfter(fromToken)); diff --git a/src/rules/no-extraneous-dependencies.js b/src/rules/no-extraneous-dependencies.js index a149ca659..0408e0866 100644 --- a/src/rules/no-extraneous-dependencies.js +++ b/src/rules/no-extraneous-dependencies.js @@ -64,18 +64,18 @@ function getDependencies(context, packageDir) { if (!Array.isArray(packageDir)) { paths = [path.resolve(packageDir)]; } else { - paths = packageDir.map(dir => path.resolve(dir)); + paths = packageDir.map((dir) => path.resolve(dir)); } } if (paths.length > 0) { // use rule config to find package.json - paths.forEach(dir => { + paths.forEach((dir) => { const packageJsonPath = path.join(dir, 'package.json'); const _packageContent = getPackageDepFields(packageJsonPath, true); - Object.keys(packageContent).forEach(depsKey => - Object.assign(packageContent[depsKey], _packageContent[depsKey]), - ); + Object.keys(packageContent).forEach((depsKey) => { + Object.assign(packageContent[depsKey], _packageContent[depsKey]); + }); }); } else { const packageJsonPath = pkgUp({ @@ -110,7 +110,7 @@ function getDependencies(context, packageDir) { } if (e.name === 'JSONError' || e instanceof SyntaxError) { context.report({ - message: 'The package.json file could not be parsed: ' + e.message, + message: `The package.json file could not be parsed: ${e.message}`, loc: { line: 0, column: 0 }, }); } @@ -120,8 +120,7 @@ function getDependencies(context, packageDir) { } function missingErrorMessage(packageName) { - return `'${packageName}' should be listed in the project's dependencies. ` + - `Run 'npm i -S ${packageName}' to add it`; + return `'${packageName}' should be listed in the project's dependencies. Run 'npm i -S ${packageName}' to add it`; } function devDepErrorMessage(packageName) { @@ -129,8 +128,7 @@ function devDepErrorMessage(packageName) { } function optDepErrorMessage(packageName) { - return `'${packageName}' should be listed in the project's dependencies, ` + - `not optionalDependencies.`; + return `'${packageName}' should be listed in the project's dependencies, not optionalDependencies.`; } function getModuleOriginalName(name) { @@ -162,27 +160,24 @@ function checkDependencyDeclaration(deps, packageName, declarationStatus) { } }); - return packageHierarchy.reduce((result, ancestorName) => { - return { - isInDeps: result.isInDeps || deps.dependencies[ancestorName] !== undefined, - isInDevDeps: result.isInDevDeps || deps.devDependencies[ancestorName] !== undefined, - isInOptDeps: result.isInOptDeps || deps.optionalDependencies[ancestorName] !== undefined, - isInPeerDeps: result.isInPeerDeps || deps.peerDependencies[ancestorName] !== undefined, - isInBundledDeps: + return packageHierarchy.reduce((result, ancestorName) => ({ + isInDeps: result.isInDeps || deps.dependencies[ancestorName] !== undefined, + isInDevDeps: result.isInDevDeps || deps.devDependencies[ancestorName] !== undefined, + isInOptDeps: result.isInOptDeps || deps.optionalDependencies[ancestorName] !== undefined, + isInPeerDeps: result.isInPeerDeps || deps.peerDependencies[ancestorName] !== undefined, + isInBundledDeps: result.isInBundledDeps || deps.bundledDependencies.indexOf(ancestorName) !== -1, - }; - }, newDeclarationStatus); + }), newDeclarationStatus); } function reportIfMissing(context, deps, depsOptions, node, name) { // Do not report when importing types unless option is enabled if ( - !depsOptions.verifyTypeImports && - (node.importKind === 'type' || node.importKind === 'typeof' || - ( - Array.isArray(node.specifiers) && - node.specifiers.length && - node.specifiers.every((specifier) => specifier.importKind === 'type' || specifier.importKind === 'typeof')) + !depsOptions.verifyTypeImports + && ( + node.importKind === 'type' + || node.importKind === 'typeof' + || Array.isArray(node.specifiers) && node.specifiers.length && node.specifiers.every((specifier) => specifier.importKind === 'type' || specifier.importKind === 'typeof') ) ) { return; @@ -204,11 +199,11 @@ function reportIfMissing(context, deps, depsOptions, node, name) { let declarationStatus = checkDependencyDeclaration(deps, importPackageName); if ( - declarationStatus.isInDeps || - (depsOptions.allowDevDeps && declarationStatus.isInDevDeps) || - (depsOptions.allowPeerDeps && declarationStatus.isInPeerDeps) || - (depsOptions.allowOptDeps && declarationStatus.isInOptDeps) || - (depsOptions.allowBundledDeps && declarationStatus.isInBundledDeps) + declarationStatus.isInDeps + || depsOptions.allowDevDeps && declarationStatus.isInDevDeps + || depsOptions.allowPeerDeps && declarationStatus.isInPeerDeps + || depsOptions.allowOptDeps && declarationStatus.isInOptDeps + || depsOptions.allowBundledDeps && declarationStatus.isInBundledDeps ) { return; } @@ -220,11 +215,11 @@ function reportIfMissing(context, deps, depsOptions, node, name) { declarationStatus = checkDependencyDeclaration(deps, realPackageName, declarationStatus); if ( - declarationStatus.isInDeps || - (depsOptions.allowDevDeps && declarationStatus.isInDevDeps) || - (depsOptions.allowPeerDeps && declarationStatus.isInPeerDeps) || - (depsOptions.allowOptDeps && declarationStatus.isInOptDeps) || - (depsOptions.allowBundledDeps && declarationStatus.isInBundledDeps) + declarationStatus.isInDeps + || depsOptions.allowDevDeps && declarationStatus.isInDevDeps + || depsOptions.allowPeerDeps && declarationStatus.isInPeerDeps + || depsOptions.allowOptDeps && declarationStatus.isInOptDeps + || depsOptions.allowBundledDeps && declarationStatus.isInBundledDeps ) { return; } @@ -249,10 +244,9 @@ function testConfig(config, filename) { return config; } // Array of globs. - return config.some(c => ( - minimatch(filename, c) || - minimatch(filename, path.join(process.cwd(), c)) - )); + return config.some((c) => minimatch(filename, c) + || minimatch(filename, path.join(process.cwd(), c)), + ); } module.exports = { @@ -266,17 +260,17 @@ module.exports = { schema: [ { - 'type': 'object', - 'properties': { - 'devDependencies': { 'type': ['boolean', 'array'] }, - 'optionalDependencies': { 'type': ['boolean', 'array'] }, - 'peerDependencies': { 'type': ['boolean', 'array'] }, - 'bundledDependencies': { 'type': ['boolean', 'array'] }, - 'packageDir': { 'type': ['string', 'array'] }, - 'includeInternal': { 'type': ['boolean'] }, - 'includeTypes': { 'type': ['boolean'] }, + type: 'object', + properties: { + devDependencies: { type: ['boolean', 'array'] }, + optionalDependencies: { type: ['boolean', 'array'] }, + peerDependencies: { type: ['boolean', 'array'] }, + bundledDependencies: { type: ['boolean', 'array'] }, + packageDir: { type: ['string', 'array'] }, + includeInternal: { type: ['boolean'] }, + includeTypes: { type: ['boolean'] }, }, - 'additionalProperties': false, + additionalProperties: false, }, ], }, @@ -300,7 +294,7 @@ module.exports = { }, { commonjs: true }); }, - 'Program:exit': () => { + 'Program:exit'() { depFieldCache.clear(); }, }; diff --git a/src/rules/no-import-module-exports.js b/src/rules/no-import-module-exports.js index 5a91acd07..bc4605c39 100644 --- a/src/rules/no-import-module-exports.js +++ b/src/rules/no-import-module-exports.js @@ -16,12 +16,12 @@ function getEntryPoint(context) { function findScope(context, identifier) { const { scopeManager } = context.getSourceCode(); - return scopeManager && scopeManager.scopes.slice().reverse().find((scope) => scope.variables.some(variable => variable.identifiers.some((node) => node.name === identifier))); + return scopeManager && scopeManager.scopes.slice().reverse().find((scope) => scope.variables.some((variable) => variable.identifiers.some((node) => node.name === identifier))); } function findDefinition(objectScope, identifier) { - const variable = objectScope.variables.find(variable => variable.name === identifier); - return variable.defs.find(def => def.name.name === identifier); + const variable = objectScope.variables.find((variable) => variable.name === identifier); + return variable.defs.find((def) => def.name.name === identifier); } module.exports = { @@ -35,11 +35,11 @@ module.exports = { fixable: 'code', schema: [ { - 'type': 'object', - 'properties': { - 'exceptions': { 'type': 'array' }, + type: 'object', + properties: { + exceptions: { type: 'array' }, }, - 'additionalProperties': false, + additionalProperties: false, }, ], }, @@ -58,14 +58,13 @@ module.exports = { const variableDefinition = objectScope && findDefinition(objectScope, node.object.name); const isImportBinding = variableDefinition && variableDefinition.type === 'ImportBinding'; const hasCJSExportReference = hasKeywords && (!objectScope || objectScope.type === 'module'); - const isException = !!options.exceptions && options.exceptions.some(glob => minimatch(fileName, glob)); + const isException = !!options.exceptions && options.exceptions.some((glob) => minimatch(fileName, glob)); if (isIdentifier && hasCJSExportReference && !isEntryPoint && !isException && !isImportBinding) { - importDeclarations.forEach(importDeclaration => { + importDeclarations.forEach((importDeclaration) => { context.report({ node: importDeclaration, - message: `Cannot use import declarations in modules that export using ` + - `CommonJS (module.exports = 'foo' or exports.bar = 'hi')`, + message: `Cannot use import declarations in modules that export using CommonJS (module.exports = 'foo' or exports.bar = 'hi')`, }); }); alreadyReported = true; diff --git a/src/rules/no-internal-modules.js b/src/rules/no-internal-modules.js index 2416c1ce3..687193f5c 100644 --- a/src/rules/no-internal-modules.js +++ b/src/rules/no-internal-modules.js @@ -48,8 +48,8 @@ module.exports = { create: function noReachingInside(context) { const options = context.options[0] || {}; - const allowRegexps = (options.allow || []).map(p => minimatch.makeRe(p)); - const forbidRegexps = (options.forbid || []).map(p => minimatch.makeRe(p)); + const allowRegexps = (options.allow || []).map((p) => minimatch.makeRe(p)); + const forbidRegexps = (options.forbid || []).map((p) => minimatch.makeRe(p)); // minimatch patterns are expected to use / path separators, like import // statements, so normalize paths to use the same @@ -73,29 +73,29 @@ module.exports = { // test if reaching to this destination is allowed function reachingAllowed(importPath) { - return allowRegexps.some(re => re.test(importPath)); + return allowRegexps.some((re) => re.test(importPath)); } // test if reaching to this destination is forbidden function reachingForbidden(importPath) { - return forbidRegexps.some(re => re.test(importPath)); + return forbidRegexps.some((re) => re.test(importPath)); } function isAllowViolation(importPath) { const steps = toSteps(importPath); - const nonScopeSteps = steps.filter(step => step.indexOf('@') !== 0); - if (nonScopeSteps.length <= 1) return false; + const nonScopeSteps = steps.filter((step) => step.indexOf('@') !== 0); + if (nonScopeSteps.length <= 1) { return false; } // before trying to resolve, see if the raw import (with relative // segments resolved) matches an allowed pattern const justSteps = steps.join('/'); - if (reachingAllowed(justSteps) || reachingAllowed(`/${justSteps}`)) return false; + if (reachingAllowed(justSteps) || reachingAllowed(`/${justSteps}`)) { return false; } // if the import statement doesn't match directly, try to match the // resolved path if the import is resolvable const resolved = resolve(importPath, context); - if (!resolved || reachingAllowed(normalizeSep(resolved))) return false; + if (!resolved || reachingAllowed(normalizeSep(resolved))) { return false; } // this import was not allowed by the allowed paths, and reaches // so it is a violation @@ -109,12 +109,12 @@ module.exports = { // segments resolved) matches a forbidden pattern const justSteps = steps.join('/'); - if (reachingForbidden(justSteps) || reachingForbidden(`/${justSteps}`)) return true; + if (reachingForbidden(justSteps) || reachingForbidden(`/${justSteps}`)) { return true; } // if the import statement doesn't match directly, try to match the // resolved path if the import is resolvable const resolved = resolve(importPath, context); - if (resolved && reachingForbidden(normalizeSep(resolved))) return true; + if (resolved && reachingForbidden(normalizeSep(resolved))) { return true; } // this import was not forbidden by the forbidden paths so it is not a violation return false; @@ -125,8 +125,9 @@ module.exports = { function checkImportForReaching(importPath, node) { const potentialViolationTypes = ['parent', 'index', 'sibling', 'external', 'internal']; - if (potentialViolationTypes.indexOf(importType(importPath, context)) !== -1 && - isReachViolation(importPath) + if ( + potentialViolationTypes.indexOf(importType(importPath, context)) !== -1 + && isReachViolation(importPath) ) { context.report({ node, @@ -135,8 +136,11 @@ module.exports = { } } - return moduleVisitor((source) => { - checkImportForReaching(source.value, source); - }, { commonjs: true }); + return moduleVisitor( + (source) => { + checkImportForReaching(source.value, source); + }, + { commonjs: true }, + ); }, }; diff --git a/src/rules/no-mutable-exports.js b/src/rules/no-mutable-exports.js index 75a321b62..433d64e16 100644 --- a/src/rules/no-mutable-exports.js +++ b/src/rules/no-mutable-exports.js @@ -52,8 +52,8 @@ module.exports = { } return { - 'ExportDefaultDeclaration': handleExportDefault, - 'ExportNamedDeclaration': handleExportNamed, + ExportDefaultDeclaration: handleExportDefault, + ExportNamedDeclaration: handleExportNamed, }; }, }; diff --git a/src/rules/no-named-as-default-member.js b/src/rules/no-named-as-default-member.js index 0fb092724..e00a4cbc8 100644 --- a/src/rules/no-named-as-default-member.js +++ b/src/rules/no-named-as-default-member.js @@ -24,81 +24,68 @@ module.exports = { }, create(context) { - const fileImports = new Map(); const allPropertyLookups = new Map(); - function handleImportDefault(node) { - const declaration = importDeclaration(context); - const exportMap = Exports.get(declaration.source.value, context); - if (exportMap == null) return; - - if (exportMap.errors.length) { - exportMap.reportErrors(context, declaration); - return; - } - - fileImports.set(node.local.name, { - exportMap, - sourcePath: declaration.source.value, - }); - } - function storePropertyLookup(objectName, propName, node) { const lookups = allPropertyLookups.get(objectName) || []; lookups.push({ node, propName }); allPropertyLookups.set(objectName, lookups); } - function handlePropLookup(node) { - const objectName = node.object.name; - const propName = node.property.name; - storePropertyLookup(objectName, propName, node); - } + return { + ImportDefaultSpecifier(node) { + const declaration = importDeclaration(context); + const exportMap = Exports.get(declaration.source.value, context); + if (exportMap == null) { return; } - function handleDestructuringAssignment(node) { - const isDestructure = ( - node.id.type === 'ObjectPattern' && - node.init != null && - node.init.type === 'Identifier' - ); - if (!isDestructure) return; + if (exportMap.errors.length) { + exportMap.reportErrors(context, declaration); + return; + } - const objectName = node.init.name; - for (const { key } of node.id.properties) { - if (key == null) continue; // true for rest properties - storePropertyLookup(objectName, key.name, key); - } - } + fileImports.set(node.local.name, { + exportMap, + sourcePath: declaration.source.value, + }); + }, - function handleProgramExit() { - allPropertyLookups.forEach((lookups, objectName) => { - const fileImport = fileImports.get(objectName); - if (fileImport == null) return; + MemberExpression(node) { + const objectName = node.object.name; + const propName = node.property.name; + storePropertyLookup(objectName, propName, node); + }, - for (const { propName, node } of lookups) { - // the default import can have a "default" property - if (propName === 'default') continue; - if (!fileImport.exportMap.namespace.has(propName)) continue; + VariableDeclarator(node) { + const isDestructure = node.id.type === 'ObjectPattern' + && node.init != null + && node.init.type === 'Identifier'; + if (!isDestructure) { return; } - context.report({ - node, - message: ( - `Caution: \`${objectName}\` also has a named export ` + - `\`${propName}\`. Check if you meant to write ` + - `\`import {${propName}} from '${fileImport.sourcePath}'\` ` + - 'instead.' - ), - }); + const objectName = node.init.name; + for (const { key } of node.id.properties) { + if (key == null) { continue; } // true for rest properties + storePropertyLookup(objectName, key.name, key); } - }); - } + }, - return { - 'ImportDefaultSpecifier': handleImportDefault, - 'MemberExpression': handlePropLookup, - 'VariableDeclarator': handleDestructuringAssignment, - 'Program:exit': handleProgramExit, + 'Program:exit'() { + allPropertyLookups.forEach((lookups, objectName) => { + const fileImport = fileImports.get(objectName); + if (fileImport == null) { return; } + + for (const { propName, node } of lookups) { + // the default import can have a "default" property + if (propName === 'default') { continue; } + if (!fileImport.exportMap.namespace.has(propName)) { continue; } + + context.report({ + node, + message: `Caution: \`${objectName}\` also has a named export \`${propName}\`. Check if you meant to write \`import {${propName}} from '${fileImport.sourcePath}'\` instead.`, + }); + } + }); + }, }; }, }; diff --git a/src/rules/no-named-as-default.js b/src/rules/no-named-as-default.js index c3a35ff64..40b1e175b 100644 --- a/src/rules/no-named-as-default.js +++ b/src/rules/no-named-as-default.js @@ -16,30 +16,30 @@ module.exports = { create(context) { function checkDefault(nameKey, defaultSpecifier) { // #566: default is a valid specifier - if (defaultSpecifier[nameKey].name === 'default') return; + if (defaultSpecifier[nameKey].name === 'default') { return; } const declaration = importDeclaration(context); const imports = Exports.get(declaration.source.value, context); - if (imports == null) return; + if (imports == null) { return; } if (imports.errors.length) { imports.reportErrors(context, declaration); return; } - if (imports.has('default') && - imports.has(defaultSpecifier[nameKey].name)) { + if (imports.has('default') && imports.has(defaultSpecifier[nameKey].name)) { - context.report(defaultSpecifier, - 'Using exported name \'' + defaultSpecifier[nameKey].name + - '\' as identifier for default export.'); + context.report( + defaultSpecifier, + `Using exported name '${defaultSpecifier[nameKey].name}' as identifier for default export.`, + ); } } return { - 'ImportDefaultSpecifier': checkDefault.bind(null, 'local'), - 'ExportDefaultSpecifier': checkDefault.bind(null, 'exported'), + ImportDefaultSpecifier: checkDefault.bind(null, 'local'), + ExportDefaultSpecifier: checkDefault.bind(null, 'exported'), }; }, }; diff --git a/src/rules/no-named-default.js b/src/rules/no-named-default.js index 8745ce389..1ed0e31df 100644 --- a/src/rules/no-named-default.js +++ b/src/rules/no-named-default.js @@ -13,7 +13,7 @@ module.exports = { create(context) { return { - 'ImportDeclaration': function (node) { + ImportDeclaration(node) { node.specifiers.forEach(function (im) { if (im.importKind === 'type' || im.importKind === 'typeof') { return; diff --git a/src/rules/no-named-export.js b/src/rules/no-named-export.js index b0722f359..efaf9dc4c 100644 --- a/src/rules/no-named-export.js +++ b/src/rules/no-named-export.js @@ -29,7 +29,7 @@ module.exports = { return context.report({ node, message }); } - const someNamed = node.specifiers.some(specifier => (specifier.exported.name || specifier.exported.value) !== 'default'); + const someNamed = node.specifiers.some((specifier) => (specifier.exported.name || specifier.exported.value) !== 'default'); if (someNamed) { context.report({ node, message }); } diff --git a/src/rules/no-namespace.js b/src/rules/no-namespace.js index a078137e6..d3e591876 100644 --- a/src/rules/no-namespace.js +++ b/src/rules/no-namespace.js @@ -10,7 +10,6 @@ import docsUrl from '../docsUrl'; // Rule Definition //------------------------------------------------------------------------------ - module.exports = { meta: { type: 'suggestion', @@ -40,20 +39,20 @@ module.exports = { return { ImportNamespaceSpecifier(node) { - if (ignoreGlobs && ignoreGlobs.find(glob => minimatch(node.parent.source.value, glob, { matchBase: true }))) { + if (ignoreGlobs && ignoreGlobs.find((glob) => minimatch(node.parent.source.value, glob, { matchBase: true }))) { return; } const scopeVariables = context.getScope().variables; const namespaceVariable = scopeVariables.find((variable) => variable.defs[0].node === node); const namespaceReferences = namespaceVariable.references; - const namespaceIdentifiers = namespaceReferences.map(reference => reference.identifier); + const namespaceIdentifiers = namespaceReferences.map((reference) => reference.identifier); const canFix = namespaceIdentifiers.length > 0 && !usesNamespaceAsObject(namespaceIdentifiers); context.report({ node, message: `Unexpected namespace import.`, - fix: canFix && (fixer => { + fix: canFix && ((fixer) => { const scopeManager = context.getSourceCode().scopeManager; const fixes = []; @@ -82,11 +81,10 @@ module.exports = { ); // Replace the ImportNamespaceSpecifier with a list of ImportSpecifiers - const namedImportSpecifiers = importNames.map((importName) => ( - importName === importLocalNames[importName] - ? importName - : `${importName} as ${importLocalNames[importName]}` - )); + const namedImportSpecifiers = importNames.map((importName) => importName === importLocalNames[importName] + ? importName + : `${importName} as ${importLocalNames[importName]}`, + ); fixes.push(fixer.replaceText(node, `{ ${namedImportSpecifiers.join(', ')} }`)); // Pass 2: Replace references to the namespace with references to the named imports @@ -116,8 +114,9 @@ function usesNamespaceAsObject(namespaceIdentifiers) { // `namespace.x` or `namespace['x']` return ( - parent && parent.type === 'MemberExpression' && - (parent.property.type === 'Identifier' || parent.property.type === 'Literal') + parent + && parent.type === 'MemberExpression' + && (parent.property.type === 'Identifier' || parent.property.type === 'Literal') ); }); } @@ -144,7 +143,7 @@ function getVariableNamesInScope(scopeManager, node) { currentNode = currentNode.parent; scope = scopeManager.acquire(currentNode, true); } - return new Set(scope.variables.concat(scope.upper.variables).map(variable => variable.name)); + return new Set(scope.variables.concat(scope.upper.variables).map((variable) => variable.name)); } /** diff --git a/src/rules/no-nodejs-modules.js b/src/rules/no-nodejs-modules.js index a87bff796..82594bb60 100644 --- a/src/rules/no-nodejs-modules.js +++ b/src/rules/no-nodejs-modules.js @@ -4,7 +4,7 @@ import docsUrl from '../docsUrl'; function reportIfMissing(context, node, allowed, name) { if (allowed.indexOf(name) === -1 && importType(name, context) === 'builtin') { - context.report(node, 'Do not import Node.js builtin module "' + name + '"'); + context.report(node, `Do not import Node.js builtin module "${name}"`); } } diff --git a/src/rules/no-relative-packages.js b/src/rules/no-relative-packages.js index 6b0a62767..1d215519f 100644 --- a/src/rules/no-relative-packages.js +++ b/src/rules/no-relative-packages.js @@ -47,7 +47,7 @@ function checkImportForRelativePackage(context, importPath, node) { context.report({ node, message: `Relative import from another package is not allowed. Use \`${properImport}\` instead of \`${importPath}\``, - fix: fixer => fixer.replaceText(node, JSON.stringify(toPosixPath(properImport))) + fix: (fixer) => fixer.replaceText(node, JSON.stringify(toPosixPath(properImport))) , }); } diff --git a/src/rules/no-relative-parent-imports.js b/src/rules/no-relative-parent-imports.js index fd8dcb302..decd2ef7d 100644 --- a/src/rules/no-relative-parent-imports.js +++ b/src/rules/no-relative-parent-imports.js @@ -18,7 +18,7 @@ module.exports = { create: function noRelativePackages(context) { const myPath = context.getPhysicalFilename ? context.getPhysicalFilename() : context.getFilename(); - if (myPath === '') return {}; // can't check a non-file + if (myPath === '') { return {}; } // can't check a non-file function checkSourceValue(sourceNode) { const depPath = sourceNode.value; @@ -38,10 +38,7 @@ module.exports = { if (importType(relDepPath, context) === 'parent') { context.report({ node: sourceNode, - message: 'Relative imports from parent directories are not allowed. ' + - `Please either pass what you're importing through at runtime ` + - `(dependency injection), move \`${basename(myPath)}\` to same ` + - `directory as \`${depPath}\` or consider making \`${depPath}\` a package.`, + message: `Relative imports from parent directories are not allowed. Please either pass what you're importing through at runtime (dependency injection), move \`${basename(myPath)}\` to same directory as \`${depPath}\` or consider making \`${depPath}\` a package.`, }); } } diff --git a/src/rules/no-restricted-paths.js b/src/rules/no-restricted-paths.js index 229311959..bce9fd1a0 100644 --- a/src/rules/no-restricted-paths.js +++ b/src/rules/no-restricted-paths.js @@ -77,11 +77,9 @@ module.exports = { const restrictedPaths = options.zones || []; const basePath = options.basePath || process.cwd(); const currentFilename = context.getPhysicalFilename ? context.getPhysicalFilename() : context.getFilename(); - const matchingZones = restrictedPaths.filter((zone) => { - return [].concat(zone.target) - .map(target => path.resolve(basePath, target)) - .some(targetPath => isMatchingTargetPath(currentFilename, targetPath)); - }); + const matchingZones = restrictedPaths.filter((zone) => [].concat(zone.target) + .map((target) => path.resolve(basePath, target)) + .some((targetPath) => isMatchingTargetPath(currentFilename, targetPath))); function isMatchingTargetPath(filename, targetPath) { if (isGlob(targetPath)) { @@ -180,7 +178,7 @@ module.exports = { } function reportInvalidExceptions(validators, node) { - validators.forEach(validator => validator.reportInvalidException(node)); + validators.forEach((validator) => validator.reportInvalidException(node)); } function reportImportsInRestrictedZone(validators, node, importPath, customMessage) { @@ -203,7 +201,7 @@ module.exports = { const isGlobPattern = areGlobPatterns.every((isGlob) => isGlob); - return allZoneFrom.map(singleZoneFrom => { + return allZoneFrom.map((singleZoneFrom) => { const absoluteFrom = path.resolve(basePath, singleZoneFrom); if (isGlobPattern) { @@ -227,14 +225,14 @@ module.exports = { validators[index] = makePathValidators(zone.from, zone.except); } - const applicableValidatorsForImportPath = validators[index].filter(validator => validator.isPathRestricted(absoluteImportPath)); + const applicableValidatorsForImportPath = validators[index].filter((validator) => validator.isPathRestricted(absoluteImportPath)); - const validatorsWithInvalidExceptions = applicableValidatorsForImportPath.filter(validator => !validator.hasValidExceptions); + const validatorsWithInvalidExceptions = applicableValidatorsForImportPath.filter((validator) => !validator.hasValidExceptions); reportInvalidExceptions(validatorsWithInvalidExceptions, node); const applicableValidatorsForImportPathExcludingExceptions = applicableValidatorsForImportPath - .filter(validator => validator.hasValidExceptions) - .filter(validator => !validator.isPathException(absoluteImportPath)); + .filter((validator) => validator.hasValidExceptions) + .filter((validator) => !validator.isPathException(absoluteImportPath)); reportImportsInRestrictedZone(applicableValidatorsForImportPathExcludingExceptions, node, importPath, zone.message); }); } diff --git a/src/rules/no-unassigned-import.js b/src/rules/no-unassigned-import.js index b79014192..0af9f2e9f 100644 --- a/src/rules/no-unassigned-import.js +++ b/src/rules/no-unassigned-import.js @@ -24,16 +24,15 @@ function testIsAllow(globs, filename, source) { filePath = path.resolve(path.dirname(filename), source); // get source absolute path } - return globs.find(glob => ( - minimatch(filePath, glob) || - minimatch(filePath, path.join(process.cwd(), glob)) - )) !== undefined; + return globs.find((glob) => minimatch(filePath, glob) + || minimatch(filePath, path.join(process.cwd(), glob)), + ) !== undefined; } function create(context) { const options = context.options[0] || {}; const filename = context.getPhysicalFilename ? context.getPhysicalFilename() : context.getFilename(); - const isAllow = source => testIsAllow(options.allow, filename, source); + const isAllow = (source) => testIsAllow(options.allow, filename, source); return { ImportDeclaration(node) { @@ -42,9 +41,11 @@ function create(context) { } }, ExpressionStatement(node) { - if (node.expression.type === 'CallExpression' && - isStaticRequire(node.expression) && - !isAllow(node.expression.arguments[0].value)) { + if ( + node.expression.type === 'CallExpression' + && isStaticRequire(node.expression) + && !isAllow(node.expression.arguments[0].value) + ) { report(context, node.expression); } }, @@ -62,19 +63,19 @@ module.exports = { }, schema: [ { - 'type': 'object', - 'properties': { - 'devDependencies': { 'type': ['boolean', 'array'] }, - 'optionalDependencies': { 'type': ['boolean', 'array'] }, - 'peerDependencies': { 'type': ['boolean', 'array'] }, - 'allow': { - 'type': 'array', - 'items': { - 'type': 'string', + type: 'object', + properties: { + devDependencies: { type: ['boolean', 'array'] }, + optionalDependencies: { type: ['boolean', 'array'] }, + peerDependencies: { type: ['boolean', 'array'] }, + allow: { + type: 'array', + items: { + type: 'string', }, }, }, - 'additionalProperties': false, + additionalProperties: false, }, ], }, diff --git a/src/rules/no-unused-modules.js b/src/rules/no-unused-modules.js index bd8c524ab..4b09128a1 100644 --- a/src/rules/no-unused-modules.js +++ b/src/rules/no-unused-modules.js @@ -40,11 +40,12 @@ try { const { listFilesToProcess: originalListFilesToProcess } = require('eslint/lib/util/glob-util'); listFilesToProcess = function (src, extensions) { - const patterns = src.reduce((carry, pattern) => { - return carry.concat(extensions.map((extension) => { - return /\*\*|\*\./.test(pattern) ? pattern : `${pattern}/**/*${extension}`; - })); - }, src.slice()); + const patterns = src.reduce( + (carry, pattern) => carry.concat( + extensions.map((extension) => (/\*\*|\*\./).test(pattern) ? pattern : `${pattern}/**/*${extension}`), + ), + src, + ); return originalListFilesToProcess(patterns); }; @@ -84,11 +85,11 @@ const DEFAULT = 'default'; function forEachDeclarationIdentifier(declaration, cb) { if (declaration) { if ( - declaration.type === FUNCTION_DECLARATION || - declaration.type === CLASS_DECLARATION || - declaration.type === TS_INTERFACE_DECLARATION || - declaration.type === TS_TYPE_ALIAS_DECLARATION || - declaration.type === TS_ENUM_DECLARATION + declaration.type === FUNCTION_DECLARATION + || declaration.type === CLASS_DECLARATION + || declaration.type === TS_INTERFACE_DECLARATION + || declaration.type === TS_TYPE_ALIAS_DECLARATION + || declaration.type === TS_ENUM_DECLARATION ) { cb(declaration.id.name); } else if (declaration.type === VARIABLE_DECLARATION) { @@ -160,9 +161,7 @@ const visitorKeyMap = new Map(); const ignoredFiles = new Set(); const filesOutsideSrc = new Set(); -const isNodeModule = path => { - return /\/(node_modules)\//.test(path); -}; +const isNodeModule = (path) => (/\/(node_modules)\//).test(path); /** * read all files matching the patterns in src and ignoreExports @@ -191,7 +190,7 @@ const resolveFiles = (src, ignoreExports, context) => { */ const prepareImportsAndExports = (srcFiles, context) => { const exportAll = new Map(); - srcFiles.forEach(file => { + srcFiles.forEach((file) => { const exports = new Map(); const imports = new Map(); const currentExports = Exports.get(file, context); @@ -207,7 +206,7 @@ const prepareImportsAndExports = (srcFiles, context) => { visitorKeyMap.set(file, visitorKeys); // dependencies === export * from const currentExportAll = new Set(); - dependencies.forEach(getDependency => { + dependencies.forEach((getDependency) => { const dependency = getDependency(); if (dependency === null) { return; @@ -247,9 +246,11 @@ const prepareImportsAndExports = (srcFiles, context) => { return; } const localImport = imports.get(key) || new Set(); - value.declarations.forEach(({ importedSpecifiers }) => - importedSpecifiers.forEach(specifier => localImport.add(specifier)), - ); + value.declarations.forEach(({ importedSpecifiers }) => { + importedSpecifiers.forEach((specifier) => { + localImport.add(specifier); + }); + }); imports.set(key, localImport); }); importList.set(file, imports); @@ -271,7 +272,7 @@ const prepareImportsAndExports = (srcFiles, context) => { exportList.set(file, exports); }); exportAll.forEach((value, key) => { - value.forEach(val => { + value.forEach((val) => { const currentExports = exportList.get(val); if (currentExports) { const currentExport = currentExports.get(EXPORT_ALL_DECLARATION); @@ -290,7 +291,7 @@ const determineUsage = () => { listValue.forEach((value, key) => { const exports = exportList.get(key); if (typeof exports !== 'undefined') { - value.forEach(currentImport => { + value.forEach((currentImport) => { let specifier; if (currentImport === IMPORT_NAMESPACE_SPECIFIER) { specifier = IMPORT_NAMESPACE_SPECIFIER; @@ -313,7 +314,7 @@ const determineUsage = () => { }); }; -const getSrc = src => { +const getSrc = (src) => { if (src) { return src; } @@ -347,33 +348,31 @@ const doPreparation = (src, ignoreExports, context) => { lastPrepareKey = prepareKey; }; -const newNamespaceImportExists = specifiers => - specifiers.some(({ type }) => type === IMPORT_NAMESPACE_SPECIFIER); +const newNamespaceImportExists = (specifiers) => specifiers.some(({ type }) => type === IMPORT_NAMESPACE_SPECIFIER); -const newDefaultImportExists = specifiers => - specifiers.some(({ type }) => type === IMPORT_DEFAULT_SPECIFIER); +const newDefaultImportExists = (specifiers) => specifiers.some(({ type }) => type === IMPORT_DEFAULT_SPECIFIER); -const fileIsInPkg = file => { +const fileIsInPkg = (file) => { const { path, pkg } = readPkgUp({ cwd: file }); const basePath = dirname(path); - const checkPkgFieldString = pkgField => { + const checkPkgFieldString = (pkgField) => { if (join(basePath, pkgField) === file) { return true; } }; - const checkPkgFieldObject = pkgField => { + const checkPkgFieldObject = (pkgField) => { const pkgFieldFiles = values(pkgField) .filter((value) => typeof value !== 'boolean') - .map(value => join(basePath, value)); + .map((value) => join(basePath, value)); if (includes(pkgFieldFiles, file)) { return true; } }; - const checkPkgField = pkgField => { + const checkPkgField = (pkgField) => { if (typeof pkgField === 'string') { return checkPkgFieldString(pkgField); } @@ -452,7 +451,7 @@ module.exports = { missingExports: { enum: [false] }, }, }, - anyOf:[{ + anyOf: [{ not: { properties: { unusedExports: { enum: [true] }, @@ -480,7 +479,7 @@ module.exports = { }], }, - create: context => { + create(context) { const { src, ignoreExports = [], @@ -494,7 +493,7 @@ module.exports = { const file = context.getPhysicalFilename ? context.getPhysicalFilename() : context.getFilename(); - const checkExportPresence = node => { + const checkExportPresence = (node) => { if (!missingExports) { return; } @@ -589,7 +588,7 @@ module.exports = { * * update lists of existing exports during runtime */ - const updateExportUsage = node => { + const updateExportUsage = (node) => { if (ignoredFiles.has(file)) { return; } @@ -611,7 +610,7 @@ module.exports = { } if (type === EXPORT_NAMED_DECLARATION) { if (specifiers.length > 0) { - specifiers.forEach(specifier => { + specifiers.forEach((specifier) => { if (specifier.exported) { newExportIdentifiers.add(specifier.exported.name || specifier.exported.value); } @@ -631,7 +630,7 @@ module.exports = { }); // new export identifiers added: add to map of new exports - newExportIdentifiers.forEach(key => { + newExportIdentifiers.forEach((key) => { if (!exports.has(key)) { newExports.set(key, { whereUsed: new Set() }); } @@ -655,7 +654,7 @@ module.exports = { * * update lists of existing imports during runtime */ - const updateImportUsage = node => { + const updateImportUsage = (node) => { if (!unusedExports) { return; } @@ -686,9 +685,11 @@ module.exports = { if (value.has(IMPORT_DEFAULT_SPECIFIER)) { oldDefaultImports.add(key); } - value.forEach(val => { - if (val !== IMPORT_NAMESPACE_SPECIFIER && - val !== IMPORT_DEFAULT_SPECIFIER) { + value.forEach((val) => { + if ( + val !== IMPORT_NAMESPACE_SPECIFIER + && val !== IMPORT_DEFAULT_SPECIFIER + ) { oldImports.set(val, key); } }); @@ -716,14 +717,14 @@ module.exports = { }, }); - node.body.forEach(astNode => { + node.body.forEach((astNode) => { let resolvedPath; // support for export { value } from 'module' if (astNode.type === EXPORT_NAMED_DECLARATION) { if (astNode.source) { resolvedPath = resolve(astNode.source.raw.replace(/('|")/g, ''), context); - astNode.specifiers.forEach(specifier => { + astNode.specifiers.forEach((specifier) => { const name = specifier.local.name || specifier.local.value; if (name === DEFAULT) { newDefaultImports.add(resolvedPath); @@ -757,17 +758,15 @@ module.exports = { newDefaultImports.add(resolvedPath); } - astNode.specifiers.forEach(specifier => { - if (specifier.type === IMPORT_DEFAULT_SPECIFIER || - specifier.type === IMPORT_NAMESPACE_SPECIFIER) { - return; - } - newImports.set(specifier.imported.name || specifier.imported.value, resolvedPath); - }); + astNode.specifiers + .filter((specifier) => specifier.type !== IMPORT_DEFAULT_SPECIFIER && specifier.type !== IMPORT_NAMESPACE_SPECIFIER) + .forEach((specifier) => { + newImports.set(specifier.imported.name || specifier.imported.value, resolvedPath); + }); } }); - newExportAll.forEach(value => { + newExportAll.forEach((value) => { if (!oldExportAll.has(value)) { let imports = oldImportPaths.get(value); if (typeof imports === 'undefined') { @@ -795,7 +794,7 @@ module.exports = { } }); - oldExportAll.forEach(value => { + oldExportAll.forEach((value) => { if (!newExportAll.has(value)) { const imports = oldImportPaths.get(value); imports.delete(EXPORT_ALL_DECLARATION); @@ -810,7 +809,7 @@ module.exports = { } }); - newDefaultImports.forEach(value => { + newDefaultImports.forEach((value) => { if (!oldDefaultImports.has(value)) { let imports = oldImportPaths.get(value); if (typeof imports === 'undefined') { @@ -838,7 +837,7 @@ module.exports = { } }); - oldDefaultImports.forEach(value => { + oldDefaultImports.forEach((value) => { if (!newDefaultImports.has(value)) { const imports = oldImportPaths.get(value); imports.delete(IMPORT_DEFAULT_SPECIFIER); @@ -853,7 +852,7 @@ module.exports = { } }); - newNamespaceImports.forEach(value => { + newNamespaceImports.forEach((value) => { if (!oldNamespaceImports.has(value)) { let imports = oldImportPaths.get(value); if (typeof imports === 'undefined') { @@ -881,7 +880,7 @@ module.exports = { } }); - oldNamespaceImports.forEach(value => { + oldNamespaceImports.forEach((value) => { if (!newNamespaceImports.has(value)) { const imports = oldImportPaths.get(value); imports.delete(IMPORT_NAMESPACE_SPECIFIER); @@ -941,16 +940,16 @@ module.exports = { }; return { - 'Program:exit': node => { + 'Program:exit'(node) { updateExportUsage(node); updateImportUsage(node); checkExportPresence(node); }, - 'ExportDefaultDeclaration': node => { + ExportDefaultDeclaration(node) { checkUsage(node, IMPORT_DEFAULT_SPECIFIER); }, - 'ExportNamedDeclaration': node => { - node.specifiers.forEach(specifier => { + ExportNamedDeclaration(node) { + node.specifiers.forEach((specifier) => { checkUsage(node, specifier.exported.name || specifier.exported.value); }); forEachDeclarationIdentifier(node.declaration, (name) => { diff --git a/src/rules/no-useless-path-segments.js b/src/rules/no-useless-path-segments.js index a328be246..343a4f623 100644 --- a/src/rules/no-useless-path-segments.js +++ b/src/rules/no-useless-path-segments.js @@ -25,7 +25,7 @@ import docsUrl from '../docsUrl'; function toRelativePath(relativePath) { const stripped = relativePath.replace(/\/$/g, ''); // Remove trailing / - return /^((\.\.)|(\.))($|\/)/.test(stripped) ? stripped : `./${stripped}`; + return (/^((\.\.)|(\.))($|\/)/).test(stripped) ? stripped : `./${stripped}`; } function normalize(fn) { @@ -71,7 +71,7 @@ module.exports = { node: source, // Note: Using messageIds is not possible due to the support for ESLint 2 and 3 message: `Useless path segments for "${importPath}", should be "${proposedPath}"`, - fix: fixer => proposedPath && fixer.replaceText(source, JSON.stringify(proposedPath)), + fix: (fixer) => proposedPath && fixer.replaceText(source, JSON.stringify(proposedPath)), }); } diff --git a/src/rules/no-webpack-loader-syntax.js b/src/rules/no-webpack-loader-syntax.js index faedeb437..6ca7d603d 100644 --- a/src/rules/no-webpack-loader-syntax.js +++ b/src/rules/no-webpack-loader-syntax.js @@ -3,9 +3,7 @@ import docsUrl from '../docsUrl'; function reportIfNonStandard(context, node, name) { if (name && name.indexOf('!') !== -1) { - context.report(node, `Unexpected '!' in '${name}'. ` + - 'Do not use import syntax to configure webpack loaders.', - ); + context.report(node, `Unexpected '!' in '${name}'. Do not use import syntax to configure webpack loaders.`); } } diff --git a/src/rules/order.js b/src/rules/order.js index bdead9d40..5921989d2 100644 --- a/src/rules/order.js +++ b/src/rules/order.js @@ -13,7 +13,7 @@ const defaultGroups = ['builtin', 'external', 'parent', 'sibling', 'index']; function reverse(array) { return array.map(function (v) { - return Object.assign({}, v, { rank: -v.rank }); + return { ...v, rank: -v.rank }; }).reverse(); } @@ -111,9 +111,9 @@ function findEndOfLineWithComments(sourceCode, node) { } function commentOnSameLineAs(node) { - return token => (token.type === 'Block' || token.type === 'Line') && - token.loc.start.line === token.loc.end.line && - token.loc.end.line === node.loc.end.line; + return (token) => (token.type === 'Block' || token.type === 'Line') + && token.loc.start.line === token.loc.end.line + && token.loc.end.line === node.loc.end.line; } function findStartOfLineWithComments(sourceCode, node) { @@ -130,13 +130,13 @@ function findStartOfLineWithComments(sourceCode, node) { } function isRequireExpression(expr) { - return expr != null && - expr.type === 'CallExpression' && - expr.callee != null && - expr.callee.name === 'require' && - expr.arguments != null && - expr.arguments.length === 1 && - expr.arguments[0].type === 'Literal'; + return expr != null + && expr.type === 'CallExpression' + && expr.callee != null + && expr.callee.name === 'require' + && expr.arguments != null + && expr.arguments.length === 1 + && expr.arguments[0].type === 'Literal'; } function isSupportedRequireModule(node) { @@ -147,16 +147,16 @@ function isSupportedRequireModule(node) { return false; } const decl = node.declarations[0]; - const isPlainRequire = decl.id && - (decl.id.type === 'Identifier' || decl.id.type === 'ObjectPattern') && - isRequireExpression(decl.init); - const isRequireWithMemberExpression = decl.id && - (decl.id.type === 'Identifier' || decl.id.type === 'ObjectPattern') && - decl.init != null && - decl.init.type === 'CallExpression' && - decl.init.callee != null && - decl.init.callee.type === 'MemberExpression' && - isRequireExpression(decl.init.callee.object); + const isPlainRequire = decl.id + && (decl.id.type === 'Identifier' || decl.id.type === 'ObjectPattern') + && isRequireExpression(decl.init); + const isRequireWithMemberExpression = decl.id + && (decl.id.type === 'Identifier' || decl.id.type === 'ObjectPattern') + && decl.init != null + && decl.init.type === 'CallExpression' + && decl.init.callee != null + && decl.init.callee.type === 'MemberExpression' + && isRequireExpression(decl.init.callee.object); return isPlainRequire || isRequireWithMemberExpression; } @@ -211,7 +211,7 @@ function fixOutOfOrder(context, firstNode, secondNode, order) { let newCode = sourceCode.text.substring(secondRootStart, secondRootEnd); if (newCode[newCode.length - 1] !== '\n') { - newCode = newCode + '\n'; + newCode = `${newCode}\n`; } const firstImport = `${makeImportDescription(firstNode)} of \`${firstNode.displayName}\``; @@ -222,21 +222,19 @@ function fixOutOfOrder(context, firstNode, secondNode, order) { context.report({ node: secondNode.node, message, - fix: canFix && (fixer => - fixer.replaceTextRange( - [firstRootStart, secondRootEnd], - newCode + sourceCode.text.substring(firstRootStart, secondRootStart), - )), + fix: canFix && ((fixer) => fixer.replaceTextRange( + [firstRootStart, secondRootEnd], + newCode + sourceCode.text.substring(firstRootStart, secondRootStart), + )), }); } else if (order === 'after') { context.report({ node: secondNode.node, message, - fix: canFix && (fixer => - fixer.replaceTextRange( - [secondRootStart, firstRootEnd], - sourceCode.text.substring(secondRootEnd, firstRootEnd) + newCode, - )), + fix: canFix && ((fixer) => fixer.replaceTextRange( + [secondRootStart, firstRootEnd], + sourceCode.text.substring(secondRootEnd, firstRootEnd) + newCode, + )), }); } } @@ -285,8 +283,8 @@ const getNormalizedValue = (node, toLowerCase) => { function getSorter(alphabetizeOptions) { const multiplier = alphabetizeOptions.order === 'asc' ? 1 : -1; const orderImportKind = alphabetizeOptions.orderImportKind; - const multiplierImportKind = orderImportKind !== 'ignore' && - (alphabetizeOptions.orderImportKind === 'asc' ? 1 : -1); + const multiplierImportKind = orderImportKind !== 'ignore' + && (alphabetizeOptions.orderImportKind === 'asc' ? 1 : -1); return function importsSorter(nodeA, nodeB) { const importA = getNormalizedValue(nodeA, alphabetizeOptions.caseInsensitive); @@ -303,7 +301,7 @@ function getSorter(alphabetizeOptions) { for (let i = 0; i < Math.min(a, b); i++) { result = compareString(A[i], B[i]); - if (result) break; + if (result) { break; } } if (!result && a !== b) { @@ -368,7 +366,7 @@ function computePathRank(ranks, pathGroups, path, maxPosition) { for (let i = 0, l = pathGroups.length; i < l; i++) { const { pattern, patternOptions, group, position = 1 } = pathGroups[i]; if (minimatch(path, pattern, patternOptions || { nocomment: true })) { - return ranks[group] + (position / maxPosition); + return ranks[group] + position / maxPosition; } } } @@ -399,7 +397,7 @@ function computeRank(context, ranks, importEntry, excludedImportTypes) { function registerNode(context, importEntry, ranks, imported, excludedImportTypes) { const rank = computeRank(context, ranks, importEntry, excludedImportTypes); if (rank !== -1) { - imported.push(Object.assign({}, importEntry, { rank })); + imported.push({ ...importEntry, rank }); } } @@ -408,15 +406,15 @@ function getRequireBlock(node) { // Handle cases like `const baz = require('foo').bar.baz` // and `const foo = require('foo')()` while ( - (n.parent.type === 'MemberExpression' && n.parent.object === n) || - (n.parent.type === 'CallExpression' && n.parent.callee === n) + n.parent.type === 'MemberExpression' && n.parent.object === n + || n.parent.type === 'CallExpression' && n.parent.callee === n ) { n = n.parent; } if ( - n.parent.type === 'VariableDeclarator' && - n.parent.parent.type === 'VariableDeclaration' && - n.parent.parent.parent.type === 'Program' + n.parent.type === 'VariableDeclarator' + && n.parent.parent.type === 'VariableDeclaration' + && n.parent.parent.parent.type === 'Program' ) { return n.parent.parent.parent; } @@ -434,11 +432,10 @@ function convertGroupsToRanks(groups) { } group.forEach(function (groupItem) { if (types.indexOf(groupItem) === -1) { - throw new Error('Incorrect configuration of the rule: Unknown type `' + - JSON.stringify(groupItem) + '`'); + throw new Error(`Incorrect configuration of the rule: Unknown type \`${JSON.stringify(groupItem)}\``); } if (res[groupItem] !== undefined) { - throw new Error('Incorrect configuration of the rule: `' + groupItem + '` is duplicated'); + throw new Error(`Incorrect configuration of the rule: \`${groupItem}\` is duplicated`); } res[groupItem] = index * 2; }); @@ -476,7 +473,7 @@ function convertPathGroupsForRanks(pathGroups) { before[group].push(index); } - return Object.assign({}, pathGroup, { position }); + return { ...pathGroup, position }; }); let maxPosition = 1; @@ -520,7 +517,7 @@ function removeNewLineAfterImport(context, currentImport, previousImport) { findEndOfLineWithComments(sourceCode, prevRoot), findStartOfLineWithComments(sourceCode, currRoot), ]; - if (/^\s*$/.test(sourceCode.text.substring(rangeToRemove[0], rangeToRemove[1]))) { + if ((/^\s*$/).test(sourceCode.text.substring(rangeToRemove[0], rangeToRemove[1]))) { return (fixer) => fixer.removeRange(rangeToRemove); } return undefined; @@ -535,9 +532,7 @@ function makeNewlinesBetweenReport(context, imported, newlinesBetweenImports, di return linesBetweenImports.filter((line) => !line.trim().length).length; }; - const getIsStartOfDistinctGroup = (currentImport, previousImport) => { - return currentImport.rank - 1 >= previousImport.rank; - }; + const getIsStartOfDistinctGroup = (currentImport, previousImport) => currentImport.rank - 1 >= previousImport.rank; let previousImport = imported[0]; imported.slice(1).forEach(function (currentImport) { @@ -547,7 +542,7 @@ function makeNewlinesBetweenReport(context, imported, newlinesBetweenImports, di if (newlinesBetweenImports === 'always' || newlinesBetweenImports === 'always-and-inside-groups') { if (currentImport.rank !== previousImport.rank && emptyLinesBetween === 0) { - if (distinctGroup || (!distinctGroup && isStartOfDistinctGroup)) { + if (distinctGroup || !distinctGroup && isStartOfDistinctGroup) { context.report({ node: previousImport.node, message: 'There should be at least one empty line between import groups', @@ -556,7 +551,7 @@ function makeNewlinesBetweenReport(context, imported, newlinesBetweenImports, di } } else if (emptyLinesBetween > 0 && newlinesBetweenImports !== 'always-and-inside-groups') { - if ((distinctGroup && currentImport.rank === previousImport.rank) || (!distinctGroup && !isStartOfDistinctGroup)) { + if (distinctGroup && currentImport.rank === previousImport.rank || !distinctGroup && !isStartOfDistinctGroup) { context.report({ node: previousImport.node, message: 'There should be no empty line within import group', @@ -675,7 +670,7 @@ module.exports = { create: function importOrderRule(context) { const options = context.options[0] || {}; const newlinesBetweenImports = options['newlines-between'] || 'ignore'; - const pathGroupsExcludedImportTypes = new Set(options['pathGroupsExcludedImportTypes'] || ['builtin', 'external', 'object']); + const pathGroupsExcludedImportTypes = new Set(options.pathGroupsExcludedImportTypes || ['builtin', 'external', 'object']); const alphabetize = getAlphabetizeConfig(options); const distinctGroup = options.distinctGroup == null ? defaultDistinctGroup : !!options.distinctGroup; let ranks; diff --git a/src/rules/prefer-default-export.js b/src/rules/prefer-default-export.js index 32ef5004f..581f02502 100644 --- a/src/rules/prefer-default-export.js +++ b/src/rules/prefer-default-export.js @@ -15,7 +15,7 @@ module.exports = { }, schema: [{ type: 'object', - properties:{ + properties: { target: { type: 'string', enum: ['single', 'any'], @@ -51,11 +51,11 @@ module.exports = { } return { - 'ExportDefaultSpecifier': function () { + ExportDefaultSpecifier() { hasDefaultExport = true; }, - 'ExportSpecifier': function (node) { + ExportSpecifier(node) { if ((node.exported.name || node.exported.value) === 'default') { hasDefaultExport = true; } else { @@ -64,17 +64,17 @@ module.exports = { } }, - 'ExportNamedDeclaration': function (node) { + ExportNamedDeclaration(node) { // if there are specifiers, node.declaration should be null - if (!node.declaration) return; + if (!node.declaration) { return; } const { type } = node.declaration; if ( - type === 'TSTypeAliasDeclaration' || - type === 'TypeAlias' || - type === 'TSInterfaceDeclaration' || - type === 'InterfaceDeclaration' + type === 'TSTypeAliasDeclaration' + || type === 'TypeAlias' + || type === 'TSInterfaceDeclaration' + || type === 'InterfaceDeclaration' ) { specifierExportCount++; hasTypeExport = true; @@ -93,15 +93,15 @@ module.exports = { namedExportNode = node; }, - 'ExportDefaultDeclaration': function () { + ExportDefaultDeclaration() { hasDefaultExport = true; }, - 'ExportAllDeclaration': function () { + ExportAllDeclaration() { hasStarExport = true; }, - 'Program:exit': function () { + 'Program:exit'() { if (hasDefaultExport || hasStarExport || hasTypeExport) { return; } diff --git a/tests/src/cli.js b/tests/src/cli.js index e6afd8e44..8a7345487 100644 --- a/tests/src/cli.js +++ b/tests/src/cli.js @@ -21,7 +21,7 @@ describe('CLI regression tests', function () { rulePaths: ['./src/rules'], overrideConfig: { rules: { - 'named': 2, + named: 2, }, }, plugins: { 'eslint-plugin-import': importPlugin }, @@ -32,7 +32,7 @@ describe('CLI regression tests', function () { configFile: './tests/files/issue210.config.js', rulePaths: ['./src/rules'], rules: { - 'named': 2, + named: 2, }, }); cli.addPlugin('eslint-plugin-import', importPlugin); @@ -78,7 +78,7 @@ describe('CLI regression tests', function () { it('throws an error on invalid JSON', () => { const invalidJSON = './tests/files/just-json-files/invalid.json'; if (eslint) { - return eslint.lintFiles([invalidJSON]).then(results => { + return eslint.lintFiles([invalidJSON]).then((results) => { expect(results).to.eql( [ { @@ -97,16 +97,16 @@ describe('CLI regression tests', function () { }, ], errorCount: 1, - ...(semver.satisfies(eslintPkg.version, '>= 7.32 || ^8.0.0') && { + ...semver.satisfies(eslintPkg.version, '>= 7.32 || ^8.0.0') && { fatalErrorCount: 0, - }), + }, warningCount: 0, fixableErrorCount: 0, fixableWarningCount: 0, source: results[0].source, // NewLine-characters might differ depending on git-settings - ...(semver.satisfies(eslintPkg.version, '>= 8.8') && { + ...semver.satisfies(eslintPkg.version, '>= 8.8') && { suppressedMessages: [], - }), + }, usedDeprecatedRules: results[0].usedDeprecatedRules, // we don't care about this one }, ], diff --git a/tests/src/core/getExports.js b/tests/src/core/getExports.js index 86c191596..1dd6e8801 100644 --- a/tests/src/core/getExports.js +++ b/tests/src/core/getExports.js @@ -58,11 +58,10 @@ describe('ExportMap', function () { const firstAccess = ExportMap.get('./named-exports', fakeContext); expect(firstAccess).to.exist; - const differentSettings = Object.assign( - {}, - fakeContext, - { parserPath: 'espree' }, - ); + const differentSettings = { + ...fakeContext, + parserPath: 'espree', + }; expect(ExportMap.get('./named-exports', differentSettings)) .to.exist.and @@ -320,17 +319,19 @@ describe('ExportMap', function () { }); it(`'has' circular reference`, function () { expect(ExportMap.get('./narcissist', fakeContext)) - .to.exist.and.satisfy(m => m.has('soGreat')); + .to.exist.and.satisfy((m) => m.has('soGreat')); }); it(`can 'get' circular reference`, function () { expect(ExportMap.get('./narcissist', fakeContext)) - .to.exist.and.satisfy(m => m.get('soGreat') != null); + .to.exist.and.satisfy((m) => m.get('soGreat') != null); }); }); context('issue #478: never parse non-whitelist extensions', function () { - const context = Object.assign({}, fakeContext, - { settings: { 'import/extensions': ['.js'] } }); + const context = { + ...fakeContext, + settings: { 'import/extensions': ['.js'] }, + }; let imports; before('load imports', function () { @@ -359,11 +360,13 @@ describe('ExportMap', function () { configs.forEach(([description, parserConfig]) => { describe(description, function () { - const context = Object.assign({}, fakeContext, - { settings: { + const context = { + ...fakeContext, + settings: { 'import/extensions': ['.js'], 'import/parsers': parserConfig, - } }); + }, + }; let imports; before('load imports', function () { @@ -404,30 +407,24 @@ describe('ExportMap', function () { }); it('should cache tsconfig until tsconfigRootDir parser option changes', function () { - const customContext = Object.assign( - {}, - context, - { - parserOptions: { - tsconfigRootDir: null, - }, + const customContext = { + ...context, + parserOptions: { + tsconfigRootDir: null, }, - ); + }; expect(tsConfigLoader.tsConfigLoader.callCount).to.equal(0); ExportMap.parse('./baz.ts', 'export const baz = 5', customContext); expect(tsConfigLoader.tsConfigLoader.callCount).to.equal(1); ExportMap.parse('./baz.ts', 'export const baz = 5', customContext); expect(tsConfigLoader.tsConfigLoader.callCount).to.equal(1); - const differentContext = Object.assign( - {}, - context, - { - parserOptions: { - tsconfigRootDir: process.cwd(), - }, + const differentContext = { + ...context, + parserOptions: { + tsconfigRootDir: process.cwd(), }, - ); + }; ExportMap.parse('./baz.ts', 'export const baz = 5', differentContext); expect(tsConfigLoader.tsConfigLoader.callCount).to.equal(2); @@ -460,7 +457,7 @@ describe('ExportMap', function () { for (const [testFile, expectedRegexResult] of testFiles) { it(`works for ${testFile} (${expectedRegexResult})`, function () { - const content = fs.readFileSync('./tests/files/' + testFile, 'utf8'); + const content = fs.readFileSync(`./tests/files/${testFile}`, 'utf8'); expect(testUnambiguous(content)).to.equal(expectedRegexResult); }); } diff --git a/tests/src/core/hash.js b/tests/src/core/hash.js index e75783fb0..1d6a9eb85 100644 --- a/tests/src/core/hash.js +++ b/tests/src/core/hash.js @@ -7,7 +7,7 @@ const createHash = require('crypto').createHash; function expectHash(actualHash, expectedString) { const expectedHash = createHash('sha256'); expectedHash.update(expectedString); - expect(actualHash.digest('hex'), 'to be a hex digest of sha256 hash of string <' + expectedString + '>').to.equal(expectedHash.digest('hex')); + expect(actualHash.digest('hex'), `to be a hex digest of sha256 hash of string <${expectedString}>`).to.equal(expectedHash.digest('hex')); } describe('hash', function () { diff --git a/tests/src/core/parse.js b/tests/src/core/parse.js index 4ab8370ed..9c5945360 100644 --- a/tests/src/core/parse.js +++ b/tests/src/core/parse.js @@ -13,9 +13,19 @@ describe('parse(content, { settings, ecmaFeatures })', function () { const eslintParserPath = require.resolve('./eslintParser'); let content; - before((done) => - fs.readFile(path, { encoding: 'utf8' }, - (err, f) => { if (err) { done(err); } else { content = f; done(); }})); + before((done) => { + fs.readFile( + path, + { encoding: 'utf8' }, + (err, f) => { + if (err) { + done(err); + } else { + content = f; done(); + } + }, + ); + }); it('doesn\'t support JSX by default', function () { expect(() => parse(path, content, { parserPath: 'espree' })).to.throw(Error); diff --git a/tests/src/core/resolve.js b/tests/src/core/resolve.js index 05a6aaeb6..6b69fb7f1 100644 --- a/tests/src/core/resolve.js +++ b/tests/src/core/resolve.js @@ -21,32 +21,38 @@ describe('resolve', function () { it('resolves via a custom resolver with interface version 1', function () { const testContext = utils.testContext({ 'import/resolver': './foo-bar-resolver-v1' }); - expect(resolve( '../files/foo' - , Object.assign({}, testContext, { getFilename() { return utils.getFilename('foo.js'); } }), + expect(resolve( + '../files/foo', + { ...testContext, getFilename() { return utils.getFilename('foo.js'); } }, )).to.equal(utils.testFilePath('./bar.jsx')); - expect(resolve( '../files/exception' - , Object.assign({}, testContext, { getFilename() { return utils.getFilename('exception.js'); } }), + expect(resolve( + '../files/exception', + { ...testContext, getFilename() { return utils.getFilename('exception.js'); } }, )).to.equal(undefined); - expect(resolve( '../files/not-found' - , Object.assign({}, testContext, { getFilename() { return utils.getFilename('not-found.js'); } }), + expect(resolve( + '../files/not-found', + { ...testContext, getFilename() { return utils.getFilename('not-found.js'); } }, )).to.equal(undefined); }); it('resolves via a custom resolver with interface version 1 assumed if not specified', function () { const testContext = utils.testContext({ 'import/resolver': './foo-bar-resolver-no-version' }); - expect(resolve( '../files/foo' - , Object.assign({}, testContext, { getFilename() { return utils.getFilename('foo.js'); } }), + expect(resolve( + '../files/foo', + { ...testContext, getFilename() { return utils.getFilename('foo.js'); } }, )).to.equal(utils.testFilePath('./bar.jsx')); - expect(resolve( '../files/exception' - , Object.assign({}, testContext, { getFilename() { return utils.getFilename('exception.js'); } }), + expect(resolve( + '../files/exception', + { ...testContext, getFilename() { return utils.getFilename('exception.js'); } }, )).to.equal(undefined); - expect(resolve( '../files/not-found' - , Object.assign({}, testContext, { getFilename() { return utils.getFilename('not-found.js'); } }), + expect(resolve( + '../files/not-found', + { ...testContext, getFilename() { return utils.getFilename('not-found.js'); } }, )).to.equal(undefined); }); @@ -57,21 +63,24 @@ describe('resolve', function () { testContextReports.push(reportInfo); }; - expect(resolve( '../files/foo' - , Object.assign({}, testContext, { getFilename() { return utils.getFilename('foo.js'); } }), + expect(resolve( + '../files/foo', + { ...testContext, getFilename() { return utils.getFilename('foo.js'); } }, )).to.equal(utils.testFilePath('./bar.jsx')); testContextReports.length = 0; - expect(resolve( '../files/exception' - , Object.assign({}, testContext, { getFilename() { return utils.getFilename('exception.js'); } }), + expect(resolve( + '../files/exception', + { ...testContext, getFilename() { return utils.getFilename('exception.js'); } }, )).to.equal(undefined); expect(testContextReports[0]).to.be.an('object'); expect(replaceErrorStackForTest(testContextReports[0].message)).to.equal('Resolve error: foo-bar-resolver-v2 resolve test exception\n'); expect(testContextReports[0].loc).to.eql({ line: 1, column: 0 }); testContextReports.length = 0; - expect(resolve( '../files/not-found' - , Object.assign({}, testContext, { getFilename() { return utils.getFilename('not-found.js'); } }), + expect(resolve( + '../files/not-found', + { ...testContext, getFilename() { return utils.getFilename('not-found.js'); } }, )).to.equal(undefined); expect(testContextReports.length).to.equal(0); }); @@ -79,32 +88,36 @@ describe('resolve', function () { it('respects import/resolver as array of strings', function () { const testContext = utils.testContext({ 'import/resolver': [ './foo-bar-resolver-v2', './foo-bar-resolver-v1' ] }); - expect(resolve( '../files/foo' - , Object.assign({}, testContext, { getFilename() { return utils.getFilename('foo.js'); } }), + expect(resolve( + '../files/foo', + { ...testContext, getFilename() { return utils.getFilename('foo.js'); } }, )).to.equal(utils.testFilePath('./bar.jsx')); }); it('respects import/resolver as object', function () { const testContext = utils.testContext({ 'import/resolver': { './foo-bar-resolver-v2': {} } }); - expect(resolve( '../files/foo' - , Object.assign({}, testContext, { getFilename() { return utils.getFilename('foo.js'); } }), + expect(resolve( + '../files/foo', + { ...testContext, getFilename() { return utils.getFilename('foo.js'); } }, )).to.equal(utils.testFilePath('./bar.jsx')); }); it('respects import/resolver as array of objects', function () { const testContext = utils.testContext({ 'import/resolver': [ { './foo-bar-resolver-v2': {} }, { './foo-bar-resolver-v1': {} } ] }); - expect(resolve( '../files/foo' - , Object.assign({}, testContext, { getFilename() { return utils.getFilename('foo.js'); } }), + expect(resolve( + '../files/foo', + { ...testContext, getFilename() { return utils.getFilename('foo.js'); } }, )).to.equal(utils.testFilePath('./bar.jsx')); }); it('finds resolvers from the source files rather than eslint-module-utils', function () { - const testContext = utils.testContext({ 'import/resolver': { 'foo': {} } }); + const testContext = utils.testContext({ 'import/resolver': { foo: {} } }); - expect(resolve( '../files/foo' - , Object.assign({}, testContext, { getFilename() { return utils.getFilename('foo.js'); } }), + expect(resolve( + '../files/foo', + { ...testContext, getFilename() { return utils.getFilename('foo.js'); } }, )).to.equal(utils.testFilePath('./bar.jsx')); }); @@ -116,8 +129,9 @@ describe('resolve', function () { }; testContextReports.length = 0; - expect(resolve( '../files/foo' - , Object.assign({}, testContext, { getFilename() { return utils.getFilename('foo.js'); } }), + expect(resolve( + '../files/foo', + { ...testContext, getFilename() { return utils.getFilename('foo.js'); } }, )).to.equal(undefined); expect(testContextReports[0]).to.be.an('object'); expect(testContextReports[0].message).to.equal('Resolve error: invalid resolver config'); @@ -132,8 +146,9 @@ describe('resolve', function () { testContextReports.push(reportInfo); }; testContextReports.length = 0; - expect(resolve( '../files/foo' - , Object.assign({}, testContext, { getFilename() { return utils.getFilename('foo.js'); } }), + expect(resolve( + '../files/foo', + { ...testContext, getFilename() { return utils.getFilename('foo.js'); } }, )).to.equal(undefined); expect(testContextReports[0]).to.be.an('object'); expect(testContextReports[0].message).to.equal(`Resolve error: ${resolverName} with invalid interface loaded as resolver`); @@ -141,10 +156,11 @@ describe('resolve', function () { }); it('respects import/resolve extensions', function () { - const testContext = utils.testContext({ 'import/resolve': { 'extensions': ['.jsx'] } }); + const testContext = utils.testContext({ 'import/resolve': { extensions: ['.jsx'] } }); - expect(resolve( './jsx/MyCoolComponent' - , testContext, + expect(resolve( + './jsx/MyCoolComponent', + testContext, )).to.equal(utils.testFilePath('./jsx/MyCoolComponent.jsx')); }); @@ -155,8 +171,9 @@ describe('resolve', function () { testContextReports.push(reportInfo); }; - expect(resolve( '../files/exception' - , Object.assign({}, testContext, { getFilename() { return utils.getFilename('exception.js'); } }), + expect(resolve( + '../files/exception', + { ...testContext, getFilename() { return utils.getFilename('exception.js'); } }, )).to.equal(undefined); expect(testContextReports[0]).to.be.an('object'); expect(replaceErrorStackForTest(testContextReports[0].message)).to.equal('Resolve error: SyntaxError: TEST SYNTAX ERROR\n'); @@ -172,32 +189,38 @@ describe('resolve', function () { it('resolves via a custom resolver with interface version 1', function () { const testContext = utils.testContext({ 'import/resolver': './foo-bar-resolver-v1' }); - expect(resolve( '../files/foo' - , Object.assign({}, testContext, { getFilename: unexpectedCallToGetFilename, getPhysicalFilename() { return utils.getFilename('foo.js'); } }), + expect(resolve( + '../files/foo', + { ...testContext, getFilename: unexpectedCallToGetFilename, getPhysicalFilename() { return utils.getFilename('foo.js'); } }, )).to.equal(utils.testFilePath('./bar.jsx')); - expect(resolve( '../files/exception' - , Object.assign({}, testContext, { getFilename: unexpectedCallToGetFilename, getPhysicalFilename() { return utils.getFilename('exception.js'); } }), + expect(resolve( + '../files/exception', + { ...testContext, getFilename: unexpectedCallToGetFilename, getPhysicalFilename() { return utils.getFilename('exception.js'); } }, )).to.equal(undefined); - expect(resolve( '../files/not-found' - , Object.assign({}, testContext, { getFilename: unexpectedCallToGetFilename, getPhysicalFilename() { return utils.getFilename('not-found.js'); } }), + expect(resolve( + '../files/not-found', + { ...testContext, getFilename: unexpectedCallToGetFilename, getPhysicalFilename() { return utils.getFilename('not-found.js'); } }, )).to.equal(undefined); }); it('resolves via a custom resolver with interface version 1 assumed if not specified', function () { const testContext = utils.testContext({ 'import/resolver': './foo-bar-resolver-no-version' }); - expect(resolve( '../files/foo' - , Object.assign({}, testContext, { getFilename: unexpectedCallToGetFilename, getPhysicalFilename() { return utils.getFilename('foo.js'); } }), + expect(resolve( + '../files/foo', + { ...testContext, getFilename: unexpectedCallToGetFilename, getPhysicalFilename() { return utils.getFilename('foo.js'); } }, )).to.equal(utils.testFilePath('./bar.jsx')); - expect(resolve( '../files/exception' - , Object.assign({}, testContext, { getFilename: unexpectedCallToGetFilename, getPhysicalFilename() { return utils.getFilename('exception.js'); } }), + expect(resolve( + '../files/exception', + { ...testContext, getFilename: unexpectedCallToGetFilename, getPhysicalFilename() { return utils.getFilename('exception.js'); } }, )).to.equal(undefined); - expect(resolve( '../files/not-found' - , Object.assign({}, testContext, { getFilename: unexpectedCallToGetFilename, getPhysicalFilename() { return utils.getFilename('not-found.js'); } }), + expect(resolve( + '../files/not-found', + { ...testContext, getFilename: unexpectedCallToGetFilename, getPhysicalFilename() { return utils.getFilename('not-found.js'); } }, )).to.equal(undefined); }); @@ -208,21 +231,24 @@ describe('resolve', function () { testContextReports.push(reportInfo); }; - expect(resolve( '../files/foo' - , Object.assign({}, testContext, { getFilename: unexpectedCallToGetFilename, getPhysicalFilename() { return utils.getFilename('foo.js'); } }), + expect(resolve( + '../files/foo', + { ...testContext, getFilename: unexpectedCallToGetFilename, getPhysicalFilename() { return utils.getFilename('foo.js'); } }, )).to.equal(utils.testFilePath('./bar.jsx')); testContextReports.length = 0; - expect(resolve( '../files/exception' - , Object.assign({}, testContext, { getFilename: unexpectedCallToGetFilename, getPhysicalFilename() { return utils.getFilename('exception.js'); } }), + expect(resolve( + '../files/exception', + { ...testContext, getFilename: unexpectedCallToGetFilename, getPhysicalFilename() { return utils.getFilename('exception.js'); } }, )).to.equal(undefined); expect(testContextReports[0]).to.be.an('object'); expect(replaceErrorStackForTest(testContextReports[0].message)).to.equal('Resolve error: foo-bar-resolver-v2 resolve test exception\n'); expect(testContextReports[0].loc).to.eql({ line: 1, column: 0 }); testContextReports.length = 0; - expect(resolve( '../files/not-found' - , Object.assign({}, testContext, { getFilename: unexpectedCallToGetFilename, getPhysicalFilename() { return utils.getFilename('not-found.js'); } }), + expect(resolve( + '../files/not-found', + { ...testContext, getFilename: unexpectedCallToGetFilename, getPhysicalFilename() { return utils.getFilename('not-found.js'); } }, )).to.equal(undefined); expect(testContextReports.length).to.equal(0); }); @@ -230,32 +256,36 @@ describe('resolve', function () { it('respects import/resolver as array of strings', function () { const testContext = utils.testContext({ 'import/resolver': [ './foo-bar-resolver-v2', './foo-bar-resolver-v1' ] }); - expect(resolve( '../files/foo' - , Object.assign({}, testContext, { getFilename: unexpectedCallToGetFilename, getPhysicalFilename() { return utils.getFilename('foo.js'); } }), + expect(resolve( + '../files/foo', + { ...testContext, getFilename: unexpectedCallToGetFilename, getPhysicalFilename() { return utils.getFilename('foo.js'); } }, )).to.equal(utils.testFilePath('./bar.jsx')); }); it('respects import/resolver as object', function () { const testContext = utils.testContext({ 'import/resolver': { './foo-bar-resolver-v2': {} } }); - expect(resolve( '../files/foo' - , Object.assign({}, testContext, { getFilename: unexpectedCallToGetFilename, getPhysicalFilename() { return utils.getFilename('foo.js'); } }), + expect(resolve( + '../files/foo', + { ...testContext, getFilename: unexpectedCallToGetFilename, getPhysicalFilename() { return utils.getFilename('foo.js'); } }, )).to.equal(utils.testFilePath('./bar.jsx')); }); it('respects import/resolver as array of objects', function () { const testContext = utils.testContext({ 'import/resolver': [ { './foo-bar-resolver-v2': {} }, { './foo-bar-resolver-v1': {} } ] }); - expect(resolve( '../files/foo' - , Object.assign({}, testContext, { getFilename: unexpectedCallToGetFilename, getPhysicalFilename() { return utils.getFilename('foo.js'); } }), + expect(resolve( + '../files/foo', + { ...testContext, getFilename: unexpectedCallToGetFilename, getPhysicalFilename() { return utils.getFilename('foo.js'); } }, )).to.equal(utils.testFilePath('./bar.jsx')); }); it('finds resolvers from the source files rather than eslint-module-utils', function () { - const testContext = utils.testContext({ 'import/resolver': { 'foo': {} } }); + const testContext = utils.testContext({ 'import/resolver': { foo: {} } }); - expect(resolve( '../files/foo' - , Object.assign({}, testContext, { getFilename: unexpectedCallToGetFilename, getPhysicalFilename() { return utils.getFilename('foo.js'); } }), + expect(resolve( + '../files/foo', + { ...testContext, getFilename: unexpectedCallToGetFilename, getPhysicalFilename() { return utils.getFilename('foo.js'); } }, )).to.equal(utils.testFilePath('./bar.jsx')); }); @@ -267,8 +297,9 @@ describe('resolve', function () { }; testContextReports.length = 0; - expect(resolve( '../files/foo' - , Object.assign({}, testContext, { getFilename: unexpectedCallToGetFilename, getPhysicalFilename() { return utils.getFilename('foo.js'); } }), + expect(resolve( + '../files/foo', + { ...testContext, getFilename: unexpectedCallToGetFilename, getPhysicalFilename() { return utils.getFilename('foo.js'); } }, )).to.equal(undefined); expect(testContextReports[0]).to.be.an('object'); expect(testContextReports[0].message).to.equal('Resolve error: invalid resolver config'); @@ -283,8 +314,9 @@ describe('resolve', function () { testContextReports.push(reportInfo); }; testContextReports.length = 0; - expect(resolve( '../files/foo' - , Object.assign({}, testContext, { getFilename: unexpectedCallToGetFilename, getPhysicalFilename() { return utils.getFilename('foo.js'); } }), + expect(resolve( + '../files/foo', + { ...testContext, getFilename: unexpectedCallToGetFilename, getPhysicalFilename() { return utils.getFilename('foo.js'); } }, )).to.equal(undefined); expect(testContextReports[0]).to.be.an('object'); expect(testContextReports[0].message).to.equal(`Resolve error: ${resolverName} with invalid interface loaded as resolver`); @@ -292,10 +324,11 @@ describe('resolve', function () { }); it('respects import/resolve extensions', function () { - const testContext = utils.testContext({ 'import/resolve': { 'extensions': ['.jsx'] } }); + const testContext = utils.testContext({ 'import/resolve': { extensions: ['.jsx'] } }); - expect(resolve( './jsx/MyCoolComponent' - , testContext, + expect(resolve( + './jsx/MyCoolComponent', + testContext, )).to.equal(utils.testFilePath('./jsx/MyCoolComponent.jsx')); }); @@ -306,8 +339,9 @@ describe('resolve', function () { testContextReports.push(reportInfo); }; - expect(resolve( '../files/exception' - , Object.assign({}, testContext, { getFilename: unexpectedCallToGetFilename, getPhysicalFilename() { return utils.getFilename('exception.js'); } }), + expect(resolve( + '../files/exception', + { ...testContext, getFilename: unexpectedCallToGetFilename, getPhysicalFilename() { return utils.getFilename('exception.js'); } }, )).to.equal(undefined); expect(testContextReports[0]).to.be.an('object'); expect(replaceErrorStackForTest(testContextReports[0].message)).to.equal('Resolve error: SyntaxError: TEST SYNTAX ERROR\n'); @@ -315,11 +349,11 @@ describe('resolve', function () { }); }); - const caseDescribe = (!CASE_SENSITIVE_FS ? describe : describe.skip); + const caseDescribe = !CASE_SENSITIVE_FS ? describe : describe.skip; caseDescribe('case sensitivity', function () { let file; const testContext = utils.testContext({ - 'import/resolve': { 'extensions': ['.jsx'] }, + 'import/resolve': { extensions: ['.jsx'] }, 'import/cache': { lifetime: 0 }, }); const testSettings = testContext.settings; @@ -333,31 +367,30 @@ describe('resolve', function () { }); it('detects case does not match FS', function () { expect(fileExistsWithCaseSync(file, testSettings)) - .to.be.false; + .to.equal(false); }); it('detecting case does not include parent folder path (issue #720)', function () { const f = path.join(process.cwd().toUpperCase(), './tests/files/jsx/MyUnCoolComponent.jsx'); expect(fileExistsWithCaseSync(f, testSettings)) - .to.be.true; + .to.equal(true); }); it('detecting case should include parent folder path', function () { const f = path.join(process.cwd().toUpperCase(), './tests/files/jsx/MyUnCoolComponent.jsx'); expect(fileExistsWithCaseSync(f, testSettings, true)) - .to.be.false; + .to.equal(false); }); }); describe('rename cache correctness', function () { const context = utils.testContext({ - 'import/cache': { 'lifetime': 1 }, + 'import/cache': { lifetime: 1 }, }); - const infiniteContexts = [ '∞', 'Infinity' ].map(inf => [inf, + const infiniteContexts = [ '∞', 'Infinity' ].map((inf) => [inf, utils.testContext({ - 'import/cache': { 'lifetime': inf }, + 'import/cache': { lifetime: inf }, })]); - const pairs = [ ['./CaseyKasem.js', './CASEYKASEM2.js'], ]; @@ -372,7 +405,7 @@ describe('resolve', function () { // settings are part of cache key before('warm up infinite entries', function () { - infiniteContexts.forEach(([,c]) => { + infiniteContexts.forEach(([, c]) => { expect(resolve(original, c)).to.exist; }); }); @@ -384,10 +417,9 @@ describe('resolve', function () { done); }); - before('verify rename', (done) => - fs.exists( - utils.testFilePath(changed), - exists => done(exists ? null : new Error('new file does not exist')))); + before('verify rename', (done) => fs.exists( + utils.testFilePath(changed), + (exists) => done(exists ? null : new Error('new file does not exist')))); it('gets cached values within cache lifetime', function () { // get cached values initially @@ -426,7 +458,8 @@ describe('resolve', function () { fs.rename( utils.testFilePath(changed), utils.testFilePath(original), - done); + done, + ); }); }); }); diff --git a/tests/src/package.js b/tests/src/package.js index f75981975..dd55e2740 100644 --- a/tests/src/package.js +++ b/tests/src/package.js @@ -38,8 +38,8 @@ describe('package', function () { it('exports all configs', function (done) { fs.readdir(path.join(process.cwd(), 'config'), function (err, files) { if (err) { done(err); return; } - files.filter(isJSFile).forEach(file => { - if (file[0] === '.') return; + files.filter(isJSFile).forEach((file) => { + if (file[0] === '.') { return; } expect(module.configs).to.have.property(path.basename(file, '.js')); }); done(); @@ -66,7 +66,7 @@ describe('package', function () { it('marks deprecated rules in their metadata', function () { expect(module.rules['imports-first'].meta.deprecated).to.be.true; - expect(module.rules['first'].meta.deprecated).not.to.be.true; + expect(module.rules.first.meta.deprecated).not.to.be.true; }); }); diff --git a/tests/src/rules/dynamic-import-chunkname.js b/tests/src/rules/dynamic-import-chunkname.js index 46a1b97af..73617a6f3 100644 --- a/tests/src/rules/dynamic-import-chunkname.js +++ b/tests/src/rules/dynamic-import-chunkname.js @@ -969,7 +969,7 @@ ruleTester.run('dynamic-import-chunkname', rule, { context('TypeScript', () => { getTSParsers().forEach((typescriptParser) => { - const nodeType = typescriptParser === parsers.TS_OLD || (typescriptParser === parsers.TS_NEW && semver.satisfies(require('@typescript-eslint/parser/package.json').version, '^2')) + const nodeType = typescriptParser === parsers.TS_OLD || typescriptParser === parsers.TS_NEW && semver.satisfies(require('@typescript-eslint/parser/package.json').version, '^2') ? 'CallExpression' : 'ImportExpression'; diff --git a/tests/src/rules/export.js b/tests/src/rules/export.js index 95093bf4a..a7f2bec12 100644 --- a/tests/src/rules/export.js +++ b/tests/src/rules/export.js @@ -137,7 +137,6 @@ ruleTester.run('export', rule, { // errors: ['Parsing error: Duplicate export \'bar\''], // }), - // #328: "export * from" does not export a default test({ code: 'export * from "./default-export"', @@ -158,7 +157,6 @@ ruleTester.run('export', rule, { ), }); - context('TypeScript', function () { getTSParsers().forEach((parser) => { const parserConfig = { diff --git a/tests/src/rules/exports-last.js b/tests/src/rules/exports-last.js index 9f01f27f4..d7122e9a0 100644 --- a/tests/src/rules/exports-last.js +++ b/tests/src/rules/exports-last.js @@ -5,7 +5,7 @@ import rule from 'rules/exports-last'; const ruleTester = new RuleTester(); -const error = type => ({ +const error = (type) => ({ message: 'Export statements should appear at the end of the file', type, }); diff --git a/tests/src/rules/extensions.js b/tests/src/rules/extensions.js index 45b4498fe..ede1a8d88 100644 --- a/tests/src/rules/extensions.js +++ b/tests/src/rules/extensions.js @@ -31,7 +31,7 @@ ruleTester.run('extensions', rule, { 'import data from "./bar.json"', ].join('\n'), options: [ 'never' ], - settings: { 'import/resolve': { 'extensions': [ '.js', '.jsx', '.json' ] } }, + settings: { 'import/resolve': { extensions: [ '.js', '.jsx', '.json' ] } }, }), test({ @@ -41,7 +41,7 @@ ruleTester.run('extensions', rule, { 'import barhbs from "./bar.hbs"', ].join('\n'), options: [ 'always', { js: 'never', jsx: 'never' } ], - settings: { 'import/resolve': { 'extensions': [ '.js', '.jsx', '.json', '.hbs' ] } }, + settings: { 'import/resolve': { extensions: [ '.js', '.jsx', '.json', '.hbs' ] } }, }), test({ @@ -50,7 +50,7 @@ ruleTester.run('extensions', rule, { 'import pack from "./package"', ].join('\n'), options: [ 'never', { js: 'always', json: 'never' } ], - settings: { 'import/resolve': { 'extensions': [ '.js', '.json' ] } }, + settings: { 'import/resolve': { extensions: [ '.js', '.json' ] } }, }), // unresolved (#271/#295) @@ -96,8 +96,8 @@ ruleTester.run('extensions', rule, { filename: testFilePath('./internal-modules/plugins/plugin.js'), settings: { 'import/resolver': { - 'node': { 'extensions': [ '.js', '.jsx', '.json' ] }, - 'webpack': { 'config': 'webpack.empty.config.js' }, + node: { extensions: [ '.js', '.jsx', '.json' ] }, + webpack: { config: 'webpack.empty.config.js' }, }, }, }), @@ -174,7 +174,7 @@ ruleTester.run('extensions', rule, { 'import packageConfig from "./package"', ].join('\n'), options: [ { json: 'always', js: 'never' } ], - settings: { 'import/resolve': { 'extensions': [ '.js', '.json' ] } }, + settings: { 'import/resolve': { extensions: [ '.js', '.json' ] } }, errors: [ { message: 'Unexpected use of file extension "js" for "a/index.js"', @@ -195,7 +195,7 @@ ruleTester.run('extensions', rule, { 'import data from "./bar.json"', ].join('\n'), options: [ 'never' ], - settings: { 'import/resolve': { 'extensions': [ '.js', '.jsx', '.json' ] } }, + settings: { 'import/resolve': { extensions: [ '.js', '.jsx', '.json' ] } }, errors: [ { message: 'Unexpected use of file extension "js" for "./bar.js"', @@ -211,7 +211,7 @@ ruleTester.run('extensions', rule, { 'import data from "./bar.json"', ].join('\n'), options: [ { json: 'always', js: 'never', jsx: 'never' } ], - settings: { 'import/resolve': { 'extensions': [ '.js', '.jsx', '.json' ] } }, + settings: { 'import/resolve': { extensions: [ '.js', '.jsx', '.json' ] } }, errors: [ { message: 'Unexpected use of file extension "js" for "./bar.js"', @@ -227,7 +227,7 @@ ruleTester.run('extensions', rule, { 'import data from "./bar.json"', ].join('\n'), options: [ { json: 'always', js: 'never', jsx: 'never' } ], - settings: { 'import/resolve': { 'extensions': [ '.jsx', '.json', '.js' ] } }, + settings: { 'import/resolve': { extensions: [ '.jsx', '.json', '.js' ] } }, errors: [ { message: 'Unexpected use of file extension "jsx" for "./bar.jsx"', @@ -246,7 +246,7 @@ ruleTester.run('extensions', rule, { }, ], options: ['never', { js: 'always', jsx: 'always' }], - settings: { 'import/resolve': { 'extensions': ['.coffee', '.js'] } }, + settings: { 'import/resolve': { extensions: ['.coffee', '.js'] } }, }), test({ @@ -256,7 +256,7 @@ ruleTester.run('extensions', rule, { 'import barnone from "./bar"', ].join('\n'), options: [ 'always', { json: 'always', js: 'never', jsx: 'never' } ], - settings: { 'import/resolve': { 'extensions': [ '.js', '.jsx', '.json' ] } }, + settings: { 'import/resolve': { extensions: [ '.js', '.jsx', '.json' ] } }, errors: [ { message: 'Unexpected use of file extension "js" for "./bar.js"', @@ -273,7 +273,7 @@ ruleTester.run('extensions', rule, { 'import barnone from "./bar"', ].join('\n'), options: [ 'never', { json: 'always', js: 'never', jsx: 'never' } ], - settings: { 'import/resolve': { 'extensions': [ '.js', '.jsx', '.json' ] } }, + settings: { 'import/resolve': { extensions: [ '.js', '.jsx', '.json' ] } }, errors: [ { message: 'Unexpected use of file extension "js" for "./bar.js"', @@ -331,7 +331,6 @@ ruleTester.run('extensions', rule, { ], }), - test({ code: ` import foo from './foo.js' diff --git a/tests/src/rules/first.js b/tests/src/rules/first.js index 8892ff3d6..f34f227b2 100644 --- a/tests/src/rules/first.js +++ b/tests/src/rules/first.js @@ -81,7 +81,7 @@ ruleTester.run('first', rule, { code: "if (true) { console.log(1) }import a from 'b'", errors: 1, output: "import a from 'b'\nif (true) { console.log(1) }", - }), + }), ], }); diff --git a/tests/src/rules/named.js b/tests/src/rules/named.js index 227e242ef..110cfff52 100644 --- a/tests/src/rules/named.js +++ b/tests/src/rules/named.js @@ -4,12 +4,11 @@ import path from 'path'; import { CASE_SENSITIVE_FS } from 'eslint-module-utils/resolve'; - const ruleTester = new RuleTester(); const rule = require('rules/named'); function error(name, module, type = 'Identifier') { - return { message: name + ' not found in \'' + module + '\'', type }; + return { message: `${name} not found in '${module}'`, type }; } ruleTester.run('named', rule, { @@ -30,11 +29,10 @@ ruleTester.run('named', rule, { test({ code: 'import {RuleTester} from "./re-export-node_modules"' }), test({ code: 'import { jsxFoo } from "./jsx/AnotherComponent"', - settings: { 'import/resolve': { 'extensions': ['.js', '.jsx'] } } }), + settings: { 'import/resolve': { extensions: ['.js', '.jsx'] } } }), // validate that eslint-disable-line silences this properly - test({ code: 'import {a, b, d} from "./common"; ' + - '// eslint-disable-line named' }), + test({ code: 'import {a, b, d} from "./common"; // eslint-disable-line named' }), test({ code: 'import { foo, bar } from "./re-export-names"' }), @@ -192,7 +190,7 @@ ruleTester.run('named', rule, { }, })), - testVersion('>=7.8.0', () =>({ code: 'const { something } = require("./dynamic-import-in-commonjs")', + testVersion('>=7.8.0', () => ({ code: 'const { something } = require("./dynamic-import-in-commonjs")', parserOptions: { ecmaVersion: 2021 }, options: [{ commonjs: true }], })), @@ -323,7 +321,6 @@ ruleTester.run('named', rule, { errors: ["bap not found in './re-export-default'"], }), - // #328: * exports do not include default test({ code: 'import { default as barDefault } from "./re-export"', @@ -381,7 +378,6 @@ ruleTester.run('named (export *)', rule, { ], }); - context('TypeScript', function () { getTSParsers().forEach((parser) => { const settings = { @@ -459,7 +455,7 @@ context('TypeScript', function () { parser, settings, }), - (source === 'typescript-declare' + source === 'typescript-declare' ? testVersion('> 5', () => ({ code: `import { getFoo } from "./${source}"`, parser, @@ -470,7 +466,7 @@ context('TypeScript', function () { parser, settings, }) - ), + , test({ code: `import { MyEnum } from "./${source}"`, parser, diff --git a/tests/src/rules/namespace.js b/tests/src/rules/namespace.js index 163ff163e..d368fd3fe 100644 --- a/tests/src/rules/namespace.js +++ b/tests/src/rules/namespace.js @@ -5,7 +5,6 @@ import flatMap from 'array.prototype.flatmap'; const ruleTester = new RuleTester({ env: { es6: true } }); const rule = require('rules/namespace'); - function error(name, namespace) { return { message: `'${name}' not found in imported namespace '${namespace}'.` }; } @@ -14,13 +13,10 @@ const valid = [ test({ code: 'import "./malformed.js"' }), test({ code: "import * as foo from './empty-folder';" }), - test({ code: 'import * as names from "./named-exports"; ' + - 'console.log((names.b).c); ' }), + test({ code: 'import * as names from "./named-exports"; console.log((names.b).c); ' }), - test({ code: 'import * as names from "./named-exports"; ' + - 'console.log(names.a);' }), - test({ code: 'import * as names from "./re-export-names"; ' + - 'console.log(names.foo);' }), + test({ code: 'import * as names from "./named-exports"; console.log(names.a);' }), + test({ code: 'import * as names from "./re-export-names"; console.log(names.foo);' }), test({ code: "import * as elements from './jsx';", parserOptions: { @@ -61,26 +57,23 @@ const valid = [ test({ code: "import * as foo from './common';" }), // destructuring namespaces - test({ code: 'import * as names from "./named-exports";' + - 'const { a } = names' }), - test({ code: 'import * as names from "./named-exports";' + - 'const { d: c } = names' }), - test({ code: 'import * as names from "./named-exports";' + - 'const { c } = foo\n' + - ' , { length } = "names"\n' + - ' , alt = names' }), + test({ code: 'import * as names from "./named-exports"; const { a } = names' }), + test({ code: 'import * as names from "./named-exports"; const { d: c } = names' }), + test({ + code: ` + import * as names from "./named-exports"; + const { c } = foo, + { length } = "names", + alt = names; + `, + }), // deep destructuring only cares about top level - test({ code: 'import * as names from "./named-exports";' + - 'const { ExportedClass: { length } } = names' }), + test({ code: 'import * as names from "./named-exports"; const { ExportedClass: { length } } = names' }), // detect scope redefinition - test({ code: 'import * as names from "./named-exports";' + - 'function b(names) { const { c } = names }' }), - test({ code: 'import * as names from "./named-exports";' + - 'function b() { let names = null; const { c } = names }' }), - test({ code: 'import * as names from "./named-exports";' + - 'const x = function names() { const { c } = names }' }), - + test({ code: 'import * as names from "./named-exports"; function b(names) { const { c } = names }' }), + test({ code: 'import * as names from "./named-exports"; function b() { let names = null; const { c } = names }' }), + test({ code: 'import * as names from "./named-exports"; const x = function names() { const { c } = names }' }), ///////// // es7 // @@ -101,8 +94,7 @@ const valid = [ // respect hoisting test({ code: - 'function x() { console.log((names.b).c); } ' + - 'import * as names from "./named-exports"; ', + 'function x() { console.log((names.b).c); } import * as names from "./named-exports"; ', }), // names.default is valid export @@ -241,13 +233,11 @@ const valid = [ ]; const invalid = [].concat( - test({ code: "import * as names from './named-exports'; " + - ' console.log(names.c);', - errors: [error('c', 'names')] }), + test({ code: "import * as names from './named-exports'; console.log(names.c)", + errors: [error('c', 'names')] }), - test({ code: "import * as names from './named-exports';" + - " console.log(names['a']);", - errors: ["Unable to validate computed reference to imported namespace 'names'."] }), + test({ code: "import * as names from './named-exports'; console.log(names['a']);", + errors: ["Unable to validate computed reference to imported namespace 'names'."] }), // assignment warning (from no-reassign) test({ code: 'import * as foo from \'./bar\'; foo.foo = \'y\';', @@ -269,8 +259,7 @@ const invalid = [].concat( errors: [{ type: 'Property', message: "'c' not found in imported namespace 'names'." }], }), test({ - code: 'import * as names from "./named-exports";' + - 'const { c: { d } } = names', + code: 'import * as names from "./named-exports"; const { c: { d } } = names', errors: [{ type: 'Property', message: "'c' not found in imported namespace 'names'." }], }), @@ -300,15 +289,11 @@ const invalid = [].concat( // respect hoisting test({ - code: - 'console.log(names.c);' + - "import * as names from './named-exports'; ", + code: `console.log(names.c); import * as names from './named-exports';`, errors: [error('c', 'names')], }), test({ - code: - 'function x() { console.log(names.c) } ' + - "import * as names from './named-exports'; ", + code: `function x() { console.log(names.c) } import * as names from './named-exports';`, errors: [error('c', 'names')], }), @@ -340,12 +325,12 @@ const invalid = [].concat( errors: [ "'e' not found in deeply imported namespace 'b.c'." ], parserOptions: { ecmaVersion: 2022 }, })), -) +); /////////////////////// // deep dereferences // ////////////////////// -;[['deep', require.resolve('espree')], ['deep-es7', parsers.BABEL_OLD]].forEach(function ([folder, parser]) { // close over params +[['deep', require.resolve('espree')], ['deep-es7', parsers.BABEL_OLD]].forEach(function ([folder, parser]) { // close over params valid.push( test({ parser, code: `import * as a from "./${folder}/a"; console.log(a.b.c.d.e)` }), test({ parser, code: `import { b } from "./${folder}/a"; console.log(b.c.d.e)` }), diff --git a/tests/src/rules/newline-after-import.js b/tests/src/rules/newline-after-import.js index bf91064f8..5e14b570e 100644 --- a/tests/src/rules/newline-after-import.js +++ b/tests/src/rules/newline-after-import.js @@ -6,9 +6,7 @@ import { version as tsEslintVersion } from 'typescript-eslint-parser/package.jso import { getTSParsers, parsers, testVersion } from '../utils'; const IMPORT_ERROR_MESSAGE = 'Expected 1 empty line after import statement not followed by another import.'; -const IMPORT_ERROR_MESSAGE_MULTIPLE = (count) => { - return `Expected ${count} empty lines after import statement not followed by another import.`; -}; +const IMPORT_ERROR_MESSAGE_MULTIPLE = (count) => `Expected ${count} empty lines after import statement not followed by another import.`; const REQUIRE_ERROR_MESSAGE = 'Expected 1 empty line after require statement not followed by another require.'; const ruleTester = new RuleTester(); @@ -22,7 +20,7 @@ ruleTester.run('newline-after-import', require('rules/newline-after-import'), { code: ` const x = () => require('baz') , y = () => require('bar')`, - parserOptions: { ecmaVersion: 6 } , + parserOptions: { ecmaVersion: 6 }, }, { code: ` @@ -31,12 +29,12 @@ ruleTester.run('newline-after-import', require('rules/newline-after-import'), { // some comment here `, - parserOptions: { ecmaVersion: 6 } , + parserOptions: { ecmaVersion: 6 }, options: [{ considerComments: true }], }, { code: `const x = () => require('baz') && require('bar')`, - parserOptions: { ecmaVersion: 6 } , + parserOptions: { ecmaVersion: 6 }, }, { code: ` @@ -45,8 +43,8 @@ ruleTester.run('newline-after-import', require('rules/newline-after-import'), { // Some random single line comment var bar = 42; `, - parserOptions: { ecmaVersion: 6 } , - options: [{ 'considerComments': true }], + parserOptions: { ecmaVersion: 6 }, + options: [{ considerComments: true }], }, { code: ` @@ -57,7 +55,7 @@ ruleTester.run('newline-after-import', require('rules/newline-after-import'), { **/ var bar = 42; `, - parserOptions: { ecmaVersion: 6 } , + parserOptions: { ecmaVersion: 6 }, }, `function x() { require('baz'); }`, `a(require('b'), require('c'), require('d'));`, @@ -122,12 +120,12 @@ ruleTester.run('newline-after-import', require('rules/newline-after-import'), { { code: `import foo from 'foo';\n\n\nvar bar = 'bar';`, parserOptions: { ecmaVersion: 2015, sourceType: 'module' }, - options: [{ 'count': 2 }], + options: [{ count: 2 }], }, { code: `import foo from 'foo';\n\n\n\n\nvar bar = 'bar';`, parserOptions: { ecmaVersion: 2015, sourceType: 'module' }, - options: [{ 'count': 4 }], + options: [{ count: 4 }], }, { code: `var foo = require('foo-module');\n\nvar foo = 'bar';`, @@ -136,12 +134,12 @@ ruleTester.run('newline-after-import', require('rules/newline-after-import'), { { code: `var foo = require('foo-module');\n\n\nvar foo = 'bar';`, parserOptions: { ecmaVersion: 2015, sourceType: 'module' }, - options: [{ 'count': 2 }], + options: [{ count: 2 }], }, { code: `var foo = require('foo-module');\n\n\n\n\nvar foo = 'bar';`, parserOptions: { ecmaVersion: 2015, sourceType: 'module' }, - options: [{ 'count': 4 }], + options: [{ count: 4 }], }, { code: `require('foo-module');\n\nvar foo = 'bar';`, @@ -202,12 +200,12 @@ ruleTester.run('newline-after-import', require('rules/newline-after-import'), { parser: parsers.BABEL_OLD, }, { - code : `// issue 1004\nimport foo from 'foo';\n\n@SomeDecorator(foo)\nexport default class Test {}`, + code: `// issue 1004\nimport foo from 'foo';\n\n@SomeDecorator(foo)\nexport default class Test {}`, parserOptions: { sourceType: 'module' }, parser: parsers.BABEL_OLD, }, { - code : `// issue 1004\nconst foo = require('foo');\n\n@SomeDecorator(foo)\nexport default class Test {}`, + code: `// issue 1004\nconst foo = require('foo');\n\n@SomeDecorator(foo)\nexport default class Test {}`, parserOptions: { sourceType: 'module' }, parser: parsers.BABEL_OLD, }, @@ -296,7 +294,7 @@ ruleTester.run('newline-after-import', require('rules/newline-after-import'), { **/ var bar = 42; `, - parserOptions: { ecmaVersion: 2015, sourceType: 'module' } , + parserOptions: { ecmaVersion: 2015, sourceType: 'module' }, }, { code: ` @@ -308,8 +306,8 @@ ruleTester.run('newline-after-import', require('rules/newline-after-import'), { **/ var bar = 42; `, - parserOptions: { ecmaVersion: 2015, sourceType: 'module' } , - options: [{ 'considerComments': true }], + parserOptions: { ecmaVersion: 2015, sourceType: 'module' }, + options: [{ considerComments: true }], }, { code: ` @@ -319,7 +317,7 @@ ruleTester.run('newline-after-import', require('rules/newline-after-import'), { // Some random single line comment var bar = 42; `, - parserOptions: { ecmaVersion: 2015, sourceType: 'module' } , + parserOptions: { ecmaVersion: 2015, sourceType: 'module' }, }, ), @@ -344,7 +342,7 @@ ruleTester.run('newline-after-import', require('rules/newline-after-import'), { message: IMPORT_ERROR_MESSAGE, } ], parserOptions: { ecmaVersion: 2015, sourceType: 'module' }, - options: [{ 'considerComments': true }], + options: [{ considerComments: true }], }, { code: ` @@ -370,8 +368,8 @@ ruleTester.run('newline-after-import', require('rules/newline-after-import'), { column: 9, message: IMPORT_ERROR_MESSAGE, } ], - parserOptions: { ecmaVersion: 2015, sourceType: 'module' } , - options: [{ 'considerComments': true }], + parserOptions: { ecmaVersion: 2015, sourceType: 'module' }, + options: [{ considerComments: true }], }, { code: ` @@ -391,8 +389,8 @@ ruleTester.run('newline-after-import', require('rules/newline-after-import'), { column: 9, message: IMPORT_ERROR_MESSAGE, } ], - parserOptions: { ecmaVersion: 2015, sourceType: 'module' } , - options: [{ 'considerComments': true, 'count': 1 }], + parserOptions: { ecmaVersion: 2015, sourceType: 'module' }, + options: [{ considerComments: true, count: 1 }], }, { code: `import foo from 'foo';\nexport default function() {};`, @@ -407,7 +405,7 @@ ruleTester.run('newline-after-import', require('rules/newline-after-import'), { { code: `import foo from 'foo';\n\nexport default function() {};`, output: `import foo from 'foo';\n\n\nexport default function() {};`, - options: [{ 'count': 2 }], + options: [{ count: 2 }], errors: [ { line: 1, column: 1, @@ -428,7 +426,7 @@ ruleTester.run('newline-after-import', require('rules/newline-after-import'), { { code: `import foo from 'foo';\nexport default function() {};`, output: `import foo from 'foo';\n\nexport default function() {};`, - options: [{ 'count': 1 }], + options: [{ count: 1 }], errors: [ { line: 1, column: 1, diff --git a/tests/src/rules/no-commonjs.js b/tests/src/rules/no-commonjs.js index a2e3464ca..baa3b907f 100644 --- a/tests/src/rules/no-commonjs.js +++ b/tests/src/rules/no-commonjs.js @@ -19,12 +19,12 @@ ruleTester.run('no-commonjs', require('rules/no-commonjs'), { { code: 'export default "x"', parserOptions: { ecmaVersion: 2015, sourceType: 'module' } }, { code: 'export function house() {}', parserOptions: { ecmaVersion: 2015, sourceType: 'module' } }, { - code: - 'function someFunc() {\n'+ - ' const exports = someComputation();\n'+ - '\n'+ - ' expect(exports.someProp).toEqual({ a: \'value\' });\n'+ - '}', + code: ` + function someFunc() { + const exports = someComputation(); + expect(exports.someProp).toEqual({ a: 'value' }); + } + `, parserOptions: { ecmaVersion: 2015, sourceType: 'module' }, }, @@ -68,7 +68,7 @@ ruleTester.run('no-commonjs', require('rules/no-commonjs'), { invalid: [ // imports - ...(semver.satisfies(eslintPkg.version, '< 4.0.0') ? [] : [ + ...semver.satisfies(eslintPkg.version, '< 4.0.0') ? [] : [ { code: 'var x = require("x")', output: 'var x = require("x")', errors: [ { message: IMPORT_MESSAGE }] }, { code: 'x = require("x")', output: 'x = require("x")', errors: [ { message: IMPORT_MESSAGE }] }, { code: 'require("x")', output: 'require("x")', errors: [ { message: IMPORT_MESSAGE }] }, @@ -93,7 +93,7 @@ ruleTester.run('no-commonjs', require('rules/no-commonjs'), { output: 'try { require("x") } catch (error) {}', errors: [ { message: IMPORT_MESSAGE }], }, - ]), + ], // exports { code: 'exports.face = "palm"', output: 'exports.face = "palm"', errors: [ { message: EXPORT_MESSAGE }] }, diff --git a/tests/src/rules/no-cycle.js b/tests/src/rules/no-cycle.js index 155f257b7..d2adbf61f 100644 --- a/tests/src/rules/no-cycle.js +++ b/tests/src/rules/no-cycle.js @@ -6,9 +6,9 @@ import flatMap from 'array.prototype.flatmap'; const ruleTester = new RuleTester(); const rule = require('rules/no-cycle'); -const error = message => ({ message }); +const error = (message) => ({ message }); -const test = def => _test(Object.assign(def, { +const test = (def) => _test(Object.assign(def, { filename: testFilePath('./cycles/depth-zero.js'), })); const testVersion = (specifier, t) => _testVersion(specifier, () => Object.assign(t(), { diff --git a/tests/src/rules/no-deprecated.js b/tests/src/rules/no-deprecated.js index 290946735..318ea7c36 100644 --- a/tests/src/rules/no-deprecated.js +++ b/tests/src/rules/no-deprecated.js @@ -38,7 +38,6 @@ ruleTester.run('no-deprecated', rule, { code: "import { deepDep } from './deep-deprecated'; function x(deepDep) { console.log(deepDep.MY_TERRIBLE_ACTION) }", }), - ...SYNTAX_CASES, ], invalid: [ @@ -210,18 +209,20 @@ describe('TypeScript', function () { ruleTester.run(parser, rule, { valid: [ - test(Object.assign({ + test({ code: 'import * as hasDeprecated from \'./ts-deprecated.ts\'', - }, parserConfig)), + ...parserConfig, + }), ], invalid: [ - test(Object.assign({ + test({ code: 'import { foo } from \'./ts-deprecated.ts\'; console.log(foo())', errors: [ { type: 'ImportSpecifier', message: 'Deprecated: don\'t use this!' }, { type: 'Identifier', message: 'Deprecated: don\'t use this!' }, - ] }, - parserConfig)), + ], + ...parserConfig, + }), ], }); }); diff --git a/tests/src/rules/no-duplicates.js b/tests/src/rules/no-duplicates.js index ac76c3070..33e1e632e 100644 --- a/tests/src/rules/no-duplicates.js +++ b/tests/src/rules/no-duplicates.js @@ -12,7 +12,7 @@ const rule = require('rules/no-duplicates'); // autofix only possible with eslint 4+ const test = semver.satisfies(eslintPkg.version, '< 4') - ? t => testUtil(Object.assign({}, t, { output: t.code })) + ? (t) => testUtil({ ...t, output: t.code }) : testUtil; ruleTester.run('no-duplicates', rule, { @@ -22,8 +22,7 @@ ruleTester.run('no-duplicates', rule, { test({ code: "import { x } from './foo'; import { y } from './bar'" }), // #86: every unresolved module should not show up as 'null' and duplicate - test({ code: 'import foo from "234artaf";' + - 'import { shoop } from "234q25ad"' }), + test({ code: 'import foo from "234artaf"; import { shoop } from "234q25ad"' }), // #225: ignore duplicate if is a flow type import test({ @@ -34,12 +33,12 @@ ruleTester.run('no-duplicates', rule, { // #1107: Using different query strings that trigger different webpack loaders. test({ code: "import x from './bar?optionX'; import y from './bar?optionY';", - options: [{ 'considerQueryString': true }], + options: [{ considerQueryString: true }], settings: { 'import/resolver': 'webpack' }, }), test({ code: "import x from './foo'; import y from './bar';", - options: [{ 'considerQueryString': true }], + options: [{ considerQueryString: true }], settings: { 'import/resolver': 'webpack' }, }), @@ -68,10 +67,11 @@ ruleTester.run('no-duplicates', rule, { test({ code: "import { x } from './bar'; import { y } from 'bar';", output: "import { x , y } from './bar'; ", - settings: { 'import/resolve': { - paths: [path.join( process.cwd() - , 'tests', 'files', - )] } }, + settings: { + 'import/resolve': { + paths: [path.join(process.cwd(), 'tests', 'files')], + }, + }, errors: 2, // path ends up hardcoded }), @@ -90,7 +90,7 @@ ruleTester.run('no-duplicates', rule, { // #1107: Using same query strings that trigger the same loader. test({ code: "import x from './bar?optionX'; import y from './bar.js?optionX';", - options: [{ 'considerQueryString': true }], + options: [{ considerQueryString: true }], settings: { 'import/resolver': 'webpack' }, errors: 2, // path ends up hardcoded }), @@ -132,8 +132,8 @@ ruleTester.run('no-duplicates', rule, { }), // These test cases use duplicate import identifiers, which causes a fatal parsing error using ESPREE (default) and TS_OLD. - ...flatMap([parsers.BABEL_OLD, parsers.TS_NEW], parser => { - if (!parser) return []; // TS_NEW is not always available + ...flatMap([parsers.BABEL_OLD, parsers.TS_NEW], (parser) => { + if (!parser) { return []; } // TS_NEW is not always available return [ // #2347: duplicate identifiers should be removed test({ diff --git a/tests/src/rules/no-dynamic-require.js b/tests/src/rules/no-dynamic-require.js index 0b141ccd7..e316470ec 100644 --- a/tests/src/rules/no-dynamic-require.js +++ b/tests/src/rules/no-dynamic-require.js @@ -30,10 +30,9 @@ ruleTester.run('no-dynamic-require', rule, { //dynamic import ...flatMap([parsers.ESPREE, parsers.BABEL_OLD], (parser) => { - const _test = - parser === parsers.ESPREE - ? (testObj) => testVersion('>= 6.2.0', () => testObj) - : (testObj) => test(testObj); + const _test = parser === parsers.ESPREE + ? (testObj) => testVersion('>= 6.2.0', () => testObj) + : (testObj) => test(testObj); return [].concat( _test({ code: 'import("foo")', @@ -143,10 +142,9 @@ ruleTester.run('no-dynamic-require', rule, { // dynamic import ...flatMap([parsers.ESPREE, parsers.BABEL_OLD], (parser) => { - const _test = - parser === parsers.ESPREE - ? (testObj) => testVersion('>= 6.2.0', () => testObj) - : (testObj) => test(testObj); + const _test = parser === parsers.ESPREE + ? (testObj) => testVersion('>= 6.2.0', () => testObj) + : (testObj) => test(testObj); return [].concat( _test({ code: 'import("../" + name)', diff --git a/tests/src/rules/no-empty-named-blocks.js b/tests/src/rules/no-empty-named-blocks.js index 87a0a3e7c..f65e5a204 100644 --- a/tests/src/rules/no-empty-named-blocks.js +++ b/tests/src/rules/no-empty-named-blocks.js @@ -5,9 +5,8 @@ import { RuleTester } from 'eslint'; const ruleTester = new RuleTester(); const rule = require('rules/no-empty-named-blocks'); - function generateSuggestionsTestCases(cases, parser) { - return cases.map(code => test({ + return cases.map((code) => test({ code, parser, errors: [{ diff --git a/tests/src/rules/no-extraneous-dependencies.js b/tests/src/rules/no-extraneous-dependencies.js index 84aa8bb35..6f4e710f9 100644 --- a/tests/src/rules/no-extraneous-dependencies.js +++ b/tests/src/rules/no-extraneous-dependencies.js @@ -308,7 +308,7 @@ ruleTester.run('no-extraneous-dependencies', rule, { code: 'import foo from "foo"', options: [{ packageDir: packageDirWithSyntaxError }], errors: [{ - message: 'The package.json file could not be parsed: ' + packageFileWithSyntaxErrorMessage, + message: `The package.json file could not be parsed: ${packageFileWithSyntaxErrorMessage}`, }], }), test({ @@ -422,31 +422,29 @@ describe('TypeScript', () => { ruleTester.run('no-extraneous-dependencies', rule, { valid: [ - test(Object.assign({ + test({ code: 'import type T from "a";', options: [{ packageDir: packageDirWithTypescriptDevDependencies, devDependencies: false }], - }, parserConfig)), + ...parserConfig, + }), ], invalid: [ - test(Object.assign({ + test({ code: 'import T from "a";', options: [{ packageDir: packageDirWithTypescriptDevDependencies, devDependencies: false }], - errors: [{ - message: "'a' should be listed in the project's dependencies, not devDependencies.", - }], - }, parserConfig)), + errors: [{ message: "'a' should be listed in the project's dependencies, not devDependencies." }], + ...parserConfig, + }), - test(Object.assign({ - code: 'import type T from "a";', + test({ code: 'import type T from "a";', options: [{ packageDir: packageDirWithTypescriptDevDependencies, devDependencies: false, includeTypes: true, }], - errors: [{ - message: "'a' should be listed in the project's dependencies, not devDependencies.", - }], - }, parserConfig)), + errors: [{ message: "'a' should be listed in the project's dependencies, not devDependencies." }], + ...parserConfig, + }), ], }); }); diff --git a/tests/src/rules/no-import-module-exports.js b/tests/src/rules/no-import-module-exports.js index 81faceba9..c2bf7ed13 100644 --- a/tests/src/rules/no-import-module-exports.js +++ b/tests/src/rules/no-import-module-exports.js @@ -9,8 +9,7 @@ const ruleTester = new RuleTester({ const rule = require('rules/no-import-module-exports'); const error = { - message: `Cannot use import declarations in modules that export using CommonJS ` + - `(module.exports = 'foo' or exports.bar = 'hi')`, + message: `Cannot use import declarations in modules that export using CommonJS (module.exports = 'foo' or exports.bar = 'hi')`, type: 'ImportDeclaration', }; diff --git a/tests/src/rules/no-named-as-default-member.js b/tests/src/rules/no-named-as-default-member.js index 53cba230b..1773176f4 100644 --- a/tests/src/rules/no-named-as-default-member.js +++ b/tests/src/rules/no-named-as-default-member.js @@ -25,40 +25,28 @@ ruleTester.run('no-named-as-default-member', rule, { test({ code: 'import bar from "./bar"; const foo = bar.foo;', errors: [{ - message: ( - 'Caution: `bar` also has a named export `foo`. ' + - 'Check if you meant to write `import {foo} from \'./bar\'` instead.' - ), + message: 'Caution: `bar` also has a named export `foo`. Check if you meant to write `import {foo} from \'./bar\'` instead.', type: 'MemberExpression', }], }), test({ code: 'import bar from "./bar"; bar.foo();', errors: [{ - message: ( - 'Caution: `bar` also has a named export `foo`. ' + - 'Check if you meant to write `import {foo} from \'./bar\'` instead.' - ), + message: 'Caution: `bar` also has a named export `foo`. Check if you meant to write `import {foo} from \'./bar\'` instead.', type: 'MemberExpression', }], }), test({ code: 'import bar from "./bar"; const {foo} = bar;', errors: [{ - message: ( - 'Caution: `bar` also has a named export `foo`. ' + - 'Check if you meant to write `import {foo} from \'./bar\'` instead.' - ), + message: 'Caution: `bar` also has a named export `foo`. Check if you meant to write `import {foo} from \'./bar\'` instead.', type: 'Identifier', }], }), test({ code: 'import bar from "./bar"; const {foo: foo2, baz} = bar;', errors: [{ - message: ( - 'Caution: `bar` also has a named export `foo`. ' + - 'Check if you meant to write `import {foo} from \'./bar\'` instead.' - ), + message: 'Caution: `bar` also has a named export `foo`. Check if you meant to write `import {foo} from \'./bar\'` instead.', type: 'Identifier', }], }), @@ -66,10 +54,7 @@ ruleTester.run('no-named-as-default-member', rule, { testVersion('>= 8.7', () => ({ code: 'import bar from "./export-default-string-and-named"; const foo = bar.foo;', errors: [{ - message: ( - 'Caution: `bar` also has a named export `foo`. ' + - 'Check if you meant to write `import {foo} from \'./export-default-string-and-named\'` instead.' - ), + message: 'Caution: `bar` also has a named export `foo`. Check if you meant to write `import {foo} from \'./export-default-string-and-named\'` instead.', type: 'MemberExpression', }], parserOptions: { ecmaVersion: 2022 }, diff --git a/tests/src/rules/no-nodejs-modules.js b/tests/src/rules/no-nodejs-modules.js index 9be605709..b25eb0ce8 100644 --- a/tests/src/rules/no-nodejs-modules.js +++ b/tests/src/rules/no-nodejs-modules.js @@ -6,7 +6,7 @@ const isCore = require('is-core-module'); const ruleTester = new RuleTester(); const rule = require('rules/no-nodejs-modules'); -const error = message => ({ +const error = (message) => ({ message, }); @@ -69,7 +69,7 @@ ruleTester.run('no-nodejs-modules', rule, { allow: ['node:events'], }], }), - ]: [], + ] : [], isCore('node:path') ? [ test({ code: 'import path from "node:path"', diff --git a/tests/src/rules/no-relative-parent-imports.js b/tests/src/rules/no-relative-parent-imports.js index 305049802..bfd4e16bc 100644 --- a/tests/src/rules/no-relative-parent-imports.js +++ b/tests/src/rules/no-relative-parent-imports.js @@ -2,7 +2,7 @@ import { RuleTester } from 'eslint'; import rule from 'rules/no-relative-parent-imports'; import { parsers, test as _test, testFilePath } from '../utils'; -const test = def => _test(Object.assign(def, { +const test = (def) => _test(Object.assign(def, { filename: testFilePath('./internal-modules/plugins/plugin2/index.js'), parser: parsers.BABEL_OLD, })); diff --git a/tests/src/rules/no-restricted-paths.js b/tests/src/rules/no-restricted-paths.js index 81182189f..a83a804a0 100644 --- a/tests/src/rules/no-restricted-paths.js +++ b/tests/src/rules/no-restricted-paths.js @@ -713,7 +713,7 @@ ruleTester.run('no-restricted-paths', rule, { }); context('Typescript', function () { - getTSParsers().forEach(parser => { + getTSParsers().forEach((parser) => { const settings = { 'import/parsers': { [parser]: ['.ts'] }, 'import/resolver': { 'eslint-import-resolver-typescript': true }, @@ -933,8 +933,7 @@ context('Typescript', function () { }], }], errors: [{ - message: 'Restricted path exceptions must be descendants of the configured ' + - '`from` path for that zone.', + message: 'Restricted path exceptions must be descendants of the configured `from` path for that zone.', line: 1, column: 20, }], diff --git a/tests/src/rules/no-unassigned-import.js b/tests/src/rules/no-unassigned-import.js index 8724b80d3..f96808cbc 100644 --- a/tests/src/rules/no-unassigned-import.js +++ b/tests/src/rules/no-unassigned-import.js @@ -29,48 +29,48 @@ ruleTester.run('no-unassigned-import', rule, { test({ code: 'require("lodash")()' }), test({ code: 'import "app.css"', - options: [{ 'allow': ['**/*.css'] }], + options: [{ allow: ['**/*.css'] }], }), test({ code: 'import "app.css";', - options: [{ 'allow': ['*.css'] }], + options: [{ allow: ['*.css'] }], }), test({ code: 'import "./app.css"', - options: [{ 'allow': ['**/*.css'] }], + options: [{ allow: ['**/*.css'] }], }), test({ code: 'import "foo/bar"', - options: [{ 'allow': ['foo/**'] }], + options: [{ allow: ['foo/**'] }], }), test({ code: 'import "foo/bar"', - options: [{ 'allow': ['foo/bar'] }], + options: [{ allow: ['foo/bar'] }], }), test({ code: 'import "../dir/app.css"', - options: [{ 'allow': ['**/*.css'] }], + options: [{ allow: ['**/*.css'] }], }), test({ code: 'import "../dir/app.js"', - options: [{ 'allow': ['**/dir/**'] }], + options: [{ allow: ['**/dir/**'] }], }), test({ code: 'require("./app.css")', - options: [{ 'allow': ['**/*.css'] }], + options: [{ allow: ['**/*.css'] }], }), test({ code: 'import "babel-register"', - options: [{ 'allow': ['babel-register'] }], + options: [{ allow: ['babel-register'] }], }), test({ code: 'import "./styles/app.css"', - options: [{ 'allow': ['src/styles/**'] }], + options: [{ allow: ['src/styles/**'] }], filename: path.join(process.cwd(), 'src/app.js'), }), test({ code: 'import "../scripts/register.js"', - options: [{ 'allow': ['src/styles/**', '**/scripts/*.js'] }], + options: [{ allow: ['src/styles/**', '**/scripts/*.js'] }], filename: path.join(process.cwd(), 'src/app.js'), }), ], @@ -85,22 +85,22 @@ ruleTester.run('no-unassigned-import', rule, { }), test({ code: 'import "./app.css"', - options: [{ 'allow': ['**/*.js'] }], + options: [{ allow: ['**/*.js'] }], errors: [error], }), test({ code: 'import "./app.css"', - options: [{ 'allow': ['**/dir/**'] }], + options: [{ allow: ['**/dir/**'] }], errors: [error], }), test({ code: 'require("./app.css")', - options: [{ 'allow': ['**/*.js'] }], + options: [{ allow: ['**/*.js'] }], errors: [error], }), test({ code: 'import "./styles/app.css"', - options: [{ 'allow': ['styles/*.css'] }], + options: [{ allow: ['styles/*.css'] }], filename: path.join(process.cwd(), 'src/app.js'), errors: [error], }), diff --git a/tests/src/rules/no-unresolved.js b/tests/src/rules/no-unresolved.js index 024e8965a..109099c38 100644 --- a/tests/src/rules/no-unresolved.js +++ b/tests/src/rules/no-unresolved.js @@ -17,7 +17,7 @@ function runResolverTests(resolver) { ...specs, settings: { ...specs.settings, - 'import/resolver': resolver, + 'import/resolver': resolver, 'import/cache': { lifetime: 0 }, }, }); @@ -161,7 +161,7 @@ function runResolverTests(resolver) { message: "Unable to resolve path to module './empty-folder'.", type: 'Literal', }, - ], + ], }), // sanity check that this module is _not_ found without proper settings @@ -185,7 +185,7 @@ function runResolverTests(resolver) { parser: parsers.BABEL_OLD, }), - rest({ + rest({ code: 'export { foo } from "./does-not-exist"', errors: ["Unable to resolve path to module './does-not-exist'."], }), @@ -359,7 +359,7 @@ ruleTester.run('no-unresolved (import/resolve legacy)', rule, { code: "import { DEEP } from 'in-alternate-root';", settings: { 'import/resolve': { - 'paths': [ + paths: [ path.join(process.cwd(), 'tests', 'files', 'alternate-root'), ], }, @@ -373,14 +373,14 @@ ruleTester.run('no-unresolved (import/resolve legacy)', rule, { paths: [ path.join('tests', 'files', 'src-root'), path.join('tests', 'files', 'alternate-root'), - ], + ], }, }, }), test({ code: 'import * as foo from "jsx-module/foo"', - settings: { 'import/resolve': { 'extensions': ['.jsx'] } }, + settings: { 'import/resolve': { extensions: ['.jsx'] } }, }), ], @@ -417,7 +417,6 @@ ruleTester.run('no-unresolved (webpack-specific)', rule, { ], }); - ruleTester.run('no-unresolved ignore list', rule, { valid: [ test({ @@ -440,7 +439,7 @@ ruleTester.run('no-unresolved ignore list', rule, { }), ], - invalid:[ + invalid: [ test({ code: 'import "./test.gif"', options: [{ ignore: ['.png$'] }], @@ -458,7 +457,7 @@ ruleTester.run('no-unresolved ignore list', rule, { ruleTester.run('no-unresolved unknown resolver', rule, { valid: [], - invalid:[ + invalid: [ // logs resolver load error test({ @@ -490,7 +489,7 @@ ruleTester.run('no-unresolved electron', rule, { settings: { 'import/core-modules': ['electron'] }, }), ], - invalid:[ + invalid: [ test({ code: 'import "electron"', errors: [`Unable to resolve path to module 'electron'.`], @@ -500,7 +499,7 @@ ruleTester.run('no-unresolved electron', rule, { ruleTester.run('no-unresolved syntax verification', rule, { valid: SYNTAX_CASES, - invalid:[], + invalid: [], }); // https://github.com/import-js/eslint-plugin-import/issues/2024 @@ -522,7 +521,7 @@ ruleTester.run('import() with built-in parser', rule, { context('TypeScript', () => { // Type-only imports were added in TypeScript ESTree 2.23.0 - getTSParsers().filter(x => x !== parsers.TS_OLD).forEach((parser) => { + getTSParsers().filter((x) => x !== parsers.TS_OLD).forEach((parser) => { ruleTester.run(`${parser}: no-unresolved ignore type-only`, rule, { valid: [ test({ diff --git a/tests/src/rules/no-unused-modules.js b/tests/src/rules/no-unused-modules.js index 87714b599..936123ab7 100644 --- a/tests/src/rules/no-unused-modules.js +++ b/tests/src/rules/no-unused-modules.js @@ -20,7 +20,7 @@ const typescriptRuleTester = new RuleTester(typescriptConfig); const jsxRuleTester = new RuleTester(jsxConfig); const rule = require('rules/no-unused-modules'); -const error = message => ({ message }); +const error = (message) => ({ message }); const missingExportsOptions = [{ missingExports: true, @@ -109,7 +109,6 @@ ruleTester.run('no-unused-modules', rule, { ], }); - // tests for exports ruleTester.run('no-unused-modules', rule, { valid: [ @@ -247,7 +246,6 @@ ruleTester.run('no-unused-modules', rule, { ], }); - describe('dynamic imports', function () { if (semver.satisfies(eslintPkg.version, '< 6')) { beforeEach(function () { @@ -817,7 +815,6 @@ describe('test behavior for new file', () => { ], }); - describe('test behavior for new file', () => { before(() => { fs.writeFileSync(testFilePath('./no-unused-modules/file-added-1.js'), '', { encoding: 'utf8' }); @@ -1382,7 +1379,7 @@ describe('supports flat eslint', { skip: !FlatRuleTester }, () => { flatRuleTester.run('no-unused-modules', rule, { valid: [{ options: unusedExportsOptions, - code: 'import { o2 } from "./file-o";export default () => 12', + code: 'import { o2 } from "./file-o"; export default () => 12', filename: testFilePath('./no-unused-modules/file-a.js'), }], invalid: [{ diff --git a/tests/src/rules/no-webpack-loader-syntax.js b/tests/src/rules/no-webpack-loader-syntax.js index 2b841e18a..05ad242f5 100644 --- a/tests/src/rules/no-webpack-loader-syntax.js +++ b/tests/src/rules/no-webpack-loader-syntax.js @@ -88,12 +88,8 @@ context('TypeScript', function () { if (!(parser === parsers.TS_NEW && semver.satisfies(require('@typescript-eslint/parser/package.json').version, '>= 5'))) { ruleTester.run('no-webpack-loader-syntax', rule, { valid: [ - test(Object.assign({ - code: 'import { foo } from\nalert()', - }, parserConfig)), - test(Object.assign({ - code: 'import foo from\nalert()', - }, parserConfig)), + test({ code: 'import { foo } from\nalert()', ...parserConfig }), + test({ code: 'import foo from\nalert()', ...parserConfig }), ], invalid: [], }); diff --git a/tests/src/rules/order.js b/tests/src/rules/order.js index 291dae33b..8d0b315e7 100644 --- a/tests/src/rules/order.js +++ b/tests/src/rules/order.js @@ -7,7 +7,6 @@ import flatMap from 'array.prototype.flatmap'; import { resolve } from 'path'; import { default as babelPresetFlow } from 'babel-preset-flow'; - const ruleTester = new RuleTester(); const flowRuleTester = new RuleTester({ parser: resolve(__dirname, '../../../node_modules/babel-eslint'), @@ -22,7 +21,7 @@ const flowRuleTester = new RuleTester({ const rule = require('rules/order'); function withoutAutofixOutput(test) { - return Object.assign({}, test, { output: test.code }); + return { ...test, output: test.code }; } ruleTester.run('order', rule, { @@ -193,7 +192,7 @@ ruleTester.run('order', rule, { var index = require('./'); `, }), - ...flatMap(getTSParsers(), parser => [ + ...flatMap(getTSParsers(), (parser) => [ // Export equals expressions should be on top alongside with ordinary import-statements. test({ code: ` @@ -829,7 +828,7 @@ ruleTester.run('order', rule, { pathGroupsExcludedImportTypes: [], }], }), - ...flatMap(getTSParsers, parser => [ + ...flatMap(getTSParsers, (parser) => [ // Order of the `import ... = require(...)` syntax test({ code: ` @@ -950,18 +949,18 @@ ruleTester.run('order', rule, { options: [ { 'newlines-between': 'always', - 'distinctGroup': true, - 'pathGroupsExcludedImportTypes': [], - 'pathGroups': [ + distinctGroup: true, + pathGroupsExcludedImportTypes: [], + pathGroups: [ { - 'pattern': 'a', - 'group': 'external', - 'position': 'before', + pattern: 'a', + group: 'external', + position: 'before', }, { - 'pattern': 'b', - 'group': 'external', - 'position': 'after', + pattern: 'b', + group: 'external', + position: 'after', }, ], }, @@ -977,18 +976,18 @@ ruleTester.run('order', rule, { options: [ { 'newlines-between': 'always', - 'distinctGroup': false, - 'pathGroupsExcludedImportTypes': [], - 'pathGroups': [ + distinctGroup: false, + pathGroupsExcludedImportTypes: [], + pathGroups: [ { - 'pattern': 'a', - 'group': 'external', - 'position': 'before', + pattern: 'a', + group: 'external', + position: 'before', }, { - 'pattern': 'b', - 'group': 'external', - 'position': 'after', + pattern: 'b', + group: 'external', + position: 'after', }, ], }, @@ -1005,17 +1004,17 @@ ruleTester.run('order', rule, { options: [ { 'newlines-between': 'always', - 'distinctGroup': false, - 'pathGroupsExcludedImportTypes': [], - 'pathGroups': [ + distinctGroup: false, + pathGroupsExcludedImportTypes: [], + pathGroups: [ { - 'pattern': 'a', - 'group': 'external', + pattern: 'a', + group: 'external', }, { - 'pattern': 'b', - 'group': 'internal', - 'position': 'before', + pattern: 'b', + group: 'internal', + position: 'before', }, ], }, @@ -1041,53 +1040,53 @@ ruleTester.run('order', rule, { `, options: [ { - 'alphabetize': { - 'caseInsensitive': false, - 'order': 'asc', + alphabetize: { + caseInsensitive: false, + order: 'asc', }, 'newlines-between': 'always', - 'groups': [ + groups: [ ['builtin', 'external', 'internal', 'unknown', 'object', 'type'], 'parent', ['sibling', 'index'], ], - 'distinctGroup': false, - 'pathGroupsExcludedImportTypes': [], - 'pathGroups': [ + distinctGroup: false, + pathGroupsExcludedImportTypes: [], + pathGroups: [ { - 'pattern': './', - 'group': 'sibling', - 'position': 'before', + pattern: './', + group: 'sibling', + position: 'before', }, { - 'pattern': '.', - 'group': 'sibling', - 'position': 'before', + pattern: '.', + group: 'sibling', + position: 'before', }, { - 'pattern': '..', - 'group': 'parent', - 'position': 'before', + pattern: '..', + group: 'parent', + position: 'before', }, { - 'pattern': '../', - 'group': 'parent', - 'position': 'before', + pattern: '../', + group: 'parent', + position: 'before', }, { - 'pattern': '[a-z]*', - 'group': 'external', - 'position': 'before', + pattern: '[a-z]*', + group: 'external', + position: 'before', }, { - 'pattern': '../[a-z]*', - 'group': 'parent', - 'position': 'before', + pattern: '../[a-z]*', + group: 'parent', + position: 'before', }, { - 'pattern': './[a-z]*', - 'group': 'sibling', - 'position': 'before', + pattern: './[a-z]*', + group: 'sibling', + position: 'before', }, ], }, @@ -1101,7 +1100,7 @@ ruleTester.run('order', rule, { `, options: [ { - 'alphabetize': { order: 'asc', orderImportKind: 'asc', 'caseInsensitive': true }, + alphabetize: { order: 'asc', orderImportKind: 'asc', caseInsensitive: true }, }, ], }), @@ -1179,12 +1178,8 @@ ruleTester.run('order', rule, { }), // fix order with windows end of lines test({ - code: - `/* comment0 */ /* comment1 */ var async = require('async'); /* comment2 */` + `\r\n` + - `/* comment3 */ var fs = require('fs'); /* comment4 */` + `\r\n`, - output: - `/* comment3 */ var fs = require('fs'); /* comment4 */` + `\r\n` + - `/* comment0 */ /* comment1 */ var async = require('async'); /* comment2 */` + `\r\n`, + code: `/* comment0 */ /* comment1 */ var async = require('async'); /* comment2 */` + `\r\n` + `/* comment3 */ var fs = require('fs'); /* comment4 */` + `\r\n`, + output: `/* comment3 */ var fs = require('fs'); /* comment4 */` + `\r\n` + `/* comment0 */ /* comment1 */ var async = require('async'); /* comment2 */` + `\r\n`, errors: [{ message: '`fs` import should occur before import of `async`', }], @@ -1558,7 +1553,7 @@ ruleTester.run('order', rule, { message: '`fs` import should occur after import of `../foo/bar`', }], }), - ...flatMap(getTSParsers(), parser => [ + ...flatMap(getTSParsers(), (parser) => [ // Order of the `import ... = require(...)` syntax test({ code: ` @@ -2676,8 +2671,8 @@ ruleTester.run('order', rule, { options: [ { 'newlines-between': 'always', - 'distinctGroup': false, - 'pathGroupsExcludedImportTypes': [], + distinctGroup: false, + pathGroupsExcludedImportTypes: [], }, ], errors: [{ @@ -2698,18 +2693,18 @@ ruleTester.run('order', rule, { options: [ { 'newlines-between': 'always', - 'distinctGroup': false, - 'pathGroupsExcludedImportTypes': [], - 'pathGroups': [ + distinctGroup: false, + pathGroupsExcludedImportTypes: [], + pathGroups: [ { - 'pattern': 'a', - 'group': 'external', - 'position': 'before', + pattern: 'a', + group: 'external', + position: 'before', }, { - 'pattern': 'c', - 'group': 'external', - 'position': 'after', + pattern: 'c', + group: 'external', + position: 'after', }, ], }, @@ -2743,7 +2738,6 @@ ruleTester.run('order', rule, { ].filter((t) => !!t), }); - context('TypeScript', function () { getNonDefaultParsers() // Type-only imports were added in TypeScript ESTree 2.23.0 @@ -3182,7 +3176,7 @@ context('TypeScript', function () { `, errors: [{ message: '`fs` type import should occur before type import of `path`', - },{ + }, { message: '`fs` type import should occur before type import of `path`', }], ...parserConfig, @@ -3303,34 +3297,34 @@ flowRuleTester.run('order', rule, { `, options: [ { - 'groups': [ + groups: [ ['builtin', 'external'], 'internal', ['sibling', 'parent'], 'object', 'type', ], - 'pathGroups': [ + pathGroups: [ { - 'pattern': 'react', - 'group': 'builtin', - 'position': 'before', - 'patternOptions': { - 'matchBase': true, + pattern: 'react', + group: 'builtin', + position: 'before', + patternOptions: { + matchBase: true, }, }, { - 'pattern': '*.+(css|svg)', - 'group': 'type', - 'position': 'after', - 'patternOptions': { - 'matchBase': true, + pattern: '*.+(css|svg)', + group: 'type', + position: 'after', + patternOptions: { + matchBase: true, }, }, ], - 'pathGroupsExcludedImportTypes': ['react'], - 'alphabetize': { - 'order': 'asc', + pathGroupsExcludedImportTypes: ['react'], + alphabetize: { + order: 'asc', }, 'newlines-between': 'always', }, diff --git a/tests/src/rules/prefer-default-export.js b/tests/src/rules/prefer-default-export.js index ae7c16a40..a7310445b 100644 --- a/tests/src/rules/prefer-default-export.js +++ b/tests/src/rules/prefer-default-export.js @@ -362,15 +362,15 @@ context('TypeScript', function () { ...parserConfig, }), semver.satisfies(tsEslintVersion, '>= 22') ? test({ - code: 'export type foo = string /* ' + parser.replace(process.cwd(), '$$PWD') + '*/', + code: `export type foo = string /* ${parser.replace(process.cwd(), '$$PWD')}*/`, ...parserConfig, }) : [], semver.satisfies(tsEslintVersion, '> 20') ? test({ - code: 'export interface foo { bar: string; } /* ' + parser.replace(process.cwd(), '$$PWD') + '*/', + code: `export interface foo { bar: string; } /* ${parser.replace(process.cwd(), '$$PWD')}*/`, ...parserConfig, }) : [], test({ - code: 'export interface foo { bar: string; }; export function goo() {} /* ' + parser.replace(process.cwd(), '$$PWD') + '*/', + code: `export interface foo { bar: string; }; export function goo() {} /* ${parser.replace(process.cwd(), '$$PWD')}*/`, ...parserConfig, }), ), diff --git a/tests/src/utils.js b/tests/src/utils.js index b82883a6f..d5215b02e 100644 --- a/tests/src/utils.js +++ b/tests/src/utils.js @@ -50,14 +50,15 @@ export function test(t) { if (arguments.length !== 1) { throw new SyntaxError('`test` requires exactly one object argument'); } - return Object.assign({ + return { filename: FILENAME, - }, t, { - parserOptions: Object.assign({ + ...t, + parserOptions: { sourceType: 'module', ecmaVersion: 9, - }, t.parserOptions), - }); + ...t.parserOptions, + }, + }; } export function testContext(settings) { @@ -133,5 +134,4 @@ export const SYNTAX_CASES = [ test({ code: 'import { foo } from "./ignore.invalid.extension"', }), - ]; diff --git a/utils/ModuleCache.js b/utils/ModuleCache.js index a06616de9..4b1edc0ef 100644 --- a/utils/ModuleCache.js +++ b/utils/ModuleCache.js @@ -1,4 +1,5 @@ 'use strict'; + exports.__esModule = true; const log = require('debug')('eslint-module-utils:ModuleCache'); @@ -23,8 +24,10 @@ class ModuleCache { if (this.map.has(cacheKey)) { const f = this.map.get(cacheKey); // check freshness - if (process.hrtime(f.lastSeen)[0] < settings.lifetime) return f.result; - } else log('cache miss for', cacheKey); + if (process.hrtime(f.lastSeen)[0] < settings.lifetime) { return f.result; } + } else { + log('cache miss for', cacheKey); + } // cache miss return undefined; } diff --git a/utils/declaredScope.js b/utils/declaredScope.js index ded2131e4..dd2a20149 100644 --- a/utils/declaredScope.js +++ b/utils/declaredScope.js @@ -1,9 +1,10 @@ 'use strict'; + exports.__esModule = true; exports.default = function declaredScope(context, name) { const references = context.getScope().references; - const reference = references.find(x => x.identifier.name === name); - if (!reference) return undefined; + const reference = references.find((x) => x.identifier.name === name); + if (!reference) { return undefined; } return reference.resolved.scope.type; }; diff --git a/utils/hash.js b/utils/hash.js index fcf00de38..b9bff25bd 100644 --- a/utils/hash.js +++ b/utils/hash.js @@ -2,7 +2,9 @@ * utilities for hashing config objects. * basically iteratively updates hash with a JSON-like format */ + 'use strict'; + exports.__esModule = true; const createHash = require('crypto').createHash; @@ -10,7 +12,7 @@ const createHash = require('crypto').createHash; const stringify = JSON.stringify; function hashify(value, hash) { - if (!hash) hash = createHash('sha256'); + if (!hash) { hash = createHash('sha256'); } if (Array.isArray(value)) { hashArray(value, hash); @@ -25,7 +27,7 @@ function hashify(value, hash) { exports.default = hashify; function hashArray(array, hash) { - if (!hash) hash = createHash('sha256'); + if (!hash) { hash = createHash('sha256'); } hash.update('['); for (let i = 0; i < array.length; i++) { @@ -40,10 +42,10 @@ hashify.array = hashArray; exports.hashArray = hashArray; function hashObject(object, hash) { - if (!hash) hash = createHash('sha256'); + if (!hash) { hash = createHash('sha256'); } hash.update('{'); - Object.keys(object).sort().forEach(key => { + Object.keys(object).sort().forEach((key) => { hash.update(stringify(key)); hash.update(':'); hashify(object[key], hash); @@ -56,4 +58,3 @@ function hashObject(object, hash) { hashify.object = hashObject; exports.hashObject = hashObject; - diff --git a/utils/ignore.js b/utils/ignore.js index 32bbbc624..e41d1e5a5 100644 --- a/utils/ignore.js +++ b/utils/ignore.js @@ -1,4 +1,5 @@ 'use strict'; + exports.__esModule = true; const extname = require('path').extname; @@ -28,7 +29,7 @@ function makeValidExtensionSet(settings) { if (!Array.isArray(parserSettings)) { throw new TypeError('"settings" for ' + parser + ' must be an array'); } - parserSettings.forEach(ext => exts.add(ext)); + parserSettings.forEach((ext) => exts.add(ext)); } } @@ -38,9 +39,9 @@ exports.getFileExtensions = makeValidExtensionSet; exports.default = function ignore(path, context) { // check extension whitelist first (cheap) - if (!hasValidExtension(path, context)) return true; + if (!hasValidExtension(path, context)) { return true; } - if (!('import/ignore' in context.settings)) return false; + if (!('import/ignore' in context.settings)) { return false; } const ignoreStrings = context.settings['import/ignore']; for (let i = 0; i < ignoreStrings.length; i++) { diff --git a/utils/module-require.js b/utils/module-require.js index c03671ce5..96ef82ba5 100644 --- a/utils/module-require.js +++ b/utils/module-require.js @@ -1,4 +1,5 @@ 'use strict'; + exports.__esModule = true; const Module = require('module'); diff --git a/utils/moduleVisitor.js b/utils/moduleVisitor.js index 4d93a0199..c312ca2d4 100644 --- a/utils/moduleVisitor.js +++ b/utils/moduleVisitor.js @@ -1,4 +1,5 @@ 'use strict'; + exports.__esModule = true; /** @@ -16,14 +17,14 @@ exports.default = function visitModules(visitor, options) { let ignoreRegExps = []; if (options.ignore != null) { - ignoreRegExps = options.ignore.map(p => new RegExp(p)); + ignoreRegExps = options.ignore.map((p) => new RegExp(p)); } function checkSourceValue(source, importer) { - if (source == null) return; //? + if (source == null) { return; } //? // handle ignore - if (ignoreRegExps.some(re => re.test(source.value))) return; + if (ignoreRegExps.some((re) => re.test(source.value))) { return; } // fire visitor visitor(source, importer); @@ -41,14 +42,14 @@ exports.default = function visitModules(visitor, options) { if (node.type === 'ImportExpression') { modulePath = node.source; } else if (node.type === 'CallExpression') { - if (node.callee.type !== 'Import') return; - if (node.arguments.length !== 1) return; + if (node.callee.type !== 'Import') { return; } + if (node.arguments.length !== 1) { return; } modulePath = node.arguments[0]; } - if (modulePath.type !== 'Literal') return; - if (typeof modulePath.value !== 'string') return; + if (modulePath.type !== 'Literal') { return; } + if (typeof modulePath.value !== 'string') { return; } checkSourceValue(modulePath, node); } @@ -56,32 +57,35 @@ exports.default = function visitModules(visitor, options) { // for CommonJS `require` calls // adapted from @mctep: https://git.io/v4rAu function checkCommon(call) { - if (call.callee.type !== 'Identifier') return; - if (call.callee.name !== 'require') return; - if (call.arguments.length !== 1) return; + if (call.callee.type !== 'Identifier') { return; } + if (call.callee.name !== 'require') { return; } + if (call.arguments.length !== 1) { return; } const modulePath = call.arguments[0]; - if (modulePath.type !== 'Literal') return; - if (typeof modulePath.value !== 'string') return; + if (modulePath.type !== 'Literal') { return; } + if (typeof modulePath.value !== 'string') { return; } checkSourceValue(modulePath, call); } function checkAMD(call) { - if (call.callee.type !== 'Identifier') return; - if (call.callee.name !== 'require' && - call.callee.name !== 'define') return; - if (call.arguments.length !== 2) return; + if (call.callee.type !== 'Identifier') { return; } + if (call.callee.name !== 'require' && call.callee.name !== 'define') { return; } + if (call.arguments.length !== 2) { return; } const modules = call.arguments[0]; - if (modules.type !== 'ArrayExpression') return; + if (modules.type !== 'ArrayExpression') { return; } for (const element of modules.elements) { - if (element.type !== 'Literal') continue; - if (typeof element.value !== 'string') continue; + if (element.type !== 'Literal') { continue; } + if (typeof element.value !== 'string') { continue; } - if (element.value === 'require' || - element.value === 'exports') continue; // magic modules: https://github.com/requirejs/requirejs/wiki/Differences-between-the-simplified-CommonJS-wrapper-and-standard-AMD-define#magic-modules + if ( + element.value === 'require' + || element.value === 'exports' + ) { + continue; // magic modules: https://github.com/requirejs/requirejs/wiki/Differences-between-the-simplified-CommonJS-wrapper-and-standard-AMD-define#magic-modules + } checkSourceValue(element, element); } @@ -90,20 +94,20 @@ exports.default = function visitModules(visitor, options) { const visitors = {}; if (options.esmodule) { Object.assign(visitors, { - 'ImportDeclaration': checkSource, - 'ExportNamedDeclaration': checkSource, - 'ExportAllDeclaration': checkSource, - 'CallExpression': checkImportCall, - 'ImportExpression': checkImportCall, + ImportDeclaration: checkSource, + ExportNamedDeclaration: checkSource, + ExportAllDeclaration: checkSource, + CallExpression: checkImportCall, + ImportExpression: checkImportCall, }); } if (options.commonjs || options.amd) { - const currentCallExpression = visitors['CallExpression']; - visitors['CallExpression'] = function (call) { - if (currentCallExpression) currentCallExpression(call); - if (options.commonjs) checkCommon(call); - if (options.amd) checkAMD(call); + const currentCallExpression = visitors.CallExpression; + visitors.CallExpression = function (call) { + if (currentCallExpression) { currentCallExpression(call); } + if (options.commonjs) { checkCommon(call); } + if (options.amd) { checkAMD(call); } }; } @@ -116,19 +120,19 @@ exports.default = function visitModules(visitor, options) { */ function makeOptionsSchema(additionalProperties) { const base = { - 'type': 'object', - 'properties': { - 'commonjs': { 'type': 'boolean' }, - 'amd': { 'type': 'boolean' }, - 'esmodule': { 'type': 'boolean' }, - 'ignore': { - 'type': 'array', - 'minItems': 1, - 'items': { 'type': 'string' }, - 'uniqueItems': true, + type: 'object', + properties: { + commonjs: { type: 'boolean' }, + amd: { type: 'boolean' }, + esmodule: { type: 'boolean' }, + ignore: { + type: 'array', + minItems: 1, + items: { type: 'string' }, + uniqueItems: true, }, }, - 'additionalProperties': false, + additionalProperties: false, }; if (additionalProperties) { diff --git a/utils/parse.js b/utils/parse.js index dd0746aaa..7646b3177 100644 --- a/utils/parse.js +++ b/utils/parse.js @@ -1,4 +1,5 @@ 'use strict'; + exports.__esModule = true; const moduleRequire = require('./module-require').default; @@ -23,10 +24,10 @@ function keysFromParser(parserPath, parserInstance, parsedResult) { if (parsedResult && parsedResult.visitorKeys) { return parsedResult.visitorKeys; } - if (typeof parserPath === 'string' && /.*espree.*/.test(parserPath)) { + if (typeof parserPath === 'string' && (/.*espree.*/).test(parserPath)) { return parserInstance.VisitorKeys; } - if (typeof parserPath === 'string' && /.*babel-eslint.*/.test(parserPath)) { + if (typeof parserPath === 'string' && (/.*babel-eslint.*/).test(parserPath)) { return getBabelEslintVisitorKeys(parserPath); } return null; @@ -51,13 +52,13 @@ function transformHashbang(text) { } exports.default = function parse(path, content, context) { - if (context == null) throw new Error('need context to parse properly'); + if (context == null) { throw new Error('need context to parse properly'); } // ESLint in "flat" mode only sets context.languageOptions.parserOptions - let parserOptions = (context.languageOptions && context.languageOptions.parserOptions) || context.parserOptions; + let parserOptions = context.languageOptions && context.languageOptions.parserOptions || context.parserOptions; const parserOrPath = getParser(path, context); - if (!parserOrPath) throw new Error('parserPath or languageOptions.parser is required!'); + if (!parserOrPath) { throw new Error('parserPath or languageOptions.parser is required!'); } // hack: espree blows up with frozen options parserOptions = Object.assign({}, parserOptions); @@ -103,9 +104,8 @@ exports.default = function parse(path, content, context) { } if (!ast || typeof ast !== 'object') { console.warn( - '`parseForESLint` from parser `' + - (typeof parserOrPath === 'string' ? parserOrPath : '`context.languageOptions.parser`') + // Can only be invalid for custom parser per imports/parser - '` is invalid and will just be ignored' + // Can only be invalid for custom parser per imports/parser + '`parseForESLint` from parser `' + (typeof parserOrPath === 'string' ? parserOrPath : '`context.languageOptions.parser`') + '` is invalid and will just be ignored' ); } else { return makeParseReturn(ast, keysFromParser(parserOrPath, parser, undefined)); diff --git a/utils/pkgUp.js b/utils/pkgUp.js index 049869719..889f62265 100644 --- a/utils/pkgUp.js +++ b/utils/pkgUp.js @@ -1,4 +1,5 @@ 'use strict'; + exports.__esModule = true; const fs = require('fs'); @@ -6,22 +7,22 @@ const path = require('path'); /** * Derived significantly from package find-up@2.0.0. See license below. - * + * * @copyright Sindre Sorhus * MIT License * * Copyright (c) Sindre Sorhus (https://sindresorhus.com) - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE diff --git a/utils/readPkgUp.js b/utils/readPkgUp.js index 6a6a1eea3..d34fa6c81 100644 --- a/utils/readPkgUp.js +++ b/utils/readPkgUp.js @@ -1,4 +1,5 @@ 'use strict'; + exports.__esModule = true; const fs = require('fs'); @@ -10,22 +11,22 @@ function stripBOM(str) { /** * Derived significantly from read-pkg-up@2.0.0. See license below. - * + * * @copyright Sindre Sorhus * MIT License * * Copyright (c) Sindre Sorhus (https://sindresorhus.com) - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE diff --git a/utils/resolve.js b/utils/resolve.js index 9d9dfa843..0ed5bdb0c 100644 --- a/utils/resolve.js +++ b/utils/resolve.js @@ -1,4 +1,5 @@ 'use strict'; + exports.__esModule = true; const fs = require('fs'); @@ -53,16 +54,16 @@ function tryRequire(target, sourceFile) { // https://stackoverflow.com/a/27382838 exports.fileExistsWithCaseSync = function fileExistsWithCaseSync(filepath, cacheSettings, strict) { // don't care if the FS is case-sensitive - if (CASE_SENSITIVE_FS) return true; + if (CASE_SENSITIVE_FS) { return true; } // null means it resolved to a builtin - if (filepath === null) return true; - if (filepath.toLowerCase() === process.cwd().toLowerCase() && !strict) return true; + if (filepath === null) { return true; } + if (filepath.toLowerCase() === process.cwd().toLowerCase() && !strict) { return true; } const parsedPath = path.parse(filepath); const dir = parsedPath.dir; let result = fileExistsCache.get(filepath, cacheSettings); - if (result != null) return result; + if (result != null) { return result; } // base case if (dir === '' || parsedPath.root === filepath) { @@ -88,7 +89,7 @@ let memoizedHash = ''; function fullResolve(modulePath, sourceFile, settings) { // check if this is a bonus core module const coreSet = new Set(settings['import/core-modules']); - if (coreSet.has(modulePath)) return { found: true, path: null }; + if (coreSet.has(modulePath)) { return { found: true, path: null }; } const sourceDir = path.dirname(sourceFile); @@ -102,40 +103,28 @@ function fullResolve(modulePath, sourceFile, settings) { const cacheSettings = ModuleCache.getSettings(settings); const cachedPath = fileExistsCache.get(cacheKey, cacheSettings); - if (cachedPath !== undefined) return { found: true, path: cachedPath }; + if (cachedPath !== undefined) { return { found: true, path: cachedPath }; } function cache(resolvedPath) { fileExistsCache.set(cacheKey, resolvedPath); } function withResolver(resolver, config) { - - function v1() { - try { - const resolved = resolver.resolveImport(modulePath, sourceFile, config); - if (resolved === undefined) return { found: false }; - return { found: true, path: resolved }; - } catch (err) { - return { found: false }; - } - } - - function v2() { + if (resolver.interfaceVersion === 2) { return resolver.resolve(modulePath, sourceFile, config); } - switch (resolver.interfaceVersion) { - case 2: - return v2(); - - default: - case 1: - return v1(); + try { + const resolved = resolver.resolveImport(modulePath, sourceFile, config); + if (resolved === undefined) { return { found: false }; } + return { found: true, path: resolved }; + } catch (err) { + return { found: false }; } } - const configResolvers = (settings['import/resolver'] - || { 'node': settings['import/resolve'] }); // backward compatibility + const configResolvers = settings['import/resolver'] + || { node: settings['import/resolve'] }; // backward compatibility const resolvers = resolverReducer(configResolvers, new Map()); @@ -145,7 +134,7 @@ function fullResolve(modulePath, sourceFile, settings) { const resolver = requireResolver(name, sourceFile); const resolved = withResolver(resolver, config); - if (!resolved.found) continue; + if (!resolved.found) { continue; } // else, counts cache(resolved.path); @@ -160,7 +149,7 @@ exports.relative = relative; function resolverReducer(resolvers, map) { if (Array.isArray(resolvers)) { - resolvers.forEach(r => resolverReducer(r, map)); + resolvers.forEach((r) => resolverReducer(r, map)); return map; } @@ -186,9 +175,9 @@ function getBaseDir(sourceFile) { } function requireResolver(name, sourceFile) { // Try to resolve package with conventional name - const resolver = tryRequire(`eslint-import-resolver-${name}`, sourceFile) || - tryRequire(name, sourceFile) || - tryRequire(path.resolve(getBaseDir(sourceFile), name)); + const resolver = tryRequire(`eslint-import-resolver-${name}`, sourceFile) + || tryRequire(name, sourceFile) + || tryRequire(path.resolve(getBaseDir(sourceFile), name)); if (!resolver) { const err = new Error(`unable to load resolver "${name}".`); diff --git a/utils/unambiguous.js b/utils/unambiguous.js index 75f21693b..24cb12315 100644 --- a/utils/unambiguous.js +++ b/utils/unambiguous.js @@ -1,4 +1,5 @@ 'use strict'; + exports.__esModule = true; const pattern = /(^|;)\s*(export|import)((\s+\w)|(\s*[{*=]))|import\(/m; @@ -25,5 +26,5 @@ const unambiguousNodeType = /^(?:(?:Exp|Imp)ort.*Declaration|TSExportAssignment) * @return {Boolean} */ exports.isModule = function isUnambiguousModule(ast) { - return ast.body && ast.body.some(node => unambiguousNodeType.test(node.type)); + return ast.body && ast.body.some((node) => unambiguousNodeType.test(node.type)); }; diff --git a/utils/visit.js b/utils/visit.js index 77b09850a..6178faeaa 100644 --- a/utils/visit.js +++ b/utils/visit.js @@ -1,4 +1,5 @@ 'use strict'; + exports.__esModule = true; exports.default = function visit(node, keys, visitorSpec) {