import type * as d from '../../../declarations' ; import { basename , resolve } from 'path' ; import { isRemoteUrl , isString , normalizePath , noop } from '@utils' ; import { fetchUrlSync } from '../fetch/fetch-module-sync' ; import { getCurrentDirectory , IS_CASE_SENSITIVE_FILE_NAMES , IS_WEB_WORKER_ENV } from '../environment' ; import { patchTypeScriptResolveModule } from './typescript-resolve-module' ; import ts from 'typescript' ; export const patchTsSystemFileSystem = ( config , stencilSys , inMemoryFs , tsSys ) => { const realpath = ( path ) => { const rp = stencilSys . realpathSync ( path ) ; if ( isString ( rp ) ) { return rp ; } return path ; } ; const getAccessibleFileSystemEntries = ( path ) => { try { const entries = stencilSys . readDirSync ( path || '.' ) . sort ( ) ; const files = [ ] ; const directories = [ ] ; for ( const absPath of entries ) { const stat = inMemoryFs . statSync ( absPath ) ; if ( ! stat ) { continue ; } const entry = basename ( absPath ) ; if ( stat . isFile ) { files . push ( entry ) ; } else if ( stat . isDirectory ) { directories . push ( entry ) ; } } return { files , directories } ; } catch ( e ) { return { files : [ ] , directories : [ ] } ; } } ; tsSys . createDirectory = ( p ) => { stencilSys . createDirSync ( p , { recursive : true } ) ; } ; tsSys . directoryExists = ( p ) => { const s = inMemoryFs . statSync ( p ) ; return s . isDirectory ; } ; tsSys . exit = stencilSys . exit ; tsSys . fileExists = ( p ) => { let filePath = p ; if ( isRemoteUrl ( p ) ) { filePath = getTypescriptPathFromUrl ( config , tsSys . getExecutingFilePath ( ) , p ) ; } const s = inMemoryFs . statSync ( filePath ) ; return ! ! ( s && s . isFile ) ; } ; tsSys . getCurrentDirectory = stencilSys . getCurrentDirectory ; tsSys . getExecutingFilePath = stencilSys . getCompilerExecutingPath ; tsSys . getDirectories = ( p ) => { const items = stencilSys . readDirSync ( p ) ; return items . filter ( ( itemPath ) => { const s = inMemoryFs . statSync ( itemPath ) ; return ! ! ( s && s . exists && s . isDirectory ) ; } ) ; } ; tsSys . readDirectory = ( path , extensions , exclude , include , depth ) => { const cwd = stencilSys . getCurrentDirectory ( ) ; return ( ts as any ) . matchFiles ( path , extensions , exclude , include , IS_CASE_SENSITIVE_FILE_NAMES , cwd , depth , getAccessibleFileSystemEntries , realpath ) ; } ; tsSys . readFile = ( p ) => { let filePath = p ; const isUrl = isRemoteUrl ( p ) ; if ( isUrl ) { filePath = getTypescriptPathFromUrl ( config , tsSys . getExecutingFilePath ( ) , p ) ; } let content = inMemoryFs . readFileSync ( filePath , { useCache : isUrl } ) ; if ( typeof content !== 'string' && isUrl ) { if ( IS_WEB_WORKER_ENV ) { content = fetchUrlSync ( p ) ; if ( typeof content === 'string' ) { inMemoryFs . writeFile ( filePath , content ) ; } } else { config . logger . error ( `ts.sys can only request http resources from within a web worker: ${ p }` ) ; } } return content ; } ; tsSys . writeFile = ( p , data ) => inMemoryFs . writeFile ( p , data ) ; return tsSys ; } ; const patchTsSystemWatch = ( stencilSys , tsSys ) => { tsSys . watchDirectory = ( p , cb , recursive ) => { const watcher = stencilSys . watchDirectory ( p , ( filePath ) => { cb ( filePath ) ; } , recursive ) ; return { close ( ) { watcher . close ( ) ; } , } ; } ; tsSys . watchFile = ( p , cb ) => { const watcher = stencilSys . watchFile ( p , ( filePath , eventKind ) => { if ( eventKind === 'fileAdd' ) { cb ( filePath , ts . FileWatcherEventKind . Created ) ; } else if ( eventKind === 'fileUpdate' ) { cb ( filePath , ts . FileWatcherEventKind . Changed ) ; } else if ( eventKind === 'fileDelete' ) { cb ( filePath , ts . FileWatcherEventKind . Deleted ) ; } } ) ; return { close ( ) { watcher . close ( ) ; } , } ; } ; } ; export const patchTypescript = ( config , inMemoryFs ) => { if ( ! ( ts as any ) . __patched ) { if ( config . sys ) { patchTsSystemFileSystem ( config , config . sys , inMemoryFs , ts . sys ) ; patchTsSystemWatch ( config . sys , ts . sys ) ; } patchTypeScriptResolveModule ( config , inMemoryFs ) ; patchTypeScriptGetParsedCommandLineOfConfigFile ( ) ; ( ts as any ) . __patched = true ; } } ; const patchTypeScriptSysMinimum = ( ) => { if ( ! ts . sys ) { ts . sys = { args : [ ] , createDirectory : noop , directoryExists : ( ) => false , exit : noop , fileExists : ( ) => false , getCurrentDirectory , getDirectories : ( ) => [ ] , getExecutingFilePath : ( ) => './' , readDirectory : ( ) => [ ] , readFile : noop , newLine : '\n' , resolvePath : resolve , useCaseSensitiveFileNames : false , write : noop , writeFile : noop , } ; } } ; patchTypeScriptSysMinimum ( ) ; export const getTypescriptPathFromUrl = ( config , tsExecutingUrl , url ) => { const tsBaseUrl = new URL ( '..' , tsExecutingUrl ) . href ; if ( url . startsWith ( tsBaseUrl ) ) { const tsFilePath = url . replace ( tsBaseUrl , '/' ) ; const tsNodePath = config . sys . getLocalModulePath ( { rootDir : config . rootDir , moduleId : '@stencil/core' , path : tsFilePath , } ) ; return normalizePath ( tsNodePath ) ; } return url ; } ; export const patchTypeScriptGetParsedCommandLineOfConfigFile = ( ) => { const orgGetParsedCommandLineOfConfigFile = ts . getParsedCommandLineOfConfigFile ; ts . getParsedCommandLineOfConfigFile = ( configFileName , optionsToExtend , host , extendedConfigCache ) => { const results = orgGetParsedCommandLineOfConfigFile ( configFileName , optionsToExtend , host , extendedConfigCache ) ; results . fileNames = results . fileNames . filter ( ( f ) => { if ( f . includes ( '.e2e.' ) || f . includes ( '/e2e.' ) ) { return false ; } if ( f . includes ( '.spec.' ) || f . includes ( '/spec.' ) ) { return false ; } return true ; } ) ; return results ; } ; } ;