@h-ai/deploy 0.1.0-alpha5
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/LICENSE +202 -0
- package/README.md +96 -0
- package/dist/index.d.ts +370 -0
- package/dist/index.js +1270 -0
- package/dist/index.js.map +1 -0
- package/package.json +44 -0
|
@@ -0,0 +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-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","readFileSync","parse","readdirSync"],"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_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}): {body}\",\n \"deploy_fileUploadFailed\": \"File upload failed ({status}): {body}\",\n \"deploy_provisionNoResult\": \"No connection info returned from {service}\"\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_credentialSaved\": \"凭证已保存\",\n \"deploy_credentialLoaded\": \"凭证已加载\",\n \"deploy_configError\": \"部署配置错误:{error}\",\n \"deploy_credentialMissing\": \"缺少凭证字段:{fields}\",\n \"deploy_apiError\": \"{service} API 请求失败({status}):{body}\",\n \"deploy_fileUploadFailed\": \"文件上传失败({status}):{body}\",\n \"deploy_provisionNoResult\": \"{service} 未返回连接信息\"\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 * import { deployM } from '@h-ai/deploy'\n *\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 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 apiKey: z.string().min(1),\n})\n\n/** 阿里云短信服务配置 */\nconst AliyunSmsServiceSchema = z.object({\n provisioner: z.literal('aliyun'),\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 ENV_VAR_FAILED: '010:500',\n NOT_INITIALIZED: '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 /** 服务类型 */\n serviceType: ServiceType\n /** Provisioner 名称 */\n provisionerName: string\n /** 要注入到部署平台的环境变量 */\n envVars: Record<string, string>\n /** 资源标识信息(如项目名、数据库名等),用于日志和展示 */\n resourceInfo: string\n}\n\n// ─── Provider 接口 ───\n\n/**\n * 部署平台 Provider 接口(Vercel / Cloudflare Pages 等)\n *\n * 通过工厂函数创建(如 `createVercelProvider()`),负责将构建产物部署到目标平台。\n */\nexport interface DeployProvider {\n /** Provider 名称 */\n readonly name: string\n\n /**\n * 验证凭证有效性\n *\n * @param token - 平台 API Token\n * @returns 用户信息摘要(如邮箱/用户名)\n */\n authenticate: (token: string) => Promise<HaiResult<string>>\n\n /**\n * 创建平台项目(幂等:已存在则返回现有项目 ID)\n *\n * @param projectName - 项目名称\n * @returns 项目 ID\n */\n createProject: (projectName: string) => Promise<HaiResult<string>>\n\n /**\n * 批量设置项目环境变量\n *\n * @param projectId - 平台项目 ID\n * @param envVars - 环境变量键值对\n */\n setEnvVars: (projectId: string, envVars: Record<string, string>) => Promise<HaiResult<void>>\n\n /**\n * 上传构建产物并触发部署\n *\n * @param projectId - 平台项目 ID\n * @param outputDir - 构建产物目录(如 .vercel/output/)\n * @returns 部署结果\n */\n deploy: (projectId: string, outputDir: string) => Promise<HaiResult<DeployResult>>\n}\n\n// ─── Provisioner 接口 ───\n\n/**\n * 基础设施服务 Provisioner 接口(Neon / Upstash / R2 / Resend / Aliyun)\n *\n * 通过工厂函数创建(如 `createNeonProvisioner(config)`),负责开通/验证云服务。\n */\nexport interface ServiceProvisioner {\n /** Provisioner 名称 */\n readonly name: string\n /** 对应的服务类型 */\n readonly serviceType: ServiceType\n\n /**\n * 验证凭证有效性\n *\n * @param credentials - 凭证键值对\n * @returns 账户标识信息\n */\n authenticate: (credentials: Record<string, string>) => Promise<HaiResult<string>>\n\n /**\n * 开通/查找服务资源(幂等:按项目名查找已有资源)\n *\n * @param projectName - 项目名称,用作资源命名\n * @returns 开通结果(含环境变量映射)\n */\n provision: (projectName: string) => Promise<HaiResult<ProvisionResult>>\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 * 提供自动化部署的完整 API:\n * - `deploy.init()` — 初始化(加载配置、创建 Provider 和 Provisioner)\n * - `deploy.scan()` — 扫描应用依赖\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 /** 初始化模块(加载配置、创建 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 * @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`。 CLI 在加载 `_deploy.yml` 之前调用 `loadCredentials()` 将凭证注入 process.env, 使 core 的 `interpolateEnv()` 能自动解析 `${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// ─── 内部工具 ───\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') {\n return {}\n }\n return parsed as Record<string, string>\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 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 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 * @returns 构建结果\n */\nexport function buildApp(appDir: string, buildCommand: 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 },\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","/**\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, DeployResult } from '../deploy-types.js'\nimport { createHash } from 'node:crypto'\nimport { readdirSync, readFileSync, statSync } from 'node:fs'\nimport { join, relative } 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/** 构造标准错误对象 */\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 const body = await response.text()\n throw new Error(deployM('deploy_apiError', { params: { service: 'Vercel', status: String(response.status), body } }))\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))\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 // 创建新项目\n const project = await vercelFetch<{ id: string }>(\n token,\n '/v10/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 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 await vercelFetch(\n token,\n `/v10/projects/${projectId}/env`,\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 {\n return null\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 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([content.buffer as ArrayBuffer]),\n })\n\n if (!response.ok && response.status !== 409) {\n // 409 表示文件已存在,可忽略\n const body = await response.text()\n throw new Error(deployM('deploy_fileUploadFailed', { params: { status: String(response.status), body } }))\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 { ProvisionResult, ServiceProvisioner } 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\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) {\n throw new Error(deployM('deploy_credentialMissing', { params: { fields: 'access_key_id, access_key_secret' } }))\n }\n\n accessKey = akId\n secretKey = akSecret\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 envVars: {\n HAI_REACH_SMS_ACCESS_KEY: accessKey,\n HAI_REACH_SMS_SECRET_KEY: secretKey,\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 { ProvisionResult, ServiceProvisioner } 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-neon' })\n\n/** Neon API 基址 */\nconst NEON_API = 'https://console.neon.tech/api/v2'\n\n/**\n * 创建 Neon PostgreSQL Provisioner\n *\n * @returns ServiceProvisioner 实例\n *\n * @example\n * ```ts\n * const neon = createNeonProvisioner()\n * await neon.authenticate('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 const res = await fetch(`${NEON_API}/projects`, {\n headers: { Authorization: `Bearer ${apiToken}` },\n })\n if (!res.ok) {\n throw new Error(deployM('deploy_apiError', { params: { service: 'Neon', status: String(res.status), body: await res.text() } }))\n }\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 try {\n const res = await fetch(`${NEON_API}/projects`, {\n method: 'POST',\n headers: {\n 'Authorization': `Bearer ${token}`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n project: {\n name: `${appName}-db`,\n pg_version: 16,\n },\n }),\n })\n\n if (!res.ok) {\n throw new Error(deployM('deploy_apiError', { params: { service: 'Neon', status: String(res.status), body: await res.text() } }))\n }\n\n const data = await res.json() as {\n connection_uris: Array<{ connection_uri: string }>\n project: { id: string }\n }\n\n const connectionUri = data.connection_uris?.[0]?.connection_uri\n if (!connectionUri) {\n throw new Error(deployM('deploy_provisionNoResult', { params: { service: 'Neon' } }))\n }\n\n logger.info('Neon database provisioned', { projectId: data.project.id })\n\n return ok({\n serviceType: 'db',\n provisionerName: 'neon',\n envVars: {\n HAI_RELDB_URL: connectionUri,\n },\n resourceInfo: `neon-project:${data.project.id}`,\n })\n }\n catch (error) {\n logger.error('Neon provisioning failed', { appName, error })\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 { ProvisionResult, ServiceProvisioner } 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\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) {\n throw new Error(deployM('deploy_credentialMissing', { params: { fields: 'account_id, api_token' } }))\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), body: await res.text() } }))\n }\n\n accountId = acctId\n token = apiTok\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), body: await createRes.text() } }))\n }\n\n // 创建 API Token(S3 兼容访问)\n const tokenRes = await fetch(\n `${CF_API}/user/tokens`,\n {\n method: 'POST',\n headers: {\n 'Authorization': `Bearer ${token}`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n name: `${appName}-r2-token`,\n policies: [{\n effect: 'allow',\n permission_groups: [{ id: 'r2-read-write' }],\n resources: { [`com.cloudflare.edge.r2.bucket.${accountId}_default_${bucketName}`]: '*' },\n }],\n }),\n },\n )\n\n let accessKey = ''\n let secretKey = ''\n\n if (tokenRes.ok) {\n const tokenData = await tokenRes.json() as {\n result: { id: string, value: string }\n }\n accessKey = tokenData.result.id\n secretKey = tokenData.result.value\n }\n\n logger.info('R2 bucket provisioned', { bucketName })\n\n return ok({\n serviceType: 'storage',\n provisionerName: 'r2',\n envVars: {\n HAI_STORAGE_S3_ENDPOINT: `https://${accountId}.r2.cloudflarestorage.com`,\n HAI_STORAGE_S3_BUCKET: bucketName,\n HAI_STORAGE_S3_ACCESS_KEY: accessKey,\n HAI_STORAGE_S3_SECRET_KEY: secretKey,\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 { ProvisionResult, ServiceProvisioner } 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\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) {\n throw new Error('Missing \"api_key\" in credentials')\n }\n\n const res = await fetch(`${RESEND_API}/domains`, {\n headers: { Authorization: `Bearer ${apiToken}` },\n })\n if (!res.ok) {\n throw new Error(`Resend API ${res.status}: ${await res.text()}`)\n }\n token = apiToken\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 envVars: {\n HAI_REACH_RESEND_KEY: token,\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 { ProvisionResult, ServiceProvisioner } 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-upstash' })\n\n/** Upstash API 基址 */\nconst UPSTASH_API = 'https://api.upstash.com'\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 const res = await fetch(`${UPSTASH_API}/v2/redis/databases`, {\n headers: {\n Authorization: `Basic ${btoa(`${userEmail}:${userKey}`)}`,\n },\n })\n if (!res.ok) {\n throw new Error(deployM('deploy_apiError', { params: { service: 'Upstash', status: String(res.status), body: await res.text() } }))\n }\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 try {\n const res = await fetch(`${UPSTASH_API}/v2/redis/database`, {\n method: 'POST',\n headers: {\n 'Authorization': `Basic ${btoa(`${email}:${apiKey}`)}`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n name: `${appName}-cache`,\n region: 'global',\n tls: true,\n }),\n })\n\n if (!res.ok) {\n throw new Error(deployM('deploy_apiError', { params: { service: 'Upstash', status: String(res.status), body: await res.text() } }))\n }\n\n const data = await res.json() as {\n database_id: string\n rest_url: string\n rest_token: string\n }\n\n logger.info('Upstash Redis provisioned', { databaseId: data.database_id })\n\n return ok({\n serviceType: 'cache',\n provisionerName: 'upstash',\n envVars: {\n HAI_CACHE_UPSTASH_URL: data.rest_url,\n HAI_CACHE_UPSTASH_TOKEN: data.rest_token,\n },\n resourceInfo: `upstash-db:${data.database_id}`,\n })\n }\n catch (error) {\n logger.error('Upstash provisioning failed', { appName, error })\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 { DeployAppOptions, DeployFunctions, DeployProvider, DeployResult, ProvisionResult, ScanResult, ServiceProvisioner, ServiceType } from './deploy-types.js'\nimport { core, err, ok } from '@h-ai/core'\nimport { DeployConfigSchema } from './deploy-config.js'\nimport { buildApp, resolveOutputDir } from './deploy-functions.js'\nimport { deployM } from './deploy-i18n.js'\nimport { scanApp } from './deploy-scanner.js'\nimport {\n\n HaiDeployError,\n\n} 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\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 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.warn('Provisioner authentication failed', {\n service: serviceType,\n provisioner: (serviceConfig as Record<string, unknown>).provisioner,\n })\n // 非致命:记录警告但继续\n }\n else {\n logger.info('Provisioner authenticated', {\n service: serviceType,\n user: provAuthResult.data,\n })\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 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 error: provResult.error,\n })\n return err(provResult.error)\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 if (!options?.skipProvision) {\n const provResults = await deploy.provisionAll(projectName)\n if (!provResults.success) {\n return err(provResults.error)\n }\n for (const prov of provResults.data) {\n allEnvVars = { ...allEnvVars, ...prov.envVars }\n }\n }\n\n // 4. 创建平台项目\n const projectResult = await currentProvider.createProject(projectName)\n if (!projectResult.success) {\n return err(projectResult.error)\n }\n const projectId = projectResult.data\n\n // 5. 设置环境变量\n if (Object.keys(allEnvVars).length > 0) {\n const envResult = await currentProvider.setEnvVars(projectId, allEnvVars)\n if (!envResult.success) {\n return err(envResult.error)\n }\n }\n\n // 6. 构建应用\n if (!options?.skipBuild) {\n const buildResult = buildApp(appDir, scan.buildCommand)\n if (!buildResult.success) {\n return err(buildResult.error)\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 err(deployResult.error)\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"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@h-ai/deploy",
|
|
3
|
+
"type": "module",
|
|
4
|
+
"version": "0.1.0-alpha5",
|
|
5
|
+
"description": "Hai Framework deployment automation module.",
|
|
6
|
+
"license": "Apache-2.0",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"import": "./dist/index.js",
|
|
11
|
+
"default": "./dist/index.js"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"main": "./dist/index.js",
|
|
15
|
+
"types": "./dist/index.d.ts",
|
|
16
|
+
"files": [
|
|
17
|
+
"dist"
|
|
18
|
+
],
|
|
19
|
+
"publishConfig": {
|
|
20
|
+
"access": "public"
|
|
21
|
+
},
|
|
22
|
+
"dependencies": {
|
|
23
|
+
"yaml": "^2.7.0",
|
|
24
|
+
"zod": "^4.3.6",
|
|
25
|
+
"@h-ai/core": "0.1.0-alpha5"
|
|
26
|
+
},
|
|
27
|
+
"devDependencies": {
|
|
28
|
+
"@types/node": "^25.1.0",
|
|
29
|
+
"rimraf": "^6.0.1",
|
|
30
|
+
"tsup": "^8.3.5",
|
|
31
|
+
"typescript": "^5.7.2",
|
|
32
|
+
"vitest": "^4.0.18"
|
|
33
|
+
},
|
|
34
|
+
"scripts": {
|
|
35
|
+
"build": "tsup",
|
|
36
|
+
"dev": "tsup --watch",
|
|
37
|
+
"test": "vitest run",
|
|
38
|
+
"test:watch": "vitest",
|
|
39
|
+
"typecheck": "tsc --noEmit",
|
|
40
|
+
"lint": "eslint .",
|
|
41
|
+
"lint:fix": "eslint . --fix",
|
|
42
|
+
"clean": "rimraf dist .turbo"
|
|
43
|
+
}
|
|
44
|
+
}
|