libnpmexec 8.1.1 → 8.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
- const { resolve } = require('path')
2
- const { stat } = require('fs/promises')
1
+ const { resolve } = require('node:path')
2
+ const { stat } = require('node:fs/promises')
3
3
  const { walkUp } = require('walk-up-path')
4
4
 
5
5
  const fileExists = async (file) => {
package/lib/index.js CHANGED
@@ -1,9 +1,9 @@
1
1
  'use strict'
2
2
 
3
- const { mkdir } = require('fs/promises')
3
+ const { mkdir } = require('node:fs/promises')
4
4
  const Arborist = require('@npmcli/arborist')
5
5
  const ciInfo = require('ci-info')
6
- const crypto = require('crypto')
6
+ const crypto = require('node:crypto')
7
7
  const { log, input } = require('proc-log')
8
8
  const npa = require('npm-package-arg')
9
9
  const pacote = require('pacote')
@@ -14,7 +14,7 @@ const getBinFromManifest = require('./get-bin-from-manifest.js')
14
14
  const noTTY = require('./no-tty.js')
15
15
  const runScript = require('./run-script.js')
16
16
  const isWindows = require('./is-windows.js')
17
- const { dirname, resolve } = require('path')
17
+ const { dirname, resolve } = require('node:path')
18
18
 
19
19
  const binPaths = []
20
20
 
@@ -32,7 +32,7 @@ const getManifest = async (spec, flatOptions) => {
32
32
 
33
33
  // Returns the required manifest if the spec is missing from the tree
34
34
  // Returns the found node if it is in the tree
35
- const missingFromTree = async ({ spec, tree, flatOptions, isNpxTree }) => {
35
+ const missingFromTree = async ({ spec, tree, flatOptions, isNpxTree, shallow }) => {
36
36
  // If asking for a spec by name only (spec.raw === spec.name):
37
37
  // - In local or global mode go with anything in the tree that matches
38
38
  // - If looking in the npx cache check if a newer version is available
@@ -41,6 +41,10 @@ const missingFromTree = async ({ spec, tree, flatOptions, isNpxTree }) => {
41
41
  // registry spec that is not a specific tag.
42
42
  const nodesBySpec = tree.inventory.query('packageName', spec.name)
43
43
  for (const node of nodesBySpec) {
44
+ // continue if node is not a top level node
45
+ if (shallow && node.depth) {
46
+ continue
47
+ }
44
48
  if (spec.rawSpec === '*') {
45
49
  return { node }
46
50
  }
@@ -73,6 +77,11 @@ const missingFromTree = async ({ spec, tree, flatOptions, isNpxTree }) => {
73
77
  }
74
78
  }
75
79
 
80
+ // see if the package.json at `path` has an entry that matches `cmd`
81
+ const hasPkgBin = (path, cmd, flatOptions) =>
82
+ pacote.manifest(path, flatOptions)
83
+ .then(manifest => manifest?.bin?.[cmd]).catch(() => null)
84
+
76
85
  const exec = async (opts) => {
77
86
  const {
78
87
  args = [],
@@ -89,6 +98,13 @@ const exec = async (opts) => {
89
98
  ...flatOptions
90
99
  } = opts
91
100
 
101
+ let pkgPaths = opts.pkgPath
102
+ if (typeof pkgPaths === 'string') {
103
+ pkgPaths = [pkgPaths]
104
+ }
105
+ if (!pkgPaths) {
106
+ pkgPaths = ['.']
107
+ }
92
108
  let yes = opts.yes
93
109
  const run = () => runScript({
94
110
  args,
@@ -106,28 +122,31 @@ const exec = async (opts) => {
106
122
  return run()
107
123
  }
108
124
 
125
+ // Look in the local tree too
126
+ pkgPaths.push(path)
127
+
109
128
  let needPackageCommandSwap = (args.length > 0) && (packages.length === 0)
110
129
  // If they asked for a command w/o specifying a package, see if there is a
111
130
  // bin that directly matches that name:
112
- // - in the local package itself
113
- // - in the local tree
131
+ // - in any local packages (pkgPaths can have workspaces in them or just the root)
132
+ // - in the local tree (path)
114
133
  // - globally
115
134
  if (needPackageCommandSwap) {
116
- let localManifest
117
- try {
118
- localManifest = await pacote.manifest(path, flatOptions)
119
- } catch {
120
- // no local package.json? no problem, move one.
135
+ // Local packages and local tree
136
+ for (const p of pkgPaths) {
137
+ if (await hasPkgBin(p, args[0], flatOptions)) {
138
+ // we have to install the local package into the npx cache so that its
139
+ // bin links get set up
140
+ flatOptions.installLinks = false
141
+ // args[0] will exist when the package is installed
142
+ packages.push(p)
143
+ yes = true
144
+ needPackageCommandSwap = false
145
+ break
146
+ }
121
147
  }
122
- if (localManifest?.bin?.[args[0]]) {
123
- // we have to install the local package into the npx cache so that its
124
- // bin links get set up
125
- flatOptions.installLinks = false
126
- // args[0] will exist when the package is installed
127
- packages.push(path)
128
- yes = true
129
- needPackageCommandSwap = false
130
- } else {
148
+ if (needPackageCommandSwap) {
149
+ // no bin entry in local packages or in tree, now we look for binPaths
131
150
  const dir = dirname(dirname(localBin))
132
151
  const localBinPath = await localFileExists(dir, args[0], '/')
133
152
  if (localBinPath) {
@@ -187,7 +206,7 @@ const exec = async (opts) => {
187
206
  const globalArb = new Arborist({ ...flatOptions, path: globalPath, global: true })
188
207
  const globalTree = await globalArb.loadActual()
189
208
  const { manifest: globalManifest } =
190
- await missingFromTree({ spec, tree: globalTree, flatOptions })
209
+ await missingFromTree({ spec, tree: globalTree, flatOptions, shallow: true })
191
210
  if (!globalManifest && await fileExists(`${globalBin}/${args[0]}`)) {
192
211
  binPaths.push(globalBin)
193
212
  return await run()
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "libnpmexec",
3
- "version": "8.1.1",
3
+ "version": "8.1.3",
4
4
  "files": [
5
5
  "bin/",
6
6
  "lib/"
@@ -59,7 +59,7 @@
59
59
  "tap": "^16.3.8"
60
60
  },
61
61
  "dependencies": {
62
- "@npmcli/arborist": "^7.5.2",
62
+ "@npmcli/arborist": "^7.5.4",
63
63
  "@npmcli/run-script": "^8.1.0",
64
64
  "ci-info": "^4.0.0",
65
65
  "npm-package-arg": "^11.0.2",