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 150 151 152 153 | 61x 52x 222x 107x 88x 81x 69x 67x 195x 74x 121x 22x 99x 4x 95x 12x 1x 11x 14x 4x 7x 83x 5x 1x 4x 5x 1x 3x 4x 1x 2x 78x 3x 1x 2x 5x 1x 1x 75x 5x 1x 4x 4x 4x 20x 2x 2x 70x 3x 67x 2x 65x 2x 63x 63x 63x 4x 59x 59x 1x 58x 58x 58x 9x 49x | 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)
}
export function isEmptyArray(value: unknown): value is [] {
return Array.isArray(value) && value.length === 0
}
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
}
|