i18next-scanner
Advanced tools
Comparing version 2.9.2 to 2.10.0
#!/usr/bin/env node | ||
var fs = require('fs'); | ||
var path = require('path'); | ||
var program = require('commander'); | ||
var ensureArray = require('ensure-array'); | ||
var sort = require('gulp-sort'); | ||
var vfs = require('vinyl-fs'); | ||
var scanner = require('../lib'); | ||
var pkg = require('../package.json'); | ||
const fs = require('fs'); | ||
const path = require('path'); | ||
const program = require('commander'); | ||
const ensureArray = require('ensure-array'); | ||
const sort = require('gulp-sort'); | ||
const vfs = require('vinyl-fs'); | ||
const scanner = require('../lib'); | ||
const pkg = require('../package.json'); | ||
@@ -16,3 +16,3 @@ program | ||
.option('--config <config>', 'Path to the config file (default: i18next-scanner.config.js)', 'i18next-scanner.config.js') | ||
.option('--output <path>', 'Path to the output directory (default: .)', '.'); | ||
.option('--output <path>', 'Path to the output directory (default: .)'); | ||
@@ -31,4 +31,18 @@ program.on('--help', function() { | ||
var src = ensureArray(program.args) | ||
.map(function(s) { | ||
if (!program.config) { | ||
program.help(); | ||
return; | ||
} | ||
let config = {}; | ||
try { | ||
config = require(path.resolve(program.config)); | ||
} catch (err) { | ||
console.error('i18next-scanner:', err); | ||
return; | ||
} | ||
{ // Input | ||
config.input = (program.args.length > 0) ? program.args : ensureArray(config.input); | ||
config.input = config.input.map(function(s) { | ||
s = s.trim(); | ||
@@ -44,18 +58,19 @@ | ||
if (!program.config || !program.output || src.length === 0) { | ||
program.help(); | ||
return; | ||
if (config.input.length === 0) { | ||
program.help(); | ||
return; | ||
} | ||
} | ||
var config = {}; | ||
try { | ||
config = require(path.resolve(program.config)); | ||
} catch (err) { | ||
console.error('i18next-scanner:', err); | ||
return; | ||
{ // Output | ||
config.output = program.output || config.output; | ||
if (!config.output) { | ||
config.output = '.'; | ||
} | ||
} | ||
vfs.src(src) | ||
vfs.src(config.input) | ||
.pipe(sort()) // Sort files in stream by path | ||
.pipe(scanner(config.options, config.transform, config.flush)) | ||
.pipe(vfs.dest(program.output)) | ||
.pipe(vfs.dest(config.output)) |
@@ -7,16 +7,7 @@ 'use strict'; | ||
var _acorn = require('acorn'); | ||
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; // Originally from: https://github.com/sderosiaux/acorn-jsx-walk | ||
var _acornWalk = require('acorn-walk'); | ||
var _acornJsx = require('acorn-jsx'); | ||
var _acornJsx2 = _interopRequireDefault(_acornJsx); | ||
var _acornStage = require('acorn-stage3'); | ||
var _acornStage2 = _interopRequireDefault(_acornStage); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
// | ||
@@ -27,4 +18,2 @@ // Extends acorn walk with JSX elements | ||
// See: https://github.com/RReverser/acorn-jsx/issues/23#issuecomment-403753801 | ||
// Originally from: https://github.com/sderosiaux/acorn-jsx-walk | ||
Object.assign(_acornWalk.base, { | ||
@@ -66,8 +55,4 @@ FieldDefinition: function FieldDefinition(node, state, callback) { | ||
exports.default = function (source, options) { | ||
var ast = _acorn.Parser.extend(_acornStage2.default, (0, _acornJsx2.default)()).parse(source, { | ||
sourceType: 'module', | ||
ecmaVersion: 10 | ||
}); | ||
(0, _acornWalk.simple)(ast, options || {}); | ||
exports.default = function (ast, options) { | ||
(0, _acornWalk.simple)(ast, _extends({}, options)); | ||
}; |
@@ -47,3 +47,7 @@ 'use strict'; | ||
// Parse attribute (e.g. data-i18n="key") | ||
parser.parseAttrFromString(content); | ||
parser.parseAttrFromString(content, { | ||
transformOptions: { | ||
filepath: file.path | ||
} | ||
}); | ||
} | ||
@@ -53,3 +57,7 @@ | ||
// Parse translation function (e.g. i18next.t('key')) | ||
parser.parseFuncFromString(content); | ||
parser.parseFuncFromString(content, { | ||
transformOptions: { | ||
filepath: file.path | ||
} | ||
}); | ||
} | ||
@@ -59,3 +67,7 @@ | ||
// Look for Trans components in JSX | ||
parser.parseTransFromString(content); | ||
parser.parseTransFromString(content, { | ||
transformOptions: { | ||
filepath: file.path | ||
} | ||
}); | ||
} | ||
@@ -62,0 +74,0 @@ |
@@ -17,2 +17,14 @@ 'use strict'; | ||
var _acorn = require('acorn'); | ||
var acorn = _interopRequireWildcard(_acorn); | ||
var _acornJsx = require('acorn-jsx'); | ||
var _acornJsx2 = _interopRequireDefault(_acornJsx); | ||
var _acornStage = require('acorn-stage3'); | ||
var _acornStage2 = _interopRequireDefault(_acornStage); | ||
var _chalk = require('chalk'); | ||
@@ -68,2 +80,4 @@ | ||
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 }; } | ||
@@ -95,3 +109,8 @@ | ||
extensions: ['.js', '.jsx'], | ||
fallbackKey: false | ||
fallbackKey: false, | ||
acorn: { | ||
ecmaVersion: 10, // defaults to 10 | ||
sourceType: 'module' // defaults to 'module' | ||
// Check out https://github.com/acornjs/acorn/tree/master/acorn#interface for additional options | ||
} | ||
}, | ||
@@ -182,3 +201,3 @@ | ||
var transformOptions = function transformOptions(options) { | ||
var normalizeOptions = function normalizeOptions(options) { | ||
// Attribute | ||
@@ -217,2 +236,5 @@ if (_lodash2.default.isUndefined(_lodash2.default.get(options, 'attr.list'))) { | ||
} | ||
if (_lodash2.default.isUndefined(_lodash2.default.get(options, 'trans.acorn'))) { | ||
_lodash2.default.set(options, 'trans.acorn', defaults.trans.acorn); | ||
} | ||
} | ||
@@ -309,3 +331,3 @@ | ||
this.options = transformOptions(_extends({}, this.options, options)); | ||
this.options = normalizeOptions(_extends({}, this.options, options)); | ||
@@ -321,3 +343,3 @@ var lngs = this.options.lngs; | ||
if (_this.pluralSuffixes[lng].length === 0) { | ||
_this.log('i18next-scanner: No plural rule found for: ' + lng); | ||
_this.log('No plural rule found for: ' + lng); | ||
} | ||
@@ -336,4 +358,4 @@ | ||
} catch (err) { | ||
_this.log('i18next-scanner: Unable to load resource file ' + _chalk2.default.yellow(JSON.stringify(resPath)) + ': lng=' + lng + ', ns=' + ns); | ||
_this.log(err); | ||
_this.error('Unable to load resource file ' + _chalk2.default.yellow(JSON.stringify(resPath)) + ': lng=' + lng + ', ns=' + ns); | ||
_this.error(err); | ||
} | ||
@@ -343,3 +365,3 @@ }); | ||
this.log('i18next-scanner: options=' + JSON.stringify(this.options, null, 2)); | ||
this.log('options=' + JSON.stringify(this.options, null, 2)); | ||
} | ||
@@ -363,6 +385,15 @@ | ||
console.log.apply(this, args); | ||
console.log.apply(this, [_chalk2.default.cyan('i18next-scanner:')].concat(args)); | ||
} | ||
} | ||
}, { | ||
key: 'error', | ||
value: function error() { | ||
for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { | ||
args[_key2] = arguments[_key2]; | ||
} | ||
console.error.apply(this, [_chalk2.default.red('i18next-scanner:')].concat(args)); | ||
} | ||
}, { | ||
key: 'formatResourceLoadPath', | ||
@@ -520,4 +551,4 @@ value: function formatResourceLoadPath(lng, ns) { | ||
} catch (err) { | ||
_this2.log('i18next-scanner: Unable to parse code "' + code + '"'); | ||
_this2.log(err); | ||
_this2.error('Unable to parse code "' + code + '"'); | ||
_this2.error(err); | ||
} | ||
@@ -559,5 +590,14 @@ } | ||
var component = opts.component || this.options.trans.component; | ||
var i18nKey = opts.i18nKey || this.options.trans.i18nKey; | ||
var defaultsKey = opts.defaultsKey || this.options.trans.defaultsKey; | ||
var _opts2 = _extends({}, opts), | ||
_opts2$transformOptio = _opts2.transformOptions, | ||
transformOptions = _opts2$transformOptio === undefined ? {} : _opts2$transformOptio, | ||
_opts2$component = _opts2.component, | ||
component = _opts2$component === undefined ? this.options.trans.component : _opts2$component, | ||
_opts2$i18nKey = _opts2.i18nKey, | ||
i18nKey = _opts2$i18nKey === undefined ? this.options.trans.i18nKey : _opts2$i18nKey, | ||
_opts2$defaultsKey = _opts2.defaultsKey, | ||
defaultsKey = _opts2$defaultsKey === undefined ? this.options.trans.defaultsKey : _opts2$defaultsKey, | ||
fallbackKey = _opts2.fallbackKey, | ||
_opts2$acorn = _opts2.acorn, | ||
acornOptions = _opts2$acorn === undefined ? this.options.trans.acorn : _opts2$acorn; | ||
@@ -615,3 +655,3 @@ var parseJSXElement = function parseJSXElement(node) { | ||
if (typeof defaultsString !== 'string') { | ||
_this3.log('i18next-scanner: defaults value must be a static string, saw ' + _chalk2.default.yellow(defaultsString)); | ||
_this3.log('defaults value must be a static string, saw ' + _chalk2.default.yellow(defaultsString)); | ||
} | ||
@@ -621,3 +661,3 @@ | ||
defaultValue: defaultsString || (0, _nodesToString2.default)(node.children), | ||
fallbackKey: opts.fallbackKey || _this3.options.trans.fallbackKey | ||
fallbackKey: fallbackKey || _this3.options.trans.fallbackKey | ||
}; | ||
@@ -633,3 +673,3 @@ | ||
if (typeof options.context !== 'string') { | ||
_this3.log('i18next-scanner: The context attribute must be a string, saw ' + _chalk2.default.yellow(attr.context)); | ||
_this3.log('The context attribute must be a string, saw ' + _chalk2.default.yellow(attr.context)); | ||
} | ||
@@ -647,7 +687,16 @@ } | ||
try { | ||
(0, _acornJsxWalk2.default)(content, { JSXElement: parseJSXElement }); | ||
var ast = acorn.Parser.extend(_acornStage2.default, (0, _acornJsx2.default)()).parse(content, _extends({}, defaults.trans.acorn, acornOptions)); | ||
(0, _acornJsxWalk2.default)(ast, { | ||
JSXElement: parseJSXElement | ||
}); | ||
} catch (err) { | ||
this.log('i18next-scanner: Unable to parse ' + component + ' component with the content'); | ||
this.log(err); | ||
this.log(content); | ||
if (transformOptions.filepath) { | ||
this.error('Unable to parse ' + _chalk2.default.blue(component) + ' component from ' + _chalk2.default.yellow(JSON.stringify(transformOptions.filepath))); | ||
console.error(' ' + err); | ||
} else { | ||
this.error('Unable to parse ' + _chalk2.default.blue(component) + ' component:'); | ||
console.error(content); | ||
console.error(' ' + err); | ||
} | ||
} | ||
@@ -902,3 +951,3 @@ | ||
// Skip undefined namespace | ||
_this5.log('i18next-scanner: The namespace ' + _chalk2.default.yellow(JSON.stringify(ns)) + ' does not exist:', { key: key, options: options }); | ||
_this5.log('The namespace ' + _chalk2.default.yellow(JSON.stringify(ns)) + ' does not exist:', { key: key, options: options }); | ||
return; | ||
@@ -992,3 +1041,3 @@ } | ||
} | ||
_this5.log('i18next-scanner: Added a new translation key { ' + _chalk2.default.yellow(JSON.stringify(resKey)) + ': ' + _chalk2.default.yellow(JSON.stringify(resLoad[resKey])) + ' } to ' + _chalk2.default.yellow(JSON.stringify(_this5.formatResourceLoadPath(lng, ns)))); | ||
_this5.log('Added a new translation key { ' + _chalk2.default.yellow(JSON.stringify(resKey)) + ': ' + _chalk2.default.yellow(JSON.stringify(resLoad[resKey])) + ' } to ' + _chalk2.default.yellow(JSON.stringify(_this5.formatResourceLoadPath(lng, ns)))); | ||
} else if (options.defaultValue && (!options.defaultValue_plural || !resKey.endsWith(pluralSeparator + 'plural'))) { | ||
@@ -1000,3 +1049,3 @@ if (!resLoad[resKey]) { | ||
// A default value has provided but it's different with the expected default | ||
_this5.log('i18next-scanner: The translation key ' + _chalk2.default.yellow(JSON.stringify(resKey)) + ' has a different default value, you may need to check the translation key of default language (' + defaultLng + ')'); | ||
_this5.log('The translation key ' + _chalk2.default.yellow(JSON.stringify(resKey)) + ' has a different default value, you may need to check the translation key of default language (' + defaultLng + ')'); | ||
} | ||
@@ -1009,3 +1058,3 @@ } else if (options.defaultValue_plural && resKey.endsWith(pluralSeparator + 'plural')) { | ||
// A default value has provided but it's different with the expected default | ||
_this5.log('i18next-scanner: The translation key ' + _chalk2.default.yellow(JSON.stringify(resKey)) + ' has a different default value, you may need to check the translation key of default language (' + defaultLng + ')'); | ||
_this5.log('The translation key ' + _chalk2.default.yellow(JSON.stringify(resKey)) + ' has a different default value, you may need to check the translation key of default language (' + defaultLng + ')'); | ||
} | ||
@@ -1012,0 +1061,0 @@ } |
{ | ||
"name": "i18next-scanner", | ||
"version": "2.9.2", | ||
"version": "2.10.0", | ||
"description": "Scan your code, extract translation keys/values, and merge them into i18n resource files.", | ||
@@ -52,5 +52,5 @@ "homepage": "https://github.com/i18next/i18next-scanner", | ||
"dependencies": { | ||
"acorn": "^6.0.4", | ||
"acorn": "^6.1.1", | ||
"acorn-jsx": "^5.0.1", | ||
"acorn-stage3": "^1.0.0", | ||
"acorn-stage3": "^2.0.0", | ||
"acorn-walk": "^6.1.1", | ||
@@ -65,3 +65,3 @@ "chalk": "^2.4.1", | ||
"gulp-sort": "^2.0.0", | ||
"i18next": "^11.10.1", | ||
"i18next": "*", | ||
"lodash": "^4.0.0", | ||
@@ -68,0 +68,0 @@ "parse5": "^5.0.0", |
@@ -100,6 +100,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) | ||
```js | ||
var fs = require('fs'); | ||
var chalk = require('chalk'); | ||
const fs = require('fs'); | ||
const chalk = require('chalk'); | ||
module.exports = { | ||
input: [ | ||
'app/**/*.{js,jsx}', | ||
// Use ! to filter out files or directories | ||
'!app/**/*.spec.{js,jsx}', | ||
'!app/i18n/**', | ||
'!**/node_modules/**', | ||
], | ||
output: './', | ||
options: { | ||
@@ -117,4 +125,8 @@ debug: true, | ||
fallbackKey: function(ns, value) { | ||
// Returns a hash value as the fallback key | ||
return sha1(value); | ||
return value; | ||
}, | ||
acorn: { | ||
ecmaVersion: 10, // defaults to 10 | ||
sourceType: 'module', // defaults to 'module' | ||
// Check out https://github.com/acornjs/acorn/tree/master/acorn#interface for additional options | ||
} | ||
@@ -352,3 +364,3 @@ }, | ||
parser.parseAttrFromString(content, function(key) { | ||
var defaultValue = key; // use key as the value | ||
const defaultValue = key; // use key as the value | ||
parser.set(key, defaultValue); | ||
@@ -396,3 +408,3 @@ }); | ||
```js | ||
var scanner = require('i18next-scanner'); | ||
const scanner = require('i18next-scanner'); | ||
scanner.createStream(options, customTransform /* optional */, customFlush /* optional */); | ||
@@ -405,7 +417,7 @@ ``` | ||
```js | ||
var scanner = require('i18next-scanner'); | ||
var vfs = require('vinyl-fs'); | ||
var customTransform = function _transform(file, enc, done) { | ||
var parser = this.parser; | ||
var content = fs.readFileSync(file.path, enc); | ||
const scanner = require('i18next-scanner'); | ||
const vfs = require('vinyl-fs'); | ||
const customTransform = function _transform(file, enc, done) { | ||
const parser = this.parser; | ||
const content = fs.readFileSync(file.path, enc); | ||
@@ -424,8 +436,8 @@ // add your code | ||
```js | ||
var customTransform = function _transform(file, enc, done) { | ||
var parser = this.parser; | ||
var content = fs.readFileSync(file.path, enc); | ||
const customTransform = function _transform(file, enc, done) { | ||
const parser = this.parser; | ||
const content = fs.readFileSync(file.path, enc); | ||
parser.parseFuncFromString(content, { list: ['i18n.t'] }, function(key) { | ||
var defaultValue = '__L10N__'; | ||
const defaultValue = '__L10N__'; | ||
parser.set(key, defaultValue); | ||
@@ -441,10 +453,10 @@ }); | ||
```js | ||
var hash = require('sha1'); | ||
var customTransform = function _transform(file, enc, done) { | ||
var parser = this.parser; | ||
var content = fs.readFileSync(file.path, enc); | ||
const hash = require('sha1'); | ||
const customTransform = function _transform(file, enc, done) { | ||
const parser = this.parser; | ||
const content = fs.readFileSync(file.path, enc); | ||
parser.parseFuncFromString(content, { list: ['i18n._'] }, function(key) { | ||
var value = key; | ||
var defaultKey = hash(value); | ||
const value = key; | ||
const defaultKey = hash(value); | ||
parser.set(defaultKey, value); | ||
@@ -461,13 +473,13 @@ }); | ||
```js | ||
var scanner = require('i18next-scanner'); | ||
var vfs = require('vinyl-fs'); | ||
var customFlush = function _flush(done) { | ||
var parser = this.parser; | ||
var resStore = parser.getResourceStore(); | ||
const scanner = require('i18next-scanner'); | ||
const vfs = require('vinyl-fs'); | ||
const customFlush = function _flush(done) { | ||
const parser = this.parser; | ||
const resStore = parser.getResourceStore(); | ||
// loop over the resStore | ||
Object.keys(resStore).forEach(function(lng) { | ||
var namespaces = resStore[lng]; | ||
const namespaces = resStore[lng]; | ||
Object.keys(namespaces).forEach(function(ns) { | ||
var obj = namespaces[ns]; | ||
const obj = namespaces[ns]; | ||
// add your code | ||
@@ -474,0 +486,0 @@ }); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Wildcard dependency
QualityPackage has a dependency with a floating version range. This can cause issues if the dependency publishes a new major version.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
795
88631
12
1305
1
+ Added@babel/runtime@7.25.7(transitive)
+ Addedacorn-bigint@0.4.0(transitive)
+ Addedacorn-class-fields@0.3.7(transitive)
+ Addedacorn-logical-assignment@0.1.4(transitive)
+ Addedacorn-numeric-separator@0.3.6(transitive)
+ Addedacorn-private-class-elements@0.2.7(transitive)
+ Addedacorn-private-methods@0.3.3(transitive)
+ Addedacorn-stage3@2.1.0(transitive)
+ Addedacorn-static-class-features@0.2.4(transitive)
+ Addedi18next@23.15.1(transitive)
+ Addedregenerator-runtime@0.14.1(transitive)
- Removedacorn-bigint@0.3.1(transitive)
- Removedacorn-class-fields@0.2.1(transitive)
- Removedacorn-private-methods@0.2.3(transitive)
- Removedacorn-stage3@1.0.0(transitive)
- Removedacorn-static-class-features@0.1.1(transitive)
- Removedi18next@11.10.2(transitive)
Updatedacorn@^6.1.1
Updatedacorn-stage3@^2.0.0
Updatedi18next@*