chore: migrate to oxlint and oxfmt
Co-authored-by: Christoph Nakazawa <christoph.pojer@gmail.com>
This commit is contained in:
@@ -36,9 +36,7 @@ describe("buildPairingReply", () => {
|
||||
const text = buildPairingReply(testCase);
|
||||
expect(text).toContain(testCase.idLine);
|
||||
expect(text).toContain(`Pairing code: ${testCase.code}`);
|
||||
expect(text).toContain(
|
||||
`clawdbot pairing approve ${testCase.channel} <code>`,
|
||||
);
|
||||
expect(text).toContain(`clawdbot pairing approve ${testCase.channel} <code>`);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@@ -6,10 +6,7 @@ import path from "node:path";
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
|
||||
import { resolveOAuthDir } from "../config/paths.js";
|
||||
import {
|
||||
listChannelPairingRequests,
|
||||
upsertChannelPairingRequest,
|
||||
} from "./pairing-store.js";
|
||||
import { listChannelPairingRequests, upsertChannelPairingRequest } from "./pairing-store.js";
|
||||
|
||||
async function withTempStateDir<T>(fn: (stateDir: string) => Promise<T>) {
|
||||
const previous = process.env.CLAWDBOT_STATE_DIR;
|
||||
|
||||
@@ -48,10 +48,7 @@ function resolveCredentialsDir(env: NodeJS.ProcessEnv = process.env): string {
|
||||
return resolveOAuthDir(env, stateDir);
|
||||
}
|
||||
|
||||
function resolvePairingPath(
|
||||
channel: PairingChannel,
|
||||
env: NodeJS.ProcessEnv = process.env,
|
||||
): string {
|
||||
function resolvePairingPath(channel: PairingChannel, env: NodeJS.ProcessEnv = process.env): string {
|
||||
return path.join(resolveCredentialsDir(env), `${channel}-pairing.json`);
|
||||
}
|
||||
|
||||
@@ -89,10 +86,7 @@ async function readJsonFile<T>(
|
||||
async function writeJsonFile(filePath: string, value: unknown): Promise<void> {
|
||||
const dir = path.dirname(filePath);
|
||||
await fs.promises.mkdir(dir, { recursive: true, mode: 0o700 });
|
||||
const tmp = path.join(
|
||||
dir,
|
||||
`${path.basename(filePath)}.${crypto.randomUUID()}.tmp`,
|
||||
);
|
||||
const tmp = path.join(dir, `${path.basename(filePath)}.${crypto.randomUUID()}.tmp`);
|
||||
await fs.promises.writeFile(tmp, `${JSON.stringify(value, null, 2)}\n`, {
|
||||
encoding: "utf-8",
|
||||
});
|
||||
@@ -156,18 +150,14 @@ function pruneExpiredRequests(reqs: PairingRequest[], nowMs: number) {
|
||||
}
|
||||
|
||||
function resolveLastSeenAt(entry: PairingRequest): number {
|
||||
return (
|
||||
parseTimestamp(entry.lastSeenAt) ?? parseTimestamp(entry.createdAt) ?? 0
|
||||
);
|
||||
return parseTimestamp(entry.lastSeenAt) ?? parseTimestamp(entry.createdAt) ?? 0;
|
||||
}
|
||||
|
||||
function pruneExcessRequests(reqs: PairingRequest[], maxPending: number) {
|
||||
if (maxPending <= 0 || reqs.length <= maxPending) {
|
||||
return { requests: reqs, removed: false };
|
||||
}
|
||||
const sorted = reqs
|
||||
.slice()
|
||||
.sort((a, b) => resolveLastSeenAt(a) - resolveLastSeenAt(b));
|
||||
const sorted = reqs.slice().sort((a, b) => resolveLastSeenAt(a) - resolveLastSeenAt(b));
|
||||
return { requests: sorted.slice(-maxPending), removed: true };
|
||||
}
|
||||
|
||||
@@ -198,9 +188,7 @@ function normalizeAllowEntry(channel: PairingChannel, entry: string): string {
|
||||
const trimmed = entry.trim();
|
||||
if (!trimmed) return "";
|
||||
if (trimmed === "*") return "";
|
||||
const normalized = adapter.normalizeAllowEntry
|
||||
? adapter.normalizeAllowEntry(trimmed)
|
||||
: trimmed;
|
||||
const normalized = adapter.normalizeAllowEntry ? adapter.normalizeAllowEntry(trimmed) : trimmed;
|
||||
return String(normalized).trim();
|
||||
}
|
||||
|
||||
@@ -215,9 +203,7 @@ export async function readChannelAllowFromStore(
|
||||
allowFrom: [],
|
||||
});
|
||||
const list = Array.isArray(value.allowFrom) ? value.allowFrom : [];
|
||||
return list
|
||||
.map((v) => normalizeAllowEntry(channel, String(v)))
|
||||
.filter(Boolean);
|
||||
return list.map((v) => normalizeAllowEntry(channel, String(v))).filter(Boolean);
|
||||
}
|
||||
|
||||
export async function addChannelAllowFromStoreEntry(params: {
|
||||
@@ -239,13 +225,9 @@ export async function addChannelAllowFromStoreEntry(params: {
|
||||
const current = (Array.isArray(value.allowFrom) ? value.allowFrom : [])
|
||||
.map((v) => normalizeAllowEntry(params.channel, String(v)))
|
||||
.filter(Boolean);
|
||||
const normalized = normalizeAllowEntry(
|
||||
params.channel,
|
||||
normalizeId(params.entry),
|
||||
);
|
||||
const normalized = normalizeAllowEntry(params.channel, normalizeId(params.entry));
|
||||
if (!normalized) return { changed: false, allowFrom: current };
|
||||
if (current.includes(normalized))
|
||||
return { changed: false, allowFrom: current };
|
||||
if (current.includes(normalized)) return { changed: false, allowFrom: current };
|
||||
const next = [...current, normalized];
|
||||
await writeJsonFile(filePath, {
|
||||
version: 1,
|
||||
@@ -272,8 +254,10 @@ export async function listChannelPairingRequests(
|
||||
});
|
||||
const reqs = Array.isArray(value.requests) ? value.requests : [];
|
||||
const nowMs = Date.now();
|
||||
const { requests: prunedExpired, removed: expiredRemoved } =
|
||||
pruneExpiredRequests(reqs, nowMs);
|
||||
const { requests: prunedExpired, removed: expiredRemoved } = pruneExpiredRequests(
|
||||
reqs,
|
||||
nowMs,
|
||||
);
|
||||
const { requests: pruned, removed: cappedRemoved } = pruneExcessRequests(
|
||||
prunedExpired,
|
||||
PAIRING_PENDING_MAX,
|
||||
@@ -328,8 +312,10 @@ export async function upsertChannelPairingRequest(params: {
|
||||
: undefined;
|
||||
|
||||
let reqs = Array.isArray(value.requests) ? value.requests : [];
|
||||
const { requests: prunedExpired, removed: expiredRemoved } =
|
||||
pruneExpiredRequests(reqs, nowMs);
|
||||
const { requests: prunedExpired, removed: expiredRemoved } = pruneExpiredRequests(
|
||||
reqs,
|
||||
nowMs,
|
||||
);
|
||||
reqs = prunedExpired;
|
||||
const existingIdx = reqs.findIndex((r) => r.id === id);
|
||||
const existingCodes = new Set(
|
||||
@@ -343,9 +329,7 @@ export async function upsertChannelPairingRequest(params: {
|
||||
if (existingIdx >= 0) {
|
||||
const existing = reqs[existingIdx];
|
||||
const existingCode =
|
||||
existing && typeof existing.code === "string"
|
||||
? existing.code.trim()
|
||||
: "";
|
||||
existing && typeof existing.code === "string" ? existing.code.trim() : "";
|
||||
const code = existingCode || generateUniqueCode(existingCodes);
|
||||
const next: PairingRequest = {
|
||||
id,
|
||||
@@ -355,10 +339,7 @@ export async function upsertChannelPairingRequest(params: {
|
||||
meta: meta ?? existing?.meta,
|
||||
};
|
||||
reqs[existingIdx] = next;
|
||||
const { requests: capped } = pruneExcessRequests(
|
||||
reqs,
|
||||
PAIRING_PENDING_MAX,
|
||||
);
|
||||
const { requests: capped } = pruneExcessRequests(reqs, PAIRING_PENDING_MAX);
|
||||
await writeJsonFile(filePath, {
|
||||
version: 1,
|
||||
requests: capped,
|
||||
@@ -419,9 +400,7 @@ export async function approveChannelPairingCode(params: {
|
||||
const reqs = Array.isArray(value.requests) ? value.requests : [];
|
||||
const nowMs = Date.now();
|
||||
const { requests: pruned, removed } = pruneExpiredRequests(reqs, nowMs);
|
||||
const idx = pruned.findIndex(
|
||||
(r) => String(r.code ?? "").toUpperCase() === code,
|
||||
);
|
||||
const idx = pruned.findIndex((r) => String(r.code ?? "").toUpperCase() === code);
|
||||
if (idx < 0) {
|
||||
if (removed) {
|
||||
await writeJsonFile(filePath, {
|
||||
|
||||
Reference in New Issue
Block a user