@next/codemod 15.0.0-canary.166 → 15.0.0-canary.168
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 +27 -3
- package/bin/transform.js +104 -0
- package/bin/upgrade.js +180 -202
- package/lib/cra-to-next/global-css-transform.js +1 -2
- package/lib/cra-to-next/index-to-component.js +1 -2
- package/lib/handle-package.js +5 -5
- package/lib/install.js +1 -1
- package/lib/run-jscodeshift.js +8 -1
- package/lib/utils.js +92 -0
- package/package.json +2 -3
- package/transforms/cra-to-next.js +237 -235
- package/transforms/lib/async-request-api/next-async-dynamic-api.js +3 -4
- package/transforms/lib/async-request-api/next-async-dynamic-prop.js +5 -7
- package/transforms/name-default-component.js +2 -3
- package/transforms/new-link.js +2 -3
- package/transforms/next-dynamic-access-named-export.js +2 -4
- package/transforms/next-image-experimental.js +8 -12
- package/transforms/next-image-to-legacy-image.js +4 -6
- package/transforms/next-request-geo-ip.js +10 -6
- package/bin/cli.js +0 -237
|
@@ -26,7 +26,6 @@ function transformDynamicProps(source, api, _filePath) {
|
|
|
26
26
|
function processAsyncPropOfEntryFile(isClientComponent) {
|
|
27
27
|
// find `params` and `searchParams` in file, and transform the access to them
|
|
28
28
|
function renameAsyncPropIfExisted(path) {
|
|
29
|
-
var _a;
|
|
30
29
|
const decl = path.value.declaration;
|
|
31
30
|
if (decl.type !== 'FunctionDeclaration' &&
|
|
32
31
|
decl.type !== 'FunctionExpression' &&
|
|
@@ -106,19 +105,19 @@ function transformDynamicProps(source, api, _filePath) {
|
|
|
106
105
|
if (foundTypes.interfaces.length > 0) {
|
|
107
106
|
const interfaceDeclaration = foundTypes.interfaces[0];
|
|
108
107
|
if (interfaceDeclaration.type === 'TSInterfaceDeclaration' &&
|
|
109
|
-
|
|
108
|
+
interfaceDeclaration.body?.type === 'TSInterfaceBody') {
|
|
110
109
|
const typeBody = interfaceDeclaration.body.body;
|
|
111
110
|
// if it's already a Promise, don't wrap it again, return
|
|
112
111
|
// traverse the typeReference's properties, if any is in propNames, wrap it in Promise<> if needed
|
|
113
112
|
typeBody.forEach((member) => {
|
|
114
|
-
var _a, _b, _c;
|
|
115
113
|
if (member.type === 'TSPropertySignature' &&
|
|
116
114
|
member.key.type === 'Identifier' &&
|
|
117
115
|
utils_1.TARGET_PROP_NAMES.has(member.key.name)) {
|
|
118
116
|
// if it's already a Promise, don't wrap it again, return
|
|
119
117
|
if (member.typeAnnotation &&
|
|
120
118
|
member.typeAnnotation.typeAnnotation &&
|
|
121
|
-
|
|
119
|
+
member.typeAnnotation?.typeAnnotation?.typeName
|
|
120
|
+
?.name === 'Promise') {
|
|
122
121
|
return;
|
|
123
122
|
}
|
|
124
123
|
// Wrap the prop type in Promise<>
|
|
@@ -161,7 +160,6 @@ function transformDynamicProps(source, api, _filePath) {
|
|
|
161
160
|
}
|
|
162
161
|
// Helper function to insert `const params = await asyncParams;` at the beginning of the function body
|
|
163
162
|
function resolveAsyncProp(path, propertiesMap, propsIdentifierName) {
|
|
164
|
-
var _a;
|
|
165
163
|
const isDefaultExport = path.value.type === 'ExportDefaultDeclaration';
|
|
166
164
|
// If it's sync default export, and it's also server component, make the function async
|
|
167
165
|
if (isDefaultExport &&
|
|
@@ -174,7 +172,7 @@ function transformDynamicProps(source, api, _filePath) {
|
|
|
174
172
|
}
|
|
175
173
|
const isAsyncFunc = isAsyncFunctionDeclaration(path);
|
|
176
174
|
// @ts-ignore quick way to check if it's a function and it has a name
|
|
177
|
-
const functionName =
|
|
175
|
+
const functionName = path.value.declaration.id?.name || 'default';
|
|
178
176
|
const functionBody = getBodyOfFunctionDeclaration(path);
|
|
179
177
|
for (const [propName, paramsProperty] of propertiesMap) {
|
|
180
178
|
const propNameIdentifier = j.identifier(propName);
|
|
@@ -185,7 +183,7 @@ function transformDynamicProps(source, api, _filePath) {
|
|
|
185
183
|
// input: Page({ params: { slug } })
|
|
186
184
|
// output: const { slug } = await props.params; rather than const props = await props.params;
|
|
187
185
|
const uid = functionName + ':' + propName;
|
|
188
|
-
if (
|
|
186
|
+
if (paramsProperty?.type === 'ObjectPattern') {
|
|
189
187
|
const objectPattern = paramsProperty;
|
|
190
188
|
const objectPatternProperties = objectPattern.properties;
|
|
191
189
|
// destruct the object pattern, e.g. { slug } => const { slug } = params;
|
|
@@ -15,11 +15,10 @@ function transformer(file, api, options) {
|
|
|
15
15
|
(node.type === 'BlockStatement' &&
|
|
16
16
|
j(node)
|
|
17
17
|
.find(j.ReturnStatement)
|
|
18
|
-
.some((path) =>
|
|
18
|
+
.some((path) => path.value.argument?.type === 'JSXElement'));
|
|
19
19
|
const hasRootAsParent = (path) => {
|
|
20
|
-
var _a;
|
|
21
20
|
const program = path.parentPath.parentPath.parentPath.parentPath.parentPath;
|
|
22
|
-
return !program ||
|
|
21
|
+
return !program || program?.value?.type === 'Program';
|
|
23
22
|
};
|
|
24
23
|
const nameFunctionComponent = (path) => {
|
|
25
24
|
const node = path.value;
|
package/transforms/new-link.js
CHANGED
|
@@ -71,11 +71,10 @@ function transformer(file, api) {
|
|
|
71
71
|
// Add only unique props to <Link> (skip duplicate props)
|
|
72
72
|
const linkPropNames = $link
|
|
73
73
|
.get('attributes')
|
|
74
|
-
.value.map((linkProp) =>
|
|
74
|
+
.value.map((linkProp) => linkProp?.name?.name);
|
|
75
75
|
const uniqueProps = [];
|
|
76
76
|
props.forEach((anchorProp) => {
|
|
77
|
-
|
|
78
|
-
if (!linkPropNames.includes((_a = anchorProp === null || anchorProp === void 0 ? void 0 : anchorProp.name) === null || _a === void 0 ? void 0 : _a.name)) {
|
|
77
|
+
if (!linkPropNames.includes(anchorProp?.name?.name)) {
|
|
79
78
|
uniqueProps.push(anchorProp);
|
|
80
79
|
}
|
|
81
80
|
});
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.default = transformer;
|
|
4
4
|
function transformer(file, api) {
|
|
5
|
-
var _a, _b, _c;
|
|
6
5
|
const j = api.jscodeshift;
|
|
7
6
|
const root = j(file.source);
|
|
8
7
|
// Find the import declaration for 'next/dynamic'
|
|
@@ -12,7 +11,7 @@ function transformer(file, api) {
|
|
|
12
11
|
// If the import declaration is found
|
|
13
12
|
if (dynamicImportDeclaration.size() > 0) {
|
|
14
13
|
const importDecl = dynamicImportDeclaration.get(0).node;
|
|
15
|
-
const dynamicImportName =
|
|
14
|
+
const dynamicImportName = importDecl.specifiers?.[0]?.local?.name;
|
|
16
15
|
if (!dynamicImportName) {
|
|
17
16
|
return root.toSource();
|
|
18
17
|
}
|
|
@@ -22,7 +21,6 @@ function transformer(file, api) {
|
|
|
22
21
|
callee: { name: dynamicImportName },
|
|
23
22
|
})
|
|
24
23
|
.forEach((path) => {
|
|
25
|
-
var _a;
|
|
26
24
|
const arrowFunction = path.node.arguments[0];
|
|
27
25
|
// Ensure the argument is an ArrowFunctionExpression
|
|
28
26
|
if (arrowFunction && arrowFunction.type === 'ArrowFunctionExpression') {
|
|
@@ -43,7 +41,7 @@ function transformer(file, api) {
|
|
|
43
41
|
// Ensure the body of the arrow function has a return statement with a MemberExpression
|
|
44
42
|
if (returnStatement &&
|
|
45
43
|
returnStatement.type === 'ReturnStatement' &&
|
|
46
|
-
|
|
44
|
+
returnStatement.argument?.type === 'MemberExpression') {
|
|
47
45
|
returnStatement.argument = j.objectExpression([
|
|
48
46
|
j.property('init', j.identifier('default'), returnStatement.argument),
|
|
49
47
|
]);
|
|
@@ -22,14 +22,12 @@ function findAndReplaceProps(j, root, tagName) {
|
|
|
22
22
|
el.value.openingElement.name.type === 'JSXIdentifier' &&
|
|
23
23
|
el.value.openingElement.name.name === tagName)
|
|
24
24
|
.forEach((el) => {
|
|
25
|
-
var _a;
|
|
26
25
|
let layout = 'intrinsic';
|
|
27
26
|
let objectFit = null;
|
|
28
27
|
let objectPosition = null;
|
|
29
28
|
let styleExpProps = [];
|
|
30
29
|
let sizesAttr = null;
|
|
31
|
-
const attributes =
|
|
32
|
-
var _a, _b;
|
|
30
|
+
const attributes = el.node.openingElement.attributes?.filter((a) => {
|
|
33
31
|
if (a.type !== 'JSXAttribute') {
|
|
34
32
|
return true;
|
|
35
33
|
}
|
|
@@ -52,11 +50,11 @@ function findAndReplaceProps(j, root, tagName) {
|
|
|
52
50
|
return false;
|
|
53
51
|
}
|
|
54
52
|
if (a.name.name === 'style') {
|
|
55
|
-
if (
|
|
53
|
+
if (a.value?.type === 'JSXExpressionContainer' &&
|
|
56
54
|
a.value.expression.type === 'ObjectExpression') {
|
|
57
55
|
styleExpProps = a.value.expression.properties;
|
|
58
56
|
}
|
|
59
|
-
else if (
|
|
57
|
+
else if (a.value?.type === 'JSXExpressionContainer' &&
|
|
60
58
|
a.value.expression.type === 'Identifier') {
|
|
61
59
|
styleExpProps = [
|
|
62
60
|
j.spreadElement(j.identifier(a.value.expression.name)),
|
|
@@ -209,9 +207,8 @@ function transformer(file, api, options) {
|
|
|
209
207
|
source: { value: 'next/legacy/image' },
|
|
210
208
|
})
|
|
211
209
|
.forEach((imageImport) => {
|
|
212
|
-
|
|
213
|
-
const
|
|
214
|
-
const tagName = (_b = defaultSpecifier === null || defaultSpecifier === void 0 ? void 0 : defaultSpecifier.local) === null || _b === void 0 ? void 0 : _b.name;
|
|
210
|
+
const defaultSpecifier = imageImport.node.specifiers?.find((node) => node.type === 'ImportDefaultSpecifier');
|
|
211
|
+
const tagName = defaultSpecifier?.local?.name;
|
|
215
212
|
imageImport.node.source = j.stringLiteral('next/image');
|
|
216
213
|
if (tagName) {
|
|
217
214
|
findAndReplaceProps(j, root, tagName);
|
|
@@ -221,7 +218,7 @@ function transformer(file, api, options) {
|
|
|
221
218
|
// After: const Image = await import("next/image")
|
|
222
219
|
root.find(j.AwaitExpression).forEach((awaitExp) => {
|
|
223
220
|
const arg = awaitExp.value.argument;
|
|
224
|
-
if (
|
|
221
|
+
if (arg?.type === 'CallExpression' && arg.callee.type === 'Import') {
|
|
225
222
|
if (arg.arguments[0].type === 'StringLiteral' &&
|
|
226
223
|
arg.arguments[0].value === 'next/legacy/image') {
|
|
227
224
|
arg.arguments[0] = j.stringLiteral('next/image');
|
|
@@ -231,14 +228,13 @@ function transformer(file, api, options) {
|
|
|
231
228
|
// Before: const Image = require("next/legacy/image")
|
|
232
229
|
// After: const Image = require("next/image")
|
|
233
230
|
root.find(j.CallExpression).forEach((requireExp) => {
|
|
234
|
-
|
|
235
|
-
if (((_b = (_a = requireExp === null || requireExp === void 0 ? void 0 : requireExp.value) === null || _a === void 0 ? void 0 : _a.callee) === null || _b === void 0 ? void 0 : _b.type) === 'Identifier' &&
|
|
231
|
+
if (requireExp?.value?.callee?.type === 'Identifier' &&
|
|
236
232
|
requireExp.value.callee.name === 'require') {
|
|
237
233
|
let firstArg = requireExp.value.arguments[0];
|
|
238
234
|
if (firstArg &&
|
|
239
235
|
firstArg.type === 'StringLiteral' &&
|
|
240
236
|
firstArg.value === 'next/legacy/image') {
|
|
241
|
-
const tagName =
|
|
237
|
+
const tagName = requireExp?.parentPath?.value?.id?.name;
|
|
242
238
|
if (tagName) {
|
|
243
239
|
requireExp.value.arguments[0] = j.stringLiteral('next/image');
|
|
244
240
|
findAndReplaceProps(j, root, tagName);
|
|
@@ -17,7 +17,7 @@ function transformer(file, api, options) {
|
|
|
17
17
|
// After: const Image = await import("next/legacy/image")
|
|
18
18
|
root.find(j.AwaitExpression).forEach((awaitExp) => {
|
|
19
19
|
const arg = awaitExp.value.argument;
|
|
20
|
-
if (
|
|
20
|
+
if (arg?.type === 'CallExpression' && arg.callee.type === 'Import') {
|
|
21
21
|
if (arg.arguments[0].type === 'StringLiteral' &&
|
|
22
22
|
arg.arguments[0].value === 'next/image') {
|
|
23
23
|
arg.arguments[0] = j.stringLiteral('next/legacy/image');
|
|
@@ -37,7 +37,7 @@ function transformer(file, api, options) {
|
|
|
37
37
|
// After: const Image = await import("next/image")
|
|
38
38
|
root.find(j.AwaitExpression).forEach((awaitExp) => {
|
|
39
39
|
const arg = awaitExp.value.argument;
|
|
40
|
-
if (
|
|
40
|
+
if (arg?.type === 'CallExpression' && arg.callee.type === 'Import') {
|
|
41
41
|
if (arg.arguments[0].type === 'StringLiteral' &&
|
|
42
42
|
arg.arguments[0].value === 'next/future/image') {
|
|
43
43
|
arg.arguments[0] = j.stringLiteral('next/image');
|
|
@@ -47,8 +47,7 @@ function transformer(file, api, options) {
|
|
|
47
47
|
// Before: const Image = require("next/image")
|
|
48
48
|
// After: const Image = require("next/legacy/image")
|
|
49
49
|
root.find(j.CallExpression).forEach((requireExp) => {
|
|
50
|
-
|
|
51
|
-
if (((_b = (_a = requireExp === null || requireExp === void 0 ? void 0 : requireExp.value) === null || _a === void 0 ? void 0 : _a.callee) === null || _b === void 0 ? void 0 : _b.type) === 'Identifier' &&
|
|
50
|
+
if (requireExp?.value?.callee?.type === 'Identifier' &&
|
|
52
51
|
requireExp.value.callee.name === 'require') {
|
|
53
52
|
let firstArg = requireExp.value.arguments[0];
|
|
54
53
|
if (firstArg &&
|
|
@@ -61,8 +60,7 @@ function transformer(file, api, options) {
|
|
|
61
60
|
// Before: const Image = require("next/future/image")
|
|
62
61
|
// After: const Image = require("next/image")
|
|
63
62
|
root.find(j.CallExpression).forEach((requireExp) => {
|
|
64
|
-
|
|
65
|
-
if (((_b = (_a = requireExp === null || requireExp === void 0 ? void 0 : requireExp.value) === null || _a === void 0 ? void 0 : _a.callee) === null || _b === void 0 ? void 0 : _b.type) === 'Identifier' &&
|
|
63
|
+
if (requireExp?.value?.callee?.type === 'Identifier' &&
|
|
66
64
|
requireExp.value.callee.name === 'require') {
|
|
67
65
|
let firstArg = requireExp.value.arguments[0];
|
|
68
66
|
if (firstArg &&
|
|
@@ -15,8 +15,7 @@ function default_1(fileInfo, api) {
|
|
|
15
15
|
const nextReqType = root
|
|
16
16
|
.find(j.FunctionDeclaration)
|
|
17
17
|
.find(j.Identifier, (id) => {
|
|
18
|
-
|
|
19
|
-
if (((_a = id.typeAnnotation) === null || _a === void 0 ? void 0 : _a.type) !== 'TSTypeAnnotation') {
|
|
18
|
+
if (id.typeAnnotation?.type !== 'TSTypeAnnotation') {
|
|
20
19
|
return false;
|
|
21
20
|
}
|
|
22
21
|
const typeAnn = id.typeAnnotation.typeAnnotation;
|
|
@@ -74,9 +73,8 @@ function default_1(fileInfo, api) {
|
|
|
74
73
|
* Returns an existing identifier from the Vercel functions import declaration.
|
|
75
74
|
*/
|
|
76
75
|
function getExistingIdentifier(vercelFuncImportSpecifiers, identifier) {
|
|
77
|
-
var _a;
|
|
78
76
|
const existingIdentifier = vercelFuncImportSpecifiers.find((node) => node.imported.name === identifier);
|
|
79
|
-
return (
|
|
77
|
+
return (existingIdentifier?.local?.name ||
|
|
80
78
|
existingIdentifier.imported.name ||
|
|
81
79
|
identifier);
|
|
82
80
|
}
|
|
@@ -127,10 +125,16 @@ function replaceGeoIpValues(j, nextReqType, geoIdentifier, ipIdentifier) {
|
|
|
127
125
|
prop.key.name === IP));
|
|
128
126
|
// geolocation(req), ipAddress(req)
|
|
129
127
|
const geoCall = j.callExpression(j.identifier(geoIdentifier), [
|
|
130
|
-
|
|
128
|
+
{
|
|
129
|
+
...nextReqPath.node,
|
|
130
|
+
typeAnnotation: null,
|
|
131
|
+
},
|
|
131
132
|
]);
|
|
132
133
|
const ipCall = j.callExpression(j.identifier(ipIdentifier), [
|
|
133
|
-
|
|
134
|
+
{
|
|
135
|
+
...nextReqPath.node,
|
|
136
|
+
typeAnnotation: null,
|
|
137
|
+
},
|
|
134
138
|
]);
|
|
135
139
|
geoAccesses.replaceWith(geoCall);
|
|
136
140
|
ipAccesses.replaceWith(ipCall);
|
package/bin/cli.js
DELETED
|
@@ -1,237 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Copyright 2015-present, Facebook, Inc.
|
|
4
|
-
*
|
|
5
|
-
* This source code is licensed under the MIT license found in the
|
|
6
|
-
* LICENSE file in the root directory of this source tree.
|
|
7
|
-
*
|
|
8
|
-
*/
|
|
9
|
-
// Based on https://github.com/reactjs/react-codemod/blob/dd8671c9a470a2c342b221ec903c574cf31e9f57/bin/cli.js
|
|
10
|
-
// @next/codemod optional-name-of-transform optional/path/to/src [...options]
|
|
11
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
-
};
|
|
14
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
exports.transformerDirectory = exports.jscodeshiftExecutable = void 0;
|
|
16
|
-
exports.checkGitStatus = checkGitStatus;
|
|
17
|
-
exports.runTransform = runTransform;
|
|
18
|
-
exports.run = run;
|
|
19
|
-
const globby_1 = __importDefault(require("globby"));
|
|
20
|
-
const inquirer_1 = __importDefault(require("inquirer"));
|
|
21
|
-
const meow_1 = __importDefault(require("meow"));
|
|
22
|
-
const path_1 = __importDefault(require("path"));
|
|
23
|
-
const execa_1 = __importDefault(require("execa"));
|
|
24
|
-
const picocolors_1 = require("picocolors");
|
|
25
|
-
const is_git_clean_1 = __importDefault(require("is-git-clean"));
|
|
26
|
-
const handle_package_1 = require("../lib/handle-package");
|
|
27
|
-
const upgrade_1 = require("./upgrade");
|
|
28
|
-
exports.jscodeshiftExecutable = require.resolve('.bin/jscodeshift');
|
|
29
|
-
exports.transformerDirectory = path_1.default.join(__dirname, '../', 'transforms');
|
|
30
|
-
function checkGitStatus(force) {
|
|
31
|
-
let clean = false;
|
|
32
|
-
let errorMessage = 'Unable to determine if git directory is clean';
|
|
33
|
-
try {
|
|
34
|
-
clean = is_git_clean_1.default.sync(process.cwd());
|
|
35
|
-
errorMessage = 'Git directory is not clean';
|
|
36
|
-
}
|
|
37
|
-
catch (err) {
|
|
38
|
-
if (err && err.stderr && err.stderr.includes('Not a git repository')) {
|
|
39
|
-
clean = true;
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
if (!clean) {
|
|
43
|
-
if (force) {
|
|
44
|
-
console.log(`WARNING: ${errorMessage}. Forcibly continuing.`);
|
|
45
|
-
}
|
|
46
|
-
else {
|
|
47
|
-
console.log('Thank you for using @next/codemod!');
|
|
48
|
-
console.log((0, picocolors_1.yellow)('\nBut before we continue, please stash or commit your git changes.'));
|
|
49
|
-
console.log('\nYou may use the --force flag to override this safety check.');
|
|
50
|
-
process.exit(1);
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
function runTransform({ files, flags, transformer }) {
|
|
55
|
-
const transformerPath = path_1.default.join(exports.transformerDirectory, `${transformer}.js`);
|
|
56
|
-
if (transformer === 'cra-to-next') {
|
|
57
|
-
// cra-to-next transform doesn't use jscodeshift directly
|
|
58
|
-
return require(transformerPath).default(files, flags);
|
|
59
|
-
}
|
|
60
|
-
let args = [];
|
|
61
|
-
const { dry, print, runInBand } = flags;
|
|
62
|
-
if (dry) {
|
|
63
|
-
args.push('--dry');
|
|
64
|
-
}
|
|
65
|
-
if (print) {
|
|
66
|
-
args.push('--print');
|
|
67
|
-
}
|
|
68
|
-
if (runInBand) {
|
|
69
|
-
args.push('--run-in-band');
|
|
70
|
-
}
|
|
71
|
-
args.push('--verbose=2');
|
|
72
|
-
args.push('--ignore-pattern=**/node_modules/**');
|
|
73
|
-
args.push('--ignore-pattern=**/.next/**');
|
|
74
|
-
args.push('--extensions=tsx,ts,jsx,js');
|
|
75
|
-
args = args.concat(['--transform', transformerPath]);
|
|
76
|
-
if (flags.jscodeshift) {
|
|
77
|
-
args = args.concat(flags.jscodeshift);
|
|
78
|
-
}
|
|
79
|
-
args = args.concat(files);
|
|
80
|
-
console.log(`Executing command: jscodeshift ${args.join(' ')}`);
|
|
81
|
-
const result = execa_1.default.sync(exports.jscodeshiftExecutable, args, {
|
|
82
|
-
stdio: 'inherit',
|
|
83
|
-
stripFinalNewline: false,
|
|
84
|
-
});
|
|
85
|
-
if (result.failed) {
|
|
86
|
-
throw new Error(`jscodeshift exited with code ${result.exitCode}`);
|
|
87
|
-
}
|
|
88
|
-
if (!dry && transformer === 'built-in-next-font') {
|
|
89
|
-
console.log('Uninstalling `@next/font`');
|
|
90
|
-
try {
|
|
91
|
-
(0, handle_package_1.uninstallPackage)('@next/font');
|
|
92
|
-
}
|
|
93
|
-
catch (_a) {
|
|
94
|
-
console.error("Couldn't uninstall `@next/font`, please uninstall it manually");
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
if (!dry && transformer === 'next-request-geo-ip') {
|
|
98
|
-
console.log('Installing `@vercel/functions`...');
|
|
99
|
-
(0, handle_package_1.installPackage)('@vercel/functions');
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
const TRANSFORMER_INQUIRER_CHOICES = [
|
|
103
|
-
{
|
|
104
|
-
name: 'name-default-component: Transforms anonymous components into named components to make sure they work with Fast Refresh',
|
|
105
|
-
value: 'name-default-component',
|
|
106
|
-
},
|
|
107
|
-
{
|
|
108
|
-
name: 'add-missing-react-import: Transforms files that do not import `React` to include the import in order for the new React JSX transform',
|
|
109
|
-
value: 'add-missing-react-import',
|
|
110
|
-
},
|
|
111
|
-
{
|
|
112
|
-
name: 'withamp-to-config: Transforms the withAmp HOC into Next.js 9 page configuration',
|
|
113
|
-
value: 'withamp-to-config',
|
|
114
|
-
},
|
|
115
|
-
{
|
|
116
|
-
name: 'url-to-withrouter: Transforms the deprecated automatically injected url property on top level pages to using withRouter',
|
|
117
|
-
value: 'url-to-withrouter',
|
|
118
|
-
},
|
|
119
|
-
{
|
|
120
|
-
name: 'cra-to-next (experimental): automatically migrates a Create React App project to Next.js',
|
|
121
|
-
value: 'cra-to-next',
|
|
122
|
-
},
|
|
123
|
-
{
|
|
124
|
-
name: 'new-link: Ensures your <Link> usage is backwards compatible.',
|
|
125
|
-
value: 'new-link',
|
|
126
|
-
},
|
|
127
|
-
{
|
|
128
|
-
name: 'next-og-import: Transforms imports from `next/server` to `next/og` for usage of Dynamic OG Image Generation.',
|
|
129
|
-
value: 'next-og-import',
|
|
130
|
-
},
|
|
131
|
-
{
|
|
132
|
-
name: 'metadata-to-viewport-export: Migrates certain viewport related metadata from the `metadata` export to a new `viewport` export.',
|
|
133
|
-
value: 'metadata-to-viewport-export',
|
|
134
|
-
},
|
|
135
|
-
{
|
|
136
|
-
name: 'next-dynamic-access-named-export: Transforms dynamic imports that return the named export itself to a module like object.',
|
|
137
|
-
value: 'next-dynamic-access-named-export',
|
|
138
|
-
},
|
|
139
|
-
{
|
|
140
|
-
name: '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',
|
|
141
|
-
value: 'next-image-to-legacy-image',
|
|
142
|
-
},
|
|
143
|
-
{
|
|
144
|
-
name: 'next-image-experimental (experimental): dangerously migrates from `next/legacy/image` to the new `next/image` by adding inline styles and removing unused props',
|
|
145
|
-
value: 'next-image-experimental',
|
|
146
|
-
},
|
|
147
|
-
{
|
|
148
|
-
name: 'built-in-next-font: Uninstall `@next/font` and transform imports to `next/font`',
|
|
149
|
-
value: 'built-in-next-font',
|
|
150
|
-
},
|
|
151
|
-
{
|
|
152
|
-
name: 'next-async-request-api: Transforms usage of Next.js async Request APIs',
|
|
153
|
-
value: 'next-async-request-api',
|
|
154
|
-
},
|
|
155
|
-
{
|
|
156
|
-
name: 'next-request-geo-ip: Install `@vercel/functions` to replace `geo` and `ip` properties on `NextRequest`',
|
|
157
|
-
value: 'next-request-geo-ip',
|
|
158
|
-
},
|
|
159
|
-
];
|
|
160
|
-
function expandFilePathsIfNeeded(filesBeforeExpansion) {
|
|
161
|
-
const shouldExpandFiles = filesBeforeExpansion.some((file) => file.includes('*'));
|
|
162
|
-
return shouldExpandFiles
|
|
163
|
-
? globby_1.default.sync(filesBeforeExpansion)
|
|
164
|
-
: filesBeforeExpansion;
|
|
165
|
-
}
|
|
166
|
-
function run() {
|
|
167
|
-
const cli = (0, meow_1.default)({
|
|
168
|
-
description: 'Codemods for updating Next.js apps.',
|
|
169
|
-
help: `
|
|
170
|
-
Usage
|
|
171
|
-
$ npx @next/codemod <transform> <path> <...options>
|
|
172
|
-
transform One of the choices from https://github.com/vercel/next.js/tree/canary/packages/next-codemod
|
|
173
|
-
path Files or directory to transform. Can be a glob like pages/**.js
|
|
174
|
-
Options
|
|
175
|
-
--force Bypass Git safety checks and forcibly run codemods
|
|
176
|
-
--dry Dry run (no changes are made to files)
|
|
177
|
-
--print Print transformed files to your terminal
|
|
178
|
-
--jscodeshift (Advanced) Pass options directly to jscodeshift
|
|
179
|
-
`,
|
|
180
|
-
flags: {
|
|
181
|
-
boolean: ['force', 'dry', 'print', 'help'],
|
|
182
|
-
string: ['_'],
|
|
183
|
-
alias: {
|
|
184
|
-
h: 'help',
|
|
185
|
-
},
|
|
186
|
-
},
|
|
187
|
-
});
|
|
188
|
-
if (!cli.flags.dry) {
|
|
189
|
-
checkGitStatus(cli.flags.force);
|
|
190
|
-
}
|
|
191
|
-
const isUpgrade = cli.input[0] === 'upgrade' || cli.input[0] === 'up';
|
|
192
|
-
if (isUpgrade) {
|
|
193
|
-
return (0, upgrade_1.runUpgrade)().catch(console.error);
|
|
194
|
-
}
|
|
195
|
-
if (cli.input[0] &&
|
|
196
|
-
!TRANSFORMER_INQUIRER_CHOICES.find((x) => x.value === cli.input[0])) {
|
|
197
|
-
console.error('Invalid transform choice, pick one of:');
|
|
198
|
-
console.error(TRANSFORMER_INQUIRER_CHOICES.map((x) => '- ' + x.value).join('\n'));
|
|
199
|
-
process.exit(1);
|
|
200
|
-
}
|
|
201
|
-
inquirer_1.default
|
|
202
|
-
.prompt([
|
|
203
|
-
{
|
|
204
|
-
type: 'input',
|
|
205
|
-
name: 'files',
|
|
206
|
-
message: 'On which files or directory should the codemods be applied?',
|
|
207
|
-
when: !cli.input[1],
|
|
208
|
-
default: '.',
|
|
209
|
-
// validate: () =>
|
|
210
|
-
filter: (files) => files.trim(),
|
|
211
|
-
},
|
|
212
|
-
{
|
|
213
|
-
type: 'list',
|
|
214
|
-
name: 'transformer',
|
|
215
|
-
message: 'Which transform would you like to apply?',
|
|
216
|
-
when: !cli.input[0],
|
|
217
|
-
pageSize: TRANSFORMER_INQUIRER_CHOICES.length,
|
|
218
|
-
choices: TRANSFORMER_INQUIRER_CHOICES,
|
|
219
|
-
},
|
|
220
|
-
])
|
|
221
|
-
.then((answers) => {
|
|
222
|
-
const { files, transformer } = answers;
|
|
223
|
-
const filesBeforeExpansion = cli.input[1] || files;
|
|
224
|
-
const filesExpanded = expandFilePathsIfNeeded([filesBeforeExpansion]);
|
|
225
|
-
const selectedTransformer = cli.input[0] || transformer;
|
|
226
|
-
if (!filesExpanded.length) {
|
|
227
|
-
console.log(`No files found matching ${filesBeforeExpansion.join(' ')}`);
|
|
228
|
-
return null;
|
|
229
|
-
}
|
|
230
|
-
return runTransform({
|
|
231
|
-
files: filesExpanded,
|
|
232
|
-
flags: cli.flags,
|
|
233
|
-
transformer: selectedTransformer,
|
|
234
|
-
});
|
|
235
|
-
});
|
|
236
|
-
}
|
|
237
|
-
//# sourceMappingURL=cli.js.map
|