@next/codemod 15.0.3-canary.5 → 15.0.3-canary.7
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/package.json
CHANGED
|
@@ -4,6 +4,9 @@ exports.transformDynamicProps = transformDynamicProps;
|
|
|
4
4
|
const utils_1 = require("./utils");
|
|
5
5
|
const parser_1 = require("../../../lib/parser");
|
|
6
6
|
const PAGE_PROPS = 'props';
|
|
7
|
+
// Find all the member access of the prop, and await them
|
|
8
|
+
// e.g. If there's argument `props`, find all the member access of props.<name>.
|
|
9
|
+
// If the member access can be awaited, await them.
|
|
7
10
|
function awaitMemberAccessOfProp(propIdName, path, j) {
|
|
8
11
|
// search the member access of the prop
|
|
9
12
|
const functionBody = (0, utils_1.findFunctionBody)(path);
|
|
@@ -30,6 +33,17 @@ function awaitMemberAccessOfProp(propIdName, path, j) {
|
|
|
30
33
|
if (memberAccessPath.parentPath?.value.type === 'AwaitExpression') {
|
|
31
34
|
return;
|
|
32
35
|
}
|
|
36
|
+
const parentScopeOfMemberAccess = (0, utils_1.findClosetParentFunctionScope)(memberAccessPath, j);
|
|
37
|
+
// When the parent scope is sync, and it's also not the function itself, which means it's not able to convert to async.
|
|
38
|
+
if (parentScopeOfMemberAccess &&
|
|
39
|
+
!parentScopeOfMemberAccess.value?.async &&
|
|
40
|
+
parentScopeOfMemberAccess.node !== path.node) {
|
|
41
|
+
// If it's not able to convert, add a comment to the prop access to warn the user
|
|
42
|
+
// e.g. the parent scope is sync, await keyword can't be applied
|
|
43
|
+
const comment = ` ${utils_1.NEXT_CODEMOD_ERROR_PREFIX} '${propIdName}.${memberProperty.name}' is accessed without awaiting.`;
|
|
44
|
+
(0, utils_1.insertCommentOnce)(member, j, comment);
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
33
47
|
const awaitedExpr = j.awaitExpression(member);
|
|
34
48
|
const awaitMemberAccess = (0, utils_1.wrapParentheseIfNeeded)(true, j, awaitedExpr);
|
|
35
49
|
memberAccessPath.replace(awaitMemberAccess);
|
|
@@ -238,6 +252,43 @@ function modifyTypes(paramTypeAnnotation, propsIdentifier, root, j) {
|
|
|
238
252
|
}
|
|
239
253
|
}
|
|
240
254
|
}
|
|
255
|
+
if (foundTypes.imports.length > 0) {
|
|
256
|
+
// console.log('typeReference.typeName.name', typeReference.typeName.name, foundTypes)
|
|
257
|
+
// If it's React PropsWithChildren
|
|
258
|
+
if (typeReference.typeName.name === 'PropsWithChildren') {
|
|
259
|
+
const propType = typeReference.typeParameters?.params[0];
|
|
260
|
+
if (propType &&
|
|
261
|
+
j.TSTypeLiteral.check(propType) &&
|
|
262
|
+
propType.members.length > 0) {
|
|
263
|
+
const typeLiteral = propType;
|
|
264
|
+
typeLiteral.members.forEach((member) => {
|
|
265
|
+
if (j.TSPropertySignature.check(member) &&
|
|
266
|
+
j.Identifier.check(member.key) &&
|
|
267
|
+
utils_1.TARGET_PROP_NAMES.has(member.key.name)) {
|
|
268
|
+
// if it's already a Promise, don't wrap it again, return
|
|
269
|
+
if (member.typeAnnotation &&
|
|
270
|
+
member.typeAnnotation.typeAnnotation &&
|
|
271
|
+
member.typeAnnotation.typeAnnotation.type ===
|
|
272
|
+
'TSTypeReference' &&
|
|
273
|
+
member.typeAnnotation.typeAnnotation.typeName.type ===
|
|
274
|
+
'Identifier' &&
|
|
275
|
+
member.typeAnnotation.typeAnnotation.typeName.name ===
|
|
276
|
+
'Promise') {
|
|
277
|
+
return;
|
|
278
|
+
}
|
|
279
|
+
// Wrap the prop type in Promise<>
|
|
280
|
+
if (member.typeAnnotation &&
|
|
281
|
+
j.TSTypeLiteral.check(member.typeAnnotation.typeAnnotation)) {
|
|
282
|
+
member.typeAnnotation.typeAnnotation = j.tsTypeReference(j.identifier('Promise'), j.tsTypeParameterInstantiation([
|
|
283
|
+
member.typeAnnotation.typeAnnotation,
|
|
284
|
+
]));
|
|
285
|
+
modified = true;
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
}
|
|
241
292
|
}
|
|
242
293
|
}
|
|
243
294
|
propsIdentifier.typeAnnotation = paramTypeAnnotation;
|
|
@@ -335,6 +386,9 @@ function transformDynamicProps(source, _api, filePath) {
|
|
|
335
386
|
}
|
|
336
387
|
}
|
|
337
388
|
else {
|
|
389
|
+
// If it's (props.params).<name>, await the member access
|
|
390
|
+
// const pathOfCurrentParam = path.get('params', propsArgumentIndex)
|
|
391
|
+
// const paramScope = findClosetParentFunctionScope(pathOfCurrentParam, j)
|
|
338
392
|
const awaited = awaitMemberAccessOfProp(argName, path, j);
|
|
339
393
|
modified ||= awaited;
|
|
340
394
|
}
|
|
@@ -199,6 +199,8 @@ function isFunctionScope(path, j) {
|
|
|
199
199
|
j.ArrowFunctionExpression.check(node));
|
|
200
200
|
}
|
|
201
201
|
function findClosetParentFunctionScope(path, j) {
|
|
202
|
+
if (!path.scope)
|
|
203
|
+
return null;
|
|
202
204
|
let parentFunctionPath = path.scope.path;
|
|
203
205
|
while (parentFunctionPath && !isFunctionScope(parentFunctionPath, j)) {
|
|
204
206
|
parentFunctionPath = parentFunctionPath.parent;
|