@flowerforce/flowerbase 1.7.6-beta.7 → 1.7.6-beta.9

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.
Files changed (33) hide show
  1. package/dist/auth/providers/local-userpass/controller.d.ts.map +1 -1
  2. package/dist/auth/providers/local-userpass/controller.js +30 -12
  3. package/dist/auth/providers/local-userpass/dtos.d.ts +5 -1
  4. package/dist/auth/providers/local-userpass/dtos.d.ts.map +1 -1
  5. package/dist/features/rules/interface.d.ts +6 -5
  6. package/dist/features/rules/interface.d.ts.map +1 -1
  7. package/dist/services/mongodb-atlas/index.d.ts.map +1 -1
  8. package/dist/services/mongodb-atlas/index.js +41 -28
  9. package/dist/utils/roles/helpers.d.ts.map +1 -1
  10. package/dist/utils/roles/helpers.js +6 -3
  11. package/dist/utils/roles/machines/fieldPermissions.d.ts.map +1 -1
  12. package/dist/utils/roles/machines/fieldPermissions.js +3 -0
  13. package/dist/utils/rules-matcher/interface.d.ts +2 -0
  14. package/dist/utils/rules-matcher/interface.d.ts.map +1 -1
  15. package/dist/utils/rules-matcher/interface.js +1 -0
  16. package/dist/utils/rules-matcher/utils.d.ts.map +1 -1
  17. package/dist/utils/rules-matcher/utils.js +23 -6
  18. package/package.json +1 -1
  19. package/src/auth/providers/local-userpass/controller.ts +49 -31
  20. package/src/auth/providers/local-userpass/dtos.ts +6 -1
  21. package/src/features/rules/interface.ts +18 -17
  22. package/src/features/triggers/__tests__/index.test.ts +6 -4
  23. package/src/services/mongodb-atlas/__tests__/realmCompatibility.test.ts +205 -7
  24. package/src/services/mongodb-atlas/__tests__/utils.test.ts +27 -0
  25. package/src/services/mongodb-atlas/index.ts +294 -180
  26. package/src/utils/__tests__/checkIsValidFieldNameFn.test.ts +21 -4
  27. package/src/utils/__tests__/evaluateExpression.test.ts +33 -0
  28. package/src/utils/__tests__/rule.test.ts +38 -0
  29. package/src/utils/roles/helpers.ts +10 -5
  30. package/src/utils/roles/machines/fieldPermissions.ts +2 -0
  31. package/src/utils/rules-matcher/interface.ts +2 -0
  32. package/src/utils/rules-matcher/utils.ts +33 -17
  33. package/src/utils/__tests__/readFileContent.test.ts +0 -35
@@ -1 +1 @@
1
- {"version":3,"file":"controller.d.ts","sourceRoot":"","sources":["../../../../src/auth/providers/local-userpass/controller.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAuCzC;;;;GAIG;AACH,wBAAsB,uBAAuB,CAAC,GAAG,EAAE,eAAe,iBAsZjE"}
1
+ {"version":3,"file":"controller.d.ts","sourceRoot":"","sources":["../../../../src/auth/providers/local-userpass/controller.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AA4CzC;;;;GAIG;AACH,wBAAsB,uBAAuB,CAAC,GAAG,EAAE,eAAe,iBAmajE"}
@@ -49,14 +49,22 @@ function localUserPassController(app) {
49
49
  const resetMaxAttempts = constants_1.DEFAULT_CONFIG.AUTH_RESET_MAX_ATTEMPTS;
50
50
  const refreshTokenTtlMs = constants_1.DEFAULT_CONFIG.REFRESH_TOKEN_TTL_DAYS * 24 * 60 * 60 * 1000;
51
51
  const resolveLocalUserpassProvider = () => { var _a; return (_a = constants_1.AUTH_CONFIG.authProviders) === null || _a === void 0 ? void 0 : _a['local-userpass']; };
52
+ const invalidPasswordError = {
53
+ error: 'unauthorized',
54
+ error_code: 'InvalidPassword'
55
+ };
52
56
  try {
53
- yield authDb.collection(resetPasswordCollection).createIndex({ createdAt: 1 }, { expireAfterSeconds: resetPasswordTtlSeconds });
57
+ yield authDb
58
+ .collection(resetPasswordCollection)
59
+ .createIndex({ createdAt: 1 }, { expireAfterSeconds: resetPasswordTtlSeconds });
54
60
  }
55
61
  catch (error) {
56
62
  console.error('Failed to ensure reset password TTL index', error);
57
63
  }
58
64
  try {
59
- yield authDb.collection(refreshTokensCollection).createIndex({ expiresAt: 1 }, { expireAfterSeconds: 0 });
65
+ yield authDb
66
+ .collection(refreshTokensCollection)
67
+ .createIndex({ expiresAt: 1 }, { expireAfterSeconds: 0 });
60
68
  }
61
69
  catch (error) {
62
70
  console.error('Failed to ensure refresh token TTL index', error);
@@ -80,8 +88,10 @@ function localUserPassController(app) {
80
88
  const services = state_1.StateManager.select('services');
81
89
  const currentFunction = functionsList[resetPasswordConfig.resetFunctionName];
82
90
  const baseArgs = { token, tokenId, email, password, username: email };
83
- const args = Array.isArray(extraArguments) ? [baseArgs, ...extraArguments] : [baseArgs];
84
- const response = yield (0, context_1.GenerateContext)({
91
+ const args = Array.isArray(extraArguments)
92
+ ? [baseArgs, ...extraArguments]
93
+ : [baseArgs];
94
+ const response = (yield (0, context_1.GenerateContext)({
85
95
  args,
86
96
  app,
87
97
  rules: {},
@@ -91,7 +101,7 @@ function localUserPassController(app) {
91
101
  functionsList,
92
102
  services,
93
103
  runAsSystem: true
94
- });
104
+ }));
95
105
  const resetStatus = response === null || response === void 0 ? void 0 : response.status;
96
106
  if (resetStatus === 'success') {
97
107
  if (!password) {
@@ -138,13 +148,17 @@ function localUserPassController(app) {
138
148
  }
139
149
  let result;
140
150
  try {
141
- result = yield (0, handleUserRegistration_1.default)(app, { run_as_system: true, provider: handleUserRegistration_model_1.PROVIDER.LOCAL_USERPASS })({
151
+ result = yield (0, handleUserRegistration_1.default)(app, {
152
+ run_as_system: true,
153
+ provider: handleUserRegistration_model_1.PROVIDER.LOCAL_USERPASS
154
+ })({
142
155
  email: req.body.email.toLowerCase(),
143
156
  password: req.body.password
144
157
  });
145
158
  }
146
159
  catch (error) {
147
- if (error instanceof Error && error.message === 'This email address is already used') {
160
+ if (error instanceof Error &&
161
+ error.message === 'This email address is already used') {
148
162
  res.status(409).send({
149
163
  error: 'name already in use',
150
164
  error_code: 'AccountNameInUse'
@@ -179,10 +193,10 @@ function localUserPassController(app) {
179
193
  res.status(429).send({ message: 'Too many requests' });
180
194
  return;
181
195
  }
182
- const existing = yield authDb.collection(authCollection).findOne({
196
+ const existing = (yield authDb.collection(authCollection).findOne({
183
197
  confirmationToken: req.body.token,
184
198
  confirmationTokenId: req.body.tokenId
185
- });
199
+ }));
186
200
  if (!existing) {
187
201
  res.status(500);
188
202
  throw new Error(utils_1.AUTH_ERRORS.INVALID_TOKEN);
@@ -220,11 +234,13 @@ function localUserPassController(app) {
220
234
  email: req.body.username
221
235
  });
222
236
  if (!authUser) {
223
- throw new Error(utils_1.AUTH_ERRORS.INVALID_CREDENTIALS);
237
+ res.status(401);
238
+ return invalidPasswordError;
224
239
  }
225
240
  const passwordMatches = yield (0, crypto_1.comparePassword)(req.body.password, authUser.password);
226
241
  if (!passwordMatches) {
227
- throw new Error(utils_1.AUTH_ERRORS.INVALID_CREDENTIALS);
242
+ res.status(401);
243
+ return invalidPasswordError;
228
244
  }
229
245
  const user = user_id_field && userCollection
230
246
  ? yield customUserDb
@@ -246,7 +262,9 @@ function localUserPassController(app) {
246
262
  expiresAt: new Date(Date.now() + refreshTokenTtlMs),
247
263
  revokedAt: null
248
264
  });
249
- yield authDb.collection(authCollection).updateOne({ _id: authUser._id }, { $set: { lastLoginAt: now } });
265
+ yield authDb
266
+ .collection(authCollection)
267
+ .updateOne({ _id: authUser._id }, { $set: { lastLoginAt: now } });
250
268
  return {
251
269
  access_token: this.createAccessToken(userWithCustomData),
252
270
  refresh_token: refreshToken,
@@ -15,12 +15,16 @@ export type LoginSuccessDto = {
15
15
  export type ErrorResponseDto = {
16
16
  message: string;
17
17
  };
18
+ export type InvalidPasswordResponseDto = {
19
+ error: 'unauthorized';
20
+ error_code: 'InvalidPassword';
21
+ };
18
22
  export interface RegistrationDto {
19
23
  Body: RegisterUserDto;
20
24
  }
21
25
  export interface LoginDto {
22
26
  Body: LoginUserDto;
23
- Reply: LoginSuccessDto | ErrorResponseDto;
27
+ Reply: LoginSuccessDto | ErrorResponseDto | InvalidPasswordResponseDto;
24
28
  }
25
29
  export interface ResetPasswordSendDto {
26
30
  Body: {
@@ -1 +1 @@
1
- {"version":3,"file":"dtos.d.ts","sourceRoot":"","sources":["../../../../src/auth/providers/local-userpass/dtos.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,eAAe,GAAG;IAC5B,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,MAAM,CAAA;CACjB,CAAA;AAED,MAAM,MAAM,YAAY,GAAG;IACzB,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;CACjB,CAAA;AAED,MAAM,MAAM,eAAe,GAAG;IAC5B,YAAY,EAAE,MAAM,CAAA;IACpB,SAAS,EAAE,MAAM,CAAA;IACjB,aAAa,EAAE,MAAM,CAAA;IACrB,OAAO,EAAE,MAAM,CAAA;CAChB,CAAA;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC7B,OAAO,EAAE,MAAM,CAAA;CAChB,CAAA;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,eAAe,CAAA;CACtB;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,YAAY,CAAA;IAClB,KAAK,EAAE,eAAe,GAAG,gBAAgB,CAAA;CAC1C;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE;QACJ,KAAK,EAAE,MAAM,CAAA;KACd,CAAA;CACF;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE;QACJ,KAAK,EAAE,MAAM,CAAA;QACb,QAAQ,EAAE,MAAM,CAAA;QAChB,SAAS,CAAC,EAAE,OAAO,EAAE,CAAA;KACtB,CAAA;CACF;AAED,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE;QACJ,KAAK,EAAE,MAAM,CAAA;QACb,OAAO,EAAE,MAAM,CAAA;QACf,QAAQ,EAAE,MAAM,CAAA;KACjB,CAAA;CACF;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE;QACJ,KAAK,EAAE,MAAM,CAAA;QACb,OAAO,EAAE,MAAM,CAAA;KAChB,CAAA;CACF"}
1
+ {"version":3,"file":"dtos.d.ts","sourceRoot":"","sources":["../../../../src/auth/providers/local-userpass/dtos.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,eAAe,GAAG;IAC5B,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,MAAM,CAAA;CACjB,CAAA;AAED,MAAM,MAAM,YAAY,GAAG;IACzB,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;CACjB,CAAA;AAED,MAAM,MAAM,eAAe,GAAG;IAC5B,YAAY,EAAE,MAAM,CAAA;IACpB,SAAS,EAAE,MAAM,CAAA;IACjB,aAAa,EAAE,MAAM,CAAA;IACrB,OAAO,EAAE,MAAM,CAAA;CAChB,CAAA;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC7B,OAAO,EAAE,MAAM,CAAA;CAChB,CAAA;AAED,MAAM,MAAM,0BAA0B,GAAG;IACvC,KAAK,EAAE,cAAc,CAAA;IACrB,UAAU,EAAE,iBAAiB,CAAA;CAC9B,CAAA;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,eAAe,CAAA;CACtB;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,YAAY,CAAA;IAClB,KAAK,EAAE,eAAe,GAAG,gBAAgB,GAAG,0BAA0B,CAAA;CACvE;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE;QACJ,KAAK,EAAE,MAAM,CAAA;KACd,CAAA;CACF;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE;QACJ,KAAK,EAAE,MAAM,CAAA;QACb,QAAQ,EAAE,MAAM,CAAA;QAChB,SAAS,CAAC,EAAE,OAAO,EAAE,CAAA;KACtB,CAAA;CACF;AAED,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE;QACJ,KAAK,EAAE,MAAM,CAAA;QACb,OAAO,EAAE,MAAM,CAAA;QACf,QAAQ,EAAE,MAAM,CAAA;KACjB,CAAA;CACF;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE;QACJ,KAAK,EAAE,MAAM,CAAA;QACb,OAAO,EAAE,MAAM,CAAA;KAChB,CAAA;CACF"}
@@ -1,4 +1,5 @@
1
1
  import { Document } from 'mongodb';
2
+ export type PermissionExpression = boolean | Record<string, unknown>;
2
3
  export interface Filter {
3
4
  name: string;
4
5
  query: Record<string, unknown>;
@@ -9,11 +10,11 @@ export type Projection = Record<string, 0 | 1>;
9
10
  export interface Role {
10
11
  name: string;
11
12
  apply_when: Record<string, unknown>;
12
- insert: boolean;
13
- delete: boolean;
14
- search: boolean;
15
- read: boolean;
16
- write: boolean;
13
+ insert: PermissionExpression;
14
+ delete: PermissionExpression;
15
+ search: PermissionExpression;
16
+ read: PermissionExpression;
17
+ write: PermissionExpression;
17
18
  }
18
19
  export interface RulesConfig {
19
20
  database: string;
@@ -1 +1 @@
1
- {"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../../../src/features/rules/interface.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAClC,MAAM,WAAW,MAAM;IACrB,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC9B,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACnC,UAAU,CAAC,EAAE,UAAU,CAAA;CACxB;AACD,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAA;AAC9C,MAAM,WAAW,IAAI;IACnB,IAAI,EAAE,MAAM,CAAA;IACZ,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACnC,MAAM,EAAE,OAAO,CAAA;IACf,MAAM,EAAE,OAAO,CAAA;IACf,MAAM,EAAE,OAAO,CAAA;IACf,IAAI,EAAE,OAAO,CAAA;IACb,KAAK,EAAE,OAAO,CAAA;CACf;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,EAAE,MAAM,CAAA;IAClB,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB,KAAK,EAAE,IAAI,EAAE,CAAA;CAEd;AAED,MAAM,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAA;AAE/C,MAAM,MAAM,wBAAwB,GAChC;IAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,GACnC;IAAE,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,GACrC;IAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,GAClC;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,GAClB;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,GACjB;IAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,GACnC;IAAE,OAAO,EAAE,WAAW,CAAA;CAAE,GACxB;IAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,wBAAwB,EAAE,CAAC,CAAA;CAAE,GACtD;IAAE,UAAU,EAAE,cAAc,CAAA;CAAE,CAAA;AAElC,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,QAAQ,CAAC,EAAE,wBAAwB,EAAE,CAAC;CACvC;AAED,MAAM,MAAM,mBAAmB,GAAG,QAAQ,EAAE,CAAA;AAE5C,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,oBAAoB,CAAA;AAC1D,KAAK,oBAAoB,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,wBAAwB,EAAE,CAAA;CAAE,CAAA;AAElF,oBAAY,gBAAgB;IAC1B,MAAM,YAAY;IAClB,UAAU,eAAe;IACzB,KAAK,WAAW;CACjB"}
1
+ {"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../../../src/features/rules/interface.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAClC,MAAM,MAAM,oBAAoB,GAAG,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;AAEpE,MAAM,WAAW,MAAM;IACrB,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC9B,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACnC,UAAU,CAAC,EAAE,UAAU,CAAA;CACxB;AACD,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAA;AAC9C,MAAM,WAAW,IAAI;IACnB,IAAI,EAAE,MAAM,CAAA;IACZ,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACnC,MAAM,EAAE,oBAAoB,CAAA;IAC5B,MAAM,EAAE,oBAAoB,CAAA;IAC5B,MAAM,EAAE,oBAAoB,CAAA;IAC5B,IAAI,EAAE,oBAAoB,CAAA;IAC1B,KAAK,EAAE,oBAAoB,CAAA;CAC5B;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,EAAE,MAAM,CAAA;IAClB,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB,KAAK,EAAE,IAAI,EAAE,CAAA;CACd;AAED,MAAM,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAA;AAE/C,MAAM,MAAM,wBAAwB,GAChC;IAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,GACnC;IAAE,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,GACrC;IAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,GAClC;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,GAClB;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,GACjB;IAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,GACnC;IAAE,OAAO,EAAE,WAAW,CAAA;CAAE,GACxB;IAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,wBAAwB,EAAE,CAAC,CAAA;CAAE,GACtD;IAAE,UAAU,EAAE,cAAc,CAAA;CAAE,CAAA;AAElC,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAA;IACZ,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,EAAE,EAAE,MAAM,CAAA;IACV,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC7B,QAAQ,CAAC,EAAE,wBAAwB,EAAE,CAAA;CACtC;AAED,MAAM,MAAM,mBAAmB,GAAG,QAAQ,EAAE,CAAA;AAE5C,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,oBAAoB,CAAA;AAC1D,KAAK,oBAAoB,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,wBAAwB,EAAE,CAAA;CAAE,CAAA;AAElF,oBAAY,gBAAgB;IAC1B,MAAM,YAAY;IAClB,UAAU,eAAe;IACzB,KAAK,WAAW;CACjB"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/services/mongodb-atlas/index.ts"],"names":[],"mappings":"AAKA,OAAO,EAIL,QAAQ,EAQT,MAAM,SAAS,CAAA;AAOhB,OAAO,EAGL,oBAAoB,EAErB,MAAM,SAAS,CAAA;AAgJhB,eAAO,MAAM,kBAAkB,GAAI,OAAO,OAAO,KAAG,OA0BnD,CAAA;AA4BD,eAAO,MAAM,2BAA2B,GAAI,UAAU,QAAQ,EAAE,YAK5D,CAAA;AAgtCJ,QAAA,MAAM,YAAY,EAAE,oBAwBlB,CAAA;AAEF,eAAe,YAAY,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/services/mongodb-atlas/index.ts"],"names":[],"mappings":"AAKA,OAAO,EAIL,QAAQ,EAQT,MAAM,SAAS,CAAA;AAOhB,OAAO,EAGL,oBAAoB,EAErB,MAAM,SAAS,CAAA;AA6JhB,eAAO,MAAM,kBAAkB,GAAI,OAAO,OAAO,KAAG,OA0BnD,CAAA;AA8BD,eAAO,MAAM,2BAA2B,GAAI,UAAU,QAAQ,EAAE,YAK5D,CAAA;AAmzCJ,QAAA,MAAM,YAAY,EAAE,oBAwBlB,CAAA;AAEF,eAAe,YAAY,CAAA"}
@@ -115,11 +115,15 @@ const normalizeFindOneAndUpdateOptions = (options) => {
115
115
  if (!options)
116
116
  return undefined;
117
117
  const { returnNewDocument } = options, rest = __rest(options, ["returnNewDocument"]);
118
- if (typeof returnNewDocument !== 'boolean' || typeof rest.returnDocument !== 'undefined') {
118
+ if (typeof returnNewDocument !== 'boolean' ||
119
+ typeof rest.returnDocument !== 'undefined') {
119
120
  return rest;
120
121
  }
121
122
  return Object.assign(Object.assign({}, rest), { returnDocument: returnNewDocument ? 'after' : 'before' });
122
123
  };
124
+ const getValidationExpansions = (prevRoot) => ({
125
+ '%%prevRoot': prevRoot
126
+ });
123
127
  const buildAndQuery = (clauses) => clauses.length ? { $and: clauses } : {};
124
128
  const watchChangeEventRootKeys = new Set([
125
129
  '_id',
@@ -140,7 +144,10 @@ const isWatchChangeEventPath = (key) => {
140
144
  key.startsWith('fullDocument.') ||
141
145
  key.startsWith('updateDescription.'));
142
146
  };
143
- const isWatchOpaqueChangeEventObjectKey = (key) => key === 'ns' || key === 'documentKey' || key === 'fullDocument' || key === 'updateDescription';
147
+ const isWatchOpaqueChangeEventObjectKey = (key) => key === 'ns' ||
148
+ key === 'documentKey' ||
149
+ key === 'fullDocument' ||
150
+ key === 'updateDescription';
144
151
  const toWatchMatchFilter = (value) => {
145
152
  if (Array.isArray(value)) {
146
153
  return value.map((item) => (0, exports.toWatchMatchFilter)(item));
@@ -215,10 +222,7 @@ const resolveWatchArgs = (pipelineOrOptions, options) => {
215
222
  if (Array.isArray(ids)) {
216
223
  extraMatches.push({
217
224
  $match: {
218
- $or: [
219
- { 'documentKey._id': { $in: ids } },
220
- { 'fullDocument._id': { $in: ids } }
221
- ]
225
+ $or: [{ 'documentKey._id': { $in: ids } }, { 'fullDocument._id': { $in: ids } }]
222
226
  }
223
227
  });
224
228
  }
@@ -236,7 +240,7 @@ const matchesPullCondition = (item, operand) => {
236
240
  return (0, isEqual_1.default)(item, operand);
237
241
  if (hasOperatorExpressions(operand)) {
238
242
  if (Array.isArray(operand.$in)) {
239
- return (operand.$in).some((candidate) => (0, isEqual_1.default)(candidate, item));
243
+ return operand.$in.some((candidate) => (0, isEqual_1.default)(candidate, item));
240
244
  }
241
245
  return false;
242
246
  }
@@ -274,8 +278,9 @@ const applyDocumentUpdateOperators = (baseDocument, update) => {
274
278
  Object.entries(payload).forEach(([path, value]) => {
275
279
  const currentValue = (0, get_1.default)(updated, path);
276
280
  const targetArray = Array.isArray(currentValue) ? [...currentValue] : [];
277
- if (isPlainObject(value) && Array.isArray(value.$each)) {
278
- targetArray.push(...(value.$each));
281
+ if (isPlainObject(value) &&
282
+ Array.isArray(value.$each)) {
283
+ targetArray.push(...value.$each);
279
284
  }
280
285
  else {
281
286
  targetArray.push(value);
@@ -341,7 +346,8 @@ const applyDocumentUpdateOperators = (baseDocument, update) => {
341
346
  const currentValue = (0, get_1.default)(updated, path);
342
347
  const comparableCurrent = currentValue;
343
348
  const comparableValue = value;
344
- if (typeof currentValue === 'undefined' || comparableCurrent > comparableValue) {
349
+ if (typeof currentValue === 'undefined' ||
350
+ comparableCurrent > comparableValue) {
345
351
  (0, set_1.default)(updated, path, value);
346
352
  }
347
353
  });
@@ -351,7 +357,8 @@ const applyDocumentUpdateOperators = (baseDocument, update) => {
351
357
  const currentValue = (0, get_1.default)(updated, path);
352
358
  const comparableCurrent = currentValue;
353
359
  const comparableValue = value;
354
- if (typeof currentValue === 'undefined' || comparableCurrent < comparableValue) {
360
+ if (typeof currentValue === 'undefined' ||
361
+ comparableCurrent < comparableValue) {
355
362
  (0, set_1.default)(updated, path, value);
356
363
  }
357
364
  });
@@ -490,7 +497,7 @@ const getOperators = (mongo, { rules, dbName, collName, user, run_as_system, mon
490
497
  type: 'read',
491
498
  roles,
492
499
  cursor: result,
493
- expansions: {}
500
+ expansions: getValidationExpansions(result)
494
501
  }, user)
495
502
  : fallbackAccess(result);
496
503
  // Return validated document or empty object if not permitted
@@ -546,7 +553,7 @@ const getOperators = (mongo, { rules, dbName, collName, user, run_as_system, mon
546
553
  type: 'delete',
547
554
  roles,
548
555
  cursor: result,
549
- expansions: {}
556
+ expansions: getValidationExpansions(result)
550
557
  }, user)
551
558
  : fallbackAccess(result);
552
559
  if (!status) {
@@ -595,7 +602,7 @@ const getOperators = (mongo, { rules, dbName, collName, user, run_as_system, mon
595
602
  type: 'insert',
596
603
  roles,
597
604
  cursor: data,
598
- expansions: {}
605
+ expansions: getValidationExpansions()
599
606
  }, user)
600
607
  : fallbackAccess(data);
601
608
  if (!status || !(0, isEqual_1.default)(data, document)) {
@@ -672,7 +679,7 @@ const getOperators = (mongo, { rules, dbName, collName, user, run_as_system, mon
672
679
  type: 'write',
673
680
  roles,
674
681
  cursor: docToCheck,
675
- expansions: {}
682
+ expansions: getValidationExpansions(result)
676
683
  }, user)
677
684
  : fallbackAccess(docToCheck);
678
685
  // Ensure no unauthorized changes are made
@@ -735,11 +742,13 @@ const getOperators = (mongo, { rules, dbName, collName, user, run_as_system, mon
735
742
  }
736
743
  else {
737
744
  const [computedDoc] = Array.isArray(normalizedData)
738
- ? yield collection.aggregate([
745
+ ? yield collection
746
+ .aggregate([
739
747
  { $match: buildAndQuery(safeQuery) },
740
748
  { $limit: 1 },
741
749
  ...normalizedData
742
- ]).toArray()
750
+ ])
751
+ .toArray()
743
752
  : [applyDocumentUpdateOperators(currentDoc, normalizedData)];
744
753
  docToCheck = computedDoc;
745
754
  }
@@ -749,7 +758,7 @@ const getOperators = (mongo, { rules, dbName, collName, user, run_as_system, mon
749
758
  type: validationType,
750
759
  roles,
751
760
  cursor: docToCheck,
752
- expansions: {}
761
+ expansions: getValidationExpansions(validationType === 'insert' ? undefined : currentDoc)
753
762
  }, user)
754
763
  : fallbackAccess(docToCheck);
755
764
  const areDocumentsEqual = areUpdatedFieldsAllowed(document, docToCheck, updatedPaths);
@@ -769,10 +778,12 @@ const getOperators = (mongo, { rules, dbName, collName, user, run_as_system, mon
769
778
  type: 'read',
770
779
  roles,
771
780
  cursor: updateResult,
772
- expansions: {}
781
+ expansions: getValidationExpansions(updateResult)
773
782
  }, user)
774
783
  : fallbackAccess(updateResult);
775
- const sanitizedDoc = readResult.status ? ((_a = readResult.document) !== null && _a !== void 0 ? _a : updateResult) : {};
784
+ const sanitizedDoc = readResult.status
785
+ ? ((_a = readResult.document) !== null && _a !== void 0 ? _a : updateResult)
786
+ : {};
776
787
  emitMongoEvent('findOneAndUpdate');
777
788
  return sanitizedDoc;
778
789
  }
@@ -841,7 +852,7 @@ const getOperators = (mongo, { rules, dbName, collName, user, run_as_system, mon
841
852
  type: 'read',
842
853
  roles,
843
854
  cursor: currentDoc,
844
- expansions: {}
855
+ expansions: getValidationExpansions(currentDoc)
845
856
  }, user)
846
857
  : fallbackAccess(currentDoc);
847
858
  return status ? document : undefined;
@@ -921,7 +932,9 @@ const getOperators = (mongo, { rules, dbName, collName, user, run_as_system, mon
921
932
  * This allows fine-grained control over what change events a user can observe, based on roles and filters.
922
933
  */
923
934
  watch: (pipelineOrOptions = [], options) => {
924
- const changestreamCollection = mongo[constants_1.CHANGESTREAM].client.db(dbName).collection(collName);
935
+ const changestreamCollection = mongo[constants_1.CHANGESTREAM].client
936
+ .db(dbName)
937
+ .collection(collName);
925
938
  try {
926
939
  const { pipeline, options: watchOptions, extraMatches } = resolveWatchArgs(pipelineOrOptions, options);
927
940
  if (!run_as_system) {
@@ -965,7 +978,7 @@ const getOperators = (mongo, { rules, dbName, collName, user, run_as_system, mon
965
978
  type: 'read',
966
979
  roles,
967
980
  cursor: fullDocument,
968
- expansions: {}
981
+ expansions: getValidationExpansions(fullDocument)
969
982
  }, user)
970
983
  : fallbackAccess(fullDocument);
971
984
  const { status, document } = fullDocumentValidation;
@@ -974,7 +987,7 @@ const getOperators = (mongo, { rules, dbName, collName, user, run_as_system, mon
974
987
  type: 'read',
975
988
  roles,
976
989
  cursor: updateDescription === null || updateDescription === void 0 ? void 0 : updateDescription.updatedFields,
977
- expansions: {}
990
+ expansions: getValidationExpansions(fullDocument)
978
991
  }, user)
979
992
  : fallbackAccess(updateDescription === null || updateDescription === void 0 ? void 0 : updateDescription.updatedFields);
980
993
  return {
@@ -1077,7 +1090,7 @@ const getOperators = (mongo, { rules, dbName, collName, user, run_as_system, mon
1077
1090
  type: 'insert',
1078
1091
  roles,
1079
1092
  cursor: currentDoc,
1080
- expansions: {}
1093
+ expansions: getValidationExpansions()
1081
1094
  }, user)
1082
1095
  : fallbackAccess(currentDoc);
1083
1096
  return status ? document : undefined;
@@ -1115,14 +1128,14 @@ const getOperators = (mongo, { rules, dbName, collName, user, run_as_system, mon
1115
1128
  // Check if the update data contains MongoDB update operators (e.g., $set, $inc)
1116
1129
  const updatedPaths = getUpdatedPaths(normalizedData);
1117
1130
  const docsToCheck = result.map((currentDoc) => applyDocumentUpdateOperators(currentDoc, normalizedData));
1118
- const filteredItems = yield Promise.all(docsToCheck.map((currentDoc) => __awaiter(void 0, void 0, void 0, function* () {
1131
+ const filteredItems = yield Promise.all(docsToCheck.map((currentDoc, index) => __awaiter(void 0, void 0, void 0, function* () {
1119
1132
  const winningRole = (0, utils_2.getWinningRole)(currentDoc, user, roles);
1120
1133
  const { status, document } = winningRole
1121
1134
  ? yield (0, machines_1.checkValidation)(winningRole, {
1122
1135
  type: 'write',
1123
1136
  roles,
1124
1137
  cursor: currentDoc,
1125
- expansions: {}
1138
+ expansions: getValidationExpansions(result[index])
1126
1139
  }, user)
1127
1140
  : fallbackAccess(currentDoc);
1128
1141
  return status ? document : undefined;
@@ -1176,7 +1189,7 @@ const getOperators = (mongo, { rules, dbName, collName, user, run_as_system, mon
1176
1189
  type: 'delete',
1177
1190
  roles,
1178
1191
  cursor: currentDoc,
1179
- expansions: {}
1192
+ expansions: getValidationExpansions(currentDoc)
1180
1193
  }, user)
1181
1194
  : fallbackAccess(currentDoc);
1182
1195
  return status ? document : undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../../src/utils/roles/helpers.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAA;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAgBrD,eAAO,MAAM,kBAAkB,GAC7B,QAAQ,cAAc,CAAC,QAAQ,CAAC,EAChC,aAAa,oBAAoB,EACjC,OAAO,cAAc,CAAC,MAAM,CAAC,KAC5B,OAAO,CAAC,OAAO,CAiBjB,CAAA"}
1
+ {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../../src/utils/roles/helpers.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAA;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAkBrD,eAAO,MAAM,kBAAkB,GAC7B,QAAQ,cAAc,CAAC,QAAQ,CAAC,EAChC,aAAa,oBAAoB,EACjC,OAAO,cAAc,CAAC,MAAM,CAAC,KAC5B,OAAO,CAAC,OAAO,CAoBjB,CAAA"}
@@ -30,13 +30,16 @@ const normalizeUserRole = (user) => {
30
30
  const customRole = typeof candidate.custom_data === 'object' && candidate.custom_data !== null
31
31
  ? candidate.custom_data.role
32
32
  : undefined;
33
- return typeof customRole === 'string' ? Object.assign(Object.assign({}, candidate), { role: customRole }) : user;
33
+ return typeof customRole === 'string'
34
+ ? Object.assign(Object.assign({}, candidate), { role: customRole })
35
+ : user;
34
36
  };
35
37
  const evaluateExpression = (params, expression, user) => __awaiter(void 0, void 0, void 0, function* () {
38
+ var _a;
36
39
  if (!expression || typeof expression === 'boolean')
37
40
  return !!expression;
38
41
  const normalizedUser = normalizeUserRole(user);
39
- const value = Object.assign(Object.assign(Object.assign({}, params.expansions), params.cursor), { '%%user': normalizedUser, '%%true': true });
42
+ const value = Object.assign(Object.assign(Object.assign({}, params.expansions), params.cursor), { '%%root': params.cursor, '%%prevRoot': (_a = params.expansions) === null || _a === void 0 ? void 0 : _a['%%prevRoot'], '%%user': normalizedUser, '%%true': true, '%%false': false });
40
43
  const conditions = (0, rules_1.expandQuery)(expression, value);
41
44
  const complexCondition = Object.entries(conditions).find(([key]) => functionsConditions.includes(key));
42
45
  return complexCondition
@@ -61,7 +64,7 @@ const evaluateComplexExpression = (condition, params, user) => __awaiter(void 0,
61
64
  const response = yield (0, context_1.GenerateContext)({
62
65
  args: expandedArguments,
63
66
  app,
64
- rules: state_1.StateManager.select("rules"),
67
+ rules: state_1.StateManager.select('rules'),
65
68
  user: normalizedUser,
66
69
  currentFunction,
67
70
  functionName: name,
@@ -1 +1 @@
1
- {"version":3,"file":"fieldPermissions.d.ts","sourceRoot":"","sources":["../../../../src/utils/roles/machines/fieldPermissions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAElC,OAAO,EAGL,IAAI,EACL,MAAM,cAAc,CAAA;AACrB,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AA0C5C,eAAO,MAAM,0BAA0B,GAAI,OAAO,IAAI,YACN,CAAA;AAEhD,eAAO,MAAM,gCAAgC,GAC3C,SAAS,IAAI,CAAC,cAAc,EAAE,QAAQ,GAAG,MAAM,GAAG,MAAM,CAAC,EACzD,MAAM,MAAM,GAAG,OAAO,EACtB,UAAU;IACR,YAAY,CAAC,EAAE,OAAO,CAAA;CACvB,KACA,OAAO,CAAC,QAAQ,CAkClB,CAAA"}
1
+ {"version":3,"file":"fieldPermissions.d.ts","sourceRoot":"","sources":["../../../../src/utils/roles/machines/fieldPermissions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAElC,OAAO,EAGL,IAAI,EACL,MAAM,cAAc,CAAA;AACrB,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AA0C5C,eAAO,MAAM,0BAA0B,GAAI,OAAO,IAAI,YACN,CAAA;AAEhD,eAAO,MAAM,gCAAgC,GAC3C,SAAS,IAAI,CAAC,cAAc,EAAE,QAAQ,GAAG,MAAM,GAAG,MAAM,CAAC,EACzD,MAAM,MAAM,GAAG,OAAO,EACtB,UAAU;IACR,YAAY,CAAC,EAAE,OAAO,CAAA;CACvB,KACA,OAAO,CAAC,QAAQ,CAoClB,CAAA"}
@@ -59,6 +59,9 @@ const filterDocumentByFieldPermissions = (context, mode, options) => __awaiter(v
59
59
  if (typeof readAllowed !== 'undefined') {
60
60
  allowed = readAllowed;
61
61
  }
62
+ else if (!allowed && typeof permission.write !== 'undefined') {
63
+ allowed = yield canWriteField(context, permission);
64
+ }
62
65
  }
63
66
  else {
64
67
  allowed = yield canWriteField(context, permission);
@@ -311,6 +311,7 @@ export type Operators = {
311
311
  * @returns
312
312
  */
313
313
  $regex: OperatorsFunction;
314
+ '%exists': OperatorsFunction;
314
315
  '%stringToOid': OperatorsFunction;
315
316
  '%oidToString': OperatorsFunction;
316
317
  };
@@ -331,6 +332,7 @@ export declare enum RulesOperators {
331
332
  $all = "$all",
332
333
  $size = "$size",
333
334
  $regex = "$regex",
335
+ '%exists' = "%exists",
334
336
  '%stringToOid' = "%stringToOid",
335
337
  '%oidToString' = "%oidToString"
336
338
  }
@@ -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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"}
@@ -19,6 +19,7 @@ var RulesOperators;
19
19
  RulesOperators["$all"] = "$all";
20
20
  RulesOperators["$size"] = "$size";
21
21
  RulesOperators["$regex"] = "$regex";
22
+ RulesOperators["%exists"] = "%exists";
22
23
  RulesOperators["%stringToOid"] = "%stringToOid";
23
24
  RulesOperators["%oidToString"] = "%oidToString";
24
25
  })(RulesOperators || (exports.RulesOperators = RulesOperators = {}));
@@ -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;AAsDvE;;GAEG;AACH,QAAA,MAAM,iBAAiB,EAAE,iBAsNxB,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,SAAS,EAAE,SAoDvB,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;AAmEvE;;GAEG;AACH,QAAA,MAAM,iBAAiB,EAAE,iBAoNxB,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,SAAS,EAAE,SAyDvB,CAAA;AAID,eAAe,iBAAiB,CAAA"}
@@ -23,7 +23,8 @@ const toObjectIdHex = (value) => {
23
23
  return null;
24
24
  }
25
25
  const maybeObjectId = value;
26
- if (maybeObjectId._bsontype === 'ObjectId' && typeof maybeObjectId.toHexString === 'function') {
26
+ if (maybeObjectId._bsontype === 'ObjectId' &&
27
+ typeof maybeObjectId.toHexString === 'function') {
27
28
  const hex = maybeObjectId.toHexString();
28
29
  return HEX_24_REGEXP.test(hex) ? hex.toLowerCase() : null;
29
30
  }
@@ -41,7 +42,16 @@ const includesWithSemanticEquality = (value, candidate) => rulesMatcherUtils
41
42
  .forceArray(candidate)
42
43
  .some((item) => rulesMatcherUtils
43
44
  .forceArray(value)
44
- .some((sourceItem) => rulesMatcherUtils.forceArray(item).some((candidateItem) => areSemanticallyEqual(sourceItem, candidateItem))));
45
+ .some((sourceItem) => rulesMatcherUtils
46
+ .forceArray(item)
47
+ .some((candidateItem) => areSemanticallyEqual(sourceItem, candidateItem))));
48
+ const resolveRefPath = (data, refPath, prefix) => {
49
+ const exactMatch = (0, get_1.default)(data, refPath, undefined);
50
+ if (exactMatch !== undefined) {
51
+ return exactMatch;
52
+ }
53
+ return (0, get_1.default)(data, rulesMatcherUtils.getPath(refPath, prefix), undefined);
54
+ };
45
55
  /**
46
56
  * Defines a utility object named rulesMatcherUtils, which contains various helper functions used for processing rules and data in a rule-matching context.
47
57
  */
@@ -60,7 +70,7 @@ const rulesMatcherUtils = {
60
70
  const { name } = (0, get_1.default)(valueBlock, [path], {}) || {};
61
71
  const { op, value, opt } = rulesMatcherUtils.getDefaultRule(valueBlock[path]);
62
72
  const valueRef = value && String(value).indexOf('$ref:') === 0
63
- ? (0, get_1.default)(data, rulesMatcherUtils.getPath(value.replace('$ref:', ''), prefix), undefined)
73
+ ? resolveRefPath(data, value.replace('$ref:', ''), prefix)
64
74
  : value;
65
75
  if (!exports.operators[op]) {
66
76
  throw new Error(`Error missing operator:${op}`);
@@ -82,7 +92,9 @@ const rulesMatcherUtils = {
82
92
  const res = rulesMatcherUtils.getPath(path, prefix);
83
93
  const { value } = rulesMatcherUtils.getDefaultRule(valueBlock[path]);
84
94
  if (value && String(value).indexOf('$ref:') === 0) {
85
- keys[rulesMatcherUtils.getPath(value.replace('$ref:', ''), prefix)] = true;
95
+ const refPath = value.replace('$ref:', '');
96
+ keys[refPath] = true;
97
+ keys[rulesMatcherUtils.getPath(refPath, prefix)] = true;
86
98
  }
87
99
  return (keys[res] = true);
88
100
  },
@@ -221,6 +233,7 @@ const rulesMatcherUtils = {
221
233
  */
222
234
  exports.operators = {
223
235
  $exists: (a, b) => !rulesMatcherUtils.isEmpty(a) === b,
236
+ '%exists': (a, b) => !rulesMatcherUtils.isEmpty(a) === b,
224
237
  $eq: (a, b) => areSemanticallyEqual(a, b),
225
238
  $ne: (a, b) => !areSemanticallyEqual(a, b),
226
239
  $gt: (a, b) => rulesMatcherUtils.forceNumber(a) > parseFloat(b),
@@ -233,9 +246,13 @@ exports.operators = {
233
246
  $strLte: (a, b) => String(a || '').length <= parseFloat(b),
234
247
  $in: (a, b) => includesWithSemanticEquality(a, b),
235
248
  $nin: (a, b) => !includesWithSemanticEquality(a, b),
236
- $all: (a, b) => rulesMatcherUtils.forceArray(b).every((candidate) => rulesMatcherUtils
249
+ $all: (a, b) => rulesMatcherUtils
250
+ .forceArray(b)
251
+ .every((candidate) => rulesMatcherUtils
237
252
  .forceArray(a)
238
- .some((value) => rulesMatcherUtils.forceArray(candidate).some((item) => areSemanticallyEqual(value, item)))),
253
+ .some((value) => rulesMatcherUtils
254
+ .forceArray(candidate)
255
+ .some((item) => areSemanticallyEqual(value, item)))),
239
256
  $size: (a, b) => Array.isArray(a) && a.length === parseFloat(b),
240
257
  $regex: (a, b, opt) => rulesMatcherUtils
241
258
  .forceArray(b)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flowerforce/flowerbase",
3
- "version": "1.7.6-beta.7",
3
+ "version": "1.7.6-beta.9",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",