@memberjunction/server 6.2.0-edge.0 → 6.2.0-edge.1
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/dist/.tsbuildinfo +1 -1
- package/dist/agentSessions/ReturningVisitorRecap.d.ts +2 -0
- package/dist/agentSessions/ReturningVisitorRecap.d.ts.map +1 -1
- package/dist/agentSessions/ReturningVisitorRecap.js +5 -1
- package/dist/agentSessions/ReturningVisitorRecap.js.map +1 -1
- package/dist/agentSessions/SessionManager.js +2 -2
- package/dist/agentSessions/remoteBrowserGoalEngine.d.ts +8 -0
- package/dist/agentSessions/remoteBrowserGoalEngine.d.ts.map +1 -1
- package/dist/agentSessions/remoteBrowserGoalEngine.js +21 -5
- package/dist/agentSessions/remoteBrowserGoalEngine.js.map +1 -1
- package/dist/auth/AuthProviderCatalogRouter.d.ts +2 -0
- package/dist/auth/AuthProviderCatalogRouter.d.ts.map +1 -1
- package/dist/auth/AuthProviderCatalogRouter.js +5 -1
- package/dist/auth/AuthProviderCatalogRouter.js.map +1 -1
- package/dist/auth/index.d.ts +20 -1
- package/dist/auth/index.d.ts.map +1 -1
- package/dist/auth/index.js +20 -10
- package/dist/auth/index.js.map +1 -1
- package/dist/auth/initializeProviders.d.ts +8 -0
- package/dist/auth/initializeProviders.d.ts.map +1 -1
- package/dist/auth/initializeProviders.js +21 -5
- package/dist/auth/initializeProviders.js.map +1 -1
- package/dist/auth/magicLink/MagicLinkRouter.d.ts +9 -0
- package/dist/auth/magicLink/MagicLinkRouter.d.ts.map +1 -1
- package/dist/auth/magicLink/MagicLinkRouter.js +22 -10
- package/dist/auth/magicLink/MagicLinkRouter.js.map +1 -1
- package/dist/auth/magicLink/MagicLinkService.d.ts +17 -15
- package/dist/auth/magicLink/MagicLinkService.d.ts.map +1 -1
- package/dist/auth/magicLink/MagicLinkService.js +65 -51
- package/dist/auth/magicLink/MagicLinkService.js.map +1 -1
- package/dist/auth/magicLink/index.d.ts +2 -2
- package/dist/auth/magicLink/index.d.ts.map +1 -1
- package/dist/auth/magicLink/index.js +2 -2
- package/dist/auth/magicLink/index.js.map +1 -1
- package/dist/auth/magicLink/magicLinkCore.d.ts +54 -33
- package/dist/auth/magicLink/magicLinkCore.d.ts.map +1 -1
- package/dist/auth/magicLink/magicLinkCore.js +61 -61
- package/dist/auth/magicLink/magicLinkCore.js.map +1 -1
- package/dist/auth/magicLink/redeemLanding.d.ts +4 -0
- package/dist/auth/magicLink/redeemLanding.d.ts.map +1 -1
- package/dist/auth/magicLink/redeemLanding.js +12 -4
- package/dist/auth/magicLink/redeemLanding.js.map +1 -1
- package/dist/auth/magicLink/types.d.ts +4 -4
- package/dist/auth/principals.d.ts +2 -0
- package/dist/auth/principals.d.ts.map +1 -1
- package/dist/auth/principals.js +6 -2
- package/dist/auth/principals.js.map +1 -1
- package/dist/cache.d.ts +2 -0
- package/dist/cache.d.ts.map +1 -1
- package/dist/cache.js +3 -1
- package/dist/cache.js.map +1 -1
- package/dist/config.d.ts +346 -2
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +34 -4
- package/dist/config.js.map +1 -1
- package/dist/context.d.ts +20 -0
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +27 -19
- package/dist/context.js.map +1 -1
- package/dist/directives/Public.d.ts +2 -0
- package/dist/directives/Public.d.ts.map +1 -1
- package/dist/directives/Public.js +3 -1
- package/dist/directives/Public.js.map +1 -1
- package/dist/directives/RequireSystemUser.d.ts +2 -0
- package/dist/directives/RequireSystemUser.d.ts.map +1 -1
- package/dist/directives/RequireSystemUser.js +3 -1
- package/dist/directives/RequireSystemUser.js.map +1 -1
- package/dist/generated/graphql-schemas/__mj.d.ts +11 -0
- package/dist/generated/graphql-schemas/__mj.d.ts.map +1 -1
- package/dist/generated/graphql-schemas/__mj.js +48 -0
- package/dist/generated/graphql-schemas/__mj.js.map +1 -1
- package/dist/generic/CacheInvalidationResolver.d.ts +94 -4
- package/dist/generic/CacheInvalidationResolver.d.ts.map +1 -1
- package/dist/generic/CacheInvalidationResolver.js +122 -3
- package/dist/generic/CacheInvalidationResolver.js.map +1 -1
- package/dist/generic/DeleteOptionsInput.d.ts +8 -1
- package/dist/generic/DeleteOptionsInput.d.ts.map +1 -1
- package/dist/generic/DeleteOptionsInput.js +1 -1
- package/dist/generic/DeleteOptionsInput.js.map +1 -1
- package/dist/generic/FireAndForgetHeartbeat.d.ts +3 -1
- package/dist/generic/FireAndForgetHeartbeat.d.ts.map +1 -1
- package/dist/generic/FireAndForgetHeartbeat.js +8 -4
- package/dist/generic/FireAndForgetHeartbeat.js.map +1 -1
- package/dist/generic/PushStatusResolver.d.ts +10 -1
- package/dist/generic/PushStatusResolver.d.ts.map +1 -1
- package/dist/generic/PushStatusResolver.js +11 -3
- package/dist/generic/PushStatusResolver.js.map +1 -1
- package/dist/generic/ResolverBase.d.ts +5 -1
- package/dist/generic/ResolverBase.d.ts.map +1 -1
- package/dist/generic/ResolverBase.js +15 -8
- package/dist/generic/ResolverBase.js.map +1 -1
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +30 -9
- package/dist/index.js.map +1 -1
- package/dist/integration/CustomColumnPromoter.d.ts +2 -0
- package/dist/integration/CustomColumnPromoter.d.ts.map +1 -1
- package/dist/integration/CustomColumnPromoter.js +5 -1
- package/dist/integration/CustomColumnPromoter.js.map +1 -1
- package/dist/integration/EntityMapLifecycle.d.ts +4 -0
- package/dist/integration/EntityMapLifecycle.d.ts.map +1 -1
- package/dist/integration/EntityMapLifecycle.js +10 -2
- package/dist/integration/EntityMapLifecycle.js.map +1 -1
- package/dist/logging/NoLog.d.ts +4 -0
- package/dist/logging/NoLog.d.ts.map +1 -1
- package/dist/logging/NoLog.js +10 -2
- package/dist/logging/NoLog.js.map +1 -1
- package/dist/logging/StartupLogger.d.ts +2 -0
- package/dist/logging/StartupLogger.d.ts.map +1 -1
- package/dist/logging/StartupLogger.js +5 -1
- package/dist/logging/StartupLogger.js.map +1 -1
- package/dist/logging/bootAudit.d.ts +11 -7
- package/dist/logging/bootAudit.d.ts.map +1 -1
- package/dist/logging/bootAudit.js +15 -7
- package/dist/logging/bootAudit.js.map +1 -1
- package/dist/logging/boundaryLogPayload.d.ts +4 -0
- package/dist/logging/boundaryLogPayload.d.ts.map +1 -1
- package/dist/logging/boundaryLogPayload.js +5 -1
- package/dist/logging/boundaryLogPayload.js.map +1 -1
- package/dist/logging/secretRedactor.d.ts +2 -0
- package/dist/logging/secretRedactor.d.ts.map +1 -1
- package/dist/logging/secretRedactor.js +8 -4
- package/dist/logging/secretRedactor.js.map +1 -1
- package/dist/logging/shortenForLog.d.ts +2 -0
- package/dist/logging/shortenForLog.d.ts.map +1 -1
- package/dist/logging/shortenForLog.js +7 -3
- package/dist/logging/shortenForLog.js.map +1 -1
- package/dist/logging/variablesLoggingMiddleware.d.ts +2 -0
- package/dist/logging/variablesLoggingMiddleware.d.ts.map +1 -1
- package/dist/logging/variablesLoggingMiddleware.js +8 -6
- package/dist/logging/variablesLoggingMiddleware.js.map +1 -1
- package/dist/metadataRefreshSignal.d.ts +19 -0
- package/dist/metadataRefreshSignal.d.ts.map +1 -0
- package/dist/metadataRefreshSignal.js +45 -0
- package/dist/metadataRefreshSignal.js.map +1 -0
- package/dist/middleware/MJTenantFilterMiddleware.js +4 -4
- package/dist/multiTenancy/index.d.ts +8 -0
- package/dist/multiTenancy/index.d.ts.map +1 -1
- package/dist/multiTenancy/index.js +21 -5
- package/dist/multiTenancy/index.js.map +1 -1
- package/dist/realtimeWidget/WidgetRouter.d.ts +5 -0
- package/dist/realtimeWidget/WidgetRouter.d.ts.map +1 -1
- package/dist/realtimeWidget/WidgetRouter.js +14 -10
- package/dist/realtimeWidget/WidgetRouter.js.map +1 -1
- package/dist/realtimeWidget/WidgetSessionService.d.ts +6 -6
- package/dist/realtimeWidget/WidgetSessionService.js +27 -27
- package/dist/realtimeWidget/host-identity.d.ts +5 -1
- package/dist/realtimeWidget/host-identity.d.ts.map +1 -1
- package/dist/realtimeWidget/host-identity.js +11 -3
- package/dist/realtimeWidget/host-identity.js.map +1 -1
- package/dist/realtimeWidget/index.d.ts +2 -2
- package/dist/realtimeWidget/index.d.ts.map +1 -1
- package/dist/realtimeWidget/index.js +2 -2
- package/dist/realtimeWidget/index.js.map +1 -1
- package/dist/realtimeWidget/visitorIdentity.d.ts +21 -1
- package/dist/realtimeWidget/visitorIdentity.d.ts.map +1 -1
- package/dist/realtimeWidget/visitorIdentity.js +16 -4
- package/dist/realtimeWidget/visitorIdentity.js.map +1 -1
- package/dist/realtimeWidget/widgetCore.d.ts +48 -0
- package/dist/realtimeWidget/widgetCore.d.ts.map +1 -1
- package/dist/realtimeWidget/widgetCore.js +38 -10
- package/dist/realtimeWidget/widgetCore.js.map +1 -1
- package/dist/realtimeWidget/widgetGuestElevation.d.ts +10 -6
- package/dist/realtimeWidget/widgetGuestElevation.d.ts.map +1 -1
- package/dist/realtimeWidget/widgetGuestElevation.js +14 -6
- package/dist/realtimeWidget/widgetGuestElevation.js.map +1 -1
- package/dist/resolvers/AdhocQueryResolver.js +3 -3
- package/dist/resolvers/FileResolver.js +3 -3
- package/dist/resolvers/GeoResolver.d.ts +2 -2
- package/dist/resolvers/GeoResolver.js +4 -4
- package/dist/resolvers/GetDataResolver.d.ts +14 -0
- package/dist/resolvers/GetDataResolver.d.ts.map +1 -1
- package/dist/resolvers/GetDataResolver.js +43 -15
- package/dist/resolvers/GetDataResolver.js.map +1 -1
- package/dist/resolvers/IntegrationDiscoveryResolver.js +2 -2
- package/dist/resolvers/ListOperationsResolver.d.ts +20 -0
- package/dist/resolvers/ListOperationsResolver.d.ts.map +1 -1
- package/dist/resolvers/ListOperationsResolver.js +68 -28
- package/dist/resolvers/ListOperationsResolver.js.map +1 -1
- package/dist/resolvers/MCPResolver.d.ts +11 -1
- package/dist/resolvers/MCPResolver.d.ts.map +1 -1
- package/dist/resolvers/MCPResolver.js +7 -3
- package/dist/resolvers/MCPResolver.js.map +1 -1
- package/dist/resolvers/RealtimeBridgeResolver.js +3 -3
- package/dist/resolvers/RealtimeClientSessionResolver.js +3 -3
- package/dist/resolvers/RemoteBrowserActionResolver.js +5 -5
- package/dist/resolvers/RunAIAgentResolver.d.ts +10 -4
- package/dist/resolvers/RunAIAgentResolver.d.ts.map +1 -1
- package/dist/resolvers/RunAIAgentResolver.js +69 -38
- package/dist/resolvers/RunAIAgentResolver.js.map +1 -1
- package/dist/resolvers/RunAIPromptResolver.d.ts +1 -1
- package/dist/resolvers/RunAIPromptResolver.js +2 -2
- package/dist/resolvers/RunTestResolver.js +5 -5
- package/dist/resolvers/SqlLoggingConfigResolver.d.ts +8 -4
- package/dist/resolvers/SqlLoggingConfigResolver.d.ts.map +1 -1
- package/dist/resolvers/SqlLoggingConfigResolver.js +5 -5
- package/dist/resolvers/TaskGraphFrameResolver.d.ts +8 -1
- package/dist/resolvers/TaskGraphFrameResolver.d.ts.map +1 -1
- package/dist/resolvers/TaskGraphFrameResolver.js +6 -2
- package/dist/resolvers/TaskGraphFrameResolver.js.map +1 -1
- package/dist/resolvers/adhoc-query-helpers.d.ts +6 -0
- package/dist/resolvers/adhoc-query-helpers.d.ts.map +1 -1
- package/dist/resolvers/adhoc-query-helpers.js +10 -2
- package/dist/resolvers/adhoc-query-helpers.js.map +1 -1
- package/dist/resolvers/artifact-routing.d.ts +8 -8
- package/dist/resolvers/artifact-routing.js +2 -2
- package/dist/resolvers/artifact-routing.js.map +1 -1
- package/dist/resolvers/meetingRecordingRegistration.d.ts +10 -2
- package/dist/resolvers/meetingRecordingRegistration.d.ts.map +1 -1
- package/dist/resolvers/meetingRecordingRegistration.js +24 -8
- package/dist/resolvers/meetingRecordingRegistration.js.map +1 -1
- package/dist/resolvers/peaksSidecar.d.ts +4 -0
- package/dist/resolvers/peaksSidecar.d.ts.map +1 -1
- package/dist/resolvers/peaksSidecar.js +10 -2
- package/dist/resolvers/peaksSidecar.js.map +1 -1
- package/dist/rest/EntityCRUDHandler.d.ts +28 -0
- package/dist/rest/EntityCRUDHandler.d.ts.map +1 -1
- package/dist/rest/EntityCRUDHandler.js +20 -4
- package/dist/rest/EntityCRUDHandler.js.map +1 -1
- package/dist/rest/MediaStreamHandler.d.ts +2 -0
- package/dist/rest/MediaStreamHandler.d.ts.map +1 -1
- package/dist/rest/MediaStreamHandler.js +10 -6
- package/dist/rest/MediaStreamHandler.js.map +1 -1
- package/dist/rest/OAuthCallbackHandler.d.ts +9 -0
- package/dist/rest/OAuthCallbackHandler.d.ts.map +1 -1
- package/dist/rest/OAuthCallbackHandler.js +15 -3
- package/dist/rest/OAuthCallbackHandler.js.map +1 -1
- package/dist/rest/RESTEndpointHandler.d.ts +6 -4
- package/dist/rest/RESTEndpointHandler.d.ts.map +1 -1
- package/dist/rest/RESTEndpointHandler.js +15 -11
- package/dist/rest/RESTEndpointHandler.js.map +1 -1
- package/dist/rest/RealtimeSdpBrokerHandler.d.ts +5 -1
- package/dist/rest/RealtimeSdpBrokerHandler.d.ts.map +1 -1
- package/dist/rest/RealtimeSdpBrokerHandler.js +12 -4
- package/dist/rest/RealtimeSdpBrokerHandler.js.map +1 -1
- package/dist/rest/SignatureWebhookHandler.d.ts +2 -0
- package/dist/rest/SignatureWebhookHandler.d.ts.map +1 -1
- package/dist/rest/SignatureWebhookHandler.js +5 -1
- package/dist/rest/SignatureWebhookHandler.js.map +1 -1
- package/dist/rest/UploadTokenManager.d.ts +24 -8
- package/dist/rest/UploadTokenManager.d.ts.map +1 -1
- package/dist/rest/UploadTokenManager.js +53 -21
- package/dist/rest/UploadTokenManager.js.map +1 -1
- package/dist/rest/ViewOperationsHandler.d.ts +20 -0
- package/dist/rest/ViewOperationsHandler.d.ts.map +1 -1
- package/dist/rest/ViewOperationsHandler.js +20 -4
- package/dist/rest/ViewOperationsHandler.js.map +1 -1
- package/dist/rest/mediaRange.d.ts +4 -0
- package/dist/rest/mediaRange.d.ts.map +1 -1
- package/dist/rest/mediaRange.js +10 -2
- package/dist/rest/mediaRange.js.map +1 -1
- package/dist/rest/setupRESTEndpoints.d.ts +4 -0
- package/dist/rest/setupRESTEndpoints.d.ts.map +1 -1
- package/dist/rest/setupRESTEndpoints.js +13 -7
- package/dist/rest/setupRESTEndpoints.js.map +1 -1
- package/dist/serverExtensionReservedRoots.d.ts +2 -0
- package/dist/serverExtensionReservedRoots.d.ts.map +1 -1
- package/dist/serverExtensionReservedRoots.js +5 -1
- package/dist/serverExtensionReservedRoots.js.map +1 -1
- package/dist/services/TaskGraphActionRunner.d.ts +13 -8
- package/dist/services/TaskGraphActionRunner.d.ts.map +1 -1
- package/dist/services/TaskGraphActionRunner.js +16 -15
- package/dist/services/TaskGraphActionRunner.js.map +1 -1
- package/dist/types.d.ts +2 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +7 -3
- package/dist/types.js.map +1 -1
- package/dist/util.d.ts +6 -0
- package/dist/util.d.ts.map +1 -1
- package/dist/util.js +13 -5
- package/dist/util.js.map +1 -1
- package/package.json +92 -92
- package/src/__tests__/DeleteOptionsInput.wireShape.test.ts +62 -0
- package/src/__tests__/FileResolverPeaks.test.ts +13 -13
- package/src/__tests__/ListOperationsResolver.test.ts +17 -17
- package/src/__tests__/MediaStreamHandler.test.ts +28 -28
- package/src/__tests__/NoLog.test.ts +11 -11
- package/src/__tests__/PrimaryKeyAlwaysMapped.test.ts +10 -10
- package/src/__tests__/RESTEndpointHandler.test.ts +14 -14
- package/src/__tests__/RealtimeBridgeResolver.test.ts +4 -2
- package/src/__tests__/RealtimeSdpBrokerHandler.test.ts +6 -6
- package/src/__tests__/RefreshAdoptsNewColumns.test.ts +8 -8
- package/src/__tests__/RemoteBrowserGoalEngine.test.ts +18 -18
- package/src/__tests__/RunAIAgentResolver.historyFrom.test.ts +228 -0
- package/src/__tests__/TaskGraphActionRunner.durablePayload.test.ts +129 -0
- package/src/__tests__/TaskGraphFrameResolver.test.ts +2 -2
- package/src/__tests__/WidgetSessionService.test.ts +8 -4
- package/src/__tests__/adhoc-query-helpers.test.ts +21 -21
- package/src/__tests__/bootAudit.test.ts +11 -11
- package/src/__tests__/boundaryLogPayload.test.ts +6 -6
- package/src/__tests__/cacheInvalidationRecordData.test.ts +177 -0
- package/src/__tests__/databaseAbstraction.test.ts +12 -6
- package/src/__tests__/getDataTokenRedaction.test.ts +7 -7
- package/src/__tests__/initializeProviders.refresh.test.ts +4 -4
- package/src/__tests__/magicLink.test.ts +73 -134
- package/src/__tests__/magicLinkService.consume.test.ts +224 -0
- package/src/__tests__/meetingRecordingRegistration.test.ts +12 -12
- package/src/__tests__/metadataRefreshSignal.test.ts +78 -0
- package/src/__tests__/multiTenancy.security.test.ts +40 -40
- package/src/__tests__/multiTenancy.test.ts +18 -18
- package/src/__tests__/newUsers.test.ts +24 -23
- package/src/__tests__/principals.test.ts +22 -22
- package/src/__tests__/pushStatusResolver.filter.test.ts +8 -8
- package/src/__tests__/secretRedactor.failOpen.test.ts +12 -12
- package/src/__tests__/secretRedactor.test.ts +12 -12
- package/src/__tests__/serverExtensionReservedRoots.test.ts +7 -7
- package/src/__tests__/subscriptionRedaction.test.ts +5 -5
- package/src/__tests__/unifiedAuth.test.ts +15 -9
- package/src/__tests__/visitorIdentity.resolve.test.ts +6 -6
- package/src/__tests__/widget.test.ts +45 -45
- package/src/__tests__/widgetGuestElevation.test.ts +7 -7
- package/src/__tests__/widgetHostIdentity.test.ts +14 -14
- package/src/agentSessions/ReturningVisitorRecap.ts +12 -1
- package/src/agentSessions/SessionManager.ts +2 -2
- package/src/agentSessions/remoteBrowserGoalEngine.ts +30 -5
- package/src/auth/AuthProviderCatalogRouter.ts +6 -1
- package/src/auth/__tests__/backward-compatibility.test.ts +3 -3
- package/src/auth/index.ts +43 -28
- package/src/auth/initializeProviders.ts +25 -5
- package/src/auth/magicLink/MagicLinkRouter.ts +28 -10
- package/src/auth/magicLink/MagicLinkService.ts +71 -52
- package/src/auth/magicLink/index.ts +7 -7
- package/src/auth/magicLink/magicLinkCore.ts +96 -64
- package/src/auth/magicLink/redeemLanding.ts +14 -4
- package/src/auth/magicLink/types.ts +54 -54
- package/src/auth/newUsers.ts +1 -1
- package/src/auth/principals.ts +11 -2
- package/src/cache.ts +4 -1
- package/src/config.ts +37 -4
- package/src/context.ts +37 -24
- package/src/directives/Public.ts +4 -1
- package/src/directives/RequireSystemUser.ts +4 -1
- package/src/generated/graphql-schemas/__mj.ts +37 -0
- package/src/generic/CacheInvalidationResolver.ts +148 -4
- package/src/generic/DeleteOptionsInput.ts +9 -2
- package/src/generic/FireAndForgetHeartbeat.ts +19 -14
- package/src/generic/PushStatusResolver.ts +21 -7
- package/src/generic/ResolverBase.ts +16 -8
- package/src/generic/RunViewResolver.ts +22 -22
- package/src/generic/__tests__/FireAndForgetHeartbeat.test.ts +7 -7
- package/src/index.ts +35 -9
- package/src/integration/CustomColumnPromoter.ts +6 -1
- package/src/integration/EntityMapLifecycle.ts +20 -2
- package/src/logging/NoLog.ts +16 -2
- package/src/logging/StartupLogger.ts +6 -1
- package/src/logging/bootAudit.ts +26 -16
- package/src/logging/boundaryLogPayload.ts +8 -1
- package/src/logging/secretRedactor.ts +14 -9
- package/src/logging/shortenForLog.ts +8 -3
- package/src/logging/variablesLoggingMiddleware.ts +9 -6
- package/src/metadataRefreshSignal.ts +45 -0
- package/src/middleware/MJTenantFilterMiddleware.ts +4 -4
- package/src/multiTenancy/index.ts +29 -5
- package/src/realtimeWidget/WidgetRouter.ts +15 -10
- package/src/realtimeWidget/WidgetSessionService.ts +76 -76
- package/src/realtimeWidget/host-identity.ts +24 -10
- package/src/realtimeWidget/index.ts +3 -3
- package/src/realtimeWidget/visitorIdentity.ts +39 -8
- package/src/realtimeWidget/widgetCore.ts +75 -10
- package/src/realtimeWidget/widgetGuestElevation.ts +25 -12
- package/src/resolvers/AdhocQueryResolver.ts +3 -3
- package/src/resolvers/AgentSessionResolver.ts +3 -3
- package/src/resolvers/ColorResolver.ts +6 -6
- package/src/resolvers/ComponentRegistryResolver.ts +36 -36
- package/src/resolvers/EntityCommunicationsResolver.ts +4 -4
- package/src/resolvers/ExecuteRemoteOperationResolver.ts +9 -9
- package/src/resolvers/FileResolver.ts +42 -42
- package/src/resolvers/GeoResolver.ts +4 -4
- package/src/resolvers/GetDataResolver.ts +50 -15
- package/src/resolvers/IntegrationDiscoveryResolver.ts +2 -2
- package/src/resolvers/ListOperationsResolver.ts +78 -28
- package/src/resolvers/MCPResolver.ts +30 -15
- package/src/resolvers/QueryResolver.ts +13 -13
- package/src/resolvers/RealtimeBridgeResolver.ts +3 -3
- package/src/resolvers/RealtimeClientSessionResolver.ts +3 -3
- package/src/resolvers/RemoteBrowserActionResolver.ts +5 -5
- package/src/resolvers/RunAIAgentResolver.ts +113 -72
- package/src/resolvers/RunAIPromptResolver.ts +22 -22
- package/src/resolvers/RunTemplateResolver.ts +4 -4
- package/src/resolvers/RunTestResolver.ts +25 -25
- package/src/resolvers/SqlLoggingConfigResolver.ts +56 -56
- package/src/resolvers/TaskGraphFrameResolver.ts +37 -28
- package/src/resolvers/TelemetryResolver.ts +79 -79
- package/src/resolvers/__tests__/GetDataResolver.tokens.test.ts +40 -38
- package/src/resolvers/__tests__/artifact-routing.test.ts +23 -23
- package/src/resolvers/adhoc-query-helpers.ts +19 -2
- package/src/resolvers/artifact-routing.ts +19 -19
- package/src/resolvers/meetingRecordingRegistration.ts +44 -10
- package/src/resolvers/peaksSidecar.ts +12 -2
- package/src/rest/EntityCRUDHandler.ts +24 -4
- package/src/rest/MediaStreamHandler.ts +11 -6
- package/src/rest/OAuthCallbackHandler.ts +25 -7
- package/src/rest/RESTEndpointHandler.ts +20 -15
- package/src/rest/RealtimeSdpBrokerHandler.ts +14 -4
- package/src/rest/SignatureWebhookHandler.ts +6 -1
- package/src/rest/UploadTokenManager.ts +66 -30
- package/src/rest/ViewOperationsHandler.ts +24 -4
- package/src/rest/mediaRange.ts +16 -6
- package/src/rest/setupRESTEndpoints.ts +24 -12
- package/src/serverExtensionReservedRoots.ts +6 -1
- package/src/services/TaskGraphActionRunner.ts +16 -15
- package/src/types.ts +21 -16
- package/src/util.ts +16 -6
|
@@ -22,24 +22,24 @@ import type { ApplyResult, ListDelta } from '@memberjunction/lists-base';
|
|
|
22
22
|
import {
|
|
23
23
|
ApplyDeltaInput,
|
|
24
24
|
ListSourceInput,
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
25
|
+
FromCoreApplyResult,
|
|
26
|
+
FromCoreDelta,
|
|
27
|
+
FromCoreWarning,
|
|
28
|
+
RebuildDeltaFromInput,
|
|
29
|
+
ToCoreSource,
|
|
30
30
|
} from '../resolvers/ListOperationsResolver.js';
|
|
31
31
|
|
|
32
32
|
describe('ListOperationsResolver — boundary converters', () => {
|
|
33
33
|
describe('toCoreSource', () => {
|
|
34
34
|
it('maps a list-kind input to a core ListSource', () => {
|
|
35
35
|
const input = Object.assign(new ListSourceInput(), { Kind: 'list', ListID: 'list-1' });
|
|
36
|
-
const result =
|
|
36
|
+
const result = ToCoreSource(input);
|
|
37
37
|
expect(result).toEqual({ kind: 'list', listId: 'list-1' });
|
|
38
38
|
});
|
|
39
39
|
|
|
40
40
|
it('maps a view-kind input to a core ListSource', () => {
|
|
41
41
|
const input = Object.assign(new ListSourceInput(), { Kind: 'view', ViewID: 'view-1' });
|
|
42
|
-
expect(
|
|
42
|
+
expect(ToCoreSource(input)).toEqual({ kind: 'view', viewId: 'view-1' });
|
|
43
43
|
});
|
|
44
44
|
|
|
45
45
|
it('maps an adhoc-kind input to a core ListSource', () => {
|
|
@@ -48,7 +48,7 @@ describe('ListOperationsResolver — boundary converters', () => {
|
|
|
48
48
|
EntityName: 'Contacts',
|
|
49
49
|
ExtraFilter: "Status='Active'",
|
|
50
50
|
});
|
|
51
|
-
expect(
|
|
51
|
+
expect(ToCoreSource(input)).toEqual({
|
|
52
52
|
kind: 'adhoc',
|
|
53
53
|
entityName: 'Contacts',
|
|
54
54
|
extraFilter: "Status='Active'",
|
|
@@ -57,22 +57,22 @@ describe('ListOperationsResolver — boundary converters', () => {
|
|
|
57
57
|
|
|
58
58
|
it('throws when list-kind input has no ListID', () => {
|
|
59
59
|
const input = Object.assign(new ListSourceInput(), { Kind: 'list' });
|
|
60
|
-
expect(() =>
|
|
60
|
+
expect(() => ToCoreSource(input)).toThrow(/ListID is required/);
|
|
61
61
|
});
|
|
62
62
|
|
|
63
63
|
it('throws when view-kind input has no ViewID', () => {
|
|
64
64
|
const input = Object.assign(new ListSourceInput(), { Kind: 'view' });
|
|
65
|
-
expect(() =>
|
|
65
|
+
expect(() => ToCoreSource(input)).toThrow(/ViewID is required/);
|
|
66
66
|
});
|
|
67
67
|
|
|
68
68
|
it('throws when adhoc-kind input lacks EntityName or ExtraFilter', () => {
|
|
69
69
|
const input = Object.assign(new ListSourceInput(), { Kind: 'adhoc', EntityName: 'X' });
|
|
70
|
-
expect(() =>
|
|
70
|
+
expect(() => ToCoreSource(input)).toThrow(/EntityName and ExtraFilter/);
|
|
71
71
|
});
|
|
72
72
|
|
|
73
73
|
it('throws on an unknown discriminator', () => {
|
|
74
74
|
const input = Object.assign(new ListSourceInput(), { Kind: 'mystery' as never });
|
|
75
|
-
expect(() =>
|
|
75
|
+
expect(() => ToCoreSource(input)).toThrow(/Unknown ListSourceInput\.Kind/);
|
|
76
76
|
});
|
|
77
77
|
});
|
|
78
78
|
|
|
@@ -90,7 +90,7 @@ describe('ListOperationsResolver — boundary converters', () => {
|
|
|
90
90
|
],
|
|
91
91
|
DeltaToken: 'abc.def',
|
|
92
92
|
};
|
|
93
|
-
const output =
|
|
93
|
+
const output = FromCoreDelta(delta);
|
|
94
94
|
expect(output).toMatchObject({
|
|
95
95
|
TargetListId: 'list-1',
|
|
96
96
|
EntityName: 'Contacts',
|
|
@@ -111,7 +111,7 @@ describe('ListOperationsResolver — boundary converters', () => {
|
|
|
111
111
|
|
|
112
112
|
describe('fromCoreWarning', () => {
|
|
113
113
|
it('leaves DetailsJSON undefined when no details supplied', () => {
|
|
114
|
-
const output =
|
|
114
|
+
const output = FromCoreWarning({ Code: 'EMPTY_SOURCE', Message: 'No records' });
|
|
115
115
|
expect(output.DetailsJSON).toBeUndefined();
|
|
116
116
|
});
|
|
117
117
|
});
|
|
@@ -126,7 +126,7 @@ describe('ListOperationsResolver — boundary converters', () => {
|
|
|
126
126
|
CreatedListId: 'list-1',
|
|
127
127
|
Counts: { Added: 5, Removed: 2, Failed: 0 },
|
|
128
128
|
};
|
|
129
|
-
const output =
|
|
129
|
+
const output = FromCoreApplyResult(result);
|
|
130
130
|
expect(output).toMatchObject({
|
|
131
131
|
Success: true,
|
|
132
132
|
ResultCode: 'SUCCESS',
|
|
@@ -145,7 +145,7 @@ describe('ListOperationsResolver — boundary converters', () => {
|
|
|
145
145
|
Message: 'partial',
|
|
146
146
|
Errors: ['failed record a'],
|
|
147
147
|
};
|
|
148
|
-
expect(
|
|
148
|
+
expect(FromCoreApplyResult(result).Errors).toEqual(['failed record a']);
|
|
149
149
|
});
|
|
150
150
|
});
|
|
151
151
|
|
|
@@ -165,7 +165,7 @@ describe('ListOperationsResolver — boundary converters', () => {
|
|
|
165
165
|
DeltaToken: 'tok',
|
|
166
166
|
ConfirmDrops: true,
|
|
167
167
|
});
|
|
168
|
-
const out =
|
|
168
|
+
const out = RebuildDeltaFromInput(input);
|
|
169
169
|
expect(out).toMatchObject({
|
|
170
170
|
TargetListId: 'list-1',
|
|
171
171
|
EntityName: 'Contacts',
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { describe, it, expect } from 'vitest';
|
|
2
|
-
import {
|
|
2
|
+
import { ParseRangeHeaderLoose, ParseRange } from '../rest/mediaRange.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Tests for the pure HTTP-Range parsing helpers behind the authenticated `/media/:fileId`
|
|
@@ -16,34 +16,34 @@ import { parseRangeHeaderLoose, parseRange } from '../rest/mediaRange.js';
|
|
|
16
16
|
|
|
17
17
|
describe('parseRangeHeaderLoose (streaming path — no known total)', () => {
|
|
18
18
|
it('parses a closed range bytes=start-end into inclusive offsets', () => {
|
|
19
|
-
expect(
|
|
20
|
-
expect(
|
|
19
|
+
expect(ParseRangeHeaderLoose('bytes=0-499')).toEqual({ start: 0, end: 499 });
|
|
20
|
+
expect(ParseRangeHeaderLoose('bytes=200-1023')).toEqual({ start: 200, end: 1023 });
|
|
21
21
|
});
|
|
22
22
|
|
|
23
23
|
it('leaves end undefined for an open-ended range bytes=start- (stream to EOF)', () => {
|
|
24
|
-
expect(
|
|
25
|
-
expect(
|
|
24
|
+
expect(ParseRangeHeaderLoose('bytes=500-')).toEqual({ start: 500 });
|
|
25
|
+
expect(ParseRangeHeaderLoose('bytes=0-')).toEqual({ start: 0 });
|
|
26
26
|
});
|
|
27
27
|
|
|
28
28
|
it('tolerates surrounding whitespace', () => {
|
|
29
|
-
expect(
|
|
29
|
+
expect(ParseRangeHeaderLoose(' bytes=10-20 ')).toEqual({ start: 10, end: 20 });
|
|
30
30
|
});
|
|
31
31
|
|
|
32
32
|
it('returns undefined when end < start (nonsensical range)', () => {
|
|
33
|
-
expect(
|
|
33
|
+
expect(ParseRangeHeaderLoose('bytes=500-100')).toBeUndefined();
|
|
34
34
|
});
|
|
35
35
|
|
|
36
36
|
it('returns undefined for malformed / multi-range / suffix-only headers', () => {
|
|
37
|
-
expect(
|
|
38
|
-
expect(
|
|
39
|
-
expect(
|
|
40
|
-
expect(
|
|
41
|
-
expect(
|
|
42
|
-
expect(
|
|
37
|
+
expect(ParseRangeHeaderLoose('bytes=abc-def')).toBeUndefined();
|
|
38
|
+
expect(ParseRangeHeaderLoose('bytes=-500')).toBeUndefined(); // suffix range — left to a full read
|
|
39
|
+
expect(ParseRangeHeaderLoose('bytes=0-100,200-300')).toBeUndefined(); // multi-range
|
|
40
|
+
expect(ParseRangeHeaderLoose('items=0-100')).toBeUndefined(); // wrong unit
|
|
41
|
+
expect(ParseRangeHeaderLoose('bytes=')).toBeUndefined();
|
|
42
|
+
expect(ParseRangeHeaderLoose('')).toBeUndefined();
|
|
43
43
|
});
|
|
44
44
|
|
|
45
45
|
it('accepts a zero-length point range bytes=N-N', () => {
|
|
46
|
-
expect(
|
|
46
|
+
expect(ParseRangeHeaderLoose('bytes=42-42')).toEqual({ start: 42, end: 42 });
|
|
47
47
|
});
|
|
48
48
|
});
|
|
49
49
|
|
|
@@ -51,41 +51,41 @@ describe('parseRange (buffer path — known total)', () => {
|
|
|
51
51
|
const TOTAL = 1000;
|
|
52
52
|
|
|
53
53
|
it('parses a closed range within bounds', () => {
|
|
54
|
-
expect(
|
|
54
|
+
expect(ParseRange('bytes=0-499', TOTAL)).toEqual({ start: 0, end: 499 });
|
|
55
55
|
});
|
|
56
56
|
|
|
57
57
|
it('clamps end to the last byte when the requested end exceeds total', () => {
|
|
58
58
|
// bytes=500-99999 against a 1000-byte file → end clamps to 999.
|
|
59
|
-
expect(
|
|
59
|
+
expect(ParseRange('bytes=500-99999', TOTAL)).toEqual({ start: 500, end: 999 });
|
|
60
60
|
});
|
|
61
61
|
|
|
62
62
|
it('resolves an open-ended range to the last byte', () => {
|
|
63
|
-
expect(
|
|
63
|
+
expect(ParseRange('bytes=200-', TOTAL)).toEqual({ start: 200, end: 999 });
|
|
64
64
|
});
|
|
65
65
|
|
|
66
66
|
it('returns undefined when start is at or past EOF (unsatisfiable → 416)', () => {
|
|
67
|
-
expect(
|
|
68
|
-
expect(
|
|
67
|
+
expect(ParseRange('bytes=1000-1100', TOTAL)).toBeUndefined(); // start === total
|
|
68
|
+
expect(ParseRange('bytes=2000-', TOTAL)).toBeUndefined(); // start > total
|
|
69
69
|
});
|
|
70
70
|
|
|
71
71
|
it('returns undefined when end < start after parsing', () => {
|
|
72
|
-
expect(
|
|
72
|
+
expect(ParseRange('bytes=600-100', TOTAL)).toBeUndefined();
|
|
73
73
|
});
|
|
74
74
|
|
|
75
75
|
it('returns undefined for malformed / multi-range / suffix-only headers', () => {
|
|
76
|
-
expect(
|
|
77
|
-
expect(
|
|
78
|
-
expect(
|
|
79
|
-
expect(
|
|
80
|
-
expect(
|
|
76
|
+
expect(ParseRange('bytes=abc-', TOTAL)).toBeUndefined();
|
|
77
|
+
expect(ParseRange('bytes=-200', TOTAL)).toBeUndefined();
|
|
78
|
+
expect(ParseRange('bytes=0-100,200-300', TOTAL)).toBeUndefined();
|
|
79
|
+
expect(ParseRange('items=0-100', TOTAL)).toBeUndefined();
|
|
80
|
+
expect(ParseRange('', TOTAL)).toBeUndefined();
|
|
81
81
|
});
|
|
82
82
|
|
|
83
83
|
it('handles the very first byte and the very last byte exactly', () => {
|
|
84
|
-
expect(
|
|
85
|
-
expect(
|
|
84
|
+
expect(ParseRange('bytes=0-0', TOTAL)).toEqual({ start: 0, end: 0 });
|
|
85
|
+
expect(ParseRange('bytes=999-999', TOTAL)).toEqual({ start: 999, end: 999 });
|
|
86
86
|
});
|
|
87
87
|
|
|
88
88
|
it('tolerates surrounding whitespace', () => {
|
|
89
|
-
expect(
|
|
89
|
+
expect(ParseRange(' bytes=10-20 ', TOTAL)).toEqual({ start: 10, end: 20 });
|
|
90
90
|
});
|
|
91
91
|
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import 'reflect-metadata';
|
|
2
2
|
import { describe, it, expect } from 'vitest';
|
|
3
|
-
import { NoLog,
|
|
3
|
+
import { NoLog, HasNoLogParameter, GetNoLogFields } from '../logging/NoLog.js';
|
|
4
4
|
|
|
5
5
|
describe('NoLog decorator', () => {
|
|
6
6
|
it('marks a resolver method parameter (3-arg call) and is readable via hasNoLogParameter', () => {
|
|
@@ -11,9 +11,9 @@ describe('NoLog decorator', () => {
|
|
|
11
11
|
}
|
|
12
12
|
NoLog(MyResolver.prototype, 'doThing', 1);
|
|
13
13
|
|
|
14
|
-
expect(
|
|
15
|
-
expect(
|
|
16
|
-
expect(
|
|
14
|
+
expect(HasNoLogParameter(MyResolver, 'doThing', 1)).toBe(true);
|
|
15
|
+
expect(HasNoLogParameter(MyResolver, 'doThing', 0)).toBe(false);
|
|
16
|
+
expect(HasNoLogParameter(MyResolver, 'unknownMethod', 0)).toBe(false);
|
|
17
17
|
});
|
|
18
18
|
|
|
19
19
|
it('marks a field on an input class (2-arg call) and is readable via getNoLogFields', () => {
|
|
@@ -24,7 +24,7 @@ describe('NoLog decorator', () => {
|
|
|
24
24
|
}
|
|
25
25
|
NoLog(MyInput.prototype, 'Token');
|
|
26
26
|
|
|
27
|
-
const fields =
|
|
27
|
+
const fields = GetNoLogFields(MyInput);
|
|
28
28
|
expect(fields.has('Token')).toBe(true);
|
|
29
29
|
expect(fields.has('Queries')).toBe(false);
|
|
30
30
|
expect(fields.size).toBe(1);
|
|
@@ -41,8 +41,8 @@ describe('NoLog decorator', () => {
|
|
|
41
41
|
B: string = '';
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
expect(
|
|
45
|
-
expect(
|
|
44
|
+
expect(HasNoLogParameter(UndecoratedResolver, 'doNothing', 0)).toBe(false);
|
|
45
|
+
expect(GetNoLogFields(UndecoratedInput).size).toBe(0);
|
|
46
46
|
});
|
|
47
47
|
|
|
48
48
|
it('supports multiple parameter marks on the same method', () => {
|
|
@@ -54,9 +54,9 @@ describe('NoLog decorator', () => {
|
|
|
54
54
|
NoLog(TwoSecrets.prototype, 'handle', 0);
|
|
55
55
|
NoLog(TwoSecrets.prototype, 'handle', 2);
|
|
56
56
|
|
|
57
|
-
expect(
|
|
58
|
-
expect(
|
|
59
|
-
expect(
|
|
57
|
+
expect(HasNoLogParameter(TwoSecrets, 'handle', 0)).toBe(true);
|
|
58
|
+
expect(HasNoLogParameter(TwoSecrets, 'handle', 1)).toBe(false);
|
|
59
|
+
expect(HasNoLogParameter(TwoSecrets, 'handle', 2)).toBe(true);
|
|
60
60
|
});
|
|
61
61
|
|
|
62
62
|
it('supports multiple field marks on the same input class', () => {
|
|
@@ -68,7 +68,7 @@ describe('NoLog decorator', () => {
|
|
|
68
68
|
NoLog(TwoFieldSecrets.prototype, 'A');
|
|
69
69
|
NoLog(TwoFieldSecrets.prototype, 'C');
|
|
70
70
|
|
|
71
|
-
const fields =
|
|
71
|
+
const fields = GetNoLogFields(TwoFieldSecrets);
|
|
72
72
|
expect(fields.has('A')).toBe(true);
|
|
73
73
|
expect(fields.has('B')).toBe(false);
|
|
74
74
|
expect(fields.has('C')).toBe(true);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { describe, it, expect } from 'vitest';
|
|
2
|
-
import {
|
|
2
|
+
import { SelectFieldsToMap } from '../integration/EntityMapLifecycle.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Deselecting the primary key must not cost the object its identity.
|
|
@@ -18,41 +18,41 @@ const names = (out: Array<{ Name: string }>) => out.map(x => x.Name);
|
|
|
18
18
|
|
|
19
19
|
describe('selectFieldsToMap — the primary key is never optional', () => {
|
|
20
20
|
it('includes the key even when the user did not select it', () => {
|
|
21
|
-
expect(names(
|
|
21
|
+
expect(names(SelectFieldsToMap(ALL, ['name', 'email']))).toEqual(['id', 'name', 'email']);
|
|
22
22
|
});
|
|
23
23
|
|
|
24
24
|
it('includes the key when the selection is EMPTY — an empty choice is still a choice', () => {
|
|
25
25
|
// Distinct from "no selection". An empty array is unusual but real, and it still cannot
|
|
26
26
|
// produce a keyless map.
|
|
27
|
-
expect(names(
|
|
27
|
+
expect(names(SelectFieldsToMap(ALL, []))).toEqual(['id']);
|
|
28
28
|
});
|
|
29
29
|
|
|
30
30
|
it('does not duplicate the key when it IS selected', () => {
|
|
31
|
-
expect(names(
|
|
31
|
+
expect(names(SelectFieldsToMap(ALL, ['id', 'name']))).toEqual(['id', 'name']);
|
|
32
32
|
});
|
|
33
33
|
|
|
34
34
|
it('null or undefined selection means every field', () => {
|
|
35
|
-
expect(names(
|
|
36
|
-
expect(names(
|
|
35
|
+
expect(names(SelectFieldsToMap(ALL, null))).toEqual(['id', 'name', 'email', 'notes']);
|
|
36
|
+
expect(names(SelectFieldsToMap(ALL, undefined))).toEqual(['id', 'name', 'email', 'notes']);
|
|
37
37
|
});
|
|
38
38
|
|
|
39
39
|
it('keeps every part of a COMPOSITE key, selected or not', () => {
|
|
40
40
|
const composite = [f('tenant_id', true), f('row_id', true), f('label')];
|
|
41
|
-
expect(names(
|
|
41
|
+
expect(names(SelectFieldsToMap(composite, ['label']))).toEqual(['tenant_id', 'row_id', 'label']);
|
|
42
42
|
});
|
|
43
43
|
|
|
44
44
|
it('matches selection names case-insensitively', () => {
|
|
45
|
-
expect(names(
|
|
45
|
+
expect(names(SelectFieldsToMap(ALL, ['NAME', 'Email']))).toEqual(['id', 'name', 'email']);
|
|
46
46
|
});
|
|
47
47
|
|
|
48
48
|
it('preserves the discovered field order', () => {
|
|
49
49
|
// Field-map creation walks this list; reordering would reshuffle Priority-adjacent behaviour
|
|
50
50
|
// for no reason.
|
|
51
|
-
expect(names(
|
|
51
|
+
expect(names(SelectFieldsToMap(ALL, ['notes', 'name']))).toEqual(['id', 'name', 'notes']);
|
|
52
52
|
});
|
|
53
53
|
|
|
54
54
|
it('an object with no key at all is unaffected', () => {
|
|
55
55
|
const keyless = [f('a'), f('b')];
|
|
56
|
-
expect(names(
|
|
56
|
+
expect(names(SelectFieldsToMap(keyless, ['a']))).toEqual(['a']);
|
|
57
57
|
});
|
|
58
58
|
});
|
|
@@ -188,26 +188,26 @@ describe('RESTEndpointHandler.isEntityAllowed', () => {
|
|
|
188
188
|
});
|
|
189
189
|
|
|
190
190
|
it('blocks entities in excluded schemas (case-insensitive), with schema exclusion taking top precedence', () => {
|
|
191
|
-
const schemaOnly = makeHandler({
|
|
191
|
+
const schemaOnly = makeHandler({ ExcludeSchemas: ['VAULT'] });
|
|
192
192
|
expect(schemaOnly.isEntityAllowed('Secrets')).toBe(false);
|
|
193
193
|
expect(schemaOnly.isEntityAllowed('Users')).toBe(true); // other schemas unaffected
|
|
194
194
|
|
|
195
195
|
// Even an explicit entity include cannot override a schema exclusion
|
|
196
|
-
const withInclude = makeHandler({
|
|
196
|
+
const withInclude = makeHandler({ ExcludeSchemas: ['vault'], IncludeEntities: ['secrets'] });
|
|
197
197
|
expect(withInclude.isEntityAllowed('Secrets')).toBe(false);
|
|
198
198
|
});
|
|
199
199
|
|
|
200
200
|
it('restricts to included schemas when includeSchemas is set', () => {
|
|
201
|
-
const handler = makeHandler({
|
|
201
|
+
const handler = makeHandler({ IncludeSchemas: ['crm'] });
|
|
202
202
|
expect(handler.isEntityAllowed('Users')).toBe(true);
|
|
203
203
|
expect(handler.isEntityAllowed('Secrets')).toBe(false);
|
|
204
204
|
});
|
|
205
205
|
|
|
206
206
|
it('blocks lowercase exact-name exclusions and wildcard exclusions of any case', () => {
|
|
207
|
-
const lowercase = makeHandler({
|
|
207
|
+
const lowercase = makeHandler({ ExcludeEntities: ['secrets'] });
|
|
208
208
|
expect(lowercase.isEntityAllowed('Secrets')).toBe(false);
|
|
209
209
|
|
|
210
|
-
const wildcard = makeHandler({
|
|
210
|
+
const wildcard = makeHandler({ ExcludeEntities: ['Secret*'] });
|
|
211
211
|
expect(wildcard.isEntityAllowed('Secrets')).toBe(false);
|
|
212
212
|
expect(wildcard.isEntityAllowed('Users')).toBe(true);
|
|
213
213
|
});
|
|
@@ -217,25 +217,25 @@ describe('RESTEndpointHandler.isEntityAllowed', () => {
|
|
|
217
217
|
// the RAW configured pattern (only the wildcard branch lowercases patterns).
|
|
218
218
|
// An operator writing excludeEntities: ['Secrets'] — the natural casing —
|
|
219
219
|
// gets NO exclusion. Pinned so a normalization fix flips this test.
|
|
220
|
-
const handler = makeHandler({
|
|
220
|
+
const handler = makeHandler({ ExcludeEntities: ['Secrets'] });
|
|
221
221
|
expect(handler.isEntityAllowed('Secrets')).toBe(true); // exclusion ineffective!
|
|
222
222
|
});
|
|
223
223
|
|
|
224
224
|
it('exclusions override inclusions for the same entity', () => {
|
|
225
|
-
const handler = makeHandler({
|
|
225
|
+
const handler = makeHandler({ IncludeEntities: ['user*'], ExcludeEntities: ['userroles'] });
|
|
226
226
|
expect(handler.isEntityAllowed('Users')).toBe(true);
|
|
227
227
|
expect(handler.isEntityAllowed('UserRoles')).toBe(false);
|
|
228
228
|
});
|
|
229
229
|
|
|
230
230
|
it('an include list denies everything not on it, with wildcard support', () => {
|
|
231
|
-
const handler = makeHandler({
|
|
231
|
+
const handler = makeHandler({ IncludeEntities: ['user*'] });
|
|
232
232
|
expect(handler.isEntityAllowed('Users')).toBe(true);
|
|
233
233
|
expect(handler.isEntityAllowed('UserRoles')).toBe(true);
|
|
234
234
|
expect(handler.isEntityAllowed('Secrets')).toBe(false);
|
|
235
235
|
});
|
|
236
236
|
|
|
237
237
|
it('SECURITY GAP: a mixed-case exact inclusion fails to include (same raw-pattern comparison)', () => {
|
|
238
|
-
const handler = makeHandler({
|
|
238
|
+
const handler = makeHandler({ IncludeEntities: ['Users'] });
|
|
239
239
|
expect(handler.isEntityAllowed('Users')).toBe(false); // include list active, but never matches
|
|
240
240
|
});
|
|
241
241
|
});
|
|
@@ -271,7 +271,7 @@ describe('RESTEndpointHandler middleware', () => {
|
|
|
271
271
|
|
|
272
272
|
describe('checkEntityAccess', () => {
|
|
273
273
|
it('rejects blocked entities with 403 before any handler runs', () => {
|
|
274
|
-
const handler = makeHandler({
|
|
274
|
+
const handler = makeHandler({ ExcludeEntities: ['secrets'] });
|
|
275
275
|
const req = makeReq({ params: { entityName: 'Secrets' } });
|
|
276
276
|
const { res, statusCode, jsonBody } = makeRes();
|
|
277
277
|
const next = vi.fn();
|
|
@@ -286,7 +286,7 @@ describe('RESTEndpointHandler middleware', () => {
|
|
|
286
286
|
});
|
|
287
287
|
|
|
288
288
|
it('passes allowed entities through', () => {
|
|
289
|
-
const handler = makeHandler({
|
|
289
|
+
const handler = makeHandler({ ExcludeEntities: ['secrets'] });
|
|
290
290
|
const next = vi.fn();
|
|
291
291
|
|
|
292
292
|
handler.checkEntityAccess(makeReq({ params: { entityName: 'Users' } }), makeRes().res, next);
|
|
@@ -295,7 +295,7 @@ describe('RESTEndpointHandler middleware', () => {
|
|
|
295
295
|
});
|
|
296
296
|
|
|
297
297
|
it('passes through when no entityName param is present', () => {
|
|
298
|
-
const handler = makeHandler({
|
|
298
|
+
const handler = makeHandler({ IncludeEntities: ['nothing'] });
|
|
299
299
|
const next = vi.fn();
|
|
300
300
|
|
|
301
301
|
handler.checkEntityAccess(makeReq({ params: {} }), makeRes().res, next);
|
|
@@ -565,7 +565,7 @@ describe('RESTEndpointHandler view routes', () => {
|
|
|
565
565
|
});
|
|
566
566
|
|
|
567
567
|
it('returns 403 WITHOUT invoking the view layer when every requested entity is blocked', async () => {
|
|
568
|
-
const handler = makeHandler({
|
|
568
|
+
const handler = makeHandler({ IncludeEntities: ['users'] });
|
|
569
569
|
const { res, statusCode } = makeRes();
|
|
570
570
|
|
|
571
571
|
await handler.runViews(
|
|
@@ -579,7 +579,7 @@ describe('RESTEndpointHandler view routes', () => {
|
|
|
579
579
|
|
|
580
580
|
it('silently drops blocked entities and executes only the allowed remainder', async () => {
|
|
581
581
|
mockOpsRunViews.mockResolvedValue({ success: true, results: [{ Success: true, Results: [] }] });
|
|
582
|
-
const handler = makeHandler({
|
|
582
|
+
const handler = makeHandler({ ExcludeEntities: ['secrets'] });
|
|
583
583
|
const req = makeReq({ body: { params: [{ EntityName: 'Users' }, { EntityName: 'Secrets' }] } });
|
|
584
584
|
const { res, jsonBody } = makeRes();
|
|
585
585
|
|
|
@@ -50,8 +50,10 @@ vi.mock('@memberjunction/ai-agents', () => ({
|
|
|
50
50
|
// Mock the meeting-recording registration so the thin resolver is tested in isolation (no MJStorage /
|
|
51
51
|
// core-entities graph). Its own behavior is covered by meetingRecordingRegistration.test.ts.
|
|
52
52
|
vi.mock('../resolvers/meetingRecordingRegistration', () => ({
|
|
53
|
-
|
|
54
|
-
|
|
53
|
+
RegisterMeetingRecordingFile: vi.fn(async () => ({ Success: true, RecordingFileID: 'file-1', ConversationID: 'conv-1' })),
|
|
54
|
+
get registerMeetingRecordingFile() { return this.RegisterMeetingRecordingFile; },
|
|
55
|
+
CorrelateRecordingStart: vi.fn(async () => true),
|
|
56
|
+
get correlateRecordingStart() { return this.CorrelateRecordingStart; },
|
|
55
57
|
}));
|
|
56
58
|
|
|
57
59
|
import { RealtimeBridgeResolver, MintLiveKitClientTokenInput, LiveKitRecordingInput } from '../resolvers/RealtimeBridgeResolver';
|
|
@@ -2,7 +2,7 @@ import { describe, it, expect, beforeEach, vi } from 'vitest';
|
|
|
2
2
|
import type { Request, Response, NextFunction } from 'express';
|
|
3
3
|
import { MJGlobal, RegisterClass } from '@memberjunction/global';
|
|
4
4
|
import { BaseRealtimeModel, RealtimeProxyRegistry, IRealtimeSession, RealtimeSessionParams } from '@memberjunction/ai';
|
|
5
|
-
import {
|
|
5
|
+
import { CreateRealtimeSdpBrokerRouter, createOpenAILiveBrokerRouter, RequireTicket } from '../rest/RealtimeSdpBrokerHandler.js';
|
|
6
6
|
|
|
7
7
|
@RegisterClass(BaseRealtimeModel, 'MockOpenAILiveForBrokerTest', 10)
|
|
8
8
|
class MockOpenAILiveForBrokerTest extends BaseRealtimeModel {
|
|
@@ -67,20 +67,20 @@ function makeMockReqRes(query: Record<string, string>, body: unknown): {
|
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
describe('RealtimeSdpBrokerHandler', () => {
|
|
70
|
-
let router: ReturnType<typeof
|
|
70
|
+
let router: ReturnType<typeof CreateRealtimeSdpBrokerRouter>;
|
|
71
71
|
|
|
72
72
|
beforeEach(() => {
|
|
73
|
-
router =
|
|
73
|
+
router = CreateRealtimeSdpBrokerRouter();
|
|
74
74
|
});
|
|
75
75
|
|
|
76
76
|
it('createOpenAILiveBrokerRouter is backwards-compatible alias', () => {
|
|
77
|
-
expect(createOpenAILiveBrokerRouter).toBe(
|
|
77
|
+
expect(createOpenAILiveBrokerRouter).toBe(CreateRealtimeSdpBrokerRouter);
|
|
78
78
|
});
|
|
79
79
|
|
|
80
80
|
it('requireTicket middleware rejects missing ticket without calling next()', () => {
|
|
81
81
|
const { req, res, getStatus, getJson } = makeMockReqRes({}, {});
|
|
82
82
|
const next = vi.fn();
|
|
83
|
-
|
|
83
|
+
RequireTicket(req, res, next as NextFunction);
|
|
84
84
|
expect(getStatus()).toBe(401);
|
|
85
85
|
expect(getJson().error).toContain('missing ticket');
|
|
86
86
|
expect(next).not.toHaveBeenCalled();
|
|
@@ -89,7 +89,7 @@ describe('RealtimeSdpBrokerHandler', () => {
|
|
|
89
89
|
it('requireTicket middleware rejects invalid ticket without calling next()', () => {
|
|
90
90
|
const { req, res, getStatus, getJson } = makeMockReqRes({ ticket: 'non-existent-ticket' }, {});
|
|
91
91
|
const next = vi.fn();
|
|
92
|
-
|
|
92
|
+
RequireTicket(req, res, next as NextFunction);
|
|
93
93
|
expect(getStatus()).toBe(401);
|
|
94
94
|
expect(getJson().error).toContain('invalid or expired ticket');
|
|
95
95
|
expect(next).not.toHaveBeenCalled();
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { describe, it, expect } from 'vitest';
|
|
2
2
|
import { readFileSync } from 'node:fs';
|
|
3
3
|
import { join } from 'node:path';
|
|
4
|
-
import {
|
|
4
|
+
import { DecideFieldMapReconcile } from '../integration/EntityMapLifecycle.js';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* A REFRESH adopts the source's current shape: new objects and new columns both arrive ENABLED.
|
|
@@ -17,20 +17,20 @@ const fm = (SourceFieldName: string, Status: string) => ({ SourceFieldName, Stat
|
|
|
17
17
|
|
|
18
18
|
describe('decideFieldMapReconcile — a refresh adopts new columns', () => {
|
|
19
19
|
it('creates a new column ENABLED on an enabled map, by default', () => {
|
|
20
|
-
const plan =
|
|
20
|
+
const plan = DecideFieldMapReconcile(['id', 'brand_new_col'], [fm('id', 'Active')], true);
|
|
21
21
|
expect(plan.Create).toEqual([{ SourceFieldName: 'brand_new_col', Status: 'Active' }]);
|
|
22
22
|
expect(plan.Enable).toEqual([]);
|
|
23
23
|
expect(plan.Disable).toEqual([]);
|
|
24
24
|
});
|
|
25
25
|
|
|
26
26
|
it('autoEnableNewColumns:false gates it for a connection that wants to review first', () => {
|
|
27
|
-
const plan =
|
|
27
|
+
const plan = DecideFieldMapReconcile(['id', 'brand_new_col'], [fm('id', 'Active')], true, false);
|
|
28
28
|
expect(plan.Create).toEqual([{ SourceFieldName: 'brand_new_col', Status: 'Inactive' }]);
|
|
29
29
|
});
|
|
30
30
|
|
|
31
31
|
it('a DISABLED map never gets an Active column — the map always bounds the column', () => {
|
|
32
32
|
// Adopting new columns must not resurrect a map the user switched off.
|
|
33
|
-
const plan =
|
|
33
|
+
const plan = DecideFieldMapReconcile(['brand_new_col'], [], false, true);
|
|
34
34
|
expect(plan.Create).toEqual([{ SourceFieldName: 'brand_new_col', Status: 'Inactive' }]);
|
|
35
35
|
});
|
|
36
36
|
});
|
|
@@ -40,24 +40,24 @@ describe('decideFieldMapReconcile — retiring and restoring are both non-destru
|
|
|
40
40
|
// That row is not new — it was disabled because the source stopped reporting the column, so
|
|
41
41
|
// it returns to the state it had. Gating it would silently demote a column the user chose to
|
|
42
42
|
// sync whenever the source flickered.
|
|
43
|
-
const plan =
|
|
43
|
+
const plan = DecideFieldMapReconcile(['came_back'], [fm('came_back', 'Inactive')], true, false);
|
|
44
44
|
expect(plan.Enable).toEqual(['came_back']);
|
|
45
45
|
expect(plan.Create).toEqual([]); // reuses the row, never mints a second one
|
|
46
46
|
});
|
|
47
47
|
|
|
48
48
|
it('a column absent from the resolution is DISABLED, never deleted', () => {
|
|
49
|
-
const plan =
|
|
49
|
+
const plan = DecideFieldMapReconcile(['kept'], [fm('kept', 'Active'), fm('vanished', 'Active')], true);
|
|
50
50
|
expect(plan.Disable).toEqual(['vanished']);
|
|
51
51
|
expect(plan.Enable).toEqual([]); // survivor untouched
|
|
52
52
|
});
|
|
53
53
|
|
|
54
54
|
it('does not re-enable anything while the map itself is disabled', () => {
|
|
55
|
-
const plan =
|
|
55
|
+
const plan = DecideFieldMapReconcile(['came_back'], [fm('came_back', 'Inactive')], false);
|
|
56
56
|
expect(plan.Enable).toEqual([]);
|
|
57
57
|
});
|
|
58
58
|
|
|
59
59
|
it('matches source field names case-insensitively on both sides', () => {
|
|
60
|
-
const plan =
|
|
60
|
+
const plan = DecideFieldMapReconcile(['ID', 'Name'], [fm('id', 'Active'), fm('name', 'Active')], true);
|
|
61
61
|
expect(plan.Create).toEqual([]);
|
|
62
62
|
expect(plan.Disable).toEqual([]);
|
|
63
63
|
});
|