/
githubmirror
/
gutenberg
Обзор
Документация
Войти
/
githubmirror
/
gutenberg
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
trunk
tools/docs/gen-components-docs/index.mjs
146 строк
4 KB
Marco Ciampini
ESLint: Replace strict config with bulk suppressions (#81248)
07 авг 2026, 14:34
Не верифицирован
07 авг 2026, 14:34
7f43eaf
Код
Авторство
О чём код?
import fs from 'node:fs/promises'; import path from 'path'; import { fileURLToPath } from 'node:url'; import docgen from 'react-docgen-typescript'; import glob from 'glob'; import { generateMarkdownDocs } from './markdown/index.mjs'; import { getDescriptionsForSubcomponents } from './get-subcomponent-descriptions.mjs'; import { getTagsFromStorybook } from './get-tags-from-storybook.mjs'; export const ROOT_DIR = path.resolve( path.dirname( fileURLToPath( import.meta.url ) ), '../../..' ); const MANIFEST_GLOB = path .join( ROOT_DIR, 'packages/components/src/**/docs-manifest.json' ) .replace( /\\/g, '/' ); /** * For consistency, options should generally match the options used in Storybook. * @type {import('react-docgen-typescript').ParserOptions} */ const OPTIONS = { shouldExtractLiteralValuesFromEnum: true, shouldRemoveUndefinedFromOptional: true, propFilter: ( prop ) => prop.parent ? ! /node_modules/.test( prop.parent.fileName ) : true, savePropValueAsString: true, }; function getTypeDocsForComponent( { manifestPath, componentFilePath, displayName, } ) { const resolvedPath = path.resolve( path.dirname( manifestPath ), componentFilePath ); const typeDocs = docgen.parse( resolvedPath, OPTIONS ); if ( typeDocs.length === 0 ) { throw new Error( `react-docgen-typescript could not generate any type docs from ${ resolvedPath }` ); } const matchingTypeDoc = typeDocs.find( ( obj ) => obj.displayName === displayName ); if ( typeof matchingTypeDoc === 'undefined' ) { const unmatchedTypeDocs = typeDocs .map( ( obj ) => `\`${ obj.displayName }\`` ) .join( ', ' ); throw new Error( `react-docgen-typescript could not find type docs for ${ displayName } in ${ resolvedPath }. (Found ${ unmatchedTypeDocs })` ); } return matchingTypeDoc; } async function parseManifest( manifestPath ) { try { return JSON.parse( await fs.readFile( manifestPath, 'utf8' ) ); } catch ( e ) { throw new Error( `Error parsing docs manifest at ${ manifestPath }: ${ e.message }` ); } } const manifests = glob.sync( MANIFEST_GLOB ); await Promise.all( manifests.map( async ( manifestPath ) => { const manifest = await parseManifest( manifestPath ); const typeDocs = getTypeDocsForComponent( { manifestPath, componentFilePath: manifest.filePath, displayName: manifest.displayName, } ); let subcomponentDescriptions; const subcomponentTypeDocs = await Promise.all( manifest.subcomponents?.map( async ( subcomponent ) => { const docs = getTypeDocsForComponent( { manifestPath, componentFilePath: subcomponent.filePath, displayName: subcomponent.displayName, } ); if ( subcomponent.preferredDisplayName ) { docs.displayName = subcomponent.preferredDisplayName; } if ( ! subcomponent.description ) { subcomponentDescriptions ??= getDescriptionsForSubcomponents( path.resolve( path.dirname( manifestPath ), manifest.filePath ), manifest.displayName ); docs.description = ( await subcomponentDescriptions )?.[ subcomponent.displayName ]; } return docs; } ) ?? [] ); const tags = await getTagsFromStorybook( path.resolve( path.dirname( manifestPath ), 'stories/index.story.tsx' ) ); const docs = generateMarkdownDocs( { typeDocs, subcomponentTypeDocs, tags, } ); const outputFile = path.resolve( path.dirname( manifestPath ), './README.md' ); try { console.log( `Writing docs to ${ outputFile }` ); return fs.writeFile( outputFile, docs ); } catch ( e ) { throw new Error( `Error writing docs to ${ outputFile }: ${ e.message }` ); } } ) );