@antv/x6
Version:
JavaScript diagramming library that uses SVG and HTML for rendering
150 lines (130 loc) • 3.27 kB
text/typescript
export {
has,
pick,
merge,
isEqual,
isEmpty,
isObject,
isPlainObject,
clone,
cloneDeep,
defaults,
defaultsDeep,
} from 'lodash-es'
export * from './mixins'
export * from './inherit'
export function ensure<T>(value: T | null | undefined, defaultValue: T) {
return value != null ? value : defaultValue!
}
export function getValue<T>(obj: any, key: string, defaultValue?: T): T | null {
const value = obj != null ? obj[key] : null
return defaultValue !== undefined ? ensure<T>(value, defaultValue) : value
}
export function getNumber(obj: any, key: string, defaultValue: number) {
let value = obj != null ? obj[key] : null
if (value == null) {
return defaultValue
}
value = +value
if (Number.isNaN(value) || !Number.isFinite(value)) {
return defaultValue
}
return value as number
}
export function getBoolean(obj: any, key: string, defaultValue: boolean) {
const value = obj != null ? obj[key] : null
if (value == null) {
return defaultValue
}
return !!value
}
export function isMaliciousProp(prop: string): boolean {
return prop === '__proto__'
}
export function getByPath(
obj: any,
path: string | string[],
delimiter: string | RegExp = '/',
) {
let ret
const keys = Array.isArray(path) ? path : path.split(delimiter)
if (keys.length) {
ret = obj
while (keys.length) {
const key = keys.shift()
if (Object(ret) === ret && key && key in ret) {
ret = ret[key]
} else {
return undefined
}
}
}
return ret
}
export function setByPath(
obj: any,
path: string | string[],
value: any,
delimiter: string | RegExp = '/',
) {
const keys = Array.isArray(path) ? path : path.split(delimiter)
const lastKey = keys.pop()
if (lastKey && !isMaliciousProp(lastKey)) {
let diver = obj
keys.forEach((key) => {
if (!isMaliciousProp(key)) {
if (diver[key] == null) {
diver[key] = {}
}
diver = diver[key]
}
})
diver[lastKey] = value
}
return obj
}
export function unsetByPath(
obj: any,
path: string | string[],
delimiter: string | RegExp = '/',
) {
const keys = Array.isArray(path) ? path.slice() : path.split(delimiter)
const propertyToRemove = keys.pop()
if (propertyToRemove) {
if (keys.length > 0) {
const parent = getByPath(obj, keys)
if (parent) {
delete parent[propertyToRemove]
}
} else {
delete obj[propertyToRemove]
}
}
return obj
}
// eslint-disable-next-line default-param-last
export function flatten(obj: any, delim = '/', stop?: (val: any) => boolean) {
const ret: { [key: string]: any } = {}
Object.keys(obj).forEach((key) => {
const val = obj[key]
let deep = typeof val === 'object' || Array.isArray(val)
if (deep && stop && stop(val)) {
deep = false
}
if (deep) {
const flatObject = flatten(val, delim, stop)
Object.keys(flatObject).forEach((flatKey) => {
ret[key + delim + flatKey] = flatObject[flatKey]
})
} else {
ret[key] = val
}
})
// eslint-disable-next-line no-restricted-syntax
for (const key in obj) {
if (!Object.prototype.hasOwnProperty.call(obj, key)) {
continue
}
}
return ret
}