Socket
Socket
Sign inDemoInstall

i18next-scanner

Package Overview
Dependencies
5
Maintainers
1
Versions
92
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 1.1.0 to 1.2.0

lib/match-recursive-regexp.js

235

lib/parser.js

@@ -18,2 +18,6 @@ 'use strict';

var _esprima = require('esprima');
var _esprima2 = _interopRequireDefault(_esprima);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

@@ -56,2 +60,4 @@

nsSeparator: ':', // char to split namespace from key
pluralSeparator: '_', // char to split plural from key
contextSeparator: '_', // char to split context from key

@@ -65,2 +71,36 @@ // interpolation options

// http://codereview.stackexchange.com/questions/45991/balanced-parentheses
var matchBalancedParentheses = function matchBalancedParentheses() {
var str = arguments.length <= 0 || arguments[0] === undefined ? '' : arguments[0];
var parentheses = '[]{}()';
var stack = [];
var bracePosition = void 0;
var start = -1;
str = '' + str; // ensure string
for (var _i = 0; _i < str.length; ++_i) {
if (start >= 0 && stack.length === 0) {
return str.substring(start, _i);
}
bracePosition = parentheses.indexOf(str[_i]);
if (bracePosition < 0) {
continue;
}
if (bracePosition % 2 === 0) {
if (start < 0) {
start = _i; // remember the start position
}
stack.push(bracePosition + 1); // push next expected brace position
continue;
}
if (stack.pop() !== bracePosition) {
return str.substring(start, _i);
}
}
return str.substring(start, i);
};
var transformOptions = function transformOptions(options) {

@@ -217,20 +257,42 @@ // Attribute

}).value().join('|').replace(/\./g, '\\.');
var pattern = '(?:(?:^[\s]*)|[^a-zA-Z0-9_])(?:' + matchPattern + ')\\(("(?:[^"\\\\]|\\\\.)*"|\'(?:[^\'\\\\]|\\\\.)*\')\\s*[\\,\\)]';
var results = content.match(new RegExp(pattern, 'gim')) || [];
results.forEach(function (result) {
var r = result.match(new RegExp(pattern));
if (!r) {
return;
}
var pattern = '(?:(?:^[\\s]*)|[^a-zA-Z0-9_])(?:' + matchPattern + ')\\(("(?:[^"\\\\]|\\\\.)*"|\'(?:[^\'\\\\]|\\\\.)*\')\\s*[\\,\\)]';
var re = new RegExp(pattern, 'gim');
var r = void 0;
var _loop = function _loop() {
var full = r[0];
var key = _lodash2.default.trim(r[1], '\'"');
var options = {};
var endsWithComma = full[full.length - 1] === ',';
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'];
props.forEach(function (prop) {
if (_lodash2.default.includes(supportedOptions, prop.key.name)) {
options[prop.key.name] = prop.value.value;
}
});
})();
}
if (customHandler) {
customHandler(key);
return;
customHandler(key, options);
return 'continue';
}
_this2.set(key);
});
_this2.set(key, options);
};
while (r = re.exec(content)) {
var _ret = _loop();
if (_ret === 'continue') continue;
}
return this;

@@ -259,10 +321,7 @@ }

}).value().join('|').replace(/\./g, '\\.');
var pattern = '(?:(?:^[\s]*)|[^a-zA-Z0-9_])(?:' + matchPattern + ')=("[^"]*"|\'[^\']*\')';
var results = content.match(new RegExp(pattern, 'gim')) || [];
results.forEach(function (result) {
var r = result.match(new RegExp(pattern));
if (!r) {
return;
}
var pattern = '(?:(?:^[\\s]*)|[^a-zA-Z0-9_])(?:' + matchPattern + ')=("[^"]*"|\'[^\']*\')';
var re = new RegExp(pattern, 'gim');
var r = void 0;
while (r = re.exec(content)) {
var attr = _lodash2.default.trim(r[1], '\'"');

@@ -292,3 +351,3 @@ var keys = attr.indexOf(';') >= 0 ? attr.split(';') : [attr];

});
});
}

@@ -337,4 +396,3 @@ return this;

if (!_lodash2.default.isUndefined(key)) {
var options = this.options;
var ns = options.defaultNs;
var ns = this.options.defaultNs;

@@ -349,4 +407,4 @@ // http://i18next.com/translate/keyBasedFallback/

if (_lodash2.default.isString(options.nsSeparator) && key.indexOf(options.nsSeparator) > -1) {
var parts = key.split(options.nsSeparator);
if (_lodash2.default.isString(this.options.nsSeparator) && key.indexOf(this.options.nsSeparator) > -1) {
var parts = key.split(this.options.nsSeparator);
ns = parts[0];

@@ -356,4 +414,4 @@ key = parts[1];

var keys = _lodash2.default.isString(options.keySeparator) ? key.split(options.keySeparator) : [key];
var lng = opts.lng ? opts.lng : options.fallbackLng;
var keys = _lodash2.default.isString(this.options.keySeparator) ? key.split(this.options.keySeparator) : [key];
var lng = opts.lng ? opts.lng : this.options.fallbackLng;
var namespaces = resStore[lng] || {};

@@ -375,12 +433,22 @@

// @param {string} key The translation key
// @param {string} [defaultValue] The key's value
// @param {object} [options] The options object
// @param {string} [options.defaultValue] defaultValue to return if translation not found
// @param {number} [options.count] count value used for plurals
// @param {string} [options.context] used for contexts (eg. male)
}, {
key: 'set',
value: function set(key, defaultValue) {
value: function set(key) {
var _this4 = this;
var options = this.options;
var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
var ns = options.defaultNs;
// Backward compatibility
if (_lodash2.default.isString(options)) {
var defaultValue = options;
options = {};
options.defaultValue = defaultValue;
}
var ns = this.options.defaultNs;
console.assert(_lodash2.default.isString(ns) && !!ns.length, 'ns is not a valid string', ns);

@@ -396,4 +464,4 @@

if (_lodash2.default.isString(options.nsSeparator) && key.indexOf(options.nsSeparator) > -1) {
var parts = key.split(options.nsSeparator);
if (_lodash2.default.isString(this.options.nsSeparator) && key.indexOf(this.options.nsSeparator) > -1) {
var parts = key.split(this.options.nsSeparator);
ns = parts[0];

@@ -403,40 +471,75 @@ key = parts[1];

var keys = _lodash2.default.isString(options.keySeparator) ? key.split(options.keySeparator) : [key];
options.lngs.forEach(function (lng) {
var value = _this4.resStore[lng] && _this4.resStore[lng][ns];
var x = 0;
var keys = _lodash2.default.isString(this.options.keySeparator) ? key.split(this.options.keySeparator) : [key];
this.options.lngs.forEach(function (lng) {
var res = _this4.resStore[lng] && _this4.resStore[lng][ns];
while (keys[x]) {
value = value && value[keys[x]];
x++;
if (!_lodash2.default.isObject(res)) {
// skip undefined namespace
console.log('The namespace "' + ns + '" does not exist:', { key: key, options: options });
return;
}
if (!_lodash2.default.isUndefined(value)) {
// Found a value associated with the key
var lookupKey = '[' + lng + '][' + ns + '][' + keys.join('][') + ']';
_this4.debuglog('Found a value %s associated with the key %s in %s.', JSON.stringify(_lodash2.default.get(_this4.resStore, lookupKey)), JSON.stringify(keys.join(options.keySeparator || '')), JSON.stringify(_this4.formatResourceLoadPath(lng, ns)));
} else if (_lodash2.default.isObject(_this4.resStore[lng][ns])) {
(function () {
// Adding a new entry
var res = _this4.resStore[lng][ns];
Object.keys(keys).forEach(function (index) {
var elem = keys[index];
if (index >= keys.length - 1) {
if (_lodash2.default.isUndefined(defaultValue)) {
res[elem] = _lodash2.default.isFunction(options.defaultValue) ? options.defaultValue(lng, ns, elem) : options.defaultValue;
} else {
res[elem] = defaultValue;
}
} else {
res[elem] = res[elem] || {};
res = res[elem];
}
});
var lookupKey = '[' + lng + '][' + ns + '][' + keys.join('][') + ']';
_this4.debuglog('Adding a new entry {%s:%s} to %s.', JSON.stringify(keys.join(options.keySeparator || '')), JSON.stringify(_lodash2.default.get(_this4.resStore, lookupKey)), JSON.stringify(_this4.formatResourceLoadPath(lng, ns)));
})();
} else {
// skip the namespace that is not defined in the i18next options
console.log('The namespace "' + ns + '" does not exist:', { key: key, defaultValue: defaultValue });
}
Object.keys(keys).forEach(function (index) {
var key = keys[index];
if (index < keys.length - 1) {
res[key] = res[key] || {};
res = res[key];
return; // continue
}
var hasContext = options.context !== undefined;
var hasCount = options.count !== undefined;
// Context & Plural
// http://i18next.com/translate/context/
// http://i18next.com/translate/pluralSimple/
//
// Format:
// "<key>[[{{contextSeparator}}<context>]{{pluralSeparator}}<plural>]"
//
// Example:
// {
// "translation": {
// "friend": "A friend",
// "friend_male": "A boyfriend",
// "friend_female": "A girlfriend",
// "friend_male_plural": "{{count}} boyfriends",
// "friend_female_plural": "{{count}} girlfriends"
// }
// }
var formattedKey = key;
// http://i18next.com/translate/context/
if (hasContext) {
formattedKey = formattedKey + _this4.options.contextSeparator + options.context;
}
// http://i18next.com/translate/pluralSimple/
if (hasCount) {
// TODO: multiple plural forms
formattedKey = formattedKey + _this4.options.pluralSeparator + 'plural';
}
if (options.defaultValue !== undefined) {
// Use `options.defaultValue` if specified
if (res[key] === undefined) {
res[key] = options.defaultValue;
_this4.debuglog('Added a new translation key { %s: %s } to %s', JSON.stringify(key), JSON.stringify(res[key]), JSON.stringify(_this4.formatResourceLoadPath(lng, ns)));
}
if (formattedKey !== key && res[formattedKey] === undefined) {
res[formattedKey] = options.defaultValue;
_this4.debuglog('Added a new translation key { %s: %s } to %s', JSON.stringify(formattedKey), JSON.stringify(res[formattedKey]), JSON.stringify(_this4.formatResourceLoadPath(lng, ns)));
}
} else {
// Fallback to `this.options.defaultValue`
if (res[key] === undefined) {
res[key] = _lodash2.default.isFunction(_this4.options.defaultValue) ? _this4.options.defaultValue(lng, ns, key) : _this4.options.defaultValue;
_this4.debuglog('Added a new translation key { %s: %s } to %s', JSON.stringify(key), JSON.stringify(res[key]), JSON.stringify(_this4.formatResourceLoadPath(lng, ns)));
}
if (formattedKey !== key && res[formattedKey] === undefined) {
res[formattedKey] = _lodash2.default.isFunction(_this4.options.defaultValue) ? _this4.options.defaultValue(lng, ns, key) : _this4.options.defaultValue;
_this4.debuglog('Added a new translation key { %s: %s } to %s', JSON.stringify(formattedKey), JSON.stringify(res[formattedKey]), JSON.stringify(_this4.formatResourceLoadPath(lng, ns)));
}
}
});
});

@@ -443,0 +546,0 @@ }

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

@@ -40,2 +40,3 @@ "homepage": "https://github.com/i18next/i18next-scanner",

"dependencies": {
"esprima": "^2.7.2",
"lodash": "^4.6.1",

@@ -55,4 +56,2 @@ "through2": "^2.0.0",

"eslint": "^2.4.0",
"eslint-config-airbnb": "^6.1.0",
"eslint-plugin-react": "^4.2.1",
"gulp": "^3.9.1",

@@ -59,0 +58,0 @@ "gulp-tap": "^0.1.3",

@@ -32,4 +32,3 @@ # 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)

var customHandler = function(key) {
var defaultValue = '__TRANSLATION__'; // optional default value
parser.set(key, defaultValue);
parser.set(key, '__TRANSLATION__');
};

@@ -157,9 +156,9 @@

parser.parseFuncFromString(content, function(key) {
var defaultValue = key; // use key as the value
parser.set(key, defaultValue);
parser.parseFuncFromString(content, function(key, options) {
options.defaultValue = key; // use key as the value
parser.set(key, options);
});
parser.parseFuncFromString(content, { list: ['_t'] }, function(key) {
parser.set(key); // use defaultValue
parser.parseFuncFromString(content, { list: ['_t'] }, function(key, options) {
parser.set(key, options); // use defaultValue
});

@@ -204,7 +203,12 @@ ```

```js
// Set translation key
// Set a translation key
parser.set(key);
// Set translation key with its defaultValue
// Set a translation key with default value
parser.set(key, defaultValue);
// Set a translation key with default value using options
parser.set(key, {
defaultValue: defaultValue
});
```

@@ -325,2 +329,4 @@

keySeparator: '.',
pluralSeparator: '_',
contextSeparator: '_',
interpolation: {

@@ -419,8 +425,8 @@ pefix: '{{',

Provides the default value with a function:
Provides the default value as a callback function:
```js
{
// @param {string} lng The language currently used.
// @param {ns} ns The namespace currently used.
// @param {key} key The translation key.
// @param {string} ns The namespace currently used.
// @param {string} key The translation key.
// @return {string} Returns a default value for the translation key.

@@ -474,2 +480,14 @@ defaultValue: function(lng, ns, key) {

#### pluralSeparator
Type: `String` Default: `'_'`
The character to split plural from key.
#### contextSeparator
Type: `String` Default: `'_'`
The character to split context from key.
#### interpolation

@@ -476,0 +494,0 @@

/* eslint no-console: 0 */
import _ from 'lodash';
import fs from 'fs';
import esprima from 'esprima';

@@ -38,2 +39,4 @@ const defaults = {

nsSeparator: ':', // char to split namespace from key
pluralSeparator: '_', // char to split plural from key
contextSeparator: '_', // char to split context from key

@@ -47,2 +50,34 @@ // interpolation options

// http://codereview.stackexchange.com/questions/45991/balanced-parentheses
const matchBalancedParentheses = (str = '') => {
const parentheses = '[]{}()';
const stack = [];
let bracePosition;
let start = -1;
str = '' + str; // ensure string
for (let i = 0; i < str.length; ++i) {
if ((start >= 0) && (stack.length === 0)) {
return str.substring(start, i);
}
bracePosition = parentheses.indexOf(str[i]);
if (bracePosition < 0) {
continue;
}
if ((bracePosition % 2) === 0) {
if (start < 0) {
start = i; // remember the start position
}
stack.push(bracePosition + 1); // push next expected brace position
continue;
}
if (stack.pop() !== bracePosition) {
return str.substring(start, i);
}
}
return str.substring(start, i);
};
const transformOptions = (options) => {

@@ -183,19 +218,36 @@ // Attribute

.replace(/\./g, '\\.');
const pattern = '(?:(?:^[\s]*)|[^a-zA-Z0-9_])(?:' + matchPattern + ')\\(("(?:[^"\\\\]|\\\\.)*"|\'(?:[^\'\\\\]|\\\\.)*\')\\s*[\\,\\)]';
const results = content.match(new RegExp(pattern, 'gim')) || [];
results.forEach((result) => {
const r = result.match(new RegExp(pattern));
if (!r) {
return;
}
const pattern = '(?:(?:^[\\s]*)|[^a-zA-Z0-9_])(?:' + matchPattern + ')\\(("(?:[^"\\\\]|\\\\.)*"|\'(?:[^\'\\\\]|\\\\.)*\')\\s*[\\,\\)]';
const re = new RegExp(pattern, 'gim');
let r;
while ((r = re.exec(content))) {
const full = r[0];
const key = _.trim(r[1], '\'"');
const options = {};
const endsWithComma = (full[full.length - 1] === ',');
if (endsWithComma) {
const code = matchBalancedParentheses(content.substr(re.lastIndex));
const syntax = esprima.parse('(' + code + ')');
const props = _.get(syntax, 'body[0].expression.properties') || [];
// http://i18next.com/docs/options/
const supportedOptions = [
'defaultValue',
'count',
'context'
];
props.forEach((prop) => {
if (_.includes(supportedOptions, prop.key.name)) {
options[prop.key.name] = prop.value.value;
}
});
}
if (customHandler) {
customHandler(key);
return;
customHandler(key, options);
continue;
}
this.set(key);
});
this.set(key, options);
}

@@ -219,10 +271,7 @@ return this;

.replace(/\./g, '\\.');
const pattern = '(?:(?:^[\s]*)|[^a-zA-Z0-9_])(?:' + matchPattern + ')=("[^"]*"|\'[^\']*\')';
const results = content.match(new RegExp(pattern, 'gim')) || [];
results.forEach((result) => {
const r = result.match(new RegExp(pattern));
if (!r) {
return;
}
const pattern = '(?:(?:^[\\s]*)|[^a-zA-Z0-9_])(?:' + matchPattern + ')=("[^"]*"|\'[^\']*\')';
const re = new RegExp(pattern, 'gim');
let r;
while ((r = re.exec(content))) {
const attr = _.trim(r[1], '\'"');

@@ -252,3 +301,3 @@ const keys = (attr.indexOf(';') >= 0) ? attr.split(';') : [attr];

});
});
}

@@ -292,4 +341,3 @@ return this;

if (!_.isUndefined(key)) {
const options = this.options;
let ns = options.defaultNs;
let ns = this.options.defaultNs;

@@ -304,4 +352,4 @@ // http://i18next.com/translate/keyBasedFallback/

if (_.isString(options.nsSeparator) && (key.indexOf(options.nsSeparator) > -1)) {
const parts = key.split(options.nsSeparator);
if (_.isString(this.options.nsSeparator) && (key.indexOf(this.options.nsSeparator) > -1)) {
const parts = key.split(this.options.nsSeparator);
ns = parts[0];

@@ -311,4 +359,6 @@ key = parts[1];

const keys = _.isString(options.keySeparator) ? key.split(options.keySeparator) : [key];
const lng = opts.lng ? opts.lng : options.fallbackLng;
const keys = _.isString(this.options.keySeparator)
? key.split(this.options.keySeparator)
: [key];
const lng = opts.lng ? opts.lng : this.options.fallbackLng;
const namespaces = resStore[lng] || {};

@@ -330,7 +380,15 @@

// @param {string} key The translation key
// @param {string} [defaultValue] The key's value
set(key, defaultValue) {
const options = this.options;
// @param {object} [options] The options object
// @param {string} [options.defaultValue] defaultValue to return if translation not found
// @param {number} [options.count] count value used for plurals
// @param {string} [options.context] used for contexts (eg. male)
set(key, options = {}) {
// Backward compatibility
if (_.isString(options)) {
let defaultValue = options;
options = {};
options.defaultValue = defaultValue;
}
let ns = options.defaultNs;
let ns = this.options.defaultNs;
console.assert(_.isString(ns) && !!ns.length, 'ns is not a valid string', ns);

@@ -346,4 +404,4 @@

if (_.isString(options.nsSeparator) && (key.indexOf(options.nsSeparator) > -1)) {
const parts = key.split(options.nsSeparator);
if (_.isString(this.options.nsSeparator) && (key.indexOf(this.options.nsSeparator) > -1)) {
const parts = key.split(this.options.nsSeparator);
ns = parts[0];

@@ -353,45 +411,93 @@ key = parts[1];

const keys = _.isString(options.keySeparator) ? key.split(options.keySeparator) : [key];
options.lngs.forEach((lng) => {
let value = this.resStore[lng] && this.resStore[lng][ns];
let x = 0;
const keys = _.isString(this.options.keySeparator) ? key.split(this.options.keySeparator) : [key];
this.options.lngs.forEach((lng) => {
let res = this.resStore[lng] && this.resStore[lng][ns];
while (keys[x]) {
value = value && value[keys[x]];
x++;
if (!_.isObject(res)) { // skip undefined namespace
console.log('The namespace "' + ns + '" does not exist:', { key, options });
return;
}
if (!_.isUndefined(value)) {
// Found a value associated with the key
let lookupKey = '[' + lng + '][' + ns + '][' + keys.join('][') + ']';
this.debuglog('Found a value %s associated with the key %s in %s.',
JSON.stringify(_.get(this.resStore, lookupKey)),
JSON.stringify(keys.join(options.keySeparator || '')),
JSON.stringify(this.formatResourceLoadPath(lng, ns))
);
} else if (_.isObject(this.resStore[lng][ns])) {
// Adding a new entry
let res = this.resStore[lng][ns];
Object.keys(keys).forEach((index) => {
const elem = keys[index];
if (index >= (keys.length - 1)) {
if (_.isUndefined(defaultValue)) {
res[elem] = _.isFunction(options.defaultValue) ? options.defaultValue(lng, ns, elem) : options.defaultValue;
} else {
res[elem] = defaultValue;
}
} else {
res[elem] = res[elem] || {};
res = res[elem];
Object.keys(keys).forEach((index) => {
const key = keys[index];
if (index < (keys.length - 1)) {
res[key] = res[key] || {};
res = res[key];
return; // continue
}
const hasContext = (options.context !== undefined);
const hasCount = (options.count !== undefined);
// Context & Plural
// http://i18next.com/translate/context/
// http://i18next.com/translate/pluralSimple/
//
// Format:
// "<key>[[{{contextSeparator}}<context>]{{pluralSeparator}}<plural>]"
//
// Example:
// {
// "translation": {
// "friend": "A friend",
// "friend_male": "A boyfriend",
// "friend_female": "A girlfriend",
// "friend_male_plural": "{{count}} boyfriends",
// "friend_female_plural": "{{count}} girlfriends"
// }
// }
let formattedKey = key;
// http://i18next.com/translate/context/
if (hasContext) {
formattedKey = formattedKey + this.options.contextSeparator + options.context;
}
// http://i18next.com/translate/pluralSimple/
if (hasCount) { // TODO: multiple plural forms
formattedKey = formattedKey + this.options.pluralSeparator + 'plural';
}
if (options.defaultValue !== undefined) {
// Use `options.defaultValue` if specified
if (res[key] === undefined) {
res[key] = options.defaultValue;
this.debuglog('Added a new translation key { %s: %s } to %s',
JSON.stringify(key),
JSON.stringify(res[key]),
JSON.stringify(this.formatResourceLoadPath(lng, ns))
);
}
});
let lookupKey = '[' + lng + '][' + ns + '][' + keys.join('][') + ']';
this.debuglog('Adding a new entry {%s:%s} to %s.',
JSON.stringify(keys.join(options.keySeparator || '')),
JSON.stringify(_.get(this.resStore, lookupKey)),
JSON.stringify(this.formatResourceLoadPath(lng, ns))
);
} else { // skip the namespace that is not defined in the i18next options
console.log('The namespace "' + ns + '" does not exist:', { key, defaultValue });
}
if ((formattedKey !== key) && (res[formattedKey] === undefined)) {
res[formattedKey] = options.defaultValue;
this.debuglog('Added a new translation key { %s: %s } to %s',
JSON.stringify(formattedKey),
JSON.stringify(res[formattedKey]),
JSON.stringify(this.formatResourceLoadPath(lng, ns))
);
}
} else {
// Fallback to `this.options.defaultValue`
if (res[key] === undefined) {
res[key] = _.isFunction(this.options.defaultValue)
? this.options.defaultValue(lng, ns, key)
: this.options.defaultValue;
this.debuglog('Added a new translation key { %s: %s } to %s',
JSON.stringify(key),
JSON.stringify(res[key]),
JSON.stringify(this.formatResourceLoadPath(lng, ns))
);
}
if ((formattedKey !== key) && (res[formattedKey] === undefined)) {
res[formattedKey] = _.isFunction(this.options.defaultValue)
? this.options.defaultValue(lng, ns, key)
: this.options.defaultValue;
this.debuglog('Added a new translation key { %s: %s } to %s',
JSON.stringify(formattedKey),
JSON.stringify(res[formattedKey]),
JSON.stringify(this.formatResourceLoadPath(lng, ns))
);
}
}
});
});

@@ -398,0 +504,0 @@ }

@@ -10,5 +10,8 @@ var i18n = require('i18next');

_t('This value does not exist.'),
_t('YouTube has more than __count__ billion users.', {count: 1})
_t('YouTube has more than {{count}} billion users.', {count: 1}),
_t('You have {{count}} messages.', {
count: 10
});
].join('\n');
console.log(msg);

@@ -6,2 +6,3 @@ import _ from 'lodash';

import tap from 'gulp-tap';
import VirtualFile from 'vinyl';
import { test } from 'tap';

@@ -24,3 +25,3 @@ import scanner from '../src';

loadPath: '',
savePath: 'i18n/__lng__/__ns__.json'
savePath: 'i18n/{{lng}}/{{ns}}.json'
},

@@ -30,7 +31,45 @@ nsSeparator: false, // namespace separator

interpolation: {
prefix: '__',
suffix: '__'
prefix: '{{',
suffix: '}}'
}
};
test('Parse both .html and .js files', (t) => {
const options = _.merge({}, defaults, {});
const list = [
'test/fixtures/app.html',
'test/fixtures/modules/**/*.js'
];
gulp.src(list)
.pipe(scanner(options))
.pipe(tap(function(file) {
const contents = file.contents.toString();
const list = [
'i18n/de/resource.json',
'i18n/en/resource.json',
];
if (_.includes(list, file.path)) {
const found = JSON.parse(contents);
const wanted = {
"Loading...": "__STRING_NOT_TRANSLATED__",
"This value does not exist.": "__STRING_NOT_TRANSLATED__",
"You have {{count}} messages.": "__STRING_NOT_TRANSLATED__",
"You have {{count}} messages._plural": "__STRING_NOT_TRANSLATED__",
"YouTube has more than {{count}} billion users.": "__STRING_NOT_TRANSLATED__",
"YouTube has more than {{count}} billion users._plural": "__STRING_NOT_TRANSLATED__",
'key4': '__STRING_NOT_TRANSLATED__',
'key3': '__STRING_NOT_TRANSLATED__',
'key2': '__STRING_NOT_TRANSLATED__',
'key1': '__STRING_NOT_TRANSLATED__'
};
t.same(found, wanted);
}
}))
.on('end', function() {
t.end();
});
});
test('[Key Based Fallback] defaultValue as string', function(t) {

@@ -57,3 +96,6 @@ const options = _.merge({}, defaults, {

"This value does not exist.": "__STRING_NOT_TRANSLATED__",
"YouTube has more than __count__ billion users.": "__STRING_NOT_TRANSLATED__"
"YouTube has more than {{count}} billion users.": "__STRING_NOT_TRANSLATED__",
"YouTube has more than {{count}} billion users._plural": "__STRING_NOT_TRANSLATED__",
"You have {{count}} messages.": "__STRING_NOT_TRANSLATED__",
"You have {{count}} messages._plural": "__STRING_NOT_TRANSLATED__"
};

@@ -91,3 +133,6 @@ t.same(found, wanted);

"This value does not exist.": "This value does not exist.",
"YouTube has more than __count__ billion users.": "YouTube has more than __count__ billion users."
"YouTube has more than {{count}} billion users.": "YouTube has more than {{count}} billion users.",
"YouTube has more than {{count}} billion users._plural": "YouTube has more than {{count}} billion users.",
"You have {{count}} messages.": "You have {{count}} messages.",
"You have {{count}} messages._plural": "You have {{count}} messages."
};

@@ -102,3 +147,6 @@ t.same(found, wanted);

"This value does not exist.": "__STRING_NOT_TRANSLATED__",
"YouTube has more than __count__ billion users.": "__STRING_NOT_TRANSLATED__"
"YouTube has more than {{count}} billion users.": "__STRING_NOT_TRANSLATED__",
"YouTube has more than {{count}} billion users._plural": "__STRING_NOT_TRANSLATED__",
"You have {{count}} messages.": "__STRING_NOT_TRANSLATED__",
"You have {{count}} messages._plural": "__STRING_NOT_TRANSLATED__"
};

@@ -113,3 +161,3 @@ t.same(found, wanted);

test('should get empty result', function(t) {
test('Empty result', function(t) {
const options = _.merge({}, defaults, {

@@ -140,1 +188,64 @@ func: {

});
test('Custom transform', function(t) {
const options = _.merge({}, defaults, {
});
const expectedKey = 'CUSTOM TRANSFORM';
const customTransform = function(file, enc, done) {
this.parser.set(expectedKey);
done();
};
gulp.src('test/fixtures/modules/**/*.js')
.pipe(scanner(options, customTransform))
.pipe(tap(function(file) {
const contents = file.contents.toString();
const list = [
'i18n/de/resource.json',
'i18n/en/resource.json',
];
if (_.includes(list, file.path)) {
const found = JSON.parse(contents);
const wanted = {
"Loading...": "__STRING_NOT_TRANSLATED__",
"This value does not exist.": "__STRING_NOT_TRANSLATED__",
"YouTube has more than {{count}} billion users.": "__STRING_NOT_TRANSLATED__",
"YouTube has more than {{count}} billion users._plural": "__STRING_NOT_TRANSLATED__",
"You have {{count}} messages.": "__STRING_NOT_TRANSLATED__",
"You have {{count}} messages._plural": "__STRING_NOT_TRANSLATED__",
"CUSTOM TRANSFORM": "__STRING_NOT_TRANSLATED__"
};
t.same(found, wanted);
}
}))
.on('end', function() {
t.end();
});
});
test('Custom flush', function(t) {
const options = _.merge({}, defaults, {
});
const expectedContents = 'CUSTOM FLUSH';
const customFlush = function(done) {
this.push(new VirtualFile({
path: 'virtual-path',
contents: new Buffer(expectedContents)
}));
done();
};
gulp.src('test/fixtures/modules/**/*.js')
.pipe(scanner(options, null, customFlush))
.pipe(tap(function(file) {
const contents = file.contents.toString();
t.same(contents, expectedContents);
}))
.on('end', function() {
t.end();
});
});

@@ -73,5 +73,7 @@ import fs from 'fs';

translation: {
"key4": "__TRANSLATION__",
"key3": "__TRANSLATION__",
"key2": "__TRANSLATION__",
"key1": "__TRANSLATION__"
}
}
}

@@ -85,3 +87,5 @@ });

"key1": "__TRANSLATION__",
"key2": "__TRANSLATION__"
"key2": "__TRANSLATION__",
"key3": "__TRANSLATION__",
"key4": "__TRANSLATION__"
}

@@ -118,3 +122,6 @@ }

"This value does not exist.": "This value does not exist.",
"YouTube has more than __count__ billion users.": "YouTube has more than __count__ billion users."
"YouTube has more than {{count}} billion users.": "YouTube has more than {{count}} billion users.",
"YouTube has more than {{count}} billion users._plural": "YouTube has more than {{count}} billion users.",
"You have {{count}} messages.": "You have {{count}} messages.",
"You have {{count}} messages._plural": "You have {{count}} messages."
}

@@ -209,1 +216,53 @@ }

});
test('Plural', (t) => {
const parser = new Parser();
const content = fs.readFileSync(path.resolve(__dirname, 'fixtures/plural.js'), 'utf-8');
parser.parseFuncFromString(content);
t.same(parser.get(), {
en: {
translation: {
"key": "",
"key_plural": "",
"keyWithCount": "",
"keyWithCount_plural": ""
}
}
});
t.end();
});
test('Context', (t) => {
const parser = new Parser();
const content = fs.readFileSync(path.resolve(__dirname, 'fixtures/context.js'), 'utf-8');
parser.parseFuncFromString(content);
t.same(parser.get(), {
en: {
translation: {
"friend": "",
"friend_male": "",
"friend_female": ""
}
}
});
t.end();
});
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": ""
}
}
});
t.end();
});

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

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

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc