Skip to content

Commit d5d5e9d

Browse files
authored
Support transformation of v2 client imports (#48)
1 parent 5018232 commit d5d5e9d

12 files changed

+1294
-9
lines changed

.changeset/hot-maps-walk.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": minor
3+
---
4+
5+
Support transformation of v2 client imports

src/transforms/v2-to-v3/__fixtures__/clients-individual-all.input.ts

Lines changed: 596 additions & 0 deletions
Large diffs are not rendered by default.

src/transforms/v2-to-v3/__fixtures__/clients-individual-all.output.ts

Lines changed: 596 additions & 0 deletions
Large diffs are not rendered by default.

src/transforms/v2-to-v3/transformer.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,12 @@ import { API, FileInfo } from "jscodeshift";
33
import {
44
addV3ClientImport,
55
getClientMetadata,
6+
getV2ClientImportNames,
67
getV2ClientNames,
78
getV2DefaultImportName,
89
removeDefaultImportIfNotUsed,
910
removePromiseCalls,
11+
removeV2ClientImport,
1012
replaceClientCreation,
1113
} from "./utils";
1214

@@ -15,16 +17,18 @@ export default function transformer(file: FileInfo, api: API) {
1517
const source = j(file.source);
1618

1719
const v2DefaultImportName = getV2DefaultImportName(j, source);
18-
if (!v2DefaultImportName) {
20+
const v2ClientImportNames = getV2ClientImportNames(j, source);
21+
if (!v2DefaultImportName && v2ClientImportNames.length === 0) {
1922
return source.toSource();
2023
}
2124

22-
const v2ClientNames = getV2ClientNames(j, source, v2DefaultImportName);
25+
const v2ClientNames = getV2ClientNames(j, source, { v2DefaultImportName, v2ClientImportNames });
2326
const clientMetadata = getClientMetadata(v2ClientNames);
2427

2528
for (const [v2ClientName, v3ClientMetadata] of Object.entries(clientMetadata).reverse()) {
2629
const { v3ClientName, v3ClientPackageName } = v3ClientMetadata;
27-
addV3ClientImport(j, source, { v3ClientName, v3ClientPackageName });
30+
addV3ClientImport(j, source, { v2ClientName, v3ClientName, v3ClientPackageName });
31+
removeV2ClientImport(j, source, v2ClientName);
2832
removePromiseCalls(j, source, { v2DefaultImportName, v2ClientName });
2933
replaceClientCreation(j, source, { v2DefaultImportName, v2ClientName, v3ClientName });
3034
}

src/transforms/v2-to-v3/utils/addV3ClientImport.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
import { Collection, JSCodeshift } from "jscodeshift";
22

33
export interface AddV3ClientImportOptions {
4+
v2ClientName: string;
45
v3ClientName: string;
56
v3ClientPackageName: string;
67
}
78

89
export const addV3ClientImport = (
910
j: JSCodeshift,
1011
source: Collection<any>,
11-
{ v3ClientName, v3ClientPackageName }: AddV3ClientImportOptions
12+
{ v2ClientName, v3ClientName, v3ClientPackageName }: AddV3ClientImportOptions
1213
): void => {
1314
const existingImports = source.find(j.ImportDeclaration, {
1415
source: { value: v3ClientPackageName },
@@ -25,9 +26,14 @@ export const addV3ClientImport = (
2526
return;
2627
}
2728

29+
// Insert after default import if present. If not, insert after client import.
2830
source
2931
.find(j.ImportDeclaration)
30-
.filter((path) => path.value.source.value === "aws-sdk")
32+
.filter(
33+
(path) =>
34+
path.value.source.value === "aws-sdk" ||
35+
path.value.source.value === `aws-sdk/clients/${v2ClientName.toLowerCase()}`
36+
)
3137
.insertAfter(
3238
j.importDeclaration(
3339
[j.importSpecifier(j.identifier(v3ClientName))],
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
1+
export * from "./CLIENT_NAMES";
12
export * from "./CLIENT_NAMES_MAP";
23
export * from "./CLIENT_PACKAGE_NAMES_MAP";
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { Collection, JSCodeshift } from "jscodeshift";
2+
import findImports from "jscodeshift-find-imports";
3+
4+
import { CLIENT_NAMES } from "./config";
5+
6+
export const getV2ClientImportNames = (j: JSCodeshift, source: Collection<any>): string[] => {
7+
const v2ClientImportNames = [];
8+
const { statement } = j.template;
9+
10+
for (const clientName of CLIENT_NAMES) {
11+
const importStatement = `import ${clientName} from 'aws-sdk/clients/${clientName.toLowerCase()}'`;
12+
const imports = findImports(source, statement([importStatement]));
13+
14+
for (const importObj of Object.values(imports)) {
15+
if (importObj.type === "Identifier") v2ClientImportNames.push(importObj.name);
16+
}
17+
}
18+
19+
return v2ClientImportNames;
20+
};

src/transforms/v2-to-v3/utils/getV2ClientNames.ts

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
11
import { Collection, Identifier, JSCodeshift, MemberExpression } from "jscodeshift";
22

3+
export interface GetV2ClientNamesOptions {
4+
v2DefaultImportName: string;
5+
v2ClientImportNames: string[];
6+
}
7+
38
export const getV2ClientNames = (
49
j: JSCodeshift,
510
source: Collection<any>,
6-
v2DefaultImportName: string
7-
): Array<string> =>
8-
source
11+
{ v2DefaultImportName, v2ClientImportNames }: GetV2ClientNamesOptions
12+
): Array<string> => {
13+
const v2ClientNamesFromDefaultImport = source
914
.find(j.NewExpression, {
1015
callee: {
1116
type: "MemberExpression",
@@ -17,3 +22,11 @@ export const getV2ClientNames = (
1722
.map(
1823
(newExpression) => ((newExpression.callee as MemberExpression).property as Identifier).name
1924
);
25+
26+
// Merge v2ClientNamesFromDefaultImport with v2ClientImportNames with duplicates removed.
27+
return v2ClientNamesFromDefaultImport.concat(
28+
v2ClientImportNames.filter(
29+
(v2ClientImportName) => v2ClientNamesFromDefaultImport.indexOf(v2ClientImportName) < 0
30+
)
31+
);
32+
};
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
export * from "./addV3ClientImport";
22
export * from "./getClientMetadata";
3+
export * from "./getV2ClientImportNames";
34
export * from "./getV2ClientNames";
45
export * from "./getV2DefaultImportName";
56
export * from "./removeDefaultImportIfNotUsed";
67
export * from "./removePromiseCalls";
8+
export * from "./removeV2ClientImport";
79
export * from "./replaceClientCreation";
810
export * from "./types";

src/transforms/v2-to-v3/utils/removeDefaultImportIfNotUsed.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ export const removeDefaultImportIfNotUsed = (
1717
source: { value: "aws-sdk" },
1818
})
1919
.forEach((declerationPath) => {
20-
// Remove default import from ImportDecleration.
20+
// Remove default import from ImportDeclaration.
2121
declerationPath.value.specifiers = declerationPath.value.specifiers.filter(
2222
(specifier) =>
2323
specifier.type !== "ImportDefaultSpecifier" &&

0 commit comments

Comments
 (0)