@schema-render/core-react
Version:
Through a set of simple JSON Schema, efficiently build a set of forms.
175 lines (174 loc) • 4.71 kB
JavaScript
import assert from "./assert";
import { hasOwnProperty } from "./base";
import { isArray, isFunction, isNumber, isObject, isPlainObject, isString } from "./checking";
/**
* fork from https://github.com/lukeed/klona/blob/master/src/json.js
* @param val input JSON Value
* @returns cloned JSON Value
*/ export function cloneDeep(val) {
let k, out, tmp;
if (Array.isArray(val)) {
out = Array(k = val.length);
while(k--)out[k] = (tmp = val[k]) && typeof tmp === 'object' ? cloneDeep(tmp) : tmp;
return out;
}
if (Object.prototype.toString.call(val) === '[object Object]') {
out = {};
for(k in val){
if (k === '__proto__') {
Object.defineProperty(out, k, {
value: cloneDeep(val[k]),
configurable: true,
enumerable: true,
writable: true
});
} else {
out[k] = (tmp = val[k]) && typeof tmp === 'object' ? cloneDeep(tmp) : tmp;
}
}
return out;
}
return val;
}
export function mapKeys(obj, fn) {
if (!isPlainObject(obj) || !isFunction(fn)) {
return {};
}
const keys = Object.keys(obj);
const result = {};
keys.map((key)=>{
const value = obj[key];
const newKey = fn(value, key);
result[newKey] = value;
});
return result;
}
export function pick(obj, ...keys) {
const result = {};
if (!isPlainObject(obj)) {
return result;
}
keys.map((key)=>{
if (hasOwnProperty(obj, key)) {
result[key] = obj[key];
}
});
return result;
}
export function omit(obj, ...keys) {
if (!isPlainObject(obj)) {
return {};
}
const result = {
...obj
};
keys.map((key)=>{
if (hasOwnProperty(obj, key)) {
delete result[key];
}
});
return result;
}
// ref https://github.com/you-dont-need/You-Dont-Need-Lodash-Underscore#_dropRight
export function dropRight(arr, n = 1) {
if (!isArray(arr)) {
return [];
}
return arr.slice(0, n > 0 ? n * -1 : arr.length);
}
export function find(arr, predicate, fromIndex = 0) {
if (!isArray(arr)) {
return undefined;
}
const length = arr.length;
for(let i = fromIndex; i < length; i++){
const item = arr[i];
if (isFunction(predicate)) {
if (predicate(item)) {
return item;
}
} else if (isPlainObject(predicate)) {
if (isMatch(item, predicate)) {
return item;
}
}
}
}
export function isMatch(obj, source) {
if (!isPlainObject(obj)) {
return true;
}
const keys = Object.keys(source);
for(let i = 0; i < keys.length; i++){
const key = keys[i];
if (!hasOwnProperty(obj, key) || source[key] !== obj[key]) {
return false;
}
}
return true;
}
export function get(obj, path) {
if (!isPlainObject(obj) || !isArray(path)) {
return undefined;
}
let value = obj;
for(let i = 0; i < path.length; i++){
const filed = path[i];
if (value) {
value = value[filed];
} else {
return undefined;
}
}
return value;
}
/**
* fork from https://github.com/lodash/lodash/blob/4.17.21-es/_isIndex.js
*/ const regIsUint = /^(?:0|[1-9]\d*)$/;
function isIndex(value) {
return isNumber(value) || regIsUint.test(value);
}
/**
* fork from https://github.com/lodash/lodash/blob/4.17.21-es/_baseSet.js
*/ export function set(obj, path, value) {
if (!isPlainObject(obj)) {
return obj;
}
const length = path.length;
const lastIndex = length - 1;
let index = -1;
let nested = obj;
while(nested !== null && ++index < length){
const key = path[index];
let newValue = value;
if (index !== lastIndex) {
const objValue = nested[key];
newValue = isObject(objValue) ? objValue : isIndex(path[index + 1]) ? [] : {};
}
nested[key] = newValue;
nested = nested[key];
}
return obj;
}
export function debounce(func, wait) {
if (!isFunction(func)) {
assert.fail('Expected a function');
}
let timeout;
function debounced(...args) {
clearTimeout(timeout);
timeout = setTimeout(()=>{
return func.apply(this, args);
}, wait);
}
debounced.cancel = ()=>{
clearTimeout(timeout);
};
return debounced;
}
export function toLower(str) {
if (isString(str)) {
return str.toLowerCase();
}
return '';
}