@simplysm/sd-cli 14.0.42 → 14.0.44

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 (338) hide show
  1. package/dist/angular/angular-compiler.d.ts +0 -35
  2. package/dist/angular/angular-compiler.d.ts.map +1 -1
  3. package/dist/angular/angular-compiler.js +0 -374
  4. package/dist/angular/angular-compiler.js.map +1 -1
  5. package/dist/angular/hmr-candidates.d.ts +13 -0
  6. package/dist/angular/hmr-candidates.d.ts.map +1 -0
  7. package/dist/angular/hmr-candidates.js +230 -0
  8. package/dist/angular/hmr-candidates.js.map +1 -0
  9. package/dist/angular/ngtsc-build-core.d.ts +41 -37
  10. package/dist/angular/ngtsc-build-core.d.ts.map +1 -1
  11. package/dist/angular/ngtsc-build-core.js +155 -52
  12. package/dist/angular/ngtsc-build-core.js.map +1 -1
  13. package/dist/angular/vite-angular-plugin.d.ts +1 -1
  14. package/dist/angular/vite-angular-plugin.d.ts.map +1 -1
  15. package/dist/angular/vite-angular-plugin.js +63 -56
  16. package/dist/angular/vite-angular-plugin.js.map +1 -1
  17. package/dist/angular/web-worker-transformer.d.ts +9 -0
  18. package/dist/angular/web-worker-transformer.d.ts.map +1 -0
  19. package/dist/angular/web-worker-transformer.js +73 -0
  20. package/dist/angular/web-worker-transformer.js.map +1 -0
  21. package/dist/capacitor/capacitor.d.ts.map +1 -1
  22. package/dist/capacitor/capacitor.js +6 -4
  23. package/dist/capacitor/capacitor.js.map +1 -1
  24. package/dist/commands/check.d.ts +1 -1
  25. package/dist/commands/check.d.ts.map +1 -1
  26. package/dist/commands/check.js +15 -65
  27. package/dist/commands/check.js.map +1 -1
  28. package/dist/commands/publish/deployment-phase.d.ts.map +1 -1
  29. package/dist/commands/publish/deployment-phase.js +13 -5
  30. package/dist/commands/publish/deployment-phase.js.map +1 -1
  31. package/dist/commands/publish/npm-publisher.js +1 -1
  32. package/dist/commands/publish/npm-publisher.js.map +1 -1
  33. package/dist/commands/publish/publish-command.js +1 -1
  34. package/dist/commands/publish/publish-command.js.map +1 -1
  35. package/dist/commands/publish/version-upgrade.d.ts.map +1 -1
  36. package/dist/commands/publish/version-upgrade.js +16 -13
  37. package/dist/commands/publish/version-upgrade.js.map +1 -1
  38. package/dist/commands/replace-deps.d.ts.map +1 -1
  39. package/dist/commands/replace-deps.js +2 -1
  40. package/dist/commands/replace-deps.js.map +1 -1
  41. package/dist/deps/replace-deps/collect-deps.d.ts.map +1 -1
  42. package/dist/deps/replace-deps/collect-deps.js +5 -2
  43. package/dist/deps/replace-deps/collect-deps.js.map +1 -1
  44. package/dist/deps/replace-deps/replace-deps-resolve.d.ts.map +1 -1
  45. package/dist/deps/replace-deps/replace-deps-resolve.js +6 -7
  46. package/dist/deps/replace-deps/replace-deps-resolve.js.map +1 -1
  47. package/dist/deps/replace-deps/replace-deps.d.ts +21 -3
  48. package/dist/deps/replace-deps/replace-deps.d.ts.map +1 -1
  49. package/dist/deps/replace-deps/replace-deps.js +175 -66
  50. package/dist/deps/replace-deps/replace-deps.js.map +1 -1
  51. package/dist/electron/electron.js +7 -7
  52. package/dist/electron/electron.js.map +1 -1
  53. package/dist/engines/BaseEngine.d.ts.map +1 -1
  54. package/dist/engines/BaseEngine.js +2 -5
  55. package/dist/engines/BaseEngine.js.map +1 -1
  56. package/dist/engines/EsbuildClientEngine.d.ts.map +1 -1
  57. package/dist/engines/EsbuildClientEngine.js +16 -9
  58. package/dist/engines/EsbuildClientEngine.js.map +1 -1
  59. package/dist/engines/NgtscEngine.d.ts +4 -4
  60. package/dist/engines/NgtscEngine.d.ts.map +1 -1
  61. package/dist/engines/NgtscEngine.js +5 -5
  62. package/dist/engines/NgtscEngine.js.map +1 -1
  63. package/dist/engines/TscEngine.d.ts.map +1 -1
  64. package/dist/engines/TscEngine.js +0 -2
  65. package/dist/engines/TscEngine.js.map +1 -1
  66. package/dist/engines/types.d.ts +2 -0
  67. package/dist/engines/types.d.ts.map +1 -1
  68. package/dist/esbuild/esbuild-angular-compiler-plugin.d.ts +36 -0
  69. package/dist/esbuild/esbuild-angular-compiler-plugin.d.ts.map +1 -0
  70. package/dist/esbuild/esbuild-angular-compiler-plugin.js +464 -0
  71. package/dist/esbuild/esbuild-angular-compiler-plugin.js.map +1 -0
  72. package/dist/esbuild/esbuild-client-config.d.ts +8 -2
  73. package/dist/esbuild/esbuild-client-config.d.ts.map +1 -1
  74. package/dist/esbuild/esbuild-client-config.js +48 -33
  75. package/dist/esbuild/esbuild-client-config.js.map +1 -1
  76. package/dist/esbuild/esbuild-postcss-plugin.d.ts.map +1 -1
  77. package/dist/esbuild/esbuild-postcss-plugin.js +9 -6
  78. package/dist/esbuild/esbuild-postcss-plugin.js.map +1 -1
  79. package/dist/esbuild/esbuild-tsc-plugin.d.ts +4 -1
  80. package/dist/esbuild/esbuild-tsc-plugin.d.ts.map +1 -1
  81. package/dist/esbuild/esbuild-tsc-plugin.js +27 -23
  82. package/dist/esbuild/esbuild-tsc-plugin.js.map +1 -1
  83. package/dist/esbuild/file-reference-tracker.d.ts +24 -0
  84. package/dist/esbuild/file-reference-tracker.d.ts.map +1 -0
  85. package/dist/esbuild/file-reference-tracker.js +57 -0
  86. package/dist/esbuild/file-reference-tracker.js.map +1 -0
  87. package/dist/esbuild/lmdb-cache-store.d.ts +18 -0
  88. package/dist/esbuild/lmdb-cache-store.d.ts.map +1 -0
  89. package/dist/esbuild/lmdb-cache-store.js +41 -0
  90. package/dist/esbuild/lmdb-cache-store.js.map +1 -0
  91. package/dist/esbuild/load-result-cache.d.ts +17 -0
  92. package/dist/esbuild/load-result-cache.d.ts.map +1 -0
  93. package/dist/esbuild/load-result-cache.js +61 -0
  94. package/dist/esbuild/load-result-cache.js.map +1 -0
  95. package/dist/index.d.ts +3 -0
  96. package/dist/index.d.ts.map +1 -1
  97. package/dist/index.js +2 -0
  98. package/dist/index.js.map +1 -1
  99. package/dist/lint/lint-core.js +7 -7
  100. package/dist/lint/lint-core.js.map +1 -1
  101. package/dist/orchestrators/BaseOrchestrator.js +2 -2
  102. package/dist/orchestrators/BaseOrchestrator.js.map +1 -1
  103. package/dist/orchestrators/BuildOrchestrator.d.ts.map +1 -1
  104. package/dist/orchestrators/BuildOrchestrator.js +5 -19
  105. package/dist/orchestrators/BuildOrchestrator.js.map +1 -1
  106. package/dist/orchestrators/DevOrchestrator.js +5 -5
  107. package/dist/orchestrators/DevOrchestrator.js.map +1 -1
  108. package/dist/orchestrators/WatchOrchestrator.js +6 -6
  109. package/dist/orchestrators/WatchOrchestrator.js.map +1 -1
  110. package/dist/runtime/ResultCollector.d.ts +1 -0
  111. package/dist/runtime/ResultCollector.d.ts.map +1 -1
  112. package/dist/runtime/ResultCollector.js.map +1 -1
  113. package/dist/runtime/engine-watch-events.d.ts.map +1 -1
  114. package/dist/runtime/engine-watch-events.js +3 -0
  115. package/dist/runtime/engine-watch-events.js.map +1 -1
  116. package/dist/runtime/rebuild-manager.js +1 -1
  117. package/dist/runtime/rebuild-manager.js.map +1 -1
  118. package/dist/runtime/worker-utils.js +1 -1
  119. package/dist/runtime/worker-utils.js.map +1 -1
  120. package/dist/sd-cli-entry.d.ts.map +1 -1
  121. package/dist/sd-cli-entry.js +4 -3
  122. package/dist/sd-cli-entry.js.map +1 -1
  123. package/dist/sd-cli.js +3 -3
  124. package/dist/sd-cli.js.map +1 -1
  125. package/dist/ts-compiler/SdTsCompiler.d.ts +39 -0
  126. package/dist/ts-compiler/SdTsCompiler.d.ts.map +1 -0
  127. package/dist/ts-compiler/SdTsCompiler.js +593 -0
  128. package/dist/ts-compiler/SdTsCompiler.js.map +1 -0
  129. package/dist/ts-compiler/sd-ts-compiler-options.d.ts +40 -0
  130. package/dist/ts-compiler/sd-ts-compiler-options.d.ts.map +1 -0
  131. package/dist/ts-compiler/sd-ts-compiler-options.js +2 -0
  132. package/dist/ts-compiler/sd-ts-compiler-options.js.map +1 -0
  133. package/dist/ts-compiler/sd-ts-compiler-result.d.ts +34 -0
  134. package/dist/ts-compiler/sd-ts-compiler-result.d.ts.map +1 -0
  135. package/dist/ts-compiler/sd-ts-compiler-result.js +2 -0
  136. package/dist/ts-compiler/sd-ts-compiler-result.js.map +1 -0
  137. package/dist/utils/copy-public.d.ts +6 -4
  138. package/dist/utils/copy-public.d.ts.map +1 -1
  139. package/dist/utils/copy-public.js +9 -7
  140. package/dist/utils/copy-public.js.map +1 -1
  141. package/dist/utils/diagnostic-utils.d.ts +2 -3
  142. package/dist/utils/diagnostic-utils.d.ts.map +1 -1
  143. package/dist/utils/diagnostic-utils.js +8 -9
  144. package/dist/utils/diagnostic-utils.js.map +1 -1
  145. package/dist/utils/output-utils.d.ts +8 -2
  146. package/dist/utils/output-utils.d.ts.map +1 -1
  147. package/dist/utils/output-utils.js +32 -8
  148. package/dist/utils/output-utils.js.map +1 -1
  149. package/dist/workers/client.worker.d.ts +1 -1
  150. package/dist/workers/client.worker.d.ts.map +1 -1
  151. package/dist/workers/client.worker.js +115 -110
  152. package/dist/workers/client.worker.js.map +1 -1
  153. package/dist/workers/incremental-mtime-tracker.d.ts +13 -0
  154. package/dist/workers/incremental-mtime-tracker.d.ts.map +1 -0
  155. package/dist/workers/incremental-mtime-tracker.js +65 -0
  156. package/dist/workers/incremental-mtime-tracker.js.map +1 -0
  157. package/dist/workers/library-build.worker.d.ts +0 -2
  158. package/dist/workers/library-build.worker.d.ts.map +1 -1
  159. package/dist/workers/library-build.worker.js +169 -70
  160. package/dist/workers/library-build.worker.js.map +1 -1
  161. package/dist/workers/server-build.worker.d.ts.map +1 -1
  162. package/dist/workers/server-build.worker.js +30 -57
  163. package/dist/workers/server-build.worker.js.map +1 -1
  164. package/dist/workers/server-esbuild-context.d.ts +7 -0
  165. package/dist/workers/server-esbuild-context.d.ts.map +1 -1
  166. package/dist/workers/server-esbuild-context.js +11 -2
  167. package/dist/workers/server-esbuild-context.js.map +1 -1
  168. package/package.json +5 -4
  169. package/src/angular/angular-compiler.ts +0 -502
  170. package/src/angular/hmr-candidates.ts +295 -0
  171. package/src/angular/ngtsc-build-core.ts +192 -91
  172. package/src/angular/vite-angular-plugin.ts +71 -65
  173. package/src/angular/web-worker-transformer.ts +117 -0
  174. package/src/capacitor/capacitor.ts +6 -4
  175. package/src/commands/check.ts +17 -76
  176. package/src/commands/publish/deployment-phase.ts +11 -7
  177. package/src/commands/publish/npm-publisher.ts +1 -1
  178. package/src/commands/publish/publish-command.ts +1 -1
  179. package/src/commands/publish/version-upgrade.ts +44 -35
  180. package/src/commands/replace-deps.ts +3 -1
  181. package/src/deps/replace-deps/collect-deps.ts +4 -2
  182. package/src/deps/replace-deps/replace-deps-resolve.ts +12 -7
  183. package/src/deps/replace-deps/replace-deps.ts +191 -69
  184. package/src/electron/electron.ts +7 -7
  185. package/src/engines/BaseEngine.ts +2 -6
  186. package/src/engines/EsbuildClientEngine.ts +16 -10
  187. package/src/engines/NgtscEngine.ts +7 -7
  188. package/src/engines/TscEngine.ts +0 -2
  189. package/src/engines/types.ts +2 -0
  190. package/src/esbuild/esbuild-angular-compiler-plugin.ts +647 -0
  191. package/src/esbuild/esbuild-client-config.ts +57 -41
  192. package/src/esbuild/esbuild-postcss-plugin.ts +9 -6
  193. package/src/esbuild/esbuild-tsc-plugin.ts +33 -23
  194. package/src/esbuild/file-reference-tracker.ts +61 -0
  195. package/src/esbuild/lmdb-cache-store.ts +46 -0
  196. package/src/esbuild/load-result-cache.ts +85 -0
  197. package/src/index.ts +5 -0
  198. package/src/lint/lint-core.ts +7 -7
  199. package/src/orchestrators/BaseOrchestrator.ts +2 -2
  200. package/src/orchestrators/BuildOrchestrator.ts +5 -24
  201. package/src/orchestrators/DevOrchestrator.ts +5 -5
  202. package/src/orchestrators/WatchOrchestrator.ts +6 -6
  203. package/src/runtime/ResultCollector.ts +1 -0
  204. package/src/runtime/engine-watch-events.ts +3 -0
  205. package/src/runtime/rebuild-manager.ts +1 -1
  206. package/src/runtime/worker-utils.ts +1 -1
  207. package/src/sd-cli-entry.ts +5 -3
  208. package/src/sd-cli.ts +4 -4
  209. package/src/ts-compiler/SdTsCompiler.ts +815 -0
  210. package/src/ts-compiler/sd-ts-compiler-options.ts +46 -0
  211. package/src/ts-compiler/sd-ts-compiler-result.ts +34 -0
  212. package/src/utils/copy-public.ts +9 -6
  213. package/src/utils/diagnostic-utils.ts +8 -9
  214. package/src/utils/output-utils.ts +38 -8
  215. package/src/workers/client.worker.ts +141 -126
  216. package/src/workers/incremental-mtime-tracker.ts +68 -0
  217. package/src/workers/library-build.worker.ts +214 -75
  218. package/src/workers/server-build.worker.ts +31 -61
  219. package/src/workers/server-esbuild-context.ts +14 -2
  220. package/tests/angular/fixtures/packages/basic-app/dist/styles.css +3 -0
  221. package/tests/angular/fixtures/packages/basic-app/scss/styles.scss +5 -0
  222. package/tests/angular/ngtsc-build-core.acc.spec.ts +210 -0
  223. package/tests/angular/ngtsc-build-core.spec.ts +52 -0
  224. package/tests/angular/vite-angular-plugin-sdtscompiler.verify.md +13 -0
  225. package/tests/angular/web-worker-transformer.spec.ts +154 -0
  226. package/tests/capacitor/capacitor-build.spec.ts +1 -1
  227. package/tests/capacitor/capacitor-icon.spec.ts +1 -1
  228. package/tests/capacitor/capacitor-init.spec.ts +1 -1
  229. package/tests/commands/check.spec.ts +90 -104
  230. package/tests/commands/publish.spec.ts +12 -4
  231. package/tests/commands/slice3-severity-cleanup.verify.md +12 -0
  232. package/tests/commands/version-upgrade.acc.spec.ts +210 -0
  233. package/tests/commands/version-upgrade.spec.ts +148 -0
  234. package/tests/deps/replace-deps/collect-deps.acc.spec.ts +62 -0
  235. package/tests/deps/replace-deps/collect-deps.spec.ts +49 -0
  236. package/tests/deps/replace-deps/replace-deps-filter.spec.ts +103 -0
  237. package/tests/deps/replace-deps/replace-deps-perf.verify.md +15 -0
  238. package/tests/deps/replace-deps/replace-deps-resolve.acc.spec.ts +124 -0
  239. package/tests/deps/replace-deps/replace-deps-setup.acc.spec.ts +156 -0
  240. package/tests/electron/electron.spec.ts +4 -1
  241. package/tests/engines/engine-adapter-isolation.spec.ts +5 -6
  242. package/tests/engines/engine-duplicate-output-removal.verify.md +10 -0
  243. package/tests/engines/esbuild-client-engine.acc.spec.ts +79 -0
  244. package/tests/engines/esbuild-client-engine.spec.ts +73 -3
  245. package/tests/esbuild/esbuild-angular-compiler-plugin-hmr.verify.md +23 -0
  246. package/tests/esbuild/esbuild-angular-compiler-plugin-onload.verify.md +21 -0
  247. package/tests/esbuild/esbuild-angular-compiler-plugin-onstart-extraction.verify.md +16 -0
  248. package/tests/esbuild/esbuild-angular-compiler-plugin-sdtscompiler.verify.md +15 -0
  249. package/tests/esbuild/esbuild-angular-compiler-plugin-stylesheet.verify.md +31 -0
  250. package/tests/esbuild/esbuild-angular-compiler-plugin-worker.verify.md +31 -0
  251. package/tests/esbuild/esbuild-angular-compiler-plugin.spec.ts +397 -0
  252. package/tests/esbuild/esbuild-angular-compiler-plugin.verify.md +21 -0
  253. package/tests/esbuild/esbuild-postcss-plugin-chunking.verify.md +17 -0
  254. package/tests/esbuild/esbuild-postcss-plugin.acc.spec.ts +152 -0
  255. package/tests/esbuild/esbuild-tsc-plugin-imports.verify.md +13 -0
  256. package/tests/esbuild/esbuild-tsc-plugin.acc.spec.ts +56 -111
  257. package/tests/esbuild/esbuild-tsc-plugin.spec.ts +116 -52
  258. package/tests/esbuild/file-reference-tracker.spec.ts +99 -0
  259. package/tests/esbuild/lmdb-cache-store.spec.ts +58 -0
  260. package/tests/esbuild/load-result-cache.acc.spec.ts +55 -0
  261. package/tests/esbuild/load-result-cache.spec.ts +133 -0
  262. package/tests/orchestrators/build-orchestrator.spec.ts +4 -3
  263. package/tests/orchestrators/dev-orchestrator.spec.ts +5 -5
  264. package/tests/orchestrators/slice1-stdout-to-consola.verify.md +10 -0
  265. package/tests/orchestrators/typecheck-orchestrator.spec.ts +1 -1
  266. package/tests/orchestrators/watch-orchestrator.spec.ts +7 -7
  267. package/tests/runtime/result-collector.spec.ts +64 -0
  268. package/tests/sd-cli-entry.spec.ts +3 -4
  269. package/tests/sd-cli-log-tag.verify.md +11 -0
  270. package/tests/ts-compiler/SdTsCompiler-affected-files.verify.md +8 -0
  271. package/tests/ts-compiler/SdTsCompiler-diagnostics.verify.md +12 -0
  272. package/tests/ts-compiler/SdTsCompiler-emit.verify.md +9 -0
  273. package/tests/ts-compiler/SdTsCompiler.acc.spec.ts +603 -0
  274. package/tests/ts-compiler/SdTsCompiler.spec.ts +265 -0
  275. package/tests/ts-compiler/SdTsCompiler.verify.md +41 -0
  276. package/tests/ts-compiler/fixtures/non-angular-pkg/.cache/typecheck-browser.tsbuildinfo +1 -0
  277. package/tests/ts-compiler/fixtures/non-angular-pkg/.cache/typecheck-node.tsbuildinfo +1 -0
  278. package/tests/ts-compiler/fixtures/non-angular-pkg/.cache/typecheck.tsbuildinfo +1 -0
  279. package/tests/ts-compiler/fixtures/non-angular-pkg/src/index.ts +3 -0
  280. package/tests/ts-compiler/fixtures/non-angular-pkg/src/util.ts +3 -0
  281. package/tests/ts-compiler/fixtures/non-angular-pkg/tests/sample.test-file.ts +3 -0
  282. package/tests/ts-compiler/fixtures/non-angular-pkg/tsconfig.json +12 -0
  283. package/tests/ts-compiler/scss-lint-integration.verify.md +14 -0
  284. package/tests/utils/angular-build.spec.ts +1 -1
  285. package/tests/utils/copy-public-outdir.verify.md +8 -0
  286. package/tests/utils/copy-public.acc.spec.ts +52 -0
  287. package/tests/utils/copy-public.spec.ts +56 -0
  288. package/tests/utils/diagnostic-utils.spec.ts +24 -15
  289. package/tests/utils/engine-watch-events.acc.spec.ts +59 -0
  290. package/tests/utils/engine-watch-events.spec.ts +58 -0
  291. package/tests/utils/esbuild-client-config-integration.verify.md +9 -0
  292. package/tests/utils/esbuild-client-config.acc.spec.ts +45 -61
  293. package/tests/utils/esbuild-client-config.spec.ts +70 -52
  294. package/tests/utils/ngtsc-build-core-write-emit.spec.ts +136 -12
  295. package/tests/utils/ngtsc-build-core.spec.ts +1 -44
  296. package/tests/utils/output-utils.spec.ts +133 -13
  297. package/tests/utils/replace-deps-watch.acc.spec.ts +7 -1
  298. package/tests/utils/replace-deps-watch.spec.ts +57 -1
  299. package/tests/utils/worker-utils.spec.ts +8 -2
  300. package/tests/workers/client-worker-initial-build-error.verify.md +2 -3
  301. package/tests/workers/client-worker-initial-build-warnings.verify.md +7 -0
  302. package/tests/workers/client-worker-mtime-incremental.verify.md +10 -0
  303. package/tests/workers/client-worker-refactor.verify.md +22 -0
  304. package/tests/workers/client-worker-ts-cache-invalidation.verify.md +12 -0
  305. package/tests/workers/client-worker.acc.spec.ts +6 -3
  306. package/tests/workers/incremental-mtime-tracker.acc.spec.ts +144 -0
  307. package/tests/workers/incremental-mtime-tracker.spec.ts +102 -0
  308. package/tests/workers/library-build-lint.spec.ts +40 -45
  309. package/tests/workers/library-build-worker.spec.ts +298 -40
  310. package/tests/workers/server-build-lint.spec.ts +59 -45
  311. package/tests/workers/server-build-worker.spec.ts +63 -24
  312. package/tests/workers/server-esbuild-context.acc.spec.ts +2 -0
  313. package/tests/workers/server-esbuild-context.spec.ts +2 -0
  314. package/tests/workers/server-runtime-worker.spec.ts +1 -1
  315. package/tests/workers/shared-worker-lifecycle.acc.spec.ts +1 -1
  316. package/dist/angular/angular-build-pipeline.d.ts +0 -97
  317. package/dist/angular/angular-build-pipeline.d.ts.map +0 -1
  318. package/dist/angular/angular-build-pipeline.js +0 -285
  319. package/dist/angular/angular-build-pipeline.js.map +0 -1
  320. package/dist/utils/tsc-build.d.ts +0 -51
  321. package/dist/utils/tsc-build.d.ts.map +0 -1
  322. package/dist/utils/tsc-build.js +0 -156
  323. package/dist/utils/tsc-build.js.map +0 -1
  324. package/dist/workers/ngtsc-build.worker.d.ts +0 -23
  325. package/dist/workers/ngtsc-build.worker.d.ts.map +0 -1
  326. package/dist/workers/ngtsc-build.worker.js +0 -267
  327. package/dist/workers/ngtsc-build.worker.js.map +0 -1
  328. package/src/angular/angular-build-pipeline.ts +0 -406
  329. package/src/utils/tsc-build.ts +0 -226
  330. package/src/workers/ngtsc-build.worker.ts +0 -351
  331. package/tests/angular/angular-build-pipeline.spec.ts +0 -247
  332. package/tests/angular/angular-compiler-aot.acc.spec.ts +0 -68
  333. package/tests/angular/angular-compiler-aot.spec.ts +0 -80
  334. package/tests/utils/angular-compiler-emit.spec.ts +0 -666
  335. package/tests/utils/angular-compiler.spec.ts +0 -707
  336. package/tests/utils/tsc-build.spec.ts +0 -527
  337. package/tests/workers/ngtsc-build-lint.spec.ts +0 -141
  338. package/tests/workers/ngtsc-build-worker.spec.ts +0 -199
@@ -22,7 +22,7 @@ describe("writeEmitResults", () => {
22
22
  });
23
23
 
24
24
  it("emitResults를 output-path-rewriting 적용하여 파일로 쓴다", async () => {
25
- const { writeEmitResults } = await import("../../src/angular/angular-build-pipeline");
25
+ const { writeEmitResults } = await import("../../src/angular/ngtsc-build-core");
26
26
 
27
27
  const distDir = path.join(pkgDir, "dist");
28
28
  // Simulate nested output: dist/my-pkg/src/index.js
@@ -40,7 +40,7 @@ describe("writeEmitResults", () => {
40
40
  });
41
41
 
42
42
  it("output-path-rewriter가 null을 반환하면 파일을 쓰지 않는다", async () => {
43
- const { writeEmitResults } = await import("../../src/angular/angular-build-pipeline");
43
+ const { writeEmitResults } = await import("../../src/angular/ngtsc-build-core");
44
44
 
45
45
  const distDir = path.join(pkgDir, "dist");
46
46
  // Nested output from OTHER package: dist/other-pkg/src/index.js
@@ -59,7 +59,7 @@ describe("writeEmitResults", () => {
59
59
  });
60
60
 
61
61
  it("이미 flat 구조인 경로는 그대로 쓴다", async () => {
62
- const { writeEmitResults } = await import("../../src/angular/angular-build-pipeline");
62
+ const { writeEmitResults } = await import("../../src/angular/ngtsc-build-core");
63
63
 
64
64
  const distDir = path.join(pkgDir, "dist");
65
65
  const flatPath = path.join(distDir, "index.js");
@@ -74,7 +74,7 @@ describe("writeEmitResults", () => {
74
74
  });
75
75
 
76
76
  it("디렉��리가 없으면 ��동 생성한다", async () => {
77
- const { writeEmitResults } = await import("../../src/angular/angular-build-pipeline");
77
+ const { writeEmitResults } = await import("../../src/angular/ngtsc-build-core");
78
78
 
79
79
  const distDir = path.join(pkgDir, "dist");
80
80
  // Nested path under new subdirectory
@@ -109,7 +109,7 @@ describe("writeEmitResults with side-effect SCSS", () => {
109
109
  });
110
110
 
111
111
  it("compiles side-effect SCSS to CSS and rewrites import path in JS", async () => {
112
- const { writeEmitResults } = await import("../../src/angular/angular-build-pipeline");
112
+ const { writeEmitResults } = await import("../../src/angular/ngtsc-build-core");
113
113
 
114
114
  // Create source SCSS file
115
115
  const scssPath = path.join(srcDir, "ui", "layout", "sd-flex.scss");
@@ -149,7 +149,7 @@ describe("writeEmitResults with side-effect SCSS", () => {
149
149
 
150
150
  // Acceptance: Scenario "SCSS @use 의존성 해석"
151
151
  it("resolves SCSS @use dependencies via loadPaths", async () => {
152
- const { writeEmitResults } = await import("../../src/angular/angular-build-pipeline");
152
+ const { writeEmitResults } = await import("../../src/angular/ngtsc-build-core");
153
153
 
154
154
  // Create SCSS load path with a shared variables file
155
155
  const scssLoadDir = path.join(pkgDir, "scss");
@@ -194,7 +194,7 @@ describe("writeEmitResults with side-effect SCSS", () => {
194
194
 
195
195
  // Acceptance: Scenario "SCSS 컴파일 에러"
196
196
  it("reports SCSS compilation error in scssErrors", async () => {
197
- const { writeEmitResults } = await import("../../src/angular/angular-build-pipeline");
197
+ const { writeEmitResults } = await import("../../src/angular/ngtsc-build-core");
198
198
 
199
199
  // Create SCSS file with syntax error
200
200
  const scssPath = path.join(srcDir, "ui", "layout", "broken.scss");
@@ -224,7 +224,7 @@ describe("writeEmitResults with side-effect SCSS", () => {
224
224
 
225
225
  // Acceptance: Scenario "참조하는 SCSS 파일이 존재하지 않음"
226
226
  it("reports error when referenced SCSS file does not exist", async () => {
227
- const { writeEmitResults } = await import("../../src/angular/angular-build-pipeline");
227
+ const { writeEmitResults } = await import("../../src/angular/ngtsc-build-core");
228
228
 
229
229
  const distDir = path.join(pkgDir, "dist");
230
230
  const jsPath = path.join(distDir, "my-pkg", "src", "ui", "layout", "missing.directive.js");
@@ -267,7 +267,7 @@ describe("writeEmitResults with registry", () => {
267
267
  });
268
268
 
269
269
  it("registers side-effect SCSS entries in registry when provided", async () => {
270
- const { writeEmitResults } = await import("../../src/angular/angular-build-pipeline");
270
+ const { writeEmitResults } = await import("../../src/angular/ngtsc-build-core");
271
271
 
272
272
  // Create source SCSS file
273
273
  const scssPath = path.join(srcDir, "ui", "layout", "sd-flex.scss");
@@ -304,7 +304,7 @@ describe("writeEmitResults with registry", () => {
304
304
  });
305
305
 
306
306
  it("clears stale registry entries for re-emitted source file before registering new ones", async () => {
307
- const { writeEmitResults } = await import("../../src/angular/angular-build-pipeline");
307
+ const { writeEmitResults } = await import("../../src/angular/ngtsc-build-core");
308
308
 
309
309
  const scssPath = path.join(srcDir, "ui", "layout", "sd-flex.scss");
310
310
  fs.writeFileSync(scssPath, ".sd-flex { display: flex; }", "utf-8");
@@ -345,7 +345,7 @@ describe("writeEmitResults with registry", () => {
345
345
  });
346
346
 
347
347
  it("removes registry entry when source file is re-emitted without SCSS imports", async () => {
348
- const { writeEmitResults } = await import("../../src/angular/angular-build-pipeline");
348
+ const { writeEmitResults } = await import("../../src/angular/ngtsc-build-core");
349
349
 
350
350
  const distDir = path.join(pkgDir, "dist");
351
351
  const sourceFileName = path.join(srcDir, "ui", "layout", "sd-flex.directive.ts");
@@ -382,7 +382,7 @@ describe("writeEmitResults with registry", () => {
382
382
  });
383
383
 
384
384
  it("preserves registry entries for non-emitted source files", async () => {
385
- const { writeEmitResults } = await import("../../src/angular/angular-build-pipeline");
385
+ const { writeEmitResults } = await import("../../src/angular/ngtsc-build-core");
386
386
 
387
387
  const distDir = path.join(pkgDir, "dist");
388
388
  const sourceFileA = path.join(srcDir, "ui", "layout", "sd-flex.directive.ts");
@@ -428,6 +428,130 @@ describe("writeEmitResults with registry", () => {
428
428
  });
429
429
  });
430
430
 
431
+ // Feature 1.1 (review fix): writeEmitResults에서 sideEffectScssDeps 갱신
432
+ describe("writeEmitResults with sideEffectScssDeps", () => {
433
+ let tmpDir: string;
434
+ let pkgDir: string;
435
+ let srcDir: string;
436
+
437
+ beforeEach(() => {
438
+ tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "write-emit-se-deps-"));
439
+ pkgDir = path.join(tmpDir, "my-pkg");
440
+ srcDir = path.join(pkgDir, "src");
441
+ fs.mkdirSync(path.join(pkgDir, "dist"), { recursive: true });
442
+ fs.mkdirSync(path.join(srcDir, "ui", "layout"), { recursive: true });
443
+ });
444
+
445
+ afterEach(() => {
446
+ fs.rmSync(tmpDir, { recursive: true, force: true });
447
+ });
448
+
449
+ // Acceptance: 새 side-effect SCSS의 의존성이 sideEffectScssDeps에 기록된다
450
+ it("records side-effect SCSS dependencies in sideEffectScssDeps after compileScssFile", async () => {
451
+ const { writeEmitResults } = await import("../../src/angular/ngtsc-build-core");
452
+
453
+ // Create shared variables file
454
+ const scssLoadDir = path.join(pkgDir, "scss");
455
+ fs.mkdirSync(path.join(scssLoadDir, "commons"), { recursive: true });
456
+ fs.writeFileSync(
457
+ path.join(scssLoadDir, "commons", "_variables.scss"),
458
+ "$primary: #ff0000;",
459
+ "utf-8",
460
+ );
461
+
462
+ // Create source SCSS that uses @use
463
+ const scssPath = path.join(srcDir, "ui", "layout", "sd-card.scss");
464
+ fs.writeFileSync(
465
+ scssPath,
466
+ '@use "commons/variables" as vars;\n.sd-card { color: vars.$primary; }',
467
+ "utf-8",
468
+ );
469
+
470
+ const distDir = path.join(pkgDir, "dist");
471
+ const jsPath = path.join(distDir, "my-pkg", "src", "ui", "layout", "sd-card.directive.js");
472
+ const sourceFileName = path.join(srcDir, "ui", "layout", "sd-card.directive.ts");
473
+ const emitResults = [
474
+ {
475
+ filename: jsPath,
476
+ contents: 'import "./sd-card.scss";\nexport class SdCardDirective {}',
477
+ sourceFileName,
478
+ },
479
+ ];
480
+
481
+ const sideEffectScssDeps = new Map<string, Set<string>>();
482
+ const scss: SideEffectScssOptions = {
483
+ loadPaths: [scssLoadDir],
484
+ scssErrors: [],
485
+ scssDependencies: new Map(),
486
+ sideEffectScssDeps,
487
+ };
488
+ writeEmitResults(emitResults, pkgDir, scss);
489
+
490
+ // sideEffectScssDeps should have the SCSS entry with its dependencies
491
+ expect(sideEffectScssDeps.has(scssPath)).toBe(true);
492
+ const deps = sideEffectScssDeps.get(scssPath)!;
493
+ expect(deps.size).toBeGreaterThan(0);
494
+ expect([...deps].some((d) => d.includes("_variables.scss"))).toBe(true);
495
+ });
496
+
497
+ // Unit: sideEffectScssDeps 미제공 시 기존 동작 유지
498
+ it("does not crash when sideEffectScssDeps is not provided", async () => {
499
+ const { writeEmitResults } = await import("../../src/angular/ngtsc-build-core");
500
+
501
+ const scssPath = path.join(srcDir, "ui", "layout", "sd-flex.scss");
502
+ fs.writeFileSync(scssPath, ".sd-flex { display: flex; }", "utf-8");
503
+
504
+ const distDir = path.join(pkgDir, "dist");
505
+ const jsPath = path.join(distDir, "my-pkg", "src", "ui", "layout", "sd-flex.directive.js");
506
+ const emitResults = [
507
+ {
508
+ filename: jsPath,
509
+ contents: 'import "./sd-flex.scss";\nexport class SdFlexDirective {}',
510
+ sourceFileName: path.join(srcDir, "ui", "layout", "sd-flex.directive.ts"),
511
+ },
512
+ ];
513
+
514
+ const scss: SideEffectScssOptions = {
515
+ loadPaths: [],
516
+ scssErrors: [],
517
+ scssDependencies: new Map(),
518
+ };
519
+
520
+ // Should not throw
521
+ writeEmitResults(emitResults, pkgDir, scss);
522
+ expect(scss.scssErrors).toEqual([]);
523
+ });
524
+
525
+ // Unit: SCSS 컴파일 에러 시 sideEffectScssDeps에 기록하지 않는다
526
+ it("does not record in sideEffectScssDeps when SCSS compilation fails", async () => {
527
+ const { writeEmitResults } = await import("../../src/angular/ngtsc-build-core");
528
+
529
+ const distDir = path.join(pkgDir, "dist");
530
+ const jsPath = path.join(distDir, "my-pkg", "src", "ui", "layout", "missing.directive.js");
531
+ const emitResults = [
532
+ {
533
+ filename: jsPath,
534
+ contents: 'import "./missing.scss";\nexport class MissingDirective {}',
535
+ sourceFileName: path.join(srcDir, "ui", "layout", "missing.directive.ts"),
536
+ },
537
+ ];
538
+
539
+ const sideEffectScssDeps = new Map<string, Set<string>>();
540
+ const scss: SideEffectScssOptions = {
541
+ loadPaths: [],
542
+ scssErrors: [],
543
+ scssDependencies: new Map(),
544
+ sideEffectScssDeps,
545
+ };
546
+ writeEmitResults(emitResults, pkgDir, scss);
547
+
548
+ // Error should be reported
549
+ expect(scss.scssErrors.length).toBeGreaterThan(0);
550
+ // sideEffectScssDeps should be empty (no successful compilation)
551
+ expect(sideEffectScssDeps.size).toBe(0);
552
+ });
553
+ });
554
+
431
555
  // Feature 1.2: compileSideEffectScss
432
556
  describe("compileSideEffectScss", () => {
433
557
  let tmpDir: string;
@@ -87,17 +87,10 @@ vi.mock("../../src/angular/angular-build", () => {
87
87
  };
88
88
  });
89
89
 
90
- const {
91
- buildScssLoadPaths,
92
- } = await import("../../src/angular/ngtsc-build-core");
93
90
  const {
94
91
  createLibraryTransformStylesheet,
95
- } = await import("../../src/angular/angular-build-pipeline");
96
-
97
- import { join } from "node:path";
92
+ } = await import("../../src/angular/ngtsc-build-core");
98
93
 
99
- const fakeCwd = "/workspace";
100
- const fakePkgDir = "/workspace/packages/my-angular-lib";
101
94
 
102
95
  // ─── createLibraryTransformStylesheet ───
103
96
 
@@ -193,39 +186,3 @@ describe("createLibraryTransformStylesheet", () => {
193
186
  });
194
187
  });
195
188
 
196
- // ─── buildScssLoadPaths ───
197
-
198
- describe("buildScssLoadPaths", () => {
199
- it("returns [pkgDir/scss, cwd/node_modules] for given NgtscBuildInfo", () => {
200
- const info = {
201
- name: "my-angular-lib",
202
- cwd: fakeCwd,
203
- pkgDir: fakePkgDir,
204
- output: { js: true, dts: false },
205
- };
206
-
207
- const result = buildScssLoadPaths(info);
208
-
209
- expect(result).toEqual([
210
- join(fakePkgDir, "scss"),
211
- join(fakeCwd, "node_modules"),
212
- ]);
213
- });
214
-
215
- it("uses cwd from info to construct node_modules path", () => {
216
- const customCwd = "/custom/workspace";
217
- const customPkgDir = "/custom/workspace/packages/my-pkg";
218
-
219
- const result = buildScssLoadPaths({
220
- name: "test",
221
- cwd: customCwd,
222
- pkgDir: customPkgDir,
223
- output: { js: true, dts: false },
224
- });
225
-
226
- expect(result).toEqual([
227
- join(customPkgDir, "scss"),
228
- join(customCwd, "node_modules"),
229
- ]);
230
- });
231
- });
@@ -1,32 +1,112 @@
1
1
  import { describe, it, expect, vi, beforeEach } from "vitest";
2
2
  import { consola } from "consola";
3
- import { formatBuildMessages, printErrors, printServers } from "../../src/utils/output-utils";
4
3
  import type { BuildResult } from "../../src/runtime/ResultCollector";
4
+ import type { PartialMessage } from "esbuild";
5
+
6
+ // output-utils.ts가 모듈 로드 시 consola.withTag("sd:cli:output")로 로거를 생성하므로,
7
+ // withTag가 consola 자체를 반환하도록 하여 기존 스파이가 태그 로거 호출을 캡처하게 한다.
8
+ vi.mock("consola", async (importOriginal) => {
9
+ const mod = await importOriginal<typeof import("consola")>();
10
+ const orig = mod.consola;
11
+ vi.spyOn(orig, "withTag").mockReturnValue(orig);
12
+ return { consola: orig };
13
+ });
14
+
15
+ const { formatBuildMessages, formatEsbuildMessages, printDiagnostics, printServers } =
16
+ await import("../../src/utils/output-utils");
5
17
 
6
18
  vi.spyOn(consola, "error").mockImplementation(() => {});
19
+ vi.spyOn(consola, "warn").mockImplementation(() => {});
7
20
  vi.spyOn(consola, "info").mockImplementation(() => {});
8
21
 
9
22
  describe("formatBuildMessages", () => {
10
23
  it("formats name, label, and messages into indented lines", () => {
11
24
  const result = formatBuildMessages("core", "node", ["error in file.ts"]);
12
- expect(result).toBe("core (node)\n error in file.ts");
25
+ expect(result).toBe("core (node)\n error in file.ts");
13
26
  });
14
27
 
15
28
  it("splits multiline messages into separate indented lines", () => {
16
29
  const result = formatBuildMessages("core", "node", ["line1\nline2"]);
17
- expect(result).toContain("line1");
18
- expect(result).toContain("line2");
30
+ expect(result).toContain(" line1");
31
+ expect(result).toContain(" line2");
19
32
  });
20
33
 
21
34
  it("handles multiple messages", () => {
22
35
  const result = formatBuildMessages("core", "node", ["err1", "err2"]);
23
36
  expect(result).toContain("core (node)");
24
- expect(result).toContain("err1");
25
- expect(result).toContain("err2");
37
+ expect(result).toContain(" err1");
38
+ expect(result).toContain(" err2");
39
+ });
40
+
41
+ it("preserves empty lines without arrow prefix", () => {
42
+ const result = formatBuildMessages("core", "node", ["line1\n\nline3"]);
43
+ const lines = result.split("\n");
44
+ expect(lines[0]).toBe("core (node)");
45
+ expect(lines[1]).toBe(" line1");
46
+ expect(lines[2]).toBe("");
47
+ expect(lines[3]).toBe(" line3");
26
48
  });
27
49
  });
28
50
 
29
- describe("printErrors", () => {
51
+ describe("formatEsbuildMessages", () => {
52
+ it("빈 배열이면 빈 배열을 반환한다", () => {
53
+ expect(formatEsbuildMessages([], "error")).toEqual([]);
54
+ });
55
+
56
+ it("location이 없는 에러 메시지를 포맷한다", () => {
57
+ const msgs: PartialMessage[] = [{ text: "Some global error" }];
58
+ const result = formatEsbuildMessages(msgs, "error");
59
+ expect(result).toHaveLength(1);
60
+ expect(result[0]).toContain("Some global error");
61
+ expect(result[0]).not.toContain("[ERROR]");
62
+ });
63
+
64
+ it("location이 있으면 파일 경로와 코드 컨텍스트를 포함한다", () => {
65
+ const msgs: PartialMessage[] = [{
66
+ text: "Property 'id' does not exist",
67
+ location: {
68
+ file: "src/app/page.ts",
69
+ line: 10,
70
+ column: 4,
71
+ length: 2,
72
+ lineText: " item.id;",
73
+ },
74
+ }];
75
+ const result = formatEsbuildMessages(msgs, "error");
76
+ expect(result).toHaveLength(1);
77
+ expect(result[0]).toContain("src/app/page.ts");
78
+ expect(result[0]).toContain("Property 'id' does not exist");
79
+ });
80
+
81
+ it("notes를 포함한다", () => {
82
+ const msgs: PartialMessage[] = [{
83
+ text: "Build failed",
84
+ notes: [{ text: "hint message" }],
85
+ }];
86
+ const result = formatEsbuildMessages(msgs, "error");
87
+ expect(result[0]).toContain("hint message");
88
+ });
89
+
90
+ it("warning kind에서 [WARNING] 접두사를 제거한다", () => {
91
+ const msgs: PartialMessage[] = [{ text: "Unused variable" }];
92
+ const result = formatEsbuildMessages(msgs, "warning");
93
+ expect(result[0]).not.toContain("[WARNING]");
94
+ expect(result[0]).toContain("Unused variable");
95
+ });
96
+
97
+ it("여러 메시지를 각각 포맷한다", () => {
98
+ const msgs: PartialMessage[] = [
99
+ { text: "Error A" },
100
+ { text: "Error B" },
101
+ ];
102
+ const result = formatEsbuildMessages(msgs, "error");
103
+ expect(result).toHaveLength(2);
104
+ expect(result[0]).toContain("Error A");
105
+ expect(result[1]).toContain("Error B");
106
+ });
107
+ });
108
+
109
+ describe("printDiagnostics", () => {
30
110
  beforeEach(() => {
31
111
  vi.clearAllMocks();
32
112
  });
@@ -35,7 +115,7 @@ describe("printErrors", () => {
35
115
  const results = new Map<string, BuildResult>([
36
116
  ["core:build", { name: "core", target: "node", type: "build", status: "error", message: "failed" }],
37
117
  ]);
38
- printErrors(results);
118
+ printDiagnostics(results);
39
119
  expect(consola.error).toHaveBeenCalledOnce();
40
120
  });
41
121
 
@@ -43,7 +123,7 @@ describe("printErrors", () => {
43
123
  const results = new Map<string, BuildResult>([
44
124
  ["core:build", { name: "core", target: "node", type: "build", status: "error" }],
45
125
  ]);
46
- printErrors(results);
126
+ printDiagnostics(results);
47
127
  expect(consola.error).toHaveBeenCalledOnce();
48
128
  });
49
129
 
@@ -51,7 +131,7 @@ describe("printErrors", () => {
51
131
  const results = new Map<string, BuildResult>([
52
132
  ["core:build", { name: "core", target: "node", type: "build", status: "success" }],
53
133
  ]);
54
- printErrors(results);
134
+ printDiagnostics(results);
55
135
  expect(consola.error).not.toHaveBeenCalled();
56
136
  });
57
137
 
@@ -61,7 +141,7 @@ describe("printErrors", () => {
61
141
  const results = new Map<string, BuildResult>([
62
142
  ["my-server:lint", { name: "my-server", target: "server", type: "lint", status: "error", message: "no-unused-vars" }],
63
143
  ]);
64
- printErrors(results);
144
+ printDiagnostics(results);
65
145
  const callArg = vi.mocked(consola.error).mock.calls[0][0] as string;
66
146
  expect(callArg).toContain("my-server (lint)");
67
147
  });
@@ -70,7 +150,7 @@ describe("printErrors", () => {
70
150
  const results = new Map<string, BuildResult>([
71
151
  ["core:build", { name: "core-common", target: "node", type: "build", status: "error", message: "build err" }],
72
152
  ]);
73
- printErrors(results);
153
+ printDiagnostics(results);
74
154
  const callArg = vi.mocked(consola.error).mock.calls[0][0] as string;
75
155
  expect(callArg).toContain("core-common (node)");
76
156
  });
@@ -79,8 +159,48 @@ describe("printErrors", () => {
79
159
  const results = new Map<string, BuildResult>([
80
160
  ["core:lint", { name: "core-common", target: "node", type: "lint", status: "success" }],
81
161
  ]);
82
- printErrors(results);
162
+ printDiagnostics(results);
163
+ expect(consola.error).not.toHaveBeenCalled();
164
+ });
165
+
166
+ //#endregion
167
+
168
+ //#region Feature 1.1 Slice 2: printDiagnostics() 경고 출력 확장
169
+
170
+ it("prints warnings with consola.warn", () => {
171
+ const results = new Map<string, BuildResult>([
172
+ ["core:build", { name: "core", target: "node", type: "build", status: "success", warnings: "unused var" }],
173
+ ]);
174
+ printDiagnostics(results);
175
+ expect(consola.error).not.toHaveBeenCalled();
176
+ expect(consola.warn).toHaveBeenCalledOnce();
177
+ const callArg = vi.mocked(consola.warn).mock.calls[0][0] as string;
178
+ expect(callArg).toContain("core (node)");
179
+ expect(callArg).toContain("unused var");
180
+ });
181
+
182
+ it("prints errors before warnings", () => {
183
+ const results = new Map<string, BuildResult>([
184
+ ["core:build", { name: "core", target: "node", type: "build", status: "error", message: "type error" }],
185
+ ["lib:build", { name: "lib", target: "browser", type: "build", status: "success", warnings: "deprecation" }],
186
+ ]);
187
+ printDiagnostics(results);
188
+ expect(consola.error).toHaveBeenCalledOnce();
189
+ expect(consola.warn).toHaveBeenCalledOnce();
190
+
191
+ // error가 warn보다 먼저 호출되었는지 확인
192
+ const errorOrder = vi.mocked(consola.error).mock.invocationCallOrder[0];
193
+ const warnOrder = vi.mocked(consola.warn).mock.invocationCallOrder[0];
194
+ expect(errorOrder).toBeLessThan(warnOrder);
195
+ });
196
+
197
+ it("does not print warnings when there are none", () => {
198
+ const results = new Map<string, BuildResult>([
199
+ ["core:build", { name: "core", target: "node", type: "build", status: "success" }],
200
+ ]);
201
+ printDiagnostics(results);
83
202
  expect(consola.error).not.toHaveBeenCalled();
203
+ expect(consola.warn).not.toHaveBeenCalled();
84
204
  });
85
205
 
86
206
  //#endregion
@@ -32,7 +32,13 @@ describe("watchReplaceDeps onChanged 콜백", () => {
32
32
  tmpDir = await fs.promises.mkdtemp(path.join(os.tmpdir(), "sd-replace-deps-"));
33
33
 
34
34
  // 소스 패키지 생성
35
- const sourceDir = path.join(tmpDir, "source-pkg", "src");
35
+ const sourcePkg = path.join(tmpDir, "source-pkg");
36
+ await fs.promises.mkdir(sourcePkg, { recursive: true });
37
+ await fs.promises.writeFile(
38
+ path.join(sourcePkg, "package.json"),
39
+ JSON.stringify({ name: "@test/pkg", files: ["src"] }),
40
+ );
41
+ const sourceDir = path.join(sourcePkg, "src");
36
42
  await fs.promises.mkdir(sourceDir, { recursive: true });
37
43
  await fs.promises.writeFile(path.join(sourceDir, "index.ts"), "export const a = 1;");
38
44
 
@@ -17,7 +17,13 @@ describe("watchReplaceDeps onChanged", () => {
17
17
  tmpDir = await fs.promises.mkdtemp(path.join(os.tmpdir(), "sd-replace-deps-unit-"));
18
18
 
19
19
  // 소스 패키지 생성
20
- const sourceDir = path.join(tmpDir, "source-pkg", "src");
20
+ const sourcePkg = path.join(tmpDir, "source-pkg");
21
+ await fs.promises.mkdir(sourcePkg, { recursive: true });
22
+ await fs.promises.writeFile(
23
+ path.join(sourcePkg, "package.json"),
24
+ JSON.stringify({ name: "@test/pkg", files: ["src"] }),
25
+ );
26
+ const sourceDir = path.join(sourcePkg, "src");
21
27
  await fs.promises.mkdir(sourceDir, { recursive: true });
22
28
  await fs.promises.writeFile(path.join(sourceDir, "index.ts"), "export const v = 1;");
23
29
 
@@ -75,6 +81,56 @@ describe("watchReplaceDeps onChanged", () => {
75
81
  expect(callCount).toBe(1);
76
82
  }, 10_000);
77
83
 
84
+ it("files에 없는 파일의 변경은 감지되지 않는다", async () => {
85
+ const projectRoot = path.join(tmpDir, "project");
86
+ const sourcePath = path.join(tmpDir, "source-pkg");
87
+
88
+ // files에 없는 파일 생성
89
+ await fs.promises.writeFile(path.join(sourcePath, "tsconfig.json"), "{}");
90
+
91
+ let callCount = 0;
92
+
93
+ watchResult = await watchReplaceDeps(projectRoot, { "@test/pkg": sourcePath }, {
94
+ onChanged: () => {
95
+ callCount++;
96
+ },
97
+ });
98
+
99
+ // files에 없는 파일 변경
100
+ await fs.promises.writeFile(path.join(sourcePath, "tsconfig.json"), '{"strict": true}');
101
+
102
+ // 충분한 대기 시간 (300ms 배칭 + 여유)
103
+ await new Promise((r) => setTimeout(r, 1500));
104
+
105
+ // files에 없으므로 감지되지 않음
106
+ expect(callCount).toBe(0);
107
+ }, 10_000);
108
+
109
+ it("npm 기본 파일(README.md) 변경이 감지된다", async () => {
110
+ const projectRoot = path.join(tmpDir, "project");
111
+ const sourcePath = path.join(tmpDir, "source-pkg");
112
+
113
+ // 소스에 README.md 생성
114
+ await fs.promises.writeFile(path.join(sourcePath, "README.md"), "# README v1");
115
+
116
+ let resolveChanged: () => void;
117
+ const changedPromise = new Promise<void>((resolve) => {
118
+ resolveChanged = resolve;
119
+ });
120
+
121
+ watchResult = await watchReplaceDeps(projectRoot, { "@test/pkg": sourcePath }, {
122
+ onChanged: () => {
123
+ resolveChanged();
124
+ },
125
+ });
126
+
127
+ // README.md 변경
128
+ await fs.promises.writeFile(path.join(sourcePath, "README.md"), "# README v2");
129
+
130
+ // 콜백 호출 대기
131
+ await changedPromise;
132
+ }, 10_000);
133
+
78
134
  it("options 파라미터가 undefined일 때 에러가 발생하지 않는다", async () => {
79
135
  const projectRoot = path.join(tmpDir, "project");
80
136
  const sourcePath = path.join(tmpDir, "source-pkg");
@@ -11,7 +11,7 @@ describe("setupWorkerConsola", () => {
11
11
  afterEach(() => {
12
12
  consola.level = originalLevel;
13
13
  consola.options.reporters = originalReporters;
14
- if (originalEnv === undefined) {
14
+ if (originalEnv == null) {
15
15
  delete process.env["SD_DEBUG"];
16
16
  } else {
17
17
  process.env["SD_DEBUG"] = originalEnv;
@@ -40,7 +40,13 @@ describe("createOnceGuard", () => {
40
40
  it("throws on second call", () => {
41
41
  const guard = createOnceGuard("startWatch");
42
42
  guard();
43
- expect(() => guard()).toThrow("startWatch can only be called once per Worker");
43
+ expect(() => guard()).toThrow("Worker당 번만 호출할 있습니다: startWatch");
44
+ });
45
+
46
+ it("includes the label in Korean error message", () => {
47
+ const guard = createOnceGuard("myFunction");
48
+ guard();
49
+ expect(() => guard()).toThrow("Worker당 한 번만 호출할 수 있습니다: myFunction");
44
50
  });
45
51
  });
46
52
 
@@ -3,6 +3,5 @@
3
3
  ## 검증 항목
4
4
 
5
5
  - [x] client.worker.ts onEnd에서 초기 빌드 시 errors 필드가 포함되는지: `client.worker.ts:285-291` — `initialBuildResolve`에 `errors: result.errors.map((e) => e.text)` 포함 확인
6
- - [x] EsbuildClientEngine.startWatch에서 반환값의 success 확인 후 에러 로깅하는지: `EsbuildClientEngine.ts:135-137` — `result != null && !result.success` 조건으로 `logger.error` 호출 확인. 테스트 실행 `[my-client] 초기 빌드 실패: Module not found: @angular/core; Syntax error in app.ts` 출력 확인
7
- - [x] esbuild-client-config.ts에서 dev 모드 logLevel이 "warning"인지: `esbuild-client-config.ts:169` — `logLevel: isDev ? "warning" : "silent"` 확인. `isDev = options.mode === "dev"` (line 52)
8
- - [x] esbuild-client-config.ts에서 build 모드 logLevel이 "silent"인지: 동일 라인 — 삼항 연산자의 false 분기가 `"silent"` 확인
6
+ - [x] EsbuildClientEngine.startWatch에서 반환값의 success 확인 후 ResultCollector에 보고하는지: `EsbuildClientEngine.ts:129-138` — `!result.success` 조건으로 `resultCollector.add()` 호출 확인. logger.error는 Feature 1.2에서 제거됨 (중복 출력 방지)
7
+ - [x] esbuild-client-config.ts에서 logLevel이 "silent"인지: `esbuild-client-config.ts:191` — `logLevel: "silent"` 확인. Feature 1.2에서 dev/build 모두 "silent" 통일됨
@@ -0,0 +1,7 @@
1
+ # 초기 빌드 warnings 전달 — LLM 검증
2
+
3
+ ## 검증 항목
4
+
5
+ - [x] client.worker.ts의 initialBuildResolve에 warnings 필드가 포함되는지: `client.worker.ts:305-315` — `initialBuildResolve`에 `warnings: result.warnings.length > 0 ? result.warnings.map(formatEsbuildMessage) : undefined` 포함 확인. 후속 빌드(line 295-298)와 동일 패턴
6
+ - [x] warnings가 없을 때 undefined인지: `client.worker.ts:312-314` — `result.warnings.length > 0` 조건으로 빈 배열일 때 undefined 반환 확인
7
+ - [x] ClientBuildResult 인터페이스에 warnings 필드가 있는지: `client.worker.ts:47` — `warnings?: string[]` 확인. 변경 불필요
@@ -0,0 +1,10 @@
1
+ # client.worker mtime 증분 추적 — LLM 검증
2
+
3
+ ## 검증 항목
4
+
5
+ - [x] createSourceFileCachePlugin이 IncrementalMtimeTracker를 사용하는지 확인: `client.worker.ts:198` — `const mtimeTracker = new IncrementalMtimeTracker();` 확인됨
6
+ - [x] onStart에서 detectChanges 결과로 invalidate가 호출되는지 확인: `client.worker.ts:210-213` — `mtimeTracker.detectChanges(watchTargets)` 결과를 `sourceFileCache.invalidate(changedFiles)`에 전달. 기존 로직과 동작 동일
7
+ - [x] onEnd에서 updateMtimes가 호출되는지 확인: `client.worker.ts:228` — `mtimeTracker.updateMtimes(watchTargets)` 호출 확인. `prevMtimes.clear()` + 전체 순회 제거됨
8
+ - [x] esbuildResult == null 가드가 유지되는지 확인: onStart의 `if (esbuildResult != null)` (라인 202), onEnd의 `if (esbuildResult == null) return;` (라인 222) 모두 유지됨
9
+ - [x] isInitialBuild 가드와 sender.send("buildStart")가 유지되는지 확인: `client.worker.ts:216-218` — `if (!isInitialBuild) { sender.send("buildStart", {}); }` 유지됨
10
+ - [x] import 경로에 .js 확장자가 없는지 확인: `client.worker.ts:20` — `from "./incremental-mtime-tracker"` (확장자 없음)