@pnpm/config.commands 1100.0.37 → 1101.0.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/CHANGELOG.md +53 -0
- package/lib/configGet.js +7 -1
- package/lib/configSet.d.ts +4 -0
- package/lib/configSet.js +40 -10
- package/lib/configToRecord.d.ts +3 -1
- package/lib/configToRecord.js +33 -4
- package/package.json +10 -9
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,58 @@
|
|
|
1
1
|
# @pnpm/plugin-commands-config
|
|
2
2
|
|
|
3
|
+
## 1101.0.0
|
|
4
|
+
|
|
5
|
+
### Major Changes
|
|
6
|
+
|
|
7
|
+
- The three registry lookups are now named for what they are keyed by, so that none of them is called `registries` — a name the `registries` setting itself has taken:
|
|
8
|
+
|
|
9
|
+
| before | after |
|
|
10
|
+
|---|---|
|
|
11
|
+
| `Config.registries` | `Config.registriesByScope` |
|
|
12
|
+
| `Config.namedRegistries` | `Config.registriesByPrefix` |
|
|
13
|
+
| `Config.registryOptions` | `Config.registryOptionsByUrl` |
|
|
14
|
+
|
|
15
|
+
The same rename applies to the `RegistryContext` fields, the `Registries` and `NamedRegistries` types (now `RegistriesByScope` and `RegistriesByPrefix`), `normalizeRegistries` / `normalizeNamedRegistries` (now `normalizeRegistriesByScope` / `normalizeRegistriesByPrefix`), and the `BUILTIN_NAMED_REGISTRIES` constant (now `BUILTIN_REGISTRIES_BY_PREFIX`).
|
|
16
|
+
|
|
17
|
+
This is an internal rename: no setting, error code, lockfile field, or `.pnpmfile.cjs` hook field changes. A `preResolution` hook still reads `ctx.registries`, which is the name pacquet passes as well. The `registries` and `namedRegistries` settings are read under the names users write them.
|
|
18
|
+
|
|
19
|
+
The pnpr resolve request sends `registriesByPrefix` where it sent `namedRegistries`. A pnpr server and its clients must be on matching versions, which is already the case for an experimental server.
|
|
20
|
+
|
|
21
|
+
### Minor Changes
|
|
22
|
+
|
|
23
|
+
- `pnpm config get` and `pnpm config list` now show the settings pnpm acts on under their documented names:
|
|
24
|
+
|
|
25
|
+
- `registries` shows the registries pnpm resolves from, merged across every source (`.npmrc`, `pnpm-workspace.yaml`, the global config, CLI flags), in the shape the setting is written in: keyed by registry URL, with the default registry declared as the bare `@` scope. Built-in routes are included — the `@jsr` scope and the `npmjs` and `gh` prefixes — unless pointed elsewhere. Previously `pnpm config get registries` printed `undefined`.
|
|
26
|
+
- `update` and `audit` show the effective sections, whichever spelling set them. The deprecated internal spellings (`updateConfig`, `auditConfig`, `auditLevel`) are no longer listed.
|
|
27
|
+
- `catalogs` shows the complete resolved catalog set — the singular `catalog` block is its `default` entry — whichever spelling declared it.
|
|
28
|
+
- The `registry` and `@scope:registry` entries show the merged routes rather than raw `.npmrc` values, so they always agree with the `registries` view.
|
|
29
|
+
|
|
30
|
+
### Patch Changes
|
|
31
|
+
|
|
32
|
+
- Updated dependencies:
|
|
33
|
+
- @pnpm/cli.utils@1101.0.24
|
|
34
|
+
- @pnpm/config.normalize-registries@1101.0.0
|
|
35
|
+
- @pnpm/config.reader@1102.0.0
|
|
36
|
+
- @pnpm/constants@1102.0.0
|
|
37
|
+
- @pnpm/error@1100.1.3
|
|
38
|
+
- @pnpm/object.property-path@1100.1.5
|
|
39
|
+
- @pnpm/workspace.workspace-manifest-writer@1100.1.1
|
|
40
|
+
|
|
41
|
+
## 1100.1.0
|
|
42
|
+
|
|
43
|
+
### Minor Changes
|
|
44
|
+
|
|
45
|
+
- `pnpm config set` refuses to write a setting to a project's `pnpm-workspace.yaml` that pnpm does not read from there, rather than leaving a key in the file that does nothing. Those settings are `configDir`, `pnpmHomeDir`, `stateDir` and the others that name machine-level state. The command fails with `ERR_PNPM_CONFIG_SET_NOT_A_PROJECT_SETTING`, naming where the setting does belong when it belongs somewhere. `pnpm config delete` still clears one that a file already carries, in whichever spelling it uses [#13629](https://github.com/pnpm/pnpm/issues/13629).
|
|
46
|
+
|
|
47
|
+
### Patch Changes
|
|
48
|
+
|
|
49
|
+
- Updated dependencies:
|
|
50
|
+
- @pnpm/cli.utils@1101.0.23
|
|
51
|
+
- @pnpm/config.reader@1101.17.0
|
|
52
|
+
- @pnpm/error@1100.1.2
|
|
53
|
+
- @pnpm/object.property-path@1100.1.4
|
|
54
|
+
- @pnpm/workspace.workspace-manifest-writer@1100.1.0
|
|
55
|
+
|
|
3
56
|
## 1100.0.37
|
|
4
57
|
|
|
5
58
|
### Patch Changes
|
package/lib/configGet.js
CHANGED
|
@@ -20,7 +20,7 @@ function lookupConfig(opts, key, isScopedKey) {
|
|
|
20
20
|
// `pnpm publish` and the resolvers actually use.
|
|
21
21
|
if (key.endsWith(':registry')) {
|
|
22
22
|
const scope = key.slice(0, key.length - ':registry'.length);
|
|
23
|
-
const merged = opts._config.
|
|
23
|
+
const merged = opts._config.registriesByScope?.[scope];
|
|
24
24
|
if (merged !== undefined) {
|
|
25
25
|
return { value: merged };
|
|
26
26
|
}
|
|
@@ -31,6 +31,12 @@ function lookupConfig(opts, key, isScopedKey) {
|
|
|
31
31
|
return { value: getGlobalConfigPath(opts.configDir) };
|
|
32
32
|
}
|
|
33
33
|
const kebabKey = isCamelCase(key) ? kebabCase(key) : key;
|
|
34
|
+
// The merged map is what resolvers use, so `registry` answers the same
|
|
35
|
+
// default the resolved `registries` view declares as the bare `@` scope —
|
|
36
|
+
// a raw `.npmrc` value would contradict it.
|
|
37
|
+
if (kebabKey === 'registry') {
|
|
38
|
+
return { value: opts._config.registriesByScope?.default ?? opts.authConfig.registry };
|
|
39
|
+
}
|
|
34
40
|
// Resolve typed keys from Config — check explicitly set values first,
|
|
35
41
|
// then fall back to authConfig (for keys like registry set in .npmrc)
|
|
36
42
|
if (Object.hasOwn(types, kebabKey)) {
|
package/lib/configSet.d.ts
CHANGED
|
@@ -15,6 +15,10 @@ export declare class ConfigSetUnsupportedWorkspaceKeyError extends PnpmError {
|
|
|
15
15
|
readonly key: string;
|
|
16
16
|
constructor(key: string);
|
|
17
17
|
}
|
|
18
|
+
export declare class ConfigSetNotAProjectSettingError extends PnpmError {
|
|
19
|
+
readonly key: string;
|
|
20
|
+
constructor(key: string);
|
|
21
|
+
}
|
|
18
22
|
export declare class ConfigSetUnsupportedYamlConfigKeyError extends PnpmError {
|
|
19
23
|
readonly key: string;
|
|
20
24
|
constructor(key: string);
|
package/lib/configSet.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
2
|
import util from 'node:util';
|
|
3
|
-
import { isConfigFileKey, isIniConfigKey, types } from '@pnpm/config.reader';
|
|
3
|
+
import { isConfigFileKey, isIniConfigKey, isProjectManifestSkippedKey, types, whereRefusedKeyBelongs } from '@pnpm/config.reader';
|
|
4
4
|
import { GLOBAL_CONFIG_YAML_FILENAME, WORKSPACE_MANIFEST_FILENAME } from '@pnpm/constants';
|
|
5
5
|
import { PnpmError } from '@pnpm/error';
|
|
6
6
|
import { parsePropertyPath } from '@pnpm/object.property-path';
|
|
@@ -45,16 +45,28 @@ export async function configSet(opts, key, valueParam) {
|
|
|
45
45
|
switch (configFileName) {
|
|
46
46
|
case GLOBAL_CONFIG_YAML_FILENAME:
|
|
47
47
|
case WORKSPACE_MANIFEST_FILENAME: {
|
|
48
|
-
|
|
48
|
+
// `pnpm config set <key> null` casts to a removal too.
|
|
49
|
+
const castValue = castField(value, kebabCase(key));
|
|
50
|
+
const isRemoval = castValue == null;
|
|
51
|
+
// Validation stops a write landing in a file that will not read it back.
|
|
52
|
+
// Nothing reads back a key being deleted, so a removal skips both checks.
|
|
53
|
+
if (configFileName === GLOBAL_CONFIG_YAML_FILENAME && !isRemoval) {
|
|
49
54
|
key = validateYamlConfigKey(key);
|
|
50
55
|
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
}
|
|
56
|
+
const writtenKey = isRemoval ? camelCase(key) : validateWorkspaceKey(key);
|
|
57
|
+
if (castValue != null && configFileName === WORKSPACE_MANIFEST_FILENAME && isProjectManifestSkippedKey(writtenKey)) {
|
|
58
|
+
throw new ConfigSetNotAProjectSettingError(writtenKey);
|
|
59
|
+
}
|
|
60
|
+
const updatedFields = {
|
|
61
|
+
[writtenKey]: castValue,
|
|
62
|
+
};
|
|
63
|
+
// A hand-edited file may carry a spelling pnpm did not write, and that
|
|
64
|
+
// is the one the reader's warning names, so a removal clears them all.
|
|
65
|
+
if (isRemoval) {
|
|
66
|
+
updatedFields[key] = null;
|
|
67
|
+
updatedFields[kebabCase(writtenKey)] = null;
|
|
68
|
+
}
|
|
69
|
+
await updateWorkspaceManifest(configDir, { fileName: configFileName, updatedFields });
|
|
58
70
|
break;
|
|
59
71
|
}
|
|
60
72
|
case 'auth.ini':
|
|
@@ -169,6 +181,22 @@ export class ConfigSetUnsupportedWorkspaceKeyError extends PnpmError {
|
|
|
169
181
|
this.key = key;
|
|
170
182
|
}
|
|
171
183
|
}
|
|
184
|
+
/** The suggestion for {@link key}, which falls back when the key is allowed in a project manifest. */
|
|
185
|
+
function hintForRefusedKey(key, fallback) {
|
|
186
|
+
const camelKey = camelCase(key);
|
|
187
|
+
if (!isProjectManifestSkippedKey(camelKey))
|
|
188
|
+
return fallback;
|
|
189
|
+
return whereRefusedKeyBelongs(camelKey);
|
|
190
|
+
}
|
|
191
|
+
export class ConfigSetNotAProjectSettingError extends PnpmError {
|
|
192
|
+
key;
|
|
193
|
+
constructor(key) {
|
|
194
|
+
super('CONFIG_SET_NOT_A_PROJECT_SETTING', `The key ${JSON.stringify(key)} cannot be set in a project's pnpm-workspace.yaml`, {
|
|
195
|
+
hint: whereRefusedKeyBelongs(key),
|
|
196
|
+
});
|
|
197
|
+
this.key = key;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
172
200
|
/**
|
|
173
201
|
* Only an rc option key would be allowed to be kebab-case, otherwise, it must be camelCase.
|
|
174
202
|
*
|
|
@@ -177,6 +205,8 @@ export class ConfigSetUnsupportedWorkspaceKeyError extends PnpmError {
|
|
|
177
205
|
function validateWorkspaceKey(key) {
|
|
178
206
|
if (Object.hasOwn(types, key) || isConfigFileKey(key))
|
|
179
207
|
return camelCase(key);
|
|
208
|
+
if (isProjectManifestSkippedKey(camelCase(key)))
|
|
209
|
+
return camelCase(key);
|
|
180
210
|
if (!isCamelCase(key))
|
|
181
211
|
throw new ConfigSetUnsupportedWorkspaceKeyError(key);
|
|
182
212
|
return key;
|
|
@@ -205,7 +235,7 @@ export class ConfigSetUnsupportedYamlConfigKeyError extends PnpmError {
|
|
|
205
235
|
key;
|
|
206
236
|
constructor(key) {
|
|
207
237
|
super('CONFIG_SET_UNSUPPORTED_YAML_CONFIG_KEY', `The key ${JSON.stringify(key)} isn't supported by the global config.yaml file`, {
|
|
208
|
-
hint: 'Try setting them instead to the local pnpm-workspace.yaml file',
|
|
238
|
+
hint: hintForRefusedKey(key, 'Try setting them instead to the local pnpm-workspace.yaml file'),
|
|
209
239
|
});
|
|
210
240
|
this.key = key;
|
|
211
241
|
}
|
package/lib/configToRecord.d.ts
CHANGED
|
@@ -2,7 +2,9 @@ import { type Config } from '@pnpm/config.reader';
|
|
|
2
2
|
/**
|
|
3
3
|
* Convert a Config object to a camelCase record for display.
|
|
4
4
|
* Only includes explicitly set values (from CLI, env vars, or workspace yaml),
|
|
5
|
-
* not default values. Auth/registry keys from authConfig are always included
|
|
5
|
+
* not default values. Auth/registry keys from authConfig are always included,
|
|
6
|
+
* and so is `registries` — the registries the CLI resolves from, merged
|
|
7
|
+
* across every source.
|
|
6
8
|
*
|
|
7
9
|
* Accepts a clean Config object (without ConfigContext fields mixed in),
|
|
8
10
|
* so no INTERNAL_CONFIG_KEYS exclusion list is needed.
|
package/lib/configToRecord.js
CHANGED
|
@@ -1,15 +1,24 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { pickRegistryContext, toResolvedRegistryDeclarations } from '@pnpm/config.normalize-registries';
|
|
2
|
+
import { toAuditSettings, toUpdateSettings, types } from '@pnpm/config.reader';
|
|
2
3
|
import { sortDirectKeys } from '@pnpm/object.key-sorting';
|
|
3
4
|
import camelcase from 'camelcase';
|
|
4
5
|
import { censorProtectedSettings } from './protectedSettings.js';
|
|
5
|
-
//
|
|
6
|
+
// Config fields the record does not copy verbatim: internal objects, the
|
|
7
|
+
// lookups and spellings the `registries` / `update` / `audit` settings are
|
|
8
|
+
// split into (shown re-joined under the documented names instead), and
|
|
9
|
+
// `catalogs`, which is re-added below as the resolved catalog set.
|
|
6
10
|
const NON_SETTING_CONFIG_KEYS = new Set([
|
|
7
11
|
'authConfig', 'configByUri',
|
|
12
|
+
'registriesByScope', 'registriesByPrefix', 'registryOptionsByUrl',
|
|
13
|
+
'updateConfig', 'auditConfig', 'auditLevel',
|
|
14
|
+
'catalogs',
|
|
8
15
|
]);
|
|
9
16
|
/**
|
|
10
17
|
* Convert a Config object to a camelCase record for display.
|
|
11
18
|
* Only includes explicitly set values (from CLI, env vars, or workspace yaml),
|
|
12
|
-
* not default values. Auth/registry keys from authConfig are always included
|
|
19
|
+
* not default values. Auth/registry keys from authConfig are always included,
|
|
20
|
+
* and so is `registries` — the registries the CLI resolves from, merged
|
|
21
|
+
* across every source.
|
|
13
22
|
*
|
|
14
23
|
* Accepts a clean Config object (without ConfigContext fields mixed in),
|
|
15
24
|
* so no INTERNAL_CONFIG_KEYS exclusion list is needed.
|
|
@@ -19,7 +28,7 @@ export function configToRecord(config, explicitlySetKeys) {
|
|
|
19
28
|
// Add typed settings (only explicitly set ones if tracking is available)
|
|
20
29
|
for (const kebabKey of Object.keys(types)) {
|
|
21
30
|
const camelKey = camelcase(kebabKey, { locale: 'en-US' });
|
|
22
|
-
if (!explicitlySetKeys.has(camelKey))
|
|
31
|
+
if (!explicitlySetKeys.has(camelKey) || NON_SETTING_CONFIG_KEYS.has(camelKey))
|
|
23
32
|
continue;
|
|
24
33
|
const value = config[camelKey];
|
|
25
34
|
if (value !== undefined) {
|
|
@@ -40,10 +49,30 @@ export function configToRecord(config, explicitlySetKeys) {
|
|
|
40
49
|
result[key] = value;
|
|
41
50
|
}
|
|
42
51
|
}
|
|
52
|
+
// The `registry` / `@scope:registry` rows show the merged routes — the
|
|
53
|
+
// values `config get` answers — so a raw `.npmrc` row cannot contradict
|
|
54
|
+
// the resolved `registries` view.
|
|
55
|
+
for (const [scope, url] of Object.entries(config.registriesByScope ?? {})) {
|
|
56
|
+
result[scope === 'default' ? 'registry' : `${scope}:registry`] = url;
|
|
57
|
+
}
|
|
43
58
|
// Always include user-agent for debugging connectivity issues
|
|
44
59
|
if (config.userAgent) {
|
|
45
60
|
result.userAgent = config.userAgent;
|
|
46
61
|
}
|
|
62
|
+
result.registries = toResolvedRegistryDeclarations(pickRegistryContext(config));
|
|
63
|
+
const update = toUpdateSettings(config.updateConfig);
|
|
64
|
+
if (update != null) {
|
|
65
|
+
result.update = update;
|
|
66
|
+
}
|
|
67
|
+
const audit = toAuditSettings(config);
|
|
68
|
+
if (audit != null) {
|
|
69
|
+
result.audit = audit;
|
|
70
|
+
}
|
|
71
|
+
// `catalogs` shows the complete resolved catalog set — the singular
|
|
72
|
+
// `catalog` block is its `default` entry — whichever spelling declared it.
|
|
73
|
+
if (config.catalogs != null && Object.values(config.catalogs).some((catalog) => catalog != null)) {
|
|
74
|
+
result.catalogs = config.catalogs;
|
|
75
|
+
}
|
|
47
76
|
return censorProtectedSettings(sortDirectKeys(result));
|
|
48
77
|
}
|
|
49
78
|
//# sourceMappingURL=configToRecord.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pnpm/config.commands",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "1101.0.0",
|
|
4
4
|
"description": "Commands for reading and writing settings to/from config files",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pnpm",
|
|
@@ -28,14 +28,15 @@
|
|
|
28
28
|
"!*.map"
|
|
29
29
|
],
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@pnpm/cli.utils": "1101.0.
|
|
32
|
-
"@pnpm/config.
|
|
33
|
-
"@pnpm/
|
|
34
|
-
"@pnpm/
|
|
31
|
+
"@pnpm/cli.utils": "1101.0.24",
|
|
32
|
+
"@pnpm/config.normalize-registries": "1101.0.0",
|
|
33
|
+
"@pnpm/config.reader": "1102.0.0",
|
|
34
|
+
"@pnpm/constants": "1102.0.0",
|
|
35
|
+
"@pnpm/error": "1100.1.3",
|
|
35
36
|
"@pnpm/object.key-sorting": "1100.0.2",
|
|
36
|
-
"@pnpm/object.property-path": "1100.1.
|
|
37
|
+
"@pnpm/object.property-path": "1100.1.5",
|
|
37
38
|
"@pnpm/text.naming-cases": "1100.0.2",
|
|
38
|
-
"@pnpm/workspace.workspace-manifest-writer": "1100.
|
|
39
|
+
"@pnpm/workspace.workspace-manifest-writer": "1100.1.1",
|
|
39
40
|
"camelcase": "^9.0.0",
|
|
40
41
|
"ini": "6.0.0",
|
|
41
42
|
"lodash.kebabcase": "^4.1.1",
|
|
@@ -49,9 +50,9 @@
|
|
|
49
50
|
},
|
|
50
51
|
"devDependencies": {
|
|
51
52
|
"@jest/globals": "30.4.1",
|
|
52
|
-
"@pnpm/config.commands": "
|
|
53
|
+
"@pnpm/config.commands": "1101.0.0",
|
|
53
54
|
"@pnpm/logger": "1100.0.0",
|
|
54
|
-
"@pnpm/prepare": "1100.0.
|
|
55
|
+
"@pnpm/prepare": "1100.0.27",
|
|
55
56
|
"@types/ini": "4.1.1",
|
|
56
57
|
"@types/lodash.kebabcase": "4.1.9",
|
|
57
58
|
"read-yaml-file": "^3.0.0"
|