@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,566 @@
1
+ import { describe, it, expect, vi, beforeEach } from "vitest";
2
+ import path from "path";
3
+
4
+ //#region Mocks
5
+
6
+ let workerFns: Record<string, (...args: any[]) => any>;
7
+ let mockSend: ReturnType<typeof vi.fn>;
8
+
9
+ // Guard mock state
10
+ let guardCalled = false;
11
+
12
+ // fs mock tracking
13
+ const writtenFiles = new Map<string, string>();
14
+ const mockWriteFileSync = vi.fn((filePath: string, content: string) => {
15
+ writtenFiles.set(filePath, content);
16
+ });
17
+ const mockReadFileSync = vi.fn();
18
+ const mockExistsSync = vi.fn();
19
+
20
+ // FsWatcher mock
21
+ const mockOnChange = vi.fn();
22
+ const mockWatcherClose = vi.fn();
23
+
24
+ // esbuild context mock
25
+ const mockRebuild = vi.fn();
26
+ const mockDispose = vi.fn();
27
+ let mockMetafileInputs: Record<string, unknown> = {};
28
+
29
+ // tsc build mock
30
+ const mockRunTscPackageBuild = vi.fn(() => ({
31
+ success: true,
32
+ errors: undefined,
33
+ diagnostics: [],
34
+ errorCount: 0,
35
+ warningCount: 0,
36
+ }));
37
+
38
+ vi.mock("@simplysm/core-node", () => ({
39
+ createWorker: vi.fn((fns: Record<string, Function>) => {
40
+ workerFns = fns as any;
41
+ mockSend = vi.fn();
42
+ return { send: mockSend };
43
+ }),
44
+ FsWatcher: {
45
+ watch: vi.fn(() => Promise.resolve({
46
+ onChange: mockOnChange,
47
+ close: mockWatcherClose,
48
+ })),
49
+ },
50
+ pathx: {
51
+ norm: vi.fn((...args: string[]) => path.resolve(...args).replace(/\\/g, "/")),
52
+ },
53
+ }));
54
+
55
+ vi.mock("@simplysm/core-common", () => ({
56
+ err: { message: (e: any) => e?.message ?? String(e) },
57
+ }));
58
+
59
+ vi.mock("consola", () => ({
60
+ consola: {
61
+ withTag: vi.fn(() => ({
62
+ debug: vi.fn(),
63
+ warn: vi.fn(),
64
+ })),
65
+ },
66
+ }));
67
+
68
+ vi.mock("esbuild", () => ({
69
+ default: {
70
+ context: vi.fn(() => {
71
+ mockRebuild.mockResolvedValue({
72
+ errors: [],
73
+ warnings: [],
74
+ outputFiles: [],
75
+ metafile: { inputs: mockMetafileInputs, outputs: {} },
76
+ });
77
+ return Promise.resolve({ rebuild: mockRebuild, dispose: mockDispose });
78
+ }),
79
+ build: vi.fn(() => Promise.resolve({
80
+ errors: [],
81
+ warnings: [],
82
+ outputFiles: [{ path: "/workspace/packages/my-server/dist/main.js", text: "export {}" }],
83
+ })),
84
+ },
85
+ }));
86
+
87
+ vi.mock("fs", () => ({
88
+ default: {
89
+ readFileSync: (...args: unknown[]) => mockReadFileSync(...(args as [string])),
90
+ writeFileSync: (...args: unknown[]) => mockWriteFileSync(...(args as [string, string])),
91
+ existsSync: (...args: unknown[]) => mockExistsSync(...(args as [string])),
92
+ },
93
+ readFileSync: (...args: unknown[]) => mockReadFileSync(...(args as [string])),
94
+ writeFileSync: (...args: unknown[]) => mockWriteFileSync(...(args as [string, string])),
95
+ existsSync: (...args: unknown[]) => mockExistsSync(...(args as [string])),
96
+ }));
97
+
98
+ vi.mock("execa", () => ({
99
+ execaSync: vi.fn(() => ({ stdout: "v20.11.0" })),
100
+ }));
101
+
102
+ vi.mock("../../src/utils/tsconfig", () => ({
103
+ parseTsconfig: vi.fn(() => ({
104
+ options: { target: 1, module: 99 },
105
+ fileNames: ["/workspace/packages/my-server/src/main.ts"],
106
+ errors: [],
107
+ })),
108
+ getPackageSourceFiles: vi.fn(() => ["/workspace/packages/my-server/src/main.ts"]),
109
+ }));
110
+
111
+ vi.mock("../../src/utils/esbuild-config", () => ({
112
+ createServerEsbuildOptions: vi.fn(() => ({ plugins: [] })),
113
+ collectUninstalledOptionalPeerDeps: vi.fn(() => []),
114
+ collectNativeModuleExternals: vi.fn(() => []),
115
+ writeChangedOutputFiles: vi.fn(() => Promise.resolve(true)),
116
+ }));
117
+
118
+ vi.mock("../../src/utils/tsc-build", () => ({
119
+ runTscPackageBuild: mockRunTscPackageBuild,
120
+ }));
121
+
122
+ vi.mock("../../src/utils/worker-utils", () => ({
123
+ registerCleanupHandlers: vi.fn(),
124
+ createOnceGuard: vi.fn(() => () => {
125
+ if (guardCalled) throw new Error("startWatch has already been called");
126
+ guardCalled = true;
127
+ }),
128
+ applyDebugLevel: vi.fn(),
129
+ }));
130
+
131
+ vi.mock("../../src/utils/package-utils", () => ({
132
+ collectDeps: vi.fn(() => ({ workspaceDeps: [], replaceDeps: [] })),
133
+ }));
134
+
135
+ vi.mock("../../src/utils/copy-public", () => ({
136
+ copyPublicFiles: vi.fn(() => Promise.resolve()),
137
+ watchPublicFiles: vi.fn(() => Promise.resolve(undefined)),
138
+ }));
139
+
140
+ //#endregion
141
+
142
+ // Import triggers createWorker, capturing the functions
143
+ await import("../../src/workers/server-build.worker");
144
+
145
+ const esbuild = (await import("esbuild")).default;
146
+ const { FsWatcher } = await import("@simplysm/core-node");
147
+ const { copyPublicFiles, watchPublicFiles } = await import("../../src/utils/copy-public");
148
+ const { collectUninstalledOptionalPeerDeps, collectNativeModuleExternals } =
149
+ await import("../../src/utils/esbuild-config");
150
+
151
+ describe("server-build.worker build()", () => {
152
+ const baseBuildInfo = {
153
+ name: "my-server",
154
+ cwd: "/workspace",
155
+ pkgDir: "/workspace/packages/my-server",
156
+ output: { js: true, dts: false },
157
+ };
158
+
159
+ beforeEach(() => {
160
+ writtenFiles.clear();
161
+ mockWriteFileSync.mockClear();
162
+ mockReadFileSync.mockReset();
163
+ mockExistsSync.mockReset();
164
+ vi.mocked(esbuild.build).mockClear();
165
+ vi.mocked(copyPublicFiles).mockClear();
166
+ vi.mocked(collectUninstalledOptionalPeerDeps).mockReturnValue([]);
167
+ vi.mocked(collectNativeModuleExternals).mockReturnValue([]);
168
+ mockRunTscPackageBuild.mockReturnValue({
169
+ success: true,
170
+ errors: undefined,
171
+ diagnostics: [],
172
+ errorCount: 0,
173
+ warningCount: 0,
174
+ });
175
+
176
+ mockReadFileSync.mockImplementation((filePath: string) => {
177
+ if (String(filePath).endsWith("package.json")) {
178
+ return JSON.stringify({
179
+ name: "@simplysm/my-server",
180
+ version: "1.0.0",
181
+ type: "module",
182
+ dependencies: {},
183
+ });
184
+ }
185
+ return "";
186
+ });
187
+ });
188
+
189
+ // Acceptance: esbuild + typecheck parallel execution
190
+ it("runs esbuild and tsc in parallel for server build", async () => {
191
+ const result = await workerFns["build"](baseBuildInfo);
192
+
193
+ expect(result.js.success).toBe(true);
194
+ expect(result.dts.success).toBe(true);
195
+ expect(result.mainJsPath).toBe(path.join(baseBuildInfo.pkgDir, "dist", "main.js"));
196
+
197
+ // esbuild was called
198
+ expect(esbuild.build).toHaveBeenCalled();
199
+
200
+ // tsc was called with emit=false (server doesn't emit .d.ts)
201
+ expect(mockRunTscPackageBuild).toHaveBeenCalledWith(
202
+ expect.objectContaining({ output: { js: false, dts: false } }),
203
+ );
204
+ });
205
+
206
+ // Acceptance: type error detected
207
+ it("reports typecheck error in dts field", async () => {
208
+ mockRunTscPackageBuild.mockReturnValueOnce({
209
+ success: false,
210
+ errors: ["TS2345: type error"] as any,
211
+ diagnostics: [{ code: 2345, category: 1 }] as any,
212
+ errorCount: 1,
213
+ warningCount: 0,
214
+ });
215
+
216
+ const result = await workerFns["build"](baseBuildInfo);
217
+
218
+ expect(result.js.success).toBe(true);
219
+ expect(result.dts.success).toBe(false);
220
+ expect(result.dts.errors).toContain("TS2345: type error");
221
+ expect(result.dts.diagnostics).toHaveLength(1);
222
+ });
223
+
224
+ // Acceptance: esbuild error detected
225
+ it("reports esbuild error in js field", async () => {
226
+ vi.mocked(esbuild.build).mockResolvedValueOnce({
227
+ errors: [{ text: "syntax error" }],
228
+ warnings: [],
229
+ outputFiles: [],
230
+ } as any);
231
+
232
+ const result = await workerFns["build"](baseBuildInfo);
233
+
234
+ expect(result.js.success).toBe(false);
235
+ expect(result.js.errors).toContain("syntax error");
236
+ expect(result.dts.success).toBe(true);
237
+ });
238
+
239
+ // Unit: .d.ts files are NOT generated (emit=false)
240
+ it("never emits .d.ts files for server builds", async () => {
241
+ await workerFns["build"](baseBuildInfo);
242
+
243
+ expect(mockRunTscPackageBuild).toHaveBeenCalledWith(
244
+ expect.objectContaining({ output: { js: false, dts: false } }),
245
+ );
246
+ });
247
+
248
+ // Unit: esbuild exception handling
249
+ it("handles esbuild exception gracefully", async () => {
250
+ vi.mocked(esbuild.build).mockRejectedValueOnce(new Error("esbuild crash"));
251
+
252
+ const result = await workerFns["build"](baseBuildInfo);
253
+
254
+ expect(result.js.success).toBe(false);
255
+ expect(result.js.errors).toContain("esbuild crash");
256
+ });
257
+
258
+ // Unit: tsconfig parsed and passed to tsc
259
+ it("parses tsconfig and passes parsedConfig to tsc", async () => {
260
+ const { parseTsconfig } = await import("../../src/utils/tsconfig");
261
+ vi.mocked(parseTsconfig).mockClear();
262
+
263
+ await workerFns["build"](baseBuildInfo);
264
+
265
+ expect(parseTsconfig).toHaveBeenCalledTimes(1);
266
+ expect(mockRunTscPackageBuild).toHaveBeenCalledWith(
267
+ expect.objectContaining({ parsedConfig: expect.any(Object) }),
268
+ );
269
+ });
270
+
271
+ // --- Production artifacts (from existing server.worker tests) ---
272
+
273
+ it("writes .config.json with configs data", async () => {
274
+ await workerFns["build"]({
275
+ ...baseBuildInfo,
276
+ configs: { db: { host: "localhost", port: 5432 } },
277
+ });
278
+
279
+ const configPath = path.join(baseBuildInfo.pkgDir, "dist", ".config.json");
280
+ expect(writtenFiles.has(configPath)).toBe(true);
281
+ expect(JSON.parse(writtenFiles.get(configPath)!)).toEqual({ db: { host: "localhost", port: 5432 } });
282
+ });
283
+
284
+ it("generates dist/package.json with externals as dependencies", async () => {
285
+ vi.mocked(collectNativeModuleExternals).mockReturnValue(["bcrypt"]);
286
+
287
+ await workerFns["build"]({
288
+ ...baseBuildInfo,
289
+ externals: ["some-pkg"],
290
+ });
291
+
292
+ const pkgJsonPath = path.join(baseBuildInfo.pkgDir, "dist", "package.json");
293
+ const pkg = JSON.parse(writtenFiles.get(pkgJsonPath)!);
294
+ expect(pkg.name).toBe("@simplysm/my-server");
295
+ expect(pkg.dependencies["bcrypt"]).toBe("*");
296
+ expect(pkg.dependencies["some-pkg"]).toBe("*");
297
+ });
298
+
299
+ it("generates dist/openssl.cnf with legacy provider config", async () => {
300
+ await workerFns["build"](baseBuildInfo);
301
+
302
+ const opensslPath = path.join(baseBuildInfo.pkgDir, "dist", "openssl.cnf");
303
+ expect(writtenFiles.has(opensslPath)).toBe(true);
304
+ expect(writtenFiles.get(opensslPath)!).toContain("[legacy_sect]");
305
+ });
306
+
307
+ it("generates dist/pm2.config.cjs when pm2 option is provided", async () => {
308
+ await workerFns["build"]({
309
+ ...baseBuildInfo,
310
+ pm2: { name: "my-app", ignoreWatchPaths: ["logs"] },
311
+ });
312
+
313
+ const pm2Path = path.join(baseBuildInfo.pkgDir, "dist", "pm2.config.cjs");
314
+ expect(writtenFiles.has(pm2Path)).toBe(true);
315
+ expect(writtenFiles.get(pm2Path)!).toContain('"my-app"');
316
+ });
317
+
318
+ it("generates dist/mise.toml when packageManager=mise", async () => {
319
+ mockExistsSync.mockImplementation((filePath: string) =>
320
+ String(filePath).endsWith("mise.toml"),
321
+ );
322
+ mockReadFileSync.mockImplementation((filePath: string) => {
323
+ if (String(filePath).endsWith("mise.toml")) return '[tools]\nnode = "22.5.0"';
324
+ return JSON.stringify({ name: "@simplysm/my-server", version: "1.0.0", type: "module" });
325
+ });
326
+
327
+ await workerFns["build"]({
328
+ ...baseBuildInfo,
329
+ packageManager: "mise",
330
+ });
331
+
332
+ const misePath = path.join(baseBuildInfo.pkgDir, "dist", "mise.toml");
333
+ expect(writtenFiles.get(misePath)).toContain('node = "22.5.0"');
334
+ });
335
+
336
+ it("adds volta field to dist/package.json when packageManager=volta", async () => {
337
+ await workerFns["build"]({
338
+ ...baseBuildInfo,
339
+ packageManager: "volta",
340
+ });
341
+
342
+ const pkgJsonPath = path.join(baseBuildInfo.pkgDir, "dist", "package.json");
343
+ const pkg = JSON.parse(writtenFiles.get(pkgJsonPath)!);
344
+ expect(pkg.volta).toBeDefined();
345
+ expect(pkg.volta.node).toBe("v20.11.0");
346
+ });
347
+
348
+ it("calls copyPublicFiles with includeDev=false for production build", async () => {
349
+ await workerFns["build"](baseBuildInfo);
350
+ expect(copyPublicFiles).toHaveBeenCalledWith(baseBuildInfo.pkgDir, false);
351
+ });
352
+
353
+ it("collects externals from three sources", async () => {
354
+ vi.mocked(collectUninstalledOptionalPeerDeps).mockReturnValue(["opt-dep"]);
355
+ vi.mocked(collectNativeModuleExternals).mockReturnValue(["native-mod"]);
356
+
357
+ await workerFns["build"]({
358
+ ...baseBuildInfo,
359
+ externals: ["manual-ext"],
360
+ });
361
+
362
+ const pkgJsonPath = path.join(baseBuildInfo.pkgDir, "dist", "package.json");
363
+ const pkg = JSON.parse(writtenFiles.get(pkgJsonPath)!);
364
+ expect(pkg.dependencies["opt-dep"]).toBe("*");
365
+ expect(pkg.dependencies["native-mod"]).toBe("*");
366
+ expect(pkg.dependencies["manual-ext"]).toBe("*");
367
+ });
368
+ });
369
+
370
+ describe("server-build.worker startWatch()", () => {
371
+ const watchInfo = {
372
+ name: "my-server",
373
+ cwd: "/workspace",
374
+ pkgDir: "/workspace/packages/my-server",
375
+ output: { js: true, dts: false },
376
+ };
377
+
378
+ beforeEach(() => {
379
+ guardCalled = false;
380
+ mockMetafileInputs = {};
381
+ writtenFiles.clear();
382
+ mockWriteFileSync.mockClear();
383
+ mockRebuild.mockClear();
384
+ mockDispose.mockClear();
385
+ mockOnChange.mockClear();
386
+ mockWatcherClose.mockClear();
387
+ mockSend.mockClear();
388
+ vi.mocked(esbuild.context).mockClear();
389
+ vi.mocked(FsWatcher.watch).mockClear();
390
+ vi.mocked(watchPublicFiles).mockClear();
391
+ mockRunTscPackageBuild.mockReturnValue({
392
+ success: true,
393
+ errors: undefined,
394
+ diagnostics: [],
395
+ errorCount: 0,
396
+ warningCount: 0,
397
+ });
398
+
399
+ mockReadFileSync.mockImplementation((filePath: string) => {
400
+ if (String(filePath).endsWith("package.json")) {
401
+ return JSON.stringify({
402
+ name: "@simplysm/my-server",
403
+ version: "1.0.0",
404
+ type: "module",
405
+ });
406
+ }
407
+ return "";
408
+ });
409
+ });
410
+
411
+ // Acceptance: initial build with typecheck
412
+ it("sends build event with js+dts results after initial build", async () => {
413
+ await workerFns["startWatch"](watchInfo);
414
+
415
+ expect(mockSend).toHaveBeenCalledWith("build", expect.objectContaining({
416
+ js: expect.objectContaining({ success: true }),
417
+ dts: expect.objectContaining({ success: true }),
418
+ mainJsPath: path.join(watchInfo.pkgDir, "dist", "main.js"),
419
+ }));
420
+ });
421
+
422
+ // Acceptance: typecheck runs on rebuild
423
+ it("runs tsc on file change rebuild", async () => {
424
+ await workerFns["startWatch"](watchInfo);
425
+
426
+ const onChangeHandler = mockOnChange.mock.calls[0][1] as (
427
+ changes: Array<{ event: string; path: string }>,
428
+ ) => Promise<void>;
429
+
430
+ mockRunTscPackageBuild.mockClear();
431
+ await onChangeHandler([{ event: "add", path: "/workspace/packages/my-server/src/new.ts" }]);
432
+
433
+ expect(mockRunTscPackageBuild).toHaveBeenCalled();
434
+ });
435
+
436
+ // Acceptance: FsWatcher + dependency tracking
437
+ it("creates esbuild context and starts FsWatcher", async () => {
438
+ await workerFns["startWatch"](watchInfo);
439
+
440
+ expect(esbuild.context).toHaveBeenCalled();
441
+ expect(FsWatcher.watch).toHaveBeenCalled();
442
+ expect(mockOnChange).toHaveBeenCalledWith({ delay: 300 }, expect.any(Function));
443
+ });
444
+
445
+ // Acceptance: workspace dependency source change triggers rebuild
446
+ it("includes workspace dependency paths in FsWatcher", async () => {
447
+ const { collectDeps } = await import("../../src/utils/package-utils");
448
+ vi.mocked(collectDeps).mockReturnValue({
449
+ workspaceDeps: ["core-common"],
450
+ replaceDeps: [],
451
+ } as any);
452
+
453
+ await workerFns["startWatch"](watchInfo);
454
+
455
+ const watchPaths = vi.mocked(FsWatcher.watch).mock.calls[0][0];
456
+ expect(watchPaths.some((p) => p.includes("core-common"))).toBe(true);
457
+ });
458
+
459
+ // Acceptance: replaceDeps dist change triggers rebuild
460
+ it("includes replaceDeps dist paths in FsWatcher", async () => {
461
+ const { collectDeps } = await import("../../src/utils/package-utils");
462
+ vi.mocked(collectDeps).mockReturnValue({
463
+ workspaceDeps: [],
464
+ replaceDeps: ["@other/lib"],
465
+ } as any);
466
+
467
+ await workerFns["startWatch"]({
468
+ ...watchInfo,
469
+ replaceDeps: { "@other/lib": "/external/lib" },
470
+ });
471
+
472
+ const watchPaths = vi.mocked(FsWatcher.watch).mock.calls[0][0];
473
+ expect(watchPaths.some((p) => p.includes("@other") && p.includes("dist"))).toBe(true);
474
+ });
475
+
476
+ // Acceptance: metafile-based filtering
477
+ it("skips rebuild when changed file is not in metafile.inputs", async () => {
478
+ mockMetafileInputs = { "packages/my-server/src/main.ts": {} };
479
+
480
+ await workerFns["startWatch"](watchInfo);
481
+
482
+ const onChangeHandler = mockOnChange.mock.calls[0][1] as (
483
+ changes: Array<{ event: string; path: string }>,
484
+ ) => Promise<void>;
485
+
486
+ mockRebuild.mockClear();
487
+ mockSend.mockClear();
488
+ const absPath = path.resolve("/workspace", "packages/my-server/src/unrelated.ts").replace(/\\/g, "/");
489
+ await onChangeHandler([{ event: "change", path: absPath }]);
490
+
491
+ expect(mockRebuild).not.toHaveBeenCalled();
492
+ // buildStart must NOT be sent when rebuild is skipped (LOGIC-001 fix)
493
+ expect(mockSend).not.toHaveBeenCalledWith("buildStart", expect.anything());
494
+ });
495
+
496
+ // Acceptance: watch mode doesn't generate production artifacts
497
+ it("writes .config.json but not production files in watch mode", async () => {
498
+ await workerFns["startWatch"]({
499
+ ...watchInfo,
500
+ configs: { key: "value" },
501
+ });
502
+
503
+ const configPath = path.join(watchInfo.pkgDir, "dist", ".config.json");
504
+ expect(writtenFiles.has(configPath)).toBe(true);
505
+
506
+ // Production files should NOT be generated
507
+ const pkgJsonPath = path.join(watchInfo.pkgDir, "dist", "package.json");
508
+ expect(writtenFiles.has(pkgJsonPath)).toBe(false);
509
+ });
510
+
511
+ // Unit: file add recreates context
512
+ it("recreates context on file add", async () => {
513
+ await workerFns["startWatch"](watchInfo);
514
+
515
+ const onChangeHandler = mockOnChange.mock.calls[0][1] as (
516
+ changes: Array<{ event: string; path: string }>,
517
+ ) => Promise<void>;
518
+
519
+ vi.mocked(esbuild.context).mockClear();
520
+ await onChangeHandler([{ event: "add", path: "/workspace/packages/my-server/src/new.ts" }]);
521
+
522
+ expect(mockDispose).toHaveBeenCalled();
523
+ expect(esbuild.context).toHaveBeenCalled();
524
+ });
525
+
526
+ // Unit: public files watched in dev mode
527
+ it("calls watchPublicFiles with includeDev=true", async () => {
528
+ await workerFns["startWatch"](watchInfo);
529
+ expect(watchPublicFiles).toHaveBeenCalledWith(watchInfo.pkgDir, true);
530
+ });
531
+
532
+ // Unit: guard prevents duplicate startWatch
533
+ it("prevents duplicate startWatch calls", async () => {
534
+ await workerFns["startWatch"](watchInfo);
535
+ await expect(workerFns["startWatch"](watchInfo)).rejects.toThrow("already been called");
536
+ });
537
+ });
538
+
539
+ describe("server-build.worker stopWatch()", () => {
540
+ beforeEach(() => {
541
+ guardCalled = false;
542
+ mockDispose.mockClear();
543
+ mockWatcherClose.mockClear();
544
+ mockRunTscPackageBuild.mockReturnValue({
545
+ success: true,
546
+ errors: undefined,
547
+ diagnostics: [],
548
+ errorCount: 0,
549
+ warningCount: 0,
550
+ });
551
+ mockReadFileSync.mockImplementation(() => JSON.stringify({ name: "x", version: "1.0.0", type: "module" }));
552
+ });
553
+
554
+ it("cleans up esbuild context and FsWatcher", async () => {
555
+ await workerFns["startWatch"]({
556
+ name: "my-server",
557
+ cwd: "/workspace",
558
+ pkgDir: "/workspace/packages/my-server",
559
+ output: { js: true, dts: false },
560
+ });
561
+ await workerFns["stopWatch"]();
562
+
563
+ expect(mockDispose).toHaveBeenCalled();
564
+ expect(mockWatcherClose).toHaveBeenCalled();
565
+ });
566
+ });