@friggframework/core 2.0.0-next.11 → 2.0.0-next.110

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 (375) hide show
  1. package/CLAUDE.md +702 -0
  2. package/README.md +999 -50
  3. package/admin-scripts/index.js +52 -0
  4. package/admin-scripts/repositories/admin-script-execution-repository-documentdb.js +21 -0
  5. package/admin-scripts/repositories/admin-script-execution-repository-factory.js +51 -0
  6. package/admin-scripts/repositories/admin-script-execution-repository-interface.js +171 -0
  7. package/admin-scripts/repositories/admin-script-execution-repository-mongo.js +238 -0
  8. package/admin-scripts/repositories/admin-script-execution-repository-postgres.js +278 -0
  9. package/admin-scripts/repositories/script-schedule-repository-documentdb.js +21 -0
  10. package/admin-scripts/repositories/script-schedule-repository-factory.js +51 -0
  11. package/admin-scripts/repositories/script-schedule-repository-interface.js +108 -0
  12. package/admin-scripts/repositories/script-schedule-repository-mongo.js +179 -0
  13. package/admin-scripts/repositories/script-schedule-repository-postgres.js +210 -0
  14. package/application/commands/README.md +451 -0
  15. package/application/commands/admin-script-commands.js +359 -0
  16. package/application/commands/credential-commands.js +262 -0
  17. package/application/commands/entity-commands.js +336 -0
  18. package/application/commands/integration-commands.js +356 -0
  19. package/application/commands/integration-mapping-commands.js +25 -0
  20. package/application/commands/process-commands.js +135 -0
  21. package/application/commands/report-commands.js +188 -0
  22. package/application/commands/scheduler-commands.js +263 -0
  23. package/application/commands/usage-commands.js +56 -0
  24. package/application/commands/user-commands.js +312 -0
  25. package/application/index.js +83 -0
  26. package/artifacts/repositories/artifact-repository-factory.js +19 -0
  27. package/artifacts/repositories/artifact-repository-interface.js +27 -0
  28. package/artifacts/repositories/artifact-repository-local.js +42 -0
  29. package/artifacts/repositories/artifact-repository-s3.js +61 -0
  30. package/assertions/index.js +0 -3
  31. package/core/CLAUDE.md +700 -0
  32. package/core/Worker.js +60 -24
  33. package/core/create-handler.js +189 -5
  34. package/core/parameters-to-env.js +257 -0
  35. package/core/ssm-preload.mjs +34 -0
  36. package/credential/repositories/credential-active-type.js +32 -0
  37. package/credential/repositories/credential-repository-documentdb.js +355 -0
  38. package/credential/repositories/credential-repository-factory.js +54 -0
  39. package/credential/repositories/credential-repository-interface.js +113 -0
  40. package/credential/repositories/credential-repository-mongo.js +294 -0
  41. package/credential/repositories/credential-repository-postgres.js +312 -0
  42. package/credential/repositories/credential-repository.js +300 -0
  43. package/credential/use-cases/get-credential-for-user.js +25 -0
  44. package/credential/use-cases/update-authentication-status.js +15 -0
  45. package/database/MONGODB_TRANSACTION_FIX.md +198 -0
  46. package/database/adapters/lambda-invoker.js +97 -0
  47. package/database/config.js +154 -0
  48. package/database/documentdb-encryption-service.js +330 -0
  49. package/database/documentdb-utils.js +192 -0
  50. package/database/encryption/README.md +839 -0
  51. package/database/encryption/documentdb-encryption-service.md +3575 -0
  52. package/database/encryption/encryption-schema-registry.js +401 -0
  53. package/database/encryption/field-encryption-service.js +254 -0
  54. package/database/encryption/logger.js +79 -0
  55. package/database/encryption/prisma-encryption-extension.js +230 -0
  56. package/database/index.js +21 -21
  57. package/database/prisma.js +182 -0
  58. package/database/repositories/health-check-repository-documentdb.js +138 -0
  59. package/database/repositories/health-check-repository-factory.js +48 -0
  60. package/database/repositories/health-check-repository-interface.js +82 -0
  61. package/database/repositories/health-check-repository-mongodb.js +89 -0
  62. package/database/repositories/health-check-repository-postgres.js +82 -0
  63. package/database/repositories/migration-status-repository-s3.js +137 -0
  64. package/database/use-cases/check-database-health-use-case.js +29 -0
  65. package/database/use-cases/check-database-state-use-case.js +81 -0
  66. package/database/use-cases/check-encryption-health-use-case.js +83 -0
  67. package/database/use-cases/get-database-state-via-worker-use-case.js +61 -0
  68. package/database/use-cases/get-migration-status-use-case.js +93 -0
  69. package/database/use-cases/resolve-migration-via-worker-use-case.js +49 -0
  70. package/database/use-cases/run-database-migration-use-case.js +139 -0
  71. package/database/use-cases/test-encryption-use-case.js +253 -0
  72. package/database/use-cases/trigger-database-migration-use-case.js +157 -0
  73. package/database/utils/mongodb-collection-utils.js +94 -0
  74. package/database/utils/mongodb-schema-init.js +108 -0
  75. package/database/utils/prisma-runner.js +491 -0
  76. package/database/utils/prisma-schema-parser.js +182 -0
  77. package/docs/PROCESS_MANAGEMENT_QUEUE_SPEC.md +517 -0
  78. package/encrypt/Cryptor.js +34 -168
  79. package/encrypt/index.js +1 -2
  80. package/errors/client-safe-error.js +26 -0
  81. package/errors/fetch-error.js +15 -7
  82. package/errors/index.js +2 -0
  83. package/generated/prisma-mongodb/client.d.ts +1 -0
  84. package/generated/prisma-mongodb/client.js +5 -0
  85. package/generated/prisma-mongodb/default.d.ts +1 -0
  86. package/generated/prisma-mongodb/default.js +5 -0
  87. package/generated/prisma-mongodb/edge.d.ts +1 -0
  88. package/generated/prisma-mongodb/edge.js +386 -0
  89. package/generated/prisma-mongodb/index-browser.js +368 -0
  90. package/generated/prisma-mongodb/index.d.ts +27065 -0
  91. package/generated/prisma-mongodb/index.js +411 -0
  92. package/generated/prisma-mongodb/libquery_engine-debian-openssl-3.0.x.so.node +0 -0
  93. package/generated/prisma-mongodb/libquery_engine-rhel-openssl-3.0.x.so.node +0 -0
  94. package/generated/prisma-mongodb/package.json +183 -0
  95. package/generated/prisma-mongodb/runtime/edge-esm.js +35 -0
  96. package/generated/prisma-mongodb/runtime/edge.js +35 -0
  97. package/generated/prisma-mongodb/runtime/index-browser.d.ts +370 -0
  98. package/generated/prisma-mongodb/runtime/index-browser.js +17 -0
  99. package/generated/prisma-mongodb/runtime/library.d.ts +3982 -0
  100. package/generated/prisma-mongodb/runtime/library.js +147 -0
  101. package/generated/prisma-mongodb/runtime/react-native.js +84 -0
  102. package/generated/prisma-mongodb/runtime/wasm-compiler-edge.js +85 -0
  103. package/generated/prisma-mongodb/runtime/wasm-engine-edge.js +38 -0
  104. package/generated/prisma-mongodb/schema.prisma +455 -0
  105. package/generated/prisma-mongodb/wasm-edge-light-loader.mjs +5 -0
  106. package/generated/prisma-mongodb/wasm-worker-loader.mjs +5 -0
  107. package/generated/prisma-mongodb/wasm.d.ts +1 -0
  108. package/generated/prisma-mongodb/wasm.js +393 -0
  109. package/generated/prisma-postgresql/client.d.ts +1 -0
  110. package/generated/prisma-postgresql/client.js +5 -0
  111. package/generated/prisma-postgresql/default.d.ts +1 -0
  112. package/generated/prisma-postgresql/default.js +5 -0
  113. package/generated/prisma-postgresql/edge.d.ts +1 -0
  114. package/generated/prisma-postgresql/edge.js +407 -0
  115. package/generated/prisma-postgresql/index-browser.js +389 -0
  116. package/generated/prisma-postgresql/index.d.ts +29904 -0
  117. package/generated/prisma-postgresql/index.js +432 -0
  118. package/generated/prisma-postgresql/libquery_engine-debian-openssl-3.0.x.so.node +0 -0
  119. package/generated/prisma-postgresql/libquery_engine-rhel-openssl-3.0.x.so.node +0 -0
  120. package/generated/prisma-postgresql/package.json +183 -0
  121. package/generated/prisma-postgresql/query_engine_bg.js +2 -0
  122. package/generated/prisma-postgresql/query_engine_bg.wasm +0 -0
  123. package/generated/prisma-postgresql/runtime/edge-esm.js +35 -0
  124. package/generated/prisma-postgresql/runtime/edge.js +35 -0
  125. package/generated/prisma-postgresql/runtime/index-browser.d.ts +370 -0
  126. package/generated/prisma-postgresql/runtime/index-browser.js +17 -0
  127. package/generated/prisma-postgresql/runtime/library.d.ts +3982 -0
  128. package/generated/prisma-postgresql/runtime/library.js +147 -0
  129. package/generated/prisma-postgresql/runtime/react-native.js +84 -0
  130. package/generated/prisma-postgresql/runtime/wasm-compiler-edge.js +85 -0
  131. package/generated/prisma-postgresql/runtime/wasm-engine-edge.js +38 -0
  132. package/generated/prisma-postgresql/schema.prisma +436 -0
  133. package/generated/prisma-postgresql/wasm-edge-light-loader.mjs +5 -0
  134. package/generated/prisma-postgresql/wasm-worker-loader.mjs +5 -0
  135. package/generated/prisma-postgresql/wasm.d.ts +1 -0
  136. package/generated/prisma-postgresql/wasm.js +414 -0
  137. package/handlers/WEBHOOKS.md +653 -0
  138. package/handlers/app-definition-loader.js +67 -0
  139. package/handlers/app-handler-helpers.js +3 -3
  140. package/handlers/backend-utils.js +271 -42
  141. package/handlers/database-migration-handler.js +227 -0
  142. package/handlers/integration-event-dispatcher.js +68 -0
  143. package/handlers/middleware/admin-auth.js +73 -0
  144. package/handlers/routers/HEALTHCHECK.md +342 -0
  145. package/handlers/routers/auth.js +4 -15
  146. package/handlers/routers/db-migration.handler.js +29 -0
  147. package/handlers/routers/db-migration.js +329 -0
  148. package/handlers/routers/health.js +518 -0
  149. package/handlers/routers/integration-defined-routers.js +85 -10
  150. package/handlers/routers/integration-webhook-routers.js +80 -0
  151. package/handlers/routers/user.js +27 -5
  152. package/handlers/routers/websocket.js +5 -3
  153. package/handlers/use-cases/check-external-apis-health-use-case.js +81 -0
  154. package/handlers/use-cases/check-integrations-health-use-case.js +44 -0
  155. package/handlers/workers/db-migration.js +427 -0
  156. package/handlers/workers/dlq-processor.js +63 -0
  157. package/handlers/workers/integration-defined-workers.js +13 -7
  158. package/index.js +102 -46
  159. package/infrastructure/scheduler/eventbridge-scheduler-adapter.js +184 -0
  160. package/infrastructure/scheduler/index.js +33 -0
  161. package/infrastructure/scheduler/mock-scheduler-adapter.js +143 -0
  162. package/infrastructure/scheduler/scheduler-service-factory.js +73 -0
  163. package/infrastructure/scheduler/scheduler-service-interface.js +47 -0
  164. package/integrations/EXTENSIONS.md +240 -0
  165. package/integrations/WEBHOOK-QUICKSTART.md +151 -0
  166. package/integrations/extension.js +254 -0
  167. package/integrations/index.js +20 -10
  168. package/integrations/integration-base.js +730 -74
  169. package/integrations/integration-router.js +398 -180
  170. package/integrations/options.js +1 -1
  171. package/integrations/repositories/config-patch-shared.js +43 -0
  172. package/integrations/repositories/integration-mapping-repository-documentdb.js +303 -0
  173. package/integrations/repositories/integration-mapping-repository-factory.js +57 -0
  174. package/integrations/repositories/integration-mapping-repository-interface.js +120 -0
  175. package/integrations/repositories/integration-mapping-repository-mongo.js +183 -0
  176. package/integrations/repositories/integration-mapping-repository-postgres.js +255 -0
  177. package/integrations/repositories/integration-mapping-repository.js +156 -0
  178. package/integrations/repositories/integration-repository-documentdb.js +322 -0
  179. package/integrations/repositories/integration-repository-factory.js +51 -0
  180. package/integrations/repositories/integration-repository-interface.js +189 -0
  181. package/integrations/repositories/integration-repository-mongo.js +450 -0
  182. package/integrations/repositories/integration-repository-postgres.js +492 -0
  183. package/integrations/repositories/process-repository-documentdb.js +311 -0
  184. package/integrations/repositories/process-repository-factory.js +53 -0
  185. package/integrations/repositories/process-repository-interface.js +136 -0
  186. package/integrations/repositories/process-repository-mongo.js +262 -0
  187. package/integrations/repositories/process-repository-postgres.js +380 -0
  188. package/integrations/repositories/process-update-ops-shared.js +112 -0
  189. package/integrations/repositories/report-id.js +13 -0
  190. package/integrations/tests/doubles/config-capturing-integration.js +81 -0
  191. package/integrations/tests/doubles/dummy-integration-class.js +113 -0
  192. package/integrations/tests/doubles/test-integration-repository.js +146 -0
  193. package/integrations/use-cases/create-integration.js +215 -0
  194. package/integrations/use-cases/create-process.js +130 -0
  195. package/integrations/use-cases/delete-integration-for-user.js +119 -0
  196. package/integrations/use-cases/find-integration-by-entity-external-id.js +74 -0
  197. package/integrations/use-cases/find-integration-context-by-external-entity-id.js +76 -0
  198. package/integrations/use-cases/get-integration-for-user.js +78 -0
  199. package/integrations/use-cases/get-integration-instance-by-definition.js +67 -0
  200. package/integrations/use-cases/get-integration-instance.js +83 -0
  201. package/integrations/use-cases/get-integrations-for-user.js +88 -0
  202. package/integrations/use-cases/get-possible-integrations.js +27 -0
  203. package/integrations/use-cases/get-process.js +89 -0
  204. package/integrations/use-cases/index.js +19 -0
  205. package/integrations/use-cases/list-integrations-by-entity-external-id.js +46 -0
  206. package/integrations/use-cases/load-integration-context.js +71 -0
  207. package/integrations/use-cases/patch-integration-config.js +39 -0
  208. package/integrations/use-cases/process-errors.js +28 -0
  209. package/integrations/use-cases/update-integration-config.js +32 -0
  210. package/integrations/use-cases/update-integration-messages.js +44 -0
  211. package/integrations/use-cases/update-integration-status.js +32 -0
  212. package/integrations/use-cases/update-integration.js +92 -0
  213. package/integrations/use-cases/update-process-metrics.js +222 -0
  214. package/integrations/use-cases/update-process-state.js +163 -0
  215. package/integrations/utils/map-integration-dto.js +37 -0
  216. package/jest-global-setup-noop.js +3 -0
  217. package/jest-global-teardown-noop.js +3 -0
  218. package/logs/logger.js +0 -4
  219. package/{module-plugin → modules}/index.js +0 -10
  220. package/modules/module-factory.js +56 -0
  221. package/modules/module.js +307 -0
  222. package/modules/repositories/module-repository-documentdb.js +350 -0
  223. package/modules/repositories/module-repository-factory.js +40 -0
  224. package/modules/repositories/module-repository-interface.js +145 -0
  225. package/modules/repositories/module-repository-mongo.js +436 -0
  226. package/modules/repositories/module-repository-postgres.js +481 -0
  227. package/modules/repositories/module-repository.js +369 -0
  228. package/modules/requester/api-key.js +52 -0
  229. package/modules/requester/oauth-2.js +555 -0
  230. package/modules/requester/requester.js +542 -0
  231. package/{module-plugin → modules}/test/mock-api/api.js +8 -3
  232. package/{module-plugin → modules}/test/mock-api/definition.js +14 -10
  233. package/modules/tests/doubles/test-module-factory.js +16 -0
  234. package/modules/tests/doubles/test-module-repository.js +39 -0
  235. package/modules/use-cases/get-entities-for-user.js +32 -0
  236. package/modules/use-cases/get-entity-options-by-id.js +71 -0
  237. package/modules/use-cases/get-entity-options-by-type.js +34 -0
  238. package/modules/use-cases/get-module-instance-from-type.js +34 -0
  239. package/modules/use-cases/get-module.js +74 -0
  240. package/modules/use-cases/process-authorization-callback.js +243 -0
  241. package/modules/use-cases/refresh-entity-options.js +72 -0
  242. package/modules/use-cases/test-module-auth.js +72 -0
  243. package/modules/utils/map-module-dto.js +18 -0
  244. package/package.json +92 -50
  245. package/prisma-mongodb/schema.prisma +455 -0
  246. package/prisma-postgresql/migrations/20250930193005_init/migration.sql +315 -0
  247. package/prisma-postgresql/migrations/20251006135218_init/migration.sql +9 -0
  248. package/prisma-postgresql/migrations/20251010000000_remove_unused_entity_reference_map/migration.sql +3 -0
  249. package/prisma-postgresql/migrations/20251112195422_update_user_unique_constraints/migration.sql +25 -0
  250. package/prisma-postgresql/migrations/20260422120000_add_entity_data_column/migration.sql +10 -0
  251. package/prisma-postgresql/migrations/20260422120001_create_process_table/migration.sql +48 -0
  252. package/prisma-postgresql/migrations/20260625000000_add_user_organization_id_index/migration.sql +2 -0
  253. package/prisma-postgresql/migrations/20260703000000_add_integration_status_in_creation_in_deletion/migration.sql +11 -0
  254. package/prisma-postgresql/migrations/20260703000001_integration_status_default_in_creation/migration.sql +8 -0
  255. package/prisma-postgresql/migrations/20260705000000_create_usage_counter/migration.sql +26 -0
  256. package/prisma-postgresql/migrations/20260706000000_add_admin_script_execution_and_schedule/migration.sql +61 -0
  257. package/prisma-postgresql/migrations/migration_lock.toml +3 -0
  258. package/prisma-postgresql/schema.prisma +436 -0
  259. package/queues/queuer-util.js +103 -21
  260. package/reporting/README.md +154 -0
  261. package/reporting/builtin-reports.js +6 -0
  262. package/reporting/index.js +13 -0
  263. package/reporting/report-base.js +49 -0
  264. package/reporting/reports/integrations-report.js +221 -0
  265. package/syncs/manager.js +468 -443
  266. package/syncs/repositories/sync-repository-documentdb.js +240 -0
  267. package/syncs/repositories/sync-repository-factory.js +43 -0
  268. package/syncs/repositories/sync-repository-interface.js +109 -0
  269. package/syncs/repositories/sync-repository-mongo.js +239 -0
  270. package/syncs/repositories/sync-repository-postgres.js +319 -0
  271. package/syncs/sync.js +0 -1
  272. package/telemetry/README.md +331 -0
  273. package/telemetry/bind-telemetry-context.js +73 -0
  274. package/telemetry/canonical-counters.js +52 -0
  275. package/telemetry/exporters.js +85 -0
  276. package/telemetry/index.js +26 -0
  277. package/telemetry/instrument-handler.js +87 -0
  278. package/telemetry/no-op-telemetry.js +67 -0
  279. package/telemetry/north-star.js +103 -0
  280. package/telemetry/otel-telemetry.js +213 -0
  281. package/telemetry/plugin-subscribers.js +77 -0
  282. package/telemetry/telemetry-config.js +120 -0
  283. package/telemetry/telemetry-context.js +40 -0
  284. package/telemetry/telemetry-event-bus.js +58 -0
  285. package/telemetry/telemetry-runtime.js +147 -0
  286. package/telemetry/telemetry-service.js +51 -0
  287. package/telemetry/usage-rollup-subscriber.js +116 -0
  288. package/token/repositories/token-repository-documentdb.js +137 -0
  289. package/token/repositories/token-repository-factory.js +40 -0
  290. package/token/repositories/token-repository-interface.js +131 -0
  291. package/token/repositories/token-repository-mongo.js +219 -0
  292. package/token/repositories/token-repository-postgres.js +264 -0
  293. package/token/repositories/token-repository.js +219 -0
  294. package/types/associations/index.d.ts +0 -17
  295. package/types/core/index.d.ts +12 -4
  296. package/types/database/index.d.ts +10 -2
  297. package/types/encrypt/index.d.ts +5 -3
  298. package/types/integrations/index.d.ts +3 -8
  299. package/types/module-plugin/index.d.ts +20 -69
  300. package/types/syncs/index.d.ts +0 -17
  301. package/usage/README.md +54 -0
  302. package/usage/index.js +17 -0
  303. package/usage/repositories/usage-repository-documentdb.js +194 -0
  304. package/usage/repositories/usage-repository-factory.js +25 -0
  305. package/usage/repositories/usage-repository-interface.js +37 -0
  306. package/usage/repositories/usage-repository-prisma.js +146 -0
  307. package/usage/tracked-metrics.js +38 -0
  308. package/usage/usage-windows.js +24 -0
  309. package/user/repositories/user-repository-documentdb.js +458 -0
  310. package/user/repositories/user-repository-factory.js +52 -0
  311. package/user/repositories/user-repository-interface.js +214 -0
  312. package/user/repositories/user-repository-mongo.js +323 -0
  313. package/user/repositories/user-repository-postgres.js +377 -0
  314. package/user/tests/doubles/test-user-repository.js +72 -0
  315. package/user/use-cases/authenticate-user.js +127 -0
  316. package/user/use-cases/authenticate-with-shared-secret.js +48 -0
  317. package/user/use-cases/create-individual-user.js +61 -0
  318. package/user/use-cases/create-organization-user.js +47 -0
  319. package/user/use-cases/create-token-for-user-id.js +30 -0
  320. package/user/use-cases/get-user-from-adopter-jwt.js +149 -0
  321. package/user/use-cases/get-user-from-bearer-token.js +77 -0
  322. package/user/use-cases/get-user-from-x-frigg-headers.js +132 -0
  323. package/user/use-cases/login-user.js +122 -0
  324. package/user/user.js +125 -0
  325. package/utils/backend-path.js +38 -0
  326. package/utils/index.js +6 -0
  327. package/websocket/repositories/websocket-connection-repository-documentdb.js +119 -0
  328. package/websocket/repositories/websocket-connection-repository-factory.js +44 -0
  329. package/websocket/repositories/websocket-connection-repository-interface.js +106 -0
  330. package/websocket/repositories/websocket-connection-repository-mongo.js +156 -0
  331. package/websocket/repositories/websocket-connection-repository-postgres.js +196 -0
  332. package/websocket/repositories/websocket-connection-repository.js +161 -0
  333. package/assertions/is-equal.js +0 -17
  334. package/associations/model.js +0 -54
  335. package/database/models/IndividualUser.js +0 -76
  336. package/database/models/OrganizationUser.js +0 -29
  337. package/database/models/State.js +0 -9
  338. package/database/models/Token.js +0 -70
  339. package/database/models/UserModel.js +0 -7
  340. package/database/models/WebsocketConnection.js +0 -49
  341. package/database/mongo.js +0 -45
  342. package/database/mongoose.js +0 -5
  343. package/encrypt/Cryptor.test.js +0 -32
  344. package/encrypt/encrypt.js +0 -132
  345. package/encrypt/encrypt.test.js +0 -1069
  346. package/encrypt/test-encrypt.js +0 -107
  347. package/errors/base-error.test.js +0 -32
  348. package/errors/fetch-error.test.js +0 -79
  349. package/errors/halt-error.test.js +0 -11
  350. package/errors/validation-errors.test.js +0 -120
  351. package/handlers/routers/middleware/loadUser.js +0 -15
  352. package/handlers/routers/middleware/requireLoggedInUser.js +0 -12
  353. package/integrations/create-frigg-backend.js +0 -31
  354. package/integrations/integration-factory.js +0 -251
  355. package/integrations/integration-mapping.js +0 -43
  356. package/integrations/integration-model.js +0 -46
  357. package/integrations/integration-user.js +0 -144
  358. package/integrations/test/integration-base.test.js +0 -144
  359. package/lambda/TimeoutCatcher.test.js +0 -68
  360. package/logs/logger.test.js +0 -76
  361. package/module-plugin/auther.js +0 -393
  362. package/module-plugin/credential.js +0 -22
  363. package/module-plugin/entity-manager.js +0 -70
  364. package/module-plugin/entity.js +0 -46
  365. package/module-plugin/manager.js +0 -169
  366. package/module-plugin/module-factory.js +0 -61
  367. package/module-plugin/requester/api-key.js +0 -36
  368. package/module-plugin/requester/oauth-2.js +0 -219
  369. package/module-plugin/requester/requester.js +0 -165
  370. package/module-plugin/requester/requester.test.js +0 -28
  371. package/module-plugin/test/auther.test.js +0 -97
  372. package/syncs/model.js +0 -62
  373. /package/{module-plugin → modules}/ModuleConstants.js +0 -0
  374. /package/{module-plugin → modules}/requester/basic.js +0 -0
  375. /package/{module-plugin → modules}/test/mock-api/mocks/hubspot.js +0 -0
@@ -0,0 +1,450 @@
1
+ const { prisma } = require('../../database/prisma');
2
+ const {
3
+ IntegrationRepositoryInterface,
4
+ } = require('./integration-repository-interface');
5
+ const { validateConfigPatch } = require('./config-patch-shared');
6
+
7
+ /**
8
+ * MongoDB Integration Repository Adapter
9
+ * Handles integration persistence using Prisma with MongoDB
10
+ *
11
+ * MongoDB-specific characteristics:
12
+ * - Uses scalar fields for relations (userId, entityIds)
13
+ * - IDs are strings with @db.ObjectId
14
+ * - Arrays used for many-to-many relationships
15
+ *
16
+ * Migration from Mongoose:
17
+ * - Constructor injection of Prisma client
18
+ * - populate() → include in Prisma queries
19
+ * - lean: true → No longer needed (Prisma returns plain objects)
20
+ * - toString() conversions → Done automatically by Prisma
21
+ */
22
+ class IntegrationRepositoryMongo extends IntegrationRepositoryInterface {
23
+ constructor() {
24
+ super();
25
+ this.prisma = prisma;
26
+ }
27
+
28
+ /**
29
+ * Find all integrations for a user
30
+ * Replaces: IntegrationModel.find({ user: userId }).populate('entities')
31
+ *
32
+ * @param {string} userId - User ID (MongoDB ObjectId as string)
33
+ * @returns {Promise<Array>} Array of integration objects
34
+ */
35
+ async findIntegrationsByUserId(userId) {
36
+ const integrations = await this.prisma.integration.findMany({
37
+ where: { userId },
38
+ include: {
39
+ entities: true,
40
+ },
41
+ });
42
+
43
+ // Map to domain objects (maintains same API)
44
+ return integrations.map((integration) => ({
45
+ id: integration.id,
46
+ entitiesIds: integration.entities.map((e) => e.id),
47
+ userId: integration.userId,
48
+ config: integration.config,
49
+ version: integration.version,
50
+ status: integration.status,
51
+ messages: integration.messages,
52
+ createdAt: integration.createdAt,
53
+ }));
54
+ }
55
+
56
+ /**
57
+ * Find integrations, optionally filtered by config type and/or status.
58
+ *
59
+ * @param {Object} [filter={}]
60
+ * @param {string} [filter.type] - Integration type (config.type)
61
+ * @param {string} [filter.status] - Integration status
62
+ * @returns {Promise<Array>} Array of integration objects (possibly empty)
63
+ */
64
+ async findIntegrations({ type, status } = {}) {
65
+ const where = {};
66
+ if (type) {
67
+ where.config = { path: ['type'], equals: type };
68
+ }
69
+ if (status) {
70
+ where.status = status;
71
+ }
72
+
73
+ const integrations = await this.prisma.integration.findMany({
74
+ where,
75
+ include: {
76
+ entities: true,
77
+ },
78
+ });
79
+
80
+ return integrations.map((integration) => ({
81
+ id: integration.id,
82
+ entitiesIds: integration.entities.map((e) => e.id),
83
+ userId: integration.userId,
84
+ config: integration.config,
85
+ version: integration.version,
86
+ status: integration.status,
87
+ messages: integration.messages,
88
+ createdAt: integration.createdAt,
89
+ }));
90
+ }
91
+
92
+ /**
93
+ * Find every integration in a report-shaped projection.
94
+ *
95
+ * type lives in config.type (a JSON path not portably groupable across
96
+ * DBs); it is left in the row for the caller to bucket.
97
+ *
98
+ * @param {Object} [filter={}]
99
+ * @param {string} [filter.status] - Integration status
100
+ * @param {string} [filter.userId] - Owning user ID (ObjectId as string)
101
+ * @returns {Promise<Array>} Report-shaped integration rows
102
+ */
103
+ async findAllForReport({ status, userId } = {}) {
104
+ const where = {};
105
+ if (status) where.status = status;
106
+ if (userId !== undefined && userId !== null) where.userId = userId;
107
+
108
+ const integrations = await this.prisma.integration.findMany({
109
+ where,
110
+ include: { entities: { select: { id: true } } },
111
+ });
112
+
113
+ return integrations.map((integration) => ({
114
+ id: integration.id,
115
+ type: integration.config?.type ?? null,
116
+ status: integration.status ?? null,
117
+ userId: integration.userId ?? null,
118
+ version: integration.version ?? null,
119
+ errorCount: Array.isArray(integration.errors)
120
+ ? integration.errors.length
121
+ : 0,
122
+ moduleCount: integration.entities?.length ?? 0,
123
+ createdAt: integration.createdAt ?? null,
124
+ updatedAt: integration.updatedAt ?? null,
125
+ }));
126
+ }
127
+
128
+ /**
129
+ * Delete integration by ID
130
+ * Replaces: IntegrationModel.deleteOne({ _id: integrationId })
131
+ *
132
+ * @param {string} integrationId - Integration ID
133
+ * @returns {Promise<Object>} Deletion result
134
+ */
135
+ async deleteIntegrationById(integrationId) {
136
+ await this.prisma.integration.delete({
137
+ where: { id: integrationId },
138
+ });
139
+
140
+ // Return Mongoose-compatible result
141
+ return { acknowledged: true, deletedCount: 1 };
142
+ }
143
+
144
+ /**
145
+ * Find integration by name
146
+ * Replaces: IntegrationModel.findOne({ 'config.type': name }).populate('entities')
147
+ *
148
+ * @param {string} name - Integration type name
149
+ * @returns {Promise<Object>} Integration object
150
+ */
151
+ async findIntegrationByName(name) {
152
+ const integration = await this.prisma.integration.findFirst({
153
+ where: {
154
+ config: {
155
+ path: ['type'],
156
+ equals: name,
157
+ },
158
+ },
159
+ include: {
160
+ entities: true,
161
+ },
162
+ });
163
+
164
+ if (!integration) {
165
+ throw new Error(`Integration with name ${name} not found`);
166
+ }
167
+
168
+ return {
169
+ id: integration.id,
170
+ entitiesIds: integration.entities.map((e) => e.id),
171
+ userId: integration.userId,
172
+ config: integration.config,
173
+ version: integration.version,
174
+ status: integration.status,
175
+ messages: integration.messages,
176
+ };
177
+ }
178
+
179
+ /**
180
+ * Find integration by ID
181
+ * Replaces: IntegrationModel.findById(id).populate('entities')
182
+ *
183
+ * @param {string} id - Integration ID
184
+ * @returns {Promise<Object>} Integration object
185
+ */
186
+ async findIntegrationById(id) {
187
+ const integration = await this.prisma.integration.findUnique({
188
+ where: { id },
189
+ include: {
190
+ entities: true,
191
+ },
192
+ });
193
+
194
+ if (!integration) {
195
+ throw new Error(`Integration with id ${id} not found`);
196
+ }
197
+
198
+ return {
199
+ id: integration.id,
200
+ entitiesIds: integration.entities.map((e) => e.id),
201
+ userId: integration.userId,
202
+ config: integration.config,
203
+ version: integration.version,
204
+ status: integration.status,
205
+ messages: integration.messages,
206
+ };
207
+ }
208
+
209
+ /**
210
+ * Update integration status
211
+ * Replaces: IntegrationModel.updateOne({ _id: integrationId }, { status })
212
+ *
213
+ * @param {string} integrationId - Integration ID
214
+ * @param {string} status - New status
215
+ * @returns {Promise<boolean>} Success indicator
216
+ */
217
+ async updateIntegrationStatus(integrationId, status) {
218
+ await this.prisma.integration.update({
219
+ where: { id: integrationId },
220
+ data: { status },
221
+ });
222
+
223
+ return true; // Mongoose compatibility
224
+ }
225
+
226
+ /**
227
+ * Update integration messages
228
+ * Replaces: IntegrationModel.updateOne with $push operator
229
+ *
230
+ * @param {string} integrationId - Integration ID
231
+ * @param {string} messageType - Type of message (errors, warnings, info, logs)
232
+ * @param {string} messageTitle - Message title
233
+ * @param {string} messageBody - Message body
234
+ * @param {Date} messageTimestamp - Message timestamp
235
+ * @returns {Promise<boolean>} Success indicator
236
+ */
237
+ async updateIntegrationMessages(
238
+ integrationId,
239
+ messageType,
240
+ messageTitle,
241
+ messageBody,
242
+ messageTimestamp
243
+ ) {
244
+ // Get current integration
245
+ const integration = await this.prisma.integration.findUnique({
246
+ where: { id: integrationId },
247
+ });
248
+
249
+ if (!integration) {
250
+ throw new Error(`Integration ${integrationId} not found`);
251
+ }
252
+
253
+ // Parse existing messages (JSON field)
254
+ const messages = integration.messages || {};
255
+ const messageArray = Array.isArray(messages[messageType])
256
+ ? messages[messageType]
257
+ : [];
258
+
259
+ // Add new message
260
+ messageArray.push({
261
+ title: messageTitle,
262
+ message: messageBody,
263
+ timestamp: messageTimestamp,
264
+ });
265
+
266
+ // Update messages
267
+ await this.prisma.integration.update({
268
+ where: { id: integrationId },
269
+ data: {
270
+ [messageType]: messageArray,
271
+ },
272
+ });
273
+
274
+ return true; // Mongoose compatibility
275
+ }
276
+
277
+ /**
278
+ * Find all integrations whose entity set includes the given entity ID.
279
+ *
280
+ * @param {string} entityId - Entity ID (MongoDB ObjectId as string)
281
+ * @returns {Promise<Array>} Array of integration objects (possibly empty)
282
+ */
283
+ async findIntegrationsByEntityId(entityId) {
284
+ const integrations = await this.prisma.integration.findMany({
285
+ where: {
286
+ entityIds: { has: entityId },
287
+ },
288
+ include: {
289
+ entities: true,
290
+ },
291
+ });
292
+
293
+ return integrations.map((integration) => ({
294
+ id: integration.id,
295
+ entitiesIds: integration.entities.map((e) => e.id),
296
+ userId: integration.userId,
297
+ config: integration.config,
298
+ version: integration.version,
299
+ status: integration.status,
300
+ messages: integration.messages,
301
+ }));
302
+ }
303
+
304
+ /**
305
+ * Create a new integration
306
+ * Replaces: IntegrationModel.create({ entities, user, config })
307
+ *
308
+ * MongoDB-specific: Uses scalar fields for relations
309
+ *
310
+ * @param {Array<string>} entities - Array of entity IDs (MongoDB ObjectIds)
311
+ * @param {string} userId - User ID (MongoDB ObjectId)
312
+ * @param {Object} config - Integration configuration
313
+ * @returns {Promise<Object>} Created integration object
314
+ */
315
+ async createIntegration(entities, userId, config) {
316
+ const data = {
317
+ config,
318
+ version: '0.0.0',
319
+ userId: userId,
320
+ entityIds: entities,
321
+ };
322
+
323
+ const integration = await this.prisma.integration.create({
324
+ data,
325
+ include: {
326
+ entities: true,
327
+ },
328
+ });
329
+
330
+ return {
331
+ id: integration.id,
332
+ entitiesIds: integration.entities.map((e) => e.id),
333
+ userId: integration.userId,
334
+ config: integration.config,
335
+ version: integration.version,
336
+ status: integration.status,
337
+ messages: integration.messages,
338
+ };
339
+ }
340
+
341
+ /**
342
+ * Find integration by user ID (returns single integration)
343
+ * Replaces: IntegrationModel.findOne({ user: userId }).populate('entities')
344
+ *
345
+ * @param {string} userId - User ID
346
+ * @returns {Promise<Object|null>} Integration object or null
347
+ */
348
+ async findIntegrationByUserId(userId) {
349
+ const integration = await this.prisma.integration.findFirst({
350
+ where: { userId },
351
+ include: {
352
+ entities: true,
353
+ },
354
+ });
355
+
356
+ if (!integration) {
357
+ return null;
358
+ }
359
+
360
+ return {
361
+ id: integration.id,
362
+ entitiesIds: integration.entities.map((e) => e.id),
363
+ userId: integration.userId,
364
+ config: integration.config,
365
+ version: integration.version,
366
+ status: integration.status,
367
+ messages: integration.messages,
368
+ };
369
+ }
370
+
371
+ /**
372
+ * Update integration configuration
373
+ * Replaces: IntegrationModel.updateOne({ _id: integrationId }, { config })
374
+ *
375
+ * @param {string} integrationId - Integration ID (MongoDB ObjectId as string)
376
+ * @param {Object} config - Updated configuration object
377
+ * @returns {Promise<Object>} Updated integration object
378
+ */
379
+ async updateIntegrationConfig(integrationId, config) {
380
+ if (config === null || config === undefined) {
381
+ throw new Error('Config parameter is required');
382
+ }
383
+
384
+ const integration = await this.prisma.integration.update({
385
+ where: { id: integrationId },
386
+ data: { config },
387
+ include: {
388
+ entities: true,
389
+ },
390
+ });
391
+
392
+ return {
393
+ id: integration.id,
394
+ entitiesIds: integration.entities.map((e) => e.id),
395
+ userId: integration.userId,
396
+ config: integration.config,
397
+ version: integration.version,
398
+ status: integration.status,
399
+ messages: integration.messages,
400
+ };
401
+ }
402
+
403
+ /**
404
+ * Atomically merge a patch into the existing config via findAndModify,
405
+ * so the write and the post-write read happen in one server-side round
406
+ * trip with no JS-side read-modify-write to race on. entityIds is a
407
+ * scalar array directly on the Integration document in Mongo, so the
408
+ * raw document already carries everything needed to shape the return
409
+ * value — no follow-up findUnique.
410
+ *
411
+ * @param {string} integrationId - Integration ID
412
+ * @param {Object} patch - Keys to merge into the existing config
413
+ * @returns {Promise<Object>} Updated integration object
414
+ */
415
+ async patchIntegrationConfig(integrationId, patch) {
416
+ validateConfigPatch(patch);
417
+
418
+ const $set = {};
419
+ for (const [key, value] of Object.entries(patch)) {
420
+ $set[`config.${key}`] = value;
421
+ }
422
+ $set.updatedAt = new Date();
423
+
424
+ const result = await this.prisma.$runCommandRaw({
425
+ findAndModify: 'Integration',
426
+ query: { _id: { $oid: integrationId } },
427
+ update: { $set },
428
+ new: true,
429
+ });
430
+
431
+ const doc = result && result.value;
432
+ if (!doc) {
433
+ throw new Error(`Integration with id ${integrationId} not found`);
434
+ }
435
+
436
+ return {
437
+ id: doc._id.$oid ?? doc._id,
438
+ entitiesIds: (doc.entityIds || []).map(
439
+ (entityId) => entityId.$oid ?? entityId
440
+ ),
441
+ userId: doc.userId?.$oid ?? doc.userId ?? null,
442
+ config: doc.config,
443
+ version: doc.version,
444
+ status: doc.status,
445
+ messages: doc.messages,
446
+ };
447
+ }
448
+ }
449
+
450
+ module.exports = { IntegrationRepositoryMongo };