43 lines
1.7 KiB
JavaScript
43 lines
1.7 KiB
JavaScript
import { readFile } from "node:fs/promises";
|
|
import path from "node:path";
|
|
import { spawnSync } from "node:child_process";
|
|
import { fileURLToPath } from "node:url";
|
|
|
|
const scriptDirectory = path.dirname(fileURLToPath(import.meta.url));
|
|
const repoRoot = path.resolve(scriptDirectory, "..");
|
|
const openApiPath = path.join(repoRoot, "openapi", "RpgRoller.json");
|
|
const appJsPath = path.join(repoRoot, "RpgRoller", "wwwroot", "app.js");
|
|
const generatedClientPath = path.join(repoRoot, "RpgRoller", "wwwroot", "generated", "api-client.js");
|
|
|
|
const openApi = JSON.parse(await readFile(openApiPath, "utf8"));
|
|
const generatedClient = await readFile(generatedClientPath, "utf8");
|
|
const errors = [];
|
|
|
|
const appSyntaxCheck = spawnSync(process.execPath, ["--check", appJsPath], { encoding: "utf8" });
|
|
if (appSyntaxCheck.status !== 0) {
|
|
errors.push(`Syntax error in ${path.relative(repoRoot, appJsPath)}:\n${appSyntaxCheck.stderr}`);
|
|
}
|
|
|
|
for (const [pathKey, pathItem] of Object.entries(openApi.paths ?? {})) {
|
|
for (const [method, operation] of Object.entries(pathItem ?? {})) {
|
|
if (operation === null || typeof operation !== "object") {
|
|
continue;
|
|
}
|
|
|
|
if (typeof operation.operationId !== "string" || operation.operationId.length === 0) {
|
|
errors.push(`Missing operationId for ${method.toUpperCase()} ${pathKey}`);
|
|
continue;
|
|
}
|
|
|
|
if (!generatedClient.includes(`apiOperations.${operation.operationId}`)) {
|
|
errors.push(`Generated client is missing operation export for ${operation.operationId}`);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (errors.length > 0) {
|
|
throw new Error(errors.join("\n"));
|
|
}
|
|
|
|
console.log("Frontend lint checks passed.");
|