@go-mailer/jarvis 3.2.1 → 3.2.3

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/lib/query.js CHANGED
@@ -2,14 +2,15 @@ const buildQuery = (options) => {
2
2
  const sort_condition = options.sort_by ? buildSortOrderString(options.sort_by) : ''
3
3
  const fields_to_return = options.return_only ? buildReturnFieldsString(options.return_only) : ''
4
4
  const count = options.count || false
5
- const seek_conditions = options.bool ? { ...buildBooleanQuery(options.bool || '')} : {}
6
- const group_by = options.group_by ? cleanGroupBy(options.group_by) : null
5
+ const seek_conditions = options.bool ? { ...buildBooleanQuery(options.bool || '') } : {}
6
+ const group_by = options.group_by || null
7
7
 
8
8
  const { skip, limit } = determinePagination(options.page, options.population)
9
9
 
10
10
  /** Delete sort and return fields */
11
11
  delete options.bool
12
12
  delete options.count
13
+ delete options.group_by
13
14
  delete options.page
14
15
  delete options.population
15
16
  delete options.return_only
@@ -32,9 +33,21 @@ const buildQuery = (options) => {
32
33
  seek_conditions[field] = { ...condition }
33
34
  })
34
35
 
36
+ let pipeline = []
37
+ if (group_by) {
38
+ pipeline = generatePipeline({
39
+ group_by,
40
+ seek_conditions,
41
+ fields_to_return,
42
+ sort_condition,
43
+ skip,
44
+ limit
45
+ })
46
+ }
47
+
35
48
  return {
36
49
  count,
37
- group_by,
50
+ pipeline,
38
51
  fields_to_return,
39
52
  limit,
40
53
  seek_conditions,
@@ -52,7 +65,7 @@ const buildBooleanQuery = (value) => {
52
65
  truthiness = false
53
66
  key = val.substr(1)
54
67
  }
55
-
68
+
56
69
  return {
57
70
  ...sac,
58
71
  [key]: truthiness
@@ -110,12 +123,6 @@ const buildWildcardOptions = (key_list, value) => {
110
123
  }
111
124
  }
112
125
 
113
- const cleanGroupBy = (value) => {
114
- if (!value || typeof value !== string) return null
115
-
116
- return value.split(',')[0]
117
- }
118
-
119
126
  const determinePagination = (page = 0, population = Number.MAX_SAFE_INTEGER) => {
120
127
  return {
121
128
  limit: Number(population),
@@ -123,6 +130,68 @@ const determinePagination = (page = 0, population = Number.MAX_SAFE_INTEGER) =>
123
130
  }
124
131
  }
125
132
 
133
+ const generateGroupPipeline = ({ group_by, seek_conditions, sort_condition, skip, limit, fields_to_return, count }) => {
134
+ if (!group_by || typeof group_by !== 'string') return null
135
+
136
+ const pipeline = []
137
+ const group_field = group_by.split(',')[0]
138
+
139
+ pipeline.push({
140
+ $match: { ...seek_conditions }
141
+ })
142
+
143
+ if (skip) {
144
+ pipeline.push({
145
+ $skip: { skip }
146
+ })
147
+ }
148
+
149
+ if (limit) {
150
+ pipeline.push({
151
+ $limit: { limit }
152
+ })
153
+ }
154
+
155
+ if (sort_condition){
156
+ const sort_options = sort_condition.split(' ').reduce((sac, condition) => {
157
+ let key = condition
158
+ let value = 1
159
+ if (key.includes('-')) {
160
+ key = key.split('-')[1]
161
+ value = -1
162
+ }
163
+
164
+ return { ...sac, [key]: value }
165
+ }, {})
166
+
167
+ pipeline.push({
168
+ $sort: { ...sort_options }
169
+ })
170
+ }
171
+
172
+ if (fields_to_return){
173
+ const projection_options = fields_to_return.split(' ').reduce((sac, condition) => ({ ...sac, [condition]: 1 }), {})
174
+
175
+ pipeline.push({
176
+ $project: { ...projection_options }
177
+ })
178
+ }
179
+
180
+ pipeline.push({
181
+ $group: {
182
+ _id: { group_field: `$${group_field}`}
183
+ }
184
+ })
185
+
186
+ if (count) {
187
+ pipeline.push({
188
+ $count: "size"
189
+ })
190
+ }
191
+
192
+ return pipeline
193
+ }
194
+
126
195
  module.exports = {
127
196
  buildInQuery,
128
197
  buildNorQuery,
@@ -132,5 +201,6 @@ module.exports = {
132
201
  buildReturnFieldsString,
133
202
  buildSortOrderString,
134
203
  buildWildcardOptions,
135
- determinePagination
204
+ determinePagination,
205
+ generateGroupPipeline
136
206
  }
package/package.json CHANGED
@@ -1,10 +1,13 @@
1
1
  {
2
2
  "name": "@go-mailer/jarvis",
3
- "version": "3.2.1",
3
+ "version": "3.2.3",
4
4
  "main": "index.js",
5
5
  "repository": "git@github.com:go-mailer-ltd/jarvis-node.git",
6
6
  "author": "Nathan Oguntuberu <nateoguns.work@gmail.com>",
7
7
  "license": "MIT",
8
+ "scripts": {
9
+ "test": "mocha --recursive -w -c || true"
10
+ },
8
11
  "dependencies": {
9
12
  "@logtail/node": "^0.3.3",
10
13
  "axios": "^1.3.4",
@@ -0,0 +1,46 @@
1
+ /** */
2
+ const { expect } = require('chai')
3
+ const { generateGroupPipeline } = require('../lib/query')
4
+
5
+ describe('Query Processor', () => {
6
+
7
+ describe('Requests: Group By', () => {
8
+ it('should return `null` when the group_by keyword is not used.', () => {
9
+ const pipeline = generateGroupPipeline({ name: 'test name' })
10
+ expect(pipeline).to.be.null
11
+ })
12
+
13
+ it('create the correct pipeline with only `group_by` specified', () => {
14
+ const group_by = 'age'
15
+ const pipeline = generateGroupPipeline({ group_by })
16
+ expect(pipeline).to.deep.include({ $group: { _id: { group_field: `$${group_by}` } } })
17
+ })
18
+
19
+ it('create the correct pipeline with `seek_conditions` specified', () => {
20
+ const group_by = 'age'
21
+ const seek_conditions = { status: 'active' }
22
+ const pipeline = generateGroupPipeline({ group_by, seek_conditions })
23
+ expect(pipeline).to.deep.include({ $match: seek_conditions })
24
+ })
25
+
26
+ it('create the correct pipeline with `sort_conditions` specified', () => {
27
+ const group_by = 'age'
28
+ const sort_condition = '-created_on age'
29
+ const pipeline = generateGroupPipeline({ group_by, sort_condition })
30
+ expect(pipeline).to.deep.include({ $sort: { created_on: -1, age: 1 } })
31
+ })
32
+
33
+ it('create the correct pipeline with only `fields_to_return` specified', () => {
34
+ const group_by = 'age'
35
+ const fields_to_return = 'age name'
36
+ const pipeline = generateGroupPipeline({ group_by, fields_to_return })
37
+ expect(pipeline).to.deep.include({ $project: { age: 1, name: 1 } })
38
+ })
39
+
40
+ it('create the correct pipeline with only `count` specified', () => {
41
+ const group_by = 'age'
42
+ const pipeline = generateGroupPipeline({ group_by, count: true })
43
+ expect(pipeline).to.deep.include({ $count: 'size' })
44
+ })
45
+ })
46
+ })