UNPKG

@qntm-code/utils

Version:

A collection of useful utility functions with associated TypeScript types. All functions have been unit tested.

107 lines (106 loc) 4.02 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.clone = void 0; const isPlainObject_js_1 = require("../type-predicates/isPlainObject.js"); const typeOf_js_1 = require("../type-predicates/typeOf.js"); /** * Recursively (deep) clones native types, like Object, Array, RegExp, Date, Map, Set, Symbol, Error as well as primitives. */ function clone(value, instanceClone = false) { switch ((0, typeOf_js_1.typeOf)(value)) { case typeOf_js_1.ValueType.object: { return cloneObjectDeep(value, instanceClone); } case typeOf_js_1.ValueType.array: case typeOf_js_1.ValueType.int8array: case typeOf_js_1.ValueType.uint8array: case typeOf_js_1.ValueType.uint8clampedarray: case typeOf_js_1.ValueType.int16array: case typeOf_js_1.ValueType.uint16array: case typeOf_js_1.ValueType.int32array: case typeOf_js_1.ValueType.uint32array: case typeOf_js_1.ValueType.float32array: case typeOf_js_1.ValueType.float64array: case typeOf_js_1.ValueType.bigint64array: case typeOf_js_1.ValueType.biguint64array: { return cloneArrayDeep(value, instanceClone); } default: { return cloneShallow(value); } } } exports.clone = clone; function cloneShallow(value) { switch ((0, typeOf_js_1.typeOf)(value)) { case typeOf_js_1.ValueType.buffer: { return cloneBuffer(value); } case typeOf_js_1.ValueType.symbol: { return cloneSymbol(value); } case typeOf_js_1.ValueType.error: { return Object.create(value); } case typeOf_js_1.ValueType.map: { return new Map(value); } case typeOf_js_1.ValueType.set: { return new Set(value); } case typeOf_js_1.ValueType.date: { return new Date(value); } case typeOf_js_1.ValueType.regexp: { return cloneRegExp(value); } case typeOf_js_1.ValueType.moment: { return value.clone(); } } return value; } function cloneObjectDeep(value, instanceClone) { if (typeof instanceClone === 'function') { return instanceClone(value); } if (instanceClone || (0, isPlainObject_js_1.isPlainObject)(value)) { // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access const cloned = new value.constructor(); for (const key in value) { // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access cloned[key] = clone(value[key]); } // eslint-disable-next-line @typescript-eslint/no-unsafe-return return cloned; } return value; } function cloneArrayDeep(value, instanceClone) { const length = value.length; // eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access const cloned = new value.constructor(length); for (let i = 0; i < length; i++) { cloned[i] = clone(value[i], instanceClone); } return cloned; } function cloneRegExp(value) { // eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access const cloned = new value.constructor(value.source, value.flags); cloned.lastIndex = value.lastIndex; return cloned; } function cloneBuffer(value) { const length = value.length; // eslint-disable-next-line @typescript-eslint/no-unsafe-argument const buffer = Buffer.allocUnsafe ? Buffer.allocUnsafe(length) : Buffer.from(length); value.copy(buffer); return buffer; } // eslint-disable-next-line @typescript-eslint/unbound-method const valueOf = Symbol.prototype.valueOf; function cloneSymbol(value) { // eslint-disable-next-line @typescript-eslint/no-unsafe-return return valueOf ? Object(valueOf.call(value)) : {}; }