@fastify/caching 9.0.2 → 9.0.3

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.
@@ -8,9 +8,6 @@
8
8
  that provides server-side caching and mechanisms for manipulating HTTP cache headers according to
9
9
  [RFC 2616 §14.9](https://tools.ietf.org/html/rfc2616#section-14.9).
10
10
 
11
- Supports Fastify versions ^3.0.0. Version v5.x supports Fastify ^3.0.0 in
12
- the [`v5.x` branch](https://github.com/fastify/fastify-caching/tree/v5.x).
13
-
14
11
  This plugin fully supports Fastify's encapsulation. Therefore, routes that
15
12
  should have differing cache settings should be registered within different
16
13
  contexts.
@@ -19,14 +16,33 @@ In addition to providing header manipulation, the plugin also decorates the
19
16
  server instance with an object that can be used for caching items. **Note:**
20
17
  the default cache should not be used in a "production" environment. It is
21
18
  an LRU, in-memory cache that is capped at 100,000 items. It is *highly*
22
- recommended that a full featured cache object be supplied, e.g.
19
+ recommended that a full-featured cache object be supplied, e.g.
23
20
  [abstract-cache-redis][acache-redis].
24
21
 
25
22
  [acache-redis]: https://www.npmjs.com/package/abstract-cache-redis
26
23
 
24
+ ## Install
25
+ ```
26
+ npm i @fastify/caching
27
+ ```
28
+
29
+ ### Compatibility
30
+ | Plugin version | Fastify version |
31
+ | ---------------|-----------------|
32
+ | `^9.x` | `^5.x` |
33
+ | `^8.x` | `^4.x` |
34
+ | `^6.x` | `^3.x` |
35
+ | `^4.x` | `^2.x` |
36
+ | `^1.x` | `^1.x` |
37
+
38
+
39
+ Please note that if a Fastify version is out of support, then so are the corresponding versions of this plugin
40
+ in the table above.
41
+ See [Fastify's LTS policy](https://github.com/fastify/fastify/blob/main/docs/Reference/LTS.md) for more details.
42
+
27
43
  ## Example
28
44
 
29
- This example shows using the plugin to disable client side caching of all
45
+ This example shows using the plugin to disable client-side caching of all
30
46
  routes.
31
47
 
32
48
  ```js
@@ -107,7 +123,7 @@ for a *cache-response-directive* as defined by RFC 2616.
107
123
  resource may be cached. When this is set, and `privacy` is not set to `no-cache`,
108
124
  then `', max-age=<value>'` will be appended to the `cache-control` header.
109
125
  + `cache` (Default: `abstract-cache.memclient`): an [abstract-cache][acache]
110
- protocol compliant cache object. Note: the plugin requires a cache instance to
126
+ protocol-compliant cache object. Note: the plugin requires a cache instance to
111
127
  properly support the ETag mechanism. Therefore, if a falsy value is supplied
112
128
  the default will be used.
113
129
  + `cacheSegment` (Default: `'@fastify/caching'`): segment identifier to use when
@@ -128,7 +144,7 @@ recommended to always supply a value to this method to avoid this operation.
128
144
  All incoming requests to paths affected by this plugin will be inspected for
129
145
  the `if-none-match` header. If the header is present, the value will be used
130
146
  to lookup the tag within the cache associated with this plugin. If the tag is
131
- found, then the response will be ended with a 304 status code sent to
147
+ found, then the response will end with a 304 status code sent to
132
148
  the client.
133
149
 
134
150
  Tags will be cached according to the second parameter. If the second parameter
@@ -142,11 +158,11 @@ milliseconds. The default lifetime, when the parameter is not specified, is
142
158
  ### `reply.expires(date)`
143
159
 
144
160
  This method allows setting of the `expires` header. It accepts a regular `Date`
145
- object, or a string that is a valid date string according to
161
+ object or a string that is a valid date string according to
146
162
  [RFC 2616 §14.21][sec14.21].
147
163
 
148
164
  [sec14.21]: https://tools.ietf.org/html/rfc2616#section-14.21
149
165
 
150
166
  ## License
151
167
 
152
- [MIT License](https://jsumners.mit-license.org/)
168
+ Licensed under [MIT](./LICENSE).
package/index.js CHANGED
@@ -38,7 +38,7 @@ function cachingLoadByEtag (req, res, next) {
38
38
  })
39
39
  }
40
40
 
41
- function cachingStoreByEtag (req, res, payload, next) {
41
+ function cachingStoreByEtag (_req, res, payload, next) {
42
42
  const etag = res.getHeader('etag')
43
43
  if (!etag || !res._etagLife) return next()
44
44
  this.cache.set(
@@ -70,7 +70,7 @@ function fastifyCaching (instance, options, next) {
70
70
  value += `, s-maxage=${_options.serverExpiresIn}`
71
71
  }
72
72
 
73
- instance.addHook('onRequest', function cachingSetCacheControlHeader (req, res, next) {
73
+ instance.addHook('onRequest', function cachingSetCacheControlHeader (_req, res, next) {
74
74
  if (!res.hasHeader('Cache-control')) {
75
75
  res.header('Cache-control', value)
76
76
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fastify/caching",
3
- "version": "9.0.2",
3
+ "version": "9.0.3",
4
4
  "description": "A plugin for Fastify to enable management of cache control headers",
5
5
  "main": "index.js",
6
6
  "type": "commonjs",
@@ -28,17 +28,47 @@
28
28
  "caching"
29
29
  ],
30
30
  "author": "James Sumners <james.sumners@gmail.com>",
31
+ "contributors": [
32
+ {
33
+ "name": "Matteo Collina",
34
+ "email": "hello@matteocollina.com"
35
+ },
36
+ {
37
+ "name": "Manuel Spigolon",
38
+ "email": "behemoth89@gmail.com"
39
+ },
40
+ {
41
+ "name": "Aras Abbasi",
42
+ "email": "aras.abbasi@gmail.com"
43
+ },
44
+ {
45
+ "name": "Frazer Smith",
46
+ "email": "frazer.dev@icloud.com",
47
+ "url": "https://github.com/fdawgs"
48
+ }
49
+ ],
31
50
  "license": "MIT",
32
51
  "bugs": {
33
52
  "url": "https://github.com/fastify/fastify-caching/issues"
34
53
  },
35
54
  "homepage": "https://github.com/fastify/fastify-caching#readme",
55
+ "funding": [
56
+ {
57
+ "type": "github",
58
+ "url": "https://github.com/sponsors/fastify"
59
+ },
60
+ {
61
+ "type": "opencollective",
62
+ "url": "https://opencollective.com/fastify"
63
+ }
64
+ ],
36
65
  "devDependencies": {
37
66
  "@fastify/pre-commit": "^2.1.0",
38
67
  "@types/node": "^22.0.0",
39
68
  "c8": "^10.1.2",
69
+ "eslint": "^9.17.0",
40
70
  "fastify": "^5.0.0",
41
- "neostandard": "^0.11.9",
71
+ "neostandard": "^0.12.0",
42
72
  "tsd": "^0.31.0"
43
73
  },
44
74
  "dependencies": {
@@ -21,25 +21,25 @@ test('cache is usable', async (t) => {
21
21
  t.plan(4)
22
22
 
23
23
  const fastify = Fastify()
24
- await fastify.register(async (instance, options) => {
25
- instance.addHook('onRequest', async function checkCachingRegistered (req, reply) {
24
+ await fastify.register(async (instance) => {
25
+ instance.addHook('onRequest', async function checkCachingRegistered () {
26
26
  t.assert.ifError(instance[Symbol.for('fastify-caching.registered')])
27
27
  })
28
28
  })
29
29
  await fastify.register(plugin)
30
30
 
31
- fastify.addHook('onRequest', async function checkCachingRegistered (req, reply) {
31
+ fastify.addHook('onRequest', async function checkCachingRegistered () {
32
32
  t.assert.strictEqual(this[Symbol.for('fastify-caching.registered')], true)
33
33
  })
34
34
 
35
- fastify.get('/one', (req, reply) => {
35
+ fastify.get('/one', (_req, reply) => {
36
36
  fastify.cache.set('one', { one: true }, 1000, (err) => {
37
37
  if (err) return reply.send(err)
38
38
  reply.redirect('/two')
39
39
  })
40
40
  })
41
41
 
42
- fastify.get('/two', (req, reply) => {
42
+ fastify.get('/two', (_req, reply) => {
43
43
  fastify.cache.get('one', (err, obj) => {
44
44
  t.assert.ifError(err)
45
45
  t.assert.strictEqual(obj.item, { one: true })
@@ -70,25 +70,25 @@ test('cache is usable with function as plugin default options input', async (t)
70
70
  t.plan(4)
71
71
 
72
72
  const fastify = Fastify()
73
- await fastify.register(async (instance, options) => {
74
- instance.addHook('onRequest', async function checkCachingNotRegistered (req, reply) {
73
+ await fastify.register(async (instance) => {
74
+ instance.addHook('onRequest', async function checkCachingNotRegistered () {
75
75
  t.assert.failure(instance[Symbol.for('fastify-caching.registered')])
76
76
  })
77
77
  })
78
78
  await fastify.register(plugin, () => () => {})
79
79
 
80
- fastify.addHook('onRequest', async function checkCachingRegistered (req, reply) {
80
+ fastify.addHook('onRequest', async function checkCachingRegistered () {
81
81
  t.assert.strictEqual(this[Symbol.for('fastify-caching.registered')], true)
82
82
  })
83
83
 
84
- fastify.get('/one', (req, reply) => {
84
+ fastify.get('/one', (_req, reply) => {
85
85
  fastify.cache.set('one', { one: true }, 1000, (err) => {
86
86
  if (err) return reply.send(err)
87
87
  reply.redirect('/two')
88
88
  })
89
89
  })
90
90
 
91
- fastify.get('/two', (req, reply) => {
91
+ fastify.get('/two', (_req, reply) => {
92
92
  fastify.cache.get('one', (err, obj) => {
93
93
  t.assert.ifError(err)
94
94
  t.assert.strictEqual(obj.item, { one: true })
@@ -120,21 +120,21 @@ test('getting cache item with error returns error', async (t) => {
120
120
  t.plan(1)
121
121
 
122
122
  const mockCache = {
123
- get: (info, callback) => callback(new Error('cache.get always errors')),
124
- set: (key, value, ttl, callback) => callback()
123
+ get: (_info, callback) => callback(new Error('cache.get always errors')),
124
+ set: (_key, _value, _ttl, callback) => callback()
125
125
  }
126
126
 
127
127
  const fastify = Fastify()
128
128
  await fastify.register(plugin, { cache: mockCache })
129
129
 
130
- fastify.get('/one', (req, reply) => {
130
+ fastify.get('/one', (_req, reply) => {
131
131
  fastify.cache.set('one', { one: true }, 1000, (err) => {
132
132
  if (err) return reply.send(err)
133
133
  return reply.etag('123456').send({ hello: 'world' })
134
134
  })
135
135
  })
136
136
 
137
- fastify.get('/two', (req, reply) => {
137
+ fastify.get('/two', () => {
138
138
  fastify.cache.get('one', (err, obj) => {
139
139
  t.assert.failure(err)
140
140
  t.assert.failure(obj)
@@ -164,7 +164,7 @@ test('etags get stored in cache', async (t) => {
164
164
  const fastify = Fastify()
165
165
  await fastify.register(plugin)
166
166
 
167
- fastify.get('/one', (req, reply) => {
167
+ fastify.get('/one', (_req, reply) => {
168
168
  reply.etag('123456').send({ hello: 'world' })
169
169
  })
170
170
 
@@ -191,7 +191,7 @@ test('etag cache life is customizable', async (t) => {
191
191
  const fastify = Fastify()
192
192
  await fastify.register(plugin)
193
193
 
194
- fastify.get('/one', function (req, reply) {
194
+ fastify.get('/one', function (_req, reply) {
195
195
  reply
196
196
  // We set a cache lifetime of 50 milliseconds
197
197
  .etag('123456', 50)
@@ -237,7 +237,7 @@ test('returns response payload', async (t) => {
237
237
  const fastify = Fastify()
238
238
  await fastify.register(plugin)
239
239
 
240
- fastify.get('/one', (req, reply) => {
240
+ fastify.get('/one', (_req, reply) => {
241
241
  reply.etag('123456', 300).send({ hello: 'world' })
242
242
  })
243
243
 
@@ -10,7 +10,7 @@ test('decorators get added', async (t) => {
10
10
  const fastify = Fastify()
11
11
  await fastify.register(plugin)
12
12
 
13
- fastify.get('/', (req, reply) => {
13
+ fastify.get('/', (_req, reply) => {
14
14
  t.assert.ok(reply.etag)
15
15
  reply.send()
16
16
  })
@@ -31,7 +31,7 @@ test('decorators add headers', async (t) => {
31
31
  const fastify = Fastify()
32
32
  await fastify.register(plugin)
33
33
 
34
- fastify.get('/', (req, reply) => {
34
+ fastify.get('/', (_req, reply) => {
35
35
  reply.etag(tag).send()
36
36
  })
37
37
 
@@ -51,7 +51,7 @@ test('sets etag header for falsy argument', async (t) => {
51
51
  const fastify = Fastify()
52
52
  await fastify.register(plugin)
53
53
 
54
- fastify.get('/', (req, reply) => {
54
+ fastify.get('/', (_req, reply) => {
55
55
  reply.etag().send()
56
56
  })
57
57
 
@@ -70,7 +70,7 @@ test('sets no-cache header', async (t) => {
70
70
  const fastify = Fastify()
71
71
  await fastify.register(plugin, { privacy: plugin.privacy.NOCACHE })
72
72
 
73
- fastify.get('/', (req, reply) => {
73
+ fastify.get('/', (_req, reply) => {
74
74
  reply.send({ hello: 'world' })
75
75
  })
76
76
 
@@ -95,7 +95,7 @@ test('sets private with max-age header', async (t) => {
95
95
  const fastify = Fastify()
96
96
  await fastify.register(plugin, opts)
97
97
 
98
- fastify.get('/', (req, reply) => {
98
+ fastify.get('/', (_req, reply) => {
99
99
  reply.send({ hello: 'world' })
100
100
  })
101
101
 
@@ -124,7 +124,7 @@ test('sets public with max-age and s-maxage header', async (t) => {
124
124
  const fastify = Fastify()
125
125
  await fastify.register(plugin, opts)
126
126
 
127
- fastify.get('/', (req, reply) => {
127
+ fastify.get('/', (_req, reply) => {
128
128
  reply.send({ hello: 'world' })
129
129
  })
130
130
 
@@ -151,12 +151,12 @@ test('do not set headers if another upstream plugin already sets it', async (t)
151
151
  }
152
152
 
153
153
  const fastify = Fastify()
154
- fastify.addHook('onRequest', async function checkCachingDoesNotOverrideCacheControlHeader (req, reply) {
154
+ fastify.addHook('onRequest', async function checkCachingDoesNotOverrideCacheControlHeader (_req, reply) {
155
155
  reply.header('cache-control', 'do not override')
156
156
  })
157
157
  await fastify.register(plugin, opts)
158
158
 
159
- fastify.get('/', (req, reply) => {
159
+ fastify.get('/', (_req, reply) => {
160
160
  reply.send({ hello: 'world' })
161
161
  })
162
162
 
@@ -182,7 +182,7 @@ test('only sets max-age and ignores s-maxage with private header', async (t) =>
182
182
  const fastify = Fastify()
183
183
  await fastify.register(plugin, opts)
184
184
 
185
- fastify.get('/', (req, reply) => {
185
+ fastify.get('/', (_req, reply) => {
186
186
  reply.send({ hello: 'world' })
187
187
  })
188
188
 
@@ -210,7 +210,7 @@ test('s-maxage is optional with public header', async (t) => {
210
210
  const fastify = Fastify()
211
211
  await fastify.register(plugin, opts)
212
212
 
213
- fastify.get('/', (req, reply) => {
213
+ fastify.get('/', (_req, reply) => {
214
214
  reply.send({ hello: 'world' })
215
215
  })
216
216
 
@@ -230,7 +230,7 @@ test('sets no-store with max-age header', async (t) => {
230
230
  const fastify = Fastify()
231
231
  await fastify.register(plugin, { privacy: 'no-store', expiresIn: 300 })
232
232
 
233
- fastify.get('/', (req, reply) => {
233
+ fastify.get('/', (_req, reply) => {
234
234
  reply.send({ hello: 'world' })
235
235
  })
236
236
 
@@ -255,7 +255,7 @@ test('sets the expires header', async (t) => {
255
255
  const fastify = Fastify()
256
256
  await fastify.register(plugin, { privacy: plugin.privacy.NOCACHE })
257
257
 
258
- fastify.get('/', (req, reply) => {
258
+ fastify.get('/', (_req, reply) => {
259
259
  reply.expires(now).send({ hello: 'world' })
260
260
  })
261
261
 
@@ -275,7 +275,7 @@ test('sets the expires header to a falsy value', async (t) => {
275
275
  const fastify = Fastify()
276
276
  await fastify.register(plugin, { privacy: plugin.privacy.NOCACHE })
277
277
 
278
- fastify.get('/', (req, reply) => {
278
+ fastify.get('/', (_req, reply) => {
279
279
  reply.expires().send({ hello: 'world' })
280
280
  })
281
281
 
@@ -294,7 +294,7 @@ test('sets the expires header to a custom value', async (t) => {
294
294
  const fastify = Fastify()
295
295
  await fastify.register(plugin, { privacy: plugin.privacy.NOCACHE })
296
296
 
297
- fastify.get('/', (req, reply) => {
297
+ fastify.get('/', (_req, reply) => {
298
298
  reply.expires('foobar').send({ hello: 'world' })
299
299
  })
300
300
 
@@ -22,7 +22,7 @@ expectType<AbstractCacheCompliantObject['set']>(fastify.cache.set)
22
22
  expectType<string>(fastify.cacheSegment)
23
23
  // expectType<number>(fastify.etagMaxLife);
24
24
 
25
- fastify.get('/one', async (request, reply) => {
25
+ fastify.get('/one', async (_request, reply) => {
26
26
  expectType<(tag?: string, timeToLive?: number) => FastifyReply>(reply.etag)
27
27
  expectType<(date?: Date) => FastifyReply>(reply.expires)
28
28
 
@@ -32,7 +32,7 @@ fastify.get('/one', async (request, reply) => {
32
32
  return { message: 'one' }
33
33
  })
34
34
 
35
- fastify.get('/two', async (request, reply) => {
35
+ fastify.get('/two', async (_request, reply) => {
36
36
  expectType<FastifyReply>(
37
37
  reply.etag('hello', 6000).expires(new Date(Date.now() + 6000))
38
38
  )
@@ -51,7 +51,7 @@ const badCachingOptions = {
51
51
 
52
52
  expectError(shouldErrorApp.register(fastifyCaching, badCachingOptions))
53
53
 
54
- fastify.get('/three', async (request, reply) => {
54
+ fastify.get('/three', async () => {
55
55
  expectAssignable<Promise<unknown>>(
56
56
  fastify.cache.get('well-known')
57
57
  )