39 lines
1.3 KiB
JavaScript
39 lines
1.3 KiB
JavaScript
import { mkdir, writeFile } from "node:fs/promises"
|
|
import { resolve, dirname } from "node:path"
|
|
import { createContext, runInNewContext } from "node:vm"
|
|
|
|
const sourceUrl = "https://docs.serverspace.io"
|
|
const targetPath = resolve(process.cwd(), "hey-api/backend/serverspace.json")
|
|
|
|
const response = await fetch(sourceUrl)
|
|
|
|
if (!response.ok) {
|
|
throw new Error(`Failed to download the ServerSpace docs page: ${response.status}`)
|
|
}
|
|
|
|
const html = await response.text()
|
|
|
|
// Extract the __redoc_state JS block from the <script> tag
|
|
const scriptMatch = html.match(/const\s+__redoc_state\s*=\s*\{[\s\S]*?(?=\n\s*var\s+container\b)/)
|
|
if (!scriptMatch) {
|
|
throw new Error("Could not find __redoc_state block in the HTML")
|
|
}
|
|
|
|
// Evaluate the JS to get the parsed object — replace const with var so it
|
|
// leaks into the VM sandbox context for extraction
|
|
const code = scriptMatch[0].replace(/^const\s+/, "var ")
|
|
const ctx = createContext({})
|
|
runInNewContext(code, ctx)
|
|
const specData = ctx.__redoc_state?.spec?.data
|
|
|
|
if (!specData || !specData.openapi) {
|
|
throw new Error("Extracted spec.data does not look like an OpenAPI spec")
|
|
}
|
|
|
|
const json = JSON.stringify(specData, null, 2)
|
|
|
|
await mkdir(dirname(targetPath), { recursive: true })
|
|
await writeFile(targetPath, json + "\n", "utf8")
|
|
|
|
console.log(`Saved ServerSpace OpenAPI spec to ${targetPath}`)
|