@fastify/reply-from 12.0.0 → 12.0.2

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 (99) hide show
  1. package/.github/dependabot.yml +1 -1
  2. package/.github/workflows/ci.yml +0 -1
  3. package/README.md +16 -16
  4. package/eslint.config.js +6 -0
  5. package/examples/example.js +2 -2
  6. package/index.js +6 -8
  7. package/lib/request.js +4 -4
  8. package/package.json +37 -10
  9. package/test/async-route-handler.test.js +1 -1
  10. package/test/base-get.test.js +1 -1
  11. package/test/base-path.test.js +2 -2
  12. package/test/base-querystring.test.js +1 -1
  13. package/test/core-with-path-in-base.test.js +1 -1
  14. package/test/custom-undici-instance.test.js +2 -2
  15. package/test/disable-request-logging.test.js +3 -3
  16. package/test/fastify-multipart-incompatibility.test.js +2 -2
  17. package/test/fix-GHSA-v2v2-hph8-q5xp.test.js +52 -36
  18. package/test/full-delete-http2.test.js +2 -2
  19. package/test/full-get-test.test.js +1 -1
  20. package/test/full-https-get.test.js +1 -1
  21. package/test/full-post-extended-content-type.test.js +1 -1
  22. package/test/full-post-http2.test.js +1 -1
  23. package/test/full-post-stream-core.test.js +3 -3
  24. package/test/full-post-stream.test.js +3 -3
  25. package/test/full-post.test.js +2 -2
  26. package/test/full-querystring-rewrite-option-complex.test.js +1 -1
  27. package/test/full-querystring-rewrite-option-function-request.test.js +3 -3
  28. package/test/full-querystring-rewrite-option-function.test.js +1 -1
  29. package/test/full-querystring-rewrite-option.test.js +1 -1
  30. package/test/full-querystring-rewrite-string.test.js +1 -1
  31. package/test/full-querystring-rewrite.test.js +1 -1
  32. package/test/full-querystring.test.js +1 -1
  33. package/test/full-rewrite-body-content-type.test.js +10 -7
  34. package/test/full-rewrite-body-http.test.js +2 -2
  35. package/test/full-rewrite-body-to-empty-string.test.js +2 -2
  36. package/test/full-rewrite-body-to-null.test.js +2 -2
  37. package/test/full-rewrite-body.test.js +2 -2
  38. package/test/get-upstream-http.test.js +3 -3
  39. package/test/get-upstream-undici.test.js +1 -1
  40. package/test/get-with-body.test.js +1 -1
  41. package/test/head-with-body.test.js +1 -7
  42. package/test/host-header.test.js +4 -4
  43. package/test/http-agents.test.js +1 -1
  44. package/test/http-global-agent.test.js +1 -1
  45. package/test/http-http2.test.js +2 -2
  46. package/test/http-invalid-target.test.js +1 -1
  47. package/test/http-retry.test.js +3 -3
  48. package/test/http-timeout.test.js +4 -4
  49. package/test/http2-http2.test.js +2 -2
  50. package/test/http2-https.test.js +2 -2
  51. package/test/http2-invalid-target.test.js +1 -1
  52. package/test/http2-target-crash.test.js +2 -2
  53. package/test/http2-target-multi-crash.test.js +1 -1
  54. package/test/http2-timeout-disabled.test.js +2 -2
  55. package/test/http2-timeout.test.js +4 -4
  56. package/test/https-agents.test.js +1 -1
  57. package/test/https-global-agent.test.js +1 -1
  58. package/test/method.test.js +3 -3
  59. package/test/modifyCoreObjects-false.test.js +1 -1
  60. package/test/no-body-opts-with-get.test.js +2 -2
  61. package/test/no-body-opts-with-head.test.js +2 -2
  62. package/test/no-stream-body-option.test.js +2 -2
  63. package/test/on-error.test.js +2 -2
  64. package/test/on-invalid-upstream-response.test.js +1 -1
  65. package/test/padded-body.test.js +2 -2
  66. package/test/post-formbody.test.js +1 -1
  67. package/test/post-plain-text.test.js +1 -1
  68. package/test/post-with-custom-encoded-contenttype.test.js +2 -2
  69. package/test/post-with-octet-stream.test.js +5 -5
  70. package/test/retry-on-503.test.js +4 -4
  71. package/test/retry-with-a-custom-handler.test.js +7 -7
  72. package/test/rewrite-headers-type.test.js +2 -2
  73. package/test/rewrite-headers.test.js +3 -3
  74. package/test/rewrite-request-headers-type.test.js +2 -2
  75. package/test/rewrite-request-headers.test.js +2 -2
  76. package/test/transform-body.test.js +3 -3
  77. package/test/undici-agent.test.js +2 -2
  78. package/test/undici-body.test.js +3 -3
  79. package/test/undici-chaining.test.js +3 -3
  80. package/test/undici-connect-timeout.test.js +2 -2
  81. package/test/undici-custom-dispatcher.test.js +2 -2
  82. package/test/undici-global-agent.test.js +2 -2
  83. package/test/undici-no-destroy.test.js +1 -1
  84. package/test/undici-options.test.js +2 -2
  85. package/test/undici-proxy-agent.test.js +47 -28
  86. package/test/undici-retry.test.js +3 -3
  87. package/test/undici-timeout-body-partial.test.js +1 -1
  88. package/test/undici-timeout-body.test.js +1 -1
  89. package/test/undici-timeout.test.js +2 -2
  90. package/test/undici-with-path-in-base.test.js +1 -1
  91. package/test/undici.test.js +1 -1
  92. package/test/unexpected-error.test.js +2 -2
  93. package/test/unix-http-undici-from.test.js +3 -3
  94. package/test/unix-http-undici.test.js +1 -1
  95. package/test/unix-http.test.js +1 -1
  96. package/test/unix-https-undici.test.js +1 -1
  97. package/test/unix-https.test.js +1 -1
  98. package/types/index.d.ts +10 -11
  99. package/types/index.test-d.ts +138 -108
@@ -37,7 +37,7 @@ t.test('undici body timeout', async (t) => {
37
37
  }
38
38
  })
39
39
 
40
- instance.get('/', (request, reply) => {
40
+ instance.get('/', (_request, reply) => {
41
41
  reply.from()
42
42
  })
43
43
 
@@ -35,7 +35,7 @@ t.test('undici body timeout', async (t) => {
35
35
  }
36
36
  })
37
37
 
38
- instance.get('/', (request, reply) => {
38
+ instance.get('/', (_request, reply) => {
39
39
  reply.from()
40
40
  })
41
41
 
@@ -12,7 +12,7 @@ t.test('undici request timeout', async (t) => {
12
12
  const target = Fastify()
13
13
  t.teardown(target.close.bind(target))
14
14
 
15
- target.get('/', (request, reply) => {
15
+ target.get('/', (_request, reply) => {
16
16
  t.pass('request arrives')
17
17
 
18
18
  clock.setTimeout(() => {
@@ -33,7 +33,7 @@ t.test('undici request timeout', async (t) => {
33
33
  }
34
34
  })
35
35
 
36
- instance.get('/', (request, reply) => {
36
+ instance.get('/', (_request, reply) => {
37
37
  reply.from()
38
38
  })
39
39
 
@@ -22,7 +22,7 @@ const target = http.createServer((req, res) => {
22
22
  res.end('hello world')
23
23
  })
24
24
 
25
- instance.get('/', (request, reply) => {
25
+ instance.get('/', (_request, reply) => {
26
26
  reply.from('/hello')
27
27
  })
28
28
 
@@ -22,7 +22,7 @@ const target = http.createServer((req, res) => {
22
22
  res.end('hello world')
23
23
  })
24
24
 
25
- instance.get('/', (request, reply) => {
25
+ instance.get('/', (_request, reply) => {
26
26
  reply.from()
27
27
  })
28
28
 
@@ -9,7 +9,7 @@ const proxyquire = require('proxyquire')
9
9
  const From = proxyquire('..', {
10
10
  './lib/request': function () {
11
11
  return {
12
- request: (opts, callback) => { callback(new Error('foo')) },
12
+ request: (_opts, callback) => { callback(new Error('foo')) },
13
13
  close: () => {}
14
14
  }
15
15
  }
@@ -20,7 +20,7 @@ test('unexpected error renders 500', async (t) => {
20
20
 
21
21
  t.teardown(instance.close.bind(instance))
22
22
 
23
- instance.get('/', (request, reply) => {
23
+ instance.get('/', (_request, reply) => {
24
24
  reply.code(201)
25
25
  reply.from()
26
26
  })
@@ -26,12 +26,12 @@ try {
26
26
  } catch (_) {
27
27
  }
28
28
 
29
- const target = http.createServer((req, res) => {
29
+ const target = http.createServer((_req, res) => {
30
30
  t.fail('no response')
31
31
  res.end()
32
32
  })
33
33
 
34
- instance.get('/', (request, reply) => {
34
+ instance.get('/', (_request, reply) => {
35
35
  reply.from(`unix+http://${querystring.escape(socketPath)}/hello`)
36
36
  })
37
37
 
@@ -43,7 +43,7 @@ instance.listen({ port: 0 }, (err) => {
43
43
  target.listen(socketPath, (err) => {
44
44
  t.error(err)
45
45
 
46
- get(`http://localhost:${instance.server.address().port}`, (err, res, data) => {
46
+ get(`http://localhost:${instance.server.address().port}`, (err, res) => {
47
47
  t.error(err)
48
48
  t.equal(res.statusCode, 500)
49
49
  })
@@ -39,7 +39,7 @@ const target = http.createServer((req, res) => {
39
39
  res.end('hello world')
40
40
  })
41
41
 
42
- instance.get('/', (request, reply) => {
42
+ instance.get('/', (_request, reply) => {
43
43
  reply.from('hello')
44
44
  })
45
45
 
@@ -42,7 +42,7 @@ const target = http.createServer((req, res) => {
42
42
  res.end('hello world')
43
43
  })
44
44
 
45
- instance.get('/', (request, reply) => {
45
+ instance.get('/', (_request, reply) => {
46
46
  reply.from('hello')
47
47
  })
48
48
 
@@ -45,7 +45,7 @@ const target = https.createServer(certs, (req, res) => {
45
45
  res.end('hello world')
46
46
  })
47
47
 
48
- instance.get('/', (request, reply) => {
48
+ instance.get('/', (_request, reply) => {
49
49
  reply.from('hello')
50
50
  })
51
51
 
@@ -45,7 +45,7 @@ const target = https.createServer(certs, (req, res) => {
45
45
  res.end('hello world')
46
46
  })
47
47
 
48
- instance.get('/', (request, reply) => {
48
+ instance.get('/', (_request, reply) => {
49
49
  reply.from(`unix+https://${querystring.escape(socketPath)}/hello`)
50
50
  })
51
51
 
package/types/index.d.ts CHANGED
@@ -9,29 +9,28 @@ import {
9
9
  RawServerBase,
10
10
  RequestGenericInterface,
11
11
  RouteGenericInterface
12
- } from 'fastify';
12
+ } from 'fastify'
13
13
 
14
14
  import {
15
15
  Agent,
16
16
  AgentOptions,
17
17
  IncomingHttpHeaders,
18
18
  RequestOptions,
19
- } from "http";
19
+ } from 'http'
20
20
  import {
21
21
  ClientSessionOptions,
22
22
  ClientSessionRequestOptions,
23
23
  IncomingHttpHeaders as Http2IncomingHttpHeaders,
24
24
  SecureClientSessionOptions,
25
- } from "http2";
25
+ } from 'http2'
26
26
  import {
27
27
  Agent as SecureAgent,
28
28
  AgentOptions as SecureAgentOptions,
29
29
  RequestOptions as SecureRequestOptions
30
- } from "https";
31
- import { Pool } from 'undici';
32
- import { ProxyAgent } from 'undici';
30
+ } from 'https'
31
+ import { Pool, ProxyAgent, Dispatcher } from 'undici'
33
32
 
34
- declare module "fastify" {
33
+ declare module 'fastify' {
35
34
  interface FastifyReply {
36
35
  from(
37
36
  source?: string,
@@ -46,7 +45,7 @@ declare namespace fastifyReplyFrom {
46
45
  search: string | undefined,
47
46
  reqUrl: string,
48
47
  request: FastifyRequest<RequestGenericInterface, RawServerBase>
49
- ) => string;
48
+ ) => string
50
49
 
51
50
  export type RetryDetails = {
52
51
  err: Error;
@@ -105,7 +104,7 @@ declare namespace fastifyReplyFrom {
105
104
  disableCache?: boolean;
106
105
  http?: HttpOptions;
107
106
  http2?: Http2Options | boolean;
108
- undici?: Pool.Options & { proxy?: string | URL | ProxyAgent.Options };
107
+ undici?: Pool.Options & { proxy?: string | URL | ProxyAgent.Options } | { request: Dispatcher['request'] };
109
108
  contentTypesToEncode?: string[];
110
109
  retryMethods?: (HTTPMethods | 'TRACE')[];
111
110
  maxRetriesOn503?: number;
@@ -115,8 +114,8 @@ declare namespace fastifyReplyFrom {
115
114
  }
116
115
 
117
116
  export const fastifyReplyFrom: FastifyReplyFrom
118
- export { fastifyReplyFrom as default };
117
+ export { fastifyReplyFrom as default }
119
118
  }
120
119
 
121
- declare function fastifyReplyFrom(...params: Parameters<FastifyReplyFrom>): ReturnType<FastifyReplyFrom>
120
+ declare function fastifyReplyFrom (...params: Parameters<FastifyReplyFrom>): ReturnType<FastifyReplyFrom>
122
121
  export = fastifyReplyFrom
@@ -1,15 +1,16 @@
1
- import fastify, { FastifyReply, FastifyRequest, RawReplyDefaultExpression, RawServerBase, RequestGenericInterface, RouteGenericInterface } from "fastify";
2
- import * as http from 'http';
3
- import { IncomingHttpHeaders } from "http2";
4
- import * as https from 'https';
5
- import { AddressInfo } from "net";
6
- import { expectType } from 'tsd';
7
- import replyFrom, { FastifyReplyFromOptions } from "..";
1
+ import fastify, { FastifyReply, FastifyRequest, RawReplyDefaultExpression, RawServerBase, RequestGenericInterface, RouteGenericInterface } from 'fastify'
2
+ import * as http from 'node:http'
3
+ import { IncomingHttpHeaders } from 'http2'
4
+ import * as https from 'node:https'
5
+ import { AddressInfo } from 'net'
6
+ import { expectType } from 'tsd'
7
+ import { Agent, Client, Dispatcher, Pool } from 'undici'
8
+ import replyFrom, { FastifyReplyFromOptions } from '..'
8
9
  // @ts-ignore
9
- import tap from 'tap';
10
+ import tap from 'tap'
10
11
 
11
12
  const fullOptions: FastifyReplyFromOptions = {
12
- base: "http://example2.com",
13
+ base: 'http://example2.com',
13
14
  http: {
14
15
  agentOptions: {
15
16
  keepAliveMsecs: 60 * 1000,
@@ -47,118 +48,147 @@ const fullOptions: FastifyReplyFromOptions = {
47
48
  disableRequestLogging: false,
48
49
  globalAgent: false,
49
50
  destroyAgent: true
50
- };
51
-
52
- async function main() {
53
- const server = fastify();
54
-
55
- server.register(replyFrom);
56
-
57
- server.register(replyFrom, {});
58
-
59
- server.register(replyFrom, {http2: true});
60
-
61
- server.register(replyFrom, fullOptions);
62
-
63
- server.register(replyFrom, { undici: { proxy: new URL('http://example2.com:8080') } });
64
-
65
- server.register(replyFrom, { undici: { proxy: { uri: 'http://example2.com:8080' } } });
66
-
67
- server.get("/v1", (request, reply) => {
68
- expectType<FastifyReply>(reply.from());
69
- });
70
- server.get("/v3", (request, reply) => {
71
- reply.from("/v3", {
72
- body: {hello: "world"},
73
- rewriteRequestHeaders(req, headers) {
74
- expectType<FastifyRequest<RequestGenericInterface, RawServerBase>>(req);
75
- return headers;
76
- },
77
- getUpstream(req, base) {
78
- expectType<FastifyRequest<RequestGenericInterface, RawServerBase>>(req);
79
- return base;
80
- },
81
- onResponse(request, reply, res) {
82
- expectType<FastifyRequest<RequestGenericInterface, RawServerBase>>(request);
83
- expectType<FastifyReply<RouteGenericInterface, RawServerBase>>(reply);
84
- expectType<RawReplyDefaultExpression<RawServerBase>>(res);
85
- expectType<number>(res.statusCode);
86
- }
87
- });
88
- });
89
-
90
- // http2
91
- const instance = fastify({http2: true});
51
+ }
52
+
53
+ async function main () {
54
+ const server = fastify()
55
+
56
+ server.register(replyFrom)
57
+
58
+ server.register(replyFrom, {})
59
+
60
+ server.register(replyFrom, { http2: true })
61
+
62
+ server.register(replyFrom, fullOptions)
63
+
64
+ server.register(replyFrom, { undici: { proxy: new URL('http://example2.com:8080') } })
65
+
66
+ server.register(replyFrom, { undici: { proxy: { uri: 'http://example2.com:8080' } } })
67
+
68
+ server.get('/v1', (_request, reply) => {
69
+ expectType<FastifyReply>(reply.from())
70
+ })
71
+ server.get('/v3', (_request, reply) => {
72
+ reply.from('/v3', {
73
+ body: { hello: 'world' },
74
+ rewriteRequestHeaders (req, headers) {
75
+ expectType<FastifyRequest<RequestGenericInterface, RawServerBase>>(req)
76
+ return headers
77
+ },
78
+ getUpstream (req, base) {
79
+ expectType<FastifyRequest<RequestGenericInterface, RawServerBase>>(req)
80
+ return base
81
+ },
82
+ onResponse (request, reply, res) {
83
+ expectType<FastifyRequest<RequestGenericInterface, RawServerBase>>(request)
84
+ expectType<FastifyReply<RouteGenericInterface, RawServerBase>>(reply)
85
+ expectType<RawReplyDefaultExpression<RawServerBase>>(res)
86
+ expectType<number>(res.statusCode)
87
+ }
88
+ })
89
+ })
90
+
91
+ // http2
92
+ const instance = fastify({ http2: true })
92
93
  // @ts-ignore
93
- tap.tearDown(instance.close.bind(instance));
94
- const target = fastify({http2: true});
94
+ tap.tearDown(instance.close.bind(instance))
95
+ const target = fastify({ http2: true })
95
96
  // @ts-ignore
96
- tap.tearDown(target.close.bind(target));
97
- instance.get("/", (request, reply) => {
98
- reply.from();
99
- });
100
-
101
- instance.get("/http2", (request, reply) => {
102
- reply.from("/", {
103
- method: "POST",
104
- retryDelay: ({err, req, res, attempt, retriesCount, getDefaultDelay }) => {
105
- const defaultDelay = getDefaultDelay();
106
- if (defaultDelay) return defaultDelay;
107
-
108
- if (res && res.statusCode === 500 && req.method === "GET") {
109
- return 300;
110
- }
111
- return null;
112
- },
113
- rewriteHeaders(headers, req) {
114
- return headers;
115
- },
116
- rewriteRequestHeaders(req, headers: IncomingHttpHeaders) {
117
- return headers;
118
- },
119
- getUpstream(req, base) {
120
- return base;
121
- },
122
- onError(reply: FastifyReply<RouteGenericInterface, RawServerBase>, error) {
123
- return reply.send(error.error);
124
- },
125
- queryString(search, reqUrl, request) {
126
- expectType<string | undefined>(search);
127
- expectType<string>(reqUrl);
128
- expectType<FastifyRequest<RequestGenericInterface, RawServerBase>>(request);
129
- return '';
130
- },
131
- });
132
- });
133
-
134
- await target.listen({ port: 0 });
135
- const port = (target.server.address() as AddressInfo).port;
97
+ tap.tearDown(target.close.bind(target))
98
+ instance.get('/', (_request, reply) => {
99
+ reply.from()
100
+ })
101
+
102
+ instance.get('/http2', (_request, reply) => {
103
+ reply.from('/', {
104
+ method: 'POST',
105
+ // eslint-disable-next-line n/handle-callback-err -- Not a real request, not handling errors
106
+ retryDelay: ({ req, res, getDefaultDelay }) => {
107
+ const defaultDelay = getDefaultDelay()
108
+ if (defaultDelay) return defaultDelay
109
+
110
+ if (res && res.statusCode === 500 && req.method === 'GET') {
111
+ return 300
112
+ }
113
+ return null
114
+ },
115
+ rewriteHeaders (headers) {
116
+ return headers
117
+ },
118
+ rewriteRequestHeaders (_req, headers: IncomingHttpHeaders) {
119
+ return headers
120
+ },
121
+ getUpstream (_req, base) {
122
+ return base
123
+ },
124
+ onError (reply: FastifyReply<RouteGenericInterface, RawServerBase>, error) {
125
+ return reply.send(error.error)
126
+ },
127
+ queryString (search, reqUrl, request) {
128
+ expectType<string | undefined>(search)
129
+ expectType<string>(reqUrl)
130
+ expectType<FastifyRequest<RequestGenericInterface, RawServerBase>>(request)
131
+ return ''
132
+ },
133
+ })
134
+ })
135
+
136
+ await target.listen({ port: 0 })
137
+ const port = (target.server.address() as AddressInfo).port
136
138
  instance.register(replyFrom, {
137
- base: `http://localhost:${port}`,
138
- http2: {
139
- sessionOptions: {
140
- rejectUnauthorized: false,
141
- },
139
+ base: `http://localhost:${port}`,
140
+ http2: {
141
+ sessionOptions: {
142
+ rejectUnauthorized: false,
142
143
  },
143
- });
144
+ },
145
+ })
144
146
  instance.register(replyFrom, {
145
147
  base: `http://localhost:${port}`,
146
148
  http2: true,
147
- });
148
- await instance.listen({ port: 0 });
149
+ })
150
+ await instance.listen({ port: 0 })
149
151
 
150
- const undiciInstance = fastify();
152
+ const undiciInstance = fastify()
151
153
  undiciInstance.register(replyFrom, {
152
- base: "http://example2.com",
154
+ base: 'http://example2.com',
153
155
  undici: {
154
156
  pipelining: 10,
155
157
  connections: 10
156
158
  }
157
- });
158
- await undiciInstance.ready();
159
+ })
160
+ await undiciInstance.ready()
161
+
162
+ const undiciInstanceAgent = fastify()
163
+ undiciInstance.register(replyFrom, {
164
+ base: 'http://example2.com',
165
+ undici: new Agent()
166
+ })
167
+ await undiciInstanceAgent.ready()
168
+
169
+ const undiciInstancePool = fastify()
170
+ undiciInstance.register(replyFrom, {
171
+ base: 'http://example2.com',
172
+ undici: new Pool('http://example2.com')
173
+ })
174
+ await undiciInstancePool.ready()
175
+
176
+ const undiciInstanceClient = fastify()
177
+ undiciInstance.register(replyFrom, {
178
+ base: 'http://example2.com',
179
+ undici: new Client('http://example2.com')
180
+ })
181
+ await undiciInstanceClient.ready()
182
+
183
+ const undiciInstanceDispatcher = fastify()
184
+ undiciInstance.register(replyFrom, {
185
+ base: 'http://example2.com',
186
+ undici: new Dispatcher()
187
+ })
188
+ await undiciInstanceDispatcher.ready()
159
189
 
160
- tap.pass('done');
161
- tap.end();
190
+ tap.pass('done')
191
+ tap.end()
162
192
  }
163
193
 
164
- main();
194
+ main()