///
///
///
///
// TODO: Use the `URL` global when targeting Node.js 10
// tslint:disable-next-line
const URLGlobal = typeof URL === 'undefined' ? require('url').URL : URL;
type TypedArray = Int8Array | Uint8Array | Uint8ClampedArray | Int16Array | Uint16Array | Int32Array | Uint32Array | Float32Array | Float64Array;
type Primitive = null | undefined | string | number | boolean | Symbol;
export interface ArrayLike {
length: number;
}
export type Class = new(...args: any[]) => T;
type DomElement = object & { nodeType: 1; nodeName: string };
type NodeStream = object & { pipe: Function };
export const enum TypeName {
null = 'null',
boolean = 'boolean',
undefined = 'undefined',
string = 'string',
number = 'number',
symbol = 'symbol',
Function = 'Function',
GeneratorFunction = 'GeneratorFunction',
AsyncFunction = 'AsyncFunction',
Observable = 'Observable',
Array = 'Array',
Buffer = 'Buffer',
Object = 'Object',
RegExp = 'RegExp',
Date = 'Date',
Error = 'Error',
Map = 'Map',
Set = 'Set',
WeakMap = 'WeakMap',
WeakSet = 'WeakSet',
Int8Array = 'Int8Array',
Uint8Array = 'Uint8Array',
Uint8ClampedArray = 'Uint8ClampedArray',
Int16Array = 'Int16Array',
Uint16Array = 'Uint16Array',
Int32Array = 'Int32Array',
Uint32Array = 'Uint32Array',
Float32Array = 'Float32Array',
Float64Array = 'Float64Array',
ArrayBuffer = 'ArrayBuffer',
SharedArrayBuffer = 'SharedArrayBuffer',
DataView = 'DataView',
Promise = 'Promise',
URL = 'URL'
}
const toString = Object.prototype.toString;
const isOfType = (type: string) => (value: unknown): value is T => typeof value === type;
const isBuffer = (input: unknown): input is Buffer => !is.nullOrUndefined(input) && !is.nullOrUndefined((input as Buffer).constructor) && is.function_((input as Buffer).constructor.isBuffer) && (input as Buffer).constructor.isBuffer(input);
const getObjectType = (value: unknown): TypeName | null => {
const objectName = toString.call(value).slice(8, -1);
if (objectName) {
return objectName as TypeName;
}
return null;
};
const isObjectOfType = (type: TypeName) => (value: unknown): value is T => getObjectType(value) === type;
function is(value: unknown): TypeName { // tslint:disable-line:only-arrow-functions
switch (value) {
case null:
return TypeName.null;
case true:
case false:
return TypeName.boolean;
default:
}
switch (typeof value) {
case 'undefined':
return TypeName.undefined;
case 'string':
return TypeName.string;
case 'number':
return TypeName.number;
case 'symbol':
return TypeName.symbol;
default:
}
if (is.function_(value)) {
return TypeName.Function;
}
if (is.observable(value)) {
return TypeName.Observable;
}
if (Array.isArray(value)) {
return TypeName.Array;
}
if (isBuffer(value)) {
return TypeName.Buffer;
}
const tagType = getObjectType(value);
if (tagType) {
return tagType;
}
if (value instanceof String || value instanceof Boolean || value instanceof Number) {
throw new TypeError('Please don\'t use object wrappers for primitive types');
}
return TypeName.Object;
}
// tslint:disable-next-line:strict-type-predicates
const isObject = (value: unknown): value is object => typeof value === 'object';
is.undefined = isOfType('undefined');
is.string = isOfType('string');
is.number = isOfType('number');
is.function_ = isOfType('function');
// tslint:disable-next-line:strict-type-predicates
is.null_ = (value: unknown): value is null => value === null;
is.class_ = (value: unknown): value is Class => is.function_(value) && value.toString().startsWith('class ');
is.boolean = (value: unknown): value is boolean => value === true || value === false;
is.symbol = isOfType('symbol');
// tslint:enable:variable-name
is.numericString = (value: unknown): boolean =>
is.string(value) && value.length > 0 && !Number.isNaN(Number(value));
is.array = Array.isArray;
is.buffer = isBuffer;
is.nullOrUndefined = (value: unknown): value is null | undefined => is.null_(value) || is.undefined(value);
is.object = (value: unknown): value is object => !is.nullOrUndefined(value) && (is.function_(value) || isObject(value));
is.iterable = (value: unknown): value is IterableIterator => !is.nullOrUndefined(value) && is.function_((value as IterableIterator)[Symbol.iterator]);
is.asyncIterable = (value: unknown): value is AsyncIterableIterator => !is.nullOrUndefined(value) && is.function_((value as AsyncIterableIterator)[Symbol.asyncIterator]);
is.generator = (value: unknown): value is Generator => is.iterable(value) && is.function_(value.next) && is.function_(value.throw);
is.nativePromise = (value: unknown): value is Promise =>
isObjectOfType>(TypeName.Promise)(value);
const hasPromiseAPI = (value: unknown): value is Promise =>
!is.null_(value) &&
isObject(value) as unknown &&
is.function_((value as Promise).then) &&
is.function_((value as Promise).catch);
is.promise = (value: unknown): value is Promise => is.nativePromise(value) || hasPromiseAPI(value);
is.generatorFunction = isObjectOfType(TypeName.GeneratorFunction);
is.asyncFunction = isObjectOfType(TypeName.AsyncFunction);
is.boundFunction = (value: unknown): value is Function => is.function_(value) && !value.hasOwnProperty('prototype');
is.regExp = isObjectOfType(TypeName.RegExp);
is.date = isObjectOfType(TypeName.Date);
is.error = isObjectOfType(TypeName.Error);
is.map = (value: unknown): value is Map => isObjectOfType