mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-09 09:47:40 +00:00
refactor: split providers commands
This commit is contained in:
260
src/commands/providers/remove.ts
Normal file
260
src/commands/providers/remove.ts
Normal file
@@ -0,0 +1,260 @@
|
||||
import { type ClawdbotConfig, writeConfigFile } from "../../config/config.js";
|
||||
import { listDiscordAccountIds } from "../../discord/accounts.js";
|
||||
import { listIMessageAccountIds } from "../../imessage/accounts.js";
|
||||
import {
|
||||
listChatProviders,
|
||||
normalizeChatProviderId,
|
||||
} from "../../providers/registry.js";
|
||||
import {
|
||||
DEFAULT_ACCOUNT_ID,
|
||||
normalizeAccountId,
|
||||
} from "../../routing/session-key.js";
|
||||
import { defaultRuntime, type RuntimeEnv } from "../../runtime.js";
|
||||
import { listSignalAccountIds } from "../../signal/accounts.js";
|
||||
import { listSlackAccountIds } from "../../slack/accounts.js";
|
||||
import { listTelegramAccountIds } from "../../telegram/accounts.js";
|
||||
import { listWhatsAppAccountIds } from "../../web/accounts.js";
|
||||
import { createClackPrompter } from "../../wizard/clack-prompter.js";
|
||||
import {
|
||||
type ChatProvider,
|
||||
providerLabel,
|
||||
requireValidConfig,
|
||||
shouldUseWizard,
|
||||
} from "./shared.js";
|
||||
|
||||
export type ProvidersRemoveOptions = {
|
||||
provider?: string;
|
||||
account?: string;
|
||||
delete?: boolean;
|
||||
};
|
||||
|
||||
function listAccountIds(cfg: ClawdbotConfig, provider: ChatProvider): string[] {
|
||||
switch (provider) {
|
||||
case "whatsapp":
|
||||
return listWhatsAppAccountIds(cfg);
|
||||
case "telegram":
|
||||
return listTelegramAccountIds(cfg);
|
||||
case "discord":
|
||||
return listDiscordAccountIds(cfg);
|
||||
case "slack":
|
||||
return listSlackAccountIds(cfg);
|
||||
case "signal":
|
||||
return listSignalAccountIds(cfg);
|
||||
case "imessage":
|
||||
return listIMessageAccountIds(cfg);
|
||||
}
|
||||
}
|
||||
|
||||
export async function providersRemoveCommand(
|
||||
opts: ProvidersRemoveOptions,
|
||||
runtime: RuntimeEnv = defaultRuntime,
|
||||
params?: { hasFlags?: boolean },
|
||||
) {
|
||||
const cfg = await requireValidConfig(runtime);
|
||||
if (!cfg) return;
|
||||
|
||||
const useWizard = shouldUseWizard(params);
|
||||
const prompter = useWizard ? createClackPrompter() : null;
|
||||
let provider = normalizeChatProviderId(opts.provider);
|
||||
let accountId = normalizeAccountId(opts.account);
|
||||
const deleteConfig = Boolean(opts.delete);
|
||||
|
||||
if (useWizard && prompter) {
|
||||
await prompter.intro("Remove provider account");
|
||||
provider = (await prompter.select({
|
||||
message: "Provider",
|
||||
options: listChatProviders().map((meta) => ({
|
||||
value: meta.id,
|
||||
label: meta.label,
|
||||
})),
|
||||
})) as ChatProvider;
|
||||
|
||||
accountId = await (async () => {
|
||||
const ids = listAccountIds(cfg, provider);
|
||||
const choice = (await prompter.select({
|
||||
message: "Account",
|
||||
options: ids.map((id) => ({
|
||||
value: id,
|
||||
label: id === DEFAULT_ACCOUNT_ID ? "default (primary)" : id,
|
||||
})),
|
||||
initialValue: ids[0] ?? DEFAULT_ACCOUNT_ID,
|
||||
})) as string;
|
||||
return normalizeAccountId(choice);
|
||||
})();
|
||||
|
||||
const wantsDisable = await prompter.confirm({
|
||||
message: `Disable ${providerLabel(provider)} account "${accountId}"? (keeps config)`,
|
||||
initialValue: true,
|
||||
});
|
||||
if (!wantsDisable) {
|
||||
await prompter.outro("Cancelled.");
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (!provider) {
|
||||
runtime.error("Provider is required. Use --provider <name>.");
|
||||
runtime.exit(1);
|
||||
return;
|
||||
}
|
||||
if (!deleteConfig) {
|
||||
const confirm = createClackPrompter();
|
||||
const ok = await confirm.confirm({
|
||||
message: `Disable ${providerLabel(provider)} account "${accountId}"? (keeps config)`,
|
||||
initialValue: true,
|
||||
});
|
||||
if (!ok) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let next = { ...cfg };
|
||||
const accountKey = accountId || DEFAULT_ACCOUNT_ID;
|
||||
|
||||
const setAccountEnabled = (key: ChatProvider, enabled: boolean) => {
|
||||
if (key === "whatsapp") {
|
||||
next = {
|
||||
...next,
|
||||
whatsapp: {
|
||||
...next.whatsapp,
|
||||
accounts: {
|
||||
...next.whatsapp?.accounts,
|
||||
[accountKey]: {
|
||||
...next.whatsapp?.accounts?.[accountKey],
|
||||
enabled,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
return;
|
||||
}
|
||||
const base = (next as Record<string, unknown>)[key] as
|
||||
| {
|
||||
accounts?: Record<string, Record<string, unknown>>;
|
||||
enabled?: boolean;
|
||||
}
|
||||
| undefined;
|
||||
const baseAccounts: Record<
|
||||
string,
|
||||
Record<string, unknown>
|
||||
> = base?.accounts ?? {};
|
||||
const existingAccount = baseAccounts[accountKey] ?? {};
|
||||
if (accountKey === DEFAULT_ACCOUNT_ID && !base?.accounts) {
|
||||
next = {
|
||||
...next,
|
||||
[key]: {
|
||||
...base,
|
||||
enabled,
|
||||
},
|
||||
} as ClawdbotConfig;
|
||||
return;
|
||||
}
|
||||
next = {
|
||||
...next,
|
||||
[key]: {
|
||||
...base,
|
||||
accounts: {
|
||||
...baseAccounts,
|
||||
[accountKey]: {
|
||||
...existingAccount,
|
||||
enabled,
|
||||
},
|
||||
},
|
||||
},
|
||||
} as ClawdbotConfig;
|
||||
};
|
||||
|
||||
const deleteAccount = (key: ChatProvider) => {
|
||||
if (key === "whatsapp") {
|
||||
const accounts = { ...next.whatsapp?.accounts };
|
||||
delete accounts[accountKey];
|
||||
next = {
|
||||
...next,
|
||||
whatsapp: {
|
||||
...next.whatsapp,
|
||||
accounts: Object.keys(accounts).length ? accounts : undefined,
|
||||
},
|
||||
};
|
||||
return;
|
||||
}
|
||||
const base = (next as Record<string, unknown>)[key] as
|
||||
| {
|
||||
accounts?: Record<string, Record<string, unknown>>;
|
||||
enabled?: boolean;
|
||||
}
|
||||
| undefined;
|
||||
if (accountKey !== DEFAULT_ACCOUNT_ID) {
|
||||
const accounts = { ...base?.accounts };
|
||||
delete accounts[accountKey];
|
||||
next = {
|
||||
...next,
|
||||
[key]: {
|
||||
...base,
|
||||
accounts: Object.keys(accounts).length ? accounts : undefined,
|
||||
},
|
||||
} as ClawdbotConfig;
|
||||
return;
|
||||
}
|
||||
if (base?.accounts && Object.keys(base.accounts).length > 0) {
|
||||
const accounts = { ...base.accounts };
|
||||
delete accounts[accountKey];
|
||||
next = {
|
||||
...next,
|
||||
[key]: {
|
||||
...base,
|
||||
accounts: Object.keys(accounts).length ? accounts : undefined,
|
||||
...(key === "telegram"
|
||||
? { botToken: undefined, tokenFile: undefined, name: undefined }
|
||||
: key === "discord"
|
||||
? { token: undefined, name: undefined }
|
||||
: key === "slack"
|
||||
? { botToken: undefined, appToken: undefined, name: undefined }
|
||||
: key === "signal"
|
||||
? {
|
||||
account: undefined,
|
||||
httpUrl: undefined,
|
||||
httpHost: undefined,
|
||||
httpPort: undefined,
|
||||
cliPath: undefined,
|
||||
name: undefined,
|
||||
}
|
||||
: key === "imessage"
|
||||
? {
|
||||
cliPath: undefined,
|
||||
dbPath: undefined,
|
||||
service: undefined,
|
||||
region: undefined,
|
||||
name: undefined,
|
||||
}
|
||||
: {}),
|
||||
},
|
||||
} as ClawdbotConfig;
|
||||
return;
|
||||
}
|
||||
// No accounts map: remove entire provider section.
|
||||
const clone = { ...next } as Record<string, unknown>;
|
||||
delete clone[key];
|
||||
next = clone as ClawdbotConfig;
|
||||
};
|
||||
|
||||
if (deleteConfig) {
|
||||
deleteAccount(provider);
|
||||
} else {
|
||||
setAccountEnabled(provider, false);
|
||||
}
|
||||
|
||||
await writeConfigFile(next);
|
||||
if (useWizard && prompter) {
|
||||
await prompter.outro(
|
||||
deleteConfig
|
||||
? `Deleted ${providerLabel(provider)} account "${accountKey}".`
|
||||
: `Disabled ${providerLabel(provider)} account "${accountKey}".`,
|
||||
);
|
||||
} else {
|
||||
runtime.log(
|
||||
deleteConfig
|
||||
? `Deleted ${providerLabel(provider)} account "${accountKey}".`
|
||||
: `Disabled ${providerLabel(provider)} account "${accountKey}".`,
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user