UNPKG

@dream2023/data-mapping

Version:

@dream2023/data-mapping is a perfect object mapping solution。

538 lines (446 loc) 13.3 kB
import mapObject from 'map-obj'; // 合并对象 function mergeObj(target, source) { var sourceKeys = Object.keys(source); var targetKeys = Object.keys(target); sourceKeys.forEach(function (sourceKey) { if (!targetKeys.includes(sourceKey)) { target[sourceKey] = source[sourceKey]; } }); return target; } // 替换 $ 符号 function replace$(target) { if (Object.prototype.toString.call(target['$']) === '[object Object]') { // 展开对象 target = mergeObj(target, target['$']); delete target['$']; } return target; } // 是否为 undefined 或者 null var isNil = function isNil(val) { return val === undefined || val === null; }; function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread2(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } var _filters = {}; var _delimiters; // 设置过滤函数 function setFilters(filters) { _filters = _objectSpread2(_objectSpread2({}, _filters), filters); } // 设置单个过滤函数 function setFilter(name, filter) { _filters[name] = filter; } // 获取过滤函数 function getFilters() { return _filters; } // 清除 filters function clearFilters() { _filters = {}; } // 设置变量分隔符 function setDelimiters(delimiters) { _delimiters = delimiters; } // 获取分隔符 function getDelimiters() { return _delimiters; } // 清除分隔符 function clearDelimiters() { _delimiters = undefined; } var validDivisionCharRE = /[\w).+\-_$\]]/; function parseFilters(exp) { var inSingle = false; var inDouble = false; var inTemplateString = false; var inRegex = false; var curly = 0; var square = 0; var paren = 0; var lastFilterIndex = 0; var c, prev, i, expression, filters; for (i = 0; i < exp.length; i++) { prev = c; c = exp.charCodeAt(i); if (inSingle) { if (c === 0x27 && prev !== 0x5c) inSingle = false; } else if (inDouble) { if (c === 0x22 && prev !== 0x5c) inDouble = false; } else if (inTemplateString) { if (c === 0x60 && prev !== 0x5c) inTemplateString = false; } else if (inRegex) { if (c === 0x2f && prev !== 0x5c) inRegex = false; } else if (c === 0x7c && // pipe exp.charCodeAt(i + 1) !== 0x7c && exp.charCodeAt(i - 1) !== 0x7c && !curly && !square && !paren) { if (expression === undefined) { // first filter, end of expression lastFilterIndex = i + 1; expression = exp.slice(0, i).trim(); } else { pushFilter(); } } else { switch (c) { case 0x22: inDouble = true; break; // " case 0x27: inSingle = true; break; // ' case 0x60: inTemplateString = true; break; // ` case 0x28: paren++; break; // ( case 0x29: paren--; break; // ) case 0x5b: square++; break; // [ case 0x5d: square--; break; // ] case 0x7b: curly++; break; // { case 0x7d: curly--; break; // } } if (c === 0x2f) { // / var j = i - 1; var p = void 0; // find first non-whitespace prev char for (; j >= 0; j--) { p = exp.charAt(j); if (p !== ' ') break; } if (!p || !validDivisionCharRE.test(p)) { inRegex = true; } } } } if (expression === undefined) { expression = exp.slice(0, i).trim(); } else if (lastFilterIndex !== 0) { pushFilter(); } function pushFilter() { (filters || (filters = [])).push(exp.slice(lastFilterIndex, i).trim()); lastFilterIndex = i + 1; } if (filters) { for (i = 0; i < filters.length; i++) { expression = wrapFilter(expression, filters[i]); } } return expression; } function wrapFilter(exp, filter) { var i = filter.indexOf('('); if (i < 0) { return "".concat(filter, "(").concat(exp, ")"); } else { var name = filter.slice(0, i); var args = filter.slice(i + 1); return "".concat(name, "(").concat(exp).concat(args !== ')' ? ',' + args : args); } } var defaultTagRE = /\{\{((?:.|\r?\n)+?)\}\}/g; var regexEscapeRE = /[-.*+?^${}()|[\]/\\]/g; var buildRegex = function buildRegex(delimiters) { var open = delimiters[0].replace(regexEscapeRE, '\\$&'); var close = delimiters[1].replace(regexEscapeRE, '\\$&'); return new RegExp(open + '((?:.|\\n)+?)' + close, 'g'); }; function parseText(text, delimiters) { var tagRE = delimiters ? buildRegex(delimiters) : defaultTagRE; if (!tagRE.test(text)) { return "\"".concat(text, "\""); } var tokens = []; var rawTokens = []; var lastIndex = tagRE.lastIndex = 0; var match, index, tokenValue; while (match = tagRE.exec(text)) { index = match.index; // push text token if (index > lastIndex) { rawTokens.push(tokenValue = text.slice(lastIndex, index)); tokens.push(JSON.stringify(tokenValue)); } // tag token var exp = parseFilters(match[1].trim()); tokens.push(exp); lastIndex = index + match[0].length; } if (lastIndex < text.length) { tokenValue = text.slice(lastIndex); tokens.push(JSON.stringify(tokenValue)); } return tokens.join(' + '); } var global$1 = (typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}); /* from https://github.com/substack/vm-browserify/blob/bfd7c5f59edec856dc7efe0b77a4f6b2fa20f226/index.js MIT license no Copyright holder mentioned */ function Object_keys(obj) { if (Object.keys) return Object.keys(obj) else { var res = []; for (var key in obj) res.push(key); return res; } } function forEach(xs, fn) { if (xs.forEach) return xs.forEach(fn) else for (var i = 0; i < xs.length; i++) { fn(xs[i], i, xs); } } var _defineProp; function defineProp(obj, name, value) { if (typeof _defineProp !== 'function') { _defineProp = createDefineProp; } _defineProp(obj, name, value); } function createDefineProp() { try { Object.defineProperty({}, '_', {}); return function(obj, name, value) { Object.defineProperty(obj, name, { writable: true, enumerable: false, configurable: true, value: value }); }; } catch (e) { return function(obj, name, value) { obj[name] = value; }; } } var globals = ['Array', 'Boolean', 'Date', 'Error', 'EvalError', 'Function', 'Infinity', 'JSON', 'Math', 'NaN', 'Number', 'Object', 'RangeError', 'ReferenceError', 'RegExp', 'String', 'SyntaxError', 'TypeError', 'URIError', 'decodeURI', 'decodeURIComponent', 'encodeURI', 'encodeURIComponent', 'escape', 'eval', 'isFinite', 'isNaN', 'parseFloat', 'parseInt', 'undefined', 'unescape' ]; function Context() {} Context.prototype = {}; function Script(code) { if (!(this instanceof Script)) return new Script(code); this.code = code; } function otherRunInContext(code, context) { var args = Object_keys(global$1); args.push('with (this.__ctx__){return eval(this.__code__)}'); var fn = Function.apply(null, args); return fn.apply({ __code__: code, __ctx__: context }); } Script.prototype.runInContext = function(context) { if (!(context instanceof Context)) { throw new TypeError('needs a \'context\' argument.'); } if (global$1.document) { var iframe = global$1.document.createElement('iframe'); if (!iframe.style) iframe.style = {}; iframe.style.display = 'none'; global$1.document.body.appendChild(iframe); var win = iframe.contentWindow; var wEval = win.eval, wExecScript = win.execScript; if (!wEval && wExecScript) { // win.eval() magically appears when this is called in IE: wExecScript.call(win, 'null'); wEval = win.eval; } forEach(Object_keys(context), function(key) { win[key] = context[key]; }); forEach(globals, function(key) { if (context[key]) { win[key] = context[key]; } }); var winKeys = Object_keys(win); var res = wEval.call(win, this.code); forEach(Object_keys(win), function(key) { // Avoid copying circular objects like `top` and `window` by only // updating existing context properties or new properties in the `win` // that was only introduced after the eval. if (key in context || indexOf(winKeys, key) === -1) { context[key] = win[key]; } }); forEach(globals, function(key) { if (!(key in context)) { defineProp(context, key, win[key]); } }); global$1.document.body.removeChild(iframe); return res; } return otherRunInContext(this.code, context); }; Script.prototype.runInThisContext = function() { var fn = new Function('code', 'return eval(code);'); return fn.call(global$1, this.code); // maybe... }; Script.prototype.runInNewContext = function(context) { var ctx = createContext(context); var res = this.runInContext(ctx); if (context) { forEach(Object_keys(ctx), function(key) { context[key] = ctx[key]; }); } return res; }; function createScript(code) { return new Script(code); } function createContext(context) { if (isContext(context)) { return context; } var copy = new Context(); if (typeof context === 'object') { forEach(Object_keys(context), function(key) { copy[key] = context[key]; }); } return copy; } function runInContext(code, contextifiedSandbox, options) { var script = new Script(code, options); return script.runInContext(contextifiedSandbox, options); } function runInThisContext(code, options) { var script = new Script(code, options); return script.runInThisContext(options); } function isContext(context) { return context instanceof Context; } function runInNewContext(code, sandbox, options) { var script = new Script(code, options); return script.runInNewContext(sandbox, options); } var vm = { runInContext: runInContext, isContext: isContext, createContext: createContext, createScript: createScript, Script: Script, runInThisContext: runInThisContext, runInNewContext: runInNewContext }; /* from indexOf @ author tjholowaychuk @ license MIT */ var _indexOf = [].indexOf; function indexOf(arr, obj){ if (_indexOf) return arr.indexOf(obj); for (var i = 0; i < arr.length; ++i) { if (arr[i] === obj) return i; } return -1; } function compilerStr(str, data, delimiters) { // 如果 str 或者 data 为空,则直接返回字符串 if (isNil(str) || isNil(data)) return str; var exp = parseText(str, delimiters || getDelimiters()); // 字符串和表达式相同,则直接返回字符串 // 否则进行解析,并将数据和过滤器传递进去 return exp === "\"".concat(str, "\"") ? str : vm.runInNewContext(exp, _objectSpread2(_objectSpread2({}, data), getFilters())); } // 对象数据映射 function dataMapping(_ref) { var schema = _ref.schema, data = _ref.data, delimiters = _ref.delimiters, _ref$defaultValue = _ref.defaultValue, defaultValue = _ref$defaultValue === void 0 ? 'schema-data' : _ref$defaultValue; if (isNil(data) || isNil(schema)) { switch (defaultValue) { case 'schema': return schema; case 'data': return data; default: return schema ? schema : data; } } if (typeof schema === 'string') return compilerStr(schema, data, delimiters); if (typeof schema === 'function') return schema(data); // 遍历每个 schema 对象 var res = mapObject(schema, function (key, val) { if (typeof val === 'string') { return [key, compilerStr(val, data, delimiters)]; } else if (typeof val === 'function') { return [key, val(data)]; } else { return [key, val]; } }, { deep: true }); return replace$(res); } export { clearDelimiters, clearFilters, compilerStr, dataMapping, getDelimiters, getFilters, isNil, mergeObj, parseFilters, parseText, replace$, setDelimiters, setFilter, setFilters };