-
Notifications
You must be signed in to change notification settings - Fork 11
feat(): 框架支持LANGUAGE常量
#4783
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(): 框架支持LANGUAGE常量
#4783
Conversation
Walkthrough在计算全局变量的实现中新增对“LANGUAGE”的处理逻辑,并在相关测试中引入 i18n 的 supportedLngs 配置、在评估前切换语言为 zh、更新翻译断言,以及新增验证 LANGUAGE 返回值为 zh 的用例。 Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Pre-merge checks and finishing touches❌ Failed checks (2 warnings)
✅ Passed checks (1 passed)
✨ Finishing touches
🧪 Generate unit tests
Tip 👮 Agentic pre-merge checks are now available in preview!Pro plan users can now enable pre-merge checks in their settings to enforce checklists before merging PRs.
Please see the documentation for more information. Example: reviews:
pre_merge_checks:
custom_checks:
- name: "Undocumented Breaking Changes"
mode: "warning"
instructions: |
Pass/fail criteria: All breaking changes to public APIs, CLI flags, environment variables, configuration keys, database schemas, or HTTP/GraphQL endpoints must be documented in the "Breaking Change" section of the PR description and in CHANGELOG.md. Exclude purely internal or private changes (e.g., code not exported from package entry points or explicitly marked as internal).Please share your feedback with us on this Discord post. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
🧹 Nitpick comments (5)
packages/runtime/src/internal/compute/language.ts (2)
26-30: fromEntries 的键使用了[[lng]],多包了一层数组功能虽可工作(会被字符串化),但可读性与类型均不佳,应使用
[lng, value]。应用如下微调:
- return Object.fromEntries( - lngs.map((lng) => [[lng], i18n.language === lng]) - ); + return Object.fromEntries( + lngs.map((lng) => [lng, i18n.language === lng]) + );
31-33: 确认默认兜底语义:为何固定zh: true?默认返回
{ en: false, zh: true }会在未配置任何语言时强行偏向中文。请确认这是否为产品约定;否则更自然的兜底是基于i18n.language或fallbackLng生成。如需我改成基于
fallbackLng的动态兜底,我可以直接给出改动版 diff。packages/runtime/src/internal/compute/language.spec.ts (1)
55-68: 避免直接赋值i18n.options(破坏内部不变量)多处通过重写
i18n.options来模拟场景,存在与类型定义不符及污染全局实例的风险。建议改为使用i18n.init(...)重新初始化或封装帮助函数重置配置。可改为:
- 记录原配置:
const original = { ...i18n.options };- 测试内调用
i18n.init({ ...original, supportedLngs: 'en', resources: { ... } })- 用后还原:
i18n.init(original)Also applies to: 70-84, 125-131
packages/runtime/src/internal/compute/evaluate.ts (1)
507-510: 新增全局常量 LANGUAGE 的计算分支合理 ✅按需计算并注入
getSupportedLanguages()的结果,且不引入副作用。建议在文档中补充 LANGUAGE 的可用性说明。packages/runtime/src/internal/compute/evaluate.spec.ts (1)
325-325: 新增对<% LANGUAGE %>的断言到位 ✅覆盖了基础路径,建议后续追加一个“当前语言不在 supportedLngs 中返回全 false”的集成断言(与 language.spec 相呼应)。
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Cache: Disabled due to data retention organization setting
Knowledge base: Disabled due to data retention organization setting
📒 Files selected for processing (4)
packages/runtime/src/internal/compute/evaluate.spec.ts(4 hunks)packages/runtime/src/internal/compute/evaluate.ts(2 hunks)packages/runtime/src/internal/compute/language.spec.ts(1 hunks)packages/runtime/src/internal/compute/language.ts(1 hunks)
🧰 Additional context used
🪛 GitHub Actions: CI
packages/runtime/src/internal/compute/language.ts
[error] 9-9: Command failed: tsc --emitDeclarationOnly --declaration --declarationDir dist/types --project tsconfig.build.json. TS2339: Property 'options' does not exist on type 'typeof import(/home/runner/work/next-core/next-core/node_modules/i18next/index)'.
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: update (20.x)
- GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (5)
packages/runtime/src/internal/compute/language.spec.ts (1)
48-51: 用例覆盖良好 ✅包含对
cimode过滤、空配置、仅 resources 推导与“当前语言不在列表”边界的断言,能有效保护回退与布尔映射逻辑。Also applies to: 104-116, 148-162, 182-193
packages/runtime/src/internal/compute/evaluate.ts (1)
47-47: 引入 LANGUAGE 依赖的导入位置与扩展名一致 ✅与项目现有相对导入风格保持一致(.js 扩展名),无循环依赖风险。
packages/runtime/src/internal/compute/evaluate.spec.ts (3)
85-86: 测试初始化补充 supportedLngs 合理 ✅与 LANGUAGE 行为强相关,确保解析出的语言集合可预期。
259-260: 在每个用例前切换到 zh,避免语言状态串扰 ✅
297-298: Widget I18N 期望值改为“世界”与当前语言保持一致 ✅
| import i18n from "i18next"; | ||
| import { getSupportedLanguages } from "./language"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
测试应与生产一致地复用同一 i18n 实例
生产代码应从 @next-core/i18n 获取实例,建议测试也改为相同来源,避免测试与运行时各用一套实例导致行为偏差。
应用如下 diff:
-import i18n from "i18next";
+import { i18n } from "@next-core/i18n";📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| import i18n from "i18next"; | |
| import { getSupportedLanguages } from "./language"; | |
| import { i18n } from "@next-core/i18n"; | |
| import { getSupportedLanguages } from "./language"; |
🤖 Prompt for AI Agents
In packages/runtime/src/internal/compute/language.spec.ts lines 1-2, the test
imports a fresh i18n from "i18next" which creates a separate instance from
production; change the test to import the shared i18n instance from
"@next-core/i18n" so tests and runtime reuse the same i18n instance, update the
import statement accordingly and remove the direct "i18next" import.
| @@ -0,0 +1,33 @@ | |||
| import i18n from "i18next"; | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
修复 CI:错误的 i18n 导入导致 TS2339(options 不存在)
这里从 "i18next" 默认导入拿到的是模块类型而非实例,导致 i18n.options 报错。应统一与其余代码使用同一实例:@next-core/i18n。
应用如下 diff:
-import i18n from "i18next";
+import { i18n } from "@next-core/i18n";📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| import i18n from "i18next"; | |
| import { i18n } from "@next-core/i18n"; |
🤖 Prompt for AI Agents
In packages/runtime/src/internal/compute/language.ts around line 1, the file
currently imports the i18next module instead of the shared i18n instance which
causes TS2339 when accessing i18n.options; update the import to use the
project-wide instance by replacing `import i18n from "i18next";` with `import
i18n from "@next-core/i18n";` so the code uses the same initialized instance and
typings as the rest of the codebase.
| export interface SupportedLanguages { | ||
| en: boolean; | ||
| zh: boolean; | ||
| [key: string]: boolean; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
类型定义与实现不一致(会返回不含 zh 的对象)
SupportedLanguages 将 en/zh 标为必填,但实现当仅有单语言(如 "en")时会返回 { en: true }。建议改为通用映射类型,或将 en/zh 设为可选。
建议采用更简单的定义:
-export interface SupportedLanguages {
- en: boolean;
- zh: boolean;
- [key: string]: boolean;
-}
+export type SupportedLanguages = Record<string, boolean>;📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| export interface SupportedLanguages { | |
| en: boolean; | |
| zh: boolean; | |
| [key: string]: boolean; | |
| } | |
| export type SupportedLanguages = Record<string, boolean>; |
🤖 Prompt for AI Agents
In packages/runtime/src/internal/compute/language.ts around lines 3 to 7, the
SupportedLanguages interface marks en and zh as required but the code can return
objects like { en: true } without zh; change the type to match runtime output by
replacing the interface with a general mapping (e.g., Record<string, boolean>)
or make en and zh optional (en?: boolean; zh?: boolean), and update any
callers/assignments to satisfy the new type so implementations that only include
a single language no longer violate the type.
| const s = opt.supportedLngs; | ||
| let lngs: string[] = []; | ||
| if (Array.isArray(s)) { | ||
| lngs = s.filter((lng) => lng !== "cimode"); | ||
| } | ||
|
|
||
| if (typeof s === "string" && s) { | ||
| lngs = [s]; | ||
| } | ||
|
|
||
| // fallback: 从 resources 中取 key | ||
| if (opt.resources && typeof opt.resources === "object") { | ||
| lngs = Object.keys(opt.resources); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
“resources 作为兜底”逻辑写成了“覆盖”——应仅在前面未取到时才回退
当前无条件用 resources 覆盖 supportedLngs,与注释“fallback”不符。
应用如下修正,并统一过滤 cimode:
- const s = opt.supportedLngs;
- let lngs: string[] = [];
- if (Array.isArray(s)) {
- lngs = s.filter((lng) => lng !== "cimode");
- }
- if (typeof s === "string" && s) {
- lngs = [s];
- }
- // fallback: 从 resources 中取 key
- if (opt.resources && typeof opt.resources === "object") {
- lngs = Object.keys(opt.resources);
- }
+ const s = opt.supportedLngs as unknown;
+ let lngs: string[] = [];
+ if (Array.isArray(s)) {
+ lngs = s.filter((lng) => lng && lng !== "cimode");
+ } else if (typeof s === "string" && s) {
+ lngs = [s];
+ }
+ // fallback: 仅当未从 supportedLngs 获取到时,从 resources 中取 key
+ if (!lngs.length && opt.resources && typeof opt.resources === "object") {
+ lngs = Object.keys(opt.resources).filter((lng) => lng && lng !== "cimode");
+ }📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const s = opt.supportedLngs; | |
| let lngs: string[] = []; | |
| if (Array.isArray(s)) { | |
| lngs = s.filter((lng) => lng !== "cimode"); | |
| } | |
| if (typeof s === "string" && s) { | |
| lngs = [s]; | |
| } | |
| // fallback: 从 resources 中取 key | |
| if (opt.resources && typeof opt.resources === "object") { | |
| lngs = Object.keys(opt.resources); | |
| } | |
| const s = opt.supportedLngs as unknown; | |
| let lngs: string[] = []; | |
| if (Array.isArray(s)) { | |
| lngs = s.filter((lng) => lng && lng !== "cimode"); | |
| } else if (typeof s === "string" && s) { | |
| lngs = [s]; | |
| } | |
| // fallback: 仅当未从 supportedLngs 获取到时,从 resources 中取 key | |
| if (!lngs.length && opt.resources && typeof opt.resources === "object") { | |
| lngs = Object.keys(opt.resources).filter((lng) => lng && lng !== "cimode"); | |
| } |
🤖 Prompt for AI Agents
In packages/runtime/src/internal/compute/language.ts around lines 11 to 24, the
current code unconditionally overwrites supportedLngs with opt.resources
(contradicting the "fallback" comment); change the logic so resources are used
only if no languages were obtained from supportedLngs (array or string), and
always filter out "cimode" from the final list; i.e., compute lngs from
opt.supportedLngs when present (handle array and string cases), then if lngs is
empty and opt.resources is an object set lngs = Object.keys(opt.resources), and
finally apply a filter to remove "cimode".
Closes CMDB_INSTANCE-3369
c69dabc to
ac0ed0d
Compare
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## v3 #4783 +/- ##
==========================================
- Coverage 95.22% 95.21% -0.02%
==========================================
Files 210 210
Lines 9175 9176 +1
Branches 1768 1769 +1
==========================================
Hits 8737 8737
Misses 324 324
- Partials 114 115 +1
🚀 New features to boost your workflow:
|
next-core
|
||||||||||||||||||||||||||||
| Project |
next-core
|
| Branch Review |
alex/supportLanguageV3
|
| Run status |
|
| Run duration | 00m 22s |
| Commit |
|
| Committer | Chén Wénháo |
| View all properties for this run ↗︎ | |
| Test results | |
|---|---|
|
|
0
|
|
|
0
|
|
|
0
|
|
|
0
|
|
|
17
|
| View all changes introduced in this branch ↗︎ | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (2)
packages/runtime/src/internal/compute/getGeneralGlobals.ts (2)
84-86: 语言值建议标准化,避免返回 en-US/zh-CN 造成下游判定失配直接用
i18n.language可能返回区域化代码或空串。建议优先resolvedLanguage,再按supportedLngs抽取基语言,最后保持与现有默认一致的回退值。- case "LANGUAGE": { - return collectCoverage ? "zh" : i18n.language || "zh"; - } + case "LANGUAGE": { + if (collectCoverage) return "zh"; + const lang = + // i18next >=21 暴露 resolvedLanguage;旧版本没有则回退 language + (i18n as any).resolvedLanguage ?? i18n.language ?? ""; + const supported = (i18n.options?.supportedLngs as string[] | undefined) ?? []; + const base = lang.split("-")[0] || ""; + return supported.includes(lang) + ? lang + : supported.includes(base) + ? base + : lang || "zh"; + }
84-86: 覆盖模式下 LANGUAGE=zh 与 I18N_TEXT(en) 的假实现不一致collectCoverage 时
LANGUAGE固定为 zh,但fakeI18nText取data.en,两者组合可能产生自相矛盾的断言。二选一以保持一致:
- 方案 A(更动最小):覆盖模式改为返回 "en"。
- return collectCoverage ? "zh" : i18n.language || "zh"; + return collectCoverage ? "en" : i18n.language || "en";
- 方案 B(保留 LANGUAGE=zh):调整
fakeI18nText优先 zh 回退 en(此变更位于本段之外,仅示例)。function fakeI18nText(data: Record<string, string>): string { return data?.zh ?? data?.en; }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Cache: Disabled due to data retention organization setting
Knowledge base: Disabled due to data retention organization setting
📒 Files selected for processing (2)
packages/runtime/src/internal/compute/evaluate.spec.ts(4 hunks)packages/runtime/src/internal/compute/getGeneralGlobals.ts(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- packages/runtime/src/internal/compute/evaluate.spec.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: build (20.x)
- GitHub Check: Analyze (javascript-typescript)
| case "LANGUAGE": { | ||
| return collectCoverage ? "zh" : i18n.language || "zh"; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
同步公开契约:为新全局 LANGUAGE 补齐类型/文档/清单
新增全局需同步到:API 文档、d.ts/类型提示、表达式/DSL 提示、dll manifest/白名单、CHANGELOG。请确认并补齐。
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# 1) 搜索是否已有白名单/类型里显式列出全局名
rg -nP -C2 '\b(BASE_URL|I18N_TEXT|I18N|THEME|PERMISSIONS|console|location|LANGUAGE)\b' -S
# 2) 检查 d.ts 是否已包含 LANGUAGE
fd -t f -e d.ts | xargs rg -n 'LANGUAGE' -n || true
# 3) 文档与变更记录
rg -n 'LANGUAGE' docs CHANGELOG.md -S || true
# 4) 可能的 dll manifest/白名单文件
fd -i -t f 'manifest' | xargs rg -n 'LANGUAGE' -n || true
# 5) 用例覆盖
rg -n 'LANGUAGE' -g '!**/node_modules/**' -SLength of output: 267155
补齐公开契约:为新全局 LANGUAGE 补齐类型/文档/清单
检查结果:LANGUAGE 已在 runtime 中新增并被单测使用,但未在类型/白名单/文档/CHANGELOG 中登记。
需要补齐的项(最小可交付):
- 类型 / 白名单:将 LANGUAGE 加入 packages/types/src/manifest.ts(或仓库中负责表达式全局的类型/manifest)并新增/更新相关 .d.ts,保证 IDE 类型提示。
- 表达式 / DSL 提示:更新表达式提示/文档生成逻辑(doc-helpers 或 docs 源)以暴露 LANGUAGE 给编辑器/DSL 用户。
- dll manifest / 白名单:在 bricks/manifest 或项目的白名单文件中加入 LANGUAGE(以便打包/运行时允许)。
- CHANGELOG:在 packages/runtime/CHANGELOG.md(或受影响包的 CHANGELOG)记录新增全局及兼容说明。
参考位置(便于快速修改):
- 使用处:packages/runtime/src/internal/compute/getGeneralGlobals.ts — case "LANGUAGE"(行 84–86)
- 单测:packages/runtime/src/internal/compute/evaluate.spec.ts — 测试 "<% LANGUAGE %>"(行 ~324)
我可协助生成所需的 d.ts/manifest/文档补丁或 PR。
Closes CMDB_INSTANCE-3369
依赖检查
组件之间的依赖声明,是微服务组件架构下的重要信息,请确保其正确性。
请勾选以下两组选项其中之一:
或者:
提交信息检查
Git 提交信息将决定包的版本发布及自动生成的 CHANGELOG,请检查工作内容与提交信息是否相符,并在以下每组选项中都依次确认。
破坏性变更:
feat作为提交类型。BREAKING CHANGE: 你的变更说明。新特性:
feat作为提交类型。问题修复:
fix作为提交类型。杂项工作:
即所有对下游使用者无任何影响、且没有必要显示在 CHANGELOG 中的改动,例如修改注释、测试用例、开发文档等:
chore,docs,test等作为提交类型。Summary by CodeRabbit