@simplysm/sd-cli 14.0.7 → 14.0.9

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 (265) hide show
  1. package/dist/angular/client-transform-stylesheet.d.ts.map +1 -1
  2. package/dist/angular/client-transform-stylesheet.js.map +1 -1
  3. package/dist/angular/vite-angular-plugin.d.ts.map +1 -1
  4. package/dist/angular/vite-angular-plugin.js +15 -8
  5. package/dist/angular/vite-angular-plugin.js.map +1 -1
  6. package/dist/angular/vite-postcss-inline-plugin.d.ts.map +1 -1
  7. package/dist/angular/vite-postcss-inline-plugin.js.map +1 -1
  8. package/dist/capacitor/capacitor.d.ts +1 -1
  9. package/dist/capacitor/capacitor.d.ts.map +1 -1
  10. package/dist/capacitor/capacitor.js +43 -44
  11. package/dist/capacitor/capacitor.js.map +1 -1
  12. package/dist/commands/build.d.ts.map +1 -1
  13. package/dist/commands/build.js.map +1 -1
  14. package/dist/commands/check.d.ts.map +1 -1
  15. package/dist/commands/check.js +2 -2
  16. package/dist/commands/check.js.map +1 -1
  17. package/dist/commands/dev.d.ts.map +1 -1
  18. package/dist/commands/dev.js.map +1 -1
  19. package/dist/commands/lint.d.ts.map +1 -1
  20. package/dist/commands/lint.js.map +1 -1
  21. package/dist/commands/publish.d.ts.map +1 -1
  22. package/dist/commands/publish.js +12 -13
  23. package/dist/commands/publish.js.map +1 -1
  24. package/dist/commands/replace-deps.d.ts.map +1 -1
  25. package/dist/commands/replace-deps.js.map +1 -1
  26. package/dist/commands/typecheck.d.ts.map +1 -1
  27. package/dist/commands/typecheck.js +12 -12
  28. package/dist/commands/typecheck.js.map +1 -1
  29. package/dist/commands/watch.d.ts.map +1 -1
  30. package/dist/commands/watch.js.map +1 -1
  31. package/dist/electron/electron.d.ts.map +1 -1
  32. package/dist/electron/electron.js +42 -37
  33. package/dist/electron/electron.js.map +1 -1
  34. package/dist/engines/BaseEngine.d.ts +1 -5
  35. package/dist/engines/BaseEngine.d.ts.map +1 -1
  36. package/dist/engines/BaseEngine.js +7 -16
  37. package/dist/engines/BaseEngine.js.map +1 -1
  38. package/dist/engines/NgtscEngine.d.ts.map +1 -1
  39. package/dist/engines/NgtscEngine.js +10 -11
  40. package/dist/engines/NgtscEngine.js.map +1 -1
  41. package/dist/engines/ServerEsbuildEngine.d.ts.map +1 -1
  42. package/dist/engines/ServerEsbuildEngine.js +10 -11
  43. package/dist/engines/ServerEsbuildEngine.js.map +1 -1
  44. package/dist/engines/TscEngine.d.ts.map +1 -1
  45. package/dist/engines/TscEngine.js +10 -11
  46. package/dist/engines/TscEngine.js.map +1 -1
  47. package/dist/engines/ViteEngine.d.ts.map +1 -1
  48. package/dist/engines/ViteEngine.js +3 -13
  49. package/dist/engines/ViteEngine.js.map +1 -1
  50. package/dist/engines/index.d.ts.map +1 -1
  51. package/dist/engines/index.js.map +1 -1
  52. package/dist/engines/types.d.ts +3 -6
  53. package/dist/engines/types.d.ts.map +1 -1
  54. package/dist/engines/types.js.map +1 -1
  55. package/dist/index.d.ts.map +1 -1
  56. package/dist/index.js.map +1 -1
  57. package/dist/infra/ResultCollector.d.ts +1 -1
  58. package/dist/infra/ResultCollector.d.ts.map +1 -1
  59. package/dist/infra/ResultCollector.js.map +1 -1
  60. package/dist/infra/SignalHandler.d.ts.map +1 -1
  61. package/dist/infra/SignalHandler.js.map +1 -1
  62. package/dist/infra/WorkerManager.d.ts.map +1 -1
  63. package/dist/infra/WorkerManager.js.map +1 -1
  64. package/dist/orchestrators/BuildOrchestrator.d.ts.map +1 -1
  65. package/dist/orchestrators/BuildOrchestrator.js +30 -61
  66. package/dist/orchestrators/BuildOrchestrator.js.map +1 -1
  67. package/dist/orchestrators/DevWatchOrchestrator.d.ts +2 -0
  68. package/dist/orchestrators/DevWatchOrchestrator.d.ts.map +1 -1
  69. package/dist/orchestrators/DevWatchOrchestrator.js +40 -44
  70. package/dist/orchestrators/DevWatchOrchestrator.js.map +1 -1
  71. package/dist/sd-cli-entry.d.ts.map +1 -1
  72. package/dist/sd-cli-entry.js +2 -13
  73. package/dist/sd-cli-entry.js.map +1 -1
  74. package/dist/sd-cli.d.ts.map +1 -1
  75. package/dist/sd-cli.js +5 -5
  76. package/dist/sd-cli.js.map +1 -1
  77. package/dist/sd-config.types.d.ts.map +1 -1
  78. package/dist/sd-config.types.js.map +1 -1
  79. package/dist/utils/SdCliReporter.d.ts +18 -0
  80. package/dist/utils/SdCliReporter.d.ts.map +1 -0
  81. package/dist/utils/SdCliReporter.js +144 -0
  82. package/dist/utils/SdCliReporter.js.map +1 -0
  83. package/dist/utils/angular-build.d.ts.map +1 -1
  84. package/dist/utils/angular-build.js.map +1 -1
  85. package/dist/utils/angular-compiler.d.ts.map +1 -1
  86. package/dist/utils/angular-compiler.js +11 -4
  87. package/dist/utils/angular-compiler.js.map +1 -1
  88. package/dist/utils/build-env.d.ts.map +1 -1
  89. package/dist/utils/build-env.js +2 -1
  90. package/dist/utils/build-env.js.map +1 -1
  91. package/dist/utils/concurrency.d.ts.map +1 -1
  92. package/dist/utils/concurrency.js.map +1 -1
  93. package/dist/utils/copy-public.d.ts.map +1 -1
  94. package/dist/utils/copy-public.js +21 -21
  95. package/dist/utils/copy-public.js.map +1 -1
  96. package/dist/utils/copy-src.d.ts.map +1 -1
  97. package/dist/utils/copy-src.js +12 -12
  98. package/dist/utils/copy-src.js.map +1 -1
  99. package/dist/utils/diagnostic-utils.d.ts.map +1 -1
  100. package/dist/utils/diagnostic-utils.js +3 -2
  101. package/dist/utils/diagnostic-utils.js.map +1 -1
  102. package/dist/utils/engine-stop.d.ts.map +1 -1
  103. package/dist/utils/engine-stop.js.map +1 -1
  104. package/dist/utils/esbuild-config.d.ts.map +1 -1
  105. package/dist/utils/esbuild-config.js +2 -0
  106. package/dist/utils/esbuild-config.js.map +1 -1
  107. package/dist/utils/generate-pwa-icons.d.ts.map +1 -1
  108. package/dist/utils/generate-pwa-icons.js.map +1 -1
  109. package/dist/utils/hmr-candidates.d.ts.map +1 -1
  110. package/dist/utils/hmr-candidates.js.map +1 -1
  111. package/dist/utils/lint-utils.d.ts.map +1 -1
  112. package/dist/utils/lint-utils.js.map +1 -1
  113. package/dist/utils/lint-with-program.d.ts.map +1 -1
  114. package/dist/utils/lint-with-program.js +7 -3
  115. package/dist/utils/lint-with-program.js.map +1 -1
  116. package/dist/utils/ngtsc-build-core.d.ts +2 -10
  117. package/dist/utils/ngtsc-build-core.d.ts.map +1 -1
  118. package/dist/utils/ngtsc-build-core.js +16 -15
  119. package/dist/utils/ngtsc-build-core.js.map +1 -1
  120. package/dist/utils/orchestrator-utils.d.ts.map +1 -1
  121. package/dist/utils/orchestrator-utils.js.map +1 -1
  122. package/dist/utils/output-path-rewriter.d.ts.map +1 -1
  123. package/dist/utils/output-path-rewriter.js +7 -7
  124. package/dist/utils/output-path-rewriter.js.map +1 -1
  125. package/dist/utils/output-utils.d.ts.map +1 -1
  126. package/dist/utils/output-utils.js +1 -1
  127. package/dist/utils/output-utils.js.map +1 -1
  128. package/dist/utils/package-utils.d.ts +4 -0
  129. package/dist/utils/package-utils.d.ts.map +1 -1
  130. package/dist/utils/package-utils.js +34 -13
  131. package/dist/utils/package-utils.js.map +1 -1
  132. package/dist/utils/rebuild-manager.d.ts +1 -1
  133. package/dist/utils/rebuild-manager.d.ts.map +1 -1
  134. package/dist/utils/rebuild-manager.js +3 -1
  135. package/dist/utils/rebuild-manager.js.map +1 -1
  136. package/dist/utils/replace-deps.d.ts.map +1 -1
  137. package/dist/utils/replace-deps.js +10 -10
  138. package/dist/utils/replace-deps.js.map +1 -1
  139. package/dist/utils/scss-compiler.d.ts.map +1 -1
  140. package/dist/utils/scss-compiler.js.map +1 -1
  141. package/dist/utils/sd-config.d.ts.map +1 -1
  142. package/dist/utils/sd-config.js +2 -3
  143. package/dist/utils/sd-config.js.map +1 -1
  144. package/dist/utils/tsc-build.d.ts +3 -1
  145. package/dist/utils/tsc-build.d.ts.map +1 -1
  146. package/dist/utils/tsc-build.js +7 -4
  147. package/dist/utils/tsc-build.js.map +1 -1
  148. package/dist/utils/tsconfig.d.ts.map +1 -1
  149. package/dist/utils/tsconfig.js.map +1 -1
  150. package/dist/utils/typecheck-non-package.d.ts.map +1 -1
  151. package/dist/utils/typecheck-non-package.js +10 -5
  152. package/dist/utils/typecheck-non-package.js.map +1 -1
  153. package/dist/utils/typecheck-serialization.d.ts.map +1 -1
  154. package/dist/utils/typecheck-serialization.js.map +1 -1
  155. package/dist/utils/vite-config.d.ts.map +1 -1
  156. package/dist/utils/vite-config.js +2 -1
  157. package/dist/utils/vite-config.js.map +1 -1
  158. package/dist/utils/vite-scope-watch-plugin.d.ts.map +1 -1
  159. package/dist/utils/vite-scope-watch-plugin.js.map +1 -1
  160. package/dist/utils/worker-events.d.ts +1 -1
  161. package/dist/utils/worker-events.d.ts.map +1 -1
  162. package/dist/utils/worker-events.js +1 -0
  163. package/dist/utils/worker-events.js.map +1 -1
  164. package/dist/utils/worker-utils.d.ts +1 -1
  165. package/dist/utils/worker-utils.d.ts.map +1 -1
  166. package/dist/utils/worker-utils.js +3 -1
  167. package/dist/utils/worker-utils.js.map +1 -1
  168. package/dist/vitest-plugin.d.ts.map +1 -1
  169. package/dist/vitest-plugin.js +2 -0
  170. package/dist/vitest-plugin.js.map +1 -1
  171. package/dist/workers/client.worker.d.ts.map +1 -1
  172. package/dist/workers/client.worker.js +4 -0
  173. package/dist/workers/client.worker.js.map +1 -1
  174. package/dist/workers/library-build.worker.d.ts +2 -10
  175. package/dist/workers/library-build.worker.d.ts.map +1 -1
  176. package/dist/workers/library-build.worker.js +38 -14
  177. package/dist/workers/library-build.worker.js.map +1 -1
  178. package/dist/workers/lint.worker.d.ts.map +1 -1
  179. package/dist/workers/lint.worker.js.map +1 -1
  180. package/dist/workers/ngtsc-build.worker.d.ts.map +1 -1
  181. package/dist/workers/ngtsc-build.worker.js +40 -14
  182. package/dist/workers/ngtsc-build.worker.js.map +1 -1
  183. package/dist/workers/server-build.worker.d.ts +2 -10
  184. package/dist/workers/server-build.worker.d.ts.map +1 -1
  185. package/dist/workers/server-build.worker.js +30 -22
  186. package/dist/workers/server-build.worker.js.map +1 -1
  187. package/dist/workers/server-runtime.worker.d.ts.map +1 -1
  188. package/dist/workers/server-runtime.worker.js.map +1 -1
  189. package/package.json +4 -5
  190. package/src/angular/vite-angular-plugin.ts +18 -9
  191. package/src/capacitor/capacitor.ts +43 -44
  192. package/src/commands/check.ts +2 -2
  193. package/src/commands/publish.ts +12 -13
  194. package/src/commands/typecheck.ts +12 -12
  195. package/src/electron/electron.ts +44 -38
  196. package/src/engines/BaseEngine.ts +8 -19
  197. package/src/engines/NgtscEngine.ts +11 -11
  198. package/src/engines/ServerEsbuildEngine.ts +11 -11
  199. package/src/engines/TscEngine.ts +11 -11
  200. package/src/engines/ViteEngine.ts +3 -14
  201. package/src/engines/types.ts +3 -6
  202. package/src/infra/ResultCollector.ts +1 -1
  203. package/src/orchestrators/BuildOrchestrator.ts +31 -62
  204. package/src/orchestrators/DevWatchOrchestrator.ts +41 -44
  205. package/src/sd-cli-entry.ts +2 -12
  206. package/src/sd-cli.ts +8 -5
  207. package/src/utils/SdCliReporter.ts +177 -0
  208. package/src/utils/angular-compiler.ts +11 -4
  209. package/src/utils/build-env.ts +2 -1
  210. package/src/utils/copy-public.ts +21 -21
  211. package/src/utils/copy-src.ts +12 -12
  212. package/src/utils/diagnostic-utils.ts +3 -2
  213. package/src/utils/esbuild-config.ts +2 -0
  214. package/src/utils/lint-with-program.ts +7 -3
  215. package/src/utils/ngtsc-build-core.ts +18 -18
  216. package/src/utils/output-path-rewriter.ts +7 -7
  217. package/src/utils/output-utils.ts +1 -1
  218. package/src/utils/package-utils.ts +37 -13
  219. package/src/utils/rebuild-manager.ts +4 -2
  220. package/src/utils/replace-deps.ts +10 -10
  221. package/src/utils/sd-config.ts +2 -3
  222. package/src/utils/tsc-build.ts +9 -4
  223. package/src/utils/typecheck-non-package.ts +10 -5
  224. package/src/utils/vite-config.ts +2 -1
  225. package/src/utils/worker-events.ts +2 -1
  226. package/src/utils/worker-utils.ts +3 -1
  227. package/src/vitest-plugin.ts +5 -0
  228. package/src/workers/client.worker.ts +4 -0
  229. package/src/workers/library-build.worker.ts +48 -18
  230. package/src/workers/ngtsc-build.worker.ts +48 -13
  231. package/src/workers/server-build.worker.ts +32 -26
  232. package/tests/angular/vite-angular-plugin-hmr-fallback.spec.ts +11 -7
  233. package/tests/angular/vite-angular-plugin-lint.spec.ts +6 -1
  234. package/tests/capacitor/capacitor-build.spec.ts +14 -7
  235. package/tests/capacitor/capacitor-icon.spec.ts +14 -7
  236. package/tests/capacitor/capacitor-init.spec.ts +13 -6
  237. package/tests/capacitor/capacitor-run.spec.ts +18 -11
  238. package/tests/capacitor/capacitor-workspace.spec.ts +13 -6
  239. package/tests/commands/check.spec.ts +5 -2
  240. package/tests/commands/publish.spec.ts +4 -4
  241. package/tests/commands/typecheck.spec.ts +20 -31
  242. package/tests/electron/electron.spec.ts +32 -23
  243. package/tests/engines/base-engine.spec.ts +15 -21
  244. package/tests/engines/engine-lint-integration.spec.ts +5 -10
  245. package/tests/engines/ngtsc-engine.spec.ts +27 -41
  246. package/tests/engines/server-esbuild-engine.spec.ts +18 -29
  247. package/tests/engines/tsc-engine.spec.ts +14 -23
  248. package/tests/engines/vite-engine.spec.ts +10 -15
  249. package/tests/infra/result-collector.spec.ts +2 -2
  250. package/tests/orchestrators/build-orchestrator.spec.ts +19 -29
  251. package/tests/orchestrators/dev-watch-orchestrator.spec.ts +110 -95
  252. package/tests/utils/copy-src.spec.ts +25 -19
  253. package/tests/utils/diagnostic-utils.spec.ts +72 -0
  254. package/tests/utils/ngtsc-build-core-angular-compiler.spec.ts +2 -3
  255. package/tests/utils/output-path-rewriter.spec.ts +7 -6
  256. package/tests/utils/output-utils.spec.ts +5 -5
  257. package/tests/utils/rebuild-manager.spec.ts +1 -1
  258. package/tests/utils/sd-config.spec.ts +4 -0
  259. package/tests/utils/tsc-build.spec.ts +23 -5
  260. package/tests/workers/library-build-worker.spec.ts +113 -20
  261. package/tests/workers/ngtsc-build-lint.spec.ts +3 -6
  262. package/tests/workers/ngtsc-build-worker.spec.ts +11 -13
  263. package/tests/workers/server-build-lint.spec.ts +4 -1
  264. package/tests/workers/server-build-worker.spec.ts +25 -25
  265. package/tests/angular/migration-cleanup.spec.ts +0 -59
@@ -2,6 +2,7 @@ import path from "path";
2
2
  import { createHash } from "crypto";
3
3
  import ts from "typescript";
4
4
  import { consola } from "consola";
5
+ import { pathx } from "@simplysm/core-node";
5
6
  import { NgtscProgram, OptimizeFor } from "./angular-build";
6
7
  import { collectHmrCandidates } from "./hmr-candidates.js";
7
8
 
@@ -67,7 +68,7 @@ export class AngularSourceFileCache extends Map<string, ts.SourceFile> {
67
68
 
68
69
  invalidate(files: Iterable<string>): void {
69
70
  for (const file of files) {
70
- const normalized = file.replace(/\\/g, "/");
71
+ const normalized = pathx.posix(file);
71
72
  this.delete(normalized);
72
73
  this.modifiedFiles.add(normalized);
73
74
  }
@@ -312,7 +313,7 @@ export class AngularCompiler {
312
313
  }
313
314
  const sf = node.getSourceFile();
314
315
  let relativePath = path.relative(host.getCurrentDirectory(), sf.fileName);
315
- relativePath = relativePath.replace(/\\/g, "/");
316
+ relativePath = pathx.posix(relativePath);
316
317
 
317
318
  const updateId = encodeURIComponent(
318
319
  `${host.getCanonicalFileName(relativePath)}@${node.name?.text}`,
@@ -352,6 +353,7 @@ export class AngularCompiler {
352
353
  angularCompiler: NgCompiler,
353
354
  sourceFileCache?: AngularSourceFileCache,
354
355
  ): Set<ts.SourceFile> {
356
+ logger.debug("affected 파일 탐색 시작");
355
357
  const affectedFiles = new Set<ts.SourceFile>();
356
358
 
357
359
  while (true) {
@@ -393,7 +395,7 @@ export class AngularCompiler {
393
395
  // modifiedFiles의 경로를 정규화한 Set 생성 (Windows backslash 대응)
394
396
  const normalizedModifiedFiles = new Set<string>();
395
397
  for (const f of sourceFileCache.modifiedFiles) {
396
- normalizedModifiedFiles.add(f.replace(/\\/g, "/"));
398
+ normalizedModifiedFiles.add(pathx.posix(f));
397
399
  }
398
400
 
399
401
  for (const sourceFile of builderProgram.getSourceFiles()) {
@@ -402,7 +404,7 @@ export class AngularCompiler {
402
404
  }
403
405
  const resourceDependencies = angularCompiler.getResourceDependencies(sourceFile);
404
406
  for (const resourceDep of resourceDependencies) {
405
- if (normalizedModifiedFiles.has(resourceDep.replace(/\\/g, "/"))) {
407
+ if (normalizedModifiedFiles.has(pathx.posix(resourceDep))) {
406
408
  this._diagnosticCache.delete(sourceFile);
407
409
  affectedFiles.add(sourceFile);
408
410
  break;
@@ -411,6 +413,7 @@ export class AngularCompiler {
411
413
  }
412
414
  }
413
415
 
416
+ logger.debug(`affected 파일 탐색 완료 (${affectedFiles.size}개)`);
414
417
  return affectedFiles;
415
418
  }
416
419
 
@@ -420,6 +423,7 @@ export class AngularCompiler {
420
423
  affectedFiles: ReadonlySet<ts.SourceFile>;
421
424
  templateUpdates?: Map<string, string>;
422
425
  }> {
426
+ logger.debug("증분 업데이트 시작");
423
427
  const sourceFileCache = this._options.sourceFileCache;
424
428
  if (sourceFileCache == null) {
425
429
  throw new Error("sourceFileCache가 없으면 incremental rebuild를 수행할 수 없습니다");
@@ -432,6 +436,7 @@ export class AngularCompiler {
432
436
  if (this._ngtscProgram == null || this._builderProgram == null) {
433
437
  throw new Error("initialize()를 먼저 호출해야 합니다");
434
438
  }
439
+ logger.debug("emitAffectedFiles 시작");
435
440
 
436
441
  const compilerOptions = this._builderProgram.getCompilerOptions();
437
442
 
@@ -519,6 +524,7 @@ export class AngularCompiler {
519
524
  }
520
525
 
521
526
  // 7. sourceFilter 적용 후 yield
527
+ logger.debug(`emitAffectedFiles 완료 (${emitResults.length}개 파일)`);
522
528
  for (const result of emitResults) {
523
529
  if (options?.sourceFilter != null && !options.sourceFilter(result.sourceFileName)) {
524
530
  continue;
@@ -531,6 +537,7 @@ export class AngularCompiler {
531
537
  if (this._ngtscProgram == null || this._builderProgram == null) {
532
538
  throw new Error("initialize()를 먼저 호출해야 합니다");
533
539
  }
540
+ logger.debug("진단 수집 시작");
534
541
 
535
542
  const angularCompiler = this._ngtscProgram.compiler;
536
543
  const builderProgram = this._builderProgram;
@@ -1,11 +1,12 @@
1
1
  import path from "path";
2
2
  import fs from "fs/promises";
3
+ import { pathx } from "@simplysm/core-node";
3
4
 
4
5
  /**
5
6
  * Get version from root package.json
6
7
  */
7
8
  export async function getVersion(cwd: string): Promise<string> {
8
- const pkgJsonPath = path.join(cwd, "package.json");
9
+ const pkgJsonPath = pathx.posix(path.join(cwd, "package.json"));
9
10
  const pkgJsonContent = await fs.readFile(pkgJsonPath, "utf-8");
10
11
  const pkgJson = JSON.parse(pkgJsonContent) as { version?: string };
11
12
  return pkgJson.version ?? "0.0.0";
@@ -13,18 +13,18 @@ import {
13
13
  * @param includeDev Whether to include public-dev/ (true only in dev mode)
14
14
  */
15
15
  export async function copyPublicFiles(pkgDir: string, includeDev: boolean): Promise<void> {
16
- const distDir = path.join(pkgDir, "dist");
16
+ const distDir = pathx.posix(path.join(pkgDir, "dist"));
17
17
  await fsx.mkdir(distDir);
18
18
 
19
19
  // Copy public/
20
- const publicDir = path.join(pkgDir, "public");
20
+ const publicDir = pathx.posix(path.join(pkgDir, "public"));
21
21
  if (await fsx.exists(publicDir)) {
22
22
  const files = await fsx.glob("**/*", { cwd: publicDir, absolute: true });
23
23
  await Promise.all(
24
24
  files.map(async (file) => {
25
- const relativePath = path.relative(publicDir, file);
26
- const distPath = path.join(distDir, relativePath);
27
- await fsx.mkdir(path.dirname(distPath));
25
+ const relativePath = pathx.posix(path.relative(publicDir, file));
26
+ const distPath = pathx.posix(path.join(distDir, relativePath));
27
+ await fsx.mkdir(pathx.posix(path.dirname(distPath)));
28
28
  await fsx.copy(file, distPath);
29
29
  }),
30
30
  );
@@ -32,14 +32,14 @@ export async function copyPublicFiles(pkgDir: string, includeDev: boolean): Prom
32
32
 
33
33
  // Copy public-dev/ (overlay: overwrites public/)
34
34
  if (includeDev) {
35
- const publicDevDir = path.join(pkgDir, "public-dev");
35
+ const publicDevDir = pathx.posix(path.join(pkgDir, "public-dev"));
36
36
  if (await fsx.exists(publicDevDir)) {
37
37
  const files = await fsx.glob("**/*", { cwd: publicDevDir, absolute: true });
38
38
  await Promise.all(
39
39
  files.map(async (file) => {
40
- const relativePath = path.relative(publicDevDir, file);
41
- const distPath = path.join(distDir, relativePath);
42
- await fsx.mkdir(path.dirname(distPath));
40
+ const relativePath = pathx.posix(path.relative(publicDevDir, file));
41
+ const distPath = pathx.posix(path.join(distDir, relativePath));
42
+ await fsx.mkdir(pathx.posix(path.dirname(distPath)));
43
43
  await fsx.copy(file, distPath);
44
44
  }),
45
45
  );
@@ -59,9 +59,9 @@ export async function watchPublicFiles(
59
59
  pkgDir: string,
60
60
  includeDev: boolean,
61
61
  ): Promise<FsWatcher | undefined> {
62
- const distDir = path.join(pkgDir, "dist");
63
- const publicDir = path.join(pkgDir, "public");
64
- const publicDevDir = path.join(pkgDir, "public-dev");
62
+ const distDir = pathx.posix(path.join(pkgDir, "dist"));
63
+ const publicDir = pathx.posix(path.join(pkgDir, "public"));
64
+ const publicDevDir = pathx.posix(path.join(pkgDir, "public-dev"));
65
65
 
66
66
  // Initial copy
67
67
  await copyPublicFiles(pkgDir, includeDev);
@@ -69,10 +69,10 @@ export async function watchPublicFiles(
69
69
  // Collect watch target paths
70
70
  const watchPaths: string[] = [];
71
71
  if (await fsx.exists(publicDir)) {
72
- watchPaths.push(path.join(publicDir, "**/*"));
72
+ watchPaths.push(pathx.posix(path.join(publicDir, "**/*")));
73
73
  }
74
74
  if (includeDev && (await fsx.exists(publicDevDir))) {
75
- watchPaths.push(path.join(publicDevDir, "**/*"));
75
+ watchPaths.push(pathx.posix(path.join(publicDevDir, "**/*")));
76
76
  }
77
77
 
78
78
  if (watchPaths.length === 0) {
@@ -91,22 +91,22 @@ export async function watchPublicFiles(
91
91
  sourceDir = publicDir;
92
92
  }
93
93
 
94
- const relPath = path.relative(sourceDir, filePath);
95
- const distPath = path.join(distDir, relPath);
94
+ const relPath = pathx.posix(path.relative(sourceDir, filePath));
95
+ const distPath = pathx.posix(path.join(distDir, relPath));
96
96
 
97
97
  if (event === "unlink") {
98
98
  // If deleted from public, don't delete if same file exists in public-dev
99
99
  if (sourceDir === publicDir && includeDev) {
100
- const devOverride = path.join(publicDevDir, relPath);
100
+ const devOverride = pathx.posix(path.join(publicDevDir, relPath));
101
101
  if (await fsx.exists(devOverride)) {
102
102
  continue;
103
103
  }
104
104
  }
105
105
  // If deleted from public-dev, restore from public if it exists (fallback restore)
106
106
  if (sourceDir === publicDevDir && includeDev) {
107
- const publicFallback = path.join(publicDir, relPath);
107
+ const publicFallback = pathx.posix(path.join(publicDir, relPath));
108
108
  if (await fsx.exists(publicFallback)) {
109
- await fsx.mkdir(path.dirname(distPath));
109
+ await fsx.mkdir(pathx.posix(path.dirname(distPath)));
110
110
  await fsx.copy(publicFallback, distPath);
111
111
  continue;
112
112
  }
@@ -115,12 +115,12 @@ export async function watchPublicFiles(
115
115
  } else if (event === "add" || event === "change") {
116
116
  // If changed in public, skip if same file exists in public-dev (overlay takes priority)
117
117
  if (sourceDir === publicDir && includeDev) {
118
- const devOverride = path.join(publicDevDir, relPath);
118
+ const devOverride = pathx.posix(path.join(publicDevDir, relPath));
119
119
  if (await fsx.exists(devOverride)) {
120
120
  continue;
121
121
  }
122
122
  }
123
- await fsx.mkdir(path.dirname(distPath));
123
+ await fsx.mkdir(pathx.posix(path.dirname(distPath)));
124
124
  await fsx.copy(filePath, distPath);
125
125
  }
126
126
  }
@@ -1,5 +1,5 @@
1
1
  import path from "path";
2
- import { fsx, FsWatcher } from "@simplysm/core-node";
2
+ import { fsx, pathx, FsWatcher } from "@simplysm/core-node";
3
3
 
4
4
  /**
5
5
  * Copy files matching glob patterns from src/ to dist/
@@ -9,16 +9,16 @@ import { fsx, FsWatcher } from "@simplysm/core-node";
9
9
  * @param patterns Array of glob patterns (relative to src/)
10
10
  */
11
11
  export async function copySrcFiles(pkgDir: string, patterns: string[]): Promise<void> {
12
- const srcDir = path.join(pkgDir, "src");
13
- const distDir = path.join(pkgDir, "dist");
12
+ const srcDir = pathx.posix(path.join(pkgDir, "src"));
13
+ const distDir = pathx.posix(path.join(pkgDir, "dist"));
14
14
 
15
15
  for (const pattern of patterns) {
16
16
  const files = await fsx.glob(pattern, { cwd: srcDir, absolute: true });
17
17
  await Promise.all(
18
18
  files.map(async (file) => {
19
- const relativePath = path.relative(srcDir, file);
20
- const distPath = path.join(distDir, relativePath);
21
- await fsx.mkdir(path.dirname(distPath));
19
+ const relativePath = pathx.posix(path.relative(srcDir, file));
20
+ const distPath = pathx.posix(path.join(distDir, relativePath));
21
+ await fsx.mkdir(pathx.posix(path.dirname(distPath)));
22
22
  await fsx.copy(file, distPath);
23
23
  }),
24
24
  );
@@ -34,25 +34,25 @@ export async function copySrcFiles(pkgDir: string, patterns: string[]): Promise<
34
34
  * @returns FsWatcher instance (call close() on shutdown)
35
35
  */
36
36
  export async function watchCopySrcFiles(pkgDir: string, patterns: string[]): Promise<FsWatcher> {
37
- const srcDir = path.join(pkgDir, "src");
38
- const distDir = path.join(pkgDir, "dist");
37
+ const srcDir = pathx.posix(path.join(pkgDir, "src"));
38
+ const distDir = pathx.posix(path.join(pkgDir, "dist"));
39
39
 
40
40
  // Initial copy
41
41
  await copySrcFiles(pkgDir, patterns);
42
42
 
43
43
  // Start watch
44
- const watchPaths = patterns.map((p) => path.join(srcDir, p));
44
+ const watchPaths = patterns.map((p) => pathx.posix(path.join(srcDir, p)));
45
45
  const watcher = await FsWatcher.watch(watchPaths);
46
46
 
47
47
  watcher.onChange({ delay: 300 }, async (changes) => {
48
48
  for (const { event, path: filePath } of changes) {
49
- const relPath = path.relative(srcDir, filePath);
50
- const distPath = path.join(distDir, relPath);
49
+ const relPath = pathx.posix(path.relative(srcDir, filePath));
50
+ const distPath = pathx.posix(path.join(distDir, relPath));
51
51
 
52
52
  if (event === "unlink") {
53
53
  await fsx.rm(distPath);
54
54
  } else if (event === "add" || event === "change") {
55
- await fsx.mkdir(path.dirname(distPath));
55
+ await fsx.mkdir(pathx.posix(path.dirname(distPath)));
56
56
  await fsx.copy(filePath, distPath);
57
57
  }
58
58
  }
@@ -1,4 +1,5 @@
1
1
  import ts from "typescript";
2
+ import { pathx } from "@simplysm/core-node";
2
3
 
3
4
  /**
4
5
  * 워크스페이스 스코프 진단 필터.
@@ -8,8 +9,8 @@ import ts from "typescript";
8
9
  export function isWorkspaceDiagnostic(diagnostic: ts.Diagnostic, cwd: string): boolean {
9
10
  if (diagnostic.file == null) return true;
10
11
 
11
- const normalized = diagnostic.file.fileName.replace(/\\/g, "/");
12
- const normalizedCwd = cwd.replace(/\\/g, "/").replace(/\/$/, "");
12
+ const normalized = pathx.posix(diagnostic.file.fileName);
13
+ const normalizedCwd = pathx.posix(cwd).replace(/\/$/, "");
13
14
  return normalized.startsWith(normalizedCwd + "/") && !normalized.includes("/node_modules/");
14
15
  }
15
16
 
@@ -15,6 +15,7 @@ const logger = consola.withTag("sd:cli:esbuild-config");
15
15
  * - Skip writing if content matches existing file to preserve timestamps
16
16
  */
17
17
  export async function writeChangedOutputFiles(outputFiles: esbuild.OutputFile[]): Promise<boolean> {
18
+ logger.debug(`변경된 출력 파일 쓰기 시작 (${outputFiles.length}개)`);
18
19
  let hasChanges = false;
19
20
  await Promise.all(
20
21
  outputFiles.map(async (file) => {
@@ -40,6 +41,7 @@ export async function writeChangedOutputFiles(outputFiles: esbuild.OutputFile[])
40
41
  await fs.writeFile(file.path, finalText);
41
42
  }),
42
43
  );
44
+ logger.debug(`변경된 출력 파일 쓰기 완료 (변경: ${String(hasChanges)})`);
43
45
  return hasChanges;
44
46
  }
45
47
 
@@ -1,6 +1,7 @@
1
1
  import path from "path";
2
2
  import type ts from "typescript";
3
3
  import { ESLint } from "eslint";
4
+ import { pathx } from "@simplysm/core-node";
4
5
  import { consola } from "consola";
5
6
 
6
7
  const logger = consola.withTag("sd:cli:lint-with-program");
@@ -58,11 +59,12 @@ export class LintWithProgramRunner {
58
59
  * Includes all workspace source files (cwd scope), excludes .d.ts, node_modules, and Angular shims.
59
60
  */
60
61
  private _extractFiles(program: ts.Program): string[] {
61
- const normalizedCwd = this._cwd.replace(/\\/g, "/");
62
+ logger.debug(`[${this._pkgName}] 린트 대상 파일 추출 시작`);
63
+ const normalizedCwd = pathx.posix(this._cwd);
62
64
  const files: string[] = [];
63
65
 
64
66
  for (const sf of program.getSourceFiles()) {
65
- const fileName = sf.fileName.replace(/\\/g, "/");
67
+ const fileName = pathx.posix(sf.fileName);
66
68
 
67
69
  // Must be within workspace root
68
70
  if (!fileName.startsWith(normalizedCwd + "/")) {
@@ -87,6 +89,7 @@ export class LintWithProgramRunner {
87
89
  files.push(sf.fileName);
88
90
  }
89
91
 
92
+ logger.debug(`[${this._pkgName}] 린트 대상 파일 추출 완료 (${files.length}개)`);
90
93
  return files;
91
94
  }
92
95
 
@@ -103,7 +106,7 @@ export class LintWithProgramRunner {
103
106
 
104
107
  // When affectedFiles is provided, intersect with extracted files
105
108
  if (affectedFiles != null) {
106
- files = files.filter((f) => affectedFiles.has(f.replace(/\\/g, "/")));
109
+ files = files.filter((f) => affectedFiles.has(pathx.posix(f)));
107
110
  }
108
111
 
109
112
  if (files.length === 0) {
@@ -127,6 +130,7 @@ export class LintWithProgramRunner {
127
130
 
128
131
  // Create new ESLint instance when cache policy changes or on first call
129
132
  if (this._eslint == null || this._lastUseCache !== useCache) {
133
+ logger.debug(`[${this._pkgName}] ESLint 인스턴스 생성 (cache: ${String(useCache)})`);
130
134
  // ESLint Flat Config serializes languageOptions via languageOptionsToJSON(),
131
135
  // which recurses into parserOptions and throws on ts.Program methods.
132
136
  // Adding toJSON() to parserOptions returns a serializable representation
@@ -2,6 +2,7 @@ import path from "path";
2
2
  import fs from "fs";
3
3
  import ts from "typescript";
4
4
  import { err as errNs } from "@simplysm/core-common";
5
+ import { pathx } from "@simplysm/core-node";
5
6
  import { consola } from "consola";
6
7
 
7
8
  const logger = consola.withTag("sd:cli:ngtsc-build");
@@ -12,6 +13,7 @@ import type { LintWithProgramResult } from "./lint-with-program";
12
13
  import {
13
14
  parseTsconfig,
14
15
  getPackageSourceFiles,
16
+ getPackageFiles,
15
17
  getCompilerOptionsForEnv,
16
18
  type TypecheckEnv,
17
19
  } from "./tsconfig";
@@ -34,8 +36,7 @@ export interface NgtscBuildInfo {
34
36
  }
35
37
 
36
38
  export interface NgtscBuildResult {
37
- js: { success: boolean; errors?: string[]; warnings?: string[] };
38
- dts: { success: boolean; errors?: string[]; diagnostics: SerializedDiagnostic[] };
39
+ build: { success: boolean; errors?: string[]; warnings?: string[]; diagnostics: SerializedDiagnostic[] };
39
40
  lint?: LintWithProgramResult;
40
41
  }
41
42
 
@@ -45,8 +46,7 @@ export interface NgtscBuildInternalResult extends NgtscBuildResult {
45
46
  }
46
47
 
47
48
  export interface NgtscCombinedBuildEvent {
48
- js: { success: boolean; errors?: string[]; warnings?: string[] };
49
- dts: { success: boolean; errors?: string[] };
49
+ build: { success: boolean; errors?: string[]; warnings?: string[] };
50
50
  lint?: LintWithProgramResult;
51
51
  }
52
52
 
@@ -192,6 +192,7 @@ export function writeEmitResults(
192
192
  pkgDir: string,
193
193
  scss?: SideEffectScssOptions,
194
194
  ): void {
195
+ logger.debug("emit 결과 파일 쓰기 시작");
195
196
  const rewritePath = createOutputPathRewriter(pkgDir);
196
197
  for (const { filename, contents, sourceFileName } of emitResults) {
197
198
  const rewrite = rewritePath(filename, contents);
@@ -241,6 +242,7 @@ export function writeEmitResults(
241
242
  fs.mkdirSync(path.dirname(newPath), { recursive: true });
242
243
  fs.writeFileSync(newPath, newContent, "utf-8");
243
244
  }
245
+ logger.debug("emit 결과 파일 쓰기 완료");
244
246
  }
245
247
 
246
248
  //#region Side-effect SCSS
@@ -256,6 +258,7 @@ export function compileSideEffectScss(
256
258
  scssErrors: string[],
257
259
  scssDependencies: Map<string, Set<string>>,
258
260
  ): void {
261
+ logger.debug(`side-effect SCSS 컴파일 시작 (${registry.size}개)`);
259
262
  for (const entry of registry.values()) {
260
263
  try {
261
264
  const result = compileScssFile(entry.scssAbsPath, loadPaths);
@@ -266,6 +269,7 @@ export function compileSideEffectScss(
266
269
  scssErrors.push(formatScssError(err, entry.scssAbsPath));
267
270
  }
268
271
  }
272
+ logger.debug("side-effect SCSS 컴파일 완료");
269
273
  }
270
274
 
271
275
  //#endregion
@@ -278,6 +282,7 @@ export function compileGlobalScss(
278
282
  ): string[] {
279
283
  const stylesPath = path.join(pkgDir, "scss", "styles.scss");
280
284
  if (!fs.existsSync(stylesPath)) return [];
285
+ logger.debug("global SCSS 컴파일 시작");
281
286
 
282
287
  const errors: string[] = [];
283
288
  try {
@@ -288,6 +293,7 @@ export function compileGlobalScss(
288
293
  } catch (err) {
289
294
  errors.push(`Global SCSS error: ${errNs.message(err)}`);
290
295
  }
296
+ logger.debug("global SCSS 컴파일 완료");
291
297
  return errors;
292
298
  }
293
299
 
@@ -302,7 +308,9 @@ export async function runNgtscBuild(info: NgtscBuildInfo): Promise<NgtscBuildInt
302
308
  logger.debug(`[${info.name}] ngtsc 빌드 시작 (env: ${info.env ?? "none"}, js: ${info.output.js}, dts: ${info.output.dts})`);
303
309
 
304
310
  const parsedConfig = parseTsconfig(info.pkgDir);
305
- const sourceFiles = getPackageSourceFiles(info.pkgDir, parsedConfig);
311
+ const sourceFiles = info.output.includeTests === true
312
+ ? getPackageFiles(info.pkgDir, parsedConfig)
313
+ : getPackageSourceFiles(info.pkgDir, parsedConfig);
306
314
  logger.debug(`[${info.name}] rootNames: ${sourceFiles.length}개 파일`);
307
315
 
308
316
  const baseOptions =
@@ -311,12 +319,9 @@ export async function runNgtscBuild(info: NgtscBuildInfo): Promise<NgtscBuildInt
311
319
  : parsedConfig.options;
312
320
  const compilerOptions = buildCompilerOptions(baseOptions, info.pkgDir, info.output);
313
321
  const pkgSrcDir = path.join(info.pkgDir, "src");
314
- const normalizedSrcDir = pkgSrcDir.replace(/\\/g, "/");
322
+ const normalizedSrcDir = pathx.posix(pkgSrcDir);
315
323
 
316
- // Read angularCompilerOptions from root tsconfig
317
- const rootTsconfigPath = path.join(info.cwd, "tsconfig.json");
318
- const rootRawConfig = ts.readConfigFile(rootTsconfigPath, ts.sys.readFile);
319
- const angularOptions = rootRawConfig.config?.angularCompilerOptions ?? {};
324
+ const angularOptions = (parsedConfig.raw?.angularCompilerOptions ?? {}) as Record<string, unknown>;
320
325
 
321
326
  // SCSS closure variables
322
327
  const scssErrors: string[] = [];
@@ -355,7 +360,7 @@ export async function runNgtscBuild(info: NgtscBuildInfo): Promise<NgtscBuildInt
355
360
  // Emit via AngularCompiler + output-path-rewriting
356
361
  const emitResults = compiler.emitAffectedFiles({
357
362
  sourceFilter: (fileName: string) =>
358
- fileName.replace(/\\/g, "/").startsWith(normalizedSrcDir + "/"),
363
+ pathx.posix(fileName).startsWith(normalizedSrcDir + "/"),
359
364
  });
360
365
  writeEmitResults(emitResults, info.pkgDir, {
361
366
  loadPaths,
@@ -372,14 +377,10 @@ export async function runNgtscBuild(info: NgtscBuildInfo): Promise<NgtscBuildInt
372
377
  const buildSuccess = errorCount === 0 && scssErrors.length === 0 && globalScssErrors.length === 0;
373
378
 
374
379
  return {
375
- js: {
380
+ build: {
376
381
  success: buildSuccess,
377
382
  errors: allErrors.length > 0 ? allErrors : undefined,
378
383
  warnings: undefined,
379
- },
380
- dts: {
381
- success: buildSuccess,
382
- errors: allErrors.length > 0 ? allErrors : undefined,
383
384
  diagnostics: serialized,
384
385
  },
385
386
  program: compiler.getTsProgram(),
@@ -392,8 +393,7 @@ export async function runNgtscBuild(info: NgtscBuildInfo): Promise<NgtscBuildInt
392
393
  logger.debug(`[${info.name}] 스택 트레이스:\n${stack}`);
393
394
  }
394
395
  return {
395
- js: { success: false, errors: [message] },
396
- dts: { success: false, errors: [message], diagnostics: [] },
396
+ build: { success: false, errors: [message], diagnostics: [] },
397
397
  };
398
398
  }
399
399
  }
@@ -46,7 +46,7 @@ export function adjustMapSources(content: string, originalDir: string, newDir: s
46
46
  if (Array.isArray(map.sources)) {
47
47
  map.sources = map.sources.map((source) => {
48
48
  const absoluteSource = path.resolve(originalDir, source);
49
- return path.relative(newDir, absoluteSource);
49
+ return pathx.posix(path.relative(newDir, absoluteSource));
50
50
  });
51
51
  }
52
52
  return JSON.stringify(map);
@@ -69,19 +69,19 @@ export function createOutputPathRewriter(
69
69
  pkgDir: string,
70
70
  ): (fileName: string, content: string) => [string, string] | null {
71
71
  const pkgName = path.basename(pkgDir);
72
- const distDir = pathx.norm(path.join(pkgDir, "dist"));
73
- const distPrefix = distDir + path.sep;
72
+ const distDir = pathx.posixResolve(pkgDir, "dist");
73
+ const distPrefix = distDir + "/";
74
74
  // Nested structure prefix for this package: dist/{pkgName}/src/
75
- const ownNestedPrefix = pathx.norm(path.join(distDir, pkgName, "src")) + path.sep;
75
+ const ownNestedPrefix = pathx.posixResolve(distDir, pkgName, "src") + "/";
76
76
 
77
77
  return (fileName, content) => {
78
- fileName = pathx.norm(fileName);
78
+ fileName = pathx.posixResolve(fileName);
79
79
 
80
80
  if (!fileName.startsWith(distPrefix)) return null;
81
81
 
82
82
  if (fileName.startsWith(ownNestedPrefix)) {
83
83
  // Rewrite nested path to flat: dist/{pkgName}/src/... → dist/...
84
- const flatPath = path.join(distDir, fileName.slice(ownNestedPrefix.length));
84
+ const flatPath = pathx.posixResolve(distDir, fileName.slice(ownNestedPrefix.length));
85
85
  if (fileName.endsWith(".d.ts.map") || fileName.endsWith(".js.map")) {
86
86
  content = adjustMapSources(content, path.dirname(fileName), path.dirname(flatPath));
87
87
  }
@@ -90,7 +90,7 @@ export function createOutputPathRewriter(
90
90
 
91
91
  // Nested output from other packages (dist/{otherPkg}/src/...) → ignore
92
92
  const relFromDist = fileName.slice(distPrefix.length);
93
- const segments = relFromDist.split(path.sep);
93
+ const segments = relFromDist.split("/");
94
94
  if (segments.length >= 3 && segments[1] === "src") {
95
95
  return null;
96
96
  }
@@ -21,7 +21,7 @@ export function formatBuildMessages(name: string, label: string, messages: strin
21
21
  export function printErrors(results: Map<string, BuildResult>): void {
22
22
  for (const result of results.values()) {
23
23
  if (result.status === "error") {
24
- const typeLabel = result.type === "dts" ? "dts" : result.type === "lint" ? "lint" : result.target;
24
+ const typeLabel = result.type === "lint" ? "lint" : result.target;
25
25
  if (result.message != null && result.message !== "") {
26
26
  consola.error(formatBuildMessages(result.name, typeLabel, [result.message]));
27
27
  } else {