From 34afe10b002bdf0e2b90be442ccd42be232b9d95 Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Tue, 14 Apr 2026 17:08:13 +0100 Subject: [PATCH] perf(config): skip duplicate channel legacy rule loads --- src/channels/plugins/legacy-config.test.ts | 31 ++++++++++++++++++++++ src/channels/plugins/legacy-config.ts | 17 +++++++++--- src/config/legacy.ts | 17 +++++++++++- 3 files changed, 60 insertions(+), 5 deletions(-) diff --git a/src/channels/plugins/legacy-config.test.ts b/src/channels/plugins/legacy-config.test.ts index fb65f43f30c..63024fca5d4 100644 --- a/src/channels/plugins/legacy-config.test.ts +++ b/src/channels/plugins/legacy-config.test.ts @@ -136,4 +136,35 @@ describe("collectChannelLegacyConfigRules", () => { expect(loadBundledChannelDoctorContractApiMock).toHaveBeenCalledTimes(1); expect(loadBundledChannelDoctorContractApiMock).toHaveBeenCalledWith("discord"); }); + + it("skips channel ids already covered by explicit legacy rules", () => { + loadBundledChannelDoctorContractApiMock.mockImplementation((channelId: string) => ({ + legacyConfigRules: [ + { + path: ["channels", channelId], + message: `legacy ${channelId} rule`, + }, + ], + })); + + const rules = collectChannelLegacyConfigRules( + { + channels: { + discord: {}, + telegram: {}, + }, + }, + undefined, + new Set(["telegram"]), + ); + + expect(rules).toEqual([ + { + path: ["channels", "discord"], + message: "legacy discord rule", + }, + ]); + expect(loadBundledChannelDoctorContractApiMock).toHaveBeenCalledTimes(1); + expect(loadBundledChannelDoctorContractApiMock).toHaveBeenCalledWith("discord"); + }); }); diff --git a/src/channels/plugins/legacy-config.ts b/src/channels/plugins/legacy-config.ts index 884c6c6fb84..3ac6c966590 100644 --- a/src/channels/plugins/legacy-config.ts +++ b/src/channels/plugins/legacy-config.ts @@ -38,10 +38,14 @@ function shouldIncludeLegacyRuleForTouchedPaths( function collectRelevantChannelIdsForTouchedPaths(params: { raw?: unknown; touchedPaths?: ReadonlyArray>; + excludedChannelIds?: ReadonlySet; }): ChannelId[] { const channelIds = collectConfiguredChannelIds(params.raw); + const filteredChannelIds = params.excludedChannelIds?.size + ? channelIds.filter((channelId) => !params.excludedChannelIds?.has(channelId)) + : channelIds; if (!params.touchedPaths || params.touchedPaths.length === 0) { - return channelIds; + return filteredChannelIds; } const touchedChannelIds = new Set(); @@ -51,7 +55,7 @@ function collectRelevantChannelIdsForTouchedPaths(params: { continue; } if (!second) { - return channelIds; + return filteredChannelIds; } if (second === "defaults") { continue; @@ -62,14 +66,19 @@ function collectRelevantChannelIdsForTouchedPaths(params: { if (touchedChannelIds.size === 0) { return []; } - return channelIds.filter((channelId) => touchedChannelIds.has(channelId)); + return filteredChannelIds.filter((channelId) => touchedChannelIds.has(channelId)); } export function collectChannelLegacyConfigRules( raw?: unknown, touchedPaths?: ReadonlyArray>, + excludedChannelIds?: ReadonlySet, ): LegacyConfigRule[] { - const channelIds = collectRelevantChannelIdsForTouchedPaths({ raw, touchedPaths }); + const channelIds = collectRelevantChannelIdsForTouchedPaths({ + raw, + touchedPaths, + excludedChannelIds, + }); const rules: LegacyConfigRule[] = []; const unresolvedChannelIds: ChannelId[] = []; for (const channelId of channelIds) { diff --git a/src/config/legacy.ts b/src/config/legacy.ts index 79bac2bd033..1fb703432d5 100644 --- a/src/config/legacy.ts +++ b/src/config/legacy.ts @@ -14,6 +14,20 @@ function getPathValue(root: Record, path: string[]): unknown { return cursor; } +function collectExplicitRuleOwnedChannelIds( + extraRules: readonly LegacyConfigRule[], +): ReadonlySet | undefined { + const channelIds = new Set(); + for (const rule of extraRules) { + const [first, second] = rule.path; + if (first !== "channels" || typeof second !== "string" || second === "defaults") { + continue; + } + channelIds.add(second); + } + return channelIds.size > 0 ? channelIds : undefined; +} + export function findLegacyConfigIssues( raw: unknown, sourceRaw?: unknown, @@ -27,9 +41,10 @@ export function findLegacyConfigIssues( const sourceRoot = sourceRaw && typeof sourceRaw === "object" ? (sourceRaw as Record) : root; const issues: LegacyConfigIssue[] = []; + const explicitRuleOwnedChannelIds = collectExplicitRuleOwnedChannelIds(extraRules); for (const rule of [ ...LEGACY_CONFIG_RULES, - ...collectChannelLegacyConfigRules(raw, touchedPaths), + ...collectChannelLegacyConfigRules(raw, touchedPaths, explicitRuleOwnedChannelIds), ...extraRules, ]) { const cursor = getPathValue(root, rule.path);