Skip to content

Commit 0ed75c4

Browse files
authored
Add comments for unsupported named deep import of DocumentClient (#541)
1 parent 0c09d94 commit 0ed75c4

11 files changed

+191
-85
lines changed

.changeset/khaki-zebras-relax.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"aws-sdk-js-codemod": patch
3+
---
4+
5+
Add comments for unsupported named deep import of DocumentClient
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import { DocumentClient } from "aws-sdk/clients/dynamodb";
2+
3+
const documentClient = new DocumentClient({ region: "us-west-2" });
4+
const response = await documentClient.scan({ TableName: "TABLE_NAME" }).promise();
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// Transformation of DocumentClient named import from deep path is unsupported in aws-sdk-js-codemod.
2+
// Please convert to a default import, and re-run aws-sdk-js-codemod.
3+
import { DocumentClient } from "aws-sdk/clients/dynamodb";
4+
5+
const documentClient = new DocumentClient({ region: "us-west-2" });
6+
const response = await documentClient.scan({ TableName: "TABLE_NAME" }).promise();
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
const { DocumentClient } = require("aws-sdk/clients/dynamodb");
2+
3+
const documentClient = new DocumentClient({ region: "us-west-2" });
4+
const response = await documentClient.scan({ TableName: "TABLE_NAME" }).promise();
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// Transformation of DocumentClient named import from deep path is unsupported in aws-sdk-js-codemod.
2+
// Please convert to a default import, and re-run aws-sdk-js-codemod.
3+
const { DocumentClient } = require("aws-sdk/clients/dynamodb");
4+
5+
const documentClient = new DocumentClient({ region: "us-west-2" });
6+
const response = await documentClient.scan({ TableName: "TABLE_NAME" }).promise();
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
import { Collection, JSCodeshift } from "jscodeshift";
2+
3+
import { FUNCTION_TYPE_LIST } from "../config";
4+
import { getClientApiCallExpression } from "./getClientApiCallExpression";
5+
import { getClientIdentifiers } from "./getClientIdentifiers";
6+
import { getClientWaiterCallExpression } from "./getClientWaiterCallExpression";
7+
import { getClientWaiterStates } from "./getClientWaiterStates";
8+
9+
export interface CommentsForUnsupportedAPIsOptions {
10+
v2ClientName: string;
11+
v2ClientLocalName: string;
12+
v2GlobalName?: string;
13+
}
14+
15+
export const addNotSupportedClientComments = (
16+
j: JSCodeshift,
17+
source: Collection<unknown>,
18+
options: CommentsForUnsupportedAPIsOptions
19+
): void => {
20+
const clientIdentifiers = getClientIdentifiers(j, source, options);
21+
22+
for (const clientId of clientIdentifiers) {
23+
const waiterStates = getClientWaiterStates(j, source, options);
24+
25+
for (const waiterState of waiterStates) {
26+
source
27+
.find(j.CallExpression, getClientWaiterCallExpression(clientId, waiterState))
28+
.forEach((callExpression) => {
29+
const args = callExpression.node.arguments;
30+
31+
if (FUNCTION_TYPE_LIST.includes(args[args.length - 1].type)) {
32+
const comments = callExpression.node.comments || [];
33+
comments.push(
34+
j.commentLine(
35+
" Waiters with callbacks are not supported in AWS SDK for JavaScript (v3)."
36+
)
37+
);
38+
comments.push(
39+
j.commentLine(
40+
" Please convert to `await client.waitFor(state, params).promise()`, and re-run aws-sdk-js-codemod."
41+
)
42+
);
43+
callExpression.node.comments = comments;
44+
}
45+
});
46+
}
47+
}
48+
49+
if (options.v2ClientName === "S3") {
50+
for (const clientId of clientIdentifiers) {
51+
const apiMetadata = [
52+
{
53+
apiName: "upload",
54+
apiDescription: "S3 ManagedUpload",
55+
apiSuggestion: "await client.upload(params, options).promise()",
56+
},
57+
{
58+
apiName: "getSignedUrl",
59+
apiDescription: "S3 getSignedUrl",
60+
apiSuggestion: "client.getSignedUrl(apiName, options)",
61+
},
62+
];
63+
for (const { apiName, apiDescription, apiSuggestion } of apiMetadata) {
64+
source
65+
.find(j.CallExpression, getClientApiCallExpression(clientId, apiName))
66+
.forEach((callExpression) => {
67+
const args = callExpression.node.arguments;
68+
69+
if (FUNCTION_TYPE_LIST.includes(args[args.length - 1].type)) {
70+
const comments = callExpression.node.comments || [];
71+
comments.push(
72+
j.commentLine(
73+
` ${apiDescription} with callbacks are not supported in AWS SDK for JavaScript (v3).`
74+
)
75+
);
76+
comments.push(
77+
j.commentLine(
78+
` Please convert to '${apiSuggestion}', and re-run aws-sdk-js-codemod.`
79+
)
80+
);
81+
callExpression.node.comments = comments;
82+
}
83+
});
84+
}
85+
}
86+
}
87+
};
Lines changed: 19 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -1,87 +1,22 @@
11
import { Collection, JSCodeshift } from "jscodeshift";
2-
3-
import { FUNCTION_TYPE_LIST } from "../config";
4-
import { getClientApiCallExpression } from "./getClientApiCallExpression";
5-
import { getClientIdentifiers } from "./getClientIdentifiers";
6-
import { getClientWaiterCallExpression } from "./getClientWaiterCallExpression";
7-
import { getClientWaiterStates } from "./getClientWaiterStates";
8-
9-
export interface CommentsForUnsupportedAPIsOptions {
10-
v2ClientName: string;
11-
v2ClientLocalName: string;
12-
v2GlobalName?: string;
13-
}
14-
15-
export const addNotSupportedComments = (
16-
j: JSCodeshift,
17-
source: Collection<unknown>,
18-
options: CommentsForUnsupportedAPIsOptions
19-
): void => {
20-
const clientIdentifiers = getClientIdentifiers(j, source, options);
21-
22-
for (const clientId of clientIdentifiers) {
23-
const waiterStates = getClientWaiterStates(j, source, options);
24-
25-
for (const waiterState of waiterStates) {
26-
source
27-
.find(j.CallExpression, getClientWaiterCallExpression(clientId, waiterState))
28-
.forEach((callExpression) => {
29-
const args = callExpression.node.arguments;
30-
31-
if (FUNCTION_TYPE_LIST.includes(args[args.length - 1].type)) {
32-
const comments = callExpression.node.comments || [];
33-
comments.push(
34-
j.commentLine(
35-
" Waiters with callbacks are not supported in AWS SDK for JavaScript (v3)."
36-
)
37-
);
38-
comments.push(
39-
j.commentLine(
40-
" Please convert to `await client.waitFor(state, params).promise()`, and re-run aws-sdk-js-codemod."
41-
)
42-
);
43-
callExpression.node.comments = comments;
44-
}
45-
});
46-
}
47-
}
48-
49-
if (options.v2ClientName === "S3") {
50-
for (const clientId of clientIdentifiers) {
51-
const apiMetadata = [
52-
{
53-
apiName: "upload",
54-
apiDescription: "S3 ManagedUpload",
55-
apiSuggestion: "await client.upload(params, options).promise()",
56-
},
57-
{
58-
apiName: "getSignedUrl",
59-
apiDescription: "S3 getSignedUrl",
60-
apiSuggestion: "client.getSignedUrl(apiName, options)",
61-
},
62-
];
63-
for (const { apiName, apiDescription, apiSuggestion } of apiMetadata) {
64-
source
65-
.find(j.CallExpression, getClientApiCallExpression(clientId, apiName))
66-
.forEach((callExpression) => {
67-
const args = callExpression.node.arguments;
68-
69-
if (FUNCTION_TYPE_LIST.includes(args[args.length - 1].type)) {
70-
const comments = callExpression.node.comments || [];
71-
comments.push(
72-
j.commentLine(
73-
` ${apiDescription} with callbacks are not supported in AWS SDK for JavaScript (v3).`
74-
)
75-
);
76-
comments.push(
77-
j.commentLine(
78-
` Please convert to '${apiSuggestion}', and re-run aws-sdk-js-codemod.`
79-
)
80-
);
81-
callExpression.node.comments = comments;
82-
}
83-
});
84-
}
85-
}
2+
import { getClientNamesFromDeepImport } from "../client-names";
3+
import { DYNAMODB } from "../config";
4+
import { getNodesWithDocClientNamedImportFromDeepPath } from "./getNodesWithDocClientNamedImportFromDeepPath";
5+
6+
export const addNotSupportedComments = (j: JSCodeshift, source: Collection<unknown>) => {
7+
const clientNamesFromDeepImport = getClientNamesFromDeepImport(source.toSource());
8+
9+
if (clientNamesFromDeepImport.includes(DYNAMODB)) {
10+
const documentClientDeepNamedImportUnsupportedComments = [
11+
j.commentLine(
12+
" Transformation of DocumentClient named import from deep path is unsupported in aws-sdk-js-codemod."
13+
),
14+
j.commentLine(" Please convert to a default import, and re-run aws-sdk-js-codemod."),
15+
];
16+
17+
getNodesWithDocClientNamedImportFromDeepPath(j, source).forEach((node) => {
18+
const comments = node.value.comments || [];
19+
node.value.comments = [...comments, ...documentClientDeepNamedImportUnsupportedComments];
20+
});
8621
}
8722
};
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import {
2+
Collection,
3+
JSCodeshift,
4+
ObjectProperty,
5+
Property,
6+
VariableDeclaration,
7+
} from "jscodeshift";
8+
import { DOCUMENT_CLIENT, DYNAMODB, OBJECT_PROPERTY_TYPE_LIST } from "../config";
9+
import { hasRequire } from "../modules";
10+
import { getClientDeepImportPath } from "../utils";
11+
12+
export const getNodesWithDocClientNamedImportFromDeepPath = (
13+
j: JSCodeshift,
14+
source: Collection<unknown>
15+
) => {
16+
const deepImportPath = getClientDeepImportPath(DYNAMODB);
17+
if (hasRequire(j, source)) {
18+
return source
19+
.find(j.VariableDeclarator, {
20+
init: {
21+
type: "CallExpression",
22+
callee: { type: "Identifier", name: "require" },
23+
arguments: [{ value: deepImportPath }],
24+
},
25+
})
26+
.filter(
27+
(variableDeclarator) =>
28+
variableDeclarator.value.id.type === "ObjectPattern" &&
29+
(variableDeclarator.value.id.properties || []).some((property) => {
30+
if (!OBJECT_PROPERTY_TYPE_LIST.includes(property.type)) {
31+
return false;
32+
}
33+
const propertyKey = (property as Property | ObjectProperty).key;
34+
return propertyKey.type === "Identifier" && propertyKey.name === DOCUMENT_CLIENT;
35+
})
36+
)
37+
.map(
38+
(variableDeclarator) => variableDeclarator.parentPath.parentPath
39+
) as Collection<VariableDeclaration>;
40+
} else {
41+
return source
42+
.find(j.ImportDeclaration, {
43+
type: "ImportDeclaration",
44+
source: { value: deepImportPath },
45+
})
46+
.filter((importDeclaration) =>
47+
(importDeclaration.value.specifiers || []).some(
48+
(importDeclaration) =>
49+
importDeclaration.type === "ImportSpecifier" &&
50+
importDeclaration.imported.name === DOCUMENT_CLIENT
51+
)
52+
);
53+
}
54+
};

src/transforms/v2-to-v3/apis/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
export * from "./addNotSupportedComments";
2+
export * from "./addNotSupportedClientComments";
23
export * from "./getClientWaiterStates";
34
export * from "./getV3ClientWaiterApiName";
45
export * from "./getS3SignedUrlApiNames";
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
export * from "./getClientMetadataRecord";
22
export * from "./getClientNamesFromGlobal";
33
export * from "./getClientNamesRecord";
4+
export * from "./getClientNamesFromDeepImport";

0 commit comments

Comments
 (0)