MCPcopy
hub / github.com/lobehub/lobehub / registerAllowlistCommand

Function registerAllowlistCommand

apps/cli/src/commands/bot.ts:149–271  ·  view source on GitHub ↗

* Build a `list / add / remove / clear` subcommand group around an * array-typed settings field (`allowFrom` or `groupAllowFrom`). All write * paths read existing settings first and merge — passing only a partial * `settings` object to the TRPC `update` would replace the whole JSONB * column and

(bot: Command, opts: AllowlistGroupOptions)

Source from the content-addressed store, hash-verified

147 * column and silently drop unrelated fields.
148 */
149function registerAllowlistCommand(bot: Command, opts: AllowlistGroupOptions) {
150 const group = bot.command(opts.name).description(opts.description);
151
152 // Read the current entries off a freshly-fetched bot row.
153 const readEntries = (bot: any): AllowEntry[] =>
154 normalizeAllowList((bot.settings as Record<string, unknown> | null)?.[opts.fieldKey]);
155
156 // Build the next settings payload from existing settings + the new entries.
157 const buildPayload = (bot: any, nextEntries: AllowEntry[]) => ({
158 id: bot.id,
159 settings: {
160 ...(bot.settings as Record<string, unknown>),
161 [opts.fieldKey]: nextEntries,
162 },
163 });
164
165 group
166 .command('list <botId>')
167 .description(`List ${opts.fieldKey} entries`)
168 .option('--json', 'Output JSON')
169 .action(async (botId: string, options: { json?: boolean }) => {
170 const client = await getTrpcClient();
171 const b = await findBot(client, botId);
172 const entries = readEntries(b);
173
174 if (options.json) {
175 outputJson(entries);
176 return;
177 }
178
179 if (entries.length === 0) {
180 console.log(`${pc.dim(`No ${opts.fieldKey} entries.`)}`);
181 return;
182 }
183
184 printTable(
185 entries.map((e) => [e.id, e.name ?? pc.dim('-')]),
186 ['ID', 'NAME'],
187 );
188 });
189
190 group
191 .command('add <botId> <id>')
192 .description(`Add a ${opts.idLabel} to ${opts.fieldKey}`)
193 .option('--name <name>', 'Optional human-friendly label so you can recognise the entry later')
194 .action(async (botId: string, id: string, options: { name?: string }) => {
195 const trimmedId = id.trim();
196 if (!trimmedId) {
197 log.error('ID cannot be empty.');
198 process.exit(1);
199 return;
200 }
201
202 const client = await getTrpcClient();
203 const b = await findBot(client, botId);
204 const entries = readEntries(b);
205
206 if (entries.some((e) => e.id === trimmedId)) {

Callers 1

registerBotCommandFunction · 0.85

Calls 8

getTrpcClientFunction · 0.90
outputJsonFunction · 0.90
printTableFunction · 0.90
confirmFunction · 0.90
findBotFunction · 0.85
readEntriesFunction · 0.85
logMethod · 0.80
buildPayloadFunction · 0.70

Tested by

no test coverage detected