prime-dev-cli 1.0.11-beta.2 → 1.0.12-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/server/.next/BUILD_ID +1 -1
- package/dist/server/.next/app-build-manifest.json +5 -5
- package/dist/server/.next/app-path-routes-manifest.json +1 -0
- package/dist/server/.next/build-manifest.json +6 -6
- package/dist/server/.next/cache/.tsbuildinfo +1 -1
- package/dist/server/.next/cache/eslint/.cache_1qa5vxt +1 -1
- package/dist/server/.next/fallback-build-manifest.json +6 -6
- 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 +9 -9
- package/dist/server/.next/server/app/_not-found/page/app-build-manifest.json +1 -1
- package/dist/server/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/dist/server/.next/server/app/_not-found.html +1 -1
- package/dist/server/.next/server/app/_not-found.rsc +2 -2
- package/dist/server/.next/server/app/api/all-projects-envs/route.js +1 -1
- package/dist/server/.next/server/app/api/all-projects-envs/route.js.nft.json +1 -1
- package/dist/server/.next/server/app/api/check-mock-intercept/route.js +1 -1
- package/dist/server/.next/server/app/api/check-mock-intercept/route.js.nft.json +1 -1
- package/dist/server/.next/server/app/api/check-workspace/route.js +1 -1
- package/dist/server/.next/server/app/api/check-workspace/route.js.nft.json +1 -1
- package/dist/server/.next/server/app/api/cleanup-mock/route.js +1 -1
- package/dist/server/.next/server/app/api/cleanup-mock/route.js.nft.json +1 -1
- package/dist/server/.next/server/app/api/current-branch/route/app-build-manifest.json +11 -0
- package/dist/server/.next/server/app/api/current-branch/route/app-paths-manifest.json +3 -0
- package/dist/server/.next/server/app/api/current-branch/route/build-manifest.json +17 -0
- package/dist/server/.next/server/app/api/current-branch/route/next-font-manifest.json +6 -0
- package/dist/server/.next/server/app/api/current-branch/route/react-loadable-manifest.json +1 -0
- package/dist/server/.next/server/app/api/current-branch/route/server-reference-manifest.json +4 -0
- package/dist/server/.next/server/app/api/current-branch/route.js +8 -0
- package/dist/server/.next/server/app/api/current-branch/route.js.map +5 -0
- package/dist/server/.next/server/app/api/current-branch/route.js.nft.json +1 -0
- package/dist/server/.next/server/app/api/current-branch/route_client-reference-manifest.js +2 -0
- package/dist/server/.next/server/app/api/delete-mock-api/route.js +1 -1
- package/dist/server/.next/server/app/api/delete-mock-api/route.js.nft.json +1 -1
- package/dist/server/.next/server/app/api/get-mock-data/route.js +1 -1
- package/dist/server/.next/server/app/api/get-mock-data/route.js.nft.json +1 -1
- package/dist/server/.next/server/app/api/initialize-workspace/route.js +1 -1
- package/dist/server/.next/server/app/api/initialize-workspace/route.js.nft.json +1 -1
- package/dist/server/.next/server/app/api/microapp-proxy-change-stream/route.js +1 -1
- 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-config/route.js +1 -1
- package/dist/server/.next/server/app/api/microapp-proxy-config/route.js.nft.json +1 -1
- package/dist/server/.next/server/app/api/mock-file/route.js +1 -1
- package/dist/server/.next/server/app/api/mock-file/route.js.nft.json +1 -1
- package/dist/server/.next/server/app/api/mock-file-content/route.js +1 -1
- package/dist/server/.next/server/app/api/mock-file-content/route.js.nft.json +1 -1
- package/dist/server/.next/server/app/api/mock-open-status/route.js +1 -1
- package/dist/server/.next/server/app/api/mock-open-status/route.js.nft.json +1 -1
- package/dist/server/.next/server/app/api/mock-setting/route.js +1 -1
- package/dist/server/.next/server/app/api/mock-setting/route.js.nft.json +1 -1
- package/dist/server/.next/server/app/api/open-all-mock/route.js +1 -1
- package/dist/server/.next/server/app/api/open-all-mock/route.js.nft.json +1 -1
- package/dist/server/.next/server/app/api/process/start/route.js +1 -1
- package/dist/server/.next/server/app/api/process/start/route.js.nft.json +1 -1
- package/dist/server/.next/server/app/api/process/status/route.js +1 -1
- package/dist/server/.next/server/app/api/process/status/route.js.nft.json +1 -1
- package/dist/server/.next/server/app/api/project-config/route.js +1 -1
- package/dist/server/.next/server/app/api/project-config/route.js.nft.json +1 -1
- package/dist/server/.next/server/app/api/retry-project/route.js +1 -1
- package/dist/server/.next/server/app/api/retry-project/route.js.nft.json +1 -1
- package/dist/server/.next/server/app/configuration/page/app-build-manifest.json +2 -2
- 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 +1 -1
- package/dist/server/.next/server/app/configuration.html +1 -1
- package/dist/server/.next/server/app/configuration.rsc +3 -3
- package/dist/server/.next/server/app/index.html +1 -1
- package/dist/server/.next/server/app/index.rsc +2 -2
- package/dist/server/.next/server/app/initialization/page/app-build-manifest.json +1 -1
- package/dist/server/.next/server/app/initialization/page_client-reference-manifest.js +1 -1
- package/dist/server/.next/server/app/initialization.html +1 -1
- package/dist/server/.next/server/app/initialization.rsc +2 -2
- package/dist/server/.next/server/app/page/app-build-manifest.json +1 -1
- package/dist/server/.next/server/app/page_client-reference-manifest.js +1 -1
- package/dist/server/.next/server/app-paths-manifest.json +1 -0
- package/dist/server/.next/server/chunks/{[root-of-the-server]__27f3b464._.js → [root-of-the-server]__07de450e._.js} +2 -2
- package/dist/server/.next/server/chunks/{[root-of-the-server]__27f3b464._.js.map → [root-of-the-server]__07de450e._.js.map} +1 -1
- package/dist/server/.next/server/chunks/{[root-of-the-server]__ec631eb4._.js → [root-of-the-server]__09808308._.js} +2 -2
- package/dist/server/.next/server/chunks/{[root-of-the-server]__ec631eb4._.js.map → [root-of-the-server]__09808308._.js.map} +1 -1
- package/dist/server/.next/server/chunks/{[root-of-the-server]__dfe36c1a._.js → [root-of-the-server]__09914a79._.js} +2 -2
- package/dist/server/.next/server/chunks/{[root-of-the-server]__dfe36c1a._.js.map → [root-of-the-server]__09914a79._.js.map} +1 -1
- package/dist/server/.next/server/chunks/{[root-of-the-server]__c513ec4a._.js → [root-of-the-server]__42bc7b42._.js} +2 -2
- package/dist/server/.next/server/chunks/{[root-of-the-server]__c513ec4a._.js.map → [root-of-the-server]__42bc7b42._.js.map} +1 -1
- package/dist/server/.next/server/chunks/{[root-of-the-server]__b68e0025._.js → [root-of-the-server]__4dc677cb._.js} +2 -2
- package/dist/server/.next/server/chunks/{[root-of-the-server]__b68e0025._.js.map → [root-of-the-server]__4dc677cb._.js.map} +1 -1
- package/dist/server/.next/server/chunks/{[root-of-the-server]__92625851._.js → [root-of-the-server]__52d487d8._.js} +2 -2
- package/dist/server/.next/server/chunks/{[root-of-the-server]__92625851._.js.map → [root-of-the-server]__52d487d8._.js.map} +1 -1
- package/dist/server/.next/server/chunks/{[root-of-the-server]__7a46f739._.js → [root-of-the-server]__582946e6._.js} +2 -2
- package/dist/server/.next/server/chunks/{[root-of-the-server]__7a46f739._.js.map → [root-of-the-server]__582946e6._.js.map} +1 -1
- package/dist/server/.next/server/chunks/{[root-of-the-server]__0111ac14._.js → [root-of-the-server]__5cddc64c._.js} +2 -2
- package/dist/server/.next/server/chunks/{[root-of-the-server]__0111ac14._.js.map → [root-of-the-server]__5cddc64c._.js.map} +1 -1
- package/dist/server/.next/server/chunks/{[root-of-the-server]__63462bcb._.js → [root-of-the-server]__802aba2d._.js} +2 -2
- package/dist/server/.next/server/chunks/{[root-of-the-server]__63462bcb._.js.map → [root-of-the-server]__802aba2d._.js.map} +1 -1
- package/dist/server/.next/server/chunks/{[root-of-the-server]__9544d1f9._.js → [root-of-the-server]__837d58ae._.js} +2 -2
- package/dist/server/.next/server/chunks/{[root-of-the-server]__9544d1f9._.js.map → [root-of-the-server]__837d58ae._.js.map} +1 -1
- package/dist/server/.next/server/chunks/{[root-of-the-server]__c43c9880._.js → [root-of-the-server]__933f7077._.js} +2 -2
- package/dist/server/.next/server/chunks/{[root-of-the-server]__c43c9880._.js.map → [root-of-the-server]__933f7077._.js.map} +1 -1
- package/dist/server/.next/server/chunks/[root-of-the-server]__94e10604._.js +3 -0
- package/dist/server/.next/server/chunks/[root-of-the-server]__94e10604._.js.map +1 -0
- package/dist/server/.next/server/chunks/{[root-of-the-server]__84542811._.js → [root-of-the-server]__a6211ee0._.js} +2 -2
- package/dist/server/.next/server/chunks/{[root-of-the-server]__84542811._.js.map → [root-of-the-server]__a6211ee0._.js.map} +1 -1
- package/dist/server/.next/server/chunks/{[root-of-the-server]__29969c0b._.js → [root-of-the-server]__aca25fcf._.js} +2 -2
- package/dist/server/.next/server/chunks/{[root-of-the-server]__29969c0b._.js.map → [root-of-the-server]__aca25fcf._.js.map} +1 -1
- package/dist/server/.next/server/chunks/{[root-of-the-server]__3da8edfd._.js → [root-of-the-server]__be3de126._.js} +2 -2
- package/dist/server/.next/server/chunks/{[root-of-the-server]__3da8edfd._.js.map → [root-of-the-server]__be3de126._.js.map} +1 -1
- package/dist/server/.next/server/chunks/{[root-of-the-server]__fab72f0c._.js → [root-of-the-server]__da89e112._.js} +2 -2
- package/dist/server/.next/server/chunks/{[root-of-the-server]__fab72f0c._.js.map → [root-of-the-server]__da89e112._.js.map} +1 -1
- package/dist/server/.next/server/chunks/[root-of-the-server]__e07d75ff._.js +3 -0
- package/dist/server/.next/server/chunks/[root-of-the-server]__e07d75ff._.js.map +1 -0
- package/dist/server/.next/server/chunks/{[root-of-the-server]__1efea51d._.js → [root-of-the-server]__e301c560._.js} +2 -2
- package/dist/server/.next/server/chunks/{[root-of-the-server]__1efea51d._.js.map → [root-of-the-server]__e301c560._.js.map} +1 -1
- package/dist/server/.next/server/chunks/{[root-of-the-server]__525f44e0._.js → [root-of-the-server]__ef09a48e._.js} +2 -2
- package/dist/server/.next/server/chunks/{[root-of-the-server]__525f44e0._.js.map → [root-of-the-server]__ef09a48e._.js.map} +1 -1
- package/dist/server/.next/server/chunks/ssr/{_2488faea._.js → _bb352729._.js} +3 -3
- package/dist/server/.next/server/chunks/ssr/_bb352729._.js.map +1 -0
- package/dist/server/.next/server/middleware-build-manifest.js +4 -4
- 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 +2 -2
- package/dist/server/.next/server/pages/_error/build-manifest.json +2 -2
- package/dist/server/.next/static/chunks/{d5028315079b40b4.js → 2befba13bed43c5f.js} +1 -1
- package/dist/server/.next/static/chunks/344b0062191ace22.css.map +1 -0
- package/dist/server/.next/static/chunks/{249486689b72c55c.js → 4cbec079b6e3e189.js} +2 -2
- package/dist/server/.next/static/chunks/6c91d5f280e79a14.css +3 -0
- package/dist/server/.next/static/chunks/700389bfed628512.js +61 -0
- package/dist/server/.next/static/chunks/8d4c1c4e33fc41f3.js.map +1 -0
- package/dist/server/.next/static/chunks/{5e9dc9d078da6e2d.js.map → a898634af0862944.js.map} +1 -1
- package/dist/server/.next/static/chunks/{8d6bbd36cdf03018.js → d74cc70dd8ef74c9.js} +1 -1
- package/dist/server/.next/static/chunks/pages/_app.js +2 -2
- package/dist/server/.next/static/chunks/pages/_error.js +2 -2
- package/dist/server/.next/trace +1 -1
- package/package.json +3 -2
- package/dist/server/.next/server/chunks/[root-of-the-server]__ec0f2f72._.js +0 -3
- package/dist/server/.next/server/chunks/[root-of-the-server]__ec0f2f72._.js.map +0 -1
- package/dist/server/.next/server/chunks/ssr/_2488faea._.js.map +0 -1
- package/dist/server/.next/static/chunks/1f1c09f06b1f73d5.css +0 -3
- package/dist/server/.next/static/chunks/4791e420776e4b33.js.map +0 -1
- package/dist/server/.next/static/chunks/76692beeeb707278.css.map +0 -1
- package/dist/server/.next/static/chunks/f99d8b48dbb26003.js +0 -61
- /package/dist/server/.next/static/{DiL7txnLfsR2XvLBEz06H → CockuVPN955YqCV3kRDYs}/_buildManifest.js +0 -0
- /package/dist/server/.next/static/{DiL7txnLfsR2XvLBEz06H → CockuVPN955YqCV3kRDYs}/_clientMiddlewareManifest.json +0 -0
- /package/dist/server/.next/static/{DiL7txnLfsR2XvLBEz06H → CockuVPN955YqCV3kRDYs}/_ssgManifest.js +0 -0
|
@@ -1 +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-setting/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, currentSite } = await request.json();\n\n // 参数验证\n if (!projectName || !apiName || !method || !currentSite) {\n return NextResponse.json(\n {\n success: false,\n error: '缺少必要参数:projectName, apiName, method, currentSite',\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.cjs文件路径\n const projectPath = join(WORKSPACE_CONFIG.WORKSPACE_ROOT, projectName);\n const settingFilePath = join(projectPath, '.mock', apiName, method.toLowerCase(), 'setting.cjs');\n\n // 检查setting.cjs文件是否存在\n try {\n await fs.access(settingFilePath);\n } catch {\n return NextResponse.json(\n { success: false, error: 'setting.cjs文件不存在' },\n { status: 404 },\n );\n }\n\n // 使用require直接导入setting.cjs\n let currentConfig: { currentSite?: string; [key: string]: unknown } = {};\n \n try {\n const resolvedPath = resolve(settingFilePath);\n delete require.cache[resolvedPath];\n currentConfig = require(resolvedPath);\n } catch (parseError) {\n console.warn(`解析setting.cjs失败: ${settingFilePath}`, parseError);\n }\n\n // 更新currentSite\n currentConfig.currentSite = currentSite;\n\n // 生成新的文件内容\n const newContent = `module.exports = ${JSON.stringify(currentConfig, null, 2).replace(/\"([^\"]+)\":/g, '$1:')};`;\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 currentSite,\n filePath: join('.mock', apiName, method.toLowerCase(), 'setting.cjs'),\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]}
|
|
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-setting/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, currentSite } = await request.json();\n\n // 参数验证\n if (!projectName || !apiName || !method || !currentSite) {\n return NextResponse.json(\n {\n success: false,\n error: '缺少必要参数:projectName, apiName, method, currentSite',\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.cjs文件路径\n const projectPath = join(WORKSPACE_CONFIG.WORKSPACE_ROOT, projectName);\n const settingFilePath = join(projectPath, '.mock', apiName, method.toLowerCase(), 'setting.cjs');\n\n // 检查setting.cjs文件是否存在\n try {\n await fs.access(settingFilePath);\n } catch {\n return NextResponse.json(\n { success: false, error: 'setting.cjs文件不存在' },\n { status: 404 },\n );\n }\n\n // 使用require直接导入setting.cjs\n let currentConfig: { currentSite?: string; [key: string]: unknown } = {};\n \n try {\n const resolvedPath = resolve(settingFilePath);\n delete require.cache[resolvedPath];\n currentConfig = require(resolvedPath);\n } catch (parseError) {\n console.warn(`解析setting.cjs失败: ${settingFilePath}`, parseError);\n }\n\n // 更新currentSite\n currentConfig.currentSite = currentSite;\n\n // 生成新的文件内容\n const newContent = `module.exports = ${JSON.stringify(currentConfig, null, 2).replace(/\"([^\"]+)\":/g, '$1:')};`;\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 currentSite,\n filePath: join('.mock', apiName, method.toLowerCase(), 'setting.cjs'),\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]}
|
|
@@ -1,3 +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"))},35692:e=>{"use strict";var{g:r,__dirname:t}=e;e.s({ProjectStatus:()=>a,getProjectsConfig:()=>o,saveProjectsConfig:()=>i});var n=e.i(9892),s=e.i(88941);async function o(){try{await (0,n.access)(s.PROJECT_CONFIG_PATH,n.constants.F_OK)}catch{return await i({}),{}}try{let e=await (0,n.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 r=s.PROJECT_CONFIG_PATH+".tmp";try{await (0,n.writeFile)(r,JSON.stringify(e,null,2),"utf-8"),await (0,n.rename)(r,s.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}({})},
|
|
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"))},35692:e=>{"use strict";var{g:r,__dirname:t}=e;e.s({ProjectStatus:()=>a,getProjectsConfig:()=>o,saveProjectsConfig:()=>i});var n=e.i(9892),s=e.i(88941);async function o(){try{await (0,n.access)(s.PROJECT_CONFIG_PATH,n.constants.F_OK)}catch{return await i({}),{}}try{let e=await (0,n.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 r=s.PROJECT_CONFIG_PATH+".tmp";try{await (0,n.writeFile)(r,JSON.stringify(e,null,2),"utf-8"),await (0,n.rename)(r,s.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}({})},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"))},30331:function(e){var{g:r,__dirname:t,m:n,e:s}=e;n.exports=e.x("path",()=>require("path"))},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"))},13442:function(e){var{g:r,__dirname:t,m:n,e:s}=e;n.exports=e.x("os",()=>require("os"))},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"))},88941:e=>{"use strict";var{g:r,__dirname:t}=e;{e.s({PROJECT_CONFIG_PATH:()=>t,ProjectStatus:()=>o,WORKSPACE_CONFIG:()=>r});var n=e.i(13442),s=e.i(30331);let r={WORKSPACE_ROOT:(0,s.join)((0,n.homedir)(),"Documents","prime-workspace"),GIT_TIMEOUT:3e5,MAX_CONCURRENT_CLONES:Math.max(2,Math.min((0,n.cpus)().length,8)),MAX_RETRY_ATTEMPTS:3},t=(0,s.join)((0,n.homedir)(),".prime-projects.json");var o=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}({})}},9892:function(e){var{g:r,__dirname:t,m:n,e:s}=e;n.exports=e.x("fs/promises",()=>require("fs/promises"))},76687:function(e){var{g:r,__dirname:t,m:n,e:s}=e},84038:e=>{"use strict";var{g:r,__dirname:t}=e;e.s({GET:()=>o});var n=e.i(15494),s=e.i(35692);async function o(e){try{let{searchParams:r}=new URL(e.url),t=r.get("project");if(!t)return n.NextResponse.json({success:!1,error:"项目名称参数缺失"},{status:400});let o=await (0,s.getProjectsConfig)();if(!o[t])return n.NextResponse.json({success:!1,error:`项目 ${t} 不存在`},{status:404});let i=o[t];return n.NextResponse.json({success:!0,data:{mockingIntercept:i.mockingIntercept||!1,mockOpen:i.mockOpen||!1}})}catch(r){let e=r instanceof Error?r.message:"获取Mock拦截状态失败";return console.error("获取Mock拦截状态失败:",r),n.NextResponse.json({success:!1,error:e},{status:500})}}},30449:e=>{"use strict";var{g:r,__dirname:t}=e;{e.s({patchFetch:()=>a,routeModule:()=>r,serverHooks:()=>p,workAsyncStorage:()=>t,workUnitAsyncStorage:()=>c});var n=e.i(45746),s=e.i(93828),o=e.i(18250),i=e.i(84038);let r=new n.AppRouteRouteModule({definition:{kind:s.RouteKind.APP_ROUTE,page:"/api/check-mock-intercept/route",pathname:"/api/check-mock-intercept",filename:"route",bundlePath:""},resolvedPagePath:"[project]/packages/server/src/app/api/check-mock-intercept/route.ts",nextConfigOutput:"",userland:i}),{workAsyncStorage:t,workUnitAsyncStorage:c,serverHooks:p}=r;function a(){return(0,o.patchFetch)({workAsyncStorage:t,workUnitAsyncStorage:c})}}}};
|
|
2
2
|
|
|
3
|
-
//# sourceMappingURL=%5Broot-of-the-server%
|
|
3
|
+
//# sourceMappingURL=%5Broot-of-the-server%5D__09808308._.js.map
|
|
@@ -1 +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/check-mock-intercept/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 { getProjectsConfig } from '@/lib/workspace-config';\n\nexport async function GET(request: NextRequest) {\n try {\n const { searchParams } = new URL(request.url);\n const projectName = searchParams.get('project');\n\n if (!projectName) {\n return NextResponse.json(\n { success: false, error: '项目名称参数缺失' },\n { status: 400 },\n );\n }\n\n // 读取项目配置文件\n const projectsConfig = await getProjectsConfig();\n\n // 检查项目是否存在\n if (!projectsConfig[projectName]) {\n return NextResponse.json(\n { success: false, error: `项目 ${projectName} 不存在` },\n { status: 404 },\n );\n }\n\n const projectConfig = projectsConfig[projectName];\n\n return NextResponse.json({\n success: true,\n data: {\n mockingIntercept: projectConfig.mockingIntercept || false,\n mockOpen: projectConfig.mockOpen || false,\n },\n });\n } catch (error) {\n const errorMessage =\n 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]}
|
|
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/check-mock-intercept/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 { getProjectsConfig } from '@/lib/workspace-config';\n\nexport async function GET(request: NextRequest) {\n try {\n const { searchParams } = new URL(request.url);\n const projectName = searchParams.get('project');\n\n if (!projectName) {\n return NextResponse.json(\n { success: false, error: '项目名称参数缺失' },\n { status: 400 },\n );\n }\n\n // 读取项目配置文件\n const projectsConfig = await getProjectsConfig();\n\n // 检查项目是否存在\n if (!projectsConfig[projectName]) {\n return NextResponse.json(\n { success: false, error: `项目 ${projectName} 不存在` },\n { status: 404 },\n );\n }\n\n const projectConfig = projectsConfig[projectName];\n\n return NextResponse.json({\n success: true,\n data: {\n mockingIntercept: projectConfig.mockingIntercept || false,\n mockOpen: projectConfig.mockOpen || false,\n },\n });\n } catch (error) {\n const errorMessage =\n 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]}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
module.exports={45935:function(e){var{g:t,__dirname:r,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"))},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}({})},
|
|
1
|
+
module.exports={45935:function(e){var{g:t,__dirname:r,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"))},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}({})},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"))},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}({})}},9892:function(e){var{g:t,__dirname:r,m:s,e:n}=e;s.exports=e.x("fs/promises",()=>require("fs/promises"))},87485:function(e){var{g:t,__dirname:r,m:s,e:n}=e;s.exports=e.x("child_process",()=>require("child_process"))},4713:function(e){var{g:t,__dirname:r,m:s,e:n}=e;s.exports=e.x("util",()=>require("util"))},30646:function(e){var{g:t,__dirname:r,m:s,e:n}=e},47814:e=>{"use strict";var{g:t,__dirname:r}=e;e.s({initializeProcessMonitoring:()=>p,loadAndCleanProcesses:()=>l});var s=e.i(9892),n=e.i(30331),i=e.i(13442),o=e.i(87485);function a(){return n.default.join(i.default.homedir(),".prime-processes.json")}async function c(e){try{return process.kill(e,0),!0}catch{return!1}}async function l(){try{let e=await s.default.readFile(a(),"utf-8"),t=JSON.parse(e),r=[];for(let e of t)await c(e.pid)&&r.push(e);return r.length!==t.length&&await s.default.writeFile(a(),JSON.stringify(r,null,2)),r}catch{return[]}}async function p(){console.log("初始化进程监控...");let e=await l();return console.log(`发现 ${e.length} 个正在运行的进程`),e}(0,e.i(4713).promisify)(o.exec)},91359:e=>{"use strict";var{g:t,__dirname:r}=e;{e.s({DELETE:()=>x,POST:()=>m});var s=e.i(15494),n=e.i(87485),i=e.i(30331),o=e.i(9892),a=e.i(13442),c=e.i(47814),l=e.i(35692),p=e.i(88941);let t=new Map;function u(e){return i.default.join(a.default.homedir(),".prime-process-logs",`${e}.log`)}async function d(e,t){let r=i.default.join(a.default.homedir(),".prime-process-logs"),s=u(e);try{await o.default.mkdir(r,{recursive:!0}),await o.default.writeFile(s,t.join("\n"),"utf-8")}catch(e){console.error("保存进程日志失败:",e)}}async function f(){let e=[];t.forEach((t,r)=>{e.push({key:r,projectName:t.projectName,envName:t.envName,startTime:t.startTime,port:t.port,pid:t.process.pid})});try{await o.default.writeFile(i.default.join(a.default.homedir(),".prime-processes.json"),JSON.stringify(e,null,2))}catch(e){console.error("保存进程信息失败:",e)}}let r=!1;async function g(){if(!r){for(let e of(await (0,c.loadAndCleanProcesses)())){let r=[];try{let t=u(e.key),s=await o.default.readFile(t,"utf-8");r.push(...s.split("\n").filter(e=>e.trim()))}catch{}t.set(e.key,{process:{pid:e.pid,killed:!1},projectName:e.projectName,envName:e.envName,startTime:new Date(e.startTime),port:e.port,logs:r,maxLogLines:1e3})}r=!0}}async function m(e){await g();try{let{projectName:r,envName:a,startCommand:c}=await e.json();if(!r||!a||!c)return s.NextResponse.json({success:!1,error:"缺少必要参数"},{status:400});let u=`${r}-${a}`;if(t.has(u)){let e=t.get(u);if(e&&e.process&&!e.process.killed)return s.NextResponse.json({success:!1,error:"该环境已经在运行中"},{status:400})}let g=await (0,l.getProjectsConfig)(),m=p.WORKSPACE_CONFIG.WORKSPACE_ROOT,x=i.default.join(m,r);try{await o.default.access(x)}catch{return s.NextResponse.json({success:!1,error:"项目目录不存在"},{status:404})}let[h,...w]=c.split(" "),v=(0,n.spawn)(h,w,{cwd:x,shell:!0,detached:!1,stdio:["ignore","pipe","pipe"],env:{...process.env,NODE_ENV:"development",FORCE_COLOR:"1"}}),N=g[r],j=N?.envs?.[a],y=j?.host?.split(":").pop()||"",E=[],O={process:{pid:v.pid||0,killed:!1,kill:()=>v.kill(),on:(e,t)=>{v.on(e,t)}},projectName:r,envName:a,startTime:new Date,port:y,logs:E,maxLogLines:1e3};t.set(u,O),v.stdout&&v.stdout.on("data",e=>{e.toString().split("\n").forEach(e=>{if(e.replace(/\x1b\[[0-9;]*m/g,"").replace(/\x1b\[[0-9]*[A-Z]/g,"").replace(/\[\d+[A-Z]/g,"").trim()){let t=`[${new Date().toISOString()}] [STDOUT] ${e}`;E.push(t),E.length>1e3&&E.shift()}})}),v.stderr&&v.stderr.on("data",e=>{e.toString().split("\n").forEach(e=>{if(e.replace(/\x1b\[[0-9;]*m/g,"").replace(/\x1b\[[0-9]*[A-Z]/g,"").replace(/\[\d+[A-Z]/g,"").trim()){let t=`[${new Date().toISOString()}] [STDERR] ${e}`;E.push(t),E.length>1e3&&E.shift()}})}),await f(),await d(u,E);let T=function(e){let r=setInterval(async()=>{let s=t.get(e);s?await d(e,s.logs):clearInterval(r)},5e3);return r}(u);if(v.on("exit",async e=>{console.log(`进程 ${u} 退出,退出码: ${e}`);let r=`[${new Date().toISOString()}] [SYSTEM] 进程退出,退出码: ${e}`;E.push(r),await d(u,E),clearInterval(T),t.delete(u),await f()}),v.on("error",e=>{console.error(`进程 ${u} 错误:`,e),t.delete(u),f()}),await new Promise(e=>setTimeout(e,2e3)),v.killed)return t.delete(u),await f(),s.NextResponse.json({success:!1,error:"进程启动失败"},{status:500});return s.NextResponse.json({success:!0,data:{pid:v.pid,startTime:new Date,port:y}})}catch(e){return console.error("启动进程失败:",e),s.NextResponse.json({success:!1,error:e instanceof Error?e.message:"启动进程失败"},{status:500})}}async function x(e){await g();try{let{searchParams:r}=new URL(e.url),n=r.get("projectName"),i=r.get("envName");if(!n||!i)return s.NextResponse.json({success:!1,error:"缺少必要参数"},{status:400});let a=`${n}-${i}`,c=t.get(a);if(!c)return s.NextResponse.json({success:!1,error:"进程未找到"},{status:404});try{process.kill(c.process.pid,"SIGTERM"),await new Promise(e=>setTimeout(e,1e3));try{process.kill(c.process.pid,0),process.kill(c.process.pid,"SIGKILL")}catch{}}catch(e){console.error("终止进程失败:",e)}t.delete(a),await f();try{let e=u(a);await o.default.unlink(e)}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})}}}},93992:e=>{"use strict";var{g:t,__dirname:r}=e;{e.s({patchFetch:()=>a,routeModule:()=>t,serverHooks:()=>l,workAsyncStorage:()=>r,workUnitAsyncStorage:()=>c});var s=e.i(45746),n=e.i(93828),i=e.i(18250),o=e.i(91359);let t=new s.AppRouteRouteModule({definition:{kind:n.RouteKind.APP_ROUTE,page:"/api/process/start/route",pathname:"/api/process/start",filename:"route",bundlePath:""},resolvedPagePath:"[project]/packages/server/src/app/api/process/start/route.ts",nextConfigOutput:"",userland:o}),{workAsyncStorage:r,workUnitAsyncStorage:c,serverHooks:l}=t;function a(){return(0,i.patchFetch)({workAsyncStorage:r,workUnitAsyncStorage:c})}}}};
|
|
2
2
|
|
|
3
|
-
//# sourceMappingURL=%5Broot-of-the-server%
|
|
3
|
+
//# sourceMappingURL=%5Broot-of-the-server%5D__09914a79._.js.map
|
|
@@ -1 +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/process-monitor.ts","turbopack:///[project]/packages/server/src/app/api/process/start/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 fs from 'fs/promises';\nimport path from 'path';\nimport os from 'os';\nimport { exec } from 'child_process';\nimport { promisify } from 'util';\n\nconst execAsync = promisify(exec);\n\n// 进程信息接口\ninterface ProcessInfo {\n key: string;\n projectName: string;\n envName: string;\n pid: number;\n startTime: Date;\n port: string;\n}\n\n// 获取进程存储文件路径\nfunction getProcessStorePath() {\n return path.join(os.homedir(), '.prime-processes.json');\n}\n\n// 检查进程是否仍在运行\nasync function isProcessRunning(pid: number): Promise<boolean> {\n try {\n if (process.platform !== 'win32') {\n process.kill(pid, 0);\n return true;\n } else {\n const { stdout } = await execAsync(`tasklist /FI \"PID eq ${pid}\"`);\n return stdout.includes(pid.toString());\n }\n } catch {\n return false;\n }\n}\n\n// 加载并清理过期的进程信息\nexport async function loadAndCleanProcesses(): Promise<ProcessInfo[]> {\n try {\n const processInfoContent = await fs.readFile(getProcessStorePath(), 'utf-8');\n const processInfoList: ProcessInfo[] = JSON.parse(processInfoContent);\n \n // 过滤出仍在运行的进程\n const runningProcesses: ProcessInfo[] = [];\n \n for (const processInfo of processInfoList) {\n const isRunning = await isProcessRunning(processInfo.pid);\n if (isRunning) {\n runningProcesses.push(processInfo);\n }\n }\n \n // 如果有进程被清理,更新文件\n if (runningProcesses.length !== processInfoList.length) {\n await fs.writeFile(getProcessStorePath(), JSON.stringify(runningProcesses, null, 2));\n }\n \n return runningProcesses;\n } catch {\n // 文件不存在或解析错误,返回空数组\n return [];\n }\n}\n\n// 初始化进程监控 - 在应用启动时调用\nexport async function initializeProcessMonitoring() {\n console.log('初始化进程监控...');\n const processes = await loadAndCleanProcesses();\n console.log(`发现 ${processes.length} 个正在运行的进程`);\n return processes;\n}","import { NextRequest, NextResponse } from 'next/server';\nimport { spawn } from 'child_process';\nimport path from 'path';\nimport fs from 'fs/promises';\nimport os from 'os';\nimport { loadAndCleanProcesses } from '@/lib/process-monitor';\nimport { getProjectsConfig } from '@/lib/workspace-config';\nimport { WORKSPACE_CONFIG } from '@/lib/workspace-types';\n\n// 存储进程信息的Map\ninterface ProcessData {\n process: {\n pid: number;\n killed: boolean;\n kill?: () => void;\n on?: (event: string, callback: (code?: number) => void) => void;\n };\n projectName: string;\n envName: string;\n startTime: Date;\n port: string;\n logs: string[];\n maxLogLines?: number;\n}\n\nconst processes = new Map<string, ProcessData>();\nconst MAX_LOG_LINES = 1000; // 最多保存1000行日志\n\n// 获取进程存储文件路径\nfunction getProcessStorePath() {\n return path.join(os.homedir(), '.prime-processes.json');\n}\n\n// 获取进程日志文件路径\nfunction getProcessLogPath(processKey: string) {\n return path.join(os.homedir(), '.prime-process-logs', `${processKey}.log`);\n}\n\n// 保存进程日志\nasync function saveProcessLogs(processKey: string, logs: string[]) {\n const logDir = path.join(os.homedir(), '.prime-process-logs');\n const logPath = getProcessLogPath(processKey);\n \n try {\n // 确保日志目录存在\n await fs.mkdir(logDir, { recursive: true });\n // 写入日志文件\n await fs.writeFile(logPath, logs.join('\\n'), 'utf-8');\n } catch (error) {\n console.error('保存进程日志失败:', error);\n }\n}\n\n// 定期保存日志\nfunction startLogSaver(processKey: string) {\n const interval = setInterval(async () => {\n const processData = processes.get(processKey);\n if (processData) {\n await saveProcessLogs(processKey, processData.logs);\n } else {\n clearInterval(interval);\n }\n }, 5000); // 每5秒保存一次\n \n return interval;\n}\n\n// 保存进程信息到文件\nasync function saveProcessInfo() {\n const processInfo: {\n key: string;\n projectName: string;\n envName: string;\n startTime: Date;\n port: string;\n pid: number;\n }[] = [];\n processes.forEach((value, key) => {\n processInfo.push({\n key,\n projectName: value.projectName,\n envName: value.envName,\n startTime: value.startTime,\n port: value.port,\n pid: value.process.pid\n });\n });\n \n try {\n await fs.writeFile(getProcessStorePath(), JSON.stringify(processInfo, null, 2));\n } catch (error) {\n console.error('保存进程信息失败:', error);\n }\n}\n\n// 在启动时加载现有进程信息\nlet processesInitialized = false;\nasync function ensureProcessesLoaded() {\n if (!processesInitialized) {\n const existingProcesses = await loadAndCleanProcesses();\n for (const processInfo of existingProcesses) {\n // 恢复进程信息到内存,但不恢复实际的进程对象\n // 因为我们只需要知道进程存在,状态查询会检查实际的PID\n // 尝试加载已保存的日志\n const logs: string[] = [];\n try {\n const logPath = getProcessLogPath(processInfo.key);\n const logContent = await fs.readFile(logPath, 'utf-8');\n logs.push(...logContent.split('\\n').filter(line => line.trim()));\n } catch {\n // 日志文件不存在或读取失败,使用空日志\n }\n \n processes.set(processInfo.key, {\n process: { pid: processInfo.pid, killed: false },\n projectName: processInfo.projectName,\n envName: processInfo.envName,\n startTime: new Date(processInfo.startTime),\n port: processInfo.port,\n logs,\n maxLogLines: MAX_LOG_LINES\n });\n }\n processesInitialized = true;\n }\n}\n\nexport async function POST(request: NextRequest) {\n await ensureProcessesLoaded();\n try {\n const { projectName, envName, startCommand } = await request.json();\n\n if (!projectName || !envName || !startCommand) {\n return NextResponse.json({\n success: false,\n error: '缺少必要参数'\n }, { status: 400 });\n }\n\n // 生成进程的唯一标识\n const processKey = `${projectName}-${envName}`;\n\n // 检查进程是否已经在运行\n if (processes.has(processKey)) {\n const existingProcess = processes.get(processKey);\n if (existingProcess && existingProcess.process && !existingProcess.process.killed) {\n return NextResponse.json({\n success: false,\n error: '该环境已经在运行中'\n }, { status: 400 });\n }\n }\n\n // 读取配置文件获取工作区路径\n const config = await getProjectsConfig();\n \n // 使用工作区常量路径\n const workspacePath = WORKSPACE_CONFIG.WORKSPACE_ROOT;\n \n // 构建项目路径\n const projectPath = path.join(workspacePath, projectName);\n\n // 检查项目目录是否存在\n try {\n await fs.access(projectPath);\n } catch {\n return NextResponse.json({\n success: false,\n error: '项目目录不存在'\n }, { status: 404 });\n }\n\n // 解析命令\n const [command, ...args] = startCommand.split(' ');\n\n // 启动进程 - 不传递 env 参数,让子进程继承父进程环境变量\n // 但通过环境变量覆盖确保开发模式\n const childProcess = spawn(command, args, {\n cwd: projectPath,\n shell: true,\n detached: false,\n stdio: ['ignore', 'pipe', 'pipe'],\n env: {\n ...process.env,\n NODE_ENV: 'development', // 强制设置为开发模式\n FORCE_COLOR: '1', // 保留颜色输出\n }\n });\n\n // 获取项目配置中的端口信息\n const projectConfig = config[projectName];\n const envConfig = projectConfig?.envs?.[envName];\n const port = envConfig?.host?.split(':').pop() || '';\n\n // 初始化日志数组\n const logs: string[] = [];\n \n // 存储进程信息\n const processData: ProcessData = {\n process: {\n pid: childProcess.pid || 0,\n killed: false,\n kill: () => childProcess.kill(),\n on: (event: string, callback: (code?: number) => void) => {\n childProcess.on(event, callback);\n }\n },\n projectName,\n envName,\n startTime: new Date(),\n port,\n logs,\n maxLogLines: MAX_LOG_LINES\n };\n \n processes.set(processKey, processData);\n \n // 捕获标准输出\n if (childProcess.stdout) {\n childProcess.stdout.on('data', (data: Buffer) => {\n const text = data.toString();\n // 分割成行,但保留空行以便过滤\n const lines = text.split('\\n');\n \n lines.forEach(line => {\n // 过滤掉只包含控制序列的行\n const cleanedLine = line\n .replace(/\\x1b\\[[0-9;]*m/g, '') // 移除颜色代码\n .replace(/\\x1b\\[[0-9]*[A-Z]/g, '') // 移除光标控制\n .replace(/\\[\\d+[A-Z]/g, '') // 移除其他控制序列\n .trim();\n \n // 如果清理后的行不为空,则记录\n if (cleanedLine) {\n const logEntry = `[${new Date().toISOString()}] [STDOUT] ${line}`;\n logs.push(logEntry);\n // 限制日志大小\n if (logs.length > MAX_LOG_LINES) {\n logs.shift();\n }\n }\n });\n });\n }\n \n // 捕获标准错误\n if (childProcess.stderr) {\n childProcess.stderr.on('data', (data: Buffer) => {\n const text = data.toString();\n const lines = text.split('\\n');\n \n lines.forEach(line => {\n // 过滤掉只包含控制序列的行\n const cleanedLine = line\n .replace(/\\x1b\\[[0-9;]*m/g, '')\n .replace(/\\x1b\\[[0-9]*[A-Z]/g, '')\n .replace(/\\[\\d+[A-Z]/g, '')\n .trim();\n \n if (cleanedLine) {\n const logEntry = `[${new Date().toISOString()}] [STDERR] ${line}`;\n logs.push(logEntry);\n // 限制日志大小\n if (logs.length > MAX_LOG_LINES) {\n logs.shift();\n }\n }\n });\n });\n }\n\n // 保存进程信息到文件\n await saveProcessInfo();\n \n // 同时保存日志\n await saveProcessLogs(processKey, logs);\n\n // 启动日志定期保存\n const logSaveInterval = startLogSaver(processKey);\n \n // 监听进程退出\n childProcess.on('exit', async (code) => {\n console.log(`进程 ${processKey} 退出,退出码: ${code}`);\n const logEntry = `[${new Date().toISOString()}] [SYSTEM] 进程退出,退出码: ${code}`;\n logs.push(logEntry);\n \n // 最后一次保存日志\n await saveProcessLogs(processKey, logs);\n \n // 清理定时器\n clearInterval(logSaveInterval);\n \n processes.delete(processKey);\n await saveProcessInfo();\n });\n\n childProcess.on('error', (error) => {\n console.error(`进程 ${processKey} 错误:`, error);\n processes.delete(processKey);\n saveProcessInfo();\n });\n\n // 等待一小段时间确保进程启动\n await new Promise(resolve => setTimeout(resolve, 2000));\n\n // 检查进程是否仍在运行\n if (childProcess.killed) {\n processes.delete(processKey);\n await saveProcessInfo();\n return NextResponse.json({\n success: false,\n error: '进程启动失败'\n }, { status: 500 });\n }\n\n return NextResponse.json({\n success: true,\n data: {\n pid: childProcess.pid,\n startTime: new Date(),\n port\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 await ensureProcessesLoaded();\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 processKey = `${projectName}-${envName}`;\n const processInfo = processes.get(processKey);\n\n if (!processInfo) {\n return NextResponse.json({\n success: false,\n error: '进程未找到'\n }, { status: 404 });\n }\n\n try {\n // 尝试优雅地终止进程\n process.kill(processInfo.process.pid, 'SIGTERM');\n \n // 给进程一些时间来清理\n await new Promise(resolve => setTimeout(resolve, 1000));\n \n // 如果进程仍在运行,强制终止\n try {\n process.kill(processInfo.process.pid, 0); // 检查进程是否存在\n process.kill(processInfo.process.pid, 'SIGKILL');\n } catch {\n // 进程已经退出\n }\n } catch (error) {\n console.error('终止进程失败:', error);\n }\n\n processes.delete(processKey);\n await saveProcessInfo();\n \n // 清理日志文件\n try {\n const logPath = getProcessLogPath(processKey);\n await fs.unlink(logPath);\n } catch {\n // 忽略删除失败\n }\n\n return NextResponse.json({\n success: true,\n message: '进程已停止'\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":[4]}
|
|
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/process-monitor.ts","turbopack:///[project]/packages/server/src/app/api/process/start/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 fs from 'fs/promises';\nimport path from 'path';\nimport os from 'os';\nimport { exec } from 'child_process';\nimport { promisify } from 'util';\n\nconst execAsync = promisify(exec);\n\n// 进程信息接口\ninterface ProcessInfo {\n key: string;\n projectName: string;\n envName: string;\n pid: number;\n startTime: Date;\n port: string;\n}\n\n// 获取进程存储文件路径\nfunction getProcessStorePath() {\n return path.join(os.homedir(), '.prime-processes.json');\n}\n\n// 检查进程是否仍在运行\nasync function isProcessRunning(pid: number): Promise<boolean> {\n try {\n if (process.platform !== 'win32') {\n process.kill(pid, 0);\n return true;\n } else {\n const { stdout } = await execAsync(`tasklist /FI \"PID eq ${pid}\"`);\n return stdout.includes(pid.toString());\n }\n } catch {\n return false;\n }\n}\n\n// 加载并清理过期的进程信息\nexport async function loadAndCleanProcesses(): Promise<ProcessInfo[]> {\n try {\n const processInfoContent = await fs.readFile(getProcessStorePath(), 'utf-8');\n const processInfoList: ProcessInfo[] = JSON.parse(processInfoContent);\n \n // 过滤出仍在运行的进程\n const runningProcesses: ProcessInfo[] = [];\n \n for (const processInfo of processInfoList) {\n const isRunning = await isProcessRunning(processInfo.pid);\n if (isRunning) {\n runningProcesses.push(processInfo);\n }\n }\n \n // 如果有进程被清理,更新文件\n if (runningProcesses.length !== processInfoList.length) {\n await fs.writeFile(getProcessStorePath(), JSON.stringify(runningProcesses, null, 2));\n }\n \n return runningProcesses;\n } catch {\n // 文件不存在或解析错误,返回空数组\n return [];\n }\n}\n\n// 初始化进程监控 - 在应用启动时调用\nexport async function initializeProcessMonitoring() {\n console.log('初始化进程监控...');\n const processes = await loadAndCleanProcesses();\n console.log(`发现 ${processes.length} 个正在运行的进程`);\n return processes;\n}","import { NextRequest, NextResponse } from 'next/server';\nimport { spawn } from 'child_process';\nimport path from 'path';\nimport fs from 'fs/promises';\nimport os from 'os';\nimport { loadAndCleanProcesses } from '@/lib/process-monitor';\nimport { getProjectsConfig } from '@/lib/workspace-config';\nimport { WORKSPACE_CONFIG } from '@/lib/workspace-types';\n\n// 存储进程信息的Map\ninterface ProcessData {\n process: {\n pid: number;\n killed: boolean;\n kill?: () => void;\n on?: (event: string, callback: (code?: number) => void) => void;\n };\n projectName: string;\n envName: string;\n startTime: Date;\n port: string;\n logs: string[];\n maxLogLines?: number;\n}\n\nconst processes = new Map<string, ProcessData>();\nconst MAX_LOG_LINES = 1000; // 最多保存1000行日志\n\n// 获取进程存储文件路径\nfunction getProcessStorePath() {\n return path.join(os.homedir(), '.prime-processes.json');\n}\n\n// 获取进程日志文件路径\nfunction getProcessLogPath(processKey: string) {\n return path.join(os.homedir(), '.prime-process-logs', `${processKey}.log`);\n}\n\n// 保存进程日志\nasync function saveProcessLogs(processKey: string, logs: string[]) {\n const logDir = path.join(os.homedir(), '.prime-process-logs');\n const logPath = getProcessLogPath(processKey);\n \n try {\n // 确保日志目录存在\n await fs.mkdir(logDir, { recursive: true });\n // 写入日志文件\n await fs.writeFile(logPath, logs.join('\\n'), 'utf-8');\n } catch (error) {\n console.error('保存进程日志失败:', error);\n }\n}\n\n// 定期保存日志\nfunction startLogSaver(processKey: string) {\n const interval = setInterval(async () => {\n const processData = processes.get(processKey);\n if (processData) {\n await saveProcessLogs(processKey, processData.logs);\n } else {\n clearInterval(interval);\n }\n }, 5000); // 每5秒保存一次\n \n return interval;\n}\n\n// 保存进程信息到文件\nasync function saveProcessInfo() {\n const processInfo: {\n key: string;\n projectName: string;\n envName: string;\n startTime: Date;\n port: string;\n pid: number;\n }[] = [];\n processes.forEach((value, key) => {\n processInfo.push({\n key,\n projectName: value.projectName,\n envName: value.envName,\n startTime: value.startTime,\n port: value.port,\n pid: value.process.pid\n });\n });\n \n try {\n await fs.writeFile(getProcessStorePath(), JSON.stringify(processInfo, null, 2));\n } catch (error) {\n console.error('保存进程信息失败:', error);\n }\n}\n\n// 在启动时加载现有进程信息\nlet processesInitialized = false;\nasync function ensureProcessesLoaded() {\n if (!processesInitialized) {\n const existingProcesses = await loadAndCleanProcesses();\n for (const processInfo of existingProcesses) {\n // 恢复进程信息到内存,但不恢复实际的进程对象\n // 因为我们只需要知道进程存在,状态查询会检查实际的PID\n // 尝试加载已保存的日志\n const logs: string[] = [];\n try {\n const logPath = getProcessLogPath(processInfo.key);\n const logContent = await fs.readFile(logPath, 'utf-8');\n logs.push(...logContent.split('\\n').filter(line => line.trim()));\n } catch {\n // 日志文件不存在或读取失败,使用空日志\n }\n \n processes.set(processInfo.key, {\n process: { pid: processInfo.pid, killed: false },\n projectName: processInfo.projectName,\n envName: processInfo.envName,\n startTime: new Date(processInfo.startTime),\n port: processInfo.port,\n logs,\n maxLogLines: MAX_LOG_LINES\n });\n }\n processesInitialized = true;\n }\n}\n\nexport async function POST(request: NextRequest) {\n await ensureProcessesLoaded();\n try {\n const { projectName, envName, startCommand } = await request.json();\n\n if (!projectName || !envName || !startCommand) {\n return NextResponse.json({\n success: false,\n error: '缺少必要参数'\n }, { status: 400 });\n }\n\n // 生成进程的唯一标识\n const processKey = `${projectName}-${envName}`;\n\n // 检查进程是否已经在运行\n if (processes.has(processKey)) {\n const existingProcess = processes.get(processKey);\n if (existingProcess && existingProcess.process && !existingProcess.process.killed) {\n return NextResponse.json({\n success: false,\n error: '该环境已经在运行中'\n }, { status: 400 });\n }\n }\n\n // 读取配置文件获取工作区路径\n const config = await getProjectsConfig();\n \n // 使用工作区常量路径\n const workspacePath = WORKSPACE_CONFIG.WORKSPACE_ROOT;\n \n // 构建项目路径\n const projectPath = path.join(workspacePath, projectName);\n\n // 检查项目目录是否存在\n try {\n await fs.access(projectPath);\n } catch {\n return NextResponse.json({\n success: false,\n error: '项目目录不存在'\n }, { status: 404 });\n }\n\n // 解析命令\n const [command, ...args] = startCommand.split(' ');\n\n // 启动进程 - 不传递 env 参数,让子进程继承父进程环境变量\n // 但通过环境变量覆盖确保开发模式\n const childProcess = spawn(command, args, {\n cwd: projectPath,\n shell: true,\n detached: false,\n stdio: ['ignore', 'pipe', 'pipe'],\n env: {\n ...process.env,\n NODE_ENV: 'development', // 强制设置为开发模式\n FORCE_COLOR: '1', // 保留颜色输出\n }\n });\n\n // 获取项目配置中的端口信息\n const projectConfig = config[projectName];\n const envConfig = projectConfig?.envs?.[envName];\n const port = envConfig?.host?.split(':').pop() || '';\n\n // 初始化日志数组\n const logs: string[] = [];\n \n // 存储进程信息\n const processData: ProcessData = {\n process: {\n pid: childProcess.pid || 0,\n killed: false,\n kill: () => childProcess.kill(),\n on: (event: string, callback: (code?: number) => void) => {\n childProcess.on(event, callback);\n }\n },\n projectName,\n envName,\n startTime: new Date(),\n port,\n logs,\n maxLogLines: MAX_LOG_LINES\n };\n \n processes.set(processKey, processData);\n \n // 捕获标准输出\n if (childProcess.stdout) {\n childProcess.stdout.on('data', (data: Buffer) => {\n const text = data.toString();\n // 分割成行,但保留空行以便过滤\n const lines = text.split('\\n');\n \n lines.forEach(line => {\n // 过滤掉只包含控制序列的行\n const cleanedLine = line\n .replace(/\\x1b\\[[0-9;]*m/g, '') // 移除颜色代码\n .replace(/\\x1b\\[[0-9]*[A-Z]/g, '') // 移除光标控制\n .replace(/\\[\\d+[A-Z]/g, '') // 移除其他控制序列\n .trim();\n \n // 如果清理后的行不为空,则记录\n if (cleanedLine) {\n const logEntry = `[${new Date().toISOString()}] [STDOUT] ${line}`;\n logs.push(logEntry);\n // 限制日志大小\n if (logs.length > MAX_LOG_LINES) {\n logs.shift();\n }\n }\n });\n });\n }\n \n // 捕获标准错误\n if (childProcess.stderr) {\n childProcess.stderr.on('data', (data: Buffer) => {\n const text = data.toString();\n const lines = text.split('\\n');\n \n lines.forEach(line => {\n // 过滤掉只包含控制序列的行\n const cleanedLine = line\n .replace(/\\x1b\\[[0-9;]*m/g, '')\n .replace(/\\x1b\\[[0-9]*[A-Z]/g, '')\n .replace(/\\[\\d+[A-Z]/g, '')\n .trim();\n \n if (cleanedLine) {\n const logEntry = `[${new Date().toISOString()}] [STDERR] ${line}`;\n logs.push(logEntry);\n // 限制日志大小\n if (logs.length > MAX_LOG_LINES) {\n logs.shift();\n }\n }\n });\n });\n }\n\n // 保存进程信息到文件\n await saveProcessInfo();\n \n // 同时保存日志\n await saveProcessLogs(processKey, logs);\n\n // 启动日志定期保存\n const logSaveInterval = startLogSaver(processKey);\n \n // 监听进程退出\n childProcess.on('exit', async (code) => {\n console.log(`进程 ${processKey} 退出,退出码: ${code}`);\n const logEntry = `[${new Date().toISOString()}] [SYSTEM] 进程退出,退出码: ${code}`;\n logs.push(logEntry);\n \n // 最后一次保存日志\n await saveProcessLogs(processKey, logs);\n \n // 清理定时器\n clearInterval(logSaveInterval);\n \n processes.delete(processKey);\n await saveProcessInfo();\n });\n\n childProcess.on('error', (error) => {\n console.error(`进程 ${processKey} 错误:`, error);\n processes.delete(processKey);\n saveProcessInfo();\n });\n\n // 等待一小段时间确保进程启动\n await new Promise(resolve => setTimeout(resolve, 2000));\n\n // 检查进程是否仍在运行\n if (childProcess.killed) {\n processes.delete(processKey);\n await saveProcessInfo();\n return NextResponse.json({\n success: false,\n error: '进程启动失败'\n }, { status: 500 });\n }\n\n return NextResponse.json({\n success: true,\n data: {\n pid: childProcess.pid,\n startTime: new Date(),\n port\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 await ensureProcessesLoaded();\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 processKey = `${projectName}-${envName}`;\n const processInfo = processes.get(processKey);\n\n if (!processInfo) {\n return NextResponse.json({\n success: false,\n error: '进程未找到'\n }, { status: 404 });\n }\n\n try {\n // 尝试优雅地终止进程\n process.kill(processInfo.process.pid, 'SIGTERM');\n \n // 给进程一些时间来清理\n await new Promise(resolve => setTimeout(resolve, 1000));\n \n // 如果进程仍在运行,强制终止\n try {\n process.kill(processInfo.process.pid, 0); // 检查进程是否存在\n process.kill(processInfo.process.pid, 'SIGKILL');\n } catch {\n // 进程已经退出\n }\n } catch (error) {\n console.error('终止进程失败:', error);\n }\n\n processes.delete(processKey);\n await saveProcessInfo();\n \n // 清理日志文件\n try {\n const logPath = getProcessLogPath(processKey);\n await fs.unlink(logPath);\n } catch {\n // 忽略删除失败\n }\n\n return NextResponse.json({\n success: true,\n message: '进程已停止'\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":[4]}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
module.exports={83886:function(e){var{g:r,__dirname:t,m:s,e:n}=e;s.exports=e.x("fs",()=>require("fs"))},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"))},35692:e=>{"use strict";var{g:r,__dirname:t}=e;e.s({ProjectStatus:()=>i,getProjectsConfig:()=>o,saveProjectsConfig:()=>a});var s=e.i(9892),n=e.i(88941);async function o(){try{await (0,s.access)(n.PROJECT_CONFIG_PATH,s.constants.F_OK)}catch{return await a({}),{}}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 a(e){let r=n.PROJECT_CONFIG_PATH+".tmp";try{await (0,s.writeFile)(r,JSON.stringify(e,null,2),"utf-8"),await (0,s.rename)(r,n.PROJECT_CONFIG_PATH)}catch(e){throw console.error("保存项目配置文件失败:",e),Error("无法保存项目配置")}}var i=function(e){return e.PENDING="pending",e.EXISTING="existing",e.CLONING="cloning",e.SUCCESS="success",e.FAILED="failed",e.RETRYING="retrying",e}({})},
|
|
1
|
+
module.exports={83886:function(e){var{g:r,__dirname:t,m:s,e:n}=e;s.exports=e.x("fs",()=>require("fs"))},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"))},35692:e=>{"use strict";var{g:r,__dirname:t}=e;e.s({ProjectStatus:()=>i,getProjectsConfig:()=>o,saveProjectsConfig:()=>a});var s=e.i(9892),n=e.i(88941);async function o(){try{await (0,s.access)(n.PROJECT_CONFIG_PATH,s.constants.F_OK)}catch{return await a({}),{}}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 a(e){let r=n.PROJECT_CONFIG_PATH+".tmp";try{await (0,s.writeFile)(r,JSON.stringify(e,null,2),"utf-8"),await (0,s.rename)(r,n.PROJECT_CONFIG_PATH)}catch(e){throw console.error("保存项目配置文件失败:",e),Error("无法保存项目配置")}}var i=function(e){return e.PENDING="pending",e.EXISTING="existing",e.CLONING="cloning",e.SUCCESS="success",e.FAILED="failed",e.RETRYING="retrying",e}({})},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"))},88941:e=>{"use strict";var{g:r,__dirname:t}=e;{e.s({PROJECT_CONFIG_PATH:()=>t,ProjectStatus:()=>o,WORKSPACE_CONFIG:()=>r});var s=e.i(13442),n=e.i(30331);let r={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},t=(0,n.join)((0,s.homedir)(),".prime-projects.json");var o=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}({})}},9892:function(e){var{g:r,__dirname:t,m:s,e:n}=e;s.exports=e.x("fs/promises",()=>require("fs/promises"))},15650:function(e){var{g:r,__dirname:t,m:s,e:n}=e;s.exports=e.x("module",()=>require("module"))},80298:function(e){var{g:r,__dirname:t,m:s,e:n}=e},17717:e=>{"use strict";var{g:r,__dirname:t}=e;{e.s({POST:()=>c});var s=e.i(15494),n=e.i(83886),o=e.i(30331),a=e.i(35692),i=e.i(88941);let r=(0,e.i(15650).createRequire)({get url(){return`file://${e.P("packages/server/src/app/api/cleanup-mock/route.ts")}`}}.url);async function c(e){try{let{projectName:t}=await e.json();if(!t)return s.NextResponse.json({success:!1,error:"项目名称参数缺失"},{status:400});if(!(await (0,a.getProjectsConfig)())[t])return s.NextResponse.json({success:!1,error:`项目 ${t} 不存在`},{status:404});let c=(0,o.join)(i.WORKSPACE_CONFIG.WORKSPACE_ROOT,t),u=(0,o.join)(c,".mock");try{await n.promises.access(u)}catch{return s.NextResponse.json({success:!0,message:"Mock目录不存在,无需清理",data:{projectName:t,timestamp:new Date().toISOString()}})}let p=async e=>{for(let t of(await n.promises.readdir(e,{withFileTypes:!0}))){let s=(0,o.join)(e,t.name);if(t.isDirectory())await p(s);else if("setting.cjs"===t.name)try{let e=(0,o.resolve)(s);delete r.cache[e];let t=r(e),a=`module.exports = {
|
|
2
2
|
// 当前场景名称
|
|
3
3
|
currentSite: '${t.currentSite||""}',
|
|
4
4
|
// 开启Mock的场景列表(已清空)
|
|
5
5
|
open: []
|
|
6
6
|
};`;await n.promises.writeFile(s,a,"utf-8")}catch(e){console.warn(`解析setting.cjs失败: ${s}`,e)}}};return await p(u),s.NextResponse.json({success:!0,message:"所有Mock场景已清空",data:{projectName:t,timestamp:new Date().toISOString()}})}catch(r){let e=r instanceof Error?r.message:"清空Mock场景失败";return console.error("清空Mock场景失败:",r),s.NextResponse.json({success:!1,error:e},{status:500})}}}},30706:e=>{"use strict";var{g:r,__dirname:t}=e;{e.s({patchFetch:()=>i,routeModule:()=>r,serverHooks:()=>u,workAsyncStorage:()=>t,workUnitAsyncStorage:()=>c});var s=e.i(45746),n=e.i(93828),o=e.i(18250),a=e.i(17717);let r=new s.AppRouteRouteModule({definition:{kind:n.RouteKind.APP_ROUTE,page:"/api/cleanup-mock/route",pathname:"/api/cleanup-mock",filename:"route",bundlePath:""},resolvedPagePath:"[project]/packages/server/src/app/api/cleanup-mock/route.ts",nextConfigOutput:"",userland:a}),{workAsyncStorage:t,workUnitAsyncStorage:c,serverHooks:u}=r;function i(){return(0,o.patchFetch)({workAsyncStorage:t,workUnitAsyncStorage:c})}}}};
|
|
7
7
|
|
|
8
|
-
//# sourceMappingURL=%5Broot-of-the-server%
|
|
8
|
+
//# sourceMappingURL=%5Broot-of-the-server%5D__42bc7b42._.js.map
|
|
@@ -1 +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/cleanup-mock/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 POST(request: NextRequest) {\n try {\n // 解析请求体\n const { projectName } = await request.json();\n\n if (!projectName) {\n return NextResponse.json(\n { success: false, error: '项目名称参数缺失' },\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 // 构建 .mock 目录路径\n const projectPath = join(WORKSPACE_CONFIG.WORKSPACE_ROOT, projectName);\n const mockPath = join(projectPath, '.mock');\n\n // 检查 .mock 目录是否存在\n try {\n await fs.access(mockPath);\n } catch {\n return NextResponse.json({\n success: true,\n message: 'Mock目录不存在,无需清理',\n data: {\n projectName,\n timestamp: new Date().toISOString(),\n },\n });\n }\n\n // 递归处理所有目录\n const processDirectory = async (dirPath: string) => {\n const entries = await fs.readdir(dirPath, { withFileTypes: true });\n\n for (const entry of entries) {\n const fullPath = join(dirPath, entry.name);\n\n if (entry.isDirectory()) {\n // 递归处理子目录\n await processDirectory(fullPath);\n } else if (entry.name === 'setting.cjs') {\n // 使用require直接导入setting.cjs\n try {\n const resolvedPath = resolve(fullPath);\n delete require.cache[resolvedPath];\n const currentConfig = require(resolvedPath);\n \n // 保持当前场景名称,但清空 open 数组\n const newContent = `module.exports = {\n // 当前场景名称\n currentSite: '${currentConfig.currentSite || ''}',\n // 开启Mock的场景列表(已清空)\n open: []\n};`;\n \n // 写入更新后的内容\n await fs.writeFile(fullPath, newContent, 'utf-8');\n } catch (parseError) {\n console.warn(`解析setting.cjs失败: ${fullPath}`, parseError);\n }\n }\n }\n };\n\n // 开始处理\n await processDirectory(mockPath);\n\n return NextResponse.json({\n success: true,\n message: '所有Mock场景已清空',\n data: {\n projectName,\n timestamp: new Date().toISOString(),\n },\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]}
|
|
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/cleanup-mock/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 POST(request: NextRequest) {\n try {\n // 解析请求体\n const { projectName } = await request.json();\n\n if (!projectName) {\n return NextResponse.json(\n { success: false, error: '项目名称参数缺失' },\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 // 构建 .mock 目录路径\n const projectPath = join(WORKSPACE_CONFIG.WORKSPACE_ROOT, projectName);\n const mockPath = join(projectPath, '.mock');\n\n // 检查 .mock 目录是否存在\n try {\n await fs.access(mockPath);\n } catch {\n return NextResponse.json({\n success: true,\n message: 'Mock目录不存在,无需清理',\n data: {\n projectName,\n timestamp: new Date().toISOString(),\n },\n });\n }\n\n // 递归处理所有目录\n const processDirectory = async (dirPath: string) => {\n const entries = await fs.readdir(dirPath, { withFileTypes: true });\n\n for (const entry of entries) {\n const fullPath = join(dirPath, entry.name);\n\n if (entry.isDirectory()) {\n // 递归处理子目录\n await processDirectory(fullPath);\n } else if (entry.name === 'setting.cjs') {\n // 使用require直接导入setting.cjs\n try {\n const resolvedPath = resolve(fullPath);\n delete require.cache[resolvedPath];\n const currentConfig = require(resolvedPath);\n \n // 保持当前场景名称,但清空 open 数组\n const newContent = `module.exports = {\n // 当前场景名称\n currentSite: '${currentConfig.currentSite || ''}',\n // 开启Mock的场景列表(已清空)\n open: []\n};`;\n \n // 写入更新后的内容\n await fs.writeFile(fullPath, newContent, 'utf-8');\n } catch (parseError) {\n console.warn(`解析setting.cjs失败: ${fullPath}`, parseError);\n }\n }\n }\n };\n\n // 开始处理\n await processDirectory(mockPath);\n\n return NextResponse.json({\n success: true,\n message: '所有Mock场景已清空',\n data: {\n projectName,\n timestamp: new Date().toISOString(),\n },\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]}
|
|
@@ -1,3 +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"))},35692:e=>{"use strict";var{g:r,__dirname:t}=e;e.s({ProjectStatus:()=>i,getProjectsConfig:()=>o,saveProjectsConfig:()=>a});var s=e.i(9892),n=e.i(88941);async function o(){try{await (0,s.access)(n.PROJECT_CONFIG_PATH,s.constants.F_OK)}catch{return await a({}),{}}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 a(e){let r=n.PROJECT_CONFIG_PATH+".tmp";try{await (0,s.writeFile)(r,JSON.stringify(e,null,2),"utf-8"),await (0,s.rename)(r,n.PROJECT_CONFIG_PATH)}catch(e){throw console.error("保存项目配置文件失败:",e),Error("无法保存项目配置")}}var i=function(e){return e.PENDING="pending",e.EXISTING="existing",e.CLONING="cloning",e.SUCCESS="success",e.FAILED="failed",e.RETRYING="retrying",e}({})},
|
|
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"))},35692:e=>{"use strict";var{g:r,__dirname:t}=e;e.s({ProjectStatus:()=>i,getProjectsConfig:()=>o,saveProjectsConfig:()=>a});var s=e.i(9892),n=e.i(88941);async function o(){try{await (0,s.access)(n.PROJECT_CONFIG_PATH,s.constants.F_OK)}catch{return await a({}),{}}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 a(e){let r=n.PROJECT_CONFIG_PATH+".tmp";try{await (0,s.writeFile)(r,JSON.stringify(e,null,2),"utf-8"),await (0,s.rename)(r,n.PROJECT_CONFIG_PATH)}catch(e){throw console.error("保存项目配置文件失败:",e),Error("无法保存项目配置")}}var i=function(e){return e.PENDING="pending",e.EXISTING="existing",e.CLONING="cloning",e.SUCCESS="success",e.FAILED="failed",e.RETRYING="retrying",e}({})},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"))},88941:e=>{"use strict";var{g:r,__dirname:t}=e;{e.s({PROJECT_CONFIG_PATH:()=>t,ProjectStatus:()=>o,WORKSPACE_CONFIG:()=>r});var s=e.i(13442),n=e.i(30331);let r={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},t=(0,n.join)((0,s.homedir)(),".prime-projects.json");var o=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}({})}},9892:function(e){var{g:r,__dirname:t,m:s,e:n}=e;s.exports=e.x("fs/promises",()=>require("fs/promises"))},85748:function(e){var{g:r,__dirname:t,m:s,e:n}=e},46299:e=>{"use strict";var{g:r,__dirname:t}=e;e.s({GET:()=>a,OPTIONS:()=>o});var s=e.i(15494),n=e.i(35692);async function o(){return new s.NextResponse(null,{status:200,headers:{"Access-Control-Allow-Origin":"*","Access-Control-Allow-Methods":"GET, POST, PUT, DELETE, OPTIONS","Access-Control-Allow-Headers":"Content-Type, Authorization, X-Requested-With","Access-Control-Max-Age":"86400"}})}async function a(){try{let e=await (0,n.getProjectsConfig)(),r=Object.entries(e).flatMap(([e,r])=>Object.entries(r.envs).map(([t,s])=>({projectName:e,envName:t,host:s.host,repo:r.repo,currentProxy:s.currentProxy,proxyEnv:s.proxyEnv,subApps:s.subApps||[]}))),t=s.NextResponse.json({success:!0,data:r,message:`成功获取 ${r.length} 个环境配置`});return t.headers.set("Access-Control-Allow-Origin","*"),t.headers.set("Access-Control-Allow-Methods","GET, POST, PUT, DELETE, OPTIONS"),t.headers.set("Access-Control-Allow-Headers","Content-Type, Authorization, X-Requested-With"),t}catch(t){let e=t instanceof Error?t.message:"获取项目环境配置失败";console.error("获取所有项目环境配置失败:",t);let r=s.NextResponse.json({success:!1,error:e},{status:500});return r.headers.set("Access-Control-Allow-Origin","*"),r.headers.set("Access-Control-Allow-Methods","GET, POST, PUT, DELETE, OPTIONS"),r.headers.set("Access-Control-Allow-Headers","Content-Type, Authorization, X-Requested-With"),r}}},22785:e=>{"use strict";var{g:r,__dirname:t}=e;{e.s({patchFetch:()=>i,routeModule:()=>r,serverHooks:()=>p,workAsyncStorage:()=>t,workUnitAsyncStorage:()=>c});var s=e.i(45746),n=e.i(93828),o=e.i(18250),a=e.i(46299);let r=new s.AppRouteRouteModule({definition:{kind:n.RouteKind.APP_ROUTE,page:"/api/all-projects-envs/route",pathname:"/api/all-projects-envs",filename:"route",bundlePath:""},resolvedPagePath:"[project]/packages/server/src/app/api/all-projects-envs/route.ts",nextConfigOutput:"",userland:a}),{workAsyncStorage:t,workUnitAsyncStorage:c,serverHooks:p}=r;function i(){return(0,o.patchFetch)({workAsyncStorage:t,workUnitAsyncStorage:c})}}}};
|
|
2
2
|
|
|
3
|
-
//# sourceMappingURL=%5Broot-of-the-server%
|
|
3
|
+
//# sourceMappingURL=%5Broot-of-the-server%5D__4dc677cb._.js.map
|
|
@@ -1 +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/all-projects-envs/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 { NextResponse } from 'next/server';\nimport { getProjectsConfig } from '@/lib/workspace-config';\n\n// 处理预检请求\nexport async function OPTIONS() {\n return new NextResponse(null, {\n status: 200,\n headers: {\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',\n 'Access-Control-Allow-Headers': 'Content-Type, Authorization, X-Requested-With',\n 'Access-Control-Max-Age': '86400',\n },\n });\n}\n\nexport async function GET() {\n try {\n // 读取项目配置文件\n const projectsConfig = await getProjectsConfig();\n \n // 转换数据结构,提取所有项目的环境信息\n const allProjectsEnvs = Object.entries(projectsConfig).flatMap(([projectName, projectConfig]) => {\n return Object.entries(projectConfig.envs).map(([envName, envConfig]) => ({\n projectName,\n envName,\n host: envConfig.host,\n repo: projectConfig.repo,\n currentProxy: envConfig.currentProxy,\n proxyEnv: envConfig.proxyEnv,\n subApps: envConfig.subApps || [],\n }));\n });\n\n const response = NextResponse.json({\n success: true,\n data: allProjectsEnvs,\n message: `成功获取 ${allProjectsEnvs.length} 个环境配置`,\n });\n\n // 添加CORS headers\n response.headers.set('Access-Control-Allow-Origin', '*');\n response.headers.set('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');\n response.headers.set('Access-Control-Allow-Headers', 'Content-Type, Authorization, X-Requested-With');\n\n return response;\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : '获取项目环境配置失败';\n console.error('获取所有项目环境配置失败:', error);\n const errorResponse = NextResponse.json(\n { success: false, error: errorMessage },\n { status: 500 },\n );\n\n // 为错误响应也添加CORS headers\n errorResponse.headers.set('Access-Control-Allow-Origin', '*');\n errorResponse.headers.set('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');\n errorResponse.headers.set('Access-Control-Allow-Headers', 'Content-Type, Authorization, X-Requested-With');\n\n return errorResponse;\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":"8VAAA,IAAA,EAAA,EAAA,CAAA,CAAA,MAEA,EAAA,EAAA,CAAA,CAAA,OAMO,eAAe,IACpB,GAAI,CACF,MAAM,CAAA,EAAA,EAAA,MAAA,AAAK,EAAE,EAAA,mBAAmB,CAAE,EAAA,GAA5B,MAAqC,CAAC,IAAI,AAAnC,CACf,CAAE,KAAM,CAGN,OADA,MAHkC,AAG5B,EAAmB,CAAC,GACnB,CAAC,CACV,CAEA,GAAI,CACF,IAAM,EAAgB,MAAM,CAAA,EAAA,EAAA,QAAO,AAAP,EAAS,EAAA,mBAAmB,CAAE,GAA9B,MAE5B,GAAI,CAAC,EACH,CAHmC,KAG5B,CAAC,EAEV,IAHoB,GAGb,KAAK,KAAK,CAAC,EACpB,CAAE,MAAO,EAAO,CAGd,MAFA,QAAQ,KAAK,CAAC,iBAAkB,GAE1B,AAAI,MAAM,WAClB,CACF,CAMO,eAAe,EAAmB,CAAsB,EAC7D,IAAM,EAAiB,EAAA,mBAAmB,CAAG,OAC7C,GAAI,CACF,KAFqB,CAEf,CAAA,EAAA,EAAA,SAAA,AAAQ,EAAE,EAAgB,KAAK,SAAS,CAAC,EAAQ,KAAjD,AAAuD,GAAI,SACjE,MAAM,CAAA,EAAA,EAAA,MAAA,AAAK,EAAE,EAAgB,EAAA,mBAAmB,CAClD,CAAE,EADM,IACC,EAAO,CAEd,MAH6B,AAE7B,QAAQ,KAAK,CAAC,cAAe,GACvB,AAAI,MAAM,WAClB,CACF,CAKO,IAAK,EAAA,SAAA,CAAA,mIAAA,mICjDZ,IAAA,EAAA,EAAA,CAAA,CAAA,OACA,EAAA,EAAA,CAAA,CAAA,OAKO,IAAM,EAAmB,CAE9B,eAAgB,CAAA,EAAA,EAAA,IAAA,AAAG,EAAE,CAAA,EAAA,EAAA,OAAA,AAAM,IAAK,YAAa,EAA7B,WAAK,MAGrB,YAAa,IAGb,sBAAuB,KAAK,GAAG,CAAC,EAAG,KAAK,GAAG,CAAC,CAAA,EAAA,EAAA,IAAA,AAAG,IAAI,MAAM,CAAE,IAG3D,iBAH4C,EAGxB,CACtB,EAEa,EAAsB,GAAA,EAAA,IAAA,AAAG,EAAE,CAAA,EAAA,EAAA,OAAA,AAAM,IAAK,cAAhB,UA2B5B,CA3BiC,GA2B5B,EAAA,SAAA,CAAA,6JAAA,23CC/CZ,IAAA,EAAA,EAAA,CAAA,CAAA,OACA,EAAA,EAAA,CAAA,CAAA,OAGO,eAAe,IACpB,OAAO,IAAI,EAAA,YAAY,CAAC,KAAM,CAC5B,OAAQ,IACR,MAFS,EAEA,CACP,8BAA+B,IAC/B,+BAAgC,kCAChC,+BAAgC,gDAChC,yBAA0B,OAC5B,CACF,EACF,CAEO,eAAe,IACpB,GAAI,CAEF,IAAM,EAAiB,MAAM,CAAA,EAAA,EAAA,iBAAA,AAAgB,IAGvC,EAAkB,OAAO,MAHF,CAGS,CAAC,GAAgB,OAAO,CAAC,CAAC,CAAC,EAAa,EAAc,GACnF,OAAO,OAAO,CAAC,EAAc,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,EAAS,EAAU,GAAK,CAAC,aACvE,UACA,EACA,KAAM,EAAU,IAAI,CACpB,KAAM,EAAc,IAAI,CACxB,aAAc,EAAU,YAAY,CACpC,SAAU,EAAU,QAAQ,CAC5B,QAAS,EAAU,OAAO,EAAI,EAAE,CAClC,CAAC,GAGG,EAAW,EAAA,YAAY,CAAC,IAAI,CAAC,CACjC,SAAS,EACT,KAAM,CAFS,CAGf,QAAS,CAAC,KAAK,EAAE,EAAgB,MAAM,CAAC,MAAM,CAAC,AACjD,GAOA,OAJA,EAAS,OAAO,CAAC,GAAG,CAAC,8BAA+B,KACpD,EAAS,OAAO,CAAC,GAAG,CAAC,+BAAgC,mCACrD,EAAS,OAAO,CAAC,GAAG,CAAC,+BAAgC,iDAE9C,CACT,CAAE,MAAO,EAAO,CACd,IAAM,EAAe,aAAiB,MAAQ,EAAM,OAAO,CAAG,aAC9D,QAAQ,KAAK,CAAC,gBAAiB,GAC/B,IAAM,EAAgB,EAAA,YAAY,CAAC,IAAI,CACrC,CAAE,SAAS,EAAO,MAAO,AADL,CACkB,EACtC,CAAE,OAAQ,GAAI,GAQhB,OAJA,EAAc,OAAO,CAAC,GAAG,CAAC,8BAA+B,KACzD,EAAc,OAAO,CAAC,GAAG,CAAC,+BAAgC,mCAC1D,EAAc,OAAO,CAAC,GAAG,CAAC,+BAAgC,iDAEnD,CACT,CACF,gKC7DA,IAAA,EAGO,EAAA,CAFLA,AAEK,CAAA,OACP,EAA0B,EAAyB,CAA1CC,AAA0C,CAAA,GAAA,EAH9B,EAIrB,CADkB,CAD2C,AAEnB,EAAA,CAAjCC,AAAiC,CAFnC,AAEmC,GADhB,CAC8C,GAExE,EAAwC,EAAA,CAAA,CAFjBC,AAEiB,EAA5BC,KAWZ,IAbkC,AAa5BC,EAAc,GAXM,CAWN,EAAIL,AAbkB,YAEF,OAWhBA,CAAoB,CAC1CM,WAAY,CACVC,KAAMN,EAAAA,SAAAA,CAAUO,SAAS,CACzBC,KAAM,+BACNC,SAAU,yBACVC,SAAU,QACVC,WAAY,EACd,EACAC,iBAAkB,mEAClBC,iBAXF,CAA0B,WAYxBV,CACF,GAKM,kBAAEW,CAAgB,sBAAEC,CAAoB,aAAEC,CAAW,CAAE,CAAGZ,EAEhE,SAASH,IACP,MAAA,CAAA,EAAA,EAAOC,UAAAA,EAAY,kBACjBY,uBACAC,CACF,EACF","ignoreList":[3]}
|
|
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/all-projects-envs/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 { NextResponse } from 'next/server';\nimport { getProjectsConfig } from '@/lib/workspace-config';\n\n// 处理预检请求\nexport async function OPTIONS() {\n return new NextResponse(null, {\n status: 200,\n headers: {\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',\n 'Access-Control-Allow-Headers': 'Content-Type, Authorization, X-Requested-With',\n 'Access-Control-Max-Age': '86400',\n },\n });\n}\n\nexport async function GET() {\n try {\n // 读取项目配置文件\n const projectsConfig = await getProjectsConfig();\n \n // 转换数据结构,提取所有项目的环境信息\n const allProjectsEnvs = Object.entries(projectsConfig).flatMap(([projectName, projectConfig]) => {\n return Object.entries(projectConfig.envs).map(([envName, envConfig]) => ({\n projectName,\n envName,\n host: envConfig.host,\n repo: projectConfig.repo,\n currentProxy: envConfig.currentProxy,\n proxyEnv: envConfig.proxyEnv,\n subApps: envConfig.subApps || [],\n }));\n });\n\n const response = NextResponse.json({\n success: true,\n data: allProjectsEnvs,\n message: `成功获取 ${allProjectsEnvs.length} 个环境配置`,\n });\n\n // 添加CORS headers\n response.headers.set('Access-Control-Allow-Origin', '*');\n response.headers.set('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');\n response.headers.set('Access-Control-Allow-Headers', 'Content-Type, Authorization, X-Requested-With');\n\n return response;\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : '获取项目环境配置失败';\n console.error('获取所有项目环境配置失败:', error);\n const errorResponse = NextResponse.json(\n { success: false, error: errorMessage },\n { status: 500 },\n );\n\n // 为错误响应也添加CORS headers\n errorResponse.headers.set('Access-Control-Allow-Origin', '*');\n errorResponse.headers.set('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');\n errorResponse.headers.set('Access-Control-Allow-Headers', 'Content-Type, Authorization, X-Requested-With');\n\n return errorResponse;\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]}
|