import fs from 'fs' ; import type { Stats } from 'fs' ; import path from 'path' ; import { promisify } from 'util' ; const fsStat = promisify ( fs . stat ) ; export type MoveOptions = { sourcePaths : Array < string > ; targetPath : string ; } ; export type PathMap = { [ x ] : string ; } ; export const DEFAULT = { parser : 'flow' , recast : { quote : 'single' } , } ; export const JS_EXTENSIONS = new Set ( [ 'js' , 'jsx' , 'mjs' , 'es' , 'es6' , 'ts' , 'tsx' , ] ) ; export const JS_EXTENSIONS_DOTTED = new Set ( [ ... Array . from ( JS_EXTENSIONS , ( ext ) => `.${ ext }` ) , ] ) ; async function gracefulFsStat ( _path ) { if ( _path == null ) { return null ; } try { return await fsStat ( _path ) ; } catch ( error ) { if ( error . code === 'ENOENT' ) { return null ; } throw error ; } } async function validateSourcePaths ( options ) { const { sourcePaths } = options ; await Promise . all ( sourcePaths . map ( ( sourcePath ) => ( { sourcePath , stat : gracefulFsStat ( sourcePath ) } ) ) . map ( async ( { sourcePath , stat } ) => { const sourceStat = await stat ; if ( ! sourceStat ) { throw new Error ( `Source "${ sourcePath }" doesn't exist.` ) ; } } ) ) ; } async function validateTargetPath ( options ) { const { sourcePaths , targetPath } = options ; const targetStat = await gracefulFsStat ( targetPath ) ; if ( sourcePaths . length === 1 ) { if ( targetStat && ! targetStat . isDirectory ( ) ) { throw new Error ( `Target "${ targetPath }" already exists.` ) ; } } else { if ( ! targetStat ) { throw new Error ( `Target "${ targetPath }" doesn't exists.` ) ; } if ( ! targetStat . isDirectory ( ) ) { throw new Error ( `Multiple source paths were provided but "${ targetPath }" is not a folder.` ) ; } } } export async function validate ( options ) { await Promise . all ( [ validateSourcePaths ( options ) , validateTargetPath ( options ) , ] ) ; return options ; } export async function createMovePaths ( options ) { const { sourcePaths , targetPath } = options ; const resolvedTargetPath = path . resolve ( targetPath ) ; const targetStat = await gracefulFsStat ( resolvedTargetPath ) ; const getTargetPath = targetStat && targetStat . isDirectory ( ) ? ( sourcePath ) => path . join ( resolvedTargetPath , path . basename ( sourcePath ) ) : ( ) => resolvedTargetPath ; return sourcePaths . reduce < { [ k ] : string ; } > ( ( acc , sourcePath ) => { acc [ path . resolve ( sourcePath ) ] = getTargetPath ( sourcePath ) ; return acc ; } , { } ) ; }