Repository: i18next/i18next-parser
Pull request #195 (2020-01-10 08:26:25)

Use default namespace from useTranslation hook if supplied

heivo: This is a fix for issue #161 
heivo: I added a feature to evaluate namespace overrides in the t-function options (see docs here: https://www.i18next.com/translation-function/essentials).

Patch:
diff --git a/dist/lexers/javascript-lexer.js b/dist/lexers/javascript-lexer.js
index c971dbb..4f10526 100644
--- a/dist/lexers/javascript-lexer.js
+++ b/dist/lexers/javascript-lexer.js
@@ -1,4 +1,4 @@
-'use strict';Object.defineProperty(exports, "__esModule", { value: true });var _createClass = function () {function defineProperties(target, props) {for (var i = 0; i < props.length; i++) {var descriptor = props[i];descriptor.enumerable = descriptor.enumerable || false;descriptor.configurable = true;if ("value" in descriptor) descriptor.writable = true;Object.defineProperty(target, descriptor.key, descriptor);}}return function (Constructor, protoProps, staticProps) {if (protoProps) defineProperties(Constructor.prototype, protoProps);if (staticProps) defineProperties(Constructor, staticProps);return Constructor;};}();var _baseLexer = require('./base-lexer');var _baseLexer2 = _interopRequireDefault(_baseLexer);
+'use strict';Object.defineProperty(exports, "__esModule", { value: true });var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) {return typeof obj;} : function (obj) {return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;};var _createClass = function () {function defineProperties(target, props) {for (var i = 0; i < props.length; i++) {var descriptor = props[i];descriptor.enumerable = descriptor.enumerable || false;descriptor.configurable = true;if ("value" in descriptor) descriptor.writable = true;Object.defineProperty(target, descriptor.key, descriptor);}}return function (Constructor, protoProps, staticProps) {if (protoProps) defineProperties(Constructor.prototype, protoProps);if (staticProps) defineProperties(Constructor, staticProps);return Constructor;};}();var _baseLexer = require('./base-lexer');var _baseLexer2 = _interopRequireDefault(_baseLexer);
 var _typescript = require('typescript');var ts = _interopRequireWildcard(_typescript);function _interopRequireWildcard(obj) {if (obj && obj.__esModule) {return obj;} else {var newObj = {};if (obj != null) {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];}}newObj.default = obj;return newObj;}}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };}function _classCallCheck(instance, Constructor) {if (!(instance instanceof Constructor)) {throw new TypeError("Cannot call a class as a function");}}function _possibleConstructorReturn(self, call) {if (!self) {throw new ReferenceError("this hasn't been initialised - super() hasn't been called");}return call && (typeof call === "object" || typeof call === "function") ? call : self;}function _inherits(subClass, superClass) {if (typeof superClass !== "function" && superClass !== null) {throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);}subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } });if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;}var
 
 JavascriptLexer = function (_BaseLexer) {_inherits(JavascriptLexer, _BaseLexer);
@@ -74,9 +74,23 @@ JavascriptLexer = function (_BaseLexer) {_inherits(JavascriptLexer, _BaseLexer);
             }} catch (err) {_didIteratorError = true;_iteratorError = err;} finally {try {if (!_iteratorNormalCompletion && _iterator.return) {_iterator.return();}} finally {if (_didIteratorError) {throw _iteratorError;}}}
         }
 
+        if (entry.ns) {
+          if (typeof entry.ns === 'string') {
+            entry.namespace = entry.ns;
+          } else if (_typeof(entry.ns) === 'object' && entry.ns.length) {
+            entry.namespace = entry.ns[0];
+          }
+        } else if (this.defaultNamespace) {
+          entry.namespace = this.defaultNamespace;
+        }
+
         return entry;
       }
 
+      if (node.expression.escapedText === 'useTranslation' && node.arguments.length) {
+        this.defaultNamespace = node.arguments[0].text;
+      }
+
       return null;
     } }, { key: 'concatenateString', value: function concatenateString(
 
diff --git a/src/lexers/javascript-lexer.js b/src/lexers/javascript-lexer.js
index 5e6b7e8..9177f7d 100644
--- a/src/lexers/javascript-lexer.js
+++ b/src/lexers/javascript-lexer.js
@@ -74,9 +74,23 @@ export default class JavascriptLexer extends BaseLexer {
         }
       }
 
+      if (entry.ns) {
+        if (typeof entry.ns === 'string') {
+          entry.namespace = entry.ns
+        } else if (typeof entry.ns === 'object' && entry.ns.length) {
+          entry.namespace = entry.ns[0]
+        }
+      } else if (this.defaultNamespace) {
+        entry.namespace = this.defaultNamespace
+      }
+
       return entry
     }
 
+    if(node.expression.escapedText === 'useTranslation' && node.arguments.length) {
+      this.defaultNamespace = node.arguments[0].text
+    }
+
     return null
   }
 


Test patch:
diff --git a/test/lexers/javascript-lexer.test.js b/test/lexers/javascript-lexer.test.js
index 3e00f8b..bbb7ebf 100644
--- a/test/lexers/javascript-lexer.test.js
+++ b/test/lexers/javascript-lexer.test.js
@@ -123,4 +123,17 @@ describe('JavascriptLexer', () => {
     const content = 'i18n.t("first") as potato'
     assert.deepEqual(Lexer.extract(content), [{ key: 'first' }])
   })
+
+  it('extracts default namespace from useTranslation hook', () => {
+    const Lexer = new JavascriptLexer()
+    const content = 'const {t} = useTranslation("foo"); t("bar");'
+    assert.deepEqual(Lexer.extract(content), [{ namespace: 'foo', key: 'bar' }])
+  })
+
+  it('uses namespace from t function with priority', () => {
+    const Lexer = new JavascriptLexer()
+    const content = 'const {t} = useTranslation("foo"); t("bar", {ns: "baz"});'
+    assert.deepEqual(Lexer.extract(content), [{ namespace: 'baz', key: 'bar', ns: 'baz' }])
+  })
+
 })