@middy/core 4.2.8 → 4.3.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 (4) hide show
  1. package/index.cjs +26 -4
  2. package/index.d.ts +100 -21
  3. package/index.js +24 -2
  4. package/package.json +3 -2
package/index.cjs CHANGED
@@ -6,13 +6,16 @@ Object.defineProperty(module, "exports", {
6
6
  enumerable: true,
7
7
  get: ()=>_default
8
8
  });
9
- const _promises = require("node:timers/promises");
9
+ const _nodeStream = require("node:stream");
10
+ const _promises = require("node:stream/promises");
11
+ const _promises1 = require("node:timers/promises");
10
12
  const defaultLambdaHandler = ()=>{};
11
13
  const defaultPlugin = {
12
14
  timeoutEarlyInMillis: 5,
13
15
  timeoutEarlyResponse: ()=>{
14
16
  throw new Error('Timeout');
15
- }
17
+ },
18
+ streamifyResponse: false
16
19
  };
17
20
  const middy = (lambdaHandler = defaultLambdaHandler, plugin = {})=>{
18
21
  if (typeof lambdaHandler !== 'function') {
@@ -28,7 +31,7 @@ const middy = (lambdaHandler = defaultLambdaHandler, plugin = {})=>{
28
31
  const beforeMiddlewares = [];
29
32
  const afterMiddlewares = [];
30
33
  const onErrorMiddlewares = [];
31
- const middy = (event = {}, context = {})=>{
34
+ const middyHandler = (event = {}, context = {})=>{
32
35
  plugin.requestStart?.();
33
36
  const request = {
34
37
  event,
@@ -45,6 +48,25 @@ const middy = (lambdaHandler = defaultLambdaHandler, plugin = {})=>{
45
48
  ...onErrorMiddlewares
46
49
  ], plugin);
47
50
  };
51
+ const middy = plugin.streamifyResponse ? awslambda.streamifyResponse(async (event, responseStream, context)=>{
52
+ const response = await middyHandler(event, context);
53
+ response.body ??= '';
54
+ let { body } = response;
55
+ if (typeof body === 'string') {
56
+ function* iterator(input) {
57
+ const size = 16 * 1024;
58
+ let position = 0;
59
+ const length = input.length;
60
+ while(position < length){
61
+ yield input.substring(position, position + size);
62
+ position += size;
63
+ }
64
+ }
65
+ body = _nodeStream.Readable.from(iterator(response.body));
66
+ }
67
+ responseStream = awslambda.HttpResponseStream.from(responseStream, response);
68
+ await (0, _promises.pipeline)(body, responseStream);
69
+ }) : middyHandler;
48
70
  middy.use = (middlewares)=>{
49
71
  if (!Array.isArray(middlewares)) {
50
72
  middlewares = [
@@ -93,7 +115,7 @@ const runRequest = async (request, beforeMiddlewares, lambdaHandler, afterMiddle
93
115
  lambdaHandler(request.event, request.context, {
94
116
  signal: handlerAbort.signal
95
117
  }),
96
- timeoutEarly ? (0, _promises.setTimeout)(request.context.getRemainingTimeInMillis() - plugin.timeoutEarlyInMillis, undefined, {
118
+ timeoutEarly ? (0, _promises1.setTimeout)(request.context.getRemainingTimeInMillis() - plugin.timeoutEarlyInMillis, undefined, {
97
119
  signal: timeoutAbort.signal
98
120
  }).then(()=>{
99
121
  handlerAbort.abort();
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,9 +21,15 @@ 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
+ > {
25
33
  event: TEvent
26
34
  context: TContext
27
35
  response: TResult | null
@@ -31,9 +39,19 @@ export interface Request<TEvent = any, TResult = any, TErr = Error, TContext ext
31
39
  }
32
40
  }
33
41
 
34
- declare type MiddlewareFn<TEvent = any, TResult = any, TErr = Error, TContext extends LambdaContext = LambdaContext> = (request: Request<TEvent, TResult, TErr, TContext>) => any
42
+ declare type MiddlewareFn<
43
+ TEvent = any,
44
+ TResult = any,
45
+ TErr = Error,
46
+ TContext extends LambdaContext = LambdaContext
47
+ > = (request: Request<TEvent, TResult, TErr, TContext>) => any
35
48
 
36
- export interface MiddlewareObj<TEvent = unknown, TResult = any, TErr = Error, TContext extends LambdaContext = LambdaContext> {
49
+ export interface MiddlewareObj<
50
+ TEvent = unknown,
51
+ TResult = any,
52
+ TErr = Error,
53
+ TContext extends LambdaContext = LambdaContext
54
+ > {
37
55
  before?: MiddlewareFn<TEvent, TResult, TErr, TContext>
38
56
  after?: MiddlewareFn<TEvent, TResult, TErr, TContext>
39
57
  onError?: MiddlewareFn<TEvent, TResult, TErr, TContext>
@@ -41,40 +59,101 @@ export interface MiddlewareObj<TEvent = unknown, TResult = any, TErr = Error, TC
41
59
 
42
60
  // The AWS provided Handler type uses void | Promise<TResult> so we have no choice but to follow and suppress the linter warning
43
61
  // 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>
62
+ type MiddyInputHandler<
63
+ TEvent,
64
+ TResult,
65
+ TContext extends LambdaContext = LambdaContext
66
+ > = (
67
+ event: TEvent,
68
+ context: TContext,
69
+ callback: LambdaCallback<TResult>
70
+ ) => // eslint-disable-next-line @typescript-eslint/no-invalid-void-type
71
+ void | Promise<TResult>
72
+ type MiddyInputPromiseHandler<
73
+ TEvent,
74
+ TResult,
75
+ TContext extends LambdaContext = LambdaContext
76
+ > = (event: TEvent, context: TContext) => Promise<TResult>
46
77
 
47
- export interface MiddyfiedHandler<TEvent = any, TResult = any, TErr = Error, TContext extends LambdaContext = LambdaContext> extends MiddyInputHandler<TEvent, TResult, TContext>,
78
+ export interface MiddyfiedHandler<
79
+ TEvent = any,
80
+ TResult = any,
81
+ TErr = Error,
82
+ TContext extends LambdaContext = LambdaContext
83
+ > extends MiddyInputHandler<TEvent, TResult, TContext>,
48
84
  MiddyInputPromiseHandler<TEvent, TResult, TContext> {
49
85
  use: UseFn<TEvent, TResult, TErr, TContext>
50
86
  before: AttachMiddlewareFn<TEvent, TResult, TErr, TContext>
51
87
  after: AttachMiddlewareFn<TEvent, TResult, TErr, TContext>
52
88
  onError: AttachMiddlewareFn<TEvent, TResult, TErr, TContext>
53
- handler: <TAdditional>(handler: MiddlewareHandler<LambdaHandler<TEvent & TAdditional, TResult>, TContext>) => MiddyfiedHandler<TEvent, TResult, TErr, TContext>
89
+ handler: <TAdditional>(
90
+ handler: MiddlewareHandler<
91
+ LambdaHandler<TEvent & TAdditional, TResult>,
92
+ TContext
93
+ >
94
+ ) => MiddyfiedHandler<TEvent, TResult, TErr, TContext>
54
95
  }
55
96
 
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>
97
+ declare type AttachMiddlewareFn<
98
+ TEvent = any,
99
+ TResult = any,
100
+ TErr = Error,
101
+ TContext extends LambdaContext = LambdaContext
102
+ > = (
103
+ middleware: MiddlewareFn<TEvent, TResult, TErr, TContext>
104
+ ) => MiddyfiedHandler<TEvent, TResult, TErr, TContext>
58
105
 
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>
106
+ declare type AttachMiddlewareObj<
107
+ TEvent = any,
108
+ TResult = any,
109
+ TErr = Error,
110
+ TContext extends LambdaContext = LambdaContext
111
+ > = (
112
+ middleware: MiddlewareObj<TEvent, TResult, TErr, TContext>
113
+ ) => MiddyfiedHandler<TEvent, TResult, TErr, TContext>
61
114
 
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
115
+ declare type UseFn<
116
+ TEvent = any,
117
+ TResult = any,
118
+ TErr = Error,
119
+ TContext extends LambdaContext = LambdaContext
120
+ > = <TMiddleware extends MiddlewareObj<any, any, Error, any>>(
121
+ middlewares: TMiddleware | TMiddleware[]
122
+ ) => TMiddleware extends MiddlewareObj<
123
+ infer TMiddlewareEvent,
124
+ any,
125
+ Error,
126
+ infer TMiddlewareContext
127
+ >
128
+ ? MiddyfiedHandler<
129
+ TMiddlewareEvent & TEvent,
130
+ TResult,
131
+ TErr,
132
+ TMiddlewareContext & TContext
133
+ > // always true
134
+ : never
66
135
 
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
136
+ declare type MiddlewareHandler<
137
+ THandler extends LambdaHandler<any, any>,
138
+ TContext extends LambdaContext = LambdaContext
139
+ > = THandler extends LambdaHandler<infer TEvent, infer TResult> // always true
140
+ ? MiddyInputHandler<TEvent, TResult, TContext>
141
+ : never
71
142
 
72
143
  /**
73
144
  * Middy factory function. Use it to wrap your existing handler to enable middlewares on it.
74
145
  * @param handler your original AWS Lambda function
75
146
  * @param plugin wraps around each middleware and handler to add custom lifecycle behaviours (e.g. to profile performance)
76
147
  */
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>
148
+ declare function middy<
149
+ TEvent = unknown,
150
+ TResult = any,
151
+ TErr = Error,
152
+ TContext extends LambdaContext = LambdaContext
153
+ > (
154
+ handler?: MiddlewareHandler<LambdaHandler<TEvent, TResult>, TContext>,
155
+ plugin?: PluginObject
156
+ ): MiddyfiedHandler<TEvent, TResult, TErr, TContext>
78
157
 
79
158
  declare namespace middy {
80
159
  export {
package/index.js CHANGED
@@ -1,10 +1,13 @@
1
+ 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
8
  throw new Error('Timeout');
7
- }
9
+ },
10
+ streamifyResponse: false
8
11
  };
9
12
  const middy = (lambdaHandler = defaultLambdaHandler, plugin = {})=>{
10
13
  if (typeof lambdaHandler !== 'function') {
@@ -20,7 +23,7 @@ const middy = (lambdaHandler = defaultLambdaHandler, plugin = {})=>{
20
23
  const beforeMiddlewares = [];
21
24
  const afterMiddlewares = [];
22
25
  const onErrorMiddlewares = [];
23
- const middy = (event = {}, context = {})=>{
26
+ const middyHandler = (event = {}, context = {})=>{
24
27
  plugin.requestStart?.();
25
28
  const request = {
26
29
  event,
@@ -37,6 +40,25 @@ const middy = (lambdaHandler = defaultLambdaHandler, plugin = {})=>{
37
40
  ...onErrorMiddlewares
38
41
  ], plugin);
39
42
  };
43
+ const middy = plugin.streamifyResponse ? awslambda.streamifyResponse(async (event, responseStream, context)=>{
44
+ const response = await middyHandler(event, context);
45
+ response.body ??= '';
46
+ let { body } = response;
47
+ if (typeof body === 'string') {
48
+ function* iterator(input) {
49
+ const size = 16 * 1024;
50
+ let position = 0;
51
+ const length = input.length;
52
+ while(position < length){
53
+ yield input.substring(position, position + size);
54
+ position += size;
55
+ }
56
+ }
57
+ body = Readable.from(iterator(response.body));
58
+ }
59
+ responseStream = awslambda.HttpResponseStream.from(responseStream, response);
60
+ await pipeline(body, responseStream);
61
+ }) : middyHandler;
40
62
  middy.use = (middlewares)=>{
41
63
  if (!Array.isArray(middlewares)) {
42
64
  middlewares = [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@middy/core",
3
- "version": "4.2.8",
3
+ "version": "4.3.1",
4
4
  "description": "🛵 The stylish Node.js middleware engine for AWS Lambda (core package)",
5
5
  "type": "module",
6
6
  "engines": {
@@ -62,8 +62,9 @@
62
62
  "url": "https://github.com/sponsors/willfarrell"
63
63
  },
64
64
  "devDependencies": {
65
+ "@datastream/core": "0.0.29",
65
66
  "@types/aws-lambda": "^8.10.76",
66
67
  "@types/node": "^18.0.0"
67
68
  },
68
- "gitHead": "9e7eec0f50fd1edef232edb7a99c035f9bc1f159"
69
+ "gitHead": "e7576b56f165591acc427fd567b6cba8d4874340"
69
70
  }