@simplysm/sd-cli 14.0.7 → 14.0.9

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 (265) hide show
  1. package/dist/angular/client-transform-stylesheet.d.ts.map +1 -1
  2. package/dist/angular/client-transform-stylesheet.js.map +1 -1
  3. package/dist/angular/vite-angular-plugin.d.ts.map +1 -1
  4. package/dist/angular/vite-angular-plugin.js +15 -8
  5. package/dist/angular/vite-angular-plugin.js.map +1 -1
  6. package/dist/angular/vite-postcss-inline-plugin.d.ts.map +1 -1
  7. package/dist/angular/vite-postcss-inline-plugin.js.map +1 -1
  8. package/dist/capacitor/capacitor.d.ts +1 -1
  9. package/dist/capacitor/capacitor.d.ts.map +1 -1
  10. package/dist/capacitor/capacitor.js +43 -44
  11. package/dist/capacitor/capacitor.js.map +1 -1
  12. package/dist/commands/build.d.ts.map +1 -1
  13. package/dist/commands/build.js.map +1 -1
  14. package/dist/commands/check.d.ts.map +1 -1
  15. package/dist/commands/check.js +2 -2
  16. package/dist/commands/check.js.map +1 -1
  17. package/dist/commands/dev.d.ts.map +1 -1
  18. package/dist/commands/dev.js.map +1 -1
  19. package/dist/commands/lint.d.ts.map +1 -1
  20. package/dist/commands/lint.js.map +1 -1
  21. package/dist/commands/publish.d.ts.map +1 -1
  22. package/dist/commands/publish.js +12 -13
  23. package/dist/commands/publish.js.map +1 -1
  24. package/dist/commands/replace-deps.d.ts.map +1 -1
  25. package/dist/commands/replace-deps.js.map +1 -1
  26. package/dist/commands/typecheck.d.ts.map +1 -1
  27. package/dist/commands/typecheck.js +12 -12
  28. package/dist/commands/typecheck.js.map +1 -1
  29. package/dist/commands/watch.d.ts.map +1 -1
  30. package/dist/commands/watch.js.map +1 -1
  31. package/dist/electron/electron.d.ts.map +1 -1
  32. package/dist/electron/electron.js +42 -37
  33. package/dist/electron/electron.js.map +1 -1
  34. package/dist/engines/BaseEngine.d.ts +1 -5
  35. package/dist/engines/BaseEngine.d.ts.map +1 -1
  36. package/dist/engines/BaseEngine.js +7 -16
  37. package/dist/engines/BaseEngine.js.map +1 -1
  38. package/dist/engines/NgtscEngine.d.ts.map +1 -1
  39. package/dist/engines/NgtscEngine.js +10 -11
  40. package/dist/engines/NgtscEngine.js.map +1 -1
  41. package/dist/engines/ServerEsbuildEngine.d.ts.map +1 -1
  42. package/dist/engines/ServerEsbuildEngine.js +10 -11
  43. package/dist/engines/ServerEsbuildEngine.js.map +1 -1
  44. package/dist/engines/TscEngine.d.ts.map +1 -1
  45. package/dist/engines/TscEngine.js +10 -11
  46. package/dist/engines/TscEngine.js.map +1 -1
  47. package/dist/engines/ViteEngine.d.ts.map +1 -1
  48. package/dist/engines/ViteEngine.js +3 -13
  49. package/dist/engines/ViteEngine.js.map +1 -1
  50. package/dist/engines/index.d.ts.map +1 -1
  51. package/dist/engines/index.js.map +1 -1
  52. package/dist/engines/types.d.ts +3 -6
  53. package/dist/engines/types.d.ts.map +1 -1
  54. package/dist/engines/types.js.map +1 -1
  55. package/dist/index.d.ts.map +1 -1
  56. package/dist/index.js.map +1 -1
  57. package/dist/infra/ResultCollector.d.ts +1 -1
  58. package/dist/infra/ResultCollector.d.ts.map +1 -1
  59. package/dist/infra/ResultCollector.js.map +1 -1
  60. package/dist/infra/SignalHandler.d.ts.map +1 -1
  61. package/dist/infra/SignalHandler.js.map +1 -1
  62. package/dist/infra/WorkerManager.d.ts.map +1 -1
  63. package/dist/infra/WorkerManager.js.map +1 -1
  64. package/dist/orchestrators/BuildOrchestrator.d.ts.map +1 -1
  65. package/dist/orchestrators/BuildOrchestrator.js +30 -61
  66. package/dist/orchestrators/BuildOrchestrator.js.map +1 -1
  67. package/dist/orchestrators/DevWatchOrchestrator.d.ts +2 -0
  68. package/dist/orchestrators/DevWatchOrchestrator.d.ts.map +1 -1
  69. package/dist/orchestrators/DevWatchOrchestrator.js +40 -44
  70. package/dist/orchestrators/DevWatchOrchestrator.js.map +1 -1
  71. package/dist/sd-cli-entry.d.ts.map +1 -1
  72. package/dist/sd-cli-entry.js +2 -13
  73. package/dist/sd-cli-entry.js.map +1 -1
  74. package/dist/sd-cli.d.ts.map +1 -1
  75. package/dist/sd-cli.js +5 -5
  76. package/dist/sd-cli.js.map +1 -1
  77. package/dist/sd-config.types.d.ts.map +1 -1
  78. package/dist/sd-config.types.js.map +1 -1
  79. package/dist/utils/SdCliReporter.d.ts +18 -0
  80. package/dist/utils/SdCliReporter.d.ts.map +1 -0
  81. package/dist/utils/SdCliReporter.js +144 -0
  82. package/dist/utils/SdCliReporter.js.map +1 -0
  83. package/dist/utils/angular-build.d.ts.map +1 -1
  84. package/dist/utils/angular-build.js.map +1 -1
  85. package/dist/utils/angular-compiler.d.ts.map +1 -1
  86. package/dist/utils/angular-compiler.js +11 -4
  87. package/dist/utils/angular-compiler.js.map +1 -1
  88. package/dist/utils/build-env.d.ts.map +1 -1
  89. package/dist/utils/build-env.js +2 -1
  90. package/dist/utils/build-env.js.map +1 -1
  91. package/dist/utils/concurrency.d.ts.map +1 -1
  92. package/dist/utils/concurrency.js.map +1 -1
  93. package/dist/utils/copy-public.d.ts.map +1 -1
  94. package/dist/utils/copy-public.js +21 -21
  95. package/dist/utils/copy-public.js.map +1 -1
  96. package/dist/utils/copy-src.d.ts.map +1 -1
  97. package/dist/utils/copy-src.js +12 -12
  98. package/dist/utils/copy-src.js.map +1 -1
  99. package/dist/utils/diagnostic-utils.d.ts.map +1 -1
  100. package/dist/utils/diagnostic-utils.js +3 -2
  101. package/dist/utils/diagnostic-utils.js.map +1 -1
  102. package/dist/utils/engine-stop.d.ts.map +1 -1
  103. package/dist/utils/engine-stop.js.map +1 -1
  104. package/dist/utils/esbuild-config.d.ts.map +1 -1
  105. package/dist/utils/esbuild-config.js +2 -0
  106. package/dist/utils/esbuild-config.js.map +1 -1
  107. package/dist/utils/generate-pwa-icons.d.ts.map +1 -1
  108. package/dist/utils/generate-pwa-icons.js.map +1 -1
  109. package/dist/utils/hmr-candidates.d.ts.map +1 -1
  110. package/dist/utils/hmr-candidates.js.map +1 -1
  111. package/dist/utils/lint-utils.d.ts.map +1 -1
  112. package/dist/utils/lint-utils.js.map +1 -1
  113. package/dist/utils/lint-with-program.d.ts.map +1 -1
  114. package/dist/utils/lint-with-program.js +7 -3
  115. package/dist/utils/lint-with-program.js.map +1 -1
  116. package/dist/utils/ngtsc-build-core.d.ts +2 -10
  117. package/dist/utils/ngtsc-build-core.d.ts.map +1 -1
  118. package/dist/utils/ngtsc-build-core.js +16 -15
  119. package/dist/utils/ngtsc-build-core.js.map +1 -1
  120. package/dist/utils/orchestrator-utils.d.ts.map +1 -1
  121. package/dist/utils/orchestrator-utils.js.map +1 -1
  122. package/dist/utils/output-path-rewriter.d.ts.map +1 -1
  123. package/dist/utils/output-path-rewriter.js +7 -7
  124. package/dist/utils/output-path-rewriter.js.map +1 -1
  125. package/dist/utils/output-utils.d.ts.map +1 -1
  126. package/dist/utils/output-utils.js +1 -1
  127. package/dist/utils/output-utils.js.map +1 -1
  128. package/dist/utils/package-utils.d.ts +4 -0
  129. package/dist/utils/package-utils.d.ts.map +1 -1
  130. package/dist/utils/package-utils.js +34 -13
  131. package/dist/utils/package-utils.js.map +1 -1
  132. package/dist/utils/rebuild-manager.d.ts +1 -1
  133. package/dist/utils/rebuild-manager.d.ts.map +1 -1
  134. package/dist/utils/rebuild-manager.js +3 -1
  135. package/dist/utils/rebuild-manager.js.map +1 -1
  136. package/dist/utils/replace-deps.d.ts.map +1 -1
  137. package/dist/utils/replace-deps.js +10 -10
  138. package/dist/utils/replace-deps.js.map +1 -1
  139. package/dist/utils/scss-compiler.d.ts.map +1 -1
  140. package/dist/utils/scss-compiler.js.map +1 -1
  141. package/dist/utils/sd-config.d.ts.map +1 -1
  142. package/dist/utils/sd-config.js +2 -3
  143. package/dist/utils/sd-config.js.map +1 -1
  144. package/dist/utils/tsc-build.d.ts +3 -1
  145. package/dist/utils/tsc-build.d.ts.map +1 -1
  146. package/dist/utils/tsc-build.js +7 -4
  147. package/dist/utils/tsc-build.js.map +1 -1
  148. package/dist/utils/tsconfig.d.ts.map +1 -1
  149. package/dist/utils/tsconfig.js.map +1 -1
  150. package/dist/utils/typecheck-non-package.d.ts.map +1 -1
  151. package/dist/utils/typecheck-non-package.js +10 -5
  152. package/dist/utils/typecheck-non-package.js.map +1 -1
  153. package/dist/utils/typecheck-serialization.d.ts.map +1 -1
  154. package/dist/utils/typecheck-serialization.js.map +1 -1
  155. package/dist/utils/vite-config.d.ts.map +1 -1
  156. package/dist/utils/vite-config.js +2 -1
  157. package/dist/utils/vite-config.js.map +1 -1
  158. package/dist/utils/vite-scope-watch-plugin.d.ts.map +1 -1
  159. package/dist/utils/vite-scope-watch-plugin.js.map +1 -1
  160. package/dist/utils/worker-events.d.ts +1 -1
  161. package/dist/utils/worker-events.d.ts.map +1 -1
  162. package/dist/utils/worker-events.js +1 -0
  163. package/dist/utils/worker-events.js.map +1 -1
  164. package/dist/utils/worker-utils.d.ts +1 -1
  165. package/dist/utils/worker-utils.d.ts.map +1 -1
  166. package/dist/utils/worker-utils.js +3 -1
  167. package/dist/utils/worker-utils.js.map +1 -1
  168. package/dist/vitest-plugin.d.ts.map +1 -1
  169. package/dist/vitest-plugin.js +2 -0
  170. package/dist/vitest-plugin.js.map +1 -1
  171. package/dist/workers/client.worker.d.ts.map +1 -1
  172. package/dist/workers/client.worker.js +4 -0
  173. package/dist/workers/client.worker.js.map +1 -1
  174. package/dist/workers/library-build.worker.d.ts +2 -10
  175. package/dist/workers/library-build.worker.d.ts.map +1 -1
  176. package/dist/workers/library-build.worker.js +38 -14
  177. package/dist/workers/library-build.worker.js.map +1 -1
  178. package/dist/workers/lint.worker.d.ts.map +1 -1
  179. package/dist/workers/lint.worker.js.map +1 -1
  180. package/dist/workers/ngtsc-build.worker.d.ts.map +1 -1
  181. package/dist/workers/ngtsc-build.worker.js +40 -14
  182. package/dist/workers/ngtsc-build.worker.js.map +1 -1
  183. package/dist/workers/server-build.worker.d.ts +2 -10
  184. package/dist/workers/server-build.worker.d.ts.map +1 -1
  185. package/dist/workers/server-build.worker.js +30 -22
  186. package/dist/workers/server-build.worker.js.map +1 -1
  187. package/dist/workers/server-runtime.worker.d.ts.map +1 -1
  188. package/dist/workers/server-runtime.worker.js.map +1 -1
  189. package/package.json +4 -5
  190. package/src/angular/vite-angular-plugin.ts +18 -9
  191. package/src/capacitor/capacitor.ts +43 -44
  192. package/src/commands/check.ts +2 -2
  193. package/src/commands/publish.ts +12 -13
  194. package/src/commands/typecheck.ts +12 -12
  195. package/src/electron/electron.ts +44 -38
  196. package/src/engines/BaseEngine.ts +8 -19
  197. package/src/engines/NgtscEngine.ts +11 -11
  198. package/src/engines/ServerEsbuildEngine.ts +11 -11
  199. package/src/engines/TscEngine.ts +11 -11
  200. package/src/engines/ViteEngine.ts +3 -14
  201. package/src/engines/types.ts +3 -6
  202. package/src/infra/ResultCollector.ts +1 -1
  203. package/src/orchestrators/BuildOrchestrator.ts +31 -62
  204. package/src/orchestrators/DevWatchOrchestrator.ts +41 -44
  205. package/src/sd-cli-entry.ts +2 -12
  206. package/src/sd-cli.ts +8 -5
  207. package/src/utils/SdCliReporter.ts +177 -0
  208. package/src/utils/angular-compiler.ts +11 -4
  209. package/src/utils/build-env.ts +2 -1
  210. package/src/utils/copy-public.ts +21 -21
  211. package/src/utils/copy-src.ts +12 -12
  212. package/src/utils/diagnostic-utils.ts +3 -2
  213. package/src/utils/esbuild-config.ts +2 -0
  214. package/src/utils/lint-with-program.ts +7 -3
  215. package/src/utils/ngtsc-build-core.ts +18 -18
  216. package/src/utils/output-path-rewriter.ts +7 -7
  217. package/src/utils/output-utils.ts +1 -1
  218. package/src/utils/package-utils.ts +37 -13
  219. package/src/utils/rebuild-manager.ts +4 -2
  220. package/src/utils/replace-deps.ts +10 -10
  221. package/src/utils/sd-config.ts +2 -3
  222. package/src/utils/tsc-build.ts +9 -4
  223. package/src/utils/typecheck-non-package.ts +10 -5
  224. package/src/utils/vite-config.ts +2 -1
  225. package/src/utils/worker-events.ts +2 -1
  226. package/src/utils/worker-utils.ts +3 -1
  227. package/src/vitest-plugin.ts +5 -0
  228. package/src/workers/client.worker.ts +4 -0
  229. package/src/workers/library-build.worker.ts +48 -18
  230. package/src/workers/ngtsc-build.worker.ts +48 -13
  231. package/src/workers/server-build.worker.ts +32 -26
  232. package/tests/angular/vite-angular-plugin-hmr-fallback.spec.ts +11 -7
  233. package/tests/angular/vite-angular-plugin-lint.spec.ts +6 -1
  234. package/tests/capacitor/capacitor-build.spec.ts +14 -7
  235. package/tests/capacitor/capacitor-icon.spec.ts +14 -7
  236. package/tests/capacitor/capacitor-init.spec.ts +13 -6
  237. package/tests/capacitor/capacitor-run.spec.ts +18 -11
  238. package/tests/capacitor/capacitor-workspace.spec.ts +13 -6
  239. package/tests/commands/check.spec.ts +5 -2
  240. package/tests/commands/publish.spec.ts +4 -4
  241. package/tests/commands/typecheck.spec.ts +20 -31
  242. package/tests/electron/electron.spec.ts +32 -23
  243. package/tests/engines/base-engine.spec.ts +15 -21
  244. package/tests/engines/engine-lint-integration.spec.ts +5 -10
  245. package/tests/engines/ngtsc-engine.spec.ts +27 -41
  246. package/tests/engines/server-esbuild-engine.spec.ts +18 -29
  247. package/tests/engines/tsc-engine.spec.ts +14 -23
  248. package/tests/engines/vite-engine.spec.ts +10 -15
  249. package/tests/infra/result-collector.spec.ts +2 -2
  250. package/tests/orchestrators/build-orchestrator.spec.ts +19 -29
  251. package/tests/orchestrators/dev-watch-orchestrator.spec.ts +110 -95
  252. package/tests/utils/copy-src.spec.ts +25 -19
  253. package/tests/utils/diagnostic-utils.spec.ts +72 -0
  254. package/tests/utils/ngtsc-build-core-angular-compiler.spec.ts +2 -3
  255. package/tests/utils/output-path-rewriter.spec.ts +7 -6
  256. package/tests/utils/output-utils.spec.ts +5 -5
  257. package/tests/utils/rebuild-manager.spec.ts +1 -1
  258. package/tests/utils/sd-config.spec.ts +4 -0
  259. package/tests/utils/tsc-build.spec.ts +23 -5
  260. package/tests/workers/library-build-worker.spec.ts +113 -20
  261. package/tests/workers/ngtsc-build-lint.spec.ts +3 -6
  262. package/tests/workers/ngtsc-build-worker.spec.ts +11 -13
  263. package/tests/workers/server-build-lint.spec.ts +4 -1
  264. package/tests/workers/server-build-worker.spec.ts +25 -25
  265. package/tests/angular/migration-cleanup.spec.ts +0 -59
@@ -48,12 +48,12 @@ vi.mock("../../src/utils/replace-deps", () => ({
48
48
  parseWorkspaceGlobs: mocks.parseWorkspaceGlobs,
49
49
  }));
50
50
 
51
- vi.mock("execa", () => ({
52
- execa: mocks.execa,
53
- }));
54
-
55
51
  vi.mock("@simplysm/core-node", () => ({
56
52
  fsx: mocks.fsx,
53
+ cpx: {
54
+ exec: mocks.execa,
55
+ execSync: vi.fn().mockReturnValue({ stdout: "", stderr: "", exitCode: 0 }),
56
+ },
57
57
  }));
58
58
 
59
59
  vi.mock("@simplysm/core-common", () => {
@@ -86,8 +86,7 @@ function createMockEngine() {
86
86
  const engine = {
87
87
  run: vi.fn().mockResolvedValue({
88
88
  success: true,
89
- js: { success: true, errors: [], warnings: [] },
90
- dts: { success: true, errors: [], warnings: [], diagnostics: [] },
89
+ build: { success: true, errors: [], warnings: [], diagnostics: [] },
91
90
 
92
91
  }),
93
92
  startWatch: vi.fn(),
@@ -161,7 +160,7 @@ describe("executeTypecheck", () => {
161
160
  }),
162
161
  expect.any(Object),
163
162
  );
164
- expect(mockEngines[0].run).toHaveBeenCalledWith({ js: false, dts: false, env: "node" });
163
+ expect(mockEngines[0].run).toHaveBeenCalledWith({ js: false, dts: false, env: "node", includeTests: true });
165
164
  });
166
165
 
167
166
  it("excludes scripts packages from typecheck", async () => {
@@ -217,8 +216,7 @@ describe("executeTypecheck", () => {
217
216
  const engine = {
218
217
  run: vi.fn().mockResolvedValue({
219
218
  success: false,
220
- js: { success: true, errors: [], warnings: [] },
221
- dts: { success: false, errors: [], warnings: [], diagnostics: [engineDiag] },
219
+ build: { success: false, errors: [], warnings: [], diagnostics: [engineDiag] },
222
220
 
223
221
  }),
224
222
  startWatch: vi.fn(),
@@ -260,8 +258,7 @@ describe("executeTypecheck", () => {
260
258
  active--;
261
259
  return {
262
260
  success: true,
263
- js: { success: true, errors: [], warnings: [] },
264
- dts: { success: true, errors: [], warnings: [], diagnostics: [] },
261
+ build: { success: true, errors: [], warnings: [], diagnostics: [] },
265
262
 
266
263
  };
267
264
  }),
@@ -341,8 +338,8 @@ describe("executeTypecheck", () => {
341
338
 
342
339
  const runCalls = mockEngines.map((e) => e.run.mock.calls[0][0]);
343
340
  expect(runCalls).toEqual([
344
- { js: false, dts: false, env: "node" },
345
- { js: false, dts: false, env: "browser" },
341
+ { js: false, dts: false, env: "node", includeTests: true },
342
+ { js: false, dts: false, env: "browser", includeTests: true },
346
343
  ]);
347
344
  });
348
345
 
@@ -352,7 +349,7 @@ describe("executeTypecheck", () => {
352
349
  await executeTypecheck({ targets: [], options: [] });
353
350
 
354
351
  expect(mocks.createBuildEngine).toHaveBeenCalledTimes(1);
355
- expect(mockEngines[0].run).toHaveBeenCalledWith({ js: false, dts: false, env: "node" });
352
+ expect(mockEngines[0].run).toHaveBeenCalledWith({ js: false, dts: false, env: "node", includeTests: true });
356
353
  });
357
354
 
358
355
  it("creates 1 task (browser) for browser target", async () => {
@@ -361,7 +358,7 @@ describe("executeTypecheck", () => {
361
358
  await executeTypecheck({ targets: [], options: [] });
362
359
 
363
360
  expect(mocks.createBuildEngine).toHaveBeenCalledTimes(1);
364
- expect(mockEngines[0].run).toHaveBeenCalledWith({ js: false, dts: false, env: "browser" });
361
+ expect(mockEngines[0].run).toHaveBeenCalledWith({ js: false, dts: false, env: "browser", includeTests: true });
365
362
  });
366
363
 
367
364
  it("creates 1 task (node) for server target", async () => {
@@ -370,7 +367,7 @@ describe("executeTypecheck", () => {
370
367
  await executeTypecheck({ targets: [], options: [] });
371
368
 
372
369
  expect(mocks.createBuildEngine).toHaveBeenCalledTimes(1);
373
- expect(mockEngines[0].run).toHaveBeenCalledWith({ js: false, dts: false, env: "node" });
370
+ expect(mockEngines[0].run).toHaveBeenCalledWith({ js: false, dts: false, env: "node", includeTests: true });
374
371
  });
375
372
 
376
373
  it("passes env to engine.run() for each task", async () => {
@@ -454,8 +451,7 @@ describe("executeTypecheck", () => {
454
451
  const engine = {
455
452
  run: vi.fn().mockResolvedValue({
456
453
  success: false,
457
- js: { success: true, errors: [], warnings: [] },
458
- dts: { success: false, errors: [], warnings: [], diagnostics: [diag] },
454
+ build: { success: false, errors: [], warnings: [], diagnostics: [diag] },
459
455
 
460
456
  }),
461
457
  startWatch: vi.fn(),
@@ -511,8 +507,7 @@ describe("executeTypecheck", () => {
511
507
  const engine = {
512
508
  run: vi.fn().mockResolvedValue({
513
509
  success: true,
514
- js: { success: true, errors: [], warnings: [] },
515
- dts: { success: true, errors: [], warnings: [], diagnostics: [] },
510
+ build: { success: true, errors: [], warnings: [], diagnostics: [] },
516
511
  lint: { success: false, errorCount: 2, warningCount: 1, formattedOutput: "lint errors from pkg" },
517
512
  }),
518
513
  startWatch: vi.fn(),
@@ -567,8 +562,7 @@ describe("executeTypecheck", () => {
567
562
  const engine = {
568
563
  run: vi.fn().mockResolvedValue({
569
564
  success: true,
570
- js: { success: true, errors: [], warnings: [] },
571
- dts: { success: true, errors: [], warnings: [], diagnostics: [] },
565
+ build: { success: true, errors: [], warnings: [], diagnostics: [] },
572
566
  lint: { success: true, errorCount: 0, warningCount: 0, formattedOutput: "" },
573
567
  }),
574
568
  startWatch: vi.fn(),
@@ -663,8 +657,7 @@ describe("executeTypecheck", () => {
663
657
  const engine = {
664
658
  run: vi.fn().mockResolvedValue({
665
659
  success: true,
666
- js: { success: true, errors: [], warnings: [] },
667
- dts: { success: true, errors: [], warnings: [], diagnostics: [] },
660
+ build: { success: true, errors: [], warnings: [], diagnostics: [] },
668
661
  lint: { success: false, errorCount: 2, warningCount: 1, formattedOutput: "lint err" },
669
662
  }),
670
663
  startWatch: vi.fn(),
@@ -718,8 +711,7 @@ describe("executeTypecheck", () => {
718
711
  const engine = {
719
712
  run: vi.fn().mockResolvedValue({
720
713
  success: false,
721
- js: { success: true, errors: [], warnings: [] },
722
- dts: {
714
+ build: {
723
715
  success: false,
724
716
  errors: ["[core-node:node] Something went wrong"],
725
717
  warnings: [],
@@ -741,7 +733,7 @@ describe("executeTypecheck", () => {
741
733
  });
742
734
 
743
735
  // Acceptance: Scenario "복수 엔진이 문자열 에러를 반환"
744
- it("복수 엔진이 각각 dts.errors에 메시지를 반환하면 모든 에러 메시지가 formattedOutput에 포함된다", async () => {
736
+ it("복수 엔진이 각각 build.errors에 메시지를 반환하면 모든 에러 메시지가 formattedOutput에 포함된다", async () => {
745
737
  setupDefaults({
746
738
  "pkg-a": { target: "node" },
747
739
  "pkg-b": { target: "node" },
@@ -758,8 +750,7 @@ describe("executeTypecheck", () => {
758
750
  const engine = {
759
751
  run: vi.fn().mockResolvedValue({
760
752
  success: false,
761
- js: { success: true, errors: [], warnings: [] },
762
- dts: {
753
+ build: {
763
754
  success: false,
764
755
  errors: [errorMessages[idx]],
765
756
  warnings: [],
@@ -780,16 +771,15 @@ describe("executeTypecheck", () => {
780
771
  expect(result.formattedOutput).toContain("[pkg-b:node] Error in package B");
781
772
  });
782
773
 
783
- // Unit: 단일 엔진이 dts.errors에 복수 메시지를 반환하면 각각 합성 Diagnostic으로 변환된다
784
- it("단일 엔진이 dts.errors에 복수 메시지를 담으면 errorCount가 메시지 수와 일치한다", async () => {
774
+ // Unit: 단일 엔진이 build.errors에 복수 메시지를 반환하면 각각 합성 Diagnostic으로 변환된다
775
+ it("단일 엔진이 build.errors에 복수 메시지를 담으면 errorCount가 메시지 수와 일치한다", async () => {
785
776
  setupDefaults({ "core-node": { target: "node" } });
786
777
 
787
778
  mocks.createBuildEngine.mockImplementation(() => {
788
779
  const engine = {
789
780
  run: vi.fn().mockResolvedValue({
790
781
  success: false,
791
- js: { success: true, errors: [], warnings: [] },
792
- dts: {
782
+ build: {
793
783
  success: false,
794
784
  errors: ["Error message 1", "Error message 2", "Error message 3"],
795
785
  warnings: [],
@@ -821,8 +811,7 @@ describe("executeTypecheck", () => {
821
811
  const engine = {
822
812
  run: vi.fn().mockResolvedValue({
823
813
  success: false,
824
- js: { success: true, errors: [], warnings: [] },
825
- dts: { success: false, errors: [], warnings: [], diagnostics: [diag] },
814
+ build: { success: false, errors: [], warnings: [], diagnostics: [diag] },
826
815
  }),
827
816
  startWatch: vi.fn(),
828
817
  stop: vi.fn().mockResolvedValue(undefined),
@@ -1,3 +1,4 @@
1
+ import path from "path";
1
2
  import { describe, it, expect, vi, beforeEach } from "vitest";
2
3
 
3
4
  //#region Mocks
@@ -21,13 +22,18 @@ vi.mock("@simplysm/core-node", () => ({
21
22
  readdir: mockFsxReaddir,
22
23
  glob: mockFsxGlob,
23
24
  },
25
+ cpx: {
26
+ exec: mockCpxExec,
27
+ execSync: vi.fn().mockReturnValue({ stdout: "", stderr: "", exitCode: 0 }),
28
+ },
29
+ pathx: {
30
+ posixResolve: (...args: string[]) => path.resolve(...args).replace(/\\/g, "/"),
31
+ posix: (p: string) => p.replace(/\\/g, "/"),
32
+ },
24
33
  }));
25
34
 
26
- // execa mock
27
- const mockExeca = vi.fn().mockResolvedValue({ stdout: "" });
28
- vi.mock("execa", () => ({
29
- execa: mockExeca,
30
- }));
35
+ // cpx mock (was execa)
36
+ const mockCpxExec = vi.fn().mockResolvedValue({ stdout: "", stderr: "", exitCode: 0 });
31
37
 
32
38
  // esbuild mock
33
39
  const mockEsbuildBuild = vi.fn().mockResolvedValue({});
@@ -91,13 +97,15 @@ function setupDefaultMocks() {
91
97
  });
92
98
  mockFsxReaddir.mockResolvedValue(["index.html", "assets", "electron"]);
93
99
  // Default: glob returns one exe file matching the builder output
94
- mockFsxGlob.mockImplementation((pattern: string, opts?: { cwd?: string }) => {
95
- if (pattern === "*.exe" && opts?.cwd != null) {
96
- return Promise.resolve([opts.cwd.replace(/\\/g, "/") + "/My App Setup 1.0.0.exe"]);
100
+ mockFsxGlob.mockImplementation((pattern: string) => {
101
+ const normalized = pattern.replace(/\\/g, "/");
102
+ if (normalized.endsWith(".electron/dist/*.exe")) {
103
+ const dir = normalized.replace("/*.exe", "");
104
+ return Promise.resolve([dir + "/My App Setup 1.0.0.exe"]);
97
105
  }
98
106
  return Promise.resolve([]);
99
107
  });
100
- mockExeca.mockResolvedValue({ stdout: "" });
108
+ mockCpxExec.mockResolvedValue({ stdout: "", stderr: "", exitCode: 0 });
101
109
  mockEsbuildBuild.mockResolvedValue({});
102
110
  }
103
111
 
@@ -171,7 +179,7 @@ describe("Electron", () => {
171
179
 
172
180
  expect(findElectronPackageJson()).toBeDefined();
173
181
 
174
- const execaCalls = mockExeca.mock.calls;
182
+ const execaCalls = mockCpxExec.mock.calls;
175
183
  expect(
176
184
  execaCalls.find((c) => c[0] === "npm" && (c[1] as string[]).includes("install")),
177
185
  ).toBeDefined();
@@ -188,7 +196,7 @@ describe("Electron", () => {
188
196
  const electron = await Electron.create(PKG_PATH, { appId: "com.test.app" });
189
197
  await electron.initialize();
190
198
 
191
- const rebuildCall = mockExeca.mock.calls.find(
199
+ const rebuildCall = mockCpxExec.mock.calls.find(
192
200
  (c) => typeof c[0] === "string" && c[0].includes("electron-rebuild"),
193
201
  );
194
202
  expect(rebuildCall).toBeUndefined();
@@ -418,7 +426,8 @@ describe("Electron", () => {
418
426
 
419
427
  it("빌드 산출물이 없으면 경고를 출력한다", async () => {
420
428
  mockFsxGlob.mockImplementation((pattern: string) => {
421
- if (pattern === "*.exe") return Promise.resolve([]);
429
+ const normalized = pattern.replace(/\\/g, "/");
430
+ if (normalized.endsWith(".electron/dist/*.exe")) return Promise.resolve([]);
422
431
  return Promise.resolve([]);
423
432
  });
424
433
 
@@ -436,15 +445,15 @@ describe("Electron", () => {
436
445
  //#region Rule: 개발 모드에서 Electron 앱을 실행한다
437
446
 
438
447
  describe("인수 테스트: run()", () => {
439
- // Helper: creates a deferred execa mock where Electron process can be controlled
440
- function setupExecaForRun(): {
448
+ // Helper: creates a deferred cpx mock where Electron process can be controlled
449
+ function setupCpxForRun(): {
441
450
  electronKill: ReturnType<typeof vi.fn>;
442
451
  resolveElectron: () => void;
443
452
  } {
444
453
  const electronKill = vi.fn();
445
454
  let resolveElectron: () => void = () => {};
446
455
 
447
- mockExeca.mockImplementation((cmd: string) => {
456
+ mockCpxExec.mockImplementation((cmd: string) => {
448
457
  if (typeof cmd === "string" && cmd.includes("electron")) {
449
458
  // Electron process: create a deferred promise we can resolve externally
450
459
  const p = new Promise<void>((resolve) => {
@@ -453,14 +462,14 @@ describe("Electron", () => {
453
462
  p.kill = electronKill;
454
463
  return p;
455
464
  }
456
- return Promise.resolve({ stdout: "" });
465
+ return Promise.resolve({ stdout: "", stderr: "", exitCode: 0 });
457
466
  });
458
467
 
459
468
  return { electronKill, resolveElectron: () => resolveElectron() };
460
469
  }
461
470
 
462
471
  it("creates esbuild context with banner for env and spawns Electron", async () => {
463
- const { resolveElectron } = setupExecaForRun();
472
+ const { resolveElectron } = setupCpxForRun();
464
473
 
465
474
  const { Electron } = await import("../../src/electron/electron.js");
466
475
  const electron = await Electron.create(PKG_PATH, { appId: "com.test.app" });
@@ -503,7 +512,7 @@ describe("Electron", () => {
503
512
  });
504
513
 
505
514
  it("resolves on SIGINT signal", async () => {
506
- const { electronKill } = setupExecaForRun();
515
+ const { electronKill } = setupCpxForRun();
507
516
 
508
517
  const { Electron } = await import("../../src/electron/electron.js");
509
518
  const electron = await Electron.create(PKG_PATH, { appId: "com.test.app" });
@@ -526,7 +535,7 @@ describe("Electron", () => {
526
535
  describe("단위: run() 플러그인 동작", () => {
527
536
  it("passes custom env and ELECTRON_DEV_URL via esbuild banner", async () => {
528
537
  let resolveElectron: () => void = () => {};
529
- mockExeca.mockImplementation((cmd: string) => {
538
+ mockCpxExec.mockImplementation((cmd: string) => {
530
539
  if (typeof cmd === "string" && cmd.includes("electron")) {
531
540
  const p = new Promise<void>((resolve) => {
532
541
  resolveElectron = resolve;
@@ -534,7 +543,7 @@ describe("Electron", () => {
534
543
  p.kill = vi.fn();
535
544
  return p;
536
545
  }
537
- return Promise.resolve({ stdout: "" });
546
+ return Promise.resolve({ stdout: "", stderr: "", exitCode: 0 });
538
547
  });
539
548
 
540
549
  const { Electron } = await import("../../src/electron/electron.js");
@@ -559,7 +568,7 @@ describe("Electron", () => {
559
568
 
560
569
  it("calls initialize() before starting esbuild context", async () => {
561
570
  let resolveElectron: () => void = () => {};
562
- mockExeca.mockImplementation((cmd: string) => {
571
+ mockCpxExec.mockImplementation((cmd: string) => {
563
572
  if (typeof cmd === "string" && cmd.includes("electron")) {
564
573
  const p = new Promise<void>((resolve) => {
565
574
  resolveElectron = resolve;
@@ -567,7 +576,7 @@ describe("Electron", () => {
567
576
  p.kill = vi.fn();
568
577
  return p;
569
578
  }
570
- return Promise.resolve({ stdout: "" });
579
+ return Promise.resolve({ stdout: "", stderr: "", exitCode: 0 });
571
580
  });
572
581
 
573
582
  const { Electron } = await import("../../src/electron/electron.js");
@@ -579,7 +588,7 @@ describe("Electron", () => {
579
588
  await runPromise;
580
589
 
581
590
  // initialize calls npm install -> execa should have been called with npm install
582
- const npmInstallCall = mockExeca.mock.calls.find(
591
+ const npmInstallCall = mockCpxExec.mock.calls.find(
583
592
  (c: any[]) => c[0] === "npm" && (c[1] as string[]).includes("install"),
584
593
  );
585
594
  expect(npmInstallCall).toBeDefined();
@@ -46,8 +46,7 @@ function createMockPkg(overrides: Partial<BuildPackageInfo> = {}): BuildPackageI
46
46
 
47
47
  function setupDefaultBuildResult(): void {
48
48
  mockWorker.build.mockResolvedValue({
49
- js: { success: true, errors: undefined, warnings: undefined },
50
- dts: { success: true, errors: undefined, diagnostics: [] },
49
+ build: { success: true, errors: undefined, warnings: undefined, diagnostics: [] },
51
50
  lint: { success: true, errorCount: 0, warningCount: 0, formattedOutput: "" },
52
51
  });
53
52
  mockWorker.terminate.mockResolvedValue(undefined);
@@ -78,7 +77,7 @@ describe("BaseEngine", () => {
78
77
  const buildHandler = mockWorker.on.mock.calls.find(
79
78
  (call: any[]) => call[0] === "build",
80
79
  )?.[1];
81
- buildHandler?.({ js: { success: true }, dts: { success: true } });
80
+ buildHandler?.({ build: { success: true } });
82
81
  });
83
82
 
84
83
  const engine = new TscEngine({ cwd: "/root", pkg: createMockPkg() });
@@ -101,7 +100,7 @@ describe("BaseEngine", () => {
101
100
  const buildHandler = mockWorker.on.mock.calls.find(
102
101
  (call: any[]) => call[0] === "build",
103
102
  )?.[1];
104
- buildHandler?.({ js: { success: true }, dts: { success: true } });
103
+ buildHandler?.({ build: { success: true } });
105
104
  });
106
105
 
107
106
  const engine = new TscEngine({ cwd: "/root", pkg: createMockPkg() });
@@ -114,7 +113,7 @@ describe("BaseEngine", () => {
114
113
  await engine.stop();
115
114
  });
116
115
 
117
- it("reports build and dts results separately to ResultCollector", async () => {
116
+ it("reports build result to ResultCollector", async () => {
118
117
  const mockResultCollector = { add: vi.fn() };
119
118
 
120
119
  mockWorker.startWatch.mockImplementation(() => {
@@ -122,8 +121,7 @@ describe("BaseEngine", () => {
122
121
  (call: any[]) => call[0] === "build",
123
122
  )?.[1];
124
123
  buildHandler?.({
125
- js: { success: true, errors: undefined },
126
- dts: { success: false, errors: ["type error"] },
124
+ build: { success: false, errors: ["type error"] },
127
125
  });
128
126
  });
129
127
 
@@ -137,13 +135,10 @@ describe("BaseEngine", () => {
137
135
 
138
136
  const addCalls = mockResultCollector.add.mock.calls;
139
137
  const buildResult = addCalls.find((c: any[]) => c[0].type === "build");
140
- const dtsResult = addCalls.find((c: any[]) => c[0].type === "dts");
141
138
 
142
139
  expect(buildResult).toBeDefined();
143
- expect(buildResult![0].status).toBe("success");
140
+ expect(buildResult![0].status).toBe("error");
144
141
  expect(buildResult![0].target).toBe("node");
145
- expect(dtsResult).toBeDefined();
146
- expect(dtsResult![0].status).toBe("error");
147
142
 
148
143
  await engine.stop();
149
144
  });
@@ -157,7 +152,7 @@ describe("BaseEngine", () => {
157
152
  const buildHandler = mockWorker.on.mock.calls.find(
158
153
  (call: any[]) => call[0] === "build",
159
154
  )?.[1];
160
- buildHandler?.({ js: { success: true }, dts: { success: true } });
155
+ buildHandler?.({ build: { success: true } });
161
156
  });
162
157
 
163
158
  const engine = new TscEngine({
@@ -182,7 +177,7 @@ describe("BaseEngine", () => {
182
177
  "test-pkg (node)",
183
178
  );
184
179
 
185
- buildHandler?.({ js: { success: true }, dts: { success: true } });
180
+ buildHandler?.({ build: { success: true } });
186
181
  expect(mockResolver).toHaveBeenCalled();
187
182
 
188
183
  await engine.stop();
@@ -209,7 +204,7 @@ describe("BaseEngine", () => {
209
204
  const buildHandler = mockWorker.on.mock.calls.find(
210
205
  (call: any[]) => call[0] === "build",
211
206
  )?.[1];
212
- buildHandler?.({ js: { success: true }, dts: { success: true } });
207
+ buildHandler?.({ build: { success: true } });
213
208
  });
214
209
 
215
210
  const engine = new TscEngine({
@@ -229,7 +224,7 @@ describe("BaseEngine", () => {
229
224
  )?.[1];
230
225
 
231
226
  buildStartHandler?.({});
232
- buildHandler?.({ js: { success: true }, dts: { success: true } });
227
+ buildHandler?.({ build: { success: true } });
233
228
 
234
229
  // The resolver should have been called, which resolves the RebuildManager promise
235
230
  expect(resolverFn).toBeDefined();
@@ -237,7 +232,7 @@ describe("BaseEngine", () => {
237
232
  await engine.stop();
238
233
  });
239
234
 
240
- it("does not call registerBuild on initial buildStart (only on rebuilds)", async () => {
235
+ it("calls registerBuild on initial buildStart as well as rebuilds", async () => {
241
236
  const mockRebuildManager = { registerBuild: vi.fn(() => vi.fn()) };
242
237
 
243
238
  mockWorker.startWatch.mockImplementation(() => {
@@ -251,7 +246,7 @@ describe("BaseEngine", () => {
251
246
  const buildHandler = mockWorker.on.mock.calls.find(
252
247
  (call: any[]) => call[0] === "build",
253
248
  )?.[1];
254
- buildHandler?.({ js: { success: true }, dts: { success: true } });
249
+ buildHandler?.({ build: { success: true } });
255
250
  });
256
251
 
257
252
  const engine = new TscEngine({
@@ -262,8 +257,8 @@ describe("BaseEngine", () => {
262
257
 
263
258
  await engine.startWatch({ js: true, dts: true });
264
259
 
265
- // registerBuild should NOT have been called for the initial build
266
- expect(mockRebuildManager.registerBuild).not.toHaveBeenCalled();
260
+ // registerBuild should be called for ALL builds including initial
261
+ expect(mockRebuildManager.registerBuild).toHaveBeenCalledOnce();
267
262
 
268
263
  await engine.stop();
269
264
  });
@@ -276,8 +271,7 @@ describe("BaseEngine", () => {
276
271
  (call: any[]) => call[0] === "build",
277
272
  )?.[1];
278
273
  buildHandler?.({
279
- js: { success: true },
280
- dts: { success: true },
274
+ build: { success: true },
281
275
  });
282
276
  });
283
277
 
@@ -48,8 +48,7 @@ function createMockPkg(): BuildPackageInfo {
48
48
  beforeEach(() => {
49
49
  vi.clearAllMocks();
50
50
  mockWorker.build.mockResolvedValue({
51
- js: { success: true },
52
- dts: { success: true, diagnostics: [] },
51
+ build: { success: true, diagnostics: [] },
53
52
  lint: { success: true, errorCount: 0, warningCount: 0, formattedOutput: "" },
54
53
  });
55
54
  mockWorker.terminate.mockResolvedValue(undefined);
@@ -72,8 +71,7 @@ describe("엔진 lint 통합 (Slice 2)", () => {
72
71
  describe("Scenario: EngineResult includes lint field", () => {
73
72
  it("run() returns EngineResult with lint field when worker provides it", async () => {
74
73
  mockWorker.build.mockResolvedValue({
75
- js: { success: true },
76
- dts: { success: true, diagnostics: [] },
74
+ build: { success: true, diagnostics: [] },
77
75
  lint: { success: false, errorCount: 3, warningCount: 1, formattedOutput: "lint errors" },
78
76
  });
79
77
 
@@ -92,8 +90,7 @@ describe("엔진 lint 통합 (Slice 2)", () => {
92
90
 
93
91
  it("run() returns EngineResult without lint when lint is not in output", async () => {
94
92
  mockWorker.build.mockResolvedValue({
95
- js: { success: true },
96
- dts: { success: true, diagnostics: [] },
93
+ build: { success: true, diagnostics: [] },
97
94
  });
98
95
 
99
96
  const engine = new TscEngine({ cwd: "/root", pkg: createMockPkg() });
@@ -114,8 +111,7 @@ describe("엔진 lint 통합 (Slice 2)", () => {
114
111
  (call: any[]) => call[0] === "build",
115
112
  )?.[1];
116
113
  buildHandler?.({
117
- js: { success: true },
118
- dts: { success: true },
114
+ build: { success: true },
119
115
  lint: { success: false, errorCount: 2, warningCount: 0, formattedOutput: "errors" },
120
116
  });
121
117
  });
@@ -150,8 +146,7 @@ describe("엔진 lint 통합 (Slice 2)", () => {
150
146
  (call: any[]) => call[0] === "build",
151
147
  )?.[1];
152
148
  buildHandler?.({
153
- js: { success: true },
154
- dts: { success: true },
149
+ build: { success: true },
155
150
  });
156
151
  });
157
152