strapi-plugin-navigation 2.3.1 → 2.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +47 -6
- package/admin/src/components/AdditionalFieldInput/index.d.ts +2 -2
- package/admin/src/components/AdditionalFieldInput/index.js +36 -8
- package/admin/src/components/AdditionalFieldInput/types.d.ts +1 -1
- package/admin/src/components/DragButton/index.d.ts +3 -1
- package/admin/src/components/DragButton/index.js +2 -1
- package/admin/src/components/Item/ItemCardHeader/index.d.ts +1 -0
- package/admin/src/components/Item/ItemCardHeader/index.js +10 -5
- package/admin/src/components/Item/index.js +24 -4
- package/admin/src/components/NavigationItemList/index.js +1 -1
- package/admin/src/components/Search/index.d.ts +10 -4
- package/admin/src/components/Search/index.js +45 -6
- package/admin/src/components/TextArrayInput/index.d.ts +2 -1
- package/admin/src/hooks/useAllContentTypes.d.ts +1 -1
- package/admin/src/hooks/useNavigationConfig.d.ts +3 -3
- package/admin/src/index.d.ts +3 -1
- package/admin/src/pages/SettingsPage/common/const.d.ts +2 -0
- package/admin/src/pages/SettingsPage/common/const.js +5 -0
- package/admin/src/pages/SettingsPage/common/index.d.ts +2 -0
- package/admin/src/pages/SettingsPage/common/index.js +18 -0
- package/admin/src/pages/SettingsPage/components/CustomFieldForm/index.js +27 -12
- package/admin/src/pages/SettingsPage/components/CustomFieldTable/index.js +1 -1
- package/admin/src/pages/SettingsPage/components/DisableI18nModal/index.d.ts +2 -3
- package/admin/src/pages/SettingsPage/components/DisableI18nModal/index.js +12 -14
- package/admin/src/pages/SettingsPage/index.js +3 -2
- package/admin/src/pages/SettingsPage/utils/form.js +2 -1
- package/admin/src/pages/View/components/NavigationItemForm/index.js +49 -19
- package/admin/src/pages/View/components/NavigationItemForm/types.d.ts +2 -1
- package/admin/src/pages/View/components/NavigationItemForm/utils/form.js +2 -0
- package/admin/src/pages/View/index.js +20 -10
- package/admin/src/pages/View/utils/form.d.ts +1 -1
- package/admin/src/pages/View/utils/types.d.ts +3 -0
- package/admin/src/pages/View/utils/types.js +3 -0
- package/admin/src/translations/ca.json +1 -0
- package/admin/src/translations/en.json +3 -0
- package/admin/src/translations/fr.json +1 -0
- package/admin/src/utils/api.d.ts +4 -4
- package/admin/src/utils/api.js +1 -1
- package/package.json +8 -3
- package/server/content-types/index.d.ts +2 -0
- package/server/content-types/navigation/index.d.ts +1 -0
- package/server/content-types/navigation/index.js +3 -1
- package/server/content-types/navigation/lifecycles.d.ts +3 -0
- package/server/content-types/navigation/lifecycles.js +7 -0
- package/server/content-types/navigation-item/index.d.ts +1 -0
- package/server/content-types/navigation-item/index.js +3 -1
- package/server/content-types/navigation-item/lifecycles.d.ts +3 -0
- package/server/content-types/navigation-item/lifecycles.js +7 -0
- package/server/controllers/admin.js +19 -16
- package/server/controllers/client.js +6 -4
- package/server/graphql/queries/render-navigation-child.d.ts +1 -1
- package/server/graphql/queries/render-navigation.d.ts +1 -1
- package/server/graphql/types/index.js +1 -0
- package/server/graphql/types/navigation-item-additional-field-media.d.ts +5 -0
- package/server/graphql/types/navigation-item-additional-field-media.js +13 -0
- package/server/graphql/types/navigation-item.js +3 -0
- package/server/i18n/utils.d.ts +1 -0
- package/server/i18n/utils.js +4 -0
- package/server/index.d.ts +2 -0
- package/server/services/admin.js +18 -8
- package/server/services/client.js +42 -11
- package/server/services/common.js +17 -5
- package/server/utils/constant.d.ts +3 -0
- package/server/utils/constant.js +21 -1
- package/server/utils/functions.d.ts +16 -4
- package/server/utils/functions.js +54 -8
- package/strapi-server.d.ts +2 -0
- package/tsconfig.tsbuildinfo +1 -1
- package/types/contentTypes.d.ts +7 -2
- package/types/controllers.d.ts +4 -3
- package/types/index.d.ts +1 -0
- package/types/index.js +1 -0
- package/types/lifecycle.d.ts +22 -0
- package/types/lifecycle.js +3 -0
- package/types/services.d.ts +13 -1
|
@@ -7,29 +7,32 @@ const utils_3 = require("../utils");
|
|
|
7
7
|
const InvalidParamNavigationError_1 = require("../../utils/InvalidParamNavigationError");
|
|
8
8
|
const NavigationError_1 = require("../../utils/NavigationError");
|
|
9
9
|
const adminControllers = {
|
|
10
|
-
|
|
11
|
-
return (0, utils_2.getPluginService)(
|
|
10
|
+
getAdminService() {
|
|
11
|
+
return (0, utils_2.getPluginService)("admin");
|
|
12
|
+
},
|
|
13
|
+
getCommonService() {
|
|
14
|
+
return (0, utils_2.getPluginService)("common");
|
|
12
15
|
},
|
|
13
16
|
async get() {
|
|
14
|
-
return await this.
|
|
17
|
+
return await this.getAdminService().get();
|
|
15
18
|
},
|
|
16
19
|
post(ctx) {
|
|
17
20
|
const { auditLog } = ctx;
|
|
18
21
|
const { body = {} } = ctx.request;
|
|
19
|
-
return this.
|
|
22
|
+
return this.getAdminService().post(body, auditLog);
|
|
20
23
|
},
|
|
21
24
|
put(ctx) {
|
|
22
25
|
const { params, auditLog } = ctx;
|
|
23
26
|
const { id } = (0, utils_2.parseParams)(params);
|
|
24
27
|
const { body = {} } = ctx.request;
|
|
25
|
-
return this.
|
|
28
|
+
return this.getAdminService().put(id, body, auditLog).catch((0, utils_3.errorHandler)(ctx));
|
|
26
29
|
},
|
|
27
30
|
async delete(ctx) {
|
|
28
31
|
const { params, auditLog } = ctx;
|
|
29
32
|
const { id } = (0, utils_2.parseParams)(params);
|
|
30
33
|
try {
|
|
31
34
|
(0, types_1.assertNotEmpty)(id, new InvalidParamNavigationError_1.InvalidParamNavigationError("Navigation's id is not a id"));
|
|
32
|
-
await this.
|
|
35
|
+
await this.getAdminService().delete(id, auditLog);
|
|
33
36
|
return {};
|
|
34
37
|
}
|
|
35
38
|
catch (error) {
|
|
@@ -41,11 +44,11 @@ const adminControllers = {
|
|
|
41
44
|
}
|
|
42
45
|
},
|
|
43
46
|
async config() {
|
|
44
|
-
return this.
|
|
47
|
+
return this.getAdminService().config();
|
|
45
48
|
},
|
|
46
49
|
async updateConfig(ctx) {
|
|
47
50
|
try {
|
|
48
|
-
await this.
|
|
51
|
+
await this.getAdminService().updateConfig(ctx.request.body);
|
|
49
52
|
}
|
|
50
53
|
catch (e) {
|
|
51
54
|
(0, utils_3.errorHandler)(ctx)(e);
|
|
@@ -54,7 +57,7 @@ const adminControllers = {
|
|
|
54
57
|
},
|
|
55
58
|
async restoreConfig(ctx) {
|
|
56
59
|
try {
|
|
57
|
-
await this.
|
|
60
|
+
await this.getAdminService().restoreConfig();
|
|
58
61
|
}
|
|
59
62
|
catch (e) {
|
|
60
63
|
(0, utils_3.errorHandler)(ctx)(e);
|
|
@@ -62,11 +65,11 @@ const adminControllers = {
|
|
|
62
65
|
return ctx.send({ status: 200 });
|
|
63
66
|
},
|
|
64
67
|
async settingsConfig() {
|
|
65
|
-
return this.
|
|
68
|
+
return this.getAdminService().config(true);
|
|
66
69
|
},
|
|
67
70
|
async settingsRestart(ctx) {
|
|
68
71
|
try {
|
|
69
|
-
await this.
|
|
72
|
+
await this.getAdminService().restart();
|
|
70
73
|
return ctx.send({ status: 200 });
|
|
71
74
|
}
|
|
72
75
|
catch (e) {
|
|
@@ -76,19 +79,19 @@ const adminControllers = {
|
|
|
76
79
|
async getById(ctx) {
|
|
77
80
|
const { params } = ctx;
|
|
78
81
|
const { id } = (0, utils_2.parseParams)(params);
|
|
79
|
-
return this.
|
|
82
|
+
return this.getAdminService().getById(id);
|
|
80
83
|
},
|
|
81
84
|
async getContentTypeItems(ctx) {
|
|
82
85
|
const { params, query = {} } = ctx;
|
|
83
86
|
const { model } = (0, utils_2.parseParams)(params);
|
|
84
|
-
return this.
|
|
87
|
+
return this.getCommonService().getContentTypeItems(model, query);
|
|
85
88
|
},
|
|
86
89
|
fillFromOtherLocale(ctx) {
|
|
87
90
|
const { params, auditLog } = ctx;
|
|
88
91
|
const { source, target } = (0, utils_2.parseParams)(params);
|
|
89
92
|
try {
|
|
90
93
|
assertCopyParams(source, target);
|
|
91
|
-
return this.
|
|
94
|
+
return this.getAdminService().fillFromOtherLocale({ source, target, auditLog });
|
|
92
95
|
}
|
|
93
96
|
catch (error) {
|
|
94
97
|
if (error instanceof Error) {
|
|
@@ -103,7 +106,7 @@ const adminControllers = {
|
|
|
103
106
|
try {
|
|
104
107
|
assertCopyParams(source, target);
|
|
105
108
|
(0, types_1.assertNotEmpty)(path, new InvalidParamNavigationError_1.InvalidParamNavigationError("Path is missing"));
|
|
106
|
-
return await this.
|
|
109
|
+
return await this.getAdminService().readNavigationItemFromLocale({
|
|
107
110
|
path,
|
|
108
111
|
source,
|
|
109
112
|
target,
|
|
@@ -125,7 +128,7 @@ const adminControllers = {
|
|
|
125
128
|
const { query: { q } } = ctx;
|
|
126
129
|
try {
|
|
127
130
|
(0, types_1.assertNotEmpty)(q);
|
|
128
|
-
return this.
|
|
131
|
+
return this.getCommonService().getSlug(q).then((slug) => ({ slug }));
|
|
129
132
|
}
|
|
130
133
|
catch (error) {
|
|
131
134
|
if (error instanceof Error) {
|
|
@@ -3,15 +3,17 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
const utils_1 = require("@strapi/utils");
|
|
4
4
|
const utils_2 = require("../utils");
|
|
5
5
|
const clientControllers = {
|
|
6
|
-
getService(
|
|
7
|
-
return (0, utils_2.getPluginService)(
|
|
6
|
+
getService() {
|
|
7
|
+
return (0, utils_2.getPluginService)("client");
|
|
8
8
|
},
|
|
9
9
|
async readAll(ctx) {
|
|
10
10
|
const { query = {} } = ctx;
|
|
11
11
|
const { locale, orderBy, orderDirection } = query;
|
|
12
12
|
try {
|
|
13
13
|
return await this.getService().readAll({
|
|
14
|
-
locale,
|
|
14
|
+
locale,
|
|
15
|
+
orderBy,
|
|
16
|
+
orderDirection,
|
|
15
17
|
});
|
|
16
18
|
}
|
|
17
19
|
catch (error) {
|
|
@@ -32,7 +34,7 @@ const clientControllers = {
|
|
|
32
34
|
menuOnly,
|
|
33
35
|
rootPath,
|
|
34
36
|
locale,
|
|
35
|
-
populate
|
|
37
|
+
populate: (0, utils_2.sanitizePopulateField)(populate),
|
|
36
38
|
});
|
|
37
39
|
}
|
|
38
40
|
catch (error) {
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
module.exports = ({ nexus }) => nexus.objectType({
|
|
3
|
+
name: "NavigationItemAdditionalFieldMedia",
|
|
4
|
+
definition(t) {
|
|
5
|
+
t.nonNull.string("name");
|
|
6
|
+
t.nonNull.string("url");
|
|
7
|
+
t.nonNull.string("mime");
|
|
8
|
+
t.nonNull.int("width");
|
|
9
|
+
t.nonNull.int("height");
|
|
10
|
+
t.string("previewUrl");
|
|
11
|
+
}
|
|
12
|
+
});
|
|
13
|
+
//# sourceMappingURL=navigation-item-additional-field-media.js.map
|
|
@@ -26,6 +26,9 @@ module.exports = ({ nexus, config }) => nexus.objectType({
|
|
|
26
26
|
if (field !== 'audience') {
|
|
27
27
|
if (field.enabled) {
|
|
28
28
|
switch (field.type) {
|
|
29
|
+
case 'media':
|
|
30
|
+
t.field(field.name, { type: "NavigationItemAdditionalFieldMedia" });
|
|
31
|
+
break;
|
|
29
32
|
case 'string':
|
|
30
33
|
t.string(field.name);
|
|
31
34
|
break;
|
package/server/i18n/utils.d.ts
CHANGED
package/server/i18n/utils.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getI18nStatus = void 0;
|
|
4
|
+
const fp_1 = require("lodash/fp");
|
|
4
5
|
const getI18nStatus = async ({ strapi, }) => {
|
|
5
6
|
const i18nPlugin = strapi.plugin("i18n");
|
|
6
7
|
const hasI18NPlugin = !!i18nPlugin;
|
|
@@ -13,16 +14,19 @@ const getI18nStatus = async ({ strapi, }) => {
|
|
|
13
14
|
});
|
|
14
15
|
const localeService = i18nPlugin ? i18nPlugin.service("locales") : null;
|
|
15
16
|
const defaultLocale = await localeService?.getDefaultLocale();
|
|
17
|
+
const locales = (await localeService?.find({}))?.map((0, fp_1.prop)("code"));
|
|
16
18
|
return hasI18NPlugin
|
|
17
19
|
? {
|
|
18
20
|
hasI18NPlugin,
|
|
19
21
|
enabled: config.i18nEnabled,
|
|
20
22
|
defaultLocale,
|
|
23
|
+
locales,
|
|
21
24
|
}
|
|
22
25
|
: {
|
|
23
26
|
hasI18NPlugin,
|
|
24
27
|
enabled: false,
|
|
25
28
|
defaultLocale: undefined,
|
|
29
|
+
locales: undefined
|
|
26
30
|
};
|
|
27
31
|
};
|
|
28
32
|
exports.getI18nStatus = getI18nStatus;
|
package/server/index.d.ts
CHANGED
|
@@ -82,6 +82,7 @@ declare const _default: {
|
|
|
82
82
|
};
|
|
83
83
|
};
|
|
84
84
|
};
|
|
85
|
+
lifecycles: Record<import("../types").LifeCycleHookName, import("../types").Effect<import("../types").LifeCycleEvent<import("../types").LifeCycleHookName, unknown, Record<string, unknown>>>>;
|
|
85
86
|
};
|
|
86
87
|
"navigation-item": {
|
|
87
88
|
schema: {
|
|
@@ -185,6 +186,7 @@ declare const _default: {
|
|
|
185
186
|
};
|
|
186
187
|
};
|
|
187
188
|
};
|
|
189
|
+
lifecycles: Record<import("../types").LifeCycleHookName, import("../types").Effect<import("../types").LifeCycleEvent<import("../types").LifeCycleHookName, unknown, Record<string, unknown>>>>;
|
|
188
190
|
};
|
|
189
191
|
"navigations-items-related": {
|
|
190
192
|
schema: {
|
package/server/services/admin.js
CHANGED
|
@@ -69,17 +69,27 @@ const adminService = ({ strapi, }) => ({
|
|
|
69
69
|
},
|
|
70
70
|
async get(ids) {
|
|
71
71
|
const { masterModel } = (0, utils_2.getPluginModels)();
|
|
72
|
-
const
|
|
72
|
+
const { enabled: i18nEnabled, locales } = await (0, i18n_1.getI18nStatus)({ strapi });
|
|
73
|
+
const whereClause = {};
|
|
74
|
+
if (ids) {
|
|
75
|
+
whereClause.id = { $in: ids };
|
|
76
|
+
}
|
|
77
|
+
let entities = await strapi.query(masterModel.uid).findMany({
|
|
73
78
|
limit: Number.MAX_SAFE_INTEGER,
|
|
74
79
|
populate: utils_2.DEFAULT_POPULATE,
|
|
75
|
-
where:
|
|
76
|
-
? {
|
|
77
|
-
id: {
|
|
78
|
-
$in: ids,
|
|
79
|
-
},
|
|
80
|
-
}
|
|
81
|
-
: undefined,
|
|
80
|
+
where: whereClause,
|
|
82
81
|
});
|
|
82
|
+
if (i18nEnabled) {
|
|
83
|
+
entities = entities.reduce((acc, entity) => {
|
|
84
|
+
if (entity.localeCode && locales?.includes(entity.localeCode)) {
|
|
85
|
+
acc.push({
|
|
86
|
+
...entity,
|
|
87
|
+
localizations: entity.localizations?.filter(({ localeCode }) => localeCode && locales?.includes(localeCode)),
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
return acc;
|
|
91
|
+
}, []);
|
|
92
|
+
}
|
|
83
93
|
return entities;
|
|
84
94
|
},
|
|
85
95
|
async getById(id) {
|
|
@@ -7,10 +7,12 @@ const utils_1 = require("../utils");
|
|
|
7
7
|
const utils_2 = require("@strapi/utils");
|
|
8
8
|
const i18n_1 = require("../i18n");
|
|
9
9
|
const NavigationError_1 = require("../../utils/NavigationError");
|
|
10
|
+
const fp_1 = require("lodash/fp");
|
|
10
11
|
const clientService = ({ strapi }) => ({
|
|
11
12
|
async readAll({ locale, orderBy = 'createdAt', orderDirection = "DESC" }) {
|
|
12
13
|
const { masterModel } = (0, utils_1.getPluginModels)();
|
|
13
|
-
const
|
|
14
|
+
const { enabled: i18nEnabled, locales } = await (0, i18n_1.getI18nStatus)({ strapi });
|
|
15
|
+
let navigations = await strapi
|
|
14
16
|
.query(masterModel.uid)
|
|
15
17
|
.findMany({
|
|
16
18
|
where: locale
|
|
@@ -22,6 +24,17 @@ const clientService = ({ strapi }) => ({
|
|
|
22
24
|
limit: Number.MAX_SAFE_INTEGER,
|
|
23
25
|
populate: false
|
|
24
26
|
});
|
|
27
|
+
if (i18nEnabled) {
|
|
28
|
+
navigations = navigations.reduce((acc, navigation) => {
|
|
29
|
+
if (navigation.localeCode && locales?.includes(navigation.localeCode)) {
|
|
30
|
+
acc.push({
|
|
31
|
+
...navigation,
|
|
32
|
+
localizations: navigation.localizations?.filter(({ localeCode }) => localeCode && locales?.includes(localeCode)),
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
return acc;
|
|
36
|
+
}, []);
|
|
37
|
+
}
|
|
25
38
|
return navigations;
|
|
26
39
|
},
|
|
27
40
|
async render({ idOrSlug, type = utils_1.RENDER_TYPES.FLAT, menuOnly = false, rootPath = null, wrapRelated = false, locale, populate, }) {
|
|
@@ -223,6 +236,8 @@ const clientService = ({ strapi }) => ({
|
|
|
223
236
|
id: itemContentType.id,
|
|
224
237
|
attributes: { ...itemContentType }
|
|
225
238
|
} : itemContentType;
|
|
239
|
+
const pickMediaFields = (0, fp_1.pick)(["name", "url", "mime", "width", "height", "previewUrl"]);
|
|
240
|
+
const customFieldsDefinitions = additionalFields.filter(_ => typeof _ !== "string");
|
|
226
241
|
switch (type) {
|
|
227
242
|
case utils_1.RENDER_TYPES.TREE:
|
|
228
243
|
case utils_1.RENDER_TYPES.RFR:
|
|
@@ -235,6 +250,13 @@ const clientService = ({ strapi }) => ({
|
|
|
235
250
|
const slug = (0, lodash_1.isString)(parentPath) ? await commonService.getSlug(((0, lodash_1.first)(parentPath) === '/' ? parentPath.substring(1) : parentPath).replace(/\//g, '-')) : undefined;
|
|
236
251
|
const lastRelated = (0, lodash_1.isArray)(item.related) ? (0, lodash_1.last)(item.related) : item.related;
|
|
237
252
|
const relatedContentType = wrapContentType(lastRelated);
|
|
253
|
+
const customFields = enabledCustomFieldsNames.reduce((acc, field) => {
|
|
254
|
+
const mapper = customFieldsDefinitions.find(({ name }) => name === field)?.type === "media"
|
|
255
|
+
? (_) => pickMediaFields(JSON.parse(_))
|
|
256
|
+
: fp_1.identity;
|
|
257
|
+
const content = (0, lodash_1.get)(item, `additionalFields.${field}`);
|
|
258
|
+
return { ...acc, [field]: content ? mapper(content) : content };
|
|
259
|
+
}, {});
|
|
238
260
|
return {
|
|
239
261
|
id: item.id,
|
|
240
262
|
title: (0, utils_1.composeItemTitle)(item, contentTypesNameFields, contentTypes),
|
|
@@ -251,11 +273,11 @@ const clientService = ({ strapi }) => ({
|
|
|
251
273
|
},
|
|
252
274
|
audience: !(0, lodash_1.isEmpty)(item.audience) ? item.audience.map(({ key }) => key) : undefined,
|
|
253
275
|
items: isExternal ? undefined : await clientService.renderTree(items, item.id, field, parentPath, itemParser),
|
|
254
|
-
...
|
|
276
|
+
...customFields
|
|
255
277
|
};
|
|
256
278
|
};
|
|
257
279
|
const { items: itemsFilteredByPath, root: rootElement, } = (0, utils_1.filterByPath)(items, rootPath);
|
|
258
|
-
const treeStructure = await clientService.renderTree((0, lodash_1.isNil)(rootPath) ? items : itemsFilteredByPath, (0, lodash_1.get)(rootElement, 'parent.id'), 'parent', (0, lodash_1.get)(rootElement, 'parent.path'), itemParser);
|
|
280
|
+
const treeStructure = await clientService.renderTree((0, lodash_1.isNil)(rootPath) ? items : itemsFilteredByPath, (0, lodash_1.get)(rootElement, 'parent.id') ?? null, 'parent', (0, lodash_1.get)(rootElement, 'parent.path'), itemParser);
|
|
259
281
|
const filteredStructure = filter
|
|
260
282
|
? treeStructure.filter((item) => item.uiRouterKey === filter)
|
|
261
283
|
: treeStructure;
|
|
@@ -286,14 +308,23 @@ const clientService = ({ strapi }) => ({
|
|
|
286
308
|
return nestedOrders;
|
|
287
309
|
};
|
|
288
310
|
return result
|
|
289
|
-
.map(({ additionalFields, ...item }) =>
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
311
|
+
.map(({ additionalFields, ...item }) => {
|
|
312
|
+
const customFields = enabledCustomFieldsNames.reduce((acc, field) => {
|
|
313
|
+
const mapper = customFieldsDefinitions.find(({ name }) => name === field)?.type === "media"
|
|
314
|
+
? (_) => pickMediaFields(JSON.parse(_.toString()))
|
|
315
|
+
: fp_1.identity;
|
|
316
|
+
const content = (0, lodash_1.get)(additionalFields, field);
|
|
317
|
+
return { ...acc, [field]: content ? mapper(content) : content };
|
|
318
|
+
}, {});
|
|
319
|
+
return ({
|
|
320
|
+
...item,
|
|
321
|
+
audience: item.audience?.map(_ => (_).key),
|
|
322
|
+
title: (0, utils_1.composeItemTitle)({ ...item, additionalFields }, contentTypesNameFields, contentTypes) || '',
|
|
323
|
+
related: wrapContentType(item.related),
|
|
324
|
+
items: null,
|
|
325
|
+
...customFields,
|
|
326
|
+
});
|
|
327
|
+
})
|
|
297
328
|
.sort((a, b) => (0, utils_1.compareArraysOfNumbers)(getNestedOrders(a.id), getNestedOrders(b.id)));
|
|
298
329
|
}
|
|
299
330
|
}
|
|
@@ -10,6 +10,10 @@ const config_1 = require("../config");
|
|
|
10
10
|
const i18n_1 = require("../i18n");
|
|
11
11
|
const utils_2 = require("../utils");
|
|
12
12
|
const slugify_1 = __importDefault(require("@sindresorhus/slugify"));
|
|
13
|
+
const lifecycleHookListeners = {
|
|
14
|
+
navigation: {},
|
|
15
|
+
"navigation-item": {}
|
|
16
|
+
};
|
|
13
17
|
const commonService = ({ strapi }) => ({
|
|
14
18
|
analyzeBranch(items = [], masterEntity = null, parentItem = null, prevOperations = {}) {
|
|
15
19
|
const commonService = (0, utils_2.getPluginService)('common');
|
|
@@ -241,11 +245,7 @@ const commonService = ({ strapi }) => ({
|
|
|
241
245
|
const relatedData = data.get(item.id);
|
|
242
246
|
if (relatedData) {
|
|
243
247
|
return Object.assign(item, {
|
|
244
|
-
related:
|
|
245
|
-
...relatedData,
|
|
246
|
-
createdBy: (0, utils_2.purgeSensitiveData)(relatedData.createdBy),
|
|
247
|
-
updatedBy: (0, utils_2.purgeSensitiveData)(relatedData.updatedBy),
|
|
248
|
-
}
|
|
248
|
+
related: (0, utils_2.purgeSensitiveData)(relatedData),
|
|
249
249
|
});
|
|
250
250
|
}
|
|
251
251
|
return { ...item, related: null };
|
|
@@ -368,6 +368,18 @@ const commonService = ({ strapi }) => ({
|
|
|
368
368
|
}
|
|
369
369
|
return slug.toLowerCase();
|
|
370
370
|
},
|
|
371
|
+
registerLifecycleHook({ callback, contentTypeName, hookName }) {
|
|
372
|
+
if (!lifecycleHookListeners[contentTypeName][hookName]) {
|
|
373
|
+
lifecycleHookListeners[contentTypeName][hookName] = [];
|
|
374
|
+
}
|
|
375
|
+
lifecycleHookListeners[contentTypeName][hookName]?.push(callback);
|
|
376
|
+
},
|
|
377
|
+
async runLifecycleHook({ contentTypeName, event, hookName }) {
|
|
378
|
+
const hookListeners = lifecycleHookListeners[contentTypeName][hookName] ?? [];
|
|
379
|
+
for (const listener of hookListeners) {
|
|
380
|
+
await listener(event);
|
|
381
|
+
}
|
|
382
|
+
},
|
|
371
383
|
});
|
|
372
384
|
exports.default = commonService;
|
|
373
385
|
//# sourceMappingURL=common.js.map
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { LifeCycleHookName } from "../../types";
|
|
1
2
|
export declare const TEMPLATE_DEFAULT: "Generic";
|
|
2
3
|
export declare const MODEL_TYPES: {
|
|
3
4
|
readonly CONTENT_TYPE: "contentType";
|
|
@@ -21,4 +22,6 @@ export declare const RENDER_TYPES: Readonly<{
|
|
|
21
22
|
TREE: "TREE";
|
|
22
23
|
RFR: "RFR";
|
|
23
24
|
}>;
|
|
25
|
+
export type ContentType = "navigation" | "navigation-item";
|
|
26
|
+
export declare const allLifecycleHooks: ReadonlyArray<LifeCycleHookName>;
|
|
24
27
|
//# sourceMappingURL=constant.d.ts.map
|
package/server/utils/constant.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.RENDER_TYPES = exports.DEFAULT_NAVIGATION_ITEM = exports.DEFAULT_POPULATE = exports.CONTENT_TYPES_NAME_FIELDS_DEFAULTS = exports.EXCLUDED_CONTENT_TYPES = exports.RESTRICTED_CONTENT_TYPES = exports.ALLOWED_CONTENT_TYPES = exports.KIND_TYPES = exports.MODEL_TYPES = exports.TEMPLATE_DEFAULT = void 0;
|
|
3
|
+
exports.allLifecycleHooks = exports.RENDER_TYPES = exports.DEFAULT_NAVIGATION_ITEM = exports.DEFAULT_POPULATE = exports.CONTENT_TYPES_NAME_FIELDS_DEFAULTS = exports.EXCLUDED_CONTENT_TYPES = exports.RESTRICTED_CONTENT_TYPES = exports.ALLOWED_CONTENT_TYPES = exports.KIND_TYPES = exports.MODEL_TYPES = exports.TEMPLATE_DEFAULT = void 0;
|
|
4
4
|
const i18n_1 = require("../i18n");
|
|
5
5
|
exports.TEMPLATE_DEFAULT = 'Generic';
|
|
6
6
|
exports.MODEL_TYPES = { CONTENT_TYPE: 'contentType' };
|
|
@@ -20,4 +20,24 @@ exports.RENDER_TYPES = {
|
|
|
20
20
|
TREE: 'TREE',
|
|
21
21
|
RFR: 'RFR'
|
|
22
22
|
};
|
|
23
|
+
exports.allLifecycleHooks = [
|
|
24
|
+
"beforeCreate",
|
|
25
|
+
"beforeCreateMany",
|
|
26
|
+
"afterCreate",
|
|
27
|
+
"afterCreateMany",
|
|
28
|
+
"beforeUpdate",
|
|
29
|
+
"beforeUpdateMany",
|
|
30
|
+
"afterUpdate",
|
|
31
|
+
"afterUpdateMany",
|
|
32
|
+
"beforeDelete",
|
|
33
|
+
"beforeDeleteMany",
|
|
34
|
+
"afterDelete",
|
|
35
|
+
"afterDeleteMany",
|
|
36
|
+
"beforeCount",
|
|
37
|
+
"afterCount",
|
|
38
|
+
"beforeFindOne",
|
|
39
|
+
"afterFindOne",
|
|
40
|
+
"beforeFindMany",
|
|
41
|
+
"afterFindMany",
|
|
42
|
+
];
|
|
23
43
|
//# sourceMappingURL=constant.js.map
|
|
@@ -1,8 +1,15 @@
|
|
|
1
|
-
import { PopulateClause } from 'strapi-typed';
|
|
1
|
+
import { PopulateClause, StrapiContext } from 'strapi-typed';
|
|
2
2
|
import { Id, IStrapi, Primitive, StrapiContentType, StringMap, StrapiContentTypeFullSchema } from "strapi-typed";
|
|
3
|
-
import { AuditLogContext, AuditLogParams, ContentTypeEntity, NavigationActions, NavigationItem, NavigationItemAdditionalField, NavigationItemCustomField, NavigationItemEntity,
|
|
3
|
+
import { AuditLogContext, AuditLogParams, ContentTypeEntity, Effect, IAdminService, IClientService, ICommonService, LifeCycleEvent, LifeCycleHookName, NavigationActions, NavigationItem, NavigationItemAdditionalField, NavigationItemCustomField, NavigationItemEntity, NavigationServiceName, NestedPath, NestedStructure, PluginConfigNameFields, PopulateQueryParam, ToBeFixed } from "../../types";
|
|
4
4
|
import { NavigationError } from '../../utils/NavigationError';
|
|
5
|
-
|
|
5
|
+
import { ContentType } from './constant';
|
|
6
|
+
type Populate = string | undefined | boolean | Array<Populate> | Record<string, string | boolean | undefined>;
|
|
7
|
+
type TypeMap = {
|
|
8
|
+
client: IClientService;
|
|
9
|
+
admin: IAdminService;
|
|
10
|
+
common: ICommonService;
|
|
11
|
+
};
|
|
12
|
+
export declare function getPluginService<T extends NavigationServiceName>(name: T): T extends infer R extends NavigationServiceName ? TypeMap[R] : never;
|
|
6
13
|
export declare const errorHandler: (ctx: ToBeFixed) => (error: NavigationError | string) => any;
|
|
7
14
|
export declare const getCustomFields: (additionalFields: NavigationItemAdditionalField[]) => NavigationItemCustomField[];
|
|
8
15
|
export declare const parseParams: <TParams extends StringMap<string> = StringMap<string>, TResult extends StringMap<Primitive> = StringMap<Primitive>>(params: TParams) => TResult;
|
|
@@ -136,6 +143,11 @@ export declare const compareArraysOfNumbers: (arrA: number[], arrB: number[]) =>
|
|
|
136
143
|
export declare const getPluginModels: () => Record<'masterModel' | 'itemModel' | 'relatedModel' | 'audienceModel', StrapiContentTypeFullSchema>;
|
|
137
144
|
export declare const validateAdditionalFields: (additionalFields: NavigationItemAdditionalField[]) => void;
|
|
138
145
|
export declare const parsePopulateQuery: (populate: PopulateQueryParam) => PopulateClause;
|
|
139
|
-
export declare const purgeSensitiveData: (data
|
|
146
|
+
export declare const purgeSensitiveData: (data: ToBeFixed) => ToBeFixed;
|
|
147
|
+
export declare const purgeSensitiveDataFromUser: (data?: any) => {} | undefined;
|
|
140
148
|
export declare const resolveGlobalLikeId: (uid?: string) => string;
|
|
149
|
+
export declare const sanitizePopulateField: (populate: Populate) => Populate;
|
|
150
|
+
export declare const buildHookListener: (contentTypeName: ContentType, { strapi }: StrapiContext) => (hookName: LifeCycleHookName) => [LifeCycleHookName, Effect<LifeCycleEvent>];
|
|
151
|
+
export declare const buildAllHookListeners: (contentTypeName: ContentType, context: StrapiContext) => Record<LifeCycleHookName, Effect<LifeCycleEvent>>;
|
|
152
|
+
export {};
|
|
141
153
|
//# sourceMappingURL=functions.d.ts.map
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.resolveGlobalLikeId = exports.purgeSensitiveData = exports.parsePopulateQuery = exports.validateAdditionalFields = exports.getPluginModels = exports.compareArraysOfNumbers = exports.intercalate = exports.isContentTypeEligible = exports.filterByPath = exports.buildNestedPaths = exports.buildNestedStructure = exports.singularize = exports.checkDuplicatePath = exports.filterOutUnpublished = exports.extractItemRelationTitle = exports.composeItemTitle = exports.sendAuditLog = exports.prepareAuditLog = exports.getTemplateComponentFromTemplate = exports.templateNameFactory = exports.parseParams = exports.getCustomFields = exports.errorHandler = exports.getPluginService = void 0;
|
|
3
|
+
exports.buildAllHookListeners = exports.buildHookListener = exports.sanitizePopulateField = exports.resolveGlobalLikeId = exports.purgeSensitiveDataFromUser = exports.purgeSensitiveData = exports.parsePopulateQuery = exports.validateAdditionalFields = exports.getPluginModels = exports.compareArraysOfNumbers = exports.intercalate = exports.isContentTypeEligible = exports.filterByPath = exports.buildNestedPaths = exports.buildNestedStructure = exports.singularize = exports.checkDuplicatePath = exports.filterOutUnpublished = exports.extractItemRelationTitle = exports.composeItemTitle = exports.sendAuditLog = exports.prepareAuditLog = exports.getTemplateComponentFromTemplate = exports.templateNameFactory = exports.parseParams = exports.getCustomFields = exports.errorHandler = exports.getPluginService = void 0;
|
|
4
4
|
const lodash_1 = require("lodash");
|
|
5
5
|
const types_1 = require("../../types");
|
|
6
6
|
const NavigationError_1 = require("../../utils/NavigationError");
|
|
7
7
|
const constant_1 = require("./constant");
|
|
8
8
|
const UID_REGEX = /^(?<type>[a-z0-9-]+)\:{2}(?<api>[a-z0-9-]+)\.{1}(?<contentType>[a-z0-9-]+)$/i;
|
|
9
|
-
|
|
9
|
+
function getPluginService(name) {
|
|
10
|
+
return strapi.plugin("navigation").service(name);
|
|
11
|
+
}
|
|
10
12
|
exports.getPluginService = getPluginService;
|
|
11
13
|
const errorHandler = (ctx) => (error) => {
|
|
12
14
|
if (error instanceof NavigationError_1.NavigationError) {
|
|
@@ -184,7 +186,7 @@ const buildNestedPaths = (items, id = null, parentPath = null) => {
|
|
|
184
186
|
{
|
|
185
187
|
id: entity.id,
|
|
186
188
|
parent: parentPath ? {
|
|
187
|
-
id: (0, lodash_1.get)(entity, 'parent
|
|
189
|
+
id: (0, lodash_1.get)(entity, ['parent', 'id']),
|
|
188
190
|
path: parentPath,
|
|
189
191
|
} : undefined,
|
|
190
192
|
path,
|
|
@@ -262,20 +264,34 @@ const parsePopulateQuery = (populate) => {
|
|
|
262
264
|
}
|
|
263
265
|
};
|
|
264
266
|
exports.parsePopulateQuery = parsePopulateQuery;
|
|
265
|
-
const purgeSensitiveData = (data
|
|
267
|
+
const purgeSensitiveData = (data) => {
|
|
268
|
+
if (!data || !(typeof data === "object") || !Object.keys(data).length) {
|
|
269
|
+
return data;
|
|
270
|
+
}
|
|
271
|
+
const { createdBy = undefined, updatedBy = undefined, ...rest } = data;
|
|
272
|
+
if (!createdBy && !updatedBy) {
|
|
273
|
+
return data;
|
|
274
|
+
}
|
|
275
|
+
return {
|
|
276
|
+
...Object.fromEntries(Object.entries(rest).map(([key, value]) => [key, (0, exports.purgeSensitiveData)(value)])),
|
|
277
|
+
...(createdBy ? { createdBy: (0, exports.purgeSensitiveDataFromUser)(createdBy) } : {}),
|
|
278
|
+
...(updatedBy ? { updatedBy: (0, exports.purgeSensitiveDataFromUser)(updatedBy) } : {}),
|
|
279
|
+
};
|
|
280
|
+
};
|
|
281
|
+
exports.purgeSensitiveData = purgeSensitiveData;
|
|
282
|
+
const purgeSensitiveDataFromUser = (data = {}) => {
|
|
266
283
|
if (!data) {
|
|
267
284
|
return undefined;
|
|
268
285
|
}
|
|
269
|
-
const
|
|
286
|
+
const allowedFields = ['username', 'firstname', 'lastname', 'email'];
|
|
270
287
|
return Object.keys(data)
|
|
271
|
-
.filter((key) =>
|
|
272
|
-
(0, lodash_1.isEmpty)(forbiddenFields.filter(_ => key.toLowerCase().includes(_))))
|
|
288
|
+
.filter((key) => allowedFields.includes(key.toLowerCase()))
|
|
273
289
|
.reduce((prev, curr) => ({
|
|
274
290
|
...prev,
|
|
275
291
|
[curr]: data[curr],
|
|
276
292
|
}), {});
|
|
277
293
|
};
|
|
278
|
-
exports.
|
|
294
|
+
exports.purgeSensitiveDataFromUser = purgeSensitiveDataFromUser;
|
|
279
295
|
const resolveGlobalLikeId = (uid = '') => {
|
|
280
296
|
const parse = (str) => str.split('-')
|
|
281
297
|
.map(_ => (0, lodash_1.capitalize)(_))
|
|
@@ -290,4 +306,34 @@ exports.resolveGlobalLikeId = resolveGlobalLikeId;
|
|
|
290
306
|
const splitTypeUid = (uid = '') => {
|
|
291
307
|
return uid.split(UID_REGEX).filter((s) => s && s.length > 0);
|
|
292
308
|
};
|
|
309
|
+
const sanitizePopulateField = (populate) => {
|
|
310
|
+
if (!populate || populate === true || populate === "*") {
|
|
311
|
+
return undefined;
|
|
312
|
+
}
|
|
313
|
+
if (Array.isArray(populate)) {
|
|
314
|
+
return populate
|
|
315
|
+
.map((item) => (0, exports.sanitizePopulateField)(item));
|
|
316
|
+
}
|
|
317
|
+
if ("object" === typeof populate) {
|
|
318
|
+
return Object.fromEntries(Object.entries(populate).map(([key, value]) => [key, (0, exports.sanitizePopulateField)(value)]));
|
|
319
|
+
}
|
|
320
|
+
return populate;
|
|
321
|
+
};
|
|
322
|
+
exports.sanitizePopulateField = sanitizePopulateField;
|
|
323
|
+
const buildHookListener = (contentTypeName, { strapi }) => (hookName) => [
|
|
324
|
+
hookName,
|
|
325
|
+
async (event) => {
|
|
326
|
+
const commonService = strapi
|
|
327
|
+
.plugin("navigation")
|
|
328
|
+
.service("common");
|
|
329
|
+
await commonService.runLifecycleHook({
|
|
330
|
+
contentTypeName,
|
|
331
|
+
hookName,
|
|
332
|
+
event,
|
|
333
|
+
});
|
|
334
|
+
},
|
|
335
|
+
];
|
|
336
|
+
exports.buildHookListener = buildHookListener;
|
|
337
|
+
const buildAllHookListeners = (contentTypeName, context) => Object.fromEntries(constant_1.allLifecycleHooks.map((0, exports.buildHookListener)(contentTypeName, context)));
|
|
338
|
+
exports.buildAllHookListeners = buildAllHookListeners;
|
|
293
339
|
//# sourceMappingURL=functions.js.map
|
package/strapi-server.d.ts
CHANGED
|
@@ -82,6 +82,7 @@ declare const _default: () => {
|
|
|
82
82
|
};
|
|
83
83
|
};
|
|
84
84
|
};
|
|
85
|
+
lifecycles: Record<import("./types").LifeCycleHookName, import("./types").Effect<import("./types").LifeCycleEvent<import("./types").LifeCycleHookName, unknown, Record<string, unknown>>>>;
|
|
85
86
|
};
|
|
86
87
|
"navigation-item": {
|
|
87
88
|
schema: {
|
|
@@ -185,6 +186,7 @@ declare const _default: () => {
|
|
|
185
186
|
};
|
|
186
187
|
};
|
|
187
188
|
};
|
|
189
|
+
lifecycles: Record<import("./types").LifeCycleHookName, import("./types").Effect<import("./types").LifeCycleEvent<import("./types").LifeCycleHookName, unknown, Record<string, unknown>>>>;
|
|
188
190
|
};
|
|
189
191
|
"navigations-items-related": {
|
|
190
192
|
schema: {
|