@aws-sdk/find-v2 0.3.2 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +25 -14
- package/dist/cli.js +12 -0
- package/dist/{scanLambdaFunction.js → getLambdaFunctionScanOutput.js} +28 -11
- package/dist/scanLambdaFunctions.js +10 -13
- package/package.json +5 -2
- package/dist/constants.js +0 -5
package/README.md
CHANGED
|
@@ -32,20 +32,31 @@ Commands:
|
|
|
32
32
|
Run `lambda` command to scan Lambda Node.js Functions for JavaScript SDK v2.
|
|
33
33
|
|
|
34
34
|
```console
|
|
35
|
-
$ npx @aws-sdk/find-v2 lambda
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
35
|
+
$ npx @aws-sdk/find-v2 lambda --yes
|
|
36
|
+
[
|
|
37
|
+
{
|
|
38
|
+
"FunctionName": "fn-without-aws-sdk-in-bundle",
|
|
39
|
+
"Region": "us-east-2",
|
|
40
|
+
"ContainsAwsSdkJsV2": false
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
"FunctionName": "fn-with-aws-sdk-in-bundle",
|
|
44
|
+
"Region": "us-east-2",
|
|
45
|
+
"ContainsAwsSdkJsV2": true,
|
|
46
|
+
"AwsSdkJsV2Location": "Bundled in index file."
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
"FunctionName": "fn-with-aws-sdk-in-package-json-deps",
|
|
50
|
+
"Region": "us-east-2",
|
|
51
|
+
"ContainsAwsSdkJsV2": true,
|
|
52
|
+
"AwsSdkJsV2Location": "Defined in package.json dependencies."
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
"FunctionName": "fn-without-aws-sdk-in-package-json-deps",
|
|
56
|
+
"Region": "us-east-2",
|
|
57
|
+
"ContainsAwsSdkJsV2": false
|
|
58
|
+
}
|
|
59
|
+
]
|
|
49
60
|
```
|
|
50
61
|
|
|
51
62
|
This script requires AWS Managed Policy [AWSLambda_ReadOnlyAccess][].
|
package/dist/cli.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Command } from "commander";
|
|
2
|
+
import { cpus } from "node:os";
|
|
2
3
|
import packageJson from "../package.json" with { type: "json" };
|
|
3
4
|
import { scanLambdaFunctions } from "./scanLambdaFunctions.js";
|
|
4
5
|
/**
|
|
@@ -18,6 +19,17 @@ export const createProgram = () => {
|
|
|
18
19
|
.description("Scans Lambda Node.js Functions for JavaScript SDK v2")
|
|
19
20
|
.option("-r, --region <region>", "AWS region to scan")
|
|
20
21
|
.option("-y, --yes", "answer yes for all prompts")
|
|
22
|
+
.option("-j, --jobs <count>", "number of parallel jobs", (value) => {
|
|
23
|
+
const trimmed = value.trim();
|
|
24
|
+
if (!/^\d+$/.test(trimmed)) {
|
|
25
|
+
throw new Error("jobs must be a positive integer");
|
|
26
|
+
}
|
|
27
|
+
const parsed = Number.parseInt(trimmed, 10);
|
|
28
|
+
if (parsed < 1) {
|
|
29
|
+
throw new Error("jobs must be a positive integer");
|
|
30
|
+
}
|
|
31
|
+
return parsed;
|
|
32
|
+
}, cpus().length)
|
|
21
33
|
.action(async (options) => {
|
|
22
34
|
await scanLambdaFunctions(options);
|
|
23
35
|
});
|
|
@@ -1,15 +1,19 @@
|
|
|
1
|
-
import { JS_SDK_V2_MARKER } from "./constants.js";
|
|
2
1
|
import { downloadFile } from "./utils/downloadFile.js";
|
|
3
2
|
import { getLambdaFunctionContents, } from "./utils/getLambdaFunctionContents.js";
|
|
4
3
|
import { hasSdkV2InBundle } from "./utils/hasSdkV2InBundle.js";
|
|
5
4
|
import { rm } from "node:fs/promises";
|
|
6
5
|
import { tmpdir } from "node:os";
|
|
7
6
|
import { join } from "node:path";
|
|
8
|
-
export const
|
|
7
|
+
export const getLambdaFunctionScanOutput = async (client, { functionName, region }) => {
|
|
8
|
+
const output = {
|
|
9
|
+
FunctionName: functionName,
|
|
10
|
+
Region: region,
|
|
11
|
+
ContainsAwsSdkJsV2: null,
|
|
12
|
+
};
|
|
9
13
|
const response = await client.getFunction({ FunctionName: functionName });
|
|
10
14
|
if (!response.Code?.Location) {
|
|
11
|
-
|
|
12
|
-
return;
|
|
15
|
+
output.AwsSdkJsV2Error = "Function Code location not found.";
|
|
16
|
+
return output;
|
|
13
17
|
}
|
|
14
18
|
const zipPath = join(tmpdir(), `${functionName}.zip`);
|
|
15
19
|
let lambdaFunctionContents;
|
|
@@ -17,6 +21,13 @@ export const scanLambdaFunction = async (client, functionName) => {
|
|
|
17
21
|
await downloadFile(response.Code.Location, zipPath);
|
|
18
22
|
lambdaFunctionContents = await getLambdaFunctionContents(zipPath);
|
|
19
23
|
}
|
|
24
|
+
catch (error) {
|
|
25
|
+
output.AwsSdkJsV2Error =
|
|
26
|
+
error instanceof Error
|
|
27
|
+
? `Error downloading or reading Lambda function code: ${error.message}`
|
|
28
|
+
: "Error downloading or reading Lambda function code.";
|
|
29
|
+
return output;
|
|
30
|
+
}
|
|
20
31
|
finally {
|
|
21
32
|
await rm(zipPath, { force: true });
|
|
22
33
|
}
|
|
@@ -28,21 +39,27 @@ export const scanLambdaFunction = async (client, functionName) => {
|
|
|
28
39
|
const packageJson = JSON.parse(packageJsonContent);
|
|
29
40
|
const dependencies = packageJson.dependencies || {};
|
|
30
41
|
if ("aws-sdk" in dependencies) {
|
|
31
|
-
|
|
32
|
-
|
|
42
|
+
output.ContainsAwsSdkJsV2 = true;
|
|
43
|
+
output.AwsSdkJsV2Location = "Defined in package.json dependencies.";
|
|
44
|
+
return output;
|
|
33
45
|
}
|
|
34
|
-
// oxlint-disable-next-line no-unused-vars
|
|
35
46
|
}
|
|
36
47
|
catch (error) {
|
|
37
|
-
|
|
48
|
+
output.AwsSdkJsV2Error =
|
|
49
|
+
error instanceof Error
|
|
50
|
+
? `Error parsing package.json: ${error.message}`
|
|
51
|
+
: "Error parsing package.json";
|
|
52
|
+
return output;
|
|
38
53
|
}
|
|
39
54
|
}
|
|
40
55
|
}
|
|
41
56
|
// Check for code of "aws-sdk" in bundle, if not found in package.json dependencies.
|
|
42
57
|
if (bundleContent && hasSdkV2InBundle(bundleContent)) {
|
|
43
|
-
|
|
44
|
-
|
|
58
|
+
output.ContainsAwsSdkJsV2 = true;
|
|
59
|
+
output.AwsSdkJsV2Location = "Bundled in index file.";
|
|
60
|
+
return output;
|
|
45
61
|
}
|
|
46
62
|
// "aws-sdk" dependency/code not found.
|
|
47
|
-
|
|
63
|
+
output.ContainsAwsSdkJsV2 = false;
|
|
64
|
+
return output;
|
|
48
65
|
};
|
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
import { Lambda } from "@aws-sdk/client-lambda";
|
|
2
2
|
import pLimit from "p-limit";
|
|
3
|
-
import {
|
|
4
|
-
import { JS_SDK_V2_MARKER } from "./constants.js";
|
|
5
|
-
import { scanLambdaFunction } from "./scanLambdaFunction.js";
|
|
3
|
+
import { getLambdaFunctionScanOutput } from "./getLambdaFunctionScanOutput.js";
|
|
6
4
|
import { getDownloadConfirmation } from "./utils/getDownloadConfirmation.js";
|
|
7
5
|
import { getLambdaFunctions } from "./utils/getLambdaFunctions.js";
|
|
8
|
-
export const scanLambdaFunctions = async (
|
|
6
|
+
export const scanLambdaFunctions = async (options = {}) => {
|
|
7
|
+
const { region, yes, jobs } = options;
|
|
9
8
|
const client = new Lambda({ region });
|
|
10
9
|
const functions = await getLambdaFunctions(client);
|
|
11
10
|
const functionCount = functions.length;
|
|
12
|
-
const concurrency = Math.min(functionCount,
|
|
11
|
+
const concurrency = Math.min(functionCount, jobs || 1);
|
|
13
12
|
const codeSizeToDownload = functions.reduce((acc, fn) => acc + (fn.CodeSize || 0), 0);
|
|
14
13
|
const codeSizeToSaveOnDisk = functions
|
|
15
14
|
.map((fn) => fn.CodeSize || 0)
|
|
@@ -17,7 +16,7 @@ export const scanLambdaFunctions = async ({ region, yes } = {}) => {
|
|
|
17
16
|
.slice(0, concurrency)
|
|
18
17
|
.reduce((acc, size) => acc + size, 0);
|
|
19
18
|
if (functionCount === 0) {
|
|
20
|
-
console.log("
|
|
19
|
+
console.log("[]");
|
|
21
20
|
process.exit(0);
|
|
22
21
|
}
|
|
23
22
|
if (!yes) {
|
|
@@ -28,13 +27,11 @@ export const scanLambdaFunctions = async ({ region, yes } = {}) => {
|
|
|
28
27
|
process.exit(0);
|
|
29
28
|
}
|
|
30
29
|
}
|
|
31
|
-
console.log(`Note about output:`);
|
|
32
|
-
console.log(`- ${JS_SDK_V2_MARKER.Y} means "aws-sdk" is found in Lambda function, and migration is recommended.`);
|
|
33
|
-
console.log(`- ${JS_SDK_V2_MARKER.N} means "aws-sdk" is not found in Lambda function.`);
|
|
34
|
-
console.log(`- ${JS_SDK_V2_MARKER.UNKNOWN} means script was not able to proceed, and it emits reason.\n`);
|
|
35
30
|
const clientRegion = await client.config.region();
|
|
36
|
-
console.log(`Reading ${functionCount} function${functionCount > 1 ? "s" : ""} from "${clientRegion}" region.`);
|
|
37
31
|
const limit = pLimit(concurrency);
|
|
38
|
-
await Promise.all(functions.map((fn) => limit(() =>
|
|
39
|
-
|
|
32
|
+
const output = await Promise.all(functions.map((fn) => limit(() => getLambdaFunctionScanOutput(client, {
|
|
33
|
+
functionName: fn.FunctionName,
|
|
34
|
+
region: clientRegion,
|
|
35
|
+
}))));
|
|
36
|
+
console.log(JSON.stringify(output, null, 2));
|
|
40
37
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aws-sdk/find-v2",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "CLI to find resources which call AWS using JavaScript SDK v2",
|
|
5
5
|
"main": "dist/cli.js",
|
|
6
6
|
"types": "dist/cli.d.ts",
|
|
@@ -18,6 +18,8 @@
|
|
|
18
18
|
"@rollup/plugin-json": "^6.1.0",
|
|
19
19
|
"@rollup/plugin-node-resolve": "^16.0.3",
|
|
20
20
|
"@rollup/plugin-terser": "^0.4.4",
|
|
21
|
+
"@rspack/cli": "^1.6.8",
|
|
22
|
+
"@rspack/core": "^1.6.8",
|
|
21
23
|
"@tsconfig/node-ts": "^23.6.2",
|
|
22
24
|
"@tsconfig/node20": "^20.1.8",
|
|
23
25
|
"@types/node": "^20.14.8",
|
|
@@ -25,6 +27,7 @@
|
|
|
25
27
|
"esbuild": "~0.27.1",
|
|
26
28
|
"oxfmt": "^0.18.0",
|
|
27
29
|
"oxlint": "^1.33.0",
|
|
30
|
+
"parcel": "^2.16.3",
|
|
28
31
|
"rolldown": "1.0.0-beta.54",
|
|
29
32
|
"rollup": "^4.53.3",
|
|
30
33
|
"typescript": "^5.9.3",
|
|
@@ -37,7 +40,7 @@
|
|
|
37
40
|
"lint": "oxlint src/**/*.ts",
|
|
38
41
|
"format": "oxfmt",
|
|
39
42
|
"test": "vitest",
|
|
40
|
-
"test:generate:bundles": "
|
|
43
|
+
"test:generate:bundles": "sh scripts/generateBundles.sh",
|
|
41
44
|
"release": "yarn build && changeset publish"
|
|
42
45
|
},
|
|
43
46
|
"repository": {
|