Skip to content

Commit 9a16571

Browse files
author
jikrana
committed
fix: clone sponsor/link objects instead of mutating caller props
1 parent c75b4d3 commit 9a16571

1 file changed

Lines changed: 23 additions & 18 deletions

File tree

src/utils/validateProps.ts

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -242,12 +242,12 @@ export function validateProps(
242242

243243
sponsors = [];
244244
} else {
245-
sponsors = sponsors.filter((sponsor, index) => {
245+
sponsors = sponsors.reduce((normalized, sponsor, index) => {
246246
if (!isObject(sponsor)) {
247247
warn(
248248
`sponsors[${index}] must be an object. This sponsor will be ignored.`,
249249
);
250-
return false;
250+
return normalized;
251251
}
252252

253253
const name =
@@ -257,7 +257,7 @@ export function validateProps(
257257
warn(
258258
`sponsors[${index}].name must be a non-empty string. This sponsor will be ignored.`,
259259
);
260-
return false;
260+
return normalized;
261261
}
262262

263263
let sponsorshipTier = sponsor.sponsorshipTier;
@@ -277,16 +277,19 @@ export function validateProps(
277277
sponsorshipTier = undefined;
278278
}
279279

280-
sponsor.name = name;
280+
// Build a brand-new sponsor object instead of mutating the
281+
// caller-owned one — omit sponsorshipTier from the spread first,
282+
// then add it back only if it's valid.
283+
const { sponsorshipTier: _originalTier, ...sponsorRest } = sponsor;
281284

282-
if (sponsorshipTier === undefined) {
283-
delete sponsor.sponsorshipTier;
284-
} else {
285-
sponsor.sponsorshipTier = sponsorshipTier;
286-
}
285+
normalized.push(
286+
sponsorshipTier === undefined
287+
? { ...sponsorRest, name }
288+
: { ...sponsorRest, name, sponsorshipTier },
289+
);
287290

288-
return true;
289-
});
291+
return normalized;
292+
}, [] as typeof sponsors);
290293
}
291294
} else {
292295
sponsors = [];
@@ -316,12 +319,12 @@ export function validateProps(
316319
sponsorLink: [],
317320
};
318321
} else {
319-
const sponsorLink = ctaSection.sponsorLink.filter((link, index) => {
322+
const sponsorLink = ctaSection.sponsorLink.reduce((normalized, link, index) => {
320323
if (!isObject(link)) {
321324
warn(
322325
`ctaSection.sponsorLink[${index}] must be an object. This link will be ignored.`,
323326
);
324-
return false;
327+
return normalized;
325328
}
326329

327330
const name = typeof link.name === "string" ? link.name.trim() : "";
@@ -330,20 +333,22 @@ export function validateProps(
330333
warn(
331334
`ctaSection.sponsorLink[${index}].name must be a non-empty string. This link will be ignored.`,
332335
);
333-
return false;
336+
return normalized;
334337
}
335338

336339
if (!isValidUrl(link.url)) {
337340
warn(
338341
`ctaSection.sponsorLink[${index}].url must be a valid http(s) URL. This link will be ignored.`,
339342
);
340-
return false;
343+
return normalized;
341344
}
342345

343-
link.name = name;
346+
// Build a brand-new link object instead of mutating the
347+
// caller-owned one.
348+
normalized.push({ ...link, name });
344349

345-
return true;
346-
});
350+
return normalized;
351+
}, [] as typeof ctaSection.sponsorLink);
347352

348353
if (sponsorLink.length === 0) {
349354
warn(

0 commit comments

Comments
 (0)