@simplysm/lint 13.0.69 → 13.0.71

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.
@@ -18,27 +18,27 @@ function isClassMemberWithAccessibility(
18
18
  }
19
19
 
20
20
  /**
21
- * ECMAScript private 필드(`#field`) 사용을 제한하고 TypeScript `private` 키워드 사용을 강제하는 ESLint 규칙
21
+ * ESLint rule that restricts ECMAScript private fields (`#field`) and enforces TypeScript `private` keyword usage.
22
22
  *
23
23
  * @remarks
24
- * 규칙은 다음을 검사한다:
25
- * - 클래스 필드 선언: `#field`
26
- * - 클래스 메서드 선언: `#method()`
27
- * - 클래스 접근자 선언: `accessor #field`
28
- * - 멤버 접근 표현식: `this.#field`
24
+ * This rule checks:
25
+ * - Class field declarations: `#field`
26
+ * - Class method declarations: `#method()`
27
+ * - Class accessor declarations: `accessor #field`
28
+ * - Member access expressions: `this.#field`
29
29
  */
30
30
  export default createRule({
31
31
  name: "no-hard-private",
32
32
  meta: {
33
33
  type: "problem",
34
34
  docs: {
35
- description: '하드 프라이빗 필드(#) 대신 TypeScript "private _" 스타일을 강제한다.',
35
+ description: 'Enforces TypeScript "private _" style instead of hard private fields (#).',
36
36
  },
37
37
  messages: {
38
38
  preferSoftPrivate:
39
- '하드 프라이빗 필드(#) 허용되지 않습니다. "private _" 스타일을 사용하세요.',
39
+ 'Hard private fields (#) are not allowed. Use the "private _" style instead.',
40
40
  nameConflict:
41
- '하드 프라이빗 필드 "#{{name}}" "_{{name}}"으로 변환할 없습니다. 동일한 이름의 멤버가 이미 존재합니다.',
41
+ 'Cannot convert hard private field "#{{name}}" to "_{{name}}". A member with the same name already exists.',
42
42
  },
43
43
  fixable: "code",
44
44
  schema: [],
@@ -46,11 +46,11 @@ export default createRule({
46
46
  defaultOptions: [],
47
47
  create(context) {
48
48
  const sourceCode = context.sourceCode;
49
- // 중첩 클래스 지원을 위한 스택 구조
49
+ // Stack structure for supporting nested classes
50
50
  const classStack: Set<string>[] = [];
51
51
 
52
52
  return {
53
- // 0. 클래스 진입 멤버 이름 수집
53
+ // 0. Collect member names when entering a class
54
54
  "ClassBody"(node: TSESTree.ClassBody) {
55
55
  const memberNames = new Set<string>();
56
56
  for (const member of node.body) {
@@ -67,7 +67,7 @@ export default createRule({
67
67
  classStack.pop();
68
68
  },
69
69
 
70
- // 1. 선언부 감지 (PropertyDefinition, MethodDefinition, AccessorProperty)
70
+ // 1. Detect declarations (PropertyDefinition, MethodDefinition, AccessorProperty)
71
71
  "PropertyDefinition > PrivateIdentifier, MethodDefinition > PrivateIdentifier, AccessorProperty > PrivateIdentifier"(
72
72
  node: TSESTree.PrivateIdentifier,
73
73
  ) {
@@ -76,11 +76,11 @@ export default createRule({
76
76
  return;
77
77
  }
78
78
 
79
- const identifierName = node.name; // '#' 제외한 이름
79
+ const identifierName = node.name; // Name without the '#' character
80
80
  const targetName = `_${identifierName}`;
81
81
  const currentClassMembers = classStack.at(-1);
82
82
 
83
- // 이름 충돌 검사
83
+ // Check for name conflicts
84
84
  if (currentClassMembers?.has(targetName)) {
85
85
  context.report({
86
86
  node,
@@ -96,25 +96,25 @@ export default createRule({
96
96
  fix(fixer) {
97
97
  const fixes: RuleFix[] = [];
98
98
 
99
- // 1-1. 이름 변경 (#a -> _a)
99
+ // 1-1. Rename (#a -> _a)
100
100
  fixes.push(fixer.replaceText(node, targetName));
101
101
 
102
- // 1-2. 'private' 접근 제어자 추가 위치 계산
102
+ // 1-2. Calculate the position to add the 'private' access modifier
103
103
  if (parent.accessibility == null) {
104
- // 기본 삽입 위치: 부모 노드의 시작 지점 (static, async 등 포함)
104
+ // Default insertion position: beginning of parent node (including static, async, etc)
105
105
  let tokenToInsertBefore = sourceCode.getFirstToken(parent);
106
106
 
107
- // 데코레이터가 있다면, 마지막 데코레이터 '다음' 토큰 앞에 삽입
107
+ // If decorators exist, insert before the token after the last decorator
108
108
  // (@Deco private static _foo)
109
109
  if (parent.decorators.length > 0) {
110
110
  const lastDecorator = parent.decorators.at(-1)!;
111
111
  tokenToInsertBefore = sourceCode.getTokenAfter(lastDecorator);
112
112
  }
113
113
 
114
- // tokenToInsertBefore 이제 'static', 'async', 'readonly' 또는 변수명('_foo')입니다.
115
- // 앞에 'private ' 붙이면 자연스럽게 'private static ...' 순서가 됩니다.
116
- // tokenToInsertBefore null 경우는 AST 파싱 오류 예외 상황이므로,
117
- // 이름만 변경되는 불완전한 fix 방지하기 위해 전체 fix 생략한다.
114
+ // tokenToInsertBefore is now 'static', 'async', 'readonly', or a variable name ('_foo').
115
+ // Inserting 'private ' before it naturally results in the correct order 'private static ...'.
116
+ // If tokenToInsertBefore is null, it indicates an exceptional situation such as an AST parsing error.
117
+ // In such cases, skip the entire fix to prevent an incomplete fix that only renames.
118
118
  if (tokenToInsertBefore == null) {
119
119
  return [];
120
120
  }
@@ -126,7 +126,7 @@ export default createRule({
126
126
  });
127
127
  },
128
128
 
129
- // 2. 사용부 감지 (this.#field)
129
+ // 2. Detect usage (this.#field)
130
130
  "MemberExpression > PrivateIdentifier"(node: TSESTree.PrivateIdentifier) {
131
131
  const identifierName = node.name;
132
132
  context.report({
@@ -2,13 +2,13 @@ import { AST_NODE_TYPES, TSESTree } from "@typescript-eslint/utils";
2
2
  import { createRule } from "../utils/create-rule";
3
3
 
4
4
  /**
5
- * `@simplysm/*` 패키지에서 'src' 서브경로 import를 금지하는 ESLint 규칙
5
+ * ESLint rule that prohibits 'src' subpath imports from `@simplysm/*` packages.
6
6
  *
7
7
  * @remarks
8
- * 규칙은 다음을 검사한다:
9
- * - 정적 import 문: `import ... from '...'`
10
- * - 동적 import: `import('...')`
11
- * - re-export 문: `export { ... } from '...'`, `export * from '...'`
8
+ * This rule checks:
9
+ * - Static import statements: `import ... from '...'`
10
+ * - Dynamic imports: `import('...')`
11
+ * - Re-export statements: `export { ... } from '...'`, `export * from '...'`
12
12
  */
13
13
  export default createRule({
14
14
  name: "no-subpath-imports-from-simplysm",
@@ -16,13 +16,13 @@ export default createRule({
16
16
  type: "problem",
17
17
  docs: {
18
18
  description:
19
- "@simplysm 패키지에서 'src' 서브경로 import를 금지한다. (ex: @simplysm/pkg/src/x → 금지)",
19
+ "Prohibits 'src' subpath imports from @simplysm packages. (e.g., @simplysm/pkg/src/x → prohibited)",
20
20
  },
21
21
  fixable: "code",
22
22
  schema: [],
23
23
  messages: {
24
24
  noSubpathImport:
25
- "'@simplysm/{{pkg}}' 패키지는 'src' 서브경로를 import할 수 없습니다: '{{importPath}}'",
25
+ "Cannot import 'src' subpath from '@simplysm/{{pkg}}' package: '{{importPath}}'",
26
26
  },
27
27
  },
28
28
  defaultOptions: [],
@@ -32,8 +32,8 @@ export default createRule({
32
32
 
33
33
  const parts = importPath.split("/");
34
34
 
35
- // 허용: @simplysm/pkg, @simplysm/pkg/xxx, @simplysm/pkg/xxx/yyy
36
- // 금지: @simplysm/pkg/src, @simplysm/pkg/src/xxx
35
+ // Allowed: @simplysm/pkg, @simplysm/pkg/xxx, @simplysm/pkg/xxx/yyy
36
+ // Prohibited: @simplysm/pkg/src, @simplysm/pkg/src/xxx
37
37
  if (parts.length >= 3 && parts[2] === "src") {
38
38
  const fixedPath = `@simplysm/${parts[1]}`;
39
39
  context.report({
@@ -52,12 +52,12 @@ export default createRule({
52
52
  }
53
53
 
54
54
  return {
55
- // 정적 import: import { x } from '...'
55
+ // Static import: import { x } from '...'
56
56
  ImportDeclaration(node) {
57
57
  checkAndReport(node.source, node.source.value);
58
58
  },
59
59
 
60
- // 동적 import: import('...')
60
+ // Dynamic import: import('...')
61
61
  ImportExpression(node) {
62
62
  if (node.source.type !== AST_NODE_TYPES.Literal) return;
63
63
  const importPath = node.source.value;
@@ -65,13 +65,13 @@ export default createRule({
65
65
  checkAndReport(node.source, importPath);
66
66
  },
67
67
 
68
- // re-export: export { x } from '...'
68
+ // Re-export: export { x } from '...'
69
69
  ExportNamedDeclaration(node) {
70
70
  if (!node.source) return;
71
71
  checkAndReport(node.source, node.source.value);
72
72
  },
73
73
 
74
- // re-export all: export * from '...'
74
+ // Re-export all: export * from '...'
75
75
  ExportAllDeclaration(node) {
76
76
  checkAndReport(node.source, node.source.value);
77
77
  },
@@ -2,25 +2,25 @@ import { AST_NODE_TYPES, ASTUtils, type TSESTree } from "@typescript-eslint/util
2
2
  import { createRule } from "../utils/create-rule";
3
3
 
4
4
  /**
5
- * `@simplysm/core-common`의 `NotImplementedError` 사용을 감지하여 경고하는 ESLint 규칙
5
+ * ESLint rule that detects and warns about the use of `NotImplementedError` from `@simplysm/core-common`.
6
6
  *
7
7
  * @remarks
8
- * 규칙은 `@simplysm/core-common`에서 import된 `NotImplementedError`를 `new`로 생성하는 코드를 감지한다.
9
- * 미구현 코드가 프로덕션에 포함되는 것을 방지한다.
8
+ * This rule detects code that instantiates `NotImplementedError` imported from `@simplysm/core-common` using `new`.
9
+ * It prevents unimplemented code from being included in production.
10
10
  *
11
- * 지원하는 import 형태:
11
+ * Supported import forms:
12
12
  * - named import: `import { NotImplementedError } from "@simplysm/core-common"`
13
13
  * - aliased import: `import { NotImplementedError as NIE } from "@simplysm/core-common"`
14
14
  * - namespace import: `import * as CC from "@simplysm/core-common"` → `new CC.NotImplementedError()`
15
15
  *
16
- * 동적 import(`await import(...)`) 감지하지 않는다.
16
+ * Dynamic imports (`await import(...)`) are not detected.
17
17
  */
18
18
  export default createRule({
19
19
  name: "ts-no-throw-not-implemented-error",
20
20
  meta: {
21
21
  type: "suggestion",
22
22
  docs: {
23
- description: "'NotImplementedError' 사용 경고",
23
+ description: "Warns about 'NotImplementedError' usage",
24
24
  },
25
25
  schema: [],
26
26
  messages: {
@@ -30,10 +30,10 @@ export default createRule({
30
30
  defaultOptions: [],
31
31
  create(context) {
32
32
  /**
33
- * identifier @simplysm/core-common에서 import된 것인지 확인
34
- * @param identifier - 확인할 identifier
35
- * @param expectedImportedName - named import인 경우 확인할 원본 이름 (namespace import는 undefined)
36
- * @returns import 출처가 @simplysm/core-common이면 true, 아니면 false
33
+ * Checks if an identifier is imported from @simplysm/core-common.
34
+ * @param identifier - The identifier to check
35
+ * @param expectedImportedName - The original name to check for named imports (undefined for namespace imports)
36
+ * @returns true if the import source is @simplysm/core-common, false otherwise
37
37
  */
38
38
  function isImportedFromSimplysm(
39
39
  identifier: TSESTree.Identifier,
@@ -48,7 +48,7 @@ export default createRule({
48
48
  if (def.parent.type !== AST_NODE_TYPES.ImportDeclaration) continue;
49
49
  if (def.parent.source.value !== "@simplysm/core-common") continue;
50
50
 
51
- // named/aliased import: import { NotImplementedError } 또는 import { NotImplementedError as NIE }
51
+ // named/aliased import: import { NotImplementedError } or import { NotImplementedError as NIE }
52
52
  if (def.node.type === AST_NODE_TYPES.ImportSpecifier && expectedImportedName != null) {
53
53
  const imported = def.node.imported;
54
54
  if (
@@ -75,7 +75,7 @@ export default createRule({
75
75
  NewExpression(node: TSESTree.NewExpression) {
76
76
  let shouldReport = false;
77
77
 
78
- // Case 1: new NotImplementedError() 또는 new NIE() (named/aliased import)
78
+ // Case 1: new NotImplementedError() or new NIE() (named/aliased import)
79
79
  if (node.callee.type === AST_NODE_TYPES.Identifier) {
80
80
  shouldReport = isImportedFromSimplysm(node.callee, "NotImplementedError");
81
81
  }
@@ -92,7 +92,7 @@ export default createRule({
92
92
 
93
93
  if (!shouldReport) return;
94
94
 
95
- let msg = "미구현";
95
+ let msg = "Not implemented";
96
96
  const firstArg = node.arguments.at(0);
97
97
  if (
98
98
  firstArg?.type === AST_NODE_TYPES.Literal &&
@@ -2,7 +2,7 @@ export default {
2
2
  extends: ["stylelint-config-standard", "stylelint-config-tailwindcss"],
3
3
  plugins: ["stylelint-no-unsupported-browser-features", "stylelint-no-unresolved-module"],
4
4
  rules: {
5
- // Chrome 84+ 호환성 체크
5
+ // Chrome 84+ compatibility check
6
6
  "plugin/no-unsupported-browser-features": [
7
7
  true,
8
8
  {
@@ -11,9 +11,9 @@ export default {
11
11
  ignore: ["css-cascade-layers", "css-nesting", "css-overflow"],
12
12
  },
13
13
  ],
14
- // inset Chrome 87+이므로 shorthand 강제 비활성화
14
+ // inset requires Chrome 87+, so enforce shorthand is disabled
15
15
  "declaration-block-no-redundant-longhand-properties": [true, { ignoreShorthands: ["inset"] }],
16
- // @import, url() 파일 존재 체크
16
+ // Check for file existence in @import and url()
17
17
  "plugin/no-unresolved-module": true,
18
18
  },
19
19
  };
@@ -1,11 +1,11 @@
1
1
  import { ESLintUtils } from "@typescript-eslint/utils";
2
2
 
3
3
  /**
4
- * ESLint 규칙을 생성하는 팩토리 함수
4
+ * Factory function to create ESLint rules.
5
5
  *
6
6
  * @remarks
7
- * `@typescript-eslint/utils`의 `RuleCreator`를 래핑하여
8
- * 규칙 문서 URL을 자동으로 생성한다.
7
+ * Wraps `RuleCreator` from `@typescript-eslint/utils` and
8
+ * automatically generates rule documentation URLs.
9
9
  *
10
10
  * @example
11
11
  * ```typescript