@friggframework/core 2.0.0--canary.397.b7e1978.0 → 2.0.0--canary.397.3862908.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.
Files changed (25) hide show
  1. package/handlers/backend-utils.js +9 -3
  2. package/integrations/integration-router.js +6 -6
  3. package/integrations/integration.js +1 -1
  4. package/integrations/test/integration-base.test.js +6 -6
  5. package/integrations/tests/doubles/dummy-integration-class.js +11 -0
  6. package/integrations/tests/doubles/test-integration-repository.js +52 -0
  7. package/integrations/tests/use-cases/create-integration.test.js +27 -0
  8. package/integrations/tests/use-cases/delete-integration-for-user.test.js +20 -0
  9. package/integrations/tests/use-cases/get-integration-for-user.test.js +29 -0
  10. package/integrations/tests/use-cases/get-integration-instance.test.js +26 -0
  11. package/integrations/tests/use-cases/get-integrations-for-user.test.js +30 -0
  12. package/integrations/tests/use-cases/get-possible-integrations.test.js +12 -0
  13. package/integrations/tests/use-cases/update-integration-messages.test.js +15 -0
  14. package/integrations/tests/use-cases/update-integration-status.test.js +0 -0
  15. package/integrations/tests/use-cases/update-integration.test.js +24 -0
  16. package/integrations/use-cases/create-integration.js +4 -4
  17. package/integrations/use-cases/get-integration-for-user.js +3 -3
  18. package/integrations/use-cases/get-integration-instance.js +4 -4
  19. package/integrations/use-cases/get-integrations-for-user.js +3 -3
  20. package/integrations/use-cases/update-integration.js +4 -4
  21. package/modules/{module-service.js → module-factory.js} +7 -2
  22. package/modules/module-repository.js +2 -21
  23. package/modules/tests/doubles/test-module-factory.js +16 -0
  24. package/modules/tests/doubles/test-module-repository.js +19 -0
  25. package/package.json +5 -5
@@ -2,8 +2,10 @@ const { Router } = require('express');
2
2
  const { Worker } = require('@friggframework/core');
3
3
  const { loadAppDefinition } = require('./app-definition-loader');
4
4
  const { IntegrationRepository } = require('../integrations/integration-repository');
5
- const { ModuleService } = require('../modules/module-service');
5
+ const { ModuleFactory } = require('../modules/module-factory');
6
6
  const { GetIntegrationInstance } = require('../integrations/use-cases/get-integration-instance');
7
+ const { getModulesDefinitionFromIntegrationClasses } = require('../integrations/utils/map-integration-dto');
8
+ const { ModuleRepository } = require('../modules/module-repository');
7
9
 
8
10
  const loadRouterFromObject = (IntegrationClass, routerObject) => {
9
11
  const router = Router();
@@ -42,12 +44,16 @@ const createQueueWorker = (integrationClass) => {
42
44
  } else {
43
45
  const { integrations: integrationClasses } = loadAppDefinition();
44
46
  const integrationRepository = new IntegrationRepository();
45
- const moduleService = new ModuleService();
47
+ const moduleRepository = new ModuleRepository();
48
+ const moduleFactory = new ModuleFactory({
49
+ moduleRepository,
50
+ moduleDefinitions: getModulesDefinitionFromIntegrationClasses(integrationClasses),
51
+ });
46
52
 
47
53
  const getIntegrationInstance = new GetIntegrationInstance({
48
54
  integrationRepository,
49
55
  integrationClasses,
50
- moduleService,
56
+ moduleFactory,
51
57
  });
52
58
 
53
59
  // todo: are we going to have the userId available here?
@@ -8,7 +8,7 @@ const { GetIntegrationsForUser } = require('./use-cases/get-integrations-for-use
8
8
  const { CredentialRepository } = require('../credential/credential-repository');
9
9
  const { GetCredentialForUser } = require('../credential/use-cases/get-credential-for-user');
10
10
  const { CreateIntegration } = require('./use-cases/create-integration');
11
- const { ModuleService } = require('../modules/module-service');
11
+ const { ModuleFactory } = require('../modules/module-factory');
12
12
  const { ModuleRepository } = require('../modules/module-repository');
13
13
  const { GetEntitiesForUser } = require('../modules/use-cases/get-entities-for-user');
14
14
  const { loadAppDefinition } = require('../handlers/app-definition-loader');
@@ -36,7 +36,7 @@ function createIntegrationRouter(params) {
36
36
  const integrationRepository = new IntegrationRepository();
37
37
  const credentialRepository = new CredentialRepository();
38
38
 
39
- const moduleService = new ModuleService({
39
+ const moduleFactory = new ModuleFactory({
40
40
  moduleRepository,
41
41
  moduleDefinitions: getModulesDefinitionFromIntegrationClasses(integrationClasses),
42
42
  });
@@ -48,7 +48,7 @@ function createIntegrationRouter(params) {
48
48
  const getIntegrationsForUser = new GetIntegrationsForUser({
49
49
  integrationRepository,
50
50
  integrationClasses,
51
- moduleService,
51
+ moduleFactory,
52
52
  moduleRepository,
53
53
  });
54
54
 
@@ -59,7 +59,7 @@ function createIntegrationRouter(params) {
59
59
  const createIntegration = new CreateIntegration({
60
60
  integrationRepository,
61
61
  integrationClasses,
62
- moduleService,
62
+ moduleFactory,
63
63
  });
64
64
 
65
65
  const getEntitiesForUser = new GetEntitiesForUser({
@@ -70,13 +70,13 @@ function createIntegrationRouter(params) {
70
70
  const getIntegrationInstance = new GetIntegrationInstance({
71
71
  integrationRepository,
72
72
  integrationClasses,
73
- moduleService,
73
+ moduleFactory,
74
74
  });
75
75
 
76
76
  const updateIntegration = new UpdateIntegration({
77
77
  integrationRepository,
78
78
  integrationClasses,
79
- moduleService,
79
+ moduleFactory,
80
80
  });
81
81
 
82
82
  const getModuleInstanceFromType = new GetModuleInstanceFromType({
@@ -119,7 +119,7 @@ class Integration {
119
119
  // -----------------------------------------------------------------
120
120
  // Inject the real Module instances (with credentials) so that any
121
121
  // behaviour code accessing `this.<moduleName>.api` hits the
122
- // correctly authenticated requester created by ModuleService.
122
+ // correctly authenticated requester created by ModuleFactory.
123
123
  // -----------------------------------------------------------------
124
124
  for (const mod of this._moduleInstances) {
125
125
  const key = typeof mod.getName === 'function' ? mod.getName() : mod.name;
@@ -2,10 +2,10 @@ const _ = require('lodash');
2
2
  const { mongoose } = require('../../database/mongoose');
3
3
  const { expect } = require('chai');
4
4
  const { IntegrationBase } = require("../integration-base");
5
- const {Credential} = require('../../module-plugin/credential');
6
- const {Entity} = require('../../module-plugin/entity');
5
+ const { Credential } = require('../../module-plugin/credential');
6
+ const { Entity } = require('../../module-plugin/entity');
7
7
  const { IntegrationMapping } = require('../integration-mapping')
8
- const {IntegrationModel} = require("../integration-model");
8
+ const { IntegrationModel } = require("../integration-model");
9
9
 
10
10
  describe(`Should fully test the IntegrationBase Class`, () => {
11
11
  let integrationRecord;
@@ -93,15 +93,15 @@ describe(`Should fully test the IntegrationBase Class`, () => {
93
93
  describe('upsertIntegrationMapping()', () => {
94
94
  it('should throw error if sourceId is null', async () => {
95
95
  try {
96
- await integration.upsertMapping( null, {});
96
+ await integration.upsertMapping(null, {});
97
97
  fail('should have thrown error')
98
- } catch(err) {
98
+ } catch (err) {
99
99
  expect(err.message).to.contain('sourceId must be set');
100
100
  }
101
101
  });
102
102
 
103
103
  it('should return for empty mapping', async () => {
104
- const mapping = await integration.upsertMapping( 'validId2', {});
104
+ const mapping = await integration.upsertMapping('validId2', {});
105
105
  expect(_.pick(mapping, ['integration', 'sourceId', 'mapping'])).to.eql({
106
106
  integration: integrationRecord._id,
107
107
  sourceId: 'validId2',
@@ -0,0 +1,11 @@
1
+ const { IntegrationBase } = require('../../integration-base');
2
+
3
+ class DummyIntegration extends IntegrationBase {
4
+ static Definition = {
5
+ name: 'dummy',
6
+ version: '1.0.0',
7
+ modules: {},
8
+ };
9
+ }
10
+
11
+ module.exports = { DummyIntegration };
@@ -0,0 +1,52 @@
1
+ const { v4: uuid } = require('uuid');
2
+
3
+ class TestIntegrationRepository {
4
+ constructor() {
5
+ this.store = new Map();
6
+ }
7
+
8
+ async createIntegration(entities, userId, config) {
9
+ const id = uuid();
10
+ const record = {
11
+ id,
12
+ entitiesIds: entities,
13
+ userId,
14
+ config,
15
+ version: '0.0.0',
16
+ status: 'NEW',
17
+ messages: {},
18
+ };
19
+ this.store.set(id, record);
20
+ return record;
21
+ }
22
+
23
+ async findIntegrationById(id) {
24
+ const rec = this.store.get(id);
25
+ if (!rec) return null;
26
+ return rec;
27
+ }
28
+
29
+ async findIntegrationsByUserId(userId) {
30
+ return Array.from(this.store.values()).filter(r => r.userId === userId);
31
+ }
32
+
33
+ async updateIntegrationMessages(id, type, title, body, timestamp) {
34
+ const rec = this.store.get(id);
35
+ if (!rec) return false;
36
+ if (!rec.messages[type]) rec.messages[type] = [];
37
+ rec.messages[type].push({ title, message: body, timestamp });
38
+ return true;
39
+ }
40
+
41
+ async deleteIntegrationById(id) {
42
+ return this.store.delete(id);
43
+ }
44
+
45
+ async updateIntegrationStatus(id, status) {
46
+ const rec = this.store.get(id);
47
+ if (rec) rec.status = status;
48
+ return true;
49
+ }
50
+ }
51
+
52
+ module.exports = { TestIntegrationRepository };
@@ -0,0 +1,27 @@
1
+ const { CreateIntegration } = require('../../use-cases/create-integration');
2
+ const { TestIntegrationRepository } = require('../doubles/test-integration-repository');
3
+ const { TestModuleFactory } = require('../../../modules/tests/doubles/test-module-factory');
4
+ const { DummyIntegration } = require('../doubles/dummy-integration-class');
5
+
6
+ describe('CreateIntegration Use-Case', () => {
7
+ it('creates an integration and returns DTO', async () => {
8
+ const integrationRepository = new TestIntegrationRepository();
9
+ const moduleFactory = new TestModuleFactory();
10
+
11
+ const useCase = new CreateIntegration({
12
+ integrationRepository,
13
+ integrationClasses: [DummyIntegration],
14
+ moduleFactory,
15
+ });
16
+
17
+ const entities = ['entity-1'];
18
+ const userId = 'user-1';
19
+ const config = { type: 'dummy', foo: 'bar' };
20
+
21
+ const dto = await useCase.execute(entities, userId, config);
22
+
23
+ expect(dto.id).toBeDefined();
24
+ expect(dto.config).toEqual(config);
25
+ expect(dto.userId).toBe(userId);
26
+ });
27
+ });
@@ -0,0 +1,20 @@
1
+ const { DeleteIntegrationForUser } = require('../../use-cases/delete-integration-for-user');
2
+ const { TestIntegrationRepository } = require('../doubles/test-integration-repository');
3
+ const { DummyIntegration } = require('../doubles/dummy-integration-class');
4
+
5
+ describe('DeleteIntegrationForUser', () => {
6
+ it('deletes integration', async () => {
7
+ const repo = new TestIntegrationRepository();
8
+ const record = await repo.createIntegration(['e1'], 'user-1', { type: 'dummy' });
9
+
10
+ const useCase = new DeleteIntegrationForUser({
11
+ integrationRepository: repo,
12
+ integrationClasses: [DummyIntegration],
13
+ });
14
+
15
+ await useCase.execute(record.id, 'user-1');
16
+
17
+ const found = await repo.findIntegrationById(record.id);
18
+ expect(found).toBeNull();
19
+ });
20
+ });
@@ -0,0 +1,29 @@
1
+ const { GetIntegrationForUser } = require('../../use-cases/get-integration-for-user');
2
+ const { TestIntegrationRepository } = require('../doubles/test-integration-repository');
3
+ const { TestModuleFactory } = require('../../../modules/tests/doubles/test-module-factory');
4
+ const { TestModuleRepository } = require('../../../modules/tests/doubles/test-module-repository');
5
+ const { DummyIntegration } = require('../doubles/dummy-integration-class');
6
+
7
+
8
+ describe('GetIntegrationForUser', () => {
9
+ it('returns integration dto', async () => {
10
+ const iRepo = new TestIntegrationRepository();
11
+ const mRepo = new TestModuleRepository();
12
+ const mFactory = new TestModuleFactory();
13
+
14
+ const entity = { id: 'entity-1' };
15
+ mRepo.addEntity(entity);
16
+
17
+ const record = await iRepo.createIntegration([entity.id], 'user-1', { type: 'dummy' });
18
+
19
+ const useCase = new GetIntegrationForUser({
20
+ integrationRepository: iRepo,
21
+ integrationClasses: [DummyIntegration],
22
+ moduleFactory: mFactory,
23
+ moduleRepository: mRepo,
24
+ });
25
+
26
+ const dto = await useCase.execute(record.id, 'user-1');
27
+ expect(dto.id).toBe(record.id);
28
+ });
29
+ });
@@ -0,0 +1,26 @@
1
+ const { GetIntegrationInstance } = require('../../use-cases/get-integration-instance');
2
+ const { TestIntegrationRepository } = require('../doubles/test-integration-repository');
3
+ const { TestModuleFactory } = require('../../../modules/tests/doubles/test-module-factory');
4
+ const { DummyIntegration } = require('../doubles/dummy-integration-class');
5
+
6
+ describe('GetIntegrationInstance Use-Case', () => {
7
+ it('returns hydrated integration instance', async () => {
8
+ const integrationRepository = new TestIntegrationRepository();
9
+ const moduleFactory = new TestModuleFactory();
10
+
11
+ // first create record directly via repo
12
+ const record = await integrationRepository.createIntegration(['entity-1'], 'user-1', { type: 'dummy' });
13
+
14
+ const useCase = new GetIntegrationInstance({
15
+ integrationRepository,
16
+ integrationClasses: [DummyIntegration],
17
+ moduleFactory,
18
+ });
19
+
20
+ const instance = await useCase.execute(record.id, 'user-1');
21
+
22
+ expect(instance.id).toBe(record.id);
23
+ expect(instance.getConfig().type).toBe('dummy');
24
+ expect(instance.entities).toEqual(record.entitiesIds);
25
+ });
26
+ });
@@ -0,0 +1,30 @@
1
+ const { GetIntegrationsForUser } = require('../../use-cases/get-integrations-for-user');
2
+ const { TestIntegrationRepository } = require('../doubles/test-integration-repository');
3
+ const { TestModuleFactory } = require('../../../modules/tests/doubles/test-module-factory');
4
+ const { TestModuleRepository } = require('../../../modules/tests/doubles/test-module-repository');
5
+ const { DummyIntegration } = require('../doubles/dummy-integration-class');
6
+
7
+ describe('GetIntegrationsForUser', () => {
8
+ it('returns integrations dto list', async () => {
9
+ const integrationRepo = new TestIntegrationRepository();
10
+ const moduleRepo = new TestModuleRepository();
11
+ const moduleFactory = new TestModuleFactory();
12
+
13
+ // setup entity and module repo
14
+ const entity = { id: 'entity-1' };
15
+ moduleRepo.addEntity(entity);
16
+
17
+ await integrationRepo.createIntegration([entity.id], 'user-1', { type: 'dummy' });
18
+
19
+ const useCase = new GetIntegrationsForUser({
20
+ integrationRepository: integrationRepo,
21
+ integrationClasses: [DummyIntegration],
22
+ moduleFactory,
23
+ moduleRepository: moduleRepo,
24
+ });
25
+
26
+ const list = await useCase.execute('user-1');
27
+ expect(list.length).toBe(1);
28
+ expect(list[0].config.type).toBe('dummy');
29
+ });
30
+ });
@@ -0,0 +1,12 @@
1
+ const { GetPossibleIntegrations } = require('../../use-cases/get-possible-integrations');
2
+ const { DummyIntegration } = require('../doubles/dummy-integration-class');
3
+
4
+ describe('GetPossibleIntegrations', () => {
5
+ it('returns option details array', async () => {
6
+ const useCase = new GetPossibleIntegrations({ integrationClasses: [DummyIntegration] });
7
+ const res = await useCase.execute();
8
+ expect(Array.isArray(res)).toBe(true);
9
+ expect(res.length).toBe(1);
10
+ expect(res[0].display).toBeDefined();
11
+ });
12
+ });
@@ -0,0 +1,15 @@
1
+ const { UpdateIntegrationMessages } = require('../../use-cases/update-integration-messages');
2
+ const { TestIntegrationRepository } = require('../doubles/test-integration-repository');
3
+
4
+ describe('UpdateIntegrationMessages', () => {
5
+ it('adds message', async () => {
6
+ const repo = new TestIntegrationRepository();
7
+ const rec = await repo.createIntegration(['e1'], 'user-1', { type: 'dummy' });
8
+
9
+ const useCase = new UpdateIntegrationMessages({ integrationRepository: repo });
10
+ await useCase.execute(rec.id, 'errors', 'title', 'body', Date.now());
11
+
12
+ const fetched = await repo.findIntegrationById(rec.id);
13
+ expect(fetched.messages.errors.length).toBe(1);
14
+ });
15
+ });
@@ -0,0 +1,24 @@
1
+ const { UpdateIntegration } = require('../../use-cases/update-integration');
2
+ const { TestIntegrationRepository } = require('../doubles/test-integration-repository');
3
+ const { TestModuleFactory } = require('../../../modules/tests/doubles/test-module-factory');
4
+ const { DummyIntegration } = require('../doubles/dummy-integration-class');
5
+
6
+ describe('UpdateIntegration', () => {
7
+ it('calls on update and returns dto', async () => {
8
+ const repo = new TestIntegrationRepository();
9
+ const mf = new TestModuleFactory();
10
+
11
+ const record = await repo.createIntegration(['e1'], 'user-1', { type: 'dummy', foo: 'bar' });
12
+
13
+ const useCase = new UpdateIntegration({
14
+ integrationRepository: repo,
15
+ integrationClasses: [DummyIntegration],
16
+ moduleFactory: mf,
17
+ });
18
+
19
+ const newConfig = { type: 'dummy', foo: 'baz' };
20
+ const dto = await useCase.execute(record.id, 'user-1', newConfig);
21
+
22
+ expect(dto.config.foo).toBe('baz');
23
+ });
24
+ });
@@ -6,12 +6,12 @@ class CreateIntegration {
6
6
  * @param {Object} params
7
7
  * @param {import('../integration-repository').IntegrationRepository} params.integrationRepository
8
8
  * @param {import('../integration-classes').IntegrationClasses} params.integrationClasses
9
- * @param {import('../../modules/module-service').ModuleService} params.moduleService
9
+ * @param {import('../../modules/module-factory').ModuleFactory} params.moduleFactory
10
10
  */
11
- constructor({ integrationRepository, integrationClasses, moduleService }) {
11
+ constructor({ integrationRepository, integrationClasses, moduleFactory }) {
12
12
  this.integrationRepository = integrationRepository;
13
13
  this.integrationClasses = integrationClasses;
14
- this.moduleService = moduleService;
14
+ this.moduleFactory = moduleFactory;
15
15
  }
16
16
 
17
17
  async execute(entities, userId, config) {
@@ -28,7 +28,7 @@ class CreateIntegration {
28
28
 
29
29
  const modules = [];
30
30
  for (const entityId of integrationRecord.entitiesIds) {
31
- const moduleInstance = await this.moduleService.getModuleInstance(
31
+ const moduleInstance = await this.moduleFactory.getModuleInstance(
32
32
  entityId,
33
33
  integrationRecord.userId
34
34
  );
@@ -2,14 +2,14 @@ const { Integration } = require('../integration');
2
2
  const { mapIntegrationClassToIntegrationDTO } = require('../utils/map-integration-dto');
3
3
 
4
4
  class GetIntegrationForUser {
5
- constructor({ integrationRepository, integrationClasses, moduleService, moduleRepository }) {
5
+ constructor({ integrationRepository, integrationClasses, moduleFactory, moduleRepository }) {
6
6
 
7
7
  /**
8
8
  * @type {import('../integration-repository').IntegrationRepository}
9
9
  */
10
10
  this.integrationRepository = integrationRepository;
11
11
  this.integrationClasses = integrationClasses;
12
- this.moduleService = moduleService;
12
+ this.moduleFactory = moduleFactory;
13
13
  this.moduleRepository = moduleRepository;
14
14
  }
15
15
 
@@ -36,7 +36,7 @@ class GetIntegrationForUser {
36
36
 
37
37
  const modules = [];
38
38
  for (const entity of entities) {
39
- const moduleInstance = await this.moduleService.getModuleInstance(
39
+ const moduleInstance = await this.moduleFactory.getModuleInstance(
40
40
  entity._id,
41
41
  integrationRecord.user
42
42
  );
@@ -8,16 +8,16 @@ class GetIntegrationInstance {
8
8
  * @param {Object} params
9
9
  * @param {import('../integration-repository').IntegrationRepository} params.integrationRepository - Repository for integration data access
10
10
  * @param {Array<import('../integration').Integration>} params.integrationClasses - Array of available integration classes
11
- * @param {import('../module-plugin/module-service').ModuleService} params.moduleService - Service for module instantiation and management
11
+ * @param {import('../../modules/module-factory').ModuleFactory} params.moduleFactory - Service for module instantiation and management
12
12
  */
13
13
  constructor({
14
14
  integrationRepository,
15
15
  integrationClasses,
16
- moduleService,
16
+ moduleFactory,
17
17
  }) {
18
18
  this.integrationRepository = integrationRepository;
19
19
  this.integrationClasses = integrationClasses;
20
- this.moduleService = moduleService;
20
+ this.moduleFactory = moduleFactory;
21
21
  }
22
22
 
23
23
  async execute(integrationId, userId) {
@@ -44,7 +44,7 @@ class GetIntegrationInstance {
44
44
 
45
45
  const modules = [];
46
46
  for (const entityId of integrationRecord.entitiesIds) {
47
- const moduleInstance = await this.moduleService.getModuleInstance(
47
+ const moduleInstance = await this.moduleFactory.getModuleInstance(
48
48
  entityId,
49
49
  integrationRecord.userId
50
50
  );
@@ -2,14 +2,14 @@ const { Integration } = require('../integration');
2
2
  const { mapIntegrationClassToIntegrationDTO } = require('../utils/map-integration-dto');
3
3
 
4
4
  class GetIntegrationsForUser {
5
- constructor({ integrationRepository, integrationClasses, moduleService, moduleRepository }) {
5
+ constructor({ integrationRepository, integrationClasses, moduleFactory, moduleRepository }) {
6
6
 
7
7
  /**
8
8
  * @type {import('../integration-repository').IntegrationRepository}
9
9
  */
10
10
  this.integrationRepository = integrationRepository;
11
11
  this.integrationClasses = integrationClasses;
12
- this.moduleService = moduleService;
12
+ this.moduleFactory = moduleFactory;
13
13
  this.moduleRepository = moduleRepository;
14
14
  }
15
15
 
@@ -31,7 +31,7 @@ class GetIntegrationsForUser {
31
31
 
32
32
  const modules = [];
33
33
  for (const entity of entities) {
34
- const moduleInstance = await this.moduleService.getModuleInstance(
34
+ const moduleInstance = await this.moduleFactory.getModuleInstance(
35
35
  entity.id,
36
36
  integrationRecord.userId
37
37
  );
@@ -10,16 +10,16 @@ class UpdateIntegration {
10
10
  * @param {Object} params
11
11
  * @param {import('../integration-repository').IntegrationRepository} params.integrationRepository - Repository for integration data access
12
12
  * @param {Array<import('../integration').Integration>} params.integrationClasses - Array of available integration classes
13
- * @param {import('../module-plugin/module-service').ModuleService} params.moduleService - Service for module instantiation and management
13
+ * @param {import('../../modules/module-factory').ModuleFactory} params.moduleFactory - Service for module instantiation and management
14
14
  */
15
15
  constructor({
16
16
  integrationRepository,
17
17
  integrationClasses,
18
- moduleService,
18
+ moduleFactory,
19
19
  }) {
20
20
  this.integrationRepository = integrationRepository;
21
21
  this.integrationClasses = integrationClasses;
22
- this.moduleService = moduleService;
22
+ this.moduleFactory = moduleFactory;
23
23
  }
24
24
 
25
25
  async execute(integrationId, userId, config) {
@@ -49,7 +49,7 @@ class UpdateIntegration {
49
49
  // 3. Load modules based on entity references
50
50
  const modules = [];
51
51
  for (const entityId of integrationRecord.entitiesIds) {
52
- const moduleInstance = await this.moduleService.getModuleInstance(
52
+ const moduleInstance = await this.moduleFactory.getModuleInstance(
53
53
  entityId,
54
54
  integrationRecord.userId
55
55
  );
@@ -1,6 +1,11 @@
1
1
  const { Module } = require('./module');
2
2
 
3
- class ModuleService {
3
+ /**
4
+ * Acts as a factory for fully-hydrated domain Module instances.
5
+ * Provides methods to retrieve and construct Module objects with their associated
6
+ * entity and definition.
7
+ */
8
+ class ModuleFactory {
4
9
  /**
5
10
  * @param {Object} params - Configuration parameters.
6
11
  * @param {import('./module-repository').ModuleRepository} params.moduleRepository - Repository for module data operations.
@@ -46,4 +51,4 @@ class ModuleService {
46
51
  }
47
52
  }
48
53
 
49
- module.exports = { ModuleService };
54
+ module.exports = { ModuleFactory };
@@ -19,26 +19,6 @@ class ModuleRepository {
19
19
  };
20
20
  }
21
21
 
22
- async findEntitiesByIds(entitiesIds) {
23
- const entitiesRecords = await Entity.find({ _id: { $in: entitiesIds } }, '', { lean: true }).populate('credential');
24
-
25
- // todo: this is a workaround needed while we create an integration with the same entity twice
26
- if (entitiesRecords.length !== entitiesIds.length && entitiesIds[0] !== entitiesIds[1]) {
27
- throw new Error(`Some entities not found`);
28
- }
29
-
30
- return entitiesRecords.map(e => ({
31
- id: e._id,
32
- accountId: e.accountId,
33
- credential: e.credential,
34
- userId: e.user.toString(),
35
- name: e.name,
36
- externalId: e.externalId,
37
- type: e.__t,
38
- moduleName: e.moduleName,
39
- }));
40
- }
41
-
42
22
  async findEntitiesByUserId(userId) {
43
23
  const entitiesRecords = await Entity.find(
44
24
  { user: userId },
@@ -84,7 +64,8 @@ class ModuleRepository {
84
64
  * @returns {Promise<import('mongoose').UpdateWriteOpResult>}
85
65
  */
86
66
  async unsetCredential(entityId) {
87
- return Entity.updateOne({ _id: entityId }, { $unset: { credential: "" } });
67
+ const result = await Entity.updateOne({ _id: entityId }, { $unset: { credential: "" } });
68
+ return result.acknowledged;
88
69
  }
89
70
  }
90
71
 
@@ -0,0 +1,16 @@
1
+ class TestModuleFactory {
2
+ constructor() { }
3
+
4
+ async getModuleInstance(entityId, userId) {
5
+ // return minimal stub module with getName and api property
6
+ return {
7
+ getName() { return 'stubModule'; },
8
+ api: {},
9
+ entityId,
10
+ userId,
11
+ testAuth: async () => true,
12
+ };
13
+ }
14
+ }
15
+
16
+ module.exports = { TestModuleFactory };
@@ -0,0 +1,19 @@
1
+ class TestModuleRepository {
2
+ constructor() {
3
+ this.entities = new Map();
4
+ }
5
+
6
+ addEntity(entity) {
7
+ this.entities.set(entity.id, entity);
8
+ }
9
+
10
+ async findEntityById(id) {
11
+ return this.entities.get(id);
12
+ }
13
+
14
+ async findEntitiesByIds(ids) {
15
+ return ids.map((id) => this.entities.get(id));
16
+ }
17
+ }
18
+
19
+ module.exports = { TestModuleRepository };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@friggframework/core",
3
3
  "prettier": "@friggframework/prettier-config",
4
- "version": "2.0.0--canary.397.b7e1978.0",
4
+ "version": "2.0.0--canary.397.3862908.0",
5
5
  "dependencies": {
6
6
  "@hapi/boom": "^10.0.1",
7
7
  "aws-sdk": "^2.1200.0",
@@ -22,9 +22,9 @@
22
22
  "uuid": "^9.0.1"
23
23
  },
24
24
  "devDependencies": {
25
- "@friggframework/eslint-config": "2.0.0--canary.397.b7e1978.0",
26
- "@friggframework/prettier-config": "2.0.0--canary.397.b7e1978.0",
27
- "@friggframework/test": "2.0.0--canary.397.b7e1978.0",
25
+ "@friggframework/eslint-config": "2.0.0--canary.397.3862908.0",
26
+ "@friggframework/prettier-config": "2.0.0--canary.397.3862908.0",
27
+ "@friggframework/test": "2.0.0--canary.397.3862908.0",
28
28
  "@types/lodash": "4.17.15",
29
29
  "@typescript-eslint/eslint-plugin": "^8.0.0",
30
30
  "chai": "^4.3.6",
@@ -53,5 +53,5 @@
53
53
  },
54
54
  "homepage": "https://github.com/friggframework/frigg#readme",
55
55
  "description": "",
56
- "gitHead": "b7e197879d90d5bd782c5299aa55f312eb7d4b63"
56
+ "gitHead": "3862908989603188a6c3a404d456f4349c84e54b"
57
57
  }