@fastify/static 6.11.0 → 6.11.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/README.md +3 -3
- package/example/server-compress.js +1 -1
- package/example/server-dir-list.js +1 -1
- package/example/server-hidden-file.js +1 -1
- package/example/server.js +1 -1
- package/index.js +145 -140
- package/lib/dirList.js +7 -9
- package/package.json +3 -4
- package/test/content-type.test.js +1 -1
- package/test/dir-list.test.js +2 -2
- package/test/static.test.js +5 -5
- package/test/content-type/sample.jpg.br +0 -0
package/README.md
CHANGED
|
@@ -21,7 +21,7 @@ Plugin for serving static files as fast as possible. Supports Fastify version `4
|
|
|
21
21
|
|
|
22
22
|
```js
|
|
23
23
|
const fastify = require('fastify')({logger: true})
|
|
24
|
-
const path = require('path')
|
|
24
|
+
const path = require('node:path')
|
|
25
25
|
|
|
26
26
|
fastify.register(require('@fastify/static'), {
|
|
27
27
|
root: path.join(__dirname, 'public'),
|
|
@@ -57,7 +57,7 @@ fastify.listen({ port: 3000 }, (err, address) => {
|
|
|
57
57
|
```js
|
|
58
58
|
const fastify = require('fastify')()
|
|
59
59
|
const fastifyStatic = require('@fastify/static')
|
|
60
|
-
const path = require('path')
|
|
60
|
+
const path = require('node:path')
|
|
61
61
|
// first plugin
|
|
62
62
|
fastify.register(fastifyStatic, {
|
|
63
63
|
root: path.join(__dirname, 'public')
|
|
@@ -76,7 +76,7 @@ fastify.register(fastifyStatic, {
|
|
|
76
76
|
|
|
77
77
|
```js
|
|
78
78
|
const fastify = require('fastify')()
|
|
79
|
-
const path = require('path')
|
|
79
|
+
const path = require('node:path')
|
|
80
80
|
|
|
81
81
|
fastify.register(require('@fastify/static'), {
|
|
82
82
|
root: path.join(__dirname, 'public'),
|
package/example/server.js
CHANGED
package/index.js
CHANGED
|
@@ -1,27 +1,34 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const
|
|
4
|
-
const
|
|
5
|
-
const
|
|
6
|
-
const {
|
|
3
|
+
const { PassThrough } = require('node:stream')
|
|
4
|
+
const path = require('node:path')
|
|
5
|
+
const { fileURLToPath } = require('node:url')
|
|
6
|
+
const { statSync } = require('node:fs')
|
|
7
|
+
const { promisify } = require('node:util')
|
|
7
8
|
const glob = require('glob')
|
|
8
|
-
const
|
|
9
|
-
const contentDisposition = require('content-disposition')
|
|
9
|
+
const globPromise = promisify(glob)
|
|
10
10
|
const fp = require('fastify-plugin')
|
|
11
|
-
const
|
|
12
|
-
const globPromise = util.promisify(glob)
|
|
11
|
+
const send = require('@fastify/send')
|
|
13
12
|
const encodingNegotiator = require('@fastify/accept-negotiator')
|
|
14
|
-
|
|
15
|
-
send.mime.default_type = 'application/octet-stream'
|
|
13
|
+
const contentDisposition = require('content-disposition')
|
|
16
14
|
|
|
17
15
|
const dirList = require('./lib/dirList')
|
|
18
16
|
|
|
17
|
+
const winSeparatorRegex = new RegExp(`\\${path.win32.sep}`, 'g')
|
|
18
|
+
const backslashRegex = /\\/g
|
|
19
|
+
const startForwardSlashRegex = /^\//
|
|
20
|
+
const endForwardSlashRegex = /\/$/
|
|
21
|
+
const doubleForwardSlashRegex = /\/\//g
|
|
22
|
+
const asteriskRegex = /\*/g
|
|
23
|
+
|
|
24
|
+
const supportedEncodings = ['br', 'gzip', 'deflate']
|
|
25
|
+
send.mime.default_type = 'application/octet-stream'
|
|
26
|
+
|
|
19
27
|
async function fastifyStatic (fastify, opts) {
|
|
20
28
|
opts.root = normalizeRoot(opts.root)
|
|
21
29
|
checkRootPathForErrors(fastify, opts.root)
|
|
22
30
|
|
|
23
31
|
const setHeaders = opts.setHeaders
|
|
24
|
-
|
|
25
32
|
if (setHeaders !== undefined && typeof setHeaders !== 'function') {
|
|
26
33
|
throw new TypeError('The `setHeaders` option must be a function')
|
|
27
34
|
}
|
|
@@ -48,19 +55,124 @@ async function fastifyStatic (fastify, opts) {
|
|
|
48
55
|
maxAge: opts.maxAge
|
|
49
56
|
}
|
|
50
57
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
if (opts.prefix === undefined) opts.prefix = '/'
|
|
54
|
-
|
|
55
|
-
let prefix = opts.prefix
|
|
58
|
+
let prefix = opts.prefix ?? (opts.prefix = '/')
|
|
56
59
|
|
|
57
60
|
if (!opts.prefixAvoidTrailingSlash) {
|
|
58
61
|
prefix =
|
|
59
|
-
|
|
60
|
-
?
|
|
61
|
-
:
|
|
62
|
+
prefix[prefix.length - 1] === '/'
|
|
63
|
+
? prefix
|
|
64
|
+
: prefix + '/'
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Set the schema hide property if defined in opts or true by default
|
|
68
|
+
const routeOpts = {
|
|
69
|
+
constraints: opts.constraints,
|
|
70
|
+
schema: {
|
|
71
|
+
hide: opts.schemaHide !== undefined ? opts.schemaHide : true
|
|
72
|
+
},
|
|
73
|
+
errorHandler (error, request, reply) {
|
|
74
|
+
if (error?.code === 'ERR_STREAM_PREMATURE_CLOSE') {
|
|
75
|
+
reply.request.raw.destroy()
|
|
76
|
+
return
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
fastify.errorHandler(error, request, reply)
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (opts.decorateReply !== false) {
|
|
84
|
+
fastify.decorateReply('sendFile', function (filePath, rootPath, options) {
|
|
85
|
+
const opts = typeof rootPath === 'object' ? rootPath : options
|
|
86
|
+
const root = typeof rootPath === 'string' ? rootPath : opts && opts.root
|
|
87
|
+
pumpSendToReply(
|
|
88
|
+
this.request,
|
|
89
|
+
this,
|
|
90
|
+
filePath,
|
|
91
|
+
root || sendOptions.root,
|
|
92
|
+
0,
|
|
93
|
+
opts
|
|
94
|
+
)
|
|
95
|
+
return this
|
|
96
|
+
})
|
|
97
|
+
|
|
98
|
+
fastify.decorateReply(
|
|
99
|
+
'download',
|
|
100
|
+
function (filePath, fileName, options = {}) {
|
|
101
|
+
const { root, ...opts } =
|
|
102
|
+
typeof fileName === 'object' ? fileName : options
|
|
103
|
+
fileName = typeof fileName === 'string' ? fileName : filePath
|
|
104
|
+
|
|
105
|
+
// Set content disposition header
|
|
106
|
+
this.header('content-disposition', contentDisposition(fileName))
|
|
107
|
+
|
|
108
|
+
pumpSendToReply(this.request, this, filePath, root, 0, opts)
|
|
109
|
+
|
|
110
|
+
return this
|
|
111
|
+
}
|
|
112
|
+
)
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
if (opts.serve !== false) {
|
|
116
|
+
if (opts.wildcard && typeof opts.wildcard !== 'boolean') {
|
|
117
|
+
throw new Error('"wildcard" option must be a boolean')
|
|
118
|
+
}
|
|
119
|
+
if (opts.wildcard === undefined || opts.wildcard === true) {
|
|
120
|
+
fastify.head(prefix + '*', routeOpts, function (req, reply) {
|
|
121
|
+
pumpSendToReply(req, reply, '/' + req.params['*'], sendOptions.root)
|
|
122
|
+
})
|
|
123
|
+
fastify.get(prefix + '*', routeOpts, function (req, reply) {
|
|
124
|
+
pumpSendToReply(req, reply, '/' + req.params['*'], sendOptions.root)
|
|
125
|
+
})
|
|
126
|
+
if (opts.redirect === true && prefix !== opts.prefix) {
|
|
127
|
+
fastify.get(opts.prefix, routeOpts, function (req, reply) {
|
|
128
|
+
reply.redirect(301, getRedirectUrl(req.raw.url))
|
|
129
|
+
})
|
|
130
|
+
}
|
|
131
|
+
} else {
|
|
132
|
+
const globPattern = '**/**'
|
|
133
|
+
const indexDirs = new Map()
|
|
134
|
+
const routes = new Set()
|
|
135
|
+
|
|
136
|
+
const roots = Array.isArray(sendOptions.root) ? sendOptions.root : [sendOptions.root]
|
|
137
|
+
for (let i = 0; i < roots.length; ++i) {
|
|
138
|
+
const rootPath = roots[i]
|
|
139
|
+
const files = await globPromise(path.join(rootPath, globPattern).replace(winSeparatorRegex, path.posix.sep), { nodir: true, dot: opts.serveDotFiles })
|
|
140
|
+
const indexes = opts.index === undefined ? ['index.html'] : [].concat(opts.index)
|
|
141
|
+
|
|
142
|
+
for (let i = 0; i < files.length; ++i) {
|
|
143
|
+
const file = files[i].replace(rootPath.replace(backslashRegex, '/'), '')
|
|
144
|
+
.replace(startForwardSlashRegex, '')
|
|
145
|
+
const route = (prefix + file).replace(doubleForwardSlashRegex, '/')
|
|
146
|
+
|
|
147
|
+
if (routes.has(route)) {
|
|
148
|
+
continue
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
routes.add(route)
|
|
152
|
+
|
|
153
|
+
setUpHeadAndGet(routeOpts, route, '/' + file, rootPath)
|
|
154
|
+
|
|
155
|
+
const key = path.posix.basename(route)
|
|
156
|
+
if (indexes.includes(key) && !indexDirs.has(key)) {
|
|
157
|
+
indexDirs.set(path.posix.dirname(route), rootPath)
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
for (const [dirname, rootPath] of indexDirs.entries()) {
|
|
163
|
+
const pathname = dirname + (dirname.endsWith('/') ? '' : '/')
|
|
164
|
+
const file = '/' + pathname.replace(prefix, '')
|
|
165
|
+
setUpHeadAndGet(routeOpts, pathname, file, rootPath)
|
|
166
|
+
|
|
167
|
+
if (opts.redirect === true) {
|
|
168
|
+
setUpHeadAndGet(routeOpts, pathname.replace(endForwardSlashRegex, ''), file.replace(endForwardSlashRegex, ''), rootPath)
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
62
172
|
}
|
|
63
173
|
|
|
174
|
+
const allowedPath = opts.allowedPath
|
|
175
|
+
|
|
64
176
|
function pumpSendToReply (
|
|
65
177
|
request,
|
|
66
178
|
reply,
|
|
@@ -271,121 +383,12 @@ async function fastifyStatic (fastify, opts) {
|
|
|
271
383
|
stream.pipe(wrap)
|
|
272
384
|
}
|
|
273
385
|
|
|
274
|
-
const errorHandler = (error, request, reply) => {
|
|
275
|
-
if (error && error.code === 'ERR_STREAM_PREMATURE_CLOSE') {
|
|
276
|
-
reply.request.raw.destroy()
|
|
277
|
-
return
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
fastify.errorHandler(error, request, reply)
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
// Set the schema hide property if defined in opts or true by default
|
|
284
|
-
const routeOpts = {
|
|
285
|
-
constraints: opts.constraints,
|
|
286
|
-
schema: {
|
|
287
|
-
hide: typeof opts.schemaHide !== 'undefined' ? opts.schemaHide : true
|
|
288
|
-
},
|
|
289
|
-
errorHandler
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
if (opts.decorateReply !== false) {
|
|
293
|
-
fastify.decorateReply('sendFile', function (filePath, rootPath, options) {
|
|
294
|
-
const opts = typeof rootPath === 'object' ? rootPath : options
|
|
295
|
-
const root = typeof rootPath === 'string' ? rootPath : opts && opts.root
|
|
296
|
-
pumpSendToReply(
|
|
297
|
-
this.request,
|
|
298
|
-
this,
|
|
299
|
-
filePath,
|
|
300
|
-
root || sendOptions.root,
|
|
301
|
-
0,
|
|
302
|
-
opts
|
|
303
|
-
)
|
|
304
|
-
return this
|
|
305
|
-
})
|
|
306
|
-
|
|
307
|
-
fastify.decorateReply(
|
|
308
|
-
'download',
|
|
309
|
-
function (filePath, fileName, options = {}) {
|
|
310
|
-
const { root, ...opts } =
|
|
311
|
-
typeof fileName === 'object' ? fileName : options
|
|
312
|
-
fileName = typeof fileName === 'string' ? fileName : filePath
|
|
313
|
-
|
|
314
|
-
// Set content disposition header
|
|
315
|
-
this.header('content-disposition', contentDisposition(fileName))
|
|
316
|
-
|
|
317
|
-
pumpSendToReply(this.request, this, filePath, root, 0, opts)
|
|
318
|
-
|
|
319
|
-
return this
|
|
320
|
-
}
|
|
321
|
-
)
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
if (opts.serve !== false) {
|
|
325
|
-
if (opts.wildcard && typeof opts.wildcard !== 'boolean') {
|
|
326
|
-
throw new Error('"wildcard" option must be a boolean')
|
|
327
|
-
}
|
|
328
|
-
if (opts.wildcard === undefined || opts.wildcard === true) {
|
|
329
|
-
fastify.head(prefix + '*', routeOpts, function (req, reply) {
|
|
330
|
-
pumpSendToReply(req, reply, '/' + req.params['*'], sendOptions.root)
|
|
331
|
-
})
|
|
332
|
-
fastify.get(prefix + '*', routeOpts, function (req, reply) {
|
|
333
|
-
pumpSendToReply(req, reply, '/' + req.params['*'], sendOptions.root)
|
|
334
|
-
})
|
|
335
|
-
if (opts.redirect === true && prefix !== opts.prefix) {
|
|
336
|
-
fastify.get(opts.prefix, routeOpts, function (req, reply) {
|
|
337
|
-
reply.redirect(301, getRedirectUrl(req.raw.url))
|
|
338
|
-
})
|
|
339
|
-
}
|
|
340
|
-
} else {
|
|
341
|
-
const globPattern = '**/**'
|
|
342
|
-
const indexDirs = new Map()
|
|
343
|
-
const routes = new Set()
|
|
344
|
-
|
|
345
|
-
const winSeparatorRegex = new RegExp(`\\${path.win32.sep}`, 'g')
|
|
346
|
-
|
|
347
|
-
for (const rootPath of Array.isArray(sendOptions.root) ? sendOptions.root : [sendOptions.root]) {
|
|
348
|
-
const files = await globPromise(path.join(rootPath, globPattern).replace(winSeparatorRegex, path.posix.sep), { nodir: true, dot: opts.serveDotFiles })
|
|
349
|
-
const indexes = typeof opts.index === 'undefined' ? ['index.html'] : [].concat(opts.index)
|
|
350
|
-
|
|
351
|
-
for (let file of files) {
|
|
352
|
-
file = file
|
|
353
|
-
.replace(rootPath.replace(/\\/g, '/'), '')
|
|
354
|
-
.replace(/^\//, '')
|
|
355
|
-
const route = (prefix + file).replace(/\/\//g, '/')
|
|
356
|
-
if (routes.has(route)) {
|
|
357
|
-
continue
|
|
358
|
-
}
|
|
359
|
-
routes.add(route)
|
|
360
|
-
|
|
361
|
-
setUpHeadAndGet(routeOpts, route, '/' + file, rootPath)
|
|
362
|
-
|
|
363
|
-
const key = path.posix.basename(route)
|
|
364
|
-
if (indexes.includes(key) && !indexDirs.has(key)) {
|
|
365
|
-
indexDirs.set(path.posix.dirname(route), rootPath)
|
|
366
|
-
}
|
|
367
|
-
}
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
for (const [dirname, rootPath] of indexDirs.entries()) {
|
|
371
|
-
const pathname = dirname + (dirname.endsWith('/') ? '' : '/')
|
|
372
|
-
const file = '/' + pathname.replace(prefix, '')
|
|
373
|
-
setUpHeadAndGet(routeOpts, pathname, file, rootPath)
|
|
374
|
-
|
|
375
|
-
if (opts.redirect === true) {
|
|
376
|
-
setUpHeadAndGet(routeOpts, pathname.replace(/\/$/, ''), file.replace(/\/$/, ''), rootPath)
|
|
377
|
-
}
|
|
378
|
-
}
|
|
379
|
-
}
|
|
380
|
-
}
|
|
381
|
-
|
|
382
386
|
function setUpHeadAndGet (routeOpts, route, file, rootPath) {
|
|
383
|
-
const toSetUp = {
|
|
384
|
-
...routeOpts,
|
|
387
|
+
const toSetUp = Object.assign({}, routeOpts, {
|
|
385
388
|
method: ['HEAD', 'GET'],
|
|
386
389
|
url: route,
|
|
387
390
|
handler: serveFileHandler
|
|
388
|
-
}
|
|
391
|
+
})
|
|
389
392
|
toSetUp.config = toSetUp.config || {}
|
|
390
393
|
toSetUp.config.file = file
|
|
391
394
|
toSetUp.config.rootPath = rootPath
|
|
@@ -393,9 +396,10 @@ async function fastifyStatic (fastify, opts) {
|
|
|
393
396
|
}
|
|
394
397
|
|
|
395
398
|
function serveFileHandler (req, reply) {
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
+
// TODO: remove the fallback branch when bump major
|
|
400
|
+
/* istanbul ignore next */
|
|
401
|
+
const routeConfig = req.routeOptions?.config || req.routeConfig
|
|
402
|
+
pumpSendToReply(req, reply, routeConfig.file, routeConfig.rootPath)
|
|
399
403
|
}
|
|
400
404
|
}
|
|
401
405
|
|
|
@@ -404,13 +408,13 @@ function normalizeRoot (root) {
|
|
|
404
408
|
return root
|
|
405
409
|
}
|
|
406
410
|
if (root instanceof URL && root.protocol === 'file:') {
|
|
407
|
-
return
|
|
411
|
+
return fileURLToPath(root)
|
|
408
412
|
}
|
|
409
413
|
if (Array.isArray(root)) {
|
|
410
414
|
const result = []
|
|
411
415
|
for (let i = 0, il = root.length; i < il; ++i) {
|
|
412
416
|
if (root[i] instanceof URL && root[i].protocol === 'file:') {
|
|
413
|
-
result.push(
|
|
417
|
+
result.push(fileURLToPath(root[i]))
|
|
414
418
|
} else {
|
|
415
419
|
result.push(root[i])
|
|
416
420
|
}
|
|
@@ -503,13 +507,13 @@ function findIndexFile (pathname, root, indexFiles = ['index.html']) {
|
|
|
503
507
|
return false
|
|
504
508
|
}
|
|
505
509
|
|
|
506
|
-
const supportedEncodings = ['br', 'gzip', 'deflate']
|
|
507
|
-
|
|
508
510
|
// Adapted from https://github.com/fastify/fastify-compress/blob/665e132fa63d3bf05ad37df3c20346660b71a857/index.js#L451
|
|
509
511
|
function getEncodingHeader (headers, checked) {
|
|
510
512
|
if (!('accept-encoding' in headers)) return
|
|
511
513
|
|
|
512
|
-
|
|
514
|
+
// consider the no-preference token as gzip for downstream compat
|
|
515
|
+
const header = headers['accept-encoding'].toLowerCase().replace(asteriskRegex, 'gzip')
|
|
516
|
+
|
|
513
517
|
return encodingNegotiator.negotiate(
|
|
514
518
|
header,
|
|
515
519
|
supportedEncodings.filter((enc) => !checked.has(enc))
|
|
@@ -529,14 +533,15 @@ function getEncodingExtension (encoding) {
|
|
|
529
533
|
function getRedirectUrl (url) {
|
|
530
534
|
let i = 0
|
|
531
535
|
// we detect how many slash before a valid path
|
|
532
|
-
for (
|
|
536
|
+
for (; i < url.length; ++i) {
|
|
533
537
|
if (url[i] !== '/' && url[i] !== '\\') break
|
|
534
538
|
}
|
|
535
539
|
// turns all leading / or \ into a single /
|
|
536
540
|
url = '/' + url.substr(i)
|
|
537
541
|
try {
|
|
538
542
|
const parsed = new URL(url, 'http://localhost.com/')
|
|
539
|
-
|
|
543
|
+
const parsedPathname = parsed.pathname
|
|
544
|
+
return parsedPathname + (parsedPathname[parsedPathname.length - 1] !== '/' ? '/' : '') + (parsed.search || '')
|
|
540
545
|
} catch (error) {
|
|
541
546
|
// the try-catch here is actually unreachable, but we keep it for safety and prevent DoS attack
|
|
542
547
|
/* istanbul ignore next */
|
package/lib/dirList.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const path = require('path')
|
|
4
|
-
const fs = require('fs')
|
|
3
|
+
const path = require('node:path')
|
|
4
|
+
const fs = require('node:fs/promises')
|
|
5
5
|
const pLimit = require('p-limit')
|
|
6
6
|
|
|
7
7
|
const dirList = {
|
|
@@ -16,7 +16,7 @@ const dirList = {
|
|
|
16
16
|
const entries = { dirs: [], files: [] }
|
|
17
17
|
let files = await fs.readdir(dir)
|
|
18
18
|
if (dotfiles === 'deny' || dotfiles === 'ignore') {
|
|
19
|
-
files = files.filter(
|
|
19
|
+
files = files.filter(file => file.charAt(0) !== '.')
|
|
20
20
|
}
|
|
21
21
|
if (files.length < 1) {
|
|
22
22
|
return entries
|
|
@@ -92,6 +92,7 @@ const dirList = {
|
|
|
92
92
|
|
|
93
93
|
entries.dirs.sort((a, b) => a.name.localeCompare(b.name))
|
|
94
94
|
entries.files.sort((a, b) => a.name.localeCompare(b.name))
|
|
95
|
+
|
|
95
96
|
return entries
|
|
96
97
|
},
|
|
97
98
|
|
|
@@ -141,7 +142,7 @@ const dirList = {
|
|
|
141
142
|
* @return {ListFile}
|
|
142
143
|
*/
|
|
143
144
|
htmlInfo: function (entry, route, prefix, options) {
|
|
144
|
-
if (options.names
|
|
145
|
+
if (options.names?.includes(path.basename(route))) {
|
|
145
146
|
route = path.normalize(path.join(route, '..'))
|
|
146
147
|
}
|
|
147
148
|
return {
|
|
@@ -159,12 +160,9 @@ const dirList = {
|
|
|
159
160
|
* @return {boolean}
|
|
160
161
|
*/
|
|
161
162
|
handle: function (route, options) {
|
|
162
|
-
|
|
163
|
-
return false
|
|
164
|
-
}
|
|
165
|
-
return options.names.includes(path.basename(route)) ||
|
|
163
|
+
return options.names?.includes(path.basename(route)) ||
|
|
166
164
|
// match trailing slash
|
|
167
|
-
(options.names
|
|
165
|
+
((options.names?.includes('/') && route[route.length - 1] === '/') ?? false)
|
|
168
166
|
},
|
|
169
167
|
|
|
170
168
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fastify/static",
|
|
3
|
-
"version": "6.11.
|
|
3
|
+
"version": "6.11.2",
|
|
4
4
|
"description": "Plugin for serving static files as fast as possible.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "types/index.d.ts",
|
|
@@ -35,8 +35,7 @@
|
|
|
35
35
|
"content-disposition": "^0.5.3",
|
|
36
36
|
"fastify-plugin": "^4.0.0",
|
|
37
37
|
"glob": "^8.0.1",
|
|
38
|
-
"p-limit": "^3.1.0"
|
|
39
|
-
"readable-stream": "^4.0.0"
|
|
38
|
+
"p-limit": "^3.1.0"
|
|
40
39
|
},
|
|
41
40
|
"devDependencies": {
|
|
42
41
|
"@fastify/compress": "^6.0.0",
|
|
@@ -55,7 +54,7 @@
|
|
|
55
54
|
"snazzy": "^9.0.0",
|
|
56
55
|
"standard": "^17.0.0",
|
|
57
56
|
"tap": "^16.0.0",
|
|
58
|
-
"tsd": "^0.
|
|
57
|
+
"tsd": "^0.29.0",
|
|
59
58
|
"typescript": "^5.1.6"
|
|
60
59
|
},
|
|
61
60
|
"tsd": {
|
package/test/dir-list.test.js
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
/* eslint n/no-deprecated-api: "off" */
|
|
4
4
|
|
|
5
|
-
const fs = require('fs')
|
|
6
|
-
const path = require('path')
|
|
5
|
+
const fs = require('node:fs')
|
|
6
|
+
const path = require('node:path')
|
|
7
7
|
const t = require('tap')
|
|
8
8
|
const simple = require('simple-get')
|
|
9
9
|
const Fastify = require('fastify')
|
package/test/static.test.js
CHANGED
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
/* eslint n/no-deprecated-api: "off" */
|
|
4
4
|
|
|
5
|
-
const path = require('path')
|
|
6
|
-
const fs = require('fs')
|
|
7
|
-
const url = require('url')
|
|
8
|
-
const http = require('http')
|
|
5
|
+
const path = require('node:path')
|
|
6
|
+
const fs = require('node:fs')
|
|
7
|
+
const url = require('node:url')
|
|
8
|
+
const http = require('node:http')
|
|
9
9
|
const t = require('tap')
|
|
10
10
|
const simple = require('simple-get')
|
|
11
11
|
const Fastify = require('fastify')
|
|
@@ -2823,7 +2823,7 @@ t.test(
|
|
|
2823
2823
|
'register with rootpath that causes statSync to fail with non-ENOENT code',
|
|
2824
2824
|
(t) => {
|
|
2825
2825
|
const fastifyStatic = proxyquire('../', {
|
|
2826
|
-
fs: {
|
|
2826
|
+
'node:fs': {
|
|
2827
2827
|
statSync: function statSyncStub (path) {
|
|
2828
2828
|
throw new Error({ code: 'MOCK' })
|
|
2829
2829
|
}
|
|
Binary file
|