@friggframework/core 2.0.0-next.6 → 2.0.0-next.60
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 +694 -0
- package/README.md +959 -50
- package/application/commands/README.md +451 -0
- package/application/commands/credential-commands.js +245 -0
- package/application/commands/entity-commands.js +336 -0
- package/application/commands/integration-commands.js +210 -0
- package/application/commands/user-commands.js +283 -0
- package/application/index.js +69 -0
- package/core/CLAUDE.md +690 -0
- package/core/Worker.js +8 -21
- package/core/create-handler.js +14 -7
- 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 +291 -0
- package/credential/repositories/credential-repository.js +302 -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 +268 -0
- package/database/encryption/field-encryption-service.js +226 -0
- package/database/encryption/logger.js +79 -0
- package/database/encryption/prisma-encryption-extension.js +222 -0
- package/database/index.js +61 -21
- package/database/models/WebsocketConnection.js +16 -10
- package/database/models/readme.md +1 -0
- package/database/prisma.js +182 -0
- package/database/repositories/health-check-repository-documentdb.js +134 -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/health-check-repository.js +108 -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 +91 -0
- package/database/utils/mongodb-schema-init.js +106 -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/encrypt/test-encrypt.js +0 -2
- package/errors/client-safe-error.js +26 -0
- package/errors/fetch-error.js +2 -1
- package/errors/index.js +2 -0
- package/generated/prisma-mongodb/client.d.ts +1 -0
- package/generated/prisma-mongodb/client.js +4 -0
- package/generated/prisma-mongodb/default.d.ts +1 -0
- package/generated/prisma-mongodb/default.js +4 -0
- package/generated/prisma-mongodb/edge.d.ts +1 -0
- package/generated/prisma-mongodb/edge.js +334 -0
- package/generated/prisma-mongodb/index-browser.js +316 -0
- package/generated/prisma-mongodb/index.d.ts +22903 -0
- package/generated/prisma-mongodb/index.js +359 -0
- package/generated/prisma-mongodb/package.json +183 -0
- package/generated/prisma-mongodb/query-engine-debian-openssl-3.0.x +0 -0
- package/generated/prisma-mongodb/query-engine-rhel-openssl-3.0.x +0 -0
- package/generated/prisma-mongodb/runtime/binary.d.ts +1 -0
- package/generated/prisma-mongodb/runtime/binary.js +289 -0
- package/generated/prisma-mongodb/runtime/edge-esm.js +34 -0
- package/generated/prisma-mongodb/runtime/edge.js +34 -0
- package/generated/prisma-mongodb/runtime/index-browser.d.ts +370 -0
- package/generated/prisma-mongodb/runtime/index-browser.js +16 -0
- package/generated/prisma-mongodb/runtime/library.d.ts +3977 -0
- package/generated/prisma-mongodb/runtime/react-native.js +83 -0
- package/generated/prisma-mongodb/runtime/wasm-compiler-edge.js +84 -0
- package/generated/prisma-mongodb/runtime/wasm-engine-edge.js +36 -0
- package/generated/prisma-mongodb/schema.prisma +360 -0
- package/generated/prisma-mongodb/wasm-edge-light-loader.mjs +4 -0
- package/generated/prisma-mongodb/wasm-worker-loader.mjs +4 -0
- package/generated/prisma-mongodb/wasm.d.ts +1 -0
- package/generated/prisma-mongodb/wasm.js +341 -0
- package/generated/prisma-postgresql/client.d.ts +1 -0
- package/generated/prisma-postgresql/client.js +4 -0
- package/generated/prisma-postgresql/default.d.ts +1 -0
- package/generated/prisma-postgresql/default.js +4 -0
- package/generated/prisma-postgresql/edge.d.ts +1 -0
- package/generated/prisma-postgresql/edge.js +356 -0
- package/generated/prisma-postgresql/index-browser.js +338 -0
- package/generated/prisma-postgresql/index.d.ts +25077 -0
- package/generated/prisma-postgresql/index.js +381 -0
- package/generated/prisma-postgresql/package.json +183 -0
- package/generated/prisma-postgresql/query-engine-debian-openssl-3.0.x +0 -0
- package/generated/prisma-postgresql/query-engine-rhel-openssl-3.0.x +0 -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/binary.d.ts +1 -0
- package/generated/prisma-postgresql/runtime/binary.js +289 -0
- package/generated/prisma-postgresql/runtime/edge-esm.js +34 -0
- package/generated/prisma-postgresql/runtime/edge.js +34 -0
- package/generated/prisma-postgresql/runtime/index-browser.d.ts +370 -0
- package/generated/prisma-postgresql/runtime/index-browser.js +16 -0
- package/generated/prisma-postgresql/runtime/library.d.ts +3977 -0
- package/generated/prisma-postgresql/runtime/react-native.js +83 -0
- package/generated/prisma-postgresql/runtime/wasm-compiler-edge.js +84 -0
- package/generated/prisma-postgresql/runtime/wasm-engine-edge.js +36 -0
- package/generated/prisma-postgresql/schema.prisma +343 -0
- package/generated/prisma-postgresql/wasm-edge-light-loader.mjs +4 -0
- package/generated/prisma-postgresql/wasm-worker-loader.mjs +4 -0
- package/generated/prisma-postgresql/wasm.d.ts +1 -0
- package/generated/prisma-postgresql/wasm.js +363 -0
- package/handlers/WEBHOOKS.md +653 -0
- package/handlers/app-definition-loader.js +38 -0
- package/handlers/app-handler-helpers.js +56 -0
- package/handlers/backend-utils.js +186 -0
- package/handlers/database-migration-handler.js +227 -0
- package/handlers/integration-event-dispatcher.js +54 -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 +326 -0
- package/handlers/routers/health.js +516 -0
- package/handlers/routers/integration-defined-routers.js +45 -0
- package/handlers/routers/integration-webhook-routers.js +67 -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/integration-defined-workers.js +27 -0
- package/index.js +77 -22
- package/integrations/WEBHOOK-QUICKSTART.md +151 -0
- package/integrations/index.js +12 -10
- package/integrations/integration-base.js +326 -55
- package/integrations/integration-router.js +374 -179
- package/integrations/options.js +1 -1
- 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 +210 -0
- package/integrations/repositories/integration-repository-factory.js +51 -0
- package/integrations/repositories/integration-repository-interface.js +127 -0
- package/integrations/repositories/integration-repository-mongo.js +303 -0
- package/integrations/repositories/integration-repository-postgres.js +352 -0
- package/integrations/repositories/process-repository-documentdb.js +243 -0
- package/integrations/repositories/process-repository-factory.js +53 -0
- package/integrations/repositories/process-repository-interface.js +90 -0
- package/integrations/repositories/process-repository-mongo.js +190 -0
- package/integrations/repositories/process-repository-postgres.js +217 -0
- package/integrations/tests/doubles/dummy-integration-class.js +83 -0
- package/integrations/tests/doubles/test-integration-repository.js +99 -0
- package/integrations/use-cases/create-integration.js +83 -0
- package/integrations/use-cases/create-process.js +128 -0
- package/integrations/use-cases/delete-integration-for-user.js +101 -0
- package/integrations/use-cases/find-integration-context-by-external-entity-id.js +72 -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 +87 -0
- package/integrations/use-cases/index.js +19 -0
- package/integrations/use-cases/load-integration-context.js +71 -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 +93 -0
- package/integrations/use-cases/update-process-metrics.js +201 -0
- package/integrations/use-cases/update-process-state.js +119 -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}/entity.js +1 -1
- package/{module-plugin → modules}/index.js +0 -8
- package/modules/module-factory.js +56 -0
- package/modules/module.js +221 -0
- package/modules/repositories/module-repository-documentdb.js +307 -0
- package/modules/repositories/module-repository-factory.js +40 -0
- package/modules/repositories/module-repository-interface.js +129 -0
- package/modules/repositories/module-repository-mongo.js +377 -0
- package/modules/repositories/module-repository-postgres.js +426 -0
- package/modules/repositories/module-repository.js +316 -0
- package/modules/requester/api-key.js +52 -0
- package/{module-plugin → modules}/requester/requester.js +1 -0
- package/{module-plugin → modules}/test/mock-api/api.js +8 -3
- package/{module-plugin → modules}/test/mock-api/definition.js +12 -8
- 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 +31 -0
- package/modules/use-cases/get-module.js +74 -0
- package/modules/use-cases/process-authorization-callback.js +133 -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 +360 -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/migration_lock.toml +3 -0
- package/prisma-postgresql/schema.prisma +343 -0
- package/queues/queuer-util.js +27 -22
- 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/core/index.d.ts +2 -2
- package/types/integrations/index.d.ts +2 -6
- package/types/module-plugin/index.d.ts +5 -59
- package/types/syncs/index.d.ts +0 -2
- package/user/repositories/user-repository-documentdb.js +441 -0
- package/user/repositories/user-repository-factory.js +52 -0
- package/user/repositories/user-repository-interface.js +201 -0
- package/user/repositories/user-repository-mongo.js +308 -0
- package/user/repositories/user-repository-postgres.js +360 -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/database/models/State.js +0 -9
- package/database/models/Token.js +0 -70
- package/database/mongo.js +0 -45
- package/encrypt/Cryptor.test.js +0 -32
- package/encrypt/encrypt.js +0 -132
- package/encrypt/encrypt.test.js +0 -1069
- 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 -393
- package/module-plugin/credential.js +0 -22
- package/module-plugin/entity-manager.js +0 -70
- 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/requester.test.js +0 -28
- package/module-plugin/test/auther.test.js +0 -97
- /package/{module-plugin → modules}/ModuleConstants.js +0 -0
- /package/{module-plugin → modules}/requester/basic.js +0 -0
- /package/{module-plugin → modules}/requester/oauth-2.js +0 -0
- /package/{module-plugin → modules}/test/mock-api/mocks/hubspot.js +0 -0
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
const fs = require('fs-extra');
|
|
2
|
+
const path = require('node:path');
|
|
3
|
+
const PACKAGE_JSON = 'package.json';
|
|
4
|
+
|
|
5
|
+
function findNearestBackendPackageJson() {
|
|
6
|
+
let currentDir = process.cwd();
|
|
7
|
+
|
|
8
|
+
// First check if we're in production by looking for package.json in the current directory
|
|
9
|
+
const rootPackageJson = path.join(currentDir, PACKAGE_JSON);
|
|
10
|
+
if (fs.existsSync(rootPackageJson)) {
|
|
11
|
+
// In production environment, check for index.js in the same directory
|
|
12
|
+
const indexJs = path.join(currentDir, 'index.js');
|
|
13
|
+
if (fs.existsSync(indexJs)) {
|
|
14
|
+
return rootPackageJson;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// If not found at root or not in production, look for it in the backend directory
|
|
19
|
+
while (currentDir !== path.parse(currentDir).root) {
|
|
20
|
+
const packageJsonPath = path.join(currentDir, 'backend', PACKAGE_JSON);
|
|
21
|
+
if (fs.existsSync(packageJsonPath)) {
|
|
22
|
+
return packageJsonPath;
|
|
23
|
+
}
|
|
24
|
+
currentDir = path.dirname(currentDir);
|
|
25
|
+
}
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function validateBackendPath(backendPath) {
|
|
30
|
+
if (!backendPath) {
|
|
31
|
+
throw new Error('Could not find a backend package.json file.');
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
module.exports = {
|
|
36
|
+
findNearestBackendPackageJson,
|
|
37
|
+
validateBackendPath,
|
|
38
|
+
};
|
package/utils/index.js
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
const { prisma } = require('../../database/prisma');
|
|
2
|
+
const {
|
|
3
|
+
ApiGatewayManagementApiClient,
|
|
4
|
+
PostToConnectionCommand,
|
|
5
|
+
} = require('@aws-sdk/client-apigatewaymanagementapi');
|
|
6
|
+
const {
|
|
7
|
+
toObjectId,
|
|
8
|
+
fromObjectId,
|
|
9
|
+
findMany,
|
|
10
|
+
findOne,
|
|
11
|
+
insertOne,
|
|
12
|
+
deleteOne,
|
|
13
|
+
deleteMany,
|
|
14
|
+
} = require('../../database/documentdb-utils');
|
|
15
|
+
const {
|
|
16
|
+
WebsocketConnectionRepositoryInterface,
|
|
17
|
+
} = require('./websocket-connection-repository-interface');
|
|
18
|
+
|
|
19
|
+
class WebsocketConnectionRepositoryDocumentDB extends WebsocketConnectionRepositoryInterface {
|
|
20
|
+
constructor() {
|
|
21
|
+
super();
|
|
22
|
+
this.prisma = prisma;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
async createConnection(connectionId) {
|
|
26
|
+
const now = new Date();
|
|
27
|
+
const document = {
|
|
28
|
+
connectionId,
|
|
29
|
+
createdAt: now,
|
|
30
|
+
updatedAt: now,
|
|
31
|
+
};
|
|
32
|
+
const insertedId = await insertOne(this.prisma, 'WebsocketConnection', document);
|
|
33
|
+
const created = await findOne(this.prisma, 'WebsocketConnection', { _id: insertedId });
|
|
34
|
+
return this._mapConnection(created);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
async deleteConnection(connectionId) {
|
|
38
|
+
const result = await deleteOne(this.prisma, 'WebsocketConnection', { connectionId });
|
|
39
|
+
const deleted = result?.n ?? 0;
|
|
40
|
+
return { acknowledged: true, deletedCount: deleted };
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
async getActiveConnections() {
|
|
44
|
+
if (!process.env.WEBSOCKET_API_ENDPOINT) {
|
|
45
|
+
return [];
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const connections = await findMany(
|
|
49
|
+
this.prisma,
|
|
50
|
+
'WebsocketConnection',
|
|
51
|
+
{},
|
|
52
|
+
{ projection: { connectionId: 1 } }
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
return connections.map((conn) => ({
|
|
56
|
+
connectionId: conn.connectionId,
|
|
57
|
+
send: async (data) => {
|
|
58
|
+
const apigwManagementApi = new ApiGatewayManagementApiClient({
|
|
59
|
+
endpoint: process.env.WEBSOCKET_API_ENDPOINT,
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
try {
|
|
63
|
+
const command = new PostToConnectionCommand({
|
|
64
|
+
ConnectionId: conn.connectionId,
|
|
65
|
+
Data: JSON.stringify(data),
|
|
66
|
+
});
|
|
67
|
+
await apigwManagementApi.send(command);
|
|
68
|
+
} catch (error) {
|
|
69
|
+
if (error.statusCode === 410 || error.$metadata?.httpStatusCode === 410) {
|
|
70
|
+
console.log(`Stale connection ${conn.connectionId}`);
|
|
71
|
+
await deleteMany(this.prisma, 'WebsocketConnection', {
|
|
72
|
+
connectionId: conn.connectionId,
|
|
73
|
+
});
|
|
74
|
+
} else {
|
|
75
|
+
throw error;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
}));
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
async findConnection(connectionId) {
|
|
83
|
+
const doc = await findOne(this.prisma, 'WebsocketConnection', { connectionId });
|
|
84
|
+
return doc ? this._mapConnection(doc) : null;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
async findConnectionById(id) {
|
|
88
|
+
const objectId = toObjectId(id);
|
|
89
|
+
if (!objectId) return null;
|
|
90
|
+
const doc = await findOne(this.prisma, 'WebsocketConnection', { _id: objectId });
|
|
91
|
+
return doc ? this._mapConnection(doc) : null;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
async getAllConnections() {
|
|
95
|
+
const docs = await findMany(this.prisma, 'WebsocketConnection');
|
|
96
|
+
return docs.map((doc) => this._mapConnection(doc));
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
async deleteAllConnections() {
|
|
100
|
+
const result = await deleteMany(this.prisma, 'WebsocketConnection', {});
|
|
101
|
+
const deleted = result?.n ?? 0;
|
|
102
|
+
return {
|
|
103
|
+
acknowledged: true,
|
|
104
|
+
deletedCount: deleted,
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
_mapConnection(doc) {
|
|
109
|
+
if (!doc) return null;
|
|
110
|
+
return {
|
|
111
|
+
id: fromObjectId(doc._id),
|
|
112
|
+
connectionId: doc.connectionId,
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
module.exports = { WebsocketConnectionRepositoryDocumentDB };
|
|
118
|
+
|
|
119
|
+
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
const {
|
|
2
|
+
WebsocketConnectionRepositoryMongo,
|
|
3
|
+
} = require('./websocket-connection-repository-mongo');
|
|
4
|
+
const {
|
|
5
|
+
WebsocketConnectionRepositoryPostgres,
|
|
6
|
+
} = require('./websocket-connection-repository-postgres');
|
|
7
|
+
const {
|
|
8
|
+
WebsocketConnectionRepositoryDocumentDB,
|
|
9
|
+
} = require('./websocket-connection-repository-documentdb');
|
|
10
|
+
const config = require('../../database/config');
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Websocket Connection Repository Factory
|
|
14
|
+
* Creates the appropriate repository adapter based on database type
|
|
15
|
+
*
|
|
16
|
+
* @returns {WebsocketConnectionRepositoryInterface} Configured repository adapter
|
|
17
|
+
*/
|
|
18
|
+
function createWebsocketConnectionRepository() {
|
|
19
|
+
const dbType = config.DB_TYPE;
|
|
20
|
+
|
|
21
|
+
switch (dbType) {
|
|
22
|
+
case 'mongodb':
|
|
23
|
+
return new WebsocketConnectionRepositoryMongo();
|
|
24
|
+
|
|
25
|
+
case 'postgresql':
|
|
26
|
+
return new WebsocketConnectionRepositoryPostgres();
|
|
27
|
+
|
|
28
|
+
case 'documentdb':
|
|
29
|
+
return new WebsocketConnectionRepositoryDocumentDB();
|
|
30
|
+
|
|
31
|
+
default:
|
|
32
|
+
throw new Error(
|
|
33
|
+
`Unsupported database type: ${dbType}. Supported values: 'mongodb', 'documentdb', 'postgresql'`
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
module.exports = {
|
|
39
|
+
createWebsocketConnectionRepository,
|
|
40
|
+
// Export adapters for direct testing
|
|
41
|
+
WebsocketConnectionRepositoryMongo,
|
|
42
|
+
WebsocketConnectionRepositoryPostgres,
|
|
43
|
+
WebsocketConnectionRepositoryDocumentDB,
|
|
44
|
+
};
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Websocket Connection Repository Interface
|
|
3
|
+
* Abstract base class defining the contract for websocket connection persistence adapters
|
|
4
|
+
*
|
|
5
|
+
* This follows the Port in Hexagonal Architecture:
|
|
6
|
+
* - Domain layer depends on this abstraction
|
|
7
|
+
* - Concrete adapters implement this interface
|
|
8
|
+
* - Use cases receive repositories via dependency injection
|
|
9
|
+
*
|
|
10
|
+
* Note: Currently, WebsocketConnection model has identical structure across MongoDB and PostgreSQL,
|
|
11
|
+
* so WebsocketConnectionRepository serves both. This interface exists for consistency and
|
|
12
|
+
* future-proofing if database-specific implementations become needed.
|
|
13
|
+
*
|
|
14
|
+
* @abstract
|
|
15
|
+
*/
|
|
16
|
+
class WebsocketConnectionRepositoryInterface {
|
|
17
|
+
/**
|
|
18
|
+
* Create a new websocket connection
|
|
19
|
+
*
|
|
20
|
+
* @param {string} connectionId - Connection ID
|
|
21
|
+
* @returns {Promise<Object>} Created connection object
|
|
22
|
+
* @abstract
|
|
23
|
+
*/
|
|
24
|
+
async createConnection(connectionId) {
|
|
25
|
+
throw new Error(
|
|
26
|
+
'Method createConnection must be implemented by subclass'
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Delete a websocket connection
|
|
32
|
+
*
|
|
33
|
+
* @param {string} connectionId - Connection ID
|
|
34
|
+
* @returns {Promise<Object>} Deletion result
|
|
35
|
+
* @abstract
|
|
36
|
+
*/
|
|
37
|
+
async deleteConnection(connectionId) {
|
|
38
|
+
throw new Error(
|
|
39
|
+
'Method deleteConnection must be implemented by subclass'
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Get active connections
|
|
45
|
+
*
|
|
46
|
+
* @returns {Promise<Array>} Array of active connection objects
|
|
47
|
+
* @abstract
|
|
48
|
+
*/
|
|
49
|
+
async getActiveConnections() {
|
|
50
|
+
throw new Error(
|
|
51
|
+
'Method getActiveConnections must be implemented by subclass'
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Find connection by connection ID
|
|
57
|
+
*
|
|
58
|
+
* @param {string} connectionId - Connection ID
|
|
59
|
+
* @returns {Promise<Object|null>} Connection object or null
|
|
60
|
+
* @abstract
|
|
61
|
+
*/
|
|
62
|
+
async findConnection(connectionId) {
|
|
63
|
+
throw new Error(
|
|
64
|
+
'Method findConnection must be implemented by subclass'
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Find connection by database ID
|
|
70
|
+
*
|
|
71
|
+
* @param {string|number} id - Database ID
|
|
72
|
+
* @returns {Promise<Object|null>} Connection object or null
|
|
73
|
+
* @abstract
|
|
74
|
+
*/
|
|
75
|
+
async findConnectionById(id) {
|
|
76
|
+
throw new Error(
|
|
77
|
+
'Method findConnectionById must be implemented by subclass'
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Get all connections
|
|
83
|
+
*
|
|
84
|
+
* @returns {Promise<Array>} Array of all connection objects
|
|
85
|
+
* @abstract
|
|
86
|
+
*/
|
|
87
|
+
async getAllConnections() {
|
|
88
|
+
throw new Error(
|
|
89
|
+
'Method getAllConnections must be implemented by subclass'
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Delete all connections
|
|
95
|
+
*
|
|
96
|
+
* @returns {Promise<Object>} Deletion result
|
|
97
|
+
* @abstract
|
|
98
|
+
*/
|
|
99
|
+
async deleteAllConnections() {
|
|
100
|
+
throw new Error(
|
|
101
|
+
'Method deleteAllConnections must be implemented by subclass'
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
module.exports = { WebsocketConnectionRepositoryInterface };
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
const { prisma } = require('../../database/prisma');
|
|
2
|
+
const {
|
|
3
|
+
ApiGatewayManagementApiClient,
|
|
4
|
+
PostToConnectionCommand,
|
|
5
|
+
} = require('@aws-sdk/client-apigatewaymanagementapi');
|
|
6
|
+
const {
|
|
7
|
+
WebsocketConnectionRepositoryInterface,
|
|
8
|
+
} = require('./websocket-connection-repository-interface');
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* MongoDB WebSocket Connection Repository Adapter
|
|
12
|
+
* Handles persistence of active WebSocket connections
|
|
13
|
+
*
|
|
14
|
+
* MongoDB-specific characteristics:
|
|
15
|
+
* - Uses String IDs (ObjectId)
|
|
16
|
+
* - No ID conversion needed (IDs are already strings)
|
|
17
|
+
* - AWS API Gateway Management API integration preserved
|
|
18
|
+
*/
|
|
19
|
+
class WebsocketConnectionRepositoryMongo extends WebsocketConnectionRepositoryInterface {
|
|
20
|
+
constructor() {
|
|
21
|
+
super();
|
|
22
|
+
this.prisma = prisma;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Create a new WebSocket connection record
|
|
27
|
+
* Replaces: WebsocketConnection.create({ connectionId })
|
|
28
|
+
*
|
|
29
|
+
* @param {string} connectionId - The WebSocket connection ID
|
|
30
|
+
* @returns {Promise<Object>} The created connection record with string IDs
|
|
31
|
+
*/
|
|
32
|
+
async createConnection(connectionId) {
|
|
33
|
+
return await this.prisma.websocketConnection.create({
|
|
34
|
+
data: { connectionId },
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Delete a WebSocket connection record
|
|
40
|
+
* Replaces: WebsocketConnection.deleteOne({ connectionId })
|
|
41
|
+
*
|
|
42
|
+
* @param {string} connectionId - The WebSocket connection ID to delete
|
|
43
|
+
* @returns {Promise<Object>} The deletion result
|
|
44
|
+
*/
|
|
45
|
+
async deleteConnection(connectionId) {
|
|
46
|
+
try {
|
|
47
|
+
await this.prisma.websocketConnection.delete({
|
|
48
|
+
where: { connectionId },
|
|
49
|
+
});
|
|
50
|
+
return { acknowledged: true, deletedCount: 1 };
|
|
51
|
+
} catch (error) {
|
|
52
|
+
if (error.code === 'P2025') {
|
|
53
|
+
// Record not found
|
|
54
|
+
return { acknowledged: true, deletedCount: 0 };
|
|
55
|
+
}
|
|
56
|
+
throw error;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Get all active WebSocket connections with send capability
|
|
62
|
+
* Replaces: WebsocketConnection.getActiveConnections()
|
|
63
|
+
*
|
|
64
|
+
* @returns {Promise<Array>} Array of active connection objects with send capability
|
|
65
|
+
*/
|
|
66
|
+
async getActiveConnections() {
|
|
67
|
+
try {
|
|
68
|
+
// Return empty array if websockets are not configured
|
|
69
|
+
if (!process.env.WEBSOCKET_API_ENDPOINT) {
|
|
70
|
+
return [];
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const connections = await this.prisma.websocketConnection.findMany({
|
|
74
|
+
select: { connectionId: true },
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
return connections.map((conn) => ({
|
|
78
|
+
connectionId: conn.connectionId,
|
|
79
|
+
send: async (data) => {
|
|
80
|
+
const apigwManagementApi = new ApiGatewayManagementApiClient({
|
|
81
|
+
endpoint: process.env.WEBSOCKET_API_ENDPOINT,
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
try {
|
|
85
|
+
const command = new PostToConnectionCommand({
|
|
86
|
+
ConnectionId: conn.connectionId,
|
|
87
|
+
Data: JSON.stringify(data),
|
|
88
|
+
});
|
|
89
|
+
await apigwManagementApi.send(command);
|
|
90
|
+
} catch (error) {
|
|
91
|
+
if (error.statusCode === 410 || error.$metadata?.httpStatusCode === 410) {
|
|
92
|
+
console.log(
|
|
93
|
+
`Stale connection ${conn.connectionId}`
|
|
94
|
+
);
|
|
95
|
+
// Delete stale connection
|
|
96
|
+
await this.prisma.websocketConnection.deleteMany({
|
|
97
|
+
where: { connectionId: conn.connectionId },
|
|
98
|
+
});
|
|
99
|
+
} else {
|
|
100
|
+
throw error;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
},
|
|
104
|
+
}));
|
|
105
|
+
} catch (error) {
|
|
106
|
+
console.error('Error getting active connections:', error);
|
|
107
|
+
throw error;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Find a connection by connection ID
|
|
113
|
+
* Replaces: WebsocketConnection.findOne({ connectionId })
|
|
114
|
+
*
|
|
115
|
+
* @param {string} connectionId - The WebSocket connection ID
|
|
116
|
+
* @returns {Promise<Object|null>} The connection record with string IDs or null
|
|
117
|
+
*/
|
|
118
|
+
async findConnection(connectionId) {
|
|
119
|
+
return await this.prisma.websocketConnection.findFirst({
|
|
120
|
+
where: { connectionId },
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Find connection by internal ID
|
|
126
|
+
* @param {string} id - The internal connection ID
|
|
127
|
+
* @returns {Promise<Object|null>} The connection record with string IDs or null
|
|
128
|
+
*/
|
|
129
|
+
async findConnectionById(id) {
|
|
130
|
+
return await this.prisma.websocketConnection.findUnique({
|
|
131
|
+
where: { id },
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Get all connections
|
|
137
|
+
* @returns {Promise<Array>} Array of all connection records with string IDs
|
|
138
|
+
*/
|
|
139
|
+
async getAllConnections() {
|
|
140
|
+
return await this.prisma.websocketConnection.findMany();
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Delete all connections
|
|
145
|
+
* @returns {Promise<Object>} The deletion result
|
|
146
|
+
*/
|
|
147
|
+
async deleteAllConnections() {
|
|
148
|
+
const result = await this.prisma.websocketConnection.deleteMany();
|
|
149
|
+
return {
|
|
150
|
+
acknowledged: true,
|
|
151
|
+
deletedCount: result.count,
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
module.exports = { WebsocketConnectionRepositoryMongo };
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
const { prisma } = require('../../database/prisma');
|
|
2
|
+
const {
|
|
3
|
+
ApiGatewayManagementApiClient,
|
|
4
|
+
PostToConnectionCommand,
|
|
5
|
+
} = require('@aws-sdk/client-apigatewaymanagementapi');
|
|
6
|
+
const {
|
|
7
|
+
WebsocketConnectionRepositoryInterface,
|
|
8
|
+
} = require('./websocket-connection-repository-interface');
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* PostgreSQL WebSocket Connection Repository Adapter
|
|
12
|
+
* Handles persistence of active WebSocket connections
|
|
13
|
+
*
|
|
14
|
+
* PostgreSQL-specific characteristics:
|
|
15
|
+
* - Uses Int IDs with autoincrement
|
|
16
|
+
* - Requires ID conversion: String (app layer) ↔ Int (database)
|
|
17
|
+
* - All returned IDs are converted to strings for application layer consistency
|
|
18
|
+
*/
|
|
19
|
+
class WebsocketConnectionRepositoryPostgres extends WebsocketConnectionRepositoryInterface {
|
|
20
|
+
constructor() {
|
|
21
|
+
super();
|
|
22
|
+
this.prisma = prisma;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Convert string ID to integer for PostgreSQL queries
|
|
27
|
+
* @private
|
|
28
|
+
* @param {string|number|null|undefined} id - ID to convert
|
|
29
|
+
* @returns {number|null|undefined} Integer ID or null/undefined
|
|
30
|
+
* @throws {Error} If ID cannot be converted to integer
|
|
31
|
+
*/
|
|
32
|
+
_convertId(id) {
|
|
33
|
+
if (id === null || id === undefined) return id;
|
|
34
|
+
const parsed = parseInt(id, 10);
|
|
35
|
+
if (isNaN(parsed)) {
|
|
36
|
+
throw new Error(`Invalid ID: ${id} cannot be converted to integer`);
|
|
37
|
+
}
|
|
38
|
+
return parsed;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Convert connection object IDs to strings
|
|
43
|
+
* @private
|
|
44
|
+
* @param {Object|null} connection - Connection object from database
|
|
45
|
+
* @returns {Object|null} Connection with string IDs
|
|
46
|
+
*/
|
|
47
|
+
_convertConnectionIds(connection) {
|
|
48
|
+
if (!connection) return connection;
|
|
49
|
+
return {
|
|
50
|
+
...connection,
|
|
51
|
+
id: connection.id?.toString(),
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Create a new WebSocket connection record
|
|
57
|
+
* Replaces: WebsocketConnection.create({ connectionId })
|
|
58
|
+
*
|
|
59
|
+
* @param {string} connectionId - The WebSocket connection ID
|
|
60
|
+
* @returns {Promise<Object>} The created connection record with string IDs
|
|
61
|
+
*/
|
|
62
|
+
async createConnection(connectionId) {
|
|
63
|
+
const connection = await this.prisma.websocketConnection.create({
|
|
64
|
+
data: { connectionId },
|
|
65
|
+
});
|
|
66
|
+
return this._convertConnectionIds(connection);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Delete a WebSocket connection record
|
|
71
|
+
* Replaces: WebsocketConnection.deleteOne({ connectionId })
|
|
72
|
+
*
|
|
73
|
+
* Note: connectionId is a string field in schema, not the primary key,
|
|
74
|
+
* so no conversion needed here.
|
|
75
|
+
*
|
|
76
|
+
* @param {string} connectionId - The WebSocket connection ID to delete
|
|
77
|
+
* @returns {Promise<Object>} The deletion result
|
|
78
|
+
*/
|
|
79
|
+
async deleteConnection(connectionId) {
|
|
80
|
+
try {
|
|
81
|
+
await this.prisma.websocketConnection.delete({
|
|
82
|
+
where: { connectionId },
|
|
83
|
+
});
|
|
84
|
+
return { acknowledged: true, deletedCount: 1 };
|
|
85
|
+
} catch (error) {
|
|
86
|
+
if (error.code === 'P2025') {
|
|
87
|
+
// Record not found
|
|
88
|
+
return { acknowledged: true, deletedCount: 0 };
|
|
89
|
+
}
|
|
90
|
+
throw error;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Get all active WebSocket connections with send capability
|
|
96
|
+
* Replaces: WebsocketConnection.getActiveConnections()
|
|
97
|
+
*
|
|
98
|
+
* @returns {Promise<Array>} Array of active connection objects with send capability
|
|
99
|
+
*/
|
|
100
|
+
async getActiveConnections() {
|
|
101
|
+
try {
|
|
102
|
+
// Return empty array if websockets are not configured
|
|
103
|
+
if (!process.env.WEBSOCKET_API_ENDPOINT) {
|
|
104
|
+
return [];
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const connections = await this.prisma.websocketConnection.findMany({
|
|
108
|
+
select: { connectionId: true },
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
return connections.map((conn) => ({
|
|
112
|
+
connectionId: conn.connectionId,
|
|
113
|
+
send: async (data) => {
|
|
114
|
+
const apigwManagementApi = new ApiGatewayManagementApiClient({
|
|
115
|
+
endpoint: process.env.WEBSOCKET_API_ENDPOINT,
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
try {
|
|
119
|
+
const command = new PostToConnectionCommand({
|
|
120
|
+
ConnectionId: conn.connectionId,
|
|
121
|
+
Data: JSON.stringify(data),
|
|
122
|
+
});
|
|
123
|
+
await apigwManagementApi.send(command);
|
|
124
|
+
} catch (error) {
|
|
125
|
+
if (error.statusCode === 410 || error.$metadata?.httpStatusCode === 410) {
|
|
126
|
+
console.log(
|
|
127
|
+
`Stale connection ${conn.connectionId}`
|
|
128
|
+
);
|
|
129
|
+
// Delete stale connection
|
|
130
|
+
await this.prisma.websocketConnection.deleteMany({
|
|
131
|
+
where: { connectionId: conn.connectionId },
|
|
132
|
+
});
|
|
133
|
+
} else {
|
|
134
|
+
throw error;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
},
|
|
138
|
+
}));
|
|
139
|
+
} catch (error) {
|
|
140
|
+
console.error('Error getting active connections:', error);
|
|
141
|
+
throw error;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Find a connection by connection ID
|
|
147
|
+
* Replaces: WebsocketConnection.findOne({ connectionId })
|
|
148
|
+
*
|
|
149
|
+
* Note: connectionId is a string field, not the primary key
|
|
150
|
+
*
|
|
151
|
+
* @param {string} connectionId - The WebSocket connection ID
|
|
152
|
+
* @returns {Promise<Object|null>} The connection record with string IDs or null
|
|
153
|
+
*/
|
|
154
|
+
async findConnection(connectionId) {
|
|
155
|
+
const connection = await this.prisma.websocketConnection.findFirst({
|
|
156
|
+
where: { connectionId },
|
|
157
|
+
});
|
|
158
|
+
return this._convertConnectionIds(connection);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Find connection by internal ID
|
|
163
|
+
* @param {string} id - The internal connection ID (string from application layer)
|
|
164
|
+
* @returns {Promise<Object|null>} The connection record with string IDs or null
|
|
165
|
+
*/
|
|
166
|
+
async findConnectionById(id) {
|
|
167
|
+
const intId = this._convertId(id);
|
|
168
|
+
const connection = await this.prisma.websocketConnection.findUnique({
|
|
169
|
+
where: { id: intId },
|
|
170
|
+
});
|
|
171
|
+
return this._convertConnectionIds(connection);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Get all connections
|
|
176
|
+
* @returns {Promise<Array>} Array of all connection records with string IDs
|
|
177
|
+
*/
|
|
178
|
+
async getAllConnections() {
|
|
179
|
+
const connections = await this.prisma.websocketConnection.findMany();
|
|
180
|
+
return connections.map((conn) => this._convertConnectionIds(conn));
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Delete all connections
|
|
185
|
+
* @returns {Promise<Object>} The deletion result
|
|
186
|
+
*/
|
|
187
|
+
async deleteAllConnections() {
|
|
188
|
+
const result = await this.prisma.websocketConnection.deleteMany();
|
|
189
|
+
return {
|
|
190
|
+
acknowledged: true,
|
|
191
|
+
deletedCount: result.count,
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
module.exports = { WebsocketConnectionRepositoryPostgres };
|