@pnpm/cli.default-reporter 1002.0.11
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/LICENSE +22 -0
- package/README.md +41 -0
- package/lib/constants.d.ts +1 -0
- package/lib/constants.js +4 -0
- package/lib/index.d.ts +54 -0
- package/lib/index.js +230 -0
- package/lib/mergeOutputs.d.ts +4 -0
- package/lib/mergeOutputs.js +69 -0
- package/lib/reportError.d.ts +3 -0
- package/lib/reportError.js +425 -0
- package/lib/reporterForClient/index.d.ts +52 -0
- package/lib/reporterForClient/index.js +94 -0
- package/lib/reporterForClient/outputConstants.d.ts +4 -0
- package/lib/reporterForClient/outputConstants.js +6 -0
- package/lib/reporterForClient/pkgsDiff.d.ts +36 -0
- package/lib/reporterForClient/pkgsDiff.js +113 -0
- package/lib/reporterForClient/reportBigTarballsProgress.d.ts +8 -0
- package/lib/reporterForClient/reportBigTarballsProgress.js +26 -0
- package/lib/reporterForClient/reportContext.d.ts +10 -0
- package/lib/reporterForClient/reportContext.js +34 -0
- package/lib/reporterForClient/reportDeprecations.d.ts +11 -0
- package/lib/reporterForClient/reportDeprecations.js +27 -0
- package/lib/reporterForClient/reportExecutionTime.d.ts +6 -0
- package/lib/reporterForClient/reportExecutionTime.js +13 -0
- package/lib/reporterForClient/reportHooks.d.ts +8 -0
- package/lib/reporterForClient/reportHooks.js +12 -0
- package/lib/reporterForClient/reportIgnoredBuilds.d.ts +11 -0
- package/lib/reporterForClient/reportIgnoredBuilds.js +21 -0
- package/lib/reporterForClient/reportInstallChecks.d.ts +7 -0
- package/lib/reporterForClient/reportInstallChecks.js +19 -0
- package/lib/reporterForClient/reportInstallingConfigDeps.d.ts +5 -0
- package/lib/reporterForClient/reportInstallingConfigDeps.js +18 -0
- package/lib/reporterForClient/reportLifecycleScripts.d.ts +13 -0
- package/lib/reporterForClient/reportLifecycleScripts.js +193 -0
- package/lib/reporterForClient/reportMisc.d.ts +17 -0
- package/lib/reporterForClient/reportMisc.js +69 -0
- package/lib/reporterForClient/reportPeerDependencyIssues.d.ts +7 -0
- package/lib/reporterForClient/reportPeerDependencyIssues.js +16 -0
- package/lib/reporterForClient/reportProgress.d.ts +16 -0
- package/lib/reporterForClient/reportProgress.js +123 -0
- package/lib/reporterForClient/reportRequestRetry.d.ts +5 -0
- package/lib/reporterForClient/reportRequestRetry.js +15 -0
- package/lib/reporterForClient/reportScope.d.ts +8 -0
- package/lib/reporterForClient/reportScope.js +41 -0
- package/lib/reporterForClient/reportSkippedOptionalDependencies.d.ts +7 -0
- package/lib/reporterForClient/reportSkippedOptionalDependencies.js +8 -0
- package/lib/reporterForClient/reportStats.d.ts +13 -0
- package/lib/reporterForClient/reportStats.js +143 -0
- package/lib/reporterForClient/reportSummary.d.ts +19 -0
- package/lib/reporterForClient/reportSummary.js +79 -0
- package/lib/reporterForClient/reportUpdateCheck.d.ts +8 -0
- package/lib/reporterForClient/reportUpdateCheck.js +42 -0
- package/lib/reporterForClient/utils/formatPrefix.d.ts +2 -0
- package/lib/reporterForClient/utils/formatPrefix.js +19 -0
- package/lib/reporterForClient/utils/formatWarn.d.ts +1 -0
- package/lib/reporterForClient/utils/formatWarn.js +8 -0
- package/lib/reporterForClient/utils/zooming.d.ts +4 -0
- package/lib/reporterForClient/utils/zooming.js +13 -0
- package/package.json +76 -0
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { PeerDependencyIssuesLog } from '@pnpm/core-loggers';
|
|
2
|
+
import * as Rx from 'rxjs';
|
|
3
|
+
export declare function reportPeerDependencyIssues(log$: {
|
|
4
|
+
peerDependencyIssues: Rx.Observable<PeerDependencyIssuesLog>;
|
|
5
|
+
}): Rx.Observable<Rx.Observable<{
|
|
6
|
+
msg: string;
|
|
7
|
+
}>>;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { renderPeerIssues } from '@pnpm/installing.render-peer-issues';
|
|
2
|
+
import * as Rx from 'rxjs';
|
|
3
|
+
import { map, take } from 'rxjs/operators';
|
|
4
|
+
import { formatWarn } from './utils/formatWarn.js';
|
|
5
|
+
export function reportPeerDependencyIssues(log$) {
|
|
6
|
+
return log$.peerDependencyIssues.pipe(take(1), map((log) => {
|
|
7
|
+
const renderedPeerIssues = renderPeerIssues(log.issuesByProjects);
|
|
8
|
+
if (!renderedPeerIssues) {
|
|
9
|
+
return Rx.NEVER;
|
|
10
|
+
}
|
|
11
|
+
return Rx.of({
|
|
12
|
+
msg: `${formatWarn('Issues with peer dependencies found')}\n${renderedPeerIssues}`,
|
|
13
|
+
});
|
|
14
|
+
}));
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=reportPeerDependencyIssues.js.map
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { ProgressLog, StageLog } from '@pnpm/core-loggers';
|
|
2
|
+
import * as Rx from 'rxjs';
|
|
3
|
+
export interface StatusMessage {
|
|
4
|
+
msg: string;
|
|
5
|
+
fixed: boolean;
|
|
6
|
+
done?: boolean;
|
|
7
|
+
}
|
|
8
|
+
export declare function reportProgress(log$: {
|
|
9
|
+
progress: Rx.Observable<ProgressLog>;
|
|
10
|
+
stage: Rx.Observable<StageLog>;
|
|
11
|
+
}, opts: {
|
|
12
|
+
cwd: string;
|
|
13
|
+
throttle?: Rx.OperatorFunction<any, any>;
|
|
14
|
+
hideAddedPkgsProgress?: boolean;
|
|
15
|
+
hideProgressPrefix?: boolean;
|
|
16
|
+
}): Rx.Observable<Rx.Observable<StatusMessage>>;
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import * as Rx from 'rxjs';
|
|
2
|
+
import { filter, map, mapTo, startWith, take, takeWhile } from 'rxjs/operators';
|
|
3
|
+
import { hlValue } from './outputConstants.js';
|
|
4
|
+
import { zoomOut } from './utils/zooming.js';
|
|
5
|
+
export function reportProgress(log$, opts) {
|
|
6
|
+
const progressOutput = throttledProgressOutput.bind(null, opts);
|
|
7
|
+
return getModulesInstallProgress$(log$.stage, log$.progress).pipe(map(opts.hideProgressPrefix
|
|
8
|
+
? ({ importingDone$, progress$ }) => progressOutput(importingDone$, progress$)
|
|
9
|
+
: ({ importingDone$, progress$, requirer }) => {
|
|
10
|
+
const output$ = progressOutput(importingDone$, progress$);
|
|
11
|
+
if (requirer === opts.cwd) {
|
|
12
|
+
return output$;
|
|
13
|
+
}
|
|
14
|
+
return output$.pipe(map((msg) => {
|
|
15
|
+
msg['msg'] = zoomOut(opts.cwd, requirer, msg['msg']);
|
|
16
|
+
return msg;
|
|
17
|
+
}));
|
|
18
|
+
}));
|
|
19
|
+
}
|
|
20
|
+
function throttledProgressOutput(opts, importingDone$, progress$) {
|
|
21
|
+
if (opts.throttle != null) {
|
|
22
|
+
progress$ = progress$.pipe(opts.throttle);
|
|
23
|
+
}
|
|
24
|
+
const combinedProgress = Rx.combineLatest(progress$, importingDone$)
|
|
25
|
+
// Avoid logs after all resolved packages were downloaded.
|
|
26
|
+
// Fixing issue: https://github.com/pnpm/pnpm/issues/1028#issuecomment-364782901
|
|
27
|
+
.pipe(takeWhile(([, importingDone]) => !importingDone, true));
|
|
28
|
+
return combinedProgress.pipe(map(opts.hideAddedPkgsProgress ? createStatusMessageWithoutAdded : createStatusMessage));
|
|
29
|
+
}
|
|
30
|
+
function getModulesInstallProgress$(stage$, progress$) {
|
|
31
|
+
const modulesInstallProgressPushStream = new Rx.Subject();
|
|
32
|
+
const progressStatsPushStreamByRequirer = getProgressStatsPushStreamByRequirer(progress$);
|
|
33
|
+
const stagePushStreamByRequirer = {};
|
|
34
|
+
stage$
|
|
35
|
+
.forEach((log) => {
|
|
36
|
+
if (!stagePushStreamByRequirer[log.prefix]) {
|
|
37
|
+
stagePushStreamByRequirer[log.prefix] = new Rx.Subject();
|
|
38
|
+
if (!progressStatsPushStreamByRequirer[log.prefix]) {
|
|
39
|
+
progressStatsPushStreamByRequirer[log.prefix] = new Rx.Subject();
|
|
40
|
+
}
|
|
41
|
+
modulesInstallProgressPushStream.next({
|
|
42
|
+
importingDone$: stage$ToImportingDone$(Rx.from(stagePushStreamByRequirer[log.prefix])),
|
|
43
|
+
progress$: Rx.from(progressStatsPushStreamByRequirer[log.prefix]),
|
|
44
|
+
requirer: log.prefix,
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
stagePushStreamByRequirer[log.prefix].next(log);
|
|
48
|
+
if (log.stage === 'importing_done') {
|
|
49
|
+
progressStatsPushStreamByRequirer[log.prefix].complete();
|
|
50
|
+
stagePushStreamByRequirer[log.prefix].complete();
|
|
51
|
+
}
|
|
52
|
+
})
|
|
53
|
+
.catch(() => { });
|
|
54
|
+
return Rx.from(modulesInstallProgressPushStream);
|
|
55
|
+
}
|
|
56
|
+
function stage$ToImportingDone$(stage$) {
|
|
57
|
+
return stage$
|
|
58
|
+
.pipe(filter((log) => log.stage === 'importing_done'), mapTo(true), take(1), startWith(false));
|
|
59
|
+
}
|
|
60
|
+
function getProgressStatsPushStreamByRequirer(progress$) {
|
|
61
|
+
const progressStatsPushStreamByRequirer = {};
|
|
62
|
+
const previousProgressStatsByRequirer = {};
|
|
63
|
+
progress$
|
|
64
|
+
.forEach((log) => {
|
|
65
|
+
if (!previousProgressStatsByRequirer[log.requester]) {
|
|
66
|
+
previousProgressStatsByRequirer[log.requester] = {
|
|
67
|
+
fetched: 0,
|
|
68
|
+
imported: 0,
|
|
69
|
+
resolved: 0,
|
|
70
|
+
reused: 0,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
switch (log.status) {
|
|
74
|
+
case 'resolved':
|
|
75
|
+
previousProgressStatsByRequirer[log.requester].resolved++;
|
|
76
|
+
break;
|
|
77
|
+
case 'fetched':
|
|
78
|
+
previousProgressStatsByRequirer[log.requester].fetched++;
|
|
79
|
+
break;
|
|
80
|
+
case 'found_in_store':
|
|
81
|
+
previousProgressStatsByRequirer[log.requester].reused++;
|
|
82
|
+
break;
|
|
83
|
+
case 'imported':
|
|
84
|
+
previousProgressStatsByRequirer[log.requester].imported++;
|
|
85
|
+
break;
|
|
86
|
+
}
|
|
87
|
+
if (!progressStatsPushStreamByRequirer[log.requester]) {
|
|
88
|
+
progressStatsPushStreamByRequirer[log.requester] = new Rx.Subject();
|
|
89
|
+
}
|
|
90
|
+
progressStatsPushStreamByRequirer[log.requester].next(previousProgressStatsByRequirer[log.requester]);
|
|
91
|
+
})
|
|
92
|
+
.catch(() => { });
|
|
93
|
+
return progressStatsPushStreamByRequirer;
|
|
94
|
+
}
|
|
95
|
+
function createStatusMessage([progress, importingDone]) {
|
|
96
|
+
const msg = `Progress: resolved ${hlValue(progress.resolved.toString())}, reused ${hlValue(progress.reused.toString())}, downloaded ${hlValue(progress.fetched.toString())}, added ${hlValue(progress.imported.toString())}`;
|
|
97
|
+
if (importingDone) {
|
|
98
|
+
return {
|
|
99
|
+
done: true,
|
|
100
|
+
fixed: false,
|
|
101
|
+
msg: `${msg}, done`,
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
return {
|
|
105
|
+
fixed: true,
|
|
106
|
+
msg,
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
function createStatusMessageWithoutAdded([progress, importingDone]) {
|
|
110
|
+
const msg = `Progress: resolved ${hlValue(progress.resolved.toString())}, reused ${hlValue(progress.reused.toString())}, downloaded ${hlValue(progress.fetched.toString())}`;
|
|
111
|
+
if (importingDone) {
|
|
112
|
+
return {
|
|
113
|
+
done: true,
|
|
114
|
+
fixed: false,
|
|
115
|
+
msg: `${msg}, done`,
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
return {
|
|
119
|
+
fixed: true,
|
|
120
|
+
msg,
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
//# sourceMappingURL=reportProgress.js.map
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import prettyMilliseconds from 'pretty-ms';
|
|
2
|
+
import * as Rx from 'rxjs';
|
|
3
|
+
import { map } from 'rxjs/operators';
|
|
4
|
+
import { formatWarn } from './utils/formatWarn.js';
|
|
5
|
+
export function reportRequestRetry(requestRetry$) {
|
|
6
|
+
return requestRetry$.pipe(map((log) => {
|
|
7
|
+
const retriesLeft = log.maxRetries - log.attempt + 1;
|
|
8
|
+
const errorCode = log.error.httpStatusCode ?? log.error.status ?? log.error.errno ?? log.error.code;
|
|
9
|
+
const msg = `${log.method} ${log.url} error (${errorCode}). \
|
|
10
|
+
Will retry in ${prettyMilliseconds(log.timeout, { verbose: true })}. \
|
|
11
|
+
${retriesLeft} retries left.`;
|
|
12
|
+
return Rx.of({ msg: formatWarn(msg) });
|
|
13
|
+
}));
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=reportRequestRetry.js.map
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import * as Rx from 'rxjs';
|
|
2
|
+
import { map, take } from 'rxjs/operators';
|
|
3
|
+
const COMMANDS_THAT_REPORT_SCOPE = new Set([
|
|
4
|
+
'install',
|
|
5
|
+
'link',
|
|
6
|
+
'prune',
|
|
7
|
+
'rebuild',
|
|
8
|
+
'remove',
|
|
9
|
+
'unlink',
|
|
10
|
+
'update',
|
|
11
|
+
'run',
|
|
12
|
+
'test',
|
|
13
|
+
]);
|
|
14
|
+
export function reportScope(scope$, opts) {
|
|
15
|
+
if (!COMMANDS_THAT_REPORT_SCOPE.has(opts.cmd)) {
|
|
16
|
+
return Rx.NEVER;
|
|
17
|
+
}
|
|
18
|
+
return scope$.pipe(take(1), map((log) => {
|
|
19
|
+
if (log.selected === 1) {
|
|
20
|
+
return Rx.NEVER;
|
|
21
|
+
}
|
|
22
|
+
let msg = 'Scope: ';
|
|
23
|
+
if (log.selected === log.total) {
|
|
24
|
+
msg += `all ${log.total}`;
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
msg += `${log.selected}`;
|
|
28
|
+
if (log.total) {
|
|
29
|
+
msg += ` of ${log.total}`;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
if (log.workspacePrefix) {
|
|
33
|
+
msg += ' workspace projects';
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
msg += ' projects';
|
|
37
|
+
}
|
|
38
|
+
return Rx.of({ msg });
|
|
39
|
+
}));
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=reportScope.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { SkippedOptionalDependencyLog } from '@pnpm/core-loggers';
|
|
2
|
+
import * as Rx from 'rxjs';
|
|
3
|
+
export declare function reportSkippedOptionalDependencies(skippedOptionalDependency$: Rx.Observable<SkippedOptionalDependencyLog>, opts: {
|
|
4
|
+
cwd: string;
|
|
5
|
+
}): Rx.Observable<Rx.Observable<{
|
|
6
|
+
msg: string;
|
|
7
|
+
}>>;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import * as Rx from 'rxjs';
|
|
2
|
+
import { filter, map } from 'rxjs/operators';
|
|
3
|
+
export function reportSkippedOptionalDependencies(skippedOptionalDependency$, opts) {
|
|
4
|
+
return skippedOptionalDependency$.pipe(filter((log) => Boolean(log['prefix'] === opts.cwd && log.parents && log.parents.length === 0)), map((log) => Rx.of({
|
|
5
|
+
msg: `info: ${log.package.id || log.package.name && (`${log.package.name}@${log.package.version}`) || log.package.bareSpecifier} is an optional dependency and failed compatibility check. Excluding it from installation.`,
|
|
6
|
+
})));
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=reportSkippedOptionalDependencies.js.map
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { StatsLog } from '@pnpm/core-loggers';
|
|
2
|
+
import * as Rx from 'rxjs';
|
|
3
|
+
export declare function reportStats(log$: {
|
|
4
|
+
stats: Rx.Observable<StatsLog>;
|
|
5
|
+
}, opts: {
|
|
6
|
+
cmd: string;
|
|
7
|
+
cwd: string;
|
|
8
|
+
isRecursive: boolean;
|
|
9
|
+
width: number;
|
|
10
|
+
hideProgressPrefix?: boolean;
|
|
11
|
+
}): Array<Rx.Observable<Rx.Observable<{
|
|
12
|
+
msg: string;
|
|
13
|
+
}>>>;
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { repeat } from 'ramda';
|
|
3
|
+
import * as Rx from 'rxjs';
|
|
4
|
+
import { filter, map, reduce, take } from 'rxjs/operators';
|
|
5
|
+
import stringLength from 'string-length';
|
|
6
|
+
import { EOL } from '../constants.js';
|
|
7
|
+
import { ADDED_CHAR, REMOVED_CHAR, } from './outputConstants.js';
|
|
8
|
+
import { zoomOut } from './utils/zooming.js';
|
|
9
|
+
export function reportStats(log$, opts) {
|
|
10
|
+
if (opts.hideProgressPrefix) {
|
|
11
|
+
return [statsForCurrentPackage(log$.stats, {
|
|
12
|
+
cmd: opts.cmd,
|
|
13
|
+
width: opts.width,
|
|
14
|
+
})];
|
|
15
|
+
}
|
|
16
|
+
const stats$ = opts.isRecursive
|
|
17
|
+
? log$.stats
|
|
18
|
+
: log$.stats.pipe(filter((log) => log.prefix !== opts.cwd));
|
|
19
|
+
const outputs = [
|
|
20
|
+
statsForNotCurrentPackage(stats$, {
|
|
21
|
+
cmd: opts.cmd,
|
|
22
|
+
currentPrefix: opts.cwd,
|
|
23
|
+
width: opts.width,
|
|
24
|
+
}),
|
|
25
|
+
];
|
|
26
|
+
if (!opts.isRecursive) {
|
|
27
|
+
outputs.push(statsForCurrentPackage(log$.stats.pipe(filter((log) => log.prefix === opts.cwd)), {
|
|
28
|
+
cmd: opts.cmd,
|
|
29
|
+
width: opts.width,
|
|
30
|
+
}));
|
|
31
|
+
}
|
|
32
|
+
return outputs;
|
|
33
|
+
}
|
|
34
|
+
function statsForCurrentPackage(stats$, opts) {
|
|
35
|
+
return stats$.pipe(take((opts.cmd === 'install' || opts.cmd === 'install-test' || opts.cmd === 'add' || opts.cmd === 'update' || opts.cmd === 'dlx') ? 2 : 1), reduce((acc, log) => {
|
|
36
|
+
if (typeof log['added'] === 'number') {
|
|
37
|
+
acc['added'] = log['added'];
|
|
38
|
+
}
|
|
39
|
+
else if (typeof log['removed'] === 'number') {
|
|
40
|
+
acc['removed'] = log['removed'];
|
|
41
|
+
}
|
|
42
|
+
return acc;
|
|
43
|
+
}, {}), map((stats) => {
|
|
44
|
+
if (!stats['removed'] && !stats['added']) {
|
|
45
|
+
if (opts.cmd === 'link') {
|
|
46
|
+
return Rx.NEVER;
|
|
47
|
+
}
|
|
48
|
+
return Rx.of({ msg: 'Already up to date' });
|
|
49
|
+
}
|
|
50
|
+
let msg = 'Packages:';
|
|
51
|
+
if (stats['added']) {
|
|
52
|
+
msg += ' ' + chalk.green(`+${stats['added'].toString()}`);
|
|
53
|
+
}
|
|
54
|
+
if (stats['removed']) {
|
|
55
|
+
msg += ' ' + chalk.red(`-${stats['removed'].toString()}`);
|
|
56
|
+
}
|
|
57
|
+
msg += EOL + printPlusesAndMinuses(opts.width, (stats['added'] ?? 0), (stats['removed'] ?? 0));
|
|
58
|
+
return Rx.of({ msg });
|
|
59
|
+
}));
|
|
60
|
+
}
|
|
61
|
+
function statsForNotCurrentPackage(stats$, opts) {
|
|
62
|
+
const stats = {};
|
|
63
|
+
const cookedStats$ = (opts.cmd !== 'remove'
|
|
64
|
+
? stats$.pipe(map((log) => {
|
|
65
|
+
// As of pnpm v2.9.0, during `pnpm recursive link`, logging of removed stats happens twice
|
|
66
|
+
// 1. during linking
|
|
67
|
+
// 2. during installing
|
|
68
|
+
// Hence, the stats are added before reported
|
|
69
|
+
const { prefix } = log;
|
|
70
|
+
if (!stats[prefix]) {
|
|
71
|
+
stats[prefix] = log;
|
|
72
|
+
return { seed: stats, value: null };
|
|
73
|
+
}
|
|
74
|
+
else if (typeof stats[prefix].added === 'number' && typeof log['added'] === 'number') {
|
|
75
|
+
stats[prefix].added += log['added'];
|
|
76
|
+
return { seed: stats, value: null };
|
|
77
|
+
}
|
|
78
|
+
else if (typeof stats[prefix].removed === 'number' && typeof log['removed'] === 'number') {
|
|
79
|
+
stats[prefix].removed += log['removed'];
|
|
80
|
+
return { seed: stats, value: null };
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
const value = { ...stats[prefix], ...log };
|
|
84
|
+
delete stats[prefix];
|
|
85
|
+
return value;
|
|
86
|
+
}
|
|
87
|
+
}, {}))
|
|
88
|
+
: stats$);
|
|
89
|
+
return cookedStats$.pipe(filter((stats) => stats !== null && Boolean(stats['removed'] || stats['added'])), map((stats) => {
|
|
90
|
+
const parts = [];
|
|
91
|
+
if (stats['added']) {
|
|
92
|
+
parts.push(padStep(chalk.green(`+${stats['added'].toString()}`), 4));
|
|
93
|
+
}
|
|
94
|
+
if (stats['removed']) {
|
|
95
|
+
parts.push(padStep(chalk.red(`-${stats['removed'].toString()}`), 4));
|
|
96
|
+
}
|
|
97
|
+
let msg = zoomOut(opts.currentPrefix, stats.prefix, parts.join(' '));
|
|
98
|
+
const rest = Math.max(0, opts.width - 1 - stringLength(msg));
|
|
99
|
+
msg += ' ' + printPlusesAndMinuses(rest, roundStats(stats['added'] || 0), roundStats(stats['removed'] || 0));
|
|
100
|
+
return Rx.of({ msg });
|
|
101
|
+
}));
|
|
102
|
+
}
|
|
103
|
+
function padStep(s, step) {
|
|
104
|
+
const sLength = stringLength(s);
|
|
105
|
+
const placeholderLength = Math.ceil(sLength / step) * step;
|
|
106
|
+
if (sLength < placeholderLength) {
|
|
107
|
+
return repeat(' ', placeholderLength - sLength).join('') + s;
|
|
108
|
+
}
|
|
109
|
+
return s;
|
|
110
|
+
}
|
|
111
|
+
function roundStats(stat) {
|
|
112
|
+
if (stat === 0)
|
|
113
|
+
return 0;
|
|
114
|
+
return Math.max(1, Math.round(stat / 10));
|
|
115
|
+
}
|
|
116
|
+
function printPlusesAndMinuses(maxWidth, added, removed) {
|
|
117
|
+
if (maxWidth === 0)
|
|
118
|
+
return '';
|
|
119
|
+
const changes = added + removed;
|
|
120
|
+
let addedChars;
|
|
121
|
+
let removedChars;
|
|
122
|
+
if (changes > maxWidth) {
|
|
123
|
+
if (!added) {
|
|
124
|
+
addedChars = 0;
|
|
125
|
+
removedChars = maxWidth;
|
|
126
|
+
}
|
|
127
|
+
else if (!removed) {
|
|
128
|
+
addedChars = maxWidth;
|
|
129
|
+
removedChars = 0;
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
const p = maxWidth / changes;
|
|
133
|
+
addedChars = Math.min(Math.max(Math.floor(added * p), 1), maxWidth - 1);
|
|
134
|
+
removedChars = maxWidth - addedChars;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
else {
|
|
138
|
+
addedChars = added;
|
|
139
|
+
removedChars = removed;
|
|
140
|
+
}
|
|
141
|
+
return `${repeat(ADDED_CHAR, addedChars).join('')}${repeat(REMOVED_CHAR, removedChars).join('')}`;
|
|
142
|
+
}
|
|
143
|
+
//# sourceMappingURL=reportStats.js.map
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { Config } from '@pnpm/config.reader';
|
|
2
|
+
import type { DeprecationLog, PackageManifestLog, RootLog, SummaryLog } from '@pnpm/core-loggers';
|
|
3
|
+
import * as Rx from 'rxjs';
|
|
4
|
+
import { type PackageDiff } from './pkgsDiff.js';
|
|
5
|
+
export declare function reportSummary(log$: {
|
|
6
|
+
deprecation: Rx.Observable<DeprecationLog>;
|
|
7
|
+
summary: Rx.Observable<SummaryLog>;
|
|
8
|
+
root: Rx.Observable<RootLog>;
|
|
9
|
+
packageManifest: Rx.Observable<PackageManifestLog>;
|
|
10
|
+
}, opts: {
|
|
11
|
+
cmd: string;
|
|
12
|
+
cwd: string;
|
|
13
|
+
env: NodeJS.ProcessEnv;
|
|
14
|
+
filterPkgsDiff?: FilterPkgsDiff;
|
|
15
|
+
pnpmConfig?: Config;
|
|
16
|
+
}): Rx.Observable<Rx.Observable<{
|
|
17
|
+
msg: string;
|
|
18
|
+
}>>;
|
|
19
|
+
export type FilterPkgsDiff = (pkgsDiff: PackageDiff) => boolean;
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
import * as Rx from 'rxjs';
|
|
4
|
+
import { map, take } from 'rxjs/operators';
|
|
5
|
+
import semver from 'semver';
|
|
6
|
+
import { EOL } from '../constants.js';
|
|
7
|
+
import { ADDED_CHAR, REMOVED_CHAR, } from './outputConstants.js';
|
|
8
|
+
import { getPkgsDiff, propertyByDependencyType, } from './pkgsDiff.js';
|
|
9
|
+
const CONFIG_BY_DEP_TYPE = {
|
|
10
|
+
prod: 'production',
|
|
11
|
+
dev: 'dev',
|
|
12
|
+
optional: 'optional',
|
|
13
|
+
};
|
|
14
|
+
export function reportSummary(log$, opts) {
|
|
15
|
+
const pkgsDiff$ = getPkgsDiff(log$, { prefix: opts.pnpmConfig?.global ? undefined : opts.cwd });
|
|
16
|
+
const summaryLog$ = log$.summary.pipe(take(1));
|
|
17
|
+
const _printDiffs = printDiffs.bind(null, { cmd: opts.cmd, prefix: opts.cwd, pnpmConfig: opts.pnpmConfig });
|
|
18
|
+
return Rx.combineLatest(pkgsDiff$, summaryLog$)
|
|
19
|
+
.pipe(take(1), map(([pkgsDiff]) => {
|
|
20
|
+
let msg = '';
|
|
21
|
+
for (const depType of ['prod', 'optional', 'peer', 'dev', 'nodeModulesOnly']) {
|
|
22
|
+
let diffs = Object.values(pkgsDiff[depType]);
|
|
23
|
+
if (opts.filterPkgsDiff) {
|
|
24
|
+
// This filtering is only used by Bit CLI currently.
|
|
25
|
+
// Related PR: https://github.com/teambit/bit/pull/7176
|
|
26
|
+
diffs = diffs.filter((pkgDiff) => opts.filterPkgsDiff(pkgDiff));
|
|
27
|
+
}
|
|
28
|
+
if (diffs.length > 0) {
|
|
29
|
+
msg += EOL;
|
|
30
|
+
msg += chalk.cyanBright(opts.pnpmConfig?.global ? 'global:' : `${propertyByDependencyType[depType]}:`);
|
|
31
|
+
msg += EOL;
|
|
32
|
+
msg += _printDiffs(diffs, depType);
|
|
33
|
+
msg += EOL;
|
|
34
|
+
}
|
|
35
|
+
else if (CONFIG_BY_DEP_TYPE[depType] && opts.pnpmConfig?.[CONFIG_BY_DEP_TYPE[depType]] === false) {
|
|
36
|
+
msg += EOL;
|
|
37
|
+
msg += `${chalk.cyanBright(`${propertyByDependencyType[depType]}:`)} skipped`;
|
|
38
|
+
msg += EOL;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return Rx.of({ msg });
|
|
42
|
+
}));
|
|
43
|
+
}
|
|
44
|
+
function printDiffs(opts, pkgsDiff, depType) {
|
|
45
|
+
// Sorts by alphabet then by removed/added
|
|
46
|
+
// + ava 0.10.0
|
|
47
|
+
// - chalk 1.0.0
|
|
48
|
+
// + chalk 2.0.0
|
|
49
|
+
pkgsDiff.sort((a, b) => (a.name.localeCompare(b.name) * 10 + (Number(!b.added) - Number(!a.added))));
|
|
50
|
+
const msg = pkgsDiff.map((pkg) => {
|
|
51
|
+
let result = pkg.added
|
|
52
|
+
? ADDED_CHAR
|
|
53
|
+
: REMOVED_CHAR;
|
|
54
|
+
if (!pkg.realName || pkg.name === pkg.realName) {
|
|
55
|
+
result += ` ${pkg.name}`;
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
result += ` ${pkg.name} <- ${pkg.realName}`;
|
|
59
|
+
}
|
|
60
|
+
if (pkg.version) {
|
|
61
|
+
result += ` ${chalk.grey(pkg.version)}`;
|
|
62
|
+
if (pkg.latest && semver.lt(pkg.version, pkg.latest)) {
|
|
63
|
+
result += ` ${chalk.grey(`(${pkg.latest} is available)`)}`;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
if (pkg.deprecated) {
|
|
67
|
+
result += ` ${chalk.red('deprecated')}`;
|
|
68
|
+
}
|
|
69
|
+
if (pkg.from) {
|
|
70
|
+
result += ` ${chalk.grey(`<- ${path.relative(opts.prefix, pkg.from) || pkg.from}`)}`;
|
|
71
|
+
}
|
|
72
|
+
if (pkg.added && depType === 'dev' && opts.pnpmConfig?.saveDev === false && opts.cmd === 'add') {
|
|
73
|
+
result += `${chalk.yellow(' already in devDependencies, was not moved to dependencies.')}`;
|
|
74
|
+
}
|
|
75
|
+
return result;
|
|
76
|
+
}).join(EOL);
|
|
77
|
+
return msg;
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=reportSummary.js.map
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { UpdateCheckLog } from '@pnpm/core-loggers';
|
|
2
|
+
import * as Rx from 'rxjs';
|
|
3
|
+
export declare function reportUpdateCheck(log$: Rx.Observable<UpdateCheckLog>, opts: {
|
|
4
|
+
env: NodeJS.ProcessEnv;
|
|
5
|
+
process: NodeJS.Process;
|
|
6
|
+
}): Rx.Observable<Rx.Observable<{
|
|
7
|
+
msg: string;
|
|
8
|
+
}>>;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { detectIfCurrentPkgIsExecutable, isExecutedByCorepack } from '@pnpm/cli.meta';
|
|
2
|
+
import boxen from 'boxen';
|
|
3
|
+
import chalk from 'chalk';
|
|
4
|
+
import * as Rx from 'rxjs';
|
|
5
|
+
import { filter, map, take } from 'rxjs/operators';
|
|
6
|
+
import semver from 'semver';
|
|
7
|
+
export function reportUpdateCheck(log$, opts) {
|
|
8
|
+
return log$.pipe(take(1), filter((log) => semver.gt(log.latestVersion, log.currentVersion)), map((log) => {
|
|
9
|
+
const updateMessage = renderUpdateMessage({
|
|
10
|
+
currentPkgIsExecutable: detectIfCurrentPkgIsExecutable(opts.process),
|
|
11
|
+
latestVersion: log.latestVersion,
|
|
12
|
+
env: opts.env,
|
|
13
|
+
});
|
|
14
|
+
return Rx.of({
|
|
15
|
+
msg: boxen(`\
|
|
16
|
+
Update available! ${chalk.red(log.currentVersion)} → ${chalk.green(log.latestVersion)}.
|
|
17
|
+
${chalk.magenta('Changelog:')} https://pnpm.io/v/${log.latestVersion}
|
|
18
|
+
${updateMessage}`, {
|
|
19
|
+
padding: 1,
|
|
20
|
+
margin: 1,
|
|
21
|
+
align: 'center',
|
|
22
|
+
borderColor: 'yellow',
|
|
23
|
+
borderStyle: 'round',
|
|
24
|
+
}),
|
|
25
|
+
});
|
|
26
|
+
}));
|
|
27
|
+
}
|
|
28
|
+
function renderUpdateMessage(opts) {
|
|
29
|
+
const updateCommand = renderUpdateCommand(opts);
|
|
30
|
+
return `To update, run: ${chalk.magenta(updateCommand)}`;
|
|
31
|
+
}
|
|
32
|
+
function renderUpdateCommand(opts) {
|
|
33
|
+
if (isExecutedByCorepack(opts.env)) {
|
|
34
|
+
return `corepack use pnpm@${opts.latestVersion}`;
|
|
35
|
+
}
|
|
36
|
+
if (opts.env.PNPM_HOME) {
|
|
37
|
+
return 'pnpm self-update';
|
|
38
|
+
}
|
|
39
|
+
const pkgName = opts.currentPkgIsExecutable ? '@pnpm/exe' : 'pnpm';
|
|
40
|
+
return `pnpm add -g ${pkgName}`;
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=reportUpdateCheck.js.map
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import normalize from 'normalize-path';
|
|
3
|
+
import { PREFIX_MAX_LENGTH } from '../outputConstants.js';
|
|
4
|
+
export function formatPrefix(cwd, prefix) {
|
|
5
|
+
prefix = formatPrefixNoTrim(cwd, prefix);
|
|
6
|
+
if (prefix.length <= PREFIX_MAX_LENGTH) {
|
|
7
|
+
return prefix;
|
|
8
|
+
}
|
|
9
|
+
const shortPrefix = prefix.slice(-PREFIX_MAX_LENGTH + 3);
|
|
10
|
+
const separatorLocation = shortPrefix.indexOf('/');
|
|
11
|
+
if (separatorLocation <= 0) {
|
|
12
|
+
return `...${shortPrefix}`;
|
|
13
|
+
}
|
|
14
|
+
return `...${shortPrefix.slice(separatorLocation)}`;
|
|
15
|
+
}
|
|
16
|
+
export function formatPrefixNoTrim(cwd, prefix) {
|
|
17
|
+
return normalize(path.relative(cwd, prefix) || '.');
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=formatPrefix.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function formatWarn(message: string): string;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
export function formatWarn(message) {
|
|
3
|
+
// The \u2009 is the "thin space" unicode character
|
|
4
|
+
// It is used instead of ' ' because chalk (as of version 2.1.0)
|
|
5
|
+
// trims whitespace at the beginning
|
|
6
|
+
return `${chalk.bgYellow.black('\u2009WARN\u2009')} ${message}`;
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=formatWarn.js.map
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { PREFIX_MAX_LENGTH } from '../outputConstants.js';
|
|
2
|
+
import { formatPrefix } from './formatPrefix.js';
|
|
3
|
+
export function autozoom(currentPrefix, logPrefix, line, opts) {
|
|
4
|
+
if (!logPrefix || !opts.zoomOutCurrent && currentPrefix === logPrefix) {
|
|
5
|
+
return line;
|
|
6
|
+
}
|
|
7
|
+
return zoomOut(currentPrefix, logPrefix, line);
|
|
8
|
+
}
|
|
9
|
+
export function zoomOut(currentPrefix, logPrefix, line) {
|
|
10
|
+
const prefix = formatPrefix(currentPrefix, logPrefix);
|
|
11
|
+
return `${prefix.padEnd(PREFIX_MAX_LENGTH)} | ${line}`;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=zooming.js.map
|