Skip to content

Commit

Permalink
Replace named imports for Input/Output types (#216)
Browse files Browse the repository at this point in the history
  • Loading branch information
trivikr authored Dec 27, 2022
1 parent 52d8543 commit 222c00c
Show file tree
Hide file tree
Showing 12 changed files with 146 additions and 33 deletions.
5 changes: 5 additions & 0 deletions .changeset/purple-pans-shave.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"aws-sdk-js-codemod": patch
---

Replace named imports for Input/Output types
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import DynamoDB, { ListTablesInput, ListTablesOutput } from "aws-sdk/clients/dynamodb";

const client = new DynamoDB({ region: "us-west-2" });

const listTablesInput: ListTablesInput = { Limit: 10 };
const listTablesOutput: ListTablesOutput = await client
.listTables(listTablesInput)
.promise();
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { DynamoDB, ListTablesCommandInput, ListTablesCommandOutput } from "@aws-sdk/client-dynamodb";

const client = new DynamoDB({ region: "us-west-2" });

const listTablesInput: ListTablesCommandInput = { Limit: 10 };
const listTablesOutput: ListTablesCommandOutput = await client
.listTables(listTablesInput);
8 changes: 4 additions & 4 deletions src/transforms/v2-to-v3/transformer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,10 @@ export default function transformer(file: FileInfo, api: API) {
v3ClientPackageName,
v2DefaultModuleName,
});
removeV2ClientModule(j, source, v2ClientName);
removePromiseCalls(j, source, { v2DefaultModuleName, v2ClientName });
replaceClientCreation(j, source, { v2DefaultModuleName, v2ClientName, v3ClientName });
replaceTSTypeReference(j, source, { v2DefaultModuleName, v2ClientName, v3ClientName });
replaceTSTypeReference(j, source, { v2ClientName, v2DefaultModuleName, v3ClientName });
removeV2ClientModule(j, source, { v2ClientName, v2DefaultModuleName });
removePromiseCalls(j, source, { v2ClientName, v2DefaultModuleName });
replaceClientCreation(j, source, { v2ClientName, v2DefaultModuleName, v3ClientName });
}

removeDefaultModuleIfNotUsed(j, source, v2DefaultModuleName);
Expand Down
4 changes: 4 additions & 0 deletions src/transforms/v2-to-v3/utils/config/constants.ts
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
export const PACKAGE_NAME = "aws-sdk";

// ToDo: Add Request and Response suffixes in future version.
export const V2_CLIENT_INPUT_SUFFIX_LIST = ["Input"];
export const V2_CLIENT_OUTPUT_SUFFIX_LIST = ["Output"];
24 changes: 23 additions & 1 deletion src/transforms/v2-to-v3/utils/get/getV2ClientTypeNames.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,14 @@
import { Collection, Identifier, JSCodeshift, TSQualifiedName, TSTypeReference } from "jscodeshift";
import {
Collection,
Identifier,
ImportDeclaration,
ImportSpecifier,
JSCodeshift,
TSQualifiedName,
TSTypeReference,
} from "jscodeshift";

import { getV2ServiceModulePath } from "./getV2ServiceModulePath";

export interface GetV2ClientTypeNamesOptions {
v2ClientName: string;
Expand Down Expand Up @@ -28,6 +38,11 @@ export const getV2ClientTypeNames = (
},
} as TSTypeReference;

const v2ClientTypeFromNamedImport = {
type: "ImportDeclaration",
source: { value: getV2ServiceModulePath(v2ClientName) },
} as ImportDeclaration;

return [
...source
.find(j.TSTypeReference, v2DefaultTypeName)
Expand All @@ -37,5 +52,12 @@ export const getV2ClientTypeNames = (
.find(j.TSTypeReference, v2ClientTypeName)
.nodes()
.map((node) => getRightIdentifierName(node)),
...source
.find(j.ImportDeclaration, v2ClientTypeFromNamedImport)
.nodes()
.map((node) => node.specifiers)
.flat()
.filter((node) => (node as ImportSpecifier).type === "ImportSpecifier")
.map((node) => ((node as ImportSpecifier).local as Identifier).name),
];
};
13 changes: 0 additions & 13 deletions src/transforms/v2-to-v3/utils/get/getV3ClientType.ts

This file was deleted.

14 changes: 10 additions & 4 deletions src/transforms/v2-to-v3/utils/get/getV3ClientTypeName.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
import { V2_CLIENT_INPUT_SUFFIX_LIST, V2_CLIENT_OUTPUT_SUFFIX_LIST } from "../config";

export const getV3ClientTypeName = (v2ClientTypeName: string) => {
if (v2ClientTypeName.endsWith("Input")) {
return v2ClientTypeName.replace(/Input$/, "CommandInput");
for (const inputSuffix of V2_CLIENT_INPUT_SUFFIX_LIST) {
if (v2ClientTypeName.endsWith(inputSuffix)) {
return v2ClientTypeName.replace(new RegExp(`${inputSuffix}$`), "CommandInput");
}
}

if (v2ClientTypeName.endsWith("Output")) {
return v2ClientTypeName.replace(/Output$/, "CommandOutput");
for (const outputSuffix of V2_CLIENT_OUTPUT_SUFFIX_LIST) {
if (v2ClientTypeName.endsWith(outputSuffix)) {
return v2ClientTypeName.replace(new RegExp(`${outputSuffix}$`), "CommandOutput");
}
}

return undefined;
Expand Down
3 changes: 2 additions & 1 deletion src/transforms/v2-to-v3/utils/get/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ export * from "./getRequireVariableDeclaration";
export * from "./getV2ClientIdentifiers";
export * from "./getV2ClientIdThisExpressions";
export * from "./getV2ClientNames";
export * from "./getV2ClientTypeNames";
export * from "./getV2DefaultModuleName";
export * from "./getV2ServiceModuleNames";
export * from "./getV2ServiceModulePath";
export * from "./getV3ClientType";
export * from "./getV3ClientTypeName";
export * from "./getV3ClientTypeNames";
6 changes: 6 additions & 0 deletions src/transforms/v2-to-v3/utils/isV2ClientInputOutputType.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { V2_CLIENT_INPUT_SUFFIX_LIST, V2_CLIENT_OUTPUT_SUFFIX_LIST } from "./config";

export const isV2ClientInputOutputType = (v2ClientTypeName: string) =>
[...V2_CLIENT_INPUT_SUFFIX_LIST, ...V2_CLIENT_OUTPUT_SUFFIX_LIST].some((suffix) =>
v2ClientTypeName.endsWith(suffix)
);
35 changes: 29 additions & 6 deletions src/transforms/v2-to-v3/utils/remove/removeV2ClientModule.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,43 @@
import { Collection, JSCodeshift } from "jscodeshift";

import { containsRequire } from "../containsRequire";
import { getV2ServiceModulePath } from "../get";
import { getV2ClientTypeNames, getV2ServiceModulePath } from "../get";
import { isV2ClientInputOutputType } from "../isV2ClientInputOutputType";
import { removeImportIdentifierName } from "./removeImportIdentifierName";
import { removeRequireIdentifierName } from "./removeRequireIdentifierName";

export interface RemoveV2ClientModuleOptions {
v2ClientName: string;
v2DefaultModuleName: string;
}

export const removeV2ClientModule = (
j: JSCodeshift,
source: Collection<unknown>,
v2ClientName: string
{ v2ClientName, v2DefaultModuleName }: RemoveV2ClientModuleOptions
) => {
const literalValue = getV2ServiceModulePath(v2ClientName);
const removeIdentifierNameOptions = {
identifierName: v2ClientName,
literalValue: getV2ServiceModulePath(v2ClientName),
literalValue,
};
return containsRequire(j, source)
? removeRequireIdentifierName(j, source, removeIdentifierNameOptions)
: removeImportIdentifierName(j, source, removeIdentifierNameOptions);

if (containsRequire(j, source)) {
removeRequireIdentifierName(j, source, removeIdentifierNameOptions);
} else {
removeImportIdentifierName(j, source, removeIdentifierNameOptions);

const v2ClientTypeNames = getV2ClientTypeNames(j, source, {
v2ClientName,
v2DefaultModuleName,
});
for (const v2ClientTypeName of v2ClientTypeNames) {
if (isV2ClientInputOutputType(v2ClientTypeName)) {
removeImportIdentifierName(j, source, {
identifierName: v2ClientTypeName,
literalValue,
});
}
}
}
};
52 changes: 48 additions & 4 deletions src/transforms/v2-to-v3/utils/replace/replaceTSTypeReference.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,42 @@
import { Collection, JSCodeshift } from "jscodeshift";
import {
ASTPath,
Collection,
Identifier,
JSCodeshift,
TSQualifiedName,
TSTypeReference,
} from "jscodeshift";

import { getV3ClientType } from "../get";
import { getV2ClientTypeNames, getV3ClientTypeName } from "../get";
import { isV2ClientInputOutputType } from "../isV2ClientInputOutputType";

export interface ReplaceTypeReferenceOptions {
v2ClientName: string;
v3ClientName: string;
v2DefaultModuleName: string;
}

const getV3ClientTypeFromRightIdentifier = (
j: JSCodeshift,
v2ClientType: ASTPath<TSTypeReference>
) => {
const v3ClientType = getV3ClientTypeName(
((v2ClientType.node.typeName as TSQualifiedName).right as Identifier).name
);
if (!v3ClientType) {
return v2ClientType.node;
}
return j.tsTypeReference(j.identifier(v3ClientType));
};

const getV3ClientTypeFromIdentifier = (j: JSCodeshift, v2ClientType: ASTPath<TSTypeReference>) => {
const v3ClientType = getV3ClientTypeName((v2ClientType.node.typeName as Identifier).name);
if (!v3ClientType) {
return v2ClientType.node;
}
return j.tsTypeReference(j.identifier(v3ClientType));
};

// Replace v2 client type reference with v3 client type reference.
export const replaceTSTypeReference = (
j: JSCodeshift,
Expand Down Expand Up @@ -40,7 +69,7 @@ export const replaceTSTypeReference = (
right: { type: "Identifier" },
},
})
.replaceWith((v2ClientType) => getV3ClientType(j, v2ClientType));
.replaceWith((v2ClientType) => getV3ClientTypeFromRightIdentifier(j, v2ClientType));

// Replace type reference to client created with client module.
source
Expand All @@ -49,5 +78,20 @@ export const replaceTSTypeReference = (
left: { type: "Identifier", name: v2ClientName },
},
})
.replaceWith((v2ClientType) => getV3ClientType(j, v2ClientType));
.replaceWith((v2ClientType) => getV3ClientTypeFromRightIdentifier(j, v2ClientType));

// Replace type reference to client input/output import with named imports.
const v2ClientTypeNames = getV2ClientTypeNames(j, source, {
v2ClientName,
v2DefaultModuleName,
});
for (const v2ClientTypeName of v2ClientTypeNames) {
if (isV2ClientInputOutputType(v2ClientTypeName)) {
source
.find(j.TSTypeReference, {
typeName: { type: "Identifier", name: v2ClientTypeName },
})
.replaceWith((v2ClientType) => getV3ClientTypeFromIdentifier(j, v2ClientType));
}
}
};

0 comments on commit 222c00c

Please sign in to comment.