@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.
@@ -14,4 +14,5 @@ jobs:
14
14
  test:
15
15
  uses: fastify/workflows/.github/workflows/plugins-ci.yml@v3
16
16
  with:
17
+ license-check: true
17
18
  lint: true
package/README.md CHANGED
@@ -4,19 +4,23 @@
4
4
  [![NPM version](https://img.shields.io/npm/v/@fastify/static.svg?style=flat)](https://www.npmjs.com/package/@fastify/static)
5
5
  [![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat)](https://standardjs.com/)
6
6
 
7
- Plugin for serving static files as fast as possible. Supports Fastify version `3.x`.
7
+ Plugin for serving static files as fast as possible. Supports Fastify version `4.x`.
8
8
 
9
- Please refer to [this branch](https://github.com/fastify/fastify-static/tree/2.x) and related versions for Fastify `^2.0.0` compatibility.
10
- Please refer to [this branch](https://github.com/fastify/fastify-static/tree/1.x) and related versions for Fastify `^1.11.0` compatibility.
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 install --save @fastify/static`
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
- return reply.sendFile('myHtml.html') // serving path.join(__dirname, 'public', 'myHtml.html') directly
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
- return reply.sendFile('myHtml.html', path.join(__dirname, 'build')) // serving a file from a different root location
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
- return reply.sendFile('myHtml.html', { cacheControl: false }) // overriding the options disabling cache-control headers
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
- return reply.download('myHtml.html', 'custom-filename.html') // sending path.join(__dirname, 'public', 'myHtml.html') directly with custom filename
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
- return reply.download('myHtml.html', { cacheControl: false }) // serving a file disabling cache-control headers
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
- return reply.download('myHtml.html', 'custom-filename.html', { cacheControl: false })
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: `(pathname, root) => true`
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
 
@@ -10,6 +10,6 @@ fastify
10
10
  // An absolute path containing static files to serve.
11
11
  root: path.join(__dirname, '/public')
12
12
  })
13
- .listen(3000, err => {
13
+ .listen({ port: 3000 }, err => {
14
14
  if (err) throw err
15
15
  })
@@ -44,6 +44,6 @@ fastify
44
44
  render: (dirs, files) => handlebarTemplate({ dirs, files })
45
45
  }
46
46
  })
47
- .listen(3000, err => {
47
+ .listen({ port: 3000 }, err => {
48
48
  if (err) throw err
49
49
  })
package/example/server.js CHANGED
@@ -8,6 +8,6 @@ fastify
8
8
  // An absolute path containing static files to serve.
9
9
  root: path.join(__dirname, '/public')
10
10
  })
11
- .listen(3000, err => {
11
+ .listen({ port: 3000 }, err => {
12
12
  if (err) throw err
13
13
  })
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.4.1",
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
- "pre-commit": "^1.2.2",
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.22.0",
57
- "typescript": "^4.0.2"
57
+ "tsd": "^0.24.1"
58
58
  },
59
59
  "tsd": {
60
60
  "directory": "test/types"
Binary file
@@ -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
- return reply.sendFile('index.html')
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
- return reply.sendFile('/index.html')
859
+ reply.sendFile('/index.html')
860
860
  })
861
861
 
862
862
  fastify.get('/root/path/override/test', (request, reply) => {
863
- return reply.sendFile(
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
- return reply.sendFile('/index.html', { maxAge })
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
- return reply.download('/index.html')
1069
+ reply.download('/index.html')
1029
1070
  })
1030
1071
 
1031
1072
  fastify.get('/foo/bar/change', function (req, reply) {
1032
- return reply.download('/index.html', 'hello-world.html')
1073
+ reply.download('/index.html', 'hello-world.html')
1033
1074
  })
1034
1075
 
1035
1076
  fastify.get('/foo/bar/override', function (req, reply) {
1036
- return reply.download('/index.html', 'hello-world.html', {
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
- return reply.download('/index.html', { acceptRanges: false })
1084
+ reply.download('/index.html', { acceptRanges: false })
1044
1085
  })
1045
1086
 
1046
1087
  fastify.get('/root/path/override/test', (request, reply) => {
1047
- return reply.download('/foo.html', {
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
- return reply.download('/foo.html', 'hello-world.html', {
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 { FastifyPluginCallback, FastifyReply } from 'fastify';
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 = FastifyPluginCallback<NonNullable<fastifyStatic.FastifyStaticOptions>>;
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?: string) => boolean;
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, FastifyPluginCallback } from 'fastify'
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<FastifyPluginCallback<FastifyStaticOptions, Server>>(fastifyStatic);
24
- expectType<FastifyPluginCallback<FastifyStaticOptions, Server>>(fastifyStaticNamed);
25
- expectType<FastifyPluginCallback<FastifyStaticOptions, Server>>(fastifyStaticCjsImport.default);
26
- expectType<FastifyPluginCallback<FastifyStaticOptions, Server>>(fastifyStaticCjsImport.fastifyStatic);
27
- expectType<FastifyPluginCallback<FastifyStaticOptions, Server>>(fastifyStaticStar.default);
28
- expectType<FastifyPluginCallback<FastifyStaticOptions, Server>>(
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>({