@simplysm/sd-cli 13.0.99 → 14.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/build.js +29 -19
- package/dist/commands/build.js.map +1 -6
- package/dist/commands/check.d.ts +1 -0
- package/dist/commands/check.d.ts.map +1 -1
- package/dist/commands/check.js +130 -115
- package/dist/commands/check.js.map +1 -6
- package/dist/commands/dev.d.ts +6 -7
- package/dist/commands/dev.d.ts.map +1 -1
- package/dist/commands/dev.js +24 -14
- package/dist/commands/dev.js.map +1 -6
- package/dist/commands/lint.d.ts +1 -1
- package/dist/commands/lint.js +158 -116
- package/dist/commands/lint.js.map +1 -6
- package/dist/commands/publish.d.ts.map +1 -1
- package/dist/commands/publish.js +637 -510
- package/dist/commands/publish.js.map +1 -6
- package/dist/commands/replace-deps.js +12 -12
- package/dist/commands/replace-deps.js.map +1 -6
- package/dist/commands/typecheck.d.ts +5 -30
- package/dist/commands/typecheck.d.ts.map +1 -1
- package/dist/commands/typecheck.js +144 -207
- package/dist/commands/typecheck.js.map +1 -6
- package/dist/commands/watch.d.ts +6 -4
- package/dist/commands/watch.d.ts.map +1 -1
- package/dist/commands/watch.js +25 -16
- package/dist/commands/watch.js.map +1 -6
- package/dist/engines/NgtscEngine.d.ts +47 -0
- package/dist/engines/NgtscEngine.d.ts.map +1 -0
- package/dist/engines/NgtscEngine.js +151 -0
- package/dist/engines/NgtscEngine.js.map +1 -0
- package/dist/engines/ServerEsbuildEngine.d.ts +47 -0
- package/dist/engines/ServerEsbuildEngine.d.ts.map +1 -0
- package/dist/engines/ServerEsbuildEngine.js +159 -0
- package/dist/engines/ServerEsbuildEngine.js.map +1 -0
- package/dist/engines/TscEngine.d.ts +47 -0
- package/dist/engines/TscEngine.d.ts.map +1 -0
- package/dist/engines/TscEngine.js +153 -0
- package/dist/engines/TscEngine.js.map +1 -0
- package/dist/engines/ViteEngine.d.ts +49 -0
- package/dist/engines/ViteEngine.d.ts.map +1 -0
- package/dist/engines/ViteEngine.js +161 -0
- package/dist/engines/ViteEngine.js.map +1 -0
- package/dist/engines/index.d.ts +26 -0
- package/dist/engines/index.d.ts.map +1 -0
- package/dist/engines/index.js +30 -0
- package/dist/engines/index.js.map +1 -0
- package/dist/engines/types.d.ts +77 -0
- package/dist/engines/types.d.ts.map +1 -0
- package/dist/engines/types.js +2 -0
- package/dist/engines/types.js.map +1 -0
- package/dist/index.d.ts +0 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -6
- package/dist/infra/ResultCollector.d.ts +1 -1
- package/dist/infra/ResultCollector.d.ts.map +1 -1
- package/dist/infra/ResultCollector.js +30 -27
- package/dist/infra/ResultCollector.js.map +1 -6
- package/dist/infra/SignalHandler.js +45 -42
- package/dist/infra/SignalHandler.js.map +1 -6
- package/dist/infra/WorkerManager.js +56 -53
- package/dist/infra/WorkerManager.js.map +1 -6
- package/dist/orchestrators/BuildOrchestrator.d.ts +33 -1
- package/dist/orchestrators/BuildOrchestrator.d.ts.map +1 -1
- package/dist/orchestrators/BuildOrchestrator.js +314 -309
- package/dist/orchestrators/BuildOrchestrator.js.map +1 -6
- package/dist/orchestrators/DevWatchOrchestrator.d.ts +60 -0
- package/dist/orchestrators/DevWatchOrchestrator.d.ts.map +1 -0
- package/dist/orchestrators/DevWatchOrchestrator.js +465 -0
- package/dist/orchestrators/DevWatchOrchestrator.js.map +1 -0
- package/dist/sd-cli-entry.d.ts.map +1 -1
- package/dist/sd-cli-entry.js +190 -266
- package/dist/sd-cli-entry.js.map +1 -6
- package/dist/sd-cli.js +77 -49
- package/dist/sd-cli.js.map +1 -6
- package/dist/sd-config.types.d.ts +2 -0
- package/dist/sd-config.types.d.ts.map +1 -1
- package/dist/sd-config.types.js +2 -1
- package/dist/sd-config.types.js.map +1 -6
- package/dist/utils/angular-build.d.ts +77 -0
- package/dist/utils/angular-build.d.ts.map +1 -0
- package/dist/utils/angular-build.js +84 -0
- package/dist/utils/angular-build.js.map +1 -0
- package/dist/utils/build-env.js +9 -9
- package/dist/utils/build-env.js.map +1 -6
- package/dist/utils/concurrency.d.ts +15 -0
- package/dist/utils/concurrency.d.ts.map +1 -0
- package/dist/utils/concurrency.js +38 -0
- package/dist/utils/concurrency.js.map +1 -0
- package/dist/utils/copy-public.js +104 -87
- package/dist/utils/copy-public.js.map +1 -6
- package/dist/utils/copy-src.js +49 -35
- package/dist/utils/copy-src.js.map +1 -6
- package/dist/utils/esbuild-config.d.ts +0 -29
- package/dist/utils/esbuild-config.d.ts.map +1 -1
- package/dist/utils/esbuild-config.js +151 -218
- package/dist/utils/esbuild-config.js.map +1 -6
- package/dist/utils/ngtsc-build-core.d.ts +49 -0
- package/dist/utils/ngtsc-build-core.d.ts.map +1 -0
- package/dist/utils/ngtsc-build-core.js +250 -0
- package/dist/utils/ngtsc-build-core.js.map +1 -0
- package/dist/utils/output-path-rewriter.d.ts +23 -0
- package/dist/utils/output-path-rewriter.d.ts.map +1 -0
- package/dist/utils/output-path-rewriter.js +74 -0
- package/dist/utils/output-path-rewriter.js.map +1 -0
- package/dist/utils/output-utils.js +55 -40
- package/dist/utils/output-utils.js.map +1 -6
- package/dist/utils/package-utils.d.ts +8 -0
- package/dist/utils/package-utils.d.ts.map +1 -1
- package/dist/utils/package-utils.js +103 -73
- package/dist/utils/package-utils.js.map +1 -6
- package/dist/utils/rebuild-manager.js +41 -44
- package/dist/utils/rebuild-manager.js.map +1 -6
- package/dist/utils/replace-deps.js +283 -184
- package/dist/utils/replace-deps.js.map +1 -6
- package/dist/utils/scss-compiler.d.ts +10 -0
- package/dist/utils/scss-compiler.d.ts.map +1 -0
- package/dist/utils/scss-compiler.js +36 -0
- package/dist/utils/scss-compiler.js.map +1 -0
- package/dist/utils/sd-config.js +29 -19
- package/dist/utils/sd-config.js.map +1 -6
- package/dist/utils/tsc-build.d.ts +36 -0
- package/dist/utils/tsc-build.d.ts.map +1 -0
- package/dist/utils/tsc-build.js +130 -0
- package/dist/utils/tsc-build.js.map +1 -0
- package/dist/utils/tsconfig.d.ts +7 -26
- package/dist/utils/tsconfig.d.ts.map +1 -1
- package/dist/utils/tsconfig.js +39 -64
- package/dist/utils/tsconfig.js.map +1 -6
- package/dist/utils/typecheck-non-package.d.ts +18 -0
- package/dist/utils/typecheck-non-package.d.ts.map +1 -0
- package/dist/utils/typecheck-non-package.js +64 -0
- package/dist/utils/typecheck-non-package.js.map +1 -0
- package/dist/utils/typecheck-serialization.js +58 -40
- package/dist/utils/typecheck-serialization.js.map +1 -6
- package/dist/utils/worker-events.js +48 -40
- package/dist/utils/worker-events.js.map +1 -6
- package/dist/utils/worker-utils.js +48 -28
- package/dist/utils/worker-utils.js.map +1 -6
- package/dist/vitest-plugin.d.ts +9 -0
- package/dist/vitest-plugin.d.ts.map +1 -0
- package/dist/vitest-plugin.js +85 -0
- package/dist/vitest-plugin.js.map +1 -0
- package/dist/workers/library-build.worker.d.ts +54 -0
- package/dist/workers/library-build.worker.d.ts.map +1 -0
- package/dist/workers/library-build.worker.js +97 -0
- package/dist/workers/library-build.worker.js.map +1 -0
- package/dist/workers/lint.worker.js +9 -6
- package/dist/workers/lint.worker.js.map +1 -6
- package/dist/workers/ngtsc-build.worker.d.ts +23 -0
- package/dist/workers/ngtsc-build.worker.d.ts.map +1 -0
- package/dist/workers/ngtsc-build.worker.js +98 -0
- package/dist/workers/ngtsc-build.worker.js.map +1 -0
- package/dist/workers/{server.worker.d.ts → server-build.worker.d.ts} +39 -29
- package/dist/workers/server-build.worker.d.ts.map +1 -0
- package/dist/workers/server-build.worker.js +399 -0
- package/dist/workers/server-build.worker.js.map +1 -0
- package/dist/workers/server-runtime.worker.d.ts +3 -2
- package/dist/workers/server-runtime.worker.d.ts.map +1 -1
- package/dist/workers/server-runtime.worker.js +100 -95
- package/dist/workers/server-runtime.worker.js.map +1 -6
- package/dist/workers/vite-build.worker.d.ts +56 -0
- package/dist/workers/vite-build.worker.d.ts.map +1 -0
- package/dist/workers/vite-build.worker.js +167 -0
- package/dist/workers/vite-build.worker.js.map +1 -0
- package/package.json +10 -16
- package/src/commands/check.ts +21 -3
- package/src/commands/dev.ts +10 -8
- package/src/commands/lint.ts +1 -1
- package/src/commands/publish.ts +4 -0
- package/src/commands/typecheck.ts +89 -256
- package/src/commands/watch.ts +9 -8
- package/src/engines/NgtscEngine.ts +190 -0
- package/src/engines/ServerEsbuildEngine.ts +195 -0
- package/src/engines/TscEngine.ts +189 -0
- package/src/engines/ViteEngine.ts +203 -0
- package/src/engines/index.ts +49 -0
- package/src/engines/types.ts +79 -0
- package/src/index.ts +0 -3
- package/src/infra/ResultCollector.ts +1 -1
- package/src/orchestrators/BuildOrchestrator.ts +87 -157
- package/src/orchestrators/DevWatchOrchestrator.ts +573 -0
- package/src/sd-cli-entry.ts +13 -116
- package/src/sd-config.types.ts +2 -0
- package/src/utils/angular-build.ts +157 -0
- package/src/utils/concurrency.ts +43 -0
- package/src/utils/esbuild-config.ts +1 -122
- package/src/utils/ngtsc-build-core.ts +379 -0
- package/src/utils/output-path-rewriter.ts +82 -0
- package/src/utils/package-utils.ts +20 -0
- package/src/utils/scss-compiler.ts +58 -0
- package/src/utils/tsc-build.ts +175 -0
- package/src/utils/tsconfig.ts +27 -95
- package/src/utils/typecheck-non-package.ts +87 -0
- package/src/vitest-plugin.ts +118 -0
- package/src/workers/library-build.worker.ts +153 -0
- package/src/workers/ngtsc-build.worker.ts +146 -0
- package/src/workers/server-build.worker.ts +565 -0
- package/src/workers/server-runtime.worker.ts +17 -26
- package/src/workers/vite-build.worker.ts +252 -0
- package/tests/commands/check.spec.ts +276 -0
- package/tests/commands/dev.spec.ts +53 -0
- package/tests/commands/lint.spec.ts +243 -0
- package/tests/commands/publish.spec.ts +1159 -0
- package/tests/commands/typecheck.spec.ts +294 -0
- package/tests/commands/watch.spec.ts +53 -0
- package/tests/engines/engine-selection.spec.ts +247 -0
- package/tests/engines/ngtsc-engine.spec.ts +274 -0
- package/tests/engines/server-esbuild-engine.spec.ts +256 -0
- package/tests/engines/tsc-engine.spec.ts +213 -0
- package/tests/engines/vite-engine.spec.ts +358 -0
- package/tests/infra/result-collector.spec.ts +46 -0
- package/tests/infra/signal-handler.spec.ts +32 -0
- package/tests/infra/worker-manager.spec.ts +63 -0
- package/tests/orchestrators/build-orchestrator.spec.ts +772 -0
- package/tests/orchestrators/dev-watch-orchestrator.spec.ts +1173 -0
- package/tests/sd-cli-entry.spec.ts +49 -0
- package/tests/utils/angular-build.spec.ts +251 -0
- package/tests/utils/build-env.spec.ts +33 -0
- package/tests/utils/concurrency.spec.ts +65 -0
- package/tests/utils/copy-src.spec.ts +144 -0
- package/tests/utils/esbuild-config.spec.ts +186 -0
- package/tests/utils/external-modules.spec.ts +161 -0
- package/tests/utils/ngtsc-scss-refactor.spec.ts +66 -0
- package/tests/utils/output-path-rewriter.spec.ts +165 -0
- package/tests/utils/output-utils.spec.ts +104 -0
- package/tests/utils/package-utils.spec.ts +52 -0
- package/tests/utils/rebuild-manager.spec.ts +30 -27
- package/tests/utils/replace-deps.spec.ts +69 -0
- package/tests/utils/scss-compiler.spec.ts +131 -0
- package/tests/utils/sd-config.spec.ts +77 -0
- package/tests/utils/tsc-build.spec.ts +358 -0
- package/tests/utils/tsconfig-angular.spec.ts +71 -0
- package/tests/utils/typecheck-non-package.spec.ts +120 -0
- package/tests/utils/worker-events.spec.ts +155 -0
- package/tests/utils/worker-utils.spec.ts +43 -0
- package/tests/vitest-plugin-cwd.spec.ts +68 -0
- package/tests/vitest-plugin.spec.ts +103 -0
- package/tests/workers/library-build-worker.spec.ts +258 -0
- package/tests/workers/ngtsc-build-worker.spec.ts +187 -0
- package/tests/workers/server-build-worker.spec.ts +566 -0
- package/tests/workers/server-runtime-worker.spec.ts +251 -0
- package/README.md +0 -295
- package/dist/builders/BaseBuilder.d.ts +0 -88
- package/dist/builders/BaseBuilder.d.ts.map +0 -1
- package/dist/builders/BaseBuilder.js +0 -142
- package/dist/builders/BaseBuilder.js.map +0 -6
- package/dist/builders/DtsBuilder.d.ts +0 -22
- package/dist/builders/DtsBuilder.d.ts.map +0 -1
- package/dist/builders/DtsBuilder.js +0 -72
- package/dist/builders/DtsBuilder.js.map +0 -6
- package/dist/builders/LibraryBuilder.d.ts +0 -22
- package/dist/builders/LibraryBuilder.d.ts.map +0 -1
- package/dist/builders/LibraryBuilder.js +0 -85
- package/dist/builders/LibraryBuilder.js.map +0 -6
- package/dist/builders/types.d.ts +0 -55
- package/dist/builders/types.d.ts.map +0 -1
- package/dist/builders/types.js +0 -1
- package/dist/builders/types.js.map +0 -6
- package/dist/capacitor/capacitor.d.ts +0 -151
- package/dist/capacitor/capacitor.d.ts.map +0 -1
- package/dist/capacitor/capacitor.js +0 -694
- package/dist/capacitor/capacitor.js.map +0 -6
- package/dist/commands/device.d.ts +0 -22
- package/dist/commands/device.d.ts.map +0 -1
- package/dist/commands/device.js +0 -98
- package/dist/commands/device.js.map +0 -6
- package/dist/commands/init.d.ts +0 -14
- package/dist/commands/init.d.ts.map +0 -1
- package/dist/commands/init.js +0 -72
- package/dist/commands/init.js.map +0 -6
- package/dist/electron/electron.d.ts +0 -84
- package/dist/electron/electron.d.ts.map +0 -1
- package/dist/electron/electron.js +0 -263
- package/dist/electron/electron.js.map +0 -6
- package/dist/orchestrators/DevOrchestrator.d.ts +0 -83
- package/dist/orchestrators/DevOrchestrator.d.ts.map +0 -1
- package/dist/orchestrators/DevOrchestrator.js +0 -540
- package/dist/orchestrators/DevOrchestrator.js.map +0 -6
- package/dist/orchestrators/WatchOrchestrator.d.ts +0 -57
- package/dist/orchestrators/WatchOrchestrator.d.ts.map +0 -1
- package/dist/orchestrators/WatchOrchestrator.js +0 -199
- package/dist/orchestrators/WatchOrchestrator.js.map +0 -6
- package/dist/utils/tailwind-config-deps.d.ts +0 -8
- package/dist/utils/tailwind-config-deps.d.ts.map +0 -1
- package/dist/utils/tailwind-config-deps.js +0 -82
- package/dist/utils/tailwind-config-deps.js.map +0 -6
- package/dist/utils/template.d.ts +0 -14
- package/dist/utils/template.d.ts.map +0 -1
- package/dist/utils/template.js +0 -33
- package/dist/utils/template.js.map +0 -6
- package/dist/utils/vite-config.d.ts +0 -35
- package/dist/utils/vite-config.d.ts.map +0 -1
- package/dist/utils/vite-config.js +0 -259
- package/dist/utils/vite-config.js.map +0 -6
- package/dist/workers/client.worker.d.ts +0 -83
- package/dist/workers/client.worker.d.ts.map +0 -1
- package/dist/workers/client.worker.js +0 -111
- package/dist/workers/client.worker.js.map +0 -6
- package/dist/workers/dts.worker.d.ts +0 -75
- package/dist/workers/dts.worker.d.ts.map +0 -1
- package/dist/workers/dts.worker.js +0 -270
- package/dist/workers/dts.worker.js.map +0 -6
- package/dist/workers/library.worker.d.ts +0 -75
- package/dist/workers/library.worker.d.ts.map +0 -1
- package/dist/workers/library.worker.js +0 -166
- package/dist/workers/library.worker.js.map +0 -6
- package/dist/workers/server.worker.d.ts.map +0 -1
- package/dist/workers/server.worker.js +0 -482
- package/dist/workers/server.worker.js.map +0 -6
- package/src/builders/BaseBuilder.ts +0 -218
- package/src/builders/DtsBuilder.ts +0 -92
- package/src/builders/LibraryBuilder.ts +0 -110
- package/src/builders/types.ts +0 -60
- package/src/capacitor/capacitor.ts +0 -931
- package/src/commands/device.ts +0 -140
- package/src/commands/init.ts +0 -113
- package/src/electron/electron.ts +0 -362
- package/src/orchestrators/DevOrchestrator.ts +0 -744
- package/src/orchestrators/WatchOrchestrator.ts +0 -277
- package/src/utils/tailwind-config-deps.ts +0 -98
- package/src/utils/template.ts +0 -56
- package/src/utils/vite-config.ts +0 -390
- package/src/workers/client.worker.ts +0 -250
- package/src/workers/dts.worker.ts +0 -453
- package/src/workers/library.worker.ts +0 -316
- package/src/workers/server.worker.ts +0 -734
- package/templates/init/.gitignore.hbs +0 -34
- package/templates/init/.npmrc.hbs +0 -1
- package/templates/init/.prettierignore +0 -1
- package/templates/init/.prettierrc.yaml +0 -12
- package/templates/init/eslint.config.ts +0 -15
- package/templates/init/mise.toml +0 -3
- package/templates/init/package.json.hbs +0 -32
- package/templates/init/packages/client-admin/index.html.hbs +0 -144
- package/templates/init/packages/client-admin/package.json.hbs +0 -27
- package/templates/init/packages/client-admin/public/assets/logo-landscape.png +0 -0
- package/templates/init/packages/client-admin/public/assets/logo.png +0 -0
- package/templates/init/packages/client-admin/public/favicon.ico +0 -0
- package/templates/init/packages/client-admin/src/App.tsx +0 -42
- package/templates/init/packages/client-admin/src/dev/DevDialog.tsx +0 -34
- package/templates/init/packages/client-admin/src/events/AuthChangeEvent.ts +0 -3
- package/templates/init/packages/client-admin/src/main.css +0 -4
- package/templates/init/packages/client-admin/src/main.tsx.hbs +0 -146
- package/templates/init/packages/client-admin/src/providers/AppServiceProvider.tsx.hbs +0 -103
- package/templates/init/packages/client-admin/src/providers/AppStructureProvider.tsx +0 -84
- package/templates/init/packages/client-admin/src/providers/AuthProvider.tsx.hbs +0 -96
- package/templates/init/packages/client-admin/src/providers/configureSharedData.ts.hbs +0 -67
- package/templates/init/packages/client-admin/src/views/auth/LoginView.tsx +0 -132
- package/templates/init/packages/client-admin/src/views/home/HomeView.tsx +0 -108
- package/templates/init/packages/client-admin/src/views/home/base/employee/EmployeeDetail.tsx.hbs +0 -243
- package/templates/init/packages/client-admin/src/views/home/base/employee/EmployeeSheet.tsx.hbs +0 -271
- package/templates/init/packages/client-admin/src/views/home/base/role-permission/RoleDetail.tsx.hbs +0 -146
- package/templates/init/packages/client-admin/src/views/home/base/role-permission/RolePermissionDetail.tsx.hbs +0 -121
- package/templates/init/packages/client-admin/src/views/home/base/role-permission/RolePermissionView.tsx +0 -52
- package/templates/init/packages/client-admin/src/views/home/base/role-permission/RoleSheet.tsx.hbs +0 -125
- package/templates/init/packages/client-admin/src/views/home/main/MainView.tsx.hbs +0 -13
- package/templates/init/packages/client-admin/src/views/home/my-info/MyInfoDetail.tsx.hbs +0 -241
- package/templates/init/packages/client-admin/src/views/home/system/system-log/SystemLogSheet.tsx.hbs +0 -169
- package/templates/init/packages/client-admin/src/views/not-found/NotFoundView.tsx +0 -15
- package/templates/init/packages/client-admin/tailwind.config.ts +0 -10
- package/templates/init/packages/db-main/package.json.hbs +0 -13
- package/templates/init/packages/db-main/src/MainDbContext.ts +0 -22
- package/templates/init/packages/db-main/src/dataLogExt.ts +0 -127
- package/templates/init/packages/db-main/src/index.ts +0 -14
- package/templates/init/packages/db-main/src/tables/base/Employee.ts +0 -24
- package/templates/init/packages/db-main/src/tables/base/EmployeeConfig.ts +0 -13
- package/templates/init/packages/db-main/src/tables/base/Role.ts +0 -9
- package/templates/init/packages/db-main/src/tables/base/RolePermission.ts +0 -13
- package/templates/init/packages/db-main/src/tables/system/_DataLog.ts +0 -19
- package/templates/init/packages/db-main/src/tables/system/_Log.ts +0 -16
- package/templates/init/packages/server/package.json.hbs +0 -20
- package/templates/init/packages/server/public-dev/dev//354/264/210/352/270/260/355/231/224.xlsx +0 -0
- package/templates/init/packages/server/src/index.ts +0 -4
- package/templates/init/packages/server/src/main.ts.hbs +0 -34
- package/templates/init/packages/server/src/services/AuthService.ts.hbs +0 -171
- package/templates/init/packages/server/src/services/DevService.ts.hbs +0 -94
- package/templates/init/packages/server/src/services/EmployeeService.ts.hbs +0 -122
- package/templates/init/packages/server/src/services/RoleService.ts.hbs +0 -59
- package/templates/init/pnpm-workspace.yaml +0 -15
- package/templates/init/sd.config.ts.hbs +0 -48
- package/templates/init/tsconfig.json.hbs +0 -39
- package/templates/init/vitest.config.ts +0 -36
- package/tests/capacitor-exclude.spec.ts +0 -78
- package/tests/capacitor.spec.ts +0 -49
- package/tests/copy-src.spec.ts +0 -50
- package/tests/electron-exclude.spec.ts +0 -61
- package/tests/get-compiler-options-for-package.spec.ts +0 -80
- package/tests/get-package-source-files.spec.ts +0 -139
- package/tests/get-types-from-package-json.spec.ts +0 -92
- package/tests/infra/ResultCollector.spec.ts +0 -30
- package/tests/infra/SignalHandler.spec.ts +0 -38
- package/tests/infra/WorkerManager.spec.ts +0 -63
- package/tests/load-ignore-patterns.spec.ts +0 -163
- package/tests/load-sd-config.spec.ts +0 -100
- package/tests/package-utils.spec.ts +0 -188
- package/tests/parse-root-tsconfig.spec.ts +0 -89
- package/tests/publish-config-narrowing.spec.ts +0 -20
- package/tests/replace-deps.spec.ts +0 -308
- package/tests/run-lint.spec.ts +0 -366
- package/tests/run-typecheck.spec.ts +0 -544
- package/tests/run-watch.spec.ts +0 -76
- package/tests/sd-cli.spec.ts +0 -265
- package/tests/sd-public-dev-plugin-mime.spec.ts +0 -19
- package/tests/tailwind-config-deps.spec.ts +0 -30
- package/tests/template.spec.ts +0 -70
- package/tests/vite-config-exclude.spec.ts +0 -35
- package/tests/vite-config-outdir.spec.ts +0 -38
- package/tests/write-changed-output-files.spec.ts +0 -97
|
@@ -0,0 +1,772 @@
|
|
|
1
|
+
import { describe, it, expect, vi, beforeEach } from "vitest";
|
|
2
|
+
|
|
3
|
+
// --- Mock factories (vi.mock is hoisted) ---
|
|
4
|
+
|
|
5
|
+
const mockLogger = {
|
|
6
|
+
debug: vi.fn(),
|
|
7
|
+
info: vi.fn(),
|
|
8
|
+
warn: vi.fn(),
|
|
9
|
+
error: vi.fn(),
|
|
10
|
+
start: vi.fn(),
|
|
11
|
+
success: vi.fn(),
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
vi.mock("consola", () => {
|
|
15
|
+
const consolaObj = {
|
|
16
|
+
withTag: vi.fn(() => mockLogger),
|
|
17
|
+
};
|
|
18
|
+
return { consola: consolaObj, default: consolaObj };
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
vi.mock("../../src/utils/sd-config", () => ({
|
|
22
|
+
loadSdConfig: vi.fn(),
|
|
23
|
+
}));
|
|
24
|
+
|
|
25
|
+
vi.mock("../../src/utils/build-env", () => ({
|
|
26
|
+
getVersion: vi.fn(),
|
|
27
|
+
}));
|
|
28
|
+
|
|
29
|
+
vi.mock("../../src/utils/copy-src", () => ({
|
|
30
|
+
copySrcFiles: vi.fn().mockResolvedValue(undefined),
|
|
31
|
+
}));
|
|
32
|
+
|
|
33
|
+
vi.mock("../../src/utils/output-utils", () => ({
|
|
34
|
+
formatBuildMessages: vi.fn(
|
|
35
|
+
(name: string, target: string, msgs: string[]) => `${name} (${target}): ${msgs.join(", ")}`,
|
|
36
|
+
),
|
|
37
|
+
}));
|
|
38
|
+
|
|
39
|
+
vi.mock("../../src/utils/typecheck-serialization", () => ({
|
|
40
|
+
deserializeDiagnostic: vi.fn((d: any) => d),
|
|
41
|
+
}));
|
|
42
|
+
|
|
43
|
+
vi.mock("@simplysm/core-node", () => ({
|
|
44
|
+
Worker: {
|
|
45
|
+
create: vi.fn(),
|
|
46
|
+
},
|
|
47
|
+
fsx: {
|
|
48
|
+
rm: vi.fn().mockResolvedValue(undefined),
|
|
49
|
+
},
|
|
50
|
+
}));
|
|
51
|
+
|
|
52
|
+
const mockEngines: Array<{
|
|
53
|
+
run: ReturnType<typeof vi.fn>;
|
|
54
|
+
startWatch: ReturnType<typeof vi.fn>;
|
|
55
|
+
stop: ReturnType<typeof vi.fn>;
|
|
56
|
+
}> = [];
|
|
57
|
+
|
|
58
|
+
vi.mock("../../src/engines/index", () => ({
|
|
59
|
+
createBuildEngine: vi.fn(() => {
|
|
60
|
+
const engine = {
|
|
61
|
+
run: vi.fn().mockResolvedValue({
|
|
62
|
+
success: true,
|
|
63
|
+
js: { success: true, errors: [], warnings: [] },
|
|
64
|
+
dts: { success: true, errors: [], warnings: [], diagnostics: [] },
|
|
65
|
+
}),
|
|
66
|
+
startWatch: vi.fn().mockResolvedValue(undefined),
|
|
67
|
+
stop: vi.fn().mockResolvedValue(undefined),
|
|
68
|
+
};
|
|
69
|
+
mockEngines.push(engine);
|
|
70
|
+
return engine;
|
|
71
|
+
}),
|
|
72
|
+
}));
|
|
73
|
+
|
|
74
|
+
// --- Dynamic imports after mocking ---
|
|
75
|
+
|
|
76
|
+
const { BuildOrchestrator, classifyPackages } = await import("../../src/orchestrators/BuildOrchestrator");
|
|
77
|
+
const { loadSdConfig } = await import("../../src/utils/sd-config");
|
|
78
|
+
const { getVersion } = await import("../../src/utils/build-env");
|
|
79
|
+
const { copySrcFiles } = await import("../../src/utils/copy-src");
|
|
80
|
+
const { Worker, fsx } = await import("@simplysm/core-node");
|
|
81
|
+
const { createBuildEngine } = await import("../../src/engines/index");
|
|
82
|
+
|
|
83
|
+
import type { SdConfig } from "../../src/sd-config.types";
|
|
84
|
+
|
|
85
|
+
// --- Helpers ---
|
|
86
|
+
|
|
87
|
+
interface MockWorkerProxy {
|
|
88
|
+
build: ReturnType<typeof vi.fn>;
|
|
89
|
+
lint: ReturnType<typeof vi.fn>;
|
|
90
|
+
terminate: ReturnType<typeof vi.fn>;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function createMockWorkerProxy(overrides: Partial<MockWorkerProxy> = {}): MockWorkerProxy {
|
|
94
|
+
return {
|
|
95
|
+
build: vi.fn().mockResolvedValue({ success: true, errors: [], warnings: [], diagnostics: [] }),
|
|
96
|
+
lint: vi.fn().mockResolvedValue({ success: true }),
|
|
97
|
+
terminate: vi.fn().mockResolvedValue(undefined),
|
|
98
|
+
...overrides,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function setupDefaults(config: Partial<SdConfig> = {}): void {
|
|
103
|
+
vi.mocked(loadSdConfig).mockResolvedValue({ packages: {}, ...config } as SdConfig);
|
|
104
|
+
vi.mocked(getVersion).mockResolvedValue("1.0.0");
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// --- Tests ---
|
|
108
|
+
|
|
109
|
+
beforeEach(() => {
|
|
110
|
+
vi.clearAllMocks();
|
|
111
|
+
mockEngines.length = 0;
|
|
112
|
+
// Reset process.exitCode
|
|
113
|
+
process.exitCode = undefined;
|
|
114
|
+
// Mock process.stdout.write
|
|
115
|
+
vi.spyOn(process.stdout, "write").mockReturnValue(true);
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
describe("BuildOrchestrator.initialize", () => {
|
|
119
|
+
it("loads sd.config.ts with dev=false and classifies packages", async () => {
|
|
120
|
+
setupDefaults({
|
|
121
|
+
packages: {
|
|
122
|
+
"core-common": { target: "neutral", publish: { type: "npm" } },
|
|
123
|
+
"demo-server": { target: "server" },
|
|
124
|
+
},
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
const orchestrator = new BuildOrchestrator({ targets: [], options: [] });
|
|
128
|
+
await orchestrator.initialize();
|
|
129
|
+
|
|
130
|
+
expect(loadSdConfig).toHaveBeenCalledWith(
|
|
131
|
+
expect.objectContaining({ dev: false }),
|
|
132
|
+
);
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
it("throws and sets exitCode=1 when sd.config.ts load fails", async () => {
|
|
136
|
+
vi.mocked(loadSdConfig).mockRejectedValue(new Error("syntax error"));
|
|
137
|
+
vi.mocked(getVersion).mockResolvedValue("1.0.0");
|
|
138
|
+
|
|
139
|
+
const orchestrator = new BuildOrchestrator({ targets: [], options: [] });
|
|
140
|
+
await expect(orchestrator.initialize()).rejects.toThrow("syntax error");
|
|
141
|
+
expect(process.exitCode).toBe(1);
|
|
142
|
+
expect(mockLogger.error).toHaveBeenCalled();
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
it("prepares VER and DEV environment variables", async () => {
|
|
146
|
+
setupDefaults({
|
|
147
|
+
packages: {
|
|
148
|
+
"core-common": { target: "neutral", publish: { type: "npm" } },
|
|
149
|
+
},
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
const orchestrator = new BuildOrchestrator({ targets: [], options: [] });
|
|
153
|
+
await orchestrator.initialize();
|
|
154
|
+
|
|
155
|
+
expect(getVersion).toHaveBeenCalled();
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
it("passes options to loadSdConfig", async () => {
|
|
159
|
+
setupDefaults();
|
|
160
|
+
|
|
161
|
+
const orchestrator = new BuildOrchestrator({ targets: [], options: ["production"] });
|
|
162
|
+
await orchestrator.initialize();
|
|
163
|
+
|
|
164
|
+
expect(loadSdConfig).toHaveBeenCalledWith(
|
|
165
|
+
expect.objectContaining({ options: ["production"] }),
|
|
166
|
+
);
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
it("outputs message when no packages to build", async () => {
|
|
170
|
+
setupDefaults({
|
|
171
|
+
packages: {
|
|
172
|
+
"sd-claude": { target: "scripts" } as any,
|
|
173
|
+
},
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
const orchestrator = new BuildOrchestrator({ targets: [], options: [] });
|
|
177
|
+
await orchestrator.initialize();
|
|
178
|
+
|
|
179
|
+
expect(process.stdout.write).toHaveBeenCalledWith(
|
|
180
|
+
expect.stringContaining("No packages to build"),
|
|
181
|
+
);
|
|
182
|
+
});
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
describe("BuildOrchestrator.start", () => {
|
|
186
|
+
it("cleans dist folders before building", async () => {
|
|
187
|
+
setupDefaults({
|
|
188
|
+
packages: {
|
|
189
|
+
"core-common": { target: "neutral", publish: { type: "npm" } },
|
|
190
|
+
},
|
|
191
|
+
});
|
|
192
|
+
const mockProxy = createMockWorkerProxy();
|
|
193
|
+
vi.mocked(Worker.create).mockReturnValue(mockProxy as any);
|
|
194
|
+
|
|
195
|
+
const orchestrator = new BuildOrchestrator({ targets: [], options: [] });
|
|
196
|
+
await orchestrator.initialize();
|
|
197
|
+
await orchestrator.start();
|
|
198
|
+
|
|
199
|
+
expect(fsx.rm).toHaveBeenCalledWith(
|
|
200
|
+
expect.stringContaining("core-common"),
|
|
201
|
+
);
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
it("uses BuildEngine for buildPackages", async () => {
|
|
205
|
+
setupDefaults({
|
|
206
|
+
packages: {
|
|
207
|
+
"core-common": { target: "browser", publish: { type: "npm" } },
|
|
208
|
+
},
|
|
209
|
+
});
|
|
210
|
+
const mockProxy = createMockWorkerProxy();
|
|
211
|
+
vi.mocked(Worker.create).mockReturnValue(mockProxy as any);
|
|
212
|
+
|
|
213
|
+
const orchestrator = new BuildOrchestrator({ targets: [], options: [] });
|
|
214
|
+
await orchestrator.initialize();
|
|
215
|
+
await orchestrator.start();
|
|
216
|
+
|
|
217
|
+
// BuildEngine should be created and run() called
|
|
218
|
+
expect(createBuildEngine).toHaveBeenCalledOnce();
|
|
219
|
+
expect(mockEngines[0].run).toHaveBeenCalledWith({ js: true, dts: true });
|
|
220
|
+
expect(mockEngines[0].stop).toHaveBeenCalled();
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
it("creates BuildEngine for serverPackages with merged env", async () => {
|
|
224
|
+
setupDefaults({
|
|
225
|
+
packages: {
|
|
226
|
+
"demo-server": {
|
|
227
|
+
target: "server",
|
|
228
|
+
env: { DB_HOST: "localhost" },
|
|
229
|
+
},
|
|
230
|
+
},
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
const orchestrator = new BuildOrchestrator({ targets: [], options: [] });
|
|
234
|
+
await orchestrator.initialize();
|
|
235
|
+
await orchestrator.start();
|
|
236
|
+
|
|
237
|
+
expect(createBuildEngine).toHaveBeenCalledWith(
|
|
238
|
+
expect.objectContaining({
|
|
239
|
+
name: "demo-server",
|
|
240
|
+
config: expect.objectContaining({
|
|
241
|
+
target: "server",
|
|
242
|
+
env: expect.objectContaining({
|
|
243
|
+
VER: "1.0.0",
|
|
244
|
+
DEV: "false",
|
|
245
|
+
DB_HOST: "localhost",
|
|
246
|
+
}),
|
|
247
|
+
}),
|
|
248
|
+
}),
|
|
249
|
+
expect.any(Object),
|
|
250
|
+
);
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
it("creates BuildEngine for serverPackages with pm2 config", async () => {
|
|
254
|
+
setupDefaults({
|
|
255
|
+
packages: {
|
|
256
|
+
"demo-server": {
|
|
257
|
+
target: "server",
|
|
258
|
+
pm2: { name: "demo" },
|
|
259
|
+
},
|
|
260
|
+
},
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
const orchestrator = new BuildOrchestrator({ targets: [], options: [] });
|
|
264
|
+
await orchestrator.initialize();
|
|
265
|
+
await orchestrator.start();
|
|
266
|
+
|
|
267
|
+
expect(createBuildEngine).toHaveBeenCalledWith(
|
|
268
|
+
expect.objectContaining({
|
|
269
|
+
config: expect.objectContaining({
|
|
270
|
+
pm2: { name: "demo" },
|
|
271
|
+
}),
|
|
272
|
+
}),
|
|
273
|
+
expect.any(Object),
|
|
274
|
+
);
|
|
275
|
+
});
|
|
276
|
+
|
|
277
|
+
it("calls copySrcFiles when copySrc is configured", async () => {
|
|
278
|
+
setupDefaults({
|
|
279
|
+
packages: {
|
|
280
|
+
"core-node": {
|
|
281
|
+
target: "node",
|
|
282
|
+
publish: { type: "npm" },
|
|
283
|
+
copySrc: ["README.md"],
|
|
284
|
+
},
|
|
285
|
+
},
|
|
286
|
+
});
|
|
287
|
+
const mockProxy = createMockWorkerProxy();
|
|
288
|
+
vi.mocked(Worker.create).mockReturnValue(mockProxy as any);
|
|
289
|
+
|
|
290
|
+
const orchestrator = new BuildOrchestrator({ targets: [], options: [] });
|
|
291
|
+
await orchestrator.initialize();
|
|
292
|
+
await orchestrator.start();
|
|
293
|
+
|
|
294
|
+
expect(copySrcFiles).toHaveBeenCalled();
|
|
295
|
+
});
|
|
296
|
+
|
|
297
|
+
it("does not call copySrcFiles when copySrc is not configured", async () => {
|
|
298
|
+
setupDefaults({
|
|
299
|
+
packages: {
|
|
300
|
+
"core-common": { target: "neutral", publish: { type: "npm" } },
|
|
301
|
+
},
|
|
302
|
+
});
|
|
303
|
+
const mockProxy = createMockWorkerProxy();
|
|
304
|
+
vi.mocked(Worker.create).mockReturnValue(mockProxy as any);
|
|
305
|
+
|
|
306
|
+
const orchestrator = new BuildOrchestrator({ targets: [], options: [] });
|
|
307
|
+
await orchestrator.initialize();
|
|
308
|
+
await orchestrator.start();
|
|
309
|
+
|
|
310
|
+
expect(copySrcFiles).not.toHaveBeenCalled();
|
|
311
|
+
});
|
|
312
|
+
|
|
313
|
+
it("stops engine even when build fails", async () => {
|
|
314
|
+
setupDefaults({
|
|
315
|
+
packages: {
|
|
316
|
+
"core-common": { target: "neutral", publish: { type: "npm" } },
|
|
317
|
+
},
|
|
318
|
+
});
|
|
319
|
+
// Override createBuildEngine to return engine with failing run()
|
|
320
|
+
vi.mocked(createBuildEngine).mockReturnValue({
|
|
321
|
+
run: vi.fn().mockRejectedValue(new Error("build failed")),
|
|
322
|
+
startWatch: vi.fn(),
|
|
323
|
+
stop: vi.fn().mockResolvedValue(undefined),
|
|
324
|
+
} as any);
|
|
325
|
+
const mockProxy = createMockWorkerProxy();
|
|
326
|
+
vi.mocked(Worker.create).mockReturnValue(mockProxy as any);
|
|
327
|
+
|
|
328
|
+
const orchestrator = new BuildOrchestrator({ targets: [], options: [] });
|
|
329
|
+
await orchestrator.initialize();
|
|
330
|
+
await orchestrator.start();
|
|
331
|
+
|
|
332
|
+
// Engine stop should be called even after failure
|
|
333
|
+
const engineMock = vi.mocked(createBuildEngine).mock.results[0].value;
|
|
334
|
+
expect(engineMock.stop).toHaveBeenCalled();
|
|
335
|
+
});
|
|
336
|
+
|
|
337
|
+
it("returns false when all builds succeed", async () => {
|
|
338
|
+
setupDefaults({
|
|
339
|
+
packages: {
|
|
340
|
+
"core-common": { target: "neutral", publish: { type: "npm" } },
|
|
341
|
+
},
|
|
342
|
+
});
|
|
343
|
+
const mockProxy = createMockWorkerProxy();
|
|
344
|
+
vi.mocked(Worker.create).mockReturnValue(mockProxy as any);
|
|
345
|
+
|
|
346
|
+
const orchestrator = new BuildOrchestrator({ targets: [], options: [] });
|
|
347
|
+
await orchestrator.initialize();
|
|
348
|
+
const hasError = await orchestrator.start();
|
|
349
|
+
|
|
350
|
+
expect(hasError).toBe(false);
|
|
351
|
+
expect(mockLogger.info).toHaveBeenCalledWith("Build completed");
|
|
352
|
+
});
|
|
353
|
+
|
|
354
|
+
it("returns true and logs error when any build fails", async () => {
|
|
355
|
+
setupDefaults({
|
|
356
|
+
packages: {
|
|
357
|
+
"core-common": { target: "neutral", publish: { type: "npm" } },
|
|
358
|
+
},
|
|
359
|
+
});
|
|
360
|
+
vi.mocked(createBuildEngine).mockReturnValue({
|
|
361
|
+
run: vi.fn().mockResolvedValue({
|
|
362
|
+
success: false,
|
|
363
|
+
js: { success: false, errors: ["Module not found"], warnings: [] },
|
|
364
|
+
dts: { success: true, errors: [], warnings: [], diagnostics: [] },
|
|
365
|
+
}),
|
|
366
|
+
startWatch: vi.fn(),
|
|
367
|
+
stop: vi.fn().mockResolvedValue(undefined),
|
|
368
|
+
} as any);
|
|
369
|
+
const mockProxy = createMockWorkerProxy();
|
|
370
|
+
vi.mocked(Worker.create).mockReturnValue(mockProxy as any);
|
|
371
|
+
|
|
372
|
+
const orchestrator = new BuildOrchestrator({ targets: [], options: [] });
|
|
373
|
+
await orchestrator.initialize();
|
|
374
|
+
const hasError = await orchestrator.start();
|
|
375
|
+
|
|
376
|
+
expect(hasError).toBe(true);
|
|
377
|
+
expect(mockLogger.error).toHaveBeenCalledWith("Build failed");
|
|
378
|
+
});
|
|
379
|
+
|
|
380
|
+
it("returns false when no packages to build", async () => {
|
|
381
|
+
setupDefaults({
|
|
382
|
+
packages: {
|
|
383
|
+
"sd-claude": { target: "scripts" } as any,
|
|
384
|
+
},
|
|
385
|
+
});
|
|
386
|
+
|
|
387
|
+
const orchestrator = new BuildOrchestrator({ targets: [], options: [] });
|
|
388
|
+
await orchestrator.initialize();
|
|
389
|
+
const hasError = await orchestrator.start();
|
|
390
|
+
|
|
391
|
+
expect(hasError).toBe(false);
|
|
392
|
+
});
|
|
393
|
+
|
|
394
|
+
it("limits concurrent build engine workers to maxConcurrency", async () => {
|
|
395
|
+
// Use enough packages to exceed any reasonable CPU-based concurrency limit
|
|
396
|
+
const pkgCount = 50;
|
|
397
|
+
const packages: Record<string, any> = {};
|
|
398
|
+
for (let i = 0; i < pkgCount; i++) {
|
|
399
|
+
packages[`pkg-${i}`] = { target: "neutral", publish: { type: "npm" } };
|
|
400
|
+
}
|
|
401
|
+
setupDefaults({ packages });
|
|
402
|
+
|
|
403
|
+
let active = 0;
|
|
404
|
+
let maxActive = 0;
|
|
405
|
+
|
|
406
|
+
vi.mocked(createBuildEngine).mockImplementation(() => {
|
|
407
|
+
const engine = {
|
|
408
|
+
run: vi.fn(async () => {
|
|
409
|
+
active++;
|
|
410
|
+
maxActive = Math.max(maxActive, active);
|
|
411
|
+
await new Promise((resolve) => setTimeout(resolve, 5));
|
|
412
|
+
active--;
|
|
413
|
+
return {
|
|
414
|
+
success: true,
|
|
415
|
+
js: { success: true, errors: [], warnings: [] },
|
|
416
|
+
dts: { success: true, errors: [], warnings: [], diagnostics: [] },
|
|
417
|
+
};
|
|
418
|
+
}),
|
|
419
|
+
startWatch: vi.fn(),
|
|
420
|
+
stop: vi.fn().mockResolvedValue(undefined),
|
|
421
|
+
};
|
|
422
|
+
mockEngines.push(engine);
|
|
423
|
+
return engine as any;
|
|
424
|
+
});
|
|
425
|
+
const mockProxy = createMockWorkerProxy();
|
|
426
|
+
vi.mocked(Worker.create).mockReturnValue(mockProxy as any);
|
|
427
|
+
|
|
428
|
+
const orchestrator = new BuildOrchestrator({ targets: [], options: [] });
|
|
429
|
+
await orchestrator.initialize();
|
|
430
|
+
await orchestrator.start();
|
|
431
|
+
|
|
432
|
+
// Without concurrency limit, all 50 would start simultaneously (maxActive = 50)
|
|
433
|
+
// With limit, maxActive should be < pkgCount
|
|
434
|
+
expect(maxActive).toBeLessThan(pkgCount);
|
|
435
|
+
expect(maxActive).toBeGreaterThan(0);
|
|
436
|
+
expect(mockEngines).toHaveLength(pkgCount);
|
|
437
|
+
expect(mockEngines.every((e) => e.stop.mock.calls.length > 0)).toBe(true);
|
|
438
|
+
});
|
|
439
|
+
|
|
440
|
+
it("runs lint independently of build concurrency limit", async () => {
|
|
441
|
+
const packages: Record<string, any> = {};
|
|
442
|
+
for (let i = 0; i < 5; i++) {
|
|
443
|
+
packages[`pkg-${i}`] = { target: "neutral", publish: { type: "npm" } };
|
|
444
|
+
}
|
|
445
|
+
setupDefaults({ packages });
|
|
446
|
+
|
|
447
|
+
let lintStarted = false;
|
|
448
|
+
let buildCompletedCount = 0;
|
|
449
|
+
|
|
450
|
+
vi.mocked(createBuildEngine).mockImplementation(() => {
|
|
451
|
+
const engine = {
|
|
452
|
+
run: vi.fn(async () => {
|
|
453
|
+
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
454
|
+
buildCompletedCount++;
|
|
455
|
+
return {
|
|
456
|
+
success: true,
|
|
457
|
+
js: { success: true, errors: [], warnings: [] },
|
|
458
|
+
dts: { success: true, errors: [], warnings: [], diagnostics: [] },
|
|
459
|
+
};
|
|
460
|
+
}),
|
|
461
|
+
startWatch: vi.fn(),
|
|
462
|
+
stop: vi.fn().mockResolvedValue(undefined),
|
|
463
|
+
};
|
|
464
|
+
mockEngines.push(engine);
|
|
465
|
+
return engine as any;
|
|
466
|
+
});
|
|
467
|
+
|
|
468
|
+
const mockProxy = createMockWorkerProxy({
|
|
469
|
+
lint: vi.fn(() => {
|
|
470
|
+
lintStarted = true;
|
|
471
|
+
// Lint starts immediately, not blocked by build concurrency
|
|
472
|
+
expect(buildCompletedCount).toBe(0);
|
|
473
|
+
return { success: true };
|
|
474
|
+
}),
|
|
475
|
+
});
|
|
476
|
+
vi.mocked(Worker.create).mockReturnValue(mockProxy as any);
|
|
477
|
+
|
|
478
|
+
const orchestrator = new BuildOrchestrator({ targets: [], options: [] });
|
|
479
|
+
await orchestrator.initialize();
|
|
480
|
+
await orchestrator.start();
|
|
481
|
+
|
|
482
|
+
expect(lintStarted).toBe(true);
|
|
483
|
+
});
|
|
484
|
+
|
|
485
|
+
it("logs warnings from build results", async () => {
|
|
486
|
+
setupDefaults({
|
|
487
|
+
packages: {
|
|
488
|
+
"core-common": { target: "neutral", publish: { type: "npm" } },
|
|
489
|
+
},
|
|
490
|
+
});
|
|
491
|
+
vi.mocked(createBuildEngine).mockReturnValue({
|
|
492
|
+
run: vi.fn().mockResolvedValue({
|
|
493
|
+
success: true,
|
|
494
|
+
js: { success: true, errors: [], warnings: ["Unused variable"] },
|
|
495
|
+
dts: { success: true, errors: [], warnings: [], diagnostics: [] },
|
|
496
|
+
}),
|
|
497
|
+
startWatch: vi.fn(),
|
|
498
|
+
stop: vi.fn().mockResolvedValue(undefined),
|
|
499
|
+
} as any);
|
|
500
|
+
const mockProxy = createMockWorkerProxy();
|
|
501
|
+
vi.mocked(Worker.create).mockReturnValue(mockProxy as any);
|
|
502
|
+
|
|
503
|
+
const orchestrator = new BuildOrchestrator({ targets: [], options: [] });
|
|
504
|
+
await orchestrator.initialize();
|
|
505
|
+
await orchestrator.start();
|
|
506
|
+
|
|
507
|
+
expect(mockLogger.warn).toHaveBeenCalled();
|
|
508
|
+
});
|
|
509
|
+
});
|
|
510
|
+
|
|
511
|
+
describe("classifyPackages", () => {
|
|
512
|
+
// Acceptance: Scenario "client target 패키지 분류"
|
|
513
|
+
it("classifies client target packages to clientPackages", () => {
|
|
514
|
+
const result = classifyPackages(
|
|
515
|
+
{ "my-client": { target: "client", server: "my-server" } as any },
|
|
516
|
+
[],
|
|
517
|
+
);
|
|
518
|
+
expect(result.clientPackages).toHaveLength(1);
|
|
519
|
+
expect(result.clientPackages[0].name).toBe("my-client");
|
|
520
|
+
expect(result.clientPackages[0].config.target).toBe("client");
|
|
521
|
+
});
|
|
522
|
+
|
|
523
|
+
// Acceptance: Scenario "targets 필터로 특정 client 패키지만 분류"
|
|
524
|
+
it("filters clientPackages by targets", () => {
|
|
525
|
+
const result = classifyPackages(
|
|
526
|
+
{
|
|
527
|
+
"client-a": { target: "client", server: "srv" } as any,
|
|
528
|
+
"client-b": { target: "client", server: "srv" } as any,
|
|
529
|
+
},
|
|
530
|
+
["client-a"],
|
|
531
|
+
);
|
|
532
|
+
expect(result.clientPackages).toHaveLength(1);
|
|
533
|
+
expect(result.clientPackages[0].name).toBe("client-a");
|
|
534
|
+
});
|
|
535
|
+
|
|
536
|
+
// Acceptance: Scenario "targets 필터에 미포함된 client 패키지 제외"
|
|
537
|
+
it("excludes client packages not in targets", () => {
|
|
538
|
+
const result = classifyPackages(
|
|
539
|
+
{ "my-client": { target: "client", server: "srv" } as any },
|
|
540
|
+
["other-pkg"],
|
|
541
|
+
);
|
|
542
|
+
expect(result.clientPackages).toHaveLength(0);
|
|
543
|
+
});
|
|
544
|
+
|
|
545
|
+
// Acceptance: Scenario "scripts target은 여전히 제외"
|
|
546
|
+
it("still excludes scripts target", () => {
|
|
547
|
+
const result = classifyPackages(
|
|
548
|
+
{ "sd-claude": { target: "scripts" } },
|
|
549
|
+
[],
|
|
550
|
+
);
|
|
551
|
+
expect(result.buildPackages).toHaveLength(0);
|
|
552
|
+
expect(result.serverPackages).toHaveLength(0);
|
|
553
|
+
expect(result.clientPackages).toHaveLength(0);
|
|
554
|
+
});
|
|
555
|
+
|
|
556
|
+
// Acceptance: Scenario "client 패키지가 0개인 경우"
|
|
557
|
+
it("returns empty clientPackages when no client packages exist", () => {
|
|
558
|
+
const result = classifyPackages(
|
|
559
|
+
{
|
|
560
|
+
"core-common": { target: "neutral", publish: { type: "npm" } } as any,
|
|
561
|
+
"demo-server": { target: "server" } as any,
|
|
562
|
+
},
|
|
563
|
+
[],
|
|
564
|
+
);
|
|
565
|
+
expect(result.clientPackages).toHaveLength(0);
|
|
566
|
+
expect(result.buildPackages).toHaveLength(1);
|
|
567
|
+
expect(result.serverPackages).toHaveLength(1);
|
|
568
|
+
});
|
|
569
|
+
|
|
570
|
+
// Unit: mixed packages — all types classified correctly
|
|
571
|
+
it("correctly classifies all package types together", () => {
|
|
572
|
+
const result = classifyPackages(
|
|
573
|
+
{
|
|
574
|
+
"core-common": { target: "neutral", publish: { type: "npm" } } as any,
|
|
575
|
+
"demo-server": { target: "server" } as any,
|
|
576
|
+
"my-client": { target: "client", server: "srv" } as any,
|
|
577
|
+
"sd-claude": { target: "scripts" },
|
|
578
|
+
},
|
|
579
|
+
[],
|
|
580
|
+
);
|
|
581
|
+
expect(result.buildPackages).toHaveLength(1);
|
|
582
|
+
expect(result.buildPackages[0].name).toBe("core-common");
|
|
583
|
+
expect(result.serverPackages).toHaveLength(1);
|
|
584
|
+
expect(result.serverPackages[0].name).toBe("demo-server");
|
|
585
|
+
expect(result.clientPackages).toHaveLength(1);
|
|
586
|
+
expect(result.clientPackages[0].name).toBe("my-client");
|
|
587
|
+
});
|
|
588
|
+
});
|
|
589
|
+
|
|
590
|
+
describe("BuildOrchestrator client build", () => {
|
|
591
|
+
// Acceptance: Scenario "client 패키지 프로덕션 빌드 성공"
|
|
592
|
+
it("uses ViteEngine for client packages with js:true dts:false", async () => {
|
|
593
|
+
setupDefaults({
|
|
594
|
+
packages: {
|
|
595
|
+
"my-client": { target: "client", server: "my-server" } as any,
|
|
596
|
+
},
|
|
597
|
+
});
|
|
598
|
+
vi.mocked(createBuildEngine).mockReturnValue({
|
|
599
|
+
run: vi.fn().mockResolvedValue({
|
|
600
|
+
success: true,
|
|
601
|
+
js: { success: true, errors: [], warnings: [] },
|
|
602
|
+
dts: { success: true, errors: [], warnings: [], diagnostics: [] },
|
|
603
|
+
}),
|
|
604
|
+
startWatch: vi.fn(),
|
|
605
|
+
stop: vi.fn().mockResolvedValue(undefined),
|
|
606
|
+
} as any);
|
|
607
|
+
const mockProxy = createMockWorkerProxy();
|
|
608
|
+
vi.mocked(Worker.create).mockReturnValue(mockProxy as any);
|
|
609
|
+
|
|
610
|
+
const orchestrator = new BuildOrchestrator({ targets: [], options: [] });
|
|
611
|
+
await orchestrator.initialize();
|
|
612
|
+
await orchestrator.start();
|
|
613
|
+
|
|
614
|
+
expect(createBuildEngine).toHaveBeenCalledWith(
|
|
615
|
+
expect.objectContaining({
|
|
616
|
+
name: "my-client",
|
|
617
|
+
config: expect.objectContaining({ target: "client" }),
|
|
618
|
+
}),
|
|
619
|
+
expect.any(Object),
|
|
620
|
+
);
|
|
621
|
+
const engineMock = vi.mocked(createBuildEngine).mock.results[0].value;
|
|
622
|
+
expect(engineMock.run).toHaveBeenCalledWith({ js: true, dts: false });
|
|
623
|
+
expect(engineMock.stop).toHaveBeenCalled();
|
|
624
|
+
});
|
|
625
|
+
|
|
626
|
+
// Acceptance: Scenario "client 패키지 빌드 실패"
|
|
627
|
+
it("returns true when client build fails", async () => {
|
|
628
|
+
setupDefaults({
|
|
629
|
+
packages: {
|
|
630
|
+
"my-client": { target: "client", server: "my-server" } as any,
|
|
631
|
+
},
|
|
632
|
+
});
|
|
633
|
+
vi.mocked(createBuildEngine).mockReturnValue({
|
|
634
|
+
run: vi.fn().mockResolvedValue({
|
|
635
|
+
success: false,
|
|
636
|
+
js: { success: false, errors: ["Template error"], warnings: [] },
|
|
637
|
+
dts: { success: true, errors: [], warnings: [], diagnostics: [] },
|
|
638
|
+
}),
|
|
639
|
+
startWatch: vi.fn(),
|
|
640
|
+
stop: vi.fn().mockResolvedValue(undefined),
|
|
641
|
+
} as any);
|
|
642
|
+
const mockProxy = createMockWorkerProxy();
|
|
643
|
+
vi.mocked(Worker.create).mockReturnValue(mockProxy as any);
|
|
644
|
+
|
|
645
|
+
const orchestrator = new BuildOrchestrator({ targets: [], options: [] });
|
|
646
|
+
await orchestrator.initialize();
|
|
647
|
+
const hasError = await orchestrator.start();
|
|
648
|
+
|
|
649
|
+
expect(hasError).toBe(true);
|
|
650
|
+
expect(mockLogger.error).toHaveBeenCalledWith("Build failed");
|
|
651
|
+
});
|
|
652
|
+
|
|
653
|
+
// Acceptance: Scenario "client 빌드에 env 주입하지 않음"
|
|
654
|
+
it("does not inject baseEnv for client packages", async () => {
|
|
655
|
+
setupDefaults({
|
|
656
|
+
packages: {
|
|
657
|
+
"my-client": { target: "client", server: "my-server" } as any,
|
|
658
|
+
},
|
|
659
|
+
});
|
|
660
|
+
const mockProxy = createMockWorkerProxy();
|
|
661
|
+
vi.mocked(Worker.create).mockReturnValue(mockProxy as any);
|
|
662
|
+
|
|
663
|
+
const orchestrator = new BuildOrchestrator({ targets: [], options: [] });
|
|
664
|
+
await orchestrator.initialize();
|
|
665
|
+
await orchestrator.start();
|
|
666
|
+
|
|
667
|
+
const callArgs = vi.mocked(createBuildEngine).mock.calls[0][0];
|
|
668
|
+
expect(callArgs.config).not.toHaveProperty("env");
|
|
669
|
+
});
|
|
670
|
+
|
|
671
|
+
// Acceptance: Scenario "client 패키지 dist 폴더 clean"
|
|
672
|
+
it("cleans client package dist folder before building", async () => {
|
|
673
|
+
setupDefaults({
|
|
674
|
+
packages: {
|
|
675
|
+
"my-client": { target: "client", server: "my-server" } as any,
|
|
676
|
+
},
|
|
677
|
+
});
|
|
678
|
+
const mockProxy = createMockWorkerProxy();
|
|
679
|
+
vi.mocked(Worker.create).mockReturnValue(mockProxy as any);
|
|
680
|
+
|
|
681
|
+
const orchestrator = new BuildOrchestrator({ targets: [], options: [] });
|
|
682
|
+
await orchestrator.initialize();
|
|
683
|
+
await orchestrator.start();
|
|
684
|
+
|
|
685
|
+
expect(fsx.rm).toHaveBeenCalledWith(
|
|
686
|
+
expect.stringContaining("my-client"),
|
|
687
|
+
);
|
|
688
|
+
});
|
|
689
|
+
|
|
690
|
+
// Acceptance: Scenario "client 패키지 lint 포함"
|
|
691
|
+
it("includes client packages in lint targets", async () => {
|
|
692
|
+
setupDefaults({
|
|
693
|
+
packages: {
|
|
694
|
+
"my-client": { target: "client", server: "my-server" } as any,
|
|
695
|
+
},
|
|
696
|
+
});
|
|
697
|
+
const mockProxy = createMockWorkerProxy();
|
|
698
|
+
vi.mocked(Worker.create).mockReturnValue(mockProxy as any);
|
|
699
|
+
|
|
700
|
+
const orchestrator = new BuildOrchestrator({ targets: [], options: [] });
|
|
701
|
+
await orchestrator.initialize();
|
|
702
|
+
await orchestrator.start();
|
|
703
|
+
|
|
704
|
+
expect(mockProxy.lint).toHaveBeenCalledWith(
|
|
705
|
+
expect.objectContaining({
|
|
706
|
+
targets: expect.arrayContaining(["packages/my-client"]),
|
|
707
|
+
}),
|
|
708
|
+
);
|
|
709
|
+
});
|
|
710
|
+
|
|
711
|
+
// Unit: client engine.stop() called even on failure
|
|
712
|
+
it("stops client engine even when build fails", async () => {
|
|
713
|
+
setupDefaults({
|
|
714
|
+
packages: {
|
|
715
|
+
"my-client": { target: "client", server: "my-server" } as any,
|
|
716
|
+
},
|
|
717
|
+
});
|
|
718
|
+
vi.mocked(createBuildEngine).mockReturnValue({
|
|
719
|
+
run: vi.fn().mockRejectedValue(new Error("build crashed")),
|
|
720
|
+
startWatch: vi.fn(),
|
|
721
|
+
stop: vi.fn().mockResolvedValue(undefined),
|
|
722
|
+
} as any);
|
|
723
|
+
const mockProxy = createMockWorkerProxy();
|
|
724
|
+
vi.mocked(Worker.create).mockReturnValue(mockProxy as any);
|
|
725
|
+
|
|
726
|
+
const orchestrator = new BuildOrchestrator({ targets: [], options: [] });
|
|
727
|
+
await orchestrator.initialize();
|
|
728
|
+
await orchestrator.start();
|
|
729
|
+
|
|
730
|
+
const engineMock = vi.mocked(createBuildEngine).mock.results[0].value;
|
|
731
|
+
expect(engineMock.stop).toHaveBeenCalled();
|
|
732
|
+
});
|
|
733
|
+
});
|
|
734
|
+
|
|
735
|
+
describe("BuildOrchestrator target validation", () => {
|
|
736
|
+
it("throws error for unknown target during initialize", async () => {
|
|
737
|
+
setupDefaults({
|
|
738
|
+
packages: {
|
|
739
|
+
"core-common": { target: "neutral", publish: { type: "npm" } },
|
|
740
|
+
},
|
|
741
|
+
});
|
|
742
|
+
|
|
743
|
+
const orchestrator = new BuildOrchestrator({ targets: ["nonexistent"], options: [] });
|
|
744
|
+
await expect(orchestrator.initialize()).rejects.toThrow("Unknown target: nonexistent");
|
|
745
|
+
});
|
|
746
|
+
|
|
747
|
+
it("passes with valid targets during initialize", async () => {
|
|
748
|
+
setupDefaults({
|
|
749
|
+
packages: {
|
|
750
|
+
"core-common": { target: "neutral", publish: { type: "npm" } },
|
|
751
|
+
},
|
|
752
|
+
});
|
|
753
|
+
const mockProxy = createMockWorkerProxy();
|
|
754
|
+
vi.mocked(Worker.create).mockReturnValue(mockProxy as any);
|
|
755
|
+
|
|
756
|
+
const orchestrator = new BuildOrchestrator({ targets: ["core-common"], options: [] });
|
|
757
|
+
await expect(orchestrator.initialize()).resolves.not.toThrow();
|
|
758
|
+
});
|
|
759
|
+
|
|
760
|
+
it("passes with empty targets during initialize", async () => {
|
|
761
|
+
setupDefaults({
|
|
762
|
+
packages: {
|
|
763
|
+
"core-common": { target: "neutral", publish: { type: "npm" } },
|
|
764
|
+
},
|
|
765
|
+
});
|
|
766
|
+
const mockProxy = createMockWorkerProxy();
|
|
767
|
+
vi.mocked(Worker.create).mockReturnValue(mockProxy as any);
|
|
768
|
+
|
|
769
|
+
const orchestrator = new BuildOrchestrator({ targets: [], options: [] });
|
|
770
|
+
await expect(orchestrator.initialize()).resolves.not.toThrow();
|
|
771
|
+
});
|
|
772
|
+
});
|