Skip to content

Commit f46ae7c

Browse files
authored
fix(event-handler): allow http handlers to return duplex streams (#4629)
1 parent ada48bb commit f46ae7c

File tree

2 files changed

+28
-3
lines changed

2 files changed

+28
-3
lines changed

packages/event-handler/src/rest/utils.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Readable, Writable } from 'node:stream';
1+
import { Duplex, Readable, Writable } from 'node:stream';
22
import {
33
isRecord,
44
isRegExp,
@@ -112,7 +112,7 @@ export const isNodeReadableStream = (value: unknown): value is Readable => {
112112
return (
113113
value != null &&
114114
typeof value === 'object' &&
115-
value instanceof Readable &&
115+
(value instanceof Readable || value instanceof Duplex) &&
116116
'readable' in value &&
117117
'read' in value &&
118118
typeof value.read === 'function'

packages/event-handler/tests/unit/rest/Router/streaming.test.ts

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Readable } from 'node:stream';
1+
import { Duplex, PassThrough, Readable } from 'node:stream';
22
import context from '@aws-lambda-powertools/testing-utils/context';
33
import { describe, expect, it, vi } from 'vitest';
44
import { UnauthorizedError } from '../../../../src/rest/errors.js';
@@ -306,4 +306,29 @@ describe('Class: Router - Streaming', () => {
306306
app.resolveStream(invalidEvent, context, { responseStream })
307307
).rejects.toThrow();
308308
});
309+
310+
it('handles duplex stream body', async () => {
311+
// Prepare
312+
const app = new Router();
313+
const passThrough = new PassThrough();
314+
passThrough.write(Buffer.from('{"message":"duplex stream body"}'));
315+
passThrough.end();
316+
317+
app.get('/test', () => ({
318+
statusCode: 200,
319+
body: Duplex.from(passThrough),
320+
}));
321+
322+
const responseStream = new MockResponseStream();
323+
324+
// Act
325+
await app.resolveStream(createTestEvent('/test', 'GET'), context, {
326+
responseStream,
327+
});
328+
329+
// Assess
330+
const { prelude, body } = parseStreamOutput(responseStream.chunks);
331+
expect(prelude.statusCode).toBe(200);
332+
expect(JSON.parse(body)).toEqual({ message: 'duplex stream body' });
333+
});
309334
});

0 commit comments

Comments
 (0)