@fastify/compress 5.0.0 → 6.0.0

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.
@@ -14,11 +14,9 @@ jobs:
14
14
  strategy:
15
15
  matrix:
16
16
  node-version:
17
- - 10
18
- - 12
19
17
  - 14
20
18
  - 16
21
- - 17
19
+ - 18
22
20
  os:
23
21
  - macos-latest
24
22
  - ubuntu-latest
package/README.md CHANGED
@@ -1,18 +1,18 @@
1
- # fastify-compress
1
+ # @fastify/compress
2
2
 
3
3
  ![CI](https://github.com/fastify/fastify-compress/workflows/CI/badge.svg)
4
- [![NPM version](https://img.shields.io/npm/v/fastify-compress.svg?style=flat)](https://www.npmjs.com/package/fastify-compress)
4
+ [![NPM version](https://img.shields.io/npm/v/@fastify/compress.svg?style=flat)](https://www.npmjs.com/package/@fastify/compress)
5
5
  [![Known Vulnerabilities](https://snyk.io/test/github/fastify/fastify-compress/badge.svg)](https://snyk.io/test/github/fastify/fastify-compress)
6
6
  [![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat)](https://standardjs.com/)
7
7
 
8
8
  Adds compression utils to [the Fastify `reply` object](https://www.fastify.io/docs/latest/Reference/Reply/#reply) and a hook to decompress requests payloads.
9
9
  Supports `gzip`, `deflate`, and `brotli`.
10
10
 
11
- > **Important note:** since `fastify-compress` version 4.x payloads that are compressed using the `zip` algorithm are not automatically uncompressed anymore. `fastify-compress` main feature is to provide response compression mechanism to your server, however the `zip` format does not appear in the [IANA maintained Table of Content Encodings](https://www.iana.org/assignments/http-parameters/http-parameters.xml#content-coding) and thus such behavior was out of the scope of this plugin.
11
+ > **Important note:** since `@fastify/compress` version 4.x payloads that are compressed using the `zip` algorithm are not automatically uncompressed anymore. `@fastify/compress` main feature is to provide response compression mechanism to your server, however the `zip` format does not appear in the [IANA maintained Table of Content Encodings](https://www.iana.org/assignments/http-parameters/http-parameters.xml#content-coding) and thus such behavior was out of the scope of this plugin.
12
12
 
13
13
  ## Install
14
14
  ```
15
- npm i fastify-compress
15
+ npm i @fastify/compress
16
16
  ```
17
17
 
18
18
  ## Usage - Compress replies
@@ -24,7 +24,7 @@ Currently, the following encoding tokens are supported, using the first acceptab
24
24
  1. `br`
25
25
  2. `gzip`
26
26
  3. `deflate`
27
- 4. `*` (no preference — `fastify-compress` will use `gzip`)
27
+ 4. `*` (no preference — `@fastify/compress` will use `gzip`)
28
28
  5. `identity` (no compression)
29
29
 
30
30
  If an unsupported encoding is received or if the `'accept-encoding'` header is missing, it will not compress the payload. If an unsupported encoding is received and you would like to return an error, provide an `onUnsupportedEncoding` option.
@@ -34,20 +34,20 @@ The plugin automatically decides if a payload should be compressed based on its
34
34
  ### Global hook
35
35
  The global compression hook is enabled by default. To disable it, pass the option `{ global: false }`:
36
36
  ```javascript
37
- fastify.register(
38
- require('fastify-compress'),
37
+ await fastify.register(
38
+ import('@fastify/compress'),
39
39
  { global: false }
40
40
  )
41
41
  ```
42
42
  Remember that thanks to the Fastify encapsulation model, you can set a global compression, but run it only in a subset of routes if you wrap them inside a plugin.
43
43
 
44
- Important note! If you are using `fastify-compress` plugin together with `fastify-static` plugin, you must register the `fastify-compress` (with *global hook*) **before** registering `fastify-static`.
44
+ Important note! If you are using `@fastify/compress` plugin together with `@fastify/static` plugin, you must register the `@fastify/compress` (with *global hook*) **before** registering `@fastify/static`.
45
45
 
46
46
  ### Per Route options
47
47
  You can specify different options for compression per route by passing in the `compress` options on the route's configuration.
48
48
  ```javascript
49
- fastify.register(
50
- require('fastify-compress'),
49
+ await fastify.register(
50
+ import('@fastify/compress'),
51
51
  { global: false }
52
52
  )
53
53
 
@@ -74,21 +74,19 @@ Note that the compress method is configured with either the per route parameters
74
74
  the plugin was defined as global.
75
75
 
76
76
  ```javascript
77
- const fs = require('fs')
78
- const fastify = require('fastify')()
77
+ import fs from 'fs'
78
+ import fastify from 'fastify'
79
79
 
80
- fastify.register(require('fastify-compress'), { global: false })
80
+ const app = fastify()
81
+ await app.register(import('@fastify/compress'), { global: false })
81
82
 
82
- fastify.get('/', (req, reply) => {
83
+ app.get('/', (req, reply) => {
83
84
  reply
84
85
  .type('text/plain')
85
86
  .compress(fs.createReadStream('./package.json'))
86
87
  })
87
88
 
88
- fastify.listen(3000, function (err) {
89
- if (err) throw err
90
- console.log(`server listening on ${fastify.server.address().port}`)
91
- })
89
+ await app.listen(3000)
92
90
  ```
93
91
 
94
92
  ## Compress Options
@@ -96,16 +94,16 @@ fastify.listen(3000, function (err) {
96
94
  ### threshold
97
95
  The minimum byte size for a response to be compressed. Defaults to `1024`.
98
96
  ```javascript
99
- fastify.register(
100
- require('fastify-compress'),
97
+ await fastify.register(
98
+ import('@fastify/compress'),
101
99
  { threshold: 2048 }
102
100
  )
103
101
  ```
104
102
  ### customTypes
105
103
  [mime-db](https://github.com/jshttp/mime-db) is used to determine if a `content-type` should be compressed. You can compress additional content types via regular expression.
106
104
  ```javascript
107
- fastify.register(
108
- require('fastify-compress'),
105
+ await fastify.register(
106
+ import('@fastify/compress'),
109
107
  { customTypes: /x-protobuf$/ }
110
108
  )
111
109
  ```
@@ -113,8 +111,8 @@ fastify.register(
113
111
  ### onUnsupportedEncoding
114
112
  When the encoding is not supported, a custom error response can be sent in place of the uncompressed payload by setting the `onUnsupportedEncoding(encoding, request, reply)` option to be a function that can modify the reply and return a `string | Buffer | Stream | Error` payload.
115
113
  ```javascript
116
- fastify.register(
117
- require('fastify-compress'),
114
+ await fastify.register(
115
+ import('@fastify/compress'),
118
116
  {
119
117
  onUnsupportedEncoding: (encoding, request, reply) => {
120
118
  reply.code(406)
@@ -130,8 +128,8 @@ You can selectively disable response compression by using the `x-no-compression`
130
128
  ### Inflate pre-compressed bodies for clients that do not support compression
131
129
  Optional feature to inflate pre-compressed data if the client does not include one of the supported compression types in its `accept-encoding` header.
132
130
  ```javascript
133
- fastify.register(
134
- require('fastify-compress'),
131
+ await fastify.register(
132
+ import('@fastify/compress'),
135
133
  { inflateIfDeflated: true }
136
134
  )
137
135
 
@@ -143,11 +141,11 @@ fastify.get('/file', (req, reply) =>
143
141
 
144
142
  ### Customize encoding priority
145
143
 
146
- By default, `fastify-compress` prioritizes compression as described [at the beginning of §Usage - Compress replies](#usage). You can change that by passing an array of compression tokens to the `encodings` option:
144
+ By default, `@fastify/compress` prioritizes compression as described [at the beginning of §Usage - Compress replies](#usage). You can change that by passing an array of compression tokens to the `encodings` option:
147
145
 
148
146
  ```javascript
149
- fastify.register(
150
- require('fastify-compress'),
147
+ await fastify.register(
148
+ import('@fastify/compress'),
151
149
  // Only support gzip and deflate, and prefer deflate to gzip
152
150
  { encodings: ['deflate', 'gzip'] }
153
151
  )
@@ -172,11 +170,11 @@ You can tune compression by setting the `brotliOptions` and `zlibOptions` proper
172
170
  ```
173
171
 
174
172
  ### Manage `Content-Length` header removal with removeContentLengthHeader
175
- By default, `fastify-compress` removes the reply `Content-Length` header. You can change that by setting the `removeContentLengthHeader` to `false` either on a global scope or on a route specific scope.
173
+ By default, `@fastify/compress` removes the reply `Content-Length` header. You can change that by setting the `removeContentLengthHeader` to `false` either on a global scope or on a route specific scope.
176
174
 
177
175
  ```javascript
178
176
  // Global plugin scope
179
- server.register(fastifyCompress, { global: true, removeContentLengthHeader: false });
177
+ await server.register(fastifyCompress, { global: true, removeContentLengthHeader: false });
180
178
 
181
179
  // Route specific scope
182
180
  fastify.get('/file', {
@@ -204,8 +202,8 @@ If the request header is missing, the plugin will not do anything and yield to t
204
202
 
205
203
  The global request decompression hook is enabled by default. To disable it, pass the option `{ global: false }`:
206
204
  ```javascript
207
- fastify.register(
208
- require('fastify-compress'),
205
+ await fastify.register(
206
+ import('@fastify/compress'),
209
207
  { global: false }
210
208
  )
211
209
  ```
@@ -216,8 +214,8 @@ Remember that thanks to the Fastify encapsulation model, you can set a global de
216
214
 
217
215
  You can specify different options for decompression per route by passing in the `decompress` options on the route's configuration.
218
216
  ```javascript
219
- fastify.register(
220
- require('fastify-compress'),
217
+ await fastify.register(
218
+ import('@fastify/compress'),
221
219
  { global: false }
222
220
  )
223
221
 
@@ -238,11 +236,11 @@ fastify.get('/custom-route', {
238
236
 
239
237
  ### requestEncodings
240
238
 
241
- By default, `fastify-compress` accepts all encodings specified [at the beginning of §Usage - Decompress request payloads](#usage). You can change that by passing an array of compression tokens to the `requestEncodings` option:
239
+ By default, `@fastify/compress` accepts all encodings specified [at the beginning of §Usage - Decompress request payloads](#usage). You can change that by passing an array of compression tokens to the `requestEncodings` option:
242
240
 
243
241
  ```javascript
244
- fastify.register(
245
- require('fastify-compress'),
242
+ await fastify.register(
243
+ import('@fastify/compress'),
246
244
  // Only support gzip
247
245
  { requestEncodings: ['gzip'] }
248
246
  )
@@ -250,19 +248,19 @@ fastify.register(
250
248
 
251
249
  ### forceRequestEncoding
252
250
 
253
- By default, `fastify-compress` chooses the decompressing algorithm by looking at the `content-encoding` header, if present.
251
+ By default, `@fastify/compress` chooses the decompressing algorithm by looking at the `content-encoding` header, if present.
254
252
 
255
253
  You can force one algorithm and ignore the header at all by providing the `forceRequestEncoding` option.
256
254
 
257
- Note that if the request payload is not compressed, `fastify-compress` will try to decompress, resulting in an error.
255
+ Note that if the request payload is not compressed, `@fastify/compress` will try to decompress, resulting in an error.
258
256
 
259
257
  ### onUnsupportedRequestEncoding
260
258
 
261
259
  When the request payload encoding is not supported, you can customize the response error by setting the `onUnsupportedEncoding(request, encoding)` option to be a function that returns an error.
262
260
 
263
261
  ```javascript
264
- fastify.register(
265
- require('fastify-compress'),
262
+ await fastify.register(
263
+ import('@fastify/compress'),
266
264
  {
267
265
   onUnsupportedRequestEncoding: (request, encoding) => {
268
266
  return {
@@ -281,8 +279,8 @@ fastify.register(
281
279
  When the request payload cannot be decompressed using the detected algorithm, you can customize the response error setting the `onInvalidRequestPayload(request, encoding)` option to be a function that returns an error.
282
280
 
283
281
  ```javascript
284
- fastify.register(
285
- require('fastify-compress'),
282
+ await fastify.register(
283
+ import('@fastify/compress'),
286
284
  {
287
285
  onInvalidRequestPayload: (request, encoding, error) => {
288
286
  return {
package/index.js CHANGED
@@ -143,8 +143,8 @@ function processCompressParams (opts) {
143
143
 
144
144
  params.encodings = Array.isArray(opts.encodings)
145
145
  ? supportedEncodings
146
- .filter(encoding => opts.encodings.includes(encoding))
147
- .sort((a, b) => opts.encodings.indexOf(a) - supportedEncodings.indexOf(b))
146
+ .filter(encoding => opts.encodings.includes(encoding))
147
+ .sort((a, b) => opts.encodings.indexOf(a) - supportedEncodings.indexOf(b))
148
148
  : supportedEncodings
149
149
 
150
150
  return params
@@ -175,8 +175,8 @@ function processDecompressParams (opts) {
175
175
 
176
176
  params.encodings = Array.isArray(opts.requestEncodings)
177
177
  ? supportedEncodings
178
- .filter(encoding => opts.requestEncodings.includes(encoding))
179
- .sort((a, b) => opts.requestEncodings.indexOf(a) - supportedEncodings.indexOf(b))
178
+ .filter(encoding => opts.requestEncodings.includes(encoding))
179
+ .sort((a, b) => opts.requestEncodings.indexOf(a) - supportedEncodings.indexOf(b))
180
180
  : supportedEncodings
181
181
 
182
182
  if (opts.forceRequestEncoding) {
@@ -268,8 +268,8 @@ function buildRouteCompress (fastify, params, routeOptions, decorateOnly) {
268
268
 
269
269
  params.removeContentLengthHeader
270
270
  ? reply
271
- .header('Content-Encoding', encoding)
272
- .removeHeader('content-length')
271
+ .header('Content-Encoding', encoding)
272
+ .removeHeader('content-length')
273
273
  : reply.header('Content-Encoding', encoding)
274
274
 
275
275
  stream = zipStream(params.compressStream, encoding)
@@ -393,8 +393,8 @@ function compress (params) {
393
393
 
394
394
  params.removeContentLengthHeader
395
395
  ? this
396
- .header('Content-Encoding', encoding)
397
- .removeHeader('content-length')
396
+ .header('Content-Encoding', encoding)
397
+ .removeHeader('content-length')
398
398
  : this.header('Content-Encoding', encoding)
399
399
 
400
400
  stream = zipStream(params.compressStream, encoding)
@@ -551,6 +551,6 @@ function createError (code, message, statusCode) {
551
551
  }
552
552
 
553
553
  module.exports = fp(compressPlugin, {
554
- fastify: '3.x',
555
- name: 'fastify-compress'
554
+ fastify: '4.x',
555
+ name: '@fastify/compress'
556
556
  })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fastify/compress",
3
- "version": "5.0.0",
3
+ "version": "6.0.0",
4
4
  "description": "Fastify compression utils",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -23,10 +23,10 @@
23
23
  "@typescript-eslint/eslint-plugin": "^5.9.0",
24
24
  "@typescript-eslint/parser": "^5.9.0",
25
25
  "adm-zip": "^0.5.9",
26
- "fastify": "^3.25.3",
26
+ "fastify": "^4.0.0-rc.2",
27
27
  "jsonstream": "^1.0.3",
28
28
  "pre-commit": "^1.2.2",
29
- "standard": "^16.0.4",
29
+ "standard": "^17.0.0",
30
30
  "tap": "^16.0.0",
31
31
  "tsd": "^0.20.0",
32
32
  "typescript": "^4.5.4"
@@ -8,6 +8,7 @@ const AdmZip = require('adm-zip')
8
8
  const JSONStream = require('jsonstream')
9
9
  const Fastify = require('fastify')
10
10
  const compressPlugin = require('../index')
11
+ const { once } = require('events')
11
12
 
12
13
  test('When `global` is not set, it is `true` by default :', async (t) => {
13
14
  t.test('it should compress Buffer data using brotli when `Accept-Encoding` request header is `br`', async (t) => {
@@ -343,7 +344,7 @@ test('It should send compressed Buffer data when `global` is `true` :', async (t
343
344
  t.plan(1)
344
345
 
345
346
  const fastify = Fastify()
346
- fastify.register(compressPlugin, { global: true, threshold: 0 })
347
+ await fastify.register(compressPlugin, { global: true, threshold: 0 })
347
348
 
348
349
  const buf = Buffer.from('hello world')
349
350
  fastify.get('/', (request, reply) => {
@@ -1639,14 +1640,16 @@ test('It should return a serialized payload when `inflateIfDeflated` is `true` a
1639
1640
  t.equal(two.payload, compressedBufferPayload.toString())
1640
1641
  })
1641
1642
 
1642
- test('It should close the stream', (t) => {
1643
- t.plan(4)
1643
+ test('It should close the stream', async (t) => {
1644
+ t.plan(3)
1644
1645
 
1645
1646
  const fastify = Fastify()
1646
- fastify.register(compressPlugin, { global: true })
1647
+ await fastify.register(compressPlugin, { global: true })
1648
+
1649
+ const stream = createReadStream('./package.json')
1650
+ const closed = once(stream, 'close')
1647
1651
 
1648
1652
  fastify.get('/', (request, reply) => {
1649
- const stream = createReadStream('./package.json')
1650
1653
  stream.on('close', () => t.ok('stream closed'))
1651
1654
 
1652
1655
  reply
@@ -1654,16 +1657,15 @@ test('It should close the stream', (t) => {
1654
1657
  .compress(stream)
1655
1658
  })
1656
1659
 
1657
- fastify.inject({
1660
+ const response = await fastify.inject({
1658
1661
  url: '/',
1659
1662
  method: 'GET'
1660
- }, (err, response) => {
1661
- t.error(err)
1662
-
1663
- const file = readFileSync('./package.json', 'utf8')
1664
- t.equal(response.statusCode, 200)
1665
- t.equal(file, response.payload)
1666
1663
  })
1664
+
1665
+ const file = readFileSync('./package.json', 'utf8')
1666
+ t.equal(response.statusCode, 200)
1667
+ t.equal(file, response.payload)
1668
+ await closed
1667
1669
  })
1668
1670
 
1669
1671
  test('It should log an existing error with stream onEnd handler', async (t) => {
@@ -225,27 +225,20 @@ test('When using routes `compress` settings :', async (t) => {
225
225
  })
226
226
 
227
227
  t.test('it should throw an error on invalid route `compress` settings', async (t) => {
228
- t.plan(2)
228
+ t.plan(1)
229
229
 
230
230
  const fastify = Fastify()
231
231
  await fastify.register(compressPlugin, { global: false })
232
232
 
233
- fastify.get('/', {
234
- compress: 'bad config'
235
- }, (request, reply) => {
236
- reply.send('')
237
- })
238
-
239
- await fastify.inject({
240
- url: '/',
241
- method: 'GET',
242
- headers: {
243
- 'accept-encoding': 'gzip'
244
- }
245
- }).catch((err) => {
246
- t.type(err, Error)
233
+ try {
234
+ fastify.get('/', {
235
+ compress: 'bad config'
236
+ }, (request, reply) => {
237
+ reply.send('')
238
+ })
239
+ } catch (err) {
247
240
  t.equal(err.message, 'Unknown value for route compress configuration')
248
- })
241
+ }
249
242
  })
250
243
  })
251
244
 
@@ -385,32 +378,25 @@ test('When using the old routes `{ config: compress }` option :', async (t) => {
385
378
  })
386
379
 
387
380
  t.test('it should use the old routes `{ config: compress }` options over routes `compress` options', async (t) => {
388
- t.plan(2)
381
+ t.plan(1)
389
382
 
390
383
  const fastify = Fastify()
391
384
  await fastify.register(compressPlugin, { global: false })
392
385
 
393
- fastify.get('/', {
394
- compress: {
395
- zlib: { createGzip: () => zlib.createGzip() }
396
- },
397
- config: {
398
- compress: 'bad config'
399
- }
400
- }, (request, reply) => {
401
- reply.send('')
402
- })
403
-
404
- await fastify.inject({
405
- url: '/',
406
- method: 'GET',
407
- headers: {
408
- 'accept-encoding': 'gzip'
409
- }
410
- }).catch((err) => {
411
- t.type(err, Error)
386
+ try {
387
+ fastify.get('/', {
388
+ compress: {
389
+ zlib: { createGzip: () => zlib.createGzip() }
390
+ },
391
+ config: {
392
+ compress: 'bad config'
393
+ }
394
+ }, (request, reply) => {
395
+ reply.send('')
396
+ })
397
+ } catch (err) {
412
398
  t.equal(err.message, 'Unknown value for route compress configuration')
413
- })
399
+ }
414
400
  })
415
401
  })
416
402
 
@@ -189,26 +189,18 @@ test('When using routes `decompress` settings :', async (t) => {
189
189
  })
190
190
 
191
191
  t.test('it should throw an error on invalid route `decompress` settings', async (t) => {
192
- t.plan(2)
192
+ t.plan(1)
193
193
 
194
194
  const fastify = Fastify()
195
195
  await fastify.register(compressPlugin, { global: false })
196
196
 
197
- fastify.post('/', { decompress: 'bad config' }, (request, reply) => {
198
- reply.send(request.body.name)
199
- })
200
-
201
- await fastify.inject({
202
- url: '/',
203
- method: 'POST',
204
- headers: {
205
- 'content-encoding': 'gzip'
206
- },
207
- payload: ''
208
- }).catch((err) => {
209
- t.type(err, Error)
197
+ try {
198
+ fastify.post('/', { decompress: 'bad config' }, (request, reply) => {
199
+ reply.send(request.body.name)
200
+ })
201
+ } catch (err) {
210
202
  t.equal(err.message, 'Unknown value for route decompress configuration')
211
- })
203
+ }
212
204
  })
213
205
  })
214
206
 
@@ -274,32 +266,24 @@ test('When using the old routes `{ config: decompress }` option :', async (t) =>
274
266
  })
275
267
 
276
268
  t.test('it should use the old routes `{ config: decompress }` options over routes `decompress` options', async (t) => {
277
- t.plan(2)
269
+ t.plan(1)
278
270
 
279
271
  const fastify = Fastify()
280
272
  await fastify.register(compressPlugin, { global: false })
281
273
 
282
- fastify.post('/', {
283
- decompress: {
284
- zlib: { createGunzip: () => zlib.createGunzip() }
285
- },
286
- config: {
287
- decompress: 'bad config'
288
- }
289
- }, (request, reply) => {
290
- reply.send(request.body.name)
291
- })
292
-
293
- await fastify.inject({
294
- url: '/',
295
- method: 'POST',
296
- headers: {
297
- 'content-encoding': 'gzip'
298
- },
299
- payload: ''
300
- }).catch((err) => {
301
- t.type(err, Error)
274
+ try {
275
+ fastify.post('/', {
276
+ decompress: {
277
+ zlib: { createGunzip: () => zlib.createGunzip() }
278
+ },
279
+ config: {
280
+ decompress: 'bad config'
281
+ }
282
+ }, (request, reply) => {
283
+ reply.send(request.body.name)
284
+ })
285
+ } catch (err) {
302
286
  t.equal(err.message, 'Unknown value for route decompress configuration')
303
- })
287
+ }
304
288
  })
305
289
  })