mirror of
https://github.com/pnpm/pnpm.git
synced 2026-07-26 07:27:20 -04:00
fix(audit): project versions (#5661)
This commit is contained in:
5
.changeset/old-onions-repair.md
Normal file
5
.changeset/old-onions-repair.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"pnpm": patch
|
||||
---
|
||||
|
||||
`pnpm audit` should send the versions of workspace projects for audit.
|
||||
5
.changeset/shy-foxes-repair.md
Normal file
5
.changeset/shy-foxes-repair.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"@pnpm/audit": major
|
||||
---
|
||||
|
||||
New required option added: lockfileDir.
|
||||
@@ -33,6 +33,7 @@
|
||||
"@pnpm/audit": "workspace:*",
|
||||
"@pnpm/constants": "workspace:*",
|
||||
"@pnpm/lockfile-file": "workspace:*",
|
||||
"@pnpm/test-fixtures": "workspace:*",
|
||||
"@types/ramda": "0.28.15",
|
||||
"nock": "13.2.9"
|
||||
},
|
||||
@@ -43,6 +44,7 @@
|
||||
"@pnpm/lockfile-types": "workspace:*",
|
||||
"@pnpm/lockfile-utils": "workspace:*",
|
||||
"@pnpm/lockfile-walker": "workspace:*",
|
||||
"@pnpm/read-project-manifest": "workspace:*",
|
||||
"@pnpm/types": "workspace:*",
|
||||
"ramda": "npm:@pnpm/ramda@0.28.1"
|
||||
},
|
||||
|
||||
@@ -14,12 +14,13 @@ export async function audit (
|
||||
opts: {
|
||||
agentOptions?: AgentOptions
|
||||
include?: { [dependenciesField in DependenciesField]: boolean }
|
||||
lockfileDir: string
|
||||
registry: string
|
||||
retry?: RetryTimeoutOptions
|
||||
timeout?: number
|
||||
}
|
||||
) {
|
||||
const auditTree = lockfileToAuditTree(lockfile, { include: opts.include })
|
||||
const auditTree = await lockfileToAuditTree(lockfile, { include: opts.include, lockfileDir: opts.lockfileDir })
|
||||
const registry = opts.registry.endsWith('/') ? opts.registry : `${opts.registry}/`
|
||||
const auditUrl = `${registry}-/npm/v1/security/audits`
|
||||
const authHeaderValue = getAuthHeader(registry)
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import path from 'path'
|
||||
import { Lockfile } from '@pnpm/lockfile-types'
|
||||
import { nameVerFromPkgSnapshot } from '@pnpm/lockfile-utils'
|
||||
import { lockfileWalkerGroupImporterSteps, LockfileWalkerStep } from '@pnpm/lockfile-walker'
|
||||
import { DependenciesField } from '@pnpm/types'
|
||||
import { readProjectManifest } from '@pnpm/read-project-manifest'
|
||||
import mapValues from 'ramda/src/map'
|
||||
|
||||
export interface AuditNode {
|
||||
@@ -19,25 +21,29 @@ export type AuditTree = AuditNode & {
|
||||
metadata: Object
|
||||
}
|
||||
|
||||
export function lockfileToAuditTree (
|
||||
export async function lockfileToAuditTree (
|
||||
lockfile: Lockfile,
|
||||
opts?: {
|
||||
opts: {
|
||||
include?: { [dependenciesField in DependenciesField]: boolean }
|
||||
lockfileDir: string
|
||||
}
|
||||
): AuditTree {
|
||||
): Promise<AuditTree> {
|
||||
const importerWalkers = lockfileWalkerGroupImporterSteps(lockfile, Object.keys(lockfile.importers), { include: opts?.include })
|
||||
const dependencies = {}
|
||||
importerWalkers.forEach((importerWalker) => {
|
||||
const importerDeps = lockfileToAuditNode(importerWalker.step)
|
||||
// For some reason the registry responds with 500 if the keys in dependencies have slashes
|
||||
// see issue: https://github.com/pnpm/pnpm/issues/2848
|
||||
const depName = importerWalker.importerId.replace(/\//g, '__')
|
||||
dependencies[depName] = {
|
||||
dependencies: importerDeps,
|
||||
requires: toRequires(importerDeps),
|
||||
version: '0.0.0',
|
||||
}
|
||||
})
|
||||
await Promise.all(
|
||||
importerWalkers.map(async (importerWalker) => {
|
||||
const importerDeps = lockfileToAuditNode(importerWalker.step)
|
||||
// For some reason the registry responds with 500 if the keys in dependencies have slashes
|
||||
// see issue: https://github.com/pnpm/pnpm/issues/2848
|
||||
const depName = importerWalker.importerId.replace(/\//g, '__')
|
||||
const { manifest } = await readProjectManifest(path.join(opts.lockfileDir, importerWalker.importerId))
|
||||
dependencies[depName] = {
|
||||
dependencies: importerDeps,
|
||||
requires: toRequires(importerDeps),
|
||||
version: manifest.version,
|
||||
}
|
||||
})
|
||||
)
|
||||
const auditTree: AuditTree = {
|
||||
name: undefined,
|
||||
version: undefined,
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"name": "pkg",
|
||||
"version": "1.0.0"
|
||||
}
|
||||
@@ -1,12 +1,15 @@
|
||||
import { audit } from '@pnpm/audit'
|
||||
import { LOCKFILE_VERSION } from '@pnpm/constants'
|
||||
import { PnpmError } from '@pnpm/error'
|
||||
import { fixtures } from '@pnpm/test-fixtures'
|
||||
import nock from 'nock'
|
||||
import { lockfileToAuditTree } from '../lib/lockfileToAuditTree'
|
||||
|
||||
const f = fixtures(__dirname)
|
||||
|
||||
describe('audit', () => {
|
||||
test('lockfileToAuditTree()', () => {
|
||||
expect(lockfileToAuditTree({
|
||||
test('lockfileToAuditTree()', async () => {
|
||||
expect(await lockfileToAuditTree({
|
||||
importers: {
|
||||
'.': {
|
||||
dependencies: {
|
||||
@@ -33,7 +36,7 @@ describe('audit', () => {
|
||||
},
|
||||
},
|
||||
},
|
||||
})).toEqual({
|
||||
}, { lockfileDir: f.find('one-project') })).toEqual({
|
||||
name: undefined,
|
||||
version: undefined,
|
||||
|
||||
@@ -59,7 +62,7 @@ describe('audit', () => {
|
||||
requires: {
|
||||
foo: '1.0.0',
|
||||
},
|
||||
version: '0.0.0',
|
||||
version: '1.0.0',
|
||||
},
|
||||
},
|
||||
dev: false,
|
||||
@@ -67,7 +70,7 @@ describe('audit', () => {
|
||||
integrity: undefined,
|
||||
metadata: {},
|
||||
remove: [],
|
||||
requires: { '.': '0.0.0' },
|
||||
requires: { '.': '1.0.0' },
|
||||
})
|
||||
})
|
||||
|
||||
@@ -88,6 +91,7 @@ describe('audit', () => {
|
||||
},
|
||||
getAuthHeader,
|
||||
{
|
||||
lockfileDir: f.find('one-project'),
|
||||
registry,
|
||||
retry: {
|
||||
retries: 0,
|
||||
|
||||
@@ -9,6 +9,9 @@
|
||||
"../../__typings__/**/*.d.ts"
|
||||
],
|
||||
"references": [
|
||||
{
|
||||
"path": "../../__utils__/test-fixtures"
|
||||
},
|
||||
{
|
||||
"path": "../../network/fetch"
|
||||
},
|
||||
@@ -24,6 +27,9 @@
|
||||
{
|
||||
"path": "../../packages/types"
|
||||
},
|
||||
{
|
||||
"path": "../../pkg-manifest/read-project-manifest"
|
||||
},
|
||||
{
|
||||
"path": "../lockfile-file"
|
||||
},
|
||||
|
||||
@@ -130,7 +130,8 @@ export async function handler (
|
||||
| 'rootProjectManifest'
|
||||
>
|
||||
) {
|
||||
const lockfile = await readWantedLockfile(opts.lockfileDir ?? opts.dir, { ignoreIncompatible: true })
|
||||
const lockfileDir = opts.lockfileDir ?? opts.dir
|
||||
const lockfile = await readWantedLockfile(lockfileDir, { ignoreIncompatible: true })
|
||||
if (lockfile == null) {
|
||||
throw new PnpmError('AUDIT_NO_LOCKFILE', `No ${WANTED_LOCKFILE} found: Cannot audit a project without a lockfile`)
|
||||
}
|
||||
@@ -156,6 +157,7 @@ export async function handler (
|
||||
timeout: opts.fetchTimeout,
|
||||
},
|
||||
include,
|
||||
lockfileDir,
|
||||
registry: opts.registries.default,
|
||||
retry: {
|
||||
factor: opts.fetchRetryFactor,
|
||||
|
||||
6
pnpm-lock.yaml
generated
6
pnpm-lock.yaml
generated
@@ -1576,6 +1576,9 @@ importers:
|
||||
'@pnpm/lockfile-walker':
|
||||
specifier: workspace:*
|
||||
version: link:../lockfile-walker
|
||||
'@pnpm/read-project-manifest':
|
||||
specifier: workspace:*
|
||||
version: link:../../pkg-manifest/read-project-manifest
|
||||
'@pnpm/types':
|
||||
specifier: workspace:*
|
||||
version: link:../../packages/types
|
||||
@@ -1592,6 +1595,9 @@ importers:
|
||||
'@pnpm/lockfile-file':
|
||||
specifier: workspace:*
|
||||
version: link:../lockfile-file
|
||||
'@pnpm/test-fixtures':
|
||||
specifier: workspace:*
|
||||
version: link:../../__utils__/test-fixtures
|
||||
'@types/ramda':
|
||||
specifier: 0.28.15
|
||||
version: 0.28.15
|
||||
|
||||
Reference in New Issue
Block a user