@modern-js/plugin-i18n 3.2.2 → 3.4.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/dist/cjs/cli/index.js +7 -59
- package/dist/cjs/cli/locales.js +132 -0
- package/dist/cjs/runtime/i18n/backend/defaults.js +6 -2
- package/dist/cjs/runtime/i18n/backend/defaults.node.js +47 -7
- package/dist/esm/cli/index.mjs +7 -48
- package/dist/esm/cli/locales.mjs +80 -0
- package/dist/esm/runtime/i18n/backend/defaults.mjs +6 -2
- package/dist/esm/runtime/i18n/backend/defaults.node.mjs +33 -2
- package/dist/esm-node/cli/index.mjs +7 -48
- package/dist/esm-node/cli/locales.mjs +81 -0
- package/dist/esm-node/runtime/i18n/backend/defaults.mjs +6 -2
- package/dist/esm-node/runtime/i18n/backend/defaults.node.mjs +33 -2
- package/dist/types/cli/locales.d.ts +17 -0
- package/dist/types/runtime/i18n/backend/defaults.d.ts +10 -7
- package/dist/types/runtime/i18n/backend/defaults.node.d.ts +10 -2
- package/dist/types/shared/type.d.ts +20 -0
- package/package.json +13 -13
- package/src/cli/index.ts +24 -100
- package/src/cli/locales.ts +186 -0
- package/src/runtime/i18n/backend/defaults.node.ts +74 -5
- package/src/runtime/i18n/backend/defaults.ts +20 -16
- package/src/shared/type.ts +20 -0
package/dist/cjs/cli/index.js
CHANGED
|
@@ -1,14 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
var __webpack_require__ = {};
|
|
3
|
-
(()=>{
|
|
4
|
-
__webpack_require__.n = (module)=>{
|
|
5
|
-
var getter = module && module.__esModule ? ()=>module['default'] : ()=>module;
|
|
6
|
-
__webpack_require__.d(getter, {
|
|
7
|
-
a: getter
|
|
8
|
-
});
|
|
9
|
-
return getter;
|
|
10
|
-
};
|
|
11
|
-
})();
|
|
12
3
|
(()=>{
|
|
13
4
|
__webpack_require__.d = (exports1, getters, values)=>{
|
|
14
5
|
var define = (defs, kind)=>{
|
|
@@ -40,43 +31,10 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
40
31
|
default: ()=>cli,
|
|
41
32
|
i18nPlugin: ()=>i18nPlugin
|
|
42
33
|
});
|
|
43
|
-
const external_fs_namespaceObject = require("fs");
|
|
44
|
-
var external_fs_default = /*#__PURE__*/ __webpack_require__.n(external_fs_namespaceObject);
|
|
45
|
-
const external_path_namespaceObject = require("path");
|
|
46
|
-
var external_path_default = /*#__PURE__*/ __webpack_require__.n(external_path_namespaceObject);
|
|
47
34
|
const server_core_namespaceObject = require("@modern-js/server-core");
|
|
48
35
|
const utils_js_namespaceObject = require("../shared/utils.js");
|
|
36
|
+
const external_locales_js_namespaceObject = require("./locales.js");
|
|
49
37
|
require("../runtime/types.js");
|
|
50
|
-
function hasJsonFiles(dirPath) {
|
|
51
|
-
try {
|
|
52
|
-
if (!external_fs_default().existsSync(dirPath) || !external_fs_default().statSync(dirPath).isDirectory()) return false;
|
|
53
|
-
const entries = external_fs_default().readdirSync(dirPath);
|
|
54
|
-
for (const entry of entries){
|
|
55
|
-
const entryPath = external_path_default().join(dirPath, entry);
|
|
56
|
-
const stat = external_fs_default().statSync(entryPath);
|
|
57
|
-
if (stat.isFile() && entry.endsWith('.json')) return true;
|
|
58
|
-
if (stat.isDirectory()) {
|
|
59
|
-
if (hasJsonFiles(entryPath)) return true;
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
return false;
|
|
63
|
-
} catch {
|
|
64
|
-
return false;
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
function detectLocalesDirectory(appDirectory, normalizedConfig) {
|
|
68
|
-
const rootLocalesPath = external_path_default().join(appDirectory, 'locales');
|
|
69
|
-
if (hasJsonFiles(rootLocalesPath)) return true;
|
|
70
|
-
const configPublicPath = external_path_default().join(appDirectory, 'config', 'public', 'locales');
|
|
71
|
-
if (hasJsonFiles(configPublicPath)) return true;
|
|
72
|
-
const publicDir = normalizedConfig?.server?.publicDir;
|
|
73
|
-
if (publicDir) {
|
|
74
|
-
const publicDirPath = Array.isArray(publicDir) ? publicDir[0] : publicDir;
|
|
75
|
-
const localesPath = external_path_default().isAbsolute(publicDirPath) ? external_path_default().join(publicDirPath, 'locales') : external_path_default().join(appDirectory, publicDirPath, 'locales');
|
|
76
|
-
if (hasJsonFiles(localesPath)) return true;
|
|
77
|
-
}
|
|
78
|
-
return false;
|
|
79
|
-
}
|
|
80
38
|
const i18nPlugin = (options = {})=>({
|
|
81
39
|
name: '@modern-js/plugin-i18n',
|
|
82
40
|
setup: (api)=>{
|
|
@@ -86,26 +44,16 @@ const i18nPlugin = (options = {})=>({
|
|
|
86
44
|
let backendOptions;
|
|
87
45
|
const { appDirectory } = api.getAppContext();
|
|
88
46
|
const normalizedConfig = api.getNormalizedConfig();
|
|
47
|
+
const detectedLocales = (0, external_locales_js_namespaceObject.detectLocalesDirectory)(appDirectory, normalizedConfig);
|
|
89
48
|
if (backend) {
|
|
90
49
|
const entryBackendOptions = (0, utils_js_namespaceObject.getBackendOptions)(entrypoint.entryName, backend);
|
|
91
|
-
|
|
92
|
-
else if (entryBackendOptions?.loadPath || entryBackendOptions?.addPath) backendOptions = {
|
|
50
|
+
backendOptions = entryBackendOptions?.enabled === false ? entryBackendOptions : detectedLocales ? (0, external_locales_js_namespaceObject.applyDetectedBackendPaths)(entryBackendOptions, detectedLocales) : entryBackendOptions?.loadPath || entryBackendOptions?.addPath ? {
|
|
93
51
|
...entryBackendOptions,
|
|
94
52
|
enabled: true
|
|
95
|
-
};
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
...entryBackendOptions,
|
|
100
|
-
enabled: true
|
|
101
|
-
} : entryBackendOptions;
|
|
102
|
-
} else backendOptions = entryBackendOptions;
|
|
103
|
-
} else {
|
|
104
|
-
const hasLocales = detectLocalesDirectory(appDirectory, normalizedConfig);
|
|
105
|
-
if (hasLocales) backendOptions = (0, utils_js_namespaceObject.getBackendOptions)(entrypoint.entryName, {
|
|
106
|
-
enabled: true
|
|
107
|
-
});
|
|
108
|
-
}
|
|
53
|
+
} : entryBackendOptions;
|
|
54
|
+
} else if (detectedLocales) backendOptions = (0, external_locales_js_namespaceObject.applyDetectedBackendPaths)((0, utils_js_namespaceObject.getBackendOptions)(entrypoint.entryName, {
|
|
55
|
+
enabled: true
|
|
56
|
+
}), detectedLocales);
|
|
109
57
|
const { metaName } = api.getAppContext();
|
|
110
58
|
let extendedConfig = restOptions;
|
|
111
59
|
if (transformRuntimeConfig) extendedConfig = transformRuntimeConfig(restOptions, entrypoint);
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __webpack_require__ = {};
|
|
3
|
+
(()=>{
|
|
4
|
+
__webpack_require__.n = (module)=>{
|
|
5
|
+
var getter = module && module.__esModule ? ()=>module['default'] : ()=>module;
|
|
6
|
+
__webpack_require__.d(getter, {
|
|
7
|
+
a: getter
|
|
8
|
+
});
|
|
9
|
+
return getter;
|
|
10
|
+
};
|
|
11
|
+
})();
|
|
12
|
+
(()=>{
|
|
13
|
+
__webpack_require__.d = (exports1, getters, values)=>{
|
|
14
|
+
var define = (defs, kind)=>{
|
|
15
|
+
for(var key in defs)if (__webpack_require__.o(defs, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
|
|
16
|
+
enumerable: true,
|
|
17
|
+
[kind]: defs[key]
|
|
18
|
+
});
|
|
19
|
+
};
|
|
20
|
+
define(getters, "get");
|
|
21
|
+
define(values, "value");
|
|
22
|
+
};
|
|
23
|
+
})();
|
|
24
|
+
(()=>{
|
|
25
|
+
__webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
|
|
26
|
+
})();
|
|
27
|
+
(()=>{
|
|
28
|
+
__webpack_require__.r = (exports1)=>{
|
|
29
|
+
if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
|
|
30
|
+
value: 'Module'
|
|
31
|
+
});
|
|
32
|
+
Object.defineProperty(exports1, '__esModule', {
|
|
33
|
+
value: true
|
|
34
|
+
});
|
|
35
|
+
};
|
|
36
|
+
})();
|
|
37
|
+
var __webpack_exports__ = {};
|
|
38
|
+
__webpack_require__.r(__webpack_exports__);
|
|
39
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
40
|
+
applyDetectedBackendPaths: ()=>applyDetectedBackendPaths,
|
|
41
|
+
detectLocalesDirectory: ()=>detectLocalesDirectory
|
|
42
|
+
});
|
|
43
|
+
const external_fs_namespaceObject = require("fs");
|
|
44
|
+
var external_fs_default = /*#__PURE__*/ __webpack_require__.n(external_fs_namespaceObject);
|
|
45
|
+
const external_path_namespaceObject = require("path");
|
|
46
|
+
var external_path_default = /*#__PURE__*/ __webpack_require__.n(external_path_namespaceObject);
|
|
47
|
+
const server_core_namespaceObject = require("@modern-js/server-core");
|
|
48
|
+
const LOCALES_RESOURCE_PATTERN = '{{lng}}/{{ns}}.json';
|
|
49
|
+
function hasJsonFiles(dirPath) {
|
|
50
|
+
try {
|
|
51
|
+
if (!external_fs_default().existsSync(dirPath) || !external_fs_default().statSync(dirPath).isDirectory()) return false;
|
|
52
|
+
const entries = external_fs_default().readdirSync(dirPath);
|
|
53
|
+
for (const entry of entries){
|
|
54
|
+
const entryPath = external_path_default().join(dirPath, entry);
|
|
55
|
+
const stat = external_fs_default().statSync(entryPath);
|
|
56
|
+
if (stat.isFile() && entry.endsWith('.json')) return true;
|
|
57
|
+
if (stat.isDirectory() && hasJsonFiles(entryPath)) return true;
|
|
58
|
+
}
|
|
59
|
+
return false;
|
|
60
|
+
} catch {
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
function toPosixPath(filePath) {
|
|
65
|
+
return filePath.split(external_path_default().sep).join(external_path_default().posix.sep);
|
|
66
|
+
}
|
|
67
|
+
function getPublicDirOutputPath(publicDir) {
|
|
68
|
+
return (0, server_core_namespaceObject.normalizePublicDirPath)(publicDir);
|
|
69
|
+
}
|
|
70
|
+
function buildDetectedLocalesDirectory(clientBasePath, serverBasePath, serverBasePathCandidates = [
|
|
71
|
+
serverBasePath
|
|
72
|
+
]) {
|
|
73
|
+
const normalizedClientBasePath = clientBasePath.startsWith('/') ? clientBasePath : `/${clientBasePath}`;
|
|
74
|
+
const normalizedServerBasePath = toPosixPath(serverBasePath).replace(/\/$/, '');
|
|
75
|
+
const normalizedServerBasePathCandidates = Array.from(new Set(serverBasePathCandidates.map((candidate)=>toPosixPath(candidate).replace(/\/$/, ''))));
|
|
76
|
+
const serverLoadPaths = normalizedServerBasePathCandidates.map((candidate)=>`${candidate}/${LOCALES_RESOURCE_PATTERN}`);
|
|
77
|
+
const serverAddPaths = normalizedServerBasePathCandidates.map((candidate)=>`${candidate}/${LOCALES_RESOURCE_PATTERN}`);
|
|
78
|
+
return {
|
|
79
|
+
loadPath: `${normalizedClientBasePath}/${LOCALES_RESOURCE_PATTERN}`,
|
|
80
|
+
addPath: `${normalizedClientBasePath}/${LOCALES_RESOURCE_PATTERN}`,
|
|
81
|
+
serverLoadPath: `${normalizedServerBasePath}/${LOCALES_RESOURCE_PATTERN}`,
|
|
82
|
+
serverAddPath: `${normalizedServerBasePath}/${LOCALES_RESOURCE_PATTERN}`,
|
|
83
|
+
serverLoadPaths,
|
|
84
|
+
serverAddPaths
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
function detectLocalesDirectory(appDirectory, normalizedConfig) {
|
|
88
|
+
const publicDirs = (0, server_core_namespaceObject.normalizePublicDir)(normalizedConfig?.server?.publicDir);
|
|
89
|
+
const publicDirPrefixes = (0, server_core_namespaceObject.getPublicDirRoutePrefixes)(normalizedConfig?.server?.publicDir);
|
|
90
|
+
for(let index = 0; index < publicDirs.length; index++){
|
|
91
|
+
const publicDir = publicDirs[index];
|
|
92
|
+
if (external_path_default().isAbsolute(publicDir)) continue;
|
|
93
|
+
const publicDirPath = external_path_default().join(appDirectory, publicDir);
|
|
94
|
+
const publicDirPrefix = publicDirPrefixes[index] || `/${(0, server_core_namespaceObject.normalizePublicDirPath)(publicDir)}`;
|
|
95
|
+
const publicDirOutputPath = getPublicDirOutputPath(publicDir);
|
|
96
|
+
if ('locales' === external_path_default().basename((0, server_core_namespaceObject.normalizePublicDirPath)(publicDir)) && hasJsonFiles(publicDirPath)) return buildDetectedLocalesDirectory(publicDirPrefix, `./${publicDirOutputPath}`);
|
|
97
|
+
const localesPath = external_path_default().join(publicDirPath, 'locales');
|
|
98
|
+
if (hasJsonFiles(localesPath)) return buildDetectedLocalesDirectory(`${publicDirPrefix}/locales`, `./${publicDirOutputPath}/locales`);
|
|
99
|
+
}
|
|
100
|
+
const configPublicPath = external_path_default().join(appDirectory, 'config', 'public', 'locales');
|
|
101
|
+
if (hasJsonFiles(configPublicPath)) return buildDetectedLocalesDirectory('/locales', './public/locales', [
|
|
102
|
+
'./config/public/locales',
|
|
103
|
+
'./public/locales'
|
|
104
|
+
]);
|
|
105
|
+
const rootLocalesPath = external_path_default().join(appDirectory, 'locales');
|
|
106
|
+
if (hasJsonFiles(rootLocalesPath)) return buildDetectedLocalesDirectory('/locales', './locales');
|
|
107
|
+
}
|
|
108
|
+
function applyDetectedBackendPaths(backendOptions, detectedLocales) {
|
|
109
|
+
if (!detectedLocales) return backendOptions;
|
|
110
|
+
const backendWithDetectedPaths = {
|
|
111
|
+
...backendOptions,
|
|
112
|
+
enabled: true,
|
|
113
|
+
loadPath: backendOptions.loadPath ?? detectedLocales.loadPath,
|
|
114
|
+
addPath: backendOptions.addPath ?? detectedLocales.addPath,
|
|
115
|
+
serverLoadPath: backendOptions.serverLoadPath ?? detectedLocales.serverLoadPath,
|
|
116
|
+
serverLoadPaths: backendOptions.serverLoadPath || backendOptions.serverLoadPaths ? backendOptions.serverLoadPaths : detectedLocales.serverLoadPaths,
|
|
117
|
+
serverAddPath: backendOptions.serverAddPath ?? detectedLocales.serverAddPath,
|
|
118
|
+
serverAddPaths: backendOptions.serverAddPath || backendOptions.serverAddPaths ? backendOptions.serverAddPaths : detectedLocales.serverAddPaths,
|
|
119
|
+
_detectedLoadPath: detectedLocales.loadPath,
|
|
120
|
+
_detectedAddPath: detectedLocales.addPath
|
|
121
|
+
};
|
|
122
|
+
return backendWithDetectedPaths;
|
|
123
|
+
}
|
|
124
|
+
exports.applyDetectedBackendPaths = __webpack_exports__.applyDetectedBackendPaths;
|
|
125
|
+
exports.detectLocalesDirectory = __webpack_exports__.detectLocalesDirectory;
|
|
126
|
+
for(var __rspack_i in __webpack_exports__)if (-1 === [
|
|
127
|
+
"applyDetectedBackendPaths",
|
|
128
|
+
"detectLocalesDirectory"
|
|
129
|
+
].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
|
|
130
|
+
Object.defineProperty(exports, '__esModule', {
|
|
131
|
+
value: true
|
|
132
|
+
});
|
|
@@ -32,8 +32,6 @@ const DEFAULT_I18NEXT_BACKEND_OPTIONS = {
|
|
|
32
32
|
addPath: '/locales/{{lng}}/{{ns}}.json'
|
|
33
33
|
};
|
|
34
34
|
function convertPath(path) {
|
|
35
|
-
if (!path) return path;
|
|
36
|
-
if (path.startsWith('/')) return `${window.__assetPrefix__ || ''}${path}`;
|
|
37
35
|
return path;
|
|
38
36
|
}
|
|
39
37
|
function convertBackendOptions(options) {
|
|
@@ -41,6 +39,12 @@ function convertBackendOptions(options) {
|
|
|
41
39
|
const converted = {
|
|
42
40
|
...options
|
|
43
41
|
};
|
|
42
|
+
delete converted.serverLoadPath;
|
|
43
|
+
delete converted.serverAddPath;
|
|
44
|
+
delete converted.serverLoadPaths;
|
|
45
|
+
delete converted.serverAddPaths;
|
|
46
|
+
delete converted._detectedLoadPath;
|
|
47
|
+
delete converted._detectedAddPath;
|
|
44
48
|
if (converted.loadPath) converted.loadPath = convertPath(converted.loadPath);
|
|
45
49
|
if (converted.addPath) converted.addPath = convertPath(converted.addPath);
|
|
46
50
|
return converted;
|
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
var __webpack_require__ = {};
|
|
3
|
+
(()=>{
|
|
4
|
+
__webpack_require__.n = (module)=>{
|
|
5
|
+
var getter = module && module.__esModule ? ()=>module['default'] : ()=>module;
|
|
6
|
+
__webpack_require__.d(getter, {
|
|
7
|
+
a: getter
|
|
8
|
+
});
|
|
9
|
+
return getter;
|
|
10
|
+
};
|
|
11
|
+
})();
|
|
3
12
|
(()=>{
|
|
4
13
|
__webpack_require__.d = (exports1, getters, values)=>{
|
|
5
14
|
var define = (defs, kind)=>{
|
|
@@ -27,6 +36,12 @@ var __webpack_require__ = {};
|
|
|
27
36
|
})();
|
|
28
37
|
var __webpack_exports__ = {};
|
|
29
38
|
__webpack_require__.r(__webpack_exports__);
|
|
39
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
40
|
+
DEFAULT_I18NEXT_BACKEND_OPTIONS: ()=>DEFAULT_I18NEXT_BACKEND_OPTIONS,
|
|
41
|
+
convertBackendOptions: ()=>convertBackendOptions
|
|
42
|
+
});
|
|
43
|
+
const external_fs_namespaceObject = require("fs");
|
|
44
|
+
var external_fs_default = /*#__PURE__*/ __webpack_require__.n(external_fs_namespaceObject);
|
|
30
45
|
const DEFAULT_I18NEXT_BACKEND_OPTIONS = {
|
|
31
46
|
loadPath: './locales/{{lng}}/{{ns}}.json',
|
|
32
47
|
addPath: './locales/{{lng}}/{{ns}}.json'
|
|
@@ -36,20 +51,45 @@ function convertPath(path) {
|
|
|
36
51
|
if (path.startsWith('/')) return `.${path}`;
|
|
37
52
|
return path;
|
|
38
53
|
}
|
|
54
|
+
function shouldUseServerPath(currentPath, detectedPath) {
|
|
55
|
+
return !detectedPath || currentPath === detectedPath;
|
|
56
|
+
}
|
|
57
|
+
function getResourceBasePath(resourcePath) {
|
|
58
|
+
const markerIndex = resourcePath.indexOf('{{lng}}');
|
|
59
|
+
if (markerIndex < 0) return resourcePath;
|
|
60
|
+
return resourcePath.slice(0, markerIndex).replace(/[\\/]+$/, '');
|
|
61
|
+
}
|
|
62
|
+
function pathExists(resourcePath) {
|
|
63
|
+
try {
|
|
64
|
+
return external_fs_default().existsSync(getResourceBasePath(resourcePath));
|
|
65
|
+
} catch {
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
function getServerPath(pathCandidates, fallbackPath) {
|
|
70
|
+
const candidates = Array.from(new Set([
|
|
71
|
+
...pathCandidates || [],
|
|
72
|
+
fallbackPath
|
|
73
|
+
].filter(Boolean)));
|
|
74
|
+
return candidates.find(pathExists) || candidates[0];
|
|
75
|
+
}
|
|
39
76
|
function convertBackendOptions(options) {
|
|
40
77
|
if (!options) return options;
|
|
41
78
|
const converted = {
|
|
42
79
|
...options
|
|
43
80
|
};
|
|
44
|
-
if (converted.loadPath) converted.loadPath =
|
|
45
|
-
if (converted.
|
|
81
|
+
if ((converted.serverLoadPath || converted.serverLoadPaths) && shouldUseServerPath(converted.loadPath, converted._detectedLoadPath)) converted.loadPath = getServerPath(converted.serverLoadPaths, converted.serverLoadPath);
|
|
82
|
+
else if (converted.loadPath) converted.loadPath = convertPath(converted.loadPath);
|
|
83
|
+
if ((converted.serverAddPath || converted.serverAddPaths) && shouldUseServerPath(converted.addPath, converted._detectedAddPath)) converted.addPath = getServerPath(converted.serverAddPaths, converted.serverAddPath);
|
|
84
|
+
else if (converted.addPath) converted.addPath = convertPath(converted.addPath);
|
|
85
|
+
delete converted.serverLoadPath;
|
|
86
|
+
delete converted.serverAddPath;
|
|
87
|
+
delete converted.serverLoadPaths;
|
|
88
|
+
delete converted.serverAddPaths;
|
|
89
|
+
delete converted._detectedLoadPath;
|
|
90
|
+
delete converted._detectedAddPath;
|
|
46
91
|
return converted;
|
|
47
92
|
}
|
|
48
|
-
__webpack_require__.d(__webpack_exports__, {
|
|
49
|
-
convertBackendOptions: ()=>convertBackendOptions
|
|
50
|
-
}, {
|
|
51
|
-
DEFAULT_I18NEXT_BACKEND_OPTIONS: DEFAULT_I18NEXT_BACKEND_OPTIONS
|
|
52
|
-
});
|
|
53
93
|
exports.DEFAULT_I18NEXT_BACKEND_OPTIONS = __webpack_exports__.DEFAULT_I18NEXT_BACKEND_OPTIONS;
|
|
54
94
|
exports.convertBackendOptions = __webpack_exports__.convertBackendOptions;
|
|
55
95
|
for(var __rspack_i in __webpack_exports__)if (-1 === [
|
package/dist/esm/cli/index.mjs
CHANGED
|
@@ -1,38 +1,7 @@
|
|
|
1
|
-
import fs from "fs";
|
|
2
|
-
import path from "path";
|
|
3
1
|
import { getPublicDirRoutePrefixes } from "@modern-js/server-core";
|
|
4
2
|
import { getBackendOptions, getLocaleDetectionOptions } from "../shared/utils.mjs";
|
|
3
|
+
import { applyDetectedBackendPaths, detectLocalesDirectory } from "./locales.mjs";
|
|
5
4
|
import "../runtime/types.mjs";
|
|
6
|
-
function hasJsonFiles(dirPath) {
|
|
7
|
-
try {
|
|
8
|
-
if (!fs.existsSync(dirPath) || !fs.statSync(dirPath).isDirectory()) return false;
|
|
9
|
-
const entries = fs.readdirSync(dirPath);
|
|
10
|
-
for (const entry of entries){
|
|
11
|
-
const entryPath = path.join(dirPath, entry);
|
|
12
|
-
const stat = fs.statSync(entryPath);
|
|
13
|
-
if (stat.isFile() && entry.endsWith('.json')) return true;
|
|
14
|
-
if (stat.isDirectory()) {
|
|
15
|
-
if (hasJsonFiles(entryPath)) return true;
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
return false;
|
|
19
|
-
} catch {
|
|
20
|
-
return false;
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
function detectLocalesDirectory(appDirectory, normalizedConfig) {
|
|
24
|
-
const rootLocalesPath = path.join(appDirectory, 'locales');
|
|
25
|
-
if (hasJsonFiles(rootLocalesPath)) return true;
|
|
26
|
-
const configPublicPath = path.join(appDirectory, 'config', 'public', 'locales');
|
|
27
|
-
if (hasJsonFiles(configPublicPath)) return true;
|
|
28
|
-
const publicDir = normalizedConfig?.server?.publicDir;
|
|
29
|
-
if (publicDir) {
|
|
30
|
-
const publicDirPath = Array.isArray(publicDir) ? publicDir[0] : publicDir;
|
|
31
|
-
const localesPath = path.isAbsolute(publicDirPath) ? path.join(publicDirPath, 'locales') : path.join(appDirectory, publicDirPath, 'locales');
|
|
32
|
-
if (hasJsonFiles(localesPath)) return true;
|
|
33
|
-
}
|
|
34
|
-
return false;
|
|
35
|
-
}
|
|
36
5
|
const i18nPlugin = (options = {})=>({
|
|
37
6
|
name: '@modern-js/plugin-i18n',
|
|
38
7
|
setup: (api)=>{
|
|
@@ -42,26 +11,16 @@ const i18nPlugin = (options = {})=>({
|
|
|
42
11
|
let backendOptions;
|
|
43
12
|
const { appDirectory } = api.getAppContext();
|
|
44
13
|
const normalizedConfig = api.getNormalizedConfig();
|
|
14
|
+
const detectedLocales = detectLocalesDirectory(appDirectory, normalizedConfig);
|
|
45
15
|
if (backend) {
|
|
46
16
|
const entryBackendOptions = getBackendOptions(entrypoint.entryName, backend);
|
|
47
|
-
|
|
48
|
-
else if (entryBackendOptions?.loadPath || entryBackendOptions?.addPath) backendOptions = {
|
|
17
|
+
backendOptions = entryBackendOptions?.enabled === false ? entryBackendOptions : detectedLocales ? applyDetectedBackendPaths(entryBackendOptions, detectedLocales) : entryBackendOptions?.loadPath || entryBackendOptions?.addPath ? {
|
|
49
18
|
...entryBackendOptions,
|
|
50
19
|
enabled: true
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
...entryBackendOptions,
|
|
56
|
-
enabled: true
|
|
57
|
-
} : entryBackendOptions;
|
|
58
|
-
} else backendOptions = entryBackendOptions;
|
|
59
|
-
} else {
|
|
60
|
-
const hasLocales = detectLocalesDirectory(appDirectory, normalizedConfig);
|
|
61
|
-
if (hasLocales) backendOptions = getBackendOptions(entrypoint.entryName, {
|
|
62
|
-
enabled: true
|
|
63
|
-
});
|
|
64
|
-
}
|
|
20
|
+
} : entryBackendOptions;
|
|
21
|
+
} else if (detectedLocales) backendOptions = applyDetectedBackendPaths(getBackendOptions(entrypoint.entryName, {
|
|
22
|
+
enabled: true
|
|
23
|
+
}), detectedLocales);
|
|
65
24
|
const { metaName } = api.getAppContext();
|
|
66
25
|
let extendedConfig = restOptions;
|
|
67
26
|
if (transformRuntimeConfig) extendedConfig = transformRuntimeConfig(restOptions, entrypoint);
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import { getPublicDirRoutePrefixes, normalizePublicDir, normalizePublicDirPath } from "@modern-js/server-core";
|
|
4
|
+
const LOCALES_RESOURCE_PATTERN = '{{lng}}/{{ns}}.json';
|
|
5
|
+
function hasJsonFiles(dirPath) {
|
|
6
|
+
try {
|
|
7
|
+
if (!fs.existsSync(dirPath) || !fs.statSync(dirPath).isDirectory()) return false;
|
|
8
|
+
const entries = fs.readdirSync(dirPath);
|
|
9
|
+
for (const entry of entries){
|
|
10
|
+
const entryPath = path.join(dirPath, entry);
|
|
11
|
+
const stat = fs.statSync(entryPath);
|
|
12
|
+
if (stat.isFile() && entry.endsWith('.json')) return true;
|
|
13
|
+
if (stat.isDirectory() && hasJsonFiles(entryPath)) return true;
|
|
14
|
+
}
|
|
15
|
+
return false;
|
|
16
|
+
} catch {
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
function toPosixPath(filePath) {
|
|
21
|
+
return filePath.split(path.sep).join(path.posix.sep);
|
|
22
|
+
}
|
|
23
|
+
function getPublicDirOutputPath(publicDir) {
|
|
24
|
+
return normalizePublicDirPath(publicDir);
|
|
25
|
+
}
|
|
26
|
+
function buildDetectedLocalesDirectory(clientBasePath, serverBasePath, serverBasePathCandidates = [
|
|
27
|
+
serverBasePath
|
|
28
|
+
]) {
|
|
29
|
+
const normalizedClientBasePath = clientBasePath.startsWith('/') ? clientBasePath : `/${clientBasePath}`;
|
|
30
|
+
const normalizedServerBasePath = toPosixPath(serverBasePath).replace(/\/$/, '');
|
|
31
|
+
const normalizedServerBasePathCandidates = Array.from(new Set(serverBasePathCandidates.map((candidate)=>toPosixPath(candidate).replace(/\/$/, ''))));
|
|
32
|
+
const serverLoadPaths = normalizedServerBasePathCandidates.map((candidate)=>`${candidate}/${LOCALES_RESOURCE_PATTERN}`);
|
|
33
|
+
const serverAddPaths = normalizedServerBasePathCandidates.map((candidate)=>`${candidate}/${LOCALES_RESOURCE_PATTERN}`);
|
|
34
|
+
return {
|
|
35
|
+
loadPath: `${normalizedClientBasePath}/${LOCALES_RESOURCE_PATTERN}`,
|
|
36
|
+
addPath: `${normalizedClientBasePath}/${LOCALES_RESOURCE_PATTERN}`,
|
|
37
|
+
serverLoadPath: `${normalizedServerBasePath}/${LOCALES_RESOURCE_PATTERN}`,
|
|
38
|
+
serverAddPath: `${normalizedServerBasePath}/${LOCALES_RESOURCE_PATTERN}`,
|
|
39
|
+
serverLoadPaths,
|
|
40
|
+
serverAddPaths
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
function detectLocalesDirectory(appDirectory, normalizedConfig) {
|
|
44
|
+
const publicDirs = normalizePublicDir(normalizedConfig?.server?.publicDir);
|
|
45
|
+
const publicDirPrefixes = getPublicDirRoutePrefixes(normalizedConfig?.server?.publicDir);
|
|
46
|
+
for(let index = 0; index < publicDirs.length; index++){
|
|
47
|
+
const publicDir = publicDirs[index];
|
|
48
|
+
if (path.isAbsolute(publicDir)) continue;
|
|
49
|
+
const publicDirPath = path.join(appDirectory, publicDir);
|
|
50
|
+
const publicDirPrefix = publicDirPrefixes[index] || `/${normalizePublicDirPath(publicDir)}`;
|
|
51
|
+
const publicDirOutputPath = getPublicDirOutputPath(publicDir);
|
|
52
|
+
if ('locales' === path.basename(normalizePublicDirPath(publicDir)) && hasJsonFiles(publicDirPath)) return buildDetectedLocalesDirectory(publicDirPrefix, `./${publicDirOutputPath}`);
|
|
53
|
+
const localesPath = path.join(publicDirPath, 'locales');
|
|
54
|
+
if (hasJsonFiles(localesPath)) return buildDetectedLocalesDirectory(`${publicDirPrefix}/locales`, `./${publicDirOutputPath}/locales`);
|
|
55
|
+
}
|
|
56
|
+
const configPublicPath = path.join(appDirectory, 'config', 'public', 'locales');
|
|
57
|
+
if (hasJsonFiles(configPublicPath)) return buildDetectedLocalesDirectory('/locales', './public/locales', [
|
|
58
|
+
'./config/public/locales',
|
|
59
|
+
'./public/locales'
|
|
60
|
+
]);
|
|
61
|
+
const rootLocalesPath = path.join(appDirectory, 'locales');
|
|
62
|
+
if (hasJsonFiles(rootLocalesPath)) return buildDetectedLocalesDirectory('/locales', './locales');
|
|
63
|
+
}
|
|
64
|
+
function applyDetectedBackendPaths(backendOptions, detectedLocales) {
|
|
65
|
+
if (!detectedLocales) return backendOptions;
|
|
66
|
+
const backendWithDetectedPaths = {
|
|
67
|
+
...backendOptions,
|
|
68
|
+
enabled: true,
|
|
69
|
+
loadPath: backendOptions.loadPath ?? detectedLocales.loadPath,
|
|
70
|
+
addPath: backendOptions.addPath ?? detectedLocales.addPath,
|
|
71
|
+
serverLoadPath: backendOptions.serverLoadPath ?? detectedLocales.serverLoadPath,
|
|
72
|
+
serverLoadPaths: backendOptions.serverLoadPath || backendOptions.serverLoadPaths ? backendOptions.serverLoadPaths : detectedLocales.serverLoadPaths,
|
|
73
|
+
serverAddPath: backendOptions.serverAddPath ?? detectedLocales.serverAddPath,
|
|
74
|
+
serverAddPaths: backendOptions.serverAddPath || backendOptions.serverAddPaths ? backendOptions.serverAddPaths : detectedLocales.serverAddPaths,
|
|
75
|
+
_detectedLoadPath: detectedLocales.loadPath,
|
|
76
|
+
_detectedAddPath: detectedLocales.addPath
|
|
77
|
+
};
|
|
78
|
+
return backendWithDetectedPaths;
|
|
79
|
+
}
|
|
80
|
+
export { applyDetectedBackendPaths, detectLocalesDirectory };
|
|
@@ -3,8 +3,6 @@ const DEFAULT_I18NEXT_BACKEND_OPTIONS = {
|
|
|
3
3
|
addPath: '/locales/{{lng}}/{{ns}}.json'
|
|
4
4
|
};
|
|
5
5
|
function convertPath(path) {
|
|
6
|
-
if (!path) return path;
|
|
7
|
-
if (path.startsWith('/')) return `${window.__assetPrefix__ || ''}${path}`;
|
|
8
6
|
return path;
|
|
9
7
|
}
|
|
10
8
|
function convertBackendOptions(options) {
|
|
@@ -12,6 +10,12 @@ function convertBackendOptions(options) {
|
|
|
12
10
|
const converted = {
|
|
13
11
|
...options
|
|
14
12
|
};
|
|
13
|
+
delete converted.serverLoadPath;
|
|
14
|
+
delete converted.serverAddPath;
|
|
15
|
+
delete converted.serverLoadPaths;
|
|
16
|
+
delete converted.serverAddPaths;
|
|
17
|
+
delete converted._detectedLoadPath;
|
|
18
|
+
delete converted._detectedAddPath;
|
|
15
19
|
if (converted.loadPath) converted.loadPath = convertPath(converted.loadPath);
|
|
16
20
|
if (converted.addPath) converted.addPath = convertPath(converted.addPath);
|
|
17
21
|
return converted;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import fs from "fs";
|
|
1
2
|
const DEFAULT_I18NEXT_BACKEND_OPTIONS = {
|
|
2
3
|
loadPath: './locales/{{lng}}/{{ns}}.json',
|
|
3
4
|
addPath: './locales/{{lng}}/{{ns}}.json'
|
|
@@ -7,13 +8,43 @@ function convertPath(path) {
|
|
|
7
8
|
if (path.startsWith('/')) return `.${path}`;
|
|
8
9
|
return path;
|
|
9
10
|
}
|
|
11
|
+
function shouldUseServerPath(currentPath, detectedPath) {
|
|
12
|
+
return !detectedPath || currentPath === detectedPath;
|
|
13
|
+
}
|
|
14
|
+
function getResourceBasePath(resourcePath) {
|
|
15
|
+
const markerIndex = resourcePath.indexOf('{{lng}}');
|
|
16
|
+
if (markerIndex < 0) return resourcePath;
|
|
17
|
+
return resourcePath.slice(0, markerIndex).replace(/[\\/]+$/, '');
|
|
18
|
+
}
|
|
19
|
+
function pathExists(resourcePath) {
|
|
20
|
+
try {
|
|
21
|
+
return fs.existsSync(getResourceBasePath(resourcePath));
|
|
22
|
+
} catch {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
function getServerPath(pathCandidates, fallbackPath) {
|
|
27
|
+
const candidates = Array.from(new Set([
|
|
28
|
+
...pathCandidates || [],
|
|
29
|
+
fallbackPath
|
|
30
|
+
].filter(Boolean)));
|
|
31
|
+
return candidates.find(pathExists) || candidates[0];
|
|
32
|
+
}
|
|
10
33
|
function convertBackendOptions(options) {
|
|
11
34
|
if (!options) return options;
|
|
12
35
|
const converted = {
|
|
13
36
|
...options
|
|
14
37
|
};
|
|
15
|
-
if (converted.loadPath) converted.loadPath =
|
|
16
|
-
if (converted.
|
|
38
|
+
if ((converted.serverLoadPath || converted.serverLoadPaths) && shouldUseServerPath(converted.loadPath, converted._detectedLoadPath)) converted.loadPath = getServerPath(converted.serverLoadPaths, converted.serverLoadPath);
|
|
39
|
+
else if (converted.loadPath) converted.loadPath = convertPath(converted.loadPath);
|
|
40
|
+
if ((converted.serverAddPath || converted.serverAddPaths) && shouldUseServerPath(converted.addPath, converted._detectedAddPath)) converted.addPath = getServerPath(converted.serverAddPaths, converted.serverAddPath);
|
|
41
|
+
else if (converted.addPath) converted.addPath = convertPath(converted.addPath);
|
|
42
|
+
delete converted.serverLoadPath;
|
|
43
|
+
delete converted.serverAddPath;
|
|
44
|
+
delete converted.serverLoadPaths;
|
|
45
|
+
delete converted.serverAddPaths;
|
|
46
|
+
delete converted._detectedLoadPath;
|
|
47
|
+
delete converted._detectedAddPath;
|
|
17
48
|
return converted;
|
|
18
49
|
}
|
|
19
50
|
export { DEFAULT_I18NEXT_BACKEND_OPTIONS, convertBackendOptions };
|
|
@@ -1,39 +1,8 @@
|
|
|
1
1
|
import "node:module";
|
|
2
|
-
import fs from "fs";
|
|
3
|
-
import path from "path";
|
|
4
2
|
import { getPublicDirRoutePrefixes } from "@modern-js/server-core";
|
|
5
3
|
import { getBackendOptions, getLocaleDetectionOptions } from "../shared/utils.mjs";
|
|
4
|
+
import { applyDetectedBackendPaths, detectLocalesDirectory } from "./locales.mjs";
|
|
6
5
|
import "../runtime/types.mjs";
|
|
7
|
-
function hasJsonFiles(dirPath) {
|
|
8
|
-
try {
|
|
9
|
-
if (!fs.existsSync(dirPath) || !fs.statSync(dirPath).isDirectory()) return false;
|
|
10
|
-
const entries = fs.readdirSync(dirPath);
|
|
11
|
-
for (const entry of entries){
|
|
12
|
-
const entryPath = path.join(dirPath, entry);
|
|
13
|
-
const stat = fs.statSync(entryPath);
|
|
14
|
-
if (stat.isFile() && entry.endsWith('.json')) return true;
|
|
15
|
-
if (stat.isDirectory()) {
|
|
16
|
-
if (hasJsonFiles(entryPath)) return true;
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
return false;
|
|
20
|
-
} catch {
|
|
21
|
-
return false;
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
function detectLocalesDirectory(appDirectory, normalizedConfig) {
|
|
25
|
-
const rootLocalesPath = path.join(appDirectory, 'locales');
|
|
26
|
-
if (hasJsonFiles(rootLocalesPath)) return true;
|
|
27
|
-
const configPublicPath = path.join(appDirectory, 'config', 'public', 'locales');
|
|
28
|
-
if (hasJsonFiles(configPublicPath)) return true;
|
|
29
|
-
const publicDir = normalizedConfig?.server?.publicDir;
|
|
30
|
-
if (publicDir) {
|
|
31
|
-
const publicDirPath = Array.isArray(publicDir) ? publicDir[0] : publicDir;
|
|
32
|
-
const localesPath = path.isAbsolute(publicDirPath) ? path.join(publicDirPath, 'locales') : path.join(appDirectory, publicDirPath, 'locales');
|
|
33
|
-
if (hasJsonFiles(localesPath)) return true;
|
|
34
|
-
}
|
|
35
|
-
return false;
|
|
36
|
-
}
|
|
37
6
|
const i18nPlugin = (options = {})=>({
|
|
38
7
|
name: '@modern-js/plugin-i18n',
|
|
39
8
|
setup: (api)=>{
|
|
@@ -43,26 +12,16 @@ const i18nPlugin = (options = {})=>({
|
|
|
43
12
|
let backendOptions;
|
|
44
13
|
const { appDirectory } = api.getAppContext();
|
|
45
14
|
const normalizedConfig = api.getNormalizedConfig();
|
|
15
|
+
const detectedLocales = detectLocalesDirectory(appDirectory, normalizedConfig);
|
|
46
16
|
if (backend) {
|
|
47
17
|
const entryBackendOptions = getBackendOptions(entrypoint.entryName, backend);
|
|
48
|
-
|
|
49
|
-
else if (entryBackendOptions?.loadPath || entryBackendOptions?.addPath) backendOptions = {
|
|
18
|
+
backendOptions = entryBackendOptions?.enabled === false ? entryBackendOptions : detectedLocales ? applyDetectedBackendPaths(entryBackendOptions, detectedLocales) : entryBackendOptions?.loadPath || entryBackendOptions?.addPath ? {
|
|
50
19
|
...entryBackendOptions,
|
|
51
20
|
enabled: true
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
...entryBackendOptions,
|
|
57
|
-
enabled: true
|
|
58
|
-
} : entryBackendOptions;
|
|
59
|
-
} else backendOptions = entryBackendOptions;
|
|
60
|
-
} else {
|
|
61
|
-
const hasLocales = detectLocalesDirectory(appDirectory, normalizedConfig);
|
|
62
|
-
if (hasLocales) backendOptions = getBackendOptions(entrypoint.entryName, {
|
|
63
|
-
enabled: true
|
|
64
|
-
});
|
|
65
|
-
}
|
|
21
|
+
} : entryBackendOptions;
|
|
22
|
+
} else if (detectedLocales) backendOptions = applyDetectedBackendPaths(getBackendOptions(entrypoint.entryName, {
|
|
23
|
+
enabled: true
|
|
24
|
+
}), detectedLocales);
|
|
66
25
|
const { metaName } = api.getAppContext();
|
|
67
26
|
let extendedConfig = restOptions;
|
|
68
27
|
if (transformRuntimeConfig) extendedConfig = transformRuntimeConfig(restOptions, entrypoint);
|