2db5d830a7a98862b90e1f0c2367f48703b79c89d1f9c83c0c5e2377c426b15ba1ff756f47d9925068a11b786417ae7fcdf8fc7cd73f1c11400ef48b6ee27b 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. import { Readable, Writable } from 'node:stream'
  2. export default CacheHandler
  3. declare namespace CacheHandler {
  4. export type CacheMethods = 'GET' | 'HEAD' | 'OPTIONS' | 'TRACE'
  5. export interface CacheHandlerOptions {
  6. store: CacheStore
  7. cacheByDefault?: number
  8. type?: CacheOptions['type']
  9. }
  10. export interface CacheOptions {
  11. store?: CacheStore
  12. /**
  13. * The methods to cache
  14. * Note we can only cache safe methods. Unsafe methods (i.e. PUT, POST)
  15. * invalidate the cache for a origin.
  16. * @see https://www.rfc-editor.org/rfc/rfc9111.html#name-invalidating-stored-respons
  17. * @see https://www.rfc-editor.org/rfc/rfc9110#section-9.2.1
  18. */
  19. methods?: CacheMethods[]
  20. /**
  21. * RFC9111 allows for caching responses that we aren't explicitly told to
  22. * cache or to not cache.
  23. * @see https://www.rfc-editor.org/rfc/rfc9111.html#section-3-5
  24. * @default undefined
  25. */
  26. cacheByDefault?: number
  27. /**
  28. * TODO docs
  29. * @default 'shared'
  30. */
  31. type?: 'shared' | 'private'
  32. }
  33. export interface CacheControlDirectives {
  34. 'max-stale'?: number;
  35. 'min-fresh'?: number;
  36. 'max-age'?: number;
  37. 's-maxage'?: number;
  38. 'stale-while-revalidate'?: number;
  39. 'stale-if-error'?: number;
  40. public?: true;
  41. private?: true | string[];
  42. 'no-store'?: true;
  43. 'no-cache'?: true | string[];
  44. 'must-revalidate'?: true;
  45. 'proxy-revalidate'?: true;
  46. immutable?: true;
  47. 'no-transform'?: true;
  48. 'must-understand'?: true;
  49. 'only-if-cached'?: true;
  50. }
  51. export interface CacheKey {
  52. origin: string
  53. method: string
  54. path: string
  55. headers?: Record<string, string | string[]>
  56. }
  57. export interface CacheValue {
  58. statusCode: number
  59. statusMessage: string
  60. headers: Record<string, string | string[]>
  61. vary?: Record<string, string | string[] | null>
  62. etag?: string
  63. cacheControlDirectives?: CacheControlDirectives
  64. cachedAt: number
  65. staleAt: number
  66. deleteAt: number
  67. }
  68. export interface DeleteByUri {
  69. origin: string
  70. method: string
  71. path: string
  72. }
  73. type GetResult = {
  74. statusCode: number
  75. statusMessage: string
  76. headers: Record<string, string | string[]>
  77. vary?: Record<string, string | string[] | null>
  78. etag?: string
  79. body?: Readable | Iterable<Buffer> | AsyncIterable<Buffer> | Buffer | Iterable<string> | AsyncIterable<string> | string
  80. cacheControlDirectives: CacheControlDirectives,
  81. cachedAt: number
  82. staleAt: number
  83. deleteAt: number
  84. }
  85. /**
  86. * Underlying storage provider for cached responses
  87. */
  88. export interface CacheStore {
  89. get(key: CacheKey): GetResult | Promise<GetResult | undefined> | undefined
  90. createWriteStream(key: CacheKey, val: CacheValue): Writable | undefined
  91. delete(key: CacheKey): void | Promise<void>
  92. }
  93. export interface MemoryCacheStoreOpts {
  94. /**
  95. * @default Infinity
  96. */
  97. maxCount?: number
  98. /**
  99. * @default Infinity
  100. */
  101. maxSize?: number
  102. /**
  103. * @default Infinity
  104. */
  105. maxEntrySize?: number
  106. errorCallback?: (err: Error) => void
  107. }
  108. export class MemoryCacheStore implements CacheStore {
  109. constructor (opts?: MemoryCacheStoreOpts)
  110. get (key: CacheKey): GetResult | Promise<GetResult | undefined> | undefined
  111. createWriteStream (key: CacheKey, value: CacheValue): Writable | undefined
  112. delete (key: CacheKey): void | Promise<void>
  113. }
  114. export interface SqliteCacheStoreOpts {
  115. /**
  116. * Location of the database
  117. * @default ':memory:'
  118. */
  119. location?: string
  120. /**
  121. * @default Infinity
  122. */
  123. maxCount?: number
  124. /**
  125. * @default Infinity
  126. */
  127. maxEntrySize?: number
  128. }
  129. export class SqliteCacheStore implements CacheStore {
  130. constructor (opts?: SqliteCacheStoreOpts)
  131. /**
  132. * Closes the connection to the database
  133. */
  134. close (): void
  135. get (key: CacheKey): GetResult | Promise<GetResult | undefined> | undefined
  136. createWriteStream (key: CacheKey, value: CacheValue): Writable | undefined
  137. delete (key: CacheKey): void | Promise<void>
  138. }
  139. }