UNPKG

json-tots

Version:

Template of Templates, a.k.a Template Should Eat Itself

205 lines (201 loc) 9.53 kB
"use strict"; 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 } };