@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.
- 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
|
@@ -1,694 +0,0 @@
|
|
|
1
|
-
import path from "path";
|
|
2
|
-
import { fsx } from "@simplysm/core-node";
|
|
3
|
-
import { env } from "@simplysm/core-common";
|
|
4
|
-
import { consola } from "consola";
|
|
5
|
-
import sharp from "sharp";
|
|
6
|
-
import { execa } from "execa";
|
|
7
|
-
class CapacitorConfigError extends Error {
|
|
8
|
-
constructor(message) {
|
|
9
|
-
super(message);
|
|
10
|
-
this.name = "CapacitorConfigError";
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
class Capacitor {
|
|
14
|
-
constructor(_pkgPath, _config, npmConfig, _exclude) {
|
|
15
|
-
this._pkgPath = _pkgPath;
|
|
16
|
-
this._config = _config;
|
|
17
|
-
this._exclude = _exclude;
|
|
18
|
-
this._platforms = Object.keys(this._config.platform ?? {});
|
|
19
|
-
this._npmConfig = npmConfig;
|
|
20
|
-
this._capPath = path.resolve(this._pkgPath, ".capacitor");
|
|
21
|
-
}
|
|
22
|
-
static _ANDROID_KEYSTORE_FILE_NAME = "android.keystore";
|
|
23
|
-
static _LOCK_FILE_NAME = ".capacitor.lock";
|
|
24
|
-
static _logger = consola.withTag("sd:cli:capacitor");
|
|
25
|
-
static _utf8Decoder = new TextDecoder("utf-8", { fatal: true });
|
|
26
|
-
static _fallbackDecoder = new TextDecoder("euc-kr");
|
|
27
|
-
_capPath;
|
|
28
|
-
_platforms;
|
|
29
|
-
_npmConfig;
|
|
30
|
-
/**
|
|
31
|
-
* Create Capacitor instance (with configuration validation)
|
|
32
|
-
*/
|
|
33
|
-
static async create(pkgPath, config, exclude) {
|
|
34
|
-
Capacitor._validateConfig(config);
|
|
35
|
-
const npmConfig = await fsx.readJson(path.resolve(pkgPath, "package.json"));
|
|
36
|
-
return new Capacitor(pkgPath, config, npmConfig, exclude ?? []);
|
|
37
|
-
}
|
|
38
|
-
/**
|
|
39
|
-
* F5: Validate configuration
|
|
40
|
-
*/
|
|
41
|
-
static _validateConfig(config) {
|
|
42
|
-
if (typeof config.appId !== "string" || config.appId.trim() === "") {
|
|
43
|
-
throw new CapacitorConfigError("capacitor.appId is required.");
|
|
44
|
-
}
|
|
45
|
-
if (!/^[a-z][a-z0-9_]*(\.[a-z][a-z0-9_]*)+$/i.test(config.appId)) {
|
|
46
|
-
throw new CapacitorConfigError(`capacitor.appId format is invalid: ${config.appId}`);
|
|
47
|
-
}
|
|
48
|
-
if (typeof config.appName !== "string" || config.appName.trim() === "") {
|
|
49
|
-
throw new CapacitorConfigError("capacitor.appName is required.");
|
|
50
|
-
}
|
|
51
|
-
if (!/^[\p{L}\p{N} \-]+$/u.test(config.appName)) {
|
|
52
|
-
throw new CapacitorConfigError(`capacitor.appName contains invalid characters: ${config.appName}`);
|
|
53
|
-
}
|
|
54
|
-
if (config.platform != null) {
|
|
55
|
-
const platforms = Object.keys(config.platform);
|
|
56
|
-
for (const p of platforms) {
|
|
57
|
-
if (p !== "android") {
|
|
58
|
-
throw new CapacitorConfigError(`unsupported platform: ${p} (currently only android is supported)`);
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
/**
|
|
64
|
-
* Execute a Capacitor CLI command via npx
|
|
65
|
-
*/
|
|
66
|
-
async _execCap(args) {
|
|
67
|
-
return this._exec("npx", ["cap", ...args], this._capPath);
|
|
68
|
-
}
|
|
69
|
-
/**
|
|
70
|
-
* Execute capacitor-assets CLI command via npx
|
|
71
|
-
*/
|
|
72
|
-
async _execCapAssets(args) {
|
|
73
|
-
return this._exec("npx", ["capacitor-assets", ...args], this._capPath);
|
|
74
|
-
}
|
|
75
|
-
/**
|
|
76
|
-
* Execute command (with logging)
|
|
77
|
-
*/
|
|
78
|
-
async _exec(cmd, args, cwd) {
|
|
79
|
-
Capacitor._logger.debug(`executed command: ${cmd} ${args.join(" ")}`);
|
|
80
|
-
const result = await execa(cmd, args, { cwd, reject: false, encoding: "buffer" });
|
|
81
|
-
const stdout = Capacitor._decodeOutput(result.stdout);
|
|
82
|
-
if (result.exitCode !== 0) {
|
|
83
|
-
const stderr = Capacitor._decodeOutput(result.stderr);
|
|
84
|
-
throw new Error(`${cmd} ${args.join(" ")} failed (exit ${result.exitCode}): ${stderr || stdout}`);
|
|
85
|
-
}
|
|
86
|
-
Capacitor._logger.debug(`execution result: ${stdout}`);
|
|
87
|
-
return stdout;
|
|
88
|
-
}
|
|
89
|
-
/**
|
|
90
|
-
* Decode command output (UTF-8 first, fallback to EUC-KR for Windows CP949)
|
|
91
|
-
*/
|
|
92
|
-
static _decodeOutput(bytes) {
|
|
93
|
-
try {
|
|
94
|
-
return Capacitor._utf8Decoder.decode(bytes);
|
|
95
|
-
} catch {
|
|
96
|
-
return Capacitor._fallbackDecoder.decode(bytes);
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
/**
|
|
100
|
-
* F10: Acquire lock to prevent concurrent execution
|
|
101
|
-
*/
|
|
102
|
-
async _acquireLock() {
|
|
103
|
-
const lockPath = path.resolve(this._capPath, Capacitor._LOCK_FILE_NAME);
|
|
104
|
-
if (await fsx.exists(lockPath)) {
|
|
105
|
-
const lockContent = await fsx.read(lockPath);
|
|
106
|
-
throw new Error(
|
|
107
|
-
`Another Capacitor operation is in progress (PID: ${lockContent}). If there's an issue, delete the ${lockPath} file.`
|
|
108
|
-
);
|
|
109
|
-
}
|
|
110
|
-
await fsx.mkdir(this._capPath);
|
|
111
|
-
await fsx.write(lockPath, String(process.pid));
|
|
112
|
-
}
|
|
113
|
-
/**
|
|
114
|
-
* F10: Release lock
|
|
115
|
-
*/
|
|
116
|
-
async _releaseLock() {
|
|
117
|
-
const lockPath = path.resolve(this._capPath, Capacitor._LOCK_FILE_NAME);
|
|
118
|
-
await fsx.rm(lockPath);
|
|
119
|
-
}
|
|
120
|
-
/**
|
|
121
|
-
* F4: Validate external tools
|
|
122
|
-
*/
|
|
123
|
-
async _validateTools() {
|
|
124
|
-
const sdkPath = await this._findAndroidSdk();
|
|
125
|
-
if (sdkPath == null) {
|
|
126
|
-
throw new Error(
|
|
127
|
-
"Android SDK not found.\n1. Install Android Studio or\n2. Set ANDROID_HOME or ANDROID_SDK_ROOT environment variable."
|
|
128
|
-
);
|
|
129
|
-
}
|
|
130
|
-
if (this._platforms.includes("android")) {
|
|
131
|
-
const javaPath = await this._findJava21();
|
|
132
|
-
if (javaPath == null) {
|
|
133
|
-
Capacitor._logger.warn(
|
|
134
|
-
"Java 21 not found. Gradle may use embedded JDK or the build may fail."
|
|
135
|
-
);
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
/**
|
|
140
|
-
* Initialize Capacitor project
|
|
141
|
-
*
|
|
142
|
-
* 1. Create package.json and install dependencies
|
|
143
|
-
* 2. Create capacitor.config.ts
|
|
144
|
-
* 3. Add platform (android)
|
|
145
|
-
* 4. Set up icon
|
|
146
|
-
* 5. Configure Android native settings
|
|
147
|
-
* 6. Run cap sync or cap copy
|
|
148
|
-
*/
|
|
149
|
-
async initialize() {
|
|
150
|
-
await this._acquireLock();
|
|
151
|
-
try {
|
|
152
|
-
await this._validateTools();
|
|
153
|
-
const changed = await this._initCap();
|
|
154
|
-
await this._writeCapConf();
|
|
155
|
-
await this._addPlatforms();
|
|
156
|
-
await this._setupIcon();
|
|
157
|
-
if (this._platforms.includes("android")) {
|
|
158
|
-
await this._configureAndroid();
|
|
159
|
-
}
|
|
160
|
-
if (changed) {
|
|
161
|
-
await this._execCap(["sync"]);
|
|
162
|
-
} else {
|
|
163
|
-
await this._execCap(["copy"]);
|
|
164
|
-
}
|
|
165
|
-
} finally {
|
|
166
|
-
await this._releaseLock();
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
/**
|
|
170
|
-
* Build Android APK/AAB
|
|
171
|
-
*/
|
|
172
|
-
async build(outPath) {
|
|
173
|
-
await this._acquireLock();
|
|
174
|
-
try {
|
|
175
|
-
const buildType = this._config.debug ? "debug" : "release";
|
|
176
|
-
for (const platform of this._platforms) {
|
|
177
|
-
await this._execCap(["copy", platform]);
|
|
178
|
-
if (platform === "android") {
|
|
179
|
-
await this._buildAndroid(outPath, buildType);
|
|
180
|
-
} else {
|
|
181
|
-
throw new Error(`unsupported platform: ${platform}`);
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
} finally {
|
|
185
|
-
await this._releaseLock();
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
/**
|
|
189
|
-
* Run app on device (connect WebView to development server)
|
|
190
|
-
*/
|
|
191
|
-
async runOnDevice(url) {
|
|
192
|
-
if (url != null) {
|
|
193
|
-
this._validateUrl(url);
|
|
194
|
-
await this._updateServerUrl(url);
|
|
195
|
-
}
|
|
196
|
-
for (const platform of this._platforms) {
|
|
197
|
-
await this._execCap(["copy", platform]);
|
|
198
|
-
try {
|
|
199
|
-
await this._execCap(["run", platform]);
|
|
200
|
-
} catch (err) {
|
|
201
|
-
if (platform === "android") {
|
|
202
|
-
try {
|
|
203
|
-
await this._exec("adb", ["kill-server"], this._capPath);
|
|
204
|
-
} catch {
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
throw err;
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
/**
|
|
212
|
-
* F11: Validate URL
|
|
213
|
-
*/
|
|
214
|
-
_validateUrl(url) {
|
|
215
|
-
try {
|
|
216
|
-
const parsed = new URL(url);
|
|
217
|
-
if (!["http:", "https:"].includes(parsed.protocol)) {
|
|
218
|
-
throw new Error(`unsupported protocol: ${parsed.protocol}`);
|
|
219
|
-
}
|
|
220
|
-
} catch (err) {
|
|
221
|
-
if (err instanceof TypeError) {
|
|
222
|
-
throw new Error(`invalid URL: ${url}`);
|
|
223
|
-
}
|
|
224
|
-
throw err;
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
//#region Private - Initialization
|
|
228
|
-
/**
|
|
229
|
-
* Basic Capacitor project initialization (package.json, pnpm install, cap init)
|
|
230
|
-
*/
|
|
231
|
-
async _initCap() {
|
|
232
|
-
const depChanged = await this._setupNpmConf();
|
|
233
|
-
const nodeModulesExists = await fsx.exists(path.resolve(this._capPath, "node_modules"));
|
|
234
|
-
if (!depChanged && nodeModulesExists) return false;
|
|
235
|
-
const installResult = await this._exec("npm", ["install"], this._capPath);
|
|
236
|
-
Capacitor._logger.debug(`npm install completed: ${installResult}`);
|
|
237
|
-
const configPath = path.resolve(this._capPath, "capacitor.config.ts");
|
|
238
|
-
if (!await fsx.exists(configPath)) {
|
|
239
|
-
await this._execCap(["init", this._config.appId, this._config.appId]);
|
|
240
|
-
}
|
|
241
|
-
const wwwPath = path.resolve(this._capPath, "www");
|
|
242
|
-
await fsx.mkdir(wwwPath);
|
|
243
|
-
await fsx.write(
|
|
244
|
-
path.resolve(wwwPath, "index.html"),
|
|
245
|
-
"<!DOCTYPE html><html><head></head><body></body></html>"
|
|
246
|
-
);
|
|
247
|
-
return true;
|
|
248
|
-
}
|
|
249
|
-
/**
|
|
250
|
-
* Configure package.json
|
|
251
|
-
*/
|
|
252
|
-
async _setupNpmConf() {
|
|
253
|
-
const projNpmConfigPath = path.resolve(this._pkgPath, "../../package.json");
|
|
254
|
-
if (!await fsx.exists(projNpmConfigPath)) {
|
|
255
|
-
throw new Error(`root package.json not found: ${projNpmConfigPath}`);
|
|
256
|
-
}
|
|
257
|
-
const projNpmConfig = await fsx.readJson(projNpmConfigPath);
|
|
258
|
-
const capNpmConfPath = path.resolve(this._capPath, "package.json");
|
|
259
|
-
const orgCapNpmConf = await fsx.exists(capNpmConfPath) ? await fsx.readJson(capNpmConfPath) : { name: "", version: "" };
|
|
260
|
-
const capNpmConf = { ...orgCapNpmConf };
|
|
261
|
-
capNpmConf.name = this._config.appId;
|
|
262
|
-
capNpmConf.version = this._npmConfig.version;
|
|
263
|
-
if (projNpmConfig.volta != null) {
|
|
264
|
-
capNpmConf.volta = projNpmConfig.volta;
|
|
265
|
-
}
|
|
266
|
-
capNpmConf.dependencies = capNpmConf.dependencies ?? {};
|
|
267
|
-
capNpmConf.dependencies["@capacitor/core"] = "^7.0.0";
|
|
268
|
-
capNpmConf.dependencies["@capacitor/app"] = "^7.0.0";
|
|
269
|
-
for (const platform of this._platforms) {
|
|
270
|
-
capNpmConf.dependencies[`@capacitor/${platform}`] = "^7.0.0";
|
|
271
|
-
}
|
|
272
|
-
capNpmConf.devDependencies = capNpmConf.devDependencies ?? {};
|
|
273
|
-
capNpmConf.devDependencies["@capacitor/cli"] = "^7.0.0";
|
|
274
|
-
capNpmConf.devDependencies["@capacitor/assets"] = "^3.0.0";
|
|
275
|
-
const mainDeps = {
|
|
276
|
-
...this._npmConfig.dependencies,
|
|
277
|
-
...this._npmConfig.devDependencies,
|
|
278
|
-
...this._npmConfig.peerDependencies
|
|
279
|
-
};
|
|
280
|
-
const usePlugins = Object.keys(this._config.plugins ?? {});
|
|
281
|
-
const prevPlugins = Object.keys(capNpmConf.dependencies).filter(
|
|
282
|
-
(item) => !["@capacitor/core", "@capacitor/android", "@capacitor/ios", "@capacitor/app"].includes(
|
|
283
|
-
item
|
|
284
|
-
)
|
|
285
|
-
);
|
|
286
|
-
for (const prevPlugin of prevPlugins) {
|
|
287
|
-
if (!usePlugins.includes(prevPlugin)) {
|
|
288
|
-
delete capNpmConf.dependencies[prevPlugin];
|
|
289
|
-
Capacitor._logger.debug(`plugin removed: ${prevPlugin}`);
|
|
290
|
-
}
|
|
291
|
-
}
|
|
292
|
-
for (const plugin of usePlugins) {
|
|
293
|
-
if (!(plugin in capNpmConf.dependencies)) {
|
|
294
|
-
const version = mainDeps[plugin] ?? "*";
|
|
295
|
-
capNpmConf.dependencies[plugin] = version;
|
|
296
|
-
Capacitor._logger.debug(`plugin added: ${plugin}@${version}`);
|
|
297
|
-
}
|
|
298
|
-
}
|
|
299
|
-
for (const excludePkg of this._exclude) {
|
|
300
|
-
if (!(excludePkg in capNpmConf.dependencies)) {
|
|
301
|
-
const version = mainDeps[excludePkg] ?? "*";
|
|
302
|
-
capNpmConf.dependencies[excludePkg] = version;
|
|
303
|
-
Capacitor._logger.debug(`exclude package added: ${excludePkg}@${version}`);
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
await fsx.mkdir(this._capPath);
|
|
307
|
-
await fsx.writeJson(capNpmConfPath, capNpmConf, { space: 2 });
|
|
308
|
-
const isChanged = orgCapNpmConf.volta !== capNpmConf.volta || JSON.stringify(orgCapNpmConf.dependencies) !== JSON.stringify(capNpmConf.dependencies) || JSON.stringify(orgCapNpmConf.devDependencies) !== JSON.stringify(capNpmConf.devDependencies);
|
|
309
|
-
return isChanged;
|
|
310
|
-
}
|
|
311
|
-
/**
|
|
312
|
-
* Create capacitor.config.ts
|
|
313
|
-
*/
|
|
314
|
-
async _writeCapConf() {
|
|
315
|
-
const confPath = path.resolve(this._capPath, "capacitor.config.ts");
|
|
316
|
-
const pluginOptions = {};
|
|
317
|
-
for (const [pluginName, options] of Object.entries(this._config.plugins ?? {})) {
|
|
318
|
-
if (options !== true) {
|
|
319
|
-
const configKey = this._toPascalCase(pluginName.split("/").at(-1));
|
|
320
|
-
pluginOptions[configKey] = options;
|
|
321
|
-
}
|
|
322
|
-
}
|
|
323
|
-
const pluginsConfigStr = Object.keys(pluginOptions).length > 0 ? JSON.stringify(pluginOptions, null, 2).replace(/^/gm, " ").trim() : "{}";
|
|
324
|
-
const configContent = `import type { CapacitorConfig } from "@capacitor/cli";
|
|
325
|
-
|
|
326
|
-
const config: CapacitorConfig = {
|
|
327
|
-
appId: "${this._config.appId}",
|
|
328
|
-
appName: "${this._config.appName}",
|
|
329
|
-
server: {
|
|
330
|
-
androidScheme: "http",
|
|
331
|
-
cleartext: true
|
|
332
|
-
},
|
|
333
|
-
android: {},
|
|
334
|
-
plugins: ${pluginsConfigStr},
|
|
335
|
-
};
|
|
336
|
-
|
|
337
|
-
export default config;
|
|
338
|
-
`;
|
|
339
|
-
await fsx.write(confPath, configContent);
|
|
340
|
-
}
|
|
341
|
-
/**
|
|
342
|
-
* Add platform (F12: ensure idempotency)
|
|
343
|
-
*/
|
|
344
|
-
async _addPlatforms() {
|
|
345
|
-
for (const platform of this._platforms) {
|
|
346
|
-
const platformPath = path.resolve(this._capPath, platform);
|
|
347
|
-
if (await fsx.exists(platformPath)) {
|
|
348
|
-
Capacitor._logger.debug(`platform already exists: ${platform}`);
|
|
349
|
-
continue;
|
|
350
|
-
}
|
|
351
|
-
await this._execCap(["add", platform]);
|
|
352
|
-
}
|
|
353
|
-
}
|
|
354
|
-
/**
|
|
355
|
-
* Set up icon (F6: error recovery)
|
|
356
|
-
*/
|
|
357
|
-
async _setupIcon() {
|
|
358
|
-
const assetsDirPath = path.resolve(this._capPath, "assets");
|
|
359
|
-
if (this._config.icon != null) {
|
|
360
|
-
const iconSource = path.resolve(this._pkgPath, this._config.icon);
|
|
361
|
-
if (!await fsx.exists(iconSource)) {
|
|
362
|
-
Capacitor._logger.warn(
|
|
363
|
-
`icon file not found: ${iconSource}. Using default icon.`
|
|
364
|
-
);
|
|
365
|
-
return;
|
|
366
|
-
}
|
|
367
|
-
try {
|
|
368
|
-
await fsx.mkdir(assetsDirPath);
|
|
369
|
-
const logoPath = path.resolve(assetsDirPath, "logo.png");
|
|
370
|
-
const logoSize = Math.floor(1024 * 0.6);
|
|
371
|
-
const padding = Math.floor((1024 - logoSize) / 2);
|
|
372
|
-
await sharp(iconSource).resize(logoSize, logoSize, {
|
|
373
|
-
fit: "contain",
|
|
374
|
-
background: { r: 0, g: 0, b: 0, alpha: 0 }
|
|
375
|
-
}).extend({
|
|
376
|
-
top: padding,
|
|
377
|
-
bottom: padding,
|
|
378
|
-
left: padding,
|
|
379
|
-
right: padding,
|
|
380
|
-
background: { r: 0, g: 0, b: 0, alpha: 0 }
|
|
381
|
-
}).toFile(logoPath);
|
|
382
|
-
await this._execCapAssets([
|
|
383
|
-
"generate",
|
|
384
|
-
"--iconBackgroundColor",
|
|
385
|
-
"#ffffff",
|
|
386
|
-
"--splashBackgroundColor",
|
|
387
|
-
"#ffffff"
|
|
388
|
-
]);
|
|
389
|
-
} catch (err) {
|
|
390
|
-
Capacitor._logger.warn(
|
|
391
|
-
`icon generation failed: ${err instanceof Error ? err.message : err}. Using default icon.`
|
|
392
|
-
);
|
|
393
|
-
}
|
|
394
|
-
} else {
|
|
395
|
-
await fsx.rm(assetsDirPath);
|
|
396
|
-
}
|
|
397
|
-
}
|
|
398
|
-
//#endregion
|
|
399
|
-
//#region Private - Android Configuration
|
|
400
|
-
/**
|
|
401
|
-
* Configure Android native settings
|
|
402
|
-
*/
|
|
403
|
-
async _configureAndroid() {
|
|
404
|
-
const androidPath = path.resolve(this._capPath, "android");
|
|
405
|
-
if (!await fsx.exists(androidPath)) {
|
|
406
|
-
throw new Error(`Android project directory not found: ${androidPath}`);
|
|
407
|
-
}
|
|
408
|
-
await this._configureAndroidJavaHomePath(androidPath);
|
|
409
|
-
await this._configureAndroidSdkPath(androidPath);
|
|
410
|
-
await this._configureAndroidManifest(androidPath);
|
|
411
|
-
await this._configureAndroidBuildGradle(androidPath);
|
|
412
|
-
}
|
|
413
|
-
/**
|
|
414
|
-
* Set up JAVA_HOME path (gradle.properties)
|
|
415
|
-
*/
|
|
416
|
-
async _configureAndroidJavaHomePath(androidPath) {
|
|
417
|
-
const gradlePropsPath = path.resolve(androidPath, "gradle.properties");
|
|
418
|
-
if (!await fsx.exists(gradlePropsPath)) {
|
|
419
|
-
Capacitor._logger.warn(`gradle.properties file not found: ${gradlePropsPath}`);
|
|
420
|
-
return;
|
|
421
|
-
}
|
|
422
|
-
let content = await fsx.read(gradlePropsPath);
|
|
423
|
-
const java21Path = await this._findJava21();
|
|
424
|
-
if (java21Path != null && !content.includes("org.gradle.java.home")) {
|
|
425
|
-
const escapedPath = java21Path.replace(/\\/g, "\\\\");
|
|
426
|
-
content += `
|
|
427
|
-
org.gradle.java.home=${escapedPath}
|
|
428
|
-
`;
|
|
429
|
-
await fsx.write(gradlePropsPath, content);
|
|
430
|
-
}
|
|
431
|
-
}
|
|
432
|
-
/**
|
|
433
|
-
* Auto-detect Java 21 path
|
|
434
|
-
*/
|
|
435
|
-
async _findJava21() {
|
|
436
|
-
const patterns = [
|
|
437
|
-
"C:/Program Files/Amazon Corretto/jdk21*",
|
|
438
|
-
"C:/Program Files/Eclipse Adoptium/jdk-21*",
|
|
439
|
-
"C:/Program Files/Java/jdk-21*",
|
|
440
|
-
"C:/Program Files/Microsoft/jdk-21*",
|
|
441
|
-
"/usr/lib/jvm/java-21*",
|
|
442
|
-
"/usr/lib/jvm/temurin-21*"
|
|
443
|
-
];
|
|
444
|
-
for (const pattern of patterns) {
|
|
445
|
-
const matches = await fsx.glob(pattern);
|
|
446
|
-
if (matches.length > 0) {
|
|
447
|
-
return matches.sort().at(-1);
|
|
448
|
-
}
|
|
449
|
-
}
|
|
450
|
-
return void 0;
|
|
451
|
-
}
|
|
452
|
-
/**
|
|
453
|
-
* Set up Android SDK path (local.properties)
|
|
454
|
-
*/
|
|
455
|
-
async _configureAndroidSdkPath(androidPath) {
|
|
456
|
-
const localPropsPath = path.resolve(androidPath, "local.properties");
|
|
457
|
-
const sdkPath = await this._findAndroidSdk();
|
|
458
|
-
if (sdkPath != null) {
|
|
459
|
-
await fsx.write(localPropsPath, `sdk.dir=${sdkPath.replace(/\\/g, "/")}
|
|
460
|
-
`);
|
|
461
|
-
} else {
|
|
462
|
-
throw new Error(
|
|
463
|
-
"Android SDK not found.\n1. Install Android Studio or\n2. Set ANDROID_HOME or ANDROID_SDK_ROOT environment variable."
|
|
464
|
-
);
|
|
465
|
-
}
|
|
466
|
-
}
|
|
467
|
-
/**
|
|
468
|
-
* Search for Android SDK path
|
|
469
|
-
*/
|
|
470
|
-
async _findAndroidSdk() {
|
|
471
|
-
const fromEnv = env["ANDROID_HOME"] ?? env["ANDROID_SDK_ROOT"];
|
|
472
|
-
if (fromEnv != null && await fsx.exists(fromEnv)) {
|
|
473
|
-
return fromEnv;
|
|
474
|
-
}
|
|
475
|
-
const candidates = [
|
|
476
|
-
path.resolve(env["LOCALAPPDATA"] ?? "", "Android/Sdk"),
|
|
477
|
-
path.resolve(env["HOME"] ?? "", "Android/Sdk"),
|
|
478
|
-
"C:/Program Files/Android/Sdk",
|
|
479
|
-
"C:/Android/Sdk"
|
|
480
|
-
];
|
|
481
|
-
for (const candidate of candidates) {
|
|
482
|
-
if (await fsx.exists(candidate)) {
|
|
483
|
-
return candidate;
|
|
484
|
-
}
|
|
485
|
-
}
|
|
486
|
-
return void 0;
|
|
487
|
-
}
|
|
488
|
-
/**
|
|
489
|
-
* Modify AndroidManifest.xml (F3: add error handling)
|
|
490
|
-
*/
|
|
491
|
-
async _configureAndroidManifest(androidPath) {
|
|
492
|
-
const manifestPath = path.resolve(androidPath, "app/src/main/AndroidManifest.xml");
|
|
493
|
-
if (!await fsx.exists(manifestPath)) {
|
|
494
|
-
throw new Error(`AndroidManifest.xml file not found: ${manifestPath}`);
|
|
495
|
-
}
|
|
496
|
-
let content = await fsx.read(manifestPath);
|
|
497
|
-
if (!content.includes("android:usesCleartextTraffic")) {
|
|
498
|
-
content = content.replace("<application", '<application android:usesCleartextTraffic="true"');
|
|
499
|
-
}
|
|
500
|
-
const permissions = this._config.platform?.android?.permissions ?? [];
|
|
501
|
-
for (const perm of permissions) {
|
|
502
|
-
const permTag = `<uses-permission android:name="android.permission.${perm.name}"`;
|
|
503
|
-
if (!content.includes(permTag)) {
|
|
504
|
-
const maxSdkAttr = perm.maxSdkVersion != null ? ` android:maxSdkVersion="${perm.maxSdkVersion}"` : "";
|
|
505
|
-
const ignoreAttr = perm.ignore != null ? ` tools:ignore="${perm.ignore}"` : "";
|
|
506
|
-
const permLine = ` ${permTag}${maxSdkAttr}${ignoreAttr} />
|
|
507
|
-
`;
|
|
508
|
-
if (perm.ignore != null && !content.includes("xmlns:tools=")) {
|
|
509
|
-
content = content.replace(
|
|
510
|
-
"<manifest xmlns:android",
|
|
511
|
-
'<manifest xmlns:tools="http://schemas.android.com/tools" xmlns:android'
|
|
512
|
-
);
|
|
513
|
-
}
|
|
514
|
-
content = content.replace("</manifest>", `${permLine}</manifest>`);
|
|
515
|
-
}
|
|
516
|
-
}
|
|
517
|
-
const appConfig = this._config.platform?.android?.config;
|
|
518
|
-
if (appConfig) {
|
|
519
|
-
for (const [key, value] of Object.entries(appConfig)) {
|
|
520
|
-
const attr = `android:${key}="${value}"`;
|
|
521
|
-
if (!content.includes(`android:${key}=`)) {
|
|
522
|
-
content = content.replace("<application", `<application ${attr}`);
|
|
523
|
-
}
|
|
524
|
-
}
|
|
525
|
-
}
|
|
526
|
-
const intentFilters = this._config.platform?.android?.intentFilters ?? [];
|
|
527
|
-
for (const filter of intentFilters) {
|
|
528
|
-
const filterKey = filter.action ?? filter.category ?? "";
|
|
529
|
-
if (filterKey && !content.includes(filterKey)) {
|
|
530
|
-
const actionLine = filter.action != null ? `<action android:name="${filter.action}"/>` : "";
|
|
531
|
-
const categoryLine = filter.category != null ? `<category android:name="${filter.category}"/>` : "";
|
|
532
|
-
content = content.replace(
|
|
533
|
-
/(<activity[\s\S]*?android:name="\.MainActivity"[\s\S]*?>)/,
|
|
534
|
-
`$1
|
|
535
|
-
<intent-filter>
|
|
536
|
-
${actionLine}
|
|
537
|
-
${categoryLine}
|
|
538
|
-
</intent-filter>`
|
|
539
|
-
);
|
|
540
|
-
}
|
|
541
|
-
}
|
|
542
|
-
await fsx.write(manifestPath, content);
|
|
543
|
-
}
|
|
544
|
-
/**
|
|
545
|
-
* Modify build.gradle (F3: add error handling)
|
|
546
|
-
*/
|
|
547
|
-
async _configureAndroidBuildGradle(androidPath) {
|
|
548
|
-
const buildGradlePath = path.resolve(androidPath, "app/build.gradle");
|
|
549
|
-
if (!await fsx.exists(buildGradlePath)) {
|
|
550
|
-
throw new Error(`build.gradle file not found: ${buildGradlePath}`);
|
|
551
|
-
}
|
|
552
|
-
let content = await fsx.read(buildGradlePath);
|
|
553
|
-
const version = this._npmConfig.version;
|
|
554
|
-
const cleanVersion = version.replace(/-.*$/, "");
|
|
555
|
-
const versionParts = cleanVersion.split(".");
|
|
556
|
-
const versionCode = parseInt(versionParts[0] ?? "0") * 1e4 + parseInt(versionParts[1] ?? "0") * 100 + parseInt(versionParts[2] ?? "0");
|
|
557
|
-
content = content.replace(/versionCode \d+/, `versionCode ${versionCode}`);
|
|
558
|
-
content = content.replace(/versionName "[^"]+"/, `versionName "${version}"`);
|
|
559
|
-
if (this._config.platform?.android?.sdkVersion != null) {
|
|
560
|
-
const sdkVersion = this._config.platform.android.sdkVersion;
|
|
561
|
-
content = content.replace(/minSdkVersion .+/, `minSdkVersion ${sdkVersion}`);
|
|
562
|
-
content = content.replace(/targetSdkVersion .+/, `targetSdkVersion ${sdkVersion}`);
|
|
563
|
-
} else {
|
|
564
|
-
content = content.replace(/minSdkVersion .+/, `minSdkVersion rootProject.ext.minSdkVersion`);
|
|
565
|
-
content = content.replace(
|
|
566
|
-
/targetSdkVersion .+/,
|
|
567
|
-
`targetSdkVersion rootProject.ext.targetSdkVersion`
|
|
568
|
-
);
|
|
569
|
-
}
|
|
570
|
-
const keystorePath = path.resolve(this._capPath, Capacitor._ANDROID_KEYSTORE_FILE_NAME);
|
|
571
|
-
const signConfig = this._config.platform?.android?.sign;
|
|
572
|
-
if (signConfig) {
|
|
573
|
-
const keystoreSource = path.resolve(this._pkgPath, signConfig.keystore);
|
|
574
|
-
if (!await fsx.exists(keystoreSource)) {
|
|
575
|
-
throw new Error(`keystore file not found: ${keystoreSource}`);
|
|
576
|
-
}
|
|
577
|
-
await fsx.copy(keystoreSource, keystorePath);
|
|
578
|
-
const keystoreRelativePath = path.relative(path.dirname(buildGradlePath), keystorePath).replace(/\\/g, "/");
|
|
579
|
-
const keystoreType = signConfig.keystoreType ?? "jks";
|
|
580
|
-
if (!content.includes("signingConfigs")) {
|
|
581
|
-
const signingConfigsBlock = `
|
|
582
|
-
signingConfigs {
|
|
583
|
-
release {
|
|
584
|
-
storeFile file("${keystoreRelativePath}")
|
|
585
|
-
storePassword '${Capacitor._escapeGroovyString(signConfig.storePassword)}'
|
|
586
|
-
keyAlias '${Capacitor._escapeGroovyString(signConfig.alias)}'
|
|
587
|
-
keyPassword '${Capacitor._escapeGroovyString(signConfig.password)}'
|
|
588
|
-
storeType "${keystoreType}"
|
|
589
|
-
}
|
|
590
|
-
}
|
|
591
|
-
`;
|
|
592
|
-
content = content.replace(/(android\s*\{)/, (match) => `${match}${signingConfigsBlock}`);
|
|
593
|
-
}
|
|
594
|
-
if (!content.includes("signingConfig signingConfigs.release")) {
|
|
595
|
-
content = content.replace(
|
|
596
|
-
/(buildTypes\s*\{[\s\S]*?release\s*\{)/,
|
|
597
|
-
`$1
|
|
598
|
-
signingConfig signingConfigs.release`
|
|
599
|
-
);
|
|
600
|
-
}
|
|
601
|
-
} else {
|
|
602
|
-
await fsx.rm(keystorePath);
|
|
603
|
-
}
|
|
604
|
-
await fsx.write(buildGradlePath, content);
|
|
605
|
-
}
|
|
606
|
-
/**
|
|
607
|
-
* Escape single quotes in Groovy string (for use in single-quoted strings)
|
|
608
|
-
* Groovy: 'string with \'single quote\' inside'
|
|
609
|
-
*/
|
|
610
|
-
static _escapeGroovyString(value) {
|
|
611
|
-
return value.replace(/'/g, "\\'");
|
|
612
|
-
}
|
|
613
|
-
//#endregion
|
|
614
|
-
//#region Private - Build
|
|
615
|
-
/**
|
|
616
|
-
* Build Android
|
|
617
|
-
*/
|
|
618
|
-
async _buildAndroid(outPath, buildType) {
|
|
619
|
-
const androidPath = path.resolve(this._capPath, "android");
|
|
620
|
-
const targetOutPath = path.resolve(outPath, "android");
|
|
621
|
-
const isBundle = this._config.platform?.android?.bundle;
|
|
622
|
-
const gradleTask = buildType === "release" ? isBundle ? "bundleRelease" : "assembleRelease" : "assembleDebug";
|
|
623
|
-
if (process.platform === "win32") {
|
|
624
|
-
await this._exec("cmd", ["/c", "gradlew.bat", gradleTask, "--no-daemon"], androidPath);
|
|
625
|
-
} else {
|
|
626
|
-
await this._exec("sh", ["./gradlew", gradleTask, "--no-daemon"], androidPath);
|
|
627
|
-
}
|
|
628
|
-
await this._copyAndroidBuildOutput(androidPath, targetOutPath, buildType);
|
|
629
|
-
}
|
|
630
|
-
/**
|
|
631
|
-
* Copy Android build output
|
|
632
|
-
*/
|
|
633
|
-
async _copyAndroidBuildOutput(androidPath, targetOutPath, buildType) {
|
|
634
|
-
const isBundle = this._config.platform?.android?.bundle;
|
|
635
|
-
const isSigned = Boolean(this._config.platform?.android?.sign);
|
|
636
|
-
const ext = isBundle ? "aab" : "apk";
|
|
637
|
-
const outputType = isBundle ? "bundle" : "apk";
|
|
638
|
-
const fileName = isSigned ? `app-${buildType}.${ext}` : `app-${buildType}-unsigned.${ext}`;
|
|
639
|
-
const sourcePath = path.resolve(
|
|
640
|
-
androidPath,
|
|
641
|
-
"app/build/outputs",
|
|
642
|
-
outputType,
|
|
643
|
-
buildType,
|
|
644
|
-
fileName
|
|
645
|
-
);
|
|
646
|
-
const actualPath = await fsx.exists(sourcePath) ? sourcePath : path.resolve(
|
|
647
|
-
androidPath,
|
|
648
|
-
"app/build/outputs",
|
|
649
|
-
outputType,
|
|
650
|
-
buildType,
|
|
651
|
-
`app-${buildType}.${ext}`
|
|
652
|
-
);
|
|
653
|
-
if (!await fsx.exists(actualPath)) {
|
|
654
|
-
Capacitor._logger.warn(`build output not found: ${actualPath}`);
|
|
655
|
-
return;
|
|
656
|
-
}
|
|
657
|
-
const outputFileName = `${this._config.appName}${isSigned ? "" : "-unsigned"}-latest.${ext}`;
|
|
658
|
-
await fsx.mkdir(targetOutPath);
|
|
659
|
-
await fsx.copy(actualPath, path.resolve(targetOutPath, outputFileName));
|
|
660
|
-
const updatesPath = path.resolve(targetOutPath, "updates");
|
|
661
|
-
await fsx.mkdir(updatesPath);
|
|
662
|
-
await fsx.copy(actualPath, path.resolve(updatesPath, `${this._npmConfig.version}.${ext}`));
|
|
663
|
-
}
|
|
664
|
-
//#endregion
|
|
665
|
-
//#region Private - Device Execution
|
|
666
|
-
/**
|
|
667
|
-
* Update server.url in capacitor.config.ts
|
|
668
|
-
*/
|
|
669
|
-
async _updateServerUrl(url) {
|
|
670
|
-
const configPath = path.resolve(this._capPath, "capacitor.config.ts");
|
|
671
|
-
if (!await fsx.exists(configPath)) return;
|
|
672
|
-
let content = await fsx.read(configPath);
|
|
673
|
-
if (content.includes("url:")) {
|
|
674
|
-
content = content.replace(/url:\s*"[^"]*"/, `url: "${url}"`);
|
|
675
|
-
} else if (content.includes("server:")) {
|
|
676
|
-
content = content.replace(/server:\s*\{/, `server: {
|
|
677
|
-
url: "${url}",`);
|
|
678
|
-
}
|
|
679
|
-
await fsx.write(configPath, content);
|
|
680
|
-
}
|
|
681
|
-
//#endregion
|
|
682
|
-
//#region Private - Utilities
|
|
683
|
-
/**
|
|
684
|
-
* Convert string to PascalCase
|
|
685
|
-
*/
|
|
686
|
-
_toPascalCase(str) {
|
|
687
|
-
return str.replace(/[-_](.)/g, (_, c) => c.toUpperCase()).replace(/^./, (c) => c.toUpperCase());
|
|
688
|
-
}
|
|
689
|
-
//#endregion
|
|
690
|
-
}
|
|
691
|
-
export {
|
|
692
|
-
Capacitor
|
|
693
|
-
};
|
|
694
|
-
//# sourceMappingURL=capacitor.js.map
|