@tsed/platform-serverless-testing 8.0.1 → 8.0.2

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/package.json CHANGED
@@ -2,13 +2,14 @@
2
2
  "name": "@tsed/platform-serverless-testing",
3
3
  "description": "Module to test Serverless function with Ts.ED",
4
4
  "type": "module",
5
- "version": "8.0.1",
5
+ "version": "8.0.2",
6
6
  "source": "./src/index.ts",
7
7
  "main": "./lib/esm/index.js",
8
8
  "module": "./lib/esm/index.js",
9
9
  "typings": "./lib/types/index.d.ts",
10
10
  "exports": {
11
11
  ".": {
12
+ "@tsed/source": "./src/index.ts",
12
13
  "types": "./lib/types/index.d.ts",
13
14
  "import": "./lib/esm/index.js",
14
15
  "default": "./lib/esm/index.js"
@@ -51,12 +52,12 @@
51
52
  "homepage": "https://github.com/tsedio/tsed/tree/production/packages/platform/platform-serverless-testing",
52
53
  "repository": "https://github.com/tsedio/tsed",
53
54
  "devDependencies": {
54
- "@tsed/barrels": "8.0.1",
55
- "@tsed/core": "8.0.1",
56
- "@tsed/di": "8.0.1",
57
- "@tsed/platform-http": "8.0.1",
58
- "@tsed/schema": "8.0.1",
59
- "@tsed/typescript": "8.0.1",
55
+ "@tsed/barrels": "8.0.2",
56
+ "@tsed/core": "8.0.2",
57
+ "@tsed/di": "8.0.2",
58
+ "@tsed/platform-http": "8.0.2",
59
+ "@tsed/schema": "8.0.2",
60
+ "@tsed/typescript": "8.0.2",
60
61
  "@types/aws-lambda": "^8.10.145",
61
62
  "eslint": "9.12.0",
62
63
  "typescript": "5.4.5"
@@ -65,12 +66,12 @@
65
66
  "tslib": "2.7.0"
66
67
  },
67
68
  "peerDependencies": {
68
- "@tsed/core": "8.0.1",
69
- "@tsed/di": "8.0.1",
70
- "@tsed/json-mapper": "8.0.1",
69
+ "@tsed/core": "8.0.2",
70
+ "@tsed/di": "8.0.2",
71
+ "@tsed/json-mapper": "8.0.2",
71
72
  "@tsed/logger": ">=6.7.5",
72
- "@tsed/openspec": "8.0.1",
73
- "@tsed/platform-http": "8.0.1",
74
- "@tsed/schema": "8.0.1"
73
+ "@tsed/openspec": "8.0.2",
74
+ "@tsed/platform-http": "8.0.2",
75
+ "@tsed/schema": "8.0.2"
75
76
  }
76
77
  }
@@ -0,0 +1,199 @@
1
+ import {nameOf, Type} from "@tsed/core";
2
+ import {destroyInjector, DITest} from "@tsed/di";
3
+ import type {PlatformBuilder, PlatformBuilderSettings} from "@tsed/platform-http";
4
+ import type {
5
+ APIGatewayEventDefaultAuthorizerContext,
6
+ APIGatewayProxyEventBase,
7
+ APIGatewayProxyHandler,
8
+ APIGatewayProxyResult
9
+ } from "aws-lambda";
10
+
11
+ import {createFakeContext} from "./createFakeContext.js";
12
+ import {createFakeEvent} from "./createFakeEvent.js";
13
+
14
+ export interface LambdaPromiseResult extends Promise<APIGatewayProxyResult> {}
15
+
16
+ export class LambdaClientRequest extends Promise<APIGatewayProxyResult> {
17
+ event = createFakeEvent();
18
+ context = createFakeContext();
19
+
20
+ static call(lambdaName: string) {
21
+ const resolvers: any = {};
22
+ const promise = new LambdaClientRequest((resolve, reject) => {
23
+ resolvers.resolve = resolve;
24
+ resolvers.reject = reject;
25
+ });
26
+
27
+ promise.init(lambdaName, resolvers.resolve, resolvers.reject);
28
+
29
+ return promise;
30
+ }
31
+
32
+ static get(path: string, options: Partial<APIGatewayProxyEventBase<APIGatewayEventDefaultAuthorizerContext>> = {}) {
33
+ return this.call("handler").get(path, options);
34
+ }
35
+
36
+ static post(path: string, body?: any, options: Partial<APIGatewayProxyEventBase<APIGatewayEventDefaultAuthorizerContext>> = {}) {
37
+ return this.call("handler").post(path, body, options);
38
+ }
39
+
40
+ static put(path: string, body?: any, options: Partial<APIGatewayProxyEventBase<APIGatewayEventDefaultAuthorizerContext>> = {}) {
41
+ return this.call("handler").put(path, body, options);
42
+ }
43
+
44
+ static patch(path: string, body?: any, options: Partial<APIGatewayProxyEventBase<APIGatewayEventDefaultAuthorizerContext>> = {}) {
45
+ return this.call("handler").patch(path, body, options);
46
+ }
47
+
48
+ static delete(path: string, body?: any, options: Partial<APIGatewayProxyEventBase<APIGatewayEventDefaultAuthorizerContext>> = {}) {
49
+ return this.call("handler").delete(path, body, options);
50
+ }
51
+
52
+ get(path: string, options: Partial<APIGatewayProxyEventBase<APIGatewayEventDefaultAuthorizerContext>> = {}) {
53
+ Object.assign(this.event, options);
54
+
55
+ this.event.path = path;
56
+ this.event.httpMethod = "GET";
57
+
58
+ return this;
59
+ }
60
+
61
+ post(path: string, body: any = {}, options: Partial<APIGatewayProxyEventBase<APIGatewayEventDefaultAuthorizerContext>> = {}) {
62
+ Object.assign(this.event, options);
63
+
64
+ this.event.path = path;
65
+ this.event.httpMethod = "POST";
66
+
67
+ this.body(body);
68
+
69
+ return this;
70
+ }
71
+
72
+ patch(path: string, body: any = {}, options: Partial<APIGatewayProxyEventBase<APIGatewayEventDefaultAuthorizerContext>> = {}) {
73
+ Object.assign(this.event, options);
74
+
75
+ this.event.path = path;
76
+ this.event.httpMethod = "PATCH";
77
+
78
+ this.body(body);
79
+
80
+ return this;
81
+ }
82
+
83
+ put(path: string, body: any = {}, options: Partial<APIGatewayProxyEventBase<APIGatewayEventDefaultAuthorizerContext>> = {}) {
84
+ Object.assign(this.event, options);
85
+
86
+ this.event.path = path;
87
+ this.event.httpMethod = "PUT";
88
+
89
+ this.body(body);
90
+
91
+ return this;
92
+ }
93
+
94
+ delete(path: string, body: any = {}, options: Partial<APIGatewayProxyEventBase<APIGatewayEventDefaultAuthorizerContext>> = {}) {
95
+ Object.assign(this.event, options);
96
+
97
+ this.event.path = path;
98
+ this.event.httpMethod = "DELETE";
99
+
100
+ this.body(body);
101
+
102
+ return this;
103
+ }
104
+
105
+ query(query: any) {
106
+ this.event.queryStringParameters = {
107
+ ...this.event.queryStringParameters,
108
+ ...JSON.parse(JSON.stringify(query))
109
+ };
110
+
111
+ return this;
112
+ }
113
+
114
+ params(pathParameters: any) {
115
+ this.event.pathParameters = {
116
+ ...this.event.pathParameters,
117
+ ...JSON.parse(JSON.stringify(pathParameters))
118
+ };
119
+
120
+ return this;
121
+ }
122
+
123
+ headers(headers: Record<string, any>) {
124
+ this.event.headers = {
125
+ ...this.event.headers,
126
+ ...JSON.parse(JSON.stringify(headers))
127
+ };
128
+
129
+ return this;
130
+ }
131
+
132
+ body(body: any) {
133
+ if (body !== undefined) {
134
+ this.event.headers["content-type"] = "application/json";
135
+
136
+ this.event.body = JSON.stringify(body);
137
+ }
138
+
139
+ return this;
140
+ }
141
+
142
+ protected init(lambda: string, resolve: Function, reject: Function) {
143
+ setTimeout(async () => {
144
+ try {
145
+ const result = await PlatformServerlessTest.callbacks[lambda](this.event, this.context, resolve as any);
146
+ resolve(result as any);
147
+ } catch (er) {
148
+ reject(er);
149
+ }
150
+ });
151
+ }
152
+ }
153
+
154
+ export class PlatformServerlessTest extends DITest {
155
+ static callbacks: Record<string, APIGatewayProxyHandler> = {};
156
+ static instance: any;
157
+ static request = LambdaClientRequest;
158
+
159
+ static bootstrap(
160
+ serverless: {bootstrap: (server: Type<any>, settings: TsED.Configuration) => PlatformBuilder},
161
+ {server, ...settings}: PlatformBuilderSettings<any> & {server: Type<any>}
162
+ ): () => Promise<any>;
163
+ static bootstrap(
164
+ serverless: {bootstrap: (settings: Partial<TsED.Configuration> & {lambda?: Type[]}) => any},
165
+ {server, ...settings}: PlatformBuilderSettings<any>
166
+ ): () => Promise<any>;
167
+ static bootstrap(serverless: any, {server, ...settings}: PlatformBuilderSettings<any>) {
168
+ return function before(): Promise<void> {
169
+ settings = DITest.configure(settings);
170
+
171
+ const isServerlessHttp = nameOf(serverless).includes("Http");
172
+
173
+ // @ts-ignore
174
+ const instance = isServerlessHttp ? serverless.bootstrap(server, settings) : serverless.bootstrap(settings);
175
+
176
+ PlatformServerlessTest.instance = instance;
177
+ PlatformServerlessTest.callbacks = {};
178
+
179
+ if (!isServerlessHttp) {
180
+ PlatformServerlessTest.callbacks = instance.callbacks();
181
+ }
182
+
183
+ PlatformServerlessTest.callbacks.handler = instance.handler();
184
+
185
+ return instance.promise;
186
+ };
187
+ }
188
+
189
+ /**
190
+ * Resets the test injector of the test context, so it won't pollute your next test. Call this in your `tearDown` logic.
191
+ */
192
+ static async reset() {
193
+ if (PlatformServerlessTest.instance) {
194
+ await PlatformServerlessTest.instance.stop();
195
+ }
196
+
197
+ await destroyInjector();
198
+ }
199
+ }
@@ -0,0 +1,15 @@
1
+ import type {Context} from "aws-lambda";
2
+
3
+ export function createFakeContext(context?: Context): Context {
4
+ return {
5
+ awsRequestId: "awsRequestId",
6
+ callbackWaitsForEmptyEventLoop: false,
7
+ functionName: "",
8
+ functionVersion: "",
9
+ invokedFunctionArn: "",
10
+ logGroupName: "",
11
+ logStreamName: "",
12
+ memoryLimitInMB: "",
13
+ ...(context || {})
14
+ } as Context;
15
+ }
@@ -0,0 +1,32 @@
1
+ import type {APIGatewayEventDefaultAuthorizerContext, APIGatewayProxyEventBase} from "aws-lambda";
2
+
3
+ export function createFakeEvent(event: Partial<APIGatewayProxyEventBase<APIGatewayEventDefaultAuthorizerContext>> = {}) {
4
+ return {
5
+ body: "",
6
+ headers: {},
7
+ httpMethod: "",
8
+ isBase64Encoded: false,
9
+ multiValueHeaders: {},
10
+ multiValueQueryStringParameters: {},
11
+ path: event.path || "/",
12
+ pathParameters: {},
13
+ queryStringParameters: {},
14
+ resource: "",
15
+ stageVariables: {},
16
+ ...event,
17
+ requestContext: {
18
+ ...event?.requestContext,
19
+ accountId: "",
20
+ apiId: "",
21
+ protocol: "https",
22
+ httpMethod: "",
23
+ identity: {} as any,
24
+ path: event.path || "/",
25
+ stage: "",
26
+ requestId: "requestId",
27
+ requestTimeEpoch: 0,
28
+ resourceId: 1,
29
+ resourcePath: event.path || "/"
30
+ } as any
31
+ } as APIGatewayProxyEventBase<APIGatewayEventDefaultAuthorizerContext>;
32
+ }
package/src/index.ts ADDED
@@ -0,0 +1,3 @@
1
+ export * from "./createFakeContext.js";
2
+ export * from "./createFakeEvent.js";
3
+ export * from "./PlatformServerlessTest.js";