@fastify/static 6.4.1 → 6.5.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/.github/workflows/ci.yml +1 -0
- package/README.md +32 -13
- package/example/server-compress.js +1 -1
- package/example/server-dir-list.js +1 -1
- package/example/server.js +1 -1
- package/index.js +3 -1
- package/package.json +5 -5
- package/test/static/shallow/sample.jpg +0 -0
- package/test/static-pre-compressed/sample.jpg +0 -0
- package/test/static.test.js +52 -11
- package/{index.d.ts → types/index.d.ts} +3 -3
- package/{test/types/index.ts → types/index.test-d.ts} +15 -12
package/.github/workflows/ci.yml
CHANGED
package/README.md
CHANGED
|
@@ -4,19 +4,23 @@
|
|
|
4
4
|
[](https://www.npmjs.com/package/@fastify/static)
|
|
5
5
|
[](https://standardjs.com/)
|
|
6
6
|
|
|
7
|
-
Plugin for serving static files as fast as possible. Supports Fastify version `
|
|
7
|
+
Plugin for serving static files as fast as possible. Supports Fastify version `4.x`.
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
| Fastify version | branch |
|
|
10
|
+
| --------------- | -------------------------------------------------------------------- |
|
|
11
|
+
| `^4.x` | This branch |
|
|
12
|
+
| `^3.x` | [`v5.x`](https://github.com/fastify/fastify-static/tree/v5.x) |
|
|
13
|
+
| `^2.x` | [`2.x`](https://github.com/fastify/fastify-static/tree/2.x) |
|
|
14
|
+
| `^1.11.x` | [`1.x`](https://github.com/fastify/fastify-static/tree/1.x) |
|
|
11
15
|
|
|
12
16
|
## Install
|
|
13
17
|
|
|
14
|
-
`npm
|
|
18
|
+
`npm i @fastify/static`
|
|
15
19
|
|
|
16
20
|
## Usage
|
|
17
21
|
|
|
18
22
|
```js
|
|
19
|
-
const fastify = require('fastify')()
|
|
23
|
+
const fastify = require('fastify')({logger: true})
|
|
20
24
|
const path = require('path')
|
|
21
25
|
|
|
22
26
|
fastify.register(require('@fastify/static'), {
|
|
@@ -25,15 +29,25 @@ fastify.register(require('@fastify/static'), {
|
|
|
25
29
|
})
|
|
26
30
|
|
|
27
31
|
fastify.get('/another/path', function (req, reply) {
|
|
28
|
-
|
|
32
|
+
reply.sendFile('myHtml.html') // serving path.join(__dirname, 'public', 'myHtml.html') directly
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
fastify.get('/another/patch-async', async function (req, reply) {
|
|
36
|
+
return reply.sendFile('myHtml.html')
|
|
29
37
|
})
|
|
30
38
|
|
|
31
39
|
fastify.get('/path/with/different/root', function (req, reply) {
|
|
32
|
-
|
|
40
|
+
reply.sendFile('myHtml.html', path.join(__dirname, 'build')) // serving a file from a different root location
|
|
33
41
|
})
|
|
34
42
|
|
|
35
43
|
fastify.get('/another/path', function (req, reply) {
|
|
36
|
-
|
|
44
|
+
reply.sendFile('myHtml.html', { cacheControl: false }) // overriding the options disabling cache-control headers
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
// Run the server!
|
|
48
|
+
fastify.listen({ port: 3000 }, (err, address) => {
|
|
49
|
+
if (err) throw err
|
|
50
|
+
// Server is now listening on ${address}
|
|
37
51
|
})
|
|
38
52
|
```
|
|
39
53
|
|
|
@@ -69,15 +83,20 @@ fastify.register(require('@fastify/static'), {
|
|
|
69
83
|
})
|
|
70
84
|
|
|
71
85
|
fastify.get('/another/path', function (req, reply) {
|
|
72
|
-
|
|
86
|
+
reply.download('myHtml.html', 'custom-filename.html') // sending path.join(__dirname, 'public', 'myHtml.html') directly with custom filename
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
fastify.get('another/patch-async', async function (req, reply) {
|
|
90
|
+
// an async handler must always return the reply object
|
|
91
|
+
return reply.download('myHtml.html', 'custom-filename.html')
|
|
73
92
|
})
|
|
74
93
|
|
|
75
94
|
fastify.get('/path/without/cache/control', function (req, reply) {
|
|
76
|
-
|
|
95
|
+
reply.download('myHtml.html', { cacheControl: false }) // serving a file disabling cache-control headers
|
|
77
96
|
})
|
|
78
97
|
|
|
79
98
|
fastify.get('/path/without/cache/control', function (req, reply) {
|
|
80
|
-
|
|
99
|
+
reply.download('myHtml.html', 'custom-filename.html', { cacheControl: false })
|
|
81
100
|
})
|
|
82
101
|
|
|
83
102
|
```
|
|
@@ -169,9 +188,9 @@ with `ignoreTrailingSlash` set to `true`.
|
|
|
169
188
|
|
|
170
189
|
#### `allowedPath`
|
|
171
190
|
|
|
172
|
-
Default: `(
|
|
191
|
+
Default: `(pathName, root, request) => true`
|
|
173
192
|
|
|
174
|
-
This function allows filtering the served files.
|
|
193
|
+
This function allows filtering the served files. Also, with the help of the request object a more complex path authentication is possible.
|
|
175
194
|
If the function returns `true`, the file will be served.
|
|
176
195
|
If the function returns `false`, Fastify's 404 handler will be called.
|
|
177
196
|
|
package/example/server.js
CHANGED
package/index.js
CHANGED
|
@@ -72,7 +72,7 @@ async function fastifyStatic (fastify, opts) {
|
|
|
72
72
|
}
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
-
if (allowedPath && !allowedPath(pathname, options.root)) {
|
|
75
|
+
if (allowedPath && !allowedPath(pathname, options.root, request)) {
|
|
76
76
|
return reply.callNotFound()
|
|
77
77
|
}
|
|
78
78
|
|
|
@@ -518,3 +518,5 @@ module.exports = fp(fastifyStatic, {
|
|
|
518
518
|
fastify: '4.x',
|
|
519
519
|
name: '@fastify/static'
|
|
520
520
|
})
|
|
521
|
+
module.exports.default = fastifyStatic
|
|
522
|
+
module.exports.fastifyStatic = fastifyStatic
|
package/package.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fastify/static",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.5.1",
|
|
4
4
|
"description": "Plugin for serving static files as fast as possible.",
|
|
5
5
|
"main": "index.js",
|
|
6
|
-
"types": "index.d.ts",
|
|
6
|
+
"types": "types/index.d.ts",
|
|
7
7
|
"scripts": {
|
|
8
8
|
"lint": "standard | snazzy",
|
|
9
9
|
"lint:fix": "standard --fix",
|
|
@@ -39,6 +39,7 @@
|
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
|
41
41
|
"@fastify/compress": "^6.0.0",
|
|
42
|
+
"@fastify/pre-commit": "^2.0.2",
|
|
42
43
|
"@types/node": "^18.0.0",
|
|
43
44
|
"@typescript-eslint/eslint-plugin": "^2.29.0",
|
|
44
45
|
"@typescript-eslint/parser": "^2.29.0",
|
|
@@ -47,14 +48,13 @@
|
|
|
47
48
|
"eslint-plugin-typescript": "^0.14.0",
|
|
48
49
|
"fastify": "^4.0.0-rc.2",
|
|
49
50
|
"handlebars": "^4.7.6",
|
|
50
|
-
"
|
|
51
|
+
"pino": "^8.4.2",
|
|
51
52
|
"proxyquire": "^2.1.0",
|
|
52
53
|
"simple-get": "^4.0.0",
|
|
53
54
|
"snazzy": "^9.0.0",
|
|
54
55
|
"standard": "^17.0.0",
|
|
55
56
|
"tap": "^16.0.0",
|
|
56
|
-
"tsd": "^0.
|
|
57
|
-
"typescript": "^4.0.2"
|
|
57
|
+
"tsd": "^0.24.1"
|
|
58
58
|
},
|
|
59
59
|
"tsd": {
|
|
60
60
|
"directory": "test/types"
|
|
Binary file
|
|
Binary file
|
package/test/static.test.js
CHANGED
|
@@ -808,7 +808,7 @@ t.test('serving disabled', (t) => {
|
|
|
808
808
|
fastify.register(fastifyStatic, pluginOptions)
|
|
809
809
|
|
|
810
810
|
fastify.get('/foo/bar', (request, reply) => {
|
|
811
|
-
|
|
811
|
+
reply.sendFile('index.html')
|
|
812
812
|
})
|
|
813
813
|
|
|
814
814
|
t.teardown(fastify.close.bind(fastify))
|
|
@@ -856,18 +856,18 @@ t.test('sendFile', (t) => {
|
|
|
856
856
|
fastify.register(fastifyStatic, pluginOptions)
|
|
857
857
|
|
|
858
858
|
fastify.get('/foo/bar', function (req, reply) {
|
|
859
|
-
|
|
859
|
+
reply.sendFile('/index.html')
|
|
860
860
|
})
|
|
861
861
|
|
|
862
862
|
fastify.get('/root/path/override/test', (request, reply) => {
|
|
863
|
-
|
|
863
|
+
reply.sendFile(
|
|
864
864
|
'/foo.html',
|
|
865
865
|
path.join(__dirname, 'static', 'deep', 'path', 'for', 'test', 'purpose')
|
|
866
866
|
)
|
|
867
867
|
})
|
|
868
868
|
|
|
869
869
|
fastify.get('/foo/bar/options/override/test', function (req, reply) {
|
|
870
|
-
|
|
870
|
+
reply.sendFile('/index.html', { maxAge })
|
|
871
871
|
})
|
|
872
872
|
|
|
873
873
|
fastify.listen({ port: 0 }, (err) => {
|
|
@@ -973,7 +973,7 @@ t.test('sendFile disabled', (t) => {
|
|
|
973
973
|
})
|
|
974
974
|
})
|
|
975
975
|
|
|
976
|
-
t.test('allowedPath option', (t) => {
|
|
976
|
+
t.test('allowedPath option - pathname', (t) => {
|
|
977
977
|
t.plan(3)
|
|
978
978
|
|
|
979
979
|
const pluginOptions = {
|
|
@@ -1014,6 +1014,47 @@ t.test('allowedPath option', (t) => {
|
|
|
1014
1014
|
})
|
|
1015
1015
|
})
|
|
1016
1016
|
|
|
1017
|
+
t.test('allowedPath option - request', (t) => {
|
|
1018
|
+
t.plan(3)
|
|
1019
|
+
|
|
1020
|
+
const pluginOptions = {
|
|
1021
|
+
root: path.join(__dirname, '/static'),
|
|
1022
|
+
allowedPath: (pathName, root, request) => request.query.key === 'temporaryKey'
|
|
1023
|
+
}
|
|
1024
|
+
const fastify = Fastify()
|
|
1025
|
+
fastify.register(fastifyStatic, pluginOptions)
|
|
1026
|
+
fastify.listen({ port: 0 }, (err) => {
|
|
1027
|
+
t.error(err)
|
|
1028
|
+
|
|
1029
|
+
fastify.server.unref()
|
|
1030
|
+
|
|
1031
|
+
t.test('/foobar.html not found', (t) => {
|
|
1032
|
+
t.plan(2 + GENERIC_ERROR_RESPONSE_CHECK_COUNT)
|
|
1033
|
+
simple.concat({
|
|
1034
|
+
method: 'GET',
|
|
1035
|
+
url: 'http://localhost:' + fastify.server.address().port + '/foobar.html',
|
|
1036
|
+
followRedirect: false
|
|
1037
|
+
}, (err, response, body) => {
|
|
1038
|
+
t.error(err)
|
|
1039
|
+
t.equal(response.statusCode, 404)
|
|
1040
|
+
genericErrorResponseChecks(t, response)
|
|
1041
|
+
})
|
|
1042
|
+
})
|
|
1043
|
+
|
|
1044
|
+
t.test('/index.css found', (t) => {
|
|
1045
|
+
t.plan(2)
|
|
1046
|
+
simple.concat({
|
|
1047
|
+
method: 'GET',
|
|
1048
|
+
url: 'http://localhost:' + fastify.server.address().port + '/index.css?key=temporaryKey',
|
|
1049
|
+
followRedirect: false
|
|
1050
|
+
}, (err, response, body) => {
|
|
1051
|
+
t.error(err)
|
|
1052
|
+
t.equal(response.statusCode, 200)
|
|
1053
|
+
})
|
|
1054
|
+
})
|
|
1055
|
+
})
|
|
1056
|
+
})
|
|
1057
|
+
|
|
1017
1058
|
t.test('download', (t) => {
|
|
1018
1059
|
t.plan(7)
|
|
1019
1060
|
|
|
@@ -1025,26 +1066,26 @@ t.test('download', (t) => {
|
|
|
1025
1066
|
fastify.register(fastifyStatic, pluginOptions)
|
|
1026
1067
|
|
|
1027
1068
|
fastify.get('/foo/bar', function (req, reply) {
|
|
1028
|
-
|
|
1069
|
+
reply.download('/index.html')
|
|
1029
1070
|
})
|
|
1030
1071
|
|
|
1031
1072
|
fastify.get('/foo/bar/change', function (req, reply) {
|
|
1032
|
-
|
|
1073
|
+
reply.download('/index.html', 'hello-world.html')
|
|
1033
1074
|
})
|
|
1034
1075
|
|
|
1035
1076
|
fastify.get('/foo/bar/override', function (req, reply) {
|
|
1036
|
-
|
|
1077
|
+
reply.download('/index.html', 'hello-world.html', {
|
|
1037
1078
|
maxAge: '2 hours',
|
|
1038
1079
|
immutable: true
|
|
1039
1080
|
})
|
|
1040
1081
|
})
|
|
1041
1082
|
|
|
1042
1083
|
fastify.get('/foo/bar/override/2', function (req, reply) {
|
|
1043
|
-
|
|
1084
|
+
reply.download('/index.html', { acceptRanges: false })
|
|
1044
1085
|
})
|
|
1045
1086
|
|
|
1046
1087
|
fastify.get('/root/path/override/test', (request, reply) => {
|
|
1047
|
-
|
|
1088
|
+
reply.download('/foo.html', {
|
|
1048
1089
|
root: path.join(
|
|
1049
1090
|
__dirname,
|
|
1050
1091
|
'static',
|
|
@@ -1058,7 +1099,7 @@ t.test('download', (t) => {
|
|
|
1058
1099
|
})
|
|
1059
1100
|
|
|
1060
1101
|
fastify.get('/root/path/override/test/change', (request, reply) => {
|
|
1061
|
-
|
|
1102
|
+
reply.download('/foo.html', 'hello-world.html', {
|
|
1062
1103
|
root: path.join(
|
|
1063
1104
|
__dirname,
|
|
1064
1105
|
'static',
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// Leo <https://github.com/leomelzer>
|
|
3
3
|
/// <reference types="node" />
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { FastifyPluginAsync, FastifyRequest } from 'fastify';
|
|
6
6
|
import { Stats } from 'fs';
|
|
7
7
|
|
|
8
8
|
declare module "fastify" {
|
|
@@ -16,7 +16,7 @@ declare module "fastify" {
|
|
|
16
16
|
}
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
type FastifyStaticPlugin =
|
|
19
|
+
type FastifyStaticPlugin = FastifyPluginAsync<NonNullable<fastifyStatic.FastifyStaticOptions>>;
|
|
20
20
|
|
|
21
21
|
declare namespace fastifyStatic {
|
|
22
22
|
export interface ExtendedInformation {
|
|
@@ -86,7 +86,7 @@ declare namespace fastifyStatic {
|
|
|
86
86
|
redirect?: boolean;
|
|
87
87
|
wildcard?: boolean;
|
|
88
88
|
list?: boolean | ListOptionsJsonFormat | ListOptionsHtmlFormat;
|
|
89
|
-
allowedPath?: (pathName: string, root
|
|
89
|
+
allowedPath?: (pathName: string, root: string, request: FastifyRequest) => boolean;
|
|
90
90
|
/**
|
|
91
91
|
* @description
|
|
92
92
|
* Opt-in to looking for pre-compressed files
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import fastify, { FastifyInstance,
|
|
1
|
+
import fastify, { FastifyInstance, FastifyPluginAsync, FastifyRequest } from 'fastify'
|
|
2
2
|
import { Server } from 'http';
|
|
3
3
|
import { expectAssignable, expectError, expectType } from 'tsd'
|
|
4
|
-
import * as fastifyStaticStar from '
|
|
4
|
+
import * as fastifyStaticStar from '..';
|
|
5
5
|
import fastifyStatic, {
|
|
6
6
|
FastifyStaticOptions,
|
|
7
7
|
fastifyStatic as fastifyStaticNamed,
|
|
8
|
-
} from '
|
|
8
|
+
} from '..'
|
|
9
9
|
|
|
10
|
-
import fastifyStaticCjsImport = require('
|
|
11
|
-
const fastifyStaticCjs = require('
|
|
10
|
+
import fastifyStaticCjsImport = require('..');
|
|
11
|
+
const fastifyStaticCjs = require('..');
|
|
12
12
|
|
|
13
13
|
const app: FastifyInstance = fastify();
|
|
14
14
|
|
|
@@ -20,12 +20,12 @@ app.register(fastifyStaticCjsImport.fastifyStatic);
|
|
|
20
20
|
app.register(fastifyStaticStar.default);
|
|
21
21
|
app.register(fastifyStaticStar.fastifyStatic);
|
|
22
22
|
|
|
23
|
-
expectType<
|
|
24
|
-
expectType<
|
|
25
|
-
expectType<
|
|
26
|
-
expectType<
|
|
27
|
-
expectType<
|
|
28
|
-
expectType<
|
|
23
|
+
expectType<FastifyPluginAsync<FastifyStaticOptions, Server>>(fastifyStatic);
|
|
24
|
+
expectType<FastifyPluginAsync<FastifyStaticOptions, Server>>(fastifyStaticNamed);
|
|
25
|
+
expectType<FastifyPluginAsync<FastifyStaticOptions, Server>>(fastifyStaticCjsImport.default);
|
|
26
|
+
expectType<FastifyPluginAsync<FastifyStaticOptions, Server>>(fastifyStaticCjsImport.fastifyStatic);
|
|
27
|
+
expectType<FastifyPluginAsync<FastifyStaticOptions, Server>>(fastifyStaticStar.default);
|
|
28
|
+
expectType<FastifyPluginAsync<FastifyStaticOptions, Server>>(
|
|
29
29
|
fastifyStaticStar.fastifyStatic
|
|
30
30
|
);
|
|
31
31
|
expectType<any>(fastifyStaticCjs);
|
|
@@ -52,7 +52,10 @@ const options: FastifyStaticOptions = {
|
|
|
52
52
|
setHeaders: (res: any, pathName: any) => {
|
|
53
53
|
res.setHeader('test', pathName)
|
|
54
54
|
},
|
|
55
|
-
preCompressed: false
|
|
55
|
+
preCompressed: false,
|
|
56
|
+
allowedPath: (pathName: string, root: string, request: FastifyRequest) => {
|
|
57
|
+
return true;
|
|
58
|
+
}
|
|
56
59
|
}
|
|
57
60
|
|
|
58
61
|
expectError<FastifyStaticOptions>({
|