vite-gc-i18n-plugin 1.1.6 → 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 +497 -68
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +120 -2
- package/dist/index.mjs +484 -69
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1105,71 +1105,131 @@ function initLangFile() {
|
|
|
1105
1105
|
initTranslateBasicFnFile();
|
|
1106
1106
|
}
|
|
1107
1107
|
/**
|
|
1108
|
-
*
|
|
1109
|
-
*
|
|
1108
|
+
* Normalize a language key for runtime storage aliases.
|
|
1109
|
+
* Examples: zh-cn -> zhcn, en -> en.
|
|
1110
1110
|
*/
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
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
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
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
|
-
|
|
1170
|
+
translate.locale = function (locale, nameSpace = defaultNamespace) {
|
|
1171
|
+
translate[nameSpace] = locale || {}
|
|
1172
|
+
}
|
|
1173
|
+
return translate
|
|
1174
|
+
}
|
|
1150
1175
|
|
|
1151
|
-
|
|
1152
|
-
|
|
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
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
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
|
-
|
|
1171
|
-
|
|
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,17 +2806,34 @@ 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
|
// 提取参数作为值
|
|
2740
2813
|
// 检查参数是否为字符串字面量
|
|
2741
|
-
const
|
|
2742
|
-
const
|
|
2814
|
+
const idArg = arg[0];
|
|
2815
|
+
const valueArg = arg[1];
|
|
2816
|
+
const id = types__namespace.isStringLiteral(idArg) ? idArg.value : '';
|
|
2817
|
+
const value = types__namespace.isStringLiteral(valueArg) ? valueArg.value : '';
|
|
2743
2818
|
// 检查 ID 和值是否存在,并且第二个参数是字符串字面量
|
|
2744
|
-
if (id && value && types__namespace.isStringLiteral(
|
|
2819
|
+
if (id && value && types__namespace.isStringLiteral(idArg) && types__namespace.isStringLiteral(valueArg)) {
|
|
2820
|
+
const resolvedId = resolveLangKey(id, value);
|
|
2821
|
+
if (resolvedId !== id) {
|
|
2822
|
+
idArg.value = resolvedId;
|
|
2823
|
+
idArg.extra = {
|
|
2824
|
+
raw: `'${resolvedId}'`,
|
|
2825
|
+
rawValue: resolvedId
|
|
2826
|
+
};
|
|
2827
|
+
}
|
|
2745
2828
|
// 调用翻译工具的 setLangObj 方法设置语言对象属性
|
|
2746
|
-
setLangObj(
|
|
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
|
+
});
|
|
2747
2837
|
}
|
|
2748
2838
|
}
|
|
2749
2839
|
|
|
@@ -2885,10 +2975,310 @@ var index$1 = /*#__PURE__*/Object.freeze({
|
|
|
2885
2975
|
default: index
|
|
2886
2976
|
});
|
|
2887
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
|
+
|
|
2888
3277
|
var allowedExtensions = ['.vue', '.ts', '.js', '.tsx', '.jsx'];
|
|
2889
3278
|
function vitePluginsAutoI18n(optionInfo) {
|
|
2890
3279
|
var name = 'vite-gc-i18n-plugin';
|
|
2891
3280
|
var config;
|
|
3281
|
+
var collector = createI18nManifestCollector();
|
|
2892
3282
|
initOption(__assign({
|
|
2893
3283
|
deepScan: true,
|
|
2894
3284
|
globalPath: './lang',
|
|
@@ -2913,6 +3303,27 @@ function vitePluginsAutoI18n(optionInfo) {
|
|
|
2913
3303
|
// 存储最终解析的配置
|
|
2914
3304
|
config = resolvedConfig;
|
|
2915
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
|
+
},
|
|
2916
3327
|
transform: function (code, path) {
|
|
2917
3328
|
return __awaiter(this, void 0, void 0, function () {
|
|
2918
3329
|
var sourceObj;
|
|
@@ -2940,7 +3351,11 @@ function vitePluginsAutoI18n(optionInfo) {
|
|
|
2940
3351
|
case 3:
|
|
2941
3352
|
return [2 /*return*/, babel__namespace.transformAsync(sourceObj.source, {
|
|
2942
3353
|
configFile: false,
|
|
2943
|
-
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
|
+
}))]
|
|
2944
3359
|
}).then(function (result) {
|
|
2945
3360
|
if ((config === null || config === void 0 ? void 0 : config.command) === 'serve') {
|
|
2946
3361
|
autoTranslate(); // 执行前需要确保transformAsync已经完成
|
|
@@ -3001,19 +3416,33 @@ exports.FunctionFactoryOption = FunctionFactoryOption;
|
|
|
3001
3416
|
exports.GoogleTranslator = GoogleTranslator;
|
|
3002
3417
|
exports.LanguageEnum = LanguageEnum;
|
|
3003
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;
|
|
3004
3423
|
exports.ScanTranslator = ScanTranslator;
|
|
3005
3424
|
exports.TranslateApiEnum = TranslateApiEnum;
|
|
3006
3425
|
exports.TranslateTypeEnum = TranslateTypeEnum;
|
|
3007
3426
|
exports.Translator = Translator;
|
|
3427
|
+
exports.VITE_RUNTIME_BOOTSTRAP_ID = VITE_RUNTIME_BOOTSTRAP_ID;
|
|
3428
|
+
exports.VITE_RUNTIME_MANIFEST_ID = VITE_RUNTIME_MANIFEST_ID;
|
|
3008
3429
|
exports.VolcengineTranslator = VolcengineTranslator;
|
|
3009
3430
|
exports.Vue2Extends = Vue2Extends;
|
|
3010
3431
|
exports.YoudaoTranslator = YoudaoTranslator;
|
|
3011
3432
|
exports.baseUtils = base;
|
|
3012
3433
|
exports.checkOption = checkOption;
|
|
3434
|
+
exports.createI18nManifestCollector = createI18nManifestCollector;
|
|
3435
|
+
exports.createI18nRuntime = createI18nRuntime;
|
|
3436
|
+
exports.createRuntimeBootstrapCode = createRuntimeBootstrapCode;
|
|
3013
3437
|
exports.default = vitePluginsAutoI18n;
|
|
3014
3438
|
exports.fileUtils = file;
|
|
3015
3439
|
exports.filter = index$1;
|
|
3016
3440
|
exports.initOption = initOption;
|
|
3441
|
+
exports.installI18nRuntime = installI18nRuntime;
|
|
3442
|
+
exports.prependWebpackEntry = prependWebpackEntry;
|
|
3443
|
+
exports.runtimeUtils = runtimeUtils;
|
|
3444
|
+
exports.serializeRuntimeManifest = serializeRuntimeManifest;
|
|
3017
3445
|
exports.translateUtils = translate;
|
|
3018
3446
|
exports.uploadUtils = upload$1;
|
|
3447
|
+
exports.writeWebpackRuntimeBootstrap = writeWebpackRuntimeBootstrap;
|
|
3019
3448
|
//# sourceMappingURL=index.cjs.map
|