@orderly.network/i18n 2.10.2 → 3.0.0-beta.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/README.md +193 -34
- package/bin/cli.js +92 -37
- package/dist/{constant-UZhfXyyb.d.mts → constant-BeXwHrGj.d.mts} +27 -0
- package/dist/{constant-UZhfXyyb.d.ts → constant-BeXwHrGj.d.ts} +27 -0
- package/dist/constant.d.mts +1 -1
- package/dist/constant.d.ts +1 -1
- package/dist/index.d.mts +34 -9
- package/dist/index.d.ts +34 -9
- package/dist/index.js +80 -17
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +79 -19
- package/dist/index.mjs.map +1 -1
- package/dist/locale.csv +30 -3
- package/dist/locales/de.json +30 -3
- package/dist/locales/en.json +30 -3
- package/dist/locales/es.json +30 -3
- package/dist/locales/fr.json +30 -3
- package/dist/locales/id.json +30 -3
- package/dist/locales/it.json +30 -3
- package/dist/locales/ja.json +30 -3
- package/dist/locales/ko.json +30 -3
- package/dist/locales/nl.json +30 -3
- package/dist/locales/pl.json +30 -3
- package/dist/locales/pt.json +30 -3
- package/dist/locales/ru.json +30 -3
- package/dist/locales/tc.json +30 -3
- package/dist/locales/tr.json +30 -3
- package/dist/locales/uk.json +30 -3
- package/dist/locales/vi.json +30 -3
- package/dist/locales/zh.json +30 -3
- package/dist/utils.d.mts +1 -1
- package/dist/utils.d.ts +1 -1
- package/dist/utils.js +46 -12
- package/dist/utils.js.map +1 -1
- package/dist/utils.mjs +46 -12
- package/dist/utils.mjs.map +1 -1
- package/package.json +7 -7
- package/script/copyLocales.js +0 -11
- package/script/csv2json.js +0 -28
- package/script/diffCsv.js +0 -175
- package/script/fillJson.js +0 -33
- package/script/generateCsv.js +0 -36
- package/script/generateEnJson.js +0 -11
- package/script/generateMissingKeys.js +0 -49
- package/script/json-csv-converter.js +0 -286
- package/script/json2csv.js +0 -38
- package/script/mergeJson.js +0 -67
- package/script/separateJson.js +0 -50
- package/script/utils.js +0 -88
package/script/json2csv.js
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
const fs = require("fs-extra");
|
|
2
|
-
const path = require("path");
|
|
3
|
-
const { multiJson2Csv } = require("./json-csv-converter");
|
|
4
|
-
const { checkFileExists, findJsonFiles } = require("./utils");
|
|
5
|
-
const { LocaleEnum } = require("../dist");
|
|
6
|
-
|
|
7
|
-
/** Convert multiple locale JSON files to a locale CSV file */
|
|
8
|
-
async function json2csv(inputDir, outputPath) {
|
|
9
|
-
const inputFiles = await findJsonFiles(inputDir);
|
|
10
|
-
|
|
11
|
-
// Sort input files by locale
|
|
12
|
-
inputFiles.sort((a, b) => (b.startsWith(LocaleEnum.en) ? 1 : -1));
|
|
13
|
-
|
|
14
|
-
const jsonList = [];
|
|
15
|
-
const headers = [""];
|
|
16
|
-
for (const filePath of inputFiles) {
|
|
17
|
-
const json = await fs.readJSON(path.resolve(inputDir, filePath), {
|
|
18
|
-
encoding: "utf8",
|
|
19
|
-
});
|
|
20
|
-
jsonList.push(json);
|
|
21
|
-
const fileName = path.basename(filePath, path.extname(filePath));
|
|
22
|
-
headers.push(fileName);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
const csv = multiJson2Csv(jsonList, headers);
|
|
26
|
-
|
|
27
|
-
const csvPath = path.resolve(outputPath);
|
|
28
|
-
|
|
29
|
-
await checkFileExists(csvPath);
|
|
30
|
-
|
|
31
|
-
await fs.outputFile(csvPath, csv, { encoding: "utf8" });
|
|
32
|
-
|
|
33
|
-
console.log("json2csv success =>", csvPath);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
module.exports = {
|
|
37
|
-
json2csv,
|
|
38
|
-
};
|
package/script/mergeJson.js
DELETED
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
const fs = require("fs-extra");
|
|
2
|
-
const path = require("path");
|
|
3
|
-
const { checkFileExists, findJsonFiles } = require("./utils");
|
|
4
|
-
const { LocaleEnum } = require("../dist");
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Merge default and extend JSON files back into one file
|
|
8
|
-
* @param {string} inputDir - The input directory containing both default and extend JSON files
|
|
9
|
-
* @param {string} outputDir - The output directory for merged JSON files
|
|
10
|
-
*/
|
|
11
|
-
async function mergeJson(inputDir, outputDir) {
|
|
12
|
-
const jsonFiles = await findJsonFiles(inputDir);
|
|
13
|
-
|
|
14
|
-
// Sort input files by locale
|
|
15
|
-
jsonFiles.sort((a, b) => (b.startsWith(LocaleEnum.en) ? 1 : -1));
|
|
16
|
-
let baseJson = {};
|
|
17
|
-
|
|
18
|
-
const extendDir = path.resolve(inputDir, "extend");
|
|
19
|
-
|
|
20
|
-
for (const [index, file] of jsonFiles.entries()) {
|
|
21
|
-
const defaultJsonPath = path.resolve(inputDir, file);
|
|
22
|
-
const extendJsonPath = path.resolve(extendDir, file);
|
|
23
|
-
|
|
24
|
-
// Read default JSON file
|
|
25
|
-
const defaultJson = await fs.readJSON(defaultJsonPath, {
|
|
26
|
-
encoding: "utf8",
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
// Read extend JSON file if it exists
|
|
30
|
-
let extendJson = {};
|
|
31
|
-
if (await fs.pathExists(extendJsonPath)) {
|
|
32
|
-
extendJson = await fs.readJSON(extendJsonPath, {
|
|
33
|
-
encoding: "utf8",
|
|
34
|
-
});
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
// Merge the JSON objects
|
|
38
|
-
const mergedJson = { ...defaultJson, ...extendJson };
|
|
39
|
-
|
|
40
|
-
let sortedJson = {};
|
|
41
|
-
|
|
42
|
-
// base json
|
|
43
|
-
if (index === 0) {
|
|
44
|
-
baseJson = mergedJson;
|
|
45
|
-
sortedJson = mergedJson;
|
|
46
|
-
} else {
|
|
47
|
-
for (const key of Object.keys(baseJson)) {
|
|
48
|
-
sortedJson[key] = mergedJson[key];
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
const outputPath = path.resolve(outputDir, file);
|
|
53
|
-
|
|
54
|
-
await fs.outputFile(outputPath, JSON.stringify(sortedJson, null, 2), {
|
|
55
|
-
encoding: "utf8",
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
console.log("mergeJson success =>", outputPath);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
await fs.remove(extendDir);
|
|
62
|
-
console.log("remove extendDir =>", extendDir);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
module.exports = {
|
|
66
|
-
mergeJson,
|
|
67
|
-
};
|
package/script/separateJson.js
DELETED
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
const fs = require("fs-extra");
|
|
2
|
-
const path = require("path");
|
|
3
|
-
const { checkFileExists, findJsonFiles } = require("./utils");
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Separate json file default and extend key values based on the key
|
|
7
|
-
* @param {string} inputDir - The input directory for locale JSON files
|
|
8
|
-
* @param {string} outputDir - The output directory for locale JSON files
|
|
9
|
-
* @param {string} separateKey - The key to separate the json files
|
|
10
|
-
*/
|
|
11
|
-
async function separateJson(inputDir, outputDir, separateKey) {
|
|
12
|
-
const jsonFiles = await findJsonFiles(inputDir);
|
|
13
|
-
|
|
14
|
-
const separateKeys = separateKey.split(",");
|
|
15
|
-
for (const file of jsonFiles) {
|
|
16
|
-
const json = await fs.readJSON(path.resolve(inputDir, file), {
|
|
17
|
-
encoding: "utf8",
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
const defaultJson = {};
|
|
21
|
-
const extendJson = {};
|
|
22
|
-
Object.keys(json).forEach((key) => {
|
|
23
|
-
if (separateKeys.some((k) => key.startsWith(k))) {
|
|
24
|
-
extendJson[key] = json[key];
|
|
25
|
-
} else {
|
|
26
|
-
defaultJson[key] = json[key];
|
|
27
|
-
}
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
const jsonPath = path.resolve(outputDir, file);
|
|
31
|
-
await checkFileExists(jsonPath);
|
|
32
|
-
|
|
33
|
-
await fs.outputFile(jsonPath, JSON.stringify(defaultJson, null, 2), {
|
|
34
|
-
encoding: "utf8",
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
const extendPath = path.resolve(outputDir, "extend", file);
|
|
38
|
-
await checkFileExists(extendPath);
|
|
39
|
-
|
|
40
|
-
await fs.outputFile(extendPath, JSON.stringify(extendJson, null, 2), {
|
|
41
|
-
encoding: "utf8",
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
console.log("separateJson success =>", jsonPath, extendPath);
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
module.exports = {
|
|
49
|
-
separateJson,
|
|
50
|
-
};
|
package/script/utils.js
DELETED
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
const fs = require("fs-extra");
|
|
2
|
-
|
|
3
|
-
async function checkFileExists(filePath) {
|
|
4
|
-
if (await fs.exists(filePath)) {
|
|
5
|
-
throw new Error(`${filePath} already exists, please modify file path`);
|
|
6
|
-
}
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
const i18nValidErrors = {
|
|
10
|
-
string: "Value must be a string",
|
|
11
|
-
empty: "Value cannot be empty",
|
|
12
|
-
interpolation: "Invalid interpolation",
|
|
13
|
-
mismatchedClosingTag: (tagName) => `Mismatched closing tag: </${tagName}>`,
|
|
14
|
-
unclosedTag: (tagName) => `Unclosed tag: <${tagName}>`,
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Validate the value of i18n
|
|
19
|
-
* @param {string} value - The value to validate
|
|
20
|
-
* @returns {Object} - The validation result
|
|
21
|
-
*/
|
|
22
|
-
function validateI18nValue(value) {
|
|
23
|
-
if (typeof value !== "string") {
|
|
24
|
-
return { valid: false, error: i18nValidErrors.string };
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
// 1. check if value is empty
|
|
28
|
-
if (value.trim() === "") {
|
|
29
|
-
return { valid: false, error: i18nValidErrors.empty };
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
// 2. check if placeholder format is correct (allow `{{variable}}`)
|
|
33
|
-
// allow `{{variable}}` or `{{ variable }}`
|
|
34
|
-
const interpolationRegex = /{{\s*[\w.-]+\s*}}/g;
|
|
35
|
-
// check if `{{` is not closed or `}}` is not opened
|
|
36
|
-
const invalidInterpolationRegex =
|
|
37
|
-
/{{[^{}]*$|^[^{}]*}}|[^{]{{|}}[^}]}|^{|}$|{[^{}]*}|}/;
|
|
38
|
-
|
|
39
|
-
if (
|
|
40
|
-
value.match(invalidInterpolationRegex) &&
|
|
41
|
-
!value.match(interpolationRegex)
|
|
42
|
-
) {
|
|
43
|
-
return { valid: false, error: i18nValidErrors.interpolation };
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
// 3. check if HTML tags are correctly closed
|
|
47
|
-
const tagRegex = /<\/?([a-zA-Z0-9]+)(\s*\/?)>/g;
|
|
48
|
-
let stack = [];
|
|
49
|
-
let match;
|
|
50
|
-
|
|
51
|
-
while ((match = tagRegex.exec(value)) !== null) {
|
|
52
|
-
let [, tagName, selfClosing] = match;
|
|
53
|
-
|
|
54
|
-
if (selfClosing === "/") {
|
|
55
|
-
// self-closing tag, no need to push to stack
|
|
56
|
-
continue;
|
|
57
|
-
} else if (match[0].startsWith("</")) {
|
|
58
|
-
// closing tag, check if stack top matches
|
|
59
|
-
if (stack.length === 0 || stack.pop() !== tagName) {
|
|
60
|
-
return {
|
|
61
|
-
valid: false,
|
|
62
|
-
error: i18nValidErrors.mismatchedClosingTag(tagName),
|
|
63
|
-
};
|
|
64
|
-
}
|
|
65
|
-
} else {
|
|
66
|
-
// opening tag, push to stack
|
|
67
|
-
stack.push(tagName);
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
if (stack.length > 0) {
|
|
72
|
-
return { valid: false, error: i18nValidErrors.unclosedTag(stack.pop()) };
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
return { valid: true, error: null };
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
async function findJsonFiles(dir) {
|
|
79
|
-
const files = await fs.readdir(dir);
|
|
80
|
-
return files.filter((file) => file.endsWith(".json"));
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
module.exports = {
|
|
84
|
-
checkFileExists,
|
|
85
|
-
validateI18nValue,
|
|
86
|
-
i18nValidErrors,
|
|
87
|
-
findJsonFiles,
|
|
88
|
-
};
|