Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

i18next-scanner

Package Overview
Dependencies
Maintainers
1
Versions
93
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

i18next-scanner - npm Package Compare versions

Comparing version 1.6.0 to 1.7.0

test/transform-stream.js

122

lib/parser.js

@@ -61,5 +61,13 @@ 'use strict';

nsSeparator: ':', // char to split namespace from key
pluralSeparator: '_', // char to split plural from key
// Context Form
context: true, // whether to add context form key
contextFallback: true, // whether to add a fallback key as well as the context form key
contextSeparator: '_', // char to split context from key
// Plural Form
plural: true, // whether to add plural form key
pluralFallback: true, // whether to add a fallback key as well as the plural form key
pluralSeparator: '_', // char to split plural from key
// interpolation options

@@ -308,20 +316,18 @@ interpolation: {

if (endsWithComma) {
(function () {
var code = matchBalancedParentheses(content.substr(re.lastIndex));
var syntax = _esprima2.default.parse('(' + code + ')');
var props = _lodash2.default.get(syntax, 'body[0].expression.properties') || [];
// http://i18next.com/docs/options/
var supportedOptions = ['defaultValue', 'count', 'context', 'ns'];
var code = matchBalancedParentheses(content.substr(re.lastIndex));
var syntax = _esprima2.default.parse('(' + code + ')');
var props = _lodash2.default.get(syntax, 'body[0].expression.properties') || [];
// http://i18next.com/docs/options/
var supportedOptions = ['defaultValue', 'count', 'context', 'ns'];
props.forEach(function (prop) {
if (_lodash2.default.includes(supportedOptions, prop.key.name)) {
if (prop.value.type === 'Literal') {
options[prop.key.name] = prop.value.value;
} else {
// Unable to get value of the property
options[prop.key.name] = '';
}
props.forEach(function (prop) {
if (_lodash2.default.includes(supportedOptions, prop.key.name)) {
if (prop.value.type === 'Literal') {
options[prop.key.name] = prop.value.value;
} else {
// Unable to get value of the property
options[prop.key.name] = '';
}
});
})();
}
});
}

@@ -502,6 +508,6 @@

if (_lodash2.default.isString(options)) {
var defaultValue = options;
var _defaultValue = options;
options = {};
options.defaultValue = defaultValue;
options.defaultValue = _defaultValue;
}

@@ -531,5 +537,15 @@

var _options = this.options,
lngs = _options.lngs,
context = _options.context,
contextFallback = _options.contextFallback,
contextSeparator = _options.contextSeparator,
plural = _options.plural,
pluralFallback = _options.pluralFallback,
pluralSeparator = _options.pluralSeparator,
defaultValue = _options.defaultValue;
var keys = _lodash2.default.isString(keySeparator) ? key.split(keySeparator) : [key];
this.options.lngs.forEach(function (lng) {
lngs.forEach(function (lng) {
var resLoad = _this4.resStore[lng] && _this4.resStore[lng][ns];

@@ -573,45 +589,45 @@ var resScan = _this4.resScan[lng] && _this4.resScan[lng][ns];

// }
var formattedKey = key;
var resKeys = [];
// http://i18next.com/translate/context/
// Note. The parser only supports string type for "context"
var needsContextHandling = options.context !== undefined && typeof options.context === 'string' && options.context !== '';
if (needsContextHandling) {
formattedKey = formattedKey + _this4.options.contextSeparator + options.context;
}
var containsContext = context && options.context !== undefined && typeof options.context === 'string' && options.context !== '';
// http://i18next.com/translate/pluralSimple/
var needsPluralHandling = options.count !== undefined;
if (needsPluralHandling) {
// TODO: multiple plural forms
formattedKey = formattedKey + _this4.options.pluralSeparator + 'plural';
var containsPlural = plural && options.count !== undefined;
if (!containsContext && !containsPlural) {
resKeys.push(key);
}
if (options.defaultValue !== undefined) {
// Use `options.defaultValue` if specified
if (resLoad[key] === undefined) {
resLoad[key] = options.defaultValue;
_this4.debuglog('Added a new translation key { %s: %s } to %s', JSON.stringify(key), JSON.stringify(resLoad[key]), JSON.stringify(_this4.formatResourceLoadPath(lng, ns)));
}
resScan[key] = resLoad[key];
if (containsContext && contextFallback || containsPlural && pluralFallback) {
resKeys.push(key);
}
if (formattedKey !== key && resLoad[formattedKey] === undefined) {
resLoad[formattedKey] = options.defaultValue;
_this4.debuglog('Added a new translation key { %s: %s } to %s', JSON.stringify(formattedKey), JSON.stringify(resLoad[formattedKey]), JSON.stringify(_this4.formatResourceLoadPath(lng, ns)));
if (containsContext) {
resKeys.push('' + key + contextSeparator + options.context);
}
if (containsPlural) {
resKeys.push('' + key + pluralSeparator + 'plural');
}
if (containsContext && containsPlural) {
resKeys.push('' + key + contextSeparator + options.context + pluralSeparator + 'plural');
}
resKeys.forEach(function (resKey) {
if (resLoad[resKey] === undefined) {
if (options.defaultValue !== undefined) {
// Use `options.defaultValue` if specified
resLoad[resKey] = options.defaultValue;
} else {
// Fallback to `defaultValue`
resLoad[resKey] = _lodash2.default.isFunction(defaultValue) ? defaultValue(lng, ns, key, options) : defaultValue;
}
_this4.debuglog('Added a new translation key { %s: %s } to %s', JSON.stringify(resKey), JSON.stringify(resLoad[resKey]), JSON.stringify(_this4.formatResourceLoadPath(lng, ns)));
}
resScan[formattedKey] = resLoad[formattedKey];
} else {
// Fallback to `this.options.defaultValue`
if (resLoad[key] === undefined) {
resLoad[key] = _lodash2.default.isFunction(_this4.options.defaultValue) ? _this4.options.defaultValue(lng, ns, key, options) : _this4.options.defaultValue;
_this4.debuglog('Added a new translation key { %s: %s } to %s', JSON.stringify(key), JSON.stringify(resLoad[key]), JSON.stringify(_this4.formatResourceLoadPath(lng, ns)));
}
resScan[key] = resLoad[key];
if (formattedKey !== key && resLoad[formattedKey] === undefined) {
resLoad[formattedKey] = _lodash2.default.isFunction(_this4.options.defaultValue) ? _this4.options.defaultValue(lng, ns, key, options) : _this4.options.defaultValue;
_this4.debuglog('Added a new translation key { %s: %s } to %s', JSON.stringify(formattedKey), JSON.stringify(resLoad[formattedKey]), JSON.stringify(_this4.formatResourceLoadPath(lng, ns)));
}
resScan[formattedKey] = resLoad[formattedKey];
}
resScan[resKey] = resLoad[resKey];
});
});

@@ -618,0 +634,0 @@ });

{
"name": "i18next-scanner",
"version": "1.6.0",
"version": "1.7.0",
"description": "Scan your code, extract translation keys/values, and merge them into i18n resource files.",

@@ -47,5 +47,5 @@ "homepage": "https://github.com/i18next/i18next-scanner",

"dependencies": {
"esprima": "^3.1.2",
"lodash": "^4.17.2",
"through2": "^2.0.2",
"esprima": "^3.1.3",
"lodash": "^4.17.4",
"through2": "^2.0.3",
"vinyl": "^2.0.1",

@@ -55,16 +55,17 @@ "vinyl-fs": "^2.4.4"

"devDependencies": {
"babel-cli": "^6.18.0",
"babel-core": "^6.18.2",
"babel-cli": "^6.24.0",
"babel-core": "^6.24.0",
"babel-eslint": "^7.1.1",
"babel-preset-es2015": "^6.18.0",
"babel-preset-stage-0": "^6.16.0",
"coveralls": "^2.11.15",
"eslint": "^3.11.0",
"babel-preset-es2015": "^6.24.0",
"babel-preset-stage-0": "^6.22.0",
"coveralls": "^2.12.0",
"eslint": "^3.17.1",
"gulp": "^3.9.1",
"gulp-tap": "^0.1.3",
"gulp-util": "^3.0.7",
"gulp-util": "^3.0.8",
"sha1": "^1.1.1",
"tap": "^8.0.1",
"text-table": "^0.2.0"
"tap": "^10.3.0",
"text-table": "^0.2.0",
"which": "~1.2.12"
}
}

@@ -487,8 +487,14 @@ # i18next-scanner [![build status](https://travis-ci.org/i18next/i18next-scanner.svg?branch=master)](https://travis-ci.org/i18next/i18next-scanner) [![Coverage Status](https://coveralls.io/repos/i18next/i18next-scanner/badge.svg?branch=master&service=github)](https://coveralls.io/github/i18next/i18next-scanner?branch=master)

#### pluralSeparator
#### context
Type: `String` Default: `'_'`
Type: `Boolean` Default: `true`
The character to split plural from key.
Whether to add context form key.
#### contextFallback
Type: `Boolean` Default: `true`
Whether to add a fallback key as well as the context form key.
#### contextSeparator

@@ -500,2 +506,20 @@

#### plural
Type: `Boolean` Default: `true`
Whether to add plural form key.
#### pluralFallback
Type: `Boolean` Default: `true`
Whether to add a fallback key as well as the plural form key.
#### pluralSeparator
Type: `String` Default: `'_'`
The character to split plural from key.
#### interpolation

@@ -502,0 +526,0 @@

@@ -39,5 +39,13 @@ /* eslint no-console: 0 */

nsSeparator: ':', // char to split namespace from key
pluralSeparator: '_', // char to split plural from key
// Context Form
context: true, // whether to add context form key
contextFallback: true, // whether to add a fallback key as well as the context form key
contextSeparator: '_', // char to split context from key
// Plural Form
plural: true, // whether to add plural form key
pluralFallback: true, // whether to add a fallback key as well as the plural form key
pluralSeparator: '_', // char to split plural from key
// interpolation options

@@ -465,5 +473,15 @@ interpolation: {

const {
lngs,
context,
contextFallback,
contextSeparator,
plural,
pluralFallback,
pluralSeparator,
defaultValue
} = this.options;
const keys = _.isString(keySeparator) ? key.split(keySeparator) : [key];
this.options.lngs.forEach((lng) => {
lngs.forEach((lng) => {
let resLoad = this.resStore[lng] && this.resStore[lng][ns];

@@ -506,64 +524,55 @@ let resScan = this.resScan[lng] && this.resScan[lng][ns];

// }
let formattedKey = key;
const resKeys = [];
// http://i18next.com/translate/context/
// Note. The parser only supports string type for "context"
const needsContextHandling = (options.context !== undefined) && (typeof options.context === 'string') && (options.context !== '');
if (needsContextHandling) {
formattedKey = formattedKey + this.options.contextSeparator + options.context;
}
const containsContext = context
&& (options.context !== undefined)
&& (typeof options.context === 'string')
&& (options.context !== '');
// http://i18next.com/translate/pluralSimple/
const needsPluralHandling = (options.count !== undefined);
if (needsPluralHandling) { // TODO: multiple plural forms
formattedKey = formattedKey + this.options.pluralSeparator + 'plural';
const containsPlural = plural
&& (options.count !== undefined);
if (!containsContext && !containsPlural) {
resKeys.push(key);
}
if (options.defaultValue !== undefined) {
// Use `options.defaultValue` if specified
if (resLoad[key] === undefined) {
resLoad[key] = options.defaultValue;
this.debuglog('Added a new translation key { %s: %s } to %s',
JSON.stringify(key),
JSON.stringify(resLoad[key]),
JSON.stringify(this.formatResourceLoadPath(lng, ns))
);
}
resScan[key] = resLoad[key];
if ((containsContext && contextFallback) || (containsPlural && pluralFallback)) {
resKeys.push(key);
}
if ((formattedKey !== key) && (resLoad[formattedKey] === undefined)) {
resLoad[formattedKey] = options.defaultValue;
if (containsContext) {
resKeys.push(`${key}${contextSeparator}${options.context}`);
}
if (containsPlural) {
resKeys.push(`${key}${pluralSeparator}plural`);
}
if (containsContext && containsPlural) {
resKeys.push(`${key}${contextSeparator}${options.context}${pluralSeparator}plural`);
}
resKeys.forEach(resKey => {
if (resLoad[resKey] === undefined) {
if (options.defaultValue !== undefined) {
// Use `options.defaultValue` if specified
resLoad[resKey] = options.defaultValue;
} else {
// Fallback to `defaultValue`
resLoad[resKey] = _.isFunction(defaultValue)
? defaultValue(lng, ns, key, options)
: defaultValue;
}
this.debuglog('Added a new translation key { %s: %s } to %s',
JSON.stringify(formattedKey),
JSON.stringify(resLoad[formattedKey]),
JSON.stringify(resKey),
JSON.stringify(resLoad[resKey]),
JSON.stringify(this.formatResourceLoadPath(lng, ns))
);
}
resScan[formattedKey] = resLoad[formattedKey];
} else {
// Fallback to `this.options.defaultValue`
if (resLoad[key] === undefined) {
resLoad[key] = _.isFunction(this.options.defaultValue)
? this.options.defaultValue(lng, ns, key, options)
: this.options.defaultValue;
this.debuglog('Added a new translation key { %s: %s } to %s',
JSON.stringify(key),
JSON.stringify(resLoad[key]),
JSON.stringify(this.formatResourceLoadPath(lng, ns))
);
}
resScan[key] = resLoad[key];
if ((formattedKey !== key) && (resLoad[formattedKey] === undefined)) {
resLoad[formattedKey] = _.isFunction(this.options.defaultValue)
? this.options.defaultValue(lng, ns, key, options)
: this.options.defaultValue;
this.debuglog('Added a new translation key { %s: %s } to %s',
JSON.stringify(formattedKey),
JSON.stringify(resLoad[formattedKey]),
JSON.stringify(this.formatResourceLoadPath(lng, ns))
);
}
resScan[formattedKey] = resLoad[formattedKey];
}
resScan[resKey] = resLoad[resKey];
});
});

@@ -570,0 +579,0 @@ });

@@ -1,5 +0,1 @@

i18next.t('friend', {count: 1}); // output: 'A friend'
i18next.t('friend', {count: 100}); // output: '100 friends'
i18next.t('friend', {context: 'male'}); // output: 'A boyfriend'
i18next.t('friend', {context: 'female'}); // output: 'A girlfriend'
i18next.t('friend', {context: 'male', count: 1}); // output: 'A boyfriend'

@@ -6,0 +2,0 @@ i18next.t('friend', {context: 'female', count: 1}); // output: 'A girlfriend'

@@ -1,3 +0,2 @@

i18next.t('friend'); // output: 'A friend'
i18next.t('friend', {context: 'male'}); // output: 'A boyfriend'
i18next.t('friend', {context: 'female'}); // output: 'A girlfriend'

@@ -365,17 +365,92 @@ import fs from 'fs';

test('Context with plural combined', (t) => {
const parser = new Parser();
const content = fs.readFileSync(path.resolve(__dirname, 'fixtures/context-plural.js'), 'utf-8');
parser.parseFuncFromString(content);
t.same(parser.get(), {
en: {
translation: {
"friend": "",
"friend_plural": "",
"friend_male": "",
"friend_male_plural": "",
"friend_female": "",
"friend_female_plural": ""
test('Default options', (t) => {
const parser = new Parser();
parser.parseFuncFromString(content);
t.same(parser.get(), {
en: {
translation: {
"friend": "",
"friend_plural": "",
"friend_male": "",
"friend_male_plural": "",
"friend_female": "",
"friend_female_plural": ""
}
}
}
});
t.end();
});
test('Context form only', (t) => {
const parser = new Parser({
context: true,
plural: false
});
parser.parseFuncFromString(content);
t.same(parser.get(), {
en: {
translation: {
"friend": "",
"friend_male": "",
"friend_female": ""
}
}
});
t.end();
});
test('No context fallback', (t) => {
const parser = new Parser({
context: true,
contextFallback: false,
plural: false
});
parser.parseFuncFromString(content);
t.same(parser.get(), {
en: {
translation: {
"friend_male": "",
"friend_female": ""
}
}
});
t.end();
});
test('Plural form only', (t) => {
const parser = new Parser({
context: false,
plural: true
});
parser.parseFuncFromString(content);
t.same(parser.get(), {
en: {
translation: {
"friend": "",
"friend_plural": ""
}
}
});
t.end();
});
test('No plural fallback', (t) => {
const parser = new Parser({
context: false,
plural: true,
pluralFallback: false
});
parser.parseFuncFromString(content);
t.same(parser.get(), {
en: {
translation: {
"friend_plural": ""
}
}
});
t.end();
});
t.end();

@@ -382,0 +457,0 @@ });

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc