@fastify/static 7.0.4 → 8.0.0

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.
@@ -17,7 +17,7 @@ on:
17
17
 
18
18
  jobs:
19
19
  test:
20
- uses: fastify/workflows/.github/workflows/plugins-ci.yml@v3
20
+ uses: fastify/workflows/.github/workflows/plugins-ci.yml@v5.0.0
21
21
  with:
22
22
  license-check: true
23
23
  lint: true
package/README.md CHANGED
@@ -477,13 +477,13 @@ 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
478
  [`fastify.setErrorHandler()`](https://fastify.dev/docs/latest/Reference/Server/#seterrorhandler).
479
479
 
480
- ### Payload `stream.filename`
480
+ ### Payload `stream.path`
481
481
 
482
- If you need to access the filename inside the `onSend` hook, you can use `payload.filename`.
482
+ If you need to access the file path inside the `onSend` hook, you can use `payload.path`.
483
483
 
484
484
  ```js
485
485
  fastify.addHook('onSend', function (req, reply, payload, next) {
486
- console.log(payload.filename)
486
+ console.log(payload.path)
487
487
  next()
488
488
  })
489
489
  ```
@@ -0,0 +1,6 @@
1
+ 'use strict'
2
+
3
+ module.exports = require('neostandard')({
4
+ noJsx: true,
5
+ ts: true,
6
+ })
@@ -1,32 +1,21 @@
1
1
  'use strict'
2
2
 
3
3
  const path = require('node:path')
4
- const Handlebars = require('handlebars')
5
4
 
6
5
  const fastify = require('fastify')({ logger: { level: 'trace' } })
7
6
 
8
- // Handlebar template for listing files and directories.
9
- const template = `
10
- <html>
11
- <body>
12
- dirs
13
- <ul>
14
- {{#dirs}}
15
- <li><a href="{{href}}">{{name}}</a></li>
16
- {{/dirs}}
17
- </ul>
18
-
19
- list
20
-
21
- <ul>
22
- {{#files}}
23
- <li><a href="{{href}}" target="_blank">{{name}}</a></li>
24
- {{/files}}
25
- </ul>
26
- </body>
27
- </html>
7
+ const renderer = (dirs, files) => {
8
+ return `
9
+ <html><body>
10
+ <ul>
11
+ ${dirs.map(dir => `<li><a href="${dir.href}">${dir.name}</a></li>`).join('\n ')}
12
+ </ul>
13
+ <ul>
14
+ ${files.map(file => `<li><a href="${file.href}" target="_blank">${file.name}</a></li>`).join('\n ')}
15
+ </ul>
16
+ </body></html>
28
17
  `
29
- const handlebarTemplate = Handlebars.compile(template)
18
+ }
30
19
 
31
20
  fastify
32
21
  .register(require('..'), {
@@ -41,7 +30,7 @@ fastify
41
30
  // A list of filenames that trigger a directory list response.
42
31
  names: ['index', 'index.html', 'index.htm', '/'],
43
32
  // You can provide your own render method as needed.
44
- render: (dirs, files) => handlebarTemplate({ dirs, files })
33
+ renderer
45
34
  }
46
35
  })
47
36
  .listen({ port: 3000 }, err => {
package/index.js CHANGED
@@ -1,6 +1,5 @@
1
1
  'use strict'
2
2
 
3
- const { PassThrough } = require('node:stream')
4
3
  const path = require('node:path')
5
4
  const { fileURLToPath } = require('node:url')
6
5
  const { statSync } = require('node:fs')
@@ -121,7 +120,7 @@ async function fastifyStatic (fastify, opts) {
121
120
  })
122
121
  if (opts.redirect === true && prefix !== opts.prefix) {
123
122
  fastify.get(opts.prefix, routeOpts, (req, reply) => {
124
- reply.redirect(301, getRedirectUrl(req.raw.url))
123
+ reply.redirect(getRedirectUrl(req.raw.url), 301)
125
124
  })
126
125
  }
127
126
  } else {
@@ -170,7 +169,7 @@ async function fastifyStatic (fastify, opts) {
170
169
 
171
170
  const allowedPath = opts.allowedPath
172
171
 
173
- function pumpSendToReply (
172
+ async function pumpSendToReply (
174
173
  request,
175
174
  reply,
176
175
  pathname,
@@ -222,164 +221,148 @@ async function fastifyStatic (fastify, opts) {
222
221
  }
223
222
 
224
223
  // `send(..., path, ...)` will URI-decode path so we pass an encoded path here
225
- const stream = send(request.raw, encodeURI(pathnameForSend), options)
226
- let resolvedFilename
227
- stream.on('file', function (file) {
228
- resolvedFilename = file
229
- })
230
-
231
- const wrap = new PassThrough({
232
- flush (cb) {
233
- this.finished = true
234
- if (reply.raw.statusCode === 304) {
235
- reply.send('')
224
+ const {
225
+ statusCode,
226
+ headers,
227
+ stream,
228
+ type,
229
+ metadata
230
+ } = await send(request.raw, encodeURI(pathnameForSend), options)
231
+ switch (type) {
232
+ case 'directory': {
233
+ const path = metadata.path
234
+ if (opts.list) {
235
+ await dirList.send({
236
+ reply,
237
+ dir: path,
238
+ options: opts.list,
239
+ route: pathname,
240
+ prefix,
241
+ dotfiles: opts.dotfiles
242
+ }).catch((err) => reply.send(err))
236
243
  }
237
- cb()
238
- }
239
- })
240
244
 
241
- wrap.getHeader = reply.getHeader.bind(reply)
242
- wrap.setHeader = reply.header.bind(reply)
243
- wrap.removeHeader = () => {}
244
- wrap.finished = false
245
+ if (opts.redirect === true) {
246
+ try {
247
+ reply.redirect(getRedirectUrl(request.raw.url), 301)
248
+ } /* c8 ignore start */ catch (error) {
249
+ // the try-catch here is actually unreachable, but we keep it for safety and prevent DoS attack
250
+ await reply.send(error)
251
+ } /* c8 ignore stop */
252
+ } else {
253
+ // if is a directory path without a trailing slash, and has an index file, reply as if it has a trailing slash
254
+ if (!pathname.endsWith('/') && findIndexFile(pathname, options.root, options.index)) {
255
+ return pumpSendToReply(
256
+ request,
257
+ reply,
258
+ pathname + '/',
259
+ rootPath,
260
+ undefined,
261
+ undefined,
262
+ checkedEncodings
263
+ )
264
+ }
245
265
 
246
- Object.defineProperty(wrap, 'filename', {
247
- get () {
248
- return resolvedFilename
249
- }
250
- })
251
- Object.defineProperty(wrap, 'statusCode', {
252
- get () {
253
- return reply.raw.statusCode
254
- },
255
- set (code) {
256
- reply.code(code)
266
+ reply.callNotFound()
267
+ }
268
+ break
257
269
  }
258
- })
259
-
260
- if (request.method === 'HEAD') {
261
- wrap.on('finish', reply.send.bind(reply))
262
- } else {
263
- wrap.on('pipe', function () {
264
- if (encoding) {
265
- reply.header('content-type', getContentType(pathname))
266
- reply.header('content-encoding', encoding)
270
+ case 'error': {
271
+ if (
272
+ statusCode === 403 &&
273
+ (!options.index || !options.index.length) &&
274
+ pathnameForSend[pathnameForSend.length - 1] === '/'
275
+ ) {
276
+ if (opts.list) {
277
+ await dirList.send({
278
+ reply,
279
+ dir: dirList.path(opts.root, pathname),
280
+ options: opts.list,
281
+ route: pathname,
282
+ prefix,
283
+ dotfiles: opts.dotfiles
284
+ }).catch((err) => reply.send(err))
285
+ }
267
286
  }
268
- reply.send(wrap)
269
- })
270
- }
271
-
272
- if (setHeaders !== undefined) {
273
- stream.on('headers', setHeaders)
274
- }
275
287
 
276
- stream.on('directory', function (_, path) {
277
- if (opts.list) {
278
- dirList.send({
279
- reply,
280
- dir: path,
281
- options: opts.list,
282
- route: pathname,
283
- prefix,
284
- dotfiles: opts.dotfiles
285
- }).catch((err) => reply.send(err))
286
- return
287
- }
288
+ if (metadata.error.code === 'ENOENT') {
289
+ // when preCompress is enabled and the path is a directory without a trailing slash
290
+ if (opts.preCompressed && encoding) {
291
+ const indexPathname = findIndexFile(pathname, options.root, options.index)
292
+ if (indexPathname) {
293
+ return pumpSendToReply(
294
+ request,
295
+ reply,
296
+ pathname + '/',
297
+ rootPath,
298
+ undefined,
299
+ undefined,
300
+ checkedEncodings
301
+ )
302
+ }
303
+ }
288
304
 
289
- if (opts.redirect === true) {
290
- try {
291
- reply.redirect(301, getRedirectUrl(request.raw.url))
292
- } catch (error) {
293
- // the try-catch here is actually unreachable, but we keep it for safety and prevent DoS attack
294
- /* istanbul ignore next */
295
- reply.send(error)
296
- }
297
- } else {
298
- // if is a directory path without a trailing slash, and has an index file, reply as if it has a trailing slash
299
- if (!pathname.endsWith('/') && findIndexFile(pathname, options.root, options.index)) {
300
- return pumpSendToReply(
301
- request,
302
- reply,
303
- pathname + '/',
304
- rootPath,
305
- undefined,
306
- undefined,
307
- checkedEncodings
308
- )
309
- }
305
+ // if file exists, send real file, otherwise send dir list if name match
306
+ if (opts.list && dirList.handle(pathname, opts.list)) {
307
+ await dirList.send({
308
+ reply,
309
+ dir: dirList.path(opts.root, pathname),
310
+ options: opts.list,
311
+ route: pathname,
312
+ prefix,
313
+ dotfiles: opts.dotfiles
314
+ }).catch((err) => reply.send(err))
315
+ return
316
+ }
310
317
 
311
- reply.callNotFound()
312
- }
313
- })
318
+ // root paths left to try?
319
+ if (Array.isArray(rootPath) && rootPathOffset < (rootPath.length - 1)) {
320
+ return pumpSendToReply(request, reply, pathname, rootPath, rootPathOffset + 1)
321
+ }
314
322
 
315
- stream.on('error', function (err) {
316
- if (err.code === 'ENOENT') {
317
- // when preCompress is enabled and the path is a directory without a trailing slash
318
- if (opts.preCompressed && encoding) {
319
- const indexPathname = findIndexFile(pathname, options.root, options.index)
320
- if (indexPathname) {
323
+ if (opts.preCompressed && !checkedEncodings.has(encoding)) {
324
+ checkedEncodings.add(encoding)
321
325
  return pumpSendToReply(
322
326
  request,
323
327
  reply,
324
- pathname + '/',
328
+ pathnameOrig,
325
329
  rootPath,
326
- undefined,
330
+ rootPathOffset,
327
331
  undefined,
328
332
  checkedEncodings
329
333
  )
330
334
  }
331
- }
332
335
 
333
- // if file exists, send real file, otherwise send dir list if name match
334
- if (opts.list && dirList.handle(pathname, opts.list)) {
335
- dirList.send({
336
- reply,
337
- dir: dirList.path(opts.root, pathname),
338
- options: opts.list,
339
- route: pathname,
340
- prefix,
341
- dotfiles: opts.dotfiles
342
- }).catch((err) => reply.send(err))
343
- return
336
+ return reply.callNotFound()
344
337
  }
345
338
 
346
- // root paths left to try?
347
- if (Array.isArray(rootPath) && rootPathOffset < (rootPath.length - 1)) {
348
- return pumpSendToReply(request, reply, pathname, rootPath, rootPathOffset + 1)
339
+ // The `send` library terminates the request with a 404 if the requested
340
+ // path contains a dotfile and `send` is initialized with `{dotfiles:
341
+ // 'ignore'}`. `send` aborts the request before getting far enough to
342
+ // check if the file exists (hence, a 404 `NotFoundError` instead of
343
+ // `ENOENT`).
344
+ // https://github.com/pillarjs/send/blob/de073ed3237ade9ff71c61673a34474b30e5d45b/index.js#L582
345
+ if (metadata.error.status === 404) {
346
+ return reply.callNotFound()
349
347
  }
350
348
 
351
- if (opts.preCompressed && !checkedEncodings.has(encoding)) {
352
- checkedEncodings.add(encoding)
353
- return pumpSendToReply(
354
- request,
355
- reply,
356
- pathnameOrig,
357
- rootPath,
358
- rootPathOffset,
359
- undefined,
360
- checkedEncodings
361
- )
362
- }
363
-
364
- return reply.callNotFound()
349
+ await reply.send(metadata.error)
350
+ break
365
351
  }
366
-
367
- // The `send` library terminates the request with a 404 if the requested
368
- // path contains a dotfile and `send` is initialized with `{dotfiles:
369
- // 'ignore'}`. `send` aborts the request before getting far enough to
370
- // check if the file exists (hence, a 404 `NotFoundError` instead of
371
- // `ENOENT`).
372
- // https://github.com/pillarjs/send/blob/de073ed3237ade9ff71c61673a34474b30e5d45b/index.js#L582
373
- if (err.status === 404) {
374
- return reply.callNotFound()
352
+ case 'file': {
353
+ reply.code(statusCode)
354
+ if (setHeaders !== undefined) {
355
+ setHeaders(reply.raw, metadata.path, metadata.stat)
356
+ }
357
+ reply.headers(headers)
358
+ if (encoding) {
359
+ reply.header('content-type', getContentType(pathname))
360
+ reply.header('content-encoding', encoding)
361
+ }
362
+ await reply.send(stream)
363
+ break
375
364
  }
376
-
377
- reply.send(err)
378
- })
379
-
380
- // we cannot use pump, because send error
381
- // handling is not compatible
382
- stream.pipe(wrap)
365
+ }
383
366
  }
384
367
 
385
368
  function setUpHeadAndGet (routeOpts, route, file, rootPath) {
@@ -394,11 +377,11 @@ async function fastifyStatic (fastify, opts) {
394
377
  fastify.route(toSetUp)
395
378
  }
396
379
 
397
- function serveFileHandler (req, reply) {
380
+ async function serveFileHandler (req, reply) {
398
381
  // TODO: remove the fallback branch when bump major
399
- /* istanbul ignore next */
382
+ /* c8 ignore next */
400
383
  const routeConfig = req.routeOptions?.config || req.routeConfig
401
- pumpSendToReply(req, reply, routeConfig.file, routeConfig.rootPath)
384
+ return pumpSendToReply(req, reply, routeConfig.file, routeConfig.rootPath)
402
385
  }
403
386
  }
404
387
 
@@ -489,8 +472,6 @@ function getContentType (path) {
489
472
  }
490
473
 
491
474
  function findIndexFile (pathname, root, indexFiles = ['index.html']) {
492
- // TODO remove istanbul ignore
493
- /* istanbul ignore else */
494
475
  if (Array.isArray(indexFiles)) {
495
476
  return indexFiles.find(filename => {
496
477
  const p = path.join(root, pathname, filename)
@@ -502,7 +483,7 @@ function findIndexFile (pathname, root, indexFiles = ['index.html']) {
502
483
  }
503
484
  })
504
485
  }
505
- /* istanbul ignore next */
486
+ /* c8 ignore next */
506
487
  return false
507
488
  }
508
489
 
@@ -541,19 +522,16 @@ function getRedirectUrl (url) {
541
522
  const parsed = new URL(url, 'http://localhost.com/')
542
523
  const parsedPathname = parsed.pathname
543
524
  return parsedPathname + (parsedPathname[parsedPathname.length - 1] !== '/' ? '/' : '') + (parsed.search || '')
544
- } catch {
525
+ } /* c8 ignore start */ catch {
545
526
  // the try-catch here is actually unreachable, but we keep it for safety and prevent DoS attack
546
- /* istanbul ignore next */
547
527
  const err = new Error(`Invalid redirect URL: ${url}`)
548
- /* istanbul ignore next */
549
528
  err.statusCode = 400
550
- /* istanbul ignore next */
551
529
  throw err
552
- }
530
+ } /* c8 ignore stop */
553
531
  }
554
532
 
555
533
  module.exports = fp(fastifyStatic, {
556
- fastify: '4.x',
534
+ fastify: '5.x',
557
535
  name: '@fastify/static'
558
536
  })
559
537
  module.exports.default = fastifyStatic
package/lib/dirList.js CHANGED
@@ -125,9 +125,9 @@ const dirList = {
125
125
  entries.dirs.forEach(entry => nameEntries.dirs.push(entry.name))
126
126
  entries.files.forEach(entry => nameEntries.files.push(entry.name))
127
127
 
128
- reply.send(nameEntries)
128
+ await reply.send(nameEntries)
129
129
  } else {
130
- reply.send(entries)
130
+ await reply.send(entries)
131
131
  }
132
132
  return
133
133
  }
@@ -135,7 +135,7 @@ const dirList = {
135
135
  const html = options.render(
136
136
  entries.dirs.map(entry => dirList.htmlInfo(entry, route, prefix, options)),
137
137
  entries.files.map(entry => dirList.htmlInfo(entry, route, prefix, options)))
138
- reply.type('text/html').send(html)
138
+ await reply.type('text/html').send(html)
139
139
  },
140
140
 
141
141
  /**
package/package.json CHANGED
@@ -1,16 +1,14 @@
1
1
  {
2
2
  "name": "@fastify/static",
3
- "version": "7.0.4",
3
+ "version": "8.0.0",
4
4
  "description": "Plugin for serving static files as fast as possible.",
5
5
  "main": "index.js",
6
6
  "type": "commonjs",
7
7
  "types": "types/index.d.ts",
8
8
  "scripts": {
9
9
  "coverage": "npm run test:unit -- --coverage-report=html",
10
- "lint": "npm run lint:javascript && npm run lint:typescript",
11
- "lint:javascript": "standard | snazzy",
12
- "lint:fix": "standard --fix && npm run lint:typescript -- --fix",
13
- "lint:typescript": "eslint -c .eslintrc.json types/**/*.d.ts types/**/*.test-d.ts",
10
+ "lint": "eslint",
11
+ "lint:fix": "eslint --fix",
14
12
  "test": "npm run test:unit && npm run test:typescript",
15
13
  "test:typescript": "tsd",
16
14
  "test:unit": "tap",
@@ -31,42 +29,30 @@
31
29
  },
32
30
  "homepage": "https://github.com/fastify/fastify-static",
33
31
  "dependencies": {
34
- "@fastify/accept-negotiator": "^1.0.0",
35
- "@fastify/send": "^2.0.0",
36
- "content-disposition": "^0.5.3",
37
- "fastify-plugin": "^4.0.0",
38
- "fastq": "^1.17.0",
39
- "glob": "^10.3.4"
32
+ "@fastify/accept-negotiator": "^2.0.0",
33
+ "@fastify/send": "^3.1.0",
34
+ "content-disposition": "^0.5.4",
35
+ "fastify-plugin": "^5.0.0",
36
+ "fastq": "^1.17.1",
37
+ "glob": "^11.0.0"
40
38
  },
41
39
  "devDependencies": {
42
- "@fastify/compress": "^7.0.0",
43
- "@fastify/pre-commit": "^2.0.2",
44
- "@types/node": "^20.1.0",
45
- "@typescript-eslint/eslint-plugin": "^7.1.0",
46
- "@typescript-eslint/parser": "^7.1.0",
40
+ "@fastify/compress": "^8.0.0",
41
+ "@fastify/pre-commit": "^2.1.0",
42
+ "@types/node": "^22.0.0",
47
43
  "concat-stream": "^2.0.0",
48
- "coveralls": "^3.0.4",
49
- "eslint-plugin-typescript": "^0.14.0",
50
- "fastify": "^4.0.0-rc.2",
51
- "handlebars": "^4.7.6",
52
- "pino": "^8.4.2",
53
- "proxyquire": "^2.1.0",
54
- "simple-get": "^4.0.0",
55
- "snazzy": "^9.0.0",
56
- "standard": "^17.0.0",
57
- "tap": "^16.0.0",
58
- "tsd": "^0.31.0",
59
- "typescript": "^5.1.6"
44
+ "eslint": "^9.9.0",
45
+ "fastify": "^5.0.0-alpha.4",
46
+ "neostandard": "^0.11.3",
47
+ "pino": "^9.1.0",
48
+ "proxyquire": "^2.1.3",
49
+ "simple-get": "^4.0.1",
50
+ "tap": "^18.7.1",
51
+ "tsd": "^0.31.0"
60
52
  },
61
53
  "tsd": {
62
54
  "directory": "test/types"
63
55
  },
64
- "eslintConfig": {
65
- "rules": {
66
- "no-unused-vars": "off",
67
- "@typescript-eslint/no-unused-vars": "error"
68
- }
69
- },
70
56
  "publishConfig": {
71
57
  "access": "public"
72
58
  }
@@ -171,52 +171,44 @@ t.test('dir list, custom options', t => {
171
171
  })
172
172
  })
173
173
 
174
- t.test('dir list html format', t => {
175
- t.plan(6)
174
+ t.test('dir list, custom options with empty array index', t => {
175
+ t.plan(2)
176
176
 
177
- // render html in 2 ways: one with handlebars and one with template string
177
+ const options = {
178
+ root: path.join(__dirname, '/static'),
179
+ prefix: '/public',
180
+ index: [],
181
+ list: true
182
+ }
178
183
 
179
- const Handlebars = require('handlebars')
180
- const source = `
181
- <html><body>
182
- <ul>
183
- {{#dirs}}
184
- <li><a href="{{href}}">{{name}}</a></li>
185
- {{/dirs}}
186
- </ul>
187
- <ul>
188
- {{#files}}
189
- <li><a href="{{href}}" target="_blank">{{name}}</a></li>
190
- {{/files}}
191
- </ul>
192
- </body></html>
193
- `
194
- const handlebarTemplate = Handlebars.compile(source)
195
- const templates = [
196
- {
197
- render: (dirs, files) => {
198
- return handlebarTemplate({ dirs, files })
199
- },
200
- output: `
201
- <html><body>
202
- <ul>
203
- <li><a href="/public/deep">deep</a></li>
204
- <li><a href="/public/shallow">shallow</a></li>
205
- </ul>
206
- <ul>
207
- <li><a href="/public/.example" target="_blank">.example</a></li>
208
- <li><a href="/public/100%25.txt" target="_blank">100%.txt</a></li>
209
- <li><a href="/public/a%20.md" target="_blank">a .md</a></li>
210
- <li><a href="/public/foo.html" target="_blank">foo.html</a></li>
211
- <li><a href="/public/foobar.html" target="_blank">foobar.html</a></li>
212
- <li><a href="/public/index.css" target="_blank">index.css</a></li>
213
- <li><a href="/public/index.html" target="_blank">index.html</a></li>
214
- </ul>
215
- </body></html>
216
- `
217
- },
184
+ const route = '/public/'
185
+ const content = { dirs: ['deep', 'shallow'], files: ['.example', '100%.txt', 'a .md', 'foo.html', 'foobar.html', 'index.css', 'index.html'] }
218
186
 
219
- {
187
+ helper.arrange(t, options, (url) => {
188
+ t.test(route, t => {
189
+ t.plan(3)
190
+ simple.concat({
191
+ method: 'GET',
192
+ url: url + route
193
+ }, (err, response, body) => {
194
+ t.error(err)
195
+ t.equal(response.statusCode, 200)
196
+ t.equal(body.toString(), JSON.stringify(content))
197
+ })
198
+ })
199
+ })
200
+ })
201
+
202
+ t.test('dir list html format', t => {
203
+ t.plan(3)
204
+
205
+ const options = {
206
+ root: path.join(__dirname, '/static'),
207
+ prefix: '/public',
208
+ index: false,
209
+ list: {
210
+ format: 'html',
211
+ names: ['index', 'index.htm'],
220
212
  render: (dirs, files) => {
221
213
  return `
222
214
  <html><body>
@@ -228,8 +220,24 @@ t.test('dir list html format', t => {
228
220
  </ul>
229
221
  </body></html>
230
222
  `
231
- },
232
- output: `
223
+ }
224
+ }
225
+ }
226
+ const routes = ['/public/index.htm', '/public/index']
227
+
228
+ // check all routes by names
229
+
230
+ helper.arrange(t, options, (url) => {
231
+ for (const route of routes) {
232
+ t.test(route, t => {
233
+ t.plan(3)
234
+ simple.concat({
235
+ method: 'GET',
236
+ url: url + route
237
+ }, (err, response, body) => {
238
+ t.error(err)
239
+ t.equal(response.statusCode, 200)
240
+ t.equal(body.toString(), `
233
241
  <html><body>
234
242
  <ul>
235
243
  <li><a href="/public/deep">deep</a></li>
@@ -245,42 +253,11 @@ t.test('dir list html format', t => {
245
253
  <li><a href="/public/index.html" target="_blank">index.html</a></li>
246
254
  </ul>
247
255
  </body></html>
248
- `
249
- }
250
-
251
- ]
252
-
253
- for (const template of templates) {
254
- const options = {
255
- root: path.join(__dirname, '/static'),
256
- prefix: '/public',
257
- index: false,
258
- list: {
259
- format: 'html',
260
- names: ['index', 'index.htm'],
261
- render: template.render
262
- }
263
- }
264
- const routes = ['/public/index.htm', '/public/index']
265
-
266
- // check all routes by names
267
-
268
- helper.arrange(t, options, (url) => {
269
- for (const route of routes) {
270
- t.test(route, t => {
271
- t.plan(3)
272
- simple.concat({
273
- method: 'GET',
274
- url: url + route
275
- }, (err, response, body) => {
276
- t.error(err)
277
- t.equal(response.statusCode, 200)
278
- t.equal(body.toString(), template.output)
279
- })
256
+ `)
280
257
  })
281
- }
282
- })
283
- }
258
+ })
259
+ }
260
+ })
284
261
  })
285
262
 
286
263
  t.test('dir list href nested structure', t => {
@@ -471,7 +448,7 @@ t.test('dir list json format - extended info', t => {
471
448
  t.equal(response.statusCode, 200)
472
449
  const bodyObject = JSON.parse(body.toString())
473
450
  t.equal(bodyObject.dirs[0].name, 'empty')
474
- t.equal(typeof bodyObject.dirs[0].stats.atime, 'string')
451
+ t.equal(typeof bodyObject.dirs[0].stats.atimeMs, 'number')
475
452
  t.equal(typeof bodyObject.dirs[0].extendedInfo.totalSize, 'number')
476
453
  })
477
454
  })
@@ -845,7 +822,7 @@ t.test('dir list error', t => {
845
822
  const errorMessage = 'mocking send'
846
823
  dirList.send = async () => { throw new Error(errorMessage) }
847
824
 
848
- const mock = t.mock('..', {
825
+ const mock = t.mockRequire('..', {
849
826
  '../lib/dirList.js': dirList
850
827
  })
851
828
 
@@ -681,7 +681,7 @@ t.test('register /static with constraints', (t) => {
681
681
  })
682
682
  })
683
683
 
684
- t.test('payload.filename is set', (t) => {
684
+ t.test('payload.path is set', (t) => {
685
685
  t.plan(3)
686
686
 
687
687
  const pluginOptions = {
@@ -692,7 +692,7 @@ t.test('payload.filename is set', (t) => {
692
692
  let gotFilename
693
693
  fastify.register(fastifyStatic, pluginOptions)
694
694
  fastify.addHook('onSend', function (req, reply, payload, next) {
695
- gotFilename = payload.filename
695
+ gotFilename = payload.path
696
696
  next()
697
697
  })
698
698
 
@@ -1361,13 +1361,13 @@ t.test('root not found warning', (t) => {
1361
1361
  const destination = concat((data) => {
1362
1362
  t.equal(JSON.parse(data).msg, `"root" path "${rootPath}" must exist`)
1363
1363
  })
1364
- const logger = pino(
1364
+ const loggerInstance = pino(
1365
1365
  {
1366
1366
  level: 'warn'
1367
1367
  },
1368
1368
  destination
1369
1369
  )
1370
- const fastify = Fastify({ logger })
1370
+ const fastify = Fastify({ loggerInstance })
1371
1371
  fastify.register(fastifyStatic, pluginOptions)
1372
1372
  fastify.listen({ port: 0 }, (err) => {
1373
1373
  t.error(err)
package/types/index.d.ts CHANGED
@@ -16,7 +16,7 @@ declare module 'fastify' {
16
16
  }
17
17
  }
18
18
 
19
- type FastifyStaticPlugin = FastifyPluginAsync<NonNullable<fastifyStatic.FastifyStaticOptions>>;
19
+ type FastifyStaticPlugin = FastifyPluginAsync<NonNullable<fastifyStatic.FastifyStaticOptions>>
20
20
 
21
21
  declare namespace fastifyStatic {
22
22
  export interface SetHeadersResponse {
@@ -119,6 +119,6 @@ declare namespace fastifyStatic {
119
119
  export { fastifyStatic as default }
120
120
  }
121
121
 
122
- declare function fastifyStatic(...params: Parameters<FastifyStaticPlugin>): ReturnType<FastifyStaticPlugin>;
122
+ declare function fastifyStatic (...params: Parameters<FastifyStaticPlugin>): ReturnType<FastifyStaticPlugin>
123
123
 
124
- export = fastifyStatic;
124
+ export = fastifyStatic
@@ -8,7 +8,7 @@ import fastifyStatic, {
8
8
  fastifyStatic as fastifyStaticNamed
9
9
  } from '..'
10
10
 
11
- import fastifyStaticCjsImport = require('..');
11
+ import fastifyStaticCjsImport = require('..')
12
12
  const fastifyStaticCjs = require('..')
13
13
 
14
14
  const app: FastifyInstance = fastify()
@@ -1,10 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "es6",
4
- "lib": ["ES2018"],
5
- "module": "commonjs",
6
- "noEmit": true,
7
- "strict": true
8
- },
9
- "include": ["types/*.test-d.ts", "types/*.d.ts"]
10
- }