File Explorer

/var/lang/lib/node_modules/npm/lib/commands

This explorer reads the filesystem of the server it runs on, so /workspace/user isn't present here. Browsing and the terminal still work against this server's own disk from /.

1 dir
67 files
run.js6.3 KB · 223 lines
const { output } = require('proc-log')const pkgJson = require('@npmcli/package-json')const BaseCommand = require('../base-cmd.js')const { getError } = require('../utils/error-message.js')const { outputError } = require('../utils/output-error.js') class RunScript extends BaseCommand {  static description = 'Run arbitrary package scripts'  static params = [    'workspace',    'workspaces',    'include-workspace-root',    'if-present',    'ignore-scripts',    'foreground-scripts',    'script-shell',  ]   static name = 'run'  static usage = ['<command> [-- <args>]']  static workspaces = true  static ignoreImplicitWorkspace = false  static isShellout = true  static checkDevEngines = true   static async completion (opts, npm) {    const argv = opts.conf.argv.remain    if (argv.length === 2) {      const workspacePrefixes = npm.config.get('workspace', 'default')      const localPrefix = workspacePrefixes.length        ? workspacePrefixes[0]        : npm.localPrefix      const { content: { scripts = {} } } = await pkgJson.normalize(localPrefix)        .catch(() => ({ content: {} }))      if (opts.isFish) {        return Object.keys(scripts).map(s => `${s}\t${scripts[s].slice(0, 30)}`)      }      return Object.keys(scripts)    }  }   async exec (args) {    if (args.length) {      await this.#run(args, { path: this.npm.localPrefix })    } else {      await this.#list(this.npm.localPrefix)    }  }   async execWorkspaces (args) {    await this.setWorkspaces()     const ws = [...this.workspaces.entries()]    for (const [workspace, path] of ws) {      const last = path === ws.at(-1)[1]       if (!args.length) {        const newline = await this.#list(path, { workspace })        if (newline && !last) {          output.standard()        }        continue      }       const pkg = await pkgJson.normalize(path).then(p => p.content)      try {        await this.#run(args, { path, pkg, workspace })      } catch (e) {        const err = getError(e, { npm: this.npm, command: null })        outputError({          ...err,          error: [            ['', `Lifecycle script \`${args[0]}\` failed with error:`],            ...err.error,            ['workspace', pkg._id || pkg.name],            ['location', path],          ],        })        process.exitCode = err.exitCode        if (!last) {          output.error('')        }      }    }  }   async #run ([event, ...args], { path, pkg, workspace }) {    const runScript = require('@npmcli/run-script')     pkg ??= await pkgJson.normalize(path).then(p => p.content)     const { scripts = {} } = pkg     if (event === 'restart' && !scripts.restart) {      scripts.restart = 'npm stop --if-present && npm start'    } else if (event === 'env' && !scripts.env) {      const { isWindowsShell } = require('../utils/is-windows.js')      scripts.env = isWindowsShell ? 'SET' : 'env'    }     pkg.scripts = scripts     if (      !Object.prototype.hasOwnProperty.call(scripts, event) &&      !(event === 'start' && (await runScript.isServerPackage(path)))    ) {      if (this.npm.config.get('if-present')) {        return      }       const suggestions = require('../utils/did-you-mean.js')(pkg, event)      const wsArg = workspace && path !== this.npm.localPrefix        ? ` --workspace=${pkg._id || pkg.name}`        : ''      throw new Error([        `Missing script: "${event}"${suggestions}\n`,        'To see a list of scripts, run:',        `  npm run${wsArg}`,      ].join('\n'))    }     // positional args only added to the main event, not pre/post    const events = [[event, args]]    if (!this.npm.config.get('ignore-scripts')) {      if (scripts[`pre${event}`]) {        events.unshift([`pre${event}`, []])      }       if (scripts[`post${event}`]) {        events.push([`post${event}`, []])      }    }     for (const [ev, evArgs] of events) {      await runScript({        args: evArgs,        event: ev,        nodeGyp: this.npm.config.get('node-gyp'),        path,        pkg,        // || undefined is because runScript will be unhappy with the default null value        scriptShell: this.npm.config.get('script-shell') || undefined,        stdio: 'inherit',      })    }  }   async #list (path, { workspace } = {}) {    const { scripts = {}, name, _id } = await pkgJson.normalize(path).then(p => p.content)    const scriptEntries = Object.entries(scripts)     if (this.npm.silent) {      return    }     if (this.npm.config.get('json')) {      output.buffer(workspace ? { [workspace]: scripts } : scripts)      return    }     if (!scriptEntries.length) {      return    }     if (this.npm.config.get('parseable')) {      output.standard(scriptEntries        .map((s) => (workspace ? [workspace, ...s] : s).join(':'))        .join('\n')        .trim())      return    }     const cmdList = [      'prepare', 'prepublishOnly',      'prepack', 'postpack',      'dependencies',      'preinstall', 'install', 'postinstall',      'prepublish', 'publish', 'postpublish',      'prerestart', 'restart', 'postrestart',      'prestart', 'start', 'poststart',      'prestop', 'stop', 'poststop',      'pretest', 'test', 'posttest',      'preuninstall', 'uninstall', 'postuninstall',      'preversion', 'version', 'postversion',    ]    const [cmds, runScripts] = scriptEntries.reduce((acc, s) => {      acc[cmdList.includes(s[0]) ? 0 : 1].push(s)      return acc    }, [[], []])     const { reset, bold, cyan, dim, blue } = this.npm.chalk    const pkgId = `in ${cyan(_id || name)}`    const title = (t) => reset(bold(t))     if (cmds.length) {      output.standard(`${title('Lifecycle scripts')} included ${pkgId}:`)      for (const [k, v] of cmds) {        output.standard(`  ${k}`)        output.standard(`    ${dim(v)}`)      }    }     if (runScripts.length) {      const via = `via \`${blue('npm run')}\`:`      if (!cmds.length) {        output.standard(`${title('Scripts')} available ${pkgId} ${via}`)      } else {        output.standard(`available ${via}`)      }      for (const [k, v] of runScripts) {        output.standard(`  ${k}`)        output.standard(`    ${dim(v)}`)      }    }     // Return true to indicate that something was output for this path    // that should be separated from others    return true  }} module.exports = RunScript