fastify 5.3.2 → 5.4.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.
Files changed (103) hide show
  1. package/README.md +2 -0
  2. package/build/build-validation.js +2 -1
  3. package/docs/Guides/Delay-Accepting-Requests.md +3 -3
  4. package/docs/Guides/Ecosystem.md +16 -7
  5. package/docs/Guides/Serverless.md +28 -69
  6. package/docs/Reference/ContentTypeParser.md +1 -1
  7. package/docs/Reference/Errors.md +2 -4
  8. package/docs/Reference/Hooks.md +14 -14
  9. package/docs/Reference/Logging.md +3 -3
  10. package/docs/Reference/Middleware.md +1 -1
  11. package/docs/Reference/Reply.md +8 -8
  12. package/docs/Reference/Request.md +1 -1
  13. package/docs/Reference/Routes.md +3 -3
  14. package/docs/Reference/Server.md +40 -10
  15. package/docs/Reference/Validation-and-Serialization.md +1 -1
  16. package/eslint.config.js +17 -9
  17. package/fastify.d.ts +2 -1
  18. package/fastify.js +20 -4
  19. package/lib/configValidator.js +1 -1
  20. package/lib/decorate.js +2 -2
  21. package/lib/errors.js +6 -8
  22. package/lib/logger-factory.js +1 -1
  23. package/lib/logger-pino.js +2 -2
  24. package/lib/pluginOverride.js +3 -1
  25. package/lib/reply.js +9 -13
  26. package/lib/request.js +4 -11
  27. package/lib/server.js +30 -51
  28. package/lib/symbols.js +1 -0
  29. package/lib/warnings.js +8 -0
  30. package/package.json +11 -7
  31. package/test/404s.test.js +226 -325
  32. package/test/allow-unsafe-regex.test.js +19 -48
  33. package/test/als.test.js +28 -40
  34. package/test/async-await.test.js +11 -2
  35. package/test/body-limit.test.js +41 -65
  36. package/test/build-certificate.js +1 -1
  37. package/test/close-pipelining.test.js +5 -4
  38. package/test/custom-parser-async.test.js +17 -22
  39. package/test/decorator-namespace.test._js_ +3 -4
  40. package/test/decorator.test.js +422 -341
  41. package/test/diagnostics-channel/async-delay-request.test.js +7 -16
  42. package/test/diagnostics-channel/sync-delay-request.test.js +7 -16
  43. package/test/helper.js +108 -70
  44. package/test/hooks-async.test.js +248 -218
  45. package/test/hooks.on-listen.test.js +255 -239
  46. package/test/hooks.on-ready.test.js +110 -92
  47. package/test/hooks.test.js +910 -769
  48. package/test/http-methods/lock.test.js +31 -31
  49. package/test/http-methods/mkcol.test.js +5 -9
  50. package/test/http-methods/proppatch.test.js +23 -29
  51. package/test/http-methods/report.test.js +44 -69
  52. package/test/http-methods/search.test.js +67 -82
  53. package/test/http2/closing.test.js +38 -20
  54. package/test/http2/secure-with-fallback.test.js +28 -27
  55. package/test/https/https.test.js +56 -53
  56. package/test/inject.test.js +114 -97
  57. package/test/input-validation.js +63 -53
  58. package/test/internals/errors.test.js +0 -10
  59. package/test/internals/handle-request.test.js +49 -66
  60. package/test/internals/hooks.test.js +17 -0
  61. package/test/issue-4959.test.js +14 -5
  62. package/test/listen.4.test.js +31 -43
  63. package/test/logger/response.test.js +19 -20
  64. package/test/nullable-validation.test.js +33 -46
  65. package/test/options.error-handler.test.js +1 -1
  66. package/test/options.test.js +1 -1
  67. package/test/output-validation.test.js +49 -72
  68. package/test/patch.error-handler.test.js +1 -1
  69. package/test/patch.test.js +1 -1
  70. package/test/plugin.1.test.js +71 -60
  71. package/test/plugin.2.test.js +104 -86
  72. package/test/plugin.3.test.js +56 -35
  73. package/test/plugin.4.test.js +124 -119
  74. package/test/promises.test.js +36 -30
  75. package/test/proto-poisoning.test.js +78 -97
  76. package/test/put.error-handler.test.js +1 -1
  77. package/test/put.test.js +1 -1
  78. package/test/reply-error.test.js +169 -148
  79. package/test/reply-trailers.test.js +119 -108
  80. package/test/request-error.test.js +0 -46
  81. package/test/route-hooks.test.js +112 -92
  82. package/test/route-prefix.test.js +194 -133
  83. package/test/schema-feature.test.js +309 -238
  84. package/test/schema-serialization.test.js +177 -154
  85. package/test/schema-special-usage.test.js +165 -132
  86. package/test/schema-validation.test.js +278 -199
  87. package/test/set-error-handler.test.js +58 -1
  88. package/test/skip-reply-send.test.js +64 -69
  89. package/test/stream.1.test.js +30 -27
  90. package/test/stream.2.test.js +20 -10
  91. package/test/stream.3.test.js +37 -31
  92. package/test/trust-proxy.test.js +32 -58
  93. package/test/types/errors.test-d.ts +0 -1
  94. package/test/types/fastify.test-d.ts +3 -0
  95. package/test/types/plugin.test-d.ts +1 -1
  96. package/test/types/register.test-d.ts +1 -1
  97. package/test/types/request.test-d.ts +1 -0
  98. package/test/url-rewriting.test.js +45 -62
  99. package/test/use-semicolon-delimiter.test.js +1 -1
  100. package/types/errors.d.ts +0 -1
  101. package/types/request.d.ts +1 -0
  102. package/.taprc +0 -7
  103. package/test/http2/missing-http2-module.test.js +0 -17
@@ -3,10 +3,10 @@
3
3
  const { test } = require('node:test')
4
4
  const Fastify = require('../..')
5
5
  const h2url = require('h2url')
6
- const sget = require('simple-get').concat
7
6
  const msg = { hello: 'world' }
8
7
 
9
8
  const { buildCertificate } = require('../build-certificate')
9
+ const { Agent } = require('undici')
10
10
  test.before(buildCertificate)
11
11
 
12
12
  test('secure with fallback', async (t) => {
@@ -41,12 +41,12 @@ test('secure with fallback', async (t) => {
41
41
 
42
42
  t.after(() => { fastify.close() })
43
43
 
44
- await fastify.listen({ port: 0 })
44
+ const fastifyServer = await fastify.listen({ port: 0 })
45
45
 
46
46
  await t.test('https get error', async (t) => {
47
47
  t.plan(1)
48
48
 
49
- const url = `https://localhost:${fastify.server.address().port}/error`
49
+ const url = `${fastifyServer}/error`
50
50
  const res = await h2url.concat({ url })
51
51
 
52
52
  t.assert.strictEqual(res.headers[':status'], 500)
@@ -55,9 +55,8 @@ test('secure with fallback', async (t) => {
55
55
  await t.test('https post', async (t) => {
56
56
  t.plan(2)
57
57
 
58
- const url = `https://localhost:${fastify.server.address().port}`
59
58
  const res = await h2url.concat({
60
- url,
59
+ url: fastifyServer,
61
60
  method: 'POST',
62
61
  body: JSON.stringify({ hello: 'http2' }),
63
62
  headers: {
@@ -72,39 +71,41 @@ test('secure with fallback', async (t) => {
72
71
  await t.test('https get request', async (t) => {
73
72
  t.plan(3)
74
73
 
75
- const url = `https://localhost:${fastify.server.address().port}`
76
- const res = await h2url.concat({ url })
74
+ const res = await h2url.concat({ url: fastifyServer })
77
75
 
78
76
  t.assert.strictEqual(res.headers[':status'], 200)
79
77
  t.assert.strictEqual(res.headers['content-length'], '' + JSON.stringify(msg).length)
80
78
  t.assert.deepStrictEqual(JSON.parse(res.body), msg)
81
79
  })
82
80
 
83
- await t.test('http1 get request', (t, done) => {
81
+ await t.test('http1 get request', async t => {
84
82
  t.plan(4)
85
- sget({
86
- method: 'GET',
87
- url: 'https://localhost:' + fastify.server.address().port,
88
- rejectUnauthorized: false
89
- }, (err, response, body) => {
90
- t.assert.ifError(err)
91
- t.assert.strictEqual(response.statusCode, 200)
92
- t.assert.strictEqual(response.headers['content-length'], '' + body.length)
93
- t.assert.deepStrictEqual(JSON.parse(body), { hello: 'world' })
94
- done()
83
+ const result = await fetch(fastifyServer, {
84
+ dispatcher: new Agent({
85
+ connect: {
86
+ rejectUnauthorized: false
87
+ }
88
+ })
95
89
  })
90
+
91
+ const body = await result.text()
92
+ t.assert.ok(result.ok)
93
+ t.assert.strictEqual(result.status, 200)
94
+ t.assert.strictEqual(result.headers.get('content-length'), '' + body.length)
95
+ t.assert.deepStrictEqual(JSON.parse(body), msg)
96
96
  })
97
97
 
98
- await t.test('http1 get error', (t, done) => {
98
+ await t.test('http1 get error', async t => {
99
99
  t.plan(2)
100
- sget({
101
- method: 'GET',
102
- url: 'https://localhost:' + fastify.server.address().port + '/error',
103
- rejectUnauthorized: false
104
- }, (err, response, body) => {
105
- t.assert.ifError(err)
106
- t.assert.strictEqual(response.statusCode, 500)
107
- done()
100
+ const result = await fetch(`${fastifyServer}/error`, {
101
+ dispatcher: new Agent({
102
+ connect: {
103
+ rejectUnauthorized: false
104
+ }
105
+ })
108
106
  })
107
+
108
+ t.assert.ok(!result.ok)
109
+ t.assert.strictEqual(result.status, 500)
109
110
  })
110
111
  })
@@ -1,10 +1,11 @@
1
1
  'use strict'
2
2
 
3
3
  const { test } = require('node:test')
4
- const sget = require('simple-get').concat
4
+ const { request } = require('undici')
5
5
  const Fastify = require('../..')
6
6
 
7
7
  const { buildCertificate } = require('../build-certificate')
8
+ const { Agent } = require('undici')
8
9
  test.before(buildCertificate)
9
10
 
10
11
  test('https', async (t) => {
@@ -35,43 +36,45 @@ test('https', async (t) => {
35
36
 
36
37
  t.after(() => { fastify.close() })
37
38
 
38
- await t.test('https get request', (t, done) => {
39
+ await t.test('https get request', async t => {
39
40
  t.plan(4)
40
- sget({
41
- method: 'GET',
42
- url: 'https://localhost:' + fastify.server.address().port,
43
- rejectUnauthorized: false
44
- }, (err, response, body) => {
45
- t.assert.ifError(err)
46
- t.assert.strictEqual(response.statusCode, 200)
47
- t.assert.strictEqual(response.headers['content-length'], '' + body.length)
48
- t.assert.deepStrictEqual(JSON.parse(body), { hello: 'world' })
49
- done()
41
+ const result = await fetch('https://localhost:' + fastify.server.address().port, {
42
+ dispatcher: new Agent({
43
+ connect: {
44
+ rejectUnauthorized: false
45
+ }
46
+ })
50
47
  })
48
+ t.assert.ok(result.ok)
49
+ t.assert.strictEqual(result.status, 200)
50
+ const body = await result.text()
51
+ t.assert.strictEqual(result.headers.get('content-length'), '' + body.length)
52
+ t.assert.deepStrictEqual(JSON.parse(body), { hello: 'world' })
51
53
  })
52
54
 
53
- await t.test('https get request without trust proxy - protocol', (t, done) => {
54
- t.plan(4)
55
- sget({
56
- method: 'GET',
57
- url: 'https://localhost:' + fastify.server.address().port + '/proto',
58
- rejectUnauthorized: false
59
- }, (err, response, body) => {
60
- t.assert.ifError(err)
61
- t.assert.deepStrictEqual(JSON.parse(body), { proto: 'https' })
55
+ await t.test('https get request without trust proxy - protocol', async t => {
56
+ t.plan(3)
57
+ const result1 = await fetch(`${'https://localhost:' + fastify.server.address().port}/proto`, {
58
+ dispatcher: new Agent({
59
+ connect: {
60
+ rejectUnauthorized: false
61
+ }
62
+ })
62
63
  })
63
- sget({
64
- method: 'GET',
65
- url: 'https://localhost:' + fastify.server.address().port + '/proto',
66
- rejectUnauthorized: false,
64
+ t.assert.ok(result1.ok)
65
+ t.assert.deepStrictEqual(await result1.json(), { proto: 'https' })
66
+
67
+ const result2 = await fetch(`${'https://localhost:' + fastify.server.address().port}/proto`, {
68
+ dispatcher: new Agent({
69
+ connect: {
70
+ rejectUnauthorized: false
71
+ }
72
+ }),
67
73
  headers: {
68
74
  'x-forwarded-proto': 'lorem'
69
75
  }
70
- }, (err, response, body) => {
71
- t.assert.ifError(err)
72
- t.assert.deepStrictEqual(JSON.parse(body), { proto: 'https' })
73
- done()
74
76
  })
77
+ t.assert.deepStrictEqual(await result2.json(), { proto: 'https' })
75
78
  })
76
79
  })
77
80
 
@@ -98,36 +101,36 @@ test('https - headers', async (t) => {
98
101
 
99
102
  await fastify.listen({ port: 0 })
100
103
 
101
- await t.test('https get request', (t, done) => {
102
- t.plan(4)
103
- sget({
104
- method: 'GET',
105
- url: 'https://localhost:' + fastify.server.address().port,
106
- rejectUnauthorized: false
107
- }, (err, response, body) => {
108
- t.assert.ifError(err)
109
- t.assert.strictEqual(response.statusCode, 200)
110
- const parsedBody = JSON.parse(body)
111
- t.assert.strictEqual(parsedBody.hostname, 'localhost')
112
- t.assert.strictEqual(parsedBody.port, fastify.server.address().port)
113
- done()
104
+ await t.test('https get request', async t => {
105
+ t.plan(3)
106
+ const result = await fetch('https://localhost:' + fastify.server.address().port, {
107
+ dispatcher: new Agent({
108
+ connect: {
109
+ rejectUnauthorized: false
110
+ }
111
+ })
114
112
  })
113
+ t.assert.ok(result.ok)
114
+ t.assert.strictEqual(result.status, 200)
115
+ t.assert.deepStrictEqual(await result.json(), { hostname: 'localhost', port: fastify.server.address().port, hello: 'world' })
115
116
  })
116
- await t.test('https get request - test port fall back', (t, done) => {
117
- t.plan(3)
118
- sget({
117
+
118
+ await t.test('https get request - test port fall back', async t => {
119
+ t.plan(2)
120
+
121
+ const result = await request('https://localhost:' + fastify.server.address().port, {
119
122
  method: 'GET',
120
123
  headers: {
121
124
  host: 'example.com'
122
125
  },
123
- url: 'https://localhost:' + fastify.server.address().port,
124
- rejectUnauthorized: false
125
- }, (err, response, body) => {
126
- t.assert.ifError(err)
127
- t.assert.strictEqual(response.statusCode, 200)
128
- const parsedBody = JSON.parse(body)
129
- t.assert.strictEqual(parsedBody.port, null)
130
- done()
126
+ dispatcher: new Agent({
127
+ connect: {
128
+ rejectUnauthorized: false
129
+ }
130
+ })
131
131
  })
132
+
133
+ t.assert.strictEqual(result.statusCode, 200)
134
+ t.assert.deepStrictEqual(await result.body.json(), { hello: 'world', hostname: 'example.com', port: null })
132
135
  })
133
136
  })