@simplysm/lint 13.0.96 → 13.0.98

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.
Files changed (2) hide show
  1. package/README.md +70 -236
  2. package/package.json +4 -4
package/README.md CHANGED
@@ -1,290 +1,124 @@
1
1
  # @simplysm/lint
2
2
 
3
- Simplysm 프로젝트용 ESLint 설정과 커스텀 규칙 패키지. ESLint v9 flat config 기반.
3
+ Lint configuration (ESLint) -- ESLint plugin with custom rules and a recommended flat config for Simplysm projects.
4
4
 
5
- ## 설치
5
+ ## Installation
6
6
 
7
7
  ```bash
8
- pnpm add @simplysm/lint
8
+ npm install @simplysm/lint
9
9
  ```
10
10
 
11
- ## 엔트리포인트
11
+ This package has two entrypoints:
12
12
 
13
- | Export 경로 | 설명 |
14
- |---|---|
15
- | `@simplysm/lint/eslint-recommended` | 권장 ESLint flat config 배열 (규칙 프리셋) |
16
- | `@simplysm/lint/eslint-plugin` | 커스텀 ESLint 플러그인 (`@simplysm/*` 규칙) |
13
+ - `@simplysm/lint/eslint-plugin` -- ESLint plugin exporting custom rules.
14
+ - `@simplysm/lint/eslint-recommended` -- Ready-to-use flat config with all recommended rules.
17
15
 
18
- ## 사용법
16
+ ## API Overview
19
17
 
20
- ### 권장 설정 적용 (eslint-recommended)
18
+ ### ESLint Plugin (`@simplysm/lint/eslint-plugin`)
21
19
 
22
- 프로젝트의 `eslint.config.js`에서 가져와 사용한다.
20
+ | API | Type | Description |
21
+ |-----|------|-------------|
22
+ | `default` | ESLint plugin | Plugin object with `rules` property |
23
23
 
24
- ```typescript
25
- // eslint.config.js
26
- import eslintRecommended from "@simplysm/lint/eslint-recommended";
24
+ ### Rules
27
25
 
28
- export default [
29
- ...eslintRecommended,
30
- // 추가 설정 오버라이드
31
- ];
32
- ```
26
+ | Rule | Type | Description |
27
+ |------|------|-------------|
28
+ | `no-hard-private` | problem (fixable) | Enforces TypeScript `private _` style instead of hard private fields (`#`) |
29
+ | `no-subpath-imports-from-simplysm` | problem (fixable) | Prohibits `src` subpath imports from `@simplysm/*` packages |
30
+ | `ts-no-throw-not-implemented-error` | suggestion | Warns about `NotImplementedError` usage from `@simplysm/core-common` |
33
31
 
34
- 설정에는 아래의 모든 규칙이 사전 구성되어 있으므로 별도로 플러그인을 등록할 필요가 없다.
32
+ ### ESLint Recommended Config (`@simplysm/lint/eslint-recommended`)
35
33
 
36
- ### 플러그인 단독 사용 (eslint-plugin)
34
+ | API | Type | Description |
35
+ |-----|------|-------------|
36
+ | `default` | flat config array | Complete ESLint flat config with JS/TS, SolidJS, and Tailwind CSS rules |
37
37
 
38
- 커스텀 규칙만 개별적으로 사용하려면 플러그인을 직접 등록한다.
38
+ ### Utils
39
39
 
40
- ```typescript
41
- import plugin from "@simplysm/lint/eslint-plugin";
40
+ | API | Type | Description |
41
+ |-----|------|-------------|
42
+ | `createRule` | function | Factory function to create ESLint rules (wraps `@typescript-eslint/utils` `RuleCreator`) |
42
43
 
43
- export default [
44
- {
45
- plugins: {
46
- "@simplysm": plugin,
47
- },
48
- rules: {
49
- "@simplysm/no-hard-private": "error",
50
- "@simplysm/no-subpath-imports-from-simplysm": "error",
51
- "@simplysm/ts-no-throw-not-implemented-error": "warn",
52
- },
53
- },
54
- ];
55
- ```
56
-
57
- ## 권장 설정 구성 (eslint-recommended)
58
-
59
- `eslint-recommended`는 `defineConfig()`으로 구성된 flat config 배열이다. 파일 타입별로 다른 규칙 세트가 적용된다.
60
-
61
- ### 글로벌 무시 패턴
62
-
63
- ```
64
- **/node_modules/**, **/dist/**, **/.*/**, **/_*/**
65
- ```
66
-
67
- ### 공통 규칙 (JS/TS 모두 적용)
68
-
69
- | 규칙 | 수준 | 설명 |
70
- |---|---|---|
71
- | `no-console` | error | `console.*` 사용 금지 |
72
- | `no-warning-comments` | warn | TODO/FIXME 주석 경고 |
73
- | `eqeqeq` | error | `===` 강제 (`== null`만 허용) |
74
- | `no-self-compare` | error | 자기 자신과의 비교 방지 |
75
- | `array-callback-return` | error | map/filter 콜백에서 return 누락 방지 |
76
-
77
- ### Node 빌트인 제한 규칙
78
-
79
- | 규칙 | 대상 | 대안 |
80
- |---|---|---|
81
- | `Buffer` 전역 변수 | `no-restricted-globals` | `Uint8Array` 또는 `BytesUtils` 사용 |
82
- | `buffer` 모듈 import | `no-restricted-imports` | `Uint8Array` 또는 `BytesUtils` 사용 |
83
- | `events` 모듈 import | `no-restricted-imports` | `@simplysm/core-common`의 `EventEmitter` 사용 |
84
- | `eventemitter3` import | `no-restricted-imports` | `@simplysm/core-common`의 `EventEmitter` 사용 |
85
-
86
- ### JS 전용 규칙 (*.js, *.jsx)
87
-
88
- 공통 규칙에 추가로 `require-await`, `no-shadow`, `no-duplicate-imports`, `no-unused-expressions`, `no-undef`가 적용된다.
89
-
90
- ### TypeScript 전용 규칙 (*.ts, *.tsx)
91
-
92
- 공통 규칙에 추가로 TypeScript 전용 규칙이 적용된다. `typescript-eslint` 파서를 사용하며 프로젝트 타입 정보가 필요하다 (`project: true`).
93
-
94
- | 규칙 | 수준 | 설명 |
95
- |---|---|---|
96
- | `@typescript-eslint/require-await` | error | async 함수에 await 필수 |
97
- | `@typescript-eslint/await-thenable` | error | thenable이 아닌 값에 await 금지 |
98
- | `@typescript-eslint/return-await` | error | try-catch 내에서만 return await 허용 |
99
- | `@typescript-eslint/no-floating-promises` | error | Promise를 반드시 await 또는 void 처리 |
100
- | `@typescript-eslint/no-shadow` | error | 변수 섀도잉 금지 |
101
- | `@typescript-eslint/no-unnecessary-condition` | error | 불필요한 조건 검사 금지 (상수 루프 허용) |
102
- | `@typescript-eslint/no-unnecessary-type-assertion` | error | 불필요한 타입 단언 금지 |
103
- | `@typescript-eslint/prefer-reduce-type-parameter` | error | reduce 타입 파라미터 사용 권장 |
104
- | `@typescript-eslint/prefer-return-this-type` | error | this 반환 타입 사용 권장 |
105
- | `@typescript-eslint/no-unused-expressions` | error | 미사용 표현식 금지 |
106
- | `@typescript-eslint/strict-boolean-expressions` | error | 엄격한 boolean 표현식 (nullable boolean/object 허용) |
107
- | `@typescript-eslint/ban-ts-comment` | error | `@ts-expect-error`만 설명 포함 시 허용 |
108
- | `@typescript-eslint/prefer-readonly` | error | 재할당하지 않는 속성에 readonly 강제 |
109
- | `@typescript-eslint/no-misused-promises` | error | void 콜백에 async 함수 전달 방지 (arguments/attributes 제외) |
110
- | `@typescript-eslint/only-throw-error` | error | Error 객체만 throw 허용 |
111
- | `@typescript-eslint/no-array-delete` | error | 배열에 delete 사용 금지 |
112
-
113
- ### 미사용 import 규칙
114
-
115
- | 규칙 | 수준 | 설명 |
116
- |---|---|---|
117
- | `unused-imports/no-unused-imports` | error | 미사용 import 자동 제거 |
118
- | `unused-imports/no-unused-vars` | error | 미사용 변수 금지 (`_` 접두사 허용) |
119
-
120
- ### SolidJS 규칙 (*.ts, *.tsx)
121
-
122
- | 규칙 | 수준 | 설명 |
123
- |---|---|---|
124
- | `solid/no-destructure` | error | Props 구조분해 금지 (반응성 손실 방지) |
125
- | `solid/components-return-once` | error | 컴포넌트 단일 반환 강제 |
126
- | `solid/jsx-no-duplicate-props` | error | 중복 props 금지 |
127
- | `solid/jsx-no-undef` | error | 미정의 변수 참조 금지 (TS 지원) |
128
- | `solid/no-react-deps` | error | React 의존성 배열 패턴 금지 |
129
- | `solid/no-react-specific-props` | error | React 전용 props 금지 (className 등) |
130
- | `solid/no-innerhtml` | error | innerHTML 사용 금지 (XSS 방지) |
131
- | `solid/jsx-no-script-url` | error | `javascript:` URL 금지 |
132
- | `solid/jsx-uses-vars` | error | JSX 변수 사용 추적 |
133
- | `solid/prefer-for` | error | `.map()` 대신 `<For>` 컴포넌트 사용 |
134
- | `solid/event-handlers` | error | 이벤트 핸들러 네이밍 규칙 |
135
- | `solid/imports` | error | import 일관성 |
136
- | `solid/style-prop` | error | style prop 형식 |
137
- | `solid/self-closing-comp` | error | 셀프 클로징 태그 |
138
-
139
- ### Tailwind CSS 규칙 (*.ts, *.tsx)
140
-
141
- `clsx` 템플릿 리터럴 태그를 지원한다.
142
-
143
- | 규칙 | 수준 | 설명 |
144
- |---|---|---|
145
- | `tailwindcss/classnames-order` | warn | 클래스 순서 자동 정렬 |
146
- | `tailwindcss/enforces-negative-arbitrary-values` | error | 음수 임의 값 형식 통일 |
147
- | `tailwindcss/enforces-shorthand` | error | 축약형 사용 권장 |
148
- | `tailwindcss/no-contradicting-classname` | error | 충돌 클래스 금지 (`p-2 p-4` 등) |
149
- | `tailwindcss/no-custom-classname` | error | Tailwind 외 커스텀 클래스 금지 |
150
- | `tailwindcss/no-unnecessary-arbitrary-value` | error | 불필요한 임의 값 금지 |
151
-
152
- ### 테스트 파일 오버라이드
153
-
154
- `**/tests/**`, `**/tests-e2e/**` 경로의 파일에는 다음 규칙이 완화된다:
155
-
156
- - `no-console`: off
157
- - `import/no-extraneous-dependencies`: off
158
- - `@simplysm/ts-no-throw-not-implemented-error`: off
159
-
160
- ## 커스텀 규칙 상세
161
-
162
- ### @simplysm/no-hard-private
163
-
164
- ECMAScript `#private` 필드/메서드 대신 TypeScript `private _` 키워드 사용을 강제한다.
165
-
166
- - **타입**: problem
167
- - **자동 수정**: 지원 (fixable)
168
- - **적용 대상**: JS, TS 모두
169
-
170
- **감지 범위:**
171
- - 클래스 필드 선언: `#field`
172
- - 클래스 메서드 선언: `#method()`
173
- - 클래스 접근자 선언: `accessor #field`
174
- - 멤버 접근 표현식: `this.#field`
175
- - 중첩 클래스 지원 (스택 구조)
176
-
177
- **자동 수정 동작:**
178
- 1. `#name` -> `_name`으로 이름 변경
179
- 2. `private` 접근 제한자가 없으면 자동 추가
180
- 3. 데코레이터가 있으면 데코레이터 뒤에 `private` 삽입
181
- 4. 동일 이름의 멤버가 이미 존재하면 충돌 에러 보고 (수정 불가)
44
+ ## `createRule`
182
45
 
183
46
  ```typescript
184
- // Bad
185
- class Foo {
186
- #bar = 1;
187
- #baz() { return this.#bar; }
188
- }
189
-
190
- // Good
191
- class Foo {
192
- private _bar = 1;
193
- private _baz() { return this._bar; }
194
- }
47
+ const createRule: ReturnType<typeof ESLintUtils.RuleCreator>;
195
48
  ```
196
49
 
197
- **메시지:**
198
- - `preferSoftPrivate`: `Hard private fields (#) are not allowed. Use the "private _" style instead.`
199
- - `nameConflict`: `Cannot convert hard private field "#name" to "_name". A member with the same name already exists.`
50
+ Factory function wrapping `RuleCreator` from `@typescript-eslint/utils`. Automatically generates rule documentation URLs.
200
51
 
201
- ### @simplysm/no-subpath-imports-from-simplysm
52
+ ## Rule Details
202
53
 
203
- `@simplysm/*` 패키지의 `src/` 서브경로 import를 금지한다.
54
+ ### `no-hard-private`
204
55
 
205
- - **타입**: problem
206
- - **자동 수정**: 지원 (fixable)
207
- - **적용 대상**: JS, TS 모두
56
+ Restricts ECMAScript private fields (`#field`) and enforces TypeScript `private` keyword usage. Auto-fixable: renames `#field` to `private _field` and `this.#field` to `this._field`.
208
57
 
209
- **감지 범위:**
210
- - 정적 import: `import { x } from "@simplysm/pkg/src/..."`
211
- - 동적 import: `import("@simplysm/pkg/src/...")`
212
- - named re-export: `export { x } from "@simplysm/pkg/src/..."`
213
- - 전체 re-export: `export * from "@simplysm/pkg/src/..."`
58
+ ### `no-subpath-imports-from-simplysm`
214
59
 
215
- **자동 수정 동작:**
216
- - `@simplysm/pkg/src/...` -> `@simplysm/pkg`로 경로 축약
60
+ Prohibits `src` subpath imports from `@simplysm/*` packages (e.g., `@simplysm/pkg/src/x` is prohibited). Auto-fixable: rewrites to `@simplysm/pkg`.
217
61
 
218
- ```typescript
219
- // Bad
220
- import { foo } from "@simplysm/core-common/src/utils/obj";
221
- export { bar } from "@simplysm/solid/src/controls";
62
+ ### `ts-no-throw-not-implemented-error`
222
63
 
223
- // Good
224
- import { foo } from "@simplysm/core-common";
225
- export { bar } from "@simplysm/solid";
226
- ```
64
+ Detects and warns about `new NotImplementedError()` usage from `@simplysm/core-common`. Supports named imports, aliased imports, and namespace imports. Helps prevent unimplemented code from reaching production.
227
65
 
228
- ### @simplysm/ts-no-throw-not-implemented-error
66
+ ## Recommended Config Details
229
67
 
230
- `@simplysm/core-common`의 `NotImplementedError` 사용을 경고한다. 프로덕션 코드에서 미구현 부분을 감지하기 위한 규칙.
68
+ The recommended config (`@simplysm/lint/eslint-recommended`) includes:
231
69
 
232
- - **타입**: suggestion
233
- - **자동 수정**: 미지원
234
- - **적용 대상**: TS 전용 (타입 분석 필요)
235
- - **기본 수준**: warn (테스트 파일에서는 off)
70
+ - **JS/TS common rules**: `no-console`, `eqeqeq`, `no-self-compare`, `array-callback-return`
71
+ - **TypeScript rules**: `require-await`, `no-floating-promises`, `strict-boolean-expressions`, `no-unnecessary-condition`, `prefer-readonly`, and more
72
+ - **Import rules**: `no-extraneous-dependencies`, unused import auto-removal
73
+ - **Node built-in restrictions**: Prohibits `Buffer` (use `Uint8Array`) and `events` (use `@simplysm/core-common` `EventEmitter`)
74
+ - **SolidJS rules**: `no-destructure`, `components-return-once`, `prefer-for`, `no-react-specific-props`
75
+ - **Tailwind CSS rules**: `classnames-order`, `no-contradicting-classname`, `enforces-shorthand`
236
76
 
237
- **감지 범위:**
238
- - named import: `import { NotImplementedError } from "@simplysm/core-common"`
239
- - aliased import: `import { NotImplementedError as NIE } from "@simplysm/core-common"`
240
- - namespace import: `import * as CC from "@simplysm/core-common"` -> `new CC.NotImplementedError()`
241
- - 동적 import (`await import(...)`)는 감지하지 않음
77
+ ## Usage Examples
242
78
 
243
- **보고 메시지:**
244
- - 첫 번째 인자가 문자열이면 해당 문자열을 메시지로 표시
245
- - 인자가 없으면 `"Not implemented"` 표시
79
+ ### Use recommended config
246
80
 
247
81
  ```typescript
248
- // Warning: "TODO: 나중에 구현"
249
- throw new NotImplementedError("TODO: 나중에 구현");
82
+ // eslint.config.ts
83
+ import recommended from "@simplysm/lint/eslint-recommended";
250
84
 
251
- // Warning: "Not implemented"
252
- throw new NotImplementedError();
85
+ export default recommended;
253
86
  ```
254
87
 
255
- ## 유틸리티
88
+ ### Use plugin rules individually
256
89
 
257
- ### createRule
90
+ ```typescript
91
+ // eslint.config.ts
92
+ import plugin from "@simplysm/lint/eslint-plugin";
93
+
94
+ export default [
95
+ {
96
+ plugins: { "@simplysm": plugin },
97
+ rules: {
98
+ "@simplysm/no-hard-private": "error",
99
+ "@simplysm/no-subpath-imports-from-simplysm": "error",
100
+ "@simplysm/ts-no-throw-not-implemented-error": "warn",
101
+ },
102
+ },
103
+ ];
104
+ ```
258
105
 
259
- `@typescript-eslint/utils`의 `RuleCreator`를 래핑한 팩토리 함수. 커스텀 규칙 작성 시 사용한다.
106
+ ### Create a custom rule with `createRule`
260
107
 
261
108
  ```typescript
262
- import { createRule } from "../utils/create-rule";
109
+ import { createRule } from "@simplysm/lint/eslint-plugin";
263
110
 
264
111
  export default createRule({
265
- name: "my-rule",
112
+ name: "my-custom-rule",
266
113
  meta: {
267
114
  type: "problem",
268
- docs: { description: "규칙 설명" },
269
- messages: { errorId: "에러 메시지" },
115
+ docs: { description: "My custom rule" },
270
116
  schema: [],
117
+ messages: { myMessage: "Something is wrong" },
271
118
  },
272
119
  defaultOptions: [],
273
120
  create(context) {
274
- return {
275
- // AST visitor
276
- };
121
+ return {};
277
122
  },
278
123
  });
279
124
  ```
280
-
281
- ## 의존성
282
-
283
- - `eslint` v9+
284
- - `typescript-eslint` v8+
285
- - `eslint-plugin-import` - import/export 규칙
286
- - `eslint-plugin-unused-imports` - 미사용 import 자동 제거
287
- - `eslint-plugin-solid` - SolidJS 규칙
288
- - `eslint-plugin-tailwindcss` - Tailwind CSS 규칙
289
- - `eslint-import-resolver-typescript` - TypeScript 경로 해석
290
- - `globals` - 글로벌 변수 정의 (node, browser, es2024)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@simplysm/lint",
3
- "version": "13.0.96",
3
+ "version": "13.0.98",
4
4
  "description": "Simplysm package - Lint configuration (ESLint)",
5
5
  "author": "simplysm",
6
6
  "license": "Apache-2.0",
@@ -27,7 +27,7 @@
27
27
  }
28
28
  },
29
29
  "dependencies": {
30
- "@typescript-eslint/utils": "^8.57.0",
30
+ "@typescript-eslint/utils": "^8.57.1",
31
31
  "eslint": "^9.39.4",
32
32
  "eslint-import-resolver-typescript": "^4.4.4",
33
33
  "eslint-plugin-import": "^2.32.0",
@@ -36,10 +36,10 @@
36
36
  "eslint-plugin-unused-imports": "^4.4.1",
37
37
  "globals": "^17.4.0",
38
38
  "typescript": "^5.9.3",
39
- "typescript-eslint": "^8.57.0"
39
+ "typescript-eslint": "^8.57.1"
40
40
  },
41
41
  "devDependencies": {
42
42
  "@types/eslint-plugin-tailwindcss": "^3.17.0",
43
- "@typescript-eslint/rule-tester": "^8.57.0"
43
+ "@typescript-eslint/rule-tester": "^8.57.1"
44
44
  }
45
45
  }