Spaces:
Runtime error
Runtime error
File size: 2,446 Bytes
46252cd | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | /**
* Per-session activation gate. A plugin declares whether it is session-scoped (the default); the
* operator then activates it for all sessions (`['*']`) or an explicit set. A global plugin
* (`sessionScoped === false`, e.g. a metrics logger) ignores this and is always active.
*
* A non-session-attributed event (no `sessionId`) is never gated — the plugin chose to register that
* hook, and there is no number to scope it to.
*/
export function isPluginActiveForSession(
sessionScoped: boolean,
activeSessions: string[],
sessionId: string | undefined,
): boolean {
if (!sessionScoped) return true;
if (sessionId === undefined) return true;
if (activeSessions.includes('*')) return true;
return activeSessions.includes(sessionId);
}
const isPlainObject = (v: unknown): v is Record<string, unknown> =>
typeof v === 'object' && v !== null && !Array.isArray(v);
/**
* Recursively merge `override` over `base`: nested plain objects merge key-by-key so an override that
* sets only some keys inherits the rest from the base (incl. nested secrets); arrays and scalars are
* replaced wholesale. Returns fresh objects; never mutates the inputs.
*/
function deepMerge(base: Record<string, unknown>, override: Record<string, unknown>): Record<string, unknown> {
const out: Record<string, unknown> = { ...base };
for (const [key, value] of Object.entries(override)) {
const baseValue = out[key];
out[key] = isPlainObject(baseValue) && isPlainObject(value) ? deepMerge(baseValue, value) : value;
}
return out;
}
/**
* Resolve the config a plugin sees for a given session: the per-session override (if any) deep-merged
* over the base ('*') config, so an override only changes the keys it specifies (at any depth) and
* inherits the rest from the base — a sparse override can't drop a base key (e.g. a nested secret) it
* didn't touch. A global plugin and a non-session-attributed event (no sessionId) get the base
* unchanged. Returns a fresh object on merge; never mutates the inputs.
*/
export function resolvePluginConfig(
base: Record<string, unknown>,
sessionConfig: Record<string, Record<string, unknown>> | undefined,
sessionId: string | undefined,
sessionScoped: boolean,
): Record<string, unknown> {
if (!sessionScoped || sessionId === undefined || !sessionConfig) return base;
const override = sessionConfig[sessionId];
return override ? deepMerge(base, override) : base;
}
|