Skip to content

Commit

Permalink
Refactor helpers
Browse files Browse the repository at this point in the history
  • Loading branch information
karellm committed Feb 24, 2018
1 parent 61c7201 commit 9a02447
Show file tree
Hide file tree
Showing 15 changed files with 1,965 additions and 345 deletions.
5 changes: 5 additions & 0 deletions .babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"presets": ["env"],
"sourceMaps": true,
"retainLines": true
}
17 changes: 17 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# EditorConfig helps developers define and maintain consistent
# coding styles between different editors and IDEs
# editorconfig.org

root = true


[*]
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
indent_style = space
indent_size = 2

[*.{diff,md}]
trim_trailing_whitespace = false
4 changes: 3 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
language: node_js

node_js:
- '8'
- '7'
- '6'
- '5'
- '4'
Expand All @@ -10,4 +12,4 @@ before_install:
- npm --version

after_success:
- npm run test
- npm run test
35 changes: 35 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Mocha Tests",
"cwd": "${workspaceRoot}",
"program": "${workspaceFolder}/node_modules/mocha/bin/_mocha",
"args": [
"-u", "tdd",
"--timeout", "999999",
"--colors",
"--require", "babel-register",
"--require", "babel-polyfill",
"--plugins", "transform-object-rest-spread",
"${workspaceFolder}/test/**/*.test.js"
],
"runtimeArgs": [
"--nolazy"
],
"sourceMaps": true,
"internalConsoleOptions": "openOnSessionStart"
},
{
"type": "node",
"request": "launch",
"name": "Launch Program",
"program": "${workspaceFolder}/src/helpers.js"
}
]
}
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ npm install i18next-parser -g
## Tests

```
mocha --reporter nyan test/test.js
mocha --require babel-register --require babel-polyfill test/**/*.js
```

---
Expand Down
6 changes: 3 additions & 3 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ Parser.prototype._flush = function(done) {
// simplify ${dot.separated.variables} into just their tails (${variables})
var key = self.translations[index].key.replace( /\$\{(?:[^.}]+\.)*([^}]+)\}/g, '\${$1}' );
var value = self.translations[index].defaultValue;
translationsHash = helpers.hashFromString( key, self.keySeparator, value, translationsHash );
translationsHash = helpers.dotPathToHash( key, self.keySeparator, value, translationsHash );
}


Expand Down Expand Up @@ -274,10 +274,10 @@ Parser.prototype._flush = function(done) {


// merges existing translations with the new ones
mergedTranslations = helpers.mergeHash( currentTranslations, translationsHash[namespace], null, this.keepRemoved );
mergedTranslations = helpers.mergeHashes( currentTranslations, translationsHash[namespace], null, this.keepRemoved );

// restore old translations if the key is empty
mergedTranslations.new = helpers.replaceEmpty( oldTranslations, mergedTranslations.new );
mergedTranslations.new = helpers.populateHash( oldTranslations, mergedTranslations.new );

// merges former old translations with the new ones
mergedTranslations.old = _.extend( oldTranslations, mergedTranslations.old );
Expand Down
21 changes: 13 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
{
"author": "Karel Ledru-Mathe",
"author": "Karel Ledru",
"description": "Command Line tool for i18next",
"name": "i18next-parser",
"version": "0.13.0",
"version": "1.0.0-alpha1",
"license": "MIT",
"main": "src/index.js",
"bin": {
"i18next": "./bin/cli.js"
},
"scripts": {
"test": "mocha --reporter nyan test/test.js"
"test": "mocha --require babel-register --require babel-polyfill test/**/*.test.js"
},
"repository": {
"type": "git",
Expand All @@ -18,19 +19,23 @@
"colors": "~1.1.2",
"commander": "~2.9.0",
"concat-stream": "~1.6.0",
"lodash": "~4.17.3",
"eol": "^0.9.1",
"lodash": "~4.17.4",
"mkdirp": "~0.5.1",
"plugin-error": "^1.0.1",
"readdirp": "~2.1.0",
"through2": "~2.0.3",
"vinyl": "~2.0.1"
"vinyl": "~2.0.1",
"vinyl-fs": "^3.0.2"
},
"engines": {
"node": ">=0.10.22"
},
"devDependencies": {
"mocha": "~3.2.0",
"assert": "~1.4.1"
"babel-polyfill": "^6.26.0",
"babel-preset-env": "^1.6.1",
"babel-register": "^6.26.0",
"chai": "^4.1.2",
"mocha": "^5.0.0"
},
"keywords": [
"gulpplugin",
Expand Down
167 changes: 84 additions & 83 deletions src/helpers.js
Original file line number Diff line number Diff line change
@@ -1,106 +1,107 @@
import _ from 'lodash'

// Takes a `path` of the form 'foo.bar' and
// turn it into a hash {foo: {bar: ""}}.
// The generated hash can be attached to an
// optional `hash`.
function hashFromString(path, separator, value, hash) {
separator = separator || '.';

if ( path.indexOf( separator, path.length - separator.length ) >= 0 ) {
path = path.slice( 0, -separator.length );
function dotPathToHash(path, separator = '.', value = '', target = {}) {
if (path.endsWith(separator)) {
path = path.slice( 0, -separator.length )
}

var parts = path.split( separator );
var tmp_obj = hash || {};
var obj = tmp_obj;

for( var x = 0; x < parts.length; x++ ) {
if ( x == parts.length - 1 ) {
tmp_obj[parts[x]] = value || '';
}
else if ( ! tmp_obj[parts[x]] ) {
tmp_obj[parts[x]] = {};
}
tmp_obj = tmp_obj[parts[x]];
}
return obj;
let result = {}
const segments = path.split(separator)

segments.reduce((hash, segment, index) => {
if (index === segments.length - 1) {
hash[segment] = value
}
else {
hash[segment] = {}
}
return hash[segment]
}, result)

return _.merge(target, result)
}


// Takes a `source` hash and make sure its value
// are pasted in the `target` hash, if the target
// hash has the corresponding key (or if keepRemoved is true).
// If not, the value is added to an `old` hash.
function mergeHash(source, target, old, keepRemoved) {
target = target || {};
old = old || {};

Object.keys(source).forEach(function (key) {
if ( target[key] !== undefined ) {
if (typeof source[key] === 'object' && source[key].constructor !== Array) {
var nested = mergeHash( source[key], target[key], old[key], keepRemoved );
target[key] = nested.new;
old[key] = nested.old;
}
else {
target[key] = source[key];
}
}
else {
// support for plural in keys
pluralMatch = /_plural(_\d+)?$/.test( key );
singularKey = key.replace( /_plural(_\d+)?$/, '' );

// support for context in keys
contextMatch = /_([^_]+)?$/.test( singularKey );
rawKey = singularKey.replace( /_([^_]+)?$/, '' );

if (
( contextMatch && target[rawKey] !== undefined ) ||
( pluralMatch && target[singularKey] !== undefined )
) {
target[key] = source[key];
}
else {
if (keepRemoved) {
target[key] = source[key];
}
old[key] = source[key];
}
}
});

return {
'new': target,
'old': old
};
function mergeHashes(source, target = {}, old, keepRemoved = false) {
old = old || {}
Object.keys(source).forEach((key) => {
const hasNestedEntries = (
typeof target[key] === 'object' &&
!Array.isArray(target[key])
)

if (hasNestedEntries) {
const nested = mergeHashes(source[key], target[key], old[key], keepRemoved)
target[key] = nested.new
old[key] = nested.old
}
else if ( target[key] !== undefined ) {
if (typeof source[key] === 'string' || Array.isArray(source[key])) {
target[key] = source[key]
}
else {
old[key] = source[key]
}
}
else {
// support for plural in keys
const pluralMatch = /_plural(_\d+)?$/.test( key )
const singularKey = key.replace(/_plural(_\d+)?$/, '')

// support for context in keys
const contextMatch = /_([^_]+)?$/.test(singularKey)
const rawKey = singularKey.replace(/_([^_]+)?$/, '')

if (
(contextMatch && target[rawKey] !== undefined) ||
(pluralMatch && target[singularKey] !== undefined)
) {
target[key] = source[key]
}
else if (keepRemoved) {
target[key] = source[key]
old[key] = source[key]
}
else {
old[key] = source[key]
}
}
})

return {old, new: target}
}


// Takes a `target` hash and replace its empty
// values with the `source` hash ones if they
// exist
function replaceEmpty(source, target) {
target = target || {};

Object.keys(source).forEach(function (key) {
if ( target[key] !== undefined ) {
if (typeof source[key] === 'object') {
var nested = replaceEmpty( source[key], target[key] );
target[key] = nested;
}
else if ( target[key] === '' ) {
target[key] = source[key];
}
}
});

return target;
function populateHash(source, target = {}) {
Object.keys(source).forEach((key) => {
if ( target[key] !== undefined ) {
if (typeof source[key] === 'object') {
target[key] = populateHash(source[key], target[key])
}
else if (target[key] === '') {
target[key] = source[key]
}
}
})

return target
}



module.exports = {
hashFromString: hashFromString,
mergeHash: mergeHash,
replaceEmpty: replaceEmpty
};
export {
dotPathToHash,
mergeHashes,
populateHash
}
Loading

0 comments on commit 9a02447

Please sign in to comment.