@simplysm/sd-cli 13.0.100 → 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,186 @@
1
+ import { describe, it, expect, vi, beforeEach } from "vitest";
2
+ import path from "path";
3
+
4
+ vi.mock("fs/promises", () => ({
5
+ default: {
6
+ readFile: vi.fn(),
7
+ writeFile: vi.fn(),
8
+ mkdir: vi.fn(),
9
+ },
10
+ }));
11
+
12
+ vi.mock("consola", () => ({
13
+ consola: {
14
+ withTag: vi.fn(() => ({
15
+ debug: vi.fn(),
16
+ })),
17
+ },
18
+ }));
19
+
20
+ const { createServerEsbuildOptions, writeChangedOutputFiles } =
21
+ await import("../../src/utils/esbuild-config");
22
+
23
+ const { default: mockFs } = await import("fs/promises");
24
+
25
+ describe("createServerEsbuildOptions", () => {
26
+ const baseOptions = {
27
+ pkgDir: "/pkg",
28
+ entryPoints: ["/pkg/src/index.ts"],
29
+ };
30
+
31
+ it("produces ESM bundle with platform=node and target=node20", () => {
32
+ const result = createServerEsbuildOptions(baseOptions);
33
+ expect(result.format).toBe("esm");
34
+ expect(result.bundle).toBe(true);
35
+ expect(result.platform).toBe("node");
36
+ expect(result.target).toBe("node20");
37
+ });
38
+
39
+ it("minifies by default (production build)", () => {
40
+ const result = createServerEsbuildOptions(baseOptions);
41
+ expect(result.minify).toBe(true);
42
+ });
43
+
44
+ it("skips minification when dev=true (watch mode)", () => {
45
+ const result = createServerEsbuildOptions({ ...baseOptions, dev: true });
46
+ expect(result.minify).toBe(false);
47
+ });
48
+
49
+ it("includes createRequire shim banner for CJS compatibility", () => {
50
+ const result = createServerEsbuildOptions(baseOptions);
51
+ expect(result.banner).toBeDefined();
52
+ expect((result.banner as Record<string, string>)["js"]).toContain("createRequire");
53
+ expect((result.banner as Record<string, string>)["js"]).toContain("import.meta.url");
54
+ });
55
+
56
+ it("substitutes env vars via define (process.env.KEY → constant)", () => {
57
+ const result = createServerEsbuildOptions({
58
+ ...baseOptions,
59
+ env: { API_URL: "https://api.example.com", NODE_ENV: "production" },
60
+ });
61
+ expect(result.define).toEqual({
62
+ "process.env.API_URL": '"https://api.example.com"',
63
+ "process.env.NODE_ENV": '"production"',
64
+ });
65
+ });
66
+
67
+ it("produces empty define when env is not provided", () => {
68
+ const result = createServerEsbuildOptions(baseOptions);
69
+ expect(result.define).toEqual({});
70
+ });
71
+
72
+ it("passes external modules to esbuild", () => {
73
+ const result = createServerEsbuildOptions({
74
+ ...baseOptions,
75
+ external: ["bcrypt", "sharp"],
76
+ });
77
+ expect(result.external).toEqual(["bcrypt", "sharp"]);
78
+ });
79
+
80
+ it("sets outdir to pkgDir/dist", () => {
81
+ const result = createServerEsbuildOptions(baseOptions);
82
+ expect(result.outdir).toBe(path.join("/pkg", "dist"));
83
+ });
84
+
85
+ it("sets tsconfig to pkgDir/tsconfig.json", () => {
86
+ const result = createServerEsbuildOptions(baseOptions);
87
+ expect(result.tsconfig).toBe(path.join("/pkg", "tsconfig.json"));
88
+ });
89
+ });
90
+
91
+ describe("writeChangedOutputFiles", () => {
92
+ beforeEach(() => {
93
+ vi.mocked(mockFs.readFile).mockReset();
94
+ vi.mocked(mockFs.writeFile).mockReset();
95
+ vi.mocked(mockFs.mkdir).mockReset();
96
+ vi.mocked(mockFs.mkdir).mockResolvedValue(undefined as any);
97
+ vi.mocked(mockFs.writeFile).mockResolvedValue();
98
+ });
99
+
100
+ it("adds .js extension to relative import paths in .js files", async () => {
101
+ vi.mocked(mockFs.readFile).mockRejectedValue(new Error("not found"));
102
+
103
+ await writeChangedOutputFiles([
104
+ {
105
+ path: "/pkg/dist/foo.js",
106
+ text: 'import { bar } from "./bar";\nexport { baz } from "../utils/baz";',
107
+ },
108
+ ] as any);
109
+
110
+ expect(mockFs.writeFile).toHaveBeenCalledWith(
111
+ "/pkg/dist/foo.js",
112
+ 'import { bar } from "./bar.js";\nexport { baz } from "../utils/baz.js";',
113
+ );
114
+ });
115
+
116
+ it("preserves imports that already have extensions", async () => {
117
+ vi.mocked(mockFs.readFile).mockRejectedValue(new Error("not found"));
118
+
119
+ await writeChangedOutputFiles([
120
+ {
121
+ path: "/pkg/dist/foo.js",
122
+ text: 'import data from "./data.json";\nimport styles from "./styles.css";\nimport mod from "./native.node";',
123
+ },
124
+ ] as any);
125
+
126
+ expect(mockFs.writeFile).toHaveBeenCalledWith(
127
+ "/pkg/dist/foo.js",
128
+ 'import data from "./data.json";\nimport styles from "./styles.css";\nimport mod from "./native.node";',
129
+ );
130
+ });
131
+
132
+ it("skips writing when transformed content matches existing file", async () => {
133
+ vi.mocked(mockFs.readFile).mockResolvedValue('import { bar } from "./bar.js";' as any);
134
+
135
+ const hasChanges = await writeChangedOutputFiles([
136
+ {
137
+ path: "/pkg/dist/foo.js",
138
+ text: 'import { bar } from "./bar";',
139
+ },
140
+ ] as any);
141
+
142
+ expect(mockFs.writeFile).not.toHaveBeenCalled();
143
+ expect(hasChanges).toBe(false);
144
+ });
145
+
146
+ it("writes file and returns true when content changed", async () => {
147
+ vi.mocked(mockFs.readFile).mockResolvedValue('import { old } from "./old.js";' as any);
148
+
149
+ const hasChanges = await writeChangedOutputFiles([
150
+ {
151
+ path: "/pkg/dist/foo.js",
152
+ text: 'import { bar } from "./bar";',
153
+ },
154
+ ] as any);
155
+
156
+ expect(mockFs.writeFile).toHaveBeenCalled();
157
+ expect(hasChanges).toBe(true);
158
+ });
159
+
160
+ it("writes new file when existing file does not exist", async () => {
161
+ vi.mocked(mockFs.readFile).mockRejectedValue(new Error("ENOENT"));
162
+
163
+ const hasChanges = await writeChangedOutputFiles([
164
+ {
165
+ path: "/pkg/dist/foo.js",
166
+ text: 'const x = 1;',
167
+ },
168
+ ] as any);
169
+
170
+ expect(mockFs.mkdir).toHaveBeenCalledWith(path.dirname("/pkg/dist/foo.js"), { recursive: true });
171
+ expect(mockFs.writeFile).toHaveBeenCalledWith("/pkg/dist/foo.js", "const x = 1;");
172
+ expect(hasChanges).toBe(true);
173
+ });
174
+
175
+ it("does not transform non-.js files", async () => {
176
+ vi.mocked(mockFs.readFile).mockRejectedValue(new Error("not found"));
177
+
178
+ const mapContent = '{"version":3,"sources":["./bar"]}';
179
+ await writeChangedOutputFiles([
180
+ { path: "/pkg/dist/foo.js.map", text: mapContent },
181
+ ] as any);
182
+
183
+ expect(mockFs.writeFile).toHaveBeenCalledWith("/pkg/dist/foo.js.map", mapContent);
184
+ });
185
+ });
186
+
@@ -0,0 +1,161 @@
1
+ import { describe, it, expect, vi, beforeEach } from "vitest";
2
+ import path from "path";
3
+
4
+ // Mock fs (readFileSync, existsSync)
5
+ const mockReadFileSync = vi.fn();
6
+ const mockExistsSync = vi.fn();
7
+
8
+ vi.mock("fs", () => ({
9
+ readFileSync: (...args: any[]) => mockReadFileSync(...args),
10
+ existsSync: (...args: any[]) => mockExistsSync(...args),
11
+ }));
12
+
13
+ // Mock createRequire to control module resolution
14
+ const mockResolve = vi.fn();
15
+ vi.mock("module", () => ({
16
+ createRequire: vi.fn(() => ({
17
+ resolve: mockResolve,
18
+ })),
19
+ }));
20
+
21
+ vi.mock("consola", () => ({
22
+ consola: {
23
+ withTag: vi.fn(() => ({
24
+ debug: vi.fn(),
25
+ })),
26
+ },
27
+ }));
28
+
29
+ const { collectUninstalledOptionalPeerDeps, collectNativeModuleExternals } =
30
+ await import("../../src/utils/esbuild-config");
31
+
32
+ describe("collectUninstalledOptionalPeerDeps", () => {
33
+ beforeEach(() => {
34
+ mockReadFileSync.mockReset();
35
+ mockResolve.mockReset();
36
+ });
37
+
38
+ it("detects uninstalled optional peer dependencies", () => {
39
+ // Root package.json with one dependency
40
+ mockReadFileSync.mockImplementation((filePath: string) => {
41
+ if (filePath === path.join("/pkg", "package.json")) {
42
+ return JSON.stringify({ dependencies: { "some-lib": "^1.0.0" } });
43
+ }
44
+ // some-lib's package.json with optional peer dep
45
+ return JSON.stringify({
46
+ peerDependencies: { "optional-peer": "^2.0.0" },
47
+ peerDependenciesMeta: { "optional-peer": { optional: true } },
48
+ });
49
+ });
50
+
51
+ // Resolving some-lib/package.json succeeds
52
+ mockResolve.mockImplementation((name: string) => {
53
+ if (name === "some-lib/package.json") {
54
+ return "/node_modules/some-lib/package.json";
55
+ }
56
+ // optional-peer cannot be resolved (not installed)
57
+ throw new Error("MODULE_NOT_FOUND");
58
+ });
59
+
60
+ const result = collectUninstalledOptionalPeerDeps("/pkg");
61
+ expect(result).toContain("optional-peer");
62
+ });
63
+
64
+ it("does not include installed optional peer dependencies", () => {
65
+ mockReadFileSync.mockImplementation((filePath: string) => {
66
+ if (filePath === path.join("/pkg", "package.json")) {
67
+ return JSON.stringify({ dependencies: { "some-lib": "^1.0.0" } });
68
+ }
69
+ return JSON.stringify({
70
+ peerDependencies: { "installed-peer": "^2.0.0" },
71
+ peerDependenciesMeta: { "installed-peer": { optional: true } },
72
+ });
73
+ });
74
+
75
+ mockResolve.mockImplementation((name: string) => {
76
+ if (name === "some-lib/package.json") {
77
+ return "/node_modules/some-lib/package.json";
78
+ }
79
+ // installed-peer resolves successfully
80
+ if (name === "installed-peer") {
81
+ return "/node_modules/installed-peer/index.js";
82
+ }
83
+ throw new Error("MODULE_NOT_FOUND");
84
+ });
85
+
86
+ const result = collectUninstalledOptionalPeerDeps("/pkg");
87
+ expect(result).not.toContain("installed-peer");
88
+ });
89
+
90
+ it("returns empty array when no optional peer deps exist", () => {
91
+ mockReadFileSync.mockImplementation((filePath: string) => {
92
+ if (filePath === path.join("/pkg", "package.json")) {
93
+ return JSON.stringify({ dependencies: { "some-lib": "^1.0.0" } });
94
+ }
95
+ return JSON.stringify({ dependencies: {} });
96
+ });
97
+
98
+ mockResolve.mockImplementation((name: string) => {
99
+ if (name === "some-lib/package.json") {
100
+ return "/node_modules/some-lib/package.json";
101
+ }
102
+ throw new Error("MODULE_NOT_FOUND");
103
+ });
104
+
105
+ const result = collectUninstalledOptionalPeerDeps("/pkg");
106
+ expect(result).toEqual([]);
107
+ });
108
+ });
109
+
110
+ describe("collectNativeModuleExternals", () => {
111
+ beforeEach(() => {
112
+ mockReadFileSync.mockReset();
113
+ mockExistsSync.mockReset();
114
+ mockResolve.mockReset();
115
+ });
116
+
117
+ it("detects native modules with binding.gyp", () => {
118
+ mockReadFileSync.mockImplementation((filePath: string) => {
119
+ if (filePath === path.join("/pkg", "package.json")) {
120
+ return JSON.stringify({ dependencies: { bcrypt: "^5.0.0" } });
121
+ }
122
+ return JSON.stringify({ dependencies: {} });
123
+ });
124
+
125
+ mockResolve.mockImplementation((name: string) => {
126
+ if (name === "bcrypt/package.json") {
127
+ return "/node_modules/bcrypt/package.json";
128
+ }
129
+ throw new Error("MODULE_NOT_FOUND");
130
+ });
131
+
132
+ mockExistsSync.mockImplementation((filePath: string) => {
133
+ return filePath === path.join("/node_modules/bcrypt", "binding.gyp");
134
+ });
135
+
136
+ const result = collectNativeModuleExternals("/pkg");
137
+ expect(result).toContain("bcrypt");
138
+ });
139
+
140
+ it("does not include non-native modules", () => {
141
+ mockReadFileSync.mockImplementation((filePath: string) => {
142
+ if (filePath === path.join("/pkg", "package.json")) {
143
+ return JSON.stringify({ dependencies: { lodash: "^4.0.0" } });
144
+ }
145
+ return JSON.stringify({ dependencies: {} });
146
+ });
147
+
148
+ mockResolve.mockImplementation((name: string) => {
149
+ if (name === "lodash/package.json") {
150
+ return "/node_modules/lodash/package.json";
151
+ }
152
+ throw new Error("MODULE_NOT_FOUND");
153
+ });
154
+
155
+ mockExistsSync.mockReturnValue(false);
156
+
157
+ const result = collectNativeModuleExternals("/pkg");
158
+ expect(result).not.toContain("lodash");
159
+ expect(result).toEqual([]);
160
+ });
161
+ });
@@ -0,0 +1,66 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { resolve, join } from "node:path";
3
+
4
+ const workspaceRoot = resolve(import.meta.dirname, "../../../..");
5
+ const angularPkgDir = resolve(workspaceRoot, "packages/angular");
6
+
7
+ // Scenario 1: loadPaths 헬퍼가 동일한 경로를 반환한다
8
+ describe("buildScssLoadPaths", () => {
9
+ it("returns [pkgDir/scss, cwd/node_modules] for given NgtscBuildInfo", async () => {
10
+ const { buildScssLoadPaths } = await import("../../src/utils/ngtsc-build-core");
11
+
12
+ const info = {
13
+ name: "angular",
14
+ cwd: workspaceRoot,
15
+ pkgDir: angularPkgDir,
16
+ output: { js: true, dts: false },
17
+ };
18
+
19
+ const result = buildScssLoadPaths(info);
20
+
21
+ expect(result).toEqual([
22
+ join(angularPkgDir, "scss"),
23
+ join(workspaceRoot, "node_modules"),
24
+ ]);
25
+ });
26
+
27
+ // Unit: different cwd produces different node_modules path
28
+ it("uses cwd from info to construct node_modules path", async () => {
29
+ const { buildScssLoadPaths } = await import("../../src/utils/ngtsc-build-core");
30
+
31
+ const customCwd = "/custom/workspace";
32
+ const customPkgDir = "/custom/workspace/packages/my-pkg";
33
+
34
+ const result = buildScssLoadPaths({
35
+ name: "test",
36
+ cwd: customCwd,
37
+ pkgDir: customPkgDir,
38
+ output: { js: true, dts: false },
39
+ });
40
+
41
+ expect(result).toEqual([
42
+ join(customPkgDir, "scss"),
43
+ join(customCwd, "node_modules"),
44
+ ]);
45
+ });
46
+ });
47
+
48
+ // Scenario 2: createNgtscProgramWithHost와 compileGlobalScss가 동일한 loadPaths를 사용한다
49
+ // This is verified by the fact that both call buildScssLoadPaths(info) — tested via
50
+ // running a real build and confirming success (the inline SCSS and global SCSS both resolve).
51
+ describe("runNgtscBuild loadPaths consistency", () => {
52
+ it("uses the same loadPaths for transformResource and compileGlobalScss", async () => {
53
+ const { runNgtscBuild } = await import("../../src/utils/ngtsc-build-core");
54
+
55
+ const result = await runNgtscBuild({
56
+ name: "angular",
57
+ cwd: workspaceRoot,
58
+ pkgDir: angularPkgDir,
59
+ output: { js: true, dts: false },
60
+ });
61
+
62
+ // If loadPaths were inconsistent, SCSS compilation would fail
63
+ expect(result.dts.success).toBe(true);
64
+ expect(result.dts.errors).toBeUndefined();
65
+ }, 60_000);
66
+ });
@@ -0,0 +1,165 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import path from "path";
3
+ import { createOutputPathRewriter, adjustMapSources, addJsExtensionToImports } from "../../src/utils/output-path-rewriter";
4
+
5
+ // Use path.resolve to get platform-correct absolute paths
6
+ const pkgDir = path.resolve("/workspace/packages/my-pkg");
7
+ const distDir = path.resolve(pkgDir, "dist");
8
+
9
+ describe("createOutputPathRewriter", () => {
10
+ const rewrite = createOutputPathRewriter(pkgDir);
11
+
12
+ it("rewrites own nested .d.ts to flat structure", () => {
13
+ const nestedPath = path.resolve(distDir, "my-pkg", "src", "index.d.ts");
14
+ const result = rewrite(nestedPath, "declare const x: number;");
15
+
16
+ expect(result).not.toBeNull();
17
+ expect(result![0]).toBe(path.join(distDir, "index.d.ts"));
18
+ expect(result![1]).toBe("declare const x: number;");
19
+ });
20
+
21
+ it("rewrites own nested subdirectory .d.ts to flat structure", () => {
22
+ const nestedPath = path.resolve(distDir, "my-pkg", "src", "utils", "helper.d.ts");
23
+ const result = rewrite(nestedPath, "declare const y: string;");
24
+
25
+ expect(result).not.toBeNull();
26
+ expect(result![0]).toBe(path.join(distDir, "utils", "helper.d.ts"));
27
+ });
28
+
29
+ it("returns null for other packages' nested .d.ts", () => {
30
+ const otherPkgPath = path.resolve(distDir, "other-pkg", "src", "index.d.ts");
31
+ const result = rewrite(otherPkgPath, "");
32
+
33
+ expect(result).toBeNull();
34
+ });
35
+
36
+ it("passes through already flat .d.ts as-is", () => {
37
+ const flatPath = path.resolve(distDir, "index.d.ts");
38
+ const result = rewrite(flatPath, "declare const z: boolean;");
39
+
40
+ expect(result).not.toBeNull();
41
+ expect(result![0]).toBe(flatPath);
42
+ expect(result![1]).toBe("declare const z: boolean;");
43
+ });
44
+
45
+ it("returns null for files outside dist/", () => {
46
+ const outsidePath = path.resolve(pkgDir, "src", "index.ts");
47
+ const result = rewrite(outsidePath, "");
48
+
49
+ expect(result).toBeNull();
50
+ });
51
+
52
+ it("adjusts .d.ts.map sources when rewriting nested to flat", () => {
53
+ const nestedPath = path.resolve(distDir, "my-pkg", "src", "index.d.ts.map");
54
+ const mapContent = JSON.stringify({ version: 3, sources: ["../../../../src/index.ts"] });
55
+ const result = rewrite(nestedPath, mapContent);
56
+
57
+ expect(result).not.toBeNull();
58
+ expect(result![0]).toBe(path.join(distDir, "index.d.ts.map"));
59
+ // Sources path should be adjusted for the new location
60
+ const parsedMap = JSON.parse(result![1]) as { sources: string[] };
61
+ expect(parsedMap.sources).toBeDefined();
62
+ expect(parsedMap.sources.length).toBe(1);
63
+ });
64
+ });
65
+
66
+ describe("adjustMapSources", () => {
67
+ it("returns content as-is when directories are the same", () => {
68
+ const content = JSON.stringify({ version: 3, sources: ["./foo.ts"] });
69
+ const result = adjustMapSources(content, "/a/b", "/a/b");
70
+ expect(result).toBe(content);
71
+ });
72
+
73
+ it("adjusts sources relative paths when directory changes", () => {
74
+ const original = path.resolve("/workspace/packages/my-pkg/dist/my-pkg/src");
75
+ const target = path.resolve("/workspace/packages/my-pkg/dist");
76
+ const content = JSON.stringify({
77
+ version: 3,
78
+ sources: [path.join("..", "..", "..", "src", "index.ts")],
79
+ });
80
+
81
+ const result = adjustMapSources(content, original, target);
82
+ const parsed = JSON.parse(result) as { sources: string[] };
83
+
84
+ // The absolute source should be the same, just the relative path changes
85
+ const absoluteFromOriginal = path.resolve(original, "..", "..", "..", "src", "index.ts");
86
+ const expectedRelative = path.relative(target, absoluteFromOriginal);
87
+ expect(parsed.sources[0]).toBe(expectedRelative);
88
+ });
89
+
90
+ it("returns content as-is for invalid JSON", () => {
91
+ const result = adjustMapSources("not json", "/a", "/b");
92
+ expect(result).toBe("not json");
93
+ });
94
+
95
+ it("handles content without sources array", () => {
96
+ const content = JSON.stringify({ version: 3 });
97
+ const result = adjustMapSources(content, "/a", "/b");
98
+ expect(JSON.parse(result)).toEqual({ version: 3 });
99
+ });
100
+ });
101
+
102
+ // Acceptance: Scenario "확장자 없는 상대 import에 .js 추가"
103
+ // Acceptance: Scenario "이미 확장자가 있는 import는 변경하지 않는다"
104
+ // Acceptance: Scenario "bare specifier는 변경하지 않는다"
105
+ // Acceptance: Scenario "dynamic import에도 .js 추가"
106
+ describe("addJsExtensionToImports", () => {
107
+ it("adds .js to extensionless relative import", () => {
108
+ const input = 'import { foo } from "./utils";';
109
+ expect(addJsExtensionToImports(input)).toBe('import { foo } from "./utils.js";');
110
+ });
111
+
112
+ it("adds .js to parent directory relative import", () => {
113
+ const input = 'import { bar } from "../types";';
114
+ expect(addJsExtensionToImports(input)).toBe('import { bar } from "../types.js";');
115
+ });
116
+
117
+ it("adds .js to dynamic import", () => {
118
+ const input = 'const m = import("./lazy");';
119
+ expect(addJsExtensionToImports(input)).toBe('const m = import("./lazy.js");');
120
+ });
121
+
122
+ it("does not modify import already ending with .js", () => {
123
+ const input = 'import { x } from "./already.js";';
124
+ expect(addJsExtensionToImports(input)).toBe(input);
125
+ });
126
+
127
+ it("does not modify import ending with .json", () => {
128
+ const input = 'import data from "./data.json";';
129
+ expect(addJsExtensionToImports(input)).toBe(input);
130
+ });
131
+
132
+ it("does not modify import ending with .css", () => {
133
+ const input = 'import "./styles.css";';
134
+ expect(addJsExtensionToImports(input)).toBe(input);
135
+ });
136
+
137
+ it("does not modify bare specifier", () => {
138
+ const input = 'import { z } from "lodash-es";';
139
+ expect(addJsExtensionToImports(input)).toBe(input);
140
+ });
141
+
142
+ it("does not modify scoped package specifier", () => {
143
+ const input = 'import { a } from "@simplysm/core-common";';
144
+ expect(addJsExtensionToImports(input)).toBe(input);
145
+ });
146
+
147
+ it("handles multiple imports in same text", () => {
148
+ const input = [
149
+ 'import { a } from "./foo";',
150
+ 'import { b } from "lodash";',
151
+ 'import { c } from "../bar";',
152
+ ].join("\n");
153
+ const expected = [
154
+ 'import { a } from "./foo.js";',
155
+ 'import { b } from "lodash";',
156
+ 'import { c } from "../bar.js";',
157
+ ].join("\n");
158
+ expect(addJsExtensionToImports(input)).toBe(expected);
159
+ });
160
+
161
+ it("handles re-export from relative path", () => {
162
+ const input = 'export { x } from "./module";';
163
+ expect(addJsExtensionToImports(input)).toBe('export { x } from "./module.js";');
164
+ });
165
+ });
@@ -0,0 +1,104 @@
1
+ import { describe, it, expect, vi, beforeEach } from "vitest";
2
+ import { formatBuildMessages, printErrors, printServers } from "../../src/utils/output-utils";
3
+ import type { BuildResult } from "../../src/infra/ResultCollector";
4
+
5
+ vi.mock("consola", () => ({
6
+ consola: {
7
+ error: vi.fn(),
8
+ info: vi.fn(),
9
+ },
10
+ }));
11
+
12
+
13
+ const { consola } = await import("consola");
14
+
15
+ describe("formatBuildMessages", () => {
16
+ it("formats name, label, and messages into indented lines", () => {
17
+ const result = formatBuildMessages("core", "node", ["error in file.ts"]);
18
+ expect(result).toBe("core (node)\n → error in file.ts");
19
+ });
20
+
21
+ it("splits multiline messages into separate indented lines", () => {
22
+ const result = formatBuildMessages("core", "node", ["line1\nline2"]);
23
+ expect(result).toContain("→ line1");
24
+ expect(result).toContain("→ line2");
25
+ });
26
+
27
+ it("handles multiple messages", () => {
28
+ const result = formatBuildMessages("core", "dts", ["err1", "err2"]);
29
+ expect(result).toContain("core (dts)");
30
+ expect(result).toContain("→ err1");
31
+ expect(result).toContain("→ err2");
32
+ });
33
+ });
34
+
35
+ describe("printErrors", () => {
36
+ beforeEach(() => {
37
+ vi.clearAllMocks();
38
+ });
39
+
40
+ it("prints error results with message", () => {
41
+ const results = new Map<string, BuildResult>([
42
+ ["core:build", { name: "core", target: "node", type: "build", status: "error", message: "failed" }],
43
+ ]);
44
+ printErrors(results);
45
+ expect(consola.error).toHaveBeenCalledOnce();
46
+ });
47
+
48
+ it("prints error results without message", () => {
49
+ const results = new Map<string, BuildResult>([
50
+ ["core:build", { name: "core", target: "node", type: "build", status: "error" }],
51
+ ]);
52
+ printErrors(results);
53
+ expect(consola.error).toHaveBeenCalledOnce();
54
+ });
55
+
56
+ it("uses 'dts' as label for dts type errors", () => {
57
+ const results = new Map<string, BuildResult>([
58
+ ["core:dts", { name: "core", target: "node", type: "dts", status: "error", message: "type error" }],
59
+ ]);
60
+ printErrors(results);
61
+ const callArg = vi.mocked(consola.error).mock.calls[0][0] as string;
62
+ expect(callArg).toContain("dts");
63
+ });
64
+
65
+ it("skips non-error results", () => {
66
+ const results = new Map<string, BuildResult>([
67
+ ["core:build", { name: "core", target: "node", type: "build", status: "success" }],
68
+ ]);
69
+ printErrors(results);
70
+ expect(consola.error).not.toHaveBeenCalled();
71
+ });
72
+ });
73
+
74
+ describe("printServers", () => {
75
+ beforeEach(() => {
76
+ vi.clearAllMocks();
77
+ vi.spyOn(process.stdout, "write").mockImplementation(() => true);
78
+ });
79
+
80
+ it("prints server URL with port", () => {
81
+ const results = new Map<string, BuildResult>([
82
+ ["app:server", { name: "app", target: "server", type: "server", status: "running", port: 3000 }],
83
+ ]);
84
+ printServers(results);
85
+ expect(consola.info).toHaveBeenCalledWith(expect.stringContaining("http://localhost:3000/"));
86
+ });
87
+
88
+ it("prints client URLs when server has connected clients", () => {
89
+ const results = new Map<string, BuildResult>([
90
+ ["app:server", { name: "app", target: "server", type: "server", status: "running", port: 3000 }],
91
+ ]);
92
+ const clientsMap = new Map([["app", ["client-a"]]]);
93
+ printServers(results, clientsMap);
94
+ expect(consola.info).toHaveBeenCalledWith(expect.stringContaining("http://localhost:3000/client-a/"));
95
+ });
96
+
97
+ it("does not print when no running servers", () => {
98
+ const results = new Map<string, BuildResult>([
99
+ ["core:build", { name: "core", target: "node", type: "build", status: "success" }],
100
+ ]);
101
+ printServers(results);
102
+ expect(consola.info).not.toHaveBeenCalled();
103
+ });
104
+ });