Files
TREK/server/src/nest/addons/addon-gate.ts
T
Maurice 724c88c201 style: format server and shared with prettier
A mechanical prettier --write over server/src, server/tests, server/scripts
and shared/src with the workspaces' .prettierrc; nothing but layout and
import order changes, and every file keeps the same set of imports. shared
is formatted throughout and its format baseline is empty. The server
baseline keeps the 35 files that Prettier would grow past their lint:size
limit (they need a split first, which is not a formatting change), and the
generated entity files stay as their generator writes them.
2026-10-10 21:23:37 +02:00

41 lines
1.7 KiB
TypeScript

import { ADDON_IDS } from '../../addons';
import type { McpContext } from '../../nest-mcp';
import type { AddonsService } from './addons.service';
/**
* The `when:` gates for addon-scoped MCP surfaces.
*
* They used to close over `addons.bridge`, which builds its own AddonsService
* outside the container. That was never a preference — a decorator's options
* object is built while the class is being defined, so the closure had no
* `this` to reach an injected service through, and nine domains hid an edge to
* the addons domain from the module graph to answer one boolean.
*
* `src/nest-mcp` now hands the gate the declaring controller instance, so the
* only thing a domain has to do is expose the service it already injects:
*
* constructor(private readonly vacay: VacayService, readonly addons: AddonsService) {}
* const vacayAddonOn = addonGate(ADDON_IDS.VACAY);
*
* `addons` is public rather than private because the gate is a module-level
* function in the same file, not a method — TypeScript's `private` is scoped to
* the class body.
*/
export interface HasAddons {
readonly addons: AddonsService;
}
/** Gate an MCP entry on an addon being enabled. */
export function addonGate(addonId: string) {
return (_ctx: McpContext, self: HasAddons): Promise<boolean> => self.addons.isAddonEnabled(addonId);
}
/**
* Gate on one of collab's sub-feature flags. Every collab entry rides both the
* addon toggle and its own flag — notes, polls or chat.
*/
export function collabFeatureGate(feature: 'chat' | 'notes' | 'polls') {
return async (_ctx: McpContext, self: HasAddons): Promise<boolean> =>
(await self.addons.isAddonEnabled(ADDON_IDS.COLLAB)) && (await self.addons.getCollabFeatures())[feature];
}