@next/codemod 15.0.0-canary.18 → 15.0.0-canary.181
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/next-codemod.js +32 -3
- package/bin/transform.js +110 -0
- package/bin/upgrade.js +165 -0
- package/lib/cra-to-next/global-css-transform.js +2 -3
- package/lib/cra-to-next/index-to-component.js +2 -3
- package/lib/handle-package.js +76 -0
- package/lib/install.js +2 -3
- package/lib/run-jscodeshift.js +22 -2
- package/lib/utils.js +115 -0
- package/package.json +8 -5
- package/transforms/add-missing-react-import.js +1 -1
- package/transforms/app-dir-runtime-config-experimental-edge.js +33 -0
- package/transforms/built-in-next-font.js +1 -1
- package/transforms/cra-to-next.js +238 -236
- package/transforms/lib/async-request-api/index.js +16 -0
- package/transforms/lib/async-request-api/next-async-dynamic-api.js +268 -0
- package/transforms/lib/async-request-api/next-async-dynamic-prop.js +613 -0
- package/transforms/lib/async-request-api/utils.js +345 -0
- package/transforms/metadata-to-viewport-export.js +1 -1
- package/transforms/name-default-component.js +3 -4
- package/transforms/new-link.js +5 -4
- package/transforms/next-async-request-api.js +9 -0
- package/transforms/next-dynamic-access-named-export.js +65 -0
- package/transforms/next-image-experimental.js +9 -13
- package/transforms/next-image-to-legacy-image.js +5 -7
- package/transforms/next-og-import.js +1 -1
- package/transforms/next-request-geo-ip.js +338 -0
- package/transforms/url-to-withrouter.js +1 -1
- package/transforms/withamp-to-config.js +1 -1
- package/bin/cli.js +0 -216
- package/lib/uninstall-package.js +0 -32
package/bin/next-codemod.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
2
3
|
/**
|
|
3
4
|
* Copyright 2015-present, Facebook, Inc.
|
|
4
5
|
*
|
|
@@ -6,7 +7,35 @@
|
|
|
6
7
|
* LICENSE file in the root directory of this source tree.
|
|
7
8
|
*
|
|
8
9
|
*/
|
|
9
|
-
// Based on https://github.com/reactjs/react-codemod/blob/dd8671c9a470a2c342b221ec903c574cf31e9f57/bin/
|
|
10
|
-
// next
|
|
11
|
-
|
|
10
|
+
// Based on https://github.com/reactjs/react-codemod/blob/dd8671c9a470a2c342b221ec903c574cf31e9f57/bin/cli.js
|
|
11
|
+
// @next/codemod optional-name-of-transform optional/path/to/src [...options]
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
const commander_1 = require("commander");
|
|
14
|
+
const upgrade_1 = require("./upgrade");
|
|
15
|
+
const transform_1 = require("./transform");
|
|
16
|
+
const packageJson = require('../package.json');
|
|
17
|
+
const program = new commander_1.Command(packageJson.name)
|
|
18
|
+
.description('Codemods for updating Next.js apps.')
|
|
19
|
+
.version(packageJson.version, '-v, --version', 'Output the current version of @next/codemod.')
|
|
20
|
+
.argument('[codemod]', 'Codemod slug to run. See "https://github.com/vercel/next.js/tree/canary/packages/next-codemod".')
|
|
21
|
+
.argument('[source]', 'Path to source files or directory to transform including glob patterns.')
|
|
22
|
+
.usage('[codemod] [source] [options]')
|
|
23
|
+
.helpOption('-h, --help', 'Display this help message.')
|
|
24
|
+
.option('-f, --force', 'Bypass Git safety checks and forcibly run codemods')
|
|
25
|
+
.option('-d, --dry', 'Dry run (no changes are made to files)')
|
|
26
|
+
.option('-p, --print', 'Print transformed files to your terminal')
|
|
27
|
+
.option('-j, --jscodeshift', '(Advanced) Pass options directly to jscodeshift')
|
|
28
|
+
.action(transform_1.runTransform)
|
|
29
|
+
.allowUnknownOption();
|
|
30
|
+
program
|
|
31
|
+
.command('upgrade')
|
|
32
|
+
.description('Upgrade Next.js apps to desired versions with a single command.')
|
|
33
|
+
.argument('[revision]', 'NPM dist tag or exact version to upgrade to (e.g. "latest" or "15.0.0-canary.167"). Valid dist-tags are "latest", "canary" or "rc".', packageJson.version.includes('-canary.')
|
|
34
|
+
? 'canary'
|
|
35
|
+
: packageJson.version.includes('-rc.')
|
|
36
|
+
? 'rc'
|
|
37
|
+
: 'latest')
|
|
38
|
+
.option('--verbose', 'Verbose output', false)
|
|
39
|
+
.action(upgrade_1.runUpgrade);
|
|
40
|
+
program.parse(process.argv);
|
|
12
41
|
//# sourceMappingURL=next-codemod.js.map
|
package/bin/transform.js
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.transformerDirectory = exports.jscodeshiftExecutable = void 0;
|
|
7
|
+
exports.runTransform = runTransform;
|
|
8
|
+
const execa_1 = __importDefault(require("execa"));
|
|
9
|
+
const globby_1 = __importDefault(require("globby"));
|
|
10
|
+
const prompts_1 = __importDefault(require("prompts"));
|
|
11
|
+
const node_path_1 = require("node:path");
|
|
12
|
+
const handle_package_1 = require("../lib/handle-package");
|
|
13
|
+
const utils_1 = require("../lib/utils");
|
|
14
|
+
function expandFilePathsIfNeeded(filesBeforeExpansion) {
|
|
15
|
+
const shouldExpandFiles = filesBeforeExpansion.some((file) => file.includes('*'));
|
|
16
|
+
return shouldExpandFiles
|
|
17
|
+
? globby_1.default.sync(filesBeforeExpansion)
|
|
18
|
+
: filesBeforeExpansion;
|
|
19
|
+
}
|
|
20
|
+
exports.jscodeshiftExecutable = require.resolve('.bin/jscodeshift');
|
|
21
|
+
exports.transformerDirectory = (0, node_path_1.join)(__dirname, '../', 'transforms');
|
|
22
|
+
async function runTransform(transform, path, options) {
|
|
23
|
+
let transformer = transform;
|
|
24
|
+
let directory = path;
|
|
25
|
+
if (!options.dry) {
|
|
26
|
+
(0, utils_1.checkGitStatus)(options.force);
|
|
27
|
+
}
|
|
28
|
+
if (transform &&
|
|
29
|
+
!utils_1.TRANSFORMER_INQUIRER_CHOICES.find((x) => x.value === transform)) {
|
|
30
|
+
console.error('Invalid transform choice, pick one of:');
|
|
31
|
+
console.error(utils_1.TRANSFORMER_INQUIRER_CHOICES.map((x) => '- ' + x.value).join('\n'));
|
|
32
|
+
process.exit(1);
|
|
33
|
+
}
|
|
34
|
+
if (!path) {
|
|
35
|
+
const res = await (0, prompts_1.default)({
|
|
36
|
+
type: 'text',
|
|
37
|
+
name: 'path',
|
|
38
|
+
message: 'On which files or directory should the codemods be applied?',
|
|
39
|
+
initial: '.',
|
|
40
|
+
}, { onCancel: utils_1.onCancel });
|
|
41
|
+
directory = res.path;
|
|
42
|
+
}
|
|
43
|
+
if (!transform) {
|
|
44
|
+
const res = await (0, prompts_1.default)({
|
|
45
|
+
type: 'select',
|
|
46
|
+
name: 'transformer',
|
|
47
|
+
message: 'Which transform would you like to apply?',
|
|
48
|
+
choices: utils_1.TRANSFORMER_INQUIRER_CHOICES.reverse().map(({ title, value, version }) => {
|
|
49
|
+
return {
|
|
50
|
+
title: `(v${version}) ${value}`,
|
|
51
|
+
description: title,
|
|
52
|
+
value,
|
|
53
|
+
};
|
|
54
|
+
}),
|
|
55
|
+
}, { onCancel: utils_1.onCancel });
|
|
56
|
+
transformer = res.transformer;
|
|
57
|
+
}
|
|
58
|
+
const filesExpanded = expandFilePathsIfNeeded([directory]);
|
|
59
|
+
if (!filesExpanded.length) {
|
|
60
|
+
console.log(`No files found matching "${directory}"`);
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
const transformerPath = (0, node_path_1.join)(exports.transformerDirectory, `${transformer}.js`);
|
|
64
|
+
if (transformer === 'cra-to-next') {
|
|
65
|
+
// cra-to-next transform doesn't use jscodeshift directly
|
|
66
|
+
return require(transformerPath).default(filesExpanded, options);
|
|
67
|
+
}
|
|
68
|
+
let args = [];
|
|
69
|
+
const { dry, print, runInBand, jscodeshift } = options;
|
|
70
|
+
if (dry) {
|
|
71
|
+
args.push('--dry');
|
|
72
|
+
}
|
|
73
|
+
if (print) {
|
|
74
|
+
args.push('--print');
|
|
75
|
+
}
|
|
76
|
+
if (runInBand) {
|
|
77
|
+
args.push('--run-in-band');
|
|
78
|
+
}
|
|
79
|
+
args.push('--verbose=2');
|
|
80
|
+
args.push('--ignore-pattern=**/node_modules/**');
|
|
81
|
+
args.push('--ignore-pattern=**/.next/**');
|
|
82
|
+
args.push('--extensions=tsx,ts,jsx,js');
|
|
83
|
+
args = args.concat(['--transform', transformerPath]);
|
|
84
|
+
if (jscodeshift) {
|
|
85
|
+
args = args.concat(jscodeshift);
|
|
86
|
+
}
|
|
87
|
+
args = args.concat(filesExpanded);
|
|
88
|
+
console.log(`Executing command: jscodeshift ${args.join(' ')}`);
|
|
89
|
+
const result = execa_1.default.sync(exports.jscodeshiftExecutable, args, {
|
|
90
|
+
stdio: 'inherit',
|
|
91
|
+
stripFinalNewline: false,
|
|
92
|
+
});
|
|
93
|
+
if (result.failed) {
|
|
94
|
+
throw new Error(`jscodeshift exited with code ${result.exitCode}`);
|
|
95
|
+
}
|
|
96
|
+
if (!dry && transformer === 'built-in-next-font') {
|
|
97
|
+
console.log('Uninstalling `@next/font`');
|
|
98
|
+
try {
|
|
99
|
+
(0, handle_package_1.uninstallPackage)('@next/font');
|
|
100
|
+
}
|
|
101
|
+
catch {
|
|
102
|
+
console.error("Couldn't uninstall `@next/font`, please uninstall it manually");
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
if (!dry && transformer === 'next-request-geo-ip') {
|
|
106
|
+
console.log('Installing `@vercel/functions`...');
|
|
107
|
+
(0, handle_package_1.installPackages)(['@vercel/functions']);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=transform.js.map
|
package/bin/upgrade.js
ADDED
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.runUpgrade = runUpgrade;
|
|
7
|
+
const prompts_1 = __importDefault(require("prompts"));
|
|
8
|
+
const fs_1 = __importDefault(require("fs"));
|
|
9
|
+
const child_process_1 = require("child_process");
|
|
10
|
+
const path_1 = __importDefault(require("path"));
|
|
11
|
+
const compare_versions_1 = require("compare-versions");
|
|
12
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
13
|
+
const handle_package_1 = require("../lib/handle-package");
|
|
14
|
+
const transform_1 = require("./transform");
|
|
15
|
+
const utils_1 = require("../lib/utils");
|
|
16
|
+
/**
|
|
17
|
+
* @param query
|
|
18
|
+
* @example loadHighestNPMVersionMatching("react@^18.3.0 || ^19.0.0") === Promise<"19.0.0">
|
|
19
|
+
*/
|
|
20
|
+
async function loadHighestNPMVersionMatching(query) {
|
|
21
|
+
const versionsJSON = (0, child_process_1.execSync)(`npm --silent view "${query}" --json --field version`, { encoding: 'utf-8' });
|
|
22
|
+
const versions = JSON.parse(versionsJSON);
|
|
23
|
+
if (versions.length < 1) {
|
|
24
|
+
throw new Error(`Found no React versions matching "${query}". This is a bug in the upgrade tool.`);
|
|
25
|
+
}
|
|
26
|
+
return versions[versions.length - 1];
|
|
27
|
+
}
|
|
28
|
+
async function runUpgrade(revision, options) {
|
|
29
|
+
const { verbose } = options;
|
|
30
|
+
const appPackageJsonPath = path_1.default.resolve(process.cwd(), 'package.json');
|
|
31
|
+
let appPackageJson = JSON.parse(fs_1.default.readFileSync(appPackageJsonPath, 'utf8'));
|
|
32
|
+
let targetNextPackageJson;
|
|
33
|
+
const res = await fetch(`https://registry.npmjs.org/next/${revision}`);
|
|
34
|
+
if (res.status === 200) {
|
|
35
|
+
targetNextPackageJson = await res.json();
|
|
36
|
+
}
|
|
37
|
+
const validRevision = targetNextPackageJson !== null &&
|
|
38
|
+
typeof targetNextPackageJson === 'object' &&
|
|
39
|
+
'version' in targetNextPackageJson &&
|
|
40
|
+
'peerDependencies' in targetNextPackageJson;
|
|
41
|
+
if (!validRevision) {
|
|
42
|
+
throw new Error(`${chalk_1.default.yellow(`next@${revision}`)} does not exist. Make sure you entered a valid Next.js version or dist-tag. Check available versions at ${chalk_1.default.underline('https://www.npmjs.com/package/next?activeTab=versions')}.`);
|
|
43
|
+
}
|
|
44
|
+
const installedNextVersion = getInstalledNextVersion();
|
|
45
|
+
const targetNextVersion = targetNextPackageJson.version;
|
|
46
|
+
// We're resolving a specific version here to avoid including "ugly" version queries
|
|
47
|
+
// in the manifest.
|
|
48
|
+
// E.g. in peerDependencies we could have `^18.2.0 || ^19.0.0 || 20.0.0-canary`
|
|
49
|
+
// If we'd just `npm add` that, the manifest would read the same version query.
|
|
50
|
+
// This is basically a `npm --save-exact react@$versionQuery` that works for every package manager.
|
|
51
|
+
const [targetReactVersion, targetReactTypesVersion, targetReactDOMTypesVersion,] = await Promise.all([
|
|
52
|
+
loadHighestNPMVersionMatching(`react@${targetNextPackageJson.peerDependencies['react']}`),
|
|
53
|
+
loadHighestNPMVersionMatching(`@types/react@${targetNextPackageJson.peerDependencies['react']}`),
|
|
54
|
+
loadHighestNPMVersionMatching(`@types/react-dom@${targetNextPackageJson.peerDependencies['react']}`),
|
|
55
|
+
]);
|
|
56
|
+
if ((0, compare_versions_1.compareVersions)(targetNextVersion, '15.0.0-canary') >= 0) {
|
|
57
|
+
await suggestTurbopack(appPackageJson);
|
|
58
|
+
}
|
|
59
|
+
const codemods = await suggestCodemods(installedNextVersion, targetNextVersion);
|
|
60
|
+
fs_1.default.writeFileSync(appPackageJsonPath, JSON.stringify(appPackageJson, null, 2));
|
|
61
|
+
const packageManager = (0, handle_package_1.getPkgManager)(process.cwd());
|
|
62
|
+
const nextDependency = `next@${targetNextVersion}`;
|
|
63
|
+
const reactDependencies = [
|
|
64
|
+
`react@${targetReactVersion}`,
|
|
65
|
+
`react-dom@${targetReactVersion}`,
|
|
66
|
+
];
|
|
67
|
+
if (targetReactVersion.startsWith('19.0.0-canary') ||
|
|
68
|
+
targetReactVersion.startsWith('19.0.0-beta') ||
|
|
69
|
+
targetReactVersion.startsWith('19.0.0-rc')) {
|
|
70
|
+
reactDependencies.push(`@types/react@npm:types-react@rc`);
|
|
71
|
+
reactDependencies.push(`@types/react-dom@npm:types-react-dom@rc`);
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
reactDependencies.push(`@types/react@${targetReactTypesVersion}`);
|
|
75
|
+
reactDependencies.push(`@types/react-dom@${targetReactDOMTypesVersion}`);
|
|
76
|
+
}
|
|
77
|
+
console.log(`Upgrading your project to ${chalk_1.default.blue('Next.js ' + targetNextVersion)}...\n`);
|
|
78
|
+
(0, handle_package_1.installPackages)([nextDependency, ...reactDependencies], {
|
|
79
|
+
packageManager,
|
|
80
|
+
silent: !verbose,
|
|
81
|
+
});
|
|
82
|
+
for (const codemod of codemods) {
|
|
83
|
+
await (0, transform_1.runTransform)(codemod, process.cwd(), { force: true });
|
|
84
|
+
}
|
|
85
|
+
console.log(`\n${chalk_1.default.green('✔')} Your Next.js project has been upgraded successfully. ${chalk_1.default.bold('Time to ship! 🚢')}`);
|
|
86
|
+
}
|
|
87
|
+
function getInstalledNextVersion() {
|
|
88
|
+
try {
|
|
89
|
+
return require(require.resolve('next/package.json', {
|
|
90
|
+
paths: [process.cwd()],
|
|
91
|
+
})).version;
|
|
92
|
+
}
|
|
93
|
+
catch (error) {
|
|
94
|
+
throw new Error(`Failed to get the installed Next.js version at "${process.cwd()}".\nIf you're using a monorepo, please run this command from the Next.js app directory.`, {
|
|
95
|
+
cause: error,
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
/*
|
|
100
|
+
* Heuristics are used to determine whether to Turbopack is enabled or not and
|
|
101
|
+
* to determine how to update the dev script.
|
|
102
|
+
*
|
|
103
|
+
* 1. If the dev script contains `--turbo` option, we assume that Turbopack is
|
|
104
|
+
* already enabled.
|
|
105
|
+
* 2. If the dev script contains the string `next dev`, we replace it to
|
|
106
|
+
* `next dev --turbo`.
|
|
107
|
+
* 3. Otherwise, we ask the user to manually add `--turbo` to their dev command,
|
|
108
|
+
* showing the current dev command as the initial value.
|
|
109
|
+
*/
|
|
110
|
+
async function suggestTurbopack(packageJson) {
|
|
111
|
+
const devScript = packageJson.scripts['dev'];
|
|
112
|
+
if (devScript.includes('--turbo'))
|
|
113
|
+
return;
|
|
114
|
+
const responseTurbopack = await (0, prompts_1.default)({
|
|
115
|
+
type: 'confirm',
|
|
116
|
+
name: 'enable',
|
|
117
|
+
message: 'Enable Turbopack for next dev?',
|
|
118
|
+
initial: true,
|
|
119
|
+
}, { onCancel: utils_1.onCancel });
|
|
120
|
+
if (!responseTurbopack.enable) {
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
if (devScript.includes('next dev')) {
|
|
124
|
+
packageJson.scripts['dev'] = devScript.replace('next dev', 'next dev --turbo');
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
console.log(`${chalk_1.default.yellow('⚠')} Could not find "${chalk_1.default.bold('next dev')}" in your dev script.`);
|
|
128
|
+
const responseCustomDevScript = await (0, prompts_1.default)({
|
|
129
|
+
type: 'text',
|
|
130
|
+
name: 'customDevScript',
|
|
131
|
+
message: 'Please manually add "--turbo" to your dev command.',
|
|
132
|
+
initial: devScript,
|
|
133
|
+
}, { onCancel: utils_1.onCancel });
|
|
134
|
+
packageJson.scripts['dev'] =
|
|
135
|
+
responseCustomDevScript.customDevScript || devScript;
|
|
136
|
+
}
|
|
137
|
+
async function suggestCodemods(initialNextVersion, targetNextVersion) {
|
|
138
|
+
const initialVersionIndex = utils_1.TRANSFORMER_INQUIRER_CHOICES.findIndex((versionCodemods) => (0, compare_versions_1.compareVersions)(versionCodemods.version, initialNextVersion) > 0);
|
|
139
|
+
if (initialVersionIndex === -1) {
|
|
140
|
+
return [];
|
|
141
|
+
}
|
|
142
|
+
let targetVersionIndex = utils_1.TRANSFORMER_INQUIRER_CHOICES.findIndex((versionCodemods) => (0, compare_versions_1.compareVersions)(versionCodemods.version, targetNextVersion) > 0);
|
|
143
|
+
if (targetVersionIndex === -1) {
|
|
144
|
+
targetVersionIndex = utils_1.TRANSFORMER_INQUIRER_CHOICES.length;
|
|
145
|
+
}
|
|
146
|
+
const relevantCodemods = utils_1.TRANSFORMER_INQUIRER_CHOICES.slice(initialVersionIndex, targetVersionIndex);
|
|
147
|
+
if (relevantCodemods.length === 0) {
|
|
148
|
+
return [];
|
|
149
|
+
}
|
|
150
|
+
const { codemods } = await (0, prompts_1.default)({
|
|
151
|
+
type: 'multiselect',
|
|
152
|
+
name: 'codemods',
|
|
153
|
+
message: `The following ${chalk_1.default.blue('codemods')} are recommended for your upgrade. Select the ones to apply.`,
|
|
154
|
+
choices: relevantCodemods.reverse().map(({ title, value, version }) => {
|
|
155
|
+
return {
|
|
156
|
+
title: `(v${version}) ${value}`,
|
|
157
|
+
description: title,
|
|
158
|
+
value,
|
|
159
|
+
selected: true,
|
|
160
|
+
};
|
|
161
|
+
}),
|
|
162
|
+
}, { onCancel: utils_1.onCancel });
|
|
163
|
+
return codemods;
|
|
164
|
+
}
|
|
165
|
+
//# sourceMappingURL=upgrade.js.map
|
|
@@ -4,6 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.globalCssContext = void 0;
|
|
7
|
+
exports.default = transformer;
|
|
7
8
|
const path_1 = __importDefault(require("path"));
|
|
8
9
|
exports.globalCssContext = {
|
|
9
10
|
cssImports: new Set(),
|
|
@@ -37,8 +38,7 @@ function transformer(file, api, options) {
|
|
|
37
38
|
}
|
|
38
39
|
else if (value.endsWith('.svg')) {
|
|
39
40
|
const isComponentImport = path.node.specifiers.some((specifier) => {
|
|
40
|
-
|
|
41
|
-
return ((_a = specifier.imported) === null || _a === void 0 ? void 0 : _a.name) === 'ReactComponent';
|
|
41
|
+
return specifier.imported?.name === 'ReactComponent';
|
|
42
42
|
});
|
|
43
43
|
if (isComponentImport) {
|
|
44
44
|
exports.globalCssContext.reactSvgImports.add(file.path);
|
|
@@ -52,5 +52,4 @@ function transformer(file, api, options) {
|
|
|
52
52
|
? root.toSource(options)
|
|
53
53
|
: null;
|
|
54
54
|
}
|
|
55
|
-
exports.default = transformer;
|
|
56
55
|
//# sourceMappingURL=global-css-transform.js.map
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.indexContext = void 0;
|
|
4
|
+
exports.default = transformer;
|
|
4
5
|
exports.indexContext = {
|
|
5
6
|
multipleRenderRoots: false,
|
|
6
7
|
nestedRender: false,
|
|
@@ -28,7 +29,6 @@ function transformer(file, api, options) {
|
|
|
28
29
|
root
|
|
29
30
|
.find(j.CallExpression)
|
|
30
31
|
.filter((path) => {
|
|
31
|
-
var _a, _b;
|
|
32
32
|
const { node } = path;
|
|
33
33
|
let found = false;
|
|
34
34
|
if (defaultReactDomImport &&
|
|
@@ -43,7 +43,7 @@ function transformer(file, api, options) {
|
|
|
43
43
|
if (found) {
|
|
44
44
|
foundReactRender++;
|
|
45
45
|
hasModifications = true;
|
|
46
|
-
if (!Array.isArray(
|
|
46
|
+
if (!Array.isArray(path.parentPath?.parentPath?.value)) {
|
|
47
47
|
exports.indexContext.nestedRender = true;
|
|
48
48
|
return false;
|
|
49
49
|
}
|
|
@@ -73,5 +73,4 @@ function transformer(file, api, options) {
|
|
|
73
73
|
// }).remove()
|
|
74
74
|
return hasModifications ? root.toSource(options) : null;
|
|
75
75
|
}
|
|
76
|
-
exports.default = transformer;
|
|
77
76
|
//# sourceMappingURL=index-to-component.js.map
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.getPkgManager = getPkgManager;
|
|
7
|
+
exports.uninstallPackage = uninstallPackage;
|
|
8
|
+
exports.installPackages = installPackages;
|
|
9
|
+
const fs_1 = __importDefault(require("fs"));
|
|
10
|
+
const path_1 = __importDefault(require("path"));
|
|
11
|
+
const execa_1 = __importDefault(require("execa"));
|
|
12
|
+
function getPkgManager(baseDir) {
|
|
13
|
+
try {
|
|
14
|
+
for (const { lockFile, packageManager } of [
|
|
15
|
+
{ lockFile: 'yarn.lock', packageManager: 'yarn' },
|
|
16
|
+
{ lockFile: 'pnpm-lock.yaml', packageManager: 'pnpm' },
|
|
17
|
+
{ lockFile: 'package-lock.json', packageManager: 'npm' },
|
|
18
|
+
{ lockFile: 'bun.lockb', packageManager: 'bun' },
|
|
19
|
+
]) {
|
|
20
|
+
if (fs_1.default.existsSync(path_1.default.join(baseDir, lockFile))) {
|
|
21
|
+
return packageManager;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
const userAgent = process.env.npm_config_user_agent;
|
|
25
|
+
if (userAgent) {
|
|
26
|
+
if (userAgent.startsWith('yarn')) {
|
|
27
|
+
return 'yarn';
|
|
28
|
+
}
|
|
29
|
+
else if (userAgent.startsWith('pnpm')) {
|
|
30
|
+
return 'pnpm';
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
try {
|
|
34
|
+
execa_1.default.sync('yarn --version', { stdio: 'ignore' });
|
|
35
|
+
return 'yarn';
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
try {
|
|
39
|
+
execa_1.default.sync('pnpm --version', { stdio: 'ignore' });
|
|
40
|
+
return 'pnpm';
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
execa_1.default.sync('bun --version', { stdio: 'ignore' });
|
|
44
|
+
return 'bun';
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
return 'npm';
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
function uninstallPackage(packageToUninstall, pkgManager) {
|
|
53
|
+
pkgManager ??= getPkgManager(process.cwd());
|
|
54
|
+
if (!pkgManager)
|
|
55
|
+
throw new Error('Failed to find package manager');
|
|
56
|
+
let command = 'uninstall';
|
|
57
|
+
if (pkgManager === 'yarn') {
|
|
58
|
+
command = 'remove';
|
|
59
|
+
}
|
|
60
|
+
execa_1.default.sync(pkgManager, [command, packageToUninstall], { stdio: 'inherit' });
|
|
61
|
+
}
|
|
62
|
+
function installPackages(packageToInstall, options = {}) {
|
|
63
|
+
const { packageManager = getPkgManager(process.cwd()), silent = false } = options;
|
|
64
|
+
if (!packageManager)
|
|
65
|
+
throw new Error('Failed to find package manager');
|
|
66
|
+
try {
|
|
67
|
+
execa_1.default.sync(packageManager, ['add', ...packageToInstall], {
|
|
68
|
+
// Keeping stderr since it'll likely be relevant later when it fails.
|
|
69
|
+
stdio: silent ? ['ignore', 'ignore', 'inherit'] : 'inherit',
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
catch (error) {
|
|
73
|
+
throw new Error(`Failed to install "${packageToInstall}". Please install it manually.`, { cause: error });
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=handle-package.js.map
|
package/lib/install.js
CHANGED
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.install =
|
|
6
|
+
exports.install = install;
|
|
7
7
|
/* eslint-disable import/no-extraneous-dependencies */
|
|
8
8
|
const picocolors_1 = require("picocolors");
|
|
9
9
|
const cross_spawn_1 = __importDefault(require("cross-spawn"));
|
|
@@ -84,7 +84,7 @@ function install(root, dependencies, { useYarn, isOnline, devDependencies }) {
|
|
|
84
84
|
*/
|
|
85
85
|
const child = (0, cross_spawn_1.default)(command, args, {
|
|
86
86
|
stdio: 'inherit',
|
|
87
|
-
env:
|
|
87
|
+
env: { ...process.env, ADBLOCK: '1', DISABLE_OPENCOLLECTIVE: '1' },
|
|
88
88
|
});
|
|
89
89
|
child.on('close', (code) => {
|
|
90
90
|
if (code !== 0) {
|
|
@@ -95,5 +95,4 @@ function install(root, dependencies, { useYarn, isOnline, devDependencies }) {
|
|
|
95
95
|
});
|
|
96
96
|
});
|
|
97
97
|
}
|
|
98
|
-
exports.install = install;
|
|
99
98
|
//# sourceMappingURL=install.js.map
|
package/lib/run-jscodeshift.js
CHANGED
|
@@ -3,12 +3,32 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.default = runJscodeshift;
|
|
6
7
|
// @ts-ignore internal module
|
|
7
8
|
const Runner_1 = __importDefault(require("jscodeshift/src/Runner"));
|
|
8
9
|
function runJscodeshift(transformerPath, flags, files) {
|
|
9
10
|
// we run jscodeshift in the same process to be able to
|
|
10
11
|
// share state between the main CRA transform and sub-transforms
|
|
11
|
-
return Runner_1.default.run(transformerPath, files,
|
|
12
|
+
return Runner_1.default.run(transformerPath, files, {
|
|
13
|
+
ignorePattern: [
|
|
14
|
+
'**/node_modules/**',
|
|
15
|
+
'**/.next/**',
|
|
16
|
+
'**/build/**',
|
|
17
|
+
// type files
|
|
18
|
+
'**/*.d.ts',
|
|
19
|
+
'**/*.d.cts',
|
|
20
|
+
'**/*.d.mts',
|
|
21
|
+
// test files
|
|
22
|
+
'**/*.test.*',
|
|
23
|
+
'**/*.spec.*',
|
|
24
|
+
'**/__tests__/**',
|
|
25
|
+
'**/__mocks__/**',
|
|
26
|
+
],
|
|
27
|
+
extensions: 'tsx,ts,jsx,js',
|
|
28
|
+
parser: 'tsx',
|
|
29
|
+
verbose: 2,
|
|
30
|
+
runInBand: true,
|
|
31
|
+
...flags,
|
|
32
|
+
});
|
|
12
33
|
}
|
|
13
|
-
exports.default = runJscodeshift;
|
|
14
34
|
//# sourceMappingURL=run-jscodeshift.js.map
|
package/lib/utils.js
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.TRANSFORMER_INQUIRER_CHOICES = void 0;
|
|
7
|
+
exports.checkGitStatus = checkGitStatus;
|
|
8
|
+
exports.onCancel = onCancel;
|
|
9
|
+
const picocolors_1 = require("picocolors");
|
|
10
|
+
const is_git_clean_1 = __importDefault(require("is-git-clean"));
|
|
11
|
+
function checkGitStatus(force) {
|
|
12
|
+
let clean = false;
|
|
13
|
+
let errorMessage = 'Unable to determine if git directory is clean';
|
|
14
|
+
try {
|
|
15
|
+
clean = is_git_clean_1.default.sync(process.cwd());
|
|
16
|
+
errorMessage = 'Git directory is not clean';
|
|
17
|
+
}
|
|
18
|
+
catch (err) {
|
|
19
|
+
if (err && err.stderr && err.stderr.includes('Not a git repository')) {
|
|
20
|
+
clean = true;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
if (!clean) {
|
|
24
|
+
if (force) {
|
|
25
|
+
console.log(`WARNING: ${errorMessage}. Forcibly continuing.`);
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
console.log('Thank you for using @next/codemod!');
|
|
29
|
+
console.log((0, picocolors_1.yellow)('\nBut before we continue, please stash or commit your git changes.'));
|
|
30
|
+
console.log('\nYou may use the --force flag to override this safety check.');
|
|
31
|
+
process.exit(1);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
function onCancel() {
|
|
36
|
+
process.exit(1);
|
|
37
|
+
}
|
|
38
|
+
exports.TRANSFORMER_INQUIRER_CHOICES = [
|
|
39
|
+
{
|
|
40
|
+
title: 'Transform the deprecated automatically injected url property on top level pages to using withRouter',
|
|
41
|
+
value: 'url-to-withrouter',
|
|
42
|
+
version: '6.0',
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
title: 'Transforms the withAmp HOC into Next.js 9 page configuration',
|
|
46
|
+
value: 'withamp-to-config',
|
|
47
|
+
version: '8.0',
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
title: 'Transforms anonymous components into named components to make sure they work with Fast Refresh',
|
|
51
|
+
value: 'name-default-component',
|
|
52
|
+
version: '9.0',
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
title: 'Transforms files that do not import `React` to include the import in order for the new React JSX transform',
|
|
56
|
+
value: 'add-missing-react-import',
|
|
57
|
+
version: '10.0',
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
title: 'Automatically migrates a Create React App project to Next.js (experimental)',
|
|
61
|
+
value: 'cra-to-next',
|
|
62
|
+
version: '11.0',
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
title: 'Ensures your <Link> usage is backwards compatible',
|
|
66
|
+
value: 'new-link',
|
|
67
|
+
version: '13.0',
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
title: 'Dangerously migrates from `next/legacy/image` to the new `next/image` by adding inline styles and removing unused props (experimental)',
|
|
71
|
+
value: 'next-image-experimental',
|
|
72
|
+
version: '13.0',
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
title: 'Safely migrate Next.js 10, 11, 12 applications importing `next/image` to the renamed `next/legacy/image` import in Next.js 13',
|
|
76
|
+
value: 'next-image-to-legacy-image',
|
|
77
|
+
version: '13.0',
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
title: 'Uninstall `@next/font` and transform imports to `next/font`',
|
|
81
|
+
value: 'built-in-next-font',
|
|
82
|
+
version: '13.2',
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
title: 'Migrates certain viewport related metadata from the `metadata` export to a new `viewport` export',
|
|
86
|
+
value: 'metadata-to-viewport-export',
|
|
87
|
+
version: '14.0',
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
title: 'Transforms imports from `next/server` to `next/og` for usage of Dynamic OG Image Generation',
|
|
91
|
+
value: 'next-og-import',
|
|
92
|
+
version: '14.0',
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
title: 'Transforms dynamic imports that return the named export itself to a module like object',
|
|
96
|
+
value: 'next-dynamic-access-named-export',
|
|
97
|
+
version: '15.0.0-canary.44',
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
title: 'Install `@vercel/functions` to replace `geo` and `ip` properties on `NextRequest`',
|
|
101
|
+
value: 'next-request-geo-ip',
|
|
102
|
+
version: '15.0.0-canary.153',
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
title: 'Transforms usage of Next.js async Request APIs',
|
|
106
|
+
value: 'next-async-request-api',
|
|
107
|
+
version: '15.0.0-canary.171',
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
title: 'Transforms `experimental-edge` to `edge` in the `runtime` route segment configuration within the App Router',
|
|
111
|
+
value: 'app-dir-runtime-config-experimental-edge',
|
|
112
|
+
version: '15.0.0-canary.179',
|
|
113
|
+
},
|
|
114
|
+
];
|
|
115
|
+
//# sourceMappingURL=utils.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@next/codemod",
|
|
3
|
-
"version": "15.0.0-canary.
|
|
3
|
+
"version": "15.0.0-canary.181",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -8,17 +8,20 @@
|
|
|
8
8
|
"directory": "packages/next-codemod"
|
|
9
9
|
},
|
|
10
10
|
"dependencies": {
|
|
11
|
+
"chalk": "4.1.2",
|
|
11
12
|
"cheerio": "1.0.0-rc.9",
|
|
13
|
+
"commander": "12.1.0",
|
|
14
|
+
"compare-versions": "6.1.1",
|
|
12
15
|
"execa": "4.0.3",
|
|
13
16
|
"globby": "11.0.1",
|
|
14
|
-
"inquirer": "7.3.3",
|
|
15
17
|
"is-git-clean": "1.1.0",
|
|
16
|
-
"jscodeshift": "0.
|
|
17
|
-
"
|
|
18
|
-
"
|
|
18
|
+
"jscodeshift": "17.0.0",
|
|
19
|
+
"picocolors": "1.0.0",
|
|
20
|
+
"prompts": "2.4.2"
|
|
19
21
|
},
|
|
20
22
|
"files": [
|
|
21
23
|
"transforms/*.js",
|
|
24
|
+
"transforms/lib/**/*.js",
|
|
22
25
|
"bin/*.js",
|
|
23
26
|
"lib/**/*.js",
|
|
24
27
|
"lib/cra-to-next/gitignore"
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.default = transformer;
|
|
3
4
|
function addReactImport(j, root) {
|
|
4
5
|
// We create an import specifier, this is the value of an import, eg:
|
|
5
6
|
// import React from 'react'
|
|
@@ -60,5 +61,4 @@ function transformer(file, api, options) {
|
|
|
60
61
|
}
|
|
61
62
|
return root.toSource(options);
|
|
62
63
|
}
|
|
63
|
-
exports.default = transformer;
|
|
64
64
|
//# sourceMappingURL=add-missing-react-import.js.map
|