refactor(setup): support account-scoped default patches

This commit is contained in:
Peter Steinberger
2026-03-17 03:51:02 +00:00
parent 78869f1517
commit c51842660f
3 changed files with 46 additions and 52 deletions

View File

@@ -1,52 +1,12 @@
import {
applyAccountNameToChannelSection,
type ChannelSetupAdapter,
migrateBaseNameToDefaultAccount,
normalizeAccountId,
} from "../../../src/plugin-sdk-internal/setup.js";
import { createPatchedAccountSetupAdapter } from "../../../src/channels/plugins/setup-helpers.js";
import type { ChannelSetupAdapter } from "../../../src/plugin-sdk-internal/setup.js";
const channel = "whatsapp" as const;
export const whatsappSetupAdapter: ChannelSetupAdapter = {
resolveAccountId: ({ accountId }) => normalizeAccountId(accountId),
applyAccountName: ({ cfg, accountId, name }) =>
applyAccountNameToChannelSection({
cfg,
channelKey: channel,
accountId,
name,
alwaysUseAccounts: true,
}),
applyAccountConfig: ({ cfg, accountId, input }) => {
const namedConfig = applyAccountNameToChannelSection({
cfg,
channelKey: channel,
accountId,
name: input.name,
alwaysUseAccounts: true,
});
const next = migrateBaseNameToDefaultAccount({
cfg: namedConfig,
channelKey: channel,
alwaysUseAccounts: true,
});
const entry = {
...next.channels?.whatsapp?.accounts?.[accountId],
...(input.authDir ? { authDir: input.authDir } : {}),
enabled: true,
};
return {
...next,
channels: {
...next.channels,
whatsapp: {
...next.channels?.whatsapp,
accounts: {
...next.channels?.whatsapp?.accounts,
[accountId]: entry,
},
},
},
};
},
};
export const whatsappSetupAdapter: ChannelSetupAdapter = createPatchedAccountSetupAdapter({
channelKey: channel,
alwaysUseAccounts: true,
buildPatch: (input) => ({
...(input.authDir ? { authDir: input.authDir } : {}),
}),
});

View File

@@ -130,4 +130,30 @@ describe("createPatchedAccountSetupAdapter", () => {
});
expect(next.channels?.zalo).not.toHaveProperty("name");
});
it("can store the default account in accounts.default", () => {
const adapter = createPatchedAccountSetupAdapter({
channelKey: "whatsapp",
alwaysUseAccounts: true,
buildPatch: (input) => ({ authDir: input.authDir }),
});
const next = adapter.applyAccountConfig({
cfg: asConfig({ channels: { whatsapp: {} } }),
accountId: DEFAULT_ACCOUNT_ID,
input: { name: "Phone", authDir: "/tmp/auth" },
});
expect(next.channels?.whatsapp).toMatchObject({
accounts: {
default: {
enabled: true,
name: "Phone",
authDir: "/tmp/auth",
},
},
});
expect(next.channels?.whatsapp).not.toHaveProperty("enabled");
expect(next.channels?.whatsapp).not.toHaveProperty("authDir");
});
});

View File

@@ -139,6 +139,8 @@ export function applySetupAccountConfigPatch(params: {
export function createPatchedAccountSetupAdapter(params: {
channelKey: string;
alwaysUseAccounts?: boolean;
ensureChannelEnabled?: boolean;
ensureAccountEnabled?: boolean;
validateInput?: ChannelSetupAdapter["validateInput"];
buildPatch: (input: ChannelSetupInput) => Record<string, unknown>;
}): ChannelSetupAdapter {
@@ -169,11 +171,16 @@ export function createPatchedAccountSetupAdapter(params: {
alwaysUseAccounts: params.alwaysUseAccounts,
})
: namedConfig;
return applySetupAccountConfigPatch({
const patch = params.buildPatch(input);
return patchScopedAccountConfig({
cfg: next,
channelKey: params.channelKey,
accountId,
patch: params.buildPatch(input),
patch,
accountPatch: patch,
ensureChannelEnabled: params.ensureChannelEnabled ?? !params.alwaysUseAccounts,
ensureAccountEnabled: params.ensureAccountEnabled ?? true,
scopeDefaultToAccounts: params.alwaysUseAccounts,
});
},
};
@@ -187,6 +194,7 @@ export function patchScopedAccountConfig(params: {
accountPatch?: Record<string, unknown>;
ensureChannelEnabled?: boolean;
ensureAccountEnabled?: boolean;
scopeDefaultToAccounts?: boolean;
}): OpenClawConfig {
const accountId = normalizeAccountId(params.accountId);
const channels = params.cfg.channels as Record<string, unknown> | undefined;
@@ -201,7 +209,7 @@ export function patchScopedAccountConfig(params: {
const ensureAccountEnabled = params.ensureAccountEnabled ?? ensureChannelEnabled;
const patch = params.patch;
const accountPatch = params.accountPatch ?? patch;
if (accountId === DEFAULT_ACCOUNT_ID) {
if (accountId === DEFAULT_ACCOUNT_ID && !params.scopeDefaultToAccounts) {
return {
...params.cfg,
channels: {