@kurateh/eslint-plugin 0.1.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 +8 -0
- package/dist/index.d.mts +1165 -0
- package/dist/index.d.ts +1165 -0
- package/dist/index.js +411 -0
- package/dist/index.mjs +400 -0
- package/package.json +55 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,411 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var react = require('eslint-plugin-react');
|
|
4
|
+
var reactHook = require('eslint-plugin-react-hooks');
|
|
5
|
+
var globals = require('globals');
|
|
6
|
+
var importPlugin = require('eslint-plugin-import');
|
|
7
|
+
var tseslint = require('typescript-eslint');
|
|
8
|
+
var fs = require('fs');
|
|
9
|
+
var path = require('path');
|
|
10
|
+
var utils = require('@typescript-eslint/utils');
|
|
11
|
+
var js = require('@eslint/js');
|
|
12
|
+
var eslintPluginPrettierRecommended = require('eslint-plugin-prettier/recommended');
|
|
13
|
+
var unusedImportsPlugin = require('eslint-plugin-unused-imports');
|
|
14
|
+
|
|
15
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
16
|
+
|
|
17
|
+
var react__default = /*#__PURE__*/_interopDefault(react);
|
|
18
|
+
var reactHook__default = /*#__PURE__*/_interopDefault(reactHook);
|
|
19
|
+
var globals__default = /*#__PURE__*/_interopDefault(globals);
|
|
20
|
+
var importPlugin__default = /*#__PURE__*/_interopDefault(importPlugin);
|
|
21
|
+
var tseslint__default = /*#__PURE__*/_interopDefault(tseslint);
|
|
22
|
+
var js__default = /*#__PURE__*/_interopDefault(js);
|
|
23
|
+
var eslintPluginPrettierRecommended__default = /*#__PURE__*/_interopDefault(eslintPluginPrettierRecommended);
|
|
24
|
+
var unusedImportsPlugin__default = /*#__PURE__*/_interopDefault(unusedImportsPlugin);
|
|
25
|
+
|
|
26
|
+
var __defProp = Object.defineProperty;
|
|
27
|
+
var __defProps = Object.defineProperties;
|
|
28
|
+
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
29
|
+
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
30
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
31
|
+
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
32
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
33
|
+
var __spreadValues = (a, b) => {
|
|
34
|
+
for (var prop in b || (b = {}))
|
|
35
|
+
if (__hasOwnProp.call(b, prop))
|
|
36
|
+
__defNormalProp(a, prop, b[prop]);
|
|
37
|
+
if (__getOwnPropSymbols)
|
|
38
|
+
for (var prop of __getOwnPropSymbols(b)) {
|
|
39
|
+
if (__propIsEnum.call(b, prop))
|
|
40
|
+
__defNormalProp(a, prop, b[prop]);
|
|
41
|
+
}
|
|
42
|
+
return a;
|
|
43
|
+
};
|
|
44
|
+
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
45
|
+
var createRule = utils.ESLintUtils.RuleCreator.withoutDocs;
|
|
46
|
+
|
|
47
|
+
// src/rules/import-path.ts
|
|
48
|
+
var TS_CONFIG_FILE_NAMES = ["tsconfig.path.json", "tsconfig.json"];
|
|
49
|
+
var has = (map, path) => {
|
|
50
|
+
let inner = map;
|
|
51
|
+
for (const step of path.split(".")) {
|
|
52
|
+
inner = inner[step];
|
|
53
|
+
if (inner === void 0) {
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return true;
|
|
58
|
+
};
|
|
59
|
+
var findFilePath = (filename, initialPath) => {
|
|
60
|
+
let dir = initialPath;
|
|
61
|
+
do {
|
|
62
|
+
dir = path.dirname(dir);
|
|
63
|
+
} while (!fs.existsSync(path.join(dir, filename)) && dir !== "/");
|
|
64
|
+
const filePath = path.join(dir, filename);
|
|
65
|
+
if (!fs.existsSync(filePath)) {
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
return filePath;
|
|
69
|
+
};
|
|
70
|
+
var getAbsolutePathInfo = (fileName) => {
|
|
71
|
+
for (const configPath of TS_CONFIG_FILE_NAMES) {
|
|
72
|
+
const filePath = findFilePath(configPath, fileName);
|
|
73
|
+
if (filePath === void 0) {
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
const baseDir = path.dirname(filePath);
|
|
77
|
+
const tsPathConfig = JSON.parse(
|
|
78
|
+
fs.readFileSync(filePath, {
|
|
79
|
+
encoding: "utf-8"
|
|
80
|
+
})
|
|
81
|
+
);
|
|
82
|
+
const result = {
|
|
83
|
+
baseUrl: "",
|
|
84
|
+
paths: {}
|
|
85
|
+
};
|
|
86
|
+
if (has(tsPathConfig, "compilerOptions.baseUrl")) {
|
|
87
|
+
result.baseUrl = path.join(baseDir, tsPathConfig.compilerOptions.baseUrl);
|
|
88
|
+
}
|
|
89
|
+
if (has(tsPathConfig, "compilerOptions.paths")) {
|
|
90
|
+
result.paths = Object.fromEntries(
|
|
91
|
+
Object.entries(tsPathConfig.compilerOptions.paths).map(
|
|
92
|
+
([key, value]) => [
|
|
93
|
+
key.replace(/\/\*$/, "/"),
|
|
94
|
+
value.map((path$1) => path.join(baseDir, path$1).replace(/\/\*$/, "/"))
|
|
95
|
+
]
|
|
96
|
+
)
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
return result;
|
|
100
|
+
}
|
|
101
|
+
return;
|
|
102
|
+
};
|
|
103
|
+
var import_path_default = createRule({
|
|
104
|
+
meta: {
|
|
105
|
+
type: "suggestion",
|
|
106
|
+
fixable: "code",
|
|
107
|
+
messages: {
|
|
108
|
+
shouldBeRelativePath: 'When importing a child module, you must use the relative path. Use "{{expectedPath}}" instead of "{{source}}".',
|
|
109
|
+
shouldBeAbsolutePath: 'When importing a parent module, you must use the absolute path. Use "{{expectedPath}}" instead of "{{source}}".'
|
|
110
|
+
},
|
|
111
|
+
schema: [],
|
|
112
|
+
docs: {
|
|
113
|
+
description: "Enforce import path according to the location of the imported file."
|
|
114
|
+
}
|
|
115
|
+
},
|
|
116
|
+
defaultOptions: [],
|
|
117
|
+
create: (context) => {
|
|
118
|
+
return {
|
|
119
|
+
ImportDeclaration: (node) => {
|
|
120
|
+
const fileName = context.getFilename();
|
|
121
|
+
const absolutePathInfo = getAbsolutePathInfo(fileName);
|
|
122
|
+
if (absolutePathInfo === void 0) {
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
const source = node.source.value;
|
|
126
|
+
if (source.startsWith("..")) {
|
|
127
|
+
const sourceAbsolutePath2 = path.join(path.dirname(fileName), source);
|
|
128
|
+
for (const [alias, paths] of Object.entries(absolutePathInfo.paths)) {
|
|
129
|
+
for (const path of paths) {
|
|
130
|
+
if (sourceAbsolutePath2.startsWith(path)) {
|
|
131
|
+
const expectedPath2 = sourceAbsolutePath2.replace(path, alias);
|
|
132
|
+
context.report({
|
|
133
|
+
node,
|
|
134
|
+
messageId: "shouldBeAbsolutePath",
|
|
135
|
+
data: {
|
|
136
|
+
expectedPath: expectedPath2,
|
|
137
|
+
source
|
|
138
|
+
},
|
|
139
|
+
fix(fixer) {
|
|
140
|
+
return fixer.replaceText(node.source, `"${expectedPath2}"`);
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
let sourceAbsolutePath;
|
|
150
|
+
for (const [alias, paths] of Object.entries(absolutePathInfo.paths)) {
|
|
151
|
+
for (const path$1 of paths) {
|
|
152
|
+
if (source.startsWith(alias)) {
|
|
153
|
+
sourceAbsolutePath = path.join(path$1, source.replace(alias, ""));
|
|
154
|
+
break;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
if (sourceAbsolutePath !== void 0) {
|
|
158
|
+
break;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
if (sourceAbsolutePath === void 0) {
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
const sourceRelativePath = path.relative(
|
|
165
|
+
path.dirname(fileName),
|
|
166
|
+
sourceAbsolutePath
|
|
167
|
+
);
|
|
168
|
+
if (sourceRelativePath.startsWith("..")) {
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
const expectedPath = "./" + sourceRelativePath;
|
|
172
|
+
context.report({
|
|
173
|
+
node,
|
|
174
|
+
messageId: "shouldBeRelativePath",
|
|
175
|
+
data: {
|
|
176
|
+
expectedPath,
|
|
177
|
+
source
|
|
178
|
+
},
|
|
179
|
+
fix(fixer) {
|
|
180
|
+
return fixer.replaceText(node.source, `"${expectedPath}"`);
|
|
181
|
+
}
|
|
182
|
+
});
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
// src/rules/index.ts
|
|
190
|
+
var rules_default = {
|
|
191
|
+
"import-path": import_path_default
|
|
192
|
+
};
|
|
193
|
+
var recommended_default = [
|
|
194
|
+
js__default.default.configs.recommended,
|
|
195
|
+
importPlugin__default.default.flatConfigs.recommended,
|
|
196
|
+
eslintPluginPrettierRecommended__default.default,
|
|
197
|
+
{
|
|
198
|
+
languageOptions: {
|
|
199
|
+
ecmaVersion: 2020,
|
|
200
|
+
sourceType: "module",
|
|
201
|
+
globals: __spreadValues(__spreadValues(__spreadValues({}, globals__default.default.es2017), globals__default.default.browser), globals__default.default.node)
|
|
202
|
+
},
|
|
203
|
+
plugins: {
|
|
204
|
+
"unused-imports": unusedImportsPlugin__default.default
|
|
205
|
+
},
|
|
206
|
+
ignores: ["node_modules/", "dist/", "build/", "coverage/"],
|
|
207
|
+
rules: {
|
|
208
|
+
// eslint
|
|
209
|
+
"object-shorthand": 1,
|
|
210
|
+
"no-unused-vars": [
|
|
211
|
+
1,
|
|
212
|
+
{
|
|
213
|
+
ignoreRestSiblings: true,
|
|
214
|
+
vars: "all",
|
|
215
|
+
args: "after-used",
|
|
216
|
+
argsIgnorePattern: "^_",
|
|
217
|
+
varsIgnorePattern: "^_"
|
|
218
|
+
}
|
|
219
|
+
],
|
|
220
|
+
"no-param-reassign": [
|
|
221
|
+
2,
|
|
222
|
+
{
|
|
223
|
+
props: true,
|
|
224
|
+
ignorePropertyModificationsForRegex: ["^draft$", "Draft$"]
|
|
225
|
+
}
|
|
226
|
+
],
|
|
227
|
+
camelcase: [1, { allow: ["^\\w*_[A-Z]*$"] }],
|
|
228
|
+
"no-var": 2,
|
|
229
|
+
// prettier
|
|
230
|
+
"prettier/prettier": [
|
|
231
|
+
1,
|
|
232
|
+
{
|
|
233
|
+
trailingComma: "all",
|
|
234
|
+
tabWidth: 2,
|
|
235
|
+
semi: true,
|
|
236
|
+
singleQuote: false,
|
|
237
|
+
endOfLine: "auto"
|
|
238
|
+
},
|
|
239
|
+
{
|
|
240
|
+
usePrettierrc: false
|
|
241
|
+
}
|
|
242
|
+
],
|
|
243
|
+
// import
|
|
244
|
+
"import/no-unresolved": 0,
|
|
245
|
+
"import/no-extraneous-dependencies": [
|
|
246
|
+
2,
|
|
247
|
+
{
|
|
248
|
+
devDependencies: [
|
|
249
|
+
"**/*.test.*",
|
|
250
|
+
"**/*.stories.*",
|
|
251
|
+
"**/*.config.*",
|
|
252
|
+
"**/*.spec.*"
|
|
253
|
+
]
|
|
254
|
+
}
|
|
255
|
+
],
|
|
256
|
+
"import/order": [
|
|
257
|
+
1,
|
|
258
|
+
{
|
|
259
|
+
alphabetize: {
|
|
260
|
+
order: "asc",
|
|
261
|
+
caseInsensitive: true
|
|
262
|
+
},
|
|
263
|
+
"newlines-between": "always",
|
|
264
|
+
groups: [
|
|
265
|
+
"builtin",
|
|
266
|
+
"external",
|
|
267
|
+
"internal",
|
|
268
|
+
["parent", "sibling", "index"]
|
|
269
|
+
],
|
|
270
|
+
pathGroups: [
|
|
271
|
+
{
|
|
272
|
+
pattern: "~*/**",
|
|
273
|
+
group: "internal"
|
|
274
|
+
},
|
|
275
|
+
{
|
|
276
|
+
pattern: "@*/**",
|
|
277
|
+
group: "internal"
|
|
278
|
+
}
|
|
279
|
+
]
|
|
280
|
+
}
|
|
281
|
+
],
|
|
282
|
+
// unused-imports
|
|
283
|
+
"unused-imports/no-unused-imports": 2
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
];
|
|
287
|
+
|
|
288
|
+
// src/configs/typescript.ts
|
|
289
|
+
var typescript_default = [
|
|
290
|
+
...recommended_default,
|
|
291
|
+
// eslint-disable-next-line import/no-named-as-default-member
|
|
292
|
+
...tseslint__default.default.configs.recommended,
|
|
293
|
+
importPlugin__default.default.flatConfigs.typescript,
|
|
294
|
+
{
|
|
295
|
+
// ESLint config block에 file이 있으면 해당 파일을 검사할 차례가 와서야 plugin이 적용됨
|
|
296
|
+
// 따라서 이 Plugin을 끄려면 Config File에서 file: "~~"을 넣어야 됨
|
|
297
|
+
// 이 과정을 없애기 위해 plugin 적용을 앞서 진행
|
|
298
|
+
plugins: {
|
|
299
|
+
"@kurateh": { rules: rules_default, meta: { name: "@kurateh" } }
|
|
300
|
+
}
|
|
301
|
+
},
|
|
302
|
+
{
|
|
303
|
+
files: ["**/*.ts", "**/*.tsx", "**/*.mts", "**/*.cts"],
|
|
304
|
+
settings: {
|
|
305
|
+
"import/resolver": {
|
|
306
|
+
typescript: {
|
|
307
|
+
alwaysTryTypes: true,
|
|
308
|
+
// always try to resolve types under `<root>@types` directory even it doesn't contain any source code, like `@types/unist`
|
|
309
|
+
// Choose from one of the "project" configs below or omit to use <root>/tsconfig.json by default
|
|
310
|
+
// use <root>/path/to/folder/tsconfig.json
|
|
311
|
+
project: "tsconfig.json"
|
|
312
|
+
// Multiple tsconfigs (Useful for monorepos)
|
|
313
|
+
// use a glob pattern
|
|
314
|
+
// project: "packages/*/tsconfig.json",
|
|
315
|
+
// use an array
|
|
316
|
+
// project: [
|
|
317
|
+
// "packages/module-a/tsconfig.json",
|
|
318
|
+
// "packages/module-b/tsconfig.json"
|
|
319
|
+
// ],
|
|
320
|
+
// use an array of glob patterns
|
|
321
|
+
// project: [
|
|
322
|
+
// "packages/*/tsconfig.json",
|
|
323
|
+
// "other-packages/*/
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
},
|
|
327
|
+
rules: {
|
|
328
|
+
// eslint
|
|
329
|
+
"@kurateh/import-path": 1,
|
|
330
|
+
"object-shorthand": 1,
|
|
331
|
+
"no-unused-vars": 0,
|
|
332
|
+
"@typescript-eslint/no-unused-vars": [
|
|
333
|
+
1,
|
|
334
|
+
{
|
|
335
|
+
ignoreRestSiblings: true,
|
|
336
|
+
vars: "all",
|
|
337
|
+
args: "after-used",
|
|
338
|
+
argsIgnorePattern: "^_",
|
|
339
|
+
varsIgnorePattern: "^_"
|
|
340
|
+
}
|
|
341
|
+
],
|
|
342
|
+
"@typescript-eslint/consistent-type-imports": [
|
|
343
|
+
1,
|
|
344
|
+
{
|
|
345
|
+
fixStyle: "inline-type-imports"
|
|
346
|
+
}
|
|
347
|
+
],
|
|
348
|
+
"no-param-reassign": [
|
|
349
|
+
2,
|
|
350
|
+
{
|
|
351
|
+
props: true,
|
|
352
|
+
ignorePropertyModificationsForRegex: ["^draft$", "Draft$"]
|
|
353
|
+
}
|
|
354
|
+
],
|
|
355
|
+
camelcase: [1, { allow: ["^\\w*_[A-Z]*$"] }],
|
|
356
|
+
"no-var": 2,
|
|
357
|
+
"import-plugin/no-unresolved": 0
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
];
|
|
361
|
+
|
|
362
|
+
// src/configs/react.ts
|
|
363
|
+
var _a, _b;
|
|
364
|
+
var react_default = [
|
|
365
|
+
...typescript_default,
|
|
366
|
+
(_b = (_a = react__default.default.configs.flat) == null ? void 0 : _a.recommended) != null ? _b : {},
|
|
367
|
+
{
|
|
368
|
+
plugins: { "react-hooks": reactHook__default.default },
|
|
369
|
+
files: ["**/*.{js,jsx,mjs,cjs,ts,tsx}"],
|
|
370
|
+
languageOptions: {
|
|
371
|
+
parserOptions: {
|
|
372
|
+
ecmaFeatures: {
|
|
373
|
+
jsx: true
|
|
374
|
+
}
|
|
375
|
+
},
|
|
376
|
+
globals: __spreadValues({}, globals__default.default.browser)
|
|
377
|
+
},
|
|
378
|
+
rules: __spreadProps(__spreadValues({}, reactHook__default.default.configs.recommended.rules), {
|
|
379
|
+
"react/react-in-jsx-scope": 0,
|
|
380
|
+
"react/function-component-definition": [
|
|
381
|
+
2,
|
|
382
|
+
{
|
|
383
|
+
namedComponents: "arrow-function",
|
|
384
|
+
unnamedComponents: "arrow-function"
|
|
385
|
+
}
|
|
386
|
+
],
|
|
387
|
+
"react/jsx-curly-brace-presence": [
|
|
388
|
+
1,
|
|
389
|
+
{
|
|
390
|
+
props: "never",
|
|
391
|
+
children: "never"
|
|
392
|
+
}
|
|
393
|
+
],
|
|
394
|
+
"react/prop-types": 0,
|
|
395
|
+
"react/require-default-props": 0,
|
|
396
|
+
"react/display-name": 0
|
|
397
|
+
})
|
|
398
|
+
}
|
|
399
|
+
];
|
|
400
|
+
|
|
401
|
+
// src/index.ts
|
|
402
|
+
var index_default = {
|
|
403
|
+
configs: {
|
|
404
|
+
recommended: recommended_default,
|
|
405
|
+
typescript: typescript_default,
|
|
406
|
+
react: react_default
|
|
407
|
+
},
|
|
408
|
+
rules: rules_default
|
|
409
|
+
};
|
|
410
|
+
|
|
411
|
+
module.exports = index_default;
|