repositories / pi-ext
pi-ext
bugabingas pi extensions
owned by admin
scripts/build/release.test.ts
Rawimport {
mkdirSync,
mkdtempSync,
readFileSync,
rmSync,
symlinkSync,
writeFileSync,
} from "node:fs";
import { join } from "node:path";
import { afterEach, describe, expect, it } from "vitest";
import { ROOT } from "./build.ts";
import { archivePackage, collectionManifest, treeDigest } from "./release.ts";
const roots: string[] = [];
afterEach(() => {
for (const root of roots.splice(0))
rmSync(root, { recursive: true, force: true });
});
describe("repository release", () => {
it("exposes every extension and resource from the root installation unit", () => {
expect(
collectionManifest("0.1.0", [
{ name: "a", pi: { extensions: ["index.js"], skills: ["skills"] } },
{ name: "b", pi: { extensions: ["entry.js"], prompts: ["prompts"] } },
]),
).toEqual({
name: "pi-ext",
version: "0.1.0",
private: true,
type: "module",
pi: {
extensions: ["packages/a/index.js", "packages/b/entry.js"],
skills: ["packages/a/skills"],
prompts: ["packages/b/prompts"],
},
});
});
it("archives exact package bytes and records their SHA-256", () => {
const scratch = join(ROOT, ".pi", "tmp");
mkdirSync(scratch, { recursive: true });
const root = mkdtempSync(join(scratch, "release-test-"));
roots.push(root);
const pkg = join(root, "package");
mkdirSync(pkg);
writeFileSync(join(pkg, "index.js"), "export default () => {};\n");
symlinkSync("index.js", join(pkg, "entry.js"));
const digest = treeDigest(pkg);
const archive = join(root, "package.tgz");
expect(archivePackage(pkg, archive, root)).toMatch(/^[a-f0-9]{64}$/u);
expect(readFileSync(archive).length).toBeGreaterThan(0);
expect(treeDigest(pkg)).toBe(digest);
writeFileSync(join(pkg, "index.js"), "changed\n");
expect(treeDigest(pkg)).not.toBe(digest);
writeFileSync(join(root, "outside.js"), "outside\n");
symlinkSync("../outside.js", join(pkg, "escape.js"));
expect(() => treeDigest(pkg)).toThrow(/Symlink escapes package/u);
});
});