@simplysm/sd-cli 13.0.99 → 14.0.1

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 (409) hide show
  1. package/dist/commands/build.js +29 -19
  2. package/dist/commands/build.js.map +1 -6
  3. package/dist/commands/check.d.ts +1 -0
  4. package/dist/commands/check.d.ts.map +1 -1
  5. package/dist/commands/check.js +130 -115
  6. package/dist/commands/check.js.map +1 -6
  7. package/dist/commands/dev.d.ts +6 -7
  8. package/dist/commands/dev.d.ts.map +1 -1
  9. package/dist/commands/dev.js +24 -14
  10. package/dist/commands/dev.js.map +1 -6
  11. package/dist/commands/lint.d.ts +1 -1
  12. package/dist/commands/lint.js +158 -116
  13. package/dist/commands/lint.js.map +1 -6
  14. package/dist/commands/publish.d.ts.map +1 -1
  15. package/dist/commands/publish.js +637 -510
  16. package/dist/commands/publish.js.map +1 -6
  17. package/dist/commands/replace-deps.js +12 -12
  18. package/dist/commands/replace-deps.js.map +1 -6
  19. package/dist/commands/typecheck.d.ts +5 -30
  20. package/dist/commands/typecheck.d.ts.map +1 -1
  21. package/dist/commands/typecheck.js +144 -207
  22. package/dist/commands/typecheck.js.map +1 -6
  23. package/dist/commands/watch.d.ts +6 -4
  24. package/dist/commands/watch.d.ts.map +1 -1
  25. package/dist/commands/watch.js +25 -16
  26. package/dist/commands/watch.js.map +1 -6
  27. package/dist/engines/NgtscEngine.d.ts +47 -0
  28. package/dist/engines/NgtscEngine.d.ts.map +1 -0
  29. package/dist/engines/NgtscEngine.js +151 -0
  30. package/dist/engines/NgtscEngine.js.map +1 -0
  31. package/dist/engines/ServerEsbuildEngine.d.ts +47 -0
  32. package/dist/engines/ServerEsbuildEngine.d.ts.map +1 -0
  33. package/dist/engines/ServerEsbuildEngine.js +159 -0
  34. package/dist/engines/ServerEsbuildEngine.js.map +1 -0
  35. package/dist/engines/TscEngine.d.ts +47 -0
  36. package/dist/engines/TscEngine.d.ts.map +1 -0
  37. package/dist/engines/TscEngine.js +153 -0
  38. package/dist/engines/TscEngine.js.map +1 -0
  39. package/dist/engines/ViteEngine.d.ts +49 -0
  40. package/dist/engines/ViteEngine.d.ts.map +1 -0
  41. package/dist/engines/ViteEngine.js +161 -0
  42. package/dist/engines/ViteEngine.js.map +1 -0
  43. package/dist/engines/index.d.ts +26 -0
  44. package/dist/engines/index.d.ts.map +1 -0
  45. package/dist/engines/index.js +30 -0
  46. package/dist/engines/index.js.map +1 -0
  47. package/dist/engines/types.d.ts +77 -0
  48. package/dist/engines/types.d.ts.map +1 -0
  49. package/dist/engines/types.js +2 -0
  50. package/dist/engines/types.js.map +1 -0
  51. package/dist/index.d.ts +0 -1
  52. package/dist/index.d.ts.map +1 -1
  53. package/dist/index.js +2 -2
  54. package/dist/index.js.map +1 -6
  55. package/dist/infra/ResultCollector.d.ts +1 -1
  56. package/dist/infra/ResultCollector.d.ts.map +1 -1
  57. package/dist/infra/ResultCollector.js +30 -27
  58. package/dist/infra/ResultCollector.js.map +1 -6
  59. package/dist/infra/SignalHandler.js +45 -42
  60. package/dist/infra/SignalHandler.js.map +1 -6
  61. package/dist/infra/WorkerManager.js +56 -53
  62. package/dist/infra/WorkerManager.js.map +1 -6
  63. package/dist/orchestrators/BuildOrchestrator.d.ts +33 -1
  64. package/dist/orchestrators/BuildOrchestrator.d.ts.map +1 -1
  65. package/dist/orchestrators/BuildOrchestrator.js +314 -309
  66. package/dist/orchestrators/BuildOrchestrator.js.map +1 -6
  67. package/dist/orchestrators/DevWatchOrchestrator.d.ts +60 -0
  68. package/dist/orchestrators/DevWatchOrchestrator.d.ts.map +1 -0
  69. package/dist/orchestrators/DevWatchOrchestrator.js +465 -0
  70. package/dist/orchestrators/DevWatchOrchestrator.js.map +1 -0
  71. package/dist/sd-cli-entry.d.ts.map +1 -1
  72. package/dist/sd-cli-entry.js +190 -266
  73. package/dist/sd-cli-entry.js.map +1 -6
  74. package/dist/sd-cli.js +77 -49
  75. package/dist/sd-cli.js.map +1 -6
  76. package/dist/sd-config.types.d.ts +2 -0
  77. package/dist/sd-config.types.d.ts.map +1 -1
  78. package/dist/sd-config.types.js +2 -1
  79. package/dist/sd-config.types.js.map +1 -6
  80. package/dist/utils/angular-build.d.ts +77 -0
  81. package/dist/utils/angular-build.d.ts.map +1 -0
  82. package/dist/utils/angular-build.js +84 -0
  83. package/dist/utils/angular-build.js.map +1 -0
  84. package/dist/utils/build-env.js +9 -9
  85. package/dist/utils/build-env.js.map +1 -6
  86. package/dist/utils/concurrency.d.ts +15 -0
  87. package/dist/utils/concurrency.d.ts.map +1 -0
  88. package/dist/utils/concurrency.js +38 -0
  89. package/dist/utils/concurrency.js.map +1 -0
  90. package/dist/utils/copy-public.js +104 -87
  91. package/dist/utils/copy-public.js.map +1 -6
  92. package/dist/utils/copy-src.js +49 -35
  93. package/dist/utils/copy-src.js.map +1 -6
  94. package/dist/utils/esbuild-config.d.ts +0 -29
  95. package/dist/utils/esbuild-config.d.ts.map +1 -1
  96. package/dist/utils/esbuild-config.js +151 -218
  97. package/dist/utils/esbuild-config.js.map +1 -6
  98. package/dist/utils/ngtsc-build-core.d.ts +49 -0
  99. package/dist/utils/ngtsc-build-core.d.ts.map +1 -0
  100. package/dist/utils/ngtsc-build-core.js +250 -0
  101. package/dist/utils/ngtsc-build-core.js.map +1 -0
  102. package/dist/utils/output-path-rewriter.d.ts +23 -0
  103. package/dist/utils/output-path-rewriter.d.ts.map +1 -0
  104. package/dist/utils/output-path-rewriter.js +74 -0
  105. package/dist/utils/output-path-rewriter.js.map +1 -0
  106. package/dist/utils/output-utils.js +55 -40
  107. package/dist/utils/output-utils.js.map +1 -6
  108. package/dist/utils/package-utils.d.ts +8 -0
  109. package/dist/utils/package-utils.d.ts.map +1 -1
  110. package/dist/utils/package-utils.js +103 -73
  111. package/dist/utils/package-utils.js.map +1 -6
  112. package/dist/utils/rebuild-manager.js +41 -44
  113. package/dist/utils/rebuild-manager.js.map +1 -6
  114. package/dist/utils/replace-deps.js +283 -184
  115. package/dist/utils/replace-deps.js.map +1 -6
  116. package/dist/utils/scss-compiler.d.ts +10 -0
  117. package/dist/utils/scss-compiler.d.ts.map +1 -0
  118. package/dist/utils/scss-compiler.js +36 -0
  119. package/dist/utils/scss-compiler.js.map +1 -0
  120. package/dist/utils/sd-config.js +29 -19
  121. package/dist/utils/sd-config.js.map +1 -6
  122. package/dist/utils/tsc-build.d.ts +36 -0
  123. package/dist/utils/tsc-build.d.ts.map +1 -0
  124. package/dist/utils/tsc-build.js +130 -0
  125. package/dist/utils/tsc-build.js.map +1 -0
  126. package/dist/utils/tsconfig.d.ts +7 -26
  127. package/dist/utils/tsconfig.d.ts.map +1 -1
  128. package/dist/utils/tsconfig.js +39 -64
  129. package/dist/utils/tsconfig.js.map +1 -6
  130. package/dist/utils/typecheck-non-package.d.ts +18 -0
  131. package/dist/utils/typecheck-non-package.d.ts.map +1 -0
  132. package/dist/utils/typecheck-non-package.js +64 -0
  133. package/dist/utils/typecheck-non-package.js.map +1 -0
  134. package/dist/utils/typecheck-serialization.js +58 -40
  135. package/dist/utils/typecheck-serialization.js.map +1 -6
  136. package/dist/utils/worker-events.js +48 -40
  137. package/dist/utils/worker-events.js.map +1 -6
  138. package/dist/utils/worker-utils.js +48 -28
  139. package/dist/utils/worker-utils.js.map +1 -6
  140. package/dist/vitest-plugin.d.ts +9 -0
  141. package/dist/vitest-plugin.d.ts.map +1 -0
  142. package/dist/vitest-plugin.js +85 -0
  143. package/dist/vitest-plugin.js.map +1 -0
  144. package/dist/workers/library-build.worker.d.ts +54 -0
  145. package/dist/workers/library-build.worker.d.ts.map +1 -0
  146. package/dist/workers/library-build.worker.js +97 -0
  147. package/dist/workers/library-build.worker.js.map +1 -0
  148. package/dist/workers/lint.worker.js +9 -6
  149. package/dist/workers/lint.worker.js.map +1 -6
  150. package/dist/workers/ngtsc-build.worker.d.ts +23 -0
  151. package/dist/workers/ngtsc-build.worker.d.ts.map +1 -0
  152. package/dist/workers/ngtsc-build.worker.js +98 -0
  153. package/dist/workers/ngtsc-build.worker.js.map +1 -0
  154. package/dist/workers/{server.worker.d.ts → server-build.worker.d.ts} +39 -29
  155. package/dist/workers/server-build.worker.d.ts.map +1 -0
  156. package/dist/workers/server-build.worker.js +399 -0
  157. package/dist/workers/server-build.worker.js.map +1 -0
  158. package/dist/workers/server-runtime.worker.d.ts +3 -2
  159. package/dist/workers/server-runtime.worker.d.ts.map +1 -1
  160. package/dist/workers/server-runtime.worker.js +100 -95
  161. package/dist/workers/server-runtime.worker.js.map +1 -6
  162. package/dist/workers/vite-build.worker.d.ts +56 -0
  163. package/dist/workers/vite-build.worker.d.ts.map +1 -0
  164. package/dist/workers/vite-build.worker.js +167 -0
  165. package/dist/workers/vite-build.worker.js.map +1 -0
  166. package/package.json +10 -16
  167. package/src/commands/check.ts +21 -3
  168. package/src/commands/dev.ts +10 -8
  169. package/src/commands/lint.ts +1 -1
  170. package/src/commands/publish.ts +4 -0
  171. package/src/commands/typecheck.ts +89 -256
  172. package/src/commands/watch.ts +9 -8
  173. package/src/engines/NgtscEngine.ts +190 -0
  174. package/src/engines/ServerEsbuildEngine.ts +195 -0
  175. package/src/engines/TscEngine.ts +189 -0
  176. package/src/engines/ViteEngine.ts +203 -0
  177. package/src/engines/index.ts +49 -0
  178. package/src/engines/types.ts +79 -0
  179. package/src/index.ts +0 -3
  180. package/src/infra/ResultCollector.ts +1 -1
  181. package/src/orchestrators/BuildOrchestrator.ts +87 -157
  182. package/src/orchestrators/DevWatchOrchestrator.ts +573 -0
  183. package/src/sd-cli-entry.ts +13 -116
  184. package/src/sd-config.types.ts +2 -0
  185. package/src/utils/angular-build.ts +157 -0
  186. package/src/utils/concurrency.ts +43 -0
  187. package/src/utils/esbuild-config.ts +1 -122
  188. package/src/utils/ngtsc-build-core.ts +379 -0
  189. package/src/utils/output-path-rewriter.ts +82 -0
  190. package/src/utils/package-utils.ts +20 -0
  191. package/src/utils/scss-compiler.ts +58 -0
  192. package/src/utils/tsc-build.ts +175 -0
  193. package/src/utils/tsconfig.ts +27 -95
  194. package/src/utils/typecheck-non-package.ts +87 -0
  195. package/src/vitest-plugin.ts +118 -0
  196. package/src/workers/library-build.worker.ts +153 -0
  197. package/src/workers/ngtsc-build.worker.ts +146 -0
  198. package/src/workers/server-build.worker.ts +565 -0
  199. package/src/workers/server-runtime.worker.ts +17 -26
  200. package/src/workers/vite-build.worker.ts +252 -0
  201. package/tests/commands/check.spec.ts +276 -0
  202. package/tests/commands/dev.spec.ts +53 -0
  203. package/tests/commands/lint.spec.ts +243 -0
  204. package/tests/commands/publish.spec.ts +1159 -0
  205. package/tests/commands/typecheck.spec.ts +294 -0
  206. package/tests/commands/watch.spec.ts +53 -0
  207. package/tests/engines/engine-selection.spec.ts +247 -0
  208. package/tests/engines/ngtsc-engine.spec.ts +274 -0
  209. package/tests/engines/server-esbuild-engine.spec.ts +256 -0
  210. package/tests/engines/tsc-engine.spec.ts +213 -0
  211. package/tests/engines/vite-engine.spec.ts +358 -0
  212. package/tests/infra/result-collector.spec.ts +46 -0
  213. package/tests/infra/signal-handler.spec.ts +32 -0
  214. package/tests/infra/worker-manager.spec.ts +63 -0
  215. package/tests/orchestrators/build-orchestrator.spec.ts +772 -0
  216. package/tests/orchestrators/dev-watch-orchestrator.spec.ts +1173 -0
  217. package/tests/sd-cli-entry.spec.ts +49 -0
  218. package/tests/utils/angular-build.spec.ts +251 -0
  219. package/tests/utils/build-env.spec.ts +33 -0
  220. package/tests/utils/concurrency.spec.ts +65 -0
  221. package/tests/utils/copy-src.spec.ts +144 -0
  222. package/tests/utils/esbuild-config.spec.ts +186 -0
  223. package/tests/utils/external-modules.spec.ts +161 -0
  224. package/tests/utils/ngtsc-scss-refactor.spec.ts +66 -0
  225. package/tests/utils/output-path-rewriter.spec.ts +165 -0
  226. package/tests/utils/output-utils.spec.ts +104 -0
  227. package/tests/utils/package-utils.spec.ts +52 -0
  228. package/tests/utils/rebuild-manager.spec.ts +30 -27
  229. package/tests/utils/replace-deps.spec.ts +69 -0
  230. package/tests/utils/scss-compiler.spec.ts +131 -0
  231. package/tests/utils/sd-config.spec.ts +77 -0
  232. package/tests/utils/tsc-build.spec.ts +358 -0
  233. package/tests/utils/tsconfig-angular.spec.ts +71 -0
  234. package/tests/utils/typecheck-non-package.spec.ts +120 -0
  235. package/tests/utils/worker-events.spec.ts +155 -0
  236. package/tests/utils/worker-utils.spec.ts +43 -0
  237. package/tests/vitest-plugin-cwd.spec.ts +68 -0
  238. package/tests/vitest-plugin.spec.ts +103 -0
  239. package/tests/workers/library-build-worker.spec.ts +258 -0
  240. package/tests/workers/ngtsc-build-worker.spec.ts +187 -0
  241. package/tests/workers/server-build-worker.spec.ts +566 -0
  242. package/tests/workers/server-runtime-worker.spec.ts +251 -0
  243. package/README.md +0 -295
  244. package/dist/builders/BaseBuilder.d.ts +0 -88
  245. package/dist/builders/BaseBuilder.d.ts.map +0 -1
  246. package/dist/builders/BaseBuilder.js +0 -142
  247. package/dist/builders/BaseBuilder.js.map +0 -6
  248. package/dist/builders/DtsBuilder.d.ts +0 -22
  249. package/dist/builders/DtsBuilder.d.ts.map +0 -1
  250. package/dist/builders/DtsBuilder.js +0 -72
  251. package/dist/builders/DtsBuilder.js.map +0 -6
  252. package/dist/builders/LibraryBuilder.d.ts +0 -22
  253. package/dist/builders/LibraryBuilder.d.ts.map +0 -1
  254. package/dist/builders/LibraryBuilder.js +0 -85
  255. package/dist/builders/LibraryBuilder.js.map +0 -6
  256. package/dist/builders/types.d.ts +0 -55
  257. package/dist/builders/types.d.ts.map +0 -1
  258. package/dist/builders/types.js +0 -1
  259. package/dist/builders/types.js.map +0 -6
  260. package/dist/capacitor/capacitor.d.ts +0 -151
  261. package/dist/capacitor/capacitor.d.ts.map +0 -1
  262. package/dist/capacitor/capacitor.js +0 -694
  263. package/dist/capacitor/capacitor.js.map +0 -6
  264. package/dist/commands/device.d.ts +0 -22
  265. package/dist/commands/device.d.ts.map +0 -1
  266. package/dist/commands/device.js +0 -98
  267. package/dist/commands/device.js.map +0 -6
  268. package/dist/commands/init.d.ts +0 -14
  269. package/dist/commands/init.d.ts.map +0 -1
  270. package/dist/commands/init.js +0 -72
  271. package/dist/commands/init.js.map +0 -6
  272. package/dist/electron/electron.d.ts +0 -84
  273. package/dist/electron/electron.d.ts.map +0 -1
  274. package/dist/electron/electron.js +0 -263
  275. package/dist/electron/electron.js.map +0 -6
  276. package/dist/orchestrators/DevOrchestrator.d.ts +0 -83
  277. package/dist/orchestrators/DevOrchestrator.d.ts.map +0 -1
  278. package/dist/orchestrators/DevOrchestrator.js +0 -540
  279. package/dist/orchestrators/DevOrchestrator.js.map +0 -6
  280. package/dist/orchestrators/WatchOrchestrator.d.ts +0 -57
  281. package/dist/orchestrators/WatchOrchestrator.d.ts.map +0 -1
  282. package/dist/orchestrators/WatchOrchestrator.js +0 -199
  283. package/dist/orchestrators/WatchOrchestrator.js.map +0 -6
  284. package/dist/utils/tailwind-config-deps.d.ts +0 -8
  285. package/dist/utils/tailwind-config-deps.d.ts.map +0 -1
  286. package/dist/utils/tailwind-config-deps.js +0 -82
  287. package/dist/utils/tailwind-config-deps.js.map +0 -6
  288. package/dist/utils/template.d.ts +0 -14
  289. package/dist/utils/template.d.ts.map +0 -1
  290. package/dist/utils/template.js +0 -33
  291. package/dist/utils/template.js.map +0 -6
  292. package/dist/utils/vite-config.d.ts +0 -35
  293. package/dist/utils/vite-config.d.ts.map +0 -1
  294. package/dist/utils/vite-config.js +0 -259
  295. package/dist/utils/vite-config.js.map +0 -6
  296. package/dist/workers/client.worker.d.ts +0 -83
  297. package/dist/workers/client.worker.d.ts.map +0 -1
  298. package/dist/workers/client.worker.js +0 -111
  299. package/dist/workers/client.worker.js.map +0 -6
  300. package/dist/workers/dts.worker.d.ts +0 -75
  301. package/dist/workers/dts.worker.d.ts.map +0 -1
  302. package/dist/workers/dts.worker.js +0 -270
  303. package/dist/workers/dts.worker.js.map +0 -6
  304. package/dist/workers/library.worker.d.ts +0 -75
  305. package/dist/workers/library.worker.d.ts.map +0 -1
  306. package/dist/workers/library.worker.js +0 -166
  307. package/dist/workers/library.worker.js.map +0 -6
  308. package/dist/workers/server.worker.d.ts.map +0 -1
  309. package/dist/workers/server.worker.js +0 -482
  310. package/dist/workers/server.worker.js.map +0 -6
  311. package/src/builders/BaseBuilder.ts +0 -218
  312. package/src/builders/DtsBuilder.ts +0 -92
  313. package/src/builders/LibraryBuilder.ts +0 -110
  314. package/src/builders/types.ts +0 -60
  315. package/src/capacitor/capacitor.ts +0 -931
  316. package/src/commands/device.ts +0 -140
  317. package/src/commands/init.ts +0 -113
  318. package/src/electron/electron.ts +0 -362
  319. package/src/orchestrators/DevOrchestrator.ts +0 -744
  320. package/src/orchestrators/WatchOrchestrator.ts +0 -277
  321. package/src/utils/tailwind-config-deps.ts +0 -98
  322. package/src/utils/template.ts +0 -56
  323. package/src/utils/vite-config.ts +0 -390
  324. package/src/workers/client.worker.ts +0 -250
  325. package/src/workers/dts.worker.ts +0 -453
  326. package/src/workers/library.worker.ts +0 -316
  327. package/src/workers/server.worker.ts +0 -734
  328. package/templates/init/.gitignore.hbs +0 -34
  329. package/templates/init/.npmrc.hbs +0 -1
  330. package/templates/init/.prettierignore +0 -1
  331. package/templates/init/.prettierrc.yaml +0 -12
  332. package/templates/init/eslint.config.ts +0 -15
  333. package/templates/init/mise.toml +0 -3
  334. package/templates/init/package.json.hbs +0 -32
  335. package/templates/init/packages/client-admin/index.html.hbs +0 -144
  336. package/templates/init/packages/client-admin/package.json.hbs +0 -27
  337. package/templates/init/packages/client-admin/public/assets/logo-landscape.png +0 -0
  338. package/templates/init/packages/client-admin/public/assets/logo.png +0 -0
  339. package/templates/init/packages/client-admin/public/favicon.ico +0 -0
  340. package/templates/init/packages/client-admin/src/App.tsx +0 -42
  341. package/templates/init/packages/client-admin/src/dev/DevDialog.tsx +0 -34
  342. package/templates/init/packages/client-admin/src/events/AuthChangeEvent.ts +0 -3
  343. package/templates/init/packages/client-admin/src/main.css +0 -4
  344. package/templates/init/packages/client-admin/src/main.tsx.hbs +0 -146
  345. package/templates/init/packages/client-admin/src/providers/AppServiceProvider.tsx.hbs +0 -103
  346. package/templates/init/packages/client-admin/src/providers/AppStructureProvider.tsx +0 -84
  347. package/templates/init/packages/client-admin/src/providers/AuthProvider.tsx.hbs +0 -96
  348. package/templates/init/packages/client-admin/src/providers/configureSharedData.ts.hbs +0 -67
  349. package/templates/init/packages/client-admin/src/views/auth/LoginView.tsx +0 -132
  350. package/templates/init/packages/client-admin/src/views/home/HomeView.tsx +0 -108
  351. package/templates/init/packages/client-admin/src/views/home/base/employee/EmployeeDetail.tsx.hbs +0 -243
  352. package/templates/init/packages/client-admin/src/views/home/base/employee/EmployeeSheet.tsx.hbs +0 -271
  353. package/templates/init/packages/client-admin/src/views/home/base/role-permission/RoleDetail.tsx.hbs +0 -146
  354. package/templates/init/packages/client-admin/src/views/home/base/role-permission/RolePermissionDetail.tsx.hbs +0 -121
  355. package/templates/init/packages/client-admin/src/views/home/base/role-permission/RolePermissionView.tsx +0 -52
  356. package/templates/init/packages/client-admin/src/views/home/base/role-permission/RoleSheet.tsx.hbs +0 -125
  357. package/templates/init/packages/client-admin/src/views/home/main/MainView.tsx.hbs +0 -13
  358. package/templates/init/packages/client-admin/src/views/home/my-info/MyInfoDetail.tsx.hbs +0 -241
  359. package/templates/init/packages/client-admin/src/views/home/system/system-log/SystemLogSheet.tsx.hbs +0 -169
  360. package/templates/init/packages/client-admin/src/views/not-found/NotFoundView.tsx +0 -15
  361. package/templates/init/packages/client-admin/tailwind.config.ts +0 -10
  362. package/templates/init/packages/db-main/package.json.hbs +0 -13
  363. package/templates/init/packages/db-main/src/MainDbContext.ts +0 -22
  364. package/templates/init/packages/db-main/src/dataLogExt.ts +0 -127
  365. package/templates/init/packages/db-main/src/index.ts +0 -14
  366. package/templates/init/packages/db-main/src/tables/base/Employee.ts +0 -24
  367. package/templates/init/packages/db-main/src/tables/base/EmployeeConfig.ts +0 -13
  368. package/templates/init/packages/db-main/src/tables/base/Role.ts +0 -9
  369. package/templates/init/packages/db-main/src/tables/base/RolePermission.ts +0 -13
  370. package/templates/init/packages/db-main/src/tables/system/_DataLog.ts +0 -19
  371. package/templates/init/packages/db-main/src/tables/system/_Log.ts +0 -16
  372. package/templates/init/packages/server/package.json.hbs +0 -20
  373. package/templates/init/packages/server/public-dev/dev//354/264/210/352/270/260/355/231/224.xlsx +0 -0
  374. package/templates/init/packages/server/src/index.ts +0 -4
  375. package/templates/init/packages/server/src/main.ts.hbs +0 -34
  376. package/templates/init/packages/server/src/services/AuthService.ts.hbs +0 -171
  377. package/templates/init/packages/server/src/services/DevService.ts.hbs +0 -94
  378. package/templates/init/packages/server/src/services/EmployeeService.ts.hbs +0 -122
  379. package/templates/init/packages/server/src/services/RoleService.ts.hbs +0 -59
  380. package/templates/init/pnpm-workspace.yaml +0 -15
  381. package/templates/init/sd.config.ts.hbs +0 -48
  382. package/templates/init/tsconfig.json.hbs +0 -39
  383. package/templates/init/vitest.config.ts +0 -36
  384. package/tests/capacitor-exclude.spec.ts +0 -78
  385. package/tests/capacitor.spec.ts +0 -49
  386. package/tests/copy-src.spec.ts +0 -50
  387. package/tests/electron-exclude.spec.ts +0 -61
  388. package/tests/get-compiler-options-for-package.spec.ts +0 -80
  389. package/tests/get-package-source-files.spec.ts +0 -139
  390. package/tests/get-types-from-package-json.spec.ts +0 -92
  391. package/tests/infra/ResultCollector.spec.ts +0 -30
  392. package/tests/infra/SignalHandler.spec.ts +0 -38
  393. package/tests/infra/WorkerManager.spec.ts +0 -63
  394. package/tests/load-ignore-patterns.spec.ts +0 -163
  395. package/tests/load-sd-config.spec.ts +0 -100
  396. package/tests/package-utils.spec.ts +0 -188
  397. package/tests/parse-root-tsconfig.spec.ts +0 -89
  398. package/tests/publish-config-narrowing.spec.ts +0 -20
  399. package/tests/replace-deps.spec.ts +0 -308
  400. package/tests/run-lint.spec.ts +0 -366
  401. package/tests/run-typecheck.spec.ts +0 -544
  402. package/tests/run-watch.spec.ts +0 -76
  403. package/tests/sd-cli.spec.ts +0 -265
  404. package/tests/sd-public-dev-plugin-mime.spec.ts +0 -19
  405. package/tests/tailwind-config-deps.spec.ts +0 -30
  406. package/tests/template.spec.ts +0 -70
  407. package/tests/vite-config-exclude.spec.ts +0 -35
  408. package/tests/vite-config-outdir.spec.ts +0 -38
  409. package/tests/write-changed-output-files.spec.ts +0 -97
@@ -0,0 +1,43 @@
1
+ import { describe, it, expect, afterEach } from "vitest";
2
+ import { applyDebugLevel, createOnceGuard } from "../../src/utils/worker-utils";
3
+ import consola, { LogLevels } from "consola";
4
+
5
+ describe("applyDebugLevel", () => {
6
+ const originalLevel = consola.level;
7
+ const originalEnv = process.env["SD_DEBUG"];
8
+
9
+ afterEach(() => {
10
+ consola.level = originalLevel;
11
+ if (originalEnv === undefined) {
12
+ delete process.env["SD_DEBUG"];
13
+ } else {
14
+ process.env["SD_DEBUG"] = originalEnv;
15
+ }
16
+ });
17
+
18
+ it("sets consola level to debug when SD_DEBUG is 'true'", () => {
19
+ process.env["SD_DEBUG"] = "true";
20
+ applyDebugLevel();
21
+ expect(consola.level).toBe(LogLevels.debug);
22
+ });
23
+
24
+ it("does not change level when SD_DEBUG is not set", () => {
25
+ delete process.env["SD_DEBUG"];
26
+ const before = consola.level;
27
+ applyDebugLevel();
28
+ expect(consola.level).toBe(before);
29
+ });
30
+ });
31
+
32
+ describe("createOnceGuard", () => {
33
+ it("allows first call", () => {
34
+ const guard = createOnceGuard("startWatch");
35
+ expect(() => guard()).not.toThrow();
36
+ });
37
+
38
+ it("throws on second call", () => {
39
+ const guard = createOnceGuard("startWatch");
40
+ guard();
41
+ expect(() => guard()).toThrow("startWatch can only be called once per Worker");
42
+ });
43
+ });
@@ -0,0 +1,68 @@
1
+ import { describe, it, expect, beforeAll } from "vitest";
2
+ import type { Plugin } from "vite";
3
+ import { resolve } from "node:path";
4
+
5
+ const workspaceRoot = resolve(import.meta.dirname, "../../..");
6
+ const angularTsconfig = resolve(workspaceRoot, "packages/angular/tsconfig.json");
7
+
8
+ async function callTransform(
9
+ plugin: Plugin,
10
+ code: string,
11
+ id: string,
12
+ ): Promise<{ code: string; map?: unknown } | undefined> {
13
+ if (typeof plugin.transform !== "function") return undefined;
14
+ const result = await (plugin.transform as (code: string, id: string) => Promise<unknown>).call(
15
+ {},
16
+ code,
17
+ id,
18
+ );
19
+ return result as { code: string; map?: unknown } | undefined;
20
+ }
21
+
22
+ // Scenario 3: cwd 옵션으로 워크스페이스 루트를 지정한다
23
+ describe("angularVitestPlugin with explicit cwd", () => {
24
+ let plugin: Plugin;
25
+
26
+ beforeAll(async () => {
27
+ const { angularVitestPlugin } = await import("../src/vitest-plugin");
28
+ plugin = angularVitestPlugin({ tsconfig: angularTsconfig, cwd: workspaceRoot });
29
+ if (typeof plugin.buildStart === "function") {
30
+ await (plugin.buildStart as () => Promise<void>).call({});
31
+ }
32
+ }, 30_000);
33
+
34
+ it("compiles Angular source successfully with explicit cwd", async () => {
35
+ const filePath = resolve(
36
+ workspaceRoot,
37
+ "packages/angular/src/core/providers/sd-theme-provider.ts",
38
+ );
39
+ const result = await callTransform(plugin, "", filePath);
40
+
41
+ expect(result).toBeDefined();
42
+ expect(result!.code).toContain("ɵprov");
43
+ });
44
+ });
45
+
46
+ // Scenario 4: cwd 미지정 시 tsconfig 기준 상위 2단계를 사용한다
47
+ describe("angularVitestPlugin without cwd (fallback)", () => {
48
+ let plugin: Plugin;
49
+
50
+ beforeAll(async () => {
51
+ const { angularVitestPlugin } = await import("../src/vitest-plugin");
52
+ plugin = angularVitestPlugin({ tsconfig: angularTsconfig });
53
+ if (typeof plugin.buildStart === "function") {
54
+ await (plugin.buildStart as () => Promise<void>).call({});
55
+ }
56
+ }, 30_000);
57
+
58
+ it("compiles Angular source successfully with default cwd", async () => {
59
+ const filePath = resolve(
60
+ workspaceRoot,
61
+ "packages/angular/src/core/providers/sd-theme-provider.ts",
62
+ );
63
+ const result = await callTransform(plugin, "", filePath);
64
+
65
+ expect(result).toBeDefined();
66
+ expect(result!.code).toContain("ɵprov");
67
+ });
68
+ });
@@ -0,0 +1,103 @@
1
+ import { describe, it, expect, beforeAll } from "vitest";
2
+ import type { Plugin } from "vite";
3
+ import { resolve } from "node:path";
4
+
5
+ const workspaceRoot = resolve(import.meta.dirname, "../../..");
6
+ const angularTsconfig = resolve(workspaceRoot, "packages/angular/tsconfig.json");
7
+
8
+ async function callTransform(
9
+ plugin: Plugin,
10
+ code: string,
11
+ id: string,
12
+ ): Promise<{ code: string; map?: unknown } | undefined> {
13
+ if (typeof plugin.transform !== "function") return undefined;
14
+ const result = await (plugin.transform as (code: string, id: string) => Promise<unknown>).call(
15
+ {},
16
+ code,
17
+ id,
18
+ );
19
+ return result as { code: string; map?: unknown } | undefined;
20
+ }
21
+
22
+ describe("angularVitestPlugin", () => {
23
+ let plugin: Plugin;
24
+
25
+ beforeAll(async () => {
26
+ const { angularVitestPlugin } = await import("../src/vitest-plugin");
27
+ plugin = angularVitestPlugin({ tsconfig: angularTsconfig });
28
+ if (typeof plugin.buildStart === "function") {
29
+ await (plugin.buildStart as () => Promise<void>).call({});
30
+ }
31
+ }, 30_000);
32
+
33
+ // Unit: non-Angular 파일 필터링
34
+ it("returns undefined for node_modules path", async () => {
35
+ const result = await callTransform(
36
+ plugin,
37
+ "",
38
+ resolve(workspaceRoot, "node_modules/@angular/core/index.ts"),
39
+ );
40
+ expect(result).toBeUndefined();
41
+ });
42
+
43
+ it("returns undefined for non-.ts file", async () => {
44
+ const result = await callTransform(plugin, "", resolve(workspaceRoot, "vitest.config.js"));
45
+ expect(result).toBeUndefined();
46
+ });
47
+
48
+ it("returns undefined for test file not in compilation scope", async () => {
49
+ const result = await callTransform(
50
+ plugin,
51
+ "",
52
+ resolve(workspaceRoot, "packages/angular/tests/testbed-setup.spec.ts"),
53
+ );
54
+ expect(result).toBeUndefined();
55
+ });
56
+
57
+ // Unit: @Directive 변환
58
+ it("compiles @Directive source and serves ɵdir runtime code", async () => {
59
+ const filePath = resolve(
60
+ workspaceRoot,
61
+ "packages/angular/src/core/directives/sd-events.directive.ts",
62
+ );
63
+ const result = await callTransform(plugin, "", filePath);
64
+
65
+ expect(result).toBeDefined();
66
+ expect(result!.code).toContain("ɵdir");
67
+ });
68
+
69
+ // Unit: 소스맵 포함 (inline)
70
+ it("includes inline sourcemap in compiled output", async () => {
71
+ const filePath = resolve(
72
+ workspaceRoot,
73
+ "packages/angular/src/core/providers/sd-theme-provider.ts",
74
+ );
75
+ const result = await callTransform(plugin, "", filePath);
76
+
77
+ expect(result).toBeDefined();
78
+ expect(result!.code).toContain("//# sourceMappingURL=data:application/json;base64,");
79
+ });
80
+
81
+ // Acceptance: Scenario "vitest-plugin이 동일한 SCSS 컴파일 모듈을 사용한다"
82
+ // buildStart succeeds with SCSS-enabled transformResource, proving scss-compiler is wired up.
83
+ // The angular package currently has no components with SCSS styles, so this verifies
84
+ // the integration path without exercising actual SCSS content.
85
+ it("initializes with SCSS-enabled transformResource without errors", () => {
86
+ // buildStart already called in beforeAll — if transformResource had an error, it would throw
87
+ expect(plugin).toBeDefined();
88
+ expect(plugin.name).toBe("angular-vitest");
89
+ });
90
+
91
+ // Acceptance: 플러그인 초기화 + @Injectable AOT 컴파일 + 인메모리 서빙
92
+ it("compiles @Injectable source and serves ɵprov runtime code via transform", async () => {
93
+ const filePath = resolve(
94
+ workspaceRoot,
95
+ "packages/angular/src/core/providers/sd-theme-provider.ts",
96
+ );
97
+ const result = await callTransform(plugin, "", filePath);
98
+
99
+ expect(result).toBeDefined();
100
+ expect(result!.code).toContain("ɵprov");
101
+ expect(result!.code).not.toContain("@Injectable");
102
+ });
103
+ });
@@ -0,0 +1,258 @@
1
+ import { describe, it, expect, vi, beforeEach } from "vitest";
2
+
3
+ //#region Mocks
4
+
5
+ let workerFns: Record<string, (...args: any[]) => any>;
6
+ let mockSend: ReturnType<typeof vi.fn>;
7
+
8
+ // FsWatcher mock
9
+ const mockOnChange = vi.fn();
10
+ const mockWatcherClose = vi.fn();
11
+
12
+ // tsc build mock
13
+ const mockRunTscPackageBuild = vi.fn(() => ({
14
+ success: true,
15
+ errors: undefined,
16
+ diagnostics: [],
17
+ errorCount: 0,
18
+ warningCount: 0,
19
+ }));
20
+
21
+ vi.mock("@simplysm/core-node", () => ({
22
+ createWorker: vi.fn((fns: Record<string, Function>) => {
23
+ workerFns = fns as any;
24
+ mockSend = vi.fn();
25
+ return { send: mockSend };
26
+ }),
27
+ FsWatcher: {
28
+ watch: vi.fn(() => Promise.resolve({
29
+ onChange: mockOnChange,
30
+ close: mockWatcherClose,
31
+ })),
32
+ },
33
+ }));
34
+
35
+ vi.mock("@simplysm/core-common", () => ({
36
+ err: { message: (e: any) => e?.message ?? String(e) },
37
+ }));
38
+
39
+ vi.mock("consola", () => ({
40
+ consola: {
41
+ withTag: vi.fn(() => ({
42
+ debug: vi.fn(),
43
+ warn: vi.fn(),
44
+ })),
45
+ },
46
+ }));
47
+
48
+ vi.mock("../../src/utils/tsc-build", () => ({
49
+ runTscPackageBuild: mockRunTscPackageBuild,
50
+ }));
51
+
52
+ vi.mock("../../src/utils/worker-utils", () => ({
53
+ applyDebugLevel: vi.fn(),
54
+ registerCleanupHandlers: vi.fn(),
55
+ createOnceGuard: vi.fn(() => vi.fn()),
56
+ }));
57
+
58
+ const mockCollectDeps = vi.fn((_pkgDir: string, _cwd: string) => ({ workspaceDeps: [] as string[], replaceDeps: [] as string[] }));
59
+ vi.mock("../../src/utils/package-utils", () => ({
60
+ collectDeps: (...args: [string, string]) => mockCollectDeps(...args),
61
+ }));
62
+
63
+ //#endregion
64
+
65
+ // Force fresh module import for each test
66
+ beforeEach(async () => {
67
+ vi.clearAllMocks();
68
+ mockRunTscPackageBuild.mockReturnValue({
69
+ success: true,
70
+ errors: undefined,
71
+ diagnostics: [],
72
+ errorCount: 0,
73
+ warningCount: 0,
74
+ });
75
+ mockCollectDeps.mockReturnValue({ workspaceDeps: [], replaceDeps: [] });
76
+ // Re-import to get fresh workerFns
77
+ vi.resetModules();
78
+ await import("../../src/workers/library-build.worker");
79
+ });
80
+
81
+ const buildInfo = {
82
+ name: "test-pkg",
83
+ config: { target: "node" as const },
84
+ cwd: "/",
85
+ pkgDir: "/pkg",
86
+ output: { js: true, dts: true },
87
+ };
88
+
89
+ describe("library-build.worker build()", () => {
90
+ // Acceptance: tsc builds JS + DTS in single process
91
+ it("runs tsc with output flags and returns combined result", () => {
92
+ const result = workerFns["build"]({ ...buildInfo, output: { js: true, dts: true } });
93
+
94
+ expect(result.js.success).toBe(true);
95
+ expect(result.dts.success).toBe(true);
96
+ expect(mockRunTscPackageBuild).toHaveBeenCalledWith(
97
+ expect.objectContaining({ output: { js: true, dts: true } }),
98
+ );
99
+ });
100
+
101
+ // Acceptance: DTS only build
102
+ it("passes dts-only output to tsc", () => {
103
+ const result = workerFns["build"]({ ...buildInfo, output: { js: false, dts: true } });
104
+
105
+ expect(result.js.success).toBe(true);
106
+ expect(result.dts.success).toBe(true);
107
+ expect(mockRunTscPackageBuild).toHaveBeenCalledWith(
108
+ expect.objectContaining({ output: { js: false, dts: true } }),
109
+ );
110
+ });
111
+
112
+ // Acceptance: Typecheck only
113
+ it("runs typecheck only when both false", () => {
114
+ const result = workerFns["build"]({ ...buildInfo, output: { js: false, dts: false } });
115
+
116
+ expect(result.dts.success).toBe(true);
117
+ expect(mockRunTscPackageBuild).toHaveBeenCalledWith(
118
+ expect.objectContaining({ output: { js: false, dts: false } }),
119
+ );
120
+ });
121
+
122
+ // Unit: tsc failure reflects in both js and dts results
123
+ it("reports failure in both js and dts when tsc fails", () => {
124
+ mockRunTscPackageBuild.mockReturnValueOnce({
125
+ success: false,
126
+ errors: ["TS2345: type error"] as any,
127
+ diagnostics: [{ code: 2345, category: 1 }] as any,
128
+ errorCount: 1,
129
+ warningCount: 0,
130
+ });
131
+
132
+ const result = workerFns["build"]({ ...buildInfo, output: { js: true, dts: true } });
133
+
134
+ expect(result.js.success).toBe(false);
135
+ expect(result.js.errors).toContain("TS2345: type error");
136
+ expect(result.dts.success).toBe(false);
137
+ expect(result.dts.diagnostics).toHaveLength(1);
138
+ });
139
+
140
+ // Unit: build is synchronous (no esbuild async)
141
+ it("returns result synchronously (not a Promise)", () => {
142
+ const result = workerFns["build"]({ ...buildInfo });
143
+ // If it were async, result would be a Promise
144
+ expect(result).not.toBeInstanceOf(Promise);
145
+ expect(result.js.success).toBe(true);
146
+ });
147
+ });
148
+
149
+ describe("library-build.worker startWatch()", () => {
150
+ // Acceptance: Initial build completes before returning
151
+ it("completes initial build and sends build event", async () => {
152
+ await workerFns["startWatch"]({ ...buildInfo, output: { js: true, dts: true } });
153
+
154
+ expect(mockSend).toHaveBeenCalledWith("build", expect.objectContaining({
155
+ js: expect.objectContaining({ success: true }),
156
+ dts: expect.objectContaining({ success: true }),
157
+ }));
158
+ });
159
+
160
+ // Acceptance: FsWatcher is set up
161
+ it("starts FsWatcher after initial build", async () => {
162
+ await workerFns["startWatch"]({ ...buildInfo, output: { js: true, dts: true } });
163
+
164
+ const { FsWatcher } = await import("@simplysm/core-node");
165
+ expect(FsWatcher.watch).toHaveBeenCalledWith([
166
+ expect.stringContaining("*.{ts,tsx}"),
167
+ ]);
168
+ expect(mockOnChange).toHaveBeenCalledWith(
169
+ expect.objectContaining({ delay: 300 }),
170
+ expect.any(Function),
171
+ );
172
+ });
173
+
174
+ // Acceptance: File change triggers rebuild with buildStart event
175
+ it("sends buildStart and build events on file change", async () => {
176
+ await workerFns["startWatch"]({ ...buildInfo, output: { js: true, dts: true } });
177
+
178
+ const onChangeCallback = mockOnChange.mock.calls[0][1];
179
+ mockSend.mockClear();
180
+
181
+ await onChangeCallback();
182
+
183
+ expect(mockSend).toHaveBeenCalledWith("buildStart", {});
184
+ expect(mockSend).toHaveBeenCalledWith("build", expect.objectContaining({
185
+ js: expect.objectContaining({ success: true }),
186
+ dts: expect.objectContaining({ success: true }),
187
+ }));
188
+ });
189
+
190
+ // Unit: No esbuild context management needed
191
+ it("does not require esbuild for watch mode", async () => {
192
+ await workerFns["startWatch"]({ ...buildInfo, output: { js: true, dts: true } });
193
+
194
+ // tsc is called for rebuild
195
+ expect(mockRunTscPackageBuild).toHaveBeenCalledWith(
196
+ expect.objectContaining({ output: { js: true, dts: true } }),
197
+ );
198
+ });
199
+
200
+ // Unit: error event on exception
201
+ it("sends error event on rebuild exception", async () => {
202
+ await workerFns["startWatch"]({ ...buildInfo, output: { js: true, dts: true } });
203
+
204
+ mockRunTscPackageBuild.mockImplementationOnce(() => { throw new Error("tsc crash"); });
205
+ const onChangeCallback = mockOnChange.mock.calls[0][1];
206
+ mockSend.mockClear();
207
+
208
+ await onChangeCallback();
209
+
210
+ expect(mockSend).toHaveBeenCalledWith("error", { message: "tsc crash" });
211
+ });
212
+
213
+ // Acceptance: Watches workspace dependency source directories
214
+ it("includes workspace dependency src/ in watch paths", async () => {
215
+ mockCollectDeps.mockReturnValue({ workspaceDeps: ["core-common", "core-node"], replaceDeps: [] });
216
+
217
+ await workerFns["startWatch"]({ ...buildInfo, output: { js: true, dts: true } });
218
+
219
+ const { FsWatcher } = await import("@simplysm/core-node");
220
+ const watchPaths = vi.mocked(FsWatcher.watch).mock.calls[0][0];
221
+
222
+ // Own src/ + 2 workspace deps' src/
223
+ expect(watchPaths).toHaveLength(3);
224
+ expect(watchPaths).toEqual(expect.arrayContaining([
225
+ expect.stringContaining("core-common"),
226
+ expect.stringContaining("core-node"),
227
+ ]));
228
+ });
229
+
230
+ // Unit: collectDeps is called with correct arguments
231
+ it("calls collectDeps with pkgDir and cwd", async () => {
232
+ await workerFns["startWatch"]({ ...buildInfo, output: { js: true, dts: true } });
233
+
234
+ expect(mockCollectDeps).toHaveBeenCalledWith("/pkg", "/");
235
+ });
236
+
237
+ // Unit: no extra paths when no workspace deps
238
+ it("watches only own src/ when no workspace deps", async () => {
239
+ mockCollectDeps.mockReturnValue({ workspaceDeps: [], replaceDeps: [] });
240
+
241
+ await workerFns["startWatch"]({ ...buildInfo, output: { js: true, dts: true } });
242
+
243
+ const { FsWatcher } = await import("@simplysm/core-node");
244
+ const watchPaths = vi.mocked(FsWatcher.watch).mock.calls[0][0];
245
+
246
+ expect(watchPaths).toHaveLength(1);
247
+ expect(watchPaths[0]).toContain("pkg");
248
+ });
249
+ });
250
+
251
+ describe("library-build.worker stopWatch()", () => {
252
+ it("cleans up FsWatcher", async () => {
253
+ await workerFns["startWatch"]({ ...buildInfo, output: { js: true, dts: true } });
254
+ await workerFns["stopWatch"]();
255
+
256
+ expect(mockWatcherClose).toHaveBeenCalled();
257
+ });
258
+ });
@@ -0,0 +1,187 @@
1
+ import { describe, it, expect, beforeAll, afterAll } from "vitest";
2
+ import { resolve } from "node:path";
3
+ import fs from "node:fs";
4
+ import { runNgtscBuild, compileGlobalScss } from "../../src/utils/ngtsc-build-core";
5
+
6
+ const workspaceRoot = resolve(import.meta.dirname, "../../../..");
7
+ const angularPkgDir = resolve(workspaceRoot, "packages/angular");
8
+ const distDir = resolve(angularPkgDir, "dist");
9
+
10
+ describe("ngtsc-build-core: NgtscProgram AOT compilation", () => {
11
+ beforeAll(() => {
12
+ // Clean dist before tests
13
+ if (fs.existsSync(distDir)) {
14
+ fs.rmSync(distDir, { recursive: true, force: true });
15
+ }
16
+ });
17
+
18
+ afterAll(() => {
19
+ // Clean up dist after tests
20
+ if (fs.existsSync(distDir)) {
21
+ fs.rmSync(distDir, { recursive: true, force: true });
22
+ }
23
+ });
24
+
25
+ // Acceptance: Scenario "@Injectable 데코레이터가 런타임 코드로 변환된다"
26
+ it("transforms @Injectable decorator to runtime ɵprov factory", async () => {
27
+ const result = await runNgtscBuild({
28
+ name: "angular",
29
+ cwd: workspaceRoot,
30
+ pkgDir: angularPkgDir,
31
+ output: { js: true, dts: false },
32
+ });
33
+
34
+ // Debug: print errors if build failed
35
+ if (!result.js.success) {
36
+ console.error("JS errors:", result.js.errors);
37
+ console.error("DTS errors:", result.dts.errors);
38
+ }
39
+
40
+ expect(result.js.success).toBe(true);
41
+
42
+ // Find the provider file output
43
+ const providerJsPath = resolve(distDir, "core", "providers", "sd-theme-provider.js");
44
+ expect(fs.existsSync(providerJsPath)).toBe(true);
45
+
46
+ const content = fs.readFileSync(providerJsPath, "utf-8");
47
+ // ɵprov is the Angular injectable factory
48
+ expect(content).toContain("ɵprov");
49
+ // Original @Injectable decorator should be removed
50
+ expect(content).not.toContain("@Injectable");
51
+ }, 60_000);
52
+
53
+ // Acceptance: Scenario "@Directive 데코레이터가 런타임 코드로 변환된다"
54
+ it("transforms @Directive decorator to runtime ɵdir definition", () => {
55
+ // dist already populated from prior test, check directive
56
+ const directiveJsPath = resolve(distDir, "core", "directives", "sd-events.directive.js");
57
+ expect(fs.existsSync(directiveJsPath)).toBe(true);
58
+
59
+ const content = fs.readFileSync(directiveJsPath, "utf-8");
60
+ expect(content).toContain("ɵdir");
61
+ }, 60_000);
62
+
63
+ // Acceptance: Scenario ".d.ts 파일이 Angular 메타데이터를 포함하여 출력된다"
64
+ it("outputs .d.ts files with Angular type metadata", async () => {
65
+ // Clean dist and run with dts: true
66
+ if (fs.existsSync(distDir)) {
67
+ fs.rmSync(distDir, { recursive: true, force: true });
68
+ }
69
+
70
+ const result = await runNgtscBuild({
71
+ name: "angular",
72
+ cwd: workspaceRoot,
73
+ pkgDir: angularPkgDir,
74
+ output: { js: true, dts: true },
75
+ });
76
+
77
+ expect(result.dts.success).toBe(true);
78
+
79
+ const providerDtsPath = resolve(distDir, "core", "providers", "sd-theme-provider.d.ts");
80
+ expect(fs.existsSync(providerDtsPath)).toBe(true);
81
+
82
+ const content = fs.readFileSync(providerDtsPath, "utf-8");
83
+ // Angular .d.ts includes ɵ metadata fields
84
+ expect(content).toMatch(/ɵ(prov|fac)/);
85
+ }, 60_000);
86
+
87
+ // Acceptance: Scenario "run()으로 one-time 빌드를 수행한다"
88
+ it("produces both JS and .d.ts when output is {js: true, dts: true}", () => {
89
+ // dist already populated from prior test
90
+ const jsExists = fs.existsSync(resolve(distDir, "core", "providers", "sd-theme-provider.js"));
91
+ const dtsExists = fs.existsSync(resolve(distDir, "core", "providers", "sd-theme-provider.d.ts"));
92
+
93
+ expect(jsExists).toBe(true);
94
+ expect(dtsExists).toBe(true);
95
+ }, 60_000);
96
+
97
+ // Acceptance: Scenario "run()에서 dts: false면 .d.ts를 생략한다"
98
+ it("omits .d.ts when output is {js: true, dts: false}", async () => {
99
+ if (fs.existsSync(distDir)) {
100
+ fs.rmSync(distDir, { recursive: true, force: true });
101
+ }
102
+
103
+ const result = await runNgtscBuild({
104
+ name: "angular",
105
+ cwd: workspaceRoot,
106
+ pkgDir: angularPkgDir,
107
+ output: { js: true, dts: false },
108
+ });
109
+
110
+ expect(result.js.success).toBe(true);
111
+
112
+ const jsExists = fs.existsSync(resolve(distDir, "core", "providers", "sd-theme-provider.js"));
113
+ expect(jsExists).toBe(true);
114
+
115
+ // Should NOT have .d.ts files
116
+ const dtsExists = fs.existsSync(resolve(distDir, "core", "providers", "sd-theme-provider.d.ts"));
117
+ expect(dtsExists).toBe(false);
118
+ }, 60_000);
119
+
120
+ // Acceptance: Scenario "TypeScript + Angular diagnostics를 통합 수집한다"
121
+ it("collects diagnostics from both TypeScript and Angular compiler", async () => {
122
+ if (fs.existsSync(distDir)) {
123
+ fs.rmSync(distDir, { recursive: true, force: true });
124
+ }
125
+
126
+ const result = await runNgtscBuild({
127
+ name: "angular",
128
+ cwd: workspaceRoot,
129
+ pkgDir: angularPkgDir,
130
+ output: { js: true, dts: true },
131
+ });
132
+
133
+ // Angular package should compile cleanly
134
+ expect(result.dts.diagnostics).toBeDefined();
135
+ expect(Array.isArray(result.dts.diagnostics)).toBe(true);
136
+ }, 60_000);
137
+
138
+ // Acceptance: Scenario "타입 에러가 있어도 빌드 결과를 반환한다"
139
+ // This tests error handling by verifying the result structure is always returned
140
+ it("returns complete result structure even when build succeeds", async () => {
141
+ const result = await runNgtscBuild({
142
+ name: "angular",
143
+ cwd: workspaceRoot,
144
+ pkgDir: angularPkgDir,
145
+ output: { js: true, dts: true },
146
+ });
147
+
148
+ // Verify result structure completeness
149
+ expect(result.js).toHaveProperty("success");
150
+ expect(result.dts).toHaveProperty("success");
151
+ expect(result.dts).toHaveProperty("diagnostics");
152
+ expect(Array.isArray(result.dts.diagnostics)).toBe(true);
153
+ }, 60_000);
154
+
155
+ // Acceptance: Scenario "scss/styles.scss가 CSS로 컴파일되어 dist에 출력된다"
156
+ it("compiles scss/styles.scss to dist/styles.css", async () => {
157
+ if (fs.existsSync(distDir)) {
158
+ fs.rmSync(distDir, { recursive: true, force: true });
159
+ }
160
+
161
+ const result = await runNgtscBuild({
162
+ name: "angular",
163
+ cwd: workspaceRoot,
164
+ pkgDir: angularPkgDir,
165
+ output: { js: true, dts: false },
166
+ });
167
+
168
+ expect(result.dts.success).toBe(true);
169
+
170
+ const stylesCssPath = resolve(distDir, "styles.css");
171
+ expect(fs.existsSync(stylesCssPath)).toBe(true);
172
+
173
+ const content = fs.readFileSync(stylesCssPath, "utf-8");
174
+ expect(content.length).toBeGreaterThan(0);
175
+ }, 60_000);
176
+
177
+ // Acceptance: Scenario "scss/styles.scss가 없으면 전역 스타일 컴파일을 건너뛴다"
178
+ it("skips global SCSS when scss/styles.scss does not exist", () => {
179
+ const nonExistentPkgDir = resolve(import.meta.dirname, "__nonexistent_pkg__");
180
+
181
+ const errors = compileGlobalScss(nonExistentPkgDir, []);
182
+
183
+ // No errors and no dist/styles.css created
184
+ expect(errors).toEqual([]);
185
+ expect(fs.existsSync(resolve(nonExistentPkgDir, "dist", "styles.css"))).toBe(false);
186
+ });
187
+ });