eslint-plugin-unicorn 20.0.0 → 23.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. package/index.js +10 -2
  2. package/package.json +28 -20
  3. package/readme.md +13 -1
  4. package/rules/better-regex.js +8 -4
  5. package/rules/catch-error-name.js +6 -5
  6. package/rules/consistent-function-scoping.js +20 -33
  7. package/rules/custom-error-definition.js +13 -18
  8. package/rules/error-message.js +11 -3
  9. package/rules/escape-case.js +8 -3
  10. package/rules/expiring-todo-comments.js +29 -28
  11. package/rules/explicit-length-check.js +20 -10
  12. package/rules/filename-case.js +8 -5
  13. package/rules/import-index.js +8 -2
  14. package/rules/import-style.js +373 -0
  15. package/rules/no-abusive-eslint-disable.js +10 -2
  16. package/rules/no-array-instanceof.js +7 -3
  17. package/rules/no-console-spaces.js +19 -17
  18. package/rules/no-fn-reference-in-iterator.js +14 -14
  19. package/rules/no-for-loop.js +40 -21
  20. package/rules/no-hex-escape.js +7 -1
  21. package/rules/no-keyword-prefix.js +4 -3
  22. package/rules/no-nested-ternary.js +24 -27
  23. package/rules/no-new-buffer.js +9 -2
  24. package/rules/no-null.js +6 -5
  25. package/rules/no-object-as-default-parameter.js +37 -0
  26. package/rules/no-process-exit.js +8 -3
  27. package/rules/no-reduce.js +21 -16
  28. package/rules/no-unreadable-array-destructuring.js +8 -3
  29. package/rules/no-unsafe-regex.js +8 -4
  30. package/rules/no-unused-properties.js +9 -3
  31. package/rules/no-useless-undefined.js +45 -3
  32. package/rules/no-zero-fractions.js +8 -3
  33. package/rules/number-literal-case.js +18 -12
  34. package/rules/numeric-separators-style.js +153 -0
  35. package/rules/prefer-add-event-listener.js +12 -5
  36. package/rules/prefer-array-find.js +316 -0
  37. package/rules/prefer-dataset.js +8 -2
  38. package/rules/prefer-event-key.js +9 -2
  39. package/rules/prefer-flat-map.js +28 -31
  40. package/rules/prefer-includes.js +7 -3
  41. package/rules/prefer-math-trunc.js +92 -0
  42. package/rules/prefer-negative-index.js +14 -7
  43. package/rules/prefer-node-append.js +7 -3
  44. package/rules/prefer-node-remove.js +8 -7
  45. package/rules/prefer-number-properties.js +12 -6
  46. package/rules/prefer-optional-catch-binding.js +5 -4
  47. package/rules/prefer-query-selector.js +31 -29
  48. package/rules/prefer-reflect-apply.js +10 -4
  49. package/rules/prefer-replace-all.js +8 -4
  50. package/rules/prefer-set-has.js +19 -14
  51. package/rules/prefer-spread.js +8 -2
  52. package/rules/prefer-starts-ends-with.js +6 -5
  53. package/rules/prefer-string-slice.js +11 -3
  54. package/rules/prefer-ternary.js +269 -0
  55. package/rules/prefer-text-content.js +7 -3
  56. package/rules/prefer-trim-start-end.js +11 -8
  57. package/rules/prefer-type-error.js +8 -2
  58. package/rules/prevent-abbreviations.js +22 -3
  59. package/rules/string-content.js +7 -6
  60. package/rules/throw-new-error.js +5 -3
  61. package/rules/utils/cartesian-product-samples.js +2 -2
  62. package/rules/utils/method-selector.js +2 -2
  63. package/rules/utils/not-function.js +35 -0
  64. package/rules/utils/rename-identifier.js +1 -1
package/index.js CHANGED
@@ -10,7 +10,7 @@ module.exports = {
10
10
  es6: true
11
11
  },
12
12
  parserOptions: {
13
- ecmaVersion: 2020,
13
+ ecmaVersion: 2021,
14
14
  sourceType: 'module'
15
15
  },
16
16
  plugins: [
@@ -27,6 +27,7 @@ module.exports = {
27
27
  'unicorn/explicit-length-check': 'error',
28
28
  'unicorn/filename-case': 'error',
29
29
  'unicorn/import-index': 'error',
30
+ 'unicorn/import-style': 'error',
30
31
  'unicorn/new-for-builtins': 'error',
31
32
  'unicorn/no-abusive-eslint-disable': 'error',
32
33
  'unicorn/no-array-instanceof': 'error',
@@ -39,6 +40,7 @@ module.exports = {
39
40
  'unicorn/no-nested-ternary': 'error',
40
41
  'unicorn/no-new-buffer': 'error',
41
42
  'unicorn/no-null': 'error',
43
+ 'unicorn/no-object-as-default-parameter': 'error',
42
44
  'unicorn/no-process-exit': 'error',
43
45
  'unicorn/no-reduce': 'error',
44
46
  'unicorn/no-unreadable-array-destructuring': 'error',
@@ -47,11 +49,16 @@ module.exports = {
47
49
  'unicorn/no-useless-undefined': 'error',
48
50
  'unicorn/no-zero-fractions': 'error',
49
51
  'unicorn/number-literal-case': 'error',
52
+ // TODO: Enable this by default when it's shipping in a Node.js LTS version.
53
+ 'unicorn/numeric-separators-style': 'off',
50
54
  'unicorn/prefer-add-event-listener': 'error',
55
+ 'unicorn/prefer-array-find': 'error',
51
56
  'unicorn/prefer-dataset': 'error',
52
57
  'unicorn/prefer-event-key': 'error',
53
- 'unicorn/prefer-flat-map': 'error',
58
+ // TODO: Enable this by default when targeting Node.js 12.
59
+ 'unicorn/prefer-flat-map': 'off',
54
60
  'unicorn/prefer-includes': 'error',
61
+ 'unicorn/prefer-math-trunc': 'error',
55
62
  'unicorn/prefer-modern-dom-apis': 'error',
56
63
  'unicorn/prefer-negative-index': 'error',
57
64
  'unicorn/prefer-node-append': 'error',
@@ -66,6 +73,7 @@ module.exports = {
66
73
  'unicorn/prefer-spread': 'error',
67
74
  'unicorn/prefer-starts-ends-with': 'error',
68
75
  'unicorn/prefer-string-slice': 'error',
76
+ 'unicorn/prefer-ternary': 'error',
69
77
  'unicorn/prefer-text-content': 'error',
70
78
  'unicorn/prefer-trim-start-end': 'error',
71
79
  'unicorn/prefer-type-error': 'error',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint-plugin-unicorn",
3
- "version": "20.0.0",
3
+ "version": "23.0.0",
4
4
  "description": "Various awesome ESLint rules",
5
5
  "license": "MIT",
6
6
  "repository": "sindresorhus/eslint-plugin-unicorn",
@@ -36,10 +36,11 @@
36
36
  "ci-info": "^2.0.0",
37
37
  "clean-regexp": "^1.0.0",
38
38
  "eslint-ast-utils": "^1.1.0",
39
- "eslint-template-visitor": "^1.1.0",
40
- "eslint-utils": "^2.0.0",
39
+ "eslint-template-visitor": "^2.2.1",
40
+ "eslint-utils": "^2.1.0",
41
41
  "import-modules": "^2.0.0",
42
- "lodash": "^4.17.15",
42
+ "lodash": "^4.17.20",
43
+ "pluralize": "^8.0.0",
43
44
  "read-pkg-up": "^7.0.1",
44
45
  "regexp-tree": "^0.1.21",
45
46
  "reserved-words": "^0.1.2",
@@ -48,25 +49,27 @@
48
49
  },
49
50
  "devDependencies": {
50
51
  "@ava/babel": "^1.0.1",
52
+ "@babel/code-frame": "7.10.4",
51
53
  "@lubien/fixture-beta-package": "^1.0.0-beta.1",
52
- "@typescript-eslint/parser": "^2.33.0",
53
- "ava": "^3.8.2",
54
+ "@typescript-eslint/parser": "^4.4.1",
55
+ "ava": "^3.13.0",
54
56
  "babel-eslint": "^10.1.0",
55
- "chalk": "^4.0.0",
56
- "eslint": "^7.0.0",
57
+ "chalk": "^4.1.0",
58
+ "eslint": "^7.11.0",
57
59
  "eslint-ava-rule-tester": "^4.0.0",
58
- "eslint-plugin-eslint-plugin": "^2.2.1",
59
- "execa": "^4.0.1",
60
+ "eslint-plugin-eslint-plugin": "^2.3.0",
61
+ "execa": "^4.0.3",
60
62
  "listr": "^0.14.3",
61
- "nyc": "^15.0.1",
63
+ "mem": "8.0.0",
64
+ "nyc": "^15.1.0",
62
65
  "outdent": "^0.7.1",
63
66
  "pify": "^5.0.0",
64
- "typescript": "^3.9.2",
65
- "vue-eslint-parser": "^7.0.0",
66
- "xo": "^0.30.0"
67
+ "typescript": "^4.0.3",
68
+ "vue-eslint-parser": "^7.1.1",
69
+ "xo": "^0.33.1"
67
70
  },
68
71
  "peerDependencies": {
69
- "eslint": ">=7.0.0"
72
+ "eslint": ">=7.11.0"
70
73
  },
71
74
  "ava": {
72
75
  "babel": true,
@@ -90,10 +93,14 @@
90
93
  "extends": [
91
94
  "plugin:eslint-plugin/all"
92
95
  ],
96
+ "ignores": [
97
+ "test/integration/{fixtures,unicorn}/**"
98
+ ],
93
99
  "overrides": [
94
100
  {
95
101
  "files": "rules/utils/*.js",
96
102
  "rules": {
103
+ "eslint-plugin/prefer-object-rule": "off",
97
104
  "eslint-plugin/require-meta-docs-url": "off"
98
105
  }
99
106
  },
@@ -106,14 +113,15 @@
106
113
  ],
107
114
  "rules": {
108
115
  "strict": "error",
109
- "array-callback-return": [
116
+ "unicorn/no-null": "error",
117
+ "unicorn/prevent-abbreviations": [
110
118
  "error",
111
119
  {
112
- "allowImplicit": true
120
+ "replacements": {
121
+ "fn": false
122
+ }
113
123
  }
114
- ],
115
- "unicorn/no-null": "error",
116
- "unicorn/string-content": "off"
124
+ ]
117
125
  }
118
126
  }
119
127
  }
package/readme.md CHANGED
@@ -26,7 +26,7 @@ Configure it in `package.json`.
26
26
  "es6": true
27
27
  },
28
28
  "parserOptions": {
29
- "ecmaVersion": 2020,
29
+ "ecmaVersion": 2021,
30
30
  "sourceType": "module"
31
31
  },
32
32
  "plugins": [
@@ -43,6 +43,7 @@ Configure it in `package.json`.
43
43
  "unicorn/explicit-length-check": "error",
44
44
  "unicorn/filename-case": "error",
45
45
  "unicorn/import-index": "error",
46
+ "unicorn/import-style": "error",
46
47
  "unicorn/new-for-builtins": "error",
47
48
  "unicorn/no-abusive-eslint-disable": "error",
48
49
  "unicorn/no-array-instanceof": "error",
@@ -55,6 +56,7 @@ Configure it in `package.json`.
55
56
  "unicorn/no-nested-ternary": "error",
56
57
  "unicorn/no-new-buffer": "error",
57
58
  "unicorn/no-null": "error",
59
+ "unicorn/no-object-as-default-parameter": "error",
58
60
  "unicorn/no-process-exit": "error",
59
61
  "unicorn/no-reduce": "error",
60
62
  "unicorn/no-unreadable-array-destructuring": "error",
@@ -63,11 +65,14 @@ Configure it in `package.json`.
63
65
  "unicorn/no-useless-undefined": "error",
64
66
  "unicorn/no-zero-fractions": "error",
65
67
  "unicorn/number-literal-case": "error",
68
+ "unicorn/numeric-separators-style": "off",
66
69
  "unicorn/prefer-add-event-listener": "error",
70
+ "unicorn/prefer-array-find": "error",
67
71
  "unicorn/prefer-dataset": "error",
68
72
  "unicorn/prefer-event-key": "error",
69
73
  "unicorn/prefer-flat-map": "error",
70
74
  "unicorn/prefer-includes": "error",
75
+ "unicorn/prefer-math-trunc": "error",
71
76
  "unicorn/prefer-modern-dom-apis": "error",
72
77
  "unicorn/prefer-negative-index": "error",
73
78
  "unicorn/prefer-node-append": "error",
@@ -81,6 +86,7 @@ Configure it in `package.json`.
81
86
  "unicorn/prefer-spread": "error",
82
87
  "unicorn/prefer-starts-ends-with": "error",
83
88
  "unicorn/prefer-string-slice": "error",
89
+ "unicorn/prefer-ternary": "off",
84
90
  "unicorn/prefer-text-content": "error",
85
91
  "unicorn/prefer-trim-start-end": "error",
86
92
  "unicorn/prefer-type-error": "error",
@@ -104,6 +110,7 @@ Configure it in `package.json`.
104
110
  - [explicit-length-check](docs/rules/explicit-length-check.md) - Enforce explicitly comparing the `length` property of a value. *(partly fixable)*
105
111
  - [filename-case](docs/rules/filename-case.md) - Enforce a case style for filenames.
106
112
  - [import-index](docs/rules/import-index.md) - Enforce importing index files with `.`. *(fixable)*
113
+ - [import-style](docs/rules/import-style.md) - Enforce specific import styles per module.
107
114
  - [new-for-builtins](docs/rules/new-for-builtins.md) - Enforce the use of `new` for all builtins, except `String`, `Number`, `Boolean`, `Symbol` and `BigInt`. *(fixable)*
108
115
  - [no-abusive-eslint-disable](docs/rules/no-abusive-eslint-disable.md) - Enforce specifying rules to disable in `eslint-disable` comments.
109
116
  - [no-array-instanceof](docs/rules/no-array-instanceof.md) - Require `Array.isArray()` instead of `instanceof Array`. *(fixable)*
@@ -115,6 +122,7 @@ Configure it in `package.json`.
115
122
  - [no-nested-ternary](docs/rules/no-nested-ternary.md) - Disallow nested ternary expressions. *(partly fixable)*
116
123
  - [no-new-buffer](docs/rules/no-new-buffer.md) - Enforce the use of `Buffer.from()` and `Buffer.alloc()` instead of the deprecated `new Buffer()`. *(fixable)*
117
124
  - [no-null](docs/rules/no-null.md) - Disallow the use of the `null` literal.
125
+ - [no-object-as-default-parameter](docs/rules/no-object-as-default-parameter.md) - Disallow the use of objects as default parameters.
118
126
  - [no-process-exit](docs/rules/no-process-exit.md) - Disallow `process.exit()`.
119
127
  - [no-reduce](docs/rules/no-reduce.md) - Disallow `Array#reduce()` and `Array#reduceRight()`.
120
128
  - [no-unreadable-array-destructuring](docs/rules/no-unreadable-array-destructuring.md) - Disallow unreadable array destructuring.
@@ -123,11 +131,14 @@ Configure it in `package.json`.
123
131
  - [no-useless-undefined](docs/rules/no-useless-undefined.md) - Disallow useless `undefined`. *(fixable)*
124
132
  - [no-zero-fractions](docs/rules/no-zero-fractions.md) - Disallow number literals with zero fractions or dangling dots. *(fixable)*
125
133
  - [number-literal-case](docs/rules/number-literal-case.md) - Enforce proper case for numeric literals. *(fixable)*
134
+ - [numeric-separators-style](docs/rules/numeric-separators-style.md) - Enforce the style of numeric separators by correctly grouping digits. *(fixable)*
126
135
  - [prefer-add-event-listener](docs/rules/prefer-add-event-listener.md) - Prefer `.addEventListener()` and `.removeEventListener()` over `on`-functions. *(partly fixable)*
136
+ - [prefer-array-find](docs/rules/prefer-array-find.md) - Prefer `.find(…)` over the first element from `.filter(…)`. *(partly fixable)*
127
137
  - [prefer-dataset](docs/rules/prefer-dataset.md) - Prefer using `.dataset` on DOM elements over `.setAttribute(…)`. *(fixable)*
128
138
  - [prefer-event-key](docs/rules/prefer-event-key.md) - Prefer `KeyboardEvent#key` over `KeyboardEvent#keyCode`. *(partly fixable)*
129
139
  - [prefer-flat-map](docs/rules/prefer-flat-map.md) - Prefer `.flatMap(…)` over `.map(…).flat()`. *(fixable)*
130
140
  - [prefer-includes](docs/rules/prefer-includes.md) - Prefer `.includes()` over `.indexOf()` when checking for existence or non-existence. *(fixable)*
141
+ - [prefer-math-trunc](docs/rules/prefer-math-trunc.md) - Enforce the use of `Math.trunc` instead of bitwise operators. *(partly fixable)*
131
142
  - [prefer-modern-dom-apis](docs/rules/prefer-modern-dom-apis.md) - Prefer `.before()` over `.insertBefore()`, `.replaceWith()` over `.replaceChild()`, prefer one of `.before()`, `.after()`, `.append()` or `.prepend()` over `insertAdjacentText()` and `insertAdjacentElement()`. *(fixable)*
132
143
  - [prefer-negative-index](docs/rules/prefer-negative-index.md) - Prefer negative index over `.length - index` for `{String,Array,TypedArray}#slice()` and `Array#splice()`. *(fixable)*
133
144
  - [prefer-node-append](docs/rules/prefer-node-append.md) - Prefer `Node#append()` over `Node#appendChild()`. *(fixable)*
@@ -141,6 +152,7 @@ Configure it in `package.json`.
141
152
  - [prefer-spread](docs/rules/prefer-spread.md) - Prefer the spread operator over `Array.from()`. *(fixable)*
142
153
  - [prefer-starts-ends-with](docs/rules/prefer-starts-ends-with.md) - Prefer `String#startsWith()` & `String#endsWith()` over more complex alternatives. *(partly fixable)*
143
154
  - [prefer-string-slice](docs/rules/prefer-string-slice.md) - Prefer `String#slice()` over `String#substr()` and `String#substring()`. *(partly fixable)*
155
+ - [prefer-ternary](docs/rules/prefer-ternary.md) - Prefer ternary expressions over simple `if-else` statements. *(fixable)*
144
156
  - [prefer-text-content](docs/rules/prefer-text-content.md) - Prefer `.textContent` over `.innerText`. *(fixable)*
145
157
  - [prefer-trim-start-end](docs/rules/prefer-trim-start-end.md) - Prefer `String#trimStart()` / `String#trimEnd()` over `String#trimLeft()` / `String#trimRight()`. *(fixable)*
146
158
  - [prefer-type-error](docs/rules/prefer-type-error.md) - Enforce throwing `TypeError` in type checking conditions. *(fixable)*
@@ -4,7 +4,10 @@ const {optimize} = require('regexp-tree');
4
4
  const getDocumentationUrl = require('./utils/get-documentation-url');
5
5
  const quoteString = require('./utils/quote-string');
6
6
 
7
- const message = '{{original}} can be optimized to {{optimized}}';
7
+ const MESSAGE_ID = 'better-regex';
8
+ const messages = {
9
+ [MESSAGE_ID]: '{{original}} can be optimized to {{optimized}}.'
10
+ };
8
11
 
9
12
  const create = context => {
10
13
  const {sortCharacterClasses} = context.options[0] || {};
@@ -37,7 +40,7 @@ const create = context => {
37
40
 
38
41
  context.report({
39
42
  node,
40
- message,
43
+ messageId: MESSAGE_ID,
41
44
  data: {
42
45
  original,
43
46
  optimized
@@ -64,7 +67,7 @@ const create = context => {
64
67
  if (oldPattern !== newPattern) {
65
68
  context.report({
66
69
  node,
67
- message,
70
+ messageId: MESSAGE_ID,
68
71
  data: {
69
72
  original: oldPattern,
70
73
  optimized: newPattern
@@ -99,6 +102,7 @@ module.exports = {
99
102
  url: getDocumentationUrl(__filename)
100
103
  },
101
104
  fixable: 'code',
102
- schema
105
+ schema,
106
+ messages
103
107
  }
104
108
  };
@@ -5,7 +5,10 @@ const getDocumentationUrl = require('./utils/get-documentation-url');
5
5
  const renameVariable = require('./utils/rename-variable');
6
6
  const methodSelector = require('./utils/method-selector');
7
7
 
8
- const ERROR_MESSAGE_ID = 'error';
8
+ const MESSAGE_ID = 'catch-error-name';
9
+ const messages = {
10
+ [MESSAGE_ID]: 'The catch parameter `{{originalName}}` should be named `{{fixedName}}`.'
11
+ };
9
12
 
10
13
  const promiseMethodSelector = (method, argumentsLength, argumentIndex) => [
11
14
  methodSelector({
@@ -78,7 +81,7 @@ const create = context => {
78
81
 
79
82
  context.report({
80
83
  node,
81
- messageId: ERROR_MESSAGE_ID,
84
+ messageId: MESSAGE_ID,
82
85
  data: {
83
86
  originalName,
84
87
  fixedName
@@ -124,8 +127,6 @@ module.exports = {
124
127
  },
125
128
  fixable: 'code',
126
129
  schema,
127
- messages: {
128
- [ERROR_MESSAGE_ID]: 'The catch parameter `{{originalName}}` should be named `{{fixedName}}`.'
129
- }
130
+ messages
130
131
  }
131
132
  };
@@ -1,9 +1,12 @@
1
1
  'use strict';
2
+ const {getFunctionHeadLocation, getFunctionNameWithKind} = require('eslint-utils');
2
3
  const getDocumentationUrl = require('./utils/get-documentation-url');
3
4
  const getReferences = require('./utils/get-references');
4
5
 
5
- const MESSAGE_ID_NAMED = 'named';
6
- const MESSAGE_ID_ANONYMOUS = 'anonymous';
6
+ const MESSAGE_ID = 'consistent-function-scoping';
7
+ const messages = {
8
+ [MESSAGE_ID]: 'Move {{functionNameWithKind}} to the outer scope.'
9
+ };
7
10
 
8
11
  const isSameScope = (scope1, scope2) =>
9
12
  scope1 && scope2 && (scope1 === scope2 || scope1.block === scope2.block);
@@ -105,7 +108,8 @@ const iifeFunctionTypes = new Set([
105
108
  const isIife = node => node &&
106
109
  iifeFunctionTypes.has(node.type) &&
107
110
  node.parent &&
108
- node.parent.type === 'CallExpression';
111
+ node.parent.type === 'CallExpression' &&
112
+ node.parent.callee === node;
109
113
 
110
114
  function checkNode(node, scopeManager) {
111
115
  const scope = scopeManager.acquire(node);
@@ -152,44 +156,30 @@ const create = context => {
152
156
  const {scopeManager} = sourceCode;
153
157
 
154
158
  const functions = [];
155
- let hasJsx = false;
156
159
 
157
160
  return {
158
- 'ArrowFunctionExpression, FunctionDeclaration': node => functions.push(node),
161
+ ':function': () => {
162
+ functions.push(false);
163
+ },
159
164
  JSXElement: () => {
160
165
  // Turn off this rule if we see a JSX element because scope
161
166
  // references does not include JSXElement nodes.
162
- hasJsx = true;
167
+ if (functions.length > 0) {
168
+ functions[functions.length - 1] = true;
169
+ }
163
170
  },
164
- ':matches(ArrowFunctionExpression, FunctionDeclaration):exit': node => {
165
- if (!hasJsx && !checkNode(node, scopeManager)) {
166
- const functionType = node.type === 'ArrowFunctionExpression' ? 'arrow function' : 'function';
167
- let functionName = '';
168
- if (node.id) {
169
- functionName = node.id.name;
170
- } else if (
171
- node.parent &&
172
- node.parent.type === 'VariableDeclarator' &&
173
- node.parent.id &&
174
- node.parent.id.type === 'Identifier'
175
- ) {
176
- functionName = node.parent.id.name;
177
- }
178
-
171
+ ':function:exit': node => {
172
+ const currentFunctionHasJsx = functions.pop();
173
+ if (!currentFunctionHasJsx && !checkNode(node, scopeManager)) {
179
174
  context.report({
180
175
  node,
181
- messageId: functionName ? MESSAGE_ID_NAMED : MESSAGE_ID_ANONYMOUS,
176
+ loc: getFunctionHeadLocation(node, sourceCode),
177
+ messageId: MESSAGE_ID,
182
178
  data: {
183
- functionType,
184
- functionName
179
+ functionNameWithKind: getFunctionNameWithKind(node)
185
180
  }
186
181
  });
187
182
  }
188
-
189
- functions.pop();
190
- if (functions.length === 0) {
191
- hasJsx = false;
192
- }
193
183
  }
194
184
  };
195
185
  };
@@ -201,9 +191,6 @@ module.exports = {
201
191
  docs: {
202
192
  url: getDocumentationUrl(__filename)
203
193
  },
204
- messages: {
205
- [MESSAGE_ID_NAMED]: 'Move {{functionType}} `{{functionName}}` to the outer scope.',
206
- [MESSAGE_ID_ANONYMOUS]: 'Move {{functionType}} to the outer scope.'
207
- }
194
+ messages
208
195
  }
209
196
  };
@@ -3,6 +3,9 @@ const {upperFirst} = require('lodash');
3
3
  const getDocumentationUrl = require('./utils/get-documentation-url');
4
4
 
5
5
  const MESSAGE_ID_INVALID_EXPORT = 'invalidExport';
6
+ const messages = {
7
+ [MESSAGE_ID_INVALID_EXPORT]: 'Exported error name should match error class'
8
+ };
6
9
 
7
10
  const nameRegexp = /^(?:[A-Z][\da-z]*)*Error$/;
8
11
 
@@ -122,25 +125,19 @@ const customErrorDefinition = (context, node) => {
122
125
  context.report({
123
126
  node: superExpression,
124
127
  message: 'Pass the error message to `super()` instead of setting `this.message`.',
125
- fix: fixer => {
126
- const fixings = [];
128
+ * fix(fixer) {
127
129
  if (superExpression.expression.arguments.length === 0) {
128
130
  const rhs = expression.expression.right;
129
- fixings.push(
130
- fixer.insertTextAfterRange([
131
- superExpression.range[0],
132
- superExpression.range[0] + 6
133
- ], rhs.raw || rhs.name)
134
- );
131
+ yield fixer.insertTextAfterRange([
132
+ superExpression.range[0],
133
+ superExpression.range[0] + 6
134
+ ], rhs.raw || rhs.name);
135
135
  }
136
136
 
137
- fixings.push(
138
- fixer.removeRange([
139
- messageExpressionIndex === 0 ? constructorBodyNode.range[0] : constructorBody[messageExpressionIndex - 1].range[1],
140
- expression.range[1]
141
- ])
142
- );
143
- return fixings;
137
+ yield fixer.removeRange([
138
+ messageExpressionIndex === 0 ? constructorBodyNode.range[0] : constructorBody[messageExpressionIndex - 1].range[1],
139
+ expression.range[1]
140
+ ]);
144
141
  }
145
142
  });
146
143
  }
@@ -218,8 +215,6 @@ module.exports = {
218
215
  url: getDocumentationUrl(__filename)
219
216
  },
220
217
  fixable: 'code',
221
- messages: {
222
- [MESSAGE_ID_INVALID_EXPORT]: 'Exported error name should match error class'
223
- }
218
+ messages
224
219
  }
225
220
  };
@@ -1,6 +1,13 @@
1
1
  'use strict';
2
2
  const getDocumentationUrl = require('./utils/get-documentation-url');
3
3
 
4
+ const MESSAGE_ID_MISSING_MESSAGE = 'constructorMissingMessage';
5
+ const MESSAGE_ID_EMPTY_MESSAGE = 'emptyMessage';
6
+ const messages = {
7
+ [MESSAGE_ID_MISSING_MESSAGE]: 'Pass a message to the error constructor.',
8
+ [MESSAGE_ID_EMPTY_MESSAGE]: 'Error message should not be an empty string.'
9
+ };
10
+
4
11
  const errorConstructors = new Set([
5
12
  'Error',
6
13
  'EvalError',
@@ -55,14 +62,14 @@ const reportError = (expressionNode, context) => {
55
62
  if (expressionNode.arguments.length === 0) {
56
63
  context.report({
57
64
  node: expressionNode.parent,
58
- message: 'Pass a message to the error constructor.'
65
+ messageId: MESSAGE_ID_MISSING_MESSAGE
59
66
  });
60
67
  }
61
68
 
62
69
  if (isEmptyMessageString(expressionNode)) {
63
70
  context.report({
64
71
  node: expressionNode.parent,
65
- message: 'Error message should not be an empty string.'
72
+ messageId: MESSAGE_ID_EMPTY_MESSAGE
66
73
  });
67
74
  }
68
75
  }
@@ -99,6 +106,7 @@ module.exports = {
99
106
  type: 'problem',
100
107
  docs: {
101
108
  url: getDocumentationUrl(__filename)
102
- }
109
+ },
110
+ messages
103
111
  }
104
112
  };
@@ -2,9 +2,13 @@
2
2
  const getDocumentationUrl = require('./utils/get-documentation-url');
3
3
  const replaceTemplateElement = require('./utils/replace-template-element');
4
4
 
5
+ const MESSAGE_ID = 'escape-case';
6
+ const messages = {
7
+ [MESSAGE_ID]: 'Use uppercase characters for the value of the escape sequence.'
8
+ };
9
+
5
10
  const escapeWithLowercase = /(?<=(?:^|[^\\])(?:\\\\)*\\)(?<data>x[\dA-Fa-f]{2}|u[\dA-Fa-f]{4}|u{[\dA-Fa-f]+})/g;
6
11
  const escapePatternWithLowercase = /(?<=(?:^|[^\\])(?:\\\\)*\\)(?<data>x[\dA-Fa-f]{2}|u[\dA-Fa-f]{4}|u{[\dA-Fa-f]+}|c[a-z])/g;
7
- const message = 'Use uppercase characters for the value of the escape sequence.';
8
12
 
9
13
  const create = context => {
10
14
  const check = ({node, original, regex = escapeWithLowercase, fix}) => {
@@ -13,7 +17,7 @@ const create = context => {
13
17
  if (fixed !== original) {
14
18
  context.report({
15
19
  node,
16
- message,
20
+ messageId: MESSAGE_ID,
17
21
  fix: fixer => fix ? fix(fixer, fixed) : fixer.replaceText(node, fixed)
18
22
  });
19
23
  }
@@ -54,6 +58,7 @@ module.exports = {
54
58
  docs: {
55
59
  url: getDocumentationUrl(__filename)
56
60
  },
57
- fixable: 'code'
61
+ fixable: 'code',
62
+ messages
58
63
  }
59
64
  };
@@ -16,8 +16,31 @@ const MESSAGE_ID_HAVE_PACKAGE = 'unicorn/havePackage';
16
16
  const MESSAGE_ID_DONT_HAVE_PACKAGE = 'unicorn/dontHavePackage';
17
17
  const MESSAGE_ID_VERSION_MATCHES = 'unicorn/versionMatches';
18
18
  const MESSAGE_ID_ENGINE_MATCHES = 'unicorn/engineMatches';
19
- const MESSAGE_ID_REMOVE_WHITESPACES = 'unicorn/removeWhitespaces';
19
+ const MESSAGE_ID_REMOVE_WHITESPACE = 'unicorn/removeWhitespaces';
20
20
  const MESSAGE_ID_MISSING_AT_SYMBOL = 'unicorn/missingAtSymbol';
21
+ const messages = {
22
+ [MESSAGE_ID_AVOID_MULTIPLE_DATES]:
23
+ 'Avoid using multiple expiration dates in TODO: {{expirationDates}}. {{message}}',
24
+ [MESSAGE_ID_EXPIRED_TODO]:
25
+ 'There is a TODO that is past due date: {{expirationDate}}. {{message}}',
26
+ [MESSAGE_ID_REACHED_PACKAGE_VERSION]:
27
+ 'There is a TODO that is past due package version: {{comparison}}. {{message}}',
28
+ [MESSAGE_ID_AVOID_MULTIPLE_PACKAGE_VERSIONS]:
29
+ 'Avoid using multiple package versions in TODO: {{versions}}. {{message}}',
30
+ [MESSAGE_ID_HAVE_PACKAGE]:
31
+ 'There is a TODO that is deprecated since you installed: {{package}}. {{message}}',
32
+ [MESSAGE_ID_DONT_HAVE_PACKAGE]:
33
+ 'There is a TODO that is deprecated since you uninstalled: {{package}}. {{message}}',
34
+ [MESSAGE_ID_VERSION_MATCHES]:
35
+ 'There is a TODO match for package version: {{comparison}}. {{message}}',
36
+ [MESSAGE_ID_ENGINE_MATCHES]:
37
+ 'There is a TODO match for Node.js version: {{comparison}}. {{message}}',
38
+ [MESSAGE_ID_REMOVE_WHITESPACE]:
39
+ 'Avoid using whitespace on TODO argument. On \'{{original}}\' use \'{{fix}}\'. {{message}}',
40
+ [MESSAGE_ID_MISSING_AT_SYMBOL]:
41
+ 'Missing \'@\' on TODO argument. On \'{{original}}\' use \'{{fix}}\'. {{message}}',
42
+ ...baseRule.meta.messages
43
+ };
21
44
 
22
45
  const packageResult = readPkgUp.sync();
23
46
  const hasPackage = Boolean(packageResult);
@@ -448,16 +471,16 @@ const create = context => {
448
471
  }
449
472
  }
450
473
 
451
- const withoutWhitespaces = unknown.replace(/ /g, '');
474
+ const withoutWhitespace = unknown.replace(/ /g, '');
452
475
 
453
- if (parseArgument(withoutWhitespaces).type !== 'unknowns') {
476
+ if (parseArgument(withoutWhitespace).type !== 'unknowns') {
454
477
  uses++;
455
478
  context.report({
456
479
  loc: comment.loc,
457
- messageId: MESSAGE_ID_REMOVE_WHITESPACES,
480
+ messageId: MESSAGE_ID_REMOVE_WHITESPACE,
458
481
  data: {
459
482
  original: unknown,
460
- fix: withoutWhitespaces,
483
+ fix: withoutWhitespace,
461
484
  message: parseTodoMessage(comment.value)
462
485
  }
463
486
  });
@@ -509,29 +532,7 @@ module.exports = {
509
532
  docs: {
510
533
  url: getDocumentationUrl(__filename)
511
534
  },
512
- messages: {
513
- [MESSAGE_ID_AVOID_MULTIPLE_DATES]:
514
- 'Avoid using multiple expiration dates in TODO: {{expirationDates}}. {{message}}',
515
- [MESSAGE_ID_EXPIRED_TODO]:
516
- 'There is a TODO that is past due date: {{expirationDate}}. {{message}}',
517
- [MESSAGE_ID_REACHED_PACKAGE_VERSION]:
518
- 'There is a TODO that is past due package version: {{comparison}}. {{message}}',
519
- [MESSAGE_ID_AVOID_MULTIPLE_PACKAGE_VERSIONS]:
520
- 'Avoid using multiple package versions in TODO: {{versions}}. {{message}}',
521
- [MESSAGE_ID_HAVE_PACKAGE]:
522
- 'There is a TODO that is deprecated since you installed: {{package}}. {{message}}',
523
- [MESSAGE_ID_DONT_HAVE_PACKAGE]:
524
- 'There is a TODO that is deprecated since you uninstalled: {{package}}. {{message}}',
525
- [MESSAGE_ID_VERSION_MATCHES]:
526
- 'There is a TODO match for package version: {{comparison}}. {{message}}',
527
- [MESSAGE_ID_ENGINE_MATCHES]:
528
- 'There is a TODO match for Node.js version: {{comparison}}. {{message}}',
529
- [MESSAGE_ID_REMOVE_WHITESPACES]:
530
- 'Avoid using whitespaces on TODO argument. On \'{{original}}\' use \'{{fix}}\'. {{message}}',
531
- [MESSAGE_ID_MISSING_AT_SYMBOL]:
532
- 'Missing \'@\' on TODO argument. On \'{{original}}\' use \'{{fix}}\'. {{message}}',
533
- ...baseRule.meta.messages
534
- },
535
+ messages,
535
536
  schema
536
537
  }
537
538
  };