@aws/run-mcp-servers-with-aws-lambda 0.5.12 → 0.5.14
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 +160 -11
- package/package.json +10 -10
- package/dist/client/lambdaFunction.test.d.ts +0 -1
- package/dist/client/lambdaFunction.test.js +0 -191
- package/dist/client/streamableHttpWithSigV4.test.d.ts +0 -1
- package/dist/client/streamableHttpWithSigV4.test.js +0 -442
- package/dist/handlers/handlers.test.d.ts +0 -1
- package/dist/handlers/handlers.test.js +0 -698
- package/dist/server-adapter/stdioServerAdapter.test.d.ts +0 -1
- package/dist/server-adapter/stdioServerAdapter.test.js +0 -196
- package/dist/server-adapter/stdioServerAdapterRequestHandler.test.d.ts +0 -1
- package/dist/server-adapter/stdioServerAdapterRequestHandler.test.js +0 -148
package/README.md
CHANGED
|
@@ -150,6 +150,158 @@ node /var/task/node_modules/@ivotoby/openapi-mcp-server/bin/mcp-server.js
|
|
|
150
150
|
|
|
151
151
|
</details>
|
|
152
152
|
|
|
153
|
+
### Passing credentials and other secrets to the MCP server
|
|
154
|
+
|
|
155
|
+
This library does not provide out-of-the-box mechanisms for managing any secrets needed by the wrapped
|
|
156
|
+
MCP server. For example, the [GitHub MCP server](https://github.com/modelcontextprotocol/servers/tree/main/src/github)
|
|
157
|
+
and the [Brave search MCP server](https://github.com/modelcontextprotocol/servers/tree/main/src/brave-search)
|
|
158
|
+
require API keys to make requests to third-party APIs.
|
|
159
|
+
You may configure these API keys as
|
|
160
|
+
[encrypted environment variables](https://docs.aws.amazon.com/lambda/latest/dg/configuration-envvars-encryption.html)
|
|
161
|
+
in the Lambda function's configuration or retrieve them from Secrets Manager in the Lambda function code (examples below).
|
|
162
|
+
However, note that anyone with access to invoke the Lambda function
|
|
163
|
+
will then have access to use your API key to call the third-party APIs by invoking the function.
|
|
164
|
+
We recommend limiting access to the Lambda function using
|
|
165
|
+
[least-privilege IAM policies](https://docs.aws.amazon.com/lambda/latest/dg/security-iam.html).
|
|
166
|
+
If you use an identity-based authentication mechanism such as OAuth, you could also store and retrieve API keys per user but there are no implementation examples in this repository.
|
|
167
|
+
|
|
168
|
+
<details>
|
|
169
|
+
|
|
170
|
+
<summary><b>Python server example retrieving an API key from Secrets Manager</b></summary>
|
|
171
|
+
|
|
172
|
+
```python
|
|
173
|
+
import sys
|
|
174
|
+
|
|
175
|
+
import boto3
|
|
176
|
+
from mcp.client.stdio import StdioServerParameters
|
|
177
|
+
|
|
178
|
+
# Retrieve API key from Secrets Manager
|
|
179
|
+
secrets_client = boto3.client("secretsmanager")
|
|
180
|
+
api_key = secrets_client.get_secret_value(SecretId="my-api-key-secret")["SecretString"]
|
|
181
|
+
|
|
182
|
+
server_params = StdioServerParameters(
|
|
183
|
+
command=sys.executable,
|
|
184
|
+
args=["-m", "my_mcp_server"],
|
|
185
|
+
env={
|
|
186
|
+
"API_KEY": api_key,
|
|
187
|
+
},
|
|
188
|
+
)
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
</details>
|
|
192
|
+
|
|
193
|
+
<details>
|
|
194
|
+
|
|
195
|
+
<summary><b>Typescript server example retrieving an API key from Secrets Manager</b></summary>
|
|
196
|
+
|
|
197
|
+
```typescript
|
|
198
|
+
import { SecretsManagerClient, GetSecretValueCommand } from "@aws-sdk/client-secrets-manager";
|
|
199
|
+
|
|
200
|
+
const secretsClient = new SecretsManagerClient({});
|
|
201
|
+
const secret = await secretsClient.send(
|
|
202
|
+
new GetSecretValueCommand({ SecretId: "my-api-key-secret" })
|
|
203
|
+
);
|
|
204
|
+
const apiKey = secret.SecretString;
|
|
205
|
+
|
|
206
|
+
const serverParams = {
|
|
207
|
+
command: "npx",
|
|
208
|
+
args: ["--offline", "my-mcp-server"],
|
|
209
|
+
env: {
|
|
210
|
+
API_KEY: apiKey,
|
|
211
|
+
},
|
|
212
|
+
};
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
</details>
|
|
216
|
+
<br/>
|
|
217
|
+
|
|
218
|
+
If your MCP server needs to call AWS APIs (such as the [MCP servers for AWS](https://github.com/awslabs/mcp)),
|
|
219
|
+
you can pass the Lambda function's AWS credentials to the wrapped MCP server via environment variables.
|
|
220
|
+
The wrapped MCP server's child process does not automatically inherit the Lambda execution role's credentials.
|
|
221
|
+
Again, note that anyone with access to invoke the Lambda function
|
|
222
|
+
will then have access to use the function's AWS credentials to call AWS APIs by invoking the function.
|
|
223
|
+
We recommend limiting access to the Lambda function using
|
|
224
|
+
[least-privilege IAM policies](https://docs.aws.amazon.com/lambda/latest/dg/security-iam.html).
|
|
225
|
+
|
|
226
|
+
<details>
|
|
227
|
+
|
|
228
|
+
<summary><b>Python server example using AWS credentials via environment variables</b></summary>
|
|
229
|
+
|
|
230
|
+
```python
|
|
231
|
+
import os
|
|
232
|
+
import sys
|
|
233
|
+
|
|
234
|
+
import boto3
|
|
235
|
+
from mcp.client.stdio import StdioServerParameters
|
|
236
|
+
|
|
237
|
+
# Get AWS credentials from Lambda execution role to pass to subprocess
|
|
238
|
+
session = boto3.Session()
|
|
239
|
+
credentials = session.get_credentials()
|
|
240
|
+
if credentials is None:
|
|
241
|
+
raise RuntimeError("Unable to retrieve AWS credentials from the execution environment")
|
|
242
|
+
resolved = credentials.get_frozen_credentials()
|
|
243
|
+
|
|
244
|
+
server_params = StdioServerParameters(
|
|
245
|
+
command=sys.executable,
|
|
246
|
+
args=["-m", "my_mcp_server"],
|
|
247
|
+
env={
|
|
248
|
+
"AWS_REGION": os.environ.get("AWS_REGION", "us-west-2"),
|
|
249
|
+
"AWS_DEFAULT_REGION": os.environ.get("AWS_REGION", "us-west-2"),
|
|
250
|
+
"AWS_ACCESS_KEY_ID": resolved.access_key,
|
|
251
|
+
"AWS_SECRET_ACCESS_KEY": resolved.secret_key,
|
|
252
|
+
"AWS_SESSION_TOKEN": resolved.token or "",
|
|
253
|
+
},
|
|
254
|
+
)
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
</details>
|
|
258
|
+
|
|
259
|
+
<details>
|
|
260
|
+
|
|
261
|
+
<summary><b>Python server example using AWS credentials via credentials file</b></summary>
|
|
262
|
+
|
|
263
|
+
Some MCP servers require an AWS profile and do not support credentials passed via environment variables.
|
|
264
|
+
In this case, you can write the credentials to a file and point the MCP server to it.
|
|
265
|
+
|
|
266
|
+
```python
|
|
267
|
+
import os
|
|
268
|
+
import sys
|
|
269
|
+
|
|
270
|
+
import boto3
|
|
271
|
+
from mcp.client.stdio import StdioServerParameters
|
|
272
|
+
|
|
273
|
+
# Get AWS credentials from Lambda execution role to pass to subprocess
|
|
274
|
+
session = boto3.Session()
|
|
275
|
+
credentials = session.get_credentials()
|
|
276
|
+
if credentials is None:
|
|
277
|
+
raise RuntimeError("Unable to retrieve AWS credentials from the execution environment")
|
|
278
|
+
resolved = credentials.get_frozen_credentials()
|
|
279
|
+
|
|
280
|
+
# Write credentials to disk as default profile
|
|
281
|
+
aws_dir = "/tmp/.aws"
|
|
282
|
+
os.makedirs(aws_dir, exist_ok=True)
|
|
283
|
+
with open(f"{aws_dir}/credentials", "w") as f:
|
|
284
|
+
f.write("[default]\n")
|
|
285
|
+
f.write(f"aws_access_key_id = {resolved.access_key}\n")
|
|
286
|
+
f.write(f"aws_secret_access_key = {resolved.secret_key}\n")
|
|
287
|
+
if resolved.token:
|
|
288
|
+
f.write(f"aws_session_token = {resolved.token}\n")
|
|
289
|
+
|
|
290
|
+
server_params = StdioServerParameters(
|
|
291
|
+
command=sys.executable,
|
|
292
|
+
args=["-m", "my_mcp_server"],
|
|
293
|
+
env={
|
|
294
|
+
"AWS_REGION": os.environ.get("AWS_REGION", "us-west-2"),
|
|
295
|
+
"AWS_DEFAULT_REGION": os.environ.get("AWS_REGION", "us-west-2"),
|
|
296
|
+
"AWS_SHARED_CREDENTIALS_FILE": f"{aws_dir}/credentials",
|
|
297
|
+
},
|
|
298
|
+
)
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
See a full, deployable example [here](examples/servers/sns-sqs/).
|
|
302
|
+
|
|
303
|
+
</details>
|
|
304
|
+
|
|
153
305
|
## Use API Gateway
|
|
154
306
|
|
|
155
307
|
```mermaid
|
|
@@ -341,6 +493,14 @@ npx @modelcontextprotocol/inspector --cli --method tools/list <your MCP server c
|
|
|
341
493
|
npx @modelcontextprotocol/inspector --cli --method tools/list uvx mcp-server-time > tool-schema.json
|
|
342
494
|
```
|
|
343
495
|
|
|
496
|
+
Some MCP servers generate tool schemas that AgentCore Gateway rejects with strict validation,
|
|
497
|
+
such as `"items": {}`, `"default": null`, or `anyOf` with `{"type": "null"}`.
|
|
498
|
+
You may need to clean up the schema before using it:
|
|
499
|
+
|
|
500
|
+
```bash
|
|
501
|
+
python3 scripts/clean-tool-schema.py tool-schema.json
|
|
502
|
+
```
|
|
503
|
+
|
|
344
504
|
<details>
|
|
345
505
|
|
|
346
506
|
<summary><b>Python server example</b></summary>
|
|
@@ -780,17 +940,6 @@ See a full example as part of the sample chatbot [here](examples/chatbots/typesc
|
|
|
780
940
|
the [sqlite MCP server](https://github.com/modelcontextprotocol/servers/tree/main/src/sqlite),
|
|
781
941
|
the [filesystem MCP server](https://github.com/modelcontextprotocol/servers/tree/main/src/filesystem),
|
|
782
942
|
and the [git MCP server](https://github.com/modelcontextprotocol/servers/tree/main/src/git).
|
|
783
|
-
- This library does not provide mechanisms for managing any secrets needed by the wrapped
|
|
784
|
-
MCP server. For example, the [GitHub MCP server](https://github.com/modelcontextprotocol/servers/tree/main/src/github)
|
|
785
|
-
and the [Brave search MCP server](https://github.com/modelcontextprotocol/servers/tree/main/src/brave-search)
|
|
786
|
-
require API keys to make requests to third-party APIs.
|
|
787
|
-
You may configure these API keys as
|
|
788
|
-
[encrypted environment variables](https://docs.aws.amazon.com/lambda/latest/dg/configuration-envvars-encryption.html)
|
|
789
|
-
in the Lambda function's configuration. However, note that anyone with access to invoke the Lambda function
|
|
790
|
-
will then have access to use your API key to call the third-party APIs by invoking the function.
|
|
791
|
-
We recommend limiting access to the Lambda function using
|
|
792
|
-
[least-privilege IAM policies](https://docs.aws.amazon.com/lambda/latest/dg/security-iam.html).
|
|
793
|
-
If you use an identity-based authentication mechanism such as OAuth, you could also store and retrieve API keys per user but there are no implementation examples in this repository.
|
|
794
943
|
|
|
795
944
|
## Deploy and run the examples
|
|
796
945
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aws/run-mcp-servers-with-aws-lambda",
|
|
3
3
|
"description": "Run Model Context Protocol (MCP) servers with AWS Lambda",
|
|
4
|
-
"version": "0.5.
|
|
4
|
+
"version": "0.5.14",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "Apache-2.0",
|
|
7
7
|
"author": {
|
|
@@ -44,24 +44,24 @@
|
|
|
44
44
|
"@tsconfig/recommended": "^1.0.13",
|
|
45
45
|
"@types/aws-lambda": "^8.10.161",
|
|
46
46
|
"@types/jest": "^30.0.0",
|
|
47
|
-
"@types/node": "^25.
|
|
47
|
+
"@types/node": "^25.5.0",
|
|
48
48
|
"aws-sdk-client-mock": "^4.1.0",
|
|
49
49
|
"aws-sdk-client-mock-jest": "^4.1.0",
|
|
50
|
-
"eslint": "^10.0
|
|
50
|
+
"eslint": "^10.2.0",
|
|
51
51
|
"eslint-plugin-check-file": "^3.3.1",
|
|
52
|
-
"jest": "^30.
|
|
53
|
-
"ts-jest": "^29.4.
|
|
52
|
+
"jest": "^30.3.0",
|
|
53
|
+
"ts-jest": "^29.4.9",
|
|
54
54
|
"tsx": "^4.21.0",
|
|
55
|
-
"typescript": "^
|
|
56
|
-
"typescript-eslint": "^8.
|
|
55
|
+
"typescript": "^6.0.2",
|
|
56
|
+
"typescript-eslint": "^8.58.1"
|
|
57
57
|
},
|
|
58
58
|
"dependencies": {
|
|
59
59
|
"@aws-crypto/sha256-js": "^5.2.0",
|
|
60
|
-
"@aws-sdk/client-lambda": "^3.
|
|
61
|
-
"@aws-sdk/credential-provider-node": "^3.
|
|
60
|
+
"@aws-sdk/client-lambda": "^3.1027.0",
|
|
61
|
+
"@aws-sdk/credential-provider-node": "^3.972.30",
|
|
62
62
|
"@aws-sdk/protocol-http": "^3.374.0",
|
|
63
63
|
"@aws-sdk/types": "^3.910.0",
|
|
64
|
-
"@modelcontextprotocol/sdk": "^1.
|
|
64
|
+
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
65
65
|
"@smithy/signature-v4": "^5.3.3",
|
|
66
66
|
"winston": "^3.19.0"
|
|
67
67
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import "aws-sdk-client-mock-jest";
|
|
@@ -1,191 +0,0 @@
|
|
|
1
|
-
import "aws-sdk-client-mock-jest";
|
|
2
|
-
import { LambdaClient, InvokeCommand } from "@aws-sdk/client-lambda";
|
|
3
|
-
import { LambdaFunctionClientTransport, } from "./index.js";
|
|
4
|
-
import { Uint8ArrayBlobAdapter } from "@smithy/util-stream";
|
|
5
|
-
import { mockClient } from "aws-sdk-client-mock";
|
|
6
|
-
describe("LambdaFunctionClientTransport", () => {
|
|
7
|
-
// Mock implementation of LambdaClient
|
|
8
|
-
const lambdaMock = mockClient(LambdaClient);
|
|
9
|
-
// Reset mocks before each test
|
|
10
|
-
beforeEach(() => {
|
|
11
|
-
jest.clearAllMocks();
|
|
12
|
-
lambdaMock.reset();
|
|
13
|
-
});
|
|
14
|
-
describe("constructor", () => {
|
|
15
|
-
test("should initialize client with provided region", async () => {
|
|
16
|
-
const params = {
|
|
17
|
-
functionName: "test-function",
|
|
18
|
-
regionName: "not-a-region",
|
|
19
|
-
};
|
|
20
|
-
const message = {
|
|
21
|
-
jsonrpc: "2.0",
|
|
22
|
-
id: 1,
|
|
23
|
-
method: "test-method",
|
|
24
|
-
};
|
|
25
|
-
const transport = new LambdaFunctionClientTransport(params);
|
|
26
|
-
lambdaMock.on(InvokeCommand).resolvesOnce({
|
|
27
|
-
Payload: Uint8ArrayBlobAdapter.fromString(JSON.stringify({ result: "success" })),
|
|
28
|
-
});
|
|
29
|
-
await transport.send(message);
|
|
30
|
-
expect(await lambdaMock.call(0).thisValue.config.region()).toBe("not-a-region");
|
|
31
|
-
});
|
|
32
|
-
test("should use the default region", async () => {
|
|
33
|
-
const originalRegion = process.env.AWS_REGION;
|
|
34
|
-
process.env.AWS_REGION = "default-region";
|
|
35
|
-
try {
|
|
36
|
-
const params = {
|
|
37
|
-
functionName: "test-function",
|
|
38
|
-
};
|
|
39
|
-
const message = {
|
|
40
|
-
jsonrpc: "2.0",
|
|
41
|
-
id: 1,
|
|
42
|
-
method: "test-method",
|
|
43
|
-
};
|
|
44
|
-
const transport = new LambdaFunctionClientTransport(params);
|
|
45
|
-
lambdaMock.on(InvokeCommand).resolvesOnce({
|
|
46
|
-
Payload: Uint8ArrayBlobAdapter.fromString(JSON.stringify({ result: "success" })),
|
|
47
|
-
});
|
|
48
|
-
await transport.send(message);
|
|
49
|
-
expect(await lambdaMock.call(0).thisValue.config.region()).toBe("default-region");
|
|
50
|
-
}
|
|
51
|
-
finally {
|
|
52
|
-
process.env.AWS_REGION = originalRegion;
|
|
53
|
-
}
|
|
54
|
-
});
|
|
55
|
-
});
|
|
56
|
-
describe("start and close methods", () => {
|
|
57
|
-
test("start method should be a no-op", async () => {
|
|
58
|
-
const params = {
|
|
59
|
-
functionName: "test-function",
|
|
60
|
-
};
|
|
61
|
-
const transport = new LambdaFunctionClientTransport(params);
|
|
62
|
-
await expect(transport.start()).resolves.toBeUndefined();
|
|
63
|
-
});
|
|
64
|
-
test("close method should be a no-op", async () => {
|
|
65
|
-
const params = {
|
|
66
|
-
functionName: "test-function",
|
|
67
|
-
};
|
|
68
|
-
const transport = new LambdaFunctionClientTransport(params);
|
|
69
|
-
await expect(transport.close()).resolves.toBeUndefined();
|
|
70
|
-
});
|
|
71
|
-
});
|
|
72
|
-
describe("send method", () => {
|
|
73
|
-
test("should invoke Lambda function with correct parameters", async () => {
|
|
74
|
-
const params = {
|
|
75
|
-
functionName: "test-function",
|
|
76
|
-
};
|
|
77
|
-
const message = {
|
|
78
|
-
jsonrpc: "2.0",
|
|
79
|
-
id: 1,
|
|
80
|
-
method: "test-method",
|
|
81
|
-
};
|
|
82
|
-
const transport = new LambdaFunctionClientTransport(params);
|
|
83
|
-
lambdaMock.on(InvokeCommand).resolvesOnce({
|
|
84
|
-
Payload: Uint8ArrayBlobAdapter.fromString(JSON.stringify({ result: "success" })),
|
|
85
|
-
});
|
|
86
|
-
await transport.send(message);
|
|
87
|
-
expect(lambdaMock).toHaveReceivedCommandTimes(InvokeCommand, 1);
|
|
88
|
-
expect(lambdaMock).toHaveReceivedCommandWith(InvokeCommand, {
|
|
89
|
-
FunctionName: "test-function",
|
|
90
|
-
InvocationType: "RequestResponse",
|
|
91
|
-
Payload: JSON.stringify(message),
|
|
92
|
-
});
|
|
93
|
-
});
|
|
94
|
-
test("should call onmessage with parsed response", async () => {
|
|
95
|
-
const params = {
|
|
96
|
-
functionName: "test-function",
|
|
97
|
-
};
|
|
98
|
-
const message = {
|
|
99
|
-
jsonrpc: "2.0",
|
|
100
|
-
id: 1,
|
|
101
|
-
method: "test-method",
|
|
102
|
-
};
|
|
103
|
-
const responsePayload = {
|
|
104
|
-
jsonrpc: "2.0",
|
|
105
|
-
id: 1,
|
|
106
|
-
result: { data: "test-data" },
|
|
107
|
-
};
|
|
108
|
-
const transport = new LambdaFunctionClientTransport(params);
|
|
109
|
-
const onMessageMock = jest.fn();
|
|
110
|
-
transport.onmessage = onMessageMock;
|
|
111
|
-
lambdaMock.on(InvokeCommand).resolvesOnce({
|
|
112
|
-
Payload: Uint8ArrayBlobAdapter.fromString(JSON.stringify(responsePayload)),
|
|
113
|
-
});
|
|
114
|
-
await transport.send(message);
|
|
115
|
-
expect(onMessageMock).toHaveBeenCalledTimes(1);
|
|
116
|
-
expect(onMessageMock).toHaveBeenCalledWith(responsePayload);
|
|
117
|
-
});
|
|
118
|
-
test("should not call onmessage for empty response", async () => {
|
|
119
|
-
const params = {
|
|
120
|
-
functionName: "test-function",
|
|
121
|
-
};
|
|
122
|
-
const message = {
|
|
123
|
-
jsonrpc: "2.0",
|
|
124
|
-
method: "notification",
|
|
125
|
-
};
|
|
126
|
-
const transport = new LambdaFunctionClientTransport(params);
|
|
127
|
-
const onMessageMock = jest.fn();
|
|
128
|
-
transport.onmessage = onMessageMock;
|
|
129
|
-
lambdaMock.on(InvokeCommand).resolvesOnce({
|
|
130
|
-
Payload: Uint8ArrayBlobAdapter.fromString("{}"),
|
|
131
|
-
});
|
|
132
|
-
await transport.send(message);
|
|
133
|
-
expect(onMessageMock).not.toHaveBeenCalled();
|
|
134
|
-
});
|
|
135
|
-
test("should throw error when Lambda function returns an error", async () => {
|
|
136
|
-
const params = {
|
|
137
|
-
functionName: "test-function",
|
|
138
|
-
};
|
|
139
|
-
const message = {
|
|
140
|
-
jsonrpc: "2.0",
|
|
141
|
-
id: 1,
|
|
142
|
-
method: "test-method",
|
|
143
|
-
};
|
|
144
|
-
const transport = new LambdaFunctionClientTransport(params);
|
|
145
|
-
const onErrorMock = jest.fn();
|
|
146
|
-
transport.onerror = onErrorMock;
|
|
147
|
-
lambdaMock.on(InvokeCommand).resolvesOnce({
|
|
148
|
-
FunctionError: "Unhandled",
|
|
149
|
-
Payload: Uint8ArrayBlobAdapter.fromString("Error executing function"),
|
|
150
|
-
});
|
|
151
|
-
await transport.send(message);
|
|
152
|
-
expect(onErrorMock).toHaveBeenCalledTimes(1);
|
|
153
|
-
expect(onErrorMock.mock.calls[0][0].message).toBe("Unhandled Error executing function");
|
|
154
|
-
});
|
|
155
|
-
test("should call onerror when Lambda client throws an error", async () => {
|
|
156
|
-
const params = {
|
|
157
|
-
functionName: "test-function",
|
|
158
|
-
};
|
|
159
|
-
const message = {
|
|
160
|
-
jsonrpc: "2.0",
|
|
161
|
-
id: 1,
|
|
162
|
-
method: "test-method",
|
|
163
|
-
};
|
|
164
|
-
const transport = new LambdaFunctionClientTransport(params);
|
|
165
|
-
const onErrorMock = jest.fn();
|
|
166
|
-
transport.onerror = onErrorMock;
|
|
167
|
-
const error = new Error("Network error");
|
|
168
|
-
lambdaMock.rejects(error);
|
|
169
|
-
await transport.send(message);
|
|
170
|
-
expect(onErrorMock).toHaveBeenCalledTimes(1);
|
|
171
|
-
expect(onErrorMock).toHaveBeenCalledWith(error);
|
|
172
|
-
});
|
|
173
|
-
test("should handle case when no Payload is returned", async () => {
|
|
174
|
-
const params = {
|
|
175
|
-
functionName: "test-function",
|
|
176
|
-
};
|
|
177
|
-
const message = {
|
|
178
|
-
jsonrpc: "2.0",
|
|
179
|
-
id: 1,
|
|
180
|
-
method: "test-method",
|
|
181
|
-
};
|
|
182
|
-
const transport = new LambdaFunctionClientTransport(params);
|
|
183
|
-
const onErrorMock = jest.fn();
|
|
184
|
-
transport.onerror = onErrorMock;
|
|
185
|
-
lambdaMock.on(InvokeCommand).resolvesOnce({});
|
|
186
|
-
await transport.send(message);
|
|
187
|
-
expect(onErrorMock).toHaveBeenCalledTimes(1);
|
|
188
|
-
expect(onErrorMock).toHaveBeenCalledWith(new Error("No payload returned from Lambda function"));
|
|
189
|
-
});
|
|
190
|
-
});
|
|
191
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|