Skip to content

Commit 56ee288

Browse files
committed
Fix non-first parameter merging when reconfiguring plugins
If you configure a plugin with multiple parameters (which is supported but not particularly recommended, or used), and then reconfigure it multiple times, the non-first parameters (so everything other than what’s typically the `options` object), we now take the last configured values. Previously, earlier values remained.
1 parent 6f068a0 commit 56ee288

File tree

2 files changed

+92
-14
lines changed

2 files changed

+92
-14
lines changed

lib/index.js

+13-14
Original file line numberDiff line numberDiff line change
@@ -1210,29 +1210,28 @@ export class Processor extends CallableInstance {
12101210
*/
12111211
function addPlugin(plugin, parameters) {
12121212
let index = -1
1213-
/** @type {PluginTuple<Array<unknown>> | undefined} */
1214-
let entry
1213+
let entryIndex = -1
12151214

12161215
while (++index < attachers.length) {
12171216
if (attachers[index][0] === plugin) {
1218-
entry = attachers[index]
1217+
entryIndex = index
12191218
break
12201219
}
12211220
}
12221221

1223-
if (entry) {
1224-
let value = parameters[0]
1225-
if (isPlainObj(entry[1]) && isPlainObj(value)) {
1226-
value = structuredClone({...entry[1], ...value})
1222+
if (entryIndex === -1) {
1223+
attachers.push([plugin, ...parameters])
1224+
}
1225+
// Only set if there was at least a `primary` value, otherwise we’d change
1226+
// `arguments.length`.
1227+
else if (parameters.length > 0) {
1228+
let [primary, ...rest] = parameters
1229+
const currentPrimary = attachers[entryIndex][1]
1230+
if (isPlainObj(currentPrimary) && isPlainObj(primary)) {
1231+
primary = structuredClone({...currentPrimary, ...primary})
12271232
}
12281233

1229-
entry[1] = value
1230-
// To do: should the rest be set?
1231-
} else {
1232-
// It’s important to pass arguments, because an explicit passed
1233-
// `undefined` is different from a not-passed `value`.
1234-
// This way we keep things at their place.
1235-
attachers.push([plugin, ...parameters])
1234+
attachers[entryIndex] = [plugin, primary, ...rest]
12361235
}
12371236
}
12381237
}

test/use.js

+79
Original file line numberDiff line numberDiff line change
@@ -1291,4 +1291,83 @@ test('`use`', async function (t) {
12911291
}
12921292
)
12931293
})
1294+
1295+
await t.test('reconfigure (non-first parameters)', async function (t) {
1296+
await t.test(
1297+
'should reconfigure plugins (non-first parameters)',
1298+
async function () {
1299+
let calls = 0
1300+
1301+
unified()
1302+
.use(fn, givenOptions, givenOptions, givenOptions, undefined)
1303+
.use(fn, otherOptions, otherOptions, undefined, otherOptions)
1304+
.freeze()
1305+
1306+
assert.equal(calls, 1)
1307+
1308+
/**
1309+
* @param {unknown} a
1310+
* @param {unknown} b
1311+
* @param {unknown} c
1312+
* @param {unknown} d
1313+
*/
1314+
function fn(a, b, c, d) {
1315+
assert.equal(arguments.length, 4)
1316+
assert.deepEqual(a, mergedOptions)
1317+
assert.deepEqual(b, otherOptions)
1318+
assert.deepEqual(c, undefined)
1319+
assert.deepEqual(d, otherOptions)
1320+
calls++
1321+
}
1322+
}
1323+
)
1324+
1325+
await t.test('should keep parameter length (#1)', async function () {
1326+
let calls = 0
1327+
1328+
unified().use(fn).use(fn).freeze()
1329+
1330+
assert.equal(calls, 1)
1331+
1332+
/**
1333+
* @param {...unknown} parameters
1334+
*/
1335+
function fn(...parameters) {
1336+
assert.deepEqual(parameters, [])
1337+
calls++
1338+
}
1339+
})
1340+
1341+
await t.test('should keep parameter length (#2)', async function () {
1342+
let calls = 0
1343+
1344+
unified().use(fn, givenOptions).use(fn).freeze()
1345+
1346+
assert.equal(calls, 1)
1347+
1348+
/**
1349+
* @param {...unknown} parameters
1350+
*/
1351+
function fn(...parameters) {
1352+
assert.deepEqual(parameters, [givenOptions])
1353+
calls++
1354+
}
1355+
})
1356+
1357+
await t.test('should keep parameter length (#3)', async function () {
1358+
let calls = 0
1359+
1360+
unified().use(fn).use(fn, givenOptions).freeze()
1361+
1362+
assert.equal(calls, 1)
1363+
1364+
/**
1365+
* @param {...unknown} parameters
1366+
*/
1367+
function fn(...parameters) {
1368+
assert.deepEqual(parameters, [givenOptions])
1369+
calls++
1370+
}
1371+
})
1372+
})
12941373
})

0 commit comments

Comments
 (0)