@pnpm/pkg-manifest.commands 1100.1.30 → 1100.1.32
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/CHANGELOG.md +17 -0
- package/lib/pkg.js +68 -58
- package/lib/reportKeys.d.ts +17 -0
- package/lib/reportKeys.js +44 -0
- package/package.json +5 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
# @pnpm/pkg-manifest.commands
|
|
2
2
|
|
|
3
|
+
## 1100.1.32
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- `pnpm -r pkg get` now reports every selected project when several share a package name. Projects with the same name are keyed by their directory relative to the workspace root. Before, only one of them appeared in the output.
|
|
8
|
+
|
|
9
|
+
- Updated dependencies:
|
|
10
|
+
- @pnpm/cli.utils@1101.0.31
|
|
11
|
+
- @pnpm/config.reader@1102.3.3
|
|
12
|
+
|
|
13
|
+
## 1100.1.31
|
|
14
|
+
|
|
15
|
+
### Patch Changes
|
|
16
|
+
|
|
17
|
+
- Updated dependencies:
|
|
18
|
+
- @pnpm/config.reader@1102.3.2
|
|
19
|
+
|
|
3
20
|
## 1100.1.30
|
|
4
21
|
|
|
5
22
|
### Patch Changes
|
package/lib/pkg.js
CHANGED
|
@@ -4,6 +4,7 @@ import { types as allTypes } from '@pnpm/config.reader';
|
|
|
4
4
|
import { PnpmError } from '@pnpm/error';
|
|
5
5
|
import { deleteObjectValueByPropertyPathString, getObjectValueByPropertyPathString, setObjectValueByPropertyPathString, } from '@pnpm/object.property-path';
|
|
6
6
|
import { renderHelp } from 'render-help';
|
|
7
|
+
import { assignReportKeys } from './reportKeys.js';
|
|
7
8
|
export const rcOptionsTypes = cliOptionsTypes;
|
|
8
9
|
export function cliOptionsTypes() {
|
|
9
10
|
const types = allTypes;
|
|
@@ -57,12 +58,18 @@ async function handleRecursiveCommand(opts, subcmd, args) {
|
|
|
57
58
|
throw new PnpmError('PKG_RECURSIVE_NO_PACKAGES', 'No workspace packages were selected');
|
|
58
59
|
}
|
|
59
60
|
if (subcmd === 'get') {
|
|
60
|
-
const
|
|
61
|
+
const projects = await Promise.all(selectedProjects.map(async ({ package: pkg }) => {
|
|
61
62
|
const manifest = await readProjectManifestOnly(pkg.rootDir);
|
|
62
|
-
|
|
63
|
-
|
|
63
|
+
return {
|
|
64
|
+
identity: {
|
|
65
|
+
name: manifest.name == null ? undefined : String(manifest.name),
|
|
66
|
+
dirKey: path.relative(workspaceDir, pkg.rootDir),
|
|
67
|
+
},
|
|
68
|
+
value: selectFromManifest(manifest, args),
|
|
69
|
+
};
|
|
64
70
|
}));
|
|
65
|
-
|
|
71
|
+
const keys = assignReportKeys(projects.map(({ identity }) => identity));
|
|
72
|
+
return JSON.stringify(Object.fromEntries(projects.map(({ value }, index) => [keys[index], value])), undefined, 2);
|
|
66
73
|
}
|
|
67
74
|
await Promise.all(selectedProjects.map(({ package: pkg }) => runSubcommand({ ...opts, dir: pkg.rootDir }, subcmd, args)));
|
|
68
75
|
}
|
|
@@ -129,77 +136,80 @@ async function pkgDelete(opts, args) {
|
|
|
129
136
|
}
|
|
130
137
|
async function pkgFix(opts) {
|
|
131
138
|
const { manifest, writeProjectManifest } = await readProjectManifest(opts.dir);
|
|
132
|
-
const
|
|
133
|
-
if ('name' in
|
|
134
|
-
delete
|
|
139
|
+
const untypedManifest = manifest;
|
|
140
|
+
if ('name' in untypedManifest && typeof untypedManifest.name !== 'string') {
|
|
141
|
+
delete untypedManifest.name;
|
|
135
142
|
}
|
|
136
|
-
if ('version' in
|
|
137
|
-
delete
|
|
143
|
+
if ('version' in untypedManifest && typeof untypedManifest.version !== 'string') {
|
|
144
|
+
delete untypedManifest.version;
|
|
138
145
|
}
|
|
139
146
|
for (const field of ['dependencies', 'devDependencies', 'optionalDependencies', 'peerDependencies', 'scripts']) {
|
|
140
|
-
if (field in
|
|
141
|
-
delete
|
|
147
|
+
if (field in untypedManifest && !isPlainObject(untypedManifest[field])) {
|
|
148
|
+
delete untypedManifest[field];
|
|
142
149
|
}
|
|
143
150
|
}
|
|
144
|
-
if ('bin' in
|
|
145
|
-
delete
|
|
151
|
+
if ('bin' in untypedManifest && typeof untypedManifest.bin !== 'string' && !isPlainObject(untypedManifest.bin)) {
|
|
152
|
+
delete untypedManifest.bin;
|
|
146
153
|
}
|
|
147
154
|
await writeProjectManifest(manifest);
|
|
148
155
|
}
|
|
149
156
|
function isPlainObject(value) {
|
|
150
157
|
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
151
158
|
}
|
|
159
|
+
const COMMANDS = {
|
|
160
|
+
title: 'Commands',
|
|
161
|
+
list: [
|
|
162
|
+
{
|
|
163
|
+
description: 'Retrieves a value from package.json',
|
|
164
|
+
name: 'get [<key> [<key> ...]]',
|
|
165
|
+
},
|
|
166
|
+
{
|
|
167
|
+
description: 'Sets a value in package.json',
|
|
168
|
+
name: 'set <key>=<value> [<key>=<value> ...]',
|
|
169
|
+
},
|
|
170
|
+
{
|
|
171
|
+
description: 'Deletes a key from package.json',
|
|
172
|
+
name: 'delete <key> [<key> ...]',
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
description: 'Auto corrects common errors in package.json',
|
|
176
|
+
name: 'fix',
|
|
177
|
+
},
|
|
178
|
+
],
|
|
179
|
+
};
|
|
180
|
+
const OPTIONS = {
|
|
181
|
+
title: 'Options',
|
|
182
|
+
list: [
|
|
183
|
+
{
|
|
184
|
+
description: 'When setting, parse the value as JSON. When getting a single key, return its JSON-encoded form instead of the raw value',
|
|
185
|
+
name: '--json',
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
description: 'Run on every workspace project or every project selected by a filter',
|
|
189
|
+
name: '--recursive',
|
|
190
|
+
shortAlias: '-r',
|
|
191
|
+
},
|
|
192
|
+
],
|
|
193
|
+
};
|
|
194
|
+
const USAGES = [
|
|
195
|
+
'pnpm pkg get [<key> [<key> ...]]',
|
|
196
|
+
'pnpm pkg set <key>=<value> [<key>=<value> ...]',
|
|
197
|
+
'pnpm pkg delete <key> [<key> ...]',
|
|
198
|
+
'pnpm pkg fix',
|
|
199
|
+
'pnpm pkg set <key>=<value> --json',
|
|
200
|
+
'pnpm -r pkg get name',
|
|
201
|
+
'pnpm --filter <selector> pkg get name',
|
|
202
|
+
'pnpm -r pkg set version=1.0.0',
|
|
203
|
+
];
|
|
152
204
|
export function help() {
|
|
153
205
|
return renderHelp({
|
|
154
206
|
description: 'Manages your package.json',
|
|
155
207
|
descriptionLists: [
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
list: [
|
|
159
|
-
{
|
|
160
|
-
description: 'Retrieves a value from package.json',
|
|
161
|
-
name: 'get [<key> [<key> ...]]',
|
|
162
|
-
},
|
|
163
|
-
{
|
|
164
|
-
description: 'Sets a value in package.json',
|
|
165
|
-
name: 'set <key>=<value> [<key>=<value> ...]',
|
|
166
|
-
},
|
|
167
|
-
{
|
|
168
|
-
description: 'Deletes a key from package.json',
|
|
169
|
-
name: 'delete <key> [<key> ...]',
|
|
170
|
-
},
|
|
171
|
-
{
|
|
172
|
-
description: 'Auto corrects common errors in package.json',
|
|
173
|
-
name: 'fix',
|
|
174
|
-
},
|
|
175
|
-
],
|
|
176
|
-
},
|
|
177
|
-
{
|
|
178
|
-
title: 'Options',
|
|
179
|
-
list: [
|
|
180
|
-
{
|
|
181
|
-
description: 'When setting, parse the value as JSON. When getting a single key, return its JSON-encoded form instead of the raw value',
|
|
182
|
-
name: '--json',
|
|
183
|
-
},
|
|
184
|
-
{
|
|
185
|
-
description: 'Run on every workspace project or every project selected by a filter',
|
|
186
|
-
name: '--recursive',
|
|
187
|
-
shortAlias: '-r',
|
|
188
|
-
},
|
|
189
|
-
],
|
|
190
|
-
},
|
|
208
|
+
COMMANDS,
|
|
209
|
+
OPTIONS,
|
|
191
210
|
],
|
|
192
211
|
url: docsUrl('pkg'),
|
|
193
|
-
usages:
|
|
194
|
-
'pnpm pkg get [<key> [<key> ...]]',
|
|
195
|
-
'pnpm pkg set <key>=<value> [<key>=<value> ...]',
|
|
196
|
-
'pnpm pkg delete <key> [<key> ...]',
|
|
197
|
-
'pnpm pkg fix',
|
|
198
|
-
'pnpm pkg set <key>=<value> --json',
|
|
199
|
-
'pnpm -r pkg get name',
|
|
200
|
-
'pnpm --filter <selector> pkg get name',
|
|
201
|
-
'pnpm -r pkg set version=1.0.0',
|
|
202
|
-
],
|
|
212
|
+
usages: USAGES,
|
|
203
213
|
});
|
|
204
214
|
}
|
|
205
215
|
//# sourceMappingURL=pkg.js.map
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export interface ReportIdentity {
|
|
2
|
+
/** The manifest's `name`, when it declares one. */
|
|
3
|
+
name?: string;
|
|
4
|
+
/** The project's directory, relative to the workspace root. */
|
|
5
|
+
dirKey: string;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Chooses a distinct `pnpm -r pkg get` report key for every project, in input order.
|
|
9
|
+
*
|
|
10
|
+
* A project is keyed by its name unless that would hide another project:
|
|
11
|
+
* a project without a name, every project that shares its name with
|
|
12
|
+
* another selected project, and a project whose name equals the directory
|
|
13
|
+
* key another project is reported under are keyed by their directory instead. Directories
|
|
14
|
+
* are distinct, so the keys are too, and a workspace whose names are unique
|
|
15
|
+
* keeps its name keys.
|
|
16
|
+
*/
|
|
17
|
+
export declare function assignReportKeys(identities: ReportIdentity[]): string[];
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Chooses a distinct `pnpm -r pkg get` report key for every project, in input order.
|
|
3
|
+
*
|
|
4
|
+
* A project is keyed by its name unless that would hide another project:
|
|
5
|
+
* a project without a name, every project that shares its name with
|
|
6
|
+
* another selected project, and a project whose name equals the directory
|
|
7
|
+
* key another project is reported under are keyed by their directory instead. Directories
|
|
8
|
+
* are distinct, so the keys are too, and a workspace whose names are unique
|
|
9
|
+
* keeps its name keys.
|
|
10
|
+
*/
|
|
11
|
+
export function assignReportKeys(identities) {
|
|
12
|
+
const keyedByDir = initiallyKeyedByDir(identities);
|
|
13
|
+
moveNamesShadowedByDirs(identities, keyedByDir);
|
|
14
|
+
return identities.map((identity, index) => identity.name == null || keyedByDir[index] ? identity.dirKey : identity.name);
|
|
15
|
+
}
|
|
16
|
+
function initiallyKeyedByDir(identities) {
|
|
17
|
+
const nameCounts = new Map();
|
|
18
|
+
for (const { name } of identities) {
|
|
19
|
+
if (name != null)
|
|
20
|
+
nameCounts.set(name, (nameCounts.get(name) ?? 0) + 1);
|
|
21
|
+
}
|
|
22
|
+
return identities.map(({ name }) => name == null || nameCounts.get(name) > 1);
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Moves every name-keyed project whose name equals a directory key in use
|
|
26
|
+
* to its own directory key. A moved project's directory key can in turn
|
|
27
|
+
* shadow another name, so each move is followed up the same way.
|
|
28
|
+
*/
|
|
29
|
+
function moveNamesShadowedByDirs(identities, keyedByDir) {
|
|
30
|
+
const nameKeyed = new Map();
|
|
31
|
+
for (const [index, { name }] of identities.entries()) {
|
|
32
|
+
if (name != null && !keyedByDir[index])
|
|
33
|
+
nameKeyed.set(name, index);
|
|
34
|
+
}
|
|
35
|
+
const pending = identities.flatMap((_, index) => keyedByDir[index] ? [index] : []);
|
|
36
|
+
for (let index = pending.pop(); index !== undefined; index = pending.pop()) {
|
|
37
|
+
const shadowed = nameKeyed.get(identities[index].dirKey);
|
|
38
|
+
if (shadowed !== undefined && !keyedByDir[shadowed]) {
|
|
39
|
+
keyedByDir[shadowed] = true;
|
|
40
|
+
pending.push(shadowed);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=reportKeys.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pnpm/pkg-manifest.commands",
|
|
3
|
-
"version": "1100.1.
|
|
3
|
+
"version": "1100.1.32",
|
|
4
4
|
"description": "Commands for managing package.json",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pnpm",
|
|
@@ -28,8 +28,8 @@
|
|
|
28
28
|
"!*.map"
|
|
29
29
|
],
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@pnpm/cli.utils": "1101.0.
|
|
32
|
-
"@pnpm/config.reader": "1102.3.
|
|
31
|
+
"@pnpm/cli.utils": "1101.0.31",
|
|
32
|
+
"@pnpm/config.reader": "1102.3.3",
|
|
33
33
|
"@pnpm/error": "1100.2.1",
|
|
34
34
|
"@pnpm/object.property-path": "1100.1.8",
|
|
35
35
|
"@pnpm/types": "1102.1.1",
|
|
@@ -37,8 +37,8 @@
|
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
39
39
|
"@jest/globals": "30.4.1",
|
|
40
|
-
"@pnpm/pkg-manifest.commands": "1100.1.
|
|
41
|
-
"@pnpm/prepare": "1100.0.
|
|
40
|
+
"@pnpm/pkg-manifest.commands": "1100.1.32",
|
|
41
|
+
"@pnpm/prepare": "1100.0.35"
|
|
42
42
|
},
|
|
43
43
|
"engines": {
|
|
44
44
|
"node": ">=22.13"
|