@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,647 @@
1
+ import path from "path";
2
+ import fs from "fs";
3
+ import os from "os";
4
+ import ts from "typescript";
5
+ import type esbuild from "esbuild";
6
+ import { consola } from "consola";
7
+ import { JavaScriptTransformer, Cache as AngularCache } from "@angular/build/private";
8
+ import type { AngularSourceFileCache } from "../angular/angular-compiler.js";
9
+ import type { SerializedDiagnostic } from "../typecheck/typecheck-serialization.js";
10
+ import { SdTsCompiler } from "../ts-compiler/SdTsCompiler.js";
11
+ import type { ISdTsCompilerResult } from "../ts-compiler/sd-ts-compiler-result.js";
12
+ import { FileReferenceTracker } from "./file-reference-tracker.js";
13
+ import { LmdbCacheStore } from "./lmdb-cache-store.js";
14
+ import { createCachedLoad, type LoadResultCache } from "./load-result-cache.js";
15
+ import { collectHmrCandidates, HMR_MODIFIED_FILE_LIMIT } from "../angular/hmr-candidates.js";
16
+ import { createWorkerTransformer } from "../angular/web-worker-transformer.js";
17
+
18
+ const logger = consola.withTag("sd:cli:angular-plugin");
19
+
20
+ //#region Types
21
+
22
+ export interface AngularCompilerPluginOptions {
23
+ tsconfig: string;
24
+ sourcemap: boolean;
25
+ advancedOptimizations: boolean;
26
+ thirdPartySourcemaps: boolean;
27
+ incremental: boolean;
28
+ includeTestMetadata?: boolean;
29
+ templateUpdates?: Map<string, string>;
30
+
31
+ sourceFileCache?: AngularSourceFileCache;
32
+ typeScriptFileCache?: Map<string, string | Uint8Array>;
33
+ loadResultCache?: LoadResultCache;
34
+
35
+ persistentCachePath?: string;
36
+
37
+ transformStylesheet?: (
38
+ data: string,
39
+ containingFile: string,
40
+ stylesheetFile?: string,
41
+ ) => Promise<string | null>;
42
+
43
+ externalStylesheets?: Map<string, string>;
44
+
45
+ /** SCSS 의존성 Map (transformStylesheet가 기록, Plugin이 FileReferenceTracker에 등록) */
46
+ stylesheetDependencies?: Map<string, Set<string>>;
47
+ /** SCSS 에러 배열 (transformStylesheet가 기록, Plugin이 esbuild errors로 변환) */
48
+ stylesheetErrors?: string[];
49
+ }
50
+
51
+ interface AdditionalResult {
52
+ outputFiles?: esbuild.OutputFile[];
53
+ metafile?: esbuild.Metafile;
54
+ errors?: esbuild.PartialMessage[];
55
+ }
56
+
57
+ //#endregion
58
+
59
+ //#region compilerOptions 변환
60
+
61
+ export function createCompilerOptionsTransformer(
62
+ options: AngularCompilerPluginOptions,
63
+ preserveSymlinks: boolean | undefined,
64
+ ): (compilerOptions: ts.CompilerOptions) => ts.CompilerOptions {
65
+ return (compilerOptions: ts.CompilerOptions) => {
66
+ // target < ES2022이면 강제 ES2022
67
+ if (compilerOptions.target == null || compilerOptions.target < ts.ScriptTarget.ES2022) {
68
+ compilerOptions.target = ts.ScriptTarget.ES2022;
69
+ compilerOptions.useDefineForClassFields ??= false;
70
+ }
71
+
72
+ // module < ES2015이면 강제 ES2022
73
+ if (compilerOptions.module == null || compilerOptions.module < ts.ModuleKind.ES2015) {
74
+ compilerOptions.module = ts.ModuleKind.ES2022;
75
+ }
76
+
77
+ // compilationMode: partial → full
78
+ if ((compilerOptions as Record<string, unknown>)["compilationMode"] === "partial") {
79
+ (compilerOptions as Record<string, unknown>)["compilationMode"] = "full";
80
+ }
81
+
82
+ return {
83
+ ...compilerOptions,
84
+ noEmitOnError: false,
85
+ composite: false,
86
+ declaration: false,
87
+ declarationMap: false,
88
+ inlineSources: !!options.sourcemap,
89
+ inlineSourceMap: !!options.sourcemap,
90
+ sourceMap: undefined,
91
+ mapRoot: undefined,
92
+ sourceRoot: undefined,
93
+ preserveSymlinks,
94
+ incremental: options.persistentCachePath != null,
95
+ tsBuildInfoFile:
96
+ options.persistentCachePath != null
97
+ ? path.join(options.persistentCachePath, ".tsbuildinfo")
98
+ : undefined,
99
+ _enableHmr: !!options.templateUpdates,
100
+ supportTestBed: !!options.includeTestMetadata,
101
+ supportJitMode: !!options.includeTestMetadata,
102
+ } as ts.CompilerOptions;
103
+ };
104
+ }
105
+
106
+ //#endregion
107
+
108
+ //#region diagnostics 변환
109
+
110
+ export function convertDiagnostic(
111
+ diagnostic: ts.Diagnostic,
112
+ cwd: string,
113
+ ): esbuild.PartialMessage {
114
+ const text = ts.flattenDiagnosticMessageText(diagnostic.messageText, "\n");
115
+ let location: esbuild.PartialMessage["location"] = null;
116
+
117
+ if (diagnostic.file != null && diagnostic.start != null) {
118
+ const pos = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start);
119
+ const lineStart = diagnostic.file.getLineStarts()[pos.line];
120
+ const lineEnd = diagnostic.file.getLineStarts()[pos.line + 1] ?? diagnostic.file.text.length;
121
+ const lineText = diagnostic.file.text.slice(lineStart, lineEnd).replace(/\r?\n$/, "");
122
+ location = {
123
+ file: path.relative(cwd, diagnostic.file.fileName),
124
+ line: pos.line + 1,
125
+ column: pos.character,
126
+ lineText,
127
+ length: diagnostic.length ?? 0,
128
+ };
129
+ }
130
+
131
+ return { text, location };
132
+ }
133
+
134
+ export function convertSerializedDiagnosticToEsbuild(
135
+ d: SerializedDiagnostic,
136
+ program: ts.Program,
137
+ cwd: string,
138
+ ): esbuild.PartialMessage {
139
+ let location: esbuild.PartialMessage["location"] = null;
140
+ if (d.file != null && d.start != null) {
141
+ const sf = program.getSourceFile(d.file.fileName);
142
+ if (sf != null) {
143
+ const pos = sf.getLineAndCharacterOfPosition(d.start);
144
+ const lineStart = sf.getLineStarts()[pos.line];
145
+ const lineEnd = sf.getLineStarts()[pos.line + 1] ?? sf.text.length;
146
+ const lineText = sf.text.slice(lineStart, lineEnd).replace(/\r?\n$/, "");
147
+ location = {
148
+ file: path.relative(cwd, d.file.fileName),
149
+ line: pos.line + 1,
150
+ column: pos.character,
151
+ lineText,
152
+ length: d.length ?? 0,
153
+ };
154
+ }
155
+ }
156
+ return { text: d.messageText, location };
157
+ }
158
+
159
+ //#endregion
160
+
161
+ //#region bundleWebWorker
162
+
163
+ /**
164
+ * Worker 파일을 esbuild.buildSync()로 별도 ESM 번들로 빌드한다.
165
+ * TypeScript transformer 내에서 동기적으로 호출되므로 sync API를 사용한다.
166
+ */
167
+ export function bundleWebWorker(
168
+ build: esbuild.PluginBuild,
169
+ sourcemap: boolean,
170
+ workerFile: string,
171
+ ): esbuild.BuildResult {
172
+ try {
173
+ return build.esbuild.buildSync({
174
+ ...build.initialOptions,
175
+ platform: "browser",
176
+ write: false,
177
+ bundle: true,
178
+ metafile: true,
179
+ format: "esm",
180
+ entryNames: "worker-[hash]",
181
+ entryPoints: [workerFile],
182
+ sourcemap,
183
+ supported: undefined,
184
+ plugins: undefined,
185
+ });
186
+ } catch (error) {
187
+ if (
188
+ error != null &&
189
+ typeof error === "object" &&
190
+ "errors" in error &&
191
+ "warnings" in error
192
+ ) {
193
+ return error as esbuild.BuildResult;
194
+ }
195
+ throw error;
196
+ }
197
+ }
198
+
199
+ //#endregion
200
+
201
+ //#region onLoad 헬퍼
202
+
203
+ const POTENTIAL_METADATA_REGEX =
204
+ /@angular\/core|@Component|@Directive|@Injectable|@Pipe|@NgModule/;
205
+
206
+ export function requiresAngularCompiler(contents: string): boolean {
207
+ return POTENTIAL_METADATA_REGEX.test(contents);
208
+ }
209
+
210
+ export function createMissingFileDiagnostic(
211
+ request: string,
212
+ original: string,
213
+ root: string,
214
+ angular: boolean,
215
+ ): esbuild.PartialMessage {
216
+ const relativeRequest = path.relative(root, request);
217
+ const notes: esbuild.PartialNote[] = [];
218
+
219
+ if (angular) {
220
+ notes.push({
221
+ text:
222
+ "Files containing Angular metadata ('@Component'/'@Directive'/etc.) must be part of the TypeScript compilation." +
223
+ " You can ensure the file is part of the TypeScript program via the 'files' or 'include' property.",
224
+ });
225
+ } else {
226
+ notes.push({
227
+ text:
228
+ "The file will be bundled and included in the output but will not be type-checked at build time." +
229
+ " To remove this message you can add the file to the TypeScript program via the 'files' or 'include' property.",
230
+ });
231
+ }
232
+
233
+ const relativeOriginal = path.relative(root, original);
234
+ if (relativeRequest !== relativeOriginal) {
235
+ notes.push({
236
+ text: `File is requested from a file replacement of '${relativeOriginal}'.`,
237
+ });
238
+ }
239
+
240
+ return {
241
+ text: `File '${relativeRequest}' not found in TypeScript compilation.`,
242
+ notes,
243
+ };
244
+ }
245
+
246
+ //#endregion
247
+
248
+ //#region Plugin 팩토리
249
+
250
+ export function createAngularCompilerPlugin(
251
+ pluginOptions: AngularCompilerPluginOptions,
252
+ ): esbuild.Plugin {
253
+ return {
254
+ name: "sd-angular-compiler",
255
+ setup(build: esbuild.PluginBuild) {
256
+ const preserveSymlinks = build.initialOptions.preserveSymlinks;
257
+ const cwd = build.initialOptions.absWorkingDir ?? process.cwd();
258
+
259
+ // ── define 주입 ──
260
+ build.initialOptions.define ??= {};
261
+ build.initialOptions.define["ngI18nClosureMode"] ??= "false";
262
+
263
+ // ── LMDB 캐시 초기화 ──
264
+ let cacheStore: LmdbCacheStore<Uint8Array> | undefined;
265
+ if (pluginOptions.persistentCachePath != null) {
266
+ try {
267
+ cacheStore = new LmdbCacheStore(
268
+ path.join(pluginOptions.persistentCachePath, "angular-compiler.db"),
269
+ );
270
+ } catch (e) {
271
+ logger.warn("LMDB 캐시 초기화 실패:", e instanceof Error ? e.message : String(e));
272
+ }
273
+ }
274
+
275
+ // ── JavaScriptTransformer 초기화 ──
276
+ const maxWorkers = Math.max(Math.floor((os.cpus().length * 7) / 8), 1);
277
+ const javascriptTransformer = new JavaScriptTransformer(
278
+ {
279
+ sourcemap: !!pluginOptions.sourcemap,
280
+ thirdPartySourcemaps: pluginOptions.thirdPartySourcemaps,
281
+ advancedOptimizations: pluginOptions.advancedOptimizations,
282
+ jit: pluginOptions.includeTestMetadata === true,
283
+ },
284
+ maxWorkers,
285
+ cacheStore != null ? new AngularCache(cacheStore, "jstransformer") : undefined,
286
+ );
287
+
288
+ // ── 내부 상태 ──
289
+ const typeScriptFileCache: Map<string, string | Uint8Array> =
290
+ pluginOptions.typeScriptFileCache ?? new Map();
291
+ const additionalResults = new Map<string, AdditionalResult>();
292
+ const referencedFileTracker = new FileReferenceTracker();
293
+ let sdTsCompiler: SdTsCompiler | undefined;
294
+ let lastResult: ISdTsCompilerResult | undefined;
295
+ let hasCompilationErrors = true;
296
+ // TS/JS onLoad에서 참조할 플래그 (onStart에서 compilerOptions 기반으로 결정)
297
+ let shouldTsIgnoreJs = true;
298
+ let useTypeScriptTranspilation = true;
299
+
300
+ async function hasSideEffects(filePath: string): Promise<boolean | undefined> {
301
+ if (!pluginOptions.advancedOptimizations) {
302
+ return undefined;
303
+ }
304
+ const { sideEffects } = await build.resolve(filePath, {
305
+ kind: "import-statement",
306
+ resolveDir: cwd,
307
+ });
308
+ return sideEffects;
309
+ }
310
+
311
+ // ── 서브함수: WebWorker 프로세서 생성 ──
312
+ function createWebWorkerProcessor(
313
+ errors: esbuild.PartialMessage[],
314
+ warnings: esbuild.PartialMessage[],
315
+ ): (workerFile: string, containingFile: string) => string {
316
+ return (workerFile: string, containingFile: string): string => {
317
+ const fullWorkerPath = path.join(path.dirname(containingFile), workerFile);
318
+ const workerResult = bundleWebWorker(build, pluginOptions.sourcemap, fullWorkerPath);
319
+
320
+ warnings.push(...workerResult.warnings);
321
+
322
+ if (workerResult.errors.length > 0) {
323
+ errors.push(...workerResult.errors);
324
+ // 에러 파일 경로 추적 (rebuild 허용)
325
+ referencedFileTracker.add(
326
+ containingFile,
327
+ workerResult.errors
328
+ .map((e) => e.location?.file)
329
+ .filter((f): f is string => f != null)
330
+ .map((f) => path.join(cwd, f)),
331
+ );
332
+ additionalResults.set(fullWorkerPath, { errors: workerResult.errors });
333
+ return workerFile;
334
+ }
335
+
336
+ additionalResults.set(fullWorkerPath, {
337
+ outputFiles: workerResult.outputFiles,
338
+ metafile: workerResult.metafile,
339
+ });
340
+
341
+ // metafile.inputs → FileReferenceTracker
342
+ if (workerResult.metafile != null) {
343
+ referencedFileTracker.add(
344
+ containingFile,
345
+ Object.keys(workerResult.metafile.inputs).map((input) => path.join(cwd, input)),
346
+ );
347
+ }
348
+
349
+ // worker-[HASH].js 파일 찾기
350
+ const workerCodeFile = workerResult.outputFiles?.find((file) =>
351
+ /^worker-[A-Z0-9]{8}\.[cm]?js$/.test(path.basename(file.path)),
352
+ );
353
+ if (workerCodeFile == null) {
354
+ errors.push({ text: `Web Worker bundled code file not found: ${fullWorkerPath}`, location: null });
355
+ return workerFile;
356
+ }
357
+ const outdir = build.initialOptions.outdir ?? "";
358
+ const workerCodePath = path.relative(outdir, workerCodeFile.path);
359
+ return workerCodePath.replaceAll("\\", "/");
360
+ };
361
+ }
362
+
363
+ // ── onStart ──
364
+ build.onStart(async () => {
365
+ const result: esbuild.OnStartResult = {};
366
+ const errors: esbuild.PartialMessage[] = [];
367
+ const warnings: esbuild.PartialMessage[] = [];
368
+
369
+ // ── stylesheetErrors 리셋 (stale 에러 방지) ──
370
+ if (pluginOptions.stylesheetErrors != null) {
371
+ pluginOptions.stylesheetErrors.length = 0;
372
+ }
373
+
374
+ try {
375
+ const sourceFileCache = pluginOptions.sourceFileCache;
376
+ const isIncremental =
377
+ sdTsCompiler != null &&
378
+ sourceFileCache != null &&
379
+ sourceFileCache.modifiedFiles.size > 0;
380
+
381
+ // ── HMR: staleSourceFiles 캡처 (compileAsync 전에 수행) ──
382
+ let staleSourceFiles: Map<string, ts.SourceFile> | undefined;
383
+ let expandedModifiedFiles: Set<string> | undefined;
384
+
385
+ if (isIncremental) {
386
+ const useHmr =
387
+ pluginOptions.templateUpdates != null &&
388
+ sourceFileCache.modifiedFiles.size <= HMR_MODIFIED_FILE_LIMIT;
389
+
390
+ if (useHmr && lastResult != null) {
391
+ for (const modifiedFile of sourceFileCache.modifiedFiles) {
392
+ const sf = lastResult.program.getSourceFile(modifiedFile);
393
+ if (sf != null) {
394
+ staleSourceFiles ??= new Map();
395
+ staleSourceFiles.set(modifiedFile, sf);
396
+ }
397
+ }
398
+ }
399
+
400
+ // referencedFileTracker 확장
401
+ expandedModifiedFiles = referencedFileTracker.update(
402
+ sourceFileCache.modifiedFiles,
403
+ );
404
+
405
+ // stale additionalResults 제거
406
+ for (const file of expandedModifiedFiles) {
407
+ additionalResults.delete(file);
408
+ }
409
+ }
410
+
411
+ // ── SdTsCompiler 인스턴스 생성 (첫 빌드 시) ──
412
+ if (sdTsCompiler == null) {
413
+ sdTsCompiler = new SdTsCompiler({
414
+ pkgDir: path.dirname(pluginOptions.tsconfig),
415
+ cwd,
416
+ output: { js: true, dts: false },
417
+ sourceFileCache: pluginOptions.sourceFileCache,
418
+ transformStylesheet: pluginOptions.transformStylesheet,
419
+ externalStylesheets: pluginOptions.externalStylesheets,
420
+ compilerOptionsTransformer: createCompilerOptionsTransformer(
421
+ pluginOptions,
422
+ preserveSymlinks,
423
+ ),
424
+ });
425
+ }
426
+
427
+ // ── processWebWorker + workerTransformer ──
428
+ const processWebWorker = createWebWorkerProcessor(errors, warnings);
429
+ const workerTransformer = createWorkerTransformer(processWebWorker);
430
+
431
+ // ── compileAsync ──
432
+ const compileResult = await sdTsCompiler.compileAsync(
433
+ isIncremental ? expandedModifiedFiles : undefined,
434
+ { additionalTransformers: { before: [workerTransformer] } },
435
+ );
436
+
437
+ // ── emitResults → typeScriptFileCache ──
438
+ for (const { contents, sourceFileName } of compileResult.emitResults ?? []) {
439
+ typeScriptFileCache.set(path.normalize(sourceFileName), contents);
440
+ }
441
+
442
+ // ── onLoad 플래그 결정 (첫 빌드에서만) ──
443
+ if (lastResult == null) {
444
+ const co = compileResult.program.getCompilerOptions();
445
+ shouldTsIgnoreJs = !co.allowJs;
446
+ useTypeScriptTranspilation =
447
+ !co.isolatedModules || !!co.sourceMap || !!co.inlineSourceMap;
448
+ }
449
+
450
+ // ── diagnostics → esbuild errors/warnings ──
451
+ for (const d of compileResult.diagnostics) {
452
+ const msg = convertSerializedDiagnosticToEsbuild(d, compileResult.program, cwd);
453
+ if (d.category === ts.DiagnosticCategory.Error) {
454
+ errors.push(msg);
455
+ } else if (d.category === ts.DiagnosticCategory.Warning) {
456
+ warnings.push(msg);
457
+ }
458
+ }
459
+
460
+ // ── stylesheetDependencies → FileReferenceTracker 브릿징 ──
461
+ if (pluginOptions.stylesheetDependencies != null) {
462
+ for (const [containingFile, deps] of pluginOptions.stylesheetDependencies) {
463
+ referencedFileTracker.add(containingFile, deps);
464
+ }
465
+ }
466
+
467
+ // ── stylesheetErrors → esbuild errors 변환 ──
468
+ if (pluginOptions.stylesheetErrors != null) {
469
+ for (const errText of pluginOptions.stylesheetErrors) {
470
+ errors.push({ text: errText, location: null });
471
+ }
472
+ }
473
+
474
+ // ── HMR templateUpdates 수집 (증분 빌드 시) ──
475
+ if (
476
+ isIncremental &&
477
+ staleSourceFiles != null &&
478
+ compileResult.ngtscProgram != null &&
479
+ pluginOptions.templateUpdates != null
480
+ ) {
481
+ const hmrCandidates = collectHmrCandidates(
482
+ sourceFileCache.modifiedFiles,
483
+ compileResult.ngtscProgram,
484
+ staleSourceFiles,
485
+ );
486
+
487
+ if (hmrCandidates.size > 0) {
488
+ const ngCompiler = compileResult.ngtscProgram.compiler;
489
+
490
+ for (const node of hmrCandidates) {
491
+ if (!ts.isClassDeclaration(node)) continue;
492
+
493
+ const componentFilename = node.getSourceFile().fileName;
494
+ let relativePath = path.relative(cwd, componentFilename);
495
+ if (relativePath.startsWith("..")) {
496
+ relativePath = componentFilename;
497
+ }
498
+ relativePath = relativePath.replaceAll("\\", "/");
499
+
500
+ const updateId = encodeURIComponent(
501
+ `${relativePath}@${node.name?.text}`,
502
+ );
503
+ const updateText = (ngCompiler as unknown as { emitHmrUpdateModule?: (node: ts.ClassDeclaration) => string | null })
504
+ .emitHmrUpdateModule?.(node);
505
+
506
+ if (updateText == null) {
507
+ pluginOptions.templateUpdates.clear();
508
+ break;
509
+ }
510
+
511
+ pluginOptions.templateUpdates.set(updateId, updateText);
512
+ }
513
+ }
514
+ }
515
+
516
+ hasCompilationErrors = errors.length > 0;
517
+ lastResult = compileResult;
518
+ } catch (error) {
519
+ hasCompilationErrors = true;
520
+ errors.push({
521
+ text: "Angular compilation failed.",
522
+ location: null,
523
+ notes: [
524
+ {
525
+ text: error instanceof Error ? (error.stack ?? error.message) : `${error}`,
526
+ location: null,
527
+ },
528
+ ],
529
+ });
530
+ }
531
+
532
+ if (errors.length > 0) result.errors = errors;
533
+ if (warnings.length > 0) result.warnings = warnings;
534
+ return result;
535
+ });
536
+
537
+ // ── TS onLoad ── (filter: .ts, .tsx, .mts, .cts, .js, .mjs, .cjs, .jsx)
538
+ build.onLoad({ filter: /\.[cm]?[jt]sx?$/ }, async (args) => {
539
+ const request = path.normalize(args.path);
540
+ const isJS = /\.[cm]?js$/.test(request);
541
+
542
+ // allowJs 미설정 시 JS 파일은 다음 핸들러에 위임
543
+ if (shouldTsIgnoreJs && isJS) {
544
+ return undefined;
545
+ }
546
+
547
+ let contents = typeScriptFileCache.get(request);
548
+
549
+ if (contents == null) {
550
+ // 컴파일 에러가 있으면 빈 contents 반환 (연쇄 에러 방지)
551
+ if (hasCompilationErrors) {
552
+ return { contents: "", loader: "js" as const };
553
+ }
554
+
555
+ // allowJs이고 JS 파일이면 다음 핸들러에 위임
556
+ if (!shouldTsIgnoreJs && isJS) {
557
+ return undefined;
558
+ }
559
+
560
+ // Angular 데코레이터 여부 검사
561
+ const directContents = await fs.promises.readFile(request, "utf-8");
562
+ if (!requiresAngularCompiler(directContents)) {
563
+ return {
564
+ warnings: [createMissingFileDiagnostic(request, args.path, cwd, false)],
565
+ contents: undefined,
566
+ loader: "ts" as const,
567
+ resolveDir: path.dirname(request),
568
+ };
569
+ }
570
+
571
+ return {
572
+ errors: [createMissingFileDiagnostic(request, args.path, cwd, true)],
573
+ };
574
+ }
575
+
576
+ // string 타입이면 JavaScriptTransformer로 추가 변환
577
+ if (typeof contents === "string" && (useTypeScriptTranspilation || isJS)) {
578
+ const sideEffects = await hasSideEffects(request);
579
+ contents = await javascriptTransformer.transformData(
580
+ request,
581
+ contents,
582
+ true, // skipLinker
583
+ sideEffects,
584
+ );
585
+ // Uint8Array로 재캐싱
586
+ typeScriptFileCache.set(request, contents);
587
+ }
588
+
589
+ // loader 결정
590
+ const loader: "js" | "ts" | "tsx" =
591
+ useTypeScriptTranspilation || isJS
592
+ ? "js"
593
+ : request.at(-1) === "x"
594
+ ? "tsx"
595
+ : "ts";
596
+
597
+ return {
598
+ contents,
599
+ loader,
600
+ resolveDir: path.dirname(request),
601
+ };
602
+ });
603
+
604
+ // ── JS onLoad ── (filter: .js, .mjs, .cjs)
605
+ build.onLoad(
606
+ { filter: /\.[cm]?js$/ },
607
+ createCachedLoad(pluginOptions.loadResultCache, async (args) => {
608
+ const request = path.normalize(args.path);
609
+ const sideEffects = await hasSideEffects(request);
610
+ const contents = await javascriptTransformer.transformFile(
611
+ request,
612
+ false, // skipLinker
613
+ sideEffects,
614
+ );
615
+ return {
616
+ contents,
617
+ loader: "js" as const,
618
+ resolveDir: path.dirname(request),
619
+ };
620
+ }),
621
+ );
622
+
623
+ // ── onEnd ──
624
+ build.onEnd((result: esbuild.BuildResult) => {
625
+ for (const { outputFiles, metafile } of additionalResults.values()) {
626
+ if (outputFiles != null && outputFiles.length > 0) {
627
+ result.outputFiles?.push(...outputFiles);
628
+ }
629
+ if (result.metafile != null && metafile != null) {
630
+ Object.assign(result.metafile.inputs, metafile.inputs);
631
+ Object.assign(result.metafile.outputs, metafile.outputs);
632
+ }
633
+ }
634
+ });
635
+
636
+ // ── onDispose ──
637
+ build.onDispose(() => {
638
+ sdTsCompiler = undefined;
639
+ lastResult = undefined;
640
+ void javascriptTransformer.close();
641
+ void cacheStore?.close();
642
+ });
643
+ },
644
+ };
645
+ }
646
+
647
+ //#endregion