Skip to content
28 changes: 28 additions & 0 deletions ditto/mappers/lib/comparator.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
module.exports = function comperator(operation, firstValue, secondValue) {

// Make sure we always apply strict comparison
if (operation === '==' || operation === '!=') {
operation = operation.replace('=', '==');
}

switch(operation) {
case '===':
return firstValue === secondValue;
case '==':
return firstValue === secondValue;
case '!==':
return firstValue !== secondValue;
case '!=':
return firstValue !== secondValue;
case '>':
return firstValue > secondValue;
case '<':
return firstValue < secondValue;
case '<=':
return firstValue <= secondValue;
case '>=':
return firstValue >= secondValue;
}
return false;

}
38 changes: 38 additions & 0 deletions ditto/mappers/lib/extractor.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@

const _ = require('lodash');
const comparator = require('./comparator');

module.exports = class Extractor {

constructor(plugins, transformer){
this.plugins = plugins;
this.transformer = transformer;
}

extract (document, path, output) {

const extractor = this;

if (_.isNil(path)) return;

if (path === '!') return document;

if (_.startsWith(path, '>>')) {
return _.startsWith(path, '>>%') ? eval(path.replace('>>%', '')) : path.replace('>>', '');
} else if (_.startsWith(path, '!')) {
return _.get(output, path.replace('!', ''));
} else if (/\|\|/.test(path) && !path.includes('??') ) {
let pathWithDefault = path.split(/\|\|/);
return extractor.extract(document, pathWithDefault[0], output) || extractor.extract(document, `${pathWithDefault[1]}`, output);
} else if (path.includes('??') ){
const parameters = _.zipObject(['source', 'targetValue', 'comparator', 'comparison', 'condition'],
path.match(/(.+?)\?\?(.+?)\#(.*)\#(.+)/));
const _comparator = extractor.transformer.transform(document, parameters.comparator, output);
const _condition = extractor.transformer.transform(document, parameters.condition, output);

return comparator(parameters.comparison, _comparator, _condition) ? extractor.transformer.transform(document, parameters.targetValue, output) : null;

} else return _.get(document, path);
}

}
32 changes: 32 additions & 0 deletions ditto/mappers/lib/hoover.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/**
* Remove all specified keys from an object, no matter how deep they are.
* The removal is done in place, so run it on a copy if you don't want to modify the original object.
* This function has no limit so circular objects will probably crash the browser
*
* @param obj The object from where you want to remove the keys
* @param keys An array of property names (strings) to remove
*/
module.exports = function hoover(obj, keys) {
var index;
for (var prop in obj) {
// check that this is objects own property not from prototype prop inherited
if (obj.hasOwnProperty(prop)) {
switch(typeof(obj[prop])) {
case 'string':
index = keys.indexOf(prop);
if(index > -1) {
delete obj[prop];
}
break;
case 'object':
index = keys.indexOf(prop);
if (index > -1) {
delete obj[prop];
} else {
hoover(obj[prop], keys);
}
break;
}
}
}
}
38 changes: 38 additions & 0 deletions ditto/mappers/lib/transformer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@

const _ = require('lodash');

const Extractor = require('./extractor');

module.exports = class Transformer {

constructor(plugins){
this.plugins = plugins;
this.extractor = new Extractor(plugins, this);
}

transform (document, path, output, $key) {

const transformer = this;

if (path.includes('??')) {
return transformer.extractor.extract(document, path, output);
} else if (_.startsWith(path, '$')) {
return eval(path);
} else if (_.startsWith(path, '@!')) {
return eval(path.replace('@!', ''));
} else if (_.startsWith(path, '@')) {

const parameters = _.zipObject(['name', 'arguments'], path.split(/\((.*)\)/).filter(Boolean));
const functionCall = parameters.name.replace('@', '');
const paramteresValues = _.map(parameters.arguments.split('|'), param => {
return transformer.transform(document, param.replace(',', '|'), output, $key)
}).filter(Boolean);

if (paramteresValues.length && transformer.plugins[functionCall]) {
return transformer.plugins[functionCall](...paramteresValues);
}

}
return transformer.extractor.extract(document, path, output);
}
}
Loading