@ozdao/prometheus-framework 0.1.34 → 0.1.36

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,86 @@
1
+ var common_schema = function applyCommonSchema(schema, db) {
2
+ schema.add({
3
+ status: {
4
+ type: String,
5
+ enum: ["draft", "published", "removed"],
6
+ default: "draft",
7
+ required: true
8
+ }
9
+ });
10
+ };
11
+ var engagement_schema = function applyEngagementSchema(schema, db) {
12
+ schema.add({
13
+ views: {
14
+ type: Number,
15
+ default: 0
16
+ }
17
+ });
18
+ schema.post("aggregate", async function(docs) {
19
+ if (docs.length > 0) {
20
+ console.log("Post-aggregate hook in engagement schena triggered");
21
+ try {
22
+ await Promise.all(docs.map(async (doc) => {
23
+ console.log(doc._id);
24
+ const updatedViews = await db.event.findOneAndUpdate({ _id: doc._id }, { $inc: { views: 1 } }).exec();
25
+ }));
26
+ } catch (error) {
27
+ console.error("Error updating views:", error);
28
+ }
29
+ }
30
+ });
31
+ };
32
+ var ownership_schema = function applyOwnershipSchema(schema, db) {
33
+ schema.add({
34
+ owner: {
35
+ type: {
36
+ type: String,
37
+ required: true
38
+ },
39
+ target: {
40
+ type: db.mongoose.Schema.Types.ObjectId,
41
+ refPath: "owner.type",
42
+ required: true
43
+ }
44
+ },
45
+ creator: {
46
+ hidden: {
47
+ type: Boolean,
48
+ required: true
49
+ },
50
+ type: {
51
+ type: String,
52
+ required: true
53
+ },
54
+ target: {
55
+ type: db.mongoose.Schema.Types.ObjectId,
56
+ refPath: "creator.type",
57
+ required: true
58
+ }
59
+ }
60
+ });
61
+ schema.index({
62
+ "owner.target": 1,
63
+ "creator.target": 1
64
+ });
65
+ };
66
+ var metadata_schema = function applyMetadataSchema(schema, db) {
67
+ schema.add({
68
+ url: {
69
+ type: String,
70
+ required: true
71
+ },
72
+ tags: [{
73
+ type: String
74
+ }]
75
+ });
76
+ schema.index({
77
+ "url": 1,
78
+ "tags": 1
79
+ });
80
+ };
81
+ export {
82
+ common_schema as c,
83
+ engagement_schema as e,
84
+ metadata_schema as m,
85
+ ownership_schema as o
86
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ozdao/prometheus-framework",
3
- "version": "0.1.34",
3
+ "version": "0.1.36",
4
4
  "description": "Web3 Framework focused on user experience and ease of development.",
5
5
  "author": "OZ DAO <hello@ozdao.dev>",
6
6
  "license": "GPL-3.0-or-later",
@@ -4,7 +4,7 @@ const controllerFactoryTwofa = require("../controllers/twofa.controller");
4
4
  // Middlewares
5
5
  const middlewareFactory = require('@pf/src/modules/middlewares/server');
6
6
  // Routes
7
- module.exports = function(app, db) {
7
+ module.exports = function(app, db, origins) {
8
8
  const controller = controllerFactory(db);
9
9
  const controllerTwofa = controllerFactoryTwofa(db);
10
10
 
@@ -12,11 +12,14 @@ module.exports = function(app, db) {
12
12
 
13
13
  app.use(function(req, res, next) {
14
14
 
15
- res.header(
16
- "Access-Control-Allow-Headers",
17
- "Access-Control-Allow-Origin",
18
- "x-access-token, Origin, Content-Type, Accept"
19
- );
15
+ const origin = req.headers.origin;
16
+
17
+ if (origins.includes(origin)) {
18
+ res.setHeader('Access-Control-Allow-Origin', origin);
19
+ }
20
+
21
+ res.header("Access-Control-Allow-Headers", "x-access-token, Origin, Content-Type, Accept");
22
+
20
23
  next();
21
24
  });
22
25
 
@@ -0,0 +1,290 @@
1
+ // Query Processor
2
+ const queryProcessor = require('./utils/queryProcessor');
3
+ const queryProcessorGlobals = require('@pf/src/modules/globals/controllers/utils/queryProcessor');
4
+ // Utils
5
+ const { getBlockedMembers, addConditionsForBlocked } = require('@pf/src/modules/organizations/controllers/utils/excludeBlockedMembers');
6
+
7
+ const controllerFactory = (db) => {
8
+ const Blogpost = db.blogpost;
9
+ const Organization = db.organization;
10
+ const Membership = db.membership;
11
+
12
+ const read = async (req, res) => {
13
+
14
+ let stages = [];
15
+
16
+ stages = [
17
+ ...queryProcessorGlobals.getBasicOptions(
18
+ req.query
19
+ ),
20
+ // Pagination
21
+ ...queryProcessorGlobals.getSortingOptions(
22
+ req.query
23
+ ),
24
+ ...queryProcessorGlobals.getPaginationOptions(
25
+ req.query
26
+ )
27
+ ]
28
+
29
+ let query = [];
30
+ let matchStage = {};
31
+
32
+
33
+ if (req.query.status) {
34
+ matchStage["status"] = req.query.status;
35
+ }
36
+
37
+ // EXCLUDE USERS AND ORGS BLOCKED BY USER
38
+ if (req.query.user) {
39
+ const blockedMembers = await getBlockedMembers(Membership, req.query.user);
40
+
41
+ console.log(blockedMembers);
42
+
43
+ if (blockedMembers.length > 0) {
44
+ addConditionsForBlocked(matchStage, "owner.target", blockedMembers);
45
+ addConditionsForBlocked(matchStage, "creator.target", blockedMembers);
46
+ }
47
+ }
48
+
49
+ if (req.query.tags) {
50
+ matchStage["tags"] = { $in: req.query.tags.split(',') };
51
+ }
52
+
53
+ if (req.query.period) {
54
+ const date = new Date();
55
+
56
+ switch (req.query.period) {
57
+ case 'today':
58
+ date.setDate(date.getDate() - 1);
59
+ break;
60
+ case 'week':
61
+ date.setDate(date.getDate() - 7);
62
+ break;
63
+ case 'month':
64
+ date.setMonth(date.getMonth() - 1);
65
+ break;
66
+ case 'year':
67
+ date.setFullYear(date.getFullYear() - 1);
68
+ break;
69
+ }
70
+ matchStage["createdAt"] = { $gte: date };
71
+ }
72
+
73
+ // FILTER BY CATEGORY
74
+ if (req.query.category) {
75
+ switch (req.query.category) {
76
+ case 'featured':
77
+ matchStage["tags"] = { $in: ["Featured"] };
78
+ break;
79
+ case 'popular':
80
+ query.push({ $sort: { views: -1, likes: -1 } });
81
+ break;
82
+ case 'new':
83
+ query.push({ $sort: { createdAt: -1 } });
84
+ break;
85
+ case 'following':
86
+ if (req.query.user) {
87
+ const memberships = await Membership.find({ user: req.query.user });
88
+ const followedOrganizations = memberships.filter(membership => membership.type === 'organization').map(membership => membership.target);
89
+ const followedAuthors = memberships.filter(membership => membership.type === 'user').map(membership => membership.target);
90
+
91
+ matchStage["$or"] = [
92
+ { "owner.target": { $in: followedOrganizations } },
93
+ { "owner.target": { $in: followedAuthors } }
94
+ ];
95
+ }
96
+ break;
97
+ }
98
+ }
99
+
100
+
101
+ query.push({ $match: matchStage });
102
+
103
+
104
+ query.push({
105
+ $lookup: {
106
+ from: "comments",
107
+ localField: "_id",
108
+ foreignField: "target",
109
+ as: "comments"
110
+ }
111
+ });
112
+
113
+ query.push({
114
+ $lookup: {
115
+ from: "reactions",
116
+ localField: "_id",
117
+ foreignField: "target",
118
+ as: "reactions"
119
+ }
120
+ });
121
+
122
+ query.push({
123
+ $addFields: {
124
+ numberOfComments: { $size: "$comments" },
125
+ numberOfReactions: { $size: "$reactions" },
126
+ isReacted: {
127
+ $in: [
128
+ new db.mongoose.Types.ObjectId(req.query.user),
129
+ "$reactions.user"
130
+ ]
131
+ },
132
+ reactionId: {
133
+ $let: {
134
+ vars: {
135
+ reactionIndex: {
136
+ $indexOfArray: [
137
+ "$reactions.user",
138
+ new db.mongoose.Types.ObjectId(req.query.user)
139
+ ]
140
+ }
141
+ },
142
+ in: {
143
+ $cond: [
144
+ { $gte: ["$$reactionIndex", 0] },
145
+ { $arrayElemAt: ["$reactions._id", "$$reactionIndex"] },
146
+ null
147
+ ]
148
+ }
149
+ }
150
+ }
151
+ }
152
+ });
153
+
154
+ query.push({
155
+ $lookup: {
156
+ from: "users",
157
+ localField: "creator.target",
158
+ foreignField: "_id",
159
+ as: "creatorUser"
160
+ }
161
+ },
162
+ {
163
+ $lookup: {
164
+ from: "organizations",
165
+ localField: "creator.target",
166
+ foreignField: "_id",
167
+ as: "creatorOrganization"
168
+ }
169
+ },
170
+ // Для owner
171
+ {
172
+ $lookup: {
173
+ from: "users",
174
+ localField: "owner.target",
175
+ foreignField: "_id",
176
+ as: "ownerUser"
177
+ }
178
+ },
179
+ {
180
+ $lookup: {
181
+ from: "organizations",
182
+ localField: "owner.target",
183
+ foreignField: "_id",
184
+ as: "ownerOrganization"
185
+ }
186
+ },
187
+ {
188
+ $addFields: {
189
+ "creator.target": {
190
+ $cond: [
191
+ { $eq: ["$creator.type", "user"] },
192
+ { $arrayElemAt: ["$creatorUser", 0] },
193
+ { $arrayElemAt: ["$creatorOrganization", 0] }
194
+ ]
195
+ },
196
+ "owner.target": {
197
+ $cond: [
198
+ { $eq: ["$owner.type", "user"] },
199
+ { $arrayElemAt: ["$ownerUser", 0] },
200
+ { $arrayElemAt: ["$ownerOrganization", 0] }
201
+ ]
202
+ }
203
+ }
204
+ })
205
+
206
+ query.push({
207
+ $project: {
208
+ comments: 0,
209
+ reactions: 0
210
+ }
211
+ });
212
+
213
+ try {
214
+ const posts = await Blogpost.aggregate(query).exec();
215
+
216
+ if (posts.length === 0) {
217
+ return res.status(200).send([]);
218
+ // return res.status(404).send({ message: "Posts not found." });
219
+ }
220
+
221
+ console.log(posts)
222
+
223
+ res.status(200).send(posts);
224
+ } catch (err) {
225
+ console.log(err);
226
+ res.status(500).send({ err });
227
+ }
228
+ };
229
+
230
+
231
+ const create = (req, res) => {
232
+ let user = JSON.parse(req.cookies.user);
233
+
234
+ const newBlogpost = {
235
+ url: req.body.name.toLowerCase().replace(/ /g, '-').replace(/[^\w-]+/g, ''),
236
+ name: req.body.name,
237
+ status: req.body.status,
238
+ tags: req.body.tags ? req.body.tags : ['All'],
239
+ owner: req.body.owner,
240
+ creator: req.body.creator,
241
+ content: req.body.content,
242
+ views: 1
243
+ };
244
+
245
+ Blogpost.create(newBlogpost)
246
+ .then((post) => {
247
+ res.status(200).send(post);
248
+ })
249
+ .catch((err) => {
250
+ res.status(500).send({ message: err.message || "Some error occurred while creating the blogpost." });
251
+ });
252
+ };
253
+
254
+ const update = (req, res) => {
255
+ Blogpost.findOneAndUpdate({ _id: req.body._id }, { $set: req.body }, { new: true })
256
+ .exec()
257
+ .then((post) => {
258
+ if (!post) {
259
+ return res.status(404).send({ message: "Something wrong when updating the blogpost." });
260
+ }
261
+ res.status(200).send(post);
262
+ })
263
+ .catch((err) => {
264
+ res.status(500).send({ message: err.message || "Some error occurred while updating the blogpost." });
265
+ });
266
+ };
267
+
268
+ const del = (req, res) => {
269
+ Blogpost.findOneAndDelete({ _id: req.params._id })
270
+ .exec()
271
+ .then((post) => {
272
+ if (!post) {
273
+ return res.status(404).send({ message: "The blogpost is not deleted." });
274
+ }
275
+ res.status(200).send(post);
276
+ })
277
+ .catch((err) => {
278
+ res.status(500).send({ message: err.message || "Some error occurred while deleting the blogpost." });
279
+ });
280
+ };
281
+
282
+ return {
283
+ read,
284
+ create,
285
+ update,
286
+ delete: del
287
+ };
288
+ };
289
+
290
+ module.exports = controllerFactory;
@@ -1,48 +1,17 @@
1
- module.exports = (mongoose) => {
2
- const BlogpostSchema = new mongoose.Schema({
3
- url: { type: String },
4
- name: { type: String },
5
- content: { type: Array },
6
- views: { type: Number },
7
- tags: { type: Array },
8
- status: {
9
- type: String,
10
- enum: ['draft','published','removed'],
11
- default: 'draft',
12
- required: true,
1
+ const applyCommonSchema = require('@pf/src/modules/globals/models/common.schema.js');
2
+ const applyEngagementSchema = require('@pf/src/modules/globals/models/engagement.schema.js');
3
+ const applyOwnershipSchema = require('@pf/src/modules/globals/models/ownership.schema.js');
4
+ const applyMetadataSchema = require('@pf/src/modules/globals/models/metadata.schema.js');
5
+
6
+ module.exports = (db) => {
7
+ const BlogpostSchema = new db.mongoose.Schema({
8
+ name: {
9
+ type: String,
10
+ required: true
13
11
  },
14
- owner: {
15
- type: {
16
- type: String,
17
- required: true
18
- },
19
- target: {
20
- type: mongoose.Schema.Types.ObjectId,
21
- ref: function (value) {
22
- if (this.owner.type === 'user') return 'User';
23
- if (this.owner.type === 'organization') return 'Organization';
24
- },
25
- required: true,
26
- },
12
+ content: {
13
+ type: Array
27
14
  },
28
- creator: {
29
- hidden: {
30
- type: Boolean,
31
- required: true
32
- },
33
- type: {
34
- type: String,
35
- required: true
36
- },
37
- target: {
38
- type: mongoose.Schema.Types.ObjectId,
39
- ref: function (value) {
40
- if (this.owner.type === 'user') return 'User';
41
- if (this.owner.type === 'organization') return 'Organization';
42
- },
43
- required: true,
44
- },
45
- }
46
15
  }, {
47
16
  timestamps: {
48
17
  currentTime: () => Date.now()
@@ -51,7 +20,12 @@ module.exports = (mongoose) => {
51
20
  strict: false
52
21
  });
53
22
 
54
- const Blogpost = mongoose.model("Blogpost", BlogpostSchema);
23
+ applyCommonSchema(BlogpostSchema,db);
24
+ applyEngagementSchema(BlogpostSchema,db);
25
+ applyOwnershipSchema(BlogpostSchema,db);
26
+ applyMetadataSchema(BlogpostSchema,db);
27
+
28
+ const Blogpost = db.mongoose.model("Blogpost", BlogpostSchema);
55
29
 
56
30
  return Blogpost;
57
31
  };
@@ -3,18 +3,22 @@ const controllerFactory = require("../controllers/blog.controller");
3
3
  const middlewareFactoryGlobal = require('@pf/src/modules/middlewares/server');
4
4
  const middlewareFactoryCommunity = require('../middlewares/server');
5
5
 
6
- module.exports = function(app, db) {
6
+ module.exports = function(app, db, origins) {
7
7
  const controller = controllerFactory(db);
8
8
 
9
9
  const { authJwt } = middlewareFactoryGlobal(db);
10
10
  const { verifyBlogpost } = middlewareFactoryCommunity(db);
11
11
 
12
12
  app.use(function(req, res, next) {
13
- res.header(
14
- "Access-Control-Allow-Headers",
15
- "Access-Control-Allow-Origin",
16
- "x-access-token, Origin, Content-Type, Accept"
17
- );
13
+
14
+ const origin = req.headers.origin;
15
+
16
+ if (origins.includes(origin)) {
17
+ res.setHeader('Access-Control-Allow-Origin', origin);
18
+ }
19
+
20
+ res.header("Access-Control-Allow-Headers", "x-access-token, Origin, Content-Type, Accept");
21
+
18
22
  next();
19
23
  });
20
24
 
@@ -61,6 +61,7 @@ const middlewareFactory = (db) => {
61
61
  try {
62
62
  const events = await Event.aggregate(stages).exec();
63
63
  res.status(200).send(events);
64
+
64
65
  } catch (err) {
65
66
  console.log(err);
66
67
  return res.status(500).send({ message: err });
@@ -69,7 +70,7 @@ const middlewareFactory = (db) => {
69
70
 
70
71
 
71
72
  const create = async (req, res) => {
72
- if (req.body._id) delete req.body._id;
73
+ delete req.body._id;
73
74
 
74
75
  try {
75
76
  req.body.url = createFriendlyURL(req.body.name);
@@ -23,10 +23,12 @@ const middlewareFactory = (db) => {
23
23
  // Обновление события
24
24
  const updatingEventId = req.body._id; // Изменено с updatingBlogpostId на updatingEventId
25
25
  const existingEvent = await Event.findById(updatingEventId); // Изменено с Blogpost на Event и с existingBlogpost на existingEvent
26
+
26
27
  if (!existingEvent) { // Изменено с existingBlogpost на existingEvent
27
28
  res.status(404).send({ errorCode: 'EVENT_NOT_FOUND', accessToken: null }); // Изменено с BLOGPOST_NOT_FOUND на EVENT_NOT_FOUND
28
29
  return;
29
30
  }
31
+
30
32
  if (existingEvent.url !== url) { // Изменено с existingBlogpost на existingEvent
31
33
  const event = await Event.findOne({ url }); // Изменено с Blogpost на Event и с blogpost на event
32
34
  if (event) { // Изменено с blogpost на event
@@ -1,9 +1,11 @@
1
- module.exports = (mongoose) => {
2
- const EventSchema = new mongoose.Schema({
3
- url: {
4
- type: String,
5
- required: true
6
- },
1
+ const applyCommonSchema = require('@pf/src/modules/globals/models/common.schema.js');
2
+ const applyEngagementSchema = require('@pf/src/modules/globals/models/engagement.schema.js');
3
+ const applyOwnershipSchema = require('@pf/src/modules/globals/models/ownership.schema.js');
4
+ const applyMetadataSchema = require('@pf/src/modules/globals/models/metadata.schema.js');
5
+
6
+ module.exports = (db) => {
7
+
8
+ const EventSchema = new db.mongoose.Schema({
7
9
  cover: {
8
10
  type: String,
9
11
  },
@@ -11,12 +13,6 @@ module.exports = (mongoose) => {
11
13
  type: String,
12
14
  required: true
13
15
  },
14
- status: {
15
- type: String,
16
- enum: ['draft','published','removed'],
17
- default: 'draft',
18
- required: true,
19
- },
20
16
  description: {
21
17
  type: String,
22
18
  required: true
@@ -32,41 +28,6 @@ module.exports = (mongoose) => {
32
28
  end: {
33
29
  type: Date,
34
30
  }
35
- },
36
- tags: [{
37
- type: String
38
- }],
39
- owner: {
40
- type: {
41
- type: String,
42
- required: true
43
- },
44
- target: {
45
- type: mongoose.Schema.Types.ObjectId,
46
- ref: function (value) {
47
- if (this.owner.type === 'user') return 'User';
48
- if (this.owner.type === 'organization') return 'Organization';
49
- },
50
- required: true,
51
- },
52
- },
53
- creator: {
54
- hidden: {
55
- type: Boolean,
56
- required: true
57
- },
58
- type: {
59
- type: String,
60
- required: true
61
- },
62
- target: {
63
- type: mongoose.Schema.Types.ObjectId,
64
- ref: function (value) {
65
- if (this.owner.type === 'user') return 'User';
66
- if (this.owner.type === 'organization') return 'Organization';
67
- },
68
- required: true,
69
- },
70
31
  }
71
32
  }, {
72
33
  timestamps: {
@@ -74,9 +35,23 @@ module.exports = (mongoose) => {
74
35
  }
75
36
  });
76
37
 
77
- EventSchema.index({ 'url': 1, 'name': 1, 'date.start': 1, 'date.end': -1, 'tags': 1, 'owner.target': 1, 'creator.target': 1 });
38
+ EventSchema.index({
39
+ 'name': 1,
40
+ 'date.start': 1,
41
+ 'date.end': -1,
42
+ });
78
43
 
79
- const Event = mongoose.model("Event", EventSchema);
44
+ applyCommonSchema(EventSchema,db);
45
+ applyEngagementSchema(EventSchema,db);
46
+ applyOwnershipSchema(EventSchema,db);
47
+ applyMetadataSchema(EventSchema,db);
48
+
49
+ EventSchema.post('aggregate', async function(docs) {
50
+ console.log(EventSchema)
51
+ });
52
+
53
+ const Event = db.mongoose.model("Event", EventSchema);
80
54
 
81
55
  return Event;
82
- };
56
+ };
57
+
@@ -4,7 +4,7 @@ const controllerFactory = require("../controllers/events.controller");
4
4
  const middlewareFactoryGlobal = require('@pf/src/modules/middlewares/server');
5
5
  const middlewareFactoryEvents = require('../middlewares/server');
6
6
  // Routes
7
- module.exports = function(app, db) {
7
+ module.exports = function(app, db, origins) {
8
8
  const controller = controllerFactory(db);
9
9
 
10
10
  const { authJwt } = middlewareFactoryGlobal(db);
@@ -12,11 +12,14 @@ module.exports = function(app, db) {
12
12
 
13
13
  app.use(function(req, res, next) {
14
14
 
15
- res.header(
16
- "Access-Control-Allow-Headers",
17
- "Access-Control-Allow-Origin",
18
- "x-access-token, Origin, Content-Type, Accept"
19
- );
15
+ const origin = req.headers.origin;
16
+
17
+ if (origins.includes(origin)) {
18
+ res.setHeader('Access-Control-Allow-Origin', origin);
19
+ }
20
+
21
+ res.header("Access-Control-Allow-Headers", "x-access-token, Origin, Content-Type, Accept");
22
+
20
23
  next();
21
24
  });
22
25