@fastify/reply-from 8.2.1 → 8.3.1
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/workflows/ci.yml +1 -0
- package/.taprc +8 -2
- package/README.md +3 -4
- package/{example.js → examples/example.js} +1 -1
- package/index.js +16 -6
- package/lib/request.js +2 -6
- package/package.json +14 -14
- package/test/get-upstream-cache.js +72 -0
- package/test/http2-invalid-base.js +13 -0
- package/test/http2-unix-socket.js +16 -0
- package/test/post-with-octet-stream.js +131 -0
- package/test/utils-filter-pseudo-headers.js +18 -0
- package/types/index.d.ts +105 -0
- package/{test → types}/index.test-d.ts +2 -2
- package/index.d.ts +0 -100
package/.github/workflows/ci.yml
CHANGED
package/.taprc
CHANGED
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @fastify/reply-from
|
|
2
2
|
|
|
3
|
-
](https://github.com/fastify/reply-fro/actions/workflows/ci.yml)
|
|
4
4
|
[](https://www.npmjs.com/package/@fastify/reply-from)
|
|
5
5
|
[](https://standardjs.com/)
|
|
6
6
|
|
|
@@ -115,7 +115,7 @@ proxy.register(require('@fastify/reply-from'), {
|
|
|
115
115
|
|
|
116
116
|
#### `http`
|
|
117
117
|
|
|
118
|
-
Set the `http` option to
|
|
118
|
+
Set the `http` option to an Object to use
|
|
119
119
|
Node's [`http.request`](https://nodejs.org/api/http.html#http_http_request_options_callback)
|
|
120
120
|
will be used if you do not enable [`http2`](#http2). To customize the `request`,
|
|
121
121
|
you can pass in [`agentOptions`](https://nodejs.org/api/http.html#http_new_agent_options) and
|
|
@@ -203,8 +203,7 @@ This only applies when a custom [`body`](#body) is not passed in. Defaults to:
|
|
|
203
203
|
|
|
204
204
|
```js
|
|
205
205
|
[
|
|
206
|
-
'application/json'
|
|
207
|
-
'application/x-www-form-urlencoded'
|
|
206
|
+
'application/json'
|
|
208
207
|
]
|
|
209
208
|
```
|
|
210
209
|
|
package/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
const fp = require('fastify-plugin')
|
|
4
|
-
const lru = require('tiny-lru')
|
|
5
|
-
const querystring = require('querystring')
|
|
4
|
+
const { lru } = require('tiny-lru')
|
|
5
|
+
const querystring = require('fast-querystring')
|
|
6
6
|
const Stream = require('stream')
|
|
7
7
|
const buildRequest = require('./lib/request')
|
|
8
8
|
const {
|
|
@@ -21,7 +21,7 @@ const {
|
|
|
21
21
|
InternalServerError
|
|
22
22
|
} = require('./lib/errors')
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
const fastifyReplyFrom = fp(function from (fastify, opts, next) {
|
|
25
25
|
const contentTypesToEncode = new Set([
|
|
26
26
|
'application/json',
|
|
27
27
|
...(opts.contentTypesToEncode || [])
|
|
@@ -33,12 +33,17 @@ module.exports = fp(function from (fastify, opts, next) {
|
|
|
33
33
|
|
|
34
34
|
const cache = opts.disableCache ? undefined : lru(opts.cacheURLs || 100)
|
|
35
35
|
const base = opts.base
|
|
36
|
-
const
|
|
36
|
+
const requestBuilt = buildRequest({
|
|
37
37
|
http: opts.http,
|
|
38
38
|
http2: opts.http2,
|
|
39
39
|
base,
|
|
40
40
|
undici: opts.undici
|
|
41
41
|
})
|
|
42
|
+
if (requestBuilt instanceof Error) {
|
|
43
|
+
next(requestBuilt)
|
|
44
|
+
return
|
|
45
|
+
}
|
|
46
|
+
const { request, close, retryOnError } = requestBuilt
|
|
42
47
|
const disableRequestLogging = opts.disableRequestLogging || false
|
|
43
48
|
|
|
44
49
|
fastify.decorateReply('from', function (source, opts) {
|
|
@@ -60,8 +65,9 @@ module.exports = fp(function from (fastify, opts, next) {
|
|
|
60
65
|
const dest = getUpstream(req, base)
|
|
61
66
|
let url
|
|
62
67
|
if (cache) {
|
|
63
|
-
|
|
64
|
-
cache.
|
|
68
|
+
const cacheKey = dest + source
|
|
69
|
+
url = cache.get(cacheKey) || buildURL(source, dest)
|
|
70
|
+
cache.set(cacheKey, url)
|
|
65
71
|
} else {
|
|
66
72
|
url = buildURL(source, dest)
|
|
67
73
|
}
|
|
@@ -274,3 +280,7 @@ function createRequestRetry (requestImpl, reply, retriesCount, retryOnError, max
|
|
|
274
280
|
|
|
275
281
|
return requestRetry
|
|
276
282
|
}
|
|
283
|
+
|
|
284
|
+
module.exports = fastifyReplyFrom
|
|
285
|
+
module.exports.default = fastifyReplyFrom
|
|
286
|
+
module.exports.fastifyReplyFrom = fastifyReplyFrom
|
package/lib/request.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
'use strict'
|
|
2
|
-
const semver = require('semver')
|
|
3
2
|
const http = require('http')
|
|
4
3
|
const https = require('https')
|
|
5
4
|
const querystring = require('querystring')
|
|
@@ -48,12 +47,9 @@ function buildRequest (opts) {
|
|
|
48
47
|
let agents
|
|
49
48
|
|
|
50
49
|
if (isHttp2) {
|
|
51
|
-
if (
|
|
52
|
-
throw new Error('Http2 support requires Node version >= 9.0.0')
|
|
53
|
-
}
|
|
54
|
-
if (!opts.base) throw new Error('Option base is required when http2 is true')
|
|
50
|
+
if (!opts.base) return new Error('Option base is required when http2 is true')
|
|
55
51
|
if (opts.base.startsWith('unix+')) {
|
|
56
|
-
|
|
52
|
+
return new Error('Unix socket destination is not supported when http2 is true')
|
|
57
53
|
}
|
|
58
54
|
} else {
|
|
59
55
|
agents = httpOpts.agents || {
|
package/package.json
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fastify/reply-from",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.3.1",
|
|
4
4
|
"description": "forward your HTTP request to another server, for fastify",
|
|
5
5
|
"main": "index.js",
|
|
6
|
-
"types": "index.d.ts",
|
|
6
|
+
"types": "types/index.d.ts",
|
|
7
7
|
"scripts": {
|
|
8
|
-
"
|
|
8
|
+
"lint": "standard | snazzy",
|
|
9
9
|
"lint:fix": "standard --fix",
|
|
10
|
-
"test": "
|
|
11
|
-
"test:
|
|
12
|
-
"typescript": "tsd"
|
|
10
|
+
"test": "npm run test:unit && npm run test:typescript",
|
|
11
|
+
"test:unit": "tap",
|
|
12
|
+
"test:typescript": "tsd"
|
|
13
13
|
},
|
|
14
14
|
"repository": {
|
|
15
15
|
"type": "git",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"@fastify/formbody": "^7.0.1",
|
|
32
32
|
"@fastify/multipart": "^7.1.0",
|
|
33
33
|
"@fastify/pre-commit": "^2.0.2",
|
|
34
|
-
"@sinonjs/fake-timers": "^
|
|
34
|
+
"@sinonjs/fake-timers": "^10.0.0",
|
|
35
35
|
"@types/node": "^18.0.0",
|
|
36
36
|
"@types/tap": "^15.0.7",
|
|
37
37
|
"fastify": "^4.0.2",
|
|
@@ -46,21 +46,21 @@
|
|
|
46
46
|
"split2": "^4.1.0",
|
|
47
47
|
"standard": "^17.0.0",
|
|
48
48
|
"tap": "^16.2.0",
|
|
49
|
-
"tsd": "^0.
|
|
50
|
-
"typescript": "^4.7.3"
|
|
49
|
+
"tsd": "^0.24.1"
|
|
51
50
|
},
|
|
52
51
|
"dependencies": {
|
|
53
52
|
"@fastify/error": "^3.0.0",
|
|
54
53
|
"end-of-stream": "^1.4.4",
|
|
54
|
+
"fast-querystring": "^1.0.0",
|
|
55
55
|
"fastify-plugin": "^4.0.0",
|
|
56
56
|
"pump": "^3.0.0",
|
|
57
|
-
"
|
|
58
|
-
"tiny-lru": "^8.0.2",
|
|
57
|
+
"tiny-lru": "^10.0.0",
|
|
59
58
|
"undici": "^5.5.1"
|
|
60
59
|
},
|
|
61
|
-
"
|
|
62
|
-
"
|
|
63
|
-
|
|
60
|
+
"pre-commit": [
|
|
61
|
+
"lint",
|
|
62
|
+
"test"
|
|
63
|
+
],
|
|
64
64
|
"publishConfig": {
|
|
65
65
|
"access": "public"
|
|
66
66
|
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const t = require('tap')
|
|
4
|
+
const Fastify = require('fastify')
|
|
5
|
+
const From = require('..')
|
|
6
|
+
|
|
7
|
+
async function createTarget (i) {
|
|
8
|
+
const target = Fastify({
|
|
9
|
+
keepAliveTimeout: 1
|
|
10
|
+
})
|
|
11
|
+
|
|
12
|
+
target.get('/test', async () => {
|
|
13
|
+
return `Hello from target ${i}`
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
t.teardown(() => target.close())
|
|
17
|
+
await target.listen({ port: 3000 + i })
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
t.plan(4)
|
|
21
|
+
|
|
22
|
+
async function run () {
|
|
23
|
+
await Promise.all([
|
|
24
|
+
createTarget(1),
|
|
25
|
+
createTarget(2)
|
|
26
|
+
])
|
|
27
|
+
|
|
28
|
+
const instance = Fastify({
|
|
29
|
+
keepAliveTimeout: 1
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
instance.register(From, {
|
|
33
|
+
base: 'http://localhost',
|
|
34
|
+
http: true
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
instance.get('/', (req, reply) => {
|
|
38
|
+
const hostNumber = parseInt(req.headers['x-host-number'])
|
|
39
|
+
const port = 3000 + hostNumber
|
|
40
|
+
|
|
41
|
+
reply.from('/test', {
|
|
42
|
+
getUpstream () {
|
|
43
|
+
return `http://localhost:${port}`
|
|
44
|
+
}
|
|
45
|
+
})
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
t.teardown(() => instance.close())
|
|
49
|
+
await instance.listen({ port: 3000 })
|
|
50
|
+
|
|
51
|
+
const res1 = await instance.inject({
|
|
52
|
+
method: 'GET',
|
|
53
|
+
url: '/',
|
|
54
|
+
headers: {
|
|
55
|
+
'x-host-number': 1
|
|
56
|
+
}
|
|
57
|
+
})
|
|
58
|
+
t.equal(res1.statusCode, 200)
|
|
59
|
+
t.equal(res1.body, 'Hello from target 1')
|
|
60
|
+
|
|
61
|
+
const res2 = await instance.inject({
|
|
62
|
+
method: 'GET',
|
|
63
|
+
url: '/',
|
|
64
|
+
headers: {
|
|
65
|
+
'x-host-number': 2
|
|
66
|
+
}
|
|
67
|
+
})
|
|
68
|
+
t.equal(res2.statusCode, 200)
|
|
69
|
+
t.equal(res2.body, 'Hello from target 2')
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
run()
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { test } = require('tap')
|
|
4
|
+
const Fastify = require('fastify')
|
|
5
|
+
const From = require('../index')
|
|
6
|
+
|
|
7
|
+
test('http2 invalid base', async (t) => {
|
|
8
|
+
const instance = Fastify()
|
|
9
|
+
|
|
10
|
+
await t.rejects(instance.register(From, {
|
|
11
|
+
http2: { requestTimeout: 100 }
|
|
12
|
+
}), new Error('Option base is required when http2 is true'))
|
|
13
|
+
})
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { test } = require('tap')
|
|
4
|
+
const Fastify = require('fastify')
|
|
5
|
+
const From = require('../index')
|
|
6
|
+
|
|
7
|
+
test('throw an error if http2 is used with a Unix socket destination', async t => {
|
|
8
|
+
t.plan(1)
|
|
9
|
+
|
|
10
|
+
const instance = Fastify()
|
|
11
|
+
|
|
12
|
+
await t.rejects(instance.register(From, {
|
|
13
|
+
base: 'unix+http://localhost:1337',
|
|
14
|
+
http2: { requestTimeout: 100 }
|
|
15
|
+
}), new Error('Unix socket destination is not supported when http2 is true'))
|
|
16
|
+
})
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const test = require('tap').test
|
|
4
|
+
const Fastify = require('fastify')
|
|
5
|
+
const From = require('../index')
|
|
6
|
+
const http = require('http')
|
|
7
|
+
const get = require('simple-get').concat
|
|
8
|
+
const { parse } = require('querystring')
|
|
9
|
+
|
|
10
|
+
test('with explicitly set content-type application/octet-stream', t => {
|
|
11
|
+
const instance = Fastify()
|
|
12
|
+
instance.register(From, {
|
|
13
|
+
contentTypesToEncode: ['application/octet-stream']
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
instance.addContentTypeParser(
|
|
17
|
+
'application/octet-stream',
|
|
18
|
+
{ parseAs: 'buffer', bodyLimit: 1000 },
|
|
19
|
+
(req, body, done) => done(null, parse(body.toString()))
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
t.plan(9)
|
|
23
|
+
t.teardown(instance.close.bind(instance))
|
|
24
|
+
|
|
25
|
+
const target = http.createServer((req, res) => {
|
|
26
|
+
t.pass('request proxied')
|
|
27
|
+
t.equal(req.method, 'POST')
|
|
28
|
+
t.equal(req.headers['content-type'], 'application/octet-stream')
|
|
29
|
+
let data = ''
|
|
30
|
+
req.setEncoding('utf8')
|
|
31
|
+
req.on('data', (d) => {
|
|
32
|
+
data += d
|
|
33
|
+
})
|
|
34
|
+
req.on('end', () => {
|
|
35
|
+
const str = data.toString()
|
|
36
|
+
t.same(JSON.parse(data), { some: 'info', another: 'detail' })
|
|
37
|
+
res.statusCode = 200
|
|
38
|
+
res.setHeader('content-type', 'application/octet-stream')
|
|
39
|
+
res.end(str)
|
|
40
|
+
})
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
instance.post('/', (request, reply) => {
|
|
44
|
+
reply.from(`http://localhost:${target.address().port}`)
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
t.teardown(target.close.bind(target))
|
|
48
|
+
|
|
49
|
+
instance.listen({ port: 0 }, (err) => {
|
|
50
|
+
t.error(err)
|
|
51
|
+
|
|
52
|
+
target.listen({ port: 0 }, (err) => {
|
|
53
|
+
t.error(err)
|
|
54
|
+
|
|
55
|
+
get({
|
|
56
|
+
url: `http://localhost:${instance.server.address().port}`,
|
|
57
|
+
method: 'POST',
|
|
58
|
+
headers: { 'content-type': 'application/octet-stream' },
|
|
59
|
+
body: 'some=info&another=detail'
|
|
60
|
+
}, (err, res, data) => {
|
|
61
|
+
t.error(err)
|
|
62
|
+
t.equal(res.headers['content-type'], 'application/octet-stream')
|
|
63
|
+
t.same(JSON.parse(data), { some: 'info', another: 'detail' })
|
|
64
|
+
})
|
|
65
|
+
})
|
|
66
|
+
})
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
test('with implicit content-type application/octet-stream', t => {
|
|
70
|
+
const instance = Fastify()
|
|
71
|
+
instance.register(From, {
|
|
72
|
+
contentTypesToEncode: ['application/octet-stream']
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
instance.addContentTypeParser(
|
|
76
|
+
'application/octet-stream',
|
|
77
|
+
{ parseAs: 'buffer', bodyLimit: 1000 },
|
|
78
|
+
(req, body, done) => done(null, parse(body.toString()))
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
instance.addContentTypeParser(
|
|
82
|
+
'*',
|
|
83
|
+
{ parseAs: 'buffer', bodyLimit: 1000 },
|
|
84
|
+
(req, body, done) => done(null, parse(body.toString()))
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
t.plan(9)
|
|
88
|
+
t.teardown(instance.close.bind(instance))
|
|
89
|
+
|
|
90
|
+
const target = http.createServer((req, res) => {
|
|
91
|
+
t.pass('request proxied')
|
|
92
|
+
t.equal(req.method, 'POST')
|
|
93
|
+
t.equal(req.headers['content-type'], 'application/octet-stream')
|
|
94
|
+
let data = ''
|
|
95
|
+
req.setEncoding('utf8')
|
|
96
|
+
req.on('data', (d) => {
|
|
97
|
+
data += d
|
|
98
|
+
})
|
|
99
|
+
req.on('end', () => {
|
|
100
|
+
const str = data.toString()
|
|
101
|
+
t.same(JSON.parse(data), { some: 'info', another: 'detail' })
|
|
102
|
+
res.statusCode = 200
|
|
103
|
+
res.setHeader('content-type', 'application/octet-stream')
|
|
104
|
+
res.end(str)
|
|
105
|
+
})
|
|
106
|
+
})
|
|
107
|
+
|
|
108
|
+
instance.post('/', (request, reply) => {
|
|
109
|
+
reply.from(`http://localhost:${target.address().port}`)
|
|
110
|
+
})
|
|
111
|
+
|
|
112
|
+
t.teardown(target.close.bind(target))
|
|
113
|
+
|
|
114
|
+
instance.listen({ port: 0 }, (err) => {
|
|
115
|
+
t.error(err)
|
|
116
|
+
|
|
117
|
+
target.listen({ port: 0 }, (err) => {
|
|
118
|
+
t.error(err)
|
|
119
|
+
|
|
120
|
+
get({
|
|
121
|
+
url: `http://localhost:${instance.server.address().port}`,
|
|
122
|
+
method: 'POST',
|
|
123
|
+
body: 'some=info&another=detail'
|
|
124
|
+
}, (err, res, data) => {
|
|
125
|
+
t.error(err)
|
|
126
|
+
t.equal(res.headers['content-type'], 'application/octet-stream')
|
|
127
|
+
t.same(JSON.parse(data), { some: 'info', another: 'detail' })
|
|
128
|
+
})
|
|
129
|
+
})
|
|
130
|
+
})
|
|
131
|
+
})
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const test = require('tap').test
|
|
4
|
+
const filterPseudoHeaders = require('../lib/utils').filterPseudoHeaders
|
|
5
|
+
|
|
6
|
+
test('filterPseudoHeaders', t => {
|
|
7
|
+
t.plan(1)
|
|
8
|
+
const headers = {
|
|
9
|
+
accept: '*/*',
|
|
10
|
+
'Content-Type': 'text/html; charset=UTF-8',
|
|
11
|
+
':method': 'GET'
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
t.strictSame(filterPseudoHeaders(headers), {
|
|
15
|
+
accept: '*/*',
|
|
16
|
+
'content-type': 'text/html; charset=UTF-8'
|
|
17
|
+
})
|
|
18
|
+
})
|
package/types/index.d.ts
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
FastifyRequest,
|
|
5
|
+
FastifyReply,
|
|
6
|
+
RawReplyDefaultExpression,
|
|
7
|
+
RawServerBase,
|
|
8
|
+
RequestGenericInterface,
|
|
9
|
+
HTTPMethods,
|
|
10
|
+
FastifyPluginCallback,
|
|
11
|
+
} from 'fastify';
|
|
12
|
+
|
|
13
|
+
import {
|
|
14
|
+
IncomingMessage,
|
|
15
|
+
IncomingHttpHeaders,
|
|
16
|
+
RequestOptions,
|
|
17
|
+
AgentOptions,
|
|
18
|
+
Agent,
|
|
19
|
+
} from "http";
|
|
20
|
+
import {
|
|
21
|
+
RequestOptions as SecureRequestOptions,
|
|
22
|
+
AgentOptions as SecureAgentOptions,
|
|
23
|
+
Agent as SecureAgent
|
|
24
|
+
} from "https";
|
|
25
|
+
import {
|
|
26
|
+
Http2ServerRequest,
|
|
27
|
+
IncomingHttpHeaders as Http2IncomingHttpHeaders,
|
|
28
|
+
ClientSessionRequestOptions,
|
|
29
|
+
ClientSessionOptions,
|
|
30
|
+
SecureClientSessionOptions,
|
|
31
|
+
} from "http2";
|
|
32
|
+
import { Pool } from 'undici'
|
|
33
|
+
|
|
34
|
+
declare module "fastify" {
|
|
35
|
+
interface FastifyReply {
|
|
36
|
+
from(
|
|
37
|
+
source?: string,
|
|
38
|
+
opts?: fastifyReplyFrom.FastifyReplyFromHooks
|
|
39
|
+
): this;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
type FastifyReplyFrom = FastifyPluginCallback<fastifyReplyFrom.FastifyReplyFromOptions>
|
|
44
|
+
|
|
45
|
+
declare namespace fastifyReplyFrom {
|
|
46
|
+
type QueryStringFunction = (search: string | undefined, reqUrl: string) => string;
|
|
47
|
+
export interface FastifyReplyFromHooks {
|
|
48
|
+
queryString?: { [key: string]: unknown } | QueryStringFunction;
|
|
49
|
+
contentType?: string;
|
|
50
|
+
onResponse?: (
|
|
51
|
+
request: FastifyRequest<RequestGenericInterface, RawServerBase>,
|
|
52
|
+
reply: FastifyReply<RawServerBase>,
|
|
53
|
+
res: RawReplyDefaultExpression<RawServerBase>
|
|
54
|
+
) => void;
|
|
55
|
+
onError?: (
|
|
56
|
+
reply: FastifyReply<RawServerBase>,
|
|
57
|
+
error: { error: Error }
|
|
58
|
+
) => void;
|
|
59
|
+
body?: unknown;
|
|
60
|
+
rewriteHeaders?: (
|
|
61
|
+
headers: Http2IncomingHttpHeaders | IncomingHttpHeaders,
|
|
62
|
+
req?: Http2ServerRequest | IncomingMessage
|
|
63
|
+
) => Http2IncomingHttpHeaders | IncomingHttpHeaders;
|
|
64
|
+
rewriteRequestHeaders?: (
|
|
65
|
+
req: Http2ServerRequest | IncomingMessage,
|
|
66
|
+
headers: Http2IncomingHttpHeaders | IncomingHttpHeaders
|
|
67
|
+
) => Http2IncomingHttpHeaders | IncomingHttpHeaders;
|
|
68
|
+
getUpstream?: (
|
|
69
|
+
req: Http2ServerRequest | IncomingMessage,
|
|
70
|
+
base: string
|
|
71
|
+
) => string;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
interface Http2Options {
|
|
75
|
+
sessionTimeout?: number;
|
|
76
|
+
requestTimeout?: number;
|
|
77
|
+
sessionOptions?: ClientSessionOptions | SecureClientSessionOptions;
|
|
78
|
+
requestOptions?: ClientSessionRequestOptions;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
interface HttpOptions {
|
|
82
|
+
agentOptions?: AgentOptions | SecureAgentOptions;
|
|
83
|
+
requestOptions?: RequestOptions | SecureRequestOptions;
|
|
84
|
+
agents?: { 'http:': Agent, 'https:': SecureAgent }
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export interface FastifyReplyFromOptions {
|
|
88
|
+
base?: string;
|
|
89
|
+
cacheURLs?: number;
|
|
90
|
+
disableCache?: boolean;
|
|
91
|
+
http?: HttpOptions;
|
|
92
|
+
http2?: Http2Options | boolean;
|
|
93
|
+
undici?: Pool.Options;
|
|
94
|
+
contentTypesToEncode?: string[];
|
|
95
|
+
retryMethods?: (HTTPMethods | 'TRACE')[];
|
|
96
|
+
maxRetriesOn503?: number;
|
|
97
|
+
disableRequestLogging?: boolean;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export const fastifyReplyFrom: FastifyReplyFrom
|
|
101
|
+
export { fastifyReplyFrom as default }
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
declare function fastifyReplyFrom(...params: Parameters<FastifyReplyFrom>): ReturnType<FastifyReplyFrom>
|
|
105
|
+
export = fastifyReplyFrom
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import replyFrom, { FastifyReplyFromOptions } from "
|
|
1
|
+
import replyFrom, { FastifyReplyFromOptions } from "..";
|
|
2
2
|
import fastify, {FastifyReply, RawServerBase} from "fastify";
|
|
3
3
|
import { AddressInfo } from "net";
|
|
4
4
|
import { IncomingHttpHeaders } from "http2";
|
|
@@ -60,7 +60,7 @@ async function main() {
|
|
|
60
60
|
server.register(replyFrom, fullOptions);
|
|
61
61
|
|
|
62
62
|
server.get("/v1", (request, reply) => {
|
|
63
|
-
reply.from();
|
|
63
|
+
expectType<FastifyReply>(reply.from());
|
|
64
64
|
});
|
|
65
65
|
server.get("/v3", (request, reply) => {
|
|
66
66
|
reply.from("/v3", {
|
package/index.d.ts
DELETED
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
/// <reference types="node" />
|
|
2
|
-
|
|
3
|
-
import {
|
|
4
|
-
FastifyRequest,
|
|
5
|
-
FastifyReply,
|
|
6
|
-
RawReplyDefaultExpression,
|
|
7
|
-
RawServerBase,
|
|
8
|
-
RequestGenericInterface,
|
|
9
|
-
HTTPMethods,
|
|
10
|
-
FastifyPluginAsync,
|
|
11
|
-
FastifyPluginCallback,
|
|
12
|
-
} from 'fastify';
|
|
13
|
-
|
|
14
|
-
import {
|
|
15
|
-
IncomingMessage,
|
|
16
|
-
IncomingHttpHeaders,
|
|
17
|
-
RequestOptions,
|
|
18
|
-
AgentOptions,
|
|
19
|
-
Agent,
|
|
20
|
-
} from "http";
|
|
21
|
-
import {
|
|
22
|
-
RequestOptions as SecureRequestOptions,
|
|
23
|
-
AgentOptions as SecureAgentOptions,
|
|
24
|
-
Agent as SecureAgent
|
|
25
|
-
} from "https";
|
|
26
|
-
import {
|
|
27
|
-
Http2ServerRequest,
|
|
28
|
-
IncomingHttpHeaders as Http2IncomingHttpHeaders,
|
|
29
|
-
ClientSessionRequestOptions,
|
|
30
|
-
ClientSessionOptions,
|
|
31
|
-
SecureClientSessionOptions,
|
|
32
|
-
} from "http2";
|
|
33
|
-
import { Pool } from 'undici'
|
|
34
|
-
type QueryStringFunction = (search: string | undefined, reqUrl: string) => string;
|
|
35
|
-
export interface FastifyReplyFromHooks {
|
|
36
|
-
queryString?: { [key: string]: unknown } | QueryStringFunction;
|
|
37
|
-
contentType?: string;
|
|
38
|
-
onResponse?: (
|
|
39
|
-
request: FastifyRequest<RequestGenericInterface, RawServerBase>,
|
|
40
|
-
reply: FastifyReply<RawServerBase>,
|
|
41
|
-
res: RawReplyDefaultExpression<RawServerBase>
|
|
42
|
-
) => void;
|
|
43
|
-
onError?: (
|
|
44
|
-
reply: FastifyReply<RawServerBase>,
|
|
45
|
-
error: { error: Error }
|
|
46
|
-
) => void;
|
|
47
|
-
body?: unknown;
|
|
48
|
-
rewriteHeaders?: (
|
|
49
|
-
headers: Http2IncomingHttpHeaders | IncomingHttpHeaders,
|
|
50
|
-
req?: Http2ServerRequest | IncomingMessage
|
|
51
|
-
) => Http2IncomingHttpHeaders | IncomingHttpHeaders;
|
|
52
|
-
rewriteRequestHeaders?: (
|
|
53
|
-
req: Http2ServerRequest | IncomingMessage,
|
|
54
|
-
headers: Http2IncomingHttpHeaders | IncomingHttpHeaders
|
|
55
|
-
) => Http2IncomingHttpHeaders | IncomingHttpHeaders;
|
|
56
|
-
getUpstream?: (
|
|
57
|
-
req: Http2ServerRequest | IncomingMessage,
|
|
58
|
-
base: string
|
|
59
|
-
) => string;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
declare module "fastify" {
|
|
63
|
-
interface FastifyReply {
|
|
64
|
-
from(
|
|
65
|
-
source?: string,
|
|
66
|
-
opts?: FastifyReplyFromHooks
|
|
67
|
-
): void;
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
interface Http2Options {
|
|
72
|
-
sessionTimeout?: number;
|
|
73
|
-
requestTimeout?: number;
|
|
74
|
-
sessionOptions?: ClientSessionOptions | SecureClientSessionOptions;
|
|
75
|
-
requestOptions?: ClientSessionRequestOptions;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
interface HttpOptions {
|
|
79
|
-
agentOptions?: AgentOptions | SecureAgentOptions;
|
|
80
|
-
requestOptions?: RequestOptions | SecureRequestOptions;
|
|
81
|
-
agents?: { 'http:': Agent, 'https:': SecureAgent }
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
export interface FastifyReplyFromOptions {
|
|
85
|
-
base?: string;
|
|
86
|
-
cacheURLs?: number;
|
|
87
|
-
disableCache?: boolean;
|
|
88
|
-
http?: HttpOptions;
|
|
89
|
-
http2?: Http2Options | boolean;
|
|
90
|
-
undici?: Pool.Options;
|
|
91
|
-
contentTypesToEncode?: string[];
|
|
92
|
-
retryMethods?: (HTTPMethods | 'TRACE')[];
|
|
93
|
-
maxRetriesOn503?: number;
|
|
94
|
-
disableRequestLogging?: boolean;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
declare const fastifyReplyFrom:
|
|
98
|
-
| FastifyPluginCallback<FastifyReplyFromOptions>
|
|
99
|
-
| FastifyPluginAsync<FastifyReplyFromOptions>;
|
|
100
|
-
export default fastifyReplyFrom;
|