@pnpm/deps.compliance.commands 1101.1.11 → 1101.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/audit/audit.d.ts +5 -1
- package/lib/audit/audit.js +35 -31
- package/lib/audit/auditContext.d.ts +32 -0
- package/lib/audit/auditContext.js +43 -0
- package/lib/audit/signatures.d.ts +5 -0
- package/lib/audit/signatures.js +69 -0
- package/lib/sbom/sbom.d.ts +1 -0
- package/lib/sbom/sbom.js +22 -0
- package/package.json +29 -27
package/lib/audit/audit.d.ts
CHANGED
|
@@ -18,9 +18,13 @@ export type AuditOptions = Pick<UniversalOptions, 'dir'> & {
|
|
|
18
18
|
registries: Registries;
|
|
19
19
|
ignore?: string[];
|
|
20
20
|
ignoreUnfixable?: boolean;
|
|
21
|
-
} & Pick<Config, 'auditConfig' | 'auditLevel' | 'minimumReleaseAge' | 'ca' | 'cert' | 'httpProxy' | 'httpsProxy' | 'key' | 'localAddress' | 'maxSockets' | 'noProxy' | 'strictSsl' | 'fetchRetries' | 'fetchRetryMaxtimeout' | 'fetchRetryMintimeout' | 'fetchRetryFactor' | 'fetchTimeout' | 'production' | 'dev' | 'overrides' | 'optional' | 'configByUri' | 'virtualStoreDirMaxLength' | 'workspaceDir'> & Pick<ConfigContext, 'rootProjectManifest' | 'rootProjectManifestDir'> & InstallCommandOptions;
|
|
21
|
+
} & Pick<Config, 'auditConfig' | 'auditLevel' | 'minimumReleaseAge' | 'ca' | 'cert' | 'httpProxy' | 'httpsProxy' | 'key' | 'localAddress' | 'maxSockets' | 'networkConcurrency' | 'noProxy' | 'strictSsl' | 'fetchRetries' | 'fetchRetryMaxtimeout' | 'fetchRetryMintimeout' | 'fetchRetryFactor' | 'fetchTimeout' | 'production' | 'dev' | 'overrides' | 'optional' | 'configByUri' | 'virtualStoreDirMaxLength' | 'workspaceDir'> & Pick<ConfigContext, 'rootProjectManifest' | 'rootProjectManifestDir'> & InstallCommandOptions;
|
|
22
22
|
export declare function handler(opts: AuditOptions): Promise<{
|
|
23
23
|
exitCode: number;
|
|
24
24
|
output: string;
|
|
25
25
|
}>;
|
|
26
|
+
export declare function handler(opts: AuditOptions, params: string[]): Promise<{
|
|
27
|
+
exitCode: number;
|
|
28
|
+
output: string;
|
|
29
|
+
}>;
|
|
26
30
|
export declare function formatFixWithUpdateOutput(result: FixWithUpdateResult, auditReport: AuditReport): string;
|
package/lib/audit/audit.js
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import { docsUrl, TABLE_OPTIONS } from '@pnpm/cli.utils';
|
|
2
2
|
import { types as allTypes } from '@pnpm/config.reader';
|
|
3
|
-
import { WANTED_LOCKFILE } from '@pnpm/constants';
|
|
4
3
|
import { audit, normalizeGhsaId } from '@pnpm/deps.compliance.audit';
|
|
5
4
|
import { PnpmError } from '@pnpm/error';
|
|
6
5
|
import { update } from '@pnpm/installing.commands';
|
|
7
|
-
import { readEnvLockfile, readWantedLockfile } from '@pnpm/lockfile.fs';
|
|
8
6
|
import { globalInfo } from '@pnpm/logger';
|
|
9
7
|
import { createGetAuthHeaderByURI } from '@pnpm/network.auth-header';
|
|
10
8
|
import { table } from '@zkochan/table';
|
|
@@ -12,10 +10,12 @@ import chalk, {} from 'chalk';
|
|
|
12
10
|
import enquirer from 'enquirer';
|
|
13
11
|
import { pick, pickBy } from 'ramda';
|
|
14
12
|
import { renderHelp } from 'render-help';
|
|
13
|
+
import { createAuditNetworkOptions, loadAuditContext } from './auditContext.js';
|
|
15
14
|
import { fix } from './fix.js';
|
|
16
15
|
import { fixWithUpdate } from './fixWithUpdate.js';
|
|
17
16
|
import { getAuditFixChoices } from './getAuditFixChoices.js';
|
|
18
17
|
import { ignore } from './ignore.js';
|
|
18
|
+
import { auditSignatures } from './signatures.js';
|
|
19
19
|
const AUDIT_LEVEL_NUMBER = {
|
|
20
20
|
info: 0,
|
|
21
21
|
low: 1,
|
|
@@ -80,6 +80,15 @@ export function help() {
|
|
|
80
80
|
return renderHelp({
|
|
81
81
|
description: 'Checks for known security issues with the installed packages.',
|
|
82
82
|
descriptionLists: [
|
|
83
|
+
{
|
|
84
|
+
title: 'Commands',
|
|
85
|
+
list: [
|
|
86
|
+
{
|
|
87
|
+
description: 'Verify ECDSA registry signatures for installed packages from registries that provide signing keys at /-/npm/v1/keys.',
|
|
88
|
+
name: 'signatures',
|
|
89
|
+
},
|
|
90
|
+
],
|
|
91
|
+
},
|
|
83
92
|
{
|
|
84
93
|
title: 'Options',
|
|
85
94
|
list: [
|
|
@@ -130,48 +139,43 @@ export function help() {
|
|
|
130
139
|
},
|
|
131
140
|
],
|
|
132
141
|
url: docsUrl('audit'),
|
|
133
|
-
usages: ['pnpm audit [options]'],
|
|
142
|
+
usages: ['pnpm audit [options]', 'pnpm audit signatures [options]'],
|
|
134
143
|
});
|
|
135
144
|
}
|
|
136
145
|
const DEFAULT_FIX_METHOD = 'override';
|
|
137
|
-
export async function handler(opts) {
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
146
|
+
export async function handler(opts, params = []) {
|
|
147
|
+
if (params.length > 0) {
|
|
148
|
+
if (params[0] === 'signatures') {
|
|
149
|
+
if (params.length > 1) {
|
|
150
|
+
throw new PnpmError('AUDIT_UNKNOWN_SUBCOMMAND', `Unknown audit subcommand: ${params.slice(0, 2).join(' ')}`);
|
|
151
|
+
}
|
|
152
|
+
return auditSignatures(opts);
|
|
153
|
+
}
|
|
154
|
+
throw new PnpmError('AUDIT_UNKNOWN_SUBCOMMAND', `Unknown audit subcommand: ${params[0]}`);
|
|
142
155
|
}
|
|
143
|
-
const envLockfile = await
|
|
144
|
-
const
|
|
145
|
-
dependencies: opts.production !== false,
|
|
146
|
-
devDependencies: opts.dev !== false,
|
|
147
|
-
optionalDependencies: opts.optional !== false,
|
|
148
|
-
};
|
|
156
|
+
const { envLockfile, include, lockfile } = await loadAuditContext(opts);
|
|
157
|
+
const networkOptions = createAuditNetworkOptions(opts);
|
|
149
158
|
let auditReport;
|
|
150
159
|
const getAuthHeader = createGetAuthHeaderByURI(opts.configByUri, opts.registries?.default);
|
|
151
160
|
try {
|
|
152
161
|
auditReport = await audit(lockfile, getAuthHeader, {
|
|
153
162
|
dispatcherOptions: {
|
|
154
|
-
ca:
|
|
155
|
-
cert:
|
|
156
|
-
httpProxy:
|
|
157
|
-
httpsProxy:
|
|
158
|
-
key:
|
|
159
|
-
localAddress:
|
|
160
|
-
maxSockets:
|
|
161
|
-
noProxy:
|
|
162
|
-
strictSsl:
|
|
163
|
-
timeout:
|
|
163
|
+
ca: networkOptions.ca,
|
|
164
|
+
cert: networkOptions.cert,
|
|
165
|
+
httpProxy: networkOptions.httpProxy,
|
|
166
|
+
httpsProxy: networkOptions.httpsProxy,
|
|
167
|
+
key: networkOptions.key,
|
|
168
|
+
localAddress: networkOptions.localAddress,
|
|
169
|
+
maxSockets: networkOptions.maxSockets,
|
|
170
|
+
noProxy: networkOptions.noProxy,
|
|
171
|
+
strictSsl: networkOptions.strictSsl,
|
|
172
|
+
timeout: networkOptions.fetchTimeout,
|
|
164
173
|
},
|
|
165
174
|
envLockfile,
|
|
166
175
|
include,
|
|
167
176
|
registry: opts.registries.default,
|
|
168
|
-
retry:
|
|
169
|
-
|
|
170
|
-
maxTimeout: opts.fetchRetryMaxtimeout,
|
|
171
|
-
minTimeout: opts.fetchRetryMintimeout,
|
|
172
|
-
retries: opts.fetchRetries,
|
|
173
|
-
},
|
|
174
|
-
timeout: opts.fetchTimeout,
|
|
177
|
+
retry: networkOptions.retry,
|
|
178
|
+
timeout: networkOptions.fetchTimeout,
|
|
175
179
|
});
|
|
176
180
|
}
|
|
177
181
|
catch (err) { // eslint-disable-line
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { EnvLockfile, LockfileObject } from '@pnpm/lockfile.types';
|
|
2
|
+
import type { DependenciesField } from '@pnpm/types';
|
|
3
|
+
import type { AuditOptions } from './audit.js';
|
|
4
|
+
export interface AuditContext {
|
|
5
|
+
envLockfile: EnvLockfile | null;
|
|
6
|
+
include: {
|
|
7
|
+
[dependenciesField in DependenciesField]: boolean;
|
|
8
|
+
};
|
|
9
|
+
lockfile: LockfileObject;
|
|
10
|
+
lockfileDir: string;
|
|
11
|
+
}
|
|
12
|
+
export interface AuditNetworkOptions {
|
|
13
|
+
ca: AuditOptions['ca'];
|
|
14
|
+
cert: AuditOptions['cert'];
|
|
15
|
+
configByUri: AuditOptions['configByUri'];
|
|
16
|
+
fetchTimeout: AuditOptions['fetchTimeout'];
|
|
17
|
+
httpProxy: AuditOptions['httpProxy'];
|
|
18
|
+
httpsProxy: AuditOptions['httpsProxy'];
|
|
19
|
+
key: AuditOptions['key'];
|
|
20
|
+
localAddress: AuditOptions['localAddress'];
|
|
21
|
+
maxSockets: AuditOptions['maxSockets'];
|
|
22
|
+
noProxy: AuditOptions['noProxy'];
|
|
23
|
+
retry: {
|
|
24
|
+
factor: AuditOptions['fetchRetryFactor'];
|
|
25
|
+
maxTimeout: AuditOptions['fetchRetryMaxtimeout'];
|
|
26
|
+
minTimeout: AuditOptions['fetchRetryMintimeout'];
|
|
27
|
+
retries: AuditOptions['fetchRetries'];
|
|
28
|
+
};
|
|
29
|
+
strictSsl: AuditOptions['strictSsl'];
|
|
30
|
+
}
|
|
31
|
+
export declare function loadAuditContext(opts: AuditOptions): Promise<AuditContext>;
|
|
32
|
+
export declare function createAuditNetworkOptions(opts: AuditOptions): AuditNetworkOptions;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { WANTED_LOCKFILE } from '@pnpm/constants';
|
|
2
|
+
import { PnpmError } from '@pnpm/error';
|
|
3
|
+
import { readEnvLockfile, readWantedLockfile } from '@pnpm/lockfile.fs';
|
|
4
|
+
export async function loadAuditContext(opts) {
|
|
5
|
+
const lockfileDir = opts.lockfileDir ?? opts.dir;
|
|
6
|
+
const lockfile = await readWantedLockfile(lockfileDir, { ignoreIncompatible: true });
|
|
7
|
+
if (lockfile == null) {
|
|
8
|
+
throw new PnpmError('AUDIT_NO_LOCKFILE', `No ${WANTED_LOCKFILE} found: Cannot audit a project without a lockfile`);
|
|
9
|
+
}
|
|
10
|
+
const envLockfile = await readEnvLockfile(opts.workspaceDir ?? lockfileDir);
|
|
11
|
+
return {
|
|
12
|
+
envLockfile,
|
|
13
|
+
include: {
|
|
14
|
+
dependencies: opts.production !== false,
|
|
15
|
+
devDependencies: opts.dev !== false,
|
|
16
|
+
optionalDependencies: opts.optional !== false,
|
|
17
|
+
},
|
|
18
|
+
lockfile,
|
|
19
|
+
lockfileDir,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
export function createAuditNetworkOptions(opts) {
|
|
23
|
+
return {
|
|
24
|
+
ca: opts.ca,
|
|
25
|
+
cert: opts.cert,
|
|
26
|
+
configByUri: opts.configByUri,
|
|
27
|
+
fetchTimeout: opts.fetchTimeout,
|
|
28
|
+
httpProxy: opts.httpProxy,
|
|
29
|
+
httpsProxy: opts.httpsProxy,
|
|
30
|
+
key: opts.key,
|
|
31
|
+
localAddress: opts.localAddress,
|
|
32
|
+
maxSockets: opts.maxSockets,
|
|
33
|
+
noProxy: opts.noProxy,
|
|
34
|
+
retry: {
|
|
35
|
+
factor: opts.fetchRetryFactor,
|
|
36
|
+
maxTimeout: opts.fetchRetryMaxtimeout,
|
|
37
|
+
minTimeout: opts.fetchRetryMintimeout,
|
|
38
|
+
retries: opts.fetchRetries,
|
|
39
|
+
},
|
|
40
|
+
strictSsl: opts.strictSsl,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=auditContext.js.map
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { TABLE_OPTIONS } from '@pnpm/cli.utils';
|
|
2
|
+
import { pickRegistryForPackage } from '@pnpm/config.pick-registry-for-package';
|
|
3
|
+
import { lockfileToAuditRequest } from '@pnpm/deps.compliance.audit';
|
|
4
|
+
import { verifySignatures } from '@pnpm/deps.security.signatures';
|
|
5
|
+
import { PnpmError } from '@pnpm/error';
|
|
6
|
+
import { createGetAuthHeaderByURI } from '@pnpm/network.auth-header';
|
|
7
|
+
import { table } from '@zkochan/table';
|
|
8
|
+
import chalk from 'chalk';
|
|
9
|
+
import { createAuditNetworkOptions, loadAuditContext } from './auditContext.js';
|
|
10
|
+
export async function auditSignatures(opts) {
|
|
11
|
+
const { envLockfile, include, lockfile } = await loadAuditContext(opts);
|
|
12
|
+
const auditRequest = lockfileToAuditRequest(lockfile, { envLockfile, include });
|
|
13
|
+
const packages = Object.entries(auditRequest.request).flatMap(([name, versions]) => (versions.map((version) => ({ name, registry: pickRegistryForPackage(opts.registries, name), version }))));
|
|
14
|
+
if (packages.length === 0) {
|
|
15
|
+
throw new PnpmError('AUDIT_NO_PACKAGES', 'No installed packages found to audit');
|
|
16
|
+
}
|
|
17
|
+
const getAuthHeader = createGetAuthHeaderByURI(opts.configByUri, opts.registries?.default);
|
|
18
|
+
const networkOptions = createAuditNetworkOptions(opts);
|
|
19
|
+
const result = await verifySignatures(packages, getAuthHeader, {
|
|
20
|
+
ca: networkOptions.ca,
|
|
21
|
+
cert: networkOptions.cert,
|
|
22
|
+
configByUri: networkOptions.configByUri,
|
|
23
|
+
httpProxy: networkOptions.httpProxy,
|
|
24
|
+
httpsProxy: networkOptions.httpsProxy,
|
|
25
|
+
key: networkOptions.key,
|
|
26
|
+
localAddress: networkOptions.localAddress,
|
|
27
|
+
maxSockets: networkOptions.maxSockets,
|
|
28
|
+
networkConcurrency: opts.networkConcurrency,
|
|
29
|
+
noProxy: networkOptions.noProxy,
|
|
30
|
+
retry: networkOptions.retry,
|
|
31
|
+
strictSsl: networkOptions.strictSsl,
|
|
32
|
+
timeout: networkOptions.fetchTimeout,
|
|
33
|
+
});
|
|
34
|
+
return {
|
|
35
|
+
exitCode: result.invalid.length > 0 || result.missing.length > 0 ? 1 : 0,
|
|
36
|
+
output: opts.json ? JSON.stringify(result, null, 2) : renderSignatureVerificationResult(result),
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
function renderSignatureVerificationResult(result) {
|
|
40
|
+
const lines = [];
|
|
41
|
+
lines.push(`audited ${result.audited} package${result.audited === 1 ? '' : 's'}`);
|
|
42
|
+
lines.push('');
|
|
43
|
+
if (result.verified > 0) {
|
|
44
|
+
lines.push(`${result.verified} package${result.verified === 1 ? ' has a' : 's have'} ${chalk.bold('verified')} registry signature${result.verified === 1 ? '' : 's'}`);
|
|
45
|
+
lines.push('');
|
|
46
|
+
}
|
|
47
|
+
if (result.missing.length > 0) {
|
|
48
|
+
lines.push(`${result.missing.length} package${result.missing.length === 1 ? ' is' : 's are'} ${chalk.redBright('missing')} registry signature${result.missing.length === 1 ? '' : 's'} but the registry is providing signing keys:`);
|
|
49
|
+
lines.push('');
|
|
50
|
+
lines.push(table(result.missing.map(({ name, registry, version }) => [chalk.red(`${name}@${version}`), registry]), TABLE_OPTIONS));
|
|
51
|
+
lines.push('');
|
|
52
|
+
}
|
|
53
|
+
if (result.invalid.length > 0) {
|
|
54
|
+
lines.push(`${result.invalid.length} package${result.invalid.length === 1 ? ' has an' : 's have'} ${chalk.redBright('invalid')} registry signature${result.invalid.length === 1 ? '' : 's'}:`);
|
|
55
|
+
lines.push('');
|
|
56
|
+
lines.push(table(result.invalid.map(({ name, reason, registry, version }) => [chalk.red(`${name}@${version}`), registry, reason ?? 'Invalid registry signature']), TABLE_OPTIONS));
|
|
57
|
+
lines.push('');
|
|
58
|
+
lines.push(result.invalid.length === 1
|
|
59
|
+
? 'Someone might have tampered with this package since it was published on the registry!'
|
|
60
|
+
: 'Someone might have tampered with these packages since they were published on the registry!');
|
|
61
|
+
lines.push('');
|
|
62
|
+
}
|
|
63
|
+
if (result.audited === 0 && result.invalid.length === 0 && result.missing.length === 0 && result.verified === 0) {
|
|
64
|
+
lines.push('No dependencies were installed from a registry with signing keys');
|
|
65
|
+
lines.push('');
|
|
66
|
+
}
|
|
67
|
+
return lines.join('\n');
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=signatures.js.map
|
package/lib/sbom/sbom.d.ts
CHANGED
package/lib/sbom/sbom.js
CHANGED
|
@@ -18,6 +18,7 @@ export const cliOptionsTypes = () => ({
|
|
|
18
18
|
recursive: Boolean,
|
|
19
19
|
'sbom-format': String,
|
|
20
20
|
'sbom-type': String,
|
|
21
|
+
'sbom-spec-version': String,
|
|
21
22
|
'sbom-authors': String,
|
|
22
23
|
'sbom-supplier': String,
|
|
23
24
|
'lockfile-only': Boolean,
|
|
@@ -42,6 +43,10 @@ export function help() {
|
|
|
42
43
|
description: 'The component type for the root package (default: library)',
|
|
43
44
|
name: '--sbom-type <library|application>',
|
|
44
45
|
},
|
|
46
|
+
{
|
|
47
|
+
description: 'The CycloneDX specification version (1.5, 1.6, or 1.7; default: 1.7)',
|
|
48
|
+
name: '--sbom-spec-version <version>',
|
|
49
|
+
},
|
|
45
50
|
{
|
|
46
51
|
description: 'Only use lockfile data (skip reading from the store)',
|
|
47
52
|
name: '--lockfile-only',
|
|
@@ -90,6 +95,7 @@ export async function handler(opts, _params = []) {
|
|
|
90
95
|
throw new PnpmError('SBOM_INVALID_FORMAT', `Invalid SBOM format "${opts.sbomFormat}". Use "cyclonedx" or "spdx".`);
|
|
91
96
|
}
|
|
92
97
|
const sbomType = validateSbomType(opts.sbomType);
|
|
98
|
+
const sbomSpecVersion = validateSbomSpecVersion(opts.sbomSpecVersion, format);
|
|
93
99
|
const lockfile = await readWantedLockfile(opts.lockfileDir ?? opts.dir, {
|
|
94
100
|
ignoreIncompatible: true,
|
|
95
101
|
});
|
|
@@ -153,6 +159,7 @@ export async function handler(opts, _params = []) {
|
|
|
153
159
|
lockfileOnly: opts.lockfileOnly,
|
|
154
160
|
sbomAuthors: opts.sbomAuthors?.split(',').map((s) => s.trim()).filter(Boolean),
|
|
155
161
|
sbomSupplier: opts.sbomSupplier,
|
|
162
|
+
specVersion: sbomSpecVersion,
|
|
156
163
|
})
|
|
157
164
|
: serializeSpdx(result);
|
|
158
165
|
return { output, exitCode: 0 };
|
|
@@ -164,4 +171,19 @@ function validateSbomType(value) {
|
|
|
164
171
|
return 'application';
|
|
165
172
|
throw new PnpmError('SBOM_INVALID_TYPE', `Invalid SBOM type "${value}". Use "library" or "application".`);
|
|
166
173
|
}
|
|
174
|
+
// Versions whose schema is fully covered by what we currently emit
|
|
175
|
+
// (e.g. metadata.lifecycles requires CycloneDX 1.5+).
|
|
176
|
+
const SUPPORTED_CYCLONEDX_SPEC_VERSIONS = ['1.5', '1.6', '1.7'];
|
|
177
|
+
function validateSbomSpecVersion(value, format) {
|
|
178
|
+
if (value == null)
|
|
179
|
+
return undefined;
|
|
180
|
+
if (format !== 'cyclonedx') {
|
|
181
|
+
throw new PnpmError('SBOM_SPEC_VERSION_UNSUPPORTED_FORMAT', 'The --sbom-spec-version option is only supported with --sbom-format cyclonedx.');
|
|
182
|
+
}
|
|
183
|
+
const normalized = value.trim();
|
|
184
|
+
if (!SUPPORTED_CYCLONEDX_SPEC_VERSIONS.includes(normalized)) {
|
|
185
|
+
throw new PnpmError('SBOM_INVALID_SPEC_VERSION', `Invalid CycloneDX spec version "${value}". Supported versions: ${SUPPORTED_CYCLONEDX_SPEC_VERSIONS.join(', ')}.`);
|
|
186
|
+
}
|
|
187
|
+
return normalized;
|
|
188
|
+
}
|
|
167
189
|
//# sourceMappingURL=sbom.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pnpm/deps.compliance.commands",
|
|
3
|
-
"version": "1101.
|
|
3
|
+
"version": "1101.2.0",
|
|
4
4
|
"description": "pnpm commands for audit, licenses, and sbom",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pnpm",
|
|
@@ -28,37 +28,39 @@
|
|
|
28
28
|
],
|
|
29
29
|
"dependencies": {
|
|
30
30
|
"@zkochan/table": "^2.0.1",
|
|
31
|
-
"chalk": "^5.6.
|
|
31
|
+
"chalk": "^5.6.0",
|
|
32
32
|
"enquirer": "^2.4.1",
|
|
33
33
|
"memoize": "^10.2.0",
|
|
34
34
|
"ramda": "npm:@pnpm/ramda@0.28.1",
|
|
35
35
|
"render-help": "^2.0.0",
|
|
36
|
-
"semver": "^7.7.
|
|
37
|
-
"@pnpm/cli.command": "1100.0.1",
|
|
38
|
-
"@pnpm/cli.meta": "1100.0.2",
|
|
36
|
+
"semver": "^7.7.2",
|
|
39
37
|
"@pnpm/cli.common-cli-options-help": "1100.0.1",
|
|
40
|
-
"@pnpm/cli.
|
|
41
|
-
"@pnpm/
|
|
38
|
+
"@pnpm/cli.meta": "1100.0.3",
|
|
39
|
+
"@pnpm/cli.utils": "1101.0.3",
|
|
40
|
+
"@pnpm/config.pick-registry-for-package": "1100.0.3",
|
|
41
|
+
"@pnpm/config.writer": "1100.0.7",
|
|
42
|
+
"@pnpm/config.reader": "1101.3.0",
|
|
42
43
|
"@pnpm/constants": "1100.0.0",
|
|
43
|
-
"@pnpm/
|
|
44
|
-
"@pnpm/deps.compliance.audit": "1101.0.5",
|
|
44
|
+
"@pnpm/cli.command": "1100.0.1",
|
|
45
45
|
"@pnpm/deps.compliance.license-resolver": "1100.0.0",
|
|
46
|
-
"@pnpm/deps.compliance.
|
|
47
|
-
"@pnpm/deps.compliance.sbom": "1100.0
|
|
46
|
+
"@pnpm/deps.compliance.audit": "1101.0.6",
|
|
47
|
+
"@pnpm/deps.compliance.sbom": "1100.1.0",
|
|
48
48
|
"@pnpm/error": "1100.0.0",
|
|
49
|
-
"@pnpm/
|
|
50
|
-
"@pnpm/
|
|
51
|
-
"@pnpm/lockfile.
|
|
52
|
-
"@pnpm/
|
|
53
|
-
"@pnpm/lockfile.
|
|
54
|
-
"@pnpm/object.key-sorting": "1100.0.0",
|
|
55
|
-
"@pnpm/network.auth-header": "1100.0.1",
|
|
49
|
+
"@pnpm/deps.compliance.license-scanner": "1100.0.10",
|
|
50
|
+
"@pnpm/installing.commands": "1100.2.0",
|
|
51
|
+
"@pnpm/lockfile.fs": "1100.0.7",
|
|
52
|
+
"@pnpm/deps.security.signatures": "1101.1.0",
|
|
53
|
+
"@pnpm/lockfile.utils": "1100.0.7",
|
|
56
54
|
"@pnpm/store.path": "1100.0.1",
|
|
57
|
-
"@pnpm/
|
|
58
|
-
"@pnpm/
|
|
55
|
+
"@pnpm/network.auth-header": "1100.0.2",
|
|
56
|
+
"@pnpm/types": "1101.1.0",
|
|
57
|
+
"@pnpm/workspace.project-manifest-reader": "1100.0.4",
|
|
58
|
+
"@pnpm/lockfile.types": "1100.0.5",
|
|
59
|
+
"@pnpm/lockfile.walker": "1100.0.5",
|
|
60
|
+
"@pnpm/object.key-sorting": "1100.0.0"
|
|
59
61
|
},
|
|
60
62
|
"peerDependencies": {
|
|
61
|
-
"@pnpm/logger": "
|
|
63
|
+
"@pnpm/logger": ">=1001.0.0 <1002.0.0"
|
|
62
64
|
},
|
|
63
65
|
"devDependencies": {
|
|
64
66
|
"@jest/globals": "30.3.0",
|
|
@@ -70,14 +72,14 @@
|
|
|
70
72
|
"nock": "13.3.4",
|
|
71
73
|
"read-yaml-file": "^3.0.0",
|
|
72
74
|
"tempy": "3.0.0",
|
|
75
|
+
"@pnpm/deps.compliance.commands": "1101.2.0",
|
|
73
76
|
"@pnpm/logger": "1100.0.0",
|
|
74
|
-
"@pnpm/
|
|
75
|
-
"@pnpm/pkg-manifest.reader": "1100.0.2",
|
|
76
|
-
"@pnpm/prepare": "1100.0.6",
|
|
77
|
-
"@pnpm/test-fixtures": "1100.0.0",
|
|
77
|
+
"@pnpm/prepare": "1100.0.7",
|
|
78
78
|
"@pnpm/testing.command-defaults": "1100.0.1",
|
|
79
|
-
"@pnpm/testing.mock-agent": "1100.0.
|
|
80
|
-
"@pnpm/
|
|
79
|
+
"@pnpm/testing.mock-agent": "1100.0.3",
|
|
80
|
+
"@pnpm/test-fixtures": "1100.0.0",
|
|
81
|
+
"@pnpm/workspace.projects-filter": "1100.0.10",
|
|
82
|
+
"@pnpm/pkg-manifest.reader": "1100.0.3"
|
|
81
83
|
},
|
|
82
84
|
"engines": {
|
|
83
85
|
"node": ">=22.13"
|