feat: 支持插件声明运行时配置键

This commit is contained in:
sunlei 2026-06-18 01:59:34 +08:00
parent 00f9e662f6
commit 374c1ba0de
3 changed files with 45 additions and 0 deletions

View File

@ -82,6 +82,28 @@ const getStringArray = (
.filter(Boolean);
};
/**
* Normalizes config keys declared by a plugin package manifest.
*
* @param rawKeys - Manifest-provided values from `runtime.configKeys`; these are package-owned
* names used by the generic host to preload configuration without hard-coding plugin keys.
* @returns Unique non-empty config keys in declaration order.
*/
function parseConfigKeys(rawKeys: unknown): string[] {
if (!Array.isArray(rawKeys)) {
return [];
}
return Array.from(
new Set(
rawKeys
.filter((key): key is string => typeof key === 'string')
.map((key) => key.trim())
.filter((key) => key.length > 0),
),
);
}
/**
* QQBot
* @param source - source
@ -276,6 +298,7 @@ const parseRuntime = (
}
return {
configKeys: parseConfigKeys(runtime.configKeys),
maxConcurrency: maxConcurrency || 1,
memoryMb: memoryMb || 128,
timeoutMs: timeoutMs || 1000,

View File

@ -21,6 +21,7 @@ export type QqbotPluginPermission =
export type QqbotPluginWorkerType = (typeof QQBOT_PLUGIN_WORKER_TYPES)[number];
export type QqbotPluginRuntimeManifest = {
configKeys: string[];
maxConcurrency: number;
memoryMb: number;
timeoutMs: number;

View File

@ -155,6 +155,27 @@ describe('QQBot plugin manifest contract', () => {
);
});
it('normalizes runtime config keys without platform-owned plugin knowledge', () => {
const validManifest = createValidManifest();
const manifest = parseQqbotPluginManifest({
...validManifest,
runtime: {
...validManifest.runtime,
configKeys: [
'SAMPLE_TOKEN',
' SAMPLE_TIMEOUT_MS ',
'',
'SAMPLE_TOKEN',
],
},
});
expect(manifest.runtime.configKeys).toEqual([
'SAMPLE_TOKEN',
'SAMPLE_TIMEOUT_MS',
]);
});
it('rejects unknown permissions from both plugin and operation scopes', () => {
const manifest = createValidManifest();
manifest.permissions = ['qqbot.send', 'host.env.read'];