Skip to content

Commit

Permalink
feat(parser): Add exception for removing unused keys (#262)
Browse files Browse the repository at this point in the history
* feat(parser): Add exception filter for removing unused keys

* refactor: allow the `removeUnusedKeys` function to be passed in to determine if an unused key should be removed

* chore: bump to 4.6.0

* test: enhance test case for the `removeUnusedKeys` option

---------

Co-authored-by: cheton <[email protected]>
  • Loading branch information
yocarbo and cheton authored Oct 14, 2024
1 parent f720314 commit 138825a
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 13 deletions.
33 changes: 27 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -570,9 +570,30 @@ Set to `true` to turn on debug output.

#### removeUnusedKeys

Type: `Boolean` Default: `false`
Type: `Boolean` or `Function` Default: `false`

Set to `true` to remove unused translation keys from i18n resource files. By default, this is set to `false`.
```js
{ // Default
removeUnusedKeys: false,
}
```

Set to `true` to remove unused translation keys from i18n resource files.
If a function is provided, it will be used to decide whether an unused translation key should be removed.
```js
// Available since 4.6.0
//
// @param {string} lng The language of the unused translation key.
// @param {string} ns The namespace of the unused translation key.
// @param {array} key The translation key in its array form.
// @return {boolean} Returns true if the unused translation key should be removed.
removeUnusedKeys: function(lng, ns, key) {
if (ns === 'resource') {
return true;
}
return false;
}
```

#### sort

Expand All @@ -594,7 +615,7 @@ If an `Object` is supplied, you can either specify a list of attributes and exte
}
```

You can set attr to `false` to disable parsing attribute as below:
You can set `attr` to `false` to disable parsing attribute as below:
```js
{
attr: false
Expand All @@ -615,7 +636,7 @@ If an `Object` is supplied, you can either specify a list of translation functio
}
```

You can set func to `false` to disable parsing translation function as below:
You can set `func` to `false` to disable parsing translation function as below:
```js
{
func: false
Expand Down Expand Up @@ -649,14 +670,14 @@ If an `Object` is supplied, you can specify a list of extensions, or override th
}
```

You can set trans to `false` to disable parsing Trans component as below:
You can set `trans` to `false` to disable parsing Trans component as below:
```js
{
trans: false
}
```

The fallbackKey can either be a boolean value, or a function like so:
The `fallbackKey` can either be a boolean value, or a function like so:
```js
fallbackKey: function(ns, value) {
// Returns a hash value as the fallback key
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "i18next-scanner",
"version": "4.5.0",
"version": "4.6.0",
"description": "Scan your code, extract translation keys/values, and merge them into i18n resource files.",
"homepage": "https://github.com/i18next/i18next-scanner",
"author": "Cheton Wu <[email protected]>",
Expand Down
13 changes: 10 additions & 3 deletions src/parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -786,7 +786,7 @@ class Parser {
}

let resStore = {};
if (this.options.removeUnusedKeys) {
if (!!this.options.removeUnusedKeys) {
// Merge two objects `resStore` and `resScan` deeply, returning a new merged object with the elements from both `resStore` and `resScan`.
const overwriteMerge = (destinationArray, sourceArray, options) => sourceArray;
const resMerged = deepMerge(this.resStore, this.resScan, { arrayMerge: overwriteMerge });
Expand All @@ -798,8 +798,15 @@ class Parser {
const unusedKeys = _.differenceWith(resStoreKeys, resScanKeys, _.isEqual);

for (let i = 0; i < unusedKeys.length; ++i) {
_.unset(resMerged[lng][ns], unusedKeys[i]);
this.log(`Removed an unused translation key { ${chalk.red(JSON.stringify(unusedKeys[i]))} from ${chalk.red(JSON.stringify(this.formatResourceLoadPath(lng, ns)))}`);
const unusedKey = unusedKeys[i];
const isRemovable = (typeof this.options.removeUnusedKeys === 'function')
? this.options.removeUnusedKeys(lng, ns, unusedKey)
: !!this.options.removeUnusedKeys;

if (isRemovable) {
_.unset(resMerged[lng][ns], unusedKey);
this.log(`Removed an unused translation key { ${chalk.red(JSON.stringify(unusedKey))} } from ${chalk.red(JSON.stringify(this.formatResourceLoadPath(lng, ns)))}`);
}
}

// Omit empty object
Expand Down
19 changes: 16 additions & 3 deletions test/transform-stream.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,12 @@ test('Keep old translations', done => {
// https://github.com/i18next/i18next-scanner/issues/30
test('Remove old translation keys which are already removed from code', done => {
const options = _.merge({}, defaults, {
removeUnusedKeys: true,
removeUnusedKeys: function(lng, ns, key) {
if (ns === 'resource') {
return true;
}
return false;
},
resource: {
loadPath: 'test/fixtures/i18n/{{lng}}/{{ns}}.json',
savePath: 'i18n/{{lng}}/{{ns}}.json'
Expand All @@ -420,7 +425,11 @@ test('Remove old translation keys which are already removed from code', done =>
// English - locale.json
if (file.path === 'i18n/en/locale.json') {
const found = JSON.parse(contents);
const wanted = {};
const wanted = {
'language': {
'en-US': 'English',
},
};
expect(found).toEqual(wanted);
}

Expand All @@ -441,7 +450,11 @@ test('Remove old translation keys which are already removed from code', done =>
// German - locale.json
if (file.path === 'i18n/de/locale.json') {
const found = JSON.parse(contents);
const wanted = {};
const wanted = {
'language': {
'de-DE': 'German',
},
};
expect(found).toEqual(wanted);
}

Expand Down

0 comments on commit 138825a

Please sign in to comment.