pnpm-settings-migrator 0.2.0 → 0.4.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/README.md +12 -0
- package/dist/cli.mjs +147 -27
- package/dist/index.d.mts +50 -3
- package/dist/index.mjs +149 -27
- package/package.json +19 -17
package/README.md
CHANGED
|
@@ -31,6 +31,18 @@ Current working directory.
|
|
|
31
31
|
|
|
32
32
|
Sort keys when write `pnpm-workspace.yaml`.
|
|
33
33
|
|
|
34
|
+
### `--compatibility`
|
|
35
|
+
|
|
36
|
+
- **Type**: `'auto' | 'v10' | 'v11'`
|
|
37
|
+
- **Default**: `'auto'`
|
|
38
|
+
|
|
39
|
+
Compatibility target for migrated settings:
|
|
40
|
+
|
|
41
|
+
- `auto`: infer from `packageManager` (`pnpm@11+` => `v11`, otherwise `v10`)
|
|
42
|
+
- `v10`: keep legacy settings as-is
|
|
43
|
+
- `v11`: normalize to v11-compatible settings (`allowBuilds`, `allowUnusedPatches`, etc.)
|
|
44
|
+
and migrate all non auth/registry `.npmrc` entries to `pnpm-workspace.yaml`
|
|
45
|
+
|
|
34
46
|
### `--strategy`
|
|
35
47
|
|
|
36
48
|
- **Type**: `'discard' | 'merge' | 'overwrite'`
|
package/dist/cli.mjs
CHANGED
|
@@ -11,21 +11,15 @@ import { getColor } from "consola/utils";
|
|
|
11
11
|
import camelcaseKeys from "camelcase-keys";
|
|
12
12
|
import { readIniFile } from "read-ini-file";
|
|
13
13
|
import { kebabCase } from "uncase";
|
|
14
|
-
|
|
15
14
|
//#region package.json
|
|
16
15
|
var name = "pnpm-settings-migrator";
|
|
17
|
-
var version = "0.
|
|
18
|
-
|
|
16
|
+
var version = "0.4.0";
|
|
19
17
|
//#endregion
|
|
20
18
|
//#region src/constants.ts
|
|
21
19
|
const NPMRC = ".npmrc";
|
|
22
20
|
const PACKAGE_JSON = "package.json";
|
|
23
21
|
const PNPM_WORKSPACE_YAML = "pnpm-workspace.yaml";
|
|
24
22
|
/**
|
|
25
|
-
* Default indent: 2 spaces
|
|
26
|
-
*/
|
|
27
|
-
const DEFAULT_INDENT = 2;
|
|
28
|
-
/**
|
|
29
23
|
* @see {@link https://github.com/pnpm/pnpm/blob/main/packages/types/src/package.ts}
|
|
30
24
|
*/
|
|
31
25
|
const PNPM_SETTINGS_FIELDS = [
|
|
@@ -36,21 +30,34 @@ const PNPM_SETTINGS_FIELDS = [
|
|
|
36
30
|
"auditConfig",
|
|
37
31
|
"configDependencies",
|
|
38
32
|
"executionEnv",
|
|
33
|
+
"httpProxy",
|
|
34
|
+
"httpsProxy",
|
|
39
35
|
"ignoredBuiltDependencies",
|
|
40
36
|
"ignoredOptionalDependencies",
|
|
41
37
|
"ignorePatchFailures",
|
|
42
38
|
"neverBuiltDependencies",
|
|
39
|
+
"nodeDownloadMirrors",
|
|
40
|
+
"noProxy",
|
|
41
|
+
"npmrcAuthFile",
|
|
43
42
|
"onlyBuiltDependencies",
|
|
44
43
|
"onlyBuiltDependenciesFile",
|
|
45
44
|
"overrides",
|
|
46
45
|
"packageExtensions",
|
|
47
46
|
"patchedDependencies",
|
|
48
47
|
"peerDependencyRules",
|
|
48
|
+
"registries",
|
|
49
49
|
"requiredScripts",
|
|
50
50
|
"supportedArchitectures",
|
|
51
51
|
"updateConfig"
|
|
52
52
|
];
|
|
53
|
-
|
|
53
|
+
const PNPM_V11_REMOVED_SETTINGS = [
|
|
54
|
+
"allowNonAppliedPatches",
|
|
55
|
+
"ignorePatchFailures",
|
|
56
|
+
"ignoredBuiltDependencies",
|
|
57
|
+
"neverBuiltDependencies",
|
|
58
|
+
"onlyBuiltDependencies",
|
|
59
|
+
"onlyBuiltDependenciesFile"
|
|
60
|
+
];
|
|
54
61
|
//#endregion
|
|
55
62
|
//#region src/options.ts
|
|
56
63
|
/**
|
|
@@ -59,6 +66,7 @@ const PNPM_SETTINGS_FIELDS = [
|
|
|
59
66
|
const DEFAULT_OPTIONS = {
|
|
60
67
|
cleanNpmrc: true,
|
|
61
68
|
cleanPackageJson: true,
|
|
69
|
+
compatibility: "auto",
|
|
62
70
|
cwd: process.cwd(),
|
|
63
71
|
newlineBetween: true,
|
|
64
72
|
sortKeys: false,
|
|
@@ -70,6 +78,11 @@ const VALID_STRATEGIES = [
|
|
|
70
78
|
"merge",
|
|
71
79
|
"overwrite"
|
|
72
80
|
];
|
|
81
|
+
const VALID_COMPATIBILITIES = [
|
|
82
|
+
"auto",
|
|
83
|
+
"v10",
|
|
84
|
+
"v11"
|
|
85
|
+
];
|
|
73
86
|
/**
|
|
74
87
|
* Resolve and normalize migration options with defaults.
|
|
75
88
|
*
|
|
@@ -94,6 +107,7 @@ const VALID_STRATEGIES = [
|
|
|
94
107
|
function resolveOptions(options = {}) {
|
|
95
108
|
return {
|
|
96
109
|
cleanNpmrc: options.cleanNpmrc ?? DEFAULT_OPTIONS.cleanNpmrc,
|
|
110
|
+
compatibility: resolveCompatibility(options.compatibility),
|
|
97
111
|
cwd: options.cwd ?? DEFAULT_OPTIONS.cwd,
|
|
98
112
|
newlineBetween: options.newlineBetween ?? DEFAULT_OPTIONS.newlineBetween,
|
|
99
113
|
sortKeys: options.sortKeys ?? DEFAULT_OPTIONS.sortKeys,
|
|
@@ -102,12 +116,16 @@ function resolveOptions(options = {}) {
|
|
|
102
116
|
cleanPackageJson: options.cleanPackageJson ?? DEFAULT_OPTIONS.cleanPackageJson
|
|
103
117
|
};
|
|
104
118
|
}
|
|
119
|
+
function resolveCompatibility(compatibility) {
|
|
120
|
+
if (!compatibility) return DEFAULT_OPTIONS.compatibility;
|
|
121
|
+
if (VALID_COMPATIBILITIES.includes(compatibility)) return compatibility;
|
|
122
|
+
throw new Error(`Invalid compatibility: ${compatibility}. Expected one of: ${VALID_COMPATIBILITIES.join(", ")}`);
|
|
123
|
+
}
|
|
105
124
|
function resolveStrategy(strategy) {
|
|
106
125
|
if (!strategy) return DEFAULT_OPTIONS.strategy;
|
|
107
126
|
if (VALID_STRATEGIES.includes(strategy)) return strategy;
|
|
108
127
|
throw new Error(`Invalid strategy: ${strategy}. Expected one of: ${VALID_STRATEGIES.join(", ")}`);
|
|
109
128
|
}
|
|
110
|
-
|
|
111
129
|
//#endregion
|
|
112
130
|
//#region src/utils/fs.ts
|
|
113
131
|
/**
|
|
@@ -134,17 +152,13 @@ async function fsReadFile(path) {
|
|
|
134
152
|
async function fsWriteFile(path, content) {
|
|
135
153
|
await writeFile(path, `${content.trimEnd()}\n`, "utf-8");
|
|
136
154
|
}
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
//#region src/utils/color.ts
|
|
140
|
-
const cyan = getColor("cyan");
|
|
141
|
-
const yellow = getColor("yellow");
|
|
155
|
+
getColor("cyan");
|
|
156
|
+
getColor("yellow");
|
|
142
157
|
const dim = getColor("dim");
|
|
143
158
|
const green = getColor("green");
|
|
144
159
|
const red = getColor("red");
|
|
145
160
|
const bold = getColor("bold");
|
|
146
161
|
const magenta = getColor("magenta");
|
|
147
|
-
|
|
148
162
|
//#endregion
|
|
149
163
|
//#region src/utils/merge.ts
|
|
150
164
|
/**
|
|
@@ -220,9 +234,24 @@ function mergeWithArrayDedupe(existing, incoming) {
|
|
|
220
234
|
}
|
|
221
235
|
return result;
|
|
222
236
|
}
|
|
223
|
-
|
|
224
237
|
//#endregion
|
|
225
238
|
//#region src/utils/npmrc.ts
|
|
239
|
+
const NPMRC_AUTH_OR_REGISTRY_KEYS = [
|
|
240
|
+
"_auth",
|
|
241
|
+
"_authtoken",
|
|
242
|
+
"_password",
|
|
243
|
+
"always-auth",
|
|
244
|
+
"ca",
|
|
245
|
+
"cafile",
|
|
246
|
+
"cert",
|
|
247
|
+
"certfile",
|
|
248
|
+
"email",
|
|
249
|
+
"key",
|
|
250
|
+
"keyfile",
|
|
251
|
+
"otp",
|
|
252
|
+
"tokenhelper",
|
|
253
|
+
"username"
|
|
254
|
+
];
|
|
226
255
|
/**
|
|
227
256
|
* Remove pnpm-related settings from `.npmrc` file.
|
|
228
257
|
*
|
|
@@ -241,9 +270,15 @@ function mergeWithArrayDedupe(existing, incoming) {
|
|
|
241
270
|
* await pruneNpmrc('/path/to/.npmrc')
|
|
242
271
|
* ```
|
|
243
272
|
*/
|
|
244
|
-
async function pruneNpmrc(path) {
|
|
273
|
+
async function pruneNpmrc(path, compatibility = "v10", migratedKeys = []) {
|
|
245
274
|
const pnpmSettingsFields = PNPM_SETTINGS_FIELDS.map((v) => kebabCase(v));
|
|
246
|
-
|
|
275
|
+
const migratedKeySet = new Set(migratedKeys.map(normalizeNpmrcKey));
|
|
276
|
+
await fsWriteFile(path, (await fsReadFile(path)).split(/\r?\n/).filter((line) => {
|
|
277
|
+
const key = getNpmrcLineKey(line);
|
|
278
|
+
if (!key) return true;
|
|
279
|
+
if (compatibility === "v11") return !migratedKeySet.has(normalizeNpmrcKey(key));
|
|
280
|
+
return !pnpmSettingsFields.some((v) => key.startsWith(v));
|
|
281
|
+
}).join("\n"));
|
|
247
282
|
}
|
|
248
283
|
/**
|
|
249
284
|
* Read and parse `.npmrc` file with camelCase key conversion.
|
|
@@ -264,10 +299,57 @@ async function pruneNpmrc(path) {
|
|
|
264
299
|
* // config.allowBuilds, config.packageExtensions, etc.
|
|
265
300
|
* ```
|
|
266
301
|
*/
|
|
302
|
+
/**
|
|
303
|
+
* Read `.npmrc` and return settings that should be migrated into workspace config.
|
|
304
|
+
*
|
|
305
|
+
* - `v10`: returns all keys (legacy whitelist filtering happens in caller).
|
|
306
|
+
* - `v11`: excludes auth/registry keys because pnpm still reads them from `.npmrc`.
|
|
307
|
+
*/
|
|
308
|
+
async function readMigratableNpmrc(path, compatibility) {
|
|
309
|
+
const raw = await readIniFile(path);
|
|
310
|
+
if (compatibility === "v10") return {
|
|
311
|
+
keys: Object.keys(raw),
|
|
312
|
+
settings: camelcaseKeys(raw)
|
|
313
|
+
};
|
|
314
|
+
const migratable = {};
|
|
315
|
+
const keys = [];
|
|
316
|
+
for (const [key, value] of Object.entries(raw)) if (!isNpmrcAuthOrRegistryKey(key)) {
|
|
317
|
+
migratable[key] = value;
|
|
318
|
+
keys.push(key);
|
|
319
|
+
}
|
|
320
|
+
return {
|
|
321
|
+
keys,
|
|
322
|
+
settings: camelcaseKeys(migratable)
|
|
323
|
+
};
|
|
324
|
+
}
|
|
267
325
|
async function readNpmrc(path) {
|
|
268
326
|
return camelcaseKeys(await readIniFile(path));
|
|
269
327
|
}
|
|
270
|
-
|
|
328
|
+
/**
|
|
329
|
+
* Extract key name from a raw `.npmrc` line.
|
|
330
|
+
*/
|
|
331
|
+
function getNpmrcLineKey(line) {
|
|
332
|
+
const trimmed = line.trim();
|
|
333
|
+
if (!trimmed || trimmed.startsWith(";") || trimmed.startsWith("#")) return;
|
|
334
|
+
const index = trimmed.indexOf("=");
|
|
335
|
+
if (index <= 0) return;
|
|
336
|
+
return normalizeNpmrcKey(trimmed.slice(0, index));
|
|
337
|
+
}
|
|
338
|
+
/**
|
|
339
|
+
* Check whether a `.npmrc` key is auth/registry-related and should stay in v11.
|
|
340
|
+
*/
|
|
341
|
+
function isNpmrcAuthOrRegistryKey(key) {
|
|
342
|
+
const normalized = normalizeNpmrcKey(key);
|
|
343
|
+
if (normalized.startsWith("//")) return true;
|
|
344
|
+
if (normalized === "registry" || normalized.endsWith(":registry")) return true;
|
|
345
|
+
return NPMRC_AUTH_OR_REGISTRY_KEYS.some((v) => normalized === v || normalized.endsWith(`:${v}`));
|
|
346
|
+
}
|
|
347
|
+
/**
|
|
348
|
+
* Normalize `.npmrc` key for case-insensitive matching.
|
|
349
|
+
*/
|
|
350
|
+
function normalizeNpmrcKey(key) {
|
|
351
|
+
return key.trim().replace(/\[\]$/, "").toLowerCase();
|
|
352
|
+
}
|
|
271
353
|
//#endregion
|
|
272
354
|
//#region src/core.ts
|
|
273
355
|
/**
|
|
@@ -321,9 +403,9 @@ async function migratePnpmSettings(rawOptions = {}) {
|
|
|
321
403
|
consola.warn("No pnpm settings files to migrate");
|
|
322
404
|
return;
|
|
323
405
|
}
|
|
324
|
-
let packageJsonIndent =
|
|
406
|
+
let packageJsonIndent = 2;
|
|
325
407
|
let packageJsonObject = {};
|
|
326
|
-
let pnpmWorkspaceYamlIndent =
|
|
408
|
+
let pnpmWorkspaceYamlIndent = 2;
|
|
327
409
|
let pnpmWorkspaceYamlObject = {};
|
|
328
410
|
if (packageJsonExists) {
|
|
329
411
|
const content = await fsReadFile(packageJsonPath);
|
|
@@ -335,7 +417,15 @@ async function migratePnpmSettings(rawOptions = {}) {
|
|
|
335
417
|
pnpmWorkspaceYamlIndent = detectIndent(content).amount;
|
|
336
418
|
pnpmWorkspaceYamlObject = parse(content);
|
|
337
419
|
}
|
|
338
|
-
const
|
|
420
|
+
const compatibility = resolveCompatibilityTarget(options.compatibility, packageJsonObject.packageManager);
|
|
421
|
+
const npmrcMigratable = npmrcExists ? compatibility === "v10" ? {
|
|
422
|
+
keys: PNPM_SETTINGS_FIELDS,
|
|
423
|
+
settings: pick(await readNpmrc(npmrcPath), PNPM_SETTINGS_FIELDS)
|
|
424
|
+
} : await readMigratableNpmrc(npmrcPath, compatibility) : {
|
|
425
|
+
keys: [],
|
|
426
|
+
settings: {}
|
|
427
|
+
};
|
|
428
|
+
const pnpmSettingsInNpmrc = npmrcMigratable.settings;
|
|
339
429
|
const hasPnpmInPackageJson = !!packageJsonObject.pnpm;
|
|
340
430
|
const hasResolutions = options.yarnResolutions && !!packageJsonObject.resolutions;
|
|
341
431
|
const hasNpmrcSettings = Object.keys(pnpmSettingsInNpmrc).length > 0;
|
|
@@ -352,6 +442,7 @@ async function migratePnpmSettings(rawOptions = {}) {
|
|
|
352
442
|
...pnpmSettingsInNpmrc,
|
|
353
443
|
...pnpmSettingsInPackageJson
|
|
354
444
|
};
|
|
445
|
+
normalizeIncomingSettings(incomingSettings, compatibility);
|
|
355
446
|
const pnpmWorkspaceResult = mergeByStrategy(pnpmWorkspaceYamlObject, incomingSettings, options.strategy);
|
|
356
447
|
const yamlDocument = new Document({}, { sortMapEntries: options.sortKeys });
|
|
357
448
|
Object.entries(pnpmWorkspaceResult).forEach(([key, value]) => {
|
|
@@ -362,7 +453,7 @@ async function migratePnpmSettings(rawOptions = {}) {
|
|
|
362
453
|
});
|
|
363
454
|
const yamlContent = yamlDocument.toString({ indent: pnpmWorkspaceYamlIndent });
|
|
364
455
|
await fsWriteFile(pnpmWorkspaceYamlPath, options.newlineBetween ? yamlContent.replace(/\n(?=[^\s#][^:\n]*:)/g, "\n\n") : yamlContent);
|
|
365
|
-
if (npmrcExists && options.cleanNpmrc) await pruneNpmrc(npmrcPath);
|
|
456
|
+
if (npmrcExists && options.cleanNpmrc) await pruneNpmrc(npmrcPath, compatibility, npmrcMigratable.keys);
|
|
366
457
|
if (packageJsonExists && options.cleanPackageJson && (packageJsonObject.pnpm || packageJsonObject.resolutions)) {
|
|
367
458
|
delete packageJsonObject.pnpm;
|
|
368
459
|
if (options.yarnResolutions) delete packageJsonObject.resolutions;
|
|
@@ -373,11 +464,41 @@ async function migratePnpmSettings(rawOptions = {}) {
|
|
|
373
464
|
throw err;
|
|
374
465
|
}
|
|
375
466
|
}
|
|
376
|
-
|
|
467
|
+
/**
|
|
468
|
+
* Build v11 `allowBuilds` map from legacy build-script settings.
|
|
469
|
+
*/
|
|
470
|
+
function collectAllowBuildsFromLegacy(incomingSettings) {
|
|
471
|
+
const allowBuilds = {};
|
|
472
|
+
for (const name of incomingSettings.onlyBuiltDependencies || []) allowBuilds[name] = true;
|
|
473
|
+
for (const name of incomingSettings.ignoredBuiltDependencies || []) allowBuilds[name] = false;
|
|
474
|
+
for (const name of incomingSettings.neverBuiltDependencies || []) allowBuilds[name] = false;
|
|
475
|
+
return Object.keys(allowBuilds).length ? allowBuilds : void 0;
|
|
476
|
+
}
|
|
477
|
+
/**
|
|
478
|
+
* Normalize incoming settings according to compatibility target.
|
|
479
|
+
*/
|
|
480
|
+
function normalizeIncomingSettings(incomingSettings, compatibility) {
|
|
481
|
+
if (compatibility === "v10") return;
|
|
482
|
+
if (incomingSettings.allowNonAppliedPatches !== void 0) incomingSettings.allowUnusedPatches = incomingSettings.allowUnusedPatches ?? incomingSettings.allowNonAppliedPatches;
|
|
483
|
+
const allowBuildsFromLegacy = collectAllowBuildsFromLegacy(incomingSettings);
|
|
484
|
+
if (allowBuildsFromLegacy) incomingSettings.allowBuilds = {
|
|
485
|
+
...allowBuildsFromLegacy,
|
|
486
|
+
...incomingSettings.allowBuilds || {}
|
|
487
|
+
};
|
|
488
|
+
for (const key of PNPM_V11_REMOVED_SETTINGS) delete incomingSettings[key];
|
|
489
|
+
}
|
|
490
|
+
/**
|
|
491
|
+
* Resolve final compatibility target from user option and package manager hint.
|
|
492
|
+
*/
|
|
493
|
+
function resolveCompatibilityTarget(compatibility, packageManager) {
|
|
494
|
+
if (compatibility !== "auto") return compatibility;
|
|
495
|
+
const [, major] = (packageManager || "").match(/^pnpm@(\d+)(?:\.|$)/) || [];
|
|
496
|
+
return Number(major) >= 11 ? "v11" : "v10";
|
|
497
|
+
}
|
|
377
498
|
//#endregion
|
|
378
499
|
//#region src/cli.ts
|
|
379
500
|
const cli = cac(name);
|
|
380
|
-
cli.version(version).option("--cwd [cwd]", "Current working directory").option("--sort-keys", "Sort keys when write pnpm-workspace.yaml").option("--strategy <strategy>", "Strategy to handle conflicts (discard, merge, overwrite)").option("--no-yarn-resolutions", "Disable migrating resolutions field in package.json").option("--no-newline-between", "Disable adding newlines between each root keys").option("--no-clean-npmrc", "Disable removing pnpm settings in .npmrc file").option("--no-clean-package-json", "Disable removing pnpm fields in package.json").help();
|
|
501
|
+
cli.version(version).option("--cwd [cwd]", "Current working directory").option("--sort-keys", "Sort keys when write pnpm-workspace.yaml").option("--compatibility <compatibility>", "Compatibility target (auto, v10, v11)").option("--strategy <strategy>", "Strategy to handle conflicts (discard, merge, overwrite)").option("--no-yarn-resolutions", "Disable migrating resolutions field in package.json").option("--no-newline-between", "Disable adding newlines between each root keys").option("--no-clean-npmrc", "Disable removing pnpm settings in .npmrc file").option("--no-clean-package-json", "Disable removing pnpm fields in package.json").help();
|
|
381
502
|
cli.command("").action(async (options) => {
|
|
382
503
|
try {
|
|
383
504
|
consola$1.log(`\n${bold(magenta(name))} ${dim(`v${version}`)}`);
|
|
@@ -391,6 +512,5 @@ cli.command("").action(async (options) => {
|
|
|
391
512
|
}
|
|
392
513
|
});
|
|
393
514
|
cli.parse();
|
|
394
|
-
|
|
395
515
|
//#endregion
|
|
396
|
-
export {
|
|
516
|
+
export {};
|
package/dist/index.d.mts
CHANGED
|
@@ -2,7 +2,11 @@ import { PnpmSettings } from "@pnpm/types";
|
|
|
2
2
|
|
|
3
3
|
//#region src/types.d.ts
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
5
|
+
* Compatibility target used by the migrator.
|
|
6
|
+
*/
|
|
7
|
+
type CompatibilityTarget = 'auto' | 'v10' | 'v11';
|
|
8
|
+
/**
|
|
9
|
+
* Merge strategy for combining pnpm settings.
|
|
6
10
|
*/
|
|
7
11
|
type MergeStrategy = 'discard' | 'merge' | 'overwrite';
|
|
8
12
|
/**
|
|
@@ -21,6 +25,15 @@ interface Options {
|
|
|
21
25
|
* @default true
|
|
22
26
|
*/
|
|
23
27
|
cleanPackageJson?: boolean;
|
|
28
|
+
/**
|
|
29
|
+
* pnpm compatibility target.
|
|
30
|
+
* - `auto`: detect from `packageManager` (fallback to `v10`)
|
|
31
|
+
* - `v10`: keep legacy v10 settings
|
|
32
|
+
* - `v11`: normalize to v11-compatible settings
|
|
33
|
+
*
|
|
34
|
+
* @default 'auto'
|
|
35
|
+
*/
|
|
36
|
+
compatibility?: CompatibilityTarget;
|
|
24
37
|
/**
|
|
25
38
|
* Current working directory
|
|
26
39
|
*
|
|
@@ -68,6 +81,10 @@ interface PackageJson {
|
|
|
68
81
|
* @compatibility npm, bun
|
|
69
82
|
*/
|
|
70
83
|
overrides?: Record<string, string>;
|
|
84
|
+
/**
|
|
85
|
+
* Package manager declaration, for example `pnpm@11.0.0`
|
|
86
|
+
*/
|
|
87
|
+
packageManager?: string;
|
|
71
88
|
/**
|
|
72
89
|
* pnpm settings
|
|
73
90
|
*/
|
|
@@ -84,11 +101,41 @@ interface PackageJson {
|
|
|
84
101
|
* @pg
|
|
85
102
|
*/
|
|
86
103
|
type NpmRC = Record<string, any>;
|
|
104
|
+
/**
|
|
105
|
+
* Deprecated `pnpm` settings in `package.json`
|
|
106
|
+
* @see {@link https://github.com/pnpm/pnpm/blob/main/core/types/CHANGELOG.md#major-changes}
|
|
107
|
+
*/
|
|
108
|
+
interface PnpmSettingsDeprecated {
|
|
109
|
+
/**
|
|
110
|
+
* @deprecated
|
|
111
|
+
*/
|
|
112
|
+
allowNonAppliedPatches?: boolean;
|
|
113
|
+
/**
|
|
114
|
+
* @deprecated
|
|
115
|
+
*/
|
|
116
|
+
ignoredBuiltDependencies?: string[];
|
|
117
|
+
/**
|
|
118
|
+
* @deprecated
|
|
119
|
+
*/
|
|
120
|
+
ignorePatchFailures?: boolean;
|
|
121
|
+
/**
|
|
122
|
+
* @deprecated
|
|
123
|
+
*/
|
|
124
|
+
neverBuiltDependencies?: string[];
|
|
125
|
+
/**
|
|
126
|
+
* @deprecated
|
|
127
|
+
*/
|
|
128
|
+
onlyBuiltDependencies?: string[];
|
|
129
|
+
/**
|
|
130
|
+
* @deprecated
|
|
131
|
+
*/
|
|
132
|
+
onlyBuiltDependenciesFile?: string;
|
|
133
|
+
}
|
|
87
134
|
/**
|
|
88
135
|
* `pnpm-workspace` types
|
|
89
136
|
* @pg
|
|
90
137
|
*/
|
|
91
|
-
type PnpmWorkspace = PnpmSettings & PnpmWorkspaceLegacy;
|
|
138
|
+
type PnpmWorkspace = PnpmSettings & PnpmSettingsDeprecated & PnpmWorkspaceLegacy;
|
|
92
139
|
//#endregion
|
|
93
140
|
//#region src/core.d.ts
|
|
94
141
|
/**
|
|
@@ -151,4 +198,4 @@ declare function migratePnpmSettings(rawOptions?: Options): Promise<void>;
|
|
|
151
198
|
*/
|
|
152
199
|
declare function resolveOptions(options?: Options): Required<Options>;
|
|
153
200
|
//#endregion
|
|
154
|
-
export { MergeStrategy, NpmRC, Options, PackageJson, PnpmWorkspace, PnpmWorkspaceLegacy, migratePnpmSettings, resolveOptions };
|
|
201
|
+
export { CompatibilityTarget, MergeStrategy, NpmRC, Options, PackageJson, PnpmSettingsDeprecated, PnpmWorkspace, PnpmWorkspaceLegacy, migratePnpmSettings, resolveOptions };
|
package/dist/index.mjs
CHANGED
|
@@ -10,16 +10,11 @@ import { getColor } from "consola/utils";
|
|
|
10
10
|
import camelcaseKeys from "camelcase-keys";
|
|
11
11
|
import { readIniFile } from "read-ini-file";
|
|
12
12
|
import { kebabCase } from "uncase";
|
|
13
|
-
|
|
14
13
|
//#region src/constants.ts
|
|
15
14
|
const NPMRC = ".npmrc";
|
|
16
15
|
const PACKAGE_JSON = "package.json";
|
|
17
16
|
const PNPM_WORKSPACE_YAML = "pnpm-workspace.yaml";
|
|
18
17
|
/**
|
|
19
|
-
* Default indent: 2 spaces
|
|
20
|
-
*/
|
|
21
|
-
const DEFAULT_INDENT = 2;
|
|
22
|
-
/**
|
|
23
18
|
* @see {@link https://github.com/pnpm/pnpm/blob/main/packages/types/src/package.ts}
|
|
24
19
|
*/
|
|
25
20
|
const PNPM_SETTINGS_FIELDS = [
|
|
@@ -30,21 +25,34 @@ const PNPM_SETTINGS_FIELDS = [
|
|
|
30
25
|
"auditConfig",
|
|
31
26
|
"configDependencies",
|
|
32
27
|
"executionEnv",
|
|
28
|
+
"httpProxy",
|
|
29
|
+
"httpsProxy",
|
|
33
30
|
"ignoredBuiltDependencies",
|
|
34
31
|
"ignoredOptionalDependencies",
|
|
35
32
|
"ignorePatchFailures",
|
|
36
33
|
"neverBuiltDependencies",
|
|
34
|
+
"nodeDownloadMirrors",
|
|
35
|
+
"noProxy",
|
|
36
|
+
"npmrcAuthFile",
|
|
37
37
|
"onlyBuiltDependencies",
|
|
38
38
|
"onlyBuiltDependenciesFile",
|
|
39
39
|
"overrides",
|
|
40
40
|
"packageExtensions",
|
|
41
41
|
"patchedDependencies",
|
|
42
42
|
"peerDependencyRules",
|
|
43
|
+
"registries",
|
|
43
44
|
"requiredScripts",
|
|
44
45
|
"supportedArchitectures",
|
|
45
46
|
"updateConfig"
|
|
46
47
|
];
|
|
47
|
-
|
|
48
|
+
const PNPM_V11_REMOVED_SETTINGS = [
|
|
49
|
+
"allowNonAppliedPatches",
|
|
50
|
+
"ignorePatchFailures",
|
|
51
|
+
"ignoredBuiltDependencies",
|
|
52
|
+
"neverBuiltDependencies",
|
|
53
|
+
"onlyBuiltDependencies",
|
|
54
|
+
"onlyBuiltDependenciesFile"
|
|
55
|
+
];
|
|
48
56
|
//#endregion
|
|
49
57
|
//#region src/options.ts
|
|
50
58
|
/**
|
|
@@ -53,6 +61,7 @@ const PNPM_SETTINGS_FIELDS = [
|
|
|
53
61
|
const DEFAULT_OPTIONS = {
|
|
54
62
|
cleanNpmrc: true,
|
|
55
63
|
cleanPackageJson: true,
|
|
64
|
+
compatibility: "auto",
|
|
56
65
|
cwd: process.cwd(),
|
|
57
66
|
newlineBetween: true,
|
|
58
67
|
sortKeys: false,
|
|
@@ -64,6 +73,11 @@ const VALID_STRATEGIES = [
|
|
|
64
73
|
"merge",
|
|
65
74
|
"overwrite"
|
|
66
75
|
];
|
|
76
|
+
const VALID_COMPATIBILITIES = [
|
|
77
|
+
"auto",
|
|
78
|
+
"v10",
|
|
79
|
+
"v11"
|
|
80
|
+
];
|
|
67
81
|
/**
|
|
68
82
|
* Resolve and normalize migration options with defaults.
|
|
69
83
|
*
|
|
@@ -88,6 +102,7 @@ const VALID_STRATEGIES = [
|
|
|
88
102
|
function resolveOptions(options = {}) {
|
|
89
103
|
return {
|
|
90
104
|
cleanNpmrc: options.cleanNpmrc ?? DEFAULT_OPTIONS.cleanNpmrc,
|
|
105
|
+
compatibility: resolveCompatibility(options.compatibility),
|
|
91
106
|
cwd: options.cwd ?? DEFAULT_OPTIONS.cwd,
|
|
92
107
|
newlineBetween: options.newlineBetween ?? DEFAULT_OPTIONS.newlineBetween,
|
|
93
108
|
sortKeys: options.sortKeys ?? DEFAULT_OPTIONS.sortKeys,
|
|
@@ -96,12 +111,16 @@ function resolveOptions(options = {}) {
|
|
|
96
111
|
cleanPackageJson: options.cleanPackageJson ?? DEFAULT_OPTIONS.cleanPackageJson
|
|
97
112
|
};
|
|
98
113
|
}
|
|
114
|
+
function resolveCompatibility(compatibility) {
|
|
115
|
+
if (!compatibility) return DEFAULT_OPTIONS.compatibility;
|
|
116
|
+
if (VALID_COMPATIBILITIES.includes(compatibility)) return compatibility;
|
|
117
|
+
throw new Error(`Invalid compatibility: ${compatibility}. Expected one of: ${VALID_COMPATIBILITIES.join(", ")}`);
|
|
118
|
+
}
|
|
99
119
|
function resolveStrategy(strategy) {
|
|
100
120
|
if (!strategy) return DEFAULT_OPTIONS.strategy;
|
|
101
121
|
if (VALID_STRATEGIES.includes(strategy)) return strategy;
|
|
102
122
|
throw new Error(`Invalid strategy: ${strategy}. Expected one of: ${VALID_STRATEGIES.join(", ")}`);
|
|
103
123
|
}
|
|
104
|
-
|
|
105
124
|
//#endregion
|
|
106
125
|
//#region src/utils/fs.ts
|
|
107
126
|
/**
|
|
@@ -128,17 +147,13 @@ async function fsReadFile(path) {
|
|
|
128
147
|
async function fsWriteFile(path, content) {
|
|
129
148
|
await writeFile(path, `${content.trimEnd()}\n`, "utf-8");
|
|
130
149
|
}
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
//#region src/utils/color.ts
|
|
134
|
-
const cyan = getColor("cyan");
|
|
135
|
-
const yellow = getColor("yellow");
|
|
150
|
+
getColor("cyan");
|
|
151
|
+
getColor("yellow");
|
|
136
152
|
const dim = getColor("dim");
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
153
|
+
getColor("green");
|
|
154
|
+
getColor("red");
|
|
155
|
+
getColor("bold");
|
|
156
|
+
getColor("magenta");
|
|
142
157
|
//#endregion
|
|
143
158
|
//#region src/utils/merge.ts
|
|
144
159
|
/**
|
|
@@ -214,9 +229,24 @@ function mergeWithArrayDedupe(existing, incoming) {
|
|
|
214
229
|
}
|
|
215
230
|
return result;
|
|
216
231
|
}
|
|
217
|
-
|
|
218
232
|
//#endregion
|
|
219
233
|
//#region src/utils/npmrc.ts
|
|
234
|
+
const NPMRC_AUTH_OR_REGISTRY_KEYS = [
|
|
235
|
+
"_auth",
|
|
236
|
+
"_authtoken",
|
|
237
|
+
"_password",
|
|
238
|
+
"always-auth",
|
|
239
|
+
"ca",
|
|
240
|
+
"cafile",
|
|
241
|
+
"cert",
|
|
242
|
+
"certfile",
|
|
243
|
+
"email",
|
|
244
|
+
"key",
|
|
245
|
+
"keyfile",
|
|
246
|
+
"otp",
|
|
247
|
+
"tokenhelper",
|
|
248
|
+
"username"
|
|
249
|
+
];
|
|
220
250
|
/**
|
|
221
251
|
* Remove pnpm-related settings from `.npmrc` file.
|
|
222
252
|
*
|
|
@@ -235,9 +265,15 @@ function mergeWithArrayDedupe(existing, incoming) {
|
|
|
235
265
|
* await pruneNpmrc('/path/to/.npmrc')
|
|
236
266
|
* ```
|
|
237
267
|
*/
|
|
238
|
-
async function pruneNpmrc(path) {
|
|
268
|
+
async function pruneNpmrc(path, compatibility = "v10", migratedKeys = []) {
|
|
239
269
|
const pnpmSettingsFields = PNPM_SETTINGS_FIELDS.map((v) => kebabCase(v));
|
|
240
|
-
|
|
270
|
+
const migratedKeySet = new Set(migratedKeys.map(normalizeNpmrcKey));
|
|
271
|
+
await fsWriteFile(path, (await fsReadFile(path)).split(/\r?\n/).filter((line) => {
|
|
272
|
+
const key = getNpmrcLineKey(line);
|
|
273
|
+
if (!key) return true;
|
|
274
|
+
if (compatibility === "v11") return !migratedKeySet.has(normalizeNpmrcKey(key));
|
|
275
|
+
return !pnpmSettingsFields.some((v) => key.startsWith(v));
|
|
276
|
+
}).join("\n"));
|
|
241
277
|
}
|
|
242
278
|
/**
|
|
243
279
|
* Read and parse `.npmrc` file with camelCase key conversion.
|
|
@@ -258,10 +294,57 @@ async function pruneNpmrc(path) {
|
|
|
258
294
|
* // config.allowBuilds, config.packageExtensions, etc.
|
|
259
295
|
* ```
|
|
260
296
|
*/
|
|
297
|
+
/**
|
|
298
|
+
* Read `.npmrc` and return settings that should be migrated into workspace config.
|
|
299
|
+
*
|
|
300
|
+
* - `v10`: returns all keys (legacy whitelist filtering happens in caller).
|
|
301
|
+
* - `v11`: excludes auth/registry keys because pnpm still reads them from `.npmrc`.
|
|
302
|
+
*/
|
|
303
|
+
async function readMigratableNpmrc(path, compatibility) {
|
|
304
|
+
const raw = await readIniFile(path);
|
|
305
|
+
if (compatibility === "v10") return {
|
|
306
|
+
keys: Object.keys(raw),
|
|
307
|
+
settings: camelcaseKeys(raw)
|
|
308
|
+
};
|
|
309
|
+
const migratable = {};
|
|
310
|
+
const keys = [];
|
|
311
|
+
for (const [key, value] of Object.entries(raw)) if (!isNpmrcAuthOrRegistryKey(key)) {
|
|
312
|
+
migratable[key] = value;
|
|
313
|
+
keys.push(key);
|
|
314
|
+
}
|
|
315
|
+
return {
|
|
316
|
+
keys,
|
|
317
|
+
settings: camelcaseKeys(migratable)
|
|
318
|
+
};
|
|
319
|
+
}
|
|
261
320
|
async function readNpmrc(path) {
|
|
262
321
|
return camelcaseKeys(await readIniFile(path));
|
|
263
322
|
}
|
|
264
|
-
|
|
323
|
+
/**
|
|
324
|
+
* Extract key name from a raw `.npmrc` line.
|
|
325
|
+
*/
|
|
326
|
+
function getNpmrcLineKey(line) {
|
|
327
|
+
const trimmed = line.trim();
|
|
328
|
+
if (!trimmed || trimmed.startsWith(";") || trimmed.startsWith("#")) return;
|
|
329
|
+
const index = trimmed.indexOf("=");
|
|
330
|
+
if (index <= 0) return;
|
|
331
|
+
return normalizeNpmrcKey(trimmed.slice(0, index));
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* Check whether a `.npmrc` key is auth/registry-related and should stay in v11.
|
|
335
|
+
*/
|
|
336
|
+
function isNpmrcAuthOrRegistryKey(key) {
|
|
337
|
+
const normalized = normalizeNpmrcKey(key);
|
|
338
|
+
if (normalized.startsWith("//")) return true;
|
|
339
|
+
if (normalized === "registry" || normalized.endsWith(":registry")) return true;
|
|
340
|
+
return NPMRC_AUTH_OR_REGISTRY_KEYS.some((v) => normalized === v || normalized.endsWith(`:${v}`));
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* Normalize `.npmrc` key for case-insensitive matching.
|
|
344
|
+
*/
|
|
345
|
+
function normalizeNpmrcKey(key) {
|
|
346
|
+
return key.trim().replace(/\[\]$/, "").toLowerCase();
|
|
347
|
+
}
|
|
265
348
|
//#endregion
|
|
266
349
|
//#region src/core.ts
|
|
267
350
|
/**
|
|
@@ -315,9 +398,9 @@ async function migratePnpmSettings(rawOptions = {}) {
|
|
|
315
398
|
consola.warn("No pnpm settings files to migrate");
|
|
316
399
|
return;
|
|
317
400
|
}
|
|
318
|
-
let packageJsonIndent =
|
|
401
|
+
let packageJsonIndent = 2;
|
|
319
402
|
let packageJsonObject = {};
|
|
320
|
-
let pnpmWorkspaceYamlIndent =
|
|
403
|
+
let pnpmWorkspaceYamlIndent = 2;
|
|
321
404
|
let pnpmWorkspaceYamlObject = {};
|
|
322
405
|
if (packageJsonExists) {
|
|
323
406
|
const content = await fsReadFile(packageJsonPath);
|
|
@@ -329,7 +412,15 @@ async function migratePnpmSettings(rawOptions = {}) {
|
|
|
329
412
|
pnpmWorkspaceYamlIndent = detectIndent(content).amount;
|
|
330
413
|
pnpmWorkspaceYamlObject = parse(content);
|
|
331
414
|
}
|
|
332
|
-
const
|
|
415
|
+
const compatibility = resolveCompatibilityTarget(options.compatibility, packageJsonObject.packageManager);
|
|
416
|
+
const npmrcMigratable = npmrcExists ? compatibility === "v10" ? {
|
|
417
|
+
keys: PNPM_SETTINGS_FIELDS,
|
|
418
|
+
settings: pick(await readNpmrc(npmrcPath), PNPM_SETTINGS_FIELDS)
|
|
419
|
+
} : await readMigratableNpmrc(npmrcPath, compatibility) : {
|
|
420
|
+
keys: [],
|
|
421
|
+
settings: {}
|
|
422
|
+
};
|
|
423
|
+
const pnpmSettingsInNpmrc = npmrcMigratable.settings;
|
|
333
424
|
const hasPnpmInPackageJson = !!packageJsonObject.pnpm;
|
|
334
425
|
const hasResolutions = options.yarnResolutions && !!packageJsonObject.resolutions;
|
|
335
426
|
const hasNpmrcSettings = Object.keys(pnpmSettingsInNpmrc).length > 0;
|
|
@@ -346,6 +437,7 @@ async function migratePnpmSettings(rawOptions = {}) {
|
|
|
346
437
|
...pnpmSettingsInNpmrc,
|
|
347
438
|
...pnpmSettingsInPackageJson
|
|
348
439
|
};
|
|
440
|
+
normalizeIncomingSettings(incomingSettings, compatibility);
|
|
349
441
|
const pnpmWorkspaceResult = mergeByStrategy(pnpmWorkspaceYamlObject, incomingSettings, options.strategy);
|
|
350
442
|
const yamlDocument = new Document({}, { sortMapEntries: options.sortKeys });
|
|
351
443
|
Object.entries(pnpmWorkspaceResult).forEach(([key, value]) => {
|
|
@@ -356,7 +448,7 @@ async function migratePnpmSettings(rawOptions = {}) {
|
|
|
356
448
|
});
|
|
357
449
|
const yamlContent = yamlDocument.toString({ indent: pnpmWorkspaceYamlIndent });
|
|
358
450
|
await fsWriteFile(pnpmWorkspaceYamlPath, options.newlineBetween ? yamlContent.replace(/\n(?=[^\s#][^:\n]*:)/g, "\n\n") : yamlContent);
|
|
359
|
-
if (npmrcExists && options.cleanNpmrc) await pruneNpmrc(npmrcPath);
|
|
451
|
+
if (npmrcExists && options.cleanNpmrc) await pruneNpmrc(npmrcPath, compatibility, npmrcMigratable.keys);
|
|
360
452
|
if (packageJsonExists && options.cleanPackageJson && (packageJsonObject.pnpm || packageJsonObject.resolutions)) {
|
|
361
453
|
delete packageJsonObject.pnpm;
|
|
362
454
|
if (options.yarnResolutions) delete packageJsonObject.resolutions;
|
|
@@ -367,6 +459,36 @@ async function migratePnpmSettings(rawOptions = {}) {
|
|
|
367
459
|
throw err;
|
|
368
460
|
}
|
|
369
461
|
}
|
|
370
|
-
|
|
462
|
+
/**
|
|
463
|
+
* Build v11 `allowBuilds` map from legacy build-script settings.
|
|
464
|
+
*/
|
|
465
|
+
function collectAllowBuildsFromLegacy(incomingSettings) {
|
|
466
|
+
const allowBuilds = {};
|
|
467
|
+
for (const name of incomingSettings.onlyBuiltDependencies || []) allowBuilds[name] = true;
|
|
468
|
+
for (const name of incomingSettings.ignoredBuiltDependencies || []) allowBuilds[name] = false;
|
|
469
|
+
for (const name of incomingSettings.neverBuiltDependencies || []) allowBuilds[name] = false;
|
|
470
|
+
return Object.keys(allowBuilds).length ? allowBuilds : void 0;
|
|
471
|
+
}
|
|
472
|
+
/**
|
|
473
|
+
* Normalize incoming settings according to compatibility target.
|
|
474
|
+
*/
|
|
475
|
+
function normalizeIncomingSettings(incomingSettings, compatibility) {
|
|
476
|
+
if (compatibility === "v10") return;
|
|
477
|
+
if (incomingSettings.allowNonAppliedPatches !== void 0) incomingSettings.allowUnusedPatches = incomingSettings.allowUnusedPatches ?? incomingSettings.allowNonAppliedPatches;
|
|
478
|
+
const allowBuildsFromLegacy = collectAllowBuildsFromLegacy(incomingSettings);
|
|
479
|
+
if (allowBuildsFromLegacy) incomingSettings.allowBuilds = {
|
|
480
|
+
...allowBuildsFromLegacy,
|
|
481
|
+
...incomingSettings.allowBuilds || {}
|
|
482
|
+
};
|
|
483
|
+
for (const key of PNPM_V11_REMOVED_SETTINGS) delete incomingSettings[key];
|
|
484
|
+
}
|
|
485
|
+
/**
|
|
486
|
+
* Resolve final compatibility target from user option and package manager hint.
|
|
487
|
+
*/
|
|
488
|
+
function resolveCompatibilityTarget(compatibility, packageManager) {
|
|
489
|
+
if (compatibility !== "auto") return compatibility;
|
|
490
|
+
const [, major] = (packageManager || "").match(/^pnpm@(\d+)(?:\.|$)/) || [];
|
|
491
|
+
return Number(major) >= 11 ? "v11" : "v10";
|
|
492
|
+
}
|
|
371
493
|
//#endregion
|
|
372
|
-
export { migratePnpmSettings, resolveOptions };
|
|
494
|
+
export { migratePnpmSettings, resolveOptions };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pnpm-settings-migrator",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.4.0",
|
|
5
5
|
"description": "Move pnpm settings from `pnpm` field in `package.json` and `.npmrc` file to `pnpm-workspace.yaml`",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"migrator",
|
|
@@ -27,7 +27,6 @@
|
|
|
27
27
|
},
|
|
28
28
|
"main": "./dist/index.mjs",
|
|
29
29
|
"types": "./dist/index.d.mts",
|
|
30
|
-
"bin": "./bin.mjs",
|
|
31
30
|
"files": [
|
|
32
31
|
"bin.mjs",
|
|
33
32
|
"dist"
|
|
@@ -37,31 +36,31 @@
|
|
|
37
36
|
},
|
|
38
37
|
"sideEffects": false,
|
|
39
38
|
"dependencies": {
|
|
40
|
-
"@ntnyq/utils": "^0.
|
|
41
|
-
"@pnpm/types": "^
|
|
39
|
+
"@ntnyq/utils": "^0.13.2",
|
|
40
|
+
"@pnpm/types": "^1101.0.0",
|
|
42
41
|
"cac": "^7.0.0",
|
|
43
42
|
"camelcase-keys": "^10.0.2",
|
|
44
43
|
"consola": "^3.4.2",
|
|
45
|
-
"defu": "^6.1.
|
|
44
|
+
"defu": "^6.1.7",
|
|
46
45
|
"detect-indent": "^7.0.2",
|
|
47
46
|
"pathe": "^2.0.3",
|
|
48
|
-
"read-ini-file": "^
|
|
47
|
+
"read-ini-file": "^5.0.0",
|
|
49
48
|
"uncase": "^0.2.0",
|
|
50
|
-
"yaml": "^2.8.
|
|
49
|
+
"yaml": "^2.8.4"
|
|
51
50
|
},
|
|
52
51
|
"devDependencies": {
|
|
53
|
-
"@ntnyq/eslint-config": "^6.
|
|
54
|
-
"@types/node": "^25.
|
|
55
|
-
"@typescript/native-preview": "^7.0.0-dev.
|
|
56
|
-
"bumpp": "^
|
|
57
|
-
"eslint": "^10.0
|
|
52
|
+
"@ntnyq/eslint-config": "^6.1.3",
|
|
53
|
+
"@types/node": "^25.6.2",
|
|
54
|
+
"@typescript/native-preview": "^7.0.0-dev.20260510.1",
|
|
55
|
+
"bumpp": "^11.1.0",
|
|
56
|
+
"eslint": "^10.3.0",
|
|
58
57
|
"husky": "^9.1.7",
|
|
59
|
-
"nano-staged": "^0.
|
|
58
|
+
"nano-staged": "^1.0.2",
|
|
60
59
|
"npm-run-all2": "^8.0.4",
|
|
61
|
-
"oxfmt": "^0.
|
|
62
|
-
"tsdown": "^0.
|
|
63
|
-
"typescript": "^
|
|
64
|
-
"vitest": "^4.
|
|
60
|
+
"oxfmt": "^0.48.0",
|
|
61
|
+
"tsdown": "^0.22.0",
|
|
62
|
+
"typescript": "^6.0.3",
|
|
63
|
+
"vitest": "^4.1.5"
|
|
65
64
|
},
|
|
66
65
|
"nano-staged": {
|
|
67
66
|
"*.{js,ts,mjs,tsx,md,yml,yaml,toml,json}": "eslint --fix",
|
|
@@ -78,5 +77,8 @@
|
|
|
78
77
|
"release:version": "bumpp",
|
|
79
78
|
"test": "vitest",
|
|
80
79
|
"typecheck": "tsgo --noEmit"
|
|
80
|
+
},
|
|
81
|
+
"bin": {
|
|
82
|
+
"pnpm-settings-migrator": "./bin.mjs"
|
|
81
83
|
}
|
|
82
84
|
}
|