Skip to content

Commit ab9d567

Browse files
committed
feat: Updated to fastify 4.
1 parent 2ad02bd commit ab9d567

File tree

9 files changed

+70
-66
lines changed

9 files changed

+70
-66
lines changed

.github/workflows/ci.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@ jobs:
66
runs-on: ubuntu-latest
77
steps:
88
- name: Checkout
9-
uses: actions/checkout@v2
9+
uses: actions/checkout@v3
1010
- name: Use Node.js LTS
11-
uses: actions/setup-node@v2
11+
uses: actions/setup-node@v3
1212
with:
1313
node-version: lts/*
1414
- name: Restore cached dependencies
15-
uses: actions/cache@v2
15+
uses: actions/cache@v3
1616
with:
1717
path: ~/.pnpm-store
1818
key: node-modules-${{ hashFiles('package.json') }}
@@ -24,7 +24,7 @@ jobs:
2424
- name: Run Tests
2525
run: pnpm run ci
2626
- name: Upload coverage to Codecov
27-
uses: codecov/codecov-action@v1
27+
uses: codecov/codecov-action@v3
2828
with:
2929
file: ./coverage/coverage-final.json
3030
token: ${{ secrets.CODECOV_TOKEN }}

README.md

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,9 @@ import fastifyHttpErrorsEnhanced from 'fastify-http-errors-enhanced'
5151
import { NotFoundError } from 'http-errors-enhanced'
5252

5353
const server = fastify()
54-
server.register(fastifyHttpErrorsEnhanced)
54+
55+
// Note that await is mandatory here otherwise response validation will be lost
56+
await server.register(fastifyHttpErrorsEnhanced)
5557

5658
server.get('/invalid', {
5759
handler: async function (request, reply) {
@@ -62,7 +64,7 @@ server.get('/invalid', {
6264
}
6365
})
6466

65-
server.listen(3000, err => {
67+
server.listen({ port: 3000 }, err => {
6668
if (err) {
6769
throw err
6870
}
@@ -109,7 +111,7 @@ import fastifyHttpErrorsEnhanced from 'fastify-http-errors-enhanced'
109111
import { NotFoundError } from 'http-errors-enhanced'
110112
import createError from 'http-errors'
111113

112-
server.register(fastifyHttpErrorsEnhanced, { hideUnhandledErrors: false })
114+
await server.register(fastifyHttpErrorsEnhanced, { hideUnhandledErrors: false })
113115

114116
server.get('/invalid', {
115117
handler(request, reply) {
@@ -119,7 +121,7 @@ server.get('/invalid', {
119121
}
120122
})
121123

122-
server.listen(3000, err => {
124+
server.listen({ port: 3000 }, err => {
123125
if (err) {
124126
throw err
125127
}

package.json

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -42,23 +42,23 @@
4242
},
4343
"dependencies": {
4444
"ajv": "^8.11.0",
45-
"fastify-plugin": "^3.0.1",
46-
"http-errors-enhanced": "^1.0.6"
45+
"fastify-plugin": "^4.2.1",
46+
"http-errors-enhanced": "^1.0.7"
4747
},
4848
"devDependencies": {
49-
"@cowtech/eslint-config": "^8.7.0",
49+
"@cowtech/eslint-config": "^8.7.1",
5050
"@swc/cli": "^0.1.57",
51-
"@swc/core": "^1.2.218",
52-
"@types/node": "^18.0.6",
51+
"@swc/core": "^1.2.245",
52+
"@types/node": "^18.7.14",
5353
"@types/tap": "^15.0.7",
5454
"ajv-formats": "^2.1.1",
55-
"c8": "^7.11.3",
55+
"c8": "^7.12.0",
5656
"chokidar": "^3.5.3",
57-
"fastify": "^3.27.2",
57+
"fastify": "^4.5.3",
5858
"prettier": "^2.7.1",
59-
"tap": "^16.0.0",
59+
"tap": "^16.3.0",
6060
"ts-node": "^10.9.1",
61-
"typescript": "^4.7.4"
61+
"typescript": "^4.8.2"
6262
},
6363
"engines": {
6464
"node": ">=14.15.0"

src/handlers.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ export function handleErrors(error: FastifyError | Error, request: FastifyReques
4343
// It is a generic error, handle it
4444
const code = (error as NodeError).code
4545

46-
if (!('statusCode' in error)) {
46+
if (!('statusCode' in error) || 'validation' in error) {
4747
if ('validation' in error && request[kHttpErrorsEnhancedConfiguration]?.convertValidationErrors) {
4848
// If it is a validation error, convert errors to human friendly format
4949
error = handleValidationError(error, request)

src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ export const plugin = fastifyPlugin(
4646

4747
done()
4848
},
49-
{ name: 'fastify-http-errors-enhanced' }
49+
{ name: 'fastify-http-errors-enhanced', fastify: '4.x' }
5050
)
5151

5252
export default plugin

src/validation.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ export function convertValidationErrors(
110110
// Normalize the key
111111
let key = e.dataPath ?? e.instancePath /* c8 ignore next */ ?? ''
112112

113-
if (key.startsWith('.')) {
113+
if (/^[./]/.test(key)) {
114114
key = key.slice(1)
115115
}
116116

@@ -181,7 +181,7 @@ export function convertValidationErrors(
181181

182182
// No custom message was found, default to input one replacing the starting verb and adding some path info
183183
if (!message.length) {
184-
message = `${e.message.replace(/^should/, 'must')} (${e.keyword})`
184+
message = `${e.message?.replace(/^should/, 'must')} (${e.keyword})`
185185
}
186186

187187
// Remove useless quotes

test/hooks.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { INTERNAL_SERVER_ERROR } from 'http-errors-enhanced'
55
import t from 'tap'
66
import { plugin as fastifyHttpErrorsEnhanced } from '../src/index.js'
77

8-
function buildServer(options: FastifyPluginOptions = {}): FastifyInstance {
8+
async function buildServer(options: FastifyPluginOptions = {}): Promise<FastifyInstance> {
99
const server = fastify({
1010
ajv: {
1111
customOptions: {
@@ -17,7 +17,7 @@ function buildServer(options: FastifyPluginOptions = {}): FastifyInstance {
1717
}
1818
})
1919

20-
server.register(fastifyHttpErrorsEnhanced, options)
20+
await server.register(fastifyHttpErrorsEnhanced, options)
2121

2222
server.get('/error', {
2323
handler() {
@@ -32,7 +32,7 @@ function buildServer(options: FastifyPluginOptions = {}): FastifyInstance {
3232
}
3333

3434
t.test('should correctly allow preprocessing of error before executing the handler', async t => {
35-
const server = buildServer({
35+
const server = await buildServer({
3636
preHandler(error: FastifyError | Error) {
3737
Object.defineProperty(error, 'preHandlerExecuted', { enumerable: true, value: true })
3838
return error

test/index.test.ts

Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ function routes(instance: FastifyInstance, _options: unknown, done: Callback): v
137137
done()
138138
}
139139

140-
function buildServer(options: FastifyPluginOptions = {}): FastifyInstance {
140+
async function buildServer(options: FastifyPluginOptions = {}): Promise<FastifyInstance> {
141141
const server = fastify({
142142
ajv: {
143143
customOptions: {
@@ -149,8 +149,8 @@ function buildServer(options: FastifyPluginOptions = {}): FastifyInstance {
149149
}
150150
})
151151

152-
server.register(fastifyHttpErrorsEnhanced, options)
153-
server.register(routes)
152+
await server.register(fastifyHttpErrorsEnhanced, options)
153+
await server.register(routes)
154154

155155
return server
156156
}
@@ -191,7 +191,7 @@ function buildStandaloneServer(): FastifyInstance {
191191
t.test('Plugin', t => {
192192
t.test('Handling http-errors', t => {
193193
t.test('should correctly return client errors', async t => {
194-
const server = buildServer()
194+
const server = await buildServer()
195195

196196
const response = await server.inject({ method: 'GET', url: '/not-found' })
197197

@@ -205,7 +205,7 @@ t.test('Plugin', t => {
205205
})
206206

207207
t.test('should correctly return server errors', async t => {
208-
const server = buildServer()
208+
const server = await buildServer()
209209

210210
const response = await server.inject({ method: 'GET', url: '/bad-gateway' })
211211

@@ -218,7 +218,7 @@ t.test('Plugin', t => {
218218
})
219219

220220
t.test('should correctly return error codes when not starting with the prefix', async t => {
221-
const server = buildServer()
221+
const server = await buildServer()
222222

223223
const response = await server.inject({ method: 'GET', url: '/error-with-code' })
224224

@@ -232,7 +232,7 @@ t.test('Plugin', t => {
232232
})
233233

234234
t.test('should correctly return server duck-typed errors', async t => {
235-
const server = buildServer()
235+
const server = await buildServer()
236236

237237
const response = await server.inject({ method: 'GET', url: '/duck-error' })
238238

@@ -245,7 +245,7 @@ t.test('Plugin', t => {
245245
})
246246

247247
t.test('should correctly return additional headers', async t => {
248-
const server = buildServer()
248+
const server = await buildServer()
249249

250250
const response = await server.inject({ method: 'GET', url: '/headers' })
251251

@@ -259,7 +259,7 @@ t.test('Plugin', t => {
259259
})
260260

261261
t.test('should correctly return additional properties', async t => {
262-
const server = buildServer()
262+
const server = await buildServer()
263263

264264
const response = await server.inject({ method: 'GET', url: '/properties' })
265265

@@ -273,7 +273,7 @@ t.test('Plugin', t => {
273273
})
274274

275275
t.test('should default status code to 500 if outside HTTP range', async t => {
276-
const server = buildServer()
276+
const server = await buildServer()
277277

278278
const response = await server.inject({ method: 'GET', url: '/weird-code' })
279279

@@ -286,7 +286,7 @@ t.test('Plugin', t => {
286286
})
287287

288288
t.test('should have good defaults if the error is weirdly manipulated', async t => {
289-
const server = buildServer({ hideUnhandledErrors: false })
289+
const server = await buildServer({ hideUnhandledErrors: false })
290290

291291
const response = await server.inject({ method: 'GET', url: '/weird-error' })
292292

@@ -306,7 +306,7 @@ t.test('Plugin', t => {
306306
t.test(
307307
'should correctly return generic errors by wrapping them in a 500 http-error, including headers and properties',
308308
async t => {
309-
const server = buildServer()
309+
const server = await buildServer()
310310

311311
const response = await server.inject({ method: 'GET', url: '/error' })
312312

@@ -327,7 +327,7 @@ t.test('Plugin', t => {
327327
)
328328

329329
t.test('should correctly parse invalid content type errors', async t => {
330-
const server = buildServer()
330+
const server = await buildServer()
331331

332332
const response = await server.inject({
333333
method: 'POST',
@@ -345,7 +345,7 @@ t.test('Plugin', t => {
345345
})
346346

347347
t.test('should correctly parse missing body errors', async t => {
348-
const server = buildServer()
348+
const server = await buildServer()
349349

350350
const response = await server.inject({
351351
method: 'POST',
@@ -362,7 +362,7 @@ t.test('Plugin', t => {
362362
})
363363

364364
t.test('should correctly parse malformed body errors', async t => {
365-
const server = buildServer()
365+
const server = await buildServer()
366366

367367
const response = await server.inject({
368368
method: 'POST',
@@ -380,7 +380,7 @@ t.test('Plugin', t => {
380380
})
381381

382382
t.test('should correctly return server errors with masking explicitily enabled', async t => {
383-
const server = buildServer({ hideUnhandledErrors: true })
383+
const server = await buildServer({ hideUnhandledErrors: true })
384384

385385
const response = await server.inject({ method: 'GET', url: '/error' })
386386

@@ -393,7 +393,7 @@ t.test('Plugin', t => {
393393
})
394394

395395
t.test('should correctly return server errors with masking explicitily disabled', async t => {
396-
const server = buildServer()
396+
const server = await buildServer()
397397

398398
const response = await server.inject({ method: 'GET', url: '/error' })
399399

@@ -417,7 +417,7 @@ t.test('Plugin', t => {
417417

418418
t.test('Handling validation errors', t => {
419419
t.test('should validate params', async t => {
420-
const server = buildServer()
420+
const server = await buildServer()
421421

422422
const response = await server.inject({
423423
method: 'POST',
@@ -436,7 +436,7 @@ t.test('Plugin', t => {
436436
})
437437

438438
t.test('should validate querystring', async t => {
439-
const server = buildServer()
439+
const server = await buildServer()
440440

441441
const response = await server.inject({
442442
method: 'POST',
@@ -455,7 +455,7 @@ t.test('Plugin', t => {
455455
})
456456

457457
t.test('should validate headers', async t => {
458-
const server = buildServer()
458+
const server = await buildServer()
459459

460460
const response = await server.inject({ method: 'POST', url: '/validated/123', payload: [] })
461461

@@ -469,7 +469,7 @@ t.test('Plugin', t => {
469469
})
470470

471471
t.test('should validate body', async t => {
472-
const server = buildServer()
472+
const server = await buildServer()
473473

474474
const response = await server.inject({ method: 'POST', url: '/validated/123' })
475475

@@ -483,7 +483,7 @@ t.test('Plugin', t => {
483483
})
484484

485485
t.test('should not convert validation if option is disabled', async t => {
486-
const server = buildServer({ convertValidationErrors: false })
486+
const server = await buildServer({ convertValidationErrors: false })
487487

488488
const response = await server.inject({
489489
method: 'POST',
@@ -500,13 +500,13 @@ t.test('Plugin', t => {
500500

501501
t.same(payload, {
502502
error: 'Internal Server Error',
503-
message: '[Error] params.id should be number',
503+
message: '[Error] params/id must be number',
504504
statusCode: INTERNAL_SERVER_ERROR,
505505
validation: [
506506
{
507-
dataPath: '.id',
507+
instancePath: '/id',
508508
keyword: 'type',
509-
message: 'should be number',
509+
message: 'must be number',
510510
params: {
511511
type: 'number'
512512
},
@@ -571,13 +571,13 @@ t.test('Plugin', t => {
571571

572572
t.same(payload, {
573573
error: 'Internal Server Error',
574-
message: '[Error] params.id should be number',
574+
message: '[Error] params/id must be number',
575575
statusCode: INTERNAL_SERVER_ERROR,
576576
validation: [
577577
{
578-
dataPath: '.id',
578+
instancePath: '/id',
579579
keyword: 'type',
580-
message: 'should be number',
580+
message: 'must be number',
581581
params: {
582582
type: 'number'
583583
},

0 commit comments

Comments
 (0)