@simplysm/eslint-plugin 12.4.2 → 12.5.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@simplysm/eslint-plugin",
3
- "version": "12.4.2",
3
+ "version": "12.5.2",
4
4
  "description": "심플리즘 패키지 - ESLINT 플러그인",
5
5
  "author": "김석래",
6
6
  "repository": {
@@ -10,21 +10,16 @@
10
10
  },
11
11
  "license": "MIT",
12
12
  "type": "module",
13
- "main": "src/index.cjs",
13
+ "main": "src/index.js",
14
14
  "engines": {
15
15
  "node": "20.16.0"
16
16
  },
17
17
  "dependencies": {
18
- "@angular-eslint/eslint-plugin": "^18.3.0",
19
- "@angular-eslint/eslint-plugin-template": "^18.3.0",
20
- "@angular-eslint/template-parser": "^18.3.0",
21
- "@typescript-eslint/eslint-plugin": "^8.2.0",
22
- "@typescript-eslint/parser": "^8.2.0",
23
- "@typescript-eslint/utils": "^8.2.0",
24
- "eslint": "^8.57.0",
25
- "eslint-import-resolver-typescript": "^3.6.1",
26
- "eslint-module-utils": "^2.8.2",
27
- "eslint-plugin-import": "^2.29.1",
28
- "typescript": "~5.5.4"
18
+ "@typescript-eslint/utils": "^8.4.0",
19
+ "angular-eslint": "^18.3.0",
20
+ "eslint": "^9.9.1",
21
+ "globals": "^15.9.0",
22
+ "typescript": "~5.5.4",
23
+ "typescript-eslint": "^8.4.0"
29
24
  }
30
25
  }
@@ -0,0 +1,92 @@
1
+ import globals from "globals";
2
+ import tseslint from "typescript-eslint";
3
+ import ngeslint from "angular-eslint";
4
+ import plugin from "../plugin.js";
5
+
6
+ export default [
7
+ {
8
+ languageOptions: {
9
+ globals: {
10
+ ...globals.node,
11
+ ...globals.es2021,
12
+ },
13
+ ecmaVersion: 2021,
14
+ sourceType: "module",
15
+ },
16
+ },
17
+ {
18
+ files: ["**/*.js"],
19
+ rules: {
20
+ "no-console": ["warn"],
21
+ "no-warning-comments": ["warn"],
22
+
23
+ "require-await": ["error"],
24
+ "semi": ["error"],
25
+ "no-shadow": ["error"],
26
+ "no-duplicate-imports": ["error"],
27
+ "no-unused-expressions": ["error"],
28
+ "no-unused-vars": ["error"],
29
+ "no-undef": ["error"],
30
+ },
31
+ },
32
+ ...tseslint.config(
33
+ {
34
+ files: ["**/*.ts"],
35
+ plugins: {
36
+ "@typescript-eslint": tseslint.plugin,
37
+ "@angular-eslint": ngeslint.tsPlugin,
38
+ "@simplysm": plugin,
39
+ },
40
+ languageOptions: {
41
+ parser: tseslint.parser,
42
+ },
43
+ processor: ngeslint.processInlineTemplates,
44
+ rules: {
45
+ // 기본
46
+ "no-console": ["warn"],
47
+ "no-warning-comments": ["warn"],
48
+
49
+ // 타입스크립트
50
+ "@typescript-eslint/require-await": ["error"],
51
+ "@typescript-eslint/await-thenable": ["error"],
52
+ "@typescript-eslint/return-await": ["error", "always"],
53
+ "@typescript-eslint/no-floating-promises": ["error"],
54
+ // "@typescript-eslint/semi": ["error"], // Deprecated (https://typescript-eslint.io/rules/semi/)
55
+ "@typescript-eslint/no-shadow": ["error"],
56
+ // "@typescript-eslint/no-unnecessary-condition": ["error", {allowConstantLoopConditions: true}],
57
+ "@typescript-eslint/no-unnecessary-type-assertion": ["error"],
58
+ "@typescript-eslint/non-nullable-type-assertion-style": ["error"],
59
+ "@typescript-eslint/prefer-reduce-type-parameter": ["error"],
60
+ "@typescript-eslint/prefer-return-this-type": ["error"],
61
+ "@typescript-eslint/typedef": ["error"],
62
+ "@typescript-eslint/no-unused-expressions": ["error"],
63
+ "@typescript-eslint/no-unused-vars": ["error", { args: "none" }],
64
+ "@typescript-eslint/strict-boolean-expressions": [
65
+ "error",
66
+ {
67
+ allowNullableBoolean: true,
68
+ allowNullableObject: true,
69
+ },
70
+ ],
71
+ "@typescript-eslint/prefer-ts-expect-error": ["error"],
72
+
73
+ // 심플리즘
74
+ "@simplysm/ts-no-throw-not-implement-error": ["warn"],
75
+ },
76
+ },
77
+ {
78
+ files: ["**/*.html"],
79
+ languageOptions: {
80
+ parser: ngeslint.templateParser,
81
+ },
82
+ plugins: {
83
+ "@angular-eslint/template": ngeslint.templatePlugin,
84
+ "@simplysm": plugin,
85
+ },
86
+ rules: {
87
+ "@simplysm/ng-template-no-todo-comments": "warn",
88
+ "@angular-eslint/template/use-track-by-function": "error",
89
+ },
90
+ },
91
+ ),
92
+ ];
package/src/index.js ADDED
@@ -0,0 +1,7 @@
1
+ import root from "./configs/root.js";
2
+
3
+ export default {
4
+ configs: {
5
+ root,
6
+ },
7
+ };
package/src/plugin.js ADDED
@@ -0,0 +1,9 @@
1
+ import tsNoThrowNotImplementError from "./rules/ts-no-throw-not-implement-error.js";
2
+ import ngTemplateNoTodoComments from "./rules/ng-template-no-todo-comments.js";
3
+
4
+ export default {
5
+ rules: {
6
+ "ts-no-throw-not-implement-error": tsNoThrowNotImplementError,
7
+ "ng-template-no-todo-comments": ngTemplateNoTodoComments,
8
+ },
9
+ };
@@ -1,18 +1,18 @@
1
- module.exports = {
1
+ export default {
2
2
  meta: {
3
3
  type: "suggestion",
4
4
  docs: {
5
- description: "HTML의 'TODO' 주석 경고"
5
+ description: "HTML의 'TODO' 주석 경고",
6
6
  },
7
7
 
8
- schema: []
8
+ schema: [],
9
9
  },
10
10
 
11
11
  create: (context) => {
12
12
  // const parserServices = context.parserServices;
13
13
  return {
14
14
  Program(node) {
15
- if (node.value) {
15
+ if ("value" in node && typeof node.value === "string") {
16
16
  const comments = node.value.match(/<!--(((?!-->)[\s\S])*)-->/g);
17
17
  if (!comments) return;
18
18
 
@@ -33,13 +33,13 @@ module.exports = {
33
33
  context.report({
34
34
  loc: {
35
35
  start: { line, column },
36
- end: { line: endLine, column: endColumn }
36
+ end: { line: endLine, column: endColumn },
37
37
  },
38
- message: comment.match(/<!--(((?!-->)[\s\S])*)-->/)[1].trim()
38
+ message: comment.match(/<!--(((?!-->)[\s\S])*)-->/)[1].trim(),
39
39
  });
40
40
  }
41
41
  }
42
- }
42
+ },
43
43
  };
44
- }
44
+ },
45
45
  };
@@ -1,15 +1,16 @@
1
- const {AST_NODE_TYPES} = require("@typescript-eslint/utils");
1
+ import { AST_NODE_TYPES } from "@typescript-eslint/utils";
2
+ import { getParserServices } from "@typescript-eslint/utils/eslint-utils";
2
3
 
3
- module.exports = {
4
+ export default {
4
5
  meta: {
5
6
  type: "suggestion",
6
7
  docs: {
7
- description: "'NotImplementError' 사용 경고"
8
+ description: "'NotImplementError' 사용 경고",
8
9
  },
9
- schema: []
10
+ schema: [],
10
11
  },
11
12
  create: (context) => {
12
- const parserServices = context.parserServices;
13
+ const parserServices = getParserServices(context);
13
14
  const program = parserServices.program;
14
15
  const checker = program.getTypeChecker();
15
16
 
@@ -45,18 +46,15 @@ module.exports = {
45
46
  }
46
47
 
47
48
  function checkThrowArgument(node) {
48
- if (
49
- node.type === AST_NODE_TYPES.AwaitExpression
50
- || node.type === AST_NODE_TYPES.YieldExpression
51
- ) {
49
+ if (node.type === AST_NODE_TYPES.AwaitExpression || node.type === AST_NODE_TYPES.YieldExpression) {
52
50
  return;
53
51
  }
54
52
 
55
53
  const type = tryGetThrowArgumentType(node);
56
54
  if (type && type.getSymbol() && type.getSymbol().getName() === "NotImplementError") {
57
55
  context.report({
58
- node,
59
- message: node.arguments.value || "구현되어있지 않습니다" //"'NotImplementError'를 'throw'하고 있습니다."
56
+ node: node,
57
+ message: node["arguments"]["value"] || "구현되어있지 않습니다", //"'NotImplementError'를 'throw'하고 있습니다."
60
58
  });
61
59
  }
62
60
  }
@@ -66,7 +64,7 @@ module.exports = {
66
64
  if (node.argument) {
67
65
  checkThrowArgument(node.argument);
68
66
  }
69
- }
67
+ },
70
68
  };
71
- }
69
+ },
72
70
  };
@@ -1,109 +0,0 @@
1
- module.exports = {
2
- ignorePatterns: [
3
- "**/node_modules/**",
4
- "**/.cache/**",
5
- "**/dist/**",
6
- "**/.*/**",
7
- "**/_*/**"
8
- ],
9
- env: {
10
- node: true,
11
- es2021: true
12
- },
13
- parserOptions: {
14
- ecmaVersion: 2021,
15
- sourceType: "module"
16
- },
17
- overrides: [
18
- {
19
- files: ["*.js", "*.cjs"],
20
- plugins: ["import"],
21
- rules: {
22
- // import
23
- "import/no-extraneous-dependencies": ["error"], // 느림
24
-
25
- "no-console": ["warn"],
26
- "no-warning-comments": ["warn"],
27
-
28
- "require-await": ["error"],
29
- "semi": ["error"],
30
- "no-shadow": ["error"],
31
- "no-duplicate-imports": ["error"],
32
- "no-unused-expressions": ["error"],
33
- "no-unused-vars": ["error"],
34
- "no-undef": ["error"],
35
- },
36
- },
37
- {
38
- files: ["*.ts"],
39
- plugins: [
40
- "import",
41
- "@simplysm",
42
- "@typescript-eslint",
43
- "@angular-eslint",
44
- "@angular-eslint/template"
45
- ],
46
- parser: '@typescript-eslint/parser',
47
- processor: "@angular-eslint/template/extract-inline-html",
48
- settings: {
49
- 'import/extensions': [".js", ".cjs", ".ts"],
50
- 'import/external-module-folders': ['node_modules', 'node_modules/@types'],
51
- 'import/parsers': {
52
- '@typescript-eslint/parser': [".ts"],
53
- },
54
- "import/resolver": {
55
- "typescript": true,
56
- "node": {
57
- extensions: [".js", ".cjs", ".ts"]
58
- }
59
- }
60
- },
61
- rules: {
62
- // 기본
63
- "no-console": ["warn"],
64
- "no-warning-comments": ["warn"],
65
-
66
- // import
67
- "import/no-extraneous-dependencies": ["error"], // 느림
68
-
69
- // 타입스크립트
70
- "@typescript-eslint/require-await": ["error"],
71
- "@typescript-eslint/await-thenable": ["error"],
72
- "@typescript-eslint/return-await": ["error", "always"],
73
- "@typescript-eslint/no-floating-promises": ["error"],
74
- // "@typescript-eslint/semi": ["error"], // Deprecated (https://typescript-eslint.io/rules/semi/)
75
- "@typescript-eslint/no-shadow": ["error"],
76
- // "@typescript-eslint/no-unnecessary-condition": ["error", {allowConstantLoopConditions: true}],
77
- "@typescript-eslint/no-unnecessary-type-assertion": ["error"],
78
- "@typescript-eslint/non-nullable-type-assertion-style": ["error"],
79
- "@typescript-eslint/prefer-reduce-type-parameter": ["error"],
80
- "@typescript-eslint/prefer-return-this-type": ["error"],
81
- "@typescript-eslint/typedef": ["error"],
82
- "@typescript-eslint/no-unused-expressions": ["error"],
83
- "@typescript-eslint/no-unused-vars": ["error", {args: "none"}],
84
- "@typescript-eslint/strict-boolean-expressions": ["error", {
85
- allowNullableBoolean: true,
86
- allowNullableObject: true
87
- }],
88
- "@typescript-eslint/prefer-ts-expect-error": ["error"],
89
-
90
- // 심플리즘
91
- "@simplysm/ts-no-throw-not-implement-error": ["warn"],
92
- "@simplysm/ts-no-self-entry-import": ["error"],
93
- "@simplysm/ts-no-external-import": ["error"]
94
- }
95
- },
96
- {
97
- files: ["*.html"],
98
- plugins: [
99
- "@angular-eslint/template",
100
- "@simplysm"
101
- ],
102
- parser: "@angular-eslint/template-parser",
103
- rules: {
104
- "@simplysm/ng-template-no-todo-comments": "warn",
105
- "@angular-eslint/template/use-track-by-function": "error"
106
- }
107
- }
108
- ]
109
- };
package/src/index.cjs DELETED
@@ -1,11 +0,0 @@
1
- module.exports = {
2
- configs: {
3
- "root": require("./configs/root.cjs")
4
- },
5
- rules: {
6
- "ts-no-external-import": require("./rules/ts-no-external-import.cjs"),
7
- "ts-no-self-entry-import": require("./rules/ts-no-self-entry-import.cjs"),
8
- "ts-no-throw-not-implement-error": require("./rules/ts-no-throw-not-implement-error.cjs"),
9
- "ng-template-no-todo-comments": require("./rules/ng-template-no-todo-comments.cjs")
10
- }
11
- };
@@ -1,72 +0,0 @@
1
- const resolve = require("eslint-module-utils/resolve").default;
2
- const path = require("path");
3
- const fs = require("fs");
4
-
5
- module.exports = {
6
- meta: {
7
- type: "problem",
8
- docs: {
9
- description: "패키지 외부의 파일 직접 import 금지"
10
- },
11
- fixable: true,
12
- schema: [],
13
- },
14
- create: (context) => {
15
- const filePath = context.getFilename();
16
-
17
- function getPkgPath(currFilePath) {
18
- let curr = path.dirname(currFilePath);
19
- while (true) {
20
- if (fs.existsSync(path.resolve(curr, "package.json"))) {
21
- break;
22
- }
23
-
24
- curr = path.dirname(curr);
25
- if (!curr) break;
26
- }
27
-
28
- return curr;
29
- }
30
-
31
- function append(node) {
32
- const requirePath = node.value;
33
- if (filePath !== "<text>" && requirePath.startsWith("..")) {
34
- const resolvedPath = (resolve(requirePath, context) || requirePath).toLowerCase();
35
- if (resolvedPath) {
36
- const pkgPath = getPkgPath(filePath);
37
- const relativePath = path.relative(pkgPath, resolvedPath);
38
- const isChildPath = Boolean(relativePath) && !relativePath.startsWith("..") && !path.isAbsolute(relativePath);
39
- if (!isChildPath) {
40
- context.report({
41
- node,
42
- message: "패키지 외부의 파일을 직접 import 하고 있습니다.",
43
- fix(fixer) {
44
- const reqPkgNpmConf = JSON.parse(fs.readFileSync(path.resolve(getPkgPath(resolvedPath), "package.json"), "utf-8"));
45
- return fixer.replaceText(node, `"${reqPkgNpmConf.name}"`);
46
- }
47
- });
48
- }
49
- }
50
- }
51
- }
52
-
53
- return {
54
- "ImportDeclaration": (node) => {
55
- append(node.source);
56
- },
57
- "CallExpression": (node) => {
58
- if (
59
- node
60
- && node.callee
61
- && node.callee.type === "Identifier"
62
- && node.callee.name === "require"
63
- && node.arguments.length === 1
64
- && node.arguments[0].type === "Literal"
65
- && typeof node.arguments[0].value === "string"
66
- ) {
67
- append(node.arguments[0]);
68
- }
69
- }
70
- };
71
- }
72
- };
@@ -1,63 +0,0 @@
1
- const resolve = require("eslint-module-utils/resolve").default;
2
- const path = require("path");
3
-
4
- module.exports = {
5
- meta: {
6
- type: "problem",
7
- docs: {
8
- description: "동일 패키지 내의 index.ts 파일 import 금지"
9
- },
10
- schema: []
11
- },
12
- create: (context) => {
13
- const filePath = context.getFilename();
14
- const importMap = new Map();
15
-
16
- function append(requirePath, node) {
17
- if (filePath !== "<text>" && (requirePath.endsWith(".") || requirePath.endsWith("/"))) {
18
- const resolvedPath = (resolve(requirePath, context) || requirePath).toLowerCase();
19
- if (resolvedPath) {
20
- if (importMap.has(resolvedPath)) {
21
- importMap.get(resolvedPath).push(node);
22
- }
23
- else {
24
- importMap.set(resolvedPath, [node]);
25
- }
26
- }
27
- }
28
- }
29
-
30
- return {
31
- "ImportDeclaration": (node) => {
32
- append(node.source.value, node);
33
- },
34
- "CallExpression": (node) => {
35
- if (
36
- node
37
- && node.callee
38
- && node.callee.type === "Identifier"
39
- && node.callee.name === "require"
40
- && node.arguments.length === 1
41
- && node.arguments[0].type === "Literal"
42
- && typeof node.arguments[0].value === "string"
43
- ) {
44
- append(node.arguments[0].value, node);
45
- }
46
- },
47
- "Program:exit": () => {
48
- const rootFileNames = context.parserServices.program.getRootFileNames()
49
- .map((item) => path.normalize(item).toLowerCase());
50
- for (const rootFileName of rootFileNames) {
51
- if (importMap.has(rootFileName)) {
52
- for (const node of importMap.get(rootFileName)) {
53
- context.report({
54
- node,
55
- message: "동일 패키지상의 index.ts 파일을 import 하고 있습니다."
56
- });
57
- }
58
- }
59
- }
60
- }
61
- };
62
- }
63
- };