stemedb/community/scripts/fetch-openapi.ts
jordan b3e8a9a058 feat: Multi-application expansion with chaos testing and community UI
Major additions:
- Community Next.js app (port 18187) for browsing claims with API docs
- stemedb-chaos crate: Fault injection, chaos testing, CRDT properties
- Latent ingestion system: Reddit/FDA ingesters with ADK-Go agents
- Disputed claims handling: Manual review workflows and validation
- Aphoria security scanner: New extractors (SQL injection, command
  injection, weak crypto, TLS version), policy-based ignores, UAT reports
- Docker infrastructure: Dockerfile, docker-compose.yml for full stack
- VulnBank demo: Intentionally vulnerable multi-language test corpus

SDK & API enhancements:
- Source registry handlers for tracking data provenance
- Metrics endpoint
- Skeptic filtering improvements

Code quality:
- Split 14 large files (>500 lines) into focused modules
- All files now under 500-line limit per project guidelines

Documentation:
- Chaos testing guide, circuit breakers, observability docs
- Phase 7 UAT documentation updates
- Martin Kleppmann technical writer agent

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 01:24:14 -07:00

61 lines
2.0 KiB
TypeScript

/**
* Fetches the OpenAPI spec from the running stemedb-api server
* and saves it to public/openapi.json for use by Scalar.
*
* Usage:
* npx tsx scripts/fetch-openapi.ts
*
* Set STEMEDB_API_URL to override the default endpoint.
*/
import { writeFileSync, existsSync, readFileSync } from "fs";
import { join } from "path";
const API_URL = process.env.STEMEDB_API_URL || "http://127.0.0.1:18180";
const OPENAPI_ENDPOINT = `${API_URL}/api-docs/openapi.json`;
const OUTPUT_PATH = join(process.cwd(), "public", "openapi.json");
async function fetchOpenApiSpec(): Promise<void> {
console.log(`Fetching OpenAPI spec from ${OPENAPI_ENDPOINT}...`);
try {
const response = await fetch(OPENAPI_ENDPOINT);
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
const spec = await response.json();
// Validate it looks like an OpenAPI spec
if (!spec.openapi || !spec.info || !spec.paths) {
throw new Error("Invalid OpenAPI spec: missing required fields");
}
writeFileSync(OUTPUT_PATH, JSON.stringify(spec, null, 2));
console.log(`OpenAPI spec saved to ${OUTPUT_PATH}`);
console.log(` Version: ${spec.info.version}`);
console.log(` Title: ${spec.info.title}`);
console.log(` Endpoints: ${Object.keys(spec.paths).length}`);
} catch (error) {
if (error instanceof Error && error.message.includes("ECONNREFUSED")) {
console.warn("Could not connect to stemedb-api server.");
console.warn("Using existing spec if available, or provide a bundled fallback.");
if (existsSync(OUTPUT_PATH)) {
const existing = JSON.parse(readFileSync(OUTPUT_PATH, "utf-8"));
console.log(`Using cached spec (v${existing.info?.version || "unknown"})`);
return;
}
console.error("No cached spec available. Start stemedb-api and retry.");
process.exit(1);
}
console.error("Failed to fetch OpenAPI spec:", error);
process.exit(1);
}
}
fetchOpenApiSpec();