@h-ai/deploy 0.1.0-alpha.55 → 0.1.0-alpha.56
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/README.md +119 -3
- package/dist/index.d.ts +119 -2
- package/dist/index.js +906 -125
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../messages/en-US.json","../messages/zh-CN.json","../src/deploy-i18n.ts","../src/deploy-config.ts","../src/deploy-types.ts","../src/deploy-credentials.ts","../src/deploy-functions.ts","../src/deploy-recovery.ts","../src/deploy-scanner.ts","../src/providers/deploy-provider-vercel.ts","../src/provisioners/deploy-provisioner-aliyun.ts","../src/provisioners/deploy-provisioner-neon.ts","../src/provisioners/deploy-provisioner-r2.ts","../src/provisioners/deploy-provisioner-resend.ts","../src/provisioners/deploy-provisioner-upstash.ts","../src/deploy-main.ts"],"names":["core","logger","process","ok","err","join","existsSync","z","readFileSync","parse","readdirSync","connectionUri"],"mappings":"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","file":"index.js","sourcesContent":["{\n \"deploy_notInitialized\": \"Deploy module not initialized, call deploy.init() first\",\n \"deploy_initFailed\": \"Deploy module initialization failed: {error}\",\n \"deploy_unsupportedProviderType\": \"Unsupported deploy provider type: {type}\",\n \"deploy_unsupportedProvisionerType\": \"Unsupported service provisioner type: {type}\",\n \"deploy_configTokenRequired\": \"Deploy provider token is required\",\n \"deploy_authRequired\": \"Authentication required\",\n \"deploy_authFailed\": \"Authentication failed: {error}\",\n \"deploy_projectCreateFailed\": \"Project creation failed: {error}\",\n \"deploy_buildFailed\": \"Application build failed: {error}\",\n \"deploy_uploadFailed\": \"Build output upload failed: {error}\",\n \"deploy_deployFailed\": \"Deployment failed: {error}\",\n \"deploy_provisionFailed\": \"Service provisioning failed: {service} - {error}\",\n \"deploy_adapterMissing\": \"Target platform adapter not found, please install {adapter}\",\n \"deploy_scanFailed\": \"Application scan failed: {error}\",\n \"deploy_envVarFailed\": \"Environment variable setup failed: {error}\",\n \"deploy_credentialError\": \"Credential read/write failed: {error}\",\n \"deploy_credentialInvalidKey\": \"Unsupported credential key: {key}. Only HAI_DEPLOY_* keys are allowed\",\n \"deploy_credentialSaved\": \"Credentials saved\",\n \"deploy_credentialLoaded\": \"Credentials loaded\",\n \"deploy_configError\": \"Deploy config error: {error}\",\n \"deploy_credentialMissing\": \"Missing credential fields: {fields}\",\n \"deploy_apiError\": \"{service} API error ({status})\",\n \"deploy_fileUploadFailed\": \"File upload failed ({status})\",\n \"deploy_provisionNoResult\": \"No connection info returned from {service}\",\n \"deploy_recoveryFailure\": \"Deployment stopped at {stage}; inspect the recovery details.\",\n \"deploy_recoverySuggestion\": \"Inspect listed resources in the provider console before retrying with the same project name. Unknown means the request may have created a resource. Reused resources are never deleted automatically; remove newly created resources manually only after checking their use.\"\n}\n","{\n \"deploy_notInitialized\": \"Deploy 模块尚未初始化,请先调用 deploy.init()\",\n \"deploy_initFailed\": \"Deploy 模块初始化失败:{error}\",\n \"deploy_unsupportedProviderType\": \"不支持的部署平台类型:{type}\",\n \"deploy_unsupportedProvisionerType\": \"不支持的服务 Provisioner 类型:{type}\",\n \"deploy_configTokenRequired\": \"部署平台 Token 不能为空\",\n \"deploy_authRequired\": \"请先完成认证\",\n \"deploy_authFailed\": \"认证失败:{error}\",\n \"deploy_projectCreateFailed\": \"项目创建失败:{error}\",\n \"deploy_buildFailed\": \"应用构建失败:{error}\",\n \"deploy_uploadFailed\": \"构建产物上传失败:{error}\",\n \"deploy_deployFailed\": \"部署失败:{error}\",\n \"deploy_provisionFailed\": \"基础设施开通失败:{service} - {error}\",\n \"deploy_adapterMissing\": \"未检测到目标平台 adapter,请安装 {adapter}\",\n \"deploy_scanFailed\": \"应用扫描失败:{error}\",\n \"deploy_envVarFailed\": \"环境变量设置失败:{error}\",\n \"deploy_credentialError\": \"凭证读写失败:{error}\",\n \"deploy_credentialInvalidKey\": \"不支持的凭证键名:{key}。仅允许 HAI_DEPLOY_*\",\n \"deploy_credentialSaved\": \"凭证已保存\",\n \"deploy_credentialLoaded\": \"凭证已加载\",\n \"deploy_configError\": \"部署配置错误:{error}\",\n \"deploy_credentialMissing\": \"缺少凭证字段:{fields}\",\n \"deploy_apiError\": \"{service} API 请求失败({status})\",\n \"deploy_fileUploadFailed\": \"文件上传失败({status})\",\n \"deploy_provisionNoResult\": \"{service} 未返回连接信息\",\n \"deploy_recoveryFailure\": \"部署在 {stage} 阶段停止,请查看恢复清单。\",\n \"deploy_recoverySuggestion\": \"重试前在服务商控制台核对清单,并使用相同项目名。unknown 表示请求可能已创建资源。复用资源不会自动删除;新建资源仅在确认未被使用后人工清理。\"\n}\n","/**\n * @h-ai/deploy — i18n\n *\n * 本文件提供部署模块的 i18n 文案访问入口。\n * @module deploy-i18n\n */\n\nimport { core } from '@h-ai/core'\nimport messagesEnUS from '../messages/en-US.json'\nimport messagesZhCN from '../messages/zh-CN.json'\n\n// ─── i18n ───\n\n/** 部署模块文案 Key 类型 */\ntype DeployMessageKey = keyof typeof messagesZhCN\n\n/**\n * 获取部署模块文案\n *\n * @param key - 文案 Key\n * @param options - 插值参数与格式化选项\n * @returns 本地化后的文案字符串\n *\n * @example\n * ```ts\n * const text = deployM('deploy_notInitialized')\n * ```\n */\nexport const deployM = core.i18n.createMessageGetter<DeployMessageKey>({\n 'zh-CN': messagesZhCN,\n 'en-US': messagesEnUS,\n})\n","/**\n * @h-ai/deploy — 部署配置 Schema\n *\n * 本文件定义部署模块的错误码、Zod Schema 和配置类型。\n * @module deploy-config\n */\n\nimport { z } from 'zod'\nimport { deployM } from './deploy-i18n.js'\n\n// ─── Provider 配置 Schema ───\n\n/** Vercel 部署平台配置 */\nconst VercelProviderConfigSchema = z.object({\n type: z.literal('vercel'),\n token: z.string().min(1, deployM('deploy_configTokenRequired')),\n})\n\n/** 部署平台配置联合类型(后续可扩展更多平台) */\nexport const ProviderConfigSchema = z.discriminatedUnion('type', [\n VercelProviderConfigSchema,\n])\n\n// ─── Provisioner 配置 Schema ───\n\n/** Neon PostgreSQL 服务配置 */\nconst NeonServiceSchema = z.object({\n provisioner: z.literal('neon'),\n apiKey: z.string().min(1),\n})\n\n/** Upstash Redis 服务配置 */\nconst UpstashServiceSchema = z.object({\n provisioner: z.literal('upstash'),\n email: z.string().email(),\n apiKey: z.string().min(1),\n})\n\n/** Cloudflare R2 存储服务配置 */\nconst R2ServiceSchema = z.object({\n provisioner: z.literal('cloudflare-r2'),\n accessKeyId: z.string().min(1),\n secretAccessKey: z.string().min(1),\n accountId: z.string().min(1),\n apiToken: z.string().min(1),\n})\n\n/** Resend 邮件服务配置 */\nconst ResendServiceSchema = z.object({\n provisioner: z.literal('resend'),\n from: z.string().email(),\n apiKey: z.string().min(1),\n})\n\n/** 阿里云短信服务配置 */\nconst AliyunSmsServiceSchema = z.object({\n provisioner: z.literal('aliyun'),\n signName: z.string().min(1),\n accessKeyId: z.string().min(1),\n accessKeySecret: z.string().min(1),\n})\n\n/** 基础设施服务配置 */\nconst ServicesConfigSchema = z.object({\n db: z.discriminatedUnion('provisioner', [NeonServiceSchema]).optional(),\n cache: z.discriminatedUnion('provisioner', [UpstashServiceSchema]).optional(),\n storage: z.discriminatedUnion('provisioner', [R2ServiceSchema]).optional(),\n email: z.discriminatedUnion('provisioner', [ResendServiceSchema]).optional(),\n sms: z.discriminatedUnion('provisioner', [AliyunSmsServiceSchema]).optional(),\n}).optional()\n\n// ─── 完整配置 Schema ───\n\n/** 部署模块完整配置 Schema */\nexport const DeployConfigSchema = z.object({\n provider: ProviderConfigSchema,\n services: ServicesConfigSchema,\n})\n\n/** 部署配置类型(parse 后) */\nexport type DeployConfig = z.infer<typeof DeployConfigSchema>\n\n/** 部署配置输入类型(用户输入) */\nexport type DeployConfigInput = z.input<typeof DeployConfigSchema>\n","/**\n * @h-ai/deploy — 类型定义\n *\n * 本文件定义部署模块的核心接口和类型(非配置相关)。 配置相关类型请从 deploy-config.ts 导入。\n * @module deploy-types\n */\n\nimport type { ErrorInfo, HaiResult } from '@h-ai/core'\nimport type { DeployConfig, DeployConfigInput } from './deploy-config.js'\nimport { core } from '@h-ai/core'\n\n// ─── 错误定义(照 @h-ai/core 范式) ───\n\nconst DeployErrorInfo = {\n DEPLOY_FAILED: '001:500',\n PROJECT_CREATE_FAILED: '002:500',\n BUILD_FAILED: '003:500',\n UPLOAD_FAILED: '004:500',\n AUTH_REQUIRED: '005:401',\n AUTH_FAILED: '006:401',\n PROVISION_FAILED: '007:500',\n ADAPTER_MISSING: '008:500',\n SCAN_FAILED: '009:500',\n NOT_INITIALIZED: '010:500',\n ENV_VAR_FAILED: '011:500',\n UNSUPPORTED_TYPE: '012:400',\n CONFIG_ERROR: '013:500',\n CREDENTIAL_ERROR: '014:500',\n} as const satisfies ErrorInfo\n\nexport const HaiDeployError = core.error.buildHaiErrorsDef('deploy', DeployErrorInfo)\n\n/**\n * 部署错误接口\n *\n * 所有部署操作返回的错误都遵循此接口。\n *\n * @example\n * ```ts\n * const result = await deploy.deployApp('./apps/my-app')\n * if (!result.success) {\n * const error: DeployError = result.error\n * // 根据 error.code 处理\n * }\n * ```\n */\nexport interface DeployError {\n /** 错误定义 */\n def: (typeof HaiDeployError)[keyof typeof HaiDeployError]\n /** 错误消息 */\n message: string\n /** 原始错误(可选) */\n cause?: unknown\n}\n\n// ─── 服务类型 ───\n\n/** 基础设施服务类型 */\nexport type ServiceType = 'db' | 'cache' | 'storage' | 'email' | 'sms'\n\n// ─── 扫描结果 ───\n\n/**\n * 应用扫描结果\n *\n * 由 scanner 分析应用目录后返回,描述应用的框架类型、依赖和部署需求。\n */\nexport interface ScanResult {\n /** 应用名称(来自 package.json name) */\n appName: string\n /** 是否为 SvelteKit 项目 */\n isSvelteKit: boolean\n /** 目标平台 adapter 是否已安装(如 @sveltejs/adapter-vercel) */\n adapterInstalled: boolean\n /** 检测到的模块依赖需要的服务列表 */\n requiredServices: ServiceType[]\n /** 构建命令 */\n buildCommand: string\n}\n\n// ─── 部署结果 ───\n\n/**\n * 部署结果\n *\n * 包含部署后的访问 URL、状态和已设置的环境变量。\n */\nexport interface DeployResult {\n /** 部署后的访问 URL */\n url: string\n /** 部署 ID */\n deploymentId: string\n /** 部署状态 */\n status: 'ready' | 'building' | 'error'\n /** 已设置的环境变量名列表 */\n envVarsSet: string[]\n}\n\n// ─── 开通结果 ───\n\n/**\n * 基础设施开通结果\n *\n * 由 Provisioner 开通服务后返回,包含要注入到部署平台的环境变量。\n */\nexport interface ProvisionResult {\n /** 本次新建或复用;凭证型服务始终为 reused */\n resourceStatus: 'created' | 'reused'\n /** 服务类型 */\n serviceType: ServiceType\n /** Provisioner 名称 */\n provisionerName: string\n /** 要注入到部署平台的环境变量 */\n envVars: Record<string, string>\n /** 资源标识信息(如项目名、数据库名等),用于日志和展示 */\n resourceInfo: string\n}\n\n/** 部署失败后的安全恢复信息,不含环境变量值或原始异常。 */\nexport interface DeployRecoveryInfo {\n projectName: string\n stage: string\n platformProjectId?: string\n resources: Array<{\n serviceType: ServiceType\n provisionerName: string\n resourceInfo: string\n resourceStatus: 'created' | 'reused' | 'unknown'\n }>\n}\n\n// ─── 部署选项 ───\n\n/** 部署选项 */\nexport interface DeployAppOptions {\n /** 项目名称(默认从 package.json name 提取) */\n projectName?: string\n /** 是否跳过基础设施开通 */\n skipProvision?: boolean\n /** 是否跳过构建 */\n skipBuild?: boolean\n}\n\n// ─── 凭证子功能 ───\n\n/**\n * Deploy 凭证文件操作。\n *\n * 这些方法仅操作 `~/.hai/credentials.yml`,不依赖 `deploy.init()`。\n */\nexport interface DeployCredentialOperations {\n /** 获取凭证文件绝对路径。 */\n getPath: () => string\n /** 加载凭证文件并注入 `process.env`。 */\n load: () => HaiResult<string[]>\n /** 保存单个凭证。 */\n save: (key: string, value: string) => HaiResult<void>\n /** 批量保存凭证。 */\n saveAll: (entries: Record<string, string>) => HaiResult<void>\n}\n\n// ─── 模块功能接口 ───\n\n/**\n * Deploy 模块功能接口\n *\n * 提供自动化部署的完整 API:\n * - `deploy.credentials.*()` — 凭证文件读写(不依赖 init)\n * - `deploy.init()` — 初始化(加载配置、创建 Provider 和 Provisioner)\n * - `deploy.scan()` — 扫描应用依赖(纯文件系统能力,不依赖 init)\n * - `deploy.provisionAll()` — 开通所有已配置的基础设施\n * - `deploy.deployApp()` — 完整部署流程\n * - `deploy.close()` — 关闭模块\n *\n * @example\n * ```ts\n * import { deploy } from '@h-ai/deploy'\n *\n * await deploy.init({ provider: { type: 'vercel', token: 'xxx' } })\n * const result = await deploy.deployApp('./apps/my-app')\n * if (result.success) {\n * console.log(`Deployed: ${result.data.url}`)\n * }\n * await deploy.close()\n * ```\n */\nexport interface DeployFunctions {\n /** 全局部署凭证文件操作。 */\n readonly credentials: DeployCredentialOperations\n /** 初始化模块(加载配置、创建 Provider 和 Provisioner 实例) */\n init: (config: DeployConfigInput) => Promise<HaiResult<void>>\n /** 关闭模块 */\n close: () => Promise<void>\n /** 当前配置 */\n readonly config: DeployConfig | null\n /** 是否已初始化 */\n readonly isInitialized: boolean\n\n /**\n * 扫描应用目录,检测依赖和所需服务。\n *\n * 这是纯文件系统分析能力,不依赖云端认证状态,可在 `deploy.init()` 之前调用。\n *\n * @param appDir - 应用根目录路径\n */\n scan: (appDir: string) => Promise<HaiResult<ScanResult>>\n\n /**\n * 对所有已配置的 Provisioner 执行基础设施开通\n *\n * @param projectName - 用于资源命名的项目名\n * @returns 所有 Provisioner 的结果列表\n */\n provisionAll: (projectName: string) => Promise<HaiResult<ProvisionResult[]>>\n\n /**\n * 执行完整部署流程(provision → build → deploy)\n *\n * @param appDir - 应用根目录路径\n * @param options - 部署选项\n */\n deployApp: (appDir: string, options?: DeployAppOptions) => Promise<HaiResult<DeployResult>>\n}\n","/**\n * @h-ai/deploy — 凭证管理\n *\n * 管理全局凭证文件 `~/.hai/credentials.yml`。\n * 这些 helper 由 `deploy.credentials.*` 对外暴露,供 CLI 在加载 `_deploy.yml`\n * 之前注入 `HAI_DEPLOY_*` 环境变量。\n * @module deploy-credentials\n */\n\nimport type { HaiResult } from '@h-ai/core'\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { dirname, join } from 'node:path'\nimport process from 'node:process'\nimport { core, err, ok } from '@h-ai/core'\nimport { parse, stringify } from 'yaml'\nimport { deployM } from './deploy-i18n.js'\nimport { HaiDeployError } from './deploy-types.js'\n\nconst logger = core.logger.child({ module: 'deploy', scope: 'credentials' })\n\n/** 仅允许写入 deploy 模块自有的环境变量前缀,避免把任意 YAML key 注入 process.env。 */\nconst DEPLOY_CREDENTIAL_KEY_PATTERN = /^HAI_DEPLOY_[A-Z0-9_]+$/\n\n// ─── 内部工具 ───\n\n/** 校验凭证键名是否属于 deploy 模块。 */\nfunction isAllowedCredentialKey(key: string): boolean {\n return DEPLOY_CREDENTIAL_KEY_PATTERN.test(key)\n}\n\n/**\n * 标准化凭证键值对。\n *\n * 仅保留 `HAI_DEPLOY_*` 键,且值必须是可安全序列化为字符串的标量。\n */\nfunction normalizeCredentialEntries(entries: Record<string, unknown>): Record<string, string> {\n const normalized: Record<string, string> = {}\n\n for (const [key, value] of Object.entries(entries)) {\n if (!isAllowedCredentialKey(key)) {\n logger.warn('Ignoring unsupported deploy credential key', { key })\n continue\n }\n\n if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {\n normalized[key] = String(value)\n continue\n }\n\n logger.warn('Ignoring deploy credential with non-scalar value', { key })\n }\n\n return normalized\n}\n\n/** 在写入前校验单个凭证键名。 */\nfunction assertAllowedCredentialKey(key: string): void {\n if (!isAllowedCredentialKey(key)) {\n throw new Error(deployM('deploy_credentialInvalidKey', { params: { key } }))\n }\n}\n\n/** 在写入前校验批量凭证键名。 */\nfunction assertAllowedCredentialEntries(entries: Record<string, string>): void {\n for (const key of Object.keys(entries)) {\n assertAllowedCredentialKey(key)\n }\n}\n\n/**\n * 获取凭证文件路径\n *\n * @returns `~/.hai/credentials.yml` 的绝对路径\n */\nexport function getCredentialsPath(): string {\n return join(homedir(), '.hai', 'credentials.yml')\n}\n\n/**\n * 确保凭证目录存在\n *\n * @param filePath - 凭证文件路径\n */\nfunction ensureDir(filePath: string): void {\n const dir = dirname(filePath)\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true })\n }\n}\n\n/**\n * 读取凭证文件内容\n *\n * @returns 解析后的键值对,文件不存在时返回空对象\n */\nfunction readCredentialsFile(): Record<string, string> {\n const filePath = getCredentialsPath()\n if (!existsSync(filePath)) {\n return {}\n }\n const content = readFileSync(filePath, 'utf-8')\n const parsed = parse(content)\n if (parsed === null || parsed === undefined || typeof parsed !== 'object' || Array.isArray(parsed)) {\n return {}\n }\n return normalizeCredentialEntries(parsed as Record<string, unknown>)\n}\n\n/**\n * 写入凭证文件\n *\n * @param data - 凭证键值对\n */\nfunction writeCredentialsFile(data: Record<string, string>): void {\n const filePath = getCredentialsPath()\n ensureDir(filePath)\n const header = '# Managed by hai cli - do not edit manually\\n'\n const content = header + stringify(data)\n writeFileSync(filePath, content, { encoding: 'utf-8', mode: 0o600 })\n}\n\n// ─── 公共 API ───\n\n/**\n * 加载全局凭证文件并注入到 process.env\n *\n * 读取 `~/.hai/credentials.yml` 中的所有键值对,\n * 将每个 key-value 设置到 `process.env` 中,\n * 使后续 core 配置加载时自动解析 `${HAI_DEPLOY_*}` 变量。\n *\n * @returns 成功返回加载的凭证键名列表\n *\n * @example\n * ```ts\n * const result = loadCredentials()\n * if (result.success) {\n * console.log(`Loaded ${result.data.length} credentials`)\n * }\n * ```\n */\nexport function loadCredentials(): HaiResult<string[]> {\n try {\n const data = readCredentialsFile()\n const keys = Object.keys(data)\n for (const key of keys) {\n process.env[key] = String(data[key])\n }\n logger.debug('Credentials loaded', { count: keys.length })\n return ok(keys)\n }\n catch (error) {\n logger.error('Failed to load credentials', { error })\n return err(\n HaiDeployError.CREDENTIAL_ERROR,\n deployM('deploy_credentialError', {\n params: { error: error instanceof Error ? error.message : String(error) },\n }),\n error,\n )\n }\n}\n\n/**\n * 保存单个凭证到全局凭证文件\n *\n * 读取已有凭证 → 合并新凭证 → 写回文件。已有同名 key 会被覆盖。\n *\n * @param key - 环境变量名(如 HAI_DEPLOY_VERCEL_TOKEN)\n * @param value - 凭证值\n *\n * @example\n * ```ts\n * saveCredential('HAI_DEPLOY_VERCEL_TOKEN', 'vel_xxx')\n * ```\n */\nexport function saveCredential(key: string, value: string): HaiResult<void> {\n try {\n assertAllowedCredentialKey(key)\n const data = readCredentialsFile()\n data[key] = value\n writeCredentialsFile(data)\n process.env[key] = value\n logger.debug('Credential saved', { key })\n return ok(undefined)\n }\n catch (error) {\n logger.error('Failed to save credential', { key, error })\n return err(\n HaiDeployError.CREDENTIAL_ERROR,\n deployM('deploy_credentialError', {\n params: { error: error instanceof Error ? error.message : String(error) },\n }),\n error,\n )\n }\n}\n\n/**\n * 批量保存凭证到全局凭证文件\n *\n * @param entries - 凭证键值对\n *\n * @example\n * ```ts\n * saveCredentials({\n * HAI_DEPLOY_VERCEL_TOKEN: 'vel_xxx',\n * HAI_DEPLOY_NEON_API_KEY: 'neon_xxx',\n * })\n * ```\n */\nexport function saveCredentials(entries: Record<string, string>): HaiResult<void> {\n try {\n assertAllowedCredentialEntries(entries)\n const data = readCredentialsFile()\n for (const [key, value] of Object.entries(entries)) {\n data[key] = value\n process.env[key] = value\n }\n writeCredentialsFile(data)\n logger.debug('Credentials saved', { count: Object.keys(entries).length })\n return ok(undefined)\n }\n catch (error) {\n logger.error('Failed to save credentials', { error })\n return err(\n HaiDeployError.CREDENTIAL_ERROR,\n deployM('deploy_credentialError', {\n params: { error: error instanceof Error ? error.message : String(error) },\n }),\n error,\n )\n }\n}\n","/**\n * @h-ai/deploy — 部署辅助函数\n *\n * 包含构建、产物目录解析等与部署流程相关的辅助操作。 从 deploy-main.ts 中提取,遵循 main 仅做生命周期管理的规范。\n * @module deploy-functions\n */\n\nimport type { HaiResult } from '@h-ai/core'\nimport { execSync } from 'node:child_process'\nimport { existsSync } from 'node:fs'\nimport { join } from 'node:path'\nimport process from 'node:process'\nimport { core, err, ok } from '@h-ai/core'\nimport { deployM } from './deploy-i18n.js'\nimport { HaiDeployError } from './deploy-types.js'\n\nconst logger = core.logger.child({ module: 'deploy', scope: 'functions' })\n\n/**\n * 执行应用构建\n *\n * @param appDir - 应用根目录\n * @param buildCommand - 构建命令\n * @param envVars - 当前部署开通结果,确保构建与运行使用同一配置\n * @returns 构建结果\n */\nexport function buildApp(appDir: string, buildCommand: string, envVars: Record<string, string> = {}): HaiResult<void> {\n logger.info('Building application', { appDir, buildCommand })\n try {\n execSync(buildCommand, {\n cwd: appDir,\n stdio: 'inherit',\n env: { ...process.env, ...envVars },\n })\n return ok(undefined)\n }\n catch (error) {\n return err(\n HaiDeployError.BUILD_FAILED,\n deployM('deploy_buildFailed', {\n params: { error: error instanceof Error ? error.message : String(error) },\n }),\n error,\n )\n }\n}\n\n/**\n * 解析构建产物目录\n *\n * @param appDir - 应用根目录\n * @param providerType - Provider 类型\n * @returns 产物目录路径\n */\nexport function resolveOutputDir(appDir: string, providerType: string): string {\n switch (providerType) {\n case 'vercel': {\n const vercelOutput = join(appDir, '.vercel', 'output')\n if (existsSync(vercelOutput)) {\n return vercelOutput\n }\n // 回退到标准 build 目录\n return join(appDir, 'build')\n }\n default:\n return join(appDir, 'build')\n }\n}\n","import type { HaiError, HaiResult } from '@h-ai/core'\nimport type { DeployRecoveryInfo } from './deploy-types.js'\nimport { err } from '@h-ai/core'\nimport { z } from 'zod'\nimport { deployM } from './deploy-i18n.js'\n\nconst RecoverySchema = z.object({\n projectName: z.string(),\n stage: z.string(),\n platformProjectId: z.string().optional(),\n resources: z.array(z.object({\n serviceType: z.enum(['db', 'cache', 'storage', 'email', 'sms']),\n provisionerName: z.string(),\n resourceInfo: z.string(),\n resourceStatus: z.enum(['created', 'reused', 'unknown']),\n })),\n})\n\n/** 读取错误中的恢复清单;仅返回明确允许展示的字段。 */\nexport function getDeployRecovery(error: HaiError): DeployRecoveryInfo | undefined {\n const parsed = RecoverySchema.safeParse(error.ext?.recovery)\n return parsed.success ? parsed.data : undefined\n}\n\n/** 在错误中保留可展示的恢复信息,避免异常 cause/命令/URL 泄漏凭证。 */\nexport function recoveryFailure(error: HaiError, recovery: DeployRecoveryInfo): HaiResult<never> {\n return err({\n code: error.code,\n httpStatus: error.httpStatus,\n system: error.system,\n module: error.module,\n message: deployM('deploy_recoveryFailure', { params: { stage: recovery.stage } }),\n suggestion: deployM('deploy_recoverySuggestion'),\n ext: { recovery },\n })\n}\n","/**\n * @h-ai/deploy — 应用扫描器\n *\n * 扫描应用目录,检测框架类型、模块依赖和所需基础设施。\n * @module deploy-scanner\n */\n\nimport type { HaiResult } from '@h-ai/core'\nimport type { ScanResult, ServiceType } from './deploy-types.js'\nimport { existsSync, readdirSync, readFileSync } from 'node:fs'\nimport { join } from 'node:path'\nimport { core, err, ok } from '@h-ai/core'\nimport { parse } from 'yaml'\nimport { deployM } from './deploy-i18n.js'\nimport { HaiDeployError } from './deploy-types.js'\n\nconst logger = core.logger.child({ module: 'deploy', scope: 'scanner' })\n\n// ─── 内部工具 ───\n\n/**\n * 安全读取并解析 YAML 文件\n *\n * @param filePath - YAML 文件路径\n * @returns 解析结果,文件不存在或解析失败时返回 null\n */\nfunction readYaml(filePath: string): Record<string, unknown> | null {\n if (!existsSync(filePath)) {\n return null\n }\n try {\n const content = readFileSync(filePath, 'utf-8')\n const parsed = parse(content)\n if (parsed === null || parsed === undefined || typeof parsed !== 'object') {\n return null\n }\n return parsed as Record<string, unknown>\n }\n catch {\n return null\n }\n}\n\n/**\n * 安全读取 JSON 文件\n *\n * @param filePath - JSON 文件路径\n * @returns 解析结果,文件不存在或解析失败时返回 null\n */\nfunction readJson(filePath: string): Record<string, unknown> | null {\n if (!existsSync(filePath)) {\n return null\n }\n try {\n const content = readFileSync(filePath, 'utf-8')\n return JSON.parse(content) as Record<string, unknown>\n }\n catch {\n return null\n }\n}\n\n/**\n * 检测 package.json 的 dependencies + devDependencies 中是否包含指定包\n *\n * @param pkg - package.json 内容\n * @param name - 包名\n */\nfunction hasDependency(pkg: Record<string, unknown>, name: string): boolean {\n const deps = pkg.dependencies as Record<string, string> | undefined\n const devDeps = pkg.devDependencies as Record<string, string> | undefined\n return (deps !== undefined && name in deps) || (devDeps !== undefined && name in devDeps)\n}\n\n/**\n * 扫描 config/ 目录,推断所需基础设施服务\n *\n * @param configDir - 配置目录路径\n * @returns 需要的服务类型列表\n */\nfunction detectRequiredServices(configDir: string): ServiceType[] {\n const services: ServiceType[] = []\n\n if (!existsSync(configDir)) {\n return services\n }\n\n const files = readdirSync(configDir)\n\n // 检测数据库需求\n if (files.includes('_db.yml') || files.includes('_db.yaml')) {\n const dbConfig = readYaml(join(configDir, files.find(f => f.startsWith('_db.'))!))\n // sqlite 在云端也需要切换为 postgresql,标记为需要 db\n if (dbConfig !== null) {\n services.push('db')\n }\n }\n\n // 检测缓存需求\n if (files.includes('_cache.yml') || files.includes('_cache.yaml')) {\n const cacheConfig = readYaml(join(configDir, files.find(f => f.startsWith('_cache.'))!))\n if (cacheConfig !== null) {\n const cacheType = cacheConfig.type as string | undefined\n // memory 模式不需要外部服务,redis 需要\n if (cacheType === 'redis') {\n services.push('cache')\n }\n }\n }\n\n // 检测存储需求\n if (files.includes('_storage.yml') || files.includes('_storage.yaml')) {\n const storageConfig = readYaml(join(configDir, files.find(f => f.startsWith('_storage.'))!))\n if (storageConfig !== null) {\n detectStorageServices(storageConfig, services)\n }\n }\n\n // 检测 reach(邮件 / 短信)需求\n if (files.includes('_reach.yml') || files.includes('_reach.yaml')) {\n const reachConfig = readYaml(join(configDir, files.find(f => f.startsWith('_reach.'))!))\n if (reachConfig !== null) {\n detectReachServices(reachConfig, services)\n }\n }\n\n return services\n}\n\n/**\n * 检测存储配置中的 S3 需求\n *\n * @param config - 存储配置内容\n * @param services - 服务列表(原地修改)\n */\nfunction detectStorageServices(config: Record<string, unknown>, services: ServiceType[]): void {\n // 直接配置\n if (config.type === 's3') {\n services.push('storage')\n return\n }\n // 多 provider 配置\n const providers = config.providers as Record<string, unknown> | undefined\n if (providers === undefined) {\n return\n }\n for (const providerConfig of Object.values(providers)) {\n const typed = providerConfig as Record<string, unknown> | undefined\n if (typed?.type === 's3') {\n services.push('storage')\n return\n }\n }\n}\n\n/**\n * 检测 reach 配置中的邮件和短信需求\n *\n * @param config - reach 配置内容\n * @param services - 服务列表(原地修改)\n */\nfunction detectReachServices(config: Record<string, unknown>, services: ServiceType[]): void {\n const providers = config.providers as Array<Record<string, unknown>> | undefined\n if (!Array.isArray(providers)) {\n return\n }\n\n let hasEmail = false\n let hasSms = false\n\n for (const provider of providers) {\n const providerType = provider.type as string | undefined\n // smtp / api / resend 类型视为邮件需求\n if (!hasEmail && (providerType === 'smtp' || providerType === 'api')) {\n hasEmail = true\n services.push('email')\n }\n // aliyun-sms 类型视为短信需求\n if (!hasSms && providerType === 'aliyun-sms') {\n hasSms = true\n services.push('sms')\n }\n }\n}\n\n// ─── 公共 API ───\n\n/**\n * 扫描应用目录,检测框架类型、模块依赖和所需基础设施\n *\n * @param appDir - 应用根目录绝对路径\n * @returns 扫描结果(ScanResult)\n *\n * @example\n * ```ts\n * const result = await scanApp('/path/to/my-app')\n * if (result.success) {\n * const { appName, isSvelteKit, requiredServices } = result.data\n * }\n * ```\n */\nexport async function scanApp(appDir: string): Promise<HaiResult<ScanResult>> {\n logger.debug('Scanning application', { appDir })\n\n try {\n // 读取 package.json\n const pkg = readJson(join(appDir, 'package.json'))\n if (pkg === null) {\n return err(\n HaiDeployError.SCAN_FAILED,\n deployM('deploy_scanFailed', { params: { error: 'package.json not found' } }),\n )\n }\n\n const appName = extractAppName(pkg)\n const isSvelteKit = existsSync(join(appDir, 'svelte.config.js'))\n || existsSync(join(appDir, 'svelte.config.ts'))\n const adapterInstalled = hasDependency(pkg, '@sveltejs/adapter-vercel')\n const configDir = join(appDir, 'config')\n const configServices = detectRequiredServices(configDir)\n const depServices = detectServicesFromDependencies(pkg)\n // 合并去重:config 检测优先,依赖检测补充\n const requiredServices = Array.from(new Set([...configServices, ...depServices]))\n const scripts = pkg.scripts as Record<string, string> | undefined\n const buildCommand = scripts?.build ?? 'pnpm build'\n\n const scanResult: ScanResult = {\n appName,\n isSvelteKit,\n adapterInstalled,\n requiredServices,\n buildCommand,\n }\n\n logger.info('Application scanned', {\n appName,\n isSvelteKit,\n adapterInstalled,\n requiredServices,\n })\n\n return ok(scanResult)\n }\n catch (error) {\n logger.error('Application scan failed', { appDir, error })\n return err(\n HaiDeployError.SCAN_FAILED,\n deployM('deploy_scanFailed', {\n params: { error: error instanceof Error ? error.message : String(error) },\n }),\n error,\n )\n }\n}\n\n/**\n * 从 package.json 的 @h-ai/* 依赖推断所需服务\n *\n * 依赖映射规则:\n * - @h-ai/reldb → 'db'\n * - @h-ai/cache → 'cache'\n * - @h-ai/storage → 'storage'\n *\n * @param pkg - package.json 内容\n * @returns 需要的服务类型列表\n */\nfunction detectServicesFromDependencies(pkg: Record<string, unknown>): ServiceType[] {\n const depMap: Record<string, ServiceType> = {\n '@h-ai/reldb': 'db',\n '@h-ai/cache': 'cache',\n '@h-ai/storage': 'storage',\n }\n const services: ServiceType[] = []\n for (const [depName, serviceType] of Object.entries(depMap)) {\n if (hasDependency(pkg, depName)) {\n services.push(serviceType)\n }\n }\n return services\n}\n\n/**\n * 从 package.json 提取应用名称\n *\n * 移除 scope 前缀(如 @h-ai/admin-console → admin-console)\n *\n * @param pkg - package.json 内容\n * @returns 应用名称\n */\nfunction extractAppName(pkg: Record<string, unknown>): string {\n const name = (pkg.name as string) ?? 'app'\n // 移除 scope 前缀\n const slashIndex = name.indexOf('/')\n if (slashIndex >= 0) {\n return name.slice(slashIndex + 1)\n }\n return name\n}\n","/**\n * @h-ai/deploy — Vercel 部署 Provider\n *\n * 封装 Vercel REST API,实现 DeployProvider 接口。 使用原生 fetch 调用,零外部 SDK 依赖。\n * @module deploy-provider-vercel\n */\n\nimport type { HaiError, HaiErrorDef, HaiResult } from '@h-ai/core'\nimport type { DeployProvider } from '../deploy-internal-types.js'\nimport type { DeployResult } from '../deploy-types.js'\nimport { createHash } from 'node:crypto'\nimport { readdirSync, readFileSync, statSync } from 'node:fs'\nimport { join, relative, sep } from 'node:path'\nimport { core, err, ok } from '@h-ai/core'\nimport { deployM } from '../deploy-i18n.js'\nimport { HaiDeployError } from '../deploy-types.js'\n\nconst logger = core.logger.child({ module: 'deploy', scope: 'provider-vercel' })\n\n/** Vercel API 基址 */\nconst VERCEL_API = 'https://api.vercel.com'\n\n/** 部署状态轮询间隔(毫秒) */\nconst POLL_INTERVAL = 3000\n\n/** 部署状态轮询最大次数 */\nconst MAX_POLL_ATTEMPTS = 60\n\n// ─── 内部工具 ───\n\n/** Vercel API 错误,保留状态码用于区分 404 与真实失败 */\nclass VercelApiError extends Error {\n constructor(readonly status: number) {\n super(deployM('deploy_apiError', { params: { service: 'Vercel', status: String(status) } }))\n }\n}\n\n/** 构造标准错误对象 */\nfunction toDeployError(codeDef: HaiErrorDef, messageKey: string, error: unknown): HaiError {\n return {\n ...codeDef,\n message: deployM(messageKey as Parameters<typeof deployM>[0], {\n params: { error: error instanceof Error ? error.message : String(error) },\n }),\n cause: error,\n }\n}\n\n/**\n * 发送 Vercel API 请求\n *\n * @param token - API Token\n * @param path - API 路径(如 /v2/user)\n * @param options - fetch 选项\n * @returns 解析后的 JSON 响应\n */\nasync function vercelFetch<T>(token: string, path: string, options?: RequestInit): Promise<T> {\n const url = `${VERCEL_API}${path}`\n const response = await fetch(url, {\n ...options,\n headers: {\n 'Authorization': `Bearer ${token}`,\n 'Content-Type': 'application/json',\n ...options?.headers,\n },\n })\n\n if (!response.ok) {\n throw new VercelApiError(response.status)\n }\n\n return response.json() as Promise<T>\n}\n\n/**\n * 递归收集目录中的所有文件\n *\n * @param dir - 目录路径\n * @param baseDir - 基础目录(用于计算相对路径)\n * @returns 文件相对路径列表\n */\nfunction collectFiles(dir: string, baseDir: string): string[] {\n const results: string[] = []\n const entries = readdirSync(dir, { withFileTypes: true })\n\n for (const entry of entries) {\n const fullPath = join(dir, entry.name)\n if (entry.isDirectory()) {\n results.push(...collectFiles(fullPath, baseDir))\n }\n else {\n results.push(relative(baseDir, fullPath).split(sep).join('/'))\n }\n }\n\n return results\n}\n\n// ─── Provider 工厂 ───\n\n/**\n * 创建 Vercel 部署 Provider\n *\n * @returns DeployProvider 实例\n *\n * @example\n * ```ts\n * const provider = createVercelProvider()\n * await provider.authenticate('vel_xxx')\n * const projectId = await provider.createProject('my-app')\n * ```\n */\nexport function createVercelProvider(): DeployProvider {\n let token: string | null = null\n\n return {\n name: 'vercel',\n\n async authenticate(apiToken: string): Promise<HaiResult<string>> {\n logger.debug('Authenticating with Vercel')\n try {\n const user = await vercelFetch<{ user: { username: string, email: string } }>(\n apiToken,\n '/v2/user',\n )\n token = apiToken\n const username = user.user.username || user.user.email\n logger.info('Vercel authenticated', { user: username })\n return ok(username)\n }\n catch (error) {\n logger.error('Vercel authentication failed', { error })\n return err(toDeployError(HaiDeployError.AUTH_FAILED, 'deploy_authFailed', error))\n }\n },\n\n async createProject(projectName: string): Promise<HaiResult<string>> {\n if (!token) {\n return err(\n HaiDeployError.AUTH_REQUIRED,\n deployM('deploy_authRequired'),\n )\n }\n\n logger.debug('Creating Vercel project', { projectName })\n try {\n // 先查找已有项目\n const existingId = await findExistingProject(token, projectName)\n if (existingId !== null) {\n logger.info('Vercel project found', { projectName, projectId: existingId })\n return ok(existingId)\n }\n\n try {\n const project = await vercelFetch<{ id: string }>(\n token,\n '/v11/projects',\n {\n method: 'POST',\n body: JSON.stringify({\n name: projectName,\n framework: 'sveltekit',\n }),\n },\n )\n logger.info('Vercel project created', { projectName, projectId: project.id })\n return ok(project.id)\n }\n catch (error) {\n // 官方文档说明同名项目创建会返回 409;遇到并发竞争时回查现有项目即可实现幂等。\n if (error instanceof VercelApiError && error.status === 409) {\n const concurrentProjectId = await findExistingProject(token, projectName)\n if (concurrentProjectId !== null) {\n logger.info('Vercel project reused after create conflict', {\n projectName,\n projectId: concurrentProjectId,\n })\n return ok(concurrentProjectId)\n }\n }\n throw error\n }\n }\n catch (error) {\n logger.error('Vercel project creation failed', { projectName, error })\n return err(toDeployError(HaiDeployError.PROJECT_CREATE_FAILED, 'deploy_projectCreateFailed', error))\n }\n },\n\n async setEnvVars(projectId: string, envVars: Record<string, string>): Promise<HaiResult<void>> {\n if (!token) {\n return err(\n HaiDeployError.AUTH_REQUIRED,\n deployM('deploy_authRequired'),\n )\n }\n\n logger.debug('Setting Vercel env vars', { projectId, count: Object.keys(envVars).length })\n try {\n const envEntries = Object.entries(envVars).map(([key, value]) => ({\n key,\n value,\n type: 'encrypted' as const,\n target: ['production', 'preview', 'development'],\n }))\n\n // Vercel 官方 `upsert=true` 支持按 key 覆盖已有环境变量,避免重复部署时报“已存在”。\n await vercelFetch(\n token,\n `/v10/projects/${projectId}/env?upsert=true`,\n {\n method: 'POST',\n body: JSON.stringify(envEntries),\n },\n )\n logger.info('Vercel env vars set', { projectId, count: envEntries.length })\n return ok(undefined)\n }\n catch (error) {\n logger.error('Vercel env vars setup failed', { projectId, error })\n return err(toDeployError(HaiDeployError.ENV_VAR_FAILED, 'deploy_envVarFailed', error))\n }\n },\n\n async deploy(projectId: string, outputDir: string): Promise<HaiResult<DeployResult>> {\n if (!token) {\n return err(\n HaiDeployError.AUTH_REQUIRED,\n deployM('deploy_authRequired'),\n )\n }\n\n logger.debug('Deploying to Vercel', { projectId, outputDir })\n try {\n // 收集所有文件\n const filePaths = collectFiles(outputDir, outputDir)\n const files: Array<{ file: string, sha: string, size: number }> = []\n\n // 上传每个文件\n for (const filePath of filePaths) {\n const fullPath = join(outputDir, filePath)\n const content = readFileSync(fullPath)\n const sha = createHash('sha1').update(content).digest('hex')\n const size = statSync(fullPath).size\n\n await uploadFile(token, content, sha)\n files.push({ file: filePath, sha, size })\n }\n\n logger.debug('Files uploaded', { count: files.length })\n\n // 创建部署\n const deployment = await vercelFetch<{ id: string, url: string }>(\n token,\n '/v13/deployments',\n {\n method: 'POST',\n body: JSON.stringify({\n name: projectId,\n files,\n projectSettings: { framework: 'sveltekit' },\n }),\n },\n )\n\n // 轮询部署状态\n const finalStatus = await pollDeploymentStatus(token, deployment.id)\n\n const result: DeployResult = {\n url: `https://${deployment.url}`,\n deploymentId: deployment.id,\n status: finalStatus,\n envVarsSet: [],\n }\n\n logger.info('Vercel deployment complete', {\n deploymentId: deployment.id,\n url: result.url,\n status: finalStatus,\n })\n\n return ok(result)\n }\n catch (error) {\n logger.error('Vercel deployment failed', { projectId, error })\n return err(toDeployError(HaiDeployError.UPLOAD_FAILED, 'deploy_uploadFailed', error))\n }\n },\n }\n}\n\n// ─── 内部辅助 ───\n\n/**\n * 查找已有的 Vercel 项目\n *\n * @param token - API Token\n * @param projectName - 项目名称\n * @returns 项目 ID,不存在时返回 null\n */\nasync function findExistingProject(token: string, projectName: string): Promise<string | null> {\n try {\n const project = await vercelFetch<{ id: string }>(token, `/v10/projects/${projectName}`)\n return project.id\n }\n catch (error) {\n if (error instanceof VercelApiError && error.status === 404) {\n return null\n }\n throw error\n }\n}\n\n/**\n * 上传单个文件到 Vercel\n *\n * @param token - API Token\n * @param content - 文件内容\n * @param sha - 文件 SHA1 哈希\n */\nasync function uploadFile(token: string, content: Uint8Array, sha: string): Promise<void> {\n const url = `${VERCEL_API}/v2/files`\n const uploadContent = new Uint8Array(content)\n const response = await fetch(url, {\n method: 'POST',\n headers: {\n 'Authorization': `Bearer ${token}`,\n 'Content-Type': 'application/octet-stream',\n 'x-vercel-digest': sha,\n },\n body: new Blob([uploadContent]),\n })\n\n if (!response.ok && response.status !== 409) {\n // 409 表示文件已存在,可忽略\n throw new Error(deployM('deploy_fileUploadFailed', { params: { status: String(response.status) } }))\n }\n}\n\n/**\n * 轮询部署状态直到完成\n *\n * @param token - API Token\n * @param deploymentId - 部署 ID\n * @returns 最终状态\n */\nasync function pollDeploymentStatus(\n token: string,\n deploymentId: string,\n): Promise<'ready' | 'building' | 'error'> {\n for (let i = 0; i < MAX_POLL_ATTEMPTS; i++) {\n const deployment = await vercelFetch<{ readyState: string }>(\n token,\n `/v13/deployments/${deploymentId}`,\n )\n\n if (deployment.readyState === 'READY') {\n return 'ready'\n }\n if (deployment.readyState === 'ERROR' || deployment.readyState === 'CANCELED') {\n return 'error'\n }\n\n // 等待后重试\n await new Promise(resolve => setTimeout(resolve, POLL_INTERVAL))\n }\n\n // 超时仍在构建\n return 'building'\n}\n","/**\n * @h-ai/deploy — Aliyun SMS Provisioner\n *\n * 验证阿里云 API 凭证用于短信服务。 阿里云短信资源(签名/模板)通常在控制台预配置,此 Provisioner 仅验证凭证。\n * @module deploy-provisioner-aliyun\n */\n\nimport type { HaiResult } from '@h-ai/core'\nimport type { ServiceProvisioner } from '../deploy-internal-types.js'\nimport type { ProvisionResult } from '../deploy-types.js'\nimport { core, err, ok } from '@h-ai/core'\nimport { deployM } from '../deploy-i18n.js'\nimport { HaiDeployError } from '../deploy-types.js'\n\nconst logger = core.logger.child({ module: 'deploy', scope: 'provisioner-aliyun' })\n\n/**\n * 创建 Aliyun SMS Provisioner\n *\n * @returns ServiceProvisioner 实例\n */\nexport function createAliyunProvisioner(): ServiceProvisioner {\n let accessKey: string | null = null\n let secretKey: string | null = null\n let signName = ''\n\n return {\n name: 'aliyun',\n serviceType: 'sms',\n\n async authenticate(credentials: Record<string, string>): Promise<HaiResult<string>> {\n logger.debug('Authenticating with Aliyun')\n try {\n const akId = credentials.accessKeyId ?? credentials.access_key_id ?? credentials.access_key ?? ''\n const akSecret = credentials.accessKeySecret ?? credentials.access_key_secret ?? credentials.secret_key ?? ''\n\n if (!akId || !akSecret || !credentials.signName) {\n throw new Error(deployM('deploy_credentialMissing', { params: { fields: 'accessKeyId, accessKeySecret, signName' } }))\n }\n\n accessKey = akId\n secretKey = akSecret\n signName = credentials.signName\n logger.info('Aliyun authenticated', { accessKeyId: `${akId.slice(0, 6)}***` })\n return ok(akId)\n }\n catch (error) {\n logger.error('Aliyun authentication failed', { error })\n return err(\n HaiDeployError.AUTH_FAILED,\n deployM('deploy_authFailed', {\n params: { error: error instanceof Error ? error.message : String(error) },\n }),\n error,\n )\n }\n },\n\n async provision(_appName: string): Promise<HaiResult<ProvisionResult>> {\n if (!accessKey || !secretKey) {\n return err(\n HaiDeployError.AUTH_REQUIRED,\n deployM('deploy_authRequired'),\n )\n }\n\n logger.debug('Provisioning Aliyun SMS service')\n\n // 阿里云短信不支持 API 创建资源,仅返回凭证作为环境变量\n return ok({\n serviceType: 'sms',\n provisionerName: 'aliyun',\n resourceStatus: 'reused',\n envVars: {\n HAI_REACH_PROVIDERS: JSON.stringify([{ name: 'sms', type: 'aliyun-sms', accessKeyId: accessKey, accessKeySecret: secretKey, signName }]),\n },\n resourceInfo: 'aliyun:verify-only',\n })\n },\n }\n}\n","/**\n * @h-ai/deploy — Neon PostgreSQL Provisioner\n *\n * 通过 Neon REST API 自动创建 PostgreSQL 数据库。\n * @module deploy-provisioner-neon\n */\n\nimport type { HaiResult } from '@h-ai/core'\nimport type { ServiceProvisioner } from '../deploy-internal-types.js'\nimport type { ProvisionResult } from '../deploy-types.js'\nimport { core, err, ok } from '@h-ai/core'\nimport { deployM } from '../deploy-i18n.js'\nimport { recoveryFailure } from '../deploy-recovery.js'\nimport { HaiDeployError } from '../deploy-types.js'\n\nconst logger = core.logger.child({ module: 'deploy', scope: 'provisioner-neon' })\n\n/** Neon API 基址 */\nconst NEON_API = 'https://console.neon.tech/api/v2'\n\n/** Neon 新建项目默认生成的数据库名。 */\nconst DEFAULT_NEON_DATABASE_NAME = 'neondb'\n\n/** Neon 新建项目默认生成的角色名。 */\nconst DEFAULT_NEON_ROLE_NAME = 'neondb_owner'\n\ninterface NeonProjectSummary {\n id: string\n name: string\n}\n\ninterface NeonProjectsResponse {\n projects?: NeonProjectSummary[]\n}\n\ninterface NeonCreateProjectResponse {\n connection_uris?: Array<{ connection_uri?: string }>\n project?: { id?: string }\n}\n\ninterface NeonConnectionUriResponse {\n uri?: string\n}\n\n/** 统一发起 Neon API 请求。 */\nasync function neonFetch<T>(token: string, path: string, options?: RequestInit): Promise<T> {\n const response = await fetch(`${NEON_API}${path}`, {\n ...options,\n headers: {\n 'Accept': 'application/json',\n 'Authorization': `Bearer ${token}`,\n 'Content-Type': 'application/json',\n ...options?.headers,\n },\n })\n\n if (!response.ok) {\n throw new Error(deployM('deploy_apiError', { params: { service: 'Neon', status: String(response.status) } }))\n }\n\n return response.json() as Promise<T>\n}\n\n/** 列出当前账号下的 Neon 项目。 */\nasync function listNeonProjects(token: string): Promise<NeonProjectSummary[]> {\n const data = await neonFetch<NeonProjectsResponse>(token, '/projects')\n return data.projects ?? []\n}\n\n/** 按名称查找已有的 Neon 项目。 */\nasync function findExistingNeonProject(token: string, projectName: string): Promise<NeonProjectSummary | null> {\n const projects = await listNeonProjects(token)\n return projects.find(project => project.name === projectName) ?? null\n}\n\n/**\n * 获取现有项目的连接串。\n *\n * Neon 官方 OpenAPI 提供 `GET /projects/{project_id}/connection_uri`。\n * 这里使用创建项目时的默认数据库/角色名,保证本模块创建的项目可被幂等复用。\n */\nasync function getNeonConnectionUri(token: string, projectId: string): Promise<string> {\n const query = new URLSearchParams({\n database_name: DEFAULT_NEON_DATABASE_NAME,\n role_name: DEFAULT_NEON_ROLE_NAME,\n })\n const data = await neonFetch<NeonConnectionUriResponse>(\n token,\n `/projects/${projectId}/connection_uri?${query.toString()}`,\n { headers: { 'Content-Type': 'application/json' } },\n )\n\n if (!data.uri) {\n throw new Error(deployM('deploy_provisionNoResult', { params: { service: 'Neon' } }))\n }\n\n return data.uri\n}\n\n/** 构建统一的 Neon 开通结果。 */\nfunction buildNeonProvisionResult(projectId: string, connectionUri: string, resourceStatus: 'created' | 'reused'): ProvisionResult {\n return {\n serviceType: 'db',\n provisionerName: 'neon',\n resourceStatus,\n envVars: {\n HAI_DB: JSON.stringify({ type: 'postgresql', url: connectionUri, database: decodeURIComponent(new URL(connectionUri).pathname.slice(1)) }),\n },\n resourceInfo: `neon-project:${projectId}`,\n }\n}\n\n/**\n * 创建 Neon PostgreSQL Provisioner\n *\n * @returns ServiceProvisioner 实例\n *\n * @example\n * ```ts\n * const neon = createNeonProvisioner()\n * await neon.authenticate({ apiKey: 'neon_xxx' })\n * const result = await neon.provision('my-app')\n * ```\n */\nexport function createNeonProvisioner(): ServiceProvisioner {\n let token: string | null = null\n\n return {\n name: 'neon',\n serviceType: 'db',\n\n async authenticate(credentials: Record<string, string>): Promise<HaiResult<string>> {\n logger.debug('Authenticating with Neon')\n try {\n const apiToken = credentials.apiKey ?? credentials.token ?? credentials.api_key ?? ''\n if (!apiToken) {\n throw new Error(deployM('deploy_credentialMissing', { params: { fields: 'token' } }))\n }\n\n await listNeonProjects(apiToken)\n token = apiToken\n logger.info('Neon authenticated')\n return ok('neon-user')\n }\n catch (error) {\n logger.error('Neon authentication failed', { error })\n return err(\n HaiDeployError.AUTH_FAILED,\n deployM('deploy_authFailed', {\n params: { error: error instanceof Error ? error.message : String(error) },\n }),\n error,\n )\n }\n },\n\n async provision(appName: string): Promise<HaiResult<ProvisionResult>> {\n if (!token) {\n return err(\n HaiDeployError.AUTH_REQUIRED,\n deployM('deploy_authRequired'),\n )\n }\n\n logger.debug('Provisioning Neon database', { appName })\n let resource: { resourceInfo: string, resourceStatus: 'created' | 'reused' } | undefined\n try {\n const projectName = `${appName}-db`\n\n const existingProject = await findExistingNeonProject(token, projectName)\n if (existingProject !== null) {\n resource = { resourceInfo: `neon-project:${existingProject.id}`, resourceStatus: 'reused' }\n const connectionUri = await getNeonConnectionUri(token, existingProject.id)\n logger.info('Neon project reused', {\n projectId: existingProject.id,\n projectName,\n })\n return ok(buildNeonProvisionResult(existingProject.id, connectionUri, 'reused'))\n }\n\n const data = await neonFetch<NeonCreateProjectResponse>(token, '/projects', {\n method: 'POST',\n body: JSON.stringify({\n project: {\n name: projectName,\n pg_version: 16,\n },\n }),\n })\n\n const projectId = data.project?.id ?? ''\n if (projectId)\n resource = { resourceInfo: `neon-project:${projectId}`, resourceStatus: 'created' }\n const connectionUri = data.connection_uris?.[0]?.connection_uri ?? ''\n if (!projectId || !connectionUri) {\n throw new Error(deployM('deploy_provisionNoResult', { params: { service: 'Neon' } }))\n }\n\n logger.info('Neon database provisioned', { projectId })\n\n return ok(buildNeonProvisionResult(projectId, connectionUri, 'created'))\n }\n catch (error) {\n logger.error('Neon provisioning failed', { appName })\n if (resource) {\n return recoveryFailure({ ...HaiDeployError.PROVISION_FAILED, message: '' }, {\n projectName: appName,\n stage: 'provision:db',\n resources: [{ serviceType: 'db', provisionerName: 'neon', ...resource }],\n })\n }\n return err(\n HaiDeployError.PROVISION_FAILED,\n deployM('deploy_provisionFailed', {\n params: {\n service: 'neon',\n error: error instanceof Error ? error.message : String(error),\n },\n }),\n error,\n )\n }\n },\n }\n}\n","/**\n * @h-ai/deploy — Cloudflare R2 Provisioner\n *\n * 通过 Cloudflare API 自动创建 R2 存储桶。\n * @module deploy-provisioner-r2\n */\n\nimport type { HaiResult } from '@h-ai/core'\nimport type { ServiceProvisioner } from '../deploy-internal-types.js'\nimport type { ProvisionResult } from '../deploy-types.js'\nimport { core, err, ok } from '@h-ai/core'\nimport { deployM } from '../deploy-i18n.js'\nimport { HaiDeployError } from '../deploy-types.js'\n\nconst logger = core.logger.child({ module: 'deploy', scope: 'provisioner-r2' })\n\n/** Cloudflare API 基址 */\nconst CF_API = 'https://api.cloudflare.com/client/v4'\n\n/**\n * 创建 Cloudflare R2 Provisioner\n *\n * @returns ServiceProvisioner 实例\n */\nexport function createR2Provisioner(): ServiceProvisioner {\n let token: string | null = null\n let accountId: string | null = null\n let accessKey = ''\n let secretKey = ''\n\n return {\n name: 'r2',\n serviceType: 'storage',\n\n async authenticate(credentials: Record<string, string>): Promise<HaiResult<string>> {\n logger.debug('Authenticating with Cloudflare')\n try {\n const acctId = credentials.accountId ?? credentials.account_id ?? ''\n const apiTok = credentials.apiToken ?? credentials.api_token ?? credentials.token ?? ''\n if (!acctId || !apiTok || !credentials.accessKeyId || !credentials.secretAccessKey) {\n throw new Error(deployM('deploy_credentialMissing', { params: { fields: 'accountId, apiToken, accessKeyId, secretAccessKey' } }))\n }\n\n const res = await fetch(`${CF_API}/accounts/${acctId}/r2/buckets`, {\n headers: { Authorization: `Bearer ${apiTok}` },\n })\n if (!res.ok) {\n throw new Error(deployM('deploy_apiError', { params: { service: 'Cloudflare', status: String(res.status) } }))\n }\n\n accountId = acctId\n token = apiTok\n accessKey = credentials.accessKeyId\n secretKey = credentials.secretAccessKey\n logger.info('Cloudflare R2 authenticated', { accountId: acctId })\n return ok(acctId)\n }\n catch (error) {\n logger.error('Cloudflare R2 authentication failed', { error })\n return err(\n HaiDeployError.AUTH_FAILED,\n deployM('deploy_authFailed', {\n params: { error: error instanceof Error ? error.message : String(error) },\n }),\n error,\n )\n }\n },\n\n async provision(appName: string): Promise<HaiResult<ProvisionResult>> {\n if (!token || !accountId) {\n return err(\n HaiDeployError.AUTH_REQUIRED,\n deployM('deploy_authRequired'),\n )\n }\n\n const bucketName = `${appName}-storage`.toLowerCase().replace(/[^a-z0-9-]/g, '-')\n\n logger.debug('Provisioning R2 bucket', { appName, bucketName })\n try {\n // 创建桶\n const createRes = await fetch(\n `${CF_API}/accounts/${accountId}/r2/buckets`,\n {\n method: 'POST',\n headers: {\n 'Authorization': `Bearer ${token}`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ name: bucketName }),\n },\n )\n\n // 409 表示桶已存在,可继续\n if (!createRes.ok && createRes.status !== 409) {\n throw new Error(deployM('deploy_apiError', { params: { service: 'Cloudflare', status: String(createRes.status) } }))\n }\n\n logger.info('R2 bucket provisioned', { bucketName })\n\n return ok({\n serviceType: 'storage',\n provisionerName: 'r2',\n resourceStatus: createRes.status === 409 ? 'reused' : 'created',\n envVars: {\n HAI_STORAGE: JSON.stringify({\n type: 's3',\n endpoint: `https://${accountId}.r2.cloudflarestorage.com`,\n bucket: bucketName,\n region: 'auto',\n accessKeyId: accessKey,\n secretAccessKey: secretKey,\n }),\n },\n resourceInfo: `r2-bucket:${bucketName}`,\n })\n }\n catch (error) {\n logger.error('R2 provisioning failed', { appName, error })\n return err(\n HaiDeployError.PROVISION_FAILED,\n deployM('deploy_provisionFailed', {\n params: {\n service: 'r2',\n error: error instanceof Error ? error.message : String(error),\n },\n }),\n error,\n )\n }\n },\n }\n}\n","/**\n * @h-ai/deploy — Resend Email Provisioner\n *\n * 通过 Resend REST API 验证 API Key 并获取域信息。 Resend 不支持通过 API 创建账户,此 Provisioner 仅验证已有凭证。\n * @module deploy-provisioner-resend\n */\n\nimport type { HaiResult } from '@h-ai/core'\nimport type { ServiceProvisioner } from '../deploy-internal-types.js'\nimport type { ProvisionResult } from '../deploy-types.js'\nimport { core, err, ok } from '@h-ai/core'\n\nimport { deployM } from '../deploy-i18n.js'\nimport { HaiDeployError } from '../deploy-types.js'\n\nconst logger = core.logger.child({ module: 'deploy', scope: 'provisioner-resend' })\n\n/** Resend API 基址 */\nconst RESEND_API = 'https://api.resend.com'\n\n/**\n * 创建 Resend Email Provisioner\n *\n * @returns ServiceProvisioner 实例\n */\nexport function createResendProvisioner(): ServiceProvisioner {\n let token: string | null = null\n let from = ''\n\n return {\n name: 'resend',\n serviceType: 'email',\n\n async authenticate(credentials: Record<string, string>): Promise<HaiResult<string>> {\n logger.debug('Authenticating with Resend')\n try {\n const apiToken = credentials.apiKey ?? credentials.api_key ?? credentials.token ?? ''\n if (!apiToken || !credentials.from) {\n throw new Error(deployM('deploy_credentialMissing', { params: { fields: 'apiKey, from' } }))\n }\n\n const res = await fetch(`${RESEND_API}/domains`, {\n headers: { Authorization: `Bearer ${apiToken}` },\n })\n if (!res.ok) {\n throw new Error(deployM('deploy_apiError', { params: { service: 'Resend', status: String(res.status) } }))\n }\n token = apiToken\n from = credentials.from\n logger.info('Resend authenticated')\n return ok('resend-user')\n }\n catch (error) {\n logger.error('Resend authentication failed', { error })\n return err(\n HaiDeployError.AUTH_FAILED,\n deployM('deploy_authFailed', {\n params: { error: error instanceof Error ? error.message : String(error) },\n }),\n error,\n )\n }\n },\n\n async provision(_appName: string): Promise<HaiResult<ProvisionResult>> {\n if (!token) {\n return err(\n HaiDeployError.AUTH_REQUIRED,\n deployM('deploy_authRequired'),\n )\n }\n\n logger.debug('Provisioning Resend email service')\n\n // Resend 不支持 API 创建资源,仅返回凭证作为环境变量\n return ok({\n serviceType: 'email',\n provisionerName: 'resend',\n resourceStatus: 'reused',\n envVars: {\n HAI_REACH_PROVIDERS: JSON.stringify([{ name: 'email', type: 'smtp', host: 'smtp.resend.com', port: 465, secure: true, user: 'resend', pass: token, from }]),\n },\n resourceInfo: 'resend:verify-only',\n })\n },\n }\n}\n","/**\n * @h-ai/deploy — Upstash Redis Provisioner\n *\n * 通过 Upstash REST API 自动创建 Redis 数据库。\n * @module deploy-provisioner-upstash\n */\n\nimport type { HaiResult } from '@h-ai/core'\nimport type { ServiceProvisioner } from '../deploy-internal-types.js'\nimport type { ProvisionResult } from '../deploy-types.js'\nimport { Buffer } from 'node:buffer'\nimport { core, err, ok } from '@h-ai/core'\n\nimport { deployM } from '../deploy-i18n.js'\nimport { recoveryFailure } from '../deploy-recovery.js'\nimport { HaiDeployError } from '../deploy-types.js'\n\nconst logger = core.logger.child({ module: 'deploy', scope: 'provisioner-upstash' })\n\n/** Upstash API 基址 */\nconst UPSTASH_API = 'https://api.upstash.com'\n\ninterface UpstashDatabase {\n database_id?: string\n database_name?: string\n endpoint?: string\n port?: number\n password?: string\n}\n\n/** 构建 Upstash Developer API 的 Basic Auth 请求头。 */\nfunction createUpstashAuthHeader(email: string, apiKey: string): string {\n return `Basic ${Buffer.from(`${email}:${apiKey}`).toString('base64')}`\n}\n\n/** 统一发起 Upstash Developer API 请求。 */\nasync function upstashFetch<T>(\n email: string,\n apiKey: string,\n path: string,\n options?: RequestInit,\n): Promise<T> {\n const response = await fetch(`${UPSTASH_API}${path}`, {\n ...options,\n headers: {\n 'Authorization': createUpstashAuthHeader(email, apiKey),\n 'Content-Type': 'application/json',\n ...options?.headers,\n },\n })\n\n if (!response.ok) {\n throw new Error(deployM('deploy_apiError', { params: { service: 'Upstash', status: String(response.status) } }))\n }\n\n return response.json() as Promise<T>\n}\n\n/** 列出当前账号下的所有 Upstash 数据库。 */\nasync function listUpstashDatabases(email: string, apiKey: string): Promise<UpstashDatabase[]> {\n return upstashFetch<UpstashDatabase[]>(email, apiKey, '/v2/redis/databases')\n}\n\n/** 按数据库名查找已有资源。 */\nasync function findExistingUpstashDatabase(\n email: string,\n apiKey: string,\n databaseName: string,\n): Promise<UpstashDatabase | null> {\n const databases = await listUpstashDatabases(email, apiKey)\n return databases.find(database => database.database_name === databaseName) ?? null\n}\n\n/** 获取单个数据库详情。 */\nasync function getUpstashDatabase(email: string, apiKey: string, databaseId: string): Promise<UpstashDatabase> {\n return upstashFetch<UpstashDatabase>(email, apiKey, `/v2/redis/database/${databaseId}`)\n}\n\n/** 将 Upstash 响应转换为 deploy 统一结果。 */\nfunction buildUpstashProvisionResult(database: UpstashDatabase, resourceStatus: 'created' | 'reused'): ProvisionResult {\n const databaseId = database.database_id ?? ''\n\n if (!databaseId || !database.endpoint || !database.password || !database.port) {\n throw new Error(deployM('deploy_provisionNoResult', { params: { service: 'Upstash' } }))\n }\n\n return {\n serviceType: 'cache',\n provisionerName: 'upstash',\n resourceStatus,\n envVars: {\n HAI_CACHE: JSON.stringify({ type: 'redis', url: `rediss://default:${encodeURIComponent(database.password)}@${database.endpoint}:${database.port}` }),\n },\n resourceInfo: `upstash-db:${databaseId}`,\n }\n}\n\n/**\n * 创建 Upstash Redis Provisioner\n *\n * @returns ServiceProvisioner 实例\n */\nexport function createUpstashProvisioner(): ServiceProvisioner {\n let apiKey: string | null = null\n let email: string | null = null\n\n return {\n name: 'upstash',\n serviceType: 'cache',\n\n async authenticate(credentials: Record<string, string>): Promise<HaiResult<string>> {\n logger.debug('Authenticating with Upstash')\n try {\n const userEmail = credentials.email ?? ''\n const userKey = credentials.apiKey ?? credentials.api_key ?? credentials.token ?? ''\n if (!userEmail || !userKey) {\n throw new Error(deployM('deploy_credentialMissing', { params: { fields: 'email, api_key' } }))\n }\n\n await listUpstashDatabases(userEmail, userKey)\n\n email = userEmail\n apiKey = userKey\n logger.info('Upstash authenticated', { email: userEmail })\n return ok(userEmail)\n }\n catch (error) {\n logger.error('Upstash authentication failed', { error })\n return err(\n HaiDeployError.AUTH_FAILED,\n deployM('deploy_authFailed', {\n params: { error: error instanceof Error ? error.message : String(error) },\n }),\n error,\n )\n }\n },\n\n async provision(appName: string): Promise<HaiResult<ProvisionResult>> {\n if (!apiKey || !email) {\n return err(\n HaiDeployError.AUTH_REQUIRED,\n deployM('deploy_authRequired'),\n )\n }\n\n logger.debug('Provisioning Upstash Redis', { appName })\n let resource: { resourceInfo: string, resourceStatus: 'created' | 'reused' } | undefined\n try {\n const databaseName = `${appName}-cache`\n\n const existingDatabase = await findExistingUpstashDatabase(email, apiKey, databaseName)\n if (existingDatabase !== null) {\n const databaseId = existingDatabase.database_id ?? ''\n if (!databaseId) {\n throw new Error(deployM('deploy_provisionNoResult', { params: { service: 'Upstash' } }))\n }\n\n resource = { resourceInfo: `upstash-db:${databaseId}`, resourceStatus: 'reused' }\n const detail = await getUpstashDatabase(email, apiKey, databaseId)\n logger.info('Upstash Redis reused', { databaseId, databaseName })\n return ok(buildUpstashProvisionResult({ ...existingDatabase, ...detail }, 'reused'))\n }\n\n const data = await upstashFetch<UpstashDatabase>(email, apiKey, '/v2/redis/database', {\n method: 'POST',\n body: JSON.stringify({\n name: databaseName,\n region: 'global',\n tls: true,\n }),\n })\n\n if (data.database_id)\n resource = { resourceInfo: `upstash-db:${data.database_id}`, resourceStatus: 'created' }\n logger.info('Upstash Redis provisioned', { databaseId: data.database_id })\n\n return ok(buildUpstashProvisionResult(data, 'created'))\n }\n catch (error) {\n logger.error('Upstash provisioning failed', { appName })\n if (resource) {\n return recoveryFailure({ ...HaiDeployError.PROVISION_FAILED, message: '' }, {\n projectName: appName,\n stage: 'provision:cache',\n resources: [{ serviceType: 'cache', provisionerName: 'upstash', ...resource }],\n })\n }\n return err(\n HaiDeployError.PROVISION_FAILED,\n deployM('deploy_provisionFailed', {\n params: {\n service: 'upstash',\n error: error instanceof Error ? error.message : String(error),\n },\n }),\n error,\n )\n }\n },\n }\n}\n","/**\n * @h-ai/deploy — 模块主入口\n *\n * 提供 deploy 单例对象,暴露完整的自动化部署 API。\n * @module deploy-main\n */\n\nimport type { HaiResult } from '@h-ai/core'\nimport type { DeployConfig, DeployConfigInput } from './deploy-config.js'\nimport type { DeployProvider, ServiceProvisioner } from './deploy-internal-types.js'\nimport type {\n DeployAppOptions,\n DeployCredentialOperations,\n DeployFunctions,\n DeployRecoveryInfo,\n DeployResult,\n ProvisionResult,\n ScanResult,\n ServiceType,\n} from './deploy-types.js'\nimport { core, err, ok } from '@h-ai/core'\nimport { DeployConfigSchema } from './deploy-config.js'\nimport {\n getCredentialsPath,\n loadCredentials,\n saveCredential,\n saveCredentials,\n} from './deploy-credentials.js'\nimport { buildApp, resolveOutputDir } from './deploy-functions.js'\nimport { deployM } from './deploy-i18n.js'\nimport { getDeployRecovery, recoveryFailure } from './deploy-recovery.js'\nimport { scanApp } from './deploy-scanner.js'\nimport { HaiDeployError } from './deploy-types.js'\nimport { createVercelProvider } from './providers/deploy-provider-vercel.js'\nimport { createAliyunProvisioner } from './provisioners/deploy-provisioner-aliyun.js'\nimport { createNeonProvisioner } from './provisioners/deploy-provisioner-neon.js'\nimport { createR2Provisioner } from './provisioners/deploy-provisioner-r2.js'\nimport { createResendProvisioner } from './provisioners/deploy-provisioner-resend.js'\nimport { createUpstashProvisioner } from './provisioners/deploy-provisioner-upstash.js'\n\nconst logger = core.logger.child({ module: 'deploy', scope: 'main' })\n\n// ─── 内部状态 ───\n\nlet currentConfig: DeployConfig | null = null\nlet currentProvider: DeployProvider | null = null\nconst currentProvisioners: Map<ServiceType, ServiceProvisioner> = new Map()\n\n/** 并发初始化防护标志 */\nlet initInProgress = false\n\n// ─── 未初始化占位 ───\n\nconst notInitialized = core.module.createNotInitializedKit(\n HaiDeployError.NOT_INITIALIZED,\n () => deployM('deploy_notInitialized'),\n)\n\n// ─── Provider 工厂 ───\n\n/**\n * 根据配置类型创建对应的 DeployProvider\n *\n * @param type - Provider 类型\n * @returns DeployProvider 实例\n */\nfunction createProviderByType(type: string): DeployProvider {\n switch (type) {\n case 'vercel':\n return createVercelProvider()\n default:\n throw new Error(deployM('deploy_unsupportedProviderType', { params: { type } }))\n }\n}\n\n// ─── Provisioner 工厂 ───\n\n/**\n * 根据 provisioner 名称创建对应的 ServiceProvisioner\n *\n * @param provisioner - Provisioner 标识\n * @returns ServiceProvisioner 实例\n */\nfunction createProvisionerByName(provisioner: string): ServiceProvisioner {\n switch (provisioner) {\n case 'neon':\n return createNeonProvisioner()\n case 'upstash':\n return createUpstashProvisioner()\n case 'cloudflare-r2':\n return createR2Provisioner()\n case 'resend':\n return createResendProvisioner()\n case 'aliyun':\n return createAliyunProvisioner()\n default:\n throw new Error(deployM('deploy_unsupportedProvisionerType', { params: { type: provisioner } }))\n }\n}\n\n/**\n * 从配置中提取 provisioner 凭证并转为 Record<string, string>\n *\n * @param serviceConfig - 服务配置对象\n * @returns 凭证键值对\n */\nfunction extractCredentials(serviceConfig: Record<string, unknown>): Record<string, string> {\n const result: Record<string, string> = {}\n for (const [key, value] of Object.entries(serviceConfig)) {\n if (key !== 'provisioner' && typeof value === 'string') {\n result[key] = value\n }\n }\n return result\n}\n\n/**\n * Deploy 凭证子功能。\n *\n * 这些操作仅处理本地 `~/.hai/credentials.yml`,供 CLI 在读取 `_deploy.yml`\n * 之前注入 `HAI_DEPLOY_*` 环境变量,因此不依赖 `deploy.init()`。\n */\nconst deployCredentials: DeployCredentialOperations = {\n getPath: () => getCredentialsPath(),\n load: () => loadCredentials(),\n save: (key: string, value: string) => saveCredential(key, value),\n saveAll: (entries: Record<string, string>) => saveCredentials(entries),\n}\n\n// ─── 模块单例 ───\n\n/**\n * Deploy 模块单例\n *\n * @example\n * ```ts\n * import { deploy } from '@h-ai/deploy'\n *\n * await deploy.init({ provider: { type: 'vercel', token: 'xxx' } })\n * const result = await deploy.deployApp('./apps/my-app')\n * await deploy.close()\n * ```\n */\nexport const deploy: DeployFunctions = {\n credentials: deployCredentials,\n\n async init(config: DeployConfigInput): Promise<HaiResult<void>> {\n // 并发初始化防护:避免多次 init 同时执行导致资源泄漏\n if (initInProgress) {\n logger.warn('Deploy init already in progress, skipping concurrent call')\n return err(\n HaiDeployError.CONFIG_ERROR,\n deployM('deploy_configError', { params: { error: 'init already in progress' } }),\n )\n }\n initInProgress = true\n\n try {\n if (currentProvider) {\n logger.warn('Deploy module is already initialized, reinitializing')\n await deploy.close()\n }\n\n logger.info('Initializing deploy module')\n\n const parseResult = DeployConfigSchema.safeParse(config)\n if (!parseResult.success) {\n logger.error('Deploy config validation failed', { error: parseResult.error.message })\n return err(\n HaiDeployError.CONFIG_ERROR,\n deployM('deploy_configError', { params: { error: parseResult.error.message } }),\n parseResult.error,\n )\n }\n const parsed = parseResult.data\n\n try {\n // 创建 Provider\n const provider = createProviderByType(parsed.provider.type)\n const authResult = await provider.authenticate(parsed.provider.token)\n if (!authResult.success) {\n return err(authResult.error)\n }\n logger.info('Provider authenticated', { provider: parsed.provider.type, user: authResult.data })\n\n // 创建 Provisioners\n currentProvisioners.clear()\n if (parsed.services) {\n const serviceEntries = Object.entries(parsed.services) as Array<[ServiceType, Record<string, unknown> | undefined]>\n for (const [serviceType, serviceConfig] of serviceEntries) {\n if (!serviceConfig)\n continue\n\n const provisioner = createProvisionerByName(serviceConfig.provisioner as string)\n const credentials = extractCredentials(serviceConfig as Record<string, unknown>)\n const provAuthResult = await provisioner.authenticate(credentials)\n if (!provAuthResult.success) {\n logger.error('Provisioner authentication failed', {\n service: serviceType,\n provisioner: (serviceConfig as Record<string, unknown>).provisioner,\n })\n currentProvisioners.clear()\n return err(provAuthResult.error)\n }\n logger.info('Provisioner authenticated', {\n service: serviceType,\n user: provAuthResult.data,\n })\n currentProvisioners.set(serviceType, provisioner)\n }\n }\n\n currentProvider = provider\n currentConfig = parsed\n logger.info('Deploy module initialized', {\n provider: parsed.provider.type,\n provisioners: [...currentProvisioners.keys()],\n })\n return ok(undefined)\n }\n catch (error) {\n // 清理部分赋值的状态\n currentProvider = null\n currentConfig = null\n currentProvisioners.clear()\n logger.error('Deploy module initialization failed', { error })\n return err(\n HaiDeployError.CONFIG_ERROR,\n deployM('deploy_configError', {\n params: { error: error instanceof Error ? error.message : String(error) },\n }),\n error,\n )\n }\n }\n finally {\n initInProgress = false\n }\n },\n\n async close(): Promise<void> {\n if (!currentProvider) {\n logger.info('Deploy module already closed, skipping')\n return\n }\n\n logger.info('Closing deploy module')\n currentProvider = null\n currentConfig = null\n currentProvisioners.clear()\n logger.info('Deploy module closed')\n },\n\n get config(): DeployConfig | null {\n return currentConfig\n },\n\n get isInitialized(): boolean {\n return currentProvider !== null\n },\n\n async scan(appDir: string): Promise<HaiResult<ScanResult>> {\n // scan 仅做本地文件分析,不依赖 Provider / Provisioner 初始化状态。\n logger.debug('Scanning application', { appDir })\n return scanApp(appDir)\n },\n\n async provisionAll(projectName: string): Promise<HaiResult<ProvisionResult[]>> {\n if (!currentProvider) {\n return notInitialized.result()\n }\n\n logger.info('Provisioning all services', { projectName, count: currentProvisioners.size })\n const results: ProvisionResult[] = []\n\n for (const [serviceType, provisioner] of currentProvisioners) {\n logger.debug('Provisioning service', { serviceType, provisioner: provisioner.name })\n const provResult = await provisioner.provision(projectName)\n if (!provResult.success) {\n logger.error('Service provisioning failed', {\n serviceType,\n provisioner: provisioner.name,\n code: provResult.error.code,\n })\n return recoveryFailure(provResult.error, {\n projectName,\n stage: `provision:${serviceType}`,\n resources: [\n ...results.map(({ envVars: _envVars, ...resource }) => resource),\n ...(getDeployRecovery(provResult.error)?.resources ?? [\n { serviceType, provisionerName: provisioner.name, resourceInfo: projectName, resourceStatus: 'unknown' as const },\n ]),\n ],\n })\n }\n results.push(provResult.data)\n logger.info('Service provisioned', { serviceType, provisioner: provisioner.name })\n }\n\n return ok(results)\n },\n\n async deployApp(\n appDir: string,\n options?: DeployAppOptions,\n ): Promise<HaiResult<DeployResult>> {\n if (!currentProvider) {\n return notInitialized.result()\n }\n\n logger.info('Starting deployment', { appDir, options })\n\n // 1. 扫描应用\n const scanResult = await scanApp(appDir)\n if (!scanResult.success) {\n return err(scanResult.error)\n }\n const scan = scanResult.data\n const projectName = options?.projectName ?? scan.appName\n\n // 2. 检查 adapter\n if (scan.isSvelteKit && !scan.adapterInstalled) {\n return err(\n HaiDeployError.ADAPTER_MISSING,\n deployM('deploy_adapterMissing', {\n params: { adapter: '@sveltejs/adapter-vercel' },\n }),\n )\n }\n\n // 3. 开通基础设施\n let allEnvVars: Record<string, string> = {}\n const recovery: DeployRecoveryInfo = { projectName, stage: 'provision', resources: [] }\n if (!options?.skipProvision) {\n const provResults = await deploy.provisionAll(projectName)\n if (!provResults.success) {\n return err(provResults.error)\n }\n recovery.resources = provResults.data.map(({ envVars: _envVars, ...resource }) => resource)\n const reachProviders: unknown[] = []\n for (const prov of provResults.data) {\n if (prov.envVars.HAI_REACH_PROVIDERS)\n reachProviders.push(...JSON.parse(prov.envVars.HAI_REACH_PROVIDERS) as unknown[])\n allEnvVars = { ...allEnvVars, ...prov.envVars }\n }\n if (reachProviders.length > 0)\n allEnvVars.HAI_REACH_PROVIDERS = JSON.stringify(reachProviders)\n }\n\n // 4. 创建平台项目\n const projectResult = await currentProvider.createProject(projectName)\n if (!projectResult.success) {\n return recoveryFailure(projectResult.error, { ...recovery, stage: 'create-project' })\n }\n const projectId = projectResult.data\n recovery.platformProjectId = projectId\n\n // 5. 设置环境变量\n if (Object.keys(allEnvVars).length > 0) {\n const envResult = await currentProvider.setEnvVars(projectId, allEnvVars)\n if (!envResult.success) {\n return recoveryFailure(envResult.error, { ...recovery, stage: 'set-env' })\n }\n }\n\n // 6. 构建应用\n if (!options?.skipBuild) {\n const buildResult = buildApp(appDir, scan.buildCommand, allEnvVars)\n if (!buildResult.success) {\n return recoveryFailure(buildResult.error, { ...recovery, stage: 'build' })\n }\n }\n\n // 7. 部署\n const outputDir = resolveOutputDir(appDir, currentConfig?.provider.type ?? 'vercel')\n const deployResult = await currentProvider.deploy(projectId, outputDir)\n if (!deployResult.success) {\n return recoveryFailure(deployResult.error, { ...recovery, stage: 'deploy' })\n }\n\n // 补充环境变量列表到结果中\n const result: DeployResult = {\n ...deployResult.data,\n envVarsSet: Object.keys(allEnvVars),\n }\n\n logger.info('Deployment completed', {\n url: result.url,\n deploymentId: result.deploymentId,\n status: result.status,\n })\n\n return ok(result)\n },\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../messages/en-US.json","../messages/zh-CN.json","../src/deploy-i18n.ts","../src/deploy-config.ts","../src/deploy-types.ts","../src/deploy-credentials.ts","../src/deploy-functions.ts","../src/deploy-recovery.ts","../src/deploy-scanner.ts","../src/container/deploy-container-compose.ts","../src/container/deploy-command.ts","../src/container/deploy-container-runtime.ts","../src/container/deploy-ssh.ts","../src/providers/deploy-provider-docker-ssh.ts","../src/providers/deploy-provider-vercel.ts","../src/provisioners/deploy-provisioner-aliyun.ts","../src/provisioners/deploy-provisioner-neon.ts","../src/provisioners/deploy-provisioner-r2.ts","../src/provisioners/deploy-provisioner-resend.ts","../src/provisioners/deploy-provisioner-upstash.ts","../src/deploy-main.ts"],"names":["core","logger","process","ok","err","join","existsSync","z","readFileSync","parse","mkdirSync","dirname","writeFileSync","stringify","randomBytes","deploy","readdirSync","connectionUri"],"mappings":"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","file":"index.js","sourcesContent":["{\n \"deploy_notInitialized\": \"Deploy module not initialized, call deploy.init() first\",\n \"deploy_initFailed\": \"Deploy module initialization failed: {error}\",\n \"deploy_unsupportedProviderType\": \"Unsupported deploy provider type: {type}\",\n \"deploy_unsupportedProvisionerType\": \"Unsupported service provisioner type: {type}\",\n \"deploy_configTokenRequired\": \"Deploy provider token is required\",\n \"deploy_authRequired\": \"Authentication required\",\n \"deploy_authFailed\": \"Authentication failed: {error}\",\n \"deploy_projectCreateFailed\": \"Project creation failed: {error}\",\n \"deploy_buildFailed\": \"Application build failed: {error}\",\n \"deploy_uploadFailed\": \"Build output upload failed: {error}\",\n \"deploy_deployFailed\": \"Deployment failed: {error}\",\n \"deploy_provisionFailed\": \"Service provisioning failed: {service} - {error}\",\n \"deploy_adapterMissing\": \"Target platform adapter not found, please install {adapter}\",\n \"deploy_scanFailed\": \"Application scan failed: {error}\",\n \"deploy_envVarFailed\": \"Environment variable setup failed: {error}\",\n \"deploy_credentialError\": \"Credential read/write failed: {error}\",\n \"deploy_credentialInvalidKey\": \"Unsupported credential key: {key}. Only HAI_DEPLOY_* keys are allowed\",\n \"deploy_credentialSaved\": \"Credentials saved\",\n \"deploy_credentialLoaded\": \"Credentials loaded\",\n \"deploy_configError\": \"Deploy config error: {error}\",\n \"deploy_credentialMissing\": \"Missing credential fields: {fields}\",\n \"deploy_apiError\": \"{service} API error ({status})\",\n \"deploy_fileUploadFailed\": \"File upload failed ({status})\",\n \"deploy_provisionNoResult\": \"No connection info returned from {service}\",\n \"deploy_recoveryFailure\": \"Deployment stopped at {stage}; inspect the recovery details.\",\n \"deploy_recoverySuggestion\": \"Inspect listed resources in the provider console before retrying with the same project name. Unknown means the request may have created a resource. Reused resources are never deleted automatically; remove newly created resources manually only after checking their use.\",\n \"deploy_commandTimeout\": \"Command timed out: {command}\",\n \"deploy_commandFailed\": \"Command failed ({command}): {error}\",\n \"deploy_containerRuntimeNotFound\": \"No usable container runtime found: {runtime}\",\n \"deploy_containerBuildFailed\": \"Container image build failed: {error}\",\n \"deploy_remoteConnectFailed\": \"Cannot connect to remote host {host}: {error}\",\n \"deploy_remoteRuntimeMissing\": \"Remote host missing container runtime or compose: {runtime}\",\n \"deploy_imageTransferFailed\": \"Image transfer failed: {error}\",\n \"deploy_healthCheckFailed\": \"Health check failed, app not ready at {url}\"\n}\n","{\n \"deploy_notInitialized\": \"Deploy 模块尚未初始化,请先调用 deploy.init()\",\n \"deploy_initFailed\": \"Deploy 模块初始化失败:{error}\",\n \"deploy_unsupportedProviderType\": \"不支持的部署平台类型:{type}\",\n \"deploy_unsupportedProvisionerType\": \"不支持的服务 Provisioner 类型:{type}\",\n \"deploy_configTokenRequired\": \"部署平台 Token 不能为空\",\n \"deploy_authRequired\": \"请先完成认证\",\n \"deploy_authFailed\": \"认证失败:{error}\",\n \"deploy_projectCreateFailed\": \"项目创建失败:{error}\",\n \"deploy_buildFailed\": \"应用构建失败:{error}\",\n \"deploy_uploadFailed\": \"构建产物上传失败:{error}\",\n \"deploy_deployFailed\": \"部署失败:{error}\",\n \"deploy_provisionFailed\": \"基础设施开通失败:{service} - {error}\",\n \"deploy_adapterMissing\": \"未检测到目标平台 adapter,请安装 {adapter}\",\n \"deploy_scanFailed\": \"应用扫描失败:{error}\",\n \"deploy_envVarFailed\": \"环境变量设置失败:{error}\",\n \"deploy_credentialError\": \"凭证读写失败:{error}\",\n \"deploy_credentialInvalidKey\": \"不支持的凭证键名:{key}。仅允许 HAI_DEPLOY_*\",\n \"deploy_credentialSaved\": \"凭证已保存\",\n \"deploy_credentialLoaded\": \"凭证已加载\",\n \"deploy_configError\": \"部署配置错误:{error}\",\n \"deploy_credentialMissing\": \"缺少凭证字段:{fields}\",\n \"deploy_apiError\": \"{service} API 请求失败({status})\",\n \"deploy_fileUploadFailed\": \"文件上传失败({status})\",\n \"deploy_provisionNoResult\": \"{service} 未返回连接信息\",\n \"deploy_recoveryFailure\": \"部署在 {stage} 阶段停止,请查看恢复清单。\",\n \"deploy_recoverySuggestion\": \"重试前在服务商控制台核对清单,并使用相同项目名。unknown 表示请求可能已创建资源。复用资源不会自动删除;新建资源仅在确认未被使用后人工清理。\",\n \"deploy_commandTimeout\": \"命令执行超时:{command}\",\n \"deploy_commandFailed\": \"命令执行失败({command}):{error}\",\n \"deploy_containerRuntimeNotFound\": \"未找到可用的容器运行时:{runtime}\",\n \"deploy_containerBuildFailed\": \"容器镜像构建失败:{error}\",\n \"deploy_remoteConnectFailed\": \"无法连接远程主机 {host}:{error}\",\n \"deploy_remoteRuntimeMissing\": \"远程主机缺少容器运行时或 compose:{runtime}\",\n \"deploy_imageTransferFailed\": \"镜像传输失败:{error}\",\n \"deploy_healthCheckFailed\": \"健康检查失败,应用未在 {url} 就绪\"\n}\n","/**\n * @h-ai/deploy — i18n\n *\n * 本文件提供部署模块的 i18n 文案访问入口。\n * @module deploy-i18n\n */\n\nimport { core } from '@h-ai/core'\nimport messagesEnUS from '../messages/en-US.json'\nimport messagesZhCN from '../messages/zh-CN.json'\n\n// ─── i18n ───\n\n/** 部署模块文案 Key 类型 */\ntype DeployMessageKey = keyof typeof messagesZhCN\n\n/**\n * 获取部署模块文案\n *\n * @param key - 文案 Key\n * @param options - 插值参数与格式化选项\n * @returns 本地化后的文案字符串\n *\n * @example\n * ```ts\n * const text = deployM('deploy_notInitialized')\n * ```\n */\nexport const deployM = core.i18n.createMessageGetter<DeployMessageKey>({\n 'zh-CN': messagesZhCN,\n 'en-US': messagesEnUS,\n})\n","/**\n * @h-ai/deploy — 部署配置 Schema\n *\n * 本文件定义部署模块的错误码、Zod Schema 和配置类型。\n * @module deploy-config\n */\n\nimport { z } from 'zod'\nimport { deployM } from './deploy-i18n.js'\n\n// ─── Provider 配置 Schema ───\n\n/** Vercel 部署平台配置 */\nconst VercelProviderConfigSchema = z.object({\n type: z.literal('vercel'),\n token: z.string().min(1, deployM('deploy_configTokenRequired')),\n})\n\n/** SSH 连接配置(docker-ssh Provider 使用 OpenSSH 客户端连接远程主机) */\nconst SshConfigSchema = z.object({\n /** 远程主机地址或 ~/.ssh/config 中的 Host 别名 */\n host: z.string().min(1),\n /** SSH 端口 */\n port: z.number().int().min(1).max(65535).default(22),\n /** SSH 用户名 */\n username: z.string().min(1),\n /** 私钥文件路径(省略时使用 ssh-agent 或 ~/.ssh 默认密钥) */\n identityFile: z.string().min(1).optional(),\n /** known_hosts 文件路径(省略时使用默认;配合 CI/临时环境隔离主机指纹) */\n knownHostsFile: z.string().min(1).optional(),\n /** 严格主机密钥校验,默认开启(true→accept-new 首次信任并拒绝变更;false→关闭校验) */\n strictHostKeyChecking: z.boolean().default(true),\n /** 连接超时(秒) */\n connectTimeoutSeconds: z.number().int().positive().default(10),\n})\n\n/** 端口直出暴露配置 */\nconst PortExposeSchema = z.object({\n type: z.literal('port').default('port'),\n /** 容器内监听端口(adapter-node 默认 3000) */\n containerPort: z.number().int().positive().default(3000),\n /** 宿主机映射端口 */\n hostPort: z.number().int().positive(),\n})\n\n/** 应用暴露配置(MVP 仅支持端口直出,域名网关为后续能力) */\nconst ExposeSchema = PortExposeSchema\n\n/** docker-ssh 部署平台配置 */\nconst DockerSshProviderConfigSchema = z.object({\n type: z.literal('docker-ssh'),\n /** SSH 连接参数 */\n ssh: SshConfigSchema,\n /** 远程主机运行参数 */\n remote: z.object({\n /** 远程应用根目录 */\n baseDir: z.string().min(1).default('/opt/hai/apps'),\n /** 远程容器运行时(auto 优先 podman) */\n runtime: z.enum(['auto', 'docker', 'podman']).default('auto'),\n }).default({ baseDir: '/opt/hai/apps', runtime: 'auto' }),\n /** 应用暴露方式 */\n expose: ExposeSchema,\n})\n\n/** 部署平台配置联合类型(后续可扩展更多平台) */\nexport const ProviderConfigSchema = z.discriminatedUnion('type', [\n VercelProviderConfigSchema,\n DockerSshProviderConfigSchema,\n])\n\n/** SSH 连接配置(parse 后) */\nexport type SshConfig = z.infer<typeof SshConfigSchema>\n\n/** 端口暴露配置(parse 后) */\nexport type PortExposeConfig = z.infer<typeof PortExposeSchema>\n\n/** docker-ssh 部署平台配置(parse 后) */\nexport type DockerSshProviderConfig = z.infer<typeof DockerSshProviderConfigSchema>\n\n// ─── Provisioner 配置 Schema ───\n\n/** Neon PostgreSQL 服务配置 */\nconst NeonServiceSchema = z.object({\n provisioner: z.literal('neon'),\n apiKey: z.string().min(1),\n})\n\n/** Upstash Redis 服务配置 */\nconst UpstashServiceSchema = z.object({\n provisioner: z.literal('upstash'),\n email: z.string().email(),\n apiKey: z.string().min(1),\n})\n\n/** Cloudflare R2 存储服务配置 */\nconst R2ServiceSchema = z.object({\n provisioner: z.literal('cloudflare-r2'),\n accessKeyId: z.string().min(1),\n secretAccessKey: z.string().min(1),\n accountId: z.string().min(1),\n apiToken: z.string().min(1),\n})\n\n/** Resend 邮件服务配置 */\nconst ResendServiceSchema = z.object({\n provisioner: z.literal('resend'),\n from: z.string().email(),\n apiKey: z.string().min(1),\n})\n\n/** 阿里云短信服务配置 */\nconst AliyunSmsServiceSchema = z.object({\n provisioner: z.literal('aliyun'),\n signName: z.string().min(1),\n accessKeyId: z.string().min(1),\n accessKeySecret: z.string().min(1),\n})\n\n/** 基础设施服务配置 */\nconst ServicesConfigSchema = z.object({\n db: z.discriminatedUnion('provisioner', [NeonServiceSchema]).optional(),\n cache: z.discriminatedUnion('provisioner', [UpstashServiceSchema]).optional(),\n storage: z.discriminatedUnion('provisioner', [R2ServiceSchema]).optional(),\n email: z.discriminatedUnion('provisioner', [ResendServiceSchema]).optional(),\n sms: z.discriminatedUnion('provisioner', [AliyunSmsServiceSchema]).optional(),\n}).optional()\n\n// ─── 完整配置 Schema ───\n\n/** 部署模块完整配置 Schema */\nexport const DeployConfigSchema = z.object({\n provider: ProviderConfigSchema,\n services: ServicesConfigSchema,\n /** 本地容器构建参数(docker-ssh 使用;auto 优先 podman) */\n container: z.object({\n runtime: z.enum(['auto', 'docker', 'podman']).default('auto'),\n }).optional(),\n})\n\n/** 部署配置类型(parse 后) */\nexport type DeployConfig = z.infer<typeof DeployConfigSchema>\n\n/** 部署配置输入类型(用户输入) */\nexport type DeployConfigInput = z.input<typeof DeployConfigSchema>\n","/**\n * @h-ai/deploy — 类型定义\n *\n * 本文件定义部署模块的核心接口和类型(非配置相关)。 配置相关类型请从 deploy-config.ts 导入。\n * @module deploy-types\n */\n\nimport type { ErrorInfo, HaiResult } from '@h-ai/core'\nimport type { DeployConfig, DeployConfigInput } from './deploy-config.js'\nimport { core } from '@h-ai/core'\n\n// ─── 错误定义(照 @h-ai/core 范式) ───\n\nconst DeployErrorInfo = {\n DEPLOY_FAILED: '001:500',\n PROJECT_CREATE_FAILED: '002:500',\n BUILD_FAILED: '003:500',\n UPLOAD_FAILED: '004:500',\n AUTH_REQUIRED: '005:401',\n AUTH_FAILED: '006:401',\n PROVISION_FAILED: '007:500',\n ADAPTER_MISSING: '008:500',\n SCAN_FAILED: '009:500',\n NOT_INITIALIZED: '010:500',\n ENV_VAR_FAILED: '011:500',\n UNSUPPORTED_TYPE: '012:400',\n CONFIG_ERROR: '013:500',\n CREDENTIAL_ERROR: '014:500',\n CONTAINER_RUNTIME_NOT_FOUND: '015:500',\n CONTAINER_BUILD_FAILED: '016:500',\n REMOTE_CONNECT_FAILED: '017:500',\n REMOTE_COMMAND_FAILED: '018:500',\n IMAGE_TRANSFER_FAILED: '019:500',\n HEALTH_CHECK_FAILED: '020:500',\n} as const satisfies ErrorInfo\n\nexport const HaiDeployError = core.error.buildHaiErrorsDef('deploy', DeployErrorInfo)\n\n/**\n * 部署错误接口\n *\n * 所有部署操作返回的错误都遵循此接口。\n *\n * @example\n * ```ts\n * const result = await deploy.deployApp('./apps/my-app')\n * if (!result.success) {\n * const error: DeployError = result.error\n * // 根据 error.code 处理\n * }\n * ```\n */\nexport interface DeployError {\n /** 错误定义 */\n def: (typeof HaiDeployError)[keyof typeof HaiDeployError]\n /** 错误消息 */\n message: string\n /** 原始错误(可选) */\n cause?: unknown\n}\n\n// ─── 服务类型 ───\n\n/** 基础设施服务类型 */\nexport type ServiceType = 'db' | 'cache' | 'storage' | 'email' | 'sms' | 'vecdb'\n\n// ─── 扫描结果 ───\n\n/**\n * 应用扫描结果\n *\n * 由 scanner 分析应用目录后返回,描述应用的框架类型、依赖和部署需求。\n */\nexport interface ScanResult {\n /** 应用名称(来自 package.json name) */\n appName: string\n /** 是否为 SvelteKit 项目 */\n isSvelteKit: boolean\n /** 目标平台 adapter 是否已安装(如 @sveltejs/adapter-vercel) */\n adapterInstalled: boolean\n /** 容器部署所需的 @sveltejs/adapter-node 是否已安装 */\n nodeAdapterInstalled: boolean\n /** 检测到的模块依赖需要的服务列表 */\n requiredServices: ServiceType[]\n /** 各服务检测到的后端类型(如 db→postgresql/mysql,vecdb→qdrant),用于生成匹配的 sidecar */\n serviceBackends: Partial<Record<ServiceType, string>>\n /** 构建命令 */\n buildCommand: string\n}\n\n// ─── 部署结果 ───\n\n/**\n * 部署结果\n *\n * 包含部署后的访问 URL、状态和已设置的环境变量。\n */\nexport interface DeployResult {\n /** 部署后的访问 URL */\n url: string\n /** 部署 ID */\n deploymentId: string\n /** 部署状态 */\n status: 'ready' | 'building' | 'error'\n /** 已设置的环境变量名列表 */\n envVarsSet: string[]\n /** 部署 Provider 名称(如 vercel / docker-ssh),容器部署时返回 */\n provider?: string\n /** 健康检查结果:passed 表示 HTTP 探测成功,container-only 表示仅确认容器运行 */\n healthCheck?: 'passed' | 'container-only' | 'skipped'\n}\n\n// ─── 开通结果 ───\n\n/**\n * 基础设施开通结果\n *\n * 由 Provisioner 开通服务后返回,包含要注入到部署平台的环境变量。\n */\nexport interface ProvisionResult {\n /** 本次新建或复用;凭证型服务始终为 reused */\n resourceStatus: 'created' | 'reused'\n /** 服务类型 */\n serviceType: ServiceType\n /** Provisioner 名称 */\n provisionerName: string\n /** 要注入到部署平台的环境变量 */\n envVars: Record<string, string>\n /** 资源标识信息(如项目名、数据库名等),用于日志和展示 */\n resourceInfo: string\n}\n\n/** 部署失败后的安全恢复信息,不含环境变量值或原始异常。 */\nexport interface DeployRecoveryInfo {\n projectName: string\n stage: string\n platformProjectId?: string\n resources: Array<{\n serviceType: ServiceType\n provisionerName: string\n resourceInfo: string\n resourceStatus: 'created' | 'reused' | 'unknown'\n }>\n}\n\n// ─── 部署选项 ───\n\n/** 部署选项 */\nexport interface DeployAppOptions {\n /** 项目名称(默认从 package.json name 提取) */\n projectName?: string\n /** 是否跳过基础设施开通 */\n skipProvision?: boolean\n /** 是否跳过构建 */\n skipBuild?: boolean\n}\n\n// ─── 凭证子功能 ───\n\n/**\n * Deploy 凭证文件操作。\n *\n * 这些方法仅操作 `~/.hai/credentials.yml`,不依赖 `deploy.init()`。\n */\nexport interface DeployCredentialOperations {\n /** 获取凭证文件绝对路径。 */\n getPath: () => string\n /** 加载凭证文件并注入 `process.env`。 */\n load: () => HaiResult<string[]>\n /** 保存单个凭证。 */\n save: (key: string, value: string) => HaiResult<void>\n /** 批量保存凭证。 */\n saveAll: (entries: Record<string, string>) => HaiResult<void>\n}\n\n// ─── 模块功能接口 ───\n\n/**\n * Deploy 模块功能接口\n *\n * 提供自动化部署的完整 API:\n * - `deploy.credentials.*()` — 凭证文件读写(不依赖 init)\n * - `deploy.init()` — 初始化(加载配置、创建 Provider 和 Provisioner)\n * - `deploy.scan()` — 扫描应用依赖(纯文件系统能力,不依赖 init)\n * - `deploy.provisionAll()` — 开通所有已配置的基础设施\n * - `deploy.deployApp()` — 完整部署流程\n * - `deploy.close()` — 关闭模块\n *\n * @example\n * ```ts\n * import { deploy } from '@h-ai/deploy'\n *\n * await deploy.init({ provider: { type: 'vercel', token: 'xxx' } })\n * const result = await deploy.deployApp('./apps/my-app')\n * if (result.success) {\n * console.log(`Deployed: ${result.data.url}`)\n * }\n * await deploy.close()\n * ```\n */\nexport interface DeployFunctions {\n /** 全局部署凭证文件操作。 */\n readonly credentials: DeployCredentialOperations\n /** 初始化模块(加载配置、创建 Provider 和 Provisioner 实例) */\n init: (config: DeployConfigInput) => Promise<HaiResult<void>>\n /** 关闭模块 */\n close: () => Promise<void>\n /** 当前配置 */\n readonly config: DeployConfig | null\n /** 是否已初始化 */\n readonly isInitialized: boolean\n\n /**\n * 扫描应用目录,检测依赖和所需服务。\n *\n * 这是纯文件系统分析能力,不依赖云端认证状态,可在 `deploy.init()` 之前调用。\n *\n * @param appDir - 应用根目录路径\n */\n scan: (appDir: string) => Promise<HaiResult<ScanResult>>\n\n /**\n * 对所有已配置的 Provisioner 执行基础设施开通\n *\n * @param projectName - 用于资源命名的项目名\n * @returns 所有 Provisioner 的结果列表\n */\n provisionAll: (projectName: string) => Promise<HaiResult<ProvisionResult[]>>\n\n /**\n * 执行完整部署流程(provision → build → deploy)\n *\n * @param appDir - 应用根目录路径\n * @param options - 部署选项\n */\n deployApp: (appDir: string, options?: DeployAppOptions) => Promise<HaiResult<DeployResult>>\n}\n","/**\n * @h-ai/deploy — 凭证管理\n *\n * 管理全局凭证文件 `~/.hai/credentials.yml`。\n * 这些 helper 由 `deploy.credentials.*` 对外暴露,供 CLI 在加载 `_deploy.yml`\n * 之前注入 `HAI_DEPLOY_*` 环境变量。\n * @module deploy-credentials\n */\n\nimport type { HaiResult } from '@h-ai/core'\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { dirname, join } from 'node:path'\nimport process from 'node:process'\nimport { core, err, ok } from '@h-ai/core'\nimport { parse, stringify } from 'yaml'\nimport { deployM } from './deploy-i18n.js'\nimport { HaiDeployError } from './deploy-types.js'\n\nconst logger = core.logger.child({ module: 'deploy', scope: 'credentials' })\n\n/** 仅允许写入 deploy 模块自有的环境变量前缀,避免把任意 YAML key 注入 process.env。 */\nconst DEPLOY_CREDENTIAL_KEY_PATTERN = /^HAI_DEPLOY_[A-Z0-9_]+$/\n\n// ─── 内部工具 ───\n\n/** 校验凭证键名是否属于 deploy 模块。 */\nfunction isAllowedCredentialKey(key: string): boolean {\n return DEPLOY_CREDENTIAL_KEY_PATTERN.test(key)\n}\n\n/**\n * 标准化凭证键值对。\n *\n * 仅保留 `HAI_DEPLOY_*` 键,且值必须是可安全序列化为字符串的标量。\n */\nfunction normalizeCredentialEntries(entries: Record<string, unknown>): Record<string, string> {\n const normalized: Record<string, string> = {}\n\n for (const [key, value] of Object.entries(entries)) {\n if (!isAllowedCredentialKey(key)) {\n logger.warn('Ignoring unsupported deploy credential key', { key })\n continue\n }\n\n if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {\n normalized[key] = String(value)\n continue\n }\n\n logger.warn('Ignoring deploy credential with non-scalar value', { key })\n }\n\n return normalized\n}\n\n/** 在写入前校验单个凭证键名。 */\nfunction assertAllowedCredentialKey(key: string): void {\n if (!isAllowedCredentialKey(key)) {\n throw new Error(deployM('deploy_credentialInvalidKey', { params: { key } }))\n }\n}\n\n/** 在写入前校验批量凭证键名。 */\nfunction assertAllowedCredentialEntries(entries: Record<string, string>): void {\n for (const key of Object.keys(entries)) {\n assertAllowedCredentialKey(key)\n }\n}\n\n/**\n * 获取凭证文件路径\n *\n * @returns `~/.hai/credentials.yml` 的绝对路径\n */\nexport function getCredentialsPath(): string {\n return join(homedir(), '.hai', 'credentials.yml')\n}\n\n/**\n * 确保凭证目录存在\n *\n * @param filePath - 凭证文件路径\n */\nfunction ensureDir(filePath: string): void {\n const dir = dirname(filePath)\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true })\n }\n}\n\n/**\n * 读取凭证文件内容\n *\n * @returns 解析后的键值对,文件不存在时返回空对象\n */\nfunction readCredentialsFile(): Record<string, string> {\n const filePath = getCredentialsPath()\n if (!existsSync(filePath)) {\n return {}\n }\n const content = readFileSync(filePath, 'utf-8')\n const parsed = parse(content)\n if (parsed === null || parsed === undefined || typeof parsed !== 'object' || Array.isArray(parsed)) {\n return {}\n }\n return normalizeCredentialEntries(parsed as Record<string, unknown>)\n}\n\n/**\n * 写入凭证文件\n *\n * @param data - 凭证键值对\n */\nfunction writeCredentialsFile(data: Record<string, string>): void {\n const filePath = getCredentialsPath()\n ensureDir(filePath)\n const header = '# Managed by hai cli - do not edit manually\\n'\n const content = header + stringify(data)\n writeFileSync(filePath, content, { encoding: 'utf-8', mode: 0o600 })\n}\n\n// ─── 公共 API ───\n\n/**\n * 加载全局凭证文件并注入到 process.env\n *\n * 读取 `~/.hai/credentials.yml` 中的所有键值对,\n * 将每个 key-value 设置到 `process.env` 中,\n * 使后续 core 配置加载时自动解析 `${HAI_DEPLOY_*}` 变量。\n *\n * @returns 成功返回加载的凭证键名列表\n *\n * @example\n * ```ts\n * const result = loadCredentials()\n * if (result.success) {\n * console.log(`Loaded ${result.data.length} credentials`)\n * }\n * ```\n */\nexport function loadCredentials(): HaiResult<string[]> {\n try {\n const data = readCredentialsFile()\n const keys = Object.keys(data)\n for (const key of keys) {\n process.env[key] = String(data[key])\n }\n logger.debug('Credentials loaded', { count: keys.length })\n return ok(keys)\n }\n catch (error) {\n logger.error('Failed to load credentials', { error })\n return err(\n HaiDeployError.CREDENTIAL_ERROR,\n deployM('deploy_credentialError', {\n params: { error: error instanceof Error ? error.message : String(error) },\n }),\n error,\n )\n }\n}\n\n/**\n * 保存单个凭证到全局凭证文件\n *\n * 读取已有凭证 → 合并新凭证 → 写回文件。已有同名 key 会被覆盖。\n *\n * @param key - 环境变量名(如 HAI_DEPLOY_VERCEL_TOKEN)\n * @param value - 凭证值\n *\n * @example\n * ```ts\n * saveCredential('HAI_DEPLOY_VERCEL_TOKEN', 'vel_xxx')\n * ```\n */\nexport function saveCredential(key: string, value: string): HaiResult<void> {\n try {\n assertAllowedCredentialKey(key)\n const data = readCredentialsFile()\n data[key] = value\n writeCredentialsFile(data)\n process.env[key] = value\n logger.debug('Credential saved', { key })\n return ok(undefined)\n }\n catch (error) {\n logger.error('Failed to save credential', { key, error })\n return err(\n HaiDeployError.CREDENTIAL_ERROR,\n deployM('deploy_credentialError', {\n params: { error: error instanceof Error ? error.message : String(error) },\n }),\n error,\n )\n }\n}\n\n/**\n * 批量保存凭证到全局凭证文件\n *\n * @param entries - 凭证键值对\n *\n * @example\n * ```ts\n * saveCredentials({\n * HAI_DEPLOY_VERCEL_TOKEN: 'vel_xxx',\n * HAI_DEPLOY_NEON_API_KEY: 'neon_xxx',\n * })\n * ```\n */\nexport function saveCredentials(entries: Record<string, string>): HaiResult<void> {\n try {\n assertAllowedCredentialEntries(entries)\n const data = readCredentialsFile()\n for (const [key, value] of Object.entries(entries)) {\n data[key] = value\n process.env[key] = value\n }\n writeCredentialsFile(data)\n logger.debug('Credentials saved', { count: Object.keys(entries).length })\n return ok(undefined)\n }\n catch (error) {\n logger.error('Failed to save credentials', { error })\n return err(\n HaiDeployError.CREDENTIAL_ERROR,\n deployM('deploy_credentialError', {\n params: { error: error instanceof Error ? error.message : String(error) },\n }),\n error,\n )\n }\n}\n","/**\n * @h-ai/deploy — 部署辅助函数\n *\n * 包含构建、产物目录解析等与部署流程相关的辅助操作。 从 deploy-main.ts 中提取,遵循 main 仅做生命周期管理的规范。\n * @module deploy-functions\n */\n\nimport type { HaiResult } from '@h-ai/core'\nimport { execSync } from 'node:child_process'\nimport { existsSync } from 'node:fs'\nimport { join } from 'node:path'\nimport process from 'node:process'\nimport { core, err, ok } from '@h-ai/core'\nimport { deployM } from './deploy-i18n.js'\nimport { HaiDeployError } from './deploy-types.js'\n\nconst logger = core.logger.child({ module: 'deploy', scope: 'functions' })\n\n/**\n * 执行应用构建\n *\n * @param appDir - 应用根目录\n * @param buildCommand - 构建命令\n * @param envVars - 当前部署开通结果,确保构建与运行使用同一配置\n * @returns 构建结果\n */\nexport function buildApp(appDir: string, buildCommand: string, envVars: Record<string, string> = {}): HaiResult<void> {\n logger.info('Building application', { appDir, buildCommand })\n try {\n execSync(buildCommand, {\n cwd: appDir,\n stdio: 'inherit',\n env: { ...process.env, ...envVars },\n })\n return ok(undefined)\n }\n catch (error) {\n return err(\n HaiDeployError.BUILD_FAILED,\n deployM('deploy_buildFailed', {\n params: { error: error instanceof Error ? error.message : String(error) },\n }),\n error,\n )\n }\n}\n\n/**\n * 解析构建产物目录\n *\n * @param appDir - 应用根目录\n * @param providerType - Provider 类型\n * @returns 产物目录路径\n */\nexport function resolveOutputDir(appDir: string, providerType: string): string {\n switch (providerType) {\n case 'vercel': {\n const vercelOutput = join(appDir, '.vercel', 'output')\n if (existsSync(vercelOutput)) {\n return vercelOutput\n }\n // 回退到标准 build 目录\n return join(appDir, 'build')\n }\n default:\n return join(appDir, 'build')\n }\n}\n","import type { HaiError, HaiResult } from '@h-ai/core'\nimport type { DeployRecoveryInfo } from './deploy-types.js'\nimport { err } from '@h-ai/core'\nimport { z } from 'zod'\nimport { deployM } from './deploy-i18n.js'\n\nconst RecoverySchema = z.object({\n projectName: z.string(),\n stage: z.string(),\n platformProjectId: z.string().optional(),\n resources: z.array(z.object({\n serviceType: z.enum(['db', 'cache', 'storage', 'email', 'sms']),\n provisionerName: z.string(),\n resourceInfo: z.string(),\n resourceStatus: z.enum(['created', 'reused', 'unknown']),\n })),\n})\n\n/** 读取错误中的恢复清单;仅返回明确允许展示的字段。 */\nexport function getDeployRecovery(error: HaiError): DeployRecoveryInfo | undefined {\n const parsed = RecoverySchema.safeParse(error.ext?.recovery)\n return parsed.success ? parsed.data : undefined\n}\n\n/** 在错误中保留可展示的恢复信息,避免异常 cause/命令/URL 泄漏凭证。 */\nexport function recoveryFailure(error: HaiError, recovery: DeployRecoveryInfo): HaiResult<never> {\n return err({\n code: error.code,\n httpStatus: error.httpStatus,\n system: error.system,\n module: error.module,\n message: deployM('deploy_recoveryFailure', { params: { stage: recovery.stage } }),\n suggestion: deployM('deploy_recoverySuggestion'),\n ext: { recovery },\n })\n}\n","/**\n * @h-ai/deploy — 应用扫描器\n *\n * 扫描应用目录,检测框架类型、模块依赖和所需基础设施。\n * @module deploy-scanner\n */\n\nimport type { HaiResult } from '@h-ai/core'\nimport type { ScanResult, ServiceType } from './deploy-types.js'\nimport { existsSync, readdirSync, readFileSync } from 'node:fs'\nimport { join } from 'node:path'\nimport { core, err, ok } from '@h-ai/core'\nimport { parse } from 'yaml'\nimport { deployM } from './deploy-i18n.js'\nimport { HaiDeployError } from './deploy-types.js'\n\nconst logger = core.logger.child({ module: 'deploy', scope: 'scanner' })\n\n// ─── 内部工具 ───\n\n/**\n * 安全读取并解析 YAML 文件\n *\n * @param filePath - YAML 文件路径\n * @returns 解析结果,文件不存在或解析失败时返回 null\n */\nfunction readYaml(filePath: string): Record<string, unknown> | null {\n if (!existsSync(filePath)) {\n return null\n }\n try {\n const content = readFileSync(filePath, 'utf-8')\n const parsed = parse(content)\n if (parsed === null || parsed === undefined || typeof parsed !== 'object') {\n return null\n }\n return parsed as Record<string, unknown>\n }\n catch {\n return null\n }\n}\n\n/**\n * 安全读取 JSON 文件\n *\n * @param filePath - JSON 文件路径\n * @returns 解析结果,文件不存在或解析失败时返回 null\n */\nfunction readJson(filePath: string): Record<string, unknown> | null {\n if (!existsSync(filePath)) {\n return null\n }\n try {\n const content = readFileSync(filePath, 'utf-8')\n return JSON.parse(content) as Record<string, unknown>\n }\n catch {\n return null\n }\n}\n\n/**\n * 检测 package.json 的 dependencies + devDependencies 中是否包含指定包\n *\n * @param pkg - package.json 内容\n * @param name - 包名\n */\nfunction hasDependency(pkg: Record<string, unknown>, name: string): boolean {\n const deps = pkg.dependencies as Record<string, string> | undefined\n const devDeps = pkg.devDependencies as Record<string, string> | undefined\n return (deps !== undefined && name in deps) || (devDeps !== undefined && name in devDeps)\n}\n\n/**\n * 扫描 config/ 目录,推断所需基础设施服务及各自后端类型\n *\n * @param configDir - 配置目录路径\n * @returns 所需服务列表与后端类型映射\n */\nfunction detectRequiredServices(configDir: string): { services: ServiceType[], backends: Partial<Record<ServiceType, string>> } {\n const services: ServiceType[] = []\n const backends: Partial<Record<ServiceType, string>> = {}\n\n if (!existsSync(configDir)) {\n return { services, backends }\n }\n\n const files = readdirSync(configDir)\n\n // 数据库:记录实际后端(postgresql / mysql / sqlite)以生成匹配 sidecar\n const dbFile = files.find(f => f.startsWith('_db.'))\n if (dbFile) {\n const dbConfig = readYaml(join(configDir, dbFile))\n if (dbConfig !== null) {\n services.push('db')\n backends.db = (dbConfig.type as string | undefined) ?? 'postgresql'\n }\n }\n\n // 缓存:仅 redis 需要外部服务,memory 模式无需 sidecar\n const cacheFile = files.find(f => f.startsWith('_cache.'))\n if (cacheFile) {\n const cacheConfig = readYaml(join(configDir, cacheFile))\n if (cacheConfig !== null && cacheConfig.type === 'redis') {\n services.push('cache')\n backends.cache = 'redis'\n }\n }\n\n // 存储:s3 需要对象存储\n const storageFile = files.find(f => f.startsWith('_storage.'))\n if (storageFile) {\n const storageConfig = readYaml(join(configDir, storageFile))\n if (storageConfig !== null && detectStorageIsS3(storageConfig)) {\n services.push('storage')\n backends.storage = 's3'\n }\n }\n\n // 向量数据库:记录后端(qdrant / pgvector / lancedb / chroma)\n const vecdbFile = files.find(f => f.startsWith('_vecdb.'))\n if (vecdbFile) {\n const vecdbConfig = readYaml(join(configDir, vecdbFile))\n if (vecdbConfig !== null) {\n services.push('vecdb')\n backends.vecdb = (vecdbConfig.type as string | undefined) ?? 'qdrant'\n }\n }\n\n // reach(邮件 / 短信)为外部 API,不生成 sidecar\n const reachFile = files.find(f => f.startsWith('_reach.'))\n if (reachFile) {\n const reachConfig = readYaml(join(configDir, reachFile))\n if (reachConfig !== null) {\n detectReachServices(reachConfig, services)\n }\n }\n\n return { services, backends }\n}\n\n/**\n * 判断存储配置是否使用 S3(直接配置或多 provider 配置)\n *\n * @param config - 存储配置内容\n */\nfunction detectStorageIsS3(config: Record<string, unknown>): boolean {\n if (config.type === 's3') {\n return true\n }\n const providers = config.providers as Record<string, unknown> | undefined\n if (providers === undefined) {\n return false\n }\n return Object.values(providers).some(p => (p as Record<string, unknown> | undefined)?.type === 's3')\n}\n\n/**\n * 检测 reach 配置中的邮件和短信需求\n *\n * @param config - reach 配置内容\n * @param services - 服务列表(原地修改)\n */\nfunction detectReachServices(config: Record<string, unknown>, services: ServiceType[]): void {\n const providers = config.providers as Array<Record<string, unknown>> | undefined\n if (!Array.isArray(providers)) {\n return\n }\n\n let hasEmail = false\n let hasSms = false\n\n for (const provider of providers) {\n const providerType = provider.type as string | undefined\n // smtp / api / resend 类型视为邮件需求\n if (!hasEmail && (providerType === 'smtp' || providerType === 'api')) {\n hasEmail = true\n services.push('email')\n }\n // aliyun-sms 类型视为短信需求\n if (!hasSms && providerType === 'aliyun-sms') {\n hasSms = true\n services.push('sms')\n }\n }\n}\n\n// ─── 公共 API ───\n\n/**\n * 扫描应用目录,检测框架类型、模块依赖和所需基础设施\n *\n * @param appDir - 应用根目录绝对路径\n * @returns 扫描结果(ScanResult)\n *\n * @example\n * ```ts\n * const result = await scanApp('/path/to/my-app')\n * if (result.success) {\n * const { appName, isSvelteKit, requiredServices } = result.data\n * }\n * ```\n */\nexport async function scanApp(appDir: string): Promise<HaiResult<ScanResult>> {\n logger.debug('Scanning application', { appDir })\n\n try {\n // 读取 package.json\n const pkg = readJson(join(appDir, 'package.json'))\n if (pkg === null) {\n return err(\n HaiDeployError.SCAN_FAILED,\n deployM('deploy_scanFailed', { params: { error: 'package.json not found' } }),\n )\n }\n\n const appName = extractAppName(pkg)\n const isSvelteKit = existsSync(join(appDir, 'svelte.config.js'))\n || existsSync(join(appDir, 'svelte.config.ts'))\n const adapterInstalled = hasDependency(pkg, '@sveltejs/adapter-vercel')\n const nodeAdapterInstalled = hasDependency(pkg, '@sveltejs/adapter-node')\n const configDir = join(appDir, 'config')\n const configDetection = detectRequiredServices(configDir)\n const depServices = detectServicesFromDependencies(pkg)\n // 合并去重:config 检测优先,依赖检测补充\n const requiredServices = Array.from(new Set([...configDetection.services, ...depServices]))\n const scripts = pkg.scripts as Record<string, string> | undefined\n const buildCommand = scripts?.build ?? 'pnpm build'\n\n const scanResult: ScanResult = {\n appName,\n isSvelteKit,\n adapterInstalled,\n nodeAdapterInstalled,\n requiredServices,\n serviceBackends: configDetection.backends,\n buildCommand,\n }\n\n logger.info('Application scanned', {\n appName,\n isSvelteKit,\n adapterInstalled,\n nodeAdapterInstalled,\n requiredServices,\n serviceBackends: configDetection.backends,\n })\n\n return ok(scanResult)\n }\n catch (error) {\n logger.error('Application scan failed', { appDir, error })\n return err(\n HaiDeployError.SCAN_FAILED,\n deployM('deploy_scanFailed', {\n params: { error: error instanceof Error ? error.message : String(error) },\n }),\n error,\n )\n }\n}\n\n/**\n * 从 package.json 的 @h-ai/* 依赖推断所需服务\n *\n * 依赖映射规则:\n * - @h-ai/reldb → 'db'\n * - @h-ai/cache → 'cache'\n * - @h-ai/storage → 'storage'\n *\n * @param pkg - package.json 内容\n * @returns 需要的服务类型列表\n */\nfunction detectServicesFromDependencies(pkg: Record<string, unknown>): ServiceType[] {\n const depMap: Record<string, ServiceType> = {\n '@h-ai/reldb': 'db',\n '@h-ai/cache': 'cache',\n '@h-ai/storage': 'storage',\n '@h-ai/vecdb': 'vecdb',\n }\n const services: ServiceType[] = []\n for (const [depName, serviceType] of Object.entries(depMap)) {\n if (hasDependency(pkg, depName)) {\n services.push(serviceType)\n }\n }\n return services\n}\n\n/**\n * 从 package.json 提取应用名称\n *\n * 移除 scope 前缀(如 @h-ai/admin-console → admin-console)\n *\n * @param pkg - package.json 内容\n * @returns 应用名称\n */\nfunction extractAppName(pkg: Record<string, unknown>): string {\n const name = (pkg.name as string) ?? 'app'\n // 移除 scope 前缀\n const slashIndex = name.indexOf('/')\n if (slashIndex >= 0) {\n return name.slice(slashIndex + 1)\n }\n return name\n}\n","/**\n * @h-ai/deploy — 容器编排文件生成\n *\n * 根据应用扫描结果生成 compose 文件与运行期环境:按需为 db/cache/storage\n * 追加自建 sidecar 服务,并注入对应的 HAI_DB / HAI_CACHE / HAI_STORAGE 覆盖变量。\n * 敏感值仅写入 .env.runtime,禁止进入 compose 文件。\n * @module deploy-container-compose\n */\n\nimport type { ScanResult, ServiceType } from '../deploy-types.js'\nimport { randomBytes } from 'node:crypto'\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs'\nimport { dirname, join } from 'node:path'\nimport { stringify } from 'yaml'\n\n/** sidecar 镜像固定版本,避免 `:latest` 漂移导致行为变化。 */\nconst IMAGES = {\n postgres: 'postgres:16-alpine',\n mysql: 'mysql:8.4',\n redis: 'redis:7-alpine',\n minio: 'minio/minio:RELEASE.2025-09-07T16-13-09Z',\n mc: 'minio/mc:RELEASE.2025-08-13T08-35-41Z',\n qdrant: 'qdrant/qdrant:v1.12.4',\n pgvector: 'pgvector/pgvector:pg17',\n chroma: 'chromadb/chroma:0.5.23',\n} as const\n\n/** compose 服务定义(结构化对象,交由 yaml 序列化)。 */\ntype ComposeService = Record<string, unknown>\n\n/** sidecar 规划结果。 */\nexport interface SidecarPlan {\n /** 实际启用的自建服务 */\n services: ServiceType[]\n /** compose services 片段(不含 app) */\n composeServices: Record<string, ComposeService>\n /** 命名卷 */\n volumes: Record<string, unknown>\n /** 挂载到 app 容器的卷(如 sqlite/lancedb 的本地数据目录持久化) */\n appVolumes: string[]\n /** 追加到 .env.runtime 的环境变量(含 HAI_* 覆盖与 sidecar 凭据) */\n env: Record<string, string>\n /** app 服务的 depends_on 列表 */\n dependsOn: string[]\n /** 需要在日志中脱敏的敏感值 */\n secrets: string[]\n}\n\n/** 运行期环境构建结果。 */\nexport interface RuntimeEnvPlan {\n /** 完整运行期环境(写入 .env.runtime) */\n env: Record<string, string>\n /** sidecar 规划 */\n sidecar: SidecarPlan\n}\n\n/** 生成随机密码(url 安全)。 */\nfunction generatePassword(): string {\n return randomBytes(24).toString('base64url')\n}\n\n/**\n * 读取或创建稳定的 sidecar 凭据。\n *\n * 为保证重复部署的幂等性(密码不变,避免已存在数据卷认证失败),\n * 凭据持久化到本地 gitignore 的 `.hai/deploy/runtime/<project>.secrets.json`。\n *\n * @param appDir - 应用根目录\n * @param projectName - 项目名\n * @returns 稳定的凭据键值对\n */\nfunction resolveSidecarSecrets(appDir: string, projectName: string): Record<string, string> {\n const secretFile = join(appDir, '.hai', 'deploy', 'runtime', `${projectName}.secrets.json`)\n if (existsSync(secretFile)) {\n try {\n return JSON.parse(readFileSync(secretFile, 'utf-8')) as Record<string, string>\n }\n catch {\n // 损坏则重建\n }\n }\n const secrets = {\n dbPassword: generatePassword(),\n storagePassword: generatePassword(),\n }\n mkdirSync(dirname(secretFile), { recursive: true })\n writeFileSync(secretFile, JSON.stringify(secrets), { mode: 0o600 })\n return secrets\n}\n\n/** 为 app 追加本地数据卷(sqlite / lancedb 等文件型后端持久化)。 */\nfunction addAppDataVolume(plan: SidecarPlan, projectName: string): void {\n const mount = `${projectName}-data:/app/data`\n if (!plan.appVolumes.includes(mount)) {\n plan.appVolumes.push(mount)\n plan.volumes[`${projectName}-data`] = null\n }\n}\n\n/** PostgreSQL sidecar。 */\nfunction planPostgresDb(plan: SidecarPlan, projectName: string, password: string, net: string[]): void {\n plan.services.push('db')\n plan.dependsOn.push('db')\n plan.composeServices.db = {\n image: IMAGES.postgres,\n container_name: `hai-${projectName}-db`,\n restart: 'unless-stopped',\n env_file: ['.env.runtime'],\n volumes: [`${projectName}-db-data:/var/lib/postgresql/data`],\n networks: net,\n }\n plan.volumes[`${projectName}-db-data`] = null\n plan.env.POSTGRES_USER = 'hai'\n plan.env.POSTGRES_PASSWORD = password\n plan.env.POSTGRES_DB = 'hai'\n plan.env.HAI_DB = JSON.stringify({ type: 'postgresql', url: `postgresql://hai:${password}@db:5432/hai`, database: 'hai' })\n plan.secrets.push(password)\n}\n\n/** MySQL sidecar。 */\nfunction planMysqlDb(plan: SidecarPlan, projectName: string, password: string, net: string[]): void {\n plan.services.push('db')\n plan.dependsOn.push('db')\n plan.composeServices.db = {\n image: IMAGES.mysql,\n container_name: `hai-${projectName}-db`,\n restart: 'unless-stopped',\n env_file: ['.env.runtime'],\n volumes: [`${projectName}-db-data:/var/lib/mysql`],\n networks: net,\n }\n plan.volumes[`${projectName}-db-data`] = null\n plan.env.MYSQL_ROOT_PASSWORD = password\n plan.env.MYSQL_DATABASE = 'hai'\n plan.env.MYSQL_USER = 'hai'\n plan.env.MYSQL_PASSWORD = password\n plan.env.HAI_DB = JSON.stringify({ type: 'mysql', url: `mysql://hai:${password}@db:3306/hai`, database: 'hai' })\n plan.secrets.push(password)\n}\n\n/** Redis sidecar。 */\nfunction planRedisCache(plan: SidecarPlan, projectName: string, net: string[]): void {\n plan.services.push('cache')\n plan.dependsOn.push('cache')\n plan.composeServices.cache = {\n image: IMAGES.redis,\n container_name: `hai-${projectName}-cache`,\n restart: 'unless-stopped',\n networks: net,\n }\n plan.env.HAI_CACHE = JSON.stringify({ type: 'redis', url: 'redis://cache:6379' })\n}\n\n/** MinIO(S3) sidecar + 一次性 bucket 初始化。 */\nfunction planMinioStorage(plan: SidecarPlan, projectName: string, password: string, net: string[]): void {\n plan.services.push('storage')\n plan.dependsOn.push('storage')\n plan.composeServices.storage = {\n image: IMAGES.minio,\n container_name: `hai-${projectName}-storage`,\n restart: 'unless-stopped',\n command: ['server', '/data'],\n env_file: ['.env.runtime'],\n volumes: [`${projectName}-storage-data:/data`],\n networks: net,\n }\n plan.composeServices['storage-init'] = {\n image: IMAGES.mc,\n depends_on: ['storage'],\n env_file: ['.env.runtime'],\n entrypoint: [\n 'sh',\n '-c',\n 'until mc alias set s3 http://storage:9000 \"$MINIO_ROOT_USER\" \"$MINIO_ROOT_PASSWORD\"; do sleep 1; done; mc mb -p s3/hai; exit 0',\n ],\n networks: net,\n }\n plan.volumes[`${projectName}-storage-data`] = null\n plan.env.MINIO_ROOT_USER = 'hai'\n plan.env.MINIO_ROOT_PASSWORD = password\n plan.env.HAI_STORAGE = JSON.stringify({\n type: 's3',\n endpoint: 'http://storage:9000',\n bucket: 'hai',\n region: 'us-east-1',\n accessKeyId: 'hai',\n secretAccessKey: password,\n forcePathStyle: true,\n })\n plan.secrets.push(password)\n}\n\n/** Qdrant 向量库 sidecar。 */\nfunction planQdrantVecdb(plan: SidecarPlan, projectName: string, net: string[]): void {\n plan.services.push('vecdb')\n plan.dependsOn.push('vecdb')\n plan.composeServices.vecdb = {\n image: IMAGES.qdrant,\n container_name: `hai-${projectName}-vecdb`,\n restart: 'unless-stopped',\n volumes: [`${projectName}-vecdb-data:/qdrant/storage`],\n networks: net,\n }\n plan.volumes[`${projectName}-vecdb-data`] = null\n plan.env.HAI_VECDB = JSON.stringify({ type: 'qdrant', url: 'http://vecdb:6333' })\n}\n\n/** pgvector 向量库 sidecar(PostgreSQL + pgvector 扩展)。 */\nfunction planPgvectorVecdb(plan: SidecarPlan, projectName: string, password: string, net: string[]): void {\n plan.services.push('vecdb')\n plan.dependsOn.push('vecdb')\n plan.composeServices.vecdb = {\n image: IMAGES.pgvector,\n container_name: `hai-${projectName}-vecdb`,\n restart: 'unless-stopped',\n env_file: ['.env.runtime'],\n volumes: [`${projectName}-vecdb-data:/var/lib/postgresql/data`],\n networks: net,\n }\n plan.volumes[`${projectName}-vecdb-data`] = null\n // 与 postgres db sidecar 共用 POSTGRES_* 凭据(不同实例、不同卷,值一致即可)\n plan.env.POSTGRES_USER = 'hai'\n plan.env.POSTGRES_PASSWORD = password\n plan.env.POSTGRES_DB = 'hai'\n plan.env.HAI_VECDB = JSON.stringify({ type: 'pgvector', url: `postgresql://hai:${password}@vecdb:5432/hai`, database: 'hai' })\n plan.secrets.push(password)\n}\n\n/** Chroma 向量库 sidecar。 */\nfunction planChromaVecdb(plan: SidecarPlan, projectName: string, net: string[]): void {\n plan.services.push('vecdb')\n plan.dependsOn.push('vecdb')\n plan.composeServices.vecdb = {\n image: IMAGES.chroma,\n container_name: `hai-${projectName}-vecdb`,\n restart: 'unless-stopped',\n volumes: [`${projectName}-vecdb-data:/data`],\n networks: net,\n }\n plan.volumes[`${projectName}-vecdb-data`] = null\n plan.env.HAI_VECDB = JSON.stringify({ type: 'chroma', url: 'http://vecdb:8000' })\n}\n\n/**\n * 规划自建 sidecar 服务。\n *\n * 仅为 scan.requiredServices 中、且 Provisioner 未提供对应 HAI_* 变量的服务追加 sidecar;\n * db 与 vecdb 按扫描到的后端类型(postgresql/mysql/sqlite、qdrant/pgvector/chroma/lancedb)生成匹配实现。\n *\n * @param appDir - 应用根目录\n * @param projectName - 项目名\n * @param scan - 扫描结果\n * @param provisionEnv - Provisioner 输出的环境变量\n * @returns sidecar 规划\n */\nexport function planSidecars(\n appDir: string,\n projectName: string,\n scan: ScanResult,\n provisionEnv: Record<string, string>,\n): SidecarPlan {\n const plan: SidecarPlan = {\n services: [],\n composeServices: {},\n volumes: {},\n appVolumes: [],\n env: {},\n dependsOn: [],\n secrets: [],\n }\n const secrets = resolveSidecarSecrets(appDir, projectName)\n const net = ['hai-app']\n const backends = scan.serviceBackends\n\n for (const service of scan.requiredServices) {\n if (service === 'db' && !provisionEnv.HAI_DB) {\n const backend = backends.db ?? 'postgresql'\n if (backend === 'mysql')\n planMysqlDb(plan, projectName, secrets.dbPassword, net)\n else if (backend === 'sqlite')\n addAppDataVolume(plan, projectName) // 文件库:仅持久化数据目录,保留应用自身 sqlite 配置\n else\n planPostgresDb(plan, projectName, secrets.dbPassword, net)\n }\n else if (service === 'cache' && !provisionEnv.HAI_CACHE) {\n planRedisCache(plan, projectName, net)\n }\n else if (service === 'storage' && !provisionEnv.HAI_STORAGE) {\n planMinioStorage(plan, projectName, secrets.storagePassword, net)\n }\n else if (service === 'vecdb' && !provisionEnv.HAI_VECDB) {\n const backend = backends.vecdb ?? 'qdrant'\n if (backend === 'pgvector')\n planPgvectorVecdb(plan, projectName, secrets.dbPassword, net)\n else if (backend === 'chroma')\n planChromaVecdb(plan, projectName, net)\n else if (backend === 'lancedb')\n addAppDataVolume(plan, projectName) // 嵌入式:持久化本地向量文件\n else\n planQdrantVecdb(plan, projectName, net)\n }\n }\n\n return plan\n}\n\n/**\n * 构建运行期环境变量并规划 sidecar。\n *\n * 合并顺序(后者覆盖前者):框架默认 < sidecar 自建 < Provisioner 输出。\n *\n * @param appDir - 应用根目录\n * @param projectName - 项目名\n * @param scan - 扫描结果\n * @param provisionEnv - Provisioner 输出环境变量\n * @param containerPort - 容器内监听端口\n * @returns 运行期环境与 sidecar 规划\n */\nexport function buildRuntimeEnv(\n appDir: string,\n projectName: string,\n scan: ScanResult,\n provisionEnv: Record<string, string>,\n containerPort: number,\n): RuntimeEnvPlan {\n const sidecar = planSidecars(appDir, projectName, scan, provisionEnv)\n const env: Record<string, string> = {\n NODE_ENV: 'production',\n HOST: '0.0.0.0',\n PORT: String(containerPort),\n ...sidecar.env,\n ...provisionEnv,\n }\n return { env, sidecar }\n}\n\n/**\n * 生成 compose 文件内容。\n *\n * @param options - 生成参数\n * @param options.projectName - 项目名\n * @param options.imageRef - 应用镜像引用\n * @param options.hostPort - 宿主机映射端口\n * @param options.containerPort - 容器内端口\n * @param options.sidecar - sidecar 规划\n * @returns compose YAML 字符串\n */\nexport function generateComposeFile(options: {\n projectName: string\n imageRef: string\n hostPort: number\n containerPort: number\n sidecar: SidecarPlan\n}): string {\n const { projectName, imageRef, hostPort, containerPort, sidecar } = options\n\n const app: ComposeService = {\n image: imageRef,\n container_name: `hai-${projectName}-app`,\n restart: 'unless-stopped',\n // 镜像已由 load 注入本地,禁止 compose 再从 registry 拉取\n pull_policy: 'never',\n env_file: ['.env.runtime'],\n ports: [`${hostPort}:${containerPort}`],\n networks: ['hai-app'],\n }\n if (sidecar.appVolumes.length > 0)\n app.volumes = sidecar.appVolumes\n if (sidecar.dependsOn.length > 0)\n app.depends_on = sidecar.dependsOn\n\n const compose: Record<string, unknown> = {\n services: {\n app,\n ...sidecar.composeServices,\n },\n networks: {\n 'hai-app': { name: `hai-${projectName}` },\n },\n }\n if (Object.keys(sidecar.volumes).length > 0)\n compose.volumes = sidecar.volumes\n\n return stringify(compose)\n}\n\n/** 将环境变量对象序列化为 .env.runtime 内容(每行 KEY=VALUE)。 */\nexport function serializeEnvFile(env: Record<string, string>): string {\n return `${Object.entries(env)\n .map(([key, value]) => `${key}=${value}`)\n .join('\\n')}\\n`\n}\n\n/**\n * 生成兜底 Dockerfile 的伴随 `.dockerignore`。\n *\n * 仅排除重产物,保留全部源码(monorepo 以 workspace 根为上下文时需包含 apps/packages 源码,\n * 覆盖仓库根可能存在的排除 apps 的 `.dockerignore`)。\n *\n * @returns dockerignore 内容\n */\nexport function generateDockerignore(): string {\n return `**/node_modules\n**/dist\n**/build\n**/.turbo\n**/.svelte-kit\n**/coverage\n**/test-results\n**/playwright-report\n**/.hai/deploy\n.git\n`\n}\n\n/**\n * 生成兜底 Dockerfile(应用未自带 Dockerfile 时使用)。\n *\n * 面向 SvelteKit + @sveltejs/adapter-node。`COPY .` 复制构建上下文(单应用为 appDir、\n * monorepo 为 workspace 根,由 Provider 选择),`pnpm --filter <包名>` 只构建目标应用。\n *\n * @param packageName - 应用完整包名(用于 pnpm --filter)\n * @param containerPort - 容器监听端口\n * @returns Dockerfile 内容\n */\nexport function generateFallbackDockerfile(packageName: string, containerPort: number): string {\n return `# syntax=docker/dockerfile:1.7\nFROM node:22-bookworm-slim AS build\nENV PNPM_HOME=/pnpm\nENV PATH=$PNPM_HOME:$PATH\nENV CI=true\nWORKDIR /workspace\nRUN corepack enable && corepack prepare pnpm@9.15.0 --activate\nCOPY . .\nRUN pnpm install --frozen-lockfile --ignore-scripts\nRUN pnpm --filter ${packageName} build\nRUN pnpm --filter ${packageName} --prod deploy /prod/app\n\nFROM node:22-bookworm-slim AS runtime\nENV NODE_ENV=production\nENV HOST=0.0.0.0\nENV PORT=${containerPort}\nWORKDIR /app\nCOPY --from=build --chown=node:node /prod/app ./\nUSER node\nEXPOSE ${containerPort}\nCMD [\"node\", \"build\"]\n`\n}\n","/**\n * @h-ai/deploy — 命令执行器\n *\n * 统一封装本地/远程命令调用:command 与 args 分离、支持超时、输出捕获与敏感信息脱敏。\n * 供 docker / podman / ssh / scp 复用,禁止字符串拼接执行以避免命令注入。\n * @module deploy-command\n */\n\nimport type { HaiResult } from '@h-ai/core'\nimport type { Buffer } from 'node:buffer'\nimport { spawn } from 'node:child_process'\nimport process from 'node:process'\nimport { core, err, ok } from '@h-ai/core'\nimport { deployM } from '../deploy-i18n.js'\nimport { HaiDeployError } from '../deploy-types.js'\n\nconst logger = core.logger.child({ module: 'deploy', scope: 'command' })\n\n/** 命令执行选项 */\nexport interface CommandOptions {\n /** 工作目录 */\n cwd?: string\n /** 追加的环境变量 */\n env?: Record<string, string>\n /** 超时(毫秒),默认无超时 */\n timeoutMs?: number\n /** 通过 stdin 传入的内容 */\n input?: string\n /** 日志中需要脱敏的敏感片段(如密钥内容) */\n secrets?: string[]\n}\n\n/** 命令执行结果 */\nexport interface CommandResult {\n /** 退出码 */\n code: number\n /** 标准输出 */\n stdout: string\n /** 标准错误 */\n stderr: string\n}\n\n/** 将文本中的敏感片段替换为掩码,用于安全日志。 */\nexport function maskSecrets(text: string, secrets: string[] | undefined): string {\n if (!secrets || secrets.length === 0)\n return text\n let masked = text\n for (const secret of secrets) {\n if (secret && secret.length > 0)\n masked = masked.split(secret).join('***')\n }\n return masked\n}\n\n/**\n * 执行外部命令(command + args 分离,不经过 shell)。\n *\n * 非零退出码或超时返回 `REMOTE_COMMAND_FAILED`;进程无法启动返回同码并携带原始错误。\n *\n * @param command - 可执行文件名(docker / podman / ssh / scp)\n * @param args - 参数数组\n * @param options - 执行选项\n * @returns 命令结果(stdout / stderr / code)\n */\nexport function runCommand(\n command: string,\n args: string[],\n options: CommandOptions = {},\n): Promise<HaiResult<CommandResult>> {\n return new Promise((resolve) => {\n const child = spawn(command, args, {\n cwd: options.cwd,\n env: options.env ? { ...process.env, ...options.env } : process.env,\n shell: false,\n })\n\n let stdout = ''\n let stderr = ''\n let settled = false\n let timer: NodeJS.Timeout | undefined\n\n const finish = (result: HaiResult<CommandResult>): void => {\n if (settled)\n return\n settled = true\n if (timer)\n clearTimeout(timer)\n resolve(result)\n }\n\n if (options.timeoutMs && options.timeoutMs > 0) {\n timer = setTimeout(() => {\n child.kill('SIGKILL')\n logger.error('Command timed out', { command, timeoutMs: options.timeoutMs })\n finish(err(\n HaiDeployError.REMOTE_COMMAND_FAILED,\n deployM('deploy_commandTimeout', { params: { command } }),\n ))\n }, options.timeoutMs)\n }\n\n child.stdout.on('data', (chunk: Buffer) => {\n stdout += chunk.toString('utf-8')\n })\n child.stderr.on('data', (chunk: Buffer) => {\n stderr += chunk.toString('utf-8')\n })\n\n child.on('error', (error) => {\n logger.error('Command failed to start', { command, error: maskSecrets(String(error), options.secrets) })\n finish(err(\n HaiDeployError.REMOTE_COMMAND_FAILED,\n deployM('deploy_commandFailed', {\n params: { command, error: maskSecrets(error.message, options.secrets) },\n }),\n error,\n ))\n })\n\n child.on('close', (code) => {\n const exitCode = code ?? -1\n if (exitCode === 0) {\n finish(ok({ code: exitCode, stdout, stderr }))\n return\n }\n logger.error('Command exited with non-zero code', {\n command,\n code: exitCode,\n stderr: maskSecrets(stderr, options.secrets).slice(-500),\n })\n finish(err(\n HaiDeployError.REMOTE_COMMAND_FAILED,\n deployM('deploy_commandFailed', {\n params: { command, error: maskSecrets(stderr || `exit ${exitCode}`, options.secrets).slice(-500) },\n }),\n ))\n })\n\n if (options.input !== undefined) {\n child.stdin.write(options.input)\n child.stdin.end()\n }\n else {\n // 关闭 stdin,避免子进程(如 ssh)等待输入\n child.stdin.end()\n }\n })\n}\n","/**\n * @h-ai/deploy — 本地容器运行时\n *\n * 探测本地 docker / podman,构建镜像并导出为 tar 制品。\n * @module deploy-container-runtime\n */\n\nimport type { HaiResult } from '@h-ai/core'\nimport type { ContainerRuntime } from './deploy-container-types.js'\nimport { core, err, ok } from '@h-ai/core'\nimport { deployM } from '../deploy-i18n.js'\nimport { HaiDeployError } from '../deploy-types.js'\nimport { runCommand } from './deploy-command.js'\n\nconst logger = core.logger.child({ module: 'deploy', scope: 'container-runtime' })\n\n/**\n * 探测本地容器运行时。\n *\n * `auto` 时优先 podman,其次 docker;指定引擎时校验其可用性。\n * 用 `version`(而非 `--version`)探测:同时确认命令存在与引擎/机器可达,\n * 避免选中“已装 CLI 但未启动”的运行时。\n *\n * @param preferred - 期望引擎(auto / docker / podman)\n * @returns 可用的容器运行时\n */\nexport async function detectLocalRuntime(\n preferred: 'auto' | ContainerRuntime = 'auto',\n): Promise<HaiResult<ContainerRuntime>> {\n const candidates: ContainerRuntime[] = preferred === 'auto'\n ? ['podman', 'docker']\n : [preferred]\n\n for (const runtime of candidates) {\n const probe = await runCommand(runtime, ['version'], { timeoutMs: 15_000 })\n if (probe.success) {\n logger.info('Local container runtime detected', { runtime })\n return ok(runtime)\n }\n }\n\n return err(\n HaiDeployError.CONTAINER_RUNTIME_NOT_FOUND,\n deployM('deploy_containerRuntimeNotFound', { params: { runtime: candidates.join(' / ') } }),\n )\n}\n\n/**\n * 构建应用镜像。\n *\n * podman 多阶段构建追加 `--format docker --jobs=1`,保留 HEALTHCHECK 并规避并行阶段的信号量 panic。\n *\n * @param runtime - 容器运行时\n * @param options - 构建参数\n * @param options.contextDir - 构建上下文目录\n * @param options.dockerfilePath - Dockerfile 路径\n * @param options.imageRef - 镜像引用\n * @returns 构建结果\n */\nexport async function buildImage(\n runtime: ContainerRuntime,\n options: { contextDir: string, dockerfilePath: string, imageRef: string },\n): Promise<HaiResult<void>> {\n const args = ['build', '-f', options.dockerfilePath, '-t', options.imageRef]\n if (runtime === 'podman')\n args.push('--format', 'docker', '--jobs', '1')\n args.push(options.contextDir)\n\n logger.info('Building container image', { runtime, imageRef: options.imageRef })\n const result = await runCommand(runtime, args, { cwd: options.contextDir })\n if (!result.success) {\n return err(\n HaiDeployError.CONTAINER_BUILD_FAILED,\n deployM('deploy_containerBuildFailed', { params: { error: result.error.message } }),\n result.error,\n )\n }\n return ok(undefined)\n}\n\n/**\n * 将镜像导出为 tar 制品。\n *\n * @param runtime - 容器运行时\n * @param imageRef - 镜像引用\n * @param tarPath - 输出 tar 路径\n * @returns 导出结果\n */\nexport async function saveImage(\n runtime: ContainerRuntime,\n imageRef: string,\n tarPath: string,\n): Promise<HaiResult<void>> {\n logger.info('Saving container image', { runtime, imageRef, tarPath })\n const result = await runCommand(runtime, ['save', '-o', tarPath, imageRef], {})\n if (!result.success) {\n return err(\n HaiDeployError.CONTAINER_BUILD_FAILED,\n deployM('deploy_containerBuildFailed', { params: { error: result.error.message } }),\n result.error,\n )\n }\n return ok(undefined)\n}\n","/**\n * @h-ai/deploy — SSH 执行器\n *\n * 基于用户机器已有的 OpenSSH 客户端(ssh / scp)封装远程命令执行与文件上传。\n * 复用 ~/.ssh/config、ssh-agent 与 OpenSSH 证书,避免引入 Node SSH SDK 的密钥兼容问题。\n * 所有调用均以 command + args 数组构造,禁止字符串拼接,防止命令注入。\n * @module deploy-ssh\n */\n\nimport type { HaiResult } from '@h-ai/core'\nimport type { SshConfig } from '../deploy-config.js'\nimport type { CommandResult } from './deploy-command.js'\nimport { core, err, ok } from '@h-ai/core'\nimport { deployM } from '../deploy-i18n.js'\nimport { HaiDeployError } from '../deploy-types.js'\nimport { runCommand } from './deploy-command.js'\n\nconst logger = core.logger.child({ module: 'deploy', scope: 'ssh' })\n\n/** SSH 执行器接口 */\nexport interface SshExecutor {\n /** 在远程主机执行命令(通过远程登录 shell 运行) */\n exec: (remoteCommand: string, options?: { timeoutMs?: number, secrets?: string[] }) => Promise<HaiResult<CommandResult>>\n /** 上传本地文件到远程路径 */\n upload: (localPath: string, remotePath: string) => Promise<HaiResult<void>>\n /** 远程连通性预检(执行 true 命令) */\n ping: () => Promise<HaiResult<void>>\n}\n\n/** 构造 ssh 公共连接选项。 */\nfunction buildConnectOptions(config: SshConfig): string[] {\n const args: string[] = ['-o', 'BatchMode=yes']\n args.push('-o', `ConnectTimeout=${config.connectTimeoutSeconds}`)\n args.push('-o', `StrictHostKeyChecking=${config.strictHostKeyChecking ? 'accept-new' : 'no'}`)\n if (config.knownHostsFile)\n args.push('-o', `UserKnownHostsFile=${config.knownHostsFile}`)\n if (config.identityFile) {\n args.push('-i', config.identityFile)\n args.push('-o', 'IdentitiesOnly=yes')\n }\n return args\n}\n\n/**\n * 构造 ssh 执行命令的参数数组。\n *\n * remoteCommand 作为单个参数传入,不经过本地 shell 解析,避免本地命令注入。\n *\n * @param config - SSH 连接配置\n * @param remoteCommand - 远程命令字符串\n */\nexport function buildSshExecArgs(config: SshConfig, remoteCommand: string): string[] {\n return [\n ...buildConnectOptions(config),\n '-p',\n String(config.port),\n `${config.username}@${config.host}`,\n remoteCommand,\n ]\n}\n\n/**\n * 构造 scp 上传命令的参数数组。\n *\n * @param config - SSH 连接配置\n * @param localPath - 本地文件路径\n * @param remotePath - 远程目标路径\n */\nexport function buildScpUploadArgs(config: SshConfig, localPath: string, remotePath: string): string[] {\n return [\n ...buildConnectOptions(config),\n '-P',\n String(config.port),\n localPath,\n `${config.username}@${config.host}:${remotePath}`,\n ]\n}\n\n/**\n * 创建 SSH 执行器。\n *\n * @param config - SSH 连接配置\n * @returns SSH 执行器实例\n */\nexport function createSshExecutor(config: SshConfig): SshExecutor {\n const exec: SshExecutor['exec'] = async (remoteCommand, options) => {\n // runCommand 失败时已返回 REMOTE_COMMAND_FAILED(含 ssh stderr),无需重复包装\n return runCommand('ssh', buildSshExecArgs(config, remoteCommand), {\n timeoutMs: options?.timeoutMs,\n secrets: options?.secrets,\n })\n }\n\n const upload: SshExecutor['upload'] = async (localPath, remotePath) => {\n const args = buildScpUploadArgs(config, localPath, remotePath)\n const result = await runCommand('scp', args, {})\n if (!result.success) {\n return err(\n HaiDeployError.IMAGE_TRANSFER_FAILED,\n deployM('deploy_imageTransferFailed', { params: { error: result.error.message } }),\n result.error,\n )\n }\n return ok(undefined)\n }\n\n const ping: SshExecutor['ping'] = async () => {\n logger.debug('SSH preflight', { host: config.host, port: config.port })\n const result = await exec('true', { timeoutMs: 20_000 })\n if (!result.success) {\n return err(\n HaiDeployError.REMOTE_CONNECT_FAILED,\n deployM('deploy_remoteConnectFailed', { params: { host: config.host, error: result.error.message } }),\n result.error,\n )\n }\n return ok(undefined)\n }\n\n return { exec, upload, ping }\n}\n","/**\n * @h-ai/deploy — docker-ssh 部署 Provider\n *\n * 基于 OCI 镜像 + Docker Compose + SSH 的通用主机部署:本地构建镜像 → SSH 传输 →\n * 远程 load → compose up → HTTP 健康检查。远程仅需 SSH + docker/podman + compose。\n * @module deploy-provider-docker-ssh\n */\n\nimport type { HaiResult } from '@h-ai/core'\nimport type {\n ContainerDeployContext,\n ContainerDeployProvider,\n ContainerRuntime,\n} from '../container/deploy-container-types.js'\nimport type { DockerSshProviderConfig } from '../deploy-config.js'\nimport type { DeployResult } from '../deploy-types.js'\nimport { randomBytes } from 'node:crypto'\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs'\nimport { dirname, join } from 'node:path'\nimport { core, err, ok } from '@h-ai/core'\nimport {\n buildRuntimeEnv,\n generateComposeFile,\n generateDockerignore,\n generateFallbackDockerfile,\n serializeEnvFile,\n} from '../container/deploy-container-compose.js'\nimport { buildImage, detectLocalRuntime, saveImage } from '../container/deploy-container-runtime.js'\nimport { createSshExecutor } from '../container/deploy-ssh.js'\nimport { deployM } from '../deploy-i18n.js'\nimport { HaiDeployError } from '../deploy-types.js'\n\nconst logger = core.logger.child({ module: 'deploy', scope: 'provider-docker-ssh' })\n\n/** 健康检查轮询间隔(毫秒) */\nconst HEALTH_POLL_INTERVAL = 3000\n\n/** 健康检查最大轮询次数 */\nconst HEALTH_MAX_ATTEMPTS = 40\n\n/** 生成不可变部署 ID:`YYYYMMDD-HHmmss-<random>`。 */\nfunction makeDeploymentId(): string {\n const now = new Date()\n const pad = (n: number): string => String(n).padStart(2, '0')\n const stamp = `${now.getFullYear()}${pad(now.getMonth() + 1)}${pad(now.getDate())}`\n + `-${pad(now.getHours())}${pad(now.getMinutes())}${pad(now.getSeconds())}`\n return `${stamp}-${randomBytes(3).toString('hex')}`\n}\n\n/** 从 `docker/podman load` 输出解析加载后的镜像引用。 */\nfunction parseLoadedImageRef(stdout: string, fallback: string): string {\n const match = stdout.match(/Loaded image(?:\\(s\\))?:\\s*(\\S+)/)\n return match ? match[1] : fallback\n}\n\n/** 睡眠指定毫秒。 */\nfunction sleep(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms))\n}\n\n/** 读取应用完整包名(用于 pnpm --filter),失败回退 'app'。 */\nfunction readPackageName(appDir: string): string {\n try {\n const pkg = JSON.parse(readFileSync(join(appDir, 'package.json'), 'utf-8')) as { name?: string }\n return pkg.name ?? 'app'\n }\n catch {\n return 'app'\n }\n}\n\n/**\n * 解析镜像构建上下文根目录。\n *\n * 应用自身含 `pnpm-workspace.yaml` → 独立工程(上下文=appDir);\n * 仅上层目录含 `pnpm-workspace.yaml` → monorepo 成员(上下文=workspace 根,供 `pnpm --filter` 构建)。\n *\n * @param appDir - 应用根目录\n * @returns 构建上下文根目录\n */\nfunction resolveWorkspaceRoot(appDir: string): string {\n if (existsSync(join(appDir, 'pnpm-workspace.yaml')))\n return appDir\n let current = appDir\n let parent = dirname(current)\n while (parent !== current) {\n if (existsSync(join(parent, 'pnpm-workspace.yaml')))\n return parent\n current = parent\n parent = dirname(parent)\n }\n return appDir\n}\n\n/**\n * 创建 docker-ssh 部署 Provider。\n *\n * @param config - docker-ssh Provider 配置\n * @param localRuntimePref - 本地构建运行时偏好(auto 优先 podman)\n * @returns 容器部署 Provider 实例\n */\nexport function createDockerSshProvider(\n config: DockerSshProviderConfig,\n localRuntimePref: 'auto' | ContainerRuntime = 'auto',\n): ContainerDeployProvider {\n const ssh = createSshExecutor(config.ssh)\n const baseDir = config.remote.baseDir\n\n /** 探测远程容器运行时与 compose 可用性。 */\n async function detectRemoteRuntime(): Promise<HaiResult<ContainerRuntime>> {\n const candidates: ContainerRuntime[] = config.remote.runtime === 'auto'\n ? ['podman', 'docker']\n : [config.remote.runtime]\n\n for (const runtime of candidates) {\n const versionResult = await ssh.exec(`${runtime} version`, { timeoutMs: 20_000 })\n if (!versionResult.success)\n continue\n const composeResult = await ssh.exec(`${runtime} compose version`, { timeoutMs: 20_000 })\n if (composeResult.success) {\n logger.info('Remote container runtime detected', { runtime })\n return ok(runtime)\n }\n }\n return err(\n HaiDeployError.REMOTE_COMMAND_FAILED,\n deployM('deploy_remoteRuntimeMissing', { params: { runtime: candidates.join(' / ') } }),\n )\n }\n\n /** HTTP 健康检查:轮询访问地址直到返回成功。 */\n async function healthCheck(url: string): Promise<boolean> {\n for (let attempt = 0; attempt < HEALTH_MAX_ATTEMPTS; attempt++) {\n try {\n const response = await fetch(url, { signal: AbortSignal.timeout(5000) })\n if (response.ok)\n return true\n }\n catch {\n // 未就绪,继续轮询\n }\n await sleep(HEALTH_POLL_INTERVAL)\n }\n return false\n }\n\n const deploy = async (context: ContainerDeployContext): Promise<HaiResult<DeployResult>> => {\n const { appDir, projectName, scan, provisionEnv } = context\n const deploymentId = makeDeploymentId()\n const containerPort = config.expose.containerPort\n const hostPort = config.expose.hostPort\n const localImageTag = `hai-${projectName}:${deploymentId}`\n\n // 1. 本地运行时\n const runtimeResult = await detectLocalRuntime(localRuntimePref)\n if (!runtimeResult.success)\n return err(runtimeResult.error)\n const localRuntime = runtimeResult.data\n\n // 2. 解析构建上下文与 Dockerfile(优先复用应用自带 Dockerfile;无则按工程结构生成兜底)\n const artifactDir = join(appDir, '.hai', 'deploy')\n mkdirSync(artifactDir, { recursive: true })\n const appDockerfile = join(appDir, 'Dockerfile')\n let dockerfilePath: string\n let contextDir: string\n if (existsSync(appDockerfile)) {\n // 应用自带 Dockerfile 以 appDir 为上下文\n dockerfilePath = appDockerfile\n contextDir = appDir\n }\n else {\n // 兜底:monorepo 成员以 workspace 根为上下文,`pnpm --filter` 只构建目标应用\n dockerfilePath = join(artifactDir, 'Dockerfile')\n writeFileSync(dockerfilePath, generateFallbackDockerfile(readPackageName(appDir), containerPort))\n // 伴随 .dockerignore:保留 workspace 源码,覆盖仓库根可能排除 apps 的 .dockerignore\n writeFileSync(`${dockerfilePath}.dockerignore`, generateDockerignore())\n contextDir = resolveWorkspaceRoot(appDir)\n logger.info('Generated fallback Dockerfile', { dockerfilePath, contextDir })\n }\n\n // 3. 构建镜像\n const buildResult = await buildImage(localRuntime, {\n contextDir,\n dockerfilePath,\n imageRef: localImageTag,\n })\n if (!buildResult.success)\n return err(buildResult.error)\n\n // 4. 运行期环境与 sidecar 规划\n const { env, sidecar } = buildRuntimeEnv(appDir, projectName, scan, provisionEnv, containerPort)\n const envPath = join(artifactDir, '.env.runtime')\n writeFileSync(envPath, serializeEnvFile(env), { mode: 0o600 })\n\n // 5. 导出镜像\n const tarPath = join(artifactDir, `${projectName}.tar`)\n const saveResult = await saveImage(localRuntime, localImageTag, tarPath)\n if (!saveResult.success)\n return err(saveResult.error)\n\n // 6. 远程预检\n const pingResult = await ssh.ping()\n if (!pingResult.success)\n return err(pingResult.error)\n const remoteRuntimeResult = await detectRemoteRuntime()\n if (!remoteRuntimeResult.success)\n return err(remoteRuntimeResult.error)\n const remoteRuntime = remoteRuntimeResult.data\n\n // 7. 准备远程目录\n const remoteDir = `${baseDir}/${projectName}`\n const prepareResult = await ssh.exec(`mkdir -p ${remoteDir} && chmod 700 ${remoteDir}`)\n if (!prepareResult.success)\n return err(prepareResult.error)\n\n // 8. 传输镜像并加载\n const remoteTar = `${remoteDir}/image.tar`\n const uploadTarResult = await ssh.upload(tarPath, remoteTar)\n if (!uploadTarResult.success)\n return err(uploadTarResult.error)\n const loadResult = await ssh.exec(`${remoteRuntime} load -i ${remoteTar}`, { timeoutMs: 300_000 })\n if (!loadResult.success)\n return err(loadResult.error)\n // podman load 会把无 registry 的镜像名归一化为 docker.io/library/*,compose 据此会误拉取;\n // 统一重打为 localhost/ 本地标签(podman 永不从远端拉取 localhost/),docker 保持原名。\n const loadedRef = parseLoadedImageRef(loadResult.data.stdout, localImageTag)\n const remoteImageRef = remoteRuntime === 'podman' ? `localhost/${localImageTag}` : localImageTag\n if (loadedRef !== remoteImageRef) {\n const tagResult = await ssh.exec(`${remoteRuntime} tag ${loadedRef} ${remoteImageRef}`)\n if (!tagResult.success)\n return err(tagResult.error)\n }\n\n // 9. 生成并上传 compose + 运行期环境\n const composeContent = generateComposeFile({\n projectName,\n imageRef: remoteImageRef,\n hostPort,\n containerPort,\n sidecar,\n })\n const composePath = join(artifactDir, 'compose.yml')\n writeFileSync(composePath, composeContent)\n const uploadComposeResult = await ssh.upload(composePath, `${remoteDir}/compose.yml`)\n if (!uploadComposeResult.success)\n return err(uploadComposeResult.error)\n const uploadEnvResult = await ssh.upload(envPath, `${remoteDir}/.env.runtime`)\n if (!uploadEnvResult.success)\n return err(uploadEnvResult.error)\n const secretMask = sidecar.secrets\n const chmodResult = await ssh.exec(`chmod 600 ${remoteDir}/.env.runtime`, { secrets: secretMask })\n if (!chmodResult.success)\n return err(chmodResult.error)\n\n // 10. 启动\n const upResult = await ssh.exec(\n `cd ${remoteDir} && ${remoteRuntime} compose -p hai-${projectName} up -d`,\n { timeoutMs: 300_000, secrets: secretMask },\n )\n if (!upResult.success)\n return err(upResult.error)\n // 清理远程镜像 tar,节省空间(失败不阻断部署)\n await ssh.exec(`rm -f ${remoteTar}`)\n\n // 11. 健康检查\n const url = `http://${config.ssh.host}:${hostPort}`\n logger.info('Running health check', { url })\n const healthy = await healthCheck(`${url}/`)\n if (!healthy) {\n return err(\n HaiDeployError.HEALTH_CHECK_FAILED,\n deployM('deploy_healthCheckFailed', { params: { url } }),\n )\n }\n\n const result: DeployResult = {\n url,\n deploymentId,\n status: 'ready',\n provider: 'docker-ssh',\n healthCheck: 'passed',\n envVarsSet: Object.keys(env),\n }\n logger.info('docker-ssh deployment complete', { url, deploymentId })\n return ok(result)\n }\n\n return { name: 'docker-ssh', deploy }\n}\n","/**\n * @h-ai/deploy — Vercel 部署 Provider\n *\n * 封装 Vercel REST API,实现 DeployProvider 接口。 使用原生 fetch 调用,零外部 SDK 依赖。\n * @module deploy-provider-vercel\n */\n\nimport type { HaiError, HaiErrorDef, HaiResult } from '@h-ai/core'\nimport type { DeployProvider } from '../deploy-internal-types.js'\nimport type { DeployResult } from '../deploy-types.js'\nimport { createHash } from 'node:crypto'\nimport { readdirSync, readFileSync, statSync } from 'node:fs'\nimport { join, relative, sep } from 'node:path'\nimport { core, err, ok } from '@h-ai/core'\nimport { deployM } from '../deploy-i18n.js'\nimport { HaiDeployError } from '../deploy-types.js'\n\nconst logger = core.logger.child({ module: 'deploy', scope: 'provider-vercel' })\n\n/** Vercel API 基址 */\nconst VERCEL_API = 'https://api.vercel.com'\n\n/** 部署状态轮询间隔(毫秒) */\nconst POLL_INTERVAL = 3000\n\n/** 部署状态轮询最大次数 */\nconst MAX_POLL_ATTEMPTS = 60\n\n// ─── 内部工具 ───\n\n/** Vercel API 错误,保留状态码用于区分 404 与真实失败 */\nclass VercelApiError extends Error {\n constructor(readonly status: number) {\n super(deployM('deploy_apiError', { params: { service: 'Vercel', status: String(status) } }))\n }\n}\n\n/** 构造标准错误对象 */\nfunction toDeployError(codeDef: HaiErrorDef, messageKey: string, error: unknown): HaiError {\n return {\n ...codeDef,\n message: deployM(messageKey as Parameters<typeof deployM>[0], {\n params: { error: error instanceof Error ? error.message : String(error) },\n }),\n cause: error,\n }\n}\n\n/**\n * 发送 Vercel API 请求\n *\n * @param token - API Token\n * @param path - API 路径(如 /v2/user)\n * @param options - fetch 选项\n * @returns 解析后的 JSON 响应\n */\nasync function vercelFetch<T>(token: string, path: string, options?: RequestInit): Promise<T> {\n const url = `${VERCEL_API}${path}`\n const response = await fetch(url, {\n ...options,\n headers: {\n 'Authorization': `Bearer ${token}`,\n 'Content-Type': 'application/json',\n ...options?.headers,\n },\n })\n\n if (!response.ok) {\n throw new VercelApiError(response.status)\n }\n\n return response.json() as Promise<T>\n}\n\n/**\n * 递归收集目录中的所有文件\n *\n * @param dir - 目录路径\n * @param baseDir - 基础目录(用于计算相对路径)\n * @returns 文件相对路径列表\n */\nfunction collectFiles(dir: string, baseDir: string): string[] {\n const results: string[] = []\n const entries = readdirSync(dir, { withFileTypes: true })\n\n for (const entry of entries) {\n const fullPath = join(dir, entry.name)\n if (entry.isDirectory()) {\n results.push(...collectFiles(fullPath, baseDir))\n }\n else {\n results.push(relative(baseDir, fullPath).split(sep).join('/'))\n }\n }\n\n return results\n}\n\n// ─── Provider 工厂 ───\n\n/**\n * 创建 Vercel 部署 Provider\n *\n * @returns DeployProvider 实例\n *\n * @example\n * ```ts\n * const provider = createVercelProvider()\n * await provider.authenticate('vel_xxx')\n * const projectId = await provider.createProject('my-app')\n * ```\n */\nexport function createVercelProvider(): DeployProvider {\n let token: string | null = null\n\n return {\n name: 'vercel',\n\n async authenticate(apiToken: string): Promise<HaiResult<string>> {\n logger.debug('Authenticating with Vercel')\n try {\n const user = await vercelFetch<{ user: { username: string, email: string } }>(\n apiToken,\n '/v2/user',\n )\n token = apiToken\n const username = user.user.username || user.user.email\n logger.info('Vercel authenticated', { user: username })\n return ok(username)\n }\n catch (error) {\n logger.error('Vercel authentication failed', { error })\n return err(toDeployError(HaiDeployError.AUTH_FAILED, 'deploy_authFailed', error))\n }\n },\n\n async createProject(projectName: string): Promise<HaiResult<string>> {\n if (!token) {\n return err(\n HaiDeployError.AUTH_REQUIRED,\n deployM('deploy_authRequired'),\n )\n }\n\n logger.debug('Creating Vercel project', { projectName })\n try {\n // 先查找已有项目\n const existingId = await findExistingProject(token, projectName)\n if (existingId !== null) {\n logger.info('Vercel project found', { projectName, projectId: existingId })\n return ok(existingId)\n }\n\n try {\n const project = await vercelFetch<{ id: string }>(\n token,\n '/v11/projects',\n {\n method: 'POST',\n body: JSON.stringify({\n name: projectName,\n framework: 'sveltekit',\n }),\n },\n )\n logger.info('Vercel project created', { projectName, projectId: project.id })\n return ok(project.id)\n }\n catch (error) {\n // 官方文档说明同名项目创建会返回 409;遇到并发竞争时回查现有项目即可实现幂等。\n if (error instanceof VercelApiError && error.status === 409) {\n const concurrentProjectId = await findExistingProject(token, projectName)\n if (concurrentProjectId !== null) {\n logger.info('Vercel project reused after create conflict', {\n projectName,\n projectId: concurrentProjectId,\n })\n return ok(concurrentProjectId)\n }\n }\n throw error\n }\n }\n catch (error) {\n logger.error('Vercel project creation failed', { projectName, error })\n return err(toDeployError(HaiDeployError.PROJECT_CREATE_FAILED, 'deploy_projectCreateFailed', error))\n }\n },\n\n async setEnvVars(projectId: string, envVars: Record<string, string>): Promise<HaiResult<void>> {\n if (!token) {\n return err(\n HaiDeployError.AUTH_REQUIRED,\n deployM('deploy_authRequired'),\n )\n }\n\n logger.debug('Setting Vercel env vars', { projectId, count: Object.keys(envVars).length })\n try {\n const envEntries = Object.entries(envVars).map(([key, value]) => ({\n key,\n value,\n type: 'encrypted' as const,\n target: ['production', 'preview', 'development'],\n }))\n\n // Vercel 官方 `upsert=true` 支持按 key 覆盖已有环境变量,避免重复部署时报“已存在”。\n await vercelFetch(\n token,\n `/v10/projects/${projectId}/env?upsert=true`,\n {\n method: 'POST',\n body: JSON.stringify(envEntries),\n },\n )\n logger.info('Vercel env vars set', { projectId, count: envEntries.length })\n return ok(undefined)\n }\n catch (error) {\n logger.error('Vercel env vars setup failed', { projectId, error })\n return err(toDeployError(HaiDeployError.ENV_VAR_FAILED, 'deploy_envVarFailed', error))\n }\n },\n\n async deploy(projectId: string, outputDir: string): Promise<HaiResult<DeployResult>> {\n if (!token) {\n return err(\n HaiDeployError.AUTH_REQUIRED,\n deployM('deploy_authRequired'),\n )\n }\n\n logger.debug('Deploying to Vercel', { projectId, outputDir })\n try {\n // 收集所有文件\n const filePaths = collectFiles(outputDir, outputDir)\n const files: Array<{ file: string, sha: string, size: number }> = []\n\n // 上传每个文件\n for (const filePath of filePaths) {\n const fullPath = join(outputDir, filePath)\n const content = readFileSync(fullPath)\n const sha = createHash('sha1').update(content).digest('hex')\n const size = statSync(fullPath).size\n\n await uploadFile(token, content, sha)\n files.push({ file: filePath, sha, size })\n }\n\n logger.debug('Files uploaded', { count: files.length })\n\n // 创建部署\n const deployment = await vercelFetch<{ id: string, url: string }>(\n token,\n '/v13/deployments',\n {\n method: 'POST',\n body: JSON.stringify({\n name: projectId,\n files,\n projectSettings: { framework: 'sveltekit' },\n }),\n },\n )\n\n // 轮询部署状态\n const finalStatus = await pollDeploymentStatus(token, deployment.id)\n\n const result: DeployResult = {\n url: `https://${deployment.url}`,\n deploymentId: deployment.id,\n status: finalStatus,\n envVarsSet: [],\n }\n\n logger.info('Vercel deployment complete', {\n deploymentId: deployment.id,\n url: result.url,\n status: finalStatus,\n })\n\n return ok(result)\n }\n catch (error) {\n logger.error('Vercel deployment failed', { projectId, error })\n return err(toDeployError(HaiDeployError.UPLOAD_FAILED, 'deploy_uploadFailed', error))\n }\n },\n }\n}\n\n// ─── 内部辅助 ───\n\n/**\n * 查找已有的 Vercel 项目\n *\n * @param token - API Token\n * @param projectName - 项目名称\n * @returns 项目 ID,不存在时返回 null\n */\nasync function findExistingProject(token: string, projectName: string): Promise<string | null> {\n try {\n const project = await vercelFetch<{ id: string }>(token, `/v10/projects/${projectName}`)\n return project.id\n }\n catch (error) {\n if (error instanceof VercelApiError && error.status === 404) {\n return null\n }\n throw error\n }\n}\n\n/**\n * 上传单个文件到 Vercel\n *\n * @param token - API Token\n * @param content - 文件内容\n * @param sha - 文件 SHA1 哈希\n */\nasync function uploadFile(token: string, content: Uint8Array, sha: string): Promise<void> {\n const url = `${VERCEL_API}/v2/files`\n const uploadContent = new Uint8Array(content)\n const response = await fetch(url, {\n method: 'POST',\n headers: {\n 'Authorization': `Bearer ${token}`,\n 'Content-Type': 'application/octet-stream',\n 'x-vercel-digest': sha,\n },\n body: new Blob([uploadContent]),\n })\n\n if (!response.ok && response.status !== 409) {\n // 409 表示文件已存在,可忽略\n throw new Error(deployM('deploy_fileUploadFailed', { params: { status: String(response.status) } }))\n }\n}\n\n/**\n * 轮询部署状态直到完成\n *\n * @param token - API Token\n * @param deploymentId - 部署 ID\n * @returns 最终状态\n */\nasync function pollDeploymentStatus(\n token: string,\n deploymentId: string,\n): Promise<'ready' | 'building' | 'error'> {\n for (let i = 0; i < MAX_POLL_ATTEMPTS; i++) {\n const deployment = await vercelFetch<{ readyState: string }>(\n token,\n `/v13/deployments/${deploymentId}`,\n )\n\n if (deployment.readyState === 'READY') {\n return 'ready'\n }\n if (deployment.readyState === 'ERROR' || deployment.readyState === 'CANCELED') {\n return 'error'\n }\n\n // 等待后重试\n await new Promise(resolve => setTimeout(resolve, POLL_INTERVAL))\n }\n\n // 超时仍在构建\n return 'building'\n}\n","/**\n * @h-ai/deploy — Aliyun SMS Provisioner\n *\n * 验证阿里云 API 凭证用于短信服务。 阿里云短信资源(签名/模板)通常在控制台预配置,此 Provisioner 仅验证凭证。\n * @module deploy-provisioner-aliyun\n */\n\nimport type { HaiResult } from '@h-ai/core'\nimport type { ServiceProvisioner } from '../deploy-internal-types.js'\nimport type { ProvisionResult } from '../deploy-types.js'\nimport { core, err, ok } from '@h-ai/core'\nimport { deployM } from '../deploy-i18n.js'\nimport { HaiDeployError } from '../deploy-types.js'\n\nconst logger = core.logger.child({ module: 'deploy', scope: 'provisioner-aliyun' })\n\n/**\n * 创建 Aliyun SMS Provisioner\n *\n * @returns ServiceProvisioner 实例\n */\nexport function createAliyunProvisioner(): ServiceProvisioner {\n let accessKey: string | null = null\n let secretKey: string | null = null\n let signName = ''\n\n return {\n name: 'aliyun',\n serviceType: 'sms',\n\n async authenticate(credentials: Record<string, string>): Promise<HaiResult<string>> {\n logger.debug('Authenticating with Aliyun')\n try {\n const akId = credentials.accessKeyId ?? credentials.access_key_id ?? credentials.access_key ?? ''\n const akSecret = credentials.accessKeySecret ?? credentials.access_key_secret ?? credentials.secret_key ?? ''\n\n if (!akId || !akSecret || !credentials.signName) {\n throw new Error(deployM('deploy_credentialMissing', { params: { fields: 'accessKeyId, accessKeySecret, signName' } }))\n }\n\n accessKey = akId\n secretKey = akSecret\n signName = credentials.signName\n logger.info('Aliyun authenticated', { accessKeyId: `${akId.slice(0, 6)}***` })\n return ok(akId)\n }\n catch (error) {\n logger.error('Aliyun authentication failed', { error })\n return err(\n HaiDeployError.AUTH_FAILED,\n deployM('deploy_authFailed', {\n params: { error: error instanceof Error ? error.message : String(error) },\n }),\n error,\n )\n }\n },\n\n async provision(_appName: string): Promise<HaiResult<ProvisionResult>> {\n if (!accessKey || !secretKey) {\n return err(\n HaiDeployError.AUTH_REQUIRED,\n deployM('deploy_authRequired'),\n )\n }\n\n logger.debug('Provisioning Aliyun SMS service')\n\n // 阿里云短信不支持 API 创建资源,仅返回凭证作为环境变量\n return ok({\n serviceType: 'sms',\n provisionerName: 'aliyun',\n resourceStatus: 'reused',\n envVars: {\n HAI_REACH_PROVIDERS: JSON.stringify([{ name: 'sms', type: 'aliyun-sms', accessKeyId: accessKey, accessKeySecret: secretKey, signName }]),\n },\n resourceInfo: 'aliyun:verify-only',\n })\n },\n }\n}\n","/**\n * @h-ai/deploy — Neon PostgreSQL Provisioner\n *\n * 通过 Neon REST API 自动创建 PostgreSQL 数据库。\n * @module deploy-provisioner-neon\n */\n\nimport type { HaiResult } from '@h-ai/core'\nimport type { ServiceProvisioner } from '../deploy-internal-types.js'\nimport type { ProvisionResult } from '../deploy-types.js'\nimport { core, err, ok } from '@h-ai/core'\nimport { deployM } from '../deploy-i18n.js'\nimport { recoveryFailure } from '../deploy-recovery.js'\nimport { HaiDeployError } from '../deploy-types.js'\n\nconst logger = core.logger.child({ module: 'deploy', scope: 'provisioner-neon' })\n\n/** Neon API 基址 */\nconst NEON_API = 'https://console.neon.tech/api/v2'\n\n/** Neon 新建项目默认生成的数据库名。 */\nconst DEFAULT_NEON_DATABASE_NAME = 'neondb'\n\n/** Neon 新建项目默认生成的角色名。 */\nconst DEFAULT_NEON_ROLE_NAME = 'neondb_owner'\n\ninterface NeonProjectSummary {\n id: string\n name: string\n}\n\ninterface NeonProjectsResponse {\n projects?: NeonProjectSummary[]\n}\n\ninterface NeonCreateProjectResponse {\n connection_uris?: Array<{ connection_uri?: string }>\n project?: { id?: string }\n}\n\ninterface NeonConnectionUriResponse {\n uri?: string\n}\n\n/** 统一发起 Neon API 请求。 */\nasync function neonFetch<T>(token: string, path: string, options?: RequestInit): Promise<T> {\n const response = await fetch(`${NEON_API}${path}`, {\n ...options,\n headers: {\n 'Accept': 'application/json',\n 'Authorization': `Bearer ${token}`,\n 'Content-Type': 'application/json',\n ...options?.headers,\n },\n })\n\n if (!response.ok) {\n throw new Error(deployM('deploy_apiError', { params: { service: 'Neon', status: String(response.status) } }))\n }\n\n return response.json() as Promise<T>\n}\n\n/** 列出当前账号下的 Neon 项目。 */\nasync function listNeonProjects(token: string): Promise<NeonProjectSummary[]> {\n const data = await neonFetch<NeonProjectsResponse>(token, '/projects')\n return data.projects ?? []\n}\n\n/** 按名称查找已有的 Neon 项目。 */\nasync function findExistingNeonProject(token: string, projectName: string): Promise<NeonProjectSummary | null> {\n const projects = await listNeonProjects(token)\n return projects.find(project => project.name === projectName) ?? null\n}\n\n/**\n * 获取现有项目的连接串。\n *\n * Neon 官方 OpenAPI 提供 `GET /projects/{project_id}/connection_uri`。\n * 这里使用创建项目时的默认数据库/角色名,保证本模块创建的项目可被幂等复用。\n */\nasync function getNeonConnectionUri(token: string, projectId: string): Promise<string> {\n const query = new URLSearchParams({\n database_name: DEFAULT_NEON_DATABASE_NAME,\n role_name: DEFAULT_NEON_ROLE_NAME,\n })\n const data = await neonFetch<NeonConnectionUriResponse>(\n token,\n `/projects/${projectId}/connection_uri?${query.toString()}`,\n { headers: { 'Content-Type': 'application/json' } },\n )\n\n if (!data.uri) {\n throw new Error(deployM('deploy_provisionNoResult', { params: { service: 'Neon' } }))\n }\n\n return data.uri\n}\n\n/** 构建统一的 Neon 开通结果。 */\nfunction buildNeonProvisionResult(projectId: string, connectionUri: string, resourceStatus: 'created' | 'reused'): ProvisionResult {\n return {\n serviceType: 'db',\n provisionerName: 'neon',\n resourceStatus,\n envVars: {\n HAI_DB: JSON.stringify({ type: 'postgresql', url: connectionUri, database: decodeURIComponent(new URL(connectionUri).pathname.slice(1)) }),\n },\n resourceInfo: `neon-project:${projectId}`,\n }\n}\n\n/**\n * 创建 Neon PostgreSQL Provisioner\n *\n * @returns ServiceProvisioner 实例\n *\n * @example\n * ```ts\n * const neon = createNeonProvisioner()\n * await neon.authenticate({ apiKey: 'neon_xxx' })\n * const result = await neon.provision('my-app')\n * ```\n */\nexport function createNeonProvisioner(): ServiceProvisioner {\n let token: string | null = null\n\n return {\n name: 'neon',\n serviceType: 'db',\n\n async authenticate(credentials: Record<string, string>): Promise<HaiResult<string>> {\n logger.debug('Authenticating with Neon')\n try {\n const apiToken = credentials.apiKey ?? credentials.token ?? credentials.api_key ?? ''\n if (!apiToken) {\n throw new Error(deployM('deploy_credentialMissing', { params: { fields: 'token' } }))\n }\n\n await listNeonProjects(apiToken)\n token = apiToken\n logger.info('Neon authenticated')\n return ok('neon-user')\n }\n catch (error) {\n logger.error('Neon authentication failed', { error })\n return err(\n HaiDeployError.AUTH_FAILED,\n deployM('deploy_authFailed', {\n params: { error: error instanceof Error ? error.message : String(error) },\n }),\n error,\n )\n }\n },\n\n async provision(appName: string): Promise<HaiResult<ProvisionResult>> {\n if (!token) {\n return err(\n HaiDeployError.AUTH_REQUIRED,\n deployM('deploy_authRequired'),\n )\n }\n\n logger.debug('Provisioning Neon database', { appName })\n let resource: { resourceInfo: string, resourceStatus: 'created' | 'reused' } | undefined\n try {\n const projectName = `${appName}-db`\n\n const existingProject = await findExistingNeonProject(token, projectName)\n if (existingProject !== null) {\n resource = { resourceInfo: `neon-project:${existingProject.id}`, resourceStatus: 'reused' }\n const connectionUri = await getNeonConnectionUri(token, existingProject.id)\n logger.info('Neon project reused', {\n projectId: existingProject.id,\n projectName,\n })\n return ok(buildNeonProvisionResult(existingProject.id, connectionUri, 'reused'))\n }\n\n const data = await neonFetch<NeonCreateProjectResponse>(token, '/projects', {\n method: 'POST',\n body: JSON.stringify({\n project: {\n name: projectName,\n pg_version: 16,\n },\n }),\n })\n\n const projectId = data.project?.id ?? ''\n if (projectId)\n resource = { resourceInfo: `neon-project:${projectId}`, resourceStatus: 'created' }\n const connectionUri = data.connection_uris?.[0]?.connection_uri ?? ''\n if (!projectId || !connectionUri) {\n throw new Error(deployM('deploy_provisionNoResult', { params: { service: 'Neon' } }))\n }\n\n logger.info('Neon database provisioned', { projectId })\n\n return ok(buildNeonProvisionResult(projectId, connectionUri, 'created'))\n }\n catch (error) {\n logger.error('Neon provisioning failed', { appName })\n if (resource) {\n return recoveryFailure({ ...HaiDeployError.PROVISION_FAILED, message: '' }, {\n projectName: appName,\n stage: 'provision:db',\n resources: [{ serviceType: 'db', provisionerName: 'neon', ...resource }],\n })\n }\n return err(\n HaiDeployError.PROVISION_FAILED,\n deployM('deploy_provisionFailed', {\n params: {\n service: 'neon',\n error: error instanceof Error ? error.message : String(error),\n },\n }),\n error,\n )\n }\n },\n }\n}\n","/**\n * @h-ai/deploy — Cloudflare R2 Provisioner\n *\n * 通过 Cloudflare API 自动创建 R2 存储桶。\n * @module deploy-provisioner-r2\n */\n\nimport type { HaiResult } from '@h-ai/core'\nimport type { ServiceProvisioner } from '../deploy-internal-types.js'\nimport type { ProvisionResult } from '../deploy-types.js'\nimport { core, err, ok } from '@h-ai/core'\nimport { deployM } from '../deploy-i18n.js'\nimport { HaiDeployError } from '../deploy-types.js'\n\nconst logger = core.logger.child({ module: 'deploy', scope: 'provisioner-r2' })\n\n/** Cloudflare API 基址 */\nconst CF_API = 'https://api.cloudflare.com/client/v4'\n\n/**\n * 创建 Cloudflare R2 Provisioner\n *\n * @returns ServiceProvisioner 实例\n */\nexport function createR2Provisioner(): ServiceProvisioner {\n let token: string | null = null\n let accountId: string | null = null\n let accessKey = ''\n let secretKey = ''\n\n return {\n name: 'r2',\n serviceType: 'storage',\n\n async authenticate(credentials: Record<string, string>): Promise<HaiResult<string>> {\n logger.debug('Authenticating with Cloudflare')\n try {\n const acctId = credentials.accountId ?? credentials.account_id ?? ''\n const apiTok = credentials.apiToken ?? credentials.api_token ?? credentials.token ?? ''\n if (!acctId || !apiTok || !credentials.accessKeyId || !credentials.secretAccessKey) {\n throw new Error(deployM('deploy_credentialMissing', { params: { fields: 'accountId, apiToken, accessKeyId, secretAccessKey' } }))\n }\n\n const res = await fetch(`${CF_API}/accounts/${acctId}/r2/buckets`, {\n headers: { Authorization: `Bearer ${apiTok}` },\n })\n if (!res.ok) {\n throw new Error(deployM('deploy_apiError', { params: { service: 'Cloudflare', status: String(res.status) } }))\n }\n\n accountId = acctId\n token = apiTok\n accessKey = credentials.accessKeyId\n secretKey = credentials.secretAccessKey\n logger.info('Cloudflare R2 authenticated', { accountId: acctId })\n return ok(acctId)\n }\n catch (error) {\n logger.error('Cloudflare R2 authentication failed', { error })\n return err(\n HaiDeployError.AUTH_FAILED,\n deployM('deploy_authFailed', {\n params: { error: error instanceof Error ? error.message : String(error) },\n }),\n error,\n )\n }\n },\n\n async provision(appName: string): Promise<HaiResult<ProvisionResult>> {\n if (!token || !accountId) {\n return err(\n HaiDeployError.AUTH_REQUIRED,\n deployM('deploy_authRequired'),\n )\n }\n\n const bucketName = `${appName}-storage`.toLowerCase().replace(/[^a-z0-9-]/g, '-')\n\n logger.debug('Provisioning R2 bucket', { appName, bucketName })\n try {\n // 创建桶\n const createRes = await fetch(\n `${CF_API}/accounts/${accountId}/r2/buckets`,\n {\n method: 'POST',\n headers: {\n 'Authorization': `Bearer ${token}`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ name: bucketName }),\n },\n )\n\n // 409 表示桶已存在,可继续\n if (!createRes.ok && createRes.status !== 409) {\n throw new Error(deployM('deploy_apiError', { params: { service: 'Cloudflare', status: String(createRes.status) } }))\n }\n\n logger.info('R2 bucket provisioned', { bucketName })\n\n return ok({\n serviceType: 'storage',\n provisionerName: 'r2',\n resourceStatus: createRes.status === 409 ? 'reused' : 'created',\n envVars: {\n HAI_STORAGE: JSON.stringify({\n type: 's3',\n endpoint: `https://${accountId}.r2.cloudflarestorage.com`,\n bucket: bucketName,\n region: 'auto',\n accessKeyId: accessKey,\n secretAccessKey: secretKey,\n }),\n },\n resourceInfo: `r2-bucket:${bucketName}`,\n })\n }\n catch (error) {\n logger.error('R2 provisioning failed', { appName, error })\n return err(\n HaiDeployError.PROVISION_FAILED,\n deployM('deploy_provisionFailed', {\n params: {\n service: 'r2',\n error: error instanceof Error ? error.message : String(error),\n },\n }),\n error,\n )\n }\n },\n }\n}\n","/**\n * @h-ai/deploy — Resend Email Provisioner\n *\n * 通过 Resend REST API 验证 API Key 并获取域信息。 Resend 不支持通过 API 创建账户,此 Provisioner 仅验证已有凭证。\n * @module deploy-provisioner-resend\n */\n\nimport type { HaiResult } from '@h-ai/core'\nimport type { ServiceProvisioner } from '../deploy-internal-types.js'\nimport type { ProvisionResult } from '../deploy-types.js'\nimport { core, err, ok } from '@h-ai/core'\n\nimport { deployM } from '../deploy-i18n.js'\nimport { HaiDeployError } from '../deploy-types.js'\n\nconst logger = core.logger.child({ module: 'deploy', scope: 'provisioner-resend' })\n\n/** Resend API 基址 */\nconst RESEND_API = 'https://api.resend.com'\n\n/**\n * 创建 Resend Email Provisioner\n *\n * @returns ServiceProvisioner 实例\n */\nexport function createResendProvisioner(): ServiceProvisioner {\n let token: string | null = null\n let from = ''\n\n return {\n name: 'resend',\n serviceType: 'email',\n\n async authenticate(credentials: Record<string, string>): Promise<HaiResult<string>> {\n logger.debug('Authenticating with Resend')\n try {\n const apiToken = credentials.apiKey ?? credentials.api_key ?? credentials.token ?? ''\n if (!apiToken || !credentials.from) {\n throw new Error(deployM('deploy_credentialMissing', { params: { fields: 'apiKey, from' } }))\n }\n\n const res = await fetch(`${RESEND_API}/domains`, {\n headers: { Authorization: `Bearer ${apiToken}` },\n })\n if (!res.ok) {\n throw new Error(deployM('deploy_apiError', { params: { service: 'Resend', status: String(res.status) } }))\n }\n token = apiToken\n from = credentials.from\n logger.info('Resend authenticated')\n return ok('resend-user')\n }\n catch (error) {\n logger.error('Resend authentication failed', { error })\n return err(\n HaiDeployError.AUTH_FAILED,\n deployM('deploy_authFailed', {\n params: { error: error instanceof Error ? error.message : String(error) },\n }),\n error,\n )\n }\n },\n\n async provision(_appName: string): Promise<HaiResult<ProvisionResult>> {\n if (!token) {\n return err(\n HaiDeployError.AUTH_REQUIRED,\n deployM('deploy_authRequired'),\n )\n }\n\n logger.debug('Provisioning Resend email service')\n\n // Resend 不支持 API 创建资源,仅返回凭证作为环境变量\n return ok({\n serviceType: 'email',\n provisionerName: 'resend',\n resourceStatus: 'reused',\n envVars: {\n HAI_REACH_PROVIDERS: JSON.stringify([{ name: 'email', type: 'smtp', host: 'smtp.resend.com', port: 465, secure: true, user: 'resend', pass: token, from }]),\n },\n resourceInfo: 'resend:verify-only',\n })\n },\n }\n}\n","/**\n * @h-ai/deploy — Upstash Redis Provisioner\n *\n * 通过 Upstash REST API 自动创建 Redis 数据库。\n * @module deploy-provisioner-upstash\n */\n\nimport type { HaiResult } from '@h-ai/core'\nimport type { ServiceProvisioner } from '../deploy-internal-types.js'\nimport type { ProvisionResult } from '../deploy-types.js'\nimport { Buffer } from 'node:buffer'\nimport { core, err, ok } from '@h-ai/core'\n\nimport { deployM } from '../deploy-i18n.js'\nimport { recoveryFailure } from '../deploy-recovery.js'\nimport { HaiDeployError } from '../deploy-types.js'\n\nconst logger = core.logger.child({ module: 'deploy', scope: 'provisioner-upstash' })\n\n/** Upstash API 基址 */\nconst UPSTASH_API = 'https://api.upstash.com'\n\ninterface UpstashDatabase {\n database_id?: string\n database_name?: string\n endpoint?: string\n port?: number\n password?: string\n}\n\n/** 构建 Upstash Developer API 的 Basic Auth 请求头。 */\nfunction createUpstashAuthHeader(email: string, apiKey: string): string {\n return `Basic ${Buffer.from(`${email}:${apiKey}`).toString('base64')}`\n}\n\n/** 统一发起 Upstash Developer API 请求。 */\nasync function upstashFetch<T>(\n email: string,\n apiKey: string,\n path: string,\n options?: RequestInit,\n): Promise<T> {\n const response = await fetch(`${UPSTASH_API}${path}`, {\n ...options,\n headers: {\n 'Authorization': createUpstashAuthHeader(email, apiKey),\n 'Content-Type': 'application/json',\n ...options?.headers,\n },\n })\n\n if (!response.ok) {\n throw new Error(deployM('deploy_apiError', { params: { service: 'Upstash', status: String(response.status) } }))\n }\n\n return response.json() as Promise<T>\n}\n\n/** 列出当前账号下的所有 Upstash 数据库。 */\nasync function listUpstashDatabases(email: string, apiKey: string): Promise<UpstashDatabase[]> {\n return upstashFetch<UpstashDatabase[]>(email, apiKey, '/v2/redis/databases')\n}\n\n/** 按数据库名查找已有资源。 */\nasync function findExistingUpstashDatabase(\n email: string,\n apiKey: string,\n databaseName: string,\n): Promise<UpstashDatabase | null> {\n const databases = await listUpstashDatabases(email, apiKey)\n return databases.find(database => database.database_name === databaseName) ?? null\n}\n\n/** 获取单个数据库详情。 */\nasync function getUpstashDatabase(email: string, apiKey: string, databaseId: string): Promise<UpstashDatabase> {\n return upstashFetch<UpstashDatabase>(email, apiKey, `/v2/redis/database/${databaseId}`)\n}\n\n/** 将 Upstash 响应转换为 deploy 统一结果。 */\nfunction buildUpstashProvisionResult(database: UpstashDatabase, resourceStatus: 'created' | 'reused'): ProvisionResult {\n const databaseId = database.database_id ?? ''\n\n if (!databaseId || !database.endpoint || !database.password || !database.port) {\n throw new Error(deployM('deploy_provisionNoResult', { params: { service: 'Upstash' } }))\n }\n\n return {\n serviceType: 'cache',\n provisionerName: 'upstash',\n resourceStatus,\n envVars: {\n HAI_CACHE: JSON.stringify({ type: 'redis', url: `rediss://default:${encodeURIComponent(database.password)}@${database.endpoint}:${database.port}` }),\n },\n resourceInfo: `upstash-db:${databaseId}`,\n }\n}\n\n/**\n * 创建 Upstash Redis Provisioner\n *\n * @returns ServiceProvisioner 实例\n */\nexport function createUpstashProvisioner(): ServiceProvisioner {\n let apiKey: string | null = null\n let email: string | null = null\n\n return {\n name: 'upstash',\n serviceType: 'cache',\n\n async authenticate(credentials: Record<string, string>): Promise<HaiResult<string>> {\n logger.debug('Authenticating with Upstash')\n try {\n const userEmail = credentials.email ?? ''\n const userKey = credentials.apiKey ?? credentials.api_key ?? credentials.token ?? ''\n if (!userEmail || !userKey) {\n throw new Error(deployM('deploy_credentialMissing', { params: { fields: 'email, api_key' } }))\n }\n\n await listUpstashDatabases(userEmail, userKey)\n\n email = userEmail\n apiKey = userKey\n logger.info('Upstash authenticated', { email: userEmail })\n return ok(userEmail)\n }\n catch (error) {\n logger.error('Upstash authentication failed', { error })\n return err(\n HaiDeployError.AUTH_FAILED,\n deployM('deploy_authFailed', {\n params: { error: error instanceof Error ? error.message : String(error) },\n }),\n error,\n )\n }\n },\n\n async provision(appName: string): Promise<HaiResult<ProvisionResult>> {\n if (!apiKey || !email) {\n return err(\n HaiDeployError.AUTH_REQUIRED,\n deployM('deploy_authRequired'),\n )\n }\n\n logger.debug('Provisioning Upstash Redis', { appName })\n let resource: { resourceInfo: string, resourceStatus: 'created' | 'reused' } | undefined\n try {\n const databaseName = `${appName}-cache`\n\n const existingDatabase = await findExistingUpstashDatabase(email, apiKey, databaseName)\n if (existingDatabase !== null) {\n const databaseId = existingDatabase.database_id ?? ''\n if (!databaseId) {\n throw new Error(deployM('deploy_provisionNoResult', { params: { service: 'Upstash' } }))\n }\n\n resource = { resourceInfo: `upstash-db:${databaseId}`, resourceStatus: 'reused' }\n const detail = await getUpstashDatabase(email, apiKey, databaseId)\n logger.info('Upstash Redis reused', { databaseId, databaseName })\n return ok(buildUpstashProvisionResult({ ...existingDatabase, ...detail }, 'reused'))\n }\n\n const data = await upstashFetch<UpstashDatabase>(email, apiKey, '/v2/redis/database', {\n method: 'POST',\n body: JSON.stringify({\n name: databaseName,\n region: 'global',\n tls: true,\n }),\n })\n\n if (data.database_id)\n resource = { resourceInfo: `upstash-db:${data.database_id}`, resourceStatus: 'created' }\n logger.info('Upstash Redis provisioned', { databaseId: data.database_id })\n\n return ok(buildUpstashProvisionResult(data, 'created'))\n }\n catch (error) {\n logger.error('Upstash provisioning failed', { appName })\n if (resource) {\n return recoveryFailure({ ...HaiDeployError.PROVISION_FAILED, message: '' }, {\n projectName: appName,\n stage: 'provision:cache',\n resources: [{ serviceType: 'cache', provisionerName: 'upstash', ...resource }],\n })\n }\n return err(\n HaiDeployError.PROVISION_FAILED,\n deployM('deploy_provisionFailed', {\n params: {\n service: 'upstash',\n error: error instanceof Error ? error.message : String(error),\n },\n }),\n error,\n )\n }\n },\n }\n}\n","/**\n * @h-ai/deploy — 模块主入口\n *\n * 提供 deploy 单例对象,暴露完整的自动化部署 API。\n * @module deploy-main\n */\n\nimport type { HaiResult } from '@h-ai/core'\nimport type { ContainerDeployProvider } from './container/deploy-container-types.js'\nimport type { DeployConfig, DeployConfigInput } from './deploy-config.js'\nimport type { DeployProvider, ServiceProvisioner } from './deploy-internal-types.js'\nimport type {\n DeployAppOptions,\n DeployCredentialOperations,\n DeployFunctions,\n DeployRecoveryInfo,\n DeployResult,\n ProvisionResult,\n ScanResult,\n ServiceType,\n} from './deploy-types.js'\nimport { core, err, ok } from '@h-ai/core'\nimport { DeployConfigSchema } from './deploy-config.js'\nimport {\n getCredentialsPath,\n loadCredentials,\n saveCredential,\n saveCredentials,\n} from './deploy-credentials.js'\nimport { buildApp, resolveOutputDir } from './deploy-functions.js'\nimport { deployM } from './deploy-i18n.js'\nimport { getDeployRecovery, recoveryFailure } from './deploy-recovery.js'\nimport { scanApp } from './deploy-scanner.js'\nimport { HaiDeployError } from './deploy-types.js'\nimport { createDockerSshProvider } from './providers/deploy-provider-docker-ssh.js'\nimport { createVercelProvider } from './providers/deploy-provider-vercel.js'\nimport { createAliyunProvisioner } from './provisioners/deploy-provisioner-aliyun.js'\nimport { createNeonProvisioner } from './provisioners/deploy-provisioner-neon.js'\nimport { createR2Provisioner } from './provisioners/deploy-provisioner-r2.js'\nimport { createResendProvisioner } from './provisioners/deploy-provisioner-resend.js'\nimport { createUpstashProvisioner } from './provisioners/deploy-provisioner-upstash.js'\n\nconst logger = core.logger.child({ module: 'deploy', scope: 'main' })\n\n// ─── 内部状态 ───\n\nlet currentConfig: DeployConfig | null = null\nlet currentProvider: DeployProvider | null = null\nlet currentContainerProvider: ContainerDeployProvider | null = null\nconst currentProvisioners: Map<ServiceType, ServiceProvisioner> = new Map()\n\n/** 并发初始化防护标志 */\nlet initInProgress = false\n\n// ─── 未初始化占位 ───\n\nconst notInitialized = core.module.createNotInitializedKit(\n HaiDeployError.NOT_INITIALIZED,\n () => deployM('deploy_notInitialized'),\n)\n\n// ─── Provider 工厂 ───\n\n/**\n * 根据配置类型创建对应的 DeployProvider\n *\n * @param type - Provider 类型\n * @returns DeployProvider 实例\n */\nfunction createProviderByType(type: string): DeployProvider {\n switch (type) {\n case 'vercel':\n return createVercelProvider()\n default:\n throw new Error(deployM('deploy_unsupportedProviderType', { params: { type } }))\n }\n}\n\n// ─── Provisioner 工厂 ───\n\n/**\n * 根据 provisioner 名称创建对应的 ServiceProvisioner\n *\n * @param provisioner - Provisioner 标识\n * @returns ServiceProvisioner 实例\n */\nfunction createProvisionerByName(provisioner: string): ServiceProvisioner {\n switch (provisioner) {\n case 'neon':\n return createNeonProvisioner()\n case 'upstash':\n return createUpstashProvisioner()\n case 'cloudflare-r2':\n return createR2Provisioner()\n case 'resend':\n return createResendProvisioner()\n case 'aliyun':\n return createAliyunProvisioner()\n default:\n throw new Error(deployM('deploy_unsupportedProvisionerType', { params: { type: provisioner } }))\n }\n}\n\n/**\n * 从配置中提取 provisioner 凭证并转为 Record<string, string>\n *\n * @param serviceConfig - 服务配置对象\n * @returns 凭证键值对\n */\nfunction extractCredentials(serviceConfig: Record<string, unknown>): Record<string, string> {\n const result: Record<string, string> = {}\n for (const [key, value] of Object.entries(serviceConfig)) {\n if (key !== 'provisioner' && typeof value === 'string') {\n result[key] = value\n }\n }\n return result\n}\n\n/**\n * Deploy 凭证子功能。\n *\n * 这些操作仅处理本地 `~/.hai/credentials.yml`,供 CLI 在读取 `_deploy.yml`\n * 之前注入 `HAI_DEPLOY_*` 环境变量,因此不依赖 `deploy.init()`。\n */\nconst deployCredentials: DeployCredentialOperations = {\n getPath: () => getCredentialsPath(),\n load: () => loadCredentials(),\n save: (key: string, value: string) => saveCredential(key, value),\n saveAll: (entries: Record<string, string>) => saveCredentials(entries),\n}\n\n/** 归一化项目名为容器/镜像安全的 `[a-z0-9-]`。 */\nfunction normalizeProjectName(name: string): string {\n const normalized = name\n .replace(/^@[^/]+\\//, '')\n .toLowerCase()\n .replace(/[^a-z0-9-]+/g, '-')\n .replace(/^-+|-+$/g, '')\n return normalized || 'app'\n}\n\n/** 合并 Provisioner 输出环境变量,并聚合 HAI_REACH_PROVIDERS 数组。 */\nfunction mergeProvisionEnv(results: ProvisionResult[]): Record<string, string> {\n let env: Record<string, string> = {}\n const reachProviders: unknown[] = []\n for (const prov of results) {\n if (prov.envVars.HAI_REACH_PROVIDERS)\n reachProviders.push(...JSON.parse(prov.envVars.HAI_REACH_PROVIDERS) as unknown[])\n env = { ...env, ...prov.envVars }\n }\n if (reachProviders.length > 0)\n env.HAI_REACH_PROVIDERS = JSON.stringify(reachProviders)\n return env\n}\n\n// ─── 模块单例 ───\n\n/**\n * Deploy 模块单例\n *\n * @example\n * ```ts\n * import { deploy } from '@h-ai/deploy'\n *\n * await deploy.init({ provider: { type: 'vercel', token: 'xxx' } })\n * const result = await deploy.deployApp('./apps/my-app')\n * await deploy.close()\n * ```\n */\nexport const deploy: DeployFunctions = {\n credentials: deployCredentials,\n\n async init(config: DeployConfigInput): Promise<HaiResult<void>> {\n // 并发初始化防护:避免多次 init 同时执行导致资源泄漏\n if (initInProgress) {\n logger.warn('Deploy init already in progress, skipping concurrent call')\n return err(\n HaiDeployError.CONFIG_ERROR,\n deployM('deploy_configError', { params: { error: 'init already in progress' } }),\n )\n }\n initInProgress = true\n\n try {\n if (currentProvider || currentContainerProvider) {\n logger.warn('Deploy module is already initialized, reinitializing')\n await deploy.close()\n }\n\n logger.info('Initializing deploy module')\n\n const parseResult = DeployConfigSchema.safeParse(config)\n if (!parseResult.success) {\n logger.error('Deploy config validation failed', { error: parseResult.error.message })\n return err(\n HaiDeployError.CONFIG_ERROR,\n deployM('deploy_configError', { params: { error: parseResult.error.message } }),\n parseResult.error,\n )\n }\n const parsed = parseResult.data\n\n try {\n // 创建部署 Provider:docker-ssh 走容器路径(无远程认证),其余走平台路径并即时认证\n let provider: DeployProvider | null = null\n let containerProvider: ContainerDeployProvider | null = null\n if (parsed.provider.type === 'docker-ssh') {\n containerProvider = createDockerSshProvider(parsed.provider, parsed.container?.runtime)\n logger.info('Container deploy provider ready', { provider: 'docker-ssh', host: parsed.provider.ssh.host })\n }\n else {\n provider = createProviderByType(parsed.provider.type)\n const authResult = await provider.authenticate(parsed.provider.token)\n if (!authResult.success) {\n return err(authResult.error)\n }\n logger.info('Provider authenticated', { provider: parsed.provider.type, user: authResult.data })\n }\n\n // 创建 Provisioners(两类 Provider 均可复用云资源开通)\n currentProvisioners.clear()\n if (parsed.services) {\n const serviceEntries = Object.entries(parsed.services) as Array<[ServiceType, Record<string, unknown> | undefined]>\n for (const [serviceType, serviceConfig] of serviceEntries) {\n if (!serviceConfig)\n continue\n\n const provisioner = createProvisionerByName(serviceConfig.provisioner as string)\n const credentials = extractCredentials(serviceConfig as Record<string, unknown>)\n const provAuthResult = await provisioner.authenticate(credentials)\n if (!provAuthResult.success) {\n logger.error('Provisioner authentication failed', {\n service: serviceType,\n provisioner: (serviceConfig as Record<string, unknown>).provisioner,\n })\n currentProvisioners.clear()\n return err(provAuthResult.error)\n }\n logger.info('Provisioner authenticated', {\n service: serviceType,\n user: provAuthResult.data,\n })\n currentProvisioners.set(serviceType, provisioner)\n }\n }\n\n currentProvider = provider\n currentContainerProvider = containerProvider\n currentConfig = parsed\n logger.info('Deploy module initialized', {\n provider: parsed.provider.type,\n provisioners: [...currentProvisioners.keys()],\n })\n return ok(undefined)\n }\n catch (error) {\n // 清理部分赋值的状态\n currentProvider = null\n currentContainerProvider = null\n currentConfig = null\n currentProvisioners.clear()\n logger.error('Deploy module initialization failed', { error })\n return err(\n HaiDeployError.CONFIG_ERROR,\n deployM('deploy_configError', {\n params: { error: error instanceof Error ? error.message : String(error) },\n }),\n error,\n )\n }\n }\n finally {\n initInProgress = false\n }\n },\n\n async close(): Promise<void> {\n if (!currentProvider && !currentContainerProvider) {\n logger.info('Deploy module already closed, skipping')\n return\n }\n\n logger.info('Closing deploy module')\n currentProvider = null\n currentContainerProvider = null\n currentConfig = null\n currentProvisioners.clear()\n logger.info('Deploy module closed')\n },\n\n get config(): DeployConfig | null {\n return currentConfig\n },\n\n get isInitialized(): boolean {\n return currentProvider !== null || currentContainerProvider !== null\n },\n\n async scan(appDir: string): Promise<HaiResult<ScanResult>> {\n // scan 仅做本地文件分析,不依赖 Provider / Provisioner 初始化状态。\n logger.debug('Scanning application', { appDir })\n return scanApp(appDir)\n },\n\n async provisionAll(projectName: string): Promise<HaiResult<ProvisionResult[]>> {\n if (!currentProvider && !currentContainerProvider) {\n return notInitialized.result()\n }\n\n logger.info('Provisioning all services', { projectName, count: currentProvisioners.size })\n const results: ProvisionResult[] = []\n\n for (const [serviceType, provisioner] of currentProvisioners) {\n logger.debug('Provisioning service', { serviceType, provisioner: provisioner.name })\n const provResult = await provisioner.provision(projectName)\n if (!provResult.success) {\n logger.error('Service provisioning failed', {\n serviceType,\n provisioner: provisioner.name,\n code: provResult.error.code,\n })\n return recoveryFailure(provResult.error, {\n projectName,\n stage: `provision:${serviceType}`,\n resources: [\n ...results.map(({ envVars: _envVars, ...resource }) => resource),\n ...(getDeployRecovery(provResult.error)?.resources ?? [\n { serviceType, provisionerName: provisioner.name, resourceInfo: projectName, resourceStatus: 'unknown' as const },\n ]),\n ],\n })\n }\n results.push(provResult.data)\n logger.info('Service provisioned', { serviceType, provisioner: provisioner.name })\n }\n\n return ok(results)\n },\n\n async deployApp(\n appDir: string,\n options?: DeployAppOptions,\n ): Promise<HaiResult<DeployResult>> {\n if (!currentProvider && !currentContainerProvider) {\n return notInitialized.result()\n }\n\n logger.info('Starting deployment', { appDir, options })\n\n // 1. 扫描应用\n const scanResult = await scanApp(appDir)\n if (!scanResult.success) {\n return err(scanResult.error)\n }\n const scan = scanResult.data\n const projectName = options?.projectName ?? scan.appName\n\n // 容器 Provider(docker-ssh):走独立的容器部署编排\n if (currentContainerProvider) {\n return deployContainerApp(currentContainerProvider, appDir, scan, projectName, options)\n }\n\n // 到此必为平台 Provider(vercel)\n if (!currentProvider) {\n return notInitialized.result()\n }\n\n // 2. 检查 adapter\n if (scan.isSvelteKit && !scan.adapterInstalled) {\n return err(\n HaiDeployError.ADAPTER_MISSING,\n deployM('deploy_adapterMissing', {\n params: { adapter: '@sveltejs/adapter-vercel' },\n }),\n )\n }\n\n // 3. 开通基础设施\n let allEnvVars: Record<string, string> = {}\n const recovery: DeployRecoveryInfo = { projectName, stage: 'provision', resources: [] }\n if (!options?.skipProvision) {\n const provResults = await deploy.provisionAll(projectName)\n if (!provResults.success) {\n return err(provResults.error)\n }\n recovery.resources = provResults.data.map(({ envVars: _envVars, ...resource }) => resource)\n allEnvVars = mergeProvisionEnv(provResults.data)\n }\n\n // 4. 创建平台项目\n const projectResult = await currentProvider.createProject(projectName)\n if (!projectResult.success) {\n return recoveryFailure(projectResult.error, { ...recovery, stage: 'create-project' })\n }\n const projectId = projectResult.data\n recovery.platformProjectId = projectId\n\n // 5. 设置环境变量\n if (Object.keys(allEnvVars).length > 0) {\n const envResult = await currentProvider.setEnvVars(projectId, allEnvVars)\n if (!envResult.success) {\n return recoveryFailure(envResult.error, { ...recovery, stage: 'set-env' })\n }\n }\n\n // 6. 构建应用\n if (!options?.skipBuild) {\n const buildResult = buildApp(appDir, scan.buildCommand, allEnvVars)\n if (!buildResult.success) {\n return recoveryFailure(buildResult.error, { ...recovery, stage: 'build' })\n }\n }\n\n // 7. 部署\n const outputDir = resolveOutputDir(appDir, currentConfig?.provider.type ?? 'vercel')\n const deployResult = await currentProvider.deploy(projectId, outputDir)\n if (!deployResult.success) {\n return recoveryFailure(deployResult.error, { ...recovery, stage: 'deploy' })\n }\n\n // 补充环境变量列表到结果中\n const result: DeployResult = {\n ...deployResult.data,\n envVarsSet: Object.keys(allEnvVars),\n }\n\n logger.info('Deployment completed', {\n url: result.url,\n deploymentId: result.deploymentId,\n status: result.status,\n })\n\n return ok(result)\n },\n}\n\n/**\n * 容器 Provider(docker-ssh)部署编排。\n *\n * 校验 adapter-node → 开通云资源(可选)→ 交由容器 Provider 完成\n * 构建 / 传输 / compose up / 健康检查。\n *\n * @param provider - 容器部署 Provider\n * @param appDir - 应用根目录\n * @param scan - 扫描结果\n * @param rawProjectName - 原始项目名(未归一化)\n * @param options - 部署选项\n */\nasync function deployContainerApp(\n provider: ContainerDeployProvider,\n appDir: string,\n scan: ScanResult,\n rawProjectName: string,\n options?: DeployAppOptions,\n): Promise<HaiResult<DeployResult>> {\n const projectName = normalizeProjectName(rawProjectName)\n\n // 容器部署要求 @sveltejs/adapter-node(输出可用 node 直接运行的 build/)\n if (scan.isSvelteKit && !scan.nodeAdapterInstalled) {\n return err(\n HaiDeployError.ADAPTER_MISSING,\n deployM('deploy_adapterMissing', { params: { adapter: '@sveltejs/adapter-node' } }),\n )\n }\n\n let provisionEnv: Record<string, string> = {}\n if (!options?.skipProvision) {\n const provResults = await deploy.provisionAll(projectName)\n if (!provResults.success) {\n return err(provResults.error)\n }\n provisionEnv = mergeProvisionEnv(provResults.data)\n }\n\n return provider.deploy({ appDir, projectName, scan, provisionEnv })\n}\n"]}
|