strapi-cache 1.4.2 → 1.4.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_chunks/de-CBzKPGsY.mjs +14 -0
- package/dist/_chunks/de-CjN-9Obj.js +14 -0
- package/dist/_chunks/en-BDlRjAzq.mjs +14 -0
- package/dist/_chunks/{en-C0JeH0S_.js → en-D24wwyGh.js} +4 -7
- package/dist/admin/index.js +86 -43
- package/dist/admin/index.mjs +88 -45
- package/dist/admin/src/components/PurgeCacheButton/index.d.ts +1 -1
- package/dist/admin/src/components/PurgeEntityButton/index.d.ts +2 -0
- package/dist/admin/src/components/PurgeModal/PurgeButton/index.d.ts +4 -0
- package/dist/admin/src/components/PurgeModal/index.d.ts +7 -0
- package/dist/server/index.js +0 -1
- package/dist/server/index.mjs +0 -1
- package/package.json +1 -1
- package/dist/_chunks/en-BPx_Feq_.mjs +0 -17
- package/dist/_chunks/en-BPx_Feq_.mjs.map +0 -1
- package/dist/_chunks/en-BdzOe-Jv.mjs +0 -16
- package/dist/_chunks/en-BdzOe-Jv.mjs.map +0 -1
- package/dist/_chunks/en-Bev8UGB9.js +0 -14
- package/dist/_chunks/en-Bev8UGB9.js.map +0 -1
- package/dist/_chunks/en-BgoZyxl0.mjs +0 -10
- package/dist/_chunks/en-BgoZyxl0.mjs.map +0 -1
- package/dist/_chunks/en-C0JeH0S_.js.map +0 -1
- package/dist/_chunks/en-C0qeO9FB.mjs +0 -15
- package/dist/_chunks/en-C0qeO9FB.mjs.map +0 -1
- package/dist/_chunks/en-CIN0kRXJ.js +0 -10
- package/dist/_chunks/en-CIN0kRXJ.js.map +0 -1
- package/dist/_chunks/en-CVjURV1W.js +0 -11
- package/dist/_chunks/en-CVjURV1W.js.map +0 -1
- package/dist/_chunks/en-C_x7qEgd.mjs +0 -11
- package/dist/_chunks/en-C_x7qEgd.mjs.map +0 -1
- package/dist/_chunks/en-DZzRFINn.js +0 -16
- package/dist/_chunks/en-DZzRFINn.js.map +0 -1
- package/dist/_chunks/en-D_Fd-4QS.js +0 -15
- package/dist/_chunks/en-D_Fd-4QS.js.map +0 -1
- package/dist/_chunks/en-DdVULHeC.mjs +0 -14
- package/dist/_chunks/en-DdVULHeC.mjs.map +0 -1
- package/dist/admin/index.js.map +0 -1
- package/dist/admin/index.mjs.map +0 -1
- package/dist/server/index.js.map +0 -1
- package/dist/server/index.mjs.map +0 -1
- package/dist/server/src/destroy.d.ts +0 -5
- package/dist/server/src/routes/content-api.d.ts +0 -9
- package/dist/server/src/services/service.d.ts +0 -6
- package/dist/server/src/utils/etag.d.ts +0 -3
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
const de = {
|
|
2
|
+
"strapi-cache.name": "Strapi-Cache",
|
|
3
|
+
"strapi-cache.cache.purge": "Cache leeren",
|
|
4
|
+
"strapi-cache.cache.purge.entity": "Entity-Cache leeren",
|
|
5
|
+
"strapi-cache.cache.cancel": "Nein, abbrechen",
|
|
6
|
+
"strapi-cache.cache.confirm": "Ja, leeren",
|
|
7
|
+
"strapi-cache.cache.purge.confirmation": "Dies löscht alle Schlüssel, bei denen {key} Teil des Schlüssels ist. Sind Sie sicher, dass Sie den Cache leeren möchten?",
|
|
8
|
+
"strapi-cache.cache.purge.success": "Cache erfolgreich für {key} geleert",
|
|
9
|
+
"strapi-cache.cache.purge.error": "Fehler beim Leeren des Caches für {key}",
|
|
10
|
+
"strapi-cache.cache.purge.no-content-type": "Kein Inhaltstyp gefunden"
|
|
11
|
+
};
|
|
12
|
+
export {
|
|
13
|
+
de as default
|
|
14
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const de = {
|
|
4
|
+
"strapi-cache.name": "Strapi-Cache",
|
|
5
|
+
"strapi-cache.cache.purge": "Cache leeren",
|
|
6
|
+
"strapi-cache.cache.purge.entity": "Entity-Cache leeren",
|
|
7
|
+
"strapi-cache.cache.cancel": "Nein, abbrechen",
|
|
8
|
+
"strapi-cache.cache.confirm": "Ja, leeren",
|
|
9
|
+
"strapi-cache.cache.purge.confirmation": "Dies löscht alle Schlüssel, bei denen {key} Teil des Schlüssels ist. Sind Sie sicher, dass Sie den Cache leeren möchten?",
|
|
10
|
+
"strapi-cache.cache.purge.success": "Cache erfolgreich für {key} geleert",
|
|
11
|
+
"strapi-cache.cache.purge.error": "Fehler beim Leeren des Caches für {key}",
|
|
12
|
+
"strapi-cache.cache.purge.no-content-type": "Kein Inhaltstyp gefunden"
|
|
13
|
+
};
|
|
14
|
+
exports.default = de;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
const en = {
|
|
2
|
+
"strapi-cache.name": "Strapi Cache",
|
|
3
|
+
"strapi-cache.cache.purge": "Purge Cache",
|
|
4
|
+
"strapi-cache.cache.purge.entity": "Purge Entity Cache",
|
|
5
|
+
"strapi-cache.cache.cancel": "No, cancel",
|
|
6
|
+
"strapi-cache.cache.confirm": "Yes, purge",
|
|
7
|
+
"strapi-cache.cache.purge.confirmation": "This purges all keys where {key} is part of the key. Are you sure you want to purge the cache?",
|
|
8
|
+
"strapi-cache.cache.purge.success": "Cache purged successfully for {key}",
|
|
9
|
+
"strapi-cache.cache.purge.error": "Error purging cache for {key}",
|
|
10
|
+
"strapi-cache.cache.purge.no-content-type": "No content type found"
|
|
11
|
+
};
|
|
12
|
+
export {
|
|
13
|
+
en as default
|
|
14
|
+
};
|
|
@@ -2,16 +2,13 @@
|
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
3
|
const en = {
|
|
4
4
|
"strapi-cache.name": "Strapi Cache",
|
|
5
|
-
"strapi-cache.settings": "Cache Settings",
|
|
6
|
-
"strapi-cache.view.settings.title": "Strapi Cache Settings",
|
|
7
|
-
"strapi-cache.view.settings.subtitle": "Configure what to cache",
|
|
8
5
|
"strapi-cache.cache.purge": "Purge Cache",
|
|
6
|
+
"strapi-cache.cache.purge.entity": "Purge Entity Cache",
|
|
9
7
|
"strapi-cache.cache.cancel": "No, cancel",
|
|
10
8
|
"strapi-cache.cache.confirm": "Yes, purge",
|
|
11
|
-
"strapi-cache.cache.purge.confirmation": "Are you sure you want to purge the cache?",
|
|
12
|
-
"strapi-cache.cache.purge.success": "Cache purged successfully",
|
|
13
|
-
"strapi-cache.cache.purge.error": "Error purging cache",
|
|
9
|
+
"strapi-cache.cache.purge.confirmation": "This purges all keys where {key} is part of the key. Are you sure you want to purge the cache?",
|
|
10
|
+
"strapi-cache.cache.purge.success": "Cache purged successfully for {key}",
|
|
11
|
+
"strapi-cache.cache.purge.error": "Error purging cache for {key}",
|
|
14
12
|
"strapi-cache.cache.purge.no-content-type": "No content type found"
|
|
15
13
|
};
|
|
16
14
|
exports.default = en;
|
|
17
|
-
//# sourceMappingURL=en-C0JeH0S_.js.map
|
package/dist/admin/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
const react = require("react");
|
|
3
3
|
const jsxRuntime = require("react/jsx-runtime");
|
|
4
|
+
const admin = require("@strapi/strapi/admin");
|
|
4
5
|
const reactIntl = require("react-intl");
|
|
5
6
|
const icons = require("@strapi/icons");
|
|
6
7
|
const designSystem = require("@strapi/design-system");
|
|
7
|
-
const admin = require("@strapi/strapi/admin");
|
|
8
8
|
const __variableDynamicImportRuntimeHelper = (glob, path, segs) => {
|
|
9
9
|
const v = glob[path];
|
|
10
10
|
if (v) {
|
|
@@ -32,14 +32,19 @@ const Initializer = ({ setPlugin }) => {
|
|
|
32
32
|
const pluginPermissions = {
|
|
33
33
|
purge: [{ action: "plugin::strapi-cache.purge-cache", subject: null }]
|
|
34
34
|
};
|
|
35
|
-
function
|
|
35
|
+
function PurgeButton({ onClick }) {
|
|
36
|
+
const formatMessage = reactIntl.useIntl().formatMessage;
|
|
37
|
+
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick, children: formatMessage({
|
|
38
|
+
id: "strapi-cache.cache.confirm",
|
|
39
|
+
defaultMessage: "Yes, confirm"
|
|
40
|
+
}) });
|
|
41
|
+
}
|
|
42
|
+
function PurgeModal({ buttonText, keyToUse, buttonWidth }) {
|
|
36
43
|
const { allowedActions } = admin.useRBAC(pluginPermissions);
|
|
37
44
|
const formatMessage = reactIntl.useIntl().formatMessage;
|
|
38
45
|
const { post, get } = admin.useFetchClient();
|
|
39
46
|
const { toggleNotification } = admin.useNotification();
|
|
40
|
-
const { contentType } = admin.unstable_useContentManagerContext();
|
|
41
47
|
const [cacheableRoutes, setCacheableRoutes] = react.useState();
|
|
42
|
-
const pluralName = contentType?.info.pluralName;
|
|
43
48
|
react.useEffect(() => {
|
|
44
49
|
if (!allowedActions.canPurgeCache) {
|
|
45
50
|
return;
|
|
@@ -50,15 +55,23 @@ function PurgeCacheButton() {
|
|
|
50
55
|
return data;
|
|
51
56
|
} catch (error) {
|
|
52
57
|
console.error("Error fetching cacheable routes:", error);
|
|
53
|
-
return
|
|
58
|
+
return void 0;
|
|
54
59
|
}
|
|
55
60
|
};
|
|
56
61
|
fetchCacheableRoutes().then((data) => {
|
|
57
62
|
setCacheableRoutes(data);
|
|
58
63
|
});
|
|
59
64
|
}, [allowedActions.canPurgeCache]);
|
|
65
|
+
const isCacheableRoute = () => {
|
|
66
|
+
if (!keyToUse || !cacheableRoutes) {
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
return cacheableRoutes.length === 0 || cacheableRoutes.some((route) => {
|
|
70
|
+
return route.includes(keyToUse);
|
|
71
|
+
});
|
|
72
|
+
};
|
|
60
73
|
const clearCache = () => {
|
|
61
|
-
if (!
|
|
74
|
+
if (!keyToUse) {
|
|
62
75
|
toggleNotification({
|
|
63
76
|
type: "warning",
|
|
64
77
|
message: formatMessage({
|
|
@@ -68,65 +81,92 @@ function PurgeCacheButton() {
|
|
|
68
81
|
});
|
|
69
82
|
return;
|
|
70
83
|
}
|
|
71
|
-
post(`/strapi-cache/purge-cache/${
|
|
84
|
+
post(`/strapi-cache/purge-cache/${keyToUse}`, void 0, {
|
|
72
85
|
headers: {
|
|
73
86
|
"Content-Type": "application/json"
|
|
74
87
|
}
|
|
75
88
|
}).then(() => {
|
|
76
89
|
toggleNotification({
|
|
77
90
|
type: "success",
|
|
78
|
-
message: formatMessage(
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
91
|
+
message: formatMessage(
|
|
92
|
+
{
|
|
93
|
+
id: "strapi-cache.cache.purge.success",
|
|
94
|
+
defaultMessage: "Cache purged successfully"
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
key: `"${keyToUse}"`
|
|
98
|
+
}
|
|
99
|
+
)
|
|
82
100
|
});
|
|
83
101
|
}).catch(() => {
|
|
84
102
|
toggleNotification({
|
|
85
103
|
type: "danger",
|
|
86
|
-
message: formatMessage(
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
104
|
+
message: formatMessage(
|
|
105
|
+
{
|
|
106
|
+
id: "strapi-cache.cache.purge.error",
|
|
107
|
+
defaultMessage: "Error purging cache"
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
key: `"${keyToUse}"`
|
|
111
|
+
}
|
|
112
|
+
)
|
|
90
113
|
});
|
|
91
114
|
});
|
|
92
115
|
};
|
|
93
|
-
const isCacheableRoute = () => {
|
|
94
|
-
if (!pluralName || !cacheableRoutes) {
|
|
95
|
-
return false;
|
|
96
|
-
}
|
|
97
|
-
return cacheableRoutes.length === 0 || cacheableRoutes.some((route) => {
|
|
98
|
-
return route.includes(pluralName);
|
|
99
|
-
});
|
|
100
|
-
};
|
|
101
116
|
if (!allowedActions.canPurgeCache || !isCacheableRoute()) {
|
|
102
117
|
return null;
|
|
103
118
|
}
|
|
104
|
-
return /* @__PURE__ */ jsxRuntime.
|
|
105
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Trigger, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { startIcon: /* @__PURE__ */ jsxRuntime.jsx(icons.Archive, {}), variant: "danger", children:
|
|
106
|
-
id: "strapi-cache.cache.purge",
|
|
107
|
-
defaultMessage: "Purge Cache"
|
|
108
|
-
}) }) }),
|
|
119
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Modal.Root, { children: [
|
|
120
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Trigger, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { width: buttonWidth, startIcon: /* @__PURE__ */ jsxRuntime.jsx(icons.Archive, {}), variant: "danger", children: buttonText }) }),
|
|
109
121
|
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Modal.Content, { children: [
|
|
110
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Title, { children:
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
122
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Title, { children: buttonText }) }),
|
|
123
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Body, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", children: formatMessage(
|
|
124
|
+
{
|
|
125
|
+
id: "strapi-cache.cache.purge.confirmation",
|
|
126
|
+
defaultMessage: "Are you sure you want to purge the cache?"
|
|
127
|
+
},
|
|
128
|
+
{ key: `"${keyToUse}"` }
|
|
129
|
+
) }) }),
|
|
118
130
|
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Modal.Footer, { children: [
|
|
119
131
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Close, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { variant: "tertiary", children: formatMessage({
|
|
120
132
|
id: "strapi-cache.cache.cancel",
|
|
121
133
|
defaultMessage: "No, cancel"
|
|
122
134
|
}) }) }),
|
|
123
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Close, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
124
|
-
id: "strapi-cache.cache.confirm",
|
|
125
|
-
defaultMessage: "Yes, confirm"
|
|
126
|
-
}) }) })
|
|
135
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Close, { children: /* @__PURE__ */ jsxRuntime.jsx(PurgeButton, { onClick: clearCache }) })
|
|
127
136
|
] })
|
|
128
137
|
] })
|
|
129
|
-
] })
|
|
138
|
+
] });
|
|
139
|
+
}
|
|
140
|
+
function PurgeCacheButton() {
|
|
141
|
+
const { contentType } = admin.unstable_useContentManagerContext();
|
|
142
|
+
const { formatMessage } = reactIntl.useIntl();
|
|
143
|
+
const keyToUse = contentType?.info.pluralName;
|
|
144
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
145
|
+
PurgeModal,
|
|
146
|
+
{
|
|
147
|
+
buttonText: formatMessage({
|
|
148
|
+
id: "strapi-cache.cache.purge",
|
|
149
|
+
defaultMessage: "Purge Cache"
|
|
150
|
+
}),
|
|
151
|
+
keyToUse
|
|
152
|
+
}
|
|
153
|
+
);
|
|
154
|
+
}
|
|
155
|
+
function PurgeEntityButton() {
|
|
156
|
+
const { formatMessage } = reactIntl.useIntl();
|
|
157
|
+
const { id, isSingleType, contentType } = admin.unstable_useContentManagerContext();
|
|
158
|
+
const keyToUse = isSingleType ? contentType?.info.singularName : id;
|
|
159
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
160
|
+
PurgeModal,
|
|
161
|
+
{
|
|
162
|
+
buttonWidth: "100%",
|
|
163
|
+
buttonText: formatMessage({
|
|
164
|
+
id: "strapi-cache.cache.purge.entity",
|
|
165
|
+
defaultMessage: "Purge Entity Cache"
|
|
166
|
+
}),
|
|
167
|
+
keyToUse
|
|
168
|
+
}
|
|
169
|
+
);
|
|
130
170
|
}
|
|
131
171
|
const index = {
|
|
132
172
|
register(app) {
|
|
@@ -140,12 +180,16 @@ const index = {
|
|
|
140
180
|
name: PurgeCacheButton,
|
|
141
181
|
Component: PurgeCacheButton
|
|
142
182
|
});
|
|
183
|
+
app.getPlugin("content-manager").injectComponent("editView", "right-links", {
|
|
184
|
+
name: PurgeEntityButton,
|
|
185
|
+
Component: PurgeEntityButton
|
|
186
|
+
});
|
|
143
187
|
},
|
|
144
188
|
async registerTrads({ locales }) {
|
|
145
189
|
return Promise.all(
|
|
146
190
|
locales.map(async (locale) => {
|
|
147
191
|
try {
|
|
148
|
-
const { default: data } = await __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/en.json": () => Promise.resolve().then(() => require("../_chunks/en-
|
|
192
|
+
const { default: data } = await __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/de.json": () => Promise.resolve().then(() => require("../_chunks/de-CjN-9Obj.js")), "./translations/en.json": () => Promise.resolve().then(() => require("../_chunks/en-D24wwyGh.js")) }), `./translations/${locale}.json`, 3);
|
|
149
193
|
return { data, locale };
|
|
150
194
|
} catch {
|
|
151
195
|
return { data: {}, locale };
|
|
@@ -155,4 +199,3 @@ const index = {
|
|
|
155
199
|
}
|
|
156
200
|
};
|
|
157
201
|
module.exports = index;
|
|
158
|
-
//# sourceMappingURL=index.js.map
|
package/dist/admin/index.mjs
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { useRef, useEffect, useState } from "react";
|
|
2
|
-
import { jsx,
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useRBAC, useFetchClient, useNotification, unstable_useContentManagerContext } from "@strapi/strapi/admin";
|
|
3
4
|
import { useIntl } from "react-intl";
|
|
4
5
|
import { Archive } from "@strapi/icons";
|
|
5
|
-
import {
|
|
6
|
-
import { useRBAC, useFetchClient, useNotification, unstable_useContentManagerContext } from "@strapi/strapi/admin";
|
|
6
|
+
import { Button, Modal, Typography } from "@strapi/design-system";
|
|
7
7
|
const __variableDynamicImportRuntimeHelper = (glob, path, segs) => {
|
|
8
8
|
const v = glob[path];
|
|
9
9
|
if (v) {
|
|
@@ -31,14 +31,19 @@ const Initializer = ({ setPlugin }) => {
|
|
|
31
31
|
const pluginPermissions = {
|
|
32
32
|
purge: [{ action: "plugin::strapi-cache.purge-cache", subject: null }]
|
|
33
33
|
};
|
|
34
|
-
function
|
|
34
|
+
function PurgeButton({ onClick }) {
|
|
35
|
+
const formatMessage = useIntl().formatMessage;
|
|
36
|
+
return /* @__PURE__ */ jsx(Button, { onClick, children: formatMessage({
|
|
37
|
+
id: "strapi-cache.cache.confirm",
|
|
38
|
+
defaultMessage: "Yes, confirm"
|
|
39
|
+
}) });
|
|
40
|
+
}
|
|
41
|
+
function PurgeModal({ buttonText, keyToUse, buttonWidth }) {
|
|
35
42
|
const { allowedActions } = useRBAC(pluginPermissions);
|
|
36
43
|
const formatMessage = useIntl().formatMessage;
|
|
37
44
|
const { post, get } = useFetchClient();
|
|
38
45
|
const { toggleNotification } = useNotification();
|
|
39
|
-
const { contentType } = unstable_useContentManagerContext();
|
|
40
46
|
const [cacheableRoutes, setCacheableRoutes] = useState();
|
|
41
|
-
const pluralName = contentType?.info.pluralName;
|
|
42
47
|
useEffect(() => {
|
|
43
48
|
if (!allowedActions.canPurgeCache) {
|
|
44
49
|
return;
|
|
@@ -49,15 +54,23 @@ function PurgeCacheButton() {
|
|
|
49
54
|
return data;
|
|
50
55
|
} catch (error) {
|
|
51
56
|
console.error("Error fetching cacheable routes:", error);
|
|
52
|
-
return
|
|
57
|
+
return void 0;
|
|
53
58
|
}
|
|
54
59
|
};
|
|
55
60
|
fetchCacheableRoutes().then((data) => {
|
|
56
61
|
setCacheableRoutes(data);
|
|
57
62
|
});
|
|
58
63
|
}, [allowedActions.canPurgeCache]);
|
|
64
|
+
const isCacheableRoute = () => {
|
|
65
|
+
if (!keyToUse || !cacheableRoutes) {
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
return cacheableRoutes.length === 0 || cacheableRoutes.some((route) => {
|
|
69
|
+
return route.includes(keyToUse);
|
|
70
|
+
});
|
|
71
|
+
};
|
|
59
72
|
const clearCache = () => {
|
|
60
|
-
if (!
|
|
73
|
+
if (!keyToUse) {
|
|
61
74
|
toggleNotification({
|
|
62
75
|
type: "warning",
|
|
63
76
|
message: formatMessage({
|
|
@@ -67,65 +80,92 @@ function PurgeCacheButton() {
|
|
|
67
80
|
});
|
|
68
81
|
return;
|
|
69
82
|
}
|
|
70
|
-
post(`/strapi-cache/purge-cache/${
|
|
83
|
+
post(`/strapi-cache/purge-cache/${keyToUse}`, void 0, {
|
|
71
84
|
headers: {
|
|
72
85
|
"Content-Type": "application/json"
|
|
73
86
|
}
|
|
74
87
|
}).then(() => {
|
|
75
88
|
toggleNotification({
|
|
76
89
|
type: "success",
|
|
77
|
-
message: formatMessage(
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
90
|
+
message: formatMessage(
|
|
91
|
+
{
|
|
92
|
+
id: "strapi-cache.cache.purge.success",
|
|
93
|
+
defaultMessage: "Cache purged successfully"
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
key: `"${keyToUse}"`
|
|
97
|
+
}
|
|
98
|
+
)
|
|
81
99
|
});
|
|
82
100
|
}).catch(() => {
|
|
83
101
|
toggleNotification({
|
|
84
102
|
type: "danger",
|
|
85
|
-
message: formatMessage(
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
103
|
+
message: formatMessage(
|
|
104
|
+
{
|
|
105
|
+
id: "strapi-cache.cache.purge.error",
|
|
106
|
+
defaultMessage: "Error purging cache"
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
key: `"${keyToUse}"`
|
|
110
|
+
}
|
|
111
|
+
)
|
|
89
112
|
});
|
|
90
113
|
});
|
|
91
114
|
};
|
|
92
|
-
const isCacheableRoute = () => {
|
|
93
|
-
if (!pluralName || !cacheableRoutes) {
|
|
94
|
-
return false;
|
|
95
|
-
}
|
|
96
|
-
return cacheableRoutes.length === 0 || cacheableRoutes.some((route) => {
|
|
97
|
-
return route.includes(pluralName);
|
|
98
|
-
});
|
|
99
|
-
};
|
|
100
115
|
if (!allowedActions.canPurgeCache || !isCacheableRoute()) {
|
|
101
116
|
return null;
|
|
102
117
|
}
|
|
103
|
-
return /* @__PURE__ */
|
|
104
|
-
/* @__PURE__ */ jsx(Modal.Trigger, { children: /* @__PURE__ */ jsx(Button, { startIcon: /* @__PURE__ */ jsx(Archive, {}), variant: "danger", children:
|
|
105
|
-
id: "strapi-cache.cache.purge",
|
|
106
|
-
defaultMessage: "Purge Cache"
|
|
107
|
-
}) }) }),
|
|
118
|
+
return /* @__PURE__ */ jsxs(Modal.Root, { children: [
|
|
119
|
+
/* @__PURE__ */ jsx(Modal.Trigger, { children: /* @__PURE__ */ jsx(Button, { width: buttonWidth, startIcon: /* @__PURE__ */ jsx(Archive, {}), variant: "danger", children: buttonText }) }),
|
|
108
120
|
/* @__PURE__ */ jsxs(Modal.Content, { children: [
|
|
109
|
-
/* @__PURE__ */ jsx(Modal.Header, { children: /* @__PURE__ */ jsx(Modal.Title, { children:
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
121
|
+
/* @__PURE__ */ jsx(Modal.Header, { children: /* @__PURE__ */ jsx(Modal.Title, { children: buttonText }) }),
|
|
122
|
+
/* @__PURE__ */ jsx(Modal.Body, { children: /* @__PURE__ */ jsx(Typography, { variant: "omega", children: formatMessage(
|
|
123
|
+
{
|
|
124
|
+
id: "strapi-cache.cache.purge.confirmation",
|
|
125
|
+
defaultMessage: "Are you sure you want to purge the cache?"
|
|
126
|
+
},
|
|
127
|
+
{ key: `"${keyToUse}"` }
|
|
128
|
+
) }) }),
|
|
117
129
|
/* @__PURE__ */ jsxs(Modal.Footer, { children: [
|
|
118
130
|
/* @__PURE__ */ jsx(Modal.Close, { children: /* @__PURE__ */ jsx(Button, { variant: "tertiary", children: formatMessage({
|
|
119
131
|
id: "strapi-cache.cache.cancel",
|
|
120
132
|
defaultMessage: "No, cancel"
|
|
121
133
|
}) }) }),
|
|
122
|
-
/* @__PURE__ */ jsx(Modal.Close, { children: /* @__PURE__ */ jsx(
|
|
123
|
-
id: "strapi-cache.cache.confirm",
|
|
124
|
-
defaultMessage: "Yes, confirm"
|
|
125
|
-
}) }) })
|
|
134
|
+
/* @__PURE__ */ jsx(Modal.Close, { children: /* @__PURE__ */ jsx(PurgeButton, { onClick: clearCache }) })
|
|
126
135
|
] })
|
|
127
136
|
] })
|
|
128
|
-
] })
|
|
137
|
+
] });
|
|
138
|
+
}
|
|
139
|
+
function PurgeCacheButton() {
|
|
140
|
+
const { contentType } = unstable_useContentManagerContext();
|
|
141
|
+
const { formatMessage } = useIntl();
|
|
142
|
+
const keyToUse = contentType?.info.pluralName;
|
|
143
|
+
return /* @__PURE__ */ jsx(
|
|
144
|
+
PurgeModal,
|
|
145
|
+
{
|
|
146
|
+
buttonText: formatMessage({
|
|
147
|
+
id: "strapi-cache.cache.purge",
|
|
148
|
+
defaultMessage: "Purge Cache"
|
|
149
|
+
}),
|
|
150
|
+
keyToUse
|
|
151
|
+
}
|
|
152
|
+
);
|
|
153
|
+
}
|
|
154
|
+
function PurgeEntityButton() {
|
|
155
|
+
const { formatMessage } = useIntl();
|
|
156
|
+
const { id, isSingleType, contentType } = unstable_useContentManagerContext();
|
|
157
|
+
const keyToUse = isSingleType ? contentType?.info.singularName : id;
|
|
158
|
+
return /* @__PURE__ */ jsx(
|
|
159
|
+
PurgeModal,
|
|
160
|
+
{
|
|
161
|
+
buttonWidth: "100%",
|
|
162
|
+
buttonText: formatMessage({
|
|
163
|
+
id: "strapi-cache.cache.purge.entity",
|
|
164
|
+
defaultMessage: "Purge Entity Cache"
|
|
165
|
+
}),
|
|
166
|
+
keyToUse
|
|
167
|
+
}
|
|
168
|
+
);
|
|
129
169
|
}
|
|
130
170
|
const index = {
|
|
131
171
|
register(app) {
|
|
@@ -139,12 +179,16 @@ const index = {
|
|
|
139
179
|
name: PurgeCacheButton,
|
|
140
180
|
Component: PurgeCacheButton
|
|
141
181
|
});
|
|
182
|
+
app.getPlugin("content-manager").injectComponent("editView", "right-links", {
|
|
183
|
+
name: PurgeEntityButton,
|
|
184
|
+
Component: PurgeEntityButton
|
|
185
|
+
});
|
|
142
186
|
},
|
|
143
187
|
async registerTrads({ locales }) {
|
|
144
188
|
return Promise.all(
|
|
145
189
|
locales.map(async (locale) => {
|
|
146
190
|
try {
|
|
147
|
-
const { default: data } = await __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/en.json": () => import("../_chunks/en-
|
|
191
|
+
const { default: data } = await __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/de.json": () => import("../_chunks/de-CBzKPGsY.mjs"), "./translations/en.json": () => import("../_chunks/en-BDlRjAzq.mjs") }), `./translations/${locale}.json`, 3);
|
|
148
192
|
return { data, locale };
|
|
149
193
|
} catch {
|
|
150
194
|
return { data: {}, locale };
|
|
@@ -156,4 +200,3 @@ const index = {
|
|
|
156
200
|
export {
|
|
157
201
|
index as default
|
|
158
202
|
};
|
|
159
|
-
//# sourceMappingURL=index.mjs.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
declare function PurgeCacheButton(): import("react/jsx-runtime").JSX.Element
|
|
1
|
+
declare function PurgeCacheButton(): import("react/jsx-runtime").JSX.Element;
|
|
2
2
|
export default PurgeCacheButton;
|
package/dist/server/index.js
CHANGED
package/dist/server/index.mjs
CHANGED
package/package.json
CHANGED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
const en = {
|
|
2
|
-
"strapi-cache.name": "Strapi Cache",
|
|
3
|
-
"strapi-cache.settings": "Cache Settings",
|
|
4
|
-
"strapi-cache.view.settings.title": "Strapi Cache Settings",
|
|
5
|
-
"strapi-cache.view.settings.subtitle": "Configure what to cache",
|
|
6
|
-
"strapi-cache.cache.purge": "Purge Cache",
|
|
7
|
-
"strapi-cache.cache.cancel": "No, cancel",
|
|
8
|
-
"strapi-cache.cache.confirm": "Yes, purge",
|
|
9
|
-
"strapi-cache.cache.purge.confirmation": "Are you sure you want to purge the cache?",
|
|
10
|
-
"strapi-cache.cache.purge.success": "Cache purged successfully",
|
|
11
|
-
"strapi-cache.cache.purge.error": "Error purging cache",
|
|
12
|
-
"strapi-cache.cache.purge.no-content-type": "No content type found"
|
|
13
|
-
};
|
|
14
|
-
export {
|
|
15
|
-
en as default
|
|
16
|
-
};
|
|
17
|
-
//# sourceMappingURL=en-BPx_Feq_.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"en-BPx_Feq_.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;"}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
const en = {
|
|
2
|
-
"strapi-cache.name": "Strapi Cache",
|
|
3
|
-
"strapi-cache.settings": "Cache Settings",
|
|
4
|
-
"strapi-cache.view.settings.title": "Strapi Cache Settings",
|
|
5
|
-
"strapi-cache.view.settings.subtitle": "Configure what to cache",
|
|
6
|
-
"strapi-cache.cache.purge": "Purge Cache",
|
|
7
|
-
"strapi-cache.cache.cancel": "No, cancel",
|
|
8
|
-
"strapi-cache.cache.confirm": "Yes, purge",
|
|
9
|
-
"strapi-cache.cache.purge.confirmation": "Are you sure you want to purge the cache?",
|
|
10
|
-
"strapi-cache.cache.purge.success": "Cache purged successfully",
|
|
11
|
-
"strapi-cache.cache.purge.error": "Error purging cache"
|
|
12
|
-
};
|
|
13
|
-
export {
|
|
14
|
-
en as default
|
|
15
|
-
};
|
|
16
|
-
//# sourceMappingURL=en-BdzOe-Jv.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"en-BdzOe-Jv.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;"}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
-
const en = {
|
|
4
|
-
"strapi-cache.name": "Strapi Cache",
|
|
5
|
-
"strapi-cache.settings": "Cache Settings",
|
|
6
|
-
"strapi-cache.view.settings.title": "Strapi Cache Settings",
|
|
7
|
-
"strapi-cache.view.settings.subtitle": "Configure what to cache",
|
|
8
|
-
"strapi-cache.cache.purge": "Purge Cache",
|
|
9
|
-
"strapi-cache.cache.cancel": "No, cancel",
|
|
10
|
-
"strapi-cache.cache.confirm": "Yes, purge",
|
|
11
|
-
"strapi-cache.cache.purge.confirmation": "Are you sure you want to purge the cache?"
|
|
12
|
-
};
|
|
13
|
-
exports.default = en;
|
|
14
|
-
//# sourceMappingURL=en-Bev8UGB9.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"en-Bev8UGB9.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;"}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
const en = {
|
|
2
|
-
"strapi-cache.name": "Strapi Cache",
|
|
3
|
-
"strapi-cache.settings": "Cache Settings",
|
|
4
|
-
"strapi-cache.view.settings.title": "Strapi Cache Settings",
|
|
5
|
-
"strapi-cache.view.settings.subtitle": "Configure what to cache"
|
|
6
|
-
};
|
|
7
|
-
export {
|
|
8
|
-
en as default
|
|
9
|
-
};
|
|
10
|
-
//# sourceMappingURL=en-BgoZyxl0.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"en-BgoZyxl0.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"en-C0JeH0S_.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;"}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
const en = {
|
|
2
|
-
"strapi-cache.name": "Strapi Cache",
|
|
3
|
-
"strapi-cache.settings": "Cache Settings",
|
|
4
|
-
"strapi-cache.view.settings.title": "Strapi Cache Settings",
|
|
5
|
-
"strapi-cache.view.settings.subtitle": "Configure what to cache",
|
|
6
|
-
"strapi-cache.cache.purge": "Purge Cache",
|
|
7
|
-
"strapi-cache.cache.cancel": "No, cancel",
|
|
8
|
-
"strapi-cache.cache.confirm": "Yes, purge",
|
|
9
|
-
"strapi-cache.cache.purge.confirmation": "Are you sure you want to purge the cache?",
|
|
10
|
-
"strapi-cache.cache.purge.success": "Cache purged successfully"
|
|
11
|
-
};
|
|
12
|
-
export {
|
|
13
|
-
en as default
|
|
14
|
-
};
|
|
15
|
-
//# sourceMappingURL=en-C0qeO9FB.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"en-C0qeO9FB.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;"}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
-
const en = {
|
|
4
|
-
"strapi-cache.name": "Strapi Cache",
|
|
5
|
-
"strapi-cache.settings": "Cache Settings",
|
|
6
|
-
"strapi-cache.view.settings.title": "Strapi Cache Settings",
|
|
7
|
-
"strapi-cache.view.settings.subtitle": "Configure what to cache"
|
|
8
|
-
};
|
|
9
|
-
exports.default = en;
|
|
10
|
-
//# sourceMappingURL=en-CIN0kRXJ.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"en-CIN0kRXJ.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;"}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
-
const en = {
|
|
4
|
-
"strapi-cache.name": "Strapi Cache",
|
|
5
|
-
"strapi-cache.settings": "Cache Settings",
|
|
6
|
-
"strapi-cache.view.settings.title": "Strapi Cache Settings",
|
|
7
|
-
"strapi-cache.view.settings.subtitle": "Configure what to cache",
|
|
8
|
-
"strapi-cache.cache.purge": "Purge Cache"
|
|
9
|
-
};
|
|
10
|
-
exports.default = en;
|
|
11
|
-
//# sourceMappingURL=en-CVjURV1W.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"en-CVjURV1W.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;"}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
const en = {
|
|
2
|
-
"strapi-cache.name": "Strapi Cache",
|
|
3
|
-
"strapi-cache.settings": "Cache Settings",
|
|
4
|
-
"strapi-cache.view.settings.title": "Strapi Cache Settings",
|
|
5
|
-
"strapi-cache.view.settings.subtitle": "Configure what to cache",
|
|
6
|
-
"strapi-cache.cache.purge": "Purge Cache"
|
|
7
|
-
};
|
|
8
|
-
export {
|
|
9
|
-
en as default
|
|
10
|
-
};
|
|
11
|
-
//# sourceMappingURL=en-C_x7qEgd.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"en-C_x7qEgd.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;"}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
-
const en = {
|
|
4
|
-
"strapi-cache.name": "Strapi Cache",
|
|
5
|
-
"strapi-cache.settings": "Cache Settings",
|
|
6
|
-
"strapi-cache.view.settings.title": "Strapi Cache Settings",
|
|
7
|
-
"strapi-cache.view.settings.subtitle": "Configure what to cache",
|
|
8
|
-
"strapi-cache.cache.purge": "Purge Cache",
|
|
9
|
-
"strapi-cache.cache.cancel": "No, cancel",
|
|
10
|
-
"strapi-cache.cache.confirm": "Yes, purge",
|
|
11
|
-
"strapi-cache.cache.purge.confirmation": "Are you sure you want to purge the cache?",
|
|
12
|
-
"strapi-cache.cache.purge.success": "Cache purged successfully",
|
|
13
|
-
"strapi-cache.cache.purge.error": "Error purging cache"
|
|
14
|
-
};
|
|
15
|
-
exports.default = en;
|
|
16
|
-
//# sourceMappingURL=en-DZzRFINn.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"en-DZzRFINn.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;"}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
-
const en = {
|
|
4
|
-
"strapi-cache.name": "Strapi Cache",
|
|
5
|
-
"strapi-cache.settings": "Cache Settings",
|
|
6
|
-
"strapi-cache.view.settings.title": "Strapi Cache Settings",
|
|
7
|
-
"strapi-cache.view.settings.subtitle": "Configure what to cache",
|
|
8
|
-
"strapi-cache.cache.purge": "Purge Cache",
|
|
9
|
-
"strapi-cache.cache.cancel": "No, cancel",
|
|
10
|
-
"strapi-cache.cache.confirm": "Yes, purge",
|
|
11
|
-
"strapi-cache.cache.purge.confirmation": "Are you sure you want to purge the cache?",
|
|
12
|
-
"strapi-cache.cache.purge.success": "Cache purged successfully"
|
|
13
|
-
};
|
|
14
|
-
exports.default = en;
|
|
15
|
-
//# sourceMappingURL=en-D_Fd-4QS.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"en-D_Fd-4QS.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;"}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
const en = {
|
|
2
|
-
"strapi-cache.name": "Strapi Cache",
|
|
3
|
-
"strapi-cache.settings": "Cache Settings",
|
|
4
|
-
"strapi-cache.view.settings.title": "Strapi Cache Settings",
|
|
5
|
-
"strapi-cache.view.settings.subtitle": "Configure what to cache",
|
|
6
|
-
"strapi-cache.cache.purge": "Purge Cache",
|
|
7
|
-
"strapi-cache.cache.cancel": "No, cancel",
|
|
8
|
-
"strapi-cache.cache.confirm": "Yes, purge",
|
|
9
|
-
"strapi-cache.cache.purge.confirmation": "Are you sure you want to purge the cache?"
|
|
10
|
-
};
|
|
11
|
-
export {
|
|
12
|
-
en as default
|
|
13
|
-
};
|
|
14
|
-
//# sourceMappingURL=en-DdVULHeC.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"en-DdVULHeC.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;"}
|
package/dist/admin/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../admin/src/pluginId.ts","../../admin/src/components/Initializer.tsx","../../admin/src/permission.ts","../../admin/src/components/PurgeCacheButton/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","export const pluginPermissions = {\n purge: [{ action: 'plugin::strapi-cache.purge-cache', subject: null }],\n};\n","import { useIntl } from 'react-intl';\nimport { Archive } from '@strapi/icons';\nimport { Button, Modal } from '@strapi/design-system';\nimport { useRBAC } from '@strapi/strapi/admin';\nimport { pluginPermissions } from '../../permission';\nimport { Typography } from '@strapi/design-system';\nimport { useFetchClient } from '@strapi/strapi/admin';\nimport { unstable_useContentManagerContext as useContentManagerContext } from '@strapi/strapi/admin';\nimport { useNotification } from '@strapi/strapi/admin';\nimport { useEffect, useState } from 'react';\n\nfunction PurgeCacheButton() {\n const { allowedActions } = useRBAC(pluginPermissions);\n const formatMessage = useIntl().formatMessage;\n const { post, get } = useFetchClient();\n const { toggleNotification } = useNotification();\n const { contentType } = useContentManagerContext();\n const [cacheableRoutes, setCacheableRoutes] = useState<string[]>();\n const pluralName = contentType?.info.pluralName;\n\n useEffect(() => {\n if (!allowedActions.canPurgeCache) {\n return;\n }\n const fetchCacheableRoutes = async () => {\n try {\n const { data } = await get('/strapi-cache/cacheable-routes');\n return data;\n } catch (error) {\n console.error('Error fetching cacheable routes:', error);\n return [];\n }\n };\n fetchCacheableRoutes().then((data) => {\n setCacheableRoutes(data);\n });\n }, [allowedActions.canPurgeCache]);\n\n const clearCache = () => {\n if (!pluralName) {\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 return;\n }\n\n post(`/strapi-cache/purge-cache/${pluralName}`, undefined, {\n headers: {\n 'Content-Type': 'application/json',\n },\n })\n .then(() => {\n toggleNotification({\n type: 'success',\n message:\n formatMessage({\n id: 'strapi-cache.cache.purge.success',\n defaultMessage: 'Cache purged successfully',\n }) + `: ${pluralName}`,\n });\n })\n .catch(() => {\n toggleNotification({\n type: 'danger',\n message:\n formatMessage({\n id: 'strapi-cache.cache.purge.error',\n defaultMessage: 'Error purging cache',\n }) + `: ${pluralName}`,\n });\n });\n };\n\n const isCacheableRoute = () => {\n if (!pluralName || !cacheableRoutes) {\n return false;\n }\n\n return (\n cacheableRoutes.length === 0 ||\n cacheableRoutes.some((route) => {\n return route.includes(pluralName);\n })\n );\n };\n\n if (!allowedActions.canPurgeCache || !isCacheableRoute()) {\n return null;\n }\n\n return (\n <>\n <Modal.Root>\n <Modal.Trigger>\n <Button startIcon={<Archive />} variant=\"danger\">\n {formatMessage({\n id: 'strapi-cache.cache.purge',\n defaultMessage: 'Purge Cache',\n })}\n </Button>\n </Modal.Trigger>\n <Modal.Content>\n <Modal.Header>\n <Modal.Title>\n {formatMessage({\n id: 'strapi-cache.cache.purge',\n defaultMessage: 'Purge Cache',\n })}\n </Modal.Title>\n </Modal.Header>\n <Modal.Body>\n <Typography variant=\"omega\">\n {formatMessage({\n id: 'strapi-cache.cache.purge.confirmation',\n defaultMessage: 'Are you sure you want to purge the cache?',\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={clearCache}>\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}\n\nexport default PurgeCacheButton;\n","import { PLUGIN_ID } from './pluginId';\nimport { Initializer } from './components/Initializer';\nimport PurgeCacheButton from './components/PurgeCacheButton';\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\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","useRBAC","useIntl","useFetchClient","useNotification","useContentManagerContext","useState","jsx","Fragment","jsxs","Modal","Button","Archive","Typography"],"mappings":"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"}
|
package/dist/admin/index.mjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","sources":["../../admin/src/pluginId.ts","../../admin/src/components/Initializer.tsx","../../admin/src/permission.ts","../../admin/src/components/PurgeCacheButton/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","export const pluginPermissions = {\n purge: [{ action: 'plugin::strapi-cache.purge-cache', subject: null }],\n};\n","import { useIntl } from 'react-intl';\nimport { Archive } from '@strapi/icons';\nimport { Button, Modal } from '@strapi/design-system';\nimport { useRBAC } from '@strapi/strapi/admin';\nimport { pluginPermissions } from '../../permission';\nimport { Typography } from '@strapi/design-system';\nimport { useFetchClient } from '@strapi/strapi/admin';\nimport { unstable_useContentManagerContext as useContentManagerContext } from '@strapi/strapi/admin';\nimport { useNotification } from '@strapi/strapi/admin';\nimport { useEffect, useState } from 'react';\n\nfunction PurgeCacheButton() {\n const { allowedActions } = useRBAC(pluginPermissions);\n const formatMessage = useIntl().formatMessage;\n const { post, get } = useFetchClient();\n const { toggleNotification } = useNotification();\n const { contentType } = useContentManagerContext();\n const [cacheableRoutes, setCacheableRoutes] = useState<string[]>();\n const pluralName = contentType?.info.pluralName;\n\n useEffect(() => {\n if (!allowedActions.canPurgeCache) {\n return;\n }\n const fetchCacheableRoutes = async () => {\n try {\n const { data } = await get('/strapi-cache/cacheable-routes');\n return data;\n } catch (error) {\n console.error('Error fetching cacheable routes:', error);\n return [];\n }\n };\n fetchCacheableRoutes().then((data) => {\n setCacheableRoutes(data);\n });\n }, [allowedActions.canPurgeCache]);\n\n const clearCache = () => {\n if (!pluralName) {\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 return;\n }\n\n post(`/strapi-cache/purge-cache/${pluralName}`, undefined, {\n headers: {\n 'Content-Type': 'application/json',\n },\n })\n .then(() => {\n toggleNotification({\n type: 'success',\n message:\n formatMessage({\n id: 'strapi-cache.cache.purge.success',\n defaultMessage: 'Cache purged successfully',\n }) + `: ${pluralName}`,\n });\n })\n .catch(() => {\n toggleNotification({\n type: 'danger',\n message:\n formatMessage({\n id: 'strapi-cache.cache.purge.error',\n defaultMessage: 'Error purging cache',\n }) + `: ${pluralName}`,\n });\n });\n };\n\n const isCacheableRoute = () => {\n if (!pluralName || !cacheableRoutes) {\n return false;\n }\n\n return (\n cacheableRoutes.length === 0 ||\n cacheableRoutes.some((route) => {\n return route.includes(pluralName);\n })\n );\n };\n\n if (!allowedActions.canPurgeCache || !isCacheableRoute()) {\n return null;\n }\n\n return (\n <>\n <Modal.Root>\n <Modal.Trigger>\n <Button startIcon={<Archive />} variant=\"danger\">\n {formatMessage({\n id: 'strapi-cache.cache.purge',\n defaultMessage: 'Purge Cache',\n })}\n </Button>\n </Modal.Trigger>\n <Modal.Content>\n <Modal.Header>\n <Modal.Title>\n {formatMessage({\n id: 'strapi-cache.cache.purge',\n defaultMessage: 'Purge Cache',\n })}\n </Modal.Title>\n </Modal.Header>\n <Modal.Body>\n <Typography variant=\"omega\">\n {formatMessage({\n id: 'strapi-cache.cache.purge.confirmation',\n defaultMessage: 'Are you sure you want to purge the cache?',\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={clearCache}>\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}\n\nexport default PurgeCacheButton;\n","import { PLUGIN_ID } from './pluginId';\nimport { Initializer } from './components/Initializer';\nimport PurgeCacheButton from './components/PurgeCacheButton';\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\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":["useContentManagerContext"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAAO,MAAM,YAAY;ACQzB,MAAM,cAAc,CAAC,EAAE,gBAAkC;AACjD,QAAA,MAAM,OAAO,SAAS;AAE5B,YAAU,MAAM;AACd,QAAI,QAAQ,SAAS;AAAA,EACvB,GAAG,EAAE;AAEE,SAAA;AACT;AChBO,MAAM,oBAAoB;AAAA,EAC/B,OAAO,CAAC,EAAE,QAAQ,oCAAoC,SAAS,KAAM,CAAA;AACvE;ACSA,SAAS,mBAAmB;AAC1B,QAAM,EAAE,eAAA,IAAmB,QAAQ,iBAAiB;AAC9C,QAAA,gBAAgB,UAAU;AAChC,QAAM,EAAE,MAAM,IAAI,IAAI,eAAe;AAC/B,QAAA,EAAE,mBAAmB,IAAI,gBAAgB;AACzC,QAAA,EAAE,YAAY,IAAIA,kCAAyB;AACjD,QAAM,CAAC,iBAAiB,kBAAkB,IAAI,SAAmB;AAC3D,QAAA,aAAa,aAAa,KAAK;AAErC,YAAU,MAAM;AACV,QAAA,CAAC,eAAe,eAAe;AACjC;AAAA,IAAA;AAEF,UAAM,uBAAuB,YAAY;AACnC,UAAA;AACF,cAAM,EAAE,KAAA,IAAS,MAAM,IAAI,gCAAgC;AACpD,eAAA;AAAA,eACA,OAAO;AACN,gBAAA,MAAM,oCAAoC,KAAK;AACvD,eAAO,CAAC;AAAA,MAAA;AAAA,IAEZ;AACqB,yBAAA,EAAE,KAAK,CAAC,SAAS;AACpC,yBAAmB,IAAI;AAAA,IAAA,CACxB;AAAA,EAAA,GACA,CAAC,eAAe,aAAa,CAAC;AAEjC,QAAM,aAAa,MAAM;AACvB,QAAI,CAAC,YAAY;AACI,yBAAA;AAAA,QACjB,MAAM;AAAA,QACN,SAAS,cAAc;AAAA,UACrB,IAAI;AAAA,UACJ,gBAAgB;AAAA,QACjB,CAAA;AAAA,MAAA,CACF;AACD;AAAA,IAAA;AAGG,SAAA,6BAA6B,UAAU,IAAI,QAAW;AAAA,MACzD,SAAS;AAAA,QACP,gBAAgB;AAAA,MAAA;AAAA,IAClB,CACD,EACE,KAAK,MAAM;AACS,yBAAA;AAAA,QACjB,MAAM;AAAA,QACN,SACE,cAAc;AAAA,UACZ,IAAI;AAAA,UACJ,gBAAgB;AAAA,QAAA,CACjB,IAAI,KAAK,UAAU;AAAA,MAAA,CACvB;AAAA,IAAA,CACF,EACA,MAAM,MAAM;AACQ,yBAAA;AAAA,QACjB,MAAM;AAAA,QACN,SACE,cAAc;AAAA,UACZ,IAAI;AAAA,UACJ,gBAAgB;AAAA,QAAA,CACjB,IAAI,KAAK,UAAU;AAAA,MAAA,CACvB;AAAA,IAAA,CACF;AAAA,EACL;AAEA,QAAM,mBAAmB,MAAM;AACzB,QAAA,CAAC,cAAc,CAAC,iBAAiB;AAC5B,aAAA;AAAA,IAAA;AAGT,WACE,gBAAgB,WAAW,KAC3B,gBAAgB,KAAK,CAAC,UAAU;AACvB,aAAA,MAAM,SAAS,UAAU;AAAA,IAAA,CACjC;AAAA,EAEL;AAEA,MAAI,CAAC,eAAe,iBAAiB,CAAC,oBAAoB;AACjD,WAAA;AAAA,EAAA;AAGT,SAEI,oBAAA,UAAA,EAAA,UAAA,qBAAC,MAAM,MAAN,EACC,UAAA;AAAA,IAAC,oBAAA,MAAM,SAAN,EACC,UAAC,oBAAA,QAAA,EAAO,WAAW,oBAAC,SAAQ,CAAA,CAAA,GAAI,SAAQ,UACrC,UAAc,cAAA;AAAA,MACb,IAAI;AAAA,MACJ,gBAAgB;AAAA,IAAA,CACjB,GACH,EACF,CAAA;AAAA,IACA,qBAAC,MAAM,SAAN,EACC,UAAA;AAAA,MAAA,oBAAC,MAAM,QAAN,EACC,8BAAC,MAAM,OAAN,EACE,UAAc,cAAA;AAAA,QACb,IAAI;AAAA,QACJ,gBAAgB;AAAA,MAAA,CACjB,GACH,EACF,CAAA;AAAA,MACA,oBAAC,MAAM,MAAN,EACC,8BAAC,YAAW,EAAA,SAAQ,SACjB,UAAc,cAAA;AAAA,QACb,IAAI;AAAA,QACJ,gBAAgB;AAAA,MAAA,CACjB,GACH,EACF,CAAA;AAAA,MACA,qBAAC,MAAM,QAAN,EACC,UAAA;AAAA,QAAA,oBAAC,MAAM,OAAN,EACC,8BAAC,QAAO,EAAA,SAAQ,YACb,UAAc,cAAA;AAAA,UACb,IAAI;AAAA,UACJ,gBAAgB;AAAA,QAAA,CACjB,GACH,EACF,CAAA;AAAA,QACA,oBAAC,MAAM,OAAN,EACC,8BAAC,QAAO,EAAA,SAAS,YACd,UAAc,cAAA;AAAA,UACb,IAAI;AAAA,UACJ,gBAAgB;AAAA,QACjB,CAAA,EACH,CAAA,EACF,CAAA;AAAA,MAAA,EACF,CAAA;AAAA,IAAA,EACF,CAAA;AAAA,EAAA,EAAA,CACF,EACF,CAAA;AAEJ;AC5IA,MAAe,QAAA;AAAA,EACb,SAAS,KAAU;AACjB,QAAI,eAAe;AAAA,MACjB,IAAI;AAAA,MACJ,aAAa;AAAA,MACb,SAAS;AAAA,MACT,MAAM;AAAA,IAAA,CACP;AAED,QAAI,UAAU,iBAAiB,EAAE,gBAAgB,YAAY,WAAW;AAAA,MACtE,MAAM;AAAA,MACN,WAAW;AAAA,IAAA,CACZ;AAAA,EACH;AAAA,EAEA,MAAM,cAAc,EAAE,WAAkC;AACtD,WAAO,QAAQ;AAAA,MACb,QAAQ,IAAI,OAAO,WAAW;AACxB,YAAA;AACF,gBAAM,EAAE,SAAS,SAAS,MAAM,qCAAA,uBAAA,OAAA,EAAA,0BAAA,MAAA,OAAA,4BAAA,EAAA,CAAA,GAAA,kBAAA,MAAA,SAAA,CAAA;AAEzB,iBAAA,EAAE,MAAM,OAAO;AAAA,QAAA,QAChB;AACN,iBAAO,EAAE,MAAM,CAAC,GAAG,OAAO;AAAA,QAAA;AAAA,MAE7B,CAAA;AAAA,IACH;AAAA,EAAA;AAEJ;"}
|
package/dist/server/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
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/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\n try {\n const contentType = strapi.contentType(uid);\n\n if (!contentType || !contentType.kind) {\n loggy.info(`Content type ${uid} not found`);\n return;\n }\n\n const pluralName =\n contentType.kind === 'singleType'\n ? contentType.info.singularName\n : contentType.info.pluralName;\n const apiPath = `/api/${pluralName}`;\n const regex = new RegExp(`^.*:${apiPath}(/.*)?(\\\\?.*)?$`);\n\n await cacheStore.clearByRegexp([regex]);\n loggy.info(`Invalidated cache for ${apiPath}`);\n } catch (error) {\n loggy.error('Cache invalidation error:');\n loggy.error(error);\n }\n}\n\nexport async function invalidateGraphqlCache(\n event: any,\n cacheStore: CacheProvider,\n strapi: Core.Strapi\n) {\n try {\n const graphqlRegex = new RegExp(`^POST:\\/graphql(:.*)?$`);\n\n await cacheStore.clearByRegexp([graphqlRegex]);\n loggy.info(`Invalidated cache for ${graphqlRegex}`);\n } catch (error) {\n loggy.error('Cache invalidation error:');\n loggy.error(error);\n }\n}\n","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 cacheStore = cacheService.getCacheInstance();\n cacheStore.init();\n\n strapi.db.lifecycles.subscribe({\n async afterCreate(event) {\n await invalidateCache(event, cacheStore, strapi);\n await invalidateGraphqlCache(event, cacheStore, strapi);\n },\n async afterUpdate(event) {\n await invalidateCache(event, cacheStore, strapi);\n await invalidateGraphqlCache(event, cacheStore, strapi);\n },\n async afterDelete(event) {\n await invalidateCache(event, cacheStore, strapi);\n await invalidateGraphqlCache(event, cacheStore, strapi);\n },\n });\n\n if (!cacheStore) {\n loggy.error('Plugin could not be initialized');\n return;\n }\n } catch (error) {\n loggy.error('Plugin could not be initialized');\n return;\n }\n loggy.info('Plugin initialized');\n\n 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 { 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 '../../src/utils/body';\n\nconst middleware = async (ctx: Context, next: any) => {\n const cacheService = strapi.plugin('strapi-cache').services.service as CacheService;\n const cacheableRoutes = strapi.plugin('strapi-cache').config('cacheableRoutes') as string[];\n const cacheStore = cacheService.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 routeIsCachable =\n cacheableRoutes.some((route) => url.startsWith(route)) ||\n (cacheableRoutes.length === 0 && url.startsWith('/api'));\n\n if (cacheEntry && !noCache) {\n loggy.info(`HIT with key: ${key}`);\n ctx.status = 200;\n ctx.body = cacheEntry.body;\n ctx.set(cacheEntry.headers);\n ctx.set({ 'Access-Control-Allow-Origin': '*', 'Content-Encoding': 'identity' });\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\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\n await cacheStore.set(key, { body: responseText, headers: ctx.response.headers });\n ctx.body = buf;\n } else {\n await cacheStore.set(key, { body: ctx.body, headers: ctx.response.headers });\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 '../../src/types/cache.types';\nimport { decodeBufferToText, decompressBuffer, streamToBuffer } from '../../src/utils/body';\n\nconst middleware = async (ctx: any, next: any) => {\n const cacheService = strapi.plugin('strapi-cache').services.service as CacheService;\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 key = generateGraphqlCacheKey(body);\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 cacheEntry = await cacheStore.get(key);\n const cacheControlHeader = ctx.request.headers['cache-control'];\n const noCache = cacheControlHeader && cacheControlHeader.includes('no-cache');\n\n if (cacheEntry && !noCache) {\n loggy.info(`HIT with key: ${key}`);\n ctx.status = 200;\n ctx.body = cacheEntry.body;\n ctx.set(cacheEntry.headers);\n ctx.set({ 'Content-Encoding': 'identity' });\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\n if (ctx.body instanceof Stream) {\n const buf = await streamToBuffer(ctx.body);\n const contentEncoding = ctx.response.headers['content-encoding']; // e.g., gzip, br, deflate\n const decompressed = await decompressBuffer(buf, contentEncoding);\n const responseText = decodeBufferToText(decompressed);\n\n await cacheStore.set(key, { body: responseText, headers: ctx.response.headers });\n ctx.body = buf;\n } else {\n await cacheStore.set(key, {\n body: ctx.body,\n headers: ctx.response.headers,\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 * 1014 * 10,\n allowStale: false,\n cacheableRoutes: [],\n provider: 'memory',\n redisUrl: env('REDIS_URL'),\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 (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' && !config.redisUrl && typeof config.redisUrl !== 'string') {\n throw new Error(`Invalid config: redisUrl must be set when using redis provider`);\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\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 cacheableRoutes(ctx: Context) {\n const cacheableRoutes = strapi.plugin('strapi-cache').config('cacheableRoutes');\n ctx.body = cacheableRoutes;\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: '/cacheable-routes',\n handler: 'controller.cacheableRoutes',\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\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 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 const timeout = 1000;\n return withTimeout(\n () =>\n new Promise((resolve) => {\n resolve(this.provider.get(key));\n }),\n timeout\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 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;\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\n const redisUrl =\n this.strapi.plugin('strapi-cache').config('redisUrl') || 'redis://localhost:6379';\n\n this.client = new Redis(redisUrl);\n this.initialized = true;\n\n loggy.info('Redis provider initialized');\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 const timeout = 1000;\n return withTimeout(() => this.client.get(key), timeout)\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 const ttl = Number(this.strapi.plugin('strapi-cache').config('ttl'));\n const serialized = JSON.stringify(val);\n if (ttl > 0) {\n await this.client.set(key, serialized, 'EX', ttl);\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 loggy.info(`Redis PURGING KEY: ${key}`);\n await this.client.del(key);\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('*');\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 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","graphql","cache","config","service","LRUCache","Redis"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","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/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\n try {\n const contentType = strapi.contentType(uid);\n\n if (!contentType || !contentType.kind) {\n loggy.info(`Content type ${uid} not found`);\n return;\n }\n\n const pluralName =\n contentType.kind === 'singleType'\n ? contentType.info.singularName\n : contentType.info.pluralName;\n const apiPath = `/api/${pluralName}`;\n const regex = new RegExp(`^.*:${apiPath}(/.*)?(\\\\?.*)?$`);\n\n await cacheStore.clearByRegexp([regex]);\n loggy.info(`Invalidated cache for ${apiPath}`);\n } catch (error) {\n loggy.error('Cache invalidation error:');\n loggy.error(error);\n }\n}\n\nexport async function invalidateGraphqlCache(\n event: any,\n cacheStore: CacheProvider,\n strapi: Core.Strapi\n) {\n try {\n const graphqlRegex = new RegExp(`^POST:\\/graphql(:.*)?$`);\n\n await cacheStore.clearByRegexp([graphqlRegex]);\n loggy.info(`Invalidated cache for ${graphqlRegex}`);\n } catch (error) {\n loggy.error('Cache invalidation error:');\n loggy.error(error);\n }\n}\n","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 cacheStore = cacheService.getCacheInstance();\n cacheStore.init();\n\n strapi.db.lifecycles.subscribe({\n async afterCreate(event) {\n await invalidateCache(event, cacheStore, strapi);\n await invalidateGraphqlCache(event, cacheStore, strapi);\n },\n async afterUpdate(event) {\n await invalidateCache(event, cacheStore, strapi);\n await invalidateGraphqlCache(event, cacheStore, strapi);\n },\n async afterDelete(event) {\n await invalidateCache(event, cacheStore, strapi);\n await invalidateGraphqlCache(event, cacheStore, strapi);\n },\n });\n\n if (!cacheStore) {\n loggy.error('Plugin could not be initialized');\n return;\n }\n } catch (error) {\n loggy.error('Plugin could not be initialized');\n return;\n }\n loggy.info('Plugin initialized');\n\n 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 { 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 '../../src/utils/body';\n\nconst middleware = async (ctx: Context, next: any) => {\n const cacheService = strapi.plugin('strapi-cache').services.service as CacheService;\n const cacheableRoutes = strapi.plugin('strapi-cache').config('cacheableRoutes') as string[];\n const cacheStore = cacheService.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 routeIsCachable =\n cacheableRoutes.some((route) => url.startsWith(route)) ||\n (cacheableRoutes.length === 0 && url.startsWith('/api'));\n\n if (cacheEntry && !noCache) {\n loggy.info(`HIT with key: ${key}`);\n ctx.status = 200;\n ctx.body = cacheEntry.body;\n ctx.set(cacheEntry.headers);\n ctx.set({ 'Access-Control-Allow-Origin': '*', 'Content-Encoding': 'identity' });\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\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\n await cacheStore.set(key, { body: responseText, headers: ctx.response.headers });\n ctx.body = buf;\n } else {\n await cacheStore.set(key, { body: ctx.body, headers: ctx.response.headers });\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 '../../src/types/cache.types';\nimport { decodeBufferToText, decompressBuffer, streamToBuffer } from '../../src/utils/body';\n\nconst middleware = async (ctx: any, next: any) => {\n const cacheService = strapi.plugin('strapi-cache').services.service as CacheService;\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 key = generateGraphqlCacheKey(body);\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 cacheEntry = await cacheStore.get(key);\n const cacheControlHeader = ctx.request.headers['cache-control'];\n const noCache = cacheControlHeader && cacheControlHeader.includes('no-cache');\n\n if (cacheEntry && !noCache) {\n loggy.info(`HIT with key: ${key}`);\n ctx.status = 200;\n ctx.body = cacheEntry.body;\n ctx.set(cacheEntry.headers);\n ctx.set({ 'Content-Encoding': 'identity' });\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\n if (ctx.body instanceof Stream) {\n const buf = await streamToBuffer(ctx.body);\n const contentEncoding = ctx.response.headers['content-encoding']; // e.g., gzip, br, deflate\n const decompressed = await decompressBuffer(buf, contentEncoding);\n const responseText = decodeBufferToText(decompressed);\n\n await cacheStore.set(key, { body: responseText, headers: ctx.response.headers });\n ctx.body = buf;\n } else {\n await cacheStore.set(key, {\n body: ctx.body,\n headers: ctx.response.headers,\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 * 1014 * 10,\n allowStale: false,\n cacheableRoutes: [],\n provider: 'memory',\n redisUrl: env('REDIS_URL'),\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 (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' && !config.redisUrl && typeof config.redisUrl !== 'string') {\n throw new Error(`Invalid config: redisUrl must be set when using redis provider`);\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\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 cacheableRoutes(ctx: Context) {\n const cacheableRoutes = strapi.plugin('strapi-cache').config('cacheableRoutes');\n ctx.body = cacheableRoutes;\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: '/cacheable-routes',\n handler: 'controller.cacheableRoutes',\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\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 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 const timeout = 1000;\n return withTimeout(\n () =>\n new Promise((resolve) => {\n resolve(this.provider.get(key));\n }),\n timeout\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 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;\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\n const redisUrl =\n this.strapi.plugin('strapi-cache').config('redisUrl') || 'redis://localhost:6379';\n\n this.client = new Redis(redisUrl);\n this.initialized = true;\n\n loggy.info('Redis provider initialized');\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 const timeout = 1000;\n return withTimeout(() => this.client.get(key), timeout)\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 const ttl = Number(this.strapi.plugin('strapi-cache').config('ttl'));\n const serialized = JSON.stringify(val);\n if (ttl > 0) {\n await this.client.set(key, serialized, 'EX', ttl);\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 loggy.info(`Redis PURGING KEY: ${key}`);\n await this.client.del(key);\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('*');\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 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","middleware","graphql","cache","config","service"],"mappings":"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"}
|