From f6fed1c0d67223426fbb19e28bd4182faecaa1ae Mon Sep 17 00:00:00 2001 From: Thomas Heymann <190132+thomheymann@users.noreply.github.com> Date: Tue, 28 Apr 2020 16:20:53 +0100 Subject: [PATCH] V3 upgrade (#107) * Upgrade to Fastify v3 * Added missing input types * Update node versions * Updated fastify requirements * Remove legacy brotli support * Add github actions and depdendabot * Update index.js Co-authored-by: Thomas Heymann Co-authored-by: Matteo Collina --- .dependabot/config.yml | 5 +++++ .github/workflows/ci.yml | 18 ++++++++++++++++++ .travis.yml | 16 ---------------- README.md | 11 ----------- index.d.ts | 39 ++++++++++++++++++-------------------- index.js | 13 +++++-------- package.json | 27 +++++++++++++------------- test/index.test-d.ts | 26 +++++++++++++++++++++++++ test/test-global.js | 41 ++++++++++++++++++++-------------------- test/types/index.ts | 17 ----------------- test/types/tsconfig.json | 9 --------- 11 files changed, 105 insertions(+), 117 deletions(-) create mode 100644 .dependabot/config.yml create mode 100644 .github/workflows/ci.yml delete mode 100644 .travis.yml create mode 100644 test/index.test-d.ts delete mode 100644 test/types/index.ts delete mode 100644 test/types/tsconfig.json diff --git a/.dependabot/config.yml b/.dependabot/config.yml new file mode 100644 index 0000000..c35198c --- /dev/null +++ b/.dependabot/config.yml @@ -0,0 +1,5 @@ +version: 1 +update_configs: + - package_manager: "javascript" + directory: "/" + update_schedule: "daily" \ No newline at end of file diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..8491347 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,18 @@ +name: Continuous Integration +on: [push, pull_request] + +jobs: + build: + runs-on: ubuntu-latest + strategy: + matrix: + node-version: [10.x, 12.x, 14.x] + name: Node ${{ matrix.node }} + steps: + - uses: actions/checkout@v1 + - name: Setup node + uses: actions/setup-node@v1 + with: + node-version: ${{ matrix.node }} + - run: npm install + - run: npm test diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 75ad2d8..0000000 --- a/.travis.yml +++ /dev/null @@ -1,16 +0,0 @@ -language: node_js -os: - - windows - - linux - -node_js: - - "12" - - "11" - - "10" - - "8" - - "6" - -notifications: - email: - on_success: never - on_failure: always diff --git a/README.md b/README.md index 1302f11..c303ee8 100644 --- a/README.md +++ b/README.md @@ -101,17 +101,6 @@ fastify.register( { customTypes: /x-protobuf$/ } ) ``` -### Brotli -Brotli compression is enabled by default if your Node.js supports it natively (≥ v11.7.0). - -For Node.js versions that don’t natively support Brotli, it's not enabled by default. If you need it, we recommend installing [`iltorb`](https://www.npmjs.com/package/iltorb) and passing it to the `brotli` option: - -```javascript -fastify.register( - require('fastify-compress'), - { brotli: require('iltorb') } -) -``` ### onUnsupportedEncoding 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. diff --git a/index.d.ts b/index.d.ts index f52475c..600ac24 100644 --- a/index.d.ts +++ b/index.d.ts @@ -1,27 +1,24 @@ -import { Plugin, FastifyReply, FastifyRequest } from 'fastify' -import { Server, IncomingMessage, ServerResponse } from 'http' +import { FastifyPlugin, FastifyReply, FastifyRequest, RawServerBase } from 'fastify' import { Stream } from 'stream'; +import { Input, InputObject } from 'into-stream'; -type EncodingToken = 'br' | 'deflate' | 'gzip' | 'identity' - -declare namespace fastifyCompress { - interface FastifyCompressOptions { - global?: boolean - threshold?: number - customTypes?: RegExp - brotli?: NodeModule - zlib?: NodeModule - inflateIfDeflated?: boolean - onUnsupportedEncoding?: (encoding: string, request: FastifyRequest, reply: FastifyReply) => string | Buffer | Stream - encodings?: Array +declare module "fastify" { + interface FastifyReplyInterface { + compress(input: Stream | Input | InputObject): void; } } -declare const fastifyCompress: Plugin< - Server, - IncomingMessage, - ServerResponse, - fastifyCompress.FastifyCompressOptions -> +type EncodingToken = 'br' | 'deflate' | 'gzip' | 'identity' + +export interface FastifyCompressOptions { + global?: boolean + threshold?: number + customTypes?: RegExp + zlib?: NodeModule + inflateIfDeflated?: boolean + onUnsupportedEncoding?: (encoding: string, request: FastifyRequest, reply: FastifyReply) => string | Buffer | Stream + encodings?: Array +} -export = fastifyCompress +declare const fastifyCompress: FastifyPlugin +export default fastifyCompress; diff --git a/index.js b/index.js index a228c9a..3bc10cb 100644 --- a/index.js +++ b/index.js @@ -79,10 +79,7 @@ function processParams (opts) { } const supportedEncodings = ['gzip', 'deflate', 'identity'] - if (opts.brotli) { - params.compressStream.br = opts.brotli.compressStream - supportedEncodings.unshift('br') - } else if (zlib.createBrotliCompress) { + if (zlib.createBrotliCompress) { params.compressStream.br = zlib.createBrotliCompress supportedEncodings.unshift('br') } @@ -127,7 +124,7 @@ function buildRouteCompress (fastify, params, routeOptions, decorateOnly) { function onSend (req, reply, payload, next) { if (payload == null) { - reply.res.log.debug('compress: missing payload') + reply.log.debug('compress: missing payload') return next() } @@ -180,7 +177,7 @@ function buildRouteCompress (fastify, params, routeOptions, decorateOnly) { function compress (params) { return function (payload) { if (payload == null) { - this.res.log.debug('compress: missing payload') + this.log.debug('compress: missing payload') this.send(new Error('Internal server error')) return } @@ -240,7 +237,7 @@ function compress (params) { } function onEnd (err) { - if (err) this.res.log.error(err) + if (err) this.raw.log.error(err) } function getEncodingHeader (encodings, request) { @@ -314,6 +311,6 @@ function unzipStream (inflate, maxRecursion) { } module.exports = fp(compressPlugin, { - fastify: '>=2.11.0', + fastify: '3.x', name: 'fastify-compress' }) diff --git a/package.json b/package.json index 49e968f..9c4b267 100644 --- a/package.json +++ b/package.json @@ -5,14 +5,14 @@ "main": "index.js", "dependencies": { "encoding-negotiator": "^2.0.0", - "fastify-plugin": "^1.0.0", - "into-stream": "4.0.0", + "fastify-plugin": "^2.0.0", + "into-stream": "^5.1.1", "is-deflate": "^1.0.0", - "is-gzip": "^1.0.0", + "is-gzip": "^2.0.0", "is-stream": "^2.0.0", "is-zip": "^1.0.0", "mime-db": "^1.43.0", - "minipass": "^2.9.0", + "minipass": "^3.1.1", "peek-stream": "^1.1.0", "pump": "^3.0.0", "pumpify": "^2.0.1", @@ -23,19 +23,19 @@ "@types/node": "^13.1.0", "@typescript-eslint/parser": "^2.19.2", "eslint-plugin-typescript": "^0.14.0", - "fastify": "^2.11.0", - "iltorb": "2.4.3", + "fastify": "^3.0.0-alpha.1", "jsonstream": "^1.0.3", "pre-commit": "^1.2.2", "standard": "^14.3.1", - "tap": "^12.6.6", + "tap": "^14.10.7", + "tsd": "^0.11.0", "typescript": "^3.7.5" }, "scripts": { "unit": "tap test/*.js", "test": "standard && npm run unit && npm run typescript", "lint:typescript": "standard --fix --parser @typescript-eslint/parser --plugin typescript test/types/*.ts", - "typescript": "tsc --project ./test/types/tsconfig.json", + "typescript": "tsd", "coverage": "npm run unit -- --cov", "coverage-report": "npm run coverage && tap --coverage-report=lcov" }, @@ -56,11 +56,10 @@ "type": "git", "url": "git+https://github.com/fastify/fastify-compress.git" }, - "greenkeeper": { - "ignore": [ - "into-stream", - "iltorb", - "tap" - ] + "engines": { + "node": ">=10.16" + }, + "tsd": { + "directory": "test" } } diff --git a/test/index.test-d.ts b/test/index.test-d.ts new file mode 100644 index 0000000..5318992 --- /dev/null +++ b/test/index.test-d.ts @@ -0,0 +1,26 @@ +import fastify from 'fastify' +import { createReadStream } from 'fs' +import fastifyCompress from '..' + +const zlib = require('zlib') + +const app = fastify() + +app.register(fastifyCompress, { + global: true, + threshold: 10, + zlib: zlib, + inflateIfDeflated: true, + customTypes: /x-protobuf$/, + encodings: ['gzip', 'br', 'identity', 'deflate'] +}) + +const appWithoutGlobal = fastify(); + +appWithoutGlobal.register(fastifyCompress, { global: false }) + +appWithoutGlobal.get('/', (req, reply) => { + reply + .type('text/plain') + .compress(createReadStream('./package.json')) +}) diff --git a/test/test-global.js b/test/test-global.js index c73435e..db04c55 100644 --- a/test/test-global.js +++ b/test/test-global.js @@ -2,7 +2,6 @@ const t = require('tap') const test = t.test -const brotli = require('iltorb') const zlib = require('zlib') const fs = require('fs') const JSONStream = require('jsonstream') @@ -248,7 +247,7 @@ test('should send a gzipped data for * header', t => { test('should send a brotli data', t => { t.plan(3) const fastify = Fastify() - fastify.register(compressPlugin, { brotli, global: false }) + fastify.register(compressPlugin, { global: false }) fastify.get('/', (req, reply) => { reply.type('text/plain').compress(createReadStream('./package.json')) @@ -264,7 +263,7 @@ test('should send a brotli data', t => { t.error(err) t.strictEqual(res.headers['content-encoding'], 'br') const file = readFileSync('./package.json', 'utf8') - const payload = brotli.decompressSync(res.rawPayload) + const payload = zlib.brotliDecompressSync(res.rawPayload) t.strictEqual(payload.toString('utf-8'), file) }) }) @@ -272,7 +271,7 @@ test('should send a brotli data', t => { test('should follow the encoding order', t => { t.plan(3) const fastify = Fastify() - fastify.register(compressPlugin, { brotli, global: false }) + fastify.register(compressPlugin, { global: false }) fastify.get('/', (req, reply) => { reply.type('text/plain').compress(createReadStream('./package.json')) @@ -288,7 +287,7 @@ test('should follow the encoding order', t => { t.error(err) t.strictEqual(res.headers['content-encoding'], 'br') const file = readFileSync('./package.json', 'utf8') - const payload = brotli.decompressSync(res.rawPayload) + const payload = zlib.brotliDecompressSync(res.rawPayload) t.strictEqual(payload.toString('utf-8'), file) }) }) @@ -685,7 +684,7 @@ test('Should compress buffer (deflate)', t => { test('Should compress buffer (brotli)', t => { t.plan(2) const fastify = Fastify() - fastify.register(compressPlugin, { global: false, brotli, threshold: 0 }) + fastify.register(compressPlugin, { global: false, threshold: 0 }) const buf = Buffer.from('hello world') fastify.get('/', (req, reply) => { @@ -700,7 +699,7 @@ test('Should compress buffer (brotli)', t => { } }, (err, res) => { t.error(err) - const payload = brotli.decompressSync(res.rawPayload) + const payload = zlib.brotliDecompressSync(res.rawPayload) t.strictEqual(payload.toString('utf-8'), buf.toString()) }) }) @@ -724,7 +723,7 @@ if (zlib.createBrotliCompress) { } }, (err, res) => { t.error(err) - const payload = brotli.decompressSync(res.rawPayload) + const payload = zlib.brotliDecompressSync(res.rawPayload) t.strictEqual(payload.toString('utf-8'), buf.toString()) }) }) @@ -802,7 +801,7 @@ test('Should compress buffer (deflate) - global', t => { test('Should compress buffer (brotli) - global', t => { t.plan(2) const fastify = Fastify() - fastify.register(compressPlugin, { brotli, threshold: 0 }) + fastify.register(compressPlugin, { threshold: 0 }) const buf = Buffer.from('hello world') fastify.get('/', (req, reply) => { @@ -817,7 +816,7 @@ test('Should compress buffer (brotli) - global', t => { } }, (err, res) => { t.error(err) - const payload = brotli.decompressSync(res.rawPayload) + const payload = zlib.brotliDecompressSync(res.rawPayload) t.strictEqual(payload.toString('utf-8'), buf.toString()) }) }) @@ -841,7 +840,7 @@ if (zlib.createBrotliCompress) { } }, (err, res) => { t.error(err) - const payload = brotli.decompressSync(res.rawPayload) + const payload = zlib.brotliDecompressSync(res.rawPayload) t.strictEqual(payload.toString('utf-8'), buf.toString()) }) }) @@ -896,7 +895,7 @@ test('Should compress json data (deflate)', t => { test('Should compress json data (brotli)', t => { t.plan(2) const fastify = Fastify() - fastify.register(compressPlugin, { global: false, brotli, threshold: 0 }) + fastify.register(compressPlugin, { global: false, threshold: 0 }) const json = { hello: 'world' } fastify.get('/', (req, reply) => { @@ -911,7 +910,7 @@ test('Should compress json data (brotli)', t => { } }, (err, res) => { t.error(err) - const payload = brotli.decompressSync(res.rawPayload) + const payload = zlib.brotliDecompressSync(res.rawPayload) t.strictEqual(payload.toString('utf-8'), JSON.stringify(json)) }) }) @@ -935,7 +934,7 @@ if (zlib.createBrotliCompress) { } }, (err, res) => { t.error(err) - const payload = brotli.decompressSync(res.rawPayload) + const payload = zlib.brotliDecompressSync(res.rawPayload) t.strictEqual(payload.toString('utf-8'), JSON.stringify(json)) }) }) @@ -988,7 +987,7 @@ test('Should compress string data (deflate)', t => { test('Should compress string data (brotli)', t => { t.plan(2) const fastify = Fastify() - fastify.register(compressPlugin, { brotli, threshold: 0 }) + fastify.register(compressPlugin, { threshold: 0 }) fastify.get('/', (req, reply) => { reply.type('text/plain').send('hello') @@ -1002,7 +1001,7 @@ test('Should compress string data (brotli)', t => { } }, (err, res) => { t.error(err) - const payload = brotli.decompressSync(res.rawPayload) + const payload = zlib.brotliDecompressSync(res.rawPayload) t.strictEqual(payload.toString('utf-8'), 'hello') }) }) @@ -1025,7 +1024,7 @@ if (zlib.createBrotliCompress) { } }, (err, res) => { t.error(err) - const payload = brotli.decompressSync(res.rawPayload) + const payload = zlib.brotliDecompressSync(res.rawPayload) t.strictEqual(payload.toString('utf-8'), 'hello') }) }) @@ -1245,7 +1244,7 @@ test('Should compress json data (deflate) - global', t => { test('Should compress json data (brotli) - global', t => { t.plan(2) const fastify = Fastify() - fastify.register(compressPlugin, { brotli, threshold: 0 }) + fastify.register(compressPlugin, { threshold: 0 }) const json = { hello: 'world' } fastify.get('/', (req, reply) => { @@ -1260,7 +1259,7 @@ test('Should compress json data (brotli) - global', t => { } }, (err, res) => { t.error(err) - const payload = brotli.decompressSync(res.rawPayload) + const payload = zlib.brotliDecompressSync(res.rawPayload) t.strictEqual(payload.toString('utf-8'), JSON.stringify(json)) }) }) @@ -1284,7 +1283,7 @@ if (zlib.createBrotliCompress) { } }, (err, res) => { t.error(err) - const payload = brotli.decompressSync(res.rawPayload) + const payload = zlib.brotliDecompressSync(res.rawPayload) t.strictEqual(payload.toString('utf-8'), JSON.stringify(json)) }) }) @@ -1615,7 +1614,7 @@ test('Should error if no entries in `encodings` are supported', t => { test('Should not compress mime types with undefined compressible values', t => { t.plan(4) const fastify = Fastify() - fastify.register(compressPlugin, { brotli, threshold: 0 }) + fastify.register(compressPlugin, { threshold: 0 }) fastify.get('/', (req, reply) => { reply.type('image/webp').send('hello') diff --git a/test/types/index.ts b/test/types/index.ts deleted file mode 100644 index ae7cf5f..0000000 --- a/test/types/index.ts +++ /dev/null @@ -1,17 +0,0 @@ -import * as fastify from 'fastify' -import * as fastifyCompress from '../..' - -const zlib = require('zlib') -const iltorb = require('iltorb') - -const app = fastify() - -app.register(fastifyCompress, { - global: true, - threshold: 10, - brotli: iltorb, - zlib: zlib, - inflateIfDeflated: true, - customTypes: /x-protobuf$/, - encodings: ['gzip', 'br', 'identity', 'deflate'] -}) diff --git a/test/types/tsconfig.json b/test/types/tsconfig.json deleted file mode 100644 index b170f36..0000000 --- a/test/types/tsconfig.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "compilerOptions": { - "target": "es6", - "module": "commonjs", - "noEmit": true, - "strict": true - }, - "files": ["./index.ts"] -}