refactor(runtime): replace Bun dependency with Node fetch

Run Perplexity search and auth requests through pi's Node runtime instead of
shelling out to Bun. Move development and CI commands to npm, add a Node test
build path, and keep OTP auth fail-fast when Set-Cookie headers are not
available.
This commit is contained in:
Ivan Pereira
2026-06-23 15:51:16 +01:00
parent 142640d96c
commit bbb5623f25
29 changed files with 4085 additions and 882 deletions
+56
View File
@@ -0,0 +1,56 @@
import { afterEach, describe, expect, mock, test } from "./test-helpers.js";
import { perplexityFetchText } from "../src/perplexity-fetch.js";
const originalFetch = globalThis.fetch;
const originalGetSetCookie = (Headers.prototype as Headers & { getSetCookie?: () => string[] }).getSetCookie;
afterEach(() => {
globalThis.fetch = originalFetch;
Object.defineProperty(Headers.prototype, "getSetCookie", {
configurable: true,
writable: true,
value: originalGetSetCookie,
});
});
describe("perplexityFetchText", () => {
test("returns all Set-Cookie headers from Node fetch", async () => {
globalThis.fetch = mock(async () =>
new Response("ok", {
status: 200,
headers: [
["set-cookie", "first=1; Path=/; HttpOnly"],
["set-cookie", "second=2; Path=/; Secure"],
],
}),
) as unknown as typeof fetch;
const response = await perplexityFetchText("https://example.com", {
method: "GET",
headers: {},
});
expect(response.ok).toBe(true);
expect(response.status).toBe(200);
expect(response.bodyText).toBe("ok");
expect(response.cookies).toEqual([
"first=1; Path=/; HttpOnly",
"second=2; Path=/; Secure",
]);
});
test("fails when the Node fetch runtime cannot expose Set-Cookie headers", async () => {
Object.defineProperty(Headers.prototype, "getSetCookie", {
configurable: true,
writable: true,
value: undefined,
});
globalThis.fetch = mock(async () => new Response("ok", { status: 200 })) as unknown as typeof fetch;
await expect(perplexityFetchText("https://example.com", { method: "GET", headers: {} })).rejects.toThrow(
"Headers.getSetCookie",
);
});
});