@friggframework/core 2.0.0-next.8 → 2.0.0-next.80
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/scheduler-commands.js +263 -0
- package/application/commands/user-commands.js +283 -0
- package/application/index.js +73 -0
- package/assertions/index.js +0 -3
- package/core/CLAUDE.md +690 -0
- package/core/Worker.js +60 -24
- package/core/create-handler.js +79 -8
- 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 +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 +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 +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 +335 -0
- package/generated/prisma-mongodb/index-browser.js +317 -0
- package/generated/prisma-mongodb/index.d.ts +22955 -0
- package/generated/prisma-mongodb/index.js +360 -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 +362 -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 +342 -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 +357 -0
- package/generated/prisma-postgresql/index-browser.js +339 -0
- package/generated/prisma-postgresql/index.d.ts +25131 -0
- package/generated/prisma-postgresql/index.js +382 -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 +345 -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 +364 -0
- package/handlers/WEBHOOKS.md +653 -0
- package/handlers/app-definition-loader.js +38 -0
- package/handlers/app-handler-helpers.js +57 -0
- package/handlers/backend-utils.js +262 -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/dlq-processor.js +63 -0
- package/handlers/workers/integration-defined-workers.js +23 -0
- package/index.js +82 -46
- 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/WEBHOOK-QUICKSTART.md +151 -0
- package/integrations/index.js +12 -10
- package/integrations/integration-base.js +364 -55
- package/integrations/integration-router.js +375 -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 +219 -0
- package/integrations/repositories/integration-repository-factory.js +51 -0
- package/integrations/repositories/integration-repository-interface.js +144 -0
- package/integrations/repositories/integration-repository-mongo.js +330 -0
- package/integrations/repositories/integration-repository-postgres.js +385 -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/config-capturing-integration.js +81 -0
- package/integrations/tests/doubles/dummy-integration-class.js +105 -0
- package/integrations/tests/doubles/test-integration-repository.js +112 -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 +92 -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}/index.js +0 -10
- package/modules/module-factory.js +56 -0
- package/modules/module.js +256 -0
- package/modules/repositories/module-repository-documentdb.js +335 -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 +408 -0
- package/modules/repositories/module-repository-postgres.js +453 -0
- package/modules/repositories/module-repository.js +345 -0
- package/modules/requester/api-key.js +52 -0
- package/modules/requester/oauth-2.js +396 -0
- package/{module-plugin → modules}/requester/requester.js +4 -2
- 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 +31 -0
- package/modules/use-cases/get-module.js +74 -0
- package/modules/use-cases/process-authorization-callback.js +177 -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 +362 -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 +345 -0
- package/queues/queuer-util.js +103 -21
- 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 +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/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 -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.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,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 };
|
|
@@ -0,0 +1,161 @@
|
|
|
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
|
+
* Prisma-based WebSocket Connection Repository
|
|
12
|
+
* Handles persistence of active WebSocket connections
|
|
13
|
+
*
|
|
14
|
+
* Works identically for both MongoDB and PostgreSQL:
|
|
15
|
+
* - MongoDB: String IDs with @db.ObjectId
|
|
16
|
+
* - PostgreSQL: Integer IDs with auto-increment
|
|
17
|
+
* - Both use same query patterns (no many-to-many differences)
|
|
18
|
+
*
|
|
19
|
+
* Migration from Mongoose:
|
|
20
|
+
* - Constructor injection of Prisma client
|
|
21
|
+
* - Static method getActiveConnections() → Instance method
|
|
22
|
+
* - AWS API Gateway Management API integration preserved
|
|
23
|
+
*/
|
|
24
|
+
class WebsocketConnectionRepository extends WebsocketConnectionRepositoryInterface {
|
|
25
|
+
constructor(prismaClient = prisma) {
|
|
26
|
+
super();
|
|
27
|
+
this.prisma = prismaClient; // Allow injection for testing
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Create a new WebSocket connection record
|
|
32
|
+
* Replaces: WebsocketConnection.create({ connectionId })
|
|
33
|
+
*
|
|
34
|
+
* @param {string} connectionId - The WebSocket connection ID
|
|
35
|
+
* @returns {Promise<Object>} The created connection record
|
|
36
|
+
*/
|
|
37
|
+
async createConnection(connectionId) {
|
|
38
|
+
return await this.prisma.websocketConnection.create({
|
|
39
|
+
data: { connectionId },
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Delete a WebSocket connection record
|
|
45
|
+
* Replaces: WebsocketConnection.deleteOne({ connectionId })
|
|
46
|
+
*
|
|
47
|
+
* @param {string} connectionId - The WebSocket connection ID to delete
|
|
48
|
+
* @returns {Promise<Object>} The deletion result
|
|
49
|
+
*/
|
|
50
|
+
async deleteConnection(connectionId) {
|
|
51
|
+
try {
|
|
52
|
+
await this.prisma.websocketConnection.delete({
|
|
53
|
+
where: { connectionId },
|
|
54
|
+
});
|
|
55
|
+
return { acknowledged: true, deletedCount: 1 };
|
|
56
|
+
} catch (error) {
|
|
57
|
+
if (error.code === 'P2025') {
|
|
58
|
+
// Record not found
|
|
59
|
+
return { acknowledged: true, deletedCount: 0 };
|
|
60
|
+
}
|
|
61
|
+
throw error;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Get all active WebSocket connections with send capability
|
|
67
|
+
* Replaces: WebsocketConnection.getActiveConnections()
|
|
68
|
+
*
|
|
69
|
+
* @returns {Promise<Array>} Array of active connection objects with send capability
|
|
70
|
+
*/
|
|
71
|
+
async getActiveConnections() {
|
|
72
|
+
try {
|
|
73
|
+
// Return empty array if websockets are not configured
|
|
74
|
+
if (!process.env.WEBSOCKET_API_ENDPOINT) {
|
|
75
|
+
return [];
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const connections = await this.prisma.websocketConnection.findMany({
|
|
79
|
+
select: { connectionId: true },
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
return connections.map((conn) => ({
|
|
83
|
+
connectionId: conn.connectionId,
|
|
84
|
+
send: async (data) => {
|
|
85
|
+
const apigwManagementApi = new ApiGatewayManagementApiClient({
|
|
86
|
+
endpoint: process.env.WEBSOCKET_API_ENDPOINT,
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
try {
|
|
90
|
+
const command = new PostToConnectionCommand({
|
|
91
|
+
ConnectionId: conn.connectionId,
|
|
92
|
+
Data: JSON.stringify(data),
|
|
93
|
+
});
|
|
94
|
+
await apigwManagementApi.send(command);
|
|
95
|
+
} catch (error) {
|
|
96
|
+
if (error.statusCode === 410 || error.$metadata?.httpStatusCode === 410) {
|
|
97
|
+
console.log(
|
|
98
|
+
`Stale connection ${conn.connectionId}`
|
|
99
|
+
);
|
|
100
|
+
// Delete stale connection
|
|
101
|
+
await this.prisma.websocketConnection.deleteMany({
|
|
102
|
+
where: { connectionId: conn.connectionId },
|
|
103
|
+
});
|
|
104
|
+
} else {
|
|
105
|
+
throw error;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
},
|
|
109
|
+
}));
|
|
110
|
+
} catch (error) {
|
|
111
|
+
console.error('Error getting active connections:', error);
|
|
112
|
+
throw error;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Find a connection by ID
|
|
118
|
+
* Replaces: WebsocketConnection.findOne({ connectionId })
|
|
119
|
+
*
|
|
120
|
+
* @param {string} connectionId - The WebSocket connection ID
|
|
121
|
+
* @returns {Promise<Object|null>} The connection record or null
|
|
122
|
+
*/
|
|
123
|
+
async findConnection(connectionId) {
|
|
124
|
+
return await this.prisma.websocketConnection.findFirst({
|
|
125
|
+
where: { connectionId },
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Find connection by internal ID
|
|
131
|
+
* @param {string} id - The internal connection ID
|
|
132
|
+
* @returns {Promise<Object|null>} The connection record or null
|
|
133
|
+
*/
|
|
134
|
+
async findConnectionById(id) {
|
|
135
|
+
return await this.prisma.websocketConnection.findUnique({
|
|
136
|
+
where: { id },
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Get all connections
|
|
142
|
+
* @returns {Promise<Array>} Array of all connection records
|
|
143
|
+
*/
|
|
144
|
+
async getAllConnections() {
|
|
145
|
+
return await this.prisma.websocketConnection.findMany();
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Delete all connections
|
|
150
|
+
* @returns {Promise<Object>} The deletion result
|
|
151
|
+
*/
|
|
152
|
+
async deleteAllConnections() {
|
|
153
|
+
const result = await this.prisma.websocketConnection.deleteMany();
|
|
154
|
+
return {
|
|
155
|
+
acknowledged: true,
|
|
156
|
+
deletedCount: result.count,
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
module.exports = { WebsocketConnectionRepository };
|
package/assertions/is-equal.js
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
const expectShallowEqualDbObject = (modelObject, compareObject) => {
|
|
2
|
-
for (const key in compareObject) {
|
|
3
|
-
let objVal = modelObject[key];
|
|
4
|
-
|
|
5
|
-
if (objVal instanceof Date) {
|
|
6
|
-
objVal = objVal.toISOString();
|
|
7
|
-
} else if (objVal instanceof mongoose.Types.ObjectId) {
|
|
8
|
-
objVal = objVal._id.toString();
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
expect(compareObject[key]).toBe(objVal);
|
|
12
|
-
}
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
// TODO not sure how much this is needed, but could rewrite with _.isEqualWith for deep equality with custom checks.
|
|
16
|
-
|
|
17
|
-
module.exports = { expectShallowEqualDbObject };
|
package/associations/model.js
DELETED
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
const mongoose = require("mongoose");
|
|
2
|
-
|
|
3
|
-
const schema = new mongoose.Schema({
|
|
4
|
-
integration: {
|
|
5
|
-
type: mongoose.Schema.Types.ObjectId,
|
|
6
|
-
ref: "Integration",
|
|
7
|
-
required: true,
|
|
8
|
-
},
|
|
9
|
-
name: { type: String, required: true },
|
|
10
|
-
type: {
|
|
11
|
-
type: String,
|
|
12
|
-
enum: ["ONE_TO_MANY", "ONE_TO_ONE", "MANY_TO_ONE"],
|
|
13
|
-
required: true,
|
|
14
|
-
},
|
|
15
|
-
primaryObject: { type: String, required: true },
|
|
16
|
-
objects: [
|
|
17
|
-
{
|
|
18
|
-
entity: {
|
|
19
|
-
type: mongoose.Schema.Types.ObjectId,
|
|
20
|
-
ref: "Entity",
|
|
21
|
-
required: true,
|
|
22
|
-
},
|
|
23
|
-
objectType: { type: String, required: true },
|
|
24
|
-
objId: { type: String, required: true },
|
|
25
|
-
metadata: { type: Object, required: false },
|
|
26
|
-
},
|
|
27
|
-
],
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
schema.statics({
|
|
31
|
-
addAssociation: async function (id, object) {
|
|
32
|
-
return this.update({ _id: id }, { $push: { objects: object } });
|
|
33
|
-
},
|
|
34
|
-
findAssociation: async function (name, dataIdentifierHash) {
|
|
35
|
-
const syncList = await this.list({
|
|
36
|
-
name: name,
|
|
37
|
-
"dataIdentifiers.hash": dataIdentifierHash,
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
if (syncList.length === 1) {
|
|
41
|
-
return syncList[0];
|
|
42
|
-
} else if (syncList.length === 0) {
|
|
43
|
-
return null;
|
|
44
|
-
} else {
|
|
45
|
-
throw new Error(
|
|
46
|
-
`there are multiple sync objects with the name ${name}, for entities [${entities}]`
|
|
47
|
-
);
|
|
48
|
-
}
|
|
49
|
-
},
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
const Association =
|
|
53
|
-
mongoose.models.Association || mongoose.model("Association", schema);
|
|
54
|
-
module.exports = { Association };
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
const { mongoose } = require('../mongoose');
|
|
2
|
-
const bcrypt = require('bcryptjs');
|
|
3
|
-
const { UserModel: Parent } = require('./UserModel');
|
|
4
|
-
|
|
5
|
-
const collectionName = 'IndividualUser';
|
|
6
|
-
|
|
7
|
-
const schema = new mongoose.Schema({
|
|
8
|
-
email: { type: String },
|
|
9
|
-
username: { type: String, unique: true },
|
|
10
|
-
hashword: { type: String },
|
|
11
|
-
appUserId: { type: String },
|
|
12
|
-
organizationUser: { type: mongoose.Schema.Types.ObjectId, ref: 'User' },
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
schema.pre('save', async function () {
|
|
16
|
-
if (this.hashword) {
|
|
17
|
-
this.hashword = await bcrypt.hashSync(
|
|
18
|
-
this.hashword,
|
|
19
|
-
parseInt(this.schema.statics.decimals)
|
|
20
|
-
)
|
|
21
|
-
}
|
|
22
|
-
})
|
|
23
|
-
|
|
24
|
-
schema.static({
|
|
25
|
-
decimals: 10,
|
|
26
|
-
update: async function (id, options) {
|
|
27
|
-
if ('password' in options) {
|
|
28
|
-
options.hashword = await bcrypt.hashSync(
|
|
29
|
-
options.password,
|
|
30
|
-
parseInt(this.decimals)
|
|
31
|
-
);
|
|
32
|
-
delete options.password;
|
|
33
|
-
}
|
|
34
|
-
return this.findOneAndUpdate(
|
|
35
|
-
{_id: id},
|
|
36
|
-
options,
|
|
37
|
-
{new: true, useFindAndModify: true}
|
|
38
|
-
);
|
|
39
|
-
},
|
|
40
|
-
getUserByUsername: async function (username) {
|
|
41
|
-
let getByUser;
|
|
42
|
-
try{
|
|
43
|
-
getByUser = await this.find({username});
|
|
44
|
-
} catch (e) {
|
|
45
|
-
console.log('oops')
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
if (getByUser.length > 1) {
|
|
49
|
-
throw new Error(
|
|
50
|
-
'Unique username or email? Please reach out to our developers'
|
|
51
|
-
);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
if (getByUser.length === 1) {
|
|
55
|
-
return getByUser[0];
|
|
56
|
-
}
|
|
57
|
-
},
|
|
58
|
-
getUserByAppUserId: async function (appUserId) {
|
|
59
|
-
const getByUser = await this.find({ appUserId });
|
|
60
|
-
|
|
61
|
-
if (getByUser.length > 1) {
|
|
62
|
-
throw new Error(
|
|
63
|
-
'Supposedly using a unique appUserId? Please reach out to our developers'
|
|
64
|
-
);
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
if (getByUser.length === 1) {
|
|
69
|
-
return getByUser[0];
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
})
|
|
73
|
-
|
|
74
|
-
const IndividualUser = Parent.discriminators?.IndividualUser || Parent.discriminator(collectionName, schema);
|
|
75
|
-
|
|
76
|
-
module.exports = {IndividualUser};
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
const { mongoose } = require('../mongoose');
|
|
2
|
-
const { UserModel: Parent } = require('./UserModel');
|
|
3
|
-
|
|
4
|
-
const collectionName = 'OrganizationUser';
|
|
5
|
-
|
|
6
|
-
const schema = new mongoose.Schema({
|
|
7
|
-
appOrgId: { type: String, required: true, unique: true },
|
|
8
|
-
name: { type: String },
|
|
9
|
-
});
|
|
10
|
-
|
|
11
|
-
schema.static({
|
|
12
|
-
getUserByAppOrgId: async function (appOrgId) {
|
|
13
|
-
const getByUser = await this.find({ appOrgId });
|
|
14
|
-
|
|
15
|
-
if (getByUser.length > 1) {
|
|
16
|
-
throw new Error(
|
|
17
|
-
'Supposedly using a unique appOrgId? Please reach out to our developers'
|
|
18
|
-
);
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
if (getByUser.length === 1) {
|
|
22
|
-
return getByUser[0];
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
})
|
|
26
|
-
|
|
27
|
-
const OrganizationUser = Parent.discriminators?.OrganizationUser || Parent.discriminator(collectionName, schema);
|
|
28
|
-
|
|
29
|
-
module.exports = {OrganizationUser};
|
package/database/models/State.js
DELETED