chore: Lint extensions folder.

This commit is contained in:
cpojer
2026-01-31 22:13:48 +09:00
parent 4f2166c503
commit 230ca789e2
221 changed files with 4006 additions and 1583 deletions

View File

@@ -114,16 +114,24 @@ function checkSenderRoles(params: { message: TwitchChatMessage; allowedRoles: st
for (const role of allowedRoles) {
switch (role) {
case "moderator":
if (isMod) return true;
if (isMod) {
return true;
}
break;
case "owner":
if (isOwner) return true;
if (isOwner) {
return true;
}
break;
case "vip":
if (isVip) return true;
if (isVip) {
return true;
}
break;
case "subscriber":
if (isSub) return true;
if (isSub) {
return true;
}
break;
}
}

View File

@@ -137,7 +137,7 @@ async function deliverTwitchReply(params: {
runtime: TwitchRuntimeEnv;
statusSink?: (patch: { lastInboundAt?: number; lastOutboundAt?: number }) => void;
}): Promise<void> {
const { payload, channel, account, accountId, config, tableMode, runtime, statusSink } = params;
const { payload, channel, account, accountId, config, runtime, statusSink } = params;
try {
const clientManager = getOrCreateClientManager(accountId, {
@@ -187,7 +187,9 @@ export async function monitorTwitchProvider(
const coreLogger = core.logging.getChildLogger({ module: "twitch" });
const logVerboseMessage = (message: string) => {
if (!core.logging.shouldLogVerbose()) return;
if (!core.logging.shouldLogVerbose()) {
return;
}
coreLogger.debug?.(message);
};
const logger = {
@@ -212,7 +214,9 @@ export async function monitorTwitchProvider(
}
const unregisterHandler = clientManager.onMessage(account, (message) => {
if (stopped) return;
if (stopped) {
return;
}
// Access control check
const botUsername = account.username.toLowerCase();

View File

@@ -105,7 +105,9 @@ async function promptToken(
initialValue: envToken ?? "",
validate: (value) => {
const raw = String(value ?? "").trim();
if (!raw) return "Required";
if (!raw) {
return "Required";
}
if (!raw.startsWith("oauth:")) {
return "Token should start with 'oauth:'";
}
@@ -265,14 +267,18 @@ const dmPolicy: ChannelOnboardingDmPolicy = {
getCurrent: (cfg) => {
const account = getAccountConfig(cfg, DEFAULT_ACCOUNT_ID);
// Map allowedRoles to policy equivalent
if (account?.allowedRoles?.includes("all")) return "open";
if (account?.allowFrom && account.allowFrom.length > 0) return "allowlist";
if (account?.allowedRoles?.includes("all")) {
return "open";
}
if (account?.allowFrom && account.allowFrom.length > 0) {
return "allowlist";
}
return "disabled";
},
setPolicy: (cfg, policy) => {
const allowedRoles: TwitchRole[] =
policy === "open" ? ["all"] : policy === "allowlist" ? [] : ["moderator"];
return setTwitchAccessControl(cfg as OpenClawConfig, allowedRoles, true);
return setTwitchAccessControl(cfg, allowedRoles, true);
},
promptAllowFrom: async ({ cfg, prompter }) => {
const account = getAccountConfig(cfg, DEFAULT_ACCOUNT_ID);
@@ -289,7 +295,7 @@ const dmPolicy: ChannelOnboardingDmPolicy = {
.map((s) => s.trim())
.filter(Boolean);
return setTwitchAccount(cfg as OpenClawConfig, {
return setTwitchAccount(cfg, {
...(account ?? undefined),
allowFrom,
});

View File

@@ -65,7 +65,7 @@ export const twitchOutbound: ChannelOutboundAdapter = {
}
// Fallback to first allowFrom entry
// biome-ignore lint/style/noNonNullAssertion: length > 0 check ensures element exists
return { ok: true, to: allowList[0]! };
return { ok: true, to: allowList[0] };
}
// For explicit mode, accept any valid channel name
@@ -75,7 +75,7 @@ export const twitchOutbound: ChannelOutboundAdapter = {
// No target provided, use allowFrom fallback
if (allowList.length > 0) {
// biome-ignore lint/style/noNonNullAssertion: length > 0 check ensures element exists
return { ok: true, to: allowList[0]! };
return { ok: true, to: allowList[0] };
}
// No target and no allowFrom - error

View File

@@ -231,7 +231,7 @@ export const twitchPlugin: ChannelPlugin<TwitchAccountConfig> = {
gateway: {
/** Start an account connection */
startAccount: async (ctx): Promise<void> => {
const account = ctx.account as TwitchAccountConfig;
const account = ctx.account;
const accountId = ctx.accountId;
ctx.setStatus?.({
@@ -256,7 +256,7 @@ export const twitchPlugin: ChannelPlugin<TwitchAccountConfig> = {
/** Stop an account connection */
stopAccount: async (ctx): Promise<void> => {
const account = ctx.account as TwitchAccountConfig;
const account = ctx.account;
const accountId = ctx.accountId;
// Disconnect and remove client manager from registry

View File

@@ -8,7 +8,6 @@ const mockUnbind = vi.fn();
// Event handler storage
let connectHandler: (() => void) | null = null;
let disconnectHandler: ((manually: boolean, reason?: Error) => void) | null = null;
let authFailHandler: (() => void) | null = null;
// Event listener mocks that store handlers and return unbind function
const mockOnConnect = vi.fn((handler: () => void) => {
@@ -21,8 +20,7 @@ const mockOnDisconnect = vi.fn((handler: (manually: boolean, reason?: Error) =>
return { unbind: mockUnbind };
});
const mockOnAuthenticationFailure = vi.fn((handler: () => void) => {
authFailHandler = handler;
const mockOnAuthenticationFailure = vi.fn((_handler: () => void) => {
return { unbind: mockUnbind };
});
@@ -65,7 +63,6 @@ describe("probeTwitch", () => {
// Reset handlers
connectHandler = null;
disconnectHandler = null;
authFailHandler = null;
});
it("returns error when username is missing", async () => {

View File

@@ -55,7 +55,9 @@ export async function probeTwitch(
let authFailListener: ReturnType<ChatClient["onAuthenticationFailure"]> | undefined;
const cleanup = () => {
if (settled) return;
if (settled) {
return;
}
settled = true;
connectListener?.unbind();
disconnectListener?.unbind();

View File

@@ -35,7 +35,9 @@ export function collectTwitchStatusIssues(
for (const entry of accounts) {
const accountId = entry.accountId;
if (!accountId) continue;
if (!accountId) {
continue;
}
let account: ReturnType<typeof getAccountConfig> | null = null;
let cfg: Parameters<typeof resolveTwitchToken>[0] | undefined;

View File

@@ -23,9 +23,13 @@ export type TwitchTokenResolution = {
* Normalize a Twitch OAuth token - ensure it has the oauth: prefix
*/
function normalizeTwitchToken(raw?: string | null): string | undefined {
if (!raw) return undefined;
if (!raw) {
return undefined;
}
const trimmed = raw.trim();
if (!trimmed) return undefined;
if (!trimmed) {
return undefined;
}
// Twitch tokens should have oauth: prefix
return trimmed.startsWith("oauth:") ? trimmed : `oauth:${trimmed}`;
}
@@ -55,7 +59,7 @@ export function resolveTwitchToken(
const accountCfg =
accountId === DEFAULT_ACCOUNT_ID
? (twitchCfg?.accounts?.[DEFAULT_ACCOUNT_ID] as Record<string, unknown> | undefined)
: (twitchCfg?.accounts?.[accountId as string] as Record<string, unknown> | undefined);
: (twitchCfg?.accounts?.[accountId] as Record<string, unknown> | undefined);
// For default account, also check base-level config
let token: string | undefined;

View File

@@ -416,7 +416,9 @@ describe("TwitchClientManager", () => {
// Get the onMessage callback
const onMessageCallback = messageHandlers[0];
if (!onMessageCallback) throw new Error("onMessageCallback not found");
if (!onMessageCallback) {
throw new Error("onMessageCallback not found");
}
// Simulate Twitch message
onMessageCallback("#testchannel", "testuser", "Hello bot!", {
@@ -521,7 +523,9 @@ describe("TwitchClientManager", () => {
// Simulate message for first account
const onMessage1 = messageHandlers[0];
if (!onMessage1) throw new Error("onMessage1 not found");
if (!onMessage1) {
throw new Error("onMessage1 not found");
}
onMessage1("#testchannel", "user1", "msg1", {
userInfo: {
userName: "user1",
@@ -537,7 +541,9 @@ describe("TwitchClientManager", () => {
// Simulate message for second account
const onMessage2 = messageHandlers[1];
if (!onMessage2) throw new Error("onMessage2 not found");
if (!onMessage2) {
throw new Error("onMessage2 not found");
}
onMessage2("#testchannel2", "user2", "msg2", {
userInfo: {
userName: "user2",

View File

@@ -61,9 +61,15 @@ export function stripMarkdownForTwitch(markdown: string): string {
export function chunkTextForTwitch(text: string, limit: number): string[] {
// First, strip markdown
const cleaned = stripMarkdownForTwitch(text);
if (!cleaned) return [];
if (limit <= 0) return [cleaned];
if (cleaned.length <= limit) return [cleaned];
if (!cleaned) {
return [];
}
if (limit <= 0) {
return [cleaned];
}
if (cleaned.length <= limit) {
return [cleaned];
}
const chunks: string[] = [];
let remaining = cleaned;