





















@@ -138,6 +138,71 @@ export type ChannelUiMetadata = {
138138configUiHints?: Record<string, ConfigUiHint>;
139139};
140140141+const EXTENSION_SCHEMA_MAX_BYTES = 256 * 1024;
142+const EXTENSION_SCHEMA_TOTAL_MAX_BYTES = 2 * 1024 * 1024;
143+const EXTENSION_SCHEMA_MAX_ITEMS = 256;
144+145+function schemaJsonBytes(schema: JsonSchemaNode): number {
146+try {
147+return Buffer.byteLength(JSON.stringify(schema), "utf-8");
148+} catch {
149+return Number.POSITIVE_INFINITY;
150+}
151+}
152+153+function buildOmittedExtensionConfigSchema(kind: "plugin" | "channel", id: string): JsonSchemaNode {
154+return {
155+type: "object",
156+additionalProperties: true,
157+description: `${kind} config schema for ${id} was omitted from the full config.schema response because installed extension schemas exceeded the Gateway response budget.`,
158+};
159+}
160+161+function limitExtensionSchemas(params: {
162+plugins: PluginUiMetadata[];
163+channels: ChannelUiMetadata[];
164+}): { plugins: PluginUiMetadata[]; channels: ChannelUiMetadata[] } {
165+let totalBytes = 0;
166+let includedItems = 0;
167+168+const keepSchema = (schema: JsonSchemaNode): boolean => {
169+const bytes = schemaJsonBytes(schema);
170+if (
171+!Number.isFinite(bytes) ||
172+bytes > EXTENSION_SCHEMA_MAX_BYTES ||
173+totalBytes + bytes > EXTENSION_SCHEMA_TOTAL_MAX_BYTES ||
174+includedItems >= EXTENSION_SCHEMA_MAX_ITEMS
175+) {
176+return false;
177+}
178+totalBytes += bytes;
179+includedItems += 1;
180+return true;
181+};
182+183+const plugins = params.plugins.map((plugin) => {
184+if (!plugin.configSchema || keepSchema(plugin.configSchema)) {
185+return plugin;
186+}
187+return {
188+ ...plugin,
189+configSchema: buildOmittedExtensionConfigSchema("plugin", plugin.id),
190+};
191+});
192+193+const channels = params.channels.map((channel) => {
194+if (!channel.configSchema || keepSchema(channel.configSchema)) {
195+return channel;
196+}
197+return {
198+ ...channel,
199+configSchema: buildOmittedExtensionConfigSchema("channel", channel.id),
200+};
201+});
202+203+return { plugins, channels };
204+}
205+141206function collectExtensionHintKeys(
142207hints: ConfigUiHints,
143208plugins: PluginUiMetadata[],
@@ -487,8 +552,10 @@ export function buildConfigSchema(params?: {
487552cache?: boolean;
488553}): ConfigSchemaResponse {
489554const base = buildBaseConfigSchema();
490-const plugins = params?.plugins ?? [];
491-const channels = params?.channels ?? [];
555+const { plugins, channels } = limitExtensionSchemas({
556+plugins: params?.plugins ?? [],
557+channels: params?.channels ?? [],
558+});
492559if (plugins.length === 0 && channels.length === 0) {
493560return base;
494561}
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。