@h-ai/deploy 0.1.0-alpha.66 → 0.1.0-alpha.67
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.en.md +97 -37
- package/README.ja.md +97 -37
- package/README.md +101 -78
- package/dist/index.d.ts +13 -3
- package/dist/index.js +547 -113
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/deploy-artifact.ts","../messages/en-US.json","../messages/zh-CN.json","../src/deploy-i18n.ts","../src/deploy-config.ts","../src/deploy-types.ts","../src/deploy-environment.ts","../src/deploy-credentials.ts","../src/deploy-functions.ts","../src/deploy-recovery.ts","../src/deploy-scanner.ts","../src/container/deploy-command.ts","../src/container/deploy-bundle.ts","../src/container/deploy-container-compose.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","../src/deploy-middleware.ts"],"names":["z","core","readFileSync","resolve","existsSync","process","join","parse","writeFileSync","ok","err","dirname","logger","basename","mkdirSync","chmodSync","stringify","randomBytes","deploy","parseEnv","relative","createHash","connectionUri"],"mappings":"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","file":"index.js","sourcesContent":["/** 已构建镜像的交付契约;构建器写入,部署器只校验和消费。 */\nimport { createHash } from 'node:crypto'\nimport { createReadStream, existsSync, lstatSync, readFileSync } from 'node:fs'\nimport { resolve } from 'node:path'\nimport { z } from 'zod'\n\n/** 镜像制品清单,例如 `{ version: 2, appVersion: '1.2.3', buildId: '1.2.3-build1', images: [{ name: 'app', file: 'app-1.2.3.tar', imageRef: 'localhost/demo:1.2.3-build1', sha256: '...' }] }`。 */\nexport const DeploymentArtifactSchema = z.object({\n /** 清单格式版本,与应用版本和部署环境无关。 */\n version: z.literal(2),\n /** 应用根 package.json 的版本,用于归档、Compose 与桌面交付;最长 80 字符。 */\n appVersion: z.string().max(80).regex(/^(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)(?:-[0-9a-z-]+(?:\\.[0-9a-z-]+)*)?(?:\\+[0-9a-z-]+(?:\\.[0-9a-z-]+)*)?$/i),\n /** 一次完整构建的标识,app/web 必须来自同一份清单。 */\n buildId: z.string().regex(/^[a-z0-9][\\w.+-]*$/i),\n /** API/独立应用和可选 Web 的镜像归档,至少包含一个 app。 */\n images: z.array(z.object({\n /** app 为服务或独立应用,web 为同源 API 代理的静态前端。 */\n name: z.enum(['app', 'web']),\n /** 相对于清单目录的 tar 文件名。 */\n file: z.string().regex(/^[\\w.+-]+\\.tar$/),\n /** 归档导入后可直接使用的不可变镜像引用。 */\n imageRef: z.string().regex(/^[a-z0-9][a-z0-9./:_-]+$/),\n /** tar 内容的 SHA-256,用于部署前校验。 */\n sha256: z.string().regex(/^[a-f0-9]{64}$/),\n /** 容器内部监听端口;服务器公开端口由部署选择。 */\n containerPort: z.number().int().min(1).max(65535).optional(),\n })).min(1).max(2).refine(images => images.filter(image => image.name === 'app').length === 1 && new Set(images.map(image => image.name)).size === images.length),\n}).refine(artifact => artifact.images.every(image => image.file === `${image.name}-${artifact.appVersion}.tar`))\n\n/** 构建器与部署器共享的镜像交付结构;参见 DeploymentArtifactSchema 示例。 */\nexport type DeploymentArtifact = z.infer<typeof DeploymentArtifactSchema>\n\n/**\n * 流式计算制品校验和,避免将大镜像一次性读入内存。\n * @example `const checksum = await artifactChecksum(\"/release/app-1.2.3.tar\")`\n */\nexport async function artifactChecksum(file: string): Promise<string> {\n const hash = createHash('sha256')\n for await (const chunk of createReadStream(file))\n hash.update(chunk)\n return hash.digest('hex')\n}\n\n/**\n * 校验完整构建产物;缺失、损坏或非法清单均抛错,由部署边界转换为 HaiResult。\n * @example `const artifact = await readDeploymentArtifact(\"/release/build-1\")`\n */\nexport async function readDeploymentArtifact(directory: string): Promise<DeploymentArtifact> {\n const artifact = DeploymentArtifactSchema.parse(JSON.parse(readFileSync(resolve(directory, 'manifest.json'), 'utf8')))\n for (const image of artifact.images) {\n const file = resolve(directory, image.file)\n if (!existsSync(file) || !lstatSync(file).isFile() || lstatSync(file).isSymbolicLink() || await artifactChecksum(file) !== image.sha256)\n throw new Error(`Invalid artifact: ${image.file}`)\n }\n return artifact\n}\n","{\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_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_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 \"deploy_invalidEnvironment\": \"Use letters, numbers, underscores or hyphens for the environment; local/example are reserved.\",\n \"deploy_environmentMissing\": \"Environment file missing: {path}. Create and configure it before deploying.\",\n \"deploy_environmentReadFailed\": \"Cannot read deployment environment files; check syntax and permissions.\",\n \"deploy_environmentWriteFailed\": \"Cannot save deployment configuration; check file syntax and permissions.\",\n \"deploy_multipleApplications\": \"Multiple service packages found; specify the application directory.\",\n \"deploy_purposeSqlite\": \"Local relational database persisted in a volume\",\n \"deploy_purposeDatabase\": \"Relational database service for business data\",\n \"deploy_purposeMemory\": \"Per-process memory cache; cleared on restart, no external service\",\n \"deploy_purposeLocal\": \"Local filesystem storage persisted in a volume\",\n \"deploy_purposeCache\": \"Shared cache, sessions and distributed locks\",\n \"deploy_purposeStorage\": \"S3-compatible object storage for uploaded files\",\n \"deploy_purposeVector\": \"Vector indexing and similarity search\",\n \"deploy_purposeDisabled\": \"LDAP login is disabled; no directory service is created\",\n \"deploy_purposeLdap\": \"Directory account authentication; the default directory has no business users\",\n \"deploy_purposeConsole\": \"Messages go to application logs without delivery\",\n \"deploy_purposeEmail\": \"Email/HTTP delivery; the default SMTP container only captures test messages\",\n \"deploy_purposeSms\": \"SMS through Aliyun credentials; requires an existing signature and quota\",\n \"deploy_webProxyInvalid\": \"The API prefix must be an absolute path containing only letters, numbers, underscores, hyphens and slashes.\",\n \"deploy_artifactInvalid\": \"Build artifacts are missing, corrupt, or could not be packaged. Run pnpm build --target docker at the project root and point --artifact-dir to a complete build directory.\",\n \"deploy_sshRequired\": \"Automatic deployment requires SSH settings. Use --bundle-only for manual transfer when the server is unreachable.\",\n \"deploy_bundleInstructions\": \"This bundle contains private configuration. Transfer it securely and restrict access.\\n1. Copy {file} to Linux using removable media, a private network or scp.\\n2. Install Docker/Podman with compose, tar, sha256sum and sh. Load middleware images using docker load/podman load with the exact tags below.\\n3. Create a private release directory: mkdir -p release && chmod 700 release\\n4. From the bundle directory run tar -xf {file} -C release\\n5. Run cd release && sh {start}. Set HAI_DEPLOY_PROVIDER_REMOTE_RUNTIME=docker or podman to select the runtime explicitly.\\n6. Check docker compose -f {compose} --env-file .env.runtime ps (or logs; use podman instead of docker for Podman), Web and /health after startup. Bundle generation does not perform server health checks.\\nRequired images (app/web are included; prepare middleware separately):\\n{images}\\nBuilt images can be reused across environments; this bundle contains configuration for the selected environment only.\",\n \"deploy_bundleMetadata\": \"Application version: {version}\\nBuild ID: {buildId}\\nCompose file: {compose}\",\n \"deploy_bundleOnlyContainer\": \"Compose bundle generation is supported only by docker-ssh.\"\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_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_remoteConnectFailed\": \"无法连接远程主机 {host}:{error}\",\n \"deploy_remoteRuntimeMissing\": \"远程主机缺少容器运行时或 compose:{runtime}\",\n \"deploy_imageTransferFailed\": \"镜像传输失败:{error}\",\n \"deploy_healthCheckFailed\": \"健康检查失败,应用未在 {url} 就绪\",\n \"deploy_invalidEnvironment\": \"环境名称仅允许字母、数字、下划线和连字符,且不能使用 local/example。\",\n \"deploy_environmentMissing\": \"缺少环境配置 {path};请先创建该文件并完成配置,再重新部署。\",\n \"deploy_environmentReadFailed\": \"部署环境文件读取失败,请检查文件格式与权限。\",\n \"deploy_environmentWriteFailed\": \"部署配置写入失败,请检查文件格式与权限。\",\n \"deploy_multipleApplications\": \"发现多个服务包,请指定要部署的应用目录。\",\n \"deploy_purposeSqlite\": \"本地文件关系数据库,使用持久化卷\",\n \"deploy_purposeDatabase\": \"独立关系数据库服务,保存业务数据\",\n \"deploy_purposeMemory\": \"单进程内存缓存,重启后清空,不创建外部服务\",\n \"deploy_purposeLocal\": \"本地文件存储,使用持久化卷\",\n \"deploy_purposeCache\": \"共享缓存、会话与分布式锁\",\n \"deploy_purposeStorage\": \"S3 兼容对象存储,保存上传文件\",\n \"deploy_purposeVector\": \"向量索引与相似度搜索\",\n \"deploy_purposeDisabled\": \"LDAP 登录未启用,不创建目录服务\",\n \"deploy_purposeLdap\": \"企业目录账号认证;默认目录不包含业务用户\",\n \"deploy_purposeConsole\": \"消息输出到应用日志,不实际投递\",\n \"deploy_purposeEmail\": \"邮件或 HTTP 通知投递;默认 SMTP 容器仅用于测试接收\",\n \"deploy_purposeSms\": \"通过阿里云凭证接入短信服务,需已有签名与额度\",\n \"deploy_webProxyInvalid\": \"API 前缀必须是仅含字母、数字、下划线、连字符和斜杠的绝对路径。\",\n \"deploy_artifactInvalid\": \"构建产物缺失、损坏或部署打包失败。请先在工程根运行 pnpm build --target docker,并检查 --artifact-dir 指向完整的构建目录。\",\n \"deploy_sshRequired\": \"自动部署需要 SSH 配置;无网络连接时使用 --bundle-only 生成部署包并手工搬运。\",\n \"deploy_bundleInstructions\": \"此包包含私有配置,请安全搬运并限制访问权限。\\n1. 将 {file} 复制到 Linux 服务器(U 盘、内网传输或 scp 均可)。\\n2. 准备 Docker/Podman、对应 compose 命令、tar、sha256sum 和 sh;将所需中间件镜像用 docker load/podman load 导入,镜像标签须与下列清单完全一致。\\n3. 新建仅部署用户可访问的目录:mkdir -p release && chmod 700 release\\n4. 在包所在目录执行 tar -xf {file} -C release\\n5. 执行 cd release && sh {start};可用 HAI_DEPLOY_PROVIDER_REMOTE_RUNTIME=docker 或 podman 显式选择运行时。\\n6. 启动后用 docker compose -f {compose} --env-file .env.runtime ps(或 logs;Podman 将 docker 换为 podman)检查状态并验证 Web、/health;仅打包不会执行服务器健康检查。\\n所需镜像(app/web 已含在包中,中间件需另行准备):\\n{images}\\n构建镜像可用于多环境;此包的环境配置仅用于本次所选环境。\",\n \"deploy_bundleMetadata\": \"应用版本:{version}\\n构建编号:{buildId}\\nCompose 文件:{compose}\",\n \"deploy_bundleOnlyContainer\": \"仅生成 Compose tar 只支持 docker-ssh。\"\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().min(1).max(65535).default(3000),\n /** 宿主机映射端口 */\n hostPort: z.number().int().min(1).max(65535),\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.optional(),\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 /** 部署环境文件模式;dev/test/prod 或自定义模式,禁止 local/example。 */\n environment: z.string().regex(/^[a-z0-9][\\w-]*$/i).refine(value => !['local', 'example'].includes(value.toLowerCase())).optional(),\n provider: ProviderConfigSchema,\n services: ServicesConfigSchema,\n /** Docker Compose 部署参数;构建配置位于项目 hai.build.json。 */\n container: z.object({\n /** 自建 S3 服务实现;协议仍为 storage.type=s3。 */\n s3Engine: z.enum(['rustfs', 'minio']).default('rustfs'),\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 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 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' | 'ldap'\n\n/** 每项中间件的处理方式;keep 不修改配置,也不开通服务。 */\nexport type MiddlewareMode = 'default' | 'custom' | 'keep'\n\n/** 扫描环境;例如 `{ environment: 'test', envDir: '/workspace/app' }`。 */\nexport interface DeployScanOptions {\n /** 环境文件模式。 */\n environment?: string\n /** 环境文件目录;默认自动定位到应用或 workspace 根。 */\n envDir?: string\n}\n\n/** 依赖对应的中间件;例如 IAM 的 LDAP 位于 `iam.ldap`,可处于 disabled 状态。 */\nexport interface MiddlewareRequirement {\n /** 中间件类别。 */\n service: ServiceType\n /** 生效后端标识。 */\n backend: string\n /** 检测来源(依赖包或配置名),用于解释为何需要此项。 */\n source: string\n /** 模块配置名。 */\n configName: string\n /** 模块配置内的路径;例如 LDAP 为 ['ldap']。 */\n configPath: string[]\n /** 约定变量前缀。 */\n envPrefix: string\n /** 生效连接配置,可能含凭据,仅用于输入默认值,不得原样输出日志。 */\n config: Record<string, unknown>\n}\n\n// ─── 扫描结果 ───\n\n/**\n * 应用扫描结果\n *\n * 由 scanner 分析应用目录后返回,描述应用的框架类型、依赖和部署需求。\n */\nexport interface ScanResult {\n /** 调用者指定的部署目录,对应 lockfile 中的一个 importer。 */\n appDir?: string\n /** 公共环境文件目录。 */\n envDir?: string\n /** 依赖与配置共同确定的中间件详情。 */\n middlewares?: MiddlewareRequirement[]\n /** 从运行依赖图识别的 Hai 模块;peer 和开发依赖不启用模块。 */\n haiModules?: string[]\n /** 应用名称(目录名称;可用 projectName 显式覆盖部署资源名)。 */\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\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' | 'packaged' | 'building' | 'error'\n /** Compose 部署 tar 的绝对路径;包含私有配置,应安全传输。 */\n bundlePath?: string\n /** 手工搬运和启动说明;仅打包不代表服务器已运行。 */\n instructions?: string\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 /** 部署环境标识;显式指定时必须存在 .env.<environment>。 */\n environment?: string\n /** 环境文件所在目录,默认自动定位。 */\n envDir?: string\n /** 按服务或变量前缀选择处理方式;如 HAI_REACH_PROVIDERS_1 可独立于另一邮件连接。 */\n serviceModes?: Partial<Record<string, MiddlewareMode>>\n /** 项目名称(默认使用明确指定的部署目录名称)。 */\n projectName?: string\n /** 是否跳过全部中间件配置与开通,默认 false;例如配置完备时设为 true。 */\n skipMiddleware?: boolean\n /** 已构建镜像目录;默认最近构建入口/锁文件目录下的 .hai/build/docker。 */\n artifactDir?: string\n /** 只生成部署 tar,不连接 SSH;仅 docker-ssh 支持。 */\n bundleOnly?: boolean\n /** 部署 tar 输出路径;默认 .hai/deploy/<环境>/bundle-<项目>-<部署ID>-<版本>.tar,自定义文件名自动补 -<版本>。 */\n output?: string\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, options?: DeployScanOptions) => Promise<HaiResult<ScanResult>>\n\n /**\n * 对所有已配置的 Provisioner 执行基础设施开通\n *\n * @param projectName - 用于资源命名的项目名\n * @returns 所有 Provisioner 的结果列表\n */\n provisionAll: (projectName: string, services?: ServiceType[]) => Promise<HaiResult<ProvisionResult[]>>\n\n /**\n * 部署已有构建产物(环境和中间件 → 打包 → 上传/启动);不会调用构建命令。\n *\n * @param appDir - 应用根目录路径\n * @param options - 部署选项\n */\n deployApp: (appDir: string, options?: DeployAppOptions) => Promise<HaiResult<DeployResult>>\n}\n","/** 部署环境的加载和持久化;公开环境文件不保存真实凭据。 */\nimport type { HaiResult } from '@h-ai/core'\nimport { chmodSync, existsSync, readFileSync, writeFileSync } from 'node:fs'\nimport { join, resolve } from 'node:path'\nimport process from 'node:process'\nimport { parseEnv } from 'node:util'\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\n/** 部署环境快照;例如 prod 的 targetValues 只来自 `.env.prod`,不包含基础/私有覆盖。 */\nexport interface DeploymentEnvironment {\n /** 文件模式(dev/test/prod 或其他合法模式名)。 */\n environment: string\n /** 环境文件的绝对目录。 */\n envDir: string\n /** 合并后的部署变量,可能含私有值,不得直接记录日志。 */\n values: Record<string, string>\n /** 仅目标环境文件显式声明的变量,用于判断能否“保持不变”。 */\n targetValues: Record<string, string>\n}\n\n/** 与 Core 一致,普通字符串如 CORS 的 `*` 不能因 YAML 标量解析失败而使配置加载失败。 */\nfunction environmentValue(value: string): unknown {\n try {\n return parse(value) ?? value\n }\n catch {\n return value\n }\n}\n\n/** 在已解析的 YAML 结构上处理覆盖,避免密码中的冒号、引号、井号变成 YAML 语法。 */\nfunction resolveConfig(value: unknown, prefix: string, env: Record<string, string | undefined>): unknown {\n if (env[prefix] !== undefined)\n return environmentValue(env[prefix])\n if (Array.isArray(value))\n return value.map((item, index) => resolveConfig(item, `${prefix}_${index}`, env))\n if (value && typeof value === 'object')\n return Object.fromEntries(Object.entries(value).map(([key, nested]) => [key, resolveConfig(nested, `${prefix}_${key.toUpperCase()}`, env)]))\n if (typeof value !== 'string')\n return value\n const resolved = value.replace(/\\$\\{([^:}]+)(?::([^}]*))?\\}/g, (_match, name: string, fallback?: string) => env[name] ?? fallback ?? '')\n return /^\\$\\{[^}]+\\}$/.test(value) ? environmentValue(resolved) : resolved\n}\n\n/**\n * 按部署环境解析配置;未选择的可选 Provisioner 缺少凭据时保留空值,选择完成后由 Schema 校验。\n * 不修改 core 缓存或进程变量,不在 YAML 文本上拼接凭据。\n * @param name - 模块配置名,例如 deploy/db/iam\n * @param path - YAML 文件绝对路径\n * @param values - 已加载的目标环境变量\n * @returns 配置对象;解析错误已脱敏\n * @example `loadDeploymentConfig('deploy', '/app/config/_deploy.yml', environment.values)`\n */\nexport function loadDeploymentConfig(name: string, path: string, values: Record<string, string | undefined>): HaiResult<Record<string, unknown>> {\n try {\n const config = resolveConfig(parse(readFileSync(path, 'utf8')), `HAI_${name.toUpperCase()}`, values)\n return ok(config && typeof config === 'object' && !Array.isArray(config) ? config as Record<string, unknown> : {})\n }\n catch {\n return err(HaiDeployError.CONFIG_ERROR, deployM('deploy_environmentReadFailed'))\n }\n}\n\n/**\n * 加载部署环境;指定环境文件缺失时返回错误并要求用户创建。\n * @param options - 模式、环境目录与是否强制存在目标文件\n * @param options.environment - dev/test/prod 或自定义模式\n * @param options.envDir - 环境文件所在目录\n * @param options.requireFile - 默认 true;扫描无显式环境时可只读取已有基础文件\n * @returns 环境快照,可能包含私有值,不得直接输出\n * @example `loadDeploymentEnvironment({ environment: 'prod', envDir: '.' })`\n */\nexport function loadDeploymentEnvironment(options: { environment: string, envDir: string, requireFile?: boolean }): HaiResult<DeploymentEnvironment> {\n const environment = options.environment === 'production' ? 'prod' : options.environment === 'development' ? 'dev' : options.environment\n if (!/^[a-z0-9][\\w-]*$/i.test(environment) || ['local', 'example'].includes(environment.toLowerCase()))\n return err(HaiDeployError.CONFIG_ERROR, deployM('deploy_invalidEnvironment'))\n const envDir = resolve(options.envDir)\n const target = join(envDir, `.env.${environment}`)\n if (options.requireFile !== false && !existsSync(target))\n return err(HaiDeployError.CONFIG_ERROR, deployM('deploy_environmentMissing', { params: { path: target } }))\n const loaded = core.config.loadEnvFiles({ mode: environment, envDir })\n if (!loaded.success)\n return loaded\n try {\n const values = { ...loaded.data }\n // 只传递应用配置和显式声明的运行变量,不上传整个调用者进程环境。\n for (const [name, value] of Object.entries(process.env)) {\n if (/^(?:HAI_|PUBLIC_|VITE_)/.test(name) && value !== undefined)\n values[name] = value\n }\n values.HAI_DEPLOY_ENVIRONMENT = environment\n values.HAI_CORE_ENV ??= environment === 'prod' ? 'production' : environment === 'dev' ? 'development' : environment === 'test' ? 'test' : 'staging'\n const targetValues: Record<string, string> = {}\n if (existsSync(target)) {\n for (const [name, value] of Object.entries(parseEnv(readFileSync(target, 'utf8')))) {\n if (value !== undefined)\n targetValues[name] = value\n }\n }\n return ok({ environment, envDir, values, targetValues })\n }\n catch {\n return err(HaiDeployError.CONFIG_ERROR, deployM('deploy_environmentReadFailed'))\n }\n}\n\n/** 判断值是否包含凭据;连接 URL 和 JSON 配置需要递归检查。 */\nfunction isSecret(name: string, value: string): boolean {\n if (/PASSWORD|SECRET|TOKEN|APIKEY|PRIVATEKEY|ACCESSKEY|AUTHORIZATION/i.test(name.replace(/[^a-z0-9]/gi, '')) || /(?:^|_)PASS$/i.test(name) || value.includes('PRIVATE KEY'))\n return true\n try {\n const url = new URL(value)\n if (url.username || url.password || [...url.searchParams.keys()].some(key => /password|secret|token|key|authorization/i.test(key)))\n return true\n }\n catch { /* 非 URL 配置继续按结构检查。 */ }\n try {\n const parsed: unknown = JSON.parse(value)\n if (parsed && typeof parsed === 'object')\n return Object.entries(parsed).some(([key, nested]) => isSecret(key, typeof nested === 'string' ? nested : JSON.stringify(nested)))\n }\n catch { /* 普通字符串无需 JSON 处理。 */ }\n return false\n}\n\n/** 将 JSON 中的凭据剥离,公共文件仍保留可审查的后端/连接结构。 */\nfunction publicConfig(value: unknown): unknown {\n if (Array.isArray(value))\n return value.map(publicConfig)\n if (value && typeof value === 'object')\n return Object.fromEntries(Object.entries(value).filter(([name, item]) => !isSecret(name, typeof item === 'string' ? item : '')).map(([name, item]) => [name, publicConfig(item)]))\n return value\n}\n\n/** dotenv 引号保留空格、注释符、美元符号和 JSON;非法换行键由调用边界拒绝。 */\nfunction quoteEnv(value: string): string {\n // JSON 内用 Unicode 转义表示单引号,dotenv 单引号即可无损保存复杂密码。\n try {\n const parsed: unknown = JSON.parse(value)\n if (parsed && typeof parsed === 'object')\n return `'${JSON.stringify(parsed).replaceAll('\\'', '\\\\u0027')}'`\n }\n catch { /* 标量按 dotenv 原生引号规则处理。 */ }\n if (!value.includes('\\''))\n return `'${value}'`\n if (!value.includes('\"'))\n return `\"${value}\"`\n if (!value.includes('`'))\n return `\\`${value}\\``\n if (!/[\\r\\n#]/.test(value))\n return value\n throw new Error('Unsupported dotenv value')\n}\n\n/** 按原有行更新键,保留注释与其他配置;更新私有文件时要求权限 600。 */\nfunction updateFile(path: string, values: Record<string, string>, privateFile: boolean): void {\n let content = existsSync(path) ? readFileSync(path, 'utf8') : '# Local private deployment configuration; do not commit.\\n'\n for (const [name, value] of Object.entries(values)) {\n if (!/^[A-Z][A-Z0-9_]*$/.test(name))\n throw new Error('Invalid environment variable name')\n const line = `${name}=${quoteEnv(value)}`\n // parseEnv 支持多行引号;替换时一起消费原值,避免遗留秘密片段。\n const pattern = new RegExp(`^(?:export\\\\s+)?${name}\\\\s*=\\\\s*(?:'[^']*'|\"[^\"]*\"|\\`[^\\`]*\\`|[^\\\\r\\\\n]*)[^\\\\r\\\\n]*`, 'gm')\n if (pattern.test(content))\n content = content.replace(pattern, () => line)\n else\n content = `${content.trimEnd()}\\n${line}\\n`\n }\n writeFileSync(path, content, { mode: privateFile ? 0o600 : 0o644 })\n if (privateFile)\n chmodSync(path, 0o600)\n}\n\n/** 明确修改的公共项必须清掉同名旧私有覆盖,避免重新加载后仍用旧后端。 */\nfunction removeOverrides(path: string, names: string[], privateFile = true): void {\n if (!existsSync(path) || names.length === 0)\n return\n let content = readFileSync(path, 'utf8')\n for (const name of names)\n content = content.replace(new RegExp(`^(?:export\\\\s+)?${name}\\\\s*=\\\\s*(?:'[^']*'|\"[^\"]*\"|\\`[^\\`]*\\`|[^\\\\r\\\\n]*)[^\\\\r\\\\n]*(?:\\\\r?\\\\n|$)`, 'gm'), '')\n writeFileSync(path, content, { mode: privateFile ? 0o600 : 0o644 })\n chmodSync(path, privateFile ? 0o600 : 0o644)\n}\n\n/**\n * 保存部署产生的变量:公共值写目标环境文件,凭据写 `.env.local`。\n * 返回实际写入的变量名,调用者只展示名称或脱敏值。\n * @param environment - 已加载的目标环境快照\n * @param values - 需要更新的变量;未提供的项保持原状\n * @param options - private 为 true 时所有值只保存在本机;适用于 SSH 地址、端口及密钥路径\n * @param options.private - 是否将全部值仅保存到 .env.local\n * @returns 已保存的变量名或脱敏错误\n * @example `saveDeploymentEnvironment(snapshot, { HAI_DB_TYPE: 'postgresql' })`\n * @example `saveDeploymentEnvironment(snapshot, { HAI_DEPLOY_PROVIDER: JSON.stringify(provider) }, { private: true })`\n */\nexport function saveDeploymentEnvironment(environment: DeploymentEnvironment, values: Record<string, string>, options: { private?: boolean } = {}): HaiResult<string[]> {\n try {\n const shared: Record<string, string> = {}\n const privateValues: Record<string, string> = {}\n for (const [name, value] of Object.entries(values)) {\n if (options.private) {\n privateValues[name] = value\n }\n else if (isSecret(name, value)) {\n privateValues[name] = value\n try {\n const parsed: unknown = JSON.parse(value)\n if (parsed && typeof parsed === 'object')\n shared[name] = JSON.stringify(publicConfig(parsed))\n }\n catch { /* 标量秘密仅写私有文件。 */ }\n }\n else {\n shared[name] = value\n }\n }\n if (Object.keys(shared).length)\n updateFile(join(environment.envDir, `.env.${environment.environment}`), shared, false)\n if (Object.keys(privateValues).length)\n updateFile(join(environment.envDir, '.env.local'), privateValues, true)\n removeOverrides(join(environment.envDir, `.env.${environment.environment}`), Object.keys(privateValues).filter(name => !(name in shared)), false)\n removeOverrides(join(environment.envDir, '.env.local'), Object.keys(shared).filter(name => !(name in privateValues)))\n if (Object.keys(privateValues).length) {\n const ignorePath = join(environment.envDir, '.gitignore')\n const ignore = existsSync(ignorePath) ? readFileSync(ignorePath, 'utf8') : ''\n if (!ignore.split(/\\r?\\n/).includes('.env.local'))\n writeFileSync(ignorePath, `${ignore.trimEnd()}\\n.env.local\\n.hai/deploy/\\n`)\n }\n return ok(Object.keys(values))\n }\n catch {\n return err(HaiDeployError.ENV_VAR_FAILED, deployM('deploy_environmentWriteFailed'))\n }\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_PROVIDER_TOKEN)\n * @param value - 凭证值\n *\n * @example\n * ```ts\n * saveCredential('HAI_DEPLOY_PROVIDER_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_PROVIDER_TOKEN: 'vel_xxx',\n * HAI_DEPLOY_SERVICES_DB_APIKEY: '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 { DeployAppOptions, ScanResult, ServiceType } from './deploy-types.js'\nimport { existsSync } from 'node:fs'\nimport { dirname, join, resolve } from 'node:path'\n\n/**\n * 定位构建目录;API workspace 的环境文件可在服务包,镜像仍位于工程根。\n * 只定位已约定的构建入口/锁文件,不从目录布局推断应用或中间件依赖。\n * @example `resolveArtifactDirectory('/workspace/demo/apps/demo-service')`\n */\nexport function resolveArtifactDirectory(appDir: string): string {\n let directory = resolve(appDir)\n while (true) {\n if (existsSync(join(directory, 'hai.build.json')) || existsSync(join(directory, 'pnpm-lock.yaml')))\n return join(directory, '.hai/build/docker')\n const parent = dirname(directory)\n if (parent === directory)\n return join(appDir, '.hai/build/docker')\n directory = parent\n }\n}\n\n/**\n * 判断同类连接中是否有默认配置项;具体变量前缀优先于服务类别,未指定时默认处理。\n * @example `usesDefaultMiddleware(scan, 'email', { serviceModes: { HAI_REACH_PROVIDERS_0: 'keep' } })`\n */\nexport function usesDefaultMiddleware(scan: ScanResult, service: ServiceType, options?: DeployAppOptions): boolean {\n const requirements = scan.middlewares?.filter(item => item.service === service) ?? []\n return requirements.length\n ? requirements.some(item => (options?.serviceModes?.[item.envPrefix] ?? options?.serviceModes?.[service] ?? 'default') === 'default')\n : (options?.serviceModes?.[service] ?? 'default') === 'default'\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 return join(appDir, '.vercel', 'output')\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","/** 应用、环境文件与中间件依赖扫描;不依赖 deploy.init(),不修改进程环境。 */\nimport type { HaiResult } from '@h-ai/core'\nimport type { DeployScanOptions, MiddlewareRequirement, ScanResult, ServiceType } from './deploy-types.js'\nimport { existsSync, readFileSync } from 'node:fs'\nimport { basename, dirname, join, relative, resolve } from 'node:path'\nimport { core, err, ok } from '@h-ai/core'\nimport { parseAllDocuments } from 'yaml'\nimport { loadDeploymentConfig, loadDeploymentEnvironment } from './deploy-environment.js'\nimport { deployM } from './deploy-i18n.js'\nimport { HaiDeployError } from './deploy-types.js'\n\nconst logger = core.logger.child({ module: 'deploy', scope: 'scanner' })\n\n/** 安全缩窄 YAML/JSON 对象;数组与 null 不作为配置对象。 */\nfunction record(value: unknown): Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value) ? value as Record<string, unknown> : {}\n}\n\n/**\n * 从当前 workspace 的 lockfile 导入项遍历运行依赖,排除 dev 和 peer 边。\n * pnpm 12 的工具链和应用分别存于多个 YAML 文档,只选择含目标 importer 的应用文档。\n * 缺少 lockfile 或目标 importer 时要求先安装,不读取 package.json 或推测应用布局。\n */\nfunction runtimeDependencies(appDir: string): { runtime: Set<string>, build: Set<string>, root: string } {\n let root = appDir\n while (!existsSync(join(root, 'pnpm-lock.yaml'))) {\n const parent = dirname(root)\n if (parent === root)\n throw new Error('Missing pnpm lockfile; run pnpm install')\n root = parent\n }\n const importerKey = relative(root, appDir).replaceAll('\\\\', '/') || '.'\n const documents = parseAllDocuments(readFileSync(join(root, 'pnpm-lock.yaml'), 'utf8'))\n if (documents.some(document => document.errors.length))\n throw new Error('Invalid pnpm lockfile')\n const lock = documents.map(document => record(document.toJS())).reverse().find(document => importerKey in record(document.importers))\n if (!lock)\n throw new Error('Application is missing from pnpm lockfile; run pnpm install')\n const importers = record(lock.importers)\n const packages = record(lock.packages)\n const snapshots = record(lock.snapshots)\n const names = new Set<string>()\n const visited = new Set<string>()\n const visit = (id: string, node: Record<string, unknown>, importer?: string): void => {\n if (visited.has(id))\n return\n visited.add(id)\n const metadata = importer === undefined ? record(packages[id.split('(')[0]]) : {}\n const peers = record(metadata.peerDependencies)\n for (const [name, reference] of Object.entries({ ...record(node.dependencies), ...record(node.optionalDependencies) })) {\n if (name in peers)\n continue\n const version = typeof reference === 'string' ? reference : record(reference).version\n if (typeof version !== 'string')\n throw new Error('Invalid pnpm dependency reference')\n if (version.startsWith('link:')) {\n if (importer === undefined)\n throw new Error('Invalid workspace dependency')\n const target = relative(root, resolve(root, importer, version.slice(5))).replaceAll('\\\\', '/') || '.'\n const linked = record(importers[target])\n if (!Object.keys(linked).length)\n throw new Error('Missing linked workspace importer')\n names.add(name)\n visit(`workspace:${target}`, linked, target)\n continue\n }\n // npm alias 的引用已包含真实包名,不能再拼接别名。\n const key = version in snapshots || version in packages ? version : `${name}@${version}`\n names.add(key.match(/^(@[^/]+\\/[^@]+|[^@]+)@/)?.[1] ?? name)\n const snapshot = record(snapshots[key] ?? packages[key])\n if (!Object.keys(snapshot).length && !(key in snapshots) && !(key in packages))\n throw new Error('Missing pnpm dependency snapshot')\n visit(key, snapshot)\n }\n }\n visit(`workspace:${importerKey}`, record(importers[importerKey]), importerKey)\n return { runtime: names, build: new Set([...names, ...Object.keys(record(record(importers[importerKey]).devDependencies))]), root }\n}\n\n/**\n * 扫描依赖和实际环境下的后端,不把 memory/local/console 强制改为外部服务。\n * 沿目标 importer 的运行依赖识别模块;LDAP 等可选能力再按实际配置识别。\n * @example `await scanApp('/workspace/packages/my-serv', { environment: 'prod' })`\n */\nexport async function scanApp(inputDir: string, options?: DeployScanOptions): Promise<HaiResult<ScanResult>> {\n try {\n const appDir = resolve(inputDir)\n const graph = runtimeDependencies(appDir)\n const envDir = options?.envDir ? resolve(options.envDir) : existsSync(join(appDir, '.env')) ? appDir : graph.root\n const loaded = loadDeploymentEnvironment({ environment: options?.environment ?? 'prod', envDir, requireFile: options?.environment !== undefined })\n if (!loaded.success)\n return loaded\n const env = loaded.data.values\n const deps = graph.runtime\n const configs: Record<string, Record<string, unknown>> = {}\n for (const [name, owner] of Object.entries({ db: 'reldb', cache: 'cache', storage: 'storage', vecdb: 'vecdb', iam: 'iam', reach: 'reach' })) {\n configs[name] = {}\n if (!deps.has(`@h-ai/${owner}`))\n continue\n const configFile = ['yml', 'yaml'].map(ext => join(appDir, 'config', `_${name}.${ext}`)).find(existsSync)\n const config = configFile ? loadDeploymentConfig(name, configFile, env) : undefined\n if (config && !config.success)\n return config\n configs[name] = config?.data ?? {}\n }\n const middlewares: MiddlewareRequirement[] = []\n const add = (service: ServiceType, backend: string, configName = service as string, configPath: string[] = [], config = configs[configName] ?? {}, source = `_${configName}.yml`) => {\n middlewares.push({ service, backend, source, configName, configPath, envPrefix: ['HAI', configName, ...configPath].map(part => part.toUpperCase()).join('_'), config })\n }\n const iam = deps.has('@h-ai/iam')\n if (deps.has('@h-ai/reldb'))\n add('db', String(configs.db.type ?? 'sqlite'), 'db', [], configs.db, '@h-ai/reldb / _db.yml')\n if (deps.has('@h-ai/cache'))\n add('cache', String(configs.cache.type ?? 'memory'), 'cache', [], configs.cache, '@h-ai/cache / _cache.yml')\n if (deps.has('@h-ai/storage'))\n add('storage', String(configs.storage.type ?? 'local'))\n if (deps.has('@h-ai/vecdb'))\n add('vecdb', String(configs.vecdb.type ?? 'lancedb'))\n if (iam) {\n const ldap = record(configs.iam.ldap)\n add('ldap', record(configs.iam.login).ldap === true ? 'ldap' : 'disabled', 'iam', ['ldap'], ldap, '@h-ai/iam (LDAP)')\n }\n const providers = configs.reach.providers\n if (deps.has('@h-ai/reach') && Array.isArray(providers)) {\n for (const [index, item] of providers.entries()) {\n const provider = record(item)\n const type = String(provider.type ?? '')\n const service = type === 'aliyun-sms' ? 'sms' : ['smtp', 'api', 'console'].includes(type) ? 'email' : undefined\n if (service)\n add(service, type, 'reach', ['providers', String(index)], provider, '@h-ai/reach')\n }\n }\n if (deps.has('@h-ai/reach') && !middlewares.some(item => item.configName === 'reach'))\n add('email', 'console', 'reach', ['providers', '0'], { name: 'email', type: 'console' }, '@h-ai/reach')\n const isSvelteKit = graph.build.has('@sveltejs/kit')\n const scan: ScanResult = {\n appDir,\n envDir,\n middlewares,\n haiModules: [...deps].filter(name => name.startsWith('@h-ai/')).sort(),\n appName: basename(appDir),\n isSvelteKit,\n adapterInstalled: graph.build.has('@sveltejs/adapter-vercel'),\n nodeAdapterInstalled: graph.build.has('@sveltejs/adapter-node'),\n requiredServices: [...new Set(middlewares.map(item => item.service))],\n serviceBackends: Object.fromEntries(middlewares.map(item => [item.service, item.backend])),\n }\n logger.info('Application scanned', { appName: scan.appName, haiModules: scan.haiModules, requiredServices: scan.requiredServices, serviceBackends: scan.serviceBackends })\n return ok(scan)\n }\n catch {\n // JSON/YAML 异常可能带有凭据行,不把原异常暴露到日志或用户错误。\n return err(HaiDeployError.SCAN_FAILED, deployM('deploy_scanFailed', { params: { error: 'Invalid or ambiguous application/configuration/lockfile; specify the application directory and run pnpm install' } }))\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 stdout: maskSecrets(stdout, options.secrets).slice(-3000),\n })\n finish(err(\n HaiDeployError.REMOTE_COMMAND_FAILED,\n deployM('deploy_commandFailed', {\n params: { command, error: maskSecrets(`${stdout.slice(-2500)}\\n${stderr || `exit ${exitCode}`}`, options.secrets).slice(-3000) },\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","/** Compose 交付包:部署器组合已有镜像和运行参数,不执行镜像构建。 */\nimport type { DeploymentArtifact } from '../deploy-artifact.js'\nimport { chmodSync, copyFileSync, mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs'\nimport { basename, dirname, join, resolve } from 'node:path'\nimport { parse } from 'yaml'\nimport { artifactChecksum } from '../deploy-artifact.js'\nimport { deployM } from '../deploy-i18n.js'\nimport { runCommand } from './deploy-command.js'\n\n/** shell 字面参数,路径和配置不能被解释为指令。 */\nexport function shellArgument(value: string): string {\n return `'${value.replaceAll('\\'', '\\'\"\\'\"\\'')}'`\n}\n\n/**\n * 生成 tar 和服务器启动说明;暂存目录无论成功失败都清理。\n * @example `await createDeploymentBundle({ directory, artifactDir, artifact, projectName, environment: 'prod', runtime: 'auto', coreEnv: 'production', output })`\n */\nexport async function createDeploymentBundle(options: {\n directory: string\n artifactDir: string\n artifact: DeploymentArtifact\n projectName: string\n environment: string\n runtime: 'auto' | 'podman' | 'docker'\n coreEnv: string\n output: string\n}): Promise<{ bundlePath: string, instructions: string, startName: string }> {\n const { directory, artifactDir, artifact, projectName, environment, runtime, coreEnv } = options\n const stem = basename(options.output).replace(/\\.tar$/i, '')\n const versionSuffix = `-${artifact.appVersion}`\n const output = resolve(dirname(options.output), `${stem.endsWith(versionSuffix) ? stem : `${stem}${versionSuffix}`}.tar`)\n const composeName = `docker-compose-${artifact.appVersion}.yml`\n mkdirSync(dirname(output), { recursive: true, mode: 0o700 })\n const staging = mkdtempSync(join(directory, '.bundle-'))\n chmodSync(staging, 0o700)\n const temporaryTar = `${output}.partial`\n const startName = `start-${environment}.sh`\n try {\n mkdirSync(join(staging, 'images'))\n for (const image of artifact.images)\n copyFileSync(join(artifactDir, image.file), join(staging, 'images', image.file))\n for (const file of [composeName, '.env.runtime', ...(artifact.images.some(image => image.name === 'web') ? ['web.conf'] : [])])\n copyFileSync(join(directory, file), join(staging, file))\n const compose = parse(readFileSync(join(directory, composeName), 'utf8')) as { services: Record<string, { image?: string }> }\n const images = [...new Set(Object.values(compose.services).flatMap(service => service.image ? [service.image] : []))]\n const start = `#!/bin/sh\nset -eu\ncd \"$(dirname \"$0\")\"\numask 077\nexport HAI_DEPLOY_ENVIRONMENT=${shellArgument(environment)}\nexport HAI_CORE_ENV=${shellArgument(coreEnv)}\nruntime=${shellArgument(runtime)}\nif [ -n \"\\${HAI_DEPLOY_PROVIDER_REMOTE_RUNTIME:-}\" ]; then runtime=\"$HAI_DEPLOY_PROVIDER_REMOTE_RUNTIME\"; fi\nif [ \"$runtime\" = auto ]; then\n if command -v podman >/dev/null 2>&1 && podman version >/dev/null 2>&1; then runtime=podman; else runtime=docker; fi\nfi\ncase \"$runtime\" in docker|podman) ;; *) echo 'HAI_DEPLOY_PROVIDER_REMOTE_RUNTIME must be docker or podman' >&2; exit 1;; esac\n\"$runtime\" version >/dev/null\n\"$runtime\" compose version >/dev/null\nsha256sum -c SHA256SUMS\nchmod 600 .env.runtime\n${artifact.images.map(image => `\"$runtime\" load -i ${shellArgument(`images/${image.file}`)}`).join('\\n')}\n# 离线服务器应先导入全部中间件镜像;禁止静默尝试联网。\nfor image in ${images.map(shellArgument).join(' ')}; do\n \"$runtime\" image inspect \"$image\" >/dev/null 2>&1 || { echo \"Missing image: $image. Load the matching image archive before retrying.\" >&2; exit 1; }\ndone\nexec \"$runtime\" compose -f ${shellArgument(composeName)} --env-file .env.runtime -p ${shellArgument(`hai-${projectName}`)} up -d\n`\n writeFileSync(join(directory, startName), start, { mode: 0o700 })\n writeFileSync(join(staging, startName), start, { mode: 0o700 })\n const instructions = deployM('deploy_bundleInstructions', { params: { file: basename(output), start: startName, images: images.join('\\n'), compose: composeName } })\n const metadata = deployM('deploy_bundleMetadata', { params: { version: artifact.appVersion, buildId: artifact.buildId, compose: composeName } })\n writeFileSync(join(staging, 'README.txt'), `${metadata}\\n${instructions}\\n`)\n copyFileSync(join(artifactDir, 'manifest.json'), join(staging, 'manifest.json'))\n const checksums: string[] = []\n for (const file of [composeName, 'manifest.json', '.env.runtime', startName, ...(artifact.images.some(image => image.name === 'web') ? ['web.conf'] : []), ...artifact.images.map(image => `images/${image.file}`)])\n checksums.push(`${await artifactChecksum(join(staging, file))} ${file}`)\n writeFileSync(join(staging, 'SHA256SUMS'), `${checksums.join('\\n')}\\n`)\n const tar = await runCommand('tar', ['-cf', temporaryTar, '-C', staging, '.'])\n if (!tar.success)\n throw new Error(tar.error.message)\n chmodSync(temporaryTar, 0o600)\n // tar 成功后再交付;失败不留下可被误用的半份包。\n const { renameSync } = await import('node:fs')\n renameSync(temporaryTar, output)\n return { bundlePath: output, instructions, startName }\n }\n finally {\n rmSync(staging, { recursive: true, force: true })\n rmSync(temporaryTar, { force: true })\n }\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 { DeployAppOptions, 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 { parse, stringify } from 'yaml'\nimport { usesDefaultMiddleware } from '../deploy-functions.js'\n\n/** sidecar 镜像固定版本,避免 `:latest` 漂移导致行为变化。 */\nconst IMAGES = {\n postgres: 'postgres:16-alpine',\n mysql: 'mysql:8.4',\n redis: 'redis:7-alpine',\n rustfs: 'ghcr.io/rustfs/rustfs:1.0.1',\n minio: 'ghcr.io/coollabsio/minio:RELEASE.2025-10-15T17-29-55Z',\n qdrant: 'qdrant/qdrant:v1.12.4',\n pgvector: 'pgvector/pgvector:pg17',\n chroma: 'chromadb/chroma:1.5.5',\n ldap: 'docker.io/osixia/openldap:1.5.0',\n smtp: 'axllent/mailpit:v1.27.4',\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 ldapPassword: 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/** S3 协议与服务实现分离;RustFS/MinIO 使用相同应用契约及幂等 bucket 初始化。 */\nfunction planS3Storage(plan: SidecarPlan, projectName: string, password: string, net: string[], engine: 'rustfs' | 'minio'): void {\n plan.services.push('storage')\n plan.dependsOn.push('storage')\n plan.composeServices.storage = {\n image: IMAGES[engine],\n container_name: `hai-${projectName}-storage`,\n restart: 'unless-stopped',\n ...(engine === 'minio' ? { command: ['server', '/data'] } : {}),\n env_file: ['.env.runtime'],\n volumes: [`${projectName}-storage-data:/data`],\n networks: net,\n }\n plan.composeServices['storage-init'] = {\n depends_on: ['storage'],\n env_file: ['.env.runtime'],\n entrypoint: [\n 'node',\n '--input-type=module',\n '-e',\n // 复用应用 @h-ai/storage 已依赖的 SDK;不额外拉取失效的 mc 镜像,不把密钥拼进命令。\n `import { S3Client, HeadBucketCommand, CreateBucketCommand } from '@aws-sdk/client-s3';\nconst config = JSON.parse(process.env.HAI_STORAGE);\nconst client = new S3Client({ endpoint: config.endpoint, region: config.region, forcePathStyle: config.forcePathStyle, credentials: { accessKeyId: config.accessKeyId, secretAccessKey: config.secretAccessKey } });\nlet ready = false;\nfor (let attempt = 0; attempt < 120; attempt++) {\n try {\n try { await client.send(new HeadBucketCommand({ Bucket: config.bucket })); }\n catch (error) {\n if (error.$$metadata?.httpStatusCode !== 404) throw error;\n await client.send(new CreateBucketCommand({ Bucket: config.bucket }));\n }\n ready = true; break;\n } catch { await new Promise(resolve => setTimeout(resolve, 1000)); }\n}\nclient.destroy();\nif (!ready) throw new Error('S3 bucket initialization failed');`,\n ],\n networks: net,\n }\n plan.volumes[`${projectName}-storage-data`] = null\n if (engine === 'rustfs') {\n Object.assign(plan.env, { RUSTFS_ACCESS_KEY: 'hai-storage', RUSTFS_SECRET_KEY: password, RUSTFS_ADDRESS: '0.0.0.0:9000', RUSTFS_VOLUMES: '/data', RUSTFS_CONSOLE_ENABLE: 'false' })\n }\n else {\n Object.assign(plan.env, { MINIO_ROOT_USER: 'hai-storage', MINIO_ROOT_PASSWORD: password })\n }\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-storage',\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 options?: DeployAppOptions,\n s3Engine: 'rustfs' | 'minio' = 'rustfs',\n): SidecarPlan {\n const plan: SidecarPlan = {\n services: [],\n composeServices: {},\n volumes: {},\n appVolumes: [],\n env: {},\n dependsOn: [],\n secrets: [],\n }\n // 全部保持不变时,连默认中间件凭据文件也不读取或创建。\n if (!scan.requiredServices.some(service => usesDefaultMiddleware(scan, service, options)))\n return plan\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 (!usesDefaultMiddleware(scan, service, options))\n continue\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 if ((backends.cache ?? 'redis') === 'redis')\n planRedisCache(plan, projectName, net)\n }\n else if (service === 'storage' && !provisionEnv.HAI_STORAGE) {\n if ((backends.storage ?? 's3') === 's3')\n planS3Storage(plan, projectName, secrets.storagePassword, net, s3Engine)\n else\n addAppDataVolume(plan, projectName)\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 else if (service === 'ldap' && backends.ldap === 'ldap' && !provisionEnv.HAI_IAM_LDAP) {\n const password = secrets.ldapPassword ?? secrets.dbPassword\n plan.services.push('ldap')\n plan.dependsOn.push('ldap')\n plan.composeServices.ldap = { image: IMAGES.ldap, restart: 'unless-stopped', env_file: ['.env.runtime'], networks: net, volumes: [`${projectName}-ldap-data:/var/lib/ldap`, `${projectName}-ldap-config:/etc/ldap/slapd.d`] }\n plan.volumes[`${projectName}-ldap-data`] = null\n plan.volumes[`${projectName}-ldap-config`] = null\n Object.assign(plan.env, { LDAP_DOMAIN: 'example.org', LDAP_ORGANISATION: 'HAI', LDAP_ADMIN_PASSWORD: password, LDAP_TLS: 'false', HAI_IAM_LOGIN_LDAP: 'true', HAI_IAM_LDAP: JSON.stringify({ url: 'ldap://ldap:389', bindDn: 'cn=admin,dc=example,dc=org', bindPassword: password, searchBase: 'dc=example,dc=org' }) })\n plan.secrets.push(password)\n }\n else if (service === 'email' && (scan.middlewares ? scan.middlewares.some(item => item.service === 'email' && item.backend === 'smtp' && (options?.serviceModes?.[item.envPrefix] ?? options?.serviceModes?.email ?? 'default') === 'default') : backends.email === 'smtp') && !provisionEnv.HAI_REACH_PROVIDERS) {\n plan.services.push('email')\n plan.dependsOn.push('email')\n plan.composeServices.email = { image: IMAGES.smtp, restart: 'unless-stopped', networks: net }\n const requirements = scan.middlewares?.filter(item => item.service === 'email' && item.backend === 'smtp' && ['default', undefined].includes(options?.serviceModes?.[item.envPrefix] ?? options?.serviceModes?.email))\n if (requirements?.length) {\n for (const requirement of requirements)\n plan.env[requirement.envPrefix] = JSON.stringify({ name: requirement.config.name ?? 'email', type: 'smtp', host: 'email', port: 1025, secure: false, from: 'noreply@example.com' })\n }\n else if (!scan.middlewares) {\n plan.env.HAI_REACH_PROVIDERS_0 = JSON.stringify({ name: 'email', type: 'smtp', host: 'email', port: 1025, secure: false, from: 'noreply@example.com' })\n }\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 options?: DeployAppOptions,\n appEnv: Record<string, string> = {},\n s3Engine: 'rustfs' | 'minio' = 'rustfs',\n): RuntimeEnvPlan {\n const sidecar = planSidecars(appDir, projectName, scan, provisionEnv, options, s3Engine)\n const env: Record<string, string> = {\n NODE_ENV: 'production',\n HOST: '0.0.0.0',\n PORT: String(containerPort),\n HAI_SERV_SERVER_HOST: '0.0.0.0',\n HAI_SERV_SERVER_PORT: String(containerPort),\n ...appEnv,\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.appVersion - 应用发布版本,例如 1.2.3;不改变持久化卷身份\n * @param options.hostPort - 宿主机映射端口\n * @param options.containerPort - 容器内端口\n * @param options.sidecar - sidecar 规划\n * @param options.previousCompose - 需要保留服务时读取的上次编排\n * @param options.serviceModes - 各中间件的处理选择\n * @param options.web - 同一编排中的 Web 镜像与监听端口,独立于私有应用环境\n * @param options.web.imageRef - Web 镜像引用\n * @param options.web.containerPort - Web 容器监听端口\n * @returns compose YAML 字符串\n */\nexport function generateComposeFile(options: {\n projectName: string\n appVersion: string\n imageRef: string\n hostPort: number\n containerPort: number\n sidecar: SidecarPlan\n /** 上次编排;保持不变的服务继续保留其定义与持久化卷。 */\n previousCompose?: string\n /** 各中间件的处理选择。 */\n serviceModes?: DeployAppOptions['serviceModes']\n /** Web 公开入口;私有运行环境仅属于 API 服务。 */\n web?: { imageRef: string, containerPort: number }\n}): string {\n const { projectName, imageRef, hostPort, containerPort, sidecar } = options\n\n const app: ComposeService = {\n image: imageRef,\n labels: { 'org.opencontainers.image.version': options.appVersion },\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 services: Record<string, ComposeService> = { app, ...sidecar.composeServices }\n if (options.web) {\n delete app.ports\n services.web = {\n image: options.web.imageRef,\n labels: { 'org.opencontainers.image.version': options.appVersion },\n container_name: `hai-${projectName}-web`,\n restart: 'unless-stopped',\n pull_policy: 'never',\n ports: [`${hostPort}:${options.web.containerPort}`],\n environment: { PUBLIC_API_BASE: '' },\n healthcheck: { test: ['CMD', 'wget', '-Y', 'off', '-q', '-O', '/dev/null', `http://127.0.0.1:${options.web.containerPort}/_hai/web-health`], interval: '30s', timeout: '5s', retries: 3 },\n volumes: ['./web.conf:/etc/nginx/conf.d/default.conf:ro'],\n depends_on: ['app'],\n networks: ['hai-app'],\n }\n }\n if (services['storage-init'])\n services['storage-init'] = { ...services['storage-init'], image: imageRef }\n const compose: Record<string, unknown> = {\n 'x-hai-version': options.appVersion,\n services,\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 if (options.previousCompose && options.serviceModes) {\n const previous = parse(options.previousCompose) as { services?: Record<string, ComposeService>, volumes?: Record<string, unknown> }\n for (const [service, mode] of Object.entries(options.serviceModes)) {\n if (mode !== 'keep')\n continue\n for (const name of [service, `${service}-init`]) {\n if (previous.services?.[name]) {\n services[name] = previous.services[name]\n app.depends_on = [...new Set([...(app.depends_on as string[] | undefined ?? []), service])]\n }\n }\n }\n const previousMounts = previous.services?.app?.volumes\n if (Array.isArray(previousMounts) && Object.values(options.serviceModes).includes('keep'))\n app.volumes = [...new Set([...(app.volumes as string[] | undefined ?? []), ...previousMounts])]\n // 保留已有卷定义不会创建/删除容器或清空卷,避免 keep 路径丢失挂载。\n compose.volumes = { ...previous.volumes, ...sidecar.volumes }\n }\n\n // S3 服务启动不等于桶已创建;初始化失败必须阻止应用启动,不能只依靠 HTTP 健康检查。\n if (services['storage-init']) {\n app.depends_on = {\n ...Object.fromEntries((app.depends_on as string[] | undefined ?? []).map(name => [name, { condition: 'service_started' }])),\n 'storage-init': { condition: 'service_completed_successfully' },\n }\n }\n\n for (const service of Object.values(services))\n service.pull_policy = 'never'\n return stringify(compose)\n}\n\n/**\n * 生成同源 Web/API 的 Nginx 配置,保留运行时配置及 SPA 页面刷新。\n * @param port - API 容器监听端口\n * @param apiPrefix - 应用实际 API 前缀,不允许向 Nginx 配置注入指令\n * @param webPort - Web 容器监听端口\n * @returns 仅含公开路由的 Nginx 配置\n * @example `generateWebProxyConfig(3000, '/api/v1')`\n */\nexport function generateWebProxyConfig(port: number, apiPrefix: string, webPort = 8080): string {\n if (!/^\\/[\\w/-]+$/.test(apiPrefix) || ![port, webPort].every(value => Number.isInteger(value) && value >= 1 && value <= 65535))\n throw new Error('Invalid web proxy target')\n return `server {\n listen ${webPort};\n server_name _;\n root /usr/share/nginx/html;\n location / {\n try_files $uri $uri/ /index.html;\n }\n location = /runtime-config.js {\n add_header Cache-Control \"no-store\";\n default_type application/javascript;\n return 200 'globalThis.__HAI_PUBLIC_CONFIG__={apiBase:globalThis.location.origin+\"${apiPrefix}\"};';\n }\n location = /_hai/web-health {\n access_log off;\n return 200 'ok';\n }\n location = /health {\n proxy_pass http://app:${port};\n proxy_set_header Host $http_host;\n }\n location ${apiPrefix.replace(/\\/$/, '')}/ {\n proxy_pass http://app:${port};\n proxy_http_version 1.1;\n proxy_set_header Host $http_host;\n proxy_set_header X-Forwarded-Proto $scheme;\n proxy_buffering off;\n }\n}\n`\n}\n\n/** 将环境变量对象序列化为 .env.runtime 内容(每行 KEY=VALUE)。 */\nexport function serializeEnvFile(env: Record<string, string>): string {\n return `${Object.entries(env)\n .map(([key, value]) => {\n let literal = value\n if (/[\\s#$'\"]/.test(value)) {\n if (value.startsWith('{') || value.startsWith('['))\n literal = `'${value.replaceAll('\\'', '\\\\u0027')}'`\n else if (!value.includes('\\''))\n literal = `'${value}'`\n else\n literal = JSON.stringify(value).replaceAll('$', '$$')\n }\n return `${key}=${literal}`\n })\n .join('\\n')}\\n`\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 的通用主机部署:消费已有镜像 → tar 打包 → 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 { DeployConfig, DockerSshProviderConfig } from '../deploy-config.js'\nimport type { DeployResult } from '../deploy-types.js'\nimport { randomBytes } from 'node:crypto'\nimport { chmodSync, existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs'\nimport { basename, join } from 'node:path'\nimport { parseEnv } from 'node:util'\nimport { core, err, ok } from '@h-ai/core'\nimport { createDeploymentBundle, shellArgument } from '../container/deploy-bundle.js'\nimport {\n buildRuntimeEnv,\n generateComposeFile,\n generateWebProxyConfig,\n serializeEnvFile,\n} from '../container/deploy-container-compose.js'\nimport { createSshExecutor } from '../container/deploy-ssh.js'\nimport { loadDeploymentConfig, loadDeploymentEnvironment, saveDeploymentEnvironment } from '../deploy-environment.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/** 睡眠指定毫秒。 */\nfunction sleep(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms))\n}\n\n/**\n * 创建 docker-ssh 部署 Provider。\n *\n * @param config - docker-ssh Provider 配置\n * @param container - Compose 中间件参数\n * @returns 容器部署 Provider 实例\n */\nexport function createDockerSshProvider(\n config: DockerSshProviderConfig,\n container?: DeployConfig['container'],\n): ContainerDeployProvider {\n const ssh = config.ssh ? createSshExecutor(config.ssh) : undefined\n const baseDir = config.remote.baseDir\n\n /** 探测远程容器运行时与 compose 可用性。 */\n async function detectRemoteRuntime(): Promise<HaiResult<ContainerRuntime>> {\n if (!ssh)\n return err(HaiDeployError.CONFIG_ERROR, deployM('deploy_sshRequired'))\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, appEnv, options } = context\n const deploymentId = makeDeploymentId()\n const hostPort = config.expose.hostPort\n const artifactDir = join(appDir, '.hai', 'deploy', options?.environment ?? 'prod')\n mkdirSync(artifactDir, { recursive: true, mode: 0o700 })\n chmodSync(artifactDir, 0o700)\n const artifact = context.artifact\n const resolvedBuildDir = context.artifactDir\n const images = artifact.images\n const web = images.find(image => image.name === 'web')\n const app = images.find(image => image.name === 'app')!\n const containerPort = app.containerPort ?? config.expose.containerPort\n const url = config.ssh ? `http://${config.ssh.host}:${hostPort}` : `http://SERVER_HOST:${hostPort}`\n\n // 先保存开通结果和 sidecar 凭据,传输失败后仍可检查与复用配置。\n const { env, sidecar } = buildRuntimeEnv(appDir, projectName, scan, provisionEnv, containerPort, options, appEnv, container?.s3Engine)\n let webProxy: string | undefined\n if (web) {\n // 路由取当前服务的真实配置,不扫描相邻应用或猜测 fullstack 布局。\n const server = loadDeploymentConfig('serv', join(appDir, 'config', '_serv.yml'), env)\n if (!server.success)\n return server\n const http = server.data.http as { apiPrefix?: string } | undefined\n const cors = server.data.cors as { origin?: string } | undefined\n const apiPrefix = http?.apiPrefix ?? '/api/v1'\n if (typeof apiPrefix !== 'string' || !/^\\/[\\w/-]+$/.test(apiPrefix))\n return err(HaiDeployError.CONFIG_ERROR, deployM('deploy_webProxyInvalid'))\n webProxy = generateWebProxyConfig(containerPort, apiPrefix, web.containerPort ?? 8080)\n // 每次从当前配置生成,避免上次运行环境里的父对象遮蔽新修改;保留明确 Origin。\n env.HAI_SERV = JSON.stringify({ ...server.data, cors: { ...cors, origin: (!cors?.origin || cors.origin === '*') && config.ssh ? url : cors?.origin ?? '*' } })\n }\n const envPath = join(artifactDir, '.env.runtime')\n const previousEnv = existsSync(envPath) ? parseEnv(readFileSync(envPath, 'utf8')) : {}\n Object.assign(env, { ...previousEnv, ...env })\n writeFileSync(envPath, serializeEnvFile(env), { mode: 0o600 })\n if (options?.environment) {\n const environment = loadDeploymentEnvironment({ environment: options.environment, envDir: options.envDir ?? scan.envDir ?? appDir })\n if (!environment.success)\n return environment\n const saved = saveDeploymentEnvironment(environment.data, { HAI_DEPLOY_ENVIRONMENT: environment.data.environment, HAI_CORE_ENV: environment.data.values.HAI_CORE_ENV, ...sidecar.env, ...provisionEnv })\n if (!saved.success)\n return saved\n }\n\n const composeName = `docker-compose-${artifact.appVersion}.yml`\n const latestPath = join(artifactDir, 'latest')\n const previousName = existsSync(latestPath) ? readFileSync(latestPath, 'utf8').trim() : ''\n const previousPath = /^[\\w.+-]+\\.yml$/.test(previousName) ? join(artifactDir, previousName) : undefined\n const composeContent = generateComposeFile({\n projectName,\n appVersion: artifact.appVersion,\n imageRef: app.imageRef,\n hostPort,\n containerPort,\n sidecar,\n web: web ? { imageRef: web.imageRef, containerPort: web.containerPort ?? 8080 } : undefined,\n serviceModes: options?.serviceModes,\n previousCompose: previousPath && existsSync(previousPath) ? readFileSync(previousPath, 'utf8') : undefined,\n })\n const composePath = join(artifactDir, composeName)\n writeFileSync(composePath, composeContent)\n if (webProxy)\n writeFileSync(join(artifactDir, 'web.conf'), webProxy)\n const bundle = await createDeploymentBundle({\n directory: artifactDir,\n artifactDir: resolvedBuildDir,\n artifact,\n projectName,\n environment: options?.environment ?? 'prod',\n runtime: config.remote.runtime,\n coreEnv: env.HAI_CORE_ENV ?? 'production',\n output: options?.output ?? join(artifactDir, `bundle-${projectName}-${deploymentId}-${artifact.appVersion}.tar`),\n })\n writeFileSync(latestPath, `${composeName}\\n`)\n if (options?.bundleOnly)\n return ok({ url: '', deploymentId, status: 'packaged', provider: 'docker-ssh', healthCheck: 'skipped', envVarsSet: Object.keys(env), ...bundle })\n if (!ssh)\n return err(HaiDeployError.CONFIG_ERROR, deployM('deploy_sshRequired'))\n const ping = await ssh.ping()\n if (!ping.success)\n return ping\n const remoteRuntime = await detectRemoteRuntime()\n if (!remoteRuntime.success)\n return remoteRuntime\n const remoteDir = `${baseDir}/${projectName}`\n const remoteTar = `${remoteDir}/${basename(bundle.bundlePath)}`\n const prepared = await ssh.exec(`mkdir -p -- ${shellArgument(remoteDir)} && chmod 700 -- ${shellArgument(remoteDir)}`)\n if (!prepared.success)\n return prepared\n const uploaded = await ssh.upload(bundle.bundlePath, remoteTar)\n if (!uploaded.success)\n return uploaded\n const started = await ssh.exec(\n `cd ${shellArgument(remoteDir)} && chmod 600 ${shellArgument(remoteTar)} && tar -xf ${shellArgument(remoteTar)} && HAI_DEPLOY_PROVIDER_REMOTE_RUNTIME=${shellArgument(remoteRuntime.data)} sh ${shellArgument(bundle.startName)}`,\n { timeoutMs: 300_000, secrets: sidecar.secrets },\n )\n if (!started.success)\n return started\n await ssh.exec(`rm -f -- ${shellArgument(remoteTar)} ${images.map(image => shellArgument(`${remoteDir}/images/${image.file}`)).join(' ')}`)\n\n // 在线部署完成后检查实际公开入口。\n logger.info('Running health check', { url })\n const healthy = await healthCheck(`${url}${!web && scan.isSvelteKit ? '/' : '/health'}`)\n && (!web || (await healthCheck(`${url}/_hai/web-health`) && 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 bundlePath: bundle.bundlePath,\n }\n logger.info('docker-ssh deployment complete', { url, deploymentId })\n return ok(result)\n }\n\n const deploySafely: ContainerDeployProvider['deploy'] = async (context) => {\n try {\n return await deploy(context)\n }\n catch (error) {\n logger.error('Deployment bundle failed', { error })\n return err(HaiDeployError.CONFIG_ERROR, deployM('deploy_artifactInvalid'), error)\n }\n }\n return { name: 'docker-ssh', deploy: deploySafely }\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 // 只接受 Build Output API v3;不把普通源码交给平台重新构建。\n const outputConfig = JSON.parse(readFileSync(join(outputDir, 'config.json'), 'utf8')) as { version?: unknown }\n if (outputConfig.version !== 3)\n return err(HaiDeployError.CONFIG_ERROR, deployM('deploy_artifactInvalid'))\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: `.vercel/output/${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?prebuilt=1',\n {\n method: 'POST',\n body: JSON.stringify({\n name: projectId,\n files,\n version: 2,\n project: projectId,\n projectSettings: { framework: null, buildCommand: '', installCommand: '' },\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 DeployScanOptions,\n ProvisionResult,\n ScanResult,\n ServiceType,\n} from './deploy-types.js'\nimport { existsSync, readFileSync } from 'node:fs'\nimport { join } from 'node:path'\nimport { core, err, ok } from '@h-ai/core'\nimport { readDeploymentArtifact } from './deploy-artifact.js'\nimport { DeployConfigSchema } from './deploy-config.js'\nimport {\n getCredentialsPath,\n loadCredentials,\n saveCredential,\n saveCredentials,\n} from './deploy-credentials.js'\nimport { loadDeploymentEnvironment, saveDeploymentEnvironment } from './deploy-environment.js'\nimport { resolveArtifactDirectory, resolveOutputDir, usesDefaultMiddleware } 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[], scan?: ScanResult, options?: DeployAppOptions): Record<string, string> {\n let env: Record<string, string> = {}\n const reachRequirements = scan?.middlewares?.filter(item => item.configName === 'reach') ?? []\n const reachProviders: unknown[] = reachRequirements.map(item => item.config)\n let hasReachOutput = false\n for (const prov of results) {\n if (prov.envVars.HAI_REACH_PROVIDERS) {\n hasReachOutput = true\n const supplied = JSON.parse(prov.envVars.HAI_REACH_PROVIDERS) as Record<string, unknown>[]\n for (const provider of supplied) {\n const targets = reachRequirements.filter((item) => {\n const mode = options?.serviceModes?.[item.envPrefix] ?? options?.serviceModes?.[item.service]\n return item.service === prov.serviceType && (!mode || mode === 'default')\n })\n if (targets.length) {\n for (const target of targets)\n reachProviders[reachRequirements.indexOf(target)] = { ...provider, name: target.config.name ?? provider.name }\n }\n else {\n reachProviders.push(provider)\n }\n }\n }\n env = { ...env, ...prov.envVars }\n }\n if (hasReachOutput)\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)\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, options?: DeployScanOptions): Promise<HaiResult<ScanResult>> {\n // scan 仅做本地文件分析,不依赖 Provider / Provisioner 初始化状态。\n logger.debug('Scanning application', { appDir })\n return scanApp(appDir, options)\n },\n\n async provisionAll(projectName: string, services?: ServiceType[]): 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 if (services && !services.includes(serviceType))\n continue\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, environment: options?.environment, projectName: options?.projectName })\n\n // 1. 扫描应用\n const scanOptions = { ...options, environment: options?.environment ?? currentConfig?.environment }\n const scanResult = await scanApp(appDir, scanOptions)\n if (!scanResult.success) {\n return err(scanResult.error)\n }\n const scan = scanResult.data\n appDir = scan.appDir ?? appDir\n const environment = loadDeploymentEnvironment({ environment: scanOptions.environment ?? 'prod', envDir: scan.envDir ?? appDir, requireFile: scanOptions.environment !== undefined })\n if (!environment.success)\n return environment\n const appEnv = Object.fromEntries(Object.entries(environment.data.values).filter(([key]) => !key.startsWith('HAI_CLI_') && (!key.startsWith('HAI_DEPLOY_') || key === 'HAI_DEPLOY_ENVIRONMENT')))\n const projectName = `${options?.projectName ?? scan.appName}${scanOptions.environment ? `-${environment.data.environment}` : ''}`\n options = {\n ...options,\n ...(scanOptions.environment ? { environment: environment.data.environment } : {}),\n ...(options?.skipMiddleware ? { serviceModes: Object.fromEntries(scan.requiredServices.map(service => [service, 'keep' as const])) } : {}),\n }\n\n // 容器 Provider(docker-ssh):走独立的容器部署编排\n if (currentContainerProvider) {\n return deployContainerApp(currentContainerProvider, appDir, scan, projectName, options, appEnv)\n }\n\n if (options?.bundleOnly)\n return err(HaiDeployError.CONFIG_ERROR, deployM('deploy_bundleOnlyContainer'))\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 if (!existsSync(resolveOutputDir(appDir, 'vercel')))\n return err(HaiDeployError.CONFIG_ERROR, deployM('deploy_artifactInvalid'))\n\n // 3. 开通基础设施\n let allEnvVars: Record<string, string> = appEnv\n const recovery: DeployRecoveryInfo = { projectName, stage: 'provision', resources: [] }\n if (!options?.skipMiddleware) {\n const provResults = await deploy.provisionAll(projectName, options?.serviceModes ? scan.requiredServices.filter(service => usesDefaultMiddleware(scan, service, options)) : undefined)\n if (!provResults.success) {\n return err(provResults.error)\n }\n recovery.resources = provResults.data.map(({ envVars: _envVars, ...resource }) => resource)\n allEnvVars = { ...allEnvVars, ...mergeProvisionEnv(provResults.data, scan, options) }\n if (options?.environment) {\n const saved = saveDeploymentEnvironment(environment.data, mergeProvisionEnv(provResults.data, scan, options))\n if (!saved.success)\n return recoveryFailure(saved.error, { ...recovery, stage: 'save-env' })\n }\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 // 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 appEnv: Record<string, string> = {},\n): Promise<HaiResult<DeployResult>> {\n const projectName = normalizeProjectName(rawProjectName)\n\n let artifact\n let artifactDir = options?.artifactDir ?? resolveArtifactDirectory(appDir)\n try {\n if (existsSync(join(artifactDir, 'latest'))) {\n const latest = readFileSync(join(artifactDir, 'latest'), 'utf8').trim()\n if (!/^[a-z0-9][\\w.+-]*$/i.test(latest))\n throw new Error('Invalid artifact pointer')\n artifactDir = join(artifactDir, latest)\n }\n artifact = await readDeploymentArtifact(artifactDir)\n }\n catch {\n return err(HaiDeployError.CONFIG_ERROR, deployM('deploy_artifactInvalid'))\n }\n if (!options?.bundleOnly && currentConfig?.provider.type === 'docker-ssh' && !currentConfig.provider.ssh)\n return err(HaiDeployError.CONFIG_ERROR, deployM('deploy_sshRequired'))\n\n let provisionEnv: Record<string, string> = {}\n if (!options?.skipMiddleware) {\n const provResults = await deploy.provisionAll(projectName, options?.serviceModes ? scan.requiredServices.filter(service => usesDefaultMiddleware(scan, service, options)) : undefined)\n if (!provResults.success) {\n return err(provResults.error)\n }\n provisionEnv = mergeProvisionEnv(provResults.data, scan, options)\n }\n\n return provider.deploy({ appDir, artifact, artifactDir, projectName, scan, provisionEnv, appEnv, options })\n}\n","/**\n * 部署中间件的后端与连接字段目录,供扫描、CLI 和容器规划共同使用。\n * 字段名与对应模块公开 Schema 保持一致,不把模块依赖等同于必须创建外部服务。\n * @module deploy-middleware\n */\nimport type { ServiceType } from './deploy-types.js'\nimport { deployM } from './deploy-i18n.js'\n\n/** 连接字段;例如 `{ name: 'port', defaultValue: '5432', kind: 'port' }`。 */\nexport interface MiddlewareField {\n /** 模块配置字段名,camelCase 不拆词。 */\n name: string\n /** 无现有配置时使用的提示默认值。 */\n defaultValue?: string\n /** 是否为连接所必需;可选项允许留空。 */\n required?: boolean\n /** 密码输入与私有环境文件写入标记。 */\n secret?: boolean\n /** 交互校验类型;端口范围为 1–65535。 */\n kind?: 'port' | 'boolean' | 'number' | 'url'\n /** 数值下限;未声明时为 0。 */\n minimum?: number\n /** 数值上限;例如 Redis db 为 15。 */\n maximum?: number\n}\n\n/** 后端目录项;例如 PostgreSQL 对应 `backend: 'postgresql'`。 */\nexport interface MiddlewareBackend {\n /** 模块 Schema 接受的后端标识。 */\n backend: string\n /** 可直接识别的产品名称。 */\n label: string\n /** 用途说明的 i18n 消息键。 */\n purpose: Parameters<typeof deployM>[0]\n /** 云自动开通器;缺失表示不能自动开通该云服务。 */\n provisioner?: 'neon' | 'upstash' | 'cloudflare-r2' | 'resend' | 'aliyun'\n /** 自定义连接需要逐项输入的字段。 */\n fields: MiddlewareField[]\n}\n\nconst field = (name: string, defaultValue?: string, kind?: MiddlewareField['kind'], secret = false): MiddlewareField => ({ name, defaultValue, kind, secret })\nconst required = (name: string, defaultValue?: string, kind?: MiddlewareField['kind']): MiddlewareField => ({ ...field(name, defaultValue, kind), required: true })\n\n/**\n * 所有可部署中间件的连接目录。\n * SQLite、memory、local 与 disabled 保留本地/禁用语义,不创建无关 sidecar。\n * @example `DEPLOY_MIDDLEWARE.db.map(item => item.label)` 返回数据库选择项。\n */\nexport const DEPLOY_MIDDLEWARE: Record<ServiceType, MiddlewareBackend[]> = {\n db: [\n { backend: 'sqlite', label: 'SQLite', purpose: 'deploy_purposeSqlite', fields: [required('database', './data/app.db')] },\n ...(['postgresql', 'mysql'] as const).map(backend => ({\n backend,\n label: backend === 'mysql' ? 'MySQL' : 'PostgreSQL',\n purpose: 'deploy_purposeDatabase' as const,\n provisioner: backend === 'postgresql' ? 'neon' as const : undefined,\n fields: [field('url', '', 'url', true), required('host', 'localhost'), required('port', backend === 'mysql' ? '3306' : '5432', 'port'), required('database', 'hai'), field('user', 'hai'), field('password', '', undefined, true), field('ssl', 'false')],\n })),\n ],\n cache: [\n { backend: 'memory', label: 'Memory', purpose: 'deploy_purposeMemory', fields: [] },\n { backend: 'redis', label: 'Redis', purpose: 'deploy_purposeCache', provisioner: 'upstash', fields: [field('url', '', 'url', true), required('host', 'localhost'), required('port', '6379', 'port'), field('password', '', undefined, true), { ...field('db', '0', 'number'), maximum: 15 }, field('tls', 'false', 'boolean'), field('keyPrefix'), field('connectTimeout', '10000', 'number'), field('commandTimeout', '5000', 'number')] },\n ],\n storage: [\n { backend: 'local', label: 'Local filesystem', purpose: 'deploy_purposeLocal', fields: [required('root', './data/storage')] },\n { backend: 's3', label: 'S3 / RustFS / MinIO / Cloudflare R2', purpose: 'deploy_purposeStorage', provisioner: 'cloudflare-r2', fields: [field('endpoint', '', 'url'), required('bucket', 'hai'), required('region', 'us-east-1'), required('accessKeyId'), { ...required('secretAccessKey'), secret: true }, field('forcePathStyle', 'true', 'boolean')] },\n ],\n vecdb: [\n { backend: 'lancedb', label: 'LanceDB', purpose: 'deploy_purposeLocal', fields: [required('path', './data/vectors')] },\n { backend: 'qdrant', label: 'Qdrant', purpose: 'deploy_purposeVector', fields: [required('url', 'http://localhost:6333', 'url'), field('apiKey', '', undefined, true)] },\n { backend: 'pgvector', label: 'PostgreSQL / pgvector', purpose: 'deploy_purposeVector', fields: [field('url', '', 'url', true), required('host', 'localhost'), required('port', '5432', 'port'), required('database', 'hai'), field('user', 'hai'), field('password', '', undefined, true)] },\n { backend: 'chroma', label: 'Chroma', purpose: 'deploy_purposeVector', fields: [required('url', 'http://localhost:8000', 'url')] },\n ],\n ldap: [\n { backend: 'disabled', label: 'Disabled', purpose: 'deploy_purposeDisabled', fields: [] },\n { backend: 'ldap', label: 'LDAP / OpenLDAP', purpose: 'deploy_purposeLdap', fields: [required('url', 'ldap://localhost:389', 'url'), required('bindDn', 'cn=admin,dc=example,dc=org'), { ...required('bindPassword'), secret: true }, required('searchBase', 'dc=example,dc=org'), field('searchFilter', '(uid={{username}})'), field('usernameAttribute', 'uid'), field('emailAttribute', 'mail'), field('displayNameAttribute', 'cn'), field('useTls', 'false', 'boolean'), { ...field('connectTimeout', '5000', 'number'), minimum: 1000 }] },\n ],\n email: [\n { backend: 'console', label: 'Console', purpose: 'deploy_purposeConsole', fields: [] },\n { backend: 'smtp', label: 'SMTP', purpose: 'deploy_purposeEmail', provisioner: 'resend', fields: [required('host', 'localhost'), required('port', '465', 'port'), field('secure', 'true', 'boolean'), field('user'), field('pass', '', undefined, true), required('from', 'noreply@example.com')] },\n { backend: 'api', label: 'HTTP notification API', purpose: 'deploy_purposeEmail', fields: [required('url', '', 'url'), field('method', 'POST'), field('headers'), field('timeout', '10000', 'number')] },\n ],\n sms: [\n { backend: 'aliyun-sms', label: 'Aliyun SMS', purpose: 'deploy_purposeSms', provisioner: 'aliyun', fields: [required('accessKeyId'), { ...required('accessKeySecret'), secret: true }, required('signName'), field('endpoint', 'dysmsapi.aliyuncs.com')] },\n ],\n}\n\n/**\n * 返回当前语言的后端用途说明。\n * @example `describeMiddlewareBackend(DEPLOY_MIDDLEWARE.db[0])`\n */\nexport function describeMiddlewareBackend(backend: MiddlewareBackend): string {\n return deployM(backend.purpose)\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/deploy-artifact.ts","../messages/en-US.json","../messages/zh-CN.json","../src/deploy-i18n.ts","../src/deploy-config.ts","../src/deploy-types.ts","../src/deploy-environment.ts","../src/deploy-credentials.ts","../src/deploy-functions.ts","../src/deploy-recovery.ts","../src/deploy-scanner.ts","../src/container/deploy-command.ts","../src/container/deploy-scripts.ts","../src/container/deploy-bundle.ts","../src/container/deploy-container-compose.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","../src/deploy-middleware.ts"],"names":["z","core","readFileSync","resolve","existsSync","process","join","parse","writeFileSync","ok","err","dirname","logger","basename","mkdirSync","chmodSync","stringify","randomBytes","deploy","relative","createHash","connectionUri"],"mappings":"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","file":"index.js","sourcesContent":["/** 已构建镜像的交付契约;构建器写入,部署器只校验和消费。 */\nimport { createHash } from 'node:crypto'\nimport { createReadStream, existsSync, lstatSync, readFileSync } from 'node:fs'\nimport { resolve } from 'node:path'\nimport { z } from 'zod'\n\n/** 镜像制品清单,例如 `{ version: 3, appVersion: '1.2.3', buildId: '1.2.3-build1', partial: false, hasWeb: false, images: [...] }`。 */\nexport const DeploymentArtifactSchema = z.object({\n /** 清单格式版本,与应用版本和部署环境无关。 */\n version: z.literal(3),\n /** 应用根 package.json 的版本,用于归档、Compose 与桌面交付;最长 80 字符。 */\n appVersion: z.string().max(80).regex(/^(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)(?:-[0-9a-z-]+(?:\\.[0-9a-z-]+)*)?(?:\\+[0-9a-z-]+(?:\\.[0-9a-z-]+)*)?$/i),\n /** 本次构建标识;同一应用版本允许重复构建。 */\n buildId: z.string().regex(/^[a-z0-9][\\w.+-]*$/i),\n /** 只包含所选镜像的构建不能用于首次安装。 */\n partial: z.boolean().default(false),\n /** API 单独构建时仍保留工程的 Web 拓扑。 */\n hasWeb: z.boolean().default(false),\n /** 工程显式配置的应用端口,部分构建未包含 app 镜像时仍保留;缺省由部署配置决定。 */\n appContainerPort: z.number().int().min(1).max(65535).optional(),\n /** 工程显式配置的 Web 端口,部分构建未包含 web 镜像时仍保留;缺省使用部署默认值。 */\n webContainerPort: z.number().int().min(1).max(65535).optional(),\n /** 本次构建选择的镜像归档。 */\n images: z.array(z.object({\n /** app 为服务或独立应用,web 为同源 API 代理的静态前端。 */\n name: z.enum(['app', 'web']),\n /** 相对于清单目录的 tar 文件名。 */\n file: z.string().regex(/^[\\w.+-]+\\.tar$/),\n /** 归档导入后可直接使用的不可变镜像引用。 */\n imageRef: z.string().regex(/^[a-z0-9][a-z0-9./:_-]*:[a-z0-9_][a-z0-9_.-]*$/).refine(value => !value.endsWith(':latest')),\n /** tar 内容的 SHA-256,用于部署前校验。 */\n sha256: z.string().regex(/^[a-f0-9]{64}$/),\n /** 容器内部监听端口;服务器公开端口由部署选择。 */\n containerPort: z.number().int().min(1).max(65535).optional(),\n })).min(1).max(2).refine(images => new Set(images.map(image => image.name)).size === images.length),\n}).refine(artifact => artifact.images.every(image => image.file === `${image.name}-${artifact.appVersion}.tar`)).refine(artifact => artifact.partial || artifact.images.some(image => image.name === 'app')).refine(artifact => artifact.partial || !artifact.hasWeb || artifact.images.some(image => image.name === 'web'))\n\n/** 构建器与部署器共享的镜像交付结构;参见 DeploymentArtifactSchema 示例。 */\nexport type DeploymentArtifact = z.infer<typeof DeploymentArtifactSchema>\n\n/**\n * 流式计算制品校验和,避免将大镜像一次性读入内存。\n * @example `const checksum = await artifactChecksum(\"/release/app-1.2.3.tar\")`\n */\nexport async function artifactChecksum(file: string): Promise<string> {\n const hash = createHash('sha256')\n for await (const chunk of createReadStream(file))\n hash.update(chunk)\n return hash.digest('hex')\n}\n\n/**\n * 校验完整构建产物;缺失、损坏或非法清单均抛错,由部署边界转换为 HaiResult。\n * @example `const artifact = await readDeploymentArtifact(\"/release/build-1\")`\n */\nexport async function readDeploymentArtifact(directory: string): Promise<DeploymentArtifact> {\n const artifact = DeploymentArtifactSchema.parse(JSON.parse(readFileSync(resolve(directory, 'manifest.json'), 'utf8')))\n for (const image of artifact.images) {\n const file = resolve(directory, image.file)\n if (!existsSync(file) || !lstatSync(file).isFile() || lstatSync(file).isSymbolicLink() || await artifactChecksum(file) !== image.sha256)\n throw new Error(`Invalid artifact: ${image.file}`)\n }\n return artifact\n}\n","{\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_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_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 \"deploy_invalidEnvironment\": \"Use letters, numbers, underscores or hyphens for the environment; local/example are reserved.\",\n \"deploy_environmentMissing\": \"Environment file missing: {path}. Create and configure it before deploying.\",\n \"deploy_environmentReadFailed\": \"Cannot read deployment environment files; check syntax and permissions.\",\n \"deploy_environmentWriteFailed\": \"Cannot save deployment configuration; check file syntax and permissions.\",\n \"deploy_multipleApplications\": \"Multiple service packages found; specify the application directory.\",\n \"deploy_purposeSqlite\": \"Local relational database persisted in a volume\",\n \"deploy_purposeDatabase\": \"Relational database service for business data\",\n \"deploy_purposeMemory\": \"Per-process memory cache; cleared on restart, no external service\",\n \"deploy_purposeLocal\": \"Local filesystem storage persisted in a volume\",\n \"deploy_purposeCache\": \"Shared cache, sessions and distributed locks\",\n \"deploy_purposeStorage\": \"S3-compatible object storage for uploaded files\",\n \"deploy_purposeVector\": \"Vector indexing and similarity search\",\n \"deploy_purposeDisabled\": \"LDAP login is disabled; no directory service is created\",\n \"deploy_purposeLdap\": \"Directory account authentication; the default directory has no business users\",\n \"deploy_purposeConsole\": \"Messages go to application logs without delivery\",\n \"deploy_purposeEmail\": \"Email/HTTP delivery; the default SMTP container only captures test messages\",\n \"deploy_purposeSms\": \"SMS through Aliyun credentials; requires an existing signature and quota\",\n \"deploy_webProxyInvalid\": \"The API prefix must be an absolute path containing only letters, numbers, underscores, hyphens and slashes.\",\n \"deploy_artifactInvalid\": \"Image artifacts are missing or invalid. Run pnpm build --target docker, select valid --artifact-dir, or use pnpm run deploy --build.\",\n \"deploy_sshRequired\": \"Automatic deployment requires SSH settings. Use --bundle-only for manual transfer when the server is unreachable.\",\n \"deploy_bundleInstructions\": \"Bundle: {file}\\nIncludes all images needed by selected services, including self-hosted middleware.\\nWith SSH access, run deploy.ps1 (Windows) or deploy.sh (Linux/macOS) from the adjacent deployment directory.\\nFor isolated servers, copy and extract the tar into a separate directory, then run sh apply.sh /opt/hai/apps/project-environment.\\nLinux requires Docker/Podman, Compose, sh, tar, sha256sum, awk, curl and filesystem/container permissions.\\nPartial updates require a successful full installation with matching ports/layout. Steps return nonzero on failure; result-DEPLOYMENT_ID.json records the outcome.\\nThe bundle contains private runtime configuration; transfer it securely.\\nIncluded images:\\n{images}\",\n \"deploy_bundleMetadata\": \"Application version: {version}\\nBuild ID: {buildId}\\nCompose file: {compose}\",\n \"deploy_bundleOnlyContainer\": \"Compose bundle generation is supported only by docker-ssh.\",\n \"deploy_selectedContainerOnly\": \"Selected-service deployment requires a docker-ssh Compose destination.\",\n \"deploy_selectionInvalid\": \"Cannot deploy {service}: check the service name and build its image first.\",\n \"deploy_imageVersionRequired\": \"Specify an image version; latest is not allowed: {image}\",\n \"deploy_bundleRuntimeRequired\": \"Start local Podman/Docker to export middleware images, or prepare this complete offline bundle on the build machine.\",\n \"deploy_bundleFailed\": \"Package preparation or deployment failed: {reason}\",\n \"deploy_configFileInvalid\": \"Invalid YAML in {path}, line {line}. Check indentation, colons and quotes.\",\n \"deploy_configFileUnreadable\": \"Cannot read configuration file {path}. Check its path and permissions.\",\n \"deploy_bundleNameInvalid\": \"Bundle filenames may contain letters, numbers, dots, plus signs, hyphens and underscores; parent directories may contain spaces.\",\n \"deploy_secretsInvalid\": \"Middleware credentials are damaged or incomplete: {path}. Restore a backup; passwords are not regenerated because existing data may become inaccessible.\",\n \"deploy_storageArtifactRequired\": \"Storage initialization requires the application image. Select a complete artifact containing app with --artifact-dir, or run pnpm build --target docker --images app first.\"\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_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_remoteConnectFailed\": \"无法连接远程主机 {host}:{error}\",\n \"deploy_remoteRuntimeMissing\": \"远程主机缺少容器运行时或 compose:{runtime}\",\n \"deploy_imageTransferFailed\": \"镜像传输失败:{error}\",\n \"deploy_healthCheckFailed\": \"健康检查失败,应用未在 {url} 就绪\",\n \"deploy_invalidEnvironment\": \"环境名称仅允许字母、数字、下划线和连字符,且不能使用 local/example。\",\n \"deploy_environmentMissing\": \"缺少环境配置 {path};请先创建该文件并完成配置,再重新部署。\",\n \"deploy_environmentReadFailed\": \"部署环境文件读取失败,请检查文件格式与权限。\",\n \"deploy_environmentWriteFailed\": \"部署配置写入失败,请检查文件格式与权限。\",\n \"deploy_multipleApplications\": \"发现多个服务包,请指定要部署的应用目录。\",\n \"deploy_purposeSqlite\": \"本地文件关系数据库,使用持久化卷\",\n \"deploy_purposeDatabase\": \"独立关系数据库服务,保存业务数据\",\n \"deploy_purposeMemory\": \"单进程内存缓存,重启后清空,不创建外部服务\",\n \"deploy_purposeLocal\": \"本地文件存储,使用持久化卷\",\n \"deploy_purposeCache\": \"共享缓存、会话与分布式锁\",\n \"deploy_purposeStorage\": \"S3 兼容对象存储,保存上传文件\",\n \"deploy_purposeVector\": \"向量索引与相似度搜索\",\n \"deploy_purposeDisabled\": \"LDAP 登录未启用,不创建目录服务\",\n \"deploy_purposeLdap\": \"企业目录账号认证;默认目录不包含业务用户\",\n \"deploy_purposeConsole\": \"消息输出到应用日志,不实际投递\",\n \"deploy_purposeEmail\": \"邮件或 HTTP 通知投递;默认 SMTP 容器仅用于测试接收\",\n \"deploy_purposeSms\": \"通过阿里云凭证接入短信服务,需已有签名与额度\",\n \"deploy_webProxyInvalid\": \"API 前缀必须是仅含字母、数字、下划线、连字符和斜杠的绝对路径。\",\n \"deploy_artifactInvalid\": \"镜像产物缺失或校验失败。请先执行 pnpm build --target docker,或用 --artifact-dir 指定有效产物;也可用 pnpm run deploy --build 一次完成。\",\n \"deploy_sshRequired\": \"自动部署需要 SSH 配置;无网络连接时使用 --bundle-only 生成部署包并手工搬运。\",\n \"deploy_bundleInstructions\": \"部署包:{file}\\n包中已包含本次选择服务需要的镜像,包括自建中间件。\\n有 SSH 连接时,在旁边的部署目录运行 deploy.ps1(Windows)或 deploy.sh(Linux/macOS)。\\n完全隔离时,复制 tar 到 Linux 服务器,在独立目录解包,再执行 sh apply.sh /opt/hai/apps/项目环境。\\n服务器需要 Docker/Podman、Compose、sh、tar、sha256sum、awk 和 curl,以及目录、容器运行权限。\\n部分更新要求服务器已有成功的完整部署,端口及应用布局保持一致。每步失败会返回非零退出码;结果记录在部署目录 result-部署ID.json。\\n包包含私有运行配置,请安全传输。\\n所含镜像:\\n{images}\",\n \"deploy_bundleMetadata\": \"应用版本:{version}\\n构建编号:{buildId}\\nCompose 文件:{compose}\",\n \"deploy_bundleOnlyContainer\": \"仅生成 Compose tar 只支持 docker-ssh。\",\n \"deploy_selectedContainerOnly\": \"按服务局部部署仅适用于 docker-ssh Compose 目标。\",\n \"deploy_selectionInvalid\": \"无法部署服务 {service}:请检查服务名称,并先构建对应镜像。\",\n \"deploy_storageArtifactRequired\": \"存储初始化需要应用镜像。请用 --artifact-dir 选择含 app 镜像的完整制品,或先执行 pnpm build --target docker --images app。\",\n \"deploy_imageVersionRequired\": \"镜像必须指定版本,不能使用 latest:{image}\",\n \"deploy_bundleRuntimeRequired\": \"完整离线包需要导出中间件镜像。请启动本地 Podman/Docker,或在构建机打包。\",\n \"deploy_bundleFailed\": \"交付准备或部署失败:{reason}\",\n \"deploy_configFileInvalid\": \"配置文件 {path} 第 {line} 行格式有误。请检查缩进、冒号和引号后重试。\",\n \"deploy_configFileUnreadable\": \"无法读取配置文件 {path},请检查文件路径与读取权限。\",\n \"deploy_bundleNameInvalid\": \"部署包文件名只支持字母、数字、点、加号、短横线和下划线;所在目录可以包含空格。\",\n \"deploy_secretsInvalid\": \"中间件凭据文件损坏或缺少字段:{path}。请从备份恢复;不会自动更换密码,以免已有数据无法访问。\"\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().regex(/^[a-z0-9][a-z0-9.:-]*$/i),\n /** SSH 端口 */\n port: z.number().int().min(1).max(65535).default(22),\n /** SSH 用户名 */\n username: z.string().regex(/^[a-z_][\\w-]*$/i),\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().min(1).max(65535).default(3000),\n /** 宿主机映射端口 */\n hostPort: z.number().int().min(1).max(65535),\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.optional(),\n /** 远程主机运行参数 */\n remote: z.object({\n /** 远程应用根目录 */\n baseDir: z.string().regex(/^\\/[\\w/. -]+$/).refine(value => !value.split('/').includes('..')).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 /** 部署环境文件模式;dev/test/prod 或自定义模式,禁止 local/example。 */\n environment: z.string().regex(/^[a-z0-9][\\w-]*$/i).refine(value => !['local', 'example'].includes(value.toLowerCase())).optional(),\n provider: ProviderConfigSchema,\n services: ServicesConfigSchema,\n /** Docker Compose 部署参数;构建配置位于项目 hai.build.json。 */\n container: z.object({\n /** 自建 S3 服务实现;协议仍为 storage.type=s3。 */\n s3Engine: z.enum(['rustfs', 'minio']).default('rustfs'),\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 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 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' | 'ldap'\n\n/** 每项中间件的处理方式;keep 不修改配置,也不开通服务。 */\nexport type MiddlewareMode = 'default' | 'custom' | 'keep'\n\n/** 扫描环境;例如 `{ environment: 'test', envDir: '/workspace/app' }`。 */\nexport interface DeployScanOptions {\n /** 环境文件模式。 */\n environment?: string\n /** 环境文件目录;默认自动定位到应用或 workspace 根。 */\n envDir?: string\n}\n\n/** 依赖对应的中间件;例如 IAM 的 LDAP 位于 `iam.ldap`,可处于 disabled 状态。 */\nexport interface MiddlewareRequirement {\n /** 中间件类别。 */\n service: ServiceType\n /** 生效后端标识。 */\n backend: string\n /** 检测来源(依赖包或配置名),用于解释为何需要此项。 */\n source: string\n /** 模块配置名。 */\n configName: string\n /** 模块配置内的路径;例如 LDAP 为 ['ldap']。 */\n configPath: string[]\n /** 约定变量前缀。 */\n envPrefix: string\n /** 生效连接配置,可能含凭据,仅用于输入默认值,不得原样输出日志。 */\n config: Record<string, unknown>\n}\n\n// ─── 扫描结果 ───\n\n/**\n * 应用扫描结果\n *\n * 由 scanner 分析应用目录后返回,描述应用的框架类型、依赖和部署需求。\n */\nexport interface ScanResult {\n /** 调用者指定的部署目录,对应 lockfile 中的一个 importer。 */\n appDir?: string\n /** 公共环境文件目录。 */\n envDir?: string\n /** 依赖与配置共同确定的中间件详情。 */\n middlewares?: MiddlewareRequirement[]\n /** 从运行依赖图识别的 Hai 模块;peer 和开发依赖不启用模块。 */\n haiModules?: string[]\n /** 应用名称(目录名称;可用 projectName 显式覆盖部署资源名)。 */\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\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' | 'packaged' | 'building' | 'error'\n /** Compose 部署 tar 的绝对路径;包含私有配置,应安全传输。 */\n bundlePath?: string\n /** 手工搬运和启动说明;仅打包不代表服务器已运行。 */\n instructions?: string\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 /** 接收实际执行阶段,用于终端进度显示;不包含凭据或配置原文。 */\n onProgress?: (stage: 'packaging' | 'preflight' | 'images' | 'dependencies' | 'start' | 'health' | 'complete') => void\n /** 只更新指定的 Compose 服务;省略时完整制品部署全部,部分制品只部署其镜像。 */\n selectedServices?: string[]\n /** 打包中间件镜像所用的本地引擎,auto 优先 Podman。 */\n runtime?: 'auto' | 'podman' | 'docker'\n /** 部署环境标识;显式指定时必须存在 .env.<environment>。 */\n environment?: string\n /** 环境文件所在目录,默认自动定位。 */\n envDir?: string\n /** 按服务或变量前缀选择处理方式;如 HAI_REACH_PROVIDERS_1 可独立于另一邮件连接。 */\n serviceModes?: Partial<Record<string, MiddlewareMode>>\n /** 项目名称(默认使用明确指定的部署目录名称)。 */\n projectName?: string\n /** 是否跳过全部中间件配置与开通,默认 false;例如配置完备时设为 true。 */\n skipMiddleware?: boolean\n /** 已构建镜像目录;默认最近构建入口/锁文件目录下的 .hai/build/docker。 */\n artifactDir?: string\n /** 只生成部署 tar,不连接 SSH;仅 docker-ssh 支持。 */\n bundleOnly?: boolean\n /** 部署 tar 输出路径;默认 .hai/deploy/<环境>/bundle-<项目>-<部署ID>-<版本>.tar,自定义文件名自动补 -<版本>。 */\n output?: string\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, options?: DeployScanOptions) => Promise<HaiResult<ScanResult>>\n\n /**\n * 对所有已配置的 Provisioner 执行基础设施开通\n *\n * @param projectName - 用于资源命名的项目名\n * @returns 所有 Provisioner 的结果列表\n */\n provisionAll: (projectName: string, services?: ServiceType[]) => Promise<HaiResult<ProvisionResult[]>>\n\n /**\n * 部署已有构建产物(环境和中间件 → 打包 → 上传/启动);不会调用构建命令。\n *\n * @param appDir - 应用根目录路径\n * @param options - 部署选项\n */\n deployApp: (appDir: string, options?: DeployAppOptions) => Promise<HaiResult<DeployResult>>\n}\n","/** 部署环境的加载和持久化;公开环境文件不保存真实凭据。 */\nimport type { HaiResult } from '@h-ai/core'\nimport { chmodSync, existsSync, readFileSync, writeFileSync } from 'node:fs'\nimport { join, resolve } from 'node:path'\nimport process from 'node:process'\nimport { parseEnv } from 'node:util'\nimport { core, err, ok } from '@h-ai/core'\nimport { LineCounter, parse, parseDocument } from 'yaml'\nimport { deployM } from './deploy-i18n.js'\nimport { HaiDeployError } from './deploy-types.js'\n\n/** 部署环境快照;例如 prod 的 targetValues 只来自 `.env.prod`,不包含基础/私有覆盖。 */\nexport interface DeploymentEnvironment {\n /** 文件模式(dev/test/prod 或其他合法模式名)。 */\n environment: string\n /** 环境文件的绝对目录。 */\n envDir: string\n /** 合并后的部署变量,可能含私有值,不得直接记录日志。 */\n values: Record<string, string>\n /** 仅目标环境文件显式声明的变量,用于判断能否“保持不变”。 */\n targetValues: Record<string, string>\n}\n\n/** 与 Core 一致,普通字符串如 CORS 的 `*` 不能因 YAML 标量解析失败而使配置加载失败。 */\nfunction environmentValue(value: string): unknown {\n try {\n return parse(value) ?? value\n }\n catch {\n return value\n }\n}\n\n/** 在已解析的 YAML 结构上处理覆盖,避免密码中的冒号、引号、井号变成 YAML 语法。 */\nfunction resolveConfig(value: unknown, prefix: string, env: Record<string, string | undefined>): unknown {\n if (env[prefix] !== undefined)\n return environmentValue(env[prefix])\n if (Array.isArray(value))\n return value.map((item, index) => resolveConfig(item, `${prefix}_${index}`, env))\n if (value && typeof value === 'object')\n return Object.fromEntries(Object.entries(value).map(([key, nested]) => [key, resolveConfig(nested, `${prefix}_${key.toUpperCase()}`, env)]))\n if (typeof value !== 'string')\n return value\n const resolved = value.replace(/\\$\\{([^:}]+)(?::([^}]*))?\\}/g, (_match, name: string, fallback?: string) => env[name] ?? fallback ?? '')\n return /^\\$\\{[^}]+\\}$/.test(value) ? environmentValue(resolved) : resolved\n}\n\n/**\n * 按部署环境解析配置;未选择的可选 Provisioner 缺少凭据时保留空值,选择完成后由 Schema 校验。\n * 不修改 core 缓存或进程变量,不在 YAML 文本上拼接凭据。\n * @param name - 模块配置名,例如 deploy/db/iam\n * @param path - YAML 文件绝对路径\n * @param values - 已加载的目标环境变量\n * @returns 配置对象;解析错误已脱敏\n * @example `loadDeploymentConfig('deploy', '/app/config/_deploy.yml', environment.values)`\n */\nexport function loadDeploymentConfig(name: string, path: string, values: Record<string, string | undefined>): HaiResult<Record<string, unknown>> {\n try {\n const lineCounter = new LineCounter()\n const document = parseDocument(readFileSync(path, 'utf8'), { lineCounter, prettyErrors: false })\n if (document.errors.length)\n return err(HaiDeployError.CONFIG_ERROR, deployM('deploy_configFileInvalid', { params: { path, line: String(lineCounter.linePos(document.errors[0]!.pos[0]).line) } }))\n const config = resolveConfig(document.toJS(), `HAI_${name.toUpperCase()}`, values)\n if (config !== null && (typeof config !== 'object' || Array.isArray(config)))\n return err(HaiDeployError.CONFIG_ERROR, deployM('deploy_configFileInvalid', { params: { path, line: '1' } }))\n return ok(config && typeof config === 'object' && !Array.isArray(config) ? config as Record<string, unknown> : {})\n }\n catch {\n return err(HaiDeployError.CONFIG_ERROR, deployM('deploy_configFileUnreadable', { params: { path } }))\n }\n}\n\n/**\n * 加载部署环境;指定环境文件缺失时返回错误并要求用户创建。\n * @param options - 模式、环境目录与是否强制存在目标文件\n * @param options.environment - dev/test/prod 或自定义模式\n * @param options.envDir - 环境文件所在目录\n * @param options.requireFile - 默认 true;扫描无显式环境时可只读取已有基础文件\n * @returns 环境快照,可能包含私有值,不得直接输出\n * @example `loadDeploymentEnvironment({ environment: 'prod', envDir: '.' })`\n */\nexport function loadDeploymentEnvironment(options: { environment: string, envDir: string, requireFile?: boolean }): HaiResult<DeploymentEnvironment> {\n const environment = options.environment === 'production' ? 'prod' : options.environment === 'development' ? 'dev' : options.environment\n if (!/^[a-z0-9][\\w-]*$/i.test(environment) || ['local', 'example'].includes(environment.toLowerCase()))\n return err(HaiDeployError.CONFIG_ERROR, deployM('deploy_invalidEnvironment'))\n const envDir = resolve(options.envDir)\n const target = join(envDir, `.env.${environment}`)\n if (options.requireFile !== false && !existsSync(target))\n return err(HaiDeployError.CONFIG_ERROR, deployM('deploy_environmentMissing', { params: { path: target } }))\n const loaded = core.config.loadEnvFiles({ mode: environment, envDir })\n if (!loaded.success)\n return loaded\n try {\n const values = { ...loaded.data }\n // 只传递应用配置和显式声明的运行变量,不上传整个调用者进程环境。\n for (const [name, value] of Object.entries(process.env)) {\n if (/^(?:HAI_|PUBLIC_|VITE_)/.test(name) && value !== undefined)\n values[name] = value\n }\n values.HAI_DEPLOY_ENVIRONMENT = environment\n values.HAI_CORE_ENV ??= environment === 'prod' ? 'production' : environment === 'dev' ? 'development' : environment === 'test' ? 'test' : 'staging'\n const targetValues: Record<string, string> = {}\n if (existsSync(target)) {\n for (const [name, value] of Object.entries(parseEnv(readFileSync(target, 'utf8')))) {\n if (value !== undefined)\n targetValues[name] = value\n }\n }\n return ok({ environment, envDir, values, targetValues })\n }\n catch {\n return err(HaiDeployError.CONFIG_ERROR, deployM('deploy_environmentReadFailed'))\n }\n}\n\n/** 判断值是否包含凭据;连接 URL 和 JSON 配置需要递归检查。 */\nfunction isSecret(name: string, value: string): boolean {\n if (/PASSWORD|SECRET|TOKEN|APIKEY|PRIVATEKEY|ACCESSKEY|AUTHORIZATION/i.test(name.replace(/[^a-z0-9]/gi, '')) || /(?:^|_)PASS$/i.test(name) || value.includes('PRIVATE KEY'))\n return true\n try {\n const url = new URL(value)\n if (url.username || url.password || [...url.searchParams.keys()].some(key => /password|secret|token|key|authorization/i.test(key)))\n return true\n }\n catch { /* 非 URL 配置继续按结构检查。 */ }\n try {\n const parsed: unknown = JSON.parse(value)\n if (parsed && typeof parsed === 'object')\n return Object.entries(parsed).some(([key, nested]) => isSecret(key, typeof nested === 'string' ? nested : JSON.stringify(nested)))\n }\n catch { /* 普通字符串无需 JSON 处理。 */ }\n return false\n}\n\n/** 将 JSON 中的凭据剥离,公共文件仍保留可审查的后端/连接结构。 */\nfunction publicConfig(value: unknown): unknown {\n if (Array.isArray(value))\n return value.map(publicConfig)\n if (value && typeof value === 'object')\n return Object.fromEntries(Object.entries(value).filter(([name, item]) => !isSecret(name, typeof item === 'string' ? item : '')).map(([name, item]) => [name, publicConfig(item)]))\n return value\n}\n\n/** dotenv 引号保留空格、注释符、美元符号和 JSON;非法换行键由调用边界拒绝。 */\nfunction quoteEnv(value: string): string {\n // JSON 内用 Unicode 转义表示单引号,dotenv 单引号即可无损保存复杂密码。\n try {\n const parsed: unknown = JSON.parse(value)\n if (parsed && typeof parsed === 'object')\n return `'${JSON.stringify(parsed).replaceAll('\\'', '\\\\u0027')}'`\n }\n catch { /* 标量按 dotenv 原生引号规则处理。 */ }\n if (!value.includes('\\''))\n return `'${value}'`\n if (!value.includes('\"'))\n return `\"${value}\"`\n if (!value.includes('`'))\n return `\\`${value}\\``\n if (!/[\\r\\n#]/.test(value))\n return value\n throw new Error('Unsupported dotenv value')\n}\n\n/** 按原有行更新键,保留注释与其他配置;更新私有文件时要求权限 600。 */\nfunction updateFile(path: string, values: Record<string, string>, privateFile: boolean): void {\n let content = existsSync(path) ? readFileSync(path, 'utf8') : '# Local private deployment configuration; do not commit.\\n'\n for (const [name, value] of Object.entries(values)) {\n if (!/^[A-Z][A-Z0-9_]*$/.test(name))\n throw new Error('Invalid environment variable name')\n const line = `${name}=${quoteEnv(value)}`\n // parseEnv 支持多行引号;替换时一起消费原值,避免遗留秘密片段。\n const pattern = new RegExp(`^(?:export\\\\s+)?${name}\\\\s*=\\\\s*(?:'[^']*'|\"[^\"]*\"|\\`[^\\`]*\\`|[^\\\\r\\\\n]*)[^\\\\r\\\\n]*`, 'gm')\n if (pattern.test(content))\n content = content.replace(pattern, () => line)\n else\n content = `${content.trimEnd()}\\n${line}\\n`\n }\n writeFileSync(path, content, { mode: privateFile ? 0o600 : 0o644 })\n if (privateFile)\n chmodSync(path, 0o600)\n}\n\n/** 明确修改的公共项必须清掉同名旧私有覆盖,避免重新加载后仍用旧后端。 */\nfunction removeOverrides(path: string, names: string[], privateFile = true): void {\n if (!existsSync(path) || names.length === 0)\n return\n let content = readFileSync(path, 'utf8')\n for (const name of names)\n content = content.replace(new RegExp(`^(?:export\\\\s+)?${name}\\\\s*=\\\\s*(?:'[^']*'|\"[^\"]*\"|\\`[^\\`]*\\`|[^\\\\r\\\\n]*)[^\\\\r\\\\n]*(?:\\\\r?\\\\n|$)`, 'gm'), '')\n writeFileSync(path, content, { mode: privateFile ? 0o600 : 0o644 })\n chmodSync(path, privateFile ? 0o600 : 0o644)\n}\n\n/**\n * 保存部署产生的变量:公共值写目标环境文件,凭据写 `.env.local`。\n * 返回实际写入的变量名,调用者只展示名称或脱敏值。\n * @param environment - 已加载的目标环境快照\n * @param values - 需要更新的变量;未提供的项保持原状\n * @param options - private 为 true 时所有值只保存在本机;适用于 SSH 地址、端口及密钥路径\n * @param options.private - 是否将全部值仅保存到 .env.local\n * @returns 已保存的变量名或脱敏错误\n * @example `saveDeploymentEnvironment(snapshot, { HAI_DB_TYPE: 'postgresql' })`\n * @example `saveDeploymentEnvironment(snapshot, { HAI_DEPLOY_PROVIDER: JSON.stringify(provider) }, { private: true })`\n */\nexport function saveDeploymentEnvironment(environment: DeploymentEnvironment, values: Record<string, string>, options: { private?: boolean } = {}): HaiResult<string[]> {\n try {\n const shared: Record<string, string> = {}\n const privateValues: Record<string, string> = {}\n for (const [name, value] of Object.entries(values)) {\n if (options.private) {\n privateValues[name] = value\n }\n else if (isSecret(name, value)) {\n privateValues[name] = value\n try {\n const parsed: unknown = JSON.parse(value)\n if (parsed && typeof parsed === 'object')\n shared[name] = JSON.stringify(publicConfig(parsed))\n }\n catch { /* 标量秘密仅写私有文件。 */ }\n }\n else {\n shared[name] = value\n }\n }\n if (Object.keys(shared).length)\n updateFile(join(environment.envDir, `.env.${environment.environment}`), shared, false)\n if (Object.keys(privateValues).length)\n updateFile(join(environment.envDir, '.env.local'), privateValues, true)\n removeOverrides(join(environment.envDir, `.env.${environment.environment}`), Object.keys(privateValues).filter(name => !(name in shared)), false)\n removeOverrides(join(environment.envDir, '.env.local'), Object.keys(shared).filter(name => !(name in privateValues)))\n if (Object.keys(privateValues).length) {\n const ignorePath = join(environment.envDir, '.gitignore')\n const ignore = existsSync(ignorePath) ? readFileSync(ignorePath, 'utf8') : ''\n if (!ignore.split(/\\r?\\n/).includes('.env.local'))\n writeFileSync(ignorePath, `${ignore.trimEnd()}\\n.env.local\\n.hai/deploy/\\n`)\n }\n return ok(Object.keys(values))\n }\n catch {\n return err(HaiDeployError.ENV_VAR_FAILED, deployM('deploy_environmentWriteFailed'))\n }\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_PROVIDER_TOKEN)\n * @param value - 凭证值\n *\n * @example\n * ```ts\n * saveCredential('HAI_DEPLOY_PROVIDER_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_PROVIDER_TOKEN: 'vel_xxx',\n * HAI_DEPLOY_SERVICES_DB_APIKEY: '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 { DeployAppOptions, ScanResult, ServiceType } from './deploy-types.js'\nimport { existsSync } from 'node:fs'\nimport { dirname, join, resolve } from 'node:path'\n\n/**\n * 定位构建目录;API workspace 的环境文件可在服务包,镜像仍位于工程根。\n * 只定位已约定的构建入口/锁文件,不从目录布局推断应用或中间件依赖。\n * @example `resolveArtifactDirectory('/workspace/demo/apps/demo-service')`\n */\nexport function resolveArtifactDirectory(appDir: string): string {\n let directory = resolve(appDir)\n while (true) {\n if (existsSync(join(directory, 'hai.build.json')) || existsSync(join(directory, 'pnpm-lock.yaml')))\n return join(directory, '.hai/build/docker')\n const parent = dirname(directory)\n if (parent === directory)\n return join(appDir, '.hai/build/docker')\n directory = parent\n }\n}\n\n/**\n * 判断同类连接中是否有默认配置项;具体变量前缀优先于服务类别,未指定时默认处理。\n * @example `usesDefaultMiddleware(scan, 'email', { serviceModes: { HAI_REACH_PROVIDERS_0: 'keep' } })`\n */\nexport function usesDefaultMiddleware(scan: ScanResult, service: ServiceType, options?: DeployAppOptions): boolean {\n const requirements = scan.middlewares?.filter(item => item.service === service) ?? []\n return requirements.length\n ? requirements.some(item => (options?.serviceModes?.[item.envPrefix] ?? options?.serviceModes?.[service] ?? 'default') === 'default')\n : (options?.serviceModes?.[service] ?? 'default') === 'default'\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 return join(appDir, '.vercel', 'output')\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","/** 应用、环境文件与中间件依赖扫描;不依赖 deploy.init(),不修改进程环境。 */\nimport type { HaiResult } from '@h-ai/core'\nimport type { DeployScanOptions, MiddlewareRequirement, ScanResult, ServiceType } from './deploy-types.js'\nimport { existsSync, readFileSync } from 'node:fs'\nimport { basename, dirname, join, relative, resolve } from 'node:path'\nimport { core, err, ok } from '@h-ai/core'\nimport { parseAllDocuments } from 'yaml'\nimport { loadDeploymentConfig, loadDeploymentEnvironment } from './deploy-environment.js'\nimport { deployM } from './deploy-i18n.js'\nimport { HaiDeployError } from './deploy-types.js'\n\nconst logger = core.logger.child({ module: 'deploy', scope: 'scanner' })\n\n/** 安全缩窄 YAML/JSON 对象;数组与 null 不作为配置对象。 */\nfunction record(value: unknown): Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value) ? value as Record<string, unknown> : {}\n}\n\n/**\n * 从当前 workspace 的 lockfile 导入项遍历运行依赖,排除 dev 和 peer 边。\n * pnpm 12 的工具链和应用分别存于多个 YAML 文档,只选择含目标 importer 的应用文档。\n * 缺少 lockfile 或目标 importer 时要求先安装,不读取 package.json 或推测应用布局。\n */\nfunction runtimeDependencies(appDir: string): { runtime: Set<string>, build: Set<string>, root: string } {\n let root = appDir\n while (!existsSync(join(root, 'pnpm-lock.yaml'))) {\n const parent = dirname(root)\n if (parent === root)\n throw new Error('Missing pnpm lockfile; run pnpm install')\n root = parent\n }\n const importerKey = relative(root, appDir).replaceAll('\\\\', '/') || '.'\n const documents = parseAllDocuments(readFileSync(join(root, 'pnpm-lock.yaml'), 'utf8'))\n if (documents.some(document => document.errors.length))\n throw new Error('Invalid pnpm lockfile')\n const lock = documents.map(document => record(document.toJS())).reverse().find(document => importerKey in record(document.importers))\n if (!lock)\n throw new Error('Application is missing from pnpm lockfile; run pnpm install')\n const importers = record(lock.importers)\n const packages = record(lock.packages)\n const snapshots = record(lock.snapshots)\n const names = new Set<string>()\n const visited = new Set<string>()\n const visit = (id: string, node: Record<string, unknown>, importer?: string): void => {\n if (visited.has(id))\n return\n visited.add(id)\n const metadata = importer === undefined ? record(packages[id.split('(')[0]]) : {}\n const peers = record(metadata.peerDependencies)\n for (const [name, reference] of Object.entries({ ...record(node.dependencies), ...record(node.optionalDependencies) })) {\n if (name in peers)\n continue\n const version = typeof reference === 'string' ? reference : record(reference).version\n if (typeof version !== 'string')\n throw new Error('Invalid pnpm dependency reference')\n if (version.startsWith('link:')) {\n if (importer === undefined)\n throw new Error('Invalid workspace dependency')\n const target = relative(root, resolve(root, importer, version.slice(5))).replaceAll('\\\\', '/') || '.'\n const linked = record(importers[target])\n if (!Object.keys(linked).length)\n throw new Error('Missing linked workspace importer')\n names.add(name)\n visit(`workspace:${target}`, linked, target)\n continue\n }\n // npm alias 的引用已包含真实包名,不能再拼接别名。\n const key = version in snapshots || version in packages ? version : `${name}@${version}`\n names.add(key.match(/^(@[^/]+\\/[^@]+|[^@]+)@/)?.[1] ?? name)\n const snapshot = record(snapshots[key] ?? packages[key])\n if (!Object.keys(snapshot).length && !(key in snapshots) && !(key in packages))\n throw new Error('Missing pnpm dependency snapshot')\n visit(key, snapshot)\n }\n }\n visit(`workspace:${importerKey}`, record(importers[importerKey]), importerKey)\n return { runtime: names, build: new Set([...names, ...Object.keys(record(record(importers[importerKey]).devDependencies))]), root }\n}\n\n/**\n * 扫描依赖和实际环境下的后端,不把 memory/local/console 强制改为外部服务。\n * 沿目标 importer 的运行依赖识别模块;LDAP 等可选能力再按实际配置识别。\n * @example `await scanApp('/workspace/packages/my-serv', { environment: 'prod' })`\n */\nexport async function scanApp(inputDir: string, options?: DeployScanOptions): Promise<HaiResult<ScanResult>> {\n try {\n const appDir = resolve(inputDir)\n const graph = runtimeDependencies(appDir)\n const envDir = options?.envDir ? resolve(options.envDir) : existsSync(join(appDir, '.env')) ? appDir : graph.root\n const loaded = loadDeploymentEnvironment({ environment: options?.environment ?? 'prod', envDir, requireFile: options?.environment !== undefined })\n if (!loaded.success)\n return loaded\n const env = loaded.data.values\n const deps = graph.runtime\n const configs: Record<string, Record<string, unknown>> = {}\n for (const [name, owner] of Object.entries({ db: 'reldb', cache: 'cache', storage: 'storage', vecdb: 'vecdb', iam: 'iam', reach: 'reach' })) {\n configs[name] = {}\n if (!deps.has(`@h-ai/${owner}`))\n continue\n const configFile = ['yml', 'yaml'].map(ext => join(appDir, 'config', `_${name}.${ext}`)).find(existsSync)\n const config = configFile ? loadDeploymentConfig(name, configFile, env) : undefined\n if (config && !config.success)\n return config\n configs[name] = config?.data ?? {}\n }\n const middlewares: MiddlewareRequirement[] = []\n const add = (service: ServiceType, backend: string, configName = service as string, configPath: string[] = [], config = configs[configName] ?? {}, source = `_${configName}.yml`) => {\n middlewares.push({ service, backend, source, configName, configPath, envPrefix: ['HAI', configName, ...configPath].map(part => part.toUpperCase()).join('_'), config })\n }\n const iam = deps.has('@h-ai/iam')\n if (deps.has('@h-ai/reldb'))\n add('db', String(configs.db.type ?? 'sqlite'), 'db', [], configs.db, '@h-ai/reldb / _db.yml')\n if (deps.has('@h-ai/cache'))\n add('cache', String(configs.cache.type ?? 'memory'), 'cache', [], configs.cache, '@h-ai/cache / _cache.yml')\n if (deps.has('@h-ai/storage'))\n add('storage', String(configs.storage.type ?? 'local'))\n if (deps.has('@h-ai/vecdb'))\n add('vecdb', String(configs.vecdb.type ?? 'lancedb'))\n if (iam) {\n const ldap = record(configs.iam.ldap)\n add('ldap', record(configs.iam.login).ldap === true ? 'ldap' : 'disabled', 'iam', ['ldap'], ldap, '@h-ai/iam (LDAP)')\n }\n const providers = configs.reach.providers\n if (deps.has('@h-ai/reach') && Array.isArray(providers)) {\n for (const [index, item] of providers.entries()) {\n const provider = record(item)\n const type = String(provider.type ?? '')\n const service = type === 'aliyun-sms' ? 'sms' : ['smtp', 'api', 'console'].includes(type) ? 'email' : undefined\n if (service)\n add(service, type, 'reach', ['providers', String(index)], provider, '@h-ai/reach')\n }\n }\n if (deps.has('@h-ai/reach') && !middlewares.some(item => item.configName === 'reach'))\n add('email', 'console', 'reach', ['providers', '0'], { name: 'email', type: 'console' }, '@h-ai/reach')\n const isSvelteKit = graph.build.has('@sveltejs/kit')\n const scan: ScanResult = {\n appDir,\n envDir,\n middlewares,\n haiModules: [...deps].filter(name => name.startsWith('@h-ai/')).sort(),\n appName: basename(appDir),\n isSvelteKit,\n adapterInstalled: graph.build.has('@sveltejs/adapter-vercel'),\n nodeAdapterInstalled: graph.build.has('@sveltejs/adapter-node'),\n requiredServices: [...new Set(middlewares.map(item => item.service))],\n serviceBackends: Object.fromEntries(middlewares.map(item => [item.service, item.backend])),\n }\n logger.info('Application scanned', { appName: scan.appName, haiModules: scan.haiModules, requiredServices: scan.requiredServices, serviceBackends: scan.serviceBackends })\n return ok(scan)\n }\n catch {\n // JSON/YAML 异常可能带有凭据行,不把原异常暴露到日志或用户错误。\n return err(HaiDeployError.SCAN_FAILED, deployM('deploy_scanFailed', { params: { error: 'Invalid or ambiguous application/configuration/lockfile; specify the application directory and run pnpm install' } }))\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 onOutput?: (output: string) => void\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 windowsHide: true,\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 options.onOutput?.(maskSecrets(chunk.toString('utf-8'), options.secrets))\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 stdout: maskSecrets(stdout, options.secrets).slice(-3000),\n })\n finish(err(\n HaiDeployError.REMOTE_COMMAND_FAILED,\n deployM('deploy_commandFailed', {\n params: { command, error: maskSecrets(`${stdout.slice(-2500)}\\n${stderr || `exit ${exitCode}`}`, options.secrets).slice(-3000) },\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","/** 在线发布与手工交付共用的服务器执行脚本。远程仅依赖标准 Linux 工具及 Compose。 */\nimport type { DockerSshProviderConfig } from '../deploy-config.js'\n\n/** 将可信配置编码为一个 shell 参数。 */\nexport function shellArgument(value: string): string {\n return `'${value.replaceAll('\\'', '\\'\"\\'\"\\'')}'`\n}\n\n/** 生成分步执行、增量合并和失败恢复脚本;密钥始终从环境文件读取。 */\nexport function createApplyScript(options: {\n deploymentId: string\n projectName: string\n environment: string\n directory: string\n runtime: 'auto' | 'docker' | 'podman'\n partial: boolean\n selected: string[]\n hostPort: number\n healthPaths: string[]\n}): string {\n const values: Record<string, string> = {\n ID: shellArgument(options.deploymentId),\n PROJECT: shellArgument(`hai-${options.projectName}`),\n ENV: shellArgument(options.environment),\n RUNTIME: shellArgument(options.runtime),\n PARTIAL: options.partial ? 'true' : 'false',\n SELECTED: shellArgument(options.selected.join(' ')),\n ROOT: shellArgument(options.directory),\n PORT: String(options.hostPort),\n HEALTH: options.healthPaths.map(shellArgument).join(' '),\n }\n return String.raw`#!/bin/sh\nset -eu\numask 077\nsource_dir=$(CDPATH= cd -- \"$(dirname -- \"$0\")\" && pwd)\ndestination=@@ROOT@@\nif [ \"$#\" -gt 0 ]; then destination=$1; fi\nroot=$(mkdir -p -- \"$destination\" && CDPATH= cd -- \"$destination\" && pwd)\nid=@@ID@@\nproject=@@PROJECT@@\nexport HAI_DEPLOY_ENVIRONMENT=@@ENV@@\nruntime=@@RUNTIME@@\npartial=@@PARTIAL@@\norphan_option=''\nif [ \"$partial\" = false ]; then orphan_option=--remove-orphans; fi\nrecreate_option=--force-recreate\nif [ \"$partial\" = true ]; then recreate_option=--no-recreate; fi\nselected=@@SELECTED@@\nrelease=\"$root/releases/$id\"\ncase \"$release/\" in \"$source_dir/\"*) printf 'Extract the package outside the deployment directory before applying it.\\n' >&2; exit 1;; esac\nstage=''\nprevious=''\nrestore=''\nchanged=false\nlocked=false\nstarted=$(date +%s)\nstep_started=$started\nstep() {\n if [ -n \"$stage\" ]; then\n duration=$(( $(date +%s) - step_started ))\n printf '[PASS] %s (%ss)\\n' \"$stage\" \"$duration\"\n printf '{\"stage\":\"%s\",\"status\":\"passed\",\"durationSeconds\":%s}\\n' \"$stage\" \"$duration\" >> \"$root/steps-$id.jsonl\"\n fi\n stage=\"$1\"\n step_started=$(date +%s)\n printf '\\n[%s] %s\\n' \"$stage\" \"$2\"\n}\ncompose() {\n arguments_file=\"$release/compose-files\"\n if [ -n \"$restore\" ]; then arguments_file=\"$root/releases/$restore/compose-files\"; fi\n # -f 按顺序合并,由 Compose 保留未选服务、卷和环境文件,不自行拼装配置。\n command_args=\"$release/.compose-command\"\n # 文件列表先反向读取,再向参数头部加入,保留原始合并顺序。\n awk '{lines[NR]=$0} END {for(i=NR;i>0;i--) print lines[i]}' \"$arguments_file\" > \"$command_args\"\n while IFS= read -r file; do set -- -f \"$file\" \"$@\"; done < \"$command_args\"\n \"$runtime\" compose -p \"$project\" \"$@\"\n}\nremove_selected() {\n test \"$partial\" = true || return 0\n # 直接替换选中容器,避免 Compose Provider 连带重建依赖它的未选服务;不删除卷。\n for service in \"$@\"; do\n containers=$(\"$runtime\" ps -aq --filter \"label=com.docker.compose.project=$project\" --filter \"label=com.docker.compose.service=$service\") || return 1\n for container in $containers; do\n \"$runtime\" rm -f \"$container\" || return 1\n done\n done\n}\nfinish() {\n code=$?\n trap - EXIT HUP INT TERM\n if [ \"$code\" -ne 0 ]; then\n printf '[FAIL] %s (exit %s)\\n' \"$stage\" \"$code\" >&2\n if [ \"$changed\" = true ]; then\n diagnostics=\"$root/diagnostics-$id.log\"\n : > \"$diagnostics\"\n for service in $selected; do\n containers=$(\"$runtime\" ps -aq --filter \"label=com.docker.compose.project=$project\" --filter \"label=com.docker.compose.service=$service\" || true)\n for container in $containers; do\n \"$runtime\" inspect --format '{{.Name}} {{.State.Status}} exit={{.State.ExitCode}}' \"$container\" >> \"$diagnostics\" 2>&1 || true\n \"$runtime\" logs --tail 80 \"$container\" >> \"$diagnostics\" 2>&1 || true\n done\n done\n printf 'Startup diagnostics saved to %s (private server file).\\n' \"$diagnostics\" >&2\n fi\n if [ -f \"$release/rollback-images\" ]; then\n while IFS=' ' read -r image reference; do\n test -n \"$reference\" || continue\n \"$runtime\" tag \"$image\" \"$reference\" || printf '[FAIL] Cannot restore image %s\\n' \"$reference\" >&2\n done < \"$release/rollback-images\"\n fi\n if [ \"$changed\" = true ] && [ -n \"$previous\" ]; then\n printf '[RECOVER] Restoring previous selected services\\n' >&2\n recover_selected=$selected\n if [ \"$partial\" = false ]; then recover_selected=$(grep -v -- '-init$' \"$root/releases/$previous/services\"); fi\n restore=\"$previous\"\n if remove_selected $recover_selected && compose up -d --no-deps --no-build --pull never \"$recreate_option\" $orphan_option $recover_selected; then\n case \" $selected \" in *' app '*)\n if grep -qx web \"$root/releases/$previous/services\"; then compose exec -T web nginx -s reload || true; fi\n ;;\n esac\n printf '[RECOVER] Previous containers restored; verify application health\\n' >&2\n else\n printf '[FAIL] Recovery failed. Use the previous release and inspect container logs.\\n' >&2\n fi\n elif [ \"$changed\" = true ]; then\n compose stop $selected || true\n printf '[RECOVER] Failed first installation stopped; data volumes retained\\n' >&2\n fi\n fi\n if [ \"$locked\" = true ]; then\n elapsed=$(( $(date +%s) - started ))\n outcome=passed\n if [ \"$code\" -ne 0 ]; then outcome=failed; fi\n printf '{\"stage\":\"%s\",\"status\":\"%s\",\"durationSeconds\":%s}\\n' \"$stage\" \"$outcome\" \"$(( $(date +%s) - step_started ))\" >> \"$root/steps-$id.jsonl\"\n printf '{\"deploymentId\":\"%s\",\"stage\":\"%s\",\"exitCode\":%s,\"durationSeconds\":%s}\\n' \"$id\" \"$stage\" \"$code\" \"$elapsed\" > \"$root/result-$id.json\"\n rmdir \"$root/.deploy-lock\" || true\n fi\n exit \"$code\"\n}\ntrap finish EXIT\ntrap 'exit 130' HUP INT TERM\nstep preflight 'Checking deployment tools and package'\nfor tool in sha256sum tar awk curl; do command -v \"$tool\" >/dev/null || { printf 'Required command missing: %s\\n' \"$tool\" >&2; exit 1; }; done\nif [ \"$runtime\" = auto ]; then\n if command -v podman >/dev/null 2>&1 && podman version >/dev/null 2>&1; then runtime=podman; else runtime=docker; fi\nfi\ncase \"$runtime\" in docker|podman) ;; *) printf 'Runtime must be docker or podman\\n' >&2; exit 1;; esac\n\"$runtime\" version >/dev/null\n\"$runtime\" compose version >/dev/null\n\"$runtime\" compose up --help | grep -q never || { printf 'Compose is too old. Install Docker Compose v2 or podman-compose 1.6.0 or newer (supports --pull never).\\n' >&2; exit 1; }\nmkdir \"$root/.deploy-lock\" 2>/dev/null || { printf 'Another deployment is running. Check %s/.deploy-lock before retrying.\\n' \"$root\" >&2; exit 1; }\nlocked=true\ncd \"$source_dir\"\nsha256sum -c SHA256SUMS\nif [ -f \"$root/current\" ]; then\n previous=$(cat \"$root/current\")\n case \"$previous\" in ''|*[!a-zA-Z0-9._-]*) printf 'Invalid deployment state\\n' >&2; exit 1;; esac\n test -f \"$root/releases/$previous/compose-files\"\nfi\nif [ \"$partial\" = true ]; then\n test -n \"$previous\" || { printf 'Partial deployment requires a successful full installation. Deploy a complete bundle first.\\n' >&2; exit 1; }\n cmp -s layout \"$root/releases/$previous/layout\" || { printf 'Ports, API routes or application layout changed. Create a full deployment bundle.\\n' >&2; exit 1; }\nfi\ntest ! -e \"$release\" || { printf 'This deployment ID was already used. Create a new deployment bundle.\\n' >&2; exit 1; }\nmkdir -p \"$release\"\ncp -R \"$source_dir/.\" \"$release/\"\n# Nginx 以非 root 用户运行;只开放不含凭据的代理配置读取权限。\nif [ -f \"$release/web.conf\" ]; then chmod 644 \"$release/web.conf\"; fi\n: > \"$release/compose-files\"\nif [ \"$partial\" = true ]; then\n cp \"$root/releases/$previous/compose-files\" \"$release/compose-files\"\n cp \"$root/releases/$previous/middleware.env\" \"$release/middleware.env\"\n for service in $selected; do\n grep -qx \"$service\" \"$root/releases/$previous/services\" || { printf 'Service %s has no installed baseline. Use a full deployment.\\n' \"$service\" >&2; exit 1; }\n done\nfi\nprintf '%s\\n' \"$release/compose-entry.json\" >> \"$release/compose-files\"\ncompose config >/dev/null\ncompose config --services > \"$release/services\"\n: > \"$release/rollback-images\"\nif [ -n \"$previous\" ]; then\n for service in $selected; do\n containers=$(\"$runtime\" ps -aq --filter \"label=com.docker.compose.project=$project\" --filter \"label=com.docker.compose.service=$service\")\n for container in $containers; do\n \"$runtime\" inspect --format '{{.Image}} {{.Config.Image}}' \"$container\" >> \"$release/rollback-images\"\n done\n done\nfi\nstep images 'Loading packaged images (no registry access)'\nwhile IFS=' ' read -r archive reference; do\n test -n \"$archive\" || continue\n \"$runtime\" load -i \"$release/images/$archive\"\n \"$runtime\" image inspect \"$reference\" >/dev/null\n architecture=$(\"$runtime\" image inspect --format '{{.Architecture}}' \"$reference\")\n host_arch=$(uname -m)\n case \"$host_arch:$architecture\" in x86_64:amd64|aarch64:arm64) ;; *) printf 'Image architecture %s does not match server %s\\n' \"$architecture\" \"$host_arch\" >&2; exit 1;; esac\ndone < \"$release/image-list\"\nstep dependencies 'Checking dependencies of selected services'\nif [ \"$partial\" = true ]; then cat \"$release/services\" >> \"$release/dependencies\"; fi\nwhile IFS= read -r dependency; do\n test -n \"$dependency\" || continue\n case \"$dependency\" in *-init) continue;; esac\n case \" $selected \" in *\" $dependency \"*) continue;; esac\n running=$(\"$runtime\" ps -q --filter \"label=com.docker.compose.project=$project\" --filter \"label=com.docker.compose.service=$dependency\")\n test -n \"$running\" || { printf 'Dependency %s is not running. Include it in a full deployment.\\n' \"$dependency\" >&2; exit 1; }\n for container in $running; do\n test \"$(\"$runtime\" inspect --format '{{.State.Running}}' \"$container\")\" = true || { printf 'Dependency %s is stopped. Start it before retrying.\\n' \"$dependency\" >&2; exit 1; }\n done\ndone < \"$release/dependencies\"\nstep start 'Updating selected services'\nchanged=true\nremove_selected $selected\nif [ -f \"$release/initialize-storage\" ]; then\n remove_selected storage-init\n compose up -d --no-deps --no-build --pull never storage\n compose up --no-deps --no-build --pull never \"$recreate_option\" --exit-code-from storage-init storage-init\nfi\ncompose up -d --no-deps --no-build --pull never \"$recreate_option\" $orphan_option $selected\ncase \" $selected \" in\n *' app '*)\n case \" $selected \" in *' web '*) ;; *)\n if grep -qx web \"$release/services\"; then compose exec -T web nginx -s reload; fi\n esac\n ;;\nesac\nstep health 'Checking HTTP access'\nfor path in @@HEALTH@@; do\n ready=false\n attempt=0\n while [ \"$attempt\" -lt 40 ]; do\n if curl --noproxy '*' -fsS --max-time 5 \"http://127.0.0.1:@@PORT@@$path\" >/dev/null 2>&1; then ready=true; break; fi\n attempt=$((attempt + 1))\n sleep 3\n done\n test \"$ready\" = true || { printf 'HTTP check failed: %s. Inspect compose logs for selected services.\\n' \"$path\" >&2; exit 1; }\ndone\nstep complete 'Deployment passed all checks'\nprintf '%s\\n' \"$id\" > \"$root/current.next\"\nmv \"$root/current.next\" \"$root/current\"\nprintf '[PASS] %s\\n' \"$id\"\n`.replace(/@@([A-Z]+)@@/g, (_match, name: string) => values[name]!)\n}\n\n/** 生成无 Node/pnpm 依赖的上传脚本;换电脑时可覆盖 SSH 私钥路径。 */\nexport function createUploadScripts(config: DockerSshProviderConfig, bundle: string, projectName: string): { sh: string, ps1: string } {\n const ssh = config.ssh\n const host = ssh?.host ?? 'SERVER_HOST'\n const user = ssh?.username ?? 'deploy'\n const remote = `${config.remote.baseDir}/${projectName}`\n const port = ssh?.port ?? 22\n const sh = String.raw`#!/bin/sh\nset -eu\ncd \"$(dirname \"$0\")\"\nhost=@@HOST@@\nuser=@@USER@@\nport=@@PORT@@\nremote=@@REMOTE@@\nbundle=@@BUNDLE@@\nif [ \"$#\" -ge 1 ]; then host=$1; fi\nif [ \"$#\" -ge 2 ]; then port=$2; fi\nif [ \"$#\" -ge 3 ]; then user=$3; fi\nidentity=$(printenv HAI_DEPLOY_IDENTITY_FILE || true)\nif [ -z \"$identity\" ]; then identity=@@IDENTITY@@; fi\ntest \"$host\" != SERVER_HOST || { printf 'Specify the server: sh deploy.sh SERVER [PORT] [USER].\\n' >&2; exit 1; }\nfor tool in ssh scp; do command -v \"$tool\" >/dev/null || { printf 'Install OpenSSH (%s).\\n' \"$tool\" >&2; exit 1; }; done\nset -- -o BatchMode=yes -o StrictHostKeyChecking=@@STRICT@@ -o ConnectTimeout=10\nif [ -n \"$identity\" ]; then set -- \"$@\" -i \"$identity\"; fi\nknown_hosts=@@KNOWN@@\nif value=$(printenv HAI_DEPLOY_KNOWN_HOSTS_FILE); then known_hosts=$value; fi\nif [ -n \"$known_hosts\" ]; then set -- \"$@\" -o \"UserKnownHostsFile=$known_hosts\"; fi\nprintf '[1/3] Connecting to %s\\n' \"$host\"\nssh \"$@\" -p \"$port\" \"$user@$host\" \"mkdir -p '$remote/incoming' && chmod 700 '$remote' '$remote/incoming'\"\nprintf '[2/3] Uploading %s\\n' \"$bundle\"\nscp_host=$host\ncase \"$host\" in *:*) scp_host=\"[$host]\";; esac\nscp \"$@\" -P \"$port\" \"$bundle\" \"$user@$scp_host:$remote/incoming/$bundle\"\nprintf '[3/3] Applying package and checking HTTP access\\n'\nssh \"$@\" -p \"$port\" \"$user@$host\" \"cd '$remote/incoming' && mkdir -p '$bundle.contents' && tar -xf '$bundle' -C '$bundle.contents' && sh '$bundle.contents/apply.sh' '$remote'\"\n`\n const ps1 = String.raw`param([string]$IdentityFile = $env:HAI_DEPLOY_IDENTITY_FILE)\n$ErrorActionPreference = 'Stop'\nSet-Location -LiteralPath $PSScriptRoot\n$target = Get-Content -LiteralPath './deploy-target.json' -Raw | ConvertFrom-Json\nif ($target.host -eq 'SERVER_HOST') { throw 'Set the server host in deploy-target.json.' }\nif ($target.host -notmatch '^[a-zA-Z0-9][a-zA-Z0-9.:-]*$' -or $target.username -notmatch '^[a-zA-Z_][a-zA-Z0-9_-]*$' -or $target.directory -notmatch '^/[a-zA-Z0-9/_. -]+$' -or $target.directory -match '(^|/)\\.\\.(/|$)' -or $target.bundle -notmatch '^[a-zA-Z0-9_.+-]+\\.tar$') { throw 'Invalid deployment target.' }\n$options = @('-o', 'BatchMode=yes', '-o', 'StrictHostKeyChecking=accept-new', '-o', 'ConnectTimeout=10')\nif ($target.strictHostKeyChecking -eq $false) { $options[3] = 'StrictHostKeyChecking=no' }\nif (-not $IdentityFile) { $IdentityFile = $target.identityFile }\nif ($IdentityFile) { $options += @('-i', $IdentityFile) }\nif ($target.knownHostsFile) { $options += @('-o', \"UserKnownHostsFile=$($target.knownHostsFile)\") }\n$destination = \"$($target.username)@$($target.host)\"\n$scpDestination = if ($target.host.Contains(':')) { \"$($target.username)@[$($target.host)]\" } else { $destination }\n$remote = $target.directory\n$bundle = $target.bundle\nfunction Invoke-Step([string]$Name, [string]$Command, [string[]]$Arguments) {\n Write-Host \"[$Name]\"\n & $Command @Arguments\n if ($LASTEXITCODE -ne 0) { throw \"$Name failed (exit $LASTEXITCODE).\" }\n}\ntry {\n foreach ($tool in @('ssh', 'scp')) { Get-Command $tool -ErrorAction Stop | Out-Null }\n Invoke-Step '1/3 Connect' 'ssh' ($options + @('-p', [string]$target.port, $destination, \"mkdir -p '$remote/incoming' && chmod 700 '$remote' '$remote/incoming'\"))\n Invoke-Step '2/3 Upload' 'scp' ($options + @('-P', [string]$target.port, $bundle, \"$($scpDestination):$remote/incoming/$bundle\"))\n Invoke-Step '3/3 Apply and verify HTTP' 'ssh' ($options + @('-p', [string]$target.port, $destination, \"cd '$remote/incoming' && mkdir -p '$bundle.contents' && tar -xf '$bundle' -C '$bundle.contents' && sh '$bundle.contents/apply.sh' '$remote'\"))\n} catch { Write-Error $_; exit 1 }\n`\n const values: Record<string, string> = { HOST: shellArgument(host), USER: shellArgument(user), PORT: String(port), REMOTE: shellArgument(remote), BUNDLE: shellArgument(bundle), IDENTITY: shellArgument(ssh?.identityFile ?? ''), KNOWN: shellArgument(ssh?.knownHostsFile ?? ''), STRICT: ssh?.strictHostKeyChecking === false ? 'no' : 'accept-new' }\n return { sh: sh.replace(/@@([A-Z]+)@@/g, (_match, name: string) => values[name]!), ps1 }\n}\n","/** 完整或增量交付包,包含所选服务需要的全部镜像及跨平台部署入口。 */\nimport type { DeploymentArtifact } from '../deploy-artifact.js'\nimport type { DockerSshProviderConfig } from '../deploy-config.js'\nimport { chmodSync, copyFileSync, mkdirSync, mkdtempSync, readFileSync, renameSync, rmSync, writeFileSync } from 'node:fs'\nimport { basename, dirname, join, resolve } from 'node:path'\nimport { parse } from 'yaml'\nimport { artifactChecksum } from '../deploy-artifact.js'\nimport { deployM } from '../deploy-i18n.js'\nimport { runCommand } from './deploy-command.js'\nimport { createApplyScript, createUploadScripts } from './deploy-scripts.js'\n\n/** 打包所选服务;完整交付自动导出中间件,服务器启动时禁止联网拉取。 */\nexport async function createDeploymentBundle(options: {\n directory: string\n artifactDir: string\n artifact: DeploymentArtifact\n projectName: string\n deploymentId: string\n environment: string\n config: DockerSshProviderConfig\n runtime: 'auto' | 'podman' | 'docker'\n output: string\n selected: string[]\n partial: boolean\n middlewareEnv: string\n healthPaths: string[]\n hasWeb: boolean\n containerPort: number\n}): Promise<{ bundlePath: string, instructions: string, startName: string }> {\n const { directory, artifactDir, artifact, projectName, environment, config, selected } = options\n const stem = basename(options.output).replace(/\\.tar$/i, '')\n const suffix = `-${artifact.appVersion}`\n const output = resolve(dirname(options.output), `${stem.endsWith(suffix) ? stem : `${stem}${suffix}`}.tar`)\n if (!/^[\\w.+-]+\\.tar$/.test(basename(output)))\n throw new Error(deployM('deploy_bundleNameInvalid'))\n const staging = mkdtempSync(join(directory, '.bundle-'))\n const temporaryTar = `${output}.partial`\n mkdirSync(dirname(output), { recursive: true, mode: 0o700 })\n chmodSync(staging, 0o700)\n const files: string[] = []\n const put = (file: string, content: string): void => {\n mkdirSync(dirname(join(staging, file)), { recursive: true })\n writeFileSync(join(staging, file), content, { mode: 0o600 })\n files.push(file)\n }\n try {\n mkdirSync(join(staging, 'images'))\n const compose = parse(readFileSync(join(directory, `docker-compose-${artifact.appVersion}.yml`), 'utf8')) as {\n services: Record<string, Record<string, unknown>>\n networks?: Record<string, unknown>\n volumes?: Record<string, unknown>\n }\n const dependencies = new Set<string>()\n const references = new Set<string>()\n for (const name of selected) {\n const service = compose.services[name]\n if (!service)\n throw new Error(deployM('deploy_selectionInvalid', { params: { service: name } }))\n if (typeof service.image === 'string')\n references.add(service.image)\n if (service.depends_on) {\n for (const dependency of Array.isArray(service.depends_on) ? service.depends_on as string[] : Object.keys(service.depends_on))\n dependencies.add(dependency)\n }\n if (service.env_file)\n service.env_file = [`../${options.deploymentId}/.env.runtime`, `../${options.deploymentId}/middleware.env`]\n if (Array.isArray(service.volumes))\n service.volumes = service.volumes.map(mount => typeof mount === 'string' ? mount.replace('./web.conf:', `../${options.deploymentId}/web.conf:`) : mount)\n }\n put('compose.json', JSON.stringify({ ...compose, services: Object.fromEntries(selected.map(name => [name, compose.services[name]])) }))\n // 合并入口仅保存 extends 指向;更新服务时整体切换定义,避免旧 env_file/卷列表累加。\n put('compose-entry.json', JSON.stringify({ ...compose, services: Object.fromEntries(selected.map(name => [name, { extends: { file: `../${options.deploymentId}/compose.json`, service: name } }])) }))\n let runtime: 'podman' | 'docker' | undefined\n const imageList: string[] = []\n for (const reference of references) {\n if (!/:[^/:]+$/.test(reference) || /:latest$/i.test(reference))\n throw new Error(deployM('deploy_imageVersionRequired', { params: { image: reference } }))\n const built = artifact.images.find(image => image.imageRef === reference)\n const file = built?.file ?? `middleware-${imageList.length + 1}.tar`\n if (built) {\n copyFileSync(join(artifactDir, file), join(staging, 'images', file))\n }\n else {\n if (!runtime) {\n const candidates = options.runtime === 'auto' ? ['podman', 'docker'] as const : [options.runtime]\n for (const candidate of candidates) {\n if ((await runCommand(candidate, ['version'])).success) {\n runtime = candidate\n break\n }\n }\n if (!runtime)\n throw new Error(deployM('deploy_bundleRuntimeRequired'))\n }\n if (!(await runCommand(runtime, ['image', 'inspect', reference])).success) {\n const pulled = await runCommand(runtime, ['pull', reference], { timeoutMs: 600_000 })\n if (!pulled.success)\n throw new Error(pulled.error.message)\n }\n const saved = await runCommand(runtime, ['save', ...(runtime === 'podman' ? ['--format', 'docker-archive'] : []), '-o', join(staging, 'images', file), reference], { timeoutMs: 600_000 })\n if (!saved.success)\n throw new Error(saved.error.message)\n }\n files.push(`images/${file}`)\n imageList.push(`${file} ${reference}`)\n }\n put('.env.runtime', readFileSync(join(directory, '.env.runtime'), 'utf8'))\n put('middleware.env', options.middlewareEnv)\n if (selected.includes('web'))\n put('web.conf', readFileSync(join(directory, 'web.conf'), 'utf8'))\n put('manifest.json', `${JSON.stringify({ ...artifact, images: artifact.images.filter(image => references.has(image.imageRef)), deploymentId: options.deploymentId, selectedServices: selected, partial: options.partial }, null, 2)}\\n`)\n put('layout', `${config.expose.hostPort}:${options.containerPort}:${options.hasWeb}:${options.hasWeb ? await artifactChecksum(join(directory, 'web.conf')) : ''}\\n`)\n put('image-list', `${imageList.join('\\n')}\\n`)\n put('dependencies', `${[...dependencies].join('\\n')}\\n`)\n if (selected.includes('storage-init'))\n put('initialize-storage', '')\n put('apply.sh', createApplyScript({ deploymentId: options.deploymentId, projectName, environment, directory: `${config.remote.baseDir}/${projectName}`, runtime: config.remote.runtime, partial: options.partial, selected: selected.filter(name => name !== 'storage-init'), hostPort: config.expose.hostPort, healthPaths: options.healthPaths }))\n const instructions = deployM('deploy_bundleInstructions', { params: { file: basename(output), start: 'apply.sh', images: [...references].join('\\n'), compose: 'compose.json' } })\n put('README.txt', `${deployM('deploy_bundleMetadata', { params: { version: artifact.appVersion, buildId: artifact.buildId, compose: 'compose.json' } })}\\n${instructions}\\n`)\n const checksums = []\n for (const file of files)\n checksums.push(`${await artifactChecksum(join(staging, file))} ${file}`)\n writeFileSync(join(staging, 'SHA256SUMS'), `${checksums.join('\\n')}\\n`)\n const tar = await runCommand('tar', ['-cf', temporaryTar, '-C', staging, '.'])\n if (!tar.success)\n throw new Error(tar.error.message)\n chmodSync(temporaryTar, 0o600)\n renameSync(temporaryTar, output)\n const upload = createUploadScripts(config, basename(output), projectName)\n const scripts = `${output.slice(0, -4)}-deploy`\n mkdirSync(scripts, { recursive: true, mode: 0o700 })\n writeFileSync(join(scripts, 'deploy.sh'), upload.sh.replace('cd \"$(dirname \"$0\")\"', 'cd \"$(dirname \"$0\")/..\"'), { mode: 0o700 })\n writeFileSync(join(scripts, 'deploy.ps1'), upload.ps1.replace('Set-Location -LiteralPath $PSScriptRoot', 'Set-Location -LiteralPath (Split-Path -Parent $PSScriptRoot)').replace('\\'./deploy-target.json\\'', '(Join-Path $PSScriptRoot \\'deploy-target.json\\')'))\n writeFileSync(join(scripts, 'deploy-target.json'), `${JSON.stringify({ ...config.ssh, host: config.ssh?.host ?? 'SERVER_HOST', username: config.ssh?.username ?? 'deploy', port: config.ssh?.port ?? 22, directory: `${config.remote.baseDir}/${projectName}`, bundle: basename(output) }, null, 2)}\\n`)\n writeFileSync(join(scripts, 'README.txt'), instructions)\n return { bundlePath: output, instructions: `${instructions}\\n${scripts}`, startName: 'apply.sh' }\n }\n finally {\n rmSync(staging, { recursive: true, force: true })\n rmSync(temporaryTar, { force: true })\n }\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 { DeployAppOptions, 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'\nimport { usesDefaultMiddleware } from '../deploy-functions.js'\nimport { deployM } from '../deploy-i18n.js'\n\n/** sidecar 镜像固定版本,避免 `:latest` 漂移导致行为变化。 */\nconst IMAGES = {\n postgres: 'docker.io/library/postgres:16.15-alpine',\n mysql: 'docker.io/library/mysql:8.4.11',\n redis: 'docker.io/library/redis:7.4.11-alpine',\n rustfs: 'ghcr.io/rustfs/rustfs:1.0.1',\n minio: 'ghcr.io/coollabsio/minio:RELEASE.2025-10-15T17-29-55Z',\n qdrant: 'docker.io/qdrant/qdrant:v1.19.2',\n pgvector: 'docker.io/pgvector/pgvector:0.8.0-pg17',\n chroma: 'docker.io/chromadb/chroma:1.5.5',\n ldap: 'docker.io/osixia/openldap:1.5.0',\n smtp: 'docker.io/axllent/mailpit:v1.27.4',\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 const saved = JSON.parse(readFileSync(secretFile, 'utf-8')) as Record<string, string>\n if (!saved || !['dbPassword', 'storagePassword', 'ldapPassword'].every(key => typeof saved[key] === 'string' && saved[key].length > 0))\n throw new Error('Invalid credentials')\n return saved\n }\n catch {\n throw new Error(deployM('deploy_secretsInvalid', { params: { path: secretFile } }))\n }\n }\n const secrets = {\n dbPassword: generatePassword(),\n storagePassword: generatePassword(),\n ldapPassword: 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/** S3 协议与服务实现分离;RustFS/MinIO 使用相同应用契约及幂等 bucket 初始化。 */\nfunction planS3Storage(plan: SidecarPlan, projectName: string, password: string, net: string[], engine: 'rustfs' | 'minio'): void {\n plan.services.push('storage')\n plan.dependsOn.push('storage')\n plan.composeServices.storage = {\n image: IMAGES[engine],\n container_name: `hai-${projectName}-storage`,\n restart: 'unless-stopped',\n ...(engine === 'minio' ? { command: ['server', '/data'] } : {}),\n env_file: ['.env.runtime'],\n volumes: [`${projectName}-storage-data:/data`],\n networks: net,\n }\n plan.composeServices['storage-init'] = {\n depends_on: ['storage'],\n env_file: ['.env.runtime'],\n entrypoint: [\n 'node',\n '--input-type=module',\n '-e',\n // 复用应用 @h-ai/storage 已依赖的 SDK;不额外拉取失效的 mc 镜像,不把密钥拼进命令。\n `import { S3Client, HeadBucketCommand, CreateBucketCommand } from '@aws-sdk/client-s3';\nconst config = JSON.parse(process.env.HAI_STORAGE);\nconst client = new S3Client({ endpoint: config.endpoint, region: config.region, forcePathStyle: config.forcePathStyle, credentials: { accessKeyId: config.accessKeyId, secretAccessKey: config.secretAccessKey } });\nlet ready = false;\nfor (let attempt = 0; attempt < 120; attempt++) {\n try {\n try { await client.send(new HeadBucketCommand({ Bucket: config.bucket })); }\n catch (error) {\n if (error.$$metadata?.httpStatusCode !== 404) throw error;\n await client.send(new CreateBucketCommand({ Bucket: config.bucket }));\n }\n ready = true; break;\n } catch { await new Promise(resolve => setTimeout(resolve, 1000)); }\n}\nclient.destroy();\nif (!ready) throw new Error('S3 bucket initialization failed');`,\n ],\n networks: net,\n }\n plan.volumes[`${projectName}-storage-data`] = null\n if (engine === 'rustfs') {\n Object.assign(plan.env, { RUSTFS_ACCESS_KEY: 'hai-storage', RUSTFS_SECRET_KEY: password, RUSTFS_ADDRESS: '0.0.0.0:9000', RUSTFS_VOLUMES: '/data', RUSTFS_CONSOLE_ENABLE: 'false' })\n }\n else {\n Object.assign(plan.env, { MINIO_ROOT_USER: 'hai-storage', MINIO_ROOT_PASSWORD: password })\n }\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-storage',\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 options?: DeployAppOptions,\n s3Engine: 'rustfs' | 'minio' = 'rustfs',\n): SidecarPlan {\n // 保持配置不变仍需交付自建服务镜像;已保存的容器服务地址可明确区分外部连接。\n const serviceModes = { ...options?.serviceModes }\n for (const requirement of scan.middlewares ?? []) {\n if (options?.selectedServices && !options.selectedServices.includes(requirement.service))\n continue\n const mode = serviceModes[requirement.envPrefix] ?? serviceModes[requirement.service]\n if (mode !== 'keep')\n continue\n const endpoint = requirement.config.url ?? requirement.config.endpoint\n let host = requirement.config.host\n if (typeof endpoint === 'string') {\n try {\n host = new URL(endpoint).hostname\n }\n catch {\n continue\n }\n }\n if (host === requirement.service || ['sqlite', 'local', 'memory', 'lancedb'].includes(requirement.backend)) {\n serviceModes[requirement.envPrefix] = 'default'\n serviceModes[requirement.service] = 'default'\n }\n }\n options = { ...options, serviceModes }\n const plan: SidecarPlan = {\n services: [],\n composeServices: {},\n volumes: {},\n appVolumes: [],\n env: {},\n dependsOn: [],\n secrets: [],\n }\n // 全部保持不变时,连默认中间件凭据文件也不读取或创建。\n if (!scan.requiredServices.some(service => usesDefaultMiddleware(scan, service, options)))\n return plan\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 (!usesDefaultMiddleware(scan, service, options))\n continue\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 if ((backends.cache ?? 'redis') === 'redis')\n planRedisCache(plan, projectName, net)\n }\n else if (service === 'storage' && !provisionEnv.HAI_STORAGE) {\n if ((backends.storage ?? 's3') === 's3')\n planS3Storage(plan, projectName, secrets.storagePassword, net, s3Engine)\n else\n addAppDataVolume(plan, projectName)\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 else if (service === 'ldap' && backends.ldap === 'ldap' && !provisionEnv.HAI_IAM_LDAP) {\n const password = secrets.ldapPassword ?? secrets.dbPassword\n plan.services.push('ldap')\n plan.dependsOn.push('ldap')\n plan.composeServices.ldap = { image: IMAGES.ldap, restart: 'unless-stopped', env_file: ['.env.runtime'], networks: net, volumes: [`${projectName}-ldap-data:/var/lib/ldap`, `${projectName}-ldap-config:/etc/ldap/slapd.d`] }\n plan.volumes[`${projectName}-ldap-data`] = null\n plan.volumes[`${projectName}-ldap-config`] = null\n Object.assign(plan.env, { LDAP_DOMAIN: 'example.org', LDAP_ORGANISATION: 'HAI', LDAP_ADMIN_PASSWORD: password, LDAP_TLS: 'false', HAI_IAM_LOGIN_LDAP: 'true', HAI_IAM_LDAP: JSON.stringify({ url: 'ldap://ldap:389', bindDn: 'cn=admin,dc=example,dc=org', bindPassword: password, searchBase: 'dc=example,dc=org' }) })\n plan.secrets.push(password)\n }\n else if (service === 'email' && (scan.middlewares ? scan.middlewares.some(item => item.service === 'email' && item.backend === 'smtp' && (options?.serviceModes?.[item.envPrefix] ?? options?.serviceModes?.email ?? 'default') === 'default') : backends.email === 'smtp') && !provisionEnv.HAI_REACH_PROVIDERS) {\n plan.services.push('email')\n plan.dependsOn.push('email')\n plan.composeServices.email = { image: IMAGES.smtp, restart: 'unless-stopped', networks: net }\n const requirements = scan.middlewares?.filter(item => item.service === 'email' && item.backend === 'smtp' && ['default', undefined].includes(options?.serviceModes?.[item.envPrefix] ?? options?.serviceModes?.email))\n if (requirements?.length) {\n for (const requirement of requirements)\n plan.env[requirement.envPrefix] = JSON.stringify({ name: requirement.config.name ?? 'email', type: 'smtp', host: 'email', port: 1025, secure: false, from: 'noreply@example.com' })\n }\n else if (!scan.middlewares) {\n plan.env.HAI_REACH_PROVIDERS_0 = JSON.stringify({ name: 'email', type: 'smtp', host: 'email', port: 1025, secure: false, from: 'noreply@example.com' })\n }\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 options?: DeployAppOptions,\n appEnv: Record<string, string> = {},\n s3Engine: 'rustfs' | 'minio' = 'rustfs',\n): RuntimeEnvPlan {\n const sidecar = planSidecars(appDir, projectName, scan, provisionEnv, options, s3Engine)\n const env: Record<string, string> = {\n NODE_ENV: 'production',\n HOST: '0.0.0.0',\n PORT: String(containerPort),\n HAI_SERV_SERVER_HOST: '0.0.0.0',\n HAI_SERV_SERVER_PORT: String(containerPort),\n ...appEnv,\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.appVersion - 应用发布版本,例如 1.2.3;不改变持久化卷身份\n * @param options.hostPort - 宿主机映射端口\n * @param options.containerPort - 容器内端口\n * @param options.sidecar - sidecar 规划\n * @param options.web - 同一编排中的 Web 镜像与监听端口,独立于私有应用环境\n * @param options.web.imageRef - Web 镜像引用\n * @param options.web.containerPort - Web 容器监听端口\n * @returns compose YAML 字符串\n */\nexport function generateComposeFile(options: {\n projectName: string\n appVersion: string\n imageRef: string\n hostPort: number\n containerPort: number\n sidecar: SidecarPlan\n /** Web 公开入口;私有运行环境仅属于 API 服务。 */\n web?: { imageRef: string, containerPort: number }\n}): string {\n const { projectName, imageRef, hostPort, containerPort, sidecar } = options\n\n const app: ComposeService = {\n image: imageRef,\n labels: { 'org.opencontainers.image.version': options.appVersion },\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 services: Record<string, ComposeService> = { app, ...sidecar.composeServices }\n if (options.web) {\n delete app.ports\n services.web = {\n image: options.web.imageRef,\n labels: { 'org.opencontainers.image.version': options.appVersion },\n container_name: `hai-${projectName}-web`,\n restart: 'unless-stopped',\n pull_policy: 'never',\n ports: [`${hostPort}:${options.web.containerPort}`],\n environment: { PUBLIC_API_BASE: '' },\n healthcheck: { test: ['CMD', 'wget', '-Y', 'off', '-q', '-O', '/dev/null', `http://127.0.0.1:${options.web.containerPort}/_hai/web-health`], interval: '30s', timeout: '5s', retries: 3 },\n volumes: ['./web.conf:/etc/nginx/conf.d/default.conf:ro'],\n depends_on: ['app'],\n networks: ['hai-app'],\n }\n }\n if (services['storage-init'])\n services['storage-init'] = { ...services['storage-init'], image: imageRef }\n const compose: Record<string, unknown> = {\n 'x-hai-version': options.appVersion,\n services,\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 // S3 服务启动不等于桶已创建;初始化失败必须阻止应用启动,不能只依靠 HTTP 健康检查。\n if (services['storage-init']) {\n app.depends_on = {\n ...Object.fromEntries((app.depends_on as string[] | undefined ?? []).map(name => [name, { condition: 'service_started' }])),\n 'storage-init': { condition: 'service_completed_successfully' },\n }\n }\n\n for (const service of Object.values(services))\n service.pull_policy = 'never'\n return stringify(compose)\n}\n\n/**\n * 生成同源 Web/API 的 Nginx 配置,保留运行时配置及 SPA 页面刷新。\n * @param port - API 容器监听端口\n * @param apiPrefix - 应用实际 API 前缀,不允许向 Nginx 配置注入指令\n * @param webPort - Web 容器监听端口\n * @returns 仅含公开路由的 Nginx 配置\n * @example `generateWebProxyConfig(3000, '/api/v1')`\n */\nexport function generateWebProxyConfig(port: number, apiPrefix: string, webPort = 8080): string {\n if (!/^\\/[\\w/-]+$/.test(apiPrefix) || ![port, webPort].every(value => Number.isInteger(value) && value >= 1 && value <= 65535))\n throw new Error('Invalid web proxy target')\n return `server {\n listen ${webPort};\n server_name _;\n root /usr/share/nginx/html;\n location / {\n try_files $uri $uri/ /index.html;\n }\n location = /runtime-config.js {\n add_header Cache-Control \"no-store\";\n default_type application/javascript;\n return 200 'globalThis.__HAI_PUBLIC_CONFIG__={apiBase:globalThis.location.origin+\"${apiPrefix}\"};';\n }\n location = /_hai/web-health {\n access_log off;\n return 200 'ok';\n }\n location = /health {\n proxy_pass http://app:${port};\n proxy_set_header Host $http_host;\n }\n location ${apiPrefix.replace(/\\/$/, '')}/ {\n proxy_pass http://app:${port};\n proxy_http_version 1.1;\n proxy_set_header Host $http_host;\n proxy_set_header X-Forwarded-Proto $scheme;\n proxy_buffering off;\n }\n}\n`\n}\n\n/** 将环境变量对象序列化为 .env.runtime 内容(每行 KEY=VALUE)。 */\nexport function serializeEnvFile(env: Record<string, string>): string {\n return `${Object.entries(env)\n .map(([key, value]) => {\n let literal = value\n if (/[\\s#$'\"]/.test(value)) {\n if (value.startsWith('{') || value.startsWith('['))\n literal = `'${value.replaceAll('\\'', '\\\\u0027')}'`\n else if (!value.includes('\\''))\n literal = `'${value}'`\n else\n literal = JSON.stringify(value).replaceAll('$', '$$')\n }\n return `${key}=${literal}`\n })\n .join('\\n')}\\n`\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[], onOutput?: (output: string) => void }) => 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.includes(':') ? `[${config.host}]` : 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 onOutput: options?.onOutput,\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 的通用主机部署:消费已有镜像 → tar 打包 → 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 { DeployConfig, DockerSshProviderConfig } from '../deploy-config.js'\nimport type { DeployResult } from '../deploy-types.js'\nimport { randomBytes } from 'node:crypto'\nimport { chmodSync, mkdirSync, writeFileSync } from 'node:fs'\nimport { basename, join } from 'node:path'\nimport { core, err, ok } from '@h-ai/core'\nimport { createDeploymentBundle } from '../container/deploy-bundle.js'\nimport { maskSecrets } from '../container/deploy-command.js'\nimport {\n buildRuntimeEnv,\n generateComposeFile,\n generateWebProxyConfig,\n serializeEnvFile,\n} from '../container/deploy-container-compose.js'\nimport { shellArgument } from '../container/deploy-scripts.js'\nimport { createSshExecutor } from '../container/deploy-ssh.js'\nimport { loadDeploymentConfig, loadDeploymentEnvironment, saveDeploymentEnvironment } from '../deploy-environment.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/** 睡眠指定毫秒。 */\nfunction sleep(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms))\n}\n\n/**\n * 创建 docker-ssh 部署 Provider。\n *\n * @param config - docker-ssh Provider 配置\n * @param container - Compose 中间件参数\n * @returns 容器部署 Provider 实例\n */\nexport function createDockerSshProvider(\n config: DockerSshProviderConfig,\n container?: DeployConfig['container'],\n): ContainerDeployProvider {\n const ssh = config.ssh ? createSshExecutor(config.ssh) : undefined\n const baseDir = config.remote.baseDir\n\n /** 探测远程容器运行时与 compose 可用性。 */\n async function detectRemoteRuntime(): Promise<HaiResult<ContainerRuntime>> {\n if (!ssh)\n return err(HaiDeployError.CONFIG_ERROR, deployM('deploy_sshRequired'))\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, appEnv, options } = context\n const deploymentId = makeDeploymentId()\n const hostPort = config.expose.hostPort\n const artifactDir = join(appDir, '.hai', 'deploy', options?.environment ?? 'prod')\n mkdirSync(artifactDir, { recursive: true, mode: 0o700 })\n chmodSync(artifactDir, 0o700)\n const artifact = context.artifact\n const resolvedBuildDir = context.artifactDir\n const images = artifact.images\n const web = images.find(image => image.name === 'web')\n const app = images.find(image => image.name === 'app')\n if (options?.selectedServices) {\n const available: string[] = [...images.map(image => image.name), ...scan.requiredServices]\n const invalid = options.selectedServices.find(name => !available.includes(name))\n if (!options.selectedServices.length || new Set(options.selectedServices).size !== options.selectedServices.length || invalid)\n return err(HaiDeployError.CONFIG_ERROR, deployM('deploy_selectionInvalid', { params: { service: invalid ?? options.selectedServices.join(', ') } }))\n }\n const hasWeb = artifact.hasWeb || !!web\n const partial = artifact.partial || options?.selectedServices !== undefined\n const containerPort = app?.containerPort ?? artifact.appContainerPort ?? config.expose.containerPort\n const webContainerPort = web?.containerPort ?? artifact.webContainerPort ?? 8080\n const host = config.ssh?.host\n const url = host ? `http://${host.includes(':') ? `[${host}]` : host}:${hostPort}` : `http://SERVER_HOST:${hostPort}`\n\n // 先保存开通结果和 sidecar 凭据,传输失败后仍可检查与复用配置。\n const { env, sidecar } = buildRuntimeEnv(appDir, projectName, scan, provisionEnv, containerPort, options, appEnv, container?.s3Engine)\n if (sidecar.composeServices['storage-init'] && !app && options?.selectedServices?.includes('storage'))\n return err(HaiDeployError.CONFIG_ERROR, deployM('deploy_storageArtifactRequired'))\n let webProxy: string | undefined\n if (hasWeb) {\n // 路由取当前服务的真实配置,不扫描相邻应用或猜测 fullstack 布局。\n const server = loadDeploymentConfig('serv', join(appDir, 'config', '_serv.yml'), env)\n if (!server.success)\n return server\n const http = server.data.http as { apiPrefix?: string } | undefined\n const cors = server.data.cors as { origin?: string } | undefined\n const apiPrefix = http?.apiPrefix ?? '/api/v1'\n if (typeof apiPrefix !== 'string' || !/^\\/[\\w/-]+$/.test(apiPrefix))\n return err(HaiDeployError.CONFIG_ERROR, deployM('deploy_webProxyInvalid'))\n webProxy = generateWebProxyConfig(containerPort, apiPrefix, webContainerPort)\n // 每次从当前配置生成,避免上次运行环境里的父对象遮蔽新修改;保留明确 Origin。\n env.HAI_SERV = JSON.stringify({ ...server.data, cors: { ...cors, origin: (!cors?.origin || cors.origin === '*') && config.ssh ? url : cors?.origin ?? '*' } })\n }\n const envPath = join(artifactDir, '.env.runtime')\n writeFileSync(envPath, serializeEnvFile(env), { mode: 0o600 })\n if (options?.environment) {\n const environment = loadDeploymentEnvironment({ environment: options.environment, envDir: options.envDir ?? scan.envDir ?? appDir })\n if (!environment.success)\n return environment\n const saved = saveDeploymentEnvironment(environment.data, { HAI_DEPLOY_ENVIRONMENT: environment.data.environment, HAI_CORE_ENV: environment.data.values.HAI_CORE_ENV, ...sidecar.env, ...provisionEnv })\n if (!saved.success)\n return saved\n }\n\n const composeName = `docker-compose-${artifact.appVersion}.yml`\n const composeContent = generateComposeFile({\n projectName,\n appVersion: artifact.appVersion,\n imageRef: app?.imageRef ?? 'localhost/hai-unselected:0',\n hostPort,\n containerPort,\n sidecar,\n web: hasWeb ? { imageRef: web?.imageRef ?? 'localhost/hai-unselected:0', containerPort: webContainerPort } : undefined,\n })\n const composePath = join(artifactDir, composeName)\n writeFileSync(composePath, composeContent)\n if (webProxy)\n writeFileSync(join(artifactDir, 'web.conf'), webProxy)\n const selected = options?.selectedServices ? [...options.selectedServices] : artifact.partial ? images.map(image => image.name) : [...images.map(image => image.name), ...Object.keys(sidecar.composeServices)]\n if (!selected.length || selected.some(name => !/^[a-z][a-z0-9-]*$/.test(name)) || new Set(selected).size !== selected.length)\n return err(HaiDeployError.CONFIG_ERROR, deployM('deploy_selectionInvalid', { params: { service: selected.join(', ') } }))\n for (const name of selected) {\n if (['app', 'web'].includes(name) && !images.some(image => image.name === name))\n return err(HaiDeployError.CONFIG_ERROR, deployM('deploy_selectionInvalid', { params: { service: name } }))\n }\n if (selected.includes('storage') && sidecar.composeServices['storage-init'] && !selected.includes('storage-init'))\n selected.push('storage-init')\n options?.onProgress?.('packaging')\n const bundle = await createDeploymentBundle({\n directory: artifactDir,\n artifactDir: resolvedBuildDir,\n artifact,\n projectName,\n environment: options?.environment ?? 'prod',\n deploymentId,\n config,\n runtime: options?.runtime ?? 'auto',\n selected,\n partial,\n hasWeb,\n containerPort,\n middlewareEnv: serializeEnvFile(sidecar.env),\n healthPaths: hasWeb ? ['/health', '/_hai/web-health', '/'] : [scan.isSvelteKit ? '/' : '/health'],\n output: options?.output ?? join(artifactDir, `bundle-${projectName}-${deploymentId}-${artifact.appVersion}.tar`),\n })\n if (options?.bundleOnly)\n return ok({ url: '', deploymentId, status: 'packaged', provider: 'docker-ssh', healthCheck: 'skipped', envVarsSet: Object.keys(env), ...bundle })\n if (!ssh)\n return err(HaiDeployError.CONFIG_ERROR, deployM('deploy_sshRequired'))\n const ping = await ssh.ping()\n if (!ping.success)\n return ping\n const remoteRuntime = await detectRemoteRuntime()\n if (!remoteRuntime.success)\n return remoteRuntime\n const remoteDir = `${baseDir}/${projectName}`\n const remoteTar = `${remoteDir}/incoming/${basename(bundle.bundlePath)}`\n const prepared = await ssh.exec(`mkdir -p -- ${shellArgument(`${remoteDir}/incoming`)} && chmod 700 -- ${shellArgument(remoteDir)} ${shellArgument(`${remoteDir}/incoming`)}`)\n if (!prepared.success)\n return prepared\n const uploaded = await ssh.upload(bundle.bundlePath, remoteTar)\n if (!uploaded.success)\n return uploaded\n let pendingOutput = ''\n const started = await ssh.exec(\n `mkdir -p ${shellArgument(`${remoteTar}.contents`)} && chmod 600 ${shellArgument(remoteTar)} && tar -xf ${shellArgument(remoteTar)} -C ${shellArgument(`${remoteTar}.contents`)} && sh ${shellArgument(`${remoteTar}.contents/${bundle.startName}`)} ${shellArgument(remoteDir)}`,\n { timeoutMs: 600_000, secrets: sidecar.secrets, onOutput: (output) => {\n pendingOutput += output\n const lines = pendingOutput.split('\\n')\n pendingOutput = lines.pop() ?? ''\n for (const line of lines) {\n const stage = /^\\[(preflight|images|dependencies|start|health|complete)\\]/.exec(line)?.[1]\n if (stage)\n options?.onProgress?.(stage as 'preflight' | 'images' | 'dependencies' | 'start' | 'health' | 'complete')\n }\n } },\n )\n if (!started.success)\n return started\n\n // 在线部署完成后检查实际公开入口。\n logger.info('Running health check', { url })\n const healthy = await healthCheck(`${url}${!hasWeb && scan.isSvelteKit ? '/' : '/health'}`)\n && (!hasWeb || (await healthCheck(`${url}/_hai/web-health`) && 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 bundlePath: bundle.bundlePath,\n }\n logger.info('docker-ssh deployment complete', { url, deploymentId })\n return ok(result)\n }\n\n const deploySafely: ContainerDeployProvider['deploy'] = async (context) => {\n try {\n return await deploy(context)\n }\n catch (error) {\n logger.error('Deployment bundle failed', { error })\n const reason = error instanceof Error ? error.message : String(error)\n return err(HaiDeployError.DEPLOY_FAILED, deployM('deploy_bundleFailed', { params: { reason: maskSecrets(reason, Object.values(context.appEnv ?? {}).filter(value => value.length > 6)) } }), error)\n }\n }\n return { name: 'docker-ssh', deploy: deploySafely }\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 // 只接受 Build Output API v3;不把普通源码交给平台重新构建。\n const outputConfig = JSON.parse(readFileSync(join(outputDir, 'config.json'), 'utf8')) as { version?: unknown }\n if (outputConfig.version !== 3)\n return err(HaiDeployError.CONFIG_ERROR, deployM('deploy_artifactInvalid'))\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: `.vercel/output/${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?prebuilt=1',\n {\n method: 'POST',\n body: JSON.stringify({\n name: projectId,\n files,\n version: 2,\n project: projectId,\n projectSettings: { framework: null, buildCommand: '', installCommand: '' },\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 DeployScanOptions,\n ProvisionResult,\n ScanResult,\n ServiceType,\n} from './deploy-types.js'\nimport { existsSync, readFileSync } from 'node:fs'\nimport { join } from 'node:path'\nimport { core, err, ok } from '@h-ai/core'\nimport { readDeploymentArtifact } from './deploy-artifact.js'\nimport { DeployConfigSchema } from './deploy-config.js'\nimport {\n getCredentialsPath,\n loadCredentials,\n saveCredential,\n saveCredentials,\n} from './deploy-credentials.js'\nimport { loadDeploymentEnvironment, saveDeploymentEnvironment } from './deploy-environment.js'\nimport { resolveArtifactDirectory, resolveOutputDir, usesDefaultMiddleware } 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[], scan?: ScanResult, options?: DeployAppOptions): Record<string, string> {\n let env: Record<string, string> = {}\n const reachRequirements = scan?.middlewares?.filter(item => item.configName === 'reach') ?? []\n const reachProviders: unknown[] = reachRequirements.map(item => item.config)\n let hasReachOutput = false\n for (const prov of results) {\n if (prov.envVars.HAI_REACH_PROVIDERS) {\n hasReachOutput = true\n const supplied = JSON.parse(prov.envVars.HAI_REACH_PROVIDERS) as Record<string, unknown>[]\n for (const provider of supplied) {\n const targets = reachRequirements.filter((item) => {\n const mode = options?.serviceModes?.[item.envPrefix] ?? options?.serviceModes?.[item.service]\n return item.service === prov.serviceType && (!mode || mode === 'default')\n })\n if (targets.length) {\n for (const target of targets)\n reachProviders[reachRequirements.indexOf(target)] = { ...provider, name: target.config.name ?? provider.name }\n }\n else {\n reachProviders.push(provider)\n }\n }\n }\n env = { ...env, ...prov.envVars }\n }\n if (hasReachOutput)\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)\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, options?: DeployScanOptions): Promise<HaiResult<ScanResult>> {\n // scan 仅做本地文件分析,不依赖 Provider / Provisioner 初始化状态。\n logger.debug('Scanning application', { appDir })\n return scanApp(appDir, options)\n },\n\n async provisionAll(projectName: string, services?: ServiceType[]): 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 if (services && !services.includes(serviceType))\n continue\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, environment: options?.environment, projectName: options?.projectName })\n\n // 1. 扫描应用\n const scanOptions = { ...options, environment: options?.environment ?? currentConfig?.environment }\n const scanResult = await scanApp(appDir, scanOptions)\n if (!scanResult.success) {\n return err(scanResult.error)\n }\n const scan = scanResult.data\n appDir = scan.appDir ?? appDir\n const environment = loadDeploymentEnvironment({ environment: scanOptions.environment ?? 'prod', envDir: scan.envDir ?? appDir, requireFile: scanOptions.environment !== undefined })\n if (!environment.success)\n return environment\n const appEnv = Object.fromEntries(Object.entries(environment.data.values).filter(([key]) => !key.startsWith('HAI_CLI_') && (!key.startsWith('HAI_DEPLOY_') || key === 'HAI_DEPLOY_ENVIRONMENT')))\n const projectName = `${options?.projectName ?? scan.appName}${scanOptions.environment ? `-${environment.data.environment}` : ''}`\n options = {\n ...options,\n ...(scanOptions.environment ? { environment: environment.data.environment } : {}),\n ...(options?.skipMiddleware ? { serviceModes: Object.fromEntries(scan.requiredServices.map(service => [service, 'keep' as const])) } : {}),\n }\n if (options.selectedServices) {\n options.serviceModes = {\n ...options.serviceModes,\n ...Object.fromEntries(scan.requiredServices.filter(service => !options.selectedServices!.includes(service)).map(service => [service, 'keep' as const])),\n }\n }\n\n // 容器 Provider(docker-ssh):走独立的容器部署编排\n if (currentContainerProvider) {\n return deployContainerApp(currentContainerProvider, appDir, scan, projectName, options, appEnv)\n }\n\n if (options?.bundleOnly)\n return err(HaiDeployError.CONFIG_ERROR, deployM('deploy_bundleOnlyContainer'))\n if (options.selectedServices)\n return err(HaiDeployError.CONFIG_ERROR, deployM('deploy_selectedContainerOnly'))\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 if (!existsSync(resolveOutputDir(appDir, 'vercel')))\n return err(HaiDeployError.CONFIG_ERROR, deployM('deploy_artifactInvalid'))\n\n // 3. 开通基础设施\n let allEnvVars: Record<string, string> = appEnv\n const recovery: DeployRecoveryInfo = { projectName, stage: 'provision', resources: [] }\n if (!options?.skipMiddleware) {\n const provResults = await deploy.provisionAll(projectName, options?.serviceModes ? scan.requiredServices.filter(service => usesDefaultMiddleware(scan, service, options)) : undefined)\n if (!provResults.success) {\n return err(provResults.error)\n }\n recovery.resources = provResults.data.map(({ envVars: _envVars, ...resource }) => resource)\n allEnvVars = { ...allEnvVars, ...mergeProvisionEnv(provResults.data, scan, options) }\n if (options?.environment) {\n const saved = saveDeploymentEnvironment(environment.data, mergeProvisionEnv(provResults.data, scan, options))\n if (!saved.success)\n return recoveryFailure(saved.error, { ...recovery, stage: 'save-env' })\n }\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 // 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 appEnv: Record<string, string> = {},\n): Promise<HaiResult<DeployResult>> {\n const projectName = normalizeProjectName(rawProjectName)\n\n let artifact\n let artifactDir = options?.artifactDir ?? resolveArtifactDirectory(appDir)\n try {\n if (existsSync(join(artifactDir, 'latest'))) {\n const latest = readFileSync(join(artifactDir, 'latest'), 'utf8').trim()\n if (!/^[a-z0-9][\\w.+-]*$/i.test(latest))\n throw new Error('Invalid artifact pointer')\n artifactDir = join(artifactDir, latest)\n }\n artifact = await readDeploymentArtifact(artifactDir)\n }\n catch {\n return err(HaiDeployError.CONFIG_ERROR, deployM('deploy_artifactInvalid'))\n }\n if (artifact.partial && !options?.selectedServices) {\n const selectedServices = artifact.images.map(image => image.name)\n options = {\n ...options,\n selectedServices,\n serviceModes: {\n ...options?.serviceModes,\n ...Object.fromEntries(scan.requiredServices.map(service => [service, 'keep' as const])),\n },\n }\n }\n if (!options?.bundleOnly && currentConfig?.provider.type === 'docker-ssh' && !currentConfig.provider.ssh)\n return err(HaiDeployError.CONFIG_ERROR, deployM('deploy_sshRequired'))\n\n let provisionEnv: Record<string, string> = {}\n if (!options?.skipMiddleware) {\n const provResults = await deploy.provisionAll(projectName, options?.serviceModes ? scan.requiredServices.filter(service => usesDefaultMiddleware(scan, service, options)) : undefined)\n if (!provResults.success) {\n return err(provResults.error)\n }\n provisionEnv = mergeProvisionEnv(provResults.data, scan, options)\n }\n\n return provider.deploy({ appDir, artifact, artifactDir, projectName, scan, provisionEnv, appEnv, options })\n}\n","/**\n * 部署中间件的后端与连接字段目录,供扫描、CLI 和容器规划共同使用。\n * 字段名与对应模块公开 Schema 保持一致,不把模块依赖等同于必须创建外部服务。\n * @module deploy-middleware\n */\nimport type { ServiceType } from './deploy-types.js'\nimport { deployM } from './deploy-i18n.js'\n\n/** 连接字段;例如 `{ name: 'port', defaultValue: '5432', kind: 'port' }`。 */\nexport interface MiddlewareField {\n /** 模块配置字段名,camelCase 不拆词。 */\n name: string\n /** 无现有配置时使用的提示默认值。 */\n defaultValue?: string\n /** 是否为连接所必需;可选项允许留空。 */\n required?: boolean\n /** 密码输入与私有环境文件写入标记。 */\n secret?: boolean\n /** 交互校验类型;端口范围为 1–65535。 */\n kind?: 'port' | 'boolean' | 'number' | 'url'\n /** 数值下限;未声明时为 0。 */\n minimum?: number\n /** 数值上限;例如 Redis db 为 15。 */\n maximum?: number\n}\n\n/** 后端目录项;例如 PostgreSQL 对应 `backend: 'postgresql'`。 */\nexport interface MiddlewareBackend {\n /** 模块 Schema 接受的后端标识。 */\n backend: string\n /** 可直接识别的产品名称。 */\n label: string\n /** 用途说明的 i18n 消息键。 */\n purpose: Parameters<typeof deployM>[0]\n /** 云自动开通器;缺失表示不能自动开通该云服务。 */\n provisioner?: 'neon' | 'upstash' | 'cloudflare-r2' | 'resend' | 'aliyun'\n /** 自定义连接需要逐项输入的字段。 */\n fields: MiddlewareField[]\n}\n\nconst field = (name: string, defaultValue?: string, kind?: MiddlewareField['kind'], secret = false): MiddlewareField => ({ name, defaultValue, kind, secret })\nconst required = (name: string, defaultValue?: string, kind?: MiddlewareField['kind']): MiddlewareField => ({ ...field(name, defaultValue, kind), required: true })\n\n/**\n * 所有可部署中间件的连接目录。\n * SQLite、memory、local 与 disabled 保留本地/禁用语义,不创建无关 sidecar。\n * @example `DEPLOY_MIDDLEWARE.db.map(item => item.label)` 返回数据库选择项。\n */\nexport const DEPLOY_MIDDLEWARE: Record<ServiceType, MiddlewareBackend[]> = {\n db: [\n { backend: 'sqlite', label: 'SQLite', purpose: 'deploy_purposeSqlite', fields: [required('database', './data/app.db')] },\n ...(['postgresql', 'mysql'] as const).map(backend => ({\n backend,\n label: backend === 'mysql' ? 'MySQL' : 'PostgreSQL',\n purpose: 'deploy_purposeDatabase' as const,\n provisioner: backend === 'postgresql' ? 'neon' as const : undefined,\n fields: [field('url', '', 'url', true), required('host', 'localhost'), required('port', backend === 'mysql' ? '3306' : '5432', 'port'), required('database', 'hai'), field('user', 'hai'), field('password', '', undefined, true), field('ssl', 'false')],\n })),\n ],\n cache: [\n { backend: 'memory', label: 'Memory', purpose: 'deploy_purposeMemory', fields: [] },\n { backend: 'redis', label: 'Redis', purpose: 'deploy_purposeCache', provisioner: 'upstash', fields: [field('url', '', 'url', true), required('host', 'localhost'), required('port', '6379', 'port'), field('password', '', undefined, true), { ...field('db', '0', 'number'), maximum: 15 }, field('tls', 'false', 'boolean'), field('keyPrefix'), field('connectTimeout', '10000', 'number'), field('commandTimeout', '5000', 'number')] },\n ],\n storage: [\n { backend: 'local', label: 'Local filesystem', purpose: 'deploy_purposeLocal', fields: [required('root', './data/storage')] },\n { backend: 's3', label: 'S3 / RustFS / MinIO / Cloudflare R2', purpose: 'deploy_purposeStorage', provisioner: 'cloudflare-r2', fields: [field('endpoint', '', 'url'), required('bucket', 'hai'), required('region', 'us-east-1'), required('accessKeyId'), { ...required('secretAccessKey'), secret: true }, field('forcePathStyle', 'true', 'boolean')] },\n ],\n vecdb: [\n { backend: 'lancedb', label: 'LanceDB', purpose: 'deploy_purposeLocal', fields: [required('path', './data/vectors')] },\n { backend: 'qdrant', label: 'Qdrant', purpose: 'deploy_purposeVector', fields: [required('url', 'http://localhost:6333', 'url'), field('apiKey', '', undefined, true)] },\n { backend: 'pgvector', label: 'PostgreSQL / pgvector', purpose: 'deploy_purposeVector', fields: [field('url', '', 'url', true), required('host', 'localhost'), required('port', '5432', 'port'), required('database', 'hai'), field('user', 'hai'), field('password', '', undefined, true)] },\n { backend: 'chroma', label: 'Chroma', purpose: 'deploy_purposeVector', fields: [required('url', 'http://localhost:8000', 'url')] },\n ],\n ldap: [\n { backend: 'disabled', label: 'Disabled', purpose: 'deploy_purposeDisabled', fields: [] },\n { backend: 'ldap', label: 'LDAP / OpenLDAP', purpose: 'deploy_purposeLdap', fields: [required('url', 'ldap://localhost:389', 'url'), required('bindDn', 'cn=admin,dc=example,dc=org'), { ...required('bindPassword'), secret: true }, required('searchBase', 'dc=example,dc=org'), field('searchFilter', '(uid={{username}})'), field('usernameAttribute', 'uid'), field('emailAttribute', 'mail'), field('displayNameAttribute', 'cn'), field('useTls', 'false', 'boolean'), { ...field('connectTimeout', '5000', 'number'), minimum: 1000 }] },\n ],\n email: [\n { backend: 'console', label: 'Console', purpose: 'deploy_purposeConsole', fields: [] },\n { backend: 'smtp', label: 'SMTP', purpose: 'deploy_purposeEmail', provisioner: 'resend', fields: [required('host', 'localhost'), required('port', '465', 'port'), field('secure', 'true', 'boolean'), field('user'), field('pass', '', undefined, true), required('from', 'noreply@example.com')] },\n { backend: 'api', label: 'HTTP notification API', purpose: 'deploy_purposeEmail', fields: [required('url', '', 'url'), field('method', 'POST'), field('headers'), field('timeout', '10000', 'number')] },\n ],\n sms: [\n { backend: 'aliyun-sms', label: 'Aliyun SMS', purpose: 'deploy_purposeSms', provisioner: 'aliyun', fields: [required('accessKeyId'), { ...required('accessKeySecret'), secret: true }, required('signName'), field('endpoint', 'dysmsapi.aliyuncs.com')] },\n ],\n}\n\n/**\n * 返回当前语言的后端用途说明。\n * @example `describeMiddlewareBackend(DEPLOY_MIDDLEWARE.db[0])`\n */\nexport function describeMiddlewareBackend(backend: MiddlewareBackend): string {\n return deployM(backend.purpose)\n}\n"]}
|