Your IP : 216.73.216.86


Current Path : /home/emeraadmin/www/4d695/
Upload File :
Current File : /home/emeraadmin/www/4d695/libnpmexec.tar

package.json000064400000004047151701447250007045 0ustar00{
  "_id": "libnpmexec@8.1.2",
  "_inBundle": true,
  "_location": "/npm/libnpmexec",
  "_phantomChildren": {},
  "_requiredBy": [
    "/npm"
  ],
  "author": {
    "name": "GitHub Inc."
  },
  "bugs": {
    "url": "https://github.com/npm/cli/issues"
  },
  "contributors": [
    {
      "name": "Ruy Adorno",
      "url": "https://ruyadorno.com"
    }
  ],
  "dependencies": {
    "@npmcli/arborist": "^7.5.3",
    "@npmcli/run-script": "^8.1.0",
    "ci-info": "^4.0.0",
    "npm-package-arg": "^11.0.2",
    "pacote": "^18.0.6",
    "proc-log": "^4.2.0",
    "read": "^3.0.1",
    "read-package-json-fast": "^3.0.2",
    "semver": "^7.3.7",
    "walk-up-path": "^3.0.1"
  },
  "description": "npm exec (npx) programmatic API",
  "devDependencies": {
    "@npmcli/eslint-config": "^4.0.0",
    "@npmcli/mock-registry": "^1.0.0",
    "@npmcli/template-oss": "4.22.0",
    "bin-links": "^4.0.4",
    "chalk": "^5.2.0",
    "just-extend": "^6.2.0",
    "just-safe-set": "^4.2.1",
    "tap": "^16.3.8"
  },
  "engines": {
    "node": "^16.14.0 || >=18.0.0"
  },
  "files": [
    "bin/",
    "lib/"
  ],
  "homepage": "https://github.com/npm/cli#readme",
  "keywords": [
    "npm",
    "npmcli",
    "libnpm",
    "cli",
    "workspaces",
    "libnpmexec"
  ],
  "license": "ISC",
  "main": "lib/index.js",
  "name": "libnpmexec",
  "repository": {
    "type": "git",
    "url": "git+https://github.com/npm/cli.git",
    "directory": "workspaces/libnpmexec"
  },
  "scripts": {
    "lint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"",
    "lintfix": "npm run lint -- --fix",
    "postlint": "template-oss-check",
    "posttest": "npm run lint",
    "snap": "tap",
    "template-oss-apply": "template-oss-apply --force",
    "test": "tap"
  },
  "tap": {
    "files": "test/*.js",
    "nyc-arg": [
      "--exclude",
      "tap-snapshots/**"
    ]
  },
  "templateOSS": {
    "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.",
    "version": "4.22.0",
    "content": "../../scripts/template-oss/index.js"
  },
  "version": "8.1.2"
}
lib/is-windows.js000064400000000056151701447260007763 0ustar00module.exports = process.platform === 'win32'
lib/run-script.js000064400000002566151701447260007776 0ustar00const ciInfo = require('ci-info')
const runScript = require('@npmcli/run-script')
const readPackageJson = require('read-package-json-fast')
const { log, output } = require('proc-log')
const noTTY = require('./no-tty.js')

const run = async ({
  args,
  call,
  flatOptions,
  locationMsg,
  path,
  binPaths,
  runPath,
  scriptShell,
}) => {
  // turn list of args into command string
  const script = call || args.shift() || scriptShell

  // do the fakey runScript dance
  // still should work if no package.json in cwd
  const realPkg = await readPackageJson(`${path}/package.json`).catch(() => ({}))
  const pkg = {
    ...realPkg,
    scripts: {
      ...(realPkg.scripts || {}),
      npx: script,
    },
  }

  if (script === scriptShell) {
    if (!noTTY()) {
      if (ciInfo.isCI) {
        return log.warn('exec', 'Interactive mode disabled in CI environment')
      }

      const { chalk } = flatOptions

      output.standard(`${
        chalk.reset('\nEntering npm script environment')
      }${
        chalk.reset(locationMsg || ` at location:\n${chalk.dim(runPath)}`)
      }${
        chalk.bold('\nType \'exit\' or ^D when finished\n')
      }`)
    }
  }
  return runScript({
    ...flatOptions,
    pkg,
    // we always run in cwd, not --prefix
    path: runPath,
    binPaths,
    event: 'npx',
    args,
    stdio: 'inherit',
    scriptShell,
  })
}

module.exports = run
lib/no-tty.js000064400000000054151701447260007110 0ustar00module.exports = () => !process.stdin.isTTY
lib/index.js000064400000022644151701447260006776 0ustar00'use strict'

const { mkdir } = require('node:fs/promises')
const Arborist = require('@npmcli/arborist')
const ciInfo = require('ci-info')
const crypto = require('node:crypto')
const { log, input } = require('proc-log')
const npa = require('npm-package-arg')
const pacote = require('pacote')
const { read } = require('read')
const semver = require('semver')
const { fileExists, localFileExists } = require('./file-exists.js')
const getBinFromManifest = require('./get-bin-from-manifest.js')
const noTTY = require('./no-tty.js')
const runScript = require('./run-script.js')
const isWindows = require('./is-windows.js')
const { dirname, resolve } = require('node:path')

const binPaths = []

// when checking the local tree we look up manifests, cache those results by
// spec.raw so we don't have to fetch again when we check npxCache
const manifests = new Map()

const getManifest = async (spec, flatOptions) => {
  if (!manifests.has(spec.raw)) {
    const manifest = await pacote.manifest(spec, { ...flatOptions, preferOnline: true })
    manifests.set(spec.raw, manifest)
  }
  return manifests.get(spec.raw)
}

// Returns the required manifest if the spec is missing from the tree
// Returns the found node if it is in the tree
const missingFromTree = async ({ spec, tree, flatOptions, isNpxTree }) => {
  // If asking for a spec by name only (spec.raw === spec.name):
  //  - In local or global mode go with anything in the tree that matches
  //  - If looking in the npx cache check if a newer version is available
  const npxByNameOnly = isNpxTree && spec.name === spec.raw
  if (spec.registry && spec.type !== 'tag' && !npxByNameOnly) {
    // registry spec that is not a specific tag.
    const nodesBySpec = tree.inventory.query('packageName', spec.name)
    for (const node of nodesBySpec) {
      if (spec.rawSpec === '*') {
        return { node }
      }
      // package requested by specific version
      if (spec.type === 'version' && (node.pkgid === spec.raw)) {
        return { node }
      }
      // package requested by version range, only remaining registry type
      if (semver.satisfies(node.package.version, spec.rawSpec)) {
        return { node }
      }
    }
    const manifest = await getManifest(spec, flatOptions)
    return { manifest }
  } else {
    // non-registry spec, or a specific tag, or name only in npx tree.  Look up
    // manifest and check resolved to see if it's in the tree.
    const manifest = await getManifest(spec, flatOptions)
    if (spec.type === 'directory') {
      return { manifest }
    }
    const nodesByManifest = tree.inventory.query('packageName', manifest.name)
    for (const node of nodesByManifest) {
      if (node.package.resolved === manifest._resolved) {
        // we have a package by the same name and the same resolved destination, nothing to add.
        return { node }
      }
    }
    return { manifest }
  }
}

// see if the package.json at `path` has an entry that matches `cmd`
const hasPkgBin = (path, cmd, flatOptions) =>
  pacote.manifest(path, flatOptions)
    .then(manifest => manifest?.bin?.[cmd]).catch(() => null)

const exec = async (opts) => {
  const {
    args = [],
    call = '',
    localBin = resolve('./node_modules/.bin'),
    locationMsg = undefined,
    globalBin = '',
    globalPath,
    // dereference values because we manipulate it later
    packages: [...packages] = [],
    path = '.',
    runPath = '.',
    scriptShell = isWindows ? process.env.ComSpec || 'cmd' : 'sh',
    ...flatOptions
  } = opts

  let pkgPaths = opts.pkgPath
  if (typeof pkgPaths === 'string') {
    pkgPaths = [pkgPaths]
  }
  if (!pkgPaths) {
    pkgPaths = ['.']
  }
  let yes = opts.yes
  const run = () => runScript({
    args,
    call,
    flatOptions,
    locationMsg,
    path,
    binPaths,
    runPath,
    scriptShell,
  })

  // interactive mode
  if (!call && !args.length && !packages.length) {
    return run()
  }

  // Look in the local tree too
  pkgPaths.push(path)

  let needPackageCommandSwap = (args.length > 0) && (packages.length === 0)
  // If they asked for a command w/o specifying a package, see if there is a
  // bin that directly matches that name:
  // - in any local packages (pkgPaths can have workspaces in them or just the root)
  // - in the local tree (path)
  // - globally
  if (needPackageCommandSwap) {
    // Local packages and local tree
    for (const p of pkgPaths) {
      if (await hasPkgBin(p, args[0], flatOptions)) {
        // we have to install the local package into the npx cache so that its
        // bin links get set up
        flatOptions.installLinks = false
        // args[0] will exist when the package is installed
        packages.push(p)
        yes = true
        needPackageCommandSwap = false
        break
      }
    }
    if (needPackageCommandSwap) {
      // no bin entry in local packages or in tree, now we look for binPaths
      const dir = dirname(dirname(localBin))
      const localBinPath = await localFileExists(dir, args[0], '/')
      if (localBinPath) {
        binPaths.push(localBinPath)
        return await run()
      } else if (globalPath && await fileExists(`${globalBin}/${args[0]}`)) {
        binPaths.push(globalBin)
        return await run()
      }
      // We swap out args[0] with the bin from the manifest later
      packages.push(args[0])
    }
  }

  // Resolve any directory specs so that the npx directory is unique to the
  // resolved directory, not the potentially relative one (i.e. "npx .")
  for (const i in packages) {
    const pkg = packages[i]
    const spec = npa(pkg)
    if (spec.type === 'directory') {
      packages[i] = spec.fetchSpec
    }
  }

  const localArb = new Arborist({ ...flatOptions, path })
  const localTree = await localArb.loadActual()

  // Find anything that isn't installed locally
  const needInstall = []
  let commandManifest
  await Promise.all(packages.map(async (pkg, i) => {
    const spec = npa(pkg, path)
    const { manifest, node } = await missingFromTree({ spec, tree: localTree, flatOptions })
    if (manifest) {
      // Package does not exist in the local tree
      needInstall.push({ spec, manifest })
      if (i === 0) {
        commandManifest = manifest
      }
    } else if (i === 0) {
      // The node.package has enough to look up the bin
      commandManifest = node.package
    }
  }))

  if (needPackageCommandSwap) {
    const spec = npa(args[0])

    if (spec.type === 'directory') {
      yes = true
    }

    args[0] = getBinFromManifest(commandManifest)

    if (needInstall.length > 0 && globalPath) {
      // See if the package is installed globally, and run the translated bin
      const globalArb = new Arborist({ ...flatOptions, path: globalPath, global: true })
      const globalTree = await globalArb.loadActual()
      const { manifest: globalManifest } =
        await missingFromTree({ spec, tree: globalTree, flatOptions })
      if (!globalManifest && await fileExists(`${globalBin}/${args[0]}`)) {
        binPaths.push(globalBin)
        return await run()
      }
    }
  }

  const add = []
  if (needInstall.length > 0) {
    // Install things to the npx cache, if needed
    const { npxCache } = flatOptions
    if (!npxCache) {
      throw new Error('Must provide a valid npxCache path')
    }
    const hash = crypto.createHash('sha512')
      .update(packages.map(p => {
        // Keeps the npx directory unique to the resolved directory, not the
        // potentially relative one (i.e. "npx .")
        const spec = npa(p)
        if (spec.type === 'directory') {
          return spec.fetchSpec
        }
        return p
      }).sort((a, b) => a.localeCompare(b, 'en')).join('\n'))
      .digest('hex')
      .slice(0, 16)
    const installDir = resolve(npxCache, hash)
    await mkdir(installDir, { recursive: true })
    const npxArb = new Arborist({
      ...flatOptions,
      path: installDir,
    })
    const npxTree = await npxArb.loadActual()
    await Promise.all(needInstall.map(async ({ spec }) => {
      const { manifest } = await missingFromTree({
        spec,
        tree: npxTree,
        flatOptions,
        isNpxTree: true,
      })
      if (manifest) {
        // Manifest is not in npxCache, we need to install it there
        if (!spec.registry) {
          add.push(manifest._from)
        } else {
          add.push(manifest._id)
        }
      }
    }))

    if (add.length) {
      if (!yes) {
        const addList = add.map(a => `${a.replace(/@$/, '')}`)

        // set -n to always say no
        if (yes === false) {
          // Error message lists missing package(s) when process is canceled
          /* eslint-disable-next-line max-len */
          throw new Error(`npx canceled due to missing packages and no YES option: ${JSON.stringify(addList)}`)
        }

        if (noTTY() || ciInfo.isCI) {
          /* eslint-disable-next-line max-len */
          log.warn('exec', `The following package${add.length === 1 ? ' was' : 's were'} not found and will be installed: ${addList.join(', ')}`)
        } else {
          const confirm = await input.read(() => read({
            /* eslint-disable-next-line max-len */
            prompt: `Need to install the following packages:\n${addList.join('\n')}\nOk to proceed? `,
            default: 'y',
          }))
          if (confirm.trim().toLowerCase().charAt(0) !== 'y') {
            throw new Error('canceled')
          }
        }
      }
      await npxArb.reify({
        ...flatOptions,
        add,
      })
    }
    binPaths.push(resolve(installDir, 'node_modules/.bin'))
  }

  return await run()
}

module.exports = exec
lib/get-bin-from-manifest.js000064400000001200151701447260011742 0ustar00const getBinFromManifest = (mani) => {
  // if we have a bin matching (unscoped portion of) packagename, use that
  // otherwise if there's 1 bin or all bin value is the same (alias), use
  // that, otherwise fail
  const bin = mani.bin || {}
  if (new Set(Object.values(bin)).size === 1) {
    return Object.keys(bin)[0]
  }

  // XXX probably a util to parse this better?
  const name = mani.name.replace(/^@[^/]+\//, '')
  if (bin[name]) {
    return name
  }

  // XXX need better error message
  throw Object.assign(new Error('could not determine executable to run'), {
    pkgid: mani._id,
  })
}

module.exports = getBinFromManifest
lib/file-exists.js000064400000001227151701447260010115 0ustar00const { resolve } = require('node:path')
const { stat } = require('node:fs/promises')
const { walkUp } = require('walk-up-path')

const fileExists = async (file) => {
  try {
    const res = await stat(file)
    return res.isFile()
  } catch {
    return false
  }
}

const localFileExists = async (dir, binName, root) => {
  for (const path of walkUp(dir)) {
    const binDir = resolve(path, 'node_modules', '.bin')

    if (await fileExists(resolve(binDir, binName))) {
      return binDir
    }

    if (path.toLowerCase() === resolve(root).toLowerCase()) {
      return false
    }
  }

  return false
}

module.exports = {
  fileExists,
  localFileExists,
}
LICENSE000064400000001345151701447260005563 0ustar00The ISC License

Copyright (c) GitHub Inc.

Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.

THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
README.md000064400000004472151701447260006041 0ustar00# libnpmexec

[![npm version](https://img.shields.io/npm/v/libnpmexec.svg)](https://npm.im/libnpmexec)
[![license](https://img.shields.io/npm/l/libnpmexec.svg)](https://npm.im/libnpmexec)
[![CI - libnpmexec](https://github.com/npm/cli/actions/workflows/ci-libnpmexec.yml/badge.svg)](https://github.com/npm/cli/actions/workflows/ci-libnpmexec.yml)

The `npm exec` (`npx`) Programmatic API

## Install

`npm install libnpmexec`

## Usage:

```js
const libexec = require('libnpmexec')
await libexec({
  args: ['yosay', 'Bom dia!'],
  cache: '~/.npm/_cacache',
  npxCache: '~/.npm/_npx',
  yes: true,
})
```

## API:

### `libexec(opts)`

- `opts`:
  - `args`: List of pkgs to execute **Array<String>**, defaults to `[]`
  - `call`: An alternative command to run when using `packages` option **String**, defaults to empty string.
  - `cache`: The path location to where the npm cache folder is placed **String**
  - `npxCache`: The path location to where the npx cache folder is placed **String**
  - `chalk`: Chalk instance to use for colors? **Required**
  - `localBin`: Location to the `node_modules/.bin` folder of the local project to start scanning for bin files **String**, defaults to `./node_modules/.bin`. **libexec** will walk up the directory structure looking for `node_modules/.bin` folders in parent folders that might satisfy the current `arg` and will use that bin if found.
  - `locationMsg`: Overrides "at location" message when entering interactive mode **String**
  - `globalBin`: Location to the global space bin folder, same as: `$(npm bin -g)` **String**, defaults to empty string.
  - `packages`: A list of packages to be used (possibly fetch from the registry) **Array<String>**, defaults to `[]`
  - `path`: Location to where to read local project info (`package.json`) **String**, defaults to `.`
  - `runPath`: Location to where to execute the script **String**, defaults to `.`
  - `scriptShell`: Default shell to be used **String**, defaults to `sh` on POSIX systems, `process.env.ComSpec` OR `cmd` on Windows
  - `yes`: Should skip download confirmation prompt when fetching missing packages from the registry? **Boolean**
  - `registry`, `cache`, and more options that are forwarded to [@npmcli/arborist](https://github.com/npm/arborist/) and [pacote](https://github.com/npm/pacote/#options) **Object**

## LICENSE

[ISC](./LICENSE)