@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,427 @@
1
+ /**
2
+ * Database Migration Lambda Handler
3
+ *
4
+ * Lambda function that runs Prisma database migrations from within the VPC,
5
+ * enabling CI/CD pipelines to migrate databases without requiring public access.
6
+ *
7
+ * This handler uses the prisma-runner utilities from @friggframework/core,
8
+ * ensuring consistency with the `frigg db:setup` command.
9
+ *
10
+ * Environment Variables Required:
11
+ * - DATABASE_URL: Database connection string (automatically set from Secrets Manager)
12
+ * - DB_TYPE: Database type ('postgresql', 'mongodb', or 'documentdb')
13
+ * - STAGE: Deployment stage (determines migration command: 'dev' or 'deploy')
14
+ *
15
+ * Invocation:
16
+ * aws lambda invoke \
17
+ * --function-name my-app-production-dbMigrate \
18
+ * --region us-east-1 \
19
+ * response.json
20
+ *
21
+ * Success Response:
22
+ * {
23
+ * "statusCode": 200,
24
+ * "body": {
25
+ * "success": true,
26
+ * "message": "Database migration completed successfully",
27
+ * "dbType": "postgresql",
28
+ * "stage": "production",
29
+ * "migrationCommand": "deploy"
30
+ * }
31
+ * }
32
+ *
33
+ * Error Response:
34
+ * {
35
+ * "statusCode": 500,
36
+ * "body": {
37
+ * "success": false,
38
+ * "error": "Migration failed: ...",
39
+ * "stack": "Error: ..."
40
+ * }
41
+ * }
42
+ */
43
+
44
+ const {
45
+ RunDatabaseMigrationUseCase,
46
+ MigrationError,
47
+ ValidationError,
48
+ } = require('../../database/use-cases/run-database-migration-use-case');
49
+ const {
50
+ CheckDatabaseStateUseCase,
51
+ } = require('../../database/use-cases/check-database-state-use-case');
52
+ const {
53
+ MigrationStatusRepositoryS3,
54
+ } = require('../../database/repositories/migration-status-repository-s3');
55
+
56
+ // Inject prisma-runner as dependency
57
+ const prismaRunner = require('../../database/utils/prisma-runner');
58
+
59
+ // Use S3 repository for migration status tracking (no User table dependency)
60
+ const bucketName = process.env.S3_BUCKET_NAME || process.env.MIGRATION_STATUS_BUCKET;
61
+ const migrationStatusRepository = new MigrationStatusRepositoryS3(bucketName);
62
+
63
+ /**
64
+ * Sanitizes error messages to prevent credential leaks
65
+ * @param {string} errorMessage - Error message that might contain credentials
66
+ * @returns {string} Sanitized error message
67
+ */
68
+ function sanitizeError(errorMessage) {
69
+ if (!errorMessage) return 'Unknown error';
70
+
71
+ return String(errorMessage)
72
+ // Remove PostgreSQL connection strings
73
+ .replace(/postgresql:\/\/[^@\s]+@[^\s/]+/gi, 'postgresql://***:***@***')
74
+ // Remove MongoDB connection strings
75
+ .replace(/mongodb(\+srv)?:\/\/[^@\s]+@[^\s/]+/gi, 'mongodb$1://***:***@***')
76
+ // Remove password parameters
77
+ .replace(/password[=:]\s*[^\s,;)]+/gi, 'password=***')
78
+ // Remove API keys
79
+ .replace(/apikey[=:]\s*[^\s,;)]+/gi, 'apikey=***')
80
+ .replace(/api[_-]?key[=:]\s*[^\s,;)]+/gi, 'api_key=***')
81
+ // Remove tokens
82
+ .replace(/token[=:]\s*[^\s,;)]+/gi, 'token=***')
83
+ .replace(/bearer\s+[^\s,;)]+/gi, 'bearer ***');
84
+ }
85
+
86
+ /**
87
+ * Sanitizes DATABASE_URL for safe logging
88
+ * @param {string} url - Database URL
89
+ * @returns {string} Sanitized URL
90
+ */
91
+ function sanitizeDatabaseUrl(url) {
92
+ if (!url) return '';
93
+
94
+ // Replace credentials in connection string
95
+ return url.replace(/(:\/\/)([^:]+):([^@]+)@/, '$1***:***@');
96
+ }
97
+
98
+ /**
99
+ * Extract migration parameters from SQS event or direct invocation
100
+ * @param {Object} event - Lambda event (SQS or direct)
101
+ * @returns {Object} Extracted parameters { migrationId, dbType, stage }
102
+ */
103
+ function extractMigrationParams(event) {
104
+ let migrationId = null;
105
+ let stage = null;
106
+ let dbType = process.env.DB_TYPE || 'postgresql';
107
+
108
+ // Check if this is an SQS event
109
+ if (event.Records && event.Records.length > 0) {
110
+ // SQS event - extract from message body
111
+ const message = JSON.parse(event.Records[0].body);
112
+ migrationId = message.migrationId;
113
+ stage = message.stage || process.env.STAGE || 'production';
114
+ dbType = message.dbType || dbType;
115
+
116
+ console.log('SQS event detected');
117
+ console.log(` Migration ID: ${migrationId}`);
118
+ console.log(` DB Type: ${dbType}`);
119
+ console.log(` Stage: ${stage}`);
120
+ } else {
121
+ // Direct invocation - use event properties or environment variables
122
+ migrationId = event.migrationId || null;
123
+ stage = event.stage || process.env.STAGE || 'production';
124
+ dbType = event.dbType || dbType;
125
+
126
+ console.log('Direct invocation detected');
127
+ if (migrationId) {
128
+ console.log(` Migration ID: ${migrationId}`);
129
+ }
130
+ console.log(` DB Type: ${dbType}`);
131
+ console.log(` Stage: ${stage}`);
132
+ }
133
+
134
+ return { migrationId, dbType, stage };
135
+ }
136
+
137
+ /**
138
+ * Lambda handler entry point
139
+ * @param {Object} event - Lambda event (SQS message or direct invocation)
140
+ * @param {Object} context - Lambda context (contains AWS request ID, timeout info)
141
+ * @returns {Promise<Object>} Response with statusCode and body
142
+ */
143
+ exports.handler = async (event, context) => {
144
+ console.log('========================================');
145
+ console.log('Database Migration Lambda Started');
146
+ console.log('========================================');
147
+ console.log('Event:', JSON.stringify(event, null, 2));
148
+ console.log('Context:', JSON.stringify({
149
+ requestId: context.requestId,
150
+ functionName: context.functionName,
151
+ remainingTimeInMillis: context.getRemainingTimeInMillis(),
152
+ }, null, 2));
153
+
154
+ // Extract migration parameters from event
155
+ const { migrationId, dbType, stage } = extractMigrationParams(event);
156
+
157
+ // Check for action parameter (direct invocation for status checks)
158
+ const action = event.action || 'migrate'; // Default to migration
159
+
160
+ // Handle checkStatus action
161
+ if (action === 'checkStatus') {
162
+ console.log(`\n========================================`);
163
+ console.log(`Action: checkStatus (dbType=${dbType}, stage=${stage})`);
164
+ console.log(`========================================`);
165
+
166
+ try {
167
+ const checkDbStateUseCase = new CheckDatabaseStateUseCase({ prismaRunner });
168
+ const status = await checkDbStateUseCase.execute(dbType, stage);
169
+
170
+ console.log('✓ Database state check completed');
171
+ console.log(` Up to date: ${status.upToDate}`);
172
+ console.log(` Pending migrations: ${status.pendingMigrations}`);
173
+
174
+ return {
175
+ statusCode: 200,
176
+ body: status,
177
+ };
178
+ } catch (error) {
179
+ console.error('❌ Database state check failed:', error.message);
180
+ return {
181
+ statusCode: 500,
182
+ body: {
183
+ success: false,
184
+ error: sanitizeError(error.message),
185
+ upToDate: false,
186
+ },
187
+ };
188
+ }
189
+ }
190
+
191
+ if (action === 'resolve') {
192
+ const { migrationName, resolveAction = 'applied' } = event;
193
+ console.log(`\n========================================`);
194
+ console.log(
195
+ `Action: resolve (migration=${migrationName}, mode=${resolveAction})`
196
+ );
197
+ console.log(`========================================`);
198
+
199
+ if (!migrationName) {
200
+ return {
201
+ statusCode: 400,
202
+ body: { success: false, error: 'migrationName is required' },
203
+ };
204
+ }
205
+ if (!/^\d{14}_[a-z0-9_]+$/i.test(migrationName)) {
206
+ return {
207
+ statusCode: 400,
208
+ body: {
209
+ success: false,
210
+ error: 'migrationName is not a valid migration identifier',
211
+ },
212
+ };
213
+ }
214
+ if (!['applied', 'rolled-back'].includes(resolveAction)) {
215
+ return {
216
+ statusCode: 400,
217
+ body: {
218
+ success: false,
219
+ error: 'resolveAction must be "applied" or "rolled-back"',
220
+ },
221
+ };
222
+ }
223
+ if (dbType !== 'postgresql') {
224
+ return {
225
+ statusCode: 400,
226
+ body: {
227
+ success: false,
228
+ error: `Migration resolve is only supported for postgresql, not "${dbType}"`,
229
+ },
230
+ };
231
+ }
232
+
233
+ try {
234
+ const result = await prismaRunner.runPrismaMigrateResolve(
235
+ migrationName,
236
+ resolveAction,
237
+ true
238
+ );
239
+ if (!result.success) {
240
+ return {
241
+ statusCode: 500,
242
+ body: {
243
+ success: false,
244
+ error: sanitizeError(result.error),
245
+ },
246
+ };
247
+ }
248
+ return {
249
+ statusCode: 200,
250
+ body: {
251
+ success: true,
252
+ message: `Migration ${migrationName} marked as ${resolveAction}`,
253
+ migrationName,
254
+ action: resolveAction,
255
+ },
256
+ };
257
+ } catch (error) {
258
+ console.error('❌ Migration resolve failed:', error.message);
259
+ return {
260
+ statusCode: 500,
261
+ body: { success: false, error: sanitizeError(error.message) },
262
+ };
263
+ }
264
+ }
265
+
266
+ // Otherwise, handle migration (existing code)
267
+ console.log(`\n========================================`);
268
+ console.log(`Action: migrate (migrationId=${migrationId || 'new'})`);
269
+ console.log(`========================================`);
270
+
271
+ // Get environment variables
272
+ const databaseUrl = process.env.DATABASE_URL;
273
+
274
+ try {
275
+ // Validate DATABASE_URL is set
276
+ if (!databaseUrl) {
277
+ const error = 'DATABASE_URL environment variable is not set';
278
+ console.error('❌ Validation failed:', error);
279
+ return {
280
+ statusCode: 500,
281
+ body: JSON.stringify({
282
+ success: false,
283
+ error,
284
+ }),
285
+ };
286
+ }
287
+
288
+ console.log('✓ Environment validated');
289
+ console.log(` Database Type: ${dbType}`);
290
+ console.log(` Stage: ${stage}`);
291
+ console.log(` Database URL: ${sanitizeDatabaseUrl(databaseUrl)}`);
292
+
293
+ // Update migration status to RUNNING (if migrationId provided)
294
+ if (migrationId) {
295
+ console.log(`\n✓ Updating migration status to RUNNING: ${migrationId}`);
296
+ await migrationStatusRepository.update({
297
+ migrationId,
298
+ stage,
299
+ state: 'RUNNING',
300
+ progress: 10,
301
+ startedAt: new Date().toISOString(),
302
+ });
303
+ }
304
+
305
+ // Create use case with dependencies (Dependency Injection)
306
+ const runDatabaseMigrationUseCase = new RunDatabaseMigrationUseCase({
307
+ prismaRunner,
308
+ });
309
+
310
+ console.log('\n========================================');
311
+ console.log('Executing Database Migration');
312
+ console.log('========================================');
313
+
314
+ // Execute use case (business logic layer)
315
+ const result = await runDatabaseMigrationUseCase.execute({
316
+ dbType,
317
+ stage,
318
+ verbose: true, // Enable verbose output for Lambda CloudWatch logs
319
+ });
320
+
321
+ console.log('✓ Database migration completed successfully');
322
+ console.log('\n========================================');
323
+ console.log('Migration Summary');
324
+ console.log('========================================');
325
+ console.log(` Status: Success`);
326
+ console.log(` Database: ${result.dbType}`);
327
+ console.log(` Stage: ${result.stage}`);
328
+ console.log(` Command: ${result.command}`);
329
+ console.log('========================================');
330
+
331
+ // Update migration status to COMPLETED (if migrationId provided)
332
+ if (migrationId) {
333
+ console.log(`\n✓ Updating migration status to COMPLETED: ${migrationId}`);
334
+ await migrationStatusRepository.update({
335
+ migrationId,
336
+ stage,
337
+ state: 'COMPLETED',
338
+ progress: 100,
339
+ completedAt: new Date().toISOString(),
340
+ migrationCommand: result.command,
341
+ });
342
+ }
343
+
344
+ // Return success response (adapter layer - HTTP mapping)
345
+ const responseBody = {
346
+ success: true,
347
+ message: result.message,
348
+ dbType: result.dbType,
349
+ stage: result.stage,
350
+ migrationCommand: result.command,
351
+ timestamp: new Date().toISOString(),
352
+ };
353
+
354
+ if (migrationId) {
355
+ responseBody.migrationId = migrationId;
356
+ }
357
+
358
+ return {
359
+ statusCode: 200,
360
+ body: JSON.stringify(responseBody),
361
+ };
362
+
363
+ } catch (error) {
364
+ console.error('\n========================================');
365
+ console.error('Migration Failed');
366
+ console.error('========================================');
367
+ console.error('Error:', error.name, error.message);
368
+
369
+ // Log full stack trace to CloudWatch (only visible to developers)
370
+ if (error.stack) {
371
+ console.error('Stack:', error.stack);
372
+ }
373
+
374
+ // Log context if available (from MigrationError)
375
+ if (error.context) {
376
+ console.error('Context:', JSON.stringify(error.context, null, 2));
377
+ }
378
+
379
+ // Map domain errors to HTTP status codes (adapter layer)
380
+ let statusCode = 500;
381
+ let errorMessage = error.message || 'Unknown error occurred';
382
+
383
+ if (error instanceof ValidationError) {
384
+ statusCode = 400; // Bad Request for validation errors
385
+ } else if (error instanceof MigrationError) {
386
+ statusCode = 500; // Internal Server Error for migration failures
387
+ }
388
+
389
+ // Sanitize error message before returning
390
+ const sanitizedError = sanitizeError(errorMessage);
391
+
392
+ // Update migration status to FAILED (if migrationId provided)
393
+ if (migrationId) {
394
+ try {
395
+ console.log(`\n✓ Updating migration status to FAILED: ${migrationId}`);
396
+ await migrationStatusRepository.update({
397
+ migrationId,
398
+ stage,
399
+ state: 'FAILED',
400
+ progress: 0,
401
+ error: sanitizedError,
402
+ failedAt: new Date().toISOString(),
403
+ });
404
+ } catch (updateError) {
405
+ console.error('Failed to update migration status:', updateError.message);
406
+ // Continue - don't let status update failure block error response
407
+ }
408
+ }
409
+
410
+ const errorBody = {
411
+ success: false,
412
+ error: sanitizedError,
413
+ errorType: error.name || 'Error',
414
+ // Only include stack traces in development environments
415
+ ...(stage === 'dev' || stage === 'local' || stage === 'test' ? { stack: error.stack } : {}),
416
+ };
417
+
418
+ if (migrationId) {
419
+ errorBody.migrationId = migrationId;
420
+ }
421
+
422
+ return {
423
+ statusCode,
424
+ body: JSON.stringify(errorBody),
425
+ };
426
+ }
427
+ };
@@ -0,0 +1,63 @@
1
+ /**
2
+ * DLQ Processor — logs failed messages from the InternalErrorQueue
3
+ * with structured context for monitoring and debugging.
4
+ *
5
+ * This handler MUST NOT throw. If it throws, the message goes back to
6
+ * the DLQ and creates an infinite loop. All errors are caught and logged.
7
+ */
8
+
9
+ function extractQueueName(eventSourceARN) {
10
+ if (!eventSourceARN) return 'UNKNOWN';
11
+ const parts = eventSourceARN.split(':');
12
+ return parts[parts.length - 1] || 'UNKNOWN';
13
+ }
14
+
15
+ function parseMessageBody(body) {
16
+ try {
17
+ const parsed = JSON.parse(body);
18
+ return {
19
+ event: parsed.event || 'UNKNOWN',
20
+ integrationId: parsed.data?.integrationId || null,
21
+ processId: parsed.data?.processId || null,
22
+ data: parsed.data,
23
+ };
24
+ } catch (error) {
25
+ console.warn('[DLQ] Failed to parse message body', { error: error.message, body });
26
+ return {
27
+ event: 'UNKNOWN',
28
+ integrationId: null,
29
+ processId: null,
30
+ rawBody: body,
31
+ };
32
+ }
33
+ }
34
+
35
+ async function dlqProcessor(event) {
36
+ if (!event?.Records?.length) return { batchItemFailures: [] };
37
+
38
+ for (const record of event.Records) {
39
+ try {
40
+ const parsed = parseMessageBody(record.body);
41
+
42
+ console.error('[DLQ] Failed message', {
43
+ messageId: record.messageId,
44
+ event: parsed.event,
45
+ integrationId: parsed.integrationId,
46
+ processId: parsed.processId,
47
+ receiveCount: record.attributes?.ApproximateReceiveCount,
48
+ sentTimestamp: record.attributes?.SentTimestamp,
49
+ sourceQueue: extractQueueName(record.eventSourceARN),
50
+ ...(parsed.rawBody !== undefined && { rawBody: parsed.rawBody }),
51
+ });
52
+ } catch (error) {
53
+ console.error('[DLQ] Error processing DLQ record', {
54
+ messageId: record.messageId,
55
+ error: error.message,
56
+ });
57
+ }
58
+ }
59
+
60
+ return { batchItemFailures: [] };
61
+ }
62
+
63
+ module.exports = { dlqProcessor };
@@ -1,8 +1,18 @@
1
1
  const { createHandler } = require('@friggframework/core');
2
- const { integrationFactory, createQueueWorker } = require('../backend-utils');
2
+ const { loadAppDefinition } = require('../app-definition-loader');
3
+ const { createQueueWorker } = require('../backend-utils');
4
+ // TODO(Phase 2): mount extension-declared workers in addition to the per-integration
5
+ // default queue worker. Today, getExtensionWorkers(IntegrationClass) returns the
6
+ // declared workers but they are not yet bound to dedicated SQS sources. Extension-
7
+ // contributed *events* still flow through the default queue worker below because
8
+ // _mergeExtensions() registers them in instance.events, so end-to-end webhook
9
+ // delivery for Tier 3 extensions works without this Phase 2 work.
10
+ // const { getExtensionWorkers } = require('../../integrations/extension');
3
11
 
4
12
  const handlers = {};
5
- integrationFactory.integrationClasses.forEach((IntegrationClass) => {
13
+ const { integrations: integrationClasses } = loadAppDefinition();
14
+
15
+ integrationClasses.forEach((IntegrationClass) => {
6
16
  const defaultQueueWorker = createQueueWorker(IntegrationClass);
7
17
 
8
18
  handlers[`${IntegrationClass.Definition.name}`] = {
@@ -11,11 +21,7 @@ integrationFactory.integrationClasses.forEach((IntegrationClass) => {
11
21
  isUserFacingResponse: false,
12
22
  method: async (event, context) => {
13
23
  const worker = new defaultQueueWorker();
14
- await worker.run(event, context);
15
- return {
16
- message: 'Successfully processed the Generic Queue Worker',
17
- input: event,
18
- };
24
+ return await worker.run(event, context);
19
25
  },
20
26
  }),
21
27
  };