mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 18:50:42 +00:00
fix(qr): replace qrcode-terminal with qrcode-tui
Replace legacy qrcode-terminal usage with shared qrcode-tui media helpers, bound QR PNG rendering options, and raise bundled plugin host floors for the new SDK runtime surface.
This commit is contained in:
@@ -6,7 +6,6 @@
|
||||
"dependencies": {
|
||||
"@whiskeysockets/baileys": "7.0.0-rc.9",
|
||||
"jimp": "^1.6.1",
|
||||
"qrcode-terminal": "^0.12.0",
|
||||
"typebox": "1.1.28",
|
||||
"undici": "8.1.0"
|
||||
},
|
||||
@@ -15,7 +14,7 @@
|
||||
"openclaw": "workspace:*"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"openclaw": ">=2026.4.20"
|
||||
"openclaw": ">=2026.4.23"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"openclaw": {
|
||||
@@ -54,10 +53,10 @@
|
||||
"install": {
|
||||
"npmSpec": "@openclaw/whatsapp",
|
||||
"defaultChoice": "npm",
|
||||
"minHostVersion": ">=2026.4.10"
|
||||
"minHostVersion": ">=2026.4.23"
|
||||
},
|
||||
"compat": {
|
||||
"pluginApi": ">=2026.4.20"
|
||||
"pluginApi": ">=2026.4.23"
|
||||
},
|
||||
"bundle": {
|
||||
"stageRuntimeDependencies": true
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
import { EventEmitter } from "node:events";
|
||||
import { readFile } from "node:fs/promises";
|
||||
import { resolve } from "node:path";
|
||||
import { resetLogger, setLoggerOverride } from "openclaw/plugin-sdk/runtime-env";
|
||||
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { renderQrPngBase64 } from "./qr-image.js";
|
||||
@@ -88,13 +86,4 @@ describe("renderQrPngBase64", () => {
|
||||
const buf = Buffer.from(b64, "base64");
|
||||
expect(buf.subarray(0, 8).toString("hex")).toBe("89504e470d0a1a0a");
|
||||
});
|
||||
|
||||
it("avoids dynamic require of qrcode-terminal vendor modules", async () => {
|
||||
const sourcePath = resolve(process.cwd(), "src/media/qr-image.ts");
|
||||
const source = await readFile(sourcePath, "utf-8");
|
||||
expect(source).not.toContain("createRequire(");
|
||||
expect(source).not.toContain('require("qrcode-terminal/vendor/QRCode")');
|
||||
expect(source).toContain("qrcode-terminal/vendor/QRCode/index.js");
|
||||
expect(source).toContain("qrcode-terminal/vendor/QRCode/QRErrorCorrectLevel.js");
|
||||
});
|
||||
});
|
||||
|
||||
1
extensions/whatsapp/src/qr-terminal.ts
Normal file
1
extensions/whatsapp/src/qr-terminal.ts
Normal file
@@ -0,0 +1 @@
|
||||
export { renderQrTerminal } from "openclaw/plugin-sdk/media-runtime";
|
||||
12
extensions/whatsapp/src/qrcode-terminal.d.ts
vendored
12
extensions/whatsapp/src/qrcode-terminal.d.ts
vendored
@@ -1,12 +0,0 @@
|
||||
declare module "qrcode-terminal" {
|
||||
type GenerateOptions = {
|
||||
small?: boolean;
|
||||
};
|
||||
|
||||
type QrCodeTerminal = {
|
||||
generate: (input: string, options?: GenerateOptions, cb?: (output: string) => void) => void;
|
||||
};
|
||||
|
||||
const qrcode: QrCodeTerminal;
|
||||
export default qrcode;
|
||||
}
|
||||
@@ -21,6 +21,7 @@ import {
|
||||
writeCredsJsonAtomically,
|
||||
type CredsQueueWaitResult,
|
||||
} from "./creds-persistence.js";
|
||||
import { renderQrTerminal } from "./qr-terminal.js";
|
||||
import { formatError, getStatusCode } from "./session-errors.js";
|
||||
import {
|
||||
DisconnectReason,
|
||||
@@ -60,11 +61,6 @@ const LOGGED_OUT_STATUS = DisconnectReason?.loggedOut ?? 401;
|
||||
const CREDS_FLUSH_TIMEOUT_MESSAGE =
|
||||
"Queued WhatsApp creds save did not finish before auth bootstrap; skipping repair and continuing with primary creds.";
|
||||
|
||||
async function loadQrTerminal() {
|
||||
const mod = await import("qrcode-terminal");
|
||||
return mod.default ?? mod;
|
||||
}
|
||||
|
||||
function enqueueSaveCreds(
|
||||
authDir: string,
|
||||
saveCreds: () => Promise<void> | void,
|
||||
@@ -113,6 +109,11 @@ async function safeSaveCreds(
|
||||
}
|
||||
}
|
||||
|
||||
async function printTerminalQr(qr: string): Promise<void> {
|
||||
const output = await renderQrTerminal(qr, { small: true });
|
||||
process.stdout.write(output.endsWith("\n") ? output : `${output}\n`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a Baileys socket backed by the multi-file auth store we keep on disk.
|
||||
* Consumers can opt into QR printing for interactive login flows.
|
||||
@@ -172,8 +173,9 @@ export async function createWaSocket(
|
||||
opts.onQr?.(qr);
|
||||
if (printQr) {
|
||||
console.log("Scan this QR in WhatsApp (Linked Devices):");
|
||||
const qrcode = await loadQrTerminal();
|
||||
qrcode.generate(qr, { small: true });
|
||||
void printTerminalQr(qr).catch((err) => {
|
||||
sessionLogger.warn({ error: String(err) }, "failed rendering WhatsApp QR");
|
||||
});
|
||||
}
|
||||
}
|
||||
if (connection === "close") {
|
||||
|
||||
@@ -610,9 +610,8 @@ vi.mock("./session.runtime.js", () => {
|
||||
};
|
||||
});
|
||||
|
||||
vi.mock("qrcode-terminal", () => ({
|
||||
default: { generate: vi.fn() },
|
||||
generate: vi.fn(),
|
||||
vi.mock("./qr-terminal.js", () => ({
|
||||
renderQrTerminal: vi.fn(async () => "ASCII-QR"),
|
||||
}));
|
||||
|
||||
export const baileys = await import("./session.runtime.js");
|
||||
|
||||
Reference in New Issue
Block a user