2018-06-13 22:39:39 +03:00
|
|
|
'use strict';
|
|
|
|
|
2018-06-18 12:42:41 +03:00
|
|
|
export function defineReadOnly(object: any, name: string, value: any): void {
|
2018-06-13 22:39:39 +03:00
|
|
|
Object.defineProperty(object, name, {
|
|
|
|
enumerable: true,
|
|
|
|
value: value,
|
|
|
|
writable: false,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2018-07-26 04:15:43 +03:00
|
|
|
// There are some issues with instanceof with npm link, so we use this
|
|
|
|
// to ensure types are what we expect.
|
|
|
|
|
|
|
|
export function setType(object: any, type: string): void {
|
|
|
|
Object.defineProperty(object, '_ethersType', { configurable: false, value: type, writable: false });
|
|
|
|
}
|
|
|
|
|
|
|
|
export function isType(object: any, type: string): boolean {
|
2018-08-13 18:56:59 +03:00
|
|
|
return (object && object._ethersType === type);
|
2018-07-26 04:15:43 +03:00
|
|
|
}
|
|
|
|
|
2018-06-18 12:42:41 +03:00
|
|
|
export function resolveProperties(object: any): Promise<any> {
|
2018-06-13 22:39:39 +03:00
|
|
|
let result: any = {};
|
|
|
|
|
2018-06-23 08:33:51 +03:00
|
|
|
let promises: Array<Promise<void>> = [];
|
2018-06-13 22:39:39 +03:00
|
|
|
Object.keys(object).forEach((key) => {
|
|
|
|
let value = object[key];
|
|
|
|
if (value instanceof Promise) {
|
|
|
|
promises.push(
|
2018-06-23 08:33:51 +03:00
|
|
|
value.then((value) => {
|
|
|
|
result[key] = value;
|
2018-07-03 23:44:05 +03:00
|
|
|
return null;
|
2018-06-23 08:33:51 +03:00
|
|
|
})
|
2018-06-13 22:39:39 +03:00
|
|
|
);
|
|
|
|
} else {
|
|
|
|
result[key] = value;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
return Promise.all(promises).then(() => {
|
2018-06-22 03:41:09 +03:00
|
|
|
return result;
|
2018-06-13 22:39:39 +03:00
|
|
|
});
|
|
|
|
}
|
2018-06-15 11:18:17 +03:00
|
|
|
|
|
|
|
export function shallowCopy(object: any): any {
|
2018-06-23 03:30:50 +03:00
|
|
|
let result: any = {};
|
2018-06-15 11:18:17 +03:00
|
|
|
for (var key in object) { result[key] = object[key]; }
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2018-08-21 14:11:44 +03:00
|
|
|
let opaque: { [key: string]: boolean } = { boolean: true, number: true, string: true };
|
|
|
|
|
|
|
|
export function deepCopy(object: any, frozen?: boolean): any {
|
|
|
|
|
2018-10-02 00:30:45 +03:00
|
|
|
// Opaque objects are not mutable, so safe to copy by assignment
|
2018-08-21 14:11:44 +03:00
|
|
|
if (object === undefined || object === null || opaque[typeof(object)]) { return object; }
|
|
|
|
|
2018-10-02 00:30:45 +03:00
|
|
|
// Arrays are mutable, so we need to create a copy
|
2018-08-21 14:11:44 +03:00
|
|
|
if (Array.isArray(object)) {
|
2018-10-02 00:30:45 +03:00
|
|
|
let result = object.map((item) => deepCopy(item, frozen));
|
2018-08-21 14:11:44 +03:00
|
|
|
if (frozen) { Object.freeze(result); }
|
|
|
|
return result
|
|
|
|
}
|
|
|
|
|
|
|
|
if (typeof(object) === 'object') {
|
|
|
|
|
|
|
|
// Some internal objects, which are already immutable
|
|
|
|
if (isType(object, 'BigNumber')) { return object; }
|
|
|
|
if (isType(object, 'Description')) { return object; }
|
|
|
|
if (isType(object, 'Indexed')) { return object; }
|
|
|
|
|
|
|
|
let result: { [ key: string ]: any } = {};
|
2018-10-02 00:30:45 +03:00
|
|
|
for (let key in object) {
|
2018-08-21 14:11:44 +03:00
|
|
|
let value = object[key];
|
|
|
|
if (value === undefined) { continue; }
|
|
|
|
defineReadOnly(result, key, deepCopy(value, frozen));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (frozen) { Object.freeze(result); }
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2018-10-02 00:30:45 +03:00
|
|
|
// The function type is also immutable, so safe to copy by assignment
|
|
|
|
if (typeof(object) === 'function') {
|
|
|
|
return object;
|
|
|
|
}
|
|
|
|
|
2018-08-21 14:11:44 +03:00
|
|
|
throw new Error('Cannot deepCopy ' + typeof(object));
|
2018-06-15 11:18:17 +03:00
|
|
|
}
|
2018-07-31 01:59:52 +03:00
|
|
|
|
|
|
|
// See: https://github.com/isaacs/inherits/blob/master/inherits_browser.js
|
|
|
|
function inherits(ctor: any, superCtor: any): void {
|
|
|
|
ctor.super_ = superCtor
|
|
|
|
ctor.prototype = Object.create(superCtor.prototype, {
|
|
|
|
constructor: {
|
|
|
|
value: ctor,
|
|
|
|
enumerable: false,
|
|
|
|
writable: true,
|
|
|
|
configurable: true
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
export function inheritable(parent: any): (child: any) => void {
|
|
|
|
return function(child: any): void {
|
|
|
|
inherits(child, parent);
|
|
|
|
defineReadOnly(child, 'inherits', inheritable(child));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|