mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 07:30:43 +00:00
refactor: gate setup promotion by manifest feature
This commit is contained in:
@@ -30,6 +30,9 @@
|
||||
"./index.ts"
|
||||
],
|
||||
"setupEntry": "./setup-entry.ts",
|
||||
"setupFeatures": {
|
||||
"configPromotion": true
|
||||
},
|
||||
"channel": {
|
||||
"id": "matrix",
|
||||
"label": "Matrix",
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
],
|
||||
"setupEntry": "./setup-entry.ts",
|
||||
"setupFeatures": {
|
||||
"configPromotion": true,
|
||||
"legacyStateMigrations": true
|
||||
},
|
||||
"channel": {
|
||||
|
||||
@@ -50,6 +50,11 @@ type BundledChannelSetupEntryRuntimeContract = {
|
||||
};
|
||||
};
|
||||
|
||||
type BundledChannelPackageSetupFeature =
|
||||
| "configPromotion"
|
||||
| "legacyStateMigrations"
|
||||
| "legacySessionSurfaces";
|
||||
|
||||
type GeneratedBundledChannelEntry = {
|
||||
id: string;
|
||||
entry: BundledChannelEntryRuntimeContract;
|
||||
@@ -507,6 +512,16 @@ export function listBundledChannelPluginIds(): readonly ChannelId[] {
|
||||
return listBundledChannelPluginIdsForRoot(resolveBundledChannelRootScope());
|
||||
}
|
||||
|
||||
export function hasBundledChannelPackageSetupFeature(
|
||||
id: ChannelId,
|
||||
feature: BundledChannelPackageSetupFeature,
|
||||
): boolean {
|
||||
const rootScope = resolveBundledChannelRootScope();
|
||||
return (
|
||||
resolveBundledChannelMetadata(id, rootScope)?.packageManifest?.setupFeatures?.[feature] === true
|
||||
);
|
||||
}
|
||||
|
||||
function resolveBundledChannelMetadata(
|
||||
id: ChannelId,
|
||||
rootScope: BundledChannelRootScope,
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
const getBundledChannelPluginMock = vi.hoisted(() => vi.fn());
|
||||
const hasBundledChannelPackageSetupFeatureMock = vi.hoisted(() => vi.fn());
|
||||
const getLoadedChannelPluginMock = vi.hoisted(() => vi.fn());
|
||||
|
||||
vi.mock("./bundled.js", () => ({
|
||||
getBundledChannelPlugin: getBundledChannelPluginMock,
|
||||
hasBundledChannelPackageSetupFeature: hasBundledChannelPackageSetupFeatureMock,
|
||||
}));
|
||||
|
||||
vi.mock("./registry.js", () => ({
|
||||
@@ -19,6 +21,8 @@ import {
|
||||
describe("setup promotion helpers", () => {
|
||||
beforeEach(() => {
|
||||
getBundledChannelPluginMock.mockReset();
|
||||
hasBundledChannelPackageSetupFeatureMock.mockReset();
|
||||
hasBundledChannelPackageSetupFeatureMock.mockReturnValue(false);
|
||||
getLoadedChannelPluginMock.mockReset();
|
||||
});
|
||||
|
||||
@@ -38,9 +42,9 @@ describe("setup promotion helpers", () => {
|
||||
expect(getBundledChannelPluginMock).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("keeps WhatsApp static promotion cheap even when named accounts already exist", () => {
|
||||
it("skips bundled setup promotion without a manifest feature", () => {
|
||||
const keys = resolveSingleAccountKeysToMove({
|
||||
channelKey: "whatsapp",
|
||||
channelKey: "demo",
|
||||
channel: {
|
||||
accounts: {
|
||||
work: { enabled: true },
|
||||
@@ -53,11 +57,16 @@ describe("setup promotion helpers", () => {
|
||||
});
|
||||
|
||||
expect(keys).toEqual(["dmPolicy", "allowFrom", "groupPolicy", "groupAllowFrom"]);
|
||||
expect(getLoadedChannelPluginMock).toHaveBeenCalledWith("whatsapp");
|
||||
expect(getLoadedChannelPluginMock).toHaveBeenCalledWith("demo");
|
||||
expect(hasBundledChannelPackageSetupFeatureMock).toHaveBeenCalledWith(
|
||||
"demo",
|
||||
"configPromotion",
|
||||
);
|
||||
expect(getBundledChannelPluginMock).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("loads bundled setup only for non-static migration keys", () => {
|
||||
hasBundledChannelPackageSetupFeatureMock.mockReturnValue(true);
|
||||
getBundledChannelPluginMock.mockReturnValue({
|
||||
setup: {
|
||||
singleAccountKeysToMove: ["customAuth"],
|
||||
@@ -96,6 +105,7 @@ describe("setup promotion helpers", () => {
|
||||
});
|
||||
|
||||
it("loads bundled setup for named-account filters before registry bootstrap", () => {
|
||||
hasBundledChannelPackageSetupFeatureMock.mockReturnValue(true);
|
||||
getBundledChannelPluginMock.mockReturnValue({
|
||||
setup: {
|
||||
namedAccountPromotionKeys: ["token"],
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "../../routing/session-key.js";
|
||||
import { normalizeOptionalString } from "../../shared/string-coerce.js";
|
||||
import { getBundledChannelPlugin } from "./bundled.js";
|
||||
import { getBundledChannelPlugin, hasBundledChannelPackageSetupFeature } from "./bundled.js";
|
||||
import { getLoadedChannelPlugin } from "./registry.js";
|
||||
|
||||
type ChannelSectionBase = {
|
||||
@@ -49,8 +49,6 @@ type ChannelSetupPromotionSurface = {
|
||||
}) => string | undefined;
|
||||
};
|
||||
|
||||
const BUNDLED_CHANNELS_WITHOUT_SETUP_PROMOTION_SURFACE = new Set(["whatsapp"]);
|
||||
|
||||
function asPromotionSurface(setup: unknown): ChannelSetupPromotionSurface | null {
|
||||
return setup && typeof setup === "object" ? (setup as ChannelSetupPromotionSurface) : null;
|
||||
}
|
||||
@@ -64,7 +62,7 @@ function getLoadedChannelSetupPromotionSurface(
|
||||
function getBundledChannelSetupPromotionSurface(
|
||||
channelKey: string,
|
||||
): ChannelSetupPromotionSurface | null {
|
||||
if (BUNDLED_CHANNELS_WITHOUT_SETUP_PROMOTION_SURFACE.has(channelKey)) {
|
||||
if (!hasBundledChannelPackageSetupFeature(channelKey, "configPromotion")) {
|
||||
return null;
|
||||
}
|
||||
return asPromotionSurface(getBundledChannelPlugin(channelKey)?.setup);
|
||||
|
||||
@@ -975,6 +975,7 @@ export type OpenClawPackageStartup = {
|
||||
};
|
||||
|
||||
export type OpenClawPackageSetupFeatures = {
|
||||
configPromotion?: boolean;
|
||||
legacyStateMigrations?: boolean;
|
||||
legacySessionSurfaces?: boolean;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user