@simplysm/sd-cli 14.0.42 → 14.0.43

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 (321) 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 +29 -34
  10. package/dist/angular/ngtsc-build-core.d.ts.map +1 -1
  11. package/dist/angular/ngtsc-build-core.js +90 -51
  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.js +1 -1
  36. package/dist/commands/publish/version-upgrade.js.map +1 -1
  37. package/dist/commands/replace-deps.d.ts.map +1 -1
  38. package/dist/commands/replace-deps.js +2 -1
  39. package/dist/commands/replace-deps.js.map +1 -1
  40. package/dist/deps/replace-deps/collect-deps.d.ts.map +1 -1
  41. package/dist/deps/replace-deps/collect-deps.js +5 -2
  42. package/dist/deps/replace-deps/collect-deps.js.map +1 -1
  43. package/dist/deps/replace-deps/replace-deps.d.ts +21 -3
  44. package/dist/deps/replace-deps/replace-deps.d.ts.map +1 -1
  45. package/dist/deps/replace-deps/replace-deps.js +107 -62
  46. package/dist/deps/replace-deps/replace-deps.js.map +1 -1
  47. package/dist/electron/electron.js +7 -7
  48. package/dist/electron/electron.js.map +1 -1
  49. package/dist/engines/BaseEngine.d.ts.map +1 -1
  50. package/dist/engines/BaseEngine.js +2 -5
  51. package/dist/engines/BaseEngine.js.map +1 -1
  52. package/dist/engines/EsbuildClientEngine.d.ts.map +1 -1
  53. package/dist/engines/EsbuildClientEngine.js +16 -9
  54. package/dist/engines/EsbuildClientEngine.js.map +1 -1
  55. package/dist/engines/NgtscEngine.d.ts +4 -4
  56. package/dist/engines/NgtscEngine.d.ts.map +1 -1
  57. package/dist/engines/NgtscEngine.js +5 -5
  58. package/dist/engines/NgtscEngine.js.map +1 -1
  59. package/dist/engines/TscEngine.d.ts.map +1 -1
  60. package/dist/engines/TscEngine.js +0 -2
  61. package/dist/engines/TscEngine.js.map +1 -1
  62. package/dist/engines/types.d.ts +2 -0
  63. package/dist/engines/types.d.ts.map +1 -1
  64. package/dist/esbuild/esbuild-angular-compiler-plugin.d.ts +36 -0
  65. package/dist/esbuild/esbuild-angular-compiler-plugin.d.ts.map +1 -0
  66. package/dist/esbuild/esbuild-angular-compiler-plugin.js +464 -0
  67. package/dist/esbuild/esbuild-angular-compiler-plugin.js.map +1 -0
  68. package/dist/esbuild/esbuild-client-config.d.ts +8 -2
  69. package/dist/esbuild/esbuild-client-config.d.ts.map +1 -1
  70. package/dist/esbuild/esbuild-client-config.js +48 -33
  71. package/dist/esbuild/esbuild-client-config.js.map +1 -1
  72. package/dist/esbuild/esbuild-tsc-plugin.d.ts +4 -1
  73. package/dist/esbuild/esbuild-tsc-plugin.d.ts.map +1 -1
  74. package/dist/esbuild/esbuild-tsc-plugin.js +27 -23
  75. package/dist/esbuild/esbuild-tsc-plugin.js.map +1 -1
  76. package/dist/esbuild/file-reference-tracker.d.ts +24 -0
  77. package/dist/esbuild/file-reference-tracker.d.ts.map +1 -0
  78. package/dist/esbuild/file-reference-tracker.js +57 -0
  79. package/dist/esbuild/file-reference-tracker.js.map +1 -0
  80. package/dist/esbuild/lmdb-cache-store.d.ts +18 -0
  81. package/dist/esbuild/lmdb-cache-store.d.ts.map +1 -0
  82. package/dist/esbuild/lmdb-cache-store.js +41 -0
  83. package/dist/esbuild/lmdb-cache-store.js.map +1 -0
  84. package/dist/esbuild/load-result-cache.d.ts +17 -0
  85. package/dist/esbuild/load-result-cache.d.ts.map +1 -0
  86. package/dist/esbuild/load-result-cache.js +61 -0
  87. package/dist/esbuild/load-result-cache.js.map +1 -0
  88. package/dist/index.d.ts +3 -0
  89. package/dist/index.d.ts.map +1 -1
  90. package/dist/index.js +2 -0
  91. package/dist/index.js.map +1 -1
  92. package/dist/lint/lint-core.js +7 -7
  93. package/dist/lint/lint-core.js.map +1 -1
  94. package/dist/orchestrators/BaseOrchestrator.js +2 -2
  95. package/dist/orchestrators/BaseOrchestrator.js.map +1 -1
  96. package/dist/orchestrators/BuildOrchestrator.d.ts.map +1 -1
  97. package/dist/orchestrators/BuildOrchestrator.js +5 -19
  98. package/dist/orchestrators/BuildOrchestrator.js.map +1 -1
  99. package/dist/orchestrators/DevOrchestrator.js +5 -5
  100. package/dist/orchestrators/DevOrchestrator.js.map +1 -1
  101. package/dist/orchestrators/WatchOrchestrator.js +6 -6
  102. package/dist/orchestrators/WatchOrchestrator.js.map +1 -1
  103. package/dist/runtime/ResultCollector.d.ts +1 -0
  104. package/dist/runtime/ResultCollector.d.ts.map +1 -1
  105. package/dist/runtime/ResultCollector.js.map +1 -1
  106. package/dist/runtime/engine-watch-events.d.ts.map +1 -1
  107. package/dist/runtime/engine-watch-events.js +3 -0
  108. package/dist/runtime/engine-watch-events.js.map +1 -1
  109. package/dist/runtime/rebuild-manager.js +1 -1
  110. package/dist/runtime/rebuild-manager.js.map +1 -1
  111. package/dist/runtime/worker-utils.js +1 -1
  112. package/dist/runtime/worker-utils.js.map +1 -1
  113. package/dist/sd-cli-entry.d.ts.map +1 -1
  114. package/dist/sd-cli-entry.js +4 -3
  115. package/dist/sd-cli-entry.js.map +1 -1
  116. package/dist/sd-cli.js +3 -3
  117. package/dist/sd-cli.js.map +1 -1
  118. package/dist/ts-compiler/SdTsCompiler.d.ts +39 -0
  119. package/dist/ts-compiler/SdTsCompiler.d.ts.map +1 -0
  120. package/dist/ts-compiler/SdTsCompiler.js +593 -0
  121. package/dist/ts-compiler/SdTsCompiler.js.map +1 -0
  122. package/dist/ts-compiler/sd-ts-compiler-options.d.ts +40 -0
  123. package/dist/ts-compiler/sd-ts-compiler-options.d.ts.map +1 -0
  124. package/dist/ts-compiler/sd-ts-compiler-options.js +2 -0
  125. package/dist/ts-compiler/sd-ts-compiler-options.js.map +1 -0
  126. package/dist/ts-compiler/sd-ts-compiler-result.d.ts +34 -0
  127. package/dist/ts-compiler/sd-ts-compiler-result.d.ts.map +1 -0
  128. package/dist/ts-compiler/sd-ts-compiler-result.js +2 -0
  129. package/dist/ts-compiler/sd-ts-compiler-result.js.map +1 -0
  130. package/dist/utils/copy-public.d.ts +6 -4
  131. package/dist/utils/copy-public.d.ts.map +1 -1
  132. package/dist/utils/copy-public.js +9 -7
  133. package/dist/utils/copy-public.js.map +1 -1
  134. package/dist/utils/diagnostic-utils.d.ts +2 -3
  135. package/dist/utils/diagnostic-utils.d.ts.map +1 -1
  136. package/dist/utils/diagnostic-utils.js +8 -9
  137. package/dist/utils/diagnostic-utils.js.map +1 -1
  138. package/dist/utils/output-utils.d.ts +8 -2
  139. package/dist/utils/output-utils.d.ts.map +1 -1
  140. package/dist/utils/output-utils.js +32 -8
  141. package/dist/utils/output-utils.js.map +1 -1
  142. package/dist/workers/client.worker.d.ts +1 -1
  143. package/dist/workers/client.worker.d.ts.map +1 -1
  144. package/dist/workers/client.worker.js +136 -110
  145. package/dist/workers/client.worker.js.map +1 -1
  146. package/dist/workers/library-build.worker.d.ts +0 -2
  147. package/dist/workers/library-build.worker.d.ts.map +1 -1
  148. package/dist/workers/library-build.worker.js +147 -70
  149. package/dist/workers/library-build.worker.js.map +1 -1
  150. package/dist/workers/server-build.worker.d.ts.map +1 -1
  151. package/dist/workers/server-build.worker.js +30 -57
  152. package/dist/workers/server-build.worker.js.map +1 -1
  153. package/dist/workers/server-esbuild-context.d.ts +7 -0
  154. package/dist/workers/server-esbuild-context.d.ts.map +1 -1
  155. package/dist/workers/server-esbuild-context.js +11 -2
  156. package/dist/workers/server-esbuild-context.js.map +1 -1
  157. package/package.json +5 -4
  158. package/src/angular/angular-compiler.ts +0 -502
  159. package/src/angular/hmr-candidates.ts +295 -0
  160. package/src/angular/ngtsc-build-core.ts +125 -92
  161. package/src/angular/vite-angular-plugin.ts +71 -65
  162. package/src/angular/web-worker-transformer.ts +117 -0
  163. package/src/capacitor/capacitor.ts +6 -4
  164. package/src/commands/check.ts +17 -76
  165. package/src/commands/publish/deployment-phase.ts +11 -7
  166. package/src/commands/publish/npm-publisher.ts +1 -1
  167. package/src/commands/publish/publish-command.ts +1 -1
  168. package/src/commands/publish/version-upgrade.ts +1 -1
  169. package/src/commands/replace-deps.ts +3 -1
  170. package/src/deps/replace-deps/collect-deps.ts +4 -2
  171. package/src/deps/replace-deps/replace-deps.ts +114 -66
  172. package/src/electron/electron.ts +7 -7
  173. package/src/engines/BaseEngine.ts +2 -6
  174. package/src/engines/EsbuildClientEngine.ts +16 -10
  175. package/src/engines/NgtscEngine.ts +7 -7
  176. package/src/engines/TscEngine.ts +0 -2
  177. package/src/engines/types.ts +2 -0
  178. package/src/esbuild/esbuild-angular-compiler-plugin.ts +647 -0
  179. package/src/esbuild/esbuild-client-config.ts +57 -41
  180. package/src/esbuild/esbuild-tsc-plugin.ts +33 -23
  181. package/src/esbuild/file-reference-tracker.ts +61 -0
  182. package/src/esbuild/lmdb-cache-store.ts +46 -0
  183. package/src/esbuild/load-result-cache.ts +85 -0
  184. package/src/index.ts +5 -0
  185. package/src/lint/lint-core.ts +7 -7
  186. package/src/orchestrators/BaseOrchestrator.ts +2 -2
  187. package/src/orchestrators/BuildOrchestrator.ts +5 -24
  188. package/src/orchestrators/DevOrchestrator.ts +5 -5
  189. package/src/orchestrators/WatchOrchestrator.ts +6 -6
  190. package/src/runtime/ResultCollector.ts +1 -0
  191. package/src/runtime/engine-watch-events.ts +3 -0
  192. package/src/runtime/rebuild-manager.ts +1 -1
  193. package/src/runtime/worker-utils.ts +1 -1
  194. package/src/sd-cli-entry.ts +5 -3
  195. package/src/sd-cli.ts +4 -4
  196. package/src/ts-compiler/SdTsCompiler.ts +815 -0
  197. package/src/ts-compiler/sd-ts-compiler-options.ts +46 -0
  198. package/src/ts-compiler/sd-ts-compiler-result.ts +34 -0
  199. package/src/utils/copy-public.ts +9 -6
  200. package/src/utils/diagnostic-utils.ts +8 -9
  201. package/src/utils/output-utils.ts +38 -8
  202. package/src/workers/client.worker.ts +160 -126
  203. package/src/workers/library-build.worker.ts +187 -75
  204. package/src/workers/server-build.worker.ts +31 -61
  205. package/src/workers/server-esbuild-context.ts +14 -2
  206. package/tests/angular/fixtures/packages/basic-app/dist/styles.css +3 -0
  207. package/tests/angular/fixtures/packages/basic-app/scss/styles.scss +5 -0
  208. package/tests/angular/vite-angular-plugin-sdtscompiler.verify.md +13 -0
  209. package/tests/angular/web-worker-transformer.spec.ts +154 -0
  210. package/tests/capacitor/capacitor-build.spec.ts +1 -1
  211. package/tests/capacitor/capacitor-icon.spec.ts +1 -1
  212. package/tests/capacitor/capacitor-init.spec.ts +1 -1
  213. package/tests/commands/check.spec.ts +90 -104
  214. package/tests/commands/publish.spec.ts +12 -4
  215. package/tests/commands/slice3-severity-cleanup.verify.md +12 -0
  216. package/tests/deps/replace-deps/collect-deps.acc.spec.ts +62 -0
  217. package/tests/deps/replace-deps/collect-deps.spec.ts +49 -0
  218. package/tests/deps/replace-deps/replace-deps-filter.spec.ts +103 -0
  219. package/tests/deps/replace-deps/replace-deps-setup.acc.spec.ts +156 -0
  220. package/tests/electron/electron.spec.ts +4 -1
  221. package/tests/engines/engine-adapter-isolation.spec.ts +5 -6
  222. package/tests/engines/engine-duplicate-output-removal.verify.md +10 -0
  223. package/tests/engines/esbuild-client-engine.acc.spec.ts +79 -0
  224. package/tests/engines/esbuild-client-engine.spec.ts +73 -3
  225. package/tests/esbuild/esbuild-angular-compiler-plugin-hmr.verify.md +23 -0
  226. package/tests/esbuild/esbuild-angular-compiler-plugin-onload.verify.md +21 -0
  227. package/tests/esbuild/esbuild-angular-compiler-plugin-onstart-extraction.verify.md +16 -0
  228. package/tests/esbuild/esbuild-angular-compiler-plugin-sdtscompiler.verify.md +15 -0
  229. package/tests/esbuild/esbuild-angular-compiler-plugin-stylesheet.verify.md +31 -0
  230. package/tests/esbuild/esbuild-angular-compiler-plugin-worker.verify.md +31 -0
  231. package/tests/esbuild/esbuild-angular-compiler-plugin.spec.ts +397 -0
  232. package/tests/esbuild/esbuild-angular-compiler-plugin.verify.md +21 -0
  233. package/tests/esbuild/esbuild-tsc-plugin-imports.verify.md +13 -0
  234. package/tests/esbuild/esbuild-tsc-plugin.acc.spec.ts +56 -111
  235. package/tests/esbuild/esbuild-tsc-plugin.spec.ts +116 -52
  236. package/tests/esbuild/file-reference-tracker.spec.ts +99 -0
  237. package/tests/esbuild/lmdb-cache-store.spec.ts +58 -0
  238. package/tests/esbuild/load-result-cache.acc.spec.ts +55 -0
  239. package/tests/esbuild/load-result-cache.spec.ts +133 -0
  240. package/tests/orchestrators/build-orchestrator.spec.ts +4 -3
  241. package/tests/orchestrators/dev-orchestrator.spec.ts +5 -5
  242. package/tests/orchestrators/slice1-stdout-to-consola.verify.md +10 -0
  243. package/tests/orchestrators/typecheck-orchestrator.spec.ts +1 -1
  244. package/tests/orchestrators/watch-orchestrator.spec.ts +7 -7
  245. package/tests/runtime/result-collector.spec.ts +64 -0
  246. package/tests/sd-cli-entry.spec.ts +3 -4
  247. package/tests/sd-cli-log-tag.verify.md +11 -0
  248. package/tests/ts-compiler/SdTsCompiler-affected-files.verify.md +8 -0
  249. package/tests/ts-compiler/SdTsCompiler-diagnostics.verify.md +12 -0
  250. package/tests/ts-compiler/SdTsCompiler-emit.verify.md +9 -0
  251. package/tests/ts-compiler/SdTsCompiler.acc.spec.ts +603 -0
  252. package/tests/ts-compiler/SdTsCompiler.spec.ts +265 -0
  253. package/tests/ts-compiler/SdTsCompiler.verify.md +41 -0
  254. package/tests/ts-compiler/fixtures/non-angular-pkg/.cache/typecheck-browser.tsbuildinfo +1 -0
  255. package/tests/ts-compiler/fixtures/non-angular-pkg/.cache/typecheck-node.tsbuildinfo +1 -0
  256. package/tests/ts-compiler/fixtures/non-angular-pkg/.cache/typecheck.tsbuildinfo +1 -0
  257. package/tests/ts-compiler/fixtures/non-angular-pkg/dist/index.d.ts +2 -0
  258. package/tests/ts-compiler/fixtures/non-angular-pkg/dist/index.d.ts.map +1 -0
  259. package/tests/ts-compiler/fixtures/non-angular-pkg/dist/index.js +4 -0
  260. package/tests/ts-compiler/fixtures/non-angular-pkg/dist/index.js.map +1 -0
  261. package/tests/ts-compiler/fixtures/non-angular-pkg/dist/util.d.ts +2 -0
  262. package/tests/ts-compiler/fixtures/non-angular-pkg/dist/util.d.ts.map +1 -0
  263. package/tests/ts-compiler/fixtures/non-angular-pkg/dist/util.js +4 -0
  264. package/tests/ts-compiler/fixtures/non-angular-pkg/dist/util.js.map +1 -0
  265. package/tests/ts-compiler/fixtures/non-angular-pkg/src/index.ts +3 -0
  266. package/tests/ts-compiler/fixtures/non-angular-pkg/src/util.ts +3 -0
  267. package/tests/ts-compiler/fixtures/non-angular-pkg/tests/sample.test-file.ts +3 -0
  268. package/tests/ts-compiler/fixtures/non-angular-pkg/tsconfig.json +12 -0
  269. package/tests/ts-compiler/scss-lint-integration.verify.md +14 -0
  270. package/tests/utils/angular-build.spec.ts +1 -1
  271. package/tests/utils/copy-public-outdir.verify.md +8 -0
  272. package/tests/utils/copy-public.acc.spec.ts +52 -0
  273. package/tests/utils/copy-public.spec.ts +56 -0
  274. package/tests/utils/diagnostic-utils.spec.ts +24 -15
  275. package/tests/utils/engine-watch-events.acc.spec.ts +59 -0
  276. package/tests/utils/engine-watch-events.spec.ts +58 -0
  277. package/tests/utils/esbuild-client-config-integration.verify.md +9 -0
  278. package/tests/utils/esbuild-client-config.acc.spec.ts +45 -61
  279. package/tests/utils/esbuild-client-config.spec.ts +70 -52
  280. package/tests/utils/ngtsc-build-core-write-emit.spec.ts +12 -12
  281. package/tests/utils/ngtsc-build-core.spec.ts +1 -44
  282. package/tests/utils/output-utils.spec.ts +133 -13
  283. package/tests/utils/replace-deps-watch.acc.spec.ts +7 -1
  284. package/tests/utils/replace-deps-watch.spec.ts +57 -1
  285. package/tests/utils/worker-utils.spec.ts +8 -2
  286. package/tests/workers/client-worker-initial-build-error.verify.md +2 -3
  287. package/tests/workers/client-worker-initial-build-warnings.verify.md +7 -0
  288. package/tests/workers/client-worker-refactor.verify.md +22 -0
  289. package/tests/workers/client-worker-ts-cache-invalidation.verify.md +12 -0
  290. package/tests/workers/client-worker.acc.spec.ts +6 -3
  291. package/tests/workers/library-build-lint.spec.ts +40 -45
  292. package/tests/workers/library-build-worker.spec.ts +294 -40
  293. package/tests/workers/server-build-lint.spec.ts +59 -45
  294. package/tests/workers/server-build-worker.spec.ts +63 -24
  295. package/tests/workers/server-esbuild-context.acc.spec.ts +2 -0
  296. package/tests/workers/server-esbuild-context.spec.ts +2 -0
  297. package/tests/workers/server-runtime-worker.spec.ts +1 -1
  298. package/tests/workers/shared-worker-lifecycle.acc.spec.ts +1 -1
  299. package/dist/angular/angular-build-pipeline.d.ts +0 -97
  300. package/dist/angular/angular-build-pipeline.d.ts.map +0 -1
  301. package/dist/angular/angular-build-pipeline.js +0 -285
  302. package/dist/angular/angular-build-pipeline.js.map +0 -1
  303. package/dist/utils/tsc-build.d.ts +0 -51
  304. package/dist/utils/tsc-build.d.ts.map +0 -1
  305. package/dist/utils/tsc-build.js +0 -156
  306. package/dist/utils/tsc-build.js.map +0 -1
  307. package/dist/workers/ngtsc-build.worker.d.ts +0 -23
  308. package/dist/workers/ngtsc-build.worker.d.ts.map +0 -1
  309. package/dist/workers/ngtsc-build.worker.js +0 -267
  310. package/dist/workers/ngtsc-build.worker.js.map +0 -1
  311. package/src/angular/angular-build-pipeline.ts +0 -406
  312. package/src/utils/tsc-build.ts +0 -226
  313. package/src/workers/ngtsc-build.worker.ts +0 -351
  314. package/tests/angular/angular-build-pipeline.spec.ts +0 -247
  315. package/tests/angular/angular-compiler-aot.acc.spec.ts +0 -68
  316. package/tests/angular/angular-compiler-aot.spec.ts +0 -80
  317. package/tests/utils/angular-compiler-emit.spec.ts +0 -666
  318. package/tests/utils/angular-compiler.spec.ts +0 -707
  319. package/tests/utils/tsc-build.spec.ts +0 -527
  320. package/tests/workers/ngtsc-build-lint.spec.ts +0 -141
  321. package/tests/workers/ngtsc-build-worker.spec.ts +0 -199
@@ -0,0 +1,295 @@
1
+ import ts from "typescript";
2
+ import type { NgtscProgram } from "./angular-build.js";
3
+
4
+ // NgCompiler 타입은 NgtscProgram.compiler에서 추론
5
+ type NgCompiler = NgtscProgram["compiler"];
6
+
7
+ /** HMR 분석 대상 최대 변경 파일 수 */
8
+ export const HMR_MODIFIED_FILE_LIMIT = 32;
9
+
10
+ /**
11
+ * HMR 지원 메타데이터 필드.
12
+ * template, templateUrl, styles, styleUrl, stylesUrl만 HMR 업데이트를 지원한다.
13
+ */
14
+ const SUPPORTED_FIELD_NAMES = new Set([
15
+ "template",
16
+ "templateUrl",
17
+ "styles",
18
+ "styleUrl",
19
+ "stylesUrl",
20
+ ]);
21
+
22
+ const enum MetaUpdateAnalysis {
23
+ Supported = 0,
24
+ Unsupported = 1,
25
+ None = 2,
26
+ }
27
+
28
+ /**
29
+ * 변경된 파일에서 HMR 후보 컴포넌트 클래스를 수집한다.
30
+ *
31
+ * - 템플릿/스타일 파일 변경 → 해당 파일을 사용하는 컴포넌트가 후보
32
+ * - 소스 파일 변경 → 인라인 템플릿/스타일만 변경된 컴포넌트가 후보
33
+ * - 지원 불가 변경(클래스 멤버, 비-컴포넌트 문 변경 등) → 후보 전체 무효화
34
+ */
35
+ export function collectHmrCandidates(
36
+ modifiedFiles: Set<string>,
37
+ angularProgram: NgtscProgram,
38
+ staleSourceFiles?: Map<string, ts.SourceFile>,
39
+ ): Set<ts.ClassDeclaration> {
40
+ const compiler = angularProgram.compiler;
41
+ const candidates = new Set<ts.ClassDeclaration>();
42
+
43
+ for (const file of modifiedFiles) {
44
+ // 템플릿 파일 변경 → 소유 컴포넌트 추가
45
+ const templateFileNodes = compiler.getComponentsWithTemplateFile(file);
46
+ if (templateFileNodes.size > 0) {
47
+ for (const node of templateFileNodes) {
48
+ if (ts.isClassDeclaration(node)) {
49
+ candidates.add(node);
50
+ }
51
+ }
52
+ continue;
53
+ }
54
+
55
+ // 스타일 파일 변경 → 소유 컴포넌트 추가
56
+ const styleFileNodes = compiler.getComponentsWithStyleFile(file);
57
+ if (styleFileNodes.size > 0) {
58
+ for (const node of styleFileNodes) {
59
+ if (ts.isClassDeclaration(node)) {
60
+ candidates.add(node);
61
+ }
62
+ }
63
+ continue;
64
+ }
65
+
66
+ // 소스 파일 변경 → 상세 분석
67
+ const staleSource = staleSourceFiles?.get(file);
68
+ if (staleSource == null) {
69
+ // 알 수 없는 파일 → full rebuild
70
+ candidates.clear();
71
+ break;
72
+ }
73
+
74
+ const updatedSource = compiler.getCurrentProgram().getSourceFile(file);
75
+ if (updatedSource == null) {
76
+ // 더 이상 존재하지 않는 파일 → full rebuild
77
+ candidates.clear();
78
+ break;
79
+ }
80
+
81
+ const fileCandidates = analyzeFileUpdates(staleSource, updatedSource, compiler);
82
+ if (fileCandidates != null) {
83
+ for (const node of fileCandidates) {
84
+ candidates.add(node);
85
+ }
86
+ } else {
87
+ // 지원 불가 변경 → full rebuild
88
+ candidates.clear();
89
+ break;
90
+ }
91
+ }
92
+
93
+ return candidates;
94
+ }
95
+
96
+ /**
97
+ * 소스 파일의 변경사항을 분석하여 HMR 후보 컴포넌트를 반환한다.
98
+ * 지원 불가 변경이 있으면 null을 반환한다.
99
+ */
100
+ function analyzeFileUpdates(
101
+ stale: ts.SourceFile,
102
+ updated: ts.SourceFile,
103
+ compiler: NgCompiler,
104
+ ): ts.ClassDeclaration[] | null {
105
+ if (stale.statements.length !== updated.statements.length) {
106
+ return null;
107
+ }
108
+
109
+ const candidates: ts.ClassDeclaration[] = [];
110
+
111
+ for (let i = 0; i < updated.statements.length; ++i) {
112
+ const updatedNode = updated.statements[i];
113
+ const staleNode = stale.statements[i];
114
+
115
+ if (ts.isClassDeclaration(updatedNode)) {
116
+ if (!ts.isClassDeclaration(staleNode)) {
117
+ return null;
118
+ }
119
+
120
+ // 클래스 이름/상속/수정자 변경 확인
121
+ if (updatedNode.name?.text !== staleNode.name?.text) {
122
+ return null;
123
+ }
124
+ if (!equalRangeText(updatedNode.heritageClauses, updated, staleNode.heritageClauses, stale)) {
125
+ return null;
126
+ }
127
+ const updatedModifiers = ts.getModifiers(updatedNode);
128
+ const staleModifiers = ts.getModifiers(staleNode);
129
+ if (
130
+ updatedModifiers?.length !== staleModifiers?.length ||
131
+ !updatedModifiers?.every((m) => staleModifiers?.some((sm) => m.kind === sm.kind))
132
+ ) {
133
+ return null;
134
+ }
135
+
136
+ // 컴포넌트 클래스 확인
137
+ const meta = compiler.getMeta(updatedNode);
138
+ if (meta?.decorator != null && (meta as unknown as Record<string, unknown>)["isComponent"] === true) {
139
+ const updatedDecorators = ts.getDecorators(updatedNode);
140
+ const staleDecorators = ts.getDecorators(staleNode);
141
+
142
+ if (staleDecorators == null || staleDecorators.length !== updatedDecorators?.length) {
143
+ return null;
144
+ }
145
+ if (staleDecorators.length > 1) {
146
+ return null;
147
+ }
148
+
149
+ const metaDecoratorIndex = updatedDecorators.indexOf(meta.decorator);
150
+
151
+ const updatedDecExpr = meta.decorator.expression;
152
+ if (
153
+ !ts.isCallExpression(updatedDecExpr) ||
154
+ updatedDecExpr.arguments.length !== 1
155
+ ) {
156
+ return null;
157
+ }
158
+
159
+ const staleDecExpr = staleDecorators[metaDecoratorIndex].expression;
160
+ if (
161
+ !ts.isCallExpression(staleDecExpr) ||
162
+ staleDecExpr.arguments.length !== 1
163
+ ) {
164
+ return null;
165
+ }
166
+
167
+ // 데코레이터 이름/표현식 비교
168
+ if (!equalRangeText(updatedDecExpr.expression, updated, staleDecExpr.expression, stale)) {
169
+ return null;
170
+ }
171
+
172
+ // 메타데이터 변경 분석
173
+ const analysis = analyzeMetaUpdates(staleDecExpr, stale, updatedDecExpr, updated);
174
+ if (analysis === MetaUpdateAnalysis.Unsupported) {
175
+ return null;
176
+ }
177
+
178
+ // 클래스 멤버 변경 확인
179
+ if (!equalRangeText(updatedNode.members, updated, staleNode.members, stale)) {
180
+ return null;
181
+ }
182
+
183
+ if (analysis === MetaUpdateAnalysis.Supported) {
184
+ candidates.push(updatedNode);
185
+ }
186
+ continue;
187
+ }
188
+ }
189
+
190
+ // 비-컴포넌트 문 변경 확인
191
+ if (!equalRangeText(updatedNode, updated, staleNode, stale)) {
192
+ return null;
193
+ }
194
+ }
195
+
196
+ return candidates;
197
+ }
198
+
199
+ /**
200
+ * 컴포넌트 데코레이터의 메타데이터 필드 변경을 분석한다.
201
+ * 지원 필드(template, styles 등)만 변경되었으면 Supported,
202
+ * 비지원 필드가 변경되었으면 Unsupported,
203
+ * 변경 없으면 None.
204
+ */
205
+ function analyzeMetaUpdates(
206
+ staleCall: ts.CallExpression,
207
+ staleSource: ts.SourceFile,
208
+ updatedCall: ts.CallExpression,
209
+ updatedSource: ts.SourceFile,
210
+ ): MetaUpdateAnalysis {
211
+ const staleObject = staleCall.arguments[0];
212
+ const updatedObject = updatedCall.arguments[0];
213
+ let hasSupportedUpdate = false;
214
+
215
+ if (!ts.isObjectLiteralExpression(staleObject) || !ts.isObjectLiteralExpression(updatedObject)) {
216
+ return MetaUpdateAnalysis.Unsupported;
217
+ }
218
+
219
+ const supportedFields = new Map<string, ts.Expression>();
220
+ const unsupportedFields: ts.Expression[] = [];
221
+
222
+ for (const property of staleObject.properties) {
223
+ if (!ts.isPropertyAssignment(property) || ts.isComputedPropertyName(property.name)) {
224
+ return MetaUpdateAnalysis.Unsupported;
225
+ }
226
+ const name = (property.name as ts.Identifier).text;
227
+ if (SUPPORTED_FIELD_NAMES.has(name)) {
228
+ supportedFields.set(name, property.initializer);
229
+ } else {
230
+ unsupportedFields.push(property.initializer);
231
+ }
232
+ }
233
+
234
+ let j = 0;
235
+ for (const property of updatedObject.properties) {
236
+ if (!ts.isPropertyAssignment(property) || ts.isComputedPropertyName(property.name)) {
237
+ return MetaUpdateAnalysis.Unsupported;
238
+ }
239
+ const name = (property.name as ts.Identifier).text;
240
+ if (SUPPORTED_FIELD_NAMES.has(name)) {
241
+ const staleInitializer = supportedFields.get(name);
242
+ if (
243
+ staleInitializer == null ||
244
+ !equalRangeText(property.initializer, updatedSource, staleInitializer, staleSource)
245
+ ) {
246
+ hasSupportedUpdate = true;
247
+ }
248
+ supportedFields.delete(name);
249
+ } else {
250
+ if (!equalRangeText(property.initializer, updatedSource, unsupportedFields[j++], staleSource)) {
251
+ return MetaUpdateAnalysis.Unsupported;
252
+ }
253
+ }
254
+ }
255
+
256
+ if (j !== unsupportedFields.length) {
257
+ return MetaUpdateAnalysis.Unsupported;
258
+ }
259
+
260
+ // 남은 supported field → 제거됨 → supported update
261
+ hasSupportedUpdate ||= supportedFields.size > 0;
262
+
263
+ return hasSupportedUpdate ? MetaUpdateAnalysis.Supported : MetaUpdateAnalysis.None;
264
+ }
265
+
266
+ /**
267
+ * 두 소스 파일 범위의 텍스트를 문자 단위로 비교한다.
268
+ */
269
+ function equalRangeText(
270
+ firstRange: ts.TextRange | ts.NodeArray<ts.Node> | undefined,
271
+ firstSource: ts.SourceFile,
272
+ secondRange: ts.TextRange | ts.NodeArray<ts.Node> | undefined,
273
+ secondSource: ts.SourceFile,
274
+ ): boolean {
275
+ if (firstRange == null || secondRange == null) {
276
+ return firstRange === secondRange;
277
+ }
278
+
279
+ const firstLength = firstRange.end - firstRange.pos;
280
+ const secondLength = secondRange.end - secondRange.pos;
281
+ if (firstLength !== secondLength) {
282
+ return false;
283
+ }
284
+
285
+ for (let i = 0; i < firstLength; ++i) {
286
+ if (
287
+ firstSource.text.charCodeAt(i + firstRange.pos) !==
288
+ secondSource.text.charCodeAt(i + secondRange.pos)
289
+ ) {
290
+ return false;
291
+ }
292
+ }
293
+
294
+ return true;
295
+ }
@@ -1,101 +1,11 @@
1
1
  import path from "path";
2
2
  import fs from "fs";
3
- import ts from "typescript";
4
3
  import { err as errNs } from "@simplysm/core-common";
5
4
  import { consola } from "consola";
6
5
 
7
6
  const logger = consola.withTag("sd:cli:ngtsc-build");
8
- import type { BuildOutput } from "../engines/types";
9
- import type { SerializedDiagnostic } from "../typecheck/typecheck-serialization";
10
- import type { LintWithProgramResult } from "../lint/lint-with-program";
11
- import type { TypecheckEnv } from "../utils/tsconfig";
12
- import { compileScssFile } from "./scss-compiler";
13
-
14
- //#region Types
15
-
16
- export interface NgtscBuildInfo {
17
- name: string;
18
- cwd: string;
19
- pkgDir: string;
20
- output: BuildOutput;
21
- /** 타입체크 환경. 설정 시 getCompilerOptionsForEnv()로 compilerOptions를 조정한다. */
22
- env?: TypecheckEnv;
23
- /** sd.config.ts의 replaceDeps 설정 */
24
- replaceDeps?: Record<string, string>;
25
- }
26
-
27
- export interface NgtscBuildResult {
28
- build: { success: boolean; errors?: string[]; warnings?: string[]; diagnostics: SerializedDiagnostic[] };
29
- lint?: LintWithProgramResult;
30
- }
31
-
32
- export interface NgtscCombinedBuildEvent {
33
- build: { success: boolean; errors?: string[]; warnings?: string[] };
34
- lint?: LintWithProgramResult;
35
- }
36
-
37
- //#endregion
38
-
39
- //#region CompilerOptions helpers
40
-
41
- export function buildCompilerOptions(
42
- baseOptions: ts.CompilerOptions,
43
- pkgDir: string,
44
- output: BuildOutput,
45
- ): ts.CompilerOptions {
46
- const needsEmit = output.js || output.dts;
47
- const options: ts.CompilerOptions = {
48
- ...baseOptions,
49
- sourceMap: false,
50
- outDir: path.join(pkgDir, "dist"),
51
- incremental: true,
52
- tsBuildInfoFile: path.join(
53
- pkgDir,
54
- ".cache",
55
- needsEmit ? "ngtsc-build.tsbuildinfo" : "ngtsc-typecheck.tsbuildinfo",
56
- ),
57
- };
58
-
59
- if (output.js && output.dts) {
60
- options.noEmit = false;
61
- options.declaration = true;
62
- options.declarationMap = true;
63
- options.emitDeclarationOnly = false;
64
- options.declarationDir = path.join(pkgDir, "dist");
65
- } else if (output.js && !output.dts) {
66
- options.noEmit = false;
67
- options.declaration = false;
68
- options.declarationMap = false;
69
- options.emitDeclarationOnly = false;
70
- } else if (!output.js && output.dts) {
71
- options.noEmit = false;
72
- options.declaration = true;
73
- options.declarationMap = true;
74
- options.emitDeclarationOnly = true;
75
- options.declarationDir = path.join(pkgDir, "dist");
76
- } else {
77
- // 둘 다 false — 타입체크만 수행
78
- options.noEmit = true;
79
- options.declaration = false;
80
- options.declarationMap = false;
81
- options.emitDeclarationOnly = false;
82
- }
83
-
84
- return options;
85
- }
86
-
87
- //#endregion
88
-
89
- //#region SCSS loadPaths helper
90
-
91
- export function buildScssLoadPaths(info: NgtscBuildInfo): string[] {
92
- return [
93
- path.join(info.pkgDir, "scss"),
94
- path.join(info.cwd, "node_modules"),
95
- ];
96
- }
97
-
98
- //#endregion
7
+ import { compileScssFile, compileScssString } from "./scss-compiler";
8
+ import { createOutputPathRewriter, rewriteScssImports } from "../utils/output-path-rewriter";
99
9
 
100
10
  export function trackDeps(
101
11
  depsMap: Map<string, Set<string>>,
@@ -130,6 +40,52 @@ export interface SideEffectScssOptions {
130
40
  registry?: Map<string, SideEffectScssEntry>;
131
41
  }
132
42
 
43
+ //#region Library SCSS transform
44
+
45
+ /**
46
+ * Library용 transformStylesheet 콜백 팩토리.
47
+ * AngularCompiler의 transformStylesheet 옵션에 주입된다.
48
+ *
49
+ * - 외부 .scss 파일: compileScssFile로 CSS 반환 + 의존성 기록
50
+ * - 외부 비-SCSS 파일 (.css 등): null 반환 (readResource가 처리)
51
+ * - 인라인 스타일: compileScssString으로 CSS 반환 + 의존성 기록
52
+ * - 에러 시: scssErrors에 추가, SCSS error comment 반환
53
+ */
54
+ export function createLibraryTransformStylesheet(
55
+ loadPaths: string[],
56
+ scssErrors: string[],
57
+ scssDependencies: Map<string, Set<string>>,
58
+ ): (data: string, containingFile: string, stylesheetFile?: string) => Promise<string | null> {
59
+ return (
60
+ data: string,
61
+ containingFile: string,
62
+ stylesheetFile?: string,
63
+ ): Promise<string | null> => {
64
+ try {
65
+ if (stylesheetFile != null && stylesheetFile.endsWith(".scss")) {
66
+ const result = compileScssFile(stylesheetFile, loadPaths);
67
+ trackDeps(scssDependencies, containingFile, result.dependencies);
68
+ return Promise.resolve(result.css);
69
+ }
70
+
71
+ if (stylesheetFile != null) {
72
+ // .css 등 비-SCSS 파일 → null 반환 (readResource가 처리)
73
+ return Promise.resolve(null);
74
+ }
75
+
76
+ // 인라인 스타일 — SCSS로 컴파일
77
+ const result = compileScssString(data, containingFile, loadPaths);
78
+ trackDeps(scssDependencies, containingFile, result.dependencies);
79
+ return Promise.resolve(result.css);
80
+ } catch (err) {
81
+ scssErrors.push(formatScssError(err, containingFile));
82
+ return Promise.resolve("/* SCSS compilation error */");
83
+ }
84
+ };
85
+ }
86
+
87
+ //#endregion
88
+
133
89
  //#region Side-effect SCSS
134
90
 
135
91
  /**
@@ -184,3 +140,80 @@ export function compileGlobalScss(
184
140
 
185
141
  //#endregion
186
142
 
143
+ //#region writeEmitResults
144
+
145
+ export interface WriteEmitResultsOptions {
146
+ /** 출력 대상 패키지 디렉토리 */
147
+ pkgDir: string;
148
+ /** emit 결과 필터 (src/ 하위만 등) */
149
+ sourceFilter?: (fileName: string) => boolean;
150
+ /** side-effect SCSS 옵션 */
151
+ scss?: SideEffectScssOptions;
152
+ }
153
+
154
+ /**
155
+ * emitAffectedFiles 결과를 output-path-rewriting 적용 후 파일로 쓴다.
156
+ * scss 옵션이 제공되면 .js 파일 내 .scss side-effect import를 처리한다:
157
+ * 1. import 경로를 .scss → .css로 변환
158
+ * 2. 참조된 SCSS 파일을 CSS로 컴파일하여 dist에 출력
159
+ */
160
+ export function writeEmitResults(
161
+ emitResults: Iterable<{ filename: string; contents: string; sourceFileName?: string }>,
162
+ pkgDir: string,
163
+ scss?: SideEffectScssOptions,
164
+ ): void {
165
+ logger.debug("emit 결과 파일 쓰기 시작");
166
+ const rewritePath = createOutputPathRewriter(pkgDir);
167
+ for (const { filename, contents, sourceFileName } of emitResults) {
168
+ const rewrite = rewritePath(filename, contents);
169
+ if (rewrite == null) continue;
170
+ let [newPath, newContent] = rewrite;
171
+
172
+ // .js 파일 내 side-effect SCSS import 처리
173
+ if (scss != null && newPath.endsWith(".js")) {
174
+ const { text, scssImports } = rewriteScssImports(newContent);
175
+ newContent = text;
176
+
177
+ // 새 항목 등록 전에 이 소스 파일의 기존 레지스트리 항목 제거
178
+ if (scss.registry != null && sourceFileName != null) {
179
+ for (const [key, entry] of scss.registry) {
180
+ if (entry.sourceFileName === sourceFileName) {
181
+ scss.registry.delete(key);
182
+ }
183
+ }
184
+ }
185
+
186
+ if (scssImports.length > 0 && sourceFileName != null) {
187
+ const sourceDir = path.dirname(sourceFileName);
188
+ const outputDir = path.dirname(newPath);
189
+
190
+ for (const scssImport of scssImports) {
191
+ const scssAbsPath = path.resolve(sourceDir, scssImport);
192
+ const cssFileName = scssImport.replace(/\.scss$/, ".css");
193
+ const cssAbsPath = path.resolve(outputDir, cssFileName);
194
+
195
+ // 레지스트리가 제공된 경우 등록 (scssAbsPath를 키로 사용하여 중복 방지)
196
+ if (scss.registry != null) {
197
+ scss.registry.set(scssAbsPath, { scssAbsPath, cssAbsPath, sourceFileName });
198
+ }
199
+
200
+ try {
201
+ const result = compileScssFile(scssAbsPath, scss.loadPaths);
202
+ fs.mkdirSync(path.dirname(cssAbsPath), { recursive: true });
203
+ fs.writeFileSync(cssAbsPath, result.css, "utf-8");
204
+ trackDeps(scss.scssDependencies, sourceFileName, result.dependencies);
205
+ } catch (err) {
206
+ scss.scssErrors.push(formatScssError(err, scssAbsPath));
207
+ }
208
+ }
209
+ }
210
+ }
211
+
212
+ fs.mkdirSync(path.dirname(newPath), { recursive: true });
213
+ fs.writeFileSync(newPath, newContent, "utf-8");
214
+ }
215
+ logger.debug("emit 결과 파일 쓰기 완료");
216
+ }
217
+
218
+ //#endregion
219
+