Skip to content

Latest commit

 

History

History
1072 lines (976 loc) · 21.3 KB

TRANSFORMATIONS.md

File metadata and controls

1072 lines (976 loc) · 21.3 KB

Static imports

The codemod detects static imports from the code written in the different ways below, and transforms them to their equivalent static imports in v3.

Name Example
Default Import
import AWS from "aws-sdk";
Namespace Import
import * as AWS from "aws-sdk";
Variable Require
const AWS = require("aws-sdk");
Import Equals
import AWS = require(“aws-sdk");
Named Import
import { DynamoDB } from "aws-sdk";
ObjectPattern Require
const { DynamoDB } = require("aws-sdk");
Named Import with a local name
import { DynamoDB as DynDB } from "aws-sdk";
ObjectPattern Require with a local name
const { DynamoDB: DynDB } = require("aws-sdk");
Variable Require Property
const DynamoDB = require("aws-sdk").DynamoDB;
Variable Require Property with a local name
const DynDB = require("aws-sdk").DynamoDB;
Default Import with deep path
import DynamoDB from "aws-sdk/clients/dynamodb";
Namespace Import with deep path
import * as DynamoDB from "aws-sdk/clients/dynamodb";
Variable Require with deep path
const DynamoDB = require("aws-sdk/clients/dynamodb");
Import Equals with deep path
import DynamoDB = require(“aws-sdk/clients/dynamodb”);

Example

// Before (SDK v2)
import AWS from "aws-sdk";
const client = new AWS.DynamoDB();
// After (SDK v3)
import { DynamoDB } from "@aws-sdk/client-dynamodb";
const client = new DynamoDB();

Client creation

Name Before (SDK v2) After (SDK v3)
Client name same in v2 vs v3
import AWS from "aws-sdk";
const client = new AWS.S3();
import { S3 } from "@aws-sdk/client-s3";
const client = new S3();
Client name different in v2 vs v3
import AWS from "aws-sdk";
const client = new AWS.IotData();
import { IoTDataPlane } from @aws-sdk/client-iot-data-plane";
const client = new IoTDataPlane();
Client with local name
import { DynamoDB as DynDB } from "aws-sdk";
const client = new DynDB();
import { DynamoDB as DynDB } from "@aws-sdk/client-dynamodb";
const client = new DynDB();

Config in clients

Simple configuration which is deprecated, and not needed.

// Before (SDK v2)
const client = new AWS.DynamoDB({
  correctClockSkew: true,
});
// After (SDK v3)
const client = new DynamoDB({
  // The key correctClockSkew is no longer supported in v3, and can be removed.
  // @deprecated The clock skew correction is applied by default.
  correctClockSkew: true,
});

Simple configuration which is not supported

// Before (SDK v2)
const client = new AWS.DynamoDB({
  convertResponseTypes: true,
});
// After (SDK v3)
const client = new DynamoDB({
  // The key convertResponseTypes is no longer supported in v3, and can be removed.
  // @deprecated Not type-safe. It doesn't convert time stamp or base64 binaries from the JSON response.
  convertResponseTypes: true,
});

Simple configuration which is replaced

// Before (SDK v2)
const client = new AWS.DynamoDB({
  accessKeyId: "KEY",
  secretAccessKey: "SECRET",
});
// After (SDK v3)
const client = new DynamoDB({
  credentials: {
    accessKeyId: "KEY",
    secretAccessKey: "SECRET",
  },
});

Configuration which is not changed

// Before (SDK v2)
const client = new AWS.DynamoDB({
  region: "us-west-2",
});
// After (SDK v3)
const client = new DynamoDB({
  region: "us-west-2",
});

Configuration which is renamed

// Before (SDK v2)
const client = new AWS.DynamoDB({
  maxRetries: 5,
});
// After (SDK v3)
const client = new DynamoDB({
  // The key maxRetries is renamed to maxAttempts.
  // The value of maxAttempts needs to be maxRetries + 1.
  maxAttempts: 5,
});

Global config keys

The transformation of client configuration applies to global config keys

// Before (SDK v2)
import AWS from "aws-sdk";

AWS.config.region = "us-west-2";

const client = new AWS.DynamoDB();
// After (SDK v3)
import AWS from "aws-sdk";

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

// JS SDK v3 does not support global configuration.
// Codemod has attempted to pass values to each service client in this file.
// You may need to update clients outside of this file, if they use global config.
AWS.config.region = "us-west-2";

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

Global config update call

The transformation of client configuration applies to global config update call

// Before (SDK v2)
import AWS from "aws-sdk";

AWS.config.update({ region: "us-west-2" });

const client = new AWS.DynamoDB();
// After (SDK v3)
import AWS from "aws-sdk";

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

// JS SDK v3 does not support global configuration.
// Codemod has attempted to pass values to each service client in this file.
// You may need to update clients outside of this file, if they use global config.
AWS.config.update({ region: "us-west-2" });

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

Removal of .promise() from API calls

The examples below does not include SDK import and client creation.

Name Before (SDK v2) After (SDK v3)
await expression
await client.listTables().promise();
await client.listTables();
call expression
client.listTables().promise();
client.listTables();
member expression
client.listTables().promise().then(console.log);
client.listTables().then(console.log);
client as a class member
this.clientInClass.listTables().promise()
this.clientInClass.listTables();
client defined as a type (no creation in file)
export const listTables = async (
  client: AWS.DynamoDB
) => client.listTables().promise();
export const listTables = async (
  client: DynamoDB
) => client.listTables();
Request stored in identifier
const listTablesRequest = client.listTables();
const response = await listTablesRequest.promise();
const listTablesRequest = client.listTables();
const response = await listTablesRequest;

TypeScript types

Name Before (SDK v2) After (SDK v3)
Basic Type
import AWS from "aws-sdk";
const foo: AWS.S3.Tag[] = [];
import { Tag } from "@aws-sdk/client-s3";
const foo: Tag[] = [];
Input/Output Type
import AWS from "aws-sdk";
const listTablesInput: AWS.DynamoDB.ListTablesInput = { Limit: 10 };
const listTablesOutput: AWS.DynamoDB.ListTablesOutput = {};
import { ListTablesCommandInput, ListTablesCommandOutput } from "@aws-sdk/client-dynamodb";
const listTablesInput: ListTablesCommandInput = { Limit: 10 };
const listTablesOutput: ListTablesCommandOutput = {};

Redundant TypeScript types

The examples include imports wherever v3 requires a import. The redundant import of v2 is removed by codemod.

Name Before (SDK v2) After (SDK v3)
Native Type (string)
const stringType: AWS.S3.AccountId = "string";
const stringType: string = "string";
Native Type (boolean)
const booleanType: AWS.S3.BucketKeyEnabled = true;
const booleanType: boolean = true;
Native Type (number)
const numberType: AWS.S3.ContentLength = 123;
const numberType: number = 123;
Native Type (Date)
const dateType: AWS.S3.CreationDate = new Date();
const dateType: Date = new Date();
Native Type (Uint8Array)
const blobType: AWS.RDSDataService._Blob = new Uint8Array();
const blobType: Uint8Array = new Uint8Array();
Array (strings)
const stringArray: AWS.S3.AllowedHeaders = ["string"];
const stringArray: Array = ["string"];
Array (boolean)
const booleanArray: AWS.RDSDataService.BooleanArray = [true, false];
const booleanArray: Array = [true, false];
Array (number)
const numberArray: AWS.RDSDataService.LongArray = [123, 456];
const numberArray: Array = [123, 456];
Array (Uint8Array)
const blobArray: AWS.IoTFleetWise.NetworkFilesList = [
  new Uint8Array()
];
const blobArray: Array = [
  new Uint8Array()
];
Array (enum)
import AWS from "aws-sdk";
const enumArray: AWS.S3.ChecksumAlgorithmList = ["CRC32"];
import { ChecksumAlgorithm } from "@aws-sdk/client-s3";
const enumArray: Array = ["CRC32"];
Array (structure)
import AWS from "aws-sdk";
const structureArray: AWS.S3.Buckets = [{ Name: "bucketName" }];
import { Bucket } from "@aws-sdk/client-s3";
const structureArray: Array = [{ Name: "bucketName" }];
Map (string)
const stringMap: AWS.S3.Metadata = { key: "value" };
const stringMap: Record = { key: "value" };
Map (boolean)
const booleanMap: AWS.APIGateway.MapOfStringToBoolean = {
  key: true
};
const booleanMap: Record = {
  key: true
};
Map (number)
const numberMap: AWS.SSM.AssociationStatusAggregatedCount = {
  key: 123
};
const numberMap: Record = {
  key: 123
};
Map (structure)
import AWS from "aws-sdk";
const structureMap: AWS.APIGateway.MapOfMethodSnapshot = {
  key: { apiKeyRequired: true }
};
import { MethodSnapshot } from "@aws-sdk/client-api-gateway";
const structureMap: Record = {
  key: { apiKeyRequired: true }
};
Nested array (twice)
const arrayNestedTwice: AWS.SageMakerGeospatial.LinearRing = [
  [1, 2], [3, 4]
];
const arrayNestedTwice: Array> = [
  [1, 2], [3, 4]
];
Nested array (thrice)
const arrayNestedThrice: AWS.SageMakerGeospatial.LinearRings = [
  [[1, 2], [3, 4]], [[4, 5], [6, 7]]
];
const arrayNestedThrice: Array>> = [
  [[1, 2], [3, 4]], [[4, 5], [6, 7]]
];
Nested array (four times)
const arrayNestedFour: AWS.SageMakerGeospatial.LinearRingsList = [
  [[[1], [2]], [[3], [4]]],
  [[[5], [6]], [[7], [8]]]
];
const arrayNestedFour: Array>>> = [
  [[[1], [2]], [[3], [4]]],
  [[[5], [6]], [[7], [8]]]
];
Nested Maps
const mapNestedTwice: AWS.LexModelsV2.ConditionMap = {
  key: stringMap
};
const mapNestedTwice: Record> = {
  key: stringMap
};
Nested Maps (structure)
import AWS from "aws-sdk";
const mapNestedTwiceStruct: AWS.APIGateway.PathToMapOfMethodSnapshot = {
  key: structureMap
};
import { MethodSnapshot } from "@aws-sdk/client-api-gateway";
const mapNestedTwiceStruct: Record> = {
  key: structureMap
};
Map of Arrays
const mapOfArrays: AWS.NetworkManager.FilterMap = {
  key: ["value"]
};
const mapOfArrays: Record> = {
  key: ["value"]
};
Map of Map of Arrays
const mapOfMapOfArrays: AWS.AppIntegrations.ObjectConfiguration = {
  key: mapOfArrays
};
const mapOfMapOfArrays: Record>> = {
  key: mapOfArrays
};
Map of Array of Maps
import AWS from "aws-sdk";
const mapOfArrayOfMaps: AWS.DynamoDB.BatchGetResponseMap = {
  key: [{ key: { S:"A" }}]
};
import { AttributeValue } from "@aws-sdk/client-dynamodb";
const mapOfArrayOfMaps: Record>> = {
  key: [{ key: { S:"A" }}]
};
Map of Array of Arrays
const mapOfArrayOfArrays: AWS.APIGateway.MapOfKeyUsages = {
  key: [[1], [2]]
};
const mapOfArrayOfArrays: Record>> = {
  key: [[1], [2]]
};
Array of Maps
const arrayOfMaps: AWS.SSM.InventoryItemEntryList = [stringMap];
const arrayOfMaps: Array> = [stringMap];
Array of Map of Arrays
const arrayOfMapOfArrays: AWS.SSM.TargetMaps = [mapOfArrays];
const arrayOfMapOfArrays: Array>> = [mapOfArrays];

Waiters

Transforms waitFor calls with specific waitUntil* functions

// Before (SDK v2)
import AWS from "aws-sdk";

const client = new AWS.S3();

await client.waitFor("bucketExists", { Bucket }).promise();
// After (SDK v3)
import { S3, waitUntilBucketExists } from "@aws-sdk/client-s3";

const client = new S3();

await waitUntilBucketExists(
  {
    client,
    maxWaitTime: 200,
  },
  { Bucket }
);

Credential Providers and Chain

We maintain a list of credential providers in v2, and replace them with ones in v3. The credential providers have changed from creating new class instances to functions which provide Promise of credentials.

v2 credentials v3 credentials
ChainableTemporaryCredentials fromTemporaryCredentials
CognitoIdentityCredentials fromCognitoIdentity
EC2MetadataCredentials fromInstanceMetadata
ECSCredentials fromContainerMetadata
EnvironmentCredentials fromEnv
ProcessCredentials fromProcess
RemoteCredentials fromContainerMetadata
SharedIniFileCredentials fromIni
SsoCredentials fromSSO
TokenFileWebIdentityCredentials fromTokenFile
WebIdentityCredentials fromWebToken

Example transformation

// Before (SDK v2)
import AWS from "aws-sdk";

new AWS.EnvironmentCredentials("AWS");
// After (SDK v3)
import { fromEnv } from "@aws-sdk/credential-providers";

// JS SDK v3 switched credential providers from classes to functions.
// This is the closest approximation from codemod of what your application needs.
// Reference: https://www.npmjs.com/package/@aws-sdk/credential-providers
fromEnv("AWS");

Token Providers and Chain

We maintain a list of token providers in v2, and replace them with ones in v3. The token providers have changed from creating new class instances to functions which provide Promise of token

v2 token providers v3 token providers
SSOTokenProvider fromSso
StaticTokenProvider fromStatic

Example transformation

// Before (SDK v2)
import AWS from "aws-sdk";

new AWS.SSOTokenProvider(options);
// After (SDK v3)
import { fromSso } from "@aws-sdk/token-providers";

// JS SDK v3 switched token providers from classes to functions.
// This is the closest approximation from codemod of what your application needs.
// Reference: https://www.npmjs.com/package/@aws-sdk/token-providers
fromSso(options);

DynamoDB DocumentClient

Applies all client transformations to DynamoDB DocumentClient.

Example transformation

// Before (SDK v2)
import AWS from "aws-sdk";

const documentClient = new AWS.DynamoDB.DocumentClient({ region: "us-west-2" });
const response = await documentClient.scan({ TableName: "TABLE_NAME" }).promise();
// After (SDK v3)
import { DynamoDBDocument } from "@aws-sdk/lib-dynamodb";
import { DynamoDB } from "@aws-sdk/client-dynamodb";

const documentClient = DynamoDBDocument.from(new DynamoDB({ region: "us-west-2" }));
const response = await documentClient.scan({ TableName: "TABLE_NAME" });

S3 getSignedUrl

Example transformation

// Before (SDK v2)
import AWS from "aws-sdk";

const client = new AWS.S3();

const url = client.getSignedUrl("getObject", { Bucket: "bucket", Key: "key" });
// After (SDK v3)
import { getSignedUrl } from "@aws-sdk/s3-request-presigner";
import { GetObjectCommand, S3 } from "@aws-sdk/client-s3";

const client = new S3();

const url = await getSignedUrl(client, new GetObjectCommand({ Bucket: "bucket", Key: "key" }));

S3 multi-part upload

Example transformation

// Before (SDK v2)
import AWS from "aws-sdk";

const client = new AWS.S3();

await client
  .upload({
    Body: "BODY",
    Bucket: "Bucket",
    ContentType: "ContentType",
    Key: "Key",
  })
  .promise();
// After (SDK v3)
import { Upload } from "@aws-sdk/lib-storage";
import { S3 } from "@aws-sdk/client-s3";

const client = new S3();

await new Upload({
  client,
  params: {
    Body: "BODY",
    Bucket: "Bucket",
    ContentType: "ContentType",
    Key: "Key",
  },
}).done();