eslint-plugin-unicorn-ts 0.0.1-security → 50.0.1

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.

Potentially problematic release.


This version of eslint-plugin-unicorn-ts might be problematic. Click here for more details.

Files changed (214) hide show
  1. package/configs/all.js +6 -0
  2. package/configs/flat-config-base.js +10 -0
  3. package/configs/legacy-config-base.js +10 -0
  4. package/configs/recommended.js +117 -0
  5. package/index.js +91 -0
  6. package/license +9 -0
  7. package/package.json +186 -4
  8. package/readme.md +356 -0
  9. package/rules/ast/call-or-new-expression.js +127 -0
  10. package/rules/ast/function-types.js +5 -0
  11. package/rules/ast/index.js +39 -0
  12. package/rules/ast/is-arrow-function-body.js +7 -0
  13. package/rules/ast/is-empty-node.js +20 -0
  14. package/rules/ast/is-expression-statement.js +11 -0
  15. package/rules/ast/is-function.js +8 -0
  16. package/rules/ast/is-member-expression.js +101 -0
  17. package/rules/ast/is-method-call.js +65 -0
  18. package/rules/ast/is-reference-identifier.js +156 -0
  19. package/rules/ast/is-static-require.js +14 -0
  20. package/rules/ast/is-undefined.js +7 -0
  21. package/rules/ast/literal.js +29 -0
  22. package/rules/better-regex.js +144 -0
  23. package/rules/catch-error-name.js +136 -0
  24. package/rules/consistent-destructuring.js +168 -0
  25. package/rules/consistent-function-scoping.js +223 -0
  26. package/rules/custom-error-definition.js +215 -0
  27. package/rules/empty-brace-spaces.js +72 -0
  28. package/rules/error-message.js +104 -0
  29. package/rules/escape-case.js +63 -0
  30. package/rules/expiring-todo-comments.js +580 -0
  31. package/rules/explicit-length-check.js +229 -0
  32. package/rules/filename-case.js +258 -0
  33. package/rules/fix/add-parenthesizes-to-return-or-throw-expression.js +21 -0
  34. package/rules/fix/append-argument.js +20 -0
  35. package/rules/fix/extend-fix-range.js +15 -0
  36. package/rules/fix/fix-space-around-keywords.js +35 -0
  37. package/rules/fix/index.js +23 -0
  38. package/rules/fix/remove-argument.js +32 -0
  39. package/rules/fix/remove-member-expression-property.js +11 -0
  40. package/rules/fix/remove-method-call.js +20 -0
  41. package/rules/fix/remove-parentheses.js +11 -0
  42. package/rules/fix/remove-spaces-after.js +14 -0
  43. package/rules/fix/rename-variable.js +9 -0
  44. package/rules/fix/replace-argument.js +8 -0
  45. package/rules/fix/replace-node-or-token-and-spaces-before.js +21 -0
  46. package/rules/fix/replace-reference-identifier.js +35 -0
  47. package/rules/fix/replace-string-literal.js +11 -0
  48. package/rules/fix/replace-string-raw.js +14 -0
  49. package/rules/fix/replace-template-element.js +11 -0
  50. package/rules/fix/switch-call-expression-to-new-expression.js +18 -0
  51. package/rules/fix/switch-new-expression-to-call-expression.js +34 -0
  52. package/rules/import-style.js +364 -0
  53. package/rules/new-for-builtins.js +85 -0
  54. package/rules/no-abusive-eslint-disable.js +48 -0
  55. package/rules/no-array-callback-reference.js +256 -0
  56. package/rules/no-array-for-each.js +473 -0
  57. package/rules/no-array-method-this-argument.js +188 -0
  58. package/rules/no-array-push-push.js +144 -0
  59. package/rules/no-array-reduce.js +126 -0
  60. package/rules/no-await-expression-member.js +90 -0
  61. package/rules/no-console-spaces.js +86 -0
  62. package/rules/no-document-cookie.js +25 -0
  63. package/rules/no-empty-file.js +57 -0
  64. package/rules/no-for-loop.js +427 -0
  65. package/rules/no-hex-escape.js +46 -0
  66. package/rules/no-instanceof-array.js +65 -0
  67. package/rules/no-invalid-remove-event-listener.js +60 -0
  68. package/rules/no-keyword-prefix.js +199 -0
  69. package/rules/no-lonely-if.js +151 -0
  70. package/rules/no-negated-condition.js +144 -0
  71. package/rules/no-nested-ternary.js +58 -0
  72. package/rules/no-new-array.js +104 -0
  73. package/rules/no-new-buffer.js +98 -0
  74. package/rules/no-null.js +153 -0
  75. package/rules/no-object-as-default-parameter.js +50 -0
  76. package/rules/no-process-exit.js +104 -0
  77. package/rules/no-static-only-class.js +224 -0
  78. package/rules/no-thenable.js +198 -0
  79. package/rules/no-this-assignment.js +38 -0
  80. package/rules/no-typeof-undefined.js +143 -0
  81. package/rules/no-unnecessary-await.js +107 -0
  82. package/rules/no-unnecessary-polyfills.js +176 -0
  83. package/rules/no-unreadable-array-destructuring.js +83 -0
  84. package/rules/no-unreadable-iife.js +45 -0
  85. package/rules/no-unused-properties.js +238 -0
  86. package/rules/no-useless-fallback-in-spread.js +68 -0
  87. package/rules/no-useless-length-check.js +152 -0
  88. package/rules/no-useless-promise-resolve-reject.js +212 -0
  89. package/rules/no-useless-spread.js +381 -0
  90. package/rules/no-useless-switch-case.js +71 -0
  91. package/rules/no-useless-undefined.js +301 -0
  92. package/rules/no-zero-fractions.js +79 -0
  93. package/rules/number-literal-case.js +52 -0
  94. package/rules/numeric-separators-style.js +181 -0
  95. package/rules/prefer-add-event-listener.js +188 -0
  96. package/rules/prefer-array-find.js +423 -0
  97. package/rules/prefer-array-flat-map.js +82 -0
  98. package/rules/prefer-array-flat.js +279 -0
  99. package/rules/prefer-array-index-of.js +32 -0
  100. package/rules/prefer-array-some.js +157 -0
  101. package/rules/prefer-at.js +374 -0
  102. package/rules/prefer-blob-reading-methods.js +45 -0
  103. package/rules/prefer-code-point.js +67 -0
  104. package/rules/prefer-date-now.js +135 -0
  105. package/rules/prefer-default-parameters.js +219 -0
  106. package/rules/prefer-dom-node-append.js +48 -0
  107. package/rules/prefer-dom-node-dataset.js +120 -0
  108. package/rules/prefer-dom-node-remove.js +122 -0
  109. package/rules/prefer-dom-node-text-content.js +75 -0
  110. package/rules/prefer-event-target.js +117 -0
  111. package/rules/prefer-export-from.js +413 -0
  112. package/rules/prefer-includes.js +98 -0
  113. package/rules/prefer-json-parse-buffer.js +159 -0
  114. package/rules/prefer-keyboard-event-key.js +186 -0
  115. package/rules/prefer-logical-operator-over-ternary.js +159 -0
  116. package/rules/prefer-math-trunc.js +109 -0
  117. package/rules/prefer-modern-dom-apis.js +141 -0
  118. package/rules/prefer-modern-math-apis.js +212 -0
  119. package/rules/prefer-module.js +349 -0
  120. package/rules/prefer-native-coercion-functions.js +185 -0
  121. package/rules/prefer-negative-index.js +213 -0
  122. package/rules/prefer-node-protocol.js +61 -0
  123. package/rules/prefer-number-properties.js +126 -0
  124. package/rules/prefer-object-from-entries.js +252 -0
  125. package/rules/prefer-optional-catch-binding.js +75 -0
  126. package/rules/prefer-prototype-methods.js +88 -0
  127. package/rules/prefer-query-selector.js +135 -0
  128. package/rules/prefer-reflect-apply.js +97 -0
  129. package/rules/prefer-regexp-test.js +156 -0
  130. package/rules/prefer-set-has.js +186 -0
  131. package/rules/prefer-set-size.js +103 -0
  132. package/rules/prefer-spread.js +529 -0
  133. package/rules/prefer-string-replace-all.js +145 -0
  134. package/rules/prefer-string-slice.js +182 -0
  135. package/rules/prefer-string-starts-ends-with.js +199 -0
  136. package/rules/prefer-string-trim-start-end.js +44 -0
  137. package/rules/prefer-switch.js +344 -0
  138. package/rules/prefer-ternary.js +282 -0
  139. package/rules/prefer-top-level-await.js +152 -0
  140. package/rules/prefer-type-error.js +151 -0
  141. package/rules/prevent-abbreviations.js +645 -0
  142. package/rules/relative-url-style.js +168 -0
  143. package/rules/require-array-join-separator.js +63 -0
  144. package/rules/require-number-to-fixed-digits-argument.js +54 -0
  145. package/rules/require-post-message-target-origin.js +71 -0
  146. package/rules/shared/abbreviations.js +262 -0
  147. package/rules/shared/dom-events.js +275 -0
  148. package/rules/shared/event-keys.js +52 -0
  149. package/rules/shared/negative-index.js +46 -0
  150. package/rules/shared/simple-array-search-rule.js +128 -0
  151. package/rules/shared/typed-array.js +16 -0
  152. package/rules/string-content.js +187 -0
  153. package/rules/switch-case-braces.js +109 -0
  154. package/rules/template-indent.js +219 -0
  155. package/rules/text-encoding-identifier-case.js +108 -0
  156. package/rules/throw-new-error.js +53 -0
  157. package/rules/utils/array-or-object-prototype-property.js +63 -0
  158. package/rules/utils/assert-token.js +32 -0
  159. package/rules/utils/avoid-capture.js +146 -0
  160. package/rules/utils/boolean.js +92 -0
  161. package/rules/utils/builtins.js +36 -0
  162. package/rules/utils/cartesian-product-samples.js +24 -0
  163. package/rules/utils/create-deprecated-rules.js +25 -0
  164. package/rules/utils/escape-string.js +26 -0
  165. package/rules/utils/escape-template-element-raw.js +6 -0
  166. package/rules/utils/get-ancestor.js +20 -0
  167. package/rules/utils/get-builtin-rule.js +7 -0
  168. package/rules/utils/get-call-expression-arguments-text.js +21 -0
  169. package/rules/utils/get-class-head-location.js +22 -0
  170. package/rules/utils/get-documentation-url.js +10 -0
  171. package/rules/utils/get-indent-string.js +11 -0
  172. package/rules/utils/get-previous-node.js +24 -0
  173. package/rules/utils/get-references.js +9 -0
  174. package/rules/utils/get-scopes.js +14 -0
  175. package/rules/utils/get-switch-case-head-location.js +21 -0
  176. package/rules/utils/get-variable-identifiers.js +7 -0
  177. package/rules/utils/global-reference-tracker.js +72 -0
  178. package/rules/utils/has-optional-chain-element.js +21 -0
  179. package/rules/utils/has-same-range.js +7 -0
  180. package/rules/utils/index.js +53 -0
  181. package/rules/utils/is-function-self-used-inside.js +43 -0
  182. package/rules/utils/is-left-hand-side.js +22 -0
  183. package/rules/utils/is-logical-expression.js +16 -0
  184. package/rules/utils/is-method-named.js +9 -0
  185. package/rules/utils/is-new-expression-with-parentheses.js +26 -0
  186. package/rules/utils/is-node-matches.js +53 -0
  187. package/rules/utils/is-node-value-not-dom-node.js +21 -0
  188. package/rules/utils/is-node-value-not-function.js +42 -0
  189. package/rules/utils/is-number.js +224 -0
  190. package/rules/utils/is-object-method.js +11 -0
  191. package/rules/utils/is-on-same-line.js +7 -0
  192. package/rules/utils/is-same-identifier.js +8 -0
  193. package/rules/utils/is-same-reference.js +173 -0
  194. package/rules/utils/is-shadowed.js +33 -0
  195. package/rules/utils/is-shorthand-export-local.js +9 -0
  196. package/rules/utils/is-shorthand-import-local.js +9 -0
  197. package/rules/utils/is-shorthand-property-assignment-pattern-left.js +10 -0
  198. package/rules/utils/is-shorthand-property-value.js +8 -0
  199. package/rules/utils/is-value-not-usable.js +5 -0
  200. package/rules/utils/lodash.js +1589 -0
  201. package/rules/utils/needs-semicolon.js +114 -0
  202. package/rules/utils/numeric.js +53 -0
  203. package/rules/utils/parentheses.js +73 -0
  204. package/rules/utils/resolve-variable-name.js +20 -0
  205. package/rules/utils/rule.js +190 -0
  206. package/rules/utils/should-add-parentheses-to-conditional-expression-child.js +17 -0
  207. package/rules/utils/should-add-parentheses-to-expression-statement-expression.js +26 -0
  208. package/rules/utils/should-add-parentheses-to-logical-expression-child.js +47 -0
  209. package/rules/utils/should-add-parentheses-to-member-expression-object.js +47 -0
  210. package/rules/utils/should-add-parentheses-to-new-expression-callee.js +32 -0
  211. package/rules/utils/should-add-parentheses-to-spread-element-argument.js +22 -0
  212. package/rules/utils/singular.js +18 -0
  213. package/rules/utils/to-location.js +21 -0
  214. package/README.md +0 -5
@@ -0,0 +1,114 @@
1
+ 'use strict';
2
+
3
+ // https://github.com/eslint/espree/blob/6b7d0b8100537dcd5c84a7fb17bbe28edcabe05d/lib/token-translator.js#L20
4
+ const tokenTypesNeedsSemicolon = new Set([
5
+ 'String',
6
+ 'Null',
7
+ 'Boolean',
8
+ 'Numeric',
9
+ 'RegularExpression',
10
+ ]);
11
+
12
+ const charactersMightNeedsSemicolon = new Set([
13
+ '[',
14
+ '(',
15
+ '/',
16
+ '`',
17
+ '+',
18
+ '-',
19
+ '*',
20
+ ',',
21
+ '.',
22
+ ]);
23
+
24
+ /**
25
+ Determines if a semicolon needs to be inserted before `code`, in order to avoid a SyntaxError.
26
+
27
+ @param {Token} tokenBefore Token before `code`.
28
+ @param {SourceCode} sourceCode
29
+ @param {String} [code] Code text to determine.
30
+ @returns {boolean} `true` if a semicolon needs to be inserted before `code`.
31
+ */
32
+
33
+ function needsSemicolon(tokenBefore, sourceCode, code) {
34
+ if (
35
+ code === ''
36
+ || (code && !charactersMightNeedsSemicolon.has(code.charAt(0)))
37
+ ) {
38
+ return false;
39
+ }
40
+
41
+ if (!tokenBefore) {
42
+ return false;
43
+ }
44
+
45
+ const {type, value, range} = tokenBefore;
46
+ const lastBlockNode = sourceCode.getNodeByRangeIndex(range[0]);
47
+ if (type === 'Punctuator') {
48
+ if (value === ';') {
49
+ return false;
50
+ }
51
+
52
+ if (value === ']') {
53
+ return true;
54
+ }
55
+
56
+ if (value === ')') {
57
+ switch (lastBlockNode.type) {
58
+ case 'IfStatement': {
59
+ if (sourceCode.getTokenBefore(lastBlockNode.consequent) === tokenBefore) {
60
+ return false;
61
+ }
62
+
63
+ break;
64
+ }
65
+
66
+ case 'ForStatement':
67
+ case 'ForInStatement':
68
+ case 'ForOfStatement':
69
+ case 'WhileStatement':
70
+ case 'DoWhileStatement':
71
+ case 'WithStatement': {
72
+ if (lastBlockNode.body && sourceCode.getTokenBefore(lastBlockNode.body) === tokenBefore) {
73
+ return false;
74
+ }
75
+
76
+ break;
77
+ }
78
+ // No default
79
+ }
80
+
81
+ return true;
82
+ }
83
+ }
84
+
85
+ if (tokenTypesNeedsSemicolon.has(type)) {
86
+ return true;
87
+ }
88
+
89
+ if (type === 'Template') {
90
+ return value.endsWith('`');
91
+ }
92
+
93
+ if (lastBlockNode.type === 'ObjectExpression') {
94
+ return true;
95
+ }
96
+
97
+ if (type === 'Identifier') {
98
+ // `for...of`
99
+ if (value === 'of' && lastBlockNode.type === 'ForOfStatement') {
100
+ return false;
101
+ }
102
+
103
+ // `await`
104
+ if (value === 'await' && lastBlockNode.type === 'AwaitExpression') {
105
+ return false;
106
+ }
107
+
108
+ return true;
109
+ }
110
+
111
+ return false;
112
+ }
113
+
114
+ module.exports = needsSemicolon;
@@ -0,0 +1,53 @@
1
+ 'use strict';
2
+
3
+ const {isNumberLiteral, isBigIntLiteral} = require('../ast/index.js');
4
+
5
+ // Determine whether this node is a decimal integer literal.
6
+ // Copied from https://github.com/eslint/eslint/blob/cc4871369645c3409dc56ded7a555af8a9f63d51/lib/rules/utils/ast-utils.js#L1237
7
+ const DECIMAL_INTEGER_PATTERN = /^(?:0|0[0-7]*[89]\d*|[1-9](?:_?\d)*)$/u;
8
+ const isDecimalInteger = text => DECIMAL_INTEGER_PATTERN.test(text);
9
+ const isDecimalIntegerNode = node => isNumberLiteral(node) && isDecimalInteger(node.raw);
10
+
11
+ const isNumeric = node => isNumberLiteral(node) || isBigIntLiteral(node);
12
+ const isLegacyOctal = node => isNumberLiteral(node) && /^0\d+$/.test(node.raw);
13
+
14
+ function getPrefix(text) {
15
+ let prefix = '';
16
+ let data = text;
17
+
18
+ if (/^0[box]/i.test(text)) {
19
+ prefix = text.slice(0, 2);
20
+ data = text.slice(2);
21
+ }
22
+
23
+ return {prefix, data};
24
+ }
25
+
26
+ function parseNumber(text) {
27
+ const {
28
+ number,
29
+ mark = '',
30
+ sign = '',
31
+ power = '',
32
+ } = text.match(/^(?<number>[\d._]*?)(?:(?<mark>[Ee])(?<sign>[+-])?(?<power>[\d_]+))?$/).groups;
33
+
34
+ return {number, mark, sign, power};
35
+ }
36
+
37
+ function parseFloatNumber(text) {
38
+ const parts = text.split('.');
39
+ const [integer, fractional = ''] = parts;
40
+ const dot = parts.length === 2 ? '.' : '';
41
+
42
+ return {integer, dot, fractional};
43
+ }
44
+
45
+ module.exports = {
46
+ isDecimalIntegerNode,
47
+ isDecimalInteger,
48
+ isNumeric,
49
+ isLegacyOctal,
50
+ getPrefix,
51
+ parseNumber,
52
+ parseFloatNumber,
53
+ };
@@ -0,0 +1,73 @@
1
+ 'use strict';
2
+ const {isParenthesized, isOpeningParenToken, isClosingParenToken} = require('@eslint-community/eslint-utils');
3
+
4
+ /*
5
+ Get how many times the node is parenthesized.
6
+
7
+ @param {Node} node - The node to be checked.
8
+ @param {SourceCode} sourceCode - The source code object.
9
+ @returns {number}
10
+ */
11
+ function getParenthesizedTimes(node, sourceCode) {
12
+ let times = 0;
13
+
14
+ while (isParenthesized(times + 1, node, sourceCode)) {
15
+ times++;
16
+ }
17
+
18
+ return times;
19
+ }
20
+
21
+ /*
22
+ Get all parentheses tokens around the node.
23
+
24
+ @param {Node} node - The node to be checked.
25
+ @param {SourceCode} sourceCode - The source code object.
26
+ @returns {Token[]}
27
+ */
28
+ function getParentheses(node, sourceCode) {
29
+ const count = getParenthesizedTimes(node, sourceCode);
30
+
31
+ if (count === 0) {
32
+ return [];
33
+ }
34
+
35
+ return [
36
+ ...sourceCode.getTokensBefore(node, {count, filter: isOpeningParenToken}),
37
+ ...sourceCode.getTokensAfter(node, {count, filter: isClosingParenToken}),
38
+ ];
39
+ }
40
+
41
+ /*
42
+ Get the parenthesized range of the node.
43
+
44
+ @param {Node} node - The node to be checked.
45
+ @param {SourceCode} sourceCode - The source code object.
46
+ @returns {number[]}
47
+ */
48
+ function getParenthesizedRange(node, sourceCode) {
49
+ const parentheses = getParentheses(node, sourceCode);
50
+ const [start] = (parentheses[0] || node).range;
51
+ const [, end] = (parentheses.at(-1) || node).range;
52
+ return [start, end];
53
+ }
54
+
55
+ /*
56
+ Get the parenthesized text of the node.
57
+
58
+ @param {Node} node - The node to be checked.
59
+ @param {SourceCode} sourceCode - The source code object.
60
+ @returns {string}
61
+ */
62
+ function getParenthesizedText(node, sourceCode) {
63
+ const [start, end] = getParenthesizedRange(node, sourceCode);
64
+ return sourceCode.text.slice(start, end);
65
+ }
66
+
67
+ module.exports = {
68
+ isParenthesized,
69
+ getParenthesizedTimes,
70
+ getParentheses,
71
+ getParenthesizedRange,
72
+ getParenthesizedText,
73
+ };
@@ -0,0 +1,20 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ Finds a variable named `name` in the scope `scope` (or it's parents).
5
+
6
+ @param {string} name - The variable name to be resolve.
7
+ @param {Scope} scope - The scope to look for the variable in.
8
+ @returns {Variable?} - The found variable, if any.
9
+ */
10
+ module.exports = (name, scope) => {
11
+ while (scope) {
12
+ const variable = scope.set.get(name);
13
+
14
+ if (variable) {
15
+ return variable;
16
+ }
17
+
18
+ scope = scope.upper;
19
+ }
20
+ };
@@ -0,0 +1,190 @@
1
+ 'use strict';
2
+ const path = require('node:path');
3
+ const fs = require('node:fs');
4
+ const getDocumentationUrl = require('./get-documentation-url.js');
5
+
6
+ const isIterable = object => typeof object?.[Symbol.iterator] === 'function';
7
+
8
+ class FixAbortError extends Error {}
9
+ const fixOptions = {
10
+ abort() {
11
+ throw new FixAbortError('Fix aborted.');
12
+ },
13
+ };
14
+
15
+ function wrapFixFunction(fix) {
16
+ return fixer => {
17
+ const result = fix(fixer, fixOptions);
18
+
19
+ if (isIterable(result)) {
20
+ try {
21
+ return [...result];
22
+ } catch (error) {
23
+ if (error instanceof FixAbortError) {
24
+ return;
25
+ }
26
+
27
+ /* c8 ignore next */
28
+ throw error;
29
+ }
30
+ }
31
+
32
+ return result;
33
+ };
34
+ }
35
+
36
+ function reportListenerProblems(problems, context) {
37
+ if (!problems) {
38
+ return;
39
+ }
40
+
41
+ if (!isIterable(problems)) {
42
+ problems = [problems];
43
+ }
44
+
45
+ for (const problem of problems) {
46
+ if (problem.fix) {
47
+ problem.fix = wrapFixFunction(problem.fix);
48
+ }
49
+
50
+ if (Array.isArray(problem.suggest)) {
51
+ for (const suggest of problem.suggest) {
52
+ if (suggest.fix) {
53
+ suggest.fix = wrapFixFunction(suggest.fix);
54
+ }
55
+
56
+ suggest.data = {
57
+ ...problem.data,
58
+ ...suggest.data,
59
+ };
60
+ }
61
+ }
62
+
63
+ context.report(problem);
64
+ }
65
+ }
66
+
67
+ // `checkVueTemplate` function will wrap `create` function, there is no need to wrap twice
68
+ const wrappedFunctions = new Set();
69
+ function reportProblems(create) {
70
+ if (wrappedFunctions.has(create)) {
71
+ return create;
72
+ }
73
+
74
+ const wrapped = context => {
75
+ const listeners = {};
76
+ const addListener = (selector, listener) => {
77
+ listeners[selector] ??= [];
78
+ listeners[selector].push(listener);
79
+ };
80
+
81
+ const contextProxy = new Proxy(context, {
82
+ get(target, property, receiver) {
83
+ if (property === 'on') {
84
+ return (selectorOrSelectors, listener) => {
85
+ const selectors = Array.isArray(selectorOrSelectors) ? selectorOrSelectors : [selectorOrSelectors];
86
+ for (const selector of selectors) {
87
+ addListener(selector, listener);
88
+ }
89
+ };
90
+ }
91
+
92
+ if (property === 'onExit') {
93
+ return (selectorOrSelectors, listener) => {
94
+ const selectors = Array.isArray(selectorOrSelectors) ? selectorOrSelectors : [selectorOrSelectors];
95
+ for (const selector of selectors) {
96
+ addListener(`${selector}:exit`, listener);
97
+ }
98
+ };
99
+ }
100
+
101
+ return Reflect.get(target, property, receiver);
102
+ },
103
+ });
104
+
105
+ for (const [selector, listener] of Object.entries(create(contextProxy) ?? {})) {
106
+ addListener(selector, listener);
107
+ }
108
+
109
+ return Object.fromEntries(
110
+ Object.entries(listeners)
111
+ .map(([selector, listeners]) => [
112
+ selector,
113
+ // Listener arguments can be `codePath, node` or `node`
114
+ (...listenerArguments) => {
115
+ for (const listener of listeners) {
116
+ reportListenerProblems(listener(...listenerArguments), context);
117
+ }
118
+ },
119
+ ]),
120
+ );
121
+ };
122
+
123
+ wrappedFunctions.add(wrapped);
124
+
125
+ return wrapped;
126
+ }
127
+
128
+ function checkVueTemplate(create, options) {
129
+ const {
130
+ visitScriptBlock,
131
+ } = {
132
+ visitScriptBlock: true,
133
+ ...options,
134
+ };
135
+
136
+ create = reportProblems(create);
137
+
138
+ const wrapped = context => {
139
+ const listeners = create(context);
140
+ const {parserServices} = context.sourceCode;
141
+
142
+ // `vue-eslint-parser`
143
+ if (parserServices?.defineTemplateBodyVisitor) {
144
+ return visitScriptBlock
145
+ ? parserServices.defineTemplateBodyVisitor(listeners, listeners)
146
+ : parserServices.defineTemplateBodyVisitor(listeners);
147
+ }
148
+
149
+ return listeners;
150
+ };
151
+
152
+ wrappedFunctions.add(wrapped);
153
+ return wrapped;
154
+ }
155
+
156
+ /** @returns {import('eslint').Rule.RuleModule} */
157
+ function loadRule(ruleId) {
158
+ const rule = require(`../${ruleId}`);
159
+
160
+ return {
161
+ meta: {
162
+ // If there is are, options add `[]` so ESLint can validate that no data is passed to the rule.
163
+ // https://github.com/not-an-aardvark/eslint-plugin-eslint-plugin/blob/master/docs/rules/require-meta-schema.md
164
+ schema: [],
165
+ ...rule.meta,
166
+ docs: {
167
+ ...rule.meta.docs,
168
+ url: getDocumentationUrl(ruleId),
169
+ },
170
+ },
171
+ create: reportProblems(rule.create),
172
+ };
173
+ }
174
+
175
+ function loadRules() {
176
+ return Object.fromEntries(
177
+ fs.readdirSync(path.join(__dirname, '..'), {withFileTypes: true})
178
+ .filter(file => file.isFile())
179
+ .map(file => {
180
+ const ruleId = path.basename(file.name, '.js');
181
+ return [ruleId, loadRule(ruleId)];
182
+ }),
183
+ );
184
+ }
185
+
186
+ module.exports = {
187
+ loadRule,
188
+ loadRules,
189
+ checkVueTemplate,
190
+ };
@@ -0,0 +1,17 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ Check if parentheses should be added to a `node` when it's used as child of `ConditionalExpression`.
5
+
6
+ @param {Node} node - The AST node to check.
7
+ @returns {boolean}
8
+ */
9
+ function shouldAddParenthesesToConditionalExpressionChild(node) {
10
+ return node.type === 'AwaitExpression'
11
+ // Lower precedence, see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence#Table
12
+ || node.type === 'AssignmentExpression'
13
+ || node.type === 'YieldExpression'
14
+ || node.type === 'SequenceExpression';
15
+ }
16
+
17
+ module.exports = shouldAddParenthesesToConditionalExpressionChild;
@@ -0,0 +1,26 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ Check if parentheses should to be added to a `node` when it's used as an `expression` of `ExpressionStatement`.
5
+
6
+ @param {Node} node - The AST node to check.
7
+ @param {SourceCode} sourceCode - The source code object.
8
+ @returns {boolean}
9
+ */
10
+ function shouldAddParenthesesToExpressionStatementExpression(node) {
11
+ switch (node.type) {
12
+ case 'ObjectExpression': {
13
+ return true;
14
+ }
15
+
16
+ case 'AssignmentExpression': {
17
+ return node.left.type === 'ObjectPattern' || node.left.type === 'ArrayPattern';
18
+ }
19
+
20
+ default: {
21
+ return false;
22
+ }
23
+ }
24
+ }
25
+
26
+ module.exports = shouldAddParenthesesToExpressionStatementExpression;
@@ -0,0 +1,47 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ Check if parentheses should be added to a `node` when it's used as child of `LogicalExpression`.
5
+ @param {Node} node - The AST node to check.
6
+ @param {{operator: string, property: string}} options - Options
7
+ @returns {boolean}
8
+ */
9
+ function shouldAddParenthesesToLogicalExpressionChild(node, {operator, property}) {
10
+ // We are not using this, but we can improve this function with it
11
+ /* c8 ignore next 3 */
12
+ if (!property) {
13
+ throw new Error('`property` is required.');
14
+ }
15
+
16
+ if (
17
+ node.type === 'LogicalExpression'
18
+ && node.operator === operator
19
+ ) {
20
+ return false;
21
+ }
22
+
23
+ // Not really needed, but more readable
24
+ if (
25
+ node.type === 'AwaitExpression'
26
+ || node.type === 'BinaryExpression'
27
+ ) {
28
+ return true;
29
+ }
30
+
31
+ // Lower precedence than `LogicalExpression`
32
+ // see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence#Table
33
+ if (
34
+ node.type === 'LogicalExpression'
35
+ || node.type === 'ConditionalExpression'
36
+ || node.type === 'AssignmentExpression'
37
+ || node.type === 'ArrowFunctionExpression'
38
+ || node.type === 'YieldExpression'
39
+ || node.type === 'SequenceExpression'
40
+ ) {
41
+ return true;
42
+ }
43
+
44
+ return false;
45
+ }
46
+
47
+ module.exports = shouldAddParenthesesToLogicalExpressionChild;
@@ -0,0 +1,47 @@
1
+ 'use strict';
2
+
3
+ const isNewExpressionWithParentheses = require('./is-new-expression-with-parentheses.js');
4
+ const {isDecimalIntegerNode} = require('./numeric.js');
5
+
6
+ /**
7
+ Check if parentheses should to be added to a `node` when it's used as an `object` of `MemberExpression`.
8
+
9
+ @param {Node} node - The AST node to check.
10
+ @param {SourceCode} sourceCode - The source code object.
11
+ @returns {boolean}
12
+ */
13
+ function shouldAddParenthesesToMemberExpressionObject(node, sourceCode) {
14
+ switch (node.type) {
15
+ // This is not a full list. Some other nodes like `FunctionDeclaration` don't need parentheses,
16
+ // but it's not possible to be in the place we are checking at this point.
17
+ case 'Identifier':
18
+ case 'MemberExpression':
19
+ case 'CallExpression':
20
+ case 'ChainExpression':
21
+ case 'TemplateLiteral':
22
+ case 'ThisExpression':
23
+ case 'ArrayExpression':
24
+ case 'FunctionExpression': {
25
+ return false;
26
+ }
27
+
28
+ case 'NewExpression': {
29
+ return !isNewExpressionWithParentheses(node, sourceCode);
30
+ }
31
+
32
+ case 'Literal': {
33
+ /* c8 ignore next */
34
+ if (isDecimalIntegerNode(node)) {
35
+ return true;
36
+ }
37
+
38
+ return false;
39
+ }
40
+
41
+ default: {
42
+ return true;
43
+ }
44
+ }
45
+ }
46
+
47
+ module.exports = shouldAddParenthesesToMemberExpressionObject;
@@ -0,0 +1,32 @@
1
+ 'use strict';
2
+
3
+ // Copied from https://github.com/eslint/eslint/blob/aa87329d919f569404ca573b439934552006572f/lib/rules/no-extra-parens.js#L448
4
+ /**
5
+ Check if a member expression contains a call expression.
6
+
7
+ @param {ASTNode} node - The `MemberExpression` node to evaluate.
8
+ @returns {boolean} true if found, false if not.
9
+ */
10
+ function doesMemberExpressionContainCallExpression(node) {
11
+ let currentNode = node.object;
12
+ let currentNodeType = node.object.type;
13
+
14
+ while (currentNodeType === 'MemberExpression') {
15
+ currentNode = currentNode.object;
16
+ currentNodeType = currentNode.type;
17
+ }
18
+
19
+ return currentNodeType === 'CallExpression';
20
+ }
21
+
22
+ /**
23
+ Check if parentheses should be added to a `node` when it's used as `callee` of `NewExpression`.
24
+
25
+ @param {Node} node - The AST node to check.
26
+ @returns {boolean}
27
+ */
28
+ function shouldAddParenthesesToNewExpressionCallee(node) {
29
+ return node.type === 'MemberExpression' && doesMemberExpressionContainCallExpression(node);
30
+ }
31
+
32
+ module.exports = shouldAddParenthesesToNewExpressionCallee;
@@ -0,0 +1,22 @@
1
+ 'use strict';
2
+
3
+ const nodeTypesDoNotNeedParentheses = new Set([
4
+ 'CallExpression',
5
+ 'Identifier',
6
+ 'Literal',
7
+ 'MemberExpression',
8
+ 'NewExpression',
9
+ 'TemplateLiteral',
10
+ 'ThisExpression',
11
+ ]);
12
+
13
+ /**
14
+ Check if parentheses should be added to a `node` when it's used as `argument` of `SpreadElement`.
15
+
16
+ @param {Node} node - The AST node to check.
17
+ @returns {boolean}
18
+ */
19
+ const shouldAddParenthesesToSpreadElementArgument = node =>
20
+ !nodeTypesDoNotNeedParentheses.has(node.type);
21
+
22
+ module.exports = shouldAddParenthesesToSpreadElementArgument;
@@ -0,0 +1,18 @@
1
+ 'use strict';
2
+
3
+ const {singular: pluralizeSingular} = require('pluralize');
4
+
5
+ /**
6
+ Singularizes a word/name, i.e. `items` to `item`.
7
+
8
+ @param {string} original - The word/name to singularize.
9
+ @returns {string|undefined} - The singularized result, or `undefined` if attempting singularization resulted in no change.
10
+ */
11
+ const singular = original => {
12
+ const singularized = pluralizeSingular(original);
13
+ if (singularized !== original) {
14
+ return singularized;
15
+ }
16
+ };
17
+
18
+ module.exports = singular;
@@ -0,0 +1,21 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ Get location info for the given node or range.
5
+
6
+ @param {import('estree').Node | number[]} nodeOrRange - The AST node or range to get the location for.
7
+ @param {import('eslint').SourceCode} sourceCode - The source code object.
8
+ @param {int} [startOffset] - Start position offset.
9
+ @param {int} [endOffset] - End position offset.
10
+ @returns {import('estree').SourceLocation}
11
+ */
12
+ function toLocation(nodeOrRange, sourceCode, startOffset = 0, endOffset = 0) {
13
+ const [start, end] = Array.isArray(nodeOrRange) ? nodeOrRange : nodeOrRange.range;
14
+
15
+ return {
16
+ start: sourceCode.getLocFromIndex(start + startOffset),
17
+ end: sourceCode.getLocFromIndex(end + endOffset),
18
+ };
19
+ }
20
+
21
+ module.exports = toLocation;
package/README.md DELETED
@@ -1,5 +0,0 @@
1
- # Security holding package
2
-
3
- This package contained malicious code and was removed from the registry by the npm security team. A placeholder was published to ensure users are not affected in the future.
4
-
5
- Please refer to www.npmjs.com/advisories?search=eslint-plugin-unicorn-ts for more information.