import { IPackageJSONService , IPackageFile } from './types' ; import * as fs from 'fs' ; import { promisify } from './util' ; import detectIndent from 'detect-indent' ; const statAsync = promisify ( fs . stat ) ; const readFileAsync = promisify ( fs . readFile ) ; const writeFileAsync = promisify ( fs . writeFile ) ; export function createPackageJSONFileService ( ) { return { readPackageFile : async ( filePath ) => { const contents = await readFileContents ( filePath ) ; return JSON . parse ( contents ) as IPackageFile ; } , writePackageFile : async ( filePath , fileContent ) => { const contents = await readFileContents ( filePath ) ; const { indent } = detectIndent ( contents ) ; const trailingNewline = contents . length ? contents [ contents . length - 1 ] === '\n' : false ; const data = JSON . stringify ( fileContent , null , indent || '  ' ) ; await writeFileAsync ( filePath , data + ( trailingNewline ? '\n' : '' ) ) ; } , } ; } async function readFileContents ( filePath ) { await assertFile ( filePath ) ; return readFileAsync ( filePath , 'utf-8' ) . then ( ( x ) => x . toString ( ) ) ; } async function assertFile ( filePath ) { if ( ! ( await existsAsync ( filePath ) ) ) { throw new Error ( `${ filePath } does not exist.` ) ; } } async function existsAsync ( filePath ) { return statAsync ( filePath ) . then ( ( ) => true ) . catch ( ( err ) => { if ( err . code === 'ENOENT' ) { return false ; } throw err ; } ) ; }