@flowerforce/flowerbase 1.7.0 → 1.7.2-beta.0

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/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ ## 1.7.1 (2026-02-04)
2
+
3
+
4
+ ### 🩹 Fixes
5
+
6
+ - add missing deps ([b7a0f42](https://github.com/flowerforce/flowerbase/commit/b7a0f42))
7
+
1
8
  ## 1.7.0 (2026-02-04)
2
9
 
3
10
 
@@ -15,6 +15,7 @@ export declare const executeQuery: ({ currentMethod, query, update, filter, proj
15
15
  find: () => Promise<any[]>;
16
16
  findOne: () => Promise<unknown>;
17
17
  count: () => Promise<number>;
18
+ countDocuments: () => Promise<number>;
18
19
  deleteOne: () => Promise<import("mongodb").DeleteResult>;
19
20
  insertOne: () => Promise<import("mongodb").InsertOneResult<Document>>;
20
21
  updateOne: () => Promise<unknown> | import("mongodb").FindCursor<any> | import("mongodb").ChangeStream<Document, Document> | import("mongodb").AggregationCursor<Document>;
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/features/functions/utils.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAGlC,OAAO,EAAE,kBAAkB,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAE3D;;;GAGG;AACH,eAAO,MAAM,aAAa,GAAU,gBAAuB,KAAG,OAAO,CAAC,SAAS,CAwB9E,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,YAAY,GAAU,2HAYhC,kBAAkB;;;;;;;;;;;;EA4FpB,CAAA"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/features/functions/utils.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAGlC,OAAO,EAAE,kBAAkB,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAE3D;;;GAGG;AACH,eAAO,MAAM,aAAa,GAAU,gBAAuB,KAAG,OAAO,CAAC,SAAS,CAwB9E,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,YAAY,GAAU,2HAYhC,kBAAkB;;;;;;;;;;;;;EAiGpB,CAAA"}
@@ -97,6 +97,7 @@ const executeQuery = (_a) => __awaiter(void 0, [_a], void 0, function* ({ curren
97
97
  }),
98
98
  findOne: () => currentMethod(bson_1.EJSON.deserialize(resolvedQuery), resolvedProjection, parsedOptions),
99
99
  count: () => currentMethod(bson_1.EJSON.deserialize(resolvedQuery), parsedOptions),
100
+ countDocuments: () => currentMethod(bson_1.EJSON.deserialize(resolvedQuery), parsedOptions),
100
101
  deleteOne: () => currentMethod(bson_1.EJSON.deserialize(resolvedQuery), parsedOptions),
101
102
  insertOne: () => currentMethod(bson_1.EJSON.deserialize(document)),
102
103
  updateOne: () => currentMethod(bson_1.EJSON.deserialize(resolvedQuery), bson_1.EJSON.deserialize(resolvedUpdate)),
@@ -44,7 +44,7 @@ const activateTriggers = (_a) => __awaiter(void 0, [_a], void 0, function* ({ fa
44
44
  triggersToActivate.push({
45
45
  fileName: '__auto_on_user_creation_trigger__.json',
46
46
  content: {
47
- name: 'onUserCreation',
47
+ name: constants_1.AUTH_CONFIG.on_user_creation_function_name,
48
48
  type: 'AUTHENTICATION',
49
49
  disabled: false,
50
50
  config: {
@@ -1 +1 @@
1
- {"version":3,"file":"endpoints.d.ts","sourceRoot":"","sources":["../../../src/monitoring/routes/endpoints.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAG9C,OAAO,EAAiB,YAAY,EAAY,MAAM,UAAU,CAAA;AAgBhE,MAAM,MAAM,kBAAkB,GAAG;IAC/B,MAAM,EAAE,MAAM,CAAA;IACd,WAAW,EAAE,OAAO,CAAA;IACpB,QAAQ,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAA;CACxC,CAAA;AAsCD,eAAO,MAAM,sBAAsB,GAAI,KAAK,eAAe,EAAE,MAAM,kBAAkB,SAyEpF,CAAA"}
1
+ {"version":3,"file":"endpoints.d.ts","sourceRoot":"","sources":["../../../src/monitoring/routes/endpoints.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAG9C,OAAO,EAAiB,YAAY,EAAY,MAAM,UAAU,CAAA;AAiBhE,MAAM,MAAM,kBAAkB,GAAG;IAC/B,MAAM,EAAE,MAAM,CAAA;IACd,WAAW,EAAE,OAAO,CAAA;IACpB,QAAQ,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAA;CACxC,CAAA;AA0CD,eAAO,MAAM,sBAAsB,GAAI,KAAK,eAAe,EAAE,MAAM,kBAAkB,SAkGpF,CAAA"}
@@ -35,6 +35,9 @@ const buildQueryString = (query) => {
35
35
  });
36
36
  return params.toString();
37
37
  };
38
+ const normalizeRoute = (value) => {
39
+ return (value || '').replace(/^\/+/, '').trim();
40
+ };
38
41
  const normalizeHeaders = (headers) => {
39
42
  const normalized = {};
40
43
  if (!headers)
@@ -62,7 +65,7 @@ const registerEndpointRoutes = (app, deps) => {
62
65
  return { items: endpoints };
63
66
  }));
64
67
  app.post(`${prefix}/api/endpoints/invoke`, (req, reply) => __awaiter(void 0, void 0, void 0, function* () {
65
- var _a, _b;
68
+ var _a, _b, _c, _d;
66
69
  if (!allowInvoke) {
67
70
  reply.code(403);
68
71
  return { error: 'Endpoint invocation disabled' };
@@ -78,10 +81,13 @@ const registerEndpointRoutes = (app, deps) => {
78
81
  reply.code(400);
79
82
  return { error: 'Project ID not available' };
80
83
  }
81
- const normalizedRoute = route.replace(/^\/+/, '');
84
+ const normalizedRoute = normalizeRoute(route);
82
85
  const rawMethod = (body.method || 'POST').toUpperCase();
83
86
  const method = rawMethod;
84
87
  const effectiveMethod = (rawMethod === 'ALL' ? 'POST' : rawMethod);
88
+ const functionName = (_b = body.functionName) === null || _b === void 0 ? void 0 : _b.trim();
89
+ const functionsList = state_1.StateManager.select('functions');
90
+ const runAsSystem = functionName ? !!((_c = functionsList === null || functionsList === void 0 ? void 0 : functionsList[functionName]) === null || _c === void 0 ? void 0 : _c.run_as_system) : undefined;
85
91
  const queryString = buildQueryString(body.query);
86
92
  const encodedProjectId = encodeURIComponent(projectId);
87
93
  const baseUrl = `/app/${encodedProjectId}/endpoint/${normalizedRoute}`;
@@ -106,21 +112,43 @@ const registerEndpointRoutes = (app, deps) => {
106
112
  headers,
107
113
  payload
108
114
  };
109
- const response = yield app.inject(injectOptions);
110
- const parsedBody = parseInjectResponse(response.payload);
111
- const responseHeaders = {};
112
- Object.entries((_b = response.headers) !== null && _b !== void 0 ? _b : {}).forEach(([key, value]) => {
113
- if (value === undefined)
114
- return;
115
- responseHeaders[key] = Array.isArray(value) ? value.join(', ') : String(value);
116
- });
117
115
  addEvent({
118
116
  id: (0, utils_1.createEventId)(),
119
117
  ts: Date.now(),
120
118
  type: 'http_endpoint',
121
119
  source: 'monit',
122
120
  message: `${rawMethod} ${route}`,
123
- data: (0, utils_1.sanitize)({ method: effectiveMethod, route, query: body.query, headers: body.headers, payload: body.payload })
121
+ data: (0, utils_1.sanitize)({
122
+ method: effectiveMethod,
123
+ route,
124
+ query: body.query,
125
+ headers: body.headers,
126
+ payload: body.payload,
127
+ functionName
128
+ })
129
+ });
130
+ if (functionName) {
131
+ addEvent({
132
+ id: (0, utils_1.createEventId)(),
133
+ ts: Date.now(),
134
+ type: 'function',
135
+ source: 'monit',
136
+ message: `invoke ${functionName}`,
137
+ data: (0, utils_1.sanitize)({
138
+ name: functionName,
139
+ runAsSystem,
140
+ invokedFrom: functionName,
141
+ endpoint: { method: rawMethod, route }
142
+ })
143
+ });
144
+ }
145
+ const response = yield app.inject(injectOptions);
146
+ const parsedBody = parseInjectResponse(response.payload);
147
+ const responseHeaders = {};
148
+ Object.entries((_d = response.headers) !== null && _d !== void 0 ? _d : {}).forEach(([key, value]) => {
149
+ if (value === undefined)
150
+ return;
151
+ responseHeaders[key] = Array.isArray(value) ? value.join(', ') : String(value);
124
152
  });
125
153
  const result = {
126
154
  statusCode: response.statusCode,
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/services/mongodb-atlas/index.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAyC,oBAAoB,EAAE,MAAM,SAAS,CAAA;AA0+BrF,QAAA,MAAM,YAAY,EAAE,oBAuBlB,CAAA;AAEF,eAAe,YAAY,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/services/mongodb-atlas/index.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAyC,oBAAoB,EAAE,MAAM,SAAS,CAAA;AA8/BrF,QAAA,MAAM,YAAY,EAAE,oBAuBlB,CAAA;AAEF,eAAe,YAAY,CAAA"}
@@ -536,6 +536,26 @@ const getOperators = (collection, { rules, collName, user, run_as_system, monito
536
536
  throw error;
537
537
  }
538
538
  }),
539
+ countDocuments: (query, options) => __awaiter(void 0, void 0, void 0, function* () {
540
+ try {
541
+ if (!run_as_system) {
542
+ (0, utils_3.checkDenyOperation)(normalizedRules, collection.collectionName, model_1.CRUD_OPERATIONS.READ);
543
+ const formattedQuery = (0, utils_3.getFormattedQuery)(filters, query, user);
544
+ const currentQuery = formattedQuery.length ? { $and: formattedQuery } : {};
545
+ logService('countDocuments query', { collName, currentQuery });
546
+ const result = yield collection.countDocuments(currentQuery, options);
547
+ emitMongoEvent('countDocuments');
548
+ return result;
549
+ }
550
+ const result = yield collection.countDocuments(query, options);
551
+ emitMongoEvent('countDocuments');
552
+ return result;
553
+ }
554
+ catch (error) {
555
+ emitMongoEvent('countDocuments', undefined, error);
556
+ throw error;
557
+ }
558
+ }),
539
559
  /**
540
560
  * Watches changes on a MongoDB collection with optional role-based filtering of change events.
541
561
  *
@@ -35,6 +35,7 @@ export type GetOperatorsFunction = (collection: Collection<Document>, { rules, c
35
35
  findOneAndUpdate: (filter: MongoFilter<Document>, update: UpdateFilter<Document> | Document[], options?: FindOneAndUpdateOptions) => Promise<Document | null>;
36
36
  find: (filter?: MongoFilter<Document>, projection?: Document, options?: FindOptions) => FindCursor;
37
37
  count: (...params: Parameters<Method<'countDocuments'>>) => ReturnType<Method<'countDocuments'>>;
38
+ countDocuments: (...params: Parameters<Method<'countDocuments'>>) => ReturnType<Method<'countDocuments'>>;
38
39
  watch: (...params: Parameters<Method<'watch'>>) => ReturnType<Method<'watch'>>;
39
40
  aggregate: (...params: [...Parameters<Method<'aggregate'>>, isClient: boolean]) => ReturnType<Method<'aggregate'>>;
40
41
  insertMany: (...params: Parameters<Method<'insertMany'>>) => ReturnType<Method<'insertMany'>>;
@@ -1 +1 @@
1
- {"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../../../src/services/mongodb-atlas/model.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../../../src/services/mongodb-atlas/model.ts"],"names":[],"mappings":"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"}
@@ -291,6 +291,15 @@ export type Operators = {
291
291
  * @returns
292
292
  */
293
293
  $all: OperatorsFunction;
294
+ /**
295
+ * @param a
296
+ * @param b
297
+ *
298
+ * Checks whether the length of the user input array is equal to the rule value.
299
+ *
300
+ * @returns
301
+ */
302
+ $size: OperatorsFunction;
294
303
  /**
295
304
  * @param a
296
305
  * @param b
@@ -318,6 +327,7 @@ export declare enum RulesOperators {
318
327
  $in = "$in",
319
328
  $nin = "$nin",
320
329
  $all = "$all",
330
+ $size = "$size",
321
331
  $regex = "$regex"
322
332
  }
323
333
  export type RulesOperatorsInArray<T> = Partial<{
@@ -1 +1 @@
1
- {"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../../../src/utils/rules-matcher/interface.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../../../src/utils/rules-matcher/interface.ts"],"names":[],"mappings":"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"}
@@ -17,6 +17,7 @@ var RulesOperators;
17
17
  RulesOperators["$in"] = "$in";
18
18
  RulesOperators["$nin"] = "$nin";
19
19
  RulesOperators["$all"] = "$all";
20
+ RulesOperators["$size"] = "$size";
20
21
  RulesOperators["$regex"] = "$regex";
21
22
  })(RulesOperators || (exports.RulesOperators = RulesOperators = {}));
22
23
  var RulesModes;
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/utils/rules-matcher/utils.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,SAAS,EAAE,iBAAiB,EAAe,MAAM,aAAa,CAAA;AAIvE;;GAEG;AACH,QAAA,MAAM,iBAAiB,EAAE,iBAsNxB,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,SAAS,EAAE,SAsDvB,CAAA;AAID,eAAe,iBAAiB,CAAA"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/utils/rules-matcher/utils.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,SAAS,EAAE,iBAAiB,EAAe,MAAM,aAAa,CAAA;AAIvE;;GAEG;AACH,QAAA,MAAM,iBAAiB,EAAE,iBAsNxB,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,SAAS,EAAE,SAwDvB,CAAA;AAID,eAAe,iBAAiB,CAAA"}
@@ -209,6 +209,7 @@ exports.operators = {
209
209
  .forceArray(b)
210
210
  .every((c) => (0, intersection_1.default)(rulesMatcherUtils.forceArray(a), rulesMatcherUtils.forceArray(c))
211
211
  .length),
212
+ $size: (a, b) => Array.isArray(a) && a.length === parseFloat(b),
212
213
  $regex: (a, b, opt) => rulesMatcherUtils
213
214
  .forceArray(b)
214
215
  .some((c) => (c instanceof RegExp ? c.test(a) : new RegExp(c, opt).test(a)))
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flowerforce/flowerbase",
3
- "version": "1.7.0",
3
+ "version": "1.7.2-beta.0",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -34,6 +34,7 @@
34
34
  "fastify": "^5.0.0",
35
35
  "fastify-plugin": "^5.0.1",
36
36
  "fastify-raw-body": "^5.0.0",
37
+ "jsonwebtoken": "^9.0.3",
37
38
  "lodash": "^4.17.21",
38
39
  "node-cron": "^3.0.3",
39
40
  "nodemon": "^3.1.7",
@@ -48,6 +49,7 @@
48
49
  "@eslint/js": "^9.12.0",
49
50
  "@types/cors": "^2.8.17",
50
51
  "@types/jest": "^29.5.14",
52
+ "@types/jsonwebtoken": "^9.0.10",
51
53
  "@types/lodash": "^4.17.9",
52
54
  "@types/node": "22.6.1",
53
55
  "@types/node-cron": "^3.0.11",
@@ -108,6 +108,11 @@ export const executeQuery = async ({
108
108
  EJSON.deserialize(resolvedQuery),
109
109
  parsedOptions
110
110
  ),
111
+ countDocuments: () =>
112
+ (currentMethod as ReturnType<GetOperatorsFunction>['countDocuments'])(
113
+ EJSON.deserialize(resolvedQuery),
114
+ parsedOptions
115
+ ),
111
116
  deleteOne: () =>
112
117
  (currentMethod as ReturnType<GetOperatorsFunction>['deleteOne'])(
113
118
  EJSON.deserialize(resolvedQuery),
@@ -30,7 +30,7 @@ export const activateTriggers = async ({
30
30
  triggersToActivate.push({
31
31
  fileName: '__auto_on_user_creation_trigger__.json',
32
32
  content: {
33
- name: 'onUserCreation',
33
+ name: AUTH_CONFIG.on_user_creation_function_name,
34
34
  type: 'AUTHENTICATION',
35
35
  disabled: false,
36
36
  config: {
@@ -10,6 +10,7 @@ type EndpointInvokeBody = {
10
10
  query?: Record<string, unknown>
11
11
  headers?: Record<string, unknown>
12
12
  payload?: unknown
13
+ functionName?: string
13
14
  }
14
15
 
15
16
  type EndpointResponse = {
@@ -41,6 +42,10 @@ const buildQueryString = (query?: Record<string, unknown>) => {
41
42
  return params.toString()
42
43
  }
43
44
 
45
+ const normalizeRoute = (value?: string) => {
46
+ return (value || '').replace(/^\/+/, '').trim()
47
+ }
48
+
44
49
  const normalizeHeaders = (headers?: Record<string, unknown>) => {
45
50
  const normalized: Record<string, string> = {}
46
51
  if (!headers) return normalized
@@ -84,10 +89,13 @@ export const registerEndpointRoutes = (app: FastifyInstance, deps: EndpointRoute
84
89
  reply.code(400)
85
90
  return { error: 'Project ID not available' }
86
91
  }
87
- const normalizedRoute = route.replace(/^\/+/, '')
92
+ const normalizedRoute = normalizeRoute(route)
88
93
  const rawMethod = (body.method || 'POST').toUpperCase()
89
94
  const method = rawMethod as InjectOptions['method']
90
95
  const effectiveMethod = (rawMethod === 'ALL' ? 'POST' : rawMethod) as InjectOptions['method']
96
+ const functionName = body.functionName?.trim()
97
+ const functionsList = StateManager.select('functions') as Record<string, { run_as_system?: boolean }>
98
+ const runAsSystem = functionName ? !!functionsList?.[functionName]?.run_as_system : undefined
91
99
  const queryString = buildQueryString(body.query)
92
100
  const encodedProjectId = encodeURIComponent(projectId)
93
101
  const baseUrl = `/app/${encodedProjectId}/endpoint/${normalizedRoute}`
@@ -111,20 +119,42 @@ export const registerEndpointRoutes = (app: FastifyInstance, deps: EndpointRoute
111
119
  headers,
112
120
  payload
113
121
  }
114
- const response = await app.inject(injectOptions) as InjectResponse
115
- const parsedBody = parseInjectResponse(response.payload)
116
- const responseHeaders: Record<string, string> = {}
117
- Object.entries(response.headers ?? {}).forEach(([key, value]) => {
118
- if (value === undefined) return
119
- responseHeaders[key] = Array.isArray(value) ? value.join(', ') : String(value)
120
- })
121
122
  addEvent({
122
123
  id: createEventId(),
123
124
  ts: Date.now(),
124
125
  type: 'http_endpoint',
125
126
  source: 'monit',
126
127
  message: `${rawMethod} ${route}`,
127
- data: sanitize({ method: effectiveMethod, route, query: body.query, headers: body.headers, payload: body.payload })
128
+ data: sanitize({
129
+ method: effectiveMethod,
130
+ route,
131
+ query: body.query,
132
+ headers: body.headers,
133
+ payload: body.payload,
134
+ functionName
135
+ })
136
+ })
137
+ if (functionName) {
138
+ addEvent({
139
+ id: createEventId(),
140
+ ts: Date.now(),
141
+ type: 'function',
142
+ source: 'monit',
143
+ message: `invoke ${functionName}`,
144
+ data: sanitize({
145
+ name: functionName,
146
+ runAsSystem,
147
+ invokedFrom: functionName,
148
+ endpoint: { method: rawMethod, route }
149
+ })
150
+ })
151
+ }
152
+ const response = await app.inject(injectOptions) as InjectResponse
153
+ const parsedBody = parseInjectResponse(response.payload)
154
+ const responseHeaders: Record<string, string> = {}
155
+ Object.entries(response.headers ?? {}).forEach(([key, value]) => {
156
+ if (value === undefined) return
157
+ responseHeaders[key] = Array.isArray(value) ? value.join(', ') : String(value)
128
158
  })
129
159
  const result: EndpointResponse = {
130
160
  statusCode: response.statusCode,
@@ -351,6 +351,7 @@
351
351
  method: 'POST',
352
352
  body: JSON.stringify({
353
353
  route: state.selectedEndpoint.route,
354
+ functionName: state.selectedEndpoint.function_name,
354
355
  method,
355
356
  query,
356
357
  headers,
@@ -84,4 +84,37 @@ describe('mongodb-atlas count', () => {
84
84
  expect(result).toBe(42)
85
85
  expect(countDocuments).toHaveBeenCalledWith({ workspace: 'workspace-2' }, options)
86
86
  })
87
+
88
+ it('supports countDocuments alias with RBAC filtering', async () => {
89
+ const countDocuments = jest.fn().mockResolvedValue(3)
90
+ const collection = {
91
+ collectionName: 'todos',
92
+ countDocuments
93
+ }
94
+
95
+ const rules = {
96
+ filters: [
97
+ {
98
+ name: 'ownerFilter',
99
+ query: { ownerId: 'user-1' },
100
+ apply_when: {}
101
+ }
102
+ ]
103
+ }
104
+
105
+ const operators = MongoDbAtlas(createAppWithCollection(collection) as any, {
106
+ rules: createRules(rules),
107
+ user: { id: 'user-1' }
108
+ })
109
+ .db('db')
110
+ .collection('todos')
111
+
112
+ const result = await operators.countDocuments({ workspace: 'workspace-1' })
113
+
114
+ expect(result).toBe(3)
115
+ expect(countDocuments).toHaveBeenCalledWith(
116
+ { $and: [{ ownerId: 'user-1' }, { workspace: 'workspace-1' }] },
117
+ undefined
118
+ )
119
+ })
87
120
  })
@@ -628,6 +628,26 @@ const getOperators: GetOperatorsFunction = (
628
628
  throw error
629
629
  }
630
630
  },
631
+ countDocuments: async (query, options) => {
632
+ try {
633
+ if (!run_as_system) {
634
+ checkDenyOperation(normalizedRules, collection.collectionName, CRUD_OPERATIONS.READ)
635
+ const formattedQuery = getFormattedQuery(filters, query, user)
636
+ const currentQuery = formattedQuery.length ? { $and: formattedQuery } : {}
637
+ logService('countDocuments query', { collName, currentQuery })
638
+ const result = await collection.countDocuments(currentQuery, options)
639
+ emitMongoEvent('countDocuments')
640
+ return result
641
+ }
642
+
643
+ const result = await collection.countDocuments(query, options)
644
+ emitMongoEvent('countDocuments')
645
+ return result
646
+ } catch (error) {
647
+ emitMongoEvent('countDocuments', undefined, error)
648
+ throw error
649
+ }
650
+ },
631
651
  /**
632
652
  * Watches changes on a MongoDB collection with optional role-based filtering of change events.
633
653
  *
@@ -81,6 +81,9 @@ export type GetOperatorsFunction = (
81
81
  count: (
82
82
  ...params: Parameters<Method<'countDocuments'>>
83
83
  ) => ReturnType<Method<'countDocuments'>>
84
+ countDocuments: (
85
+ ...params: Parameters<Method<'countDocuments'>>
86
+ ) => ReturnType<Method<'countDocuments'>>
84
87
  watch: (...params: Parameters<Method<'watch'>>) => ReturnType<Method<'watch'>>
85
88
  aggregate: (
86
89
  ...params: [...Parameters<Method<'aggregate'>>, isClient: boolean]
@@ -86,6 +86,12 @@ describe('operators', () => {
86
86
  expect(operators.$all({ name: 'ciao' }, [{ name: 'ciao' }, 4, 5])).toBe(false)
87
87
  expect(operators.$all([{ name: 'ciao' }, 4, 5], [{ name: 'ciao' }, 4, 5])).toBe(false)
88
88
  })
89
+ it('should check array size', () => {
90
+ expect(operators.$size([1, 2, 3], 3)).toBe(true)
91
+ expect(operators.$size([1, 2, 3], 2)).toBe(false)
92
+ expect(operators.$size([], 0)).toBe(true)
93
+ expect(operators.$size('not-array', 0)).toBe(false)
94
+ })
89
95
  it('should check regex', () => {
90
96
  const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/
91
97
  expect(operators.$regex('test@gmail.com', emailRegex)).toBe(true)
@@ -311,6 +311,15 @@ export type Operators = {
311
311
  * @returns
312
312
  */
313
313
  $all: OperatorsFunction
314
+ /**
315
+ * @param a
316
+ * @param b
317
+ *
318
+ * Checks whether the length of the user input array is equal to the rule value.
319
+ *
320
+ * @returns
321
+ */
322
+ $size: OperatorsFunction
314
323
  /**
315
324
  * @param a
316
325
  * @param b
@@ -339,6 +348,7 @@ export enum RulesOperators {
339
348
  $in = '$in',
340
349
  $nin = '$nin',
341
350
  $all = '$all',
351
+ $size = '$size',
342
352
  $regex = '$regex'
343
353
  }
344
354
 
@@ -277,6 +277,8 @@ export const operators: Operators = {
277
277
  .length
278
278
  ),
279
279
 
280
+ $size: (a, b) => Array.isArray(a) && a.length === parseFloat(b),
281
+
280
282
  $regex: (a, b, opt) =>
281
283
  rulesMatcherUtils
282
284
  .forceArray(b)