chore: 初始化仓库

This commit is contained in:
Lydanne
2026-02-15 22:02:21 +08:00
commit 08d011d63f
381 changed files with 87202 additions and 0 deletions

156
docs/advanced/i18n.md Normal file
View File

@@ -0,0 +1,156 @@
# i18n 国际化
Spaceflow 基于 [i18next](https://www.i18next.com/) 实现国际化,采用纯函数式设计,不依赖 NestJS DI。
## 语言检测优先级
1. 环境变量 `SPACEFLOW_LANG`
2. `spaceflow.json` 中的 `lang` 字段
3. 系统 locale`process.env.LANG` / `process.env.LC_ALL`
4. 回退到 `zh-CN`
## 核心 API
### `initI18n(lang?: string)`
同步初始化 i18next。必须在 NestJS 模块加载前调用。
```typescript
import { initI18n } from "@spaceflow/core";
initI18n(); // 自动检测语言
initI18n("en"); // 手动指定
```
### `t(key: string, options?: Record<string, unknown>)`
全局翻译函数,装饰器和运行时均可使用。
```typescript
import { t } from "@spaceflow/core";
// 公共 key默认命名空间
t("common.executionFailed", { error: msg });
// Extension 命名空间(用 : 分隔)
t("build:description");
t("review:options.dryRun");
```
### `addLocaleResources(ns: string, resources: Record<string, Record<string, string>>)`
注册 Extension 的语言资源到指定命名空间。
```typescript
import { addLocaleResources } from "@spaceflow/core";
addLocaleResources("hello", {
"zh-CN": { description: "打招呼命令" },
en: { description: "Say hello" },
});
```
## 命名空间规则
| 类型 | 命名空间 | 示例 |
|------|----------|------|
| 公共 key | 默认(`translation` | `common.*`, `config.*`, `extensionLoader.*` |
| 内部 Extension | Extension 名称 | `build:`, `dev:`, `commit:`, `install:` 等 |
| 外部 Extension | Extension 名称 | `review:`, `publish:`, `ci-scripts:` 等 |
## 语言包结构
### core 公共语言包
```text
core/src/locales/
├── zh-cn/
│ └── translation.json # 公共 key
└── en/
└── translation.json
```
### Extension 语言包
```text
cli/src/commands/<name>/locales/
├── zh-cn/
│ └── <name>.json
├── en/
│ └── <name>.json
└── index.ts # 导入并注册资源
```
## Extension 中使用 i18n
### 1. 创建语言包文件
```json
// locales/zh-cn/hello.json
{
"description": "打招呼命令",
"options.name": "名字",
"greeting": "你好,{{name}}"
}
```
### 2. 注册语言资源
```typescript
// locales/index.ts
import zhCN from "./zh-cn/hello.json";
import en from "./en/hello.json";
import { addLocaleResources } from "@spaceflow/core";
export const helloLocales = { "zh-CN": zhCN, en };
// Side-effect: 立即注册
addLocaleResources("hello", helloLocales);
```
### 3. 在命令中使用
```typescript
import { t } from "@spaceflow/core";
// 必须在命令模块 import 之前导入 localesside-effect
import "./locales";
@Command({
name: "hello",
description: t("hello:description"),
})
export class HelloCommand extends CommandRunner {
// ...
}
```
### 4. 在 Extension 入口声明
```typescript
export class HelloExtension implements SpaceflowExtension {
getMetadata(): SpaceflowExtensionMetadata {
return {
name: "hello",
commands: ["hello"],
locales: helloLocales, // 加载时自动注册
};
}
}
```
## 插值语法
使用 i18next 默认的 `{{variable}}` 语法:
```typescript
t("hello:greeting", { name: "World" });
// → "你好World"
```
## 注意事项
- **同步初始化** — `initI18n()` 使用 `initSync`,确保装饰器执行时语言包已加载
- **装饰器时机** — `@Command` / `@Option` 在 import 时执行,`initI18n()` 必须在所有命令模块 import 之前调用
- **Side-effect import** — 每个 Extension 的 `locales/index.ts` 在导入时立即调用 `addLocaleResources`
- **key 不存在时** — i18next 默认返回 key 本身,不会报错