json-tots
Version:
Template of Templates, a.k.a Template Should Eat Itself
205 lines (201 loc) • 9.53 kB
JavaScript
;
var _Object$keys = require("@babel/runtime-corejs3/core-js-stable/object/keys");
var _Object$getOwnPropertySymbols = require("@babel/runtime-corejs3/core-js-stable/object/get-own-property-symbols");
var _filterInstanceProperty = require("@babel/runtime-corejs3/core-js-stable/instance/filter");
var _Object$getOwnPropertyDescriptor = require("@babel/runtime-corejs3/core-js-stable/object/get-own-property-descriptor");
var _forEachInstanceProperty = require("@babel/runtime-corejs3/core-js-stable/instance/for-each");
var _Object$getOwnPropertyDescriptors = require("@babel/runtime-corejs3/core-js-stable/object/get-own-property-descriptors");
var _Object$defineProperties = require("@babel/runtime-corejs3/core-js-stable/object/define-properties");
var _Object$defineProperty = require("@babel/runtime-corejs3/core-js-stable/object/define-property");
var _interopRequireDefault = require("@babel/runtime-corejs3/helpers/interopRequireDefault");
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/defineProperty"));
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/toConsumableArray"));
var _toArray2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/toArray"));
var _reduce = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/reduce"));
var _map = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/map"));
var _slice = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/slice"));
var _concat = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/concat"));
var _indexOf = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/index-of"));
function ownKeys(object, enumerableOnly) { var keys = _Object$keys(object); if (_Object$getOwnPropertySymbols) { var symbols = _Object$getOwnPropertySymbols(object); enumerableOnly && (symbols = _filterInstanceProperty(symbols).call(symbols, function (sym) { return _Object$getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var _context3, _context4; var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? _forEachInstanceProperty(_context3 = ownKeys(Object(source), !0)).call(_context3, function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }) : _Object$getOwnPropertyDescriptors ? _Object$defineProperties(target, _Object$getOwnPropertyDescriptors(source)) : _forEachInstanceProperty(_context4 = ownKeys(Object(source))).call(_context4, function (key) { _Object$defineProperty(target, key, _Object$getOwnPropertyDescriptor(source, key)); }); } return target; }
/* eslint-disable no-useless-escape */
var jp = require('jsonpath');
var F = require('functional-pipelines');
var sx = require('./strings');
var operators = require('./operators');
var Fb = require('./times');
var parser = require('./peg/parser');
var rejectPlaceHolder = {
open: '{!!{',
close: '}!!}'
};
function renderString(node, derefedList) {
var rendered;
if (derefedList.length === 1 && derefedList[0].source === node) {
rendered = derefedList[0].value; // stand alone '{{path}}' expands to value, without toString conversion
} else {
var replace = function replace(acc, _ref) {
var source = _ref.source,
value = _ref.value;
return acc.replace(new RegExp(sx.escapeStringForRegex(source), 'g'), value !== undefined ? value : '');
};
rendered = (0, _reduce["default"])(F).call(F, replace, function () {
return node;
}, derefedList);
}
return rendered;
}
function renderStringNode(contextRef) {
var _ref2 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
_ref2$meta = _ref2.meta,
meta = _ref2$meta === void 0 ? 0 : _ref2$meta,
_ref2$sources = _ref2.sources,
sources = _ref2$sources === void 0 ? {
"default": {}
} : _ref2$sources,
_ref2$tags = _ref2.tags,
tags = _ref2$tags === void 0 ? {} : _ref2$tags,
_ref2$functions = _ref2.functions,
functions = _ref2$functions === void 0 ? {} : _ref2$functions,
_ref2$args = _ref2.args,
args = _ref2$args === void 0 ? {} : _ref2$args,
config = _ref2.config;
var refList;
try {
refList = parser.parse(contextRef.node);
} catch (error) {
return {
rendered: contextRef.node
};
}
var derefedList = (0, _map["default"])(F).call(F, operators.applyAll({
meta: meta,
sources: sources,
tags: tags,
functions: functions,
args: args,
context: contextRef,
config: config
}), refList);
var rendered = renderString(contextRef.node, derefedList);
return {
rendered: rendered,
asts: derefedList
};
}
function renderFunctionExpressionNode(contextRef) {
var _context, _context2;
var _ref3 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
_ref3$meta = _ref3.meta,
meta = _ref3$meta === void 0 ? 0 : _ref3$meta,
_ref3$sources = _ref3.sources,
sources = _ref3$sources === void 0 ? {
"default": {}
} : _ref3$sources,
_ref3$tags = _ref3.tags,
tags = _ref3$tags === void 0 ? {} : _ref3$tags,
_ref3$functions = _ref3.functions,
functions = _ref3$functions === void 0 ? {} : _ref3$functions,
_ref3$args = _ref3.args,
args = _ref3$args === void 0 ? {} : _ref3$args,
config = _ref3.config;
var document = arguments.length > 2 ? arguments[2] : undefined;
// eslint-disable-next-line no-template-curly-in-string
var missingFunctionError = sx.lazyTemplate('Error: No such builtin function: [${node}]');
var evaluateArgs = operators.normalizeArgs({
functions: functions,
args: args
});
var node = contextRef.node;
var _node$slice$split = (0, _slice["default"])(node).call(node, 1).split(operators.regex.PIPE),
_node$slice$split2 = (0, _toArray2["default"])(_node$slice$split),
fnName = _node$slice$split2[0],
fnExprs = (0, _slice["default"])(_node$slice$split2).call(_node$slice$split2, 1);
var fn = functions[fnName] || (config["throws"] ? function () {
throw new Error(missingFunctionError({
node: node
}));
} : F.lazy(missingFunctionError({
node: node
})));
var fnPipeline = F.pipes.apply(F, (0, _concat["default"])(_context = [fn]).call(_context, (0, _toConsumableArray2["default"])((0, _map["default"])(F).call(F, function (fnExpr) {
var _fnExpr$split = fnExpr.split(operators.regex.fnArgsSeparator),
_fnExpr$split2 = (0, _toArray2["default"])(_fnExpr$split),
fnName = _fnExpr$split2[0],
args = (0, _slice["default"])(_fnExpr$split2).call(_fnExpr$split2, 1);
if (!(fnName in functions)) {
throw new Error("could not resolve function name [".concat(fnName, "]")); // @TODO: Alternatives to throwing inside a mapping!!!!
}
var phIndex = (0, _indexOf["default"])(args).call(args, '__');
var fn = _objectSpread(_objectSpread({}, functions), {}, {
'*': operators.flatten,
'**': operators.doubleFlatten
})[fnName];
if (phIndex > 0) {
args[phIndex] = F.__;
fn = F.oneslot(functions[fnName]);
}
return args.length ? fn.apply(void 0, (0, _toConsumableArray2["default"])(args)) : fn;
}, fnExprs))));
var fnArgKeys = ["$.".concat(contextRef.path.join('.')), (0, _slice["default"])(_context2 = contextRef.path).call(_context2, -1).pop(), fnName];
var argList = evaluateArgs(fnArgKeys, document);
return {
rendered: F.reduced(fnPipeline.apply(void 0, (0, _toConsumableArray2["default"])(argList)))
};
}
function transduception(enumerable, options) {
var ast = enumerable.metadata();
return operators.inception(options)(ast, enumerable);
}
function renderArrayNode(contextRef, options) {
var NONE = {};
var isString = function isString(x) {
return F.isString(x) ? x : F.reduced(NONE);
};
var hasReph0 = function hasReph0(x) {
var refList;
try {
refList = parser.parse(x);
return refList[0];
} catch (error) {
return F.reduced(NONE);
}
// return F.isReduced(refList) ? F.reduced(NONE) : refList[0];
};
var hasInception = function hasInception(ast) {
return jp.value(ast, '$.operators.inception') ? ast : F.reduced(NONE);
};
var partitionFn = F.composes(function (ast) {
ast.medium = contextRef;
return ast;
}, operators.inceptionPreprocessor, hasInception, hasReph0, isString);
var stickyWhen = function stickyWhen(x, _, ctx) {
ctx.n = x.$depth ? x.$depth : ctx.n;
return x.$depth !== undefined;
};
var partitionedGen = F.partitionBy(F.sticky(1, {
when: stickyWhen,
recharge: false
})(partitionFn), contextRef.node);
var _require = require('../transform'),
transform = _require.transform; // lazy require to break cyclic dependency
var lols = (0, _map["default"])(F).call(F, function (iter) {
return iter.metadata().$depth ? transduception(iter, options) : (0, _map["default"])(F).call(F, function (item) {
return transform(item, options)(options.sources.origin);
}, iter);
}, partitionedGen);
return {
rendered: F.flatten(lols),
asts: {}
};
}
module.exports = {
renderString: renderString,
renderStringNode: renderStringNode,
renderFunctionExpressionNode: renderFunctionExpressionNode,
renderArrayNode: renderArrayNode,
data: {
placeholder: parser.fullPlaceholderRegex,
rejectPlaceHolder: rejectPlaceHolder
}
};