• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1'use strict';
2
3/* eslint-env node */
4
5const Module = require('module');
6const path = require('path');
7
8const NodePlugin = require('./tools/node_modules/eslint-plugin-node-core');
9NodePlugin.RULES_DIR = path.resolve(__dirname, 'tools', 'eslint-rules');
10
11// The Module._findPath() monkeypatching is to make it so that ESLint will work
12// if invoked by a globally-installed ESLint or ESLint installed elsewhere
13// rather than the one we ship. This makes it possible for IDEs to lint files
14// with our rules while people edit them.
15const ModuleFindPath = Module._findPath;
16const hacks = [
17  'eslint-plugin-node-core',
18  'eslint-plugin-markdown',
19  'babel-eslint',
20];
21Module._findPath = (request, paths, isMain) => {
22  const r = ModuleFindPath(request, paths, isMain);
23  if (!r && hacks.includes(request)) {
24    try {
25      return require.resolve(`./tools/node_modules/${request}`);
26    // Keep the variable in place to ensure that ESLint started by older Node.js
27    // versions work as expected.
28    // eslint-disable-next-line no-unused-vars
29    } catch (e) {
30      return require.resolve(
31        `./tools/node_modules/eslint/node_modules/${request}`);
32    }
33  }
34  return r;
35};
36
37module.exports = {
38  root: true,
39  plugins: ['markdown', 'node-core'],
40  parser: 'babel-eslint',
41  parserOptions: { sourceType: 'script' },
42  overrides: [
43    {
44      files: [
45        'doc/api/esm.md',
46        'doc/api/module.md',
47        'doc/api/modules.md',
48        'doc/api/packages.md',
49        'test/es-module/test-esm-type-flag.js',
50        'test/es-module/test-esm-type-flag-alias.js',
51        '*.mjs',
52        'test/es-module/test-esm-example-loader.js',
53      ],
54      parserOptions: { sourceType: 'module' },
55    },
56    {
57      files: ['**/*.md'],
58      parserOptions: { ecmaFeatures: { impliedStrict: true } },
59      rules: { strict: 'off' },
60    },
61  ],
62  rules: {
63    // ESLint built-in rules
64    // https://eslint.org/docs/rules/
65    'accessor-pairs': 'error',
66    'array-callback-return': 'error',
67    'arrow-parens': ['error', 'always'],
68    'arrow-spacing': ['error', { before: true, after: true }],
69    'block-scoped-var': 'error',
70    'block-spacing': 'error',
71    'brace-style': ['error', '1tbs', { allowSingleLine: true }],
72    'capitalized-comments': ['error', 'always', {
73      line: {
74        // Ignore all lines that have less characters than 20 and all lines that
75        // start with something that looks like a variable name or code.
76        // eslint-disable-next-line max-len
77        ignorePattern: '.{0,20}$|[a-z]+ ?[0-9A-Z_.(/=:[#-]|std|http|ssh|ftp|(let|var|const) [a-z_A-Z0-9]+ =|[b-z] |[a-z]*[0-9].* ',
78        ignoreInlineComments: true,
79        ignoreConsecutiveComments: true,
80      },
81      block: {
82        ignorePattern: '.*',
83      },
84    }],
85    'comma-dangle': ['error', 'only-multiline'],
86    'comma-spacing': 'error',
87    'comma-style': 'error',
88    'computed-property-spacing': 'error',
89    'constructor-super': 'error',
90    'default-case-last': 'error',
91    'dot-location': ['error', 'property'],
92    'dot-notation': 'error',
93    'eol-last': 'error',
94    'eqeqeq': ['error', 'smart'],
95    'for-direction': 'error',
96    'func-call-spacing': 'error',
97    'func-name-matching': 'error',
98    'func-style': ['error', 'declaration', { allowArrowFunctions: true }],
99    'getter-return': 'error',
100    'indent': ['error', 2, {
101      ArrayExpression: 'first',
102      CallExpression: { arguments: 'first' },
103      FunctionDeclaration: { parameters: 'first' },
104      FunctionExpression: { parameters: 'first' },
105      MemberExpression: 'off',
106      ObjectExpression: 'first',
107      SwitchCase: 1,
108    }],
109    'key-spacing': ['error', { mode: 'strict' }],
110    'keyword-spacing': 'error',
111    'linebreak-style': ['error', 'unix'],
112    'max-len': ['error', {
113      code: 80,
114      ignorePattern: '^// Flags:',
115      ignoreRegExpLiterals: true,
116      ignoreUrls: true,
117      tabWidth: 2,
118    }],
119    'new-parens': 'error',
120    'no-async-promise-executor': 'error',
121    'no-class-assign': 'error',
122    'no-confusing-arrow': 'error',
123    'no-const-assign': 'error',
124    'no-constructor-return': 'error',
125    'no-control-regex': 'error',
126    'no-debugger': 'error',
127    'no-delete-var': 'error',
128    'no-dupe-args': 'error',
129    'no-dupe-class-members': 'error',
130    'no-dupe-keys': 'error',
131    'no-dupe-else-if': 'error',
132    'no-duplicate-case': 'error',
133    'no-duplicate-imports': 'error',
134    'no-else-return': ['error', { allowElseIf: true }],
135    'no-empty-character-class': 'error',
136    'no-ex-assign': 'error',
137    'no-extra-boolean-cast': 'error',
138    'no-extra-parens': ['error', 'functions'],
139    'no-extra-semi': 'error',
140    'no-fallthrough': 'error',
141    'no-func-assign': 'error',
142    'no-global-assign': 'error',
143    'no-invalid-regexp': 'error',
144    'no-irregular-whitespace': 'error',
145    'no-lonely-if': 'error',
146    'no-misleading-character-class': 'error',
147    'no-mixed-requires': 'error',
148    'no-mixed-spaces-and-tabs': 'error',
149    'no-multi-spaces': ['error', { ignoreEOLComments: true }],
150    'no-multiple-empty-lines': ['error', { max: 2, maxEOF: 0, maxBOF: 0 }],
151    'no-new-require': 'error',
152    'no-new-symbol': 'error',
153    'no-obj-calls': 'error',
154    'no-octal': 'error',
155    'no-path-concat': 'error',
156    'no-proto': 'error',
157    'no-redeclare': ['error', { 'builtinGlobals': false }],
158    'no-restricted-modules': ['error', 'sys'],
159    /* eslint-disable max-len */
160    'no-restricted-properties': [
161      'error',
162      {
163        object: 'assert',
164        property: 'deepEqual',
165        message: 'Use `assert.deepStrictEqual()`.',
166      },
167      {
168        object: 'assert',
169        property: 'notDeepEqual',
170        message: 'Use `assert.notDeepStrictEqual()`.',
171      },
172      {
173        object: 'assert',
174        property: 'equal',
175        message: 'Use `assert.strictEqual()` rather than `assert.equal()`.',
176      },
177      {
178        object: 'assert',
179        property: 'notEqual',
180        message: 'Use `assert.notStrictEqual()` rather than `assert.notEqual()`.',
181      },
182      {
183        property: '__defineGetter__',
184        message: '__defineGetter__ is deprecated.',
185      },
186      {
187        property: '__defineSetter__',
188        message: '__defineSetter__ is deprecated.',
189      },
190    ],
191    // If this list is modified, please copy changes that should apply to ./lib
192    // as well to lib/.eslintrc.yaml.
193    'no-restricted-syntax': [
194      'error',
195      {
196        selector: "CallExpression[callee.name='setTimeout'][arguments.length<2]",
197        message: '`setTimeout()` must be invoked with at least two arguments.',
198      },
199      {
200        selector: "CallExpression[callee.name='setInterval'][arguments.length<2]",
201        message: '`setInterval()` must be invoked with at least two arguments.',
202      },
203      {
204        selector: 'ThrowStatement > CallExpression[callee.name=/Error$/]',
205        message: 'Use `new` keyword when throwing an `Error`.',
206      },
207      {
208        selector: "CallExpression[callee.name='isNaN']",
209        message: 'Use Number.isNaN() instead of the global isNaN() function.',
210      },
211    ],
212    /* eslint-enable max-len */
213    'no-return-await': 'error',
214    'no-self-assign': 'error',
215    'no-self-compare': 'error',
216    'no-setter-return': 'error',
217    'no-shadow-restricted-names': 'error',
218    'no-tabs': 'error',
219    'no-template-curly-in-string': 'error',
220    'no-this-before-super': 'error',
221    'no-throw-literal': 'error',
222    'no-trailing-spaces': 'error',
223    'no-undef': ['error', { typeof: true }],
224    'no-undef-init': 'error',
225    'no-unexpected-multiline': 'error',
226    'no-unreachable': 'error',
227    'no-unsafe-finally': 'error',
228    'no-unsafe-negation': 'error',
229    'no-unused-labels': 'error',
230    'no-unused-vars': ['error', { args: 'none', caughtErrors: 'all' }],
231    'no-use-before-define': ['error', {
232      classes: true,
233      functions: false,
234      variables: false,
235    }],
236    'no-useless-backreference': 'error',
237    'no-useless-call': 'error',
238    'no-useless-catch': 'error',
239    'no-useless-concat': 'error',
240    'no-useless-constructor': 'error',
241    'no-useless-escape': 'error',
242    'no-useless-return': 'error',
243    'no-void': 'error',
244    'no-whitespace-before-property': 'error',
245    'no-with': 'error',
246    'object-curly-spacing': ['error', 'always'],
247    'one-var': ['error', { initialized: 'never' }],
248    'one-var-declaration-per-line': 'error',
249    'operator-linebreak': ['error', 'after'],
250    'padding-line-between-statements': [
251      'error',
252      { blankLine: 'always', prev: 'function', next: 'function' },
253    ],
254    'prefer-const': ['error', { ignoreReadBeforeAssign: true }],
255    'quotes': ['error', 'single', { avoidEscape: true }],
256    'quote-props': ['error', 'consistent'],
257    'rest-spread-spacing': 'error',
258    'semi': 'error',
259    'semi-spacing': 'error',
260    'space-before-blocks': ['error', 'always'],
261    'space-before-function-paren': ['error', {
262      anonymous: 'never',
263      named: 'never',
264      asyncArrow: 'always',
265    }],
266    'space-in-parens': ['error', 'never'],
267    'space-infix-ops': 'error',
268    'space-unary-ops': 'error',
269    'spaced-comment': ['error', 'always', {
270      'block': { 'balanced': true },
271      'exceptions': ['-'],
272    }],
273    'strict': ['error', 'global'],
274    'symbol-description': 'error',
275    'template-curly-spacing': 'error',
276    'unicode-bom': 'error',
277    'use-isnan': 'error',
278    'valid-typeof': 'error',
279
280    // Custom rules from eslint-plugin-node-core
281    'node-core/no-unescaped-regexp-dot': 'error',
282    'node-core/no-duplicate-requires': 'error',
283  },
284  globals: {
285    Atomics: 'readable',
286    BigInt: 'readable',
287    BigInt64Array: 'readable',
288    BigUint64Array: 'readable',
289    TextEncoder: 'readable',
290    TextDecoder: 'readable',
291    queueMicrotask: 'readable',
292    globalThis: 'readable',
293  },
294};
295