babel-gettext-extractor
Advanced tools
Comparing version 2.0.0 to 3.0.0
67
index.js
@@ -1,3 +0,2 @@ | ||
'use strict'; | ||
var utils = require('./utils'); | ||
var gettextParser = require('gettext-parser'); | ||
@@ -14,3 +13,3 @@ var fs = require('fs'); | ||
npgettext: ['msgctxt', 'msgid', 'msgid_plural', 'count'], | ||
dnpgettext: ['domain', 'msgctxt', 'msgid', 'msgid_plural', 'count'] | ||
dnpgettext: ['domain', 'msgctxt', 'msgid', 'msgid_plural', 'count'], | ||
}; | ||
@@ -22,5 +21,6 @@ | ||
'content-type': 'text/plain; charset=UTF-8', | ||
'plural-forms': 'nplurals = 2; plural = (n !== 1);' | ||
'plural-forms': 'nplurals = 2; plural = (n !== 1);', | ||
}; | ||
function getTranslatorComment(node) { | ||
@@ -37,3 +37,4 @@ var comments = []; | ||
exports.default = function() { | ||
module.exports = function() { | ||
var currentFileName; | ||
@@ -43,5 +44,5 @@ var data; | ||
return {visitor: { | ||
return { visitor: { | ||
VariableDeclaration: function(nodePath, plugin) { | ||
VariableDeclaration(nodePath) { | ||
var translatorComment = getTranslatorComment(nodePath.node); | ||
@@ -60,3 +61,3 @@ if (!translatorComment) { | ||
CallExpression: function(nodePath, plugin) { | ||
CallExpression(nodePath, plugin) { | ||
var functionNames = plugin.opts && plugin.opts.functionNames || DEFAULT_FUNCTION_NAMES; | ||
@@ -75,3 +76,3 @@ var fileName = plugin.opts && plugin.opts.fileName || DEFAULT_FILE_NAME; | ||
headers: headers, | ||
translations: {context: {}} | ||
translations: { context: {} }, | ||
}; | ||
@@ -88,6 +89,6 @@ | ||
let callee = nodePath.node.callee; | ||
const callee = nodePath.node.callee; | ||
if (functionNames.hasOwnProperty(callee.name) | ||
|| callee.property && | ||
if (functionNames.hasOwnProperty(callee.name) || | ||
callee.property && | ||
functionNames.hasOwnProperty(callee.property.name)) { | ||
@@ -98,3 +99,3 @@ var functionName = functionNames[callee.name] | ||
var args = nodePath.node.arguments; | ||
var args = nodePath.get('arguments'); | ||
for (var i = 0, l = args.length; i < l; i++) { | ||
@@ -104,5 +105,8 @@ var name = functionName[i]; | ||
if (name && name !== 'count' && name !== 'domain') { | ||
var arg = args[i]; | ||
var arg = args[i].evaluate(); | ||
var value = arg.value; | ||
if (value) { | ||
if (arg.confident && value) { | ||
if (plugin.opts.stripTemplateLiteralIndent) { | ||
value = utils.stripIndent(value); | ||
} | ||
translate[name] = value; | ||
@@ -121,3 +125,3 @@ } | ||
var fn = this.file.opts.filename; | ||
if (base && fn && fn.substr(0, base.length) == base) { | ||
if (base && fn && fn.substr(0, base.length) === base) { | ||
fn = fn.substr(base.length); | ||
@@ -127,3 +131,3 @@ } | ||
translate.comments = { | ||
reference: fn + ':' + nodePath.node.loc.start.line | ||
reference: fn + ':' + nodePath.node.loc.start.line, | ||
}; | ||
@@ -133,3 +137,3 @@ | ||
if (!translatorComment) { | ||
translatorComment = getTranslatorComment(nodePath.parent); | ||
translatorComment = getTranslatorComment(nodePath.parentPath); | ||
if (!translatorComment) { | ||
@@ -152,9 +156,26 @@ translatorComment = relocatedComments[ | ||
context[translate.msgid] = translate; | ||
if (typeof context[translate.msgid] !== 'undefined') { | ||
// If we already have this translation append the new file reference | ||
// so we know about all the places it is used. | ||
var newRef = translate.comments.reference; | ||
var currentRef = context[translate.msgid].comments.reference; | ||
var refs = currentRef.split('\n'); | ||
if (refs.indexOf(newRef) === -1) { | ||
refs.push(newRef); | ||
context[translate.msgid].comments.reference = refs.sort().join('\n'); | ||
} | ||
} else if (typeof translate.msgid !== 'undefined') { | ||
// Do not add translation if msgid is undefined. | ||
context[translate.msgid] = translate; | ||
} | ||
var output = gettextParser.po.compile(data); | ||
fs.writeFileSync(fileName, output); | ||
// Sort by file reference to make output idempotent for the same input. | ||
if (data.translations && data.translations.context) { | ||
data.translations.context = utils.sortObjectKeysByRef(data.translations.context); | ||
} | ||
fs.writeFileSync(fileName, gettextParser.po.compile(data)); | ||
} | ||
} | ||
}}; | ||
}, | ||
} }; | ||
}; |
{ | ||
"name": "babel-gettext-extractor", | ||
"version": "2.0.0", | ||
"version": "3.0.0", | ||
"description": " Extract gettext string with babel", | ||
"main": "index.js", | ||
"scripts": { | ||
"test": "./node_modules/.bin/mocha" | ||
"test": "mocha", | ||
"lint": "eslint *.js **/*.js", | ||
"test-ci": "npm run clean && npm run test && npm run lint", | ||
"clean": "rimraf 'test/*.po'" | ||
}, | ||
@@ -27,8 +30,15 @@ "repository": { | ||
"babel-core": "^6.0.0", | ||
"gettext-parser": "^1.1.1" | ||
"gettext-parser": "^1.1.2" | ||
}, | ||
"devDependencies": { | ||
"babel": "^6.0.0", | ||
"mocha": "^2.3.4" | ||
"babel-preset-react": "^6.5.0", | ||
"eslint": "^3.19.0", | ||
"eslint-config-airbnb": "14.1.0", | ||
"eslint-plugin-import": "2.2.0", | ||
"eslint-plugin-jsx-a11y": "4.0.0", | ||
"eslint-plugin-react": "6.10.0", | ||
"mocha": "^2.3.4", | ||
"rimraf": "^2.6.1" | ||
} | ||
} |
@@ -0,1 +1,3 @@ | ||
[![Build Status](https://travis-ci.org/mozilla/babel-gettext-extractor.svg?branch=master)](https://travis-ci.org/mozilla/babel-gettext-extractor) | ||
# babel-gettext-extractor | ||
@@ -7,2 +9,10 @@ | ||
Supports babel 6. | ||
Install | ||
======== | ||
`yarn add babel-gettext-extractor` | ||
or | ||
`npm install --save babel-gettext-extractor` | ||
Node use | ||
@@ -27,10 +37,11 @@ ======== | ||
You can pass otions as extra in babel options : | ||
```js | ||
plugins: [ | ||
['babel-gettext-extractor', { | ||
headers: <Object>, | ||
functionNames: <Object>, | ||
fileName: <String>, | ||
baseDirectory: <String> | ||
"plugins": [ | ||
[ "babel-gettext-extractor", { | ||
"headers": <Object>, | ||
"functionNames": <Object>, | ||
"fileName": <String>, | ||
"baseDirectory": <String>, | ||
"stripTemplateLiteralIndent": <Boolean> | ||
}] | ||
@@ -72,2 +83,9 @@ ] | ||
### stripTemplateLiteralIndent ### | ||
If true this will strip leading indents from multiline strings. Note: this | ||
requires gettext function implementations to do the same leading indent removal. | ||
Useful if you want to use Template literals for multiline strings to be passed | ||
into to gettext functions. | ||
License | ||
@@ -74,0 +92,0 @@ ======= |
151
test/test.js
@@ -1,3 +0,1 @@ | ||
'use strict'; | ||
var assert = require('assert'); | ||
@@ -7,10 +5,8 @@ var babel = require('babel-core'); | ||
var fs = require('fs'); | ||
var plugin = require('../index.js').default; | ||
var plugin = require('../index.js'); | ||
describe('babel-gettext-plugin', function() { | ||
describe('babel-gettext-extractor', function() { | ||
describe('#extract()', function() { | ||
it('Should return a result', function() { | ||
it('Should return a result for simple code example', function() { | ||
var result = babel.transform('let t = _t("code");_t("hello");', { | ||
@@ -20,7 +16,7 @@ plugins: [ | ||
functionNames: { | ||
_t: ['msgid'] | ||
_t: ['msgid'], | ||
}, | ||
fileName: './test/first.po' | ||
}] | ||
] | ||
fileName: './test/first.po', | ||
}], | ||
], | ||
}); | ||
@@ -30,14 +26,14 @@ assert(!!result); | ||
var content = fs.readFileSync('./test/first.po'); | ||
assert(!!content); | ||
assert(content.indexOf('msgid "code"') !== -1); | ||
assert(content.indexOf('msgid "hello"') !== -1); | ||
}); | ||
it('No file', function() { | ||
it('No file created if no file name provided', function() { | ||
var result = babel.transform('let t = _t("code");_t("hello");', { | ||
plugins: [ | ||
[plugin, { | ||
fileName: './test/test2.po' | ||
}] | ||
] | ||
fileName: './test/test2.po', | ||
}], | ||
], | ||
}); | ||
assert(!!result); | ||
@@ -47,31 +43,28 @@ assert(!fs.existsSync('./test/test2.po')); | ||
it('Should return a result', function() { | ||
var result = babel.transform('dnpgettext("mydomain", "mycontext", ' + | ||
'"msg", "plurial", 10)', { | ||
it('Should return a result for dnpgettext', function() { | ||
var result = babel.transform('dnpgettext("mydomain", "mycontext", "msg", "plurial", 10)', { | ||
plugins: [ | ||
[plugin, { | ||
fileName: './test/dnpgettext.po' | ||
}] | ||
] | ||
fileName: './test/dnpgettext.po', | ||
}], | ||
], | ||
}); | ||
assert(!!result); | ||
var content = fs.readFileSync('./test/dnpgettext.po'); | ||
assert(!!content); | ||
assert(content.indexOf('msgid "msg"') !== -1); | ||
assert(content.indexOf('msgid_plural "plurial"') !== -1); | ||
}); | ||
it('Should have comments', function() { | ||
var result = babel.transform('// Translators: whatever happens\n' + | ||
'let t = _t("code");', { | ||
it('Should extract comments', function() { | ||
var result = babel.transform('// Translators: whatever happens\n let t = _t("code");', { | ||
plugins: [ | ||
[plugin, { | ||
functionNames: { | ||
_t: ['msgid'] | ||
_t: ['msgid'], | ||
}, | ||
fileName: './test/comments.po' | ||
}] | ||
] | ||
fileName: './test/comments.po', | ||
}], | ||
], | ||
}); | ||
assert(!!result); | ||
var content = fs.readFileSync('./test/comments.po') + ''; | ||
@@ -81,3 +74,95 @@ assert(content.match(/whatever happens/)); | ||
it('Should return a result when expression is used as an argument', function() { | ||
var result = babel.transform("let t = _t('some' + ' expression');", { | ||
plugins: [ | ||
[plugin, { | ||
functionNames: { | ||
_t: ['msgid'], | ||
}, | ||
fileName: './test/defaultTranslate.po', | ||
}], | ||
], | ||
}); | ||
assert(!!result); | ||
var content = fs.readFileSync('./test/defaultTranslate.po'); | ||
assert(content.indexOf('msgid "some expression"') !== -1); | ||
}); | ||
it('Should stripIndent from template literals when configured', function() { | ||
var result = babel.transform(`let t = _t(\`spread | ||
over | ||
multi | ||
lines\`);`, { | ||
plugins: [ | ||
[plugin, { | ||
functionNames: { | ||
_t: ['msgid'], | ||
}, | ||
fileName: './test/multiline.po', | ||
stripTemplateLiteralIndent: true, | ||
}], | ||
], | ||
}); | ||
assert(!!result); | ||
var content = fs.readFileSync('./test/multiline.po'); | ||
assert(content.indexOf('spread over multi lines') !== -1); | ||
}); | ||
it('Should stripIndent from template literals in plurals', function() { | ||
var result = babel.transform(`let t = ngettext(\`multi | ||
line\`, \`multi | ||
line | ||
plural\`, foo);`, { | ||
plugins: [ | ||
[plugin, { | ||
functionNames: { | ||
ngettext: ['msgid', 'msgid_plural', 'count'], | ||
}, | ||
fileName: './test/multiline-plural.po', | ||
stripTemplateLiteralIndent: true, | ||
}], | ||
], | ||
}); | ||
assert(!!result); | ||
var content = fs.readFileSync('./test/multiline-plural.po'); | ||
assert(content.indexOf('msgid "multi line') !== -1); | ||
assert(content.indexOf('msgid_plural "multi line plural') !== -1); | ||
}); | ||
it('Should not stripIndent from template literals by default', function() { | ||
var result = babel.transform(`let t = _t(\`spread | ||
over | ||
multi | ||
lines\`);`, { | ||
plugins: [ | ||
[plugin, { | ||
functionNames: { | ||
_t: ['msgid'], | ||
}, | ||
fileName: './test/stripIndent-not-configured.po', | ||
}], | ||
], | ||
}); | ||
assert(!!result); | ||
var content = fs.readFileSync('./test/stripIndent-not-configured.po'); | ||
assert(content.indexOf('spread over multi lines') === -1); | ||
}); | ||
it('Should return a result for JSX', function() { | ||
var result = babel.transform('let jsx = <h1>{_t("title")}</h1>', { | ||
presets: ['react'], | ||
plugins: [ | ||
[plugin, { | ||
functionNames: { | ||
_t: ['msgid'], | ||
}, | ||
fileName: './test/react.po', | ||
}], | ||
], | ||
}); | ||
assert(!!result); | ||
var content = fs.readFileSync('./test/react.po'); | ||
assert(content.indexOf('msgid "title"') !== -1); | ||
}); | ||
}); | ||
}); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
64937
10
325
92
9
1
Updatedgettext-parser@^1.1.2