Files
2026-06-04 12:09:45 -03:00

82 lines
2.3 KiB
TypeScript

/**
* Regenerates src/endpoints.ts from the live Clarizen API docs.
* Requires CLARIZEN_API_KEY (or API_KEY_AW) in .env for Accept: text/html.
*/
import { writeFileSync } from "node:fs";
import { resolve } from "node:path";
const baseUrl = process.env.CLARIZEN_BASE_URL ?? "https://api.clarizen.com";
const apiKey = process.env.CLARIZEN_API_KEY ?? process.env.API_KEY_AW;
if (!apiKey) {
console.error("Set CLARIZEN_API_KEY or API_KEY_AW");
process.exit(1);
}
const indexRes = await fetch(`${baseUrl}/V2.0/services/`, {
headers: {
Authorization: `ApiKey ${apiKey}`,
Accept: "text/html",
},
});
const html = await indexRes.text();
const linkRe = /href="(\/V2\.0\/services\/[^"]+)"/g;
const paths = [...new Set([...html.matchAll(linkRe)].map((m) => m[1]))].filter(
(p) => !p.endsWith("/objects"),
);
const endpoints: Array<{
namespace: string;
operation: string;
path: string;
httpMethods: string[];
description: string;
}> = [];
for (const docPath of paths) {
const res = await fetch(`${baseUrl}${docPath}`, {
headers: {
Authorization: `ApiKey ${apiKey}`,
Accept: "text/html",
},
});
const page = await res.text();
const parts = docPath.split("/");
const namespace = parts[3] ?? "";
const operation = parts[4] ?? "";
const pathMatch = page.match(/<samp>([^<]+)<\/samp>/);
const methodMatch = page.match(
/<dt>HTTP Method<\/dt>\s*<dd><code>([^<]+)<\/code>/,
);
const descMatch = page.match(/<dt>Description<\/dt>\s*<dd>([^<]+)/);
endpoints.push({
namespace,
operation,
path: pathMatch?.[1] ?? docPath,
httpMethods: (methodMatch?.[1] ?? "POST")
.split(",")
.map((m) => m.trim().toUpperCase()),
description: (descMatch?.[1] ?? "")
.replace(/\u00a0/g, " ")
.trim(),
});
}
const namespaces = [...new Set(endpoints.map((e) => e.namespace))];
const out = `import type { EndpointDefinition } from "./types.js";
/** Auto-generated from ${baseUrl}/V2.0/services/ — run: npm run scrape */
export const ENDPOINTS: EndpointDefinition[] = ${JSON.stringify(endpoints, null, 2)};
export const NAMESPACES = ${JSON.stringify(namespaces, null, 2)} as const;
export type ClarizenNamespace = (typeof NAMESPACES)[number];
`;
const target = resolve(import.meta.dirname, "../src/endpoints.ts");
writeFileSync(target, out);
console.log(`Wrote ${endpoints.length} endpoints to ${target}`);