Files
bun.sh/test/cli/install/dummy.registry.ts
2025-01-20 23:17:52 -08:00

162 lines
3.9 KiB
TypeScript

/**
* This file can be directly run
*
* PACKAGE_DIR_TO_USE=(realpath .) bun test/cli/install/dummy.registry.ts
*/
import { file, Server } from "bun";
import { tmpdirSync } from "harness";
let expect: (typeof import("bun:test"))["expect"];
import { readdir, writeFile } from "fs/promises";
import { basename, join } from "path";
type Handler = (req: Request) => Response | Promise<Response>;
type Pkg = {
name: string;
version: string;
dist: {
tarball: string;
};
};
let handler: Handler;
let server: Server;
export let package_dir: string;
export let requested: number;
export let root_url: string;
export let check_npm_auth_type = { check: true };
export function dummyRegistry(urls: string[], info: any = { "0.0.2": {} }, numberOfTimesTo500PerURL = 0) {
let retryCountsByURL = new Map<string, number>();
const _handler: Handler = async request => {
urls.push(request.url);
const url = request.url.replaceAll("%2f", "/");
let status = 200;
if (numberOfTimesTo500PerURL > 0) {
let currentCount = retryCountsByURL.get(request.url);
if (currentCount === undefined) {
retryCountsByURL.set(request.url, numberOfTimesTo500PerURL);
status = 500;
} else {
retryCountsByURL.set(request.url, currentCount - 1);
status = currentCount > 0 ? 500 : 200;
}
}
expect(request.method).toBe("GET");
if (url.endsWith(".tgz")) {
return new Response(file(join(import.meta.dir, basename(url).toLowerCase())), { status });
}
expect(request.headers.get("accept")).toBe(
"application/vnd.npm.install-v1+json; q=1.0, application/json; q=0.8, */*",
);
if (check_npm_auth_type.check) {
expect(request.headers.get("npm-auth-type")).toBe(null);
}
expect(await request.text()).toBe("");
const name = url.slice(url.indexOf("/", root_url.length) + 1);
const versions: Record<string, Pkg> = {};
let version;
for (version in info) {
if (!/^[0-9]/.test(version)) continue;
versions[version] = {
name,
version,
dist: {
tarball: `${url}-${info[version].as ?? version}.tgz`,
},
...info[version],
};
}
return new Response(
JSON.stringify({
name,
versions,
"dist-tags": {
latest: info.latest ?? version,
},
}),
{
status: status,
},
);
};
return _handler;
}
export function setHandler(newHandler: Handler) {
handler = newHandler;
}
function resetHandler() {
setHandler(() => new Response("Tea Break~", { status: 418 }));
}
export function dummyBeforeAll() {
server = Bun.serve({
async fetch(request) {
requested++;
return await handler(request);
},
port: 0,
});
root_url = `http://localhost:${server.port}`;
}
export function dummyAfterAll() {
server.stop();
}
export function getPort() {
return server.port;
}
let packageDirGetter: () => string = () => {
return tmpdirSync();
};
export async function dummyBeforeEach() {
resetHandler();
requested = 0;
package_dir = packageDirGetter();
await writeFile(
join(package_dir, "bunfig.toml"),
`
[install]
cache = false
registry = "http://localhost:${server.port}/"
saveTextLockfile = false
`,
);
}
export async function dummyAfterEach() {
resetHandler();
}
if (Bun.main === import.meta.path) {
// @ts-expect-error
expect = value => {
return {
toBe(expected) {
if (value !== expected) {
throw new Error(`Expected ${value} to be ${expected}`);
}
},
};
};
if (process.env.PACKAGE_DIR_TO_USE) {
packageDirGetter = () => process.env.PACKAGE_DIR_TO_USE!;
}
await dummyBeforeAll();
await dummyBeforeEach();
setHandler(dummyRegistry([]));
console.log("Running dummy registry!\n\n URL: ", root_url!, "\n", "DIR: ", package_dir!);
} else {
// @ts-expect-error
({ expect } = Bun.jest(import.meta.path));
}