strapi-cache 1.6.2-rc.1 → 1.6.2-rc.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.
Files changed (123) hide show
  1. package/README.md +1 -1
  2. package/dist/_chunks/{index-nPKhLzd1.js → index-7Lm6jbM0.js} +2 -2
  3. package/dist/_chunks/{index-B4lfccXW.js.map → index-7Lm6jbM0.js.map} +1 -1
  4. package/dist/_chunks/{index-BsW67w0G.js → index-BJj5EZfj.js} +10 -6
  5. package/dist/_chunks/index-BJj5EZfj.js.map +1 -0
  6. package/dist/_chunks/{index-B2N_r7ow.mjs → index-BS9N2eCV.mjs} +2 -2
  7. package/dist/_chunks/{index-B2N_r7ow.mjs.map → index-BS9N2eCV.mjs.map} +1 -1
  8. package/dist/_chunks/{index-CH_6jFHP.mjs → index-dynpWXaG.mjs} +10 -6
  9. package/dist/_chunks/index-dynpWXaG.mjs.map +1 -0
  10. package/dist/admin/index.js +1 -1
  11. package/dist/admin/index.mjs +1 -1
  12. package/dist/server/index.js +13 -3
  13. package/dist/server/index.js.map +1 -1
  14. package/dist/server/index.mjs +13 -3
  15. package/dist/server/index.mjs.map +1 -1
  16. package/dist/server/src/utils/key.d.ts +1 -0
  17. package/package.json +1 -1
  18. package/dist/_chunks/index-0I5epaEy.mjs +0 -339
  19. package/dist/_chunks/index-0I5epaEy.mjs.map +0 -1
  20. package/dist/_chunks/index-4_D-e55T.mjs +0 -51
  21. package/dist/_chunks/index-4_D-e55T.mjs.map +0 -1
  22. package/dist/_chunks/index-AEAJzn1w.js +0 -329
  23. package/dist/_chunks/index-AEAJzn1w.js.map +0 -1
  24. package/dist/_chunks/index-B4lfccXW.js +0 -51
  25. package/dist/_chunks/index-B9z92A-z.js +0 -338
  26. package/dist/_chunks/index-B9z92A-z.js.map +0 -1
  27. package/dist/_chunks/index-BAocboRs.mjs +0 -51
  28. package/dist/_chunks/index-BAocboRs.mjs.map +0 -1
  29. package/dist/_chunks/index-BDTo3jFO.js +0 -338
  30. package/dist/_chunks/index-BDTo3jFO.js.map +0 -1
  31. package/dist/_chunks/index-BDgn0QTy.mjs +0 -333
  32. package/dist/_chunks/index-BDgn0QTy.mjs.map +0 -1
  33. package/dist/_chunks/index-BK-ldmu4.mjs +0 -330
  34. package/dist/_chunks/index-BK-ldmu4.mjs.map +0 -1
  35. package/dist/_chunks/index-BPBBFdba.js +0 -51
  36. package/dist/_chunks/index-BPBBFdba.js.map +0 -1
  37. package/dist/_chunks/index-BRqFfzVo.js +0 -51
  38. package/dist/_chunks/index-BRqFfzVo.js.map +0 -1
  39. package/dist/_chunks/index-Babxgmom.js +0 -329
  40. package/dist/_chunks/index-Babxgmom.js.map +0 -1
  41. package/dist/_chunks/index-Bbs05bkg.js +0 -338
  42. package/dist/_chunks/index-Bbs05bkg.js.map +0 -1
  43. package/dist/_chunks/index-BhexB2Ap.mjs +0 -339
  44. package/dist/_chunks/index-BhexB2Ap.mjs.map +0 -1
  45. package/dist/_chunks/index-BleWVvBy.js +0 -51
  46. package/dist/_chunks/index-BleWVvBy.js.map +0 -1
  47. package/dist/_chunks/index-BpocF_uO.mjs +0 -51
  48. package/dist/_chunks/index-BpocF_uO.mjs.map +0 -1
  49. package/dist/_chunks/index-BsW67w0G.js.map +0 -1
  50. package/dist/_chunks/index-C7hTisBG.js +0 -51
  51. package/dist/_chunks/index-C7hTisBG.js.map +0 -1
  52. package/dist/_chunks/index-CAtoueJW.js +0 -51
  53. package/dist/_chunks/index-CAtoueJW.js.map +0 -1
  54. package/dist/_chunks/index-CEeS79tY.js +0 -332
  55. package/dist/_chunks/index-CEeS79tY.js.map +0 -1
  56. package/dist/_chunks/index-CH_6jFHP.mjs.map +0 -1
  57. package/dist/_chunks/index-CIkUFmSg.mjs +0 -51
  58. package/dist/_chunks/index-CIkUFmSg.mjs.map +0 -1
  59. package/dist/_chunks/index-CKXptyYg.mjs +0 -51
  60. package/dist/_chunks/index-CKXptyYg.mjs.map +0 -1
  61. package/dist/_chunks/index-CMD6gyze.mjs +0 -51
  62. package/dist/_chunks/index-CMD6gyze.mjs.map +0 -1
  63. package/dist/_chunks/index-CNdnmVNv.mjs +0 -333
  64. package/dist/_chunks/index-CNdnmVNv.mjs.map +0 -1
  65. package/dist/_chunks/index-CRIKbcQf.mjs +0 -51
  66. package/dist/_chunks/index-CRIKbcQf.mjs.map +0 -1
  67. package/dist/_chunks/index-C_lxmzx9.mjs +0 -339
  68. package/dist/_chunks/index-C_lxmzx9.mjs.map +0 -1
  69. package/dist/_chunks/index-Cb8-_hTN.js +0 -332
  70. package/dist/_chunks/index-Cb8-_hTN.js.map +0 -1
  71. package/dist/_chunks/index-CfW8wHJo.js +0 -51
  72. package/dist/_chunks/index-CfW8wHJo.js.map +0 -1
  73. package/dist/_chunks/index-CiKulRWM.mjs +0 -51
  74. package/dist/_chunks/index-CiKulRWM.mjs.map +0 -1
  75. package/dist/_chunks/index-CmkUlwFo.mjs +0 -51
  76. package/dist/_chunks/index-CmkUlwFo.mjs.map +0 -1
  77. package/dist/_chunks/index-Cp2mUH0P.mjs +0 -51
  78. package/dist/_chunks/index-Cp2mUH0P.mjs.map +0 -1
  79. package/dist/_chunks/index-CqFapeJX.js +0 -338
  80. package/dist/_chunks/index-CqFapeJX.js.map +0 -1
  81. package/dist/_chunks/index-CtY2yrFD.mjs +0 -340
  82. package/dist/_chunks/index-CtY2yrFD.mjs.map +0 -1
  83. package/dist/_chunks/index-Cw8htF0V.js +0 -51
  84. package/dist/_chunks/index-Cw8htF0V.js.map +0 -1
  85. package/dist/_chunks/index-D0RpKca8.js +0 -51
  86. package/dist/_chunks/index-D0RpKca8.js.map +0 -1
  87. package/dist/_chunks/index-D4MlIADe.mjs +0 -339
  88. package/dist/_chunks/index-D4MlIADe.mjs.map +0 -1
  89. package/dist/_chunks/index-D8vo3HTK.mjs +0 -333
  90. package/dist/_chunks/index-D8vo3HTK.mjs.map +0 -1
  91. package/dist/_chunks/index-DILoEiPw.js +0 -339
  92. package/dist/_chunks/index-DILoEiPw.js.map +0 -1
  93. package/dist/_chunks/index-DLSvStnN.js +0 -332
  94. package/dist/_chunks/index-DLSvStnN.js.map +0 -1
  95. package/dist/_chunks/index-DRfYMo02.mjs +0 -51
  96. package/dist/_chunks/index-DRfYMo02.mjs.map +0 -1
  97. package/dist/_chunks/index-D_s9wFvx.js +0 -51
  98. package/dist/_chunks/index-D_s9wFvx.js.map +0 -1
  99. package/dist/_chunks/index-DfNrHbHH.mjs +0 -51
  100. package/dist/_chunks/index-DfNrHbHH.mjs.map +0 -1
  101. package/dist/_chunks/index-Di3zybjV.mjs +0 -339
  102. package/dist/_chunks/index-Di3zybjV.mjs.map +0 -1
  103. package/dist/_chunks/index-DqecouGO.js +0 -51
  104. package/dist/_chunks/index-DqecouGO.js.map +0 -1
  105. package/dist/_chunks/index-DrWpyMvJ.mjs +0 -51
  106. package/dist/_chunks/index-DrWpyMvJ.mjs.map +0 -1
  107. package/dist/_chunks/index-DuPh9DG8.mjs +0 -333
  108. package/dist/_chunks/index-DuPh9DG8.mjs.map +0 -1
  109. package/dist/_chunks/index-DvS-9p_U.js +0 -51
  110. package/dist/_chunks/index-DvS-9p_U.js.map +0 -1
  111. package/dist/_chunks/index-KhVph3TL.js +0 -332
  112. package/dist/_chunks/index-KhVph3TL.js.map +0 -1
  113. package/dist/_chunks/index-XBDBRoF4.js +0 -338
  114. package/dist/_chunks/index-XBDBRoF4.js.map +0 -1
  115. package/dist/_chunks/index-dhIfLdu3.mjs +0 -339
  116. package/dist/_chunks/index-dhIfLdu3.mjs.map +0 -1
  117. package/dist/_chunks/index-gWZp3d_B.mjs +0 -330
  118. package/dist/_chunks/index-gWZp3d_B.mjs.map +0 -1
  119. package/dist/_chunks/index-jBwEyYSm.js +0 -338
  120. package/dist/_chunks/index-jBwEyYSm.js.map +0 -1
  121. package/dist/_chunks/index-nPKhLzd1.js.map +0 -1
  122. package/dist/_chunks/index-ycP1Faro.js +0 -51
  123. package/dist/_chunks/index-ycP1Faro.js.map +0 -1
package/README.md CHANGED
@@ -72,7 +72,7 @@ In your Strapi project, navigate to `config/plugins.js` and add the following co
72
72
  The plugin creates three new routes
73
73
 
74
74
  - `POST /strapi-cache/purge-cache` (purges the whole cache)
75
- - `POST /strapi-cache/purge-cache/:key` (purges cache entries that have the key in the cache key)
75
+ - `POST /strapi-cache/purge-cache/key` (purges cache entries that have the key in the cache key, expects JSON body with `key` field)
76
76
  - `GET /strapi-cache/cacheable-routes` (returns the cacheable routes defined in the config)
77
77
  - `GET /strapi-cache/config` (returns the current plugin config)
78
78
 
@@ -3,7 +3,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const jsxRuntime = require("react/jsx-runtime");
4
4
  const designSystem = require("@strapi/design-system");
5
5
  const reactIntl = require("react-intl");
6
- const index = require("./index-BsW67w0G.js");
6
+ const index = require("./index-BJj5EZfj.js");
7
7
  const react = require("react");
8
8
  const SettingsPage = () => {
9
9
  const { formatMessage } = reactIntl.useIntl();
@@ -48,4 +48,4 @@ const SettingsPage = () => {
48
48
  ] });
49
49
  };
50
50
  exports.default = SettingsPage;
51
- //# sourceMappingURL=index-nPKhLzd1.js.map
51
+ //# sourceMappingURL=index-7Lm6jbM0.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index-B4lfccXW.js","sources":["../../admin/src/components/SettingsPage/index.tsx"],"sourcesContent":["import { TextInput, Typography } from '@strapi/design-system';\nimport { useIntl } from 'react-intl';\nimport PurgeModal from '../PurgeModal';\nimport { useState } from 'react';\n\nconst SettingsPage = () => {\n const { formatMessage } = useIntl();\n const [keyToUse, setKeyToUse] = useState<string>('');\n\n return (\n <div style={{ padding: '20px' }}>\n <Typography variant=\"alpha\" as=\"h1\">\n {formatMessage({\n id: 'strapi-cache.name',\n defaultMessage: 'Strapi Cache Settings',\n })}\n </Typography>\n\n <div style={{ marginTop: '16px', marginBottom: '24px' }}>\n <Typography variant=\"omega\">\n {formatMessage({\n id: 'strapi-cache.settings.description',\n defaultMessage:\n 'Enter a cache key below and click \"Purge Cache\" to clear specific cached content.',\n })}\n </Typography>\n </div>\n\n <div\n style={{\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n gap: '12px',\n maxWidth: '400px',\n }}\n >\n <div style={{ flex: 1 }}>\n <TextInput\n placeholder={formatMessage({\n id: 'strapi-cache.settings.key-placeholder',\n defaultMessage: 'Enter cache key to purge',\n })}\n size=\"M\"\n type=\"text\"\n value={keyToUse}\n onChange={(e: React.ChangeEvent<HTMLInputElement>) => setKeyToUse(e.target.value)}\n />\n </div>\n <PurgeModal buttonText=\"Purge Cache\" keyToUse={keyToUse} isSettingsPage />\n </div>\n </div>\n );\n};\n\nexport default SettingsPage;\n"],"names":["useIntl","useState","jsx","Typography","jsxs","TextInput","PurgeModal"],"mappings":";;;;;;;AAKA,MAAM,eAAe,MAAM;AACnB,QAAA,EAAE,cAAc,IAAIA,kBAAQ;AAClC,QAAM,CAAC,UAAU,WAAW,IAAIC,MAAAA,SAAiB,EAAE;AAEnD,yCACG,OAAI,EAAA,OAAO,EAAE,SAAS,OACrB,GAAA,UAAA;AAAA,IAAAC,+BAACC,aAAAA,YAAW,EAAA,SAAQ,SAAQ,IAAG,MAC5B,UAAc,cAAA;AAAA,MACb,IAAI;AAAA,MACJ,gBAAgB;AAAA,IACjB,CAAA,GACH;AAAA,IAECD,2BAAA,IAAA,OAAA,EAAI,OAAO,EAAE,WAAW,QAAQ,cAAc,OAC7C,GAAA,UAAAA,2BAAA,IAACC,yBAAW,EAAA,SAAQ,SACjB,UAAc,cAAA;AAAA,MACb,IAAI;AAAA,MACJ,gBACE;AAAA,IAAA,CACH,GACH,EACF,CAAA;AAAA,IAEAC,2BAAA;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,OAAO;AAAA,UACL,SAAS;AAAA,UACT,gBAAgB;AAAA,UAChB,YAAY;AAAA,UACZ,KAAK;AAAA,UACL,UAAU;AAAA,QACZ;AAAA,QAEA,UAAA;AAAA,UAAAF,2BAAA,IAAC,OAAI,EAAA,OAAO,EAAE,MAAM,KAClB,UAAAA,2BAAA;AAAA,YAACG,aAAA;AAAA,YAAA;AAAA,cACC,aAAa,cAAc;AAAA,gBACzB,IAAI;AAAA,gBACJ,gBAAgB;AAAA,cAAA,CACjB;AAAA,cACD,MAAK;AAAA,cACL,MAAK;AAAA,cACL,OAAO;AAAA,cACP,UAAU,CAAC,MAA2C,YAAY,EAAE,OAAO,KAAK;AAAA,YAAA;AAAA,UAAA,GAEpF;AAAA,yCACCC,MAAW,YAAA,EAAA,YAAW,eAAc,UAAoB,gBAAc,KAAC,CAAA;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,EAC1E,GACF;AAEJ;;"}
1
+ {"version":3,"file":"index-7Lm6jbM0.js","sources":["../../admin/src/components/SettingsPage/index.tsx"],"sourcesContent":["import { TextInput, Typography } from '@strapi/design-system';\nimport { useIntl } from 'react-intl';\nimport PurgeModal from '../PurgeModal';\nimport { useState } from 'react';\n\nconst SettingsPage = () => {\n const { formatMessage } = useIntl();\n const [keyToUse, setKeyToUse] = useState<string>('');\n\n return (\n <div style={{ padding: '20px' }}>\n <Typography variant=\"alpha\" as=\"h1\">\n {formatMessage({\n id: 'strapi-cache.name',\n defaultMessage: 'Strapi Cache Settings',\n })}\n </Typography>\n\n <div style={{ marginTop: '16px', marginBottom: '24px' }}>\n <Typography variant=\"omega\">\n {formatMessage({\n id: 'strapi-cache.settings.description',\n defaultMessage:\n 'Enter a cache key below and click \"Purge Cache\" to clear specific cached content.',\n })}\n </Typography>\n </div>\n\n <div\n style={{\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n gap: '12px',\n maxWidth: '400px',\n }}\n >\n <div style={{ flex: 1 }}>\n <TextInput\n placeholder={formatMessage({\n id: 'strapi-cache.settings.key-placeholder',\n defaultMessage: 'Enter cache key to purge',\n })}\n size=\"M\"\n type=\"text\"\n value={keyToUse}\n onChange={(e: React.ChangeEvent<HTMLInputElement>) => setKeyToUse(e.target.value)}\n />\n </div>\n <PurgeModal buttonText=\"Purge Cache\" keyToUse={keyToUse} isSettingsPage />\n </div>\n </div>\n );\n};\n\nexport default SettingsPage;\n"],"names":["useIntl","useState","jsx","Typography","jsxs","TextInput","PurgeModal"],"mappings":";;;;;;;AAKA,MAAM,eAAe,MAAM;AACnB,QAAA,EAAE,cAAc,IAAIA,kBAAQ;AAClC,QAAM,CAAC,UAAU,WAAW,IAAIC,MAAAA,SAAiB,EAAE;AAEnD,yCACG,OAAI,EAAA,OAAO,EAAE,SAAS,OACrB,GAAA,UAAA;AAAA,IAAAC,+BAACC,aAAAA,YAAW,EAAA,SAAQ,SAAQ,IAAG,MAC5B,UAAc,cAAA;AAAA,MACb,IAAI;AAAA,MACJ,gBAAgB;AAAA,IACjB,CAAA,GACH;AAAA,IAECD,2BAAA,IAAA,OAAA,EAAI,OAAO,EAAE,WAAW,QAAQ,cAAc,OAC7C,GAAA,UAAAA,2BAAA,IAACC,yBAAW,EAAA,SAAQ,SACjB,UAAc,cAAA;AAAA,MACb,IAAI;AAAA,MACJ,gBACE;AAAA,IAAA,CACH,GACH,EACF,CAAA;AAAA,IAEAC,2BAAA;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,OAAO;AAAA,UACL,SAAS;AAAA,UACT,gBAAgB;AAAA,UAChB,YAAY;AAAA,UACZ,KAAK;AAAA,UACL,UAAU;AAAA,QACZ;AAAA,QAEA,UAAA;AAAA,UAAAF,2BAAA,IAAC,OAAI,EAAA,OAAO,EAAE,MAAM,KAClB,UAAAA,2BAAA;AAAA,YAACG,aAAA;AAAA,YAAA;AAAA,cACC,aAAa,cAAc;AAAA,gBACzB,IAAI;AAAA,gBACJ,gBAAgB;AAAA,cAAA,CACjB;AAAA,cACD,MAAK;AAAA,cACL,MAAK;AAAA,cACL,OAAO;AAAA,cACP,UAAU,CAAC,MAA2C,YAAY,EAAE,OAAO,KAAK;AAAA,YAAA;AAAA,UAAA,GAEpF;AAAA,yCACCC,MAAW,YAAA,EAAA,YAAW,eAAc,UAAoB,gBAAc,KAAC,CAAA;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,EAC1E,GACF;AAEJ;;"}
@@ -102,11 +102,15 @@ const useCacheOperations = () => {
102
102
  };
103
103
  }
104
104
  try {
105
- await post(`/strapi-cache/purge-cache/${keyToUse}`, void 0, {
106
- headers: {
107
- "Content-Type": "application/json"
105
+ await post(
106
+ `/strapi-cache/purge-cache/key`,
107
+ { key: keyToUse },
108
+ {
109
+ headers: {
110
+ "Content-Type": "application/json"
111
+ }
108
112
  }
109
- });
113
+ );
110
114
  return {
111
115
  success: true,
112
116
  message: `Cache purged successfully for key: "${keyToUse}"`
@@ -314,7 +318,7 @@ const index = {
314
318
  },
315
319
  id: "settings",
316
320
  to: `${PLUGIN_ID}/settings`,
317
- Component: () => Promise.resolve().then(() => require("./index-nPKhLzd1.js")),
321
+ Component: () => Promise.resolve().then(() => require("./index-7Lm6jbM0.js")),
318
322
  permissions: []
319
323
  }
320
324
  ]
@@ -335,4 +339,4 @@ const index = {
335
339
  };
336
340
  exports.PurgeModal = PurgeModal;
337
341
  exports.index = index;
338
- //# sourceMappingURL=index-BsW67w0G.js.map
342
+ //# sourceMappingURL=index-BJj5EZfj.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-BJj5EZfj.js","sources":["../../admin/src/pluginId.ts","../../admin/src/components/Initializer.tsx","../../admin/src/hooks/useCacheConfig.ts","../../admin/src/permission.ts","../../admin/src/hooks/useCachePermissions.ts","../../admin/src/hooks/useCacheOperations.ts","../../admin/src/hooks/useCacheNotifications.ts","../../admin/src/components/PurgeModal/index.tsx","../../admin/src/components/PurgeCacheButton/index.tsx","../../admin/src/components/PurgeEntityButton/index.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 { useState, useEffect } from 'react';\nimport { useFetchClient } from '@strapi/strapi/admin';\n\nexport type CacheConfig = {\n cacheableRoutes: string[];\n disableAdminPopups: boolean;\n};\n\nexport const useCacheConfig = (enabled: boolean = true) => {\n const [config, setConfig] = useState<CacheConfig>();\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const { get } = useFetchClient();\n\n useEffect(() => {\n if (!enabled) {\n return;\n }\n\n const fetchConfig = async () => {\n setIsLoading(true);\n setError(null);\n\n try {\n const { data } = await get('/strapi-cache/config');\n setConfig(data);\n } catch (error: any) {\n setError(error);\n } finally {\n setIsLoading(false);\n }\n };\n\n fetchConfig();\n }, [enabled, get]);\n\n return {\n config,\n isLoading,\n error,\n refetch: () => {\n const fetchConfig = async () => {\n setIsLoading(true);\n setError(null);\n\n try {\n const { data } = await get('/strapi-cache/config');\n setConfig(data);\n } catch (error: any) {\n setError(error);\n } finally {\n setIsLoading(false);\n }\n };\n fetchConfig();\n },\n };\n};\n","export const pluginPermissions = {\n purge: [{ action: 'plugin::strapi-cache.purge-cache', subject: null }],\n};\n","import { useRBAC } from '@strapi/strapi/admin';\nimport { pluginPermissions } from '../permission';\n\nexport const useCachePermissions = () => {\n const { allowedActions } = useRBAC(pluginPermissions);\n\n return {\n canPurgeCache: allowedActions.canPurgeCache,\n allowedActions,\n };\n};\n","import { useFetchClient } from '@strapi/strapi/admin';\nimport { CacheConfig } from './useCacheConfig';\n\nexport type CacheOperationResult = {\n success: boolean;\n message?: string;\n error?: Error;\n};\n\nexport const useCacheOperations = () => {\n const { post } = useFetchClient();\n\n const isCacheableRoute = (\n keyToUse?: string,\n contentTypeName?: string,\n config?: CacheConfig\n ): boolean => {\n if (!keyToUse || !config) {\n return false;\n }\n\n const { cacheableRoutes } = config;\n return (\n cacheableRoutes.length === 0 ||\n cacheableRoutes.some((route) => {\n return route.includes(keyToUse) || (contentTypeName && route.includes(contentTypeName));\n })\n );\n };\n\n const clearCache = async (keyToUse?: string): Promise<CacheOperationResult> => {\n if (!keyToUse) {\n return {\n success: false,\n message: 'No content type found',\n };\n }\n\n try {\n await post(\n `/strapi-cache/purge-cache/key`,\n { key: keyToUse },\n {\n headers: {\n 'Content-Type': 'application/json',\n },\n }\n );\n\n return {\n success: true,\n message: `Cache purged successfully for key: \"${keyToUse}\"`,\n };\n } catch (error: any) {\n return {\n success: false,\n message: `Error purging cache for key: \"${keyToUse}\"`,\n error,\n };\n }\n };\n\n return {\n isCacheableRoute,\n clearCache,\n };\n};\n","import { useIntl } from 'react-intl';\nimport { useNotification } from '@strapi/strapi/admin';\nimport { CacheConfig } from './useCacheConfig';\n\nexport const useCacheNotifications = (config?: CacheConfig) => {\n const formatMessage = useIntl().formatMessage;\n const { toggleNotification } = useNotification();\n\n const showConfigFetchError = (error: Error) => {\n // only show error notification if its not a permissions error and popups are not disabled\n const isPermissionError =\n (error as any)?.response?.status === 403 || (error as any)?.response?.status === 401;\n\n if (!isPermissionError && !config?.disableAdminPopups) {\n toggleNotification({\n type: 'warning',\n message: formatMessage({\n id: 'strapi-cache.cache.routes.fetch-error',\n defaultMessage: 'Unable to fetch cache config. Cache purge may not work correctly.',\n }),\n });\n }\n };\n\n const showPurgeSuccess = (key: string) => {\n if (!config?.disableAdminPopups) {\n toggleNotification({\n type: 'success',\n message: formatMessage(\n {\n id: 'strapi-cache.cache.purge.success',\n defaultMessage: 'Cache purged successfully',\n },\n {\n key: `\"${key}\"`,\n }\n ),\n });\n }\n };\n\n const showPurgeError = (key: string) => {\n if (!config?.disableAdminPopups) {\n toggleNotification({\n type: 'danger',\n message: formatMessage(\n {\n id: 'strapi-cache.cache.purge.error',\n defaultMessage: 'Error purging cache',\n },\n {\n key: `\"${key}\"`,\n }\n ),\n });\n }\n };\n\n const showNoContentTypeWarning = () => {\n if (!config?.disableAdminPopups) {\n toggleNotification({\n type: 'warning',\n message: formatMessage({\n id: 'strapi-cache.cache.purge.no-content-type',\n defaultMessage: 'No content type found',\n }),\n });\n }\n };\n\n return {\n showConfigFetchError,\n showPurgeSuccess,\n showPurgeError,\n showNoContentTypeWarning,\n };\n};\n","import { useIntl } from 'react-intl';\nimport { Archive } from '@strapi/icons';\nimport { Button, Modal } from '@strapi/design-system';\nimport { Typography } from '@strapi/design-system';\nimport { useEffect } from 'react';\nimport {\n useCacheConfig,\n useCachePermissions,\n useCacheOperations,\n useCacheNotifications,\n} from '../../hooks';\n\nexport type PurgeProps = {\n buttonText: string;\n buttonWidth?: string;\n keyToUse?: string;\n contentTypeName?: string;\n isSettingsPage?: boolean;\n};\n\nfunction PurgeModal({\n buttonText,\n keyToUse,\n buttonWidth,\n contentTypeName,\n isSettingsPage,\n}: PurgeProps) {\n const { canPurgeCache } = useCachePermissions();\n const { config, error: configError } = useCacheConfig(canPurgeCache);\n const { isCacheableRoute, clearCache } = useCacheOperations();\n const { showConfigFetchError, showPurgeSuccess, showPurgeError, showNoContentTypeWarning } =\n useCacheNotifications(config);\n const formatMessage = useIntl().formatMessage;\n\n useEffect(() => {\n if (configError) {\n showConfigFetchError(configError);\n }\n }, [configError, showConfigFetchError]);\n\n const handleClearCache = async () => {\n if (!keyToUse) {\n showNoContentTypeWarning();\n return;\n }\n\n const result = await clearCache(keyToUse);\n\n if (result.success) {\n showPurgeSuccess(keyToUse);\n } else {\n showPurgeError(keyToUse);\n }\n };\n\n if (!canPurgeCache || (!isSettingsPage && !isCacheableRoute(keyToUse, contentTypeName, config))) {\n return null;\n }\n\n return (\n <Modal.Root>\n <Modal.Trigger>\n <Button width={buttonWidth} disabled={!keyToUse} startIcon={<Archive />} variant=\"danger\">\n {buttonText}\n </Button>\n </Modal.Trigger>\n <Modal.Content>\n <Modal.Header>\n <Modal.Title>{buttonText}</Modal.Title>\n </Modal.Header>\n <Modal.Body>\n <Typography variant=\"omega\">\n {formatMessage(\n {\n id: 'strapi-cache.cache.purge.confirmation',\n defaultMessage: 'Are you sure you want to purge the cache?',\n },\n { key: `\"${keyToUse}\"` }\n )}\n </Typography>\n </Modal.Body>\n <Modal.Footer>\n <Modal.Close>\n <Button variant=\"tertiary\">\n {formatMessage({\n id: 'strapi-cache.cache.cancel',\n defaultMessage: 'No, cancel',\n })}\n </Button>\n </Modal.Close>\n <Modal.Close>\n <Button onClick={handleClearCache}>\n {formatMessage({\n id: 'strapi-cache.cache.confirm',\n defaultMessage: 'Yes, confirm',\n })}\n </Button>\n </Modal.Close>\n </Modal.Footer>\n </Modal.Content>\n </Modal.Root>\n );\n}\n\nexport default PurgeModal;\n","import { unstable_useContentManagerContext as useContentManagerContext } from '@strapi/strapi/admin';\nimport PurgeModal from '../PurgeModal';\nimport { useIntl } from 'react-intl';\n\nfunction PurgeCacheButton() {\n const { contentType } = useContentManagerContext();\n const { formatMessage } = useIntl();\n const keyToUse = contentType?.info.pluralName;\n\n return (\n <PurgeModal\n buttonText={formatMessage({\n id: 'strapi-cache.cache.purge',\n defaultMessage: 'Purge Cache',\n })}\n keyToUse={keyToUse}\n ></PurgeModal>\n );\n}\n\nexport default PurgeCacheButton;\n","import { unstable_useContentManagerContext as useContentManagerContext } from '@strapi/strapi/admin';\nimport PurgeModal from '../PurgeModal';\nimport { useIntl } from 'react-intl';\n\nfunction PurgeEntityButton() {\n const { formatMessage } = useIntl();\n const { id, isSingleType, contentType } = useContentManagerContext();\n const apiPath = isSingleType ? contentType?.info.singularName : id;\n\n if (!apiPath) {\n return null;\n }\n\n const keyToUse = encodeURIComponent(apiPath);\n const contentTypeName = isSingleType\n ? contentType?.info.singularName\n : contentType?.info.pluralName;\n\n return (\n <PurgeModal\n buttonWidth=\"100%\"\n buttonText={formatMessage({\n id: 'strapi-cache.cache.purge.entity',\n defaultMessage: 'Purge Entity Cache',\n })}\n keyToUse={keyToUse}\n contentTypeName={contentTypeName}\n ></PurgeModal>\n );\n}\n\nexport default PurgeEntityButton;\n","import { PLUGIN_ID } from './pluginId';\nimport { Initializer } from './components/Initializer';\nimport PurgeCacheButton from './components/PurgeCacheButton';\nimport PurgeEntityButton from './components/PurgeEntityButton';\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 app.getPlugin('content-manager').injectComponent('listView', 'actions', {\n name: PurgeCacheButton,\n Component: PurgeCacheButton,\n });\n\n app.getPlugin('content-manager').injectComponent('editView', 'right-links', {\n name: PurgeEntityButton,\n Component: PurgeEntityButton,\n });\n\n app.createSettingSection(\n {\n id: PLUGIN_ID,\n intlLabel: {\n id: 'strapi-cache.settings.link',\n defaultMessage: 'Strapi Cache',\n },\n },\n [\n {\n intlLabel: {\n id: 'strapi-cache.settings.link',\n defaultMessage: 'Strapi Cache',\n },\n id: 'settings',\n to: `${PLUGIN_ID}/settings`,\n Component: () => import('./components/SettingsPage'),\n permissions: [],\n },\n ]\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","useState","useFetchClient","error","useRBAC","useIntl","useNotification","jsxs","Modal","jsx","Button","Archive","Typography","useContentManagerContext"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  import { jsxs, jsx } from "react/jsx-runtime";
2
2
  import { Typography, TextInput } from "@strapi/design-system";
3
3
  import { useIntl } from "react-intl";
4
- import { P as PurgeModal } from "./index-CH_6jFHP.mjs";
4
+ import { P as PurgeModal } from "./index-dynpWXaG.mjs";
5
5
  import { useState } from "react";
6
6
  const SettingsPage = () => {
7
7
  const { formatMessage } = useIntl();
@@ -48,4 +48,4 @@ const SettingsPage = () => {
48
48
  export {
49
49
  SettingsPage as default
50
50
  };
51
- //# sourceMappingURL=index-B2N_r7ow.mjs.map
51
+ //# sourceMappingURL=index-BS9N2eCV.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index-B2N_r7ow.mjs","sources":["../../admin/src/components/SettingsPage/index.tsx"],"sourcesContent":["import { TextInput, Typography } from '@strapi/design-system';\nimport { useIntl } from 'react-intl';\nimport PurgeModal from '../PurgeModal';\nimport { useState } from 'react';\n\nconst SettingsPage = () => {\n const { formatMessage } = useIntl();\n const [keyToUse, setKeyToUse] = useState<string>('');\n\n return (\n <div style={{ padding: '20px' }}>\n <Typography variant=\"alpha\" as=\"h1\">\n {formatMessage({\n id: 'strapi-cache.name',\n defaultMessage: 'Strapi Cache Settings',\n })}\n </Typography>\n\n <div style={{ marginTop: '16px', marginBottom: '24px' }}>\n <Typography variant=\"omega\">\n {formatMessage({\n id: 'strapi-cache.settings.description',\n defaultMessage:\n 'Enter a cache key below and click \"Purge Cache\" to clear specific cached content.',\n })}\n </Typography>\n </div>\n\n <div\n style={{\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n gap: '12px',\n maxWidth: '400px',\n }}\n >\n <div style={{ flex: 1 }}>\n <TextInput\n placeholder={formatMessage({\n id: 'strapi-cache.settings.key-placeholder',\n defaultMessage: 'Enter cache key to purge',\n })}\n size=\"M\"\n type=\"text\"\n value={keyToUse}\n onChange={(e: React.ChangeEvent<HTMLInputElement>) => setKeyToUse(e.target.value)}\n />\n </div>\n <PurgeModal buttonText=\"Purge Cache\" keyToUse={keyToUse} isSettingsPage />\n </div>\n </div>\n );\n};\n\nexport default SettingsPage;\n"],"names":[],"mappings":";;;;;AAKA,MAAM,eAAe,MAAM;AACnB,QAAA,EAAE,cAAc,IAAI,QAAQ;AAClC,QAAM,CAAC,UAAU,WAAW,IAAI,SAAiB,EAAE;AAEnD,8BACG,OAAI,EAAA,OAAO,EAAE,SAAS,OACrB,GAAA,UAAA;AAAA,IAAA,oBAAC,YAAW,EAAA,SAAQ,SAAQ,IAAG,MAC5B,UAAc,cAAA;AAAA,MACb,IAAI;AAAA,MACJ,gBAAgB;AAAA,IACjB,CAAA,GACH;AAAA,IAEC,oBAAA,OAAA,EAAI,OAAO,EAAE,WAAW,QAAQ,cAAc,OAC7C,GAAA,UAAA,oBAAC,YAAW,EAAA,SAAQ,SACjB,UAAc,cAAA;AAAA,MACb,IAAI;AAAA,MACJ,gBACE;AAAA,IAAA,CACH,GACH,EACF,CAAA;AAAA,IAEA;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,OAAO;AAAA,UACL,SAAS;AAAA,UACT,gBAAgB;AAAA,UAChB,YAAY;AAAA,UACZ,KAAK;AAAA,UACL,UAAU;AAAA,QACZ;AAAA,QAEA,UAAA;AAAA,UAAA,oBAAC,OAAI,EAAA,OAAO,EAAE,MAAM,KAClB,UAAA;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,aAAa,cAAc;AAAA,gBACzB,IAAI;AAAA,gBACJ,gBAAgB;AAAA,cAAA,CACjB;AAAA,cACD,MAAK;AAAA,cACL,MAAK;AAAA,cACL,OAAO;AAAA,cACP,UAAU,CAAC,MAA2C,YAAY,EAAE,OAAO,KAAK;AAAA,YAAA;AAAA,UAAA,GAEpF;AAAA,8BACC,YAAW,EAAA,YAAW,eAAc,UAAoB,gBAAc,KAAC,CAAA;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,EAC1E,GACF;AAEJ;"}
1
+ {"version":3,"file":"index-BS9N2eCV.mjs","sources":["../../admin/src/components/SettingsPage/index.tsx"],"sourcesContent":["import { TextInput, Typography } from '@strapi/design-system';\nimport { useIntl } from 'react-intl';\nimport PurgeModal from '../PurgeModal';\nimport { useState } from 'react';\n\nconst SettingsPage = () => {\n const { formatMessage } = useIntl();\n const [keyToUse, setKeyToUse] = useState<string>('');\n\n return (\n <div style={{ padding: '20px' }}>\n <Typography variant=\"alpha\" as=\"h1\">\n {formatMessage({\n id: 'strapi-cache.name',\n defaultMessage: 'Strapi Cache Settings',\n })}\n </Typography>\n\n <div style={{ marginTop: '16px', marginBottom: '24px' }}>\n <Typography variant=\"omega\">\n {formatMessage({\n id: 'strapi-cache.settings.description',\n defaultMessage:\n 'Enter a cache key below and click \"Purge Cache\" to clear specific cached content.',\n })}\n </Typography>\n </div>\n\n <div\n style={{\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n gap: '12px',\n maxWidth: '400px',\n }}\n >\n <div style={{ flex: 1 }}>\n <TextInput\n placeholder={formatMessage({\n id: 'strapi-cache.settings.key-placeholder',\n defaultMessage: 'Enter cache key to purge',\n })}\n size=\"M\"\n type=\"text\"\n value={keyToUse}\n onChange={(e: React.ChangeEvent<HTMLInputElement>) => setKeyToUse(e.target.value)}\n />\n </div>\n <PurgeModal buttonText=\"Purge Cache\" keyToUse={keyToUse} isSettingsPage />\n </div>\n </div>\n );\n};\n\nexport default SettingsPage;\n"],"names":[],"mappings":";;;;;AAKA,MAAM,eAAe,MAAM;AACnB,QAAA,EAAE,cAAc,IAAI,QAAQ;AAClC,QAAM,CAAC,UAAU,WAAW,IAAI,SAAiB,EAAE;AAEnD,8BACG,OAAI,EAAA,OAAO,EAAE,SAAS,OACrB,GAAA,UAAA;AAAA,IAAA,oBAAC,YAAW,EAAA,SAAQ,SAAQ,IAAG,MAC5B,UAAc,cAAA;AAAA,MACb,IAAI;AAAA,MACJ,gBAAgB;AAAA,IACjB,CAAA,GACH;AAAA,IAEC,oBAAA,OAAA,EAAI,OAAO,EAAE,WAAW,QAAQ,cAAc,OAC7C,GAAA,UAAA,oBAAC,YAAW,EAAA,SAAQ,SACjB,UAAc,cAAA;AAAA,MACb,IAAI;AAAA,MACJ,gBACE;AAAA,IAAA,CACH,GACH,EACF,CAAA;AAAA,IAEA;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,OAAO;AAAA,UACL,SAAS;AAAA,UACT,gBAAgB;AAAA,UAChB,YAAY;AAAA,UACZ,KAAK;AAAA,UACL,UAAU;AAAA,QACZ;AAAA,QAEA,UAAA;AAAA,UAAA,oBAAC,OAAI,EAAA,OAAO,EAAE,MAAM,KAClB,UAAA;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,aAAa,cAAc;AAAA,gBACzB,IAAI;AAAA,gBACJ,gBAAgB;AAAA,cAAA,CACjB;AAAA,cACD,MAAK;AAAA,cACL,MAAK;AAAA,cACL,OAAO;AAAA,cACP,UAAU,CAAC,MAA2C,YAAY,EAAE,OAAO,KAAK;AAAA,YAAA;AAAA,UAAA,GAEpF;AAAA,8BACC,YAAW,EAAA,YAAW,eAAc,UAAoB,gBAAc,KAAC,CAAA;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,EAC1E,GACF;AAEJ;"}
@@ -101,11 +101,15 @@ const useCacheOperations = () => {
101
101
  };
102
102
  }
103
103
  try {
104
- await post(`/strapi-cache/purge-cache/${keyToUse}`, void 0, {
105
- headers: {
106
- "Content-Type": "application/json"
104
+ await post(
105
+ `/strapi-cache/purge-cache/key`,
106
+ { key: keyToUse },
107
+ {
108
+ headers: {
109
+ "Content-Type": "application/json"
110
+ }
107
111
  }
108
- });
112
+ );
109
113
  return {
110
114
  success: true,
111
115
  message: `Cache purged successfully for key: "${keyToUse}"`
@@ -313,7 +317,7 @@ const index = {
313
317
  },
314
318
  id: "settings",
315
319
  to: `${PLUGIN_ID}/settings`,
316
- Component: () => import("./index-B2N_r7ow.mjs"),
320
+ Component: () => import("./index-BS9N2eCV.mjs"),
317
321
  permissions: []
318
322
  }
319
323
  ]
@@ -336,4 +340,4 @@ export {
336
340
  PurgeModal as P,
337
341
  index as i
338
342
  };
339
- //# sourceMappingURL=index-CH_6jFHP.mjs.map
343
+ //# sourceMappingURL=index-dynpWXaG.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-dynpWXaG.mjs","sources":["../../admin/src/pluginId.ts","../../admin/src/components/Initializer.tsx","../../admin/src/hooks/useCacheConfig.ts","../../admin/src/permission.ts","../../admin/src/hooks/useCachePermissions.ts","../../admin/src/hooks/useCacheOperations.ts","../../admin/src/hooks/useCacheNotifications.ts","../../admin/src/components/PurgeModal/index.tsx","../../admin/src/components/PurgeCacheButton/index.tsx","../../admin/src/components/PurgeEntityButton/index.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 { useState, useEffect } from 'react';\nimport { useFetchClient } from '@strapi/strapi/admin';\n\nexport type CacheConfig = {\n cacheableRoutes: string[];\n disableAdminPopups: boolean;\n};\n\nexport const useCacheConfig = (enabled: boolean = true) => {\n const [config, setConfig] = useState<CacheConfig>();\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const { get } = useFetchClient();\n\n useEffect(() => {\n if (!enabled) {\n return;\n }\n\n const fetchConfig = async () => {\n setIsLoading(true);\n setError(null);\n\n try {\n const { data } = await get('/strapi-cache/config');\n setConfig(data);\n } catch (error: any) {\n setError(error);\n } finally {\n setIsLoading(false);\n }\n };\n\n fetchConfig();\n }, [enabled, get]);\n\n return {\n config,\n isLoading,\n error,\n refetch: () => {\n const fetchConfig = async () => {\n setIsLoading(true);\n setError(null);\n\n try {\n const { data } = await get('/strapi-cache/config');\n setConfig(data);\n } catch (error: any) {\n setError(error);\n } finally {\n setIsLoading(false);\n }\n };\n fetchConfig();\n },\n };\n};\n","export const pluginPermissions = {\n purge: [{ action: 'plugin::strapi-cache.purge-cache', subject: null }],\n};\n","import { useRBAC } from '@strapi/strapi/admin';\nimport { pluginPermissions } from '../permission';\n\nexport const useCachePermissions = () => {\n const { allowedActions } = useRBAC(pluginPermissions);\n\n return {\n canPurgeCache: allowedActions.canPurgeCache,\n allowedActions,\n };\n};\n","import { useFetchClient } from '@strapi/strapi/admin';\nimport { CacheConfig } from './useCacheConfig';\n\nexport type CacheOperationResult = {\n success: boolean;\n message?: string;\n error?: Error;\n};\n\nexport const useCacheOperations = () => {\n const { post } = useFetchClient();\n\n const isCacheableRoute = (\n keyToUse?: string,\n contentTypeName?: string,\n config?: CacheConfig\n ): boolean => {\n if (!keyToUse || !config) {\n return false;\n }\n\n const { cacheableRoutes } = config;\n return (\n cacheableRoutes.length === 0 ||\n cacheableRoutes.some((route) => {\n return route.includes(keyToUse) || (contentTypeName && route.includes(contentTypeName));\n })\n );\n };\n\n const clearCache = async (keyToUse?: string): Promise<CacheOperationResult> => {\n if (!keyToUse) {\n return {\n success: false,\n message: 'No content type found',\n };\n }\n\n try {\n await post(\n `/strapi-cache/purge-cache/key`,\n { key: keyToUse },\n {\n headers: {\n 'Content-Type': 'application/json',\n },\n }\n );\n\n return {\n success: true,\n message: `Cache purged successfully for key: \"${keyToUse}\"`,\n };\n } catch (error: any) {\n return {\n success: false,\n message: `Error purging cache for key: \"${keyToUse}\"`,\n error,\n };\n }\n };\n\n return {\n isCacheableRoute,\n clearCache,\n };\n};\n","import { useIntl } from 'react-intl';\nimport { useNotification } from '@strapi/strapi/admin';\nimport { CacheConfig } from './useCacheConfig';\n\nexport const useCacheNotifications = (config?: CacheConfig) => {\n const formatMessage = useIntl().formatMessage;\n const { toggleNotification } = useNotification();\n\n const showConfigFetchError = (error: Error) => {\n // only show error notification if its not a permissions error and popups are not disabled\n const isPermissionError =\n (error as any)?.response?.status === 403 || (error as any)?.response?.status === 401;\n\n if (!isPermissionError && !config?.disableAdminPopups) {\n toggleNotification({\n type: 'warning',\n message: formatMessage({\n id: 'strapi-cache.cache.routes.fetch-error',\n defaultMessage: 'Unable to fetch cache config. Cache purge may not work correctly.',\n }),\n });\n }\n };\n\n const showPurgeSuccess = (key: string) => {\n if (!config?.disableAdminPopups) {\n toggleNotification({\n type: 'success',\n message: formatMessage(\n {\n id: 'strapi-cache.cache.purge.success',\n defaultMessage: 'Cache purged successfully',\n },\n {\n key: `\"${key}\"`,\n }\n ),\n });\n }\n };\n\n const showPurgeError = (key: string) => {\n if (!config?.disableAdminPopups) {\n toggleNotification({\n type: 'danger',\n message: formatMessage(\n {\n id: 'strapi-cache.cache.purge.error',\n defaultMessage: 'Error purging cache',\n },\n {\n key: `\"${key}\"`,\n }\n ),\n });\n }\n };\n\n const showNoContentTypeWarning = () => {\n if (!config?.disableAdminPopups) {\n toggleNotification({\n type: 'warning',\n message: formatMessage({\n id: 'strapi-cache.cache.purge.no-content-type',\n defaultMessage: 'No content type found',\n }),\n });\n }\n };\n\n return {\n showConfigFetchError,\n showPurgeSuccess,\n showPurgeError,\n showNoContentTypeWarning,\n };\n};\n","import { useIntl } from 'react-intl';\nimport { Archive } from '@strapi/icons';\nimport { Button, Modal } from '@strapi/design-system';\nimport { Typography } from '@strapi/design-system';\nimport { useEffect } from 'react';\nimport {\n useCacheConfig,\n useCachePermissions,\n useCacheOperations,\n useCacheNotifications,\n} from '../../hooks';\n\nexport type PurgeProps = {\n buttonText: string;\n buttonWidth?: string;\n keyToUse?: string;\n contentTypeName?: string;\n isSettingsPage?: boolean;\n};\n\nfunction PurgeModal({\n buttonText,\n keyToUse,\n buttonWidth,\n contentTypeName,\n isSettingsPage,\n}: PurgeProps) {\n const { canPurgeCache } = useCachePermissions();\n const { config, error: configError } = useCacheConfig(canPurgeCache);\n const { isCacheableRoute, clearCache } = useCacheOperations();\n const { showConfigFetchError, showPurgeSuccess, showPurgeError, showNoContentTypeWarning } =\n useCacheNotifications(config);\n const formatMessage = useIntl().formatMessage;\n\n useEffect(() => {\n if (configError) {\n showConfigFetchError(configError);\n }\n }, [configError, showConfigFetchError]);\n\n const handleClearCache = async () => {\n if (!keyToUse) {\n showNoContentTypeWarning();\n return;\n }\n\n const result = await clearCache(keyToUse);\n\n if (result.success) {\n showPurgeSuccess(keyToUse);\n } else {\n showPurgeError(keyToUse);\n }\n };\n\n if (!canPurgeCache || (!isSettingsPage && !isCacheableRoute(keyToUse, contentTypeName, config))) {\n return null;\n }\n\n return (\n <Modal.Root>\n <Modal.Trigger>\n <Button width={buttonWidth} disabled={!keyToUse} startIcon={<Archive />} variant=\"danger\">\n {buttonText}\n </Button>\n </Modal.Trigger>\n <Modal.Content>\n <Modal.Header>\n <Modal.Title>{buttonText}</Modal.Title>\n </Modal.Header>\n <Modal.Body>\n <Typography variant=\"omega\">\n {formatMessage(\n {\n id: 'strapi-cache.cache.purge.confirmation',\n defaultMessage: 'Are you sure you want to purge the cache?',\n },\n { key: `\"${keyToUse}\"` }\n )}\n </Typography>\n </Modal.Body>\n <Modal.Footer>\n <Modal.Close>\n <Button variant=\"tertiary\">\n {formatMessage({\n id: 'strapi-cache.cache.cancel',\n defaultMessage: 'No, cancel',\n })}\n </Button>\n </Modal.Close>\n <Modal.Close>\n <Button onClick={handleClearCache}>\n {formatMessage({\n id: 'strapi-cache.cache.confirm',\n defaultMessage: 'Yes, confirm',\n })}\n </Button>\n </Modal.Close>\n </Modal.Footer>\n </Modal.Content>\n </Modal.Root>\n );\n}\n\nexport default PurgeModal;\n","import { unstable_useContentManagerContext as useContentManagerContext } from '@strapi/strapi/admin';\nimport PurgeModal from '../PurgeModal';\nimport { useIntl } from 'react-intl';\n\nfunction PurgeCacheButton() {\n const { contentType } = useContentManagerContext();\n const { formatMessage } = useIntl();\n const keyToUse = contentType?.info.pluralName;\n\n return (\n <PurgeModal\n buttonText={formatMessage({\n id: 'strapi-cache.cache.purge',\n defaultMessage: 'Purge Cache',\n })}\n keyToUse={keyToUse}\n ></PurgeModal>\n );\n}\n\nexport default PurgeCacheButton;\n","import { unstable_useContentManagerContext as useContentManagerContext } from '@strapi/strapi/admin';\nimport PurgeModal from '../PurgeModal';\nimport { useIntl } from 'react-intl';\n\nfunction PurgeEntityButton() {\n const { formatMessage } = useIntl();\n const { id, isSingleType, contentType } = useContentManagerContext();\n const apiPath = isSingleType ? contentType?.info.singularName : id;\n\n if (!apiPath) {\n return null;\n }\n\n const keyToUse = encodeURIComponent(apiPath);\n const contentTypeName = isSingleType\n ? contentType?.info.singularName\n : contentType?.info.pluralName;\n\n return (\n <PurgeModal\n buttonWidth=\"100%\"\n buttonText={formatMessage({\n id: 'strapi-cache.cache.purge.entity',\n defaultMessage: 'Purge Entity Cache',\n })}\n keyToUse={keyToUse}\n contentTypeName={contentTypeName}\n ></PurgeModal>\n );\n}\n\nexport default PurgeEntityButton;\n","import { PLUGIN_ID } from './pluginId';\nimport { Initializer } from './components/Initializer';\nimport PurgeCacheButton from './components/PurgeCacheButton';\nimport PurgeEntityButton from './components/PurgeEntityButton';\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 app.getPlugin('content-manager').injectComponent('listView', 'actions', {\n name: PurgeCacheButton,\n Component: PurgeCacheButton,\n });\n\n app.getPlugin('content-manager').injectComponent('editView', 'right-links', {\n name: PurgeEntityButton,\n Component: PurgeEntityButton,\n });\n\n app.createSettingSection(\n {\n id: PLUGIN_ID,\n intlLabel: {\n id: 'strapi-cache.settings.link',\n defaultMessage: 'Strapi Cache',\n },\n },\n [\n {\n intlLabel: {\n id: 'strapi-cache.settings.link',\n defaultMessage: 'Strapi Cache',\n },\n id: 'settings',\n to: `${PLUGIN_ID}/settings`,\n Component: () => import('./components/SettingsPage'),\n permissions: [],\n },\n ]\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":["error","useContentManagerContext"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
1
  "use strict";
2
- const index = require("../_chunks/index-BsW67w0G.js");
2
+ const index = require("../_chunks/index-BJj5EZfj.js");
3
3
  module.exports = index.index;
4
4
  //# sourceMappingURL=index.js.map
@@ -1,4 +1,4 @@
1
- import { i } from "../_chunks/index-CH_6jFHP.mjs";
1
+ import { i } from "../_chunks/index-dynpWXaG.mjs";
2
2
  export {
3
3
  i as default
4
4
  };
@@ -489,9 +489,17 @@ const controller = ({ strapi: strapi2 }) => ({
489
489
  };
490
490
  },
491
491
  async purgeCacheByKey(ctx) {
492
- const { key } = ctx.params;
492
+ const { key } = ctx.request.body;
493
+ if (!key || typeof key !== "string" || key.trim() === "") {
494
+ ctx.status = 400;
495
+ ctx.body = {
496
+ error: "Key is required and must be a non-empty string"
497
+ };
498
+ return;
499
+ }
493
500
  const service2 = strapi2.plugin("strapi-cache").service("service");
494
- const regex = new RegExp(`(^|/)?${key}(/|\\?|$)`);
501
+ const escapeRegExp = (s) => s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
502
+ const regex = new RegExp(escapeRegExp(key));
495
503
  await service2.getCacheInstance().clearByRegexp([regex]);
496
504
  ctx.body = {
497
505
  message: `Cache purged successfully for key: ${key}`
@@ -534,7 +542,7 @@ const purgeRoute = [
534
542
  },
535
543
  {
536
544
  method: "POST",
537
- path: "/purge-cache/:key",
545
+ path: "/purge-cache/key",
538
546
  handler: "controller.purgeCacheByKey",
539
547
  config: {
540
548
  policies: [
@@ -785,8 +793,10 @@ class RedisCacheProvider {
785
793
  }
786
794
  async clearByRegexp(regExps) {
787
795
  const keys = await this.keys();
796
+ loggy.info(JSON.stringify(keys));
788
797
  if (!keys) return;
789
798
  const toDelete = keys.filter((key) => regExps.some((re) => re.test(key)));
799
+ loggy.info(JSON.stringify(toDelete));
790
800
  await Promise.all(toDelete.map((key) => this.del(key)));
791
801
  }
792
802
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../server/src/utils/log.ts","../../server/src/utils/invalidateCache.ts","../../server/src/permissions.ts","../../server/src/bootstrap.ts","../../server/src/utils/key.ts","../../server/src/utils/body.ts","../../server/src/utils/header.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/purge.ts","../../server/src/routes/index.ts","../../server/src/utils/withTimeout.ts","../../server/src/services/memory/provider.ts","../../server/src/services/redis/provider.ts","../../server/src/services/resolver.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 const restApiPrefix = strapi.config.get('api.rest.prefix', '/api');\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 = `${restApiPrefix}/${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","export const actions = [\n {\n section: 'plugins',\n displayName: 'Purge Cache',\n uid: 'purge-cache',\n pluginName: 'strapi-cache',\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';\nimport { actions } from './permissions';\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 autoPurgeCache = strapi.plugin('strapi-cache').config('autoPurgeCache') as boolean;\n const autoPurgeCacheOnStart = strapi.plugin('strapi-cache').config('autoPurgeCacheOnStart') as boolean;\n const cacheStore = cacheService.getCacheInstance();\n\n if (!cacheStore) {\n loggy.error('Plugin could not be initialized');\n return;\n }\n\n cacheStore.init();\n\n if (autoPurgeCache) {\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\n if (autoPurgeCacheOnStart) {\n cacheStore.reset().then(() => {\n loggy.info('Cache purged successfully');\n }).catch((error) => {\n loggy.error(`Error purging cache on start: ${error.message}`);\n })\n }\n } catch (error) {\n loggy.error('Plugin could not be initialized');\n return;\n }\n loggy.info('Plugin initialized');\n\n strapi.admin.services.permission.actionProvider.registerMany(actions);\n};\n\nexport default bootstrap;\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 { Stream } from 'stream';\nimport { createGunzip, createBrotliDecompress, createInflate } from 'zlib';\n\nexport const streamToBuffer = (stream: Stream): Promise<Buffer> => {\n return new Promise((resolve, reject) => {\n const chunks: Buffer[] = [];\n stream.on('data', (chunk) => chunks.push(chunk));\n stream.on('end', () => resolve(Buffer.concat(chunks)));\n stream.on('error', reject);\n });\n};\n\nexport const decompressBuffer = async (buffer: Buffer, encoding?: string): Promise<Buffer> => {\n return new Promise((resolve, reject) => {\n let decompressStream;\n switch (encoding) {\n case 'gzip':\n decompressStream = createGunzip();\n break;\n case 'br':\n decompressStream = createBrotliDecompress();\n break;\n case 'deflate':\n decompressStream = createInflate();\n break;\n default:\n return resolve(buffer);\n }\n\n const chunks: Buffer[] = [];\n decompressStream.on('data', (chunk) => chunks.push(chunk));\n decompressStream.on('end', () => resolve(Buffer.concat(chunks)));\n decompressStream.on('error', reject);\n\n decompressStream.end(buffer);\n });\n};\n\nexport const decodeBufferToText = (buffer: Buffer): string => {\n const decoder = new TextDecoder('utf-8');\n return decoder.decode(buffer);\n};\n","import { Context } from 'koa';\nimport { OutgoingHttpHeaders } from 'http';\n\nexport function getHeadersToStore(\n ctx: Context,\n cacheHeaders: boolean,\n cacheHeadersAllowList: string[] = [],\n cacheHeadersDenyList: string[] = []\n): OutgoingHttpHeaders | null {\n let headersToStore: OutgoingHttpHeaders | null = null;\n\n if (cacheHeaders) {\n let headers = ctx.response.headers;\n\n if (cacheHeadersAllowList.length) {\n headers = Object.fromEntries(\n Object.entries(headers).filter(([key]) => cacheHeadersAllowList.includes(key.toLowerCase()))\n );\n }\n\n if (cacheHeadersDenyList.length) {\n headers = Object.fromEntries(\n Object.entries(headers).filter(([key]) => !cacheHeadersDenyList.includes(key.toLowerCase()))\n );\n }\n\n headersToStore = headers;\n }\n\n return headersToStore;\n}\n\nexport function getCacheHeaderConfig() {\n const cacheHeaders = strapi.plugin('strapi-cache').config('cacheHeaders') as boolean;\n const cacheHeadersDenyList = strapi\n .plugin('strapi-cache')\n .config('cacheHeadersDenyList') as string[];\n const cacheHeadersAllowList = strapi\n .plugin('strapi-cache')\n .config('cacheHeadersAllowList') as string[];\n const cacheAuthorizedRequests = strapi\n .plugin('strapi-cache')\n .config('cacheAuthorizedRequests') as boolean;\n\n return {\n cacheHeaders,\n cacheHeadersDenyList,\n cacheHeadersAllowList,\n cacheAuthorizedRequests,\n };\n}\n","import { Context } from 'koa';\nimport { generateCacheKey } from '../utils/key';\nimport { CacheService } from '../../src/types/cache.types';\nimport { loggy } from '../utils/log';\nimport Stream from 'stream';\nimport { decodeBufferToText, decompressBuffer, streamToBuffer } from '../utils/body';\nimport { getCacheHeaderConfig, getHeadersToStore } from '../utils/header';\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 excludeRoutes = strapi.plugin('strapi-cache').config('excludeRoutes') as string[];\n const { cacheHeaders, cacheHeadersDenyList, cacheHeadersAllowList, cacheAuthorizedRequests } =\n getCacheHeaderConfig();\n const cacheStore = cacheService.getCacheInstance();\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 restApiPrefix = strapi.config.get('api.rest.prefix', '/api');\n\n const routeIsExcluded = excludeRoutes.some((route) => url.startsWith(route));\n \n if (routeIsExcluded) {\n loggy.info(`Route excluded from cache: ${url}`);\n await next();\n return;\n }\n\n const routeIsCachable =\n cacheableRoutes.some((route) => url.startsWith(route)) ||\n (cacheableRoutes.length === 0 && url.startsWith(restApiPrefix));\n\n const authorizationHeader = ctx.request.headers['authorization'];\n\n if (authorizationHeader && !cacheAuthorizedRequests) {\n loggy.info(`Authorized request bypassing cache: ${key}`);\n await next();\n return;\n }\n\n const middlewaresConfig = strapi.config.get('middlewares') as any[];\n const corsMiddleware = middlewaresConfig.find((mw: any) => mw.name === 'strapi::cors');\n\n const corsConfig = corsMiddleware?.config;\n const origin = ctx?.request?.headers?.origin;\n let allowedOrigins = corsConfig?.origin ?? '*';\n\n if (typeof allowedOrigins === 'string') {\n allowedOrigins = [allowedOrigins];\n }\n\n if (cacheEntry && !noCache) {\n loggy.info(`HIT with key: ${key}`);\n ctx.status = 200;\n ctx.body = cacheEntry.body;\n\n if (cacheHeaders) {\n ctx.set(cacheEntry.headers);\n }\n\n if (corsMiddleware) {\n loggy.info('CORS middleware is set, checking allowed origins');\n if (allowedOrigins.includes(origin)) {\n loggy.info(`Setting Access-Control-Allow-Origin to ${origin}`);\n ctx.set('Access-Control-Allow-Origin', origin);\n } else if (typeof origin === 'undefined' || allowedOrigins.includes('*')) {\n loggy.info('No origin header or * in allowed origins, setting to *');\n ctx.set('Access-Control-Allow-Origin', '*');\n }\n } else {\n loggy.info('No CORS middleware set, setting to request origin or *');\n ctx.set('Access-Control-Allow-Origin', ctx.request.headers.origin || '*');\n }\n\n return;\n }\n\n await next();\n\n if (ctx.method === 'GET' && ctx.status >= 200 && ctx.status < 300 && routeIsCachable) {\n loggy.info(`MISS with key: ${key}`);\n const headersToStore = getHeadersToStore(\n ctx,\n cacheHeaders,\n cacheHeadersAllowList,\n cacheHeadersDenyList\n );\n\n let setCache = true;\n\n if (corsMiddleware) {\n if (allowedOrigins.includes(origin)) {\n //do nothing as the origin is allowed\n } else if (typeof origin === 'undefined' || allowedOrigins.includes('*')) {\n //do nothing as the origin is undefined (POSTMAN) or allowedOrigins includes '*'\n } else {\n setCache = false;\n }\n }\n\n if (ctx.body instanceof Stream) {\n const buf = await streamToBuffer(ctx.body);\n const contentEncoding = ctx.response.headers['content-encoding'];\n const decompressed = await decompressBuffer(buf, contentEncoding);\n const responseText = decodeBufferToText(decompressed);\n if (setCache) {\n await cacheStore.set(key, { body: responseText, headers: headersToStore });\n }\n ctx.body = buf;\n } else {\n if (setCache) {\n await cacheStore.set(key, { body: ctx.body, headers: headersToStore });\n }\n }\n }\n};\n\nexport default middleware;\n","import rawBody from 'raw-body';\nimport { generateGraphqlCacheKey } from '../utils/key';\nimport Stream, { Readable } from 'stream';\nimport { loggy } from '../utils/log';\nimport { CacheService } from '../types/cache.types';\nimport { decodeBufferToText, decompressBuffer, streamToBuffer } from '../utils/body';\nimport { getCacheHeaderConfig, getHeadersToStore } from '../utils/header';\n\nconst middleware = async (ctx: any, next: any) => {\n const cacheService = strapi.plugin('strapi-cache').services.service as CacheService;\n const { cacheHeaders, cacheHeadersDenyList, cacheHeadersAllowList, cacheAuthorizedRequests } =\n getCacheHeaderConfig();\n const cacheStore = cacheService.getCacheInstance();\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 isIntrospectionQuery = body.includes('IntrospectionQuery');\n if (isIntrospectionQuery) {\n loggy.info('Skipping cache for introspection query');\n await next();\n return;\n }\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 const authorizationHeader = ctx.request.headers['authorization'];\n\n if (authorizationHeader && !cacheAuthorizedRequests) {\n loggy.info(`Authorized request bypassing cache: ${key}`);\n await next();\n return;\n }\n\n const middlewaresConfig = strapi.config.get('middlewares') as any[];\n const corsMiddleware = middlewaresConfig.find((mw: any) => mw.name === 'strapi::cors');\n\n const corsConfig = corsMiddleware?.config;\n const origin = ctx?.request?.headers?.origin;\n let allowedOrigins = corsConfig?.origin ?? '*';\n\n if (typeof allowedOrigins === 'string') {\n allowedOrigins = [allowedOrigins];\n }\n\n if (cacheEntry && !noCache) {\n loggy.info(`HIT with key: ${key}`);\n ctx.status = 200;\n ctx.body = cacheEntry.body;\n if (cacheHeaders) {\n ctx.set(cacheEntry.headers);\n }\n\n if (corsMiddleware) {\n loggy.info('CORS middleware is set, checking allowed origins');\n\n if (allowedOrigins.includes(origin)) {\n loggy.info(`Setting Access-Control-Allow-Origin to ${origin}`);\n ctx.set('Access-Control-Allow-Origin', origin);\n } else if (typeof origin === 'undefined' || allowedOrigins.includes('*')) {\n loggy.info('No origin header or * in allowed origins, setting to *');\n ctx.set('Access-Control-Allow-Origin', '*');\n }\n } else {\n loggy.info('No CORS middleware set, setting to request origin or *');\n ctx.set('Access-Control-Allow-Origin', ctx.request.headers.origin || '*');\n }\n return;\n }\n\n await next();\n\n if (\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 const headers = ctx.request.headers;\n const authorizationHeader = headers['authorization'];\n\n if (authorizationHeader && !cacheAuthorizedRequests) {\n loggy.info(`Authorized request not caching: ${key}`);\n return;\n }\n\n const headersToStore = getHeadersToStore(\n ctx,\n cacheHeaders,\n cacheHeadersAllowList,\n cacheHeadersDenyList\n );\n\n let setCache = true;\n\n if (corsMiddleware) {\n if (allowedOrigins.includes(origin)) {\n //do nothing as the origin is allowed\n } else if (typeof origin === 'undefined' || allowedOrigins.includes('*')) {\n //do nothing as the origin is undefined (POSTMAN) or allowedOrigins includes '*'\n } else {\n setCache = false;\n }\n }\n\n if (ctx.body instanceof Stream) {\n const buf = await streamToBuffer(ctx.body);\n const contentEncoding = ctx.response.headers['content-encoding'];\n const decompressed = await decompressBuffer(buf, contentEncoding);\n const responseText = decodeBufferToText(decompressed);\n if (setCache) {\n await cacheStore.set(key, { body: responseText, headers: headersToStore });\n }\n ctx.body = buf;\n } else {\n if (setCache) {\n await cacheStore.set(key, { body: ctx.body, headers: headersToStore });\n }\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 * 1024 * 10,\n allowStale: false,\n cacheableRoutes: [],\n provider: 'memory',\n excludeRoutes: [],\n redisConfig: env('REDIS_URL'),\n redisClusterNodes: [],\n redisClusterOptions: {},\n cacheHeaders: true,\n cacheHeadersDenyList: [],\n cacheHeadersAllowList: [],\n cacheAuthorizedRequests: false,\n cacheGetTimeoutInMs: 1000,\n autoPurgeCache: true,\n autoPurgeCacheOnStart: true,\n disableAdminPopups: false,\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 if (\n !Array.isArray(config.excludeRoutes) ||\n config.excludeRoutes.some((item) => typeof item !== 'string')\n ) {\n throw new Error(`Invalid config: excludeRoutes must be a string array`);\n }\n if (typeof config.provider !== 'string') {\n throw new Error(`Invalid config: provider must be a string`);\n }\n if (config.provider !== 'memory' && config.provider !== 'redis') {\n throw new Error(`Invalid config: provider must be 'memory' or 'redis'`);\n }\n if (config.provider === 'redis') {\n if (!config.redisConfig) {\n throw new Error(`Invalid config: redisConfig must be set when using redis provider`);\n }\n if (typeof config.redisConfig !== 'string' && typeof config.redisConfig !== 'object') {\n throw new Error(\n `Invalid config: redisConfig must be a string or object when using redis provider`\n );\n }\n if (\n !Array.isArray(config.redisClusterNodes) ||\n config.redisClusterNodes.some((item) => !('host' in item && 'port' in item))\n ) {\n throw new Error(\n `Invalid config: redisClusterNodes must be as a list of objects with keys 'host' and 'port'`\n );\n }\n if (typeof config.redisClusterOptions !== 'object') {\n throw new Error(`Invalid config: redisClusterOptions must be an object`);\n }\n }\n if (typeof config.cacheHeaders !== 'boolean') {\n throw new Error(`Invalid config: cacheHeaders must be a boolean`);\n }\n if (\n !Array.isArray(config.cacheHeadersDenyList) ||\n config.cacheHeadersDenyList.some((item) => typeof item !== 'string')\n ) {\n throw new Error(`Invalid config: cacheHeadersDenyList must be an string array`);\n }\n if (\n !Array.isArray(config.cacheHeadersAllowList) ||\n config.cacheHeadersAllowList.some((item) => typeof item !== 'string')\n ) {\n throw new Error(`Invalid config: cacheHeadersAllowList must be an string array`);\n }\n if (typeof config.cacheAuthorizedRequests !== 'boolean') {\n throw new Error(`Invalid config: cacheAuthorizedRequests must be a boolean`);\n }\n if (typeof config.cacheGetTimeoutInMs !== 'number') {\n throw new Error(`Invalid config: cacheGetTimeoutInMs must be a number`);\n }\n if (typeof config.autoPurgeCache !== 'boolean') {\n throw new Error(`Invalid config: autoPurgeCache must be a boolean`);\n }\n if (typeof config.autoPurgeCacheOnStart !== 'boolean') {\n throw new Error(`Invalid config: autoPurgeCacheOnStart must be a boolean`);\n }\n if (typeof config.disableAdminPopups !== 'boolean') {\n throw new Error(`Invalid config: disableAdminPopups must be a boolean`);\n }\n },\n};\n","export default {};\n","import type { Core } from '@strapi/strapi';\nimport { Context } from 'koa';\nimport { CacheService } from 'src/types/cache.types';\n\ninterface PluginConfig {\n cacheableRoutes: string[];\n disableAdminPopups: boolean;\n}\n\nconst controller = ({ strapi }: { strapi: Core.Strapi }) => ({\n async purgeCache(ctx: Context) {\n const service = strapi.plugin('strapi-cache').service('service') as CacheService;\n\n await service.getCacheInstance().reset();\n\n ctx.body = {\n message: 'Cache purged successfully',\n };\n },\n async purgeCacheByKey(ctx: Context) {\n const { key } = ctx.params;\n const service = strapi.plugin('strapi-cache').service('service') as CacheService;\n const regex = new RegExp(`(^|\\/)?${key}(\\/|\\\\?|$)`);\n\n await service.getCacheInstance().clearByRegexp([regex]);\n\n ctx.body = {\n message: `Cache purged successfully for key: ${key}`,\n };\n },\n async config(ctx: Context) {\n try {\n // construct config object with only the properties needed by admin\n const config: PluginConfig = {\n cacheableRoutes: strapi.plugin('strapi-cache').config('cacheableRoutes') ?? [],\n disableAdminPopups: strapi.plugin('strapi-cache').config('disableAdminPopups') ?? false,\n };\n\n ctx.body = config;\n } catch (error) {\n console.error('Error constructing config:', error);\n ctx.status = 500;\n ctx.body = { error: 'Configuration not available' };\n }\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: 'POST',\n path: '/purge-cache',\n handler: 'controller.purgeCache',\n config: {\n policies: [\n 'admin::isAuthenticatedAdmin',\n {\n name: 'plugin::content-manager.hasPermissions',\n config: {\n actions: ['plugin::strapi-cache.purge-cache'],\n },\n },\n ],\n },\n },\n {\n method: 'POST',\n path: '/purge-cache/:key',\n handler: 'controller.purgeCacheByKey',\n config: {\n policies: [\n 'admin::isAuthenticatedAdmin',\n {\n name: 'plugin::content-manager.hasPermissions',\n config: {\n actions: ['plugin::strapi-cache.purge-cache'],\n },\n },\n ],\n },\n },\n {\n method: 'GET',\n path: '/config',\n handler: 'controller.config',\n config: {\n policies: [\n 'admin::isAuthenticatedAdmin',\n {\n name: 'plugin::content-manager.hasPermissions',\n config: {\n actions: ['plugin::strapi-cache.purge-cache'],\n },\n },\n ],\n },\n },\n];\n","import purgeRoute from './purge';\n\nconst routes = {\n 'purge-route': {\n type: 'admin',\n routes: purgeRoute,\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 '../../utils/withTimeout';\nimport { CacheProvider, CacheService } from '../../types/cache.types';\nimport { loggy } from '../../utils/log';\n\nexport class InMemoryCacheProvider implements CacheProvider {\n private initialized = false;\n private provider!: LRUCache<string, any>;\n private cacheGetTimeoutInMs: number;\n\n constructor(private strapi: Core.Strapi) {}\n\n init(): void {\n if (this.initialized) {\n loggy.error('Provider already initialized');\n return;\n }\n\n this.initialized = true;\n\n const max = Number(this.strapi.plugin('strapi-cache').config('max'));\n const ttl = Number(this.strapi.plugin('strapi-cache').config('ttl'));\n const size = Number(this.strapi.plugin('strapi-cache').config('size'));\n const allowStale = Boolean(this.strapi.plugin('strapi-cache').config('allowStale'));\n\n this.provider = new LRUCache({\n max,\n ttl,\n size,\n allowStale,\n });\n\n this.cacheGetTimeoutInMs = Number(\n this.strapi.plugin('strapi-cache').config('cacheGetTimeoutInMs')\n );\n\n loggy.info('Provider initialized');\n }\n\n get ready(): boolean {\n if (!this.initialized) {\n loggy.info('Provider not initialized');\n return false;\n }\n\n return true;\n }\n\n async get(key: string): Promise<any | null> {\n if (!this.ready) return null;\n\n return withTimeout(\n () =>\n new Promise((resolve) => {\n resolve(this.provider.get(key));\n }),\n this.cacheGetTimeoutInMs\n ).catch((error) => {\n loggy.error(`Error during get: ${error?.message || error}`);\n return null;\n });\n }\n\n async set(key: string, val: any): Promise<any | null> {\n if (!this.ready) return null;\n\n try {\n return this.provider.set(key, val);\n } catch (error) {\n loggy.error(`Error during set: ${error}`);\n return null;\n }\n }\n\n async del(key: string): Promise<any | null> {\n if (!this.ready) return null;\n\n try {\n loggy.info(`PURGING KEY: ${key}`);\n return this.provider.delete(key);\n } catch (error) {\n loggy.error(`Error during delete: ${error}`);\n return null;\n }\n }\n\n async keys(): Promise<string[] | null> {\n if (!this.ready) return null;\n\n try {\n return Array.from(this.provider.keys());\n } catch (error) {\n loggy.error(`Error fetching keys: ${error}`);\n return null;\n }\n }\n\n async reset(): Promise<any | null> {\n if (!this.ready) return null;\n\n try {\n const allKeys = await this.keys();\n if (!allKeys) return null;\n\n loggy.info(`PURGING ALL KEYS: ${allKeys.length}`);\n await Promise.all(allKeys.map((key) => this.del(key)));\n return true;\n } catch (error) {\n loggy.error(`Error during reset: ${error}`);\n return null;\n }\n }\n\n async clearByRegexp(regExps: RegExp[]): Promise<void> {\n const keys = (await this.keys()) || [];\n const matches = keys.filter((key) => regExps.some((re) => re.test(key)));\n await Promise.all(matches.map((key) => this.del(key)));\n }\n}\n","import type { Core } from '@strapi/strapi';\nimport { Redis, Cluster, ClusterNode, ClusterOptions } from 'ioredis';\nimport { withTimeout } from '../../utils/withTimeout';\nimport { CacheProvider } from '../../types/cache.types';\nimport { loggy } from '../../utils/log';\n\nexport class RedisCacheProvider implements CacheProvider {\n private initialized = false;\n private client!: Redis | Cluster;\n private cacheGetTimeoutInMs: number;\n private keyPrefix: string;\n\n constructor(private strapi: Core.Strapi) { }\n\n init(): void {\n if (this.initialized) {\n loggy.error('Redis provider already initialized');\n return;\n }\n try {\n const redisConfig =\n this.strapi.plugin('strapi-cache').config('redisConfig') || 'redis://localhost:6379';\n const redisClusterNodes: ClusterNode[] =\n this.strapi.plugin('strapi-cache').config('redisClusterNodes');\n this.cacheGetTimeoutInMs = Number(\n this.strapi.plugin('strapi-cache').config('cacheGetTimeoutInMs')\n );\n this.keyPrefix = this.strapi.plugin('strapi-cache').config('redisConfig')?.[\"keyPrefix\"] as string | undefined ?? \"\";\n if (redisClusterNodes.length) {\n const redisClusterOptions: ClusterOptions =\n this.strapi.plugin('strapi-cache').config('redisClusterOptions');\n if (!redisClusterOptions['redisOptions']) {\n redisClusterOptions.redisOptions = redisConfig;\n }\n this.client = new Redis.Cluster(redisClusterNodes, redisClusterOptions);\n } else {\n this.client = new Redis(redisConfig);\n }\n this.initialized = true;\n\n loggy.info('Redis provider initialized');\n } catch (error) {\n loggy.error(error);\n }\n }\n\n get ready(): boolean {\n if (!this.initialized) {\n loggy.info('Redis provider not initialized');\n return false;\n }\n\n return true;\n }\n\n async get(key: string): Promise<any | null> {\n if (!this.ready) return null;\n\n return withTimeout(() => this.client.get(key), this.cacheGetTimeoutInMs)\n .then((data) => (data ? JSON.parse(data) : null))\n .catch((error) => {\n loggy.error(`Redis get error: ${error?.message || error}`);\n return null;\n });\n }\n\n async set(key: string, val: any): Promise<any | null> {\n if (!this.ready) return null;\n\n try {\n // plugin ttl is ms, ioredis ttl is s, so we convert here\n const ttlInMs = Number(this.strapi.plugin('strapi-cache').config('ttl'));\n const ttlInS = Number((ttlInMs/1000).toFixed());\n const serialized = JSON.stringify(val);\n if (ttlInS > 0) {\n await this.client.set(key, serialized, 'EX', ttlInS);\n } else {\n await this.client.set(key, serialized);\n }\n return val;\n } catch (error) {\n loggy.error(`Redis set error: ${error}`);\n return null;\n }\n }\n\n async del(key: string): Promise<any | null> {\n if (!this.ready) return null;\n\n try {\n const relativeKey = key.slice(this.keyPrefix.length)\n loggy.info(`Redis PURGING KEY: ${relativeKey}`);\n await this.client.del(relativeKey);\n return true;\n } catch (error) {\n loggy.error(`Redis del error: ${error}`);\n return null;\n }\n }\n\n async keys(): Promise<string[] | null> {\n if (!this.ready) return null;\n\n try {\n const keys = await this.client.keys(`${this.keyPrefix}*`);\n return keys;\n } catch (error) {\n loggy.error(`Redis keys error: ${error}`);\n return null;\n }\n }\n\n async reset(): Promise<any | null> {\n if (!this.ready) return null;\n\n try {\n if (this.keyPrefix) {\n loggy.info(`Redis FLUSHING NAMESPACE: ${this.keyPrefix}`);\n const keys = await this.keys();\n if (!keys) return null;\n\n const toDelete = keys.filter((key) => key.startsWith(this.keyPrefix));\n await Promise.all(toDelete.map((key) => this.del(key)));\n return true;\n }\n\n loggy.info(`Redis FLUSHING ALL KEYS`);\n await this.client.flushdb();\n return true;\n } catch (error) {\n loggy.error(`Redis reset error: ${error}`);\n return null;\n }\n }\n\n async clearByRegexp(regExps: RegExp[]): Promise<void> {\n const keys = await this.keys();\n if (!keys) return;\n\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","import type { Core } from '@strapi/strapi';\nimport { InMemoryCacheProvider } from './memory/provider';\nimport { RedisCacheProvider } from './redis/provider';\nimport { CacheProvider } from '../../src/types/cache.types';\nimport { loggy } from '../../src/utils/log';\n\nexport const resolveCacheProvider = (strapi: Core.Strapi): CacheProvider => {\n const providerType = strapi.plugin('strapi-cache').config('provider') || 'memory';\n\n loggy.info(`Selected cache provider: ${providerType}`);\n\n let instance: CacheProvider;\n\n switch (providerType) {\n case 'redis':\n instance = new RedisCacheProvider(strapi);\n break;\n default:\n instance = new InMemoryCacheProvider(strapi);\n break;\n }\n\n return instance;\n};\n","import type { Core } from '@strapi/strapi';\nimport { resolveCacheProvider } from './resolver';\nimport { CacheProvider, CacheService } from '../../src/types/cache.types';\nimport { loggy } from '../../src/utils/log';\n\nconst service = ({ strapi }: { strapi: Core.Strapi }): CacheService => {\n let instance: null | CacheProvider = null;\n\n return {\n getCacheInstance() {\n if (!instance) {\n loggy.info('Initializing cache service from provider config...');\n instance = resolveCacheProvider(strapi);\n }\n return instance;\n },\n };\n};\n\nexport default {\n service,\n};\n","/**\n * Application methods\n */\nimport bootstrap from './bootstrap';\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","createGunzip","createBrotliDecompress","createInflate","middleware","Stream","rawBody","Readable","authorizationHeader","graphql","cache","config","service","LRUCache","Redis"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../../server/src/utils/log.ts","../../server/src/utils/invalidateCache.ts","../../server/src/permissions.ts","../../server/src/bootstrap.ts","../../server/src/utils/key.ts","../../server/src/utils/body.ts","../../server/src/utils/header.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/purge.ts","../../server/src/routes/index.ts","../../server/src/utils/withTimeout.ts","../../server/src/services/memory/provider.ts","../../server/src/services/redis/provider.ts","../../server/src/services/resolver.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 const restApiPrefix = strapi.config.get('api.rest.prefix', '/api');\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 = `${restApiPrefix}/${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","export const actions = [\n {\n section: 'plugins',\n displayName: 'Purge Cache',\n uid: 'purge-cache',\n pluginName: 'strapi-cache',\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';\nimport { actions } from './permissions';\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 autoPurgeCache = strapi.plugin('strapi-cache').config('autoPurgeCache') as boolean;\n const autoPurgeCacheOnStart = strapi.plugin('strapi-cache').config('autoPurgeCacheOnStart') as boolean;\n const cacheStore = cacheService.getCacheInstance();\n\n if (!cacheStore) {\n loggy.error('Plugin could not be initialized');\n return;\n }\n\n cacheStore.init();\n\n if (autoPurgeCache) {\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\n if (autoPurgeCacheOnStart) {\n cacheStore.reset().then(() => {\n loggy.info('Cache purged successfully');\n }).catch((error) => {\n loggy.error(`Error purging cache on start: ${error.message}`);\n })\n }\n } catch (error) {\n loggy.error('Plugin could not be initialized');\n return;\n }\n loggy.info('Plugin initialized');\n\n strapi.admin.services.permission.actionProvider.registerMany(actions);\n};\n\nexport default bootstrap;\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\nexport const escapeRegExp = (s: string) => s.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n","import { Stream } from 'stream';\nimport { createGunzip, createBrotliDecompress, createInflate } from 'zlib';\n\nexport const streamToBuffer = (stream: Stream): Promise<Buffer> => {\n return new Promise((resolve, reject) => {\n const chunks: Buffer[] = [];\n stream.on('data', (chunk) => chunks.push(chunk));\n stream.on('end', () => resolve(Buffer.concat(chunks)));\n stream.on('error', reject);\n });\n};\n\nexport const decompressBuffer = async (buffer: Buffer, encoding?: string): Promise<Buffer> => {\n return new Promise((resolve, reject) => {\n let decompressStream;\n switch (encoding) {\n case 'gzip':\n decompressStream = createGunzip();\n break;\n case 'br':\n decompressStream = createBrotliDecompress();\n break;\n case 'deflate':\n decompressStream = createInflate();\n break;\n default:\n return resolve(buffer);\n }\n\n const chunks: Buffer[] = [];\n decompressStream.on('data', (chunk) => chunks.push(chunk));\n decompressStream.on('end', () => resolve(Buffer.concat(chunks)));\n decompressStream.on('error', reject);\n\n decompressStream.end(buffer);\n });\n};\n\nexport const decodeBufferToText = (buffer: Buffer): string => {\n const decoder = new TextDecoder('utf-8');\n return decoder.decode(buffer);\n};\n","import { Context } from 'koa';\nimport { OutgoingHttpHeaders } from 'http';\n\nexport function getHeadersToStore(\n ctx: Context,\n cacheHeaders: boolean,\n cacheHeadersAllowList: string[] = [],\n cacheHeadersDenyList: string[] = []\n): OutgoingHttpHeaders | null {\n let headersToStore: OutgoingHttpHeaders | null = null;\n\n if (cacheHeaders) {\n let headers = ctx.response.headers;\n\n if (cacheHeadersAllowList.length) {\n headers = Object.fromEntries(\n Object.entries(headers).filter(([key]) => cacheHeadersAllowList.includes(key.toLowerCase()))\n );\n }\n\n if (cacheHeadersDenyList.length) {\n headers = Object.fromEntries(\n Object.entries(headers).filter(([key]) => !cacheHeadersDenyList.includes(key.toLowerCase()))\n );\n }\n\n headersToStore = headers;\n }\n\n return headersToStore;\n}\n\nexport function getCacheHeaderConfig() {\n const cacheHeaders = strapi.plugin('strapi-cache').config('cacheHeaders') as boolean;\n const cacheHeadersDenyList = strapi\n .plugin('strapi-cache')\n .config('cacheHeadersDenyList') as string[];\n const cacheHeadersAllowList = strapi\n .plugin('strapi-cache')\n .config('cacheHeadersAllowList') as string[];\n const cacheAuthorizedRequests = strapi\n .plugin('strapi-cache')\n .config('cacheAuthorizedRequests') as boolean;\n\n return {\n cacheHeaders,\n cacheHeadersDenyList,\n cacheHeadersAllowList,\n cacheAuthorizedRequests,\n };\n}\n","import { Context } from 'koa';\nimport { generateCacheKey } from '../utils/key';\nimport { CacheService } from '../../src/types/cache.types';\nimport { loggy } from '../utils/log';\nimport Stream from 'stream';\nimport { decodeBufferToText, decompressBuffer, streamToBuffer } from '../utils/body';\nimport { getCacheHeaderConfig, getHeadersToStore } from '../utils/header';\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 excludeRoutes = strapi.plugin('strapi-cache').config('excludeRoutes') as string[];\n const { cacheHeaders, cacheHeadersDenyList, cacheHeadersAllowList, cacheAuthorizedRequests } =\n getCacheHeaderConfig();\n const cacheStore = cacheService.getCacheInstance();\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 restApiPrefix = strapi.config.get('api.rest.prefix', '/api');\n\n const routeIsExcluded = excludeRoutes.some((route) => url.startsWith(route));\n \n if (routeIsExcluded) {\n loggy.info(`Route excluded from cache: ${url}`);\n await next();\n return;\n }\n\n const routeIsCachable =\n cacheableRoutes.some((route) => url.startsWith(route)) ||\n (cacheableRoutes.length === 0 && url.startsWith(restApiPrefix));\n\n const authorizationHeader = ctx.request.headers['authorization'];\n\n if (authorizationHeader && !cacheAuthorizedRequests) {\n loggy.info(`Authorized request bypassing cache: ${key}`);\n await next();\n return;\n }\n\n const middlewaresConfig = strapi.config.get('middlewares') as any[];\n const corsMiddleware = middlewaresConfig.find((mw: any) => mw.name === 'strapi::cors');\n\n const corsConfig = corsMiddleware?.config;\n const origin = ctx?.request?.headers?.origin;\n let allowedOrigins = corsConfig?.origin ?? '*';\n\n if (typeof allowedOrigins === 'string') {\n allowedOrigins = [allowedOrigins];\n }\n\n if (cacheEntry && !noCache) {\n loggy.info(`HIT with key: ${key}`);\n ctx.status = 200;\n ctx.body = cacheEntry.body;\n\n if (cacheHeaders) {\n ctx.set(cacheEntry.headers);\n }\n\n if (corsMiddleware) {\n loggy.info('CORS middleware is set, checking allowed origins');\n if (allowedOrigins.includes(origin)) {\n loggy.info(`Setting Access-Control-Allow-Origin to ${origin}`);\n ctx.set('Access-Control-Allow-Origin', origin);\n } else if (typeof origin === 'undefined' || allowedOrigins.includes('*')) {\n loggy.info('No origin header or * in allowed origins, setting to *');\n ctx.set('Access-Control-Allow-Origin', '*');\n }\n } else {\n loggy.info('No CORS middleware set, setting to request origin or *');\n ctx.set('Access-Control-Allow-Origin', ctx.request.headers.origin || '*');\n }\n\n return;\n }\n\n await next();\n\n if (ctx.method === 'GET' && ctx.status >= 200 && ctx.status < 300 && routeIsCachable) {\n loggy.info(`MISS with key: ${key}`);\n const headersToStore = getHeadersToStore(\n ctx,\n cacheHeaders,\n cacheHeadersAllowList,\n cacheHeadersDenyList\n );\n\n let setCache = true;\n\n if (corsMiddleware) {\n if (allowedOrigins.includes(origin)) {\n //do nothing as the origin is allowed\n } else if (typeof origin === 'undefined' || allowedOrigins.includes('*')) {\n //do nothing as the origin is undefined (POSTMAN) or allowedOrigins includes '*'\n } else {\n setCache = false;\n }\n }\n\n if (ctx.body instanceof Stream) {\n const buf = await streamToBuffer(ctx.body);\n const contentEncoding = ctx.response.headers['content-encoding'];\n const decompressed = await decompressBuffer(buf, contentEncoding);\n const responseText = decodeBufferToText(decompressed);\n if (setCache) {\n await cacheStore.set(key, { body: responseText, headers: headersToStore });\n }\n ctx.body = buf;\n } else {\n if (setCache) {\n await cacheStore.set(key, { body: ctx.body, headers: headersToStore });\n }\n }\n }\n};\n\nexport default middleware;\n","import rawBody from 'raw-body';\nimport { generateGraphqlCacheKey } from '../utils/key';\nimport Stream, { Readable } from 'stream';\nimport { loggy } from '../utils/log';\nimport { CacheService } from '../types/cache.types';\nimport { decodeBufferToText, decompressBuffer, streamToBuffer } from '../utils/body';\nimport { getCacheHeaderConfig, getHeadersToStore } from '../utils/header';\n\nconst middleware = async (ctx: any, next: any) => {\n const cacheService = strapi.plugin('strapi-cache').services.service as CacheService;\n const { cacheHeaders, cacheHeadersDenyList, cacheHeadersAllowList, cacheAuthorizedRequests } =\n getCacheHeaderConfig();\n const cacheStore = cacheService.getCacheInstance();\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 isIntrospectionQuery = body.includes('IntrospectionQuery');\n if (isIntrospectionQuery) {\n loggy.info('Skipping cache for introspection query');\n await next();\n return;\n }\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 const authorizationHeader = ctx.request.headers['authorization'];\n\n if (authorizationHeader && !cacheAuthorizedRequests) {\n loggy.info(`Authorized request bypassing cache: ${key}`);\n await next();\n return;\n }\n\n const middlewaresConfig = strapi.config.get('middlewares') as any[];\n const corsMiddleware = middlewaresConfig.find((mw: any) => mw.name === 'strapi::cors');\n\n const corsConfig = corsMiddleware?.config;\n const origin = ctx?.request?.headers?.origin;\n let allowedOrigins = corsConfig?.origin ?? '*';\n\n if (typeof allowedOrigins === 'string') {\n allowedOrigins = [allowedOrigins];\n }\n\n if (cacheEntry && !noCache) {\n loggy.info(`HIT with key: ${key}`);\n ctx.status = 200;\n ctx.body = cacheEntry.body;\n if (cacheHeaders) {\n ctx.set(cacheEntry.headers);\n }\n\n if (corsMiddleware) {\n loggy.info('CORS middleware is set, checking allowed origins');\n\n if (allowedOrigins.includes(origin)) {\n loggy.info(`Setting Access-Control-Allow-Origin to ${origin}`);\n ctx.set('Access-Control-Allow-Origin', origin);\n } else if (typeof origin === 'undefined' || allowedOrigins.includes('*')) {\n loggy.info('No origin header or * in allowed origins, setting to *');\n ctx.set('Access-Control-Allow-Origin', '*');\n }\n } else {\n loggy.info('No CORS middleware set, setting to request origin or *');\n ctx.set('Access-Control-Allow-Origin', ctx.request.headers.origin || '*');\n }\n return;\n }\n\n await next();\n\n if (\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 const headers = ctx.request.headers;\n const authorizationHeader = headers['authorization'];\n\n if (authorizationHeader && !cacheAuthorizedRequests) {\n loggy.info(`Authorized request not caching: ${key}`);\n return;\n }\n\n const headersToStore = getHeadersToStore(\n ctx,\n cacheHeaders,\n cacheHeadersAllowList,\n cacheHeadersDenyList\n );\n\n let setCache = true;\n\n if (corsMiddleware) {\n if (allowedOrigins.includes(origin)) {\n //do nothing as the origin is allowed\n } else if (typeof origin === 'undefined' || allowedOrigins.includes('*')) {\n //do nothing as the origin is undefined (POSTMAN) or allowedOrigins includes '*'\n } else {\n setCache = false;\n }\n }\n\n if (ctx.body instanceof Stream) {\n const buf = await streamToBuffer(ctx.body);\n const contentEncoding = ctx.response.headers['content-encoding'];\n const decompressed = await decompressBuffer(buf, contentEncoding);\n const responseText = decodeBufferToText(decompressed);\n if (setCache) {\n await cacheStore.set(key, { body: responseText, headers: headersToStore });\n }\n ctx.body = buf;\n } else {\n if (setCache) {\n await cacheStore.set(key, { body: ctx.body, headers: headersToStore });\n }\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 * 1024 * 10,\n allowStale: false,\n cacheableRoutes: [],\n provider: 'memory',\n excludeRoutes: [],\n redisConfig: env('REDIS_URL'),\n redisClusterNodes: [],\n redisClusterOptions: {},\n cacheHeaders: true,\n cacheHeadersDenyList: [],\n cacheHeadersAllowList: [],\n cacheAuthorizedRequests: false,\n cacheGetTimeoutInMs: 1000,\n autoPurgeCache: true,\n autoPurgeCacheOnStart: true,\n disableAdminPopups: false,\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 if (\n !Array.isArray(config.excludeRoutes) ||\n config.excludeRoutes.some((item) => typeof item !== 'string')\n ) {\n throw new Error(`Invalid config: excludeRoutes must be a string array`);\n }\n if (typeof config.provider !== 'string') {\n throw new Error(`Invalid config: provider must be a string`);\n }\n if (config.provider !== 'memory' && config.provider !== 'redis') {\n throw new Error(`Invalid config: provider must be 'memory' or 'redis'`);\n }\n if (config.provider === 'redis') {\n if (!config.redisConfig) {\n throw new Error(`Invalid config: redisConfig must be set when using redis provider`);\n }\n if (typeof config.redisConfig !== 'string' && typeof config.redisConfig !== 'object') {\n throw new Error(\n `Invalid config: redisConfig must be a string or object when using redis provider`\n );\n }\n if (\n !Array.isArray(config.redisClusterNodes) ||\n config.redisClusterNodes.some((item) => !('host' in item && 'port' in item))\n ) {\n throw new Error(\n `Invalid config: redisClusterNodes must be as a list of objects with keys 'host' and 'port'`\n );\n }\n if (typeof config.redisClusterOptions !== 'object') {\n throw new Error(`Invalid config: redisClusterOptions must be an object`);\n }\n }\n if (typeof config.cacheHeaders !== 'boolean') {\n throw new Error(`Invalid config: cacheHeaders must be a boolean`);\n }\n if (\n !Array.isArray(config.cacheHeadersDenyList) ||\n config.cacheHeadersDenyList.some((item) => typeof item !== 'string')\n ) {\n throw new Error(`Invalid config: cacheHeadersDenyList must be an string array`);\n }\n if (\n !Array.isArray(config.cacheHeadersAllowList) ||\n config.cacheHeadersAllowList.some((item) => typeof item !== 'string')\n ) {\n throw new Error(`Invalid config: cacheHeadersAllowList must be an string array`);\n }\n if (typeof config.cacheAuthorizedRequests !== 'boolean') {\n throw new Error(`Invalid config: cacheAuthorizedRequests must be a boolean`);\n }\n if (typeof config.cacheGetTimeoutInMs !== 'number') {\n throw new Error(`Invalid config: cacheGetTimeoutInMs must be a number`);\n }\n if (typeof config.autoPurgeCache !== 'boolean') {\n throw new Error(`Invalid config: autoPurgeCache must be a boolean`);\n }\n if (typeof config.autoPurgeCacheOnStart !== 'boolean') {\n throw new Error(`Invalid config: autoPurgeCacheOnStart must be a boolean`);\n }\n if (typeof config.disableAdminPopups !== 'boolean') {\n throw new Error(`Invalid config: disableAdminPopups must be a boolean`);\n }\n },\n};\n","export default {};\n","import type { Core } from '@strapi/strapi';\nimport { Context } from 'koa';\nimport { CacheService } from 'src/types/cache.types';\n\ninterface PluginConfig {\n cacheableRoutes: string[];\n disableAdminPopups: boolean;\n}\n\nconst controller = ({ strapi }: { strapi: Core.Strapi }) => ({\n async purgeCache(ctx: Context) {\n const service = strapi.plugin('strapi-cache').service('service') as CacheService;\n\n await service.getCacheInstance().reset();\n\n ctx.body = {\n message: 'Cache purged successfully',\n };\n },\n async purgeCacheByKey(ctx: Context) {\n const { key } = ctx.request.body as { key?: string };\n\n if (!key || typeof key !== 'string' || key.trim() === '') {\n ctx.status = 400;\n ctx.body = {\n error: 'Key is required and must be a non-empty string',\n };\n return;\n }\n\n const service = strapi.plugin('strapi-cache').service('service') as CacheService;\n const escapeRegExp = (s: string) => s.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n const regex = new RegExp(escapeRegExp(key));\n\n await service.getCacheInstance().clearByRegexp([regex]);\n\n ctx.body = {\n message: `Cache purged successfully for key: ${key}`,\n };\n },\n async config(ctx: Context) {\n try {\n // construct config object with only the properties needed by admin\n const config: PluginConfig = {\n cacheableRoutes: strapi.plugin('strapi-cache').config('cacheableRoutes') ?? [],\n disableAdminPopups: strapi.plugin('strapi-cache').config('disableAdminPopups') ?? false,\n };\n\n ctx.body = config;\n } catch (error) {\n console.error('Error constructing config:', error);\n ctx.status = 500;\n ctx.body = { error: 'Configuration not available' };\n }\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: 'POST',\n path: '/purge-cache',\n handler: 'controller.purgeCache',\n config: {\n policies: [\n 'admin::isAuthenticatedAdmin',\n {\n name: 'plugin::content-manager.hasPermissions',\n config: {\n actions: ['plugin::strapi-cache.purge-cache'],\n },\n },\n ],\n },\n },\n {\n method: 'POST',\n path: '/purge-cache/key',\n handler: 'controller.purgeCacheByKey',\n config: {\n policies: [\n 'admin::isAuthenticatedAdmin',\n {\n name: 'plugin::content-manager.hasPermissions',\n config: {\n actions: ['plugin::strapi-cache.purge-cache'],\n },\n },\n ],\n },\n },\n {\n method: 'GET',\n path: '/config',\n handler: 'controller.config',\n config: {\n policies: [\n 'admin::isAuthenticatedAdmin',\n {\n name: 'plugin::content-manager.hasPermissions',\n config: {\n actions: ['plugin::strapi-cache.purge-cache'],\n },\n },\n ],\n },\n },\n];\n","import purgeRoute from './purge';\n\nconst routes = {\n 'purge-route': {\n type: 'admin',\n routes: purgeRoute,\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 '../../utils/withTimeout';\nimport { CacheProvider, CacheService } from '../../types/cache.types';\nimport { loggy } from '../../utils/log';\n\nexport class InMemoryCacheProvider implements CacheProvider {\n private initialized = false;\n private provider!: LRUCache<string, any>;\n private cacheGetTimeoutInMs: number;\n\n constructor(private strapi: Core.Strapi) {}\n\n init(): void {\n if (this.initialized) {\n loggy.error('Provider already initialized');\n return;\n }\n\n this.initialized = true;\n\n const max = Number(this.strapi.plugin('strapi-cache').config('max'));\n const ttl = Number(this.strapi.plugin('strapi-cache').config('ttl'));\n const size = Number(this.strapi.plugin('strapi-cache').config('size'));\n const allowStale = Boolean(this.strapi.plugin('strapi-cache').config('allowStale'));\n\n this.provider = new LRUCache({\n max,\n ttl,\n size,\n allowStale,\n });\n\n this.cacheGetTimeoutInMs = Number(\n this.strapi.plugin('strapi-cache').config('cacheGetTimeoutInMs')\n );\n\n loggy.info('Provider initialized');\n }\n\n get ready(): boolean {\n if (!this.initialized) {\n loggy.info('Provider not initialized');\n return false;\n }\n\n return true;\n }\n\n async get(key: string): Promise<any | null> {\n if (!this.ready) return null;\n\n return withTimeout(\n () =>\n new Promise((resolve) => {\n resolve(this.provider.get(key));\n }),\n this.cacheGetTimeoutInMs\n ).catch((error) => {\n loggy.error(`Error during get: ${error?.message || error}`);\n return null;\n });\n }\n\n async set(key: string, val: any): Promise<any | null> {\n if (!this.ready) return null;\n\n try {\n return this.provider.set(key, val);\n } catch (error) {\n loggy.error(`Error during set: ${error}`);\n return null;\n }\n }\n\n async del(key: string): Promise<any | null> {\n if (!this.ready) return null;\n\n try {\n loggy.info(`PURGING KEY: ${key}`);\n return this.provider.delete(key);\n } catch (error) {\n loggy.error(`Error during delete: ${error}`);\n return null;\n }\n }\n\n async keys(): Promise<string[] | null> {\n if (!this.ready) return null;\n\n try {\n return Array.from(this.provider.keys());\n } catch (error) {\n loggy.error(`Error fetching keys: ${error}`);\n return null;\n }\n }\n\n async reset(): Promise<any | null> {\n if (!this.ready) return null;\n\n try {\n const allKeys = await this.keys();\n if (!allKeys) return null;\n\n loggy.info(`PURGING ALL KEYS: ${allKeys.length}`);\n await Promise.all(allKeys.map((key) => this.del(key)));\n return true;\n } catch (error) {\n loggy.error(`Error during reset: ${error}`);\n return null;\n }\n }\n\n async clearByRegexp(regExps: RegExp[]): Promise<void> {\n const keys = (await this.keys()) || [];\n const matches = keys.filter((key) => regExps.some((re) => re.test(key)));\n await Promise.all(matches.map((key) => this.del(key)));\n }\n}\n","import type { Core } from '@strapi/strapi';\nimport { Redis, Cluster, ClusterNode, ClusterOptions } from 'ioredis';\nimport { withTimeout } from '../../utils/withTimeout';\nimport { CacheProvider } from '../../types/cache.types';\nimport { loggy } from '../../utils/log';\n\nexport class RedisCacheProvider implements CacheProvider {\n private initialized = false;\n private client!: Redis | Cluster;\n private cacheGetTimeoutInMs: number;\n private keyPrefix: string;\n\n constructor(private strapi: Core.Strapi) {}\n\n init(): void {\n if (this.initialized) {\n loggy.error('Redis provider already initialized');\n return;\n }\n try {\n const redisConfig =\n this.strapi.plugin('strapi-cache').config('redisConfig') || 'redis://localhost:6379';\n const redisClusterNodes: ClusterNode[] = this.strapi\n .plugin('strapi-cache')\n .config('redisClusterNodes');\n this.cacheGetTimeoutInMs = Number(\n this.strapi.plugin('strapi-cache').config('cacheGetTimeoutInMs')\n );\n this.keyPrefix =\n (this.strapi.plugin('strapi-cache').config('redisConfig')?.['keyPrefix'] as\n | string\n | undefined) ?? '';\n if (redisClusterNodes.length) {\n const redisClusterOptions: ClusterOptions = this.strapi\n .plugin('strapi-cache')\n .config('redisClusterOptions');\n if (!redisClusterOptions['redisOptions']) {\n redisClusterOptions.redisOptions = redisConfig;\n }\n this.client = new Redis.Cluster(redisClusterNodes, redisClusterOptions);\n } else {\n this.client = new Redis(redisConfig);\n }\n this.initialized = true;\n\n loggy.info('Redis provider initialized');\n } catch (error) {\n loggy.error(error);\n }\n }\n\n get ready(): boolean {\n if (!this.initialized) {\n loggy.info('Redis provider not initialized');\n return false;\n }\n\n return true;\n }\n\n async get(key: string): Promise<any | null> {\n if (!this.ready) return null;\n\n return withTimeout(() => this.client.get(key), this.cacheGetTimeoutInMs)\n .then((data) => (data ? JSON.parse(data) : null))\n .catch((error) => {\n loggy.error(`Redis get error: ${error?.message || error}`);\n return null;\n });\n }\n\n async set(key: string, val: any): Promise<any | null> {\n if (!this.ready) return null;\n\n try {\n // plugin ttl is ms, ioredis ttl is s, so we convert here\n const ttlInMs = Number(this.strapi.plugin('strapi-cache').config('ttl'));\n const ttlInS = Number((ttlInMs / 1000).toFixed());\n const serialized = JSON.stringify(val);\n if (ttlInS > 0) {\n await this.client.set(key, serialized, 'EX', ttlInS);\n } else {\n await this.client.set(key, serialized);\n }\n return val;\n } catch (error) {\n loggy.error(`Redis set error: ${error}`);\n return null;\n }\n }\n\n async del(key: string): Promise<any | null> {\n if (!this.ready) return null;\n\n try {\n const relativeKey = key.slice(this.keyPrefix.length);\n loggy.info(`Redis PURGING KEY: ${relativeKey}`);\n await this.client.del(relativeKey);\n return true;\n } catch (error) {\n loggy.error(`Redis del error: ${error}`);\n return null;\n }\n }\n\n async keys(): Promise<string[] | null> {\n if (!this.ready) return null;\n\n try {\n const keys = await this.client.keys(`${this.keyPrefix}*`);\n return keys;\n } catch (error) {\n loggy.error(`Redis keys error: ${error}`);\n return null;\n }\n }\n\n async reset(): Promise<any | null> {\n if (!this.ready) return null;\n\n try {\n if (this.keyPrefix) {\n loggy.info(`Redis FLUSHING NAMESPACE: ${this.keyPrefix}`);\n const keys = await this.keys();\n if (!keys) return null;\n\n const toDelete = keys.filter((key) => key.startsWith(this.keyPrefix));\n await Promise.all(toDelete.map((key) => this.del(key)));\n return true;\n }\n\n loggy.info(`Redis FLUSHING ALL KEYS`);\n await this.client.flushdb();\n return true;\n } catch (error) {\n loggy.error(`Redis reset error: ${error}`);\n return null;\n }\n }\n\n async clearByRegexp(regExps: RegExp[]): Promise<void> {\n const keys = await this.keys();\n\n loggy.info(JSON.stringify(keys));\n if (!keys) return;\n\n const toDelete = keys.filter((key) => regExps.some((re) => re.test(key)));\n loggy.info(JSON.stringify(toDelete));\n await Promise.all(toDelete.map((key) => this.del(key)));\n }\n}\n","import type { Core } from '@strapi/strapi';\nimport { InMemoryCacheProvider } from './memory/provider';\nimport { RedisCacheProvider } from './redis/provider';\nimport { CacheProvider } from '../../src/types/cache.types';\nimport { loggy } from '../../src/utils/log';\n\nexport const resolveCacheProvider = (strapi: Core.Strapi): CacheProvider => {\n const providerType = strapi.plugin('strapi-cache').config('provider') || 'memory';\n\n loggy.info(`Selected cache provider: ${providerType}`);\n\n let instance: CacheProvider;\n\n switch (providerType) {\n case 'redis':\n instance = new RedisCacheProvider(strapi);\n break;\n default:\n instance = new InMemoryCacheProvider(strapi);\n break;\n }\n\n return instance;\n};\n","import type { Core } from '@strapi/strapi';\nimport { resolveCacheProvider } from './resolver';\nimport { CacheProvider, CacheService } from '../../src/types/cache.types';\nimport { loggy } from '../../src/utils/log';\n\nconst service = ({ strapi }: { strapi: Core.Strapi }): CacheService => {\n let instance: null | CacheProvider = null;\n\n return {\n getCacheInstance() {\n if (!instance) {\n loggy.info('Initializing cache service from provider config...');\n instance = resolveCacheProvider(strapi);\n }\n return instance;\n },\n };\n};\n\nexport default {\n service,\n};\n","/**\n * Application methods\n */\nimport bootstrap from './bootstrap';\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","createGunzip","createBrotliDecompress","createInflate","middleware","Stream","rawBody","Readable","authorizationHeader","graphql","cache","config","service","LRUCache","Redis"],"mappings":"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"}