Repository: i18next/i18next-parser
Pull request #676 (2022-11-08 06:34:08)

Add entry value as a parameter to defaultValue function
### Why am I submitting this PR

This replaces the `skipDefaultValues` and `useKeysAsDefaultValues` with a more powerful option to use `value` itself as a function param.

Example:
```
defaultValue: (locale, namespace, key, value) => value ? value : `${key}`
```

### Does it fix an existing ticket?

Yes #677 

### Checklist

- [x] only relevant code is changed (make a diff before you submit the PR)
- [x] tests are included and pass: `yarn test` (see [details here](https://github.com/i18next/i18next-parser/blob/master/docs/development.md#tests))
- [x] documentation is changed or added



Patch:
diff --git a/README.md b/README.md
index ee45273..4aaa012 100644
--- a/README.md
+++ b/README.md
@@ -127,8 +127,8 @@ export default {
   // Default namespace used in your i18next config
 
   defaultValue: '',
-  // Default value to give to empty keys
-  // You may also specify a function accepting the locale, namespace, and key as arguments
+  // Default value to give to keys with no value
+  // You may also specify a function accepting the locale, namespace, key, and value as arguments
 
   indentation: 2,
   // Indentation of the catalog files
@@ -183,15 +183,6 @@ export default {
   sort: false,
   // Whether or not to sort the catalog. Can also be a [compareFunction](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#parameters)
 
-  skipDefaultValues: false,
-  // Whether to ignore default values
-  // You may also specify a function accepting the locale and namespace as arguments
-
-  useKeysAsDefaultValue: false,
-  // Whether to use the keys as the default value; ex. "Hello": "Hello", "World": "World"
-  // This option takes precedence over the `defaultValue` and `skipDefaultValues` options
-  // You may also specify a function accepting the locale and namespace as arguments
-
   verbose: false,
   // Display info about the parsing including some stats
 
diff --git a/src/helpers.js b/src/helpers.js
index e53412b..570bad4 100644
--- a/src/helpers.js
+++ b/src/helpers.js
@@ -35,33 +35,12 @@ function dotPathToHash(entry, target = {}, options = {}) {
   }
 
   const defaultValue =
-    typeof options.value === 'function'
-      ? options.value(options.locale, entry.namespace, key)
-      : options.value
-
-  const skipDefaultValues =
-    typeof options.skipDefaultValues === 'function'
-      ? options.skipDefaultValues(options.locale, entry.namespace)
-      : options.skipDefaultValues
-
-  const useKeysAsDefaultValue =
-    typeof options.useKeysAsDefaultValue === 'function'
-      ? options.useKeysAsDefaultValue(options.locale, entry.namespace)
-      : options.useKeysAsDefaultValue
+    entry[`defaultValue${options.suffix}`] || entry.defaultValue || ''
 
   let newValue =
-    entry[`defaultValue${options.suffix}`] ||
-    entry.defaultValue ||
-    defaultValue ||
-    ''
-
-  if (skipDefaultValues) {
-    newValue = ''
-  }
-
-  if (useKeysAsDefaultValue) {
-    newValue = key
-  }
+    typeof options.value === 'function'
+      ? options.value(options.locale, entry.namespace, key, defaultValue)
+      : options.value || defaultValue
 
   if (path.endsWith(separator)) {
     path = path.slice(0, -separator.length)
diff --git a/src/transform.js b/src/transform.js
index 07ba0c7..3f692a6 100644
--- a/src/transform.js
+++ b/src/transform.js
@@ -36,9 +36,7 @@ export default class i18nTransform extends Transform {
       output: 'locales/$LOCALE/$NAMESPACE.json',
       resetDefaultValueLocale: null,
       sort: false,
-      useKeysAsDefaultValue: false,
       verbose: false,
-      skipDefaultValues: false,
       customValueTemplate: null,
       failOnWarnings: false,
       yamlOptions: null,
@@ -171,8 +169,6 @@ export default class i18nTransform extends Transform {
           separator: this.options.keySeparator,
           pluralSeparator: this.options.pluralSeparator,
           value: this.options.defaultValue,
-          useKeysAsDefaultValue: this.options.useKeysAsDefaultValue,
-          skipDefaultValues: this.options.skipDefaultValues,
           customValueTemplate: this.options.customValueTemplate,
         })
 


Test patch:
diff --git a/test/helpers/dotPathToHash.test.js b/test/helpers/dotPathToHash.test.js
index 0ed2a1f..559c6d4 100644
--- a/test/helpers/dotPathToHash.test.js
+++ b/test/helpers/dotPathToHash.test.js
@@ -35,16 +35,6 @@ describe('dotPathToHash helper function', () => {
     done()
   })
 
-  it('supports custom separator when `useKeysAsDefaultValue` is true', (done) => {
-    const { target } = dotPathToHash(
-      { keyWithNamespace: 'namespace-two-three' },
-      {},
-      { separator: '-', useKeysAsDefaultValue: true }
-    )
-    assert.deepEqual(target, { namespace: { two: { three: 'two-three' } } })
-    done()
-  })
-
   it('handles an empty namespace', (done) => {
     const { target, duplicate } = dotPathToHash({
       keyWithNamespace: 'ns.',
diff --git a/test/parser.test.js b/test/parser.test.js
index 130251b..a6b0233 100644
--- a/test/parser.test.js
+++ b/test/parser.test.js
@@ -1083,79 +1083,78 @@ describe('parser', () => {
     })
 
     it('supports a defaultValue function', (done) => {
-      let result
+      let enResult
+      let arResult
       const i18nextParser = new i18nTransform({
-        defaultValue: (locale, namespace, key) =>
-          `${locale}:${namespace}:${key}`,
+        defaultValue: (locale, namespace, key, value) =>
+          `${locale}:${namespace}:${key}:${value}`,
+        locales: ['en', 'ar'],
       })
       const fakeFile = new Vinyl({
-        contents: Buffer.from("t('first')"),
+        contents: Buffer.from("t('first', 'myDefault')"),
         path: 'file.js',
       })
 
       i18nextParser.on('data', (file) => {
         if (file.relative.endsWith(enLibraryPath)) {
-          result = JSON.parse(file.contents)
+          enResult = JSON.parse(file.contents)
+        } else if (file.relative.endsWith(arLibraryPath)) {
+          arResult = JSON.parse(file.contents)
         }
       })
       i18nextParser.once('end', () => {
-        assert.deepEqual(result, { first: 'en:translation:first' })
+        assert.deepEqual(enResult, { first: 'en:translation:first:myDefault' })
+        assert.deepEqual(arResult, { first: 'ar:translation:first:myDefault' })
         done()
       })
 
       i18nextParser.end(fakeFile)
     })
 
-    it('supports a useKeysAsDefaultValue function', (done) => {
-      let enResult
-      let arResult
+    it('supports a defaultValue function with empty result', (done) => {
+      let result
       const i18nextParser = new i18nTransform({
-        locales: ['en', 'ar'],
-        useKeysAsDefaultValue: (locale, namespace) => locale === 'en',
+        defaultValue: (locale, namespace, key, value) => '',
       })
       const fakeFile = new Vinyl({
-        contents: Buffer.from("t('first')"),
+        contents: Buffer.from("t('first', 'myDefault')"),
         path: 'file.js',
       })
 
       i18nextParser.on('data', (file) => {
         if (file.relative.endsWith(enLibraryPath)) {
-          enResult = JSON.parse(file.contents)
-        } else if (file.relative.endsWith(arLibraryPath)) {
-          arResult = JSON.parse(file.contents)
+          result = JSON.parse(file.contents)
         }
       })
       i18nextParser.once('end', () => {
-        assert.deepEqual(enResult, { first: 'first' })
-        assert.deepEqual(arResult, { first: '' })
+        assert.deepEqual(result, { first: '' })
         done()
       })
 
       i18nextParser.end(fakeFile)
     })
 
-    it('supports a skipDefaultValues function', (done) => {
-      let enResult
-      let arResult
+    it('supports a defaultValue function with conditionals', (done) => {
+      let result
       const i18nextParser = new i18nTransform({
-        locales: ['en', 'ar'],
-        skipDefaultValues: (locale, namespace) => locale === 'en',
+        defaultValue: (locale, namespace, key, value) =>
+          value ? value : `${key}`,
       })
       const fakeFile = new Vinyl({
-        contents: Buffer.from("t('first', { defaultValue: 'default' })"),
+        contents: Buffer.from("t('first', 'myDefault'); t('second')"),
         path: 'file.js',
       })
 
       i18nextParser.on('data', (file) => {
         if (file.relative.endsWith(enLibraryPath)) {
-          enResult = JSON.parse(file.contents)
-        } else if (file.relative.endsWith(arLibraryPath)) {
-          arResult = JSON.parse(file.contents)
+          result = JSON.parse(file.contents)
         }
       })
       i18nextParser.once('end', () => {
-        assert.deepEqual(enResult, { first: '' })
-        assert.deepEqual(arResult, { first: 'default' })
+        assert.deepEqual(result, {
+          first: 'myDefault',
+          second: 'second',
+        })
         done()
       })
 
@@ -1527,37 +1526,6 @@ describe('parser', () => {
       i18nextParser.end(fakeFile)
     })
 
-    it('supports useKeysAsDefaultValue', (done) => {
-      let result
-      const i18nextParser = new i18nTransform({
-        useKeysAsDefaultValue: true,
-      })
-      const fakeFile = new Vinyl({
-        contents: Buffer.from(
-          "t('first'); \n t('second and third'); t('$fourth %fifth%'); t('six.seven');"
-        ),
-        path: 'file.js',
-      })
-
-      i18nextParser.once('data', (file) => {
-        if (file.relative.endsWith(enLibraryPath)) {
-          result = JSON.parse(file.contents)
-        }
-      })
-      i18nextParser.on('end', () => {
-        assert.deepEqual(result, {
-          first: 'first',
-          'second and third': 'second and third',
-          '$fourth %fifth%': '$fourth %fifth%',
-          six: {
-            seven: 'six.seven',
-          },
-        })
-        done()
-      })
-      i18nextParser.end(fakeFile)
-    })
-
     it('generates plurals', (done) => {
       let result
       const i18nextParser = new i18nTransform()
@@ -1719,10 +1687,10 @@ describe('parser', () => {
       i18nextParser.end(fakeFile)
     })
 
-    it('generates plurals with key as value', (done) => {
+    it('generates plurals for defaultValue function', (done) => {
       let result
       const i18nextParser = new i18nTransform({
-        useKeysAsDefaultValue: true,
+        defaultValue: (locale, namespace, key, value) => `${key}`,
       })
       const fakeFile = new Vinyl({
         contents: Buffer.from("t('test {{count}}', { count: 1 })"),
@@ -1835,10 +1803,10 @@ describe('parser', () => {
       i18nextParser.end(fakeFile)
     })
 
-    it('generates plurals with key as value for languages with multiple plural forms', (done) => {
+    it('generates plurals for defaultValue function for languages with multiple plural forms', (done) => {
       let result
       const i18nextParser = new i18nTransform({
-        useKeysAsDefaultValue: true,
+        defaultValue: (locale, namespace, key, value) => `${key}`,
         locales: ['ar'],
       })
       const fakeFile = new Vinyl({
@@ -1894,36 +1862,6 @@ describe('parser', () => {
       i18nextParser.end(fakeFile)
     })
 
-    it('supports skipDefaultValues option', (done) => {
-      let result
-      const i18nextParser = new i18nTransform({
-        skipDefaultValues: true,
-      })
-
-      const fakeFile = new Vinyl({
-        contents: Buffer.from(
-          "t('headline1', 'There will be a headline here.') \n" +
-            "t('headline2', {defaultValue: 'Another Headline here'}})"
-        ),
-        path: 'file.js',
-      })
-
-      i18nextParser.on('data', (file) => {
-        result = JSON.parse(file.contents)
-      })
-
-      i18nextParser.on('end', () => {
-        assert.deepEqual(result, {
-          headline1: '',
-          headline2: '',
-        })
-
-        done()
-      })
-
-      i18nextParser.end(fakeFile)
-    })
-
     it('supports customValueTemplate option', (done) => {
       let result
       const i18nextParser = new i18nTransform({