strapi-plugin-navigation 2.4.0 โ†’ 2.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/README.md +12 -1
  2. package/admin/src/pages/DataManagerProvider/actions.d.ts +2 -0
  3. package/admin/src/pages/DataManagerProvider/actions.js +3 -1
  4. package/admin/src/pages/DataManagerProvider/index.js +28 -0
  5. package/admin/src/pages/DataManagerProvider/reducer.js +8 -0
  6. package/admin/src/pages/SettingsPage/index.js +19 -7
  7. package/admin/src/pages/SettingsPage/types.d.ts +2 -1
  8. package/admin/src/pages/View/components/NavigationHeader/index.d.ts +2 -1
  9. package/admin/src/pages/View/components/NavigationHeader/index.js +5 -3
  10. package/admin/src/pages/View/components/NavigationManager/AllNavigations/icons.d.ts +1 -0
  11. package/admin/src/pages/View/components/NavigationManager/AllNavigations/icons.js +2 -1
  12. package/admin/src/pages/View/components/NavigationManager/AllNavigations/index.js +16 -4
  13. package/admin/src/pages/View/components/NavigationManager/PurgeCacheConfirm/index.d.ts +8 -0
  14. package/admin/src/pages/View/components/NavigationManager/PurgeCacheConfirm/index.js +34 -0
  15. package/admin/src/pages/View/components/NavigationManager/index.js +15 -2
  16. package/admin/src/pages/View/components/NavigationManager/types.d.ts +5 -1
  17. package/admin/src/pages/View/index.js +5 -2
  18. package/admin/src/translations/en.json +7 -0
  19. package/package.json +6 -6
  20. package/server/bootstrap/index.js +3 -0
  21. package/server/cache/index.d.ts +2 -0
  22. package/server/cache/index.js +18 -0
  23. package/server/cache/serviceEnhancers.d.ts +3 -0
  24. package/server/cache/serviceEnhancers.js +16 -0
  25. package/server/cache/setupStrategy.d.ts +3 -0
  26. package/server/cache/setupStrategy.js +38 -0
  27. package/server/cache/types.d.ts +11 -0
  28. package/server/cache/types.js +3 -0
  29. package/server/cache/utils.d.ts +11 -0
  30. package/server/cache/utils.js +19 -0
  31. package/server/config/index.js +1 -0
  32. package/server/config/setupStrategy.js +1 -0
  33. package/server/controllers/admin.js +18 -0
  34. package/server/i18n/navigationSetupStrategy.js +1 -1
  35. package/server/routes/admin.js +20 -0
  36. package/server/services/admin.js +42 -8
  37. package/server/utils/functions.d.ts +1 -1
  38. package/server/utils/functions.js +2 -2
  39. package/tsconfig.tsbuildinfo +1 -1
  40. package/types/bootstrap.d.ts +3 -0
  41. package/types/config.d.ts +1 -0
  42. package/types/controllers.d.ts +10 -0
  43. package/types/services.d.ts +7 -1
package/README.md CHANGED
@@ -52,6 +52,7 @@ Strapi Navigation Plugin provides a website navigation / menu builder feature fo
52
52
  - [GraphQL API](#graphql-api)
53
53
  10. [๐Ÿ”Œ Extensions](#-extensions)
54
54
  11. [๐ŸŒฟ Model lifecycle hooks](#model-life-cycle-hooks)
55
+ 11. [๐Ÿงน REST Cache](#rest-cache)
55
56
  12. [๐Ÿงฉ Examples](#-examples)
56
57
  13. [๐Ÿ’ฌ FAQ](#-faq)
57
58
  14. [๐Ÿค Contributing](#-contributing)
@@ -123,7 +124,7 @@ Complete installation requirements are exact same as for Strapi itself and can b
123
124
 
124
125
  **Supported Strapi versions**:
125
126
 
126
- - Strapi v4.20.x (recently tested)
127
+ - Strapi v4.24.x (recently tested)
127
128
  - Strapi v4.x
128
129
 
129
130
  > This plugin is designed for **Strapi v4** and is not working with v3.x. To get version for **Strapi v3** install version [v1.x](https://github.com/VirtusLab-Open-Source/strapi-plugin-navigation/tree/strapi-v3).
@@ -774,6 +775,16 @@ Example:
774
775
  });
775
776
  ```
776
777
 
778
+ ## ๐Ÿงน REST Cache
779
+
780
+ If your strapi server uses [REST Cache plugin](https://strapi-community.github.io/strapi-plugin-rest-cache/) this plugin can take integrate with it. All you need to do is to enable it in configuration of Navigation plugin. After integration is enabled all client calls will be wrapped with caching middleware.
781
+
782
+ In admin panel new controls will be available. Cache clearing is done manually or after cache will timeout(`rest-cache` plugin's settings are used).
783
+
784
+ Navigation edit screen will have "Clear cache" button.
785
+
786
+ Navigation management modal items will also have icon button for clearing the cache.
787
+
777
788
  ## ๐Ÿงฉ Examples
778
789
 
779
790
  Live example of plugin usage can be found in the [VirtusLab Strapi Examples](https://github.com/VirtusLab/strapi-examples/tree/master/strapi-plugin-navigation) repository.
@@ -13,6 +13,8 @@ export const GET_CONFIG_SUCCEEDED: "GET_CONFIG_SUCCEEDED";
13
13
  export const SUBMIT_NAVIGATION: "SUBMIT_NAVIGATION";
14
14
  export const SUBMIT_NAVIGATION_SUCCEEDED: "SUBMIT_NAVIGATION_SUCCEEDED";
15
15
  export const SUBMIT_NAVIGATION_ERROR: "SUBMIT_NAVIGATION_ERROR";
16
+ export const CACHE_CLEAR: "CACHE_CLEAR";
17
+ export const CACHE_CLEAR_SUCCEEDED: "CACHE_CLEAR_SUCCEEDED";
16
18
  export const RELOAD_PLUGIN: "RELOAD_PLUGIN";
17
19
  export const I18N_COPY_NAVIGATION: "I18N_COPY_NAVIGATION";
18
20
  export const I18N_COPY_NAVIGATION_SUCCESS: "I18N_COPY_NAVIGATION_SUCCESS";
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.I18N_COPY_NAVIGATION_SUCCESS = exports.I18N_COPY_NAVIGATION = exports.RELOAD_PLUGIN = exports.SUBMIT_NAVIGATION_ERROR = exports.SUBMIT_NAVIGATION_SUCCEEDED = exports.SUBMIT_NAVIGATION = exports.GET_CONFIG_SUCCEEDED = exports.GET_CONFIG = exports.GET_CONTENT_TYPE_ITEMS_SUCCEEDED = exports.GET_CONTENT_TYPE_ITEMS = exports.CHANGE_NAVIGATION_ITEM_POPUP_VISIBILITY = exports.CHANGE_NAVIGATION_POPUP_VISIBILITY = exports.RESET_NAVIGATION_DATA = exports.CHANGE_NAVIGATION_DATA = exports.GET_NAVIGATION_DATA_SUCCEEDED = exports.GET_NAVIGATION_DATA = exports.GET_LIST_DATA_SUCCEEDED = exports.GET_LIST_DATA = void 0;
3
+ exports.I18N_COPY_NAVIGATION_SUCCESS = exports.I18N_COPY_NAVIGATION = exports.RELOAD_PLUGIN = exports.CACHE_CLEAR_SUCCEEDED = exports.CACHE_CLEAR = exports.SUBMIT_NAVIGATION_ERROR = exports.SUBMIT_NAVIGATION_SUCCEEDED = exports.SUBMIT_NAVIGATION = exports.GET_CONFIG_SUCCEEDED = exports.GET_CONFIG = exports.GET_CONTENT_TYPE_ITEMS_SUCCEEDED = exports.GET_CONTENT_TYPE_ITEMS = exports.CHANGE_NAVIGATION_ITEM_POPUP_VISIBILITY = exports.CHANGE_NAVIGATION_POPUP_VISIBILITY = exports.RESET_NAVIGATION_DATA = exports.CHANGE_NAVIGATION_DATA = exports.GET_NAVIGATION_DATA_SUCCEEDED = exports.GET_NAVIGATION_DATA = exports.GET_LIST_DATA_SUCCEEDED = exports.GET_LIST_DATA = void 0;
4
4
  exports.GET_LIST_DATA = "GET_LIST_DATA";
5
5
  exports.GET_LIST_DATA_SUCCEEDED = "GET_LIST_DATA_SUCCEEDED";
6
6
  exports.GET_NAVIGATION_DATA = "GET_NAVIGATION_DATA";
@@ -16,6 +16,8 @@ exports.GET_CONFIG_SUCCEEDED = "GET_CONFIG_SUCCEEDED";
16
16
  exports.SUBMIT_NAVIGATION = "SUBMIT_NAVIGATION";
17
17
  exports.SUBMIT_NAVIGATION_SUCCEEDED = "SUBMIT_NAVIGATION_SUCCEEDED";
18
18
  exports.SUBMIT_NAVIGATION_ERROR = "SUBMIT_NAVIGATION_ERROR";
19
+ exports.CACHE_CLEAR = "CACHE_CLEAR";
20
+ exports.CACHE_CLEAR_SUCCEEDED = "CACHE_CLEAR_SUCCEEDED";
19
21
  exports.RELOAD_PLUGIN = "RELOAD_PLUGIN";
20
22
  exports.I18N_COPY_NAVIGATION = "I18N_COPY_NAVIGATION";
21
23
  exports.I18N_COPY_NAVIGATION_SUCCESS = "I18N_COPY_NAVIGATION_SUCCESS";
@@ -296,6 +296,33 @@ const DataManagerProvider = ({ children }) => {
296
296
  }
297
297
  };
298
298
  const handleNavigationsDeletion = (ids) => Promise.all(ids.map(handleNavigationDeletion));
299
+ const handleNavigationsPurge = async (ids, withLangVersions = false, skipDispatch = false) => {
300
+ if (!skipDispatch) {
301
+ dispatch({ type: actions_1.CACHE_CLEAR });
302
+ }
303
+ try {
304
+ if (ids.length) {
305
+ await Promise.all(ids.map((id) => handleNavigationPurgeReq(id, withLangVersions)));
306
+ }
307
+ else {
308
+ await handleNavigationsPurgeReq();
309
+ }
310
+ }
311
+ catch (error) {
312
+ console.error("Unable to clear navigation cache");
313
+ }
314
+ if (!skipDispatch) {
315
+ dispatch({ type: actions_1.CACHE_CLEAR_SUCCEEDED });
316
+ }
317
+ };
318
+ const handleNavigationPurgeReq = (id, withLangVersions) => (0, helper_plugin_1.request)(`/${pluginId_1.default}/cache/purge/${id}?clearLocalisations=${!!withLangVersions}`, {
319
+ method: "DELETE",
320
+ signal,
321
+ });
322
+ const handleNavigationsPurgeReq = () => (0, helper_plugin_1.request)(`/${pluginId_1.default}/cache/purge`, {
323
+ method: "DELETE",
324
+ signal,
325
+ });
299
326
  const handleNavigationDeletion = (id) => (0, helper_plugin_1.request)(`/${pluginId_1.default}/${id}`, {
300
327
  method: "DELETE",
301
328
  signal,
@@ -340,6 +367,7 @@ const DataManagerProvider = ({ children }) => {
340
367
  availableLocale,
341
368
  readNavigationItemFromLocale,
342
369
  handleNavigationsDeletion,
370
+ handleNavigationsPurge,
343
371
  hardReset,
344
372
  slugify,
345
373
  permissions: {
@@ -116,6 +116,14 @@ const reducer = (state, action) => (0, immer_1.default)(state, draftState => {
116
116
  draftState.isLoading = false;
117
117
  break;
118
118
  }
119
+ case actions_1.CACHE_CLEAR: {
120
+ draftState.isLoading = true;
121
+ break;
122
+ }
123
+ case actions_1.CACHE_CLEAR_SUCCEEDED: {
124
+ draftState.isLoading = false;
125
+ break;
126
+ }
119
127
  default:
120
128
  return draftState;
121
129
  }
@@ -96,6 +96,7 @@ const SettingsPage = () => {
96
96
  pathDefaultFields: (0, lodash_1.get)(navigationConfigData, "pathDefaultFields", {}),
97
97
  populate: (0, lodash_1.get)(navigationConfigData, "contentTypesPopulate", {}),
98
98
  selectedContentTypes: configContentTypes.map(item => item.uid),
99
+ isCacheEnabled: (0, lodash_1.get)(navigationConfigData, "isCacheEnabled", false),
99
100
  }), [configContentTypes, navigationConfigData, utils_1.navigationItemAdditionalFields]);
100
101
  const { disableI18nModal, setDisableI18nModalOpened, setI18nModalOnCancel, } = (0, DisableI18nModal_1.useDisableI18nModal)(({ pruneNavigations }) => {
101
102
  setPruneObsoleteI18nNavigations(pruneNavigations);
@@ -105,7 +106,7 @@ const SettingsPage = () => {
105
106
  ?.filter((field) => field !== utils_1.navigationItemAdditionalFields.AUDIENCE);
106
107
  setCustomFields(additionalFields || []);
107
108
  }, [navigationConfigData]);
108
- const preparePayload = (0, react_1.useCallback)(({ form: { allowedLevels, audienceFieldChecked, cascadeMenuAttachedChecked, i18nEnabled, nameFields, pathDefaultFields, populate, selectedContentTypes, }, pruneObsoleteI18nNavigations }) => ({
109
+ const preparePayload = (0, react_1.useCallback)(({ form: { allowedLevels, audienceFieldChecked, cascadeMenuAttachedChecked, i18nEnabled, nameFields, pathDefaultFields, populate, selectedContentTypes, isCacheEnabled, }, pruneObsoleteI18nNavigations }) => ({
109
110
  additionalFields: audienceFieldChecked ? ['audience', ...customFields] : [...customFields],
110
111
  allowedLevels,
111
112
  cascadeMenuAttached: cascadeMenuAttachedChecked,
@@ -117,7 +118,8 @@ const SettingsPage = () => {
117
118
  pruneObsoleteI18nNavigations,
118
119
  gql: {
119
120
  navigationItemRelated: selectedContentTypes.map((uid) => (0, functions_1.resolveGlobalLikeId)(uid)),
120
- }
121
+ },
122
+ isCacheEnabled,
121
123
  }), [customFields]);
122
124
  const onSave = async (form) => {
123
125
  lockApp();
@@ -125,10 +127,14 @@ const SettingsPage = () => {
125
127
  await submitMutation({ body: payload });
126
128
  const isContentTypesChanged = !(0, lodash_1.isEqual)(payload.contentTypes, navigationConfigData.contentTypes);
127
129
  const isI18nChanged = !(0, lodash_1.isEqual)(payload.i18nEnabled, navigationConfigData.i18nEnabled);
130
+ const isCacheChanged = !(0, lodash_1.isEqual)(payload.isCacheEnabled, navigationConfigData.isCacheEnabled);
128
131
  const restartReasons = [];
129
132
  if (isI18nChanged) {
130
133
  restartReasons.push('I18N');
131
134
  }
135
+ if (isCacheChanged) {
136
+ restartReasons.push('CACHE');
137
+ }
132
138
  if (isContentTypesChanged && navigationConfigData.isGQLPluginEnabled) {
133
139
  restartReasons.push('GRAPH_QL');
134
140
  }
@@ -186,6 +192,7 @@ const SettingsPage = () => {
186
192
  return ct;
187
193
  }), ct => ct.info.displayName) : [];
188
194
  const isI18NPluginEnabled = navigationConfigData?.isI18NPluginEnabled;
195
+ const isCachePluginEnabled = navigationConfigData?.isCachePluginEnabled;
189
196
  const defaultLocale = navigationConfigData?.defaultLocale;
190
197
  const handleSubmitCustomField = (field) => {
191
198
  const filteredFields = customFields.filter(f => f.name !== field.name);
@@ -252,17 +259,17 @@ const SettingsPage = () => {
252
259
  react_1.default.createElement(Stack_1.Stack, { size: 4 },
253
260
  react_1.default.createElement(Typography_1.Typography, { variant: "delta", as: "h2" }, (0, utils_2.getMessage)('pages.settings.additional.title')),
254
261
  react_1.default.createElement(Grid_1.Grid, { gap: 4 },
255
- react_1.default.createElement(Grid_1.GridItem, { col: 4, s: 6, xs: 12 },
262
+ react_1.default.createElement(Grid_1.GridItem, { col: 6, s: 6, xs: 12 },
256
263
  react_1.default.createElement(Box_1.Box, { style: { maxWidth: 257 } },
257
264
  react_1.default.createElement(NumberInput_1.NumberInput, { name: "allowedLevels", label: (0, utils_2.getMessage)('pages.settings.form.allowedLevels.label'), placeholder: (0, utils_2.getMessage)('pages.settings.form.allowedLevels.placeholder'), hint: (0, utils_2.getMessage)('pages.settings.form.allowedLevels.hint'), onValueChange: (value) => setFieldValue('allowedLevels', value, false), value: values.allowedLevels, disabled: restartStatus.required }))),
258
- react_1.default.createElement(Grid_1.GridItem, { col: 4, s: 12, xs: 12 },
265
+ react_1.default.createElement(Grid_1.GridItem, { col: 6, s: 12, xs: 12 },
259
266
  react_1.default.createElement(ToggleInput_1.ToggleInput, { name: "cascadeMenuAttachedChecked", label: (0, utils_2.getMessage)('pages.settings.form.cascadeMenuAttached.label'), hint: (0, utils_2.getMessage)('pages.settings.form.cascadeMenuAttached.hint'), checked: values.cascadeMenuAttachedChecked, onChange: ({ target: { checked } }) => {
260
267
  setFieldValue('cascadeMenuAttachedChecked', checked, true);
261
268
  }, onLabel: "Enabled", offLabel: "Disabled", disabled: restartStatus.required }))),
262
269
  react_1.default.createElement(Grid_1.Grid, { gap: 4 },
263
- react_1.default.createElement(Grid_1.GridItem, { col: 4, s: 12, xs: 12 },
270
+ react_1.default.createElement(Grid_1.GridItem, { col: 6, s: 12, xs: 12 },
264
271
  react_1.default.createElement(ToggleInput_1.ToggleInput, { name: "audienceFieldChecked", label: (0, utils_2.getMessage)('pages.settings.form.audience.label'), hint: (0, utils_2.getMessage)('pages.settings.form.audience.hint'), checked: values.audienceFieldChecked, onChange: () => setFieldValue('audienceFieldChecked', !values.audienceFieldChecked, false), onLabel: "Enabled", offLabel: "Disabled", disabled: restartStatus.required })),
265
- isI18NPluginEnabled && (react_1.default.createElement(Grid_1.GridItem, { col: 4, s: 12, xs: 12 },
272
+ isI18NPluginEnabled && (react_1.default.createElement(Grid_1.GridItem, { col: 6, s: 12, xs: 12 },
266
273
  react_1.default.createElement(ToggleInput_1.ToggleInput, { name: "i18nEnabled", label: (0, utils_2.getMessage)('pages.settings.form.i18n.label'), hint: defaultLocale
267
274
  ? (0, utils_2.getMessage)('pages.settings.form.i18n.hint')
268
275
  : (0, utils_2.getMessage)('pages.settings.form.i18n.hint.missingDefaultLocale'), checked: values.i18nEnabled, onChange: ({ target: { checked } }) => {
@@ -276,7 +283,12 @@ const SettingsPage = () => {
276
283
  setFieldValue('i18nEnabled', true);
277
284
  });
278
285
  }
279
- }, onLabel: "Enabled", offLabel: "Disabled", disabled: restartStatus.required || !defaultLocale })))))),
286
+ }, onLabel: "Enabled", offLabel: "Disabled", disabled: restartStatus.required || !defaultLocale })))),
287
+ isCachePluginEnabled && (react_1.default.createElement(Grid_1.Grid, { gap: 4 },
288
+ react_1.default.createElement(Grid_1.GridItem, { col: 12, s: 12, xs: 12 },
289
+ react_1.default.createElement(ToggleInput_1.ToggleInput, { name: "cacheEnabled", label: (0, utils_2.getMessage)('pages.settings.form.cache.label'), hint: (0, utils_2.getMessage)('pages.settings.form.cache.hint'), checked: values.isCacheEnabled, onChange: ({ target: { checked } }) => {
290
+ setFieldValue('isCacheEnabled', checked, false);
291
+ }, onLabel: "Enabled", offLabel: "Disabled", disabled: restartStatus.required })))))),
280
292
  react_1.default.createElement(Box_1.Box, { ...BOX_DEFAULT_PROPS },
281
293
  react_1.default.createElement(Stack_1.Stack, { size: 4 },
282
294
  react_1.default.createElement(Typography_1.Typography, { variant: "delta", as: "h2" }, (0, utils_2.getMessage)('pages.settings.customFields.title')),
@@ -9,6 +9,7 @@ export type RawPayload = {
9
9
  pathDefaultFields: Record<string, string[]>;
10
10
  populate: Record<string, string[]>;
11
11
  selectedContentTypes: string[];
12
+ isCacheEnabled: boolean;
12
13
  };
13
14
  export type StrapiContentTypeSchema = StrapiContentTypeFullSchema & {
14
15
  available: boolean;
@@ -23,7 +24,7 @@ export type PreparePayload = (payload: {
23
24
  export type OnSave = Effect<RawPayload>;
24
25
  export type OnPopupClose = Effect<boolean>;
25
26
  export type HandleSetContentTypeExpanded = Effect<string | undefined>;
26
- export type RestartReasons = 'I18N' | 'GRAPH_QL' | 'I18N_NAVIGATIONS_PRUNE';
27
+ export type RestartReasons = 'I18N' | 'GRAPH_QL' | 'I18N_NAVIGATIONS_PRUNE' | 'CACHE';
27
28
  export type RestartStatus = {
28
29
  required: true;
29
30
  reasons?: RestartReasons[];
@@ -1,5 +1,5 @@
1
1
  export default NavigationHeader;
2
- declare function NavigationHeader({ activeNavigation, availableNavigations, structureHasErrors, structureHasChanged, handleChangeSelection, handleLocalizationSelection, handleSave, config, permissions, }: {
2
+ declare function NavigationHeader({ activeNavigation, availableNavigations, structureHasErrors, structureHasChanged, handleChangeSelection, handleLocalizationSelection, handleSave, handleCachePurge, config, permissions, }: {
3
3
  activeNavigation: any;
4
4
  availableNavigations: any;
5
5
  structureHasErrors: any;
@@ -7,6 +7,7 @@ declare function NavigationHeader({ activeNavigation, availableNavigations, stru
7
7
  handleChangeSelection: any;
8
8
  handleLocalizationSelection: any;
9
9
  handleSave: any;
10
+ handleCachePurge: any;
10
11
  config: any;
11
12
  permissions?: {} | undefined;
12
13
  }): JSX.Element;
@@ -50,7 +50,7 @@ const pickDefaultLocaleNavigation = ({ activeNavigation, config }) => config.i18
50
50
  : activeNavigation?.localizations.find(({ localeCode }) => localeCode === config.defaultLocale)
51
51
  : null
52
52
  : activeNavigation;
53
- const NavigationHeader = ({ activeNavigation, availableNavigations, structureHasErrors, structureHasChanged, handleChangeSelection, handleLocalizationSelection, handleSave, config, permissions = {}, }) => {
53
+ const NavigationHeader = ({ activeNavigation, availableNavigations, structureHasErrors, structureHasChanged, handleChangeSelection, handleLocalizationSelection, handleSave, handleCachePurge, config, permissions = {}, }) => {
54
54
  const { formatMessage } = (0, react_intl_1.useIntl)();
55
55
  const allLocaleVersions = (0, react_1.useMemo)(() => activeNavigation?.localizations.length && config.i18nEnabled
56
56
  ? (0, lodash_1.uniqBy)([activeNavigation, ...(activeNavigation.localizations ?? [])].sort((a, b) => a.localeCode.localeCompare(b.localeCode)), 'id')
@@ -66,7 +66,7 @@ const NavigationHeader = ({ activeNavigation, availableNavigations, structureHas
66
66
  })
67
67
  : null), primaryAction: react_1.default.createElement(Stack_1.Stack, { horizontal: true, size: 2 },
68
68
  react_1.default.createElement(Box_1.Box, { marginRight: "8px" },
69
- react_1.default.createElement(Grid_1.Grid, { gap: 4 },
69
+ react_1.default.createElement(Grid_1.Grid, { gap: 4, style: config.isCacheEnabled ? { display: "flex" } : undefined },
70
70
  !hasLocalizations ? (react_1.default.createElement(Grid_1.GridItem, { col: 2 })) : null,
71
71
  canUpdate && (react_1.default.createElement(Grid_1.GridItem, { col: 3 },
72
72
  react_1.default.createElement(Button_1.Button, { onClick: openNavigationManagerModal, startIcon: null, type: "button", variant: "secondary", fullWidth: true, size: "S" }, formatMessage((0, translations_1.getTrad)('header.action.manage'))))),
@@ -77,7 +77,9 @@ const NavigationHeader = ({ activeNavigation, availableNavigations, structureHas
77
77
  react_1.default.createElement(Select_1.Select, { type: "select", placeholder: formatMessage((0, translations_1.getTrad)('pages.main.header.localization.select.placeholder')), name: "navigationLocalizationSelect", onChange: handleLocalizationSelection, value: activeNavigation?.id, size: "S" }, allLocaleVersions.map(({ id, localeCode }) => react_1.default.createElement(Select_1.Option, { key: id, value: id }, localeCode))))
78
78
  : null,
79
79
  canUpdate && (react_1.default.createElement(Grid_1.GridItem, { col: 3 },
80
- react_1.default.createElement(Button_1.Button, { onClick: handleSave, startIcon: submitIcon, disabled: structureHasErrors || !structureHasChanged, type: "submit", fullWidth: true, size: "S" }, formatMessage((0, translations_1.getTrad)('submit.cta.save'))))))),
80
+ react_1.default.createElement(Button_1.Button, { onClick: handleSave, startIcon: submitIcon, disabled: structureHasErrors || !structureHasChanged, type: "submit", fullWidth: true, size: "S" }, formatMessage((0, translations_1.getTrad)('submit.cta.save'))))),
81
+ config.isCacheEnabled && (react_1.default.createElement(Grid_1.GridItem, { col: 3 },
82
+ react_1.default.createElement(Button_1.Button, { onClick: handleCachePurge, variant: "danger", type: "submit", fullWidth: true, size: "S" }, formatMessage((0, translations_1.getTrad)('submit.cta.cache.purge'))))))),
81
83
  canUpdate && navigationManagerModal), title: formatMessage({
82
84
  id: (0, translations_1.getTrad)('header.title'),
83
85
  defaultMessage: 'UI Navigation',
@@ -1,3 +1,4 @@
1
1
  export declare const edit: JSX.Element;
2
2
  export declare const deleteIcon: JSX.Element;
3
+ export declare const brushIcon: JSX.Element;
3
4
  //# sourceMappingURL=icons.d.ts.map
@@ -3,9 +3,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.deleteIcon = exports.edit = void 0;
6
+ exports.brushIcon = exports.deleteIcon = exports.edit = void 0;
7
7
  const react_1 = __importDefault(require("react"));
8
8
  const icons_1 = require("@strapi/icons");
9
9
  exports.edit = react_1.default.createElement(icons_1.Pencil, null);
10
10
  exports.deleteIcon = react_1.default.createElement(icons_1.Trash, null);
11
+ exports.brushIcon = react_1.default.createElement(icons_1.Brush, null);
11
12
  //# sourceMappingURL=icons.js.map
@@ -43,7 +43,7 @@ const Footer_1 = require("../Footer");
43
43
  const NewNavigation_1 = require("../NewNavigation");
44
44
  const icons = __importStar(require("./icons"));
45
45
  const AllNavigations = ({ navigations, selected, setState }) => {
46
- const { config: { i18nEnabled }, } = (0, useDataManager_1.default)();
46
+ const { config: { i18nEnabled, isCacheEnabled }, } = (0, useDataManager_1.default)();
47
47
  const hasAnySelected = !!selected.length;
48
48
  const toggleSelected = (0, react_1.useCallback)(() => setState({
49
49
  navigations,
@@ -73,7 +73,14 @@ const AllNavigations = ({ navigations, selected, setState }) => {
73
73
  navigations,
74
74
  });
75
75
  };
76
+ const purgeCache = (navigations) => () => {
77
+ setState({
78
+ view: "CACHE_PURGE",
79
+ navigations,
80
+ });
81
+ };
76
82
  const deleteSelected = (0, react_1.useCallback)(_delete(selected), [_delete]);
83
+ const purgeSelected = (0, react_1.useCallback)(purgeCache(selected), [purgeCache]);
77
84
  return (react_1.default.createElement(react_1.default.Fragment, null,
78
85
  react_1.default.createElement(Grid_1.Grid, null,
79
86
  react_1.default.createElement(Grid_1.GridItem, { col: 12, paddingBottom: 3 }, hasAnySelected ? (react_1.default.createElement(Flex_1.Flex, { direction: "row", gap: 1 },
@@ -83,7 +90,8 @@ const AllNavigations = ({ navigations, selected, setState }) => {
83
90
  count: selected.length,
84
91
  },
85
92
  })),
86
- react_1.default.createElement(Button_1.Button, { onClick: deleteSelected, variant: "tertiary" }, (0, utils_1.getMessage)("popup.navigation.manage.button.delete")))) : null)),
93
+ react_1.default.createElement(Button_1.Button, { onClick: deleteSelected, variant: "tertiary" }, (0, utils_1.getMessage)("popup.navigation.manage.button.delete")),
94
+ isCacheEnabled ? (react_1.default.createElement(Button_1.Button, { onClick: purgeSelected, variant: "tertiary" }, (0, utils_1.getMessage)("popup.navigation.manage.button.purge"))) : null)) : null)),
87
95
  react_1.default.createElement(Table_1.Table, { rowCount: navigations.length, colCount: i18nEnabled ? 6 : 5 },
88
96
  react_1.default.createElement(Table_1.Thead, null,
89
97
  react_1.default.createElement(Table_1.Tr, null,
@@ -97,7 +105,9 @@ const AllNavigations = ({ navigations, selected, setState }) => {
97
105
  react_1.default.createElement(Typography_1.Typography, { textColor: "neutral800" }, (0, utils_1.getMessage)("popup.navigation.manage.table.locale")))) : null,
98
106
  react_1.default.createElement(Table_1.Th, null,
99
107
  react_1.default.createElement(Typography_1.Typography, { textColor: "neutral800" }, (0, utils_1.getMessage)("popup.navigation.manage.table.visibility"))),
100
- react_1.default.createElement(Table_1.Th, null))),
108
+ react_1.default.createElement(Table_1.Th, null, isCacheEnabled ? (react_1.default.createElement(Flex_1.Flex, { direction: "row" },
109
+ react_1.default.createElement(Box_1.Box, { paddingLeft: 1 },
110
+ react_1.default.createElement(IconButton_1.IconButton, { onClick: purgeCache([]), label: (0, utils_1.getMessage)("popup.navigation.manage.button.purge"), noBorder: true, icon: icons.brushIcon })))) : null))),
101
111
  react_1.default.createElement(Table_1.Tbody, null, navigations.map((navigation) => (react_1.default.createElement(Table_1.Tr, { key: navigation.id },
102
112
  react_1.default.createElement(Table_1.Td, null,
103
113
  react_1.default.createElement(BaseCheckbox_1.BaseCheckbox, { onValueChange: handleSelect(navigation, currentlySelectedSet.has(navigation.id)), value: currentlySelectedSet.has(navigation.id) })),
@@ -117,7 +127,9 @@ const AllNavigations = ({ navigations, selected, setState }) => {
117
127
  react_1.default.createElement(Box_1.Box, { paddingLeft: 1 },
118
128
  react_1.default.createElement(IconButton_1.IconButton, { onClick: edit(navigation), label: (0, utils_1.getMessage)("popup.navigation.manage.button.edit"), noBorder: true, icon: icons.edit })),
119
129
  react_1.default.createElement(Box_1.Box, { paddingLeft: 1 },
120
- react_1.default.createElement(IconButton_1.IconButton, { onClick: _delete([navigation]), label: (0, utils_1.getMessage)("popup.navigation.manage.button.delete"), noBorder: true, icon: icons.deleteIcon })))))))))));
130
+ react_1.default.createElement(IconButton_1.IconButton, { onClick: _delete([navigation]), label: (0, utils_1.getMessage)("popup.navigation.manage.button.delete"), noBorder: true, icon: icons.deleteIcon })),
131
+ isCacheEnabled ? (react_1.default.createElement(Box_1.Box, { paddingLeft: 1 },
132
+ react_1.default.createElement(IconButton_1.IconButton, { onClick: purgeCache([navigation]), label: (0, utils_1.getMessage)("popup.navigation.manage.button.purge"), noBorder: true, icon: icons.brushIcon }))) : null)))))))));
121
133
  };
122
134
  exports.AllNavigations = AllNavigations;
123
135
  const AllNavigationsFooter = ({ onClose, state, setState, navigations, }) => (react_1.default.createElement(Footer_1.FooterBase, { start: {
@@ -0,0 +1,8 @@
1
+ import { Footer } from "../Footer";
2
+ import { CommonProps, PurgeCacheState } from "../types";
3
+ interface Props extends PurgeCacheState, CommonProps {
4
+ }
5
+ export declare const PurgeCacheConfirm: ({ navigations }: Props) => JSX.Element;
6
+ export declare const PurgeCacheConfirmFooter: Footer;
7
+ export {};
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.PurgeCacheConfirmFooter = exports.PurgeCacheConfirm = void 0;
7
+ const Flex_1 = require("@strapi/design-system/Flex");
8
+ const Grid_1 = require("@strapi/design-system/Grid");
9
+ const Typography_1 = require("@strapi/design-system/Typography");
10
+ const fp_1 = require("lodash/fp");
11
+ const react_1 = __importDefault(require("react"));
12
+ const utils_1 = require("../../../../../utils");
13
+ const Footer_1 = require("../Footer");
14
+ const PurgeCacheConfirm = ({ navigations }) => (react_1.default.createElement(Grid_1.Grid, null,
15
+ react_1.default.createElement(Grid_1.GridItem, { col: 12, paddingBottom: 1 },
16
+ react_1.default.createElement(Flex_1.Flex, null,
17
+ react_1.default.createElement(Typography_1.Typography, { variant: "beta" }, (0, utils_1.getMessage)("popup.navigation.manage.purge.header")))),
18
+ react_1.default.createElement(Grid_1.GridItem, { col: 12, paddingBottom: 1 },
19
+ react_1.default.createElement(Typography_1.Typography, { variant: "omega", fontWeight: "semiBold" }, renderItems(navigations)))));
20
+ exports.PurgeCacheConfirm = PurgeCacheConfirm;
21
+ const PurgeCacheConfirmFooter = ({ state, onSubmit, onReset }) => (react_1.default.createElement(Footer_1.FooterBase, { start: {
22
+ children: (0, utils_1.getMessage)("popup.item.form.button.cancel"),
23
+ disabled: state.isLoading,
24
+ onClick: onReset,
25
+ variant: "tertiary",
26
+ }, end: {
27
+ children: (0, utils_1.getMessage)("popup.navigation.manage.footer.button.purge"),
28
+ disabled: state.isLoading,
29
+ onClick: onSubmit,
30
+ variant: "danger",
31
+ } }));
32
+ exports.PurgeCacheConfirmFooter = PurgeCacheConfirmFooter;
33
+ const renderItems = (navigations) => navigations.map((0, fp_1.prop)("name")).join(", ");
34
+ //# sourceMappingURL=index.js.map
@@ -41,10 +41,11 @@ const DeletionConfirm_1 = require("./DeletionConfirm");
41
41
  const ErrorDetails_1 = require("./ErrorDetails");
42
42
  const NavigationUpdate_1 = require("./NavigationUpdate");
43
43
  const NewNavigation_1 = require("./NewNavigation");
44
+ const PurgeCacheConfirm_1 = require("./PurgeCacheConfirm");
44
45
  const NavigationManager = ({ initialState, isOpened, onClose, }) => {
45
46
  const { formatMessage } = (0, react_intl_1.useIntl)();
46
47
  const [state, setState] = (0, react_1.useState)(initialState);
47
- const { items = [], handleNavigationsDeletion, handleSubmitNavigation, hardReset, } = (0, useDataManager_1.default)();
48
+ const { items = [], handleNavigationsDeletion, handleNavigationsPurge, handleSubmitNavigation, hardReset, } = (0, useDataManager_1.default)();
48
49
  const navigations = (0, react_1.useMemo)(() => (0, lodash_1.sortBy)(items, "id"), [items]);
49
50
  const onReset = (0, react_1.useCallback)(() => setState({ view: "INITIAL" }), [setState]);
50
51
  const onSubmit = (0, react_1.useCallback)(async () => {
@@ -58,7 +59,12 @@ const NavigationManager = ({ initialState, isOpened, onClose, }) => {
58
59
  await handleSubmitNavigation(formatMessage, state.current);
59
60
  await hardReset();
60
61
  }
61
- : () => { };
62
+ : state.view === "CACHE_PURGE"
63
+ ? async () => {
64
+ await handleNavigationsPurge(state.navigations.map((0, fp_1.prop)("id")), true, true);
65
+ await hardReset();
66
+ }
67
+ : () => { };
62
68
  try {
63
69
  setState({
64
70
  ...state,
@@ -110,6 +116,7 @@ const renderHeader = (state) => {
110
116
  case "LIST":
111
117
  case "CREATE":
112
118
  case "ERROR":
119
+ case "CACHE_PURGE":
113
120
  case "DELETE": {
114
121
  return (react_1.default.createElement(Flex_1.Flex, { direction: "row" },
115
122
  state.isLoading ? react_1.default.createElement(Loader_1.Loader, { small: true }) : null,
@@ -149,6 +156,9 @@ const renderContent = (state, setState) => {
149
156
  case "DELETE": {
150
157
  return react_1.default.createElement(DeletionConfirm_1.DeletionConfirm, { ...state, ...commonProps });
151
158
  }
159
+ case "CACHE_PURGE": {
160
+ return react_1.default.createElement(PurgeCacheConfirm_1.PurgeCacheConfirm, { ...state, ...commonProps });
161
+ }
152
162
  case "INITIAL": {
153
163
  return react_1.default.createElement(Loader_1.Loader, { small: true });
154
164
  }
@@ -173,6 +183,9 @@ const renderFooter = (props) => {
173
183
  case "DELETE": {
174
184
  return react_1.default.createElement(DeletionConfirm_1.DeleteConfirmFooter, { ...props });
175
185
  }
186
+ case "CACHE_PURGE": {
187
+ return react_1.default.createElement(PurgeCacheConfirm_1.PurgeCacheConfirmFooter, { ...props });
188
+ }
176
189
  case "ERROR": {
177
190
  return react_1.default.createElement(ErrorDetails_1.ErrorDetailsFooter, { ...props });
178
191
  }
@@ -1,7 +1,7 @@
1
1
  import { Dispatch, SetStateAction } from "react";
2
2
  import { Navigation as FullNavigationEntity } from "../../../../../../types";
3
3
  export type Navigation = Pick<FullNavigationEntity, "id" | "items" | "name" | "localeCode" | "localizations" | "visible">;
4
- export type State = InitialState | ListState | EditState | CreateState | DeleteState | ErrorState;
4
+ export type State = InitialState | ListState | EditState | CreateState | DeleteState | PurgeCacheState | ErrorState;
5
5
  export type SetState = Dispatch<SetStateAction<State>>;
6
6
  interface CommonState {
7
7
  isLoading?: boolean;
@@ -32,6 +32,10 @@ export interface DeleteState extends CommonState {
32
32
  view: "DELETE";
33
33
  navigations: Array<Navigation>;
34
34
  }
35
+ export interface PurgeCacheState extends CommonState {
36
+ view: "CACHE_PURGE";
37
+ navigations: Array<Navigation>;
38
+ }
35
39
  export interface ErrorState extends CommonState {
36
40
  view: "ERROR";
37
41
  errors: Array<Error>;
@@ -54,7 +54,7 @@ const parsers_1 = require("./utils/parsers");
54
54
  const NoAccessPage_1 = __importDefault(require("../NoAccessPage"));
55
55
  const View = () => {
56
56
  const toggleNotification = (0, helper_plugin_1.useNotification)();
57
- const { items: availableNavigations, activeItem: activeNavigation, changedActiveItem: changedActiveNavigation, config, navigationItemPopupOpened, isLoading, isLoadingForAdditionalDataToBeSet, isLoadingForSubmit, handleChangeNavigationItemPopupVisibility, handleChangeSelection, handleChangeNavigationData, handleResetNavigationData, handleSubmitNavigation, handleLocalizationSelection, handleI18nCopy, getContentTypeItems, error, availableLocale: allAvailableLocale, readNavigationItemFromLocale, slugify, permissions, } = (0, useDataManager_1.default)();
57
+ const { items: availableNavigations, activeItem: activeNavigation, changedActiveItem: changedActiveNavigation, config, navigationItemPopupOpened, isLoading, isLoadingForAdditionalDataToBeSet, isLoadingForSubmit, handleChangeNavigationItemPopupVisibility, handleChangeSelection, handleChangeNavigationData, handleResetNavigationData, handleSubmitNavigation, handleLocalizationSelection, handleI18nCopy, getContentTypeItems, error, availableLocale: allAvailableLocale, readNavigationItemFromLocale, slugify, permissions, handleNavigationsPurge, } = (0, useDataManager_1.default)();
58
58
  const { canAccess, canUpdate } = permissions;
59
59
  const availableLocale = (0, react_1.useMemo)(() => allAvailableLocale.filter(locale => locale !== changedActiveNavigation?.localeCode), [changedActiveNavigation, allAvailableLocale]);
60
60
  const { i18nCopyItemsModal, i18nCopySourceLocale, setI18nCopyModalOpened, setI18nCopySourceLocale } = (0, useI18nCopyNavigationItemsModal_1.useI18nCopyNavigationItemsModal)((0, react_1.useCallback)((sourceLocale) => {
@@ -83,6 +83,9 @@ const View = () => {
83
83
  const handleSave = () => isLoadingForSubmit || structureHasErrors
84
84
  ? null
85
85
  : handleSubmitNavigation(formatMessage, (0, parsers_1.transformToRESTPayload)(changedActiveNavigation, config));
86
+ const handleCachePurge = () => {
87
+ handleNavigationsPurge([navigationSelectValue]);
88
+ };
86
89
  const changeNavigationItemPopupState = (visible, editedItem = {}) => {
87
90
  setActiveNavigationItemState(editedItem);
88
91
  handleChangeNavigationItemPopupVisibility(visible);
@@ -233,7 +236,7 @@ const View = () => {
233
236
  });
234
237
  }
235
238
  return (react_1.default.createElement(Main_1.Main, { labelledBy: "title", "aria-busy": isLoadingForSubmit },
236
- react_1.default.createElement(NavigationHeader_1.default, { structureHasErrors: structureHasErrors, structureHasChanged: structureChanged, availableNavigations: availableNavigations, activeNavigation: activeNavigation, handleChangeSelection: handleChangeNavigationSelection, handleSave: handleSave, handleLocalizationSelection: handleLocalizationSelection, config: config, permissions: {
239
+ react_1.default.createElement(NavigationHeader_1.default, { structureHasErrors: structureHasErrors, structureHasChanged: structureChanged, availableNavigations: availableNavigations, activeNavigation: activeNavigation, handleChangeSelection: handleChangeNavigationSelection, handleSave: handleSave, handleCachePurge: handleCachePurge, handleLocalizationSelection: handleLocalizationSelection, config: config, permissions: {
237
240
  canAccess, canUpdate
238
241
  } }),
239
242
  react_1.default.createElement(Layout_1.ContentLayout, null,
@@ -9,6 +9,7 @@
9
9
  "header.action.expandAll": "Expand All",
10
10
  "submit.cta.cancel": "Cancel",
11
11
  "submit.cta.save": "Save",
12
+ "submit.cta.cache.purge": "Clear cache",
12
13
  "empty": "Your navigation is empty",
13
14
  "empty.cta": "Create first item",
14
15
  "popup.item.header.view": "View navigation item",
@@ -66,10 +67,14 @@
66
67
  "popup.navigation.manage.button.goBack": "Go back",
67
68
  "popup.navigation.manage.button.cancel": "Cancel",
68
69
  "popup.navigation.manage.button.delete": "Delete",
70
+ "popup.navigation.manage.button.purge": "Clear read cache",
71
+ "popup.navigation.manage.footer.button.purge": "Clear",
72
+ "popup.navigation.manage.purge.header": "This action will clear API read cache. This will result in brief slowdown of reads for navigations below.",
69
73
  "popup.navigation.manage.button.save": "Save",
70
74
  "popup.navigation.manage.button.edit": "Edit",
71
75
  "popup.navigation.manage.button.create": "Create",
72
76
  "popup.navigation.manage.delete.header": "Following navigations will be removed:",
77
+ "popup.navigation.manage.header.CACHE_PURGE": "Read cache clear",
73
78
  "popup.navigation.manage.header.LIST": "All navigations",
74
79
  "popup.navigation.manage.header.CREATE": "New navigation",
75
80
  "popup.navigation.manage.header.DELETE": "Deleting",
@@ -134,6 +139,8 @@
134
139
  "pages.settings.form.cascadeMenuAttached.label": "Cascade menu attached",
135
140
  "pages.settings.form.cascadeMenuAttached.hint": "Disable if you don't want \"Menu attached\" to cascade on child items",
136
141
  "pages.settings.form.contentTypes.label": "Enable navigation for",
142
+ "pages.settings.form.cache.label": "REST cache",
143
+ "pages.settings.form.cache.hint": "Enable caching of client read requests",
137
144
  "pages.settings.form.i18n.label": "i18n",
138
145
  "pages.settings.form.i18n.hint": "Enable internationalisation",
139
146
  "pages.settings.form.i18n.hint.missingDefaultLocale": "Default locale missing!",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "strapi-plugin-navigation",
3
- "version": "2.4.0",
3
+ "version": "2.5.1",
4
4
  "description": "Strapi - Navigation plugin",
5
5
  "strapi": {
6
6
  "name": "navigation",
@@ -16,19 +16,19 @@
16
16
  "types": "./types/index.d.ts",
17
17
  "dependencies": {
18
18
  "@sindresorhus/slugify": "1.1.0",
19
- "@strapi/utils": "^4.20.0",
19
+ "@strapi/utils": "^4.24.4",
20
20
  "lodash": "^4.17.21",
21
21
  "pluralize": "^8.0.0",
22
- "react": "^18.2.0",
23
- "react-dom": "^18.2.0",
22
+ "react": "^17.0.0 || ^18.0.0",
23
+ "react-dom": "^17.0.0 || ^18.0.0",
24
24
  "react-intl": "6.4.1",
25
25
  "react-router": "^5.3.4",
26
- "react-router-dom": "^5.3.4",
26
+ "react-router-dom": "^5.2.0",
27
27
  "uuid": "^8.3.0"
28
28
  },
29
29
  "devDependencies": {},
30
30
  "peerDependencies": {
31
- "@strapi/data-transfer": "4.15.5",
31
+ "@strapi/data-transfer": "4.24.4",
32
32
  "@strapi/strapi": "4.x",
33
33
  "react": "^17.0.0 || ^18.0.0",
34
34
  "react-dom": "^17.0.0 || ^18.0.0",
@@ -6,6 +6,7 @@ const permissions_1 = __importDefault(require("../../permissions"));
6
6
  const graphql_1 = require("../graphql");
7
7
  const navigation_1 = require("../navigation");
8
8
  const config_1 = require("../config");
9
+ const cache_1 = require("../cache");
9
10
  const assertUserPermissionsAvailability = ({ strapi }) => {
10
11
  if (!strapi.plugin("users-permissions")) {
11
12
  throw new Error("In order to make the navigation plugin work the users-permissions plugin is required");
@@ -14,6 +15,7 @@ const assertUserPermissionsAvailability = ({ strapi }) => {
14
15
  const setupGraphQL = graphql_1.graphQLSetupStrategy;
15
16
  const setupNavigation = navigation_1.navigationSetupStrategy;
16
17
  const setupConfig = config_1.configSetupStrategy;
18
+ const setupCache = cache_1.setupCacheStrategy;
17
19
  const setupPermissions = async ({ strapi }) => {
18
20
  const actions = [
19
21
  {
@@ -43,5 +45,6 @@ module.exports = async ({ strapi }) => {
43
45
  await setupConfig({ strapi });
44
46
  await setupGraphQL({ strapi });
45
47
  await setupNavigation({ strapi });
48
+ await setupCache({ strapi });
46
49
  };
47
50
  //# sourceMappingURL=index.js.map
@@ -0,0 +1,2 @@
1
+ export * from "./setupStrategy";
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./setupStrategy"), exports);
18
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,3 @@
1
+ import { AddCacheConfigFieldsInput, CacheConfigFields } from "./types";
2
+ export declare const addCacheConfigFields: <T>({ previousConfig, strapi, }: AddCacheConfigFieldsInput<T>) => Promise<T & CacheConfigFields>;
3
+ //# sourceMappingURL=serviceEnhancers.d.ts.map