@middy/core 5.0.0-alpha.0 → 5.0.0-alpha.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/README.md +3 -2
- package/index.d.ts +120 -31
- package/index.js +55 -7
- package/package.json +6 -9
- package/index.cjs +0 -136
package/README.md
CHANGED
|
@@ -19,8 +19,9 @@
|
|
|
19
19
|
<a href="https://snyk.io/test/github/middyjs/middy">
|
|
20
20
|
<img src="https://snyk.io/test/github/middyjs/middy/badge.svg" alt="Known Vulnerabilities" data-canonical-src="https://snyk.io/test/github/middyjs/middy" style="max-width:100%;">
|
|
21
21
|
</a>
|
|
22
|
-
<a href="https://
|
|
23
|
-
<img src="https://
|
|
22
|
+
<a href="https://github.com/middyjs/middy/actions/workflows/sast.yml">
|
|
23
|
+
<img src="https://github.com/middyjs/middy/actions/workflows/sast.yml/badge.svg
|
|
24
|
+
?branch=main&event=push" alt="CodeQL" style="max-width:100%;">
|
|
24
25
|
</a>
|
|
25
26
|
<a href="https://bestpractices.coreinfrastructure.org/projects/5280">
|
|
26
27
|
<img src="https://bestpractices.coreinfrastructure.org/projects/5280/badge" alt="Core Infrastructure Initiative (CII) Best Practices" style="max-width:100%;">
|
package/index.d.ts
CHANGED
|
@@ -6,7 +6,9 @@ import {
|
|
|
6
6
|
|
|
7
7
|
declare type PluginHook = () => void
|
|
8
8
|
declare type PluginHookWithMiddlewareName = (middlewareName: string) => void
|
|
9
|
-
declare type PluginHookPromise = (
|
|
9
|
+
declare type PluginHookPromise = (
|
|
10
|
+
request: Request
|
|
11
|
+
) => Promise<unknown> | unknown
|
|
10
12
|
|
|
11
13
|
interface PluginObject {
|
|
12
14
|
internal?: any
|
|
@@ -19,62 +21,149 @@ interface PluginObject {
|
|
|
19
21
|
timeoutEarlyResponse?: PluginHook
|
|
20
22
|
afterHandler?: PluginHook
|
|
21
23
|
requestEnd?: PluginHookPromise
|
|
24
|
+
streamifyResponse?: Boolean
|
|
22
25
|
}
|
|
23
26
|
|
|
24
|
-
export interface Request<
|
|
27
|
+
export interface Request<
|
|
28
|
+
TEvent = any,
|
|
29
|
+
TResult = any,
|
|
30
|
+
TErr = Error,
|
|
31
|
+
TContext extends LambdaContext = LambdaContext,
|
|
32
|
+
TInternal extends Record<string, unknown> = {}
|
|
33
|
+
> {
|
|
25
34
|
event: TEvent
|
|
26
35
|
context: TContext
|
|
27
36
|
response: TResult | null
|
|
28
37
|
error: TErr | null
|
|
29
|
-
internal:
|
|
30
|
-
[key: string]: any
|
|
31
|
-
}
|
|
38
|
+
internal: TInternal
|
|
32
39
|
}
|
|
33
40
|
|
|
34
|
-
declare type MiddlewareFn<
|
|
41
|
+
declare type MiddlewareFn<
|
|
42
|
+
TEvent = any,
|
|
43
|
+
TResult = any,
|
|
44
|
+
TErr = Error,
|
|
45
|
+
TContext extends LambdaContext = LambdaContext,
|
|
46
|
+
TInternal extends Record<string, unknown> = {}
|
|
47
|
+
> = (request: Request<TEvent, TResult, TErr, TContext, TInternal>) => any
|
|
35
48
|
|
|
36
|
-
export interface MiddlewareObj<
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
49
|
+
export interface MiddlewareObj<
|
|
50
|
+
TEvent = unknown,
|
|
51
|
+
TResult = any,
|
|
52
|
+
TErr = Error,
|
|
53
|
+
TContext extends LambdaContext = LambdaContext,
|
|
54
|
+
TInternal extends Record<string, unknown> = {}
|
|
55
|
+
> {
|
|
56
|
+
before?: MiddlewareFn<TEvent, TResult, TErr, TContext, TInternal>
|
|
57
|
+
after?: MiddlewareFn<TEvent, TResult, TErr, TContext, TInternal>
|
|
58
|
+
onError?: MiddlewareFn<TEvent, TResult, TErr, TContext, TInternal>
|
|
40
59
|
}
|
|
41
60
|
|
|
42
61
|
// The AWS provided Handler type uses void | Promise<TResult> so we have no choice but to follow and suppress the linter warning
|
|
43
62
|
// eslint-disable-next-line @typescript-eslint/no-invalid-void-type
|
|
44
|
-
type MiddyInputHandler<
|
|
45
|
-
|
|
63
|
+
type MiddyInputHandler<
|
|
64
|
+
TEvent,
|
|
65
|
+
TResult,
|
|
66
|
+
TContext extends LambdaContext = LambdaContext
|
|
67
|
+
> = (
|
|
68
|
+
event: TEvent,
|
|
69
|
+
context: TContext,
|
|
70
|
+
callback: LambdaCallback<TResult>
|
|
71
|
+
) => // eslint-disable-next-line @typescript-eslint/no-invalid-void-type
|
|
72
|
+
void | Promise<TResult> | TResult
|
|
73
|
+
type MiddyInputPromiseHandler<
|
|
74
|
+
TEvent,
|
|
75
|
+
TResult,
|
|
76
|
+
TContext extends LambdaContext = LambdaContext
|
|
77
|
+
> = (event: TEvent, context: TContext) => Promise<TResult>
|
|
46
78
|
|
|
47
|
-
export interface MiddyfiedHandler<
|
|
79
|
+
export interface MiddyfiedHandler<
|
|
80
|
+
TEvent = any,
|
|
81
|
+
TResult = any,
|
|
82
|
+
TErr = Error,
|
|
83
|
+
TContext extends LambdaContext = LambdaContext,
|
|
84
|
+
TInternal extends Record<string, unknown> = {}
|
|
85
|
+
> extends MiddyInputHandler<TEvent, TResult, TContext>,
|
|
48
86
|
MiddyInputPromiseHandler<TEvent, TResult, TContext> {
|
|
49
|
-
use: UseFn<TEvent, TResult, TErr, TContext>
|
|
50
|
-
before: AttachMiddlewareFn<TEvent, TResult, TErr, TContext>
|
|
51
|
-
after: AttachMiddlewareFn<TEvent, TResult, TErr, TContext>
|
|
52
|
-
onError: AttachMiddlewareFn<TEvent, TResult, TErr, TContext>
|
|
53
|
-
handler: <TAdditional>(
|
|
87
|
+
use: UseFn<TEvent, TResult, TErr, TContext, TInternal>
|
|
88
|
+
before: AttachMiddlewareFn<TEvent, TResult, TErr, TContext, TInternal>
|
|
89
|
+
after: AttachMiddlewareFn<TEvent, TResult, TErr, TContext, TInternal>
|
|
90
|
+
onError: AttachMiddlewareFn<TEvent, TResult, TErr, TContext, TInternal>
|
|
91
|
+
handler: <TAdditional>(
|
|
92
|
+
handler: MiddlewareHandler<
|
|
93
|
+
LambdaHandler<TEvent & TAdditional, TResult>,
|
|
94
|
+
TContext
|
|
95
|
+
>
|
|
96
|
+
) => MiddyfiedHandler<TEvent, TResult, TErr, TContext, TInternal>
|
|
54
97
|
}
|
|
55
98
|
|
|
56
|
-
declare type AttachMiddlewareFn<
|
|
57
|
-
|
|
99
|
+
declare type AttachMiddlewareFn<
|
|
100
|
+
TEvent = any,
|
|
101
|
+
TResult = any,
|
|
102
|
+
TErr = Error,
|
|
103
|
+
TContext extends LambdaContext = LambdaContext,
|
|
104
|
+
TInternal extends Record<string, unknown> = {}
|
|
105
|
+
> = (
|
|
106
|
+
middleware: MiddlewareFn<TEvent, TResult, TErr, TContext, TInternal>
|
|
107
|
+
) => MiddyfiedHandler<TEvent, TResult, TErr, TContext, TInternal>
|
|
58
108
|
|
|
59
|
-
declare type AttachMiddlewareObj<
|
|
60
|
-
|
|
109
|
+
declare type AttachMiddlewareObj<
|
|
110
|
+
TEvent = any,
|
|
111
|
+
TResult = any,
|
|
112
|
+
TErr = Error,
|
|
113
|
+
TContext extends LambdaContext = LambdaContext,
|
|
114
|
+
TInternal extends Record<string, unknown> = {}
|
|
115
|
+
> = (
|
|
116
|
+
middleware: MiddlewareObj<TEvent, TResult, TErr, TContext, TInternal>
|
|
117
|
+
) => MiddyfiedHandler<TEvent, TResult, TErr, TContext, TInternal>
|
|
61
118
|
|
|
62
|
-
declare type UseFn<
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
119
|
+
declare type UseFn<
|
|
120
|
+
TEvent = any,
|
|
121
|
+
TResult = any,
|
|
122
|
+
TErr = Error,
|
|
123
|
+
TContext extends LambdaContext = LambdaContext,
|
|
124
|
+
TInternal extends Record<string, unknown> = {}
|
|
125
|
+
> = <TMiddleware extends MiddlewareObj<any, any, Error, any, any>>(
|
|
126
|
+
middlewares: TMiddleware | TMiddleware[]
|
|
127
|
+
) => TMiddleware extends MiddlewareObj<
|
|
128
|
+
infer TMiddlewareEvent,
|
|
129
|
+
any,
|
|
130
|
+
Error,
|
|
131
|
+
infer TMiddlewareContext,
|
|
132
|
+
infer TMiddlewareInternal
|
|
133
|
+
>
|
|
134
|
+
? MiddyfiedHandler<
|
|
135
|
+
TMiddlewareEvent & TEvent,
|
|
136
|
+
TResult,
|
|
137
|
+
TErr,
|
|
138
|
+
TMiddlewareContext & TContext,
|
|
139
|
+
TMiddlewareInternal & TInternal
|
|
140
|
+
> // always true
|
|
141
|
+
: never
|
|
66
142
|
|
|
67
|
-
declare type MiddlewareHandler<
|
|
68
|
-
THandler extends LambdaHandler<
|
|
69
|
-
|
|
70
|
-
|
|
143
|
+
declare type MiddlewareHandler<
|
|
144
|
+
THandler extends LambdaHandler<any, any>,
|
|
145
|
+
TContext extends LambdaContext = LambdaContext
|
|
146
|
+
> = THandler extends LambdaHandler<infer TEvent, infer TResult> // always true
|
|
147
|
+
? MiddyInputHandler<TEvent, TResult, TContext>
|
|
148
|
+
: never
|
|
71
149
|
|
|
72
150
|
/**
|
|
73
151
|
* Middy factory function. Use it to wrap your existing handler to enable middlewares on it.
|
|
74
152
|
* @param handler your original AWS Lambda function
|
|
75
153
|
* @param plugin wraps around each middleware and handler to add custom lifecycle behaviours (e.g. to profile performance)
|
|
76
154
|
*/
|
|
77
|
-
declare function middy<
|
|
155
|
+
declare function middy<
|
|
156
|
+
TEvent = unknown,
|
|
157
|
+
TResult = any,
|
|
158
|
+
TErr = Error,
|
|
159
|
+
TContext extends LambdaContext = LambdaContext,
|
|
160
|
+
TInternal extends Record<string, unknown> = {}
|
|
161
|
+
> (
|
|
162
|
+
handler?:
|
|
163
|
+
| MiddlewareHandler<LambdaHandler<TEvent, TResult>, TContext>
|
|
164
|
+
| PluginObject,
|
|
165
|
+
plugin?: PluginObject
|
|
166
|
+
): MiddyfiedHandler<TEvent, TResult, TErr, TContext, TInternal>
|
|
78
167
|
|
|
79
168
|
declare namespace middy {
|
|
80
169
|
export {
|
package/index.js
CHANGED
|
@@ -1,12 +1,22 @@
|
|
|
1
|
+
/* global awslambda */ import { Readable } from 'node:stream';
|
|
2
|
+
import { pipeline } from 'node:stream/promises';
|
|
1
3
|
import { setTimeout } from 'node:timers/promises';
|
|
2
4
|
const defaultLambdaHandler = ()=>{};
|
|
3
5
|
const defaultPlugin = {
|
|
4
6
|
timeoutEarlyInMillis: 5,
|
|
5
7
|
timeoutEarlyResponse: ()=>{
|
|
6
|
-
|
|
7
|
-
|
|
8
|
+
const err = new Error('[AbortError]: The operation was aborted.', {
|
|
9
|
+
cause: {
|
|
10
|
+
package: '@middy/core'
|
|
11
|
+
}
|
|
12
|
+
});
|
|
13
|
+
err.name = 'TimeoutError';
|
|
14
|
+
throw err;
|
|
15
|
+
},
|
|
16
|
+
streamifyResponse: false // Deprecate need for this when AWS provides a flag for when it's looking for it
|
|
8
17
|
};
|
|
9
18
|
const middy = (lambdaHandler = defaultLambdaHandler, plugin = {})=>{
|
|
19
|
+
// Allow base handler to be set using .handler()
|
|
10
20
|
if (typeof lambdaHandler !== 'function') {
|
|
11
21
|
plugin = lambdaHandler;
|
|
12
22
|
lambdaHandler = defaultLambdaHandler;
|
|
@@ -20,7 +30,7 @@ const middy = (lambdaHandler = defaultLambdaHandler, plugin = {})=>{
|
|
|
20
30
|
const beforeMiddlewares = [];
|
|
21
31
|
const afterMiddlewares = [];
|
|
22
32
|
const onErrorMiddlewares = [];
|
|
23
|
-
const
|
|
33
|
+
const middyHandler = (event = {}, context = {})=>{
|
|
24
34
|
plugin.requestStart?.();
|
|
25
35
|
const request = {
|
|
26
36
|
event,
|
|
@@ -37,6 +47,35 @@ const middy = (lambdaHandler = defaultLambdaHandler, plugin = {})=>{
|
|
|
37
47
|
...onErrorMiddlewares
|
|
38
48
|
], plugin);
|
|
39
49
|
};
|
|
50
|
+
const middy = plugin.streamifyResponse ? awslambda.streamifyResponse(async (event, responseStream, context)=>{
|
|
51
|
+
const handlerResponse = await middyHandler(event, context);
|
|
52
|
+
let handlerBody = handlerResponse;
|
|
53
|
+
if (handlerResponse.statusCode) {
|
|
54
|
+
handlerBody = handlerResponse.body ?? '';
|
|
55
|
+
responseStream = awslambda.HttpResponseStream.from(responseStream, handlerResponse);
|
|
56
|
+
}
|
|
57
|
+
// Source @datastream/core (MIT)
|
|
58
|
+
let handlerStream;
|
|
59
|
+
if (handlerBody._readableState) {
|
|
60
|
+
handlerStream = handlerBody;
|
|
61
|
+
} else if (typeof handlerBody === 'string') {
|
|
62
|
+
function* iterator(input) {
|
|
63
|
+
const size = 16384 // 16 * 1024 // Node.js default
|
|
64
|
+
;
|
|
65
|
+
let position = 0;
|
|
66
|
+
const length = input.length;
|
|
67
|
+
while(position < length){
|
|
68
|
+
yield input.substring(position, position + size);
|
|
69
|
+
position += size;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
handlerStream = Readable.from(iterator(handlerBody));
|
|
73
|
+
}
|
|
74
|
+
if (!handlerStream) {
|
|
75
|
+
throw new Error('handler response not a ReadableStream');
|
|
76
|
+
}
|
|
77
|
+
await pipeline(handlerStream, responseStream);
|
|
78
|
+
}) : middyHandler;
|
|
40
79
|
middy.use = (middlewares)=>{
|
|
41
80
|
if (!Array.isArray(middlewares)) {
|
|
42
81
|
middlewares = [
|
|
@@ -44,7 +83,7 @@ const middy = (lambdaHandler = defaultLambdaHandler, plugin = {})=>{
|
|
|
44
83
|
];
|
|
45
84
|
}
|
|
46
85
|
for (const middleware of middlewares){
|
|
47
|
-
const { before
|
|
86
|
+
const { before, after, onError } = middleware;
|
|
48
87
|
if (!before && !after && !onError) {
|
|
49
88
|
throw new Error('Middleware must be an object containing at least one key among "before", "after", "onError"');
|
|
50
89
|
}
|
|
@@ -54,6 +93,7 @@ const middy = (lambdaHandler = defaultLambdaHandler, plugin = {})=>{
|
|
|
54
93
|
}
|
|
55
94
|
return middy;
|
|
56
95
|
};
|
|
96
|
+
// Inline Middlewares
|
|
57
97
|
middy.before = (beforeMiddleware)=>{
|
|
58
98
|
beforeMiddlewares.push(beforeMiddleware);
|
|
59
99
|
return middy;
|
|
@@ -74,9 +114,11 @@ const middy = (lambdaHandler = defaultLambdaHandler, plugin = {})=>{
|
|
|
74
114
|
};
|
|
75
115
|
const runRequest = async (request, beforeMiddlewares, lambdaHandler, afterMiddlewares, onErrorMiddlewares, plugin)=>{
|
|
76
116
|
let timeoutAbort;
|
|
77
|
-
const timeoutEarly = plugin.timeoutEarly && request.context.getRemainingTimeInMillis
|
|
117
|
+
const timeoutEarly = plugin.timeoutEarly && request.context.getRemainingTimeInMillis // disable when AWS context missing (tests, containers)
|
|
118
|
+
;
|
|
78
119
|
try {
|
|
79
120
|
await runMiddlewares(request, beforeMiddlewares, plugin);
|
|
121
|
+
// Check if before stack hasn't exit early
|
|
80
122
|
if (typeof request.response === 'undefined') {
|
|
81
123
|
plugin.beforeHandler?.();
|
|
82
124
|
const handlerAbort = new AbortController();
|
|
@@ -92,21 +134,26 @@ const runRequest = async (request, beforeMiddlewares, lambdaHandler, afterMiddle
|
|
|
92
134
|
return plugin.timeoutEarlyResponse();
|
|
93
135
|
}) : Promise.race([])
|
|
94
136
|
]);
|
|
95
|
-
timeoutAbort?.abort()
|
|
137
|
+
timeoutAbort?.abort() // lambdaHandler may not be a promise
|
|
138
|
+
;
|
|
96
139
|
plugin.afterHandler?.();
|
|
97
140
|
await runMiddlewares(request, afterMiddlewares, plugin);
|
|
98
141
|
}
|
|
99
142
|
} catch (e) {
|
|
100
|
-
timeoutAbort?.abort()
|
|
143
|
+
timeoutAbort?.abort() // timeout should be aborted on errors
|
|
144
|
+
;
|
|
145
|
+
// Reset response changes made by after stack before error thrown
|
|
101
146
|
request.response = undefined;
|
|
102
147
|
request.error = e;
|
|
103
148
|
try {
|
|
104
149
|
await runMiddlewares(request, onErrorMiddlewares, plugin);
|
|
105
150
|
} catch (e) {
|
|
151
|
+
// Save error that wasn't handled
|
|
106
152
|
e.originalError = request.error;
|
|
107
153
|
request.error = e;
|
|
108
154
|
throw request.error;
|
|
109
155
|
}
|
|
156
|
+
// Catch if onError stack hasn't handled the error
|
|
110
157
|
if (typeof request.response === 'undefined') throw request.error;
|
|
111
158
|
} finally{
|
|
112
159
|
await plugin.requestEnd?.(request);
|
|
@@ -118,6 +165,7 @@ const runMiddlewares = async (request, middlewares, plugin)=>{
|
|
|
118
165
|
plugin.beforeMiddleware?.(nextMiddleware.name);
|
|
119
166
|
const res = await nextMiddleware(request);
|
|
120
167
|
plugin.afterMiddleware?.(nextMiddleware.name);
|
|
168
|
+
// short circuit chaining and respond early
|
|
121
169
|
if (typeof res !== 'undefined') {
|
|
122
170
|
request.response = res;
|
|
123
171
|
return;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@middy/core",
|
|
3
|
-
"version": "5.0.0-alpha.
|
|
3
|
+
"version": "5.0.0-alpha.2",
|
|
4
4
|
"description": "🛵 The stylish Node.js middleware engine for AWS Lambda (core package)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
@@ -10,24 +10,18 @@
|
|
|
10
10
|
"publishConfig": {
|
|
11
11
|
"access": "public"
|
|
12
12
|
},
|
|
13
|
-
"main": "./index.cjs",
|
|
14
13
|
"module": "./index.js",
|
|
15
14
|
"exports": {
|
|
16
15
|
".": {
|
|
17
16
|
"import": {
|
|
18
17
|
"types": "./index.d.ts",
|
|
19
18
|
"default": "./index.js"
|
|
20
|
-
},
|
|
21
|
-
"require": {
|
|
22
|
-
"types": "./index.d.ts",
|
|
23
|
-
"default": "./index.cjs"
|
|
24
19
|
}
|
|
25
20
|
}
|
|
26
21
|
},
|
|
27
22
|
"types": "index.d.ts",
|
|
28
23
|
"files": [
|
|
29
24
|
"index.js",
|
|
30
|
-
"index.cjs",
|
|
31
25
|
"index.d.ts"
|
|
32
26
|
],
|
|
33
27
|
"scripts": {
|
|
@@ -63,7 +57,10 @@
|
|
|
63
57
|
},
|
|
64
58
|
"devDependencies": {
|
|
65
59
|
"@types/aws-lambda": "^8.10.76",
|
|
66
|
-
"@types/node": "^
|
|
60
|
+
"@types/node": "^20.0.0"
|
|
67
61
|
},
|
|
68
|
-
"gitHead": "
|
|
62
|
+
"gitHead": "ebce8d5df8783077fa49ba62ee9be20e8486a7f1",
|
|
63
|
+
"dependencies": {
|
|
64
|
+
"@datastream/core": "0.0.35"
|
|
65
|
+
}
|
|
69
66
|
}
|
package/index.cjs
DELETED
|
@@ -1,136 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", {
|
|
3
|
-
value: true
|
|
4
|
-
});
|
|
5
|
-
Object.defineProperty(module, "exports", {
|
|
6
|
-
enumerable: true,
|
|
7
|
-
get: ()=>_default
|
|
8
|
-
});
|
|
9
|
-
const _promises = require("node:timers/promises");
|
|
10
|
-
const defaultLambdaHandler = ()=>{};
|
|
11
|
-
const defaultPlugin = {
|
|
12
|
-
timeoutEarlyInMillis: 5,
|
|
13
|
-
timeoutEarlyResponse: ()=>{
|
|
14
|
-
throw new Error('Timeout');
|
|
15
|
-
}
|
|
16
|
-
};
|
|
17
|
-
const middy = (lambdaHandler = defaultLambdaHandler, plugin = {})=>{
|
|
18
|
-
if (typeof lambdaHandler !== 'function') {
|
|
19
|
-
plugin = lambdaHandler;
|
|
20
|
-
lambdaHandler = defaultLambdaHandler;
|
|
21
|
-
}
|
|
22
|
-
plugin = {
|
|
23
|
-
...defaultPlugin,
|
|
24
|
-
...plugin
|
|
25
|
-
};
|
|
26
|
-
plugin.timeoutEarly = plugin.timeoutEarlyInMillis > 0;
|
|
27
|
-
plugin.beforePrefetch?.();
|
|
28
|
-
const beforeMiddlewares = [];
|
|
29
|
-
const afterMiddlewares = [];
|
|
30
|
-
const onErrorMiddlewares = [];
|
|
31
|
-
const middy = (event = {}, context = {})=>{
|
|
32
|
-
plugin.requestStart?.();
|
|
33
|
-
const request = {
|
|
34
|
-
event,
|
|
35
|
-
context,
|
|
36
|
-
response: undefined,
|
|
37
|
-
error: undefined,
|
|
38
|
-
internal: plugin.internal ?? {}
|
|
39
|
-
};
|
|
40
|
-
return runRequest(request, [
|
|
41
|
-
...beforeMiddlewares
|
|
42
|
-
], lambdaHandler, [
|
|
43
|
-
...afterMiddlewares
|
|
44
|
-
], [
|
|
45
|
-
...onErrorMiddlewares
|
|
46
|
-
], plugin);
|
|
47
|
-
};
|
|
48
|
-
middy.use = (middlewares)=>{
|
|
49
|
-
if (!Array.isArray(middlewares)) {
|
|
50
|
-
middlewares = [
|
|
51
|
-
middlewares
|
|
52
|
-
];
|
|
53
|
-
}
|
|
54
|
-
for (const middleware of middlewares){
|
|
55
|
-
const { before , after , onError } = middleware;
|
|
56
|
-
if (!before && !after && !onError) {
|
|
57
|
-
throw new Error('Middleware must be an object containing at least one key among "before", "after", "onError"');
|
|
58
|
-
}
|
|
59
|
-
if (before) middy.before(before);
|
|
60
|
-
if (after) middy.after(after);
|
|
61
|
-
if (onError) middy.onError(onError);
|
|
62
|
-
}
|
|
63
|
-
return middy;
|
|
64
|
-
};
|
|
65
|
-
middy.before = (beforeMiddleware)=>{
|
|
66
|
-
beforeMiddlewares.push(beforeMiddleware);
|
|
67
|
-
return middy;
|
|
68
|
-
};
|
|
69
|
-
middy.after = (afterMiddleware)=>{
|
|
70
|
-
afterMiddlewares.unshift(afterMiddleware);
|
|
71
|
-
return middy;
|
|
72
|
-
};
|
|
73
|
-
middy.onError = (onErrorMiddleware)=>{
|
|
74
|
-
onErrorMiddlewares.unshift(onErrorMiddleware);
|
|
75
|
-
return middy;
|
|
76
|
-
};
|
|
77
|
-
middy.handler = (replaceLambdaHandler)=>{
|
|
78
|
-
lambdaHandler = replaceLambdaHandler;
|
|
79
|
-
return middy;
|
|
80
|
-
};
|
|
81
|
-
return middy;
|
|
82
|
-
};
|
|
83
|
-
const runRequest = async (request, beforeMiddlewares, lambdaHandler, afterMiddlewares, onErrorMiddlewares, plugin)=>{
|
|
84
|
-
let timeoutAbort;
|
|
85
|
-
const timeoutEarly = plugin.timeoutEarly && request.context.getRemainingTimeInMillis;
|
|
86
|
-
try {
|
|
87
|
-
await runMiddlewares(request, beforeMiddlewares, plugin);
|
|
88
|
-
if (typeof request.response === 'undefined') {
|
|
89
|
-
plugin.beforeHandler?.();
|
|
90
|
-
const handlerAbort = new AbortController();
|
|
91
|
-
if (timeoutEarly) timeoutAbort = new AbortController();
|
|
92
|
-
request.response = await Promise.race([
|
|
93
|
-
lambdaHandler(request.event, request.context, {
|
|
94
|
-
signal: handlerAbort.signal
|
|
95
|
-
}),
|
|
96
|
-
timeoutEarly ? (0, _promises.setTimeout)(request.context.getRemainingTimeInMillis() - plugin.timeoutEarlyInMillis, undefined, {
|
|
97
|
-
signal: timeoutAbort.signal
|
|
98
|
-
}).then(()=>{
|
|
99
|
-
handlerAbort.abort();
|
|
100
|
-
return plugin.timeoutEarlyResponse();
|
|
101
|
-
}) : Promise.race([])
|
|
102
|
-
]);
|
|
103
|
-
timeoutAbort?.abort();
|
|
104
|
-
plugin.afterHandler?.();
|
|
105
|
-
await runMiddlewares(request, afterMiddlewares, plugin);
|
|
106
|
-
}
|
|
107
|
-
} catch (e) {
|
|
108
|
-
timeoutAbort?.abort();
|
|
109
|
-
request.response = undefined;
|
|
110
|
-
request.error = e;
|
|
111
|
-
try {
|
|
112
|
-
await runMiddlewares(request, onErrorMiddlewares, plugin);
|
|
113
|
-
} catch (e) {
|
|
114
|
-
e.originalError = request.error;
|
|
115
|
-
request.error = e;
|
|
116
|
-
throw request.error;
|
|
117
|
-
}
|
|
118
|
-
if (typeof request.response === 'undefined') throw request.error;
|
|
119
|
-
} finally{
|
|
120
|
-
await plugin.requestEnd?.(request);
|
|
121
|
-
}
|
|
122
|
-
return request.response;
|
|
123
|
-
};
|
|
124
|
-
const runMiddlewares = async (request, middlewares, plugin)=>{
|
|
125
|
-
for (const nextMiddleware of middlewares){
|
|
126
|
-
plugin.beforeMiddleware?.(nextMiddleware.name);
|
|
127
|
-
const res = await nextMiddleware(request);
|
|
128
|
-
plugin.afterMiddleware?.(nextMiddleware.name);
|
|
129
|
-
if (typeof res !== 'undefined') {
|
|
130
|
-
request.response = res;
|
|
131
|
-
return;
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
};
|
|
135
|
-
const _default = middy;
|
|
136
|
-
|