@6thbridge/utils 1.5.5 → 1.6.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.
@@ -8,6 +8,7 @@ export declare class ObjectToMongoDBQueryOption {
8
8
  dateFormat?: string | string[];
9
9
  searchFields?: string[];
10
10
  enableParentClientSearch?: boolean;
11
+ populate?: string[];
11
12
  }
12
13
  export declare class ObjectToMongoDBQueryResult {
13
14
  page?: number;
@@ -15,6 +16,7 @@ export declare class ObjectToMongoDBQueryResult {
15
16
  expand?: string[];
16
17
  filter: any;
17
18
  sort: any;
19
+ populate?: Record<string, number>;
18
20
  }
19
21
  export declare class DatabaseUtil {
20
22
  static resolveObjectToMongoDBQuery(requestQuery: Record<string, any>, options?: ObjectToMongoDBQueryOption): ObjectToMongoDBQueryResult;
@@ -12,6 +12,7 @@ const DEFAULT_QUERY_OPTIONS = {
12
12
  dateField: 'createdAt',
13
13
  dateFormat: ['X', 'YYYY-MM-DD', 'YYYY-MM-DDTHH:mm:ss.SSSZ', 'DD-MM-YYYY'],
14
14
  enableParentClientSearch: false,
15
+ populate: [],
15
16
  };
16
17
  /**
17
18
  * @description resolveRequestQueryToMongoDBQuery
@@ -23,6 +24,7 @@ class ObjectToMongoDBQueryOption {
23
24
  this.dateField = 'createdAt';
24
25
  this.dateFormat = ['X', "YYYY-MM-DD", "YYYY-MM-DDTHH:mm:ss.SSSZ", "DD-MM-YYYY"];
25
26
  this.enableParentClientSearch = false;
27
+ this.populate = [];
26
28
  }
27
29
  }
28
30
  exports.ObjectToMongoDBQueryOption = ObjectToMongoDBQueryOption;
@@ -32,6 +34,7 @@ class ObjectToMongoDBQueryResult {
32
34
  this.limit = 50;
33
35
  this.filter = {};
34
36
  this.sort = { _id: -1 };
37
+ this.populate = {};
35
38
  }
36
39
  }
37
40
  exports.ObjectToMongoDBQueryResult = ObjectToMongoDBQueryResult;
@@ -56,7 +59,7 @@ const addOrFilterGroup = (filter, conditions) => {
56
59
  };
57
60
  class DatabaseUtil {
58
61
  static resolveObjectToMongoDBQuery(requestQuery, options) {
59
- var _a, _b;
62
+ var _a, _b, _c;
60
63
  const resolvedOptions = Object.assign(Object.assign({}, DEFAULT_QUERY_OPTIONS), options);
61
64
  const response = {
62
65
  page: 1,
@@ -64,6 +67,7 @@ class DatabaseUtil {
64
67
  filter: {},
65
68
  expand: [],
66
69
  sort: { _id: -1 },
70
+ populate: undefined,
67
71
  };
68
72
  for (const key of Object.keys(requestQuery)) {
69
73
  if (key === 'page') {
@@ -113,6 +117,12 @@ class DatabaseUtil {
113
117
  }
114
118
  response.filter[key] = requestQuery[key];
115
119
  }
120
+ if ((_c = resolvedOptions.populate) === null || _c === void 0 ? void 0 : _c.length) {
121
+ response.populate = {};
122
+ for (const populate of resolvedOptions.populate) {
123
+ response.populate[populate] = 1;
124
+ }
125
+ }
116
126
  return response;
117
127
  }
118
128
  }
@@ -1 +1 @@
1
- {"version":3,"file":"database.js","sourceRoot":"","sources":["../../src/utils/database.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"database.js","sourceRoot":"","sources":["../../src/utils/database.ts"],"names":[],"mappings":"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"}
@@ -3,277 +3,270 @@ 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 database_1 = require("./database");
7
6
  const dayjs_1 = __importDefault(require("dayjs"));
8
- // Mock the dependencies
9
- // jest.mock('../helpers', () => ({
10
- // dayjs: jest.fn().mockImplementation((date, format) => {
11
- // const mockDayjs = {
12
- // startOf: jest.fn().mockReturnThis(),
13
- // endOf: jest.fn().mockReturnThis(),
14
- // toDate: jest.fn().mockReturnValue(new Date(date))
15
- // };
16
- // return mockDayjs;
17
- // })
18
- // }));
19
- describe('DatabaseAction', () => {
20
- describe('resolveObjectToMongoDBQuery', () => {
21
- afterEach(() => {
22
- jest.clearAllMocks();
23
- });
24
- it('should return default values when empty request query is provided', () => {
25
- const requestQuery = {};
26
- const result = database_1.DatabaseUtil.resolveObjectToMongoDBQuery(requestQuery);
27
- expect(result).toEqual({
7
+ const customParseFormat_1 = __importDefault(require("dayjs/plugin/customParseFormat"));
8
+ const database_1 = require("./database");
9
+ dayjs_1.default.extend(customParseFormat_1.default);
10
+ const expectRegex = (value, source, flags = 'gi') => {
11
+ expect(value).toBeInstanceOf(RegExp);
12
+ expect(value.source).toBe(source);
13
+ expect(value.flags).toBe(flags);
14
+ };
15
+ const expectDayBounds = (value, expected, format = 'DD-MM-YYYY', bound = 'startOf') => {
16
+ const expectedDate = (0, dayjs_1.default)(expected, format)[bound]('day').toDate();
17
+ expect(value).toEqual(expectedDate);
18
+ };
19
+ describe('DatabaseUtil.resolveObjectToMongoDBQuery', () => {
20
+ describe('base query controls', () => {
21
+ it('returns the default query shape for an empty request query', () => {
22
+ expect(database_1.DatabaseUtil.resolveObjectToMongoDBQuery({})).toEqual({
28
23
  page: 1,
29
24
  limit: 50,
30
25
  filter: {},
31
26
  expand: [],
32
- sort: { _id: -1 }
27
+ sort: { _id: -1 },
28
+ populate: undefined,
33
29
  });
34
30
  });
35
- it('should use default options when options parameter is not provided', () => {
36
- const requestQuery = { dateFrom: '01-01-2023', dateTo: '31-01-2023' };
37
- const result = database_1.DatabaseUtil.resolveObjectToMongoDBQuery(requestQuery);
38
- expect(result.filter.createdAt).toBeDefined();
39
- });
40
- it('should parse page and limit parameters correctly', () => {
41
- const requestQuery = { page: '2', limit: '25' };
42
- const result = database_1.DatabaseUtil.resolveObjectToMongoDBQuery(requestQuery);
43
- expect(result.page).toBe(2);
44
- expect(result.limit).toBe(25);
45
- });
46
- it('should handle non-numeric page and limit parameters', () => {
47
- const requestQuery = { page: 'abc', limit: 'xyz' };
48
- const result = database_1.DatabaseUtil.resolveObjectToMongoDBQuery(requestQuery);
49
- expect(result.page).toBe(NaN);
50
- expect(result.limit).toBe(NaN);
51
- });
52
- it('should parse sort parameters correctly with provided sortValue', () => {
53
- const requestQuery = { sort: 'name,1' };
54
- const result = database_1.DatabaseUtil.resolveObjectToMongoDBQuery(requestQuery);
55
- expect(result.sort).toEqual({ name: '1' });
31
+ it('parses page, limit, sort, and expand controls without adding them to the filter', () => {
32
+ const result = database_1.DatabaseUtil.resolveObjectToMongoDBQuery({
33
+ page: '2',
34
+ limit: '25',
35
+ sort: 'createdAt,1',
36
+ expand: 'author,comments',
37
+ });
38
+ expect(result).toMatchObject({
39
+ page: 2,
40
+ limit: 25,
41
+ sort: { createdAt: '1' },
42
+ expand: ['author', 'comments'],
43
+ filter: {},
44
+ });
56
45
  });
57
- it('should parse sort parameters correctly with default sortValue', () => {
58
- const requestQuery = { sort: 'name' };
59
- const result = database_1.DatabaseUtil.resolveObjectToMongoDBQuery(requestQuery);
46
+ it('uses descending sort when only a sort field is provided', () => {
47
+ const result = database_1.DatabaseUtil.resolveObjectToMongoDBQuery({ sort: 'name' });
60
48
  expect(result.sort).toEqual({ name: -1 });
61
49
  });
62
- it('should handle expand parameter correctly', () => {
63
- const requestQuery = { expand: 'user,profile,settings' };
64
- const result = database_1.DatabaseUtil.resolveObjectToMongoDBQuery(requestQuery);
65
- expect(result.expand).toEqual(['user', 'profile', 'settings']);
50
+ it('keeps parseInt results for invalid numeric controls', () => {
51
+ const result = database_1.DatabaseUtil.resolveObjectToMongoDBQuery({
52
+ page: 'not-a-page',
53
+ limit: 'not-a-limit',
54
+ });
55
+ expect(result.page).toBeNaN();
56
+ expect(result.limit).toBeNaN();
66
57
  });
67
- it('should handle empty expand parameter', () => {
68
- const requestQuery = { expand: '' };
69
- const result = database_1.DatabaseUtil.resolveObjectToMongoDBQuery(requestQuery);
58
+ it('splits an empty expand value using native string split behavior', () => {
59
+ const result = database_1.DatabaseUtil.resolveObjectToMongoDBQuery({ expand: '' });
70
60
  expect(result.expand).toEqual(['']);
71
61
  });
72
- it('should handle dateFrom parameter correctly', () => {
73
- const requestQuery = { dateFrom: '01-01-2023' };
74
- const result = database_1.DatabaseUtil.resolveObjectToMongoDBQuery(requestQuery);
75
- expect(result.filter.createdAt.$gte).toEqual(new Date('01-01-2023'));
62
+ });
63
+ describe('date filters', () => {
64
+ it('adds dateFrom as an inclusive start-of-day lower bound on createdAt by default', () => {
65
+ const result = database_1.DatabaseUtil.resolveObjectToMongoDBQuery({ dateFrom: '01-01-2023' });
66
+ expectDayBounds(result.filter.createdAt.$gte, '01-01-2023');
67
+ expect(result.filter.createdAt.$lte).toBeUndefined();
68
+ });
69
+ it('adds dateTo as an inclusive end-of-day upper bound on createdAt by default', () => {
70
+ const result = database_1.DatabaseUtil.resolveObjectToMongoDBQuery({ dateTo: '31-01-2023' });
71
+ expect(result.filter.createdAt.$gte).toBeUndefined();
72
+ expectDayBounds(result.filter.createdAt.$lte, '31-01-2023', 'DD-MM-YYYY', 'endOf');
76
73
  });
77
- it('should handle dateTo parameter correctly', () => {
78
- const requestQuery = { dateTo: '31-01-2023' };
79
- const result = database_1.DatabaseUtil.resolveObjectToMongoDBQuery(requestQuery);
80
- expect(result.filter.createdAt.$lte).toEqual((0, dayjs_1.default)(requestQuery.dateTo, 'DD-MM-YYYY').endOf('day').toDate());
74
+ it('combines dateFrom and dateTo on the same date field', () => {
75
+ const result = database_1.DatabaseUtil.resolveObjectToMongoDBQuery({
76
+ dateFrom: '01-01-2023',
77
+ dateTo: '31-01-2023',
78
+ });
79
+ expectDayBounds(result.filter.createdAt.$gte, '01-01-2023');
80
+ expectDayBounds(result.filter.createdAt.$lte, '31-01-2023', 'DD-MM-YYYY', 'endOf');
81
81
  });
82
- it('should handle both dateFrom and dateTo parameters correctly', () => {
83
- const requestQuery = { dateFrom: '01-01-2023', dateTo: '31-01-2023' };
84
- const result = database_1.DatabaseUtil.resolveObjectToMongoDBQuery(requestQuery);
85
- expect(result.filter.createdAt.$gte).toEqual((0, dayjs_1.default)(requestQuery.dateFrom, 'DD-MM-YYYY').startOf('day').toDate());
86
- expect(result.filter.createdAt.$lte).toEqual((0, dayjs_1.default)(requestQuery.dateTo, 'DD-MM-YYYY').endOf('day').toDate());
82
+ it('uses a custom date field when provided', () => {
83
+ const result = database_1.DatabaseUtil.resolveObjectToMongoDBQuery({
84
+ dateFrom: '01-01-2023',
85
+ dateTo: '31-01-2023',
86
+ }, { dateField: 'updatedAt' });
87
+ expect(result.filter.createdAt).toBeUndefined();
88
+ expectDayBounds(result.filter.updatedAt.$gte, '01-01-2023');
89
+ expectDayBounds(result.filter.updatedAt.$lte, '31-01-2023', 'DD-MM-YYYY', 'endOf');
87
90
  });
88
- it('should use custom dateField from options', () => {
89
- const requestQuery = { dateFrom: '01-01-2023', dateTo: '31-01-2023' };
90
- const options = { dateField: 'updatedAt' };
91
- const result = database_1.DatabaseUtil.resolveObjectToMongoDBQuery(requestQuery, options);
92
- expect(result.filter.updatedAt.$gte).toEqual((0, dayjs_1.default)(requestQuery.dateFrom, 'DD-MM-YYYY').startOf('day').toDate());
93
- expect(result.filter.updatedAt.$lte).toEqual((0, dayjs_1.default)(requestQuery.dateTo, 'DD-MM-YYYY').endOf('day').toDate());
91
+ it('uses a custom date format when provided', () => {
92
+ const options = { dateFormat: 'YYYY/MM/DD' };
93
+ const result = database_1.DatabaseUtil.resolveObjectToMongoDBQuery({
94
+ dateFrom: '2023/01/01',
95
+ dateTo: '2023/01/31',
96
+ }, options);
97
+ expectDayBounds(result.filter.createdAt.$gte, '2023/01/01', options.dateFormat);
98
+ expectDayBounds(result.filter.createdAt.$lte, '2023/01/31', options.dateFormat, 'endOf');
94
99
  });
95
- it('should use custom dateFormat from options', () => {
96
- const requestQuery = { dateFrom: '2023-01-01', dateTo: '2023-01-31' };
97
- const options = { dateFormat: 'YYYY-MM-DD' };
98
- const result = database_1.DatabaseUtil.resolveObjectToMongoDBQuery(requestQuery, options);
100
+ it.each([
101
+ ['unix timestamp seconds', '1672531200'],
102
+ ['ISO date', '2023-01-01'],
103
+ ['ISO timestamp with offset', '2023-01-01T13:30:00.000+00:00'],
104
+ ['DD-MM-YYYY date', '01-01-2023'],
105
+ ])('parses the default %s date format', (_label, dateFrom) => {
106
+ const result = database_1.DatabaseUtil.resolveObjectToMongoDBQuery({ dateFrom });
107
+ expect(result.filter.createdAt.$gte).toBeInstanceOf(Date);
108
+ expect(result.filter.createdAt.$gte.toString()).not.toBe('Invalid Date');
99
109
  });
100
- it('should ignore empty dateFrom and dateTo parameters', () => {
101
- const requestQuery = { dateFrom: '', dateTo: '' };
102
- const result = database_1.DatabaseUtil.resolveObjectToMongoDBQuery(requestQuery);
110
+ it('ignores empty date boundaries', () => {
111
+ const result = database_1.DatabaseUtil.resolveObjectToMongoDBQuery({
112
+ dateFrom: '',
113
+ dateTo: '',
114
+ });
103
115
  expect(result.filter.createdAt).toBeUndefined();
104
116
  });
105
- it('should handle search query with no searchFields', () => {
106
- const requestQuery = { q: 'test-query' };
107
- const result = database_1.DatabaseUtil.resolveObjectToMongoDBQuery(requestQuery);
108
- // Should sanitize the query
109
- const sanitizedQuery = 'testquery';
117
+ });
118
+ describe('search filters', () => {
119
+ it('creates a text search filter when no search fields are configured', () => {
120
+ const result = database_1.DatabaseUtil.resolveObjectToMongoDBQuery({ q: 'test-query' });
110
121
  expect(result.filter.$text).toEqual({
111
122
  $search: expect.any(RegExp),
112
- $caseSensitive: false
123
+ $caseSensitive: false,
113
124
  });
114
- // Check the regex pattern
115
- const regex = result.filter.$text.$search;
116
- expect(regex.source).toBe(sanitizedQuery);
117
- expect(regex.flags).toBe('gi');
125
+ expectRegex(result.filter.$text.$search, 'testquery');
118
126
  });
119
- it('should sanitize special characters from search query', () => {
120
- const requestQuery = { q: '+test-query with $pecial ch@racters!' };
121
- const result = database_1.DatabaseUtil.resolveObjectToMongoDBQuery(requestQuery);
122
- // The sanitized query should only contain alphanumeric characters and spaces
123
- expect(result.filter.$text.$search.source).toBe('testquery with pecial chracters');
127
+ it('sanitizes special characters from text search input', () => {
128
+ const result = database_1.DatabaseUtil.resolveObjectToMongoDBQuery({
129
+ q: '+test-query with $pecial ch@racters!',
130
+ });
131
+ expectRegex(result.filter.$text.$search, 'testquery with pecial chracters');
124
132
  });
125
- it('should handle search query with provided searchFields', () => {
126
- const requestQuery = { q: 'test-query' };
127
- const options = {
128
- searchFields: ['name', 'description', 'tags']
129
- };
130
- const result = database_1.DatabaseUtil.resolveObjectToMongoDBQuery(requestQuery, options);
131
- // Should sanitize the query
132
- const sanitizedQuery = 'testquery';
133
+ it('creates a field search $or group when search fields are configured', () => {
134
+ const result = database_1.DatabaseUtil.resolveObjectToMongoDBQuery({ q: 'Harry Potter' }, { searchFields: ['title', 'description', 'tags'] });
133
135
  expect(result.filter.$or).toEqual([
134
- { name: expect.any(RegExp) },
136
+ { title: expect.any(RegExp) },
135
137
  { description: expect.any(RegExp) },
136
- { tags: expect.any(RegExp) }
138
+ { tags: expect.any(RegExp) },
137
139
  ]);
138
- // Check the regex patterns
139
- result.filter.$or.forEach((item) => {
140
- const field = Object.keys(item)[0];
141
- const regex = item[field];
142
- expect(regex.source).toBe(sanitizedQuery);
143
- expect(regex.flags).toBe('gi');
140
+ result.filter.$or.forEach((condition) => {
141
+ expectRegex(condition[Object.keys(condition)[0]], 'Harry Potter');
144
142
  });
143
+ expect(result.filter.$text).toBeUndefined();
145
144
  });
146
- it('should append to existing $or array when handling search with searchFields', () => {
147
- const requestQuery = { q: 'test-query', status: 'active' };
148
- const existingOr = [{ type: 'special' }];
149
- const options = {
150
- searchFields: ['name']
151
- };
152
- // First add an $or condition
153
- const initialResult = database_1.DatabaseUtil.resolveObjectToMongoDBQuery({ $or: existingOr }, options);
154
- // Then process the search query
155
- const finalResult = database_1.DatabaseUtil.resolveObjectToMongoDBQuery(requestQuery, options);
156
- expect(finalResult.filter.$or.length).toBe(1);
157
- });
158
- it('should add other query parameters to filter directly', () => {
159
- const requestQuery = { status: 'active', category: 'books', isPublished: true };
160
- const result = database_1.DatabaseUtil.resolveObjectToMongoDBQuery(requestQuery);
161
- expect(result.filter.status).toBe('active');
162
- expect(result.filter.category).toBe('books');
163
- expect(result.filter.isPublished).toBe(true);
145
+ it('does not add an $or group for search when searchFields is empty', () => {
146
+ const result = database_1.DatabaseUtil.resolveObjectToMongoDBQuery({ q: 'Harry Potter' }, { searchFields: [] });
147
+ expect(result.filter.$or).toBeUndefined();
148
+ expectRegex(result.filter.$text.$search, 'Harry Potter');
164
149
  });
165
- it('should handle mixed query parameters correctly', () => {
166
- const requestQuery = {
167
- page: '2',
168
- limit: '25',
169
- sort: 'createdAt,-1',
170
- expand: 'author,comments',
171
- dateFrom: '01-01-2023',
172
- dateTo: '31-01-2023',
173
- q: 'Harry Potter',
174
- status: 'published',
175
- category: 'fiction'
176
- };
177
- const options = {
178
- searchFields: ['title', 'description']
179
- };
180
- const result = database_1.DatabaseUtil.resolveObjectToMongoDBQuery(requestQuery, options);
181
- expect(result.page).toBe(2);
182
- expect(result.limit).toBe(25);
183
- expect(result.sort).toEqual({ createdAt: '-1' });
184
- expect(result.expand).toEqual(['author', 'comments']);
185
- expect(result.filter.createdAt.$gte).toEqual((0, dayjs_1.default)(requestQuery.dateFrom, 'DD-MM-YYYY').startOf('day').toDate());
186
- expect(result.filter.createdAt.$lte).toEqual((0, dayjs_1.default)(requestQuery.dateTo, 'DD-MM-YYYY').endOf('day').toDate());
187
- expect(result.filter.$or).toHaveLength(2);
188
- expect(result.filter.status).toBe('published');
189
- expect(result.filter.category).toBe('fiction');
150
+ });
151
+ describe('parent client search', () => {
152
+ it('passes clientId through as a direct filter when parent client search is disabled', () => {
153
+ const result = database_1.DatabaseUtil.resolveObjectToMongoDBQuery({ clientId: 'client-1' });
154
+ expect(result.filter).toEqual({ clientId: 'client-1' });
190
155
  });
191
- it('should handle null or undefined values in request query', () => {
192
- const requestQuery = {
193
- status: null,
194
- category: undefined,
195
- tags: []
196
- };
197
- const result = database_1.DatabaseUtil.resolveObjectToMongoDBQuery(requestQuery);
198
- expect(result.filter.status).toBe(null);
199
- expect(result.filter.category).toBe(undefined);
200
- expect(result.filter.tags).toEqual([]);
156
+ it('expands clientId into clientId or parentClientId when enabled', () => {
157
+ const result = database_1.DatabaseUtil.resolveObjectToMongoDBQuery({ clientId: 'client-1' }, { enableParentClientSearch: true });
158
+ expect(result.filter).toEqual({
159
+ $or: [{ clientId: 'client-1' }, { parentClientId: 'client-1' }],
160
+ });
201
161
  });
202
- });
203
- describe('enableParentClientSearch', () => {
204
- it('should enable search by clientId', () => {
205
- const requestQuery = {
206
- page: '2',
207
- limit: '25',
208
- sort: 'createdAt,-1',
209
- expand: 'author,comments',
210
- dateFrom: '01-01-2023',
211
- dateTo: '31-01-2023',
162
+ it('combines parent client search and field search with $and when q is processed first', () => {
163
+ const result = database_1.DatabaseUtil.resolveObjectToMongoDBQuery({
212
164
  q: 'Harry Potter',
213
- status: 'published',
214
- category: 'fiction',
215
- clientId: '1234567890'
216
- };
217
- const options = {
218
- enableParentClientSearch: true
219
- };
220
- const result = database_1.DatabaseUtil.resolveObjectToMongoDBQuery(requestQuery, options);
221
- expect(result.filter["$or"]).toHaveLength(2);
222
- expect(result.filter["$or"][0]).toEqual({ clientId: "1234567890" });
223
- expect(result.filter["$or"][1]).toEqual({ parentClientId: "1234567890" });
224
- expect(result.filter.clientId).toBe(undefined);
165
+ clientId: 'client-1',
166
+ }, {
167
+ enableParentClientSearch: true,
168
+ searchFields: ['title', 'description'],
169
+ });
170
+ expect(result.filter.$or).toBeUndefined();
171
+ expect(result.filter.$and).toEqual([
172
+ {
173
+ $or: [{ title: expect.any(RegExp) }, { description: expect.any(RegExp) }],
174
+ },
175
+ {
176
+ $or: [{ clientId: 'client-1' }, { parentClientId: 'client-1' }],
177
+ },
178
+ ]);
225
179
  });
226
- it('should combine parent client search and field search without broadening the query', () => {
227
- const requestQuery = {
180
+ it('combines parent client search and field search with $and when clientId is processed first', () => {
181
+ const result = database_1.DatabaseUtil.resolveObjectToMongoDBQuery({
182
+ clientId: 'client-1',
228
183
  q: 'Harry Potter',
229
- clientId: '1234567890'
230
- };
231
- const options = {
184
+ }, {
232
185
  enableParentClientSearch: true,
233
- searchFields: ['title', 'description']
234
- };
235
- const result = database_1.DatabaseUtil.resolveObjectToMongoDBQuery(requestQuery, options);
186
+ searchFields: ['title', 'description'],
187
+ });
236
188
  expect(result.filter.$or).toBeUndefined();
237
189
  expect(result.filter.$and).toEqual([
238
190
  {
239
- $or: [
240
- { title: expect.any(RegExp) },
241
- { description: expect.any(RegExp) }
242
- ]
191
+ $or: [{ clientId: 'client-1' }, { parentClientId: 'client-1' }],
243
192
  },
244
193
  {
245
- $or: [
246
- { clientId: '1234567890' },
247
- { parentClientId: '1234567890' }
248
- ]
249
- }
194
+ $or: [{ title: expect.any(RegExp) }, { description: expect.any(RegExp) }],
195
+ },
250
196
  ]);
251
197
  });
252
- it('should combine parent client search and field search consistently regardless of query order', () => {
253
- const requestQuery = {
254
- clientId: '1234567890',
255
- q: 'Harry Potter'
256
- };
257
- const options = {
198
+ it('appends additional $or groups to an existing $and group', () => {
199
+ const result = database_1.DatabaseUtil.resolveObjectToMongoDBQuery({
200
+ clientId: 'client-1',
201
+ q: 'Harry Potter',
202
+ accountId: 'account-1',
203
+ }, {
258
204
  enableParentClientSearch: true,
259
- searchFields: ['title', 'description']
260
- };
261
- const result = database_1.DatabaseUtil.resolveObjectToMongoDBQuery(requestQuery, options);
262
- expect(result.filter.$or).toBeUndefined();
205
+ searchFields: ['title'],
206
+ });
263
207
  expect(result.filter.$and).toEqual([
264
208
  {
265
- $or: [
266
- { clientId: '1234567890' },
267
- { parentClientId: '1234567890' }
268
- ]
209
+ $or: [{ clientId: 'client-1' }, { parentClientId: 'client-1' }],
269
210
  },
270
211
  {
271
- $or: [
272
- { title: expect.any(RegExp) },
273
- { description: expect.any(RegExp) }
274
- ]
275
- }
212
+ $or: [{ title: expect.any(RegExp) }],
213
+ },
276
214
  ]);
215
+ expect(result.filter.accountId).toBe('account-1');
216
+ });
217
+ });
218
+ describe('populate and direct filters', () => {
219
+ it('maps configured populate fields to include flags', () => {
220
+ const result = database_1.DatabaseUtil.resolveObjectToMongoDBQuery({}, { populate: ['client', 'wallet'] });
221
+ expect(result.populate).toEqual({
222
+ client: 1,
223
+ wallet: 1,
224
+ });
225
+ });
226
+ it('passes unreserved query parameters through to the filter unchanged', () => {
227
+ const result = database_1.DatabaseUtil.resolveObjectToMongoDBQuery({
228
+ status: 'active',
229
+ category: undefined,
230
+ isPublished: true,
231
+ metadata: { source: 'api' },
232
+ tags: [],
233
+ });
234
+ expect(result.filter).toEqual({
235
+ status: 'active',
236
+ category: undefined,
237
+ isPublished: true,
238
+ metadata: { source: 'api' },
239
+ tags: [],
240
+ });
241
+ });
242
+ it('resolves a mixed request query', () => {
243
+ const result = database_1.DatabaseUtil.resolveObjectToMongoDBQuery({
244
+ page: '2',
245
+ limit: '25',
246
+ sort: 'createdAt,-1',
247
+ expand: 'author,comments',
248
+ dateFrom: '01-01-2023',
249
+ dateTo: '31-01-2023',
250
+ q: 'Harry Potter',
251
+ status: 'published',
252
+ category: 'fiction',
253
+ }, {
254
+ searchFields: ['title', 'description'],
255
+ populate: ['author'],
256
+ });
257
+ expect(result.page).toBe(2);
258
+ expect(result.limit).toBe(25);
259
+ expect(result.sort).toEqual({ createdAt: '-1' });
260
+ expect(result.expand).toEqual(['author', 'comments']);
261
+ expectDayBounds(result.filter.createdAt.$gte, '01-01-2023');
262
+ expectDayBounds(result.filter.createdAt.$lte, '31-01-2023', 'DD-MM-YYYY', 'endOf');
263
+ expect(result.filter.$or).toEqual([
264
+ { title: expect.any(RegExp) },
265
+ { description: expect.any(RegExp) },
266
+ ]);
267
+ expect(result.filter.status).toBe('published');
268
+ expect(result.filter.category).toBe('fiction');
269
+ expect(result.populate).toEqual({ author: 1 });
277
270
  });
278
271
  });
279
272
  });