@middy/core 7.1.2 → 7.1.3
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 +1 -1
- package/executionModeDurableContext.js +5 -5
- package/executionModeStandard.js +2 -2
- package/executionModeStreamifyResponse.js +2 -2
- package/index.d.ts +10 -10
- package/index.js +33 -21
- package/package.json +5 -3
package/README.md
CHANGED
|
@@ -42,7 +42,7 @@ npm install --save @middy/core
|
|
|
42
42
|
|
|
43
43
|
## Documentation and examples
|
|
44
44
|
|
|
45
|
-
For documentation and examples,
|
|
45
|
+
For documentation and examples, refer to the main [Middy monorepo on GitHub](https://github.com/middyjs/middy) or [Middy official website](https://middy.js.org).
|
|
46
46
|
|
|
47
47
|
|
|
48
48
|
## Contributing
|
|
@@ -13,7 +13,7 @@ export const executionModeDurableContext = (
|
|
|
13
13
|
) => {
|
|
14
14
|
const middy = withDurableExecution(async (event, context) => {
|
|
15
15
|
const request = middyRequest(event, context);
|
|
16
|
-
plugin.requestStart
|
|
16
|
+
plugin.requestStart(request);
|
|
17
17
|
|
|
18
18
|
// normalize context with executionModeStandard
|
|
19
19
|
// https://docs.aws.amazon.com/lambda/latest/dg/typescript-context.html
|
|
@@ -33,7 +33,7 @@ export const executionModeDurableContext = (
|
|
|
33
33
|
onErrorMiddlewares,
|
|
34
34
|
plugin,
|
|
35
35
|
);
|
|
36
|
-
await plugin.requestEnd
|
|
36
|
+
await plugin.requestEnd(request);
|
|
37
37
|
return response;
|
|
38
38
|
});
|
|
39
39
|
middy.handler = (replaceLambdaHandler) => {
|
|
@@ -44,7 +44,7 @@ export const executionModeDurableContext = (
|
|
|
44
44
|
};
|
|
45
45
|
|
|
46
46
|
const copyKeys = (to, from, keys) => {
|
|
47
|
-
keys.
|
|
48
|
-
to[
|
|
49
|
-
}
|
|
47
|
+
for (let i = 0, len = keys.length; i < len; i++) {
|
|
48
|
+
to[keys[i]] = from[keys[i]];
|
|
49
|
+
}
|
|
50
50
|
};
|
package/executionModeStandard.js
CHANGED
|
@@ -10,7 +10,7 @@ export const executionModeStandard = (
|
|
|
10
10
|
) => {
|
|
11
11
|
const middy = async (event, context) => {
|
|
12
12
|
const request = middyRequest(event, context);
|
|
13
|
-
plugin.requestStart
|
|
13
|
+
plugin.requestStart(request);
|
|
14
14
|
|
|
15
15
|
const response = await runRequest(
|
|
16
16
|
request,
|
|
@@ -20,7 +20,7 @@ export const executionModeStandard = (
|
|
|
20
20
|
onErrorMiddlewares,
|
|
21
21
|
plugin,
|
|
22
22
|
);
|
|
23
|
-
await plugin.requestEnd
|
|
23
|
+
await plugin.requestEnd(request);
|
|
24
24
|
return response;
|
|
25
25
|
};
|
|
26
26
|
middy.handler = (replaceLambdaHandler) => {
|
|
@@ -16,7 +16,7 @@ export const executionModeStreamifyResponse = (
|
|
|
16
16
|
const middy = awslambda.streamifyResponse(
|
|
17
17
|
async (event, lambdaResponseStream, context) => {
|
|
18
18
|
const request = middyRequest(event, context);
|
|
19
|
-
plugin.requestStart
|
|
19
|
+
plugin.requestStart(request);
|
|
20
20
|
const handlerResponse = await runRequest(
|
|
21
21
|
request,
|
|
22
22
|
beforeMiddlewares,
|
|
@@ -55,7 +55,7 @@ export const executionModeStreamifyResponse = (
|
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
await pipeline(handlerStream, responseStream);
|
|
58
|
-
await plugin.requestEnd
|
|
58
|
+
await plugin.requestEnd(request);
|
|
59
59
|
},
|
|
60
60
|
);
|
|
61
61
|
|
package/index.d.ts
CHANGED
|
@@ -17,7 +17,7 @@ export declare const executionModeDurableContext: PluginExecutionMode;
|
|
|
17
17
|
export declare const executionModeStreamifyResponse: PluginExecutionMode;
|
|
18
18
|
|
|
19
19
|
interface PluginObject {
|
|
20
|
-
internal?:
|
|
20
|
+
internal?: Record<string, unknown>;
|
|
21
21
|
beforePrefetch?: PluginHook;
|
|
22
22
|
requestStart?: PluginHook;
|
|
23
23
|
beforeMiddleware?: PluginHookWithMiddlewareName;
|
|
@@ -31,7 +31,7 @@ interface PluginObject {
|
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
export interface Request<
|
|
34
|
-
TEvent =
|
|
34
|
+
TEvent = unknown,
|
|
35
35
|
TResult = any,
|
|
36
36
|
TErr = Error,
|
|
37
37
|
TContext extends LambdaContext | LambdaContextDurable = LambdaContext,
|
|
@@ -39,14 +39,14 @@ export interface Request<
|
|
|
39
39
|
> {
|
|
40
40
|
event: TEvent;
|
|
41
41
|
context: TContext;
|
|
42
|
-
response: TResult |
|
|
42
|
+
response: TResult | undefined;
|
|
43
43
|
earlyResponse?: TResult | null | undefined;
|
|
44
|
-
error: TErr |
|
|
44
|
+
error: TErr | undefined;
|
|
45
45
|
internal: TInternal;
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
declare type MiddlewareFn<
|
|
49
|
-
TEvent =
|
|
49
|
+
TEvent = unknown,
|
|
50
50
|
TResult = any,
|
|
51
51
|
TErr = Error,
|
|
52
52
|
TContext extends LambdaContext | LambdaContextDurable = LambdaContext,
|
|
@@ -91,7 +91,7 @@ type MiddyInputPromiseHandler<
|
|
|
91
91
|
> = (event: TEvent, context: TContext) => Promise<TResult>;
|
|
92
92
|
|
|
93
93
|
export interface MiddyfiedHandler<
|
|
94
|
-
TEvent =
|
|
94
|
+
TEvent = unknown,
|
|
95
95
|
TResult = any,
|
|
96
96
|
TErr = Error,
|
|
97
97
|
TContext extends LambdaContext | LambdaContextDurable = LambdaContext,
|
|
@@ -122,7 +122,7 @@ export interface MiddyfiedHandler<
|
|
|
122
122
|
}
|
|
123
123
|
|
|
124
124
|
declare type AttachMiddlewareFn<
|
|
125
|
-
TEvent =
|
|
125
|
+
TEvent = unknown,
|
|
126
126
|
TResult = any,
|
|
127
127
|
TErr = Error,
|
|
128
128
|
TContext extends LambdaContext | LambdaContextDurable = LambdaContext,
|
|
@@ -132,7 +132,7 @@ declare type AttachMiddlewareFn<
|
|
|
132
132
|
) => MiddyfiedHandler<TEvent, TResult, TErr, TContext, TInternal>;
|
|
133
133
|
|
|
134
134
|
declare type AttachMiddlewareObj<
|
|
135
|
-
TEvent =
|
|
135
|
+
TEvent = unknown,
|
|
136
136
|
TResult = any,
|
|
137
137
|
TErr = Error,
|
|
138
138
|
TContext extends LambdaContext | LambdaContextDurable = LambdaContext,
|
|
@@ -142,7 +142,7 @@ declare type AttachMiddlewareObj<
|
|
|
142
142
|
) => MiddyfiedHandler<TEvent, TResult, TErr, TContext, TInternal>;
|
|
143
143
|
|
|
144
144
|
declare type UseFn<
|
|
145
|
-
TEvent =
|
|
145
|
+
TEvent = unknown,
|
|
146
146
|
TResult = any,
|
|
147
147
|
TErr = Error,
|
|
148
148
|
TContext extends LambdaContext | LambdaContextDurable = LambdaContext,
|
|
@@ -187,7 +187,7 @@ declare type MiddlewareHandler<
|
|
|
187
187
|
THandler extends LambdaHandler<any, any>,
|
|
188
188
|
TContext extends LambdaContext | LambdaContextDurable = LambdaContext,
|
|
189
189
|
TResult = any,
|
|
190
|
-
TEvent =
|
|
190
|
+
TEvent = unknown,
|
|
191
191
|
> =
|
|
192
192
|
THandler extends LambdaHandler<TEvent, TResult> // always true
|
|
193
193
|
? MiddyInputHandler<TEvent, TResult, TContext>
|
package/index.js
CHANGED
|
@@ -4,6 +4,7 @@ import { setTimeout } from "node:timers";
|
|
|
4
4
|
import { executionModeStandard } from "./executionModeStandard.js";
|
|
5
5
|
|
|
6
6
|
const defaultLambdaHandler = () => {};
|
|
7
|
+
const noop = () => {};
|
|
7
8
|
const defaultPluginConfig = {
|
|
8
9
|
timeoutEarlyInMillis: 5,
|
|
9
10
|
timeoutEarlyResponse: () => {
|
|
@@ -29,6 +30,14 @@ export const middy = (setupLambdaHandler, pluginConfig) => {
|
|
|
29
30
|
}
|
|
30
31
|
plugin.timeoutEarly = plugin.timeoutEarlyInMillis > 0;
|
|
31
32
|
|
|
33
|
+
// Pre-compute single-call plugin hooks as noop to avoid optional chaining
|
|
34
|
+
// Note: beforeMiddleware/afterMiddleware kept as optional chaining in runMiddlewares
|
|
35
|
+
// because V8 optimizes ?.() null-checks faster than noop calls in tight loops
|
|
36
|
+
plugin.requestStart ??= noop;
|
|
37
|
+
plugin.requestEnd ??= noop;
|
|
38
|
+
plugin.beforeHandler ??= noop;
|
|
39
|
+
plugin.afterHandler ??= noop;
|
|
40
|
+
|
|
32
41
|
plugin.beforePrefetch?.();
|
|
33
42
|
const beforeMiddlewares = [];
|
|
34
43
|
const afterMiddlewares = [];
|
|
@@ -95,6 +104,7 @@ export const middy = (setupLambdaHandler, pluginConfig) => {
|
|
|
95
104
|
|
|
96
105
|
// shared AbortController, because it's slow
|
|
97
106
|
let handlerAbort = new AbortController();
|
|
107
|
+
let abortOpts = { signal: handlerAbort.signal };
|
|
98
108
|
const runRequest = async (
|
|
99
109
|
request,
|
|
100
110
|
beforeMiddlewares,
|
|
@@ -114,23 +124,24 @@ const runRequest = async (
|
|
|
114
124
|
await runMiddlewares(request, beforeMiddlewares, plugin);
|
|
115
125
|
|
|
116
126
|
// Check if before stack hasn't exit early
|
|
117
|
-
if (!
|
|
118
|
-
plugin.beforeHandler
|
|
127
|
+
if (!("earlyResponse" in request)) {
|
|
128
|
+
plugin.beforeHandler();
|
|
119
129
|
|
|
120
130
|
// Can't manually abort and timeout with same AbortSignal
|
|
121
131
|
// https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal/timeout_static
|
|
122
132
|
if (handlerAbort.signal.aborted) {
|
|
123
133
|
handlerAbort = new AbortController();
|
|
134
|
+
abortOpts = { signal: handlerAbort.signal };
|
|
124
135
|
}
|
|
125
|
-
const promises = [
|
|
126
|
-
lambdaHandler(request.event, request.context, {
|
|
127
|
-
signal: handlerAbort.signal,
|
|
128
|
-
}),
|
|
129
|
-
];
|
|
130
136
|
|
|
131
137
|
// clearTimeout pattern is 10x faster than using AbortController
|
|
132
138
|
// Note: signal.abort is slow ~6_000ns
|
|
133
139
|
// Required --test-force-exit to ignore unresolved timeoutPromise
|
|
140
|
+
const handlerResult = lambdaHandler(
|
|
141
|
+
request.event,
|
|
142
|
+
request.context,
|
|
143
|
+
abortOpts,
|
|
144
|
+
);
|
|
134
145
|
if (timeoutEarly) {
|
|
135
146
|
let timeoutResolve;
|
|
136
147
|
const timeoutPromise = new Promise((resolve, reject) => {
|
|
@@ -138,8 +149,8 @@ const runRequest = async (
|
|
|
138
149
|
handlerAbort.abort();
|
|
139
150
|
try {
|
|
140
151
|
resolve(plugin.timeoutEarlyResponse());
|
|
141
|
-
} catch (
|
|
142
|
-
reject(
|
|
152
|
+
} catch (err) {
|
|
153
|
+
reject(err);
|
|
143
154
|
}
|
|
144
155
|
};
|
|
145
156
|
});
|
|
@@ -147,18 +158,19 @@ const runRequest = async (
|
|
|
147
158
|
timeoutResolve,
|
|
148
159
|
getRemainingTimeInMillis() - plugin.timeoutEarlyInMillis,
|
|
149
160
|
);
|
|
150
|
-
|
|
161
|
+
request.response = await Promise.race([handlerResult, timeoutPromise]);
|
|
162
|
+
} else {
|
|
163
|
+
request.response = await handlerResult;
|
|
151
164
|
}
|
|
152
|
-
request.response = await Promise.race(promises);
|
|
153
165
|
|
|
154
166
|
if (timeoutID) {
|
|
155
167
|
clearTimeout(timeoutID);
|
|
156
168
|
}
|
|
157
169
|
|
|
158
|
-
plugin.afterHandler
|
|
170
|
+
plugin.afterHandler();
|
|
159
171
|
await runMiddlewares(request, afterMiddlewares, plugin);
|
|
160
172
|
}
|
|
161
|
-
} catch (
|
|
173
|
+
} catch (err) {
|
|
162
174
|
// timeout should be aborted when errors happen in handler
|
|
163
175
|
if (timeoutID) {
|
|
164
176
|
clearTimeout(timeoutID);
|
|
@@ -166,13 +178,13 @@ const runRequest = async (
|
|
|
166
178
|
|
|
167
179
|
// Reset response changes made by after stack before error thrown
|
|
168
180
|
request.response = undefined;
|
|
169
|
-
request.error =
|
|
181
|
+
request.error = err;
|
|
170
182
|
try {
|
|
171
183
|
await runMiddlewares(request, onErrorMiddlewares, plugin);
|
|
172
|
-
} catch (
|
|
184
|
+
} catch (err) {
|
|
173
185
|
// Save error that wasn't handled
|
|
174
|
-
|
|
175
|
-
request.error =
|
|
186
|
+
err.originalError = request.error;
|
|
187
|
+
request.error = err;
|
|
176
188
|
|
|
177
189
|
throw request.error;
|
|
178
190
|
}
|
|
@@ -183,17 +195,17 @@ const runRequest = async (
|
|
|
183
195
|
return request.response;
|
|
184
196
|
};
|
|
185
197
|
|
|
186
|
-
const runMiddlewares = async (request, middlewares,
|
|
198
|
+
const runMiddlewares = async (request, middlewares, plugin) => {
|
|
187
199
|
for (const nextMiddleware of middlewares) {
|
|
188
|
-
|
|
200
|
+
plugin.beforeMiddleware?.(nextMiddleware.name);
|
|
189
201
|
const res = await nextMiddleware(request);
|
|
190
|
-
|
|
202
|
+
plugin.afterMiddleware?.(nextMiddleware.name);
|
|
191
203
|
// short circuit chaining and respond early
|
|
192
204
|
if (typeof res !== "undefined") {
|
|
193
205
|
request.earlyResponse = res;
|
|
194
206
|
}
|
|
195
207
|
// earlyResponse pattern added in 6.0.0 to handle undefined values
|
|
196
|
-
if (
|
|
208
|
+
if ("earlyResponse" in request) {
|
|
197
209
|
request.response = request.earlyResponse;
|
|
198
210
|
return;
|
|
199
211
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@middy/core",
|
|
3
|
-
"version": "7.1.
|
|
3
|
+
"version": "7.1.3",
|
|
4
4
|
"description": "🛵 The stylish Node.js middleware engine for AWS Lambda (core package)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
@@ -96,6 +96,9 @@
|
|
|
96
96
|
"type": "github",
|
|
97
97
|
"url": "https://github.com/sponsors/willfarrell"
|
|
98
98
|
},
|
|
99
|
+
"dependencies": {
|
|
100
|
+
"@middy/util": "7.1.3"
|
|
101
|
+
},
|
|
99
102
|
"peerDependencies": {
|
|
100
103
|
"@aws/durable-execution-sdk-js": "^1.0.0"
|
|
101
104
|
},
|
|
@@ -110,6 +113,5 @@
|
|
|
110
113
|
"@datastream/core": "0.0.42",
|
|
111
114
|
"@types/aws-lambda": "^8.0.0",
|
|
112
115
|
"@types/node": "^22.0.0"
|
|
113
|
-
}
|
|
114
|
-
"gitHead": "7a6c0fbb8ab71d6a2171e678697de9f237568431"
|
|
116
|
+
}
|
|
115
117
|
}
|