i18n-a11y 1.0.0 → 1.0.1
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/.github/checkFlow.yml +0 -0
- package/dist/i18n.config.js +3 -3
- package/dist/src/ai.js +0 -3
- package/dist/src/cli.js +19 -8
- package/dist/src/utils/index.js +19 -0
- package/i18n.config.ts +3 -3
- package/package.json +54 -54
- package/src/ai.ts +0 -3
- package/src/cli.ts +30 -8
- package/src/utils/index.ts +25 -0
|
File without changes
|
package/dist/i18n.config.js
CHANGED
package/dist/src/ai.js
CHANGED
package/dist/src/cli.js
CHANGED
|
@@ -2,18 +2,26 @@
|
|
|
2
2
|
import { Command } from "commander";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import fs from "node:fs/promises";
|
|
5
|
+
import { logger, print, pickKeys, loadEnv } from "./utils/index.js";
|
|
6
|
+
loadEnv();
|
|
5
7
|
import { scanFiles } from "./scanFiles.js";
|
|
6
8
|
import { extractKeys } from "./extractKeys.js";
|
|
7
9
|
import translate from "./ai.js";
|
|
8
|
-
import { logger, print, pickKeys } from "./utils/index.js";
|
|
9
10
|
const program = new Command();
|
|
10
|
-
program
|
|
11
|
+
program
|
|
12
|
+
.name("auto-i18n")
|
|
13
|
+
.description("I18n a11y CLI")
|
|
14
|
+
.version("1.0.0");
|
|
11
15
|
const onAction = async () => {
|
|
12
16
|
try {
|
|
13
17
|
await print("AUTO I18N");
|
|
14
18
|
const configPath = path.resolve(process.cwd(), "i18n.config.ts");
|
|
15
19
|
const { genI18nConfig } = await import("./utils/genI18nConfig.js");
|
|
16
|
-
|
|
20
|
+
const exists = await fs
|
|
21
|
+
.access(configPath)
|
|
22
|
+
.then(() => true)
|
|
23
|
+
.catch(() => false);
|
|
24
|
+
if (!exists) {
|
|
17
25
|
await genI18nConfig();
|
|
18
26
|
}
|
|
19
27
|
const files = await scanFiles();
|
|
@@ -27,12 +35,12 @@ const onAction = async () => {
|
|
|
27
35
|
const keys = await extractKeys(file);
|
|
28
36
|
const allKeys = pickKeys(keys);
|
|
29
37
|
for (const key of allKeys) {
|
|
30
|
-
if (!keyFileMap.has(key))
|
|
38
|
+
if (!keyFileMap.has(key)) {
|
|
31
39
|
keyFileMap.set(key, new Set());
|
|
32
|
-
|
|
40
|
+
}
|
|
41
|
+
keyFileMap.get(key).add(file);
|
|
33
42
|
for (const lang of config.languages) {
|
|
34
|
-
|
|
35
|
-
translateResult[key] = {};
|
|
43
|
+
translateResult[key] ?? (translateResult[key] = {});
|
|
36
44
|
const result = await translate(key, lang);
|
|
37
45
|
translateResult[key][lang] = result;
|
|
38
46
|
logger.info(`Translated "${key}" to ${lang}: ${result}`);
|
|
@@ -51,5 +59,8 @@ const onAction = async () => {
|
|
|
51
59
|
process.exit(1);
|
|
52
60
|
}
|
|
53
61
|
};
|
|
54
|
-
program
|
|
62
|
+
program
|
|
63
|
+
.command("scan")
|
|
64
|
+
.description("scan project and generate i18n files")
|
|
65
|
+
.action(onAction);
|
|
55
66
|
program.parse(process.argv);
|
package/dist/src/utils/index.js
CHANGED
|
@@ -22,3 +22,22 @@ export const pickKeys = (keys) => {
|
|
|
22
22
|
});
|
|
23
23
|
return Array.from(result);
|
|
24
24
|
};
|
|
25
|
+
import fs from "fs";
|
|
26
|
+
import path from "path";
|
|
27
|
+
import dotenv from "dotenv";
|
|
28
|
+
export function loadEnv() {
|
|
29
|
+
const cwd = process.cwd();
|
|
30
|
+
const candidates = [
|
|
31
|
+
path.resolve(cwd, "env/.env.local"),
|
|
32
|
+
path.resolve(cwd, "env/.env"),
|
|
33
|
+
path.resolve(cwd, ".env.local"),
|
|
34
|
+
path.resolve(cwd, ".env"),
|
|
35
|
+
];
|
|
36
|
+
for (const filePath of candidates) {
|
|
37
|
+
if (fs.existsSync(filePath)) {
|
|
38
|
+
dotenv.config({ path: filePath });
|
|
39
|
+
return filePath;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return null;
|
|
43
|
+
}
|
package/i18n.config.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,54 +1,54 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "i18n-a11y",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"description": "CLI tool for generating i18n files",
|
|
5
|
-
"main": "dist/index.js",
|
|
6
|
-
"bin": {
|
|
7
|
-
"auto-i18n": "dist/src/cli.js"
|
|
8
|
-
},
|
|
9
|
-
"type": "module",
|
|
10
|
-
"scripts": {
|
|
11
|
-
"build": "tsc",
|
|
12
|
-
"i18n:build": "node dist/src/cli.js scan",
|
|
13
|
-
"i18n:local": "node src/cli.js scan",
|
|
14
|
-
"prepublishOnly": "npm run build"
|
|
15
|
-
},
|
|
16
|
-
"keywords": [
|
|
17
|
-
"i18n",
|
|
18
|
-
"cli",
|
|
19
|
-
"typescript"
|
|
20
|
-
],
|
|
21
|
-
"repository": {
|
|
22
|
-
"type": "git",
|
|
23
|
-
"url": "https://github.com/flylea/auto-i18n.git"
|
|
24
|
-
},
|
|
25
|
-
"author": "hi@flylea.com",
|
|
26
|
-
"license": "MIT",
|
|
27
|
-
"bugs": {
|
|
28
|
-
"url": "https://github.com/flylea/auto-i18n/issues"
|
|
29
|
-
},
|
|
30
|
-
"homepage": "https://github.com/flylea/auto-i18n#readme",
|
|
31
|
-
"devDependencies": {
|
|
32
|
-
"@types/babel__traverse": "^7.28.0",
|
|
33
|
-
"@types/node": "^24.10.2",
|
|
34
|
-
"dotenv": "^17.2.3",
|
|
35
|
-
"typescript": "^5.9.3"
|
|
36
|
-
},
|
|
37
|
-
"dependencies": {
|
|
38
|
-
"@babel/parser": "^7.28.5",
|
|
39
|
-
"@babel/traverse": "^7.28.5",
|
|
40
|
-
"@babel/types": "^7.28.5",
|
|
41
|
-
"@types/cli-progress": "^3.11.6",
|
|
42
|
-
"@vue/compiler-dom": "^3.5.25",
|
|
43
|
-
"@vue/compiler-sfc": "^3.3.4",
|
|
44
|
-
"chalk": "^4.1.2",
|
|
45
|
-
"cli-progress": "^3.12.0",
|
|
46
|
-
"colors": "^1.4.0",
|
|
47
|
-
"commander": "^14.0.2",
|
|
48
|
-
"fast-glob": "^3.3.3",
|
|
49
|
-
"figlet": "^1.9.4",
|
|
50
|
-
"inquirer": "^13.1.0",
|
|
51
|
-
"openai": "^4.26.0",
|
|
52
|
-
"p-limit": "^5.0.0"
|
|
53
|
-
}
|
|
54
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "i18n-a11y",
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"description": "CLI tool for generating i18n files",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"auto-i18n": "dist/src/cli.js"
|
|
8
|
+
},
|
|
9
|
+
"type": "module",
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "tsc",
|
|
12
|
+
"i18n:build": "node dist/src/cli.js scan",
|
|
13
|
+
"i18n:local": "node src/cli.js scan",
|
|
14
|
+
"prepublishOnly": "npm run build"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [
|
|
17
|
+
"i18n",
|
|
18
|
+
"cli",
|
|
19
|
+
"typescript"
|
|
20
|
+
],
|
|
21
|
+
"repository": {
|
|
22
|
+
"type": "git",
|
|
23
|
+
"url": "https://github.com/flylea/auto-i18n.git"
|
|
24
|
+
},
|
|
25
|
+
"author": "hi@flylea.com",
|
|
26
|
+
"license": "MIT",
|
|
27
|
+
"bugs": {
|
|
28
|
+
"url": "https://github.com/flylea/auto-i18n/issues"
|
|
29
|
+
},
|
|
30
|
+
"homepage": "https://github.com/flylea/auto-i18n#readme",
|
|
31
|
+
"devDependencies": {
|
|
32
|
+
"@types/babel__traverse": "^7.28.0",
|
|
33
|
+
"@types/node": "^24.10.2",
|
|
34
|
+
"dotenv": "^17.2.3",
|
|
35
|
+
"typescript": "^5.9.3"
|
|
36
|
+
},
|
|
37
|
+
"dependencies": {
|
|
38
|
+
"@babel/parser": "^7.28.5",
|
|
39
|
+
"@babel/traverse": "^7.28.5",
|
|
40
|
+
"@babel/types": "^7.28.5",
|
|
41
|
+
"@types/cli-progress": "^3.11.6",
|
|
42
|
+
"@vue/compiler-dom": "^3.5.25",
|
|
43
|
+
"@vue/compiler-sfc": "^3.3.4",
|
|
44
|
+
"chalk": "^4.1.2",
|
|
45
|
+
"cli-progress": "^3.12.0",
|
|
46
|
+
"colors": "^1.4.0",
|
|
47
|
+
"commander": "^14.0.2",
|
|
48
|
+
"fast-glob": "^3.3.3",
|
|
49
|
+
"figlet": "^1.9.4",
|
|
50
|
+
"inquirer": "^13.1.0",
|
|
51
|
+
"openai": "^4.26.0",
|
|
52
|
+
"p-limit": "^5.0.0"
|
|
53
|
+
}
|
|
54
|
+
}
|
package/src/ai.ts
CHANGED
package/src/cli.ts
CHANGED
|
@@ -2,13 +2,20 @@
|
|
|
2
2
|
import { Command } from "commander";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import fs from "node:fs/promises";
|
|
5
|
+
|
|
6
|
+
import { logger, print, pickKeys,loadEnv } from "./utils/index.js";
|
|
7
|
+
loadEnv();
|
|
8
|
+
|
|
5
9
|
import { scanFiles } from "./scanFiles.js";
|
|
6
10
|
import { extractKeys } from "./extractKeys.js";
|
|
7
11
|
import translate from "./ai.js";
|
|
8
|
-
import { logger, print, pickKeys } from "./utils/index.js";
|
|
9
12
|
|
|
10
13
|
const program = new Command();
|
|
11
|
-
|
|
14
|
+
|
|
15
|
+
program
|
|
16
|
+
.name("auto-i18n")
|
|
17
|
+
.description("I18n a11y CLI")
|
|
18
|
+
.version("1.0.0");
|
|
12
19
|
|
|
13
20
|
const onAction = async () => {
|
|
14
21
|
try {
|
|
@@ -17,7 +24,12 @@ const onAction = async () => {
|
|
|
17
24
|
const configPath = path.resolve(process.cwd(), "i18n.config.ts");
|
|
18
25
|
const { genI18nConfig } = await import("./utils/genI18nConfig.js");
|
|
19
26
|
|
|
20
|
-
|
|
27
|
+
const exists = await fs
|
|
28
|
+
.access(configPath)
|
|
29
|
+
.then(() => true)
|
|
30
|
+
.catch(() => false);
|
|
31
|
+
|
|
32
|
+
if (!exists) {
|
|
21
33
|
await genI18nConfig();
|
|
22
34
|
}
|
|
23
35
|
|
|
@@ -25,6 +37,7 @@ const onAction = async () => {
|
|
|
25
37
|
if (!files.length) return;
|
|
26
38
|
|
|
27
39
|
const { default: config } = await import("../i18n.config.js");
|
|
40
|
+
|
|
28
41
|
const translateResult: Record<string, Record<string, string>> = {};
|
|
29
42
|
const keyFileMap = new Map<string, Set<string>>();
|
|
30
43
|
|
|
@@ -34,18 +47,23 @@ const onAction = async () => {
|
|
|
34
47
|
const allKeys = pickKeys(keys);
|
|
35
48
|
|
|
36
49
|
for (const key of allKeys) {
|
|
37
|
-
if (!keyFileMap.has(key))
|
|
38
|
-
|
|
50
|
+
if (!keyFileMap.has(key)) {
|
|
51
|
+
keyFileMap.set(key, new Set());
|
|
52
|
+
}
|
|
53
|
+
keyFileMap.get(key)!.add(file);
|
|
39
54
|
|
|
40
55
|
for (const lang of config.languages) {
|
|
41
|
-
|
|
56
|
+
translateResult[key] ??= {};
|
|
42
57
|
const result = await translate(key, lang);
|
|
43
58
|
translateResult[key][lang] = result;
|
|
59
|
+
|
|
44
60
|
logger.info(`Translated "${key}" to ${lang}: ${result}`);
|
|
45
61
|
}
|
|
46
62
|
}
|
|
47
63
|
} catch (err) {
|
|
48
|
-
logger.error(
|
|
64
|
+
logger.error(
|
|
65
|
+
`Extract keys from ${file} failed: ${(err as Error).message}`
|
|
66
|
+
);
|
|
49
67
|
}
|
|
50
68
|
}
|
|
51
69
|
|
|
@@ -57,5 +75,9 @@ const onAction = async () => {
|
|
|
57
75
|
}
|
|
58
76
|
};
|
|
59
77
|
|
|
60
|
-
program
|
|
78
|
+
program
|
|
79
|
+
.command("scan")
|
|
80
|
+
.description("scan project and generate i18n files")
|
|
81
|
+
.action(onAction);
|
|
82
|
+
|
|
61
83
|
program.parse(process.argv);
|
package/src/utils/index.ts
CHANGED
|
@@ -33,3 +33,28 @@ export const pickKeys = (keys: string[] | string) => {
|
|
|
33
33
|
return Array.from(result);
|
|
34
34
|
};
|
|
35
35
|
|
|
36
|
+
import fs from "fs";
|
|
37
|
+
import path from "path";
|
|
38
|
+
import dotenv from "dotenv";
|
|
39
|
+
|
|
40
|
+
export function loadEnv() {
|
|
41
|
+
const cwd = process.cwd();
|
|
42
|
+
|
|
43
|
+
const candidates = [
|
|
44
|
+
path.resolve(cwd, "env/.env.local"),
|
|
45
|
+
path.resolve(cwd, "env/.env"),
|
|
46
|
+
path.resolve(cwd, ".env.local"),
|
|
47
|
+
path.resolve(cwd, ".env"),
|
|
48
|
+
];
|
|
49
|
+
|
|
50
|
+
for (const filePath of candidates) {
|
|
51
|
+
if (fs.existsSync(filePath)) {
|
|
52
|
+
dotenv.config({ path: filePath });
|
|
53
|
+
return filePath;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
|