@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
@@ -4,8 +4,11 @@ const { get } = require('../assertions');
4
4
  class Options {
5
5
  constructor(params) {
6
6
  this.module = get(params, 'module');
7
- this.modules = params.modules || {}; // Store modules for requiredEntities extraction
7
+ this.isMany = Boolean(get(params, 'isMany', false));
8
8
  this.hasUserConfig = Boolean(get(params, 'hasUserConfig', false));
9
+ this.requiresNewEntity = Boolean(
10
+ get(params, 'requiresNewEntity', false)
11
+ );
9
12
  if (!params.display) {
10
13
  throw new RequiredPropertyError({
11
14
  parent: this,
@@ -14,66 +17,36 @@ class Options {
14
17
  }
15
18
 
16
19
  this.display = {};
17
- // Required fields
18
20
  this.display.name = get(params.display, 'label');
19
21
  this.display.description = get(params.display, 'description');
20
- // Optional fields - use defaults if not provided
21
- this.display.detailsUrl = params.display.detailsUrl || null;
22
- this.display.icon = params.display.icon || null;
22
+ this.display.detailsUrl = get(params.display, 'detailsUrl');
23
+ this.display.icon = get(params.display, 'icon');
23
24
  }
24
25
 
25
26
  get() {
26
- // Extract module names from the modules object to determine required entities
27
- const requiredEntities = this.modules ? Object.keys(this.modules) : [];
28
-
29
- // Get module type name - handle both getName() method and moduleName property
30
- const moduleType = this._getModuleTypeName();
31
-
32
27
  return {
33
- type: moduleType,
28
+ type: this.module.definition.getName(),
34
29
 
35
30
  // Flag for if the User can configure any settings
36
31
  hasUserConfig: this.hasUserConfig,
37
32
 
38
- // Array of module/entity type names required for this integration (e.g., ['nagaris', 'creditorwatch'])
39
- // UI uses this to check if user has connected the necessary accounts before creating integration
40
- requiredEntities: requiredEntities,
33
+ // if this integration can be used multiple times with the same integration pair. For example I want to
34
+ // connect two different Etsy shops to the same Freshbooks account.
35
+ isMany: this.isMany,
36
+
37
+ // if this is true it means we need to create a new entity for every integration pair and not use an
38
+ // existing one. This would be true for scenarios where the client wishes to have individual control over
39
+ // the integerations it has connected to its app. They would want this to let their users only delete
40
+ // single integrations without notifying our server.
41
+ requiresNewEntity: this.requiresNewEntity,
41
42
 
42
43
  // this is information required for the display side of things on the front end
43
44
  display: this.display,
44
- };
45
- }
46
-
47
- /**
48
- * Get the module type name from the module definition.
49
- * Supports both:
50
- * - getName() method (standard Frigg API modules)
51
- * - moduleName property (custom API modules)
52
- * @returns {string} The module type name
53
- * @private
54
- */
55
- _getModuleTypeName() {
56
- const definition = this.module?.definition;
57
- if (!definition) {
58
- return 'unknown';
59
- }
60
45
 
61
- // Try getName() method first (standard pattern)
62
- if (typeof definition.getName === 'function') {
63
- return definition.getName();
64
- }
65
-
66
- // Fall back to moduleName property
67
- if (definition.moduleName) {
68
- return definition.moduleName;
69
- }
70
-
71
- // Last resort - try name property
72
- if (definition.name) {
73
- return definition.name;
74
- }
75
-
76
- return 'unknown';
46
+ // this is information for post-authentication config, using jsonSchema and uiSchema for display on the frontend
47
+ // Maybe include but probably not, I like making someone make a follow-on request
48
+ // configOptions: this.configOptions,
49
+ };
77
50
  }
78
51
  }
79
52
 
@@ -29,17 +29,13 @@ class IntegrationRepositoryDocumentDB extends IntegrationRepositoryInterface {
29
29
  async deleteIntegrationById(integrationId) {
30
30
  const objectId = toObjectId(integrationId);
31
31
  if (!objectId) return { acknowledged: true, deletedCount: 0 };
32
- const result = await deleteOne(this.prisma, 'Integration', {
33
- _id: objectId,
34
- });
32
+ const result = await deleteOne(this.prisma, 'Integration', { _id: objectId });
35
33
  const deleted = result?.n ?? 0;
36
34
  return { acknowledged: true, deletedCount: deleted };
37
35
  }
38
36
 
39
37
  async findIntegrationByName(name) {
40
- const doc = await findOne(this.prisma, 'Integration', {
41
- 'config.type': name,
42
- });
38
+ const doc = await findOne(this.prisma, 'Integration', { 'config.type': name });
43
39
  if (!doc) {
44
40
  throw new Error(`Integration with name ${name} not found`);
45
41
  }
@@ -51,9 +47,7 @@ class IntegrationRepositoryDocumentDB extends IntegrationRepositoryInterface {
51
47
  if (!objectId) {
52
48
  throw new Error(`Integration with id ${id} not found`);
53
49
  }
54
- const doc = await findOne(this.prisma, 'Integration', {
55
- _id: objectId,
56
- });
50
+ const doc = await findOne(this.prisma, 'Integration', { _id: objectId });
57
51
  if (!doc) {
58
52
  throw new Error(`Integration with id ${id} not found`);
59
53
  }
@@ -85,16 +79,12 @@ class IntegrationRepositoryDocumentDB extends IntegrationRepositoryInterface {
85
79
  if (!objectId) {
86
80
  throw new Error(`Integration ${integrationId} not found`);
87
81
  }
88
- const existing = await findOne(this.prisma, 'Integration', {
89
- _id: objectId,
90
- });
82
+ const existing = await findOne(this.prisma, 'Integration', { _id: objectId });
91
83
  if (!existing) {
92
84
  throw new Error(`Integration ${integrationId} not found`);
93
85
  }
94
86
  const messages = this._extractMessages(existing);
95
- const list = Array.isArray(messages[messageType])
96
- ? [...messages[messageType]]
97
- : [];
87
+ const list = Array.isArray(messages[messageType]) ? [...messages[messageType]] : [];
98
88
  list.push({
99
89
  title: messageTitle ?? null,
100
90
  message: messageBody,
@@ -135,26 +125,17 @@ class IntegrationRepositoryDocumentDB extends IntegrationRepositoryInterface {
135
125
  createdAt: now,
136
126
  updatedAt: now,
137
127
  };
138
- const insertedId = await insertOne(
139
- this.prisma,
140
- 'Integration',
141
- document
142
- );
143
- const created = await findOne(this.prisma, 'Integration', {
144
- _id: insertedId,
145
- });
128
+ const insertedId = await insertOne(this.prisma, 'Integration', document);
129
+ const created = await findOne(this.prisma, 'Integration', { _id: insertedId });
146
130
  if (!created) {
147
- console.error(
148
- '[IntegrationRepositoryDocumentDB] Integration not found after insert',
149
- {
150
- insertedId: fromObjectId(insertedId),
151
- userId,
152
- config,
153
- }
154
- );
131
+ console.error('[IntegrationRepositoryDocumentDB] Integration not found after insert', {
132
+ insertedId: fromObjectId(insertedId),
133
+ userId,
134
+ config,
135
+ });
155
136
  throw new Error(
156
137
  'Failed to create integration: Document not found after insert. ' +
157
- 'This indicates a database consistency issue.'
138
+ 'This indicates a database consistency issue.'
158
139
  );
159
140
  }
160
141
  return this._mapIntegration(created);
@@ -163,9 +144,7 @@ class IntegrationRepositoryDocumentDB extends IntegrationRepositoryInterface {
163
144
  async findIntegrationByUserId(userId) {
164
145
  const objectId = toObjectId(userId);
165
146
  if (!objectId) return null;
166
- const doc = await findOne(this.prisma, 'Integration', {
167
- userId: objectId,
168
- });
147
+ const doc = await findOne(this.prisma, 'Integration', { userId: objectId });
169
148
  return doc ? this._mapIntegration(doc) : null;
170
149
  }
171
150
 
@@ -188,20 +167,15 @@ class IntegrationRepositoryDocumentDB extends IntegrationRepositoryInterface {
188
167
  },
189
168
  }
190
169
  );
191
- const updated = await findOne(this.prisma, 'Integration', {
192
- _id: objectId,
193
- });
170
+ const updated = await findOne(this.prisma, 'Integration', { _id: objectId });
194
171
  if (!updated) {
195
- console.error(
196
- '[IntegrationRepositoryDocumentDB] Integration not found after update',
197
- {
198
- integrationId: fromObjectId(objectId),
199
- config,
200
- }
201
- );
172
+ console.error('[IntegrationRepositoryDocumentDB] Integration not found after update', {
173
+ integrationId: fromObjectId(objectId),
174
+ config,
175
+ });
202
176
  throw new Error(
203
177
  'Failed to update integration: Document not found after update. ' +
204
- 'This indicates a database consistency issue.'
178
+ 'This indicates a database consistency issue.'
205
179
  );
206
180
  }
207
181
  return this._mapIntegration(updated);
@@ -211,9 +185,7 @@ class IntegrationRepositoryDocumentDB extends IntegrationRepositoryInterface {
211
185
  const messages = this._extractMessages(doc);
212
186
  return {
213
187
  id: fromObjectId(doc?._id),
214
- entitiesIds: (doc?.entityIds || []).map((value) =>
215
- fromObjectId(value)
216
- ),
188
+ entitiesIds: (doc?.entityIds || []).map((value) => fromObjectId(value)),
217
189
  userId: fromObjectId(doc?.userId),
218
190
  config: doc?.config ?? null,
219
191
  version: doc?.version ?? null,
@@ -223,10 +195,7 @@ class IntegrationRepositoryDocumentDB extends IntegrationRepositoryInterface {
223
195
  }
224
196
 
225
197
  _extractMessages(doc) {
226
- const base =
227
- doc?.messages && typeof doc.messages === 'object'
228
- ? doc.messages
229
- : {};
198
+ const base = doc?.messages && typeof doc.messages === 'object' ? doc.messages : {};
230
199
  return {
231
200
  errors: base.errors ?? doc?.errors ?? [],
232
201
  warnings: base.warnings ?? doc?.warnings ?? [],
@@ -237,3 +206,5 @@ class IntegrationRepositoryDocumentDB extends IntegrationRepositoryInterface {
237
206
  }
238
207
 
239
208
  module.exports = { IntegrationRepositoryDocumentDB };
209
+
210
+
@@ -1,9 +1,5 @@
1
- const {
2
- IntegrationRepositoryMongo,
3
- } = require('./integration-repository-mongo');
4
- const {
5
- IntegrationRepositoryPostgres,
6
- } = require('./integration-repository-postgres');
1
+ const { IntegrationRepositoryMongo } = require('./integration-repository-mongo');
2
+ const { IntegrationRepositoryPostgres } = require('./integration-repository-postgres');
7
3
  const {
8
4
  IntegrationRepositoryDocumentDB,
9
5
  } = require('./integration-repository-documentdb');
@@ -18,9 +18,7 @@ class IntegrationRepositoryInterface {
18
18
  * @abstract
19
19
  */
20
20
  async findIntegrationsByUserId(userId) {
21
- throw new Error(
22
- 'Method findIntegrationsByUserId must be implemented by subclass'
23
- );
21
+ throw new Error('Method findIntegrationsByUserId must be implemented by subclass');
24
22
  }
25
23
 
26
24
  /**
@@ -31,9 +29,7 @@ class IntegrationRepositoryInterface {
31
29
  * @abstract
32
30
  */
33
31
  async deleteIntegrationById(integrationId) {
34
- throw new Error(
35
- 'Method deleteIntegrationById must be implemented by subclass'
36
- );
32
+ throw new Error('Method deleteIntegrationById must be implemented by subclass');
37
33
  }
38
34
 
39
35
  /**
@@ -44,9 +40,7 @@ class IntegrationRepositoryInterface {
44
40
  * @abstract
45
41
  */
46
42
  async findIntegrationByName(name) {
47
- throw new Error(
48
- 'Method findIntegrationByName must be implemented by subclass'
49
- );
43
+ throw new Error('Method findIntegrationByName must be implemented by subclass');
50
44
  }
51
45
 
52
46
  /**
@@ -57,9 +51,7 @@ class IntegrationRepositoryInterface {
57
51
  * @abstract
58
52
  */
59
53
  async findIntegrationById(id) {
60
- throw new Error(
61
- 'Method findIntegrationById must be implemented by subclass'
62
- );
54
+ throw new Error('Method findIntegrationById must be implemented by subclass');
63
55
  }
64
56
 
65
57
  /**
@@ -71,9 +63,7 @@ class IntegrationRepositoryInterface {
71
63
  * @abstract
72
64
  */
73
65
  async updateIntegrationStatus(integrationId, status) {
74
- throw new Error(
75
- 'Method updateIntegrationStatus must be implemented by subclass'
76
- );
66
+ throw new Error('Method updateIntegrationStatus must be implemented by subclass');
77
67
  }
78
68
 
79
69
  /**
@@ -94,9 +84,7 @@ class IntegrationRepositoryInterface {
94
84
  messageBody,
95
85
  messageTimestamp
96
86
  ) {
97
- throw new Error(
98
- 'Method updateIntegrationMessages must be implemented by subclass'
99
- );
87
+ throw new Error('Method updateIntegrationMessages must be implemented by subclass');
100
88
  }
101
89
 
102
90
  /**
@@ -109,9 +97,7 @@ class IntegrationRepositoryInterface {
109
97
  * @abstract
110
98
  */
111
99
  async createIntegration(entities, userId, config) {
112
- throw new Error(
113
- 'Method createIntegration must be implemented by subclass'
114
- );
100
+ throw new Error('Method createIntegration must be implemented by subclass');
115
101
  }
116
102
 
117
103
  /**
@@ -122,9 +108,7 @@ class IntegrationRepositoryInterface {
122
108
  * @abstract
123
109
  */
124
110
  async findIntegrationByUserId(userId) {
125
- throw new Error(
126
- 'Method findIntegrationByUserId must be implemented by subclass'
127
- );
111
+ throw new Error('Method findIntegrationByUserId must be implemented by subclass');
128
112
  }
129
113
 
130
114
  /**
@@ -136,9 +120,7 @@ class IntegrationRepositoryInterface {
136
120
  * @abstract
137
121
  */
138
122
  async updateIntegrationConfig(integrationId, config) {
139
- throw new Error(
140
- 'Method updateIntegrationConfig must be implemented by subclass'
141
- );
123
+ throw new Error('Method updateIntegrationConfig must be implemented by subclass');
142
124
  }
143
125
  }
144
126
 
@@ -49,12 +49,12 @@ class IntegrationRepositoryPostgres extends IntegrationRepositoryInterface {
49
49
  ...integration,
50
50
  id: integration.id?.toString(),
51
51
  userId: integration.userId?.toString(),
52
- entities: integration.entities?.map((e) => ({
52
+ entities: integration.entities?.map(e => ({
53
53
  ...e,
54
54
  id: e.id?.toString(),
55
55
  userId: e.userId?.toString(),
56
- credentialId: e.credentialId?.toString(),
57
- })),
56
+ credentialId: e.credentialId?.toString()
57
+ }))
58
58
  };
59
59
  }
60
60
 
@@ -50,3 +50,4 @@ module.exports = {
50
50
  ProcessRepositoryPostgres,
51
51
  ProcessRepositoryDocumentDB,
52
52
  };
53
+
@@ -1,9 +1,9 @@
1
1
  /**
2
2
  * ProcessRepository Interface
3
- *
3
+ *
4
4
  * Defines the contract for Process data access operations.
5
5
  * Implementations must provide concrete methods for all operations.
6
- *
6
+ *
7
7
  * This interface supports the Hexagonal Architecture pattern by:
8
8
  * - Defining clear boundaries between domain logic and data access
9
9
  * - Allowing multiple implementations (MongoDB, PostgreSQL, in-memory)
@@ -54,9 +54,7 @@ class ProcessRepositoryInterface {
54
54
  * @returns {Promise<Array>} Array of process records
55
55
  */
56
56
  async findByIntegrationAndType(integrationId, type) {
57
- throw new Error(
58
- 'Method findByIntegrationAndType() must be implemented'
59
- );
57
+ throw new Error('Method findByIntegrationAndType() must be implemented');
60
58
  }
61
59
 
62
60
  /**
@@ -65,10 +63,7 @@ class ProcessRepositoryInterface {
65
63
  * @param {string[]} [excludeStates=['COMPLETED', 'ERROR']] - States to exclude
66
64
  * @returns {Promise<Array>} Array of active process records
67
65
  */
68
- async findActiveProcesses(
69
- integrationId,
70
- excludeStates = ['COMPLETED', 'ERROR']
71
- ) {
66
+ async findActiveProcesses(integrationId, excludeStates = ['COMPLETED', 'ERROR']) {
72
67
  throw new Error('Method findActiveProcesses() must be implemented');
73
68
  }
74
69
 
@@ -92,3 +87,4 @@ class ProcessRepositoryInterface {
92
87
  }
93
88
 
94
89
  module.exports = { ProcessRepositoryInterface };
90
+
@@ -1,7 +1,5 @@
1
1
  const { prisma } = require('../../database/prisma');
2
- const {
3
- ProcessRepositoryInterface,
4
- } = require('./process-repository-interface');
2
+ const { ProcessRepositoryInterface } = require('./process-repository-interface');
5
3
 
6
4
  /**
7
5
  * MongoDB Process Repository Adapter
@@ -120,10 +118,7 @@ class ProcessRepositoryMongo extends ProcessRepositoryInterface {
120
118
  * @param {string[]} [excludeStates=['COMPLETED', 'ERROR']] - States to exclude
121
119
  * @returns {Promise<Array>} Array of active process records
122
120
  */
123
- async findActiveProcesses(
124
- integrationId,
125
- excludeStates = ['COMPLETED', 'ERROR']
126
- ) {
121
+ async findActiveProcesses(integrationId, excludeStates = ['COMPLETED', 'ERROR']) {
127
122
  const processes = await this.prisma.process.findMany({
128
123
  where: {
129
124
  integrationId,
@@ -192,3 +187,4 @@ class ProcessRepositoryMongo extends ProcessRepositoryInterface {
192
187
  }
193
188
 
194
189
  module.exports = { ProcessRepositoryMongo };
190
+
@@ -199,8 +199,8 @@ class ProcessRepositoryPostgres extends ProcessRepositoryInterface {
199
199
  results: process.results,
200
200
  childProcesses: Array.isArray(process.childProcesses)
201
201
  ? process.childProcesses.length > 0 &&
202
- typeof process.childProcesses[0] === 'object' &&
203
- process.childProcesses[0] !== null
202
+ typeof process.childProcesses[0] === 'object' &&
203
+ process.childProcesses[0] !== null
204
204
  ? process.childProcesses.map((child) => String(child.id))
205
205
  : process.childProcesses
206
206
  : [],
@@ -2,7 +2,7 @@ const { IntegrationBase } = require('../../integration-base');
2
2
 
3
3
  class ConfigCapturingModule {
4
4
  static definition = {
5
- getName: () => 'config-capturing-module',
5
+ getName: () => 'config-capturing-module'
6
6
  };
7
7
  }
8
8
 
@@ -11,15 +11,14 @@ class ConfigCapturingIntegration extends IntegrationBase {
11
11
  name: 'config-capturing',
12
12
  version: '1.0.0',
13
13
  modules: {
14
- primary: ConfigCapturingModule,
14
+ primary: ConfigCapturingModule
15
15
  },
16
16
  display: {
17
17
  label: 'Config Capturing Integration',
18
- description:
19
- 'Test double for capturing config state during updates',
18
+ description: 'Test double for capturing config state during updates',
20
19
  detailsUrl: 'https://example.com',
21
- icon: 'test-icon',
22
- },
20
+ icon: 'test-icon'
21
+ }
23
22
  };
24
23
 
25
24
  static _capturedOnUpdateState = null;
@@ -39,10 +38,10 @@ class ConfigCapturingIntegration extends IntegrationBase {
39
38
  findIntegrationById: jest.fn().mockResolvedValue({}),
40
39
  };
41
40
  this.updateIntegrationStatus = {
42
- execute: jest.fn().mockResolvedValue({}),
41
+ execute: jest.fn().mockResolvedValue({})
43
42
  };
44
43
  this.updateIntegrationMessages = {
45
- execute: jest.fn().mockResolvedValue({}),
44
+ execute: jest.fn().mockResolvedValue({})
46
45
  };
47
46
  }
48
47
 
@@ -53,7 +52,7 @@ class ConfigCapturingIntegration extends IntegrationBase {
53
52
  async onUpdate(params) {
54
53
  ConfigCapturingIntegration._capturedOnUpdateState = {
55
54
  thisConfig: JSON.parse(JSON.stringify(this.config)),
56
- paramsConfig: params.config,
55
+ paramsConfig: params.config
57
56
  };
58
57
 
59
58
  this.config = this._deepMerge(this.config, params.config);
@@ -1,9 +1,8 @@
1
1
  const { IntegrationBase } = require('../../integration-base');
2
- const { Options } = require('../../options');
3
2
 
4
3
  class DummyModule {
5
4
  static definition = {
6
- getName: () => 'dummy',
5
+ getName: () => 'dummy'
7
6
  };
8
7
  }
9
8
 
@@ -12,25 +11,21 @@ class DummyIntegration extends IntegrationBase {
12
11
  name: 'dummy',
13
12
  version: '1.0.0',
14
13
  modules: {
15
- dummy: DummyModule,
14
+ dummy: DummyModule
16
15
  },
17
16
  display: {
18
17
  label: 'Dummy Integration',
19
18
  description: 'A dummy integration for testing',
20
19
  detailsUrl: 'https://example.com',
21
- icon: 'dummy-icon',
22
- },
20
+ icon: 'dummy-icon'
21
+ }
23
22
  };
24
23
 
25
24
  static getOptionDetails() {
26
- const options = new Options({
27
- module: Object.values(this.Definition.modules)[0],
28
- ...this.Definition,
29
- });
30
25
  return {
31
26
  name: this.Definition.name,
32
27
  version: this.Definition.version,
33
- ...options.get(),
28
+ display: this.Definition.display
34
29
  };
35
30
  }
36
31
 
@@ -46,11 +41,11 @@ class DummyIntegration extends IntegrationBase {
46
41
  };
47
42
 
48
43
  this.updateIntegrationStatus = {
49
- execute: jest.fn().mockResolvedValue({}),
44
+ execute: jest.fn().mockResolvedValue({})
50
45
  };
51
46
 
52
47
  this.updateIntegrationMessages = {
53
- execute: jest.fn().mockResolvedValue({}),
48
+ execute: jest.fn().mockResolvedValue({})
54
49
  };
55
50
  }
56
51
 
@@ -107,72 +102,4 @@ class DummyIntegration extends IntegrationBase {
107
102
  }
108
103
  }
109
104
 
110
- class DummyIntegrationWithGlobalEntity extends IntegrationBase {
111
- static Definition = {
112
- name: 'dummy-with-global',
113
- version: '1.0.0',
114
- modules: { dummy: DummyModule },
115
- display: { label: 'Dummy With Global', description: 'Test' },
116
- entities: {
117
- sharedService: {
118
- type: 'shared-api',
119
- global: true,
120
- required: true,
121
- },
122
- },
123
- };
124
-
125
- constructor(params) {
126
- super(params);
127
- this.sendSpy = jest.fn();
128
- this.integrationRepository = {
129
- updateIntegrationById: jest.fn().mockResolvedValue({}),
130
- findIntegrationById: jest.fn().mockResolvedValue({}),
131
- };
132
- this.updateIntegrationStatus = { execute: jest.fn().mockResolvedValue({}) };
133
- this.updateIntegrationMessages = { execute: jest.fn().mockResolvedValue({}) };
134
- }
135
-
136
- async loadDynamicUserActions() { return {}; }
137
- async send(event, data) { this.sendSpy(event, data); return { event, data }; }
138
- async initialize() { return; }
139
- async onCreate() { return; }
140
- }
141
-
142
- class DummyIntegrationWithOptionalGlobalEntity extends IntegrationBase {
143
- static Definition = {
144
- name: 'dummy-with-optional-global',
145
- version: '1.0.0',
146
- modules: { dummy: DummyModule },
147
- display: { label: 'Dummy With Optional Global', description: 'Test' },
148
- entities: {
149
- optionalService: {
150
- type: 'optional-api',
151
- global: true,
152
- required: false,
153
- },
154
- },
155
- };
156
-
157
- constructor(params) {
158
- super(params);
159
- this.sendSpy = jest.fn();
160
- this.integrationRepository = {
161
- updateIntegrationById: jest.fn().mockResolvedValue({}),
162
- findIntegrationById: jest.fn().mockResolvedValue({}),
163
- };
164
- this.updateIntegrationStatus = { execute: jest.fn().mockResolvedValue({}) };
165
- this.updateIntegrationMessages = { execute: jest.fn().mockResolvedValue({}) };
166
- }
167
-
168
- async loadDynamicUserActions() { return {}; }
169
- async send(event, data) { this.sendSpy(event, data); return { event, data }; }
170
- async initialize() { return; }
171
- async onCreate() { return; }
172
- }
173
-
174
- module.exports = {
175
- DummyIntegration,
176
- DummyIntegrationWithGlobalEntity,
177
- DummyIntegrationWithOptionalGlobalEntity,
178
- };
105
+ module.exports = { DummyIntegration };