@middy/core 6.1.6 → 6.2.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.
Files changed (3) hide show
  1. package/index.d.ts +157 -147
  2. package/index.js +245 -236
  3. package/package.json +64 -67
package/index.d.ts CHANGED
@@ -1,169 +1,174 @@
1
- import { Context as LambdaContext, Handler as LambdaHandler } from 'aws-lambda'
1
+ import type {
2
+ Context as LambdaContext,
3
+ Handler as LambdaHandler,
4
+ } from "aws-lambda";
2
5
 
3
- declare type PluginHook = () => void
4
- declare type PluginHookWithMiddlewareName = (middlewareName: string) => void
6
+ declare type PluginHook = () => undefined;
7
+ declare type PluginHookWithMiddlewareName = (
8
+ middlewareName: string,
9
+ ) => undefined;
5
10
  declare type PluginHookPromise = (
6
- request: Request
7
- ) => Promise<unknown> | unknown
11
+ request: Request,
12
+ ) => Promise<unknown> | unknown;
8
13
 
9
14
  interface PluginObject {
10
- internal?: any
11
- beforePrefetch?: PluginHook
12
- requestStart?: PluginHook
13
- beforeMiddleware?: PluginHookWithMiddlewareName
14
- afterMiddleware?: PluginHookWithMiddlewareName
15
- beforeHandler?: PluginHook
16
- timeoutEarlyInMillis?: number
17
- timeoutEarlyResponse?: PluginHook
18
- afterHandler?: PluginHook
19
- requestEnd?: PluginHookPromise
20
- streamifyResponse?: Boolean
15
+ internal?: any;
16
+ beforePrefetch?: PluginHook;
17
+ requestStart?: PluginHook;
18
+ beforeMiddleware?: PluginHookWithMiddlewareName;
19
+ afterMiddleware?: PluginHookWithMiddlewareName;
20
+ beforeHandler?: PluginHook;
21
+ timeoutEarlyInMillis?: number;
22
+ timeoutEarlyResponse?: PluginHook;
23
+ afterHandler?: PluginHook;
24
+ requestEnd?: PluginHookPromise;
25
+ streamifyResponse?: boolean;
21
26
  }
22
27
 
23
28
  export interface Request<
24
- TEvent = any,
25
- TResult = any,
26
- TErr = Error,
27
- TContext extends LambdaContext = LambdaContext,
28
- TInternal extends Record<string, unknown> = {}
29
+ TEvent = any,
30
+ TResult = any,
31
+ TErr = Error,
32
+ TContext extends LambdaContext = LambdaContext,
33
+ TInternal extends Record<string, unknown> = {},
29
34
  > {
30
- event: TEvent
31
- context: TContext
32
- response: TResult | null
33
- earlyResponse?: TResult | null | undefined
34
- error: TErr | null
35
- internal: TInternal
35
+ event: TEvent;
36
+ context: TContext;
37
+ response: TResult | null;
38
+ earlyResponse?: TResult | null | undefined;
39
+ error: TErr | null;
40
+ internal: TInternal;
36
41
  }
37
42
 
38
43
  declare type MiddlewareFn<
39
- TEvent = any,
40
- TResult = any,
41
- TErr = Error,
42
- TContext extends LambdaContext = LambdaContext,
43
- TInternal extends Record<string, unknown> = {}
44
- > = (request: Request<TEvent, TResult, TErr, TContext, TInternal>) => any
44
+ TEvent = any,
45
+ TResult = any,
46
+ TErr = Error,
47
+ TContext extends LambdaContext = LambdaContext,
48
+ TInternal extends Record<string, unknown> = {},
49
+ > = (request: Request<TEvent, TResult, TErr, TContext, TInternal>) => any;
45
50
 
46
51
  export interface MiddlewareObj<
47
- TEvent = unknown,
48
- TResult = any,
49
- TErr = Error,
50
- TContext extends LambdaContext = LambdaContext,
51
- TInternal extends Record<string, unknown> = {}
52
+ TEvent = unknown,
53
+ TResult = any,
54
+ TErr = Error,
55
+ TContext extends LambdaContext = LambdaContext,
56
+ TInternal extends Record<string, unknown> = {},
52
57
  > {
53
- before?: MiddlewareFn<TEvent, TResult, TErr, TContext, TInternal>
54
- after?: MiddlewareFn<TEvent, TResult, TErr, TContext, TInternal>
55
- onError?: MiddlewareFn<TEvent, TResult, TErr, TContext, TInternal>
56
- name?: string
58
+ before?: MiddlewareFn<TEvent, TResult, TErr, TContext, TInternal>;
59
+ after?: MiddlewareFn<TEvent, TResult, TErr, TContext, TInternal>;
60
+ onError?: MiddlewareFn<TEvent, TResult, TErr, TContext, TInternal>;
61
+ name?: string;
57
62
  }
58
63
 
59
64
  export interface MiddyHandlerObject {
60
- /**
61
- * An abort signal that will be canceled just before the lambda times out.
62
- * @see timeoutEarlyInMillis
63
- */
64
- signal: AbortSignal
65
+ /**
66
+ * An abort signal that will be canceled just before the lambda times out.
67
+ * @see timeoutEarlyInMillis
68
+ */
69
+ signal: AbortSignal;
65
70
  }
66
71
 
67
72
  // The AWS provided Handler type uses void | Promise<TResult> so we have no choice but to follow and suppress the linter warning
68
73
  // eslint-disable-next-line @typescript-eslint/no-invalid-void-type
69
74
  type MiddyInputHandler<
70
- TEvent,
71
- TResult,
72
- TContext extends LambdaContext = LambdaContext
75
+ TEvent,
76
+ TResult,
77
+ TContext extends LambdaContext = LambdaContext,
73
78
  > = (
74
- event: TEvent,
75
- context: TContext,
76
- opts: MiddyHandlerObject
77
- ) => // eslint-disable-next-line @typescript-eslint/no-invalid-void-type
78
- void | Promise<TResult> | TResult
79
+ event: TEvent,
80
+ context: TContext,
81
+ opts: MiddyHandlerObject,
82
+ ) => undefined | Promise<TResult> | TResult; // eslint-disable-next-line @typescript-eslint/no-invalid-void-type
79
83
  type MiddyInputPromiseHandler<
80
- TEvent,
81
- TResult,
82
- TContext extends LambdaContext = LambdaContext
83
- > = (event: TEvent, context: TContext) => Promise<TResult>
84
+ TEvent,
85
+ TResult,
86
+ TContext extends LambdaContext = LambdaContext,
87
+ > = (event: TEvent, context: TContext) => Promise<TResult>;
84
88
 
85
89
  export interface MiddyfiedHandler<
86
- TEvent = any,
87
- TResult = any,
88
- TErr = Error,
89
- TContext extends LambdaContext = LambdaContext,
90
- TInternal extends Record<string, unknown> = {}
90
+ TEvent = any,
91
+ TResult = any,
92
+ TErr = Error,
93
+ TContext extends LambdaContext = LambdaContext,
94
+ TInternal extends Record<string, unknown> = {},
91
95
  > extends MiddyInputHandler<TEvent, TResult, TContext>,
92
- MiddyInputPromiseHandler<TEvent, TResult, TContext> {
93
- use: UseFn<TEvent, TResult, TErr, TContext, TInternal>
94
- before: AttachMiddlewareFn<TEvent, TResult, TErr, TContext, TInternal>
95
- after: AttachMiddlewareFn<TEvent, TResult, TErr, TContext, TInternal>
96
- onError: AttachMiddlewareFn<TEvent, TResult, TErr, TContext, TInternal>
97
- handler: <
98
- TInputHandlerEventProps = TEvent,
99
- TInputHandlerResultProps = TResult
100
- >(
101
- handler: MiddlewareHandler<
102
- LambdaHandler<TInputHandlerEventProps, TInputHandlerResultProps>,
103
- TContext,
104
- TResult
105
- >
106
- ) => MiddyfiedHandler<
107
- TInputHandlerEventProps,
108
- TInputHandlerResultProps,
109
- TErr,
110
- TContext,
111
- TInternal
112
- >
96
+ MiddyInputPromiseHandler<TEvent, TResult, TContext> {
97
+ use: UseFn<TEvent, TResult, TErr, TContext, TInternal>;
98
+ before: AttachMiddlewareFn<TEvent, TResult, TErr, TContext, TInternal>;
99
+ after: AttachMiddlewareFn<TEvent, TResult, TErr, TContext, TInternal>;
100
+ onError: AttachMiddlewareFn<TEvent, TResult, TErr, TContext, TInternal>;
101
+ handler: <
102
+ TInputHandlerEventProps = TEvent,
103
+ TInputHandlerResultProps = TResult,
104
+ >(
105
+ handler: MiddlewareHandler<
106
+ LambdaHandler<TInputHandlerEventProps, TInputHandlerResultProps>,
107
+ TContext,
108
+ TResult,
109
+ TEvent
110
+ >,
111
+ ) => MiddyfiedHandler<
112
+ TInputHandlerEventProps,
113
+ TInputHandlerResultProps,
114
+ TErr,
115
+ TContext,
116
+ TInternal
117
+ >;
113
118
  }
114
119
 
115
120
  declare type AttachMiddlewareFn<
116
- TEvent = any,
117
- TResult = any,
118
- TErr = Error,
119
- TContext extends LambdaContext = LambdaContext,
120
- TInternal extends Record<string, unknown> = {}
121
+ TEvent = any,
122
+ TResult = any,
123
+ TErr = Error,
124
+ TContext extends LambdaContext = LambdaContext,
125
+ TInternal extends Record<string, unknown> = {},
121
126
  > = (
122
- middleware: MiddlewareFn<TEvent, TResult, TErr, TContext, TInternal>
123
- ) => MiddyfiedHandler<TEvent, TResult, TErr, TContext, TInternal>
127
+ middleware: MiddlewareFn<TEvent, TResult, TErr, TContext, TInternal>,
128
+ ) => MiddyfiedHandler<TEvent, TResult, TErr, TContext, TInternal>;
124
129
 
125
130
  declare type AttachMiddlewareObj<
126
- TEvent = any,
127
- TResult = any,
128
- TErr = Error,
129
- TContext extends LambdaContext = LambdaContext,
130
- TInternal extends Record<string, unknown> = {}
131
+ TEvent = any,
132
+ TResult = any,
133
+ TErr = Error,
134
+ TContext extends LambdaContext = LambdaContext,
135
+ TInternal extends Record<string, unknown> = {},
131
136
  > = (
132
- middleware: MiddlewareObj<TEvent, TResult, TErr, TContext, TInternal>
133
- ) => MiddyfiedHandler<TEvent, TResult, TErr, TContext, TInternal>
137
+ middleware: MiddlewareObj<TEvent, TResult, TErr, TContext, TInternal>,
138
+ ) => MiddyfiedHandler<TEvent, TResult, TErr, TContext, TInternal>;
134
139
 
135
140
  declare type UseFn<
136
- TEvent = any,
137
- TResult = any,
138
- TErr = Error,
139
- TContext extends LambdaContext = LambdaContext,
140
- TInternal extends Record<string, unknown> = {}
141
+ TEvent = any,
142
+ TResult = any,
143
+ TErr = Error,
144
+ TContext extends LambdaContext = LambdaContext,
145
+ TInternal extends Record<string, unknown> = {},
141
146
  > = <TMiddleware extends MiddlewareObj<any, any, Error, any, any>>(
142
- middlewares: TMiddleware | TMiddleware[]
147
+ middlewares: TMiddleware | TMiddleware[],
143
148
  ) => TMiddleware extends MiddlewareObj<
144
- infer TMiddlewareEvent,
145
- any,
146
- Error,
147
- infer TMiddlewareContext,
148
- infer TMiddlewareInternal
149
+ infer TMiddlewareEvent,
150
+ any,
151
+ Error,
152
+ infer TMiddlewareContext,
153
+ infer TMiddlewareInternal
149
154
  >
150
- ? MiddyfiedHandler<
151
- TMiddlewareEvent & TEvent,
152
- TResult,
153
- TErr,
154
- TMiddlewareContext & TContext,
155
- TMiddlewareInternal & TInternal
156
- > // always true
157
- : never
155
+ ? MiddyfiedHandler<
156
+ TMiddlewareEvent & TEvent,
157
+ TResult,
158
+ TErr,
159
+ TMiddlewareContext & TContext,
160
+ TMiddlewareInternal & TInternal
161
+ > // always true
162
+ : never;
158
163
 
159
164
  declare type MiddlewareHandler<
160
- THandler extends LambdaHandler<any, any>,
161
- TContext extends LambdaContext = LambdaContext,
162
- TResult = any
163
- > =
164
- THandler extends LambdaHandler<infer TEvent, TResult> // always true
165
- ? MiddyInputHandler<TEvent, TResult, TContext>
166
- : never
165
+ THandler extends LambdaHandler<any, any>,
166
+ TContext extends LambdaContext = LambdaContext,
167
+ TResult = any,
168
+ TEvent = any,
169
+ > = THandler extends LambdaHandler<TEvent, TResult> // always true
170
+ ? MiddyInputHandler<TEvent, TResult, TContext>
171
+ : never;
167
172
 
168
173
  /**
169
174
  * Middy factory function. Use it to wrap your existing handler to enable middlewares on it.
@@ -171,29 +176,34 @@ declare type MiddlewareHandler<
171
176
  * @param plugin wraps around each middleware and handler to add custom lifecycle behaviours (e.g. to profile performance)
172
177
  */
173
178
  declare function middy<
174
- TEvent = unknown,
175
- TResult = any,
176
- TErr = Error,
177
- TContext extends LambdaContext = LambdaContext,
178
- TInternal extends Record<string, unknown> = {}
179
- > (
180
- handler?:
181
- | LambdaHandler<TEvent, TResult>
182
- | MiddlewareHandler<LambdaHandler<TEvent, TResult>, TContext, TResult>
183
- | PluginObject,
184
- plugin?: PluginObject
185
- ): MiddyfiedHandler<TEvent, TResult, TErr, TContext, TInternal>
179
+ TEvent = unknown,
180
+ TResult = any,
181
+ TErr = Error,
182
+ TContext extends LambdaContext = LambdaContext,
183
+ TInternal extends Record<string, unknown> = {},
184
+ >(
185
+ handler?:
186
+ | LambdaHandler<TEvent, TResult>
187
+ | MiddlewareHandler<
188
+ LambdaHandler<TEvent, TResult>,
189
+ TContext,
190
+ TResult,
191
+ TEvent
192
+ >
193
+ | PluginObject,
194
+ plugin?: PluginObject,
195
+ ): MiddyfiedHandler<TEvent, TResult, TErr, TContext, TInternal>;
186
196
 
187
197
  declare namespace middy {
188
- export {
189
- Request,
190
- PluginHook,
191
- PluginHookWithMiddlewareName,
192
- PluginObject,
193
- MiddlewareFn,
194
- MiddlewareObj,
195
- MiddyfiedHandler
196
- }
198
+ export type {
199
+ Request,
200
+ PluginHook,
201
+ PluginHookWithMiddlewareName,
202
+ PluginObject,
203
+ MiddlewareFn,
204
+ MiddlewareObj,
205
+ MiddyfiedHandler,
206
+ };
197
207
  }
198
208
 
199
- export default middy
209
+ export default middy;
package/index.js CHANGED
@@ -1,244 +1,253 @@
1
1
  /* global awslambda */
2
- import { Readable } from 'node:stream'
3
- import { ReadableStream } from 'node:stream/web'
4
- import { pipeline } from 'node:stream/promises'
5
- import { setTimeout } from 'node:timers'
6
-
7
- const defaultLambdaHandler = () => {}
8
- const defaultPlugin = {
9
- timeoutEarlyInMillis: 5,
10
- timeoutEarlyResponse: () => {
11
- const err = new Error('[AbortError]: The operation was aborted.', {
12
- cause: { package: '@middy/core' }
13
- })
14
- err.name = 'TimeoutError'
15
- throw err
16
- },
17
- streamifyResponse: false // Deprecate need for this when AWS provides a flag for when it's looking for it
18
- }
19
-
20
- const middy = (lambdaHandler = defaultLambdaHandler, plugin = {}) => {
21
- // Allow base handler to be set using .handler()
22
- if (typeof lambdaHandler !== 'function') {
23
- plugin = lambdaHandler
24
- lambdaHandler = defaultLambdaHandler
25
- }
26
- plugin = { ...defaultPlugin, ...plugin }
27
- plugin.timeoutEarly = plugin.timeoutEarlyInMillis > 0
28
-
29
- plugin.beforePrefetch?.()
30
- const beforeMiddlewares = []
31
- const afterMiddlewares = []
32
- const onErrorMiddlewares = []
33
-
34
- const middyHandler = (event = {}, context = {}) => {
35
- plugin.requestStart?.()
36
- const request = {
37
- event,
38
- context,
39
- response: undefined,
40
- error: undefined,
41
- internal: plugin.internal ?? {}
42
- }
43
-
44
- return runRequest(
45
- request,
46
- beforeMiddlewares,
47
- lambdaHandler,
48
- afterMiddlewares,
49
- onErrorMiddlewares,
50
- plugin
51
- )
52
- }
53
- const middy = plugin.streamifyResponse
54
- ? awslambda.streamifyResponse(async (event, responseStream, context) => {
55
- const handlerResponse = await middyHandler(event, context)
56
-
57
- let handlerBody = handlerResponse
58
- if (handlerResponse.statusCode) {
59
- handlerBody = handlerResponse.body ?? ''
60
- delete handlerResponse.body // #1137
61
- responseStream = awslambda.HttpResponseStream.from(
62
- responseStream,
63
- handlerResponse
64
- )
65
- }
66
-
67
- let handlerStream
68
- if (handlerBody._readableState || handlerBody instanceof ReadableStream) {
69
- handlerStream = handlerBody
70
- } else if (typeof handlerBody === 'string') {
71
- // #1189
72
- handlerStream = Readable.from(
73
- handlerBody.length < stringIteratorSize
74
- ? handlerBody
75
- : stringIterator(handlerBody)
76
- )
77
- }
78
-
79
- if (!handlerStream) {
80
- throw new Error('handler response not a ReadableStream')
81
- }
82
-
83
- await pipeline(handlerStream, responseStream)
84
- })
85
- : middyHandler
86
-
87
- middy.use = (middlewares) => {
88
- if (!Array.isArray(middlewares)) {
89
- middlewares = [middlewares]
90
- }
91
- for (const middleware of middlewares) {
92
- const { before, after, onError } = middleware
93
-
94
- if (before || after || onError) {
95
- if (before) middy.before(before)
96
- if (after) middy.after(after)
97
- if (onError) middy.onError(onError)
98
- } else {
99
- throw new Error(
100
- 'Middleware must be an object containing at least one key among "before", "after", "onError"'
101
- )
102
- }
103
- }
104
- return middy
105
- }
106
-
107
- // Inline Middlewares
108
- middy.before = (beforeMiddleware) => {
109
- beforeMiddlewares.push(beforeMiddleware)
110
- return middy
111
- }
112
- middy.after = (afterMiddleware) => {
113
- afterMiddlewares.unshift(afterMiddleware)
114
- return middy
115
- }
116
- middy.onError = (onErrorMiddleware) => {
117
- onErrorMiddlewares.unshift(onErrorMiddleware)
118
- return middy
119
- }
120
- middy.handler = (replaceLambdaHandler) => {
121
- lambdaHandler = replaceLambdaHandler
122
- return middy
123
- }
124
-
125
- return middy
126
- }
127
-
128
- const stringIteratorSize = 16384 // 16 * 1024 // Node.js default
129
- function * stringIterator (input) {
130
- let position = 0
131
- const length = input.length
132
- while (position < length) {
133
- yield input.substring(position, position + stringIteratorSize)
134
- position += stringIteratorSize
135
- }
2
+ import { Readable } from "node:stream";
3
+ import { pipeline } from "node:stream/promises";
4
+ import { ReadableStream } from "node:stream/web";
5
+ import { setTimeout } from "node:timers";
6
+
7
+ const defaultLambdaHandler = () => {};
8
+ const defaultPluginConfig = {
9
+ timeoutEarlyInMillis: 5,
10
+ timeoutEarlyResponse: () => {
11
+ const err = new Error("[AbortError]: The operation was aborted.", {
12
+ cause: { package: "@middy/core" },
13
+ });
14
+ err.name = "TimeoutError";
15
+ throw err;
16
+ },
17
+ streamifyResponse: false, // Deprecate need for this when AWS provides a flag for when it's looking for it
18
+ };
19
+
20
+ const middy = (setupLambdaHandler, pluginConfig) => {
21
+ let lambdaHandler;
22
+ let plugin;
23
+ // Allow base handler to be set using .handler()
24
+ if (typeof setupLambdaHandler === "function") {
25
+ lambdaHandler = setupLambdaHandler;
26
+ plugin = { ...defaultPluginConfig, ...pluginConfig };
27
+ } else {
28
+ lambdaHandler = defaultLambdaHandler;
29
+ plugin = { ...defaultPluginConfig, ...setupLambdaHandler };
30
+ }
31
+ plugin.timeoutEarly = plugin.timeoutEarlyInMillis > 0;
32
+
33
+ plugin.beforePrefetch?.();
34
+ const beforeMiddlewares = [];
35
+ const afterMiddlewares = [];
36
+ const onErrorMiddlewares = [];
37
+
38
+ const middyHandler = (event = {}, context = {}) => {
39
+ plugin.requestStart?.();
40
+ const request = {
41
+ event,
42
+ context,
43
+ response: undefined,
44
+ error: undefined,
45
+ internal: plugin.internal ?? {},
46
+ };
47
+
48
+ return runRequest(
49
+ request,
50
+ beforeMiddlewares,
51
+ lambdaHandler,
52
+ afterMiddlewares,
53
+ onErrorMiddlewares,
54
+ plugin,
55
+ );
56
+ };
57
+ const middy = plugin.streamifyResponse
58
+ ? awslambda.streamifyResponse(
59
+ async (event, lambdaResponseStream, context) => {
60
+ const handlerResponse = await middyHandler(event, context);
61
+ let responseStream = lambdaResponseStream;
62
+ let handlerBody = handlerResponse;
63
+ if (handlerResponse.statusCode) {
64
+ const { body, ...restResponse } = handlerResponse;
65
+ handlerBody = body ?? ""; // #1137
66
+ responseStream = awslambda.HttpResponseStream.from(
67
+ responseStream,
68
+ restResponse,
69
+ );
70
+ }
71
+
72
+ let handlerStream;
73
+ if (
74
+ handlerBody._readableState ||
75
+ handlerBody instanceof ReadableStream
76
+ ) {
77
+ handlerStream = handlerBody;
78
+ } else if (typeof handlerBody === "string") {
79
+ // #1189
80
+ handlerStream = Readable.from(
81
+ handlerBody.length < stringIteratorSize
82
+ ? handlerBody
83
+ : stringIterator(handlerBody),
84
+ );
85
+ }
86
+
87
+ if (!handlerStream) {
88
+ throw new Error("handler response not a ReadableStream");
89
+ }
90
+
91
+ await pipeline(handlerStream, responseStream);
92
+ },
93
+ )
94
+ : middyHandler;
95
+
96
+ middy.use = (inputMiddleware) => {
97
+ const middlewares = Array.isArray(inputMiddleware)
98
+ ? inputMiddleware
99
+ : [inputMiddleware];
100
+ for (const middleware of middlewares) {
101
+ const { before, after, onError } = middleware;
102
+
103
+ if (before || after || onError) {
104
+ if (before) middy.before(before);
105
+ if (after) middy.after(after);
106
+ if (onError) middy.onError(onError);
107
+ } else {
108
+ throw new Error(
109
+ 'Middleware must be an object containing at least one key among "before", "after", "onError"',
110
+ );
111
+ }
112
+ }
113
+ return middy;
114
+ };
115
+
116
+ // Inline Middlewares
117
+ middy.before = (beforeMiddleware) => {
118
+ beforeMiddlewares.push(beforeMiddleware);
119
+ return middy;
120
+ };
121
+ middy.after = (afterMiddleware) => {
122
+ afterMiddlewares.unshift(afterMiddleware);
123
+ return middy;
124
+ };
125
+ middy.onError = (onErrorMiddleware) => {
126
+ onErrorMiddlewares.unshift(onErrorMiddleware);
127
+ return middy;
128
+ };
129
+ middy.handler = (replaceLambdaHandler) => {
130
+ lambdaHandler = replaceLambdaHandler;
131
+ return middy;
132
+ };
133
+
134
+ return middy;
135
+ };
136
+
137
+ const stringIteratorSize = 16384; // 16 * 1024 // Node.js default
138
+ function* stringIterator(input) {
139
+ let position = 0;
140
+ const length = input.length;
141
+ while (position < length) {
142
+ yield input.substring(position, position + stringIteratorSize);
143
+ position += stringIteratorSize;
144
+ }
136
145
  }
137
146
 
138
147
  // shared AbortController, because it's slow
139
- let handlerAbort = new AbortController()
148
+ let handlerAbort = new AbortController();
140
149
  const runRequest = async (
141
- request,
142
- beforeMiddlewares,
143
- lambdaHandler,
144
- afterMiddlewares,
145
- onErrorMiddlewares,
146
- plugin
150
+ request,
151
+ beforeMiddlewares,
152
+ lambdaHandler,
153
+ afterMiddlewares,
154
+ onErrorMiddlewares,
155
+ plugin,
147
156
  ) => {
148
- let timeoutID
149
- // context.getRemainingTimeInMillis checked for when AWS context missing (tests, containers)
150
- const timeoutEarly =
151
- plugin.timeoutEarly && request.context.getRemainingTimeInMillis
152
-
153
- try {
154
- await runMiddlewares(request, beforeMiddlewares, plugin)
155
-
156
- // Check if before stack hasn't exit early
157
- if (!Object.prototype.hasOwnProperty.call(request, 'earlyResponse')) {
158
- plugin.beforeHandler?.()
159
-
160
- // Can't manually abort and timeout with same AbortSignal
161
- // https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal/timeout_static
162
- if (handlerAbort.signal.aborted) {
163
- handlerAbort = new AbortController()
164
- }
165
- const promises = [
166
- lambdaHandler(request.event, request.context, {
167
- signal: handlerAbort.signal
168
- })
169
- ]
170
-
171
- // clearTimeout pattern is 10x faster than using AbortController
172
- // Note: signal.abort is slow ~6000ns
173
- if (timeoutEarly) {
174
- let timeoutResolve
175
- const timeoutPromise = new Promise((resolve, reject) => {
176
- timeoutResolve = () => {
177
- handlerAbort.abort()
178
- try {
179
- resolve(plugin.timeoutEarlyResponse())
180
- } catch (e) {
181
- reject(e)
182
- }
183
- }
184
- })
185
- timeoutID = setTimeout(
186
- timeoutResolve,
187
- request.context.getRemainingTimeInMillis() -
188
- plugin.timeoutEarlyInMillis
189
- )
190
- promises.push(timeoutPromise)
191
- }
192
- request.response = await Promise.race(promises)
193
- if (timeoutID) {
194
- clearTimeout(timeoutID)
195
- }
196
-
197
- plugin.afterHandler?.()
198
- await runMiddlewares(request, afterMiddlewares, plugin)
199
- }
200
- } catch (e) {
201
- // timeout should be aborted when errors happen in handler
202
- if (timeoutID) {
203
- clearTimeout(timeoutID)
204
- }
205
-
206
- // Reset response changes made by after stack before error thrown
207
- request.response = undefined
208
- request.error = e
209
- try {
210
- await runMiddlewares(request, onErrorMiddlewares, plugin)
211
- } catch (e) {
212
- // Save error that wasn't handled
213
- e.originalError = request.error
214
- request.error = e
215
-
216
- throw request.error
217
- }
218
- // Catch if onError stack hasn't handled the error
219
- if (typeof request.response === 'undefined') throw request.error
220
- } finally {
221
- await plugin.requestEnd?.(request)
222
- }
223
-
224
- return request.response
225
- }
157
+ let timeoutID;
158
+ // context.getRemainingTimeInMillis checked for when AWS context missing (tests, containers)
159
+ const timeoutEarly =
160
+ plugin.timeoutEarly && request.context.getRemainingTimeInMillis;
161
+
162
+ try {
163
+ await runMiddlewares(request, beforeMiddlewares, plugin);
164
+
165
+ // Check if before stack hasn't exit early
166
+ if (!Object.prototype.hasOwnProperty.call(request, "earlyResponse")) {
167
+ plugin.beforeHandler?.();
168
+
169
+ // Can't manually abort and timeout with same AbortSignal
170
+ // https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal/timeout_static
171
+ if (handlerAbort.signal.aborted) {
172
+ handlerAbort = new AbortController();
173
+ }
174
+ const promises = [
175
+ lambdaHandler(request.event, request.context, {
176
+ signal: handlerAbort.signal,
177
+ }),
178
+ ];
179
+
180
+ // clearTimeout pattern is 10x faster than using AbortController
181
+ // Note: signal.abort is slow ~6000ns
182
+ if (timeoutEarly) {
183
+ let timeoutResolve;
184
+ const timeoutPromise = new Promise((resolve, reject) => {
185
+ timeoutResolve = () => {
186
+ handlerAbort.abort();
187
+ try {
188
+ resolve(plugin.timeoutEarlyResponse());
189
+ } catch (e) {
190
+ reject(e);
191
+ }
192
+ };
193
+ });
194
+ timeoutID = setTimeout(
195
+ timeoutResolve,
196
+ request.context.getRemainingTimeInMillis() -
197
+ plugin.timeoutEarlyInMillis,
198
+ );
199
+ promises.push(timeoutPromise);
200
+ }
201
+ request.response = await Promise.race(promises);
202
+ if (timeoutID) {
203
+ clearTimeout(timeoutID);
204
+ }
205
+
206
+ plugin.afterHandler?.();
207
+ await runMiddlewares(request, afterMiddlewares, plugin);
208
+ }
209
+ } catch (e) {
210
+ // timeout should be aborted when errors happen in handler
211
+ if (timeoutID) {
212
+ clearTimeout(timeoutID);
213
+ }
214
+
215
+ // Reset response changes made by after stack before error thrown
216
+ request.response = undefined;
217
+ request.error = e;
218
+ try {
219
+ await runMiddlewares(request, onErrorMiddlewares, plugin);
220
+ } catch (e) {
221
+ // Save error that wasn't handled
222
+ e.originalError = request.error;
223
+ request.error = e;
224
+
225
+ throw request.error;
226
+ }
227
+ // Catch if onError stack hasn't handled the error
228
+ if (typeof request.response === "undefined") throw request.error;
229
+ } finally {
230
+ await plugin.requestEnd?.(request);
231
+ }
232
+
233
+ return request.response;
234
+ };
226
235
 
227
236
  const runMiddlewares = async (request, middlewares, plugin) => {
228
- for (const nextMiddleware of middlewares) {
229
- plugin.beforeMiddleware?.(nextMiddleware.name)
230
- const res = await nextMiddleware(request)
231
- plugin.afterMiddleware?.(nextMiddleware.name)
232
- // short circuit chaining and respond early
233
- if (typeof res !== 'undefined') {
234
- request.earlyResponse = res
235
- }
236
- // earlyResponse pattern added in 6.0.0 to handle undefined values
237
- if (Object.prototype.hasOwnProperty.call(request, 'earlyResponse')) {
238
- request.response = request.earlyResponse
239
- return
240
- }
241
- }
242
- }
243
-
244
- export default middy
237
+ for (const nextMiddleware of middlewares) {
238
+ plugin.beforeMiddleware?.(nextMiddleware.name);
239
+ const res = await nextMiddleware(request);
240
+ plugin.afterMiddleware?.(nextMiddleware.name);
241
+ // short circuit chaining and respond early
242
+ if (typeof res !== "undefined") {
243
+ request.earlyResponse = res;
244
+ }
245
+ // earlyResponse pattern added in 6.0.0 to handle undefined values
246
+ if (Object.prototype.hasOwnProperty.call(request, "earlyResponse")) {
247
+ request.response = request.earlyResponse;
248
+ return;
249
+ }
250
+ }
251
+ };
252
+
253
+ export default middy;
package/package.json CHANGED
@@ -1,69 +1,66 @@
1
1
  {
2
- "name": "@middy/core",
3
- "version": "6.1.6",
4
- "description": "🛵 The stylish Node.js middleware engine for AWS Lambda (core package)",
5
- "type": "module",
6
- "engines": {
7
- "node": ">=20"
8
- },
9
- "engineStrict": true,
10
- "publishConfig": {
11
- "access": "public"
12
- },
13
- "module": "./index.js",
14
- "exports": {
15
- ".": {
16
- "import": {
17
- "types": "./index.d.ts",
18
- "default": "./index.js"
19
- },
20
- "require": {
21
- "default": "./index.js"
22
- }
23
- }
24
- },
25
- "types": "index.d.ts",
26
- "files": [
27
- "index.js",
28
- "index.d.ts"
29
- ],
30
- "scripts": {
31
- "test": "npm run test:unit && npm run test:fuzz",
32
- "test:unit": "node --test __tests__/index.js",
33
- "test:fuzz": "node --test __tests__/fuzz.js",
34
- "test:benchmark": "node __benchmarks__/index.js",
35
- "test:profile": "node --prof __benchmarks__/index.js && node --prof-process --preprocess -j isolate*.log | speedscope -"
36
- },
37
- "license": "MIT",
38
- "keywords": [
39
- "Lambda",
40
- "Middleware",
41
- "Serverless",
42
- "Framework",
43
- "AWS",
44
- "AWS Lambda"
45
- ],
46
- "author": {
47
- "name": "Middy contributors",
48
- "url": "https://github.com/middyjs/middy/graphs/contributors"
49
- },
50
- "repository": {
51
- "type": "git",
52
- "url": "git+https://github.com/middyjs/middy.git",
53
- "directory": "packages/core"
54
- },
55
- "bugs": {
56
- "url": "https://github.com/middyjs/middy/issues"
57
- },
58
- "homepage": "https://middy.js.org",
59
- "funding": {
60
- "type": "github",
61
- "url": "https://github.com/sponsors/willfarrell"
62
- },
63
- "devDependencies": {
64
- "@datastream/core": "0.0.40",
65
- "@types/aws-lambda": "^8.10.76",
66
- "@types/node": "^20.0.0"
67
- },
68
- "gitHead": "7a6c0fbb8ab71d6a2171e678697de9f237568431"
2
+ "name": "@middy/core",
3
+ "version": "6.2.0",
4
+ "description": "🛵 The stylish Node.js middleware engine for AWS Lambda (core package)",
5
+ "type": "module",
6
+ "engines": {
7
+ "node": ">=20"
8
+ },
9
+ "engineStrict": true,
10
+ "publishConfig": {
11
+ "access": "public"
12
+ },
13
+ "module": "./index.js",
14
+ "exports": {
15
+ ".": {
16
+ "import": {
17
+ "types": "./index.d.ts",
18
+ "default": "./index.js"
19
+ },
20
+ "require": {
21
+ "default": "./index.js"
22
+ }
23
+ }
24
+ },
25
+ "types": "index.d.ts",
26
+ "files": ["index.js", "index.d.ts"],
27
+ "scripts": {
28
+ "test": "npm run test:unit && npm run test:fuzz",
29
+ "test:unit": "node --test",
30
+ "test:fuzz": "node --test index.fuzz.js",
31
+ "test:perf": "node --test index.perf.js",
32
+ "test:profile": "node --prof __benchmarks__/index.js && node --prof-process --preprocess -j isolate*.log | speedscope -"
33
+ },
34
+ "license": "MIT",
35
+ "keywords": [
36
+ "Lambda",
37
+ "Middleware",
38
+ "Serverless",
39
+ "Framework",
40
+ "AWS",
41
+ "AWS Lambda"
42
+ ],
43
+ "author": {
44
+ "name": "Middy contributors",
45
+ "url": "https://github.com/middyjs/middy/graphs/contributors"
46
+ },
47
+ "repository": {
48
+ "type": "git",
49
+ "url": "git+https://github.com/middyjs/middy.git",
50
+ "directory": "packages/core"
51
+ },
52
+ "bugs": {
53
+ "url": "https://github.com/middyjs/middy/issues"
54
+ },
55
+ "homepage": "https://middy.js.org",
56
+ "funding": {
57
+ "type": "github",
58
+ "url": "https://github.com/sponsors/willfarrell"
59
+ },
60
+ "devDependencies": {
61
+ "@datastream/core": "0.0.40",
62
+ "@types/aws-lambda": "^8.10.76",
63
+ "@types/node": "^20.0.0"
64
+ },
65
+ "gitHead": "7a6c0fbb8ab71d6a2171e678697de9f237568431"
69
66
  }