import { writeFileSync } from 'node:fs'; import { resolve } from 'node:path'; import type { ProjectReflection } from 'typedoc'; import { ReflectionKind } from 'typedoc'; import type { Method } from '../../docs/.vitepress/components/api-docs/method'; import type { APIGroup, APIItem } from '../../docs/api/api-types'; import { extractModuleName, selectApiModules } from './moduleMethods'; import type { PageIndex } from './utils'; import { formatMarkdown, formatTypescript, pathDocsDir, pathOutputDir, } from './utils'; const pathDocsApiPages = resolve(pathDocsDir, '.vitepress', 'api-pages.ts'); const pathDocsApiSearchIndex = resolve( pathDocsDir, 'api', 'api-search-index.json' ); const scriptCommand = 'pnpm run generate:api-docs'; // Moved here because this must not be formatted by prettier const vitePressInFileOptions = `--- editLink: false --- `; /** * Writes the api page for the given module to the correct location. * * @param moduleName The name of the module to write the docs for. * @param lowerModuleName The lowercase name of the module. * @param comment The module comments. * @param methods The methods of the module. */ export function writeApiDocsModulePage( moduleName: string, lowerModuleName: string, comment: string, methods: Method[] ): void { // Write api docs page let content = ` # ${moduleName} ::: v-pre ${comment} ::: ${methods .map( (method) => ` ## ${method.name} ` ) .join('')} `.replace(/\n +/g, '\n'); content = vitePressInFileOptions + formatMarkdown(content); writeFileSync(resolve(pathOutputDir, `${lowerModuleName}.md`), content); } /** * Writes the api docs data to correct location. * * @param lowerModuleName The lowercase name of the module. * @param methods The methods data to save. */ export function writeApiDocsData( lowerModuleName: string, methods: Method[] ): void { const content = JSON.stringify( methods.reduce>( (map, method) => ({ ...map, [method.name]: method, }), {} ) ); writeFileSync(resolve(pathOutputDir, `${lowerModuleName}.json`), content); } /** * Writes the api docs index to correct location. * * @param pages The pages to write into the index. */ export function writeApiPagesIndex(pages: PageIndex): void { // Write api-pages.ts console.log('Updating api-pages.ts'); pages.sort((a, b) => a.text.localeCompare(b.text)); pages.splice(0, 0, { text: 'Overview', link: '/api/' }); let apiPagesContent = ` // This file is automatically generated. // Run '${scriptCommand}' to update export const apiPages = ${JSON.stringify(pages)}; `.replace(/\n +/, '\n'); apiPagesContent = formatTypescript(apiPagesContent); writeFileSync(pathDocsApiPages, apiPagesContent); } export function writeApiSearchIndex(project: ProjectReflection): void { const apiIndex: APIGroup[] = []; const moduleApiSection: APIGroup = { text: 'Module API', items: [], }; apiIndex.push(moduleApiSection); const apiModules = selectApiModules(project); moduleApiSection.items = apiModules .map((module) => { const moduleName = extractModuleName(module); const apiSection: APIItem = { text: moduleName, link: moduleName.toLowerCase(), headers: [], }; if (module.kind !== ReflectionKind.Property) { apiSection.headers = module .getChildrenByKind(ReflectionKind.Method) .map((child) => ({ anchor: child.name, text: child.name, })); } else { // TODO @Shinigami92 2022-08-17: Extract capitalization into own function apiSection.text = apiSection.text.substring(0, 1).toUpperCase() + apiSection.text.substring(1); apiSection.headers = [ { anchor: module.name, text: module.name, }, ]; } return apiSection; }) .sort((a, b) => a.text.localeCompare(b.text)); writeFileSync(pathDocsApiSearchIndex, JSON.stringify(apiIndex)); }