@fastify/static 6.3.0 → 6.4.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.
package/index.d.ts CHANGED
@@ -45,11 +45,13 @@ interface ListRender {
45
45
  interface ListOptions {
46
46
  names?: string[];
47
47
  extendedFolderInfo?: boolean;
48
+ jsonFormat?: 'names' | 'extended';
48
49
  }
49
50
 
50
51
  interface ListOptionsJsonFormat extends ListOptions {
51
52
  format: 'json';
52
- jsonFormat?: 'names' | 'extended';
53
+ // Required when the URL parameter `format=html` exists
54
+ render?: ListRender;
53
55
  }
54
56
 
55
57
  interface ListOptionsHtmlFormat extends ListOptions {
package/index.js CHANGED
@@ -195,7 +195,7 @@ async function fastifyStatic (fastify, opts) {
195
195
 
196
196
  stream.on('error', function (err) {
197
197
  if (err.code === 'ENOENT') {
198
- // when preCompress is enabled and the path is a directoy without a trailing shash
198
+ // when preCompress is enabled and the path is a directory without a trailing slash
199
199
  if (opts.preCompressed && encoding) {
200
200
  const indexPathname = findIndexFile(pathname, options.root, options.index)
201
201
  if (indexPathname) {
@@ -494,7 +494,7 @@ function getEncodingExtension (encoding) {
494
494
 
495
495
  function getRedirectUrl (url) {
496
496
  let i = 0
497
- // we detech how many slash before a valid path
497
+ // we detect how many slash before a valid path
498
498
  for (i; i < url.length; i++) {
499
499
  if (url[i] !== '/' && url[i] !== '\\') break
500
500
  }
package/lib/dirList.js CHANGED
@@ -104,6 +104,10 @@ const dirList = {
104
104
  * @param {string} dotfiles
105
105
  */
106
106
  send: async function ({ reply, dir, options, route, prefix, dotfiles }) {
107
+ if (reply.request.query.format === 'html' && typeof options.render !== 'function') {
108
+ throw new Error('The `list.render` option must be a function and is required with the URL parameter `format=html`')
109
+ }
110
+
107
111
  let entries
108
112
  try {
109
113
  entries = await dirList.list(dir, options, dotfiles)
@@ -200,9 +204,6 @@ const dirList = {
200
204
  if (options.list.format === 'html' && typeof options.list.render !== 'function') {
201
205
  return new TypeError('The `list.render` option must be a function and is required with html format')
202
206
  }
203
- if (options.list.format === 'html' && options.list.jsonFormat != null) {
204
- return new TypeError('The `list.jsonFormat` option must be with json format')
205
- }
206
207
  }
207
208
 
208
209
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fastify/static",
3
- "version": "6.3.0",
3
+ "version": "6.4.0",
4
4
  "description": "Plugin for serving static files as fast as possible.",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -72,14 +72,6 @@ t.test('throws when `list.format` is html and `list render` is not a function',
72
72
  t.equal(err.message, 'The `list.render` option must be a function and is required with html format')
73
73
  })
74
74
 
75
- t.test('throws when `list.format` is html and `list.jsonFormat` is given', t => {
76
- t.plan(2)
77
-
78
- const err = dirList.validateOptions({ list: { format: 'html', render: () => '', jsonFormat: 'extended' } })
79
- t.type(err, TypeError)
80
- t.equal(err.message, 'The `list.jsonFormat` option must be with json format')
81
- })
82
-
83
75
  t.test('dir list wrong options', t => {
84
76
  t.plan(3)
85
77
 
@@ -485,7 +477,103 @@ t.test('dir list json format - extended info', t => {
485
477
  })
486
478
  })
487
479
 
488
- t.test('dir list - url parameter format', t => {
480
+ t.test('json format with url parameter format', t => {
481
+ t.plan(13)
482
+
483
+ const options = {
484
+ root: path.join(__dirname, '/static'),
485
+ prefix: '/public',
486
+ index: false,
487
+ list: {
488
+ format: 'json',
489
+ render (dirs, files) {
490
+ return 'html'
491
+ }
492
+ }
493
+ }
494
+ const route = '/public/'
495
+ const jsonContent = { dirs: ['deep', 'shallow'], files: ['.example', 'a .md', 'foo.html', 'foobar.html', 'index.css', 'index.html'] }
496
+
497
+ helper.arrange(t, options, (url) => {
498
+ simple.concat({
499
+ method: 'GET',
500
+ url: url + route
501
+ }, (err, response, body) => {
502
+ t.error(err)
503
+ t.equal(response.statusCode, 200)
504
+ t.equal(body.toString(), JSON.stringify(jsonContent))
505
+ t.ok(response.headers['content-type'].includes('application/json'))
506
+ })
507
+
508
+ simple.concat({
509
+ method: 'GET',
510
+ url: url + route + '?format=html'
511
+ }, (err, response, body) => {
512
+ t.error(err)
513
+ t.equal(response.statusCode, 200)
514
+ t.equal(body.toString(), 'html')
515
+ t.ok(response.headers['content-type'].includes('text/html'))
516
+ })
517
+
518
+ simple.concat({
519
+ method: 'GET',
520
+ url: url + route + '?format=json'
521
+ }, (err, response, body) => {
522
+ t.error(err)
523
+ t.equal(response.statusCode, 200)
524
+ t.equal(body.toString(), JSON.stringify(jsonContent))
525
+ t.ok(response.headers['content-type'].includes('application/json'))
526
+ })
527
+ })
528
+ })
529
+
530
+ t.test('json format with url parameter format and without render option', t => {
531
+ t.plan(12)
532
+
533
+ const options = {
534
+ root: path.join(__dirname, '/static'),
535
+ prefix: '/public',
536
+ index: false,
537
+ list: {
538
+ format: 'json'
539
+ }
540
+ }
541
+ const route = '/public/'
542
+ const jsonContent = { dirs: ['deep', 'shallow'], files: ['.example', 'a .md', 'foo.html', 'foobar.html', 'index.css', 'index.html'] }
543
+
544
+ helper.arrange(t, options, (url) => {
545
+ simple.concat({
546
+ method: 'GET',
547
+ url: url + route
548
+ }, (err, response, body) => {
549
+ t.error(err)
550
+ t.equal(response.statusCode, 200)
551
+ t.equal(body.toString(), JSON.stringify(jsonContent))
552
+ t.ok(response.headers['content-type'].includes('application/json'))
553
+ })
554
+
555
+ simple.concat({
556
+ method: 'GET',
557
+ url: url + route + '?format=html'
558
+ }, (err, response, body) => {
559
+ t.error(err)
560
+ t.equal(response.statusCode, 500)
561
+ t.equal(JSON.parse(body.toString()).message, 'The `list.render` option must be a function and is required with the URL parameter `format=html`')
562
+ })
563
+
564
+ simple.concat({
565
+ method: 'GET',
566
+ url: url + route + '?format=json'
567
+ }, (err, response, body) => {
568
+ t.error(err)
569
+ t.equal(response.statusCode, 200)
570
+ t.equal(body.toString(), JSON.stringify(jsonContent))
571
+ t.ok(response.headers['content-type'].includes('application/json'))
572
+ })
573
+ })
574
+ })
575
+
576
+ t.test('html format with url parameter format', t => {
489
577
  t.plan(13)
490
578
 
491
579
  const options = {
@@ -500,6 +588,7 @@ t.test('dir list - url parameter format', t => {
500
588
  }
501
589
  }
502
590
  const route = '/public/'
591
+ const jsonContent = { dirs: ['deep', 'shallow'], files: ['.example', 'a .md', 'foo.html', 'foobar.html', 'index.css', 'index.html'] }
503
592
 
504
593
  helper.arrange(t, options, (url) => {
505
594
  simple.concat({
@@ -528,7 +617,7 @@ t.test('dir list - url parameter format', t => {
528
617
  }, (err, response, body) => {
529
618
  t.error(err)
530
619
  t.equal(response.statusCode, 200)
531
- t.ok(body.toString())
620
+ t.equal(body.toString(), JSON.stringify(jsonContent))
532
621
  t.ok(response.headers['content-type'].includes('application/json'))
533
622
  })
534
623
  })
@@ -2840,7 +2840,7 @@ t.test('routes should fallback to default errorHandler', t => {
2840
2840
  })
2841
2841
  })
2842
2842
 
2843
- t.test('precent encoded URLs in glob mode', (t) => {
2843
+ t.test('percent encoded URLs in glob mode', (t) => {
2844
2844
  t.plan(4)
2845
2845
 
2846
2846
  const fastify = Fastify({})
@@ -39,7 +39,7 @@ expectAssignable<FastifyStaticOptions>({
39
39
  }
40
40
  })
41
41
 
42
- expectError<FastifyStaticOptions>({
42
+ expectAssignable<FastifyStaticOptions>({
43
43
  root: '',
44
44
  list: {
45
45
  format: 'json',