@spaceflow/core 0.6.0 → 0.7.0
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/package.json
CHANGED
|
@@ -85,7 +85,6 @@ export class SchemaGeneratorService {
|
|
|
85
85
|
|
|
86
86
|
// 写入文件
|
|
87
87
|
fs.writeFileSync(outputPath, JSON.stringify(fullSchema, null, 2), "utf-8");
|
|
88
|
-
console.log(`✅ JSON Schema 已生成: ${outputPath}`);
|
|
89
88
|
|
|
90
89
|
// 自动添加到 .gitignore
|
|
91
90
|
this.addToGitignore(dir, path.basename(outputPath));
|
|
@@ -7,5 +7,7 @@
|
|
|
7
7
|
"common.options.ci": "Run in CI environment",
|
|
8
8
|
"config.parseWarning": "Warning: unable to parse config file {{path}}",
|
|
9
9
|
"config.validationFailed": "Spaceflow config validation failed:\n{{errors}}",
|
|
10
|
-
"extensionLoader.loadFailed": "⚠️ Failed to load Extension {{name}}: {{error}}"
|
|
10
|
+
"extensionLoader.loadFailed": "⚠️ Failed to load Extension {{name}}: {{error}}",
|
|
11
|
+
"extensionLoader.autoInstalling": "📦 Auto-installing missing extensions: {{packages}}",
|
|
12
|
+
"extensionLoader.autoInstallFailed": "⚠️ Auto-install failed, please run spaceflow install manually"
|
|
11
13
|
}
|
|
@@ -7,5 +7,7 @@
|
|
|
7
7
|
"common.options.ci": "是否在 CI 环境中运行",
|
|
8
8
|
"config.parseWarning": "警告: 无法解析配置文件 {{path}}",
|
|
9
9
|
"config.validationFailed": "Spaceflow 配置验证失败:\n{{errors}}",
|
|
10
|
-
"extensionLoader.loadFailed": "⚠️ 加载 Extension {{name}} 失败: {{error}}"
|
|
10
|
+
"extensionLoader.loadFailed": "⚠️ 加载 Extension {{name}} 失败: {{error}}",
|
|
11
|
+
"extensionLoader.autoInstalling": "📦 自动安装缺失的扩展: {{packages}}",
|
|
12
|
+
"extensionLoader.autoInstallFailed": "⚠️ 自动安装扩展失败,请手动执行 spaceflow install"
|
|
11
13
|
}
|
package/src/shared/i18n/i18n.ts
CHANGED
|
@@ -11,8 +11,28 @@ import en from "../../locales/en/translation.json";
|
|
|
11
11
|
/** 默认命名空间 */
|
|
12
12
|
const DEFAULT_NS = "translation";
|
|
13
13
|
|
|
14
|
-
/**
|
|
15
|
-
|
|
14
|
+
/** globalThis 上的 key,确保多份 core 实例共享同一个 i18n 状态 */
|
|
15
|
+
const GLOBAL_I18N_KEY = "__spaceflow_i18n__";
|
|
16
|
+
|
|
17
|
+
interface GlobalI18nState {
|
|
18
|
+
instance: i18n;
|
|
19
|
+
initialized: boolean;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* 获取全局 i18n 状态(单例)
|
|
24
|
+
* 无论有几份 @spaceflow/core 实例,都共享同一个 i18next 实例
|
|
25
|
+
*/
|
|
26
|
+
function getGlobalState(): GlobalI18nState {
|
|
27
|
+
const g = globalThis as Record<string, unknown>;
|
|
28
|
+
if (!g[GLOBAL_I18N_KEY]) {
|
|
29
|
+
g[GLOBAL_I18N_KEY] = {
|
|
30
|
+
instance: i18next,
|
|
31
|
+
initialized: false,
|
|
32
|
+
} satisfies GlobalI18nState;
|
|
33
|
+
}
|
|
34
|
+
return g[GLOBAL_I18N_KEY] as GlobalI18nState;
|
|
35
|
+
}
|
|
16
36
|
|
|
17
37
|
/**
|
|
18
38
|
* 初始化 i18n
|
|
@@ -20,10 +40,11 @@ let initialized = false;
|
|
|
20
40
|
* @param lang 指定语言,不传则自动检测
|
|
21
41
|
*/
|
|
22
42
|
export function initI18n(lang?: string): void {
|
|
23
|
-
|
|
43
|
+
const state = getGlobalState();
|
|
44
|
+
if (state.initialized) return;
|
|
24
45
|
const lng = lang || detectLocale();
|
|
25
46
|
// i18next v25+ 移除了 initSync,但提供内联 resources 时 init() 同步完成
|
|
26
|
-
void
|
|
47
|
+
void state.instance.init({
|
|
27
48
|
lng,
|
|
28
49
|
fallbackLng: "zh-CN",
|
|
29
50
|
defaultNS: DEFAULT_NS,
|
|
@@ -42,27 +63,29 @@ export function initI18n(lang?: string): void {
|
|
|
42
63
|
// i18next v25.8+ 会在 init 时输出 locize.com 推广日志
|
|
43
64
|
showSupportNotice: false,
|
|
44
65
|
});
|
|
45
|
-
initialized = true;
|
|
66
|
+
state.initialized = true;
|
|
46
67
|
}
|
|
47
68
|
|
|
48
69
|
/**
|
|
49
70
|
* 重置 i18n 状态(仅用于测试)
|
|
50
71
|
*/
|
|
51
72
|
export function resetI18n(): void {
|
|
52
|
-
|
|
73
|
+
const state = getGlobalState();
|
|
74
|
+
state.initialized = false;
|
|
53
75
|
}
|
|
54
76
|
|
|
55
77
|
/**
|
|
56
78
|
* 翻译函数
|
|
57
|
-
*
|
|
79
|
+
* 通过 globalThis 共享 i18next 实例,确保多份 core 实例下翻译一致
|
|
58
80
|
* @param key 翻译 key
|
|
59
81
|
* @param options 插值参数
|
|
60
82
|
*/
|
|
61
83
|
export function t(key: string, options?: TOptions): string {
|
|
62
|
-
|
|
84
|
+
const state = getGlobalState();
|
|
85
|
+
if (!state.initialized) {
|
|
63
86
|
initI18n();
|
|
64
87
|
}
|
|
65
|
-
return
|
|
88
|
+
return state.instance.t(key, options) as string;
|
|
66
89
|
}
|
|
67
90
|
|
|
68
91
|
/**
|
|
@@ -74,15 +97,16 @@ export function addLocaleResources(
|
|
|
74
97
|
ns: string,
|
|
75
98
|
resources: Record<string, Record<string, unknown>>,
|
|
76
99
|
): void {
|
|
77
|
-
|
|
100
|
+
const state = getGlobalState();
|
|
101
|
+
if (!state.initialized) {
|
|
78
102
|
initI18n();
|
|
79
103
|
}
|
|
80
104
|
for (const [lng, translations] of Object.entries(resources)) {
|
|
81
|
-
|
|
105
|
+
state.instance.addResourceBundle(lng, ns, translations, true, true);
|
|
82
106
|
}
|
|
83
|
-
if (!
|
|
84
|
-
|
|
85
|
-
} else if (Array.isArray(
|
|
86
|
-
|
|
107
|
+
if (!state.instance.options.ns) {
|
|
108
|
+
state.instance.options.ns = [DEFAULT_NS, ns];
|
|
109
|
+
} else if (Array.isArray(state.instance.options.ns) && !state.instance.options.ns.includes(ns)) {
|
|
110
|
+
state.instance.options.ns.push(ns);
|
|
87
111
|
}
|
|
88
112
|
}
|