Skip to content

Commit

Permalink
Support ImportEqualsDeclaration (#283)
Browse files Browse the repository at this point in the history
  • Loading branch information
trivikr committed Jan 3, 2023
1 parent d16d0da commit dc417b9
Show file tree
Hide file tree
Showing 22 changed files with 319 additions and 3 deletions.
5 changes: 5 additions & 0 deletions .changeset/short-boats-retire.md
@@ -0,0 +1,5 @@
---
"aws-sdk-js-codemod": patch
---

Add support for ImportEqualsDeclaration
11 changes: 11 additions & 0 deletions scripts/generateNewClientTests/getGlobalImportEqualsInput.ts
@@ -0,0 +1,11 @@
import { CLIENTS_TO_TEST } from "./config";
import { getV2ClientsNewExpressionCode } from "./getV2ClientsNewExpressionCode";

export const getGlobalImportEqualsInput = (codegenComment: string) => {
let globalImportEqualsInputContent = `${codegenComment}\n`;

globalImportEqualsInputContent += `import AWS = require("aws-sdk");\n\n`;
globalImportEqualsInputContent += getV2ClientsNewExpressionCode(CLIENTS_TO_TEST, `AWS.`);

return globalImportEqualsInputContent;
};
29 changes: 29 additions & 0 deletions scripts/generateNewClientTests/getGlobalImportEqualsOutput.ts
@@ -0,0 +1,29 @@
import { CLIENT_NAMES_MAP, CLIENT_PACKAGE_NAMES_MAP } from "../../src/transforms/v2-to-v3/config";
import { getV3ClientDefaultLocalName } from "../../src/transforms/v2-to-v3/utils";
import { CLIENTS_TO_TEST } from "./config";
import { getClientNamesSortedByPackageName } from "./getClientNamesSortedByPackageName";
import { getV3ClientsNewExpressionCode } from "./getV3ClientsNewExpressionCode";

export const getGlobalImportEqualsOutput = (codegenComment: string) => {
let globalImportEqualsOutputContent = `${codegenComment};\n`;

const sortedClientNames = getClientNamesSortedByPackageName(CLIENTS_TO_TEST);

for (const v2ClientName of sortedClientNames) {
const v3ClientDefaultLocalName = getV3ClientDefaultLocalName(v2ClientName);
const v3ClientPackageName = `@aws-sdk/${CLIENT_PACKAGE_NAMES_MAP[v2ClientName]}`;
globalImportEqualsOutputContent += `import ${v3ClientDefaultLocalName} = require("${v3ClientPackageName}");\n\n`;

const v3ClientName = CLIENT_NAMES_MAP[v2ClientName];
const v3ObjectPattern =
v3ClientName === v2ClientName ? v3ClientName : `${v3ClientName}: ${v2ClientName}`;
globalImportEqualsOutputContent +=
`const {\n` +
` ${v3ObjectPattern}\n` +
`} = ${getV3ClientDefaultLocalName(v2ClientName)};\n\n`;
}

globalImportEqualsOutputContent += getV3ClientsNewExpressionCode(CLIENTS_TO_TEST);

return globalImportEqualsOutputContent;
};
13 changes: 13 additions & 0 deletions scripts/generateNewClientTests/getServiceImportEqualsInput.ts
@@ -0,0 +1,13 @@
import { CLIENTS_TO_TEST } from "./config";
import { getV2ClientsNewExpressionCode } from "./getV2ClientsNewExpressionCode";

export const getServiceImportEqualsInput = (codegenComment: string) => {
let serviceImportEqualsInputContent = `${codegenComment}\n`;

for (const clientName of CLIENTS_TO_TEST) {
serviceImportEqualsInputContent += `import ${clientName} = require("aws-sdk/clients/${clientName.toLowerCase()}");\n`;
}
serviceImportEqualsInputContent += getV2ClientsNewExpressionCode(CLIENTS_TO_TEST);

return serviceImportEqualsInputContent;
};
26 changes: 26 additions & 0 deletions scripts/generateNewClientTests/getServiceImportEqualsOutput.ts
@@ -0,0 +1,26 @@
import { CLIENT_NAMES_MAP, CLIENT_PACKAGE_NAMES_MAP } from "../../src/transforms/v2-to-v3/config";
import { getV3ClientDefaultLocalName } from "../../src/transforms/v2-to-v3/utils";
import { CLIENTS_TO_TEST } from "./config";
import { getV3ClientsNewExpressionCode } from "./getV3ClientsNewExpressionCode";

export const getServiceImportEqualsOutput = (codegenComment: string) => {
let serviceImportEqualsOutputContent = `${codegenComment};\n`;

for (const v2ClientName of CLIENTS_TO_TEST) {
const v3ClientDefaultLocalName = getV3ClientDefaultLocalName(v2ClientName);
const v3ClientPackageName = `@aws-sdk/${CLIENT_PACKAGE_NAMES_MAP[v2ClientName]}`;
serviceImportEqualsOutputContent += `import ${v3ClientDefaultLocalName} = require("${v3ClientPackageName}");\n\n`;

const v3ClientName = CLIENT_NAMES_MAP[v2ClientName];
const v3ObjectPattern =
v3ClientName === v2ClientName ? v3ClientName : `${v3ClientName}: ${v2ClientName}`;
serviceImportEqualsOutputContent +=
`const {\n` +
` ${v3ObjectPattern}\n` +
`} = ${getV3ClientDefaultLocalName(v2ClientName)};\n\n`;
}

serviceImportEqualsOutputContent += getV3ClientsNewExpressionCode(CLIENTS_TO_TEST);

return serviceImportEqualsOutputContent;
};
8 changes: 8 additions & 0 deletions scripts/generateNewClientTests/index.ts
Expand Up @@ -3,12 +3,16 @@
import { writeFile } from "fs/promises";
import { join } from "path";

import { getGlobalImportEqualsInput } from "./getGlobalImportEqualsInput";
import { getGlobalImportEqualsOutput } from "./getGlobalImportEqualsOutput";
import { getGlobalImportInput } from "./getGlobalImportInput";
import { getGlobalImportOutput } from "./getGlobalImportOutput";
import { getGlobalRequireInput } from "./getGlobalRequireInput";
import { getGlobalRequireOutput } from "./getGlobalRequireOutput";
import { getServiceImportDeepInput } from "./getServiceImportDeepInput";
import { getServiceImportDeepOutput } from "./getServiceImportDeepOutput";
import { getServiceImportEqualsInput } from "./getServiceImportEqualsInput";
import { getServiceImportEqualsOutput } from "./getServiceImportEqualsOutput";
import { getServiceImportInput } from "./getServiceImportInput";
import { getServiceImportOutput } from "./getServiceImportOutput";
import { getServiceRequireDeepInput } from "./getServiceRequireDeepInput";
Expand All @@ -30,10 +34,14 @@ const newClientTestsPath = join(__dirname, "..", "..", newClientsTestsFolder);
for (const [fileName, getFileContent] of [
["global-import.input.js", getGlobalImportInput],
["global-import.output.js", getGlobalImportOutput],
["global-import-equals.input.ts", getGlobalImportEqualsInput],
["global-import-equals.output.ts", getGlobalImportEqualsOutput],
["global-require.input.js", getGlobalRequireInput],
["global-require.output.js", getGlobalRequireOutput],
["service-import.input.js", getServiceImportInput],
["service-import.output.js", getServiceImportOutput],
["service-import-equals.input.ts", getServiceImportEqualsInput],
["service-import-equals.output.ts", getServiceImportEqualsOutput],
["service-import-deep.input.js", getServiceImportDeepInput],
["service-import-deep.output.js", getServiceImportDeepOutput],
["service-require.input.js", getServiceRequireInput],
Expand Down
@@ -0,0 +1,8 @@
// This file is generated by scripts/generateNewClientTests/index.ts
// Do not edit this file directly. Instead, edit the script and run it to regenerate this file.
"use strict";
import AWS = require("aws-sdk");

new AWS.ACM();
new AWS.AccessAnalyzer();
new AWS.Discovery();
@@ -0,0 +1,24 @@
// This file is generated by scripts/generateNewClientTests/index.ts
// Do not edit this file directly. Instead, edit the script and run it to regenerate this file.
"use strict";;
import AWS_AccessAnalyzer = require("@aws-sdk/client-accessanalyzer");

const {
AccessAnalyzer
} = AWS_AccessAnalyzer;

import AWS_ACM = require("@aws-sdk/client-acm");

const {
ACM
} = AWS_ACM;

import AWS_Discovery = require("@aws-sdk/client-application-discovery-service");

const {
ApplicationDiscoveryService: Discovery
} = AWS_Discovery;

new ACM();
new AccessAnalyzer();
new Discovery();
@@ -0,0 +1,9 @@
// This file is generated by scripts/generateNewClientTests/index.ts
// Do not edit this file directly. Instead, edit the script and run it to regenerate this file.
"use strict";
import ACM = require("aws-sdk/clients/acm");
import AccessAnalyzer = require("aws-sdk/clients/accessanalyzer");
import Discovery = require("aws-sdk/clients/discovery");
new ACM();
new AccessAnalyzer();
new Discovery();
@@ -0,0 +1,24 @@
// This file is generated by scripts/generateNewClientTests/index.ts
// Do not edit this file directly. Instead, edit the script and run it to regenerate this file.
"use strict";;
import AWS_ACM = require("@aws-sdk/client-acm");

const {
ACM
} = AWS_ACM;

import AWS_AccessAnalyzer = require("@aws-sdk/client-accessanalyzer");

const {
AccessAnalyzer
} = AWS_AccessAnalyzer;

import AWS_Discovery = require("@aws-sdk/client-application-discovery-service");

const {
ApplicationDiscoveryService: Discovery
} = AWS_Discovery;

new ACM();
new AccessAnalyzer();
new Discovery();
@@ -1,6 +1,7 @@
import { Collection, Identifier, ImportSpecifier, JSCodeshift } from "jscodeshift";

import { CLIENT_NAMES, PACKAGE_NAME } from "../config";
import { getImportEqualsDeclaration } from "../modules";
import { getV2ServiceModulePath } from "../utils";
import { getImportSpecifiers } from "./getImportSpecifiers";

Expand All @@ -25,13 +26,22 @@ export const getV2ClientNamesRecordFromImport = (

for (const clientName of v2ClientNamesWithServiceModule) {
const deepImportPath = getV2ServiceModulePath(clientName);

const specifiersFromDeepImport = getImportSpecifiers(j, source, deepImportPath).filter(
(specifier) =>
["ImportDefaultSpecifier", "ImportNamespaceSpecifier"].includes(specifier?.type as string)
);
if (specifiersFromDeepImport.length > 0) {
v2ClientNamesRecord[clientName] = (specifiersFromDeepImport[0]?.local as Identifier).name;
}

const identifiersFromImportEquals = source.find(
j.TSImportEqualsDeclaration,
getImportEqualsDeclaration(deepImportPath)
);
if (identifiersFromImportEquals.length > 0) {
v2ClientNamesRecord[clientName] = identifiersFromImportEquals.nodes()[0]?.id.name;
}
}

return v2ClientNamesRecord;
Expand Down
80 changes: 80 additions & 0 deletions src/transforms/v2-to-v3/modules/addV3ClientImportEquals.ts
@@ -0,0 +1,80 @@
import { Collection, JSCodeshift, TSExternalModuleReference } from "jscodeshift";

import { PACKAGE_NAME } from "../config";
import { getV2ServiceModulePath, getV3ClientDefaultLocalName } from "../utils";
import { getImportEqualsDeclaration } from "./getImportEqualsDeclaration";
import { V3ClientModulesOptions } from "./types";

export const addV3ClientImportEquals = (
j: JSCodeshift,
source: Collection<unknown>,
{
v2ClientLocalName,
v2ClientName,
v2GlobalName,
v3ClientName,
v3ClientPackageName,
}: V3ClientModulesOptions
): void => {
const v3ClientDefaultLocalName = getV3ClientDefaultLocalName(v2ClientLocalName);
const existingImportEquals = source.find(
j.TSImportEqualsDeclaration,
getImportEqualsDeclaration(v3ClientPackageName)
);

if (existingImportEquals.size()) {
if (
existingImportEquals
.nodes()
.some(
(importEqualsDeclaration) => importEqualsDeclaration.id.name === v3ClientDefaultLocalName
)
) {
return;
}
}

// Insert after global, or service import equals.
source
.find(j.TSImportEqualsDeclaration, getImportEqualsDeclaration())
.filter((importEqualsDeclaration) => {
const identifierName = importEqualsDeclaration.value.id.name;
const importEqualsModuleRef = importEqualsDeclaration.value
.moduleReference as TSExternalModuleReference;
const expressionValue = importEqualsModuleRef.expression.value;

if (expressionValue === PACKAGE_NAME && identifierName === v2GlobalName) {
return true;
}

if (
expressionValue === getV2ServiceModulePath(v2ClientName) &&
identifierName === v2ClientLocalName
) {
return true;
}

return false;
})
.at(0)
.insertAfter(
j.variableDeclaration("const", [
j.variableDeclarator(
j.objectPattern([
j.objectProperty.from({
key: j.identifier(v3ClientName),
value: j.identifier(v2ClientLocalName),
shorthand: true,
}),
]),
j.identifier(v3ClientDefaultLocalName)
),
])
)
.insertAfter(
j.tsImportEqualsDeclaration(
j.identifier(v3ClientDefaultLocalName),
j.tsExternalModuleReference(j.stringLiteral(v3ClientPackageName))
)
);
};
7 changes: 7 additions & 0 deletions src/transforms/v2-to-v3/modules/addV3ClientImports.ts
Expand Up @@ -2,14 +2,21 @@ import { Collection, JSCodeshift } from "jscodeshift";

import { getV3ClientTypeNames } from "../ts-type";
import { addV3ClientDefaultImport } from "./addV3ClientDefaultImport";
import { addV3ClientImportEquals } from "./addV3ClientImportEquals";
import { addV3ClientNamedImport } from "./addV3ClientNamedImport";
import { hasImportEquals } from "./hasImportEquals";
import { V3ClientModulesOptions } from "./types";

export const addV3ClientImports = (
j: JSCodeshift,
source: Collection<unknown>,
options: V3ClientModulesOptions
): void => {
if (hasImportEquals(j, source)) {
addV3ClientImportEquals(j, source, options);
return;
}

addV3ClientNamedImport(j, source, options);

const { v2ClientName, v2GlobalName } = options;
Expand Down
10 changes: 10 additions & 0 deletions src/transforms/v2-to-v3/modules/getImportEqualsDeclaration.ts
@@ -0,0 +1,10 @@
import { TSImportEqualsDeclaration } from "jscodeshift";

export const getImportEqualsDeclaration = (expressionValue?: string) =>
({
type: "TSImportEqualsDeclaration",
moduleReference: {
type: "TSExternalModuleReference",
expression: { type: "StringLiteral", ...(expressionValue && { value: expressionValue }) },
},
} as TSImportEqualsDeclaration);
10 changes: 10 additions & 0 deletions src/transforms/v2-to-v3/modules/getV2GlobalNameFromModule.ts
@@ -1,6 +1,7 @@
import { Collection, Identifier, JSCodeshift } from "jscodeshift";

import { PACKAGE_NAME } from "../config";
import { getImportEqualsDeclaration } from "./getImportEqualsDeclaration";
import { hasRequire } from "./hasRequire";

export const getV2GlobalNameFromModule = (
Expand Down Expand Up @@ -40,5 +41,14 @@ export const getV2GlobalNameFromModule = (
return (importDefaultNamespaceSpecifiers[0]?.local as Identifier).name;
}

const importEqualsDeclarations = source.find(
j.TSImportEqualsDeclaration,
getImportEqualsDeclaration(PACKAGE_NAME)
);

if (importEqualsDeclarations.length > 0) {
return importEqualsDeclarations.nodes()[0]?.id?.name;
}

return undefined;
};
6 changes: 6 additions & 0 deletions src/transforms/v2-to-v3/modules/hasImportEquals.ts
@@ -0,0 +1,6 @@
import { Collection, JSCodeshift } from "jscodeshift";

import { getImportEqualsDeclaration } from "./getImportEqualsDeclaration";

export const hasImportEquals = (j: JSCodeshift, source: Collection<unknown>) =>
source.find(j.TSImportEqualsDeclaration, getImportEqualsDeclaration()).size() > 0;
1 change: 1 addition & 0 deletions src/transforms/v2-to-v3/modules/index.ts
@@ -1,4 +1,5 @@
export * from "./addV3ClientModules";
export * from "./getImportEqualsDeclaration";
export * from "./getV2GlobalNameFromModule";
export * from "./hasRequire";
export * from "./removeV2ClientModule";
Expand Down
@@ -0,0 +1,23 @@
import { Collection, JSCodeshift } from "jscodeshift";

export interface RemoveImportEqualsIdentifierNameOptions {
localName: string;
sourceValue: string;
}

export const removeImportEqualsIdentifierName = (
j: JSCodeshift,
source: Collection<unknown>,
{ localName, sourceValue }: RemoveImportEqualsIdentifierNameOptions
) => {
source
.find(j.TSImportEqualsDeclaration, {
type: "TSImportEqualsDeclaration",
id: { name: localName },
moduleReference: {
type: "TSExternalModuleReference",
expression: { type: "StringLiteral", value: sourceValue },
},
})
.remove();
};

0 comments on commit dc417b9

Please sign in to comment.