-
Notifications
You must be signed in to change notification settings - Fork 30.4k
Expand file tree
/
Copy pathaws-lambda-tests.ts
More file actions
220 lines (200 loc) · 6.83 KB
/
Copy pathaws-lambda-tests.ts
File metadata and controls
220 lines (200 loc) · 6.83 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
// Declare a bunch of basic types up front. Since this file has no imports
// or exports, typescript treats these as global declarations that can be
// used in tests/* files.
// Don't add declarations for service-specific types here; i.e. not from
// common/ or trigger/, but handler.d.ts is fine. Those can be in the
// service-specific tests in tests/{service}-tests.ts
declare let str: string;
declare let strOrNull: string | null;
declare let strOrUndefined: string | undefined;
declare let strOrUndefinedOrNull: string | undefined | null;
declare let date: Date;
declare let obj: {};
declare let array: any[];
declare let anyObj: any;
declare let num: number;
declare let error: Error;
declare let bool: boolean;
declare let boolOrUndefined: boolean | undefined;
declare let boolOrNumOrStr: boolean | number | string;
declare let numOrUndefined: number | undefined;
declare let strArrayOrUndefined: string[] | undefined;
declare let nullOrUndefined: null | undefined;
declare let objectOrUndefined: {} | undefined;
// handler.d.ts types
declare let context: AWSLambda.Context;
declare let clientCtx: AWSLambda.ClientContext;
declare let clientCtxOrUndefined: AWSLambda.ClientContext | undefined;
declare let clientContextEnv: AWSLambda.ClientContextEnv;
declare let clientContextClient: AWSLambda.ClientContextClient;
declare let identity: AWSLambda.CognitoIdentity;
declare let identityOrUndefined: AWSLambda.CognitoIdentity | undefined;
/* Context */
bool = context.callbackWaitsForEmptyEventLoop;
str = context.functionName;
str = context.functionVersion;
str = context.invokedFunctionArn;
str = context.memoryLimitInMB;
str = context.awsRequestId;
str = context.logGroupName;
str = context.logStreamName;
identityOrUndefined = context.identity;
clientCtxOrUndefined = context.clientContext;
str = identity.cognitoIdentityId;
str = identity.cognitoIdentityPoolId;
/* ClientContext */
clientContextClient = clientCtx.client;
anyObj = clientCtx.custom;
clientContextEnv = clientCtx.env;
/* ClientContextEnv */
str = clientContextEnv.locale;
str = clientContextEnv.make;
str = clientContextEnv.model;
str = clientContextEnv.platform;
str = clientContextEnv.platformVersion;
/* ClientContextClient */
str = clientContextClient.appPackageName;
str = clientContextClient.appTitle;
str = clientContextClient.appVersionCode;
str = clientContextClient.appVersionName;
str = clientContextClient.installationId;
declare const untypedCallback: AWSLambda.Callback;
untypedCallback();
untypedCallback(undefined);
untypedCallback(null);
untypedCallback(error);
untypedCallback(str); // https://docs.aws.amazon.com/apigateway/latest/developerguide/handle-errors-in-lambda-integration.html
untypedCallback(null, anyObj);
untypedCallback(undefined, bool);
untypedCallback(null, bool);
untypedCallback(null, str);
untypedCallback(null, num);
untypedCallback(null, { foo: 123 });
untypedCallback(null, { bar: 123 });
// @ts-expect-error
untypedCallback(null, anyObj, anyObj);
interface TestResult {
foo: number;
}
declare const typedCallback: AWSLambda.Callback<TestResult>;
typedCallback();
typedCallback(undefined);
typedCallback(null);
typedCallback(error);
typedCallback(str); // https://docs.aws.amazon.com/apigateway/latest/developerguide/handle-errors-in-lambda-integration.html
typedCallback(null, anyObj);
typedCallback(null, { foo: 123 });
// @ts-expect-error
typedCallback(null, str);
// @ts-expect-error
typedCallback(null, { bar: 123 });
/* Compatibility functions */
context.done();
context.done(error);
context.done(error, anyObj);
context.succeed(str);
context.succeed(anyObj);
context.succeed(str, anyObj);
context.fail(error);
context.fail(str);
interface CustomTEvent {
eventString: string;
eventBool: boolean;
}
interface CustomTResult {
resultString: string;
resultBool?: boolean | undefined;
}
type CustomHandler = AWSLambda.Handler<CustomTEvent, CustomTResult>;
type CustomCallback = AWSLambda.Callback<CustomTResult>;
// Untyped handlers should work
const untypedAsyncHandler: AWSLambda.Handler = async (event, context, cb) => {
// $ExpectType any
event;
// $ExpectType Context
context;
// $ExpectType Callback<any>
cb;
// Can still use callback
cb(null, { resultString: str });
if (bool) {
// Uncaught error
return { resultString: bool };
}
return { resultString: str };
};
const untypedCallbackHandler: AWSLambda.Handler = (event, context, cb) => {
// $ExpectType any
event;
// $ExpectType Context
context;
// $ExpectType Callback<any>
cb;
cb(null, { resultString: str });
// Uncaught error
cb(null, { resultString: bool });
};
/* In node8.10 runtime, handlers may return a promise for the result value, so existing async
* handlers that return Promise<void> before calling the callback will now have a `null` result.
* Be safe and make that badly typed with a major verson bump to 8.10 so users expect the breaking change,
* since the upgrade effort should be pretty low in most cases, and it points them at a nicer solution.
*/
// Test we get error for unsafe old style
// @ts-expect-error
const unsafeAsyncHandler: CustomHandler = async (event, context, cb) => {
cb(null, { resultString: "No longer valid" });
};
// Test safe old style still works
const typedCallbackHandler: CustomHandler = (event, context, cb) => {
// $ExpectType CustomTEvent
event;
str = event.eventString;
// $ExpectType Context
context;
str = context.functionName;
// $ExpectType Callback<CustomTResult>
cb;
cb();
cb(null);
cb(new Error());
// @ts-expect-error
cb(null, {});
cb(null, { resultString: str });
// @ts-expect-error
cb(null, { resultString: bool });
};
// Test preferred new type
const typedAsyncHandler: CustomHandler = async (event, context, cb) => {
// $ExpectType CustomTEvent
event;
// $ExpectType Context
context;
// $ExpectType Callback<CustomTResult>
cb;
// Can still use callback
cb(null, { resultString: str });
return { resultString: "Is now valid!" };
};
// @ts-expect-error
const badTypedAsyncHandler: CustomHandler = async (event, context, cb) => ({ resultString: bool });
// Test using untyped Callback type still works.
const mixedUntypedCallbackTypedHandler: CustomHandler = (
event: CustomTEvent,
context: AWSLambda.Context,
cb: AWSLambda.Callback,
) => {};
// Test streamifyResponse
const streamifyResponseHandler: AWSLambda.StreamifyHandler = (event, responseStream, context) => {
const metadata = {
statusCode: 200,
headers: {
"Content-Type": "application/json",
"CustomHeader": "outerspace",
},
};
responseStream = awslambda.HttpResponseStream.from(responseStream, metadata);
responseStream.setContentType("text/plain");
responseStream.write("Hello, world!");
responseStream.end();
};
awslambda.streamifyResponse(streamifyResponseHandler);