@memberjunction/server 6.2.0-edge.2 → 6.2.0-edge.4
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/README.md +30 -0
- package/dist/.tsbuildinfo +1 -1
- package/dist/agentSessions/BridgeHostInstance.d.ts +25 -0
- package/dist/agentSessions/BridgeHostInstance.d.ts.map +1 -0
- package/dist/agentSessions/BridgeHostInstance.js +30 -0
- package/dist/agentSessions/BridgeHostInstance.js.map +1 -0
- package/dist/agentSessions/HostInstance.d.ts +75 -11
- package/dist/agentSessions/HostInstance.d.ts.map +1 -1
- package/dist/agentSessions/HostInstance.js +99 -28
- package/dist/agentSessions/HostInstance.js.map +1 -1
- package/dist/agentSessions/ReturningVisitorRecap.d.ts.map +1 -1
- package/dist/agentSessions/ReturningVisitorRecap.js +7 -3
- package/dist/agentSessions/ReturningVisitorRecap.js.map +1 -1
- package/dist/agentSessions/SessionJanitor.d.ts +173 -25
- package/dist/agentSessions/SessionJanitor.d.ts.map +1 -1
- package/dist/agentSessions/SessionJanitor.js +452 -54
- package/dist/agentSessions/SessionJanitor.js.map +1 -1
- package/dist/agentSessions/SessionManager.d.ts +43 -2
- package/dist/agentSessions/SessionManager.d.ts.map +1 -1
- package/dist/agentSessions/SessionManager.js +99 -8
- package/dist/agentSessions/SessionManager.js.map +1 -1
- package/dist/agentSessions/SessionRunIDVerifier.d.ts +63 -0
- package/dist/agentSessions/SessionRunIDVerifier.d.ts.map +1 -0
- package/dist/agentSessions/SessionRunIDVerifier.js +129 -0
- package/dist/agentSessions/SessionRunIDVerifier.js.map +1 -0
- package/dist/agentSessions/index.d.ts +2 -0
- package/dist/agentSessions/index.d.ts.map +1 -1
- package/dist/agentSessions/index.js +10 -3
- package/dist/agentSessions/index.js.map +1 -1
- package/dist/auth/actionAuthorization.d.ts +40 -0
- package/dist/auth/actionAuthorization.d.ts.map +1 -0
- package/dist/auth/actionAuthorization.js +94 -0
- package/dist/auth/actionAuthorization.js.map +1 -0
- package/dist/auth/index.d.ts.map +1 -1
- package/dist/auth/index.js +3 -10
- package/dist/auth/index.js.map +1 -1
- package/dist/auth/magicLink/MagicLinkService.d.ts.map +1 -1
- package/dist/auth/magicLink/MagicLinkService.js +6 -3
- package/dist/auth/magicLink/MagicLinkService.js.map +1 -1
- package/dist/auth/newUsers.d.ts +10 -0
- package/dist/auth/newUsers.d.ts.map +1 -1
- package/dist/auth/newUsers.js +80 -11
- package/dist/auth/newUsers.js.map +1 -1
- package/dist/config.d.ts +4567 -71
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +246 -3
- package/dist/config.js.map +1 -1
- package/dist/context.d.ts +8 -0
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +25 -34
- package/dist/context.js.map +1 -1
- package/dist/generated/graphql-schemas/__mj.d.ts +1073 -10
- package/dist/generated/graphql-schemas/__mj.d.ts.map +1 -1
- package/dist/generated/graphql-schemas/__mj.js +9188 -3649
- package/dist/generated/graphql-schemas/__mj.js.map +1 -1
- package/dist/generic/OrphanedConversationDetailReconciler.js +3 -3
- package/dist/generic/OrphanedConversationDetailReconciler.js.map +1 -1
- package/dist/generic/ResolverBase.d.ts +62 -6
- package/dist/generic/ResolverBase.d.ts.map +1 -1
- package/dist/generic/ResolverBase.js +179 -35
- package/dist/generic/ResolverBase.js.map +1 -1
- package/dist/generic/RunViewResolver.d.ts +4 -0
- package/dist/generic/RunViewResolver.d.ts.map +1 -1
- package/dist/generic/RunViewResolver.js +37 -1
- package/dist/generic/RunViewResolver.js.map +1 -1
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +214 -159
- package/dist/index.js.map +1 -1
- package/dist/isolatedProvider.d.ts +20 -0
- package/dist/isolatedProvider.d.ts.map +1 -0
- package/dist/isolatedProvider.js +22 -0
- package/dist/isolatedProvider.js.map +1 -0
- package/dist/postgresqlCompat.d.ts +8 -0
- package/dist/postgresqlCompat.d.ts.map +1 -0
- package/dist/postgresqlCompat.js +19 -0
- package/dist/postgresqlCompat.js.map +1 -0
- package/dist/postgresqlPoolSettings.d.ts +108 -0
- package/dist/postgresqlPoolSettings.d.ts.map +1 -0
- package/dist/postgresqlPoolSettings.js +134 -0
- package/dist/postgresqlPoolSettings.js.map +1 -0
- package/dist/realtimeProxy/RealtimeProxyServer.d.ts +44 -4
- package/dist/realtimeProxy/RealtimeProxyServer.d.ts.map +1 -1
- package/dist/realtimeProxy/RealtimeProxyServer.js +121 -16
- package/dist/realtimeProxy/RealtimeProxyServer.js.map +1 -1
- package/dist/realtimeProxy/RealtimeRelayTunnel.d.ts +171 -0
- package/dist/realtimeProxy/RealtimeRelayTunnel.d.ts.map +1 -0
- package/dist/realtimeProxy/RealtimeRelayTunnel.js +532 -0
- package/dist/realtimeProxy/RealtimeRelayTunnel.js.map +1 -0
- package/dist/realtimeSessions/RealtimeSessionEventService.d.ts +148 -0
- package/dist/realtimeSessions/RealtimeSessionEventService.d.ts.map +1 -0
- package/dist/realtimeSessions/RealtimeSessionEventService.js +191 -0
- package/dist/realtimeSessions/RealtimeSessionEventService.js.map +1 -0
- package/dist/realtimeSessions/RealtimeSessionVerificationService.d.ts +66 -0
- package/dist/realtimeSessions/RealtimeSessionVerificationService.d.ts.map +1 -0
- package/dist/realtimeSessions/RealtimeSessionVerificationService.js +138 -0
- package/dist/realtimeSessions/RealtimeSessionVerificationService.js.map +1 -0
- package/dist/realtimeSessions/RealtimeVerifyRouter.d.ts +38 -0
- package/dist/realtimeSessions/RealtimeVerifyRouter.d.ts.map +1 -0
- package/dist/realtimeSessions/RealtimeVerifyRouter.js +98 -0
- package/dist/realtimeSessions/RealtimeVerifyRouter.js.map +1 -0
- package/dist/realtimeSessions/SessionVerificationPortsBase.d.ts +61 -0
- package/dist/realtimeSessions/SessionVerificationPortsBase.d.ts.map +1 -0
- package/dist/realtimeSessions/SessionVerificationPortsBase.js +149 -0
- package/dist/realtimeSessions/SessionVerificationPortsBase.js.map +1 -0
- package/dist/realtimeSessions/SlidingWindowRateLimiter.d.ts +57 -0
- package/dist/realtimeSessions/SlidingWindowRateLimiter.d.ts.map +1 -0
- package/dist/realtimeSessions/SlidingWindowRateLimiter.js +69 -0
- package/dist/realtimeSessions/SlidingWindowRateLimiter.js.map +1 -0
- package/dist/realtimeSessions/index.d.ts +17 -0
- package/dist/realtimeSessions/index.d.ts.map +1 -0
- package/dist/realtimeSessions/index.js +17 -0
- package/dist/realtimeSessions/index.js.map +1 -0
- package/dist/realtimeSessions/sessionAccess.d.ts +86 -0
- package/dist/realtimeSessions/sessionAccess.d.ts.map +1 -0
- package/dist/realtimeSessions/sessionAccess.js +90 -0
- package/dist/realtimeSessions/sessionAccess.js.map +1 -0
- package/dist/realtimeSessions/sessionConfigStamps.d.ts +70 -0
- package/dist/realtimeSessions/sessionConfigStamps.d.ts.map +1 -0
- package/dist/realtimeSessions/sessionConfigStamps.js +93 -0
- package/dist/realtimeSessions/sessionConfigStamps.js.map +1 -0
- package/dist/realtimeSessions/subscriptionAuthorization.d.ts +65 -0
- package/dist/realtimeSessions/subscriptionAuthorization.d.ts.map +1 -0
- package/dist/realtimeSessions/subscriptionAuthorization.js +71 -0
- package/dist/realtimeSessions/subscriptionAuthorization.js.map +1 -0
- package/dist/realtimeSessions/verificationCore.d.ts +243 -0
- package/dist/realtimeSessions/verificationCore.d.ts.map +1 -0
- package/dist/realtimeSessions/verificationCore.js +356 -0
- package/dist/realtimeSessions/verificationCore.js.map +1 -0
- package/dist/realtimeSessions/verificationPages.d.ts +66 -0
- package/dist/realtimeSessions/verificationPages.d.ts.map +1 -0
- package/dist/realtimeSessions/verificationPages.js +110 -0
- package/dist/realtimeSessions/verificationPages.js.map +1 -0
- package/dist/realtimeSessions/verificationPolicy.d.ts +147 -0
- package/dist/realtimeSessions/verificationPolicy.d.ts.map +1 -0
- package/dist/realtimeSessions/verificationPolicy.js +249 -0
- package/dist/realtimeSessions/verificationPolicy.js.map +1 -0
- package/dist/realtimeSessions/verificationWorkflow.d.ts +263 -0
- package/dist/realtimeSessions/verificationWorkflow.d.ts.map +1 -0
- package/dist/realtimeSessions/verificationWorkflow.js +435 -0
- package/dist/realtimeSessions/verificationWorkflow.js.map +1 -0
- package/dist/realtimeWidget/widgetGuestElevation.d.ts +20 -2
- package/dist/realtimeWidget/widgetGuestElevation.d.ts.map +1 -1
- package/dist/realtimeWidget/widgetGuestElevation.js +31 -2
- package/dist/realtimeWidget/widgetGuestElevation.js.map +1 -1
- package/dist/resolvers/ActionResolver.d.ts +31 -5
- package/dist/resolvers/ActionResolver.d.ts.map +1 -1
- package/dist/resolvers/ActionResolver.js +75 -14
- package/dist/resolvers/ActionResolver.js.map +1 -1
- package/dist/resolvers/AdhocQueryResolver.d.ts +35 -17
- package/dist/resolvers/AdhocQueryResolver.d.ts.map +1 -1
- package/dist/resolvers/AdhocQueryResolver.js +92 -166
- package/dist/resolvers/AdhocQueryResolver.js.map +1 -1
- package/dist/resolvers/CacheStatsResolver.d.ts +27 -0
- package/dist/resolvers/CacheStatsResolver.d.ts.map +1 -1
- package/dist/resolvers/CacheStatsResolver.js +113 -2
- package/dist/resolvers/CacheStatsResolver.js.map +1 -1
- package/dist/resolvers/ClientToolRequestResolver.d.ts +4 -2
- package/dist/resolvers/ClientToolRequestResolver.d.ts.map +1 -1
- package/dist/resolvers/ClientToolRequestResolver.js +28 -10
- package/dist/resolvers/ClientToolRequestResolver.js.map +1 -1
- package/dist/resolvers/EntityRecordNameResolver.d.ts +7 -23
- package/dist/resolvers/EntityRecordNameResolver.d.ts.map +1 -1
- package/dist/resolvers/EntityRecordNameResolver.js +9 -47
- package/dist/resolvers/EntityRecordNameResolver.js.map +1 -1
- package/dist/resolvers/FetchEntityVectorsResolver.d.ts +12 -1
- package/dist/resolvers/FetchEntityVectorsResolver.d.ts.map +1 -1
- package/dist/resolvers/FetchEntityVectorsResolver.js +83 -2
- package/dist/resolvers/FetchEntityVectorsResolver.js.map +1 -1
- package/dist/resolvers/GetDataResolver.d.ts.map +1 -1
- package/dist/resolvers/GetDataResolver.js +9 -0
- package/dist/resolvers/GetDataResolver.js.map +1 -1
- package/dist/resolvers/HumanHandoffResolver.d.ts +107 -0
- package/dist/resolvers/HumanHandoffResolver.d.ts.map +1 -0
- package/dist/resolvers/HumanHandoffResolver.js +330 -0
- package/dist/resolvers/HumanHandoffResolver.js.map +1 -0
- package/dist/resolvers/MCPResolver.d.ts.map +1 -1
- package/dist/resolvers/MCPResolver.js +9 -4
- package/dist/resolvers/MCPResolver.js.map +1 -1
- package/dist/resolvers/MeetingResolver.d.ts +69 -0
- package/dist/resolvers/MeetingResolver.d.ts.map +1 -0
- package/dist/resolvers/MeetingResolver.js +381 -0
- package/dist/resolvers/MeetingResolver.js.map +1 -0
- package/dist/resolvers/RealtimeBridgeResolver.d.ts +88 -3
- package/dist/resolvers/RealtimeBridgeResolver.d.ts.map +1 -1
- package/dist/resolvers/RealtimeBridgeResolver.js +352 -12
- package/dist/resolvers/RealtimeBridgeResolver.js.map +1 -1
- package/dist/resolvers/RealtimeClientSessionResolver.d.ts +156 -108
- package/dist/resolvers/RealtimeClientSessionResolver.d.ts.map +1 -1
- package/dist/resolvers/RealtimeClientSessionResolver.js +395 -293
- package/dist/resolvers/RealtimeClientSessionResolver.js.map +1 -1
- package/dist/resolvers/RealtimeSessionEventsResolver.d.ts +61 -0
- package/dist/resolvers/RealtimeSessionEventsResolver.d.ts.map +1 -0
- package/dist/resolvers/RealtimeSessionEventsResolver.js +130 -0
- package/dist/resolvers/RealtimeSessionEventsResolver.js.map +1 -0
- package/dist/resolvers/RealtimeSessionVerificationResolver.d.ts +85 -0
- package/dist/resolvers/RealtimeSessionVerificationResolver.d.ts.map +1 -0
- package/dist/resolvers/RealtimeSessionVerificationResolver.js +188 -0
- package/dist/resolvers/RealtimeSessionVerificationResolver.js.map +1 -0
- package/dist/resolvers/RemoteBrowserActionResolver.d.ts +2 -0
- package/dist/resolvers/RemoteBrowserActionResolver.d.ts.map +1 -1
- package/dist/resolvers/RemoteBrowserActionResolver.js +5 -1
- package/dist/resolvers/RemoteBrowserActionResolver.js.map +1 -1
- package/dist/resolvers/RunAIAgentResolver.d.ts +10 -0
- package/dist/resolvers/RunAIAgentResolver.d.ts.map +1 -1
- package/dist/resolvers/RunAIAgentResolver.js +68 -11
- package/dist/resolvers/RunAIAgentResolver.js.map +1 -1
- package/dist/resolvers/RunTemplateResolver.d.ts.map +1 -1
- package/dist/resolvers/RunTemplateResolver.js +12 -11
- package/dist/resolvers/RunTemplateResolver.js.map +1 -1
- package/dist/resolvers/SyncDataResolver.d.ts.map +1 -1
- package/dist/resolvers/SyncDataResolver.js +6 -2
- package/dist/resolvers/SyncDataResolver.js.map +1 -1
- package/dist/resolvers/SyncRolesUsersResolver.d.ts +2 -0
- package/dist/resolvers/SyncRolesUsersResolver.d.ts.map +1 -1
- package/dist/resolvers/SyncRolesUsersResolver.js +23 -6
- package/dist/resolvers/SyncRolesUsersResolver.js.map +1 -1
- package/dist/resolvers/UserAvatarResolver.d.ts +16 -0
- package/dist/resolvers/UserAvatarResolver.d.ts.map +1 -0
- package/dist/resolvers/UserAvatarResolver.js +124 -0
- package/dist/resolvers/UserAvatarResolver.js.map +1 -0
- package/dist/resolvers/UserResolver.d.ts.map +1 -1
- package/dist/resolvers/UserResolver.js +2 -17
- package/dist/resolvers/UserResolver.js.map +1 -1
- package/dist/resolvers/adhocTimeout.d.ts +7 -0
- package/dist/resolvers/adhocTimeout.d.ts.map +1 -0
- package/dist/resolvers/adhocTimeout.js +12 -0
- package/dist/resolvers/adhocTimeout.js.map +1 -0
- package/dist/resolvers/agentVisionConsentAudit.d.ts +37 -0
- package/dist/resolvers/agentVisionConsentAudit.d.ts.map +1 -0
- package/dist/resolvers/agentVisionConsentAudit.js +63 -0
- package/dist/resolvers/agentVisionConsentAudit.js.map +1 -0
- package/dist/resolvers/avatarInputValidation.d.ts +40 -0
- package/dist/resolvers/avatarInputValidation.d.ts.map +1 -0
- package/dist/resolvers/avatarInputValidation.js +97 -0
- package/dist/resolvers/avatarInputValidation.js.map +1 -0
- package/dist/resolvers/currentUserRoles.d.ts +29 -0
- package/dist/resolvers/currentUserRoles.d.ts.map +1 -1
- package/dist/resolvers/currentUserRoles.js +30 -0
- package/dist/resolvers/currentUserRoles.js.map +1 -1
- package/dist/resolvers/meetings/index.d.ts +5 -0
- package/dist/resolvers/meetings/index.d.ts.map +1 -0
- package/dist/resolvers/meetings/index.js +5 -0
- package/dist/resolvers/meetings/index.js.map +1 -0
- package/dist/resolvers/meetings/meetingHelpers.d.ts +17 -0
- package/dist/resolvers/meetings/meetingHelpers.d.ts.map +1 -0
- package/dist/resolvers/meetings/meetingHelpers.js +212 -0
- package/dist/resolvers/meetings/meetingHelpers.js.map +1 -0
- package/dist/resolvers/meetings/meetingMutations.d.ts +18 -0
- package/dist/resolvers/meetings/meetingMutations.d.ts.map +1 -0
- package/dist/resolvers/meetings/meetingMutations.js +439 -0
- package/dist/resolvers/meetings/meetingMutations.js.map +1 -0
- package/dist/resolvers/meetings/meetingQueries.d.ts +7 -0
- package/dist/resolvers/meetings/meetingQueries.d.ts.map +1 -0
- package/dist/resolvers/meetings/meetingQueries.js +113 -0
- package/dist/resolvers/meetings/meetingQueries.js.map +1 -0
- package/dist/resolvers/meetings/meetingTypes.d.ts +89 -0
- package/dist/resolvers/meetings/meetingTypes.d.ts.map +1 -0
- package/dist/resolvers/meetings/meetingTypes.js +345 -0
- package/dist/resolvers/meetings/meetingTypes.js.map +1 -0
- package/dist/rest/ViewOperationsHandler.d.ts.map +1 -1
- package/dist/rest/ViewOperationsHandler.js +8 -5
- package/dist/rest/ViewOperationsHandler.js.map +1 -1
- package/dist/services/TaskGraphActionRunner.d.ts +8 -0
- package/dist/services/TaskGraphActionRunner.d.ts.map +1 -1
- package/dist/services/TaskGraphActionRunner.js +27 -1
- package/dist/services/TaskGraphActionRunner.js.map +1 -1
- package/dist/services/TaskGraphContinuationDeliverer.d.ts +4 -3
- package/dist/services/TaskGraphContinuationDeliverer.d.ts.map +1 -1
- package/dist/services/TaskGraphContinuationDeliverer.js +13 -7
- package/dist/services/TaskGraphContinuationDeliverer.js.map +1 -1
- package/dist/services/WorkQueueHostService.d.ts +36 -0
- package/dist/services/WorkQueueHostService.d.ts.map +1 -0
- package/dist/services/WorkQueueHostService.js +97 -0
- package/dist/services/WorkQueueHostService.js.map +1 -0
- package/dist/services/workQueueConfig.d.ts +103 -0
- package/dist/services/workQueueConfig.d.ts.map +1 -0
- package/dist/services/workQueueConfig.js +48 -0
- package/dist/services/workQueueConfig.js.map +1 -0
- package/dist/sharedCache.d.ts +105 -0
- package/dist/sharedCache.d.ts.map +1 -0
- package/dist/sharedCache.js +276 -0
- package/dist/sharedCache.js.map +1 -0
- package/dist/types.d.ts +11 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +97 -94
- package/src/__tests__/ActionResolver.authorization.test.ts +353 -0
- package/src/__tests__/AdhocQueryResolver.bugs.test.ts +14 -35
- package/src/__tests__/AdhocQueryResolver.pagination.test.ts +6 -2
- package/src/__tests__/AdhocQueryResolver.scopeGuard.test.ts +3 -3
- package/src/__tests__/AdhocQueryResolver.sqlAuthorizer.test.ts +104 -0
- package/src/__tests__/BridgeHostInstance.test.ts +232 -0
- package/src/__tests__/ClientToolRequestResolver.test.ts +116 -0
- package/src/__tests__/EntityRecordNameResolver.fieldSecurity.test.ts +27 -72
- package/src/__tests__/FetchEntityVectorsResolver.test.ts +285 -0
- package/src/__tests__/HostInstance.test.ts +84 -0
- package/src/__tests__/HumanHandoffResolver.test.ts +250 -0
- package/src/__tests__/MeetingResolver.test.ts +448 -0
- package/src/__tests__/RealtimeBridgeResolver.test.ts +651 -4
- package/src/__tests__/RealtimeClientSessionResolver.configTamper.test.ts +383 -0
- package/src/__tests__/RealtimeClientSessionResolver.test.ts +682 -58
- package/src/__tests__/RealtimeProxyServer.test.ts +16 -1
- package/src/__tests__/RealtimeRelay.test.ts +876 -0
- package/src/__tests__/RemoteBrowserActionResolver.goalRunLink.test.ts +129 -0
- package/src/__tests__/ResolverBase.adhocReadScope.test.ts +96 -0
- package/src/__tests__/ResolverBase.aggregateScreen.test.ts +174 -0
- package/src/__tests__/ResolverBase.clientOldValues.test.ts +6 -3
- package/src/__tests__/ResolverBase.filterEscaping.test.ts +21 -2
- package/src/__tests__/ResolverBase.includeBinaryFields.test.ts +291 -0
- package/src/__tests__/ReturningVisitorRecap.test.ts +115 -0
- package/src/__tests__/RunAIAgentResolver.branch.test.ts +169 -0
- package/src/__tests__/RunAIAgentResolver.historyFrom.test.ts +4 -4
- package/src/__tests__/RunAIAgentResolver.stoppedPredecessor.test.ts +166 -0
- package/src/__tests__/RunTemplateResolver.test.ts +132 -0
- package/src/__tests__/RunViewResolver.cacheCheckForwarding.test.ts +63 -0
- package/src/__tests__/SessionJanitor.test.ts +845 -18
- package/src/__tests__/SessionManager.test.ts +213 -17
- package/src/__tests__/SessionRunIDVerifier.test.ts +251 -0
- package/src/__tests__/SyncRolesUsersResolver.userRoles.test.ts +97 -0
- package/src/__tests__/TaskGraphActionRunner.durablePayload.test.ts +41 -0
- package/src/__tests__/TaskGraphContinuationDeliverer.test.ts +50 -3
- package/src/__tests__/UserAvatarResolver.test.ts +255 -0
- package/src/__tests__/UserResolver.currentUser.test.ts +16 -1
- package/src/__tests__/WorkQueueHostService.test.ts +133 -0
- package/src/__tests__/actionAuthorization.test.ts +130 -0
- package/src/__tests__/adhocTimeoutClamp.test.ts +26 -0
- package/src/__tests__/agentVisionConsentAudit.test.ts +118 -0
- package/src/__tests__/avatarInputValidation.test.ts +160 -0
- package/src/__tests__/isolatedProviderTransactions.test.ts +169 -0
- package/src/__tests__/magicLinkService.consume.test.ts +6 -0
- package/src/__tests__/magicLinkService.provisionLog.test.ts +5 -0
- package/src/__tests__/newUsers.template.test.ts +151 -0
- package/src/__tests__/newUsers.test.ts +74 -5
- package/src/__tests__/orphanedConversationDetailReconciler.test.ts +17 -2
- package/src/__tests__/postgresqlPoolSettings.test.ts +131 -0
- package/src/__tests__/realtimeSessions/RealtimeSessionEventService.test.ts +201 -0
- package/src/__tests__/realtimeSessions/RealtimeSessionEventsResolver.test.ts +215 -0
- package/src/__tests__/realtimeSessions/RealtimeSessionVerificationResolver.test.ts +102 -0
- package/src/__tests__/realtimeSessions/RealtimeSessionVerificationService.test.ts +349 -0
- package/src/__tests__/realtimeSessions/RealtimeVerifyRouter.test.ts +131 -0
- package/src/__tests__/realtimeSessions/SlidingWindowRateLimiter.test.ts +56 -0
- package/src/__tests__/realtimeSessions/helpers.ts +4 -0
- package/src/__tests__/realtimeSessions/sessionAccess.test.ts +129 -0
- package/src/__tests__/realtimeSessions/sessionConfigStamps.test.ts +124 -0
- package/src/__tests__/realtimeSessions/verificationCore.test.ts +355 -0
- package/src/__tests__/realtimeSessions/verificationPages.test.ts +84 -0
- package/src/__tests__/realtimeSessions/verificationPolicy.test.ts +226 -0
- package/src/__tests__/realtimeSessions/verificationWorkflow.test.ts +633 -0
- package/src/__tests__/resolverBase.fls.test.ts +87 -4
- package/src/__tests__/serverExtensionReservedRoots.test.ts +2 -0
- package/src/__tests__/sharedCache.test.ts +310 -0
- package/src/__tests__/translateBracketsToPG.test.ts +20 -0
- package/src/__tests__/widgetGuestElevation.test.ts +44 -0
- package/src/agentSessions/BridgeHostInstance.ts +32 -0
- package/src/agentSessions/HostInstance.ts +124 -28
- package/src/agentSessions/ReturningVisitorRecap.ts +7 -3
- package/src/agentSessions/SessionJanitor.ts +543 -57
- package/src/agentSessions/SessionManager.ts +125 -25
- package/src/agentSessions/SessionRunIDVerifier.ts +171 -0
- package/src/agentSessions/index.ts +10 -3
- package/src/auth/actionAuthorization.ts +116 -0
- package/src/auth/index.ts +3 -8
- package/src/auth/magicLink/MagicLinkService.ts +6 -3
- package/src/auth/newUsers.ts +99 -11
- package/src/config.ts +255 -3
- package/src/context.ts +26 -34
- package/src/generated/graphql-schemas/__mj.ts +22701 -18838
- package/src/generic/OrphanedConversationDetailReconciler.ts +3 -3
- package/src/generic/ResolverBase.ts +210 -36
- package/src/generic/RunViewResolver.ts +37 -2
- package/src/index.ts +236 -170
- package/src/isolatedProvider.ts +22 -0
- package/src/postgresqlCompat.ts +21 -0
- package/src/postgresqlPoolSettings.ts +213 -0
- package/src/realtimeProxy/RealtimeProxyServer.ts +148 -16
- package/src/realtimeProxy/RealtimeRelayTunnel.ts +645 -0
- package/src/realtimeSessions/README.md +179 -0
- package/src/realtimeSessions/RealtimeSessionEventService.ts +274 -0
- package/src/realtimeSessions/RealtimeSessionVerificationService.ts +167 -0
- package/src/realtimeSessions/RealtimeVerifyRouter.ts +108 -0
- package/src/realtimeSessions/SessionVerificationPortsBase.ts +189 -0
- package/src/realtimeSessions/SlidingWindowRateLimiter.ts +92 -0
- package/src/realtimeSessions/index.ts +16 -0
- package/src/realtimeSessions/sessionAccess.ts +141 -0
- package/src/realtimeSessions/sessionConfigStamps.ts +123 -0
- package/src/realtimeSessions/subscriptionAuthorization.ts +116 -0
- package/src/realtimeSessions/verificationCore.ts +502 -0
- package/src/realtimeSessions/verificationPages.ts +149 -0
- package/src/realtimeSessions/verificationPolicy.ts +321 -0
- package/src/realtimeSessions/verificationWorkflow.ts +702 -0
- package/src/realtimeWidget/widgetGuestElevation.ts +34 -2
- package/src/resolvers/ActionResolver.ts +84 -21
- package/src/resolvers/AdhocQueryResolver.ts +105 -187
- package/src/resolvers/CacheStatsResolver.ts +89 -2
- package/src/resolvers/ClientToolRequestResolver.ts +25 -7
- package/src/resolvers/EntityRecordNameResolver.ts +9 -51
- package/src/resolvers/FetchEntityVectorsResolver.ts +97 -2
- package/src/resolvers/GetDataResolver.ts +10 -0
- package/src/resolvers/HumanHandoffResolver.ts +312 -0
- package/src/resolvers/MCPResolver.ts +8 -5
- package/src/resolvers/MeetingResolver.ts +438 -0
- package/src/resolvers/RealtimeBridgeResolver.ts +385 -19
- package/src/resolvers/RealtimeClientSessionResolver.ts +503 -344
- package/src/resolvers/RealtimeSessionEventsResolver.ts +133 -0
- package/src/resolvers/RealtimeSessionVerificationResolver.ts +174 -0
- package/src/resolvers/RemoteBrowserActionResolver.ts +11 -1
- package/src/resolvers/RunAIAgentResolver.ts +78 -11
- package/src/resolvers/RunTemplateResolver.ts +13 -12
- package/src/resolvers/SyncDataResolver.ts +6 -2
- package/src/resolvers/SyncRolesUsersResolver.ts +24 -6
- package/src/resolvers/UserAvatarResolver.ts +111 -0
- package/src/resolvers/UserResolver.ts +2 -16
- package/src/resolvers/adhocTimeout.ts +12 -0
- package/src/resolvers/agentVisionConsentAudit.ts +82 -0
- package/src/resolvers/avatarInputValidation.ts +123 -0
- package/src/resolvers/currentUserRoles.ts +32 -1
- package/src/resolvers/meetings/index.ts +4 -0
- package/src/resolvers/meetings/meetingHelpers.ts +307 -0
- package/src/resolvers/meetings/meetingMutations.ts +556 -0
- package/src/resolvers/meetings/meetingQueries.ts +172 -0
- package/src/resolvers/meetings/meetingTypes.ts +238 -0
- package/src/rest/ViewOperationsHandler.ts +8 -5
- package/src/services/TaskGraphActionRunner.ts +29 -1
- package/src/services/TaskGraphContinuationDeliverer.ts +13 -7
- package/src/services/WorkQueueHostService.ts +129 -0
- package/src/services/workQueueConfig.ts +52 -0
- package/src/sharedCache.ts +302 -0
- package/src/types.ts +12 -0
- package/dist/resolvers/adhoc-query-helpers.d.ts +0 -33
- package/dist/resolvers/adhoc-query-helpers.d.ts.map +0 -1
- package/dist/resolvers/adhoc-query-helpers.js +0 -50
- package/dist/resolvers/adhoc-query-helpers.js.map +0 -1
- package/src/__tests__/adhoc-query-helpers.test.ts +0 -50
- package/src/resolvers/adhoc-query-helpers.ts +0 -67
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { Field, Float, Int, ObjectType, Query, Resolver } from 'type-graphql';
|
|
2
|
-
import { LocalCacheManager, CacheStats, CacheEntryType } from '@memberjunction/core';
|
|
1
|
+
import { Arg, Field, Float, Int, ObjectType, Query, Resolver } from 'type-graphql';
|
|
2
|
+
import { BaseEngine, BaseEngineRegistry, LocalCacheManager, CacheStats, CacheEntryType } from '@memberjunction/core';
|
|
3
|
+
import type { EngineStateCensus } from '@memberjunction/core';
|
|
3
4
|
import { RequireSystemUser } from '../directives/index.js';
|
|
4
5
|
|
|
5
6
|
// ============================================================================
|
|
@@ -66,10 +67,83 @@ class CacheStatsDetailGQL extends CacheStatsGQL {
|
|
|
66
67
|
EntityBreakdown: CacheEntityBreakdownGQL[];
|
|
67
68
|
}
|
|
68
69
|
|
|
70
|
+
@ObjectType()
|
|
71
|
+
class EnginePropertyCensusGQL {
|
|
72
|
+
@Field(() => String)
|
|
73
|
+
PropertyName: string;
|
|
74
|
+
|
|
75
|
+
@Field(() => String, { nullable: true })
|
|
76
|
+
EntityName?: string;
|
|
77
|
+
|
|
78
|
+
@Field(() => String, { nullable: true })
|
|
79
|
+
DatasetName?: string;
|
|
80
|
+
|
|
81
|
+
@Field(() => Int)
|
|
82
|
+
RowCount: number;
|
|
83
|
+
|
|
84
|
+
@Field(() => String, { nullable: true })
|
|
85
|
+
MaxUpdatedAt: string | null;
|
|
86
|
+
|
|
87
|
+
@Field(() => String, { nullable: true })
|
|
88
|
+
IdentityHash: string | null;
|
|
89
|
+
|
|
90
|
+
@Field(() => Boolean)
|
|
91
|
+
LoadedSuccessfully: boolean;
|
|
92
|
+
|
|
93
|
+
@Field(() => Boolean)
|
|
94
|
+
PermissionDenied: boolean;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
@ObjectType()
|
|
98
|
+
class EngineDerivedCountGQL {
|
|
99
|
+
@Field(() => String)
|
|
100
|
+
Name: string;
|
|
101
|
+
|
|
102
|
+
@Field(() => Int)
|
|
103
|
+
Value: number;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
@ObjectType()
|
|
107
|
+
class EngineStateCensusGQL {
|
|
108
|
+
@Field(() => String)
|
|
109
|
+
EngineClass: string;
|
|
110
|
+
|
|
111
|
+
@Field(() => Boolean)
|
|
112
|
+
Loaded: boolean;
|
|
113
|
+
|
|
114
|
+
@Field(() => Boolean)
|
|
115
|
+
PermissionConstrained: boolean;
|
|
116
|
+
|
|
117
|
+
@Field(() => [EnginePropertyCensusGQL])
|
|
118
|
+
Properties: EnginePropertyCensusGQL[];
|
|
119
|
+
|
|
120
|
+
@Field(() => [EngineDerivedCountGQL])
|
|
121
|
+
Derived: EngineDerivedCountGQL[];
|
|
122
|
+
}
|
|
123
|
+
|
|
69
124
|
// ============================================================================
|
|
70
125
|
// Helpers (pure core)
|
|
71
126
|
// ============================================================================
|
|
72
127
|
|
|
128
|
+
function censusToGQL(census: EngineStateCensus): EngineStateCensusGQL {
|
|
129
|
+
const gql = new EngineStateCensusGQL();
|
|
130
|
+
gql.EngineClass = census.EngineClass;
|
|
131
|
+
gql.Loaded = census.Loaded;
|
|
132
|
+
gql.PermissionConstrained = census.PermissionConstrained;
|
|
133
|
+
gql.Properties = census.Properties.map(p => Object.assign(new EnginePropertyCensusGQL(), p));
|
|
134
|
+
gql.Derived = Object.entries(census.Derived).map(([Name, Value]) => Object.assign(new EngineDerivedCountGQL(), { Name, Value }));
|
|
135
|
+
return gql;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/** Census of every registered engine in this process, optionally narrowed to one class name. */
|
|
139
|
+
function buildEngineCensus(engineClass?: string): EngineStateCensusGQL[] {
|
|
140
|
+
return BaseEngineRegistry.Instance.GetAllEngines()
|
|
141
|
+
.filter((engine): engine is BaseEngine<unknown> => engine instanceof BaseEngine)
|
|
142
|
+
.filter(engine => !engineClass || engine.constructor.name === engineClass)
|
|
143
|
+
.map(engine => censusToGQL(engine.GetStateCensus()))
|
|
144
|
+
.sort((a, b) => a.EngineClass.localeCompare(b.EngineClass));
|
|
145
|
+
}
|
|
146
|
+
|
|
73
147
|
function toGQL(stats: CacheStats): CacheStatsGQL {
|
|
74
148
|
const gql = new CacheStatsGQL();
|
|
75
149
|
gql.TotalEntries = stats.totalEntries;
|
|
@@ -139,4 +213,17 @@ export class CacheStatsResolver {
|
|
|
139
213
|
result.EntityBreakdown = buildEntityBreakdown();
|
|
140
214
|
return result;
|
|
141
215
|
}
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* What each engine in this server process holds — row counts, newest timestamps, a row-version
|
|
219
|
+
* hash, and engine-specific derived-state counts. Comparing the hashes across servers shows
|
|
220
|
+
* whether they converged; a derived count of zero next to a full array shows lost derived state.
|
|
221
|
+
*/
|
|
222
|
+
@RequireSystemUser()
|
|
223
|
+
@Query(() => [EngineStateCensusGQL])
|
|
224
|
+
EngineStateCensus(
|
|
225
|
+
@Arg('EngineClass', () => String, { nullable: true }) engineClass?: string
|
|
226
|
+
): EngineStateCensusGQL[] {
|
|
227
|
+
return buildEngineCensus(engineClass);
|
|
228
|
+
}
|
|
142
229
|
}
|
|
@@ -14,6 +14,7 @@ import { AppContext } from '../types.js';
|
|
|
14
14
|
import { LogStatus, LogError } from '@memberjunction/core';
|
|
15
15
|
import { ResolverBase } from '../generic/ResolverBase.js';
|
|
16
16
|
import { ClientToolRequestManager, CLIENT_TOOL_REQUEST_TOPIC, ClientToolRequestNotificationPayload } from '@memberjunction/ai-agents';
|
|
17
|
+
import { ParseClientToolMedia } from '@memberjunction/ai-core-plus';
|
|
17
18
|
|
|
18
19
|
@ObjectType()
|
|
19
20
|
export class ClientToolRequestNotification {
|
|
@@ -71,7 +72,9 @@ export class ClientToolRequestResolver extends ResolverBase {
|
|
|
71
72
|
/**
|
|
72
73
|
* Client sends the result of executing a client tool back to the server.
|
|
73
74
|
* This resolves the pending Promise in ClientToolRequestManager so the
|
|
74
|
-
* agent loop can continue.
|
|
75
|
+
* agent loop can continue. `media` is an optional JSON array of images.
|
|
76
|
+
* When `media` fails validation or `result` is not valid JSON, the request
|
|
77
|
+
* resolves as a failed result.
|
|
75
78
|
*/
|
|
76
79
|
@Mutation(() => Boolean)
|
|
77
80
|
async RespondToClientToolRequest(
|
|
@@ -79,15 +82,25 @@ export class ClientToolRequestResolver extends ResolverBase {
|
|
|
79
82
|
@Arg('success') success: boolean,
|
|
80
83
|
@Arg('result', { nullable: true }) result: string | undefined,
|
|
81
84
|
@Arg('errorMessage', { nullable: true }) errorMessage: string | undefined,
|
|
85
|
+
@Arg('media', { nullable: true }) media: string | undefined,
|
|
82
86
|
@Ctx() _context: AppContext = {} as AppContext
|
|
83
87
|
): Promise<boolean> {
|
|
84
88
|
try {
|
|
85
|
-
const
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
89
|
+
const parsedMedia = ParseClientToolMedia(media);
|
|
90
|
+
// `=== true` narrows the union; this package compiles without strictNullChecks.
|
|
91
|
+
const found = ClientToolRequestManager.Instance.ReceiveResponse(parsedMedia.ok === true
|
|
92
|
+
? {
|
|
93
|
+
RequestID: requestID,
|
|
94
|
+
Success: success,
|
|
95
|
+
Result: result ? JSON.parse(result) : undefined,
|
|
96
|
+
ErrorMessage: errorMessage,
|
|
97
|
+
Media: parsedMedia.media.length ? parsedMedia.media : undefined
|
|
98
|
+
}
|
|
99
|
+
: {
|
|
100
|
+
RequestID: requestID,
|
|
101
|
+
Success: false,
|
|
102
|
+
ErrorMessage: `Client tool media rejected: ${parsedMedia.error}`
|
|
103
|
+
});
|
|
91
104
|
|
|
92
105
|
if (!found) {
|
|
93
106
|
LogError(`RespondToClientToolRequest: no pending request for ${requestID} (may have timed out)`);
|
|
@@ -96,6 +109,11 @@ export class ClientToolRequestResolver extends ResolverBase {
|
|
|
96
109
|
} catch (error) {
|
|
97
110
|
const msg = error instanceof Error ? error.message : String(error);
|
|
98
111
|
LogError(`RespondToClientToolRequest error: ${msg}`);
|
|
112
|
+
ClientToolRequestManager.Instance.ReceiveResponse({
|
|
113
|
+
RequestID: requestID,
|
|
114
|
+
Success: false,
|
|
115
|
+
ErrorMessage: `Client tool response rejected: ${msg}`
|
|
116
|
+
});
|
|
99
117
|
return false;
|
|
100
118
|
}
|
|
101
119
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CompositeKey, DatabaseProviderBase
|
|
1
|
+
import { CompositeKey, DatabaseProviderBase } from '@memberjunction/core';
|
|
2
2
|
import { Arg, Ctx, Field, InputType, ObjectType, Query, Resolver } from 'type-graphql';
|
|
3
3
|
import { AppContext, UserPayload } from '../types.js';
|
|
4
4
|
import { CompositeKeyInputType, CompositeKeyOutputType } from '../generic/KeyInputOutputTypes.js';
|
|
@@ -36,20 +36,13 @@ export class EntityRecordNameResult {
|
|
|
36
36
|
* Resolves a record's display NAME from its primary key — the lookup behind every foreign-key
|
|
37
37
|
* link, breadcrumb and picker label in the UI.
|
|
38
38
|
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
* strips denied fields. Field-level security turned that latent gap into a live bypass — the
|
|
43
|
-
* form-field FK control falls through to this query precisely WHEN the joined display column is
|
|
44
|
-
* denied, so the one case the fallback exists for was the case that leaked.
|
|
39
|
+
* Entity-level read permission is checked here ({@link ResolverBase.CheckUserReadPermissions}).
|
|
40
|
+
* Field- and row-level security are applied by the provider's lookup, for the acting user passed
|
|
41
|
+
* to it: when any field the name is built from is withheld, it answers with no name.
|
|
45
42
|
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
* A field-level denial answers `Success: false` with no name rather than throwing. Callers
|
|
51
|
-
* already treat "no name" as "show the primary key", which is the intended degradation — and it
|
|
52
|
-
* keeps this query from becoming a probe that distinguishes "restricted" from "missing".
|
|
43
|
+
* A withheld name answers `Success: false` with the same status as a record that does not exist.
|
|
44
|
+
* Callers already treat "no name" as "show the primary key", and the identical answer keeps this
|
|
45
|
+
* query from becoming a probe that distinguishes "restricted" from "missing".
|
|
53
46
|
*/
|
|
54
47
|
@Resolver(EntityRecordNameResult)
|
|
55
48
|
export class EntityRecordNameResolver extends ResolverBase {
|
|
@@ -91,53 +84,18 @@ export class EntityRecordNameResolver extends ResolverBase {
|
|
|
91
84
|
const e = md.Entities.find((e) => e.Name === EntityName);
|
|
92
85
|
if (e) {
|
|
93
86
|
const contextUser = userPayload ? this.GetUserFromPayload(userPayload) : undefined;
|
|
94
|
-
|
|
95
|
-
LogDebug(
|
|
96
|
-
`[FieldSecurity] Suppressed GetEntityRecordName for '${EntityName}': ` +
|
|
97
|
-
`the name field is not readable by this user`
|
|
98
|
-
);
|
|
99
|
-
return {
|
|
100
|
-
Success: false,
|
|
101
|
-
Status: `Name for record, or record ${pk.ToString()} itself not found, could be an access issue`,
|
|
102
|
-
CompositeKey: pk,
|
|
103
|
-
EntityName,
|
|
104
|
-
};
|
|
105
|
-
}
|
|
106
|
-
// Pass the acting user through: the provider signature accepts it, and omitting it ran the
|
|
107
|
-
// underlying lookup with no identity at all — so row-level security had nothing to filter on
|
|
108
|
-
// either. The field-level gate above is the column half; this is the row half.
|
|
87
|
+
// The acting user is what field- and row-level security are applied for.
|
|
109
88
|
const recordName = await md.GetEntityRecordName(e.Name, pk, contextUser);
|
|
110
89
|
if (recordName) return { Success: true, Status: 'OK', CompositeKey: pk, RecordName: recordName, EntityName };
|
|
111
90
|
else
|
|
112
91
|
return {
|
|
113
92
|
Success: false,
|
|
114
|
-
Status: `Name for record, or record ${pk.ToString()} itself not found, could be an access issue
|
|
93
|
+
Status: `Name for record, or record ${pk.ToString()} itself not found, could be an access issue`,
|
|
115
94
|
CompositeKey: pk,
|
|
116
95
|
EntityName,
|
|
117
96
|
};
|
|
118
97
|
} else return { Success: false, Status: `Entity ${EntityName} not found`, CompositeKey: pk, EntityName };
|
|
119
98
|
}
|
|
120
|
-
|
|
121
|
-
/**
|
|
122
|
-
* Whether field security withholds this entity's NAME field from the user.
|
|
123
|
-
*
|
|
124
|
-
* Resolves the name field the same way the provider's own lookup does — the designated
|
|
125
|
-
* `IsNameField`, else a field literally called `Name` — so the check cannot drift from the
|
|
126
|
-
* value it is guarding. Fails OPEN only where field security does not apply at all (flag off,
|
|
127
|
-
* no user, no name field), matching every other FLS gate.
|
|
128
|
-
*/
|
|
129
|
-
protected IsNameFieldDeniedToUser(entity: EntityInfo, contextUser?: UserInfo): boolean {
|
|
130
|
-
if (!entity?.EnableFieldLevelSecurity || !contextUser) {
|
|
131
|
-
return false;
|
|
132
|
-
}
|
|
133
|
-
const nameField =
|
|
134
|
-
entity.Fields?.find(f => f.IsNameField) ??
|
|
135
|
-
entity.Fields?.find(f => f.Name?.trim().toLowerCase() === 'name');
|
|
136
|
-
if (!nameField) {
|
|
137
|
-
return false;
|
|
138
|
-
}
|
|
139
|
-
return entity.GetDeniedReadFields(contextUser).has(nameField.Name.trim().toLowerCase());
|
|
140
|
-
}
|
|
141
99
|
}
|
|
142
100
|
|
|
143
101
|
export default EntityRecordNameResolver;
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { Resolver, Query, Arg, Ctx, ObjectType, Field, Float, Int } from 'type-graphql';
|
|
2
2
|
import { AppContext } from '../types.js';
|
|
3
|
-
import { LogError, LogStatus, Metadata, RunView, UserInfo } from '@memberjunction/core';
|
|
3
|
+
import { CompositeKey, EntityInfo, IMetadataProvider, LogError, LogStatus, Metadata, RunView, UserInfo } from '@memberjunction/core';
|
|
4
4
|
import { MJEntityDocumentEntity, MJVectorIndexEntity, MJVectorDatabaseEntity } from '@memberjunction/core-entities';
|
|
5
5
|
import { ResolverBase } from '../generic/ResolverBase.js';
|
|
6
|
+
import { GetReadOnlyProvider } from '../util.js';
|
|
6
7
|
import { GetAIAPIKey } from '@memberjunction/ai';
|
|
7
8
|
import { VectorDBBase } from '@memberjunction/ai-vectordb';
|
|
8
9
|
import { AIEngine } from '@memberjunction/aiengine';
|
|
@@ -50,7 +51,7 @@ export class FetchEntityVectorsResolver extends ResolverBase {
|
|
|
50
51
|
@Arg('entityDocumentID') entityDocumentID: string,
|
|
51
52
|
@Arg('maxRecords', () => Int, { nullable: true }) maxRecords: number | undefined,
|
|
52
53
|
@Arg('filter', { nullable: true }) filter: string | undefined,
|
|
53
|
-
@Ctx() { userPayload }: AppContext = {} as AppContext
|
|
54
|
+
@Ctx() { userPayload, providers }: AppContext = {} as AppContext
|
|
54
55
|
): Promise<FetchEntityVectorsResult> {
|
|
55
56
|
const startTime = Date.now();
|
|
56
57
|
try {
|
|
@@ -85,6 +86,17 @@ export class FetchEntityVectorsResolver extends ResolverBase {
|
|
|
85
86
|
);
|
|
86
87
|
}
|
|
87
88
|
|
|
89
|
+
// Providers that keep their vectors in MJ, keyed by EntityDocumentID (the in-process
|
|
90
|
+
// SimpleVectorServiceProvider), can't be listed through QueryIndex: they key by the
|
|
91
|
+
// document ID rather than the index name, aren't handed the context user, and return
|
|
92
|
+
// matches without vector values. Read the stored Entity Record Document rows instead.
|
|
93
|
+
if (vectorDBInstance.QueryKeyIsEntityDocumentID) {
|
|
94
|
+
const md = GetReadOnlyProvider(providers, { allowFallbackToReadWrite: true }) ?? Metadata.Provider;
|
|
95
|
+
const results = await this.fetchStoredVectors(entityDoc, limit, filter, currentUser, md);
|
|
96
|
+
LogStatus(`FetchEntityVectors: Loaded ${results.length} stored vectors for entity "${entityDoc.Entity}" in ${Date.now() - startTime}ms`);
|
|
97
|
+
return { Success: true, Results: results, TotalCount: results.length, ElapsedMs: Date.now() - startTime };
|
|
98
|
+
}
|
|
99
|
+
|
|
88
100
|
// Step 4: Query with zero vector + Entity metadata filter.
|
|
89
101
|
// Pinecone's list API doesn't support metadata filtering, but query does.
|
|
90
102
|
// A zero vector returns results in arbitrary order (similarity is meaningless),
|
|
@@ -227,6 +239,89 @@ export class FetchEntityVectorsResolver extends ResolverBase {
|
|
|
227
239
|
return instance;
|
|
228
240
|
}
|
|
229
241
|
|
|
242
|
+
/**
|
|
243
|
+
* Load the vectors an EntityDocument stored in MJ (`MJ: Entity Record Documents.VectorJSON`),
|
|
244
|
+
* restricted to the entity records that pass `filter`. Each item's metadata carries the entity
|
|
245
|
+
* name, the record ID and the record's name fields, which is what the cluster view labels from.
|
|
246
|
+
*/
|
|
247
|
+
private async fetchStoredVectors(
|
|
248
|
+
entityDoc: MJEntityDocumentEntity,
|
|
249
|
+
limit: number,
|
|
250
|
+
filter: string | undefined,
|
|
251
|
+
contextUser: UserInfo,
|
|
252
|
+
md: IMetadataProvider
|
|
253
|
+
): Promise<EntityVectorItem[]> {
|
|
254
|
+
const entityInfo = md.EntityByName(entityDoc.Entity);
|
|
255
|
+
if (!entityInfo) {
|
|
256
|
+
throw new Error(`Entity "${entityDoc.Entity}" not found in metadata`);
|
|
257
|
+
}
|
|
258
|
+
const labelsByRecordID = await this.loadRecordLabels(entityInfo, filter, contextUser);
|
|
259
|
+
|
|
260
|
+
const rv = new RunView();
|
|
261
|
+
const docResult = await rv.RunView<{ ID: string; RecordID: string; VectorJSON: string }>({
|
|
262
|
+
EntityName: 'MJ: Entity Record Documents',
|
|
263
|
+
ExtraFilter: `EntityDocumentID='${EscapeSQLString(entityDoc.ID)}' AND VectorJSON IS NOT NULL`,
|
|
264
|
+
Fields: ['ID', 'RecordID', 'VectorJSON'],
|
|
265
|
+
IgnoreMaxRows: true,
|
|
266
|
+
ResultType: 'simple',
|
|
267
|
+
}, contextUser);
|
|
268
|
+
if (!docResult.Success) {
|
|
269
|
+
throw new Error(`Failed to load stored vectors: ${docResult.ErrorMessage}`);
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
const results: EntityVectorItem[] = [];
|
|
273
|
+
for (const row of docResult.Results) {
|
|
274
|
+
const labels = labelsByRecordID.get(row.RecordID.toLowerCase());
|
|
275
|
+
if (!labels) continue; // filtered out, not readable by this user, or the record no longer exists
|
|
276
|
+
results.push({
|
|
277
|
+
ID: row.ID,
|
|
278
|
+
Values: JSON.parse(row.VectorJSON) as number[],
|
|
279
|
+
Metadata: JSON.stringify({ Entity: entityDoc.Entity, RecordID: row.RecordID, ...labels }),
|
|
280
|
+
});
|
|
281
|
+
if (results.length >= limit) break;
|
|
282
|
+
}
|
|
283
|
+
return results;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
* Map each record that passes `filter` to its name-field values, keyed by the same compact
|
|
288
|
+
* record-ID form the vector sync writes to `MJ: Entity Record Documents.RecordID` (lower-cased).
|
|
289
|
+
*/
|
|
290
|
+
private async loadRecordLabels(
|
|
291
|
+
entityInfo: EntityInfo,
|
|
292
|
+
filter: string | undefined,
|
|
293
|
+
contextUser: UserInfo
|
|
294
|
+
): Promise<Map<string, Record<string, string>>> {
|
|
295
|
+
const nameFields = entityInfo.Fields.filter(f => f.IsNameField).map(f => f.Name);
|
|
296
|
+
if (nameFields.length === 0 && entityInfo.NameField) {
|
|
297
|
+
nameFields.push(entityInfo.NameField.Name);
|
|
298
|
+
}
|
|
299
|
+
const keyFields = entityInfo.PrimaryKeys.map(pk => pk.Name);
|
|
300
|
+
|
|
301
|
+
const rv = new RunView();
|
|
302
|
+
const result = await rv.RunView<Record<string, unknown>>({
|
|
303
|
+
EntityName: entityInfo.Name,
|
|
304
|
+
ExtraFilter: filter || undefined,
|
|
305
|
+
Fields: [...new Set([...keyFields, ...nameFields])],
|
|
306
|
+
IgnoreMaxRows: true,
|
|
307
|
+
ResultType: 'simple',
|
|
308
|
+
}, contextUser);
|
|
309
|
+
if (!result.Success) {
|
|
310
|
+
throw new Error(`Failed to load "${entityInfo.Name}" records: ${result.ErrorMessage}`);
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
const map = new Map<string, Record<string, string>>();
|
|
314
|
+
for (const row of result.Results) {
|
|
315
|
+
const key = CompositeKey.FromEntityRecord(entityInfo, row).ToCompactURLSegment().toLowerCase();
|
|
316
|
+
const labels: Record<string, string> = {};
|
|
317
|
+
for (const name of nameFields) {
|
|
318
|
+
if (row[name] != null) labels[name] = String(row[name]);
|
|
319
|
+
}
|
|
320
|
+
map.set(key, labels);
|
|
321
|
+
}
|
|
322
|
+
return map;
|
|
323
|
+
}
|
|
324
|
+
|
|
230
325
|
private errorResult(message: string, startTime: number): FetchEntityVectorsResult {
|
|
231
326
|
return {
|
|
232
327
|
Success: false,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Arg, Ctx, Field, InputType, ObjectType, Query } from 'type-graphql';
|
|
2
|
+
import { SQLExpressionValidator } from '@memberjunction/global';
|
|
2
3
|
import { AppContext } from '../types.js';
|
|
3
4
|
import { LogError, LogStatus, LogStatusEx, Metadata } from '@memberjunction/core';
|
|
4
5
|
import { QueryCompositionEngine } from '@memberjunction/generic-database-provider';
|
|
@@ -154,6 +155,15 @@ export class GetDataResolver {
|
|
|
154
155
|
resolvedSQL = compositionResult.ResolvedSQL;
|
|
155
156
|
}
|
|
156
157
|
|
|
158
|
+
// Defense-in-depth: even system-token holders get SELECT-only SQL here.
|
|
159
|
+
// The read-only pool is the primary control, but if it is ever
|
|
160
|
+
// misconfigured to a read-write login this validator still refuses DML/DDL
|
|
161
|
+
// (mirrors AdhocQueryResolver).
|
|
162
|
+
const validation = SQLExpressionValidator.Instance.validateFullQuery(resolvedSQL);
|
|
163
|
+
if (!validation.valid) {
|
|
164
|
+
return { result: null, error: validation.error || 'SQL validation failed' };
|
|
165
|
+
}
|
|
166
|
+
|
|
157
167
|
const request = new sql.Request(readOnlyDataSource);
|
|
158
168
|
const result = await request.query(resolvedSQL);
|
|
159
169
|
return { result: result.recordset, error: null };
|