Giter VIP home page Giter VIP logo

aws-sdk-js-codemod's Introduction

aws-sdk-js-codemod

This repository contains a collection of codemod scripts for use with JSCodeshift that help update AWS SDK for JavaScript APIs.

The aws-sdk-js-codemod CLI is a lightweight wrapper over jscodeshift. It processes --help, --version and --transform options before passing them downstream.

You can provide names of the custom transforms instead of a local path or url:

 v2-to-v3  Converts AWS SDK for JavaScript APIs in a Javascript/TypeScript
           codebase from version 2 (v2) to version 3 (v3).

Please review the code change thoroughly for required functionality before deploying it to production. If the transformation is not complete or is incorrect, please report the issue on GitHub.

Prerequisites

To use aws-sdk-js-codemod, please install Node.js.

Usage

  • Optionally execute dry-run for the transform, and print transformed files on stdout:
    npx aws-sdk-js-codemod@latest --dry --print -t v2-to-v3 PATH...
  • Run transform, and make changes to files:
    npx aws-sdk-js-codemod@latest -t v2-to-v3 PATH...

Example

$ cat example.ts
import AWS from "aws-sdk";
const client = new AWS.DynamoDB();
const response = await client.listTables({}).promise();

$ npx aws-sdk-js-codemod@latest -t v2-to-v3 example.ts

$ cat example.ts
import { DynamoDB } from "@aws-sdk/client-dynamodb";
const client = new DynamoDB();
const response = await client.listTables({});

For a summary of supported transformations, check TRANSFORMATIONS.md.

License

This library is licensed under the MIT-0 License. See the LICENSE file.

aws-sdk-js-codemod's People

Contributors

github-actions[bot] avatar renovate[bot] avatar trivikr avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

aws-sdk-js-codemod's Issues

[Feature]: Add named import/require for module only if a client is created

Self-service

  • I'd be willing to implement this feature

Input code

import { S3 } from "aws-sdk";
const testTags: S3.Tag[] = [{ Key: "abc", Value: "value" }];

Expected Output

Current Output

import AWS_S3, { S3 } from "@aws-sdk/client-s3";
const testTags: AWS_S3.Tag[] = [{ Key: "abc", Value: "value" }];

Expected Output

import AWS_S3 from "@aws-sdk/client-s3";
const testTags: AWS_S3.Tag[] = [{ Key: "abc", Value: "value" }];

Additional context

Refs: #225 (comment)

The transformer.spec.ts tests are run in series which takes time

Is your feature request related to a problem? Please describe.

The test file which takes most time is transformer.spec.ts, and the test there are run in series.

Tested by adding logs:

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

it.each(testFiles)(`transforms correctly using "%s" data`, async (filePrefix, fileExtension) => {
  console.log("test start:", filePrefix, Date.now());

  // ...

  console.log("test end: ", filePrefix, Date.now());
}

Output:

    test start: api-callback 1671669601287
    test end:  api-callback 1671669601556

    test start: api-promise-service-import 1671669601560
    test end:  api-promise-service-import 1671669601842

    test start: api-promise-service-import 1671669601845

Describe the solution you'd like

Check if jest allows running tests from a single file in parallel, and implement it

Describe alternatives you've considered

N/A

[Bug]: aws-sdk-js-codemod doesn't modify file when parser=ts is passed

Self-service

  • I'd be willing to implement a fix

Describe the bug

aws-sdk-js-codemod doesn't modify file when parser=ts is passed

Template name

v2-to-v3

Input code

// example.ts
import AWS from "aws-sdk";

const client = new AWS.DynamoDB();

Observed failure

No failure, but there's no modification when parser=ts is passed.

$ aws-sdk-js-codemod -t v2-to-v3 example.ts --parser=ts
Processing 1 files... 
Spawning 1 workers...
Sending 1 files to free worker...
All done. 
Results: 
0 errors
1 unmodified
0 skipped
0 ok
Time elapsed: 0.926seconds

Expected output

import { DynamoDB } from "@aws-sdk/client-dynamodb";

const client = new DynamoDB();

Environment

aws-sdk-js-codemod: 0.4.2

jscodeshift: 0.13.1
 - babel: 7.17.5
 - babylon: 7.17.3
 - flow: 0.172.0
 - recast: 0.20.5

Additional context

This is likely an issue with jscodeshift. This was noticed when an attempt to pass parser=ts was made in tests in #83

[Feature]: Support transformation of API call when client is created outside of file

Self-service

  • I'd be willing to implement this feature

Input code

import AWS from "aws-sdk";

export const listTables = (client: AWS.DynamoDB) => client.listTables().promise();

Expected Output

import { DynamoDB } from "@aws-sdk/client-dynamodb";

export const listTables = (client: DynamoDB) => client.listTables();

Additional context

No response

[Bug]: Error Removal of .promise() not implemented for VariableDeclarator

Self-service

  • I'd be willing to implement a fix

Describe the bug

Error Removal of .promise() not implemented for VariableDeclarator

Template name

v2-to-v3

Input code

import AWS from "aws-sdk";

const client = new AWS.DynamoDB();

const listTablesPromise = client.listTables().promise();
listTablesPromise.then((data) => console.log(data))
  .catch((err) => console.log(err, err.stack));

Observed failure

Removal of .promise() not implemented for VariableDeclarator

      55 |               break;
      56 |             default:
    > 57 |               throw new Error(
         |                     ^
      58 |                 `Removal of .promise() not implemented for ${callExpressionPath.parentPath.value.type}`
      59 |               );
      60 |           }

Expected output

import { DynamoDB } from "@aws-sdk/client-dynamodb";

const client = new DynamoDB();

const listTablesPromise = client.listTables();
listTablesPromise
  .then((data) => console.log(data))
  .catch((err) => console.log(err, err.stack));

Environment

aws-sdk-js-codemod: 0.2.1

jscodeshift: 0.13.1
 - babel: 7.17.5
 - babylon: 7.17.3
 - flow: 0.172.0
 - recast: 0.20.5

Additional context

No response

[Bug]: Passing `--bail` option to test does not exit on first test failure

Describe the bug

Passing --bail option to test does not bail out on test failure

Steps to reproduce

# Add code to fail test
$ sed -i "1s|^|console.log\('foobar'\);\n|" src/transforms/v2-to-v3/__fixtures__/api-await.input.ts

$ git diff
diff --git a/src/transforms/v2-to-v3/__fixtures__/api-await.input.ts b/src/transforms/v2-to-v3/__fixtures__/api-await.input.ts
index 6ba6791..377fecf 100644
--- a/src/transforms/v2-to-v3/__fixtures__/api-await.input.ts
+++ b/src/transforms/v2-to-v3/__fixtures__/api-await.input.ts
@@ -1,3 +1,4 @@
+console.log('foobar');
 import AWS from "aws-sdk";
 
 const client = new AWS.DynamoDB();

Observed behavior

The tests fail after ~600 tests have run within 4s, but jest does not bail out.

$ yarn test --bail
 ...
Test Suites: 1 failed, 3 passed, 4 total
Tests:       2 failed, 648 passed, 650 total
Snapshots:   0 total
Time:        73.413 s

Expected behavior

Jest to bail out when first test fails with error message.

Additional context

Recommended in #157 (comment)

[Feature]: Automatically pass parser as `ts` whey codemod is run on TypeScript code

Is your feature request related to a problem? Please describe.

When user wants to perform transform on TypeScript code, they sometimes get errors and explicitly pass parser as ts

For example, consider the following code which only uses DynamoDB type:

// example.ts
import AWS from "aws-sdk";

export const listTables = (client: AWS.DynamoDB) =>
  client.listTables().promise();

The default transform without parser Transformation error

$ npx aws-sdk-js-codemod -t v2-to-v3 example.ts
Processing 1 files... 
Spawning 1 workers...
Sending 1 files to free worker...
 ERR example.ts Transformation error (Unexpected token, expected "," (3:33))
SyntaxError: Unexpected token, expected "," (3:33)
    at instantiate (/Users/trivikr/.fnm/node-versions/v16.18.1/installation/lib/node_modules/jscodeshift/node_modules/@babel/parser/src/parse-error/credentials.ts:62:21)
    at toParseError (/Users/trivikr/.fnm/node-versions/v16.18.1/installation/lib/node_modules/jscodeshift/node_modules/@babel/parser/src/parse-error.ts:60:12)
    at JSXParserMixin.raise (/Users/trivikr/.fnm/node-versions/v16.18.1/installation/lib/node_modules/jscodeshift/node_modules/@babel/parser/src/tokenizer/index.ts:1474:19)
    at JSXParserMixin.unexpected (/Users/trivikr/.fnm/node-versions/v16.18.1/installation/lib/node_modules/jscodeshift/node_modules/@babel/parser/src/tokenizer/index.ts:1520:16)
    at JSXParserMixin.expect (/Users/trivikr/.fnm/node-versions/v16.18.1/installation/lib/node_modules/jscodeshift/node_modules/@babel/parser/src/parser/util.ts:149:28)
    at JSXParserMixin.parseParenAndDistinguishExpression (/Users/trivikr/.fnm/node-versions/v16.18.1/installation/lib/node_modules/jscodeshift/node_modules/@babel/parser/src/parser/expression.ts:1752:14)
    at JSXParserMixin.parseExprAtom (/Users/trivikr/.fnm/node-versions/v16.18.1/installation/lib/node_modules/jscodeshift/node_modules/@babel/parser/src/parser/expression.ts:1162:21)
    at JSXParserMixin.parseExprAtom (/Users/trivikr/.fnm/node-versions/v16.18.1/installation/lib/node_modules/jscodeshift/node_modules/@babel/parser/src/plugins/jsx/index.ts:579:22)
    at JSXParserMixin.parseExprSubscripts (/Users/trivikr/.fnm/node-versions/v16.18.1/installation/lib/node_modules/jscodeshift/node_modules/@babel/parser/src/parser/expression.ts:722:23)
    at JSXParserMixin.parseUpdate (/Users/trivikr/.fnm/node-versions/v16.18.1/installation/lib/node_modules/jscodeshift/node_modules/@babel/parser/src/parser/expression.ts:699:21)
All done. 
Results: 
1 errors
0 unmodified
0 skipped
0 ok
Time elapsed: 0.796seconds

The error is not thrown when parser is explicitly set to ts

$ npx aws-sdk-js-codemod -t v2-to-v3 example.ts --parser ts
Processing 1 files... 
Spawning 1 workers...
Sending 1 files to free worker...
All done. 
Results: 
0 errors
0 unmodified
0 skipped
1 ok
Time elapsed: 0.833seconds

Describe the solution you'd like

Explicitly set parser to ts when TypeScript files are passed to the codemod.

Describe alternatives you've considered

N/A

[Bug]: The .promise() calls are not removed if API is called from client import

Self-service

  • I'd be willing to implement a fix

Describe the bug

The .promise() calls are not removed if API is called from client import

Template name

v2-to-v3

Input code

import DynamoDB from "aws-sdk/clients/dynamodb";

const client = new DynamoDB();
const data = await client.listTables().promise();

Observed failure

The .promise() call is note removed.

import { DynamoDB } from "@aws-sdk/client-dynamodb";

const client = new DynamoDB();
const data = await client.listTables().promise();

Expected output

import { DynamoDB } from "@aws-sdk/client-dynamodb";

const client = new DynamoDB();
const data = await client.listTables();

Environment

aws-sdk-js-codemod: 0.4.5

jscodeshift: 0.13.1
 - babel: 7.17.5
 - babylon: 7.17.3
 - flow: 0.172.0
 - recast: 0.20.5

Additional context

No response

Run the names test for clients only once

Is your feature request related to a problem? Please describe.

The new-client tests take too much time to run. The times taken for executions were documented in #252

Describe the solution you'd like

Run the names test for clients only once, say in global-import.

The rest of the tests can only check generic test cases like:

  • Client where LocalName is same as ClientName. e.g. ACM.
  • Client where LocalName is different from ClientName. e.g. Discovery/ApplicationDiscoveryService.
  • Client whose import should come first because of package name. e.g. AccessAnalyzer before ACM.

Describe alternatives you've considered

N/A

[Bug]: Do not introduce v3 import if already present

Self-service

  • I'd be willing to implement a fix

Describe the bug

The v2-to-v3 transform introduces new import even if it's already present.

Template name

v2-to-v3

Input code

import AWS from "aws-sdk";
import { DynamoDB } from "@aws-sdk/client-dynamodb";

const client1 = new AWS.DynamoDB();
const client2 = new DynamoDB();

Observed failure

Not failure, but double import

import { DynamoDB } from "@aws-sdk/client-dynamodb";
import { DynamoDB } from "@aws-sdk/client-dynamodb";

const client1 = new DynamoDB();
const client2 = new DynamoDB();

Expected output

import { DynamoDB } from "@aws-sdk/client-dynamodb";
import { DynamoDB } from "@aws-sdk/client-dynamodb";

const client1 = new DynamoDB();
const client2 = new DynamoDB();

Environment

aws-sdk-js-codemod: 0.1.3

jscodeshift: 0.13.1
 - babel: 7.17.5
 - babylon: 7.17.3
 - flow: 0.172.0
 - recast: 0.20.5

Additional context

No response

[Feature]: Replace named imports for Request/Response types

Self-service

  • I'd be willing to implement this feature

Input code

import AWS from "aws-sdk";

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

const getCallerIdentityInput: AWS.STS.GetCallerIdentityRequest = {};
const getCallerIdentityOutput: AWS.STS.GetCallerIdentityResponse = await client
  .getCallerIdentity(getCallerIdentityInput)
  .promise();

Expected Output

import {
  STS,
  GetCallerIdentityCommandInput,
  GetCallerIdentityCommandOutput,
} from "@aws-sdk/client-sts";

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

const getCallerIdentityInput: GetCallerIdentityCommandInput = {};
const getCallerIdentityOutput: GetCallerIdentityCommandOutput = await client
  .getCallerIdentity(getCallerIdentityInput);

Additional context

The transformation for input/output types with Input/Output suffix was added in #216

[Bug]: The call to `.promise()` is not removed in v3 code

Self-service

  • I'd be willing to implement a fix

Describe the bug

The call to .promise() is not removed in v3 code

Template name

v2-to-v3

Input code

import AWS from "aws-sdk";

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

client
  .listTables({})
  .promise()
  .then((data) => console.log(data))
  .catch((err) => console.log(err, err.stack));

Observed failure

Not an error, but the call to .promise() is not removed from input.

import { DynamoDB } from "@aws-sdk/client-dynamodb";

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

client
  .listTables({})
  .promise()
  .then((data) => console.log(data))
  .catch((err) => console.log(err, err.stack));

Expected output

import { DynamoDB } from "@aws-sdk/client-dynamodb";

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

client
  .listTables({})
  .then((data) => console.log(data))
  .catch((err) => console.log(err, err.stack));

Environment

aws-sdk-js-codemod: 0.1.3

jscodeshift: 0.13.1
 - babel: 7.17.5
 - babylon: 7.17.3
 - flow: 0.172.0
 - recast: 0.20.5

Additional context

No response

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

Awaiting Schedule

These updates are awaiting their schedule. Click on a checkbox to get an update now.

  • chore(deps): lock file maintenance

Detected dependencies

github-actions
.github/workflows/build.yml
.github/workflows/lock.yml
.github/workflows/push.yml
.github/workflows/secrets_scan.yml
.github/workflows/security_scan.yml
npm
package.json

  • Check this box to trigger a request for Renovate to run again on this repository

[Feature]: Replace named imports for Input/Output types

Self-service

  • I'd be willing to implement this feature

Input code

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();

Expected Output

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);

Additional context

Transformation for Input/Output types was added in #209

[Feature]: The transformer tests are not run in parallel

Is your feature request related to a problem? Please describe.

The transformer tests are not run in parallel

The tests start in parallel, but are run in sync

Diff:

-  describe.each(fixtureSubDirs)("%s", (subDir) => {
+  describe.each(["new-client"])("%s", (subDir) => {
     const subDirPath = join(fixtureDir, subDir);
     it.concurrent.each(getTestFileMetadata(subDirPath))(
       `transforms: %s.%s`,
       async (filePrefix, fileExtension) => {
+        const startDate = new Date();
+        console.log(`${filePrefix} start: `, startDate.toTimeString());
+
         const { input, outputCode } = await getTestMetadata(subDirPath, filePrefix, fileExtension);
         runInlineTest(transformer, null, input, outputCode);
+
+        const endDate = new Date();
+        console.log(`${filePrefix} end: ${endDate.toTimeString()}`);
+        console.log(`${filePrefix} test run time: ${endDate.getTime() - startDate.getTime()}ms`);
       }
     );

Output:

    global-import start:  14:25:39 GMT-0800 (Pacific Standard Time)
    global-require start:  14:25:39 GMT-0800 (Pacific Standard Time)
    service-import-deep start:  14:25:39 GMT-0800 (Pacific Standard Time)
    service-import start:  14:25:39 GMT-0800 (Pacific Standard Time)
    service-require-deep start:  14:25:39 GMT-0800 (Pacific Standard Time)

    service-import end: 14:25:51 GMT-0800 (Pacific Standard Time)
    service-import test run time: 11781ms

    service-require start:  14:25:51 GMT-0800 (Pacific Standard Time)

    global-require end: 14:26:04 GMT-0800 (Pacific Standard Time)
    global-require test run time: 24973ms

    service-require-deep end: 14:26:20 GMT-0800 (Pacific Standard Time)
    service-require-deep test run time: 40440ms

    global-import end: 14:26:30 GMT-0800 (Pacific Standard Time)
    global-import test run time: 50777ms

    service-import-deep end: 14:26:41 GMT-0800 (Pacific Standard Time)
    service-import-deep test run time: 62212ms

    service-require end: 14:27:00 GMT-0800 (Pacific Standard Time)
    service-require test run time: 68779ms

This leads to CI taking time. For example, the test step takes 3m https://github.com/awslabs/aws-sdk-js-codemod/actions/runs/3803141886/jobs/6469293363

Describe the solution you'd like

Experiment with Jest code or configuration to run tests in parallel

Describe alternatives you've considered

N/A

Additional Context

$ yarn dlx -q envinfo --preset jest

  System:
    OS: macOS 12.1
    CPU: (8) arm64 Apple M1 Pro
  Binaries:
    Node: 18.12.1 - /private/var/folders/42/54jl1_3x4hz06cf7bc_kzd4h0000gn/T/xfs-6daa84fb/node
    Yarn: 3.3.1 - /private/var/folders/42/54jl1_3x4hz06cf7bc_kzd4h0000gn/T/xfs-6daa84fb/yarn
    npm: 8.19.2 - ~/Library/Caches/fnm_multishells/57062_1672199177403/bin/npm
  npmPackages:
    jest: ^29.3.1 => 29.3.1

Search for service module path on file.source, and run file.source APIs only on present clients

Is your feature request related to a problem? Please describe.

The getV2ClientNamesRecord* functions search for service module path of all clients.

https://github.com/awslabs/aws-sdk-js-codemod/blob/2c8312f84d003a915a3dbafef5e692da544bb0e9/src/transforms/v2-to-v3/utils/get/getV2ClientNamesRecordFromImport.ts#L40-L48

The times taken were logged in #261

Describe the solution you'd like

Search for service module path on file.source, and run file.source APIs only on the clients which are present.

Describe alternatives you've considered

N/A

[Feature]: Remove promise call from request stored in a variable declarator

Self-service

  • I'd be willing to implement this feature

Input code

import AWS from "aws-sdk";

const client = new AWS.DynamoDB();

const listTablesRequest = client.listTables();
listTablesRequest
  .promise()
  .then((data) => console.log(data))
  .catch((err) => console.log(err, err.stack));

Expected Output

import { DynamoDB } from "@aws-sdk/client-dynamodb";

const client = new DynamoDB();

const listTablesRequest = client.listTables();
listTablesRequest
  .then((data) => console.log(data))
  .catch((err) => console.log(err, err.stack));

Additional context

Test added in #184

[Feature]: Support transformation for client star import

Self-service

  • I'd be willing to implement this feature

Input code

import * as DynamoDB from "aws-sdk/clients/dynamodb";

const client = new DynamoDB();

Expected Output

import { DynamoDB } from "@aws-sdk/client-dynamodb";

const client = new DynamoDB();

Additional context

Transformation for v2 client imports was added in #48

[Feature]: destructuring imports

Self-service

  • I'd be willing to implement this feature

Input code

import { Lambda, Sagemaker } from "aws-sdk";
const { S3, EC2 } = require("aws-sdk");

const sagemaker = new SageMaker({});
const lambda = new Lambda({});
const s3 = new S3({});
const ec2 = new EC2({});

Expected Output

import { Lambda } from "@aws-sdk/client-lambda";
import { SageMaker } from "@aws-sdk/client-sagemaker";
const { S3 } = require("@aws-sdk/client-s3");
const { EC2 } = require("@aws-sdk/client-ec2");

const sagemaker = new SageMaker({});
const lambda = new Lambda({});
const s3 = new S3({});
const ec2 = new EC2({});

Additional context

Checkout https://github.com/awslabs/aws-sdk-js-codemod/compare/main...kuhe:aws-sdk-js-codemod:example/imports?expand=1

And run npx jest -t destructure

Improve the test running time for global-import-new-clients and service-import

Is your feature request related to a problem? Please describe.

During benchmarking, the test global-import-new-clients and service-import took the most time, i.e. 16s.
Rest of the tests take ~100ms

Tested by adding logs:

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

it.each(testFiles)(`transforms correctly using "%s" data`, async (filePrefix, fileExtension) => {
  const testStart = Date.now();
  console.log("test start:", filePrefix, testStart);

  // ...

  const testEnd = Date.now();
  console.log("test end: ", filePrefix, testEnd);
  console.log("test duration: ", filePrefix, testEnd - testStart);
}

Output:

test duration:  global-import-new-clients 15979
...
test duration:  service-import 18148

Describe the solution you'd like

Check if the issue is with efficiency of source code, which can be improved.
If not, identify if tests can be run faster.

Describe alternatives you've considered

N/A

Parse through named imports to search for client names instead of vice versa

Is your feature request related to a problem? Please describe.

In getV2ClientNamesRecord* functions, the for loop goes through all client names and checks if any named imports are present.

https://github.com/awslabs/aws-sdk-js-codemod/blob/447398594737bcdf16d781bf7d73693c9de72cf5/src/transforms/v2-to-v3/utils/get/getV2ClientNamesRecordFromImport.ts#L34-L41

The code can parse through the named imports instead, and check if any named import matches the client name

Describe the solution you'd like

Parse through named imports to search for client names.

Describe alternatives you've considered

N/A

[Feature]: Fail early in jest is any of the tests fail

Is your feature request related to a problem? Please describe.

Jest runs all tests (650 at the time of writing), before failing.

$ sed -i "1s|^|console.log('foobar');\n|" src/transforms/v2-to-v3/__fixtures__/api-await.input.ts

$ git diff
diff --git a/src/transforms/v2-to-v3/__fixtures__/api-await.input.ts b/src/transforms/v2-to-v3/__fixtures__/api-await.input.ts
index 6ba6791..377fecf 100644
--- a/src/transforms/v2-to-v3/__fixtures__/api-await.input.ts
+++ b/src/transforms/v2-to-v3/__fixtures__/api-await.input.ts
@@ -1,3 +1,4 @@
+console.log('foobar');
 import AWS from "aws-sdk";
 
 const client = new AWS.DynamoDB();
 
 $ yarn test
 ...
Test Suites: 1 failed, 3 passed, 4 total
Tests:       2 failed, 648 passed, 650 total
Snapshots:   0 total
Time:        57.94 s, estimated 58 s

Describe the solution you'd like

Fail early if any of the test fails. Explore using jest --bail option

Describe alternatives you've considered

N/A

[Bug]: The v2-to-v3 codemod removes Variable Declaration instead of Declarator

Self-service

  • I'd be willing to implement a fix

Describe the bug

The v2-to-v3 codemod removes Variable Declaration instead of Declarator

Template name

v2-to-v3

Input code

const AWS = require("aws-sdk"),
  client = new AWS.DynamoDB();

const response = await client.listTables().promise();

Observed failure

Removes client creation, as it's part of variable declaration which contains require for aws-sdk

const {
  DynamoDB
} = require("@aws-sdk/client-dynamodb");

const response = await client.listTables();

Expected output

const { 
  DynamoDB
} = require("@aws-sdk/client-dynamodb"),
  client = new DynamoDB();

const response = await client.listTables();

Environment

aws-sdk-js-codemod: 0.7.4

jscodeshift: 0.14.0
 - babel: 7.20.7
 - babylon: 7.20.7
 - flow: 0.196.3
 - recast: 0.21.5

Additional context

ASTExplorer: https://astexplorer.net/#/gist/06acdba498d4d88f9bad5a2480c1f72a/66b0637459b7b0f720e29c3373c3c238edfc54f9

[Feature]: Pass values set in `AWS.config.update` during client creation

Self-service

  • I'd be willing to implement this feature

Input code

import AWS from "aws-sdk";

AWS.config.update({ region: "us-west-2"});
const dynamodbClient = new AWS.DynamoDB();
const s3Client = new AWS.S3();

Expected Output

import { DynamoDB } from "@aws-sdk/client-dynamodb";
import { S3 } from "@aws-sdk/client-s3";

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

Additional context

Current output:

import { DynamoDB } from "@aws-sdk/client-dynamodb";
import { S3 } from "@aws-sdk/client-s3";

AWS.config.update({ region = "us-west-2"});
const dynamodbClient = new DynamoDB();
const s3Client = new S3(); 

Version:

aws-sdk-js-codemod: 0.1.3

jscodeshift: 0.13.1
 - babel: 7.17.5
 - babylon: 7.17.3
 - flow: 0.172.0
 - recast: 0.20.5

AWS.Config.update property

[Feature]: Sort imports according to client package names in output

Self-service

  • I'd be willing to implement this feature

Input code

import AWS from "aws-sdk";

const region = "us-west-2";

const dynamodbClient = new AWS.DynamoDB({ region });
const s3Client = new AWS.S3({ region });

Expected Output

import { DynamoDB } from "@aws-sdk/client-dynamodb";
import { S3 } from "@aws-sdk/client-s3";

const region = "us-west-2";

const dynamodbClient = new DynamoDB({ region });
const s3Client = new S3({ region });

Additional context

The output received is:

import { S3 } from "@aws-sdk/client-s3";
import { DynamoDB } from "@aws-sdk/client-dynamodb";

const region = "us-west-2";

const dynamodbClient = new DynamoDB({ region });
const s3Client = new S3({ region });
aws-sdk-js-codemod: 0.1.3

jscodeshift: 0.13.1
 - babel: 7.17.5
 - babylon: 7.17.3
 - flow: 0.172.0
 - recast: 0.20.5

[Feature]: The promise call needs to be removed from API called on a class member

Self-service

  • I'd be willing to implement this feature

Input code

import * as AWS from 'aws-sdk';

export class SecretsManager {
  constructor(client = new AWS.SecretsManager()) {
    this.client = client;
  }

  async getSecretValue(secretId) {
    const response = await this.client
      .getSecretValue({ SecretId: secretId })
      .promise();
    if (response.SecretString) {
      return response.SecretString;
    } else {
      throw new Error(`Unable to get the secret value from ${secretId}`);
    }
  }
}

Expected Output

import { SecretsManager } from "@aws-sdk/client-secrets-manager";

export class SecretsManager {
  constructor(client = new SecretsManager()) {
    this.client = client;
  }

  async getSecretValue(secretId) {
    const response = await this.client
      .getSecretValue({ SecretId: secretId });
    if (response.SecretString) {
      return response.SecretString;
    } else {
      throw new Error(`Unable to get the secret value from ${secretId}`);
    }
  }
}

Additional context

Example in #181

[Feature]: Support named imports from "aws-sdk"

Self-service

  • I'd be willing to implement this feature

Input code

import { DynamoDB } from "aws-sdk";

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

Expected Output

import { DynamoDB } from "@aws-sdk/client-dynamodb";

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

Additional context

This missing feature was noticed in #225

[Feature]: Use default imports to minimize identifier conflicts with existing code

Self-service

  • I'd be willing to implement this feature

Input code

Input:

import DynamoDB from "aws-sdk/clients/dynamodb";

const ddbClient = new DynamoDB({ region: "us-west-2" });
const listTablesInput: DynamoDB.ListTablesInput = { Limit: 10 };
const listTablesOutput: DynamoDB.ListTablesOutput = await ddbClient
  .listTables(listTablesInput)
  .promise();

Existing output:

import { DynamoDB, ListTablesCommandInput, ListTablesCommandOutput } from "@aws-sdk/client-dynamodb";

const ddbClient = new DynamoDB({ region: "us-west-2" });
const listTablesInput: ListTablesCommandInput = { Limit: 10 };
const listTablesOutput: ListTablesCommandOutput = await ddbClient
  .listTables(listTablesInput);

Expected Output

import * as DynamoDB from "@aws-sdk/client-dynamodb";

const ddbClient = new DynamoDB.DynamoDB({ region: "us-west-2" });
const listTablesInput: DynamoDB.ListTablesCommandInput = { Limit: 10 };
const listTablesOutput: DynamoDB.ListTablesCommandOutput = await ddbClient.listTables(
  listTablesInput
);

Additional context

This solution not only minimizes imports which can conflict with other variables defined in the code, but also adds support for nested type definitions requested in #225

Update transformer modules to operate on `ClientMetadataMap`

Is your feature request related to a problem? Please describe.

The individual modification functions operate on clientName separately

https://github.com/awslabs/aws-sdk-js-codemod/blob/7cec9bdefc31c0f994e39a9fc3719ff5087527fd/src/transforms/v2-to-v3/transformer.ts#L36-L52

This not only takes more time, but also difficult to maintain as each function needs different parameters.

Describe the solution you'd like

Update transformer modules to operate on ClientMetadataMap so that operations can be performed in a single pass.

Describe alternatives you've considered

N/A

Additional context

Refs: #251 (comment)

[Feature]: Add support for individual client imports

Self-service

  • I'd be willing to implement this feature

Input code

import DynamoDB from "aws-sdk/clients/dynamodb";

const client = new DynamoDB();

Expected Output

import { DynamoDB } from "@aws-sdk/client-dynamodb";

const client = new DynamoDB();

Additional context

No response

[Bug?]: can't set type on arguments

Self-service

Describe the bug

Running transform complains about missing comma.

npx aws-sdk-js-codemod -t v2-to-v3 lib/index.ts 
Processing 1 files... 
Spawning 1 workers...
Sending 1 files to free worker...
 ERR lib/index.ts Transformation error (Unexpected token, expected "," (9:29))
SyntaxError: Unexpected token, expected "," (9:29)
    at instantiate (/home/gitpod/.npm/_npx/c5e6d14ea42cfa80/node_modules/@babel/parser/src/parse-error/credentials.ts:62:21)
    .....

Template name

v2-to-v3

Input code

import S3 from 'aws-sdk/clients/s3';

const s3=new S3();

export const handler = (event:any ,context:any) => {
    const data = s3.listBuckets(function(err,data) {;
        if (err) {
            console.log("Error", err, err.stack);
            return ("");
        } else {
            console.log("Success", data.Buckets);
            return (data.Buckets);
        } 
    });
    console.log(`DATA ${data}}`);

    return ( {
        statusCode: 200,
        body: JSON.stringify({
            message: 'hello world',
        }),
    });
};

Observed failure

npx aws-sdk-js-codemod -t v2-to-v3 lib/index.ts 
Processing 1 files... 
Spawning 1 workers...
Sending 1 files to free worker...
 ERR lib/index.ts Transformation error (Unexpected token, expected "," (9:29))
SyntaxError: Unexpected token, expected "," (9:29)
    at instantiate (/home/gitpod/.npm/_npx/c5e6d14ea42cfa80/node_modules/@babel/parser/src/parse-error/credentials.ts:62:21)
    ....

Line 9 is :

export const handler = (event:any ,context:any) => {

Char 29 is the t of "event" (assuming char 1 is "e")

Expected Output

npx aws-sdk-js-codemod -t v2-to-v3 index.ts 
Processing 1 files... 
Spawning 1 workers...
Sending 1 files to free worker...
All done. 
Results: 
0 errors
0 unmodified
0 skipped
1 ok

Environment

$ aws-sdk-js-codemod --version
bash: aws-sdk-js-codemod: command not found
$ npx aws-sdk-js-codemod --version
aws-sdk-js-codemod: 0.6.1

jscodeshift: 0.14.0
 - babel: 7.20.2
 - babylon: 7.20.3
 - flow: 0.193.0
 - recast: 0.21.5


### Additional context

I'm deploying the index.ts with CDK as a node JS 16. And it works.

Change to node JS 18 and it fails to import with "not found" errors.

[Bug]: The v2-to-v3 transform removes top level comment

Self-service

  • I'd be willing to implement a fix

Describe the bug

The v2-to-v3 transform removes top level comment

Template name

v2-to-v3

Input code

// Top level comment
import AWS from "aws-sdk";

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

// Make listTables call
client.listTables({}, (err, data) => {
  if (err) console.log(err, err.stack);
  else console.log(data);
});

Observed failure

No failure, but the top level comment is removed

import { DynamoDB } from "@aws-sdk/client-dynamodb";

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

// Make listTables call
client.listTables({}, (err, data) => {
  if (err) console.log(err, err.stack);
  else console.log(data);
});

Expected output

// Top level comment
import { DynamoDB } from "@aws-sdk/client-dynamodb";

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

// Make listTables call
client.listTables({}, (err, data) => {
  if (err) console.log(err, err.stack);
  else console.log(data);
});

### Environment

```shell
aws-sdk-js-codemod: 0.6.4

jscodeshift: 0.14.0
 - babel: 7.20.5
 - babylon: 7.20.5
 - flow: 0.196.2
 - recast: 0.21.5

Additional context

No response

[Feature]: Create a documentation website for supported test cases

Is your feature request related to a problem? Please describe.

The supported test cases are not documented anywhere. They can be viewed in __fixtures__ directory.

Describe the solution you'd like

Create a documentation website with supported test cases.

Describe alternatives you've considered

Going through __fixtures__ directory for supported test cases

Additional context

Alternatively, a playground link will be helpful requested in #116

[Feature]: Support transformation for require

Self-service

  • I'd be willing to implement this feature

Input code

const AWS = require("aws-sdk");

const client = new AWS.DynamoDB();

Expected Output

const { DynamoDB } = require("@aws-sdk/client-dynamodb");

const client = new DynamoDB();

Additional context

No response

[Feature]: Generate V3 client name and package name according to v3 release

Self-service

  • I'd be willing to implement this feature

Description

Currently the V3 package names are static: code, but the upstream V3 SDK repo releases new clients constantly. This is not scalable for maintainers to update this list often.

We can create a workflow to add new package/client names to the metadata automatically, either by periodically checking the V3 repo or triggered by a V3 GitHub release.

[Feature]: Transform import from service module path when identifier does not match client name

Self-service

  • I'd be willing to implement this feature

Input code

import ACMClient from "aws-sdk/clients/acm";

const client = new ACMClient();

Expected Output

import { ACM as ACMClient } from "@aws-sdk/client-acm";

const client = new ACMClient();

Additional context

Existing codemod does not modify the file

$ npx aws-sdk-js-codemod -t v2-to-v3 index.v2.ts
Processing 1 files... 
Spawning 1 workers...
Sending 1 files to free worker...
All done. 
Results: 
0 errors
1 unmodified
0 skipped
0 ok
Time elapsed: 0.379seconds

$ npx aws-sdk-js-codemod --version
aws-sdk-js-codemod: 0.6.12

jscodeshift: 0.14.0
 - babel: 7.20.7
 - babylon: 7.20.7
 - flow: 0.196.3
 - recast: 0.21.5

[Feature]: Migrating nested type definitions from v2 to v3

Self-service

  • I'd be willing to implement this feature

Test Comand

npx aws-sdk-js-codemod --dry --print -t v2-to-v3 example.ts

Input code

import { S3 } from "aws-sdk";
const testTags: S3.Tag[] = [{ Key: "abc", Value: "value" }];

Current Output

Results:
0 errors
1 unmodified
0 skipped
0 ok

Expected Output

import { Tag } from "@aws-sdk/client-s3";
const testTags: Tag[] = [{ Key: "abc", Value: "value" }];

Additional context

Would it be possible to migrate the import of Typescript type definitions from v2 to v3?
My project has a global store that uses the AWS SDK types to store objects and tags. During migration, it'll be great to also have those types updated to their v3 references.

[Feature]: Dynamic imports

Self-service

  • I'd be willing to implement this feature

Input code

import("aws-sdk")
  .then((module) => {
    return module.S3;
  })
  .then(() => {
    const AWS = require("aws-sdk");
    const s3 = new AWS.S3({});
  });

Expected Output

import("@aws-sdk/client-s3")
  .then((module) => {
    return module.S3;
  })
  .then(async () => {
    const { S3 } = require("@aws-sdk/client-s3");
    const s3 = new S3({});
  });

Additional context

Can be observed by checking out this change: https://github.com/awslabs/aws-sdk-js-codemod/compare/main...kuhe:aws-sdk-js-codemod:example/imports?expand=1

And running npx jest -t dynamic

[Bug]: npx does not use the latest version of the codemod

Describe the bug

npx does not use the latest version of codemod

Steps to reproduce

To reproduce, you need to have an older version of aws-sdk-js-codemod installed

$ npm view aws-sdk-js-codemod version 
0.6.3

$ npx aws-sdk-js-codemod --version
aws-sdk-js-codemod: 0.6.1
...

Run the following commands:

$ npx aws-sdk-js-codemod@latest --version

$ npx aws-sdk-js-codemod --version

Observed behavior

When latest is explicitly passed, it uses the latest version.
But it does not override the previously installed version

$ npx aws-sdk-js-codemod@latest --version
Need to install the following packages:
  [email protected]
Ok to proceed? (y) y
aws-sdk-js-codemod: 0.6.3
...

$ npx aws-sdk-js-codemod --version 
aws-sdk-js-codemod: 0.6.1
...

Expected behavior

Default documentation should update how to use the latest version.

The current usage recommends npx aws-sdk-js-codemod which will use the catched version: https://github.com/awslabs/aws-sdk-js-codemod#usage

[Feature]: Do not emit types as aws-sdk-js-codemod is designed to be used as a CLI

Self-service

  • I'd be willing to implement this feature

Description

Do not emit types as aws-sdk-js-codemod is designed to be used as a CLI.

$ npm install aws-sdk-js-codemod
....

$ npm list aws-sdk-js-codemod
...
└── [email protected]

$ du -sh node_modules/aws-sdk-js-codemod
416K	node_modules/aws-sdk-js-codemod

$ find node_modules/aws-sdk-js-codemod -name "*.d.ts" -type f -delete

$ du -sh node_modules/aws-sdk-js-codemod                             
236K	node_modules/aws-sdk-js-codemod

[Feature]: Support transformation for client require

Self-service

  • I'd be willing to implement this feature

Input code

const DynamoDB = require("aws-sdk/clients/dynamodb");

const client = new DynamoDB();

Expected Output

const { DynamoDB } = require("@aws-sdk/client-dynamodb");

const client = new DynamoDB();

Additional context

The transformation for global require was added in #62

[Bug]: The `.promise()` is not removed on await of API call

Self-service

  • I'd be willing to implement a fix

Describe the bug

The .promise() is not removed on await of API call

Template name

v2-to-v3

Input code

import AWS from "aws-sdk";

const client = new AWS.DynamoDB();
try {
  const data = await client.listTables().promise();
  console.log(data);
} catch (err) {
  console.log(err, err.stack);
}

Observed failure

import { DynamoDB } from "@aws-sdk/client-dynamodb";

const client = new DynamoDB();
try {
  const data = await client.listTables().promise();
  console.log(data);
} catch (err) {
  console.log(err, err.stack);
}

Expected output

import { DynamoDB } from "@aws-sdk/client-dynamodb";

const client = new DynamoDB();
try {
  const data = await client.listTables();
  console.log(data);
} catch (err) {
  console.log(err, err.stack);
}

Environment

aws-sdk-js-codemod: 0.2.0

jscodeshift: 0.13.1
 - babel: 7.17.5
 - babylon: 7.17.3
 - flow: 0.172.0
 - recast: 0.20.5

Additional context

No response

[Feature]: Support ImportEqualsDeclaration

Self-service

  • I'd be willing to implement this feature

Input code

import AWS = require("aws-sdk");

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

Expected Output

import { DynamoDB } = require("@aws-sdk/client-dynamodb");

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

Additional context

This missing feature was noticed in #242

[Bug?]: codemod considers non client types as clients and throws error

Self-service

  • I'd be willing to implement a fix

Describe the bug

codemod considers non client types as clients and throws error

Template name

v2-to-v3

Input code

import { ListTablesInput } from "aws-sdk/clients/dynamodb";

const listTablesInput: ListTablesInput = { Limit: 10 };

Observed failure

Transformation error (Client 'ListTablesInput' is either deprecated or newly added.)
Error: Client 'ListTablesInput' is either deprecated or newly added.
    at getV3ClientName (/Users/trivikr/.npm/_npx/c10ddf24489924c3/node_modules/aws-sdk-js-codemod/dist/transforms/v2-to-v3/utils/get/getV3ClientName.js:9:11)
    at reduce (/Users/trivikr/.npm/_npx/c10ddf24489924c3/node_modules/aws-sdk-js-codemod/dist/transforms/v2-to-v3/utils/get/getClientMetadata.js:9:60)
    at Array.reduce (<anonymous>)
    at getClientMetadata (/Users/trivikr/.npm/_npx/c10ddf24489924c3/node_modules/aws-sdk-js-codemod/dist/transforms/v2-to-v3/utils/get/getClientMetadata.js:6:75)
    at transformer (/Users/trivikr/.npm/_npx/c10ddf24489924c3/node_modules/aws-sdk-js-codemod/dist/transforms/v2-to-v3/transformer.js:13:57)

Expected output

Ideally, the codemod should support transformation for those types which is requested in #210

But it shouldn't throw an error for these cases.

Environment

aws-sdk-js-codemod: 0.6.6

jscodeshift: 0.14.0
 - babel: 7.20.5
 - babylon: 7.20.5
 - flow: 0.196.1
 - recast: 0.21.5

Additional context

No response

[Feature]: Support v2-to-v3 transformation of waiters

Self-service

  • I'd be willing to implement this feature

Input code

import AWS from "aws-sdk";

const Bucket = "BUCKET_NAME";
const client = new AWS.S3({ region: "REGION" });

await client.createBucket({ Bucket }).promise();
await client.waitFor("bucketExists", { Bucket }).promise();

Expected Output

import { S3, waitUntilBucketExists } from "@aws-sdk/client-s3";

const Bucket = "BUCKET_NAME";
const client = new S3({ region: "REGION" });

await client.createBucket({ Bucket });
await waitUntilBucketExists({ client, maxWaitTime: 60 }, { Bucket });

Additional context

Blog post: Waiters in modular AWS SDK for JavaScript

[Feature]: Support transformation for API input and output types

Self-service

  • I'd be willing to implement this feature

Input code

import AWS from "aws-sdk";

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

const listTablesInput: AWS.DynamoDB.ListTablesInput = { Limit: 10 };
const listTablesOutput: AWS.DynamoDB.ListTablesOutput = await client
  .listTables(listTablesInput)
  .promise();

Expected Output

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);

Additional context

Example test in #209

Create a playground for aws-sdk-js-codemod

Is your feature request related to a problem? Please describe.

To test aws-sdk-js-codemod the users have to install it using npm install or npx

Describe the solution you'd like

Create a playground where users can select template, provide their code and check the output.

Additional context

vue-codemod playground vuejs/vue-codemod#2

[Feature]: Support v2-to-v3 transformation for DynamoDB Document client

Self-service

  • I'd be willing to implement this feature

Input code

import AWS from "aws-sdk";

const documentClient = new AWS.DynamoDB.DocumentClient(
  { region: "us-east-1" }
);

Expected Output

import { DynamoDBDocument } from "@aws-sdk/lib-dynamodb";
import { DynamoDB } from "@aws-sdk/client-dynamodb";

const documentClient = DynamoDBDocument.from(
  new DynamoDB({ region: "us-east-1" })
);

Additional context

No response

[Feature]: Do not add newline while updating requires

Self-service

  • I'd be willing to implement this feature

Input code

const ACM = require("aws-sdk/clients/acm");

const client = new ACM();

Expected Output

Expected output

const { ACM } = require("@aws-sdk/client-acm");

const client = new ACM();

Observed output

const {
  ACM
} = require("@aws-sdk/client-acm");

const client = new ACM();

Additional context

No response

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.