@middy/core 5.0.0-alpha.0 → 5.0.0-alpha.1

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 (5) hide show
  1. package/README.md +3 -2
  2. package/index.d.ts +120 -31
  3. package/index.js +201 -120
  4. package/package.json +6 -9
  5. 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://lgtm.com/projects/g/middyjs/middy/context:javascript">
23
- <img src="https://img.shields.io/lgtm/grade/javascript/g/middyjs/middy.svg?logo=lgtm&logoWidth=18" alt="Language grade: JavaScript" style="max-width:100%;">
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 = (request: Request) => Promise<unknown> | unknown
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<TEvent = any, TResult = any, TErr = Error, TContext extends LambdaContext = LambdaContext> {
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<TEvent = any, TResult = any, TErr = Error, TContext extends LambdaContext = LambdaContext> = (request: Request<TEvent, TResult, TErr, TContext>) => any
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<TEvent = unknown, TResult = any, TErr = Error, TContext extends LambdaContext = LambdaContext> {
37
- before?: MiddlewareFn<TEvent, TResult, TErr, TContext>
38
- after?: MiddlewareFn<TEvent, TResult, TErr, TContext>
39
- onError?: MiddlewareFn<TEvent, TResult, TErr, TContext>
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<TEvent, TResult, TContext extends LambdaContext = LambdaContext> = (event: TEvent, context: TContext, callback: LambdaCallback<TResult>) => void | Promise<TResult>
45
- type MiddyInputPromiseHandler<TEvent, TResult, TContext extends LambdaContext = LambdaContext> = (event: TEvent, context: TContext,) => Promise<TResult>
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<TEvent = any, TResult = any, TErr = Error, TContext extends LambdaContext = LambdaContext> extends MiddyInputHandler<TEvent, TResult, TContext>,
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>(handler: MiddlewareHandler<LambdaHandler<TEvent & TAdditional, TResult>, TContext>) => MiddyfiedHandler<TEvent, TResult, TErr, TContext>
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<TEvent = any, TResult = any, TErr = Error, TContext extends LambdaContext = LambdaContext> =
57
- (middleware: MiddlewareFn<TEvent, TResult, TErr, TContext>) => MiddyfiedHandler<TEvent, TResult, TErr, TContext>
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<TEvent = any, TResult = any, TErr = Error, TContext extends LambdaContext = LambdaContext> =
60
- (middleware: MiddlewareObj<TEvent, TResult, TErr, TContext>) => MiddyfiedHandler<TEvent, TResult, TErr, TContext>
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<TEvent = any, TResult = any, TErr = Error, TContext extends LambdaContext = LambdaContext> =
63
- <TMiddleware extends MiddlewareObj<any, any, Error, any>>(middlewares: TMiddleware | TMiddleware[]) => TMiddleware extends MiddlewareObj<infer TMiddlewareEvent, any, Error, infer TMiddlewareContext>
64
- ? MiddyfiedHandler<TMiddlewareEvent & TEvent, TResult, TErr, TMiddlewareContext & TContext> // always true
65
- : never
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<THandler extends LambdaHandler<any, any>, TContext extends LambdaContext = LambdaContext> =
68
- THandler extends LambdaHandler<infer TEvent, infer TResult> // always true
69
- ? MiddyInputHandler<TEvent, TResult, TContext>
70
- : never
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<TEvent = unknown, TResult = any, TErr = Error, TContext extends LambdaContext = LambdaContext> (handler?: MiddlewareHandler<LambdaHandler<TEvent, TResult>, TContext>, plugin?: PluginObject): MiddyfiedHandler<TEvent, TResult, TErr, TContext>
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,128 +1,209 @@
1
- import { setTimeout } from 'node:timers/promises';
2
- const defaultLambdaHandler = ()=>{};
1
+ /* global awslambda */
2
+ import { Readable } from 'node:stream'
3
+ import { pipeline } from 'node:stream/promises'
4
+ import { setTimeout } from 'node:timers/promises'
5
+
6
+ const defaultLambdaHandler = () => {}
3
7
  const defaultPlugin = {
4
- timeoutEarlyInMillis: 5,
5
- timeoutEarlyResponse: ()=>{
6
- throw new Error('Timeout');
7
- }
8
- };
9
- const middy = (lambdaHandler = defaultLambdaHandler, plugin = {})=>{
10
- if (typeof lambdaHandler !== 'function') {
11
- plugin = lambdaHandler;
12
- lambdaHandler = defaultLambdaHandler;
8
+ timeoutEarlyInMillis: 5,
9
+ timeoutEarlyResponse: () => {
10
+ const err = new Error('[AbortError]: The operation was aborted.', {
11
+ cause: { package: '@middy/core' }
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
17
+ }
18
+
19
+ const middy = (lambdaHandler = defaultLambdaHandler, plugin = {}) => {
20
+ // Allow base handler to be set using .handler()
21
+ if (typeof lambdaHandler !== 'function') {
22
+ plugin = lambdaHandler
23
+ lambdaHandler = defaultLambdaHandler
24
+ }
25
+ plugin = { ...defaultPlugin, ...plugin }
26
+ plugin.timeoutEarly = plugin.timeoutEarlyInMillis > 0
27
+
28
+ plugin.beforePrefetch?.()
29
+ const beforeMiddlewares = []
30
+ const afterMiddlewares = []
31
+ const onErrorMiddlewares = []
32
+
33
+ const middyHandler = (event = {}, context = {}) => {
34
+ plugin.requestStart?.()
35
+ const request = {
36
+ event,
37
+ context,
38
+ response: undefined,
39
+ error: undefined,
40
+ internal: plugin.internal ?? {}
13
41
  }
14
- plugin = {
15
- ...defaultPlugin,
16
- ...plugin
17
- };
18
- plugin.timeoutEarly = plugin.timeoutEarlyInMillis > 0;
19
- plugin.beforePrefetch?.();
20
- const beforeMiddlewares = [];
21
- const afterMiddlewares = [];
22
- const onErrorMiddlewares = [];
23
- const middy = (event = {}, context = {})=>{
24
- plugin.requestStart?.();
25
- const request = {
26
- event,
27
- context,
28
- response: undefined,
29
- error: undefined,
30
- internal: plugin.internal ?? {}
31
- };
32
- return runRequest(request, [
33
- ...beforeMiddlewares
34
- ], lambdaHandler, [
35
- ...afterMiddlewares
36
- ], [
37
- ...onErrorMiddlewares
38
- ], plugin);
39
- };
40
- middy.use = (middlewares)=>{
41
- if (!Array.isArray(middlewares)) {
42
- middlewares = [
43
- middlewares
44
- ];
45
- }
46
- for (const middleware of middlewares){
47
- const { before , after , onError } = middleware;
48
- if (!before && !after && !onError) {
49
- throw new Error('Middleware must be an object containing at least one key among "before", "after", "onError"');
50
- }
51
- if (before) middy.before(before);
52
- if (after) middy.after(after);
53
- if (onError) middy.onError(onError);
42
+
43
+ return runRequest(
44
+ request,
45
+ [...beforeMiddlewares],
46
+ lambdaHandler,
47
+ [...afterMiddlewares],
48
+ [...onErrorMiddlewares],
49
+ plugin
50
+ )
51
+ }
52
+ const middy = plugin.streamifyResponse
53
+ ? awslambda.streamifyResponse(async (event, responseStream, context) => {
54
+ const handlerResponse = await middyHandler(event, context)
55
+
56
+ let handlerBody = handlerResponse
57
+ if (handlerResponse.statusCode) {
58
+ handlerBody = handlerResponse.body ?? ''
59
+ responseStream = awslambda.HttpResponseStream.from(
60
+ responseStream,
61
+ handlerResponse
62
+ )
63
+ }
64
+
65
+ // Source @datastream/core (MIT)
66
+ let handlerStream
67
+ if (handlerBody._readableState) {
68
+ handlerStream = handlerBody
69
+ } else if (typeof handlerBody === 'string') {
70
+ function * iterator (input) {
71
+ const size = 16384 // 16 * 1024 // Node.js default
72
+ let position = 0
73
+ const length = input.length
74
+ while (position < length) {
75
+ yield input.substring(position, position + size)
76
+ position += size
77
+ }
54
78
  }
55
- return middy;
56
- };
57
- middy.before = (beforeMiddleware)=>{
58
- beforeMiddlewares.push(beforeMiddleware);
59
- return middy;
60
- };
61
- middy.after = (afterMiddleware)=>{
62
- afterMiddlewares.unshift(afterMiddleware);
63
- return middy;
64
- };
65
- middy.onError = (onErrorMiddleware)=>{
66
- onErrorMiddlewares.unshift(onErrorMiddleware);
67
- return middy;
68
- };
69
- middy.handler = (replaceLambdaHandler)=>{
70
- lambdaHandler = replaceLambdaHandler;
71
- return middy;
72
- };
73
- return middy;
74
- };
75
- const runRequest = async (request, beforeMiddlewares, lambdaHandler, afterMiddlewares, onErrorMiddlewares, plugin)=>{
76
- let timeoutAbort;
77
- const timeoutEarly = plugin.timeoutEarly && request.context.getRemainingTimeInMillis;
79
+ handlerStream = Readable.from(iterator(handlerBody))
80
+ }
81
+
82
+ if (!handlerStream) {
83
+ throw new Error('handler response not a ReadableStream')
84
+ }
85
+
86
+ await pipeline(handlerStream, responseStream)
87
+ })
88
+ : middyHandler
89
+
90
+ middy.use = (middlewares) => {
91
+ if (!Array.isArray(middlewares)) {
92
+ middlewares = [middlewares]
93
+ }
94
+ for (const middleware of middlewares) {
95
+ const { before, after, onError } = middleware
96
+
97
+ if (!before && !after && !onError) {
98
+ throw new Error(
99
+ 'Middleware must be an object containing at least one key among "before", "after", "onError"'
100
+ )
101
+ }
102
+
103
+ if (before) middy.before(before)
104
+ if (after) middy.after(after)
105
+ if (onError) middy.onError(onError)
106
+ }
107
+ return middy
108
+ }
109
+
110
+ // Inline Middlewares
111
+ middy.before = (beforeMiddleware) => {
112
+ beforeMiddlewares.push(beforeMiddleware)
113
+ return middy
114
+ }
115
+ middy.after = (afterMiddleware) => {
116
+ afterMiddlewares.unshift(afterMiddleware)
117
+ return middy
118
+ }
119
+ middy.onError = (onErrorMiddleware) => {
120
+ onErrorMiddlewares.unshift(onErrorMiddleware)
121
+ return middy
122
+ }
123
+ middy.handler = (replaceLambdaHandler) => {
124
+ lambdaHandler = replaceLambdaHandler
125
+ return middy
126
+ }
127
+
128
+ return middy
129
+ }
130
+
131
+ const runRequest = async (
132
+ request,
133
+ beforeMiddlewares,
134
+ lambdaHandler,
135
+ afterMiddlewares,
136
+ onErrorMiddlewares,
137
+ plugin
138
+ ) => {
139
+ let timeoutAbort
140
+ const timeoutEarly =
141
+ plugin.timeoutEarly && request.context.getRemainingTimeInMillis // disable when AWS context missing (tests, containers)
142
+ try {
143
+ await runMiddlewares(request, beforeMiddlewares, plugin)
144
+ // Check if before stack hasn't exit early
145
+ if (typeof request.response === 'undefined') {
146
+ plugin.beforeHandler?.()
147
+
148
+ const handlerAbort = new AbortController()
149
+
150
+ if (timeoutEarly) timeoutAbort = new AbortController()
151
+ request.response = await Promise.race([
152
+ lambdaHandler(request.event, request.context, {
153
+ signal: handlerAbort.signal
154
+ }),
155
+ timeoutEarly
156
+ ? setTimeout(
157
+ request.context.getRemainingTimeInMillis() -
158
+ plugin.timeoutEarlyInMillis,
159
+ undefined,
160
+ { signal: timeoutAbort.signal }
161
+ ).then(() => {
162
+ handlerAbort.abort()
163
+ return plugin.timeoutEarlyResponse()
164
+ })
165
+ : Promise.race([])
166
+ ])
167
+ timeoutAbort?.abort() // lambdaHandler may not be a promise
168
+
169
+ plugin.afterHandler?.()
170
+ await runMiddlewares(request, afterMiddlewares, plugin)
171
+ }
172
+ } catch (e) {
173
+ timeoutAbort?.abort() // timeout should be aborted on errors
174
+
175
+ // Reset response changes made by after stack before error thrown
176
+ request.response = undefined
177
+ request.error = e
78
178
  try {
79
- await runMiddlewares(request, beforeMiddlewares, plugin);
80
- if (typeof request.response === 'undefined') {
81
- plugin.beforeHandler?.();
82
- const handlerAbort = new AbortController();
83
- if (timeoutEarly) timeoutAbort = new AbortController();
84
- request.response = await Promise.race([
85
- lambdaHandler(request.event, request.context, {
86
- signal: handlerAbort.signal
87
- }),
88
- timeoutEarly ? setTimeout(request.context.getRemainingTimeInMillis() - plugin.timeoutEarlyInMillis, undefined, {
89
- signal: timeoutAbort.signal
90
- }).then(()=>{
91
- handlerAbort.abort();
92
- return plugin.timeoutEarlyResponse();
93
- }) : Promise.race([])
94
- ]);
95
- timeoutAbort?.abort();
96
- plugin.afterHandler?.();
97
- await runMiddlewares(request, afterMiddlewares, plugin);
98
- }
179
+ await runMiddlewares(request, onErrorMiddlewares, plugin)
99
180
  } catch (e) {
100
- timeoutAbort?.abort();
101
- request.response = undefined;
102
- request.error = e;
103
- try {
104
- await runMiddlewares(request, onErrorMiddlewares, plugin);
105
- } catch (e) {
106
- e.originalError = request.error;
107
- request.error = e;
108
- throw request.error;
109
- }
110
- if (typeof request.response === 'undefined') throw request.error;
111
- } finally{
112
- await plugin.requestEnd?.(request);
181
+ // Save error that wasn't handled
182
+ e.originalError = request.error
183
+ request.error = e
184
+
185
+ throw request.error
113
186
  }
114
- return request.response;
115
- };
116
- const runMiddlewares = async (request, middlewares, plugin)=>{
117
- for (const nextMiddleware of middlewares){
118
- plugin.beforeMiddleware?.(nextMiddleware.name);
119
- const res = await nextMiddleware(request);
120
- plugin.afterMiddleware?.(nextMiddleware.name);
121
- if (typeof res !== 'undefined') {
122
- request.response = res;
123
- return;
124
- }
187
+ // Catch if onError stack hasn't handled the error
188
+ if (typeof request.response === 'undefined') throw request.error
189
+ } finally {
190
+ await plugin.requestEnd?.(request)
191
+ }
192
+
193
+ return request.response
194
+ }
195
+
196
+ const runMiddlewares = async (request, middlewares, plugin) => {
197
+ for (const nextMiddleware of middlewares) {
198
+ plugin.beforeMiddleware?.(nextMiddleware.name)
199
+ const res = await nextMiddleware(request)
200
+ plugin.afterMiddleware?.(nextMiddleware.name)
201
+ // short circuit chaining and respond early
202
+ if (typeof res !== 'undefined') {
203
+ request.response = res
204
+ return
125
205
  }
126
- };
127
- export default middy;
206
+ }
207
+ }
128
208
 
209
+ export default middy
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@middy/core",
3
- "version": "5.0.0-alpha.0",
3
+ "version": "5.0.0-alpha.1",
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": "^18.0.0"
60
+ "@types/node": "^20.0.0"
67
61
  },
68
- "gitHead": "08c35e3dba9efdad0b86666ce206ce302cc65d07"
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
-