From 8b5407c52747fbf441d2a8974d66b0226a3b1604 Mon Sep 17 00:00:00 2001 From: mmohajer <89998014+mmohajer@users.noreply.github.com> Date: Thu, 16 Jun 2022 03:18:47 -0700 Subject: [PATCH] feat: add `metadata` attribute for passing context information about the translation key/string (#230) * feat: Add externalOptions support * cleanup * cleanup * update handleObject expression * Add test * Add comment * Update readme * update description and test * update key name * update file name Co-authored-by: webguy-github-ssh-key --- README.md | 6 +++++ src/parser.js | 55 +++++++++++++++++++++++++++++++-------- test/fixtures/metadata.js | 1 + test/parser.js | 25 ++++++++++++++++++ 4 files changed, 76 insertions(+), 11 deletions(-) create mode 100644 test/fixtures/metadata.js diff --git a/README.md b/README.md index 9d7e54f..8ce3ebf 100755 --- a/README.md +++ b/README.md @@ -822,6 +822,12 @@ interpolation options ## Integration Guide Checkout [Integration Guide](https://github.com/i18next/i18next-scanner/wiki/Integration-Guide) to learn how to integrate with [React](https://github.com/i18next/i18next-scanner/wiki/Integration-Guide#react), [Gettext Style I18n](https://github.com/i18next/i18next-scanner/wiki/Integration-Guide#gettext-style-i18n), and [Handlebars](https://github.com/i18next/i18next-scanner/wiki/Integration-Guide#handlebars). +#### metadata + +Type: `Object` Default: `{}` + +This can be used to pass any additional information regarding the string. + ## License MIT diff --git a/src/parser.js b/src/parser.js index 285e312..7a9dc4a 100644 --- a/src/parser.js +++ b/src/parser.js @@ -95,7 +95,8 @@ const defaults = { interpolation: { prefix: '{{', // prefix for interpolation suffix: '}}' // suffix for interpolation - } + }, + metadata: {} // additional custom options }; // http://codereview.stackexchange.com/questions/45991/balanced-parentheses @@ -366,6 +367,46 @@ class Parser { return fixedString; } + handleObjectExpression(props) { + return props.reduce((acc, prop) => { + if (prop.type !== 'ObjectMethod') { + const value = this.optionsBuilder(prop.value); + if (value !== undefined) { + return { + ...acc, + [prop.key.name]: value + }; + } + } + return acc; + }, {}); + } + + handleArrayExpression(elements) { + return elements.reduce((acc, element) => [ + ...acc, + this.optionsBuilder(element) + ], + [],); + } + + optionsBuilder(prop) { + if (prop.value && prop.value.type === 'Literal' || prop.type && prop.type === 'Literal') { + return prop.value.value !== undefined ? prop.value.value : prop.value; + } else if (prop.value && prop.value.type === 'TemplateLiteral' || prop.type && prop.type === 'TemplateLiteral') { + return prop.value.quasis.map((element) => { + return element.value.cooked; + }).join(''); + } else if (prop.value && prop.value.type === 'ObjectExpression' || prop.type && prop.type === 'ObjectExpression') { + return this.handleObjectExpression(prop.value.properties); + } else if (prop.value && prop.value.type === 'ArrayExpression' || prop.type && prop.type === 'ArrayExpression') { + return this.handleArrayExpression(prop.elements); + } else { + // Unable to get value of the property + return ''; + } + } + // i18next.t('ns:foo.bar') // matched // i18next.t("ns:foo.bar") // matched // i18next.t('ns:foo.bar') // matched @@ -450,20 +491,12 @@ class Parser { 'ns', 'keySeparator', 'nsSeparator', + 'metadata', ]; props.forEach((prop) => { if (_.includes(supportedOptions, prop.key.name)) { - if (prop.value.type === 'Literal') { - options[prop.key.name] = prop.value.value; - } else if (prop.value.type === 'TemplateLiteral') { - options[prop.key.name] = prop.value.quasis - .map(element => element.value.cooked) - .join(''); - } else { - // Unable to get value of the property - options[prop.key.name] = ''; - } + options[prop.key.name] = this.optionsBuilder(prop); } }); } catch (err) { diff --git a/test/fixtures/metadata.js b/test/fixtures/metadata.js new file mode 100644 index 0000000..d7b24eb --- /dev/null +++ b/test/fixtures/metadata.js @@ -0,0 +1 @@ +i18next.t('friend', {metadata: {tags: ['tag1', 'tag2']}}); diff --git a/test/parser.js b/test/parser.js index 23408a6..e03b976 100644 --- a/test/parser.js +++ b/test/parser.js @@ -1198,3 +1198,28 @@ test('Default values test', (t) => { t.end(); }); + +test('metadata', (t) => { + const parser = new Parser(); + const content = fs.readFileSync(path.resolve(__dirname, 'fixtures/metadata.js'), 'utf-8'); + const customHandler = function(key, options) { + parser.set(key, options); + t.same(options, { + 'metadata': { + 'tags': [ + 'tag1', + 'tag2', + ], + }, + }); + }; + parser.parseFuncFromString(content, customHandler); + t.same(parser.get(), { + en: { + translation: { + 'friend': '', + } + } + }); + t.end(); +});