Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 | 21x 19x 169x 82x 61x 54x 42x 40x 143x 49x 94x 21x 73x 4x 69x 13x 2x 11x 14x 4x 7x 56x 5x 1x 4x 5x 1x 3x 4x 1x 2x 51x 3x 1x 2x 5x 1x 1x 48x 5x 1x 4x 4x 4x 20x 2x 2x 43x 3x 40x 2x 38x 2x 36x 36x 36x 4x 32x 51x 1x 31x 48x 48x 10x 21x | export function isDefined<T>(value?: T): value is NonNullable<T> {
return value !== undefined && value !== null
}
export function isTruthy<T>(value?: T | null): value is T {
return Boolean(value)
}
function isObject(value: unknown): value is Record<string, unknown> {
return typeof value === 'object' && value !== null
}
function isArray(value: unknown): value is unknown[] {
return Array.isArray(value)
}
function isMap(value: unknown): value is Map<unknown, unknown> {
return value instanceof Map
}
function isSet(value: unknown): value is Set<unknown> {
return value instanceof Set
}
function hasCustomValueOf(value: Record<string, unknown>): value is Record<string, unknown> & { valueOf(): unknown } {
return typeof value.valueOf === 'function' && value.valueOf !== Object.prototype.valueOf
}
function hasCustomToString(value: Record<string, unknown>): value is { toString(): string } {
return typeof value.toString === 'function' && value.toString !== Object.prototype.toString
}
/**
* Structural equality check.
*
* Adapted from fast-deep-equal (MIT), kept close to upstream so it stays easy to diff against the
* original while keeping the SDK free of runtime dependencies. The upstream implementation is
* untyped JS; this port narrows `unknown` with type guards instead.
*
* @see https://github.com/epoberezkin/fast-deep-equal/blob/master/src/index.jst
*/
export function deepEqual(a: unknown, b: unknown): boolean {
if (a === b) {
return true
}
if (!isObject(a) || !isObject(b)) {
// true if both NaN, false otherwise
return typeof a === 'number' && typeof b === 'number' && Number.isNaN(a) && Number.isNaN(b)
}
if (a.constructor !== b.constructor) {
return false
}
if (isArray(a) && isArray(b)) {
if (a.length !== b.length) {
return false
}
for (let i = a.length; i-- !== 0;) {
if (!deepEqual(a[i], b[i])) {
return false
}
}
return true
}
if (isMap(a) && isMap(b)) {
if (a.size !== b.size) {
return false
}
for (const key of a.keys()) {
if (!b.has(key)) {
return false
}
}
for (const [key, value] of a) {
if (!deepEqual(value, b.get(key))) {
return false
}
}
return true
}
if (isSet(a) && isSet(b)) {
if (a.size !== b.size) {
return false
}
for (const value of a.values()) {
if (!b.has(value)) {
return false
}
}
return true
}
if (ArrayBuffer.isView(a) && ArrayBuffer.isView(b)) {
// Upstream indexes the typed arrays directly; `ArrayBufferView` is not index-typed and casting to
// `ArrayLike<number>` is unsound, so compare the raw bytes instead. Constructors already matched
// above, so equal byte contents imply equal element contents.
if (a.byteLength !== b.byteLength) {
return false
}
const bytesA = new Uint8Array(a.buffer, a.byteOffset, a.byteLength)
const bytesB = new Uint8Array(b.buffer, b.byteOffset, b.byteLength)
for (let i = bytesA.length; i-- !== 0;) {
if (bytesA[i] !== bytesB[i]) {
return false
}
}
return true
}
if (a instanceof RegExp && b instanceof RegExp) {
return a.source === b.source && a.flags === b.flags
}
if (hasCustomValueOf(a) && hasCustomValueOf(b)) {
return a.valueOf() === b.valueOf()
}
if (hasCustomToString(a) && hasCustomToString(b)) {
// The guards above already established that `toString` is overridden (not `Object.prototype`'s),
// so it will not produce the default `[object Object]`; `no-base-to-string` can't see through the guard.
// eslint-disable-next-line @typescript-eslint/no-base-to-string
return a.toString() === b.toString()
}
const keys = Object.keys(a)
const { length } = keys
if (length !== Object.keys(b).length) {
return false
}
for (let i = length; i-- !== 0;) {
if (!Object.prototype.hasOwnProperty.call(b, keys[i])) {
return false
}
}
for (let i = length; i-- !== 0;) {
const key = keys[i]
if (!deepEqual(a[key], b[key])) {
return false
}
}
return true
}
|