From 8e4521496505a19d3f0f9c2778b79979325029d2 Mon Sep 17 00:00:00 2001 From: janryWang Date: Thu, 16 May 2019 00:33:50 +0800 Subject: [PATCH] feat(@uform/utils): support ts, but build scripts is not work --- packages/utils/src/accessor.js | 483 -------------------------------- packages/utils/src/accessor.ts | 20 +- packages/utils/src/array.js | 126 --------- packages/utils/src/array.ts | 11 +- packages/utils/src/broadcast.js | 56 ---- packages/utils/src/broadcast.ts | 17 +- packages/utils/src/case.js | 3 - packages/utils/src/case.ts | 6 +- packages/utils/src/clone.js | 63 ----- packages/utils/src/clone.ts | 24 +- packages/utils/src/compare.js | 102 ------- packages/utils/src/compare.ts | 21 +- packages/utils/src/defer.js | 13 - packages/utils/src/defer.ts | 4 +- packages/utils/src/index.js | 11 - packages/utils/src/isEmpty.js | 81 ------ packages/utils/src/isEmpty.ts | 28 +- packages/utils/src/lru.js | 310 -------------------- packages/utils/src/lru.ts | 52 ++-- packages/utils/src/schema.js | 110 -------- packages/utils/src/schema.ts | 51 +++- packages/utils/src/types.js | 10 - packages/utils/src/types.ts | 4 +- 23 files changed, 128 insertions(+), 1478 deletions(-) delete mode 100644 packages/utils/src/accessor.js delete mode 100644 packages/utils/src/array.js delete mode 100644 packages/utils/src/broadcast.js delete mode 100644 packages/utils/src/case.js delete mode 100644 packages/utils/src/clone.js delete mode 100644 packages/utils/src/compare.js delete mode 100644 packages/utils/src/defer.js delete mode 100644 packages/utils/src/index.js delete mode 100644 packages/utils/src/isEmpty.js delete mode 100644 packages/utils/src/lru.js delete mode 100644 packages/utils/src/schema.js delete mode 100644 packages/utils/src/types.js diff --git a/packages/utils/src/accessor.js b/packages/utils/src/accessor.js deleted file mode 100644 index cdc48656993..00000000000 --- a/packages/utils/src/accessor.js +++ /dev/null @@ -1,483 +0,0 @@ -import { isStr, isNum, isPlainObj, isArr, isObj } from './types' -import { map, each, every } from './array' -import { LRUMap } from './lru' -function whitespace(c) { - return c === ' ' || c === '\n' || c === '\t' || c === '\f' || c === '\r' -} - -function toString(val) { - if (!val) return '' - if (isArr(val)) { - return val.join('.') - } - return isStr(val) ? val : '' -} - -const PathCache = new LRUMap(1000) - -export function getPathSegments(path) { - if (isArr(path)) return path - if (isStr(path) && path) { - const cached = PathCache.get(path) - if (cached) return cached - const pathArr = path.split('.') - const parts = [] - - for (let i = 0; i < pathArr.length; i++) { - let p = pathArr[i] - - while (p[p.length - 1] === '\\' && pathArr[i + 1] !== undefined) { - p = p.slice(0, -1) + '.' - p += pathArr[++i] - } - - parts.push(p) - } - PathCache.set(path, parts) - return parts - } - if (isNum(path)) return [path] - return [] -} - -class DestructTokenizer { - constructor(text, cbs) { - this.text = text - this.index = 0 - this.cbs = cbs - this.state = this.processNameStart - this.declareNameStart = 0 - this.declareNameEnd = 0 - this.nbraceCount = 0 - this.nbracketCount = 0 - } - - goto(name) { - this.state = this.StateMap[name] - } - - parse() { - let char = '' - let prev = '' - let l = this.text.length - for (; this.index < l; this.index++) { - char = this.text.charAt(this.index) - this.EOF = l - 1 === this.index - this.state(char, prev) - prev = char - } - } - - processNameStart(char) { - if (char === '{' || char === '[') { - this.state = this.processDestructStart - this.index-- - } else if (!whitespace(char)) { - this.declareNameStart = this.index - this.state = this.processName - } - } - - processName(char, prev) { - if (whitespace(char)) { - this.declareNameEnd = this.index - this.cbs.name(this.getName()) - } else if (this.EOF) { - this.declareNameEnd = this.index + 1 - this.cbs.name(this.getName()) - } - } - - processDestructStart(char) { - if (char === '{') { - this.nbraceCount++ - this.cbs.destructObjectStart() - } else if (char === '[') { - this.nbracketCount++ - this.cbs.destructArrayStart() - } else if (!whitespace(char)) { - this.state = this.processDestructKey - this.destructKeyStart = this.index - this.index-- - } - } - - processDestructKey(char, prev) { - if (char === '}') { - this.nbraceCount-- - - if (this.nbraceCount || this.nbracketCount) { - this.state = this.processDestructStart - } - if (!whitespace(prev)) { - this.destructKey = this.text.substring( - this.destructKeyStart, - this.index - ) - } - - this.cbs.destructKey(this.destructKey) - this.cbs.destructObjectEnd() - if (!this.nbraceCount && !this.nbracketCount) { - this.index = this.text.length - } - } else if (char === ']') { - this.nbracketCount-- - - if (this.nbraceCount || this.nbracketCount) { - this.state = this.processDestructStart - } - if (!whitespace(prev)) { - this.destructKey = this.text.substring( - this.destructKeyStart, - this.index - ) - } - this.cbs.destructKey(this.destructKey) - this.cbs.destructArrayEnd() - if (!this.nbraceCount && !this.nbracketCount) { - this.index = this.text.length - } - } else if (whitespace(char) || char === ':' || char === ',') { - if (!whitespace(prev)) { - this.destructKey = this.text.substring( - this.destructKeyStart, - this.index - ) - } - if (!whitespace(char)) { - this.state = this.processDestructStart - this.cbs.destructKey(this.destructKey, char === ':') - } - } - } - - getName() { - return this.text.substring(this.declareNameStart, this.declareNameEnd) - } -} - -const parseDestruct = string => { - if (!isStr(string)) return string - - let destruct - let stack = [] - let token = '' - let realKey = '' - let lastDestruct - let root - - new DestructTokenizer(string, { - name(key) { - root = key - }, - destructKey(key, readyReplace) { - if (!key) return - token = key - if (readyReplace) { - realKey = key - lastDestruct = destruct - return - } - if (isArr(destruct)) { - destruct.push(key) - } else if (isPlainObj(destruct)) { - destruct[realKey && lastDestruct === destruct ? realKey : key] = key - } - realKey = '' - lastDestruct = destruct - }, - destructArrayStart() { - if (!destruct) { - root = [] - destruct = root - } else { - destruct = [] - } - const tail = stack[stack.length - 1] - if (isPlainObj(tail)) { - tail[token] = destruct - } else if (isArr(tail)) { - tail.push(destruct) - } - stack.push(destruct) - }, - destructObjectStart() { - if (!destruct) { - root = {} - destruct = root - } else { - destruct = {} - } - const tail = stack[stack.length - 1] - if (isPlainObj(tail)) { - tail[token] = destruct - } else if (isArr(tail)) { - tail.push(destruct) - } - stack.push(destruct) - }, - destructArrayEnd() { - stack.pop() - destruct = stack[stack.length - 1] - }, - destructObjectEnd() { - stack.pop() - destruct = stack[stack.length - 1] - } - }).parse() - return root -} - -const traverse = (obj, callback) => { - const _traverse = (obj, path, callback) => { - if (isStr(obj)) return callback(obj, obj) - each(obj, (item, key) => { - const _path = path.concat(key) - if (isArr(item) || isPlainObj(item)) { - _traverse(item, _path, callback) - } else { - callback(_path, item) - } - }) - } - - return _traverse(obj, [], callback) -} - -const mapReduce = (obj, callback) => { - const _traverse = (obj, path, callback) => { - return map(obj, (item, key) => { - const _path = path.concat(key) - if (isArr(item) || isPlainObj(item)) { - return _traverse(item, _path, callback) - } else { - return callback(_path, _path.slice(0, _path.length - 1).concat(item)) - } - }) - } - - return _traverse(obj, [], callback) -} - -const parseDesturctPath = path => { - const _path = getPathSegments(path) - const lastKey = _path[_path.length - 1] - const startPath = _path.slice(0, _path.length - 1) - const destruct = parseDestruct(lastKey) - return { - path: _path, - lastKey, - startPath, - destruct - } -} - -const parsePaths = path => { - const result = [] - const parsed = parseDesturctPath(path) - if (isStr(parsed.destruct)) { - return path - } else if (parsed.destruct) { - traverse(parsed.destruct, (path, key) => { - result.push({ - path: parsed.startPath.concat(path), - startPath: parsed.startPath, - endPath: path, - key - }) - }) - return result - } else { - return path - } -} - -const resolveGetIn = get => { - const cache = new Map() - return (obj, path, value) => { - let ast = null - if (!(ast = cache.get(path))) { - ast = parseDesturctPath(path) - cache.set(path, ast) - } - if (!isArr(ast.destruct) && !isPlainObj(ast.destruct)) { - return get(obj, path, value) - } - return mapReduce(ast.destruct, (path, key) => { - return get(obj, ast.startPath.concat(key)) - }) - } -} - -const resolveUpdateIn = (update, getIn) => { - const cache = new Map() - return (obj, path, value) => { - let paths = [] - if (!(paths = cache.get(path))) { - paths = parsePaths(path) - cache.set(path, paths) - } - if (!isArr(paths)) return update(obj, path, value) - if (paths && paths.length) { - each(paths, ({ path, key, startPath, endPath }) => { - update(obj, startPath.concat(key), getIn(value, endPath)) - }) - } - return obj - } -} - -const resolveExistIn = has => { - const cache = new Map() - return (obj, path) => { - let paths = [] - if (!(paths = cache.get(path))) { - paths = parsePaths(path) - cache.set(path, paths) - } - if (!isArr(paths)) { - return has(obj, path) - } - if (paths && paths.length) { - return every(paths, ({ startPath, key }) => { - return has(obj, startPath.concat(key)) - }) - } - - return false - } -} - -function _getIn(obj, path, value) { - if (!isObj(obj) || !path) { - return obj - } - - path = toString(path) - - if (path in obj) { - return obj[path] - } - - const pathArr = getPathSegments(path) - - for (let i = 0; i < pathArr.length; i++) { - if (!Object.prototype.propertyIsEnumerable.call(obj, pathArr[i])) { - return value - } - - obj = obj[pathArr[i]] - - if (obj === undefined || obj === null) { - // `obj` is either `undefined` or `null` so we want to stop the loop, and - // if this is not the last bit of the path, and - // if it did't return `undefined` - // it would return `null` if `obj` is `null` - // but we want `get({foo: null}, 'foo.bar')` to equal `undefined`, or the supplied value, not `null` - if (i !== pathArr.length - 1) { - return value - } - - break - } - } - - return obj -} - -function _setIn(obj, path, value) { - if (!isObj(obj) || !path) { - return - } - - path = toString(path) - - if (path in obj) { - obj[path] = value - return - } - - const pathArr = getPathSegments(path) - - for (let i = 0; i < pathArr.length; i++) { - const p = pathArr[i] - - if (!isObj(obj[p])) { - obj[p] = {} - } - - if (i === pathArr.length - 1) { - obj[p] = value - } - - obj = obj[p] - } -} - -function _deleteIn(obj, path) { - if (!isObj(obj) || !path) { - return - } - - path = toString(path) - - if (path in obj) { - delete obj[path] - return - } - - const pathArr = getPathSegments(path) - - for (let i = 0; i < pathArr.length; i++) { - const p = pathArr[i] - - if (i === pathArr.length - 1) { - if (isArr(obj)) { - obj.splice(p, 1) - } else { - delete obj[p] - } - return - } - - obj = obj[p] - - if (!isObj(obj)) { - return - } - } -} - -function _existIn(obj, path) { - if (!isObj(obj) || !path) { - return false - } - - path = toString(path) - - if (path in obj) { - return true - } - - const pathArr = getPathSegments(path) - - for (let i = 0; i < pathArr.length; i++) { - if (isObj(obj)) { - if (!(pathArr[i] in obj)) { - return false - } - - obj = obj[pathArr[i]] - } else { - return false - } - } - - return true -} -export const getIn = resolveGetIn(_getIn) -export const setIn = resolveUpdateIn(_setIn, getIn) -export const deleteIn = resolveUpdateIn(_deleteIn, getIn) -export const existIn = resolveExistIn(_existIn) -export { parseDesturctPath, parseDestruct, parsePaths } diff --git a/packages/utils/src/accessor.ts b/packages/utils/src/accessor.ts index 77db06dc7a0..0fd3ea063df 100644 --- a/packages/utils/src/accessor.ts +++ b/packages/utils/src/accessor.ts @@ -11,14 +11,14 @@ type TokenizerHandlers = { destructKey(str: string, isColon?: boolean): void } +export type Path = Array | string + type Destruct = { [key: string]: string } | Path type TraverseCallback = (path: string[], item: any) => void -type Path = Path - type Getter = (obj: any, path: Path, value?: any) => any type Setter = (obj: any, path: Path, value?: any) => any @@ -274,7 +274,7 @@ const parseDestruct = (string: string | number) => { } const traverse = (obj: any, callback: TraverseCallback) => { - const _traverse = (obj: any, path: Path, callback: TraverseCallback) => { + const _traverse = (obj: any, path: string[], callback: TraverseCallback) => { if (isStr(obj)) return callback(obj, obj) each(obj, (item: any, key: string) => { const _path = path.concat(key) @@ -290,7 +290,7 @@ const traverse = (obj: any, callback: TraverseCallback) => { } const mapReduce = (obj: any, callback: TraverseCallback) => { - const _traverse = (obj: any, path: Path, callback: TraverseCallback) => { + const _traverse = (obj: any, path: string[], callback: TraverseCallback) => { return map(obj, (item: any, key: string) => { const _path = path.concat(key) if (isArr(item) || isPlainObj(item)) { @@ -304,7 +304,7 @@ const mapReduce = (obj: any, callback: TraverseCallback) => { return _traverse(obj, [], callback) } -const parseDesturctPath = (path: Path) => { +const parseDesturctPath = (path: Path): any => { const _path = getPathSegments(path) const lastKey = _path[_path.length - 1] const startPath = _path.slice(0, _path.length - 1) @@ -317,7 +317,7 @@ const parseDesturctPath = (path: Path) => { } } -const parsePaths = (path: Path) => { +const parsePaths = (path: Path): any => { const result = [] const parsed = parseDesturctPath(path) if (isStr(parsed.destruct)) { @@ -339,7 +339,7 @@ const parsePaths = (path: Path) => { const resolveGetIn = (get: Getter) => { const cache = new Map() - return (obj: any, path: Path, value: any): any => { + return (obj: any, path: Path, value?: any): any => { let ast = null if (!(ast = cache.get(path))) { ast = parseDesturctPath(path) @@ -401,7 +401,7 @@ function _getIn(obj: any, path: Path, value: any) { path = toString(path) if (path in obj) { - return obj[path] + return obj[path as string] } const pathArr = getPathSegments(path) @@ -438,7 +438,7 @@ function _setIn(obj: any, path: Path, value: any) { path = toString(path) if (path in obj) { - obj[path] = value + obj[path as string] = value return } @@ -467,7 +467,7 @@ function _deleteIn(obj: any, path: Path) { path = toString(path) if (path in obj) { - delete obj[path] + delete obj[path as string] return } diff --git a/packages/utils/src/array.js b/packages/utils/src/array.js deleted file mode 100644 index f34000369dd..00000000000 --- a/packages/utils/src/array.js +++ /dev/null @@ -1,126 +0,0 @@ -import { isArr } from './types' - -export const toArr = val => (isArr(val) ? val : val ? [val] : []) - -export const each = (val, callback, revert) => { - if (isArr(val)) { - if (revert) { - for (let i = val.length - 1; i >= 0; i--) { - if (callback(val[i], i) === false) { - return - } - } - } else { - for (let i = 0, length = val.length; i < length; i++) { - if (callback(val[i], i) === false) { - return - } - } - } - } else { - for (let key in val) { - if (Object.hasOwnProperty.call(val, key)) { - if (callback(val[key], key) === false) { - return - } - } - } - } -} - -export const map = (val, callback, revert) => { - let res = isArr(val) ? [] : {} - each( - val, - (item, key) => { - const value = callback(item, key) - if (isArr(res)) { - res.push(value) - } else { - res[key] = value - } - }, - revert - ) - return res -} - -export const reduce = (val, callback, initial, revert) => { - let res = initial - each( - val, - (item, key) => { - res = callback(res, item, key) - }, - revert - ) - return res -} - -export const every = (val, callback, revert) => { - let res = false - each( - val, - (item, key) => { - if (!callback(item, key)) { - res = false - return false - } else { - res = true - } - }, - revert - ) - return res -} - -export const some = (val, callback, revert) => { - let res = true - each( - val, - (item, key) => { - if (callback(item, key)) { - res = true - return false - } else { - res = false - } - }, - revert - ) - return res -} - -export const findIndex = (val, callback, revert) => { - let res = -1 - each( - val, - (item, key) => { - if (callback(item, key)) { - res = key - return false - } - }, - revert - ) - return res -} - -export const find = (val, callback, revert) => { - let res - each( - val, - (item, key) => { - if (callback(item, key)) { - res = item - return false - } - }, - revert - ) - return res -} - -export const includes = (val, searchElement, revert) => { - return some(val, item => item === searchElement, revert) -} diff --git a/packages/utils/src/array.ts b/packages/utils/src/array.ts index a05a1f1793e..44454d3b4de 100644 --- a/packages/utils/src/array.ts +++ b/packages/utils/src/array.ts @@ -2,6 +2,8 @@ import { isArr } from './types' type EachCallback = (item: any, key: string | number) => void | boolean +type ReduceCallback = (buffer: any, item: any, key: string | number) => void | boolean + type ArrayLike = object | Array export const toArr = (val: any): Array => (isArr(val) ? val : val ? [val] : []) @@ -9,20 +11,21 @@ export const toArr = (val: any): Array => (isArr(val) ? val : val ? [val] : export const each = (val: ArrayLike, callback: EachCallback, revert?: boolean) => { if (isArr(val)) { if (revert) { - for (let i = (val as Array).length - 1; i >= 0; i--) { + for (let i: number = (val as Array).length - 1; i >= 0; i--) { if (callback(val[i], i) === false) { return } } } else { - for (let i = 0, length = (val as Array).length; i < length; i++) { + for (let i: number = 0, length = (val as Array).length; i < length; i++) { if (callback(val[i], i) === false) { return } } } } else { - for (let key in val) { + let key: string + for (key in val) { if (Object.hasOwnProperty.call(val, key)) { if (callback(val[key], key) === false) { return @@ -49,7 +52,7 @@ export const map = (val: ArrayLike, callback: EachCallback, revert?: boolean): A return res } -export const reduce = (val: ArrayLike, callback: EachCallback, initial: any, revert?: boolean): any => { +export const reduce = (val: ArrayLike, callback: ReduceCallback, initial: any, revert?: boolean): any => { let res = initial each( val, diff --git a/packages/utils/src/broadcast.js b/packages/utils/src/broadcast.js deleted file mode 100644 index 7de51da50e2..00000000000 --- a/packages/utils/src/broadcast.js +++ /dev/null @@ -1,56 +0,0 @@ -import { each } from './array' -import { isFn } from './types' - -export class Broadcast { - entries = [] - buffer = [] - - subscribe(subscriber, subscription) { - if (!isFn(subscriber)) return () => {} - let index = this.entries.length - this.entries.push({ - subscriber, - subscription - }) - this.flushBuffer(this.entries[index]) - return () => { - this.entries.splice(index, 1) - } - } - - unsubscribe() { - this.entries.length = 0 - this.buffer.length = 0 - } - - flushBuffer({ subscriber, subscription }) { - each(this.buffer, ({ payload, filter }) => { - if (isFn(filter)) { - let notification - if ((notification = filter(payload, subscription))) { - subscriber(notification) - } - } else { - subscriber(payload, subscription) - } - }) - } - - notify(payload, filter) { - if (this.length === 0) { - this.buffer.push({ payload, filter }) - return - } - each(this.entries, ({ subscriber, subscription }) => { - if (isFn(filter)) { - let notification - if ((notification = filter(payload, subscription))) { - subscriber(notification) - } - } else { - subscriber(payload, subscription) - } - }) - this.buffer.length = 0 - } -} diff --git a/packages/utils/src/broadcast.ts b/packages/utils/src/broadcast.ts index efae155fba0..42c305ad844 100644 --- a/packages/utils/src/broadcast.ts +++ b/packages/utils/src/broadcast.ts @@ -1,11 +1,16 @@ import { each } from './array' import { isFn } from './types' +type Subscriber = (notification: any) => void + +type Filter = (payload: any, subscription: any) => any + export class Broadcast { - entries = [] - buffer = [] + private entries = [] + private buffer = [] + private length: number - subscribe(subscriber, subscription) { + subscribe(subscriber: Subscriber, subscription: any) { if (!isFn(subscriber)) return () => { } let index = this.entries.length this.entries.push({ @@ -26,7 +31,7 @@ export class Broadcast { flushBuffer({ subscriber, subscription }) { each(this.buffer, ({ payload, filter }) => { if (isFn(filter)) { - let notification + let notification: any if ((notification = filter(payload, subscription))) { subscriber(notification) } @@ -36,14 +41,14 @@ export class Broadcast { }) } - notify(payload, filter) { + notify(payload: any, filter: Filter) { if (this.length === 0) { this.buffer.push({ payload, filter }) return } each(this.entries, ({ subscriber, subscription }) => { if (isFn(filter)) { - let notification + let notification: any if ((notification = filter(payload, subscription))) { subscriber(notification) } diff --git a/packages/utils/src/case.js b/packages/utils/src/case.js deleted file mode 100644 index 3bd4f659dbd..00000000000 --- a/packages/utils/src/case.js +++ /dev/null @@ -1,3 +0,0 @@ -export const camelCase = require('camel-case') - -export const lowercase = str => String(str || '').toLowerCase() diff --git a/packages/utils/src/case.ts b/packages/utils/src/case.ts index 3bd4f659dbd..f373fce13aa 100644 --- a/packages/utils/src/case.ts +++ b/packages/utils/src/case.ts @@ -1,3 +1,5 @@ -export const camelCase = require('camel-case') +import camelCase from 'camel-case' +export { camelCase } -export const lowercase = str => String(str || '').toLowerCase() + +export const lowercase = (str: any) => String(str || '').toLowerCase() diff --git a/packages/utils/src/clone.js b/packages/utils/src/clone.js deleted file mode 100644 index b9993b03ca6..00000000000 --- a/packages/utils/src/clone.js +++ /dev/null @@ -1,63 +0,0 @@ -import { isFn } from './types' - -const self = this || global || window - -const NATIVE_KEYS = [ - ['Map', map => new Map(map)], - ['WeakMap', map => new WeakMap(map)], - ['WeakSet', set => new WeakSet(set)], - ['Set', set => new Set(set)], - 'FileList', - 'File', - 'URL', - 'RegExp', - [ - 'Promise', - promise => new Promise((resolve, reject) => promise.then(resolve, reject)) - ] -] - -const isNativeObject = values => { - for (let i = 0; i < NATIVE_KEYS.length; i++) { - let item = NATIVE_KEYS[i] - if (Array.isArray(item) && item[0]) { - if (self[item[0]] && values instanceof self[item[0]]) { - return item[1] ? item[1] : item[0] - } - } else { - if (self[item] && values instanceof self[item]) { - return item - } - } - } -} - -export const clone = (values, filter) => { - let _nativeClone - if (Array.isArray(values)) { - return values.map(item => clone(item, filter)) - } else if ((_nativeClone = isNativeObject(values))) { - return isFn(_nativeClone) ? _nativeClone(values) : values - } else if (typeof values === 'object' && !!values) { - if ('$$typeof' in values && '_owner' in values) { - return values - } - let res = {} - for (let key in values) { - if (Object.hasOwnProperty.call(values, key)) { - if (isFn(filter)) { - if (filter(values[key], key)) { - res[key] = clone(values[key], filter) - } else { - res[key] = values[key] - } - } else { - res[key] = clone(values[key], filter) - } - } - } - return res - } else { - return values - } -} diff --git a/packages/utils/src/clone.ts b/packages/utils/src/clone.ts index b9993b03ca6..4a485d09c92 100644 --- a/packages/utils/src/clone.ts +++ b/packages/utils/src/clone.ts @@ -1,39 +1,41 @@ import { isFn } from './types' -const self = this || global || window +type Filter = (value: any, key: string) => any + +const self: { [key: string]: any } = this || global || window const NATIVE_KEYS = [ - ['Map', map => new Map(map)], - ['WeakMap', map => new WeakMap(map)], - ['WeakSet', set => new WeakSet(set)], - ['Set', set => new Set(set)], + ['Map', (map: any) => new Map(map)], + ['WeakMap', (map: any) => new WeakMap(map)], + ['WeakSet', (set: any) => new WeakSet(set)], + ['Set', (set: any) => new Set(set)], 'FileList', 'File', 'URL', 'RegExp', [ 'Promise', - promise => new Promise((resolve, reject) => promise.then(resolve, reject)) + (promise: Promise) => new Promise((resolve, reject) => promise.then(resolve, reject)) ] ] -const isNativeObject = values => { +const isNativeObject = (values: any) : any => { for (let i = 0; i < NATIVE_KEYS.length; i++) { let item = NATIVE_KEYS[i] if (Array.isArray(item) && item[0]) { - if (self[item[0]] && values instanceof self[item[0]]) { + if (self[item[0] as string] && values instanceof self[item[0] as string]) { return item[1] ? item[1] : item[0] } } else { - if (self[item] && values instanceof self[item]) { + if (self[item as string] && values instanceof self[item as string]) { return item } } } } -export const clone = (values, filter) => { - let _nativeClone +export const clone = (values: any, filter: Filter) => { + let _nativeClone: (values: any) => any if (Array.isArray(values)) { return values.map(item => clone(item, filter)) } else if ((_nativeClone = isNativeObject(values))) { diff --git a/packages/utils/src/compare.js b/packages/utils/src/compare.js deleted file mode 100644 index 5cb8f6cd76c..00000000000 --- a/packages/utils/src/compare.js +++ /dev/null @@ -1,102 +0,0 @@ -import { isFn, isArr } from './types' -var isArray = isArr -var keyList = Object.keys -var hasProp = Object.prototype.hasOwnProperty -/* eslint-disable */ -function equal(a, b, filter) { - // fast-deep-equal index.js 2.0.1 - if (a === b) return true - - if (a && b && typeof a === 'object' && typeof b === 'object') { - var arrA = isArray(a) - var arrB = isArray(b) - var i - var length - var key - - if (arrA && arrB) { - length = a.length - if (length !== b.length) return false - for (i = length; i-- !== 0; ) if (!equal(a[i], b[i], filter)) return false - return true - } - - if (arrA != arrB) return false - - var dateA = a instanceof Date - var dateB = b instanceof Date - if (dateA != dateB) return false - if (dateA && dateB) return a.getTime() == b.getTime() - - var regexpA = a instanceof RegExp - var regexpB = b instanceof RegExp - if (regexpA != regexpB) return false - if (regexpA && regexpB) return a.toString() == b.toString() - var urlA = a instanceof URL - var urlB = b instanceof URL - if (urlA && urlB) return urlA.href == urlB.href - var keys = keyList(a) - length = keys.length - - if (length !== keyList(b).length) return false - - for (i = length; i-- !== 0; ) if (!hasProp.call(b, keys[i])) return false - // end fast-deep-equal - - // Custom handling for React - for (i = length; i-- !== 0; ) { - key = keys[i] - if (key === '_owner' && a.$$typeof) { - // React-specific: avoid traversing React elements' _owner. - // _owner contains circular references - // and is not needed when comparing the actual elements (and not their owners) - // .$$typeof and ._store on just reasonable markers of a react element - continue - } else { - if (isFn(filter)) { - if (filter({ a: a[key], b: b[key] }, key)) { - if (!equal(a[key], b[key], filter)) return false - } - } else { - // all other properties should be traversed as usual - if (!equal(a[key], b[key], filter)) return false - } - } - } - - // fast-deep-equal index.js 2.0.1 - return true - } - - if (a && b && typeof a === 'function' && typeof b === 'function') { - return a.toString() === b.toString() - } - - return a !== a && b !== b -} -// end fast-deep-equal - -export const isEqual = function exportedEqual(a, b, filter) { - try { - return equal(a, b, filter) - } catch (error) { - if ( - (error.message && error.message.match(/stack|recursion/i)) || - error.number === -2146828260 - ) { - // warn on circular references, don't crash - // browsers give this different errors name and messages: - // chrome/safari: "RangeError", "Maximum call stack size exceeded" - // firefox: "InternalError", too much recursion" - // edge: "Error", "Out of stack space" - console.warn( - 'Warning: react-fast-compare does not handle circular references.', - error.name, - error.message - ) - return false - } - // some other error. we should definitely know about these - throw error - } -} diff --git a/packages/utils/src/compare.ts b/packages/utils/src/compare.ts index 5cb8f6cd76c..5075dd43f5a 100644 --- a/packages/utils/src/compare.ts +++ b/packages/utils/src/compare.ts @@ -2,22 +2,25 @@ import { isFn, isArr } from './types' var isArray = isArr var keyList = Object.keys var hasProp = Object.prototype.hasOwnProperty + +type Filter = (comparies: { a: any, b: any }, key: string) => boolean + /* eslint-disable */ -function equal(a, b, filter) { +function equal(a: any, b: any, filter: Filter) { // fast-deep-equal index.js 2.0.1 if (a === b) return true if (a && b && typeof a === 'object' && typeof b === 'object') { var arrA = isArray(a) var arrB = isArray(b) - var i - var length - var key + var i: number + var length: number + var key: string | number if (arrA && arrB) { length = a.length if (length !== b.length) return false - for (i = length; i-- !== 0; ) if (!equal(a[i], b[i], filter)) return false + for (i = length; i-- !== 0;) if (!equal(a[i], b[i], filter)) return false return true } @@ -34,17 +37,17 @@ function equal(a, b, filter) { if (regexpA && regexpB) return a.toString() == b.toString() var urlA = a instanceof URL var urlB = b instanceof URL - if (urlA && urlB) return urlA.href == urlB.href + if (urlA && urlB) return a.href == b.href var keys = keyList(a) length = keys.length if (length !== keyList(b).length) return false - for (i = length; i-- !== 0; ) if (!hasProp.call(b, keys[i])) return false + for (i = length; i-- !== 0;) if (!hasProp.call(b, keys[i])) return false // end fast-deep-equal // Custom handling for React - for (i = length; i-- !== 0; ) { + for (i = length; i-- !== 0;) { key = keys[i] if (key === '_owner' && a.$$typeof) { // React-specific: avoid traversing React elements' _owner. @@ -76,7 +79,7 @@ function equal(a, b, filter) { } // end fast-deep-equal -export const isEqual = function exportedEqual(a, b, filter) { +export const isEqual = function exportedEqual(a: any, b: any, filter: Filter) { try { return equal(a, b, filter) } catch (error) { diff --git a/packages/utils/src/defer.js b/packages/utils/src/defer.js deleted file mode 100644 index d6f48f4637d..00000000000 --- a/packages/utils/src/defer.js +++ /dev/null @@ -1,13 +0,0 @@ -export const defer = () => { - let _resolve - let _reject - const promise = new Promise((resolve, reject) => { - _resolve = resolve - _reject = reject - }) - return { - promise, - resolve: _resolve, - reject: _reject - } -} diff --git a/packages/utils/src/defer.ts b/packages/utils/src/defer.ts index d6f48f4637d..35df20a0a47 100644 --- a/packages/utils/src/defer.ts +++ b/packages/utils/src/defer.ts @@ -1,6 +1,6 @@ export const defer = () => { - let _resolve - let _reject + let _resolve: (payload: any) => void + let _reject: (error: any) => void const promise = new Promise((resolve, reject) => { _resolve = resolve _reject = reject diff --git a/packages/utils/src/index.js b/packages/utils/src/index.js deleted file mode 100644 index eb391ebb342..00000000000 --- a/packages/utils/src/index.js +++ /dev/null @@ -1,11 +0,0 @@ -export * from './accessor' -export * from './array' -export * from './compare' -export * from './broadcast' -export * from './types' -export * from './clone' -export * from './schema' -export * from './lru' -export * from './isEmpty' -export * from './case' -export * from './defer' diff --git a/packages/utils/src/isEmpty.js b/packages/utils/src/isEmpty.js deleted file mode 100644 index 2e40411b51c..00000000000 --- a/packages/utils/src/isEmpty.js +++ /dev/null @@ -1,81 +0,0 @@ -/** - * copyright by https://github.com/ianstormtaylor/is-empty - */ - -/** - * Has own property. - * - * @type {Function} - */ - -var has = Object.prototype.hasOwnProperty - -/** - * To string. - * - * @type {Function} - */ - -var toString = Object.prototype.toString - -/** - * Test whether a value is "empty". - * - * @param {Mixed} val - * @return {Boolean} - */ - -export function isEmpty(val) { - // Null and Undefined... - if (val == null) return true - - // Booleans... - if (typeof val === 'boolean') return false - - // Numbers... - if (typeof val === 'number') return false - - // Strings... - if (typeof val === 'string') return val.length === 0 - - // Functions... - if (typeof val === 'function') return val.length === 0 - - // Arrays... - if (Array.isArray(val)) { - if (val.length === 0) return true - for (let i = 0; i < val.length; i++) { - if (val[i] !== undefined && val[i] !== null && val[i] !== '' && val[i] !== 0) { - return false - } - } - return true - } - - // Errors... - if (val instanceof Error) return val.message === '' - - // Objects... - if (val.toString === toString) { - switch (val.toString()) { - // Maps, Sets, Files and Errors... - case '[object File]': - case '[object Map]': - case '[object Set]': { - return val.size === 0 - } - - // Plain objects... - case '[object Object]': { - for (var key in val) { - if (has.call(val, key)) return false - } - - return true - } - } - } - - // Anything else... - return false -} diff --git a/packages/utils/src/isEmpty.ts b/packages/utils/src/isEmpty.ts index 2e40411b51c..56d81fad190 100644 --- a/packages/utils/src/isEmpty.ts +++ b/packages/utils/src/isEmpty.ts @@ -1,31 +1,9 @@ -/** - * copyright by https://github.com/ianstormtaylor/is-empty - */ -/** - * Has own property. - * - * @type {Function} - */ +const has = Object.prototype.hasOwnProperty -var has = Object.prototype.hasOwnProperty +const toString = Object.prototype.toString -/** - * To string. - * - * @type {Function} - */ - -var toString = Object.prototype.toString - -/** - * Test whether a value is "empty". - * - * @param {Mixed} val - * @return {Boolean} - */ - -export function isEmpty(val) { +export function isEmpty(val: any): boolean { // Null and Undefined... if (val == null) return true diff --git a/packages/utils/src/lru.js b/packages/utils/src/lru.js deleted file mode 100644 index 1a0ff9a576a..00000000000 --- a/packages/utils/src/lru.js +++ /dev/null @@ -1,310 +0,0 @@ -/** - * A doubly linked list-based Least Recently Used (LRU) cache. Will keep most - * recently used items while discarding least recently used items when its limit - * is reached. - * - * Licensed under MIT. Copyright (c) 2010 Rasmus Andersson - * See README.md for details. - * - * Illustration of the design: - * - * entry entry entry entry - * ______ ______ ______ ______ - * | head |.newer => | |.newer => | |.newer => | tail | - * | A | | B | | C | | D | - * |______| <= older.|______| <= older.|______| <= older.|______| - * - * removed <-- <-- <-- <-- <-- <-- <-- <-- <-- <-- <-- added - */ -/* eslint-disable */ - -const NEWER = Symbol('newer') -const OLDER = Symbol('older') - -export function LRUMap(limit, entries) { - if (typeof limit !== 'number') { - // called as (entries) - entries = limit - limit = 0 - } - - this.size = 0 - this.limit = limit - this.oldest = this.newest = undefined - this._keymap = new Map() - - if (entries) { - this.assign(entries) - if (limit < 1) { - this.limit = this.size - } - } -} - -function Entry(key, value) { - this.key = key - this.value = value - this[NEWER] = undefined - this[OLDER] = undefined -} - -LRUMap.prototype._markEntryAsUsed = function(entry) { - if (entry === this.newest) { - // Already the most recenlty used entry, so no need to update the list - return - } - // HEAD--------------TAIL - // <.older .newer> - // <--- add direction -- - // A B C E - if (entry[NEWER]) { - if (entry === this.oldest) { - this.oldest = entry[NEWER] - } - entry[NEWER][OLDER] = entry[OLDER] // C <-- E. - } - if (entry[OLDER]) { - entry[OLDER][NEWER] = entry[NEWER] // C. --> E - } - entry[NEWER] = undefined // D --x - entry[OLDER] = this.newest // D. --> E - if (this.newest) { - this.newest[NEWER] = entry // E. <-- D - } - this.newest = entry -} - -LRUMap.prototype.assign = function(entries) { - let entry - let limit = this.limit || Number.MAX_VALUE - this._keymap.clear() - let it = entries[Symbol.iterator]() - for (let itv = it.next(); !itv.done; itv = it.next()) { - let e = new Entry(itv.value[0], itv.value[1]) - this._keymap.set(e.key, e) - if (!entry) { - this.oldest = e - } else { - entry[NEWER] = e - e[OLDER] = entry - } - entry = e - if (limit-- === 0) { - throw new Error('overflow') - } - } - this.newest = entry - this.size = this._keymap.size -} - -LRUMap.prototype.get = function(key) { - // First, find our cache entry - var entry = this._keymap.get(key) - if (!entry) return // Not cached. Sorry. - // As was found in the cache, register it as being requested recently - this._markEntryAsUsed(entry) - return entry.value -} - -LRUMap.prototype.set = function(key, value) { - var entry = this._keymap.get(key) - - if (entry) { - // update existing - entry.value = value - this._markEntryAsUsed(entry) - return this - } - - // new entry - this._keymap.set(key, (entry = new Entry(key, value))) - - if (this.newest) { - // link previous tail to the new tail (entry) - this.newest[NEWER] = entry - entry[OLDER] = this.newest - } else { - // we're first in -- yay - this.oldest = entry - } - - // add new entry to the end of the linked list -- it's now the freshest entry. - this.newest = entry - ++this.size - if (this.size > this.limit) { - // we hit the limit -- remove the head - this.shift() - } - - return this -} - -LRUMap.prototype.shift = function() { - // todo: handle special case when limit == 1 - var entry = this.oldest - if (entry) { - if (this.oldest[NEWER]) { - // advance the list - this.oldest = this.oldest[NEWER] - this.oldest[OLDER] = undefined - } else { - // the cache is exhausted - this.oldest = undefined - this.newest = undefined - } - // Remove last strong reference to and remove links from the purged - // entry being returned: - entry[NEWER] = entry[OLDER] = undefined - this._keymap.delete(entry.key) - --this.size - return [entry.key, entry.value] - } -} - -// ---------------------------------------------------------------------------- -// Following code is optional and can be removed without breaking the core -// functionality. - -LRUMap.prototype.find = function(key) { - let e = this._keymap.get(key) - return e ? e.value : undefined -} - -LRUMap.prototype.has = function(key) { - return this._keymap.has(key) -} - -LRUMap.prototype['delete'] = function(key) { - var entry = this._keymap.get(key) - if (!entry) return - this._keymap.delete(entry.key) - if (entry[NEWER] && entry[OLDER]) { - // relink the older entry with the newer entry - entry[OLDER][NEWER] = entry[NEWER] - entry[NEWER][OLDER] = entry[OLDER] - } else if (entry[NEWER]) { - // remove the link to us - entry[NEWER][OLDER] = undefined - // link the newer entry to head - this.oldest = entry[NEWER] - } else if (entry[OLDER]) { - // remove the link to us - entry[OLDER][NEWER] = undefined - // link the newer entry to head - this.newest = entry[OLDER] - } else { - // if(entry[OLDER] === undefined && entry.newer === undefined) { - this.oldest = this.newest = undefined - } - - this.size-- - return entry.value -} - -LRUMap.prototype.clear = function() { - // Not clearing links should be safe, as we don't expose live links to user - this.oldest = this.newest = undefined - this.size = 0 - this._keymap.clear() -} - -function EntryIterator(oldestEntry) { - this.entry = oldestEntry -} -EntryIterator.prototype[Symbol.iterator] = function() { - return this -} -EntryIterator.prototype.next = function() { - let ent = this.entry - if (ent) { - this.entry = ent[NEWER] - return { done: false, value: [ent.key, ent.value] } - } else { - return { done: true, value: undefined } - } -} - -function KeyIterator(oldestEntry) { - this.entry = oldestEntry -} -KeyIterator.prototype[Symbol.iterator] = function() { - return this -} -KeyIterator.prototype.next = function() { - let ent = this.entry - if (ent) { - this.entry = ent[NEWER] - return { done: false, value: ent.key } - } else { - return { done: true, value: undefined } - } -} - -function ValueIterator(oldestEntry) { - this.entry = oldestEntry -} -ValueIterator.prototype[Symbol.iterator] = function() { - return this -} -ValueIterator.prototype.next = function() { - let ent = this.entry - if (ent) { - this.entry = ent[NEWER] - return { done: false, value: ent.value } - } else { - return { done: true, value: undefined } - } -} - -LRUMap.prototype.keys = function() { - return new KeyIterator(this.oldest) -} - -LRUMap.prototype.values = function() { - return new ValueIterator(this.oldest) -} - -LRUMap.prototype.entries = function() { - return this -} - -LRUMap.prototype[Symbol.iterator] = function() { - return new EntryIterator(this.oldest) -} - -LRUMap.prototype.forEach = function(fun, thisObj) { - if (typeof thisObj !== 'object') { - thisObj = this - } - let entry = this.oldest - while (entry) { - fun.call(thisObj, entry.value, entry.key, this) - entry = entry[NEWER] - } -} - -/** Returns a JSON (array) representation */ -LRUMap.prototype.toJSON = function() { - var s = new Array(this.size) - var i = 0 - var entry = this.oldest - while (entry) { - s[i++] = { key: entry.key, value: entry.value } - entry = entry[NEWER] - } - return s -} - -/** Returns a String representation */ -LRUMap.prototype.toString = function() { - var s = '' - var entry = this.oldest - while (entry) { - s += String(entry.key) + ':' + entry.value - entry = entry[NEWER] - if (entry) { - s += ' < ' - } - } - return s -} diff --git a/packages/utils/src/lru.ts b/packages/utils/src/lru.ts index 1a0ff9a576a..72cc9b0f64b 100644 --- a/packages/utils/src/lru.ts +++ b/packages/utils/src/lru.ts @@ -21,7 +21,7 @@ const NEWER = Symbol('newer') const OLDER = Symbol('older') -export function LRUMap(limit, entries) { +export function LRUMap(limit: number, entries?: any) { if (typeof limit !== 'number') { // called as (entries) entries = limit @@ -41,14 +41,14 @@ export function LRUMap(limit, entries) { } } -function Entry(key, value) { +function Entry(key: any, value: any) { this.key = key this.value = value this[NEWER] = undefined this[OLDER] = undefined } -LRUMap.prototype._markEntryAsUsed = function(entry) { +LRUMap.prototype._markEntryAsUsed = function (entry: any) { if (entry === this.newest) { // Already the most recenlty used entry, so no need to update the list return @@ -74,8 +74,8 @@ LRUMap.prototype._markEntryAsUsed = function(entry) { this.newest = entry } -LRUMap.prototype.assign = function(entries) { - let entry +LRUMap.prototype.assign = function (entries: any) { + let entry: any let limit = this.limit || Number.MAX_VALUE this._keymap.clear() let it = entries[Symbol.iterator]() @@ -97,7 +97,7 @@ LRUMap.prototype.assign = function(entries) { this.size = this._keymap.size } -LRUMap.prototype.get = function(key) { +LRUMap.prototype.get = function (key: any) { // First, find our cache entry var entry = this._keymap.get(key) if (!entry) return // Not cached. Sorry. @@ -106,7 +106,7 @@ LRUMap.prototype.get = function(key) { return entry.value } -LRUMap.prototype.set = function(key, value) { +LRUMap.prototype.set = function (key: any, value: any) { var entry = this._keymap.get(key) if (entry) { @@ -139,7 +139,7 @@ LRUMap.prototype.set = function(key, value) { return this } -LRUMap.prototype.shift = function() { +LRUMap.prototype.shift = function () { // todo: handle special case when limit == 1 var entry = this.oldest if (entry) { @@ -165,16 +165,16 @@ LRUMap.prototype.shift = function() { // Following code is optional and can be removed without breaking the core // functionality. -LRUMap.prototype.find = function(key) { +LRUMap.prototype.find = function (key: any) { let e = this._keymap.get(key) return e ? e.value : undefined } -LRUMap.prototype.has = function(key) { +LRUMap.prototype.has = function (key: any) { return this._keymap.has(key) } -LRUMap.prototype['delete'] = function(key) { +LRUMap.prototype['delete'] = function (key: any) { var entry = this._keymap.get(key) if (!entry) return this._keymap.delete(entry.key) @@ -201,20 +201,20 @@ LRUMap.prototype['delete'] = function(key) { return entry.value } -LRUMap.prototype.clear = function() { +LRUMap.prototype.clear = function () { // Not clearing links should be safe, as we don't expose live links to user this.oldest = this.newest = undefined this.size = 0 this._keymap.clear() } -function EntryIterator(oldestEntry) { +function EntryIterator(oldestEntry: any) { this.entry = oldestEntry } -EntryIterator.prototype[Symbol.iterator] = function() { +EntryIterator.prototype[Symbol.iterator] = function () { return this } -EntryIterator.prototype.next = function() { +EntryIterator.prototype.next = function () { let ent = this.entry if (ent) { this.entry = ent[NEWER] @@ -227,10 +227,10 @@ EntryIterator.prototype.next = function() { function KeyIterator(oldestEntry) { this.entry = oldestEntry } -KeyIterator.prototype[Symbol.iterator] = function() { +KeyIterator.prototype[Symbol.iterator] = function () { return this } -KeyIterator.prototype.next = function() { +KeyIterator.prototype.next = function () { let ent = this.entry if (ent) { this.entry = ent[NEWER] @@ -243,10 +243,10 @@ KeyIterator.prototype.next = function() { function ValueIterator(oldestEntry) { this.entry = oldestEntry } -ValueIterator.prototype[Symbol.iterator] = function() { +ValueIterator.prototype[Symbol.iterator] = function () { return this } -ValueIterator.prototype.next = function() { +ValueIterator.prototype.next = function () { let ent = this.entry if (ent) { this.entry = ent[NEWER] @@ -256,23 +256,23 @@ ValueIterator.prototype.next = function() { } } -LRUMap.prototype.keys = function() { +LRUMap.prototype.keys = function () { return new KeyIterator(this.oldest) } -LRUMap.prototype.values = function() { +LRUMap.prototype.values = function () { return new ValueIterator(this.oldest) } -LRUMap.prototype.entries = function() { +LRUMap.prototype.entries = function () { return this } -LRUMap.prototype[Symbol.iterator] = function() { +LRUMap.prototype[Symbol.iterator] = function () { return new EntryIterator(this.oldest) } -LRUMap.prototype.forEach = function(fun, thisObj) { +LRUMap.prototype.forEach = function (fun: (value: any, key: any, ctx: object) => void, thisObj: any) { if (typeof thisObj !== 'object') { thisObj = this } @@ -284,7 +284,7 @@ LRUMap.prototype.forEach = function(fun, thisObj) { } /** Returns a JSON (array) representation */ -LRUMap.prototype.toJSON = function() { +LRUMap.prototype.toJSON = function () { var s = new Array(this.size) var i = 0 var entry = this.oldest @@ -296,7 +296,7 @@ LRUMap.prototype.toJSON = function() { } /** Returns a String representation */ -LRUMap.prototype.toString = function() { +LRUMap.prototype.toString = function () { var s = '' var entry = this.oldest while (entry) { diff --git a/packages/utils/src/schema.js b/packages/utils/src/schema.js deleted file mode 100644 index de3596334cd..00000000000 --- a/packages/utils/src/schema.js +++ /dev/null @@ -1,110 +0,0 @@ -import { each, toArr } from './array' -import { getIn, setIn } from './accessor' -import { isFn } from './types' -import { isEmpty } from './isEmpty' -const numberRE = /^\d+$/ -const VIRTUAL_BOXES = {} - -export const getSchemaNodeFromPath = (schema, path) => { - let res = schema - let suc = 0 - path = toArr(path) - for (let i = 0; i < path.length; i++) { - var key = path[i] - if (res && !isEmpty(res.properties)) { - res = res.properties[key] - suc++ - } else if (res && !isEmpty(res.items) && numberRE.test(key)) { - res = res.items - suc++ - } - } - return suc === path.length ? res : undefined -} - -export const schemaIs = (schema, type) => { - return schema && schema.type === type -} - -export const isVirtualBox = name => { - return !!VIRTUAL_BOXES[name] -} - -export const registerVirtualboxFlag = name => { - VIRTUAL_BOXES[name] = true -} - -const isVirtualBoxSchema = schema => { - return isVirtualBox(schema['type']) || isVirtualBox(schema['x-component']) -} - -const schemaTraverse = (schema, callback, path = [], schemaPath = []) => { - if (schema) { - if (isVirtualBoxSchema(schema)) { - path = path.slice(0, path.length - 1) - } - callback(schema, { path, schemaPath }) - if (schemaIs(schema, 'object') || schema.properties) { - each(schema.properties, (schema, key) => { - schemaTraverse( - schema, - callback, - path.concat(key), - schemaPath.concat(key) - ) - }) - } else if (schemaIs(schema, 'array') || schema.items) { - if (schema.items) { - callback( - schema.items, - index => { - schemaTraverse( - schema.items, - callback, - path.concat(index), - schemaPath.concat(index) - ) - }, - path - ) - } - } - } -} - -export const caculateSchemaInitialValues = ( - schema, - initialValues, - callback -) => { - initialValues = initialValues || schema.default || {} - schemaTraverse(schema, (schema, $path, parentPath) => { - const defaultValue = schema.default - if (isFn($path) && parentPath) { - each(toArr(getIn(initialValues, parentPath)), function(value, index) { - $path(index) - }) - } else if ($path) { - const isVirtualBox = isVirtualBoxSchema(schema) - const name = isVirtualBox - ? $path.schemaPath.join('.') - : $path.path.join('.') - const path = isVirtualBox ? $path.schemaPath : $path.path - const schemaPath = $path.schemaPath - const initialValue = getIn(initialValues, name) - let value = !isEmpty(initialValue) ? initialValue : defaultValue - if (!isEmpty(value)) { - setIn(initialValues, name, value) - } - if (isFn(callback)) { - const _path = { - name, - path, - schemaPath - } - callback(_path, schema, value) - } - } - }) - return initialValues -} diff --git a/packages/utils/src/schema.ts b/packages/utils/src/schema.ts index de3596334cd..067602c7a08 100644 --- a/packages/utils/src/schema.ts +++ b/packages/utils/src/schema.ts @@ -1,11 +1,36 @@ import { each, toArr } from './array' -import { getIn, setIn } from './accessor' +import { getIn, setIn, Path } from './accessor' import { isFn } from './types' import { isEmpty } from './isEmpty' const numberRE = /^\d+$/ const VIRTUAL_BOXES = {} -export const getSchemaNodeFromPath = (schema, path) => { +type traverseCallback = (schema: Schema, payload: any, path?: Path) => void + +type PathInfo = { + name: string + path: string[] + schemaPath: string[] +} + +export type Schema = { + type?: string + title?: string + description?: string + default?: any + properties?: { + [key: string]: Schema + } + items?: Schema + minItems?: number + maxItems?: number + ['x-props']: object + ['x-index']: number + ['x-component']: string + ['x-effect']: (dispatch: any) => { [key: string]: any } +} + +export const getSchemaNodeFromPath = (schema: Schema, path: Path) => { let res = schema let suc = 0 path = toArr(path) @@ -14,7 +39,7 @@ export const getSchemaNodeFromPath = (schema, path) => { if (res && !isEmpty(res.properties)) { res = res.properties[key] suc++ - } else if (res && !isEmpty(res.items) && numberRE.test(key)) { + } else if (res && !isEmpty(res.items) && numberRE.test(key as string)) { res = res.items suc++ } @@ -22,7 +47,7 @@ export const getSchemaNodeFromPath = (schema, path) => { return suc === path.length ? res : undefined } -export const schemaIs = (schema, type) => { +export const schemaIs = (schema: Schema, type: string) => { return schema && schema.type === type } @@ -30,15 +55,15 @@ export const isVirtualBox = name => { return !!VIRTUAL_BOXES[name] } -export const registerVirtualboxFlag = name => { +export const registerVirtualboxFlag = (name: string) => { VIRTUAL_BOXES[name] = true } -const isVirtualBoxSchema = schema => { +const isVirtualBoxSchema = (schema: Schema) => { return isVirtualBox(schema['type']) || isVirtualBox(schema['x-component']) } -const schemaTraverse = (schema, callback, path = [], schemaPath = []) => { +const schemaTraverse = (schema: Schema, callback: traverseCallback, path: Array = [], schemaPath = []) => { if (schema) { if (isVirtualBoxSchema(schema)) { path = path.slice(0, path.length - 1) @@ -49,7 +74,7 @@ const schemaTraverse = (schema, callback, path = [], schemaPath = []) => { schemaTraverse( schema, callback, - path.concat(key), + path.concat(key as string), schemaPath.concat(key) ) }) @@ -57,7 +82,7 @@ const schemaTraverse = (schema, callback, path = [], schemaPath = []) => { if (schema.items) { callback( schema.items, - index => { + (index: number | string) => { schemaTraverse( schema.items, callback, @@ -73,15 +98,15 @@ const schemaTraverse = (schema, callback, path = [], schemaPath = []) => { } export const caculateSchemaInitialValues = ( - schema, - initialValues, - callback + schema: Schema, + initialValues: any, + callback: (pathInfo: PathInfo, schema: Schema, value: any) => void ) => { initialValues = initialValues || schema.default || {} schemaTraverse(schema, (schema, $path, parentPath) => { const defaultValue = schema.default if (isFn($path) && parentPath) { - each(toArr(getIn(initialValues, parentPath)), function(value, index) { + each(toArr(getIn(initialValues, parentPath)), function (value, index) { $path(index) }) } else if ($path) { diff --git a/packages/utils/src/types.js b/packages/utils/src/types.js deleted file mode 100644 index 357a74b2547..00000000000 --- a/packages/utils/src/types.js +++ /dev/null @@ -1,10 +0,0 @@ -const isType = type => obj => - obj != null && Object.prototype.toString.call(obj) === `[object ${type}]` -export const isFn = isType('Function') -export const isArr = Array.isArray || isType('Array') -export const isPlainObj = isType('Object') -export const isStr = isType('String') -export const isBool = isType('Boolean') -export const isNum = isType('Number') -export const isObj = val => typeof val === 'object' -export const isRegExp = isType('RegExp') diff --git a/packages/utils/src/types.ts b/packages/utils/src/types.ts index 357a74b2547..351e8a44dd3 100644 --- a/packages/utils/src/types.ts +++ b/packages/utils/src/types.ts @@ -1,4 +1,4 @@ -const isType = type => obj => +const isType = (type: string) => (obj: any) => obj != null && Object.prototype.toString.call(obj) === `[object ${type}]` export const isFn = isType('Function') export const isArr = Array.isArray || isType('Array') @@ -6,5 +6,5 @@ export const isPlainObj = isType('Object') export const isStr = isType('String') export const isBool = isType('Boolean') export const isNum = isType('Number') -export const isObj = val => typeof val === 'object' +export const isObj = (val: any) => typeof val === 'object' export const isRegExp = isType('RegExp')