i18next-parser
Advanced tools
Comparing version 1.0.0-beta14 to 1.0.0-beta16
@@ -5,3 +5,3 @@ #!/usr/bin/env node | ||
var fs = require('fs') | ||
var i18nTransform = require('../dist') | ||
var i18nTransform = require('../dist/transform') | ||
var path = require('path') | ||
@@ -8,0 +8,0 @@ var pkg = require('../package.json') |
# Changelog | ||
## 1.0.0-beta14 - latest | ||
## 1.0.0-beta16 - latest | ||
@@ -5,0 +5,0 @@ - The changelog for the beta can be found in the [releases](https://github.com/i18next/i18next-parser/releases) |
@@ -1,228 +0,4 @@ | ||
'use strict';Object.defineProperty(exports, "__esModule", { value: true });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;};var _createClass = function () {function defineProperties(target, props) {for (var i = 0; i < props.length; i++) {var descriptor = props[i];descriptor.enumerable = descriptor.enumerable || false;descriptor.configurable = true;if ("value" in descriptor) descriptor.writable = true;Object.defineProperty(target, descriptor.key, descriptor);}}return function (Constructor, protoProps, staticProps) {if (protoProps) defineProperties(Constructor.prototype, protoProps);if (staticProps) defineProperties(Constructor, staticProps);return Constructor;};}();var _helpers = require('./helpers'); | ||
var _stream = require('stream'); | ||
var _lodash = require('lodash');var _lodash2 = _interopRequireDefault(_lodash); | ||
var _eol = require('eol');var _eol2 = _interopRequireDefault(_eol); | ||
var _fs = require('fs');var _fs2 = _interopRequireDefault(_fs); | ||
var _parser = require('./parser');var _parser2 = _interopRequireDefault(_parser); | ||
var _path = require('path');var _path2 = _interopRequireDefault(_path); | ||
var _vinyl = require('vinyl');var _vinyl2 = _interopRequireDefault(_vinyl); | ||
var _yamljs = require('yamljs');var _yamljs2 = _interopRequireDefault(_yamljs); | ||
var _baseLexer = require('./lexers/base-lexer');var _baseLexer2 = _interopRequireDefault(_baseLexer);function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };}function _classCallCheck(instance, Constructor) {if (!(instance instanceof Constructor)) {throw new TypeError("Cannot call a class as a function");}}function _possibleConstructorReturn(self, call) {if (!self) {throw new ReferenceError("this hasn't been initialised - super() hasn't been called");}return call && (typeof call === "object" || typeof call === "function") ? call : self;}function _inherits(subClass, superClass) {if (typeof superClass !== "function" && superClass !== null) {throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);}subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } });if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;}var | ||
i18nTransform = function (_Transform) {_inherits(i18nTransform, _Transform); | ||
function i18nTransform() {var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};_classCallCheck(this, i18nTransform); | ||
options.objectMode = true;var _this = _possibleConstructorReturn(this, (i18nTransform.__proto__ || Object.getPrototypeOf(i18nTransform)).call(this, | ||
options)); | ||
_this.defaults = { | ||
contextSeparator: '_', | ||
createOldCatalogs: true, | ||
defaultNamespace: 'translation', | ||
defaultValue: '', | ||
extension: '.json', | ||
filename: '$NAMESPACE', | ||
indentation: 2, | ||
keepRemoved: false, | ||
keySeparator: '.', | ||
lexers: {}, | ||
lineEnding: 'auto', | ||
locales: ['en', 'fr'], | ||
namespaceSeparator: ':', | ||
output: 'locales', | ||
reactNamespace: false, | ||
sort: false }; | ||
_this.options = _extends({}, _this.defaults, options); | ||
if (_this.options.keySeparator === false) { | ||
_this.options.keySeparator = '__!NO_KEY_SEPARATOR!__'; | ||
} | ||
if (_this.options.namespaceSeparator === false) { | ||
_this.options.namespaceSeparator = '__!NO_NAMESPACE_SEPARATOR!__'; | ||
} | ||
_this.entries = []; | ||
_this.parser = new _parser2.default(_this.options); | ||
_this.parser.on('error', function (error) {return _this.emit('error', error);}); | ||
_this.parser.on('warning', function (warning) {return _this.emit('warning', warning);}); | ||
_this.localeRegex = /\$LOCALE/g; | ||
_this.namespaceRegex = /\$NAMESPACE/g;return _this; | ||
}_createClass(i18nTransform, [{ key: '_transform', value: function _transform( | ||
file, encoding, done) {var _this2 = this; | ||
var content = void 0; | ||
if (file.isBuffer()) { | ||
content = file.contents.toString('utf8'); | ||
} else | ||
{ | ||
content = _fs2.default.readFileSync(file.path, encoding); | ||
} | ||
this.emit('reading', file); | ||
var extension = _path2.default.extname(file.path).substring(1); | ||
var entries = this.parser.parse(content, extension); | ||
entries.forEach(function (entry) { | ||
var key = entry.key; | ||
var parts = key.split(_this2.options.namespaceSeparator); | ||
// make sure we're not pulling a 'namespace' out of a default value | ||
if (parts.length > 1 && key !== entry.defaultValue) { | ||
entry.namespace = parts.shift(); | ||
} else | ||
if (extension === 'jsx' || _this2.options.reactNamespace) { | ||
entry.namespace = _this2.grabReactNamespace(content); | ||
} | ||
entry.namespace = entry.namespace || _this2.options.defaultNamespace; | ||
key = parts.join(_this2.options.namespaceSeparator); | ||
key = key.replace(/\\('|"|`)/g, '$1'); | ||
key = key.replace(/\\n/g, '\n'); | ||
key = key.replace(/\\r/g, '\r'); | ||
key = key.replace(/\\t/g, '\t'); | ||
key = key.replace(/\\\\/g, '\\'); | ||
entry.key = entry.namespace + _this2.options.keySeparator + key; | ||
_this2.addEntry(entry); | ||
}); | ||
done(); | ||
} }, { key: '_flush', value: function _flush( | ||
done) {var _this3 = this; | ||
var catalog = {}; | ||
if (this.options.sort) { | ||
this.entries = this.entries.sort(function (a, b) {return a.key.localeCompare(b.key);}); | ||
} | ||
this.entries.forEach(function (entry) { | ||
catalog = (0, _helpers.dotPathToHash)( | ||
entry, | ||
catalog, | ||
{ | ||
separator: _this3.options.keySeparator, | ||
value: _this3.options.defaultValue }); | ||
}); | ||
this.options.locales.forEach(function (locale) { | ||
var outputPath = _path2.default.resolve(_this3.options.output, locale); | ||
Object.keys(catalog).forEach(function (namespace) { | ||
var filename = _this3.options.filename; | ||
filename = filename.replace(_this3.localeRegex, locale); | ||
filename = filename.replace(_this3.namespaceRegex, namespace); | ||
var extension = _this3.options.extension; | ||
extension = extension.replace(_this3.localeRegex, locale); | ||
extension = extension.replace(_this3.namespaceRegex, namespace); | ||
var oldFilename = filename + '_old' + extension; | ||
filename += extension; | ||
var namespacePath = _path2.default.resolve(outputPath, filename); | ||
var namespaceOldPath = _path2.default.resolve(outputPath, oldFilename); | ||
var newCatalog = void 0; | ||
var existingCatalog = _this3.getCatalog(namespacePath); | ||
var oldCatalog = _this3.getCatalog(namespaceOldPath); | ||
// merges existing translations with the new ones | ||
var _mergeHashes = (0, _helpers.mergeHashes)( | ||
existingCatalog, | ||
catalog[namespace], | ||
null, | ||
_this3.options.keepRemoved),newKeys = _mergeHashes.new,oldKeys = _mergeHashes.old; | ||
// restore old translations if the key is empty | ||
newCatalog = (0, _helpers.populateHash)(oldCatalog, newKeys); | ||
// add keys from the current catalog that are no longer used | ||
oldCatalog = _lodash2.default.extend(oldCatalog, oldKeys); | ||
// push files back to the stream | ||
_this3.pushFile(namespacePath, newCatalog); | ||
if (_this3.options.createOldCatalogs) { | ||
_this3.pushFile(namespaceOldPath, oldCatalog); | ||
} | ||
}); | ||
}); | ||
done(); | ||
} }, { key: 'addEntry', value: function addEntry( | ||
entry) { | ||
var existing = this.entries.filter(function (x) {return x.key === entry.key;})[0]; | ||
if (!existing) { | ||
this.entries.push(entry); | ||
} else | ||
{ | ||
existing = _extends({}, existing, entry); | ||
} | ||
if (entry.context) { | ||
var contextEntry = Object.assign({}, entry); | ||
delete contextEntry.context; | ||
contextEntry.key += this.options.contextSeparator + entry.context; | ||
this.addEntry(contextEntry); | ||
} | ||
} }, { key: 'getCatalog', value: function getCatalog( | ||
path) { | ||
var content = void 0; | ||
try { | ||
content = JSON.parse(_fs2.default.readFileSync(path)); | ||
} | ||
catch (error) { | ||
if (error.code !== 'ENOENT') { | ||
this.emit('error', error); | ||
} | ||
content = {}; | ||
} | ||
return content; | ||
} }, { key: 'pushFile', value: function pushFile( | ||
path, contents) { | ||
var text = void 0; | ||
if (path.endsWith('yml')) { | ||
text = _yamljs2.default.stringify(contents, null, this.options.indentation); | ||
} else | ||
{ | ||
text = JSON.stringify(contents, null, this.options.indentation) + '\n'; | ||
} | ||
if (this.options.lineEnding === 'auto') { | ||
text = _eol2.default.auto(text); | ||
} else | ||
if (lineEnding === '\r\n' || lineEnding === 'crlf') { | ||
text = _eol2.default.crlf(text); | ||
} else | ||
if (lineEnding === '\r' || lineEnding === 'cr') { | ||
text = _eol2.default.cr(text); | ||
} else | ||
{ | ||
// Defaults to LF, aka \n | ||
text = _eol2.default.lf(text); | ||
} | ||
var file = new _vinyl2.default({ | ||
path: path, | ||
contents: Buffer.from(text) }); | ||
this.push(file); | ||
} }, { key: 'grabReactNamespace', value: function grabReactNamespace( | ||
content) { | ||
var reactTranslateRegex = new RegExp( | ||
'translate\\((?:\\s*\\[?\\s*)(' + _baseLexer2.default.stringPattern + ')'); | ||
var translateMatches = content.match(reactTranslateRegex); | ||
if (translateMatches) { | ||
return translateMatches[1].slice(1, -1); | ||
} | ||
} }]);return i18nTransform;}(_stream.Transform);exports.default = i18nTransform;module.exports = exports['default']; | ||
'use strict';Object.defineProperty(exports, "__esModule", { value: true });var _broccoli = require('./broccoli');Object.defineProperty(exports, 'broccoli', { enumerable: true, get: function get() {return _interopRequireDefault(_broccoli).default;} });var _parser = require('./parser');Object.defineProperty(exports, 'parser', { enumerable: true, get: function get() {return _interopRequireDefault(_parser). | ||
default;} });var _transform = require('./transform');Object.defineProperty(exports, 'transform', { enumerable: true, get: function get() {return _interopRequireDefault(_transform). | ||
default;} });Object.defineProperty(exports, 'gulp', { enumerable: true, get: function get() {return _interopRequireDefault(_transform). | ||
default;} });function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} |
@@ -64,3 +64,3 @@ 'use strict';Object.defineProperty(exports, "__esModule", { value: true });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;};var _createClass = function () {function defineProperties(target, props) {for (var i = 0; i < props.length; i++) {var descriptor = props[i];descriptor.enumerable = descriptor.enumerable || false;descriptor.configurable = true;if ("value" in descriptor) descriptor.writable = true;Object.defineProperty(target, descriptor.key, descriptor);}}return function (Constructor, protoProps, staticProps) {if (protoProps) defineProperties(Constructor.prototype, protoProps);if (staticProps) defineProperties(Constructor, staticProps);return Constructor;};}();var _baseLexer = require('./base-lexer');var _baseLexer2 = _interopRequireDefault(_baseLexer);function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };}function _classCallCheck(instance, Constructor) {if (!(instance instanceof Constructor)) {throw new TypeError("Cannot call a class as a function");}}function _possibleConstructorReturn(self, call) {if (!self) {throw new ReferenceError("this hasn't been initialised - super() hasn't been called");}return call && (typeof call === "object" || typeof call === "function") ? call : self;}function _inherits(subClass, superClass) {if (typeof superClass !== "function" && superClass !== null) {throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);}subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } });if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;}var | ||
var functionPattern = this.functionPattern(); | ||
var curlyPattern = '(?:{{)' + functionPattern + '\\s+(.*)(?:}})'; | ||
var curlyPattern = '(?:{{)' + functionPattern + '\\s+(.*?)(?:}})'; | ||
var parenthesisPattern = '(?:\\()' + functionPattern + '\\s+(.*)(?:\\))'; | ||
@@ -67,0 +67,0 @@ var pattern = curlyPattern + '|' + parenthesisPattern; |
@@ -52,5 +52,16 @@ # Contribute | ||
``` | ||
yarn global add gulp@next | ||
cd test | ||
gulp i18next | ||
``` | ||
To test broccoli: | ||
``` | ||
yarn global add broccoli-cli | ||
cd test | ||
rm -rf dist && broccoli build dist | ||
``` | ||
## `0.x` vs `1.x` | ||
@@ -57,0 +68,0 @@ |
@@ -5,3 +5,3 @@ { | ||
"name": "i18next-parser", | ||
"version": "1.0.0-beta14", | ||
"version": "1.0.0-beta16", | ||
"license": "MIT", | ||
@@ -23,2 +23,3 @@ "main": "dist/index.js", | ||
"acorn-jsx": "^4.1.1", | ||
"broccoli-plugin": "^1.3.0", | ||
"cheerio": "^1.0.0-rc.2", | ||
@@ -31,2 +32,3 @@ "colors": "~1.2.0-rc0", | ||
"lodash": "~4.17.4", | ||
"rsvp": "^4.8.2", | ||
"through2": "~2.0.3", | ||
@@ -47,3 +49,6 @@ "vinyl": "~2.0.1", | ||
"babel-register": "^6.26.0", | ||
"broccoli": "^1.1.4", | ||
"broccoli-funnel": "^2.0.1", | ||
"chai": "^4.1.2", | ||
"fs-extra": "^6.0.1", | ||
"gulp": "^4.0.0", | ||
@@ -50,0 +55,0 @@ "mocha": "^5.0.0" |
@@ -50,3 +50,3 @@ # i18next Parser [![Build Status](https://travis-ci.org/i18next/i18next-parser.svg?branch=master)](https://travis-ci.org/i18next/i18next-parser) | ||
yarn add -D i18next-parser@next | ||
npm install --save-dev i18next-parser | ||
npm install --save-dev i18next-parser@next | ||
``` | ||
@@ -57,7 +57,7 @@ | ||
```javascript | ||
const i18next = require('i18next-parser'); | ||
const i18nextParser = require('i18next-parser').gulp; | ||
gulp.task('i18next', function() { | ||
gulp.src('app/**') | ||
.pipe(new i18next({ | ||
.pipe(new i18nextParser({ | ||
locales: ['en', 'de'], | ||
@@ -72,3 +72,32 @@ output: 'locales' | ||
### Broccoli | ||
Save the package to your devDependencies: | ||
``` | ||
yarn add -D i18next-parser@next | ||
npm install --save-dev i18next-parser@next | ||
``` | ||
[Broccoli.js](https://github.com/broccolijs/broccoli) defines itself as a fast, reliable asset pipeline, supporting constant-time rebuilds and compact build definitions. | ||
```javascript | ||
const Funnel = require('broccoli-funnel') | ||
const i18nextParser = require('i18next-parser').broccoli; | ||
const appRoot = 'broccoli' | ||
let i18n = new Funnel(appRoot, { | ||
files: ['handlebars.hbs', 'javascript.js'], | ||
annotation: 'i18next-parser' | ||
}) | ||
i18n = new i18nextParser([i18n], { | ||
output: 'broccoli/locales' | ||
}) | ||
module.exports = i18n | ||
``` | ||
## Options | ||
@@ -75,0 +104,0 @@ |
233
src/index.js
@@ -1,229 +0,4 @@ | ||
import { dotPathToHash, mergeHashes, populateHash } from './helpers' | ||
import { Transform } from 'stream' | ||
import _ from 'lodash' | ||
import eol from 'eol' | ||
import fs from 'fs' | ||
import Parser from './parser' | ||
import path from 'path' | ||
import VirtualFile from 'vinyl' | ||
import YAML from 'yamljs' | ||
import BaseLexer from './lexers/base-lexer'; | ||
export default class i18nTransform extends Transform { | ||
constructor(options = {}) { | ||
options.objectMode = true | ||
super(options) | ||
this.defaults = { | ||
contextSeparator: '_', | ||
createOldCatalogs: true, | ||
defaultNamespace: 'translation', | ||
defaultValue: '', | ||
extension: '.json', | ||
filename: '$NAMESPACE', | ||
indentation: 2, | ||
keepRemoved: false, | ||
keySeparator: '.', | ||
lexers: {}, | ||
lineEnding: 'auto', | ||
locales: ['en', 'fr'], | ||
namespaceSeparator: ':', | ||
output: 'locales', | ||
reactNamespace: false, | ||
sort: false | ||
} | ||
this.options = { ...this.defaults, ...options } | ||
if (this.options.keySeparator === false) { | ||
this.options.keySeparator = '__!NO_KEY_SEPARATOR!__' | ||
} | ||
if (this.options.namespaceSeparator === false) { | ||
this.options.namespaceSeparator = '__!NO_NAMESPACE_SEPARATOR!__' | ||
} | ||
this.entries = [] | ||
this.parser = new Parser(this.options) | ||
this.parser.on('error', error => this.emit('error', error)) | ||
this.parser.on('warning', warning => this.emit('warning', warning)) | ||
this.localeRegex = /\$LOCALE/g | ||
this.namespaceRegex = /\$NAMESPACE/g | ||
} | ||
_transform(file, encoding, done) { | ||
let content | ||
if (file.isBuffer()) { | ||
content = file.contents.toString('utf8') | ||
} | ||
else { | ||
content = fs.readFileSync(file.path, encoding) | ||
} | ||
this.emit('reading', file) | ||
const extension = path.extname(file.path).substring(1) | ||
const entries = this.parser.parse(content, extension) | ||
entries.forEach(entry => { | ||
let key = entry.key | ||
const parts = key.split(this.options.namespaceSeparator) | ||
// make sure we're not pulling a 'namespace' out of a default value | ||
if (parts.length > 1 && key !== entry.defaultValue) { | ||
entry.namespace = parts.shift() | ||
} | ||
else if (extension === 'jsx' || this.options.reactNamespace) { | ||
entry.namespace = this.grabReactNamespace(content) | ||
} | ||
entry.namespace = entry.namespace || this.options.defaultNamespace | ||
key = parts.join(this.options.namespaceSeparator) | ||
key = key.replace(/\\('|"|`)/g, '$1') | ||
key = key.replace(/\\n/g, '\n') | ||
key = key.replace(/\\r/g, '\r') | ||
key = key.replace(/\\t/g, '\t') | ||
key = key.replace(/\\\\/g, '\\') | ||
entry.key = entry.namespace + this.options.keySeparator + key | ||
this.addEntry(entry) | ||
}) | ||
done() | ||
} | ||
_flush(done) { | ||
let catalog = {} | ||
if (this.options.sort) { | ||
this.entries = this.entries.sort((a, b) => a.key.localeCompare(b.key)) | ||
} | ||
this.entries.forEach(entry => { | ||
catalog = dotPathToHash( | ||
entry, | ||
catalog, | ||
{ | ||
separator: this.options.keySeparator, | ||
value: this.options.defaultValue | ||
} | ||
) | ||
}) | ||
this.options.locales.forEach(locale => { | ||
const outputPath = path.resolve(this.options.output, locale) | ||
Object.keys(catalog).forEach(namespace => { | ||
let filename = this.options.filename | ||
filename = filename.replace(this.localeRegex, locale) | ||
filename = filename.replace(this.namespaceRegex, namespace) | ||
let extension = this.options.extension | ||
extension = extension.replace(this.localeRegex, locale) | ||
extension = extension.replace(this.namespaceRegex, namespace) | ||
const oldFilename = filename + '_old' + extension | ||
filename += extension | ||
const namespacePath = path.resolve(outputPath, filename) | ||
const namespaceOldPath = path.resolve(outputPath, oldFilename) | ||
let newCatalog | ||
let existingCatalog = this.getCatalog(namespacePath) | ||
let oldCatalog = this.getCatalog(namespaceOldPath) | ||
// merges existing translations with the new ones | ||
const { new: newKeys, old: oldKeys } = mergeHashes( | ||
existingCatalog, | ||
catalog[namespace], | ||
null, | ||
this.options.keepRemoved | ||
) | ||
// restore old translations if the key is empty | ||
newCatalog = populateHash(oldCatalog, newKeys) | ||
// add keys from the current catalog that are no longer used | ||
oldCatalog = _.extend(oldCatalog, oldKeys) | ||
// push files back to the stream | ||
this.pushFile(namespacePath, newCatalog) | ||
if (this.options.createOldCatalogs) { | ||
this.pushFile(namespaceOldPath, oldCatalog) | ||
} | ||
}) | ||
}) | ||
done() | ||
} | ||
addEntry(entry) { | ||
let existing = this.entries.filter(x => x.key === entry.key)[0] | ||
if (!existing) { | ||
this.entries.push(entry) | ||
} | ||
else { | ||
existing = { ...existing, ...entry } | ||
} | ||
if (entry.context) { | ||
const contextEntry = Object.assign({}, entry) | ||
delete contextEntry.context | ||
contextEntry.key += this.options.contextSeparator + entry.context | ||
this.addEntry(contextEntry) | ||
} | ||
} | ||
getCatalog(path) { | ||
let content | ||
try { | ||
content = JSON.parse( fs.readFileSync( path ) ) | ||
} | ||
catch (error) { | ||
if (error.code !== 'ENOENT') { | ||
this.emit('error', error) | ||
} | ||
content = {} | ||
} | ||
return content | ||
} | ||
pushFile(path, contents) { | ||
let text | ||
if (path.endsWith('yml')) { | ||
text = YAML.stringify(contents, null, this.options.indentation) | ||
} | ||
else { | ||
text = JSON.stringify(contents, null, this.options.indentation) + '\n' | ||
} | ||
if (this.options.lineEnding === 'auto') { | ||
text = eol.auto(text) | ||
} | ||
else if (lineEnding === '\r\n' || lineEnding === 'crlf') { | ||
text = eol.crlf(text) | ||
} | ||
else if (lineEnding === '\r' || lineEnding === 'cr') { | ||
text = eol.cr(text) | ||
} | ||
else { | ||
// Defaults to LF, aka \n | ||
text = eol.lf(text) | ||
} | ||
const file = new VirtualFile({ | ||
path, | ||
contents: Buffer.from(text) | ||
}) | ||
this.push(file) | ||
} | ||
grabReactNamespace(content) { | ||
const reactTranslateRegex = new RegExp( | ||
'translate\\((?:\\s*\\[?\\s*)(' + BaseLexer.stringPattern + ')' | ||
) | ||
const translateMatches = content.match(reactTranslateRegex) | ||
if (translateMatches) { | ||
return translateMatches[1].slice(1, -1) | ||
} | ||
} | ||
} | ||
export { default as broccoli } from './broccoli' | ||
export { default as parser } from './parser' | ||
export { default as transform } from './transform' | ||
export { default as gulp } from './transform' |
@@ -64,3 +64,3 @@ import BaseLexer from './base-lexer' | ||
const functionPattern = this.functionPattern() | ||
const curlyPattern = '(?:{{)' + functionPattern + '\\s+(.*)(?:}})' | ||
const curlyPattern = '(?:{{)' + functionPattern + '\\s+(.*?)(?:}})' | ||
const parenthesisPattern = '(?:\\()' + functionPattern + '\\s+(.*)(?:\\))' | ||
@@ -67,0 +67,0 @@ const pattern = curlyPattern + '|' + parenthesisPattern |
{ | ||
"bar": "", | ||
"foo": "", | ||
"first": "Yo2!", | ||
"second": "", | ||
"fourth": "", | ||
"second": "", | ||
"bar": "", | ||
"foo": "", | ||
"third": { | ||
@@ -12,3 +12,5 @@ "first": "Hello <1><0>{{name}}</0></1>, you have <3>{{count}}</3> unread message. <5>Go to messages</5>.", | ||
}, | ||
"fifth": "" | ||
"fifth": "", | ||
"This should be part of the value and the key": "This should be part of the value and the key", | ||
"don't split <1>{{on}}</1>": "don't split <1>{{on}}</1>" | ||
} |
@@ -12,3 +12,4 @@ { | ||
"sixth": "", | ||
"seventh": "defaultValue" | ||
"seventh": "defaultValue", | ||
"selfClosing": "" | ||
} |
{ | ||
"bar": "", | ||
"foo": "", | ||
"first": "", | ||
"second": "", | ||
"fourth": "", | ||
"second": "", | ||
"bar": "", | ||
"foo": "", | ||
"third": { | ||
@@ -12,3 +12,5 @@ "first": "Hello <1><0>{{name}}</0></1>, you have <3>{{count}}</3> unread message. <5>Go to messages</5>.", | ||
}, | ||
"fifth": "" | ||
"fifth": "", | ||
"This should be part of the value and the key": "This should be part of the value and the key", | ||
"don't split <1>{{on}}</1>": "don't split <1>{{on}}</1>" | ||
} |
@@ -12,3 +12,4 @@ { | ||
"sixth": "", | ||
"seventh": "defaultValue" | ||
"seventh": "defaultValue", | ||
"selfClosing": "" | ||
} |
@@ -12,2 +12,9 @@ import { assert } from 'chai' | ||
it('extracts multiple keys on a single line', (done) => { | ||
const Lexer = new HandlebarsLexer() | ||
const content = '<p>{{t "first"}} {{t "second"}}</p>' | ||
assert.deepEqual(Lexer.extract(content), [{ key: 'first' }, { key: 'second' }]) | ||
done() | ||
}) | ||
it('extracts the second argument as defaultValue', (done) => { | ||
@@ -14,0 +21,0 @@ const Lexer = new HandlebarsLexer() |
import { assert } from 'chai' | ||
import Vinyl from 'vinyl' | ||
import fs from 'fs' | ||
import i18nTransform from '../src/index' | ||
import i18nTransform from '../src/transform' | ||
import path from 'path' | ||
@@ -6,0 +6,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
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
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
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
430414
73
3426
213
15
12
7
+ Addedbroccoli-plugin@^1.3.0
+ Addedrsvp@^4.8.2
+ Addedbroccoli-plugin@1.3.1(transitive)
+ Addedmktemp@0.4.0(transitive)
+ Addedpromise-map-series@0.2.3(transitive)
+ Addedquick-temp@0.1.8(transitive)
+ Addedrimraf@2.7.1(transitive)
+ Addedrsvp@3.6.24.8.5(transitive)
+ Addedsprintf-js@1.1.3(transitive)
+ Addedsymlink-or-copy@1.3.1(transitive)
+ Addedunderscore.string@3.3.6(transitive)