@friggframework/core 2.0.0--canary.549.a579cca.0 → 2.0.0--canary.549.6674256.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 (305) hide show
  1. package/assertions/jest.config.ts +7 -0
  2. package/database/jest.config.ts +7 -0
  3. package/database/models/WorkflowExecutionModel.ts +315 -0
  4. package/database/models/WorkflowModel.ts +129 -0
  5. package/jest-global-setup-noop.ts +3 -0
  6. package/jest-global-teardown-noop.ts +3 -0
  7. package/jest-resolver.ts +36 -0
  8. package/jest-setup.ts +2 -0
  9. package/jest-teardown.ts +2 -0
  10. package/jest.config.ts +20 -0
  11. package/package.json +8 -5
  12. package/src/application/commands/integration-commands.test.ts +158 -0
  13. package/src/application/commands/integration-commands.ts +20 -35
  14. package/src/core/Worker.test.ts +158 -0
  15. package/src/database/adapters/lambda-invoker.test.ts +104 -0
  16. package/src/database/encryption/encryption-schema-registry.test.ts +397 -0
  17. package/src/database/encryption/field-encryption-service.test.ts +511 -0
  18. package/src/database/encryption/mongo-decryption-fix-verification.test.ts +337 -0
  19. package/src/database/encryption/postgres-decryption-fix-verification.test.ts +335 -0
  20. package/src/database/encryption/postgres-relation-decryption.test.ts +205 -0
  21. package/src/database/encryption/prisma-encryption-extension.test.ts +433 -0
  22. package/src/database/prisma.test.ts +65 -0
  23. package/src/database/repositories/health-check-repository-mongodb.test.ts +178 -0
  24. package/src/database/repositories/health-check-repository-postgres.test.ts +94 -0
  25. package/src/database/repositories/migration-status-repository-s3.test.ts +150 -0
  26. package/src/database/use-cases/check-database-health-use-case.test.ts +131 -0
  27. package/src/database/use-cases/check-database-state-use-case.test.ts +131 -0
  28. package/src/database/use-cases/check-encryption-health-use-case.test.ts +183 -0
  29. package/src/database/use-cases/get-database-state-via-worker-use-case.test.ts +126 -0
  30. package/src/database/use-cases/get-migration-status-use-case.test.ts +160 -0
  31. package/src/database/use-cases/run-database-migration-use-case.test.ts +350 -0
  32. package/src/database/use-cases/trigger-database-migration-use-case.test.ts +256 -0
  33. package/src/database/utils/mongodb-collection-utils.test.ts +133 -0
  34. package/src/database/utils/mongodb-schema-init.test.ts +152 -0
  35. package/src/database/utils/prisma-runner.test.ts +513 -0
  36. package/src/database/utils/prisma-schema-parser.test.ts +283 -0
  37. package/src/declarations.d.ts +7 -0
  38. package/src/encrypt/Cryptor.test.ts +137 -0
  39. package/src/errors/base-error.test.ts +32 -0
  40. package/src/errors/fetch-error.test.ts +105 -0
  41. package/src/errors/halt-error.test.ts +11 -0
  42. package/src/errors/validation-errors.test.ts +122 -0
  43. package/src/handlers/auth-flow.integration.test.ts +149 -0
  44. package/src/handlers/integration-event-dispatcher.test.ts +211 -0
  45. package/src/handlers/routers/db-migration.test.ts +69 -0
  46. package/src/handlers/routers/health.test.ts +251 -0
  47. package/src/handlers/routers/health.ts +9 -12
  48. package/src/handlers/routers/integration-webhook-routers.test.ts +116 -0
  49. package/src/handlers/use-cases/check-integrations-health-use-case.test.ts +124 -0
  50. package/src/handlers/webhook-flow.integration.test.ts +318 -0
  51. package/src/handlers/workers/db-migration.test.ts +168 -0
  52. package/src/handlers/workers/db-migration.ts +11 -13
  53. package/src/handlers/workers/integration-defined-workers.test.ts +254 -0
  54. package/src/integrations/integration-base.module-keys.test.ts +204 -0
  55. package/{integrations/tests/doubles/config-capturing-integration.js → src/integrations/tests/doubles/config-capturing-integration.ts} +13 -13
  56. package/{integrations/tests/doubles/dummy-integration-class.js → src/integrations/tests/doubles/dummy-integration-class.ts} +21 -17
  57. package/{integrations/tests/doubles/test-integration-repository.js → src/integrations/tests/doubles/test-integration-repository.ts} +14 -13
  58. package/src/integrations/tests/integration-router-multi-auth.test.ts +531 -0
  59. package/src/integrations/tests/use-cases/create-integration.test.ts +131 -0
  60. package/src/integrations/tests/use-cases/delete-integration-for-user.test.ts +150 -0
  61. package/src/integrations/tests/use-cases/find-integration-context-by-external-entity-id.test.ts +92 -0
  62. package/src/integrations/tests/use-cases/get-integration-for-user.test.ts +150 -0
  63. package/src/integrations/tests/use-cases/get-integration-instance.test.ts +176 -0
  64. package/src/integrations/tests/use-cases/get-integrations-for-user.test.ts +176 -0
  65. package/src/integrations/tests/use-cases/get-possible-integrations.test.ts +188 -0
  66. package/src/integrations/tests/use-cases/update-integration-messages.test.ts +142 -0
  67. package/src/integrations/tests/use-cases/update-integration-status.test.ts +103 -0
  68. package/src/integrations/tests/use-cases/update-integration.test.ts +208 -0
  69. package/src/integrations/use-cases/create-process.test.ts +172 -0
  70. package/src/integrations/use-cases/get-process.test.ts +181 -0
  71. package/src/integrations/use-cases/load-integration-context-full.test.ts +316 -0
  72. package/src/integrations/use-cases/load-integration-context.test.ts +115 -0
  73. package/src/integrations/use-cases/update-process-metrics.test.ts +278 -0
  74. package/src/integrations/use-cases/update-process-state.test.ts +249 -0
  75. package/src/lambda/TimeoutCatcher.test.ts +69 -0
  76. package/src/logs/logger.test.ts +76 -0
  77. package/src/modules/module-hydration.test.ts +203 -0
  78. package/src/modules/module.ts +1 -1
  79. package/src/modules/requester/oauth-2.test.ts +425 -0
  80. package/src/modules/requester/requester.test.ts +28 -0
  81. package/{modules/test/mock-api/api.js → src/modules/test/mock-api/api.ts} +6 -8
  82. package/{modules/test/mock-api/definition.js → src/modules/test/mock-api/definition.ts} +13 -14
  83. package/{modules/test/mock-api/mocks/hubspot.js → src/modules/test/mock-api/mocks/hubspot.ts} +6 -8
  84. package/{modules/tests/doubles/test-module-factory.js → src/modules/tests/doubles/test-module-factory.ts} +2 -5
  85. package/{modules/tests/doubles/test-module-repository.js → src/modules/tests/doubles/test-module-repository.ts} +7 -7
  86. package/src/modules/tests/module-on-token-update.test.ts +125 -0
  87. package/src/queues/queuer-util.test.ts +131 -0
  88. package/{user/tests/doubles/test-user-repository.js → src/user/tests/doubles/test-user-repository.ts} +17 -15
  89. package/src/user/tests/use-cases/create-individual-user.test.ts +24 -0
  90. package/src/user/tests/use-cases/create-organization-user.test.ts +28 -0
  91. package/src/user/tests/use-cases/create-token-for-user-id.test.ts +18 -0
  92. package/src/user/tests/use-cases/get-user-from-adopter-jwt.test.ts +113 -0
  93. package/src/user/tests/use-cases/get-user-from-bearer-token.test.ts +64 -0
  94. package/src/user/tests/use-cases/get-user-from-x-frigg-headers.test.ts +440 -0
  95. package/src/user/tests/use-cases/login-user.test.ts +220 -0
  96. package/src/user/use-cases/authenticate-with-shared-secret.test.ts +127 -0
  97. package/src/websocket/repositories/websocket-connection-repository.test.ts +220 -0
  98. package/tsconfig.test.json +10 -0
  99. package/workflows/frigg-workflow.ts +322 -0
  100. package/workflows/index.ts +205 -0
  101. package/workflows/steps/fan-out-step.ts +275 -0
  102. package/workflows/steps/function-step.ts +174 -0
  103. package/workflows/steps/index.ts +30 -0
  104. package/workflows/steps/workflow-step.ts +115 -0
  105. package/workflows/use-cases/create-workflow.ts +332 -0
  106. package/workflows/use-cases/execute-workflow-step.ts +465 -0
  107. package/workflows/use-cases/execute-workflow.ts +403 -0
  108. package/workflows/workflow-execution-repository.ts +415 -0
  109. package/workflows/workflow-execution.ts +209 -0
  110. package/workflows/workflow-queue-service.ts +379 -0
  111. package/workflows/workflow-repository.ts +295 -0
  112. package/workflows/workflow.ts +117 -0
  113. package/application/commands/credential-commands.js +0 -245
  114. package/application/commands/entity-commands.js +0 -336
  115. package/application/commands/integration-commands.js +0 -210
  116. package/application/commands/scheduler-commands.js +0 -263
  117. package/application/commands/user-commands.js +0 -283
  118. package/application/index.js +0 -73
  119. package/assertions/get.js +0 -139
  120. package/assertions/index.js +0 -16
  121. package/assertions/jest.config.js +0 -5
  122. package/associations/association.js +0 -3
  123. package/core/Delegate.js +0 -29
  124. package/core/Worker.js +0 -72
  125. package/core/create-handler.js +0 -75
  126. package/core/index.js +0 -7
  127. package/core/load-installed-modules.js +0 -28
  128. package/core/secrets-to-env.js +0 -61
  129. package/credential/repositories/credential-repository-documentdb.js +0 -304
  130. package/credential/repositories/credential-repository-factory.js +0 -54
  131. package/credential/repositories/credential-repository-interface.js +0 -98
  132. package/credential/repositories/credential-repository-mongo.js +0 -269
  133. package/credential/repositories/credential-repository-postgres.js +0 -287
  134. package/credential/repositories/credential-repository.js +0 -300
  135. package/credential/use-cases/get-credential-for-user.js +0 -25
  136. package/credential/use-cases/update-authentication-status.js +0 -15
  137. package/database/adapters/lambda-invoker.js +0 -97
  138. package/database/config.js +0 -154
  139. package/database/documentdb-encryption-service.js +0 -330
  140. package/database/documentdb-utils.js +0 -136
  141. package/database/encryption/encryption-schema-registry.js +0 -272
  142. package/database/encryption/field-encryption-service.js +0 -226
  143. package/database/encryption/logger.js +0 -79
  144. package/database/encryption/prisma-encryption-extension.js +0 -222
  145. package/database/index.js +0 -25
  146. package/database/jest.config.js +0 -5
  147. package/database/prisma.js +0 -182
  148. package/database/repositories/health-check-repository-documentdb.js +0 -138
  149. package/database/repositories/health-check-repository-factory.js +0 -48
  150. package/database/repositories/health-check-repository-interface.js +0 -82
  151. package/database/repositories/health-check-repository-mongodb.js +0 -89
  152. package/database/repositories/health-check-repository-postgres.js +0 -82
  153. package/database/repositories/migration-status-repository-s3.js +0 -137
  154. package/database/use-cases/check-database-health-use-case.js +0 -29
  155. package/database/use-cases/check-database-state-use-case.js +0 -81
  156. package/database/use-cases/check-encryption-health-use-case.js +0 -83
  157. package/database/use-cases/get-database-state-via-worker-use-case.js +0 -61
  158. package/database/use-cases/get-migration-status-use-case.js +0 -93
  159. package/database/use-cases/run-database-migration-use-case.js +0 -139
  160. package/database/use-cases/test-encryption-use-case.js +0 -253
  161. package/database/use-cases/trigger-database-migration-use-case.js +0 -157
  162. package/database/utils/mongodb-collection-utils.js +0 -94
  163. package/database/utils/mongodb-schema-init.js +0 -108
  164. package/database/utils/prisma-runner.js +0 -477
  165. package/database/utils/prisma-schema-parser.js +0 -182
  166. package/encrypt/Cryptor.js +0 -102
  167. package/encrypt/aes.js +0 -27
  168. package/encrypt/index.js +0 -3
  169. package/errors/base-error.js +0 -3
  170. package/errors/client-safe-error.js +0 -3
  171. package/errors/fetch-error.js +0 -3
  172. package/errors/halt-error.js +0 -3
  173. package/errors/index.js +0 -14
  174. package/errors/validation-errors.js +0 -3
  175. package/handlers/app-definition-loader.js +0 -38
  176. package/handlers/app-handler-helpers.js +0 -57
  177. package/handlers/backend-utils.js +0 -186
  178. package/handlers/database-migration-handler.js +0 -227
  179. package/handlers/integration-event-dispatcher.js +0 -54
  180. package/handlers/routers/auth.js +0 -15
  181. package/handlers/routers/db-migration.handler.js +0 -29
  182. package/handlers/routers/db-migration.js +0 -326
  183. package/handlers/routers/health.js +0 -516
  184. package/handlers/routers/integration-defined-routers.js +0 -45
  185. package/handlers/routers/integration-webhook-routers.js +0 -67
  186. package/handlers/routers/user.js +0 -63
  187. package/handlers/routers/websocket.js +0 -57
  188. package/handlers/use-cases/check-external-apis-health-use-case.js +0 -81
  189. package/handlers/use-cases/check-integrations-health-use-case.js +0 -44
  190. package/handlers/workers/db-migration.js +0 -352
  191. package/handlers/workers/integration-defined-workers.js +0 -27
  192. package/index.js +0 -176
  193. package/infrastructure/scheduler/eventbridge-scheduler-adapter.js +0 -184
  194. package/infrastructure/scheduler/index.js +0 -33
  195. package/infrastructure/scheduler/mock-scheduler-adapter.js +0 -143
  196. package/infrastructure/scheduler/scheduler-service-factory.js +0 -73
  197. package/infrastructure/scheduler/scheduler-service-interface.js +0 -47
  198. package/integrations/index.js +0 -21
  199. package/integrations/integration-base.js +0 -535
  200. package/integrations/integration-router.js +0 -666
  201. package/integrations/options.js +0 -53
  202. package/integrations/repositories/integration-mapping-repository-documentdb.js +0 -280
  203. package/integrations/repositories/integration-mapping-repository-factory.js +0 -57
  204. package/integrations/repositories/integration-mapping-repository-interface.js +0 -106
  205. package/integrations/repositories/integration-mapping-repository-mongo.js +0 -161
  206. package/integrations/repositories/integration-mapping-repository-postgres.js +0 -227
  207. package/integrations/repositories/integration-mapping-repository.js +0 -156
  208. package/integrations/repositories/integration-repository-documentdb.js +0 -210
  209. package/integrations/repositories/integration-repository-factory.js +0 -51
  210. package/integrations/repositories/integration-repository-interface.js +0 -127
  211. package/integrations/repositories/integration-repository-mongo.js +0 -303
  212. package/integrations/repositories/integration-repository-postgres.js +0 -352
  213. package/integrations/repositories/process-repository-documentdb.js +0 -243
  214. package/integrations/repositories/process-repository-factory.js +0 -53
  215. package/integrations/repositories/process-repository-interface.js +0 -90
  216. package/integrations/repositories/process-repository-mongo.js +0 -190
  217. package/integrations/repositories/process-repository-postgres.js +0 -217
  218. package/integrations/use-cases/create-integration.js +0 -83
  219. package/integrations/use-cases/create-process.js +0 -128
  220. package/integrations/use-cases/delete-integration-for-user.js +0 -101
  221. package/integrations/use-cases/find-integration-context-by-external-entity-id.js +0 -72
  222. package/integrations/use-cases/get-integration-for-user.js +0 -78
  223. package/integrations/use-cases/get-integration-instance-by-definition.js +0 -67
  224. package/integrations/use-cases/get-integration-instance.js +0 -83
  225. package/integrations/use-cases/get-integrations-for-user.js +0 -88
  226. package/integrations/use-cases/get-possible-integrations.js +0 -27
  227. package/integrations/use-cases/get-process.js +0 -87
  228. package/integrations/use-cases/index.js +0 -19
  229. package/integrations/use-cases/load-integration-context.js +0 -71
  230. package/integrations/use-cases/update-integration-messages.js +0 -44
  231. package/integrations/use-cases/update-integration-status.js +0 -32
  232. package/integrations/use-cases/update-integration.js +0 -92
  233. package/integrations/use-cases/update-process-metrics.js +0 -201
  234. package/integrations/use-cases/update-process-state.js +0 -119
  235. package/integrations/utils/map-integration-dto.js +0 -38
  236. package/jest-global-setup-noop.js +0 -3
  237. package/jest-global-teardown-noop.js +0 -3
  238. package/jest-setup.js +0 -2
  239. package/jest-teardown.js +0 -2
  240. package/jest.config.js +0 -21
  241. package/lambda/TimeoutCatcher.js +0 -43
  242. package/lambda/index.js +0 -3
  243. package/logs/index.js +0 -7
  244. package/logs/logger.js +0 -65
  245. package/modules/ModuleConstants.js +0 -10
  246. package/modules/index.js +0 -15
  247. package/modules/module-factory.js +0 -56
  248. package/modules/module.js +0 -228
  249. package/modules/repositories/module-repository-documentdb.js +0 -335
  250. package/modules/repositories/module-repository-factory.js +0 -40
  251. package/modules/repositories/module-repository-interface.js +0 -129
  252. package/modules/repositories/module-repository-mongo.js +0 -408
  253. package/modules/repositories/module-repository-postgres.js +0 -453
  254. package/modules/repositories/module-repository.js +0 -345
  255. package/modules/requester/api-key.js +0 -52
  256. package/modules/requester/basic.js +0 -43
  257. package/modules/requester/oauth-2.js +0 -396
  258. package/modules/requester/requester.js +0 -167
  259. package/modules/use-cases/get-entities-for-user.js +0 -32
  260. package/modules/use-cases/get-entity-options-by-id.js +0 -71
  261. package/modules/use-cases/get-entity-options-by-type.js +0 -34
  262. package/modules/use-cases/get-module-instance-from-type.js +0 -31
  263. package/modules/use-cases/get-module.js +0 -74
  264. package/modules/use-cases/process-authorization-callback.js +0 -133
  265. package/modules/use-cases/refresh-entity-options.js +0 -72
  266. package/modules/use-cases/test-module-auth.js +0 -72
  267. package/modules/utils/map-module-dto.js +0 -18
  268. package/queues/index.js +0 -4
  269. package/queues/queuer-util.js +0 -66
  270. package/syncs/manager.js +0 -489
  271. package/syncs/repositories/sync-repository-documentdb.js +0 -240
  272. package/syncs/repositories/sync-repository-factory.js +0 -43
  273. package/syncs/repositories/sync-repository-interface.js +0 -109
  274. package/syncs/repositories/sync-repository-mongo.js +0 -239
  275. package/syncs/repositories/sync-repository-postgres.js +0 -319
  276. package/syncs/sync.js +0 -113
  277. package/token/repositories/token-repository-documentdb.js +0 -137
  278. package/token/repositories/token-repository-factory.js +0 -40
  279. package/token/repositories/token-repository-interface.js +0 -131
  280. package/token/repositories/token-repository-mongo.js +0 -219
  281. package/token/repositories/token-repository-postgres.js +0 -264
  282. package/token/repositories/token-repository.js +0 -219
  283. package/user/repositories/user-repository-documentdb.js +0 -441
  284. package/user/repositories/user-repository-factory.js +0 -52
  285. package/user/repositories/user-repository-interface.js +0 -201
  286. package/user/repositories/user-repository-mongo.js +0 -308
  287. package/user/repositories/user-repository-postgres.js +0 -360
  288. package/user/use-cases/authenticate-user.js +0 -127
  289. package/user/use-cases/authenticate-with-shared-secret.js +0 -48
  290. package/user/use-cases/create-individual-user.js +0 -61
  291. package/user/use-cases/create-organization-user.js +0 -47
  292. package/user/use-cases/create-token-for-user-id.js +0 -30
  293. package/user/use-cases/get-user-from-adopter-jwt.js +0 -149
  294. package/user/use-cases/get-user-from-bearer-token.js +0 -77
  295. package/user/use-cases/get-user-from-x-frigg-headers.js +0 -132
  296. package/user/use-cases/login-user.js +0 -122
  297. package/user/user.js +0 -125
  298. package/utils/backend-path.js +0 -6
  299. package/utils/index.js +0 -6
  300. package/websocket/repositories/websocket-connection-repository-documentdb.js +0 -119
  301. package/websocket/repositories/websocket-connection-repository-factory.js +0 -44
  302. package/websocket/repositories/websocket-connection-repository-interface.js +0 -106
  303. package/websocket/repositories/websocket-connection-repository-mongo.js +0 -156
  304. package/websocket/repositories/websocket-connection-repository-postgres.js +0 -196
  305. package/websocket/repositories/websocket-connection-repository.js +0 -161
@@ -0,0 +1,7 @@
1
+ import type { Config } from 'jest';
2
+
3
+ const config: Config = {
4
+ preset: '@friggframework/test-environment',
5
+ };
6
+
7
+ export default config;
@@ -0,0 +1,7 @@
1
+ import type { Config } from 'jest';
2
+
3
+ const config: Config = {
4
+ preset: '@friggframework/test-environment',
5
+ };
6
+
7
+ export default config;
@@ -0,0 +1,315 @@
1
+ const { mongoose } = require('../mongoose');
2
+
3
+ const stepExecutionSchema = new mongoose.Schema({
4
+ stepId: {
5
+ type: String,
6
+ required: true
7
+ },
8
+ stepName: {
9
+ type: String,
10
+ required: true
11
+ },
12
+ status: {
13
+ type: String,
14
+ enum: ['RUNNING', 'COMPLETED', 'FAILED', 'RETRYING'],
15
+ required: true
16
+ },
17
+ startTime: {
18
+ type: Date,
19
+ required: true
20
+ },
21
+ endTime: Date,
22
+ result: mongoose.Schema.Types.Mixed,
23
+ error: {
24
+ message: String,
25
+ stack: String,
26
+ code: String,
27
+ timestamp: Date
28
+ },
29
+ retryCount: {
30
+ type: Number,
31
+ default: 0
32
+ },
33
+ duration: Number // Duration in milliseconds
34
+ }, { _id: false });
35
+
36
+ const fanOutStateSchema = new mongoose.Schema({
37
+ stepId: String,
38
+ stepName: String,
39
+ totalBatches: {
40
+ type: Number,
41
+ required: true
42
+ },
43
+ completedBatches: {
44
+ type: Number,
45
+ default: 0
46
+ },
47
+ batchResults: [mongoose.Schema.Types.Mixed],
48
+ aggregatedResult: mongoose.Schema.Types.Mixed,
49
+ status: {
50
+ type: String,
51
+ enum: ['RUNNING', 'COMPLETED', 'FAILED'],
52
+ default: 'RUNNING'
53
+ },
54
+ fanOutType: {
55
+ type: String,
56
+ enum: ['PAGINATION', 'DATA_PROCESSING'],
57
+ required: true
58
+ },
59
+ createdAt: {
60
+ type: Date,
61
+ default: Date.now
62
+ },
63
+ completedAt: Date,
64
+ lastUpdated: {
65
+ type: Date,
66
+ default: Date.now
67
+ }
68
+ }, { _id: false });
69
+
70
+ const workflowExecutionSchema = new mongoose.Schema({
71
+ workflowId: {
72
+ type: mongoose.Schema.Types.ObjectId,
73
+ ref: 'WorkflowModel',
74
+ required: true,
75
+ index: true
76
+ },
77
+ triggerType: {
78
+ type: String,
79
+ enum: ['MANUAL', 'WEBHOOK', 'SCHEDULE', 'EVENT'],
80
+ required: true,
81
+ index: true
82
+ },
83
+ status: {
84
+ type: String,
85
+ enum: ['RUNNING', 'COMPLETED', 'FAILED', 'PAUSED', 'CANCELLED'],
86
+ default: 'RUNNING',
87
+ index: true
88
+ },
89
+ startTime: {
90
+ type: Date,
91
+ required: true,
92
+ default: Date.now,
93
+ index: true
94
+ },
95
+ endTime: Date,
96
+ stepExecutions: [stepExecutionSchema],
97
+ context: {
98
+ triggerData: mongoose.Schema.Types.Mixed,
99
+ stepResults: mongoose.Schema.Types.Mixed,
100
+ variables: mongoose.Schema.Types.Mixed,
101
+ currentStep: String,
102
+ fanOutStates: {
103
+ type: Map,
104
+ of: fanOutStateSchema
105
+ }
106
+ },
107
+ metadata: {
108
+ totalSteps: {
109
+ type: Number,
110
+ default: 0
111
+ },
112
+ completedSteps: {
113
+ type: Number,
114
+ default: 0
115
+ },
116
+ failedSteps: {
117
+ type: Number,
118
+ default: 0
119
+ },
120
+ retryCount: {
121
+ type: Number,
122
+ default: 0
123
+ },
124
+ userId: {
125
+ type: mongoose.Schema.Types.ObjectId,
126
+ ref: 'IndividualUser'
127
+ },
128
+ integrationId: {
129
+ type: mongoose.Schema.Types.ObjectId,
130
+ ref: 'Integration'
131
+ },
132
+ executionSource: String, // 'UI', 'API', 'WEBHOOK', etc.
133
+ parentExecutionId: {
134
+ type: mongoose.Schema.Types.ObjectId,
135
+ ref: 'WorkflowExecutionModel'
136
+ }
137
+ },
138
+ lastUpdated: {
139
+ type: Date,
140
+ default: Date.now,
141
+ index: true
142
+ }
143
+ }, {
144
+ timestamps: true
145
+ });
146
+
147
+ // Indexes for performance
148
+ workflowExecutionSchema.index({ workflowId: 1, startTime: -1 });
149
+ workflowExecutionSchema.index({ status: 1, lastUpdated: 1 });
150
+ workflowExecutionSchema.index({ 'metadata.userId': 1, startTime: -1 });
151
+ workflowExecutionSchema.index({ triggerType: 1, status: 1 });
152
+
153
+ // TTL index to automatically delete old completed executions after 90 days
154
+ workflowExecutionSchema.index(
155
+ { endTime: 1 },
156
+ {
157
+ expireAfterSeconds: 90 * 24 * 60 * 60, // 90 days
158
+ partialFilterExpression: {
159
+ status: { $in: ['COMPLETED', 'FAILED', 'CANCELLED'] }
160
+ }
161
+ }
162
+ );
163
+
164
+ // Virtual properties
165
+ workflowExecutionSchema.virtual('duration').get(function() {
166
+ if (!this.startTime) return 0;
167
+ const endTime = this.endTime || new Date();
168
+ return endTime.getTime() - this.startTime.getTime();
169
+ });
170
+
171
+ workflowExecutionSchema.virtual('progress').get(function() {
172
+ if (!this.metadata.totalSteps || this.metadata.totalSteps === 0) return 0;
173
+ return (this.metadata.completedSteps / this.metadata.totalSteps) * 100;
174
+ });
175
+
176
+ workflowExecutionSchema.virtual('isRunning').get(function() {
177
+ return this.status === 'RUNNING';
178
+ });
179
+
180
+ workflowExecutionSchema.virtual('isCompleted').get(function() {
181
+ return this.status === 'COMPLETED';
182
+ });
183
+
184
+ workflowExecutionSchema.virtual('isFailed').get(function() {
185
+ return this.status === 'FAILED';
186
+ });
187
+
188
+ // Pre-save middleware
189
+ workflowExecutionSchema.pre('save', function(next) {
190
+ this.lastUpdated = new Date();
191
+
192
+ // Calculate completed steps from stepExecutions
193
+ if (this.stepExecutions) {
194
+ this.metadata.completedSteps = this.stepExecutions.filter(
195
+ step => step.status === 'COMPLETED'
196
+ ).length;
197
+ this.metadata.failedSteps = this.stepExecutions.filter(
198
+ step => step.status === 'FAILED'
199
+ ).length;
200
+ }
201
+
202
+ next();
203
+ });
204
+
205
+ // Pre-update middleware
206
+ workflowExecutionSchema.pre(['updateOne', 'findOneAndUpdate'], function(next) {
207
+ this.set({ lastUpdated: new Date() });
208
+ next();
209
+ });
210
+
211
+ // Instance methods
212
+ workflowExecutionSchema.methods.addStepExecution = function(stepExecution) {
213
+ // Calculate duration if not provided
214
+ if (stepExecution.startTime && stepExecution.endTime && !stepExecution.duration) {
215
+ stepExecution.duration = stepExecution.endTime.getTime() - stepExecution.startTime.getTime();
216
+ }
217
+
218
+ this.stepExecutions.push(stepExecution);
219
+ this.lastUpdated = new Date();
220
+
221
+ // Update context with step result if provided
222
+ if (stepExecution.result && stepExecution.stepName) {
223
+ if (!this.context.stepResults) {
224
+ this.context.stepResults = {};
225
+ }
226
+ this.context.stepResults[stepExecution.stepName] = stepExecution.result;
227
+ }
228
+
229
+ this.context.currentStep = stepExecution.stepId;
230
+ };
231
+
232
+ workflowExecutionSchema.methods.updateStatus = function(newStatus, endTime = null) {
233
+ this.status = newStatus;
234
+ this.lastUpdated = new Date();
235
+
236
+ if (endTime) {
237
+ this.endTime = endTime;
238
+ } else if (newStatus === 'COMPLETED' || newStatus === 'FAILED' || newStatus === 'CANCELLED') {
239
+ this.endTime = new Date();
240
+ }
241
+ };
242
+
243
+ workflowExecutionSchema.methods.getLastCompletedStep = function() {
244
+ const completedSteps = this.stepExecutions.filter(step => step.status === 'COMPLETED');
245
+ return completedSteps.length > 0 ? completedSteps[completedSteps.length - 1] : null;
246
+ };
247
+
248
+ workflowExecutionSchema.methods.getSummary = function() {
249
+ return {
250
+ id: this._id,
251
+ workflowId: this.workflowId,
252
+ triggerType: this.triggerType,
253
+ status: this.status,
254
+ startTime: this.startTime,
255
+ endTime: this.endTime,
256
+ duration: this.duration,
257
+ progress: this.progress,
258
+ stepCount: this.stepExecutions.length,
259
+ completedSteps: this.metadata.completedSteps,
260
+ failedSteps: this.metadata.failedSteps,
261
+ currentStep: this.context.currentStep,
262
+ fanOutSteps: this.context.fanOutStates ? Array.from(this.context.fanOutStates.keys()) : []
263
+ };
264
+ };
265
+
266
+ // Static methods
267
+ workflowExecutionSchema.statics.findByWorkflow = function(workflowId, options = {}) {
268
+ const query = this.find({ workflowId });
269
+
270
+ if (options.limit) query.limit(options.limit);
271
+ if (options.sort) query.sort(options.sort);
272
+ else query.sort({ startTime: -1 });
273
+
274
+ return query;
275
+ };
276
+
277
+ workflowExecutionSchema.statics.findRunning = function(filters = {}) {
278
+ return this.find({ status: 'RUNNING', ...filters });
279
+ };
280
+
281
+ workflowExecutionSchema.statics.findStalled = function(minutesStalled = 30) {
282
+ const stalledTime = new Date(Date.now() - minutesStalled * 60 * 1000);
283
+ return this.find({
284
+ status: 'RUNNING',
285
+ lastUpdated: { $lt: stalledTime }
286
+ });
287
+ };
288
+
289
+ workflowExecutionSchema.statics.getStatistics = function(filters = {}) {
290
+ return this.aggregate([
291
+ { $match: filters },
292
+ {
293
+ $group: {
294
+ _id: '$status',
295
+ count: { $sum: 1 },
296
+ avgDuration: {
297
+ $avg: {
298
+ $cond: [
299
+ { $and: ['$startTime', '$endTime'] },
300
+ { $subtract: ['$endTime', '$startTime'] },
301
+ null
302
+ ]
303
+ }
304
+ },
305
+ avgCompletedSteps: { $avg: '$metadata.completedSteps' }
306
+ }
307
+ },
308
+ { $sort: { _id: 1 } }
309
+ ]);
310
+ };
311
+
312
+ const WorkflowExecutionModel = mongoose.models.WorkflowExecutionModel ||
313
+ mongoose.model('WorkflowExecutionModel', workflowExecutionSchema);
314
+
315
+ module.exports = { WorkflowExecutionModel };
@@ -0,0 +1,129 @@
1
+ const { mongoose } = require('../mongoose');
2
+
3
+ const workflowSchema = new mongoose.Schema({
4
+ name: {
5
+ type: String,
6
+ required: true,
7
+ trim: true,
8
+ maxlength: 200
9
+ },
10
+ description: {
11
+ type: String,
12
+ trim: true,
13
+ maxlength: 1000
14
+ },
15
+ integrationId: {
16
+ type: mongoose.Schema.Types.ObjectId,
17
+ ref: 'Integration',
18
+ required: true,
19
+ index: true
20
+ },
21
+ userId: {
22
+ type: mongoose.Schema.Types.ObjectId,
23
+ ref: 'IndividualUser',
24
+ required: true,
25
+ index: true
26
+ },
27
+ status: {
28
+ type: String,
29
+ enum: ['ACTIVE', 'PAUSED', 'ERROR', 'DISABLED'],
30
+ default: 'ACTIVE',
31
+ index: true
32
+ },
33
+ definition: {
34
+ steps: [{
35
+ type: mongoose.Schema.Types.Mixed,
36
+ required: true
37
+ }],
38
+ triggers: [{
39
+ type: mongoose.Schema.Types.Mixed,
40
+ required: true
41
+ }]
42
+ },
43
+ metadata: {
44
+ createdAt: {
45
+ type: Date,
46
+ default: Date.now,
47
+ index: true
48
+ },
49
+ updatedAt: {
50
+ type: Date,
51
+ default: Date.now
52
+ },
53
+ version: {
54
+ type: String,
55
+ default: '1.0.0'
56
+ },
57
+ tags: [String],
58
+ category: String,
59
+ lastExecutedAt: Date,
60
+ executionCount: {
61
+ type: Number,
62
+ default: 0
63
+ }
64
+ }
65
+ }, {
66
+ timestamps: true // Adds createdAt and updatedAt automatically
67
+ });
68
+
69
+ // Indexes for better query performance
70
+ workflowSchema.index({ integrationId: 1, userId: 1 });
71
+ workflowSchema.index({ status: 1, 'metadata.createdAt': -1 });
72
+ workflowSchema.index({ userId: 1, status: 1 });
73
+
74
+ // Virtual for workflow summary
75
+ workflowSchema.virtual('stepCount').get(function() {
76
+ return this.definition && this.definition.steps ? this.definition.steps.length : 0;
77
+ });
78
+
79
+ workflowSchema.virtual('triggerCount').get(function() {
80
+ return this.definition && this.definition.triggers ? this.definition.triggers.length : 0;
81
+ });
82
+
83
+ // Pre-save middleware to update metadata.updatedAt
84
+ workflowSchema.pre('save', function(next) {
85
+ this.metadata.updatedAt = new Date();
86
+ next();
87
+ });
88
+
89
+ // Pre-update middleware to update metadata.updatedAt
90
+ workflowSchema.pre(['updateOne', 'findOneAndUpdate'], function(next) {
91
+ this.set({ 'metadata.updatedAt': new Date() });
92
+ next();
93
+ });
94
+
95
+ // Instance methods
96
+ workflowSchema.methods.isExecutable = function() {
97
+ return this.status === 'ACTIVE' &&
98
+ this.definition &&
99
+ this.definition.steps &&
100
+ this.definition.steps.length > 0;
101
+ };
102
+
103
+ workflowSchema.methods.getSummary = function() {
104
+ return {
105
+ id: this._id,
106
+ name: this.name,
107
+ description: this.description,
108
+ status: this.status,
109
+ stepCount: this.stepCount,
110
+ triggerCount: this.triggerCount,
111
+ createdAt: this.metadata.createdAt,
112
+ updatedAt: this.metadata.updatedAt,
113
+ version: this.metadata.version,
114
+ executionCount: this.metadata.executionCount
115
+ };
116
+ };
117
+
118
+ // Static methods
119
+ workflowSchema.statics.findByIntegrationAndUser = function(integrationId, userId) {
120
+ return this.find({ integrationId, userId });
121
+ };
122
+
123
+ workflowSchema.statics.findActiveWorkflows = function(filters = {}) {
124
+ return this.find({ status: 'ACTIVE', ...filters });
125
+ };
126
+
127
+ const WorkflowModel = mongoose.models.WorkflowModel || mongoose.model('WorkflowModel', workflowSchema);
128
+
129
+ module.exports = { WorkflowModel };
@@ -0,0 +1,3 @@
1
+ export default async function noopGlobalSetup(): Promise<void> {
2
+ // No global setup required for unit tests.
3
+ }
@@ -0,0 +1,3 @@
1
+ export default async function noopGlobalTeardown(): Promise<void> {
2
+ // No global teardown required for unit tests.
3
+ }
@@ -0,0 +1,36 @@
1
+ const path = require('path');
2
+
3
+ interface ResolverOptions {
4
+ defaultResolver: (request: string, options: ResolverOptions) => string;
5
+ rootDir?: string;
6
+ basedir: string;
7
+ }
8
+
9
+ module.exports = (request: string, options: ResolverOptions): string => {
10
+ const { defaultResolver } = options;
11
+ try {
12
+ return defaultResolver(request, options);
13
+ } catch (error: unknown) {
14
+ if (
15
+ error instanceof Error &&
16
+ 'code' in error &&
17
+ (error as NodeJS.ErrnoException).code === 'MODULE_NOT_FOUND' &&
18
+ !request.startsWith('@') &&
19
+ !path.isAbsolute(request)
20
+ ) {
21
+ const rootDir = options.rootDir || path.resolve(__dirname);
22
+ const resolved = path.resolve(options.basedir, request);
23
+ const relative = path.relative(rootDir, resolved);
24
+
25
+ if (relative && !relative.startsWith('..') && !relative.startsWith('node_modules')) {
26
+ const distPath = path.join(rootDir, 'dist', relative);
27
+ try {
28
+ return defaultResolver(distPath, { ...options, basedir: rootDir });
29
+ } catch {
30
+ // fall through to original error
31
+ }
32
+ }
33
+ }
34
+ throw error;
35
+ }
36
+ };
package/jest-setup.ts ADDED
@@ -0,0 +1,2 @@
1
+ import { globalSetup } from '@friggframework/test';
2
+ export default globalSetup;
@@ -0,0 +1,2 @@
1
+ import { globalTeardown } from '@friggframework/test';
2
+ export default globalTeardown;
package/jest.config.ts ADDED
@@ -0,0 +1,20 @@
1
+ import type { Config } from 'jest';
2
+
3
+ const config: Config = {
4
+ resolver: './jest-resolver.ts',
5
+ transform: {
6
+ '^.+\\.tsx?$': ['ts-jest', { tsconfig: 'tsconfig.test.json', diagnostics: false }],
7
+ },
8
+ coverageThreshold: {
9
+ global: {
10
+ statements: 13,
11
+ branches: 0,
12
+ functions: 1,
13
+ lines: 13,
14
+ },
15
+ },
16
+ globalSetup: './jest-setup.ts',
17
+ globalTeardown: './jest-teardown.ts',
18
+ };
19
+
20
+ export default config;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@friggframework/core",
3
3
  "prettier": "@friggframework/prettier-config",
4
- "version": "2.0.0--canary.549.a579cca.0",
4
+ "version": "2.0.0--canary.549.6674256.0",
5
5
  "dependencies": {
6
6
  "@aws-sdk/client-apigatewaymanagementapi": "^3.588.0",
7
7
  "@aws-sdk/client-kms": "^3.588.0",
@@ -40,14 +40,16 @@
40
40
  }
41
41
  },
42
42
  "devDependencies": {
43
- "@friggframework/eslint-config": "2.0.0--canary.549.a579cca.0",
44
- "@friggframework/prettier-config": "2.0.0--canary.549.a579cca.0",
45
- "@friggframework/test": "2.0.0--canary.549.a579cca.0",
43
+ "@friggframework/eslint-config": "2.0.0--canary.549.6674256.0",
44
+ "@friggframework/prettier-config": "2.0.0--canary.549.6674256.0",
45
+ "@friggframework/test": "2.0.0--canary.549.6674256.0",
46
46
  "@prisma/client": "^6.17.0",
47
47
  "@types/common-tags": "^1.8.4",
48
48
  "@types/express": "^4.17.21",
49
+ "@types/jest": "^30.0.0",
49
50
  "@types/lodash": "4.17.15",
50
51
  "@types/node": "^22.0.0",
52
+ "@types/sinon": "^17.0.4",
51
53
  "@typescript-eslint/eslint-plugin": "^8.0.0",
52
54
  "chai": "^4.3.6",
53
55
  "eslint": "^8.22.0",
@@ -58,6 +60,7 @@
58
60
  "prettier": "^2.7.1",
59
61
  "prisma": "^6.17.0",
60
62
  "sinon": "^16.1.1",
63
+ "ts-jest": "^29.4.6",
61
64
  "typescript": "^5.0.2"
62
65
  },
63
66
  "scripts": {
@@ -99,5 +102,5 @@
99
102
  "publishConfig": {
100
103
  "access": "public"
101
104
  },
102
- "gitHead": "a579cca5c61e1dc8187b05268a64c1c2453ca664"
105
+ "gitHead": "66742560debce86ce48a82f311234c655ac9553f"
103
106
  }