@friggframework/core 2.0.0--canary.397.84ecb0e.0 → 2.0.0--canary.398.bdb6d27.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 (98) hide show
  1. package/README.md +50 -931
  2. package/core/create-handler.js +0 -1
  3. package/database/models/WebsocketConnection.js +5 -0
  4. package/handlers/app-handler-helpers.js +3 -0
  5. package/handlers/backend-utils.js +36 -49
  6. package/handlers/routers/auth.js +14 -3
  7. package/handlers/routers/integration-defined-routers.js +5 -8
  8. package/handlers/routers/middleware/loadUser.js +15 -0
  9. package/handlers/routers/middleware/requireLoggedInUser.js +12 -0
  10. package/handlers/routers/user.js +5 -25
  11. package/handlers/workers/integration-defined-workers.js +3 -6
  12. package/index.js +16 -1
  13. package/integrations/create-frigg-backend.js +31 -0
  14. package/integrations/index.js +5 -0
  15. package/integrations/integration-base.js +44 -42
  16. package/integrations/integration-factory.js +251 -0
  17. package/integrations/integration-router.js +178 -301
  18. package/integrations/integration-user.js +144 -0
  19. package/integrations/options.js +1 -1
  20. package/integrations/test/integration-base.test.js +144 -0
  21. package/module-plugin/auther.js +393 -0
  22. package/module-plugin/entity-manager.js +70 -0
  23. package/{modules → module-plugin}/index.js +8 -0
  24. package/module-plugin/manager.js +169 -0
  25. package/module-plugin/module-factory.js +61 -0
  26. package/{modules → module-plugin}/test/mock-api/api.js +3 -8
  27. package/{modules → module-plugin}/test/mock-api/definition.js +8 -12
  28. package/package.json +5 -5
  29. package/syncs/sync.js +1 -0
  30. package/types/integrations/index.d.ts +6 -2
  31. package/types/module-plugin/index.d.ts +56 -4
  32. package/types/syncs/index.d.ts +2 -0
  33. package/credential/credential-repository.js +0 -42
  34. package/credential/use-cases/get-credential-for-user.js +0 -21
  35. package/credential/use-cases/update-authentication-status.js +0 -15
  36. package/handlers/app-definition-loader.js +0 -38
  37. package/integrations/integration-repository.js +0 -80
  38. package/integrations/integration.js +0 -233
  39. package/integrations/tests/doubles/dummy-integration-class.js +0 -90
  40. package/integrations/tests/doubles/test-integration-repository.js +0 -89
  41. package/integrations/tests/use-cases/create-integration.test.js +0 -124
  42. package/integrations/tests/use-cases/delete-integration-for-user.test.js +0 -143
  43. package/integrations/tests/use-cases/get-integration-for-user.test.js +0 -143
  44. package/integrations/tests/use-cases/get-integration-instance.test.js +0 -169
  45. package/integrations/tests/use-cases/get-integrations-for-user.test.js +0 -169
  46. package/integrations/tests/use-cases/get-possible-integrations.test.js +0 -188
  47. package/integrations/tests/use-cases/update-integration-messages.test.js +0 -142
  48. package/integrations/tests/use-cases/update-integration-status.test.js +0 -103
  49. package/integrations/tests/use-cases/update-integration.test.js +0 -134
  50. package/integrations/use-cases/create-integration.js +0 -72
  51. package/integrations/use-cases/delete-integration-for-user.js +0 -73
  52. package/integrations/use-cases/get-integration-for-user.js +0 -80
  53. package/integrations/use-cases/get-integration-instance-by-definition.js +0 -67
  54. package/integrations/use-cases/get-integration-instance.js +0 -84
  55. package/integrations/use-cases/get-integrations-for-user.js +0 -77
  56. package/integrations/use-cases/get-possible-integrations.js +0 -27
  57. package/integrations/use-cases/index.js +0 -11
  58. package/integrations/use-cases/update-integration-messages.js +0 -31
  59. package/integrations/use-cases/update-integration-status.js +0 -28
  60. package/integrations/use-cases/update-integration.js +0 -92
  61. package/integrations/utils/map-integration-dto.js +0 -36
  62. package/modules/module-factory.js +0 -54
  63. package/modules/module-repository.js +0 -107
  64. package/modules/module.js +0 -221
  65. package/modules/tests/doubles/test-module-factory.js +0 -16
  66. package/modules/tests/doubles/test-module-repository.js +0 -19
  67. package/modules/use-cases/get-entities-for-user.js +0 -32
  68. package/modules/use-cases/get-entity-options-by-id.js +0 -58
  69. package/modules/use-cases/get-entity-options-by-type.js +0 -34
  70. package/modules/use-cases/get-module-instance-from-type.js +0 -31
  71. package/modules/use-cases/get-module.js +0 -56
  72. package/modules/use-cases/process-authorization-callback.js +0 -114
  73. package/modules/use-cases/refresh-entity-options.js +0 -58
  74. package/modules/use-cases/test-module-auth.js +0 -54
  75. package/modules/utils/map-module-dto.js +0 -18
  76. package/user/tests/doubles/test-user-repository.js +0 -72
  77. package/user/tests/use-cases/create-individual-user.test.js +0 -24
  78. package/user/tests/use-cases/create-organization-user.test.js +0 -28
  79. package/user/tests/use-cases/create-token-for-user-id.test.js +0 -19
  80. package/user/tests/use-cases/get-user-from-bearer-token.test.js +0 -64
  81. package/user/tests/use-cases/login-user.test.js +0 -140
  82. package/user/use-cases/create-individual-user.js +0 -61
  83. package/user/use-cases/create-organization-user.js +0 -47
  84. package/user/use-cases/create-token-for-user-id.js +0 -30
  85. package/user/use-cases/get-user-from-bearer-token.js +0 -77
  86. package/user/use-cases/login-user.js +0 -122
  87. package/user/user-repository.js +0 -62
  88. package/user/user.js +0 -77
  89. /package/{modules → module-plugin}/ModuleConstants.js +0 -0
  90. /package/{modules → module-plugin}/credential.js +0 -0
  91. /package/{modules → module-plugin}/entity.js +0 -0
  92. /package/{modules → module-plugin}/requester/api-key.js +0 -0
  93. /package/{modules → module-plugin}/requester/basic.js +0 -0
  94. /package/{modules → module-plugin}/requester/oauth-2.js +0 -0
  95. /package/{modules → module-plugin}/requester/requester.js +0 -0
  96. /package/{modules → module-plugin}/requester/requester.test.js +0 -0
  97. /package/{modules → module-plugin}/test/auther.test.js +0 -0
  98. /package/{modules → module-plugin}/test/mock-api/mocks/hubspot.js +0 -0
@@ -34,7 +34,6 @@ const createHandler = (optionByName = {}) => {
34
34
  // Helps mongoose reuse the connection. Lowers response times.
35
35
  context.callbackWaitsForEmptyEventLoop = false;
36
36
 
37
- // todo: this should not be necessary anymore
38
37
  if (shouldUseDatabase) {
39
38
  await connectToDatabase();
40
39
  }
@@ -8,6 +8,11 @@ const schema = new mongoose.Schema({
8
8
  // Add a static method to get active connections
9
9
  schema.statics.getActiveConnections = async function () {
10
10
  try {
11
+ // Return empty array if websockets are not configured
12
+ if (!process.env.WEBSOCKET_API_ENDPOINT) {
13
+ return [];
14
+ }
15
+
11
16
  const connections = await this.find({}, 'connectionId');
12
17
  return connections.map((conn) => ({
13
18
  connectionId: conn.connectionId,
@@ -3,6 +3,7 @@ const express = require('express');
3
3
  const bodyParser = require('body-parser');
4
4
  const cors = require('cors');
5
5
  const Boom = require('@hapi/boom');
6
+ const loadUserManager = require('./routers/middleware/loadUser');
6
7
  const serverlessHttp = require('serverless-http');
7
8
 
8
9
  const createApp = (applyMiddleware) => {
@@ -19,6 +20,8 @@ const createApp = (applyMiddleware) => {
19
20
  })
20
21
  );
21
22
 
23
+ app.use(loadUserManager);
24
+
22
25
  if (applyMiddleware) applyMiddleware(app);
23
26
 
24
27
  // Handle sending error response and logging server errors to console
@@ -1,22 +1,25 @@
1
- const { Router } = require('express');
2
- const { Worker } = require('@friggframework/core');
3
- const { loadAppDefinition } = require('./app-definition-loader');
4
- const { IntegrationRepository } = require('../integrations/integration-repository');
5
- const { ModuleFactory } = require('../modules/module-factory');
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');
9
- const { GetIntegrationInstanceByDefinition } = require('../integrations/use-cases/get-integration-instance-by-definition');
1
+ const { createFriggBackend, Worker } = require('@friggframework/core');
2
+ const { findNearestBackendPackageJson } = require('@friggframework/core/utils');
3
+ const path = require('node:path');
4
+ const fs = require('fs-extra');
10
5
 
11
- const loadRouterFromObject = (IntegrationClass, routerObject) => {
6
+ const backendPath = findNearestBackendPackageJson();
7
+ if (!backendPath) {
8
+ throw new Error('Could not find backend package.json');
9
+ }
12
10
 
13
- const integrationRepository = new IntegrationRepository();
14
- const moduleRepository = new ModuleRepository();
15
- const moduleFactory = new ModuleFactory({
16
- moduleRepository,
17
- moduleDefinitions: getModulesDefinitionFromIntegrationClasses(integrationClasses),
18
- });
11
+ const backendDir = path.dirname(backendPath);
12
+ const backendFilePath = path.join(backendDir, 'index.js');
13
+ if (!fs.existsSync(backendFilePath)) {
14
+ throw new Error('Could not find index.js');
15
+ }
16
+
17
+ const backendJsFile = require(backendFilePath);
18
+ const { Router } = require('express');
19
+ const appDefinition = backendJsFile.Definition;
19
20
 
21
+ const backend = createFriggBackend(appDefinition);
22
+ const loadRouterFromObject = (IntegrationClass, routerObject) => {
20
23
  const router = Router();
21
24
  const { path, method, event } = routerObject;
22
25
  console.log(
@@ -24,13 +27,10 @@ const loadRouterFromObject = (IntegrationClass, routerObject) => {
24
27
  );
25
28
  router[method.toLowerCase()](path, async (req, res, next) => {
26
29
  try {
27
- const getIntegrationInstanceByDefinition = new GetIntegrationInstanceByDefinition({
28
- integrationRepository,
29
- moduleFactory,
30
- moduleRepository,
31
- });
32
- const integration = await getIntegrationInstanceByDefinition.execute(IntegrationClass.Definition);
33
- const result = await integration.send(event, { req, res, next });
30
+ const integration = new IntegrationClass({});
31
+ await integration.loadModules();
32
+ await integration.registerEventHandlers();
33
+ const result = await integration.send(event, {req, res, next});
34
34
  res.json(result);
35
35
  } catch (error) {
36
36
  next(error);
@@ -39,43 +39,29 @@ const loadRouterFromObject = (IntegrationClass, routerObject) => {
39
39
 
40
40
  return router;
41
41
  };
42
-
43
- //todo: this should be in a use case class
44
- const createQueueWorker = (integrationClass) => {
42
+ const createQueueWorker = (integrationClass, integrationFactory) => {
45
43
  class QueueWorker extends Worker {
46
44
  async _run(params, context) {
47
45
  try {
48
- let integrationInstance;
46
+ let instance;
49
47
  if (!params.integrationId) {
50
- integrationInstance = new integrationClass();
51
- await integrationInstance.loadModules();
52
- await integrationInstance.registerEventHandlers();
48
+ instance = new integrationClass({});
49
+ await instance.loadModules();
50
+ // await instance.loadUserActions();
51
+ await instance.registerEventHandlers();
53
52
  console.log(
54
53
  `${params.event} for ${integrationClass.Definition.name} integration with no integrationId`
55
54
  );
56
55
  } else {
57
- const { integrations: integrationClasses } = loadAppDefinition();
58
- const integrationRepository = new IntegrationRepository();
59
- const moduleRepository = new ModuleRepository();
60
- const moduleFactory = new ModuleFactory({
61
- moduleRepository,
62
- moduleDefinitions: getModulesDefinitionFromIntegrationClasses(integrationClasses),
63
- });
64
-
65
- const getIntegrationInstance = new GetIntegrationInstance({
66
- integrationRepository,
67
- integrationClasses,
68
- moduleFactory,
69
- });
70
-
71
- // todo: are we going to have the userId available here?
72
- integrationInstance = await getIntegrationInstance.execute(params.integrationId, params.userId);
56
+ instance =
57
+ await integrationFactory.getInstanceFromIntegrationId({
58
+ integrationId: params.integrationId,
59
+ });
73
60
  console.log(
74
- `${params.event} for ${integrationInstance.record.config.type} of integrationId: ${params.integrationId}`
61
+ `${params.event} for ${instance.record.config.type} of integrationId: ${params.integrationId}`
75
62
  );
76
63
  }
77
-
78
- const res = await integrationInstance.send(params.event, {
64
+ const res = await instance.send(params.event, {
79
65
  data: params.data,
80
66
  context,
81
67
  });
@@ -93,6 +79,7 @@ const createQueueWorker = (integrationClass) => {
93
79
  };
94
80
 
95
81
  module.exports = {
82
+ ...backend,
96
83
  loadRouterFromObject,
97
84
  createQueueWorker,
98
85
  };
@@ -1,15 +1,26 @@
1
1
  const { createIntegrationRouter } = require('@friggframework/core');
2
2
  const { createAppHandler } = require('./../app-handler-helpers');
3
+ const { requireLoggedInUser } = require('./middleware/requireLoggedInUser');
4
+ const {
5
+ moduleFactory,
6
+ integrationFactory,
7
+ IntegrationHelper,
8
+ } = require('./../backend-utils');
3
9
 
4
- const router = createIntegrationRouter();
10
+ const router = createIntegrationRouter({
11
+ factory: { moduleFactory, integrationFactory, IntegrationHelper },
12
+ requireLoggedInUser,
13
+ getUserId: (req) => req.user.getUserId(),
14
+ });
5
15
 
6
16
  router.route('/redirect/:appId').get((req, res) => {
7
17
  res.redirect(
8
- `${process.env.FRONTEND_URI}/redirect/${req.params.appId
18
+ `${process.env.FRONTEND_URI}/redirect/${
19
+ req.params.appId
9
20
  }?${new URLSearchParams(req.query)}`
10
21
  );
11
22
  });
12
23
 
13
24
  const handler = createAppHandler('HTTP Event: Auth', router);
14
25
 
15
- module.exports = { handler };
26
+ module.exports = { handler, router };
@@ -1,18 +1,15 @@
1
1
  const { createAppHandler } = require('./../app-handler-helpers');
2
2
  const {
3
- loadAppDefinition,
4
- } = require('../app-definition-loader');
3
+ integrationFactory,
4
+ loadRouterFromObject,
5
+ } = require('./../backend-utils');
5
6
  const { Router } = require('express');
6
- const { loadRouterFromObject } = require('../backend-utils');
7
7
 
8
8
  const handlers = {};
9
- const { integrations: integrationClasses } = loadAppDefinition();
10
-
11
- //todo: this should be in a use case class
12
- for (const IntegrationClass of integrationClasses) {
9
+ for (const IntegrationClass of integrationFactory.integrationClasses) {
13
10
  const router = Router();
14
11
  const basePath = `/api/${IntegrationClass.Definition.name}-integration`;
15
-
12
+
16
13
  console.log(`\n│ Configuring routes for ${IntegrationClass.Definition.name} Integration:`);
17
14
 
18
15
  for (const routeDef of IntegrationClass.Definition.routes) {
@@ -0,0 +1,15 @@
1
+ const catchAsyncError = require('express-async-handler');
2
+ const { User } = require('../../backend-utils');
3
+
4
+ module.exports = catchAsyncError(async (req, res, next) => {
5
+ const authorizationHeader = req.headers.authorization;
6
+
7
+ if (authorizationHeader) {
8
+ // Removes "Bearer " and trims
9
+ const token = authorizationHeader.split(' ')[1].trim();
10
+ // Load user for later middleware/routes to use
11
+ req.user = await User.newUser({ token });
12
+ }
13
+
14
+ return next();
15
+ });
@@ -0,0 +1,12 @@
1
+ const Boom = require('@hapi/boom');
2
+
3
+ // CheckLoggedIn Middleware
4
+ const requireLoggedInUser = (req, res, next) => {
5
+ if (!req.user || !req.user.isLoggedIn()) {
6
+ throw Boom.unauthorized('Invalid Token');
7
+ }
8
+
9
+ next();
10
+ };
11
+
12
+ module.exports = { requireLoggedInUser };
@@ -1,29 +1,10 @@
1
1
  const express = require('express');
2
2
  const { createAppHandler } = require('../app-handler-helpers');
3
3
  const { checkRequiredParams } = require('@friggframework/core');
4
- const { UserRepository } = require('../../user/user-repository');
5
- const {
6
- CreateIndividualUser,
7
- } = require('../../user/use-cases/create-individual-user');
8
- const { LoginUser } = require('../../user/use-cases/login-user');
9
- const {
10
- CreateTokenForUserId,
11
- } = require('../../user/use-cases/create-token-for-user-id');
4
+ const { User } = require('../backend-utils');
12
5
  const catchAsyncError = require('express-async-handler');
13
- const { loadAppDefinition } = require('../app-definition-loader');
14
6
 
15
7
  const router = express();
16
- const { userConfig } = loadAppDefinition();
17
- const userRepository = new UserRepository({ userConfig });
18
- const createIndividualUser = new CreateIndividualUser({
19
- userRepository,
20
- userConfig,
21
- });
22
- const loginUser = new LoginUser({
23
- userRepository,
24
- userConfig,
25
- });
26
- const createTokenForUserId = new CreateTokenForUserId({ userRepository });
27
8
 
28
9
  // define the login endpoint
29
10
  router.route('/user/login').post(
@@ -32,8 +13,8 @@ router.route('/user/login').post(
32
13
  'username',
33
14
  'password',
34
15
  ]);
35
- const user = await loginUser.execute({ username, password });
36
- const token = await createTokenForUserId.execute(user.getId(), 120);
16
+ const user = await User.loginUser({ username, password });
17
+ const token = await user.createUserToken(120);
37
18
  res.status(201);
38
19
  res.json({ token });
39
20
  })
@@ -45,12 +26,11 @@ router.route('/user/create').post(
45
26
  'username',
46
27
  'password',
47
28
  ]);
48
-
49
- const user = await createIndividualUser.execute({
29
+ const user = await User.createIndividualUser({
50
30
  username,
51
31
  password,
52
32
  });
53
- const token = await createTokenForUserId.execute(user.getId(), 120);
33
+ const token = await user.createUserToken(120);
54
34
  res.status(201);
55
35
  res.json({ token });
56
36
  })
@@ -1,12 +1,9 @@
1
1
  const { createHandler } = require('@friggframework/core');
2
- const { loadAppDefinition } = require('../app-definition-loader');
3
- const { createQueueWorker } = require('../backend-utils');
2
+ const { integrationFactory, createQueueWorker } = require('../backend-utils');
4
3
 
5
4
  const handlers = {};
6
- const { integrations: integrationClasses } = loadAppDefinition();
7
-
8
- integrationClasses.forEach((IntegrationClass) => {
9
- const defaultQueueWorker = createQueueWorker(IntegrationClass);
5
+ integrationFactory.integrationClasses.forEach((IntegrationClass) => {
6
+ const defaultQueueWorker = createQueueWorker(IntegrationClass, integrationFactory);
10
7
 
11
8
  handlers[`${IntegrationClass.Definition.name}`] = {
12
9
  queueWorker: createHandler({
package/index.js CHANGED
@@ -38,20 +38,27 @@ const {
38
38
  IntegrationModel,
39
39
  Options,
40
40
  IntegrationMapping,
41
+ IntegrationFactory,
42
+ IntegrationHelper,
41
43
  createIntegrationRouter,
42
44
  checkRequiredParams,
45
+ createFriggBackend,
43
46
  } = require('./integrations/index');
44
47
  const { TimeoutCatcher } = require('./lambda/index');
45
48
  const { debug, initDebugLog, flushDebugLog } = require('./logs/index');
46
49
  const {
47
50
  Credential,
51
+ EntityManager,
48
52
  Entity,
53
+ ModuleManager,
49
54
  ApiKeyRequester,
50
55
  BasicAuthRequester,
51
56
  OAuth2Requester,
52
57
  Requester,
53
58
  ModuleConstants,
54
- } = require('./modules/index');
59
+ ModuleFactory,
60
+ Auther,
61
+ } = require('./module-plugin/index');
55
62
  const utils = require('./utils');
56
63
 
57
64
  // const {Sync } = require('./syncs/model');
@@ -102,8 +109,11 @@ module.exports = {
102
109
  IntegrationModel,
103
110
  Options,
104
111
  IntegrationMapping,
112
+ IntegrationFactory,
113
+ IntegrationHelper,
105
114
  checkRequiredParams,
106
115
  createIntegrationRouter,
116
+ createFriggBackend,
107
117
 
108
118
  // lambda
109
119
  TimeoutCatcher,
@@ -115,12 +125,17 @@ module.exports = {
115
125
 
116
126
  // module plugin
117
127
  Credential,
128
+ EntityManager,
118
129
  Entity,
130
+ ModuleManager,
119
131
  ApiKeyRequester,
120
132
  BasicAuthRequester,
121
133
  OAuth2Requester,
122
134
  Requester,
123
135
  ModuleConstants,
136
+ ModuleFactory,
137
+ Auther,
138
+
124
139
  // queues
125
140
  QueuerUtil,
126
141
 
@@ -0,0 +1,31 @@
1
+ const {IntegrationFactory, IntegrationHelper} = require('./integration-factory');
2
+ const User = require('./integration-user');
3
+
4
+ function createFriggBackend(appDefinition) {
5
+ const {integrations = [], user=null} = appDefinition
6
+ const integrationFactory = new IntegrationFactory(integrations);
7
+ if (user) {
8
+ if (user.usePassword) {
9
+ User.usePassword = true;
10
+ }
11
+ if (user.primary === 'organization') {
12
+ User.primary = User.OrganizationUser
13
+ }
14
+ if (user.individualUserRequired !== undefined) {
15
+ User.individualUserRequired = user.individualUserRequired
16
+ }
17
+ if (user.organizationUserRequired !== undefined) {
18
+ User.organizationUserRequired = user.organizationUserRequired
19
+ }
20
+
21
+ }
22
+ const backend = {
23
+ integrationFactory,
24
+ moduleFactory: integrationFactory.moduleFactory,
25
+ IntegrationHelper,
26
+ User: User
27
+ }
28
+ return backend
29
+ }
30
+
31
+ module.exports = { createFriggBackend }
@@ -2,13 +2,18 @@ const { IntegrationBase } = require('./integration-base');
2
2
  const { IntegrationModel } = require('./integration-model');
3
3
  const { Options } = require('./options');
4
4
  const { IntegrationMapping } = require('./integration-mapping');
5
+ const { IntegrationFactory, IntegrationHelper } = require('./integration-factory');
5
6
  const { createIntegrationRouter, checkRequiredParams } = require('./integration-router');
7
+ const { createFriggBackend } = require('./create-frigg-backend');
6
8
 
7
9
  module.exports = {
8
10
  IntegrationBase,
9
11
  IntegrationModel,
10
12
  Options,
11
13
  IntegrationMapping,
14
+ IntegrationFactory,
15
+ IntegrationHelper,
12
16
  createIntegrationRouter,
13
17
  checkRequiredParams,
18
+ createFriggBackend
14
19
  };
@@ -1,9 +1,5 @@
1
1
  const { IntegrationMapping } = require('./integration-mapping');
2
2
  const { Options } = require('./options');
3
- const { UpdateIntegrationStatus } = require('./use-cases/update-integration-status');
4
- const { IntegrationRepository } = require('./integration-repository');
5
- const { UpdateIntegrationMessages } = require('./use-cases/update-integration-messages');
6
-
7
3
  const constantsToBeMigrated = {
8
4
  defaultEvents: {
9
5
  ON_CREATE: 'ON_CREATE',
@@ -23,12 +19,6 @@ const constantsToBeMigrated = {
23
19
  };
24
20
 
25
21
  class IntegrationBase {
26
-
27
- // todo: maybe we can pass this as Dependency Injection in the sub-class constructor
28
- integrationRepository = new IntegrationRepository();
29
- updateIntegrationStatus = new UpdateIntegrationStatus({ integrationRepository: this.integrationRepository });
30
- updateIntegrationMessages = new UpdateIntegrationMessages({ integrationRepository: this.integrationRepository });
31
-
32
22
  static getOptionDetails() {
33
23
  const options = new Options({
34
24
  module: Object.values(this.Definition.modules)[0], // This is a placeholder until we revamp the frontend
@@ -36,7 +26,6 @@ class IntegrationBase {
36
26
  });
37
27
  return options.get();
38
28
  }
39
-
40
29
  /**
41
30
  * CHILDREN SHOULD SPECIFY A DEFINITION FOR THE INTEGRATION
42
31
  */
@@ -61,7 +50,21 @@ class IntegrationBase {
61
50
  static getCurrentVersion() {
62
51
  return this.Definition.version;
63
52
  }
64
-
53
+ loadModules() {
54
+ // Load all the modules defined in Definition.modules
55
+ const moduleNames = Object.keys(this.constructor.Definition.modules);
56
+ for (const moduleName of moduleNames) {
57
+ const { definition } =
58
+ this.constructor.Definition.modules[moduleName];
59
+ if (typeof definition.API === 'function') {
60
+ this[moduleName] = { api: new definition.API() };
61
+ } else {
62
+ throw new Error(
63
+ `Module ${moduleName} must be a function that extends IntegrationModule`
64
+ );
65
+ }
66
+ }
67
+ }
65
68
  registerEventHandlers() {
66
69
  this.on = {
67
70
  ...this.defaultEvents,
@@ -70,7 +73,6 @@ class IntegrationBase {
70
73
  }
71
74
 
72
75
  constructor(params) {
73
-
74
76
  this.defaultEvents = {
75
77
  [constantsToBeMigrated.defaultEvents.ON_CREATE]: {
76
78
  type: constantsToBeMigrated.types.LIFE_CYCLE_EVENT,
@@ -105,6 +107,7 @@ class IntegrationBase {
105
107
  handler: this.refreshActionOptions,
106
108
  },
107
109
  };
110
+ this.loadModules();
108
111
  }
109
112
 
110
113
  async send(event, object) {
@@ -118,7 +121,7 @@ class IntegrationBase {
118
121
 
119
122
  async validateConfig() {
120
123
  const configOptions = await this.getConfigOptions();
121
- const currentConfig = this.getConfig();
124
+ const currentConfig = this.record.config;
122
125
  let needsConfig = false;
123
126
  for (const option of configOptions) {
124
127
  if (option.required) {
@@ -130,18 +133,17 @@ class IntegrationBase {
130
133
  )
131
134
  ) {
132
135
  needsConfig = true;
133
- await this.updateIntegrationMessages.execute(
134
- this.id,
135
- 'warnings',
136
- 'Config Validation Error',
137
- `Missing required field of ${option.label}`,
138
- Date.now()
139
- );
136
+ this.record.messages.warnings.push({
137
+ title: 'Config Validation Error',
138
+ message: `Missing required field of ${option.label}`,
139
+ timestamp: Date.now(),
140
+ });
140
141
  }
141
142
  }
142
143
  }
143
144
  if (needsConfig) {
144
- await this.updateIntegrationStatus.execute(this.id, 'NEEDS_CONFIG');
145
+ this.record.status = 'NEEDS_CONFIG';
146
+ await this.record.save();
145
147
  }
146
148
  }
147
149
 
@@ -153,36 +155,34 @@ class IntegrationBase {
153
155
  await this[module].testAuth();
154
156
  } catch {
155
157
  didAuthPass = false;
156
- await this.updateIntegrationMessages.execute(
157
- this.id,
158
- 'errors',
159
- 'Authentication Error',
160
- `There was an error with your ${this[
158
+ this.record.messages.errors.push({
159
+ title: 'Authentication Error',
160
+ message: `There was an error with your ${this[
161
161
  module
162
162
  ].constructor.getName()} Entity.
163
163
  Please reconnect/re-authenticate, or reach out to Support for assistance.`,
164
- Date.now()
165
- );
164
+ timestamp: Date.now(),
165
+ });
166
166
  }
167
167
  }
168
168
 
169
169
  if (!didAuthPass) {
170
- await this.updateIntegrationStatus.execute(this.id, 'ERROR');
170
+ this.record.status = 'ERROR';
171
+ this.record.markModified('messages.error');
172
+ await this.record.save();
171
173
  }
172
174
  }
173
175
 
174
176
  async getMapping(sourceId) {
175
- // todo: this should be a use case
176
- return IntegrationMapping.findBy(this.id, sourceId);
177
+ return IntegrationMapping.findBy(this.record.id, sourceId);
177
178
  }
178
179
 
179
180
  async upsertMapping(sourceId, mapping) {
180
181
  if (!sourceId) {
181
182
  throw new Error(`sourceId must be set`);
182
183
  }
183
- // todo: this should be a use case
184
184
  return await IntegrationMapping.upsert(
185
- this.id,
185
+ this.record.id,
186
186
  sourceId,
187
187
  mapping
188
188
  );
@@ -191,13 +191,15 @@ class IntegrationBase {
191
191
  /**
192
192
  * CHILDREN CAN OVERRIDE THESE CONFIGURATION METHODS
193
193
  */
194
- async onCreate({ integrationId }) {
195
- await this.updateIntegrationStatus.execute(integrationId, 'ENABLED');
194
+ async onCreate(params) {
195
+ this.record.status = 'ENABLED';
196
+ await this.record.save();
197
+ return this.record;
196
198
  }
197
199
 
198
- async onUpdate(params) { }
200
+ async onUpdate(params) {}
199
201
 
200
- async onDelete(params) { }
202
+ async onDelete(params) {}
201
203
 
202
204
  async getConfigOptions() {
203
205
  const options = {
@@ -234,10 +236,10 @@ class IntegrationBase {
234
236
  const dynamicUserActions = await this.loadDynamicUserActions();
235
237
  const filteredDynamicActions = actionType
236
238
  ? Object.fromEntries(
237
- Object.entries(dynamicUserActions).filter(
238
- ([_, event]) => event.userActionType === actionType
239
- )
240
- )
239
+ Object.entries(dynamicUserActions).filter(
240
+ ([_, event]) => event.userActionType === actionType
241
+ )
242
+ )
241
243
  : dynamicUserActions;
242
244
  return { ...userActions, ...filteredDynamicActions };
243
245
  }