Skip to content

Commit

Permalink
feat: support custom streams
Browse files Browse the repository at this point in the history
  • Loading branch information
KristapsR committed Aug 13, 2024
1 parent cfdb77f commit 1fc1825
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 4 deletions.
7 changes: 7 additions & 0 deletions __tests__/response/body.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
'use strict'

const response = require('../../test-helpers/context').response
const CustomStream = require('../../test-helpers/stream')
const assert = require('assert')
const fs = require('fs')
const Stream = require('stream')
Expand Down Expand Up @@ -109,6 +110,12 @@ describe('res.body=', () => {
assert.strictEqual('application/octet-stream', res.header['content-type'])
})

it('should support custom stream', () => {
const res = response()
res.body = new CustomStream.Readable()
assert.strictEqual('application/octet-stream', res.header['content-type'])
})

it('should add error handler to the stream, but only once', () => {
const res = response()
const body = new Stream.PassThrough()
Expand Down
3 changes: 2 additions & 1 deletion lib/application.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ const Emitter = require('events')
const util = require('util')
const Stream = require('stream')
const http = require('http')
const isStream = require('./is-stream.js')
const only = require('./only.js')
const { HttpError } = require('http-errors')

Expand Down Expand Up @@ -303,10 +304,10 @@ function respond (ctx) {

if (Buffer.isBuffer(body)) return res.end(body)
if (typeof body === 'string') return res.end(body)
if (body instanceof Stream) return body.pipe(res)
if (body instanceof Blob) return Stream.Readable.from(body.stream()).pipe(res)
if (body instanceof ReadableStream) return Stream.Readable.from(body).pipe(res)
if (body instanceof Response) return Stream.Readable.from(body?.body).pipe(res)
if (isStream(body)) return body.pipe(res)

// body: json
body = JSON.stringify(body)
Expand Down
18 changes: 18 additions & 0 deletions lib/is-stream.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
'use strict'

const Stream = require('stream')

module.exports = (stream) => {
return (
stream instanceof Stream ||
(stream !== null &&
typeof stream === 'object' &&
!!stream.readable &&
typeof stream.pipe === 'function' &&
typeof stream.read === 'function' &&
typeof stream.readable === 'boolean' &&
typeof stream.readableObjectMode === 'boolean' &&
typeof stream.destroy === 'function' &&
typeof stream.destroyed === 'boolean')
)
}
6 changes: 3 additions & 3 deletions lib/response.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ const destroy = require('destroy')
const assert = require('assert')
const extname = require('path').extname
const vary = require('vary')
const isStream = require('./is-stream.js')
const only = require('./only.js')
const util = require('util')
const encodeUrl = require('encodeurl')
const Stream = require('stream')

/**
* Prototype.
Expand Down Expand Up @@ -171,7 +171,7 @@ module.exports = {
}

// stream
if (val instanceof Stream) {
if (isStream(val)) {
onFinish(this.res, destroy.bind(null, val))
if (original !== val) {
val.once('error', err => this.ctx.onerror(err))
Expand Down Expand Up @@ -242,7 +242,7 @@ module.exports = {
}

const { body } = this
if (!body || body instanceof Stream) return undefined
if (!body || isStream(body)) return undefined
if (typeof body === 'string') return Buffer.byteLength(body)
if (Buffer.isBuffer(body)) return body.length
return Buffer.byteLength(JSON.stringify(body))
Expand Down
24 changes: 24 additions & 0 deletions test-helpers/stream.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
'use strict'

const { EventEmitter } = require('events')

class Readable extends EventEmitter {
pipe () {}
read () {}
destroy () {}
get readable () {
return true
}

get readableObjectMode () {
return false
}

get destroyed () {
return false
}
}

module.exports = {
Readable
}

0 comments on commit 1fc1825

Please sign in to comment.