@blumintinc/eslint-plugin-blumint 0.1.0 → 0.1.2
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 +28 -14
- package/docs/rules/array-methods-this-context.md +5 -1
- package/docs/rules/export-if-in-doubt.md +28 -0
- package/docs/rules/extract-global-constants.md +35 -0
- package/docs/rules/generic-starts-with-t.md +3 -1
- package/docs/rules/no-async-array-filter.md +3 -1
- package/docs/rules/no-filter-without-return.md +3 -1
- package/docs/rules/no-misused-switch-case.md +38 -0
- package/docs/rules/no-unpinned-dependencies.md +3 -1
- package/docs/rules/prefer-fragment-shorthand.md +3 -1
- package/docs/rules/prefer-type-over-interface.md +3 -1
- package/lib/index.js +31 -2
- package/lib/rules/array-methods-this-context.js +15 -9
- package/lib/rules/export-if-in-doubt.js +35 -0
- package/lib/rules/extract-global-constants.js +62 -0
- package/lib/rules/generic-starts-with-t.js +3 -3
- package/lib/rules/no-async-array-filter.js +1 -2
- package/lib/rules/no-filter-without-return.js +3 -40
- package/lib/rules/no-misused-switch-case.js +35 -0
- package/lib/rules/no-unpinned-dependencies.js +5 -2
- package/lib/rules/prefer-fragment-shorthand.js +1 -2
- package/lib/utils/ASTHelpers.js +136 -0
- package/lib/utils/createRule.js +1 -2
- package/lib/utils/ruleTester.js +23 -0
- package/package.json +7 -5
- package/scripts/make-docs.sh +21 -0
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# eslint-plugin-blumint
|
|
1
|
+
# @blumintinc/eslint-plugin-blumint
|
|
2
2
|
|
|
3
3
|
Custom eslint rules for use at BluMint
|
|
4
4
|
|
|
@@ -10,20 +10,20 @@ You'll first need to install [ESLint](https://eslint.org/):
|
|
|
10
10
|
npm i eslint --save-dev
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
-
Next, install
|
|
13
|
+
Next, install `@blumintinc/eslint-plugin-blumint`:
|
|
14
14
|
|
|
15
15
|
```sh
|
|
16
|
-
npm install eslint-plugin-blumint --save-dev
|
|
16
|
+
npm install @blumintinc/eslint-plugin-blumint --save-dev
|
|
17
17
|
```
|
|
18
18
|
|
|
19
19
|
## Usage
|
|
20
20
|
|
|
21
|
-
Add
|
|
21
|
+
Add `@blumintinc/blumint` to the plugins section of your `.eslintrc` configuration file. You can omit the `eslint-plugin-` prefix:
|
|
22
22
|
|
|
23
23
|
```json
|
|
24
24
|
{
|
|
25
25
|
"plugins": [
|
|
26
|
-
"blumint"
|
|
26
|
+
"@blumintinc/blumint"
|
|
27
27
|
]
|
|
28
28
|
}
|
|
29
29
|
```
|
|
@@ -39,21 +39,35 @@ Then configure the rules you want to use under the rules section.
|
|
|
39
39
|
}
|
|
40
40
|
```
|
|
41
41
|
|
|
42
|
+
Or use the recommended config:
|
|
43
|
+
|
|
44
|
+
```json
|
|
45
|
+
{
|
|
46
|
+
"extends": ["some-other-plugin", "plugin:@blumintinc/blumint/recommended"]
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
42
50
|
## Rules
|
|
43
51
|
|
|
44
52
|
<!-- begin auto-generated rules list -->
|
|
45
53
|
|
|
54
|
+
💼 Configurations enabled in.\
|
|
55
|
+
⚠️ Configurations set to warn in.\
|
|
56
|
+
✅ Set in the `recommended` configuration.\
|
|
46
57
|
🔧 Automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/user-guide/command-line-interface#--fix).
|
|
47
58
|
|
|
48
|
-
| Name | Description | 🔧 |
|
|
49
|
-
| :--------------------------------------------------------------------- | :---------------------------------------------------------------------------------------- | :- |
|
|
50
|
-
| [array-methods-this-context](docs/rules/array-methods-this-context.md) | Disallow async callbacks for Array.filter |
|
|
51
|
-
| [
|
|
52
|
-
| [
|
|
53
|
-
| [
|
|
54
|
-
| [no-
|
|
55
|
-
| [
|
|
56
|
-
| [
|
|
59
|
+
| Name | Description | 💼 | ⚠️ | 🔧 |
|
|
60
|
+
| :--------------------------------------------------------------------- | :---------------------------------------------------------------------------------------- | :- | :- | :- |
|
|
61
|
+
| [array-methods-this-context](docs/rules/array-methods-this-context.md) | Disallow async callbacks for Array.filter | | ✅ | |
|
|
62
|
+
| [export-if-in-doubt](docs/rules/export-if-in-doubt.md) | All top-level const definitions, type definitions, and functions should be exported | | ✅ | |
|
|
63
|
+
| [extract-global-constants](docs/rules/extract-global-constants.md) | Extract constants/functions from React components to the global scope when possible | | ✅ | |
|
|
64
|
+
| [generic-starts-with-t](docs/rules/generic-starts-with-t.md) | Enforce TypeScript generic types to start with T | | ✅ | |
|
|
65
|
+
| [no-async-array-filter](docs/rules/no-async-array-filter.md) | Disallow async callbacks for Array.filter | ✅ | | |
|
|
66
|
+
| [no-filter-without-return](docs/rules/no-filter-without-return.md) | Disallow Array.filter callbacks without an explicit return (if part of a block statement) | ✅ | | |
|
|
67
|
+
| [no-misused-switch-case](docs/rules/no-misused-switch-case.md) | Prevent misuse of logical OR (||) in switch case statements | ✅ | | |
|
|
68
|
+
| [no-unpinned-dependencies](docs/rules/no-unpinned-dependencies.md) | Enforces pinned dependencies | ✅ | | 🔧 |
|
|
69
|
+
| [prefer-fragment-shorthand](docs/rules/prefer-fragment-shorthand.md) | Prefer <> shorthand for <React.Fragment> | | ✅ | 🔧 |
|
|
70
|
+
| [prefer-type-over-interface](docs/rules/prefer-type-over-interface.md) | Prefer using type alias over interface | | ✅ | |
|
|
57
71
|
|
|
58
72
|
<!-- end auto-generated rules list -->
|
|
59
73
|
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Prevent misuse of Array methods in OOP (`@blumintinc/blumint/array-methods-this-context`)
|
|
2
|
+
|
|
3
|
+
⚠️ This rule _warns_ in the ✅ `recommended` config.
|
|
4
|
+
|
|
5
|
+
<!-- end auto-generated rule header -->
|
|
2
6
|
|
|
3
7
|
This rule disallows the direct use of class methods in Array methods like 'map', 'filter', 'forEach', 'reduce', 'some', 'every'. Instead, arrow functions should be used to preserve the 'this' context.
|
|
4
8
|
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Always Export Top-level Const Definitions, Type Definitions, and Functions (`@blumintinc/blumint/export-if-in-doubt`)
|
|
2
|
+
|
|
3
|
+
⚠️ This rule _warns_ in the ✅ `recommended` config.
|
|
4
|
+
|
|
5
|
+
<!-- end auto-generated rule header -->
|
|
6
|
+
|
|
7
|
+
This rule enforces that all top-level const definitions, type definitions, and functions should always be exported. If not done, this rule will trigger a warning message suggesting to export the declaration.
|
|
8
|
+
|
|
9
|
+
## Rule Details
|
|
10
|
+
|
|
11
|
+
This rule targets `VariableDeclaration`, `FunctionDeclaration`, and `TSTypeAliasDeclaration` at the top-level of the file. It will issue a warning if these are not part of an `ExportNamedDeclaration`.
|
|
12
|
+
|
|
13
|
+
### Examples of incorrect code for this rule:
|
|
14
|
+
|
|
15
|
+
```typescript
|
|
16
|
+
const someVar = "Hello, world!";
|
|
17
|
+
function someFunc() { return someVar; }
|
|
18
|
+
type SomeType = { val: number };
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
### Examples of correct code for this rule:
|
|
22
|
+
|
|
23
|
+
```typescript
|
|
24
|
+
export const someVar = "Hello, world!";
|
|
25
|
+
export function someFunc() { return someVar; }
|
|
26
|
+
export type SomeType = { val: number };
|
|
27
|
+
```
|
|
28
|
+
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Extract Constants/Functions to the Global Scope When Possible (`@blumintinc/blumint/extract-global-constants`)
|
|
2
|
+
|
|
3
|
+
⚠️ This rule _warns_ in the ✅ `recommended` config.
|
|
4
|
+
|
|
5
|
+
<!-- end auto-generated rule header -->
|
|
6
|
+
|
|
7
|
+
This rule suggests that if a constant or a function within a function or block scope doesn't depend on any other identifiers in that scope, it should be moved to the global scope. This aims to improve the readability of the code and the possibility of reuse.
|
|
8
|
+
|
|
9
|
+
## Rule Details
|
|
10
|
+
|
|
11
|
+
This rule enforces that all `const` declarations and `FunctionDeclaration` at a non-global scope, which have no dependencies on other identifiers within the scope, should be extracted to the global scope.
|
|
12
|
+
|
|
13
|
+
### Examples of incorrect code for this rule:
|
|
14
|
+
|
|
15
|
+
```typescript
|
|
16
|
+
function someFunc() {
|
|
17
|
+
const SOME_CONST = "Hello, world!";
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function parentFunc() {
|
|
21
|
+
function childFunc() { return "Hello, world!"; }
|
|
22
|
+
}
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### Examples of correct code for this rule:
|
|
26
|
+
|
|
27
|
+
```typescript
|
|
28
|
+
const SOME_CONST = "Hello, world!";
|
|
29
|
+
function someFunc() { /* ... */ }
|
|
30
|
+
|
|
31
|
+
function childFunc() { return "Hello, world!"; }
|
|
32
|
+
function parentFunc() { /* ... */ }
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
In the correct examples, each declaration is moved to the global scope since they don't depend on any identifier in their previous block or function scope. This aligns with the rule and promotes potential reuse of these declarations.
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
# Enforce TypeScript generic types to start with T (
|
|
1
|
+
# Enforce TypeScript generic types to start with T (`@blumintinc/blumint/generic-starts-with-t`)
|
|
2
|
+
|
|
3
|
+
⚠️ This rule _warns_ in the ✅ `recommended` config.
|
|
2
4
|
|
|
3
5
|
<!-- end auto-generated rule header -->
|
|
4
6
|
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
# Disallow async callbacks for Array.filter (
|
|
1
|
+
# Disallow async callbacks for Array.filter (`@blumintinc/blumint/no-async-array-filter`)
|
|
2
|
+
|
|
3
|
+
💼 This rule is enabled in the ✅ `recommended` config.
|
|
2
4
|
|
|
3
5
|
<!-- end auto-generated rule header -->
|
|
4
6
|
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
# Disallow Array.filter callbacks without an explicit return (if part of a block statement) (
|
|
1
|
+
# Disallow Array.filter callbacks without an explicit return (if part of a block statement) (`@blumintinc/blumint/no-filter-without-return`)
|
|
2
|
+
|
|
3
|
+
💼 This rule is enabled in the ✅ `recommended` config.
|
|
2
4
|
|
|
3
5
|
<!-- end auto-generated rule header -->
|
|
4
6
|
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# Prevent Misuse of Logical OR in Switch Case Statements (`@blumintinc/blumint/no-misused-switch-case`)
|
|
2
|
+
|
|
3
|
+
💼 This rule is enabled in the ✅ `recommended` config.
|
|
4
|
+
|
|
5
|
+
<!-- end auto-generated rule header -->
|
|
6
|
+
|
|
7
|
+
This rule prevents the misuse of logical OR (`||`) in switch case statements. Instead, cascading cases should be used. This improves code readability and understanding.
|
|
8
|
+
|
|
9
|
+
## Rule Details
|
|
10
|
+
|
|
11
|
+
This rule specifically targets `SwitchStatement` and issues a warning if a case uses a logical OR (`||`) in its test.
|
|
12
|
+
|
|
13
|
+
### Examples of incorrect code for this rule:
|
|
14
|
+
|
|
15
|
+
```typescript
|
|
16
|
+
switch (value) {
|
|
17
|
+
case 'a' || 'b':
|
|
18
|
+
console.log('It is a or b');
|
|
19
|
+
break;
|
|
20
|
+
default:
|
|
21
|
+
console.log('Unknown value');
|
|
22
|
+
}
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### Examples of correct code for this rule:
|
|
26
|
+
|
|
27
|
+
```typescript
|
|
28
|
+
switch (value) {
|
|
29
|
+
case 'a':
|
|
30
|
+
case 'b':
|
|
31
|
+
console.log('It is a or b');
|
|
32
|
+
break;
|
|
33
|
+
default:
|
|
34
|
+
console.log('Unknown value');
|
|
35
|
+
}
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
In the correct example, instead of using a logical OR in the case test, cascading cases are used to capture the multiple possibilities. This is the standard way to handle multiple possibilities in a switch case and adheres to the rule.
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
# Enforces pinned dependencies (
|
|
1
|
+
# Enforces pinned dependencies (`@blumintinc/blumint/no-unpinned-dependencies`)
|
|
2
|
+
|
|
3
|
+
💼 This rule is enabled in the ✅ `recommended` config.
|
|
2
4
|
|
|
3
5
|
🔧 This rule is automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix).
|
|
4
6
|
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
# Prefer <> shorthand for <React.Fragment> (
|
|
1
|
+
# Prefer <> shorthand for <React.Fragment> (`@blumintinc/blumint/prefer-fragment-shorthand`)
|
|
2
|
+
|
|
3
|
+
⚠️ This rule _warns_ in the ✅ `recommended` config.
|
|
2
4
|
|
|
3
5
|
🔧 This rule is automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix).
|
|
4
6
|
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
# Prefer using type alias over interface (
|
|
1
|
+
# Prefer using type alias over interface (`@blumintinc/blumint/prefer-type-over-interface`)
|
|
2
|
+
|
|
3
|
+
⚠️ This rule _warns_ in the ✅ `recommended` config.
|
|
2
4
|
|
|
3
5
|
<!-- end auto-generated rule header -->
|
|
4
6
|
|
package/lib/index.js
CHANGED
|
@@ -1,28 +1,57 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.testingAFunction = void 0;
|
|
3
4
|
const array_methods_this_context_1 = require("./rules/array-methods-this-context");
|
|
5
|
+
const export_if_in_doubt_1 = require("./rules/export-if-in-doubt");
|
|
6
|
+
const extract_global_constants_1 = require("./rules/extract-global-constants");
|
|
4
7
|
const generic_starts_with_t_1 = require("./rules/generic-starts-with-t");
|
|
5
8
|
const no_async_array_filter_1 = require("./rules/no-async-array-filter");
|
|
6
9
|
const no_filter_without_return_1 = require("./rules/no-filter-without-return");
|
|
10
|
+
const no_misused_switch_case_1 = require("./rules/no-misused-switch-case");
|
|
7
11
|
const no_unpinned_dependencies_1 = require("./rules/no-unpinned-dependencies");
|
|
8
12
|
const prefer_fragment_shorthand_1 = require("./rules/prefer-fragment-shorthand");
|
|
9
13
|
const prefer_type_over_interface_1 = require("./rules/prefer-type-over-interface");
|
|
10
14
|
module.exports = {
|
|
11
15
|
meta: {
|
|
12
|
-
name: 'eslint-plugin-blumint',
|
|
13
|
-
version: '0.
|
|
16
|
+
name: '@blumintinc/eslint-plugin-blumint',
|
|
17
|
+
version: '0.1.2',
|
|
14
18
|
},
|
|
15
19
|
parseOptions: {
|
|
16
20
|
ecmaVersion: 2020,
|
|
17
21
|
},
|
|
22
|
+
configs: {
|
|
23
|
+
recommended: {
|
|
24
|
+
plugins: ['@blumintinc/blumint'],
|
|
25
|
+
rules: {
|
|
26
|
+
'@blumintinc/blumint/array-methods-this-context': 'warn',
|
|
27
|
+
'@blumintinc/blumint/export-if-in-doubt': 'warn',
|
|
28
|
+
'@blumintinc/blumint/extract-global-constants': 'warn',
|
|
29
|
+
'@blumintinc/blumint/generic-starts-with-t': 'warn',
|
|
30
|
+
'@blumintinc/blumint/no-async-array-filter': 'error',
|
|
31
|
+
'@blumintinc/blumint/no-filter-without-return': 'error',
|
|
32
|
+
'@blumintinc/blumint/no-misused-switch-case': 'error',
|
|
33
|
+
'@blumintinc/blumint/no-unpinned-dependencies': 'error',
|
|
34
|
+
'@blumintinc/blumint/prefer-fragment-shorthand': 'warn',
|
|
35
|
+
'@blumintinc/blumint/prefer-type-over-interface': 'warn',
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
},
|
|
18
39
|
rules: {
|
|
19
40
|
'array-methods-this-context': array_methods_this_context_1.arrayMethodsThisContext,
|
|
41
|
+
'export-if-in-doubt': export_if_in_doubt_1.exportIfInDoubt,
|
|
42
|
+
'extract-global-constants': extract_global_constants_1.extractGlobalConstants,
|
|
20
43
|
'generic-starts-with-t': generic_starts_with_t_1.genericStartsWithT,
|
|
21
44
|
'no-async-array-filter': no_async_array_filter_1.noAsyncArrayFilter,
|
|
22
45
|
'no-filter-without-return': no_filter_without_return_1.noFilterWithoutReturn,
|
|
46
|
+
'no-misused-switch-case': no_misused_switch_case_1.noMisusedSwitchCase,
|
|
23
47
|
'no-unpinned-dependencies': no_unpinned_dependencies_1.noUnpinnedDependencies,
|
|
24
48
|
'prefer-fragment-shorthand': prefer_fragment_shorthand_1.preferFragmentShorthand,
|
|
25
49
|
'prefer-type-over-interface': prefer_type_over_interface_1.preferTypeOverInterface,
|
|
26
50
|
},
|
|
27
51
|
};
|
|
52
|
+
const testingAFunction = (input) => {
|
|
53
|
+
const a = input?.A;
|
|
54
|
+
return a;
|
|
55
|
+
};
|
|
56
|
+
exports.testingAFunction = testingAFunction;
|
|
28
57
|
//# sourceMappingURL=index.js.map
|
|
@@ -1,28 +1,35 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.arrayMethodsThisContext = void 0;
|
|
3
|
+
exports.arrayMethodsThisContext = exports.ARRAY_METHODS = void 0;
|
|
4
4
|
const createRule_1 = require("../utils/createRule");
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
exports.ARRAY_METHODS = [
|
|
6
|
+
'map',
|
|
7
|
+
'filter',
|
|
8
|
+
'forEach',
|
|
9
|
+
'reduce',
|
|
10
|
+
'some',
|
|
11
|
+
'every',
|
|
12
|
+
];
|
|
13
|
+
exports.arrayMethodsThisContext = (0, createRule_1.createRule)({
|
|
7
14
|
create(context) {
|
|
8
15
|
return {
|
|
9
16
|
CallExpression(node) {
|
|
10
17
|
// Array method called with a class method reference
|
|
11
18
|
if (node.callee.type === 'MemberExpression' &&
|
|
12
19
|
node.callee.property.type === 'Identifier' &&
|
|
13
|
-
|
|
20
|
+
exports.ARRAY_METHODS.includes(node.callee.property.name) &&
|
|
14
21
|
node.arguments.length > 0 &&
|
|
15
22
|
node.arguments[0].type === 'MemberExpression' &&
|
|
16
23
|
node.arguments[0].object.type === 'ThisExpression') {
|
|
17
24
|
context.report({
|
|
18
25
|
node: node.arguments[0],
|
|
19
|
-
messageId: 'unexpected'
|
|
26
|
+
messageId: 'unexpected',
|
|
20
27
|
});
|
|
21
28
|
}
|
|
22
29
|
// Function expression bound to `this` in array method
|
|
23
30
|
else if (node.callee.type === 'MemberExpression' &&
|
|
24
31
|
node.callee.property.type === 'Identifier' &&
|
|
25
|
-
|
|
32
|
+
exports.ARRAY_METHODS.includes(node.callee.property.name) &&
|
|
26
33
|
node.arguments.length > 0 &&
|
|
27
34
|
node.arguments[0].type === 'CallExpression' &&
|
|
28
35
|
node.arguments[0].callee.type === 'MemberExpression' &&
|
|
@@ -33,7 +40,7 @@ const arrayMethodsThisContext = (0, createRule_1.createRule)({
|
|
|
33
40
|
node.arguments[0].arguments[0].type === 'ThisExpression') {
|
|
34
41
|
context.report({
|
|
35
42
|
node: node.arguments[0],
|
|
36
|
-
messageId: 'preferArrow'
|
|
43
|
+
messageId: 'preferArrow',
|
|
37
44
|
});
|
|
38
45
|
}
|
|
39
46
|
},
|
|
@@ -49,10 +56,9 @@ const arrayMethodsThisContext = (0, createRule_1.createRule)({
|
|
|
49
56
|
schema: [],
|
|
50
57
|
messages: {
|
|
51
58
|
unexpected: 'Use an arrow function to preserve "this" context.',
|
|
52
|
-
preferArrow: 'Use an arrow function instead of binding this.'
|
|
59
|
+
preferArrow: 'Use an arrow function instead of binding this.',
|
|
53
60
|
},
|
|
54
61
|
},
|
|
55
62
|
defaultOptions: [],
|
|
56
63
|
});
|
|
57
|
-
exports.arrayMethodsThisContext = arrayMethodsThisContext;
|
|
58
64
|
//# sourceMappingURL=array-methods-this-context.js.map
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.exportIfInDoubt = void 0;
|
|
4
|
+
const createRule_1 = require("../utils/createRule");
|
|
5
|
+
exports.exportIfInDoubt = (0, createRule_1.createRule)({
|
|
6
|
+
name: 'always-export',
|
|
7
|
+
meta: {
|
|
8
|
+
type: 'suggestion',
|
|
9
|
+
docs: {
|
|
10
|
+
description: 'All top-level const definitions, type definitions, and functions should be exported',
|
|
11
|
+
recommended: 'warn',
|
|
12
|
+
},
|
|
13
|
+
schema: [],
|
|
14
|
+
messages: {
|
|
15
|
+
exportIfInDoubt: 'Top-level const definitions, type definitions, and functions should be exported.',
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
defaultOptions: [],
|
|
19
|
+
create(context) {
|
|
20
|
+
return {
|
|
21
|
+
'Program > VariableDeclaration > VariableDeclarator, Program > FunctionDeclaration, Program > TSTypeAliasDeclaration'(node) {
|
|
22
|
+
if ((node.parent && node.parent.type !== 'ExportNamedDeclaration') ||
|
|
23
|
+
(node.parent &&
|
|
24
|
+
node.parent.parent &&
|
|
25
|
+
node.parent.parent.type !== 'ExportNamedDeclaration')) {
|
|
26
|
+
context.report({
|
|
27
|
+
node,
|
|
28
|
+
messageId: 'exportIfInDoubt',
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
},
|
|
34
|
+
});
|
|
35
|
+
//# sourceMappingURL=export-if-in-doubt.js.map
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.extractGlobalConstants = void 0;
|
|
4
|
+
const ASTHelpers_1 = require("../utils/ASTHelpers");
|
|
5
|
+
const createRule_1 = require("../utils/createRule");
|
|
6
|
+
exports.extractGlobalConstants = (0, createRule_1.createRule)({
|
|
7
|
+
create(context) {
|
|
8
|
+
return {
|
|
9
|
+
VariableDeclaration(node) {
|
|
10
|
+
if (node.kind !== 'const') {
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
const scope = context.getScope();
|
|
14
|
+
const hasDependencies = node.declarations.some((declaration) => declaration.init &&
|
|
15
|
+
ASTHelpers_1.ASTHelpers.declarationIncludesIdentifier(declaration.init));
|
|
16
|
+
if (!hasDependencies && scope.type === 'function') {
|
|
17
|
+
const constName = node.declarations[0].id.name;
|
|
18
|
+
context.report({
|
|
19
|
+
node,
|
|
20
|
+
messageId: 'extractGlobalConstants',
|
|
21
|
+
data: {
|
|
22
|
+
declarationName: constName,
|
|
23
|
+
},
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
FunctionDeclaration(node) {
|
|
28
|
+
if (node.parent &&
|
|
29
|
+
(node.parent.type === 'FunctionDeclaration' ||
|
|
30
|
+
node.parent.type === 'FunctionExpression' ||
|
|
31
|
+
node.parent.type === 'ArrowFunctionExpression')) {
|
|
32
|
+
const scope = context.getScope();
|
|
33
|
+
const hasDependencies = ASTHelpers_1.ASTHelpers.blockIncludesIdentifier(node.body);
|
|
34
|
+
if (!hasDependencies && scope.type === 'function') {
|
|
35
|
+
const funcName = node.id.name;
|
|
36
|
+
context.report({
|
|
37
|
+
node,
|
|
38
|
+
messageId: 'extractGlobalConstants',
|
|
39
|
+
data: {
|
|
40
|
+
declarationName: funcName,
|
|
41
|
+
},
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
},
|
|
48
|
+
name: 'extract-global-constants',
|
|
49
|
+
meta: {
|
|
50
|
+
type: 'suggestion',
|
|
51
|
+
docs: {
|
|
52
|
+
description: 'Extract constants/functions from React components to the global scope when possible',
|
|
53
|
+
recommended: 'error',
|
|
54
|
+
},
|
|
55
|
+
schema: [],
|
|
56
|
+
messages: {
|
|
57
|
+
extractGlobalConstants: 'Move this declaration {{ declarationName }} to the global scope and rename it to UPPER_SNAKE_CASE if necessary.',
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
defaultOptions: [],
|
|
61
|
+
});
|
|
62
|
+
//# sourceMappingURL=extract-global-constants.js.map
|
|
@@ -2,12 +2,13 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.genericStartsWithT = void 0;
|
|
4
4
|
const createRule_1 = require("../utils/createRule");
|
|
5
|
-
|
|
5
|
+
exports.genericStartsWithT = (0, createRule_1.createRule)({
|
|
6
6
|
create(context) {
|
|
7
7
|
return {
|
|
8
8
|
TSTypeParameterDeclaration(node) {
|
|
9
9
|
for (const param of node.params) {
|
|
10
|
-
if (typeof param.name.name === 'string' &&
|
|
10
|
+
if (typeof param.name.name === 'string' &&
|
|
11
|
+
param.name.name[0] !== 'T') {
|
|
11
12
|
context.report({
|
|
12
13
|
node: param,
|
|
13
14
|
messageId: 'genericStartsWithT',
|
|
@@ -31,5 +32,4 @@ const genericStartsWithT = (0, createRule_1.createRule)({
|
|
|
31
32
|
},
|
|
32
33
|
defaultOptions: [],
|
|
33
34
|
});
|
|
34
|
-
exports.genericStartsWithT = genericStartsWithT;
|
|
35
35
|
//# sourceMappingURL=generic-starts-with-t.js.map
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.noAsyncArrayFilter = void 0;
|
|
4
4
|
const createRule_1 = require("../utils/createRule");
|
|
5
|
-
|
|
5
|
+
exports.noAsyncArrayFilter = (0, createRule_1.createRule)({
|
|
6
6
|
create(context) {
|
|
7
7
|
return {
|
|
8
8
|
CallExpression(node) {
|
|
@@ -37,5 +37,4 @@ const noAsyncArrayFilter = (0, createRule_1.createRule)({
|
|
|
37
37
|
},
|
|
38
38
|
defaultOptions: [],
|
|
39
39
|
});
|
|
40
|
-
exports.noAsyncArrayFilter = noAsyncArrayFilter;
|
|
41
40
|
//# sourceMappingURL=no-async-array-filter.js.map
|
|
@@ -1,45 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.noFilterWithoutReturn = void 0;
|
|
4
|
+
const ASTHelpers_1 = require("../utils/ASTHelpers");
|
|
4
5
|
const createRule_1 = require("../utils/createRule");
|
|
5
|
-
|
|
6
|
+
exports.noFilterWithoutReturn = (0, createRule_1.createRule)({
|
|
6
7
|
create(context) {
|
|
7
|
-
function isNode(value) {
|
|
8
|
-
return typeof value === 'object'
|
|
9
|
-
&& value !== null
|
|
10
|
-
&& 'type' in value;
|
|
11
|
-
}
|
|
12
|
-
function hasReturnStatement(node) {
|
|
13
|
-
if (node.type === 'ReturnStatement') {
|
|
14
|
-
return true;
|
|
15
|
-
}
|
|
16
|
-
else if (node.type === 'IfStatement') {
|
|
17
|
-
// Check both branches of the if statement
|
|
18
|
-
const consequentHasReturn = hasReturnStatement(node.consequent);
|
|
19
|
-
const alternateHasReturn = !!node.alternate && hasReturnStatement(node.alternate);
|
|
20
|
-
return consequentHasReturn && alternateHasReturn;
|
|
21
|
-
}
|
|
22
|
-
else if (node.type === 'BlockStatement') {
|
|
23
|
-
// Check all statements in the block
|
|
24
|
-
for (const statement of node.body) {
|
|
25
|
-
if (hasReturnStatement(statement)) {
|
|
26
|
-
return true;
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
for (const key in node) {
|
|
31
|
-
if (key === 'parent') {
|
|
32
|
-
continue; // Ignore the parent property
|
|
33
|
-
}
|
|
34
|
-
const value = node[key];
|
|
35
|
-
if (isNode(value)) {
|
|
36
|
-
if (hasReturnStatement(value)) {
|
|
37
|
-
return true;
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
return false;
|
|
42
|
-
}
|
|
43
8
|
return {
|
|
44
9
|
'CallExpression[callee.property.name="filter"]'(node) {
|
|
45
10
|
const callback = node.arguments[0];
|
|
@@ -49,8 +14,7 @@ const noFilterWithoutReturn = (0, createRule_1.createRule)({
|
|
|
49
14
|
// If the body is not a block statement, it's a direct return
|
|
50
15
|
return;
|
|
51
16
|
}
|
|
52
|
-
|
|
53
|
-
if (!hasReturnStatement(body)) {
|
|
17
|
+
if (!ASTHelpers_1.ASTHelpers.hasReturnStatement(body)) {
|
|
54
18
|
context.report({
|
|
55
19
|
node,
|
|
56
20
|
messageId: 'unexpected',
|
|
@@ -74,5 +38,4 @@ const noFilterWithoutReturn = (0, createRule_1.createRule)({
|
|
|
74
38
|
},
|
|
75
39
|
defaultOptions: [],
|
|
76
40
|
});
|
|
77
|
-
exports.noFilterWithoutReturn = noFilterWithoutReturn;
|
|
78
41
|
//# sourceMappingURL=no-filter-without-return.js.map
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.noMisusedSwitchCase = void 0;
|
|
4
|
+
const createRule_1 = require("../utils/createRule");
|
|
5
|
+
exports.noMisusedSwitchCase = (0, createRule_1.createRule)({
|
|
6
|
+
name: 'no-misused-switch-case',
|
|
7
|
+
meta: {
|
|
8
|
+
type: 'problem',
|
|
9
|
+
docs: {
|
|
10
|
+
description: 'Prevent misuse of logical OR (||) in switch case statements',
|
|
11
|
+
recommended: 'error',
|
|
12
|
+
},
|
|
13
|
+
schema: [],
|
|
14
|
+
messages: {
|
|
15
|
+
noMisusedSwitchCase: 'Avoid using logical OR (||) in switch case. Use cascading cases instead.',
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
defaultOptions: [],
|
|
19
|
+
create(context) {
|
|
20
|
+
return {
|
|
21
|
+
SwitchStatement(node) {
|
|
22
|
+
for (const switchCase of node.cases) {
|
|
23
|
+
if (switchCase.test?.type === 'LogicalExpression' &&
|
|
24
|
+
switchCase.test.operator === '||') {
|
|
25
|
+
context.report({
|
|
26
|
+
node: switchCase,
|
|
27
|
+
messageId: 'noMisusedSwitchCase',
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
},
|
|
34
|
+
});
|
|
35
|
+
//# sourceMappingURL=no-misused-switch-case.js.map
|
|
@@ -21,6 +21,7 @@ exports.noUnpinnedDependencies = (0, createRule_1.createRule)({
|
|
|
21
21
|
return {
|
|
22
22
|
JSONLiteral(node) {
|
|
23
23
|
const property = node?.parent;
|
|
24
|
+
// const property = node.parent;
|
|
24
25
|
const configSection = node?.parent?.parent?.parent;
|
|
25
26
|
if (!property || !configSection) {
|
|
26
27
|
return;
|
|
@@ -32,8 +33,10 @@ exports.noUnpinnedDependencies = (0, createRule_1.createRule)({
|
|
|
32
33
|
// Check if we're in the "dependencies" or "devDependencies" section of package.json
|
|
33
34
|
if (node.type === 'JSONLiteral' &&
|
|
34
35
|
property?.type === 'JSONProperty' &&
|
|
35
|
-
(configKey.name === 'devDependencies' ||
|
|
36
|
-
configKey.
|
|
36
|
+
(configKey.name === 'devDependencies' ||
|
|
37
|
+
configKey.value === 'devDependencies' ||
|
|
38
|
+
configKey.name === 'dependencies' ||
|
|
39
|
+
configKey.value === 'dependencies')) {
|
|
37
40
|
// Get the version string
|
|
38
41
|
const version = node.value;
|
|
39
42
|
const propertyName = property.key.name ||
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.preferFragmentShorthand = void 0;
|
|
4
|
-
|
|
4
|
+
exports.preferFragmentShorthand = {
|
|
5
5
|
create(context) {
|
|
6
6
|
return {
|
|
7
7
|
JSXElement(node) {
|
|
@@ -37,5 +37,4 @@ const preferFragmentShorthand = {
|
|
|
37
37
|
},
|
|
38
38
|
defaultOptions: [],
|
|
39
39
|
};
|
|
40
|
-
exports.preferFragmentShorthand = preferFragmentShorthand;
|
|
41
40
|
//# sourceMappingURL=prefer-fragment-shorthand.js.map
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ASTHelpers = void 0;
|
|
4
|
+
// import { RuleContext } from '@typescript-eslint/utils/dist/ts-eslint';
|
|
5
|
+
class ASTHelpers {
|
|
6
|
+
static blockIncludesIdentifier(block) {
|
|
7
|
+
for (const statement of block.body) {
|
|
8
|
+
if (ASTHelpers.declarationIncludesIdentifier(statement)) {
|
|
9
|
+
return true;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
return false;
|
|
13
|
+
}
|
|
14
|
+
static declarationIncludesIdentifier(node) {
|
|
15
|
+
if (!node) {
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
console.log('visting node of type', node.type);
|
|
19
|
+
switch (node.type) {
|
|
20
|
+
case 'BlockStatement':
|
|
21
|
+
return ASTHelpers.blockIncludesIdentifier(node);
|
|
22
|
+
case 'Identifier':
|
|
23
|
+
return true;
|
|
24
|
+
case 'SpreadElement':
|
|
25
|
+
return ASTHelpers.declarationIncludesIdentifier(node.argument);
|
|
26
|
+
case 'ChainExpression':
|
|
27
|
+
return ASTHelpers.declarationIncludesIdentifier(node.expression);
|
|
28
|
+
case 'ArrayExpression':
|
|
29
|
+
return node.elements.some((element) => element &&
|
|
30
|
+
(element.type === 'SpreadElement'
|
|
31
|
+
? ASTHelpers.declarationIncludesIdentifier(element.argument)
|
|
32
|
+
: ASTHelpers.declarationIncludesIdentifier(element)));
|
|
33
|
+
case 'ObjectExpression':
|
|
34
|
+
return node.properties.some((property) => {
|
|
35
|
+
if (property.type === 'Property') {
|
|
36
|
+
return ASTHelpers.declarationIncludesIdentifier(property.value);
|
|
37
|
+
}
|
|
38
|
+
else if (property.type === 'SpreadElement') {
|
|
39
|
+
return ASTHelpers.declarationIncludesIdentifier(property.argument);
|
|
40
|
+
}
|
|
41
|
+
return false;
|
|
42
|
+
});
|
|
43
|
+
case 'Property':
|
|
44
|
+
return this.declarationIncludesIdentifier(node.value);
|
|
45
|
+
case 'BinaryExpression':
|
|
46
|
+
case 'LogicalExpression':
|
|
47
|
+
return (this.declarationIncludesIdentifier(node.left) ||
|
|
48
|
+
this.declarationIncludesIdentifier(node.right));
|
|
49
|
+
case 'UnaryExpression':
|
|
50
|
+
case 'UpdateExpression':
|
|
51
|
+
return this.declarationIncludesIdentifier(node.argument);
|
|
52
|
+
case 'MemberExpression':
|
|
53
|
+
return this.declarationIncludesIdentifier(node.object);
|
|
54
|
+
case 'CallExpression':
|
|
55
|
+
case 'NewExpression':
|
|
56
|
+
// For function and constructor calls, we care about both the callee and the arguments.
|
|
57
|
+
return (this.declarationIncludesIdentifier(node.callee) ||
|
|
58
|
+
node.arguments.some((arg) => this.declarationIncludesIdentifier(arg)));
|
|
59
|
+
case 'ConditionalExpression':
|
|
60
|
+
return (this.declarationIncludesIdentifier(node.test) ||
|
|
61
|
+
this.declarationIncludesIdentifier(node.consequent) ||
|
|
62
|
+
this.declarationIncludesIdentifier(node.alternate));
|
|
63
|
+
default:
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
// public static declarationIncludesIdentifier(
|
|
68
|
+
// node: TSESTree.Expression | null,
|
|
69
|
+
// ): boolean {
|
|
70
|
+
// if (!node) {
|
|
71
|
+
// return false;
|
|
72
|
+
// }
|
|
73
|
+
// switch (node.type) {
|
|
74
|
+
// case 'Identifier':
|
|
75
|
+
// return true;
|
|
76
|
+
// case 'ArrayExpression':
|
|
77
|
+
// return node.elements.some(
|
|
78
|
+
// (element) =>
|
|
79
|
+
// element &&
|
|
80
|
+
// (element.type === 'SpreadElement'
|
|
81
|
+
// ? ASTHelpers.declarationIncludesIdentifier(element.argument)
|
|
82
|
+
// : ASTHelpers.declarationIncludesIdentifier(element)),
|
|
83
|
+
// );
|
|
84
|
+
// case 'ObjectExpression':
|
|
85
|
+
// return node.properties.some((property) => {
|
|
86
|
+
// if (property.type === 'Property') {
|
|
87
|
+
// return ASTHelpers.declarationIncludesIdentifier(property.key);
|
|
88
|
+
// } else if (property.type === 'SpreadElement') {
|
|
89
|
+
// return ASTHelpers.declarationIncludesIdentifier(property.argument);
|
|
90
|
+
// }
|
|
91
|
+
// return false;
|
|
92
|
+
// });
|
|
93
|
+
// default:
|
|
94
|
+
// return (
|
|
95
|
+
// ASTHelpers.declarationIncludesIdentifier((node as any).left) ||
|
|
96
|
+
// ASTHelpers.declarationIncludesIdentifier((node as any).right)
|
|
97
|
+
// );
|
|
98
|
+
// }
|
|
99
|
+
// }
|
|
100
|
+
static isNode(value) {
|
|
101
|
+
return typeof value === 'object' && value !== null && 'type' in value;
|
|
102
|
+
}
|
|
103
|
+
static hasReturnStatement(node) {
|
|
104
|
+
if (node.type === 'ReturnStatement') {
|
|
105
|
+
return true;
|
|
106
|
+
}
|
|
107
|
+
else if (node.type === 'IfStatement') {
|
|
108
|
+
// Check both branches of the if statement
|
|
109
|
+
const consequentHasReturn = ASTHelpers.hasReturnStatement(node.consequent);
|
|
110
|
+
const alternateHasReturn = !!node.alternate && ASTHelpers.hasReturnStatement(node.alternate);
|
|
111
|
+
return consequentHasReturn && alternateHasReturn;
|
|
112
|
+
}
|
|
113
|
+
else if (node.type === 'BlockStatement') {
|
|
114
|
+
// Check all statements in the block
|
|
115
|
+
for (const statement of node.body) {
|
|
116
|
+
if (ASTHelpers.hasReturnStatement(statement)) {
|
|
117
|
+
return true;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
for (const key in node) {
|
|
122
|
+
if (key === 'parent') {
|
|
123
|
+
continue; // Ignore the parent property
|
|
124
|
+
}
|
|
125
|
+
const value = node[key];
|
|
126
|
+
if (ASTHelpers.isNode(value)) {
|
|
127
|
+
if (ASTHelpers.hasReturnStatement(value)) {
|
|
128
|
+
return true;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
return false;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
exports.ASTHelpers = ASTHelpers;
|
|
136
|
+
//# sourceMappingURL=ASTHelpers.js.map
|
package/lib/utils/createRule.js
CHANGED
|
@@ -2,6 +2,5 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.createRule = void 0;
|
|
4
4
|
const utils_1 = require("@typescript-eslint/utils");
|
|
5
|
-
|
|
6
|
-
exports.createRule = createRule;
|
|
5
|
+
exports.createRule = utils_1.ESLintUtils.RuleCreator((name) => `https://github.com/BluMintInc/custom-eslint-rules/plugin/docs/rules/${name}.md`);
|
|
7
6
|
//# sourceMappingURL=createRule.js.map
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ruleTesterJson = exports.ruleTesterJsx = exports.ruleTesterTs = void 0;
|
|
4
|
+
const utils_1 = require("@typescript-eslint/utils");
|
|
5
|
+
const eslint_1 = require("eslint");
|
|
6
|
+
exports.ruleTesterTs = new utils_1.ESLintUtils.RuleTester({
|
|
7
|
+
parser: '@typescript-eslint/parser',
|
|
8
|
+
});
|
|
9
|
+
exports.ruleTesterJsx = new utils_1.ESLintUtils.RuleTester({
|
|
10
|
+
parser: '@typescript-eslint/parser',
|
|
11
|
+
parserOptions: {
|
|
12
|
+
ecmaFeatures: {
|
|
13
|
+
jsx: true,
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
});
|
|
17
|
+
exports.ruleTesterJson = new eslint_1.RuleTester({
|
|
18
|
+
parser: require.resolve('jsonc-eslint-parser'),
|
|
19
|
+
parserOptions: {
|
|
20
|
+
ecmaVersion: 2020,
|
|
21
|
+
},
|
|
22
|
+
});
|
|
23
|
+
//# sourceMappingURL=ruleTester.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@blumintinc/eslint-plugin-blumint",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "Custom eslint rules for use at BluMint",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"eslint",
|
|
@@ -15,23 +15,25 @@
|
|
|
15
15
|
"lint:eslint-docs": "npm-run-all \"update:eslint-docs -- --check\"",
|
|
16
16
|
"lint:js": "eslint .",
|
|
17
17
|
"test": "jest",
|
|
18
|
+
"docs": "./scripts/make-docs.sh && npm run update:eslint-docs",
|
|
18
19
|
"update:eslint-docs": "eslint-doc-generator"
|
|
19
20
|
},
|
|
20
21
|
"dependencies": {
|
|
21
22
|
"requireindex": "1.2.0"
|
|
22
23
|
},
|
|
23
24
|
"devDependencies": {
|
|
24
|
-
"@types/eslint": "
|
|
25
|
+
"@types/eslint": "8.37.0",
|
|
25
26
|
"@typescript-eslint/utils": "5.59.6",
|
|
26
27
|
"eslint": "8.19.0",
|
|
27
28
|
"eslint-doc-generator": "1.0.0",
|
|
28
|
-
"eslint-import-resolver-typescript": "
|
|
29
|
-
"eslint-plugin-eslint-plugin": "
|
|
29
|
+
"eslint-import-resolver-typescript": "3.5.5",
|
|
30
|
+
"eslint-plugin-eslint-plugin": "5.0.0",
|
|
31
|
+
"@blumintinc/eslint-plugin-blumint": "file:./",
|
|
30
32
|
"eslint-plugin-node": "11.1.0",
|
|
31
33
|
"jest": "29.3.1",
|
|
32
34
|
"jsonc-eslint-parser": "2.3.0",
|
|
33
35
|
"npm-run-all": "4.1.5",
|
|
34
|
-
"ts-jest": "
|
|
36
|
+
"ts-jest": "29.0.5"
|
|
35
37
|
},
|
|
36
38
|
"engines": {
|
|
37
39
|
"node": "16.0.0"
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# Set the directories relative to the script location
|
|
4
|
+
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
|
5
|
+
SRC_DIR="$SCRIPT_DIR/../src/rules"
|
|
6
|
+
DOCS_DIR="$SCRIPT_DIR/../docs/rules"
|
|
7
|
+
|
|
8
|
+
# Create docs/rules directory if it doesn't exist
|
|
9
|
+
mkdir -p "$DOCS_DIR"
|
|
10
|
+
|
|
11
|
+
# Iterate over every file in src/rules
|
|
12
|
+
for SRC_FILE in $SRC_DIR/*; do
|
|
13
|
+
# Extract the filename without the extension
|
|
14
|
+
FILENAME=$(basename -- "$SRC_FILE")
|
|
15
|
+
FILENAME="${FILENAME%.*}"
|
|
16
|
+
|
|
17
|
+
# Create a corresponding .md file in docs/rules
|
|
18
|
+
touch "$DOCS_DIR/$FILENAME.md"
|
|
19
|
+
done
|
|
20
|
+
|
|
21
|
+
echo "Markdown files have been created in $DOCS_DIR."
|