@simplysm/lint 13.0.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.
Files changed (37) hide show
  1. package/README.md +522 -0
  2. package/dist/eslint-plugin.d.ts +15 -0
  3. package/dist/eslint-plugin.d.ts.map +1 -0
  4. package/dist/eslint-plugin.js +14 -0
  5. package/dist/eslint-plugin.js.map +6 -0
  6. package/dist/eslint-recommended.d.ts +3 -0
  7. package/dist/eslint-recommended.d.ts.map +1 -0
  8. package/dist/eslint-recommended.js +259 -0
  9. package/dist/eslint-recommended.js.map +6 -0
  10. package/dist/rules/no-hard-private.d.ts +15 -0
  11. package/dist/rules/no-hard-private.d.ts.map +1 -0
  12. package/dist/rules/no-hard-private.js +95 -0
  13. package/dist/rules/no-hard-private.js.map +6 -0
  14. package/dist/rules/no-subpath-imports-from-simplysm.d.ts +14 -0
  15. package/dist/rules/no-subpath-imports-from-simplysm.d.ts.map +1 -0
  16. package/dist/rules/no-subpath-imports-from-simplysm.js +64 -0
  17. package/dist/rules/no-subpath-imports-from-simplysm.js.map +6 -0
  18. package/dist/rules/ts-no-throw-not-implemented-error.d.ts +19 -0
  19. package/dist/rules/ts-no-throw-not-implemented-error.d.ts.map +1 -0
  20. package/dist/rules/ts-no-throw-not-implemented-error.js +63 -0
  21. package/dist/rules/ts-no-throw-not-implemented-error.js.map +6 -0
  22. package/dist/stylelint-recommended.d.ts +13 -0
  23. package/dist/stylelint-recommended.d.ts.map +1 -0
  24. package/dist/stylelint-recommended.js +20 -0
  25. package/dist/stylelint-recommended.js.map +6 -0
  26. package/dist/utils/create-rule.d.ts +22 -0
  27. package/dist/utils/create-rule.d.ts.map +1 -0
  28. package/dist/utils/create-rule.js +8 -0
  29. package/dist/utils/create-rule.js.map +6 -0
  30. package/package.json +52 -0
  31. package/src/eslint-plugin.ts +11 -0
  32. package/src/eslint-recommended.ts +274 -0
  33. package/src/rules/no-hard-private.ts +136 -0
  34. package/src/rules/no-subpath-imports-from-simplysm.ts +78 -0
  35. package/src/rules/ts-no-throw-not-implemented-error.ts +103 -0
  36. package/src/stylelint-recommended.ts +16 -0
  37. package/src/utils/create-rule.ts +22 -0
@@ -0,0 +1,259 @@
1
+ import globals from "globals";
2
+ import tseslint, {} from "typescript-eslint";
3
+ import plugin from "./eslint-plugin.js";
4
+ import importPlugin from "eslint-plugin-import";
5
+ import unusedImportsPlugin from "eslint-plugin-unused-imports";
6
+ import solidPlugin from "eslint-plugin-solid";
7
+ import tailwindcssPlugin from "eslint-plugin-tailwindcss";
8
+ import { defineConfig, globalIgnores } from "eslint/config";
9
+ import { ESLint } from "eslint";
10
+ const commonRules = {
11
+ "no-console": "error",
12
+ "no-warning-comments": "warn",
13
+ "eqeqeq": ["error", "always", { null: "ignore" }],
14
+ "no-self-compare": "error",
15
+ "array-callback-return": "error"
16
+ };
17
+ const noNodeBuiltinsRules = {
18
+ "no-restricted-globals": [
19
+ "error",
20
+ {
21
+ name: "Buffer",
22
+ message: "Uint8Array\uB97C \uC0AC\uC6A9\uD558\uC138\uC694. \uBCF5\uC7A1\uD55C \uC5F0\uC0B0\uC740 @simplysm/core-common\uC758 BytesUtils\uB97C \uC0AC\uC6A9\uD558\uC138\uC694."
23
+ }
24
+ ],
25
+ "no-restricted-imports": [
26
+ "error",
27
+ {
28
+ paths: [
29
+ {
30
+ name: "buffer",
31
+ message: "Uint8Array\uB97C \uC0AC\uC6A9\uD558\uC138\uC694. \uBCF5\uC7A1\uD55C \uC5F0\uC0B0\uC740 @simplysm/core-common\uC758 BytesUtils\uB97C \uC0AC\uC6A9\uD558\uC138\uC694."
32
+ },
33
+ {
34
+ name: "events",
35
+ message: "@simplysm/core-common\uC758 SdEventEmitter\uB97C \uC0AC\uC6A9\uD558\uC138\uC694."
36
+ },
37
+ {
38
+ name: "eventemitter3",
39
+ message: "@simplysm/core-common\uC758 SdEventEmitter\uB97C \uC0AC\uC6A9\uD558\uC138\uC694."
40
+ }
41
+ ]
42
+ }
43
+ ]
44
+ };
45
+ const unusedImportsRules = {
46
+ "unused-imports/no-unused-imports": "error",
47
+ "unused-imports/no-unused-vars": [
48
+ "error",
49
+ {
50
+ vars: "all",
51
+ varsIgnorePattern: "^_",
52
+ args: "after-used",
53
+ argsIgnorePattern: "^_"
54
+ }
55
+ ]
56
+ };
57
+ var eslint_recommended_default = defineConfig([
58
+ globalIgnores([
59
+ // directory/** 형태로 순회 자체를 건너뜀
60
+ "**/node_modules/**",
61
+ "**/dist/**",
62
+ "**/.*/**",
63
+ "**/_*/**"
64
+ ]),
65
+ {
66
+ languageOptions: {
67
+ globals: {
68
+ ...globals.node,
69
+ ...globals.es2024,
70
+ ...globals.browser
71
+ },
72
+ ecmaVersion: 2024,
73
+ sourceType: "module"
74
+ }
75
+ },
76
+ {
77
+ files: ["**/*.js", "**/*.jsx"],
78
+ plugins: {
79
+ "import": importPlugin,
80
+ "@simplysm": plugin,
81
+ "unused-imports": unusedImportsPlugin
82
+ },
83
+ rules: {
84
+ ...commonRules,
85
+ "require-await": "error",
86
+ "no-shadow": "error",
87
+ "no-duplicate-imports": "error",
88
+ "no-unused-expressions": "error",
89
+ "no-undef": "error",
90
+ ...unusedImportsRules,
91
+ "import/no-extraneous-dependencies": [
92
+ "error",
93
+ {
94
+ devDependencies: ["**/lib/**", "**/eslint.config.js", "**/simplysm.js", "**/vitest.config.js"]
95
+ }
96
+ ],
97
+ // JS/TS 공통
98
+ "@simplysm/no-subpath-imports-from-simplysm": "error",
99
+ "@simplysm/no-hard-private": "error",
100
+ ...noNodeBuiltinsRules
101
+ }
102
+ },
103
+ {
104
+ files: ["**/*.ts", "**/*.tsx"],
105
+ plugins: {
106
+ "@typescript-eslint": tseslint.plugin,
107
+ "@simplysm": plugin,
108
+ "import": importPlugin,
109
+ "unused-imports": unusedImportsPlugin
110
+ },
111
+ languageOptions: {
112
+ parser: tseslint.parser,
113
+ parserOptions: {
114
+ project: true
115
+ }
116
+ },
117
+ rules: {
118
+ ...commonRules,
119
+ "@typescript-eslint/require-await": "error",
120
+ "@typescript-eslint/await-thenable": "error",
121
+ "@typescript-eslint/return-await": ["error", "in-try-catch"],
122
+ "@typescript-eslint/no-floating-promises": "error",
123
+ "@typescript-eslint/no-shadow": "error",
124
+ "@typescript-eslint/no-unnecessary-condition": ["error", { allowConstantLoopConditions: true }],
125
+ "@typescript-eslint/no-unnecessary-type-assertion": "error",
126
+ // "@typescript-eslint/non-nullable-type-assertion-style": "error",
127
+ "@typescript-eslint/prefer-reduce-type-parameter": "error",
128
+ "@typescript-eslint/prefer-return-this-type": "error",
129
+ "@typescript-eslint/no-unused-expressions": "error",
130
+ "@typescript-eslint/strict-boolean-expressions": [
131
+ "error",
132
+ {
133
+ allowNullableBoolean: true,
134
+ allowNullableObject: true
135
+ }
136
+ ],
137
+ "@typescript-eslint/ban-ts-comment": [
138
+ "error",
139
+ {
140
+ "ts-expect-error": "allow-with-description",
141
+ "minimumDescriptionLength": 3
142
+ }
143
+ ],
144
+ "@typescript-eslint/prefer-readonly": "error",
145
+ // 실수 방지: void 콜백에 async 함수 전달 (에러 누락 방지)
146
+ // - arguments: false → socket.on("event", async () => {}) 허용 (내부 try-catch로 처리)
147
+ // - attributes: false → JSX 이벤트 핸들러 허용 (SolidJS 호환)
148
+ "@typescript-eslint/no-misused-promises": [
149
+ "error",
150
+ { checksVoidReturn: { arguments: false, attributes: false } }
151
+ ],
152
+ // 실수 방지: Error 아닌 것을 throw (스택 트레이스 손실 방지)
153
+ "@typescript-eslint/only-throw-error": "error",
154
+ // 실수 방지: 배열에 delete 사용 (희소 배열 버그 방지)
155
+ "@typescript-eslint/no-array-delete": "error",
156
+ "@simplysm/no-hard-private": "error",
157
+ "@simplysm/no-subpath-imports-from-simplysm": "error",
158
+ "@simplysm/ts-no-throw-not-implemented-error": "warn",
159
+ ...unusedImportsRules,
160
+ ...noNodeBuiltinsRules,
161
+ "import/no-extraneous-dependencies": [
162
+ "error",
163
+ {
164
+ devDependencies: [
165
+ "**/lib/**",
166
+ "**/eslint.config.ts",
167
+ "**/simplysm.ts",
168
+ "**/vitest.config.ts",
169
+ "**/vitest.setup.ts"
170
+ ]
171
+ }
172
+ ]
173
+ }
174
+ },
175
+ // 테스트 폴더: 루트 devDependencies(vitest 등) 사용 허용
176
+ {
177
+ files: ["**/tests/**/*.ts", "**/tests/**/*.tsx"],
178
+ rules: {
179
+ "no-console": "off",
180
+ "import/no-extraneous-dependencies": "off",
181
+ "@simplysm/ts-no-throw-not-implemented-error": "off"
182
+ }
183
+ },
184
+ // SolidJS TSX 파일: 모든 규칙 명시적으로 설정 (error)
185
+ {
186
+ files: ["**/*.ts", "**/*.tsx"],
187
+ plugins: {
188
+ solid: solidPlugin,
189
+ tailwindcss: tailwindcssPlugin
190
+ },
191
+ settings: {
192
+ tailwindcss: {
193
+ // 템플릿 리터럴 태그 지원: clsx`py-0.5 px-1.5` 형태 인식
194
+ tags: ["clsx"]
195
+ }
196
+ },
197
+ rules: {
198
+ // ─── 실수 방지 ───
199
+ "solid/reactivity": ["error", { customReactiveFunctions: ["makePersisted"] }],
200
+ // 반응성 손실 (가장 중요!)
201
+ "solid/no-destructure": "error",
202
+ // props 구조분해 → 반응성 손실
203
+ "solid/components-return-once": "error",
204
+ // early return → 버그
205
+ "solid/jsx-no-duplicate-props": "error",
206
+ // 중복 props
207
+ "solid/jsx-no-undef": ["error", { typescriptEnabled: true }],
208
+ // 정의 안 된 변수
209
+ "solid/no-react-deps": "error",
210
+ // React 의존성 배열 실수
211
+ "solid/no-react-specific-props": "error",
212
+ // React props 실수 (className 등)
213
+ // ─── 보안 ───
214
+ "solid/no-innerhtml": "error",
215
+ // XSS 방지
216
+ "solid/jsx-no-script-url": "error",
217
+ // javascript: URL 방지
218
+ // ─── 도구 지원 ───
219
+ "solid/jsx-uses-vars": "error",
220
+ // unused import 오탐 방지
221
+ // ─── 컨벤션 ───
222
+ "solid/prefer-for": "error",
223
+ // For 컴포넌트 권장
224
+ "solid/event-handlers": "error",
225
+ // 이벤트 핸들러 네이밍
226
+ "solid/imports": "error",
227
+ // import 일관성
228
+ "solid/style-prop": "error",
229
+ // style prop 형식
230
+ "solid/self-closing-comp": "error",
231
+ // 자체 닫기 태그
232
+ // ─── Tailwind CSS ───
233
+ "tailwindcss/classnames-order": "warn",
234
+ // 클래스 순서 자동 정렬
235
+ "tailwindcss/enforces-negative-arbitrary-values": "error",
236
+ // 음수 임의값 형식 통일
237
+ "tailwindcss/enforces-shorthand": "error",
238
+ // 축약형 사용 권장
239
+ "tailwindcss/no-contradicting-classname": "error",
240
+ // 충돌하는 클래스 금지 (p-2 p-4 등)
241
+ "tailwindcss/no-custom-classname": "error",
242
+ // Tailwind에 없는 커스텀 클래스 금지
243
+ "tailwindcss/no-unnecessary-arbitrary-value": "error"
244
+ // 불필요한 임의값 금지
245
+ }
246
+ },
247
+ // 테스트 폴더: solid/reactivity 비활성화
248
+ {
249
+ files: ["**/tests/**/*.ts", "**/tests/**/*.tsx"],
250
+ rules: {
251
+ // 테스트에서는 waitFor 등 비동기 콜백 내 signal 접근이 의도된 동작
252
+ "solid/reactivity": "off"
253
+ }
254
+ }
255
+ ]);
256
+ export {
257
+ eslint_recommended_default as default
258
+ };
259
+ //# sourceMappingURL=eslint-recommended.js.map
@@ -0,0 +1,6 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/eslint-recommended.ts"],
4
+ "mappings": "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",
5
+ "names": []
6
+ }
@@ -0,0 +1,15 @@
1
+ /**
2
+ * ECMAScript private 필드(`#field`) 사용을 제한하고 TypeScript `private` 키워드 사용을 강제하는 ESLint 규칙
3
+ *
4
+ * @remarks
5
+ * 이 규칙은 다음을 검사한다:
6
+ * - 클래스 필드 선언: `#field`
7
+ * - 클래스 메서드 선언: `#method()`
8
+ * - 클래스 접근자 선언: `accessor #field`
9
+ * - 멤버 접근 표현식: `this.#field`
10
+ */
11
+ declare const _default: import("@typescript-eslint/utils/ts-eslint").RuleModule<"preferSoftPrivate" | "nameConflict", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
12
+ name: string;
13
+ };
14
+ export default _default;
15
+ //# sourceMappingURL=no-hard-private.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-hard-private.d.ts","sourceRoot":"","sources":["../../src/rules/no-hard-private.ts"],"names":[],"mappings":"AAcA;;;;;;;;;GASG;;;;AACH,wBA+GG"}
@@ -0,0 +1,95 @@
1
+ import { AST_NODE_TYPES } from "@typescript-eslint/utils";
2
+ import { createRule } from "../utils/create-rule.js";
3
+ function isClassMemberWithAccessibility(node) {
4
+ return node?.type === AST_NODE_TYPES.PropertyDefinition || node?.type === AST_NODE_TYPES.MethodDefinition || node?.type === AST_NODE_TYPES.AccessorProperty;
5
+ }
6
+ var no_hard_private_default = createRule({
7
+ name: "no-hard-private",
8
+ meta: {
9
+ type: "problem",
10
+ docs: {
11
+ description: '\uD558\uB4DC \uD504\uB77C\uC774\uBE57 \uD544\uB4DC(#) \uB300\uC2E0 TypeScript "private _" \uC2A4\uD0C0\uC77C\uC744 \uAC15\uC81C\uD55C\uB2E4.'
12
+ },
13
+ messages: {
14
+ preferSoftPrivate: '\uD558\uB4DC \uD504\uB77C\uC774\uBE57 \uD544\uB4DC(#)\uB294 \uD5C8\uC6A9\uB418\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. "private _" \uC2A4\uD0C0\uC77C\uC744 \uC0AC\uC6A9\uD558\uC138\uC694.',
15
+ nameConflict: '\uD558\uB4DC \uD504\uB77C\uC774\uBE57 \uD544\uB4DC "#{{name}}"\uC744 "_{{name}}"\uC73C\uB85C \uBCC0\uD658\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4. \uB3D9\uC77C\uD55C \uC774\uB984\uC758 \uBA64\uBC84\uAC00 \uC774\uBBF8 \uC874\uC7AC\uD569\uB2C8\uB2E4.'
16
+ },
17
+ fixable: "code",
18
+ schema: []
19
+ },
20
+ defaultOptions: [],
21
+ create(context) {
22
+ const sourceCode = context.sourceCode;
23
+ const classStack = [];
24
+ return {
25
+ // 0. 클래스 진입 시 멤버 이름 수집
26
+ "ClassBody"(node) {
27
+ const memberNames = /* @__PURE__ */ new Set();
28
+ for (const member of node.body) {
29
+ if (!("key" in member)) continue;
30
+ const key = member.key;
31
+ if (key.type === AST_NODE_TYPES.Identifier) {
32
+ memberNames.add(key.name);
33
+ }
34
+ }
35
+ classStack.push(memberNames);
36
+ },
37
+ "ClassBody:exit"() {
38
+ classStack.pop();
39
+ },
40
+ // 1. 선언부 감지 (PropertyDefinition, MethodDefinition, AccessorProperty)
41
+ "PropertyDefinition > PrivateIdentifier, MethodDefinition > PrivateIdentifier, AccessorProperty > PrivateIdentifier"(node) {
42
+ const parent = node.parent;
43
+ if (!isClassMemberWithAccessibility(parent)) {
44
+ return;
45
+ }
46
+ const identifierName = node.name;
47
+ const targetName = `_${identifierName}`;
48
+ const currentClassMembers = classStack.at(-1);
49
+ if (currentClassMembers?.has(targetName)) {
50
+ context.report({
51
+ node,
52
+ messageId: "nameConflict",
53
+ data: { name: identifierName }
54
+ });
55
+ return;
56
+ }
57
+ context.report({
58
+ node,
59
+ messageId: "preferSoftPrivate",
60
+ fix(fixer) {
61
+ const fixes = [];
62
+ fixes.push(fixer.replaceText(node, targetName));
63
+ if (parent.accessibility == null) {
64
+ let tokenToInsertBefore = sourceCode.getFirstToken(parent);
65
+ if (parent.decorators.length > 0) {
66
+ const lastDecorator = parent.decorators.at(-1);
67
+ tokenToInsertBefore = sourceCode.getTokenAfter(lastDecorator);
68
+ }
69
+ if (tokenToInsertBefore == null) {
70
+ return [];
71
+ }
72
+ fixes.push(fixer.insertTextBefore(tokenToInsertBefore, "private "));
73
+ }
74
+ return fixes;
75
+ }
76
+ });
77
+ },
78
+ // 2. 사용부 감지 (this.#field)
79
+ "MemberExpression > PrivateIdentifier"(node) {
80
+ const identifierName = node.name;
81
+ context.report({
82
+ node,
83
+ messageId: "preferSoftPrivate",
84
+ fix(fixer) {
85
+ return fixer.replaceText(node, `_${identifierName}`);
86
+ }
87
+ });
88
+ }
89
+ };
90
+ }
91
+ });
92
+ export {
93
+ no_hard_private_default as default
94
+ };
95
+ //# sourceMappingURL=no-hard-private.js.map
@@ -0,0 +1,6 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/rules/no-hard-private.ts"],
4
+ "mappings": "AAAA,SAAS,sBAAqC;AAE9C,SAAS,kBAAkB;AAI3B,SAAS,+BAA+B,MAAuE;AAC7G,SACE,MAAM,SAAS,eAAe,sBAC9B,MAAM,SAAS,eAAe,oBAC9B,MAAM,SAAS,eAAe;AAElC;AAYA,IAAO,0BAAQ,WAAW;AAAA,EACxB,MAAM;AAAA,EACN,MAAM;AAAA,IACJ,MAAM;AAAA,IACN,MAAM;AAAA,MACJ,aAAa;AAAA,IACf;AAAA,IACA,UAAU;AAAA,MACR,mBAAmB;AAAA,MACnB,cACE;AAAA,IACJ;AAAA,IACA,SAAS;AAAA,IACT,QAAQ,CAAC;AAAA,EACX;AAAA,EACA,gBAAgB,CAAC;AAAA,EACjB,OAAO,SAAS;AACd,UAAM,aAAa,QAAQ;AAE3B,UAAM,aAA4B,CAAC;AAEnC,WAAO;AAAA;AAAA,MAEL,YAAY,MAA0B;AACpC,cAAM,cAAc,oBAAI,IAAY;AACpC,mBAAW,UAAU,KAAK,MAAM;AAC9B,cAAI,EAAE,SAAS,QAAS;AACxB,gBAAM,MAAM,OAAO;AACnB,cAAI,IAAI,SAAS,eAAe,YAAY;AAC1C,wBAAY,IAAI,IAAI,IAAI;AAAA,UAC1B;AAAA,QACF;AACA,mBAAW,KAAK,WAAW;AAAA,MAC7B;AAAA,MAEA,mBAAmB;AACjB,mBAAW,IAAI;AAAA,MACjB;AAAA;AAAA,MAGA,qHACE,MACA;AACA,cAAM,SAAS,KAAK;AACpB,YAAI,CAAC,+BAA+B,MAAM,GAAG;AAC3C;AAAA,QACF;AAEA,cAAM,iBAAiB,KAAK;AAC5B,cAAM,aAAa,IAAI,cAAc;AACrC,cAAM,sBAAsB,WAAW,GAAG,EAAE;AAG5C,YAAI,qBAAqB,IAAI,UAAU,GAAG;AACxC,kBAAQ,OAAO;AAAA,YACb;AAAA,YACA,WAAW;AAAA,YACX,MAAM,EAAE,MAAM,eAAe;AAAA,UAC/B,CAAC;AACD;AAAA,QACF;AAEA,gBAAQ,OAAO;AAAA,UACb;AAAA,UACA,WAAW;AAAA,UACX,IAAI,OAAO;AACT,kBAAM,QAAmB,CAAC;AAG1B,kBAAM,KAAK,MAAM,YAAY,MAAM,UAAU,CAAC;AAG9C,gBAAI,OAAO,iBAAiB,MAAM;AAEhC,kBAAI,sBAAsB,WAAW,cAAc,MAAM;AAIzD,kBAAI,OAAO,WAAW,SAAS,GAAG;AAChC,sBAAM,gBAAgB,OAAO,WAAW,GAAG,EAAE;AAC7C,sCAAsB,WAAW,cAAc,aAAa;AAAA,cAC9D;AAMA,kBAAI,uBAAuB,MAAM;AAC/B,uBAAO,CAAC;AAAA,cACV;AACA,oBAAM,KAAK,MAAM,iBAAiB,qBAAqB,UAAU,CAAC;AAAA,YACpE;AAEA,mBAAO;AAAA,UACT;AAAA,QACF,CAAC;AAAA,MACH;AAAA;AAAA,MAGA,uCAAuC,MAAkC;AACvE,cAAM,iBAAiB,KAAK;AAC5B,gBAAQ,OAAO;AAAA,UACb;AAAA,UACA,WAAW;AAAA,UACX,IAAI,OAAO;AACT,mBAAO,MAAM,YAAY,MAAM,IAAI,cAAc,EAAE;AAAA,UACrD;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AACF,CAAC;",
5
+ "names": []
6
+ }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * `@simplysm/*` 패키지에서 'src' 서브경로 import를 금지하는 ESLint 규칙
3
+ *
4
+ * @remarks
5
+ * 이 규칙은 다음을 검사한다:
6
+ * - 정적 import 문: `import ... from '...'`
7
+ * - 동적 import: `import('...')`
8
+ * - re-export 문: `export { ... } from '...'`, `export * from '...'`
9
+ */
10
+ declare const _default: import("@typescript-eslint/utils/ts-eslint").RuleModule<"noSubpathImport", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
11
+ name: string;
12
+ };
13
+ export default _default;
14
+ //# sourceMappingURL=no-subpath-imports-from-simplysm.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-subpath-imports-from-simplysm.d.ts","sourceRoot":"","sources":["../../src/rules/no-subpath-imports-from-simplysm.ts"],"names":[],"mappings":"AAGA;;;;;;;;GAQG;;;;AACH,wBAiEG"}
@@ -0,0 +1,64 @@
1
+ import { AST_NODE_TYPES, TSESTree } from "@typescript-eslint/utils";
2
+ import { createRule } from "../utils/create-rule.js";
3
+ var no_subpath_imports_from_simplysm_default = createRule({
4
+ name: "no-subpath-imports-from-simplysm",
5
+ meta: {
6
+ type: "problem",
7
+ docs: {
8
+ description: "@simplysm \uD328\uD0A4\uC9C0\uC5D0\uC11C 'src' \uC11C\uBE0C\uACBD\uB85C import\uB97C \uAE08\uC9C0\uD55C\uB2E4. (ex: @simplysm/pkg/src/x \u2192 \uAE08\uC9C0)"
9
+ },
10
+ fixable: "code",
11
+ schema: [],
12
+ messages: {
13
+ noSubpathImport: "'@simplysm/{{pkg}}' \uD328\uD0A4\uC9C0\uB294 'src' \uC11C\uBE0C\uACBD\uB85C\uB97C import\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: '{{importPath}}'"
14
+ }
15
+ },
16
+ defaultOptions: [],
17
+ create(context) {
18
+ function checkAndReport(sourceNode, importPath) {
19
+ if (!importPath.startsWith("@simplysm/")) return;
20
+ const parts = importPath.split("/");
21
+ if (parts.length >= 3 && parts[2] === "src") {
22
+ const fixedPath = `@simplysm/${parts[1]}`;
23
+ context.report({
24
+ node: sourceNode,
25
+ messageId: "noSubpathImport",
26
+ data: {
27
+ pkg: parts[1],
28
+ importPath
29
+ },
30
+ fix(fixer) {
31
+ const quote = sourceNode.raw[0];
32
+ return fixer.replaceText(sourceNode, `${quote}${fixedPath}${quote}`);
33
+ }
34
+ });
35
+ }
36
+ }
37
+ return {
38
+ // 정적 import: import { x } from '...'
39
+ ImportDeclaration(node) {
40
+ checkAndReport(node.source, node.source.value);
41
+ },
42
+ // 동적 import: import('...')
43
+ ImportExpression(node) {
44
+ if (node.source.type !== AST_NODE_TYPES.Literal) return;
45
+ const importPath = node.source.value;
46
+ if (typeof importPath !== "string") return;
47
+ checkAndReport(node.source, importPath);
48
+ },
49
+ // re-export: export { x } from '...'
50
+ ExportNamedDeclaration(node) {
51
+ if (!node.source) return;
52
+ checkAndReport(node.source, node.source.value);
53
+ },
54
+ // re-export all: export * from '...'
55
+ ExportAllDeclaration(node) {
56
+ checkAndReport(node.source, node.source.value);
57
+ }
58
+ };
59
+ }
60
+ });
61
+ export {
62
+ no_subpath_imports_from_simplysm_default as default
63
+ };
64
+ //# sourceMappingURL=no-subpath-imports-from-simplysm.js.map
@@ -0,0 +1,6 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/rules/no-subpath-imports-from-simplysm.ts"],
4
+ "mappings": "AAAA,SAAS,gBAAgB,gBAAgB;AACzC,SAAS,kBAAkB;AAW3B,IAAO,2CAAQ,WAAW;AAAA,EACxB,MAAM;AAAA,EACN,MAAM;AAAA,IACJ,MAAM;AAAA,IACN,MAAM;AAAA,MACJ,aAAa;AAAA,IACf;AAAA,IACA,SAAS;AAAA,IACT,QAAQ,CAAC;AAAA,IACT,UAAU;AAAA,MACR,iBAAiB;AAAA,IACnB;AAAA,EACF;AAAA,EACA,gBAAgB,CAAC;AAAA,EACjB,OAAO,SAAS;AACd,aAAS,eAAe,YAAoC,YAAoB;AAC9E,UAAI,CAAC,WAAW,WAAW,YAAY,EAAG;AAE1C,YAAM,QAAQ,WAAW,MAAM,GAAG;AAIlC,UAAI,MAAM,UAAU,KAAK,MAAM,CAAC,MAAM,OAAO;AAC3C,cAAM,YAAY,aAAa,MAAM,CAAC,CAAC;AACvC,gBAAQ,OAAO;AAAA,UACb,MAAM;AAAA,UACN,WAAW;AAAA,UACX,MAAM;AAAA,YACJ,KAAK,MAAM,CAAC;AAAA,YACZ;AAAA,UACF;AAAA,UACA,IAAI,OAAO;AACT,kBAAM,QAAQ,WAAW,IAAI,CAAC;AAC9B,mBAAO,MAAM,YAAY,YAAY,GAAG,KAAK,GAAG,SAAS,GAAG,KAAK,EAAE;AAAA,UACrE;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF;AAEA,WAAO;AAAA;AAAA,MAEL,kBAAkB,MAAM;AACtB,uBAAe,KAAK,QAAQ,KAAK,OAAO,KAAK;AAAA,MAC/C;AAAA;AAAA,MAGA,iBAAiB,MAAM;AACrB,YAAI,KAAK,OAAO,SAAS,eAAe,QAAS;AACjD,cAAM,aAAa,KAAK,OAAO;AAC/B,YAAI,OAAO,eAAe,SAAU;AACpC,uBAAe,KAAK,QAAQ,UAAU;AAAA,MACxC;AAAA;AAAA,MAGA,uBAAuB,MAAM;AAC3B,YAAI,CAAC,KAAK,OAAQ;AAClB,uBAAe,KAAK,QAAQ,KAAK,OAAO,KAAK;AAAA,MAC/C;AAAA;AAAA,MAGA,qBAAqB,MAAM;AACzB,uBAAe,KAAK,QAAQ,KAAK,OAAO,KAAK;AAAA,MAC/C;AAAA,IACF;AAAA,EACF;AACF,CAAC;",
5
+ "names": []
6
+ }
@@ -0,0 +1,19 @@
1
+ /**
2
+ * `@simplysm/core-common`의 `NotImplementedError` 사용을 감지하여 경고하는 ESLint 규칙
3
+ *
4
+ * @remarks
5
+ * 이 규칙은 `@simplysm/core-common`에서 import된 `NotImplementedError`를 `new`로 생성하는 코드를 감지한다.
6
+ * 미구현 코드가 프로덕션에 포함되는 것을 방지한다.
7
+ *
8
+ * 지원하는 import 형태:
9
+ * - named import: `import { NotImplementedError } from "@simplysm/core-common"`
10
+ * - aliased import: `import { NotImplementedError as NIE } from "@simplysm/core-common"`
11
+ * - namespace import: `import * as CC from "@simplysm/core-common"` → `new CC.NotImplementedError()`
12
+ *
13
+ * 동적 import(`await import(...)`)는 감지하지 않는다.
14
+ */
15
+ declare const _default: import("@typescript-eslint/utils/ts-eslint").RuleModule<"noThrowNotImplementedError", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
16
+ name: string;
17
+ };
18
+ export default _default;
19
+ //# sourceMappingURL=ts-no-throw-not-implemented-error.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ts-no-throw-not-implemented-error.d.ts","sourceRoot":"","sources":["../../src/rules/ts-no-throw-not-implemented-error.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;GAaG;;;;AACH,wBAqFG"}
@@ -0,0 +1,63 @@
1
+ import { AST_NODE_TYPES, ASTUtils } from "@typescript-eslint/utils";
2
+ import { createRule } from "../utils/create-rule.js";
3
+ var ts_no_throw_not_implemented_error_default = createRule({
4
+ name: "ts-no-throw-not-implemented-error",
5
+ meta: {
6
+ type: "suggestion",
7
+ docs: {
8
+ description: "'NotImplementedError' \uC0AC\uC6A9 \uACBD\uACE0"
9
+ },
10
+ schema: [],
11
+ messages: {
12
+ noThrowNotImplementedError: "{{text}}"
13
+ }
14
+ },
15
+ defaultOptions: [],
16
+ create(context) {
17
+ function isImportedFromSimplysm(identifier, expectedImportedName) {
18
+ const scope = context.sourceCode.getScope(identifier);
19
+ const variable = ASTUtils.findVariable(scope, identifier.name);
20
+ if (!variable) return false;
21
+ for (const def of variable.defs) {
22
+ if (def.type !== "ImportBinding") continue;
23
+ if (def.parent.type !== AST_NODE_TYPES.ImportDeclaration) continue;
24
+ if (def.parent.source.value !== "@simplysm/core-common") continue;
25
+ if (def.node.type === AST_NODE_TYPES.ImportSpecifier && expectedImportedName != null) {
26
+ const imported = def.node.imported;
27
+ if (imported.type === AST_NODE_TYPES.Identifier && imported.name === expectedImportedName) {
28
+ return true;
29
+ }
30
+ }
31
+ if (def.node.type === AST_NODE_TYPES.ImportNamespaceSpecifier && expectedImportedName == null) {
32
+ return true;
33
+ }
34
+ }
35
+ return false;
36
+ }
37
+ return {
38
+ NewExpression(node) {
39
+ let shouldReport = false;
40
+ if (node.callee.type === AST_NODE_TYPES.Identifier) {
41
+ shouldReport = isImportedFromSimplysm(node.callee, "NotImplementedError");
42
+ } else if (node.callee.type === AST_NODE_TYPES.MemberExpression && node.callee.property.type === AST_NODE_TYPES.Identifier && node.callee.property.name === "NotImplementedError" && node.callee.object.type === AST_NODE_TYPES.Identifier) {
43
+ shouldReport = isImportedFromSimplysm(node.callee.object, void 0);
44
+ }
45
+ if (!shouldReport) return;
46
+ let msg = "\uBBF8\uAD6C\uD604";
47
+ const firstArg = node.arguments.at(0);
48
+ if (firstArg?.type === AST_NODE_TYPES.Literal && typeof firstArg.value === "string" && firstArg.value !== "") {
49
+ msg = firstArg.value;
50
+ }
51
+ context.report({
52
+ node,
53
+ messageId: "noThrowNotImplementedError",
54
+ data: { text: msg }
55
+ });
56
+ }
57
+ };
58
+ }
59
+ });
60
+ export {
61
+ ts_no_throw_not_implemented_error_default as default
62
+ };
63
+ //# sourceMappingURL=ts-no-throw-not-implemented-error.js.map
@@ -0,0 +1,6 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/rules/ts-no-throw-not-implemented-error.ts"],
4
+ "mappings": "AAAA,SAAS,gBAAgB,gBAA+B;AACxD,SAAS,kBAAkB;AAgB3B,IAAO,4CAAQ,WAAW;AAAA,EACxB,MAAM;AAAA,EACN,MAAM;AAAA,IACJ,MAAM;AAAA,IACN,MAAM;AAAA,MACJ,aAAa;AAAA,IACf;AAAA,IACA,QAAQ,CAAC;AAAA,IACT,UAAU;AAAA,MACR,4BAA4B;AAAA,IAC9B;AAAA,EACF;AAAA,EACA,gBAAgB,CAAC;AAAA,EACjB,OAAO,SAAS;AAOd,aAAS,uBACP,YACA,sBACS;AACT,YAAM,QAAQ,QAAQ,WAAW,SAAS,UAAU;AACpD,YAAM,WAAW,SAAS,aAAa,OAAO,WAAW,IAAI;AAC7D,UAAI,CAAC,SAAU,QAAO;AAEtB,iBAAW,OAAO,SAAS,MAAM;AAC/B,YAAI,IAAI,SAAS,gBAAiB;AAClC,YAAI,IAAI,OAAO,SAAS,eAAe,kBAAmB;AAC1D,YAAI,IAAI,OAAO,OAAO,UAAU,wBAAyB;AAGzD,YAAI,IAAI,KAAK,SAAS,eAAe,mBAAmB,wBAAwB,MAAM;AACpF,gBAAM,WAAW,IAAI,KAAK;AAC1B,cAAI,SAAS,SAAS,eAAe,cAAc,SAAS,SAAS,sBAAsB;AACzF,mBAAO;AAAA,UACT;AAAA,QACF;AAGA,YAAI,IAAI,KAAK,SAAS,eAAe,4BAA4B,wBAAwB,MAAM;AAC7F,iBAAO;AAAA,QACT;AAAA,MACF;AAEA,aAAO;AAAA,IACT;AAEA,WAAO;AAAA,MACL,cAAc,MAA8B;AAC1C,YAAI,eAAe;AAGnB,YAAI,KAAK,OAAO,SAAS,eAAe,YAAY;AAClD,yBAAe,uBAAuB,KAAK,QAAQ,qBAAqB;AAAA,QAC1E,WAIE,KAAK,OAAO,SAAS,eAAe,oBACpC,KAAK,OAAO,SAAS,SAAS,eAAe,cAC7C,KAAK,OAAO,SAAS,SAAS,yBAC9B,KAAK,OAAO,OAAO,SAAS,eAAe,YAC3C;AACA,yBAAe,uBAAuB,KAAK,OAAO,QAAQ,MAAS;AAAA,QACrE;AAEA,YAAI,CAAC,aAAc;AAEnB,YAAI,MAAM;AACV,cAAM,WAAW,KAAK,UAAU,GAAG,CAAC;AACpC,YAAI,UAAU,SAAS,eAAe,WAAW,OAAO,SAAS,UAAU,YAAY,SAAS,UAAU,IAAI;AAC5G,gBAAM,SAAS;AAAA,QACjB;AAEA,gBAAQ,OAAO;AAAA,UACb;AAAA,UACA,WAAW;AAAA,UACX,MAAM,EAAE,MAAM,IAAI;AAAA,QACpB,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AACF,CAAC;",
5
+ "names": []
6
+ }
@@ -0,0 +1,13 @@
1
+ declare const _default: {
2
+ extends: string[];
3
+ plugins: string[];
4
+ rules: {
5
+ "plugin/no-unsupported-browser-features": (boolean | {
6
+ severity: string;
7
+ browsers: string[];
8
+ })[];
9
+ "plugin/no-unresolved-module": boolean;
10
+ };
11
+ };
12
+ export default _default;
13
+ //# sourceMappingURL=stylelint-recommended.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stylelint-recommended.d.ts","sourceRoot":"","sources":["../src/stylelint-recommended.ts"],"names":[],"mappings":";;;;;;;;;;;AAAA,wBAeE"}
@@ -0,0 +1,20 @@
1
+ var stylelint_recommended_default = {
2
+ extends: ["stylelint-config-standard", "stylelint-config-tailwindcss"],
3
+ plugins: ["stylelint-no-unsupported-browser-features", "stylelint-no-unresolved-module"],
4
+ rules: {
5
+ // Chrome 84+ 호환성 체크
6
+ "plugin/no-unsupported-browser-features": [
7
+ true,
8
+ {
9
+ severity: "error",
10
+ browsers: ["chrome >= 84"]
11
+ }
12
+ ],
13
+ // @import, url() 파일 존재 체크
14
+ "plugin/no-unresolved-module": true
15
+ }
16
+ };
17
+ export {
18
+ stylelint_recommended_default as default
19
+ };
20
+ //# sourceMappingURL=stylelint-recommended.js.map
@@ -0,0 +1,6 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/stylelint-recommended.ts"],
4
+ "mappings": "AAAA,IAAO,gCAAQ;AAAA,EACb,SAAS,CAAC,6BAA6B,8BAA8B;AAAA,EACrE,SAAS,CAAC,6CAA6C,gCAAgC;AAAA,EACvF,OAAO;AAAA;AAAA,IAEL,0CAA0C;AAAA,MACxC;AAAA,MACA;AAAA,QACE,UAAU;AAAA,QACV,UAAU,CAAC,cAAc;AAAA,MAC3B;AAAA,IACF;AAAA;AAAA,IAEA,+BAA+B;AAAA,EACjC;AACF;",
5
+ "names": []
6
+ }
@@ -0,0 +1,22 @@
1
+ import { ESLintUtils } from "@typescript-eslint/utils";
2
+ /**
3
+ * ESLint 규칙을 생성하는 팩토리 함수
4
+ *
5
+ * @remarks
6
+ * `@typescript-eslint/utils`의 `RuleCreator`를 래핑하여
7
+ * 규칙 문서 URL을 자동으로 생성한다.
8
+ *
9
+ * @example
10
+ * ```typescript
11
+ * export default createRule({
12
+ * name: "my-rule",
13
+ * meta: { ... },
14
+ * defaultOptions: [],
15
+ * create(context) { ... },
16
+ * });
17
+ * ```
18
+ */
19
+ export declare const createRule: <Options extends readonly unknown[], MessageIds extends string>({ meta, name, ...rule }: Readonly<ESLintUtils.RuleWithMetaAndName<Options, MessageIds, unknown>>) => ESLintUtils.RuleModule<MessageIds, Options, unknown, ESLintUtils.RuleListener> & {
20
+ name: string;
21
+ };
22
+ //# sourceMappingURL=create-rule.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-rule.d.ts","sourceRoot":"","sources":["../../src/utils/create-rule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAEvD;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,UAAU;;CAEtB,CAAC"}