import chalk from 'chalk' ; import debugConstructor from 'debug' ; import fs from 'fs' ; import StreamZip from 'node-stream-zip' ; import oraConstructor from 'ora' ; import portfinder from 'portfinder' ; import shelljs from 'shelljs' ; import tmp from 'tmp' ; import upath from 'upath' ; import util from 'util' ; export const debug = debugConstructor ( 'vs-cli' ) ; export const cwd = upath . normalize ( process . cwd ( ) ) ; const ora = oraConstructor ( { color : 'blue' , spinner : 'circle' } ) ; export let beforeExitHandlers = [ ] ; const exitSignals = [ 'exit' , 'SIGINT' , 'SIGTERM' , 'SIGHUP' ] ; exitSignals . forEach ( ( sig ) => { process . on ( sig , ( code ) => { while ( beforeExitHandlers . length ) { try { beforeExitHandlers . shift ( ) ?. ( ) ; } catch ( e ) { } } process . exit ( code ) ; } ) ; } ) ; export function startLogging ( text ? ) { ora . start ( text ) ; } export function stopLogging ( text ? , symbol ? ) { if ( ! text ) { ora . stop ( ) ; return ; } ora . stopAndPersist ( { text , symbol } ) ; } export function log ( ... obj ) { console . log ( ... obj ) ; } export function logUpdate ( ... obj ) { ora . text = obj . join ( ' ' ) ; } export function logSuccess ( ... obj ) { ora . succeed ( obj . join ( ' ' ) ) ; } export function logError ( ... obj ) { ora . fail ( obj . join ( ' ' ) ) ; } export function logInfo ( ... obj ) { ora . info ( obj . join ( ' ' ) ) ; } export function gracefulError ( err ) { const message = err . stack ? err . stack . replace ( /^Error:/ , chalk . red . bold ( 'Error:' ) ) : `${ chalk . red . bold ( 'Error:' ) } ${ err . message }` ; if ( ora . isSpinning ) { ora . fail ( message ) ; } else { console . error ( message ) ; } console . log ( chalk . gray ( `
If you think this is a bug, please report at https://github.com/vivliostyle/vivliostyle-cli/issues` ) ) ; process . exit ( 1 ) ; } export function readJSON ( path ) { try { return JSON . parse ( fs . readFileSync ( path , 'utf8' ) ) ; } catch ( err ) { return undefined ; } } export async function statFile ( filePath ) { try { return util . promisify ( fs . stat ) ( filePath ) ; } catch ( err ) { if ( err . code === 'ENOENT' ) { throw new Error ( `Specified input doesn't exists: ${ filePath }` ) ; } throw err ; } } export async function inflateZip ( filePath , dest ) { return await new Promise < void > ( ( res , rej ) => { try { const zip = new StreamZip ( { file : filePath , storeEntries : true , } ) ; zip . on ( 'error' , ( err ) => { rej ( err ) ; } ) ; zip . on ( 'ready' , async ( ) => { await util . promisify ( zip . extract ) ( null , dest ) ; await util . promisify ( zip . close ) ( ) ; debug ( `Unzipped ${ filePath } to ${ dest }` ) ; res ( ) ; } ) ; } catch ( err ) { rej ( err ) ; } } ) ; } export function useTmpDirectory ( ) { return new Promise < [ string , ( ) => void ] > ( ( res , rej ) => { tmp . dir ( { unsafeCleanup : true } , ( err , path , clear ) => { if ( err ) { return rej ( err ) ; } debug ( `Created the temporary directory: ${ path }` ) ; const callback = ( ) => { shelljs . rm ( '-rf' , path ) ; debug ( `Removed the temporary directory: ${ path }` ) ; } ; beforeExitHandlers . push ( callback ) ; res ( [ path , callback ] ) ; } ) ; } ) ; } export async function touchTmpFile ( path ) { shelljs . touch ( path ) ; debug ( `Created the temporary file: ${ path }` ) ; const callback = ( ) => { shelljs . rm ( '-f' , path ) ; debug ( `Removed the temporary file: ${ path }` ) ; } ; beforeExitHandlers . push ( callback ) ; return callback ; } export function pathStartsWith ( path1 , path2 ) { const path1n = upath . normalize ( path1 ) . replace ( /\/?$/ , '/' ) ; const path2n = upath . normalize ( path2 ) . replace ( /\/?$/ , '/' ) ; return path1n . startsWith ( path2n ) ; } export function isUrlString ( str ) { return /^(https?|file|data):/i . test ( str ) ; } export function findAvailablePort ( ) { portfinder . basePort = 13000 ; return portfinder . getPortPromise ( ) ; }