Skip to content

Commit

Permalink
Support transformation of S3 getSignedUrl (#517)
Browse files Browse the repository at this point in the history
  • Loading branch information
trivikr committed Jul 28, 2023
1 parent d21db67 commit d194142
Show file tree
Hide file tree
Showing 30 changed files with 466 additions and 42 deletions.
5 changes: 5 additions & 0 deletions .changeset/sour-yaks-smell.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"aws-sdk-js-codemod": minor
---

Support transformation of S3 getSignedUrl
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import AWS from "aws-sdk";

const s3 = new AWS.S3();
const params = { Bucket: "bucket", Key: "key" };

s3.getSignedUrl("getObject", params, function (err, url) {
console.log('The URL is', url);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import AWS from "aws-sdk";

const s3 = new AWS.S3();
const params = { Bucket: "bucket", Key: "key" };

// S3 getSignedUrl with callbacks are not supported in AWS SDK for JavaScript (v3).
// Please convert to 'client.getSignedUrl(apiName, options)', and re-run aws-sdk-js-codemod.
s3.getSignedUrl("getObject", params, function (err, url) {
console.log('The URL is', url);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import AWS from "aws-sdk";

const s3 = new AWS.S3();
const params = { Bucket: "bucket", Key: "key" };

url = s3.getSignedUrl("getObject", params);
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { getSignedUrl } from "@aws-sdk/s3-request-presigner";
import { GetObjectCommand, S3 } from "@aws-sdk/client-s3";

const s3 = new S3();
const params = { Bucket: "bucket", Key: "key" };

url = await getSignedUrl(s3, new GetObjectCommand(params), {
expiresIn: "/* add value from 'Expires' from v2 call if present, else remove */"
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import AWS = require("aws-sdk");

const s3 = new AWS.S3();

url = s3.getSignedUrl("getObject", { Bucket: "bucket", Key: "key" });
url = s3.getSignedUrl("getObject", { Bucket: "bucket", Key: "key", Expires: 60 });
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import AWS_s3_request_presigner = require("@aws-sdk/s3-request-presigner");

const {
getSignedUrl
} = AWS_s3_request_presigner;

import AWS_S3 = require("@aws-sdk/client-s3");

const {
GetObjectCommand,
S3
} = AWS_S3;

const s3 = new S3();

url = await getSignedUrl(s3, new GetObjectCommand({ Bucket: "bucket", Key: "key" }));
url = await getSignedUrl(s3, new GetObjectCommand({
Bucket: "bucket",
Key: "key"
}), {
expiresIn: 60
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import AWS from "aws-sdk";

const s3 = new AWS.S3();

url = s3.getSignedUrl("getObject", { Bucket: "bucket", Key: "key" });
url = s3.getSignedUrl("getObject", { Bucket: "bucket", Key: "key", Expires: 60 });
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { getSignedUrl } from "@aws-sdk/s3-request-presigner";
import { GetObjectCommand, S3 } from "@aws-sdk/client-s3";

const s3 = new S3();

url = await getSignedUrl(s3, new GetObjectCommand({ Bucket: "bucket", Key: "key" }));
url = await getSignedUrl(s3, new GetObjectCommand({
Bucket: "bucket",
Key: "key"
}), {
expiresIn: 60
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import AWS from "aws-sdk";

const s3 = new AWS.S3();
const params = { Bucket: "bucket", Key: "key" };

url = await s3.getSignedUrlPromise("getObject", params);

url = await s3.getSignedUrlPromise("getObject", { Bucket: "bucket", Key: "key" });
url = await s3.getSignedUrlPromise("getObject", { Bucket: "bucket", Key: "key", Expires: 60 });
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { getSignedUrl } from "@aws-sdk/s3-request-presigner";
import { GetObjectCommand, S3 } from "@aws-sdk/client-s3";

const s3 = new S3();
const params = { Bucket: "bucket", Key: "key" };

url = await getSignedUrl(s3, new GetObjectCommand(params), {
expiresIn: "/* add value from 'Expires' from v2 call if present, else remove */"
});

url = await getSignedUrl(s3, new GetObjectCommand({ Bucket: "bucket", Key: "key" }));
url = await getSignedUrl(s3, new GetObjectCommand({
Bucket: "bucket",
Key: "key"
}), {
expiresIn: 60
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
const AWS = require("aws-sdk");

const s3 = new AWS.S3();

url = s3.getSignedUrl("getObject", { Bucket: "bucket", Key: "key" });
url = s3.getSignedUrl("getObject", { Bucket: "bucket", Key: "key", Expires: 60 });
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
const {
getSignedUrl
} = require("@aws-sdk/s3-request-presigner"),
{
GetObjectCommand,
S3
} = require("@aws-sdk/client-s3");

const s3 = new S3();

url = await getSignedUrl(s3, new GetObjectCommand({ Bucket: "bucket", Key: "key" }));
url = await getSignedUrl(s3, new GetObjectCommand({
Bucket: "bucket",
Key: "key"
}), {
expiresIn: 60
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import AWS from "aws-sdk";

const s3 = new AWS.S3();

url = s3.getSignedUrl("putObject", { Bucket: "bucket", Key: "key" });
url = s3.getSignedUrl("putObject", { Bucket: "bucket", Key: "key", Expires: 60 });
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { getSignedUrl } from "@aws-sdk/s3-request-presigner";
import { PutObjectCommand, S3 } from "@aws-sdk/client-s3";

const s3 = new S3();

url = await getSignedUrl(s3, new PutObjectCommand({ Bucket: "bucket", Key: "key" }));
url = await getSignedUrl(s3, new PutObjectCommand({
Bucket: "bucket",
Key: "key"
}), {
expiresIn: 60
});
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const uploadParams = {
};

// S3 ManagedUpload with callbacks are not supported in AWS SDK for JavaScript (v3).
// Please convert to `await client.upload(params, options).promise()`, and re-run aws-sdk-js-codemod.
// Please convert to 'await client.upload(params, options).promise()', and re-run aws-sdk-js-codemod.
client.upload(uploadParams, (err, data) => {
if (err) console.log(err, err.stack); // an error occurred
else console.log(data); // successful response
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const uploadParams = {
};

// S3 ManagedUpload with callbacks are not supported in AWS SDK for JavaScript (v3).
// Please convert to `await client.upload(params, options).promise()`, and re-run aws-sdk-js-codemod.
// Please convert to 'await client.upload(params, options).promise()', and re-run aws-sdk-js-codemod.
client.upload(uploadParams, function (err, data) {
if (err) console.log(err, err.stack); // an error occurred
else console.log(data); // successful response
Expand Down
54 changes: 34 additions & 20 deletions src/transforms/v2-to-v3/apis/addNotSupportedComments.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { Collection, JSCodeshift } from "jscodeshift";

import { FUNCTION_TYPE_LIST } from "../config";
import { getClientApiCallExpression } from "./getClientApiCallExpression";
import { getClientIdentifiers } from "./getClientIdentifiers";
import { getClientWaiterCallExpression } from "./getClientWaiterCallExpression";
import { getClientWaiterStates } from "./getClientWaiterStates";
import { getS3UploadCallExpression } from "./getS3UploadCallExpression";

export interface CommentsForUnsupportedAPIsOptions {
v2ClientName: string;
Expand Down Expand Up @@ -48,26 +48,40 @@ export const addNotSupportedComments = (

if (options.v2ClientName === "S3") {
for (const clientId of clientIdentifiers) {
source
.find(j.CallExpression, getS3UploadCallExpression(clientId))
.forEach((callExpression) => {
const args = callExpression.node.arguments;
const apiMetadata = [
{
apiName: "upload",
apiDescription: "S3 ManagedUpload",
apiSuggestion: "await client.upload(params, options).promise()",
},
{
apiName: "getSignedUrl",
apiDescription: "S3 getSignedUrl",
apiSuggestion: "client.getSignedUrl(apiName, options)",
},
];
for (const { apiName, apiDescription, apiSuggestion } of apiMetadata) {
source
.find(j.CallExpression, getClientApiCallExpression(clientId, apiName))
.forEach((callExpression) => {
const args = callExpression.node.arguments;

if (FUNCTION_TYPE_LIST.includes(args[args.length - 1].type)) {
const comments = callExpression.node.comments || [];
comments.push(
j.commentLine(
" S3 ManagedUpload with callbacks are not supported in AWS SDK for JavaScript (v3)."
)
);
comments.push(
j.commentLine(
" Please convert to `await client.upload(params, options).promise()`, and re-run aws-sdk-js-codemod."
)
);
callExpression.node.comments = comments;
}
});
if (FUNCTION_TYPE_LIST.includes(args[args.length - 1].type)) {
const comments = callExpression.node.comments || [];
comments.push(
j.commentLine(
` ${apiDescription} with callbacks are not supported in AWS SDK for JavaScript (v3).`
)
);
comments.push(
j.commentLine(
` Please convert to '${apiSuggestion}', and re-run aws-sdk-js-codemod.`
)
);
callExpression.node.comments = comments;
}
});
}
}
}
};
16 changes: 16 additions & 0 deletions src/transforms/v2-to-v3/apis/getClientApiCallExpression.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { CallExpression } from "jscodeshift";

import { ClientIdentifier } from "./getClientIdentifiers";

export const getClientApiCallExpression = (
clientId: ClientIdentifier,
apiName: string
// @ts-expect-error Property 'arguments' is missing in type
): CallExpression => ({
type: "CallExpression",
callee: {
type: "MemberExpression",
object: clientId,
property: { type: "Identifier", name: apiName },
},
});
4 changes: 4 additions & 0 deletions src/transforms/v2-to-v3/apis/getCommandName.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// Returns the command name for a given API name
// Example input `getObject` returns `GetObjectCommand`
export const getCommandName = (apiName: string): string =>
`${apiName[0].toUpperCase()}${apiName.slice(1)}Command`;
38 changes: 38 additions & 0 deletions src/transforms/v2-to-v3/apis/getS3SignedUrlApiNames.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { Collection, JSCodeshift, Literal } from "jscodeshift";

import { getClientIdentifiers } from "./getClientIdentifiers";

export interface GetS3SignedUrlApiNameOptions {
v2ClientName: string;
v2ClientLocalName: string;
v2GlobalName?: string;
}

export const getS3SignedUrlApiNames = (
j: JSCodeshift,
source: Collection<unknown>,
options: GetS3SignedUrlApiNameOptions
): string[] => {
if (options.v2ClientName !== "S3") return [];

const apiNames: Set<string> = new Set();
const clientIdentifiers = getClientIdentifiers(j, source, options);

for (const clientId of clientIdentifiers) {
for (const apiName of ["getSignedUrl", "getSignedUrlPromise"]) {
source
.find(j.CallExpression, {
callee: {
type: "MemberExpression",
object: clientId,
property: { type: "Identifier", name: apiName },
},
})
.forEach((callExpression) => {
apiNames.add((callExpression.value.arguments[0] as Literal).value as string);
});
}
}

return [...apiNames].sort();
};
13 changes: 0 additions & 13 deletions src/transforms/v2-to-v3/apis/getS3UploadCallExpression.ts

This file was deleted.

5 changes: 5 additions & 0 deletions src/transforms/v2-to-v3/apis/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
export * from "./addNotSupportedComments";
export * from "./getClientWaiterStates";
export * from "./getV3ClientWaiterApiName";
export * from "./getS3SignedUrlApiNames";
export * from "./isS3GetSignedUrlApiUsed";
export * from "./isS3UploadApiUsed";
export * from "./removePromiseCalls";
export * from "./replaceS3GetSignedUrlApi";
export * from "./replaceS3UploadApi";
export * from "./replaceWaiterApi";
export * from "./getCommandName";
34 changes: 34 additions & 0 deletions src/transforms/v2-to-v3/apis/isS3GetSignedUrlApiUsed.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { Collection, JSCodeshift } from "jscodeshift";

import { getClientIdentifiers } from "./getClientIdentifiers";

export interface IsS3GetSignedUrlApiUsedOptions {
v2ClientName: string;
v2ClientLocalName: string;
v2GlobalName?: string;
}

export const isS3GetSignedUrlApiUsed = (
j: JSCodeshift,
source: Collection<unknown>,
options: IsS3GetSignedUrlApiUsedOptions
) => {
if (options.v2ClientName !== "S3") return false;

const clientIdentifiers = getClientIdentifiers(j, source, options);

for (const clientId of clientIdentifiers) {
for (const apiName of ["getSignedUrl", "getSignedUrlPromise"]) {
const s3GetSignedUrlCallExpressions = source.find(j.CallExpression, {
callee: {
type: "MemberExpression",
object: clientId,
property: { type: "Identifier", name: apiName },
},
});
if (s3GetSignedUrlCallExpressions.length) return true;
}
}

return false;
};
Loading

0 comments on commit d194142

Please sign in to comment.