@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,312 @@
1
+ const {
2
+ createUserRepository,
3
+ } = require('../../user/repositories/user-repository-factory');
4
+
5
+ const ERROR_CODE_MAP = {
6
+ USER_NOT_FOUND: 404,
7
+ USER_ALREADY_EXISTS: 409,
8
+ INVALID_USER_DATA: 400,
9
+ };
10
+
11
+ function mapErrorToResponse(error) {
12
+ const status = ERROR_CODE_MAP[error?.code] || 500;
13
+ return {
14
+ error: status,
15
+ reason: error?.message,
16
+ code: error?.code,
17
+ };
18
+ }
19
+
20
+ /**
21
+ * Create user command factory
22
+ *
23
+ * NOTE: This is an internal API. Integration developers should use createFriggCommands() instead.
24
+ *
25
+ * @returns {Object} User command object with CRUD operations
26
+ */
27
+ function createUserCommands() {
28
+ const userRepository = createUserRepository();
29
+
30
+ return {
31
+ /**
32
+ * Create a new individual user
33
+ * @param {Object} params
34
+ * @param {string} params.username - Username (usually email)
35
+ * @param {string} [params.email] - Email address
36
+ * @param {string} [params.appUserId] - External application user ID
37
+ * @param {string} [params.password] - Password (optional)
38
+ * @returns {Promise<Object>} Created user object
39
+ */
40
+ async createUser({ username, email, appUserId, password } = {}) {
41
+ try {
42
+ if (!username) {
43
+ const error = new Error('username is required');
44
+ error.code = 'INVALID_USER_DATA';
45
+ throw error;
46
+ }
47
+
48
+ const userData = { username };
49
+ if (email) userData.email = email;
50
+ if (appUserId) userData.appUserId = appUserId;
51
+ if (password) userData.password = password;
52
+
53
+ const user = await userRepository.createIndividualUser(
54
+ userData
55
+ );
56
+
57
+ return {
58
+ id: user.id,
59
+ username: user.username,
60
+ email: user.email,
61
+ appUserId: user.appUserId,
62
+ };
63
+ } catch (error) {
64
+ if (error.code === 11000) {
65
+ // Duplicate key error
66
+ const duplicateError = new Error(
67
+ `User with username '${username}' already exists`
68
+ );
69
+ duplicateError.code = 'USER_ALREADY_EXISTS';
70
+ return mapErrorToResponse(duplicateError);
71
+ }
72
+ return mapErrorToResponse(error);
73
+ }
74
+ },
75
+
76
+ /**
77
+ * Find a user by their application user ID
78
+ * @param {string} appUserId - External application user ID
79
+ * @returns {Promise<Object|null>} User object or null if not found
80
+ */
81
+ async findUserByAppUserId(appUserId) {
82
+ try {
83
+ if (!appUserId) {
84
+ const error = new Error('appUserId is required');
85
+ error.code = 'INVALID_USER_DATA';
86
+ throw error;
87
+ }
88
+
89
+ const user = await userRepository.findIndividualUserByAppUserId(
90
+ appUserId
91
+ );
92
+
93
+ if (!user) {
94
+ return null;
95
+ }
96
+
97
+ return {
98
+ id: user.id,
99
+ username: user.username,
100
+ email: user.email,
101
+ appUserId: user.appUserId,
102
+ };
103
+ } catch (error) {
104
+ return mapErrorToResponse(error);
105
+ }
106
+ },
107
+
108
+ /**
109
+ * Find a user by their username
110
+ * @param {string} username - Username to search for
111
+ * @returns {Promise<Object|null>} User object or null if not found
112
+ */
113
+ async findUserByUsername(username) {
114
+ try {
115
+ if (!username) {
116
+ const error = new Error('username is required');
117
+ error.code = 'INVALID_USER_DATA';
118
+ throw error;
119
+ }
120
+
121
+ const user = await userRepository.findIndividualUserByUsername(
122
+ username
123
+ );
124
+
125
+ if (!user) {
126
+ return null;
127
+ }
128
+
129
+ return {
130
+ id: user.id,
131
+ username: user.username,
132
+ email: user.email,
133
+ appUserId: user.appUserId,
134
+ };
135
+ } catch (error) {
136
+ return mapErrorToResponse(error);
137
+ }
138
+ },
139
+
140
+ /**
141
+ * Find an individual user by their ID
142
+ * @param {string} userId - Individual user ID to search for
143
+ * @returns {Promise<Object|null>} Individual user object or null if not found
144
+ */
145
+ async findIndividualUserById(userId) {
146
+ try {
147
+ if (!userId) {
148
+ const error = new Error('userId is required');
149
+ error.code = 'INVALID_USER_DATA';
150
+ throw error;
151
+ }
152
+
153
+ const user = await userRepository.findIndividualUserById(
154
+ userId
155
+ );
156
+
157
+ if (!user) {
158
+ return null;
159
+ }
160
+
161
+ return {
162
+ id: user._id?.toString() || user.id,
163
+ username: user.username,
164
+ email: user.email,
165
+ appUserId: user.appUserId,
166
+ };
167
+ } catch (error) {
168
+ return mapErrorToResponse(error);
169
+ }
170
+ },
171
+
172
+ /**
173
+ * Find all individual users linked to an organization user
174
+ * @param {string} organizationUserId - Organization user ID to search for
175
+ * @returns {Promise<Object[]>} Array of individual user objects (empty if none)
176
+ */
177
+ async findIndividualUsersByOrganizationId(organizationUserId) {
178
+ try {
179
+ if (!organizationUserId) {
180
+ const error = new Error('organizationUserId is required');
181
+ error.code = 'INVALID_USER_DATA';
182
+ throw error;
183
+ }
184
+
185
+ const users =
186
+ await userRepository.findIndividualUsersByOrganizationId(
187
+ organizationUserId
188
+ );
189
+
190
+ return (users || []).map((user) => ({
191
+ id: user._id?.toString() || user.id,
192
+ username: user.username,
193
+ email: user.email,
194
+ appUserId: user.appUserId,
195
+ }));
196
+ } catch (error) {
197
+ return mapErrorToResponse(error);
198
+ }
199
+ },
200
+
201
+ /**
202
+ * Find an organization user by their ID
203
+ * @param {string} userId - Organization user ID to search for
204
+ * @returns {Promise<Object|null>} Organization user object or null if not found
205
+ */
206
+ async findOrganizationUserById(userId) {
207
+ try {
208
+ if (!userId) {
209
+ const error = new Error('userId is required');
210
+ error.code = 'INVALID_USER_DATA';
211
+ throw error;
212
+ }
213
+
214
+ const user = await userRepository.findOrganizationUserById(
215
+ userId
216
+ );
217
+
218
+ if (!user) {
219
+ return null;
220
+ }
221
+
222
+ return {
223
+ id: user.id,
224
+ appOrgId: user.appOrgId,
225
+ name: user.name,
226
+ };
227
+ } catch (error) {
228
+ return mapErrorToResponse(error);
229
+ }
230
+ },
231
+
232
+ /**
233
+ * Update a user by ID
234
+ * @param {string} userId - User ID to update
235
+ * @param {Object} updates - Fields to update
236
+ * @returns {Promise<Object>} Updated user object
237
+ */
238
+ async updateUser(userId, updates) {
239
+ try {
240
+ if (!userId) {
241
+ const error = new Error('userId is required');
242
+ error.code = 'INVALID_USER_DATA';
243
+ throw error;
244
+ }
245
+
246
+ const user = await userRepository.IndividualUser.update(
247
+ userId,
248
+ updates
249
+ );
250
+
251
+ if (!user) {
252
+ const error = new Error(`User ${userId} not found`);
253
+ error.code = 'USER_NOT_FOUND';
254
+ throw error;
255
+ }
256
+
257
+ return {
258
+ id: user._id.toString(),
259
+ username: user.username,
260
+ email: user.email,
261
+ appUserId: user.appUserId,
262
+ };
263
+ } catch (error) {
264
+ return mapErrorToResponse(error);
265
+ }
266
+ },
267
+
268
+ /**
269
+ * Delete a user by ID
270
+ *
271
+ * IMPORTANT: This does NOT automatically cascade delete related records in MongoDB.
272
+ * Integration developers MUST manually delete related data first:
273
+ * 1. Delete integrations (via deleteIntegrationById)
274
+ * 2. Delete entities (via deleteEntityById)
275
+ * 3. Delete credentials (via deleteCredentialById)
276
+ * 4. Finally delete user (via deleteUserById)
277
+ *
278
+ * @param {string} userId - User ID to delete
279
+ * @returns {Promise<Object>} Deletion result
280
+ */
281
+ async deleteUserById(userId) {
282
+ try {
283
+ if (!userId) {
284
+ const error = new Error('userId is required');
285
+ error.code = 'INVALID_USER_DATA';
286
+ throw error;
287
+ }
288
+
289
+ const deleted = await userRepository.deleteUser(userId);
290
+
291
+ if (!deleted) {
292
+ const error = new Error(`User ${userId} not found`);
293
+ error.code = 'USER_NOT_FOUND';
294
+ return mapErrorToResponse(error);
295
+ }
296
+
297
+ return {
298
+ success: true,
299
+ userId,
300
+ message: 'User deleted successfully',
301
+ };
302
+ } catch (error) {
303
+ return mapErrorToResponse(error);
304
+ }
305
+ },
306
+ };
307
+ }
308
+
309
+ module.exports = {
310
+ createUserCommands,
311
+ ERROR_CODE_MAP,
312
+ };
@@ -0,0 +1,83 @@
1
+ const {
2
+ createIntegrationCommands,
3
+ findIntegrationContextByExternalEntityId,
4
+ } = require('./commands/integration-commands');
5
+ const { createUserCommands } = require('./commands/user-commands');
6
+ const { createEntityCommands } = require('./commands/entity-commands');
7
+ const { createCredentialCommands } = require('./commands/credential-commands');
8
+ const { createProcessCommands } = require('./commands/process-commands');
9
+ const { createSchedulerCommands } = require('./commands/scheduler-commands');
10
+ const { createUsageCommands } = require('./commands/usage-commands');
11
+
12
+ /**
13
+ * Create a unified command factory with all CRUD operations
14
+ *
15
+ * This is the main entry point for integration developers to access all
16
+ * database operations without directly touching Mongoose models.
17
+ *
18
+ * @param {Object} params
19
+ * @param {Object} params.integrationClass - Integration class (required)
20
+ * @returns {Object} Unified commands object with all CRUD operations
21
+ *
22
+ * @example
23
+ * const commands = createFriggCommands({ integrationClass: MyIntegration });
24
+ * const user = await commands.createUser({ username: 'user@example.com' });
25
+ * const credential = await commands.createCredential({ userId: user.id, ... });
26
+ */
27
+ function createFriggCommands({ integrationClass }) {
28
+ // All commands use Frigg's default repositories and use cases
29
+ const integrationCommands = createIntegrationCommands({ integrationClass });
30
+
31
+ const userCommands = createUserCommands();
32
+
33
+ const entityCommands = createEntityCommands();
34
+
35
+ const credentialCommands = createCredentialCommands();
36
+
37
+ const processCommands = createProcessCommands();
38
+
39
+ return {
40
+ // Integration commands
41
+ ...integrationCommands,
42
+
43
+ // User commands
44
+ ...userCommands,
45
+
46
+ // Entity commands
47
+ ...entityCommands,
48
+
49
+ // Credential commands
50
+ ...credentialCommands,
51
+
52
+ // Process commands
53
+ ...processCommands,
54
+
55
+ // Usage read/write — nested to match `frigg.usage.*`. The North Star
56
+ // read takes its config as a call argument, so nothing telemetry-specific
57
+ // is threaded through this general factory.
58
+ usage: createUsageCommands(),
59
+ };
60
+ }
61
+
62
+ module.exports = {
63
+ // Unified factory
64
+ createFriggCommands,
65
+
66
+ // Individual factories
67
+ createIntegrationCommands,
68
+ createUserCommands,
69
+ createEntityCommands,
70
+ createCredentialCommands,
71
+ createProcessCommands,
72
+ createSchedulerCommands,
73
+ createUsageCommands,
74
+
75
+ // Legacy standalone function
76
+ findIntegrationContextByExternalEntityId,
77
+
78
+ // Deprecated - use createFriggCommands instead
79
+ integrationCommands: {
80
+ create: createIntegrationCommands,
81
+ findIntegrationContextByExternalEntityId,
82
+ },
83
+ };
@@ -0,0 +1,19 @@
1
+ // A configured bucket always wins, even in dev (unlike the encryption stage-bypass):
2
+ // a deployed Lambda writes artifacts and the router reads them in different containers,
3
+ // so routing dev to ephemeral /tmp would silently lose them.
4
+ const { ArtifactRepositoryS3 } = require('./artifact-repository-s3');
5
+ const { ArtifactRepositoryLocal } = require('./artifact-repository-local');
6
+
7
+ function createArtifactRepository() {
8
+ const bucket = process.env.REPORT_ARTIFACT_BUCKET;
9
+ if (bucket) {
10
+ return new ArtifactRepositoryS3({ bucket });
11
+ }
12
+ return new ArtifactRepositoryLocal();
13
+ }
14
+
15
+ module.exports = {
16
+ createArtifactRepository,
17
+ ArtifactRepositoryS3,
18
+ ArtifactRepositoryLocal,
19
+ };
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Port for report artifacts (non-JSON output like CSV, PDF). Implementations
3
+ * write bytes to a durable store and return a location reference the caller
4
+ * persists; signed URLs are minted on read.
5
+ */
6
+ class ArtifactRepositoryInterface {
7
+ /**
8
+ * @param {string} key - Caller-supplied, e.g. `reports/{executionId}/{name}-{stamp}.{ext}`.
9
+ * @returns {Promise<{bucket: string, key: string}>} Location reference.
10
+ */
11
+ async put(key, body, contentType) {
12
+ throw new Error('ArtifactRepositoryInterface.put not implemented');
13
+ }
14
+
15
+ /**
16
+ * @param {{bucket: string, key: string}|string} ref - Reference from put(), or a bare key.
17
+ */
18
+ async signedUrl(ref, { expiresIn } = {}) {
19
+ throw new Error('ArtifactRepositoryInterface.signedUrl not implemented');
20
+ }
21
+
22
+ async get(key) {
23
+ throw new Error('ArtifactRepositoryInterface.get not implemented');
24
+ }
25
+ }
26
+
27
+ module.exports = { ArtifactRepositoryInterface };
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Dev/test artifact adapter: writes to a local directory and returns file:// URLs.
3
+ * Selected by the factory only when no object store is configured (no REPORT_ARTIFACT_BUCKET).
4
+ */
5
+ const fs = require('fs');
6
+ const path = require('path');
7
+ const os = require('os');
8
+ const {
9
+ ArtifactRepositoryInterface,
10
+ } = require('./artifact-repository-interface');
11
+
12
+ class ArtifactRepositoryLocal extends ArtifactRepositoryInterface {
13
+ constructor({ baseDir } = {}) {
14
+ super();
15
+ this.baseDir =
16
+ baseDir ||
17
+ process.env.REPORT_ARTIFACT_DIR ||
18
+ path.join(os.tmpdir(), 'frigg-report-artifacts');
19
+ }
20
+
21
+ _pathFor(key) {
22
+ return path.join(this.baseDir, key);
23
+ }
24
+
25
+ async put(key, body, _contentType) {
26
+ const filePath = this._pathFor(key);
27
+ await fs.promises.mkdir(path.dirname(filePath), { recursive: true });
28
+ await fs.promises.writeFile(filePath, body);
29
+ return { bucket: this.baseDir, key };
30
+ }
31
+
32
+ async signedUrl(ref, _options = {}) {
33
+ const key = ref?.key || ref;
34
+ return `file://${this._pathFor(key)}`;
35
+ }
36
+
37
+ async get(key) {
38
+ return fs.promises.readFile(this._pathFor(key), 'utf8');
39
+ }
40
+ }
41
+
42
+ module.exports = { ArtifactRepositoryLocal };
@@ -0,0 +1,61 @@
1
+ // aws-sdk modules are lazy-required so importing this file (and the factory that
2
+ // references it) never forces the SDK to load for contexts that only need the local adapter.
3
+ const {
4
+ ArtifactRepositoryInterface,
5
+ } = require('./artifact-repository-interface');
6
+
7
+ class ArtifactRepositoryS3 extends ArtifactRepositoryInterface {
8
+ constructor({ bucket, region, s3Client } = {}) {
9
+ super();
10
+ this.bucket = bucket || process.env.REPORT_ARTIFACT_BUCKET;
11
+ this.region = region || process.env.AWS_REGION || 'us-east-1';
12
+ this._s3Client = s3Client || null;
13
+ }
14
+
15
+ _getClient() {
16
+ if (!this._s3Client) {
17
+ const { S3Client } = require('@aws-sdk/client-s3');
18
+ this._s3Client = new S3Client({ region: this.region });
19
+ }
20
+ return this._s3Client;
21
+ }
22
+
23
+ async put(key, body, contentType) {
24
+ if (!this.bucket) {
25
+ throw new Error(
26
+ 'REPORT_ARTIFACT_BUCKET is not configured; cannot store report artifact'
27
+ );
28
+ }
29
+ const { PutObjectCommand } = require('@aws-sdk/client-s3');
30
+ // No ACL set: the bucket blocks public access, so objects stay private.
31
+ await this._getClient().send(
32
+ new PutObjectCommand({
33
+ Bucket: this.bucket,
34
+ Key: key,
35
+ Body: body,
36
+ ContentType: contentType,
37
+ ServerSideEncryption: 'AES256',
38
+ })
39
+ );
40
+ return { bucket: this.bucket, key };
41
+ }
42
+
43
+ async signedUrl(ref, { expiresIn = 3600 } = {}) {
44
+ const { GetObjectCommand } = require('@aws-sdk/client-s3');
45
+ const { getSignedUrl } = require('@aws-sdk/s3-request-presigner');
46
+ const bucket = ref?.bucket || this.bucket;
47
+ const key = ref?.key || ref;
48
+ const command = new GetObjectCommand({ Bucket: bucket, Key: key });
49
+ return getSignedUrl(this._getClient(), command, { expiresIn });
50
+ }
51
+
52
+ async get(key) {
53
+ const { GetObjectCommand } = require('@aws-sdk/client-s3');
54
+ const response = await this._getClient().send(
55
+ new GetObjectCommand({ Bucket: this.bucket, Key: key })
56
+ );
57
+ return response.Body.transformToString();
58
+ }
59
+ }
60
+
61
+ module.exports = { ArtifactRepositoryS3 };
@@ -6,10 +6,7 @@ const {
6
6
  getArrayParamAndVerifyParamType,
7
7
  getAndVerifyType,
8
8
  } = require('./get');
9
- const { expectShallowEqualDbObject } = require('./is-equal');
10
-
11
9
  module.exports = {
12
- expectShallowEqualDbObject,
13
10
  get,
14
11
  getAll,
15
12
  verifyType,