@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
@@ -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,102 +1,32 @@
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";
7
+ import { compileScssFile, compileScssString } from "./scss-compiler";
8
+ import { createOutputPathRewriter, rewriteScssImports } from "../utils/output-path-rewriter";
13
9
 
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;
10
+ /**
11
+ * 정방향 의존성 맵(소유파일→의존성 Set)에서 역방향 인덱스(의존성→소유파일 Set)를 구축한다.
12
+ */
13
+ export function buildReverseDeps(
14
+ forwardDeps: ReadonlyMap<string, ReadonlySet<string>>,
15
+ ): Map<string, Set<string>> {
16
+ const reverse = new Map<string, Set<string>>();
17
+ for (const [ownerFile, deps] of forwardDeps) {
18
+ for (const dep of deps) {
19
+ let owners = reverse.get(dep);
20
+ if (owners == null) {
21
+ owners = new Set();
22
+ reverse.set(dep, owners);
23
+ }
24
+ owners.add(ownerFile);
25
+ }
82
26
  }
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
- ];
27
+ return reverse;
96
28
  }
97
29
 
98
- //#endregion
99
-
100
30
  export function trackDeps(
101
31
  depsMap: Map<string, Set<string>>,
102
32
  containingFile: string,
@@ -128,13 +58,64 @@ export interface SideEffectScssOptions {
128
58
  scssErrors: string[];
129
59
  scssDependencies: Map<string, Set<string>>;
130
60
  registry?: Map<string, SideEffectScssEntry>;
61
+ /** sourceFileName → Set<registryKey(=scssAbsPath)> 역방향 인덱스. O(1) 삭제용 */
62
+ registryReverseIndex?: Map<string, Set<string>>;
63
+ /** side-effect SCSS별 의존성 맵. compileScssFile 후 갱신. 증분 판별용 */
64
+ sideEffectScssDeps?: Map<string, Set<string>>;
131
65
  }
132
66
 
67
+ //#region Library SCSS transform
68
+
69
+ /**
70
+ * Library용 transformStylesheet 콜백 팩토리.
71
+ * AngularCompiler의 transformStylesheet 옵션에 주입된다.
72
+ *
73
+ * - 외부 .scss 파일: compileScssFile로 CSS 반환 + 의존성 기록
74
+ * - 외부 비-SCSS 파일 (.css 등): null 반환 (readResource가 처리)
75
+ * - 인라인 스타일: compileScssString으로 CSS 반환 + 의존성 기록
76
+ * - 에러 시: scssErrors에 추가, SCSS error comment 반환
77
+ */
78
+ export function createLibraryTransformStylesheet(
79
+ loadPaths: string[],
80
+ scssErrors: string[],
81
+ scssDependencies: Map<string, Set<string>>,
82
+ ): (data: string, containingFile: string, stylesheetFile?: string) => Promise<string | null> {
83
+ return (
84
+ data: string,
85
+ containingFile: string,
86
+ stylesheetFile?: string,
87
+ ): Promise<string | null> => {
88
+ try {
89
+ if (stylesheetFile != null && stylesheetFile.endsWith(".scss")) {
90
+ const result = compileScssFile(stylesheetFile, loadPaths);
91
+ trackDeps(scssDependencies, containingFile, result.dependencies);
92
+ return Promise.resolve(result.css);
93
+ }
94
+
95
+ if (stylesheetFile != null) {
96
+ // .css 등 비-SCSS 파일 → null 반환 (readResource가 처리)
97
+ return Promise.resolve(null);
98
+ }
99
+
100
+ // 인라인 스타일 — SCSS로 컴파일
101
+ const result = compileScssString(data, containingFile, loadPaths);
102
+ trackDeps(scssDependencies, containingFile, result.dependencies);
103
+ return Promise.resolve(result.css);
104
+ } catch (err) {
105
+ scssErrors.push(formatScssError(err, containingFile));
106
+ return Promise.resolve("/* SCSS compilation error */");
107
+ }
108
+ };
109
+ }
110
+
111
+ //#endregion
112
+
133
113
  //#region Side-effect SCSS
134
114
 
135
115
  /**
136
- * 레지스트리의 모든 side-effect SCSS 항목을 CSS로 컴파일한다.
137
- * compileGlobalScss와 동일한 패턴 항상 모든 항목을 재컴파일한다.
116
+ * 레지스트리의 side-effect SCSS 항목을 CSS로 컴파일한다.
117
+ * changedScssFiles가 제공되면 영향받는 항목만 재컴파일한다 (증분 모드).
118
+ * changedScssFiles가 미제공이면 전체 재컴파일한다 (초기 빌드).
138
119
  * 에러 발생 시 scssErrors에 추가하고 기존 CSS 파일을 보존한다.
139
120
  */
140
121
  export function compileSideEffectScss(
@@ -142,14 +123,32 @@ export function compileSideEffectScss(
142
123
  loadPaths: string[],
143
124
  scssErrors: string[],
144
125
  scssDependencies: Map<string, Set<string>>,
126
+ changedScssFiles?: ReadonlySet<string>,
127
+ sideEffectScssDeps?: Map<string, Set<string>>,
145
128
  ): void {
146
129
  logger.debug(`side-effect SCSS 컴파일 시작 (${registry.size}개)`);
147
130
  for (const entry of registry.values()) {
131
+ // 증분 모드: 영향받는 항목만 재컴파일
132
+ if (changedScssFiles != null && sideEffectScssDeps != null) {
133
+ const isDirectHit = changedScssFiles.has(entry.scssAbsPath);
134
+ let isDepsHit = false;
135
+ const deps = sideEffectScssDeps.get(entry.scssAbsPath);
136
+ if (deps != null) {
137
+ for (const d of deps) {
138
+ if (changedScssFiles.has(d)) { isDepsHit = true; break; }
139
+ }
140
+ }
141
+ if (!isDirectHit && !isDepsHit) continue;
142
+ }
148
143
  try {
149
144
  const result = compileScssFile(entry.scssAbsPath, loadPaths);
150
145
  fs.mkdirSync(path.dirname(entry.cssAbsPath), { recursive: true });
151
146
  fs.writeFileSync(entry.cssAbsPath, result.css, "utf-8");
152
147
  trackDeps(scssDependencies, entry.sourceFileName, result.dependencies);
148
+ // 의존성 기록 (증분 판별용)
149
+ if (sideEffectScssDeps != null) {
150
+ sideEffectScssDeps.set(entry.scssAbsPath, new Set(result.dependencies));
151
+ }
153
152
  } catch (err) {
154
153
  scssErrors.push(formatScssError(err, entry.scssAbsPath));
155
154
  }
@@ -184,3 +183,105 @@ export function compileGlobalScss(
184
183
 
185
184
  //#endregion
186
185
 
186
+ //#region writeEmitResults
187
+
188
+ export interface WriteEmitResultsOptions {
189
+ /** 출력 대상 패키지 디렉토리 */
190
+ pkgDir: string;
191
+ /** emit 결과 필터 (src/ 하위만 등) */
192
+ sourceFilter?: (fileName: string) => boolean;
193
+ /** side-effect SCSS 옵션 */
194
+ scss?: SideEffectScssOptions;
195
+ }
196
+
197
+ /**
198
+ * emitAffectedFiles 결과를 output-path-rewriting 적용 후 파일로 쓴다.
199
+ * scss 옵션이 제공되면 .js 파일 내 .scss side-effect import를 처리한다:
200
+ * 1. import 경로를 .scss → .css로 변환
201
+ * 2. 참조된 SCSS 파일을 CSS로 컴파일하여 dist에 출력
202
+ */
203
+ export function writeEmitResults(
204
+ emitResults: Iterable<{ filename: string; contents: string; sourceFileName?: string }>,
205
+ pkgDir: string,
206
+ scss?: SideEffectScssOptions,
207
+ ): void {
208
+ logger.debug("emit 결과 파일 쓰기 시작");
209
+ const rewritePath = createOutputPathRewriter(pkgDir);
210
+ for (const { filename, contents, sourceFileName } of emitResults) {
211
+ const rewrite = rewritePath(filename, contents);
212
+ if (rewrite == null) continue;
213
+ let [newPath, newContent] = rewrite;
214
+
215
+ // .js 파일 내 side-effect SCSS import 처리
216
+ if (scss != null && newPath.endsWith(".js")) {
217
+ const { text, scssImports } = rewriteScssImports(newContent);
218
+ newContent = text;
219
+
220
+ // 새 항목 등록 전에 이 소스 파일의 기존 레지스트리 항목 제거
221
+ if (scss.registry != null && sourceFileName != null) {
222
+ if (scss.registryReverseIndex != null) {
223
+ // O(1) 삭제: 역방향 인덱스 활용
224
+ const keys = scss.registryReverseIndex.get(sourceFileName);
225
+ if (keys != null) {
226
+ for (const key of keys) {
227
+ scss.registry.delete(key);
228
+ }
229
+ scss.registryReverseIndex.delete(sourceFileName);
230
+ }
231
+ } else {
232
+ // 폴백: O(n) 순회 삭제
233
+ for (const [key, entry] of scss.registry) {
234
+ if (entry.sourceFileName === sourceFileName) {
235
+ scss.registry.delete(key);
236
+ }
237
+ }
238
+ }
239
+ }
240
+
241
+ if (scssImports.length > 0 && sourceFileName != null) {
242
+ const sourceDir = path.dirname(sourceFileName);
243
+ const outputDir = path.dirname(newPath);
244
+
245
+ for (const scssImport of scssImports) {
246
+ const scssAbsPath = path.resolve(sourceDir, scssImport);
247
+ const cssFileName = scssImport.replace(/\.scss$/, ".css");
248
+ const cssAbsPath = path.resolve(outputDir, cssFileName);
249
+
250
+ // 레지스트리가 제공된 경우 등록 (scssAbsPath를 키로 사용하여 중복 방지)
251
+ if (scss.registry != null) {
252
+ scss.registry.set(scssAbsPath, { scssAbsPath, cssAbsPath, sourceFileName });
253
+ // 역방향 인덱스 갱신
254
+ if (scss.registryReverseIndex != null) {
255
+ let keys = scss.registryReverseIndex.get(sourceFileName);
256
+ if (keys == null) {
257
+ keys = new Set();
258
+ scss.registryReverseIndex.set(sourceFileName, keys);
259
+ }
260
+ keys.add(scssAbsPath);
261
+ }
262
+ }
263
+
264
+ try {
265
+ const result = compileScssFile(scssAbsPath, scss.loadPaths);
266
+ fs.mkdirSync(path.dirname(cssAbsPath), { recursive: true });
267
+ fs.writeFileSync(cssAbsPath, result.css, "utf-8");
268
+ trackDeps(scss.scssDependencies, sourceFileName, result.dependencies);
269
+ // side-effect SCSS 의존성 기록 (증분 판별용)
270
+ if (scss.sideEffectScssDeps != null) {
271
+ scss.sideEffectScssDeps.set(scssAbsPath, new Set(result.dependencies));
272
+ }
273
+ } catch (err) {
274
+ scss.scssErrors.push(formatScssError(err, scssAbsPath));
275
+ }
276
+ }
277
+ }
278
+ }
279
+
280
+ fs.mkdirSync(path.dirname(newPath), { recursive: true });
281
+ fs.writeFileSync(newPath, newContent, "utf-8");
282
+ }
283
+ logger.debug("emit 결과 파일 쓰기 완료");
284
+ }
285
+
286
+ //#endregion
287
+