Skip to content
This repository was archived by the owner on Apr 21, 2025. It is now read-only.

Commit 9b498c6

Browse files
committed
finalize logic
1 parent 0445234 commit 9b498c6

File tree

3 files changed

+79
-104
lines changed

3 files changed

+79
-104
lines changed

.eslintrc.cjs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@ module.exports = {
2222
}
2323
},
2424
{
25-
files: ['src/i18n/**/translations.ts'], // Specify the path pattern for the files you want to apply the rule to
25+
files: ['src/i18n/**/translations.ts'],
2626
rules: {
27-
"internal-rules/check-i18n-keys": "off"
27+
"internal-rules/check-i18n-keys": "warn"
2828
}
2929
},
3030
],

tools/internal-rules/lib/rules/check-i18n-keys.js

Lines changed: 41 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -18,97 +18,76 @@ module.exports = {
1818
schema: []
1919
},
2020
create: function (context) {
21-
function extractKeysFromObjectExpression(node) {
21+
function extractKeysFromObjectExpression(node, parentKey = "") {
2222
const keys = [];
2323

24-
function traverseProperties(properties) {
25-
if (!properties) return; // Handle undefined or null properties
26-
27-
for (const property of properties) {
24+
function traverseObjectProperties(properties, parentKey) {
25+
properties.forEach((property) => {
2826
if (
29-
property.type === "Property" &&
30-
property.value.type === "ObjectExpression"
31-
) {
32-
traverseProperties(property.value.properties);
33-
} else if (
34-
property.type === "Property" &&
35-
property.value.type === "ArrayExpression"
36-
) {
37-
traverseArrayElements(property.value.elements);
38-
} else if (
3927
property.type === "Property" &&
4028
property.key.type === "Identifier"
4129
) {
42-
keys.push(property.key.name);
43-
}
44-
}
45-
}
46-
47-
function traverseArrayElements(elements) {
48-
if (!elements) return; // Handle undefined or null elements
49-
50-
for (const element of elements) {
51-
if (element.type === "ObjectExpression") {
52-
traverseProperties(element.properties);
30+
const currentKey = parentKey
31+
? `${parentKey}.${property.key.name}`
32+
: property.key.name;
33+
keys.push(currentKey);
34+
if (property.value.type === "ObjectExpression") {
35+
traverseObjectProperties(
36+
property.value.properties,
37+
currentKey
38+
);
39+
}
5340
}
54-
}
41+
});
5542
}
5643

57-
traverseProperties(node.properties);
44+
traverseObjectProperties(node.properties, parentKey);
5845

5946
return keys;
6047
}
6148

62-
function extractKeysFromFile(filePath) {
49+
function extractKeysFromFile(filePath, parentKey = "") {
6350
const fileContent = fs.readFileSync(filePath, "utf8");
6451
const ast = parse(fileContent, {
65-
sourceType: "module", // or 'script' depending on your file
52+
sourceType: "module",
6653
plugins: ["typescript", "jsx"]
6754
});
6855
const keys = [];
6956

7057
const properties = ast.program.body[0].declaration.properties;
7158

72-
function traverseProperties(properties) {
73-
for (const property of properties) {
59+
function traverseFileProperties(properties, parentKey) {
60+
properties.forEach((property) => {
7461
if (
75-
property.type === "ObjectProperty" &&
76-
property.value.type === "ObjectExpression"
77-
) {
78-
traverseProperties(property.value.properties);
79-
} else if (
80-
property.type === "ObjectProperty" &&
81-
property.value.type === "ArrayExpression"
82-
) {
83-
traverseArrayElements(property.value.elements);
84-
} else if (
8562
property.type === "ObjectProperty" &&
8663
property.key.type === "Identifier"
8764
) {
88-
keys.push(property.key.name);
89-
}
90-
}
91-
}
92-
93-
function traverseArrayElements(elements) {
94-
if (!elements) return; // Handle undefined or null elements
95-
96-
for (const element of elements) {
97-
if (element.type === "ObjectExpression") {
98-
traverseProperties(element.properties);
65+
const currentKey = parentKey
66+
? `${parentKey}.${property.key.name}`
67+
: property.key.name;
68+
keys.push(currentKey);
69+
if (property.value.type === "ObjectExpression") {
70+
traverseFileProperties(
71+
property.value.properties,
72+
currentKey
73+
);
74+
}
9975
}
100-
}
76+
});
10177
}
10278

103-
traverseProperties(properties);
79+
traverseFileProperties(properties, parentKey);
10480

10581
return keys;
10682
}
10783

10884
return {
10985
Program(node) {
11086
for (const statement of node.body) {
111-
const relativePath = path.relative(process.cwd(), context.getFilename())
87+
const relativePath = path.relative(
88+
process.cwd(),
89+
context.getFilename()
90+
);
11291
const fallbackFilePath = path
11392
.relative(process.cwd(), context.getFilename())
11493
.replace(
@@ -121,27 +100,23 @@ module.exports = {
121100
);
122101

123102
const enKeys = extractKeysFromFile(fallbackFilePath);
124-
// Report missing keys and incorrect order
125-
enKeys.forEach((enKey, index) => {
103+
104+
// Report missing keys
105+
enKeys.forEach((enKey) => {
126106
if (!keys.includes(enKey)) {
127107
context.report({
128108
node: node,
129-
message: `missing key '${enKey}'`
130-
});
131-
} else if (keys.indexOf(enKey) !== index) {
132-
context.report({
133-
node: node,
134-
message: `incorrect key location '${enKey}'`
109+
message: `missing key '${enKey}' ${relativePath}`
135110
});
136111
}
137112
});
138113

139114
// Report extra keys
140-
keys.forEach(key => {
115+
keys.forEach((key) => {
141116
if (!enKeys.includes(key)) {
142117
context.report({
143118
node: node,
144-
message: `extra key '${key}'`
119+
message: `extra key '${key}' ${relativePath}`
145120
});
146121
}
147122
});

tools/internal-rules/package.json

Lines changed: 36 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,38 @@
11
{
2-
"name": "eslint-plugin-internal-rules",
3-
"version": "0.0.0",
4-
"description": "internal eslint rules",
5-
"keywords": [
6-
"eslint",
7-
"eslintplugin",
8-
"eslint-plugin"
9-
],
10-
"author": "",
11-
"main": "./lib/index.js",
12-
"exports": "./lib/index.js",
13-
"scripts": {
14-
"lint": "npm-run-all \"lint:*\"",
15-
"lint:eslint-docs": "npm-run-all \"update:eslint-docs -- --check\"",
16-
"lint:js": "eslint .",
17-
"test": "mocha tests --recursive",
18-
"update:eslint-docs": "eslint-doc-generator"
19-
},
20-
"dependencies": {
21-
"requireindex": "^1.2.0"
22-
},
23-
"devDependencies": {
24-
"eslint": "^8.19.0",
25-
"eslint-doc-generator": "^1.0.0",
26-
"eslint-plugin-eslint-plugin": "^5.0.0",
27-
"eslint-plugin-node": "^11.1.0",
28-
"mocha": "^10.0.0",
29-
"npm-run-all": "^4.1.5"
30-
},
31-
"engines": {
32-
"node": "^14.17.0 || ^16.0.0 || >= 18.0.0"
33-
},
34-
"peerDependencies": {
35-
"eslint": ">=7"
36-
},
37-
"license": "ISC"
2+
"name": "eslint-plugin-internal-rules",
3+
"version": "0.0.0",
4+
"description": "internal eslint rules",
5+
"keywords": [
6+
"eslint",
7+
"eslintplugin",
8+
"eslint-plugin"
9+
],
10+
"author": "",
11+
"main": "./lib/index.js",
12+
"exports": "./lib/index.js",
13+
"scripts": {
14+
"lint": "npm-run-all \"lint:*\"",
15+
"lint:eslint-docs": "npm-run-all \"update:eslint-docs -- --check\"",
16+
"lint:js": "eslint .",
17+
"test": "mocha tests --recursive",
18+
"update:eslint-docs": "eslint-doc-generator"
19+
},
20+
"dependencies": {
21+
"requireindex": "^1.2.0"
22+
},
23+
"devDependencies": {
24+
"eslint": "^8.19.0",
25+
"eslint-doc-generator": "^1.0.0",
26+
"eslint-plugin-eslint-plugin": "^5.0.0",
27+
"eslint-plugin-node": "^11.1.0",
28+
"mocha": "^10.0.0",
29+
"npm-run-all": "^4.1.5"
30+
},
31+
"engines": {
32+
"node": "^14.17.0 || ^16.0.0 || >= 18.0.0"
33+
},
34+
"peerDependencies": {
35+
"eslint": ">=7"
36+
},
37+
"license": "ISC"
3838
}

0 commit comments

Comments
 (0)