eslint-plugin-th-rules 2.7.1 → 2.8.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.
- package/README.md +171 -11
- package/dist/configs/bundles/recommended-react.d.ts +199 -0
- package/dist/configs/bundles/recommended-react.js +11 -0
- package/dist/configs/bundles/recommended-typescript.d.ts +190 -0
- package/dist/configs/bundles/recommended-typescript.js +6 -0
- package/dist/configs/bundles/recommended.d.ts +190 -0
- package/dist/configs/bundles/recommended.js +8 -0
- package/dist/configs/core/base.d.ts +170 -0
- package/dist/configs/core/base.js +23 -0
- package/dist/configs/core/react.d.ts +6 -0
- package/dist/configs/core/react.js +8 -0
- package/dist/configs/core/typescript.d.ts +2 -0
- package/dist/configs/core/typescript.js +19 -0
- package/dist/configs/externals/base.d.ts +15 -0
- package/dist/configs/externals/base.js +16 -0
- package/dist/configs/externals/opinionated.d.ts +10 -0
- package/dist/configs/externals/opinionated.js +12 -0
- package/dist/index.d.ts +1170 -0
- package/dist/index.js +21 -0
- package/dist/plugin.d.ts +5 -0
- package/dist/plugin.js +14 -0
- package/dist/rules/no-boolean-coercion.d.ts +5 -0
- package/dist/rules/no-boolean-coercion.js +98 -0
- package/dist/rules/no-comments.d.ts +11 -0
- package/dist/rules/no-comments.js +83 -0
- package/dist/rules/no-default-export.d.ts +5 -0
- package/dist/rules/no-default-export.js +61 -0
- package/dist/rules/no-destructuring.d.ts +8 -0
- package/dist/rules/no-destructuring.js +121 -0
- package/dist/rules/prefer-is-empty.d.ts +5 -0
- package/dist/rules/prefer-is-empty.js +101 -0
- package/dist/rules/schemas-in-schemas-file.d.ts +9 -0
- package/dist/rules/schemas-in-schemas-file.js +141 -0
- package/dist/rules/top-level-functions.d.ts +5 -0
- package/dist/rules/top-level-functions.js +153 -0
- package/dist/rules/types-in-dts.d.ts +8 -0
- package/dist/rules/types-in-dts.js +76 -0
- package/package.json +25 -14
- package/.github/dependabot.yml +0 -15
- package/.github/workflows/codecov.yml +0 -26
- package/.github/workflows/codeql.yml +0 -82
- package/.github/workflows/dependency-review.yml +0 -20
- package/.github/workflows/main.yml +0 -43
- package/.github/workflows/scorecard.yml +0 -72
- package/.github/workflows/snyk-security.yml +0 -67
- package/.releaserc +0 -13
- package/.vscode/settings.json +0 -8
- package/.yarn/releases/yarn-4.12.0.cjs +0 -942
- package/.yarnrc.yml +0 -3
- package/CHANGELOG.md +0 -628
- package/SECURITY.md +0 -48
- package/docs/rules/no-boolean-coercion.md +0 -9
- package/docs/rules/no-comments.md +0 -50
- package/docs/rules/no-default-export.md +0 -26
- package/docs/rules/no-destructuring.md +0 -40
- package/docs/rules/prefer-is-empty.md +0 -9
- package/docs/rules/schemas-in-schemas-file.md +0 -170
- package/docs/rules/top-level-functions.md +0 -48
- package/docs/rules/types-in-dts.md +0 -112
- package/renovate.json +0 -3
- package/scripts/verify.mjs +0 -16
- package/src/index.js +0 -144
- package/src/rules/no-boolean-coercion.js +0 -124
- package/src/rules/no-comments.js +0 -94
- package/src/rules/no-default-export.js +0 -64
- package/src/rules/no-destructuring.js +0 -114
- package/src/rules/prefer-is-empty.js +0 -104
- package/src/rules/schemas-in-schemas-file.js +0 -191
- package/src/rules/top-level-functions.js +0 -200
- package/src/rules/types-in-dts.js +0 -94
- package/tests/no-boolean-coercion.test.ts +0 -83
- package/tests/prefer-is-empty.test.ts +0 -148
- package/tsconfig.json +0 -22
- package/xo.config.ts +0 -2
|
@@ -1,200 +0,0 @@
|
|
|
1
|
-
/* eslint-disable unicorn/prefer-module */
|
|
2
|
-
|
|
3
|
-
const meta = {
|
|
4
|
-
type: 'suggestion',
|
|
5
|
-
docs: {
|
|
6
|
-
description: 'Require all top-level functions to be named/regular functions.',
|
|
7
|
-
category: 'Stylistic Issues',
|
|
8
|
-
recommended: false,
|
|
9
|
-
url: 'https://github.com/tomerh2001/eslint-plugin-th-rules/blob/main/docs/rules/top-level-functions.md',
|
|
10
|
-
},
|
|
11
|
-
fixable: 'code',
|
|
12
|
-
schema: [],
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Build a replacement code string for an arrow function:
|
|
17
|
-
*
|
|
18
|
-
* @param {string} funcName - The name of the new function.
|
|
19
|
-
* @param {ArrowFunctionExpression} arrowNode - The ArrowFunctionExpression node.
|
|
20
|
-
* @param {import('eslint').SourceCode} sourceCode - The ESLint SourceCode object.
|
|
21
|
-
* @param {boolean} isExport - Whether or not this function is exported (e.g., `export const foo = ...`).
|
|
22
|
-
* @returns {string} The replacement code.
|
|
23
|
-
*/
|
|
24
|
-
function buildArrowFunctionReplacement(functionName, arrowNode, sourceCode, isExport) {
|
|
25
|
-
const asyncKeyword = arrowNode.async ? 'async ' : '';
|
|
26
|
-
const exportKeyword = isExport ? 'export ' : '';
|
|
27
|
-
|
|
28
|
-
const parametersText = arrowNode.params.map(parameter => sourceCode.getText(parameter)).join(', ');
|
|
29
|
-
|
|
30
|
-
let bodyText;
|
|
31
|
-
if (arrowNode.body.type === 'BlockStatement') {
|
|
32
|
-
bodyText = sourceCode.getText(arrowNode.body);
|
|
33
|
-
} else {
|
|
34
|
-
const expressionText = sourceCode.getText(arrowNode.body);
|
|
35
|
-
bodyText = `{ return ${expressionText}; }`;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
return `${exportKeyword}${asyncKeyword}function ${functionName}(${parametersText}) ${bodyText}`;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* Build a replacement code string for a function expression:
|
|
43
|
-
*
|
|
44
|
-
* @param {string} funcName - The name of the new function.
|
|
45
|
-
* @param {FunctionExpression} funcExprNode - The FunctionExpression node.
|
|
46
|
-
* @param {import('eslint').SourceCode} sourceCode - The ESLint SourceCode object.
|
|
47
|
-
* @param {boolean} isExport - Whether or not this function is exported.
|
|
48
|
-
* @returns {string} The replacement code.
|
|
49
|
-
*/
|
|
50
|
-
function buildFunctionExpressionReplacement(functionName, functionExprNode, sourceCode, isExport) {
|
|
51
|
-
const asyncKeyword = functionExprNode.async ? 'async ' : '';
|
|
52
|
-
const exportKeyword = isExport ? 'export ' : '';
|
|
53
|
-
|
|
54
|
-
const parametersText = functionExprNode.params.map(parameter => sourceCode.getText(parameter)).join(', ');
|
|
55
|
-
const bodyText = sourceCode.getText(functionExprNode.body);
|
|
56
|
-
|
|
57
|
-
return `${exportKeyword}${asyncKeyword}function ${functionName}(${parametersText}) ${bodyText}`;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Build a replacement for an anonymous top-level FunctionDeclaration (including async).
|
|
62
|
-
*
|
|
63
|
-
* @param {import('eslint').SourceCode} sourceCode
|
|
64
|
-
* @param {import('estree').FunctionDeclaration} node
|
|
65
|
-
* @param {string} [funcName='defaultFunction']
|
|
66
|
-
* @param {boolean} [isExport=false]
|
|
67
|
-
*/
|
|
68
|
-
function buildAnonymousFunctionDeclarationReplacement(sourceCode, node, functionName = 'defaultFunction', isExport = false) {
|
|
69
|
-
const originalText = sourceCode.getText(node);
|
|
70
|
-
const exportKeyword = isExport ? 'export ' : '';
|
|
71
|
-
|
|
72
|
-
let replaced = originalText;
|
|
73
|
-
const asyncFunctionRegex = /^\s*async\s+function\s*\(/;
|
|
74
|
-
const functionRegex = /^\s*function\s*\(/;
|
|
75
|
-
|
|
76
|
-
replaced = asyncFunctionRegex.test(replaced) ? replaced.replace(asyncFunctionRegex, `async function ${functionName}(`) : replaced.replace(functionRegex, `function ${functionName}(`);
|
|
77
|
-
|
|
78
|
-
if (isExport && !replaced.trimStart().startsWith('export')) {
|
|
79
|
-
replaced = `${exportKeyword}${replaced}`;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
return replaced;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
function create(context) {
|
|
86
|
-
const sourceCode = context.getSourceCode();
|
|
87
|
-
|
|
88
|
-
return {
|
|
89
|
-
VariableDeclarator(node) {
|
|
90
|
-
const declParent = node.parent;
|
|
91
|
-
const grandParent = declParent.parent;
|
|
92
|
-
|
|
93
|
-
const isTopLevel
|
|
94
|
-
= grandParent.type === 'Program'
|
|
95
|
-
|| grandParent.type === 'ExportNamedDeclaration'
|
|
96
|
-
|| grandParent.type === 'ExportDefaultDeclaration';
|
|
97
|
-
|
|
98
|
-
if (!isTopLevel) {
|
|
99
|
-
return;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
const isExport
|
|
103
|
-
= grandParent.type === 'ExportNamedDeclaration'
|
|
104
|
-
|| grandParent.type === 'ExportDefaultDeclaration';
|
|
105
|
-
|
|
106
|
-
if (!node.init) {
|
|
107
|
-
return;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
const functionName = node.id && node.id.name;
|
|
111
|
-
if (!functionName) {
|
|
112
|
-
return;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
if (node.init.type === 'ArrowFunctionExpression') {
|
|
116
|
-
context.report({
|
|
117
|
-
node: node.init,
|
|
118
|
-
message: 'Top-level arrow functions must be named/regular functions.',
|
|
119
|
-
fix(fixer) {
|
|
120
|
-
const replacement = buildArrowFunctionReplacement(
|
|
121
|
-
functionName,
|
|
122
|
-
node.init,
|
|
123
|
-
sourceCode,
|
|
124
|
-
isExport,
|
|
125
|
-
);
|
|
126
|
-
|
|
127
|
-
return fixer.replaceText(
|
|
128
|
-
isExport ? grandParent : declParent,
|
|
129
|
-
replacement,
|
|
130
|
-
);
|
|
131
|
-
},
|
|
132
|
-
});
|
|
133
|
-
} else if (node.init.type === 'FunctionExpression') {
|
|
134
|
-
context.report({
|
|
135
|
-
node: node.init,
|
|
136
|
-
message: 'Top-level function expressions must be named/regular functions.',
|
|
137
|
-
fix(fixer) {
|
|
138
|
-
const replacement = buildFunctionExpressionReplacement(
|
|
139
|
-
functionName,
|
|
140
|
-
node.init,
|
|
141
|
-
sourceCode,
|
|
142
|
-
isExport,
|
|
143
|
-
);
|
|
144
|
-
return fixer.replaceText(
|
|
145
|
-
isExport ? grandParent : declParent,
|
|
146
|
-
replacement,
|
|
147
|
-
);
|
|
148
|
-
},
|
|
149
|
-
});
|
|
150
|
-
}
|
|
151
|
-
},
|
|
152
|
-
|
|
153
|
-
FunctionDeclaration(node) {
|
|
154
|
-
if (node.id) {
|
|
155
|
-
return;
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
const parent = node.parent;
|
|
159
|
-
|
|
160
|
-
const isTopLevel
|
|
161
|
-
= parent.type === 'Program'
|
|
162
|
-
|| parent.type === 'ExportNamedDeclaration'
|
|
163
|
-
|| parent.type === 'ExportDefaultDeclaration';
|
|
164
|
-
|
|
165
|
-
if (!isTopLevel) {
|
|
166
|
-
return;
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
const isExport
|
|
170
|
-
= parent.type === 'ExportNamedDeclaration'
|
|
171
|
-
|| parent.type === 'ExportDefaultDeclaration';
|
|
172
|
-
|
|
173
|
-
context.report({
|
|
174
|
-
node,
|
|
175
|
-
message: 'Top-level anonymous function declarations must be named.',
|
|
176
|
-
fix(fixer) {
|
|
177
|
-
const newName = 'defaultFunction';
|
|
178
|
-
const replacement = buildAnonymousFunctionDeclarationReplacement(
|
|
179
|
-
sourceCode,
|
|
180
|
-
node,
|
|
181
|
-
newName,
|
|
182
|
-
isExport,
|
|
183
|
-
);
|
|
184
|
-
|
|
185
|
-
return fixer.replaceText(
|
|
186
|
-
isExport ? parent : node,
|
|
187
|
-
replacement,
|
|
188
|
-
);
|
|
189
|
-
},
|
|
190
|
-
});
|
|
191
|
-
},
|
|
192
|
-
};
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
const rule = {
|
|
196
|
-
meta,
|
|
197
|
-
create,
|
|
198
|
-
};
|
|
199
|
-
|
|
200
|
-
module.exports = rule;
|
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @fileoverview Enforce that TypeScript type declarations exist only in .d.ts files.
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
const meta = {
|
|
6
|
-
type: 'problem',
|
|
7
|
-
docs: {
|
|
8
|
-
description: 'Require TypeScript type declarations (type/interface/enum) to be placed in .d.ts files',
|
|
9
|
-
category: 'Best Practices',
|
|
10
|
-
recommended: true,
|
|
11
|
-
url: 'https://github.com/tomerh2001/eslint-plugin-th-rules/blob/main/docs/rules/types-in-dts.md',
|
|
12
|
-
},
|
|
13
|
-
schema: [
|
|
14
|
-
{
|
|
15
|
-
type: 'object',
|
|
16
|
-
properties: {
|
|
17
|
-
allowEnums: {type: 'boolean'},
|
|
18
|
-
allowDeclare: {type: 'boolean'},
|
|
19
|
-
},
|
|
20
|
-
additionalProperties: false,
|
|
21
|
-
},
|
|
22
|
-
],
|
|
23
|
-
messages: {
|
|
24
|
-
moveToDts:
|
|
25
|
-
'Type declarations must be defined in a a .d.ts file.',
|
|
26
|
-
},
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* @param {import('eslint').Rule.RuleContext} context
|
|
31
|
-
*/
|
|
32
|
-
function create(context) {
|
|
33
|
-
const options = context.options?.[0] ?? {};
|
|
34
|
-
const allowEnums = Boolean(options.allowEnums);
|
|
35
|
-
const allowDeclare = Boolean(options.allowDeclare);
|
|
36
|
-
|
|
37
|
-
function isDtsFile(filename) {
|
|
38
|
-
if (!filename || filename === '<input>') {
|
|
39
|
-
return false;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
return filename.endsWith('.d.ts');
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
function hasDeclareModifier(node) {
|
|
46
|
-
if (node && node.declare === true) {
|
|
47
|
-
return true;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
const mods = node && Array.isArray(node.modifiers) ? node.modifiers : [];
|
|
51
|
-
return mods.some(m => m && m.type === 'TSDeclareKeyword');
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
function reportIfNotDts(node) {
|
|
55
|
-
const filename = context.getFilename();
|
|
56
|
-
if (isDtsFile(filename)) {
|
|
57
|
-
return;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
if (allowDeclare && hasDeclareModifier(node)) {
|
|
61
|
-
return;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
context.report({
|
|
65
|
-
node,
|
|
66
|
-
messageId: 'moveToDts',
|
|
67
|
-
data: {filename},
|
|
68
|
-
});
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
return {
|
|
72
|
-
TSTypeAliasDeclaration(node) {
|
|
73
|
-
reportIfNotDts(node);
|
|
74
|
-
},
|
|
75
|
-
|
|
76
|
-
TSInterfaceDeclaration(node) {
|
|
77
|
-
reportIfNotDts(node);
|
|
78
|
-
},
|
|
79
|
-
|
|
80
|
-
TSEnumDeclaration(node) {
|
|
81
|
-
if (allowEnums) {
|
|
82
|
-
return;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
reportIfNotDts(node);
|
|
86
|
-
},
|
|
87
|
-
|
|
88
|
-
};
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
module.exports = {
|
|
92
|
-
meta,
|
|
93
|
-
create,
|
|
94
|
-
};
|
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
const {RuleTester} = require('@typescript-eslint/rule-tester');
|
|
2
|
-
const rule = require('../src/rules/no-boolean-coercion');
|
|
3
|
-
|
|
4
|
-
const ruleTester = new RuleTester({
|
|
5
|
-
languageOptions: {
|
|
6
|
-
ecmaVersion: 2020,
|
|
7
|
-
sourceType: 'module',
|
|
8
|
-
},
|
|
9
|
-
});
|
|
10
|
-
|
|
11
|
-
ruleTester.run('no-boolean-coercion', rule, {
|
|
12
|
-
valid: [
|
|
13
|
-
'_.isNil(value);',
|
|
14
|
-
'_.isEmpty(list);',
|
|
15
|
-
'if (value != null) {}',
|
|
16
|
-
'if (list.length > 0) {}',
|
|
17
|
-
'Boolean;',
|
|
18
|
-
'const BooleanValue = true;',
|
|
19
|
-
'const fn = Boolean;',
|
|
20
|
-
],
|
|
21
|
-
|
|
22
|
-
invalid: [
|
|
23
|
-
{
|
|
24
|
-
code: 'Boolean(foo);',
|
|
25
|
-
errors: [
|
|
26
|
-
{
|
|
27
|
-
messageId: 'useIsNil',
|
|
28
|
-
suggestions: [
|
|
29
|
-
{
|
|
30
|
-
desc: 'Replace with !_.isNil(foo)',
|
|
31
|
-
output: '!_.isNil(foo);',
|
|
32
|
-
},
|
|
33
|
-
],
|
|
34
|
-
},
|
|
35
|
-
],
|
|
36
|
-
},
|
|
37
|
-
|
|
38
|
-
{
|
|
39
|
-
code: 'const x = Boolean(bar);',
|
|
40
|
-
errors: [
|
|
41
|
-
{
|
|
42
|
-
messageId: 'useIsNil',
|
|
43
|
-
suggestions: [
|
|
44
|
-
{
|
|
45
|
-
desc: 'Replace with !_.isNil(bar)',
|
|
46
|
-
output: 'const x = !_.isNil(bar);',
|
|
47
|
-
},
|
|
48
|
-
],
|
|
49
|
-
},
|
|
50
|
-
],
|
|
51
|
-
},
|
|
52
|
-
|
|
53
|
-
{
|
|
54
|
-
code: '!!value;',
|
|
55
|
-
errors: [
|
|
56
|
-
{
|
|
57
|
-
messageId: 'useIsNil',
|
|
58
|
-
suggestions: [
|
|
59
|
-
{
|
|
60
|
-
desc: 'Replace with !_.isNil(value)',
|
|
61
|
-
output: '!_.isNil(value);',
|
|
62
|
-
},
|
|
63
|
-
],
|
|
64
|
-
},
|
|
65
|
-
],
|
|
66
|
-
},
|
|
67
|
-
|
|
68
|
-
{
|
|
69
|
-
code: 'Boolean([]);',
|
|
70
|
-
errors: [
|
|
71
|
-
{
|
|
72
|
-
messageId: 'useIsEmpty',
|
|
73
|
-
suggestions: [
|
|
74
|
-
{
|
|
75
|
-
desc: 'Replace with !_.isEmpty([])',
|
|
76
|
-
output: '!_.isEmpty([]);',
|
|
77
|
-
},
|
|
78
|
-
],
|
|
79
|
-
},
|
|
80
|
-
],
|
|
81
|
-
},
|
|
82
|
-
],
|
|
83
|
-
});
|
|
@@ -1,148 +0,0 @@
|
|
|
1
|
-
const {RuleTester} = require('@typescript-eslint/rule-tester');
|
|
2
|
-
const rule = require('../src/rules/prefer-is-empty');
|
|
3
|
-
|
|
4
|
-
const ruleTester = new RuleTester({
|
|
5
|
-
languageOptions: {
|
|
6
|
-
ecmaVersion: 2020,
|
|
7
|
-
sourceType: 'module',
|
|
8
|
-
},
|
|
9
|
-
});
|
|
10
|
-
|
|
11
|
-
ruleTester.run('prefer-is-empty', rule, {
|
|
12
|
-
valid: [
|
|
13
|
-
'_.isEmpty(values);',
|
|
14
|
-
'!_.isEmpty(values);',
|
|
15
|
-
'Array.isArray(values);',
|
|
16
|
-
'values.size > 0;', // Non-length property
|
|
17
|
-
],
|
|
18
|
-
|
|
19
|
-
invalid: [
|
|
20
|
-
{
|
|
21
|
-
code: 'values.length === 0;',
|
|
22
|
-
errors: [
|
|
23
|
-
{
|
|
24
|
-
message:
|
|
25
|
-
'Use _.isEmpty(values) instead of checking values.length === 0',
|
|
26
|
-
suggestions: [
|
|
27
|
-
{
|
|
28
|
-
desc: 'Replace with _.isEmpty(values)',
|
|
29
|
-
output: '_.isEmpty(values);',
|
|
30
|
-
},
|
|
31
|
-
],
|
|
32
|
-
},
|
|
33
|
-
],
|
|
34
|
-
},
|
|
35
|
-
|
|
36
|
-
{
|
|
37
|
-
code: 'values.length < 1;',
|
|
38
|
-
errors: [
|
|
39
|
-
{
|
|
40
|
-
message:
|
|
41
|
-
'Use _.isEmpty(values) instead of checking values.length < 1',
|
|
42
|
-
suggestions: [
|
|
43
|
-
{
|
|
44
|
-
desc: 'Replace with _.isEmpty(values)',
|
|
45
|
-
output: '_.isEmpty(values);',
|
|
46
|
-
},
|
|
47
|
-
],
|
|
48
|
-
},
|
|
49
|
-
],
|
|
50
|
-
},
|
|
51
|
-
|
|
52
|
-
{
|
|
53
|
-
code: 'values.length <= 0;',
|
|
54
|
-
errors: [
|
|
55
|
-
{
|
|
56
|
-
message:
|
|
57
|
-
'Use _.isEmpty(values) instead of checking values.length <= 0',
|
|
58
|
-
suggestions: [
|
|
59
|
-
{
|
|
60
|
-
desc: 'Replace with _.isEmpty(values)',
|
|
61
|
-
output: '_.isEmpty(values);',
|
|
62
|
-
},
|
|
63
|
-
],
|
|
64
|
-
},
|
|
65
|
-
],
|
|
66
|
-
},
|
|
67
|
-
|
|
68
|
-
{
|
|
69
|
-
code: 'values.length > 0;',
|
|
70
|
-
errors: [
|
|
71
|
-
{
|
|
72
|
-
message:
|
|
73
|
-
'Use _.isEmpty(values) instead of checking values.length > 0',
|
|
74
|
-
suggestions: [
|
|
75
|
-
{
|
|
76
|
-
desc: 'Replace with !_.isEmpty(values)',
|
|
77
|
-
output: '!_.isEmpty(values);',
|
|
78
|
-
},
|
|
79
|
-
],
|
|
80
|
-
},
|
|
81
|
-
],
|
|
82
|
-
},
|
|
83
|
-
|
|
84
|
-
{
|
|
85
|
-
code: 'values.length >= 1;',
|
|
86
|
-
errors: [
|
|
87
|
-
{
|
|
88
|
-
message:
|
|
89
|
-
'Use _.isEmpty(values) instead of checking values.length >= 1',
|
|
90
|
-
suggestions: [
|
|
91
|
-
{
|
|
92
|
-
desc: 'Replace with !_.isEmpty(values)',
|
|
93
|
-
output: '!_.isEmpty(values);',
|
|
94
|
-
},
|
|
95
|
-
],
|
|
96
|
-
},
|
|
97
|
-
],
|
|
98
|
-
},
|
|
99
|
-
|
|
100
|
-
{
|
|
101
|
-
code: 'values.length !== 0;',
|
|
102
|
-
errors: [
|
|
103
|
-
{
|
|
104
|
-
message:
|
|
105
|
-
'Use _.isEmpty(values) instead of checking values.length !== 0',
|
|
106
|
-
suggestions: [
|
|
107
|
-
{
|
|
108
|
-
desc: 'Replace with !_.isEmpty(values)',
|
|
109
|
-
output: '!_.isEmpty(values);',
|
|
110
|
-
},
|
|
111
|
-
],
|
|
112
|
-
},
|
|
113
|
-
],
|
|
114
|
-
},
|
|
115
|
-
|
|
116
|
-
{
|
|
117
|
-
code: 'if (items.length > 0) {}',
|
|
118
|
-
errors: [
|
|
119
|
-
{
|
|
120
|
-
message:
|
|
121
|
-
'Use _.isEmpty(items) instead of checking items.length > 0',
|
|
122
|
-
suggestions: [
|
|
123
|
-
{
|
|
124
|
-
desc: 'Replace with !_.isEmpty(items)',
|
|
125
|
-
output: 'if (!_.isEmpty(items)) {}',
|
|
126
|
-
},
|
|
127
|
-
],
|
|
128
|
-
},
|
|
129
|
-
],
|
|
130
|
-
},
|
|
131
|
-
|
|
132
|
-
{
|
|
133
|
-
code: '0 === items.length;',
|
|
134
|
-
errors: [
|
|
135
|
-
{
|
|
136
|
-
message:
|
|
137
|
-
'Use _.isEmpty(items) instead of checking items.length === 0',
|
|
138
|
-
suggestions: [
|
|
139
|
-
{
|
|
140
|
-
desc: 'Replace with _.isEmpty(items)',
|
|
141
|
-
output: '_.isEmpty(items);',
|
|
142
|
-
},
|
|
143
|
-
],
|
|
144
|
-
},
|
|
145
|
-
],
|
|
146
|
-
},
|
|
147
|
-
],
|
|
148
|
-
});
|
package/tsconfig.json
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"lib": ["ESNext"],
|
|
4
|
-
"module": "esnext",
|
|
5
|
-
"target": "esnext",
|
|
6
|
-
"moduleResolution": "bundler",
|
|
7
|
-
"moduleDetection": "force",
|
|
8
|
-
"allowImportingTsExtensions": true,
|
|
9
|
-
"noEmit": true,
|
|
10
|
-
"composite": true,
|
|
11
|
-
"strict": true,
|
|
12
|
-
"downlevelIteration": true,
|
|
13
|
-
"skipLibCheck": true,
|
|
14
|
-
"jsx": "react-jsx",
|
|
15
|
-
"allowSyntheticDefaultImports": true,
|
|
16
|
-
"forceConsistentCasingInFileNames": true,
|
|
17
|
-
"allowJs": true,
|
|
18
|
-
"types": [
|
|
19
|
-
"bun-types" // add Bun global
|
|
20
|
-
]
|
|
21
|
-
}
|
|
22
|
-
}
|
package/xo.config.ts
DELETED