pnpm-settings-migrator 0.10.0 → 0.12.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.
Files changed (5) hide show
  1. package/README.md +130 -17
  2. package/dist/cli.mjs +2249 -1562
  3. package/dist/index.d.mts +333 -84
  4. package/dist/index.mjs +2007 -1327
  5. package/package.json +10 -9
package/README.md CHANGED
@@ -85,19 +85,70 @@ Sort keys when write `pnpm-workspace.yaml`.
85
85
  - **Type**: `'auto' | 'v10' | 'v11' | 'v12'`
86
86
  - **Default**: `'auto'`
87
87
 
88
- Compatibility target for migrated settings:
88
+ Compatibility major for migrated settings:
89
89
 
90
- - `auto`: infer from `packageManager` or `devEngines.packageManager`
91
- (`pnpm@12+` => `v12`, `pnpm@11` => `v11`, otherwise `v10`)
92
- - `v10`: keep legacy settings as-is and migrate schema-aligned pnpm config keys from `.npmrc`
93
- - `v11`: normalize to v11-compatible settings (`allowBuilds`, `allowUnusedPatches`, etc.)
94
- and migrate recognized project settings from `.npmrc` to `pnpm-workspace.yaml`
95
- - `v12`: use the shared v11 schema plus the v12 delta, including
96
- `globalShims`, while rejecting v11-only workspace settings.
90
+ - `auto`: infer from `targetVersion`, `packageManager`, or
91
+ `devEngines.packageManager` (`pnpm@12+` => `v12`, `pnpm@11` => `v11`,
92
+ otherwise `v10`).
93
+ - `v10`: keep legacy settings and migrate schema-aligned pnpm config keys from `.npmrc`.
94
+ - `v11`: normalize to v11-compatible settings (`allowBuilds`, `allowUnusedPatches`, etc.).
95
+ - `v12`: use the v12 schema, including `globalShims`, and enable additional
96
+ fields according to the confirmed target version.
97
+
98
+ An explicit major still uses a matching version from the project declarations.
99
+ For example, `--compatibility v12` with `packageManager: "pnpm@12.4.0"` enables
100
+ 12.4 capabilities. A pin to another major supplies no minor capabilities for
101
+ the selected major; use `--target-version` to state the intended release.
97
102
 
98
103
  In `v11` and `v12` modes, the migrator validates existing workspace keys,
99
- filters incoming settings against the selected schema, and applies required
100
- normalization to legacy files and `pnpm-workspace.yaml`.
104
+ filters incoming settings against the resolved capabilities, and applies
105
+ required normalization to legacy files and `pnpm-workspace.yaml`.
106
+
107
+ ### `--target-version`
108
+
109
+ - **Type**: `string` (an exact version such as `'12.4.0'`)
110
+ - **Default**: inferred from the project when possible
111
+
112
+ Override the target pnpm version without changing the project's package manager
113
+ pin. Resolution order is explicit `targetVersion`, then `packageManager`, then
114
+ `devEngines.packageManager`. An explicit `compatibility` major must agree with
115
+ `targetVersion`; conflicts fail before any files are written.
116
+
117
+ ```ts
118
+ await migratePnpmSettings() // Infer the target from the project
119
+ await migratePnpmSettings({ compatibility: 'v12' }) // Infer a matching minor
120
+ await migratePnpmSettings({ targetVersion: '12.4.0' }) // Target this exact release
121
+ ```
122
+
123
+ Version ranges are not accepted by `targetVersion`. Project ranges, conflicting
124
+ `devEngines` entries, prereleases, and declarations without a confirmed matching
125
+ version retain the base major schema. Build metadata on exact stable versions
126
+ is accepted. Later stable minors automatically inherit known capabilities;
127
+ there are no minor-specific compatibility options.
128
+
129
+ For pnpm 12.4.0 and later stable v12 releases, the migrator additionally accepts
130
+ `trustPolicyExcludePrune`, `python`, `cargo`, `pipelines`, `pipelineBase`, and
131
+ `packageConfigs`, plus task fields `outputs`, `inputs`, `env`, `cache`, and
132
+ `cargoTargetDir`. On older or unconfirmed targets, a `tasks` object containing
133
+ these fields stays in its source as a whole.
134
+
135
+ For pnpm 12.5.0 and later stable v12 releases, the migrator also accepts
136
+ `concurrencyGroups`, task `concurrencyGroup`, platform lists in
137
+ `supportedArchitectures`, Python `versions` / `overrides` / `constraints`, and
138
+ `registries` declarations with `ecosystem`. Python registry `packages` routes
139
+ require 12.5.1. Unsupported nested settings stay in their source as a whole.
140
+ The legacy OS/CPU/libc architecture mapping continues to work.
141
+
142
+ pnpm 12.5 removes `python.indexUrl` and `cargo.indexUrl`. Settings containing
143
+ these fields are retained with an incompatibility warning; existing workspaces
144
+ containing them fail validation before any files are written. Replace them with
145
+ URL-keyed `registries` entries using `ecosystem: pypi` or `ecosystem: cargo`.
146
+ The registry prefix `pkg` is reserved from 12.5 onward. Tool download mirrors
147
+ under `tools` belong in global `config.yaml` or `PNPM_CONFIG_TOOLS` and are
148
+ never migrated into the project workspace.
149
+
150
+ On the v11 line, `trustPolicyExcludePrune` requires a confirmed stable version
151
+ from 11.27.0 onward; v12 support still starts at 12.4.0.
101
152
 
102
153
  Automated v10 to v11 conversions include:
103
154
 
@@ -116,20 +167,46 @@ Automated v10 to v11 conversions include:
116
167
  Notes:
117
168
 
118
169
  - `.npmrc` migration is aligned with the target pnpm workspace schema. Unknown
119
- keys and settings supported only by a different pnpm major stay in `.npmrc`
170
+ keys and settings supported only by a different pnpm version stay in `.npmrc`
120
171
  with a warning.
172
+ - Scalar list settings such as `public-hoist-pattern=*eslint*` become YAML
173
+ arrays (`publicHoistPattern: ['*eslint*']`). Existing arrays and patterns
174
+ containing commas are preserved without splitting their values.
121
175
  - In `v11` and `v12`, auth/registry keys and project-refused machine settings
122
176
  such as `globalDir`, `stateDir`, `configDir`, and `scope` stay in `.npmrc`.
123
177
  - Registry declarations containing embedded credentials or dynamic `${...}`
124
178
  URLs stay in their source with a warning.
125
- - In v11 workspaces, supported subproject `.npmrc` fields are moved to
126
- `packageConfigs` by package name. pnpm v11 accepts `hoist`, `modulesDir`,
127
- `overrides`, `saveExact`, and `savePrefix` there. pnpm v12 does not support
128
- `packageConfigs`, so subproject settings are retained with a warning.
179
+ - Dynamic `${...}` values in `httpProxy`, `httpsProxy`, `noProxy`, `proxy`, and
180
+ `noproxy` stay in their source for every target. Project YAML does not expand
181
+ these placeholders; configure them globally in trusted configuration or use
182
+ environment variables. Existing dynamic proxy settings in YAML block migration.
183
+ The migrator never expands and writes these values.
184
+ - pnpm v11 and confirmed stable v12 targets from 12.4.0 accept `packageConfigs`
185
+ as package-name maps or matcher arrays, with `hoist`, `modulesDir`,
186
+ `overrides`, `saveExact`, and `savePrefix`. Supported subproject `.npmrc`
187
+ fields are moved there by package name. pnpm 12.0–12.3 does not support
188
+ `packageConfigs`.
189
+ - For v12 targets from 12.4.0, migrating `packageConfigs` or subproject settings
190
+ requires `sharedWorkspaceLockfile: false` in the merged workspace. Otherwise
191
+ source settings remain with a warning; existing `packageConfigs` blocks
192
+ migration until the effective lockfile mode is compatible. This restriction
193
+ does not apply to v11. The migrator does not change this mode automatically.
129
194
  - Cleanup removes only source keys represented in the final workspace after
130
195
  applying the selected merge strategy.
196
+ Each source is checked against its own values, including deprecated-key
197
+ replacements. Conflicting values in `.npmrc`, `package.json#pnpm`, or Yarn
198
+ resolutions remain in their original source.
131
199
  Unrecognized, refused, incompatible, or otherwise unsupported
132
200
  `package.json#pnpm` child keys remain in `package.json`.
201
+ INI sections in `.npmrc` are retained conservatively; their child names are
202
+ never treated as root keys during cleanup.
203
+ - Runtime migration writes `devEngines.runtime` before removing a workspace
204
+ runtime declaration. A failed write preserves source settings for retry.
205
+ If an existing runtime declaration conflicts with a workspace runtime, migration
206
+ stops before writing any files. An identical Node.js declaration is reused.
207
+ - YAML aliases remain when their anchors are unchanged and precede them.
208
+ If replacement, removal, or sorting would invalidate an alias, its original
209
+ value is written explicitly so unrelated settings keep their values.
133
210
  - If no auth/registry lines remain after a v11 or v12 migration, the empty
134
211
  `.npmrc` is removed.
135
212
  - Values moved from `auditConfig.ignoreCves` still contain CVE IDs. Replace them
@@ -137,11 +214,31 @@ Notes:
137
214
  - The migrator does not update the `packageManager` version, CI environment variables,
138
215
  shell setup, or pnpm commands in scripts. When `packageManager` still pins pnpm 10,
139
216
  pass `--compatibility v11` explicitly and update the pin separately.
140
- - pnpm 12 is stable; this project verifies migrated output against pnpm 12.2.1
141
- as well as pnpm 11.25.0. Its removed `pnpm install --resolution-only` CLI
217
+ - Compatibility checks cover pnpm 11.27.1 and 12.5.1, retaining 11.25.0,
218
+ 11.26.0, 12.2.1, 12.3.4, 12.4.0, 12.4.2, and 12.5.0 regressions.
219
+ As audited on 2026-09-22, npm `latest` is 12.5.1 and `latest-11` is 11.27.1;
220
+ the project is pinned to 12.5.1. Its removed `pnpm install --resolution-only` CLI
142
221
  flag is outside this settings migrator's scope; replace it with
143
222
  `pnpm peers check` in scripts before upgrading.
144
223
 
224
+ For example, `--target-version 12.4.0` migrates this legacy configuration:
225
+
226
+ ```json
227
+ { "pnpm": { "pipelines": { "ci": ["build", "test"] }, "pipelineBase": "main" } }
228
+ ```
229
+
230
+ into `pnpm-workspace.yaml` and removes the applied `pnpm` keys:
231
+
232
+ ```yaml
233
+ pipelines:
234
+ ci: [build, test]
235
+ pipelineBase: main
236
+ ```
237
+
238
+ With `--target-version 12.3.4`, these settings remain in `package.json` with an
239
+ incompatibility warning. See the [version audit](docs/research/pnpm-recent-settings-audit-2026-09-10.md)
240
+ for the upstream release and schema references.
241
+
145
242
  ### `--replace-deprecated`
146
243
 
147
244
  - **Type**: `boolean`
@@ -179,6 +276,22 @@ Strategy to handle conflicts when merging settings with existing `pnpm-workspace
179
276
 
180
277
  Disable migrating `resolutions` field in `package.json`.
181
278
 
279
+ By default, plain package names are copied to pnpm overrides and global Yarn
280
+ selectors are translated: `**/foo` becomes `foo`, and `**/@scope/foo` becomes
281
+ `@scope/foo`. Path-specific selectors such as `parent/child` and
282
+ `parent/**/child` remain in `resolutions` with a warning. Conflicting selectors
283
+ that translate to the same pnpm key also remain for manual resolution.
284
+ Only individual resolutions whose values reach the final workspace are removed.
285
+
286
+ For example, an unsupported selector is now reported and retained instead of
287
+ being copied into an override that prevents pnpm from installing:
288
+
289
+ ```text
290
+ WARN Kept Yarn resolution "parent/**/child" in package.json: its selector cannot be translated safely to pnpm overrides.
291
+
292
+ ℹ No changes needed.
293
+ ```
294
+
182
295
  ### `--no-show-changes`
183
296
 
184
297
  - **Type**: `boolean`