@friggframework/core 2.0.0--canary.522.cbd3d5a.0 → 2.0.0--canary.517.35ee143.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 (225) hide show
  1. package/CHANGELOG.md +67 -66
  2. package/CLAUDE.md +124 -148
  3. package/README.md +130 -165
  4. package/admin-scripts/index.js +16 -30
  5. package/admin-scripts/repositories/{admin-api-key-repository-documentdb.js → admin-process-repository-documentdb.js} +5 -5
  6. package/admin-scripts/repositories/{admin-api-key-repository-factory.js → admin-process-repository-factory.js} +15 -19
  7. package/admin-scripts/repositories/admin-process-repository-interface.js +150 -0
  8. package/admin-scripts/repositories/admin-process-repository-mongo.js +213 -0
  9. package/admin-scripts/repositories/admin-process-repository-postgres.js +251 -0
  10. package/admin-scripts/repositories/script-schedule-repository-factory.js +2 -6
  11. package/admin-scripts/repositories/script-schedule-repository-interface.js +14 -36
  12. package/admin-scripts/repositories/script-schedule-repository-mongo.js +13 -25
  13. package/admin-scripts/repositories/script-schedule-repository-postgres.js +13 -25
  14. package/application/commands/admin-script-commands.js +102 -266
  15. package/application/commands/integration-commands.js +6 -12
  16. package/application/index.js +3 -1
  17. package/assertions/get.js +4 -1
  18. package/associations/association.js +57 -59
  19. package/associations/model.js +41 -41
  20. package/core/CLAUDE.md +156 -222
  21. package/core/Worker.js +1 -5
  22. package/credential/repositories/credential-repository-documentdb.js +1 -71
  23. package/credential/repositories/credential-repository-interface.js +2 -8
  24. package/credential/repositories/credential-repository-mongo.js +4 -45
  25. package/credential/repositories/credential-repository-postgres.js +3 -44
  26. package/credential/repositories/credential-repository.js +4 -6
  27. package/credential/use-cases/get-credential-for-user.js +3 -21
  28. package/credential/use-cases/update-authentication-status.js +2 -5
  29. package/database/MONGODB_TRANSACTION_FIX.md +52 -72
  30. package/database/adapters/lambda-invoker.js +7 -8
  31. package/database/config.js +13 -15
  32. package/database/documentdb-encryption-service.js +13 -29
  33. package/database/documentdb-utils.js +12 -21
  34. package/database/encryption/README.md +36 -53
  35. package/database/encryption/encryption-schema-registry.js +9 -21
  36. package/database/encryption/field-encryption-service.js +4 -15
  37. package/database/encryption/logger.js +2 -3
  38. package/database/encryption/prisma-encryption-extension.js +8 -5
  39. package/database/index.js +2 -4
  40. package/database/models/IndividualUser.js +15 -15
  41. package/database/models/OrganizationUser.js +4 -6
  42. package/database/models/UserModel.js +2 -2
  43. package/database/models/WebsocketConnection.js +1 -4
  44. package/database/mongoose.js +2 -2
  45. package/database/prisma.js +14 -22
  46. package/database/repositories/health-check-repository-documentdb.js +7 -22
  47. package/database/repositories/health-check-repository-factory.js +3 -9
  48. package/database/repositories/health-check-repository-interface.js +5 -15
  49. package/database/repositories/health-check-repository-mongodb.js +6 -9
  50. package/database/repositories/health-check-repository-postgres.js +1 -1
  51. package/database/repositories/migration-status-repository-s3.js +5 -10
  52. package/database/use-cases/check-database-health-use-case.js +2 -3
  53. package/database/use-cases/check-database-state-use-case.js +7 -9
  54. package/database/use-cases/get-database-state-via-worker-use-case.js +12 -15
  55. package/database/use-cases/get-migration-status-use-case.js +2 -4
  56. package/database/use-cases/run-database-migration-use-case.js +9 -41
  57. package/database/use-cases/test-encryption-use-case.js +5 -4
  58. package/database/use-cases/trigger-database-migration-use-case.js +8 -9
  59. package/database/utils/mongodb-collection-utils.js +3 -11
  60. package/database/utils/mongodb-schema-init.js +4 -10
  61. package/database/utils/prisma-runner.js +74 -144
  62. package/database/utils/prisma-schema-parser.js +2 -2
  63. package/docs/PROCESS_MANAGEMENT_QUEUE_SPEC.md +80 -135
  64. package/encrypt/Cryptor.js +2 -8
  65. package/errors/fetch-error.js +1 -1
  66. package/generated/prisma-mongodb/edge.js +16 -59
  67. package/generated/prisma-mongodb/index-browser.js +12 -62
  68. package/generated/prisma-mongodb/index.d.ts +4850 -8136
  69. package/generated/prisma-mongodb/index.js +16 -59
  70. package/generated/prisma-mongodb/package.json +1 -1
  71. package/generated/prisma-mongodb/schema.prisma +33 -75
  72. package/generated/prisma-mongodb/wasm.js +16 -59
  73. package/generated/prisma-postgresql/edge.js +15 -59
  74. package/generated/prisma-postgresql/index-browser.js +11 -62
  75. package/generated/prisma-postgresql/index.d.ts +5963 -8930
  76. package/generated/prisma-postgresql/index.js +15 -59
  77. package/generated/prisma-postgresql/package.json +1 -1
  78. package/generated/prisma-postgresql/schema.prisma +33 -73
  79. package/generated/prisma-postgresql/wasm.js +15 -59
  80. package/handlers/WEBHOOKS.md +81 -104
  81. package/handlers/app-definition-loader.js +1 -1
  82. package/handlers/app-handler-helpers.js +2 -14
  83. package/handlers/backend-utils.js +1 -0
  84. package/handlers/database-migration-handler.js +45 -64
  85. package/handlers/middleware/admin-auth.js +53 -0
  86. package/handlers/routers/HEALTHCHECK.md +135 -170
  87. package/handlers/routers/auth.js +2 -23
  88. package/handlers/routers/db-migration.handler.js +3 -2
  89. package/handlers/routers/db-migration.js +33 -69
  90. package/handlers/routers/health.js +8 -23
  91. package/handlers/routers/integration-defined-routers.js +4 -4
  92. package/handlers/routers/integration-webhook-routers.js +7 -17
  93. package/handlers/routers/websocket.js +3 -9
  94. package/handlers/use-cases/check-integrations-health-use-case.js +6 -13
  95. package/handlers/workers/db-migration.js +26 -54
  96. package/index.js +9 -5
  97. package/integrations/WEBHOOK-QUICKSTART.md +14 -21
  98. package/integrations/index.js +0 -4
  99. package/integrations/integration-base.js +6 -9
  100. package/integrations/integration-router.js +146 -1817
  101. package/integrations/options.js +20 -47
  102. package/integrations/repositories/integration-repository-documentdb.js +24 -53
  103. package/integrations/repositories/integration-repository-factory.js +2 -6
  104. package/integrations/repositories/integration-repository-interface.js +9 -27
  105. package/integrations/repositories/integration-repository-postgres.js +3 -3
  106. package/integrations/repositories/process-repository-factory.js +1 -0
  107. package/integrations/repositories/process-repository-interface.js +5 -9
  108. package/integrations/repositories/process-repository-mongo.js +3 -7
  109. package/integrations/repositories/process-repository-postgres.js +2 -2
  110. package/integrations/tests/doubles/config-capturing-integration.js +8 -9
  111. package/integrations/tests/doubles/dummy-integration-class.js +8 -81
  112. package/integrations/tests/doubles/test-integration-repository.js +11 -51
  113. package/integrations/use-cases/create-integration.js +32 -36
  114. package/integrations/use-cases/create-process.js +9 -20
  115. package/integrations/use-cases/delete-integration-for-user.js +4 -5
  116. package/integrations/use-cases/get-integration-for-user.js +10 -25
  117. package/integrations/use-cases/get-integration-instance-by-definition.js +7 -13
  118. package/integrations/use-cases/get-integrations-for-user.js +1 -4
  119. package/integrations/use-cases/get-possible-integrations.js +1 -1
  120. package/integrations/use-cases/get-process.js +6 -5
  121. package/integrations/use-cases/index.js +1 -3
  122. package/integrations/use-cases/load-integration-context.js +5 -1
  123. package/integrations/use-cases/update-process-state.js +8 -10
  124. package/integrations/utils/map-integration-dto.js +3 -9
  125. package/jest-setup.js +1 -1
  126. package/jest-teardown.js +1 -1
  127. package/lambda/TimeoutCatcher.js +30 -32
  128. package/lambda/index.js +1 -1
  129. package/logs/index.js +3 -3
  130. package/modules/module.js +1 -3
  131. package/modules/repositories/module-repository-documentdb.js +48 -114
  132. package/modules/repositories/module-repository-interface.js +0 -13
  133. package/modules/repositories/module-repository-mongo.js +6 -46
  134. package/modules/repositories/module-repository-postgres.js +6 -48
  135. package/modules/repositories/module-repository.js +1 -34
  136. package/modules/requester/api-key.js +2 -0
  137. package/modules/requester/basic.js +1 -0
  138. package/modules/requester/oauth-2.js +2 -3
  139. package/modules/test/mock-api/definition.js +10 -15
  140. package/modules/test/mock-api/mocks/hubspot.js +36 -36
  141. package/modules/tests/doubles/test-module-factory.js +4 -10
  142. package/modules/tests/doubles/test-module-repository.js +1 -1
  143. package/modules/use-cases/get-entities-for-user.js +1 -1
  144. package/modules/use-cases/get-entity-options-by-id.js +6 -8
  145. package/modules/use-cases/get-module.js +9 -12
  146. package/modules/use-cases/process-authorization-callback.js +6 -12
  147. package/modules/use-cases/refresh-entity-options.js +6 -8
  148. package/modules/use-cases/test-module-auth.js +6 -8
  149. package/modules/utils/map-module-dto.js +2 -2
  150. package/package.json +5 -7
  151. package/prisma-mongodb/schema.prisma +33 -75
  152. package/prisma-postgresql/schema.prisma +33 -73
  153. package/queues/queuer-util.js +1 -5
  154. package/syncs/model.js +51 -51
  155. package/syncs/repositories/sync-repository-documentdb.js +19 -39
  156. package/syncs/repositories/sync-repository-interface.js +2 -6
  157. package/syncs/repositories/sync-repository-postgres.js +13 -19
  158. package/syncs/sync.js +100 -104
  159. package/token/repositories/token-repository-factory.js +3 -1
  160. package/types/assertions/index.d.ts +72 -72
  161. package/types/associations/index.d.ts +57 -57
  162. package/types/core/index.d.ts +53 -59
  163. package/types/database/index.d.ts +2 -2
  164. package/types/encrypt/index.d.ts +3 -3
  165. package/types/errors/index.d.ts +54 -61
  166. package/types/eslint-config/index.d.ts +40 -40
  167. package/types/integrations/index.d.ts +183 -185
  168. package/types/lambda/index.d.ts +26 -26
  169. package/types/logs/index.d.ts +4 -4
  170. package/types/module-plugin/index.d.ts +237 -239
  171. package/types/prettier-config/index.d.ts +5 -5
  172. package/types/syncs/index.d.ts +108 -102
  173. package/types/test-environment/index.d.ts +14 -14
  174. package/types/tsconfig.json +93 -95
  175. package/user/tests/doubles/test-user-repository.js +2 -5
  176. package/user/use-cases/authenticate-user.js +4 -2
  177. package/user/use-cases/authenticate-with-shared-secret.js +1 -1
  178. package/user/use-cases/create-individual-user.js +7 -8
  179. package/user/use-cases/create-organization-user.js +1 -1
  180. package/user/use-cases/create-token-for-user-id.js +1 -1
  181. package/user/use-cases/get-user-from-adopter-jwt.js +2 -0
  182. package/user/use-cases/get-user-from-bearer-token.js +3 -7
  183. package/user/use-cases/get-user-from-x-frigg-headers.js +11 -14
  184. package/user/use-cases/login-user.js +8 -8
  185. package/user/user.js +4 -18
  186. package/utils/backend-path.js +2 -2
  187. package/utils/index.js +1 -4
  188. package/websocket/repositories/websocket-connection-repository-documentdb.js +8 -21
  189. package/websocket/repositories/websocket-connection-repository-mongo.js +4 -8
  190. package/websocket/repositories/websocket-connection-repository-postgres.js +4 -8
  191. package/websocket/repositories/websocket-connection-repository.js +4 -8
  192. package/admin-scripts/repositories/admin-api-key-repository-interface.js +0 -121
  193. package/admin-scripts/repositories/admin-api-key-repository-mongo.js +0 -155
  194. package/admin-scripts/repositories/admin-api-key-repository-postgres.js +0 -189
  195. package/admin-scripts/repositories/script-execution-repository-documentdb.js +0 -21
  196. package/admin-scripts/repositories/script-execution-repository-factory.js +0 -55
  197. package/admin-scripts/repositories/script-execution-repository-interface.js +0 -193
  198. package/admin-scripts/repositories/script-execution-repository-mongo.js +0 -278
  199. package/admin-scripts/repositories/script-execution-repository-postgres.js +0 -320
  200. package/credential/credential-router.js +0 -262
  201. package/credential/use-cases/delete-credential-for-user.js +0 -50
  202. package/credential/use-cases/list-credentials-for-user.js +0 -31
  203. package/credential/use-cases/reauthorize-credential.js +0 -103
  204. package/handlers/routers/admin.js +0 -450
  205. package/handlers/routers/docs.js +0 -180
  206. package/handlers/routers/middleware/loadUser.js +0 -39
  207. package/handlers/routers/middleware/requireAdmin.js +0 -41
  208. package/handlers/routers/middleware/requireLoggedInUser.js +0 -19
  209. package/integrations/use-cases/execute-proxy-request.js +0 -564
  210. package/modules/domain/entities/AuthorizationSession.js +0 -131
  211. package/modules/domain/entities/index.js +0 -10
  212. package/modules/repositories/authorization-session-repository-factory.js +0 -55
  213. package/modules/repositories/authorization-session-repository-interface.js +0 -75
  214. package/modules/repositories/authorization-session-repository-mongo.js +0 -169
  215. package/modules/repositories/authorization-session-repository-postgres.js +0 -170
  216. package/modules/use-cases/delete-module-entity.js +0 -23
  217. package/modules/use-cases/get-authorization-requirements.js +0 -110
  218. package/modules/use-cases/get-module-entity-by-id.js +0 -16
  219. package/modules/use-cases/process-authorization-step.js +0 -160
  220. package/modules/use-cases/start-authorization-session.js +0 -86
  221. package/modules/use-cases/update-module-entity.js +0 -27
  222. package/openapi/openapi-spec-generator.js +0 -370
  223. package/openapi/openapi-v1.yaml +0 -1360
  224. package/openapi/openapi-v2.yaml +0 -1535
  225. package/user/use-cases/delete-user.js +0 -47
@@ -31,21 +31,13 @@ class TestIntegrationRepository {
31
31
  }
32
32
 
33
33
  async findIntegrationsByUserId(userId) {
34
- const results = Array.from(this.store.values()).filter(
35
- (r) => r.userId === userId
36
- );
37
- this.operationHistory.push({
38
- operation: 'findByUserId',
39
- userId,
40
- count: results.length,
41
- });
34
+ const results = Array.from(this.store.values()).filter(r => r.userId === userId);
35
+ this.operationHistory.push({ operation: 'findByUserId', userId, count: results.length });
42
36
  return results;
43
37
  }
44
38
 
45
39
  async findIntegrationByUserId(userId) {
46
- const record = Array.from(this.store.values()).find(
47
- (r) => r.userId === userId
48
- );
40
+ const record = Array.from(this.store.values()).find((r) => r.userId === userId);
49
41
  this.operationHistory.push({
50
42
  operation: 'findSingleByUserId',
51
43
  userId,
@@ -57,52 +49,30 @@ class TestIntegrationRepository {
57
49
  async updateIntegrationMessages(id, type, title, body, timestamp) {
58
50
  const rec = this.store.get(id);
59
51
  if (!rec) {
60
- this.operationHistory.push({
61
- operation: 'updateMessages',
62
- id,
63
- success: false,
64
- });
52
+ this.operationHistory.push({ operation: 'updateMessages', id, success: false });
65
53
  return false;
66
54
  }
67
55
  if (!rec.messages[type]) rec.messages[type] = [];
68
56
  rec.messages[type].push({ title, message: body, timestamp });
69
- this.operationHistory.push({
70
- operation: 'updateMessages',
71
- id,
72
- type,
73
- success: true,
74
- });
57
+ this.operationHistory.push({ operation: 'updateMessages', id, type, success: true });
75
58
  return true;
76
59
  }
77
60
 
78
61
  async updateIntegrationConfig(id, config) {
79
62
  const rec = this.store.get(id);
80
63
  if (!rec) {
81
- this.operationHistory.push({
82
- operation: 'updateConfig',
83
- id,
84
- success: false,
85
- });
64
+ this.operationHistory.push({ operation: 'updateConfig', id, success: false });
86
65
  throw new Error(`Integration with id ${id} not found`);
87
66
  }
88
67
  rec.config = config;
89
- this.operationHistory.push({
90
- operation: 'updateConfig',
91
- id,
92
- success: true,
93
- });
68
+ this.operationHistory.push({ operation: 'updateConfig', id, success: true });
94
69
  return rec;
95
70
  }
96
71
 
97
72
  async deleteIntegrationById(id) {
98
73
  const existed = this.store.has(id);
99
74
  const result = this.store.delete(id);
100
- this.operationHistory.push({
101
- operation: 'delete',
102
- id,
103
- existed,
104
- success: result,
105
- });
75
+ this.operationHistory.push({ operation: 'delete', id, existed, success: result });
106
76
  return result;
107
77
  }
108
78
 
@@ -110,19 +80,9 @@ class TestIntegrationRepository {
110
80
  const rec = this.store.get(id);
111
81
  if (rec) {
112
82
  rec.status = status;
113
- this.operationHistory.push({
114
- operation: 'updateStatus',
115
- id,
116
- status,
117
- success: true,
118
- });
83
+ this.operationHistory.push({ operation: 'updateStatus', id, status, success: true });
119
84
  } else {
120
- this.operationHistory.push({
121
- operation: 'updateStatus',
122
- id,
123
- status,
124
- success: false,
125
- });
85
+ this.operationHistory.push({ operation: 'updateStatus', id, status, success: false });
126
86
  }
127
87
  return !!rec;
128
88
  }
@@ -136,4 +96,4 @@ class TestIntegrationRepository {
136
96
  }
137
97
  }
138
98
 
139
- module.exports = { TestIntegrationRepository };
99
+ module.exports = { TestIntegrationRepository };
@@ -1,60 +1,56 @@
1
+ // Removed Integration wrapper - using IntegrationBase directly
1
2
  const {
2
3
  mapIntegrationClassToIntegrationDTO,
3
4
  } = require('../utils/map-integration-dto');
4
5
 
6
+ /**
7
+ * Use case for creating a new integration instance.
8
+ * @class CreateIntegration
9
+ */
5
10
  class CreateIntegration {
11
+ /**
12
+ * Creates a new CreateIntegration instance.
13
+ * @param {Object} params - Configuration parameters.
14
+ * @param {import('../repositories/integration-repository-interface').IntegrationRepositoryInterface} params.integrationRepository - Repository for integration data operations.
15
+ * @param {import('../integration-classes').IntegrationClasses} params.integrationClasses - Array of available integration classes.
16
+ * @param {import('../../modules/module-factory').ModuleFactory} params.moduleFactory - Service for module instantiation and management.
17
+ */
6
18
  constructor({ integrationRepository, integrationClasses, moduleFactory }) {
7
19
  this.integrationRepository = integrationRepository;
8
20
  this.integrationClasses = integrationClasses;
9
21
  this.moduleFactory = moduleFactory;
10
22
  }
11
23
 
24
+ /**
25
+ * Executes the integration creation process.
26
+ * @async
27
+ * @param {string[]} entities - Array of entity IDs to associate with the integration.
28
+ * @param {string} userId - ID of the user creating the integration.
29
+ * @param {Object} config - Configuration object for the integration.
30
+ * @param {string} config.type - Type of integration to create.
31
+ * @returns {Promise<Object>} The created integration DTO.
32
+ * @throws {Error} When integration class is not found for the specified type.
33
+ */
12
34
  async execute(entities, userId, config) {
35
+ const integrationRecord =
36
+ await this.integrationRepository.createIntegration(
37
+ entities,
38
+ userId,
39
+ config
40
+ );
41
+
13
42
  const integrationClass = this.integrationClasses.find(
14
43
  (integrationClass) =>
15
- integrationClass.Definition.name === config.type
44
+ integrationClass.Definition.name ===
45
+ integrationRecord.config.type
16
46
  );
17
47
 
18
48
  if (!integrationClass) {
19
49
  throw new Error(
20
- `No integration class found for type: ${config.type}`
50
+ `No integration class found for type: ${integrationRecord.config.type}`
21
51
  );
22
52
  }
23
53
 
24
- const allEntities = [...entities];
25
-
26
- if (integrationClass.Definition?.entities) {
27
- for (const [entityKey, entityConfig] of Object.entries(
28
- integrationClass.Definition.entities
29
- )) {
30
- if (entityConfig.global === true) {
31
- const globalEntity =
32
- await this.moduleFactory.moduleRepository.findEntity({
33
- moduleName: entityConfig.type,
34
- isGlobal: true,
35
- });
36
-
37
- if (globalEntity && globalEntity.credential?.authIsValid) {
38
- allEntities.push(globalEntity.id.toString());
39
- } else if (entityConfig.required !== false) {
40
- const reason = !globalEntity
41
- ? 'not found'
42
- : 'exists but credential is invalid';
43
- throw new Error(
44
- `Required global entity "${entityConfig.type}" ${reason}. Admin must configure this entity first.`
45
- );
46
- }
47
- }
48
- }
49
- }
50
-
51
- const integrationRecord =
52
- await this.integrationRepository.createIntegration(
53
- allEntities,
54
- userId,
55
- config
56
- );
57
-
58
54
  const modules = [];
59
55
  for (const entityId of integrationRecord.entitiesIds) {
60
56
  const moduleInstance = await this.moduleFactory.getModuleInstance(
@@ -1,15 +1,15 @@
1
1
  /**
2
2
  * CreateProcess Use Case
3
- *
3
+ *
4
4
  * Creates a new process record for tracking long-running operations.
5
5
  * Validates required fields and delegates persistence to the repository.
6
- *
6
+ *
7
7
  * Design Philosophy:
8
8
  * - Use cases encapsulate business logic
9
9
  * - Validation happens at the use case layer
10
10
  * - Repositories handle only data access
11
11
  * - Process model is generic and reusable
12
- *
12
+ *
13
13
  * @example
14
14
  * const createProcess = new CreateProcess({ processRepository });
15
15
  * const process = await createProcess.execute({
@@ -68,9 +68,7 @@ class CreateProcess {
68
68
 
69
69
  // Delegate to repository
70
70
  try {
71
- const createdProcess = await this.processRepository.create(
72
- processToCreate
73
- );
71
+ const createdProcess = await this.processRepository.create(processToCreate);
74
72
  return createdProcess;
75
73
  } catch (error) {
76
74
  throw new Error(`Failed to create process: ${error.message}`);
@@ -85,15 +83,11 @@ class CreateProcess {
85
83
  */
86
84
  _validateProcessData(processData) {
87
85
  const requiredFields = ['userId', 'integrationId', 'name', 'type'];
88
- const missingFields = requiredFields.filter(
89
- (field) => !processData[field]
90
- );
86
+ const missingFields = requiredFields.filter(field => !processData[field]);
91
87
 
92
88
  if (missingFields.length > 0) {
93
89
  throw new Error(
94
- `Missing required fields for process creation: ${missingFields.join(
95
- ', '
96
- )}`
90
+ `Missing required fields for process creation: ${missingFields.join(', ')}`
97
91
  );
98
92
  }
99
93
 
@@ -121,19 +115,14 @@ class CreateProcess {
121
115
  if (processData.results && typeof processData.results !== 'object') {
122
116
  throw new Error('results must be an object');
123
117
  }
124
- if (
125
- processData.childProcesses &&
126
- !Array.isArray(processData.childProcesses)
127
- ) {
118
+ if (processData.childProcesses && !Array.isArray(processData.childProcesses)) {
128
119
  throw new Error('childProcesses must be an array');
129
120
  }
130
- if (
131
- processData.parentProcessId &&
132
- typeof processData.parentProcessId !== 'string'
133
- ) {
121
+ if (processData.parentProcessId && typeof processData.parentProcessId !== 'string') {
134
122
  throw new Error('parentProcessId must be a string');
135
123
  }
136
124
  }
137
125
  }
138
126
 
139
127
  module.exports = { CreateProcess };
128
+
@@ -59,11 +59,10 @@ class DeleteIntegrationForUser {
59
59
 
60
60
  for (const entityId of integrationRecord.entitiesIds) {
61
61
  try {
62
- const moduleInstance =
63
- await this.moduleFactory.getModuleInstance(
64
- entityId,
65
- integrationRecord.userId
66
- );
62
+ const moduleInstance = await this.moduleFactory.getModuleInstance(
63
+ entityId,
64
+ integrationRecord.userId
65
+ );
67
66
  modules.push(moduleInstance);
68
67
  } catch (error) {
69
68
  console.error(
@@ -1,7 +1,5 @@
1
1
  // Removed Integration wrapper - using IntegrationBase directly
2
- const {
3
- mapIntegrationClassToIntegrationDTO,
4
- } = require('../utils/map-integration-dto');
2
+ const { mapIntegrationClassToIntegrationDTO } = require('../utils/map-integration-dto');
5
3
  const Boom = require('@hapi/boom');
6
4
 
7
5
  /**
@@ -17,12 +15,8 @@ class GetIntegrationForUser {
17
15
  * @param {import('../../modules/module-factory').ModuleFactory} params.moduleFactory - Service for module instantiation and management.
18
16
  * @param {import('../../modules/module-repository-interface').ModuleRepositoryInterface} params.moduleRepository - Repository for module and entity data operations.
19
17
  */
20
- constructor({
21
- integrationRepository,
22
- integrationClasses,
23
- moduleFactory,
24
- moduleRepository,
25
- }) {
18
+ constructor({ integrationRepository, integrationClasses, moduleFactory, moduleRepository }) {
19
+
26
20
  /**
27
21
  * @type {import('../integration-repository-interface').IntegrationRepositoryInterface}
28
22
  */
@@ -42,28 +36,19 @@ class GetIntegrationForUser {
42
36
  * @throws {Boom.forbidden} When user does not have access to the integration.
43
37
  */
44
38
  async execute(integrationId, userId) {
45
- const integrationRecord =
46
- await this.integrationRepository.findIntegrationById(integrationId);
47
- const entities = await this.moduleRepository.findEntitiesByIds(
48
- integrationRecord.entitiesIds
49
- );
39
+ const integrationRecord = await this.integrationRepository.findIntegrationById(integrationId);
40
+ const entities = await this.moduleRepository.findEntitiesByIds(integrationRecord.entitiesIds);
50
41
 
51
42
  if (!integrationRecord) {
52
- throw Boom.notFound(
53
- `Integration with id of ${integrationId} does not exist`
54
- );
43
+ throw Boom.notFound(`Integration with id of ${integrationId} does not exist`);
55
44
  }
56
45
 
57
46
  if (integrationRecord.userId.toString() !== userId.toString()) {
58
- throw Boom.forbidden(
59
- 'User does not have access to this integration'
60
- );
47
+ throw Boom.forbidden('User does not have access to this integration');
61
48
  }
62
49
 
63
50
  const integrationClass = this.integrationClasses.find(
64
- (integrationClass) =>
65
- integrationClass.Definition.name ===
66
- integrationRecord.config.type
51
+ (integrationClass) => integrationClass.Definition.name === integrationRecord.config.type
67
52
  );
68
53
 
69
54
  const modules = [];
@@ -83,11 +68,11 @@ class GetIntegrationForUser {
83
68
  status: integrationRecord.status,
84
69
  version: integrationRecord.version,
85
70
  messages: integrationRecord.messages,
86
- modules,
71
+ modules
87
72
  });
88
73
 
89
74
  return mapIntegrationClassToIntegrationDTO(integrationInstance);
90
75
  }
91
76
  }
92
77
 
93
- module.exports = { GetIntegrationForUser };
78
+ module.exports = { GetIntegrationForUser };
@@ -14,6 +14,7 @@ class GetIntegrationInstanceByDefinition {
14
14
  * @param {import('../../modules/module-repository-interface').ModuleRepositoryInterface} params.moduleRepository - Repository for module and entity data operations.
15
15
  */
16
16
  constructor({ integrationRepository, moduleFactory, moduleRepository }) {
17
+
17
18
  /**
18
19
  * @type {import('../integration-repository-interface').IntegrationRepositoryInterface}
19
20
  */
@@ -29,20 +30,13 @@ class GetIntegrationInstanceByDefinition {
29
30
  * @throws {Boom.notFound} When integration with the specified definition does not exist.
30
31
  */
31
32
  async execute(integrationClass) {
32
- const integrationRecord =
33
- await this.integrationRepository.findIntegrationByName(
34
- integrationClass.Definition.name
35
- );
33
+ const integrationRecord = await this.integrationRepository.findIntegrationByName(integrationClass.Definition.name);
36
34
 
37
35
  if (!integrationRecord) {
38
- throw Boom.notFound(
39
- `Integration with name of ${integrationClass.Definition.name} does not exist`
40
- );
36
+ throw Boom.notFound(`Integration with name of ${integrationClass.Definition.name} does not exist`);
41
37
  }
42
38
 
43
- const entities = await this.moduleRepository.findEntitiesByIds(
44
- integrationRecord.entitiesIds
45
- );
39
+ const entities = await this.moduleRepository.findEntitiesByIds(integrationRecord.entitiesIds);
46
40
 
47
41
  const modules = [];
48
42
  for (const entity of entities) {
@@ -61,13 +55,13 @@ class GetIntegrationInstanceByDefinition {
61
55
  status: integrationRecord.status,
62
56
  version: integrationRecord.version,
63
57
  messages: integrationRecord.messages,
64
- modules,
58
+ modules
65
59
  });
66
60
 
67
61
  await integrationInstance.initialize();
68
62
 
69
- return integrationInstance;
63
+ return integrationInstance
70
64
  }
71
65
  }
72
66
 
73
- module.exports = { GetIntegrationInstanceByDefinition };
67
+ module.exports = { GetIntegrationInstanceByDefinition };
@@ -71,10 +71,7 @@ class GetIntegrationsForUser {
71
71
  config: integrationRecord.config,
72
72
  status: integrationRecord.status,
73
73
  version: integrationRecord.version,
74
- messages: integrationRecord.messages || {
75
- errors: [],
76
- warnings: [],
77
- },
74
+ messages: integrationRecord.messages || { errors: [], warnings: [] },
78
75
  modules,
79
76
  options: integrationClass.getOptionDetails(),
80
77
  };
@@ -24,4 +24,4 @@ class GetPossibleIntegrations {
24
24
  }
25
25
  }
26
26
 
27
- module.exports = { GetPossibleIntegrations };
27
+ module.exports = { GetPossibleIntegrations };
@@ -1,14 +1,14 @@
1
1
  /**
2
2
  * GetProcess Use Case
3
- *
3
+ *
4
4
  * Retrieves a process by ID with proper error handling.
5
5
  * Simple use case that delegates to repository.
6
- *
6
+ *
7
7
  * Design Philosophy:
8
8
  * - Use cases provide consistent error handling
9
9
  * - Business logic layer between controllers and repositories
10
10
  * - Return null for not found vs throwing error (configurable)
11
- *
11
+ *
12
12
  * @example
13
13
  * const getProcess = new GetProcess({ processRepository });
14
14
  * const process = await getProcess.execute(processId);
@@ -75,12 +75,13 @@ class GetProcess {
75
75
  }
76
76
 
77
77
  const processes = await Promise.all(
78
- processIds.map((id) => this.execute(id))
78
+ processIds.map(id => this.execute(id))
79
79
  );
80
80
 
81
81
  // Filter out nulls (not found)
82
- return processes.filter((p) => p !== null);
82
+ return processes.filter(p => p !== null);
83
83
  }
84
84
  }
85
85
 
86
86
  module.exports = { GetProcess };
87
+
@@ -6,7 +6,6 @@ const { CreateProcess } = require('./create-process');
6
6
  const { UpdateProcessState } = require('./update-process-state');
7
7
  const { UpdateProcessMetrics } = require('./update-process-metrics');
8
8
  const { GetProcess } = require('./get-process');
9
- const { ExecuteProxyRequest } = require('./execute-proxy-request');
10
9
 
11
10
  module.exports = {
12
11
  GetIntegrationsForUser,
@@ -17,5 +16,4 @@ module.exports = {
17
16
  UpdateProcessState,
18
17
  UpdateProcessMetrics,
19
18
  GetProcess,
20
- ExecuteProxyRequest,
21
- };
19
+ };
@@ -1,5 +1,9 @@
1
1
  class LoadIntegrationContextUseCase {
2
- constructor({ integrationRepository, moduleRepository, moduleFactory }) {
2
+ constructor({
3
+ integrationRepository,
4
+ moduleRepository,
5
+ moduleFactory,
6
+ }) {
3
7
  if (!integrationRepository) {
4
8
  throw new Error('integrationRepository is required');
5
9
  }
@@ -1,20 +1,20 @@
1
1
  /**
2
2
  * UpdateProcessState Use Case
3
- *
3
+ *
4
4
  * Updates the state of a process and optionally merges context updates.
5
5
  * Handles state transitions in the process state machine.
6
- *
6
+ *
7
7
  * Design Philosophy:
8
8
  * - State transitions are explicit and tracked
9
9
  * - Context updates are merged (not replaced) to preserve data
10
10
  * - Repository handles persistence, use case handles business logic
11
- *
11
+ *
12
12
  * State Machine (CRM Sync Example):
13
- * INITIALIZING → FETCHING_TOTAL → QUEUING_PAGES → PROCESSING_BATCHES →
13
+ * INITIALIZING → FETCHING_TOTAL → QUEUING_PAGES → PROCESSING_BATCHES →
14
14
  * COMPLETING → COMPLETED
15
- *
15
+ *
16
16
  * Any state can transition to ERROR on failure.
17
- *
17
+ *
18
18
  * @example
19
19
  * const updateProcessState = new UpdateProcessState({ processRepository });
20
20
  * await updateProcessState.execute(processId, 'FETCHING_TOTAL', {
@@ -75,10 +75,7 @@ class UpdateProcessState {
75
75
 
76
76
  // Persist updates
77
77
  try {
78
- const updatedProcess = await this.processRepository.update(
79
- processId,
80
- updates
81
- );
78
+ const updatedProcess = await this.processRepository.update(processId, updates);
82
79
  return updatedProcess;
83
80
  } catch (error) {
84
81
  throw new Error(`Failed to update process state: ${error.message}`);
@@ -119,3 +116,4 @@ class UpdateProcessState {
119
116
  }
120
117
 
121
118
  module.exports = { UpdateProcessState };
119
+
@@ -15,14 +15,11 @@ function mapIntegrationClassToIntegrationDTO(integration) {
15
15
  version: integration.version,
16
16
  messages: integration.messages,
17
17
  userActions: integration.userActions,
18
- options:
19
- integration.options ||
20
- (typeof integration.getOptionDetails === 'function'
21
- ? integration.getOptionDetails()
22
- : null),
18
+ options: integration.options || (typeof integration.getOptionDetails === 'function' ? integration.getOptionDetails() : null),
23
19
  };
24
20
  }
25
21
 
22
+
26
23
  const getModulesDefinitionFromIntegrationClasses = (integrationClasses) => {
27
24
  return [
28
25
  ...new Set(
@@ -37,7 +34,4 @@ const getModulesDefinitionFromIntegrationClasses = (integrationClasses) => {
37
34
  ];
38
35
  };
39
36
 
40
- module.exports = {
41
- mapIntegrationClassToIntegrationDTO,
42
- getModulesDefinitionFromIntegrationClasses,
43
- };
37
+ module.exports = { mapIntegrationClassToIntegrationDTO, getModulesDefinitionFromIntegrationClasses };
package/jest-setup.js CHANGED
@@ -1,2 +1,2 @@
1
- const { globalSetup } = require('@friggframework/test');
1
+ const {globalSetup} = require('@friggframework/test');
2
2
  module.exports = globalSetup;
package/jest-teardown.js CHANGED
@@ -1,2 +1,2 @@
1
- const { globalTeardown } = require('@friggframework/test');
1
+ const {globalTeardown} = require('@friggframework/test');
2
2
  module.exports = globalTeardown;
@@ -2,44 +2,42 @@ const isPositive = (n) => Number.isFinite(n) && n > 0;
2
2
  const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
3
3
 
4
4
  class TimeoutCatcher {
5
- constructor({ work, timeout, cleanUp = () => {}, cleanUpTime = 2_000 }) {
6
- this.isFinished = false;
7
- this.work = work;
8
- this.cleanUp = cleanUp;
9
- this.waitTime = timeout - cleanUpTime;
10
-
11
- if (!isPositive(this.waitTime))
12
- throw new Error(
13
- 'Wait time was not a positive number of milliseconds'
14
- );
5
+ constructor({ work, timeout, cleanUp = () => {}, cleanUpTime = 2_000 }) {
6
+ this.isFinished = false;
7
+ this.work = work;
8
+ this.cleanUp = cleanUp;
9
+ this.waitTime = timeout - cleanUpTime;
10
+
11
+ if (!isPositive(this.waitTime))
12
+ throw new Error("Wait time was not a positive number of milliseconds");
13
+ }
14
+
15
+ async watch() {
16
+ try {
17
+ await Promise.race([this.doWork(), this.exitBeforeTimeout()]);
18
+ return true;
19
+ } catch (error) {
20
+ if (error.isSentinelTimeout) return false;
21
+ throw error;
15
22
  }
23
+ }
16
24
 
17
- async watch() {
18
- try {
19
- await Promise.race([this.doWork(), this.exitBeforeTimeout()]);
20
- return true;
21
- } catch (error) {
22
- if (error.isSentinelTimeout) return false;
23
- throw error;
24
- }
25
- }
26
-
27
- async doWork() {
28
- await this.work();
29
- this.isFinished = true;
30
- }
25
+ async doWork() {
26
+ await this.work();
27
+ this.isFinished = true;
28
+ }
31
29
 
32
- async exitBeforeTimeout() {
33
- await sleep(this.waitTime);
30
+ async exitBeforeTimeout() {
31
+ await sleep(this.waitTime);
34
32
 
35
- if (!this.isFinished) {
36
- await this.cleanUp();
33
+ if (!this.isFinished) {
34
+ await this.cleanUp();
37
35
 
38
- const error = new Error('Sentinel Timed Out');
39
- error.isSentinelTimeout = true;
40
- throw error;
41
- }
36
+ const error = new Error("Sentinel Timed Out");
37
+ error.isSentinelTimeout = true;
38
+ throw error;
42
39
  }
40
+ }
43
41
  }
44
42
 
45
43
  module.exports = { TimeoutCatcher };
package/lambda/index.js CHANGED
@@ -1,3 +1,3 @@
1
1
  const { TimeoutCatcher } = require('./TimeoutCatcher');
2
2
 
3
- module.exports = { TimeoutCatcher };
3
+ module.exports = { TimeoutCatcher }
package/logs/index.js CHANGED
@@ -1,7 +1,7 @@
1
- const { debug, initDebugLog, flushDebugLog } = require('./logger');
1
+ const {debug, initDebugLog, flushDebugLog} = require('./logger');
2
2
 
3
3
  module.exports = {
4
4
  debug,
5
5
  initDebugLog,
6
- flushDebugLog,
7
- };
6
+ flushDebugLog
7
+ }