import * as ts from 'typescript' ; import { ENUM_NODE_KINDS , TYPE_OR_INTERFACE_NODE_KINDS } from './kinds' ; import { ExtraCommandLineOptions , LocationInFile } from '../types' ; import { FromWhat , STAR , getFrom } from './common' ; const extractAliasFirstFromElements = ( elements ) : string [ ] => elements . map ( ( e ) => e . name . text ) ; const extractPropertyOrAliasFirstFromElements = ( elements ) : string [ ] => elements . map ( ( e ) => ( e . propertyName || e . name ) . text ) ; const extractFromBindingsWith = ( bindings , extract ) : string [ ] => { if ( ts . isNamedExports ( bindings ) ) return extract ( bindings . elements ) ; return [ bindings . name . text ] ; } ; const extractAliasFirstFromBindings = ( bindings ) : string [ ] => { return extractFromBindingsWith ( bindings , extractAliasFirstFromElements ) ; } ; const extractPropertyOrAliasFromBindings = ( bindings ) : string [ ] => { return extractFromBindingsWith ( bindings , extractPropertyOrAliasFirstFromElements ) ; } ; export const extractExportStatement = ( decl ) : string [ ] => { return decl . exportClause ? extractAliasFirstFromBindings ( decl . exportClause ) : [ ] ; } ; export const extractExportFromImport = ( decl , moduleSpecifier ) : { exported : FromWhat ; imported : FromWhat ; } => { const { exportClause } = decl ; const whatExported = exportClause ? extractAliasFirstFromBindings ( exportClause ) : STAR ; const whatImported = exportClause ? extractPropertyOrAliasFromBindings ( exportClause ) : STAR ; return { exported : { from : getFrom ( moduleSpecifier ) , what : whatExported , } , imported : { from : getFrom ( moduleSpecifier ) , what : whatImported , isExportStarAs : exportClause ?. kind === ts . SyntaxKind . NamespaceExport , } , } ; } ; const parseExportNames = ( exportName ) : string [ ] => { if ( exportName . startsWith ( '{' ) ) { const names = exportName . substring ( 1 , exportName . length - 2 ) ; return names . split ( ',' ) . map ( ( n ) => ( n . includes ( ':' ) ? n . split ( ':' ) [ 1 ] : n ) ) . map ( ( n ) => n . trim ( ) ) ; } return [ exportName ] ; } ; export const extractExportNames = ( path , node ) : string [ ] => { switch ( node . kind ) { case ts . SyntaxKind . VariableStatement : return parseExportNames ( ( node as ts . VariableStatement ) . declarationList . declarations [ 0 ] . name . getText ( ) ) ; case ts . SyntaxKind . FunctionDeclaration : const { name } = node as ts . FunctionDeclaration ; return [ name ? name . text : 'default' ] ; default : { console . warn ( `WARN: ${ path }: unknown export node (kind:${ node . kind })` ) ; return [ '' ] ; } } } ; const shouldNodeTypeBeIgnored = ( node , extraOptions ? ) : boolean => { const allowUnusedTypes = ! ! extraOptions ?. allowUnusedTypes ; const allowUnusedEnums = ! ! extraOptions ?. allowUnusedEnums ; if ( allowUnusedTypes && allowUnusedEnums ) return ( TYPE_OR_INTERFACE_NODE_KINDS . includes ( node . kind ) || ENUM_NODE_KINDS . includes ( node . kind ) ) ; if ( allowUnusedTypes ) return TYPE_OR_INTERFACE_NODE_KINDS . includes ( node . kind ) ; if ( allowUnusedEnums ) return ENUM_NODE_KINDS . includes ( node . kind ) ; return false ; } ; export const addExportCore = ( exportName , file , node , exportLocations , exports , extraOptions ? ) : void => { if ( exports . includes ( exportName ) || shouldNodeTypeBeIgnored ( node , extraOptions ) ) { return ; } exports . push ( exportName ) ; const location = file . getLineAndCharacterOfPosition ( node . getStart ( ) ) ; exportLocations . push ( { line : location . line + 1 , character : location . character , } ) ; } ;