strapi-cache 1.8.8 → 1.9.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.
package/README.md CHANGED
@@ -139,7 +139,7 @@ All of these routes are protected by the policies `admin::isAuthenticatedAdmin`
139
139
  - **Packages**: Uses [lru-cache](https://github.com/isaacs/node-lru-cache) for in-memory cache. Uses [ioredis](https://github.com/redis/ioredis) for Redis and [iovalkey](https://github.com/valkey-io/iovalkey) for Valkey caching.
140
140
  - **Automatic Invalidation**: When `autoPurgeCache` is enabled (default), relevant REST cache entries are invalidated on content create, update, or delete. When `autoPurgeGraphQL` is enabled, GraphQL cache is invalidated the same way (it is off unless you set it in config).
141
141
  - **`no-cache` Header Support**: Respects the `no-cache` header, letting you skip the cache by setting `Cache-Control: no-cache` in your request.
142
- - **Default Cached Requests**: By default, caches all GET requests to `/api` (or whatever prefix you defined) and POST requests to `/graphql`. You can customize which routes or entities to cache using `cacheableRoutes` or `cacheableEntities` config options.
142
+ - **Default Cached Requests**: By default, caches all GET requests to `/api` (or whatever prefix you defined) and POST requests to `/graphql` or predefined graphql route from graphql plugin config. You can customize which routes or entities to cache using `cacheableRoutes` or `cacheableEntities` config options.
143
143
 
144
144
  ## 🔮 Planned Features
145
145
 
@@ -63,7 +63,7 @@ async function invalidateGraphqlCache(event, cacheStore, strapi2) {
63
63
  const contentType = strapi2.contentType(model.uid);
64
64
  if (!contentType || !contentType.info) {
65
65
  loggy.info(`Content type ${model.uid} not found, purging all GraphQL cache`);
66
- const graphqlRegex2 = new RegExp(`^(GET|POST):/graphql:.*`);
66
+ const graphqlRegex2 = new RegExp(`^(GET|POST):${strapi2.plugin("graphql")?.config("endpoint", "/graphql") ?? "/graphql"}:.*`);
67
67
  await cacheStore.clearByRegexp([graphqlRegex2]);
68
68
  return;
69
69
  }
@@ -72,12 +72,12 @@ async function invalidateGraphqlCache(event, cacheStore, strapi2) {
72
72
  const fieldNames = [...new Set([singularName, pluralName].filter(Boolean))];
73
73
  if (fieldNames.length === 0) {
74
74
  loggy.info(`No field names for ${model.uid}, purging all GraphQL cache`);
75
- const graphqlRegex2 = new RegExp(`^(GET|POST):/graphql:.*`);
75
+ const graphqlRegex2 = new RegExp(`^(GET|POST):${strapi2.plugin("graphql")?.config("endpoint", "/graphql") ?? "/graphql"}:.*`);
76
76
  await cacheStore.clearByRegexp([graphqlRegex2]);
77
77
  return;
78
78
  }
79
79
  const escapedNames = fieldNames.map((name) => name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join("|");
80
- const graphqlRegex = new RegExp(`^(GET|POST):/graphql:[^:]*\\b(${escapedNames})\\b[^:]*:`);
80
+ const graphqlRegex = new RegExp(`^(GET|POST):${strapi2.plugin("graphql")?.config("endpoint", "/graphql") ?? "/graphql"}:[^:]*\\b(${escapedNames})\\b[^:]*:`);
81
81
  await cacheStore.clearByRegexp([graphqlRegex]);
82
82
  loggy.info(`Invalidated GraphQL cache for ${model.uid} (${fieldNames.join(", ")})`);
83
83
  } catch (error) {
@@ -157,10 +157,10 @@ const generateCacheKey = (context) => {
157
157
  const { method } = context.request;
158
158
  return `${method}:${url}`;
159
159
  };
160
- const generateGraphqlCacheKey = (payload, method = "POST", rootFields = []) => {
160
+ const generateGraphqlCacheKey = (payload, method = "POST", rootFields = [], strapi2) => {
161
161
  const hash = crypto.createHash("sha256").update(payload).digest("base64url");
162
162
  const rootFieldsSegment = rootFields.length > 0 ? [...rootFields].sort((a, b) => a.localeCompare(b)).join(",") : "_";
163
- return `${method}:/graphql:${rootFieldsSegment}:${hash}`;
163
+ return `${method}:${strapi2?.plugin("graphql")?.config("endpoint", "/graphql") ?? "/graphql"}:${rootFieldsSegment}:${hash}`;
164
164
  };
165
165
  const escapeRegExp = (s) => s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
166
166
  const generateEntityKey = (url, restApiPrefix) => {
@@ -390,7 +390,7 @@ function getRootFieldsFromQuery(query) {
390
390
  }
391
391
  const middleware = async (ctx, next) => {
392
392
  const { url, method } = ctx.request;
393
- if (!url.startsWith("/graphql")) {
393
+ if (!url.startsWith(strapi.plugin("graphql")?.config("endpoint", "/graphql"))) {
394
394
  await next();
395
395
  return;
396
396
  }
@@ -424,7 +424,7 @@ const middleware = async (ctx, next) => {
424
424
  }
425
425
  const payload = parseGraphqlPayload(body, isGet);
426
426
  const rootFields = getRootFieldsFromQuery(payload.query);
427
- const key = generateGraphqlCacheKey(body, isGet ? "GET" : "POST", rootFields);
427
+ const key = generateGraphqlCacheKey(body, isGet ? "GET" : "POST", rootFields, strapi);
428
428
  loggy.info(
429
429
  `GraphQL request: ${JSON.stringify({
430
430
  operationName: payload.operationName,
@@ -478,7 +478,7 @@ const middleware = async (ctx, next) => {
478
478
  return;
479
479
  }
480
480
  await next();
481
- const shouldCache = (ctx.method === "POST" || ctx.method === "GET") && ctx.status >= 200 && ctx.status < 300 && url.startsWith("/graphql");
481
+ const shouldCache = (ctx.method === "POST" || ctx.method === "GET") && ctx.status >= 200 && ctx.status < 300 && url.startsWith(strapi.plugin("graphql")?.config("endpoint", "/graphql"));
482
482
  if (shouldCache) {
483
483
  loggy.info(`MISS with key: ${key}`);
484
484
  const headers = ctx.request.headers;
@@ -59,7 +59,7 @@ async function invalidateGraphqlCache(event, cacheStore, strapi2) {
59
59
  const contentType = strapi2.contentType(model.uid);
60
60
  if (!contentType || !contentType.info) {
61
61
  loggy.info(`Content type ${model.uid} not found, purging all GraphQL cache`);
62
- const graphqlRegex2 = new RegExp(`^(GET|POST):/graphql:.*`);
62
+ const graphqlRegex2 = new RegExp(`^(GET|POST):${strapi2.plugin("graphql")?.config("endpoint", "/graphql") ?? "/graphql"}:.*`);
63
63
  await cacheStore.clearByRegexp([graphqlRegex2]);
64
64
  return;
65
65
  }
@@ -68,12 +68,12 @@ async function invalidateGraphqlCache(event, cacheStore, strapi2) {
68
68
  const fieldNames = [...new Set([singularName, pluralName].filter(Boolean))];
69
69
  if (fieldNames.length === 0) {
70
70
  loggy.info(`No field names for ${model.uid}, purging all GraphQL cache`);
71
- const graphqlRegex2 = new RegExp(`^(GET|POST):/graphql:.*`);
71
+ const graphqlRegex2 = new RegExp(`^(GET|POST):${strapi2.plugin("graphql")?.config("endpoint", "/graphql") ?? "/graphql"}:.*`);
72
72
  await cacheStore.clearByRegexp([graphqlRegex2]);
73
73
  return;
74
74
  }
75
75
  const escapedNames = fieldNames.map((name) => name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join("|");
76
- const graphqlRegex = new RegExp(`^(GET|POST):/graphql:[^:]*\\b(${escapedNames})\\b[^:]*:`);
76
+ const graphqlRegex = new RegExp(`^(GET|POST):${strapi2.plugin("graphql")?.config("endpoint", "/graphql") ?? "/graphql"}:[^:]*\\b(${escapedNames})\\b[^:]*:`);
77
77
  await cacheStore.clearByRegexp([graphqlRegex]);
78
78
  loggy.info(`Invalidated GraphQL cache for ${model.uid} (${fieldNames.join(", ")})`);
79
79
  } catch (error) {
@@ -153,10 +153,10 @@ const generateCacheKey = (context) => {
153
153
  const { method } = context.request;
154
154
  return `${method}:${url}`;
155
155
  };
156
- const generateGraphqlCacheKey = (payload, method = "POST", rootFields = []) => {
156
+ const generateGraphqlCacheKey = (payload, method = "POST", rootFields = [], strapi2) => {
157
157
  const hash = createHash("sha256").update(payload).digest("base64url");
158
158
  const rootFieldsSegment = rootFields.length > 0 ? [...rootFields].sort((a, b) => a.localeCompare(b)).join(",") : "_";
159
- return `${method}:/graphql:${rootFieldsSegment}:${hash}`;
159
+ return `${method}:${strapi2?.plugin("graphql")?.config("endpoint", "/graphql") ?? "/graphql"}:${rootFieldsSegment}:${hash}`;
160
160
  };
161
161
  const escapeRegExp = (s) => s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
162
162
  const generateEntityKey = (url, restApiPrefix) => {
@@ -386,7 +386,7 @@ function getRootFieldsFromQuery(query) {
386
386
  }
387
387
  const middleware = async (ctx, next) => {
388
388
  const { url, method } = ctx.request;
389
- if (!url.startsWith("/graphql")) {
389
+ if (!url.startsWith(strapi.plugin("graphql")?.config("endpoint", "/graphql"))) {
390
390
  await next();
391
391
  return;
392
392
  }
@@ -420,7 +420,7 @@ const middleware = async (ctx, next) => {
420
420
  }
421
421
  const payload = parseGraphqlPayload(body, isGet);
422
422
  const rootFields = getRootFieldsFromQuery(payload.query);
423
- const key = generateGraphqlCacheKey(body, isGet ? "GET" : "POST", rootFields);
423
+ const key = generateGraphqlCacheKey(body, isGet ? "GET" : "POST", rootFields, strapi);
424
424
  loggy.info(
425
425
  `GraphQL request: ${JSON.stringify({
426
426
  operationName: payload.operationName,
@@ -474,7 +474,7 @@ const middleware = async (ctx, next) => {
474
474
  return;
475
475
  }
476
476
  await next();
477
- const shouldCache = (ctx.method === "POST" || ctx.method === "GET") && ctx.status >= 200 && ctx.status < 300 && url.startsWith("/graphql");
477
+ const shouldCache = (ctx.method === "POST" || ctx.method === "GET") && ctx.status >= 200 && ctx.status < 300 && url.startsWith(strapi.plugin("graphql")?.config("endpoint", "/graphql"));
478
478
  if (shouldCache) {
479
479
  loggy.info(`MISS with key: ${key}`);
480
480
  const headers = ctx.request.headers;
@@ -1,5 +1,6 @@
1
+ import { Core } from '@strapi/strapi';
1
2
  import { Context } from 'koa';
2
3
  export declare const generateCacheKey: (context: Context) => string;
3
- export declare const generateGraphqlCacheKey: (payload: string, method?: 'GET' | 'POST', rootFields?: string[]) => string;
4
+ export declare const generateGraphqlCacheKey: (payload: string, method?: 'GET' | 'POST', rootFields?: string[], strapi?: Core.Strapi) => string;
4
5
  export declare const escapeRegExp: (s: string) => string;
5
6
  export declare const generateEntityKey: (url: string, restApiPrefix: string) => string;
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.8.8",
2
+ "version": "1.9.0",
3
3
  "keywords": [
4
4
  "strapi cache",
5
5
  "strapi rest cache",