#!/usr/bin/env node /* eslint-disable no-console */ import { access } from "node:fs/promises"; import { constants } from "node:fs"; import path from "node:path"; import { fileURLToPath } from "node:url"; import { spawn } from "node:child_process"; const __dirname = path.dirname(fileURLToPath(import.meta.url)); const repoRoot = path.resolve(__dirname, ".."); export const gateLabel = "Permissions Audit S05 permission matrix"; export const testFiles = [ "apps/web/app/utils/services/rolesAndPermissionsService.role-matrix.test.ts", "apps/web/app/routes/admin/audit-trails.test.tsx", "apps/web/app/routes/app.$tenant/settings/logs/index.test.tsx", "apps/web/app/routes/app.$tenant/settings/logs/events.test.tsx", "apps/web/app/routes/app.$tenant/settings/logs/events.$id.test.tsx", ]; export async function findMissingTestFiles(files = testFiles) { const missingFiles = []; for (const testFile of files) { try { await access(path.join(repoRoot, testFile), constants.R_OK); } catch { missingFiles.push(testFile); } } return missingFiles; } export function formatMissingTestFiles(missingFiles) { return [ `${gateLabel}: missing required test file${missingFiles.length === 1 ? "" : "s"}`, ...missingFiles.map((missingFile) => `- ${missingFile}`), ].join("\n"); } export function vitestArgs(files = testFiles) { return ["exec", "vitest", "run", ...files]; } function runVitest() { return new Promise((resolve) => { const args = vitestArgs(); console.log(`${gateLabel}: pnpm ${args.join(" ")}`); const child = spawn("pnpm", args, { cwd: repoRoot, env: { ...process.env, CI: "1" }, stdio: "inherit", shell: false, }); child.on("error", (error) => { console.error(`${gateLabel}: failed to start Vitest`); console.error(error); resolve(1); }); child.on("close", (code) => { resolve(code ?? 1); }); }); } async function main() { console.log(`${gateLabel}: starting`); const missingFiles = await findMissingTestFiles(); if (missingFiles.length > 0) { console.error(formatMissingTestFiles(missingFiles)); process.exit(1); } const exitCode = await runVitest(); if (exitCode === 0) { console.log(`${gateLabel}: passed`); } else { console.error(`${gateLabel}: failed with exit code ${exitCode}`); } process.exit(exitCode); } if (process.argv[1] === fileURLToPath(import.meta.url)) { main().catch((error) => { console.error(`${gateLabel}: runner error`); console.error(error); process.exit(1); }); }