Fix dependabot issues

This commit is contained in:
Andrew Eisenberg 2021-10-21 15:24:20 -07:00
parent c89d9bd8b0
commit 531c6ba7c8
705 changed files with 53406 additions and 20466 deletions

Binary file not shown.

View file

@ -16,7 +16,7 @@ class Registry {
alloc (value) {
const index = ++this.counter
const pointer = {descriptor: null, index}
const pointer = { descriptor: null, index }
this.map.set(value, pointer)
return pointer
}

View file

@ -1,11 +1,11 @@
'use strict'
const Circular = require('./Circular')
const constants = require('./constants')
const describe = require('./describe')
const recursorUtils = require('./recursorUtils')
const shouldCompareDeep = require('./shouldCompareDeep')
const symbolProperties = require('./symbolProperties')
const Circular = require('./Circular')
const AMBIGUOUS = constants.AMBIGUOUS
const DEEP_EQUAL = constants.DEEP_EQUAL

View file

@ -10,7 +10,7 @@ function describe (props) {
return new DescribedArgumentsValue(Object.assign({
// Treat as an array, to allow comparisons with arrays
isArray: true,
isList: true
isList: true,
}, props, { ctor: 'Arguments' }))
}
exports.describe = describe

View file

@ -7,7 +7,7 @@ function describe (props) {
buffer: Buffer.from(props.value),
// Set isArray and isList so the property recursor excludes the byte accessors
isArray: true,
isList: true
isList: true,
}, props))
}
exports.describe = describe

View file

@ -1,7 +1,7 @@
'use strict'
const recursorUtils = require('../recursorUtils')
const stringPrimitive = require('../primitiveValues/string').tag
const recursorUtils = require('../recursorUtils')
const object = require('./object')
function describe (props) {
@ -18,7 +18,7 @@ const tag = Symbol('BoxedValue')
exports.tag = tag
class BoxedValue extends object.ObjectValue {}
Object.defineProperty(BoxedValue.prototype, 'tag', {value: tag})
Object.defineProperty(BoxedValue.prototype, 'tag', { value: tag })
class DescribedBoxedValue extends object.DescribedMixin(BoxedValue) {
constructor (props) {

View file

@ -7,7 +7,7 @@ function describe (props) {
buffer: typedArray.getBuffer(props.value),
// Set isArray and isList so the property recursor excludes the byte accessors
isArray: true,
isList: true
isList: true,
}, props))
}
exports.describe = describe

View file

@ -13,7 +13,7 @@ const UNEQUAL = constants.UNEQUAL
function describe (props) {
const date = props.value
const invalid = isNaN(date.valueOf())
return new DescribedDateValue(Object.assign({}, props, {invalid}))
return new DescribedDateValue(Object.assign({}, props, { invalid }))
}
exports.describe = describe
@ -32,7 +32,7 @@ function formatDate (date) {
date,
local: false,
showTimeZone: true,
showMilliseconds: true
showMilliseconds: true,
})
}
@ -61,13 +61,13 @@ class DateValue extends object.ObjectValue {
return innerLines.isEmpty
? lineBuilder.single(string + theme.object.closeBracket)
: lineBuilder.first(string)
.concat(innerLines.withFirstPrefixed(indent.increase()).stripFlags())
.append(lineBuilder.last(indent + theme.object.closeBracket))
.concat(innerLines.withFirstPrefixed(indent.increase()).stripFlags())
.append(lineBuilder.last(indent + theme.object.closeBracket))
},
maxDepth () {
return lineBuilder.single(string + ' ' + theme.maxDepth + ' ' + theme.object.closeBracket)
}
},
})
}

View file

@ -1,8 +1,8 @@
'use strict'
const constants = require('../constants')
const isEnumerable = require('../isEnumerable')
const formatUtils = require('../formatUtils')
const isEnumerable = require('../isEnumerable')
const lineBuilder = require('../lineBuilder')
const NOOP_RECURSOR = require('../recursorUtils').NOOP_RECURSOR
const object = require('./object')
@ -15,7 +15,7 @@ function describe (props) {
nameIsEnumerable: isEnumerable(error, 'name'),
name: error.name,
messageIsEnumerable: isEnumerable(error, 'message'),
message: error.message
message: error.message,
}, props))
}
exports.describe = describe
@ -59,13 +59,13 @@ class ErrorValue extends object.ObjectValue {
return innerLines.isEmpty
? lineBuilder.single(string + theme.object.closeBracket)
: lineBuilder.first(string)
.concat(innerLines.withFirstPrefixed(indent.increase()).stripFlags())
.append(lineBuilder.last(indent + theme.object.closeBracket))
.concat(innerLines.withFirstPrefixed(indent.increase()).stripFlags())
.append(lineBuilder.last(indent + theme.object.closeBracket))
},
maxDepth () {
return lineBuilder.single(string + ' ' + theme.maxDepth + ' ' + theme.object.closeBracket)
}
},
})
}

View file

@ -1,8 +1,8 @@
'use strict'
const constants = require('../constants')
const isEnumerable = require('../isEnumerable')
const formatUtils = require('../formatUtils')
const isEnumerable = require('../isEnumerable')
const lineBuilder = require('../lineBuilder')
const NOOP_RECURSOR = require('../recursorUtils').NOOP_RECURSOR
const object = require('./object')
@ -14,7 +14,7 @@ function describe (props) {
const fn = props.value
return new DescribedFunctionValue(Object.assign({
nameIsEnumerable: isEnumerable(fn, 'name'),
name: typeof fn.name === 'string' ? fn.name : null
name: typeof fn.name === 'string' ? fn.name : null,
}, props))
}
exports.describe = describe
@ -43,13 +43,13 @@ class FunctionValue extends object.ObjectValue {
return innerLines.isEmpty
? lineBuilder.single(string + theme.object.closeBracket)
: lineBuilder.first(string)
.concat(innerLines.withFirstPrefixed(indent.increase()).stripFlags())
.append(lineBuilder.last(indent + theme.object.closeBracket))
.concat(innerLines.withFirstPrefixed(indent.increase()).stripFlags())
.append(lineBuilder.last(indent + theme.object.closeBracket))
},
maxDepth () {
return lineBuilder.single(string + ' ' + theme.maxDepth + ' ' + theme.object.closeBracket)
}
},
})
}
}

View file

@ -9,7 +9,7 @@ const UNEQUAL = constants.UNEQUAL
function describe (props) {
return new DescribedMapValue(Object.assign({
size: props.value.size
size: props.value.size,
}, props))
}
exports.describe = describe
@ -39,7 +39,7 @@ class MapValue extends object.ObjectValue {
prepareDiff (expected) {
// Maps should be compared, even if they have a different number of entries.
return {compareResult: super.compare(expected)}
return { compareResult: super.compare(expected) }
}
serialize () {

View file

@ -1,11 +1,11 @@
'use strict'
const constants = require('../constants')
const getObjectKeys = require('../getObjectKeys')
const ObjectFormatter = require('../formatUtils').ObjectFormatter
const getObjectKeys = require('../getObjectKeys')
const hasLength = require('../hasLength')
const recursorUtils = require('../recursorUtils')
const stats = require('../metaDescriptors/stats')
const recursorUtils = require('../recursorUtils')
const DEEP_EQUAL = constants.DEEP_EQUAL
const SHALLOW_EQUAL = constants.SHALLOW_EQUAL
@ -17,7 +17,7 @@ function describe (props) {
return new DescribedObjectValue(Object.assign({
isArray,
isIterable: object[Symbol.iterator] !== undefined,
isList: isArray || hasLength(object)
isList: isArray || hasLength(object),
}, props))
}
exports.describe = describe
@ -58,7 +58,7 @@ class ObjectValue {
serialize () {
return [
this.ctor, this.pointer, this.stringTag,
this.isArray, this.isIterable, this.isList
this.isArray, this.isIterable, this.isList,
]
}
}
@ -231,7 +231,7 @@ function DeserializedMixin (base) {
stringTag: state[2],
isArray: state[3],
isIterable: state[4],
isList: state[5]
isList: state[5],
})
this.deserializedRecursor = recursor

View file

@ -11,7 +11,7 @@ function describe (props) {
const regexp = props.value
return new DescribedRegexpValue(Object.assign({
flags: getSortedFlags(regexp),
source: regexp.source
source: regexp.source,
}, props))
}
exports.describe = describe
@ -69,7 +69,7 @@ class RegexpValue extends object.ObjectValue {
regexp + ' ' +
theme.maxDepth + ' ' +
theme.object.closeBracket)
}
},
})
}

View file

@ -9,7 +9,7 @@ const UNEQUAL = constants.UNEQUAL
function describe (props) {
return new DescribedSetValue(Object.assign({
size: props.value.size
size: props.value.size,
}, props))
}
exports.describe = describe
@ -39,7 +39,7 @@ class SetValue extends object.ObjectValue {
prepareDiff (expected) {
// Sets should be compared, even if they have a different number of items.
return {compareResult: super.compare(expected)}
return { compareResult: super.compare(expected) }
}
serialize () {

View file

@ -3,8 +3,8 @@
const constants = require('../constants')
const formatUtils = require('../formatUtils')
const lineBuilder = require('../lineBuilder')
const recursorUtils = require('../recursorUtils')
const propertyStatsTag = require('../metaDescriptors/stats').propertyTag
const recursorUtils = require('../recursorUtils')
const object = require('./object')
const DEEP_EQUAL = constants.DEEP_EQUAL
@ -23,7 +23,7 @@ function describe (props) {
buffer: getBuffer(props.value),
// Set isArray and isList so the property recursor excludes the byte accessors
isArray: true,
isList: true
isList: true,
}, props))
}
exports.describe = describe
@ -103,7 +103,7 @@ class TypedArrayValue extends object.ObjectValue {
if (subject.isProperty === true) return subject.key.value !== 'byteLength'
if (subject.tag === bytesTag) return subject.buffer.byteLength > 0
return true
}
},
})
}
}

View file

@ -9,5 +9,5 @@ module.exports = {
AMBIGUOUS,
DEEP_EQUAL,
SHALLOW_EQUAL,
UNEQUAL
UNEQUAL,
}

View file

@ -1,5 +1,6 @@
'use strict'
const Registry = require('./Registry')
const argumentsValue = require('./complexValues/arguments')
const arrayBufferValue = require('./complexValues/arrayBuffer')
const boxedValue = require('./complexValues/boxed')
@ -15,23 +16,21 @@ const regexpValue = require('./complexValues/regexp')
const setValue = require('./complexValues/set')
const typedArrayValue = require('./complexValues/typedArray')
const getCtor = require('./getCtor')
const getStringTag = require('./getStringTag')
const itemDescriptor = require('./metaDescriptors/item')
const mapEntryDescriptor = require('./metaDescriptors/mapEntry')
const propertyDescriptor = require('./metaDescriptors/property')
const booleanValue = require('./primitiveValues/boolean')
const pluginRegistry = require('./pluginRegistry')
const bigIntValue = require('./primitiveValues/bigInt')
const booleanValue = require('./primitiveValues/boolean')
const nullValue = require('./primitiveValues/null')
const numberValue = require('./primitiveValues/number')
const stringValue = require('./primitiveValues/string')
const symbolValue = require('./primitiveValues/symbol')
const undefinedValue = require('./primitiveValues/undefined')
const getCtor = require('./getCtor')
const getStringTag = require('./getStringTag')
const pluginRegistry = require('./pluginRegistry')
const Registry = require('./Registry')
const SpecializedComplexes = new Map([
['Arguments', argumentsValue.describe],
['ArrayBuffer', arrayBufferValue.describe],
@ -53,7 +52,7 @@ const SpecializedComplexes = new Map([
['Uint16Array', typedArrayValue.describe],
['Uint32Array', typedArrayValue.describe],
['Uint8Array', typedArrayValue.describe],
['Uint8ClampedArray', typedArrayValue.describe]
['Uint8ClampedArray', typedArrayValue.describe],
])
function describePrimitive (value) {
@ -127,12 +126,22 @@ function describeComplex (value, registry, tryPlugins, describeAny, describeItem
pointer: pointer.index,
stringTag,
unboxed,
value
value,
})
pointer.descriptor = descriptor
return descriptor
}
const describeItem = (index, valueDescriptor) => {
return valueDescriptor.isPrimitive === true
? itemDescriptor.describePrimitive(index, valueDescriptor)
: itemDescriptor.describeComplex(index, valueDescriptor)
}
const describeMapEntry = (keyDescriptor, valueDescriptor) => {
return mapEntryDescriptor.describe(keyDescriptor, valueDescriptor)
}
function describe (value, options) {
const primitive = describePrimitive(value)
if (primitive !== null) return primitive
@ -150,16 +159,6 @@ function describe (value, options) {
: curriedComplex(any)
}
const describeItem = (index, valueDescriptor) => {
return valueDescriptor.isPrimitive === true
? itemDescriptor.describePrimitive(index, valueDescriptor)
: itemDescriptor.describeComplex(index, valueDescriptor)
}
const describeMapEntry = (keyDescriptor, valueDescriptor) => {
return mapEntryDescriptor.describe(keyDescriptor, valueDescriptor)
}
const describeProperty = (key, valueDescriptor) => {
const keyDescriptor = describePrimitive(key)
return valueDescriptor.isPrimitive === true

20
node_modules/concordance/lib/diff.js generated vendored
View file

@ -1,5 +1,7 @@
'use strict'
const Circular = require('./Circular')
const Indenter = require('./Indenter')
const constants = require('./constants')
const describe = require('./describe')
const lineBuilder = require('./lineBuilder')
@ -7,8 +9,6 @@ const recursorUtils = require('./recursorUtils')
const shouldCompareDeep = require('./shouldCompareDeep')
const symbolProperties = require('./symbolProperties')
const themeUtils = require('./themeUtils')
const Circular = require('./Circular')
const Indenter = require('./Indenter')
const AMBIGUOUS = constants.AMBIGUOUS
const DEEP_EQUAL = constants.DEEP_EQUAL
@ -75,7 +75,7 @@ function diffDescriptors (lhs, rhs, options) {
const isCircular = descriptor => lhsCircular.has(descriptor) || rhsCircular.has(descriptor)
const format = (builder, subject, circular) => {
const format = (builder, subject, circular, depthOffset = 0) => {
if (diffIndex >= 0 && !diffStack[diffIndex].shouldFormat(subject)) return
if (circular.has(subject)) {
@ -113,7 +113,7 @@ function diffDescriptors (lhs, rhs, options) {
const formatter = subject.formatShallow(themeUtils.applyModifiers(subject, theme), indent)
const recursor = subject.createRecursor()
if (formatter.increaseIndent && maxDepth > 0 && indent.level === maxDepth) {
if (formatter.increaseIndent && maxDepth > 0 && indent.level === (maxDepth + depthOffset)) {
const isEmpty = recursor() === null
let formatted = !isEmpty && typeof formatter.maxDepth === 'function'
? formatter.maxDepth()
@ -131,7 +131,7 @@ function diffDescriptors (lhs, rhs, options) {
recursor,
decreaseIndent: formatter.increaseIndent,
shouldFormat: formatter.shouldFormat || alwaysFormat,
subject
subject,
})
formatIndex++
@ -277,7 +277,7 @@ function diffDescriptors (lhs, rhs, options) {
origin: lhs,
decreaseIndent: formatter.increaseIndent,
exceedsMaxDepth: formatter.increaseIndent && maxDepth > 0 && indent.level >= maxDepth,
shouldFormat: formatter.shouldFormat || alwaysFormat
shouldFormat: formatter.shouldFormat || alwaysFormat,
})
diffIndex++
@ -289,7 +289,7 @@ function diffDescriptors (lhs, rhs, options) {
decreaseIndent: formatter.increaseIndent,
exceedsMaxDepth: formatter.increaseIndent && maxDepth > 0 && indent.level >= maxDepth,
shouldFormat: formatter.shouldFormat || alwaysFormat,
subject: lhs
subject: lhs,
})
diffIndex++
@ -304,7 +304,7 @@ function diffDescriptors (lhs, rhs, options) {
topIndex++
} else {
const diffed = typeof lhs.diffDeep === 'function'
? lhs.diffDeep(rhs, themeUtils.applyModifiers(lhs, theme), indent)
? lhs.diffDeep(rhs, themeUtils.applyModifiers(lhs, theme), indent, invert)
: null
if (diffed === null) {
@ -374,14 +374,14 @@ function diffDescriptors (lhs, rhs, options) {
}
do {
format(builder, subject, circular)
format(builder, subject, circular, indent.level)
subject = stack[topIndex].recursor()
} while (subject !== null)
}
}
} while (topIndex >= 0)
return buffer.toString({diff: true, invert, theme})
return buffer.toString({ diff: true, invert, theme })
}
exports.diffDescriptors = diffDescriptors

View file

@ -1,11 +1,11 @@
'use strict'
const flattenDeep = require('lodash.flattendeep')
const flattenDeep = require('lodash/flattenDeep')
// Indexes are hexadecimal to make reading the binary output easier.
const valueTypes = {
zero: 0x00,
int8: 0x01, // Note that the hex value equals the number of bytes required
int8: 0x01, // Note that the hex value equals the number of bytes required
int16: 0x02, // to store the integer.
int24: 0x03,
int32: 0x04,
@ -24,7 +24,7 @@ const valueTypes = {
utf8: 0x11,
bytes: 0x12,
list: 0x13,
descriptor: 0x14
descriptor: 0x14,
}
const descriptorSymbol = Symbol('descriptor')
@ -83,7 +83,7 @@ function encodeValue (value) {
return [
value[descriptorSymbol] === true ? valueTypes.descriptor : valueTypes.list,
encodeValue(value.length),
value.map(encodeValue)
value.map(x => encodeValue(x)),
]
}
@ -170,15 +170,15 @@ function buildBuffer (numberOrArray) {
const array = flattenDeep(numberOrArray)
const buffers = new Array(array.length)
let byteLength = 0
for (let index = 0; index < array.length; index++) {
if (typeof array[index] === 'number') {
for (const [index, element] of array.entries()) {
if (typeof element === 'number') {
byteLength += 1
const byte = Buffer.alloc(1)
byte.writeUInt8(array[index])
byte.writeUInt8(element)
buffers[index] = byte
} else {
byteLength += array[index].byteLength
buffers[index] = array[index]
byteLength += element.byteLength
buffers[index] = element
}
}
return Buffer.concat(buffers, byteLength)
@ -205,7 +205,7 @@ function encode (serializerVersion, rootRecord, usedPlugins) {
const plugin = usedPlugins.get(name)
const record = buildBuffer([
encodeValue(name),
encodeValue(plugin.serializerVersion)
encodeValue(plugin.serializerVersion),
])
buffers.push(record)
byteOffset += record.byteLength
@ -220,7 +220,7 @@ function encode (serializerVersion, rootRecord, usedPlugins) {
const recordHeader = buildBuffer([
encodeValue(record.pluginIndex),
encodeValue(record.id),
encodeValue(record.children.length)
encodeValue(record.children.length),
])
buffers.push(recordHeader)
byteOffset += recordHeader.byteLength
@ -258,7 +258,7 @@ function decodePlugins (buffer) {
byteOffset = $name.byteOffset
const serializerVersion = decodeValue(buffer, byteOffset).value
usedPlugins.set(index, {name, serializerVersion})
usedPlugins.set(index, { name, serializerVersion })
}
return usedPlugins
@ -285,7 +285,7 @@ function decodeRecord (buffer, byteOffset) {
}
const state = decodeValue(buffer, byteOffset).value
return {id, pluginIndex, state, pointerAddresses}
return { id, pluginIndex, state, pointerAddresses }
}
exports.decodeRecord = decodeRecord
@ -298,6 +298,6 @@ function decode (buffer) {
const rootOffset = buffer.readUInt32LE(2)
const pluginBuffer = buffer.slice(6, rootOffset)
const rootRecord = decodeRecord(buffer, rootOffset)
return {pluginBuffer, rootRecord}
return { pluginBuffer, rootRecord }
}
exports.decode = decode

View file

@ -1,10 +1,10 @@
'use strict'
const Circular = require('./Circular')
const Indenter = require('./Indenter')
const describe = require('./describe')
const lineBuilder = require('./lineBuilder')
const themeUtils = require('./themeUtils')
const Circular = require('./Circular')
const Indenter = require('./Indenter')
const alwaysFormat = () => true
const fixedIndent = new Indenter(0, ' ')
@ -13,7 +13,7 @@ function formatDescriptor (subject, options) {
const theme = themeUtils.normalize(options)
if (subject.isPrimitive === true) {
const formatted = subject.formatDeep(themeUtils.applyModifiers(subject, theme), fixedIndent)
return formatted.toString({diff: false})
return formatted.toString({ diff: false })
}
const circular = new Circular()
@ -58,7 +58,7 @@ function formatDescriptor (subject, options) {
recursor,
decreaseIndent: formatter.increaseIndent,
shouldFormat: formatter.shouldFormat || alwaysFormat,
subject
subject,
})
topIndex++
@ -91,7 +91,7 @@ function formatDescriptor (subject, options) {
}
} while (topIndex >= 0)
return buffer.toString({diff: false})
return buffer.toString({ diff: false })
}
exports.formatDescriptor = formatDescriptor

View file

@ -10,13 +10,11 @@ function getObjectKeys (obj, excludeListItemAccessorsBelowLength) {
// possible.
const symbolCandidates = Object.getOwnPropertySymbols(obj)
for (let i = 0; i < nameCandidates.length; i++) {
const name = nameCandidates[i]
for (const name of nameCandidates) {
let accept = true
if (excludeListItemAccessorsBelowLength > 0) {
const index = Number(name)
accept = (index % 1 !== 0) || index >= excludeListItemAccessorsBelowLength
accept = !Number.isInteger(index) || index < 0 || index >= excludeListItemAccessorsBelowLength
}
if (accept && Object.getOwnPropertyDescriptor(obj, name).enumerable) {
@ -24,8 +22,7 @@ function getObjectKeys (obj, excludeListItemAccessorsBelowLength) {
}
}
for (let i = 0; i < symbolCandidates.length; i++) {
const symbol = symbolCandidates[i]
for (const symbol of symbolCandidates) {
if (Object.getOwnPropertyDescriptor(obj, symbol).enumerable) {
keys[size++] = symbol
}

View file

@ -12,7 +12,7 @@ const isPromise = value => {
try {
return fts.call(value.constructor) === promiseCtorString
} catch (err) {
} catch {
return false
}
}

View file

@ -1,6 +1,6 @@
'use strict'
const isLength = require('lodash.islength')
const isLength = require('lodash/isLength')
const hop = Object.prototype.hasOwnProperty

View file

@ -86,7 +86,7 @@ class Line {
.decompose()
}
}
Object.defineProperty(Line.prototype, 'isLine', {value: true})
Object.defineProperty(Line.prototype, 'isLine', { value: true })
class Collection {
constructor () {
@ -206,8 +206,8 @@ class Collection {
}
decompose () {
const first = {actual: new Collection(), expected: new Collection()}
const last = {actual: new Collection(), expected: new Collection()}
const first = { actual: new Collection(), expected: new Collection() }
const last = { actual: new Collection(), expected: new Collection() }
const remaining = new Collection()
for (const line of this) {
@ -224,10 +224,10 @@ class Collection {
}
}
return {first, last, remaining}
return { first, last, remaining }
}
}
Object.defineProperty(Collection.prototype, 'isCollection', {value: true})
Object.defineProperty(Collection.prototype, 'isCollection', { value: true })
function setDefaultGutter (iterable, gutter) {
return new Collection()
@ -282,7 +282,7 @@ module.exports = {
setDefaultGutter (lineOrCollection) {
return setDefaultGutter(lineOrCollection, ACTUAL)
}
},
},
expected: {
@ -304,6 +304,6 @@ module.exports = {
setDefaultGutter (lineOrCollection) {
return setDefaultGutter(lineOrCollection, EXPECTED)
}
}
},
},
}

View file

@ -65,7 +65,7 @@ class ComplexItem {
prepareDiff (expected, lhsRecursor, rhsRecursor, compareComplexShape, isCircular) {
// Circular values cannot be compared. They must be treated as being unequal when diffing.
if (isCircular(this.value) || isCircular(expected.value)) return {compareResult: UNEQUAL}
if (isCircular(this.value) || isCircular(expected.value)) return { compareResult: UNEQUAL }
// Try to line up this or remaining items with the expected items.
const lhsFork = recursorUtils.fork(lhsRecursor)
@ -113,7 +113,7 @@ class ComplexItem {
next.index++
return next
})
}),
}
}
@ -128,7 +128,7 @@ class ComplexItem {
next.index++
return next
}),
rhsRecursor: rhsFork.recursor
rhsRecursor: rhsFork.recursor,
}
}
@ -138,7 +138,7 @@ class ComplexItem {
mustRecurse,
isUnequal: !mustRecurse,
lhsRecursor: lhsFork.recursor,
rhsRecursor: rhsFork.recursor
rhsRecursor: rhsFork.recursor,
}
}
@ -179,14 +179,14 @@ class PrimitiveItem {
prepareDiff (expected, lhsRecursor, rhsRecursor, compareComplexShape, isCircular) {
const compareResult = this.compare(expected)
// Short-circuit when values are deeply equal.
if (compareResult === DEEP_EQUAL) return {compareResult}
if (compareResult === DEEP_EQUAL) return { compareResult }
// Short-circut when values can be diffed directly.
if (
expected.tag === primitiveTag &&
this.value.tag === expected.value.tag && typeof this.value.diffDeep === 'function'
) {
return {compareResult}
return { compareResult }
}
// Try to line up this or remaining items with the expected items.
@ -204,7 +204,7 @@ class PrimitiveItem {
next.index++
return next
})
}),
}
}
@ -219,7 +219,7 @@ class PrimitiveItem {
next.index++
return next
}),
rhsRecursor: rhsFork.recursor
rhsRecursor: rhsFork.recursor,
}
}
@ -227,7 +227,7 @@ class PrimitiveItem {
} while (true)
}
diffDeep (expected, theme, indent) {
diffDeep (expected, theme, indent, invert) {
// Verify a diff can be returned.
if (this.tag !== expected.tag || typeof this.value.diffDeep !== 'function') return null
@ -236,7 +236,7 @@ class PrimitiveItem {
// Since the value is diffed directly, modifiers are not applied. Apply
// modifiers to the item descriptor instead.
const diff = this.value.diffDeep(expected.value, theme, valueIndent)
const diff = this.value.diffDeep(expected.value, theme, valueIndent, invert)
if (diff === null) return null
if (typeof theme.item.customFormat === 'function') {

View file

@ -113,11 +113,11 @@ class MapEntry {
},
finalize () {
return mergeWithKey(theme, key, values)
}
},
}
}
diffDeep (expected, theme, indent) {
diffDeep (expected, theme, indent, invert) {
// Verify a diff can be returned.
if (this.tag !== expected.tag || typeof this.value.diffDeep !== 'function') return null
// Only use this logic to format value diffs when the keys are primitive and equal.
@ -127,7 +127,7 @@ class MapEntry {
// Since formatShallow() would result in theme modifiers being applied
// before the key and value are formatted, do the same here.
const diff = this.value.diffDeep(expected.value, themeUtils.applyModifiersToOriginal(this.value, theme), indent)
const diff = this.value.diffDeep(expected.value, themeUtils.applyModifiersToOriginal(this.value, theme), indent, invert)
if (diff === null) return null
const key = this.key.formatDeep(themeUtils.applyModifiersToOriginal(this.key, theme), indent, '')
@ -136,12 +136,12 @@ class MapEntry {
prepareDiff (expected, lhsRecursor, rhsRecursor, compareComplexShape, isCircular) {
// Circular values cannot be compared. They must be treated as being unequal when diffing.
if (isCircular(this.value) || isCircular(expected.value)) return {compareResult: UNEQUAL}
if (isCircular(this.value) || isCircular(expected.value)) return { compareResult: UNEQUAL }
const compareResult = this.compare(expected)
const keysAreEqual = this.tag === expected.tag && this.key.compare(expected.key) === DEEP_EQUAL
// Short-circuit when keys and/or values are deeply equal.
if (compareResult === DEEP_EQUAL || keysAreEqual) return {compareResult}
if (compareResult === DEEP_EQUAL || keysAreEqual) return { compareResult }
// Try to line up this or remaining map entries with the expected entries.
const lhsFork = recursorUtils.fork(lhsRecursor)
@ -186,7 +186,7 @@ class MapEntry {
return {
actualIsExtraneous: true,
lhsRecursor: lhsFork.recursor,
rhsRecursor: recursorUtils.unshift(rhsFork.recursor, initialExpected)
rhsRecursor: recursorUtils.unshift(rhsFork.recursor, initialExpected),
}
}
@ -194,7 +194,7 @@ class MapEntry {
return {
expectedIsMissing: true,
lhsRecursor: recursorUtils.unshift(lhsFork.recursor, this),
rhsRecursor: rhsFork.recursor
rhsRecursor: rhsFork.recursor,
}
}
@ -211,7 +211,7 @@ class MapEntry {
mustRecurse,
isUnequal: !mustRecurse,
lhsRecursor: lhsFork.recursor,
rhsRecursor: rhsFork.recursor
rhsRecursor: rhsFork.recursor,
}
}

View file

@ -2,8 +2,8 @@
const constants = require('../constants')
const formatUtils = require('../formatUtils')
const recursorUtils = require('../recursorUtils')
const symbolPrimitive = require('../primitiveValues/symbol').tag
const recursorUtils = require('../recursorUtils')
const AMBIGUOUS = constants.AMBIGUOUS
const DEEP_EQUAL = constants.DEEP_EQUAL
@ -56,7 +56,7 @@ class Property {
prepareDiff (expected, lhsRecursor, rhsRecursor, compareComplexShape, isCircular) {
// Circular values cannot be compared. They must be treated as being unequal when diffing.
if (isCircular(this.value) || isCircular(expected.value)) return {compareResult: UNEQUAL}
if (isCircular(this.value) || isCircular(expected.value)) return { compareResult: UNEQUAL }
// Try to line up this or remaining properties with the expected properties.
const rhsFork = recursorUtils.fork(rhsRecursor)
@ -66,7 +66,7 @@ class Property {
if (expected === null || expected.isProperty !== true) {
return {
actualIsExtraneous: true,
rhsRecursor: recursorUtils.unshift(rhsFork.recursor, initialExpected)
rhsRecursor: recursorUtils.unshift(rhsFork.recursor, initialExpected),
}
} else if (this.key.compare(expected.key) === DEEP_EQUAL) {
if (expected === initialExpected) {
@ -75,7 +75,7 @@ class Property {
return {
expectedIsMissing: true,
lhsRecursor: recursorUtils.unshift(lhsRecursor, this),
rhsRecursor: rhsFork.recursor
rhsRecursor: rhsFork.recursor,
}
}
}
@ -160,7 +160,7 @@ class PrimitiveProperty extends Property {
.withLastPostfixed(theme.property.after)
}
diffDeep (expected, theme, indent) {
diffDeep (expected, theme, indent, invert) {
// Verify a diff can be returned.
if (this.tag !== expected.tag || typeof this.value.diffDeep !== 'function') return null
// Only use this logic to diff values when the keys are the same.
@ -171,7 +171,7 @@ class PrimitiveProperty extends Property {
// Since the key and value are diffed directly, modifiers are not
// applied. Apply modifiers to the property descriptor instead.
const diff = this.value.diffDeep(expected.value, theme, valueIndent)
const diff = this.value.diffDeep(expected.value, theme, valueIndent, invert)
if (diff === null) return null
if (typeof theme.property.customFormat === 'function') {

View file

@ -75,7 +75,7 @@ class Stats {
lhsRecursor: recursorUtils.unshift(lhsRecursor, this),
// Use original `rhsRecursor`, not `rhsFork`, since the consumed
// descriptors are returned with the `missing` array.
rhsRecursor: recursorUtils.unshift(rhsRecursor, expected)
rhsRecursor: recursorUtils.unshift(rhsRecursor, expected),
}
}
@ -95,7 +95,7 @@ class Stats {
// Use original `lhsRecursor`, not `lhsFork`, since the consumed
// descriptors are returned with the `extraneous` array.
lhsRecursor: recursorUtils.unshift(lhsRecursor, actual),
rhsRecursor: recursorUtils.unshift(rhsFork.recursor, initialExpected)
rhsRecursor: recursorUtils.unshift(rhsFork.recursor, initialExpected),
}
}

View file

@ -3,10 +3,10 @@
const semver = require('semver')
const pkg = require('../package.json')
const constants = require('./constants')
const object = require('./complexValues/object')
const lineBuilder = require('./lineBuilder')
const constants = require('./constants')
const formatUtils = require('./formatUtils')
const lineBuilder = require('./lineBuilder')
const itemDescriptor = require('./metaDescriptors/item')
const propertyDescriptor = require('./metaDescriptors/property')
const stringDescriptor = require('./primitiveValues/string')
@ -94,7 +94,7 @@ const publicDescriptorTags = Object.freeze({
complexItem: itemDescriptor.complexTag,
primitiveItem: itemDescriptor.primitiveTag,
primitiveProperty: propertyDescriptor.primitiveTag,
string: stringDescriptor.tag
string: stringDescriptor.tag,
})
// Don't expose `setDefaultGutter()`.
@ -109,15 +109,15 @@ const publicLineBuilder = Object.freeze({
first: lineBuilder.actual.first,
last: lineBuilder.actual.last,
line: lineBuilder.actual.line,
single: lineBuilder.actual.single
single: lineBuilder.actual.single,
}),
expected: Object.freeze({
buffer: lineBuilder.expected.buffer,
first: lineBuilder.expected.first,
last: lineBuilder.expected.last,
line: lineBuilder.expected.line,
single: lineBuilder.expected.single
})
single: lineBuilder.expected.single,
}),
})
function modifyTheme (descriptor, modifier) {
@ -158,7 +158,7 @@ function add (plugin) {
lineBuilder: publicLineBuilder,
mapRecursor: recursorUtils.map,
modifyTheme,
wrapFromTheme: formatUtils.wrap
wrapFromTheme: formatUtils.wrap,
})
const registered = {
@ -167,7 +167,7 @@ function add (plugin) {
name,
tag2id,
theme: plugin.theme || {},
tryDescribeValue
tryDescribeValue,
}
registry.set(name, registered)
@ -185,7 +185,7 @@ function getDeserializers (plugins) {
return {
id2deserialize: registered.id2deserialize,
name: registered.name,
serializerVersion: registered.serializerVersion
serializerVersion: registered.serializerVersion,
}
})
}
@ -196,7 +196,7 @@ function getThemes (plugins) {
const registered = add(plugin)
return {
name: registered.name,
theme: registered.theme
theme: registered.theme,
}
})
}
@ -215,8 +215,8 @@ function resolveDescriptorRef (tag) {
id: registered.tag2id.get(tag),
name: registered.name,
serialization: {
serializerVersion: registered.serializerVersion
}
serializerVersion: registered.serializerVersion,
},
}
}
exports.resolveDescriptorRef = resolveDescriptorRef

View file

@ -1,7 +1,7 @@
'use strict'
const fastDiff = require('fast-diff')
const keyword = require('esutils').keyword
const fastDiff = require('fast-diff')
const constants = require('../constants')
const formatUtils = require('../formatUtils')
@ -61,7 +61,7 @@ function includesLinebreaks (string) {
return string.includes('\r') || string.includes('\n')
}
function diffLine (theme, actual, expected) {
function diffLine (theme, actual, expected, invert) {
const outcome = fastDiff(actual, expected)
// TODO: Compute when line is mostly unequal (80%? 90%?) and treat it as being
@ -83,9 +83,14 @@ function diffLine (theme, actual, expected) {
let stringExpected = ''
const noopWrap = { open: '', close: '' }
const deleteWrap = isPartiallyEqual ? theme.string.diff.delete : noopWrap
const insertWrap = isPartiallyEqual ? theme.string.diff.insert : noopWrap
let deleteWrap = isPartiallyEqual ? theme.string.diff.delete : noopWrap
let insertWrap = isPartiallyEqual ? theme.string.diff.insert : noopWrap
const equalWrap = isPartiallyEqual ? theme.string.diff.equal : noopWrap
if (invert) {
[deleteWrap, insertWrap] = [insertWrap, deleteWrap]
}
for (const diff of outcome) {
if (diff[0] === fastDiff.DELETE) {
stringActual += formatUtils.wrap(deleteWrap, diff[1])
@ -99,8 +104,11 @@ function diffLine (theme, actual, expected) {
}
if (!isPartiallyEqual) {
stringActual = formatUtils.wrap(theme.string.diff.deleteLine, stringActual)
stringExpected = formatUtils.wrap(theme.string.diff.insertLine, stringExpected)
const deleteLineWrap = invert ? theme.string.diff.insertLine : theme.string.diff.deleteLine
const insertLineWrap = invert ? theme.string.diff.deleteLine : theme.string.diff.insertLine
stringActual = formatUtils.wrap(deleteLineWrap, stringActual)
stringExpected = formatUtils.wrap(insertLineWrap, stringExpected)
}
return [stringActual, stringExpected]
@ -170,7 +178,7 @@ class StringValue {
return formatUtils.wrap(theme.string.line, formatUtils.wrap(theme.string, escaped))
}
diffDeep (expected, theme, indent) {
diffDeep (expected, theme, indent, invert) {
if (expected.tag !== tag) return null
const escapedActual = basicEscape(this.value)
@ -179,7 +187,9 @@ class StringValue {
if (!includesLinebreaks(escapedActual) && !includesLinebreaks(escapedExpected)) {
const result = diffLine(theme,
escapeQuotes(theme.string.line, escapedActual),
escapeQuotes(theme.string.line, escapedExpected))
escapeQuotes(theme.string.line, escapedExpected),
invert,
)
return lineBuilder.actual.single(formatUtils.wrap(theme.string.line, result[0]))
.concat(lineBuilder.expected.single(formatUtils.wrap(theme.string.line, result[1])))
@ -241,7 +251,8 @@ class StringValue {
}
if (actualIsExtraneous && !expectedIsMissing) {
const string = formatUtils.wrap(theme.string.diff.deleteLine, actualLines[actualIndex])
const wrap = invert ? theme.string.diff.insertLine : theme.string.diff.deleteLine
const string = formatUtils.wrap(wrap, actualLines[actualIndex])
if (actualIndex === 0) {
actualBuffer.push(lineBuilder.actual.first(theme.string.multiline.start + string))
@ -255,7 +266,8 @@ class StringValue {
actualIndex++
extraneousOffset++
} else if (expectedIsMissing && !actualIsExtraneous) {
const string = formatUtils.wrap(theme.string.diff.insertLine, expectedLines[expectedIndex])
const wrap = invert ? theme.string.diff.deleteLine : theme.string.diff.insertLine
const string = formatUtils.wrap(wrap, expectedLines[expectedIndex])
if (mustOpenNextExpected) {
expectedBuffer.push(lineBuilder.expected.first(theme.string.multiline.start + string))
@ -268,7 +280,7 @@ class StringValue {
expectedIndex++
} else {
const result = diffLine(theme, actualLines[actualIndex], expectedLines[expectedIndex])
const result = diffLine(theme, actualLines[actualIndex], expectedLines[expectedIndex], invert)
if (actualIndex === 0) {
actualBuffer.push(lineBuilder.actual.first(theme.string.multiline.start + result[0]))

View file

@ -22,7 +22,7 @@ function describe (value) {
return new SymbolValue({
stringCompare,
value
value,
})
}
exports.describe = describe
@ -34,7 +34,7 @@ function deserialize (state) {
return new DeserializedSymbolValue({
string,
stringCompare,
value: null
value: null,
})
}
exports.deserialize = deserialize

View file

@ -2,7 +2,7 @@
const NOOP_RECURSOR = {
size: 0,
next () { return null }
next () { return null },
}
exports.NOOP_RECURSOR = NOOP_RECURSOR
@ -19,11 +19,27 @@ function fork (recursor) {
recursor () {
if (buffer.length > 0) return buffer.shift()
return recursor()
}
},
}
}
exports.fork = fork
function consumeDeep (recursor) {
const stack = [recursor]
while (stack.length > 0) {
const subject = stack[stack.length - 1]()
if (subject === null) {
stack.pop()
continue
}
if (typeof subject.createRecursor === 'function') {
stack.push(subject.createRecursor())
}
}
}
exports.consumeDeep = consumeDeep
function map (recursor, mapFn) {
return () => {
const next = recursor()
@ -42,12 +58,12 @@ function replay (state, create) {
} else {
state = Object.assign({
buffer: [],
done: false
done: false,
}, recursor)
}
}
if (state === NOOP_RECURSOR) return {state, recursor: state}
if (state === NOOP_RECURSOR) return { state, recursor: state }
let done = false
let index = 0
@ -66,7 +82,7 @@ function replay (state, create) {
return retval
}
return {state, recursor: {next, size: state.size}}
return { state, recursor: { next, size: state.size } }
}
exports.replay = replay

View file

@ -2,9 +2,6 @@
const md5hex = require('md5-hex')
const encoder = require('./encoder')
const pluginRegistry = require('./pluginRegistry')
const argumentsValue = require('./complexValues/arguments')
const arrayBufferValue = require('./complexValues/arrayBuffer')
const boxedValue = require('./complexValues/boxed')
@ -20,12 +17,16 @@ const regexpValue = require('./complexValues/regexp')
const setValue = require('./complexValues/set')
const typedArrayValue = require('./complexValues/typedArray')
const encoder = require('./encoder')
const itemDescriptor = require('./metaDescriptors/item')
const mapEntryDescriptor = require('./metaDescriptors/mapEntry')
const pointerDescriptor = require('./metaDescriptors/pointer')
const propertyDescriptor = require('./metaDescriptors/property')
const statsDescriptors = require('./metaDescriptors/stats')
const pluginRegistry = require('./pluginRegistry')
const bigIntValue = require('./primitiveValues/bigInt')
const booleanValue = require('./primitiveValues/boolean')
const nullValue = require('./primitiveValues/null')
@ -34,6 +35,8 @@ const stringValue = require('./primitiveValues/string')
const symbolValue = require('./primitiveValues/symbol')
const undefinedValue = require('./primitiveValues/undefined')
const recursorUtils = require('./recursorUtils')
// Increment if encoding layout, descriptor IDs, or value types change. Previous
// Concordance versions will not be able to decode buffers generated by a newer
// version, so changing this value will require a major version bump of
@ -78,7 +81,7 @@ const mappings = [
[0x1C, regexpValue.tag, regexpValue.deserialize],
[0x1D, setValue.tag, setValue.deserialize],
[0x1E, typedArrayValue.tag, typedArrayValue.deserialize],
[0x1F, typedArrayValue.bytesTag, typedArrayValue.deserializeBytes]
[0x1F, typedArrayValue.bytesTag, typedArrayValue.deserializeBytes],
]
const tag2id = new Map(mappings.map(mapping => [mapping[1], mapping[0]]))
const id2deserialize = new Map(mappings.map(mapping => [mapping[0], mapping[2]]))
@ -116,7 +119,7 @@ class UnsupportedPluginError extends Error {
}
}
class UnsupportedVersion extends Error {
class UnsupportedVersion extends Error { // eslint-disable-line unicorn/custom-error-definition
constructor (serializerVersion) {
super('Could not deserialize buffer: a different serialization was expected')
this.name = 'UnsupportedVersion'
@ -131,7 +134,7 @@ function shallowSerializeDescriptor (descriptor, resolvePluginRef) {
}
function serializeState (state, resolvePluginRef) {
if (Array.isArray(state)) return state.map(serializeState)
if (Array.isArray(state)) return state.map(x => serializeState(x))
if (state && state.tag) {
let id, pluginIndex
@ -165,12 +168,12 @@ function serialize (descriptor) {
if (!usedPlugins.has(ref.name)) {
// Start at 1, since 0 is reserved for Concordance's descriptors.
const index = usedPlugins.size + 1
usedPlugins.set(ref.name, Object.assign({index}, ref.serialization))
usedPlugins.set(ref.name, Object.assign({ index }, ref.serialization))
}
return {
id: ref.id,
pluginIndex: usedPlugins.get(ref.name).index
pluginIndex: usedPlugins.get(ref.name).index,
}
}
@ -205,7 +208,7 @@ function serialize (descriptor) {
id,
pluginIndex,
children: [],
state: shallowSerializeDescriptor(descriptor, resolvePluginRef)
state: shallowSerializeDescriptor(descriptor, resolvePluginRef),
}
if (!rootRecord) {
rootRecord = record
@ -318,12 +321,27 @@ function deserialize (buffer, options) {
const descriptorsByPointerIndex = new Map()
const mapPointerDescriptor = descriptor => {
if (descriptor.isPointer === true) {
if (!descriptorsByPointerIndex.has(descriptor.index)) throw new PointerLookupError(descriptor.index)
if (descriptorsByPointerIndex.has(descriptor.index)) {
return descriptorsByPointerIndex.get(descriptor.index)
}
return descriptorsByPointerIndex.get(descriptor.index)
} else if (descriptor.isComplex === true) {
if (typeof rootDescriptor.createRecursor === 'function') {
// The descriptor we're pointing to may be elsewhere in the serialized
// structure. Consume the entire structure and check again.
recursorUtils.consumeDeep(rootDescriptor.createRecursor())
if (descriptorsByPointerIndex.has(descriptor.index)) {
return descriptorsByPointerIndex.get(descriptor.index)
}
}
throw new PointerLookupError(descriptor.index)
}
if (descriptor.isComplex === true) {
descriptorsByPointerIndex.set(descriptor.pointer, descriptor)
}
return descriptor
}
@ -336,6 +354,8 @@ function deserialize (buffer, options) {
return mapPointerDescriptor(deserializeDescriptor(state, recursor))
}
}
return deserializeRecord(decoded.rootRecord, getDescriptorDeserializer, buffer)
const rootDescriptor = deserializeRecord(decoded.rootRecord, getDescriptorDeserializer, buffer)
return rootDescriptor
}
exports.deserialize = deserialize

View file

@ -74,7 +74,7 @@ class Comparable {
}
expected.ordered = ordered.concat(missingProperties)
return {mustRecurse: true}
return { mustRecurse: true }
}
}
Object.defineProperty(Comparable.prototype, 'isSymbolPropertiesComparable', { value: true })

View file

@ -1,7 +1,7 @@
'use strict'
const cloneDeep = require('lodash.clonedeep')
const merge = require('lodash.merge')
const cloneDeep = require('lodash/cloneDeep')
const merge = require('lodash/merge')
const pluginRegistry = require('./pluginRegistry')
@ -28,31 +28,31 @@ const defaultTheme = freezeTheme({
circular: '[Circular]',
date: {
invalid: 'invalid',
value: { open: '', close: '' }
value: { open: '', close: '' },
},
diffGutters: {
actual: '- ',
expected: '+ ',
padding: ' '
padding: ' ',
},
error: {
ctor: { open: '(', close: ')' },
name: { open: '', close: '' }
name: { open: '', close: '' },
},
function: {
name: { open: '', close: '' },
stringTag: { open: '', close: '' }
stringTag: { open: '', close: '' },
},
global: { open: '', close: '' },
item: {
after: ',',
customFormat: null,
increaseValueIndent: false
increaseValueIndent: false,
},
list: { openBracket: '[', closeBracket: ']' },
mapEntry: {
after: ',',
separator: ' => '
separator: ' => ',
},
maxDepth: '…',
null: { open: '', close: '' },
@ -62,40 +62,40 @@ const defaultTheme = freezeTheme({
closeBracket: '}',
ctor: { open: '', close: '' },
stringTag: { open: '@', close: '' },
secondaryStringTag: { open: '@', close: '' }
secondaryStringTag: { open: '@', close: '' },
},
property: {
after: ',',
customFormat: null,
keyBracket: { open: '[', close: ']' },
separator: ': ',
increaseValueIndent: false
increaseValueIndent: false,
},
regexp: {
source: { open: '/', close: '/' },
flags: { open: '', close: '' },
separator: '---'
separator: '---',
},
stats: { separator: '---' },
string: {
open: '',
close: '',
line: { open: "'", close: "'", escapeQuote: "'" },
multiline: { start: '`', end: '`', escapeQuote: '``' },
multiline: { start: '`', end: '`', escapeQuote: '`' },
controlPicture: { open: '', close: '' },
diff: {
insert: { open: '', close: '' },
delete: { open: '', close: '' },
equal: { open: '', close: '' },
insertLine: { open: '', close: '' },
deleteLine: { open: '', close: '' }
}
deleteLine: { open: '', close: '' },
},
},
symbol: { open: '', close: '' },
typedArray: {
bytes: { open: '', close: '' }
bytes: { open: '', close: '' },
},
undefined: { open: '', close: '' }
undefined: { open: '', close: '' },
})
const pluginRefs = new Map()
@ -119,7 +119,7 @@ function normalizePlugins (plugins) {
if (normalizedPluginThemes.has(ref)) {
return {
ref,
theme: normalizedPluginThemes.get(ref)
theme: normalizedPluginThemes.get(ref),
}
}
@ -127,19 +127,19 @@ function normalizePlugins (plugins) {
return merge(acc, pluginTheme)
}, cloneDeep(defaultTheme)))
normalizedPluginThemes.set(ref, theme)
return {ref, theme}
return { ref, theme }
}
const normalizedCache = new WeakMap()
function normalize (options) {
options = Object.assign({plugins: [], theme: null}, options)
options = Object.assign({ plugins: [], theme: null }, options)
const normalizedPlugins = normalizePlugins(options.plugins)
if (!options.theme) {
return normalizedPlugins ? normalizedPlugins.theme : defaultTheme
}
const entry = normalizedCache.get(options.theme) || {theme: null, withPlugins: new Map()}
const entry = normalizedCache.get(options.theme) || { theme: null, withPlugins: new Map() }
if (!normalizedCache.has(options.theme)) normalizedCache.set(options.theme, entry)
if (normalizedPlugins) {