Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add utility requireModule getImportSpecifiers #781

Merged
merged 17 commits into from
Feb 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/brave-hounds-do.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"aws-sdk-js-codemod": patch
---

Add utility requireModule getImportSpecifiers
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
} from "jscodeshift";
import { DOCUMENT_CLIENT, DYNAMODB, OBJECT_PROPERTY_TYPE_LIST } from "../config";
import { ImportType } from "../modules";
import { getRequireDeclarators } from "../modules/requireModule";
import { getClientDeepImportPath } from "../utils";

export const getNodesWithDocClientNamedImportFromDeepPath = (
Expand All @@ -17,14 +18,7 @@ export const getNodesWithDocClientNamedImportFromDeepPath = (
const deepImportPath = getClientDeepImportPath(DYNAMODB);

if (importType === ImportType.REQUIRE) {
return source
.find(j.VariableDeclarator, {
init: {
type: "CallExpression",
callee: { type: "Identifier", name: "require" },
arguments: [{ value: deepImportPath }],
},
})
return getRequireDeclarators(j, source, deepImportPath)
.filter(
(variableDeclarator) =>
variableDeclarator.value.id.type === "ObjectPattern" &&
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,9 @@
import {
Collection,
Identifier,
JSCodeshift,
ObjectPattern,
ObjectProperty,
Property,
} from "jscodeshift";
import { Collection, JSCodeshift } from "jscodeshift";

import { CLIENT_NAMES, OBJECT_PROPERTY_TYPE_LIST, PACKAGE_NAME } from "../config";
import { getRequireDeclaratorsWithProperty } from "../modules";
import { CLIENT_NAMES, PACKAGE_NAME } from "../config";
import { ImportSpecifierDefault, ImportSpecifierPattern } from "../modules";
import { getImportSpecifiers } from "../modules/requireModule";
import { getClientDeepImportPath } from "../utils";
import { getRequireIds } from "./getRequireIds";

export const getClientNamesRecordFromRequire = (
j: JSCodeshift,
Expand All @@ -19,51 +12,23 @@ export const getClientNamesRecordFromRequire = (
) => {
const clientNamesRecord: Record<string, string> = {};

const idPropertiesFromObjectPattern = getRequireIds(j, source, PACKAGE_NAME)
.filter((id) => id.type === "ObjectPattern")
.map((objectPattern) => (objectPattern as ObjectPattern).properties)
.flat();
const idPropertiesFromObjectPattern = getImportSpecifiers(j, source, PACKAGE_NAME).filter(
(importSpecifier) => typeof importSpecifier === "object"
) as ImportSpecifierPattern[];

for (const idProperty of idPropertiesFromObjectPattern) {
if (!OBJECT_PROPERTY_TYPE_LIST.includes(idProperty.type)) {
continue;
}
const key = (idProperty as Property | ObjectProperty).key;
const value = (idProperty as Property | ObjectProperty).value;
if (key.type !== "Identifier" || value.type !== "Identifier") {
continue;
}
if (CLIENT_NAMES.includes(key.name)) {
clientNamesRecord[key.name] = value.name;
}
}

const declaratorsWithProperty = getRequireDeclaratorsWithProperty(j, source, {
sourceValue: PACKAGE_NAME,
}).nodes();

for (const declaratorWithProperty of declaratorsWithProperty) {
const { id, init } = declaratorWithProperty;
if (
id.type === "Identifier" &&
init != undefined &&
init.type === "MemberExpression" &&
init.property.type === "Identifier"
) {
const clientName = (init.property as Identifier).name;
if (CLIENT_NAMES.includes(clientName)) {
clientNamesRecord[clientName] = (id as Identifier).name;
}
for (const { importedName, localName } of idPropertiesFromObjectPattern) {
if (CLIENT_NAMES.includes(importedName)) {
clientNamesRecord[importedName] = localName || importedName;
}
}

for (const clientName of clientNamesFromDeepImport) {
const deepImportPath = getClientDeepImportPath(clientName);
const idsFromDefaultImport = getRequireIds(j, source, deepImportPath).filter(
(id) => id.type === "Identifier"
);
const idsFromDefaultImport = getImportSpecifiers(j, source, deepImportPath).filter(
(importSpecifier) => typeof importSpecifier === "string"
) as ImportSpecifierDefault[];
if (idsFromDefaultImport.length) {
clientNamesRecord[clientName] = (idsFromDefaultImport[0] as Identifier).name;
clientNamesRecord[clientName] = idsFromDefaultImport[0];
}
}

Expand Down
13 changes: 0 additions & 13 deletions src/transforms/v2-to-v3/client-names/getRequireIds.ts

This file was deleted.

12 changes: 3 additions & 9 deletions src/transforms/v2-to-v3/modules/getGlobalNameFromModule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,14 @@ import { Collection, Identifier, JSCodeshift } from "jscodeshift";
import { PACKAGE_NAME } from "../config";
import { getImportEqualsDeclarationType } from "./getImportEqualsDeclarationType";
import { getImportSpecifiers } from "./getImportSpecifiers";
import { getRequireDeclarators } from "./requireModule";

export const getGlobalNameFromModule = (
j: JSCodeshift,
source: Collection<unknown>
): string | undefined => {
const requireIdentifiers = source
.find(j.VariableDeclarator, {
id: { type: "Identifier" },
init: {
type: "CallExpression",
callee: { type: "Identifier", name: "require" },
arguments: [{ value: PACKAGE_NAME }],
},
})
const requireIdentifiers = getRequireDeclarators(j, source, PACKAGE_NAME)
.filter((declarator) => declarator.value.id.type === "Identifier")
.nodes();

if (requireIdentifiers.length > 0) {
Expand Down
11 changes: 0 additions & 11 deletions src/transforms/v2-to-v3/modules/getImportSpecifier.ts

This file was deleted.

15 changes: 0 additions & 15 deletions src/transforms/v2-to-v3/modules/getRequireDeclarators.ts

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { Collection, JSCodeshift } from "jscodeshift";

import { getRequireDeclarators } from "./getRequireDeclarators";
import { getRequireDeclarators } from "./requireModule";

export interface GetRequireDeclaratorsWithIdentifier {
identifierName: string;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Collection, JSCodeshift, ObjectProperty, Property } from "jscodeshift";

import { OBJECT_PROPERTY_TYPE_LIST } from "../config";
import { getRequireDeclarators } from "./getRequireDeclarators";
import { getRequireDeclarators } from "./requireModule";

export interface GetRequireDeclaratorsWithObjectPattern {
identifierName: string;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Collection, JSCodeshift } from "jscodeshift";
import { Collection, Identifier, JSCodeshift } from "jscodeshift";
import { getRequireDeclarators } from "./requireModule";

export interface GetRequireDeclaratorsWithPropertyOptions {
localName?: string;
Expand All @@ -11,15 +12,19 @@ export const getRequireDeclaratorsWithProperty = (
source: Collection<unknown>,
{ localName, identifierName, sourceValue }: GetRequireDeclaratorsWithPropertyOptions
) =>
source.find(j.VariableDeclarator, {
id: { type: "Identifier", ...(localName && { name: localName }) },
init: {
type: "MemberExpression",
object: {
type: "CallExpression",
callee: { type: "Identifier", name: "require" },
arguments: [{ value: sourceValue }],
},
property: { type: "Identifier", ...(identifierName && { name: identifierName }) },
},
getRequireDeclarators(j, source, sourceValue).filter((varDeclarator) => {
const declaratorId = varDeclarator.value.id;
const declaratorInit = varDeclarator.value.init;

if (declaratorId.type === "Identifier") {
const declaratorIdName = declaratorId.name;
if (declaratorInit!.type === "MemberExpression") {
const importedName = (declaratorInit.property as Identifier).name;
if (localName === declaratorIdName && identifierName === importedName) {
return true;
}
}
}

return false;
});
4 changes: 2 additions & 2 deletions src/transforms/v2-to-v3/modules/getRequireProperty.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { JSCodeshift } from "jscodeshift";

import { ImportSpecifierOptions } from "./types";
import { ImportSpecifierPattern } from "./types";

export const getRequireProperty = (
j: JSCodeshift,
{ importedName, localName }: ImportSpecifierOptions
{ importedName, localName }: ImportSpecifierPattern
) =>
j.objectProperty.from({
key: j.identifier(importedName),
Expand Down
14 changes: 3 additions & 11 deletions src/transforms/v2-to-v3/modules/hasRequire.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,5 @@
import { Collection, JSCodeshift, Literal } from "jscodeshift";
import { PACKAGE_NAME } from "../config";
import { Collection, JSCodeshift } from "jscodeshift";
import { getRequireDeclarators } from "./requireModule";

export const hasRequire = (j: JSCodeshift, source: Collection<unknown>) =>
source
.find(j.CallExpression, {
callee: { type: "Identifier", name: "require" },
})
.filter((callExpression) => {
const { value: sourceValue } = callExpression.value.arguments[0] as Literal;
return typeof sourceValue === "string" && sourceValue.startsWith(PACKAGE_NAME);
})
.size() > 0;
getRequireDeclarators(j, source).size() > 0;
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import {
} from "jscodeshift";

import { OBJECT_PROPERTY_TYPE_LIST, PACKAGE_NAME } from "../../config";
import { getImportSpecifier } from "../getImportSpecifier";
import { getImportSpecifiers } from "../getImportSpecifiers";
import { getRequireProperty } from "../getRequireProperty";
import { importSpecifierCompareFn } from "../importSpecifierCompareFn";
Expand Down Expand Up @@ -101,15 +100,17 @@ export const addNamedModule = (
// Add named import to the first import declaration.
const firstImportDeclSpecifiers = importDeclarations.nodes()[0].specifiers;
if (firstImportDeclSpecifiers) {
firstImportDeclSpecifiers.push(getImportSpecifier(j, { importedName, localName }));
firstImportDeclSpecifiers.push(
j.importSpecifier(j.identifier(importedName), j.identifier(localName))
);
firstImportDeclSpecifiers.sort(importSpecifierCompareFn);
return;
}
}

// Build a new import declaration.
const v3ImportDeclaration = j.importDeclaration(
[getImportSpecifier(j, { importedName, localName })],
[j.importSpecifier(j.identifier(importedName), j.identifier(localName))],
j.stringLiteral(packageName)
);

Expand Down
2 changes: 2 additions & 0 deletions src/transforms/v2-to-v3/modules/removeRequireIdentifier.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ export interface RemoveRequireIdentifierOptions {
sourceValue: string;
}

// ToDo: Write generic utility to remove unused modules
// Similar to https://github.com/aws/aws-sdk-js-codemod/pull/781
export const removeRequireIdentifier = (
j: JSCodeshift,
source: Collection<unknown>,
Expand Down
2 changes: 2 additions & 0 deletions src/transforms/v2-to-v3/modules/removeRequireProperty.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ export interface RemoveRequireObjectPropertyOptions {
sourceValue: string;
}

// ToDo: Write generic utility to remove unused modules
// Similar to https://github.com/aws/aws-sdk-js-codemod/pull/781
export const removeRequireProperty = (
j: JSCodeshift,
source: Collection<unknown>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ import {
} from "jscodeshift";

import { OBJECT_PROPERTY_TYPE_LIST, PACKAGE_NAME, STRING_LITERAL_TYPE_LIST } from "../../config";
import { getRequireDeclarators } from "../getRequireDeclarators";
import { getRequireProperty } from "../getRequireProperty";
import { objectPatternPropertyCompareFn } from "../objectPatternPropertyCompareFn";
import { getRequireDeclarators } from "../requireModule";
import { ModulesOptions } from "../types";

export const addNamedModule = (
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { Collection, Identifier, JSCodeshift, ObjectProperty, Property } from "jscodeshift";
import { OBJECT_PROPERTY_TYPE_LIST } from "../../config";
import { ImportSpecifierPattern, ImportSpecifierType } from "../types";
import { getRequireDeclarators } from "./getRequireDeclarators";

const getImportSpecifiersFromObjectPattern = (properties: (Property | ObjectProperty)[]) => {
const importSpecifiers = new Set<ImportSpecifierPattern>();

for (const property of properties) {
if (!OBJECT_PROPERTY_TYPE_LIST.includes(property.type)) {
continue;
}
const objectProperty = property as Property | ObjectProperty;
const key = objectProperty.key;
const value = objectProperty.value;
if (key.type === "Identifier" && value.type === "Identifier") {
importSpecifiers.add({
importedName: key.name,
localName: value.name,
});
}
}

return Array.from(importSpecifiers);
};

export const getImportSpecifiers = (
j: JSCodeshift,
source: Collection<unknown>,
path?: string
): ImportSpecifierType[] => {
const importSpecifiers = new Set<ImportSpecifierType>();

for (const varDeclarator of getRequireDeclarators(j, source, path).nodes()) {
const declaratorId = varDeclarator.id;
const declaratorInit = varDeclarator.init;

if (declaratorId.type === "Identifier") {
const declaratorIdName = declaratorId.name;
if (declaratorInit!.type === "MemberExpression") {
importSpecifiers.add({
importedName: (declaratorInit.property as Identifier).name,
localName: declaratorIdName,
});
} else {
importSpecifiers.add(declaratorIdName);
}
}

if (declaratorId.type === "ObjectPattern") {
if (declaratorInit!.type !== "CallExpression") {
continue;
}
const properties = declaratorId.properties as (Property | ObjectProperty)[];
for (const importSpecifier of getImportSpecifiersFromObjectPattern(properties)) {
importSpecifiers.add(importSpecifier);
}
}
}

return Array.from(importSpecifiers);
};
Loading