import fs from "fs" ; import path from "path" ; const ERROR_CODES = { ENOENT : "ENOENT" , } ; const Files = { _format : "utf8" as BufferEncoding , write ( pathToFile , value , options = { recursive : true } ) { if ( options . recursive ) { const directoryPath = path . dirname ( pathToFile ) ; Files . mkdir ( directoryPath , { recursive : true } ) ; } if ( typeof value === "string" ) fs . writeFileSync ( pathToFile , value , Files . _format ) ; else fs . writeFileSync ( pathToFile , JSON . stringify ( value , null , 2 ) , Files . _format ) ; } , readString ( pathToFile ) { return fs . readFileSync ( pathToFile , { encoding : Files . _format } ) ; } , readJson ( pathToFile ) { return JSON . parse ( this . readString ( pathToFile ) ) as Record < string , unknown > ; } , safeReadJson ( pathToFile ) { try { return this . readJson ( pathToFile ) ; } catch ( e ) { return null ; } } , readFirstOf < V , O extends { [ key ] : unknown ; } > ( filePaths ) { return ( converter ) : ( { path : string ; value : V ; } & O ) | undefined => { return filePaths . reduce ( ( acc , filePath ) => { if ( acc ) return acc ; else { const pathWithOpts = typeof filePath === "string" ? { path : filePath } : filePath ; if ( this . exists ( pathWithOpts . path ) ) { const optsOrDefault = pathWithOpts . options || ( { } as O ) ; const test = { path : pathWithOpts . path , ... optsOrDefault , value : converter ( this . readString ( pathWithOpts . path ) ) , } ; return test ; } else return acc ; } } , undefined ) ; } ; } , isDirectory : ( source ) : boolean => fs . lstatSync ( source ) . isDirectory ( ) , isFile : ( source ) : boolean => fs . lstatSync ( source ) . isFile ( ) , readDirectory : ( source ) : string [ ] => fs . readdirSync ( source , { encoding : Files . _format } ) , mkdir : ( target , options ) : string | undefined => fs . mkdirSync ( target , options ) , exists ( pathToFile ) { try { return Boolean ( fs . lstatSync ( pathToFile ) ) ; } catch ( e ) { if ( ( e as { code : string ; } ) . code === ERROR_CODES . ENOENT ) return false ; throw e ; } } , append ( filePath , data ) { fs . appendFileSync ( filePath , data , { encoding : Files . _format } ) ; } , copy ( src , dest , options = { recursive : false } ) { if ( options . recursive ) { const directoryPath = path . dirname ( dest ) ; Files . mkdir ( directoryPath , { recursive : true } ) ; } fs . copyFileSync ( src , dest ) ; } , remove ( src ) { fs . unlinkSync ( src ) ; } , removeAll ( srcs ) { srcs . forEach ( ( src ) => Files . remove ( src ) ) ; } , flushDirectories ( directory , recursive = true ) { try { const paths = fs . readdirSync ( directory ) ; paths . forEach ( ( p ) => { const maybedir = path . join ( directory , p ) ; if ( this . isDirectory ( maybedir ) ) { fs . rmdirSync ( maybedir , { recursive } ) ; } } ) ; } catch ( e ) { } } , } ; export default Files ;