eslint-plugin-kirklin 0.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.
- package/dist/index.cjs +156 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.mjs +154 -0
- package/package.json +25 -0
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const utils = require('@typescript-eslint/utils');
|
|
4
|
+
|
|
5
|
+
const createEslintRule = utils.ESLintUtils.RuleCreator(
|
|
6
|
+
(ruleName) => ruleName
|
|
7
|
+
);
|
|
8
|
+
|
|
9
|
+
const RULE_NAME$2 = "if-newline";
|
|
10
|
+
const ifNewline = createEslintRule({
|
|
11
|
+
name: RULE_NAME$2,
|
|
12
|
+
meta: {
|
|
13
|
+
type: "problem",
|
|
14
|
+
docs: {
|
|
15
|
+
description: "Newline after if",
|
|
16
|
+
recommended: "error"
|
|
17
|
+
},
|
|
18
|
+
fixable: "code",
|
|
19
|
+
schema: [],
|
|
20
|
+
messages: {
|
|
21
|
+
missingIfNewline: "Expect newline after if"
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
defaultOptions: [],
|
|
25
|
+
create: (context) => {
|
|
26
|
+
return {
|
|
27
|
+
IfStatement(node) {
|
|
28
|
+
if (!node.consequent)
|
|
29
|
+
return;
|
|
30
|
+
if (node.consequent.type === "BlockStatement")
|
|
31
|
+
return;
|
|
32
|
+
if (node.test.loc.end.line === node.consequent.loc.start.line) {
|
|
33
|
+
context.report({
|
|
34
|
+
node,
|
|
35
|
+
loc: {
|
|
36
|
+
start: node.test.loc.end,
|
|
37
|
+
end: node.consequent.loc.start
|
|
38
|
+
},
|
|
39
|
+
messageId: "missingIfNewline",
|
|
40
|
+
fix(fixer) {
|
|
41
|
+
return fixer.replaceTextRange([node.consequent.range[0], node.consequent.range[0]], "\n");
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
const RULE_NAME$1 = "import-dedupe";
|
|
51
|
+
const importDedupe = createEslintRule({
|
|
52
|
+
name: RULE_NAME$1,
|
|
53
|
+
meta: {
|
|
54
|
+
type: "problem",
|
|
55
|
+
docs: {
|
|
56
|
+
description: "Fix duplication in imports",
|
|
57
|
+
recommended: "error"
|
|
58
|
+
},
|
|
59
|
+
fixable: "code",
|
|
60
|
+
schema: [],
|
|
61
|
+
messages: {
|
|
62
|
+
importDedupe: "Expect no duplication in imports"
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
defaultOptions: [],
|
|
66
|
+
create: (context) => {
|
|
67
|
+
return {
|
|
68
|
+
ImportDeclaration(node) {
|
|
69
|
+
if (node.specifiers.length <= 1)
|
|
70
|
+
return;
|
|
71
|
+
const names = /* @__PURE__ */ new Set();
|
|
72
|
+
node.specifiers.forEach((n) => {
|
|
73
|
+
const id = n.local.name;
|
|
74
|
+
if (names.has(id)) {
|
|
75
|
+
context.report({
|
|
76
|
+
node,
|
|
77
|
+
loc: {
|
|
78
|
+
start: n.loc.end,
|
|
79
|
+
end: n.loc.start
|
|
80
|
+
},
|
|
81
|
+
messageId: "importDedupe",
|
|
82
|
+
fix(fixer) {
|
|
83
|
+
const s = n.range[0];
|
|
84
|
+
let e = n.range[1];
|
|
85
|
+
if (context.getSourceCode().text[e] === ",")
|
|
86
|
+
e += 1;
|
|
87
|
+
return fixer.removeRange([s, e]);
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
names.add(id);
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
const RULE_NAME = "prefer-inline-type-import";
|
|
99
|
+
const preferInlineTypeImport = createEslintRule({
|
|
100
|
+
name: RULE_NAME,
|
|
101
|
+
meta: {
|
|
102
|
+
type: "suggestion",
|
|
103
|
+
docs: {
|
|
104
|
+
description: "Newline after if",
|
|
105
|
+
recommended: "error"
|
|
106
|
+
},
|
|
107
|
+
fixable: "code",
|
|
108
|
+
schema: [],
|
|
109
|
+
messages: {
|
|
110
|
+
preferInlineTypeImport: "Prefer inline type import"
|
|
111
|
+
}
|
|
112
|
+
},
|
|
113
|
+
defaultOptions: [],
|
|
114
|
+
create: (context) => {
|
|
115
|
+
const sourceCode = context.getSourceCode();
|
|
116
|
+
return {
|
|
117
|
+
ImportDeclaration: (node) => {
|
|
118
|
+
if (node.specifiers.length === 1 && ["ImportNamespaceSpecifier", "ImportDefaultSpecifier"].includes(node.specifiers[0].type))
|
|
119
|
+
return;
|
|
120
|
+
if (node.importKind === "type") {
|
|
121
|
+
context.report({
|
|
122
|
+
*fix(fixer) {
|
|
123
|
+
yield* removeTypeSpecifier(fixer, sourceCode, node);
|
|
124
|
+
for (const specifier of node.specifiers)
|
|
125
|
+
yield fixer.insertTextBefore(specifier, "type ");
|
|
126
|
+
},
|
|
127
|
+
loc: node.loc,
|
|
128
|
+
messageId: "preferInlineTypeImport",
|
|
129
|
+
node
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
function* removeTypeSpecifier(fixer, sourceCode, node) {
|
|
137
|
+
const importKeyword = sourceCode.getFirstToken(node);
|
|
138
|
+
const typeIdentifier = sourceCode.getTokenAfter(importKeyword);
|
|
139
|
+
yield fixer.remove(typeIdentifier);
|
|
140
|
+
if (importKeyword.loc.end.column + 1 === typeIdentifier.loc.start.column) {
|
|
141
|
+
yield fixer.removeRange([
|
|
142
|
+
importKeyword.range[1],
|
|
143
|
+
importKeyword.range[1] + 1
|
|
144
|
+
]);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const index = {
|
|
149
|
+
rules: {
|
|
150
|
+
"if-newline": ifNewline,
|
|
151
|
+
"import-dedupe": importDedupe,
|
|
152
|
+
"prefer-inline-type-import": preferInlineTypeImport
|
|
153
|
+
}
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
module.exports = index;
|
package/dist/index.d.ts
ADDED
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import { ESLintUtils } from '@typescript-eslint/utils';
|
|
2
|
+
|
|
3
|
+
const createEslintRule = ESLintUtils.RuleCreator(
|
|
4
|
+
(ruleName) => ruleName
|
|
5
|
+
);
|
|
6
|
+
|
|
7
|
+
const RULE_NAME$2 = "if-newline";
|
|
8
|
+
const ifNewline = createEslintRule({
|
|
9
|
+
name: RULE_NAME$2,
|
|
10
|
+
meta: {
|
|
11
|
+
type: "problem",
|
|
12
|
+
docs: {
|
|
13
|
+
description: "Newline after if",
|
|
14
|
+
recommended: "error"
|
|
15
|
+
},
|
|
16
|
+
fixable: "code",
|
|
17
|
+
schema: [],
|
|
18
|
+
messages: {
|
|
19
|
+
missingIfNewline: "Expect newline after if"
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
defaultOptions: [],
|
|
23
|
+
create: (context) => {
|
|
24
|
+
return {
|
|
25
|
+
IfStatement(node) {
|
|
26
|
+
if (!node.consequent)
|
|
27
|
+
return;
|
|
28
|
+
if (node.consequent.type === "BlockStatement")
|
|
29
|
+
return;
|
|
30
|
+
if (node.test.loc.end.line === node.consequent.loc.start.line) {
|
|
31
|
+
context.report({
|
|
32
|
+
node,
|
|
33
|
+
loc: {
|
|
34
|
+
start: node.test.loc.end,
|
|
35
|
+
end: node.consequent.loc.start
|
|
36
|
+
},
|
|
37
|
+
messageId: "missingIfNewline",
|
|
38
|
+
fix(fixer) {
|
|
39
|
+
return fixer.replaceTextRange([node.consequent.range[0], node.consequent.range[0]], "\n");
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
const RULE_NAME$1 = "import-dedupe";
|
|
49
|
+
const importDedupe = createEslintRule({
|
|
50
|
+
name: RULE_NAME$1,
|
|
51
|
+
meta: {
|
|
52
|
+
type: "problem",
|
|
53
|
+
docs: {
|
|
54
|
+
description: "Fix duplication in imports",
|
|
55
|
+
recommended: "error"
|
|
56
|
+
},
|
|
57
|
+
fixable: "code",
|
|
58
|
+
schema: [],
|
|
59
|
+
messages: {
|
|
60
|
+
importDedupe: "Expect no duplication in imports"
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
defaultOptions: [],
|
|
64
|
+
create: (context) => {
|
|
65
|
+
return {
|
|
66
|
+
ImportDeclaration(node) {
|
|
67
|
+
if (node.specifiers.length <= 1)
|
|
68
|
+
return;
|
|
69
|
+
const names = /* @__PURE__ */ new Set();
|
|
70
|
+
node.specifiers.forEach((n) => {
|
|
71
|
+
const id = n.local.name;
|
|
72
|
+
if (names.has(id)) {
|
|
73
|
+
context.report({
|
|
74
|
+
node,
|
|
75
|
+
loc: {
|
|
76
|
+
start: n.loc.end,
|
|
77
|
+
end: n.loc.start
|
|
78
|
+
},
|
|
79
|
+
messageId: "importDedupe",
|
|
80
|
+
fix(fixer) {
|
|
81
|
+
const s = n.range[0];
|
|
82
|
+
let e = n.range[1];
|
|
83
|
+
if (context.getSourceCode().text[e] === ",")
|
|
84
|
+
e += 1;
|
|
85
|
+
return fixer.removeRange([s, e]);
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
names.add(id);
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
const RULE_NAME = "prefer-inline-type-import";
|
|
97
|
+
const preferInlineTypeImport = createEslintRule({
|
|
98
|
+
name: RULE_NAME,
|
|
99
|
+
meta: {
|
|
100
|
+
type: "suggestion",
|
|
101
|
+
docs: {
|
|
102
|
+
description: "Newline after if",
|
|
103
|
+
recommended: "error"
|
|
104
|
+
},
|
|
105
|
+
fixable: "code",
|
|
106
|
+
schema: [],
|
|
107
|
+
messages: {
|
|
108
|
+
preferInlineTypeImport: "Prefer inline type import"
|
|
109
|
+
}
|
|
110
|
+
},
|
|
111
|
+
defaultOptions: [],
|
|
112
|
+
create: (context) => {
|
|
113
|
+
const sourceCode = context.getSourceCode();
|
|
114
|
+
return {
|
|
115
|
+
ImportDeclaration: (node) => {
|
|
116
|
+
if (node.specifiers.length === 1 && ["ImportNamespaceSpecifier", "ImportDefaultSpecifier"].includes(node.specifiers[0].type))
|
|
117
|
+
return;
|
|
118
|
+
if (node.importKind === "type") {
|
|
119
|
+
context.report({
|
|
120
|
+
*fix(fixer) {
|
|
121
|
+
yield* removeTypeSpecifier(fixer, sourceCode, node);
|
|
122
|
+
for (const specifier of node.specifiers)
|
|
123
|
+
yield fixer.insertTextBefore(specifier, "type ");
|
|
124
|
+
},
|
|
125
|
+
loc: node.loc,
|
|
126
|
+
messageId: "preferInlineTypeImport",
|
|
127
|
+
node
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
function* removeTypeSpecifier(fixer, sourceCode, node) {
|
|
135
|
+
const importKeyword = sourceCode.getFirstToken(node);
|
|
136
|
+
const typeIdentifier = sourceCode.getTokenAfter(importKeyword);
|
|
137
|
+
yield fixer.remove(typeIdentifier);
|
|
138
|
+
if (importKeyword.loc.end.column + 1 === typeIdentifier.loc.start.column) {
|
|
139
|
+
yield fixer.removeRange([
|
|
140
|
+
importKeyword.range[1],
|
|
141
|
+
importKeyword.range[1] + 1
|
|
142
|
+
]);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
const index = {
|
|
147
|
+
rules: {
|
|
148
|
+
"if-newline": ifNewline,
|
|
149
|
+
"import-dedupe": importDedupe,
|
|
150
|
+
"prefer-inline-type-import": preferInlineTypeImport
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
export { index as default };
|
package/package.json
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "eslint-plugin-kirklin",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"license": "MIT",
|
|
5
|
+
"homepage": "https://github.com/kirklin/eslint-config",
|
|
6
|
+
"main": "./dist/index.cjs",
|
|
7
|
+
"module": "./dist/index.mjs",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"files": [
|
|
10
|
+
"dist"
|
|
11
|
+
],
|
|
12
|
+
"scripts": {
|
|
13
|
+
"build": "rimraf dist && unbuild",
|
|
14
|
+
"stub": "unbuild --stub",
|
|
15
|
+
"test": "vitest",
|
|
16
|
+
"prepublishOnly": "npm run build"
|
|
17
|
+
},
|
|
18
|
+
"dependencies": {
|
|
19
|
+
"@typescript-eslint/utils": "^5.35.1"
|
|
20
|
+
},
|
|
21
|
+
"devDependencies": {
|
|
22
|
+
"unbuild": "^0.8.9",
|
|
23
|
+
"vitest": "^0.22.1"
|
|
24
|
+
}
|
|
25
|
+
}
|