prime-dev-cli 1.0.11-beta.1 → 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/lib/mock-file-utils.mjs +103 -0
- package/package.json +5 -3
- 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/open-all-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.endsWith('.cjs') && entry.name !== 'setting.cjs') {\n // 找到 mock 文件,确保对应的 setting.cjs 存在\n const methodDir = join(dirPath);\n const settingPath = join(methodDir, 'setting.cjs');\n const siteName = entry.name.replace('.cjs', '');\n\n try {\n // 检查 setting.cjs 是否存在\n await fs.access(settingPath);\n } catch {\n // setting.cjs 不存在,创建默认的 setting.cjs\n const settingContent = `module.exports = {\n // 当前场景名称\n currentSite: '${siteName}',\n // 开启Mock的场景列表\n open: ['${siteName}']\n};`;\n await fs.writeFile(settingPath, settingContent, 'utf-8');\n }\n\n // 使用require直接导入并更新 setting.cjs\n try {\n const resolvedPath = resolve(settingPath);\n delete require.cache[resolvedPath];\n \n const currentConfig = require(resolvedPath);\n\n // 确保当前场景在 open 数组中\n if (!Array.isArray(currentConfig.open)) {\n currentConfig.open = [];\n }\n if (!currentConfig.open.includes(siteName)) {\n currentConfig.open.push(siteName);\n }\n\n // 更新 setting.cjs 当前开启场景是单项的\n const newContent = `module.exports = {\n // 当前场景名称\n currentSite: '${currentConfig.currentSite || siteName}',\n // 开启Mock的场景列表\n open: ${JSON.stringify(currentConfig.open)}\n};`;\n await fs.writeFile(settingPath, newContent, 'utf-8');\n } catch (parseError) {\n console.warn(`解析setting.cjs失败: ${settingPath}`, 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":"sbAAA,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,MAAM,AAH4B,EAGT,CAAC,GACnB,CAAC,CACV,CAEA,GAAI,CACF,IAAM,EAAgB,MAAM,CAAA,EAAA,EAAA,QAAA,AAAO,EAAE,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,GAAA,EAAA,SAAA,AAAQ,EAAE,EAAgB,KAAK,SAAS,CAAC,EAAQ,KAAM,AAAvD,GAA2D,SACjE,MAAM,CAAA,EAAA,EAAA,MAAA,AAAK,EAAE,EAAgB,EAAA,mBAAmB,CAClD,CAAE,EADM,IACC,EAAO,CAEd,MADA,AAF6B,QAErB,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,CAAA,EAAA,EAAA,IAAA,AAAG,EAAE,CAAA,EAAA,EAAA,OAAA,AAAM,IAAK,cAAhB,UA2B5B,CA3BiC,GA2B5B,EAAA,SAAA,CAAA,6JAAA,+8CC/CZ,IAAA,EAAA,EAAA,CAAA,CAAA,OACA,EAAA,EAAA,CAAA,CAAA,OACA,EAAA,EAAA,CAAA,CAAA,OACA,EAAA,EAAA,CAAA,CAAA,OACA,EAAA,EAAA,CAAA,CAAA,OAEA,IAAM,EAAU,GADhB,AACgB,EADhB,CAAA,CAAA,OACgB,aAAA,AAAY,EAAE,YAAd,6EAA0B,GAAG,EAEtC,eAAe,EAAK,CAAoB,EAC7C,GAAI,CAEF,GAAM,aAAE,CAAW,CAAE,CAAG,MAAM,EAAQ,IAAI,GAE1C,GAAI,CAAC,EACH,OAAO,EAAA,EADS,UACG,CAAC,IAAI,CACtB,CAAE,SAAS,EAAO,MADb,AACoB,UAAW,EACpC,CAAE,OAAQ,GAAI,GAMlB,GAAI,CADmB,AAClB,OADwB,CAAA,EAAA,EAAA,iBAAA,AAAgB,GAAA,CAC1B,CAAC,EAAY,CAC9B,CADgC,MACzB,EAAA,EAFoB,UAER,CAAC,IAAI,CACtB,CAAE,QAAS,GAAO,MAAO,AADpB,CACqB,GAAG,EAAE,EAAY,IAAI,CAAC,AAAC,EACjD,CAAE,OAAQ,GAAI,GAKlB,IAAM,EAAc,CAAA,EAAA,EAAA,IAAA,AAAG,EAAE,EAAA,gBAAgB,CAAC,WAAtB,GAAoC,CAAE,GACpD,CADmB,CACR,CAAA,EAAA,EAAA,IAAA,AAAG,EAAE,EAAa,SAGnC,GAAI,CACF,MAAM,EAAA,OAJS,CAIP,CAAC,MAAM,CAAC,EAClB,CAAE,KAAM,CACN,OAAO,EAAA,EAFD,UAEa,CAAC,IAAI,CAAC,CACvB,SAAS,EACT,MAFK,EAEI,iBACT,KAAM,aACJ,EACA,UAAW,IAAI,OAAO,WAAW,EACnC,CACF,EACF,CAGA,IAAM,EAAmB,MAAO,IAG9B,IAAK,IAAM,KAFK,IAEI,EAFE,EAAA,QAAE,CAAC,OAAO,CAAC,EAAS,CAAE,eAAe,CAArC,AAA0C,EAAA,EAEnC,CAC3B,IAAM,EAAW,CAAA,EAAA,EAAA,IAAA,AAAG,EAAE,EAAS,EAAM,IAAI,EAEzC,GAAI,EAAM,WAAW,GAEnB,CAFuB,AAFR,KAIT,EAAiB,QAClB,GAAI,EAAM,IAAI,CAAC,QAAQ,CAAC,SAAW,AAAe,kBAAT,IAAI,CAAoB,CAEtE,IAAM,EAAY,CAAA,EAAA,EAAA,IAAA,AAAG,EAAE,GACjB,EAAc,GAAA,EAAA,IAAA,AAAG,EAAE,EAAW,YADlB,GAEZ,EAAW,EAAM,IAAI,CAAC,IADR,GACe,CAAC,OAAQ,IAE5C,GAAI,CAEF,MAAM,EAAA,QAAE,CAAC,MAAM,CAAC,EAClB,CAAE,KAAM,CAEN,IAAM,EAAiB,CAAC,IAHlB;;gBAKF,EAAE,EAAS;;UAEjB,EAAE,EAAS;EACnB,CAAC,AACS,OAAM,EAAA,QAAE,CAAC,SAAS,CAAC,EAAa,EAAgB,QAClD,CAGA,GAAI,CACF,AALM,IAKA,EAAe,CAAA,EAAA,EAAA,OAAA,AAAM,EAAE,EAC7B,QAAO,EAAQ,KAAK,CAAC,EAAa,CAElC,IAAM,EAHe,AAGC,EAAQ,EAG1B,CAAC,MAAM,OAAO,CAAC,EAAc,IAAI,GAAG,AACtC,GAAc,IAAI,CAAG,EAAA,AAAE,EAErB,AAAC,EAAc,IAAI,CAAC,QAAQ,CAAC,IAC/B,EAAc,IAAI,CAAC,AADuB,IACnB,CAAC,GAI1B,IAAM,EAAa,CAAC;;gBAEhB,EAAE,EAAc,WAAW,EAAI,EAAS;;QAEhD,EAAE,KAAK,SAAS,CAAC,EAAc,IAAI,EAAE;EAC3C,CACU,AADT,OACe,EAAA,QAAE,CAAC,SAAS,CAAC,EAAa,EAAY,QAC9C,CAAE,IADM,EACC,EAAY,CACnB,QAAQ,IAAI,CAAC,CAAC,iBAAiB,EAAE,EAAA,CAAa,CAAE,EAClD,CACF,CACF,CACF,EAKA,OAFA,MAAM,EAAiB,GAEhB,EAAA,YAAY,CAAC,IAAI,CAAC,CACvB,SAAS,EACT,MAFK,EAEI,cACT,KAAM,aACJ,EACA,UAAW,IAAI,OAAO,WAAW,EACnC,CACF,EAEF,CAAE,MAAO,EAAO,CACd,IAAM,EAAe,aAAiB,MAAQ,EAAM,OAAO,CAAG,aAE9D,OADA,QAAQ,KAAK,CAAC,cAAe,GACtB,EAAA,YAAY,CAAC,IAAI,CACtB,CAAE,SAAS,EAAO,MADb,AACoB,CAAa,EACtC,CAAE,OAAQ,GAAI,EAElB,CACF,iKC/HA,IAAA,EAGO,EAAA,CAFLA,AAEK,CAAA,OACP,EAA0B,EAAyB,CAA1CC,AAA0C,CAAA,GAAA,EAH9B,EAIrB,CADkB,CACwB,AAFmB,EAEnB,CAAjCC,AAAiC,CAFnC,AAEmC,GADhB,CAC8C,GAExE,EAAwC,EAAA,CAAA,CAFjBC,AAEiB,EAA5BC,KAWZ,IAbkC,AAa5BC,EAAc,GAXM,CAWN,EAbsB,AAalBL,YAXgB,OAWhBA,CAAoB,CAC1CM,WAAY,CACVC,KAAMN,EAAAA,SAAAA,CAAUO,SAAS,CACzBC,KAAM,2BACNC,SAAU,qBACVC,SAAU,QACVC,WAAY,EACd,EACAC,iBAAkB,+DAClBC,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/open-all-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.endsWith('.cjs') && entry.name !== 'setting.cjs') {\n // 找到 mock 文件,确保对应的 setting.cjs 存在\n const methodDir = join(dirPath);\n const settingPath = join(methodDir, 'setting.cjs');\n const siteName = entry.name.replace('.cjs', '');\n\n try {\n // 检查 setting.cjs 是否存在\n await fs.access(settingPath);\n } catch {\n // setting.cjs 不存在,创建默认的 setting.cjs\n const settingContent = `module.exports = {\n // 当前场景名称\n currentSite: '${siteName}',\n // 开启Mock的场景列表\n open: ['${siteName}']\n};`;\n await fs.writeFile(settingPath, settingContent, 'utf-8');\n }\n\n // 使用require直接导入并更新 setting.cjs\n try {\n const resolvedPath = resolve(settingPath);\n delete require.cache[resolvedPath];\n \n const currentConfig = require(resolvedPath);\n\n // 确保当前场景在 open 数组中\n if (!Array.isArray(currentConfig.open)) {\n currentConfig.open = [];\n }\n if (!currentConfig.open.includes(siteName)) {\n currentConfig.open.push(siteName);\n }\n\n // 更新 setting.cjs 当前开启场景是单项的\n const newContent = `module.exports = {\n // 当前场景名称\n currentSite: '${currentConfig.currentSite || siteName}',\n // 开启Mock的场景列表\n open: ${JSON.stringify(currentConfig.open)}\n};`;\n await fs.writeFile(settingPath, newContent, 'utf-8');\n } catch (parseError) {\n console.warn(`解析setting.cjs失败: ${settingPath}`, 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,7 +1,7 @@
|
|
|
1
|
-
module.exports={45935:function(e){var{g:t,__dirname:n,m:o,e:r}=e;o.exports=e.x("next/dist/server/app-render/after-task-async-storage.external.js",()=>require("next/dist/server/app-render/after-task-async-storage.external.js"))},35692:e=>{"use strict";var{g:t,__dirname:n}=e;e.s({ProjectStatus:()=>c,getProjectsConfig:()=>s,saveProjectsConfig:()=>a});var o=e.i(9892),r=e.i(88941);async function s(){try{await (0,o.access)(r.PROJECT_CONFIG_PATH,o.constants.F_OK)}catch{return await a({}),{}}try{let e=await (0,o.readFile)(r.PROJECT_CONFIG_PATH,"utf-8");if(!e)return{};return JSON.parse(e)}catch(e){throw console.error("读取或解析项目配置文件失败:",e),Error("无法加载项目配置")}}async function a(e){let t=r.PROJECT_CONFIG_PATH+".tmp";try{await (0,o.writeFile)(t,JSON.stringify(e,null,2),"utf-8"),await (0,o.rename)(t,r.PROJECT_CONFIG_PATH)}catch(e){throw console.error("保存项目配置文件失败:",e),Error("无法保存项目配置")}}var c=function(e){return e.PENDING="pending",e.EXISTING="existing",e.CLONING="cloning",e.SUCCESS="success",e.FAILED="failed",e.RETRYING="retrying",e}({})},
|
|
1
|
+
module.exports={45935:function(e){var{g:t,__dirname:n,m:o,e:r}=e;o.exports=e.x("next/dist/server/app-render/after-task-async-storage.external.js",()=>require("next/dist/server/app-render/after-task-async-storage.external.js"))},35692:e=>{"use strict";var{g:t,__dirname:n}=e;e.s({ProjectStatus:()=>c,getProjectsConfig:()=>s,saveProjectsConfig:()=>a});var o=e.i(9892),r=e.i(88941);async function s(){try{await (0,o.access)(r.PROJECT_CONFIG_PATH,o.constants.F_OK)}catch{return await a({}),{}}try{let e=await (0,o.readFile)(r.PROJECT_CONFIG_PATH,"utf-8");if(!e)return{};return JSON.parse(e)}catch(e){throw console.error("读取或解析项目配置文件失败:",e),Error("无法加载项目配置")}}async function a(e){let t=r.PROJECT_CONFIG_PATH+".tmp";try{await (0,o.writeFile)(t,JSON.stringify(e,null,2),"utf-8"),await (0,o.rename)(t,r.PROJECT_CONFIG_PATH)}catch(e){throw console.error("保存项目配置文件失败:",e),Error("无法保存项目配置")}}var c=function(e){return e.PENDING="pending",e.EXISTING="existing",e.CLONING="cloning",e.SUCCESS="success",e.FAILED="failed",e.RETRYING="retrying",e}({})},29549:function(e){var{g:t,__dirname:n,m:o,e:r}=e;o.exports=e.x("next/dist/compiled/next-server/app-page-turbo.runtime.prod.js",()=>require("next/dist/compiled/next-server/app-page-turbo.runtime.prod.js"))},83943:function(e){var{g:t,__dirname:n,m:o,e:r}=e;o.exports=e.x("next/dist/server/app-render/work-unit-async-storage.external.js",()=>require("next/dist/server/app-render/work-unit-async-storage.external.js"))},86103:function(e){var{g:t,__dirname:n,m:o,e:r}=e;o.exports=e.x("next/dist/server/app-render/work-async-storage.external.js",()=>require("next/dist/server/app-render/work-async-storage.external.js"))},30331:function(e){var{g:t,__dirname:n,m:o,e:r}=e;o.exports=e.x("path",()=>require("path"))},23430:function(e){var{g:t,__dirname:n,m:o,e:r}=e;o.exports=e.x("next/dist/compiled/@opentelemetry/api",()=>require("next/dist/compiled/@opentelemetry/api"))},13442:function(e){var{g:t,__dirname:n,m:o,e:r}=e;o.exports=e.x("os",()=>require("os"))},52670:function(e){var{g:t,__dirname:n,m:o,e:r}=e;o.exports=e.x("next/dist/compiled/next-server/app-route-turbo.runtime.prod.js",()=>require("next/dist/compiled/next-server/app-route-turbo.runtime.prod.js"))},88941:e=>{"use strict";var{g:t,__dirname:n}=e;{e.s({PROJECT_CONFIG_PATH:()=>n,ProjectStatus:()=>s,WORKSPACE_CONFIG:()=>t});var o=e.i(13442),r=e.i(30331);let t={WORKSPACE_ROOT:(0,r.join)((0,o.homedir)(),"Documents","prime-workspace"),GIT_TIMEOUT:3e5,MAX_CONCURRENT_CLONES:Math.max(2,Math.min((0,o.cpus)().length,8)),MAX_RETRY_ATTEMPTS:3},n=(0,r.join)((0,o.homedir)(),".prime-projects.json");var s=function(e){return e.PENDING="pending",e.EXISTING="existing",e.CLONING="cloning",e.SUCCESS="success",e.FAILED="failed",e.RETRYING="retrying",e.INCOMPLETE="incomplete",e}({})}},9892:function(e){var{g:t,__dirname:n,m:o,e:r}=e;o.exports=e.x("fs/promises",()=>require("fs/promises"))},94722:e=>{"use strict";var{g:t,__dirname:n}=e;{e.s({sseConnectionManager:()=>n});class t{connections=new Map;encoder=new TextEncoder;heartbeatInterval=null;HEARTBEAT_INTERVAL=3e4;CONNECTION_TIMEOUT=12e4;constructor(){this.startHeartbeat()}addConnection(e,t,n){console.log(`[SSE] 添加连接: 环境=${e}, 客户端=${n}`);let o={controller:t,timestamp:Date.now(),clientId:n,envName:e};this.connections.has(e)||this.connections.set(e,new Set),this.connections.get(e).add(o),this.sendToConnection(o,{type:"heartbeat",timestamp:Date.now()}),console.log(`[SSE] 当前连接统计: ${this.getConnectionStats()}`)}removeConnection(e,t){console.log(`[SSE] 移除连接: 环境=${e}, 客户端=${t}`);let n=this.connections.get(e);if(n){let o=Array.from(n).find(e=>e.clientId===t);o&&(n.delete(o),0===n.size&&this.connections.delete(e))}console.log(`[SSE] 当前连接统计: ${this.getConnectionStats()}`)}broadcastToEnv(e,t){console.log(`[SSE] 向环境 ${e} 广播配置变化消息`);let n=this.connections.get(e);if(!n||0===n.size)return void console.log(`[SSE] 环境 ${e} 没有活跃连接,跳过广播`);let o=[];n.forEach(e=>{try{this.sendToConnection(e,t)}catch(t){console.error(`[SSE] 发送消息到客户端 ${e.clientId} 失败:`,t),o.push(e)}}),o.forEach(e=>{n.delete(e),console.log(`[SSE] 清理无效连接: 客户端=${e.clientId}`)}),console.log(`[SSE] 成功发送给 ${n.size} 个连接`)}sendToConnection(e,t){let n=`data: ${JSON.stringify(t)}
|
|
2
2
|
|
|
3
3
|
`,o=this.encoder.encode(n);try{e.controller.enqueue(o),e.timestamp=Date.now()}catch(e){throw console.error(`[SSE] 发送消息失败:`,e),e}}startHeartbeat(){this.heartbeatInterval=setInterval(()=>{this.sendHeartbeat(),this.cleanupStaleConnections()},this.HEARTBEAT_INTERVAL),console.log(`[SSE] 心跳机制已启动,间隔: ${this.HEARTBEAT_INTERVAL}ms`)}sendHeartbeat(){let e={type:"heartbeat",timestamp:Date.now()},t=0;this.connections.forEach(n=>{t+=n.size;let o=[];n.forEach(t=>{try{this.sendToConnection(t,e)}catch{o.push(t)}}),o.forEach(e=>n.delete(e))}),t>0&&console.log(`[SSE] 心跳发送完成,活跃连接数: ${t}`)}cleanupStaleConnections(){let e=Date.now(),t=0;this.connections.forEach((n,o)=>{let r=[];n.forEach(t=>{e-t.timestamp>this.CONNECTION_TIMEOUT&&r.push(t)}),r.forEach(e=>{n.delete(e),t++,console.log(`[SSE] 清理过期连接: 环境=${o}, 客户端=${e.clientId}`)}),0===n.size&&this.connections.delete(o)}),t>0&&console.log(`[SSE] 连接清理完成,清理数量: ${t}`)}getConnectionStats(){let e=[],t=0;return this.connections.forEach((n,o)=>{let r=n.size;t+=r,e.push(`${o}: ${r}`)}),`总计 ${t} 个连接 (${e.join(", ")})`}stop(){this.heartbeatInterval&&(clearInterval(this.heartbeatInterval),this.heartbeatInterval=null,console.log(`[SSE] 心跳机制已停止`)),this.connections.forEach(e=>{e.forEach(e=>{try{e.controller.close()}catch(e){console.error(`[SSE] 关闭连接失败:`,e)}})}),this.connections.clear(),console.log(`[SSE] 所有连接已关闭`)}}let n=new t;process.on("SIGINT",()=>{console.log("[SSE] 收到退出信号,正在清理连接..."),n.stop(),process.exit(0)}),process.on("SIGTERM",()=>{console.log("[SSE] 收到终止信号,正在清理连接..."),n.stop(),process.exit(0)})}},90449:function(e){var{g:t,__dirname:n,m:o,e:r}=e},36628:e=>{"use strict";var{g:t,__dirname:n}=e;e.s({GET:()=>a,OPTIONS:()=>c});var o=e.i(15494),r=e.i(94722),s=e.i(35692);async function a(e){let{searchParams:t}=new URL(e.url),n=t.get("env"),a=t.get("clientId")||`client-${Date.now()}-${Math.random().toString(36).substr(2,9)}`;if(!n)return o.NextResponse.json({success:!1,error:"缺少必要参数:env(环境名称)"},{status:400});try{let e=await (0,s.getProjectsConfig)(),t=!1;for(let[,o]of Object.entries(e))if(o.envs&&o.envs[n]){t=!0;break}if(!t)return o.NextResponse.json({success:!1,error:`环境 "${n}" 不存在于任何项目中`},{status:404});console.log(`[SSE] 新的连接请求: 环境=${n}, 客户端=${a}`);let c=new TextEncoder,i=new ReadableStream({start(e){r.sseConnectionManager.addConnection(n,e,a);let t={type:"connection-established",envName:n,clientId:a,timestamp:Date.now(),message:`已连接到环境 ${n} 的配置变化推送流`},o=`data: ${JSON.stringify(t)}
|
|
4
4
|
|
|
5
5
|
`;e.enqueue(c.encode(o))},cancel(){console.log(`[SSE] 连接取消: 环境=${n}, 客户端=${a}`),r.sseConnectionManager.removeConnection(n,a)}});return new Response(i,{status:200,headers:{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive","Access-Control-Allow-Origin":"*","Access-Control-Allow-Methods":"GET","Access-Control-Allow-Headers":"Cache-Control, Content-Type"}})}catch(t){let e=t instanceof Error?t.message:"SSE连接建立失败";return console.error(`[SSE] 连接建立失败: 环境=${n}, 客户端=${a}`,t),o.NextResponse.json({success:!1,error:e},{status:500})}}async function c(){return new Response(null,{status:200,headers:{"Access-Control-Allow-Origin":"*","Access-Control-Allow-Methods":"GET, OPTIONS","Access-Control-Allow-Headers":"Content-Type, Cache-Control","Access-Control-Max-Age":"86400"}})}},61976:e=>{"use strict";var{g:t,__dirname:n}=e;{e.s({patchFetch:()=>c,routeModule:()=>t,serverHooks:()=>l,workAsyncStorage:()=>n,workUnitAsyncStorage:()=>i});var o=e.i(45746),r=e.i(93828),s=e.i(18250),a=e.i(36628);let t=new o.AppRouteRouteModule({definition:{kind:r.RouteKind.APP_ROUTE,page:"/api/microapp-proxy-change-stream/route",pathname:"/api/microapp-proxy-change-stream",filename:"route",bundlePath:""},resolvedPagePath:"[project]/packages/server/src/app/api/microapp-proxy-change-stream/route.ts",nextConfigOutput:"",userland:a}),{workAsyncStorage:n,workUnitAsyncStorage:i,serverHooks:l}=t;function c(){return(0,s.patchFetch)({workAsyncStorage:n,workUnitAsyncStorage:i})}}}};
|
|
6
6
|
|
|
7
|
-
//# sourceMappingURL=%5Broot-of-the-server%
|
|
7
|
+
//# sourceMappingURL=%5Broot-of-the-server%5D__ef09a48e._.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/sse-connection-manager.ts","turbopack:///[project]/packages/server/src/app/api/microapp-proxy-change-stream/route.ts","turbopack:///[project]/node_modules/.pnpm/next@15.3.4_react-dom@19.1.0_react@19.1.0__react@19.1.0/node_modules/next/dist/src/build/templates/app-route.ts"],"sourcesContent":["import { readFile, writeFile, access, constants, rename } from 'fs/promises';\nimport type { ProjectsConfig } from './workspace-types';\nimport { PROJECT_CONFIG_PATH } from './workspace-types';\n\n/**\n * 读取并解析项目配置文件\n * @returns {Promise<ProjectsConfig>} 项目配置对象\n */\nexport async function getProjectsConfig(): Promise<ProjectsConfig> {\n try {\n await access(PROJECT_CONFIG_PATH, constants.F_OK);\n } catch {\n // 文件不存在,创建并写入空对象\n await saveProjectsConfig({});\n return {};\n }\n\n try {\n const configContent = await readFile(PROJECT_CONFIG_PATH, 'utf-8');\n // 如果文件为空,返回空对象\n if (!configContent) {\n return {};\n }\n return JSON.parse(configContent);\n } catch (error) {\n console.error('读取或解析项目配置文件失败:', error);\n // 在出错时返回空对象或抛出错误,这里选择抛出以通知调用者\n throw new Error('无法加载项目配置');\n }\n}\n\n/**\n * 将项目配置写入文件(原子操作)\n * @param {ProjectsConfig} config - 要保存的配置对象\n */\nexport async function saveProjectsConfig(config: ProjectsConfig): Promise<void> {\n const tempConfigPath = PROJECT_CONFIG_PATH + '.tmp';\n try {\n await writeFile(tempConfigPath, JSON.stringify(config, null, 2), 'utf-8');\n await rename(tempConfigPath, PROJECT_CONFIG_PATH);\n } catch (error) {\n console.error('保存项目配置文件失败:', error);\n throw new Error('无法保存项目配置');\n }\n}\n\n/**\n * 项目状态枚举\n */\nexport enum ProjectStatus {\n PENDING = 'pending',\n EXISTING = 'existing',\n CLONING = 'cloning',\n SUCCESS = 'success',\n FAILED = 'failed',\n RETRYING = 'retrying',\n}\n\n/**\n * 项目进度信息接口\n */\nexport interface ProjectProgress {\n projectName: string;\n status: ProjectStatus;\n progress: number; // 0-100\n message: string;\n error?: string;\n startTime?: number;\n endTime?: number;\n}\n\n/**\n * 初始化结果接口\n */\nexport interface InitializationResult {\n success: boolean;\n totalProjects: number;\n successCount: number;\n failedCount: number;\n failedProjects: string[];\n workspacePath: string;\n duration: number;\n}\n\n/**\n * Git 操作配置接口\n */\nexport interface GitOperationConfig {\n repoUrl: string;\n targetDir: string;\n timeout: number;\n onProgress?: (progress: number, message: string) => void;\n onError?: (error: string) => void;\n}","import { homedir, cpus } from 'os';\nimport { join } from 'path';\n\n/**\n * 工作空间配置常量\n */\nexport const WORKSPACE_CONFIG = {\n // 工作空间根目录路径\n WORKSPACE_ROOT: join(homedir(), 'Documents', 'prime-workspace'),\n\n // Git 操作超时时间 (毫秒)\n GIT_TIMEOUT: 300000, // 5分钟\n\n // 最大并发克隆数量(基于CPU核心数,最小2个,最大8个)\n MAX_CONCURRENT_CLONES: Math.max(2, Math.min(cpus().length, 8)),\n\n // 重试次数限制\n MAX_RETRY_ATTEMPTS: 3,\n} as const;\n\nexport const PROJECT_CONFIG_PATH = join(homedir(), '.prime-projects.json');\n\nexport interface ProjectConfig {\n repo: string;\n mockingIntercept?: boolean;\n mockOpen?: boolean;\n envs: {\n [envName: string]: {\n host: string;\n currentProxy: string;\n proxyEnv: {\n [key: string]: string;\n };\n envFileName: string;\n proxyKey: string;\n subApps?: string[];\n };\n };\n}\n\nexport interface ProjectsConfig {\n [projectName: string]: ProjectConfig;\n}\n\n/**\n * 项目状态枚举\n */\nexport enum ProjectStatus {\n PENDING = 'pending',\n EXISTING = 'existing',\n CLONING = 'cloning',\n SUCCESS = 'success',\n FAILED = 'failed',\n RETRYING = 'retrying',\n INCOMPLETE = 'incomplete', // 不完整的项目,需要清理\n}\n\n/**\n * 项目进度信息接口\n */\nexport interface ProjectProgress {\n projectName: string;\n status: ProjectStatus;\n progress: number; // 0-100\n message: string;\n error?: string;\n startTime?: number;\n endTime?: number;\n}\n\n/**\n * 初始化结果接口\n */\nexport interface InitializationResult {\n success: boolean;\n totalProjects: number;\n successCount: number;\n failedCount: number;\n failedProjects: string[];\n workspacePath: string;\n duration: number;\n}\n\n/**\n * Git 操作配置接口\n */\nexport interface GitOperationConfig {\n repoUrl: string;\n targetDir: string;\n timeout: number;\n onProgress?: (progress: number, message: string) => void;\n onError?: (error: string) => void;\n onLog?: (projectName: string, logType: 'stdout' | 'stderr' | 'progress', content: string) => void;\n} ","/**\n * SSE连接管理器\n * 用于管理MicroApp代理配置变化推送的SSE连接\n */\n\nexport interface ConnectionInfo {\n controller: ReadableStreamDefaultController<Uint8Array>;\n timestamp: number;\n clientId: string;\n envName: string;\n}\n\nexport interface ConfigChangeMessage {\n type: 'microapp-proxy-config-change';\n envName: string;\n timestamp: number;\n changes: {\n before: string[];\n after: string[];\n added: string[];\n removed: string[];\n };\n projectName: string;\n message: string;\n}\n\nexport interface HeartbeatMessage {\n type: 'heartbeat';\n timestamp: number;\n}\n\ntype SSEMessage = ConfigChangeMessage | HeartbeatMessage;\n\n/**\n * SSE连接管理器类\n */\nclass SSEConnectionManager {\n private connections = new Map<string, Set<ConnectionInfo>>();\n private encoder = new TextEncoder();\n private heartbeatInterval: NodeJS.Timeout | null = null;\n private readonly HEARTBEAT_INTERVAL = 30000; // 30秒心跳\n private readonly CONNECTION_TIMEOUT = 120000; // 2分钟连接超时\n\n constructor() {\n this.startHeartbeat();\n }\n\n /**\n * 添加新的SSE连接\n */\n addConnection(envName: string, controller: ReadableStreamDefaultController<Uint8Array>, clientId: string): void {\n console.log(`[SSE] 添加连接: 环境=${envName}, 客户端=${clientId}`);\n \n const connectionInfo: ConnectionInfo = {\n controller,\n timestamp: Date.now(),\n clientId,\n envName,\n };\n\n if (!this.connections.has(envName)) {\n this.connections.set(envName, new Set());\n }\n \n this.connections.get(envName)!.add(connectionInfo);\n \n // 发送连接确认消息\n this.sendToConnection(connectionInfo, {\n type: 'heartbeat',\n timestamp: Date.now(),\n });\n\n console.log(`[SSE] 当前连接统计: ${this.getConnectionStats()}`);\n }\n\n /**\n * 移除SSE连接\n */\n removeConnection(envName: string, clientId: string): void {\n console.log(`[SSE] 移除连接: 环境=${envName}, 客户端=${clientId}`);\n \n const connections = this.connections.get(envName);\n if (connections) {\n const connectionToRemove = Array.from(connections).find(conn => conn.clientId === clientId);\n if (connectionToRemove) {\n connections.delete(connectionToRemove);\n \n // 如果该环境没有连接了,删除整个entry\n if (connections.size === 0) {\n this.connections.delete(envName);\n }\n }\n }\n\n console.log(`[SSE] 当前连接统计: ${this.getConnectionStats()}`);\n }\n\n /**\n * 向指定环境广播消息\n */\n broadcastToEnv(envName: string, message: ConfigChangeMessage): void {\n console.log(`[SSE] 向环境 ${envName} 广播配置变化消息`);\n \n const connections = this.connections.get(envName);\n if (!connections || connections.size === 0) {\n console.log(`[SSE] 环境 ${envName} 没有活跃连接,跳过广播`);\n return;\n }\n\n const deadConnections: ConnectionInfo[] = [];\n \n connections.forEach(connectionInfo => {\n try {\n this.sendToConnection(connectionInfo, message);\n } catch (error) {\n console.error(`[SSE] 发送消息到客户端 ${connectionInfo.clientId} 失败:`, error);\n deadConnections.push(connectionInfo);\n }\n });\n\n // 清理无效连接\n deadConnections.forEach(conn => {\n connections.delete(conn);\n console.log(`[SSE] 清理无效连接: 客户端=${conn.clientId}`);\n });\n\n console.log(`[SSE] 成功发送给 ${connections.size} 个连接`);\n }\n\n /**\n * 向单个连接发送消息\n */\n private sendToConnection(connectionInfo: ConnectionInfo, message: SSEMessage): void {\n const data = `data: ${JSON.stringify(message)}\\n\\n`;\n const encodedData = this.encoder.encode(data);\n \n try {\n connectionInfo.controller.enqueue(encodedData);\n connectionInfo.timestamp = Date.now(); // 更新最后活跃时间\n } catch (error) {\n console.error(`[SSE] 发送消息失败:`, error);\n throw error;\n }\n }\n\n /**\n * 启动心跳机制\n */\n private startHeartbeat(): void {\n this.heartbeatInterval = setInterval(() => {\n this.sendHeartbeat();\n this.cleanupStaleConnections();\n }, this.HEARTBEAT_INTERVAL);\n \n console.log(`[SSE] 心跳机制已启动,间隔: ${this.HEARTBEAT_INTERVAL}ms`);\n }\n\n /**\n * 发送心跳消息\n */\n private sendHeartbeat(): void {\n const heartbeatMessage: HeartbeatMessage = {\n type: 'heartbeat',\n timestamp: Date.now(),\n };\n\n let totalConnections = 0;\n this.connections.forEach((connections) => {\n totalConnections += connections.size;\n const deadConnections: ConnectionInfo[] = [];\n \n connections.forEach(connectionInfo => {\n try {\n this.sendToConnection(connectionInfo, heartbeatMessage);\n } catch {\n deadConnections.push(connectionInfo);\n }\n });\n\n // 清理无效连接\n deadConnections.forEach(conn => connections.delete(conn));\n });\n\n if (totalConnections > 0) {\n console.log(`[SSE] 心跳发送完成,活跃连接数: ${totalConnections}`);\n }\n }\n\n /**\n * 清理过期连接\n */\n private cleanupStaleConnections(): void {\n const now = Date.now();\n let cleanedCount = 0;\n\n this.connections.forEach((connections, envName) => {\n const staleConnections: ConnectionInfo[] = [];\n \n connections.forEach(connectionInfo => {\n if (now - connectionInfo.timestamp > this.CONNECTION_TIMEOUT) {\n staleConnections.push(connectionInfo);\n }\n });\n\n staleConnections.forEach(conn => {\n connections.delete(conn);\n cleanedCount++;\n console.log(`[SSE] 清理过期连接: 环境=${envName}, 客户端=${conn.clientId}`);\n });\n\n // 如果该环境没有连接了,删除整个entry\n if (connections.size === 0) {\n this.connections.delete(envName);\n }\n });\n\n if (cleanedCount > 0) {\n console.log(`[SSE] 连接清理完成,清理数量: ${cleanedCount}`);\n }\n }\n\n /**\n * 获取连接统计信息\n */\n getConnectionStats(): string {\n const stats: string[] = [];\n let totalConnections = 0;\n \n this.connections.forEach((connections, envName) => {\n const count = connections.size;\n totalConnections += count;\n stats.push(`${envName}: ${count}`);\n });\n\n return `总计 ${totalConnections} 个连接 (${stats.join(', ')})`;\n }\n\n /**\n * 停止连接管理器\n */\n stop(): void {\n if (this.heartbeatInterval) {\n clearInterval(this.heartbeatInterval);\n this.heartbeatInterval = null;\n console.log(`[SSE] 心跳机制已停止`);\n }\n\n // 关闭所有连接\n this.connections.forEach((connections) => {\n connections.forEach(connectionInfo => {\n try {\n connectionInfo.controller.close();\n } catch (error) {\n console.error(`[SSE] 关闭连接失败:`, error);\n }\n });\n });\n\n this.connections.clear();\n console.log(`[SSE] 所有连接已关闭`);\n }\n}\n\n// 创建全局实例\nexport const sseConnectionManager = new SSEConnectionManager();\n\n// 在进程退出时清理资源\nprocess.on('SIGINT', () => {\n console.log('[SSE] 收到退出信号,正在清理连接...');\n sseConnectionManager.stop();\n process.exit(0);\n});\n\nprocess.on('SIGTERM', () => {\n console.log('[SSE] 收到终止信号,正在清理连接...');\n sseConnectionManager.stop();\n process.exit(0);\n}); ","import { NextRequest, NextResponse } from 'next/server';\nimport { sseConnectionManager } from '@/lib/sse-connection-manager';\nimport { getProjectsConfig } from '@/lib/workspace-config';\n\n/**\n * MicroApp代理配置变化推送 SSE 端点\n * \n * 查询参数:\n * - env: 需要监听的环境名称\n * - clientId: 客户端标识符(可选,用于连接管理)\n */\nexport async function GET(request: NextRequest): Promise<Response> {\n const { searchParams } = new URL(request.url);\n const envName = searchParams.get('env');\n const clientId = searchParams.get('clientId') || `client-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n\n // 参数验证\n if (!envName) {\n return NextResponse.json(\n { \n success: false, \n error: '缺少必要参数:env(环境名称)' \n },\n { status: 400 }\n );\n }\n\n try {\n // 验证环境是否存在\n const projectsConfig = await getProjectsConfig();\n let envExists = false;\n \n // 检查所有项目中是否存在指定环境\n for (const [, projectConfig] of Object.entries(projectsConfig)) {\n if (projectConfig.envs && projectConfig.envs[envName]) {\n envExists = true;\n break;\n }\n }\n\n if (!envExists) {\n return NextResponse.json(\n { \n success: false, \n error: `环境 \"${envName}\" 不存在于任何项目中` \n },\n { status: 404 }\n );\n }\n\n console.log(`[SSE] 新的连接请求: 环境=${envName}, 客户端=${clientId}`);\n\n // 创建SSE流\n const encoder = new TextEncoder();\n \n const stream = new ReadableStream({\n start(controller) {\n // 添加连接到管理器\n sseConnectionManager.addConnection(envName, controller, clientId);\n\n // 发送初始连接成功消息\n const initialMessage = {\n type: 'connection-established' as const,\n envName,\n clientId,\n timestamp: Date.now(),\n message: `已连接到环境 ${envName} 的配置变化推送流`\n };\n\n const data = `data: ${JSON.stringify(initialMessage)}\\n\\n`;\n controller.enqueue(encoder.encode(data));\n },\n\n cancel() {\n // 连接取消时清理\n console.log(`[SSE] 连接取消: 环境=${envName}, 客户端=${clientId}`);\n sseConnectionManager.removeConnection(envName, clientId);\n }\n });\n\n // 返回SSE响应\n return new Response(stream, {\n status: 200,\n headers: {\n 'Content-Type': 'text/event-stream',\n 'Cache-Control': 'no-cache',\n 'Connection': 'keep-alive',\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Methods': 'GET',\n 'Access-Control-Allow-Headers': 'Cache-Control, Content-Type',\n },\n });\n\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'SSE连接建立失败';\n console.error(`[SSE] 连接建立失败: 环境=${envName}, 客户端=${clientId}`, error);\n \n return NextResponse.json(\n { \n success: false, \n error: errorMessage \n },\n { status: 500 }\n );\n }\n}\n\n/**\n * 处理预检请求\n */\nexport async function OPTIONS(): Promise<Response> {\n return new Response(null, {\n status: 200,\n headers: {\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Methods': 'GET, OPTIONS',\n 'Access-Control-Allow-Headers': 'Content-Type, Cache-Control',\n 'Access-Control-Max-Age': '86400',\n },\n });\n} ","import {\n AppRouteRouteModule,\n type AppRouteRouteModuleOptions,\n} from '../../server/route-modules/app-route/module.compiled'\nimport { RouteKind } from '../../server/route-kind'\nimport { patchFetch as _patchFetch } from '../../server/lib/patch-fetch'\n\nimport * as userland from 'VAR_USERLAND'\n\n// These are injected by the loader afterwards. This is injected as a variable\n// instead of a replacement because this could also be `undefined` instead of\n// an empty string.\ndeclare const nextConfigOutput: AppRouteRouteModuleOptions['nextConfigOutput']\n\n// We inject the nextConfigOutput here so that we can use them in the route\n// module.\n// INJECT:nextConfigOutput\n\nconst routeModule = new AppRouteRouteModule({\n definition: {\n kind: RouteKind.APP_ROUTE,\n page: 'VAR_DEFINITION_PAGE',\n pathname: 'VAR_DEFINITION_PATHNAME',\n filename: 'VAR_DEFINITION_FILENAME',\n bundlePath: 'VAR_DEFINITION_BUNDLE_PATH',\n },\n resolvedPagePath: 'VAR_RESOLVED_PAGE_PATH',\n nextConfigOutput,\n userland,\n})\n\n// Pull out the exports that we need to expose from the module. This should\n// be eliminated when we've moved the other routes to the new format. These\n// are used to hook into the route.\nconst { workAsyncStorage, workUnitAsyncStorage, serverHooks } = routeModule\n\nfunction patchFetch() {\n return _patchFetch({\n workAsyncStorage,\n workUnitAsyncStorage,\n })\n}\n\nexport {\n routeModule,\n workAsyncStorage,\n workUnitAsyncStorage,\n serverHooks,\n patchFetch,\n}\n"],"names":["AppRouteRouteModule","RouteKind","patchFetch","_patchFetch","userland","routeModule","definition","kind","APP_ROUTE","page","pathname","filename","bundlePath","resolvedPagePath","nextConfigOutput","workAsyncStorage","workUnitAsyncStorage","serverHooks"],"mappings":"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","ignoreList":[4]}
|
|
1
|
+
{"version":3,"sources":["turbopack:///[project]/packages/server/src/lib/workspace-config.ts","turbopack:///[project]/packages/server/src/lib/workspace-types.ts","turbopack:///[project]/packages/server/src/lib/sse-connection-manager.ts","turbopack:///[project]/packages/server/src/app/api/microapp-proxy-change-stream/route.ts","turbopack:///[project]/node_modules/.pnpm/next@15.3.4_react-dom@19.1.0_react@19.1.0__react@19.1.0/node_modules/next/dist/src/build/templates/app-route.ts"],"sourcesContent":["import { readFile, writeFile, access, constants, rename } from 'fs/promises';\nimport type { ProjectsConfig } from './workspace-types';\nimport { PROJECT_CONFIG_PATH } from './workspace-types';\n\n/**\n * 读取并解析项目配置文件\n * @returns {Promise<ProjectsConfig>} 项目配置对象\n */\nexport async function getProjectsConfig(): Promise<ProjectsConfig> {\n try {\n await access(PROJECT_CONFIG_PATH, constants.F_OK);\n } catch {\n // 文件不存在,创建并写入空对象\n await saveProjectsConfig({});\n return {};\n }\n\n try {\n const configContent = await readFile(PROJECT_CONFIG_PATH, 'utf-8');\n // 如果文件为空,返回空对象\n if (!configContent) {\n return {};\n }\n return JSON.parse(configContent);\n } catch (error) {\n console.error('读取或解析项目配置文件失败:', error);\n // 在出错时返回空对象或抛出错误,这里选择抛出以通知调用者\n throw new Error('无法加载项目配置');\n }\n}\n\n/**\n * 将项目配置写入文件(原子操作)\n * @param {ProjectsConfig} config - 要保存的配置对象\n */\nexport async function saveProjectsConfig(config: ProjectsConfig): Promise<void> {\n const tempConfigPath = PROJECT_CONFIG_PATH + '.tmp';\n try {\n await writeFile(tempConfigPath, JSON.stringify(config, null, 2), 'utf-8');\n await rename(tempConfigPath, PROJECT_CONFIG_PATH);\n } catch (error) {\n console.error('保存项目配置文件失败:', error);\n throw new Error('无法保存项目配置');\n }\n}\n\n/**\n * 项目状态枚举\n */\nexport enum ProjectStatus {\n PENDING = 'pending',\n EXISTING = 'existing',\n CLONING = 'cloning',\n SUCCESS = 'success',\n FAILED = 'failed',\n RETRYING = 'retrying',\n}\n\n/**\n * 项目进度信息接口\n */\nexport interface ProjectProgress {\n projectName: string;\n status: ProjectStatus;\n progress: number; // 0-100\n message: string;\n error?: string;\n startTime?: number;\n endTime?: number;\n}\n\n/**\n * 初始化结果接口\n */\nexport interface InitializationResult {\n success: boolean;\n totalProjects: number;\n successCount: number;\n failedCount: number;\n failedProjects: string[];\n workspacePath: string;\n duration: number;\n}\n\n/**\n * Git 操作配置接口\n */\nexport interface GitOperationConfig {\n repoUrl: string;\n targetDir: string;\n timeout: number;\n onProgress?: (progress: number, message: string) => void;\n onError?: (error: string) => void;\n}","import { homedir, cpus } from 'os';\nimport { join } from 'path';\n\n/**\n * 工作空间配置常量\n */\nexport const WORKSPACE_CONFIG = {\n // 工作空间根目录路径\n WORKSPACE_ROOT: join(homedir(), 'Documents', 'prime-workspace'),\n\n // Git 操作超时时间 (毫秒)\n GIT_TIMEOUT: 300000, // 5分钟\n\n // 最大并发克隆数量(基于CPU核心数,最小2个,最大8个)\n MAX_CONCURRENT_CLONES: Math.max(2, Math.min(cpus().length, 8)),\n\n // 重试次数限制\n MAX_RETRY_ATTEMPTS: 3,\n} as const;\n\nexport const PROJECT_CONFIG_PATH = join(homedir(), '.prime-projects.json');\n\nexport interface ProjectConfig {\n repo: string;\n mockingIntercept?: boolean;\n mockOpen?: boolean;\n envs: {\n [envName: string]: {\n host: string;\n currentProxy: string;\n proxyEnv: {\n [key: string]: string;\n };\n envFileName: string;\n proxyKey: string;\n subApps?: string[];\n };\n };\n}\n\nexport interface ProjectsConfig {\n [projectName: string]: ProjectConfig;\n}\n\n/**\n * 项目状态枚举\n */\nexport enum ProjectStatus {\n PENDING = 'pending',\n EXISTING = 'existing',\n CLONING = 'cloning',\n SUCCESS = 'success',\n FAILED = 'failed',\n RETRYING = 'retrying',\n INCOMPLETE = 'incomplete', // 不完整的项目,需要清理\n}\n\n/**\n * 项目进度信息接口\n */\nexport interface ProjectProgress {\n projectName: string;\n status: ProjectStatus;\n progress: number; // 0-100\n message: string;\n error?: string;\n startTime?: number;\n endTime?: number;\n}\n\n/**\n * 初始化结果接口\n */\nexport interface InitializationResult {\n success: boolean;\n totalProjects: number;\n successCount: number;\n failedCount: number;\n failedProjects: string[];\n workspacePath: string;\n duration: number;\n}\n\n/**\n * Git 操作配置接口\n */\nexport interface GitOperationConfig {\n repoUrl: string;\n targetDir: string;\n timeout: number;\n onProgress?: (progress: number, message: string) => void;\n onError?: (error: string) => void;\n onLog?: (projectName: string, logType: 'stdout' | 'stderr' | 'progress', content: string) => void;\n} ","/**\n * SSE连接管理器\n * 用于管理MicroApp代理配置变化推送的SSE连接\n */\n\nexport interface ConnectionInfo {\n controller: ReadableStreamDefaultController<Uint8Array>;\n timestamp: number;\n clientId: string;\n envName: string;\n}\n\nexport interface ConfigChangeMessage {\n type: 'microapp-proxy-config-change';\n envName: string;\n timestamp: number;\n changes: {\n before: string[];\n after: string[];\n added: string[];\n removed: string[];\n };\n projectName: string;\n message: string;\n}\n\nexport interface HeartbeatMessage {\n type: 'heartbeat';\n timestamp: number;\n}\n\ntype SSEMessage = ConfigChangeMessage | HeartbeatMessage;\n\n/**\n * SSE连接管理器类\n */\nclass SSEConnectionManager {\n private connections = new Map<string, Set<ConnectionInfo>>();\n private encoder = new TextEncoder();\n private heartbeatInterval: NodeJS.Timeout | null = null;\n private readonly HEARTBEAT_INTERVAL = 30000; // 30秒心跳\n private readonly CONNECTION_TIMEOUT = 120000; // 2分钟连接超时\n\n constructor() {\n this.startHeartbeat();\n }\n\n /**\n * 添加新的SSE连接\n */\n addConnection(envName: string, controller: ReadableStreamDefaultController<Uint8Array>, clientId: string): void {\n console.log(`[SSE] 添加连接: 环境=${envName}, 客户端=${clientId}`);\n \n const connectionInfo: ConnectionInfo = {\n controller,\n timestamp: Date.now(),\n clientId,\n envName,\n };\n\n if (!this.connections.has(envName)) {\n this.connections.set(envName, new Set());\n }\n \n this.connections.get(envName)!.add(connectionInfo);\n \n // 发送连接确认消息\n this.sendToConnection(connectionInfo, {\n type: 'heartbeat',\n timestamp: Date.now(),\n });\n\n console.log(`[SSE] 当前连接统计: ${this.getConnectionStats()}`);\n }\n\n /**\n * 移除SSE连接\n */\n removeConnection(envName: string, clientId: string): void {\n console.log(`[SSE] 移除连接: 环境=${envName}, 客户端=${clientId}`);\n \n const connections = this.connections.get(envName);\n if (connections) {\n const connectionToRemove = Array.from(connections).find(conn => conn.clientId === clientId);\n if (connectionToRemove) {\n connections.delete(connectionToRemove);\n \n // 如果该环境没有连接了,删除整个entry\n if (connections.size === 0) {\n this.connections.delete(envName);\n }\n }\n }\n\n console.log(`[SSE] 当前连接统计: ${this.getConnectionStats()}`);\n }\n\n /**\n * 向指定环境广播消息\n */\n broadcastToEnv(envName: string, message: ConfigChangeMessage): void {\n console.log(`[SSE] 向环境 ${envName} 广播配置变化消息`);\n \n const connections = this.connections.get(envName);\n if (!connections || connections.size === 0) {\n console.log(`[SSE] 环境 ${envName} 没有活跃连接,跳过广播`);\n return;\n }\n\n const deadConnections: ConnectionInfo[] = [];\n \n connections.forEach(connectionInfo => {\n try {\n this.sendToConnection(connectionInfo, message);\n } catch (error) {\n console.error(`[SSE] 发送消息到客户端 ${connectionInfo.clientId} 失败:`, error);\n deadConnections.push(connectionInfo);\n }\n });\n\n // 清理无效连接\n deadConnections.forEach(conn => {\n connections.delete(conn);\n console.log(`[SSE] 清理无效连接: 客户端=${conn.clientId}`);\n });\n\n console.log(`[SSE] 成功发送给 ${connections.size} 个连接`);\n }\n\n /**\n * 向单个连接发送消息\n */\n private sendToConnection(connectionInfo: ConnectionInfo, message: SSEMessage): void {\n const data = `data: ${JSON.stringify(message)}\\n\\n`;\n const encodedData = this.encoder.encode(data);\n \n try {\n connectionInfo.controller.enqueue(encodedData);\n connectionInfo.timestamp = Date.now(); // 更新最后活跃时间\n } catch (error) {\n console.error(`[SSE] 发送消息失败:`, error);\n throw error;\n }\n }\n\n /**\n * 启动心跳机制\n */\n private startHeartbeat(): void {\n this.heartbeatInterval = setInterval(() => {\n this.sendHeartbeat();\n this.cleanupStaleConnections();\n }, this.HEARTBEAT_INTERVAL);\n \n console.log(`[SSE] 心跳机制已启动,间隔: ${this.HEARTBEAT_INTERVAL}ms`);\n }\n\n /**\n * 发送心跳消息\n */\n private sendHeartbeat(): void {\n const heartbeatMessage: HeartbeatMessage = {\n type: 'heartbeat',\n timestamp: Date.now(),\n };\n\n let totalConnections = 0;\n this.connections.forEach((connections) => {\n totalConnections += connections.size;\n const deadConnections: ConnectionInfo[] = [];\n \n connections.forEach(connectionInfo => {\n try {\n this.sendToConnection(connectionInfo, heartbeatMessage);\n } catch {\n deadConnections.push(connectionInfo);\n }\n });\n\n // 清理无效连接\n deadConnections.forEach(conn => connections.delete(conn));\n });\n\n if (totalConnections > 0) {\n console.log(`[SSE] 心跳发送完成,活跃连接数: ${totalConnections}`);\n }\n }\n\n /**\n * 清理过期连接\n */\n private cleanupStaleConnections(): void {\n const now = Date.now();\n let cleanedCount = 0;\n\n this.connections.forEach((connections, envName) => {\n const staleConnections: ConnectionInfo[] = [];\n \n connections.forEach(connectionInfo => {\n if (now - connectionInfo.timestamp > this.CONNECTION_TIMEOUT) {\n staleConnections.push(connectionInfo);\n }\n });\n\n staleConnections.forEach(conn => {\n connections.delete(conn);\n cleanedCount++;\n console.log(`[SSE] 清理过期连接: 环境=${envName}, 客户端=${conn.clientId}`);\n });\n\n // 如果该环境没有连接了,删除整个entry\n if (connections.size === 0) {\n this.connections.delete(envName);\n }\n });\n\n if (cleanedCount > 0) {\n console.log(`[SSE] 连接清理完成,清理数量: ${cleanedCount}`);\n }\n }\n\n /**\n * 获取连接统计信息\n */\n getConnectionStats(): string {\n const stats: string[] = [];\n let totalConnections = 0;\n \n this.connections.forEach((connections, envName) => {\n const count = connections.size;\n totalConnections += count;\n stats.push(`${envName}: ${count}`);\n });\n\n return `总计 ${totalConnections} 个连接 (${stats.join(', ')})`;\n }\n\n /**\n * 停止连接管理器\n */\n stop(): void {\n if (this.heartbeatInterval) {\n clearInterval(this.heartbeatInterval);\n this.heartbeatInterval = null;\n console.log(`[SSE] 心跳机制已停止`);\n }\n\n // 关闭所有连接\n this.connections.forEach((connections) => {\n connections.forEach(connectionInfo => {\n try {\n connectionInfo.controller.close();\n } catch (error) {\n console.error(`[SSE] 关闭连接失败:`, error);\n }\n });\n });\n\n this.connections.clear();\n console.log(`[SSE] 所有连接已关闭`);\n }\n}\n\n// 创建全局实例\nexport const sseConnectionManager = new SSEConnectionManager();\n\n// 在进程退出时清理资源\nprocess.on('SIGINT', () => {\n console.log('[SSE] 收到退出信号,正在清理连接...');\n sseConnectionManager.stop();\n process.exit(0);\n});\n\nprocess.on('SIGTERM', () => {\n console.log('[SSE] 收到终止信号,正在清理连接...');\n sseConnectionManager.stop();\n process.exit(0);\n}); ","import { NextRequest, NextResponse } from 'next/server';\nimport { sseConnectionManager } from '@/lib/sse-connection-manager';\nimport { getProjectsConfig } from '@/lib/workspace-config';\n\n/**\n * MicroApp代理配置变化推送 SSE 端点\n * \n * 查询参数:\n * - env: 需要监听的环境名称\n * - clientId: 客户端标识符(可选,用于连接管理)\n */\nexport async function GET(request: NextRequest): Promise<Response> {\n const { searchParams } = new URL(request.url);\n const envName = searchParams.get('env');\n const clientId = searchParams.get('clientId') || `client-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n\n // 参数验证\n if (!envName) {\n return NextResponse.json(\n { \n success: false, \n error: '缺少必要参数:env(环境名称)' \n },\n { status: 400 }\n );\n }\n\n try {\n // 验证环境是否存在\n const projectsConfig = await getProjectsConfig();\n let envExists = false;\n \n // 检查所有项目中是否存在指定环境\n for (const [, projectConfig] of Object.entries(projectsConfig)) {\n if (projectConfig.envs && projectConfig.envs[envName]) {\n envExists = true;\n break;\n }\n }\n\n if (!envExists) {\n return NextResponse.json(\n { \n success: false, \n error: `环境 \"${envName}\" 不存在于任何项目中` \n },\n { status: 404 }\n );\n }\n\n console.log(`[SSE] 新的连接请求: 环境=${envName}, 客户端=${clientId}`);\n\n // 创建SSE流\n const encoder = new TextEncoder();\n \n const stream = new ReadableStream({\n start(controller) {\n // 添加连接到管理器\n sseConnectionManager.addConnection(envName, controller, clientId);\n\n // 发送初始连接成功消息\n const initialMessage = {\n type: 'connection-established' as const,\n envName,\n clientId,\n timestamp: Date.now(),\n message: `已连接到环境 ${envName} 的配置变化推送流`\n };\n\n const data = `data: ${JSON.stringify(initialMessage)}\\n\\n`;\n controller.enqueue(encoder.encode(data));\n },\n\n cancel() {\n // 连接取消时清理\n console.log(`[SSE] 连接取消: 环境=${envName}, 客户端=${clientId}`);\n sseConnectionManager.removeConnection(envName, clientId);\n }\n });\n\n // 返回SSE响应\n return new Response(stream, {\n status: 200,\n headers: {\n 'Content-Type': 'text/event-stream',\n 'Cache-Control': 'no-cache',\n 'Connection': 'keep-alive',\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Methods': 'GET',\n 'Access-Control-Allow-Headers': 'Cache-Control, Content-Type',\n },\n });\n\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'SSE连接建立失败';\n console.error(`[SSE] 连接建立失败: 环境=${envName}, 客户端=${clientId}`, error);\n \n return NextResponse.json(\n { \n success: false, \n error: errorMessage \n },\n { status: 500 }\n );\n }\n}\n\n/**\n * 处理预检请求\n */\nexport async function OPTIONS(): Promise<Response> {\n return new Response(null, {\n status: 200,\n headers: {\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Methods': 'GET, OPTIONS',\n 'Access-Control-Allow-Headers': 'Content-Type, Cache-Control',\n 'Access-Control-Max-Age': '86400',\n },\n });\n} ","import {\n AppRouteRouteModule,\n type AppRouteRouteModuleOptions,\n} from '../../server/route-modules/app-route/module.compiled'\nimport { RouteKind } from '../../server/route-kind'\nimport { patchFetch as _patchFetch } from '../../server/lib/patch-fetch'\n\nimport * as userland from 'VAR_USERLAND'\n\n// These are injected by the loader afterwards. This is injected as a variable\n// instead of a replacement because this could also be `undefined` instead of\n// an empty string.\ndeclare const nextConfigOutput: AppRouteRouteModuleOptions['nextConfigOutput']\n\n// We inject the nextConfigOutput here so that we can use them in the route\n// module.\n// INJECT:nextConfigOutput\n\nconst routeModule = new AppRouteRouteModule({\n definition: {\n kind: RouteKind.APP_ROUTE,\n page: 'VAR_DEFINITION_PAGE',\n pathname: 'VAR_DEFINITION_PATHNAME',\n filename: 'VAR_DEFINITION_FILENAME',\n bundlePath: 'VAR_DEFINITION_BUNDLE_PATH',\n },\n resolvedPagePath: 'VAR_RESOLVED_PAGE_PATH',\n nextConfigOutput,\n userland,\n})\n\n// Pull out the exports that we need to expose from the module. This should\n// be eliminated when we've moved the other routes to the new format. These\n// are used to hook into the route.\nconst { workAsyncStorage, workUnitAsyncStorage, serverHooks } = routeModule\n\nfunction patchFetch() {\n return _patchFetch({\n workAsyncStorage,\n workUnitAsyncStorage,\n })\n}\n\nexport {\n routeModule,\n workAsyncStorage,\n workUnitAsyncStorage,\n serverHooks,\n patchFetch,\n}\n"],"names":["AppRouteRouteModule","RouteKind","patchFetch","_patchFetch","userland","routeModule","definition","kind","APP_ROUTE","page","pathname","filename","bundlePath","resolvedPagePath","nextConfigOutput","workAsyncStorage","workUnitAsyncStorage","serverHooks"],"mappings":"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","ignoreList":[4]}
|