@futagoza/publish-package
Version:
A 'npm/yarn publish' wrapper with my preferred defaults.
127 lines (76 loc) • 3.9 kB
JavaScript
;
const { existsSync } = require( "fs" );
const { join } = require( "path" );
const { exec, run } = require( "@futagoza/child-process" );
const buildArgv = require( "./lib/buildArgv" );
const generateCommand = require( "./lib/generateCommand" );
const reject = require( "./lib/reject" );
/**
* Will publish the Node package in the given folder via NPM or Yarn.
*
* _NOTE:_ Returns a rejected promise if no `package.json` is found.
*
* @param {String} [path] The package directory.
* @param {{}} [options] Options to pass to the publishing too;
*/
function publish( path, options = {} ) {
if ( typeof path !== "string" ) {
options = typeof path === "object" ? path : {};
path = options.path || options.folder || options.dir || false;
}
options = Object.assign( {}, options );
const log = typeof options.log === "function" ? options.log : () => void 0;
if ( ! path ) return reject( new Error( "No path specified to publish" ) );
if ( ! existsSync( join( path, "package.json" ) ) ) {
return reject( new Error( "A package.json was not found at " + path ), { path } );
}
if ( options.access ) {
if ( options.restricted )
return reject( new Error( `The options "access" and "restricted" cant be used together` ) );
if ( options.private )
return reject( new Error( `The options "access" and "private" cant be used together` ) );
if ( options.public )
return reject( new Error( `The options "access" and "public" cant be used together` ) );
if ( options.scoped )
return reject( new Error( `The options "access" and "scoped" cant be used together` ) );
} else if ( options.public || options.scoped ) {
const access = options.public ? "public" : "scoped";
if ( options.restricted )
return reject( new Error( `The options "${ access }" and "restricted" cant be used together` ) );
if ( options.private )
return reject( new Error( `The options "${ access }" and "private" cant be used together` ) );
} else if ( options.restricted || options.private ) {
const access = options.restricted ? "restricted" : "private";
if ( options.public )
return reject( new Error( `The options "${ access }" and "public" cant be used together` ) );
if ( options.scoped )
return reject( new Error( `The options "${ access }" and "scoped" cant be used together` ) );
} else {
options.access = "public";
}
if ( ! options.yarn && ! options.registry ) options.registry = "https://registry.npmjs.org/";
const command = generateCommand( options );
const args = buildArgv( options );
const runOpts = { cwd: path };
if ( typeof options.runOpts === "object" ) Object.assign( runOpts, options.runOpts );
log( path, command, args, runOpts );
if ( ! options.checkVersion ) return run( command, args, runOpts );
const { name, version } = require( join( path, "package.json" ) );
return exec( `npm view ${ name } version`, runOpts )
.then( ( { stdout } ) => {
// Existing package has a newer local version?
if ( version === stdout.trim() ) {
log( `${ name } ${ version } already exists.` );
return Promise.resolve();
}
return run( command, args, runOpts );
} )
.catch( error => {
if ( typeof error !== "object" ) return Promise.reject( error );
if ( typeof error.stderr !== "string" ) return Promise.reject( error );
// Does this local package exist on the NPM registry?
if ( ! error.stderr.includes( "404" ) ) return Promise.reject( error );
return run( command, args, runOpts );
} );
}
module.exports = publish;