strapi-plugin-comments 2.2.17 → 2.3.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.
- package/README.md +46 -0
- package/admin/src/components/Wysiwyg/utils/continueList.js +1 -2
- package/admin/src/custom-fields/comments/components/input/utils.d.ts +1 -1
- package/admin/src/custom-fields/comments/components/input/utils.js +2 -2
- package/admin/src/pages/App/index.d.ts +2 -3
- package/admin/src/pages/App/index.js +1 -2
- package/admin/src/pages/Details/index.d.ts +2 -2
- package/admin/src/pages/Details/index.js +1 -2
- package/admin/src/pages/Discover/index.d.ts +2 -2
- package/admin/src/pages/Discover/index.js +1 -2
- package/admin/src/pages/Reports/index.d.ts +2 -2
- package/admin/src/utils/functions.js +1 -2
- package/content-types/index.d.ts +2 -0
- package/content-types/index.js +7 -0
- package/package.json +4 -4
- package/server/controllers/client.js +6 -3
- package/server/controllers/utils/parsers.d.ts +1 -0
- package/server/controllers/utils/parsers.js +2 -1
- package/server/index.d.ts +1 -1
- package/server/services/admin.js +3 -3
- package/server/services/common.js +31 -11
- package/server/utils/constants.d.ts +2 -0
- package/server/utils/constants.js +21 -1
- package/server/utils/functions.d.ts +5 -1
- package/server/utils/functions.js +18 -1
- package/server/utils/types.d.ts +23 -0
- package/server/utils/types.js +3 -0
- package/strapi-server.d.ts +7 -5
- package/tsconfig.tsbuildinfo +1 -1
- package/types/utils.js +1 -2
package/README.md
CHANGED
|
@@ -372,6 +372,12 @@ Return a flat structure of comments by specified Author for example `Author` wit
|
|
|
372
372
|
**Example URL**: `https://localhost:1337/api/comments/author/1` - get comments by `ID:1` of Strapi User
|
|
373
373
|
**Example URL**: `https://localhost:1337/api/comments/author/1/generic` - get comments by `ID:1` of Generic User
|
|
374
374
|
|
|
375
|
+
#### Skipping fields
|
|
376
|
+
|
|
377
|
+
To skip a field from the response you can use a query param called `omit`. It is a list of `Comment` entity fields you want to ignore. For example `?omit[]=author&omit[]=related`.
|
|
378
|
+
|
|
379
|
+
**Remember!** `id` field is required so it will not be skipped.
|
|
380
|
+
|
|
375
381
|
**Example response body**
|
|
376
382
|
|
|
377
383
|
```json
|
|
@@ -931,6 +937,46 @@ For developers who upgrades their Strapi instance custom field from Comments plu
|
|
|
931
937
|
|
|
932
938
|
Read more about this feature in [Strapi's docs](https://docs-next.strapi.io/user-docs/latest/plugins/introduction-to-plugins.html#custom-fields).
|
|
933
939
|
|
|
940
|
+
## Model lifecycle hooks
|
|
941
|
+
|
|
942
|
+
Comments plugin allows to register lifecycle hooks for `Comment` and `Comment report` content types.
|
|
943
|
+
|
|
944
|
+
You can read more about lifecycle hooks [here](https://docs.strapi.io/dev-docs/backend-customization/models#lifecycle-hooks). (You can set a listener for all of the hooks).
|
|
945
|
+
|
|
946
|
+
Lifecycle hooks can be register either in `register()` or `bootstrap()` methods of your server. You can register more than one listener for a specified lifecycle hook. For example: you want to do three things on report creation and do not want to handle all of these actions in one big function. You can split logic in as many listeners as you want.
|
|
947
|
+
|
|
948
|
+
Listeners can by sync and `async`.
|
|
949
|
+
|
|
950
|
+
>Be aware that lifecycle hooks registered in `register()` may be fired by plugin's bootstrapping. If you want listen to events triggered after server's startup use `bootstrap()`.
|
|
951
|
+
|
|
952
|
+
Example:
|
|
953
|
+
|
|
954
|
+
```ts
|
|
955
|
+
const commentsCommonService = strapi
|
|
956
|
+
.plugin("comments")
|
|
957
|
+
.service("common");
|
|
958
|
+
|
|
959
|
+
commentsCommonService.registerLifecycleHook({
|
|
960
|
+
callback: async ({ action, result }) => {
|
|
961
|
+
const saveResult = await logIntoSystem(action, result);
|
|
962
|
+
|
|
963
|
+
console.log(saveResult);
|
|
964
|
+
},
|
|
965
|
+
contentTypeName: "comment",
|
|
966
|
+
hookName: "afterCreate",
|
|
967
|
+
});
|
|
968
|
+
|
|
969
|
+
commentsCommonService.registerLifecycleHook({
|
|
970
|
+
callback: async ({ action, result }) => {
|
|
971
|
+
const saveResult = await logIntoSystem(action, result);
|
|
972
|
+
|
|
973
|
+
console.log(saveResult);
|
|
974
|
+
},
|
|
975
|
+
contentTypeName: "report",
|
|
976
|
+
hookName: "afterCreate",
|
|
977
|
+
});
|
|
978
|
+
```
|
|
979
|
+
|
|
934
980
|
## 🤝 Contributing
|
|
935
981
|
|
|
936
982
|
<div>
|
|
@@ -3,7 +3,7 @@ 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.newlineAndIndentContinueMarkdownList =
|
|
6
|
+
exports.newlineAndIndentContinueMarkdownList = newlineAndIndentContinueMarkdownList;
|
|
7
7
|
const codemirror5_1 = __importDefault(require("codemirror5"));
|
|
8
8
|
var listRE = /^(\s*)(>[> ]*|[*+-] \[[x ]\]\s|[*+-]\s|(\d+)([.)]))(\s*)/, emptyListRE = /^(\s*)(>[> ]*|[*+-] \[[x ]\]|[*+-]|(\d+)[.)])(\s*)$/, unorderedListRE = /[*+-]\s/;
|
|
9
9
|
function newlineAndIndentContinueMarkdownList(cm) {
|
|
@@ -45,7 +45,6 @@ function newlineAndIndentContinueMarkdownList(cm) {
|
|
|
45
45
|
}
|
|
46
46
|
cm.replaceSelections(replacements);
|
|
47
47
|
}
|
|
48
|
-
exports.newlineAndIndentContinueMarkdownList = newlineAndIndentContinueMarkdownList;
|
|
49
48
|
function incrementRemainingMarkdownListNumbers(cm, pos) {
|
|
50
49
|
var startLine = pos.line, lookAhead = 0, skipCount = 0;
|
|
51
50
|
var startItem = listRE.exec(cm.getLine(startLine)), startIndent = startItem[1];
|
|
@@ -5,7 +5,7 @@ export declare const asString: () => string;
|
|
|
5
5
|
export declare const fromInput: (value: unknown) => CommentsFieldValue;
|
|
6
6
|
export declare const toOutput: (state: CommentsFieldValue) => string;
|
|
7
7
|
export declare function assertCorrectState(state: any): asserts state is CommentsFieldValue;
|
|
8
|
-
export declare const handleStateSliceChange: (key: keyof CommentsFieldValue, setState: Dispatch<SetStateAction<CommentsFieldValue>>) => (value:
|
|
8
|
+
export declare const handleStateSliceChange: (key: keyof CommentsFieldValue, setState: Dispatch<SetStateAction<CommentsFieldValue>>) => (value: CommentsFieldValue[typeof key]) => void;
|
|
9
9
|
export declare const handlePopulateChange: (key: PopulateField, setState: Dispatch<SetStateAction<CommentsFieldValue>>) => () => void;
|
|
10
10
|
export declare const getRenderTypeOptions: (translate: typeof getMessage) => {
|
|
11
11
|
value: string;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getApprovalStatusOptions = exports.getFilterByOptions = exports.getSortByDateOptions = exports.getRenderTypeOptions = exports.handlePopulateChange = exports.handleStateSliceChange = exports.
|
|
3
|
+
exports.getApprovalStatusOptions = exports.getFilterByOptions = exports.getSortByDateOptions = exports.getRenderTypeOptions = exports.handlePopulateChange = exports.handleStateSliceChange = exports.toOutput = exports.fromInput = exports.asString = void 0;
|
|
4
|
+
exports.assertCorrectState = assertCorrectState;
|
|
4
5
|
const lodash_1 = require("lodash");
|
|
5
6
|
const utils_1 = require("../../../../utils");
|
|
6
7
|
const consts_1 = require("./consts");
|
|
@@ -37,7 +38,6 @@ function assertCorrectState(state) {
|
|
|
37
38
|
}
|
|
38
39
|
});
|
|
39
40
|
}
|
|
40
|
-
exports.assertCorrectState = assertCorrectState;
|
|
41
41
|
const handleStateSliceChange = (key, setState) => (value) => {
|
|
42
42
|
return setState((current) => ({
|
|
43
43
|
...current,
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import React from "react";
|
|
2
1
|
export declare function mapDispatchToProps(dispatch: any): {
|
|
3
2
|
setConfig: (data: any) => {
|
|
4
3
|
data: any;
|
|
@@ -9,8 +8,8 @@ declare const _default: import("react-redux").ConnectedComponent<({ setConfig }:
|
|
|
9
8
|
setConfig: any;
|
|
10
9
|
}) => JSX.Element, {
|
|
11
10
|
setConfig: any;
|
|
12
|
-
context?:
|
|
13
|
-
store?: import("redux").Store
|
|
11
|
+
context?: import("react-redux/es/components/Context").ReactReduxContextInstance | undefined;
|
|
12
|
+
store?: import("redux").Store | undefined;
|
|
14
13
|
}>;
|
|
15
14
|
export default _default;
|
|
16
15
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -3,7 +3,7 @@ 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.mapDispatchToProps =
|
|
6
|
+
exports.mapDispatchToProps = mapDispatchToProps;
|
|
7
7
|
const react_1 = __importDefault(require("react"));
|
|
8
8
|
const react_redux_1 = require("react-redux");
|
|
9
9
|
const redux_1 = require("redux");
|
|
@@ -42,7 +42,6 @@ const mapStateToProps = (0, selectors_1.default)();
|
|
|
42
42
|
function mapDispatchToProps(dispatch) {
|
|
43
43
|
return (0, redux_1.bindActionCreators)({ setConfig: actions_1.setConfig }, dispatch);
|
|
44
44
|
}
|
|
45
|
-
exports.mapDispatchToProps = mapDispatchToProps;
|
|
46
45
|
const withConnect = (0, react_redux_1.connect)(mapStateToProps, mapDispatchToProps);
|
|
47
46
|
exports.default = (0, redux_1.compose)(withConnect)(App);
|
|
48
47
|
//# sourceMappingURL=index.js.map
|
|
@@ -4,8 +4,8 @@ declare const _default: import("react-redux").ConnectedComponent<React.MemoExoti
|
|
|
4
4
|
config: any;
|
|
5
5
|
}) => JSX.Element | null>, {
|
|
6
6
|
config: any;
|
|
7
|
-
context?:
|
|
8
|
-
store?: import("redux").Store
|
|
7
|
+
context?: import("react-redux/es/components/Context").ReactReduxContextInstance | undefined;
|
|
8
|
+
store?: import("redux").Store | undefined;
|
|
9
9
|
}>;
|
|
10
10
|
export default _default;
|
|
11
11
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -26,7 +26,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
26
26
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
27
|
};
|
|
28
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
-
exports.mapDispatchToProps =
|
|
29
|
+
exports.mapDispatchToProps = mapDispatchToProps;
|
|
30
30
|
const react_1 = __importStar(require("react"));
|
|
31
31
|
const react_redux_1 = require("react-redux");
|
|
32
32
|
const redux_1 = require("redux");
|
|
@@ -95,7 +95,6 @@ const mapStateToProps = (0, selectors_1.default)();
|
|
|
95
95
|
function mapDispatchToProps(dispatch) {
|
|
96
96
|
return (0, redux_1.bindActionCreators)({}, dispatch);
|
|
97
97
|
}
|
|
98
|
-
exports.mapDispatchToProps = mapDispatchToProps;
|
|
99
98
|
const withConnect = (0, react_redux_1.connect)(mapStateToProps, mapDispatchToProps);
|
|
100
99
|
exports.default = (0, redux_1.compose)(withConnect)((0, react_1.memo)(Details, react_fast_compare_1.default));
|
|
101
100
|
//# sourceMappingURL=index.js.map
|
|
@@ -4,8 +4,8 @@ declare const _default: import("react-redux").ConnectedComponent<React.MemoExoti
|
|
|
4
4
|
config: any;
|
|
5
5
|
}) => JSX.Element>, {
|
|
6
6
|
config: any;
|
|
7
|
-
context?:
|
|
8
|
-
store?: import("redux").Store
|
|
7
|
+
context?: import("react-redux/es/components/Context").ReactReduxContextInstance | undefined;
|
|
8
|
+
store?: import("redux").Store | undefined;
|
|
9
9
|
}>;
|
|
10
10
|
export default _default;
|
|
11
11
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -26,7 +26,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
26
26
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
27
|
};
|
|
28
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
-
exports.mapDispatchToProps =
|
|
29
|
+
exports.mapDispatchToProps = mapDispatchToProps;
|
|
30
30
|
const react_1 = __importStar(require("react"));
|
|
31
31
|
const react_redux_1 = require("react-redux");
|
|
32
32
|
const redux_1 = require("redux");
|
|
@@ -127,7 +127,6 @@ const mapStateToProps = (0, selectors_1.default)();
|
|
|
127
127
|
function mapDispatchToProps(dispatch) {
|
|
128
128
|
return (0, redux_1.bindActionCreators)({}, dispatch);
|
|
129
129
|
}
|
|
130
|
-
exports.mapDispatchToProps = mapDispatchToProps;
|
|
131
130
|
const withConnect = (0, react_redux_1.connect)(mapStateToProps, mapDispatchToProps);
|
|
132
131
|
exports.default = (0, redux_1.compose)(withConnect)((0, react_1.memo)(Discover, react_fast_compare_1.default));
|
|
133
132
|
//# sourceMappingURL=index.js.map
|
|
@@ -4,8 +4,8 @@ declare const _default: import("react-redux").ConnectedComponent<React.MemoExoti
|
|
|
4
4
|
config: any;
|
|
5
5
|
}) => JSX.Element>, {
|
|
6
6
|
config: any;
|
|
7
|
-
context?:
|
|
8
|
-
store?: import("redux").Store
|
|
7
|
+
context?: import("react-redux/es/components/Context").ReactReduxContextInstance | undefined;
|
|
8
|
+
store?: import("redux").Store | undefined;
|
|
9
9
|
}>;
|
|
10
10
|
export default _default;
|
|
11
11
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.assertString =
|
|
3
|
+
exports.assertString = assertString;
|
|
4
4
|
const errors_1 = require("./errors");
|
|
5
5
|
function assertString(value) {
|
|
6
6
|
if (typeof value !== "string") {
|
|
7
7
|
throw new errors_1.ValidationError(`String expected, but "${typeof value}" given`);
|
|
8
8
|
}
|
|
9
9
|
}
|
|
10
|
-
exports.assertString = assertString;
|
|
11
10
|
//# sourceMappingURL=functions.js.map
|
package/content-types/index.d.ts
CHANGED
|
@@ -93,6 +93,7 @@ declare const _default: {
|
|
|
93
93
|
};
|
|
94
94
|
};
|
|
95
95
|
};
|
|
96
|
+
lifecycles: Record<import("../server/utils/types").LifeCycleHookName, import("../types/utils").Effect<import("../server/utils/types").LifeCycleEvent<import("../server/utils/types").LifeCycleHookName, unknown, Record<string, unknown>>>>;
|
|
96
97
|
};
|
|
97
98
|
"comment-report": {
|
|
98
99
|
schema: {
|
|
@@ -141,6 +142,7 @@ declare const _default: {
|
|
|
141
142
|
};
|
|
142
143
|
};
|
|
143
144
|
};
|
|
145
|
+
lifecycles: Record<import("../server/utils/types").LifeCycleHookName, import("../types/utils").Effect<import("../server/utils/types").LifeCycleEvent<import("../server/utils/types").LifeCycleHookName, unknown, Record<string, unknown>>>>;
|
|
144
146
|
};
|
|
145
147
|
};
|
|
146
148
|
export default _default;
|
package/content-types/index.js
CHANGED
|
@@ -3,14 +3,21 @@ 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
|
+
const functions_1 = require("../server/utils/functions");
|
|
6
7
|
const comment_1 = __importDefault(require("./comment"));
|
|
7
8
|
const report_1 = __importDefault(require("./report"));
|
|
8
9
|
exports.default = {
|
|
9
10
|
comment: {
|
|
10
11
|
schema: comment_1.default,
|
|
12
|
+
lifecycles: (0, functions_1.buildAllHookListeners)("comment", {
|
|
13
|
+
strapi,
|
|
14
|
+
}),
|
|
11
15
|
},
|
|
12
16
|
"comment-report": {
|
|
13
17
|
schema: report_1.default,
|
|
18
|
+
lifecycles: (0, functions_1.buildAllHookListeners)("comment-report", {
|
|
19
|
+
strapi,
|
|
20
|
+
}),
|
|
14
21
|
},
|
|
15
22
|
};
|
|
16
23
|
//# sourceMappingURL=index.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "strapi-plugin-comments",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.3.1",
|
|
4
4
|
"description": "Strapi - Comments plugin",
|
|
5
5
|
"strapi": {
|
|
6
6
|
"name": "comments",
|
|
@@ -15,9 +15,9 @@
|
|
|
15
15
|
},
|
|
16
16
|
"dependencies": {
|
|
17
17
|
"@strapi/design-system": "1.18.0",
|
|
18
|
-
"@strapi/plugin-graphql": "^4.
|
|
19
|
-
"@strapi/utils": "^4.
|
|
20
|
-
"@strapi/types": "4.
|
|
18
|
+
"@strapi/plugin-graphql": "^4.25.8",
|
|
19
|
+
"@strapi/utils": "^4.25.8",
|
|
20
|
+
"@strapi/types": "4.25.8",
|
|
21
21
|
"no-profanity": "^1.4.2",
|
|
22
22
|
"styled-components": "^5.3.8",
|
|
23
23
|
"match-sorter": "^4.0.2",
|
|
@@ -15,7 +15,7 @@ const controllers = {
|
|
|
15
15
|
async findAllFlat(ctx) {
|
|
16
16
|
const { params = {}, query, sort, pagination } = ctx;
|
|
17
17
|
const { relation } = (0, functions_2.parseParams)(params);
|
|
18
|
-
const { sort: querySort, pagination: queryPagination, fields, ...filterQuery } = query || {};
|
|
18
|
+
const { sort: querySort, pagination: queryPagination, fields, omit = [], ...filterQuery } = query || {};
|
|
19
19
|
try {
|
|
20
20
|
(0, functions_1.assertParamsPresent)(params, ["relation"]);
|
|
21
21
|
return this.getService("common").findAllFlat((0, parsers_1.flatInput)({
|
|
@@ -24,6 +24,7 @@ const controllers = {
|
|
|
24
24
|
sort: sort || querySort,
|
|
25
25
|
pagination: pagination || queryPagination,
|
|
26
26
|
fields,
|
|
27
|
+
omit,
|
|
27
28
|
}));
|
|
28
29
|
}
|
|
29
30
|
catch (e) {
|
|
@@ -33,7 +34,7 @@ const controllers = {
|
|
|
33
34
|
async findAllInHierarchy(ctx) {
|
|
34
35
|
const { params, query, sort } = ctx;
|
|
35
36
|
const { relation } = (0, functions_2.parseParams)(params);
|
|
36
|
-
const { sort: querySort, fields, ...filterQuery } = query || {};
|
|
37
|
+
const { sort: querySort, fields, omit, ...filterQuery } = query || {};
|
|
37
38
|
try {
|
|
38
39
|
(0, functions_1.assertParamsPresent)(params, ["relation"]);
|
|
39
40
|
return await this.getService("common").findAllInHierarchy({
|
|
@@ -42,6 +43,7 @@ const controllers = {
|
|
|
42
43
|
query: filterQuery,
|
|
43
44
|
sort: sort || querySort,
|
|
44
45
|
fields,
|
|
46
|
+
omit,
|
|
45
47
|
}),
|
|
46
48
|
dropBlockedThreads: true,
|
|
47
49
|
});
|
|
@@ -53,7 +55,7 @@ const controllers = {
|
|
|
53
55
|
async findAllPerAuthor(ctx) {
|
|
54
56
|
const { params = {}, query, sort, pagination } = ctx;
|
|
55
57
|
const { id, type } = (0, functions_2.parseParams)(params);
|
|
56
|
-
const { sort: querySort, pagination: queryPagination, fields, ...filterQuery } = query || {};
|
|
58
|
+
const { sort: querySort, pagination: queryPagination, fields, omit = [], ...filterQuery } = query || {};
|
|
57
59
|
try {
|
|
58
60
|
(0, functions_1.assertParamsPresent)(params, ["id"]);
|
|
59
61
|
return this.getService("common").findAllPerAuthor((0, parsers_1.flatInput)({
|
|
@@ -61,6 +63,7 @@ const controllers = {
|
|
|
61
63
|
sort: sort || querySort,
|
|
62
64
|
pagination: pagination || queryPagination,
|
|
63
65
|
fields,
|
|
66
|
+
omit,
|
|
64
67
|
}), id, ![constants_1.AUTHOR_TYPE.GENERIC.toLowerCase(), constants_1.AUTHOR_TYPE.GENERIC].includes(type));
|
|
65
68
|
}
|
|
66
69
|
catch (e) {
|
|
@@ -6,5 +6,6 @@ export declare const flatInput: <T, TKeys = keyof T>(payload: FlatInput<OnlyStri
|
|
|
6
6
|
pagination: any;
|
|
7
7
|
sort: any;
|
|
8
8
|
fields: import("strapi-typed").StrapiRequestQueryFieldsClause<OnlyStrings<TKeys>> | undefined;
|
|
9
|
+
omit: string[] | undefined;
|
|
9
10
|
};
|
|
10
11
|
//# sourceMappingURL=parsers.d.ts.map
|
|
@@ -7,7 +7,7 @@ exports.flatInput = void 0;
|
|
|
7
7
|
const error_1 = __importDefault(require("../../utils/error"));
|
|
8
8
|
const functions_1 = require("../../utils/functions");
|
|
9
9
|
const flatInput = (payload) => {
|
|
10
|
-
const { relation, query, sort, pagination, fields } = payload;
|
|
10
|
+
const { relation, query, sort, pagination, fields, omit } = payload;
|
|
11
11
|
const { populate = {}, filterBy, filterByValue, ...restQuery } = query;
|
|
12
12
|
const filters = restQuery?.filters || restQuery;
|
|
13
13
|
const orOperator = (filters?.$or || []).filter((_) => !Object.keys(_).includes("removed"));
|
|
@@ -65,6 +65,7 @@ const flatInput = (payload) => {
|
|
|
65
65
|
pagination,
|
|
66
66
|
sort,
|
|
67
67
|
fields,
|
|
68
|
+
omit,
|
|
68
69
|
};
|
|
69
70
|
};
|
|
70
71
|
exports.flatInput = flatInput;
|
package/server/index.d.ts
CHANGED
package/server/services/admin.js
CHANGED
|
@@ -121,7 +121,7 @@ module.exports = ({ strapi }) => ({
|
|
|
121
121
|
});
|
|
122
122
|
const relatedEntities = await this.getCommonService().findRelatedEntitiesFor(entities);
|
|
123
123
|
const result = entities
|
|
124
|
-
.map((_) => (0, functions_2.filterOurResolvedReports)(this.getCommonService().sanitizeCommentEntity(_, [], defaultAuthorUserPopulate?.populate)))
|
|
124
|
+
.map((_) => (0, functions_2.filterOurResolvedReports)(this.getCommonService().sanitizeCommentEntity(_, [], [], defaultAuthorUserPopulate?.populate)))
|
|
125
125
|
.map((_) => this.getCommonService().mergeRelatedEntityTo(_, relatedEntities));
|
|
126
126
|
const pageCount = Math.floor(total / pageSize);
|
|
127
127
|
return {
|
|
@@ -197,7 +197,7 @@ module.exports = ({ strapi }) => ({
|
|
|
197
197
|
..._.related,
|
|
198
198
|
gotThread: isCommentWithThread,
|
|
199
199
|
}, []),
|
|
200
|
-
}, [], defaultAuthorUserPopulate?.populate));
|
|
200
|
+
}, [], [], defaultAuthorUserPopulate?.populate));
|
|
201
201
|
});
|
|
202
202
|
const pageCount = Math.floor(total / pageSize);
|
|
203
203
|
return {
|
|
@@ -291,7 +291,7 @@ module.exports = ({ strapi }) => ({
|
|
|
291
291
|
const selectedEntity = this.getCommonService().sanitizeCommentEntity({
|
|
292
292
|
...entity,
|
|
293
293
|
threadOf: entity.threadOf || null,
|
|
294
|
-
}, [], defaultAuthorUserPopulate?.populate);
|
|
294
|
+
}, [], [], defaultAuthorUserPopulate?.populate);
|
|
295
295
|
return {
|
|
296
296
|
entity: relatedEntity,
|
|
297
297
|
selected: selectedEntity,
|
|
@@ -9,6 +9,11 @@ const error_1 = __importDefault(require("./../utils/error"));
|
|
|
9
9
|
const functions_1 = require("./utils/functions");
|
|
10
10
|
const parsers_1 = require("./utils/parsers");
|
|
11
11
|
const PAGE_SIZE = 10;
|
|
12
|
+
const REQUIRED_FIELDS = ["id"];
|
|
13
|
+
const lifecycleHookListeners = {
|
|
14
|
+
comment: {},
|
|
15
|
+
"comment-report": {}
|
|
16
|
+
};
|
|
12
17
|
module.exports = ({ strapi }) => ({
|
|
13
18
|
async getConfig(prop, defaultValue, useLocal = false) {
|
|
14
19
|
const queryProp = (0, functions_1.buildConfigQueryProp)(prop);
|
|
@@ -33,8 +38,9 @@ module.exports = ({ strapi }) => ({
|
|
|
33
38
|
const result = strapi.config.get(`plugin.comments${queryProp ? "." + queryProp : ""}`);
|
|
34
39
|
return (0, lodash_1.isNil)(result) ? defaultValue : result;
|
|
35
40
|
},
|
|
36
|
-
async findAllFlat({ query = {}, populate = {}, sort, pagination, fields, isAdmin = false, }, relatedEntity = null) {
|
|
37
|
-
const
|
|
41
|
+
async findAllFlat({ query = {}, populate = {}, sort, pagination, fields, isAdmin = false, omit: baseOmit = [], }, relatedEntity = null) {
|
|
42
|
+
const omit = baseOmit.filter((field) => !REQUIRED_FIELDS.includes(field));
|
|
43
|
+
const defaultSelect = ["id", "related"].filter((field) => !omit.includes(field));
|
|
38
44
|
const populateClause = {
|
|
39
45
|
authorUser: true,
|
|
40
46
|
...((0, lodash_1.isObject)(populate) ? populate : {}),
|
|
@@ -94,9 +100,11 @@ module.exports = ({ strapi }) => ({
|
|
|
94
100
|
firstThreadItemId: (0, lodash_1.first)(nestedEntries)?.id,
|
|
95
101
|
};
|
|
96
102
|
}));
|
|
97
|
-
const relatedEntities =
|
|
98
|
-
? [
|
|
99
|
-
:
|
|
103
|
+
const relatedEntities = omit.includes("related")
|
|
104
|
+
? []
|
|
105
|
+
: relatedEntity !== null
|
|
106
|
+
? [relatedEntity]
|
|
107
|
+
: await this.findRelatedEntitiesFor([...entries]);
|
|
100
108
|
const hasRelatedEntitiesToMap = relatedEntities.filter((_) => _).length > 0;
|
|
101
109
|
const result = entries.map((_) => {
|
|
102
110
|
const threadedItem = entriesWithThreads.find((item) => item.id === _.id);
|
|
@@ -118,7 +126,7 @@ module.exports = ({ strapi }) => ({
|
|
|
118
126
|
threadOf: primitiveThreadOf || _.threadOf,
|
|
119
127
|
gotThread: (threadedItem?.itemsInTread || 0) > 0,
|
|
120
128
|
threadFirstItemId: threadedItem?.firstThreadItemId,
|
|
121
|
-
}, doNotPopulateAuthor, authorUserPopulate);
|
|
129
|
+
}, doNotPopulateAuthor, omit, authorUserPopulate);
|
|
122
130
|
});
|
|
123
131
|
return {
|
|
124
132
|
data: hasRelatedEntitiesToMap
|
|
@@ -127,8 +135,8 @@ module.exports = ({ strapi }) => ({
|
|
|
127
135
|
...((0, lodash_1.isEmpty)(meta) ? {} : { meta }),
|
|
128
136
|
};
|
|
129
137
|
},
|
|
130
|
-
async findAllInHierarchy({ query, populate = {}, sort, fields, startingFromId = null, dropBlockedThreads = false, isAdmin = false, }, relatedEntity) {
|
|
131
|
-
const entities = await this.findAllFlat({ query, populate, sort, fields, isAdmin }, relatedEntity);
|
|
138
|
+
async findAllInHierarchy({ query, populate = {}, sort, fields, startingFromId = null, dropBlockedThreads = false, isAdmin = false, omit = [], }, relatedEntity) {
|
|
139
|
+
const entities = await this.findAllFlat({ query, populate, sort, fields, isAdmin, omit }, relatedEntity);
|
|
132
140
|
return (0, functions_1.buildNestedStructure)(entities?.data, startingFromId, "threadOf", dropBlockedThreads, false);
|
|
133
141
|
},
|
|
134
142
|
async findOne(criteria) {
|
|
@@ -225,18 +233,18 @@ module.exports = ({ strapi }) => ({
|
|
|
225
233
|
return false;
|
|
226
234
|
}
|
|
227
235
|
},
|
|
228
|
-
sanitizeCommentEntity(entity, blockedAuthorProps, populate) {
|
|
236
|
+
sanitizeCommentEntity(entity, blockedAuthorProps, omit = [], populate) {
|
|
229
237
|
const fieldsToPopulate = (0, lodash_1.isArray)(populate)
|
|
230
238
|
? populate
|
|
231
239
|
: Object.keys(populate || {});
|
|
232
|
-
return {
|
|
240
|
+
return (0, lodash_1.omit)({
|
|
233
241
|
...(0, functions_1.buildAuthorModel)({
|
|
234
242
|
...entity,
|
|
235
243
|
threadOf: (0, lodash_1.isObject)(entity.threadOf)
|
|
236
244
|
? (0, functions_1.buildAuthorModel)(entity.threadOf, blockedAuthorProps, fieldsToPopulate)
|
|
237
245
|
: entity.threadOf,
|
|
238
246
|
}, blockedAuthorProps, fieldsToPopulate),
|
|
239
|
-
};
|
|
247
|
+
}, omit);
|
|
240
248
|
},
|
|
241
249
|
isValidUserContext(user) {
|
|
242
250
|
return user ? !(0, lodash_1.isNil)(user?.id) : true;
|
|
@@ -272,5 +280,17 @@ module.exports = ({ strapi }) => ({
|
|
|
272
280
|
const enabledCollections = await this.getConfig("enabledCollections", []);
|
|
273
281
|
return enabledCollections.includes(uid);
|
|
274
282
|
},
|
|
283
|
+
registerLifecycleHook({ callback, contentTypeName, hookName }) {
|
|
284
|
+
if (!lifecycleHookListeners[contentTypeName][hookName]) {
|
|
285
|
+
lifecycleHookListeners[contentTypeName][hookName] = [];
|
|
286
|
+
}
|
|
287
|
+
lifecycleHookListeners[contentTypeName][hookName]?.push(callback);
|
|
288
|
+
},
|
|
289
|
+
async runLifecycleHook({ contentTypeName, event, hookName }) {
|
|
290
|
+
const hookListeners = lifecycleHookListeners[contentTypeName][hookName] ?? [];
|
|
291
|
+
for (const listener of hookListeners) {
|
|
292
|
+
await listener(event);
|
|
293
|
+
}
|
|
294
|
+
},
|
|
275
295
|
});
|
|
276
296
|
//# sourceMappingURL=common.js.map
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ConfigParamKeys, RegExpCollection } from "../../types";
|
|
2
|
+
import { LifeCycleHookName } from "./types";
|
|
2
3
|
export declare const CONFIG_PARAMS: ConfigParamKeys;
|
|
3
4
|
export declare const APPROVAL_STATUS: {
|
|
4
5
|
PENDING: string;
|
|
@@ -10,4 +11,5 @@ export declare const AUTHOR_TYPE: {
|
|
|
10
11
|
STRAPI: string;
|
|
11
12
|
};
|
|
12
13
|
export declare const REGEX: RegExpCollection;
|
|
14
|
+
export declare const LIFECYCLE_HOOKS: ReadonlyArray<LifeCycleHookName>;
|
|
13
15
|
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.REGEX = exports.AUTHOR_TYPE = exports.APPROVAL_STATUS = exports.CONFIG_PARAMS = void 0;
|
|
3
|
+
exports.LIFECYCLE_HOOKS = exports.REGEX = exports.AUTHOR_TYPE = exports.APPROVAL_STATUS = exports.CONFIG_PARAMS = void 0;
|
|
4
4
|
exports.CONFIG_PARAMS = {
|
|
5
5
|
ENABLED_COLLECTIONS: "enabledCollections",
|
|
6
6
|
APPROVAL_FLOW: "approvalFlow",
|
|
@@ -24,4 +24,24 @@ exports.REGEX = {
|
|
|
24
24
|
email: /\S+@\S+\.\S+/,
|
|
25
25
|
sorting: /^(?<path>[a-z0-9-_\:\.]+)\:+(asc|desc)$/i,
|
|
26
26
|
};
|
|
27
|
+
exports.LIFECYCLE_HOOKS = [
|
|
28
|
+
"beforeCreate",
|
|
29
|
+
"beforeCreateMany",
|
|
30
|
+
"afterCreate",
|
|
31
|
+
"afterCreateMany",
|
|
32
|
+
"beforeUpdate",
|
|
33
|
+
"beforeUpdateMany",
|
|
34
|
+
"afterUpdate",
|
|
35
|
+
"afterUpdateMany",
|
|
36
|
+
"beforeDelete",
|
|
37
|
+
"beforeDeleteMany",
|
|
38
|
+
"afterDelete",
|
|
39
|
+
"afterDeleteMany",
|
|
40
|
+
"beforeCount",
|
|
41
|
+
"afterCount",
|
|
42
|
+
"beforeFindOne",
|
|
43
|
+
"afterFindOne",
|
|
44
|
+
"beforeFindMany",
|
|
45
|
+
"afterFindMany",
|
|
46
|
+
];
|
|
27
47
|
//# sourceMappingURL=constants.js.map
|
|
@@ -1,6 +1,10 @@
|
|
|
1
|
-
import { StrapiQueryParams, StrapiQueryParamsParsed } from "strapi-typed";
|
|
1
|
+
import { StrapiQueryParams, StrapiQueryParamsParsed, StrapiContext } from "strapi-typed";
|
|
2
|
+
import { ContentType, LifeCycleEvent, LifeCycleHookName } from "./types";
|
|
3
|
+
import { Effect } from "../../types/utils";
|
|
2
4
|
export declare const getPluginService: <T>(name: string) => T;
|
|
3
5
|
export declare const parseParams: <T = StrapiQueryParamsParsed>(params: StrapiQueryParams) => T;
|
|
4
6
|
export declare const assertParamsPresent: <T>(params: unknown, keys: string[]) => asserts params is T;
|
|
5
7
|
export declare const assertNotEmpty: <T>(value: T | null | undefined, customError?: Error) => asserts value is T;
|
|
8
|
+
export declare const buildHookListener: (contentTypeName: ContentType, { strapi }: StrapiContext) => (hookName: LifeCycleHookName) => [LifeCycleHookName, Effect<LifeCycleEvent>];
|
|
9
|
+
export declare const buildAllHookListeners: (contentTypeName: ContentType, context: StrapiContext) => Record<LifeCycleHookName, Effect<LifeCycleEvent>>;
|
|
6
10
|
//# sourceMappingURL=functions.d.ts.map
|
|
@@ -3,8 +3,9 @@ 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.assertNotEmpty = exports.assertParamsPresent = exports.parseParams = exports.getPluginService = void 0;
|
|
6
|
+
exports.buildAllHookListeners = exports.buildHookListener = exports.assertNotEmpty = exports.assertParamsPresent = exports.parseParams = exports.getPluginService = void 0;
|
|
7
7
|
const error_1 = __importDefault(require("./error"));
|
|
8
|
+
const constants_1 = require("./constants");
|
|
8
9
|
const getPluginService = (name) => strapi.plugin("comments").service(name);
|
|
9
10
|
exports.getPluginService = getPluginService;
|
|
10
11
|
const parseParams = (params) => Object.keys(params).reduce((prev, curr) => {
|
|
@@ -33,4 +34,20 @@ const assertNotEmpty = (value, customError) => {
|
|
|
33
34
|
throw (customError ?? new error_1.default(400, "Non-empty value expected, empty given"));
|
|
34
35
|
};
|
|
35
36
|
exports.assertNotEmpty = assertNotEmpty;
|
|
37
|
+
const buildHookListener = (contentTypeName, { strapi }) => (hookName) => [
|
|
38
|
+
hookName,
|
|
39
|
+
async (event) => {
|
|
40
|
+
const commonService = strapi
|
|
41
|
+
.plugin("comments")
|
|
42
|
+
.service("common");
|
|
43
|
+
await commonService.runLifecycleHook({
|
|
44
|
+
contentTypeName,
|
|
45
|
+
hookName,
|
|
46
|
+
event,
|
|
47
|
+
});
|
|
48
|
+
},
|
|
49
|
+
];
|
|
50
|
+
exports.buildHookListener = buildHookListener;
|
|
51
|
+
const buildAllHookListeners = (contentTypeName, context) => Object.fromEntries(constants_1.LIFECYCLE_HOOKS.map((0, exports.buildHookListener)(contentTypeName, context)));
|
|
52
|
+
exports.buildAllHookListeners = buildAllHookListeners;
|
|
36
53
|
//# sourceMappingURL=functions.js.map
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Effect } from "../../types/utils";
|
|
2
|
+
export type ContentType = "comment" | "comment-report";
|
|
3
|
+
export type LifeCycleHookName = "beforeCreate" | "beforeCreateMany" | "afterCreate" | "afterCreateMany" | "beforeUpdate" | "beforeUpdateMany" | "afterUpdate" | "afterUpdateMany" | "beforeDelete" | "beforeDeleteMany" | "afterDelete" | "afterDeleteMany" | "beforeCount" | "afterCount" | "beforeFindOne" | "afterFindOne" | "beforeFindMany" | "afterFindMany";
|
|
4
|
+
export interface LifeCycleEvent<THookName extends LifeCycleHookName = LifeCycleHookName, TResult = unknown, TParams = Record<string, unknown>> {
|
|
5
|
+
action: THookName;
|
|
6
|
+
model: {
|
|
7
|
+
singularName: string;
|
|
8
|
+
uid: string;
|
|
9
|
+
tableName: string;
|
|
10
|
+
attributes: Record<string, unknown>;
|
|
11
|
+
lifecycles: Partial<Record<LifeCycleHookName, Effect<LifeCycleEvent>>>;
|
|
12
|
+
indexes: Array<{
|
|
13
|
+
type?: string;
|
|
14
|
+
name: string;
|
|
15
|
+
columns: string[];
|
|
16
|
+
}>;
|
|
17
|
+
columnToAttribute: Record<string, string>;
|
|
18
|
+
};
|
|
19
|
+
state: Record<string, unknown>;
|
|
20
|
+
params: TParams;
|
|
21
|
+
result?: TResult | TResult[];
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=types.d.ts.map
|