UNPKG

@sanity/tsdoc

Version:

Generate API reference docs from TypeScript projects and store in a Sanity-friendly JSON format. Render a static frontend, or as React components.

177 lines (173 loc) 6.32 kB
"use strict"; var tsdoc = require("@sanity/tsdoc"), react = require("@vitejs/plugin-react"), chokidar = require("chokidar"), cors = require("cors"), express = require("express"), promises = require("fs/promises"), globby = require("globby"), mkdirp = require("mkdirp"), path = require("path"), vite = require("vite"); function _interopDefaultCompat(e) { return e && typeof e == "object" && "default" in e ? e : { default: e }; } var react__default = /* @__PURE__ */ _interopDefaultCompat(react), chokidar__default = /* @__PURE__ */ _interopDefaultCompat(chokidar), cors__default = /* @__PURE__ */ _interopDefaultCompat(cors), express__default = /* @__PURE__ */ _interopDefaultCompat(express), globby__default = /* @__PURE__ */ _interopDefaultCompat(globby), mkdirp__default = /* @__PURE__ */ _interopDefaultCompat(mkdirp), path__default = /* @__PURE__ */ _interopDefaultCompat(path); const HTML = `<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <meta name="viewport" content="minimum-scale=1, initial-scale=1, width=device-width, shrink-to-fit=no, viewport-fit=cover" /> <style> html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; -webkit-tap-highlight-color: transparent; -webkit-font-smoothing: antialiased; } html, body, #root { height: 100%; margin: 0; } </style> </head> <body> <div id="root"></div> <script type="module" src="/.tsdoc/main.tsx"><\/script> </body> </html> `; async function _writeHTML(options) { await promises.writeFile(path__default.default.resolve(options.outDir, "index.html"), HTML); } const SCRIPT = `import {mount} from '@sanity/tsdoc/react' mount({ docs: window.__INITIAL_STATE__ ? window.__INITIAL_STATE__.docs : undefined, element: document.getElementById('root'), releaseVersion: window.__INITIAL_STATE__ ? window.__INITIAL_STATE__.releaseVersion : undefined, }) `; async function _writeScript(options) { await promises.writeFile(path__default.default.resolve(options.outDir, "main.tsx"), SCRIPT); } async function _loadDocs(files) { const docs = []; for (const f of files) { const buf = await promises.readFile(f); docs.push(...JSON.parse(buf.toString())); } const _packageDocs = docs.filter((d) => d._type === "api.package"), _symbolDocs = docs.filter((d) => d._type === "api.symbol"), packageDocs = [], symbolDocs = []; for (const _pkgDoc of _packageDocs) { const pkg = packageDocs.find((p) => p.scope === _pkgDoc.scope && p.name === _pkgDoc.name); pkg ? _pkgDoc.latestRelease && (pkg.latestRelease = _pkgDoc.latestRelease, pkg.releases.push({ ..._pkgDoc.latestRelease, _key: _pkgDoc.latestRelease._ref })) : packageDocs.push({ ..._pkgDoc, releases: [..._pkgDoc.releases || []] }); } for (const _symbolDoc of _symbolDocs) symbolDocs.find((s) => s._id === _symbolDoc._id) || symbolDocs.push(_symbolDoc); const uniqueDocs = docs.filter((d) => d._type !== "api.package" && d._type !== "api.symbol"); return [...packageDocs, ...symbolDocs, ...uniqueDocs]; } async function devCommand(options) { const { cwd } = options, config = await tsdoc._loadConfig({ packagePath: cwd }), { alias, port = 1337 } = config?.app || {}, outDir = path__default.default.resolve(cwd, ".tsdoc"); await mkdirp__default.default(outDir), await _writeHTML({ outDir: path__default.default.resolve(cwd, ".tsdoc") }), await _writeScript({ outDir: path__default.default.resolve(cwd, ".tsdoc") }); const files = await globby__default.default(config?.input?.pattern || "etc/**/*.json", { cwd }), initialDocs = await _loadDocs(files), dataWatcher = chokidar__default.default.watch(config?.input?.pattern || "etc/**/*.json", { cwd, ignoreInitial: !0 }), sockets = []; function send(socket, msg) { socket.write(`data: ${JSON.stringify(msg)} `); } function broadcast(msg) { for (const socket of sockets) send(socket, msg); } dataWatcher.on("all", (eventType) => { eventType === "change" && _loadDocs(files).then((docs) => { broadcast({ type: "docs", docs }); }); }); const viteConfig = vite.defineConfig({ plugins: [react__default.default({ babel: { plugins: [["babel-plugin-react-compiler", { target: "19" }]] } })], resolve: { alias } }), vite$1 = await vite.createServer({ ...viteConfig, appType: "custom", configFile: !1, logLevel: "info", root: cwd, server: { hmr: { port: 15319 }, middlewareMode: !0, port }, cacheDir: "node_modules/.tsdoc/vite" }), app = express__default.default(); app.get("/events", cors__default.default({ origin: !0 }), (_req, res) => { res.set({ "Cache-Control": "no-cache", "Content-Type": "text/event-stream", Connection: "keep-alive" }), res.flushHeaders(), res.write(`retry: 10000 `), sockets.push(res), _loadDocs(files).then((docs) => { send(res, { type: "docs", docs }); }), _req.on("close", () => { const idx = sockets.indexOf(res); idx > -1 && sockets.splice(idx, 1); }); }), app.use(vite$1.middlewares), app.get("*", async (req, res, next) => { const url = req.originalUrl; try { const releaseVersion = initialDocs.find((d) => d._type === "api.release")?.version; let template = await promises.readFile(path__default.default.resolve(outDir, "index.html"), "utf-8"); template = await vite$1.transformIndexHtml(url, template); const html = template.replace('<div id="root"></div>', ['<div id="root"></div><script type="module">', "window.__INITIAL_STATE__=", JSON.stringify({ docs: initialDocs, releaseVersion }), "<\/script>"].join("")); res.status(200).set({ "Content-Type": "text/html" }).end(html); } catch (e) { e instanceof Error && vite$1.ssrFixStacktrace(e), next(e); } }), app.listen(port, () => { console.log(`listening on http://localhost:${port}`); }).on("close", () => { console.log("server closed"), process.exit(1); }); } exports.devCommand = devCommand; //# sourceMappingURL=index.js.map