@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 +3 -1
- package/index.js +2 -2
- package/lib/dirList.js +4 -3
- package/package.json +1 -1
- package/test/dir-list.test.js +99 -10
- package/test/static.test.js +1 -1
- package/test/types/index.ts +1 -1
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
|
-
|
|
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
|
|
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
|
|
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
package/test/dir-list.test.js
CHANGED
|
@@ -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('
|
|
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.
|
|
620
|
+
t.equal(body.toString(), JSON.stringify(jsonContent))
|
|
532
621
|
t.ok(response.headers['content-type'].includes('application/json'))
|
|
533
622
|
})
|
|
534
623
|
})
|
package/test/static.test.js
CHANGED
|
@@ -2840,7 +2840,7 @@ t.test('routes should fallback to default errorHandler', t => {
|
|
|
2840
2840
|
})
|
|
2841
2841
|
})
|
|
2842
2842
|
|
|
2843
|
-
t.test('
|
|
2843
|
+
t.test('percent encoded URLs in glob mode', (t) => {
|
|
2844
2844
|
t.plan(4)
|
|
2845
2845
|
|
|
2846
2846
|
const fastify = Fastify({})
|