Repository URL to install this package:
|
Version:
4.0.1 ▾
|
import {
isFrozen,
isSealed,
isArguments,
isArray,
isCircular,
isAsyncish,
isCollection,
isClass,
isDate,
isError,
isElement,
isEmpty,
isFunction,
isFlattenable,
isGenerator,
// not named is
hasIn,
ownPropertyIs,
// back to it
isNegativeInfinity,
isIterator,
isIn,
isInfinity,
isInteger,
isJSON,
isMap,
isNullOrUndefined,
isNull,
isNumber,
isObj,
isPrimitive,
isPromise,
isPrototypeOf,
isRegExp,
isStringOrNumber,
isInfinite,
isString,
isSet,
isSymbol,
isUndefined,
isURL,
isWeakMap,
isWeakSet,
isZeroish,
isBuiltIn,
isNative,
isSafe,
isNonEmptyArray,
} from 'exotic'
function mapArray(value: any, coercer: Function) {
return value.map(coercer)
}
function fromFunctionToStringAndSource(value: Function) {
try {
const functionAsString = Function.prototype.call(value)
return functionAsString
? `${value.toString()} { ${functionAsString} }`
: value.toString()
} catch (toStringException) {
return value.toString()
}
}
function fromFunctionToString(value: Function) {
const functionWithSource = fromFunctionToStringAndSource(value)
const star = isGenerator(value) ? ' *' : ''
const asyncd = isAsyncish(value) ? ' async' : ''
const fnValues = Object.keys(value).length > 0 ? fromObjToString(value) : ''
return asyncd + star + ' ' + functionWithSource + fnValues
}
function fromErrorToString(error: Error) {
//
}
function fromPromiseToString(value: Promise<any>) {
const NOT_RESOLVED = Symbol('@@EMPTY')
let resolved: any = NOT_RESOLVED
value
.then(value => {
resolved = value
})
.catch(error => {
resolved = `Error!(${error})`
})
function latePromiseToString() {
return `Promise(${resolved === NOT_RESOLVED ? 'unresolved' : resolved})`
}
return {
[Symbol.toPrimitive](type) {
return latePromiseToString()
},
toString() {
return latePromiseToString()
},
}
}
function fromObjToString(value: any) {
if (isCircular(value)) {
return '[Circular]'
}
const stringified = {}
Object.keys(value).forEach(key => {
stringified[key] = castToString(value[key])
if (isFrozen(value[key])) {
stringified[key] = `Frozen(${stringified[key]})`
} else if (isSealed(value[key])) {
stringified[key] = `Sealed(${stringified[key]})`
}
})
const serialized = JSON.stringify(stringified, undefined, 2)
// Promise()
if (isPromise(value)) {
return fromPromiseToString(value)
}
// class Eh {}
if (isClass(value)) {
return 'Class(' + serialized + ')'
}
// function() { arguments }
else if (isArguments(value)) {
return 'Arguments(' + serialized + ')'
}
// {}, new Object(), Object.create(null)
else {
return serialized
}
}
function fromArrayToString(value: any[]) {
// EMPTY_ARRAY
if (value.length === 0 && Object.isExtensible(value) === false) {
return 'FROZEN_EMPTY_ARRAY'
}
// []
if (value.length === 0) {
return 'EMPTY_ARRAY'
}
// normal
else {
return `${mapArray(
value,
(other: any) => (isNullOrUndefined(other) ? other : castToString(other))
)}`
}
}
function castToString(value) {
// null
if (isNull(value)) {
return 'null'
}
// undefined
else if (isUndefined(value)) {
return 'undefined'
}
// new Number
else if (isBuiltIn(value)) {
return `BuiltIn(${value})`
}
// Exit early for strings to avoid a performance hit in some environments.
else if (isString(value)) {
return value
}
// #
else if (isNumber(value)) {
return `#${value}`
}
// Recursively convert values (susceptible to call stack limits).
else if (isArray(value)) {
return fromArrayToString(value)
}
// proto
else if (isSymbol(value)) {
return Symbol.prototype.toString.call(value)
}
// function toString :s
else if (isFunction(value)) {
return fromFunctionToString(value)
}
// {}
else if (isObj(value)) {
return fromObjToString(value)
}
// -Infinity, -0, 0
else if (isZeroish(value) && isNegativeInfinity(value)) {
return '-0'
}
// Set(), Map()
else if (isCollection(value)) {
throw new TypeError('need to support collections')
}
// e.g. ?
else {
throw new TypeError('what type? ' + value)
// throw new TypeError('what type? ' + toTypeTag(value))
// return String(value)
}
}
export const stringify = (x: any) => castToString(x)