first commit
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
/**
|
||||
* 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}`);
|
||||
Reference in New Issue
Block a user