@fastify/static 6.12.0 → 7.0.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/README.md +3 -3
- package/index.js +15 -23
- package/lib/dirList.js +56 -54
- package/package.json +6 -6
- package/test/static.test.js +90 -0
- package/types/index.d.ts +9 -2
- package/types/index.test-d.ts +11 -3
package/README.md
CHANGED
|
@@ -124,7 +124,7 @@ A URL path prefix used to create a virtual mount path for the static directory.
|
|
|
124
124
|
Default: `{}`
|
|
125
125
|
|
|
126
126
|
Constraints that will be added to registered routes. See Fastify's documentation for
|
|
127
|
-
[route constraints](https://
|
|
127
|
+
[route constraints](https://fastify.dev/docs/latest/Reference/Routes/#constraints).
|
|
128
128
|
|
|
129
129
|
#### `prefixAvoidTrailingSlash`
|
|
130
130
|
|
|
@@ -450,7 +450,7 @@ decorators.
|
|
|
450
450
|
|
|
451
451
|
If a request matches the URL `prefix` but a file cannot be found for the
|
|
452
452
|
request, Fastify's 404 handler will be called. You can set a custom 404
|
|
453
|
-
handler with [`fastify.setNotFoundHandler()`](https://
|
|
453
|
+
handler with [`fastify.setNotFoundHandler()`](https://fastify.dev/docs/latest/Reference/Server/#setnotfoundhandler).
|
|
454
454
|
|
|
455
455
|
When registering `@fastify/static` within an encapsulated context, the `wildcard` option may need to be set to `false` in order to support index resolution and nested not-found-handler:
|
|
456
456
|
|
|
@@ -475,7 +475,7 @@ This code will send the `index.html` for the paths `docs`, `docs/`, and `docs/in
|
|
|
475
475
|
|
|
476
476
|
If an error occurs while trying to send a file, the error will be passed
|
|
477
477
|
to Fastify's error handler. You can set a custom error handler with
|
|
478
|
-
[`fastify.setErrorHandler()`](https://
|
|
478
|
+
[`fastify.setErrorHandler()`](https://fastify.dev/docs/latest/Reference/Server/#seterrorhandler).
|
|
479
479
|
|
|
480
480
|
### Payload `stream.filename`
|
|
481
481
|
|
package/index.js
CHANGED
|
@@ -4,9 +4,7 @@ const { PassThrough } = require('node:stream')
|
|
|
4
4
|
const path = require('node:path')
|
|
5
5
|
const { fileURLToPath } = require('node:url')
|
|
6
6
|
const { statSync } = require('node:fs')
|
|
7
|
-
const {
|
|
8
|
-
const glob = require('glob')
|
|
9
|
-
const globPromise = promisify(glob)
|
|
7
|
+
const { glob } = require('glob')
|
|
10
8
|
const fp = require('fastify-plugin')
|
|
11
9
|
const send = require('@fastify/send')
|
|
12
10
|
const encodingNegotiator = require('@fastify/accept-negotiator')
|
|
@@ -14,11 +12,7 @@ const contentDisposition = require('content-disposition')
|
|
|
14
12
|
|
|
15
13
|
const dirList = require('./lib/dirList')
|
|
16
14
|
|
|
17
|
-
const winSeparatorRegex = new RegExp(`\\${path.win32.sep}`, 'gu')
|
|
18
|
-
const backslashRegex = /\\/gu
|
|
19
|
-
const startForwardSlashRegex = /^\//u
|
|
20
15
|
const endForwardSlashRegex = /\/$/u
|
|
21
|
-
const doubleForwardSlashRegex = /\/\//gu
|
|
22
16
|
const asteriskRegex = /\*/gu
|
|
23
17
|
|
|
24
18
|
const supportedEncodings = ['br', 'gzip', 'deflate']
|
|
@@ -117,32 +111,30 @@ async function fastifyStatic (fastify, opts) {
|
|
|
117
111
|
throw new Error('"wildcard" option must be a boolean')
|
|
118
112
|
}
|
|
119
113
|
if (opts.wildcard === undefined || opts.wildcard === true) {
|
|
120
|
-
fastify.
|
|
121
|
-
pumpSendToReply(req, reply, '/' + req.params['*'], sendOptions.root)
|
|
122
|
-
})
|
|
123
|
-
fastify.get(prefix + '*', routeOpts, function (req, reply) {
|
|
114
|
+
fastify.get(prefix + '*', { ...routeOpts, exposeHeadRoute: true }, (req, reply) => {
|
|
124
115
|
pumpSendToReply(req, reply, '/' + req.params['*'], sendOptions.root)
|
|
125
116
|
})
|
|
126
117
|
if (opts.redirect === true && prefix !== opts.prefix) {
|
|
127
|
-
fastify.get(opts.prefix, routeOpts,
|
|
118
|
+
fastify.get(opts.prefix, routeOpts, (req, reply) => {
|
|
128
119
|
reply.redirect(301, getRedirectUrl(req.raw.url))
|
|
129
120
|
})
|
|
130
121
|
}
|
|
131
122
|
} else {
|
|
132
|
-
const
|
|
123
|
+
const indexes = opts.index === undefined ? ['index.html'] : [].concat(opts.index)
|
|
133
124
|
const indexDirs = new Map()
|
|
134
125
|
const routes = new Set()
|
|
135
126
|
|
|
136
127
|
const roots = Array.isArray(sendOptions.root) ? sendOptions.root : [sendOptions.root]
|
|
137
|
-
for (let
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
const
|
|
128
|
+
for (let rootPath of roots) {
|
|
129
|
+
rootPath = rootPath.split(path.win32.sep).join(path.posix.sep)
|
|
130
|
+
!rootPath.endsWith('/') && (rootPath += '/')
|
|
131
|
+
const files = await glob('**/**', {
|
|
132
|
+
cwd: rootPath, absolute: false, follow: true, nodir: true, dot: opts.serveDotFiles
|
|
133
|
+
})
|
|
141
134
|
|
|
142
|
-
for (let
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
const route = (prefix + file).replace(doubleForwardSlashRegex, '/')
|
|
135
|
+
for (let file of files) {
|
|
136
|
+
file = file.split(path.win32.sep).join(path.posix.sep)
|
|
137
|
+
const route = prefix + file
|
|
146
138
|
|
|
147
139
|
if (routes.has(route)) {
|
|
148
140
|
continue
|
|
@@ -150,7 +142,7 @@ async function fastifyStatic (fastify, opts) {
|
|
|
150
142
|
|
|
151
143
|
routes.add(route)
|
|
152
144
|
|
|
153
|
-
setUpHeadAndGet(routeOpts, route,
|
|
145
|
+
setUpHeadAndGet(routeOpts, route, `/${file}`, rootPath)
|
|
154
146
|
|
|
155
147
|
const key = path.posix.basename(route)
|
|
156
148
|
if (indexes.includes(key) && !indexDirs.has(key)) {
|
|
@@ -179,7 +171,7 @@ async function fastifyStatic (fastify, opts) {
|
|
|
179
171
|
pathname,
|
|
180
172
|
rootPath,
|
|
181
173
|
rootPathOffset = 0,
|
|
182
|
-
pumpOptions
|
|
174
|
+
pumpOptions,
|
|
183
175
|
checkedEncodings
|
|
184
176
|
) {
|
|
185
177
|
const options = Object.assign({}, sendOptions, pumpOptions)
|
package/lib/dirList.js
CHANGED
|
@@ -1,10 +1,60 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
+
const os = require('node:os')
|
|
3
4
|
const path = require('node:path')
|
|
4
5
|
const fs = require('node:fs/promises')
|
|
5
|
-
const
|
|
6
|
+
const fastq = require('fastq')
|
|
7
|
+
const fastqConcurrency = Math.max(1, os.cpus().length - 1)
|
|
6
8
|
|
|
7
9
|
const dirList = {
|
|
10
|
+
_getExtendedInfo: async function (dir, info) {
|
|
11
|
+
const depth = dir.split(path.sep).length
|
|
12
|
+
const files = await fs.readdir(dir)
|
|
13
|
+
|
|
14
|
+
const worker = async (filename) => {
|
|
15
|
+
const filePath = path.join(dir, filename)
|
|
16
|
+
let stats
|
|
17
|
+
try {
|
|
18
|
+
stats = await fs.stat(filePath)
|
|
19
|
+
} catch {
|
|
20
|
+
return
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if (stats.isDirectory()) {
|
|
24
|
+
info.totalFolderCount++
|
|
25
|
+
filePath.split(path.sep).length === depth + 1 && info.folderCount++
|
|
26
|
+
await dirList._getExtendedInfo(filePath, info)
|
|
27
|
+
} else {
|
|
28
|
+
info.totalSize += stats.size
|
|
29
|
+
info.totalFileCount++
|
|
30
|
+
filePath.split(path.sep).length === depth + 1 && info.fileCount++
|
|
31
|
+
info.lastModified = Math.max(info.lastModified, stats.mtimeMs)
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
const queue = fastq.promise(worker, fastqConcurrency)
|
|
35
|
+
await Promise.all(files.map(filename => queue.push(filename)))
|
|
36
|
+
},
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* get extended info about a folder
|
|
40
|
+
* @param {string} folderPath full path fs dir
|
|
41
|
+
* @return {Promise<ExtendedInfo>}
|
|
42
|
+
*/
|
|
43
|
+
getExtendedInfo: async function (folderPath) {
|
|
44
|
+
const info = {
|
|
45
|
+
totalSize: 0,
|
|
46
|
+
fileCount: 0,
|
|
47
|
+
totalFileCount: 0,
|
|
48
|
+
folderCount: 0,
|
|
49
|
+
totalFolderCount: 0,
|
|
50
|
+
lastModified: 0
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
await dirList._getExtendedInfo(folderPath, info)
|
|
54
|
+
|
|
55
|
+
return info
|
|
56
|
+
},
|
|
57
|
+
|
|
8
58
|
/**
|
|
9
59
|
* get files and dirs from dir, or error
|
|
10
60
|
* @param {string} dir full path fs dir
|
|
@@ -22,8 +72,7 @@ const dirList = {
|
|
|
22
72
|
return entries
|
|
23
73
|
}
|
|
24
74
|
|
|
25
|
-
const
|
|
26
|
-
await Promise.all(files.map(filename => limit(async () => {
|
|
75
|
+
const worker = async (filename) => {
|
|
27
76
|
let stats
|
|
28
77
|
try {
|
|
29
78
|
stats = await fs.stat(path.join(dir, filename))
|
|
@@ -33,62 +82,15 @@ const dirList = {
|
|
|
33
82
|
const entry = { name: filename, stats }
|
|
34
83
|
if (stats.isDirectory()) {
|
|
35
84
|
if (options.extendedFolderInfo) {
|
|
36
|
-
entry.extendedInfo = await getExtendedInfo(path.join(dir, filename))
|
|
85
|
+
entry.extendedInfo = await dirList.getExtendedInfo(path.join(dir, filename))
|
|
37
86
|
}
|
|
38
87
|
entries.dirs.push(entry)
|
|
39
88
|
} else {
|
|
40
89
|
entries.files.push(entry)
|
|
41
90
|
}
|
|
42
|
-
})))
|
|
43
|
-
|
|
44
|
-
async function getExtendedInfo (folderPath) {
|
|
45
|
-
const depth = folderPath.split(path.sep).length
|
|
46
|
-
let totalSize = 0
|
|
47
|
-
let fileCount = 0
|
|
48
|
-
let totalFileCount = 0
|
|
49
|
-
let folderCount = 0
|
|
50
|
-
let totalFolderCount = 0
|
|
51
|
-
let lastModified = 0
|
|
52
|
-
|
|
53
|
-
async function walk (dir) {
|
|
54
|
-
const files = await fs.readdir(dir)
|
|
55
|
-
const limit = pLimit(4)
|
|
56
|
-
await Promise.all(files.map(filename => limit(async () => {
|
|
57
|
-
const filePath = path.join(dir, filename)
|
|
58
|
-
let stats
|
|
59
|
-
try {
|
|
60
|
-
stats = await fs.stat(filePath)
|
|
61
|
-
} catch {
|
|
62
|
-
return
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
if (stats.isDirectory()) {
|
|
66
|
-
totalFolderCount++
|
|
67
|
-
if (filePath.split(path.sep).length === depth + 1) {
|
|
68
|
-
folderCount++
|
|
69
|
-
}
|
|
70
|
-
await walk(filePath)
|
|
71
|
-
} else {
|
|
72
|
-
totalSize += stats.size
|
|
73
|
-
totalFileCount++
|
|
74
|
-
if (filePath.split(path.sep).length === depth + 1) {
|
|
75
|
-
fileCount++
|
|
76
|
-
}
|
|
77
|
-
lastModified = Math.max(lastModified, stats.mtimeMs)
|
|
78
|
-
}
|
|
79
|
-
})))
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
await walk(folderPath)
|
|
83
|
-
return {
|
|
84
|
-
totalSize,
|
|
85
|
-
fileCount,
|
|
86
|
-
totalFileCount,
|
|
87
|
-
folderCount,
|
|
88
|
-
totalFolderCount,
|
|
89
|
-
lastModified
|
|
90
|
-
}
|
|
91
91
|
}
|
|
92
|
+
const queue = fastq.promise(worker, fastqConcurrency)
|
|
93
|
+
await Promise.all(files.map(filename => queue.push(filename)))
|
|
92
94
|
|
|
93
95
|
entries.dirs.sort((a, b) => a.name.localeCompare(b.name))
|
|
94
96
|
entries.files.sort((a, b) => a.name.localeCompare(b.name))
|
|
@@ -115,6 +117,7 @@ const dirList = {
|
|
|
115
117
|
} catch {
|
|
116
118
|
return reply.callNotFound()
|
|
117
119
|
}
|
|
120
|
+
|
|
118
121
|
const format = reply.request.query.format || options.format
|
|
119
122
|
if (format !== 'html') {
|
|
120
123
|
if (options.jsonFormat !== 'extended') {
|
|
@@ -203,7 +206,6 @@ const dirList = {
|
|
|
203
206
|
return new TypeError('The `list.render` option must be a function and is required with html format')
|
|
204
207
|
}
|
|
205
208
|
}
|
|
206
|
-
|
|
207
209
|
}
|
|
208
210
|
|
|
209
211
|
module.exports = dirList
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fastify/static",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "7.0.1",
|
|
4
4
|
"description": "Plugin for serving static files as fast as possible.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "commonjs",
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
},
|
|
19
19
|
"repository": {
|
|
20
20
|
"type": "git",
|
|
21
|
-
"url": "https://github.com/fastify/fastify-static.git"
|
|
21
|
+
"url": "git+https://github.com/fastify/fastify-static.git"
|
|
22
22
|
},
|
|
23
23
|
"keywords": [
|
|
24
24
|
"fastify",
|
|
@@ -35,11 +35,11 @@
|
|
|
35
35
|
"@fastify/send": "^2.0.0",
|
|
36
36
|
"content-disposition": "^0.5.3",
|
|
37
37
|
"fastify-plugin": "^4.0.0",
|
|
38
|
-
"
|
|
39
|
-
"
|
|
38
|
+
"fastq": "^1.17.0",
|
|
39
|
+
"glob": "^10.3.4"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
|
-
"@fastify/compress": "^
|
|
42
|
+
"@fastify/compress": "^7.0.0",
|
|
43
43
|
"@fastify/pre-commit": "^2.0.2",
|
|
44
44
|
"@types/node": "^20.1.0",
|
|
45
45
|
"@typescript-eslint/eslint-plugin": "^6.3.0",
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
"snazzy": "^9.0.0",
|
|
56
56
|
"standard": "^17.0.0",
|
|
57
57
|
"tap": "^16.0.0",
|
|
58
|
-
"tsd": "^0.
|
|
58
|
+
"tsd": "^0.30.0",
|
|
59
59
|
"typescript": "^5.1.6"
|
|
60
60
|
},
|
|
61
61
|
"tsd": {
|
package/test/static.test.js
CHANGED
|
@@ -2012,6 +2012,96 @@ t.test('register with wildcard false', t => {
|
|
|
2012
2012
|
})
|
|
2013
2013
|
})
|
|
2014
2014
|
|
|
2015
|
+
t.test('register with wildcard false (trailing slash in the root)', t => {
|
|
2016
|
+
t.plan(6)
|
|
2017
|
+
|
|
2018
|
+
const pluginOptions = {
|
|
2019
|
+
root: path.join(__dirname, '/static/'),
|
|
2020
|
+
prefix: '/assets/',
|
|
2021
|
+
index: false,
|
|
2022
|
+
wildcard: false
|
|
2023
|
+
}
|
|
2024
|
+
const fastify = Fastify({
|
|
2025
|
+
ignoreTrailingSlash: true
|
|
2026
|
+
})
|
|
2027
|
+
fastify.register(fastifyStatic, pluginOptions)
|
|
2028
|
+
|
|
2029
|
+
fastify.get('/*', (request, reply) => {
|
|
2030
|
+
reply.send({ hello: 'world' })
|
|
2031
|
+
})
|
|
2032
|
+
|
|
2033
|
+
t.teardown(fastify.close.bind(fastify))
|
|
2034
|
+
|
|
2035
|
+
fastify.listen({ port: 0 }, (err) => {
|
|
2036
|
+
t.error(err)
|
|
2037
|
+
|
|
2038
|
+
fastify.server.unref()
|
|
2039
|
+
|
|
2040
|
+
t.test('/index.css', (t) => {
|
|
2041
|
+
t.plan(2 + GENERIC_RESPONSE_CHECK_COUNT)
|
|
2042
|
+
simple.concat({
|
|
2043
|
+
method: 'GET',
|
|
2044
|
+
url: 'http://localhost:' + fastify.server.address().port + '/assets/index.css'
|
|
2045
|
+
}, (err, response, body) => {
|
|
2046
|
+
t.error(err)
|
|
2047
|
+
t.equal(response.statusCode, 200)
|
|
2048
|
+
genericResponseChecks(t, response)
|
|
2049
|
+
})
|
|
2050
|
+
})
|
|
2051
|
+
|
|
2052
|
+
t.test('/not-defined', (t) => {
|
|
2053
|
+
t.plan(3)
|
|
2054
|
+
simple.concat({
|
|
2055
|
+
method: 'GET',
|
|
2056
|
+
url: 'http://localhost:' + fastify.server.address().port + '/assets/not-defined'
|
|
2057
|
+
}, (err, response, body) => {
|
|
2058
|
+
t.error(err)
|
|
2059
|
+
t.equal(response.statusCode, 200)
|
|
2060
|
+
t.same(JSON.parse(body), { hello: 'world' })
|
|
2061
|
+
})
|
|
2062
|
+
})
|
|
2063
|
+
|
|
2064
|
+
t.test('/deep/path/for/test/purpose/foo.html', (t) => {
|
|
2065
|
+
t.plan(3 + GENERIC_RESPONSE_CHECK_COUNT)
|
|
2066
|
+
simple.concat({
|
|
2067
|
+
method: 'GET',
|
|
2068
|
+
url: 'http://localhost:' + fastify.server.address().port + '/assets/deep/path/for/test/purpose/foo.html'
|
|
2069
|
+
}, (err, response, body) => {
|
|
2070
|
+
t.error(err)
|
|
2071
|
+
t.equal(response.statusCode, 200)
|
|
2072
|
+
t.equal(body.toString(), deepContent)
|
|
2073
|
+
genericResponseChecks(t, response)
|
|
2074
|
+
})
|
|
2075
|
+
})
|
|
2076
|
+
|
|
2077
|
+
t.test('/../index.js', (t) => {
|
|
2078
|
+
t.plan(3)
|
|
2079
|
+
simple.concat({
|
|
2080
|
+
method: 'GET',
|
|
2081
|
+
url: 'http://localhost:' + fastify.server.address().port + '/assets/../index.js',
|
|
2082
|
+
followRedirect: false
|
|
2083
|
+
}, (err, response, body) => {
|
|
2084
|
+
t.error(err)
|
|
2085
|
+
t.equal(response.statusCode, 200)
|
|
2086
|
+
t.same(JSON.parse(body), { hello: 'world' })
|
|
2087
|
+
})
|
|
2088
|
+
})
|
|
2089
|
+
|
|
2090
|
+
t.test('/index.css', t => {
|
|
2091
|
+
t.plan(3 + GENERIC_RESPONSE_CHECK_COUNT)
|
|
2092
|
+
simple.concat({
|
|
2093
|
+
method: 'HEAD',
|
|
2094
|
+
url: 'http://localhost:' + fastify.server.address().port + '/assets/index.css'
|
|
2095
|
+
}, (err, response, body) => {
|
|
2096
|
+
t.error(err)
|
|
2097
|
+
t.equal(response.statusCode, 200)
|
|
2098
|
+
t.equal(body.toString(), '')
|
|
2099
|
+
genericResponseChecks(t, response)
|
|
2100
|
+
})
|
|
2101
|
+
})
|
|
2102
|
+
})
|
|
2103
|
+
})
|
|
2104
|
+
|
|
2015
2105
|
t.test('register with wildcard string', (t) => {
|
|
2016
2106
|
t.plan(1)
|
|
2017
2107
|
|
package/types/index.d.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// Leo <https://github.com/leomelzer>
|
|
3
3
|
/// <reference types="node" />
|
|
4
4
|
|
|
5
|
-
import { FastifyPluginAsync, FastifyRequest, RouteOptions } from 'fastify'
|
|
5
|
+
import { FastifyPluginAsync, FastifyReply, FastifyRequest, RouteOptions } from 'fastify'
|
|
6
6
|
import { Stats } from 'fs'
|
|
7
7
|
|
|
8
8
|
declare module 'fastify' {
|
|
@@ -19,6 +19,13 @@ declare module 'fastify' {
|
|
|
19
19
|
type FastifyStaticPlugin = FastifyPluginAsync<NonNullable<fastifyStatic.FastifyStaticOptions>>;
|
|
20
20
|
|
|
21
21
|
declare namespace fastifyStatic {
|
|
22
|
+
export interface SetHeadersResponse {
|
|
23
|
+
getHeader: FastifyReply['getHeader'];
|
|
24
|
+
setHeader: FastifyReply['header'];
|
|
25
|
+
readonly filename: string;
|
|
26
|
+
statusCode: number;
|
|
27
|
+
}
|
|
28
|
+
|
|
22
29
|
export interface ExtendedInformation {
|
|
23
30
|
fileCount: number;
|
|
24
31
|
totalFileCount: number;
|
|
@@ -83,7 +90,7 @@ declare namespace fastifyStatic {
|
|
|
83
90
|
serve?: boolean;
|
|
84
91
|
decorateReply?: boolean;
|
|
85
92
|
schemaHide?: boolean;
|
|
86
|
-
setHeaders?: (
|
|
93
|
+
setHeaders?: (res: SetHeadersResponse, path: string, stat: Stats) => void;
|
|
87
94
|
redirect?: boolean;
|
|
88
95
|
wildcard?: boolean;
|
|
89
96
|
list?: boolean | ListOptionsJsonFormat | ListOptionsHtmlFormat;
|
package/types/index.test-d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import fastify, { FastifyInstance, FastifyPluginAsync, FastifyRequest } from 'fastify'
|
|
1
|
+
import fastify, { FastifyInstance, FastifyPluginAsync, FastifyRequest, FastifyReply } from 'fastify'
|
|
2
2
|
import { Server } from 'http'
|
|
3
|
+
import { Stats } from 'fs'
|
|
3
4
|
import { expectAssignable, expectError, expectType } from 'tsd'
|
|
4
5
|
import * as fastifyStaticStar from '..'
|
|
5
6
|
import fastifyStatic, {
|
|
@@ -49,8 +50,15 @@ const options: FastifyStaticOptions = {
|
|
|
49
50
|
serve: true,
|
|
50
51
|
wildcard: true,
|
|
51
52
|
list: false,
|
|
52
|
-
setHeaders: (res
|
|
53
|
-
res.
|
|
53
|
+
setHeaders: (res, path, stat) => {
|
|
54
|
+
expectType<string>(res.filename)
|
|
55
|
+
expectType<number>(res.statusCode)
|
|
56
|
+
expectType<ReturnType<FastifyReply['getHeader']>>(res.getHeader('X-Test'))
|
|
57
|
+
res.setHeader('X-Test', 'string')
|
|
58
|
+
|
|
59
|
+
expectType<string>(path)
|
|
60
|
+
|
|
61
|
+
expectType<Stats>(stat)
|
|
54
62
|
},
|
|
55
63
|
preCompressed: false,
|
|
56
64
|
allowedPath: (pathName: string, root: string, request: FastifyRequest) => {
|