@friggframework/core 2.0.0-next.1 → 2.0.0-next.100
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/CLAUDE.md +702 -0
- package/README.md +959 -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 +166 -0
- package/admin-scripts/repositories/admin-script-execution-repository-mongo.js +228 -0
- package/admin-scripts/repositories/admin-script-execution-repository-postgres.js +268 -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 +358 -0
- package/application/commands/credential-commands.js +245 -0
- package/application/commands/entity-commands.js +336 -0
- package/application/commands/integration-commands.js +343 -0
- package/application/commands/process-commands.js +135 -0
- package/application/commands/scheduler-commands.js +263 -0
- package/application/commands/user-commands.js +312 -0
- package/application/index.js +82 -0
- package/assertions/index.js +0 -3
- package/core/CLAUDE.md +690 -0
- package/core/Worker.js +60 -24
- package/core/create-handler.js +84 -6
- package/credential/repositories/credential-repository-documentdb.js +304 -0
- package/credential/repositories/credential-repository-factory.js +54 -0
- package/credential/repositories/credential-repository-interface.js +98 -0
- package/credential/repositories/credential-repository-mongo.js +269 -0
- package/credential/repositories/credential-repository-postgres.js +287 -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 +154 -0
- package/database/documentdb-encryption-service.js +330 -0
- package/database/documentdb-utils.js +136 -0
- package/database/encryption/README.md +839 -0
- package/database/encryption/documentdb-encryption-service.md +3575 -0
- package/database/encryption/encryption-schema-registry.js +401 -0
- package/database/encryption/field-encryption-service.js +254 -0
- package/database/encryption/logger.js +79 -0
- package/database/encryption/prisma-encryption-extension.js +230 -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/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 +477 -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 +15 -7
- package/errors/index.js +2 -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 +374 -0
- package/generated/prisma-mongodb/index-browser.js +356 -0
- package/generated/prisma-mongodb/index.d.ts +25667 -0
- package/generated/prisma-mongodb/index.js +399 -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 +432 -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 +381 -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 +395 -0
- package/generated/prisma-postgresql/index-browser.js +377 -0
- package/generated/prisma-postgresql/index.d.ts +28455 -0
- package/generated/prisma-postgresql/index.js +420 -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 +414 -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 +402 -0
- package/handlers/WEBHOOKS.md +653 -0
- package/handlers/app-definition-loader.js +43 -0
- package/handlers/app-handler-helpers.js +57 -0
- package/handlers/backend-utils.js +316 -0
- package/handlers/database-migration-handler.js +227 -0
- package/handlers/integration-event-dispatcher.js +54 -0
- package/handlers/middleware/admin-auth.js +73 -0
- package/handlers/routers/HEALTHCHECK.md +342 -0
- package/handlers/routers/auth.js +15 -0
- package/handlers/routers/db-migration.handler.js +29 -0
- package/handlers/routers/db-migration.js +311 -0
- package/handlers/routers/health.js +518 -0
- package/handlers/routers/integration-defined-routers.js +117 -0
- package/handlers/routers/integration-webhook-routers.js +67 -0
- package/handlers/routers/reporting.js +9 -0
- package/handlers/routers/user.js +63 -0
- package/handlers/routers/websocket.js +57 -0
- 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 +352 -0
- package/handlers/workers/dlq-processor.js +63 -0
- package/handlers/workers/integration-defined-workers.js +30 -0
- package/index.js +111 -50
- 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 +619 -72
- package/integrations/integration-router.js +460 -218
- package/integrations/options.js +3 -4
- package/integrations/repositories/config-patch-shared.js +43 -0
- package/integrations/repositories/integration-mapping-repository-documentdb.js +280 -0
- package/integrations/repositories/integration-mapping-repository-factory.js +57 -0
- package/integrations/repositories/integration-mapping-repository-interface.js +106 -0
- package/integrations/repositories/integration-mapping-repository-mongo.js +161 -0
- package/integrations/repositories/integration-mapping-repository-postgres.js +227 -0
- package/integrations/repositories/integration-mapping-repository.js +156 -0
- package/integrations/repositories/integration-repository-documentdb.js +284 -0
- package/integrations/repositories/integration-repository-factory.js +51 -0
- package/integrations/repositories/integration-repository-interface.js +173 -0
- package/integrations/repositories/integration-repository-mongo.js +414 -0
- package/integrations/repositories/integration-repository-postgres.js +452 -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/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/create-integration.js +215 -0
- package/integrations/use-cases/create-process.js +130 -0
- package/integrations/use-cases/delete-integration-for-user.js +119 -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/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 +216 -0
- package/integrations/use-cases/update-process-state.js +163 -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/logs/logger.js +0 -4
- package/{module-plugin → modules}/index.js +0 -10
- package/modules/module-factory.js +56 -0
- package/modules/module.js +274 -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 +396 -0
- package/modules/requester/requester.js +285 -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 +243 -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 +18 -0
- package/package.json +82 -50
- package/prisma-mongodb/schema.prisma +432 -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/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 +414 -0
- package/queues/queuer-util.js +103 -21
- package/reporting/README.md +86 -0
- package/reporting/index.js +17 -0
- package/reporting/reporting-router.js +77 -0
- package/reporting/repositories/reporting-repository-documentdb.js +127 -0
- package/reporting/repositories/reporting-repository-factory.js +35 -0
- package/reporting/repositories/reporting-repository-interface.js +16 -0
- package/reporting/repositories/reporting-repository-mongo.js +54 -0
- package/reporting/repositories/reporting-repository-postgres.js +70 -0
- package/reporting/use-cases/index.js +6 -0
- package/reporting/use-cases/list-integrations-report.js +142 -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/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/integrations/index.d.ts +3 -8
- package/types/module-plugin/index.d.ts +17 -69
- package/types/syncs/index.d.ts +0 -17
- package/user/repositories/user-repository-documentdb.js +458 -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 +127 -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 +77 -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/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 -350
- 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,358 @@
|
|
|
1
|
+
const ERROR_CODE_MAP = {
|
|
2
|
+
SCRIPT_NOT_FOUND: 404,
|
|
3
|
+
EXECUTION_NOT_FOUND: 404,
|
|
4
|
+
};
|
|
5
|
+
|
|
6
|
+
function mapErrorToResponse(error) {
|
|
7
|
+
const status = ERROR_CODE_MAP[error?.code] || 500;
|
|
8
|
+
return { error: status, reason: error?.message, code: error?.code };
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Create admin script commands
|
|
13
|
+
* Provides command pattern API for admin script management
|
|
14
|
+
*
|
|
15
|
+
* This follows the Command pattern from integration-commands.js:
|
|
16
|
+
* - Creates repositories via factory functions
|
|
17
|
+
* - Maps errors to HTTP-friendly responses
|
|
18
|
+
* - Returns data or error objects (never throws)
|
|
19
|
+
*
|
|
20
|
+
* WHY SEPARATE FROM integration-commands.js:
|
|
21
|
+
* These commands are intentionally separate because they serve different domains:
|
|
22
|
+
* - integration-commands: User-context operations on integrations
|
|
23
|
+
* - Requires integrationClass constructor parameter
|
|
24
|
+
* - Works with userId, entityIds, integration contexts
|
|
25
|
+
* - Uses IntegrationRepository, ModuleRepository
|
|
26
|
+
* - admin-script-commands: System/admin operations without user context
|
|
27
|
+
* - No user context required
|
|
28
|
+
* - Works with AdminScriptExecution, ScriptSchedule
|
|
29
|
+
* - Uses AdminScriptExecutionRepository, ScriptScheduleRepository
|
|
30
|
+
*
|
|
31
|
+
* Merging them would violate SRP and create coupling between
|
|
32
|
+
* user-facing integration code and admin/system code.
|
|
33
|
+
*
|
|
34
|
+
* Authentication:
|
|
35
|
+
* - Uses ENV-based ADMIN_API_KEY (see handlers/middleware/admin-auth.js)
|
|
36
|
+
* - No database-backed API keys (simplified from original design)
|
|
37
|
+
*
|
|
38
|
+
* @returns {Object} Command methods for admin scripts
|
|
39
|
+
*/
|
|
40
|
+
function createAdminScriptCommands() {
|
|
41
|
+
// Lazy-load repository factories to avoid circular dependencies
|
|
42
|
+
const {
|
|
43
|
+
createAdminScriptExecutionRepository,
|
|
44
|
+
} = require('../../admin-scripts/repositories/admin-script-execution-repository-factory');
|
|
45
|
+
const {
|
|
46
|
+
createScriptScheduleRepository,
|
|
47
|
+
} = require('../../admin-scripts/repositories/script-schedule-repository-factory');
|
|
48
|
+
|
|
49
|
+
const adminScriptExecutionRepository = createAdminScriptExecutionRepository();
|
|
50
|
+
const scheduleRepository = createScriptScheduleRepository();
|
|
51
|
+
|
|
52
|
+
return {
|
|
53
|
+
// ==================== Admin Script Execution Management Commands ====================
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Create a new admin script execution record
|
|
57
|
+
*
|
|
58
|
+
* @param {Object} params - Execution creation parameters
|
|
59
|
+
* @param {string} params.scriptName - Name of script being executed
|
|
60
|
+
* @param {string} [params.scriptVersion] - Script version
|
|
61
|
+
* @param {string} params.trigger - Trigger type ('MANUAL', 'SCHEDULED', 'QUEUE', 'WEBHOOK')
|
|
62
|
+
* @param {string} [params.mode] - Execution mode ('sync' or 'async', default 'async')
|
|
63
|
+
* @param {Object} [params.input] - Input parameters
|
|
64
|
+
* @param {Object} [params.audit] - Audit information (apiKeyName, apiKeyLast4, ipAddress)
|
|
65
|
+
* @returns {Promise<Object>} Created admin script execution record
|
|
66
|
+
*/
|
|
67
|
+
async createExecution({
|
|
68
|
+
scriptName,
|
|
69
|
+
scriptVersion,
|
|
70
|
+
trigger,
|
|
71
|
+
mode,
|
|
72
|
+
input,
|
|
73
|
+
audit,
|
|
74
|
+
parentExecutionId,
|
|
75
|
+
}) {
|
|
76
|
+
try {
|
|
77
|
+
const process = await adminScriptExecutionRepository.createExecution({
|
|
78
|
+
name: scriptName,
|
|
79
|
+
type: 'ADMIN_SCRIPT',
|
|
80
|
+
// Persisted to the parentExecutionId column (self-FK), not the
|
|
81
|
+
// context blob, so the parent/child hierarchy is queryable.
|
|
82
|
+
parentExecutionId,
|
|
83
|
+
context: {
|
|
84
|
+
scriptVersion,
|
|
85
|
+
trigger,
|
|
86
|
+
mode: mode || 'async',
|
|
87
|
+
input,
|
|
88
|
+
audit,
|
|
89
|
+
},
|
|
90
|
+
});
|
|
91
|
+
return process;
|
|
92
|
+
} catch (error) {
|
|
93
|
+
return mapErrorToResponse(error);
|
|
94
|
+
}
|
|
95
|
+
},
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Find an admin script execution by ID
|
|
99
|
+
*
|
|
100
|
+
* @param {string|number} processId - The admin script execution ID
|
|
101
|
+
* @returns {Promise<Object>} Admin script execution record or error
|
|
102
|
+
*/
|
|
103
|
+
async findExecutionById(processId) {
|
|
104
|
+
try {
|
|
105
|
+
const process = await adminScriptExecutionRepository.findExecutionById(
|
|
106
|
+
processId
|
|
107
|
+
);
|
|
108
|
+
if (!process) {
|
|
109
|
+
const error = new Error(`Execution ${processId} not found`);
|
|
110
|
+
error.code = 'EXECUTION_NOT_FOUND';
|
|
111
|
+
return mapErrorToResponse(error);
|
|
112
|
+
}
|
|
113
|
+
return process;
|
|
114
|
+
} catch (error) {
|
|
115
|
+
return mapErrorToResponse(error);
|
|
116
|
+
}
|
|
117
|
+
},
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Find all admin script executions for a specific script
|
|
121
|
+
*
|
|
122
|
+
* @param {string} scriptName - Script name to filter by
|
|
123
|
+
* @param {Object} [options] - Query options (limit, offset, sortBy, sortOrder)
|
|
124
|
+
* @returns {Promise<Array>} Array of admin script execution records
|
|
125
|
+
*/
|
|
126
|
+
async findExecutionsByName(scriptName, options = {}) {
|
|
127
|
+
try {
|
|
128
|
+
const processes =
|
|
129
|
+
await adminScriptExecutionRepository.findExecutionsByName(
|
|
130
|
+
scriptName,
|
|
131
|
+
options
|
|
132
|
+
);
|
|
133
|
+
return processes;
|
|
134
|
+
} catch (error) {
|
|
135
|
+
// Return empty array on error (non-critical)
|
|
136
|
+
return [];
|
|
137
|
+
}
|
|
138
|
+
},
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Update admin script execution state
|
|
142
|
+
*
|
|
143
|
+
* @param {string|number} processId - The admin script execution ID
|
|
144
|
+
* @param {string} state - New state ('PENDING', 'RUNNING', 'COMPLETED', 'FAILED')
|
|
145
|
+
* @returns {Promise<Object>} Updated admin script execution record
|
|
146
|
+
*/
|
|
147
|
+
async updateExecutionState(processId, state) {
|
|
148
|
+
try {
|
|
149
|
+
const updated = await adminScriptExecutionRepository.updateExecutionState(
|
|
150
|
+
processId,
|
|
151
|
+
state
|
|
152
|
+
);
|
|
153
|
+
return updated;
|
|
154
|
+
} catch (error) {
|
|
155
|
+
return mapErrorToResponse(error);
|
|
156
|
+
}
|
|
157
|
+
},
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Append a log entry to an admin script execution's results.logs array
|
|
161
|
+
*
|
|
162
|
+
* @param {string|number} processId - The admin script execution ID
|
|
163
|
+
* @param {Object} logEntry - Log entry { level, message, data, timestamp }
|
|
164
|
+
* @returns {Promise<Object>} Updated admin script execution record
|
|
165
|
+
*/
|
|
166
|
+
async appendExecutionLog(processId, logEntry) {
|
|
167
|
+
try {
|
|
168
|
+
const updated = await adminScriptExecutionRepository.appendExecutionLog(
|
|
169
|
+
processId,
|
|
170
|
+
logEntry
|
|
171
|
+
);
|
|
172
|
+
return updated;
|
|
173
|
+
} catch (error) {
|
|
174
|
+
return mapErrorToResponse(error);
|
|
175
|
+
}
|
|
176
|
+
},
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Complete an admin script execution
|
|
180
|
+
* Updates state, output, error, and metrics
|
|
181
|
+
*
|
|
182
|
+
* @param {string|number} processId - The admin script execution ID
|
|
183
|
+
* @param {Object} params - Completion parameters
|
|
184
|
+
* @param {string} [params.state] - Final state ('COMPLETED', 'FAILED')
|
|
185
|
+
* @param {Object} [params.output] - Script output/result (stored in results.output)
|
|
186
|
+
* @param {Object} [params.error] - Error details { name, message, stack } (stored in results.error)
|
|
187
|
+
* @param {Object} [params.metrics] - Performance metrics { startTime, endTime, durationMs } (stored in results.metrics)
|
|
188
|
+
* @param {Array} [params.logs] - Execution log entries (stored in results.logs)
|
|
189
|
+
* @returns {Promise<Object>} { success: true } or error
|
|
190
|
+
*/
|
|
191
|
+
async completeExecution(
|
|
192
|
+
processId,
|
|
193
|
+
{ state, output, error, metrics, logs }
|
|
194
|
+
) {
|
|
195
|
+
try {
|
|
196
|
+
if (state) {
|
|
197
|
+
await adminScriptExecutionRepository.updateExecutionState(
|
|
198
|
+
processId,
|
|
199
|
+
state
|
|
200
|
+
);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// Merge output/error/metrics/logs into the results JSON in one write
|
|
204
|
+
const resultsUpdate = {};
|
|
205
|
+
if (output !== undefined) resultsUpdate.output = output;
|
|
206
|
+
if (error) resultsUpdate.error = error;
|
|
207
|
+
if (metrics) resultsUpdate.metrics = metrics;
|
|
208
|
+
if (logs) resultsUpdate.logs = logs;
|
|
209
|
+
if (Object.keys(resultsUpdate).length > 0) {
|
|
210
|
+
await adminScriptExecutionRepository.updateExecutionResults(
|
|
211
|
+
processId,
|
|
212
|
+
resultsUpdate
|
|
213
|
+
);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
return { success: true };
|
|
217
|
+
} catch (err) {
|
|
218
|
+
return mapErrorToResponse(err);
|
|
219
|
+
}
|
|
220
|
+
},
|
|
221
|
+
|
|
222
|
+
// ==================== Schedule Management Commands ====================
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Get schedule by script name
|
|
226
|
+
* Returns database override or null
|
|
227
|
+
*
|
|
228
|
+
* @param {string} scriptName - The script name
|
|
229
|
+
* @returns {Promise<Object|null>} Schedule record or null
|
|
230
|
+
*/
|
|
231
|
+
async getScheduleByScriptName(scriptName) {
|
|
232
|
+
try {
|
|
233
|
+
const schedule =
|
|
234
|
+
await scheduleRepository.findScheduleByScriptName(
|
|
235
|
+
scriptName
|
|
236
|
+
);
|
|
237
|
+
return schedule;
|
|
238
|
+
} catch (error) {
|
|
239
|
+
return mapErrorToResponse(error);
|
|
240
|
+
}
|
|
241
|
+
},
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* Create or update a schedule (upsert)
|
|
245
|
+
*
|
|
246
|
+
* @param {Object} params - Schedule parameters
|
|
247
|
+
* @param {string} params.scriptName - Name of the script
|
|
248
|
+
* @param {boolean} params.enabled - Whether schedule is enabled
|
|
249
|
+
* @param {string} params.cronExpression - Cron expression
|
|
250
|
+
* @param {string} [params.timezone] - Timezone (default 'UTC')
|
|
251
|
+
* @returns {Promise<Object>} Created or updated schedule
|
|
252
|
+
*/
|
|
253
|
+
async upsertSchedule({
|
|
254
|
+
scriptName,
|
|
255
|
+
enabled,
|
|
256
|
+
cronExpression,
|
|
257
|
+
timezone,
|
|
258
|
+
}) {
|
|
259
|
+
try {
|
|
260
|
+
const schedule = await scheduleRepository.upsertSchedule({
|
|
261
|
+
scriptName,
|
|
262
|
+
enabled,
|
|
263
|
+
cronExpression,
|
|
264
|
+
timezone,
|
|
265
|
+
});
|
|
266
|
+
return schedule;
|
|
267
|
+
} catch (error) {
|
|
268
|
+
return mapErrorToResponse(error);
|
|
269
|
+
}
|
|
270
|
+
},
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* Delete a schedule by script name
|
|
274
|
+
*
|
|
275
|
+
* @param {string} scriptName - The script name
|
|
276
|
+
* @returns {Promise<Object>} Deletion result
|
|
277
|
+
*/
|
|
278
|
+
async deleteSchedule(scriptName) {
|
|
279
|
+
try {
|
|
280
|
+
const result = await scheduleRepository.deleteSchedule(
|
|
281
|
+
scriptName
|
|
282
|
+
);
|
|
283
|
+
return result;
|
|
284
|
+
} catch (error) {
|
|
285
|
+
return mapErrorToResponse(error);
|
|
286
|
+
}
|
|
287
|
+
},
|
|
288
|
+
|
|
289
|
+
/**
|
|
290
|
+
* Update external scheduler information
|
|
291
|
+
*
|
|
292
|
+
* @param {string} scriptName - The script name
|
|
293
|
+
* @param {Object} externalInfo - External schedule information
|
|
294
|
+
* @param {string} [externalInfo.externalScheduleId] - External scheduler ID (e.g., AWS ARN)
|
|
295
|
+
* @param {string} [externalInfo.externalScheduleName] - External scheduler name
|
|
296
|
+
* @returns {Promise<Object>} Updated schedule
|
|
297
|
+
*/
|
|
298
|
+
async updateScheduleExternalInfo(
|
|
299
|
+
scriptName,
|
|
300
|
+
{ externalScheduleId, externalScheduleName }
|
|
301
|
+
) {
|
|
302
|
+
try {
|
|
303
|
+
const schedule =
|
|
304
|
+
await scheduleRepository.updateScheduleExternalInfo(
|
|
305
|
+
scriptName,
|
|
306
|
+
{
|
|
307
|
+
externalScheduleId,
|
|
308
|
+
externalScheduleName,
|
|
309
|
+
}
|
|
310
|
+
);
|
|
311
|
+
return schedule;
|
|
312
|
+
} catch (error) {
|
|
313
|
+
return mapErrorToResponse(error);
|
|
314
|
+
}
|
|
315
|
+
},
|
|
316
|
+
|
|
317
|
+
/**
|
|
318
|
+
* Update last triggered timestamp
|
|
319
|
+
* Called when a schedule triggers
|
|
320
|
+
*
|
|
321
|
+
* @param {string} scriptName - The script name
|
|
322
|
+
* @param {Date} [timestamp] - Trigger timestamp (default: now)
|
|
323
|
+
* @returns {Promise<Object>} Updated schedule
|
|
324
|
+
*/
|
|
325
|
+
async updateScheduleLastTriggered(scriptName, timestamp) {
|
|
326
|
+
try {
|
|
327
|
+
const schedule =
|
|
328
|
+
await scheduleRepository.updateScheduleLastTriggered(
|
|
329
|
+
scriptName,
|
|
330
|
+
timestamp
|
|
331
|
+
);
|
|
332
|
+
return schedule;
|
|
333
|
+
} catch (error) {
|
|
334
|
+
return mapErrorToResponse(error);
|
|
335
|
+
}
|
|
336
|
+
},
|
|
337
|
+
|
|
338
|
+
/**
|
|
339
|
+
* List all schedules
|
|
340
|
+
*
|
|
341
|
+
* @param {Object} [options] - Query options
|
|
342
|
+
* @param {boolean} [options.enabledOnly] - Only return enabled schedules
|
|
343
|
+
* @returns {Promise<Array>} Array of schedule records
|
|
344
|
+
*/
|
|
345
|
+
async listSchedules(options = {}) {
|
|
346
|
+
try {
|
|
347
|
+
const schedules = await scheduleRepository.listSchedules(
|
|
348
|
+
options
|
|
349
|
+
);
|
|
350
|
+
return schedules;
|
|
351
|
+
} catch (error) {
|
|
352
|
+
return [];
|
|
353
|
+
}
|
|
354
|
+
},
|
|
355
|
+
};
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
module.exports = { createAdminScriptCommands };
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
const {
|
|
2
|
+
createCredentialRepository,
|
|
3
|
+
} = require('../../credential/repositories/credential-repository-factory');
|
|
4
|
+
|
|
5
|
+
const ERROR_CODE_MAP = {
|
|
6
|
+
CREDENTIAL_NOT_FOUND: 404,
|
|
7
|
+
INVALID_CREDENTIAL_DATA: 400,
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
function mapErrorToResponse(error) {
|
|
11
|
+
const status = ERROR_CODE_MAP[error?.code] || 500;
|
|
12
|
+
return {
|
|
13
|
+
error: status,
|
|
14
|
+
reason: error?.message,
|
|
15
|
+
code: error?.code,
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Create credential command factory
|
|
21
|
+
*
|
|
22
|
+
* NOTE: This is an internal API. Integration developers should use createFriggCommands() instead.
|
|
23
|
+
*
|
|
24
|
+
* @returns {Object} Credential command object with CRUD operations
|
|
25
|
+
*/
|
|
26
|
+
function createCredentialCommands() {
|
|
27
|
+
const credRepo = createCredentialRepository();
|
|
28
|
+
|
|
29
|
+
return {
|
|
30
|
+
/**
|
|
31
|
+
* Create a new credential
|
|
32
|
+
* @param {Object} params
|
|
33
|
+
* @param {string} params.userId - User ID who owns this credential
|
|
34
|
+
* @param {string} params.externalId - External identifier from the API module
|
|
35
|
+
* @param {string} params.access_token - OAuth access token
|
|
36
|
+
* @param {string} [params.refresh_token] - OAuth refresh token
|
|
37
|
+
* @param {string} [params.domain] - Domain for the credential
|
|
38
|
+
* @param {boolean} [params.authIsValid=true] - Whether authentication is valid
|
|
39
|
+
* @returns {Promise<Object>} Created credential object
|
|
40
|
+
*/
|
|
41
|
+
async createCredential({
|
|
42
|
+
userId,
|
|
43
|
+
externalId,
|
|
44
|
+
access_token,
|
|
45
|
+
refresh_token,
|
|
46
|
+
domain,
|
|
47
|
+
authIsValid = true,
|
|
48
|
+
} = {}) {
|
|
49
|
+
try {
|
|
50
|
+
if (!userId || !externalId || !access_token) {
|
|
51
|
+
const error = new Error(
|
|
52
|
+
'userId, externalId, and access_token are required'
|
|
53
|
+
);
|
|
54
|
+
error.code = 'INVALID_CREDENTIAL_DATA';
|
|
55
|
+
throw error;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const credentialData = {
|
|
59
|
+
identifiers: { userId, externalId },
|
|
60
|
+
details: {
|
|
61
|
+
access_token,
|
|
62
|
+
authIsValid,
|
|
63
|
+
},
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
if (refresh_token) {
|
|
67
|
+
credentialData.details.refresh_token = refresh_token;
|
|
68
|
+
}
|
|
69
|
+
if (domain) {
|
|
70
|
+
credentialData.details.domain = domain;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const credential = await credRepo.upsertCredential(
|
|
74
|
+
credentialData
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
return {
|
|
78
|
+
id: credential.id,
|
|
79
|
+
userId: credential.userId,
|
|
80
|
+
externalId: credential.externalId,
|
|
81
|
+
access_token: credential.access_token,
|
|
82
|
+
refresh_token: credential.refresh_token,
|
|
83
|
+
authIsValid: credential.authIsValid,
|
|
84
|
+
};
|
|
85
|
+
} catch (error) {
|
|
86
|
+
return mapErrorToResponse(error);
|
|
87
|
+
}
|
|
88
|
+
},
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Find a credential by filter criteria
|
|
92
|
+
* @param {Object} filter
|
|
93
|
+
* @param {string} [filter.userId] - User ID to search for
|
|
94
|
+
* @param {string} [filter.externalId] - External ID to search for
|
|
95
|
+
* @param {string} [filter.credentialId] - Credential ID to search for
|
|
96
|
+
* @returns {Promise<Object|null>} Credential object or null if not found
|
|
97
|
+
*/
|
|
98
|
+
async findCredential(filter = {}) {
|
|
99
|
+
try {
|
|
100
|
+
if (
|
|
101
|
+
!filter.userId &&
|
|
102
|
+
!filter.externalId &&
|
|
103
|
+
!filter.credentialId
|
|
104
|
+
) {
|
|
105
|
+
const error = new Error(
|
|
106
|
+
'At least one filter criterion is required'
|
|
107
|
+
);
|
|
108
|
+
error.code = 'INVALID_CREDENTIAL_DATA';
|
|
109
|
+
throw error;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const credential = await credRepo.findCredential(filter);
|
|
113
|
+
|
|
114
|
+
if (!credential) {
|
|
115
|
+
return null;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
return {
|
|
119
|
+
id: credential.id,
|
|
120
|
+
userId: credential.userId,
|
|
121
|
+
externalId: credential.externalId,
|
|
122
|
+
access_token: credential.access_token,
|
|
123
|
+
refresh_token: credential.refresh_token,
|
|
124
|
+
authIsValid: credential.authIsValid,
|
|
125
|
+
domain: credential.domain,
|
|
126
|
+
};
|
|
127
|
+
} catch (error) {
|
|
128
|
+
return mapErrorToResponse(error);
|
|
129
|
+
}
|
|
130
|
+
},
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Update a credential by ID
|
|
134
|
+
* @param {string} credentialId - Credential ID to update
|
|
135
|
+
* @param {Object} updates - Fields to update
|
|
136
|
+
* @returns {Promise<Object>} Updated credential object
|
|
137
|
+
*/
|
|
138
|
+
async updateCredential(credentialId, updates) {
|
|
139
|
+
try {
|
|
140
|
+
if (!credentialId) {
|
|
141
|
+
const error = new Error('credentialId is required');
|
|
142
|
+
error.code = 'INVALID_CREDENTIAL_DATA';
|
|
143
|
+
throw error;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
const credential = await credRepo.updateCredential(
|
|
147
|
+
credentialId,
|
|
148
|
+
updates
|
|
149
|
+
);
|
|
150
|
+
|
|
151
|
+
if (!credential) {
|
|
152
|
+
const error = new Error(
|
|
153
|
+
`Credential ${credentialId} not found`
|
|
154
|
+
);
|
|
155
|
+
error.code = 'CREDENTIAL_NOT_FOUND';
|
|
156
|
+
throw error;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
return {
|
|
160
|
+
id: credential.id,
|
|
161
|
+
userId: credential.userId,
|
|
162
|
+
externalId: credential.externalId,
|
|
163
|
+
access_token: credential.access_token,
|
|
164
|
+
refresh_token: credential.refresh_token,
|
|
165
|
+
authIsValid: credential.authIsValid,
|
|
166
|
+
domain: credential.domain,
|
|
167
|
+
};
|
|
168
|
+
} catch (error) {
|
|
169
|
+
return mapErrorToResponse(error);
|
|
170
|
+
}
|
|
171
|
+
},
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Update authentication status for a credential
|
|
175
|
+
* @param {string} credentialId - Credential ID to update
|
|
176
|
+
* @param {boolean} isValid - Whether authentication is valid
|
|
177
|
+
* @returns {Promise<Object>} Result object with success flag
|
|
178
|
+
*/
|
|
179
|
+
async updateAuthenticationStatus(credentialId, isValid) {
|
|
180
|
+
try {
|
|
181
|
+
if (!credentialId) {
|
|
182
|
+
const error = new Error('credentialId is required');
|
|
183
|
+
error.code = 'INVALID_CREDENTIAL_DATA';
|
|
184
|
+
throw error;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
await credRepo.updateAuthenticationStatus(
|
|
188
|
+
credentialId,
|
|
189
|
+
isValid
|
|
190
|
+
);
|
|
191
|
+
|
|
192
|
+
return { success: true };
|
|
193
|
+
} catch (error) {
|
|
194
|
+
return mapErrorToResponse(error);
|
|
195
|
+
}
|
|
196
|
+
},
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Delete a credential by ID
|
|
200
|
+
* @param {string} credentialId - Credential ID to delete
|
|
201
|
+
* @returns {Promise<Object>} Result object with success flag
|
|
202
|
+
*/
|
|
203
|
+
async deleteCredential(credentialId) {
|
|
204
|
+
try {
|
|
205
|
+
if (!credentialId) {
|
|
206
|
+
const error = new Error('credentialId is required');
|
|
207
|
+
error.code = 'INVALID_CREDENTIAL_DATA';
|
|
208
|
+
throw error;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
await credRepo.deleteCredentialById(credentialId);
|
|
212
|
+
|
|
213
|
+
return { success: true };
|
|
214
|
+
} catch (error) {
|
|
215
|
+
return mapErrorToResponse(error);
|
|
216
|
+
}
|
|
217
|
+
},
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* Delete a credential by ID (alias for deleteCredential)
|
|
221
|
+
* @param {string} credentialId - Credential ID to delete
|
|
222
|
+
* @returns {Promise<Object>} Result object with success flag
|
|
223
|
+
*/
|
|
224
|
+
async deleteCredentialById(credentialId) {
|
|
225
|
+
try {
|
|
226
|
+
if (!credentialId) {
|
|
227
|
+
const error = new Error('credentialId is required');
|
|
228
|
+
error.code = 'INVALID_CREDENTIAL_DATA';
|
|
229
|
+
throw error;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
await credRepo.deleteCredentialById(credentialId);
|
|
233
|
+
|
|
234
|
+
return { success: true };
|
|
235
|
+
} catch (error) {
|
|
236
|
+
return mapErrorToResponse(error);
|
|
237
|
+
}
|
|
238
|
+
},
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
module.exports = {
|
|
243
|
+
createCredentialCommands,
|
|
244
|
+
ERROR_CODE_MAP,
|
|
245
|
+
};
|