Novu CLI 翻译管理实战指南:用 translations pull/push 命令同步多语言资源
【免费下载链接】novuThe open-source communication infrastructure for agents and products项目地址: https://gitcode.com/GitHub_Trending/no/novu
导读
本文聚焦 Novu 官方 CLI 提供的novu translations pull与novu translations push两个命令,讲解如何将 Novu Cloud 工作区中的多语言翻译资源下载到本地、以及如何将本地维护的翻译文件批量上传回云端。读完本文,你将掌握完整的参数用法、文件命名与 JSON 格式规范、环境变量配置方式,并理解 CLI 底层的 API 调用链与错误处理机制,可直接用于实际项目的翻译资产版本化管理。
命令概览:translations 子命令的定位
在 Novu CLI 中,translations是一个顶层子命令,内部又挂载了pull与push两个子命令。其命令注册位于 packages/novu/src/index.ts:
const translationsCommand = program.command('translations').description('Manage Novu translations'); translationsCommand .command('pull') .description('Pull all translation files from Novu Cloud') .option('-s, --secret-key <secret-key>', 'The Novu Secret Key', NOVU_SECRET_KEY || '') .option('-a, --api-url <url>', 'The Novu Cloud API URL', NOVU_API_URL || 'https://api.novu.co') .option('-d, --directory <path>', 'Directory to save translation files', './translations') .action(async (options) => { /* ... */ }); translationsCommand .command('push') .description('Push translation files to Novu Cloud') .option('-s, --secret-key <secret-key>', 'The Novu Secret Key', NOVU_SECRET_KEY || '') .option('-a, --api-url <url>', 'The Novu Cloud API URL', NOVU_API_URL || 'https://api.novu.co') .option('-d, --directory <path>', 'Directory containing translation files', './translations') .action(async (options) => { /* ... */ });三个选项与文档中的说明完全对应,其默认值均由 CLI 入口处定义:
-s, --secret-key:必填,用于身份认证;-a, --api-url:默认https://api.novu.co(可通过环境变量NOVU_API_URL覆盖,详见下文);-d, --directory:默认./translations。
从 packages/novu/src/commands/index.ts 可以看到,translations模块与dev、wizard一起从命令层导出,而 packages/novu/src/index.ts 中通过import { pullTranslations, pushTranslations } from './commands/translations'接入 CLI 主入口,最终由 Commander 框架统一解析执行。
命令一:novu translations pull(下载翻译文件)
pull命令用于将 Novu Cloud 中已配置的所有语言翻译文件下载到本地目录,是了解云端翻译资产结构、以及将翻译纳入版本控制的第一步。
基础用法
# 拉取翻译到默认目录(./translations) npx novu pull -s YOUR_SECRET_KEY # 拉取到自定义目录 npx novu pull -s YOUR_SECRET_KEY -d ./my-translations # 使用 EU API 端点 npx novu pull -s YOUR_SECRET_KEY -a https://eu.api.novu.co(注:与 README 一致,完整命令形式为npx novu translations pull,npx novu pull仅是便于口述的简写,实际执行请使用下文完整形式。)
# 完整形式:拉取到默认目录 npx novu translations pull -s YOUR_SECRET_KEY # 拉取到自定义目录 npx novu translations pull -s YOUR_SECRET_KEY -d ./my-translations # 使用 EU API 端点 npx novu translations pull -s YOUR_SECRET_KEY -a https://eu.api.novu.co参数说明
| 参数 | 说明 | 默认值 |
|---|---|---|
-s, --secret-key <key> | Novu Secret Key(必填) | 无 |
-a, --api-url <url> | Novu API 地址 | https://api.novu.co |
-d, --directory <path> | 保存文件的目录 | ./translations |
底层执行流程
pull命令的实现位于 packages/novu/src/commands/translations/pull.ts,其完整流程为:
- 校验 Secret Key:若未通过
-s或环境变量提供密钥,直接抛出错误Secret key is required. Use -s flag or set NOVU_SECRET_KEY environment variable.; - 校验连接:调用
client.validateConnection(),实际请求GET {apiUrl}/v1/users/me(见 client.ts),用于提前发现 API Key 无效或网络不通等问题; - 获取组织语言设置:调用
GET {apiUrl}/v1/organizations/settings,从响应中读取defaultLocale与targetLocales(见 types.ts),合并去重后得到需要拉取的语言列表; - 逐个语言下载:对每个 locale 调用
GET {apiUrl}/v2/translations/master-json?locale={locale}(见 client.ts),将返回的 JSON 内容以{locale}.json文件名写入目标目录; - 输出汇总:打印成功拉取的语言数量、各文件大小(通过
formatFileSize格式化,见 utils.ts)以及错误详情。
其中值得注意的两个细节:
- 默认语言也会被拉取:
defaultLocale会被加入目标语言列表,且会通过[...new Set(targetLocales)]去重,避免默认语言与目标语言重复时产生重复下载(见 pull.ts); - 空翻译的处理:若某个 locale 返回空对象(
Object.keys(response.data).length === 0),CLI 会提示No translations available并跳过写文件,不会创建空文件(见 pull.ts)。
常见异常场景的输出
若组织尚未在 Dashboard 中开启翻译功能,拉取会失败,CLI 会明确给出引导:
🚫 Unable to fetch organization locale settings. 💡 To use translations, you need to: 1. Go to your Novu Dashboard 2. Navigate to the Translations page 3. Enable translations and configure your target locales 4. Set your default locale同时抛出Translations not configured. Please enable translations in your dashboard first.(见 pull.ts)。
命令二:novu translations push(上传翻译文件)
push命令用于将本地目录中的翻译文件上传到 Novu Cloud,实现本地编辑、云端生效的迭代闭环。
基础用法
# 从默认目录(./translations)上传 npx novu translations push -s YOUR_SECRET_KEY # 从自定义目录上传 npx novu translations push -s YOUR_SECRET_KEY -d ./my-translations # 使用 EU API 端点 npx novu translations push -s YOUR_SECRET_KEY -a https://eu.api.novu.co参数说明
| 参数 | 说明 | 默认值 |
|---|---|---|
-s, --secret-key <key> | Novu Secret Key(必填) | 无 |
-a, --api-url <url> | Novu API 地址 | https://api.novu.co |
-d, --directory <path> | 包含翻译文件的目录 | ./translations |
底层执行流程
push的实现位于 packages/novu/src/commands/translations/push.ts,流程为:
- 校验 Secret Key 与连接(与
pull一致); - 获取组织语言设置:同样读取
defaultLocale与targetLocales,得到“已配置语言”白名单; - 加载本地文件:调用
loadTranslationFiles扫描目录(见 utils.ts)——仅接受符合^([a-z]{2}(?:_[A-Z]{2})?)\.json$命名模式的文件,非法的文件名与无法解析的 JSON 文件会被跳过并给出警告; - 过滤未配置语言:本地文件中不在组织设置白名单内的 locale 会被跳过并提示
not in organization settings(见 push.ts),避免上传错误语言; - 逐个上传:对每个文件调用
POST {apiUrl}/v2/translations/master-json/upload,以multipart/form-data方式将文件作为file字段上传(见 client.ts),请求头携带Authorization: ApiKey {secretKey}; - 输出汇总:打印成功上传的文件数、每个文件导入的资源数(
successful数组长度)以及错误详情。
关于“资源数”的含义
上传响应的数据结构定义在 types.ts:
export interface UploadResponseData { success: boolean; message: string; successful?: string[]; failed?: string[]; }successful数组中的每一项对应一条成功导入的翻译资源(如某个 workflow 步骤的subject、body等),CLI 用其长度作为“imported resources”计数展示。当success为false时,会回显服务端返回的message作为失败原因。
文件格式与目录规范
命名规范
翻译文件必须以locale.json命名,locale 采用语言_地区形式(如en_US.json)。CLI 通过正则^([a-z]{2}(?:_[A-Z]{2})?)\.json$校验文件名(见 utils.ts),这意味着:
- 语言代码必须为两位小写字母(如
en、fr); - 地区代码可选,若有则必须为两位大写字母并用下划线连接(如
_US、_FR); - 不匹配该模式的文件会被直接跳过,并在终端输出警告。
一个标准的翻译目录结构:
translations/ ├── en_US.json ├── fr_FR.json ├── es_ES.json └── de_DE.jsonJSON 内容格式
翻译文件内容为嵌套 JSON 对象,顶层键通常是工作流名称,下一层是步骤,再下一层是具体的文案字段。以en_US.json为例:
{ "workflows": { "welcome": { "subject": "Welcome to our platform!", "body": "Thank you for joining us." } } }pull写入文件时使用JSON.stringify(content, null, 2)进行美化输出(见 utils.ts),因此下载下来的文件始终是 2 空格缩进的易读格式,方便直接纳入 git 做 diff 审查。push一侧对文件内容的要求是“可被JSON.parse解析”,解析失败的 JSON 文件会被跳过。
环境变量:免去重复传参
为避免在每条命令中重复传入-s与-a,CLI 支持通过环境变量注入:
export NOVU_SECRET_KEY="your_secret_key_here" export NOVU_API_URL="https://api.novu.co" # 或 EU 区域使用 https://eu.api.novu.co # 之后可以省略 -s 与 -a 直接执行 npx novu translations pull npx novu translations push其实现机制为:CLI 启动时通过dotenv依次加载.env.local与默认.env(见 packages/novu/src/constants/constants.ts),并将NOVU_API_URL、NOVU_SECRET_KEY注入进程环境。随后在命令注册处(packages/novu/src/index.ts),-s与-a的默认值会读取这两个环境变量,因此设置了环境变量后即可省略对应 flag。
可以推断的优先级规则为:命令行 flag 显式传入 > 环境变量 > 硬编码默认值https://api.novu.co。这符合 Commanderoption(..., defaultValue)的常规行为——-s的默认值是NOVU_SECRET_KEY || '',若两者皆无则为空字符串,此时会在pull/push的实现中触发“Secret key is required”错误。
支持的语言(Locale)
CLI 侧对 locale 并无硬编码白名单,理论上任何符合xx或xx_XX命名的语言都可被处理。组织实际可用的语言由 Dashboard「Translations」页面配置的targetLocales决定,文档中列出的常用 locale 包括:
en_US、en_GB(英语)es_ES(西班牙语)fr_FR(法语)de_DE(德语)it_IT(意大利语)pt_BR(葡萄牙语)ja_JP(日语)ko_KR(韩语)zh_CN、zh_TW(中文)ru_RU(俄语)ar_SA(阿拉伯语)hi_IN(印地语)
以及更多标准 locale 代码。
错误处理机制
CLI 对常见错误提供了分层、可读的提示,主要分布在 client.ts 与两个命令实现中:
| 错误场景 | 处理方式 |
|---|---|
| Secret Key 缺失 | 命令启动时抛错:Secret key is required. Use -s flag or set NOVU_SECRET_KEY environment variable. |
| API Key 无效(401) | 所有 API 调用统一转为Invalid API key. Please check your secret key. |
| 网络连接问题 | validateConnection失败时输出Connection failed并终止 |
| 拉取时某语言无翻译(404) | 转为No translations found for locale: {locale},在汇总中以No translations available提示而非报错 |
| 上传时请求格式错误(400) | 回显服务端message或error字段 |
| 上传时接口不存在(404) | 提示Upload endpoint not found. Please check your API URL. |
| 服务端异常(5xx) | 输出状态码与错误详情 |
| 本地 JSON 解析失败 | 跳过该文件并警告:Skipping invalid JSON file: {file} - {reason} |
| 目录不存在(push) | 抛错:Directory not found: {directory} |
此外,pull在全部语言拉取失败(successCount === 0)时会给出排查建议,包括:尚未上传任何翻译、API Key 无翻译权限、或 API URL 指向错误(建议 EU 区域使用-a https://eu.api.novu.co)。文件写入权限问题则由 Node.jsfs层抛出,可通过检查目标目录权限解决。
实战建议与最佳实践
- 推送前先备份:
push是覆盖式上传,建议先pull一份最新副本,或确保云端已有历史版本,再执行推送; - 推送前校验 JSON:所有待推送文件必须能被
JSON.parse解析;文件名必须符合locale.json规范,否则会被静默跳过; - 善用版本控制:将
translations/目录纳入 git 管理,利用pull生成的文件差异(2 空格缩进、稳定排序)进行 Code Review,翻译变更可追溯; - 先用 pull 验证目录结构:在执行
push前先pull一次,可确认预期的文件结构与命名,避免上传后才发现 locale 不在组织白名单中而被跳过; - CI 中注入密钥:在 CI 流水线中优先使用
NOVU_SECRET_KEY环境变量而非在命令中明文书写密钥,配合-a指定正确的区域端点(US 默认https://api.novu.co,EU 使用https://eu.api.novu.co)。
参考实现路径
- 命令注册与参数默认值:packages/novu/src/index.ts
- pull 实现:packages/novu/src/commands/translations/pull.ts
- push 实现:packages/novu/src/commands/translations/push.ts
- API 客户端(含端点与鉴权头):packages/novu/src/commands/translations/client.ts
- 类型定义:packages/novu/src/commands/translations/types.ts
- 文件读写与命名工具:packages/novu/src/commands/translations/utils.ts
- 环境变量加载:packages/novu/src/constants/constants.ts
【免费下载链接】novuThe open-source communication infrastructure for agents and products项目地址: https://gitcode.com/GitHub_Trending/no/novu
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考