@simplysm/sd-cli 14.0.41 → 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 +7 -6
  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
@@ -1,25 +1,18 @@
1
1
  import { describe, it, expect, vi, beforeEach } from "vitest";
2
2
  import type esbuild from "esbuild";
3
- import type { TscPackageBuildResult } from "../../src/utils/tsc-build";
3
+ import type { ISdTsCompilerResult } from "../../src/ts-compiler/sd-ts-compiler-result";
4
4
 
5
5
  //#region Mocks
6
6
 
7
- const mockRunTscPackageBuild = vi.fn<(...args: unknown[]) => TscPackageBuildResult>();
7
+ const mockCompileAsync = vi.fn<() => Promise<ISdTsCompilerResult>>();
8
+ const MockSdTsCompiler = vi.fn().mockImplementation(function () {
9
+ return { compileAsync: mockCompileAsync };
10
+ });
8
11
 
9
- vi.mock("../../src/utils/tsc-build", () => ({
10
- runTscPackageBuild: (...args: unknown[]) => mockRunTscPackageBuild(...args),
12
+ vi.mock("../../src/ts-compiler/SdTsCompiler", () => ({
13
+ SdTsCompiler: MockSdTsCompiler,
11
14
  }));
12
15
 
13
- const mockParseTsconfig = vi.fn();
14
-
15
- vi.mock("../../src/utils/tsconfig", async (importOriginal) => {
16
- const actual = await importOriginal<typeof import("../../src/utils/tsconfig")>();
17
- return {
18
- ...actual,
19
- parseTsconfig: (...args: unknown[]) => mockParseTsconfig(...args),
20
- };
21
- });
22
-
23
16
  //#endregion
24
17
 
25
18
  const { createTscPlugin } = await import("../../src/esbuild/esbuild-tsc-plugin");
@@ -59,42 +52,36 @@ const baseOptions = {
59
52
  output: { dts: true },
60
53
  };
61
54
 
62
- const mockParsedConfig = {
63
- options: { target: 99 },
64
- fileNames: [],
65
- errors: [],
66
- } as any;
67
-
68
- function createSuccessTscResult(): TscPackageBuildResult {
55
+ function createSuccessCompileResult(): ISdTsCompilerResult {
69
56
  return {
70
- success: true,
57
+ program: { getSourceFiles: () => [] } as any,
58
+ builderProgram: {} as any,
59
+ isForAngular: false,
60
+ affectedFiles: new Set(["/workspace/packages/my-server/src/main.ts"]),
71
61
  diagnostics: [],
72
62
  errorCount: 0,
73
63
  warningCount: 0,
74
- program: { getSourceFiles: () => [] } as any,
75
- affectedFiles: new Set(["/workspace/packages/my-server/src/main.ts"]),
76
- builderProgram: {} as any,
64
+ errors: undefined,
65
+ emitResults: undefined,
66
+ lint: undefined,
67
+ scssErrors: [],
68
+ scssDependencies: new Map(),
77
69
  };
78
70
  }
79
71
 
80
- function createErrorTscResult(): TscPackageBuildResult {
72
+ function createErrorCompileResult(): ISdTsCompilerResult {
81
73
  return {
82
- success: false,
74
+ ...createSuccessCompileResult(),
83
75
  errors: ["TS2322: Type 'string' is not assignable to type 'number'"],
84
- diagnostics: [{ category: 1, code: 2322, messageText: "Type mismatch" }],
76
+ diagnostics: [{ category: 1, code: 2322, messageText: "Type mismatch" }] as any,
85
77
  errorCount: 1,
86
- warningCount: 0,
87
- program: { getSourceFiles: () => [] } as any,
88
- affectedFiles: new Set(["/workspace/packages/my-server/src/main.ts"]),
89
- builderProgram: {} as any,
90
78
  };
91
79
  }
92
80
 
93
81
  describe("createTscPlugin — Acceptance Tests", () => {
94
82
  beforeEach(() => {
95
83
  vi.clearAllMocks();
96
- mockParseTsconfig.mockReturnValue(mockParsedConfig);
97
- mockRunTscPackageBuild.mockReturnValue(createSuccessTscResult());
84
+ mockCompileAsync.mockResolvedValue(createSuccessCompileResult());
98
85
  });
99
86
 
100
87
  // Rule: createTscPlugin은 esbuild.Plugin과 getter 객체를 반환한다
@@ -108,12 +95,13 @@ describe("createTscPlugin — Acceptance Tests", () => {
108
95
  expect(typeof result.getAffectedFiles).toBe("function");
109
96
  expect(typeof result.getDiagnostics).toBe("function");
110
97
  expect(typeof result.getErrors).toBe("function");
98
+ expect(typeof result.getLintResult).toBe("function");
111
99
  expect(typeof result.resetBuilderProgram).toBe("function");
112
100
  });
113
101
  });
114
102
 
115
103
  describe("Scenario: 선택 옵션 포함 플러그인 생성", () => {
116
- it("env, includeTests 옵션이 runTscPackageBuild에 전달된다", async () => {
104
+ it("env, includeTests 옵션이 SdTsCompiler에 전달된다", async () => {
117
105
  const result = createTscPlugin({
118
106
  ...baseOptions,
119
107
  env: "node",
@@ -124,7 +112,7 @@ describe("createTscPlugin — Acceptance Tests", () => {
124
112
  await lifecycle.invokeOnStart();
125
113
  await lifecycle.invokeOnEnd();
126
114
 
127
- expect(mockRunTscPackageBuild).toHaveBeenCalledWith(
115
+ expect(MockSdTsCompiler).toHaveBeenCalledWith(
128
116
  expect.objectContaining({
129
117
  env: "node",
130
118
  includeTests: true,
@@ -135,10 +123,9 @@ describe("createTscPlugin — Acceptance Tests", () => {
135
123
 
136
124
  // Rule: onStart에서 tsc를 microtask로 스케줄링하고 await하지 않는다
137
125
  describe("Scenario: tsc microtask 스케줄링", () => {
138
- it("onStart는 tsc 완료를 기다리지 않고 즉시 반환한다", async () => {
126
+ it("onStart는 compileAsync 완료를 기다리지 않고 즉시 반환한다", async () => {
139
127
  const result = createTscPlugin(baseOptions);
140
128
 
141
- // onStart 콜백을 직접 캡처하여 동기적으로 호출
142
129
  let onStartCb!: () => void;
143
130
  const mockBuild = {
144
131
  onStart(cb: () => void) { onStartCb = cb; },
@@ -150,17 +137,17 @@ describe("createTscPlugin — Acceptance Tests", () => {
150
137
  const onStartResult = onStartCb();
151
138
  expect(onStartResult).toBeUndefined();
152
139
 
153
- // onStart 반환 직후, microtask 전이므로 tsc 미호출
154
- expect(mockRunTscPackageBuild).not.toHaveBeenCalled();
140
+ // onStart 반환 직후, microtask 전이므로 SdTsCompiler 미생성
141
+ expect(MockSdTsCompiler).not.toHaveBeenCalled();
155
142
 
156
- // microtask flush 후 tsc 호출됨
143
+ // microtask flush 후 SdTsCompiler 생성됨
157
144
  await Promise.resolve();
158
- expect(mockRunTscPackageBuild).toHaveBeenCalledOnce();
145
+ expect(MockSdTsCompiler).toHaveBeenCalledOnce();
159
146
  });
160
147
  });
161
148
 
162
- describe("Scenario: parsedConfig 갱신", () => {
163
- it("매 onStart마다 parseTsconfig를 호출하여 최신 tsconfig를 반영한다", async () => {
149
+ describe("Scenario: SdTsCompiler 인스턴스 재사용", () => {
150
+ it("매 onStart마다 같은 SdTsCompiler 인스턴스를 재사용하여 증분 빌드를 지원한다", async () => {
164
151
  const result = createTscPlugin(baseOptions);
165
152
  const lifecycle = setupPlugin(result.plugin);
166
153
 
@@ -169,25 +156,21 @@ describe("createTscPlugin — Acceptance Tests", () => {
169
156
  await lifecycle.invokeOnEnd();
170
157
 
171
158
  // 두 번째 빌드
172
- const updatedConfig = { ...mockParsedConfig, fileNames: ["/new-file.ts"] };
173
- mockParseTsconfig.mockReturnValue(updatedConfig);
174
-
175
159
  await lifecycle.invokeOnStart();
176
160
  await lifecycle.invokeOnEnd();
177
161
 
178
- expect(mockParseTsconfig).toHaveBeenCalledTimes(2);
179
- expect(mockParseTsconfig).toHaveBeenCalledWith(baseOptions.pkgDir);
180
- expect(mockRunTscPackageBuild).toHaveBeenLastCalledWith(
181
- expect.objectContaining({ parsedConfig: updatedConfig }),
182
- );
162
+ // SdTsCompiler 생성은 1회 (재사용)
163
+ expect(MockSdTsCompiler).toHaveBeenCalledTimes(1);
164
+ // compileAsync는 2회 호출
165
+ expect(mockCompileAsync).toHaveBeenCalledTimes(2);
183
166
  });
184
167
  });
185
168
 
186
169
  // Rule: onEnd에서 tsc Promise를 await하여 결과를 내부 상태에 저장한다
187
170
  describe("Scenario: tsc 정상 완료", () => {
188
171
  it("program, affectedFiles, diagnostics를 저장하고 errors는 undefined", async () => {
189
- const tscResult = createSuccessTscResult();
190
- mockRunTscPackageBuild.mockReturnValue(tscResult);
172
+ const compileResult = createSuccessCompileResult();
173
+ mockCompileAsync.mockResolvedValue(compileResult);
191
174
 
192
175
  const result = createTscPlugin(baseOptions);
193
176
  const lifecycle = setupPlugin(result.plugin);
@@ -195,8 +178,8 @@ describe("createTscPlugin — Acceptance Tests", () => {
195
178
  await lifecycle.invokeOnStart();
196
179
  await lifecycle.invokeOnEnd();
197
180
 
198
- expect(result.getProgram()).toBe(tscResult.program);
199
- expect(result.getAffectedFiles()).toBe(tscResult.affectedFiles);
181
+ expect(result.getProgram()).toBe(compileResult.program);
182
+ expect(result.getAffectedFiles()).toBe(compileResult.affectedFiles);
200
183
  expect(result.getDiagnostics()).toEqual([]);
201
184
  expect(result.getErrors()).toBeUndefined();
202
185
  });
@@ -204,8 +187,8 @@ describe("createTscPlugin — Acceptance Tests", () => {
204
187
 
205
188
  describe("Scenario: tsc 타입 에러 발생", () => {
206
189
  it("errors를 string[]로, diagnostics를 SerializedDiagnostic[]로 저장한다", async () => {
207
- const tscResult = createErrorTscResult();
208
- mockRunTscPackageBuild.mockReturnValue(tscResult);
190
+ const compileResult = createErrorCompileResult();
191
+ mockCompileAsync.mockResolvedValue(compileResult);
209
192
 
210
193
  const result = createTscPlugin(baseOptions);
211
194
  const lifecycle = setupPlugin(result.plugin);
@@ -215,16 +198,14 @@ describe("createTscPlugin — Acceptance Tests", () => {
215
198
 
216
199
  expect(result.getErrors()).toEqual(["TS2322: Type 'string' is not assignable to type 'number'"]);
217
200
  expect(result.getDiagnostics()).toEqual([{ category: 1, code: 2322, messageText: "Type mismatch" }]);
218
- expect(result.getProgram()).toBe(tscResult.program);
219
- expect(result.getAffectedFiles()).toBe(tscResult.affectedFiles);
201
+ expect(result.getProgram()).toBe(compileResult.program);
202
+ expect(result.getAffectedFiles()).toBe(compileResult.affectedFiles);
220
203
  });
221
204
  });
222
205
 
223
206
  describe("Scenario: tsc 예외 발생", () => {
224
207
  it("try-catch로 포착하여 errors에 메시지 저장, program/affectedFiles는 undefined", async () => {
225
- mockRunTscPackageBuild.mockImplementation(() => {
226
- throw new Error("tsconfig parse failed");
227
- });
208
+ mockCompileAsync.mockRejectedValue(new Error("tsconfig parse failed"));
228
209
 
229
210
  const result = createTscPlugin(baseOptions);
230
211
  const lifecycle = setupPlugin(result.plugin);
@@ -242,7 +223,7 @@ describe("createTscPlugin — Acceptance Tests", () => {
242
223
  // Rule: result.errors에 push하지 않는다
243
224
  describe("Scenario: tsc 에러가 있어도 result.errors는 변경하지 않음", () => {
244
225
  it("onEnd의 result.errors에 tsc 에러를 push하지 않는다", async () => {
245
- mockRunTscPackageBuild.mockReturnValue(createErrorTscResult());
226
+ mockCompileAsync.mockResolvedValue(createErrorCompileResult());
246
227
 
247
228
  const result = createTscPlugin(baseOptions);
248
229
  const lifecycle = setupPlugin(result.plugin);
@@ -255,9 +236,7 @@ describe("createTscPlugin — Acceptance Tests", () => {
255
236
  };
256
237
  await lifecycle.invokeOnEnd(buildResult);
257
238
 
258
- // result.errors는 비어있어야 함 (tsc 에러가 push되지 않음)
259
239
  expect(buildResult.errors).toEqual([]);
260
- // tsc 에러는 getErrors()로만 조회 가능
261
240
  expect(result.getErrors()).toBeDefined();
262
241
  });
263
242
  });
@@ -271,13 +250,14 @@ describe("createTscPlugin — Acceptance Tests", () => {
271
250
  expect(result.getAffectedFiles()).toBeUndefined();
272
251
  expect(result.getDiagnostics()).toEqual([]);
273
252
  expect(result.getErrors()).toBeUndefined();
253
+ expect(result.getLintResult()).toBeUndefined();
274
254
  });
275
255
  });
276
256
 
277
257
  describe("Scenario: 빌드 후 getter 호출", () => {
278
- it("tsc 빌드 성공 후 program과 affectedFiles를 반환한다", async () => {
279
- const tscResult = createSuccessTscResult();
280
- mockRunTscPackageBuild.mockReturnValue(tscResult);
258
+ it("compileAsync 성공 후 program과 affectedFiles를 반환한다", async () => {
259
+ const compileResult = createSuccessCompileResult();
260
+ mockCompileAsync.mockResolvedValue(compileResult);
281
261
 
282
262
  const result = createTscPlugin(baseOptions);
283
263
  const lifecycle = setupPlugin(result.plugin);
@@ -285,65 +265,30 @@ describe("createTscPlugin — Acceptance Tests", () => {
285
265
  await lifecycle.invokeOnStart();
286
266
  await lifecycle.invokeOnEnd();
287
267
 
288
- expect(result.getProgram()).toBe(tscResult.program);
268
+ expect(result.getProgram()).toBe(compileResult.program);
289
269
  expect(result.getAffectedFiles()).toEqual(new Set(["/workspace/packages/my-server/src/main.ts"]));
290
270
  expect(result.getDiagnostics()).toEqual([]);
291
271
  });
292
272
  });
293
273
 
294
- // Rule: lastBuilderProgram을 캐싱하여 watch 모드 증분 빌드를 지원한다
295
- describe("Scenario: 증분 빌드 — builderProgram 재사용", () => {
296
- it("첫 번째 빌드 후 캐싱된 builderProgram을 두 번째 빌드에 oldBuilderProgram으로 전달한다", async () => {
297
- const firstBuilderProgram = { kind: "first" } as any;
298
- mockRunTscPackageBuild.mockReturnValue({
299
- ...createSuccessTscResult(),
300
- builderProgram: firstBuilderProgram,
301
- });
302
-
303
- const result = createTscPlugin(baseOptions);
304
- const lifecycle = setupPlugin(result.plugin);
305
-
306
- // 첫 번째 빌드
307
- await lifecycle.invokeOnStart();
308
- await lifecycle.invokeOnEnd();
309
-
310
- // 두 번째 빌드
311
- await lifecycle.invokeOnStart();
312
- await lifecycle.invokeOnEnd();
313
-
314
- // 두 번째 호출에서 oldBuilderProgram이 첫 번째 결과의 builderProgram
315
- expect(mockRunTscPackageBuild).toHaveBeenCalledTimes(2);
316
- expect(mockRunTscPackageBuild).toHaveBeenLastCalledWith(
317
- expect.objectContaining({ oldBuilderProgram: firstBuilderProgram }),
318
- );
319
- });
320
- });
321
-
274
+ // Rule: SdTsCompiler 인스턴스를 유지하여 증분 빌드를 지원하고 resetBuilderProgram 시 재생성한다
322
275
  describe("Scenario: builderProgram 리셋", () => {
323
- it("resetBuilderProgram 호출 후 다음 빌드는 fresh build로 실행된다", async () => {
324
- const cachedBuilderProgram = { kind: "cached" } as any;
325
- mockRunTscPackageBuild.mockReturnValue({
326
- ...createSuccessTscResult(),
327
- builderProgram: cachedBuilderProgram,
328
- });
329
-
276
+ it("resetBuilderProgram 호출 후 다음 빌드는 SdTsCompiler 인스턴스로 실행된다", async () => {
330
277
  const result = createTscPlugin(baseOptions);
331
278
  const lifecycle = setupPlugin(result.plugin);
332
279
 
333
- // 첫 번째 빌드 — builderProgram 캐싱
280
+ // 첫 번째 빌드
334
281
  await lifecycle.invokeOnStart();
335
282
  await lifecycle.invokeOnEnd();
283
+ expect(MockSdTsCompiler).toHaveBeenCalledTimes(1);
336
284
 
337
285
  // 리셋
338
286
  result.resetBuilderProgram();
339
287
 
340
- // 다음 빌드 — oldBuilderProgram이 undefined (fresh build)
288
+ // 다음 빌드 — SdTsCompiler 인스턴스 생성
341
289
  await lifecycle.invokeOnStart();
342
290
  await lifecycle.invokeOnEnd();
343
-
344
- expect(mockRunTscPackageBuild).toHaveBeenLastCalledWith(
345
- expect.objectContaining({ oldBuilderProgram: undefined }),
346
- );
291
+ expect(MockSdTsCompiler).toHaveBeenCalledTimes(2);
347
292
  });
348
293
  });
349
294
  });
@@ -1,25 +1,18 @@
1
1
  import { describe, it, expect, vi, beforeEach } from "vitest";
2
2
  import type esbuild from "esbuild";
3
- import type { TscPackageBuildResult } from "../../src/utils/tsc-build";
3
+ import type { ISdTsCompilerResult } from "../../src/ts-compiler/sd-ts-compiler-result";
4
4
 
5
5
  //#region Mocks
6
6
 
7
- const mockRunTscPackageBuild = vi.fn<(...args: unknown[]) => TscPackageBuildResult>();
7
+ const mockCompileAsync = vi.fn<() => Promise<ISdTsCompilerResult>>();
8
+ const MockSdTsCompiler = vi.fn().mockImplementation(function () {
9
+ return { compileAsync: mockCompileAsync };
10
+ });
8
11
 
9
- vi.mock("../../src/utils/tsc-build", () => ({
10
- runTscPackageBuild: (...args: unknown[]) => mockRunTscPackageBuild(...args),
12
+ vi.mock("../../src/ts-compiler/SdTsCompiler", () => ({
13
+ SdTsCompiler: MockSdTsCompiler,
11
14
  }));
12
15
 
13
- const mockParseTsconfig = vi.fn();
14
-
15
- vi.mock("../../src/utils/tsconfig", async (importOriginal) => {
16
- const actual = await importOriginal<typeof import("../../src/utils/tsconfig")>();
17
- return {
18
- ...actual,
19
- parseTsconfig: (...args: unknown[]) => mockParseTsconfig(...args),
20
- };
21
- });
22
-
23
16
  //#endregion
24
17
 
25
18
  const { createTscPlugin } = await import("../../src/esbuild/esbuild-tsc-plugin");
@@ -59,29 +52,27 @@ const baseOptions = {
59
52
  output: { dts: true },
60
53
  };
61
54
 
62
- const mockParsedConfig = {
63
- options: { target: 99 },
64
- fileNames: [],
65
- errors: [],
66
- } as any;
67
-
68
- function createSuccessTscResult(): TscPackageBuildResult {
55
+ function createSuccessCompileResult(): ISdTsCompilerResult {
69
56
  return {
70
- success: true,
57
+ program: { getSourceFiles: () => [] } as any,
58
+ builderProgram: {} as any,
59
+ isForAngular: false,
60
+ affectedFiles: new Set(["/workspace/packages/my-server/src/main.ts"]),
71
61
  diagnostics: [],
72
62
  errorCount: 0,
73
63
  warningCount: 0,
74
- program: { getSourceFiles: () => [] } as any,
75
- affectedFiles: new Set(["/workspace/packages/my-server/src/main.ts"]),
76
- builderProgram: {} as any,
64
+ errors: undefined,
65
+ emitResults: undefined,
66
+ lint: undefined,
67
+ scssErrors: [],
68
+ scssDependencies: new Map(),
77
69
  };
78
70
  }
79
71
 
80
72
  describe("createTscPlugin — Unit Tests", () => {
81
73
  beforeEach(() => {
82
74
  vi.clearAllMocks();
83
- mockParseTsconfig.mockReturnValue(mockParsedConfig);
84
- mockRunTscPackageBuild.mockReturnValue(createSuccessTscResult());
75
+ mockCompileAsync.mockResolvedValue(createSuccessCompileResult());
85
76
  });
86
77
 
87
78
  describe("plugin 구조", () => {
@@ -102,20 +93,19 @@ describe("createTscPlugin — Unit Tests", () => {
102
93
  });
103
94
  });
104
95
 
105
- describe("onStart — runTscPackageBuild 옵션 전달", () => {
106
- it("pkgDir, cwd, output.dts를 올바르게 전달한다", async () => {
96
+ describe("onStart — SdTsCompiler 옵션 전달", () => {
97
+ it("pkgDir, cwd, output.js=false, output.dts를 올바르게 전달한다", async () => {
107
98
  const result = createTscPlugin(baseOptions);
108
99
  const lifecycle = setupPlugin(result.plugin);
109
100
 
110
101
  await lifecycle.invokeOnStart();
111
102
  await lifecycle.invokeOnEnd();
112
103
 
113
- expect(mockRunTscPackageBuild).toHaveBeenCalledWith(
104
+ expect(MockSdTsCompiler).toHaveBeenCalledWith(
114
105
  expect.objectContaining({
115
106
  pkgDir: "/workspace/packages/my-server",
116
107
  cwd: "/workspace",
117
108
  output: { js: false, dts: true },
118
- parsedConfig: mockParsedConfig,
119
109
  }),
120
110
  );
121
111
  });
@@ -130,23 +120,59 @@ describe("createTscPlugin — Unit Tests", () => {
130
120
  await lifecycle.invokeOnStart();
131
121
  await lifecycle.invokeOnEnd();
132
122
 
133
- expect(mockRunTscPackageBuild).toHaveBeenCalledWith(
123
+ expect(MockSdTsCompiler).toHaveBeenCalledWith(
134
124
  expect.objectContaining({
135
125
  output: { js: false, dts: false },
136
126
  }),
137
127
  );
138
128
  });
129
+
130
+ it("lint 옵션을 SdTsCompiler에 전달한다", async () => {
131
+ const result = createTscPlugin({
132
+ ...baseOptions,
133
+ lint: true,
134
+ });
135
+ const lifecycle = setupPlugin(result.plugin);
136
+
137
+ await lifecycle.invokeOnStart();
138
+ await lifecycle.invokeOnEnd();
139
+
140
+ expect(MockSdTsCompiler).toHaveBeenCalledWith(
141
+ expect.objectContaining({
142
+ lint: true,
143
+ }),
144
+ );
145
+ });
146
+
147
+ it("env, includeTests 옵션을 SdTsCompiler에 전달한다", async () => {
148
+ const result = createTscPlugin({
149
+ ...baseOptions,
150
+ env: "node" as any,
151
+ includeTests: true,
152
+ });
153
+ const lifecycle = setupPlugin(result.plugin);
154
+
155
+ await lifecycle.invokeOnStart();
156
+ await lifecycle.invokeOnEnd();
157
+
158
+ expect(MockSdTsCompiler).toHaveBeenCalledWith(
159
+ expect.objectContaining({
160
+ env: "node",
161
+ includeTests: true,
162
+ }),
163
+ );
164
+ });
139
165
  });
140
166
 
141
167
  describe("onEnd — 상태 저장", () => {
142
- it("tsc 결과의 diagnostics를 정확히 저장한다", async () => {
168
+ it("compileAsync 결과의 diagnostics를 정확히 저장한다", async () => {
143
169
  const diagnostics = [
144
170
  { category: 0, code: 6031, messageText: "Watching for changes" },
145
171
  { category: 1, code: 2322, messageText: "Type error" },
146
172
  ];
147
- mockRunTscPackageBuild.mockReturnValue({
148
- ...createSuccessTscResult(),
149
- diagnostics,
173
+ mockCompileAsync.mockResolvedValue({
174
+ ...createSuccessCompileResult(),
175
+ diagnostics: diagnostics as any,
150
176
  });
151
177
 
152
178
  const result = createTscPlugin(baseOptions);
@@ -158,10 +184,8 @@ describe("createTscPlugin — Unit Tests", () => {
158
184
  expect(result.getDiagnostics()).toEqual(diagnostics);
159
185
  });
160
186
 
161
- it("parseTsconfig 예외 시에도 에러를 저장한다", async () => {
162
- mockParseTsconfig.mockImplementation(() => {
163
- throw new Error("Invalid tsconfig.json");
164
- });
187
+ it("compileAsync 예외 시에도 에러를 저장한다", async () => {
188
+ mockCompileAsync.mockRejectedValue(new Error("Invalid tsconfig.json"));
165
189
 
166
190
  const result = createTscPlugin(baseOptions);
167
191
  const lifecycle = setupPlugin(result.plugin);
@@ -172,6 +196,28 @@ describe("createTscPlugin — Unit Tests", () => {
172
196
  expect(result.getErrors()).toEqual(["Invalid tsconfig.json"]);
173
197
  expect(result.getDiagnostics()).toEqual([]);
174
198
  expect(result.getProgram()).toBeUndefined();
199
+ expect(result.getLintResult()).toBeUndefined();
200
+ });
201
+
202
+ it("compileAsync 결과에서 lint 결과를 저장한다", async () => {
203
+ const lintResult = {
204
+ success: true,
205
+ errorCount: 0,
206
+ warningCount: 0,
207
+ formattedOutput: "",
208
+ };
209
+ mockCompileAsync.mockResolvedValue({
210
+ ...createSuccessCompileResult(),
211
+ lint: lintResult,
212
+ });
213
+
214
+ const result = createTscPlugin({ ...baseOptions, lint: true });
215
+ const lifecycle = setupPlugin(result.plugin);
216
+
217
+ await lifecycle.invokeOnStart();
218
+ await lifecycle.invokeOnEnd();
219
+
220
+ expect(result.getLintResult()).toEqual(lintResult);
175
221
  });
176
222
  });
177
223
 
@@ -181,20 +227,17 @@ describe("createTscPlugin — Unit Tests", () => {
181
227
  const lifecycle = setupPlugin(result.plugin);
182
228
 
183
229
  // 첫 번째 빌드 — 에러
184
- const errorResult: TscPackageBuildResult = {
185
- success: false,
230
+ mockCompileAsync.mockResolvedValue({
231
+ ...createSuccessCompileResult(),
186
232
  errors: ["first error"],
187
- diagnostics: [{ category: 1, code: 1, messageText: "err" }],
188
233
  errorCount: 1,
189
- warningCount: 0,
190
- };
191
- mockRunTscPackageBuild.mockReturnValue(errorResult);
234
+ });
192
235
  await lifecycle.invokeOnStart();
193
236
  await lifecycle.invokeOnEnd();
194
237
  expect(result.getErrors()).toEqual(["first error"]);
195
238
 
196
239
  // 두 번째 빌드 — 성공
197
- mockRunTscPackageBuild.mockReturnValue(createSuccessTscResult());
240
+ mockCompileAsync.mockResolvedValue(createSuccessCompileResult());
198
241
  await lifecycle.invokeOnStart();
199
242
  await lifecycle.invokeOnEnd();
200
243
  expect(result.getErrors()).toBeUndefined();
@@ -208,23 +251,44 @@ describe("createTscPlugin — Unit Tests", () => {
208
251
  expect(() => result.resetBuilderProgram()).not.toThrow();
209
252
  });
210
253
 
211
- it("여러 호출해도 안전하다", async () => {
254
+ it("리셋 다음 빌드에서 새 SdTsCompiler 인스턴스를 생성한다", async () => {
212
255
  const result = createTscPlugin(baseOptions);
213
256
  const lifecycle = setupPlugin(result.plugin);
214
257
 
258
+ // 첫 번째 빌드
259
+ await lifecycle.invokeOnStart();
260
+ await lifecycle.invokeOnEnd();
261
+ expect(MockSdTsCompiler).toHaveBeenCalledTimes(1);
262
+
263
+ // 두 번째 빌드 — 같은 인스턴스 재사용
215
264
  await lifecycle.invokeOnStart();
216
265
  await lifecycle.invokeOnEnd();
266
+ expect(MockSdTsCompiler).toHaveBeenCalledTimes(1);
217
267
 
268
+ // 리셋 후 세 번째 빌드 — 새 인스턴스 생성
269
+ result.resetBuilderProgram();
270
+ await lifecycle.invokeOnStart();
271
+ await lifecycle.invokeOnEnd();
272
+ expect(MockSdTsCompiler).toHaveBeenCalledTimes(2);
273
+ });
274
+
275
+ it("여러 번 호출해도 안전하다", () => {
276
+ const result = createTscPlugin(baseOptions);
218
277
  result.resetBuilderProgram();
219
278
  result.resetBuilderProgram();
279
+ // No throw
280
+ });
281
+ });
282
+
283
+ describe("getLintResult", () => {
284
+ it("lint 미활성 시 undefined를 반환한다", async () => {
285
+ const result = createTscPlugin(baseOptions);
286
+ const lifecycle = setupPlugin(result.plugin);
220
287
 
221
- // 리셋 후 빌드 가능
222
288
  await lifecycle.invokeOnStart();
223
289
  await lifecycle.invokeOnEnd();
224
290
 
225
- expect(mockRunTscPackageBuild).toHaveBeenLastCalledWith(
226
- expect.objectContaining({ oldBuilderProgram: undefined }),
227
- );
291
+ expect(result.getLintResult()).toBeUndefined();
228
292
  });
229
293
  });
230
294
  });