@flowerforce/flowerbase 1.8.1-beta.3 → 1.8.1-beta.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.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../src/utils/roles/machines/write/B/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAA;AAGxC,eAAO,MAAM,aAAa,EAAE,MAgE3B,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../src/utils/roles/machines/write/B/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAA;AAGxC,eAAO,MAAM,aAAa,EAAE,MAmE3B,CAAA"}
@@ -44,6 +44,9 @@ exports.STEP_B_STATES = {
44
44
  });
45
45
  const check = yield (0, commonValidators_1.evaluateTopLevelPermissionsFn)(context, 'write');
46
46
  if (check) {
47
+ if (context.params.type === 'write') {
48
+ return endValidation({ success: true });
49
+ }
47
50
  return next('evaluateTopLevelInsert');
48
51
  }
49
52
  if (check === false) {
@@ -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;AAmEvE;;GAEG;AACH,QAAA,MAAM,iBAAiB,EAAE,iBAoNxB,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,SAAS,EAAE,SAyDvB,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,iBAkOxB,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,SAAS,EAAE,SAyDvB,CAAA;AAID,eAAe,iBAAiB,CAAA"}
@@ -212,6 +212,13 @@ const rulesMatcherUtils = {
212
212
  return true;
213
213
  return block['$or'].some((item) => rulesMatcherUtils.checkRule(item, data, options));
214
214
  }
215
+ if (!Array.isArray(block) && block && typeof block === 'object') {
216
+ const keys = Object.keys(block);
217
+ const hasLogicalOperators = keys.some((key) => key === '$and' || key === '$or');
218
+ if (!hasLogicalOperators && keys.length > 1) {
219
+ return keys.every((key) => rulesMatcherUtils.checkRule({ [key]: block[key] }, data, options));
220
+ }
221
+ }
215
222
  const res = rulesMatcherUtils.rule(block, data, options);
216
223
  return res.valid;
217
224
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flowerforce/flowerbase",
3
- "version": "1.8.1-beta.3",
3
+ "version": "1.8.1-beta.4",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -77,9 +77,9 @@ describe('WRITE STEP_B_STATES', () => {
77
77
  expect(endValidation).toHaveBeenCalledWith({ success: false })
78
78
  })
79
79
 
80
- it('routes to insert check when write=true', async () => {
80
+ it('ends validation when write=true on update requests', async () => {
81
81
  ;(evaluateTopLevelPermissionsFn as jest.Mock).mockResolvedValueOnce(true)
82
- const context = {} as MachineContext
82
+ const context = { params: { type: 'write' } } as MachineContext
83
83
  await evaluateTopLevelWrite({
84
84
  context,
85
85
  endValidation,
@@ -87,13 +87,12 @@ describe('WRITE STEP_B_STATES', () => {
87
87
  next,
88
88
  initialStep: null
89
89
  })
90
- expect(next).toHaveBeenCalledWith('evaluateTopLevelInsert')
90
+ expect(endValidation).toHaveBeenCalledWith({ success: true })
91
91
  })
92
92
 
93
- it('routes to insert check when write=true and field-level rules exist', async () => {
93
+ it('routes to insert check when write=true on insert requests', async () => {
94
94
  ;(evaluateTopLevelPermissionsFn as jest.Mock).mockResolvedValueOnce(true)
95
- ;(checkFieldsPropertyExists as jest.Mock).mockReturnValue(true)
96
- const context = {} as MachineContext
95
+ const context = { params: { type: 'insert' } } as MachineContext
97
96
  await evaluateTopLevelWrite({
98
97
  context,
99
98
  endValidation,
@@ -9,7 +9,8 @@ const {
9
9
  getPath,
10
10
  forceNumber,
11
11
  getDefaultStringValue,
12
- getTypeOf
12
+ getTypeOf,
13
+ checkRule
13
14
  } = rulesMatcherUtils
14
15
 
15
16
  describe('rulesMatcherUtils', () => {
@@ -64,4 +65,33 @@ describe('rulesMatcherUtils', () => {
64
65
  expect(getPath('^data.name')).toBe('data.name')
65
66
  expect(getPath('$data.name')).toBe('$data.name')
66
67
  })
68
+
69
+ it('evaluates plain objects with multiple keys as AND conditions', () => {
70
+ const data = {
71
+ '%%root': { accountId: 'acc-1' },
72
+ '%%user': { custom_data: { accountId: 'acc-1', role: 'admin' } }
73
+ }
74
+
75
+ expect(
76
+ checkRule(
77
+ {
78
+ '%%root.accountId': '$ref:%%user.custom_data.accountId',
79
+ '%%user.custom_data.role': 'admin'
80
+ } as any,
81
+ data,
82
+ {}
83
+ )
84
+ ).toBe(true)
85
+
86
+ expect(
87
+ checkRule(
88
+ {
89
+ '%%root.accountId': '$ref:%%user.custom_data.accountId',
90
+ '%%user.custom_data.role': 'staff'
91
+ } as any,
92
+ data,
93
+ {}
94
+ )
95
+ ).toBe(false)
96
+ })
67
97
  })
@@ -37,6 +37,9 @@ export const STEP_B_STATES: States = {
37
37
  })
38
38
  const check = await evaluateTopLevelPermissionsFn(context, 'write')
39
39
  if (check) {
40
+ if (context.params.type === 'write') {
41
+ return endValidation({ success: true })
42
+ }
40
43
  return next('evaluateTopLevelInsert')
41
44
  }
42
45
  if (check === false) {
@@ -267,6 +267,20 @@ const rulesMatcherUtils: RulesMatcherUtils = {
267
267
  )
268
268
  }
269
269
 
270
+ if (!Array.isArray(block) && block && typeof block === 'object') {
271
+ const keys = Object.keys(block)
272
+ const hasLogicalOperators = keys.some((key) => key === '$and' || key === '$or')
273
+ if (!hasLogicalOperators && keys.length > 1) {
274
+ return keys.every((key) =>
275
+ rulesMatcherUtils.checkRule(
276
+ { [key]: (block as Record<string, unknown>)[key] } as any,
277
+ data,
278
+ options
279
+ )
280
+ )
281
+ }
282
+ }
283
+
270
284
  const res = rulesMatcherUtils.rule(block, data, options)
271
285
  return res.valid
272
286
  },