Giter VIP home page Giter VIP logo

npm-programmatic's Introduction

npm-programmatic Build Status

NPM

npm-programmatic is a library that allows you to access npm commands programmatically from javascript

Usage

Every function returns a Bluebird promise.
CWD refers to current working directory, allowing you to ensure the command executes in a certain folder in the filesystem. If output is set, the output of npm will be shown in the console.

Installation of Packages

    npm.install(packages, opts).then(function)
Name Type Value
packages Array packages to be installed
opts Object save:true/false; global:true/false; cwd:string; saveDev:true/false; noOptional:true/false; legacyBundling: true/false; output:true/false

Example

    var npm = require('npm-programmatic');
    npm.install(['left-pad'], {
        cwd:'/path/to/my/project',
        save:true
    })
    .then(function(){
        console.log("SUCCESS!!!");
    })
    .catch(function(){
        console.log("Unable to install package");
    });

Unistallation of Packages

    npm.uninstall(packages, opts).then(function)
Name Type Value
packages Array packages to be uninstalled
opts Object save:true/false; global:true/false; cwd:string; saveDev:true/false; output:true/false

Example

    var npm = require('npm-programmatic');
    npm.uninstall(['left-pad'], {
        cwd:'/path/to/my/project',
        save:true
    })
    .then(function(){
        console.log("SUCCESS!!!");
    })
    .catch(function(){
        console.log("Unable to uninstall package");
    });

List Installed Packages

    npm.list(path).then(function)
Name Type Value
path String path at which to look

Example

    var npm = require('npm-programmatic');
    npm.list('/path/to/project')
    .then(function(arrayOfPackages){
        console.log(arrayOfPackages);
    })
    .catch(function(){
        console.log("Unable to uninstall package");
    });

Tests

install mocha and dev dependencies. Then run npm test

npm-programmatic's People

Contributors

chalkpe avatar donothingloop avatar huan avatar kevnz avatar manak avatar vincelwt avatar wei3hua2 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

npm-programmatic's Issues

Support for more (or arbitrary) install options

There are cases where some flags have to be specified to the install command that are not supported.
For example this might be --no-optional to skip optional dependencies or --legacy-bundling to enable alternative bundling on newer npm versions.

The current approach which only allows a very few options seems outdated to me as npm itself evolves.

A solution would be to let the user specify the options in a parameter array or map. Of course the caller of the install function must take care of the npm version that is called and the options supported. Therefore it would also be great to have a getVersion() function which would return the version of the called npm.

Specify package.json?

Would it be possible to specify the directory that the package.json resides in? I want run a node.js process that installs npm packages into a specific package.json. (Would it also be possible to optionally not actually install it? and just add it to the npm package.json file too)

Does that make sense? ๐Ÿ“ฆ

EDIT:

I actually didn't see the cwd option. My bad. But would it still be possible to optionally install the package? as in just save it to the package.json file?

Unnecessary check for an empty string

if(stderr == ""){
if (stderr.indexOf("missing")== -1 && stderr.indexOf("required") == -1) {

stderr has been verified to be an empty string already, so why the code checks "missing" or "required" in the empty string again? what is the purpose of it? was it a mistake?

Publish v0.12 to include the latest PR codes

Today I found that the v0.11 does not include the latest --no-save PR.

โ”Œ [email protected]:~/chatie/wechaty/node_modules/npm-programmatic [00:33:25] tty:[ttys003] jobs:[0]
โ”” {master} $ grep version package.json 
  "version": "0.0.11"

โ”Œ [email protected]:~/chatie/wechaty/node_modules/npm-programmatic [00:35:53] tty:[ttys003] jobs:[0]
โ”” {master} $ grep -- '--save' index.js 
		+ (opts.save   ? " --save":"")

Please bumper the version to v0.12 and publish, thank you very much.

`list()` fails with ES6 when looking for global packages

I have a setup where I use ES6 in Node scripts by leveraging the esm package.esm recommends that it should not be installed globally. So when I try to use list() [no parameters] to list globally installed packages, I get the error:

Error: Cannot find module 'esm'
Require stack:
- internal/preload
    at Function.Module._resolveFilename (node:internal/modules/cjs/loader:925:15)
    at Function.Module._load (node:internal/modules/cjs/loader:769:27)
    at Module.require (node:internal/modules/cjs/loader:997:19)
    at Module._preloadModules (node:internal/modules/cjs/loader:1267:12)
    at loadPreloadModules (node:internal/bootstrap/pre_execution:455:5)
    at prepareMainThreadExecution (node:internal/bootstrap/pre_execution:74:3)
    at node:internal/main/run_main_module:7:1 {
  code: 'MODULE_NOT_FOUND',
  requireStack: [ 'internal/preload' ]
}

    at ChildProcess.exithandler (node:child_process:333:12)
    at ChildProcess.emit (node:events:376:20)
    at ChildProcess.emit (node:domain:470:12)
    at maybeClose (node:internal/child_process:1063:16)
    at Process.onexit (node:internal/child_process:295:5) {
  killed: false,
  code: 1,
  signal: null,
  cmd: 'npm ls --depth=0 -g ',

It seems to me that this happens because in the code for list() we set cwd to "/" when the search is for global packages. In doing so, the module loader looks for a global install of esm which it fails to find, since esm is only installed locally.

It might help if you allowed list() to accept an opts parameter, like install() and uninstall() so I could pass cwd: '.' to it and your code would have

cwd: opts.cwd?opts.cwd:"/"

instead of

cwd:path?path:"/"

I have tested this by making manual edits to the code in my clone, and it seems to work. I'd be happy to provide a PR.

Uninstall Example

The uninstall example is duplicate from the install example. both of them are same.

Uninstall:

    var npm = require('npm-programmatic');
    npm.install(['left-pad'], {
        cwd:'/path/to/my/project',
        save:true
    })
    .then(function(){
        console.log("SUCCESS!!!");
    })
    .catch(function(){
        console.log("Unable to uninstall package");
    });

Install:

    var npm = require('npm-programmatic');
    npm.install(['left-pad'], {
        cwd:'/path/to/my/project',
        save:true
    })
    .then(function(){
        console.log("SUCCESS!!!");
    })
    .catch(function(){
        console.log("Unable to install package");
    });

Thanks.

npm.list callback function always returns null

when I try promise-then type of code,

npm.list(directory)
  .then(res => console.log(res)) // it returns Unhandled rejection null
  .catch(e => console.log(e)) // it doesn't catch any error

and it just returns null in async-await code

try {
  let res = await npm.list(directory)
  console.log(res) 
} catch (e) {
  console.error(e) // null
}

It should be throw any error but it only returns null.

How to handle node-gyp

In electron app

I'm currently installing package using [email protected] package inside an electron v5.0.1 app:

      const npm = require('npm')
      npm.load({}, (npmErr) => {
        if (npmErr) return reject(npmErr)
        npm.commands.install(packagePath, packages, (err) => {
          if (err) return reject(err)
          installStatus.set(name, 'installed').then(resolve)
        })
      })

And it always get node-pre-gyp install --fallback-to-build spawn ENOENT in reject(err).

I'm considering switching to this package, will it work?

Top Versions

Hello,
Please, could you help me?
Is there any way for when I install the npm module, I put in the version the ^ character for it to accept higher versions?
Example: instead of "npm-programmatic": "0.0.6", be "npm-programmatic": "^ 0.0.6"
Thanks for listening

Check failed: stack_overflow

I am getting the following error:

#
# Fatal error in , line 0
# Check failed: stack_overflow().
#
#
#
#FailureMessage Object: 000000644513CF80
 1: 00007FF6FC74D2CF napi_wrap+113695
 2: 00007FF6FC688C1F std::basic_ostream<char,std::char_traits<char> >::operator<<+59535
 3: 00007FF6FD293E04 V8_Fatal+212
 4: 00007FF6FCC39B4E v8::internal::Parser::DoParseFunction+2398
 5: 00007FF6FCC3EBC4 v8::internal::Parser::ParseFunction+1444
 6: 00007FF6FCC34972 v8::internal::parsing::ParseFunction+402
 7: 00007FF6FCE7A6EC v8::internal::MessageHandler::ReportMessage+6732
 8: 00007FF6FCDBC10A v8::internal::StubCache::Set+16154
 9: 00007FF6FCDBF8E5 v8::internal::StubCache::Set+30453
10: 00007FF6FD0306FD v8::internal::SetupIsolateDelegate::SetupHeap+463949
11: 00007FF6FD0A6330 v8::internal::SetupIsolateDelegate::SetupHeap+946304
12: 00007FF6FCFC90E2 v8::internal::SetupIsolateDelegate::SetupHeap+40498
13: 00007FF6FCFC90E2 v8::internal::SetupIsolateDelegate::SetupHeap+40498
14: 00007FF6FCFC90E2 v8::internal::SetupIsolateDelegate::SetupHeap+40498
15: 00007FF6FCFC90E2 v8::internal::SetupIsolateDelegate::SetupHeap+40498
16: 00007FF6FCFC90E2 v8::internal::SetupIsolateDelegate::SetupHeap+40498
17: 00007FF6FCFC90E2 v8::internal::SetupIsolateDelegate::SetupHeap+40498
18: 00007FF6FCFC90E2 v8::internal::SetupIsolateDelegate::SetupHeap+40498
19: 00007FF6FCFC90E2 v8::internal::SetupIsolateDelegate::SetupHeap+40498
20: 00007FF6FCFC2D19 v8::internal::SetupIsolateDelegate::SetupHeap+14953
21: 00007FF6FCFC90E2 v8::internal::SetupIsolateDelegate::SetupHeap+40498
22: 00007FF6FCFD13F9 v8::internal::SetupIsolateDelegate::SetupHeap+74057
23: 00007FF6FD0A6330 v8::internal::SetupIsolateDelegate::SetupHeap+946304
24: 00007FF6FCFC90E2 v8::internal::SetupIsolateDelegate::SetupHeap+40498
25: 00007FF6FCFC90E2 v8::internal::SetupIsolateDelegate::SetupHeap+40498
26: 00007FF6FCFC90E2 v8::internal::SetupIsolateDelegate::SetupHeap+40498
27: 00007FF6FCFC90E2 v8::internal::SetupIsolateDelegate::SetupHeap+40498
28: 00007FF6FCFC90E2 v8::internal::SetupIsolateDelegate::SetupHeap+40498
29: 00007FF6FCFC90E2 v8::internal::SetupIsolateDelegate::SetupHeap+40498
30: 00007FF6FCFC90E2 v8::internal::SetupIsolateDelegate::SetupHeap+40498
31: 00007FF6FCFC90E2 v8::internal::SetupIsolateDelegate::SetupHeap+40498
32: 00007FF6FCFC90E2 v8::internal::SetupIsolateDelegate::SetupHeap+40498
33: 00007FF6FCFC90E2 v8::internal::SetupIsolateDelegate::SetupHeap+40498
34: 00007FF6FCFC90E2 v8::internal::SetupIsolateDelegate::SetupHeap+40498
35: 00007FF6FCFC90E2 v8::internal::SetupIsolateDelegate::SetupHeap+40498
36: 00007FF6FCFC90E2 v8::internal::SetupIsolateDelegate::SetupHeap+40498
37: 00007FF6FCFC6D9E v8::internal::SetupIsolateDelegate::SetupHeap+31470
38: 00007FF6FCFC698C v8::internal::SetupIsolateDelegate::SetupHeap+30428
39: 00007FF6FCE92978 v8::internal::Execution::CallWasm+1656
40: 00007FF6FCE921DF v8::internal::Execution::Call+191
41: 00007FF6FCF85D70 v8::Function::Call+608
42: 00007FF6FC71D31C napi_unref_threadsafe_function+3516
43: 00007FF6FC720343 node::Start+1219
44: 00007FF6FC7205C4 node::Start+1860
45: 00007FF6FC76EA31 node::LoadEnvironment+49
46: 00007FF6FC6ACA88 v8::internal::OrderedHashTable<v8::internal::OrderedHashMap,2>::NumberOfBucketsOffset+7640
47: 00007FF6FC71FFC5 node::Start+325
48: 00007FF6FC586BEC RC4_options+340716
49: 00007FF6FD514F28 v8::internal::compiler::RepresentationChanger::Uint32OverflowOperatorFor+139416
50: 00007FFEFAAD54E0 BaseThreadInitThunk+16
51: 00007FFEFB6E485B RtlUserThreadStart+43

bug: npm list check for missing packages prevents resolving

I have several issues with this condition: https://github.com/Manak/npm-programmatic/blob/master/index.js#L69

if (stderr.indexOf("missing") === -1 && stderr.indexOf("required") === -1) {
  1. The logic is bad: if the stderr is empty, then fail promise.
  2. The promise is rejected but the computation keeps going. It would be better to use return reject(error).
  3. It checks for stderr and then returns error which is null so the promise fails without any information.

list packages using the --json option for better parsing

For whatever reason, I'm seeing the list of packages returned by the current method prefixing each line with a + character. This ends up returning an empty result when I use npm.list. For example, after the string is split into an array onto new lines here's an example of one of the array values:
+-- [email protected]

I think it would be a more robust solution to use the --json in conjunction with --silent then parse the JSON. Once the command outputs json, parsing it for packages would be pretty simple:

var packages = JSON.parse(stdout);
return Object.keys(packages.dependencies);

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.