@f5io/jsont
Version:
Transform JSON Objects with ES6/2015 template strings
119 lines (98 loc) • 3.21 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
var _jsonpath = require('@f5io/jsonpath');
var _jsonpath2 = _interopRequireDefault(_jsonpath);
var _utils = require('./utils');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
const isRoot = Symbol('root');
const isRule = Symbol('rule');
const rulePath = Symbol('rulePath');
exports.default = transform;
function transform(path) {
function handler(strings) {
for (var _len = arguments.length, keys = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
keys[_key - 1] = arguments[_key];
}
function rule(context) {
let root = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : isRoot;
/**
* If there is no root we are at the
* top level of our transform.
*/
let rootCtx;
if (path && root === isRoot) {
root = rootCtx = context;
context = (0, _jsonpath2.default)(path, context);
} else if (root === isRoot) {
root = context;
}
/**
* If it is a mirror return stringified context.
*/
if ((0, _utils.isMirror)(strings)) {
return JSON.stringify((0, _utils.isUndefined)(context) ? null : context);
}
/**
* Create the output for this rule.
*/
const val = keys.reduce(function (acc, k, i) {
let result;
if (k[isRule]) {
const path = k[rulePath];
const ctx = path ? (0, _jsonpath2.default)(path, getContext(path)) : context;
/**
* If the context is an array, map over it
* with the current rule. Otherwise just
* pass the context into the rule.
*/
result = Array.isArray(ctx) ? '[' + ctx.map(function (x) {
return k(x, root);
}).join(',') + ']' : k(ctx, root);
} else if (typeof k === 'function') {
result = JSON.stringify(k(context, root)) || null;
} else {
result = JSON.stringify((0, _jsonpath2.default)(k, getContext(k))) || null;
}
return acc + result + strings[i + 1];
}, strings[0]);
/**
* If the path is defined we are nested and can
* return the value as a string.
*/
if (root !== context && root !== rootCtx) {
return val;
} else {
/* wot? */
}
try {
/**
* If this is the root rule, JSON.parse the
* value to get the true output.
*/
return JSON.parse(val);
} catch (e) {
throw new Error('Your transform is malformed, ' + val);
}
/**
* Determine from the beginning of the path
* whether we should be scoped or not.
*/
function getContext(s) {
return s && s[0] === '$' ? root : context;
}
};
rule[isRule] = true;
rule[rulePath] = path;
return rule;
};
if (path && path.raw) {
const strings = path;
path = null;
const args = Array.prototype.slice.call(arguments, 1);
return handler.apply(null, [strings].concat(args));
}
return handler;
};
module.exports = exports['default'];