@fastify/static 8.3.0 → 9.1.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.
@@ -27,7 +27,7 @@ jobs:
27
27
  permissions:
28
28
  contents: write
29
29
  pull-requests: write
30
- uses: fastify/workflows/.github/workflows/plugins-ci.yml@v5
30
+ uses: fastify/workflows/.github/workflows/plugins-ci.yml@v6
31
31
  with:
32
32
  license-check: true
33
33
  lint: true
package/LICENSE CHANGED
@@ -1,8 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2017-present The Fastify team
4
-
5
- The Fastify team members are listed at https://github.com/fastify/fastify#team.
3
+ Copyright (c) 2017-present The Fastify team <https://github.com/fastify/fastify#team>
6
4
 
7
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
8
6
  of this software and associated documentation files (the "Software"), to deal
package/index.js CHANGED
@@ -274,7 +274,7 @@ async function fastifyStatic (fastify, opts) {
274
274
  pathname + '/',
275
275
  rootPath,
276
276
  undefined,
277
- undefined,
277
+ pumpOptions,
278
278
  checkedEncodings
279
279
  )
280
280
  }
@@ -314,7 +314,7 @@ async function fastifyStatic (fastify, opts) {
314
314
  pathname + '/',
315
315
  rootPath,
316
316
  undefined,
317
- undefined,
317
+ pumpOptions,
318
318
  checkedEncodings
319
319
  )
320
320
  }
@@ -336,7 +336,15 @@ async function fastifyStatic (fastify, opts) {
336
336
 
337
337
  // root paths left to try?
338
338
  if (Array.isArray(rootPath) && rootPathOffset < (rootPath.length - 1)) {
339
- return pumpSendToReply(request, reply, pathname, rootPath, rootPathOffset + 1)
339
+ return pumpSendToReply(
340
+ request,
341
+ reply,
342
+ pathname,
343
+ rootPath,
344
+ rootPathOffset + 1,
345
+ pumpOptions,
346
+ undefined
347
+ )
340
348
  }
341
349
 
342
350
  if (opts.preCompressed && !checkedEncodings.has(encoding)) {
@@ -347,7 +355,7 @@ async function fastifyStatic (fastify, opts) {
347
355
  pathnameOrig,
348
356
  rootPath,
349
357
  rootPathOffset,
350
- undefined,
358
+ pumpOptions,
351
359
  checkedEncodings
352
360
  )
353
361
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fastify/static",
3
- "version": "8.3.0",
3
+ "version": "9.1.0",
4
4
  "description": "Plugin for serving static files as fast as possible.",
5
5
  "main": "index.js",
6
6
  "type": "commonjs",
@@ -60,21 +60,21 @@
60
60
  "dependencies": {
61
61
  "@fastify/accept-negotiator": "^2.0.0",
62
62
  "@fastify/send": "^4.0.0",
63
- "content-disposition": "^0.5.4",
63
+ "content-disposition": "^1.0.1",
64
64
  "fastify-plugin": "^5.0.0",
65
65
  "fastq": "^1.17.1",
66
- "glob": "^11.0.0"
66
+ "glob": "^13.0.0"
67
67
  },
68
68
  "devDependencies": {
69
69
  "@fastify/compress": "^8.0.0",
70
- "@types/node": "^24.0.13",
71
- "borp": "^0.20.0",
72
- "c8": "^10.1.3",
70
+ "@types/node": "^25.0.3",
71
+ "borp": "^1.0.0",
72
+ "c8": "^11.0.0",
73
73
  "concat-stream": "^2.0.0",
74
74
  "eslint": "^9.17.0",
75
75
  "fastify": "^5.1.0",
76
76
  "neostandard": "^0.12.0",
77
- "pino": "^9.1.0",
77
+ "pino": "^10.0.0",
78
78
  "proxyquire": "^2.1.3",
79
79
  "tsd": "^0.33.0"
80
80
  },
@@ -870,6 +870,83 @@ test('sendFile', async (t) => {
870
870
  })
871
871
  })
872
872
 
873
+ test('sendFile with multiple roots', async (t) => {
874
+ t.plan(4)
875
+
876
+ const pluginOptions = {
877
+ root: [path.join(__dirname, '/static'), path.join(__dirname, '/static2')],
878
+ prefix: '/static'
879
+ }
880
+ const fastify = Fastify()
881
+ const maxAge = Math.round(Math.random() * 10) * 10000
882
+ fastify.register(fastifyStatic, pluginOptions)
883
+
884
+ t.after(() => fastify.close())
885
+
886
+ fastify.get('/foo', function (_req, rep) {
887
+ rep.sendFile('foo.html')
888
+ })
889
+
890
+ fastify.get('/foo-with-options', function (_req, rep) {
891
+ rep.sendFile('foo.html', { maxAge })
892
+ })
893
+
894
+ fastify.get('/bar', function (_req, rep) {
895
+ rep.sendFile('bar.html')
896
+ })
897
+
898
+ fastify.get('/bar-with-options', function (_req, rep) {
899
+ rep.sendFile('bar.html', { maxAge })
900
+ })
901
+
902
+ await fastify.listen({ port: 0 })
903
+ fastify.server.unref()
904
+
905
+ await t.test('reply.sendFile() first root', async (t) => {
906
+ t.plan(4 + GENERIC_RESPONSE_CHECK_COUNT)
907
+
908
+ const response = await fetch('http://localhost:' + fastify.server.address().port + '/foo')
909
+ t.assert.ok(response.ok)
910
+ t.assert.deepStrictEqual(response.status, 200)
911
+ t.assert.deepStrictEqual(await response.text(), fooContent)
912
+ t.assert.deepStrictEqual(response.headers.get('cache-control'), 'public, max-age=0')
913
+ genericResponseChecks(t, response)
914
+ })
915
+
916
+ await t.test('reply.sendFile() first root with options', async (t) => {
917
+ t.plan(4 + GENERIC_RESPONSE_CHECK_COUNT)
918
+
919
+ const response = await fetch('http://localhost:' + fastify.server.address().port + '/foo-with-options')
920
+ t.assert.ok(response.ok)
921
+ t.assert.deepStrictEqual(response.status, 200)
922
+ t.assert.deepStrictEqual(await response.text(), fooContent)
923
+ t.assert.deepStrictEqual(response.headers.get('cache-control'), `public, max-age=${maxAge / 1000}`)
924
+ genericResponseChecks(t, response)
925
+ })
926
+
927
+ await t.test('reply.sendFile() second root', async (t) => {
928
+ t.plan(4 + GENERIC_RESPONSE_CHECK_COUNT)
929
+
930
+ const response = await fetch('http://localhost:' + fastify.server.address().port + '/bar')
931
+ t.assert.ok(response.ok)
932
+ t.assert.deepStrictEqual(response.status, 200)
933
+ t.assert.deepStrictEqual(await response.text(), barContent)
934
+ t.assert.deepStrictEqual(response.headers.get('cache-control'), 'public, max-age=0')
935
+ genericResponseChecks(t, response)
936
+ })
937
+
938
+ await t.test('reply.sendFile() second root with options', async (t) => {
939
+ t.plan(4 + GENERIC_RESPONSE_CHECK_COUNT)
940
+
941
+ const response = await fetch('http://localhost:' + fastify.server.address().port + '/bar-with-options')
942
+ t.assert.ok(response.ok)
943
+ t.assert.deepStrictEqual(response.status, 200)
944
+ t.assert.deepStrictEqual(await response.text(), barContent)
945
+ t.assert.deepStrictEqual(response.headers.get('cache-control'), `public, max-age=${maxAge / 1000}`)
946
+ genericResponseChecks(t, response)
947
+ })
948
+ })
949
+
873
950
  test('sendFile disabled', async (t) => {
874
951
  t.plan(1)
875
952
 
@@ -1438,7 +1515,7 @@ test('register no prefix', async (t) => {
1438
1515
  })
1439
1516
  })
1440
1517
 
1441
- test('with fastify-compress', async t => {
1518
+ test('with fastify-compress', { timeout: 60000 }, async t => {
1442
1519
  t.plan(2)
1443
1520
 
1444
1521
  const pluginOptions = {
@@ -1476,6 +1553,7 @@ test('with fastify-compress', async t => {
1476
1553
  genericResponseChecks(t, response)
1477
1554
  })
1478
1555
  })
1556
+
1479
1557
  test('register /static/ with schemaHide true', async t => {
1480
1558
  t.plan(2)
1481
1559
 
@@ -1712,7 +1790,9 @@ test('register with wildcard false (trailing slash in the root)', async t => {
1712
1790
  wildcard: false
1713
1791
  }
1714
1792
  const fastify = Fastify({
1715
- ignoreTrailingSlash: true
1793
+ routerOptions: {
1794
+ ignoreTrailingSlash: true
1795
+ }
1716
1796
  })
1717
1797
  fastify.register(fastifyStatic, pluginOptions)
1718
1798
 
package/types/index.d.ts CHANGED
@@ -1,7 +1,3 @@
1
- // Definitions by: Jannik <https://github.com/jannikkeye>
2
- // Leo <https://github.com/leomelzer>
3
- /// <reference types="node" />
4
-
5
1
  import { FastifyPluginAsync, FastifyReply, FastifyRequest, RouteOptions } from 'fastify'
6
2
  import { Stats } from 'node:fs'
7
3
 
@@ -8,7 +8,7 @@ import fastifyStatic, {
8
8
  fastifyStatic as fastifyStaticNamed
9
9
  } from '..'
10
10
 
11
- import fastifyStaticCjsImport = require('..')
11
+ const fastifyStaticCjsImport = fastifyStaticStar
12
12
  const fastifyStaticCjs = require('..')
13
13
 
14
14
  const app: FastifyInstance = fastify()
package/.github/stale.yml DELETED
@@ -1,21 +0,0 @@
1
- # Number of days of inactivity before an issue becomes stale
2
- daysUntilStale: 15
3
- # Number of days of inactivity before a stale issue is closed
4
- daysUntilClose: 7
5
- # Issues with these labels will never be considered stale
6
- exemptLabels:
7
- - "discussion"
8
- - "feature request"
9
- - "bug"
10
- - "help wanted"
11
- - "plugin suggestion"
12
- - "good first issue"
13
- # Label to use when marking an issue as stale
14
- staleLabel: stale
15
- # Comment to post when marking an issue as stale. Set to `false` to disable
16
- markComment: >
17
- This issue has been automatically marked as stale because it has not had
18
- recent activity. It will be closed if no further activity occurs. Thank you
19
- for your contributions.
20
- # Comment to post when closing a stale issue. Set to `false` to disable
21
- closeComment: false