{
  "version": 3,
  "sources": ["../../../../src/packages/lifecycle/runLifecycleHook.ts"],
  "sourcesContent": ["import path from 'node:path';\nimport { lifecycleLogger } from '../core-loggers/index.ts';\nimport { globalWarn } from '../logger/index.ts';\n// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-ignore\nimport lifecycle from '@pnpm/npm-lifecycle';\nimport type {\n  DependencyManifest,\n  ProjectManifest,\n  PrepareExecutionEnv,\n  PackageScripts,\n} from '../types/index.ts';\nimport { PnpmError } from '../error/index.ts';\nimport { existsSync } from 'node:fs';\nimport isWindows from 'is-windows';\nimport { quote as shellQuote } from 'shell-quote';\n\nfunction noop(): void {}\n\nexport type RunLifecycleHookOptions = {\n  args?: string[] | undefined;\n  depPath: string;\n  extraBinPaths?: string[] | undefined;\n  extraEnv?: Record<string, string> | undefined;\n  initCwd?: string | undefined;\n  optional?: boolean | undefined;\n  pkgRoot: string;\n  rawConfig: object;\n  rootModulesDir?: string | undefined;\n  scriptShell?: string | undefined;\n  silent?: boolean | undefined;\n  scriptsPrependNodePath?: boolean | 'warn-only' | undefined;\n  shellEmulator?: boolean | undefined;\n  stdio?: string | undefined;\n  unsafePerm: boolean;\n  prepareExecutionEnv?: PrepareExecutionEnv | undefined;\n};\n\nexport async function runLifecycleHook(\n  stage: string,\n  manifest: ProjectManifest | DependencyManifest,\n  opts: RunLifecycleHookOptions\n): Promise<boolean> {\n  const optional = opts.optional === true;\n\n  // To remediate CVE_2024_27980, Node.js does not allow .bat or .cmd files to\n  // be spawned without the \"shell: true\" option.\n  //\n  // https://nodejs.org/api/child_process.html#spawning-bat-and-cmd-files-on-windows\n  //\n  // Unfortunately, setting spawn's shell option also causes arguments to be\n  // evaluated before they're passed to the shell, resulting in a surprising\n  // behavior difference only with .bat/.cmd files.\n  //\n  // Instead of showing a \"spawn EINVAL\" error, let's throw a clearer error that\n  // this isn't supported.\n  //\n  // If this behavior needs to be supported in the future, the arguments would\n  // need to be escaped before they're passed to the .bat/.cmd file. For\n  // example, scripts such as \"echo %PATH%\" should be passed verbatim rather\n  // than expanded. This is difficult to do correctly. Other open source tools\n  // (e.g. Rust) attempted and introduced bugs. The Rust blog has a good\n  // high-level explanation of the same security vulnerability Node.js patched.\n  //\n  // https://blog.rust-lang.org/2024/04/09/cve-2024-24576.html#overview\n  //\n  // Note that npm (as of version 10.5.0) doesn't support setting script-shell\n  // to a .bat or .cmd file either.\n  if (opts.scriptShell != null && isWindowsBatchFile(opts.scriptShell)) {\n    throw new PnpmError(\n      'ERR_PNPM_INVALID_SCRIPT_SHELL_WINDOWS',\n      'Cannot spawn .bat or .cmd as a script shell.',\n      {\n        hint: `\\\nThe .npmrc script-shell option was configured to a .bat or .cmd file. These cannot be used as a script shell reliably.\n\nPlease unset the script-shell option, or configure it to a .exe instead.\n`,\n      }\n    );\n  }\n\n  const m = { _id: getId(manifest), ...manifest };\n  m.scripts = { ...m.scripts };\n\n  switch (stage) {\n    case 'start': {\n      if (typeof m.scripts.start === 'undefined') {\n        if (!existsSync('server.js')) {\n          throw new PnpmError(\n            'NO_SCRIPT_OR_SERVER',\n            'Missing script start or file server.js'\n          );\n        }\n\n        m.scripts.start = 'node server.js';\n      }\n\n      break;\n    }\n\n    case 'install': {\n      if (\n        typeof m.scripts.install === 'undefined' &&\n        typeof m.scripts.preinstall === 'undefined'\n      ) {\n        checkBindingGyp(opts.pkgRoot, m.scripts);\n      }\n\n      break;\n    }\n  }\n\n  if (\n    typeof opts.args?.length === 'number' &&\n    opts.args.length > 0 &&\n    typeof m.scripts[stage] === 'string'\n  ) {\n    // It is impossible to quote a command line argument that contains newline for Windows cmd.\n    const escapedArgs = isWindows()\n      ? opts.args.map((arg) => JSON.stringify(arg)).join(' ')\n      : shellQuote(opts.args);\n\n    m.scripts[stage] = `${m.scripts[stage]} ${escapedArgs}`;\n  }\n\n  // This script is used to prevent the usage of npm or Yarn.\n  // It does nothing, when pnpm is used, so we may skip its execution.\n  if (\n    m.scripts[stage] === 'npx only-allow pnpm' ||\n    typeof m.scripts[stage] === 'undefined'\n  ) {\n    return false;\n  }\n\n  if (opts.stdio !== 'inherit') {\n    lifecycleLogger.debug({\n      depPath: opts.depPath,\n      optional,\n      script: m.scripts[stage],\n      stage,\n      wd: opts.pkgRoot,\n    });\n  }\n\n  const logLevel =\n    opts.stdio !== 'inherit' || opts.silent === true ? 'silent' : undefined;\n\n  const extraBinPaths =\n    (\n      await opts.prepareExecutionEnv?.({\n        extraBinPaths: opts.extraBinPaths,\n        executionEnv: (manifest as ProjectManifest).pnpm?.executionEnv,\n      })\n    )?.extraBinPaths ?? opts.extraBinPaths;\n\n  await lifecycle(m, stage, opts.pkgRoot, {\n    config: {\n      ...opts.rawConfig,\n      'frozen-lockfile': false,\n    },\n    dir: opts.rootModulesDir,\n    extraBinPaths,\n    extraEnv: {\n      ...opts.extraEnv,\n      INIT_CWD: opts.initCwd ?? process.cwd(),\n      PNPM_SCRIPT_SRC_DIR: opts.pkgRoot,\n    },\n    log: {\n      clearProgress: noop,\n      info: noop,\n      level: logLevel,\n      pause: noop,\n      resume: noop,\n      showProgress: noop,\n      silly: npmLog,\n      verbose: npmLog,\n      warn: (...msg: string[]) => {\n        globalWarn(msg.join(' '));\n      },\n    },\n    runConcurrently: true,\n    scriptsPrependNodePath: opts.scriptsPrependNodePath,\n    scriptShell: opts.scriptShell,\n    shellEmulator: opts.shellEmulator,\n    stdio: opts.stdio ?? 'pipe',\n    unsafePerm: opts.unsafePerm,\n  });\n\n  return true;\n\n  function npmLog(\n    _prefix: string,\n    _logId: string,\n    stdtype: string,\n    line: string\n  ): void {\n    switch (stdtype) {\n      case 'stdout':\n      case 'stderr': {\n        lifecycleLogger.debug({\n          depPath: opts.depPath,\n          line: line.toString(),\n          stage,\n          stdio: stdtype,\n          wd: opts.pkgRoot,\n        });\n\n        return;\n      }\n\n      case 'Returned: code:': {\n        if (opts.stdio === 'inherit') {\n          // Preventing the pnpm reporter from overriding the project's script output\n          return;\n        }\n\n        // biome-ignore lint/style/noArguments: <explanation>\n        const code = arguments[3] ?? 1;\n\n        lifecycleLogger.debug({\n          depPath: opts.depPath,\n          exitCode: code,\n          optional,\n          stage,\n          wd: opts.pkgRoot,\n        });\n      }\n    }\n  }\n}\n\nfunction checkBindingGyp(root: string, scripts: PackageScripts): void {\n  if (existsSync(path.join(root, 'binding.gyp'))) {\n    scripts.install = 'node-gyp rebuild';\n  }\n}\n\nfunction getId(manifest: ProjectManifest | DependencyManifest): string {\n  return `${manifest.name}@${manifest.version}`;\n}\n\nfunction isWindowsBatchFile(scriptShell: string): boolean {\n  // Node.js performs a similar check to determine whether it should throw\n  // EINVAL when spawning a .cmd/.bat file.\n  //\n  // https://github.com/nodejs/node/commit/6627222409#diff-1e725bfa950eda4d4b5c0c00a2bb6be3e5b83d819872a1adf2ef87c658273903\n  const scriptShellLower = scriptShell.toLowerCase();\n\n  return (\n    isWindows() &&\n    (scriptShellLower.endsWith('.cmd') || scriptShellLower.endsWith('.bat'))\n  );\n}\n"],
  "mappings": "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",
  "names": []
}
