@dream2023/data-mapping
Version:
@dream2023/data-mapping is a perfect object mapping solution。
612 lines (505 loc) • 16.2 kB
JavaScript
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.dataMapping = {}));
}(this, (function (exports) { 'use strict';
// 合并对象
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;
}
const isObject = value => typeof value === 'object' && value !== null;
// Customized for this use-case
const isObjectCustom = value =>
isObject(value) &&
!(value instanceof RegExp) &&
!(value instanceof Error) &&
!(value instanceof Date);
const mapObject = (object, mapper, options, isSeen = new WeakMap()) => {
options = {
deep: false,
target: {},
...options
};
if (isSeen.has(object)) {
return isSeen.get(object);
}
isSeen.set(object, options.target);
const {target} = options;
delete options.target;
const mapArray = array => array.map(element => isObjectCustom(element) ? mapObject(element, mapper, options, isSeen) : element);
if (Array.isArray(object)) {
return mapArray(object);
}
for (const [key, value] of Object.entries(object)) {
let [newKey, newValue] = mapper(key, value, object);
if (options.deep && isObjectCustom(newValue)) {
newValue = Array.isArray(newValue) ?
mapArray(newValue) :
mapObject(newValue, mapper, options, isSeen);
}
target[newKey] = newValue;
}
return target;
};
var mapObj = (object, mapper, options) => {
if (!isObject(object)) {
throw new TypeError(`Expected an object, got \`${object}\` (${typeof object})`);
}
return mapObject(object, mapper, options);
};
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 = mapObj(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);
}
exports.clearDelimiters = clearDelimiters;
exports.clearFilters = clearFilters;
exports.compilerStr = compilerStr;
exports.dataMapping = dataMapping;
exports.getDelimiters = getDelimiters;
exports.getFilters = getFilters;
exports.isNil = isNil;
exports.mergeObj = mergeObj;
exports.parseFilters = parseFilters;
exports.parseText = parseText;
exports.replace$ = replace$;
exports.setDelimiters = setDelimiters;
exports.setFilter = setFilter;
exports.setFilters = setFilters;
Object.defineProperty(exports, '__esModule', { value: true });
})));