@flowerforce/flowerbase 1.0.1-beta.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/CHANGELOG.md +0 -0
- package/LICENSE +3 -0
- package/README.md +18 -0
- package/dist/auth/controller.d.ts +8 -0
- package/dist/auth/controller.d.ts.map +1 -0
- package/dist/auth/controller.js +76 -0
- package/dist/auth/dtos.d.ts +6 -0
- package/dist/auth/dtos.d.ts.map +1 -0
- package/dist/auth/dtos.js +2 -0
- package/dist/auth/plugins/jwt.d.ts +14 -0
- package/dist/auth/plugins/jwt.d.ts.map +1 -0
- package/dist/auth/plugins/jwt.js +68 -0
- package/dist/auth/providers/local-userpass/controller.d.ts +8 -0
- package/dist/auth/providers/local-userpass/controller.d.ts.map +1 -0
- package/dist/auth/providers/local-userpass/controller.js +184 -0
- package/dist/auth/providers/local-userpass/dtos.d.ts +35 -0
- package/dist/auth/providers/local-userpass/dtos.d.ts.map +1 -0
- package/dist/auth/providers/local-userpass/dtos.js +2 -0
- package/dist/auth/utils.d.ts +126 -0
- package/dist/auth/utils.d.ts.map +1 -0
- package/dist/auth/utils.js +122 -0
- package/dist/constants.d.ts +18 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +34 -0
- package/dist/features/endpoints/index.d.ts +10 -0
- package/dist/features/endpoints/index.d.ts.map +1 -0
- package/dist/features/endpoints/index.js +31 -0
- package/dist/features/endpoints/interface.d.ts +27 -0
- package/dist/features/endpoints/interface.d.ts.map +1 -0
- package/dist/features/endpoints/interface.js +2 -0
- package/dist/features/endpoints/utils.d.ts +31 -0
- package/dist/features/endpoints/utils.d.ts.map +1 -0
- package/dist/features/endpoints/utils.js +85 -0
- package/dist/features/functions/controller.d.ts +9 -0
- package/dist/features/functions/controller.d.ts.map +1 -0
- package/dist/features/functions/controller.js +88 -0
- package/dist/features/functions/dtos.d.ts +34 -0
- package/dist/features/functions/dtos.d.ts.map +1 -0
- package/dist/features/functions/dtos.js +2 -0
- package/dist/features/functions/index.d.ts +9 -0
- package/dist/features/functions/index.d.ts.map +1 -0
- package/dist/features/functions/index.js +28 -0
- package/dist/features/functions/interface.d.ts +32 -0
- package/dist/features/functions/interface.d.ts.map +1 -0
- package/dist/features/functions/interface.js +2 -0
- package/dist/features/functions/utils.d.ts +23 -0
- package/dist/features/functions/utils.d.ts.map +1 -0
- package/dist/features/functions/utils.js +75 -0
- package/dist/features/rules/index.d.ts +1 -0
- package/dist/features/rules/index.d.ts.map +1 -0
- package/dist/features/rules/index.js +1 -0
- package/dist/features/rules/interface.d.ts +22 -0
- package/dist/features/rules/interface.d.ts.map +1 -0
- package/dist/features/rules/interface.js +2 -0
- package/dist/features/rules/utils.d.ts +3 -0
- package/dist/features/rules/utils.d.ts.map +1 -0
- package/dist/features/rules/utils.js +31 -0
- package/dist/features/triggers/dtos.d.ts +9 -0
- package/dist/features/triggers/dtos.d.ts.map +1 -0
- package/dist/features/triggers/dtos.js +2 -0
- package/dist/features/triggers/index.d.ts +10 -0
- package/dist/features/triggers/index.d.ts.map +1 -0
- package/dist/features/triggers/index.js +57 -0
- package/dist/features/triggers/interface.d.ts +44 -0
- package/dist/features/triggers/interface.d.ts.map +1 -0
- package/dist/features/triggers/interface.js +2 -0
- package/dist/features/triggers/utils.d.ts +16 -0
- package/dist/features/triggers/utils.d.ts.map +1 -0
- package/dist/features/triggers/utils.js +153 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +84 -0
- package/dist/model.d.ts +2 -0
- package/dist/model.d.ts.map +1 -0
- package/dist/model.js +2 -0
- package/dist/services/api/index.d.ts +36 -0
- package/dist/services/api/index.d.ts.map +1 -0
- package/dist/services/api/index.js +36 -0
- package/dist/services/api/model.d.ts +33 -0
- package/dist/services/api/model.d.ts.map +1 -0
- package/dist/services/api/model.js +2 -0
- package/dist/services/api/utils.d.ts +16 -0
- package/dist/services/api/utils.d.ts.map +1 -0
- package/dist/services/api/utils.js +45 -0
- package/dist/services/aws/index.d.ts +13 -0
- package/dist/services/aws/index.d.ts.map +1 -0
- package/dist/services/aws/index.js +50 -0
- package/dist/services/index.d.ts +41 -0
- package/dist/services/index.d.ts.map +1 -0
- package/dist/services/index.js +14 -0
- package/dist/services/interface.d.ts +3 -0
- package/dist/services/interface.d.ts.map +1 -0
- package/dist/services/interface.js +2 -0
- package/dist/services/mongodb-atlas/index.d.ts +4 -0
- package/dist/services/mongodb-atlas/index.d.ts.map +1 -0
- package/dist/services/mongodb-atlas/index.js +483 -0
- package/dist/services/mongodb-atlas/model.d.ts +39 -0
- package/dist/services/mongodb-atlas/model.d.ts.map +1 -0
- package/dist/services/mongodb-atlas/model.js +2 -0
- package/dist/services/mongodb-atlas/utils.d.ts +8 -0
- package/dist/services/mongodb-atlas/utils.d.ts.map +1 -0
- package/dist/services/mongodb-atlas/utils.js +33 -0
- package/dist/state.d.ts +6 -0
- package/dist/state.d.ts.map +1 -0
- package/dist/state.js +18 -0
- package/dist/utils/context/helpers.d.ts +74 -0
- package/dist/utils/context/helpers.d.ts.map +1 -0
- package/dist/utils/context/helpers.js +60 -0
- package/dist/utils/context/index.d.ts +14 -0
- package/dist/utils/context/index.d.ts.map +1 -0
- package/dist/utils/context/index.js +50 -0
- package/dist/utils/context/interface.d.ts +18 -0
- package/dist/utils/context/interface.d.ts.map +1 -0
- package/dist/utils/context/interface.js +2 -0
- package/dist/utils/crypto/index.d.ts +19 -0
- package/dist/utils/crypto/index.d.ts.map +1 -0
- package/dist/utils/crypto/index.js +50 -0
- package/dist/utils/helpers/someAsync.d.ts +12 -0
- package/dist/utils/helpers/someAsync.d.ts.map +1 -0
- package/dist/utils/helpers/someAsync.js +56 -0
- package/dist/utils/index.d.ts +3 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +11 -0
- package/dist/utils/initializer/exposeRoutes.d.ts +8 -0
- package/dist/utils/initializer/exposeRoutes.d.ts.map +1 -0
- package/dist/utils/initializer/exposeRoutes.js +41 -0
- package/dist/utils/initializer/registerPlugins.d.ts +19 -0
- package/dist/utils/initializer/registerPlugins.d.ts.map +1 -0
- package/dist/utils/initializer/registerPlugins.js +84 -0
- package/dist/utils/roles/helpers.d.ts +4 -0
- package/dist/utils/roles/helpers.d.ts.map +1 -0
- package/dist/utils/roles/helpers.js +47 -0
- package/dist/utils/roles/interface.d.ts +33 -0
- package/dist/utils/roles/interface.d.ts.map +1 -0
- package/dist/utils/roles/interface.js +2 -0
- package/dist/utils/roles/machines/commonValidators.d.ts +6 -0
- package/dist/utils/roles/machines/commonValidators.d.ts.map +1 -0
- package/dist/utils/roles/machines/commonValidators.js +34 -0
- package/dist/utils/roles/machines/index.d.ts +14 -0
- package/dist/utils/roles/machines/index.d.ts.map +1 -0
- package/dist/utils/roles/machines/index.js +27 -0
- package/dist/utils/roles/machines/interface.d.ts +46 -0
- package/dist/utils/roles/machines/interface.d.ts.map +1 -0
- package/dist/utils/roles/machines/interface.js +2 -0
- package/dist/utils/roles/machines/machine.d.ts +15 -0
- package/dist/utils/roles/machines/machine.d.ts.map +1 -0
- package/dist/utils/roles/machines/machine.js +97 -0
- package/dist/utils/roles/machines/read/A/index.d.ts +3 -0
- package/dist/utils/roles/machines/read/A/index.d.ts.map +1 -0
- package/dist/utils/roles/machines/read/A/index.js +27 -0
- package/dist/utils/roles/machines/read/B/index.d.ts +3 -0
- package/dist/utils/roles/machines/read/B/index.d.ts.map +1 -0
- package/dist/utils/roles/machines/read/B/index.js +36 -0
- package/dist/utils/roles/machines/read/C/index.d.ts +3 -0
- package/dist/utils/roles/machines/read/C/index.d.ts.map +1 -0
- package/dist/utils/roles/machines/read/C/index.js +38 -0
- package/dist/utils/roles/machines/read/D/index.d.ts +3 -0
- package/dist/utils/roles/machines/read/D/index.d.ts.map +1 -0
- package/dist/utils/roles/machines/read/D/index.js +26 -0
- package/dist/utils/roles/machines/read/D/validators.d.ts +4 -0
- package/dist/utils/roles/machines/read/D/validators.d.ts.map +1 -0
- package/dist/utils/roles/machines/read/D/validators.js +24 -0
- package/dist/utils/roles/machines/read/index.d.ts +2 -0
- package/dist/utils/roles/machines/read/index.d.ts.map +1 -0
- package/dist/utils/roles/machines/read/index.js +8 -0
- package/dist/utils/roles/machines/utils.d.ts +37 -0
- package/dist/utils/roles/machines/utils.d.ts.map +1 -0
- package/dist/utils/roles/machines/utils.js +54 -0
- package/dist/utils/roles/machines/write/A/index.d.ts +3 -0
- package/dist/utils/roles/machines/write/A/index.d.ts.map +1 -0
- package/dist/utils/roles/machines/write/A/index.js +29 -0
- package/dist/utils/roles/machines/write/B/index.d.ts +3 -0
- package/dist/utils/roles/machines/write/B/index.d.ts.map +1 -0
- package/dist/utils/roles/machines/write/B/index.js +47 -0
- package/dist/utils/roles/machines/write/C/index.d.ts +3 -0
- package/dist/utils/roles/machines/write/C/index.d.ts.map +1 -0
- package/dist/utils/roles/machines/write/C/index.js +26 -0
- package/dist/utils/roles/machines/write/C/validators.d.ts +4 -0
- package/dist/utils/roles/machines/write/C/validators.d.ts.map +1 -0
- package/dist/utils/roles/machines/write/C/validators.js +24 -0
- package/dist/utils/roles/machines/write/index.d.ts +2 -0
- package/dist/utils/roles/machines/write/index.d.ts.map +1 -0
- package/dist/utils/roles/machines/write/index.js +7 -0
- package/dist/utils/rules-matcher/interface.d.ts +338 -0
- package/dist/utils/rules-matcher/interface.d.ts.map +1 -0
- package/dist/utils/rules-matcher/interface.js +26 -0
- package/dist/utils/rules-matcher/utils.d.ts +11 -0
- package/dist/utils/rules-matcher/utils.d.ts.map +1 -0
- package/dist/utils/rules-matcher/utils.js +214 -0
- package/dist/utils/rules.d.ts +2 -0
- package/dist/utils/rules.d.ts.map +1 -0
- package/dist/utils/rules.js +22 -0
- package/jest.config.ts +24 -0
- package/package.json +63 -0
- package/project.json +10 -0
- package/rollup.config.js +17 -0
- package/src/auth/controller.ts +78 -0
- package/src/auth/dtos.ts +6 -0
- package/src/auth/plugins/jwt.ts +68 -0
- package/src/auth/providers/local-userpass/controller.ts +226 -0
- package/src/auth/providers/local-userpass/dtos.ts +40 -0
- package/src/auth/utils.ts +165 -0
- package/src/babel.config.json +3 -0
- package/src/constants.ts +22 -0
- package/src/fastify.d.ts +28 -0
- package/src/features/endpoints/index.ts +27 -0
- package/src/features/endpoints/interface.ts +29 -0
- package/src/features/endpoints/utils.ts +72 -0
- package/src/features/functions/controller.ts +102 -0
- package/src/features/functions/dtos.ts +41 -0
- package/src/features/functions/index.ts +21 -0
- package/src/features/functions/interface.ts +38 -0
- package/src/features/functions/utils.ts +82 -0
- package/src/features/rules/index.tsx +0 -0
- package/src/features/rules/interface.ts +24 -0
- package/src/features/rules/utils.ts +20 -0
- package/src/features/triggers/dtos.ts +9 -0
- package/src/features/triggers/index.ts +34 -0
- package/src/features/triggers/interface.ts +44 -0
- package/src/features/triggers/utils.ts +157 -0
- package/src/global.d.ts +0 -0
- package/src/index.ts +75 -0
- package/src/model.ts +1 -0
- package/src/services/api/index.ts +50 -0
- package/src/services/api/model.ts +38 -0
- package/src/services/api/utils.ts +39 -0
- package/src/services/aws/index.ts +48 -0
- package/src/services/index.ts +9 -0
- package/src/services/interface.ts +3 -0
- package/src/services/mongodb-atlas/index.ts +569 -0
- package/src/services/mongodb-atlas/model.ts +67 -0
- package/src/services/mongodb-atlas/utils.ts +44 -0
- package/src/state.ts +24 -0
- package/src/utils/__tests__/STEP_A_STATES.test.ts +54 -0
- package/src/utils/__tests__/STEP_B_STATES.test.ts +113 -0
- package/src/utils/__tests__/STEP_C_STATES.test.ts +87 -0
- package/src/utils/__tests__/STEP_D_STATES.test.ts +93 -0
- package/src/utils/__tests__/checkAdditionalFieldsFn.test.ts +45 -0
- package/src/utils/__tests__/checkApplyWhen.test.ts +49 -0
- package/src/utils/__tests__/checkFieldsPropertyExists.test.ts +47 -0
- package/src/utils/__tests__/checkIsValidFieldNameFn.test.ts +190 -0
- package/src/utils/__tests__/comparePassword.test.ts +38 -0
- package/src/utils/__tests__/evaluateDocumentsFiltersReadFn.test.ts +57 -0
- package/src/utils/__tests__/evaluateDocumentsFiltersWriteFn.test.ts +57 -0
- package/src/utils/__tests__/evaluateTopLevelReadFn.test.ts +58 -0
- package/src/utils/__tests__/evaluateTopLevelWriteFn.test.ts +66 -0
- package/src/utils/__tests__/exposeRoutes.test.ts +65 -0
- package/src/utils/__tests__/generateContextData.test.ts +75 -0
- package/src/utils/__tests__/getDefaultRule.test.ts +29 -0
- package/src/utils/__tests__/getKey.test.ts +12 -0
- package/src/utils/__tests__/getKeys.test.ts +11 -0
- package/src/utils/__tests__/getWinningRole.test.ts +66 -0
- package/src/utils/__tests__/hashPassword.test.ts +28 -0
- package/src/utils/__tests__/isEmpty.test.ts +17 -0
- package/src/utils/__tests__/logMachineInfo.test.ts +15 -0
- package/src/utils/__tests__/operators.test.ts +99 -0
- package/src/utils/__tests__/readFileContent.test.ts +35 -0
- package/src/utils/__tests__/registerPlugins.test.ts +59 -0
- package/src/utils/__tests__/rule.test.ts +51 -0
- package/src/utils/__tests__/rulesMatcherInterfaces.test.ts +57 -0
- package/src/utils/__tests__/rulesMatcherUtils.test.ts +56 -0
- package/src/utils/__tests__/someAsync.test.ts +55 -0
- package/src/utils/context/helpers.ts +71 -0
- package/src/utils/context/index.ts +52 -0
- package/src/utils/context/interface.ts +19 -0
- package/src/utils/crypto/index.ts +36 -0
- package/src/utils/helpers/someAsync.ts +24 -0
- package/src/utils/index.ts +5 -0
- package/src/utils/initializer/exposeRoutes.ts +26 -0
- package/src/utils/initializer/registerPlugins.ts +97 -0
- package/src/utils/roles/helpers.ts +47 -0
- package/src/utils/roles/interface.ts +42 -0
- package/src/utils/roles/machines/commonValidators.ts +24 -0
- package/src/utils/roles/machines/index.ts +20 -0
- package/src/utils/roles/machines/interface.ts +46 -0
- package/src/utils/roles/machines/machine.ts +85 -0
- package/src/utils/roles/machines/read/A/index.ts +19 -0
- package/src/utils/roles/machines/read/B/index.ts +31 -0
- package/src/utils/roles/machines/read/C/index.ts +30 -0
- package/src/utils/roles/machines/read/D/index.ts +20 -0
- package/src/utils/roles/machines/read/D/validators.ts +24 -0
- package/src/utils/roles/machines/read/index.ts +6 -0
- package/src/utils/roles/machines/utils.ts +54 -0
- package/src/utils/roles/machines/write/A/index.ts +25 -0
- package/src/utils/roles/machines/write/B/index.ts +43 -0
- package/src/utils/roles/machines/write/C/index.ts +20 -0
- package/src/utils/roles/machines/write/C/validators.ts +24 -0
- package/src/utils/roles/machines/write/index.ts +5 -0
- package/src/utils/rules-matcher/interface.ts +365 -0
- package/src/utils/rules-matcher/utils.ts +281 -0
- package/src/utils/rules.ts +19 -0
- package/tsconfig.json +28 -0
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
|
|
2
|
+
import { Document, ObjectId, WithId } from "mongodb"
|
|
3
|
+
import { User } from '../../auth/dtos';
|
|
4
|
+
import { Role } from "../roles/interface";
|
|
5
|
+
import * as Utils from "../roles/machines/utils";
|
|
6
|
+
|
|
7
|
+
const { getWinningRole } = Utils
|
|
8
|
+
|
|
9
|
+
const mockUser = {
|
|
10
|
+
id: 'user123',
|
|
11
|
+
role: 'admin',
|
|
12
|
+
name: 'Test User',
|
|
13
|
+
} as User;
|
|
14
|
+
|
|
15
|
+
const mockDocument = {
|
|
16
|
+
_id: new ObjectId(),
|
|
17
|
+
field: 'value',
|
|
18
|
+
} as WithId<Document>;
|
|
19
|
+
|
|
20
|
+
const mockRoles = [
|
|
21
|
+
{ name: 'Editor', apply_when: { condition: 'test' } },
|
|
22
|
+
{ name: 'Viewer', apply_when: { condition: 'other' } }
|
|
23
|
+
] as Role[]
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
describe('getWinningRole', () => {
|
|
27
|
+
beforeEach(() => {
|
|
28
|
+
jest.clearAllMocks();
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it('should return null if roles array is empty', () => {
|
|
32
|
+
expect(getWinningRole(mockDocument, mockUser, [])).toBeNull();
|
|
33
|
+
expect(getWinningRole(mockDocument, mockUser, undefined)).toBeNull();
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it('should return the first matching role', () => {
|
|
37
|
+
const mockCheckApplyWhen = jest.spyOn(Utils, "checkApplyWhen").mockReturnValueOnce(true)
|
|
38
|
+
const result = getWinningRole(mockDocument, mockUser, mockRoles);
|
|
39
|
+
expect(result).toEqual(mockRoles[0]);
|
|
40
|
+
expect(mockCheckApplyWhen).toHaveBeenCalledWith(mockRoles[0].apply_when, mockUser, mockDocument);
|
|
41
|
+
expect(mockCheckApplyWhen).toHaveBeenCalledTimes(1);
|
|
42
|
+
mockCheckApplyWhen.mockReset()
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it('should return null if no roles match', () => {
|
|
46
|
+
const mockCheckApplyWhen = jest.spyOn(Utils, "checkApplyWhen").mockReturnValue(false)
|
|
47
|
+
const result = getWinningRole(mockDocument, mockUser, mockRoles);
|
|
48
|
+
expect(result).toBeNull();
|
|
49
|
+
expect(mockCheckApplyWhen).toHaveBeenCalledTimes(mockRoles.length);
|
|
50
|
+
mockCheckApplyWhen.mockReset()
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
it('should check all roles until it finds a match', () => {
|
|
54
|
+
const mockCheckApplyWhen = jest.spyOn(Utils, "checkApplyWhen").mockReturnValueOnce(false).mockReturnValueOnce(true)
|
|
55
|
+
const result = getWinningRole(mockDocument, mockUser, mockRoles);
|
|
56
|
+
expect(result).toEqual(mockRoles[1]);
|
|
57
|
+
expect(mockCheckApplyWhen).toHaveBeenCalledTimes(2);
|
|
58
|
+
mockCheckApplyWhen.mockReset()
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
it('should handle null document correctly', () => {
|
|
62
|
+
jest.spyOn(Utils, "checkApplyWhen").mockReturnValue(true)
|
|
63
|
+
const result = getWinningRole(null, mockUser, mockRoles);
|
|
64
|
+
expect(result).toEqual(mockRoles[0]);
|
|
65
|
+
});
|
|
66
|
+
});
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { hashPassword } from '../crypto';
|
|
2
|
+
|
|
3
|
+
describe('hashPassword', () => {
|
|
4
|
+
beforeEach(() => {
|
|
5
|
+
jest.clearAllMocks();
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
it('should return a hashed password with a valid format', async () => {
|
|
9
|
+
const plaintext = 'mySecretPassword';
|
|
10
|
+
const hashedPassword = await hashPassword(plaintext);
|
|
11
|
+
expect(hashedPassword).toMatch(/^[a-f0-9]+\.[a-f0-9]+$/);
|
|
12
|
+
const [storedHash, salt] = hashedPassword.split('.');
|
|
13
|
+
expect(storedHash).toBeDefined();
|
|
14
|
+
expect(salt).toBeDefined();
|
|
15
|
+
});
|
|
16
|
+
it('should generate different hashes for different passwords', async () => {
|
|
17
|
+
const hash1 = await hashPassword('password1');
|
|
18
|
+
const hash2 = await hashPassword('password2');
|
|
19
|
+
expect(hash1).not.toBe(hash2);
|
|
20
|
+
});
|
|
21
|
+
it('should generate different hashes for the same password (due to different salts)', async () => {
|
|
22
|
+
const plaintext = 'samePassword';
|
|
23
|
+
const hash1 = await hashPassword(plaintext);
|
|
24
|
+
const hash2 = await hashPassword(plaintext);
|
|
25
|
+
expect(hash1).not.toBe(hash2);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
});
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import rulesMatcherUtils from "../rules-matcher/utils";
|
|
2
|
+
|
|
3
|
+
describe('isEmpty', () => {
|
|
4
|
+
|
|
5
|
+
it('should check if a value is Empty', () => {
|
|
6
|
+
expect(rulesMatcherUtils.isEmpty(undefined)).toBe(true)
|
|
7
|
+
expect(rulesMatcherUtils.isEmpty(null)).toBe(true)
|
|
8
|
+
expect(rulesMatcherUtils.isEmpty(() => { })).toBe(false)
|
|
9
|
+
expect(rulesMatcherUtils.isEmpty("")).toBe(true)
|
|
10
|
+
expect(rulesMatcherUtils.isEmpty("test")).toBe(false)
|
|
11
|
+
expect(rulesMatcherUtils.isEmpty(["test"])).toBe(false)
|
|
12
|
+
expect(rulesMatcherUtils.isEmpty([])).toBe(true)
|
|
13
|
+
expect(rulesMatcherUtils.isEmpty({})).toBe(true)
|
|
14
|
+
expect(rulesMatcherUtils.isEmpty({ some: "test" })).toBe(false)
|
|
15
|
+
expect(rulesMatcherUtils.isEmpty(new Date())).toBe(false)
|
|
16
|
+
});
|
|
17
|
+
});
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { logMachineInfo } from "../roles/machines/utils";
|
|
2
|
+
|
|
3
|
+
describe('logMachineInfo', () => {
|
|
4
|
+
beforeEach(() => {
|
|
5
|
+
jest.clearAllMocks();
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
it('should log all the info only if enabled', () => {
|
|
9
|
+
const log = jest.spyOn(console, "log").mockImplementation()
|
|
10
|
+
logMachineInfo({ enabled: true, machine: "A", step: 1, stepName: "test" })
|
|
11
|
+
logMachineInfo({ enabled: false, machine: "A", step: 1, stepName: "test" })
|
|
12
|
+
expect(log).toHaveBeenNthCalledWith(1, "MACHINE A -> STEP 1: test")
|
|
13
|
+
log.mockRestore()
|
|
14
|
+
});
|
|
15
|
+
});
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { operators } from "../rules-matcher/utils";
|
|
2
|
+
|
|
3
|
+
describe('operators', () => {
|
|
4
|
+
beforeEach(() => {
|
|
5
|
+
jest.clearAllMocks();
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
it("should check equals values", () => {
|
|
9
|
+
expect(operators.$eq("a", "a")).toBe(true)
|
|
10
|
+
expect(!operators.$eq("a", "b")).toBe(true)
|
|
11
|
+
})
|
|
12
|
+
it("should check different values", () => {
|
|
13
|
+
expect(operators.$ne("a", "a")).toBe(false)
|
|
14
|
+
expect(operators.$ne("a", "b")).toBe(true)
|
|
15
|
+
})
|
|
16
|
+
it("should check string length values", () => {
|
|
17
|
+
// test $strGt
|
|
18
|
+
expect(operators.$strGt("test", 2)).toBe(true)
|
|
19
|
+
expect(operators.$strGt("test", 15)).toBe(false)
|
|
20
|
+
expect(operators.$strGt("test", 4)).toBe(false)
|
|
21
|
+
// test $strGte
|
|
22
|
+
expect(operators.$strGte("test", 2)).toBe(true)
|
|
23
|
+
expect(operators.$strGte("test", 15)).toBe(false)
|
|
24
|
+
expect(operators.$strGte("test", 4)).toBe(true)
|
|
25
|
+
// test $strLt
|
|
26
|
+
expect(operators.$strLt("test", 2)).toBe(false)
|
|
27
|
+
expect(operators.$strLt("test", 15)).toBe(true)
|
|
28
|
+
expect(operators.$strLt("test", 4)).toBe(false)
|
|
29
|
+
// test $strLte
|
|
30
|
+
expect(operators.$strLte("test", 2)).toBe(false)
|
|
31
|
+
expect(operators.$strLte("test", 15)).toBe(true)
|
|
32
|
+
expect(operators.$strLte("test", 4)).toBe(true)
|
|
33
|
+
})
|
|
34
|
+
it("should check if a value exists", () => {
|
|
35
|
+
expect(operators.$exists({ name: 1 }, true)).toBe(true)
|
|
36
|
+
expect(operators.$exists({}, false)).toBe(true)
|
|
37
|
+
expect(operators.$exists({}, true)).toBe(false)
|
|
38
|
+
expect(operators.$exists(undefined, false)).toBe(true)
|
|
39
|
+
expect(operators.$exists(null, true)).toBe(false)
|
|
40
|
+
expect(operators.$exists("", true)).toBe(false)
|
|
41
|
+
expect(operators.$exists("test", true)).toBe(true)
|
|
42
|
+
expect(operators.$exists(0, true)).toBe(true)
|
|
43
|
+
expect(operators.$exists([], true)).toBe(false)
|
|
44
|
+
expect(operators.$exists([1], true)).toBe(true)
|
|
45
|
+
expect(operators.$exists(new Date(), true)).toBe(true)
|
|
46
|
+
expect(operators.$exists(() => { }, true)).toBe(true)
|
|
47
|
+
})
|
|
48
|
+
it("should compare numbers", () => {
|
|
49
|
+
// test $gt
|
|
50
|
+
expect(operators.$gt(2, 3)).toBe(false)
|
|
51
|
+
expect(operators.$gt(2, 2)).toBe(false)
|
|
52
|
+
expect(operators.$gt(3, 2)).toBe(true)
|
|
53
|
+
// test $gte
|
|
54
|
+
expect(operators.$gte(2, 3)).toBe(false)
|
|
55
|
+
expect(operators.$gte(2, 2)).toBe(true)
|
|
56
|
+
expect(operators.$gte(3, 2)).toBe(true)
|
|
57
|
+
// test $lt
|
|
58
|
+
expect(operators.$lt(2, 3)).toBe(true)
|
|
59
|
+
expect(operators.$lt(2, 2)).toBe(false)
|
|
60
|
+
expect(operators.$lt(3, 2)).toBe(false)
|
|
61
|
+
// test $lte
|
|
62
|
+
expect(operators.$lte(2, 3)).toBe(true)
|
|
63
|
+
expect(operators.$lte(2, 2)).toBe(true)
|
|
64
|
+
expect(operators.$lte(3, 2)).toBe(false)
|
|
65
|
+
}
|
|
66
|
+
)
|
|
67
|
+
it("should find a value in an array", () => {
|
|
68
|
+
expect(operators.$in(2, [3])).toBe(false)
|
|
69
|
+
expect(operators.$in(3, [3, 4, 5])).toBe(true)
|
|
70
|
+
expect(operators.$in([3, 4], [3, 4, 5])).toBe(true)
|
|
71
|
+
expect(operators.$in([3, 6], [3, 4, 5])).toBe(true)
|
|
72
|
+
expect(operators.$in({ name: "ciao" }, [{ name: "ciao" }, 4, 5])).toBe(false)
|
|
73
|
+
})
|
|
74
|
+
it("should check if a value isn't in an array", () => {
|
|
75
|
+
expect(operators.$nin(2, [3])).toBe(true)
|
|
76
|
+
expect(operators.$nin(3, [3, 4, 5])).toBe(false)
|
|
77
|
+
expect(operators.$nin([3, 4], [3, 4, 5])).toBe(false)
|
|
78
|
+
expect(operators.$nin([3, 6], [3, 4, 5])).toBe(false)
|
|
79
|
+
expect(operators.$nin({ name: "ciao" }, [{ name: "ciao" }, 4, 5])).toBe(true)
|
|
80
|
+
})
|
|
81
|
+
it("should find all values in an array", () => {
|
|
82
|
+
expect(operators.$all(2, [3])).toBe(false)
|
|
83
|
+
expect(operators.$all(3, [3, 4, 5])).toBe(false)
|
|
84
|
+
expect(operators.$all([3], [3, 4, 5])).toBe(false)
|
|
85
|
+
expect(operators.$all([3, 4, 5], [3, 4, 5])).toBe(true)
|
|
86
|
+
expect(operators.$all([3, 6], [3, 4, 5])).toBe(false)
|
|
87
|
+
expect(operators.$all({ name: "ciao" }, [{ name: "ciao" }, 4, 5])).toBe(false)
|
|
88
|
+
expect(operators.$all([{ name: "ciao" }, 4, 5], [{ name: "ciao" }, 4, 5])).toBe(false)
|
|
89
|
+
})
|
|
90
|
+
it("should check regex", () => {
|
|
91
|
+
const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/
|
|
92
|
+
expect(operators.$regex("test@gmail.com", emailRegex)).toBe(true)
|
|
93
|
+
expect(operators.$regex("test.com", emailRegex)).toBe(false)
|
|
94
|
+
const numberRegex = /^\d+$/
|
|
95
|
+
expect(operators.$regex("1234567890", numberRegex)).toBe(true)
|
|
96
|
+
expect(operators.$regex("12345r", numberRegex)).toBe(false)
|
|
97
|
+
|
|
98
|
+
})
|
|
99
|
+
});
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import { readFileContent, readJsonContent } from '..';
|
|
3
|
+
|
|
4
|
+
jest.mock('fs');
|
|
5
|
+
|
|
6
|
+
describe('File Reading Functions', () => {
|
|
7
|
+
const mockFilePath = '/mock/path/file.txt';
|
|
8
|
+
const mockJsonPath = '/mock/path/data.json';
|
|
9
|
+
|
|
10
|
+
beforeEach(() => {
|
|
11
|
+
jest.clearAllMocks();
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
it('should read file content correctly', () => {
|
|
15
|
+
const mockContent = 'Hello, world!';
|
|
16
|
+
(fs.readFileSync as jest.Mock).mockReturnValue(mockContent);
|
|
17
|
+
const result = readFileContent(mockFilePath);
|
|
18
|
+
expect(fs.readFileSync).toHaveBeenCalledWith(mockFilePath, 'utf-8');
|
|
19
|
+
expect(result).toBe(mockContent);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it('should read JSON content correctly', () => {
|
|
23
|
+
const mockJsonContent = '{"name": "Alice", "age": 30}';
|
|
24
|
+
(fs.readFileSync as jest.Mock).mockReturnValue(mockJsonContent);
|
|
25
|
+
const result = readJsonContent(mockJsonPath);
|
|
26
|
+
expect(fs.readFileSync).toHaveBeenCalledWith(mockJsonPath, 'utf-8');
|
|
27
|
+
expect(result).toEqual(JSON.parse(mockJsonContent));
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it('should throw an error when JSON is invalid', () => {
|
|
31
|
+
const invalidJson = '{name: Alice, age: 30}';
|
|
32
|
+
(fs.readFileSync as jest.Mock).mockReturnValue(invalidJson);
|
|
33
|
+
expect(() => readJsonContent(mockJsonPath)).toThrow(SyntaxError);
|
|
34
|
+
});
|
|
35
|
+
});
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import cors from '@fastify/cors'
|
|
2
|
+
import fastifyMongodb from '@fastify/mongodb'
|
|
3
|
+
import { authController } from '../../auth/controller'
|
|
4
|
+
import jwtAuthPlugin from '../../auth/plugins/jwt'
|
|
5
|
+
import { localUserPassController } from '../../auth/providers/local-userpass/controller'
|
|
6
|
+
import { Functions } from '../../features/functions/interface'
|
|
7
|
+
import { registerPlugins } from '../initializer/registerPlugins'
|
|
8
|
+
|
|
9
|
+
const MOCKED_API_VERSION = '/api/client/v2'
|
|
10
|
+
|
|
11
|
+
jest.mock('../../constants', () => ({
|
|
12
|
+
API_VERSION: '/api/client/v2'
|
|
13
|
+
}))
|
|
14
|
+
|
|
15
|
+
const mockDbUrl = 'mongodb://localhost:27017/testdb'
|
|
16
|
+
const mockSecret = 'test-secret'
|
|
17
|
+
|
|
18
|
+
const errorMock = jest.fn().mockImplementation(() => {
|
|
19
|
+
throw new Error('Plugin registration failed')
|
|
20
|
+
})
|
|
21
|
+
const registerMock = jest.fn()
|
|
22
|
+
|
|
23
|
+
describe('registerPlugins', () => {
|
|
24
|
+
beforeEach(() => {
|
|
25
|
+
jest.clearAllMocks();
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it('should register all plugins successfully', async () => {
|
|
29
|
+
await registerPlugins({
|
|
30
|
+
register: registerMock,
|
|
31
|
+
mongodbUrl: mockDbUrl,
|
|
32
|
+
jwtSecret: mockSecret,
|
|
33
|
+
functionsList: {} as Functions
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
// Check Plugins Registration
|
|
37
|
+
expect(registerMock).toHaveBeenCalledTimes(5)
|
|
38
|
+
expect(registerMock).toHaveBeenCalledWith(cors, { origin: '*', methods: ['POST', 'GET'] })
|
|
39
|
+
expect(registerMock).toHaveBeenCalledWith(fastifyMongodb, { forceClose: true, url: mockDbUrl })
|
|
40
|
+
expect(registerMock).toHaveBeenCalledWith(jwtAuthPlugin, { secret: mockSecret })
|
|
41
|
+
expect(registerMock).toHaveBeenCalledWith(authController, { prefix: `${MOCKED_API_VERSION}/auth` })
|
|
42
|
+
expect(registerMock).toHaveBeenCalledWith(localUserPassController, { prefix: `${MOCKED_API_VERSION}/app/:appId/auth/providers/local-userpass` })
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
it('should handle errors in the catch block', async () => {
|
|
46
|
+
|
|
47
|
+
const errorLog = jest.spyOn(console, 'error').mockImplementation(() => { })
|
|
48
|
+
|
|
49
|
+
await registerPlugins({
|
|
50
|
+
register: errorMock,
|
|
51
|
+
mongodbUrl: mockDbUrl,
|
|
52
|
+
jwtSecret: mockSecret,
|
|
53
|
+
functionsList: {} as Functions
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
expect(errorLog).toHaveBeenCalledWith('Error while registering plugins', 'Plugin registration failed')
|
|
57
|
+
errorLog.mockRestore()
|
|
58
|
+
})
|
|
59
|
+
})
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import rulesMatcherUtils from '../rules-matcher/utils';
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
describe('rule function', () => {
|
|
5
|
+
it('should return valid true if the operator and value match', () => {
|
|
6
|
+
const mockData = {
|
|
7
|
+
user: { name: 'John', age: 25 }
|
|
8
|
+
};
|
|
9
|
+
const mockOptions = { prefix: 'user' };
|
|
10
|
+
const mockValueBlock = { name: { $eq: 'John' } };
|
|
11
|
+
const result = rulesMatcherUtils.rule(mockValueBlock, mockData, mockOptions);
|
|
12
|
+
expect(result.valid).toBe(true);
|
|
13
|
+
expect(result.name).toBe('user.name___$eq');
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
it('should return valid false if the operator and value do not match', () => {
|
|
17
|
+
const mockData = {
|
|
18
|
+
user: { name: 'John', age: 25 }
|
|
19
|
+
};
|
|
20
|
+
const mockOptions = { prefix: 'user' };
|
|
21
|
+
const mockValueBlock = { name: { $eq: 'Doe' } };
|
|
22
|
+
const result = rulesMatcherUtils.rule(mockValueBlock, mockData, mockOptions);
|
|
23
|
+
|
|
24
|
+
expect(result.valid).toBe(false);
|
|
25
|
+
expect(result.name).toBe('user.name___$eq');
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it('should handle $ref: values correctly', () => {
|
|
29
|
+
const mockData = {
|
|
30
|
+
user: { name: 'John', age: 25 }
|
|
31
|
+
};
|
|
32
|
+
const mockOptions = { prefix: 'user' };
|
|
33
|
+
const mockValueBlock = { name: { $eq: '$ref:user.refName' } };
|
|
34
|
+
const result = rulesMatcherUtils.rule(mockValueBlock, mockData, mockOptions);
|
|
35
|
+
|
|
36
|
+
expect(result.valid).toBe(false);
|
|
37
|
+
expect(result.name).toBe('user.name___$eq');
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it('should throw an error if the operator is missing', () => {
|
|
41
|
+
|
|
42
|
+
const mockData = {
|
|
43
|
+
user: { name: 'John', age: 25 }
|
|
44
|
+
};
|
|
45
|
+
const mockOptions = { prefix: 'user' };
|
|
46
|
+
const missingOperatorBlock = { name: { $notFoundOperator: 'value' } };
|
|
47
|
+
expect(() => {
|
|
48
|
+
rulesMatcherUtils.rule(missingOperatorBlock, mockData, mockOptions);
|
|
49
|
+
}).toThrow('Error missing operator:$notFoundOperator');
|
|
50
|
+
});
|
|
51
|
+
});
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { RulesModes, RulesOperators, RulesOperatorsInArray, RulesValuesType } from '../rules-matcher/interface';
|
|
2
|
+
|
|
3
|
+
describe('Enums and Types', () => {
|
|
4
|
+
it('should have correct values in RulesOperators enum', () => {
|
|
5
|
+
expect(RulesOperators.$exists).toBe('$exists');
|
|
6
|
+
expect(RulesOperators.$eq).toBe('$eq');
|
|
7
|
+
expect(RulesOperators.$ne).toBe('$ne');
|
|
8
|
+
expect(RulesOperators.$gt).toBe('$gt');
|
|
9
|
+
expect(RulesOperators.$gte).toBe('$gte');
|
|
10
|
+
expect(RulesOperators.$lt).toBe('$lt');
|
|
11
|
+
expect(RulesOperators.$lte).toBe('$lte');
|
|
12
|
+
expect(RulesOperators.$strGt).toBe('$strGt');
|
|
13
|
+
expect(RulesOperators.$strGte).toBe('$strGte');
|
|
14
|
+
expect(RulesOperators.$strLt).toBe('$strLt');
|
|
15
|
+
expect(RulesOperators.$strLte).toBe('$strLte');
|
|
16
|
+
expect(RulesOperators.$in).toBe('$in');
|
|
17
|
+
expect(RulesOperators.$nin).toBe('$nin');
|
|
18
|
+
expect(RulesOperators.$all).toBe('$all');
|
|
19
|
+
expect(RulesOperators.$regex).toBe('$regex');
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it('should validate RulesOperatorsInArray type', () => {
|
|
23
|
+
const valid: RulesOperatorsInArray<{ age: number }> = {
|
|
24
|
+
age: {
|
|
25
|
+
$gt: 25
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
expect(valid).toHaveProperty('age');
|
|
29
|
+
expect(valid.age).toHaveProperty('$gt', 25);
|
|
30
|
+
const partial: RulesOperatorsInArray<{ name: string }> = {
|
|
31
|
+
name: {
|
|
32
|
+
$eq: 'John Doe'
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
expect(partial).toHaveProperty('name');
|
|
36
|
+
expect(partial.name).toHaveProperty('$eq', 'John Doe');
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it('should validate RulesValuesType type', () => {
|
|
40
|
+
const valid: RulesValuesType<{ age: number }> = {
|
|
41
|
+
"$form.isValid": true,
|
|
42
|
+
age: 30
|
|
43
|
+
};
|
|
44
|
+
expect(valid["$form.isValid"]).toBe(true);
|
|
45
|
+
expect(valid.age).toBe(30);
|
|
46
|
+
const withoutFormValid: RulesValuesType<{ age: number }> = {
|
|
47
|
+
age: 25
|
|
48
|
+
};
|
|
49
|
+
expect(withoutFormValid["$form.isValid"]).toBeUndefined();
|
|
50
|
+
expect(withoutFormValid.age).toBe(25);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
it('should validate RulesModes enum values', () => {
|
|
54
|
+
expect(RulesModes.$and).toBe('$and');
|
|
55
|
+
expect(RulesModes.$or).toBe('$or');
|
|
56
|
+
});
|
|
57
|
+
});
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import rulesMatcherUtils from "../rules-matcher/utils";
|
|
2
|
+
const { forceArray, isNumber, isFunction, isString, isDate, isObject, getPath, forceNumber, getDefaultStringValue, getTypeOf } = rulesMatcherUtils
|
|
3
|
+
|
|
4
|
+
describe('rulesMatcherUtils', () => {
|
|
5
|
+
beforeEach(() => {
|
|
6
|
+
jest.clearAllMocks();
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
it('should check all utils', () => {
|
|
10
|
+
// isNumber
|
|
11
|
+
expect(isNumber(2)).toBe(true)
|
|
12
|
+
expect(isNumber("33")).toBe(true)
|
|
13
|
+
expect(isNumber("ciao")).toBe(false)
|
|
14
|
+
expect(isNumber("ciao12")).toBe(false)
|
|
15
|
+
// isFunction
|
|
16
|
+
expect(isFunction(2)).toBe(false)
|
|
17
|
+
expect(isFunction("ciao")).toBe(false)
|
|
18
|
+
expect(isFunction(() => { })).toBe(true)
|
|
19
|
+
expect(isFunction(function test() { })).toBe(true)
|
|
20
|
+
// isString
|
|
21
|
+
expect(isString(2)).toBe(false)
|
|
22
|
+
expect(isString("2")).toBe(true)
|
|
23
|
+
expect(isString("ciao")).toBe(true)
|
|
24
|
+
// isDate
|
|
25
|
+
expect(isDate(2)).toBe(false)
|
|
26
|
+
expect(isDate(new Date())).toBe(true)
|
|
27
|
+
expect(isDate({})).toBe(false)
|
|
28
|
+
// isObject
|
|
29
|
+
expect(isObject({})).toBe(true)
|
|
30
|
+
expect(isObject("test")).toBe(false)
|
|
31
|
+
expect(isObject([])).toBe(true)
|
|
32
|
+
// forceNumber
|
|
33
|
+
expect(forceNumber([1, 2, 3])).toBe(3)
|
|
34
|
+
expect(forceNumber("2")).toBe(2)
|
|
35
|
+
expect(forceNumber("test")).toBe(0)
|
|
36
|
+
// getDefaultStringValue
|
|
37
|
+
expect(getDefaultStringValue("$required")).toEqual({ op: '$exists', value: true })
|
|
38
|
+
expect(getDefaultStringValue("$exists")).toEqual({ op: '$exists', value: true })
|
|
39
|
+
expect(getDefaultStringValue("test")).toEqual({ op: '$eq', value: "test" })
|
|
40
|
+
// getTypeOf
|
|
41
|
+
expect(getTypeOf([])).toBe("array")
|
|
42
|
+
expect(getTypeOf(2)).toBe("number")
|
|
43
|
+
expect(getTypeOf(null)).toBe(null)
|
|
44
|
+
expect(getTypeOf("test")).toBe(typeof "test")
|
|
45
|
+
expect(getTypeOf(undefined)).toBe(typeof undefined)
|
|
46
|
+
// forceArray
|
|
47
|
+
expect(forceArray(["test"])).toEqual(["test"])
|
|
48
|
+
expect(forceArray(2)).toEqual([2])
|
|
49
|
+
expect(forceArray({ test: "test" })).toEqual([{ test: "test" }])
|
|
50
|
+
// getPath
|
|
51
|
+
expect(getPath("data.name", "user")).toBe("user.data.name")
|
|
52
|
+
expect(getPath("data.name")).toBe("data.name")
|
|
53
|
+
expect(getPath("^data.name")).toBe("data.name")
|
|
54
|
+
expect(getPath("$data.name")).toBe("$data.name")
|
|
55
|
+
});
|
|
56
|
+
});
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { someAsync } from "../helpers/someAsync";
|
|
2
|
+
|
|
3
|
+
const mockArray = [1, 3, 4, 4, 5]
|
|
4
|
+
|
|
5
|
+
describe('someAsync function', () => {
|
|
6
|
+
beforeEach(() => {
|
|
7
|
+
jest.clearAllMocks();
|
|
8
|
+
});
|
|
9
|
+
it('should return true', async () => {
|
|
10
|
+
let i = 0
|
|
11
|
+
const callback = async (el: unknown, index: number): Promise<boolean> => {
|
|
12
|
+
i = index
|
|
13
|
+
return new Promise(resolve => {
|
|
14
|
+
setTimeout(() => {
|
|
15
|
+
resolve(index < 6);
|
|
16
|
+
}, 0);
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
const response = await someAsync(mockArray, callback)
|
|
20
|
+
expect(response).toEqual(true)
|
|
21
|
+
expect(i).toEqual(0)
|
|
22
|
+
});
|
|
23
|
+
it('should return true for the last element', async () => {
|
|
24
|
+
let i = 0
|
|
25
|
+
const callback = async (el: unknown, index: number): Promise<boolean> => {
|
|
26
|
+
i = index
|
|
27
|
+
return new Promise(resolve => {
|
|
28
|
+
setTimeout(() => {
|
|
29
|
+
resolve(index > 3);
|
|
30
|
+
}, 0);
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
const response = await someAsync(mockArray, callback)
|
|
34
|
+
expect(response).toEqual(true)
|
|
35
|
+
expect(i).toEqual(4)
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it('should return false', async () => {
|
|
39
|
+
let i = 0
|
|
40
|
+
const callback = async (el: unknown, index: number): Promise<boolean> => {
|
|
41
|
+
i = index
|
|
42
|
+
return new Promise(resolve => {
|
|
43
|
+
setTimeout(() => {
|
|
44
|
+
resolve(index > 4);
|
|
45
|
+
}, 0);
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
const response = await someAsync(mockArray, callback)
|
|
49
|
+
expect(response).toEqual(false)
|
|
50
|
+
expect(i).toEqual(4)
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
})
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { mongodb } from '@fastify/mongodb'
|
|
2
|
+
import { Arguments } from '../../auth/dtos'
|
|
3
|
+
import { Function } from '../../features/functions/interface'
|
|
4
|
+
import { GenerateContextDataParams } from './interface'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* > Used to generate the current context data
|
|
8
|
+
* @testable
|
|
9
|
+
* @param user -> the current user
|
|
10
|
+
* @param services -> the list of all services
|
|
11
|
+
* @param app -> the fastify instance
|
|
12
|
+
* @param rules -> the rules object
|
|
13
|
+
* @param currentFunction -> the function's name that should be called
|
|
14
|
+
* @param functionsList -> the list of all functions
|
|
15
|
+
*/
|
|
16
|
+
export const generateContextData = ({
|
|
17
|
+
user,
|
|
18
|
+
services,
|
|
19
|
+
app,
|
|
20
|
+
rules,
|
|
21
|
+
currentFunction,
|
|
22
|
+
functionsList,
|
|
23
|
+
GenerateContext
|
|
24
|
+
}: GenerateContextDataParams) => ({
|
|
25
|
+
BSON: mongodb.BSON,
|
|
26
|
+
console: {
|
|
27
|
+
log: (...args: Arguments) => {
|
|
28
|
+
console.log(...args)
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
context: {
|
|
32
|
+
user,
|
|
33
|
+
environment: {
|
|
34
|
+
tag: process.env.NODE_ENV
|
|
35
|
+
},
|
|
36
|
+
values: {
|
|
37
|
+
get: (key: string) => process.env[key],
|
|
38
|
+
},
|
|
39
|
+
services: {
|
|
40
|
+
get: (serviceName: keyof typeof services) => {
|
|
41
|
+
try {
|
|
42
|
+
return services[serviceName](app, {
|
|
43
|
+
rules,
|
|
44
|
+
user,
|
|
45
|
+
run_as_system: currentFunction.run_as_system
|
|
46
|
+
})
|
|
47
|
+
} catch (error) {
|
|
48
|
+
console.error(
|
|
49
|
+
'Something went wrong while generating context function',
|
|
50
|
+
serviceName,
|
|
51
|
+
error
|
|
52
|
+
)
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
functions: {
|
|
57
|
+
execute: (name: keyof typeof functionsList, ...args: Arguments) => {
|
|
58
|
+
const currentFunction = functionsList[name] as Function
|
|
59
|
+
return GenerateContext({
|
|
60
|
+
args,
|
|
61
|
+
app,
|
|
62
|
+
rules,
|
|
63
|
+
user,
|
|
64
|
+
currentFunction,
|
|
65
|
+
functionsList,
|
|
66
|
+
services
|
|
67
|
+
})
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
})
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import m from 'module'
|
|
2
|
+
import vm from 'vm'
|
|
3
|
+
import { EJSON } from 'bson'
|
|
4
|
+
import { generateContextData } from './helpers'
|
|
5
|
+
import { GenerateContextParams } from './interface'
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* > Used to generate the current context
|
|
9
|
+
* @testable
|
|
10
|
+
* @param args -> generic arguments
|
|
11
|
+
* @param app -> the fastify instance
|
|
12
|
+
* @param rules -> the rules object
|
|
13
|
+
* @param user -> the current user
|
|
14
|
+
* @param currentFunction -> the function's name that should be called
|
|
15
|
+
* @param functionsList -> the list of all functions
|
|
16
|
+
* @param services -> the list of all services
|
|
17
|
+
*/
|
|
18
|
+
export async function GenerateContext({
|
|
19
|
+
args,
|
|
20
|
+
app,
|
|
21
|
+
rules,
|
|
22
|
+
user,
|
|
23
|
+
currentFunction,
|
|
24
|
+
functionsList,
|
|
25
|
+
services
|
|
26
|
+
}: GenerateContextParams) {
|
|
27
|
+
const contextData = generateContextData({
|
|
28
|
+
user,
|
|
29
|
+
services,
|
|
30
|
+
app,
|
|
31
|
+
rules,
|
|
32
|
+
currentFunction,
|
|
33
|
+
functionsList,
|
|
34
|
+
GenerateContext
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
try {
|
|
38
|
+
vm.runInContext(m.wrap(currentFunction.code), vm.createContext(contextData))(
|
|
39
|
+
exports,
|
|
40
|
+
require,
|
|
41
|
+
module,
|
|
42
|
+
__filename,
|
|
43
|
+
__dirname
|
|
44
|
+
)
|
|
45
|
+
}
|
|
46
|
+
catch (e) {
|
|
47
|
+
console.log(e)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
return await module.exports(...EJSON.deserialize(args))
|
|
52
|
+
}
|