@simplysm/sd-cli 13.0.1 → 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.
@@ -1 +1 @@
1
- {"version":3,"file":"lint.d.ts","sourceRoot":"","sources":["../../src/commands/lint.ts"],"names":[],"mappings":"AAKA,OAAO,uBAAuB,CAAC;AAM/B;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,0DAA0D;IAC1D,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,gBAAgB;IAChB,GAAG,EAAE,OAAO,CAAC;IACb,+CAA+C;IAC/C,MAAM,EAAE,OAAO,CAAC;CACjB;AAkCD;;;;GAIG;AACH,wBAAsB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CA+BvE;AAMD;;;;;;;;;;GAUG;AACH,wBAAsB,OAAO,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAyGjE"}
1
+ {"version":3,"file":"lint.d.ts","sourceRoot":"","sources":["../../src/commands/lint.ts"],"names":[],"mappings":"AAKA,OAAO,uBAAuB,CAAC;AAO/B;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,0DAA0D;IAC1D,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,gBAAgB;IAChB,GAAG,EAAE,OAAO,CAAC;IACb,+CAA+C;IAC/C,MAAM,EAAE,OAAO,CAAC;CACjB;AAgDD;;;;GAIG;AACH,wBAAsB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CA+BvE;AAgBD;;;;;;;;;;GAUG;AACH,wBAAsB,OAAO,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CA+LjE"}
@@ -6,7 +6,16 @@ import { fsExists, fsGlob, pathFilterByTargets } from "@simplysm/core-node";
6
6
  import "@simplysm/core-common";
7
7
  import { SdError } from "@simplysm/core-common";
8
8
  import { consola, LogLevels } from "consola";
9
+ import stylelint from "stylelint";
9
10
  const ESLINT_CONFIG_FILES = ["eslint.config.ts", "eslint.config.mts", "eslint.config.js", "eslint.config.mjs"];
11
+ const STYLELINT_CONFIG_FILES = [
12
+ "stylelint.config.ts",
13
+ "stylelint.config.mts",
14
+ "stylelint.config.js",
15
+ "stylelint.config.mjs",
16
+ ".stylelintrc.json",
17
+ ".stylelintrc.yml"
18
+ ];
10
19
  function isGlobalIgnoresConfig(item) {
11
20
  if (item == null || typeof item !== "object") return false;
12
21
  if (!("ignores" in item)) return false;
@@ -42,6 +51,12 @@ async function loadIgnorePatterns(cwd) {
42
51
  }
43
52
  return configs.filter(isGlobalIgnoresConfig).flatMap((item) => item.ignores);
44
53
  }
54
+ async function hasStylelintConfig(cwd) {
55
+ for (const f of STYLELINT_CONFIG_FILES) {
56
+ if (await fsExists(path.join(cwd, f))) return true;
57
+ }
58
+ return false;
59
+ }
45
60
  async function runLint(options) {
46
61
  const { targets, fix, timing } = options;
47
62
  const cwd = process.cwd();
@@ -102,6 +117,57 @@ async function runLint(options) {
102
117
  await ESLint.outputFixes(ctx2.results);
103
118
  logger.debug("\uC790\uB3D9 \uC218\uC815 \uC801\uC6A9 \uC644\uB8CC");
104
119
  }
120
+ },
121
+ {
122
+ title: "Stylelint \uC124\uC815 \uD655\uC778",
123
+ task: async (ctx2, task) => {
124
+ ctx2.hasStylelintConfig = await hasStylelintConfig(cwd);
125
+ if (!ctx2.hasStylelintConfig) {
126
+ task.skip("stylelint.config \uD30C\uC77C \uC5C6\uC74C");
127
+ }
128
+ }
129
+ },
130
+ {
131
+ title: "CSS \uD30C\uC77C \uC218\uC9D1",
132
+ enabled: (ctx2) => ctx2.hasStylelintConfig === true,
133
+ task: async (ctx2, task) => {
134
+ let cssFiles = await fsGlob("**/*.css", {
135
+ cwd,
136
+ ignore: ctx2.ignorePatterns,
137
+ nodir: true,
138
+ absolute: true
139
+ });
140
+ cssFiles = pathFilterByTargets(cssFiles, targets, cwd);
141
+ ctx2.cssFiles = cssFiles;
142
+ task.title = `CSS \uD30C\uC77C \uC218\uC9D1 (${cssFiles.length}\uAC1C)`;
143
+ if (cssFiles.length === 0) {
144
+ task.skip("\uB9B0\uD2B8\uD560 CSS \uD30C\uC77C\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.");
145
+ }
146
+ }
147
+ },
148
+ {
149
+ title: "Stylelint \uC2E4\uD589",
150
+ enabled: (ctx2) => (ctx2.cssFiles?.length ?? 0) > 0,
151
+ task: async (ctx2, task) => {
152
+ const cssFiles = ctx2.cssFiles;
153
+ task.title = `Stylelint \uC2E4\uD589 \uC911... (${cssFiles.length}\uAC1C \uD30C\uC77C)`;
154
+ let configFile;
155
+ for (const f of STYLELINT_CONFIG_FILES) {
156
+ const configPath = path.join(cwd, f);
157
+ if (await fsExists(configPath)) {
158
+ configFile = configPath;
159
+ break;
160
+ }
161
+ }
162
+ const result = await stylelint.lint({
163
+ files: cssFiles,
164
+ configFile,
165
+ fix,
166
+ cache: true,
167
+ cacheLocation: path.join(cwd, ".cache", "stylelint.cache")
168
+ });
169
+ ctx2.stylelintResult = result;
170
+ }
105
171
  }
106
172
  ],
107
173
  {
@@ -130,6 +196,32 @@ async function runLint(options) {
130
196
  if (errorCount > 0) {
131
197
  process.exitCode = 1;
132
198
  }
199
+ if (ctx.stylelintResult != null && ctx.stylelintResult.results.length > 0) {
200
+ const stylelintErrorCount = ctx.stylelintResult.results.sum(
201
+ (r) => r.warnings.filter((w) => w.severity === "error").length
202
+ );
203
+ const stylelintWarningCount = ctx.stylelintResult.results.sum(
204
+ (r) => r.warnings.filter((w) => w.severity === "warning").length
205
+ );
206
+ if (stylelintErrorCount > 0) {
207
+ logger.error("Stylelint \uC5D0\uB7EC \uBC1C\uC0DD", { errorCount: stylelintErrorCount, warningCount: stylelintWarningCount });
208
+ } else if (stylelintWarningCount > 0) {
209
+ logger.info("Stylelint \uC644\uB8CC (\uACBD\uACE0 \uC788\uC74C)", {
210
+ errorCount: stylelintErrorCount,
211
+ warningCount: stylelintWarningCount
212
+ });
213
+ } else {
214
+ logger.info("Stylelint \uC644\uB8CC", { errorCount: stylelintErrorCount, warningCount: stylelintWarningCount });
215
+ }
216
+ const stylelintFormatter = await stylelint.formatters.string;
217
+ const stylelintOutput = stylelintFormatter(ctx.stylelintResult.results, ctx.stylelintResult);
218
+ if (stylelintOutput) {
219
+ process.stdout.write(stylelintOutput);
220
+ }
221
+ if (stylelintErrorCount > 0) {
222
+ process.exitCode = 1;
223
+ }
224
+ }
133
225
  }
134
226
  export {
135
227
  loadIgnorePatterns,
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/commands/lint.ts"],
4
- "mappings": "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",
4
+ "mappings": "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",
5
5
  "names": ["ctx"]
6
6
  }
package/dist/sd-cli.js CHANGED
@@ -27,7 +27,7 @@ function createCliParser(argv) {
27
27
  if (args.debug) consola.level = LogLevels.debug;
28
28
  }).command(
29
29
  "lint [targets..]",
30
- "ESLint\uB97C \uC2E4\uD589\uD55C\uB2E4.",
30
+ "ESLint + Stylelint\uB97C \uC2E4\uD589\uD55C\uB2E4.",
31
31
  (cmd) => cmd.version(false).hide("help").positional("targets", {
32
32
  type: "string",
33
33
  array: true,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@simplysm/sd-cli",
3
3
  "sideEffects": false,
4
- "version": "13.0.1",
4
+ "version": "13.0.2",
5
5
  "description": "심플리즘 패키지 - CLI 도구",
6
6
  "author": "김석래",
7
7
  "repository": {
@@ -36,6 +36,7 @@
36
36
  "sharp": "^0.34.5",
37
37
  "solid-js": "^1.9.11",
38
38
  "ssh2": "^1.17.0",
39
+ "stylelint": "^16.26.1",
39
40
  "tailwindcss": "^3.4.19",
40
41
  "ts-morph": "^27.0.2",
41
42
  "typescript": "^5.9.3",
@@ -44,9 +45,9 @@
44
45
  "vite-plugin-solid": "^2.11.10",
45
46
  "vite-tsconfig-paths": "^6.1.0",
46
47
  "yargs": "^18.0.0",
47
- "@simplysm/core-common": "13.0.1",
48
- "@simplysm/core-node": "13.0.1",
49
- "@simplysm/storage": "13.0.1"
48
+ "@simplysm/core-common": "13.0.2",
49
+ "@simplysm/storage": "13.0.2",
50
+ "@simplysm/core-node": "13.0.2"
50
51
  },
51
52
  "devDependencies": {
52
53
  "@types/semver": "^7.7.1",
@@ -6,6 +6,7 @@ import { fsExists, fsGlob, pathFilterByTargets } from "@simplysm/core-node";
6
6
  import "@simplysm/core-common";
7
7
  import { SdError } from "@simplysm/core-common";
8
8
  import { consola, LogLevels } from "consola";
9
+ import stylelint from "stylelint";
9
10
 
10
11
  //#region Types
11
12
 
@@ -32,6 +33,10 @@ interface LintContext {
32
33
  eslint?: ESLint;
33
34
  /** 린트 대상 파일이 있을 때만 초기화됨 */
34
35
  results?: ESLint.LintResult[];
36
+ // Stylelint
37
+ hasStylelintConfig?: boolean;
38
+ cssFiles?: string[];
39
+ stylelintResult?: stylelint.LinterResult;
35
40
  }
36
41
 
37
42
  //#endregion
@@ -41,6 +46,16 @@ interface LintContext {
41
46
  /** ESLint 설정 파일 탐색 순서 */
42
47
  const ESLINT_CONFIG_FILES = ["eslint.config.ts", "eslint.config.mts", "eslint.config.js", "eslint.config.mjs"] as const;
43
48
 
49
+ /** Stylelint 설정 파일 탐색 순서 */
50
+ const STYLELINT_CONFIG_FILES = [
51
+ "stylelint.config.ts",
52
+ "stylelint.config.mts",
53
+ "stylelint.config.js",
54
+ "stylelint.config.mjs",
55
+ ".stylelintrc.json",
56
+ ".stylelintrc.yml",
57
+ ] as const;
58
+
44
59
  /**
45
60
  * ignores 속성만 가진 ESLint 설정 객체인지 검사하는 타입 가드
46
61
  */
@@ -91,6 +106,16 @@ export async function loadIgnorePatterns(cwd: string): Promise<string[]> {
91
106
  return configs.filter(isGlobalIgnoresConfig).flatMap((item) => item.ignores);
92
107
  }
93
108
 
109
+ /**
110
+ * Stylelint 설정 파일이 존재하는지 확인한다.
111
+ */
112
+ async function hasStylelintConfig(cwd: string): Promise<boolean> {
113
+ for (const f of STYLELINT_CONFIG_FILES) {
114
+ if (await fsExists(path.join(cwd, f))) return true;
115
+ }
116
+ return false;
117
+ }
118
+
94
119
  //#endregion
95
120
 
96
121
  //#region Main
@@ -174,6 +199,60 @@ export async function runLint(options: LintOptions): Promise<void> {
174
199
  logger.debug("자동 수정 적용 완료");
175
200
  },
176
201
  },
202
+ {
203
+ title: "Stylelint 설정 확인",
204
+ task: async (ctx, task) => {
205
+ ctx.hasStylelintConfig = await hasStylelintConfig(cwd);
206
+ if (!ctx.hasStylelintConfig) {
207
+ task.skip("stylelint.config 파일 없음");
208
+ }
209
+ },
210
+ },
211
+ {
212
+ title: "CSS 파일 수집",
213
+ enabled: (ctx) => ctx.hasStylelintConfig === true,
214
+ task: async (ctx, task) => {
215
+ let cssFiles = await fsGlob("**/*.css", {
216
+ cwd,
217
+ ignore: ctx.ignorePatterns,
218
+ nodir: true,
219
+ absolute: true,
220
+ });
221
+ cssFiles = pathFilterByTargets(cssFiles, targets, cwd);
222
+ ctx.cssFiles = cssFiles;
223
+ task.title = `CSS 파일 수집 (${cssFiles.length}개)`;
224
+ if (cssFiles.length === 0) {
225
+ task.skip("린트할 CSS 파일이 없습니다.");
226
+ }
227
+ },
228
+ },
229
+ {
230
+ title: "Stylelint 실행",
231
+ enabled: (ctx) => (ctx.cssFiles?.length ?? 0) > 0,
232
+ task: async (ctx, task) => {
233
+ const cssFiles = ctx.cssFiles!;
234
+ task.title = `Stylelint 실행 중... (${cssFiles.length}개 파일)`;
235
+
236
+ // Stylelint 설정 파일 경로 찾기
237
+ let configFile: string | undefined;
238
+ for (const f of STYLELINT_CONFIG_FILES) {
239
+ const configPath = path.join(cwd, f);
240
+ if (await fsExists(configPath)) {
241
+ configFile = configPath;
242
+ break;
243
+ }
244
+ }
245
+
246
+ const result = await stylelint.lint({
247
+ files: cssFiles,
248
+ configFile,
249
+ fix,
250
+ cache: true,
251
+ cacheLocation: path.join(cwd, ".cache", "stylelint.cache"),
252
+ });
253
+ ctx.stylelintResult = result;
254
+ },
255
+ },
177
256
  ],
178
257
  {
179
258
  renderer: consola.level >= LogLevels.debug ? "verbose" : "default",
@@ -211,6 +290,38 @@ export async function runLint(options: LintOptions): Promise<void> {
211
290
  if (errorCount > 0) {
212
291
  process.exitCode = 1;
213
292
  }
293
+
294
+ // Stylelint 결과 출력
295
+ if (ctx.stylelintResult != null && ctx.stylelintResult.results.length > 0) {
296
+ const stylelintErrorCount = ctx.stylelintResult.results.sum(
297
+ (r) => r.warnings.filter((w) => w.severity === "error").length,
298
+ );
299
+ const stylelintWarningCount = ctx.stylelintResult.results.sum(
300
+ (r) => r.warnings.filter((w) => w.severity === "warning").length,
301
+ );
302
+
303
+ if (stylelintErrorCount > 0) {
304
+ logger.error("Stylelint 에러 발생", { errorCount: stylelintErrorCount, warningCount: stylelintWarningCount });
305
+ } else if (stylelintWarningCount > 0) {
306
+ logger.info("Stylelint 완료 (경고 있음)", {
307
+ errorCount: stylelintErrorCount,
308
+ warningCount: stylelintWarningCount,
309
+ });
310
+ } else {
311
+ logger.info("Stylelint 완료", { errorCount: stylelintErrorCount, warningCount: stylelintWarningCount });
312
+ }
313
+
314
+ // Stylelint formatter 출력
315
+ const stylelintFormatter = await stylelint.formatters.string;
316
+ const stylelintOutput = stylelintFormatter(ctx.stylelintResult.results, ctx.stylelintResult);
317
+ if (stylelintOutput) {
318
+ process.stdout.write(stylelintOutput);
319
+ }
320
+
321
+ if (stylelintErrorCount > 0) {
322
+ process.exitCode = 1;
323
+ }
324
+ }
214
325
  }
215
326
 
216
327
  //#endregion
package/src/sd-cli.ts CHANGED
@@ -40,7 +40,7 @@ export function createCliParser(argv: string[]): Argv {
40
40
  })
41
41
  .command(
42
42
  "lint [targets..]",
43
- "ESLint를 실행한다.",
43
+ "ESLint + Stylelint를 실행한다.",
44
44
  (cmd) =>
45
45
  cmd
46
46
  .version(false)
@@ -4,7 +4,7 @@
4
4
  "type": "module",
5
5
  "private": true,
6
6
  "dependencies": {
7
- "@simplysm/solid": "~13.0.1",
7
+ "@simplysm/solid": "~13.0.2",
8
8
  {{#if router}}
9
9
  "@solidjs/router": "^0.15.4",
10
10
  {{/if}}
@@ -4,7 +4,7 @@
4
4
  "type": "module",
5
5
  "private": true,
6
6
  "dependencies": {
7
- "@simplysm/core-common": "~13.0.1",
8
- "@simplysm/service-server": "~13.0.1"
7
+ "@simplysm/core-common": "~13.0.2",
8
+ "@simplysm/service-server": "~13.0.2"
9
9
  }
10
10
  }
@@ -1,5 +1,5 @@
1
- import simplysmPlugin from "@simplysm/eslint-plugin";
1
+ import simplysmEslintRecommended from "@simplysm/lint/eslint-recommended";
2
2
 
3
3
  export default [
4
- ...simplysmPlugin.configs.recommended,
4
+ ...simplysmEslintRecommended,
5
5
  ];
@@ -15,12 +15,13 @@
15
15
  "vitest": "vitest"
16
16
  },
17
17
  "devDependencies": {
18
- "@simplysm/sd-cli": "~13.0.1",
19
- "@simplysm/claude": "~13.0.1",
20
- "@simplysm/eslint-plugin": "~13.0.1",
18
+ "@simplysm/sd-cli": "~13.0.2",
19
+ "@simplysm/claude": "~13.0.2",
20
+ "@simplysm/lint": "~13.0.2",
21
21
  "@types/node": "^20.19.33",
22
22
  "eslint": "^9.39.2",
23
23
  "prettier": "^3.8.1",
24
+ "stylelint": "^16.13.0",
24
25
  "typescript": "^5.9.3",
25
26
  "vite-tsconfig-paths": "^6.1.0",
26
27
  "vitest": "^4.0.18"
@@ -0,0 +1 @@
1
+ export { default } from "@simplysm/lint/stylelint-recommended";