@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.
- package/.github/dependabot.yml +1 -1
- package/.github/workflows/ci.yml +0 -1
- package/README.md +16 -16
- package/eslint.config.js +6 -0
- package/examples/example.js +2 -2
- package/index.js +6 -8
- package/lib/request.js +4 -4
- package/package.json +37 -10
- package/test/async-route-handler.test.js +1 -1
- package/test/base-get.test.js +1 -1
- package/test/base-path.test.js +2 -2
- package/test/base-querystring.test.js +1 -1
- package/test/core-with-path-in-base.test.js +1 -1
- package/test/custom-undici-instance.test.js +2 -2
- package/test/disable-request-logging.test.js +3 -3
- package/test/fastify-multipart-incompatibility.test.js +2 -2
- package/test/fix-GHSA-v2v2-hph8-q5xp.test.js +52 -36
- package/test/full-delete-http2.test.js +2 -2
- package/test/full-get-test.test.js +1 -1
- package/test/full-https-get.test.js +1 -1
- package/test/full-post-extended-content-type.test.js +1 -1
- package/test/full-post-http2.test.js +1 -1
- package/test/full-post-stream-core.test.js +3 -3
- package/test/full-post-stream.test.js +3 -3
- package/test/full-post.test.js +2 -2
- package/test/full-querystring-rewrite-option-complex.test.js +1 -1
- package/test/full-querystring-rewrite-option-function-request.test.js +3 -3
- package/test/full-querystring-rewrite-option-function.test.js +1 -1
- package/test/full-querystring-rewrite-option.test.js +1 -1
- package/test/full-querystring-rewrite-string.test.js +1 -1
- package/test/full-querystring-rewrite.test.js +1 -1
- package/test/full-querystring.test.js +1 -1
- package/test/full-rewrite-body-content-type.test.js +10 -7
- package/test/full-rewrite-body-http.test.js +2 -2
- package/test/full-rewrite-body-to-empty-string.test.js +2 -2
- package/test/full-rewrite-body-to-null.test.js +2 -2
- package/test/full-rewrite-body.test.js +2 -2
- package/test/get-upstream-http.test.js +3 -3
- package/test/get-upstream-undici.test.js +1 -1
- package/test/get-with-body.test.js +1 -1
- package/test/head-with-body.test.js +1 -7
- package/test/host-header.test.js +4 -4
- package/test/http-agents.test.js +1 -1
- package/test/http-global-agent.test.js +1 -1
- package/test/http-http2.test.js +2 -2
- package/test/http-invalid-target.test.js +1 -1
- package/test/http-retry.test.js +3 -3
- package/test/http-timeout.test.js +4 -4
- package/test/http2-http2.test.js +2 -2
- package/test/http2-https.test.js +2 -2
- package/test/http2-invalid-target.test.js +1 -1
- package/test/http2-target-crash.test.js +2 -2
- package/test/http2-target-multi-crash.test.js +1 -1
- package/test/http2-timeout-disabled.test.js +2 -2
- package/test/http2-timeout.test.js +4 -4
- package/test/https-agents.test.js +1 -1
- package/test/https-global-agent.test.js +1 -1
- package/test/method.test.js +3 -3
- package/test/modifyCoreObjects-false.test.js +1 -1
- package/test/no-body-opts-with-get.test.js +2 -2
- package/test/no-body-opts-with-head.test.js +2 -2
- package/test/no-stream-body-option.test.js +2 -2
- package/test/on-error.test.js +2 -2
- package/test/on-invalid-upstream-response.test.js +1 -1
- package/test/padded-body.test.js +2 -2
- package/test/post-formbody.test.js +1 -1
- package/test/post-plain-text.test.js +1 -1
- package/test/post-with-custom-encoded-contenttype.test.js +2 -2
- package/test/post-with-octet-stream.test.js +5 -5
- package/test/retry-on-503.test.js +4 -4
- package/test/retry-with-a-custom-handler.test.js +7 -7
- package/test/rewrite-headers-type.test.js +2 -2
- package/test/rewrite-headers.test.js +3 -3
- package/test/rewrite-request-headers-type.test.js +2 -2
- package/test/rewrite-request-headers.test.js +2 -2
- package/test/transform-body.test.js +3 -3
- package/test/undici-agent.test.js +2 -2
- package/test/undici-body.test.js +3 -3
- package/test/undici-chaining.test.js +3 -3
- package/test/undici-connect-timeout.test.js +2 -2
- package/test/undici-custom-dispatcher.test.js +2 -2
- package/test/undici-global-agent.test.js +2 -2
- package/test/undici-no-destroy.test.js +1 -1
- package/test/undici-options.test.js +2 -2
- package/test/undici-proxy-agent.test.js +47 -28
- package/test/undici-retry.test.js +3 -3
- package/test/undici-timeout-body-partial.test.js +1 -1
- package/test/undici-timeout-body.test.js +1 -1
- package/test/undici-timeout.test.js +2 -2
- package/test/undici-with-path-in-base.test.js +1 -1
- package/test/undici.test.js +1 -1
- package/test/unexpected-error.test.js +2 -2
- package/test/unix-http-undici-from.test.js +3 -3
- package/test/unix-http-undici.test.js +1 -1
- package/test/unix-http.test.js +1 -1
- package/test/unix-https-undici.test.js +1 -1
- package/test/unix-https.test.js +1 -1
- package/types/index.d.ts +10 -11
- package/types/index.test-d.ts +138 -108
|
@@ -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('/', (
|
|
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('/', (
|
|
36
|
+
instance.get('/', (_request, reply) => {
|
|
37
37
|
reply.from()
|
|
38
38
|
})
|
|
39
39
|
|
package/test/undici.test.js
CHANGED
|
@@ -9,7 +9,7 @@ const proxyquire = require('proxyquire')
|
|
|
9
9
|
const From = proxyquire('..', {
|
|
10
10
|
'./lib/request': function () {
|
|
11
11
|
return {
|
|
12
|
-
request: (
|
|
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('/', (
|
|
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((
|
|
29
|
+
const target = http.createServer((_req, res) => {
|
|
30
30
|
t.fail('no response')
|
|
31
31
|
res.end()
|
|
32
32
|
})
|
|
33
33
|
|
|
34
|
-
instance.get('/', (
|
|
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
|
|
46
|
+
get(`http://localhost:${instance.server.address().port}`, (err, res) => {
|
|
47
47
|
t.error(err)
|
|
48
48
|
t.equal(res.statusCode, 500)
|
|
49
49
|
})
|
package/test/unix-http.test.js
CHANGED
package/test/unix-https.test.js
CHANGED
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
|
|
19
|
+
} from 'http'
|
|
20
20
|
import {
|
|
21
21
|
ClientSessionOptions,
|
|
22
22
|
ClientSessionRequestOptions,
|
|
23
23
|
IncomingHttpHeaders as Http2IncomingHttpHeaders,
|
|
24
24
|
SecureClientSessionOptions,
|
|
25
|
-
} from
|
|
25
|
+
} from 'http2'
|
|
26
26
|
import {
|
|
27
27
|
Agent as SecureAgent,
|
|
28
28
|
AgentOptions as SecureAgentOptions,
|
|
29
29
|
RequestOptions as SecureRequestOptions
|
|
30
|
-
} from
|
|
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
|
|
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
|
|
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
|
package/types/index.test-d.ts
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
|
-
import fastify, { FastifyReply, FastifyRequest, RawReplyDefaultExpression, RawServerBase, RequestGenericInterface, RouteGenericInterface } from
|
|
2
|
-
import * as http from 'http'
|
|
3
|
-
import { IncomingHttpHeaders } from
|
|
4
|
-
import * as https from 'https'
|
|
5
|
-
import { AddressInfo } from
|
|
6
|
-
import { expectType } from 'tsd'
|
|
7
|
-
import
|
|
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:
|
|
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(
|
|
68
|
-
|
|
69
|
-
})
|
|
70
|
-
server.get(
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
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(
|
|
98
|
-
|
|
99
|
-
})
|
|
100
|
-
|
|
101
|
-
instance.get(
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
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
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
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:
|
|
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()
|