@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,183 @@
1
+ const { prisma } = require('../../database/prisma');
2
+ const {
3
+ IntegrationMappingRepositoryInterface,
4
+ } = require('./integration-mapping-repository-interface');
5
+
6
+ /**
7
+ * MongoDB Integration Mapping Repository Adapter
8
+ * Handles persistence of integration mappings used for data transformation
9
+ *
10
+ * MongoDB-specific characteristics:
11
+ * - Uses String IDs (ObjectId)
12
+ * - No ID conversion needed (IDs are already strings)
13
+ * - mapping data stored in JSON field
14
+ */
15
+ class IntegrationMappingRepositoryMongo extends IntegrationMappingRepositoryInterface {
16
+ constructor() {
17
+ super();
18
+ this.prisma = prisma;
19
+ }
20
+
21
+ /**
22
+ * Convert any value to string (handles null/undefined)
23
+ * @private
24
+ * @param {*} value - Value to convert
25
+ * @returns {string|null|undefined} String value or null/undefined
26
+ */
27
+ _toString(value) {
28
+ if (value === null || value === undefined) return value;
29
+ return String(value);
30
+ }
31
+
32
+ /**
33
+ * Find mapping by integration ID and source ID
34
+ * Replaces: IntegrationMapping.findBy(integrationId, sourceId)
35
+ *
36
+ * @param {string} integrationId - The integration ID
37
+ * @param {string} sourceId - The source ID for lookup
38
+ * @returns {Promise<Object|null>} The mapping object with string IDs or null
39
+ */
40
+ async findMappingBy(integrationId, sourceId) {
41
+ return await this.prisma.integrationMapping.findFirst({
42
+ where: {
43
+ integrationId,
44
+ sourceId: this._toString(sourceId),
45
+ },
46
+ });
47
+ }
48
+
49
+ /**
50
+ * Create or update a mapping
51
+ * Replaces: IntegrationMapping.upsert(integrationId, sourceId, mapping)
52
+ *
53
+ * @param {string} integrationId - The integration ID
54
+ * @param {string} sourceId - The source ID for lookup
55
+ * @param {Object} mapping - The mapping data
56
+ * @returns {Promise<Object>} The created or updated mapping document with string IDs
57
+ */
58
+ async upsertMapping(integrationId, sourceId, mapping) {
59
+ return await this.prisma.integrationMapping.upsert({
60
+ where: {
61
+ integrationId_sourceId: {
62
+ integrationId,
63
+ sourceId: this._toString(sourceId),
64
+ },
65
+ },
66
+ update: {
67
+ mapping,
68
+ },
69
+ create: {
70
+ integrationId,
71
+ sourceId: this._toString(sourceId),
72
+ mapping,
73
+ },
74
+ });
75
+ }
76
+
77
+ /**
78
+ * Find all mappings for an integration
79
+ * Replaces: IntegrationMapping.find({ integration: integrationId })
80
+ *
81
+ * @param {string} integrationId - The integration ID
82
+ * @returns {Promise<Array>} Array of mapping documents with string IDs
83
+ */
84
+ async findMappingsByIntegration(integrationId) {
85
+ return await this.prisma.integrationMapping.findMany({
86
+ where: { integrationId },
87
+ });
88
+ }
89
+
90
+ /**
91
+ * Delete a mapping by integration and source ID
92
+ * Replaces: IntegrationMapping.deleteOne({ integration, sourceId })
93
+ *
94
+ * @param {string} integrationId - The integration ID
95
+ * @param {string} sourceId - The source ID
96
+ * @returns {Promise<Object>} The deletion result
97
+ */
98
+ async deleteMapping(integrationId, sourceId) {
99
+ try {
100
+ await this.prisma.integrationMapping.delete({
101
+ where: {
102
+ integrationId_sourceId: {
103
+ integrationId,
104
+ sourceId: this._toString(sourceId),
105
+ },
106
+ },
107
+ });
108
+ return { acknowledged: true, deletedCount: 1 };
109
+ } catch (error) {
110
+ if (error.code === 'P2025') {
111
+ // Record not found
112
+ return { acknowledged: true, deletedCount: 0 };
113
+ }
114
+ throw error;
115
+ }
116
+ }
117
+
118
+ /**
119
+ * Delete all mappings for an integration
120
+ * Replaces: IntegrationMapping.deleteMany({ integration: integrationId })
121
+ *
122
+ * @param {string} integrationId - The integration ID
123
+ * @returns {Promise<Object>} The deletion result
124
+ */
125
+ async deleteMappingsByIntegration(integrationId) {
126
+ const result = await this.prisma.integrationMapping.deleteMany({
127
+ where: { integrationId },
128
+ });
129
+
130
+ return {
131
+ acknowledged: true,
132
+ deletedCount: result.count,
133
+ };
134
+ }
135
+
136
+ /**
137
+ * Count mappings grouped by integration id for a bounded id set.
138
+ *
139
+ * @param {Array<string>} ids - Integration ids
140
+ * @returns {Promise<Map<string, number>>} integrationId (string) → count
141
+ */
142
+ async countByIntegrationIds(ids = []) {
143
+ const counts = new Map();
144
+ if (!ids || ids.length === 0) return counts;
145
+
146
+ const groups = await this.prisma.integrationMapping.groupBy({
147
+ by: ['integrationId'],
148
+ where: { integrationId: { in: ids } },
149
+ _count: { _all: true },
150
+ });
151
+
152
+ for (const group of groups) {
153
+ counts.set(String(group.integrationId), group._count._all);
154
+ }
155
+ return counts;
156
+ }
157
+
158
+ /**
159
+ * Find mapping by ID
160
+ * @param {string} id - Mapping ID
161
+ * @returns {Promise<Object|null>} Mapping object with string IDs or null
162
+ */
163
+ async findMappingById(id) {
164
+ return await this.prisma.integrationMapping.findUnique({
165
+ where: { id },
166
+ });
167
+ }
168
+
169
+ /**
170
+ * Update mapping by ID
171
+ * @param {string} id - Mapping ID
172
+ * @param {Object} updates - Fields to update
173
+ * @returns {Promise<Object>} Updated mapping object with string IDs
174
+ */
175
+ async updateMapping(id, updates) {
176
+ return await this.prisma.integrationMapping.update({
177
+ where: { id },
178
+ data: updates,
179
+ });
180
+ }
181
+ }
182
+
183
+ module.exports = { IntegrationMappingRepositoryMongo };
@@ -0,0 +1,255 @@
1
+ const { prisma } = require('../../database/prisma');
2
+ const {
3
+ IntegrationMappingRepositoryInterface,
4
+ } = require('./integration-mapping-repository-interface');
5
+ const { strictIntId } = require('./report-id');
6
+
7
+ /**
8
+ * PostgreSQL Integration Mapping Repository Adapter
9
+ * Handles persistence of integration mappings used for data transformation
10
+ *
11
+ * PostgreSQL-specific characteristics:
12
+ * - Uses Int IDs with autoincrement
13
+ * - Requires ID conversion: String (app layer) ↔ Int (database)
14
+ * - All returned IDs are converted to strings for application layer consistency
15
+ */
16
+ class IntegrationMappingRepositoryPostgres extends IntegrationMappingRepositoryInterface {
17
+ constructor() {
18
+ super();
19
+ this.prisma = prisma;
20
+ }
21
+
22
+ /**
23
+ * Convert string ID to integer for PostgreSQL queries
24
+ * @private
25
+ * @param {string|number|null|undefined} id - ID to convert
26
+ * @returns {number|null|undefined} Integer ID or null/undefined
27
+ * @throws {Error} If ID cannot be converted to integer
28
+ */
29
+ _stringToInt(id) {
30
+ if (id === null || id === undefined) return id;
31
+ const parsed = parseInt(id, 10);
32
+ if (isNaN(parsed)) {
33
+ throw new Error(`Invalid ID: ${id} cannot be converted to integer`);
34
+ }
35
+ return parsed;
36
+ }
37
+
38
+ /**
39
+ * Convert any value to string (handles null/undefined)
40
+ * @private
41
+ * @param {*} value - Value to convert
42
+ * @returns {string|null|undefined} String value or null/undefined
43
+ */
44
+ _toString(value) {
45
+ if (value === null || value === undefined) return value;
46
+ return String(value);
47
+ }
48
+
49
+ /**
50
+ * Convert integer to string for application layer
51
+ * @private
52
+ * @param {number|null|undefined} id - Integer ID from database
53
+ * @returns {string|null|undefined} String ID or null/undefined
54
+ */
55
+ _intToString(id) {
56
+ if (id === null || id === undefined) return id;
57
+ return id.toString();
58
+ }
59
+
60
+ /**
61
+ * Legacy alias for _stringToInt (for backward compatibility)
62
+ * @private
63
+ */
64
+ _convertId(id) {
65
+ return this._stringToInt(id);
66
+ }
67
+
68
+ /**
69
+ * Convert mapping object IDs to strings
70
+ * @private
71
+ * @param {Object|null} mapping - Mapping object from database
72
+ * @returns {Object|null} Mapping with string IDs
73
+ */
74
+ _convertMappingIds(mapping) {
75
+ if (!mapping) return mapping;
76
+ return {
77
+ ...mapping,
78
+ id: this._intToString(mapping.id),
79
+ integrationId: this._intToString(mapping.integrationId),
80
+ };
81
+ }
82
+
83
+ /**
84
+ * Find mapping by integration ID and source ID
85
+ * Replaces: IntegrationMapping.findBy(integrationId, sourceId)
86
+ *
87
+ * @param {string} integrationId - The integration ID (string from application layer)
88
+ * @param {string} sourceId - The source ID for lookup
89
+ * @returns {Promise<Object|null>} The mapping object with string IDs or null
90
+ */
91
+ async findMappingBy(integrationId, sourceId) {
92
+ const mapping = await this.prisma.integrationMapping.findFirst({
93
+ where: {
94
+ integrationId: this._stringToInt(integrationId),
95
+ sourceId: this._toString(sourceId),
96
+ },
97
+ });
98
+ return this._convertMappingIds(mapping);
99
+ }
100
+
101
+ /**
102
+ * Create or update a mapping
103
+ * Replaces: IntegrationMapping.upsert(integrationId, sourceId, mapping)
104
+ *
105
+ * @param {string} integrationId - The integration ID (string from application layer)
106
+ * @param {string} sourceId - The source ID for lookup
107
+ * @param {Object} mapping - The mapping data
108
+ * @returns {Promise<Object>} The created or updated mapping document with string IDs
109
+ */
110
+ async upsertMapping(integrationId, sourceId, mapping) {
111
+ const result = await this.prisma.integrationMapping.upsert({
112
+ where: {
113
+ integrationId_sourceId: {
114
+ integrationId: this._stringToInt(integrationId),
115
+ sourceId: this._toString(sourceId),
116
+ },
117
+ },
118
+ update: {
119
+ mapping,
120
+ },
121
+ create: {
122
+ integrationId: this._stringToInt(integrationId),
123
+ sourceId: this._toString(sourceId),
124
+ mapping,
125
+ },
126
+ });
127
+ return this._convertMappingIds(result);
128
+ }
129
+
130
+ /**
131
+ * Find all mappings for an integration
132
+ * Replaces: IntegrationMapping.find({ integration: integrationId })
133
+ *
134
+ * @param {string} integrationId - The integration ID (string from application layer)
135
+ * @returns {Promise<Array>} Array of mapping documents with string IDs
136
+ */
137
+ async findMappingsByIntegration(integrationId) {
138
+ const intIntegrationId = this._convertId(integrationId);
139
+ const mappings = await this.prisma.integrationMapping.findMany({
140
+ where: { integrationId: intIntegrationId },
141
+ });
142
+ return mappings.map((m) => this._convertMappingIds(m));
143
+ }
144
+
145
+ /**
146
+ * Delete a mapping by integration and source ID
147
+ * Replaces: IntegrationMapping.deleteOne({ integration, sourceId })
148
+ *
149
+ * @param {string} integrationId - The integration ID (string from application layer)
150
+ * @param {string} sourceId - The source ID
151
+ * @returns {Promise<Object>} The deletion result
152
+ */
153
+ async deleteMapping(integrationId, sourceId) {
154
+ try {
155
+ await this.prisma.integrationMapping.delete({
156
+ where: {
157
+ integrationId_sourceId: {
158
+ integrationId: this._stringToInt(integrationId),
159
+ sourceId: this._toString(sourceId),
160
+ },
161
+ },
162
+ });
163
+ return { acknowledged: true, deletedCount: 1 };
164
+ } catch (error) {
165
+ if (error.code === 'P2025') {
166
+ // Record not found
167
+ return { acknowledged: true, deletedCount: 0 };
168
+ }
169
+ throw error;
170
+ }
171
+ }
172
+
173
+ /**
174
+ * Delete all mappings for an integration
175
+ * Replaces: IntegrationMapping.deleteMany({ integration: integrationId })
176
+ *
177
+ * @param {string} integrationId - The integration ID (string from application layer)
178
+ * @returns {Promise<Object>} The deletion result
179
+ */
180
+ async deleteMappingsByIntegration(integrationId) {
181
+ const intIntegrationId = this._convertId(integrationId);
182
+ const result = await this.prisma.integrationMapping.deleteMany({
183
+ where: { integrationId: intIntegrationId },
184
+ });
185
+
186
+ return {
187
+ acknowledged: true,
188
+ deletedCount: result.count,
189
+ };
190
+ }
191
+
192
+ /**
193
+ * Count mappings grouped by integration id for a bounded id set.
194
+ *
195
+ * @param {Array<string|number>} ids - Integration ids
196
+ * @returns {Promise<Map<string, number>>} integrationId (string) → count
197
+ */
198
+ async countByIntegrationIds(ids = []) {
199
+ const counts = new Map();
200
+ if (!ids || ids.length === 0) return counts;
201
+
202
+ // Strict (matches findAllForReport): reject partially-numeric ids instead of coercing.
203
+ const intIds = ids.map((id) => strictIntId(id));
204
+ const groups = await this.prisma.integrationMapping.groupBy({
205
+ by: ['integrationId'],
206
+ where: { integrationId: { in: intIds } },
207
+ _count: { _all: true },
208
+ });
209
+
210
+ for (const group of groups) {
211
+ counts.set(
212
+ this._intToString(group.integrationId),
213
+ group._count._all
214
+ );
215
+ }
216
+ return counts;
217
+ }
218
+
219
+ /**
220
+ * Find mapping by ID
221
+ * @param {string} id - Mapping ID (string from application layer)
222
+ * @returns {Promise<Object|null>} Mapping object with string IDs or null
223
+ */
224
+ async findMappingById(id) {
225
+ const intId = this._convertId(id);
226
+ const mapping = await this.prisma.integrationMapping.findUnique({
227
+ where: { id: intId },
228
+ });
229
+ return this._convertMappingIds(mapping);
230
+ }
231
+
232
+ /**
233
+ * Update mapping by ID
234
+ * @param {string} id - Mapping ID (string from application layer)
235
+ * @param {Object} updates - Fields to update (with string IDs from application layer)
236
+ * @returns {Promise<Object>} Updated mapping object with string IDs
237
+ */
238
+ async updateMapping(id, updates) {
239
+ const intId = this._convertId(id);
240
+
241
+ // Convert integrationId if present in updates
242
+ const data = { ...updates };
243
+ if (data.integrationId !== undefined) {
244
+ data.integrationId = this._convertId(data.integrationId);
245
+ }
246
+
247
+ const mapping = await this.prisma.integrationMapping.update({
248
+ where: { id: intId },
249
+ data,
250
+ });
251
+ return this._convertMappingIds(mapping);
252
+ }
253
+ }
254
+
255
+ module.exports = { IntegrationMappingRepositoryPostgres };
@@ -0,0 +1,156 @@
1
+ const { prisma } = require('../../database/prisma');
2
+ const {
3
+ IntegrationMappingRepositoryInterface,
4
+ } = require('./integration-mapping-repository-interface');
5
+
6
+ /**
7
+ * Prisma-based Integration Mapping Repository
8
+ * Handles persistence of integration mappings used for data transformation
9
+ *
10
+ * Works identically for both MongoDB and PostgreSQL:
11
+ * - MongoDB: String IDs with @db.ObjectId
12
+ * - PostgreSQL: Integer IDs with auto-increment
13
+ * - Both use same query patterns (no many-to-many differences)
14
+ *
15
+ * Migration from Mongoose:
16
+ * - Constructor injection of Prisma client
17
+ * - IntegrationMapping.findBy() → findFirst with where clause
18
+ * - IntegrationMapping.upsert() → Prisma upsert with unique constraint
19
+ * - mapping data stored in JSON field
20
+ */
21
+ class IntegrationMappingRepository extends IntegrationMappingRepositoryInterface {
22
+ constructor(prismaClient = prisma) {
23
+ super();
24
+ this.prisma = prismaClient; // Allow injection for testing
25
+ }
26
+
27
+ /**
28
+ * Find mapping by integration ID and source ID
29
+ * Replaces: IntegrationMapping.findBy(integrationId, sourceId)
30
+ *
31
+ * @param {string} integrationId - The integration ID
32
+ * @param {string} sourceId - The source ID for lookup
33
+ * @returns {Promise<Object|null>} The mapping object or null
34
+ */
35
+ async findMappingBy(integrationId, sourceId) {
36
+ return await this.prisma.integrationMapping.findFirst({
37
+ where: {
38
+ integrationId,
39
+ sourceId,
40
+ },
41
+ });
42
+ }
43
+
44
+ /**
45
+ * Create or update a mapping
46
+ * Replaces: IntegrationMapping.upsert(integrationId, sourceId, mapping)
47
+ *
48
+ * @param {string} integrationId - The integration ID
49
+ * @param {string} sourceId - The source ID for lookup
50
+ * @param {Object} mapping - The mapping data
51
+ * @returns {Promise<Object>} The created or updated mapping document
52
+ */
53
+ async upsertMapping(integrationId, sourceId, mapping) {
54
+ return await this.prisma.integrationMapping.upsert({
55
+ where: {
56
+ integrationId_sourceId: {
57
+ integrationId,
58
+ sourceId,
59
+ },
60
+ },
61
+ update: {
62
+ mapping,
63
+ },
64
+ create: {
65
+ integrationId,
66
+ sourceId,
67
+ mapping,
68
+ },
69
+ });
70
+ }
71
+
72
+ /**
73
+ * Find all mappings for an integration
74
+ * Replaces: IntegrationMapping.find({ integration: integrationId })
75
+ *
76
+ * @param {string} integrationId - The integration ID
77
+ * @returns {Promise<Array>} Array of mapping documents
78
+ */
79
+ async findMappingsByIntegration(integrationId) {
80
+ return await this.prisma.integrationMapping.findMany({
81
+ where: { integrationId },
82
+ });
83
+ }
84
+
85
+ /**
86
+ * Delete a mapping by integration and source ID
87
+ * Replaces: IntegrationMapping.deleteOne({ integration, sourceId })
88
+ *
89
+ * @param {string} integrationId - The integration ID
90
+ * @param {string} sourceId - The source ID
91
+ * @returns {Promise<Object>} The deletion result
92
+ */
93
+ async deleteMapping(integrationId, sourceId) {
94
+ try {
95
+ await this.prisma.integrationMapping.delete({
96
+ where: {
97
+ integrationId_sourceId: {
98
+ integrationId,
99
+ sourceId,
100
+ },
101
+ },
102
+ });
103
+ return { acknowledged: true, deletedCount: 1 };
104
+ } catch (error) {
105
+ if (error.code === 'P2025') {
106
+ // Record not found
107
+ return { acknowledged: true, deletedCount: 0 };
108
+ }
109
+ throw error;
110
+ }
111
+ }
112
+
113
+ /**
114
+ * Delete all mappings for an integration
115
+ * Replaces: IntegrationMapping.deleteMany({ integration: integrationId })
116
+ *
117
+ * @param {string} integrationId - The integration ID
118
+ * @returns {Promise<Object>} The deletion result
119
+ */
120
+ async deleteMappingsByIntegration(integrationId) {
121
+ const result = await this.prisma.integrationMapping.deleteMany({
122
+ where: { integrationId },
123
+ });
124
+
125
+ return {
126
+ acknowledged: true,
127
+ deletedCount: result.count,
128
+ };
129
+ }
130
+
131
+ /**
132
+ * Find mapping by ID
133
+ * @param {string} id - Mapping ID
134
+ * @returns {Promise<Object|null>} Mapping object or null
135
+ */
136
+ async findMappingById(id) {
137
+ return await this.prisma.integrationMapping.findUnique({
138
+ where: { id },
139
+ });
140
+ }
141
+
142
+ /**
143
+ * Update mapping by ID
144
+ * @param {string} id - Mapping ID
145
+ * @param {Object} updates - Fields to update
146
+ * @returns {Promise<Object>} Updated mapping object
147
+ */
148
+ async updateMapping(id, updates) {
149
+ return await this.prisma.integrationMapping.update({
150
+ where: { id },
151
+ data: updates,
152
+ });
153
+ }
154
+ }
155
+
156
+ module.exports = { IntegrationMappingRepository };