import { isFileModuleRef , isPackageModuleRef , parseModuleRef , } from "@rnx-kit/tools-node" ; import path from "path" ; import ts from "typescript" ; import { ExtensionsJavaScript , ExtensionsJSON , ExtensionsTypeScript , } from "./extension" ; import { changeModuleResolutionHostToLogFileSystemReads , logModuleBegin , logModuleEnd , ResolverLog , ResolverLogMode , } from "./log" ; import { createReactNativePackageNameReplacer } from "./react-native-package-name" ; import { resolveFileModule , resolvePackageModule } from "./resolve" ; import type { ResolverContext , ModuleResolutionHostLike } from "./types" ; param host param options param platform param platformExtensionNames param disableReactNativePackageSubstitution param traceReactNativeModuleResolutionErrors param traceResolutionLog export function changeHostToUseReactNativeResolver ( { host , options , platform , platformExtensionNames , disableReactNativePackageSubstitution , traceReactNativeModuleResolutionErrors , traceResolutionLog , } ) { host . directoryExists = host . directoryExists ?? ts . sys . directoryExists ; host . realpath = host . realpath ?? ts . sys . realpath ; host . getDirectories = host . getDirectories ?? ts . sys . getDirectories ; let mode = ResolverLogMode . Never ; if ( options . traceResolution ) { mode = ResolverLogMode . Always ; } else if ( traceReactNativeModuleResolutionErrors ) { mode = ResolverLogMode . OnFailure ; } const log = new ResolverLog ( mode , traceResolutionLog ) ; if ( mode !== ResolverLogMode . Never ) { host . trace = log . log . bind ( log ) ; changeModuleResolutionHostToLogFileSystemReads ( host as ModuleResolutionHostLike ) ; } const context = { host : host as ModuleResolutionHostLike , options , disableReactNativePackageSubstitution , log , platform , platformExtensions : [ platform , ... ( platformExtensionNames || [ ] ) ] . map ( ( e ) => `.${ e }` ) , replaceReactNativePackageName : createReactNativePackageNameReplacer ( host . getCurrentDirectory ( ) , platform , disableReactNativePackageSubstitution , log ) } ; host . resolveModuleNames = resolveModuleNames . bind ( undefined , context ) ; host . resolveTypeReferenceDirectives = resolveTypeReferenceDirectives . bind ( undefined , context ) ; } param context param moduleName param containingFile param extensions returns export function resolveModuleName ( context , moduleName , containingFile , extensions ) { let module = undefined ; const moduleRef = parseModuleRef ( moduleName ) ; const searchDir = path . dirname ( containingFile ) ; if ( isPackageModuleRef ( moduleRef ) ) { module = resolvePackageModule ( context , moduleRef , searchDir , extensions ) ; } else if ( isFileModuleRef ( moduleRef ) ) { module = resolveFileModule ( context , moduleRef , searchDir , extensions ) ; } if ( module ) { module . isExternalLibraryImport = /[/\\]node_modules[/\\]/ . test ( module . resolvedFileName ) ; const { host , options } = context ; if ( host . realpath && ! options . preserveSymlinks ) { const resolvedFileName = host . realpath ( module . resolvedFileName ) ; const originalPath = resolvedFileName === module . resolvedFileName ? undefined : module . resolvedFileName ; Object . assign ( module , { resolvedFileName , originalPath } ) ; } } return module ; } param context param moduleNames param containingFile returns export function resolveModuleNames ( context , moduleNames , containingFile , _reusedNames , _redirectedReference ? ) { const { options , log , replaceReactNativePackageName } = context ; const resolutions = [ ] ; for ( const moduleName of moduleNames ) { logModuleBegin ( log , moduleName , containingFile ) ; const finalModuleName = replaceReactNativePackageName ( moduleName ) ; log . log ( "Searching for module '%s' with target file type 'TypeScript'" , finalModuleName ) ; let module = resolveModuleName ( context , finalModuleName , containingFile , ExtensionsTypeScript ) ; if ( ! module ) { log . log ( "Searching for module '%s' with target file type 'JavaScript'" , finalModuleName ) ; module = resolveModuleName ( context , finalModuleName , containingFile , ExtensionsJavaScript ) ; if ( ! module && options . resolveJsonModule ) { log . log ( "Searching for module '%s' with target file type 'JSON'" , finalModuleName ) ; module = resolveModuleName ( context , finalModuleName , containingFile , ExtensionsJSON ) ; } } resolutions . push ( module ) ; logModuleEnd ( log , options , moduleName , module ) ; } return resolutions ; } param context param typeDirectiveNames param containingFile param redirectedReference returns export function resolveTypeReferenceDirectives ( context , typeDirectiveNames , containingFile , redirectedReference ? ) { const { host , options , log } = context ; const resolutions = [ ] ; for ( const typeDirectiveName of typeDirectiveNames ) { if ( options . traceResolution ) { log . begin ( ) ; } const { resolvedTypeReferenceDirective : directive } = ts . resolveTypeReferenceDirective ( typeDirectiveName , containingFile , options , host , redirectedReference ) ; resolutions . push ( directive ) ; if ( options . traceResolution ) { if ( directive ) { log . endSuccess ( ) ; } else { log . endFailure ( ) ; } } } return resolutions ; }