json-tots
Version:
Template of Templates, a.k.a Template Should Eat Itself
142 lines (140 loc) • 7.92 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 _slicedToArray2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/slicedToArray"));
var _concat = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/concat"));
var _map = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/map"));
var _context, _context2, _context3, _context4, _context5, _context6, _context7, _context8, _context9, _context10, _context11, _context12, _context13, _context14;
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 _context15, _context16; var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? _forEachInstanceProperty(_context15 = ownKeys(Object(source), !0)).call(_context15, function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }) : _Object$getOwnPropertyDescriptors ? _Object$defineProperties(target, _Object$getOwnPropertyDescriptors(source)) : _forEachInstanceProperty(_context16 = ownKeys(Object(source))).call(_context16, function (key) { _Object$defineProperty(target, key, _Object$getOwnPropertyDescriptor(source, key)); }); } return target; }
var F = require('functional-pipelines');
var sx = require('../../../src/core/strings');
var fullPlaceholderRegex = /{([^{]*?)?{(.*?)}([^}]*)?}/gm;
var placeholder = {
full: fullPlaceholderRegex
};
var WS = '\\s*'; // '[\s\t\r\n]*';
var OWS = '\\s*\\|?\\s*'; // '[\s\t\r\n\|,;]*';
var SYMBOL = '[a-zA-Z0-9_\\-\\$\\.\\[\\]"\\s]*';
var SOURCE_NAME = '["]?[a-zA-Z0-9_\\s\\-\\$]*["]?';
var ARG_SEPARATOR = '\\s*\\:\\s*';
var ARG_NAME = '[a-zA-Z0-9_\\s-\\$\\.]*';
var inception = '(\\.\\*|\\.{2,}|\\.\\d{1,2}|>\\*|>{2,}|>\\d{1,2}|%\\*|%{2,}|%\\d{1,2})?';
var enumeration = '(\\*{1,2})?';
var symbol = "(:".concat(SYMBOL, "|[#|@]").concat(SYMBOL, ")?");
// const symbol = /((?:\:[a-zA-Z0-9_\-\$\.\[\]"\s]*(?:\s*\:\s*[a-zA-Z0-9_\s-\$\.]*)*)*|[#|@][a-zA-Z0-9_\-\$\.\[\]"\s]*)?/g;
// const symbol = `((?:\\:${SYMBOL}${ARG_SEPARATOR}${ARG_NAME})*|[#|@]${SYMBOL})?`;
var constraint = (0, _concat["default"])(_context = (0, _concat["default"])(_context2 = "([!|\\?](?:[=|~]".concat(SYMBOL, "(?:").concat(WS, "\\:")).call(_context2, WS)).call(_context, SOURCE_NAME, ")*)?)?");
var query = '((?:\\+|\\-)\\d*)?';
var operators = (0, _concat["default"])(_context3 = (0, _concat["default"])(_context4 = (0, _concat["default"])(_context5 = (0, _concat["default"])(_context6 = (0, _concat["default"])(_context7 = (0, _concat["default"])(_context8 = (0, _concat["default"])(_context9 = (0, _concat["default"])(_context10 = (0, _concat["default"])(_context11 = "".concat(WS).concat(inception)).call(_context11, OWS)).call(_context10, enumeration)).call(_context9, OWS)).call(_context8, symbol)).call(_context7, OWS)).call(_context6, constraint)).call(_context5, OWS)).call(_context4, query)).call(_context3, OWS);
var operatorsRegex = new RegExp(operators, 'g'); // consider multi line flag `m`, unicode `u` and sticky `y`
placeholder.operators = operatorsRegex;
placeholder.operatorNames = ['inception', 'enumerate', 'symbol', 'constraints', 'query'];
var PIPE_SEPARATOR = '\\s*\\|\\s*';
var FUNCTION_NAME = '[a-zA-Z0-9_\\-\\$\\.]+';
var SPREAD_OPERATOR = '\\*{1,2}';
var pipes = (0, _concat["default"])(_context12 = (0, _concat["default"])(_context13 = (0, _concat["default"])(_context14 = "(?:".concat(PIPE_SEPARATOR, ")((?:").concat(FUNCTION_NAME, "|")).call(_context14, SPREAD_OPERATOR, ")(?:")).call(_context13, ARG_SEPARATOR)).call(_context12, ARG_NAME, ")*)"); // https://regex101.com/r/n2qnj7/6
var pipesRegex = new RegExp(pipes, 'g'); // consider multi line flag `m`, unicode `u` and sticky `y`
placeholder.pipes = pipesRegex;
/**
* regex place holder, a.k.a reph parser
*
* NOTE: the source placeholder can be repeated within the template-string, e.g. "{{x.y}} = {{x.y}}"
* reph() would consume one only, effectively optimizing by removing the need to deref twice within the same scope
* later when the dereffed value is replaced in the string, a //g regex is used and would cover all identical occurrences
*
* @param source
* @param operators
* @param path
* @param pipes
* @param meta
* @returns {*}
*/
var reph = function reph() {
var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [],
_ref2 = (0, _slicedToArray2["default"])(_ref, 2),
source = _ref2[0],
_ref2$ = _ref2[1];
_ref2$ = _ref2$ === void 0 ? [] : _ref2$;
var _ref2$2 = (0, _slicedToArray2["default"])(_ref2$, 3),
_ref2$2$ = _ref2$2[0];
_ref2$2$ = _ref2$2$ === void 0 ? [] : _ref2$2$;
var _ref2$2$2 = (0, _slicedToArray2["default"])(_ref2$2$, 1),
operators = _ref2$2$2[0],
_ref2$2$3 = _ref2$2[1];
_ref2$2$3 = _ref2$2$3 === void 0 ? [] : _ref2$2$3;
var _ref2$2$4 = (0, _slicedToArray2["default"])(_ref2$2$3, 1),
path = _ref2$2$4[0],
_ref2$2$5 = _ref2$2[2];
_ref2$2$5 = _ref2$2$5 === void 0 ? [] : _ref2$2$5;
var _ref2$2$6 = (0, _slicedToArray2["default"])(_ref2$2$5, 1),
pipes = _ref2$2$6[0];
var meta = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
var ast = {
source: source,
value: null,
'@meta': meta
};
if (F.isEmptyValue(path)) {
ast.value = source;
return F.reduced(ast);
}
ast['@meta']++;
if (operators) {
operators = sx.tokenize(placeholder.operators, operators, {
tokenNames: placeholder.operatorNames
});
operators['@meta'] = ++ast['@meta'];
ast.operators = operators;
}
if (pipes) {
pipes = sx.tokenize(placeholder.pipes, pipes, {
sequence: true
});
pipes['@meta'] = ++ast['@meta'];
ast.pipes = pipes;
}
return _objectSpread(_objectSpread({}, ast), {}, {
path: path
});
};
function rephs(text) {
var meta = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
var ast = {
source: text,
value: null,
'@meta': meta
};
var regex = new RegExp(placeholder.full.source, 'g');
var matches = sx.tokenize(regex, text, {
$n: false,
sequence: true,
cgindex: true,
cgi0: true
});
if (F.isEmptyValue(matches)) {
ast.value = text;
return F.reduced(ast);
}
return (0, _map["default"])(F).call(F, reph, F.iterator(matches, {
indexed: true,
kv: true
}));
}
module.exports = {
operatorsRegex: operatorsRegex,
operators: operatorsRegex.source,
pipesRegex: pipesRegex,
pipes: pipesRegex.source,
fullPlaceholderRegex: fullPlaceholderRegex,
fullPlaceholder: fullPlaceholderRegex.source,
parse: rephs
};