chore: enable redundant type constituent checks

This commit is contained in:
Peter Steinberger
2026-04-10 21:23:29 +01:00
parent 6783bef7ed
commit d236cb4680
25 changed files with 79 additions and 71 deletions

View File

@@ -59,7 +59,6 @@
],
"rules": {
"typescript/no-explicit-any": "off",
"typescript/no-redundant-type-constituents": "off",
"typescript/unbound-method": "off",
"eslint/no-unsafe-optional-chaining": "off"
}

View File

@@ -2,7 +2,7 @@ import { describe, expect, it } from "vitest";
type SplitCommandLine = (
value: string,
platform?: NodeJS.Platform | string,
platform?: string,
) => {
command: string;
args: string[];

View File

@@ -9,7 +9,7 @@ const mocks = vi.hoisted(() => ({
({
authConfig,
}: {
authConfig?: NonNullable<NonNullable<OpenClawConfig["gateway"]>["auth"]> | undefined;
authConfig?: NonNullable<NonNullable<OpenClawConfig["gateway"]>["auth"]>;
}) => {
const token =
typeof authConfig?.token === "string"
@@ -58,6 +58,14 @@ vi.mock("../gateway/auth.js", () => ({
resolveGatewayAuth: mocks.resolveGatewayAuth,
}));
function readPersistedConfig(): OpenClawConfig {
const persistedCfg = mocks.writeConfigFile.mock.calls[0]?.[0];
if (!persistedCfg) {
throw new Error("expected persisted config");
}
return persistedCfg;
}
let ensureBrowserControlAuth: typeof import("./control-auth.js").ensureBrowserControlAuth;
describe("ensureBrowserControlAuth", () => {
@@ -176,7 +184,7 @@ describe("ensureBrowserControlAuth", () => {
expect(result.auth.token).toBe(result.generatedToken);
expect(result.auth.password).toBeUndefined();
expect(mocks.writeConfigFile).toHaveBeenCalledTimes(1);
const persistedCfg = mocks.writeConfigFile.mock.calls[0]?.[0] as OpenClawConfig | undefined;
const persistedCfg = readPersistedConfig();
expect(persistedCfg?.gateway?.auth?.mode).toBe("none");
expect(persistedCfg?.gateway?.auth?.token).toBe(result.generatedToken);
expect(mocks.ensureGatewayStartupAuth).not.toHaveBeenCalled();
@@ -223,7 +231,7 @@ describe("ensureBrowserControlAuth", () => {
expect(result.auth.token).toBe(result.generatedToken);
expect(result.auth.password).toBeUndefined();
expect(mocks.writeConfigFile).toHaveBeenCalledTimes(1);
const persistedCfg = mocks.writeConfigFile.mock.calls[0]?.[0] as OpenClawConfig | undefined;
const persistedCfg = readPersistedConfig();
expect(persistedCfg?.gateway?.auth?.mode).toBe("none");
expect(persistedCfg?.gateway?.auth?.token).toBe(result.generatedToken);
expect(mocks.ensureGatewayStartupAuth).not.toHaveBeenCalled();
@@ -246,7 +254,7 @@ describe("ensureBrowserControlAuth", () => {
expect(result.auth.password).toBe(result.generatedToken);
expect(result.auth.token).toBeUndefined();
expect(mocks.writeConfigFile).toHaveBeenCalledTimes(1);
const persistedCfg = mocks.writeConfigFile.mock.calls[0]?.[0] as OpenClawConfig | undefined;
const persistedCfg = readPersistedConfig();
expect(persistedCfg?.gateway?.auth?.mode).toBe("trusted-proxy");
expect(persistedCfg?.gateway?.auth?.password).toBe(result.generatedToken);
expect(mocks.ensureGatewayStartupAuth).not.toHaveBeenCalled();
@@ -273,7 +281,7 @@ describe("ensureBrowserControlAuth", () => {
expect(result.auth.password).toBe(result.generatedToken);
expect(result.auth.token).toBeUndefined();
expect(mocks.writeConfigFile).toHaveBeenCalledTimes(1);
const persistedCfg = mocks.writeConfigFile.mock.calls[0]?.[0] as OpenClawConfig | undefined;
const persistedCfg = readPersistedConfig();
expect(persistedCfg?.gateway?.auth?.mode).toBe("trusted-proxy");
expect(persistedCfg?.gateway?.auth?.password).toBe(result.generatedToken);
expect(mocks.ensureGatewayStartupAuth).not.toHaveBeenCalled();

View File

@@ -1,12 +1,7 @@
import { Command } from "commander";
import type { GatewayRpcOpts } from "openclaw/plugin-sdk/browser-node-runtime";
import { createCliRuntimeCapture } from "../../test-support.js";
import type { CliRuntimeCapture } from "../../test-support.js";
type BrowserParentOpts = GatewayRpcOpts & {
json?: boolean;
browserProfile?: string;
};
import type { BrowserParentOpts } from "./browser-cli-shared.js";
export function createBrowserProgram(params?: { withGatewayUrl?: boolean }): {
program: Command;
@@ -25,7 +20,7 @@ export function createBrowserProgram(params?: { withGatewayUrl?: boolean }): {
return { program, browser, parentOpts };
}
const browserCliRuntimeState = { capture: null as CliRuntimeCapture | null };
const browserCliRuntimeState: { capture?: CliRuntimeCapture } = {};
export function getBrowserCliRuntimeCapture(): CliRuntimeCapture {
browserCliRuntimeState.capture ??= createCliRuntimeCapture();

View File

@@ -1,5 +1,5 @@
import fs from "node:fs/promises";
import type { IncomingMessage } from "node:http";
import type { IncomingMessage, ServerResponse } from "node:http";
import path from "node:path";
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
import { createMockServerResponse } from "../../../test/helpers/plugins/mock-http-response.js";
@@ -196,12 +196,16 @@ describe("diffs plugin registration", () => {
type RegisteredTool = {
execute?: (toolCallId: string, params: Record<string, unknown>) => Promise<unknown>;
};
type HttpRouteHandler = (
req: IncomingMessage,
res: ServerResponse,
) => boolean | Promise<boolean>;
type RegisteredHttpRouteParams = Parameters<OpenClawPluginApi["registerHttpRoute"]>[0];
let registeredToolFactory:
| ((ctx: OpenClawPluginToolContext) => RegisteredTool | RegisteredTool[] | null | undefined)
| undefined;
let registeredHttpRouteHandler: RegisteredHttpRouteParams["handler"] | undefined;
let registeredHttpRouteHandler: HttpRouteHandler | undefined;
const on = vi.fn();
const api = createTestPluginApi({
@@ -234,7 +238,7 @@ describe("diffs plugin registration", () => {
registeredToolFactory = typeof tool === "function" ? tool : () => tool;
},
registerHttpRoute(params: RegisteredHttpRouteParams) {
registeredHttpRouteHandler = params.handler;
registeredHttpRouteHandler = params.handler as HttpRouteHandler;
},
on,
});

View File

@@ -492,7 +492,7 @@ function createToolWithScreenshotter(
store: DiffArtifactStore,
screenshotter: DiffScreenshotter,
defaults = DEFAULT_DIFFS_TOOL_DEFAULTS,
context: OpenClawPluginToolContext | undefined = {
context: OpenClawPluginToolContext = {
agentId: "main",
sessionId: "session-123",
messageChannel: "discord",

View File

@@ -274,9 +274,7 @@ describe("Discord native slash commands with commands.allowFrom", () => {
},
});
const dispatchCall:
| Parameters<typeof dispatcherModule.dispatchReplyWithDispatcher>[0]
| undefined = vi.mocked(dispatcherModule.dispatchReplyWithDispatcher).mock.calls[0]?.[0];
const dispatchCall = vi.mocked(dispatcherModule.dispatchReplyWithDispatcher).mock.calls[0]?.[0];
await dispatchCall?.dispatcherOptions.deliver({ text: longReply }, { kind: "final" });
expect(interaction.followUp).toHaveBeenCalledWith(

View File

@@ -18,7 +18,7 @@ type DispatchReplyContext = Record<string, unknown> & {
SessionKey?: string;
};
type DispatchReplyDispatcher = {
sendFinalReply: (payload: { text: string }) => unknown | Promise<unknown>;
sendFinalReply: (payload: { text: string }) => unknown;
};
type DispatchReplyFromConfigMock = Mock<
(params: {
@@ -26,9 +26,7 @@ type DispatchReplyFromConfigMock = Mock<
dispatcher: DispatchReplyDispatcher;
}) => Promise<{ queuedFinal: boolean; counts: DispatchReplyCounts }>
>;
type WithReplyDispatcherMock = Mock<
(params: { run: () => unknown | Promise<unknown> }) => Promise<unknown>
>;
type WithReplyDispatcherMock = Mock<(params: { run: () => unknown }) => Promise<unknown>>;
type FeishuLifecycleTestMocks = {
createEventDispatcherMock: UnknownMock;
monitorWebSocketMock: AsyncUnknownMock;

View File

@@ -1,7 +1,7 @@
import "./lifecycle.test-support.js";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import { createRuntimeEnv } from "../../../test/helpers/plugins/runtime-env.js";
import type { ClawdbotConfig, RuntimeEnv } from "../runtime-api.js";
import type { ClawdbotConfig } from "../runtime-api.js";
import { getFeishuLifecycleTestMocks } from "./lifecycle.test-support.js";
import {
createFeishuLifecycleFixture,
@@ -27,7 +27,7 @@ const {
} = getFeishuLifecycleTestMocks();
let _handlers: Record<string, (data: unknown) => Promise<void>> = {};
let lastRuntime: RuntimeEnv | null = null;
let lastRuntime: ReturnType<typeof createRuntimeEnv> | null = null;
const originalStateDir = process.env.OPENCLAW_STATE_DIR;
const { cfg: lifecycleConfig, account: lifecycleAccount } = createFeishuLifecycleFixture({
accountId: "acct-acp",

View File

@@ -1,6 +1,5 @@
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import { createRuntimeEnv } from "../../../test/helpers/plugins/runtime-env.js";
import type { RuntimeEnv } from "../runtime-api.js";
import "./lifecycle.test-support.js";
import { getFeishuLifecycleTestMocks } from "./lifecycle.test-support.js";
import {
@@ -30,7 +29,7 @@ const {
} = getFeishuLifecycleTestMocks();
let _handlers: Record<string, (data: unknown) => Promise<void>> = {};
let lastRuntime: RuntimeEnv | null = null;
let lastRuntime: ReturnType<typeof createRuntimeEnv> | null = null;
const originalStateDir = process.env.OPENCLAW_STATE_DIR;
const lifecycleConfig = createFeishuLifecycleConfig({
accountId: "acct-menu",

View File

@@ -1,6 +1,5 @@
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import { createRuntimeEnv } from "../../../test/helpers/plugins/runtime-env.js";
import type { RuntimeEnv } from "../runtime-api.js";
import "./lifecycle.test-support.js";
import { resetProcessedFeishuCardActionTokensForTests } from "./card-action.js";
import { createFeishuCardInteractionEnvelope } from "./card-interaction.js";
@@ -33,7 +32,7 @@ const {
} = getFeishuLifecycleTestMocks();
let _handlers: Record<string, (data: unknown) => Promise<void>> = {};
let lastRuntime: RuntimeEnv | null = null;
let lastRuntime: ReturnType<typeof createRuntimeEnv> | null = null;
const originalStateDir = process.env.OPENCLAW_STATE_DIR;
const lifecycleConfig = createFeishuLifecycleConfig({
accountId: "acct-card",

View File

@@ -1,6 +1,5 @@
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import { createRuntimeEnv } from "../../../test/helpers/plugins/runtime-env.js";
import type { RuntimeEnv } from "../runtime-api.js";
import "./lifecycle.test-support.js";
import { getFeishuLifecycleTestMocks } from "./lifecycle.test-support.js";
import {
@@ -30,7 +29,7 @@ const {
} = getFeishuLifecycleTestMocks();
let _handlers: Record<string, (data: unknown) => Promise<void>> = {};
let lastRuntime: RuntimeEnv | null = null;
let lastRuntime: ReturnType<typeof createRuntimeEnv> | null = null;
const originalStateDir = process.env.OPENCLAW_STATE_DIR;
const lifecycleConfig = createFeishuLifecycleConfig({
accountId: "acct-lifecycle",

View File

@@ -20,7 +20,7 @@ type FeishuDispatchReplyContext = Record<string, unknown> & {
SessionKey?: string;
};
type FeishuDispatchReplyDispatcher = {
sendFinalReply: (payload: { text: string }) => unknown | Promise<unknown>;
sendFinalReply: (payload: { text: string }) => unknown;
};
type FeishuDispatchReplyMock = Mock<
(args: {

View File

@@ -1,11 +1,9 @@
import type { AnyAgentTool, OpenClawPluginApi } from "../runtime-api.js";
import type { OpenClawPluginApi } from "../runtime-api.js";
type ToolContextLike = {
agentAccountId?: string;
};
type ToolFactoryLike = (ctx: ToolContextLike) => AnyAgentTool | AnyAgentTool[] | null | undefined;
export type ToolLike = {
name: string;
execute: (
@@ -15,18 +13,18 @@ export type ToolLike = {
};
type RegisteredTool = {
tool: AnyAgentTool | ToolFactoryLike;
tool: unknown;
opts?: { name?: string };
};
function toToolList(value: AnyAgentTool | AnyAgentTool[] | null | undefined): AnyAgentTool[] {
function toToolList(value: unknown): unknown[] {
if (!value) {
return [];
}
return Array.isArray(value) ? value : [value];
}
function asToolLike(tool: AnyAgentTool, fallbackName?: string): ToolLike {
function asToolLike(tool: unknown, fallbackName?: string): ToolLike {
const candidate = tool as Partial<ToolLike>;
const name = candidate.name ?? fallbackName;
const execute = candidate.execute;

View File

@@ -24,7 +24,7 @@ function createReplyDeliveryCore(): DeliverMattermostReplyPayloadParams["core"]
resolveChunkMode: vi.fn<() => ChunkMode>(() => "length"),
resolveTextChunkLimit: vi.fn(
(
_cfg: OpenClawConfig | undefined,
_cfg?: OpenClawConfig,
_provider?: string,
_accountId?: string | null,
opts?: { fallbackLimit?: number },

View File

@@ -20,7 +20,7 @@ function resolveStoredDreaming(config: OpenClawConfig): Record<string, unknown>
}
function createHarness(initialConfig: OpenClawConfig = {}) {
let command: OpenClawPluginCommandDefinition | undefined;
const registered: { command?: OpenClawPluginCommandDefinition } = {};
let runtimeConfig: OpenClawConfig = initialConfig;
const runtime = {
@@ -35,18 +35,18 @@ function createHarness(initialConfig: OpenClawConfig = {}) {
const api = {
runtime,
registerCommand: vi.fn((definition: OpenClawPluginCommandDefinition) => {
command = definition;
registered.command = definition;
}),
} as unknown as OpenClawPluginApi;
registerDreamingCommand(api);
if (!command) {
if (!registered.command) {
throw new Error("memory-core did not register /dreaming");
}
return {
command,
command: registered.command,
runtime,
getRuntimeConfig: () => runtimeConfig,
};

View File

@@ -145,7 +145,7 @@ describe("QmdMemoryManager", () => {
let cfg: OpenClawConfig;
const agentId = "main";
const openManagers = new Set<QmdMemoryManager>();
let embedStartupJitterSpy: ReturnType<typeof vi.spyOn> | null = null;
let embedStartupJitterSpy: { mockRestore: () => void } | null = null;
function seedMemoryEmbeddingProviders(): void {
(globalThis as Record<PropertyKey, unknown>)[MEMORY_EMBEDDING_PROVIDERS_KEY] = new Map([

View File

@@ -7,18 +7,16 @@ import type { OpenClawConfig, RuntimeEnv } from "../runtime-api.js";
import { msteamsDirectoryAdapter } from "./directory.js";
import { resolveMSTeamsOutboundSessionRoute } from "./session-route.js";
function requireDirectorySelf(
directory: typeof msteamsDirectoryAdapter | null | undefined,
): NonNullable<(typeof msteamsDirectoryAdapter)["self"]> {
if (!directory?.self) {
function requireDirectorySelf(): NonNullable<(typeof msteamsDirectoryAdapter)["self"]> {
if (!msteamsDirectoryAdapter.self) {
throw new Error("expected msteams directory.self");
}
return directory.self;
return msteamsDirectoryAdapter.self;
}
describe("msteams directory", () => {
const runtimeEnv = createDirectoryTestRuntime() as RuntimeEnv;
const directorySelf = requireDirectorySelf(msteamsDirectoryAdapter);
const directorySelf = requireDirectorySelf();
afterEach(() => {
vi.unstubAllEnvs();

View File

@@ -448,7 +448,7 @@ describe("qa-lab server", () => {
const initialOutcomes = (await (
await fetchWithRetry(`${lab.baseUrl}/api/outcomes`)
).json()) as {
run: null | unknown;
run: unknown;
};
expect(initialOutcomes.run).toBeNull();

View File

@@ -9,7 +9,7 @@ const [
const { sendTypingMock, sendReadReceiptMock, dispatchInboundMessageMock, capture } = vi.hoisted(
() => {
const captureState: { ctx: MsgContext | undefined } = { ctx: undefined };
const captureState: { ctx?: MsgContext } = {};
return {
sendTypingMock: vi.fn(),
sendReadReceiptMock: vi.fn(),
@@ -53,7 +53,7 @@ vi.mock("../../../../src/pairing/pairing-store.js", () => ({
describe("signal createSignalEventHandler inbound context", () => {
beforeEach(() => {
capture.ctx = undefined;
delete capture.ctx;
sendTypingMock.mockReset().mockResolvedValue(true);
sendReadReceiptMock.mockReset().mockResolvedValue(true);
dispatchInboundMessageMock.mockClear();

View File

@@ -5,7 +5,6 @@ import {
resetInboundDedupe,
type GetReplyOptions,
type MsgContext,
type ReplyPayload,
} from "openclaw/plugin-sdk/reply-runtime";
import type { MockFn } from "openclaw/plugin-sdk/testing";
import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/text-runtime";
@@ -27,6 +26,12 @@ type DispatchReplyWithBufferedBlockDispatcherResult = Awaited<
ReturnType<DispatchReplyWithBufferedBlockDispatcherFn>
>;
type DispatchReplyHarnessParams = Parameters<DispatchReplyWithBufferedBlockDispatcherFn>[0];
type ReplyPayloadLike = {
text?: string;
mediaUrl?: string;
mediaUrls?: string[];
replyToId?: string;
};
const _EMPTY_REPLY_COUNTS: DispatchReplyWithBufferedBlockDispatcherResult["counts"] = {
block: 0,
@@ -119,7 +124,7 @@ const replySpyHoisted = vi.hoisted(() => ({
ctx: MsgContext,
opts?: GetReplyOptions,
configOverride?: OpenClawConfig,
) => Promise<ReplyPayload | ReplyPayload[] | undefined>
) => Promise<ReplyPayloadLike | ReplyPayloadLike[] | undefined>
>,
}));
@@ -127,11 +132,11 @@ async function dispatchHarnessReplies(
params: DispatchReplyHarnessParams,
runReply: (
params: DispatchReplyHarnessParams,
) => Promise<ReplyPayload | ReplyPayload[] | undefined>,
) => Promise<ReplyPayloadLike | ReplyPayloadLike[] | undefined>,
): Promise<DispatchReplyWithBufferedBlockDispatcherResult> {
await params.dispatcherOptions.typingCallbacks?.onReplyStart?.();
const reply = await runReply(params);
const payloads: ReplyPayload[] =
const payloads: ReplyPayloadLike[] =
reply === undefined ? [] : Array.isArray(reply) ? reply : [reply];
const dispatcher = createReplyDispatcher({
deliver: async (payload, info) => {

View File

@@ -187,9 +187,7 @@ describe("resolveTelegramDnsResultOrderDecision", () => {
},
{
name: "normalizes trimmed config values",
network: { dnsResultOrder: " Verbatim " } as TelegramNetworkConfig & {
dnsResultOrder: string;
},
network: { dnsResultOrder: " Verbatim " } as unknown as TelegramNetworkConfig,
nodeMajor: 20,
expected: { value: "verbatim", source: "config" },
},
@@ -203,14 +201,14 @@ describe("resolveTelegramDnsResultOrderDecision", () => {
{
name: "ignores invalid env and config values before applying Node 22 default",
env: { OPENCLAW_TELEGRAM_DNS_RESULT_ORDER: "bogus" },
network: { dnsResultOrder: "invalid" } as TelegramNetworkConfig & { dnsResultOrder: string },
network: { dnsResultOrder: "invalid" } as unknown as TelegramNetworkConfig,
nodeMajor: 22,
expected: { value: "ipv4first", source: "default-node22" },
},
] satisfies Array<{
name: string;
env?: NodeJS.ProcessEnv;
network?: TelegramNetworkConfig | (TelegramNetworkConfig & { dnsResultOrder: string });
network?: TelegramNetworkConfig;
nodeMajor: number;
expected: ReturnType<typeof resolveTelegramDnsResultOrderDecision>;
}>)("$name", ({ env, network, nodeMajor, expected }) => {

View File

@@ -24,9 +24,9 @@ const mocks = vi.hoisted(() => {
};
return {
getRealtimeTranscriptionProvider: vi.fn<
(...args: unknown[]) => RealtimeTranscriptionProviderPlugin | undefined
>(() => realtimeTranscriptionProvider),
getRealtimeTranscriptionProvider: vi.fn<(...args: unknown[]) => unknown>(
() => realtimeTranscriptionProvider,
),
listRealtimeTranscriptionProviders: vi.fn(() => [realtimeTranscriptionProvider]),
};
});

View File

@@ -185,7 +185,7 @@ function createCommandsStatusRuntimeModuleMock() {
primaryModelLabelOverride?: string;
includeTranscriptUsage?: boolean;
taskLineOverride?: string;
resolveDefaultThinkingLevel?: () => Promise<unknown> | unknown;
resolveDefaultThinkingLevel?: () => unknown;
}) => {
resolveQueueSettingsMock({
channel: params.statusChannel,

View File

@@ -21,18 +21,28 @@ vi.mock("../../infra/net/fetch-guard.js", () => ({
}));
type FetchPayloadFactory = (input: RequestInfo | URL, init?: RequestInit) => unknown;
type JsonResponseFetchMock = ReturnType<typeof vi.fn<FetchMock>> & {
preconnect: (
url: string | URL,
options?: { dns?: boolean; tcp?: boolean; http?: boolean; https?: boolean },
) => void;
__openclawAcceptsDispatcher: true;
};
export type JsonFetchMock = ReturnType<typeof createJsonResponseFetchMock>;
export function createJsonResponseFetchMock(payload: unknown | FetchPayloadFactory) {
export function createJsonResponseFetchMock(payload: FetchPayloadFactory): JsonResponseFetchMock;
export function createJsonResponseFetchMock(payload: unknown): JsonResponseFetchMock;
export function createJsonResponseFetchMock(payload: unknown) {
const fetchMock = vi.fn<FetchMock>(async (input: RequestInfo | URL, init?: RequestInit) => {
const body = typeof payload === "function" ? payload(input, init) : payload;
const body =
typeof payload === "function" ? (payload as FetchPayloadFactory)(input, init) : payload;
return new Response(JSON.stringify(body), {
status: 200,
headers: { "Content-Type": "application/json" },
});
});
return withFetchPreconnect(fetchMock);
return withFetchPreconnect(fetchMock) as JsonResponseFetchMock;
}
export function createEmbeddingDataFetchMock(embeddingValues = [0.1, 0.2, 0.3]) {