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