refactor(extensions): dedupe connector helper usage

This commit is contained in:
Peter Steinberger
2026-02-16 14:51:55 +00:00
parent bc55ffb160
commit 544ffbcf7b
49 changed files with 854 additions and 1478 deletions

View File

@@ -3,12 +3,8 @@ import type { CoreConfig } from "../../types.js";
import type { MatrixActionClient, MatrixActionClientOpts } from "./types.js";
import { getMatrixRuntime } from "../../runtime.js";
import { getActiveMatrixClient } from "../active-client.js";
import {
createMatrixClient,
isBunRuntime,
resolveMatrixAuth,
resolveSharedMatrixClient,
} from "../client.js";
import { createPreparedMatrixClient } from "../client-bootstrap.js";
import { isBunRuntime, resolveMatrixAuth, resolveSharedMatrixClient } from "../client.js";
export function ensureNodeRuntime() {
if (isBunRuntime()) {
@@ -42,24 +38,10 @@ export async function resolveActionClient(
cfg: getMatrixRuntime().config.loadConfig() as CoreConfig,
accountId,
});
const client = await createMatrixClient({
homeserver: auth.homeserver,
userId: auth.userId,
accessToken: auth.accessToken,
encryption: auth.encryption,
localTimeoutMs: opts.timeoutMs,
const client = await createPreparedMatrixClient({
auth,
timeoutMs: opts.timeoutMs,
accountId,
});
if (auth.encryption && client.crypto) {
try {
const joinedRooms = await client.getJoinedRooms();
await (client.crypto as { prepare: (rooms?: string[]) => Promise<void> }).prepare(
joinedRooms,
);
} catch {
// Ignore crypto prep failures for one-off actions.
}
}
await client.start();
return { client, stopOnDone: true };
}

View File

@@ -0,0 +1,39 @@
import { createMatrixClient } from "./client.js";
type MatrixClientBootstrapAuth = {
homeserver: string;
userId: string;
accessToken: string;
encryption?: boolean;
};
type MatrixCryptoPrepare = {
prepare: (rooms?: string[]) => Promise<void>;
};
type MatrixBootstrapClient = Awaited<ReturnType<typeof createMatrixClient>>;
export async function createPreparedMatrixClient(opts: {
auth: MatrixClientBootstrapAuth;
timeoutMs?: number;
accountId?: string;
}): Promise<MatrixBootstrapClient> {
const client = await createMatrixClient({
homeserver: opts.auth.homeserver,
userId: opts.auth.userId,
accessToken: opts.auth.accessToken,
encryption: opts.auth.encryption,
localTimeoutMs: opts.timeoutMs,
accountId: opts.accountId,
});
if (opts.auth.encryption && client.crypto) {
try {
const joinedRooms = await client.getJoinedRooms();
await (client.crypto as MatrixCryptoPrepare).prepare(joinedRooms);
} catch {
// Ignore crypto prep failures for one-off requests.
}
}
await client.start();
return client;
}

View File

@@ -22,14 +22,12 @@ describe("downloadMatrixMedia", () => {
setMatrixRuntime(runtimeStub);
});
it("decrypts encrypted media when file payloads are present", async () => {
function makeEncryptedMediaFixture() {
const decryptMedia = vi.fn().mockResolvedValue(Buffer.from("decrypted"));
const client = {
crypto: { decryptMedia },
mxcToHttp: vi.fn().mockReturnValue("https://example/mxc"),
} as unknown as import("@vector-im/matrix-bot-sdk").MatrixClient;
const file = {
url: "mxc://example/file",
key: {
@@ -43,6 +41,11 @@ describe("downloadMatrixMedia", () => {
hashes: { sha256: "hash" },
v: "v2",
};
return { decryptMedia, client, file };
}
it("decrypts encrypted media when file payloads are present", async () => {
const { decryptMedia, client, file } = makeEncryptedMediaFixture();
const result = await downloadMatrixMedia({
client,
@@ -64,26 +67,7 @@ describe("downloadMatrixMedia", () => {
});
it("rejects encrypted media that exceeds maxBytes before decrypting", async () => {
const decryptMedia = vi.fn().mockResolvedValue(Buffer.from("decrypted"));
const client = {
crypto: { decryptMedia },
mxcToHttp: vi.fn().mockReturnValue("https://example/mxc"),
} as unknown as import("@vector-im/matrix-bot-sdk").MatrixClient;
const file = {
url: "mxc://example/file",
key: {
kty: "oct",
key_ops: ["encrypt", "decrypt"],
alg: "A256CTR",
k: "secret",
ext: true,
},
iv: "iv",
hashes: { sha256: "hash" },
v: "v2",
};
const { decryptMedia, client, file } = makeEncryptedMediaFixture();
await expect(
downloadMatrixMedia({

View File

@@ -3,12 +3,8 @@ import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "openclaw/plugin-sdk/acco
import type { CoreConfig } from "../../types.js";
import { getMatrixRuntime } from "../../runtime.js";
import { getActiveMatrixClient, getAnyActiveMatrixClient } from "../active-client.js";
import {
createMatrixClient,
isBunRuntime,
resolveMatrixAuth,
resolveSharedMatrixClient,
} from "../client.js";
import { createPreparedMatrixClient } from "../client-bootstrap.js";
import { isBunRuntime, resolveMatrixAuth, resolveSharedMatrixClient } from "../client.js";
const getCore = () => getMatrixRuntime();
@@ -92,25 +88,10 @@ export async function resolveMatrixClient(opts: {
return { client, stopOnDone: false };
}
const auth = await resolveMatrixAuth({ accountId });
const client = await createMatrixClient({
homeserver: auth.homeserver,
userId: auth.userId,
accessToken: auth.accessToken,
encryption: auth.encryption,
localTimeoutMs: opts.timeoutMs,
const client = await createPreparedMatrixClient({
auth,
timeoutMs: opts.timeoutMs,
accountId,
});
if (auth.encryption && client.crypto) {
try {
const joinedRooms = await client.getJoinedRooms();
await (client.crypto as { prepare: (rooms?: string[]) => Promise<void> }).prepare(
joinedRooms,
);
} catch {
// Ignore crypto prep failures for one-off sends; normal sync will retry.
}
}
// @vector-im/matrix-bot-sdk uses start() instead of startClient()
await client.start();
return { client, stopOnDone: true };
}