adminmate-express-mongoose 1.3.3 → 1.3.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,136 +2,152 @@
2
2
  const Joi = require('joi');
3
3
  const _ = require('lodash');
4
4
  const moment = require('moment');
5
- const fnHelper = require('../helpers/functions');
6
-
7
- module.exports = async (currentModel, data) => {
8
- const paramsSchema = Joi.object({
9
- type: Joi.string().required(),
10
- model: Joi.string().required(),
11
- operation: Joi.string().required(),
12
- group_by: Joi.string().required(),
13
- timeframe: Joi.string().required().valid('day', 'week', 'month', 'year'),
14
- field: Joi.alternatives().conditional('operation', {
15
- not: 'count',
16
- then: Joi.string().required(),
17
- otherwise: Joi.string()
18
- }),
19
- limit: Joi.number().optional(),
20
- date_from: Joi.date().optional(),
21
- date_to: Joi.date().optional()
22
- });
23
-
24
- // Validate params
25
- const { error } = paramsSchema.validate(data);
26
- if (error) {
27
- return {
28
- success: false,
29
- message: error.details[0].message
30
- };
31
- }
32
-
33
- const toSum = data.field && data.operation === 'sum' ? `$${data.field}` : 1;
34
-
35
- let matchReq = {};
36
- let groupFormat = '';
37
-
38
- if (data.date_from) {
39
- matchReq['$gte'] = new Date(moment(data.date_from));
40
- }
41
-
42
- if (data.date_to) {
43
- matchReq['$lt'] = new Date(moment(data.date_to));
44
- }
45
-
46
- // Day timeframe
47
- if (data.timeframe === 'day') {
48
- groupFormat = '%Y-%m-%d 00:00:00';
49
- }
50
- // Week timeframe
51
- else if (data.timeframe === 'week') {
52
- groupFormat = '%Y-%V';
53
- }
54
- // Month timeframe
55
- else if (data.timeframe === 'month') {
56
- groupFormat = '%Y-%m-01 00:00:00';
57
- }
58
- // Year timeframe
59
- else if (data.timeframe === 'year') {
60
- groupFormat = '%Y-01-01 00:00:00';
61
- }
62
-
63
- if (!groupFormat) {
64
- return {
65
- success: false,
66
- message: 'Invalid request'
67
- };
68
- }
69
-
70
- let repartitionData;
71
- try {
72
- repartitionData = await currentModel
73
- .aggregate([
74
- {
75
- $match: Object.keys(matchReq).length > 0 ? {
76
- [data.group_by]: matchReq
77
- } : {}
78
- },
79
- {
80
- $group: {
81
- _id: { $dateToString: { format: groupFormat, date: `$${data.group_by}` } },
82
- count: { $sum: toSum }
83
- }
84
- },
85
- {
86
- $project: {
87
- key: '$_id',
88
- value: '$count',
89
- _id: false
5
+
6
+ module.exports = _conf => {
7
+ const fnHelper = require('../helpers/functions')(_conf);
8
+
9
+ const chartTime = async (currentModel, data) => {
10
+ const paramsSchema = Joi.object({
11
+ type: Joi.string().required(),
12
+ model: Joi.string().required(),
13
+ operation: Joi.string().required(),
14
+ group_by: Joi.string().required(),
15
+ timeframe: Joi.string().required().valid('day', 'week', 'month', 'year'),
16
+ field: Joi.alternatives().conditional('operation', {
17
+ not: 'count',
18
+ then: Joi.string().required(),
19
+ otherwise: Joi.string()
20
+ }),
21
+ limit: Joi.number().optional(),
22
+ date_from: Joi.date().optional(),
23
+ date_to: Joi.date().optional(),
24
+ filters: Joi.object({
25
+ operator: Joi.string().valid('and', 'or').required(),
26
+ list: Joi.array().required()
27
+ })
28
+ });
29
+
30
+ // Validate params
31
+ const { error } = paramsSchema.validate(data);
32
+ if (error) {
33
+ return {
34
+ success: false,
35
+ message: error.details[0].message
36
+ };
37
+ }
38
+
39
+ const toSum = data.field && data.operation === 'sum' ? `$${data.field}` : 1;
40
+
41
+ let matchReq = {};
42
+ let groupFormat = '';
43
+
44
+ if (data.date_from) {
45
+ matchReq['$gte'] = new Date(moment(data.date_from));
46
+ }
47
+
48
+ if (data.date_to) {
49
+ matchReq['$lt'] = new Date(moment(data.date_to));
50
+ }
51
+
52
+ // Day timeframe
53
+ if (data.timeframe === 'day') {
54
+ groupFormat = '%Y-%m-%d 00:00:00';
55
+ }
56
+ // Week timeframe
57
+ else if (data.timeframe === 'week') {
58
+ groupFormat = '%Y-%V';
59
+ }
60
+ // Month timeframe
61
+ else if (data.timeframe === 'month') {
62
+ groupFormat = '%Y-%m-01 00:00:00';
63
+ }
64
+ // Year timeframe
65
+ else if (data.timeframe === 'year') {
66
+ groupFormat = '%Y-01-01 00:00:00';
67
+ }
68
+
69
+ if (!groupFormat) {
70
+ return {
71
+ success: false,
72
+ message: 'Invalid request'
73
+ };
74
+ }
75
+
76
+ // Filters
77
+ let findParams = Object.keys(matchReq).length > 0 ? { [data.group_by]: matchReq } : {};
78
+ if (data.filters) {
79
+ const filtersQuery = fnHelper.constructQuery(data.filters);
80
+ if (filtersQuery) {
81
+ findParams = { $and: [findParams, filtersQuery] };
82
+ }
83
+ }
84
+
85
+ let repartitionData;
86
+ try {
87
+ repartitionData = await currentModel
88
+ .aggregate([
89
+ {
90
+ $match: findParams
91
+ },
92
+ {
93
+ $group: {
94
+ _id: { $dateToString: { format: groupFormat, date: `$${data.group_by}` } },
95
+ count: { $sum: toSum }
96
+ }
97
+ },
98
+ {
99
+ $project: {
100
+ key: '$_id',
101
+ value: '$count',
102
+ _id: false
103
+ }
90
104
  }
91
- }
92
- ]);
93
- }
94
- catch(e) {
95
- return {
96
- success: false,
97
- message: e.message
98
- };
99
- }
100
-
101
- const formattedData = [];
102
- if (repartitionData && repartitionData.length > 0) {
103
- // Get min & max date in the results
104
- const momentFormat = data.timeframe === 'week' ? 'YYYY-WW' : 'YYYY-MM-DD HH:mm:ss';
105
- const unixRange = repartitionData.map(data => moment(data.key, momentFormat));
106
- const min = _.min(unixRange).clone();
107
- const max = _.max(unixRange).clone();
108
-
109
- let currentDate = min;
110
- while (currentDate.isSameOrBefore(max)) {
111
- const countForTheTimeframe = repartitionData.find(d => moment(d.key, momentFormat).isSame(currentDate, data.timeframe));
112
- const value = countForTheTimeframe ? fnHelper.toFixedIfNecessary(countForTheTimeframe.value, 2) : 0;
113
- formattedData.push({
114
- key: currentDate.format('YYYY-MM-DD'),
115
- value
116
- });
117
- currentDate.add(1, data.timeframe).startOf('day');
105
+ ]);
118
106
  }
119
- }
120
-
121
- const chartConfig = {
122
- xaxis: [
123
- { dataKey: 'key' }
124
- ],
125
- yaxis: [
126
- { dataKey: 'value' }
127
- ]
128
- };
107
+ catch(e) {
108
+ return {
109
+ success: false,
110
+ message: e.message
111
+ };
112
+ }
113
+
114
+ const formattedData = [];
115
+ if (repartitionData && repartitionData.length > 0) {
116
+ // Get min & max date in the results
117
+ const momentFormat = data.timeframe === 'week' ? 'YYYY-WW' : 'YYYY-MM-DD HH:mm:ss';
118
+ const unixRange = repartitionData.map(data => moment(data.key, momentFormat));
119
+ const min = _.min(unixRange).clone();
120
+ const max = _.max(unixRange).clone();
129
121
 
130
- return {
131
- success: true,
132
- data: {
133
- config: chartConfig,
134
- data: formattedData
122
+ let currentDate = min;
123
+ while (currentDate.isSameOrBefore(max)) {
124
+ const countForTheTimeframe = repartitionData.find(d => moment(d.key, momentFormat).isSame(currentDate, data.timeframe));
125
+ const value = countForTheTimeframe ? fnHelper.toFixedIfNecessary(countForTheTimeframe.value, 2) : 0;
126
+ formattedData.push({
127
+ key: currentDate.format('YYYY-MM-DD'),
128
+ value
129
+ });
130
+ currentDate.add(1, data.timeframe).startOf('day');
131
+ }
135
132
  }
133
+
134
+ const chartConfig = {
135
+ xaxis: [
136
+ { dataKey: 'key' }
137
+ ],
138
+ yaxis: [
139
+ { dataKey: 'value' }
140
+ ]
141
+ };
142
+
143
+ return {
144
+ success: true,
145
+ data: {
146
+ config: chartConfig,
147
+ data: formattedData
148
+ }
149
+ };
136
150
  };
151
+
152
+ return chartTime;
137
153
  };
@@ -1,89 +1,124 @@
1
1
  const Joi = require('joi');
2
2
 
3
- module.exports = async (currentModel, data) => {
4
- const paramsSchema = Joi.object({
5
- type: Joi.string().required(),
6
- model: Joi.string().required(),
7
- operation: Joi.string().required(),
8
- field: Joi.alternatives().conditional('operation', {
9
- not: 'count',
10
- then: Joi.string().required(),
11
- otherwise: Joi.string()
12
- })
13
- });
3
+ module.exports = _conf => {
4
+ const fnHelper = require('../helpers/functions')(_conf);
14
5
 
15
- // Validate params
16
- const { error } = paramsSchema.validate(data);
17
- if (error) {
18
- return {
19
- success: false,
20
- message: error.details[0].message
21
- };
22
- }
23
-
24
- try {
25
- if (data.operation === 'sum') {
26
- const sumData = await currentModel
27
- .aggregate([{
28
- $group: {
29
- _id: `$${data.group_by}`,
30
- count: {
31
- $sum: `$${data.field}`
32
- }
33
- }
34
- }]);
35
-
36
- if (!sumData || !sumData[0] || typeof sumData[0].count !== 'number') {
37
- return res.status(403).json();
38
- }
6
+ const chartValue = async (currentModel, data) => {
7
+ const paramsSchema = Joi.object({
8
+ type: Joi.string().required(),
9
+ model: Joi.string().required(),
10
+ operation: Joi.string().required(),
11
+ field: Joi.alternatives().conditional('operation', {
12
+ not: 'count',
13
+ then: Joi.string().required(),
14
+ otherwise: Joi.string()
15
+ }),
16
+ filters: Joi.object({
17
+ operator: Joi.string().valid('and', 'or').required(),
18
+ list: Joi.array().required()
19
+ })
20
+ });
39
21
 
22
+ // Validate params
23
+ const { error } = paramsSchema.validate(data);
24
+ if (error) {
40
25
  return {
41
- success: true,
42
- data: {
43
- config: null,
44
- data: sumData[0].count
45
- }
26
+ success: false,
27
+ message: error.details[0].message
46
28
  };
47
29
  }
48
- else if (data.operation === 'avg') {
49
- const avgData = await currentModel
50
- .aggregate([{
51
- $group: {
52
- _id: `$${data.group_by}`,
53
- avg: {
54
- $avg: `$${data.field}`
30
+
31
+ // Filters
32
+ let findParams = {};
33
+ if (data.filters) {
34
+ const filtersQuery = fnHelper.constructQuery(data.filters);
35
+ if (filtersQuery) {
36
+ findParams = filtersQuery;
37
+ }
38
+ }
39
+
40
+ try {
41
+ if (data.operation === 'sum') {
42
+ const sumData = await currentModel
43
+ .aggregate([
44
+ {
45
+ $match: findParams
46
+ },
47
+ {
48
+ $group: {
49
+ _id: null,
50
+ count: {
51
+ $sum: `$${data.field}`
52
+ }
53
+ }
55
54
  }
55
+ ]);
56
+
57
+ if (!sumData || !sumData[0] || typeof sumData[0].count !== 'number') {
58
+ return {
59
+ success: false,
60
+ message: 'An error occurred'
61
+ };
62
+ }
63
+
64
+ return {
65
+ success: true,
66
+ data: {
67
+ config: null,
68
+ data: sumData[0].count
56
69
  }
57
- }]);
70
+ };
71
+ }
72
+ else if (data.operation === 'avg') {
73
+ const avgData = await currentModel
74
+ .aggregate([
75
+ {
76
+ $match: findParams
77
+ },
78
+ {
79
+ $group: {
80
+ _id: null,
81
+ avg: {
82
+ $avg: `$${data.field}`
83
+ }
84
+ }
85
+ }
86
+ ]);
58
87
 
59
- if (!avgData || !avgData[0] || typeof avgData[0].avg !== 'number') {
60
- return res.status(403).json();
88
+ if (!avgData || !avgData[0] || typeof avgData[0].avg !== 'number') {
89
+ return {
90
+ success: false,
91
+ message: 'An error occurred'
92
+ };
93
+ }
94
+
95
+ return {
96
+ success: true,
97
+ data: {
98
+ config: null,
99
+ data: avgData[0].avg
100
+ }
101
+ };
61
102
  }
62
103
 
104
+ // Simple count
105
+ const dataCount = await currentModel.countDocuments(findParams);
106
+
63
107
  return {
64
108
  success: true,
65
109
  data: {
66
110
  config: null,
67
- data: avgData[0].avg
111
+ data: dataCount
68
112
  }
69
113
  };
70
114
  }
115
+ catch(e) {
116
+ return {
117
+ success: false,
118
+ message: e.message
119
+ };
120
+ }
121
+ };
71
122
 
72
- // Simple count
73
- const dataCount = await currentModel.countDocuments({});
74
-
75
- return {
76
- success: true,
77
- data: {
78
- config: null,
79
- data: dataCount
80
- }
81
- };
82
- }
83
- catch(e) {
84
- return {
85
- success: false,
86
- message: e.message
87
- };
88
- }
89
- };
123
+ return chartValue;
124
+ };
@@ -1,48 +1,53 @@
1
1
  const _ = require('lodash');
2
- const fnHelper = require('../helpers/functions');
3
-
4
- module.exports.getAutocomplete = async (req, res) => {
5
- const modelName = req.params.model;
6
- const search = (req.query.s || '').trim();
7
- const refFields = req.headers['am-ref-fields'] || {};
8
- const maxItem = 10;
9
-
10
- const currentModel = fnHelper.getModelObject(modelName);
11
- if (!currentModel || !search) {
12
- return res.status(403).json({ message: 'Invalid request' });
13
- }
14
-
15
- const keys = fnHelper.getModelProperties(currentModel);
16
- const defaultFieldsToSearchIn = keys.filter(key => ['String'].includes(key.type)).map(key => key.path);
17
- const defaultFieldsToFetch = keys.filter(key => !key.path.includes('.')).map(key => key.path);
18
-
19
- const fieldsToSearchIn = refFields[modelName] ? refFields[modelName].split(' ') : defaultFieldsToSearchIn;
20
- const fieldsToFetch = refFields[modelName] ? refFields[modelName].split(' ') : defaultFieldsToFetch;
21
- const params = fnHelper.constructSearch(search, fieldsToSearchIn);
22
-
23
- const data = await currentModel
24
- .find(params)
25
- .select(fieldsToFetch)
26
- // .sort()
27
- .limit(maxItem)
28
- .lean()
29
- .catch(e => {
30
- res.status(403).json({ message: e.message });
31
- });
32
-
33
- if (!data) {
34
- return res.status(403).json();
35
- }
36
-
37
- let formattedData = [];
38
- if (data.length) {
39
- // Field to be used for the item label
40
- const fieldsToDisplay = refFields[modelName] ? refFields[modelName] : '_id';
41
- formattedData = data.map(d => {
42
- const label = fieldsToDisplay.replace(/[a-z._]+/gi, word => _.get(d, word));
43
- return { label, value: d._id };
44
- });
45
- }
46
-
47
- res.json({ data: formattedData });
48
- };
2
+
3
+ module.exports = _conf => {
4
+ const fnHelper = require('../helpers/functions')(_conf);
5
+
6
+ const getAutocomplete = async (req, res) => {
7
+ const modelName = req.params.model;
8
+ const search = (req.query.s || '').trim();
9
+ const refFields = req.headers['am-ref-fields'] || {};
10
+ const maxItem = 10;
11
+
12
+ const currentModel = fnHelper.getModelObject(modelName);
13
+ if (!currentModel || !search) {
14
+ return res.status(403).json({ message: 'Invalid request' });
15
+ }
16
+
17
+ const keys = fnHelper.getModelProperties(currentModel);
18
+ const defaultFieldsToSearchIn = keys.filter(key => ['String'].includes(key.type)).map(key => key.path);
19
+ const defaultFieldsToFetch = keys.filter(key => !key.path.includes('.')).map(key => key.path);
20
+
21
+ const fieldsToSearchIn = refFields[modelName] ? refFields[modelName].split(' ') : defaultFieldsToSearchIn;
22
+ const fieldsToFetch = refFields[modelName] ? refFields[modelName].split(' ') : defaultFieldsToFetch;
23
+ const params = fnHelper.constructSearch(search, fieldsToSearchIn);
24
+
25
+ const data = await currentModel
26
+ .find(params)
27
+ .select(fieldsToFetch)
28
+ // .sort()
29
+ .limit(maxItem)
30
+ .lean()
31
+ .catch(e => {
32
+ res.status(403).json({ message: e.message });
33
+ });
34
+
35
+ if (!data) {
36
+ return res.status(403).json();
37
+ }
38
+
39
+ let formattedData = [];
40
+ if (data.length) {
41
+ // Field to be used for the item label
42
+ const fieldsToDisplay = refFields[modelName] ? refFields[modelName] : '_id';
43
+ formattedData = data.map(d => {
44
+ const label = fieldsToDisplay.replace(/[a-z._]+/gi, word => _.get(d, word));
45
+ return { label, value: d._id };
46
+ });
47
+ }
48
+
49
+ res.json({ data: formattedData });
50
+ };
51
+
52
+ return getAutocomplete;
53
+ };
@@ -1,23 +1,26 @@
1
- const _ = require('lodash');
2
- const fnHelper = require('../helpers/functions');
1
+ module.exports = _conf => {
2
+ const fnHelper = require('../helpers/functions')(_conf);
3
3
 
4
- module.exports.deleteSome = async (req, res) => {
5
- const modelName = req.params.model;
6
- const itemIds = req.body.ids;
4
+ const deleteSome = async (req, res) => {
5
+ const modelName = req.params.model;
6
+ const itemIds = req.body.ids;
7
7
 
8
- if (!itemIds || !itemIds.length) {
9
- return res.status(403).json({ message: 'Invalid request' });
10
- }
8
+ if (!itemIds || !itemIds.length) {
9
+ return res.status(403).json({ message: 'Invalid request' });
10
+ }
11
11
 
12
- const currentModel = fnHelper.getModelObject(modelName);
13
- if (!currentModel) {
14
- return res.status(403).json({ message: 'Invalid request' });
15
- }
12
+ const currentModel = fnHelper.getModelObject(modelName);
13
+ if (!currentModel) {
14
+ return res.status(403).json({ message: 'Invalid request' });
15
+ }
16
16
 
17
- const deleteReq = await currentModel.deleteMany({ _id: { $in: itemIds }})
18
- .catch(e => {
19
- res.status(403).json({ message: 'Unable to delete the model items' });
20
- });
17
+ const deleteReq = await currentModel.deleteMany({ _id: { $in: itemIds }})
18
+ .catch(e => {
19
+ res.status(403).json({ message: 'Unable to delete the model items' });
20
+ });
21
21
 
22
- res.json({ deletedCount: deleteReq.deletedCount });
23
- };
22
+ res.json({ deletedCount: deleteReq.deletedCount });
23
+ };
24
+
25
+ return deleteSome;
26
+ };