UNPKG

@mui/internal-docs-infra

Version:

MUI Infra - internal documentation creation tools.

149 lines (135 loc) 5.69 kB
import { formatParameters, parseMarkdownToHast, applyDescriptionReplacements } from "./format.mjs"; import { formatType } from "./formatType.mjs"; import { isClassType } from "./typeGuards.mjs"; import { rewriteTypeStringsDeep } from "./rewriteTypes.mjs"; /** * Class type from typescript-api-extractor. * Defined here since ClassNode may not be exported from older versions. */ /** * Formatted class metadata with plain text types and parsed markdown descriptions. * * Type highlighting (type → HAST, shortType, detailedType) is deferred to * the loadServerTypes stage via highlightTypesMeta() after highlightTypes(). */ /** * Formatted property metadata for class properties. */ /** * Formatted method metadata for class methods. */ /** * Formats class export data into a structured metadata object. * * @param classExport - The class export node from typescript-api-extractor * @param typeNameMap - Map for transforming type names * @param rewriteContext - Context for type string rewriting including type compatibility map * @param options - Formatting options * @returns Formatted class metadata with constructor and methods */ export async function formatClassData(classExport, typeNameMap, rewriteContext, options = {}) { const { descriptionReplacements, formatting, externalTypes } = options; const { exportNames } = rewriteContext; // Cast to ClassNode since we've verified via isPublicClass const classType = classExport.type; const descriptionText = classExport.documentation?.description ? applyDescriptionReplacements(classExport.documentation.description, descriptionReplacements) : undefined; const description = descriptionText ? await parseMarkdownToHast(descriptionText) : undefined; // Get the first construct signature for constructor parameters const constructSignature = classType.constructSignatures[0]; const constructorParams = constructSignature?.parameters ?? []; const constructorParameters = await formatParameters(constructorParams, { exportNames, typeNameMap, formatting, externalTypes, descriptionReplacements }); // Format properties const propertyEntries = await Promise.all(classType.properties.map(async prop => { const propDescriptionText = prop.documentation?.description ? applyDescriptionReplacements(prop.documentation.description, descriptionReplacements) : undefined; const propDescription = propDescriptionText ? await parseMarkdownToHast(propDescriptionText) : undefined; const typeText = formatType(prop.type, { expandObjects: true, exportNames, typeNameMap, externalTypesCollector: externalTypes }); const formattedProperty = { name: prop.name, typeText, description: propDescription, descriptionText: propDescriptionText, optional: prop.optional, readonly: prop.readonly, isStatic: prop.isStatic ?? false }; return [prop.name, formattedProperty]; })); const properties = Object.fromEntries(propertyEntries); // Format methods in parallel to avoid eslint no-await-in-loop const methodEntries = await Promise.all(classType.methods.map(async method => { const methodDescriptionText = method.documentation?.description ? applyDescriptionReplacements(method.documentation.description, descriptionReplacements) : undefined; const methodDescription = methodDescriptionText ? await parseMarkdownToHast(methodDescriptionText) : undefined; // Use the first call signature (we don't support overloads in docs yet) const signature = method.callSignatures?.[0]; const methodParameters = await formatParameters(signature?.parameters ?? [], { exportNames, typeNameMap, formatting, externalTypes, descriptionReplacements }); const returnValue = signature ? formatType(signature.returnValueType, { expandObjects: true, exportNames, typeNameMap, externalTypesCollector: externalTypes }) : 'void'; // Get return value description from @returns tag if available const returnsTag = method.documentation?.tags?.find(tag => tag.name === 'returns'); const returnValueDescriptionText = returnsTag?.value; const returnValueDescription = returnValueDescriptionText ? await parseMarkdownToHast(returnValueDescriptionText) : undefined; const formattedMethod = { name: method.name, description: methodDescription, descriptionText: methodDescriptionText, parameters: methodParameters, returnValue, returnValueDescription, returnValueDescriptionText, isStatic: method.isStatic ?? false }; return [method.name, formattedMethod]; })); const methods = Object.fromEntries(methodEntries); // Extract type parameter names const typeParameters = classType.typeParameters?.map(tp => tp.toString()); const raw = { name: classExport.name, description, descriptionText, constructorParameters, properties, methods, typeParameters }; // Post-process type strings to align naming across re-exports return rewriteTypeStringsDeep(raw, rewriteContext); } /** * Type guard to check if an export node is a public class. * * @param exportNode - The export node to check * @returns true if the export is a public class that should be documented */ export function isPublicClass(exportNode) { const isPublic = exportNode.documentation?.visibility !== 'private' && exportNode.documentation?.visibility !== 'internal'; const hasIgnoreTag = exportNode.documentation?.tags?.some(tag => tag.name === 'ignore'); return isClassType(exportNode.type) && !hasIgnoreTag && isPublic; }