import * as fs from "fs" ; import { posix as path } from "path" ; export type SupportModuleType = "browser" | "node" | "require" | "import" | "default" ; export type SupportModule = { [ P in SupportModuleType ] ? : string ; } ; export interface Option { directory : Partial < SupportModule > ; } export interface ExportsField { [ filepath ] : SupportModule ; } const isFile = ( p ) => { return fs . existsSync ( p ) && fs . statSync ( p ) . isFile ( ) ; } ; const isTypeScriptFile = ( p ) : boolean => { return ! ! p . match ( /tsx?$/ ) ; } ; const isIndexFile = ( p ) => { return ! ! p . match ( /index\.tsx?$/ ) ; } ; const convertNameTsToJs = ( p ) : string => { return p . replace ( /\.tsx?$/ , ".js" ) ; } ; const isSupportModuleType = ( text ) : text is SupportModuleType => { if ( ! text ) { return false ; } return [ "node" , "browser" , "require" , "import" , "default" ] . includes ( text ) ; } ; const trimExtension = ( p ) : string => { const ext = path . extname ( p ) ; return p . replace ( new RegExp ( ext + "$" ) , "" ) ; } ; export const generateExportsField = ( sourceRootDirectory , option ) : ExportsField => { const pathArray = fs . readdirSync ( sourceRootDirectory ) ; const filteredPathArray = pathArray . filter ( p => { const pathName = path . join ( sourceRootDirectory , p ) ; return isTypeScriptFile ( pathName ) && isFile ( pathName ) ; } ) ; return filteredPathArray . reduce < ExportsField > ( ( exportsFields , pathName ) => { const filepath = isIndexFile ( pathName ) ? "." : "./" + trimExtension ( pathName ) ; const jsFilename = convertNameTsToJs ( pathName ) ; const supportModule = { } ; Object . entries ( option . directory ) . forEach ( ( [ key , exportBaseDirectory ] ) => { if ( isSupportModuleType ( key ) && typeof exportBaseDirectory === "string" ) { supportModule [ key ] = "./" + path . join ( exportBaseDirectory , jsFilename ) ; } } ) ; return { ... exportsFields , [ filepath ] : supportModule } ; } , { } ) ; } ;