@friggframework/core 2.0.0--canary.397.3862908.0 → 2.0.0--canary.397.155fecd.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 (26) hide show
  1. package/README.md +933 -50
  2. package/core/create-handler.js +1 -0
  3. package/handlers/routers/auth.js +1 -15
  4. package/integrations/integration-router.js +11 -11
  5. package/integrations/tests/doubles/dummy-integration-class.js +80 -1
  6. package/integrations/tests/doubles/test-integration-repository.js +43 -6
  7. package/integrations/tests/use-cases/create-integration.test.js +108 -11
  8. package/integrations/tests/use-cases/delete-integration-for-user.test.js +132 -9
  9. package/integrations/tests/use-cases/get-integration-for-user.test.js +129 -15
  10. package/integrations/tests/use-cases/get-integration-instance.test.js +154 -11
  11. package/integrations/tests/use-cases/get-integrations-for-user.test.js +156 -17
  12. package/integrations/tests/use-cases/get-possible-integrations.test.js +183 -7
  13. package/integrations/tests/use-cases/update-integration-messages.test.js +135 -8
  14. package/integrations/tests/use-cases/update-integration-status.test.js +103 -0
  15. package/integrations/tests/use-cases/update-integration.test.js +122 -12
  16. package/integrations/use-cases/create-integration.js +19 -4
  17. package/integrations/use-cases/delete-integration-for-user.js +19 -0
  18. package/integrations/use-cases/get-integration-for-user.js +22 -6
  19. package/integrations/use-cases/get-integration-instance.js +14 -3
  20. package/integrations/use-cases/get-integrations-for-user.js +17 -3
  21. package/integrations/use-cases/get-possible-integrations.js +14 -0
  22. package/integrations/use-cases/update-integration-messages.js +17 -6
  23. package/integrations/use-cases/update-integration-status.js +16 -0
  24. package/integrations/use-cases/update-integration.js +17 -6
  25. package/package.json +5 -5
  26. package/integrations/test/integration-base.test.js +0 -144
@@ -1,7 +1,19 @@
1
1
  const { Integration } = require('../integration');
2
2
  const { mapIntegrationClassToIntegrationDTO } = require('../utils/map-integration-dto');
3
3
 
4
+ /**
5
+ * Use case for retrieving a single integration for a specific user.
6
+ * @class GetIntegrationForUser
7
+ */
4
8
  class GetIntegrationForUser {
9
+ /**
10
+ * Creates a new GetIntegrationForUser instance.
11
+ * @param {Object} params - Configuration parameters.
12
+ * @param {import('../integration-repository').IntegrationRepository} params.integrationRepository - Repository for integration data operations.
13
+ * @param {Array<import('../integration').Integration>} params.integrationClasses - Array of available integration classes.
14
+ * @param {import('../../modules/module-factory').ModuleFactory} params.moduleFactory - Service for module instantiation and management.
15
+ * @param {import('../../modules/module-repository').ModuleRepository} params.moduleRepository - Repository for module and entity data operations.
16
+ */
5
17
  constructor({ integrationRepository, integrationClasses, moduleFactory, moduleRepository }) {
6
18
 
7
19
  /**
@@ -14,9 +26,13 @@ class GetIntegrationForUser {
14
26
  }
15
27
 
16
28
  /**
17
- * @param {string} integrationId
18
- * @param {string} userId
19
- * @returns {Promise<Integration>}
29
+ * Executes the retrieval of a single integration for a user.
30
+ * @async
31
+ * @param {string} integrationId - ID of the integration to retrieve.
32
+ * @param {string} userId - ID of the user requesting the integration.
33
+ * @returns {Promise<Object>} The integration DTO for the specified user.
34
+ * @throws {Boom.notFound} When integration with the specified ID does not exist.
35
+ * @throws {Boom.forbidden} When user does not have access to the integration.
20
36
  */
21
37
  async execute(integrationId, userId) {
22
38
  const integrationRecord = await this.integrationRepository.findIntegrationById(integrationId);
@@ -26,7 +42,7 @@ class GetIntegrationForUser {
26
42
  throw Boom.notFound(`Integration with id of ${integrationId} does not exist`);
27
43
  }
28
44
 
29
- if (integrationRecord.user.toString() !== userId.toString()) {
45
+ if (integrationRecord.userId.toString() !== userId.toString()) {
30
46
  throw Boom.forbidden('User does not have access to this integration');
31
47
  }
32
48
 
@@ -38,14 +54,14 @@ class GetIntegrationForUser {
38
54
  for (const entity of entities) {
39
55
  const moduleInstance = await this.moduleFactory.getModuleInstance(
40
56
  entity._id,
41
- integrationRecord.user
57
+ integrationRecord.userId
42
58
  );
43
59
  modules.push(moduleInstance);
44
60
  }
45
61
 
46
62
  const integrationInstance = new Integration({
47
63
  id: integrationRecord._id,
48
- userId: integrationRecord.user,
64
+ userId: integrationRecord.userId,
49
65
  entities: entities,
50
66
  config: integrationRecord.config,
51
67
  status: integrationRecord.status,
@@ -1,11 +1,14 @@
1
1
  const { Integration } = require('../integration');
2
2
 
3
+ /**
4
+ * Use case for retrieving a single integration instance by ID and user.
5
+ * @class GetIntegrationInstance
6
+ */
3
7
  class GetIntegrationInstance {
4
8
 
5
9
  /**
6
- * @class GetIntegrationInstance
7
- * @description Use case for retrieving a single integration instance by ID and user.
8
- * @param {Object} params
10
+ * Creates a new GetIntegrationInstance instance.
11
+ * @param {Object} params - Configuration parameters.
9
12
  * @param {import('../integration-repository').IntegrationRepository} params.integrationRepository - Repository for integration data access
10
13
  * @param {Array<import('../integration').Integration>} params.integrationClasses - Array of available integration classes
11
14
  * @param {import('../../modules/module-factory').ModuleFactory} params.moduleFactory - Service for module instantiation and management
@@ -20,6 +23,14 @@ class GetIntegrationInstance {
20
23
  this.moduleFactory = moduleFactory;
21
24
  }
22
25
 
26
+ /**
27
+ * Executes the retrieval of a single integration instance.
28
+ * @async
29
+ * @param {string} integrationId - ID of the integration to retrieve.
30
+ * @param {string} userId - ID of the user requesting the integration.
31
+ * @returns {Promise<Integration>} The fully initialized integration instance.
32
+ * @throws {Error} When integration is not found, doesn't belong to user, or integration class is not found.
33
+ */
23
34
  async execute(integrationId, userId) {
24
35
  const integrationRecord = await this.integrationRepository.findIntegrationById(integrationId);
25
36
 
@@ -1,7 +1,19 @@
1
1
  const { Integration } = require('../integration');
2
2
  const { mapIntegrationClassToIntegrationDTO } = require('../utils/map-integration-dto');
3
3
 
4
+ /**
5
+ * Use case for retrieving all integrations for a specific user.
6
+ * @class GetIntegrationsForUser
7
+ */
4
8
  class GetIntegrationsForUser {
9
+ /**
10
+ * Creates a new GetIntegrationsForUser instance.
11
+ * @param {Object} params - Configuration parameters.
12
+ * @param {import('../integration-repository').IntegrationRepository} params.integrationRepository - Repository for integration data operations.
13
+ * @param {Array<import('../integration').Integration>} params.integrationClasses - Array of available integration classes.
14
+ * @param {import('../../modules/module-factory').ModuleFactory} params.moduleFactory - Service for module instantiation and management.
15
+ * @param {import('../../modules/module-repository').ModuleRepository} params.moduleRepository - Repository for module and entity data operations.
16
+ */
5
17
  constructor({ integrationRepository, integrationClasses, moduleFactory, moduleRepository }) {
6
18
 
7
19
  /**
@@ -14,8 +26,10 @@ class GetIntegrationsForUser {
14
26
  }
15
27
 
16
28
  /**
17
- * @param {string} userId
18
- * @returns {Promise<Integration[]>}
29
+ * Executes the retrieval of all integrations for a user.
30
+ * @async
31
+ * @param {string} userId - ID of the user whose integrations to retrieve.
32
+ * @returns {Promise<Object[]>} Array of integration DTOs for the specified user.
19
33
  */
20
34
  async execute(userId) {
21
35
  const integrationRecords = await this.integrationRepository.findIntegrationsByUserId(userId);
@@ -40,7 +54,7 @@ class GetIntegrationsForUser {
40
54
 
41
55
  const integrationInstance = new Integration({
42
56
  id: integrationRecord.id,
43
- userId: integrationRecord.user,
57
+ userId: integrationRecord.userId,
44
58
  entities: entities,
45
59
  config: integrationRecord.config,
46
60
  status: integrationRecord.status,
@@ -1,8 +1,22 @@
1
+ /**
2
+ * Use case for retrieving all possible integration types that can be created.
3
+ * @class GetPossibleIntegrations
4
+ */
1
5
  class GetPossibleIntegrations {
6
+ /**
7
+ * Creates a new GetPossibleIntegrations instance.
8
+ * @param {Object} params - Configuration parameters.
9
+ * @param {Array<import('../integration').Integration>} params.integrationClasses - Array of available integration classes.
10
+ */
2
11
  constructor({ integrationClasses }) {
3
12
  this.integrationClasses = integrationClasses;
4
13
  }
5
14
 
15
+ /**
16
+ * Executes the retrieval of all possible integration types.
17
+ * @async
18
+ * @returns {Promise<Object[]>} Array of integration option details for all available integration types.
19
+ */
6
20
  async execute() {
7
21
  return this.integrationClasses.map((integrationClass) =>
8
22
  integrationClass.getOptionDetails()
@@ -1,15 +1,26 @@
1
+ /**
2
+ * Use case for updating messages associated with an integration.
3
+ * @class UpdateIntegrationMessages
4
+ */
1
5
  class UpdateIntegrationMessages {
6
+ /**
7
+ * Creates a new UpdateIntegrationMessages instance.
8
+ * @param {Object} params - Configuration parameters.
9
+ * @param {import('../integration-repository').IntegrationRepository} params.integrationRepository - Repository for integration data operations.
10
+ */
2
11
  constructor({ integrationRepository }) {
3
12
  this.integrationRepository = integrationRepository;
4
13
  }
5
14
 
6
15
  /**
7
- * @param {string} integrationId
8
- * @param {string} messageType - 'errors', 'warnings', 'info' or 'logs'
9
- * @param {string} messageTitle,
10
- * @param {string} messageBody,
11
- * @param {string} messageTimestamp,
12
- * @returns {Promise<Object>}
16
+ * Executes the integration messages update.
17
+ * @async
18
+ * @param {string} integrationId - ID of the integration to update.
19
+ * @param {string} messageType - Type of message: 'errors', 'warnings', 'info', or 'logs'.
20
+ * @param {string} messageTitle - Title of the message.
21
+ * @param {string} messageBody - Body content of the message.
22
+ * @param {string} messageTimestamp - Timestamp when the message was created.
23
+ * @returns {Promise<Object>} The updated integration record.
13
24
  */
14
25
  async execute(integrationId, messageType, messageTitle, messageBody, messageTimestamp) {
15
26
  const integration = await this.integrationRepository.updateIntegrationMessages(integrationId, messageType, messageTitle, messageBody, messageTimestamp);
@@ -1,8 +1,24 @@
1
+ /**
2
+ * Use case for updating the status of an integration.
3
+ * @class UpdateIntegrationStatus
4
+ */
1
5
  class UpdateIntegrationStatus {
6
+ /**
7
+ * Creates a new UpdateIntegrationStatus instance.
8
+ * @param {Object} params - Configuration parameters.
9
+ * @param {import('../integration-repository').IntegrationRepository} params.integrationRepository - Repository for integration data operations.
10
+ */
2
11
  constructor({ integrationRepository }) {
3
12
  this.integrationRepository = integrationRepository;
4
13
  }
5
14
 
15
+ /**
16
+ * Executes the integration status update.
17
+ * @async
18
+ * @param {string} integrationId - ID of the integration to update.
19
+ * @param {string} status - New status for the integration (e.g., 'ENABLED', 'DISABLED', 'ERROR').
20
+ * @returns {Promise<Object>} The updated integration record.
21
+ */
6
22
  async execute(integrationId, status) {
7
23
  const integration = await this.integrationRepository.updateIntegrationStatus(integrationId, status);
8
24
  return integration;
@@ -1,13 +1,15 @@
1
1
  const { Integration } = require('../integration');
2
2
  const { mapIntegrationClassToIntegrationDTO } = require('../utils/map-integration-dto');
3
3
 
4
-
4
+ /**
5
+ * Use case for updating a single integration by ID and user.
6
+ * @class UpdateIntegration
7
+ */
5
8
  class UpdateIntegration {
6
9
 
7
10
  /**
8
- * @class UpdateIntegration
9
- * @description Use case for updating a single integration by ID and user.
10
- * @param {Object} params
11
+ * Creates a new UpdateIntegration instance.
12
+ * @param {Object} params - Configuration parameters.
11
13
  * @param {import('../integration-repository').IntegrationRepository} params.integrationRepository - Repository for integration data access
12
14
  * @param {Array<import('../integration').Integration>} params.integrationClasses - Array of available integration classes
13
15
  * @param {import('../../modules/module-factory').ModuleFactory} params.moduleFactory - Service for module instantiation and management
@@ -22,6 +24,15 @@ class UpdateIntegration {
22
24
  this.moduleFactory = moduleFactory;
23
25
  }
24
26
 
27
+ /**
28
+ * Executes the integration update process.
29
+ * @async
30
+ * @param {string} integrationId - ID of the integration to update.
31
+ * @param {string} userId - ID of the user requesting the update.
32
+ * @param {Object} config - New configuration object for the integration.
33
+ * @returns {Promise<Object>} The updated integration DTO.
34
+ * @throws {Error} When integration is not found, doesn't belong to user, or integration class is not found.
35
+ */
25
36
  async execute(integrationId, userId, config) {
26
37
  // 1. Get integration record from repository
27
38
  const integrationRecord = await this.integrationRepository.findIntegrationById(integrationId);
@@ -56,12 +67,12 @@ class UpdateIntegration {
56
67
  modules.push(moduleInstance);
57
68
  }
58
69
 
59
- // 4. Create the Integration domain entity with modules
70
+ // 4. Create the Integration domain entity with modules and updated config
60
71
  const integrationInstance = new Integration({
61
72
  id: integrationRecord.id,
62
73
  userId: integrationRecord.userId,
63
74
  entities: integrationRecord.entitiesIds,
64
- config: integrationRecord.config,
75
+ config: config,
65
76
  status: integrationRecord.status,
66
77
  version: integrationRecord.version,
67
78
  messages: integrationRecord.messages,
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.3862908.0",
4
+ "version": "2.0.0--canary.397.155fecd.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.3862908.0",
26
- "@friggframework/prettier-config": "2.0.0--canary.397.3862908.0",
27
- "@friggframework/test": "2.0.0--canary.397.3862908.0",
25
+ "@friggframework/eslint-config": "2.0.0--canary.397.155fecd.0",
26
+ "@friggframework/prettier-config": "2.0.0--canary.397.155fecd.0",
27
+ "@friggframework/test": "2.0.0--canary.397.155fecd.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": "3862908989603188a6c3a404d456f4349c84e54b"
56
+ "gitHead": "155fecdabd27d01d1c1001261e9ec4b824826411"
57
57
  }
@@ -1,144 +0,0 @@
1
- const _ = require('lodash');
2
- const { mongoose } = require('../../database/mongoose');
3
- const { expect } = require('chai');
4
- const { IntegrationBase } = require("../integration-base");
5
- const { Credential } = require('../../module-plugin/credential');
6
- const { Entity } = require('../../module-plugin/entity');
7
- const { IntegrationMapping } = require('../integration-mapping')
8
- const { IntegrationModel } = require("../integration-model");
9
-
10
- describe(`Should fully test the IntegrationBase Class`, () => {
11
- let integrationRecord;
12
- let userId;
13
- const integration = new IntegrationBase;
14
-
15
- beforeAll(async () => {
16
- await mongoose.connect(process.env.MONGO_URI);
17
- userId = new mongoose.Types.ObjectId();
18
- const credential = await Credential.findOneAndUpdate(
19
- {
20
- user: this.userId,
21
- },
22
- { $set: { user: this.userId } },
23
- {
24
- new: true,
25
- upsert: true,
26
- setDefaultsOnInsert: true,
27
- }
28
- );
29
- const entity1 = await Entity.findOneAndUpdate(
30
- {
31
- user: this.userId,
32
- },
33
- {
34
- $set: {
35
- credential: credential.id,
36
- user: userId,
37
- },
38
- },
39
- {
40
- new: true,
41
- upsert: true,
42
- setDefaultsOnInsert: true,
43
- }
44
- );
45
- const entity2 = await Entity.findOneAndUpdate(
46
- {
47
- user: userId,
48
- },
49
- {
50
- $set: {
51
- credential: credential.id,
52
- user: userId,
53
- },
54
- },
55
- {
56
- new: true,
57
- upsert: true,
58
- setDefaultsOnInsert: true,
59
- }
60
- );
61
- integrationRecord = await IntegrationModel.create({
62
- entities: [entity1, entity2],
63
- user: userId
64
- });
65
- integration.record = integrationRecord;
66
- });
67
-
68
- afterAll(async () => {
69
- await Entity.deleteMany();
70
- await Credential.deleteMany();
71
- await IntegrationMapping.deleteMany();
72
- await IntegrationModel.deleteMany();
73
- await mongoose.disconnect();
74
- });
75
-
76
- beforeEach(() => {
77
- integration.record = integrationRecord;
78
- })
79
-
80
- describe('getIntegrationMapping()', () => {
81
- it('should return null if not found', async () => {
82
- const mappings = await integration.getMapping('badId');
83
- expect(mappings).to.be.null;
84
- });
85
-
86
- it('should return if valid ids', async () => {
87
- await integration.upsertMapping('validId', {});
88
- const mapping = await integration.getMapping('validId');
89
- expect(mapping).to.eql({})
90
- });
91
- })
92
-
93
- describe('upsertIntegrationMapping()', () => {
94
- it('should throw error if sourceId is null', async () => {
95
- try {
96
- await integration.upsertMapping(null, {});
97
- fail('should have thrown error')
98
- } catch (err) {
99
- expect(err.message).to.contain('sourceId must be set');
100
- }
101
- });
102
-
103
- it('should return for empty mapping', async () => {
104
- const mapping = await integration.upsertMapping('validId2', {});
105
- expect(_.pick(mapping, ['integration', 'sourceId', 'mapping'])).to.eql({
106
- integration: integrationRecord._id,
107
- sourceId: 'validId2',
108
- mapping: {}
109
- })
110
- });
111
-
112
- it('should return for filled mapping', async () => {
113
- const mapping = await integration.upsertMapping('validId3', {
114
- name: 'someName',
115
- value: 5
116
- });
117
- expect(_.pick(mapping, ['integration', 'sourceId', 'mapping'])).to.eql({
118
- integration: integrationRecord._id,
119
- sourceId: 'validId3',
120
- mapping: {
121
- name: 'someName',
122
- value: 5
123
- }
124
- })
125
- });
126
-
127
- it('should allow upserting to same id', async () => {
128
- await integration.upsertMapping('validId4', {});
129
- const mapping = await integration.upsertMapping('validId4', {
130
- name: 'trustMe',
131
- thisWorks: true,
132
- });
133
- expect(_.pick(mapping, ['integration', 'sourceId', 'mapping'])).to.eql({
134
- integration: integrationRecord._id,
135
- sourceId: 'validId4',
136
- mapping: {
137
- name: 'trustMe',
138
- thisWorks: true,
139
- }
140
- })
141
- });
142
- })
143
-
144
- });