import amqp from "amqplib"; const PORT = process.argv[2]; const MPORT = process.argv[3]; const B = `http://127.0.0.1:${MPORT}`; const AUTH = "Basic " + Buffer.from("guest:guest").toString("base64"); async function api(method, path, body) { const r = await fetch(B + path, { method, headers: { "content-type": "application/json", authorization: AUTH }, body: body ? JSON.stringify(body) : undefined, }); if (r.status >= 300 && r.status !== 404) throw new Error(`${method} ${path} -> ${r.status}`); } await api("PUT", "/api/exchanges/%2f/mesh.events.dead", { type: "topic", durable: true }); await api("PUT", "/api/users/al", { password: "s", tags: "" }); const Q = "anchor.al.events"; const D = "mesh.events.dead"; const q = Q.replace(/\./g, "\\."); const d = D.replace(/\./g, "\\."); // configure, write, read patterns per grant on the dead exchange const combos = { "none": { configure: `^${q}$`, write: `^${q}$`, read: `^${q}$` }, "read-dead": { configure: `^${q}$`, write: `^${q}$`, read: `^(${q}|${d})$` }, "write-dead": { configure: `^${q}$`, write: `^(${q}|${d})$`, read: `^${q}$` }, "configure-dead": { configure: `^(${q}|${d})$`, write: `^${q}$`, read: `^${q}$` }, "read+write-dead": { configure: `^${q}$`, write: `^(${q}|${d})$`, read: `^(${q}|${d})$` }, }; let i = 0; for (const [label, perms] of Object.entries(combos)) { await api("PUT", "/api/permissions/%2f/al", perms); const queue = `${Q}.${i++}`; // fresh each time try { const c = await amqp.connect(`amqp://al:s@127.0.0.1:${PORT}/`); const ch = await c.createChannel(); ch.on("error", () => {}); await ch.assertQueue(queue, { durable: true, deadLetterExchange: D }); console.log(`${label}: declare-with-DLX OK`); await c.close(); } catch (e) { console.log(`${label}: FAIL - ${String(e.message).slice(0, 70)}`); } }