import path from "path" ; import { FatalError } from "../../errors" ; import normalizePath from "normalize-path" ; import { EmittedDeclarationOutput , getDeclarationsForFile , getDiagnosticsHost , getProgram , loadTypeScript , } from "./common" ; export async function getDeclarations ( dirname , pkgName , projectDir , entrypoints ) { const typescript = loadTypeScript ( dirname , projectDir , pkgName ) ; const { program , options } = await getProgram ( dirname , pkgName , typescript ) ; let moduleResolutionCache = typescript . createModuleResolutionCache ( dirname , ( x ) => x , options ) ; let normalizedDirname = normalizePath ( dirname ) ; let resolvedEntrypointPaths = entrypoints . map ( ( x ) => { let { resolvedModule } = typescript . resolveModuleName ( path . join ( path . dirname ( x ) , path . basename ( x , path . extname ( x ) ) ) , dirname , options , typescript . sys , moduleResolutionCache ) ; if ( ! resolvedModule ) { throw new Error ( "This is an internal error, please open an issue if you see this: ts could not resolve module" ) ; } return resolvedModule . resolvedFileName ; } ) ; let allDeps = new Set < string > ( resolvedEntrypointPaths ) ; function searchDeps ( deps ) { for ( let dep of deps ) { let sourceFile = program ! . getSourceFile ( dep ) ; if ( ! sourceFile ) { throw new FatalError ( `Could not generate type declarations because ${ dep } is not in a TypeScript project. Make sure this file is included in your tsconfig.` , pkgName ) ; } let internalDeps = new Set < string > ( ) ; for ( let { text } of ( sourceFile as any ) . imports ) { let { resolvedModule } = typescript . resolveModuleName ( text , dep , options , typescript . sys , moduleResolutionCache ) ; if ( resolvedModule ) { if ( ! allDeps . has ( resolvedModule . resolvedFileName ) && ! resolvedModule . isExternalLibraryImport && resolvedModule . resolvedFileName . includes ( normalizedDirname ) && ! resolvedModule . resolvedFileName . endsWith ( ".json" ) ) { internalDeps . add ( resolvedModule . resolvedFileName ) ; allDeps . add ( resolvedModule . resolvedFileName ) ; } } } searchDeps ( internalDeps ) ; } } searchDeps ( new Set ( resolvedEntrypointPaths ) ) ; const diagnosticsHost = getDiagnosticsHost ( typescript , projectDir ) ; return Promise . all ( [ ... allDeps ] . map ( ( filename ) => { return getDeclarationsForFile ( filename , typescript , program , normalizedDirname , projectDir , diagnosticsHost ) ; } ) ) ; }