vite-gc-i18n-plugin 1.1.7 → 1.1.8

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/dist/index.cjs CHANGED
@@ -1105,71 +1105,131 @@ function initLangFile() {
1105
1105
  initTranslateBasicFnFile();
1106
1106
  }
1107
1107
  /**
1108
- * @description: 初始化翻译基础函数文件
1109
- * @returns {void}
1108
+ * Normalize a language key for runtime storage aliases.
1109
+ * Examples: zh-cn -> zhcn, en -> en.
1110
1110
  */
1111
- async function initTranslateBasicFnFile() {
1112
- // 从配置选项中获取必要的配置信息
1113
- const {
1114
- targetLangList
1115
- } = exports.option;
1116
- // 生成语言映射列表
1117
- let languages = [];
1118
- let langList = targetLangList.map(item => {
1119
- const parts = item.split('-');
1120
- const lang = parts[0] + '-' + parts[1].toUpperCase();
1121
- return _.find(allLanguage, {
1122
- code: lang
1123
- });
1124
- });
1125
- langList
1126
- // 构建语言映射项
1127
- .map(item => {
1128
- languages.push(`{
1129
- code: "${item.code}",
1130
- name: "${item.name}"
1131
- }`);
1111
+ function normalizeRuntimeLangKey(langKey) {
1112
+ return String(langKey || '').toLowerCase().replace(/[^a-z0-9]/g, '');
1113
+ }
1114
+ function resolveLanguageMeta(langKey) {
1115
+ const [lang, region] = langKey.split('-');
1116
+ const normalizedCode = region ? `${lang}-${region.toUpperCase()}` : langKey;
1117
+ const matched = _.find(allLanguage, {
1118
+ code: normalizedCode
1132
1119
  });
1133
- // 用逗号和换行符连接所有映射项
1134
- const translateBasicFnText = `
1135
- import gc_i18n from 'gc_i18n'
1136
- export const languages = [${languages.toString()}]
1137
- const gcI18nInstance = new gc_i18n({
1138
- appCode: 'TEST',
1139
- env: 'dev', // local 本地部署 dev 多语言测试环境 prod 多语言生产环境
1140
- orgCode: 'GREENCLOUD',
1141
- messages: {} // 如果你需要自己引入语言包
1142
- })
1143
- export default {
1144
- install(app, router) {
1145
- gcI18nInstance.setRouter(router)
1120
+ return {
1121
+ code: matched?.code || normalizedCode,
1122
+ name: matched?.name || langKey
1123
+ };
1124
+ }
1125
+ function getRuntimeLangKeys() {
1126
+ return Array.from(new Set([exports.option.originLang, ...exports.option.targetLangList].filter(Boolean)));
1127
+ }
1128
+
1129
+ /**
1130
+ * Create the self-contained browser runtime written to lang/index.js.
1131
+ *
1132
+ * The runtime intentionally avoids importing an external gc_i18n package so generated
1133
+ * examples/apps can translate transformed calls immediately after importing ./lang.
1134
+ */
1135
+ function createRuntimeIndexCode() {
1136
+ const namespace = exports.option.namespace || 'lang';
1137
+ const commonTranslateKey = exports.option.commonTranslateKey || '';
1138
+ const originRuntimeKey = normalizeRuntimeLangKey(exports.option.originLang);
1139
+ const languages = exports.option.targetLangList.map(resolveLanguageMeta);
1140
+ const langEntries = getRuntimeLangKeys().map(langKey => {
1141
+ const runtimeKey = normalizeRuntimeLangKey(langKey);
1142
+ return ` '${runtimeKey}': getJSONKey('${langKey}', langJSON)`;
1143
+ }).join(',\n');
1144
+ return `import langJSON from './index.json'
1145
+
1146
+ export const languages = ${JSON.stringify(languages, null, 4)}
1147
+
1148
+ const DEFAULT_NAMESPACE = '${namespace}'
1149
+ const COMMON_TRANSLATE_KEY = '${commonTranslateKey}'
1150
+ const ORIGIN_LANG = '${originRuntimeKey}'
1151
+ const root = typeof globalThis !== 'undefined' ? globalThis : window
1152
+
1153
+ function normalizeLangKey(lang) {
1154
+ return String(lang || '').toLowerCase().replace(/[^a-z0-9]/g, '')
1155
+ }
1156
+
1157
+ function getJSONKey(key, insertJSONObj = langJSON) {
1158
+ const langObj = {}
1159
+ Object.keys(insertJSONObj || {}).forEach(value => {
1160
+ langObj[value] = insertJSONObj[value] && insertJSONObj[value][key]
1161
+ })
1162
+ return langObj
1163
+ }
1164
+
1165
+ function createTranslate(defaultNamespace) {
1166
+ const translate = function (key, val, nameSpace = defaultNamespace) {
1167
+ const langPackage = translate[nameSpace] || {}
1168
+ return langPackage[key] || val
1146
1169
  }
1147
- }`;
1148
- // 构建翻译基础函数文件的路径
1149
- const indexPath = path.join(exports.option.globalPath, 'index.js');
1170
+ translate.locale = function (locale, nameSpace = defaultNamespace) {
1171
+ translate[nameSpace] = locale || {}
1172
+ }
1173
+ return translate
1174
+ }
1150
1175
 
1151
- // 文件已存在 同时 不重写配置,那么这里就结束
1152
- if (fs.existsSync(indexPath) && !exports.option.rewriteConfig) return;
1176
+ root.$t = root.$t || createTranslate(DEFAULT_NAMESPACE)
1177
+ root.$$t = root.$$t || function (val) {
1178
+ return val
1179
+ }
1180
+ root.$deepScan = root.$deepScan || function (val) {
1181
+ return val
1182
+ }
1183
+ root._getJSONKey = root._getJSONKey || getJSONKey
1153
1184
 
1154
- // 新增哈希比对逻辑
1185
+ const runtimeLangMap = {
1186
+ ${langEntries}
1187
+ }
1188
+ const existingLangMap = root.langMap || {}
1189
+ const langMap = { ...runtimeLangMap, ...existingLangMap }
1190
+ root.langMap = langMap
1155
1191
 
1156
- // 标记是否需要更新文件
1157
- let needUpdate = true;
1158
- if (fs.existsSync(indexPath)) {
1159
- // 检查文件是否已存在
1160
- // 读取现有文件内容
1161
- const existingContent = fs.readFileSync(indexPath, 'utf-8');
1162
- // 生成现有内容的哈希值
1163
- const existingHash = generateId(existingContent);
1164
- // 判断是否需要更新文件
1165
- // needUpdate = currentHash !== existingHash
1166
- needUpdate = !existingHash;
1167
- }
1192
+ function readStorageLang(key) {
1193
+ if (!key || !root.localStorage || typeof root.localStorage.getItem !== 'function') {
1194
+ return ''
1195
+ }
1196
+ return root.localStorage.getItem(key) || ''
1197
+ }
1168
1198
 
1169
- // 如果需要更新文件,则写入新内容
1170
- if (needUpdate) {
1171
- fs.writeFileSync(indexPath, translateBasicFnText);
1172
- }
1199
+ function applyLanguage(lang, nameSpace = DEFAULT_NAMESPACE) {
1200
+ const runtimeKey = normalizeLangKey(lang) || ORIGIN_LANG
1201
+ const locale = langMap[runtimeKey] || langMap[ORIGIN_LANG] || {}
1202
+ root.$t.locale(locale, nameSpace)
1203
+ return locale
1204
+ }
1205
+
1206
+ const storedCommonLang = readStorageLang(COMMON_TRANSLATE_KEY)
1207
+ const storedLang = readStorageLang('lang')
1208
+ applyLanguage(storedCommonLang || storedLang || ORIGIN_LANG)
1209
+
1210
+ root.$changeLang = function (lang, nameSpace = DEFAULT_NAMESPACE) {
1211
+ return applyLanguage(lang, nameSpace)
1212
+ }
1213
+
1214
+ export default {
1215
+ install() {
1216
+ applyLanguage(readStorageLang(COMMON_TRANSLATE_KEY) || readStorageLang('lang') || ORIGIN_LANG)
1217
+ }
1218
+ }
1219
+ `;
1220
+ }
1221
+
1222
+ /**
1223
+ * @description: 初始化翻译基础函数文件
1224
+ * @returns {void}
1225
+ */
1226
+ async function initTranslateBasicFnFile() {
1227
+ const indexPath = path.join(exports.option.globalPath, 'index.js');
1228
+
1229
+ // 项目已有 lang/index.js 时保留项目自定义运行时,不再由插件覆盖。
1230
+ if (fs.existsSync(indexPath)) return;
1231
+ const translateBasicFnText = createRuntimeIndexCode();
1232
+ fs.writeFileSync(indexPath, translateBasicFnText);
1173
1233
  }
1174
1234
  /**
1175
1235
  * @description: 生成国际化JSON文件
@@ -1294,11 +1354,13 @@ function uploadFile() {
1294
1354
 
1295
1355
  var file = /*#__PURE__*/Object.freeze({
1296
1356
  __proto__: null,
1357
+ createRuntimeIndexCode: createRuntimeIndexCode,
1297
1358
  getLangObjByJSONFileWithLangKey: getLangObjByJSONFileWithLangKey,
1298
1359
  getLangTranslateJSONFile: getLangTranslateJSONFile,
1299
1360
  initLangFile: initLangFile,
1300
1361
  initLangTranslateJSONFile: initLangTranslateJSONFile,
1301
1362
  initTranslateBasicFnFile: initTranslateBasicFnFile,
1363
+ normalizeRuntimeLangKey: normalizeRuntimeLangKey,
1302
1364
  setLangTranslateJSONFile: setLangTranslateJSONFile,
1303
1365
  uploadFile: uploadFile
1304
1366
  });
@@ -1839,6 +1901,13 @@ function createI18nTranslator(createOption) {
1839
1901
  uncodeValue: valStr,
1840
1902
  namespace: nameSpace
1841
1903
  };
1904
+ insertOption?.collector?.record?.({
1905
+ key: exports.option.useValueAsKey ? trimmedValue : generatedKey,
1906
+ value: trimmedValue,
1907
+ namespace: nameSpace,
1908
+ resourcePath: insertOption?.resourcePath,
1909
+ root: insertOption?.root
1910
+ });
1842
1911
  if (exports.option.translateExtends) {
1843
1912
  const {
1844
1913
  handleCodeCall,
@@ -2470,9 +2539,13 @@ function getExpressionPlaceholder(expression) {
2470
2539
  return getExpressionPlaceholder(expression.expression);
2471
2540
  }
2472
2541
  const generateCode = generate__namespace.default?.default || generate__namespace.default || generate__namespace;
2473
- return generateCode(expression, {
2542
+ return normalizeExpressionPlaceholder(generateCode(expression, {
2474
2543
  comments: false
2475
- }).code;
2544
+ }).code);
2545
+ }
2546
+ function normalizeExpressionPlaceholder(placeholder) {
2547
+ if (placeholder === null) return null;
2548
+ return placeholder.replace(/(^|[^\w$])(?:_vm|\$data)\s*\./g, '$1').replace(/(^|[^\w$])(?:_vm|\$data)\s*\[/g, '$1[');
2476
2549
  }
2477
2550
  function optimizeConditionalExpression(expression) {
2478
2551
  if (!types.isConditionalExpression(expression)) return null;
@@ -2718,11 +2791,11 @@ function CallExpressionFn (insertOption) {
2718
2791
  isExpression: true
2719
2792
  });
2720
2793
  path.replaceWith(replaceNode);
2721
- translateSetLang(replaceNode);
2794
+ translateSetLang(replaceNode, insertOption);
2722
2795
  }
2723
2796
  } else if (exports.option.translateType === TranslateTypeEnum.FULL_AUTO) {
2724
2797
  // 全自动模式下还是只收集 单独 $t 调用
2725
- if (callee.name === exports.option.translateKey || callee.property && callee.property.name === exports.option.translateKey) translateSetLang(node);
2798
+ if (callee.name === exports.option.translateKey || callee.property && callee.property.name === exports.option.translateKey) translateSetLang(node, insertOption);
2726
2799
  }
2727
2800
  }
2728
2801
  };
@@ -2733,7 +2806,7 @@ function CallExpressionFn (insertOption) {
2733
2806
  * @param node - 调用表达式节点
2734
2807
  * @return
2735
2808
  */
2736
- function translateSetLang(node) {
2809
+ function translateSetLang(node, insertOption) {
2737
2810
  // 获取调用表达式的参数
2738
2811
  let arg = node.arguments || [];
2739
2812
  // 提取参数作为值
@@ -2754,6 +2827,13 @@ function translateSetLang(node) {
2754
2827
  }
2755
2828
  // 调用翻译工具的 setLangObj 方法设置语言对象属性
2756
2829
  setLangObj(resolvedId, value);
2830
+ insertOption?.collector?.record?.({
2831
+ key: exports.option.useValueAsKey ? value : resolvedId,
2832
+ value,
2833
+ namespace: exports.option.namespace,
2834
+ resourcePath: insertOption?.resourcePath,
2835
+ root: insertOption?.root
2836
+ });
2757
2837
  }
2758
2838
  }
2759
2839
 
@@ -2895,10 +2975,310 @@ var index$1 = /*#__PURE__*/Object.freeze({
2895
2975
  default: index
2896
2976
  });
2897
2977
 
2978
+ const RUNTIME_MANIFEST_VERSION = 1;
2979
+ const RUNTIME_MANIFEST_GLOBAL = '__GC_I18N_RUNTIME_MANIFEST__';
2980
+ const VITE_RUNTIME_MANIFEST_ID = 'virtual:gc-i18n-runtime-manifest';
2981
+ const VITE_RUNTIME_BOOTSTRAP_ID = 'virtual:gc-i18n-runtime-bootstrap';
2982
+ const RESOLVED_VITE_RUNTIME_MANIFEST_ID = `\0${VITE_RUNTIME_MANIFEST_ID}`;
2983
+ const RESOLVED_VITE_RUNTIME_BOOTSTRAP_ID = `\0${VITE_RUNTIME_BOOTSTRAP_ID}`;
2984
+ function normalizeResourcePath(resourcePath, root) {
2985
+ if (!resourcePath) return undefined;
2986
+ if (!root) return resourcePath;
2987
+ const relativePath = path.relative(root, resourcePath);
2988
+ return relativePath && !relativePath.startsWith('..') ? relativePath : resourcePath;
2989
+ }
2990
+ function createI18nManifestCollector() {
2991
+ let root = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : process.cwd();
2992
+ const records = new Map();
2993
+ return {
2994
+ record(input) {
2995
+ if (!input.key || !input.value) return;
2996
+ const resourcePath = normalizeResourcePath(input.resourcePath, input.root || root);
2997
+ const namespace = input.namespace || 'lang';
2998
+ const dedupeKey = [namespace, resourcePath || '', input.key].join('\u0000');
2999
+ records.set(dedupeKey, {
3000
+ key: input.key,
3001
+ value: input.value,
3002
+ namespace,
3003
+ ...(resourcePath ? {
3004
+ resourcePath
3005
+ } : {})
3006
+ });
3007
+ },
3008
+ toJSON() {
3009
+ let option = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
3010
+ const recordList = Array.from(records.values()).sort((left, right) => {
3011
+ const leftPath = left.resourcePath || '';
3012
+ const rightPath = right.resourcePath || '';
3013
+ return leftPath.localeCompare(rightPath) || left.key.localeCompare(right.key);
3014
+ });
3015
+ const resourceMap = new Map();
3016
+ const allKeys = new Set();
3017
+ recordList.forEach(record => {
3018
+ const resourcePath = record.resourcePath || '<unknown>';
3019
+ const keys = resourceMap.get(resourcePath) || new Set();
3020
+ keys.add(record.key);
3021
+ allKeys.add(record.key);
3022
+ resourceMap.set(resourcePath, keys);
3023
+ });
3024
+ const byFile = Object.fromEntries(Array.from(resourceMap.entries()).map(_ref => {
3025
+ let [resourcePath, keys] = _ref;
3026
+ return [resourcePath, Array.from(keys).sort()];
3027
+ }));
3028
+ return {
3029
+ version: RUNTIME_MANIFEST_VERSION,
3030
+ namespace: option.namespace || 'lang',
3031
+ translateKey: option.translateKey || '$t',
3032
+ originLang: option.originLang || 'zh-cn',
3033
+ targetLangList: option.targetLangList || [],
3034
+ resources: Object.entries(byFile).map(_ref2 => {
3035
+ let [resourcePath, keys] = _ref2;
3036
+ return {
3037
+ path: resourcePath,
3038
+ keys
3039
+ };
3040
+ }),
3041
+ byFile,
3042
+ allKeys: Array.from(allKeys).sort(),
3043
+ records: recordList
3044
+ };
3045
+ },
3046
+ clear() {
3047
+ records.clear();
3048
+ }
3049
+ };
3050
+ }
3051
+ function serializeRuntimeManifest(manifest) {
3052
+ return `const manifest = ${JSON.stringify(manifest, null, 2)};\nexport { manifest };\nexport default manifest;\n`;
3053
+ }
3054
+ function createRuntimeBootstrapCode() {
3055
+ let manifestModuleId = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : VITE_RUNTIME_MANIFEST_ID;
3056
+ return `import manifest from ${JSON.stringify(manifestModuleId)};\nconst target = typeof globalThis !== 'undefined' ? globalThis : window;\ntarget[${JSON.stringify(RUNTIME_MANIFEST_GLOBAL)}] = manifest;\nexport { manifest };\nexport default manifest;\n`;
3057
+ }
3058
+ function writeWebpackRuntimeBootstrap(root, manifestAssetName) {
3059
+ const outputDir = path.join(root, 'node_modules', '.cache', 'gc-i18n-plugin');
3060
+ fs.mkdirSync(outputDir, {
3061
+ recursive: true
3062
+ });
3063
+ const bootstrapPath = path.join(outputDir, 'runtime-bootstrap.js');
3064
+ const source = `if (typeof globalThis !== 'undefined') {\n globalThis[${JSON.stringify(RUNTIME_MANIFEST_GLOBAL)}] = globalThis[${JSON.stringify(RUNTIME_MANIFEST_GLOBAL)}] || { version: ${RUNTIME_MANIFEST_VERSION}, resources: [], records: [] };\n globalThis[${JSON.stringify(RUNTIME_MANIFEST_GLOBAL)}].asset = ${JSON.stringify(manifestAssetName)};\n}\n`;
3065
+ fs.writeFileSync(bootstrapPath, source);
3066
+ return bootstrapPath;
3067
+ }
3068
+ function prependWebpackEntry(entry, bootstrapPath) {
3069
+ if (!entry) return entry;
3070
+ if (typeof entry === 'string') return [bootstrapPath, entry];
3071
+ if (Array.isArray(entry)) return [bootstrapPath, ...entry];
3072
+ if (typeof entry === 'function') {
3073
+ return async () => prependWebpackEntry(await entry(), bootstrapPath);
3074
+ }
3075
+ if (typeof entry === 'object') {
3076
+ return Object.fromEntries(Object.entries(entry).map(_ref3 => {
3077
+ let [name, value] = _ref3;
3078
+ if (typeof value === 'string' || Array.isArray(value)) {
3079
+ return [name, prependWebpackEntry(value, bootstrapPath)];
3080
+ }
3081
+ if (value && typeof value === 'object' && 'import' in value) {
3082
+ return [name, {
3083
+ ...value,
3084
+ import: prependWebpackEntry(value.import, bootstrapPath)
3085
+ }];
3086
+ }
3087
+ return [name, value];
3088
+ }));
3089
+ }
3090
+ return entry;
3091
+ }
3092
+
3093
+ const RTL_LANGUAGES = new Set(['ar', 'fa', 'he', 'iw', 'ps', 'ur']);
3094
+ const DEFAULT_NAMESPACE = 'lang';
3095
+ const DEFAULT_HOTKEY = 'Alt+KeyI';
3096
+ function normalizeLocale(locale) {
3097
+ let fallback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
3098
+ return String(locale || fallback).toLowerCase().replace(/_/g, '-');
3099
+ }
3100
+ function normalizeStorageKey(locale) {
3101
+ let fallback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
3102
+ return normalizeLocale(locale, fallback).replace(/[^a-z0-9]/g, '');
3103
+ }
3104
+ function cloneMessages(messages) {
3105
+ return Object.keys(messages || {}).reduce((result, locale) => {
3106
+ result[normalizeStorageKey(locale)] = {
3107
+ ...(messages?.[locale] || {})
3108
+ };
3109
+ return result;
3110
+ }, {});
3111
+ }
3112
+ function mergeMessageLayers() {
3113
+ for (var _len = arguments.length, layers = new Array(_len), _key = 0; _key < _len; _key++) {
3114
+ layers[_key] = arguments[_key];
3115
+ }
3116
+ return layers.reduce((result, layer) => {
3117
+ Object.keys(layer || {}).forEach(locale => {
3118
+ const runtimeLocale = normalizeStorageKey(locale);
3119
+ result[runtimeLocale] = {
3120
+ ...(result[runtimeLocale] || {}),
3121
+ ...(layer?.[locale] || {})
3122
+ };
3123
+ });
3124
+ return result;
3125
+ }, {});
3126
+ }
3127
+ function getMessagesForLocale(messages, runtimeLocale) {
3128
+ const baseLocale = runtimeLocale.slice(0, 2);
3129
+ return {
3130
+ ...(messages[runtimeLocale] || {}),
3131
+ ...(baseLocale === runtimeLocale ? {} : messages[baseLocale] || {})
3132
+ };
3133
+ }
3134
+ function interpolate(template, params) {
3135
+ if (!params) return template;
3136
+ return template.replace(/\{\{?\s*([\w.]+)\s*\}?\}/g, (match, path) => {
3137
+ const value = String(path).split('.').reduce((current, key) => {
3138
+ if (current && typeof current === 'object' && key in current) {
3139
+ return current[key];
3140
+ }
3141
+ return undefined;
3142
+ }, params);
3143
+ return value === undefined || value === null ? match : String(value);
3144
+ });
3145
+ }
3146
+ function parseHotkey(event, hotkey) {
3147
+ const parts = hotkey.split('+');
3148
+ const code = parts.pop();
3149
+ const modifiers = new Set(parts.map(part => part.toLowerCase()));
3150
+ return (!modifiers.has('alt') || !!event.altKey) && (!modifiers.has('ctrl') || !!event.ctrlKey) && (!modifiers.has('meta') || !!event.metaKey) && (!modifiers.has('shift') || !!event.shiftKey) && (!code || event.code === code || event.key === code);
3151
+ }
3152
+ function createI18nRuntime() {
3153
+ let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
3154
+ const namespace = options.namespace || DEFAULT_NAMESPACE;
3155
+ const fallbackLocale = normalizeStorageKey(options.fallbackLocale || options.initialLocale || 'zh-cn');
3156
+ let locale = normalizeStorageKey(options.initialLocale, fallbackLocale);
3157
+ let commonMessages = cloneMessages(options.commonMessages);
3158
+ let localMessages = cloneMessages(options.localMessages);
3159
+ let remoteMessages = cloneMessages(options.remoteMessages);
3160
+ const delta = new Map();
3161
+ const runtime = {
3162
+ namespace,
3163
+ getLocale() {
3164
+ return locale;
3165
+ },
3166
+ setRemoteMessages(messages) {
3167
+ remoteMessages = cloneMessages(messages);
3168
+ },
3169
+ mergeMessages(messages) {
3170
+ let layer = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'local';
3171
+ if (layer === 'common') commonMessages = mergeMessageLayers(commonMessages, cloneMessages(messages));
3172
+ if (layer === 'local') localMessages = mergeMessageLayers(localMessages, cloneMessages(messages));
3173
+ if (layer === 'remote') remoteMessages = mergeMessageLayers(remoteMessages, cloneMessages(messages));
3174
+ },
3175
+ t(key) {
3176
+ let value = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
3177
+ let params = arguments.length > 2 ? arguments[2] : undefined;
3178
+ let callNamespace = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : namespace;
3179
+ const interpolationParams = typeof value === 'object' ? value : params;
3180
+ const fallbackValue = typeof value === 'string' ? value : key;
3181
+ const messages = runtime.getMergedMessages();
3182
+ const localeMessages = {
3183
+ ...getMessagesForLocale(messages, fallbackLocale),
3184
+ ...getMessagesForLocale(messages, locale)
3185
+ };
3186
+ const translated = localeMessages[key];
3187
+ if (translated === undefined) {
3188
+ const deltaKey = `${callNamespace}:${locale}:${key}`;
3189
+ if (!delta.has(deltaKey)) {
3190
+ delta.set(deltaKey, {
3191
+ key,
3192
+ value: fallbackValue,
3193
+ locale,
3194
+ namespace: callNamespace
3195
+ });
3196
+ }
3197
+ }
3198
+ return interpolate(translated || fallbackValue || key, interpolationParams);
3199
+ },
3200
+ changeLocale(nextLocale) {
3201
+ locale = normalizeStorageKey(nextLocale, fallbackLocale);
3202
+ return locale;
3203
+ },
3204
+ clearI18n() {
3205
+ remoteMessages = {};
3206
+ delta.clear();
3207
+ },
3208
+ isRTL() {
3209
+ let targetLocale = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : locale;
3210
+ const lang = normalizeLocale(targetLocale).split('-')[0];
3211
+ return RTL_LANGUAGES.has(lang);
3212
+ },
3213
+ getDelta() {
3214
+ return Array.from(delta.values());
3215
+ },
3216
+ getMergedMessages() {
3217
+ return mergeMessageLayers(commonMessages, localMessages, remoteMessages);
3218
+ },
3219
+ requestConfig() {
3220
+ const payload = {
3221
+ locale,
3222
+ namespace,
3223
+ delta: runtime.getDelta(),
3224
+ messages: runtime.getMergedMessages()
3225
+ };
3226
+ options.onConfigRequest?.(payload);
3227
+ return payload;
3228
+ },
3229
+ install() {
3230
+ let target = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : options.target || (typeof globalThis !== 'undefined' ? globalThis : undefined);
3231
+ if (!target) return runtime;
3232
+ target.$t = runtime.t;
3233
+ target.$changeLocale = runtime.changeLocale;
3234
+ target.$clearI18n = runtime.clearI18n;
3235
+ target.$isRTL = runtime.isRTL;
3236
+ target.__GC_I18N_RUNTIME__ = runtime;
3237
+ return runtime;
3238
+ }
3239
+ };
3240
+ return runtime;
3241
+ }
3242
+ function installI18nRuntime(app) {
3243
+ let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
3244
+ const runtime = createI18nRuntime({
3245
+ ...options,
3246
+ localMessages: mergeMessageLayers(options.localMessages, options.messages)
3247
+ });
3248
+ runtime.install(options.target);
3249
+ if (app && typeof app.config === 'object') {
3250
+ app.config.globalProperties = app.config.globalProperties || {};
3251
+ app.config.globalProperties.$t = runtime.t;
3252
+ app.config.globalProperties.$changeLocale = runtime.changeLocale;
3253
+ app.config.globalProperties.$clearI18n = runtime.clearI18n;
3254
+ app.config.globalProperties.$isRTL = runtime.isRTL;
3255
+ }
3256
+ const target = options.target || (typeof globalThis !== 'undefined' ? globalThis : undefined);
3257
+ const hotkey = options.hotkey === false ? false : options.hotkey || DEFAULT_HOTKEY;
3258
+ if (target && hotkey && typeof target.addEventListener === 'function') {
3259
+ target.addEventListener('keydown', event => {
3260
+ if (!parseHotkey(event, hotkey)) return;
3261
+ const payload = runtime.requestConfig();
3262
+ if (typeof target.dispatchEvent === 'function' && typeof target.CustomEvent === 'function') {
3263
+ target.dispatchEvent(new target.CustomEvent('gc-i18n-config-request', {
3264
+ detail: payload
3265
+ }));
3266
+ }
3267
+ });
3268
+ }
3269
+ return runtime;
3270
+ }
3271
+ const runtimeUtils = {
3272
+ normalizeLocale,
3273
+ normalizeStorageKey,
3274
+ mergeMessageLayers
3275
+ };
3276
+
2898
3277
  var allowedExtensions = ['.vue', '.ts', '.js', '.tsx', '.jsx'];
2899
3278
  function vitePluginsAutoI18n(optionInfo) {
2900
3279
  var name = 'vite-gc-i18n-plugin';
2901
3280
  var config;
3281
+ var collector = createI18nManifestCollector();
2902
3282
  initOption(__assign({
2903
3283
  deepScan: true,
2904
3284
  globalPath: './lang',
@@ -2923,6 +3303,27 @@ function vitePluginsAutoI18n(optionInfo) {
2923
3303
  // 存储最终解析的配置
2924
3304
  config = resolvedConfig;
2925
3305
  },
3306
+ resolveId: function (id) {
3307
+ if (id === VITE_RUNTIME_MANIFEST_ID) return RESOLVED_VITE_RUNTIME_MANIFEST_ID;
3308
+ if (id === VITE_RUNTIME_BOOTSTRAP_ID) return RESOLVED_VITE_RUNTIME_BOOTSTRAP_ID;
3309
+ },
3310
+ load: function (id) {
3311
+ if (id === RESOLVED_VITE_RUNTIME_MANIFEST_ID) {
3312
+ return serializeRuntimeManifest(collector.toJSON({
3313
+ namespace: exports.option.namespace,
3314
+ translateKey: exports.option.translateKey,
3315
+ originLang: exports.option.originLang,
3316
+ targetLangList: exports.option.targetLangList
3317
+ }));
3318
+ }
3319
+ if (id === RESOLVED_VITE_RUNTIME_BOOTSTRAP_ID) {
3320
+ return createRuntimeBootstrapCode();
3321
+ }
3322
+ },
3323
+ transformIndexHtml: function (html) {
3324
+ var bootstrap = "<script type=\"module\">import ".concat(JSON.stringify(VITE_RUNTIME_BOOTSTRAP_ID), ";</script>");
3325
+ return html.includes(VITE_RUNTIME_BOOTSTRAP_ID) ? html : html.replace('</head>', "".concat(bootstrap, "\n</head>"));
3326
+ },
2926
3327
  transform: function (code, path) {
2927
3328
  return __awaiter(this, void 0, void 0, function () {
2928
3329
  var sourceObj;
@@ -2950,7 +3351,11 @@ function vitePluginsAutoI18n(optionInfo) {
2950
3351
  case 3:
2951
3352
  return [2 /*return*/, babel__namespace.transformAsync(sourceObj.source, {
2952
3353
  configFile: false,
2953
- plugins: [index()]
3354
+ plugins: [index(__assign(__assign({}, sourceObj), {
3355
+ resourcePath: path,
3356
+ root: config === null || config === void 0 ? void 0 : config.root,
3357
+ collector: collector
3358
+ }))]
2954
3359
  }).then(function (result) {
2955
3360
  if ((config === null || config === void 0 ? void 0 : config.command) === 'serve') {
2956
3361
  autoTranslate(); // 执行前需要确保transformAsync已经完成
@@ -3011,19 +3416,33 @@ exports.FunctionFactoryOption = FunctionFactoryOption;
3011
3416
  exports.GoogleTranslator = GoogleTranslator;
3012
3417
  exports.LanguageEnum = LanguageEnum;
3013
3418
  exports.OriginLangKeyEnum = OriginLangKeyEnum;
3419
+ exports.RESOLVED_VITE_RUNTIME_BOOTSTRAP_ID = RESOLVED_VITE_RUNTIME_BOOTSTRAP_ID;
3420
+ exports.RESOLVED_VITE_RUNTIME_MANIFEST_ID = RESOLVED_VITE_RUNTIME_MANIFEST_ID;
3421
+ exports.RUNTIME_MANIFEST_GLOBAL = RUNTIME_MANIFEST_GLOBAL;
3422
+ exports.RUNTIME_MANIFEST_VERSION = RUNTIME_MANIFEST_VERSION;
3014
3423
  exports.ScanTranslator = ScanTranslator;
3015
3424
  exports.TranslateApiEnum = TranslateApiEnum;
3016
3425
  exports.TranslateTypeEnum = TranslateTypeEnum;
3017
3426
  exports.Translator = Translator;
3427
+ exports.VITE_RUNTIME_BOOTSTRAP_ID = VITE_RUNTIME_BOOTSTRAP_ID;
3428
+ exports.VITE_RUNTIME_MANIFEST_ID = VITE_RUNTIME_MANIFEST_ID;
3018
3429
  exports.VolcengineTranslator = VolcengineTranslator;
3019
3430
  exports.Vue2Extends = Vue2Extends;
3020
3431
  exports.YoudaoTranslator = YoudaoTranslator;
3021
3432
  exports.baseUtils = base;
3022
3433
  exports.checkOption = checkOption;
3434
+ exports.createI18nManifestCollector = createI18nManifestCollector;
3435
+ exports.createI18nRuntime = createI18nRuntime;
3436
+ exports.createRuntimeBootstrapCode = createRuntimeBootstrapCode;
3023
3437
  exports.default = vitePluginsAutoI18n;
3024
3438
  exports.fileUtils = file;
3025
3439
  exports.filter = index$1;
3026
3440
  exports.initOption = initOption;
3441
+ exports.installI18nRuntime = installI18nRuntime;
3442
+ exports.prependWebpackEntry = prependWebpackEntry;
3443
+ exports.runtimeUtils = runtimeUtils;
3444
+ exports.serializeRuntimeManifest = serializeRuntimeManifest;
3027
3445
  exports.translateUtils = translate;
3028
3446
  exports.uploadUtils = upload$1;
3447
+ exports.writeWebpackRuntimeBootstrap = writeWebpackRuntimeBootstrap;
3029
3448
  //# sourceMappingURL=index.cjs.map