UNPKG

@storm-stack/core

Version:

A build toolkit and runtime used by Storm Software in TypeScript applications

187 lines (179 loc) 7.6 kB
import { init_esm_shims, __name } from './chunk-QH7NXH7H.js'; import { LogLevelLabel } from '@storm-software/config-tools/types'; import { existsSync } from '@stryke/fs/exists'; import { removeDirectory, createDirectory } from '@stryke/fs/helpers'; import { joinPaths } from '@stryke/path/join-paths'; import { findFileName } from '@stryke/path/file-path-fns'; import { writeFile } from 'node:fs/promises'; import { sep } from 'node:path'; import { Application, TypeDocReader, PackageJsonReader, TSConfigReader, Converter, ReflectionKind, PageEvent } from 'typedoc'; // src/commands/docs/index.ts init_esm_shims(); // src/commands/docs/api-reference/index.ts init_esm_shims(); // src/lib/typedoc/init.ts init_esm_shims(); var objectToFrontmatter = /* @__PURE__ */ __name((object = {}) => Object.entries(object).filter(([, value]) => { return value !== void 0 && value !== null && value !== "" && typeof value === "string" || Array.isArray(value) && value.length > 0; }).map(([key, value]) => `${key}: ${value}`).join("\n"), "objectToFrontmatter"); var onRendererPageEnd = /* @__PURE__ */ __name((frontmatterObject) => (event) => { if (!event.contents) { return; } else if (/README\.md$/.test(event.url)) { event.preventDefault(); return; } const frontmatter = `--- title: '${event.model.name}' ${objectToFrontmatter(frontmatterObject)} --- `; event.contents = frontmatter + event.contents; }, "onRendererPageEnd"); var buildNavigationFromProjectReflection = /* @__PURE__ */ __name((baseUrl = "", project) => { const baseUrlWithoutTrailingSlash = baseUrl.replace(/\/$/gm, ""); const result = { type: "flat" }; const isGroupOfModules = /* @__PURE__ */ __name((group) => group.title === "Modules", "isGroupOfModules"); const reflectionToNavItem = /* @__PURE__ */ __name((reflection) => { return { title: reflection.name, url: `${baseUrlWithoutTrailingSlash}/${reflection.url}`.replace(/\.md$/, "") }; }, "reflectionToNavItem"); const modulesGroupToNavigationGroup = /* @__PURE__ */ __name((module) => ({ items: (module.groups ?? []).flatMap((group) => group.children.map(reflectionToNavItem)), name: module.name }), "modulesGroupToNavigationGroup"); const navFromReflectionGroups = /* @__PURE__ */ __name((groups, nav = { type: "flat" }) => { groups.forEach((group) => { if (isGroupOfModules(group)) { nav.type = "modular"; nav.modules = group.children.map(modulesGroupToNavigationGroup); } else { nav.items = nav?.items?.length ? nav.items : []; nav.items = nav.items.concat(group.children.flatMap(reflectionToNavItem)); } }); return nav; }, "navFromReflectionGroups"); return navFromReflectionGroups(project.groups, result); }, "buildNavigationFromProjectReflection"); var onDeclaration = /* @__PURE__ */ __name((entryPoints = []) => (context, reflection) => { if (reflection.kind === ReflectionKind.Module) { const matchingEntryPoint = entryPoints.find((entryPoint) => entryPoint.path === reflection.sources[0].fullFileName); reflection.name = matchingEntryPoint?.name ?? reflection.name; } }, "onDeclaration"); var typedocConfig = { excludeExternals: true, excludeInternal: true, excludePrivate: true, excludeProtected: true, githubPages: false }; var markdownPluginConfig = { hideBreadcrumbs: true, hideInPageTOC: true, hidePageHeader: true, hidePageTitle: true }; var removeTrailingSlash = /* @__PURE__ */ __name((pathString = "") => pathString.endsWith(sep) ? pathString.slice(0, pathString.length - 1) : pathString, "removeTrailingSlash"); var initTypedoc = /* @__PURE__ */ __name(async (context, options) => { const { baseUrl = "/docs/", outputPath } = options; const entryPoints = options.entryPoints ?? context.entry.map((entry) => ({ name: entry.name || entry.output || findFileName(entry.file, { withExtension: false }), path: joinPaths(context.options.projectRoot, entry.file) })); const app = await Application.bootstrapWithPlugins({ ...typedocConfig, ...markdownPluginConfig, gitRevision: context.options.workspaceConfig.branch || "main", tsconfig: context.tsconfig.tsconfigFilePath, exclude: context.tsconfig.tsconfigJson.exclude?.filter(Boolean), out: outputPath, basePath: baseUrl, entryPoints: entryPoints?.map((e) => e.path), plugin: [ "typedoc-plugin-markdown", "@storm-stack/core/lib/typedoc/plugin" ], theme: "storm-stack", readme: "none", excludePrivate: true, hideGenerator: true }, [ new TypeDocReader(), new PackageJsonReader(), new TSConfigReader() ]); app.options.addReader(new TSConfigReader()); app.converter.on(Converter.EVENT_CREATE_DECLARATION, onDeclaration(entryPoints)); const getReflections = /* @__PURE__ */ __name(async () => app.convert(), "getReflections"); const generateDocs = /* @__PURE__ */ __name(async (opts) => { const { outputPath: outputFolder, project, frontmatter } = opts; app.renderer.on(PageEvent.END, onRendererPageEnd(frontmatter)); await app.generateDocs(project, outputFolder || outputPath); }, "generateDocs"); const generateNavigationJSON = /* @__PURE__ */ __name(async (project, outputFolder = outputPath) => { const navigation = buildNavigationFromProjectReflection(baseUrl, project); await writeFile(`${removeTrailingSlash(outputFolder)}/nav.json`, JSON.stringify(navigation)); }, "generateNavigationJSON"); return { app, generateDocs, generateNavigationJSON, getReflections }; }, "initTypedoc"); // src/commands/docs/api-reference/index.ts async function docsApiReference(context, hooks) { context.log(LogLevelLabel.TRACE, "Writing API-Reference documentation for the Storm Stack project artifacts."); const outputPath = joinPaths(context.options.projectRoot, "docs", "generated", "api-reference"); if (existsSync(outputPath)) { await removeDirectory(outputPath); } await createDirectory(outputPath); const { generateDocs, getReflections } = await initTypedoc(context, { outputPath }); const project = await getReflections(); if (project) { await generateDocs({ project }); } await hooks.callHook("docs:api-reference", context).catch((error) => { context.log(LogLevelLabel.ERROR, `An error occured while writing the API-Reference documentation for the Storm Stack project artifacts: ${error.message} ${error.stack ?? ""}`); throw new Error("An error occured while writing the API-Reference documentation for the Storm Stack project artifacts", { cause: error }); }); } __name(docsApiReference, "docsApiReference"); // src/commands/docs/index.ts async function docs(context, hooks) { await hooks.callHook("docs:begin", context).catch((error) => { context.log(LogLevelLabel.ERROR, `An error occured while starting to generate documentation for the Storm Stack project: ${error.message} ${error.stack ?? ""}`); throw new Error("An error occured while starting to generate documentation for the Storm Stack project", { cause: error }); }); await docsApiReference(context, hooks); await hooks.callHook("docs:complete", context).catch((error) => { context.log(LogLevelLabel.ERROR, `An error occured while finishing generation of documentation for the Storm Stack project: ${error.message} ${error.stack ?? ""}`); throw new Error("An error occured while finishing generation of documentation for the Storm Stack project", { cause: error }); }); } __name(docs, "docs"); export { docs };