@middy/core 2.5.3 → 3.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/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2017-2021 Luciano Mammino, will Farrell and the [Middy team](https://github.com/middyjs/middy/graphs/contributors)
3
+ Copyright (c) 2017-2022 Luciano Mammino, will Farrell and the [Middy team](https://github.com/middyjs/middy/graphs/contributors)
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -47,7 +47,7 @@ Everyone is very welcome to contribute to this repository. Feel free to [raise i
47
47
 
48
48
  ## License
49
49
 
50
- Licensed under [MIT License](LICENSE). Copyright (c) 2017-2021 Luciano Mammino, will Farrell, and the [Middy team](https://github.com/middyjs/middy/graphs/contributors).
50
+ Licensed under [MIT License](LICENSE). Copyright (c) 2017-2022 Luciano Mammino, will Farrell, and the [Middy team](https://github.com/middyjs/middy/graphs/contributors).
51
51
 
52
52
  <a href="https://app.fossa.io/projects/git%2Bgithub.com%2Fmiddyjs%2Fmiddy?ref=badge_large">
53
53
  <img src="https://app.fossa.io/api/projects/git%2Bgithub.com%2Fmiddyjs%2Fmiddy.svg?type=large" alt="FOSSA Status" style="max-width:100%;">
package/index.d.ts CHANGED
@@ -9,11 +9,14 @@ declare type PluginHookWithMiddlewareName = (middlewareName: string) => void
9
9
  declare type PluginHookPromise = (request: Request) => Promise<unknown> | unknown
10
10
 
11
11
  interface PluginObject {
12
+ internal?: any
12
13
  beforePrefetch?: PluginHook
13
14
  requestStart?: PluginHook
14
15
  beforeMiddleware?: PluginHookWithMiddlewareName
15
16
  afterMiddleware?: PluginHookWithMiddlewareName
16
17
  beforeHandler?: PluginHook
18
+ timeoutEarlyInMillis?: number
19
+ timeoutEarlyResponse?: PluginHook
17
20
  afterHandler?: PluginHook
18
21
  requestEnd?: PluginHookPromise
19
22
  }
@@ -33,7 +36,7 @@ declare type MiddlewareFn<TEvent = any, TResult = any, TErr = Error, TContext ex
33
36
  export interface MiddlewareObj<TEvent = any, TResult = any, TErr = Error, TContext extends LambdaContext = LambdaContext> {
34
37
  before?: MiddlewareFn<TEvent, TResult, TErr, TContext>
35
38
  after?: MiddlewareFn<TEvent, TResult, TErr, TContext>
36
- onError?: MiddlewareFn<TEvent, TResult, TErr>
39
+ onError?: MiddlewareFn<TEvent, TResult, TErr, TContext>
37
40
  }
38
41
 
39
42
  // The AWS provided Handler type uses void | Promise<TResult> so we have no choice but to follow and suppress the linter warning
@@ -42,15 +45,9 @@ type MiddyInputHandler<TEvent, TResult, TContext extends LambdaContext = LambdaC
42
45
 
43
46
  export interface MiddyfiedHandler<TEvent = any, TResult = any, TErr = Error, TContext extends LambdaContext = LambdaContext> extends MiddyInputHandler<TEvent, TResult, TContext> {
44
47
  use: UseFn<TEvent, TResult, TErr, TContext>
45
- applyMiddleware: AttachMiddlewareObj<TEvent, TResult, TErr, TContext>
46
48
  before: AttachMiddlewareFn<TEvent, TResult, TErr, TContext>
47
49
  after: AttachMiddlewareFn<TEvent, TResult, TErr, TContext>
48
50
  onError: AttachMiddlewareFn<TEvent, TResult, TErr, TContext>
49
- __middlewares: {
50
- before: Array<MiddlewareFn<TEvent, TResult, TErr, TContext>>
51
- after: Array<MiddlewareFn<TEvent, TResult, TErr, TContext>>
52
- onError: Array<MiddlewareFn<TEvent, TResult, TErr, TContext>>
53
- }
54
51
  }
55
52
 
56
53
  declare type AttachMiddlewareFn<TEvent = any, TResult = any, TErr = Error, TContext extends LambdaContext = LambdaContext> = (middleware: MiddlewareFn) => MiddyfiedHandler<TEvent, TResult, TErr, TContext>
package/index.js CHANGED
@@ -1,112 +1,129 @@
1
- "use strict";
1
+ import { AbortController } from 'node-abort-controller';
2
2
 
3
- const middy = (baseHandler = () => {}, plugin) => {
4
- var _plugin$beforePrefetc;
3
+ const defaultBaseHandler = () => {};
5
4
 
6
- plugin === null || plugin === void 0 ? void 0 : (_plugin$beforePrefetc = plugin.beforePrefetch) === null || _plugin$beforePrefetc === void 0 ? void 0 : _plugin$beforePrefetc.call(plugin);
5
+ const defaultPlugin = {
6
+ timeoutEarlyInMillis: 5,
7
+ timeoutEarlyResponse: () => {
8
+ throw new Error('Timeout');
9
+ }
10
+ };
11
+
12
+ const middy = (baseHandler = defaultBaseHandler, plugin = {}) => {
13
+ var _plugin$beforePrefetc, _plugin;
14
+
15
+ if (typeof baseHandler !== 'function') {
16
+ plugin = baseHandler;
17
+ baseHandler = defaultBaseHandler;
18
+ }
19
+
20
+ plugin = { ...defaultPlugin,
21
+ ...plugin
22
+ };
23
+ (_plugin$beforePrefetc = (_plugin = plugin).beforePrefetch) === null || _plugin$beforePrefetc === void 0 ? void 0 : _plugin$beforePrefetc.call(_plugin);
7
24
  const beforeMiddlewares = [];
8
25
  const afterMiddlewares = [];
9
26
  const onErrorMiddlewares = [];
10
27
 
11
- const instance = (event = {}, context = {}) => {
12
- var _plugin$requestStart;
28
+ const middy = (event = {}, context = {}) => {
29
+ var _plugin$requestStart, _plugin2;
13
30
 
14
- plugin === null || plugin === void 0 ? void 0 : (_plugin$requestStart = plugin.requestStart) === null || _plugin$requestStart === void 0 ? void 0 : _plugin$requestStart.call(plugin);
31
+ (_plugin$requestStart = (_plugin2 = plugin).requestStart) === null || _plugin$requestStart === void 0 ? void 0 : _plugin$requestStart.call(_plugin2);
15
32
  const request = {
16
33
  event,
17
34
  context,
18
35
  response: undefined,
19
36
  error: undefined,
20
- internal: {}
37
+ internal: plugin.internal ?? {}
21
38
  };
22
39
  return runRequest(request, [...beforeMiddlewares], baseHandler, [...afterMiddlewares], [...onErrorMiddlewares], plugin);
23
40
  };
24
41
 
25
- instance.use = middlewares => {
26
- if (Array.isArray(middlewares)) {
27
- for (const middleware of middlewares) {
28
- instance.applyMiddleware(middleware);
29
- }
30
-
31
- return instance;
42
+ middy.use = middlewares => {
43
+ if (!Array.isArray(middlewares)) {
44
+ middlewares = [middlewares];
32
45
  }
33
46
 
34
- return instance.applyMiddleware(middlewares);
35
- };
47
+ for (const middleware of middlewares) {
48
+ const {
49
+ before,
50
+ after,
51
+ onError
52
+ } = middleware;
36
53
 
37
- instance.applyMiddleware = middleware => {
38
- const {
39
- before,
40
- after,
41
- onError
42
- } = middleware;
54
+ if (!before && !after && !onError) {
55
+ throw new Error('Middleware must be an object containing at least one key among "before", "after", "onError"');
56
+ }
43
57
 
44
- if (!before && !after && !onError) {
45
- throw new Error('Middleware must be an object containing at least one key among "before", "after", "onError"');
58
+ if (before) middy.before(before);
59
+ if (after) middy.after(after);
60
+ if (onError) middy.onError(onError);
46
61
  }
47
62
 
48
- if (before) instance.before(before);
49
- if (after) instance.after(after);
50
- if (onError) instance.onError(onError);
51
- return instance;
52
- }; // Inline Middlewares
53
-
63
+ return middy;
64
+ };
54
65
 
55
- instance.before = beforeMiddleware => {
66
+ middy.before = beforeMiddleware => {
56
67
  beforeMiddlewares.push(beforeMiddleware);
57
- return instance;
68
+ return middy;
58
69
  };
59
70
 
60
- instance.after = afterMiddleware => {
71
+ middy.after = afterMiddleware => {
61
72
  afterMiddlewares.unshift(afterMiddleware);
62
- return instance;
73
+ return middy;
63
74
  };
64
75
 
65
- instance.onError = onErrorMiddleware => {
66
- onErrorMiddlewares.push(onErrorMiddleware);
67
- return instance;
76
+ middy.onError = onErrorMiddleware => {
77
+ onErrorMiddlewares.unshift(onErrorMiddleware);
78
+ return middy;
68
79
  };
69
80
 
70
- instance.__middlewares = {
71
- before: beforeMiddlewares,
72
- after: afterMiddlewares,
73
- onError: onErrorMiddlewares
81
+ middy.handler = replaceBaseHandler => {
82
+ baseHandler = replaceBaseHandler;
74
83
  };
75
- return instance;
84
+
85
+ return middy;
76
86
  };
77
87
 
78
88
  const runRequest = async (request, beforeMiddlewares, baseHandler, afterMiddlewares, onErrorMiddlewares, plugin) => {
79
89
  try {
80
- await runMiddlewares(request, beforeMiddlewares, plugin); // Check if before stack hasn't exit early
90
+ await runMiddlewares(request, beforeMiddlewares, plugin);
81
91
 
82
92
  if (request.response === undefined) {
83
93
  var _plugin$beforeHandler, _plugin$afterHandler;
84
94
 
85
- plugin === null || plugin === void 0 ? void 0 : (_plugin$beforeHandler = plugin.beforeHandler) === null || _plugin$beforeHandler === void 0 ? void 0 : _plugin$beforeHandler.call(plugin);
86
- request.response = await baseHandler(request.event, request.context);
87
- plugin === null || plugin === void 0 ? void 0 : (_plugin$afterHandler = plugin.afterHandler) === null || _plugin$afterHandler === void 0 ? void 0 : _plugin$afterHandler.call(plugin);
95
+ (_plugin$beforeHandler = plugin.beforeHandler) === null || _plugin$beforeHandler === void 0 ? void 0 : _plugin$beforeHandler.call(plugin);
96
+ const handlerAbort = new AbortController();
97
+ const timeoutAbort = new AbortController();
98
+ request.response = await Promise.race([baseHandler(request.event, request.context, {
99
+ signal: handlerAbort.signal
100
+ }), plugin.timeoutEarlyInMillis > 0 ? setTimeoutPromise(request.context.getRemainingTimeInMillis() - plugin.timeoutEarlyInMillis, {
101
+ signal: timeoutAbort.signal
102
+ }).then(() => {
103
+ handlerAbort.abort();
104
+ return plugin.timeoutEarlyResponse();
105
+ }) : Promise.race([])]);
106
+ timeoutAbort.abort();
107
+ (_plugin$afterHandler = plugin.afterHandler) === null || _plugin$afterHandler === void 0 ? void 0 : _plugin$afterHandler.call(plugin);
88
108
  await runMiddlewares(request, afterMiddlewares, plugin);
89
109
  }
90
110
  } catch (e) {
91
- // Reset response changes made by after stack before error thrown
92
111
  request.response = undefined;
93
112
  request.error = e;
94
113
 
95
114
  try {
96
115
  await runMiddlewares(request, onErrorMiddlewares, plugin);
97
116
  } catch (e) {
98
- // Save error that wasn't handled
99
117
  e.originalError = request.error;
100
118
  request.error = e;
101
119
  throw request.error;
102
- } // Catch if onError stack hasn't handled the error
103
-
120
+ }
104
121
 
105
122
  if (request.response === undefined) throw request.error;
106
123
  } finally {
107
124
  var _plugin$requestEnd;
108
125
 
109
- await (plugin === null || plugin === void 0 ? void 0 : (_plugin$requestEnd = plugin.requestEnd) === null || _plugin$requestEnd === void 0 ? void 0 : _plugin$requestEnd.call(plugin, request));
126
+ await ((_plugin$requestEnd = plugin.requestEnd) === null || _plugin$requestEnd === void 0 ? void 0 : _plugin$requestEnd.call(plugin, request));
110
127
  }
111
128
 
112
129
  return request.response;
@@ -116,9 +133,9 @@ const runMiddlewares = async (request, middlewares, plugin) => {
116
133
  for (const nextMiddleware of middlewares) {
117
134
  var _plugin$beforeMiddlew, _plugin$afterMiddlewa;
118
135
 
119
- plugin === null || plugin === void 0 ? void 0 : (_plugin$beforeMiddlew = plugin.beforeMiddleware) === null || _plugin$beforeMiddlew === void 0 ? void 0 : _plugin$beforeMiddlew.call(plugin, nextMiddleware === null || nextMiddleware === void 0 ? void 0 : nextMiddleware.name);
120
- const res = await (nextMiddleware === null || nextMiddleware === void 0 ? void 0 : nextMiddleware(request));
121
- plugin === null || plugin === void 0 ? void 0 : (_plugin$afterMiddlewa = plugin.afterMiddleware) === null || _plugin$afterMiddlewa === void 0 ? void 0 : _plugin$afterMiddlewa.call(plugin, nextMiddleware === null || nextMiddleware === void 0 ? void 0 : nextMiddleware.name); // short circuit chaining and respond early
136
+ (_plugin$beforeMiddlew = plugin.beforeMiddleware) === null || _plugin$beforeMiddlew === void 0 ? void 0 : _plugin$beforeMiddlew.call(plugin, nextMiddleware.name);
137
+ const res = await nextMiddleware(request);
138
+ (_plugin$afterMiddlewa = plugin.afterMiddleware) === null || _plugin$afterMiddlewa === void 0 ? void 0 : _plugin$afterMiddlewa.call(plugin, nextMiddleware.name);
122
139
 
123
140
  if (res !== undefined) {
124
141
  request.response = res;
@@ -127,4 +144,25 @@ const runMiddlewares = async (request, middlewares, plugin) => {
127
144
  }
128
145
  };
129
146
 
130
- module.exports = middy;
147
+ const setTimeoutPromise = (ms, {
148
+ signal
149
+ }) => {
150
+ if (signal.aborted) {
151
+ return Promise.reject(new Error('Aborted', 'AbortError'));
152
+ }
153
+
154
+ return new Promise((resolve, reject) => {
155
+ const abortHandler = () => {
156
+ clearTimeout(timeout);
157
+ reject(new Error('Aborted', 'AbortError'));
158
+ };
159
+
160
+ const timeout = setTimeout(() => {
161
+ resolve();
162
+ signal.removeEventListener('abort', abortHandler);
163
+ }, ms);
164
+ signal.addEventListener('abort', abortHandler);
165
+ });
166
+ };
167
+
168
+ export default middy;
package/package.json CHANGED
@@ -1,18 +1,19 @@
1
1
  {
2
2
  "name": "@middy/core",
3
- "version": "2.5.3",
3
+ "version": "3.0.0-alpha.2",
4
4
  "description": "🛵 The stylish Node.js middleware engine for AWS Lambda (core package)",
5
- "type": "commonjs",
5
+ "type": "module",
6
6
  "engines": {
7
- "node": ">=12"
7
+ "node": ">=14"
8
8
  },
9
9
  "engineStrict": true,
10
10
  "publishConfig": {
11
11
  "access": "public"
12
12
  },
13
- "main": "index.js",
13
+ "exports": "./index.js",
14
14
  "types": "index.d.ts",
15
15
  "files": [
16
+ "index.js",
16
17
  "index.d.ts"
17
18
  ],
18
19
  "scripts": {
@@ -43,7 +44,10 @@
43
44
  "homepage": "https://github.com/middyjs/middy#readme",
44
45
  "devDependencies": {
45
46
  "@types/aws-lambda": "^8.10.76",
46
- "@types/node": "^16.0.0"
47
+ "@types/node": "^17.0.0"
47
48
  },
48
- "gitHead": "690884d43b9cd632aeca9a5eba1612160b987cd4"
49
+ "gitHead": "de30419273ecbff08f367f47c7e320ec981cf145",
50
+ "dependencies": {
51
+ "node-abort-controller": "3.0.1"
52
+ }
49
53
  }