@fastify/compress 9.1.0 → 9.1.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.
@@ -34,6 +34,7 @@ updates:
34
34
  - dependency-name: "eslint"
35
35
  - dependency-name: "neostandard"
36
36
  - dependency-name: "@stylistic/*"
37
+ - dependency-name: "typescript"
37
38
  open-pull-requests-limit: 10
38
39
  groups:
39
40
  # Production dependencies with breaking changes
@@ -27,7 +27,7 @@ jobs:
27
27
  permissions:
28
28
  contents: write
29
29
  pull-requests: write
30
- uses: fastify/workflows/.github/workflows/plugins-ci.yml@v6
30
+ uses: fastify/workflows/.github/workflows/plugins-ci.yml@2073dc8e1f9e172bf42daa3843c9dbd31af1e8cb # v6.0.0
31
31
  with:
32
32
  license-check: true
33
33
  lint: true
@@ -16,4 +16,4 @@ jobs:
16
16
  permissions:
17
17
  issues: write
18
18
  pull-requests: write
19
- uses: fastify/workflows/.github/workflows/lock-threads.yml@v6
19
+ uses: fastify/workflows/.github/workflows/lock-threads.yml@2073dc8e1f9e172bf42daa3843c9dbd31af1e8cb # v6.0.0
package/index.js CHANGED
@@ -18,6 +18,7 @@ const {
18
18
  isWebReadableStream,
19
19
  isFetchResponse,
20
20
  webStreamToNodeReadable,
21
+ unwrapFetchResponse,
21
22
  createPeekTransform
22
23
  } = require('./lib/utils')
23
24
 
@@ -296,7 +297,7 @@ function buildRouteCompress (_fastify, params, routeOptions, decorateOnly) {
296
297
 
297
298
  if (typeof payload.pipe !== 'function') {
298
299
  if (isFetchResponse(payload)) {
299
- payload = payload.body
300
+ payload = unwrapFetchResponse(reply, payload)
300
301
  }
301
302
 
302
303
  if (isWebReadableStream(payload)) {
@@ -425,7 +426,7 @@ function compress (params) {
425
426
 
426
427
  if (typeof payload.pipe !== 'function') {
427
428
  if (isFetchResponse(payload)) {
428
- payload = payload.body
429
+ payload = unwrapFetchResponse(this, payload)
429
430
  }
430
431
 
431
432
  if (isWebReadableStream(payload)) {
package/lib/utils.js CHANGED
@@ -64,6 +64,14 @@ function webStreamToNodeReadable (webStream) {
64
64
  return NodeReadable.fromWeb(webStream)
65
65
  }
66
66
 
67
+ function unwrapFetchResponse (reply, response) {
68
+ reply.code(response.status)
69
+ for (const [name, value] of response.headers) {
70
+ reply.header(name, value)
71
+ }
72
+ return response.body
73
+ }
74
+
67
75
  /**
68
76
  * Provide a async iteratable for Readable.from
69
77
  */
@@ -192,5 +200,6 @@ module.exports = {
192
200
  isWebReadableStream,
193
201
  isFetchResponse,
194
202
  webStreamToNodeReadable,
203
+ unwrapFetchResponse,
195
204
  createPeekTransform
196
205
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fastify/compress",
3
- "version": "9.1.0",
3
+ "version": "9.1.1",
4
4
  "description": "Fastify compression utils",
5
5
  "main": "index.js",
6
6
  "type": "commonjs",
@@ -14,8 +14,8 @@
14
14
  },
15
15
  "devDependencies": {
16
16
  "@types/node": "^26.0.1",
17
- "adm-zip": "^0.5.12",
18
- "c8": "^11.0.0",
17
+ "adm-zip": "^0.6.0",
18
+ "c8": "^12.0.0",
19
19
  "eslint": "^9.17.0",
20
20
  "fastify": "^5.0.0",
21
21
  "jsonstream": "^1.0.3",
@@ -288,6 +288,36 @@ describe('When `global` is not set, it is `true` by default :', async () => {
288
288
  t.assert.equal(payload.toString('utf-8'), body)
289
289
  })
290
290
 
291
+ test('it should preserve a Fetch API Response status and headers', async (t) => {
292
+ t.plan(5)
293
+
294
+ const fastify = Fastify()
295
+ await fastify.register(compressPlugin, { threshold: 0 })
296
+
297
+ const body = 'hello from fetch response'
298
+ fastify.get('/fetch-resp', (_request, reply) => {
299
+ reply.send(new Response(body, {
300
+ status: 201,
301
+ headers: {
302
+ 'content-type': 'text/plain',
303
+ 'cache-control': 'public, max-age=120',
304
+ 'set-cookie': 'a=b; HttpOnly'
305
+ }
306
+ }))
307
+ })
308
+
309
+ const response = await fastify.inject({
310
+ url: '/fetch-resp',
311
+ method: 'GET',
312
+ headers: { 'accept-encoding': 'gzip' }
313
+ })
314
+ t.assert.equal(response.statusCode, 201)
315
+ t.assert.equal(response.headers['content-type'], 'text/plain')
316
+ t.assert.equal(response.headers['cache-control'], 'public, max-age=120')
317
+ t.assert.equal(response.headers['set-cookie'], 'a=b; HttpOnly')
318
+ t.assert.equal(zlib.gunzipSync(response.rawPayload).toString('utf-8'), body)
319
+ })
320
+
291
321
  test('it should compress a Web ReadableStream body', async (t) => {
292
322
  t.plan(1)
293
323
 
@@ -364,6 +364,23 @@ test('reply.compress should handle Fetch Response', async (t) => {
364
364
  t.assert.equal(zlib.gunzipSync(res.rawPayload).toString('utf8'), 'from reply.compress')
365
365
  })
366
366
 
367
+ test('reply.compress should preserve a Fetch Response status and headers', async (t) => {
368
+ t.plan(4)
369
+ const fastify = Fastify()
370
+ await fastify.register(compressPlugin, { global: true, threshold: 0 })
371
+ fastify.get('/', (_req, reply) => {
372
+ reply.compress(new Response('from reply.compress', {
373
+ status: 418,
374
+ headers: { 'content-type': 'text/plain', 'x-custom': 'kept' }
375
+ }))
376
+ })
377
+ const res = await fastify.inject({ url: '/', method: 'GET', headers: { 'accept-encoding': 'gzip' } })
378
+ t.assert.equal(res.statusCode, 418)
379
+ t.assert.equal(res.headers['content-type'], 'text/plain')
380
+ t.assert.equal(res.headers['x-custom'], 'kept')
381
+ t.assert.equal(zlib.gunzipSync(res.rawPayload).toString('utf8'), 'from reply.compress')
382
+ })
383
+
367
384
  test('reply.compress should handle Web ReadableStream', async (t) => {
368
385
  t.plan(1)
369
386
  const fastify = Fastify()