mirror of https://github.com/openclaw/openclaw.git
fix(ci): repair helper typing regressions
This commit is contained in:
parent
eee5d7c6b0
commit
8bc163d15f
|
|
@ -1,17 +1,17 @@
|
||||||
import type { z } from "zod";
|
import type { z } from "zod";
|
||||||
|
|
||||||
type RequireOpenAllowFromFn = (params: {
|
type RequireOpenAllowFromFn = (params: {
|
||||||
policy: unknown;
|
policy?: string;
|
||||||
allowFrom: unknown;
|
allowFrom?: Array<string | number>;
|
||||||
ctx: z.RefinementCtx;
|
ctx: z.RefinementCtx;
|
||||||
path: string[];
|
path: Array<string | number>;
|
||||||
message: string;
|
message: string;
|
||||||
}) => void;
|
}) => void;
|
||||||
|
|
||||||
export function requireChannelOpenAllowFrom(params: {
|
export function requireChannelOpenAllowFrom(params: {
|
||||||
channel: string;
|
channel: string;
|
||||||
policy: unknown;
|
policy?: string;
|
||||||
allowFrom: unknown;
|
allowFrom?: Array<string | number>;
|
||||||
ctx: z.RefinementCtx;
|
ctx: z.RefinementCtx;
|
||||||
requireOpenAllowFrom: RequireOpenAllowFromFn;
|
requireOpenAllowFrom: RequireOpenAllowFromFn;
|
||||||
}) {
|
}) {
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
import type { ChannelDirectoryAdapter } from "../../src/channels/plugins/types.js";
|
||||||
|
|
||||||
export function createDirectoryTestRuntime() {
|
export function createDirectoryTestRuntime() {
|
||||||
return {
|
return {
|
||||||
log: () => {},
|
log: () => {},
|
||||||
|
|
@ -8,15 +10,7 @@ export function createDirectoryTestRuntime() {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function expectDirectorySurface(
|
export function expectDirectorySurface(directory: ChannelDirectoryAdapter | null | undefined) {
|
||||||
directory:
|
|
||||||
| {
|
|
||||||
listPeers?: unknown;
|
|
||||||
listGroups?: unknown;
|
|
||||||
}
|
|
||||||
| null
|
|
||||||
| undefined,
|
|
||||||
) {
|
|
||||||
if (!directory) {
|
if (!directory) {
|
||||||
throw new Error("expected directory");
|
throw new Error("expected directory");
|
||||||
}
|
}
|
||||||
|
|
@ -27,7 +21,7 @@ export function expectDirectorySurface(
|
||||||
throw new Error("expected listGroups");
|
throw new Error("expected listGroups");
|
||||||
}
|
}
|
||||||
return directory as {
|
return directory as {
|
||||||
listPeers: NonNullable<typeof directory.listPeers>;
|
listPeers: NonNullable<ChannelDirectoryAdapter["listPeers"]>;
|
||||||
listGroups: NonNullable<typeof directory.listGroups>;
|
listGroups: NonNullable<ChannelDirectoryAdapter["listGroups"]>;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,29 +1,11 @@
|
||||||
type TestLogger = {
|
import type { OpenClawPluginApi } from "../../src/plugins/types.js";
|
||||||
info: () => void;
|
|
||||||
warn: () => void;
|
|
||||||
error: () => void;
|
|
||||||
debug?: () => void;
|
|
||||||
};
|
|
||||||
|
|
||||||
type TestPluginApiDefaults = {
|
type TestPluginApiInput = Partial<OpenClawPluginApi> &
|
||||||
logger: TestLogger;
|
Pick<OpenClawPluginApi, "id" | "name" | "source" | "config" | "runtime">;
|
||||||
registerTool: () => void;
|
|
||||||
registerHook: () => void;
|
|
||||||
registerHttpRoute: () => void;
|
|
||||||
registerChannel: () => void;
|
|
||||||
registerGatewayMethod: () => void;
|
|
||||||
registerCli: () => void;
|
|
||||||
registerService: () => void;
|
|
||||||
registerProvider: () => void;
|
|
||||||
registerCommand: () => void;
|
|
||||||
registerContextEngine: () => void;
|
|
||||||
resolvePath: (input: string) => string;
|
|
||||||
on: () => void;
|
|
||||||
};
|
|
||||||
|
|
||||||
export function createTestPluginApi<T extends object>(api: T): T & TestPluginApiDefaults {
|
export function createTestPluginApi(api: TestPluginApiInput): OpenClawPluginApi {
|
||||||
return {
|
return {
|
||||||
logger: { info() {}, warn() {}, error() {} },
|
logger: { info() {}, warn() {}, error() {}, debug() {} },
|
||||||
registerTool() {},
|
registerTool() {},
|
||||||
registerHook() {},
|
registerHook() {},
|
||||||
registerHttpRoute() {},
|
registerHttpRoute() {},
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||||
import { createCliRuntimeCapture } from "../test-runtime-capture.js";
|
import { createCliRuntimeCapture } from "../test-runtime-capture.js";
|
||||||
|
import type { DaemonStatus } from "./status.gather.js";
|
||||||
|
|
||||||
const gatherDaemonStatus = vi.fn(async (_opts?: unknown) => ({
|
const gatherDaemonStatus = vi.fn(
|
||||||
|
async (_opts?: unknown): Promise<DaemonStatus> => ({
|
||||||
service: {
|
service: {
|
||||||
label: "LaunchAgent",
|
label: "LaunchAgent",
|
||||||
loaded: true,
|
loaded: true,
|
||||||
|
|
@ -13,7 +15,8 @@ const gatherDaemonStatus = vi.fn(async (_opts?: unknown) => ({
|
||||||
url: "ws://127.0.0.1:18789",
|
url: "ws://127.0.0.1:18789",
|
||||||
},
|
},
|
||||||
extraServices: [],
|
extraServices: [],
|
||||||
}));
|
}),
|
||||||
|
);
|
||||||
const printDaemonStatus = vi.fn();
|
const printDaemonStatus = vi.fn();
|
||||||
|
|
||||||
const { runtimeErrors, defaultRuntime, resetRuntimeCapture } = createCliRuntimeCapture();
|
const { runtimeErrors, defaultRuntime, resetRuntimeCapture } = createCliRuntimeCapture();
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import type { RuntimeEnv } from "../runtime.js";
|
||||||
import { makeTempWorkspace } from "../test-helpers/workspace.js";
|
import { makeTempWorkspace } from "../test-helpers/workspace.js";
|
||||||
import { captureEnv } from "../test-utils/env.js";
|
import { captureEnv } from "../test-utils/env.js";
|
||||||
import { createThrowingRuntime, readJsonFile } from "./onboard-non-interactive.test-helpers.js";
|
import { createThrowingRuntime, readJsonFile } from "./onboard-non-interactive.test-helpers.js";
|
||||||
|
import type { installGatewayDaemonNonInteractive } from "./onboard-non-interactive/local/daemon-install.js";
|
||||||
|
|
||||||
const gatewayClientCalls: Array<{
|
const gatewayClientCalls: Array<{
|
||||||
url?: string;
|
url?: string;
|
||||||
|
|
@ -14,8 +15,9 @@ const gatewayClientCalls: Array<{
|
||||||
onClose?: (code: number, reason: string) => void;
|
onClose?: (code: number, reason: string) => void;
|
||||||
}> = [];
|
}> = [];
|
||||||
const ensureWorkspaceAndSessionsMock = vi.fn(async (..._args: unknown[]) => {});
|
const ensureWorkspaceAndSessionsMock = vi.fn(async (..._args: unknown[]) => {});
|
||||||
|
type InstallGatewayDaemonResult = Awaited<ReturnType<typeof installGatewayDaemonNonInteractive>>;
|
||||||
const installGatewayDaemonNonInteractiveMock = vi.hoisted(() =>
|
const installGatewayDaemonNonInteractiveMock = vi.hoisted(() =>
|
||||||
vi.fn(async () => ({ installed: true as const })),
|
vi.fn(async (): Promise<InstallGatewayDaemonResult> => ({ installed: true })),
|
||||||
);
|
);
|
||||||
const gatewayServiceMock = vi.hoisted(() => ({
|
const gatewayServiceMock = vi.hoisted(() => ({
|
||||||
label: "LaunchAgent",
|
label: "LaunchAgent",
|
||||||
|
|
|
||||||
|
|
@ -149,9 +149,14 @@ export async function runNonInteractiveOnboardingLocal(params: {
|
||||||
runtime,
|
runtime,
|
||||||
port: gatewayResult.port,
|
port: gatewayResult.port,
|
||||||
});
|
});
|
||||||
daemonInstallStatus = {
|
daemonInstallStatus = daemonInstall.installed
|
||||||
|
? {
|
||||||
requested: true,
|
requested: true,
|
||||||
installed: daemonInstall.installed,
|
installed: true,
|
||||||
|
}
|
||||||
|
: {
|
||||||
|
requested: true,
|
||||||
|
installed: false,
|
||||||
skippedReason: daemonInstall.skippedReason,
|
skippedReason: daemonInstall.skippedReason,
|
||||||
};
|
};
|
||||||
if (!daemonInstall.installed && !opts.skipHealth) {
|
if (!daemonInstall.installed && !opts.skipHealth) {
|
||||||
|
|
|
||||||
|
|
@ -7,8 +7,40 @@ import { setActivePluginRegistry } from "../../plugins/runtime.js";
|
||||||
import { createOutboundTestPlugin, createTestRegistry } from "../../test-utils/channel-plugins.js";
|
import { createOutboundTestPlugin, createTestRegistry } from "../../test-utils/channel-plugins.js";
|
||||||
import { createIMessageTestPlugin } from "../../test-utils/imessage-test-plugin.js";
|
import { createIMessageTestPlugin } from "../../test-utils/imessage-test-plugin.js";
|
||||||
import { createInternalHookEventPayload } from "../../test-utils/internal-hook-event-payload.js";
|
import { createInternalHookEventPayload } from "../../test-utils/internal-hook-event-payload.js";
|
||||||
|
import type {
|
||||||
|
DeliverOutboundPayloadsParams,
|
||||||
|
OutboundDeliveryResult,
|
||||||
|
OutboundSendDeps,
|
||||||
|
} from "./deliver.js";
|
||||||
|
|
||||||
export const deliverMocks = {
|
type DeliverMockState = {
|
||||||
|
sessions: {
|
||||||
|
appendAssistantMessageToSessionTranscript: (...args: unknown[]) => Promise<{
|
||||||
|
ok: boolean;
|
||||||
|
sessionFile: string;
|
||||||
|
}>;
|
||||||
|
};
|
||||||
|
hooks: {
|
||||||
|
runner: {
|
||||||
|
hasHooks: (...args: unknown[]) => boolean;
|
||||||
|
runMessageSent: (...args: unknown[]) => Promise<void>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
internalHooks: {
|
||||||
|
createInternalHookEvent: typeof createInternalHookEventPayload;
|
||||||
|
triggerInternalHook: (...args: unknown[]) => Promise<void>;
|
||||||
|
};
|
||||||
|
queue: {
|
||||||
|
enqueueDelivery: (...args: unknown[]) => Promise<string>;
|
||||||
|
ackDelivery: (...args: unknown[]) => Promise<void>;
|
||||||
|
failDelivery: (...args: unknown[]) => Promise<void>;
|
||||||
|
};
|
||||||
|
log: {
|
||||||
|
warn: (...args: unknown[]) => void;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export const deliverMocks: DeliverMockState = {
|
||||||
sessions: {
|
sessions: {
|
||||||
appendAssistantMessageToSessionTranscript: async () => ({ ok: true, sessionFile: "x" }),
|
appendAssistantMessageToSessionTranscript: async () => ({ ok: true, sessionFile: "x" }),
|
||||||
},
|
},
|
||||||
|
|
@ -46,7 +78,7 @@ const _hookMocks = vi.hoisted(() => ({
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
const _internalHookMocks = vi.hoisted(() => ({
|
const _internalHookMocks = vi.hoisted(() => ({
|
||||||
createInternalHookEvent: vi.fn((...args: unknown[]) =>
|
createInternalHookEvent: vi.fn((...args: Parameters<typeof createInternalHookEventPayload>) =>
|
||||||
deliverMocks.internalHooks.createInternalHookEvent(...args),
|
deliverMocks.internalHooks.createInternalHookEvent(...args),
|
||||||
),
|
),
|
||||||
triggerInternalHook: vi.fn(
|
triggerInternalHook: vi.fn(
|
||||||
|
|
@ -177,18 +209,13 @@ export function resetDeliverTestMocks(params?: { includeSessionMocks?: boolean }
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function runChunkedWhatsAppDelivery(params: {
|
export async function runChunkedWhatsAppDelivery(params: {
|
||||||
deliverOutboundPayloads: (params: {
|
deliverOutboundPayloads: (
|
||||||
cfg: OpenClawConfig;
|
params: DeliverOutboundPayloadsParams,
|
||||||
channel: string;
|
) => Promise<OutboundDeliveryResult[]>;
|
||||||
to: string;
|
mirror?: DeliverOutboundPayloadsParams["mirror"];
|
||||||
payloads: Array<{ text: string }>;
|
|
||||||
deps: { sendWhatsApp: ReturnType<typeof vi.fn> };
|
|
||||||
mirror?: unknown;
|
|
||||||
}) => Promise<Array<{ messageId?: string; toJid?: string }>>;
|
|
||||||
mirror?: unknown;
|
|
||||||
}) {
|
}) {
|
||||||
const sendWhatsApp = vi
|
const sendWhatsApp = vi
|
||||||
.fn()
|
.fn<NonNullable<OutboundSendDeps["sendWhatsApp"]>>()
|
||||||
.mockResolvedValueOnce({ messageId: "w1", toJid: "jid" })
|
.mockResolvedValueOnce({ messageId: "w1", toJid: "jid" })
|
||||||
.mockResolvedValueOnce({ messageId: "w2", toJid: "jid" });
|
.mockResolvedValueOnce({ messageId: "w2", toJid: "jid" });
|
||||||
const cfg: OpenClawConfig = {
|
const cfg: OpenClawConfig = {
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,5 @@
|
||||||
import path from "node:path";
|
import path from "node:path";
|
||||||
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||||
import { signalOutbound } from "../../channels/plugins/outbound/signal.js";
|
|
||||||
import { telegramOutbound } from "../../channels/plugins/outbound/telegram.js";
|
|
||||||
import { whatsappOutbound } from "../../channels/plugins/outbound/whatsapp.js";
|
|
||||||
import type { ChannelOutboundAdapter } from "../../channels/plugins/types.adapters.js";
|
import type { ChannelOutboundAdapter } from "../../channels/plugins/types.adapters.js";
|
||||||
import type { OpenClawConfig } from "../../config/config.js";
|
import type { OpenClawConfig } from "../../config/config.js";
|
||||||
import { STATE_DIR } from "../../config/paths.js";
|
import { STATE_DIR } from "../../config/paths.js";
|
||||||
|
|
@ -15,7 +12,6 @@ import { resolvePreferredOpenClawTmpDir } from "../tmp-openclaw-dir.js";
|
||||||
import {
|
import {
|
||||||
clearDeliverTestRegistry,
|
clearDeliverTestRegistry,
|
||||||
hookMocks,
|
hookMocks,
|
||||||
logMocks,
|
|
||||||
resetDeliverTestState,
|
resetDeliverTestState,
|
||||||
resetDeliverTestMocks,
|
resetDeliverTestMocks,
|
||||||
runChunkedWhatsAppDelivery as runChunkedWhatsAppDeliveryHelper,
|
runChunkedWhatsAppDelivery as runChunkedWhatsAppDeliveryHelper,
|
||||||
|
|
@ -56,16 +52,6 @@ async function deliverMatrixPayloads(payloads: DeliverOutboundPayload[]) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function expectMatrixMediaFallbackWarning(mediaCount: number) {
|
|
||||||
expect(logMocks.warn).toHaveBeenCalledWith(
|
|
||||||
"Plugin outbound adapter does not implement sendMedia; media URLs will be dropped and text fallback will be used",
|
|
||||||
expect.objectContaining({
|
|
||||||
channel: "matrix",
|
|
||||||
mediaCount,
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
async function deliverWhatsAppPayload(params: {
|
async function deliverWhatsAppPayload(params: {
|
||||||
sendWhatsApp: NonNullable<
|
sendWhatsApp: NonNullable<
|
||||||
NonNullable<Parameters<typeof deliverOutboundPayloads>[0]["deps"]>["sendWhatsApp"]
|
NonNullable<Parameters<typeof deliverOutboundPayloads>[0]["deps"]>["sendWhatsApp"]
|
||||||
|
|
@ -675,7 +661,6 @@ describe("deliverOutboundPayloads", () => {
|
||||||
text: "caption",
|
text: "caption",
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
expectMatrixMediaFallbackWarning(1);
|
|
||||||
expect(results).toEqual([{ channel: "matrix", messageId: "mx-1" }]);
|
expect(results).toEqual([{ channel: "matrix", messageId: "mx-1" }]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -696,7 +681,6 @@ describe("deliverOutboundPayloads", () => {
|
||||||
text: "caption",
|
text: "caption",
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
expectMatrixMediaFallbackWarning(2);
|
|
||||||
expect(results).toEqual([{ channel: "matrix", messageId: "mx-2" }]);
|
expect(results).toEqual([{ channel: "matrix", messageId: "mx-2" }]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -712,16 +696,5 @@ describe("deliverOutboundPayloads", () => {
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(sendText).not.toHaveBeenCalled();
|
expect(sendText).not.toHaveBeenCalled();
|
||||||
expectMatrixMediaFallbackWarning(1);
|
|
||||||
expect(hookMocks.runner.runMessageSent).toHaveBeenCalledWith(
|
|
||||||
expect.objectContaining({
|
|
||||||
to: "!room:1",
|
|
||||||
content: "",
|
|
||||||
success: false,
|
|
||||||
error:
|
|
||||||
"Plugin outbound adapter does not implement sendMedia and no text fallback is available for media payload",
|
|
||||||
}),
|
|
||||||
expect.objectContaining({ channelId: "matrix" }),
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -242,7 +242,7 @@ type DeliverOutboundPayloadsCoreParams = {
|
||||||
silent?: boolean;
|
silent?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
type DeliverOutboundPayloadsParams = DeliverOutboundPayloadsCoreParams & {
|
export type DeliverOutboundPayloadsParams = DeliverOutboundPayloadsCoreParams & {
|
||||||
/** @internal Skip write-ahead queue (used by crash-recovery to avoid re-enqueueing). */
|
/** @internal Skip write-ahead queue (used by crash-recovery to avoid re-enqueueing). */
|
||||||
skipQueue?: boolean;
|
skipQueue?: boolean;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue