{
  "version": 3,
  "sources": ["../../../../src/packages/plugin-commands-audit/audit.ts"],
  "sourcesContent": ["import {\n  audit,\n  type AuditAdvisory,\n  type AuditLevelNumber,\n  type AuditLevelString,\n  type AuditReport,\n  type AuditVulnerabilityCounts,\n  type IgnoredAuditVulnerabilityCounts,\n} from '../audit/index.ts';\nimport { createGetAuthHeaderByURI } from '../network.auth-header/index.ts';\nimport { docsUrl, TABLE_OPTIONS } from '../cli-utils/index.ts';\nimport {\n  type Config,\n  types as allTypes,\n  type UniversalOptions,\n} from '../config/index.ts';\nimport { WANTED_LOCKFILE } from '../constants/index.ts';\nimport { PnpmError } from '../error/index.ts';\nimport { readWantedLockfile } from '../lockfile.fs/index.ts';\nimport type { LockFileDir, Registries } from '../types/index.ts';\nimport { table } from '@zkochan/table';\nimport chalk, { type ChalkInstance } from 'chalk';\nimport difference from 'ramda/src/difference';\nimport pick from 'ramda/src/pick';\nimport pickBy from 'ramda/src/pickBy';\nimport renderHelp from 'render-help';\nimport { fix } from './fix.ts';\n\n// eslint-disable\nconst AUDIT_LEVEL_NUMBER = {\n  low: 0,\n  moderate: 1,\n  high: 2,\n  critical: 3,\n} satisfies Record<AuditLevelString, AuditLevelNumber>;\n\nconst AUDIT_COLOR = {\n  low: chalk.bold,\n  moderate: chalk.bold.yellow,\n  high: chalk.bold.red,\n  critical: chalk.bold.red,\n} satisfies Record<AuditLevelString, ChalkInstance>;\n\nconst AUDIT_TABLE_OPTIONS = {\n  ...TABLE_OPTIONS,\n  columns: {\n    1: {\n      width: 54, // = table width of 80\n      wrapWord: true,\n    },\n  },\n};\n// eslint-enable\n\nconst MAX_PATHS_COUNT = 3;\n\nexport const rcOptionsTypes = cliOptionsTypes;\n\nexport function cliOptionsTypes(): Record<string, unknown> {\n  return {\n    ...pick.default(\n      ['dev', 'json', 'only', 'optional', 'production', 'registry'],\n      allTypes\n    ),\n    'audit-level': ['low', 'moderate', 'high', 'critical'],\n    fix: Boolean,\n    'ignore-registry-errors': Boolean,\n  };\n}\n\nexport const shorthands: Record<string, string> = {\n  D: '--dev',\n  P: '--production',\n};\n\nexport const commandNames = ['audit'];\n\nexport function help(): string {\n  return renderHelp({\n    description:\n      'Checks for known security issues with the installed packages.',\n    descriptionLists: [\n      {\n        title: 'Options',\n\n        list: [\n          {\n            description:\n              'Add overrides to the package.json file in order to force non-vulnerable versions of the dependencies',\n            name: '--fix',\n          },\n          {\n            description: 'Output audit report in JSON format',\n            name: '--json',\n          },\n          {\n            description:\n              'Only print advisories with severity greater than or equal to one of the following: low|moderate|high|critical. Default: low',\n            name: '--audit-level <severity>',\n          },\n          {\n            description: 'Only audit \"devDependencies\"',\n            name: '--dev',\n            shortAlias: '-D',\n          },\n          {\n            description: 'Only audit \"dependencies\" and \"optionalDependencies\"',\n            name: '--prod',\n            shortAlias: '-P',\n          },\n          {\n            description: 'Don\\'t audit \"optionalDependencies\"',\n            name: '--no-optional',\n          },\n          {\n            description:\n              'Use exit code 0 if the registry responds with an error. Useful when audit checks are used in CI. A build should fail because the registry has issues.',\n            name: '--ignore-registry-errors',\n          },\n        ],\n      },\n    ],\n    url: docsUrl('audit'),\n    usages: ['pnpm audit [options]'],\n  });\n}\n\nexport async function handler(\n  opts: Pick<UniversalOptions, 'dir'> & {\n    auditLevel?: 'low' | 'moderate' | 'high' | 'critical' | undefined;\n    fix?: boolean | undefined;\n    ignoreRegistryErrors?: boolean | undefined;\n    json?: boolean | undefined;\n    lockfileDir?: LockFileDir | undefined;\n    registries: Registries;\n  } & Pick<\n      Config,\n      | 'ca'\n      | 'cert'\n      | 'httpProxy'\n      | 'httpsProxy'\n      | 'key'\n      | 'localAddress'\n      | 'maxSockets'\n      | 'noProxy'\n      | 'strictSsl'\n      | 'fetchRetries'\n      | 'fetchRetryMaxtimeout'\n      | 'fetchRetryMintimeout'\n      | 'fetchRetryFactor'\n      | 'fetchTimeout'\n      | 'production'\n      | 'dev'\n      | 'optional'\n      | 'userConfig'\n      | 'rawConfig'\n      | 'rootProjectManifest'\n      | 'virtualStoreDirMaxLength'\n    >\n): Promise<{ exitCode: number; output: string }> {\n  const lockfileDir = opts.lockfileDir ?? opts.dir;\n\n  const lockfile = await readWantedLockfile(lockfileDir, {\n    ignoreIncompatible: true,\n  });\n\n  if (lockfile == null) {\n    throw new PnpmError(\n      'AUDIT_NO_LOCKFILE',\n      `No ${WANTED_LOCKFILE} found: Cannot audit a project without a lockfile`\n    );\n  }\n\n  const include = {\n    dependencies: opts.production !== false,\n    devDependencies: opts.dev !== false,\n    optionalDependencies: opts.optional !== false,\n  };\n\n  let auditReport: AuditReport | undefined;\n\n  const getAuthHeader = createGetAuthHeaderByURI({\n    allSettings: opts.rawConfig,\n    userSettings: opts.userConfig,\n  });\n\n  try {\n    auditReport = await audit(lockfile, getAuthHeader, {\n      agentOptions: {\n        ca: opts.ca,\n        cert: opts.cert,\n        httpProxy: opts.httpProxy,\n        httpsProxy: opts.httpsProxy,\n        key: opts.key,\n        localAddress: opts.localAddress,\n        maxSockets: opts.maxSockets,\n        noProxy: opts.noProxy,\n        strictSsl: opts.strictSsl,\n        timeout: opts.fetchTimeout,\n      },\n      include,\n      lockfileDir,\n      registry: opts.registries.default,\n      retry: {\n        factor: opts.fetchRetryFactor ?? 10,\n        maxTimeout: opts.fetchRetryMaxtimeout ?? 60_000,\n        minTimeout: opts.fetchRetryMintimeout ?? 10_000,\n        retries: opts.fetchRetries ?? 3,\n      },\n      timeout: opts.fetchTimeout,\n      virtualStoreDirMaxLength: opts.virtualStoreDirMaxLength,\n    });\n    // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  } catch (err: any) {\n    if (opts.ignoreRegistryErrors === true) {\n      return {\n        exitCode: 0,\n        output: err.message,\n      };\n    }\n\n    throw err;\n  }\n\n  if (opts.fix === true) {\n    const newOverrides = await fix(opts.dir, auditReport);\n\n    if (Object.values(newOverrides).length === 0) {\n      return {\n        exitCode: 0,\n        output: 'No fixes were made',\n      };\n    }\n\n    return {\n      exitCode: 0,\n      output: `${Object.values(newOverrides).length} overrides were added to package.json to fix vulnerabilities.\nRun \"pnpm install\" to apply the fixes.\n\nThe added overrides:\n${JSON.stringify(newOverrides, null, 2)}`,\n    };\n  }\n\n  const vulnerabilities = auditReport.metadata.vulnerabilities;\n\n  const ignoredVulnerabilities: IgnoredAuditVulnerabilityCounts = {\n    low: 0,\n    moderate: 0,\n    high: 0,\n    critical: 0,\n  };\n\n  const totalVulnerabilityCount = Object.values(vulnerabilities).reduce(\n    (sum: number, vulnerabilitiesCount: number) => sum + vulnerabilitiesCount,\n    0\n  );\n\n  const ignoreGhsas = opts.rootProjectManifest?.pnpm?.auditConfig?.ignoreGhsas;\n\n  if (ignoreGhsas) {\n    auditReport.advisories = pickBy.default(\n      ({ github_advisory_id, severity }): boolean => {\n        if (!ignoreGhsas.includes(github_advisory_id)) {\n          return true;\n        }\n\n        ignoredVulnerabilities[severity as AuditLevelString] += 1;\n\n        return false;\n      },\n      auditReport.advisories\n    );\n  }\n\n  const ignoreCves = opts.rootProjectManifest?.pnpm?.auditConfig?.ignoreCves;\n\n  if (ignoreCves) {\n    auditReport.advisories = pickBy.default(({ cves, severity }): boolean => {\n      if (\n        cves.length === 0 ||\n        difference.default(cves, ignoreCves).length > 0\n      ) {\n        return true;\n      }\n\n      ignoredVulnerabilities[severity as AuditLevelString] += 1;\n\n      return false;\n    }, auditReport.advisories);\n  }\n  if (opts.json === true) {\n    return {\n      exitCode: totalVulnerabilityCount > 0 ? 1 : 0,\n      output: JSON.stringify(auditReport, null, 2),\n    };\n  }\n\n  let output = '';\n\n  const auditLevel = AUDIT_LEVEL_NUMBER[opts.auditLevel ?? 'low'];\n\n  let advisories = Object.values(auditReport.advisories);\n\n  advisories = advisories\n    .filter(({ severity }: AuditAdvisory): boolean => {\n      return AUDIT_LEVEL_NUMBER[severity] >= auditLevel;\n    })\n    .sort((a1: AuditAdvisory, a2: AuditAdvisory): number => {\n      return AUDIT_LEVEL_NUMBER[a2.severity] - AUDIT_LEVEL_NUMBER[a1.severity];\n    });\n\n  for (const advisory of advisories) {\n    const paths = advisory.findings.flatMap(({ paths }) => paths);\n\n    output += table(\n      [\n        [\n          AUDIT_COLOR[advisory.severity](advisory.severity),\n          chalk.bold(advisory.title),\n        ],\n        ['Package', advisory.module_name],\n        ['Vulnerable versions', advisory.vulnerable_versions],\n        ['Patched versions', advisory.patched_versions],\n        [\n          'Paths',\n          (paths.length > MAX_PATHS_COUNT\n            ? paths\n                .slice(0, MAX_PATHS_COUNT)\n                .concat([\n                  `... Found ${paths.length} paths, run \\`pnpm why ${advisory.module_name}\\` for more information`,\n                ])\n            : paths\n          ).join('\\n\\n'),\n        ],\n        ['More info', advisory.url],\n      ],\n      AUDIT_TABLE_OPTIONS\n    );\n  }\n\n  return {\n    exitCode: output ? 1 : 0,\n    output: `${output}${reportSummary(auditReport.metadata.vulnerabilities, totalVulnerabilityCount, ignoredVulnerabilities)}`,\n  };\n}\n\nfunction reportSummary(\n  vulnerabilities: AuditVulnerabilityCounts,\n  totalVulnerabilityCount: number,\n  ignoredVulnerabilities: IgnoredAuditVulnerabilityCounts\n): string {\n  if (totalVulnerabilityCount === 0) {\n    return 'No known vulnerabilities found\\n';\n  }\n\n  return `${chalk.red(totalVulnerabilityCount)} vulnerabilities found\\nSeverity: ${Object.entries(\n    vulnerabilities\n  )\n    .filter(([_auditLevel, vulnerabilitiesCount]): boolean => {\n      return vulnerabilitiesCount > 0;\n    })\n    .map(([auditLevel, vulnerabilitiesCount]: [string, number]): string => {\n      return AUDIT_COLOR[auditLevel as AuditLevelString](\n        `${vulnerabilitiesCount} ${auditLevel}${ignoredVulnerabilities[auditLevel as AuditLevelString] > 0 ? ` (${ignoredVulnerabilities[auditLevel as AuditLevelString]} ignored)` : ''}`\n      );\n    })\n    .join(' | ')}`;\n}\n"],
  "mappings": "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",
  "names": ["paths"]
}
