@next/codemod 15.0.3-canary.7 → 15.0.3-canary.8

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/bin/upgrade.js CHANGED
@@ -30,7 +30,7 @@ exports.runUpgrade = runUpgrade;
30
30
  const os = __importStar(require("os"));
31
31
  const prompts_1 = __importDefault(require("prompts"));
32
32
  const fs_1 = __importDefault(require("fs"));
33
- const compare_1 = __importDefault(require("semver/functions/compare"));
33
+ const semver_1 = require("semver");
34
34
  const child_process_1 = require("child_process");
35
35
  const path_1 = __importDefault(require("path"));
36
36
  const picocolors_1 = __importDefault(require("picocolors"));
@@ -95,12 +95,12 @@ async function runUpgrade(revision, options) {
95
95
  }
96
96
  const installedNextVersion = getInstalledNextVersion();
97
97
  const targetNextVersion = targetNextPackageJson.version;
98
- if ((0, compare_1.default)(installedNextVersion, targetNextVersion) === 0) {
98
+ if ((0, semver_1.compare)(installedNextVersion, targetNextVersion) === 0) {
99
99
  console.log(`${picocolors_1.default.green('✓')} Current Next.js version is already on the target version "v${targetNextVersion}".`);
100
100
  endMessage();
101
101
  return;
102
102
  }
103
- if ((0, compare_1.default)(installedNextVersion, targetNextVersion) > 0) {
103
+ if ((0, semver_1.compare)(installedNextVersion, targetNextVersion) > 0) {
104
104
  console.log(`${picocolors_1.default.green('✓')} Current Next.js version is higher than the target version "v${targetNextVersion}".`);
105
105
  endMessage();
106
106
  return;
@@ -123,7 +123,7 @@ async function runUpgrade(revision, options) {
123
123
  // we should only let the user stay on React 18 if they are using pure Pages Router.
124
124
  // x-ref(PR): https://github.com/vercel/next.js/pull/65058
125
125
  // x-ref(release): https://github.com/vercel/next.js/releases/tag/v14.3.0-canary.45
126
- (0, compare_1.default)(targetNextVersion, '14.3.0-canary.45') >= 0 &&
126
+ (0, semver_1.compare)(targetNextVersion, '14.3.0-canary.45') >= 0 &&
127
127
  installedReactVersion.startsWith('18') &&
128
128
  // Pure App Router always uses React 19
129
129
  // The mixed case is tricky to handle from a types perspective.
@@ -150,7 +150,7 @@ async function runUpgrade(revision, options) {
150
150
  const targetReactVersion = shouldStayOnReact18
151
151
  ? '18.3.1'
152
152
  : await loadHighestNPMVersionMatching(`react@${targetNextPackageJson.peerDependencies['react']}`);
153
- if ((0, compare_1.default)(targetNextVersion, '15.0.0-canary') >= 0) {
153
+ if ((0, semver_1.compare)(targetNextVersion, '15.0.0-canary') >= 0) {
154
154
  await suggestTurbopack(appPackageJson, targetNextVersion);
155
155
  }
156
156
  const codemods = await suggestCodemods(installedNextVersion, targetNextVersion);
@@ -160,8 +160,8 @@ async function runUpgrade(revision, options) {
160
160
  let execCommand = 'npx';
161
161
  // The following React codemods are for React 19
162
162
  if (!shouldStayOnReact18 &&
163
- (0, compare_1.default)(targetReactVersion, '19.0.0-0') >= 0 &&
164
- (0, compare_1.default)(installedReactVersion, '19.0.0-0') < 0) {
163
+ (0, semver_1.compare)(targetReactVersion, '19.0.0-0') >= 0 &&
164
+ (0, semver_1.compare)(installedReactVersion, '19.0.0-0') < 0) {
165
165
  shouldRunReactCodemods = await suggestReactCodemods();
166
166
  shouldRunReactTypesCodemods = await suggestReactTypesCodemods();
167
167
  const execCommandMap = {
@@ -247,7 +247,7 @@ async function runUpgrade(revision, options) {
247
247
  dependenciesToInstall.push([packageName, version]);
248
248
  }
249
249
  }
250
- console.log(`Upgrading your project to ${picocolors_1.default.blue('Next.js ' + targetNextVersion)}...\n`);
250
+ console.log(`Upgrading your project to ${picocolors_1.default.blue('Next.js ' + targetNextVersion)}...`);
251
251
  for (const [dep, version] of dependenciesToInstall) {
252
252
  (0, handle_package_1.addPackageDependency)(appPackageJson, dep, version, false);
253
253
  }
@@ -257,7 +257,7 @@ async function runUpgrade(revision, options) {
257
257
  fs_1.default.writeFileSync(appPackageJsonPath, JSON.stringify(appPackageJson, null, 2) +
258
258
  // Common IDE formatters would add a newline as well.
259
259
  os.EOL);
260
- (0, handle_package_1.runInstallation)(packageManager);
260
+ (0, handle_package_1.runInstallation)(packageManager, { cwd });
261
261
  for (const codemod of codemods) {
262
262
  await (0, transform_1.runTransform)(codemod, cwd, { force: true, verbose });
263
263
  }
@@ -282,6 +282,7 @@ async function runUpgrade(revision, options) {
282
282
  if (codemods.length > 0) {
283
283
  console.log(`${picocolors_1.default.green('✔')} Codemods have been applied successfully.`);
284
284
  }
285
+ warnDependenciesOutOfRange(appPackageJson, versionMapping);
285
286
  endMessage();
286
287
  }
287
288
  function getInstalledNextVersion() {
@@ -332,7 +333,7 @@ async function suggestTurbopack(packageJson, targetNextVersion) {
332
333
  // Turbopack flag was changed from `--turbo` to `--turbopack` in v15.0.1-canary.3
333
334
  // PR: https://github.com/vercel/next.js/pull/71657
334
335
  // Release: https://github.com/vercel/next.js/releases/tag/v15.0.1-canary.3
335
- const isAfterTurbopackFlagChange = (0, compare_1.default)(targetNextVersion, '15.0.1-canary.3') >= 0;
336
+ const isAfterTurbopackFlagChange = (0, semver_1.compare)(targetNextVersion, '15.0.1-canary.3') >= 0;
336
337
  const turboPackFlag = isAfterTurbopackFlagChange ? '--turbopack' : '--turbo';
337
338
  if (!devScript) {
338
339
  console.log(`${picocolors_1.default.yellow('⚠')} No "dev" script found in your package.json. Skipping Turbopack suggestion.`);
@@ -382,12 +383,12 @@ async function suggestCodemods(initialNextVersion, targetNextVersion) {
382
383
  // 15.0.0-canary.45 -> 15.0.0 : don't apply
383
384
  // 15.0.0-canary.44 -> 15.0.0 : apply
384
385
  const initialVersionIndex = utils_1.TRANSFORMER_INQUIRER_CHOICES.findIndex((codemod) => {
385
- return (0, compare_1.default)(codemod.version, initialNextVersion) > 0;
386
+ return (0, semver_1.compare)(codemod.version, initialNextVersion) > 0;
386
387
  });
387
388
  if (initialVersionIndex === -1) {
388
389
  return [];
389
390
  }
390
- let targetVersionIndex = utils_1.TRANSFORMER_INQUIRER_CHOICES.findIndex((codemod) => (0, compare_1.default)(codemod.version, targetNextVersion) > 0);
391
+ let targetVersionIndex = utils_1.TRANSFORMER_INQUIRER_CHOICES.findIndex((codemod) => (0, semver_1.compare)(codemod.version, targetNextVersion) > 0);
391
392
  if (targetVersionIndex === -1) {
392
393
  targetVersionIndex = utils_1.TRANSFORMER_INQUIRER_CHOICES.length;
393
394
  }
@@ -489,4 +490,59 @@ function writeOverridesField(packageJson, packageManager, overrides) {
489
490
  }
490
491
  }
491
492
  }
493
+ function warnDependenciesOutOfRange(appPackageJson, versionMapping) {
494
+ const allDirectDependencies = {
495
+ ...appPackageJson.dependencies,
496
+ ...appPackageJson.devDependencies,
497
+ };
498
+ const dependenciesOutOfRange = new Map();
499
+ const resolvedDependencyVersions = new Map();
500
+ for (const dependency of Object.keys(allDirectDependencies)) {
501
+ let pkgJson;
502
+ // TODO: Asking package manager for the installed version is most robust e.g. `pnpm why ${dependency}`
503
+ // require.resolve(`${dependency}/package.json`, { paths: [cwd] }) results in previously installed version being used in PNPM
504
+ let pkgJsonFromNodeModules;
505
+ try {
506
+ pkgJsonFromNodeModules = path_1.default.join(cwd, 'node_modules', dependency, 'package.json');
507
+ pkgJson = JSON.parse(fs_1.default.readFileSync(pkgJsonFromNodeModules, 'utf8'));
508
+ }
509
+ catch {
510
+ console.warn(`${picocolors_1.default.yellow('⚠')} Could not find package.json for dependency "${dependency}" at "${pkgJsonFromNodeModules}". This may affect peer dependency checks.`);
511
+ continue;
512
+ }
513
+ resolvedDependencyVersions.set(dependency, pkgJson.version);
514
+ if ('peerDependencies' in pkgJson) {
515
+ const peerDeps = pkgJson.peerDependencies;
516
+ const peerDepsNames = Object.keys(peerDeps);
517
+ const depsToCheck = Object.keys(versionMapping).filter((versionMappingKey) => peerDepsNames.includes(versionMappingKey));
518
+ for (const depName of depsToCheck) {
519
+ const expectedVersionRange = peerDeps[depName];
520
+ const { version: currentVersion } = versionMapping[depName];
521
+ if (!(0, semver_1.satisfies)(currentVersion, expectedVersionRange, {
522
+ includePrerelease: true,
523
+ })) {
524
+ dependenciesOutOfRange.set(dependency, {
525
+ ...dependenciesOutOfRange.get(dependency),
526
+ [depName]: {
527
+ currentVersion,
528
+ expectedVersionRange,
529
+ },
530
+ });
531
+ }
532
+ }
533
+ }
534
+ }
535
+ const size = dependenciesOutOfRange.size;
536
+ if (size > 0) {
537
+ console.log(`${picocolors_1.default.yellow('⚠')} Found ${size} ${size === 1 ? 'dependency' : 'dependencies'} that seem incompatible with the upgraded package versions.\n` +
538
+ 'You may have to update these packages to their latest version or file an issue to ask for support of the upgraded libraries.');
539
+ dependenciesOutOfRange.forEach((deps, packageName) => {
540
+ console.log(`${packageName} ${picocolors_1.default.gray(resolvedDependencyVersions.get(packageName))}`);
541
+ Object.entries(deps).forEach(([depName, value], index, depsArray) => {
542
+ const prefix = index === depsArray.length - 1 ? ' └── ' : ' ├── ';
543
+ console.log(`${prefix}${picocolors_1.default.yellow('✕ unmet peer')} ${depName}@"${value.expectedVersionRange}": found ${value.currentVersion}`);
544
+ });
545
+ });
546
+ }
547
+ }
492
548
  //# sourceMappingURL=upgrade.js.map
@@ -86,9 +86,10 @@ function installPackages(packageToInstall, options = {}) {
86
86
  throw new Error(`Failed to install "${packageToInstall}". Please install it manually.`, { cause: error });
87
87
  }
88
88
  }
89
- function runInstallation(packageManager) {
89
+ function runInstallation(packageManager, options) {
90
90
  try {
91
91
  execa_1.default.sync(packageManager, ['install'], {
92
+ cwd: options.cwd,
92
93
  stdio: 'inherit',
93
94
  shell: true,
94
95
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@next/codemod",
3
- "version": "15.0.3-canary.7",
3
+ "version": "15.0.3-canary.8",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",