@liujitcn/kratos-uni-app-core 0.0.61 → 0.0.64

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.md CHANGED
@@ -45,7 +45,7 @@ packages/core
45
45
 
46
46
  - `@liujitcn/kratos-uni-app-core`:运行时、导航、store 和组件。
47
47
  - `@liujitcn/kratos-uni-app-core/module`:模块协议和 core 模块。
48
- - `@liujitcn/kratos-uni-app-core/vite`:Vite 配置与页面装配插件。
48
+ - `@liujitcn/kratos-uni-app-core/vite`:Vite 配置、页面装配插件和构建错误文案格式化器。
49
49
  - `@liujitcn/kratos-uni-app-core/api/*`、`components/*.vue`、`utils/*`、`views/*`:白名单子路径。
50
50
 
51
51
  ## 公共设置页
package/dist/module.mjs CHANGED
@@ -33,6 +33,7 @@ var zh_CN_default = {
33
33
  "common.action.new": "\u65B0\u5EFA",
34
34
  "common.action.open_in_new_window": "\u65B0\u7A97\u53E3\u6253\u5F00",
35
35
  "common.action.save": "\u4FDD\u5B58",
36
+ "common.action.view": "\u67E5\u770B",
36
37
  "common.field.language": "\u8BED\u8A00",
37
38
  "common.language.en-US": "English",
38
39
  "common.language.zh-CN": "\u7B80\u4F53\u4E2D\u6587",
@@ -115,6 +116,7 @@ var zh_CN_default = {
115
116
  "core.login.user_name_password": "\u8BF7\u8F93\u5165\u7528\u6237\u540D\u548C\u5BC6\u7801",
116
117
  "core.login.wechat": "\u5FAE\u4FE1\u4E00\u952E\u767B\u5F55",
117
118
  "core.login.wechat_bind_tip": "\u8BE5\u5FAE\u4FE1\u5C1A\u672A\u7ED1\u5B9A\uFF0C\u8BF7\u767B\u5F55\u5DF2\u6709\u8D26\u53F7\u5B8C\u6210\u7ED1\u5B9A",
119
+ "core.login.login_failed": "\u767B\u5F55\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5",
118
120
  "core.login.wechat_failed": "\u5FAE\u4FE1\u767B\u5F55\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5",
119
121
  "core.navigation.home": "\u9996\u9875",
120
122
  "core.navigation.message": "\u6D88\u606F",
@@ -178,6 +180,7 @@ var en_US_default = {
178
180
  "common.action.new": "New",
179
181
  "common.action.open_in_new_window": "Open in new window",
180
182
  "common.action.save": "Save",
183
+ "common.action.view": "View",
181
184
  "common.field.language": "Language",
182
185
  "common.language.en-US": "English",
183
186
  "common.language.zh-CN": "\u7B80\u4F53\u4E2D\u6587",
@@ -260,6 +263,7 @@ var en_US_default = {
260
263
  "core.login.user_name_password": "Enter username and password",
261
264
  "core.login.wechat": "Continue with WeChat",
262
265
  "core.login.wechat_bind_tip": "This WeChat account is not linked. Log in to an existing account to link it.",
266
+ "core.login.login_failed": "Login failed. Try again.",
263
267
  "core.login.wechat_failed": "WeChat login failed. Try again later.",
264
268
  "core.navigation.home": "Home",
265
269
  "core.navigation.message": "Messages",
@@ -323,6 +327,7 @@ var ja_JP_default = {
323
327
  "common.action.new": "\u65B0\u898F",
324
328
  "common.action.open_in_new_window": "\u65B0\u3057\u3044\u30A6\u30A3\u30F3\u30C9\u30A6\u304C\u958B\u304D\u307E\u3059",
325
329
  "common.action.save": "\u4FDD\u5B58",
330
+ "common.action.view": "\u8868\u793A",
326
331
  "common.field.language": "\u8A00\u8A9E",
327
332
  "common.language.en-US": "\u82F1\u8A9E",
328
333
  "common.language.zh-CN": "\u7C21\u4F53\u5B57\u4E2D\u56FD\u8A9E",
@@ -405,6 +410,7 @@ var ja_JP_default = {
405
410
  "core.login.user_name_password": "\u30E6\u30FC\u30B6\u30FC\u540D\u3068\u30D1\u30B9\u30EF\u30FC\u30C9\u3092\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044",
406
411
  "core.login.wechat": "WeChat \u30EF\u30F3\u30AF\u30EA\u30C3\u30AF \u30ED\u30B0\u30A4\u30F3",
407
412
  "core.login.wechat_bind_tip": "\u3053\u306E WeChat \u30A2\u30AB\u30A6\u30F3\u30C8\u306F\u307E\u3060\u30D0\u30A4\u30F3\u30C9\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002\u30D0\u30A4\u30F3\u30C9\u3092\u5B8C\u4E86\u3059\u308B\u306B\u306F\u3001\u65E2\u5B58\u306E\u30A2\u30AB\u30A6\u30F3\u30C8\u306B\u30ED\u30B0\u30A4\u30F3\u3057\u3066\u304F\u3060\u3055\u3044\u3002",
413
+ "core.login.login_failed": "\u30ED\u30B0\u30A4\u30F3\u306B\u5931\u6557\u3057\u307E\u3057\u305F\u3002\u3082\u3046\u4E00\u5EA6\u304A\u8A66\u3057\u304F\u3060\u3055\u3044\u3002",
408
414
  "core.login.wechat_failed": "WeChat \u30ED\u30B0\u30A4\u30F3\u306B\u5931\u6557\u3057\u307E\u3057\u305F\u3002\u5F8C\u3067\u3082\u3046\u4E00\u5EA6\u8A66\u3057\u3066\u304F\u3060\u3055\u3044\u3002",
409
415
  "core.navigation.home": "\u30DB\u30FC\u30E0",
410
416
  "core.navigation.message": "\u30E1\u30C3\u30BB\u30FC\u30B8",
@@ -468,6 +474,7 @@ var zh_TW_default = {
468
474
  "common.action.new": "\u65B0\u5EFA",
469
475
  "common.action.open_in_new_window": "\u65B0\u8996\u7A97\u958B\u555F",
470
476
  "common.action.save": "\u5132\u5B58",
477
+ "common.action.view": "\u6AA2\u8996",
471
478
  "common.field.language": "\u8A9E\u8A00",
472
479
  "common.language.en-US": "English",
473
480
  "common.language.zh-CN": "\u7C21\u9AD4\u4E2D\u6587",
@@ -550,6 +557,7 @@ var zh_TW_default = {
550
557
  "core.login.user_name_password": "\u8ACB\u8F38\u5165\u4F7F\u7528\u8005\u540D\u7A31\u548C\u5BC6\u78BC",
551
558
  "core.login.wechat": "\u5FAE\u4FE1\u4E00\u9375\u767B\u5165",
552
559
  "core.login.wechat_bind_tip": "\u8A72\u5FAE\u4FE1\u5C1A\u672A\u7E6B\u7D50\uFF0C\u8ACB\u767B\u5165\u5DF2\u6709\u8CEC\u865F\u5B8C\u6210\u7E6B\u7D50",
560
+ "core.login.login_failed": "\u767B\u5165\u5931\u6557\uFF0C\u8ACB\u91CD\u8A66",
553
561
  "core.login.wechat_failed": "\u5FAE\u4FE1\u767B\u5165\u5931\u6557\uFF0C\u8ACB\u7A0D\u5F8C\u91CD\u8A66",
554
562
  "core.navigation.home": "\u9996\u9801",
555
563
  "core.navigation.message": "\u6D88\u606F",
package/dist/vite.mjs CHANGED
@@ -14,6 +14,32 @@ import { createRequire } from "node:module";
14
14
  import { dirname, isAbsolute, relative, resolve } from "node:path";
15
15
  import uniPlugin from "@dcloudio/vite-plugin-uni";
16
16
  import { defineConfig, loadEnv } from "vite";
17
+
18
+ // src/vite-messages.ts
19
+ var messages = {
20
+ "zh-CN": {
21
+ https_certificate_missing: "VITE_APP_HTTPS \u5DF2\u5F00\u542F\uFF0C\u4F46\u672A\u627E\u5230\u8BC1\u4E66\u6587\u4EF6\uFF0C\u8BF7\u5148\u5728\u4ED3\u5E93\u6839\u76EE\u5F55\u8FD0\u884C scripts/generate-dev-cert.sh\uFF1B\u671F\u671B\u8DEF\u5F84\uFF1A{keyPath} \u548C {certPath}",
22
+ transaction_mismatch: "uni-app \u6784\u5EFA\u4E8B\u52A1\u76EE\u5F55\u4E0D\u5339\u914D\uFF1A{file}",
23
+ assembly_timeout: "\u7B49\u5F85 uni-app \u9875\u9762\u88C5\u914D\u9501\u8D85\u65F6\uFF1A{file}",
24
+ source_path_not_absolute: "\u6A21\u5757\u6E90\u7801\u8DEF\u5F84\u4E0D\u662F\u7EDD\u5BF9\u8DEF\u5F84\uFF1A{path}"
25
+ },
26
+ "en-US": {
27
+ https_certificate_missing: "VITE_APP_HTTPS is enabled, but certificate files were not found. Run scripts/generate-dev-cert.sh from the repository root; expected paths: {keyPath} and {certPath}",
28
+ transaction_mismatch: "The uni-app build transaction directory does not match: {file}",
29
+ assembly_timeout: "Timed out waiting for the uni-app page assembly lock: {file}",
30
+ source_path_not_absolute: "The module source path is not absolute: {path}"
31
+ }
32
+ };
33
+ function resolveViteLocale() {
34
+ const value = process.env.KRATOS_ADMIN_LOCALE ?? process.env.LC_ALL ?? process.env.LANG ?? "";
35
+ return value.toLowerCase().startsWith("zh") ? "zh-CN" : "en-US";
36
+ }
37
+ function viteMessage(key, params = {}) {
38
+ const template = messages[resolveViteLocale()][key] ?? messages["en-US"][key] ?? key;
39
+ return template.replace(/\{([A-Za-z0-9_]+)\}/g, (_, name) => params[name] ?? `{${name}}`);
40
+ }
41
+
42
+ // src/vite.ts
17
43
  var sourceVersionCounter = 0;
18
44
  var PAGE_ASSEMBLY_WAIT_TIMEOUT_MS = 3e4;
19
45
  var PAGE_ASSEMBLY_POLL_INTERVAL_MS = 25;
@@ -264,7 +290,7 @@ function readBuildTransaction(transactionFile, inputDir, pagesFile) {
264
290
  return;
265
291
  const transaction = JSON.parse(readFileSync(transactionFile, "utf8"));
266
292
  if (transaction.inputDir !== inputDir || transaction.pagesFile !== pagesFile) {
267
- throw new Error(`uni-app \u6784\u5EFA\u4E8B\u52A1\u76EE\u5F55\u4E0D\u5339\u914D\uFF1A${transactionFile}`);
293
+ throw new Error(viteMessage("transaction_mismatch", { file: transactionFile }));
268
294
  }
269
295
  return transaction;
270
296
  }
@@ -376,7 +402,7 @@ function acquirePageAssemblyLock(lockFile) {
376
402
  continue;
377
403
  }
378
404
  if (Date.now() >= deadline) {
379
- throw new Error(`\u7B49\u5F85 uni-app \u9875\u9762\u88C5\u914D\u9501\u8D85\u65F6\uFF1A${lockFile}`);
405
+ throw new Error(viteMessage("assembly_timeout", { file: lockFile }));
380
406
  }
381
407
  waitForPageAssembly(PAGE_ASSEMBLY_POLL_INTERVAL_MS);
382
408
  }
@@ -539,7 +565,7 @@ function resolveSourceFile(target) {
539
565
  ];
540
566
  const resolved = candidates.find((candidate) => existsSync(candidate) && statSync(candidate).isFile()) ?? target;
541
567
  if (!isAbsolute(resolved))
542
- throw new Error(`\u6A21\u5757\u6E90\u7801\u8DEF\u5F84\u4E0D\u662F\u7EDD\u5BF9\u8DEF\u5F84\uFF1A${resolved}`);
568
+ throw new Error(viteMessage("source_path_not_absolute", { path: resolved }));
543
569
  return resolved;
544
570
  }
545
571
  function dependencyVersionQuery(importer, sourceVersion) {
@@ -569,5 +595,6 @@ export {
569
595
  defineConfig,
570
596
  kratosApp,
571
597
  loadEnv,
572
- recoverStalePageTransaction
598
+ recoverStalePageTransaction,
599
+ viteMessage
573
600
  };
package/package.json CHANGED
@@ -7,7 +7,7 @@
7
7
  "type": "git",
8
8
  "url": "git@github.com:liujitcn/kratos-admin.git"
9
9
  },
10
- "version": "0.0.61",
10
+ "version": "0.0.64",
11
11
  "type": "module",
12
12
  "files": [
13
13
  "dist",
@@ -86,7 +86,7 @@ export class FileServiceImpl {
86
86
  document.body.removeChild(a)
87
87
  window.URL.revokeObjectURL(url)
88
88
  } catch (error) {
89
- console.error('下载错误:', error)
89
+ console.error('File download failed:', error)
90
90
  }
91
91
  }
92
92
  }
package/src/bootstrap.ts CHANGED
@@ -3,9 +3,11 @@ import type { App, Component } from 'vue'
3
3
  import { registerKratosAppModules, type KratosAppModule } from './module'
4
4
  import {
5
5
  applyLanguageConfig,
6
+ getCurrentLocale,
6
7
  initializeLocale,
7
8
  registerLocaleChangeHandler,
8
9
  registerLocaleMessages,
10
+ t,
9
11
  } from './locales'
10
12
  import { initializeAppNavigation } from './navigation'
11
13
  import { useSettingStore } from './stores'
@@ -23,15 +25,25 @@ export interface KratosAppBootstrapOptions {
23
25
  modules: KratosAppModule[]
24
26
  }
25
27
 
28
+ function syncH5DocumentTitle(): void {
29
+ // #ifdef H5
30
+ if (typeof document === 'undefined') return
31
+ document.documentElement.lang = getCurrentLocale()
32
+ document.title = t('core.home.main_title')
33
+ // #endif
34
+ }
35
+
26
36
  /** 创建 uni-app 实例并注册模块。 */
27
37
  export function bootstrapKratosApp(options: KratosAppBootstrapOptions) {
28
38
  registerKratosAppModules(options.modules)
29
39
  registerLocaleMessages(options.modules)
30
40
  initializeLocale()
41
+ syncH5DocumentTitle()
31
42
  void defLanguageService
32
43
  .OptionLanguage({})
33
44
  .then((response) => {
34
45
  applyLanguageConfig(response)
46
+ syncH5DocumentTitle()
35
47
  })
36
48
  .catch(() => {
37
49
  // 语言公共接口失败时继续使用静态语言包和系统语言。
@@ -7,6 +7,7 @@
7
7
  "common.action.new": "New",
8
8
  "common.action.open_in_new_window": "Open in new window",
9
9
  "common.action.save": "Save",
10
+ "common.action.view": "View",
10
11
  "common.field.language": "Language",
11
12
  "common.language.en-US": "English",
12
13
  "common.language.zh-CN": "简体中文",
@@ -89,6 +90,7 @@
89
90
  "core.login.user_name_password": "Enter username and password",
90
91
  "core.login.wechat": "Continue with WeChat",
91
92
  "core.login.wechat_bind_tip": "This WeChat account is not linked. Log in to an existing account to link it.",
93
+ "core.login.login_failed": "Login failed. Try again.",
92
94
  "core.login.wechat_failed": "WeChat login failed. Try again later.",
93
95
  "core.navigation.home": "Home",
94
96
  "core.navigation.message": "Messages",
@@ -108,18 +108,19 @@ export function registerLocaleMessages(modules: KratosAppModule[]): void {
108
108
  const expectedKeys = requiredLocaleKeys(module.messages?.[DEFAULT_LOCALE] || {})
109
109
  SUPPORTED_LOCALES.forEach((locale) => {
110
110
  const messages = module.messages?.[locale]
111
- if (!messages) throw new Error(`${module.name} 缺少 ${locale} 语言包`)
111
+ if (!messages)
112
+ throw new Error(localeRuntimeMessage('missing_bundle', { module: module.name, locale }))
112
113
  const keys = requiredLocaleKeys(messages)
113
114
  if (keys.join('\u0000') !== expectedKeys.join('\u0000')) {
114
- throw new Error(`${module.name} 的 ${locale} 语言包键集合不一致`)
115
+ throw new Error(localeRuntimeMessage('key_set_mismatch', { module: module.name, locale }))
115
116
  }
116
117
  const target = defaultLocaleMessages.get(locale) as LocaleMessages
117
118
  Object.keys(messages).forEach((key) => {
118
119
  if (!isAllowedLocaleKey(module.name, key)) {
119
- throw new Error(`${module.name} 的语言键命名空间无效: ${key}`)
120
+ throw new Error(localeRuntimeMessage('namespace_invalid', { module: module.name, key }))
120
121
  }
121
122
  if (Object.prototype.hasOwnProperty.call(target, key)) {
122
- throw new Error(`${locale} 语言键重复: ${key}`)
123
+ throw new Error(localeRuntimeMessage('duplicate_key', { locale, key }))
123
124
  }
124
125
  assertLocalePlaceholders(
125
126
  module.name,
@@ -211,10 +212,34 @@ function assertLocalePlaceholders(
211
212
  const placeholders = (value: string) =>
212
213
  [...value.matchAll(/\{([A-Za-z0-9_]+)\}/g)].map((match) => match[1]).sort()
213
214
  if (placeholders(message).join('\u0000') !== placeholders(sourceMessage).join('\u0000')) {
214
- throw new Error(`${moduleName} 的 ${key} 占位符集合不一致`)
215
+ throw new Error(localeRuntimeMessage('placeholder_mismatch', { module: moduleName, key }))
215
216
  }
216
217
  }
217
218
 
219
+ function localeRuntimeMessage(key: string, params: Record<string, string>): string {
220
+ const locale = getCurrentLocale().toLowerCase().startsWith('zh') ? 'zh-CN' : 'en-US'
221
+ const templates: Record<string, Record<string, string>> = {
222
+ 'zh-CN': {
223
+ missing_bundle: '{module} 缺少 {locale} 语言包',
224
+ key_set_mismatch: '{module} 的 {locale} 语言包键集合不一致',
225
+ namespace_invalid: '{module} 的语言键命名空间无效: {key}',
226
+ duplicate_key: '{locale} 语言键重复: {key}',
227
+ placeholder_mismatch: '{module} 的 {key} 占位符集合不一致',
228
+ },
229
+ 'en-US': {
230
+ missing_bundle: '{module} is missing the {locale} locale bundle',
231
+ key_set_mismatch: '{module} has inconsistent keys in the {locale} locale bundle',
232
+ namespace_invalid: 'Invalid locale key namespace for {module}: {key}',
233
+ duplicate_key: 'Duplicate locale key in {locale}: {key}',
234
+ placeholder_mismatch: 'Placeholder set mismatch for {module}: {key}',
235
+ },
236
+ }
237
+ return (templates[locale][key] ?? key).replace(
238
+ /\{([A-Za-z0-9_]+)\}/g,
239
+ (_, name: string) => params[name] ?? `{${name}}`,
240
+ )
241
+ }
242
+
218
243
  function requiredLocaleKeys(messages: LocaleMessages): string[] {
219
244
  return Object.keys(messages)
220
245
  .filter((key) => !key.startsWith('common.language.'))
@@ -7,6 +7,7 @@
7
7
  "common.action.new": "新規",
8
8
  "common.action.open_in_new_window": "新しいウィンドウが開きます",
9
9
  "common.action.save": "保存",
10
+ "common.action.view": "表示",
10
11
  "common.field.language": "言語",
11
12
  "common.language.en-US": "英語",
12
13
  "common.language.zh-CN": "簡体字中国語",
@@ -89,6 +90,7 @@
89
90
  "core.login.user_name_password": "ユーザー名とパスワードを入力してください",
90
91
  "core.login.wechat": "WeChat ワンクリック ログイン",
91
92
  "core.login.wechat_bind_tip": "この WeChat アカウントはまだバインドされていません。バインドを完了するには、既存のアカウントにログインしてください。",
93
+ "core.login.login_failed": "ログインに失敗しました。もう一度お試しください。",
92
94
  "core.login.wechat_failed": "WeChat ログインに失敗しました。後でもう一度試してください。",
93
95
  "core.navigation.home": "ホーム",
94
96
  "core.navigation.message": "メッセージ",
@@ -7,6 +7,7 @@
7
7
  "common.action.new": "新建",
8
8
  "common.action.open_in_new_window": "新窗口打开",
9
9
  "common.action.save": "保存",
10
+ "common.action.view": "查看",
10
11
  "common.field.language": "语言",
11
12
  "common.language.en-US": "English",
12
13
  "common.language.zh-CN": "简体中文",
@@ -89,6 +90,7 @@
89
90
  "core.login.user_name_password": "请输入用户名和密码",
90
91
  "core.login.wechat": "微信一键登录",
91
92
  "core.login.wechat_bind_tip": "该微信尚未绑定,请登录已有账号完成绑定",
93
+ "core.login.login_failed": "登录失败,请重试",
92
94
  "core.login.wechat_failed": "微信登录失败,请稍后重试",
93
95
  "core.navigation.home": "首页",
94
96
  "core.navigation.message": "消息",
@@ -7,6 +7,7 @@
7
7
  "common.action.new": "新建",
8
8
  "common.action.open_in_new_window": "新視窗開啟",
9
9
  "common.action.save": "儲存",
10
+ "common.action.view": "檢視",
10
11
  "common.field.language": "語言",
11
12
  "common.language.en-US": "English",
12
13
  "common.language.zh-CN": "簡體中文",
@@ -89,6 +90,7 @@
89
90
  "core.login.user_name_password": "請輸入使用者名稱和密碼",
90
91
  "core.login.wechat": "微信一鍵登入",
91
92
  "core.login.wechat_bind_tip": "該微信尚未繫結,請登入已有賬號完成繫結",
93
+ "core.login.login_failed": "登入失敗,請重試",
92
94
  "core.login.wechat_failed": "微信登入失敗,請稍後重試",
93
95
  "core.navigation.home": "首頁",
94
96
  "core.navigation.message": "消息",
@@ -191,14 +191,30 @@ export interface UnbindOauthAccountRequest {
191
191
  export interface OauthProvider {
192
192
  /** 登录方式标识 */
193
193
  provider: string;
194
+ /** 登录方式名称 */
195
+ name: string;
196
+ /** 登录方式提示语 */
197
+ description: string;
198
+ /** 图标键或图片地址 */
199
+ icon: string;
200
+ /** Provider个性化配置JSON对象 */
201
+ config: { [key: string]: any } | undefined;
194
202
  }
195
203
 
196
204
  /** 个人中心三方账号绑定信息 */
197
205
  export interface OauthBinding {
198
206
  /** 登录方式标识 */
199
207
  provider: string;
208
+ /** 登录方式名称 */
209
+ name: string;
210
+ /** 登录方式提示语 */
211
+ description: string;
200
212
  /** 是否已绑定 */
201
213
  bound: boolean;
214
+ /** 图标键或图片地址 */
215
+ icon: string;
216
+ /** Provider个性化配置JSON对象 */
217
+ config: { [key: string]: any } | undefined;
202
218
  }
203
219
 
204
220
  /** Base三方登录公共服务 */
@@ -0,0 +1,80 @@
1
+ // Code generated by protoc-gen-ts_proto. DO NOT EDIT.
2
+ // versions:
3
+ // protoc-gen-ts_proto v2.11.8
4
+ // protoc unknown
5
+ // source: google/protobuf/struct.proto
6
+
7
+ /* eslint-disable */
8
+
9
+ /**
10
+ * `NullValue` is a singleton enumeration to represent the null value for the
11
+ * `Value` type union.
12
+ *
13
+ * The JSON representation for `NullValue` is JSON `null`.
14
+ */
15
+ export enum NullValue {
16
+ /** NULL_VALUE - Null value. */
17
+ NULL_VALUE = 0,
18
+ }
19
+
20
+ /**
21
+ * `Struct` represents a structured data value, consisting of fields
22
+ * which map to dynamically typed values. In some languages, `Struct`
23
+ * might be supported by a native representation. For example, in
24
+ * scripting languages like JS a struct is represented as an
25
+ * object. The details of that representation are described together
26
+ * with the proto support for the language.
27
+ *
28
+ * The JSON representation for `Struct` is JSON object.
29
+ */
30
+ export interface Struct {
31
+ /** Unordered map of dynamically typed values. */
32
+ fields: Map<string, any | undefined>;
33
+ }
34
+
35
+ export interface Struct_FieldsEntry {
36
+ key: string;
37
+ value: any | undefined;
38
+ }
39
+
40
+ /**
41
+ * `Value` represents a dynamically typed value which can be either
42
+ * null, a number, a string, a boolean, a recursive struct value, or a
43
+ * list of values. A producer of value is expected to set one of these
44
+ * variants. Absence of any variant indicates an error.
45
+ *
46
+ * The JSON representation for `Value` is JSON value.
47
+ */
48
+ export interface Value {
49
+ /** The kind of value. */
50
+ kind:
51
+ | //
52
+ /** Represents a null value. */
53
+ { $case: "null_value"; null_value: NullValue }
54
+ | //
55
+ /** Represents a double value. */
56
+ { $case: "number_value"; number_value: number }
57
+ | //
58
+ /** Represents a string value. */
59
+ { $case: "string_value"; string_value: string }
60
+ | //
61
+ /** Represents a boolean value. */
62
+ { $case: "bool_value"; bool_value: boolean }
63
+ | //
64
+ /** Represents a structured value. */
65
+ { $case: "struct_value"; struct_value: { [key: string]: any } | undefined }
66
+ | //
67
+ /** Represents a repeated `Value`. */
68
+ { $case: "list_value"; list_value: Array<any> | undefined }
69
+ | undefined;
70
+ }
71
+
72
+ /**
73
+ * `ListValue` is a wrapper around a repeated field of values.
74
+ *
75
+ * The JSON representation for `ListValue` is JSON array.
76
+ */
77
+ export interface ListValue {
78
+ /** Repeated field of dynamically typed values. */
79
+ values: any[];
80
+ }
@@ -216,7 +216,7 @@ export const useUserStore = defineStore(
216
216
  resolve()
217
217
  })
218
218
  .catch((error) => {
219
- console.log(' refreshToken 刷新失败', error)
219
+ console.log('Token refresh failed:', error)
220
220
  reject(error)
221
221
  })
222
222
  })
@@ -0,0 +1,30 @@
1
+ type ViteLocale = 'zh-CN' | 'en-US'
2
+
3
+ const messages: Record<ViteLocale, Record<string, string>> = {
4
+ 'zh-CN': {
5
+ https_certificate_missing:
6
+ 'VITE_APP_HTTPS 已开启,但未找到证书文件,请先在仓库根目录运行 scripts/generate-dev-cert.sh;期望路径:{keyPath} 和 {certPath}',
7
+ transaction_mismatch: 'uni-app 构建事务目录不匹配:{file}',
8
+ assembly_timeout: '等待 uni-app 页面装配锁超时:{file}',
9
+ source_path_not_absolute: '模块源码路径不是绝对路径:{path}',
10
+ },
11
+ 'en-US': {
12
+ https_certificate_missing:
13
+ 'VITE_APP_HTTPS is enabled, but certificate files were not found. Run scripts/generate-dev-cert.sh from the repository root; expected paths: {keyPath} and {certPath}',
14
+ transaction_mismatch: 'The uni-app build transaction directory does not match: {file}',
15
+ assembly_timeout: 'Timed out waiting for the uni-app page assembly lock: {file}',
16
+ source_path_not_absolute: 'The module source path is not absolute: {path}',
17
+ },
18
+ }
19
+
20
+ /** 根据环境变量选择 uni-app 构建器错误语言。 */
21
+ function resolveViteLocale(): ViteLocale {
22
+ const value = process.env.KRATOS_ADMIN_LOCALE ?? process.env.LC_ALL ?? process.env.LANG ?? ''
23
+ return value.toLowerCase().startsWith('zh') ? 'zh-CN' : 'en-US'
24
+ }
25
+
26
+ /** 渲染 uni-app 构建器稳定错误文案。 */
27
+ export function viteMessage(key: string, params: Record<string, string> = {}): string {
28
+ const template = messages[resolveViteLocale()][key] ?? messages['en-US'][key] ?? key
29
+ return template.replace(/\{([A-Za-z0-9_]+)\}/g, (_, name: string) => params[name] ?? `{${name}}`)
30
+ }
package/src/vite.ts CHANGED
@@ -15,8 +15,9 @@ import uniPlugin from '@dcloudio/vite-plugin-uni'
15
15
  import { defineConfig, loadEnv } from 'vite'
16
16
  import type { Plugin, UserConfig } from 'vite'
17
17
  import type { KratosAppModule, KratosAppPageConfig } from './module'
18
+ import { viteMessage } from './vite-messages.js'
18
19
 
19
- export { defineConfig, loadEnv }
20
+ export { defineConfig, loadEnv, viteMessage }
20
21
  export type { ConfigEnv, UserConfig } from 'vite'
21
22
 
22
23
  type PageEntry = { path: string; style?: Record<string, unknown> }
@@ -343,7 +344,7 @@ function readBuildTransaction(
343
344
  if (!existsSync(transactionFile)) return
344
345
  const transaction = JSON.parse(readFileSync(transactionFile, 'utf8')) as BuildTransaction
345
346
  if (transaction.inputDir !== inputDir || transaction.pagesFile !== pagesFile) {
346
- throw new Error(`uni-app 构建事务目录不匹配:${transactionFile}`)
347
+ throw new Error(viteMessage('transaction_mismatch', { file: transactionFile }))
347
348
  }
348
349
  return transaction
349
350
  }
@@ -459,7 +460,7 @@ function acquirePageAssemblyLock(lockFile: string): void {
459
460
  continue
460
461
  }
461
462
  if (Date.now() >= deadline) {
462
- throw new Error(`等待 uni-app 页面装配锁超时:${lockFile}`)
463
+ throw new Error(viteMessage('assembly_timeout', { file: lockFile }))
463
464
  }
464
465
  waitForPageAssembly(PAGE_ASSEMBLY_POLL_INTERVAL_MS)
465
466
  }
@@ -637,7 +638,8 @@ function resolveSourceFile(target: string): string {
637
638
  ]
638
639
  const resolved =
639
640
  candidates.find((candidate) => existsSync(candidate) && statSync(candidate).isFile()) ?? target
640
- if (!isAbsolute(resolved)) throw new Error(`模块源码路径不是绝对路径:${resolved}`)
641
+ if (!isAbsolute(resolved))
642
+ throw new Error(viteMessage('source_path_not_absolute', { path: resolved }))
641
643
  return resolved
642
644
  }
643
645