Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: improve transformer selection prompt #70932

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion packages/next-codemod/bin/transform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,15 @@ export async function runTransform(
type: 'select',
name: 'transformer',
message: 'Which transform would you like to apply?',
choices: TRANSFORMER_INQUIRER_CHOICES,
choices: TRANSFORMER_INQUIRER_CHOICES.reverse().map(
({ title, value, version }) => {
return {
title: `(v${version}) ${value}`,
description: title,
value,
}
}
),
},
{ onCancel }
)
Expand Down
23 changes: 12 additions & 11 deletions packages/next-codemod/bin/upgrade.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,9 @@ import { execSync } from 'child_process'
import path from 'path'
import { compareVersions } from 'compare-versions'
import chalk from 'chalk'
import { availableCodemods } from '../lib/codemods'
import { getPkgManager, installPackages } from '../lib/handle-package'
import { runTransform } from './transform'
import { onCancel } from '../lib/utils'
import { onCancel, TRANSFORMER_INQUIRER_CHOICES } from '../lib/utils'

type PackageManager = 'pnpm' | 'npm' | 'yarn' | 'bun'

Expand Down Expand Up @@ -200,25 +199,26 @@ async function suggestCodemods(
initialNextVersion: string,
targetNextVersion: string
): Promise<string[]> {
const initialVersionIndex = availableCodemods.findIndex(
const initialVersionIndex = TRANSFORMER_INQUIRER_CHOICES.findIndex(
(versionCodemods) =>
compareVersions(versionCodemods.version, initialNextVersion) > 0
)
if (initialVersionIndex === -1) {
return []
}

let targetVersionIndex = availableCodemods.findIndex(
let targetVersionIndex = TRANSFORMER_INQUIRER_CHOICES.findIndex(
(versionCodemods) =>
compareVersions(versionCodemods.version, targetNextVersion) > 0
)
if (targetVersionIndex === -1) {
targetVersionIndex = availableCodemods.length
targetVersionIndex = TRANSFORMER_INQUIRER_CHOICES.length
}

const relevantCodemods = availableCodemods
.slice(initialVersionIndex, targetVersionIndex)
.flatMap((versionCodemods) => versionCodemods.codemods)
const relevantCodemods = TRANSFORMER_INQUIRER_CHOICES.slice(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is a nice change. I feel like it'd also make sense to show the most recent codemods first, so users don't have to scroll all the way from v11 if they are only interested in the latest codemod.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reversed!

initialVersionIndex,
targetVersionIndex
)

if (relevantCodemods.length === 0) {
return []
Expand All @@ -229,10 +229,11 @@ async function suggestCodemods(
type: 'multiselect',
name: 'codemods',
message: `\nThe following ${chalk.blue('codemods')} are recommended for your upgrade. Would you like to apply them?`,
choices: relevantCodemods.map((codemod) => {
choices: relevantCodemods.reverse().map(({ title, value, version }) => {
return {
title: `${codemod.title} ${chalk.grey(`(${codemod.value})`)}`,
value: codemod.value,
title: `(v${version}) ${value}`,
description: title,
value,
selected: true,
}
}),
Expand Down
114 changes: 0 additions & 114 deletions packages/next-codemod/lib/codemods.ts

This file was deleted.

69 changes: 40 additions & 29 deletions packages/next-codemod/lib/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,71 +38,82 @@ export function onCancel() {
export const TRANSFORMER_INQUIRER_CHOICES = [
{
title:
'name-default-component: Transforms anonymous components into named components to make sure they work with Fast Refresh',
value: 'name-default-component',
'Transform the deprecated automatically injected url property on top level pages to using withRouter',
value: 'url-to-withrouter',
version: '6.0',
},
{
title:
'add-missing-react-import: Transforms files that do not import `React` to include the import in order for the new React JSX transform',
value: 'add-missing-react-import',
title: 'Transforms the withAmp HOC into Next.js 9 page configuration',
value: 'withamp-to-config',
version: '8.0',
},
{
title:
'withamp-to-config: Transforms the withAmp HOC into Next.js 9 page configuration',
value: 'withamp-to-config',
'Transforms anonymous components into named components to make sure they work with Fast Refresh',
value: 'name-default-component',
version: '9.0',
},
{
title:
'url-to-withrouter: Transforms the deprecated automatically injected url property on top level pages to using withRouter',
value: 'url-to-withrouter',
'Transforms files that do not import `React` to include the import in order for the new React JSX transform',
value: 'add-missing-react-import',
version: '10.0',
},
{
title:
'cra-to-next (experimental): automatically migrates a Create React App project to Next.js',
'Automatically migrates a Create React App project to Next.js (experimental)',
value: 'cra-to-next',
version: '11.0',
},
{
title: 'new-link: Ensures your <Link> usage is backwards compatible.',
title: 'Ensures your <Link> usage is backwards compatible',
value: 'new-link',
version: '13.0',
},
{
title:
'next-og-import: Transforms imports from `next/server` to `next/og` for usage of Dynamic OG Image Generation.',
value: 'next-og-import',
'Dangerously migrates from `next/legacy/image` to the new `next/image` by adding inline styles and removing unused props (experimental)',
value: 'next-image-experimental',
version: '13.0',
},
{
title:
'metadata-to-viewport-export: Migrates certain viewport related metadata from the `metadata` export to a new `viewport` export.',
value: 'metadata-to-viewport-export',
'Safely migrate Next.js 10, 11, 12 applications importing `next/image` to the renamed `next/legacy/image` import in Next.js 13',
value: 'next-image-to-legacy-image',
version: '13.0',
},
{
title:
'next-dynamic-access-named-export: Transforms dynamic imports that return the named export itself to a module like object.',
value: 'next-dynamic-access-named-export',
title: 'Uninstall `@next/font` and transform imports to `next/font`',
value: 'built-in-next-font',
version: '13.2',
},
{
title:
'next-image-to-legacy-image: safely migrate Next.js 10, 11, 12 applications importing `next/image` to the renamed `next/legacy/image` import in Next.js 13',
value: 'next-image-to-legacy-image',
'Migrates certain viewport related metadata from the `metadata` export to a new `viewport` export',
value: 'metadata-to-viewport-export',
version: '14.0',
},
{
title:
'next-image-experimental (experimental): dangerously migrates from `next/legacy/image` to the new `next/image` by adding inline styles and removing unused props',
value: 'next-image-experimental',
'Transforms imports from `next/server` to `next/og` for usage of Dynamic OG Image Generation',
value: 'next-og-import',
version: '14.0',
},
{
title:
'built-in-next-font: Uninstall `@next/font` and transform imports to `next/font`',
value: 'built-in-next-font',
'Transforms dynamic imports that return the named export itself to a module like object',
value: 'next-dynamic-access-named-export',
version: '15.0.0-canary.44',
},
{
title:
'next-async-request-api: Transforms usage of Next.js async Request APIs',
value: 'next-async-request-api',
'Install `@vercel/functions` to replace `geo` and `ip` properties on `NextRequest`',
value: 'next-request-geo-ip',
version: '15.0.0-canary.153',
},
{
title:
'next-request-geo-ip: Install `@vercel/functions` to replace `geo` and `ip` properties on `NextRequest`',
value: 'next-request-geo-ip',
title: 'Transforms usage of Next.js async Request APIs',
value: 'next-async-request-api',
version: '15.0.0-canary.171',
},
]
Loading