Skip to content

Commit faa6c46

Browse files
authored
feat(cache): add onCacheNotAvailable option (#4876)
1 parent f23e97b commit faa6c46

File tree

2 files changed

+40
-1
lines changed

2 files changed

+40
-1
lines changed

src/middleware/cache/index.test.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -416,6 +416,37 @@ describe('Cache Middleware', () => {
416416
expect(res.status).toBe(200)
417417
expect(res.headers.get('cache-control')).toBe(null)
418418
})
419+
420+
it('Should call onCacheNotAvailable when caches is not defined', async () => {
421+
vi.stubGlobal('caches', undefined)
422+
const spy = vi.fn()
423+
const app = new Hono()
424+
app.use(cache({ cacheName: 'my-app-v1', onCacheNotAvailable: spy }))
425+
app.get('/', (c) => {
426+
return c.text('cached')
427+
})
428+
const res = await app.request('/')
429+
expect(res.status).toBe(200)
430+
expect(spy).toHaveBeenCalledOnce()
431+
vi.unstubAllGlobals()
432+
})
433+
434+
it('Should suppress default log when onCacheNotAvailable is false', async () => {
435+
vi.stubGlobal('caches', undefined)
436+
const logSpy = vi.spyOn(console, 'log').mockImplementation(() => {})
437+
const app = new Hono()
438+
app.use(cache({ cacheName: 'my-app-v1', onCacheNotAvailable: false }))
439+
app.get('/', (c) => {
440+
return c.text('cached')
441+
})
442+
const res = await app.request('/')
443+
expect(res.status).toBe(200)
444+
expect(logSpy).not.toHaveBeenCalledWith(
445+
'Cache Middleware is not enabled because caches is not defined.'
446+
)
447+
logSpy.mockRestore()
448+
vi.unstubAllGlobals()
449+
})
419450
})
420451

421452
describe('Cache Skipping Logic', () => {

src/middleware/cache/index.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ const shouldSkipCache = (res: Response) => {
4545
* @param {string | string[]} [options.vary] - Sets the `Vary` header in the response. If the original response header already contains a `Vary` header, the values are merged, removing any duplicates.
4646
* @param {Function} [options.keyGenerator] - Generates keys for every request in the `cacheName` store. This can be used to cache data based on request parameters or context parameters.
4747
* @param {number[]} [options.cacheableStatusCodes=[200]] - An array of status codes that can be cached.
48+
* @param {Function | false} [options.onCacheNotAvailable] - A callback invoked when `globalThis.caches` is not available. By default, a message is logged to the console. Set to `false` to suppress the log, or provide a custom function.
4849
* @returns {MiddlewareHandler} The middleware handler function.
4950
* @throws {Error} If the `vary` option includes "*".
5051
*
@@ -66,9 +67,16 @@ export const cache = (options: {
6667
vary?: string | string[]
6768
keyGenerator?: (c: Context) => Promise<string> | string
6869
cacheableStatusCodes?: StatusCode[]
70+
onCacheNotAvailable?: (() => void) | false
6971
}): MiddlewareHandler => {
7072
if (!globalThis.caches) {
71-
console.log('Cache Middleware is not enabled because caches is not defined.')
73+
if (options.onCacheNotAvailable === false) {
74+
// suppress log
75+
} else if (options.onCacheNotAvailable) {
76+
options.onCacheNotAvailable()
77+
} else {
78+
console.log('Cache Middleware is not enabled because caches is not defined.')
79+
}
7280
return async (_c, next) => await next()
7381
}
7482

0 commit comments

Comments
 (0)