prime-dev-cli 1.0.7 → 1.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/config/projects.json +34 -1
- package/dist/server/.next/BUILD_ID +1 -1
- package/dist/server/.next/app-build-manifest.json +34 -180
- package/dist/server/.next/app-path-routes-manifest.json +13 -12
- package/dist/server/.next/build/chunks/[root-of-the-server]__5583c180._.js +491 -0
- package/dist/server/.next/build/chunks/[root-of-the-server]__5583c180._.js.map +11 -0
- package/dist/server/.next/build/chunks/[root-of-the-server]__f95a3f97._.js +173 -0
- package/dist/server/.next/build/chunks/[root-of-the-server]__f95a3f97._.js.map +7 -0
- package/dist/server/.next/build/chunks/[turbopack]_runtime.js +688 -0
- package/dist/server/.next/build/chunks/[turbopack]_runtime.js.map +10 -0
- package/dist/server/.next/build/chunks/node_modules__pnpm_ec38a98b._.js +6748 -0
- package/dist/server/.next/build/chunks/node_modules__pnpm_ec38a98b._.js.map +47 -0
- package/dist/server/.next/build/chunks/packages_server_postcss_config_mjs_transform_ts_18d17415._.js +17 -0
- package/dist/server/.next/build/chunks/packages_server_postcss_config_mjs_transform_ts_18d17415._.js.map +5 -0
- package/dist/server/.next/build-manifest.json +22 -24
- package/dist/server/.next/cache/.rscinfo +1 -1
- package/dist/server/.next/cache/.tsbuildinfo +1 -1
- package/dist/server/.next/cache/eslint/.cache_1qa5vxt +1 -1
- package/dist/server/.next/cache/webpack/client-production/0.pack +0 -0
- package/dist/server/.next/cache/webpack/client-production/1.pack +0 -0
- package/dist/server/.next/cache/webpack/client-production/2.pack +0 -0
- package/dist/server/.next/cache/webpack/client-production/index.pack +0 -0
- package/dist/server/.next/cache/webpack/client-production/index.pack.old +0 -0
- package/dist/server/.next/cache/webpack/edge-server-production/index.pack +0 -0
- package/dist/server/.next/cache/webpack/edge-server-production/index.pack.old +0 -0
- package/dist/server/.next/cache/webpack/server-production/0.pack +0 -0
- package/dist/server/.next/cache/webpack/server-production/1.pack +0 -0
- package/dist/server/.next/cache/webpack/server-production/index.pack +0 -0
- package/dist/server/.next/cache/webpack/server-production/index.pack.old +0 -0
- package/dist/server/.next/fallback-build-manifest.json +23 -0
- package/dist/server/.next/next-minimal-server.js.nft.json +1 -1
- package/dist/server/.next/next-server.js.nft.json +1 -1
- package/dist/server/.next/prerender-manifest.json +3 -3
- package/dist/server/.next/required-server-files.json +0 -2
- package/dist/server/.next/server/app/_not-found/page/app-build-manifest.json +13 -0
- package/dist/server/.next/server/app/_not-found/page/app-paths-manifest.json +3 -0
- package/dist/server/.next/server/app/_not-found/page/build-manifest.json +17 -0
- package/dist/server/.next/server/app/_not-found/page/next-font-manifest.json +6 -0
- package/dist/server/.next/server/app/_not-found/page/react-loadable-manifest.json +1 -0
- package/dist/server/.next/server/app/_not-found/page/server-reference-manifest.json +4 -0
- package/dist/server/.next/server/app/_not-found/page.js +13 -1
- package/dist/server/.next/server/app/_not-found/page.js.map +5 -0
- package/dist/server/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/dist/server/.next/server/app/_not-found/page_client-reference-manifest.js +2 -1
- package/dist/server/.next/server/app/_not-found.html +1 -1
- package/dist/server/.next/server/app/_not-found.rsc +11 -11
- package/dist/server/.next/server/app/api/all-projects-envs/route/app-build-manifest.json +11 -0
- package/dist/server/.next/server/app/api/all-projects-envs/route/app-paths-manifest.json +3 -0
- package/dist/server/.next/server/app/api/all-projects-envs/route/build-manifest.json +17 -0
- package/dist/server/.next/server/app/api/all-projects-envs/route/next-font-manifest.json +6 -0
- package/dist/server/.next/server/app/api/all-projects-envs/route/react-loadable-manifest.json +1 -0
- package/dist/server/.next/server/app/api/all-projects-envs/route/server-reference-manifest.json +4 -0
- package/dist/server/.next/server/app/api/all-projects-envs/route.js +8 -1
- package/dist/server/.next/server/app/api/all-projects-envs/route.js.map +5 -0
- package/dist/server/.next/server/app/api/all-projects-envs/route.js.nft.json +1 -1
- package/dist/server/.next/server/app/api/all-projects-envs/route_client-reference-manifest.js +2 -1
- package/dist/server/.next/server/app/api/check-mock-intercept/route/app-build-manifest.json +11 -0
- package/dist/server/.next/server/app/api/check-mock-intercept/route/app-paths-manifest.json +3 -0
- package/dist/server/.next/server/app/api/check-mock-intercept/route/build-manifest.json +17 -0
- package/dist/server/.next/server/app/api/check-mock-intercept/route/next-font-manifest.json +6 -0
- package/dist/server/.next/server/app/api/check-mock-intercept/route/react-loadable-manifest.json +1 -0
- package/dist/server/.next/server/app/api/check-mock-intercept/route/server-reference-manifest.json +4 -0
- package/dist/server/.next/server/app/api/check-mock-intercept/route.js +8 -1
- package/dist/server/.next/server/app/api/check-mock-intercept/route.js.map +5 -0
- package/dist/server/.next/server/app/api/check-mock-intercept/route.js.nft.json +1 -1
- package/dist/server/.next/server/app/api/check-mock-intercept/route_client-reference-manifest.js +2 -1
- package/dist/server/.next/server/app/api/check-workspace/route/app-build-manifest.json +11 -0
- package/dist/server/.next/server/app/api/check-workspace/route/app-paths-manifest.json +3 -0
- package/dist/server/.next/server/app/api/check-workspace/route/build-manifest.json +17 -0
- package/dist/server/.next/server/app/api/check-workspace/route/next-font-manifest.json +6 -0
- package/dist/server/.next/server/app/api/check-workspace/route/react-loadable-manifest.json +1 -0
- package/dist/server/.next/server/app/api/check-workspace/route/server-reference-manifest.json +4 -0
- package/dist/server/.next/server/app/api/check-workspace/route.js +7 -14
- package/dist/server/.next/server/app/api/check-workspace/route.js.map +5 -0
- package/dist/server/.next/server/app/api/check-workspace/route.js.nft.json +1 -1
- package/dist/server/.next/server/app/api/check-workspace/route_client-reference-manifest.js +2 -1
- package/dist/server/.next/server/app/api/cleanup-mock/route/app-build-manifest.json +11 -0
- package/dist/server/.next/server/app/api/cleanup-mock/route/app-paths-manifest.json +3 -0
- package/dist/server/.next/server/app/api/cleanup-mock/route/build-manifest.json +17 -0
- package/dist/server/.next/server/app/api/cleanup-mock/route/next-font-manifest.json +6 -0
- package/dist/server/.next/server/app/api/cleanup-mock/route/react-loadable-manifest.json +1 -0
- package/dist/server/.next/server/app/api/cleanup-mock/route/server-reference-manifest.json +4 -0
- package/dist/server/.next/server/app/api/cleanup-mock/route.js +8 -6
- package/dist/server/.next/server/app/api/cleanup-mock/route.js.map +5 -0
- package/dist/server/.next/server/app/api/cleanup-mock/route.js.nft.json +1 -1
- package/dist/server/.next/server/app/api/cleanup-mock/route_client-reference-manifest.js +2 -1
- package/dist/server/.next/server/app/api/cleanup-project/route/app-build-manifest.json +11 -0
- package/dist/server/.next/server/app/api/cleanup-project/route/app-paths-manifest.json +3 -0
- package/dist/server/.next/server/app/api/cleanup-project/route/build-manifest.json +17 -0
- package/dist/server/.next/server/app/api/cleanup-project/route/next-font-manifest.json +6 -0
- package/dist/server/.next/server/app/api/cleanup-project/route/react-loadable-manifest.json +1 -0
- package/dist/server/.next/server/app/api/cleanup-project/route/server-reference-manifest.json +4 -0
- package/dist/server/.next/server/app/api/cleanup-project/route.js +8 -1
- package/dist/server/.next/server/app/api/cleanup-project/route.js.map +5 -0
- package/dist/server/.next/server/app/api/cleanup-project/route.js.nft.json +1 -1
- package/dist/server/.next/server/app/api/cleanup-project/route_client-reference-manifest.js +2 -1
- package/dist/server/.next/server/app/api/delete-mock-api/route/app-build-manifest.json +11 -0
- package/dist/server/.next/server/app/api/delete-mock-api/route/app-paths-manifest.json +3 -0
- package/dist/server/.next/server/app/api/delete-mock-api/route/build-manifest.json +17 -0
- package/dist/server/.next/server/app/api/delete-mock-api/route/next-font-manifest.json +6 -0
- package/dist/server/.next/server/app/api/delete-mock-api/route/react-loadable-manifest.json +1 -0
- package/dist/server/.next/server/app/api/delete-mock-api/route/server-reference-manifest.json +4 -0
- package/dist/server/.next/server/app/api/delete-mock-api/route.js +8 -0
- package/dist/server/.next/server/app/api/delete-mock-api/route.js.map +5 -0
- package/dist/server/.next/server/app/api/delete-mock-api/route.js.nft.json +1 -0
- package/dist/server/.next/server/app/api/delete-mock-api/route_client-reference-manifest.js +2 -0
- package/dist/server/.next/server/app/api/get-mock-data/route/app-build-manifest.json +11 -0
- package/dist/server/.next/server/app/api/get-mock-data/route/app-paths-manifest.json +3 -0
- package/dist/server/.next/server/app/api/get-mock-data/route/build-manifest.json +17 -0
- package/dist/server/.next/server/app/api/get-mock-data/route/next-font-manifest.json +6 -0
- package/dist/server/.next/server/app/api/get-mock-data/route/react-loadable-manifest.json +1 -0
- package/dist/server/.next/server/app/api/get-mock-data/route/server-reference-manifest.json +4 -0
- package/dist/server/.next/server/app/api/get-mock-data/route.js +8 -1
- package/dist/server/.next/server/app/api/get-mock-data/route.js.map +5 -0
- package/dist/server/.next/server/app/api/get-mock-data/route.js.nft.json +1 -1
- package/dist/server/.next/server/app/api/get-mock-data/route_client-reference-manifest.js +2 -1
- package/dist/server/.next/server/app/api/initialize-workspace/route/app-build-manifest.json +11 -0
- package/dist/server/.next/server/app/api/initialize-workspace/route/app-paths-manifest.json +3 -0
- package/dist/server/.next/server/app/api/initialize-workspace/route/build-manifest.json +17 -0
- package/dist/server/.next/server/app/api/initialize-workspace/route/next-font-manifest.json +6 -0
- package/dist/server/.next/server/app/api/initialize-workspace/route/react-loadable-manifest.json +1 -0
- package/dist/server/.next/server/app/api/initialize-workspace/route/server-reference-manifest.json +4 -0
- package/dist/server/.next/server/app/api/initialize-workspace/route.js +7 -18
- package/dist/server/.next/server/app/api/initialize-workspace/route.js.map +5 -0
- package/dist/server/.next/server/app/api/initialize-workspace/route.js.nft.json +1 -1
- package/dist/server/.next/server/app/api/initialize-workspace/route_client-reference-manifest.js +2 -1
- package/dist/server/.next/server/app/api/microapp-proxy-change-stream/route/app-build-manifest.json +11 -0
- package/dist/server/.next/server/app/api/microapp-proxy-change-stream/route/app-paths-manifest.json +3 -0
- package/dist/server/.next/server/app/api/microapp-proxy-change-stream/route/build-manifest.json +17 -0
- package/dist/server/.next/server/app/api/microapp-proxy-change-stream/route/next-font-manifest.json +6 -0
- package/dist/server/.next/server/app/api/microapp-proxy-change-stream/route/react-loadable-manifest.json +1 -0
- package/dist/server/.next/server/app/api/microapp-proxy-change-stream/route/server-reference-manifest.json +4 -0
- package/dist/server/.next/server/app/api/microapp-proxy-change-stream/route.js +8 -5
- package/dist/server/.next/server/app/api/microapp-proxy-change-stream/route.js.map +5 -0
- package/dist/server/.next/server/app/api/microapp-proxy-change-stream/route.js.nft.json +1 -1
- package/dist/server/.next/server/app/api/microapp-proxy-change-stream/route_client-reference-manifest.js +2 -1
- package/dist/server/.next/server/app/api/microapp-proxy-config/route/app-build-manifest.json +11 -0
- package/dist/server/.next/server/app/api/microapp-proxy-config/route/app-paths-manifest.json +3 -0
- package/dist/server/.next/server/app/api/microapp-proxy-config/route/build-manifest.json +17 -0
- package/dist/server/.next/server/app/api/microapp-proxy-config/route/next-font-manifest.json +6 -0
- package/dist/server/.next/server/app/api/microapp-proxy-config/route/react-loadable-manifest.json +1 -0
- package/dist/server/.next/server/app/api/microapp-proxy-config/route/server-reference-manifest.json +4 -0
- package/dist/server/.next/server/app/api/microapp-proxy-config/route.js +8 -3
- package/dist/server/.next/server/app/api/microapp-proxy-config/route.js.map +5 -0
- package/dist/server/.next/server/app/api/microapp-proxy-config/route.js.nft.json +1 -1
- package/dist/server/.next/server/app/api/microapp-proxy-config/route_client-reference-manifest.js +2 -1
- package/dist/server/.next/server/app/api/mock-file/route/app-build-manifest.json +11 -0
- package/dist/server/.next/server/app/api/mock-file/route/app-paths-manifest.json +3 -0
- package/dist/server/.next/server/app/api/mock-file/route/build-manifest.json +17 -0
- package/dist/server/.next/server/app/api/mock-file/route/next-font-manifest.json +6 -0
- package/dist/server/.next/server/app/api/mock-file/route/react-loadable-manifest.json +1 -0
- package/dist/server/.next/server/app/api/mock-file/route/server-reference-manifest.json +4 -0
- package/dist/server/.next/server/app/api/mock-file/route.js +8 -6
- package/dist/server/.next/server/app/api/mock-file/route.js.map +5 -0
- package/dist/server/.next/server/app/api/mock-file/route.js.nft.json +1 -1
- package/dist/server/.next/server/app/api/mock-file/route_client-reference-manifest.js +2 -1
- package/dist/server/.next/server/app/api/mock-file-content/route/app-build-manifest.json +11 -0
- package/dist/server/.next/server/app/api/mock-file-content/route/app-paths-manifest.json +3 -0
- package/dist/server/.next/server/app/api/mock-file-content/route/build-manifest.json +17 -0
- package/dist/server/.next/server/app/api/mock-file-content/route/next-font-manifest.json +6 -0
- package/dist/server/.next/server/app/api/mock-file-content/route/react-loadable-manifest.json +1 -0
- package/dist/server/.next/server/app/api/mock-file-content/route/server-reference-manifest.json +4 -0
- package/dist/server/.next/server/app/api/mock-file-content/route.js +8 -1
- package/dist/server/.next/server/app/api/mock-file-content/route.js.map +5 -0
- package/dist/server/.next/server/app/api/mock-file-content/route.js.nft.json +1 -1
- package/dist/server/.next/server/app/api/mock-file-content/route_client-reference-manifest.js +2 -1
- package/dist/server/.next/server/app/api/mock-open-status/route/app-build-manifest.json +11 -0
- package/dist/server/.next/server/app/api/mock-open-status/route/app-paths-manifest.json +3 -0
- package/dist/server/.next/server/app/api/mock-open-status/route/build-manifest.json +17 -0
- package/dist/server/.next/server/app/api/mock-open-status/route/next-font-manifest.json +6 -0
- package/dist/server/.next/server/app/api/mock-open-status/route/react-loadable-manifest.json +1 -0
- package/dist/server/.next/server/app/api/mock-open-status/route/server-reference-manifest.json +4 -0
- package/dist/server/.next/server/app/api/mock-open-status/route.js +8 -6
- package/dist/server/.next/server/app/api/mock-open-status/route.js.map +5 -0
- package/dist/server/.next/server/app/api/mock-open-status/route.js.nft.json +1 -1
- package/dist/server/.next/server/app/api/mock-open-status/route_client-reference-manifest.js +2 -1
- package/dist/server/.next/server/app/api/mock-setting/route/app-build-manifest.json +11 -0
- package/dist/server/.next/server/app/api/mock-setting/route/app-paths-manifest.json +3 -0
- package/dist/server/.next/server/app/api/mock-setting/route/build-manifest.json +17 -0
- package/dist/server/.next/server/app/api/mock-setting/route/next-font-manifest.json +6 -0
- package/dist/server/.next/server/app/api/mock-setting/route/react-loadable-manifest.json +1 -0
- package/dist/server/.next/server/app/api/mock-setting/route/server-reference-manifest.json +4 -0
- package/dist/server/.next/server/app/api/mock-setting/route.js +8 -1
- package/dist/server/.next/server/app/api/mock-setting/route.js.map +5 -0
- package/dist/server/.next/server/app/api/mock-setting/route.js.nft.json +1 -1
- package/dist/server/.next/server/app/api/mock-setting/route_client-reference-manifest.js +2 -1
- package/dist/server/.next/server/app/api/open-all-mock/route/app-build-manifest.json +11 -0
- package/dist/server/.next/server/app/api/open-all-mock/route/app-paths-manifest.json +3 -0
- package/dist/server/.next/server/app/api/open-all-mock/route/build-manifest.json +17 -0
- package/dist/server/.next/server/app/api/open-all-mock/route/next-font-manifest.json +6 -0
- package/dist/server/.next/server/app/api/open-all-mock/route/react-loadable-manifest.json +1 -0
- package/dist/server/.next/server/app/api/open-all-mock/route/server-reference-manifest.json +4 -0
- package/dist/server/.next/server/app/api/open-all-mock/route.js +8 -11
- package/dist/server/.next/server/app/api/open-all-mock/route.js.map +5 -0
- package/dist/server/.next/server/app/api/open-all-mock/route.js.nft.json +1 -1
- package/dist/server/.next/server/app/api/open-all-mock/route_client-reference-manifest.js +2 -1
- package/dist/server/.next/server/app/api/open-project/route/app-build-manifest.json +11 -0
- package/dist/server/.next/server/app/api/open-project/route/app-paths-manifest.json +3 -0
- package/dist/server/.next/server/app/api/open-project/route/build-manifest.json +17 -0
- package/dist/server/.next/server/app/api/open-project/route/next-font-manifest.json +6 -0
- package/dist/server/.next/server/app/api/open-project/route/react-loadable-manifest.json +1 -0
- package/dist/server/.next/server/app/api/open-project/route/server-reference-manifest.json +4 -0
- package/dist/server/.next/server/app/api/open-project/route.js +7 -14
- package/dist/server/.next/server/app/api/open-project/route.js.map +5 -0
- package/dist/server/.next/server/app/api/open-project/route.js.nft.json +1 -1
- package/dist/server/.next/server/app/api/open-project/route_client-reference-manifest.js +2 -1
- package/dist/server/.next/server/app/api/process/logs/route/app-build-manifest.json +11 -0
- package/dist/server/.next/server/app/api/process/logs/route/app-paths-manifest.json +3 -0
- package/dist/server/.next/server/app/api/process/logs/route/build-manifest.json +17 -0
- package/dist/server/.next/server/app/api/process/logs/route/next-font-manifest.json +6 -0
- package/dist/server/.next/server/app/api/process/logs/route/react-loadable-manifest.json +1 -0
- package/dist/server/.next/server/app/api/process/logs/route/server-reference-manifest.json +4 -0
- package/dist/server/.next/server/app/api/process/logs/route.js +8 -1
- package/dist/server/.next/server/app/api/process/logs/route.js.map +5 -0
- package/dist/server/.next/server/app/api/process/logs/route.js.nft.json +1 -1
- package/dist/server/.next/server/app/api/process/logs/route_client-reference-manifest.js +2 -1
- package/dist/server/.next/server/app/api/process/logs/stream/route/app-build-manifest.json +11 -0
- package/dist/server/.next/server/app/api/process/logs/stream/route/app-paths-manifest.json +3 -0
- package/dist/server/.next/server/app/api/process/logs/stream/route/build-manifest.json +17 -0
- package/dist/server/.next/server/app/api/process/logs/stream/route/next-font-manifest.json +6 -0
- package/dist/server/.next/server/app/api/process/logs/stream/route/react-loadable-manifest.json +1 -0
- package/dist/server/.next/server/app/api/process/logs/stream/route/server-reference-manifest.json +4 -0
- package/dist/server/.next/server/app/api/process/logs/stream/route.js +7 -9
- package/dist/server/.next/server/app/api/process/logs/stream/route.js.map +5 -0
- package/dist/server/.next/server/app/api/process/logs/stream/route.js.nft.json +1 -1
- package/dist/server/.next/server/app/api/process/logs/stream/route_client-reference-manifest.js +2 -1
- package/dist/server/.next/server/app/api/process/start/route/app-build-manifest.json +11 -0
- package/dist/server/.next/server/app/api/process/start/route/app-paths-manifest.json +3 -0
- package/dist/server/.next/server/app/api/process/start/route/build-manifest.json +17 -0
- package/dist/server/.next/server/app/api/process/start/route/next-font-manifest.json +6 -0
- package/dist/server/.next/server/app/api/process/start/route/react-loadable-manifest.json +1 -0
- package/dist/server/.next/server/app/api/process/start/route/server-reference-manifest.json +4 -0
- package/dist/server/.next/server/app/api/process/start/route.js +8 -1
- package/dist/server/.next/server/app/api/process/start/route.js.map +5 -0
- package/dist/server/.next/server/app/api/process/start/route.js.nft.json +1 -1
- package/dist/server/.next/server/app/api/process/start/route_client-reference-manifest.js +2 -1
- package/dist/server/.next/server/app/api/process/status/route/app-build-manifest.json +11 -0
- package/dist/server/.next/server/app/api/process/status/route/app-paths-manifest.json +3 -0
- package/dist/server/.next/server/app/api/process/status/route/build-manifest.json +17 -0
- package/dist/server/.next/server/app/api/process/status/route/next-font-manifest.json +6 -0
- package/dist/server/.next/server/app/api/process/status/route/react-loadable-manifest.json +1 -0
- package/dist/server/.next/server/app/api/process/status/route/server-reference-manifest.json +4 -0
- package/dist/server/.next/server/app/api/process/status/route.js +8 -1
- package/dist/server/.next/server/app/api/process/status/route.js.map +5 -0
- package/dist/server/.next/server/app/api/process/status/route.js.nft.json +1 -1
- package/dist/server/.next/server/app/api/process/status/route_client-reference-manifest.js +2 -1
- package/dist/server/.next/server/app/api/project-config/route/app-build-manifest.json +11 -0
- package/dist/server/.next/server/app/api/project-config/route/app-paths-manifest.json +3 -0
- package/dist/server/.next/server/app/api/project-config/route/build-manifest.json +17 -0
- package/dist/server/.next/server/app/api/project-config/route/next-font-manifest.json +6 -0
- package/dist/server/.next/server/app/api/project-config/route/react-loadable-manifest.json +1 -0
- package/dist/server/.next/server/app/api/project-config/route/server-reference-manifest.json +4 -0
- package/dist/server/.next/server/app/api/project-config/route.js +8 -1
- package/dist/server/.next/server/app/api/project-config/route.js.map +5 -0
- package/dist/server/.next/server/app/api/project-config/route.js.nft.json +1 -1
- package/dist/server/.next/server/app/api/project-config/route_client-reference-manifest.js +2 -1
- package/dist/server/.next/server/app/api/retry-project/route/app-build-manifest.json +11 -0
- package/dist/server/.next/server/app/api/retry-project/route/app-paths-manifest.json +3 -0
- package/dist/server/.next/server/app/api/retry-project/route/build-manifest.json +17 -0
- package/dist/server/.next/server/app/api/retry-project/route/next-font-manifest.json +6 -0
- package/dist/server/.next/server/app/api/retry-project/route/react-loadable-manifest.json +1 -0
- package/dist/server/.next/server/app/api/retry-project/route/server-reference-manifest.json +4 -0
- package/dist/server/.next/server/app/api/retry-project/route.js +7 -14
- package/dist/server/.next/server/app/api/retry-project/route.js.map +5 -0
- package/dist/server/.next/server/app/api/retry-project/route.js.nft.json +1 -1
- package/dist/server/.next/server/app/api/retry-project/route_client-reference-manifest.js +2 -1
- package/dist/server/.next/server/app/configuration/page/app-build-manifest.json +15 -0
- package/dist/server/.next/server/app/configuration/page/app-paths-manifest.json +3 -0
- package/dist/server/.next/server/app/configuration/page/build-manifest.json +17 -0
- package/dist/server/.next/server/app/configuration/page/next-font-manifest.json +6 -0
- package/dist/server/.next/server/app/configuration/page/react-loadable-manifest.json +1 -0
- package/dist/server/.next/server/app/configuration/page/server-reference-manifest.json +4 -0
- package/dist/server/.next/server/app/configuration/page.js +14 -37
- package/dist/server/.next/server/app/configuration/page.js.map +5 -0
- package/dist/server/.next/server/app/configuration/page.js.nft.json +1 -1
- package/dist/server/.next/server/app/configuration/page_client-reference-manifest.js +2 -1
- package/dist/server/.next/server/app/configuration.html +1 -1
- package/dist/server/.next/server/app/configuration.rsc +13 -13
- package/dist/server/.next/server/app/favicon.ico/route/app-build-manifest.json +11 -0
- package/dist/server/.next/server/app/favicon.ico/route/app-paths-manifest.json +3 -0
- package/dist/server/.next/server/app/favicon.ico/route/build-manifest.json +17 -0
- package/dist/server/.next/server/app/favicon.ico/route.js +9 -1
- package/dist/server/.next/server/app/favicon.ico/route.js.map +5 -0
- package/dist/server/.next/server/app/favicon.ico/route.js.nft.json +1 -1
- package/dist/server/.next/server/app/index.html +1 -1
- package/dist/server/.next/server/app/index.rsc +11 -11
- package/dist/server/.next/server/app/initialization/page/app-build-manifest.json +15 -0
- package/dist/server/.next/server/app/initialization/page/app-paths-manifest.json +3 -0
- package/dist/server/.next/server/app/initialization/page/build-manifest.json +17 -0
- package/dist/server/.next/server/app/initialization/page/next-font-manifest.json +6 -0
- package/dist/server/.next/server/app/initialization/page/react-loadable-manifest.json +1 -0
- package/dist/server/.next/server/app/initialization/page/server-reference-manifest.json +4 -0
- package/dist/server/.next/server/app/initialization/page.js +14 -1
- package/dist/server/.next/server/app/initialization/page.js.map +5 -0
- package/dist/server/.next/server/app/initialization/page.js.nft.json +1 -1
- package/dist/server/.next/server/app/initialization/page_client-reference-manifest.js +2 -1
- package/dist/server/.next/server/app/initialization.html +1 -1
- package/dist/server/.next/server/app/initialization.rsc +12 -12
- package/dist/server/.next/server/app/page/app-build-manifest.json +13 -0
- package/dist/server/.next/server/app/page/app-paths-manifest.json +3 -0
- package/dist/server/.next/server/app/page/build-manifest.json +17 -0
- package/dist/server/.next/server/app/page/next-font-manifest.json +6 -0
- package/dist/server/.next/server/app/page/react-loadable-manifest.json +1 -0
- package/dist/server/.next/server/app/page/server-reference-manifest.json +4 -0
- package/dist/server/.next/server/app/page.js +16 -1
- package/dist/server/.next/server/app/page.js.map +5 -0
- package/dist/server/.next/server/app/page.js.nft.json +1 -1
- package/dist/server/.next/server/app/page_client-reference-manifest.js +2 -1
- package/dist/server/.next/server/app-paths-manifest.json +13 -12
- package/dist/server/.next/server/chunks/9bf22_next_37c78c05._.js +15 -0
- package/dist/server/.next/server/chunks/9bf22_next_37c78c05._.js.map +1 -0
- package/dist/server/.next/server/chunks/9bf22_next_dist_6f19b364._.js +22 -0
- package/dist/server/.next/server/chunks/9bf22_next_dist_6f19b364._.js.map +1 -0
- package/dist/server/.next/server/chunks/9bf22_next_dist_7a32bfc3._.js +22 -0
- package/dist/server/.next/server/chunks/9bf22_next_dist_7a32bfc3._.js.map +1 -0
- package/dist/server/.next/server/chunks/9bf22_next_dist_800492fd._.js +4 -0
- package/dist/server/.next/server/chunks/9bf22_next_dist_800492fd._.js.map +1 -0
- package/dist/server/.next/server/chunks/[root-of-the-server]__0111ac14._.js +18 -0
- package/dist/server/.next/server/chunks/[root-of-the-server]__0111ac14._.js.map +1 -0
- package/dist/server/.next/server/chunks/[root-of-the-server]__1efea51d._.js +13 -0
- package/dist/server/.next/server/chunks/[root-of-the-server]__1efea51d._.js.map +1 -0
- package/dist/server/.next/server/chunks/[root-of-the-server]__21616bf9._.js +3 -0
- package/dist/server/.next/server/chunks/[root-of-the-server]__21616bf9._.js.map +1 -0
- package/dist/server/.next/server/chunks/[root-of-the-server]__27f3b464._.js +3 -0
- package/dist/server/.next/server/chunks/[root-of-the-server]__27f3b464._.js.map +1 -0
- package/dist/server/.next/server/chunks/[root-of-the-server]__29969c0b._.js +3 -0
- package/dist/server/.next/server/chunks/[root-of-the-server]__29969c0b._.js.map +1 -0
- package/dist/server/.next/server/chunks/[root-of-the-server]__3da8edfd._.js +3 -0
- package/dist/server/.next/server/chunks/[root-of-the-server]__3da8edfd._.js.map +1 -0
- package/dist/server/.next/server/chunks/[root-of-the-server]__525f44e0._.js +7 -0
- package/dist/server/.next/server/chunks/[root-of-the-server]__525f44e0._.js.map +1 -0
- package/dist/server/.next/server/chunks/[root-of-the-server]__5fde5218._.js +3 -0
- package/dist/server/.next/server/chunks/[root-of-the-server]__5fde5218._.js.map +1 -0
- package/dist/server/.next/server/chunks/[root-of-the-server]__616d1a09._.js +3 -0
- package/dist/server/.next/server/chunks/[root-of-the-server]__616d1a09._.js.map +1 -0
- package/dist/server/.next/server/chunks/[root-of-the-server]__63462bcb._.js +16 -0
- package/dist/server/.next/server/chunks/[root-of-the-server]__63462bcb._.js.map +1 -0
- package/dist/server/.next/server/chunks/[root-of-the-server]__66ca8d3f._.js +11 -0
- package/dist/server/.next/server/chunks/[root-of-the-server]__66ca8d3f._.js.map +1 -0
- package/dist/server/.next/server/chunks/[root-of-the-server]__7a46f739._.js +16 -0
- package/dist/server/.next/server/chunks/[root-of-the-server]__7a46f739._.js.map +1 -0
- package/dist/server/.next/server/chunks/[root-of-the-server]__84542811._.js +8 -0
- package/dist/server/.next/server/chunks/[root-of-the-server]__84542811._.js.map +1 -0
- package/dist/server/.next/server/chunks/[root-of-the-server]__92625851._.js +5 -0
- package/dist/server/.next/server/chunks/[root-of-the-server]__92625851._.js.map +1 -0
- package/dist/server/.next/server/chunks/[root-of-the-server]__9544d1f9._.js +20 -0
- package/dist/server/.next/server/chunks/[root-of-the-server]__9544d1f9._.js.map +1 -0
- package/dist/server/.next/server/chunks/[root-of-the-server]__b68e0025._.js +3 -0
- package/dist/server/.next/server/chunks/[root-of-the-server]__b68e0025._.js.map +1 -0
- package/dist/server/.next/server/chunks/[root-of-the-server]__c43c9880._.js +3 -0
- package/dist/server/.next/server/chunks/[root-of-the-server]__c43c9880._.js.map +1 -0
- package/dist/server/.next/server/chunks/[root-of-the-server]__c513ec4a._.js +8 -0
- package/dist/server/.next/server/chunks/[root-of-the-server]__c513ec4a._.js.map +1 -0
- package/dist/server/.next/server/chunks/[root-of-the-server]__dfe36c1a._.js +3 -0
- package/dist/server/.next/server/chunks/[root-of-the-server]__dfe36c1a._.js.map +1 -0
- package/dist/server/.next/server/chunks/[root-of-the-server]__ec0f2f72._.js +3 -0
- package/dist/server/.next/server/chunks/[root-of-the-server]__ec0f2f72._.js.map +1 -0
- package/dist/server/.next/server/chunks/[root-of-the-server]__ec631eb4._.js +3 -0
- package/dist/server/.next/server/chunks/[root-of-the-server]__ec631eb4._.js.map +1 -0
- package/dist/server/.next/server/chunks/[root-of-the-server]__f6d4fb58._.js +16 -0
- package/dist/server/.next/server/chunks/[root-of-the-server]__f6d4fb58._.js.map +1 -0
- package/dist/server/.next/server/chunks/[root-of-the-server]__fab72f0c._.js +3 -0
- package/dist/server/.next/server/chunks/[root-of-the-server]__fab72f0c._.js.map +1 -0
- package/dist/server/.next/server/chunks/[turbopack]_runtime.js +688 -0
- package/dist/server/.next/server/chunks/[turbopack]_runtime.js.map +10 -0
- package/dist/server/.next/server/chunks/_88faf93c._.js +14 -0
- package/dist/server/.next/server/chunks/_88faf93c._.js.map +1 -0
- package/dist/server/.next/server/chunks/ssr/9bf22_next_dist_05ac4f07._.js +4 -0
- package/dist/server/.next/server/chunks/ssr/9bf22_next_dist_05ac4f07._.js.map +1 -0
- package/dist/server/.next/server/chunks/ssr/9bf22_next_dist_0c9074c5._.js +22 -0
- package/dist/server/.next/server/chunks/ssr/9bf22_next_dist_0c9074c5._.js.map +1 -0
- package/dist/server/.next/server/chunks/ssr/9bf22_next_dist_client_components_forbidden-error_bdb9d650.js +3 -0
- package/dist/server/.next/server/chunks/ssr/9bf22_next_dist_client_components_forbidden-error_bdb9d650.js.map +1 -0
- package/dist/server/.next/server/chunks/ssr/9bf22_next_dist_client_components_unauthorized-error_67370d77.js +3 -0
- package/dist/server/.next/server/chunks/ssr/9bf22_next_dist_client_components_unauthorized-error_67370d77.js.map +1 -0
- package/dist/server/.next/server/chunks/ssr/9bf22_next_f7d8365b._.js +3 -0
- package/dist/server/.next/server/chunks/ssr/9bf22_next_f7d8365b._.js.map +1 -0
- package/dist/server/.next/server/chunks/ssr/[root-of-the-server]__065bacdf._.js +8 -0
- package/dist/server/.next/server/chunks/ssr/[root-of-the-server]__065bacdf._.js.map +1 -0
- package/dist/server/.next/server/chunks/ssr/[root-of-the-server]__63c188bd._.js +3 -0
- package/dist/server/.next/server/chunks/ssr/[root-of-the-server]__63c188bd._.js.map +1 -0
- package/dist/server/.next/server/chunks/ssr/[root-of-the-server]__6d393273._.js +3 -0
- package/dist/server/.next/server/chunks/ssr/[root-of-the-server]__6d393273._.js.map +1 -0
- package/dist/server/.next/server/chunks/ssr/[root-of-the-server]__789bc4bd._.js +3 -0
- package/dist/server/.next/server/chunks/ssr/[root-of-the-server]__789bc4bd._.js.map +1 -0
- package/dist/server/.next/server/chunks/ssr/[root-of-the-server]__b0aa0fa4._.js +6 -0
- package/dist/server/.next/server/chunks/ssr/[root-of-the-server]__b0aa0fa4._.js.map +1 -0
- package/dist/server/.next/server/chunks/ssr/[root-of-the-server]__b3e3ec35._.js +3 -0
- package/dist/server/.next/server/chunks/ssr/[root-of-the-server]__b3e3ec35._.js.map +1 -0
- package/dist/server/.next/server/chunks/ssr/[root-of-the-server]__c53d10ac._.js +3 -0
- package/dist/server/.next/server/chunks/ssr/[root-of-the-server]__c53d10ac._.js.map +1 -0
- package/dist/server/.next/server/chunks/ssr/[root-of-the-server]__f617a52d._.js +3 -0
- package/dist/server/.next/server/chunks/ssr/[root-of-the-server]__f617a52d._.js.map +1 -0
- package/dist/server/.next/server/chunks/ssr/[turbopack]_runtime.js +688 -0
- package/dist/server/.next/server/chunks/ssr/[turbopack]_runtime.js.map +10 -0
- package/dist/server/.next/server/chunks/ssr/_2488faea._.js +61 -0
- package/dist/server/.next/server/chunks/ssr/_2488faea._.js.map +1 -0
- package/dist/server/.next/server/chunks/ssr/_89496b8a._.js +3 -0
- package/dist/server/.next/server/chunks/ssr/_89496b8a._.js.map +1 -0
- package/dist/server/.next/server/chunks/ssr/_b0947ff2._.js +3 -0
- package/dist/server/.next/server/chunks/ssr/_b0947ff2._.js.map +1 -0
- package/dist/server/.next/server/chunks/ssr/_c38b6dab._.js +3 -0
- package/dist/server/.next/server/chunks/ssr/_c38b6dab._.js.map +1 -0
- package/dist/server/.next/server/chunks/ssr/_c9f0c772._.js +3 -0
- package/dist/server/.next/server/chunks/ssr/_c9f0c772._.js.map +1 -0
- package/dist/server/.next/server/chunks/ssr/_e037a20f._.js +4 -0
- package/dist/server/.next/server/chunks/ssr/_e037a20f._.js.map +1 -0
- package/dist/server/.next/server/chunks/ssr/_fbed5872._.js +3 -0
- package/dist/server/.next/server/chunks/ssr/_fbed5872._.js.map +1 -0
- package/dist/server/.next/server/chunks/ssr/node_modules__pnpm_50840a33._.js +3 -0
- package/dist/server/.next/server/chunks/ssr/node_modules__pnpm_50840a33._.js.map +1 -0
- package/dist/server/.next/server/chunks/ssr/node_modules__pnpm_bde53e93._.js +3 -0
- package/dist/server/.next/server/chunks/ssr/node_modules__pnpm_bde53e93._.js.map +1 -0
- package/dist/server/.next/server/chunks/ssr/node_modules__pnpm_da0d20e8._.js +4 -0
- package/dist/server/.next/server/chunks/ssr/node_modules__pnpm_da0d20e8._.js.map +1 -0
- package/dist/server/.next/server/chunks/ssr/packages_server_src_7cef6dbd._.js +3 -0
- package/dist/server/.next/server/chunks/ssr/packages_server_src_7cef6dbd._.js.map +1 -0
- package/dist/server/.next/server/chunks/ssr/packages_server_src_app_eb845476._.js +3 -0
- package/dist/server/.next/server/chunks/ssr/packages_server_src_app_eb845476._.js.map +1 -0
- package/dist/server/.next/server/chunks/ssr/packages_server_src_app_layout_tsx_0712e1b4._.js +3 -0
- package/dist/server/.next/server/chunks/ssr/packages_server_src_app_layout_tsx_0712e1b4._.js.map +1 -0
- package/dist/server/.next/server/middleware-build-manifest.js +33 -1
- package/dist/server/.next/server/middleware-manifest.json +2 -2
- package/dist/server/.next/server/next-font-manifest.js +1 -1
- package/dist/server/.next/server/next-font-manifest.json +6 -1
- package/dist/server/.next/server/pages/404.html +1 -1
- package/dist/server/.next/server/pages/500.html +1 -1
- package/dist/server/.next/server/pages/_app/build-manifest.json +15 -0
- package/dist/server/.next/server/pages/_app/next-font-manifest.json +6 -0
- package/dist/server/.next/server/pages/_app/pages-manifest.json +3 -0
- package/dist/server/.next/server/pages/_app/react-loadable-manifest.json +1 -0
- package/dist/server/.next/server/pages/_app.js +5 -1
- package/dist/server/.next/server/pages/_app.js.map +5 -0
- package/dist/server/.next/server/pages/_app.js.nft.json +1 -1
- package/dist/server/.next/server/pages/_document/next-font-manifest.json +6 -0
- package/dist/server/.next/server/pages/_document/pages-manifest.json +3 -0
- package/dist/server/.next/server/pages/_document/react-loadable-manifest.json +1 -0
- package/dist/server/.next/server/pages/_document.js +6 -1
- package/dist/server/.next/server/pages/_document.js.map +5 -0
- package/dist/server/.next/server/pages/_document.js.nft.json +1 -1
- package/dist/server/.next/server/pages/_error/build-manifest.json +15 -0
- package/dist/server/.next/server/pages/_error/next-font-manifest.json +6 -0
- package/dist/server/.next/server/pages/_error/pages-manifest.json +3 -0
- package/dist/server/.next/server/pages/_error/react-loadable-manifest.json +1 -0
- package/dist/server/.next/server/pages/_error.js +8 -1
- package/dist/server/.next/server/pages/_error.js.map +5 -0
- package/dist/server/.next/server/pages/_error.js.nft.json +1 -1
- package/dist/server/.next/server/pages-manifest.json +1 -1
- package/dist/server/.next/server/server-reference-manifest.js +1 -1
- package/dist/server/.next/server/server-reference-manifest.json +5 -1
- package/dist/server/.next/static/0L93NbbowsMpjl-fJPWIj/_buildManifest.js +1 -0
- package/dist/server/.next/static/0L93NbbowsMpjl-fJPWIj/_ssgManifest.js +1 -0
- package/dist/server/.next/static/CcPdKvbUmZBYZz_Z0RQOI/_buildManifest.js +1 -0
- package/dist/server/.next/static/CcPdKvbUmZBYZz_Z0RQOI/_clientMiddlewareManifest.json +1 -0
- package/dist/server/.next/static/CcPdKvbUmZBYZz_Z0RQOI/_ssgManifest.js +1 -0
- package/dist/server/.next/static/G7Z-m_yayOJWJic2pMxim/_buildManifest.js +1 -0
- package/dist/server/.next/static/G7Z-m_yayOJWJic2pMxim/_clientMiddlewareManifest.json +1 -0
- package/dist/server/.next/static/G7Z-m_yayOJWJic2pMxim/_ssgManifest.js +1 -0
- package/dist/server/.next/static/Vj8TOfdXSkRSgi8JoSCLF/_buildManifest.js +1 -0
- package/dist/server/.next/static/Vj8TOfdXSkRSgi8JoSCLF/_ssgManifest.js +1 -0
- package/dist/server/.next/static/chunks/09f18d884b3a25a2.js.map +1 -0
- package/dist/server/.next/static/chunks/0dfafa95d29e5c79.js +3 -0
- package/dist/server/.next/static/chunks/0e57f1354cda05d5.js +3 -0
- package/dist/server/.next/static/chunks/1923d6510bea25be.js +3 -0
- package/dist/server/.next/static/chunks/1f1c09f06b1f73d5.css +3 -0
- package/dist/server/.next/static/chunks/2316c3dde76bf12d.js.map +1 -0
- package/dist/server/.next/static/chunks/249486689b72c55c.js +3 -0
- package/dist/server/.next/static/chunks/28309924e4c23ccc.js +5 -0
- package/dist/server/.next/static/chunks/2af4b91fa7a98c52.js.map +1 -0
- package/dist/server/.next/static/chunks/2b6075b99689b028.css.map +1 -0
- package/dist/server/.next/static/chunks/2c669537f498f2db.js.map +1 -0
- package/dist/server/.next/static/chunks/371387b426d53320.js +3 -0
- package/dist/server/.next/static/chunks/4553c25757d4836f.js +3 -0
- package/dist/server/.next/static/chunks/4695aadfc21f48b8.js +5 -0
- package/dist/server/.next/static/chunks/512b4b5323114f56.js +61 -0
- package/dist/server/.next/static/chunks/5a52f39dbf60c0c2.js +3 -0
- package/dist/server/.next/static/chunks/5e9dc9d078da6e2d.js.map +1 -0
- package/dist/server/.next/static/chunks/62b241f445063308.js.map +1 -0
- package/dist/server/.next/static/chunks/65c345a4e9ef046d.js.map +1 -0
- package/dist/server/.next/static/chunks/671a03c1fdfc08f8.js.map +1 -0
- package/dist/server/.next/static/chunks/684226c5a0f22bc1.js +3 -0
- package/dist/server/.next/static/chunks/6c6c1dcf9e7e2204.js.map +1 -0
- package/dist/server/.next/static/chunks/76692beeeb707278.css.map +1 -0
- package/dist/server/.next/static/chunks/7d7379cdf8fe9ec5.js +3 -0
- package/dist/server/.next/static/chunks/84f5ecdc99cc0be6.js.map +1 -0
- package/dist/server/.next/static/chunks/86b5e8830b67bd88.js.map +1 -0
- package/dist/server/.next/static/chunks/8969a52917bb9c0d.js.map +1 -0
- package/dist/server/.next/static/chunks/8d6bbd36cdf03018.js +5 -0
- package/dist/server/.next/static/chunks/9af4740ebb92591d.js.map +1 -0
- package/dist/server/.next/static/chunks/a7b45611d4ad55fe.js +4 -0
- package/dist/server/.next/static/chunks/a9cba6096fe97a30.js +5 -0
- package/dist/server/.next/static/chunks/c2cc02f47cf64419.js.map +1 -0
- package/dist/server/.next/static/chunks/cf3b2abf3523d13f.js +3 -0
- package/dist/server/.next/static/chunks/cf6e515377591a1f.js +3 -0
- package/dist/server/.next/static/chunks/d0ab7593ca8c77ca.js.map +1 -0
- package/dist/server/.next/static/chunks/d5028315079b40b4.js +5 -0
- package/dist/server/.next/static/chunks/da35f4984aadc7ee.css +3 -0
- package/dist/server/.next/static/chunks/ebfa652ea6e39124.js.map +1 -0
- package/dist/server/.next/static/chunks/ec548c7ce307cf6d.js +1 -0
- package/dist/server/.next/static/chunks/ecfccf4677b4777a.js +3 -0
- package/dist/server/.next/static/chunks/fc31ec097889736e.js +61 -0
- package/dist/server/.next/static/chunks/ffb74809cc596ae9.js.map +1 -0
- package/dist/server/.next/static/chunks/pages/_app.js +5 -0
- package/dist/server/.next/static/chunks/pages/_error.js +5 -0
- package/dist/server/.next/static/media/favicon.45db1c09.ico +0 -0
- package/dist/server/.next/static/qPRyAah5ijpk6JBI-hD27/_buildManifest.js +1 -0
- package/dist/server/.next/static/qPRyAah5ijpk6JBI-hD27/_clientMiddlewareManifest.json +1 -0
- package/dist/server/.next/static/qPRyAah5ijpk6JBI-hD27/_ssgManifest.js +1 -0
- package/dist/server/.next/trace +1 -4
- package/dist/server/.next/transform.js +7 -0
- package/dist/server/.next/transform.js.map +5 -0
- package/dist/server/.next/turbopack +0 -0
- package/package.json +1 -1
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
module.exports={45935:function(e){var{g:t,__dirname:n,m:o,e:r}=e;o.exports=e.x("next/dist/server/app-render/after-task-async-storage.external.js",()=>require("next/dist/server/app-render/after-task-async-storage.external.js"))},35692:e=>{"use strict";var{g:t,__dirname:n}=e;e.s({ProjectStatus:()=>c,getProjectsConfig:()=>s,saveProjectsConfig:()=>a});var o=e.i(9892),r=e.i(88941);async function s(){try{await (0,o.access)(r.PROJECT_CONFIG_PATH,o.constants.F_OK)}catch{return await a({}),{}}try{let e=await (0,o.readFile)(r.PROJECT_CONFIG_PATH,"utf-8");if(!e)return{};return JSON.parse(e)}catch(e){throw console.error("读取或解析项目配置文件失败:",e),Error("无法加载项目配置")}}async function a(e){let t=r.PROJECT_CONFIG_PATH+".tmp";try{await (0,o.writeFile)(t,JSON.stringify(e,null,2),"utf-8"),await (0,o.rename)(t,r.PROJECT_CONFIG_PATH)}catch(e){throw console.error("保存项目配置文件失败:",e),Error("无法保存项目配置")}}var c=function(e){return e.PENDING="pending",e.EXISTING="existing",e.CLONING="cloning",e.SUCCESS="success",e.FAILED="failed",e.RETRYING="retrying",e}({})},88941:e=>{"use strict";var{g:t,__dirname:n}=e;{e.s({PROJECT_CONFIG_PATH:()=>n,ProjectStatus:()=>s,WORKSPACE_CONFIG:()=>t});var o=e.i(13442),r=e.i(30331);let t={WORKSPACE_ROOT:(0,r.join)((0,o.homedir)(),"Documents","prime-workspace"),GIT_TIMEOUT:3e5,MAX_CONCURRENT_CLONES:Math.max(2,Math.min((0,o.cpus)().length,8)),MAX_RETRY_ATTEMPTS:3},n=(0,r.join)((0,o.homedir)(),".prime-projects.json");var s=function(e){return e.PENDING="pending",e.EXISTING="existing",e.CLONING="cloning",e.SUCCESS="success",e.FAILED="failed",e.RETRYING="retrying",e.INCOMPLETE="incomplete",e}({})}},29549:function(e){var{g:t,__dirname:n,m:o,e:r}=e;o.exports=e.x("next/dist/compiled/next-server/app-page-turbo.runtime.prod.js",()=>require("next/dist/compiled/next-server/app-page-turbo.runtime.prod.js"))},83943:function(e){var{g:t,__dirname:n,m:o,e:r}=e;o.exports=e.x("next/dist/server/app-render/work-unit-async-storage.external.js",()=>require("next/dist/server/app-render/work-unit-async-storage.external.js"))},86103:function(e){var{g:t,__dirname:n,m:o,e:r}=e;o.exports=e.x("next/dist/server/app-render/work-async-storage.external.js",()=>require("next/dist/server/app-render/work-async-storage.external.js"))},30331:function(e){var{g:t,__dirname:n,m:o,e:r}=e;o.exports=e.x("path",()=>require("path"))},23430:function(e){var{g:t,__dirname:n,m:o,e:r}=e;o.exports=e.x("next/dist/compiled/@opentelemetry/api",()=>require("next/dist/compiled/@opentelemetry/api"))},13442:function(e){var{g:t,__dirname:n,m:o,e:r}=e;o.exports=e.x("os",()=>require("os"))},52670:function(e){var{g:t,__dirname:n,m:o,e:r}=e;o.exports=e.x("next/dist/compiled/next-server/app-route-turbo.runtime.prod.js",()=>require("next/dist/compiled/next-server/app-route-turbo.runtime.prod.js"))},9892:function(e){var{g:t,__dirname:n,m:o,e:r}=e;o.exports=e.x("fs/promises",()=>require("fs/promises"))},94722:e=>{"use strict";var{g:t,__dirname:n}=e;{e.s({sseConnectionManager:()=>n});class t{connections=new Map;encoder=new TextEncoder;heartbeatInterval=null;HEARTBEAT_INTERVAL=3e4;CONNECTION_TIMEOUT=12e4;constructor(){this.startHeartbeat()}addConnection(e,t,n){console.log(`[SSE] 添加连接: 环境=${e}, 客户端=${n}`);let o={controller:t,timestamp:Date.now(),clientId:n,envName:e};this.connections.has(e)||this.connections.set(e,new Set),this.connections.get(e).add(o),this.sendToConnection(o,{type:"heartbeat",timestamp:Date.now()}),console.log(`[SSE] 当前连接统计: ${this.getConnectionStats()}`)}removeConnection(e,t){console.log(`[SSE] 移除连接: 环境=${e}, 客户端=${t}`);let n=this.connections.get(e);if(n){let o=Array.from(n).find(e=>e.clientId===t);o&&(n.delete(o),0===n.size&&this.connections.delete(e))}console.log(`[SSE] 当前连接统计: ${this.getConnectionStats()}`)}broadcastToEnv(e,t){console.log(`[SSE] 向环境 ${e} 广播配置变化消息`);let n=this.connections.get(e);if(!n||0===n.size)return void console.log(`[SSE] 环境 ${e} 没有活跃连接,跳过广播`);let o=[];n.forEach(e=>{try{this.sendToConnection(e,t)}catch(t){console.error(`[SSE] 发送消息到客户端 ${e.clientId} 失败:`,t),o.push(e)}}),o.forEach(e=>{n.delete(e),console.log(`[SSE] 清理无效连接: 客户端=${e.clientId}`)}),console.log(`[SSE] 成功发送给 ${n.size} 个连接`)}sendToConnection(e,t){let n=`data: ${JSON.stringify(t)}
|
|
2
|
+
|
|
3
|
+
`,o=this.encoder.encode(n);try{e.controller.enqueue(o),e.timestamp=Date.now()}catch(e){throw console.error(`[SSE] 发送消息失败:`,e),e}}startHeartbeat(){this.heartbeatInterval=setInterval(()=>{this.sendHeartbeat(),this.cleanupStaleConnections()},this.HEARTBEAT_INTERVAL),console.log(`[SSE] 心跳机制已启动,间隔: ${this.HEARTBEAT_INTERVAL}ms`)}sendHeartbeat(){let e={type:"heartbeat",timestamp:Date.now()},t=0;this.connections.forEach(n=>{t+=n.size;let o=[];n.forEach(t=>{try{this.sendToConnection(t,e)}catch{o.push(t)}}),o.forEach(e=>n.delete(e))}),t>0&&console.log(`[SSE] 心跳发送完成,活跃连接数: ${t}`)}cleanupStaleConnections(){let e=Date.now(),t=0;this.connections.forEach((n,o)=>{let r=[];n.forEach(t=>{e-t.timestamp>this.CONNECTION_TIMEOUT&&r.push(t)}),r.forEach(e=>{n.delete(e),t++,console.log(`[SSE] 清理过期连接: 环境=${o}, 客户端=${e.clientId}`)}),0===n.size&&this.connections.delete(o)}),t>0&&console.log(`[SSE] 连接清理完成,清理数量: ${t}`)}getConnectionStats(){let e=[],t=0;return this.connections.forEach((n,o)=>{let r=n.size;t+=r,e.push(`${o}: ${r}`)}),`总计 ${t} 个连接 (${e.join(", ")})`}stop(){this.heartbeatInterval&&(clearInterval(this.heartbeatInterval),this.heartbeatInterval=null,console.log(`[SSE] 心跳机制已停止`)),this.connections.forEach(e=>{e.forEach(e=>{try{e.controller.close()}catch(e){console.error(`[SSE] 关闭连接失败:`,e)}})}),this.connections.clear(),console.log(`[SSE] 所有连接已关闭`)}}let n=new t;process.on("SIGINT",()=>{console.log("[SSE] 收到退出信号,正在清理连接..."),n.stop(),process.exit(0)}),process.on("SIGTERM",()=>{console.log("[SSE] 收到终止信号,正在清理连接..."),n.stop(),process.exit(0)})}},90449:function(e){var{g:t,__dirname:n,m:o,e:r}=e},36628:e=>{"use strict";var{g:t,__dirname:n}=e;e.s({GET:()=>a,OPTIONS:()=>c});var o=e.i(15494),r=e.i(94722),s=e.i(35692);async function a(e){let{searchParams:t}=new URL(e.url),n=t.get("env"),a=t.get("clientId")||`client-${Date.now()}-${Math.random().toString(36).substr(2,9)}`;if(!n)return o.NextResponse.json({success:!1,error:"缺少必要参数:env(环境名称)"},{status:400});try{let e=await (0,s.getProjectsConfig)(),t=!1;for(let[,o]of Object.entries(e))if(o.envs&&o.envs[n]){t=!0;break}if(!t)return o.NextResponse.json({success:!1,error:`环境 "${n}" 不存在于任何项目中`},{status:404});console.log(`[SSE] 新的连接请求: 环境=${n}, 客户端=${a}`);let c=new TextEncoder,i=new ReadableStream({start(e){r.sseConnectionManager.addConnection(n,e,a);let t={type:"connection-established",envName:n,clientId:a,timestamp:Date.now(),message:`已连接到环境 ${n} 的配置变化推送流`},o=`data: ${JSON.stringify(t)}
|
|
4
|
+
|
|
5
|
+
`;e.enqueue(c.encode(o))},cancel(){console.log(`[SSE] 连接取消: 环境=${n}, 客户端=${a}`),r.sseConnectionManager.removeConnection(n,a)}});return new Response(i,{status:200,headers:{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive","Access-Control-Allow-Origin":"*","Access-Control-Allow-Methods":"GET","Access-Control-Allow-Headers":"Cache-Control, Content-Type"}})}catch(t){let e=t instanceof Error?t.message:"SSE连接建立失败";return console.error(`[SSE] 连接建立失败: 环境=${n}, 客户端=${a}`,t),o.NextResponse.json({success:!1,error:e},{status:500})}}async function c(){return new Response(null,{status:200,headers:{"Access-Control-Allow-Origin":"*","Access-Control-Allow-Methods":"GET, OPTIONS","Access-Control-Allow-Headers":"Content-Type, Cache-Control","Access-Control-Max-Age":"86400"}})}},61976:e=>{"use strict";var{g:t,__dirname:n}=e;{e.s({patchFetch:()=>c,routeModule:()=>t,serverHooks:()=>l,workAsyncStorage:()=>n,workUnitAsyncStorage:()=>i});var o=e.i(45746),r=e.i(93828),s=e.i(18250),a=e.i(36628);let t=new o.AppRouteRouteModule({definition:{kind:r.RouteKind.APP_ROUTE,page:"/api/microapp-proxy-change-stream/route",pathname:"/api/microapp-proxy-change-stream",filename:"route",bundlePath:""},resolvedPagePath:"[project]/packages/server/src/app/api/microapp-proxy-change-stream/route.ts",nextConfigOutput:"",userland:a}),{workAsyncStorage:n,workUnitAsyncStorage:i,serverHooks:l}=t;function c(){return(0,s.patchFetch)({workAsyncStorage:n,workUnitAsyncStorage:i})}}}};
|
|
6
|
+
|
|
7
|
+
//# sourceMappingURL=%5Broot-of-the-server%5D__525f44e0._.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["turbopack:///[project]/packages/server/src/lib/workspace-config.ts","turbopack:///[project]/packages/server/src/lib/workspace-types.ts","turbopack:///[project]/packages/server/src/lib/sse-connection-manager.ts","turbopack:///[project]/packages/server/src/app/api/microapp-proxy-change-stream/route.ts","turbopack:///[project]/node_modules/.pnpm/next@15.3.4_react-dom@19.1.0_react@19.1.0__react@19.1.0/node_modules/next/dist/src/build/templates/app-route.ts"],"sourcesContent":["import { readFile, writeFile, access, constants, rename } from 'fs/promises';\nimport type { ProjectsConfig } from './workspace-types';\nimport { PROJECT_CONFIG_PATH } from './workspace-types';\n\n/**\n * 读取并解析项目配置文件\n * @returns {Promise<ProjectsConfig>} 项目配置对象\n */\nexport async function getProjectsConfig(): Promise<ProjectsConfig> {\n try {\n await access(PROJECT_CONFIG_PATH, constants.F_OK);\n } catch {\n // 文件不存在,创建并写入空对象\n await saveProjectsConfig({});\n return {};\n }\n\n try {\n const configContent = await readFile(PROJECT_CONFIG_PATH, 'utf-8');\n // 如果文件为空,返回空对象\n if (!configContent) {\n return {};\n }\n return JSON.parse(configContent);\n } catch (error) {\n console.error('读取或解析项目配置文件失败:', error);\n // 在出错时返回空对象或抛出错误,这里选择抛出以通知调用者\n throw new Error('无法加载项目配置');\n }\n}\n\n/**\n * 将项目配置写入文件(原子操作)\n * @param {ProjectsConfig} config - 要保存的配置对象\n */\nexport async function saveProjectsConfig(config: ProjectsConfig): Promise<void> {\n const tempConfigPath = PROJECT_CONFIG_PATH + '.tmp';\n try {\n await writeFile(tempConfigPath, JSON.stringify(config, null, 2), 'utf-8');\n await rename(tempConfigPath, PROJECT_CONFIG_PATH);\n } catch (error) {\n console.error('保存项目配置文件失败:', error);\n throw new Error('无法保存项目配置');\n }\n}\n\n/**\n * 项目状态枚举\n */\nexport enum ProjectStatus {\n PENDING = 'pending',\n EXISTING = 'existing',\n CLONING = 'cloning',\n SUCCESS = 'success',\n FAILED = 'failed',\n RETRYING = 'retrying',\n}\n\n/**\n * 项目进度信息接口\n */\nexport interface ProjectProgress {\n projectName: string;\n status: ProjectStatus;\n progress: number; // 0-100\n message: string;\n error?: string;\n startTime?: number;\n endTime?: number;\n}\n\n/**\n * 初始化结果接口\n */\nexport interface InitializationResult {\n success: boolean;\n totalProjects: number;\n successCount: number;\n failedCount: number;\n failedProjects: string[];\n workspacePath: string;\n duration: number;\n}\n\n/**\n * Git 操作配置接口\n */\nexport interface GitOperationConfig {\n repoUrl: string;\n targetDir: string;\n timeout: number;\n onProgress?: (progress: number, message: string) => void;\n onError?: (error: string) => void;\n}","import { homedir, cpus } from 'os';\nimport { join } from 'path';\n\n/**\n * 工作空间配置常量\n */\nexport const WORKSPACE_CONFIG = {\n // 工作空间根目录路径\n WORKSPACE_ROOT: join(homedir(), 'Documents', 'prime-workspace'),\n\n // Git 操作超时时间 (毫秒)\n GIT_TIMEOUT: 300000, // 5分钟\n\n // 最大并发克隆数量(基于CPU核心数,最小2个,最大8个)\n MAX_CONCURRENT_CLONES: Math.max(2, Math.min(cpus().length, 8)),\n\n // 重试次数限制\n MAX_RETRY_ATTEMPTS: 3,\n} as const;\n\nexport const PROJECT_CONFIG_PATH = join(homedir(), '.prime-projects.json');\n\nexport interface ProjectConfig {\n repo: string;\n mockingIntercept?: boolean;\n mockOpen?: boolean;\n envs: {\n [envName: string]: {\n host: string;\n currentProxy: string;\n proxyEnv: {\n [key: string]: string;\n };\n envFileName: string;\n proxyKey: string;\n subApps?: string[];\n };\n };\n}\n\nexport interface ProjectsConfig {\n [projectName: string]: ProjectConfig;\n}\n\n/**\n * 项目状态枚举\n */\nexport enum ProjectStatus {\n PENDING = 'pending',\n EXISTING = 'existing',\n CLONING = 'cloning',\n SUCCESS = 'success',\n FAILED = 'failed',\n RETRYING = 'retrying',\n INCOMPLETE = 'incomplete', // 不完整的项目,需要清理\n}\n\n/**\n * 项目进度信息接口\n */\nexport interface ProjectProgress {\n projectName: string;\n status: ProjectStatus;\n progress: number; // 0-100\n message: string;\n error?: string;\n startTime?: number;\n endTime?: number;\n}\n\n/**\n * 初始化结果接口\n */\nexport interface InitializationResult {\n success: boolean;\n totalProjects: number;\n successCount: number;\n failedCount: number;\n failedProjects: string[];\n workspacePath: string;\n duration: number;\n}\n\n/**\n * Git 操作配置接口\n */\nexport interface GitOperationConfig {\n repoUrl: string;\n targetDir: string;\n timeout: number;\n onProgress?: (progress: number, message: string) => void;\n onError?: (error: string) => void;\n onLog?: (projectName: string, logType: 'stdout' | 'stderr' | 'progress', content: string) => void;\n} ","/**\n * SSE连接管理器\n * 用于管理MicroApp代理配置变化推送的SSE连接\n */\n\nexport interface ConnectionInfo {\n controller: ReadableStreamDefaultController<Uint8Array>;\n timestamp: number;\n clientId: string;\n envName: string;\n}\n\nexport interface ConfigChangeMessage {\n type: 'microapp-proxy-config-change';\n envName: string;\n timestamp: number;\n changes: {\n before: string[];\n after: string[];\n added: string[];\n removed: string[];\n };\n projectName: string;\n message: string;\n}\n\nexport interface HeartbeatMessage {\n type: 'heartbeat';\n timestamp: number;\n}\n\ntype SSEMessage = ConfigChangeMessage | HeartbeatMessage;\n\n/**\n * SSE连接管理器类\n */\nclass SSEConnectionManager {\n private connections = new Map<string, Set<ConnectionInfo>>();\n private encoder = new TextEncoder();\n private heartbeatInterval: NodeJS.Timeout | null = null;\n private readonly HEARTBEAT_INTERVAL = 30000; // 30秒心跳\n private readonly CONNECTION_TIMEOUT = 120000; // 2分钟连接超时\n\n constructor() {\n this.startHeartbeat();\n }\n\n /**\n * 添加新的SSE连接\n */\n addConnection(envName: string, controller: ReadableStreamDefaultController<Uint8Array>, clientId: string): void {\n console.log(`[SSE] 添加连接: 环境=${envName}, 客户端=${clientId}`);\n \n const connectionInfo: ConnectionInfo = {\n controller,\n timestamp: Date.now(),\n clientId,\n envName,\n };\n\n if (!this.connections.has(envName)) {\n this.connections.set(envName, new Set());\n }\n \n this.connections.get(envName)!.add(connectionInfo);\n \n // 发送连接确认消息\n this.sendToConnection(connectionInfo, {\n type: 'heartbeat',\n timestamp: Date.now(),\n });\n\n console.log(`[SSE] 当前连接统计: ${this.getConnectionStats()}`);\n }\n\n /**\n * 移除SSE连接\n */\n removeConnection(envName: string, clientId: string): void {\n console.log(`[SSE] 移除连接: 环境=${envName}, 客户端=${clientId}`);\n \n const connections = this.connections.get(envName);\n if (connections) {\n const connectionToRemove = Array.from(connections).find(conn => conn.clientId === clientId);\n if (connectionToRemove) {\n connections.delete(connectionToRemove);\n \n // 如果该环境没有连接了,删除整个entry\n if (connections.size === 0) {\n this.connections.delete(envName);\n }\n }\n }\n\n console.log(`[SSE] 当前连接统计: ${this.getConnectionStats()}`);\n }\n\n /**\n * 向指定环境广播消息\n */\n broadcastToEnv(envName: string, message: ConfigChangeMessage): void {\n console.log(`[SSE] 向环境 ${envName} 广播配置变化消息`);\n \n const connections = this.connections.get(envName);\n if (!connections || connections.size === 0) {\n console.log(`[SSE] 环境 ${envName} 没有活跃连接,跳过广播`);\n return;\n }\n\n const deadConnections: ConnectionInfo[] = [];\n \n connections.forEach(connectionInfo => {\n try {\n this.sendToConnection(connectionInfo, message);\n } catch (error) {\n console.error(`[SSE] 发送消息到客户端 ${connectionInfo.clientId} 失败:`, error);\n deadConnections.push(connectionInfo);\n }\n });\n\n // 清理无效连接\n deadConnections.forEach(conn => {\n connections.delete(conn);\n console.log(`[SSE] 清理无效连接: 客户端=${conn.clientId}`);\n });\n\n console.log(`[SSE] 成功发送给 ${connections.size} 个连接`);\n }\n\n /**\n * 向单个连接发送消息\n */\n private sendToConnection(connectionInfo: ConnectionInfo, message: SSEMessage): void {\n const data = `data: ${JSON.stringify(message)}\\n\\n`;\n const encodedData = this.encoder.encode(data);\n \n try {\n connectionInfo.controller.enqueue(encodedData);\n connectionInfo.timestamp = Date.now(); // 更新最后活跃时间\n } catch (error) {\n console.error(`[SSE] 发送消息失败:`, error);\n throw error;\n }\n }\n\n /**\n * 启动心跳机制\n */\n private startHeartbeat(): void {\n this.heartbeatInterval = setInterval(() => {\n this.sendHeartbeat();\n this.cleanupStaleConnections();\n }, this.HEARTBEAT_INTERVAL);\n \n console.log(`[SSE] 心跳机制已启动,间隔: ${this.HEARTBEAT_INTERVAL}ms`);\n }\n\n /**\n * 发送心跳消息\n */\n private sendHeartbeat(): void {\n const heartbeatMessage: HeartbeatMessage = {\n type: 'heartbeat',\n timestamp: Date.now(),\n };\n\n let totalConnections = 0;\n this.connections.forEach((connections) => {\n totalConnections += connections.size;\n const deadConnections: ConnectionInfo[] = [];\n \n connections.forEach(connectionInfo => {\n try {\n this.sendToConnection(connectionInfo, heartbeatMessage);\n } catch {\n deadConnections.push(connectionInfo);\n }\n });\n\n // 清理无效连接\n deadConnections.forEach(conn => connections.delete(conn));\n });\n\n if (totalConnections > 0) {\n console.log(`[SSE] 心跳发送完成,活跃连接数: ${totalConnections}`);\n }\n }\n\n /**\n * 清理过期连接\n */\n private cleanupStaleConnections(): void {\n const now = Date.now();\n let cleanedCount = 0;\n\n this.connections.forEach((connections, envName) => {\n const staleConnections: ConnectionInfo[] = [];\n \n connections.forEach(connectionInfo => {\n if (now - connectionInfo.timestamp > this.CONNECTION_TIMEOUT) {\n staleConnections.push(connectionInfo);\n }\n });\n\n staleConnections.forEach(conn => {\n connections.delete(conn);\n cleanedCount++;\n console.log(`[SSE] 清理过期连接: 环境=${envName}, 客户端=${conn.clientId}`);\n });\n\n // 如果该环境没有连接了,删除整个entry\n if (connections.size === 0) {\n this.connections.delete(envName);\n }\n });\n\n if (cleanedCount > 0) {\n console.log(`[SSE] 连接清理完成,清理数量: ${cleanedCount}`);\n }\n }\n\n /**\n * 获取连接统计信息\n */\n getConnectionStats(): string {\n const stats: string[] = [];\n let totalConnections = 0;\n \n this.connections.forEach((connections, envName) => {\n const count = connections.size;\n totalConnections += count;\n stats.push(`${envName}: ${count}`);\n });\n\n return `总计 ${totalConnections} 个连接 (${stats.join(', ')})`;\n }\n\n /**\n * 停止连接管理器\n */\n stop(): void {\n if (this.heartbeatInterval) {\n clearInterval(this.heartbeatInterval);\n this.heartbeatInterval = null;\n console.log(`[SSE] 心跳机制已停止`);\n }\n\n // 关闭所有连接\n this.connections.forEach((connections) => {\n connections.forEach(connectionInfo => {\n try {\n connectionInfo.controller.close();\n } catch (error) {\n console.error(`[SSE] 关闭连接失败:`, error);\n }\n });\n });\n\n this.connections.clear();\n console.log(`[SSE] 所有连接已关闭`);\n }\n}\n\n// 创建全局实例\nexport const sseConnectionManager = new SSEConnectionManager();\n\n// 在进程退出时清理资源\nprocess.on('SIGINT', () => {\n console.log('[SSE] 收到退出信号,正在清理连接...');\n sseConnectionManager.stop();\n process.exit(0);\n});\n\nprocess.on('SIGTERM', () => {\n console.log('[SSE] 收到终止信号,正在清理连接...');\n sseConnectionManager.stop();\n process.exit(0);\n}); ","import { NextRequest, NextResponse } from 'next/server';\nimport { sseConnectionManager } from '@/lib/sse-connection-manager';\nimport { getProjectsConfig } from '@/lib/workspace-config';\n\n/**\n * MicroApp代理配置变化推送 SSE 端点\n * \n * 查询参数:\n * - env: 需要监听的环境名称\n * - clientId: 客户端标识符(可选,用于连接管理)\n */\nexport async function GET(request: NextRequest): Promise<Response> {\n const { searchParams } = new URL(request.url);\n const envName = searchParams.get('env');\n const clientId = searchParams.get('clientId') || `client-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n\n // 参数验证\n if (!envName) {\n return NextResponse.json(\n { \n success: false, \n error: '缺少必要参数:env(环境名称)' \n },\n { status: 400 }\n );\n }\n\n try {\n // 验证环境是否存在\n const projectsConfig = await getProjectsConfig();\n let envExists = false;\n \n // 检查所有项目中是否存在指定环境\n for (const [, projectConfig] of Object.entries(projectsConfig)) {\n if (projectConfig.envs && projectConfig.envs[envName]) {\n envExists = true;\n break;\n }\n }\n\n if (!envExists) {\n return NextResponse.json(\n { \n success: false, \n error: `环境 \"${envName}\" 不存在于任何项目中` \n },\n { status: 404 }\n );\n }\n\n console.log(`[SSE] 新的连接请求: 环境=${envName}, 客户端=${clientId}`);\n\n // 创建SSE流\n const encoder = new TextEncoder();\n \n const stream = new ReadableStream({\n start(controller) {\n // 添加连接到管理器\n sseConnectionManager.addConnection(envName, controller, clientId);\n\n // 发送初始连接成功消息\n const initialMessage = {\n type: 'connection-established' as const,\n envName,\n clientId,\n timestamp: Date.now(),\n message: `已连接到环境 ${envName} 的配置变化推送流`\n };\n\n const data = `data: ${JSON.stringify(initialMessage)}\\n\\n`;\n controller.enqueue(encoder.encode(data));\n },\n\n cancel() {\n // 连接取消时清理\n console.log(`[SSE] 连接取消: 环境=${envName}, 客户端=${clientId}`);\n sseConnectionManager.removeConnection(envName, clientId);\n }\n });\n\n // 返回SSE响应\n return new Response(stream, {\n status: 200,\n headers: {\n 'Content-Type': 'text/event-stream',\n 'Cache-Control': 'no-cache',\n 'Connection': 'keep-alive',\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Methods': 'GET',\n 'Access-Control-Allow-Headers': 'Cache-Control, Content-Type',\n },\n });\n\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'SSE连接建立失败';\n console.error(`[SSE] 连接建立失败: 环境=${envName}, 客户端=${clientId}`, error);\n \n return NextResponse.json(\n { \n success: false, \n error: errorMessage \n },\n { status: 500 }\n );\n }\n}\n\n/**\n * 处理预检请求\n */\nexport async function OPTIONS(): Promise<Response> {\n return new Response(null, {\n status: 200,\n headers: {\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Methods': 'GET, OPTIONS',\n 'Access-Control-Allow-Headers': 'Content-Type, Cache-Control',\n 'Access-Control-Max-Age': '86400',\n },\n });\n} ","import {\n AppRouteRouteModule,\n type AppRouteRouteModuleOptions,\n} from '../../server/route-modules/app-route/module.compiled'\nimport { RouteKind } from '../../server/route-kind'\nimport { patchFetch as _patchFetch } from '../../server/lib/patch-fetch'\n\nimport * as userland from 'VAR_USERLAND'\n\n// These are injected by the loader afterwards. This is injected as a variable\n// instead of a replacement because this could also be `undefined` instead of\n// an empty string.\ndeclare const nextConfigOutput: AppRouteRouteModuleOptions['nextConfigOutput']\n\n// We inject the nextConfigOutput here so that we can use them in the route\n// module.\n// INJECT:nextConfigOutput\n\nconst routeModule = new AppRouteRouteModule({\n definition: {\n kind: RouteKind.APP_ROUTE,\n page: 'VAR_DEFINITION_PAGE',\n pathname: 'VAR_DEFINITION_PATHNAME',\n filename: 'VAR_DEFINITION_FILENAME',\n bundlePath: 'VAR_DEFINITION_BUNDLE_PATH',\n },\n resolvedPagePath: 'VAR_RESOLVED_PAGE_PATH',\n nextConfigOutput,\n userland,\n})\n\n// Pull out the exports that we need to expose from the module. This should\n// be eliminated when we've moved the other routes to the new format. These\n// are used to hook into the route.\nconst { workAsyncStorage, workUnitAsyncStorage, serverHooks } = routeModule\n\nfunction patchFetch() {\n return _patchFetch({\n workAsyncStorage,\n workUnitAsyncStorage,\n })\n}\n\nexport {\n routeModule,\n workAsyncStorage,\n workUnitAsyncStorage,\n serverHooks,\n patchFetch,\n}\n"],"names":["AppRouteRouteModule","RouteKind","patchFetch","_patchFetch","userland","routeModule","definition","kind","APP_ROUTE","page","pathname","filename","bundlePath","resolvedPagePath","nextConfigOutput","workAsyncStorage","workUnitAsyncStorage","serverHooks"],"mappings":"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","ignoreList":[4]}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
module.exports={45935:function(e){var{g:r,__dirname:t,m:n,e:s}=e;n.exports=e.x("next/dist/server/app-render/after-task-async-storage.external.js",()=>require("next/dist/server/app-render/after-task-async-storage.external.js"))},29549:function(e){var{g:r,__dirname:t,m:n,e:s}=e;n.exports=e.x("next/dist/compiled/next-server/app-page-turbo.runtime.prod.js",()=>require("next/dist/compiled/next-server/app-page-turbo.runtime.prod.js"))},83943:function(e){var{g:r,__dirname:t,m:n,e:s}=e;n.exports=e.x("next/dist/server/app-render/work-unit-async-storage.external.js",()=>require("next/dist/server/app-render/work-unit-async-storage.external.js"))},86103:function(e){var{g:r,__dirname:t,m:n,e:s}=e;n.exports=e.x("next/dist/server/app-render/work-async-storage.external.js",()=>require("next/dist/server/app-render/work-async-storage.external.js"))},23430:function(e){var{g:r,__dirname:t,m:n,e:s}=e;n.exports=e.x("next/dist/compiled/@opentelemetry/api",()=>require("next/dist/compiled/@opentelemetry/api"))},52670:function(e){var{g:r,__dirname:t,m:n,e:s}=e;n.exports=e.x("next/dist/compiled/next-server/app-route-turbo.runtime.prod.js",()=>require("next/dist/compiled/next-server/app-route-turbo.runtime.prod.js"))},61978:function(e){var{g:r,__dirname:t,m:n,e:s}=e;"use strict";n.exports=e.r(29549)},94507:function(e){var{g:r,__dirname:t,m:n,e:s}=e;"use strict";n.exports=e.r(61978).vendored["react-rsc"].React},53679:function(e){var{g:r,__dirname:t,m:n,e:s}=e}};
|
|
2
|
+
|
|
3
|
+
//# sourceMappingURL=%5Broot-of-the-server%5D__5fde5218._.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["turbopack:///[project]/node_modules/.pnpm/next@15.3.4_react-dom@19.1.0_react@19.1.0__react@19.1.0/node_modules/next/src/server/route-modules/app-page/module.compiled.js","turbopack:///[project]/node_modules/.pnpm/next@15.3.4_react-dom@19.1.0_react@19.1.0__react@19.1.0/node_modules/next/src/server/route-modules/app-page/vendored/rsc/react.ts"],"sourcesContent":["if (process.env.NEXT_RUNTIME === 'edge') {\n module.exports = require('next/dist/server/route-modules/app-page/module.js')\n} else {\n if (process.env.__NEXT_EXPERIMENTAL_REACT) {\n if (process.env.NODE_ENV === 'development') {\n if (process.env.TURBOPACK) {\n module.exports = require('next/dist/compiled/next-server/app-page-turbo-experimental.runtime.dev.js')\n } else {\n module.exports = require('next/dist/compiled/next-server/app-page-experimental.runtime.dev.js')\n }\n } else {\n if (process.env.TURBOPACK) {\n module.exports = require('next/dist/compiled/next-server/app-page-turbo-experimental.runtime.prod.js')\n } else {\n module.exports = require('next/dist/compiled/next-server/app-page-experimental.runtime.prod.js')\n }\n }\n } else {\n if (process.env.NODE_ENV === 'development') {\n if (process.env.TURBOPACK) {\n module.exports = require('next/dist/compiled/next-server/app-page-turbo.runtime.dev.js')\n } else {\n module.exports = require('next/dist/compiled/next-server/app-page.runtime.dev.js')\n }\n } else {\n if (process.env.TURBOPACK) {\n module.exports = require('next/dist/compiled/next-server/app-page-turbo.runtime.prod.js')\n } else {\n module.exports = require('next/dist/compiled/next-server/app-page.runtime.prod.js')\n }\n }\n }\n}\n","module.exports = require('../../module.compiled').vendored['react-rsc'].React\n"],"names":["process","env","NEXT_RUNTIME","__NEXT_EXPERIMENTAL_REACT","NODE_ENV","TURBOPACK","module","exports","require","vendored","React"],"mappings":"wvCA0BQM,EAAOC,OAAO,CAAGC,EAAQ,CAAA,CAAA,IAAA,kEC1BjCF,EAAOC,OAAO,CAAGC,EAAQ,CAAA,CAAA,IAAA,GAAyBC,QAAQ,CAAC,YAAY,CAACC,KAAK","ignoreList":[0,1]}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
module.exports={45935:function(e){var{g:r,__dirname:t,m:s,e:n}=e;s.exports=e.x("next/dist/server/app-render/after-task-async-storage.external.js",()=>require("next/dist/server/app-render/after-task-async-storage.external.js"))},29549:function(e){var{g:r,__dirname:t,m:s,e:n}=e;s.exports=e.x("next/dist/compiled/next-server/app-page-turbo.runtime.prod.js",()=>require("next/dist/compiled/next-server/app-page-turbo.runtime.prod.js"))},83943:function(e){var{g:r,__dirname:t,m:s,e:n}=e;s.exports=e.x("next/dist/server/app-render/work-unit-async-storage.external.js",()=>require("next/dist/server/app-render/work-unit-async-storage.external.js"))},86103:function(e){var{g:r,__dirname:t,m:s,e:n}=e;s.exports=e.x("next/dist/server/app-render/work-async-storage.external.js",()=>require("next/dist/server/app-render/work-async-storage.external.js"))},30331:function(e){var{g:r,__dirname:t,m:s,e:n}=e;s.exports=e.x("path",()=>require("path"))},23430:function(e){var{g:r,__dirname:t,m:s,e:n}=e;s.exports=e.x("next/dist/compiled/@opentelemetry/api",()=>require("next/dist/compiled/@opentelemetry/api"))},13442:function(e){var{g:r,__dirname:t,m:s,e:n}=e;s.exports=e.x("os",()=>require("os"))},52670:function(e){var{g:r,__dirname:t,m:s,e:n}=e;s.exports=e.x("next/dist/compiled/next-server/app-route-turbo.runtime.prod.js",()=>require("next/dist/compiled/next-server/app-route-turbo.runtime.prod.js"))},9892:function(e){var{g:r,__dirname:t,m:s,e:n}=e;s.exports=e.x("fs/promises",()=>require("fs/promises"))},24713:function(e){var{g:r,__dirname:t,m:s,e:n}=e},57948:e=>{"use strict";var{g:r,__dirname:t}=e;e.s({DELETE:()=>p,GET:()=>u});var s=e.i(15494),n=e.i(30331),o=e.i(9892),a=e.i(13442);function i(e,r){let t=`${e}-${r}`;return n.default.join(a.default.homedir(),".prime-process-logs",`${t}.log`)}async function u(e){try{let{searchParams:r}=new URL(e.url),t=r.get("projectName"),n=r.get("envName"),a=r.get("tail")||"100";if(!t||!n)return s.NextResponse.json({success:!1,error:"缺少必要参数"},{status:400});let u=i(t,n);try{let e=(await o.default.readFile(u,"utf-8")).split("\n").filter(e=>e.trim()),r=parseInt(a),t=e.slice(-r);return s.NextResponse.json({success:!0,data:{logs:t,totalLines:e.length,tailCount:t.length}})}catch{return s.NextResponse.json({success:!0,data:{logs:[],totalLines:0,tailCount:0}})}}catch(e){return console.error("获取进程日志失败:",e),s.NextResponse.json({success:!1,error:e instanceof Error?e.message:"获取进程日志失败"},{status:500})}}async function p(e){try{let{searchParams:r}=new URL(e.url),t=r.get("projectName"),n=r.get("envName");if(!t||!n)return s.NextResponse.json({success:!1,error:"缺少必要参数"},{status:400});let a=i(t,n);try{return await o.default.unlink(a),s.NextResponse.json({success:!0,message:"日志已清除"})}catch{return s.NextResponse.json({success:!0,message:"日志文件不存在"})}}catch(e){return console.error("清除进程日志失败:",e),s.NextResponse.json({success:!1,error:e instanceof Error?e.message:"清除进程日志失败"},{status:500})}}},47527:e=>{"use strict";var{g:r,__dirname:t}=e;{e.s({patchFetch:()=>i,routeModule:()=>r,serverHooks:()=>p,workAsyncStorage:()=>t,workUnitAsyncStorage:()=>u});var s=e.i(45746),n=e.i(93828),o=e.i(18250),a=e.i(57948);let r=new s.AppRouteRouteModule({definition:{kind:n.RouteKind.APP_ROUTE,page:"/api/process/logs/route",pathname:"/api/process/logs",filename:"route",bundlePath:""},resolvedPagePath:"[project]/packages/server/src/app/api/process/logs/route.ts",nextConfigOutput:"",userland:a}),{workAsyncStorage:t,workUnitAsyncStorage:u,serverHooks:p}=r;function i(){return(0,o.patchFetch)({workAsyncStorage:t,workUnitAsyncStorage:u})}}}};
|
|
2
|
+
|
|
3
|
+
//# sourceMappingURL=%5Broot-of-the-server%5D__616d1a09._.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["turbopack:///[project]/packages/server/src/app/api/process/logs/route.ts","turbopack:///[project]/node_modules/.pnpm/next@15.3.4_react-dom@19.1.0_react@19.1.0__react@19.1.0/node_modules/next/dist/src/build/templates/app-route.ts"],"sourcesContent":["import { NextRequest, NextResponse } from 'next/server';\nimport path from 'path';\nimport fs from 'fs/promises';\nimport os from 'os';\n\n// 获取进程日志文件路径\nfunction getProcessLogPath(projectName: string, envName: string) {\n const processKey = `${projectName}-${envName}`;\n return path.join(os.homedir(), '.prime-process-logs', `${processKey}.log`);\n}\n\nexport async function GET(request: NextRequest) {\n try {\n const { searchParams } = new URL(request.url);\n const projectName = searchParams.get('projectName');\n const envName = searchParams.get('envName');\n const tail = searchParams.get('tail') || '100'; // 默认返回最后100行\n\n if (!projectName || !envName) {\n return NextResponse.json({\n success: false,\n error: '缺少必要参数'\n }, { status: 400 });\n }\n\n const logPath = getProcessLogPath(projectName, envName);\n \n try {\n // 读取日志文件\n const logContent = await fs.readFile(logPath, 'utf-8');\n const lines = logContent.split('\\n').filter(line => line.trim());\n \n // 获取指定数量的最后几行\n const tailCount = parseInt(tail);\n const tailedLines = lines.slice(-tailCount);\n \n return NextResponse.json({\n success: true,\n data: {\n logs: tailedLines,\n totalLines: lines.length,\n tailCount: tailedLines.length\n }\n });\n } catch {\n // 日志文件不存在\n return NextResponse.json({\n success: true,\n data: {\n logs: [],\n totalLines: 0,\n tailCount: 0\n }\n });\n }\n } catch (error) {\n console.error('获取进程日志失败:', error);\n return NextResponse.json({\n success: false,\n error: error instanceof Error ? error.message : '获取进程日志失败'\n }, { status: 500 });\n }\n}\n\n// 清除日志\nexport async function DELETE(request: NextRequest) {\n try {\n const { searchParams } = new URL(request.url);\n const projectName = searchParams.get('projectName');\n const envName = searchParams.get('envName');\n\n if (!projectName || !envName) {\n return NextResponse.json({\n success: false,\n error: '缺少必要参数'\n }, { status: 400 });\n }\n\n const logPath = getProcessLogPath(projectName, envName);\n \n try {\n await fs.unlink(logPath);\n return NextResponse.json({\n success: true,\n message: '日志已清除'\n });\n } catch {\n // 文件不存在也算成功\n return NextResponse.json({\n success: true,\n message: '日志文件不存在'\n });\n }\n } catch (error) {\n console.error('清除进程日志失败:', error);\n return NextResponse.json({\n success: false,\n error: error instanceof Error ? error.message : '清除进程日志失败'\n }, { status: 500 });\n }\n}","import {\n AppRouteRouteModule,\n type AppRouteRouteModuleOptions,\n} from '../../server/route-modules/app-route/module.compiled'\nimport { RouteKind } from '../../server/route-kind'\nimport { patchFetch as _patchFetch } from '../../server/lib/patch-fetch'\n\nimport * as userland from 'VAR_USERLAND'\n\n// These are injected by the loader afterwards. This is injected as a variable\n// instead of a replacement because this could also be `undefined` instead of\n// an empty string.\ndeclare const nextConfigOutput: AppRouteRouteModuleOptions['nextConfigOutput']\n\n// We inject the nextConfigOutput here so that we can use them in the route\n// module.\n// INJECT:nextConfigOutput\n\nconst routeModule = new AppRouteRouteModule({\n definition: {\n kind: RouteKind.APP_ROUTE,\n page: 'VAR_DEFINITION_PAGE',\n pathname: 'VAR_DEFINITION_PATHNAME',\n filename: 'VAR_DEFINITION_FILENAME',\n bundlePath: 'VAR_DEFINITION_BUNDLE_PATH',\n },\n resolvedPagePath: 'VAR_RESOLVED_PAGE_PATH',\n nextConfigOutput,\n userland,\n})\n\n// Pull out the exports that we need to expose from the module. This should\n// be eliminated when we've moved the other routes to the new format. These\n// are used to hook into the route.\nconst { workAsyncStorage, workUnitAsyncStorage, serverHooks } = routeModule\n\nfunction patchFetch() {\n return _patchFetch({\n workAsyncStorage,\n workUnitAsyncStorage,\n })\n}\n\nexport {\n routeModule,\n workAsyncStorage,\n workUnitAsyncStorage,\n serverHooks,\n patchFetch,\n}\n"],"names":["AppRouteRouteModule","RouteKind","patchFetch","_patchFetch","userland","routeModule","definition","kind","APP_ROUTE","page","pathname","filename","bundlePath","resolvedPagePath","nextConfigOutput","workAsyncStorage","workUnitAsyncStorage","serverHooks"],"mappings":"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","ignoreList":[1]}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
module.exports={35692:e=>{"use strict";var{g:t,__dirname:s}=e;e.s({ProjectStatus:()=>a,getProjectsConfig:()=>i,saveProjectsConfig:()=>o});var r=e.i(9892),n=e.i(88941);async function i(){try{await (0,r.access)(n.PROJECT_CONFIG_PATH,r.constants.F_OK)}catch{return await o({}),{}}try{let e=await (0,r.readFile)(n.PROJECT_CONFIG_PATH,"utf-8");if(!e)return{};return JSON.parse(e)}catch(e){throw console.error("读取或解析项目配置文件失败:",e),Error("无法加载项目配置")}}async function o(e){let t=n.PROJECT_CONFIG_PATH+".tmp";try{await (0,r.writeFile)(t,JSON.stringify(e,null,2),"utf-8"),await (0,r.rename)(t,n.PROJECT_CONFIG_PATH)}catch(e){throw console.error("保存项目配置文件失败:",e),Error("无法保存项目配置")}}var a=function(e){return e.PENDING="pending",e.EXISTING="existing",e.CLONING="cloning",e.SUCCESS="success",e.FAILED="failed",e.RETRYING="retrying",e}({})},88941:e=>{"use strict";var{g:t,__dirname:s}=e;{e.s({PROJECT_CONFIG_PATH:()=>s,ProjectStatus:()=>i,WORKSPACE_CONFIG:()=>t});var r=e.i(13442),n=e.i(30331);let t={WORKSPACE_ROOT:(0,n.join)((0,r.homedir)(),"Documents","prime-workspace"),GIT_TIMEOUT:3e5,MAX_CONCURRENT_CLONES:Math.max(2,Math.min((0,r.cpus)().length,8)),MAX_RETRY_ATTEMPTS:3},s=(0,n.join)((0,r.homedir)(),".prime-projects.json");var i=function(e){return e.PENDING="pending",e.EXISTING="existing",e.CLONING="cloning",e.SUCCESS="success",e.FAILED="failed",e.RETRYING="retrying",e.INCOMPLETE="incomplete",e}({})}},29549:function(e){var{g:t,__dirname:s,m:r,e:n}=e;r.exports=e.x("next/dist/compiled/next-server/app-page-turbo.runtime.prod.js",()=>require("next/dist/compiled/next-server/app-page-turbo.runtime.prod.js"))},83943:function(e){var{g:t,__dirname:s,m:r,e:n}=e;r.exports=e.x("next/dist/server/app-render/work-unit-async-storage.external.js",()=>require("next/dist/server/app-render/work-unit-async-storage.external.js"))},86103:function(e){var{g:t,__dirname:s,m:r,e:n}=e;r.exports=e.x("next/dist/server/app-render/work-async-storage.external.js",()=>require("next/dist/server/app-render/work-async-storage.external.js"))},30331:function(e){var{g:t,__dirname:s,m:r,e:n}=e;r.exports=e.x("path",()=>require("path"))},23430:function(e){var{g:t,__dirname:s,m:r,e:n}=e;r.exports=e.x("next/dist/compiled/@opentelemetry/api",()=>require("next/dist/compiled/@opentelemetry/api"))},13442:function(e){var{g:t,__dirname:s,m:r,e:n}=e;r.exports=e.x("os",()=>require("os"))},52670:function(e){var{g:t,__dirname:s,m:r,e:n}=e;r.exports=e.x("next/dist/compiled/next-server/app-route-turbo.runtime.prod.js",()=>require("next/dist/compiled/next-server/app-route-turbo.runtime.prod.js"))},9892:function(e){var{g:t,__dirname:s,m:r,e:n}=e;r.exports=e.x("fs/promises",()=>require("fs/promises"))},83886:function(e){var{g:t,__dirname:s,m:r,e:n}=e;r.exports=e.x("fs",()=>require("fs"))},87485:function(e){var{g:t,__dirname:s,m:r,e:n}=e;r.exports=e.x("child_process",()=>require("child_process"))},77159:e=>{"use strict";var{g:t,__dirname:s}=e;e.s({checkMultipleProjectsExist:()=>f,checkProjectExists:()=>d,checkProjectStatus:()=>p,cleanupIncompleteProject:()=>m,cloneRepository:()=>c,createWorkspaceDirectory:()=>a,isValidGitUrl:()=>u,openProjectInCursor:()=>x,sanitizeProjectName:()=>l});var r=e.i(87485),n=e.i(83886),i=e.i(30331),o=e.i(88941);async function a(e){try{return(0,n.existsSync)(e)||(0,n.mkdirSync)(e,{recursive:!0}),{success:!0}}catch(e){return{success:!1,error:`创建工作空间目录失败: ${e instanceof Error?e.message:String(e)}`}}}async function c(e){let{repoUrl:t,targetDir:s,timeout:n,onProgress:a,onError:c,onLog:u}=e,l=(0,i.basename)(t,".git");return new Promise(e=>{let p=Date.now(),d={projectName:l,status:o.ProjectStatus.CLONING,progress:0,message:"开始克隆项目...",startTime:p};a?.(0,"开始克隆项目...");let g=(0,i.join)(s,l),m=["clone","--progress","--verbose",t,g];u?.(l,"stdout",`[开始克隆] 执行命令: git ${m.join(" ")}
|
|
2
|
+
`),u?.(l,"stdout",`[目标目录] ${g}
|
|
3
|
+
`),u?.(l,"stdout",`[仓库地址] ${t}
|
|
4
|
+
`);let f=(0,r.spawn)("git",m,{cwd:s,stdio:["pipe","pipe","pipe"]}),x="",E=0;u?.(l,"stdout",`[进程启动] Git 进程 PID: ${f.pid}
|
|
5
|
+
`);let P=setTimeout(()=>{u?.(l,"stderr",`[超时警告] Git 进程运行超过 ${n/1e3}s,即将终止
|
|
6
|
+
`),f.kill("SIGTERM");let t={...d,status:o.ProjectStatus.FAILED,progress:E,message:"克隆操作超时",error:`克隆操作超时 (${n/1e3}s)`,endTime:Date.now()};u?.(l,"stderr",`[进程终止] 克隆操作超时
|
|
7
|
+
`),c?.(`${l}: 克隆操作超时`),e(t)},n);f.stdout?.on("data",e=>{let t=e.toString();u?.(l,"stdout",t),E=Math.min(E+10,80),a?.(E,"正在克隆代码...")}),f.stderr?.on("data",e=>{let t=e.toString();x+=t,t.includes("remote:")||t.includes("Receiving objects")||t.includes("Resolving deltas")||t.includes("Counting objects")||t.includes("Enumerating objects")||t.includes("Compressing objects")||t.includes("upload-pack")||t.includes("POST git-")||t.includes("正克隆到")||t.includes("Cloning into")?u?.(l,"progress",t):u?.(l,"stderr",t),t.includes("Receiving objects")||t.includes("Resolving deltas")?(E=Math.min(E+5,90),a?.(E,"正在接收对象...")):t.includes("Counting objects")?(E=Math.min(E+2,70),a?.(E,"正在计算对象...")):t.includes("Enumerating objects")&&(E=Math.min(E+2,50),a?.(E,"正在枚举对象..."))}),f.on("close",t=>{clearTimeout(P);let s=Date.now(),r=s-p;if(u?.(l,"stdout",`[进程结束] Git 进程退出,代码: ${t},耗时: ${Math.round(r/1e3)}s
|
|
8
|
+
`),0===t){u?.(l,"stdout",`[克隆成功] 项目已成功克隆到: ${g}
|
|
9
|
+
`);let t={...d,status:o.ProjectStatus.SUCCESS,progress:100,message:"克隆完成",endTime:s};a?.(100,"克隆完成"),e(t)}else{let r=function(e){let t=e.toLowerCase();return t.includes("authentication failed")||t.includes("access denied")?"身份验证失败,请检查仓库访问权限":t.includes("repository not found")||t.includes("not found")?"仓库不存在或无法访问":t.includes("network")||t.includes("connection")?"网络连接问题,请检查网络设置":t.includes("timeout")?"网络超时,请重试":t.includes("permission denied")?"权限被拒绝,请检查文件系统权限":t.includes("already exists")?"目标目录已存在":e.slice(0,200)+(e.length>200?"...":"")}(x);u?.(l,"stderr",`[克隆失败] 错误信息: ${r}
|
|
10
|
+
`),u?.(l,"stderr",`[完整错误输出]
|
|
11
|
+
${x}
|
|
12
|
+
`);let n={...d,status:o.ProjectStatus.FAILED,progress:E,message:"克隆失败",error:r||`Git 进程退出,代码: ${t}`,endTime:s};c?.(`${l}: ${n.error}`),e(n)}}),f.on("error",t=>{clearTimeout(P),u?.(l,"stderr",`[进程错误] Git 进程启动失败: ${t.message}
|
|
13
|
+
`),u?.(l,"stderr",`[错误详情] ${t.stack||"No stack trace"}
|
|
14
|
+
`);let s={...d,status:o.ProjectStatus.FAILED,progress:E,message:"进程启动失败",error:`进程启动失败: ${t.message}`,endTime:Date.now()};c?.(`${l}: ${t.message}`),e(s)})})}function u(e){return/^(https?:\/\/|git@)[^\s]+\.git$/i.test(e)}function l(e){return e.replace(/[^a-zA-Z0-9\-_]/g,"")}async function p(e,t){try{let s=(0,i.join)(e,t);if(!(0,n.existsSync)(s))return{exists:!1,status:"not_exists",needsCleanup:!1};let r=(0,i.join)(s,".git");if(!(0,n.existsSync)(r))return{exists:!0,status:"incomplete",needsCleanup:!0};if(!await g(s))return console.log(`检测到不完整的Git仓库: ${s}`),{exists:!0,status:"incomplete",needsCleanup:!0};return{exists:!0,status:"complete",needsCleanup:!1}}catch(e){return console.error(`检查项目 ${t} 状态时出错:`,e),{exists:!1,status:"not_exists",needsCleanup:!1}}}async function d(e,t){return"complete"===(await p(e,t)).status}async function g(e){try{let t=(0,i.join)(e,".git");for(let e of["HEAD","config","refs"]){let s=(0,i.join)(t,e);if(!(0,n.existsSync)(s))return!1}let s=(await n.promises.readdir(e)).filter(e=>".git"!==e);if(0===s.length)return!1;let r=(0,i.join)(t,"HEAD"),o=await n.promises.readFile(r,"utf-8");if(!o.trim()||o.includes("unborn"))return!1;return!0}catch(e){return console.error("检查Git仓库完整性时出错:",e),!1}}async function m(e){try{console.log(`正在清理不完整的项目: ${e}`),await n.promises.rm(e,{recursive:!0,force:!0}),console.log(`清理完成: ${e}`)}catch(t){console.error(`清理项目失败 ${e}:`,t)}}async function f(e,t){let s={},r=t.map(async t=>{let r=await d(e,t);s[t]=r});return await Promise.all(r),s}async function x(e){return new Promise(t=>{if(!(0,n.existsSync)(e))return void t({success:!1,error:`项目路径不存在: ${e}`});let s=(0,r.spawn)("cursor",[e],{stdio:["ignore","pipe","pipe"],detached:!0,env:{...process.env,NODE_ENV:"development"}}),i="",o=setTimeout(()=>{s.kill("SIGTERM"),t({success:!1,error:"Cursor 命令执行超时"})},1e4);s.stderr?.on("data",e=>{i+=e.toString()}),s.on("exit",e=>{clearTimeout(o),0===e?t({success:!0}):t({success:!1,error:`Cursor 退出代码: ${e}${i?`, 错误: ${i}`:""}`})}),s.on("error",e=>{clearTimeout(o),e.message.includes("ENOENT")?t({success:!1,error:"Cursor 命令未找到,请确保 Cursor CLI 已正确安装并在 PATH 中"}):t({success:!1,error:`启动 Cursor 失败: ${e.message}`})}),s.unref()})}},30533:function(e){var{g:t,__dirname:s,m:r,e:n}=e},54635:e=>{"use strict";var{g:t,__dirname:s}=e;e.s({GET:()=>a});var r=e.i(9892),n=e.i(88941),i=e.i(35692),o=e.i(77159);async function a(){try{let e=await (0,i.getProjectsConfig)(),t=Object.keys(e);if(0===t.length)return new Response(JSON.stringify({success:!0,workspaceExists:!1,projects:[],message:"没有找到配置的项目"}),{status:200,headers:{"Content-Type":"application/json"}});let s=n.WORKSPACE_CONFIG.WORKSPACE_ROOT,a=!1;try{await r.default.access(s),a=!0}catch{a=!1}let c=[],u=(c=a?await Promise.all(t.map(async e=>{let t,r,i=await (0,o.checkProjectStatus)(s,e);switch(i.status){case"complete":t=n.ProjectStatus.EXISTING,r="项目已存在";break;case"incomplete":t=n.ProjectStatus.INCOMPLETE,r="项目不完整,需要清理";break;default:t=n.ProjectStatus.PENDING,r="待克隆"}return{name:e,status:t,message:r,needsCleanup:i.needsCleanup}})):t.map(e=>({name:e,status:n.ProjectStatus.PENDING,message:"待克隆"}))).filter(e=>e.status===n.ProjectStatus.EXISTING).length,l=c.filter(e=>e.status===n.ProjectStatus.PENDING).length,p=c.filter(e=>e.status===n.ProjectStatus.INCOMPLETE).length;return new Response(JSON.stringify({success:!0,workspaceExists:a,workspacePath:s,projects:c,summary:{total:t.length,existing:u,pending:l,incomplete:p},message:a?`工作空间已存在,发现 ${u} 个已存在项目,${l} 个待克隆项目${p>0?`,${p} 个不完整项目需要清理`:""}`:`工作空间不存在,${t.length} 个项目待克隆`}),{status:200,headers:{"Content-Type":"application/json"}})}catch(t){let e=t instanceof Error?t.message:String(t);return console.error("检查工作空间状态失败:",t),new Response(JSON.stringify({success:!1,error:`检查工作空间状态失败: ${e}`,workspaceExists:!1,projects:[]}),{status:500,headers:{"Content-Type":"application/json"}})}}},81743:e=>{"use strict";var{g:t,__dirname:s}=e;{e.s({patchFetch:()=>a,routeModule:()=>t,serverHooks:()=>u,workAsyncStorage:()=>s,workUnitAsyncStorage:()=>c});var r=e.i(45746),n=e.i(93828),i=e.i(18250),o=e.i(54635);let t=new r.AppRouteRouteModule({definition:{kind:n.RouteKind.APP_ROUTE,page:"/api/check-workspace/route",pathname:"/api/check-workspace",filename:"route",bundlePath:""},resolvedPagePath:"[project]/packages/server/src/app/api/check-workspace/route.ts",nextConfigOutput:"",userland:o}),{workAsyncStorage:s,workUnitAsyncStorage:c,serverHooks:u}=t;function a(){return(0,i.patchFetch)({workAsyncStorage:s,workUnitAsyncStorage:c})}}}};
|
|
15
|
+
|
|
16
|
+
//# sourceMappingURL=%5Broot-of-the-server%5D__63462bcb._.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["turbopack:///[project]/packages/server/src/lib/workspace-config.ts","turbopack:///[project]/packages/server/src/lib/workspace-types.ts","turbopack:///[project]/packages/server/src/lib/git-operations.ts","turbopack:///[project]/packages/server/src/app/api/check-workspace/route.ts","turbopack:///[project]/node_modules/.pnpm/next@15.3.4_react-dom@19.1.0_react@19.1.0__react@19.1.0/node_modules/next/dist/src/build/templates/app-route.ts"],"sourcesContent":["import { readFile, writeFile, access, constants, rename } from 'fs/promises';\nimport type { ProjectsConfig } from './workspace-types';\nimport { PROJECT_CONFIG_PATH } from './workspace-types';\n\n/**\n * 读取并解析项目配置文件\n * @returns {Promise<ProjectsConfig>} 项目配置对象\n */\nexport async function getProjectsConfig(): Promise<ProjectsConfig> {\n try {\n await access(PROJECT_CONFIG_PATH, constants.F_OK);\n } catch {\n // 文件不存在,创建并写入空对象\n await saveProjectsConfig({});\n return {};\n }\n\n try {\n const configContent = await readFile(PROJECT_CONFIG_PATH, 'utf-8');\n // 如果文件为空,返回空对象\n if (!configContent) {\n return {};\n }\n return JSON.parse(configContent);\n } catch (error) {\n console.error('读取或解析项目配置文件失败:', error);\n // 在出错时返回空对象或抛出错误,这里选择抛出以通知调用者\n throw new Error('无法加载项目配置');\n }\n}\n\n/**\n * 将项目配置写入文件(原子操作)\n * @param {ProjectsConfig} config - 要保存的配置对象\n */\nexport async function saveProjectsConfig(config: ProjectsConfig): Promise<void> {\n const tempConfigPath = PROJECT_CONFIG_PATH + '.tmp';\n try {\n await writeFile(tempConfigPath, JSON.stringify(config, null, 2), 'utf-8');\n await rename(tempConfigPath, PROJECT_CONFIG_PATH);\n } catch (error) {\n console.error('保存项目配置文件失败:', error);\n throw new Error('无法保存项目配置');\n }\n}\n\n/**\n * 项目状态枚举\n */\nexport enum ProjectStatus {\n PENDING = 'pending',\n EXISTING = 'existing',\n CLONING = 'cloning',\n SUCCESS = 'success',\n FAILED = 'failed',\n RETRYING = 'retrying',\n}\n\n/**\n * 项目进度信息接口\n */\nexport interface ProjectProgress {\n projectName: string;\n status: ProjectStatus;\n progress: number; // 0-100\n message: string;\n error?: string;\n startTime?: number;\n endTime?: number;\n}\n\n/**\n * 初始化结果接口\n */\nexport interface InitializationResult {\n success: boolean;\n totalProjects: number;\n successCount: number;\n failedCount: number;\n failedProjects: string[];\n workspacePath: string;\n duration: number;\n}\n\n/**\n * Git 操作配置接口\n */\nexport interface GitOperationConfig {\n repoUrl: string;\n targetDir: string;\n timeout: number;\n onProgress?: (progress: number, message: string) => void;\n onError?: (error: string) => void;\n}","import { homedir, cpus } from 'os';\nimport { join } from 'path';\n\n/**\n * 工作空间配置常量\n */\nexport const WORKSPACE_CONFIG = {\n // 工作空间根目录路径\n WORKSPACE_ROOT: join(homedir(), 'Documents', 'prime-workspace'),\n\n // Git 操作超时时间 (毫秒)\n GIT_TIMEOUT: 300000, // 5分钟\n\n // 最大并发克隆数量(基于CPU核心数,最小2个,最大8个)\n MAX_CONCURRENT_CLONES: Math.max(2, Math.min(cpus().length, 8)),\n\n // 重试次数限制\n MAX_RETRY_ATTEMPTS: 3,\n} as const;\n\nexport const PROJECT_CONFIG_PATH = join(homedir(), '.prime-projects.json');\n\nexport interface ProjectConfig {\n repo: string;\n mockingIntercept?: boolean;\n mockOpen?: boolean;\n envs: {\n [envName: string]: {\n host: string;\n currentProxy: string;\n proxyEnv: {\n [key: string]: string;\n };\n envFileName: string;\n proxyKey: string;\n subApps?: string[];\n };\n };\n}\n\nexport interface ProjectsConfig {\n [projectName: string]: ProjectConfig;\n}\n\n/**\n * 项目状态枚举\n */\nexport enum ProjectStatus {\n PENDING = 'pending',\n EXISTING = 'existing',\n CLONING = 'cloning',\n SUCCESS = 'success',\n FAILED = 'failed',\n RETRYING = 'retrying',\n INCOMPLETE = 'incomplete', // 不完整的项目,需要清理\n}\n\n/**\n * 项目进度信息接口\n */\nexport interface ProjectProgress {\n projectName: string;\n status: ProjectStatus;\n progress: number; // 0-100\n message: string;\n error?: string;\n startTime?: number;\n endTime?: number;\n}\n\n/**\n * 初始化结果接口\n */\nexport interface InitializationResult {\n success: boolean;\n totalProjects: number;\n successCount: number;\n failedCount: number;\n failedProjects: string[];\n workspacePath: string;\n duration: number;\n}\n\n/**\n * Git 操作配置接口\n */\nexport interface GitOperationConfig {\n repoUrl: string;\n targetDir: string;\n timeout: number;\n onProgress?: (progress: number, message: string) => void;\n onError?: (error: string) => void;\n onLog?: (projectName: string, logType: 'stdout' | 'stderr' | 'progress', content: string) => void;\n} ","import { spawn, ChildProcess } from 'child_process';\nimport { existsSync, mkdirSync } from 'fs';\nimport { promises as fs } from 'fs';\nimport { join, basename } from 'path';\nimport {\n ProjectStatus,\n type GitOperationConfig,\n type ProjectProgress,\n} from './workspace-types';\n\n/**\n * 创建工作空间目录\n * @param workspacePath 工作空间路径\n * @returns 创建结果\n */\nexport async function createWorkspaceDirectory(workspacePath: string): Promise<{ success: boolean; error?: string }> {\n try {\n if (!existsSync(workspacePath)) {\n mkdirSync(workspacePath, { recursive: true });\n }\n return { success: true };\n } catch (error) {\n return { \n success: false, \n error: `创建工作空间目录失败: ${error instanceof Error ? error.message : String(error)}` \n };\n }\n}\n\n/**\n * 执行 Git 克隆操作\n * @param config Git 操作配置\n * @returns Promise<ProjectProgress>\n */\nexport async function cloneRepository(config: GitOperationConfig): Promise<ProjectProgress> {\n const { repoUrl, targetDir, timeout, onProgress, onError, onLog } = config;\n const projectName = basename(repoUrl, '.git');\n \n return new Promise<ProjectProgress>((resolve) => {\n const startTime = Date.now();\n \n // 更新开始状态\n const initialProgress: ProjectProgress = {\n projectName,\n status: ProjectStatus.CLONING,\n progress: 0,\n message: '开始克隆项目...',\n startTime,\n };\n onProgress?.(0, '开始克隆项目...');\n\n // 执行 git clone 命令\n const targetPath = join(targetDir, projectName);\n // 添加 --progress 参数来强制显示进度,--verbose 显示详细信息\n const gitArgs = ['clone', '--progress', '--verbose', repoUrl, targetPath];\n \n // 记录命令启动信息\n onLog?.(projectName, 'stdout', `[开始克隆] 执行命令: git ${gitArgs.join(' ')}\\n`);\n onLog?.(projectName, 'stdout', `[目标目录] ${targetPath}\\n`);\n onLog?.(projectName, 'stdout', `[仓库地址] ${repoUrl}\\n`);\n \n const gitProcess: ChildProcess = spawn('git', gitArgs, {\n cwd: targetDir,\n stdio: ['pipe', 'pipe', 'pipe'],\n });\n\n let errorOutput = '';\n let progressValue = 0;\n \n // 记录进程启动成功\n onLog?.(projectName, 'stdout', `[进程启动] Git 进程 PID: ${gitProcess.pid}\\n`);\n\n // 设置超时\n const timeoutId = setTimeout(() => {\n onLog?.(projectName, 'stderr', `[超时警告] Git 进程运行超过 ${timeout / 1000}s,即将终止\\n`);\n gitProcess.kill('SIGTERM');\n \n const errorResult: ProjectProgress = {\n ...initialProgress,\n status: ProjectStatus.FAILED,\n progress: progressValue,\n message: '克隆操作超时',\n error: `克隆操作超时 (${timeout / 1000}s)`,\n endTime: Date.now(),\n };\n onLog?.(projectName, 'stderr', `[进程终止] 克隆操作超时\\n`);\n onError?.(`${projectName}: 克隆操作超时`);\n resolve(errorResult);\n }, timeout);\n\n // 处理标准输出\n gitProcess.stdout?.on('data', (data: Buffer) => {\n const stdoutText = data.toString();\n \n // 实时发送日志\n onLog?.(projectName, 'stdout', stdoutText);\n \n // 模拟进度更新(Git 克隆没有内置进度,这里基于时间估算)\n progressValue = Math.min(progressValue + 10, 80);\n onProgress?.(progressValue, '正在克隆代码...');\n });\n\n // 处理错误输出\n gitProcess.stderr?.on('data', (data: Buffer) => {\n const stderrText = data.toString();\n errorOutput += stderrText;\n \n // 判断是进度信息还是错误信息\n const isProgressInfo = stderrText.includes('remote:') || \n stderrText.includes('Receiving objects') || \n stderrText.includes('Resolving deltas') ||\n stderrText.includes('Counting objects') ||\n stderrText.includes('Enumerating objects') ||\n stderrText.includes('Compressing objects') ||\n stderrText.includes('upload-pack') ||\n stderrText.includes('POST git-') ||\n stderrText.includes('正克隆到') ||\n stderrText.includes('Cloning into');\n \n // 根据内容类型发送不同的日志\n if (isProgressInfo) {\n onLog?.(projectName, 'progress', stderrText);\n } else {\n onLog?.(projectName, 'stderr', stderrText);\n }\n \n // Git 的进度信息通常在 stderr 中\n if (stderrText.includes('Receiving objects') || stderrText.includes('Resolving deltas')) {\n progressValue = Math.min(progressValue + 5, 90);\n onProgress?.(progressValue, '正在接收对象...');\n } else if (stderrText.includes('Counting objects')) {\n progressValue = Math.min(progressValue + 2, 70);\n onProgress?.(progressValue, '正在计算对象...');\n } else if (stderrText.includes('Enumerating objects')) {\n progressValue = Math.min(progressValue + 2, 50);\n onProgress?.(progressValue, '正在枚举对象...');\n }\n });\n\n // 处理进程结束\n gitProcess.on('close', (code: number | null) => {\n clearTimeout(timeoutId);\n const endTime = Date.now();\n const duration = endTime - startTime;\n \n onLog?.(projectName, 'stdout', `[进程结束] Git 进程退出,代码: ${code},耗时: ${Math.round(duration / 1000)}s\\n`);\n \n if (code === 0) {\n // 克隆成功\n onLog?.(projectName, 'stdout', `[克隆成功] 项目已成功克隆到: ${targetPath}\\n`);\n const successResult: ProjectProgress = {\n ...initialProgress,\n status: ProjectStatus.SUCCESS,\n progress: 100,\n message: '克隆完成',\n endTime,\n };\n onProgress?.(100, '克隆完成');\n resolve(successResult);\n } else {\n // 克隆失败\n const parsedError = parseGitError(errorOutput);\n onLog?.(projectName, 'stderr', `[克隆失败] 错误信息: ${parsedError}\\n`);\n onLog?.(projectName, 'stderr', `[完整错误输出]\\n${errorOutput}\\n`);\n \n const failureResult: ProjectProgress = {\n ...initialProgress,\n status: ProjectStatus.FAILED,\n progress: progressValue,\n message: '克隆失败',\n error: parsedError || `Git 进程退出,代码: ${code}`,\n endTime,\n };\n onError?.(`${projectName}: ${failureResult.error}`);\n resolve(failureResult);\n }\n });\n\n // 处理进程错误\n gitProcess.on('error', (error: Error) => {\n clearTimeout(timeoutId);\n onLog?.(projectName, 'stderr', `[进程错误] Git 进程启动失败: ${error.message}\\n`);\n onLog?.(projectName, 'stderr', `[错误详情] ${error.stack || 'No stack trace'}\\n`);\n \n const errorResult: ProjectProgress = {\n ...initialProgress,\n status: ProjectStatus.FAILED,\n progress: progressValue,\n message: '进程启动失败',\n error: `进程启动失败: ${error.message}`,\n endTime: Date.now(),\n };\n onError?.(`${projectName}: ${error.message}`);\n resolve(errorResult);\n });\n });\n}\n\n/**\n * 解析 Git 错误信息,提供用户友好的错误描述\n * @param errorOutput Git stderr 输出\n * @returns 用户友好的错误描述\n */\nfunction parseGitError(errorOutput: string): string {\n const lowerOutput = errorOutput.toLowerCase();\n \n if (lowerOutput.includes('authentication failed') || lowerOutput.includes('access denied')) {\n return '身份验证失败,请检查仓库访问权限';\n }\n \n if (lowerOutput.includes('repository not found') || lowerOutput.includes('not found')) {\n return '仓库不存在或无法访问';\n }\n \n if (lowerOutput.includes('network') || lowerOutput.includes('connection')) {\n return '网络连接问题,请检查网络设置';\n }\n \n if (lowerOutput.includes('timeout')) {\n return '网络超时,请重试';\n }\n \n if (lowerOutput.includes('permission denied')) {\n return '权限被拒绝,请检查文件系统权限';\n }\n \n if (lowerOutput.includes('already exists')) {\n return '目标目录已存在';\n }\n \n // 返回原始错误的前200个字符\n return errorOutput.slice(0, 200) + (errorOutput.length > 200 ? '...' : '');\n}\n\n/**\n * 验证 Git 仓库 URL 格式\n * @param url Git 仓库 URL\n * @returns 是否有效\n */\nexport function isValidGitUrl(url: string): boolean {\n const gitUrlPattern = /^(https?:\\/\\/|git@)[^\\s]+\\.git$/i;\n return gitUrlPattern.test(url);\n}\n\n/**\n * 清理项目名称,移除不安全字符\n * @param projectName 项目名称\n * @returns 清理后的项目名称\n */\nexport function sanitizeProjectName(projectName: string): string {\n return projectName.replace(/[^a-zA-Z0-9\\-_]/g, '');\n}\n\n/**\n * 项目检查结果类型\n */\nexport type ProjectCheckResult = {\n exists: boolean;\n status: 'not_exists' | 'complete' | 'incomplete';\n needsCleanup: boolean;\n};\n\n/**\n * 检查项目状态(详细版本)\n * @param workspacePath 工作空间路径\n * @param projectName 项目名称\n * @returns Promise<ProjectCheckResult> 详细的项目状态\n */\nexport async function checkProjectStatus(workspacePath: string, projectName: string): Promise<ProjectCheckResult> {\n try {\n const projectPath = join(workspacePath, projectName);\n \n // 检查项目目录是否存在\n if (!existsSync(projectPath)) {\n return {\n exists: false,\n status: 'not_exists',\n needsCleanup: false\n };\n }\n \n // 检查是否为 Git 仓库(存在 .git 目录)\n const gitPath = join(projectPath, '.git');\n if (!existsSync(gitPath)) {\n return {\n exists: true,\n status: 'incomplete',\n needsCleanup: true\n };\n }\n \n // 更严格的完整性检查\n const isComplete = await isGitRepositoryComplete(projectPath);\n if (!isComplete) {\n console.log(`检测到不完整的Git仓库: ${projectPath}`);\n return {\n exists: true,\n status: 'incomplete',\n needsCleanup: true\n };\n }\n \n return {\n exists: true,\n status: 'complete',\n needsCleanup: false\n };\n } catch (error) {\n console.error(`检查项目 ${projectName} 状态时出错:`, error);\n return {\n exists: false,\n status: 'not_exists',\n needsCleanup: false\n };\n }\n}\n\n/**\n * 检查项目是否已存在于工作空间中(兼容版本)\n * @param workspacePath 工作空间路径\n * @param projectName 项目名称\n * @returns Promise<boolean> 项目是否存在且为有效的 Git 仓库\n */\nexport async function checkProjectExists(workspacePath: string, projectName: string): Promise<boolean> {\n const result = await checkProjectStatus(workspacePath, projectName);\n return result.status === 'complete';\n}\n\n/**\n * 检查Git仓库是否完整\n * @param projectPath 项目路径\n * @returns Promise<boolean> 仓库是否完整\n */\nasync function isGitRepositoryComplete(projectPath: string): Promise<boolean> {\n try {\n const gitPath = join(projectPath, '.git');\n \n // 检查关键的Git文件是否存在\n const requiredFiles = ['HEAD', 'config', 'refs'];\n for (const file of requiredFiles) {\n const filePath = join(gitPath, file);\n if (!existsSync(filePath)) {\n return false;\n }\n }\n \n // 检查是否有实际的项目文件(不只是.git目录)\n const entries = await fs.readdir(projectPath);\n const nonGitFiles = entries.filter((entry: string) => entry !== '.git');\n \n // 如果只有.git目录,说明克隆未完成\n if (nonGitFiles.length === 0) {\n return false;\n }\n \n // 检查HEAD文件是否有效\n const headPath = join(gitPath, 'HEAD');\n const headContent = await fs.readFile(headPath, 'utf-8');\n if (!headContent.trim() || headContent.includes('unborn')) {\n return false;\n }\n \n return true;\n } catch (error) {\n console.error('检查Git仓库完整性时出错:', error);\n return false;\n }\n}\n\n/**\n * 清理不完整的项目目录\n * @param projectPath 项目路径\n */\nexport async function cleanupIncompleteProject(projectPath: string): Promise<void> {\n try {\n console.log(`正在清理不完整的项目: ${projectPath}`);\n await fs.rm(projectPath, { recursive: true, force: true });\n console.log(`清理完成: ${projectPath}`);\n } catch (error) {\n console.error(`清理项目失败 ${projectPath}:`, error);\n // 清理失败不抛出错误,避免阻塞后续流程\n }\n}\n\n/**\n * 批量检查多个项目的存在状态\n * @param workspacePath 工作空间路径\n * @param projectNames 项目名称列表\n * @returns Promise<Record<string, boolean>> 项目名称到存在状态的映射\n */\nexport async function checkMultipleProjectsExist(\n workspacePath: string, \n projectNames: string[]\n): Promise<Record<string, boolean>> {\n const results: Record<string, boolean> = {};\n \n // 并行检查所有项目\n const checks = projectNames.map(async (projectName) => {\n const exists = await checkProjectExists(workspacePath, projectName);\n results[projectName] = exists;\n });\n \n await Promise.all(checks);\n return results;\n}\n\n/**\n * 在 Cursor 中打开项目\n * @param projectPath 项目的绝对路径\n * @returns Promise<{ success: boolean; error?: string }>\n */\nexport async function openProjectInCursor(projectPath: string): Promise<{ success: boolean; error?: string }> {\n return new Promise((resolve) => {\n // 验证项目路径存在\n if (!existsSync(projectPath)) {\n resolve({\n success: false,\n error: `项目路径不存在: ${projectPath}`\n });\n return;\n }\n\n // 执行 cursor 命令\n const cursorProcess = spawn('cursor', [projectPath], {\n stdio: ['ignore', 'pipe', 'pipe'],\n detached: true, // 让进程在后台独立运行\n env: {\n ...process.env,\n NODE_ENV: 'development', // 强制设置为开发模式\n }\n });\n\n let errorOutput = '';\n\n // 设置超时(10秒)\n const timeoutId = setTimeout(() => {\n cursorProcess.kill('SIGTERM');\n resolve({\n success: false,\n error: 'Cursor 命令执行超时'\n });\n }, 10000);\n\n // 处理错误输出\n cursorProcess.stderr?.on('data', (data: Buffer) => {\n errorOutput += data.toString();\n });\n\n // 处理进程退出\n cursorProcess.on('exit', (code: number | null) => {\n clearTimeout(timeoutId);\n \n if (code === 0) {\n resolve({ success: true });\n } else {\n resolve({\n success: false,\n error: `Cursor 退出代码: ${code}${errorOutput ? `, 错误: ${errorOutput}` : ''}`\n });\n }\n });\n\n // 处理进程错误(如命令不存在)\n cursorProcess.on('error', (error: Error) => {\n clearTimeout(timeoutId);\n \n if (error.message.includes('ENOENT')) {\n resolve({\n success: false,\n error: 'Cursor 命令未找到,请确保 Cursor CLI 已正确安装并在 PATH 中'\n });\n } else {\n resolve({\n success: false,\n error: `启动 Cursor 失败: ${error.message}`\n });\n }\n });\n\n // 让进程独立运行,不等待其完成\n cursorProcess.unref();\n });\n} ","import fs from \"fs/promises\";\nimport {\n WORKSPACE_CONFIG,\n ProjectStatus,\n} from '@/lib/workspace-types';\nimport { getProjectsConfig } from '@/lib/workspace-config';\nimport { checkProjectStatus } from '@/lib/git-operations';\n\ninterface ProjectStatusInfo {\n name: string;\n status: ProjectStatus;\n message: string;\n needsCleanup?: boolean;\n}\n\n/**\n * 检查工作空间状态 API 端点\n * 返回所有配置项目的当前状态\n */\nexport async function GET() {\n try {\n // 读取项目配置\n const projectsConfig = await getProjectsConfig();\n const projectNames = Object.keys(projectsConfig);\n \n if (projectNames.length === 0) {\n return new Response(\n JSON.stringify({ \n success: true,\n workspaceExists: false,\n projects: [],\n message: '没有找到配置的项目'\n }),\n { \n status: 200,\n headers: { 'Content-Type': 'application/json' }\n }\n );\n }\n\n const workspacePath = WORKSPACE_CONFIG.WORKSPACE_ROOT;\n \n // 检查工作空间目录是否存在\n let workspaceExists = false;\n try {\n await fs.access(workspacePath);\n workspaceExists = true;\n } catch {\n // 工作空间目录不存在\n workspaceExists = false;\n }\n\n let projectStatuses: ProjectStatusInfo[] = [];\n\n if (workspaceExists) {\n // 检查各个项目的详细状态\n const statusChecks = await Promise.all(\n projectNames.map(async (projectName) => {\n const result = await checkProjectStatus(workspacePath, projectName);\n let status: ProjectStatus;\n let message: string;\n \n switch (result.status) {\n case 'complete':\n status = ProjectStatus.EXISTING;\n message = '项目已存在';\n break;\n case 'incomplete':\n status = ProjectStatus.INCOMPLETE;\n message = '项目不完整,需要清理';\n break;\n default:\n status = ProjectStatus.PENDING;\n message = '待克隆';\n break;\n }\n \n return {\n name: projectName,\n status,\n message,\n needsCleanup: result.needsCleanup\n };\n })\n );\n \n projectStatuses = statusChecks;\n } else {\n // 工作空间不存在,所有项目都是待克隆状态\n projectStatuses = projectNames.map(projectName => ({\n name: projectName,\n status: ProjectStatus.PENDING,\n message: '待克隆',\n }));\n }\n\n // 统计信息\n const existingCount = projectStatuses.filter(p => p.status === ProjectStatus.EXISTING).length;\n const pendingCount = projectStatuses.filter(p => p.status === ProjectStatus.PENDING).length;\n const incompleteCount = projectStatuses.filter(p => p.status === ProjectStatus.INCOMPLETE).length;\n\n return new Response(\n JSON.stringify({ \n success: true,\n workspaceExists,\n workspacePath,\n projects: projectStatuses,\n summary: {\n total: projectNames.length,\n existing: existingCount,\n pending: pendingCount,\n incomplete: incompleteCount,\n },\n message: workspaceExists \n ? `工作空间已存在,发现 ${existingCount} 个已存在项目,${pendingCount} 个待克隆项目${incompleteCount > 0 ? `,${incompleteCount} 个不完整项目需要清理` : ''}`\n : `工作空间不存在,${projectNames.length} 个项目待克隆`\n }),\n { \n status: 200,\n headers: { 'Content-Type': 'application/json' }\n }\n );\n\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n console.error(\"检查工作空间状态失败:\", error);\n \n return new Response(\n JSON.stringify({ \n success: false, \n error: `检查工作空间状态失败: ${errorMessage}`,\n workspaceExists: false,\n projects: []\n }),\n { \n status: 500,\n headers: { 'Content-Type': 'application/json' }\n }\n );\n }\n} ","import {\n AppRouteRouteModule,\n type AppRouteRouteModuleOptions,\n} from '../../server/route-modules/app-route/module.compiled'\nimport { RouteKind } from '../../server/route-kind'\nimport { patchFetch as _patchFetch } from '../../server/lib/patch-fetch'\n\nimport * as userland from 'VAR_USERLAND'\n\n// These are injected by the loader afterwards. This is injected as a variable\n// instead of a replacement because this could also be `undefined` instead of\n// an empty string.\ndeclare const nextConfigOutput: AppRouteRouteModuleOptions['nextConfigOutput']\n\n// We inject the nextConfigOutput here so that we can use them in the route\n// module.\n// INJECT:nextConfigOutput\n\nconst routeModule = new AppRouteRouteModule({\n definition: {\n kind: RouteKind.APP_ROUTE,\n page: 'VAR_DEFINITION_PAGE',\n pathname: 'VAR_DEFINITION_PATHNAME',\n filename: 'VAR_DEFINITION_FILENAME',\n bundlePath: 'VAR_DEFINITION_BUNDLE_PATH',\n },\n resolvedPagePath: 'VAR_RESOLVED_PAGE_PATH',\n nextConfigOutput,\n userland,\n})\n\n// Pull out the exports that we need to expose from the module. This should\n// be eliminated when we've moved the other routes to the new format. These\n// are used to hook into the route.\nconst { workAsyncStorage, workUnitAsyncStorage, serverHooks } = routeModule\n\nfunction patchFetch() {\n return _patchFetch({\n workAsyncStorage,\n workUnitAsyncStorage,\n })\n}\n\nexport {\n routeModule,\n workAsyncStorage,\n workUnitAsyncStorage,\n serverHooks,\n patchFetch,\n}\n"],"names":["AppRouteRouteModule","RouteKind","patchFetch","_patchFetch","userland","routeModule","definition","kind","APP_ROUTE","page","pathname","filename","bundlePath","resolvedPagePath","nextConfigOutput","workAsyncStorage","workUnitAsyncStorage","serverHooks"],"mappings":"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","ignoreList":[4]}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
module.exports={29549:function(e){var{g:t,__dirname:r,m:n,e:a}=e;n.exports=e.x("next/dist/compiled/next-server/app-page-turbo.runtime.prod.js",()=>require("next/dist/compiled/next-server/app-page-turbo.runtime.prod.js"))},83943:function(e){var{g:t,__dirname:r,m:n,e:a}=e;n.exports=e.x("next/dist/server/app-render/work-unit-async-storage.external.js",()=>require("next/dist/server/app-render/work-unit-async-storage.external.js"))},86103:function(e){var{g:t,__dirname:r,m:n,e:a}=e;n.exports=e.x("next/dist/server/app-render/work-async-storage.external.js",()=>require("next/dist/server/app-render/work-async-storage.external.js"))},30331:function(e){var{g:t,__dirname:r,m:n,e:a}=e;n.exports=e.x("path",()=>require("path"))},23430:function(e){var{g:t,__dirname:r,m:n,e:a}=e;n.exports=e.x("next/dist/compiled/@opentelemetry/api",()=>require("next/dist/compiled/@opentelemetry/api"))},13442:function(e){var{g:t,__dirname:r,m:n,e:a}=e;n.exports=e.x("os",()=>require("os"))},52670:function(e){var{g:t,__dirname:r,m:n,e:a}=e;n.exports=e.x("next/dist/compiled/next-server/app-route-turbo.runtime.prod.js",()=>require("next/dist/compiled/next-server/app-route-turbo.runtime.prod.js"))},9892:function(e){var{g:t,__dirname:r,m:n,e:a}=e;n.exports=e.x("fs/promises",()=>require("fs/promises"))},33939:function(e){var{g:t,__dirname:r,m:n,e:a}=e},82988:e=>{"use strict";var{g:t,__dirname:r}=e;e.s({GET:()=>o});var n=e.i(30331),a=e.i(9892),s=e.i(13442);async function o(e){let{searchParams:t}=new URL(e.url),r=t.get("projectName"),o=t.get("envName");if(!r||!o)return new Response("缺少必要参数",{status:400});let i=function(e,t){let r=`${e}-${t}`;return n.default.join(s.default.homedir(),".prime-process-logs",`${r}.log`)}(r,o);return new Response(new ReadableStream({async start(t){let r=new TextEncoder;t.enqueue(r.encode(": ping\n\n"));try{for(let e of(await a.default.readFile(i,"utf-8")).split("\n").filter(e=>e.trim()).slice(-100)){let n=`data: ${JSON.stringify({type:"log",content:e})}
|
|
2
|
+
|
|
3
|
+
`;t.enqueue(r.encode(n))}}catch{let e=`data: ${JSON.stringify({type:"init",message:"等待日志..."})}
|
|
4
|
+
|
|
5
|
+
`;t.enqueue(r.encode(e))}let n=0;try{n=(await a.default.stat(i)).size}catch{}let s=setInterval(async()=>{try{let e=await a.default.stat(i);if(e.size>n){let s=await a.default.open(i,"r"),o=Buffer.alloc(e.size-n);for(let e of(await s.read(o,0,o.length,n),await s.close(),o.toString("utf-8").split("\n").filter(e=>e.trim()))){let n=`data: ${JSON.stringify({type:"log",content:e})}
|
|
6
|
+
|
|
7
|
+
`;t.enqueue(r.encode(n))}n=e.size}}catch{if(n>0){let e=`data: ${JSON.stringify({type:"end",message:"进程已结束"})}
|
|
8
|
+
|
|
9
|
+
`;t.enqueue(r.encode(e)),n=0}}t.enqueue(r.encode(": ping\n\n"))},1e3);e.signal.addEventListener("abort",()=>{clearInterval(s),t.close()})}}),{headers:{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"}})}},13002:e=>{"use strict";var{g:t,__dirname:r}=e;{e.s({patchFetch:()=>i,routeModule:()=>t,serverHooks:()=>u,workAsyncStorage:()=>r,workUnitAsyncStorage:()=>p});var n=e.i(45746),a=e.i(93828),s=e.i(18250),o=e.i(82988);let t=new n.AppRouteRouteModule({definition:{kind:a.RouteKind.APP_ROUTE,page:"/api/process/logs/stream/route",pathname:"/api/process/logs/stream",filename:"route",bundlePath:""},resolvedPagePath:"[project]/packages/server/src/app/api/process/logs/stream/route.ts",nextConfigOutput:"",userland:o}),{workAsyncStorage:r,workUnitAsyncStorage:p,serverHooks:u}=t;function i(){return(0,s.patchFetch)({workAsyncStorage:r,workUnitAsyncStorage:p})}}}};
|
|
10
|
+
|
|
11
|
+
//# sourceMappingURL=%5Broot-of-the-server%5D__66ca8d3f._.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["turbopack:///[project]/packages/server/src/app/api/process/logs/stream/route.ts","turbopack:///[project]/node_modules/.pnpm/next@15.3.4_react-dom@19.1.0_react@19.1.0__react@19.1.0/node_modules/next/dist/src/build/templates/app-route.ts"],"sourcesContent":["import { NextRequest } from 'next/server';\nimport path from 'path';\nimport fs from 'fs/promises';\nimport os from 'os';\n\n// 获取进程日志文件路径\nfunction getProcessLogPath(projectName: string, envName: string) {\n const processKey = `${projectName}-${envName}`;\n return path.join(os.homedir(), '.prime-process-logs', `${processKey}.log`);\n}\n\n\nexport async function GET(request: NextRequest) {\n const { searchParams } = new URL(request.url);\n const projectName = searchParams.get('projectName');\n const envName = searchParams.get('envName');\n\n if (!projectName || !envName) {\n return new Response('缺少必要参数', { status: 400 });\n }\n\n const logPath = getProcessLogPath(projectName, envName);\n\n // 创建一个可读流来发送SSE\n const stream = new ReadableStream({\n async start(controller) {\n const encoder = new TextEncoder();\n \n // 发送初始连接消息\n controller.enqueue(encoder.encode(': ping\\n\\n'));\n \n // 读取现有日志\n try {\n const logContent = await fs.readFile(logPath, 'utf-8');\n const lines = logContent.split('\\n').filter(line => line.trim());\n const tailLines = lines.slice(-100); // 发送最后100行\n \n for (const line of tailLines) {\n const data = `data: ${JSON.stringify({ type: 'log', content: line })}\\n\\n`;\n controller.enqueue(encoder.encode(data));\n }\n } catch {\n // 文件不存在,发送空日志\n const data = `data: ${JSON.stringify({ type: 'init', message: '等待日志...' })}\\n\\n`;\n controller.enqueue(encoder.encode(data));\n }\n \n // 监听文件变化\n let lastSize = 0;\n try {\n const stats = await fs.stat(logPath);\n lastSize = stats.size;\n } catch {\n // 文件不存在\n }\n \n // 定期检查文件变化\n const interval = setInterval(async () => {\n try {\n const stats = await fs.stat(logPath);\n if (stats.size > lastSize) {\n // 文件有新内容\n const fileHandle = await fs.open(logPath, 'r');\n const buffer = Buffer.alloc(stats.size - lastSize);\n await fileHandle.read(buffer, 0, buffer.length, lastSize);\n await fileHandle.close();\n \n const newContent = buffer.toString('utf-8');\n const newLines = newContent.split('\\n').filter(line => line.trim());\n \n for (const line of newLines) {\n const data = `data: ${JSON.stringify({ type: 'log', content: line })}\\n\\n`;\n controller.enqueue(encoder.encode(data));\n }\n \n lastSize = stats.size;\n }\n } catch {\n // 文件可能被删除\n if (lastSize > 0) {\n const data = `data: ${JSON.stringify({ type: 'end', message: '进程已结束' })}\\n\\n`;\n controller.enqueue(encoder.encode(data));\n lastSize = 0;\n }\n }\n \n // 发送心跳\n controller.enqueue(encoder.encode(': ping\\n\\n'));\n }, 1000); // 每秒检查一次\n \n // 清理函数\n request.signal.addEventListener('abort', () => {\n clearInterval(interval);\n controller.close();\n });\n },\n });\n\n return new Response(stream, {\n headers: {\n 'Content-Type': 'text/event-stream',\n 'Cache-Control': 'no-cache',\n 'Connection': 'keep-alive',\n },\n });\n}","import {\n AppRouteRouteModule,\n type AppRouteRouteModuleOptions,\n} from '../../server/route-modules/app-route/module.compiled'\nimport { RouteKind } from '../../server/route-kind'\nimport { patchFetch as _patchFetch } from '../../server/lib/patch-fetch'\n\nimport * as userland from 'VAR_USERLAND'\n\n// These are injected by the loader afterwards. This is injected as a variable\n// instead of a replacement because this could also be `undefined` instead of\n// an empty string.\ndeclare const nextConfigOutput: AppRouteRouteModuleOptions['nextConfigOutput']\n\n// We inject the nextConfigOutput here so that we can use them in the route\n// module.\n// INJECT:nextConfigOutput\n\nconst routeModule = new AppRouteRouteModule({\n definition: {\n kind: RouteKind.APP_ROUTE,\n page: 'VAR_DEFINITION_PAGE',\n pathname: 'VAR_DEFINITION_PATHNAME',\n filename: 'VAR_DEFINITION_FILENAME',\n bundlePath: 'VAR_DEFINITION_BUNDLE_PATH',\n },\n resolvedPagePath: 'VAR_RESOLVED_PAGE_PATH',\n nextConfigOutput,\n userland,\n})\n\n// Pull out the exports that we need to expose from the module. This should\n// be eliminated when we've moved the other routes to the new format. These\n// are used to hook into the route.\nconst { workAsyncStorage, workUnitAsyncStorage, serverHooks } = routeModule\n\nfunction patchFetch() {\n return _patchFetch({\n workAsyncStorage,\n workUnitAsyncStorage,\n })\n}\n\nexport {\n routeModule,\n workAsyncStorage,\n workUnitAsyncStorage,\n serverHooks,\n patchFetch,\n}\n"],"names":["AppRouteRouteModule","RouteKind","patchFetch","_patchFetch","userland","routeModule","definition","kind","APP_ROUTE","page","pathname","filename","bundlePath","resolvedPagePath","nextConfigOutput","workAsyncStorage","workUnitAsyncStorage","serverHooks"],"mappings":"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","ignoreList":[1]}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
module.exports={35692:e=>{"use strict";var{g:t,__dirname:r}=e;e.s({ProjectStatus:()=>a,getProjectsConfig:()=>i,saveProjectsConfig:()=>o});var s=e.i(9892),n=e.i(88941);async function i(){try{await (0,s.access)(n.PROJECT_CONFIG_PATH,s.constants.F_OK)}catch{return await o({}),{}}try{let e=await (0,s.readFile)(n.PROJECT_CONFIG_PATH,"utf-8");if(!e)return{};return JSON.parse(e)}catch(e){throw console.error("读取或解析项目配置文件失败:",e),Error("无法加载项目配置")}}async function o(e){let t=n.PROJECT_CONFIG_PATH+".tmp";try{await (0,s.writeFile)(t,JSON.stringify(e,null,2),"utf-8"),await (0,s.rename)(t,n.PROJECT_CONFIG_PATH)}catch(e){throw console.error("保存项目配置文件失败:",e),Error("无法保存项目配置")}}var a=function(e){return e.PENDING="pending",e.EXISTING="existing",e.CLONING="cloning",e.SUCCESS="success",e.FAILED="failed",e.RETRYING="retrying",e}({})},88941:e=>{"use strict";var{g:t,__dirname:r}=e;{e.s({PROJECT_CONFIG_PATH:()=>r,ProjectStatus:()=>i,WORKSPACE_CONFIG:()=>t});var s=e.i(13442),n=e.i(30331);let t={WORKSPACE_ROOT:(0,n.join)((0,s.homedir)(),"Documents","prime-workspace"),GIT_TIMEOUT:3e5,MAX_CONCURRENT_CLONES:Math.max(2,Math.min((0,s.cpus)().length,8)),MAX_RETRY_ATTEMPTS:3},r=(0,n.join)((0,s.homedir)(),".prime-projects.json");var i=function(e){return e.PENDING="pending",e.EXISTING="existing",e.CLONING="cloning",e.SUCCESS="success",e.FAILED="failed",e.RETRYING="retrying",e.INCOMPLETE="incomplete",e}({})}},29549:function(e){var{g:t,__dirname:r,m:s,e:n}=e;s.exports=e.x("next/dist/compiled/next-server/app-page-turbo.runtime.prod.js",()=>require("next/dist/compiled/next-server/app-page-turbo.runtime.prod.js"))},83943:function(e){var{g:t,__dirname:r,m:s,e:n}=e;s.exports=e.x("next/dist/server/app-render/work-unit-async-storage.external.js",()=>require("next/dist/server/app-render/work-unit-async-storage.external.js"))},86103:function(e){var{g:t,__dirname:r,m:s,e:n}=e;s.exports=e.x("next/dist/server/app-render/work-async-storage.external.js",()=>require("next/dist/server/app-render/work-async-storage.external.js"))},30331:function(e){var{g:t,__dirname:r,m:s,e:n}=e;s.exports=e.x("path",()=>require("path"))},23430:function(e){var{g:t,__dirname:r,m:s,e:n}=e;s.exports=e.x("next/dist/compiled/@opentelemetry/api",()=>require("next/dist/compiled/@opentelemetry/api"))},13442:function(e){var{g:t,__dirname:r,m:s,e:n}=e;s.exports=e.x("os",()=>require("os"))},52670:function(e){var{g:t,__dirname:r,m:s,e:n}=e;s.exports=e.x("next/dist/compiled/next-server/app-route-turbo.runtime.prod.js",()=>require("next/dist/compiled/next-server/app-route-turbo.runtime.prod.js"))},9892:function(e){var{g:t,__dirname:r,m:s,e:n}=e;s.exports=e.x("fs/promises",()=>require("fs/promises"))},83886:function(e){var{g:t,__dirname:r,m:s,e:n}=e;s.exports=e.x("fs",()=>require("fs"))},87485:function(e){var{g:t,__dirname:r,m:s,e:n}=e;s.exports=e.x("child_process",()=>require("child_process"))},77159:e=>{"use strict";var{g:t,__dirname:r}=e;e.s({checkMultipleProjectsExist:()=>f,checkProjectExists:()=>d,checkProjectStatus:()=>p,cleanupIncompleteProject:()=>m,cloneRepository:()=>c,createWorkspaceDirectory:()=>a,isValidGitUrl:()=>u,openProjectInCursor:()=>x,sanitizeProjectName:()=>l});var s=e.i(87485),n=e.i(83886),i=e.i(30331),o=e.i(88941);async function a(e){try{return(0,n.existsSync)(e)||(0,n.mkdirSync)(e,{recursive:!0}),{success:!0}}catch(e){return{success:!1,error:`创建工作空间目录失败: ${e instanceof Error?e.message:String(e)}`}}}async function c(e){let{repoUrl:t,targetDir:r,timeout:n,onProgress:a,onError:c,onLog:u}=e,l=(0,i.basename)(t,".git");return new Promise(e=>{let p=Date.now(),d={projectName:l,status:o.ProjectStatus.CLONING,progress:0,message:"开始克隆项目...",startTime:p};a?.(0,"开始克隆项目...");let g=(0,i.join)(r,l),m=["clone","--progress","--verbose",t,g];u?.(l,"stdout",`[开始克隆] 执行命令: git ${m.join(" ")}
|
|
2
|
+
`),u?.(l,"stdout",`[目标目录] ${g}
|
|
3
|
+
`),u?.(l,"stdout",`[仓库地址] ${t}
|
|
4
|
+
`);let f=(0,s.spawn)("git",m,{cwd:r,stdio:["pipe","pipe","pipe"]}),x="",C=0;u?.(l,"stdout",`[进程启动] Git 进程 PID: ${f.pid}
|
|
5
|
+
`);let y=setTimeout(()=>{u?.(l,"stderr",`[超时警告] Git 进程运行超过 ${n/1e3}s,即将终止
|
|
6
|
+
`),f.kill("SIGTERM");let t={...d,status:o.ProjectStatus.FAILED,progress:C,message:"克隆操作超时",error:`克隆操作超时 (${n/1e3}s)`,endTime:Date.now()};u?.(l,"stderr",`[进程终止] 克隆操作超时
|
|
7
|
+
`),c?.(`${l}: 克隆操作超时`),e(t)},n);f.stdout?.on("data",e=>{let t=e.toString();u?.(l,"stdout",t),C=Math.min(C+10,80),a?.(C,"正在克隆代码...")}),f.stderr?.on("data",e=>{let t=e.toString();x+=t,t.includes("remote:")||t.includes("Receiving objects")||t.includes("Resolving deltas")||t.includes("Counting objects")||t.includes("Enumerating objects")||t.includes("Compressing objects")||t.includes("upload-pack")||t.includes("POST git-")||t.includes("正克隆到")||t.includes("Cloning into")?u?.(l,"progress",t):u?.(l,"stderr",t),t.includes("Receiving objects")||t.includes("Resolving deltas")?(C=Math.min(C+5,90),a?.(C,"正在接收对象...")):t.includes("Counting objects")?(C=Math.min(C+2,70),a?.(C,"正在计算对象...")):t.includes("Enumerating objects")&&(C=Math.min(C+2,50),a?.(C,"正在枚举对象..."))}),f.on("close",t=>{clearTimeout(y);let r=Date.now(),s=r-p;if(u?.(l,"stdout",`[进程结束] Git 进程退出,代码: ${t},耗时: ${Math.round(s/1e3)}s
|
|
8
|
+
`),0===t){u?.(l,"stdout",`[克隆成功] 项目已成功克隆到: ${g}
|
|
9
|
+
`);let t={...d,status:o.ProjectStatus.SUCCESS,progress:100,message:"克隆完成",endTime:r};a?.(100,"克隆完成"),e(t)}else{let s=function(e){let t=e.toLowerCase();return t.includes("authentication failed")||t.includes("access denied")?"身份验证失败,请检查仓库访问权限":t.includes("repository not found")||t.includes("not found")?"仓库不存在或无法访问":t.includes("network")||t.includes("connection")?"网络连接问题,请检查网络设置":t.includes("timeout")?"网络超时,请重试":t.includes("permission denied")?"权限被拒绝,请检查文件系统权限":t.includes("already exists")?"目标目录已存在":e.slice(0,200)+(e.length>200?"...":"")}(x);u?.(l,"stderr",`[克隆失败] 错误信息: ${s}
|
|
10
|
+
`),u?.(l,"stderr",`[完整错误输出]
|
|
11
|
+
${x}
|
|
12
|
+
`);let n={...d,status:o.ProjectStatus.FAILED,progress:C,message:"克隆失败",error:s||`Git 进程退出,代码: ${t}`,endTime:r};c?.(`${l}: ${n.error}`),e(n)}}),f.on("error",t=>{clearTimeout(y),u?.(l,"stderr",`[进程错误] Git 进程启动失败: ${t.message}
|
|
13
|
+
`),u?.(l,"stderr",`[错误详情] ${t.stack||"No stack trace"}
|
|
14
|
+
`);let r={...d,status:o.ProjectStatus.FAILED,progress:C,message:"进程启动失败",error:`进程启动失败: ${t.message}`,endTime:Date.now()};c?.(`${l}: ${t.message}`),e(r)})})}function u(e){return/^(https?:\/\/|git@)[^\s]+\.git$/i.test(e)}function l(e){return e.replace(/[^a-zA-Z0-9\-_]/g,"")}async function p(e,t){try{let r=(0,i.join)(e,t);if(!(0,n.existsSync)(r))return{exists:!1,status:"not_exists",needsCleanup:!1};let s=(0,i.join)(r,".git");if(!(0,n.existsSync)(s))return{exists:!0,status:"incomplete",needsCleanup:!0};if(!await g(r))return console.log(`检测到不完整的Git仓库: ${r}`),{exists:!0,status:"incomplete",needsCleanup:!0};return{exists:!0,status:"complete",needsCleanup:!1}}catch(e){return console.error(`检查项目 ${t} 状态时出错:`,e),{exists:!1,status:"not_exists",needsCleanup:!1}}}async function d(e,t){return"complete"===(await p(e,t)).status}async function g(e){try{let t=(0,i.join)(e,".git");for(let e of["HEAD","config","refs"]){let r=(0,i.join)(t,e);if(!(0,n.existsSync)(r))return!1}let r=(await n.promises.readdir(e)).filter(e=>".git"!==e);if(0===r.length)return!1;let s=(0,i.join)(t,"HEAD"),o=await n.promises.readFile(s,"utf-8");if(!o.trim()||o.includes("unborn"))return!1;return!0}catch(e){return console.error("检查Git仓库完整性时出错:",e),!1}}async function m(e){try{console.log(`正在清理不完整的项目: ${e}`),await n.promises.rm(e,{recursive:!0,force:!0}),console.log(`清理完成: ${e}`)}catch(t){console.error(`清理项目失败 ${e}:`,t)}}async function f(e,t){let r={},s=t.map(async t=>{let s=await d(e,t);r[t]=s});return await Promise.all(s),r}async function x(e){return new Promise(t=>{if(!(0,n.existsSync)(e))return void t({success:!1,error:`项目路径不存在: ${e}`});let r=(0,s.spawn)("cursor",[e],{stdio:["ignore","pipe","pipe"],detached:!0,env:{...process.env,NODE_ENV:"development"}}),i="",o=setTimeout(()=>{r.kill("SIGTERM"),t({success:!1,error:"Cursor 命令执行超时"})},1e4);r.stderr?.on("data",e=>{i+=e.toString()}),r.on("exit",e=>{clearTimeout(o),0===e?t({success:!0}):t({success:!1,error:`Cursor 退出代码: ${e}${i?`, 错误: ${i}`:""}`})}),r.on("error",e=>{clearTimeout(o),e.message.includes("ENOENT")?t({success:!1,error:"Cursor 命令未找到,请确保 Cursor CLI 已正确安装并在 PATH 中"}):t({success:!1,error:`启动 Cursor 失败: ${e.message}`})}),r.unref()})}},16822:function(e){var{g:t,__dirname:r,m:s,e:n}=e},89950:e=>{"use strict";var{g:t,__dirname:r}=e;e.s({POST:()=>o});var s=e.i(88941),n=e.i(35692),i=e.i(77159);async function o(e){try{let{projectName:t}=await e.json();if(!t||"string"!=typeof t)return new Response(JSON.stringify({success:!1,error:"项目名称是必需的"}),{status:400,headers:{"Content-Type":"application/json"}});let r=await (0,n.getProjectsConfig)();if(!(t in r))return new Response(JSON.stringify({success:!1,error:`项目 ${t} 不存在于配置中`}),{status:404,headers:{"Content-Type":"application/json"}});let o=r[t],a=s.WORKSPACE_CONFIG.WORKSPACE_ROOT,c=await (0,i.cloneRepository)({repoUrl:o.repo,targetDir:a,timeout:s.WORKSPACE_CONFIG.GIT_TIMEOUT}),u={success:c.status===s.ProjectStatus.SUCCESS,projectName:t,status:c.status,message:c.message,error:c.error,progress:c.progress,duration:c.endTime&&c.startTime?c.endTime-c.startTime:0};return new Response(JSON.stringify(u),{status:200,headers:{"Content-Type":"application/json"}})}catch(t){let e=t instanceof Error?t.message:String(t);return console.error("重试项目克隆失败:",t),new Response(JSON.stringify({success:!1,error:`重试失败: ${e}`}),{status:500,headers:{"Content-Type":"application/json"}})}}},23856:e=>{"use strict";var{g:t,__dirname:r}=e;{e.s({patchFetch:()=>a,routeModule:()=>t,serverHooks:()=>u,workAsyncStorage:()=>r,workUnitAsyncStorage:()=>c});var s=e.i(45746),n=e.i(93828),i=e.i(18250),o=e.i(89950);let t=new s.AppRouteRouteModule({definition:{kind:n.RouteKind.APP_ROUTE,page:"/api/retry-project/route",pathname:"/api/retry-project",filename:"route",bundlePath:""},resolvedPagePath:"[project]/packages/server/src/app/api/retry-project/route.ts",nextConfigOutput:"",userland:o}),{workAsyncStorage:r,workUnitAsyncStorage:c,serverHooks:u}=t;function a(){return(0,i.patchFetch)({workAsyncStorage:r,workUnitAsyncStorage:c})}}}};
|
|
15
|
+
|
|
16
|
+
//# sourceMappingURL=%5Broot-of-the-server%5D__7a46f739._.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["turbopack:///[project]/packages/server/src/lib/workspace-config.ts","turbopack:///[project]/packages/server/src/lib/workspace-types.ts","turbopack:///[project]/packages/server/src/lib/git-operations.ts","turbopack:///[project]/packages/server/src/app/api/retry-project/route.ts","turbopack:///[project]/node_modules/.pnpm/next@15.3.4_react-dom@19.1.0_react@19.1.0__react@19.1.0/node_modules/next/dist/src/build/templates/app-route.ts"],"sourcesContent":["import { readFile, writeFile, access, constants, rename } from 'fs/promises';\nimport type { ProjectsConfig } from './workspace-types';\nimport { PROJECT_CONFIG_PATH } from './workspace-types';\n\n/**\n * 读取并解析项目配置文件\n * @returns {Promise<ProjectsConfig>} 项目配置对象\n */\nexport async function getProjectsConfig(): Promise<ProjectsConfig> {\n try {\n await access(PROJECT_CONFIG_PATH, constants.F_OK);\n } catch {\n // 文件不存在,创建并写入空对象\n await saveProjectsConfig({});\n return {};\n }\n\n try {\n const configContent = await readFile(PROJECT_CONFIG_PATH, 'utf-8');\n // 如果文件为空,返回空对象\n if (!configContent) {\n return {};\n }\n return JSON.parse(configContent);\n } catch (error) {\n console.error('读取或解析项目配置文件失败:', error);\n // 在出错时返回空对象或抛出错误,这里选择抛出以通知调用者\n throw new Error('无法加载项目配置');\n }\n}\n\n/**\n * 将项目配置写入文件(原子操作)\n * @param {ProjectsConfig} config - 要保存的配置对象\n */\nexport async function saveProjectsConfig(config: ProjectsConfig): Promise<void> {\n const tempConfigPath = PROJECT_CONFIG_PATH + '.tmp';\n try {\n await writeFile(tempConfigPath, JSON.stringify(config, null, 2), 'utf-8');\n await rename(tempConfigPath, PROJECT_CONFIG_PATH);\n } catch (error) {\n console.error('保存项目配置文件失败:', error);\n throw new Error('无法保存项目配置');\n }\n}\n\n/**\n * 项目状态枚举\n */\nexport enum ProjectStatus {\n PENDING = 'pending',\n EXISTING = 'existing',\n CLONING = 'cloning',\n SUCCESS = 'success',\n FAILED = 'failed',\n RETRYING = 'retrying',\n}\n\n/**\n * 项目进度信息接口\n */\nexport interface ProjectProgress {\n projectName: string;\n status: ProjectStatus;\n progress: number; // 0-100\n message: string;\n error?: string;\n startTime?: number;\n endTime?: number;\n}\n\n/**\n * 初始化结果接口\n */\nexport interface InitializationResult {\n success: boolean;\n totalProjects: number;\n successCount: number;\n failedCount: number;\n failedProjects: string[];\n workspacePath: string;\n duration: number;\n}\n\n/**\n * Git 操作配置接口\n */\nexport interface GitOperationConfig {\n repoUrl: string;\n targetDir: string;\n timeout: number;\n onProgress?: (progress: number, message: string) => void;\n onError?: (error: string) => void;\n}","import { homedir, cpus } from 'os';\nimport { join } from 'path';\n\n/**\n * 工作空间配置常量\n */\nexport const WORKSPACE_CONFIG = {\n // 工作空间根目录路径\n WORKSPACE_ROOT: join(homedir(), 'Documents', 'prime-workspace'),\n\n // Git 操作超时时间 (毫秒)\n GIT_TIMEOUT: 300000, // 5分钟\n\n // 最大并发克隆数量(基于CPU核心数,最小2个,最大8个)\n MAX_CONCURRENT_CLONES: Math.max(2, Math.min(cpus().length, 8)),\n\n // 重试次数限制\n MAX_RETRY_ATTEMPTS: 3,\n} as const;\n\nexport const PROJECT_CONFIG_PATH = join(homedir(), '.prime-projects.json');\n\nexport interface ProjectConfig {\n repo: string;\n mockingIntercept?: boolean;\n mockOpen?: boolean;\n envs: {\n [envName: string]: {\n host: string;\n currentProxy: string;\n proxyEnv: {\n [key: string]: string;\n };\n envFileName: string;\n proxyKey: string;\n subApps?: string[];\n };\n };\n}\n\nexport interface ProjectsConfig {\n [projectName: string]: ProjectConfig;\n}\n\n/**\n * 项目状态枚举\n */\nexport enum ProjectStatus {\n PENDING = 'pending',\n EXISTING = 'existing',\n CLONING = 'cloning',\n SUCCESS = 'success',\n FAILED = 'failed',\n RETRYING = 'retrying',\n INCOMPLETE = 'incomplete', // 不完整的项目,需要清理\n}\n\n/**\n * 项目进度信息接口\n */\nexport interface ProjectProgress {\n projectName: string;\n status: ProjectStatus;\n progress: number; // 0-100\n message: string;\n error?: string;\n startTime?: number;\n endTime?: number;\n}\n\n/**\n * 初始化结果接口\n */\nexport interface InitializationResult {\n success: boolean;\n totalProjects: number;\n successCount: number;\n failedCount: number;\n failedProjects: string[];\n workspacePath: string;\n duration: number;\n}\n\n/**\n * Git 操作配置接口\n */\nexport interface GitOperationConfig {\n repoUrl: string;\n targetDir: string;\n timeout: number;\n onProgress?: (progress: number, message: string) => void;\n onError?: (error: string) => void;\n onLog?: (projectName: string, logType: 'stdout' | 'stderr' | 'progress', content: string) => void;\n} ","import { spawn, ChildProcess } from 'child_process';\nimport { existsSync, mkdirSync } from 'fs';\nimport { promises as fs } from 'fs';\nimport { join, basename } from 'path';\nimport {\n ProjectStatus,\n type GitOperationConfig,\n type ProjectProgress,\n} from './workspace-types';\n\n/**\n * 创建工作空间目录\n * @param workspacePath 工作空间路径\n * @returns 创建结果\n */\nexport async function createWorkspaceDirectory(workspacePath: string): Promise<{ success: boolean; error?: string }> {\n try {\n if (!existsSync(workspacePath)) {\n mkdirSync(workspacePath, { recursive: true });\n }\n return { success: true };\n } catch (error) {\n return { \n success: false, \n error: `创建工作空间目录失败: ${error instanceof Error ? error.message : String(error)}` \n };\n }\n}\n\n/**\n * 执行 Git 克隆操作\n * @param config Git 操作配置\n * @returns Promise<ProjectProgress>\n */\nexport async function cloneRepository(config: GitOperationConfig): Promise<ProjectProgress> {\n const { repoUrl, targetDir, timeout, onProgress, onError, onLog } = config;\n const projectName = basename(repoUrl, '.git');\n \n return new Promise<ProjectProgress>((resolve) => {\n const startTime = Date.now();\n \n // 更新开始状态\n const initialProgress: ProjectProgress = {\n projectName,\n status: ProjectStatus.CLONING,\n progress: 0,\n message: '开始克隆项目...',\n startTime,\n };\n onProgress?.(0, '开始克隆项目...');\n\n // 执行 git clone 命令\n const targetPath = join(targetDir, projectName);\n // 添加 --progress 参数来强制显示进度,--verbose 显示详细信息\n const gitArgs = ['clone', '--progress', '--verbose', repoUrl, targetPath];\n \n // 记录命令启动信息\n onLog?.(projectName, 'stdout', `[开始克隆] 执行命令: git ${gitArgs.join(' ')}\\n`);\n onLog?.(projectName, 'stdout', `[目标目录] ${targetPath}\\n`);\n onLog?.(projectName, 'stdout', `[仓库地址] ${repoUrl}\\n`);\n \n const gitProcess: ChildProcess = spawn('git', gitArgs, {\n cwd: targetDir,\n stdio: ['pipe', 'pipe', 'pipe'],\n });\n\n let errorOutput = '';\n let progressValue = 0;\n \n // 记录进程启动成功\n onLog?.(projectName, 'stdout', `[进程启动] Git 进程 PID: ${gitProcess.pid}\\n`);\n\n // 设置超时\n const timeoutId = setTimeout(() => {\n onLog?.(projectName, 'stderr', `[超时警告] Git 进程运行超过 ${timeout / 1000}s,即将终止\\n`);\n gitProcess.kill('SIGTERM');\n \n const errorResult: ProjectProgress = {\n ...initialProgress,\n status: ProjectStatus.FAILED,\n progress: progressValue,\n message: '克隆操作超时',\n error: `克隆操作超时 (${timeout / 1000}s)`,\n endTime: Date.now(),\n };\n onLog?.(projectName, 'stderr', `[进程终止] 克隆操作超时\\n`);\n onError?.(`${projectName}: 克隆操作超时`);\n resolve(errorResult);\n }, timeout);\n\n // 处理标准输出\n gitProcess.stdout?.on('data', (data: Buffer) => {\n const stdoutText = data.toString();\n \n // 实时发送日志\n onLog?.(projectName, 'stdout', stdoutText);\n \n // 模拟进度更新(Git 克隆没有内置进度,这里基于时间估算)\n progressValue = Math.min(progressValue + 10, 80);\n onProgress?.(progressValue, '正在克隆代码...');\n });\n\n // 处理错误输出\n gitProcess.stderr?.on('data', (data: Buffer) => {\n const stderrText = data.toString();\n errorOutput += stderrText;\n \n // 判断是进度信息还是错误信息\n const isProgressInfo = stderrText.includes('remote:') || \n stderrText.includes('Receiving objects') || \n stderrText.includes('Resolving deltas') ||\n stderrText.includes('Counting objects') ||\n stderrText.includes('Enumerating objects') ||\n stderrText.includes('Compressing objects') ||\n stderrText.includes('upload-pack') ||\n stderrText.includes('POST git-') ||\n stderrText.includes('正克隆到') ||\n stderrText.includes('Cloning into');\n \n // 根据内容类型发送不同的日志\n if (isProgressInfo) {\n onLog?.(projectName, 'progress', stderrText);\n } else {\n onLog?.(projectName, 'stderr', stderrText);\n }\n \n // Git 的进度信息通常在 stderr 中\n if (stderrText.includes('Receiving objects') || stderrText.includes('Resolving deltas')) {\n progressValue = Math.min(progressValue + 5, 90);\n onProgress?.(progressValue, '正在接收对象...');\n } else if (stderrText.includes('Counting objects')) {\n progressValue = Math.min(progressValue + 2, 70);\n onProgress?.(progressValue, '正在计算对象...');\n } else if (stderrText.includes('Enumerating objects')) {\n progressValue = Math.min(progressValue + 2, 50);\n onProgress?.(progressValue, '正在枚举对象...');\n }\n });\n\n // 处理进程结束\n gitProcess.on('close', (code: number | null) => {\n clearTimeout(timeoutId);\n const endTime = Date.now();\n const duration = endTime - startTime;\n \n onLog?.(projectName, 'stdout', `[进程结束] Git 进程退出,代码: ${code},耗时: ${Math.round(duration / 1000)}s\\n`);\n \n if (code === 0) {\n // 克隆成功\n onLog?.(projectName, 'stdout', `[克隆成功] 项目已成功克隆到: ${targetPath}\\n`);\n const successResult: ProjectProgress = {\n ...initialProgress,\n status: ProjectStatus.SUCCESS,\n progress: 100,\n message: '克隆完成',\n endTime,\n };\n onProgress?.(100, '克隆完成');\n resolve(successResult);\n } else {\n // 克隆失败\n const parsedError = parseGitError(errorOutput);\n onLog?.(projectName, 'stderr', `[克隆失败] 错误信息: ${parsedError}\\n`);\n onLog?.(projectName, 'stderr', `[完整错误输出]\\n${errorOutput}\\n`);\n \n const failureResult: ProjectProgress = {\n ...initialProgress,\n status: ProjectStatus.FAILED,\n progress: progressValue,\n message: '克隆失败',\n error: parsedError || `Git 进程退出,代码: ${code}`,\n endTime,\n };\n onError?.(`${projectName}: ${failureResult.error}`);\n resolve(failureResult);\n }\n });\n\n // 处理进程错误\n gitProcess.on('error', (error: Error) => {\n clearTimeout(timeoutId);\n onLog?.(projectName, 'stderr', `[进程错误] Git 进程启动失败: ${error.message}\\n`);\n onLog?.(projectName, 'stderr', `[错误详情] ${error.stack || 'No stack trace'}\\n`);\n \n const errorResult: ProjectProgress = {\n ...initialProgress,\n status: ProjectStatus.FAILED,\n progress: progressValue,\n message: '进程启动失败',\n error: `进程启动失败: ${error.message}`,\n endTime: Date.now(),\n };\n onError?.(`${projectName}: ${error.message}`);\n resolve(errorResult);\n });\n });\n}\n\n/**\n * 解析 Git 错误信息,提供用户友好的错误描述\n * @param errorOutput Git stderr 输出\n * @returns 用户友好的错误描述\n */\nfunction parseGitError(errorOutput: string): string {\n const lowerOutput = errorOutput.toLowerCase();\n \n if (lowerOutput.includes('authentication failed') || lowerOutput.includes('access denied')) {\n return '身份验证失败,请检查仓库访问权限';\n }\n \n if (lowerOutput.includes('repository not found') || lowerOutput.includes('not found')) {\n return '仓库不存在或无法访问';\n }\n \n if (lowerOutput.includes('network') || lowerOutput.includes('connection')) {\n return '网络连接问题,请检查网络设置';\n }\n \n if (lowerOutput.includes('timeout')) {\n return '网络超时,请重试';\n }\n \n if (lowerOutput.includes('permission denied')) {\n return '权限被拒绝,请检查文件系统权限';\n }\n \n if (lowerOutput.includes('already exists')) {\n return '目标目录已存在';\n }\n \n // 返回原始错误的前200个字符\n return errorOutput.slice(0, 200) + (errorOutput.length > 200 ? '...' : '');\n}\n\n/**\n * 验证 Git 仓库 URL 格式\n * @param url Git 仓库 URL\n * @returns 是否有效\n */\nexport function isValidGitUrl(url: string): boolean {\n const gitUrlPattern = /^(https?:\\/\\/|git@)[^\\s]+\\.git$/i;\n return gitUrlPattern.test(url);\n}\n\n/**\n * 清理项目名称,移除不安全字符\n * @param projectName 项目名称\n * @returns 清理后的项目名称\n */\nexport function sanitizeProjectName(projectName: string): string {\n return projectName.replace(/[^a-zA-Z0-9\\-_]/g, '');\n}\n\n/**\n * 项目检查结果类型\n */\nexport type ProjectCheckResult = {\n exists: boolean;\n status: 'not_exists' | 'complete' | 'incomplete';\n needsCleanup: boolean;\n};\n\n/**\n * 检查项目状态(详细版本)\n * @param workspacePath 工作空间路径\n * @param projectName 项目名称\n * @returns Promise<ProjectCheckResult> 详细的项目状态\n */\nexport async function checkProjectStatus(workspacePath: string, projectName: string): Promise<ProjectCheckResult> {\n try {\n const projectPath = join(workspacePath, projectName);\n \n // 检查项目目录是否存在\n if (!existsSync(projectPath)) {\n return {\n exists: false,\n status: 'not_exists',\n needsCleanup: false\n };\n }\n \n // 检查是否为 Git 仓库(存在 .git 目录)\n const gitPath = join(projectPath, '.git');\n if (!existsSync(gitPath)) {\n return {\n exists: true,\n status: 'incomplete',\n needsCleanup: true\n };\n }\n \n // 更严格的完整性检查\n const isComplete = await isGitRepositoryComplete(projectPath);\n if (!isComplete) {\n console.log(`检测到不完整的Git仓库: ${projectPath}`);\n return {\n exists: true,\n status: 'incomplete',\n needsCleanup: true\n };\n }\n \n return {\n exists: true,\n status: 'complete',\n needsCleanup: false\n };\n } catch (error) {\n console.error(`检查项目 ${projectName} 状态时出错:`, error);\n return {\n exists: false,\n status: 'not_exists',\n needsCleanup: false\n };\n }\n}\n\n/**\n * 检查项目是否已存在于工作空间中(兼容版本)\n * @param workspacePath 工作空间路径\n * @param projectName 项目名称\n * @returns Promise<boolean> 项目是否存在且为有效的 Git 仓库\n */\nexport async function checkProjectExists(workspacePath: string, projectName: string): Promise<boolean> {\n const result = await checkProjectStatus(workspacePath, projectName);\n return result.status === 'complete';\n}\n\n/**\n * 检查Git仓库是否完整\n * @param projectPath 项目路径\n * @returns Promise<boolean> 仓库是否完整\n */\nasync function isGitRepositoryComplete(projectPath: string): Promise<boolean> {\n try {\n const gitPath = join(projectPath, '.git');\n \n // 检查关键的Git文件是否存在\n const requiredFiles = ['HEAD', 'config', 'refs'];\n for (const file of requiredFiles) {\n const filePath = join(gitPath, file);\n if (!existsSync(filePath)) {\n return false;\n }\n }\n \n // 检查是否有实际的项目文件(不只是.git目录)\n const entries = await fs.readdir(projectPath);\n const nonGitFiles = entries.filter((entry: string) => entry !== '.git');\n \n // 如果只有.git目录,说明克隆未完成\n if (nonGitFiles.length === 0) {\n return false;\n }\n \n // 检查HEAD文件是否有效\n const headPath = join(gitPath, 'HEAD');\n const headContent = await fs.readFile(headPath, 'utf-8');\n if (!headContent.trim() || headContent.includes('unborn')) {\n return false;\n }\n \n return true;\n } catch (error) {\n console.error('检查Git仓库完整性时出错:', error);\n return false;\n }\n}\n\n/**\n * 清理不完整的项目目录\n * @param projectPath 项目路径\n */\nexport async function cleanupIncompleteProject(projectPath: string): Promise<void> {\n try {\n console.log(`正在清理不完整的项目: ${projectPath}`);\n await fs.rm(projectPath, { recursive: true, force: true });\n console.log(`清理完成: ${projectPath}`);\n } catch (error) {\n console.error(`清理项目失败 ${projectPath}:`, error);\n // 清理失败不抛出错误,避免阻塞后续流程\n }\n}\n\n/**\n * 批量检查多个项目的存在状态\n * @param workspacePath 工作空间路径\n * @param projectNames 项目名称列表\n * @returns Promise<Record<string, boolean>> 项目名称到存在状态的映射\n */\nexport async function checkMultipleProjectsExist(\n workspacePath: string, \n projectNames: string[]\n): Promise<Record<string, boolean>> {\n const results: Record<string, boolean> = {};\n \n // 并行检查所有项目\n const checks = projectNames.map(async (projectName) => {\n const exists = await checkProjectExists(workspacePath, projectName);\n results[projectName] = exists;\n });\n \n await Promise.all(checks);\n return results;\n}\n\n/**\n * 在 Cursor 中打开项目\n * @param projectPath 项目的绝对路径\n * @returns Promise<{ success: boolean; error?: string }>\n */\nexport async function openProjectInCursor(projectPath: string): Promise<{ success: boolean; error?: string }> {\n return new Promise((resolve) => {\n // 验证项目路径存在\n if (!existsSync(projectPath)) {\n resolve({\n success: false,\n error: `项目路径不存在: ${projectPath}`\n });\n return;\n }\n\n // 执行 cursor 命令\n const cursorProcess = spawn('cursor', [projectPath], {\n stdio: ['ignore', 'pipe', 'pipe'],\n detached: true, // 让进程在后台独立运行\n env: {\n ...process.env,\n NODE_ENV: 'development', // 强制设置为开发模式\n }\n });\n\n let errorOutput = '';\n\n // 设置超时(10秒)\n const timeoutId = setTimeout(() => {\n cursorProcess.kill('SIGTERM');\n resolve({\n success: false,\n error: 'Cursor 命令执行超时'\n });\n }, 10000);\n\n // 处理错误输出\n cursorProcess.stderr?.on('data', (data: Buffer) => {\n errorOutput += data.toString();\n });\n\n // 处理进程退出\n cursorProcess.on('exit', (code: number | null) => {\n clearTimeout(timeoutId);\n \n if (code === 0) {\n resolve({ success: true });\n } else {\n resolve({\n success: false,\n error: `Cursor 退出代码: ${code}${errorOutput ? `, 错误: ${errorOutput}` : ''}`\n });\n }\n });\n\n // 处理进程错误(如命令不存在)\n cursorProcess.on('error', (error: Error) => {\n clearTimeout(timeoutId);\n \n if (error.message.includes('ENOENT')) {\n resolve({\n success: false,\n error: 'Cursor 命令未找到,请确保 Cursor CLI 已正确安装并在 PATH 中'\n });\n } else {\n resolve({\n success: false,\n error: `启动 Cursor 失败: ${error.message}`\n });\n }\n });\n\n // 让进程独立运行,不等待其完成\n cursorProcess.unref();\n });\n} ","import { NextRequest } from 'next/server';\nimport {\n WORKSPACE_CONFIG,\n ProjectStatus,\n} from '@/lib/workspace-types';\nimport { getProjectsConfig } from '@/lib/workspace-config';\nimport { cloneRepository } from '@/lib/git-operations';\n\n/**\n * 重试单个项目克隆 API 端点\n */\nexport async function POST(request: NextRequest) {\n try {\n const body = await request.json();\n const { projectName } = body;\n\n if (!projectName || typeof projectName !== 'string') {\n return new Response(\n JSON.stringify({ \n success: false, \n error: '项目名称是必需的' \n }),\n { \n status: 400,\n headers: { 'Content-Type': 'application/json' }\n }\n );\n }\n\n // 读取项目配置\n const projectsConfig = await getProjectsConfig();\n \n if (!(projectName in projectsConfig)) {\n return new Response(\n JSON.stringify({ \n success: false, \n error: `项目 ${projectName} 不存在于配置中` \n }),\n { \n status: 404,\n headers: { 'Content-Type': 'application/json' }\n }\n );\n }\n\n const projectConfig = projectsConfig[projectName];\n const workspacePath = WORKSPACE_CONFIG.WORKSPACE_ROOT;\n\n // 执行项目克隆\n const cloneResult = await cloneRepository({\n repoUrl: projectConfig.repo,\n targetDir: workspacePath,\n timeout: WORKSPACE_CONFIG.GIT_TIMEOUT,\n });\n\n // 返回克隆结果\n const response = {\n success: cloneResult.status === ProjectStatus.SUCCESS,\n projectName,\n status: cloneResult.status,\n message: cloneResult.message,\n error: cloneResult.error,\n progress: cloneResult.progress,\n duration: cloneResult.endTime && cloneResult.startTime \n ? cloneResult.endTime - cloneResult.startTime \n : 0,\n };\n\n return new Response(\n JSON.stringify(response),\n { \n status: 200,\n headers: { 'Content-Type': 'application/json' }\n }\n );\n\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n console.error(\"重试项目克隆失败:\", error);\n \n return new Response(\n JSON.stringify({ \n success: false, \n error: `重试失败: ${errorMessage}` \n }),\n { \n status: 500,\n headers: { 'Content-Type': 'application/json' }\n }\n );\n }\n} ","import {\n AppRouteRouteModule,\n type AppRouteRouteModuleOptions,\n} from '../../server/route-modules/app-route/module.compiled'\nimport { RouteKind } from '../../server/route-kind'\nimport { patchFetch as _patchFetch } from '../../server/lib/patch-fetch'\n\nimport * as userland from 'VAR_USERLAND'\n\n// These are injected by the loader afterwards. This is injected as a variable\n// instead of a replacement because this could also be `undefined` instead of\n// an empty string.\ndeclare const nextConfigOutput: AppRouteRouteModuleOptions['nextConfigOutput']\n\n// We inject the nextConfigOutput here so that we can use them in the route\n// module.\n// INJECT:nextConfigOutput\n\nconst routeModule = new AppRouteRouteModule({\n definition: {\n kind: RouteKind.APP_ROUTE,\n page: 'VAR_DEFINITION_PAGE',\n pathname: 'VAR_DEFINITION_PATHNAME',\n filename: 'VAR_DEFINITION_FILENAME',\n bundlePath: 'VAR_DEFINITION_BUNDLE_PATH',\n },\n resolvedPagePath: 'VAR_RESOLVED_PAGE_PATH',\n nextConfigOutput,\n userland,\n})\n\n// Pull out the exports that we need to expose from the module. This should\n// be eliminated when we've moved the other routes to the new format. These\n// are used to hook into the route.\nconst { workAsyncStorage, workUnitAsyncStorage, serverHooks } = routeModule\n\nfunction patchFetch() {\n return _patchFetch({\n workAsyncStorage,\n workUnitAsyncStorage,\n })\n}\n\nexport {\n routeModule,\n workAsyncStorage,\n workUnitAsyncStorage,\n serverHooks,\n patchFetch,\n}\n"],"names":["AppRouteRouteModule","RouteKind","patchFetch","_patchFetch","userland","routeModule","definition","kind","APP_ROUTE","page","pathname","filename","bundlePath","resolvedPagePath","nextConfigOutput","workAsyncStorage","workUnitAsyncStorage","serverHooks"],"mappings":"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","ignoreList":[4]}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
module.exports={83886:function(e){var{g:t,__dirname:r,m:s,e:o}=e;s.exports=e.x("fs",()=>require("fs"))},45935:function(e){var{g:t,__dirname:r,m:s,e:o}=e;s.exports=e.x("next/dist/server/app-render/after-task-async-storage.external.js",()=>require("next/dist/server/app-render/after-task-async-storage.external.js"))},35692:e=>{"use strict";var{g:t,__dirname:r}=e;e.s({ProjectStatus:()=>a,getProjectsConfig:()=>n,saveProjectsConfig:()=>i});var s=e.i(9892),o=e.i(88941);async function n(){try{await (0,s.access)(o.PROJECT_CONFIG_PATH,s.constants.F_OK)}catch{return await i({}),{}}try{let e=await (0,s.readFile)(o.PROJECT_CONFIG_PATH,"utf-8");if(!e)return{};return JSON.parse(e)}catch(e){throw console.error("读取或解析项目配置文件失败:",e),Error("无法加载项目配置")}}async function i(e){let t=o.PROJECT_CONFIG_PATH+".tmp";try{await (0,s.writeFile)(t,JSON.stringify(e,null,2),"utf-8"),await (0,s.rename)(t,o.PROJECT_CONFIG_PATH)}catch(e){throw console.error("保存项目配置文件失败:",e),Error("无法保存项目配置")}}var a=function(e){return e.PENDING="pending",e.EXISTING="existing",e.CLONING="cloning",e.SUCCESS="success",e.FAILED="failed",e.RETRYING="retrying",e}({})},88941:e=>{"use strict";var{g:t,__dirname:r}=e;{e.s({PROJECT_CONFIG_PATH:()=>r,ProjectStatus:()=>n,WORKSPACE_CONFIG:()=>t});var s=e.i(13442),o=e.i(30331);let t={WORKSPACE_ROOT:(0,o.join)((0,s.homedir)(),"Documents","prime-workspace"),GIT_TIMEOUT:3e5,MAX_CONCURRENT_CLONES:Math.max(2,Math.min((0,s.cpus)().length,8)),MAX_RETRY_ATTEMPTS:3},r=(0,o.join)((0,s.homedir)(),".prime-projects.json");var n=function(e){return e.PENDING="pending",e.EXISTING="existing",e.CLONING="cloning",e.SUCCESS="success",e.FAILED="failed",e.RETRYING="retrying",e.INCOMPLETE="incomplete",e}({})}},29549:function(e){var{g:t,__dirname:r,m:s,e:o}=e;s.exports=e.x("next/dist/compiled/next-server/app-page-turbo.runtime.prod.js",()=>require("next/dist/compiled/next-server/app-page-turbo.runtime.prod.js"))},83943:function(e){var{g:t,__dirname:r,m:s,e:o}=e;s.exports=e.x("next/dist/server/app-render/work-unit-async-storage.external.js",()=>require("next/dist/server/app-render/work-unit-async-storage.external.js"))},86103:function(e){var{g:t,__dirname:r,m:s,e:o}=e;s.exports=e.x("next/dist/server/app-render/work-async-storage.external.js",()=>require("next/dist/server/app-render/work-async-storage.external.js"))},30331:function(e){var{g:t,__dirname:r,m:s,e:o}=e;s.exports=e.x("path",()=>require("path"))},23430:function(e){var{g:t,__dirname:r,m:s,e:o}=e;s.exports=e.x("next/dist/compiled/@opentelemetry/api",()=>require("next/dist/compiled/@opentelemetry/api"))},13442:function(e){var{g:t,__dirname:r,m:s,e:o}=e;s.exports=e.x("os",()=>require("os"))},52670:function(e){var{g:t,__dirname:r,m:s,e:o}=e;s.exports=e.x("next/dist/compiled/next-server/app-route-turbo.runtime.prod.js",()=>require("next/dist/compiled/next-server/app-route-turbo.runtime.prod.js"))},9892:function(e){var{g:t,__dirname:r,m:s,e:o}=e;s.exports=e.x("fs/promises",()=>require("fs/promises"))},15650:function(e){var{g:t,__dirname:r,m:s,e:o}=e;s.exports=e.x("module",()=>require("module"))},21340:function(e){var{g:t,__dirname:r,m:s,e:o}=e},17228:e=>{"use strict";var{g:t,__dirname:r}=e;{e.s({PUT:()=>c});var s=e.i(15494),o=e.i(83886),n=e.i(30331),i=e.i(35692),a=e.i(88941);let t=(0,e.i(15650).createRequire)({get url(){return`file://${e.P("packages/server/src/app/api/mock-open-status/route.ts")}`}}.url);async function c(e){try{let{projectName:r,apiName:c,method:u,siteName:p,isOpen:l}=await e.json();if(!r||!c||!u||!p||"boolean"!=typeof l)return s.NextResponse.json({success:!1,error:"缺少必要参数:projectName, apiName, method, siteName, isOpen"},{status:400});if(!(await (0,i.getProjectsConfig)())[r])return s.NextResponse.json({success:!1,error:`项目 ${r} 不存在`},{status:404});let m=(0,n.join)(a.WORKSPACE_CONFIG.WORKSPACE_ROOT,r),x=(0,n.join)(m,".mock",c,u.toLowerCase(),"setting.js");try{await o.promises.access(x)}catch{return s.NextResponse.json({success:!1,error:"setting.js文件不存在"},{status:404})}let g={};try{let e=(0,n.resolve)(x);delete t.cache[e],g=t(e)}catch(e){console.warn(`解析setting.js失败: ${x}`,e)}Array.isArray(g.open)||(g.open=[]);let d=g.open,f=d.indexOf(p);l?-1===f&&d.push(p):-1!==f&&d.splice(f,1);let v=`module.exports = {
|
|
2
|
+
// 当前场景名称
|
|
3
|
+
currentSite: '${g.currentSite||p}',
|
|
4
|
+
// 开启Mock的场景列表
|
|
5
|
+
open: ${JSON.stringify(d)}
|
|
6
|
+
};`;return await o.promises.writeFile(x,v,"utf-8"),s.NextResponse.json({success:!0,message:"Mock开启状态更新成功",data:{projectName:r,apiName:c,method:u.toLowerCase(),siteName:p,isOpen:l,openSites:d,filePath:(0,n.join)(".mock",c,u.toLowerCase(),"setting.js"),updatedAt:new Date().toISOString()}})}catch(t){let e=t instanceof Error?t.message:"更新Mock开启状态失败";return console.error("更新Mock开启状态失败:",t),s.NextResponse.json({success:!1,error:e},{status:500})}}}},40178:e=>{"use strict";var{g:t,__dirname:r}=e;{e.s({patchFetch:()=>a,routeModule:()=>t,serverHooks:()=>u,workAsyncStorage:()=>r,workUnitAsyncStorage:()=>c});var s=e.i(45746),o=e.i(93828),n=e.i(18250),i=e.i(17228);let t=new s.AppRouteRouteModule({definition:{kind:o.RouteKind.APP_ROUTE,page:"/api/mock-open-status/route",pathname:"/api/mock-open-status",filename:"route",bundlePath:""},resolvedPagePath:"[project]/packages/server/src/app/api/mock-open-status/route.ts",nextConfigOutput:"",userland:i}),{workAsyncStorage:r,workUnitAsyncStorage:c,serverHooks:u}=t;function a(){return(0,n.patchFetch)({workAsyncStorage:r,workUnitAsyncStorage:c})}}}};
|
|
7
|
+
|
|
8
|
+
//# sourceMappingURL=%5Broot-of-the-server%5D__84542811._.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["turbopack:///[project]/packages/server/src/lib/workspace-config.ts","turbopack:///[project]/packages/server/src/lib/workspace-types.ts","turbopack:///[project]/packages/server/src/app/api/mock-open-status/route.ts","turbopack:///[project]/node_modules/.pnpm/next@15.3.4_react-dom@19.1.0_react@19.1.0__react@19.1.0/node_modules/next/dist/src/build/templates/app-route.ts"],"sourcesContent":["import { readFile, writeFile, access, constants, rename } from 'fs/promises';\nimport type { ProjectsConfig } from './workspace-types';\nimport { PROJECT_CONFIG_PATH } from './workspace-types';\n\n/**\n * 读取并解析项目配置文件\n * @returns {Promise<ProjectsConfig>} 项目配置对象\n */\nexport async function getProjectsConfig(): Promise<ProjectsConfig> {\n try {\n await access(PROJECT_CONFIG_PATH, constants.F_OK);\n } catch {\n // 文件不存在,创建并写入空对象\n await saveProjectsConfig({});\n return {};\n }\n\n try {\n const configContent = await readFile(PROJECT_CONFIG_PATH, 'utf-8');\n // 如果文件为空,返回空对象\n if (!configContent) {\n return {};\n }\n return JSON.parse(configContent);\n } catch (error) {\n console.error('读取或解析项目配置文件失败:', error);\n // 在出错时返回空对象或抛出错误,这里选择抛出以通知调用者\n throw new Error('无法加载项目配置');\n }\n}\n\n/**\n * 将项目配置写入文件(原子操作)\n * @param {ProjectsConfig} config - 要保存的配置对象\n */\nexport async function saveProjectsConfig(config: ProjectsConfig): Promise<void> {\n const tempConfigPath = PROJECT_CONFIG_PATH + '.tmp';\n try {\n await writeFile(tempConfigPath, JSON.stringify(config, null, 2), 'utf-8');\n await rename(tempConfigPath, PROJECT_CONFIG_PATH);\n } catch (error) {\n console.error('保存项目配置文件失败:', error);\n throw new Error('无法保存项目配置');\n }\n}\n\n/**\n * 项目状态枚举\n */\nexport enum ProjectStatus {\n PENDING = 'pending',\n EXISTING = 'existing',\n CLONING = 'cloning',\n SUCCESS = 'success',\n FAILED = 'failed',\n RETRYING = 'retrying',\n}\n\n/**\n * 项目进度信息接口\n */\nexport interface ProjectProgress {\n projectName: string;\n status: ProjectStatus;\n progress: number; // 0-100\n message: string;\n error?: string;\n startTime?: number;\n endTime?: number;\n}\n\n/**\n * 初始化结果接口\n */\nexport interface InitializationResult {\n success: boolean;\n totalProjects: number;\n successCount: number;\n failedCount: number;\n failedProjects: string[];\n workspacePath: string;\n duration: number;\n}\n\n/**\n * Git 操作配置接口\n */\nexport interface GitOperationConfig {\n repoUrl: string;\n targetDir: string;\n timeout: number;\n onProgress?: (progress: number, message: string) => void;\n onError?: (error: string) => void;\n}","import { homedir, cpus } from 'os';\nimport { join } from 'path';\n\n/**\n * 工作空间配置常量\n */\nexport const WORKSPACE_CONFIG = {\n // 工作空间根目录路径\n WORKSPACE_ROOT: join(homedir(), 'Documents', 'prime-workspace'),\n\n // Git 操作超时时间 (毫秒)\n GIT_TIMEOUT: 300000, // 5分钟\n\n // 最大并发克隆数量(基于CPU核心数,最小2个,最大8个)\n MAX_CONCURRENT_CLONES: Math.max(2, Math.min(cpus().length, 8)),\n\n // 重试次数限制\n MAX_RETRY_ATTEMPTS: 3,\n} as const;\n\nexport const PROJECT_CONFIG_PATH = join(homedir(), '.prime-projects.json');\n\nexport interface ProjectConfig {\n repo: string;\n mockingIntercept?: boolean;\n mockOpen?: boolean;\n envs: {\n [envName: string]: {\n host: string;\n currentProxy: string;\n proxyEnv: {\n [key: string]: string;\n };\n envFileName: string;\n proxyKey: string;\n subApps?: string[];\n };\n };\n}\n\nexport interface ProjectsConfig {\n [projectName: string]: ProjectConfig;\n}\n\n/**\n * 项目状态枚举\n */\nexport enum ProjectStatus {\n PENDING = 'pending',\n EXISTING = 'existing',\n CLONING = 'cloning',\n SUCCESS = 'success',\n FAILED = 'failed',\n RETRYING = 'retrying',\n INCOMPLETE = 'incomplete', // 不完整的项目,需要清理\n}\n\n/**\n * 项目进度信息接口\n */\nexport interface ProjectProgress {\n projectName: string;\n status: ProjectStatus;\n progress: number; // 0-100\n message: string;\n error?: string;\n startTime?: number;\n endTime?: number;\n}\n\n/**\n * 初始化结果接口\n */\nexport interface InitializationResult {\n success: boolean;\n totalProjects: number;\n successCount: number;\n failedCount: number;\n failedProjects: string[];\n workspacePath: string;\n duration: number;\n}\n\n/**\n * Git 操作配置接口\n */\nexport interface GitOperationConfig {\n repoUrl: string;\n targetDir: string;\n timeout: number;\n onProgress?: (progress: number, message: string) => void;\n onError?: (error: string) => void;\n onLog?: (projectName: string, logType: 'stdout' | 'stderr' | 'progress', content: string) => void;\n} ","import { NextRequest, NextResponse } from 'next/server';\nimport { promises as fs } from 'fs';\nimport { join, resolve } from 'path';\nimport { getProjectsConfig } from '@/lib/workspace-config';\nimport { WORKSPACE_CONFIG } from '@/lib/workspace-types';\nimport { createRequire } from \"module\";\nconst require = createRequire(import.meta.url);\n\nexport async function PUT(request: NextRequest) {\n try {\n // 解析请求体\n const { projectName, apiName, method, siteName, isOpen } = await request.json();\n\n // 参数验证\n if (!projectName || !apiName || !method || !siteName || typeof isOpen !== 'boolean') {\n return NextResponse.json(\n {\n success: false,\n error: '缺少必要参数:projectName, apiName, method, siteName, isOpen',\n },\n { status: 400 },\n );\n }\n\n // 验证项目是否存在\n const projectsConfig = await getProjectsConfig();\n if (!projectsConfig[projectName]) {\n return NextResponse.json(\n { success: false, error: `项目 ${projectName} 不存在` },\n { status: 404 },\n );\n }\n\n // 构建setting.js文件路径\n const projectPath = join(WORKSPACE_CONFIG.WORKSPACE_ROOT, projectName);\n const settingFilePath = join(projectPath, '.mock', apiName, method.toLowerCase(), 'setting.js');\n\n // 检查setting.js文件是否存在\n try {\n await fs.access(settingFilePath);\n } catch {\n return NextResponse.json(\n { success: false, error: 'setting.js文件不存在' },\n { status: 404 },\n );\n }\n\n // 使用require直接导入setting.js\n let currentConfig: { \n currentSite?: string; \n open?: string[];\n [key: string]: unknown \n } = {};\n \n try {\n const resolvedPath = resolve(settingFilePath);\n delete require.cache[resolvedPath];\n \n currentConfig = require(resolvedPath);\n } catch (parseError) {\n console.warn(`解析setting.js失败: ${settingFilePath}`, parseError);\n }\n\n // 确保open数组存在\n if (!Array.isArray(currentConfig.open)) {\n currentConfig.open = [];\n }\n\n // 更新open数组\n const openArray = currentConfig.open;\n const siteIndex = openArray.indexOf(siteName);\n \n if (isOpen) {\n // 开启Mock:如果场景不在数组中,则添加\n if (siteIndex === -1) {\n openArray.push(siteName);\n }\n } else {\n // 关闭Mock:如果场景在数组中,则移除\n if (siteIndex !== -1) {\n openArray.splice(siteIndex, 1);\n }\n }\n\n // 生成新的文件内容\n const newContent = `module.exports = {\n // 当前场景名称\n currentSite: '${currentConfig.currentSite || siteName}',\n // 开启Mock的场景列表\n open: ${JSON.stringify(openArray)}\n};`;\n\n // 写入文件\n await fs.writeFile(settingFilePath, newContent, 'utf-8');\n\n return NextResponse.json({\n success: true,\n message: 'Mock开启状态更新成功',\n data: {\n projectName,\n apiName,\n method: method.toLowerCase(),\n siteName,\n isOpen,\n openSites: openArray,\n filePath: join('.mock', apiName, method.toLowerCase(), 'setting.js'),\n updatedAt: new Date().toISOString(),\n },\n });\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : '更新Mock开启状态失败';\n console.error('更新Mock开启状态失败:', error);\n return NextResponse.json(\n { success: false, error: errorMessage },\n { status: 500 },\n );\n }\n} ","import {\n AppRouteRouteModule,\n type AppRouteRouteModuleOptions,\n} from '../../server/route-modules/app-route/module.compiled'\nimport { RouteKind } from '../../server/route-kind'\nimport { patchFetch as _patchFetch } from '../../server/lib/patch-fetch'\n\nimport * as userland from 'VAR_USERLAND'\n\n// These are injected by the loader afterwards. This is injected as a variable\n// instead of a replacement because this could also be `undefined` instead of\n// an empty string.\ndeclare const nextConfigOutput: AppRouteRouteModuleOptions['nextConfigOutput']\n\n// We inject the nextConfigOutput here so that we can use them in the route\n// module.\n// INJECT:nextConfigOutput\n\nconst routeModule = new AppRouteRouteModule({\n definition: {\n kind: RouteKind.APP_ROUTE,\n page: 'VAR_DEFINITION_PAGE',\n pathname: 'VAR_DEFINITION_PATHNAME',\n filename: 'VAR_DEFINITION_FILENAME',\n bundlePath: 'VAR_DEFINITION_BUNDLE_PATH',\n },\n resolvedPagePath: 'VAR_RESOLVED_PAGE_PATH',\n nextConfigOutput,\n userland,\n})\n\n// Pull out the exports that we need to expose from the module. This should\n// be eliminated when we've moved the other routes to the new format. These\n// are used to hook into the route.\nconst { workAsyncStorage, workUnitAsyncStorage, serverHooks } = routeModule\n\nfunction patchFetch() {\n return _patchFetch({\n workAsyncStorage,\n workUnitAsyncStorage,\n })\n}\n\nexport {\n routeModule,\n workAsyncStorage,\n workUnitAsyncStorage,\n serverHooks,\n patchFetch,\n}\n"],"names":["AppRouteRouteModule","RouteKind","patchFetch","_patchFetch","userland","routeModule","definition","kind","APP_ROUTE","page","pathname","filename","bundlePath","resolvedPagePath","nextConfigOutput","workAsyncStorage","workUnitAsyncStorage","serverHooks"],"mappings":"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","ignoreList":[3]}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
module.exports={83886:function(e){var{g:t,__dirname:r,m:o,e:s}=e;o.exports=e.x("fs",()=>require("fs"))},45935:function(e){var{g:t,__dirname:r,m:o,e:s}=e;o.exports=e.x("next/dist/server/app-render/after-task-async-storage.external.js",()=>require("next/dist/server/app-render/after-task-async-storage.external.js"))},35692:e=>{"use strict";var{g:t,__dirname:r}=e;e.s({ProjectStatus:()=>c,getProjectsConfig:()=>n,saveProjectsConfig:()=>i});var o=e.i(9892),s=e.i(88941);async function n(){try{await (0,o.access)(s.PROJECT_CONFIG_PATH,o.constants.F_OK)}catch{return await i({}),{}}try{let e=await (0,o.readFile)(s.PROJECT_CONFIG_PATH,"utf-8");if(!e)return{};return JSON.parse(e)}catch(e){throw console.error("读取或解析项目配置文件失败:",e),Error("无法加载项目配置")}}async function i(e){let t=s.PROJECT_CONFIG_PATH+".tmp";try{await (0,o.writeFile)(t,JSON.stringify(e,null,2),"utf-8"),await (0,o.rename)(t,s.PROJECT_CONFIG_PATH)}catch(e){throw console.error("保存项目配置文件失败:",e),Error("无法保存项目配置")}}var c=function(e){return e.PENDING="pending",e.EXISTING="existing",e.CLONING="cloning",e.SUCCESS="success",e.FAILED="failed",e.RETRYING="retrying",e}({})},88941:e=>{"use strict";var{g:t,__dirname:r}=e;{e.s({PROJECT_CONFIG_PATH:()=>r,ProjectStatus:()=>n,WORKSPACE_CONFIG:()=>t});var o=e.i(13442),s=e.i(30331);let t={WORKSPACE_ROOT:(0,s.join)((0,o.homedir)(),"Documents","prime-workspace"),GIT_TIMEOUT:3e5,MAX_CONCURRENT_CLONES:Math.max(2,Math.min((0,o.cpus)().length,8)),MAX_RETRY_ATTEMPTS:3},r=(0,s.join)((0,o.homedir)(),".prime-projects.json");var n=function(e){return e.PENDING="pending",e.EXISTING="existing",e.CLONING="cloning",e.SUCCESS="success",e.FAILED="failed",e.RETRYING="retrying",e.INCOMPLETE="incomplete",e}({})}},29549:function(e){var{g:t,__dirname:r,m:o,e:s}=e;o.exports=e.x("next/dist/compiled/next-server/app-page-turbo.runtime.prod.js",()=>require("next/dist/compiled/next-server/app-page-turbo.runtime.prod.js"))},83943:function(e){var{g:t,__dirname:r,m:o,e:s}=e;o.exports=e.x("next/dist/server/app-render/work-unit-async-storage.external.js",()=>require("next/dist/server/app-render/work-unit-async-storage.external.js"))},86103:function(e){var{g:t,__dirname:r,m:o,e:s}=e;o.exports=e.x("next/dist/server/app-render/work-async-storage.external.js",()=>require("next/dist/server/app-render/work-async-storage.external.js"))},30331:function(e){var{g:t,__dirname:r,m:o,e:s}=e;o.exports=e.x("path",()=>require("path"))},23430:function(e){var{g:t,__dirname:r,m:o,e:s}=e;o.exports=e.x("next/dist/compiled/@opentelemetry/api",()=>require("next/dist/compiled/@opentelemetry/api"))},13442:function(e){var{g:t,__dirname:r,m:o,e:s}=e;o.exports=e.x("os",()=>require("os"))},52670:function(e){var{g:t,__dirname:r,m:o,e:s}=e;o.exports=e.x("next/dist/compiled/next-server/app-route-turbo.runtime.prod.js",()=>require("next/dist/compiled/next-server/app-route-turbo.runtime.prod.js"))},9892:function(e){var{g:t,__dirname:r,m:o,e:s}=e;o.exports=e.x("fs/promises",()=>require("fs/promises"))},15079:e=>{"use strict";var{g:t,__dirname:r}=e;e.s({createProjectEnvFiles:()=>n,createProjectMockDirectories:()=>i,updateProjectEnvFile:()=>c});var o=e.i(83886),s=e.i(30331);async function n(e,t,r){let n=(0,s.join)(r,e),i=[],c=[];try{let e=t.envs||{};for(let t in e){let r=e[t];if(r.envFileName&&r.proxyKey){let e=(0,s.join)(n,r.envFileName);try{await o.promises.access(e),c.push(r.envFileName)}catch{let t=r.proxyEnv[r.currentProxy]||"",s=`${r.proxyKey}=${t}`;await o.promises.writeFile(e,s,"utf-8"),i.push(r.envFileName)}}}return{success:!0,createdFiles:i,skippedFiles:c}}catch(r){let t=r instanceof Error?r.message:String(r);return console.error(`在为项目 ${e} 创建环境文件时出错:`,r),{success:!1,createdFiles:i,skippedFiles:c,error:t}}}async function i(e,t){let r=(0,s.join)(t,e),n=(0,s.join)(r,".mock"),i=[],c=[];try{try{await o.promises.access(n),c.push(".mock")}catch{await o.promises.mkdir(n,{recursive:!0}),i.push(".mock")}return{success:!0,createdDirectories:i,skippedDirectories:c}}catch(r){let t=r instanceof Error?r.message:String(r);return console.error(`在为项目 ${e} 创建Mock目录时出错:`,r),{success:!1,createdDirectories:i,skippedDirectories:c,error:t}}}async function c(e,t,r,n){try{let i=r.envs[t];if(!i)return{success:!1,error:`环境 ${t} 不存在于项目 ${e} 配置中`};if(!i.envFileName||!i.proxyKey)return{success:!1,error:`环境 ${t} 缺少 envFileName 或 proxyKey 配置`};let c=(0,s.join)(n,e),a=(0,s.join)(c,i.envFileName),l=i.proxyEnv[i.currentProxy]||i.currentProxy,p=`${i.proxyKey}=${l}`;return await o.promises.writeFile(a,p,"utf-8"),console.log(`已更新环境文件: ${a}, 内容: ${p}`),{success:!0,updatedFile:i.envFileName}}catch(o){let r=o instanceof Error?o.message:String(o);return console.error(`更新项目 ${e} 环境 ${t} 的环境文件时出错:`,o),{success:!1,error:r}}}},94722:e=>{"use strict";var{g:t,__dirname:r}=e;{e.s({sseConnectionManager:()=>r});class t{connections=new Map;encoder=new TextEncoder;heartbeatInterval=null;HEARTBEAT_INTERVAL=3e4;CONNECTION_TIMEOUT=12e4;constructor(){this.startHeartbeat()}addConnection(e,t,r){console.log(`[SSE] 添加连接: 环境=${e}, 客户端=${r}`);let o={controller:t,timestamp:Date.now(),clientId:r,envName:e};this.connections.has(e)||this.connections.set(e,new Set),this.connections.get(e).add(o),this.sendToConnection(o,{type:"heartbeat",timestamp:Date.now()}),console.log(`[SSE] 当前连接统计: ${this.getConnectionStats()}`)}removeConnection(e,t){console.log(`[SSE] 移除连接: 环境=${e}, 客户端=${t}`);let r=this.connections.get(e);if(r){let o=Array.from(r).find(e=>e.clientId===t);o&&(r.delete(o),0===r.size&&this.connections.delete(e))}console.log(`[SSE] 当前连接统计: ${this.getConnectionStats()}`)}broadcastToEnv(e,t){console.log(`[SSE] 向环境 ${e} 广播配置变化消息`);let r=this.connections.get(e);if(!r||0===r.size)return void console.log(`[SSE] 环境 ${e} 没有活跃连接,跳过广播`);let o=[];r.forEach(e=>{try{this.sendToConnection(e,t)}catch(t){console.error(`[SSE] 发送消息到客户端 ${e.clientId} 失败:`,t),o.push(e)}}),o.forEach(e=>{r.delete(e),console.log(`[SSE] 清理无效连接: 客户端=${e.clientId}`)}),console.log(`[SSE] 成功发送给 ${r.size} 个连接`)}sendToConnection(e,t){let r=`data: ${JSON.stringify(t)}
|
|
2
|
+
|
|
3
|
+
`,o=this.encoder.encode(r);try{e.controller.enqueue(o),e.timestamp=Date.now()}catch(e){throw console.error(`[SSE] 发送消息失败:`,e),e}}startHeartbeat(){this.heartbeatInterval=setInterval(()=>{this.sendHeartbeat(),this.cleanupStaleConnections()},this.HEARTBEAT_INTERVAL),console.log(`[SSE] 心跳机制已启动,间隔: ${this.HEARTBEAT_INTERVAL}ms`)}sendHeartbeat(){let e={type:"heartbeat",timestamp:Date.now()},t=0;this.connections.forEach(r=>{t+=r.size;let o=[];r.forEach(t=>{try{this.sendToConnection(t,e)}catch{o.push(t)}}),o.forEach(e=>r.delete(e))}),t>0&&console.log(`[SSE] 心跳发送完成,活跃连接数: ${t}`)}cleanupStaleConnections(){let e=Date.now(),t=0;this.connections.forEach((r,o)=>{let s=[];r.forEach(t=>{e-t.timestamp>this.CONNECTION_TIMEOUT&&s.push(t)}),s.forEach(e=>{r.delete(e),t++,console.log(`[SSE] 清理过期连接: 环境=${o}, 客户端=${e.clientId}`)}),0===r.size&&this.connections.delete(o)}),t>0&&console.log(`[SSE] 连接清理完成,清理数量: ${t}`)}getConnectionStats(){let e=[],t=0;return this.connections.forEach((r,o)=>{let s=r.size;t+=s,e.push(`${o}: ${s}`)}),`总计 ${t} 个连接 (${e.join(", ")})`}stop(){this.heartbeatInterval&&(clearInterval(this.heartbeatInterval),this.heartbeatInterval=null,console.log(`[SSE] 心跳机制已停止`)),this.connections.forEach(e=>{e.forEach(e=>{try{e.controller.close()}catch(e){console.error(`[SSE] 关闭连接失败:`,e)}})}),this.connections.clear(),console.log(`[SSE] 所有连接已关闭`)}}let r=new t;process.on("SIGINT",()=>{console.log("[SSE] 收到退出信号,正在清理连接..."),r.stop(),process.exit(0)}),process.on("SIGTERM",()=>{console.log("[SSE] 收到终止信号,正在清理连接..."),r.stop(),process.exit(0)})}},57606:function(e){var{g:t,__dirname:r,m:o,e:s}=e},67375:e=>{"use strict";var{g:t,__dirname:r}=e;e.s({PUT:()=>a});var o=e.i(15494),s=e.i(35692),n=e.i(15079),i=e.i(88941),c=e.i(94722);async function a(e){try{let{envName:t,projectName:r,selectedItems:a}=await e.json();if(!t||!r||!Array.isArray(a))return o.NextResponse.json({success:!1,error:"缺少必要参数:envName, projectName, selectedItems"},{status:400});let l=await (0,s.getProjectsConfig)();if(!l[r])return o.NextResponse.json({success:!1,error:`项目 ${r} 不存在`},{status:404});if(!l[r].envs[t])return o.NextResponse.json({success:!1,error:`项目 ${r} 中不存在环境 ${t}`},{status:404});let p=l[r].envs[t].host,u=l[r].envs[t].subApps||[];l[r].envs[t].subApps=a;let g=[];if(a.forEach(e=>{Object.keys(l).forEach(t=>{if(l[t].envs[e]){let r=l[t].envs[e];r.currentProxy="custom",r.proxyEnv.custom=p,g.push({projectName:t,envName:e})}})}),await (0,s.saveProjectsConfig)(l),JSON.stringify(u.sort())!==JSON.stringify(a.sort())){console.log(`[配置变化] 环境 ${t} 的 MicroApp 代理配置发生变化`),console.log(`[配置变化] 变化前: ${JSON.stringify(u)}`),console.log(`[配置变化] 变化后: ${JSON.stringify(a)}`);let e=new Set(u),o=new Set(a),s=a.filter(t=>!e.has(t)),n=u.filter(e=>!o.has(e)),i={type:"microapp-proxy-config-change",envName:t,timestamp:Date.now(),changes:{before:u,after:a,added:s,removed:n},projectName:r,message:`环境 ${t} 的 MicroApp 代理配置已更新`};try{c.sseConnectionManager.broadcastToEnv(t,i),console.log(`[推送成功] 已向环境 ${t} 推送配置变化通知`)}catch(e){console.error(`[推送失败] 向环境 ${t} 推送通知失败:`,e)}}else console.log(`[配置未变化] 环境 ${t} 的 MicroApp 代理配置无变化,跳过推送`);let h=(await Promise.allSettled(g.map(async({projectName:e,envName:t})=>(0,n.updateProjectEnvFile)(e,t,l[e],i.WORKSPACE_CONFIG.WORKSPACE_ROOT)))).map((e,t)=>({result:e,project:g[t]})).filter(({result:e})=>"rejected"===e.status||"fulfilled"===e.status&&!e.value.success),m="MicroApp代理配置保存成功,已更新选中环境的代理地址";return h.length>0&&(m+=`,但有 ${h.length} 个环境文件更新失败`),o.NextResponse.json({success:!0,message:m,data:{projectName:r,envName:t,subApps:a,currentHost:p,updatedProjects:g.length,envFileUpdateFailures:h.length}})}catch(t){let e=t instanceof Error?t.message:"保存MicroApp代理配置失败";return console.error("保存MicroApp代理配置失败:",t),o.NextResponse.json({success:!1,error:e},{status:500})}}},30280:e=>{"use strict";var{g:t,__dirname:r}=e;{e.s({patchFetch:()=>c,routeModule:()=>t,serverHooks:()=>l,workAsyncStorage:()=>r,workUnitAsyncStorage:()=>a});var o=e.i(45746),s=e.i(93828),n=e.i(18250),i=e.i(67375);let t=new o.AppRouteRouteModule({definition:{kind:s.RouteKind.APP_ROUTE,page:"/api/microapp-proxy-config/route",pathname:"/api/microapp-proxy-config",filename:"route",bundlePath:""},resolvedPagePath:"[project]/packages/server/src/app/api/microapp-proxy-config/route.ts",nextConfigOutput:"",userland:i}),{workAsyncStorage:r,workUnitAsyncStorage:a,serverHooks:l}=t;function c(){return(0,n.patchFetch)({workAsyncStorage:r,workUnitAsyncStorage:a})}}}};
|
|
4
|
+
|
|
5
|
+
//# sourceMappingURL=%5Broot-of-the-server%5D__92625851._.js.map
|