This repository has been archived on 2026-08-23. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
pi-web/pi-web-plugins/pluginPublicApi.test.ts

39 lines
1.6 KiB
TypeScript

import { readdir, readFile } from "node:fs/promises";
import { join } from "node:path";
import { describe, expect, it } from "vitest";
const pluginRoot = "pi-web-plugins";
const forbiddenPatterns = [
{ pattern: /\bfetch\s*\(/u, message: "direct browser fetch" },
{ pattern: /["'`][^"'`]*\/api\//u, message: "direct PI WEB /api URL" },
{ pattern: /piWebInternal/u, message: "legacy internal plugin context" },
{ pattern: /(?:\.\.\/)+src\//u, message: "imports from PI WEB source internals" },
];
describe("bundled PI WEB plugins", () => {
it("use public plugin APIs instead of direct PI WEB internals", async () => {
const violations: string[] = [];
for (const file of await pluginSourceFiles(pluginRoot)) {
const content = await readFile(file, "utf8");
for (const { pattern, message } of forbiddenPatterns) {
if (pattern.test(content)) violations.push(`${file}: ${message}`);
}
if (content.includes("piWebUnstable") && !content.includes("@jmfederico/pi-web/plugin-api/unstable")) {
violations.push(`${file}: piWebUnstable use without explicit unstable type import`);
}
}
expect(violations).toEqual([]);
});
});
async function pluginSourceFiles(root: string): Promise<string[]> {
const files: string[] = [];
for (const entry of await readdir(root, { withFileTypes: true })) {
const path = join(root, entry.name);
if (entry.isDirectory()) files.push(...await pluginSourceFiles(path));
else if (entry.isFile() && entry.name.endsWith(".ts") && !entry.name.endsWith(".test.ts")) files.push(path);
}
return files;
}