Files
HiveGrid-Wireframes/hivegrid-cloud/scripts/verify-prisma-ownership.test.mjs
T

137 lines
4.4 KiB
JavaScript

import fs from "node:fs";
import os from "node:os";
import path from "node:path";
import assert from "node:assert/strict";
import { afterEach, describe, it } from "vitest";
import {
checkPackageBoundaryImports,
checkSchemaOutput,
scanForbiddenPrismaOwnershipText,
verifyPrismaOwnership,
} from "./verify-prisma-ownership.mjs";
const fixtures = [];
function writeFile(rootDir, relativePath, content) {
const absolutePath = path.join(rootDir, relativePath);
fs.mkdirSync(path.dirname(absolutePath), { recursive: true });
fs.writeFileSync(absolutePath, content);
}
function createFixture(overrides = {}) {
const rootDir = fs.mkdtempSync(path.join(os.tmpdir(), "prisma-ownership-"));
fixtures.push(rootDir);
writeFile(
rootDir,
"prisma/schema/schema.prisma",
overrides.schema ?? `generator client {
provider = "prisma-client"
output = "../../packages/db/generated/prisma/client"
}
datasource db {
provider = "postgresql"
}
`,
);
writeFile(
rootDir,
"packages/db/src/client.server.ts",
overrides.clientServer ?? `export * from "../generated/prisma/client/client.ts";
`,
);
writeFile(
rootDir,
"packages/db/src/prisma-browser.ts",
overrides.prismaBrowser ?? `export * from "../generated/prisma/client/browser.ts";
`,
);
writeFile(rootDir, "apps/web/app/routes/example.tsx", overrides.appSource ?? "export const route = true;\n");
writeFile(rootDir, "packages/db/generated/prisma/client/client.ts", "app/generated/prisma fixture text ignored in generated output\n");
return rootDir;
}
afterEach(() => {
while (fixtures.length > 0) {
fs.rmSync(fixtures.pop(), { recursive: true, force: true });
}
});
describe("verify-prisma-ownership", () => {
it("passes for a repository using package-owned Prisma 7 TypeScript entrypoints", () => {
const rootDir = createFixture({
appSource: `import { Prisma } from "@toolctrl/db/prisma-browser";
export const route = Prisma;
`,
});
const result = verifyPrismaOwnership(rootDir);
assert.deepEqual(result.failures, []);
assert.ok(result.passes.some((pass) => pass.includes("generator output is package-owned")));
assert.ok(result.passes.some((pass) => pass.includes("client.server.ts")));
assert.ok(result.passes.some((pass) => pass.includes("repository text scan")));
});
it("fails when app code imports an app-local generated Prisma browser client", () => {
const rootDir = createFixture({
appSource: `import { Prisma } from "~/generated/prisma/client/browser";
export const route = Prisma;
`,
});
const result = scanForbiddenPrismaOwnershipText(rootDir);
assert.match(result.failures.join("\n"), /app\/routes\/example\.tsx: forbidden app-local generated Prisma client import/);
});
it("fails when app code imports the old root-local generated Prisma client", () => {
const rootDir = createFixture({
appSource: `const relativeGeneratedClientPath = "../generated/prisma/client";
const appGeneratedClientPath = "app/generated/prisma/client";
`,
});
const result = scanForbiddenPrismaOwnershipText(rootDir);
assert.match(result.failures.join("\n"), /app\/routes\/example\.tsx: forbidden root\/app Prisma generated-client path/);
});
it("fails when schema output points outside packages/db", () => {
const rootDir = createFixture({
schema: `generator client {
provider = "prisma-client"
output = "../../app/generated/prisma/client"
}
`,
});
const result = checkSchemaOutput(rootDir);
assert.match(result.failures.join("\n"), /prisma\/schema\/schema\.prisma: expected generator output/);
assert.match(result.failures.join("\n"), /old root\/app generated Prisma ownership/);
});
it("fails when package boundary files do not use package-owned generated TypeScript entrypoints", () => {
const rootDir = createFixture({
clientServer: `const crossedBoundaryPath = "../../../app/generated/prisma/client";
export const client = crossedBoundaryPath;
`,
prismaBrowser: `const wrongClientPath = "@prisma/client";
export { wrongClientPath };
`,
});
const result = checkPackageBoundaryImports(rootDir);
assert.match(result.failures.join("\n"), /packages\/db\/src\/client\.server\.ts: must import\/export/);
assert.match(result.failures.join("\n"), /packages\/db\/src\/client\.server\.ts: must not cross out/);
assert.match(result.failures.join("\n"), /packages\/db\/src\/prisma-browser\.ts: must import\/export/);
});
});