11// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
22// SPDX-License-Identifier: Apache-2.0
3+ import fs from 'node:fs' ;
34import { pascalCase } from 'change-case' ;
45import pathe from 'pathe' ;
56import { matcher } from 'micromatch' ;
@@ -21,46 +22,65 @@ export interface DocumenterOptions {
2122 extraExports ?: Record < string , Array < string > > ;
2223}
2324
25+ export interface WriteOptions {
26+ outDir : string ;
27+ }
28+
29+ export function writeComponentsDocumentation ( { outDir, ...options } : WriteOptions & DocumenterOptions ) : void {
30+ const definitions = documentComponents ( options ) ;
31+ fs . mkdirSync ( outDir , { recursive : true } ) ;
32+ for ( const definition of definitions ) {
33+ fs . writeFileSync (
34+ pathe . join ( outDir , definition . dashCaseName + '.js' ) ,
35+ `module.exports = ${ JSON . stringify ( definition , null , 2 ) } ;`
36+ ) ;
37+ }
38+ const indexContent = `module.exports = {
39+ ${ definitions
40+ . map ( definition => `${ JSON . stringify ( definition . dashCaseName ) } :require('./${ definition . dashCaseName } ')` )
41+ . join ( ',\n' ) }
42+ }` ;
43+ fs . writeFileSync ( pathe . join ( outDir , 'index.js' ) , indexContent ) ;
44+ fs . copyFileSync ( require . resolve ( './interfaces.d.ts' ) , pathe . join ( outDir , 'interfaces.d.ts' ) ) ;
45+ fs . writeFileSync (
46+ pathe . join ( outDir , 'index.d.ts' ) ,
47+ `import { ComponentDefinition } from './interfaces';
48+ const definitions: Record<string, ComponentDefinition>;
49+ export default definitions;
50+ `
51+ ) ;
52+ }
53+
2454export function documentComponents ( options : DocumenterOptions ) : Array < ComponentDefinition > {
2555 const program = bootstrapTypescriptProject ( options . tsconfigPath ) ;
2656 const checker = program . getTypeChecker ( ) ;
2757
2858 const isMatch = matcher ( pathe . resolve ( options . publicFilesGlob ) ) ;
2959
30- return program
31- . getSourceFiles ( )
32- . filter ( file => isMatch ( file . fileName ) )
33- . map ( sourceFile => {
34- const moduleSymbol = checker . getSymbolAtLocation ( sourceFile ) ;
35- const { name, dashCaseName } = componentNameFromPath ( sourceFile . fileName ) ;
60+ const sourceFiles = program . getSourceFiles ( ) . filter ( file => isMatch ( file . fileName ) ) ;
61+
62+ if ( sourceFiles . length === 0 ) {
63+ throw new Error ( `No files found matching ${ options . publicFilesGlob } ` ) ;
64+ }
65+
66+ return sourceFiles . map ( sourceFile => {
67+ const moduleSymbol = checker . getSymbolAtLocation ( sourceFile ) ;
68+ const { name, dashCaseName } = componentNameFromPath ( sourceFile . fileName ) ;
3669
37- // istanbul ignore next
38- if ( ! moduleSymbol ) {
39- throw new Error ( `Unable to resolve module: ${ sourceFile . fileName } ` ) ;
40- }
41- const exportSymbols = checker . getExportsOfModule ( moduleSymbol ) ;
42- const { propsSymbol, componentSymbol } = extractExports (
43- name ,
44- exportSymbols ,
45- checker ,
46- options ?. extraExports ?? { }
47- ) ;
48- const props = extractProps ( propsSymbol , checker ) ;
49- const functions = extractFunctions ( propsSymbol , checker ) ;
50- const defaultValues = extractDefaultValues ( componentSymbol , checker ) ;
51- const componentDescription = getDescription (
52- componentSymbol . getDocumentationComment ( checker ) ,
53- extractDeclaration ( componentSymbol )
54- ) ;
70+ // istanbul ignore next
71+ if ( ! moduleSymbol ) {
72+ throw new Error ( `Unable to resolve module: ${ sourceFile . fileName } ` ) ;
73+ }
74+ const exportSymbols = checker . getExportsOfModule ( moduleSymbol ) ;
75+ const { propsSymbol, componentSymbol } = extractExports ( name , exportSymbols , checker , options ?. extraExports ?? { } ) ;
76+ const props = extractProps ( propsSymbol , checker ) ;
77+ const functions = extractFunctions ( propsSymbol , checker ) ;
78+ const defaultValues = extractDefaultValues ( componentSymbol , checker ) ;
79+ const componentDescription = getDescription (
80+ componentSymbol . getDocumentationComment ( checker ) ,
81+ extractDeclaration ( componentSymbol )
82+ ) ;
5583
56- return buildComponentDefinition (
57- name ,
58- dashCaseName ,
59- props ,
60- functions ,
61- defaultValues ,
62- componentDescription ,
63- checker
64- ) ;
65- } ) ;
84+ return buildComponentDefinition ( name , dashCaseName , props , functions , defaultValues , componentDescription , checker ) ;
85+ } ) ;
6686}
0 commit comments