@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
JavaScript
;
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