strapi-cache 1.1.2 → 1.2.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.
package/README.md CHANGED
@@ -1,11 +1,12 @@
1
1
  # 🧠 strapi-cache
2
2
 
3
3
  **A powerful LRU-Cache plugin for Strapi v5**
4
- Boost your API performance with automatic caching for REST and GraphQL requests.
4
+ Boost your API performance with automatic in-memory caching for REST and GraphQL requests.
5
5
 
6
6
  ![npm version](https://img.shields.io/badge/version-1.0.0-blue)
7
7
  ![Strapi Version](https://img.shields.io/badge/strapi-v5-blue)
8
8
  ![License: MIT](https://img.shields.io/badge/license-MIT-green)
9
+ ![npm](https://img.shields.io/npm/dt/strapi-cache)
9
10
 
10
11
  ---
11
12
 
@@ -47,6 +48,27 @@ In your Strapi project, navigate to `config/plugins.js` and add the following co
47
48
  ttl: 1000 * 60 * 60, // Time to live for cache items (1 hour)
48
49
  size: 1024 * 1024 * 1024, // Maximum size of the cache (1 GB)
49
50
  allowStale: false, // Allow stale cache items
51
+ cacheableRoutes: ['/api/products', '/api/categories'], // Caches routes which start with these paths (if empty array, all '/api' routes are cached)
50
52
  },
51
53
  },
52
54
  ```
55
+
56
+ ## 🗂️ How It Works
57
+
58
+ - **In-Memory Storage**: The plugin keeps cached data in memory using an LRU strategy. It checks the cache before querying the database.
59
+ - **Powered by `lru-cache`**: Uses the popular `lru-cache` library for managing the cache efficiently.
60
+ - **Automatic Invalidation**: Cache is cleared automatically when content is updated, deleted, or created. (GraphQL cache clears on any content update.)
61
+ - **`no-cache` Header Support**: Respects the `no-cache` header, letting you skip the cache by setting `Cache-Control: no-cache` in your request.
62
+ - **Default Cached Requests**: By default, caches all GET requests to `/api` and POST requests to `/graphql`. You can customize which content types to cache in the settings (only for GET requests).
63
+
64
+ ## 🔮 Planned Features
65
+
66
+ - [x] **Cache Invalidation**: Automatically invalidate cache on content updates, deletions, or creations.
67
+ - [x] **GraphQL Caching**: Cache GraphQL queries.
68
+ - [ ] **Purge Cache in Settings**: Add a UI option in the Strapi admin panel to manually purge the cache.
69
+ - [x] **Route/Content-Type Specific Caching**: Allow users to define which routes should be cached based.
70
+ - [ ] **Switchable Cache Providers**: Explore support for other caching providers like Redis for distributed caching.
71
+
72
+ ## 🛠️ Contributing
73
+
74
+ Contributions are welcome! If you have suggestions or improvements, please open an issue or submit a pull request.
@@ -7,3 +7,4 @@ const en = {
7
7
  export {
8
8
  en as default
9
9
  };
10
+ //# sourceMappingURL=en-BgoZyxl0.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"en-BgoZyxl0.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;"}
@@ -7,3 +7,4 @@ const en = {
7
7
  "strapi-cache.view.settings.subtitle": "Configure what to cache"
8
8
  };
9
9
  exports.default = en;
10
+ //# sourceMappingURL=en-CIN0kRXJ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"en-CIN0kRXJ.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;"}
@@ -47,3 +47,4 @@ const index = {
47
47
  }
48
48
  };
49
49
  module.exports = index;
50
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../../admin/src/pluginId.ts","../../admin/src/components/Initializer.tsx","../../admin/src/index.ts"],"sourcesContent":["export const PLUGIN_ID = 'strapi-cache';\n","import { useEffect, useRef } from 'react';\n\nimport { PLUGIN_ID } from '../pluginId';\n\ntype InitializerProps = {\n setPlugin: (id: string) => void;\n};\n\nconst Initializer = ({ setPlugin }: InitializerProps) => {\n const ref = useRef(setPlugin);\n\n useEffect(() => {\n ref.current(PLUGIN_ID);\n }, []);\n\n return null;\n};\n\nexport { Initializer };\n","import { PLUGIN_ID } from './pluginId';\nimport { Initializer } from './components/Initializer';\n\nexport default {\n register(app: any) {\n app.registerPlugin({\n id: PLUGIN_ID,\n initializer: Initializer,\n isReady: false,\n name: PLUGIN_ID,\n });\n },\n\n async registerTrads({ locales }: { locales: string[] }) {\n return Promise.all(\n locales.map(async (locale) => {\n try {\n const { default: data } = await import(`./translations/${locale}.json`);\n\n return { data, locale };\n } catch {\n return { data: {}, locale };\n }\n })\n );\n },\n};\n"],"names":["useRef","useEffect"],"mappings":";;;;;;;;;;;;;;;;;;AAAO,MAAM,YAAY;ACQzB,MAAM,cAAc,CAAC,EAAE,gBAAkC;AACjD,QAAA,MAAMA,aAAO,SAAS;AAE5BC,QAAAA,UAAU,MAAM;AACd,QAAI,QAAQ,SAAS;AAAA,EACvB,GAAG,EAAE;AAEE,SAAA;AACT;ACbA,MAAe,QAAA;AAAA,EACb,SAAS,KAAU;AACjB,QAAI,eAAe;AAAA,MACjB,IAAI;AAAA,MACJ,aAAa;AAAA,MACb,SAAS;AAAA,MACT,MAAM;AAAA,IAAA,CACP;AAAA,EACH;AAAA,EAEA,MAAM,cAAc,EAAE,WAAkC;AACtD,WAAO,QAAQ;AAAA,MACb,QAAQ,IAAI,OAAO,WAAW;AACxB,YAAA;AACF,gBAAM,EAAE,SAAS,SAAS,MAAM,qCAAA,uBAAA,OAAA,EAAA,0BAAA,MAAA,QAAA,QAAA,EAAA,KAAA,MAAA,QAAA,2BAAA,CAAA,EAAA,CAAA,GAAA,kBAAA,MAAA,SAAA,CAAA;AAEzB,iBAAA,EAAE,MAAM,OAAO;AAAA,QAAA,QAChB;AACN,iBAAO,EAAE,MAAM,CAAC,GAAG,OAAO;AAAA,QAAA;AAAA,MAE7B,CAAA;AAAA,IACH;AAAA,EAAA;AAEJ;;"}
@@ -48,3 +48,4 @@ const index = {
48
48
  export {
49
49
  index as default
50
50
  };
51
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","sources":["../../admin/src/pluginId.ts","../../admin/src/components/Initializer.tsx","../../admin/src/index.ts"],"sourcesContent":["export const PLUGIN_ID = 'strapi-cache';\n","import { useEffect, useRef } from 'react';\n\nimport { PLUGIN_ID } from '../pluginId';\n\ntype InitializerProps = {\n setPlugin: (id: string) => void;\n};\n\nconst Initializer = ({ setPlugin }: InitializerProps) => {\n const ref = useRef(setPlugin);\n\n useEffect(() => {\n ref.current(PLUGIN_ID);\n }, []);\n\n return null;\n};\n\nexport { Initializer };\n","import { PLUGIN_ID } from './pluginId';\nimport { Initializer } from './components/Initializer';\n\nexport default {\n register(app: any) {\n app.registerPlugin({\n id: PLUGIN_ID,\n initializer: Initializer,\n isReady: false,\n name: PLUGIN_ID,\n });\n },\n\n async registerTrads({ locales }: { locales: string[] }) {\n return Promise.all(\n locales.map(async (locale) => {\n try {\n const { default: data } = await import(`./translations/${locale}.json`);\n\n return { data, locale };\n } catch {\n return { data: {}, locale };\n }\n })\n );\n },\n};\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAO,MAAM,YAAY;ACQzB,MAAM,cAAc,CAAC,EAAE,gBAAkC;AACjD,QAAA,MAAM,OAAO,SAAS;AAE5B,YAAU,MAAM;AACd,QAAI,QAAQ,SAAS;AAAA,EACvB,GAAG,EAAE;AAEE,SAAA;AACT;ACbA,MAAe,QAAA;AAAA,EACb,SAAS,KAAU;AACjB,QAAI,eAAe;AAAA,MACjB,IAAI;AAAA,MACJ,aAAa;AAAA,MACb,SAAS;AAAA,MACT,MAAM;AAAA,IAAA,CACP;AAAA,EACH;AAAA,EAEA,MAAM,cAAc,EAAE,WAAkC;AACtD,WAAO,QAAQ;AAAA,MACb,QAAQ,IAAI,OAAO,WAAW;AACxB,YAAA;AACF,gBAAM,EAAE,SAAS,SAAS,MAAM,qCAAA,uBAAA,OAAA,EAAA,0BAAA,MAAA,OAAA,4BAAA,EAAA,CAAA,GAAA,kBAAA,MAAA,SAAA,CAAA;AAEzB,iBAAA,EAAE,MAAM,OAAO;AAAA,QAAA,QAChB;AACN,iBAAO,EAAE,MAAM,CAAC,GAAG,OAAO;AAAA,QAAA;AAAA,MAE7B,CAAA;AAAA,IACH;AAAA,EAAA;AAEJ;"}
@@ -100,26 +100,25 @@ const generateGraphqlCacheKey = (payload) => {
100
100
  };
101
101
  const middleware$1 = async (ctx, next) => {
102
102
  const cacheService = strapi.plugin("strapi-cache").services.service;
103
+ const cacheableRoutes = strapi.plugin("strapi-cache").config("cacheableRoutes");
103
104
  const cacheStore = cacheService.createCache();
104
105
  const { url } = ctx.request;
105
106
  const key = generateCacheKey(ctx);
106
107
  const cacheEntry = await cacheStore.get(key);
107
108
  const cacheControlHeader = ctx.request.headers["cache-control"];
108
109
  const noCache = cacheControlHeader && cacheControlHeader.includes("no-cache");
110
+ const routeIsCachable = cacheableRoutes.some((route) => url.startsWith(route)) || cacheableRoutes.length === 0 && url.startsWith("/api");
109
111
  if (cacheEntry && !noCache) {
110
112
  loggy.info(`HIT with key: ${key}`);
111
113
  ctx.status = 200;
112
- ctx.body = cacheEntry.body;
113
- ctx.set(cacheEntry.headers);
114
+ ctx.body = cacheEntry;
115
+ ctx.set({ "Access-Control-Allow-Origin": "*" });
114
116
  return;
115
117
  }
116
118
  await next();
117
- if (ctx.body && ctx.method === "GET" && ctx.status >= 200 && ctx.status <= 300 && url.startsWith("/api")) {
119
+ if (ctx.body && ctx.method === "GET" && ctx.status >= 200 && ctx.status < 300 && routeIsCachable) {
118
120
  loggy.info(`MISS with key: ${key}`);
119
- await cacheStore.set(key, {
120
- body: ctx.body,
121
- headers: ctx.response.headers
122
- });
121
+ await cacheStore.set(key, ctx.body);
123
122
  }
124
123
  };
125
124
  const middleware = async (ctx, next) => {
@@ -152,7 +151,7 @@ const middleware = async (ctx, next) => {
152
151
  return;
153
152
  }
154
153
  await next();
155
- if (ctx.body && ctx.method === "POST" && ctx.status >= 200 && ctx.status <= 300 && url.startsWith("/graphql")) {
154
+ if (ctx.body && ctx.method === "POST" && ctx.status >= 200 && ctx.status < 300 && url.startsWith("/graphql")) {
156
155
  loggy.info(`MISS with key: ${key}`);
157
156
  await cacheStore.set(key, {
158
157
  body: ctx.body,
@@ -174,7 +173,8 @@ const config = {
174
173
  max: 1e3,
175
174
  ttl: 1e3 * 60 * 60,
176
175
  size: 1024 * 1014 * 10,
177
- allowStale: false
176
+ allowStale: false,
177
+ contentTypes: []
178
178
  }),
179
179
  validator: (config2) => {
180
180
  if (typeof config2.debug !== "boolean") {
@@ -192,6 +192,9 @@ const config = {
192
192
  if (typeof config2.allowStale !== "boolean") {
193
193
  throw new Error(`Invalid config: allowStale must be a boolean`);
194
194
  }
195
+ if (!Array.isArray(config2.cacheableRoutes) || config2.cacheableRoutes.some((item) => typeof item !== "string")) {
196
+ throw new Error(`Invalid config: cacheableRoutes must be an string array`);
197
+ }
195
198
  }
196
199
  };
197
200
  const contentTypes = {};
@@ -409,3 +412,4 @@ const index = {
409
412
  middlewares
410
413
  };
411
414
  module.exports = index;
415
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../../server/src/utils/log.ts","../../server/src/utils/invalidateCache.ts","../../server/src/bootstrap.ts","../../server/src/destroy.ts","../../server/src/utils/key.ts","../../server/src/middlewares/cache.ts","../../server/src/middlewares/graphql.ts","../../server/src/middlewares/index.ts","../../server/src/register.ts","../../server/src/config/index.ts","../../server/src/content-types/index.ts","../../server/src/controllers/controller.ts","../../server/src/controllers/index.ts","../../server/src/policies/index.ts","../../server/src/routes/content-api.ts","../../server/src/routes/index.ts","../../server/src/utils/withTimeout.ts","../../server/src/services/service.ts","../../server/src/services/index.ts","../../server/src/index.ts"],"sourcesContent":["export const loggy = {\n info: (msg: string) => {\n const shouldDebug = strapi.plugin('strapi-cache').config('debug') ?? false;\n if (!shouldDebug) {\n return;\n }\n strapi.log.info(`[STRAPI CACHE] ${msg}`);\n },\n error: (msg: string) => {\n const shouldDebug = strapi.plugin('strapi-cache').config('debug') ?? false;\n if (!shouldDebug) {\n return;\n }\n strapi.log.error(`[STRAPI CACHE] ${msg}`);\n },\n warn: (msg: string) => {\n const shouldDebug = strapi.plugin('strapi-cache').config('debug') ?? false;\n if (!shouldDebug) {\n return;\n }\n strapi.log.warn(`[STRAPI CACHE] ${msg}`);\n },\n};\n","import { Core } from '@strapi/strapi';\nimport { CacheProvider } from 'src/types/cache.types';\nimport { loggy } from './log';\n\nexport async function invalidateCache(event: any, cacheStore: CacheProvider, strapi: Core.Strapi) {\n const { model } = event;\n const uid = model.uid;\n\n try {\n const contentType = strapi.contentType(uid);\n\n if (!contentType || !contentType.kind) {\n loggy.info(`Content type ${uid} not found`);\n return;\n }\n\n const pluralName =\n contentType.kind === 'singleType'\n ? contentType.info.singularName\n : contentType.info.pluralName;\n const apiPath = `/api/${pluralName}`;\n const regex = new RegExp(`^.*:${apiPath}(/.*)?(\\\\?.*)?$`);\n\n await cacheStore.clearByRegexp([regex]);\n loggy.info(`Invalidated cache for ${apiPath}`);\n } catch (error) {\n loggy.error('Cache invalidation error:');\n loggy.error(error);\n }\n}\n\nexport async function invalidateGraphqlCache(\n event: any,\n cacheStore: CacheProvider,\n strapi: Core.Strapi\n) {\n try {\n const graphqlRegex = new RegExp(`^POST:\\/graphql(:.*)?$`);\n\n await cacheStore.clearByRegexp([graphqlRegex]);\n loggy.info(`Invalidated cache for ${graphqlRegex}`);\n } catch (error) {\n loggy.error('Cache invalidation error:');\n loggy.error(error);\n }\n}\n","import type { Core } from '@strapi/strapi';\nimport { invalidateCache, invalidateGraphqlCache } from './utils/invalidateCache';\nimport { CacheService } from './types/cache.types';\nimport { loggy } from './utils/log';\n\nconst bootstrap = ({ strapi }: { strapi: Core.Strapi }) => {\n loggy.info('Initializing');\n try {\n const cacheService = strapi.plugin('strapi-cache').services.service as CacheService;\n const cacheStore = cacheService.createCache();\n cacheStore.init();\n\n strapi.db.lifecycles.subscribe({\n async afterCreate(event) {\n await invalidateCache(event, cacheStore, strapi);\n await invalidateGraphqlCache(event, cacheStore, strapi);\n },\n async afterUpdate(event) {\n await invalidateCache(event, cacheStore, strapi);\n await invalidateGraphqlCache(event, cacheStore, strapi);\n },\n async afterDelete(event) {\n await invalidateCache(event, cacheStore, strapi);\n await invalidateGraphqlCache(event, cacheStore, strapi);\n },\n });\n\n if (!cacheStore) {\n loggy.error('Plugin could not be initialized');\n return;\n }\n } catch (error) {\n loggy.error('Plugin could not be initialized');\n return;\n }\n loggy.info('Plugin initialized');\n};\n\nexport default bootstrap;\n","import type { Core } from '@strapi/strapi';\n\nconst destroy = ({ strapi }: { strapi: Core.Strapi }) => {\n // destroy phase\n};\n\nexport default destroy;\n","import { createHash } from 'crypto';\nimport { Context } from 'koa';\n\nexport const generateCacheKey = (context: Context) => {\n const { url } = context.request;\n const { method } = context.request;\n\n return `${method}:${url}`;\n};\n\nexport const generateGraphqlCacheKey = (payload: string) => {\n const hash = createHash('sha256').update(payload).digest('base64url');\n return `POST:/graphql:${hash}`;\n};\n","import { Context } from 'koa';\nimport { generateCacheKey } from '../utils/key';\nimport { CacheService } from 'src/types/cache.types';\nimport { loggy } from '../utils/log';\n\nconst middleware = async (ctx: Context, next: any) => {\n const cacheService = strapi.plugin('strapi-cache').services.service as CacheService;\n const cacheableRoutes = strapi.plugin('strapi-cache').config('cacheableRoutes') as string[];\n const cacheStore = cacheService.createCache();\n const { url } = ctx.request;\n const key = generateCacheKey(ctx);\n const cacheEntry = await cacheStore.get(key);\n const cacheControlHeader = ctx.request.headers['cache-control'];\n const noCache = cacheControlHeader && cacheControlHeader.includes('no-cache');\n const routeIsCachable =\n cacheableRoutes.some((route) => url.startsWith(route)) ||\n (cacheableRoutes.length === 0 && url.startsWith('/api'));\n\n if (cacheEntry && !noCache) {\n loggy.info(`HIT with key: ${key}`);\n ctx.status = 200;\n ctx.body = cacheEntry;\n ctx.set({ 'Access-Control-Allow-Origin': '*' });\n return;\n }\n\n await next();\n\n if (\n ctx.body &&\n ctx.method === 'GET' &&\n ctx.status >= 200 &&\n ctx.status < 300 &&\n routeIsCachable\n ) {\n loggy.info(`MISS with key: ${key}`);\n await cacheStore.set(key, ctx.body);\n }\n};\n\nexport default middleware;\n","import rawBody from 'raw-body';\nimport { generateGraphqlCacheKey } from '../utils/key';\nimport { Readable } from 'stream';\nimport { loggy } from '../utils/log';\n\nconst middleware = async (ctx: any, next: any) => {\n const cacheService = strapi.plugin('strapi-cache').services.service;\n const cacheStore = cacheService.createCache();\n const { url } = ctx.request;\n\n const originalReq = ctx.req;\n const bodyBuffer = await rawBody(originalReq);\n const body = bodyBuffer.toString();\n\n const clonedReq = new Readable();\n clonedReq.push(bodyBuffer);\n clonedReq.push(null);\n\n (clonedReq as any).headers = { ...originalReq.headers };\n (clonedReq as any).method = originalReq.method;\n (clonedReq as any).url = originalReq.url;\n (clonedReq as any).httpVersion = originalReq.httpVersion;\n (clonedReq as any).socket = originalReq.socket;\n (clonedReq as any).connection = originalReq.connection;\n\n ctx.req = clonedReq;\n ctx.request.req = clonedReq;\n\n const key = generateGraphqlCacheKey(body);\n const cacheEntry = await cacheStore.get(key);\n const cacheControlHeader = ctx.request.headers['cache-control'];\n const noCache = cacheControlHeader && cacheControlHeader.includes('no-cache');\n\n if (cacheEntry && !noCache) {\n loggy.info(`HIT with key: ${key}`);\n ctx.status = 200;\n ctx.body = cacheEntry.body;\n ctx.set(cacheEntry.headers);\n return;\n }\n\n await next();\n\n if (\n ctx.body &&\n ctx.method === 'POST' &&\n ctx.status >= 200 &&\n ctx.status < 300 &&\n url.startsWith('/graphql')\n ) {\n loggy.info(`MISS with key: ${key}`);\n await cacheStore.set(key, {\n body: ctx.body,\n headers: ctx.response.headers,\n });\n }\n};\n\nexport default middleware;\n","import cache from './cache';\nimport graphql from './graphql';\n\nexport default {\n graphql,\n cache,\n};\n","import type { Core } from '@strapi/strapi';\nimport middlewares from './middlewares';\n\nconst register = ({ strapi }: { strapi: Core.Strapi }) => {\n strapi.server.use(middlewares.cache);\n strapi.server.use(middlewares.graphql);\n};\n\nexport default register;\n","export default {\n default: ({ env }) => ({\n debug: false,\n max: 1000,\n ttl: 1000 * 60 * 60,\n size: 1024 * 1014 * 10,\n allowStale: false,\n contentTypes: [],\n }),\n validator: (config) => {\n if (typeof config.debug !== 'boolean') {\n throw new Error(`Invalid config: debug must be a boolean`);\n }\n if (typeof config.max !== 'number') {\n throw new Error(`Invalid config: max must be a number`);\n }\n if (typeof config.ttl !== 'number') {\n throw new Error(`Invalid config: ttl must be a number`);\n }\n if (typeof config.size !== 'number') {\n throw new Error(`Invalid config: size must be a number`);\n }\n if (typeof config.allowStale !== 'boolean') {\n throw new Error(`Invalid config: allowStale must be a boolean`);\n }\n if (\n !Array.isArray(config.cacheableRoutes) ||\n config.cacheableRoutes.some((item) => typeof item !== 'string')\n ) {\n throw new Error(`Invalid config: cacheableRoutes must be an string array`);\n }\n },\n};\n","export default {};\n","import type { Core } from '@strapi/strapi';\nimport { Context } from 'koa';\n\nconst controller = ({ strapi }: { strapi: Core.Strapi }) => ({\n index(ctx: Context) {\n ctx.body = strapi\n .plugin('strapi-cache')\n // the name of the service file & the method.\n .service('service')\n .getWelcomeMessage();\n },\n});\n\nexport default controller;\n","import controller from './controller';\n\nexport default {\n controller,\n};\n","export default {};\n","export default [\n {\n method: 'GET',\n path: '/',\n // name of the controller file & the method.\n handler: 'controller.index',\n config: {\n policies: [],\n },\n },\n];\n","import contentAPIRoutes from './content-api';\n\nconst routes = {\n 'content-api': {\n type: 'content-api',\n routes: contentAPIRoutes,\n },\n};\n\nexport default routes;\n","export const withTimeout = (callback: () => Promise<any>, ms: number) => {\n let timeout: NodeJS.Timeout | null = null;\n\n return Promise.race([\n callback().then((result) => {\n if (timeout) {\n clearTimeout(timeout);\n }\n return result;\n }),\n new Promise((_, reject) => {\n timeout = setTimeout(() => {\n reject(new Error('timeout'));\n }, ms);\n }),\n ]);\n};\n","import type { Core } from '@strapi/strapi';\nimport { LRUCache } from 'lru-cache';\nimport { withTimeout } from '../../src/utils/withTimeout';\nimport { CacheProvider, CacheService } from '../types/cache.types';\nimport { loggy } from '../utils/log';\n\nconst service = ({ strapi }: { strapi: Core.Strapi }): CacheService => {\n let cacheInstance: CacheProvider | null = null;\n return {\n createCache() {\n if (cacheInstance) {\n return cacheInstance;\n }\n\n let initialized = false;\n let provider: LRUCache<string, any>;\n\n loggy.info('Creating provider');\n\n const instance: CacheProvider = {\n init() {\n if (initialized) {\n loggy.error('Provider already initialized');\n return;\n }\n\n initialized = true;\n const max = strapi.plugin('strapi-cache').config('max');\n const ttl = strapi.plugin('strapi-cache').config('ttl');\n const size = strapi.plugin('strapi-cache').config('size');\n const allowStale = strapi.plugin('strapi-cache').config('allowStale');\n\n provider = new LRUCache({\n max: Number(max),\n ttl: Number(ttl),\n size: Number(size),\n allowStale: allowStale ? true : false,\n });\n loggy.info('Provider initialized');\n },\n\n /**\n * @param {string} key\n */\n async get(key: string) {\n if (!initialized) {\n loggy.error('Provider not initialized');\n return null;\n }\n\n if (!this.ready) {\n loggy.error('Provider not ready');\n return null;\n }\n\n const getTimeout = 1000;\n return withTimeout(async () => await provider.get(key), getTimeout).catch((error) => {\n if (error?.message === 'timeout') {\n loggy.error(`Provider timed-out after ${getTimeout}ms.`);\n } else {\n loggy.error(`Provider errored:`);\n loggy.error(error);\n }\n return null;\n });\n },\n\n /**\n * @param {string} key\n * @param {any} val\n */\n async set(key: string, val: any) {\n if (!initialized) {\n loggy.error('Provider not initialized');\n return null;\n }\n\n if (!this.ready) {\n loggy.error('Provider not ready');\n return null;\n }\n\n try {\n const size = provider.size;\n return provider.set(key, val);\n } catch (error) {\n loggy.error(`Provider errored:`);\n loggy.error(error);\n return null;\n }\n },\n\n /**\n * @param {string} key\n */\n async del(key: string) {\n if (!initialized) {\n loggy.error('Provider not initialized');\n return null;\n }\n\n if (!this.ready) {\n loggy.error('Provider not ready');\n return null;\n }\n\n try {\n loggy.info(`PURGING KEY: ${key}`);\n return provider.delete(key);\n } catch (error) {\n loggy.error(`Provider errored:`);\n loggy.error(error);\n return null;\n }\n },\n\n async keys() {\n if (!initialized) {\n loggy.error('Provider not initialized');\n return null;\n }\n\n if (!this.ready) {\n loggy.error('Provider not ready');\n return null;\n }\n\n try {\n return Array.from(provider.keys());\n } catch (error) {\n loggy.error(`Provider errored:`);\n loggy.error(error);\n return null;\n }\n },\n\n async reset() {\n if (!initialized) {\n loggy.error('Provider not initialized');\n return null;\n }\n\n if (!this.ready) {\n loggy.error('Provider not ready');\n return null;\n }\n\n try {\n const allKeys = await this.keys();\n if (!allKeys) {\n loggy.error('Provider not ready');\n return null;\n }\n loggy.info(`PURGING ALL KEYS: ${allKeys.length}`);\n return this.keys().then((keys) => Promise.all(allKeys.map((key) => this.del(key))));\n } catch (error) {\n loggy.error(`Provider errored:`);\n loggy.error(error);\n return null;\n }\n },\n\n get ready() {\n if (!initialized) {\n loggy.info('Provider not initialized');\n return false;\n }\n\n return true;\n },\n\n /**\n * @param {RegExp[]} regExps\n */\n async clearByRegexp(regExps: RegExp[] = []) {\n const keys = (await this.keys()) || [];\n const toDelete = keys.filter((key) => regExps.some((re) => re.test(key)));\n await Promise.all(toDelete.map((key) => this.del(key)));\n },\n };\n cacheInstance = instance;\n return instance;\n },\n };\n};\n\nexport default service;\n","import service from './service';\n\nexport default {\n service,\n};\n","/**\n * Application methods\n */\nimport bootstrap from './bootstrap';\nimport destroy from './destroy';\nimport register from './register';\n\n/**\n * Plugin server methods\n */\nimport config from './config';\nimport contentTypes from './content-types';\nimport controllers from './controllers';\nimport middlewares from './middlewares';\nimport policies from './policies';\nimport routes from './routes';\nimport services from './services';\n\nexport default {\n register,\n bootstrap,\n destroy,\n config,\n controllers,\n routes,\n services,\n contentTypes,\n policies,\n middlewares,\n};\n"],"names":["strapi","createHash","middleware","rawBody","Readable","graphql","cache","config","LRUCache"],"mappings":"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"}
@@ -97,26 +97,25 @@ const generateGraphqlCacheKey = (payload) => {
97
97
  };
98
98
  const middleware$1 = async (ctx, next) => {
99
99
  const cacheService = strapi.plugin("strapi-cache").services.service;
100
+ const cacheableRoutes = strapi.plugin("strapi-cache").config("cacheableRoutes");
100
101
  const cacheStore = cacheService.createCache();
101
102
  const { url } = ctx.request;
102
103
  const key = generateCacheKey(ctx);
103
104
  const cacheEntry = await cacheStore.get(key);
104
105
  const cacheControlHeader = ctx.request.headers["cache-control"];
105
106
  const noCache = cacheControlHeader && cacheControlHeader.includes("no-cache");
107
+ const routeIsCachable = cacheableRoutes.some((route) => url.startsWith(route)) || cacheableRoutes.length === 0 && url.startsWith("/api");
106
108
  if (cacheEntry && !noCache) {
107
109
  loggy.info(`HIT with key: ${key}`);
108
110
  ctx.status = 200;
109
- ctx.body = cacheEntry.body;
110
- ctx.set(cacheEntry.headers);
111
+ ctx.body = cacheEntry;
112
+ ctx.set({ "Access-Control-Allow-Origin": "*" });
111
113
  return;
112
114
  }
113
115
  await next();
114
- if (ctx.body && ctx.method === "GET" && ctx.status >= 200 && ctx.status <= 300 && url.startsWith("/api")) {
116
+ if (ctx.body && ctx.method === "GET" && ctx.status >= 200 && ctx.status < 300 && routeIsCachable) {
115
117
  loggy.info(`MISS with key: ${key}`);
116
- await cacheStore.set(key, {
117
- body: ctx.body,
118
- headers: ctx.response.headers
119
- });
118
+ await cacheStore.set(key, ctx.body);
120
119
  }
121
120
  };
122
121
  const middleware = async (ctx, next) => {
@@ -149,7 +148,7 @@ const middleware = async (ctx, next) => {
149
148
  return;
150
149
  }
151
150
  await next();
152
- if (ctx.body && ctx.method === "POST" && ctx.status >= 200 && ctx.status <= 300 && url.startsWith("/graphql")) {
151
+ if (ctx.body && ctx.method === "POST" && ctx.status >= 200 && ctx.status < 300 && url.startsWith("/graphql")) {
153
152
  loggy.info(`MISS with key: ${key}`);
154
153
  await cacheStore.set(key, {
155
154
  body: ctx.body,
@@ -171,7 +170,8 @@ const config = {
171
170
  max: 1e3,
172
171
  ttl: 1e3 * 60 * 60,
173
172
  size: 1024 * 1014 * 10,
174
- allowStale: false
173
+ allowStale: false,
174
+ contentTypes: []
175
175
  }),
176
176
  validator: (config2) => {
177
177
  if (typeof config2.debug !== "boolean") {
@@ -189,6 +189,9 @@ const config = {
189
189
  if (typeof config2.allowStale !== "boolean") {
190
190
  throw new Error(`Invalid config: allowStale must be a boolean`);
191
191
  }
192
+ if (!Array.isArray(config2.cacheableRoutes) || config2.cacheableRoutes.some((item) => typeof item !== "string")) {
193
+ throw new Error(`Invalid config: cacheableRoutes must be an string array`);
194
+ }
192
195
  }
193
196
  };
194
197
  const contentTypes = {};
@@ -408,3 +411,4 @@ const index = {
408
411
  export {
409
412
  index as default
410
413
  };
414
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","sources":["../../server/src/utils/log.ts","../../server/src/utils/invalidateCache.ts","../../server/src/bootstrap.ts","../../server/src/destroy.ts","../../server/src/utils/key.ts","../../server/src/middlewares/cache.ts","../../server/src/middlewares/graphql.ts","../../server/src/middlewares/index.ts","../../server/src/register.ts","../../server/src/config/index.ts","../../server/src/content-types/index.ts","../../server/src/controllers/controller.ts","../../server/src/controllers/index.ts","../../server/src/policies/index.ts","../../server/src/routes/content-api.ts","../../server/src/routes/index.ts","../../server/src/utils/withTimeout.ts","../../server/src/services/service.ts","../../server/src/services/index.ts","../../server/src/index.ts"],"sourcesContent":["export const loggy = {\n info: (msg: string) => {\n const shouldDebug = strapi.plugin('strapi-cache').config('debug') ?? false;\n if (!shouldDebug) {\n return;\n }\n strapi.log.info(`[STRAPI CACHE] ${msg}`);\n },\n error: (msg: string) => {\n const shouldDebug = strapi.plugin('strapi-cache').config('debug') ?? false;\n if (!shouldDebug) {\n return;\n }\n strapi.log.error(`[STRAPI CACHE] ${msg}`);\n },\n warn: (msg: string) => {\n const shouldDebug = strapi.plugin('strapi-cache').config('debug') ?? false;\n if (!shouldDebug) {\n return;\n }\n strapi.log.warn(`[STRAPI CACHE] ${msg}`);\n },\n};\n","import { Core } from '@strapi/strapi';\nimport { CacheProvider } from 'src/types/cache.types';\nimport { loggy } from './log';\n\nexport async function invalidateCache(event: any, cacheStore: CacheProvider, strapi: Core.Strapi) {\n const { model } = event;\n const uid = model.uid;\n\n try {\n const contentType = strapi.contentType(uid);\n\n if (!contentType || !contentType.kind) {\n loggy.info(`Content type ${uid} not found`);\n return;\n }\n\n const pluralName =\n contentType.kind === 'singleType'\n ? contentType.info.singularName\n : contentType.info.pluralName;\n const apiPath = `/api/${pluralName}`;\n const regex = new RegExp(`^.*:${apiPath}(/.*)?(\\\\?.*)?$`);\n\n await cacheStore.clearByRegexp([regex]);\n loggy.info(`Invalidated cache for ${apiPath}`);\n } catch (error) {\n loggy.error('Cache invalidation error:');\n loggy.error(error);\n }\n}\n\nexport async function invalidateGraphqlCache(\n event: any,\n cacheStore: CacheProvider,\n strapi: Core.Strapi\n) {\n try {\n const graphqlRegex = new RegExp(`^POST:\\/graphql(:.*)?$`);\n\n await cacheStore.clearByRegexp([graphqlRegex]);\n loggy.info(`Invalidated cache for ${graphqlRegex}`);\n } catch (error) {\n loggy.error('Cache invalidation error:');\n loggy.error(error);\n }\n}\n","import type { Core } from '@strapi/strapi';\nimport { invalidateCache, invalidateGraphqlCache } from './utils/invalidateCache';\nimport { CacheService } from './types/cache.types';\nimport { loggy } from './utils/log';\n\nconst bootstrap = ({ strapi }: { strapi: Core.Strapi }) => {\n loggy.info('Initializing');\n try {\n const cacheService = strapi.plugin('strapi-cache').services.service as CacheService;\n const cacheStore = cacheService.createCache();\n cacheStore.init();\n\n strapi.db.lifecycles.subscribe({\n async afterCreate(event) {\n await invalidateCache(event, cacheStore, strapi);\n await invalidateGraphqlCache(event, cacheStore, strapi);\n },\n async afterUpdate(event) {\n await invalidateCache(event, cacheStore, strapi);\n await invalidateGraphqlCache(event, cacheStore, strapi);\n },\n async afterDelete(event) {\n await invalidateCache(event, cacheStore, strapi);\n await invalidateGraphqlCache(event, cacheStore, strapi);\n },\n });\n\n if (!cacheStore) {\n loggy.error('Plugin could not be initialized');\n return;\n }\n } catch (error) {\n loggy.error('Plugin could not be initialized');\n return;\n }\n loggy.info('Plugin initialized');\n};\n\nexport default bootstrap;\n","import type { Core } from '@strapi/strapi';\n\nconst destroy = ({ strapi }: { strapi: Core.Strapi }) => {\n // destroy phase\n};\n\nexport default destroy;\n","import { createHash } from 'crypto';\nimport { Context } from 'koa';\n\nexport const generateCacheKey = (context: Context) => {\n const { url } = context.request;\n const { method } = context.request;\n\n return `${method}:${url}`;\n};\n\nexport const generateGraphqlCacheKey = (payload: string) => {\n const hash = createHash('sha256').update(payload).digest('base64url');\n return `POST:/graphql:${hash}`;\n};\n","import { Context } from 'koa';\nimport { generateCacheKey } from '../utils/key';\nimport { CacheService } from 'src/types/cache.types';\nimport { loggy } from '../utils/log';\n\nconst middleware = async (ctx: Context, next: any) => {\n const cacheService = strapi.plugin('strapi-cache').services.service as CacheService;\n const cacheableRoutes = strapi.plugin('strapi-cache').config('cacheableRoutes') as string[];\n const cacheStore = cacheService.createCache();\n const { url } = ctx.request;\n const key = generateCacheKey(ctx);\n const cacheEntry = await cacheStore.get(key);\n const cacheControlHeader = ctx.request.headers['cache-control'];\n const noCache = cacheControlHeader && cacheControlHeader.includes('no-cache');\n const routeIsCachable =\n cacheableRoutes.some((route) => url.startsWith(route)) ||\n (cacheableRoutes.length === 0 && url.startsWith('/api'));\n\n if (cacheEntry && !noCache) {\n loggy.info(`HIT with key: ${key}`);\n ctx.status = 200;\n ctx.body = cacheEntry;\n ctx.set({ 'Access-Control-Allow-Origin': '*' });\n return;\n }\n\n await next();\n\n if (\n ctx.body &&\n ctx.method === 'GET' &&\n ctx.status >= 200 &&\n ctx.status < 300 &&\n routeIsCachable\n ) {\n loggy.info(`MISS with key: ${key}`);\n await cacheStore.set(key, ctx.body);\n }\n};\n\nexport default middleware;\n","import rawBody from 'raw-body';\nimport { generateGraphqlCacheKey } from '../utils/key';\nimport { Readable } from 'stream';\nimport { loggy } from '../utils/log';\n\nconst middleware = async (ctx: any, next: any) => {\n const cacheService = strapi.plugin('strapi-cache').services.service;\n const cacheStore = cacheService.createCache();\n const { url } = ctx.request;\n\n const originalReq = ctx.req;\n const bodyBuffer = await rawBody(originalReq);\n const body = bodyBuffer.toString();\n\n const clonedReq = new Readable();\n clonedReq.push(bodyBuffer);\n clonedReq.push(null);\n\n (clonedReq as any).headers = { ...originalReq.headers };\n (clonedReq as any).method = originalReq.method;\n (clonedReq as any).url = originalReq.url;\n (clonedReq as any).httpVersion = originalReq.httpVersion;\n (clonedReq as any).socket = originalReq.socket;\n (clonedReq as any).connection = originalReq.connection;\n\n ctx.req = clonedReq;\n ctx.request.req = clonedReq;\n\n const key = generateGraphqlCacheKey(body);\n const cacheEntry = await cacheStore.get(key);\n const cacheControlHeader = ctx.request.headers['cache-control'];\n const noCache = cacheControlHeader && cacheControlHeader.includes('no-cache');\n\n if (cacheEntry && !noCache) {\n loggy.info(`HIT with key: ${key}`);\n ctx.status = 200;\n ctx.body = cacheEntry.body;\n ctx.set(cacheEntry.headers);\n return;\n }\n\n await next();\n\n if (\n ctx.body &&\n ctx.method === 'POST' &&\n ctx.status >= 200 &&\n ctx.status < 300 &&\n url.startsWith('/graphql')\n ) {\n loggy.info(`MISS with key: ${key}`);\n await cacheStore.set(key, {\n body: ctx.body,\n headers: ctx.response.headers,\n });\n }\n};\n\nexport default middleware;\n","import cache from './cache';\nimport graphql from './graphql';\n\nexport default {\n graphql,\n cache,\n};\n","import type { Core } from '@strapi/strapi';\nimport middlewares from './middlewares';\n\nconst register = ({ strapi }: { strapi: Core.Strapi }) => {\n strapi.server.use(middlewares.cache);\n strapi.server.use(middlewares.graphql);\n};\n\nexport default register;\n","export default {\n default: ({ env }) => ({\n debug: false,\n max: 1000,\n ttl: 1000 * 60 * 60,\n size: 1024 * 1014 * 10,\n allowStale: false,\n contentTypes: [],\n }),\n validator: (config) => {\n if (typeof config.debug !== 'boolean') {\n throw new Error(`Invalid config: debug must be a boolean`);\n }\n if (typeof config.max !== 'number') {\n throw new Error(`Invalid config: max must be a number`);\n }\n if (typeof config.ttl !== 'number') {\n throw new Error(`Invalid config: ttl must be a number`);\n }\n if (typeof config.size !== 'number') {\n throw new Error(`Invalid config: size must be a number`);\n }\n if (typeof config.allowStale !== 'boolean') {\n throw new Error(`Invalid config: allowStale must be a boolean`);\n }\n if (\n !Array.isArray(config.cacheableRoutes) ||\n config.cacheableRoutes.some((item) => typeof item !== 'string')\n ) {\n throw new Error(`Invalid config: cacheableRoutes must be an string array`);\n }\n },\n};\n","export default {};\n","import type { Core } from '@strapi/strapi';\nimport { Context } from 'koa';\n\nconst controller = ({ strapi }: { strapi: Core.Strapi }) => ({\n index(ctx: Context) {\n ctx.body = strapi\n .plugin('strapi-cache')\n // the name of the service file & the method.\n .service('service')\n .getWelcomeMessage();\n },\n});\n\nexport default controller;\n","import controller from './controller';\n\nexport default {\n controller,\n};\n","export default {};\n","export default [\n {\n method: 'GET',\n path: '/',\n // name of the controller file & the method.\n handler: 'controller.index',\n config: {\n policies: [],\n },\n },\n];\n","import contentAPIRoutes from './content-api';\n\nconst routes = {\n 'content-api': {\n type: 'content-api',\n routes: contentAPIRoutes,\n },\n};\n\nexport default routes;\n","export const withTimeout = (callback: () => Promise<any>, ms: number) => {\n let timeout: NodeJS.Timeout | null = null;\n\n return Promise.race([\n callback().then((result) => {\n if (timeout) {\n clearTimeout(timeout);\n }\n return result;\n }),\n new Promise((_, reject) => {\n timeout = setTimeout(() => {\n reject(new Error('timeout'));\n }, ms);\n }),\n ]);\n};\n","import type { Core } from '@strapi/strapi';\nimport { LRUCache } from 'lru-cache';\nimport { withTimeout } from '../../src/utils/withTimeout';\nimport { CacheProvider, CacheService } from '../types/cache.types';\nimport { loggy } from '../utils/log';\n\nconst service = ({ strapi }: { strapi: Core.Strapi }): CacheService => {\n let cacheInstance: CacheProvider | null = null;\n return {\n createCache() {\n if (cacheInstance) {\n return cacheInstance;\n }\n\n let initialized = false;\n let provider: LRUCache<string, any>;\n\n loggy.info('Creating provider');\n\n const instance: CacheProvider = {\n init() {\n if (initialized) {\n loggy.error('Provider already initialized');\n return;\n }\n\n initialized = true;\n const max = strapi.plugin('strapi-cache').config('max');\n const ttl = strapi.plugin('strapi-cache').config('ttl');\n const size = strapi.plugin('strapi-cache').config('size');\n const allowStale = strapi.plugin('strapi-cache').config('allowStale');\n\n provider = new LRUCache({\n max: Number(max),\n ttl: Number(ttl),\n size: Number(size),\n allowStale: allowStale ? true : false,\n });\n loggy.info('Provider initialized');\n },\n\n /**\n * @param {string} key\n */\n async get(key: string) {\n if (!initialized) {\n loggy.error('Provider not initialized');\n return null;\n }\n\n if (!this.ready) {\n loggy.error('Provider not ready');\n return null;\n }\n\n const getTimeout = 1000;\n return withTimeout(async () => await provider.get(key), getTimeout).catch((error) => {\n if (error?.message === 'timeout') {\n loggy.error(`Provider timed-out after ${getTimeout}ms.`);\n } else {\n loggy.error(`Provider errored:`);\n loggy.error(error);\n }\n return null;\n });\n },\n\n /**\n * @param {string} key\n * @param {any} val\n */\n async set(key: string, val: any) {\n if (!initialized) {\n loggy.error('Provider not initialized');\n return null;\n }\n\n if (!this.ready) {\n loggy.error('Provider not ready');\n return null;\n }\n\n try {\n const size = provider.size;\n return provider.set(key, val);\n } catch (error) {\n loggy.error(`Provider errored:`);\n loggy.error(error);\n return null;\n }\n },\n\n /**\n * @param {string} key\n */\n async del(key: string) {\n if (!initialized) {\n loggy.error('Provider not initialized');\n return null;\n }\n\n if (!this.ready) {\n loggy.error('Provider not ready');\n return null;\n }\n\n try {\n loggy.info(`PURGING KEY: ${key}`);\n return provider.delete(key);\n } catch (error) {\n loggy.error(`Provider errored:`);\n loggy.error(error);\n return null;\n }\n },\n\n async keys() {\n if (!initialized) {\n loggy.error('Provider not initialized');\n return null;\n }\n\n if (!this.ready) {\n loggy.error('Provider not ready');\n return null;\n }\n\n try {\n return Array.from(provider.keys());\n } catch (error) {\n loggy.error(`Provider errored:`);\n loggy.error(error);\n return null;\n }\n },\n\n async reset() {\n if (!initialized) {\n loggy.error('Provider not initialized');\n return null;\n }\n\n if (!this.ready) {\n loggy.error('Provider not ready');\n return null;\n }\n\n try {\n const allKeys = await this.keys();\n if (!allKeys) {\n loggy.error('Provider not ready');\n return null;\n }\n loggy.info(`PURGING ALL KEYS: ${allKeys.length}`);\n return this.keys().then((keys) => Promise.all(allKeys.map((key) => this.del(key))));\n } catch (error) {\n loggy.error(`Provider errored:`);\n loggy.error(error);\n return null;\n }\n },\n\n get ready() {\n if (!initialized) {\n loggy.info('Provider not initialized');\n return false;\n }\n\n return true;\n },\n\n /**\n * @param {RegExp[]} regExps\n */\n async clearByRegexp(regExps: RegExp[] = []) {\n const keys = (await this.keys()) || [];\n const toDelete = keys.filter((key) => regExps.some((re) => re.test(key)));\n await Promise.all(toDelete.map((key) => this.del(key)));\n },\n };\n cacheInstance = instance;\n return instance;\n },\n };\n};\n\nexport default service;\n","import service from './service';\n\nexport default {\n service,\n};\n","/**\n * Application methods\n */\nimport bootstrap from './bootstrap';\nimport destroy from './destroy';\nimport register from './register';\n\n/**\n * Plugin server methods\n */\nimport config from './config';\nimport contentTypes from './content-types';\nimport controllers from './controllers';\nimport middlewares from './middlewares';\nimport policies from './policies';\nimport routes from './routes';\nimport services from './services';\n\nexport default {\n register,\n bootstrap,\n destroy,\n config,\n controllers,\n routes,\n services,\n contentTypes,\n policies,\n middlewares,\n};\n"],"names":["strapi","middleware","graphql","cache","config"],"mappings":"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"}
@@ -7,6 +7,7 @@ declare const _default: {
7
7
  ttl: number;
8
8
  size: number;
9
9
  allowStale: boolean;
10
+ contentTypes: any[];
10
11
  };
11
12
  validator: (config: any) => void;
12
13
  };
@@ -20,6 +20,7 @@ declare const _default: {
20
20
  ttl: number;
21
21
  size: number;
22
22
  allowStale: boolean;
23
+ contentTypes: any[];
23
24
  };
24
25
  validator: (config: any) => void;
25
26
  };
@@ -0,0 +1,3 @@
1
+ export declare function etagMatch(ctx: any, etagCached: any): boolean;
2
+ export declare function etagLookup(cacheKey: any): Promise<any>;
3
+ export declare function etagGenerate(ctx: any): string;
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.1.2",
2
+ "version": "1.2.1",
3
3
  "keywords": [
4
4
  "strapi cache",
5
5
  "strapi rest cache",