doover-js 0.11.0 → 0.13.0
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 +106 -0
- package/dist/apis/_args.js +5 -5
- package/dist/apis/agents-api.d.ts +4 -4
- package/dist/apis/agents-api.js +2 -2
- package/dist/apis/aggregates-api.d.ts +4 -4
- package/dist/apis/aggregates-api.js +5 -5
- package/dist/apis/alarms-api.d.ts +2 -2
- package/dist/apis/alarms-api.js +3 -3
- package/dist/apis/channels-api.d.ts +3 -3
- package/dist/apis/channels-api.js +6 -6
- package/dist/apis/connections-api.d.ts +2 -2
- package/dist/apis/connections-api.js +6 -6
- package/dist/apis/messages-api.d.ts +4 -4
- package/dist/apis/messages-api.js +11 -11
- package/dist/apis/notifications-api.d.ts +2 -2
- package/dist/apis/notifications-api.js +4 -4
- package/dist/apis/organisations-api.d.ts +2 -2
- package/dist/apis/permissions-api.d.ts +2 -2
- package/dist/apis/permissions-api.js +3 -3
- package/dist/apis/processors-api.d.ts +2 -2
- package/dist/apis/turn-api.d.ts +2 -2
- package/dist/apis/users-api.d.ts +2 -2
- package/dist/auth/auth-store.d.ts +1 -1
- package/dist/auth/build-auth.d.ts +3 -3
- package/dist/auth/build-auth.js +8 -8
- package/dist/auth/cookie-auth.d.ts +1 -1
- package/dist/auth/cookie-auth.js +2 -2
- package/dist/auth/doover-auth.d.ts +2 -2
- package/dist/auth/doover-token-auth.d.ts +3 -3
- package/dist/auth/doover-token-auth.js +13 -13
- package/dist/auth/index.d.ts +10 -0
- package/dist/auth/index.js +15 -0
- package/dist/client/data-client.d.ts +17 -14
- package/dist/client/doover-client.d.ts +9 -7
- package/dist/client/doover-client.js +44 -42
- package/dist/client/errors.d.ts +2 -2
- package/dist/client/errors.js +4 -4
- package/dist/client/index.d.ts +6 -0
- package/dist/client/index.js +12 -0
- package/dist/client/local-agent-client.d.ts +3 -3
- package/dist/client/local-agent-client.js +19 -19
- package/dist/client/multiplex-client.d.ts +5 -5
- package/dist/client/multiplex-client.js +25 -25
- package/dist/client/multiplex-gateway.d.ts +3 -3
- package/dist/client/multiplex-merge.d.ts +1 -1
- package/dist/client/network-status.d.ts +17 -0
- package/dist/client/network-status.js +70 -0
- package/dist/client/offline-cache.d.ts +9 -4
- package/dist/client/offline-cache.js +34 -22
- package/dist/client/provenance.d.ts +1 -1
- package/dist/client/request-options.d.ts +1 -1
- package/dist/client/singleton.d.ts +2 -2
- package/dist/client/singleton.js +2 -2
- package/dist/client/status-tracker.d.ts +1 -1
- package/dist/esm/apis/_args.d.ts +16 -0
- package/dist/esm/apis/_args.js +27 -0
- package/dist/esm/apis/agents-api.d.ts +196 -0
- package/dist/esm/apis/agents-api.js +327 -0
- package/dist/esm/apis/aggregates-api.d.ts +67 -0
- package/dist/esm/apis/aggregates-api.js +64 -0
- package/dist/esm/apis/alarms-api.d.ts +48 -0
- package/dist/esm/apis/alarms-api.js +75 -0
- package/dist/esm/apis/channels-api.d.ts +83 -0
- package/dist/esm/apis/channels-api.js +65 -0
- package/dist/esm/apis/connections-api.d.ts +45 -0
- package/dist/esm/apis/connections-api.js +44 -0
- package/dist/esm/apis/messages-api.d.ts +128 -0
- package/dist/esm/apis/messages-api.js +179 -0
- package/dist/esm/apis/notifications-api.d.ts +94 -0
- package/dist/esm/apis/notifications-api.js +153 -0
- package/dist/esm/apis/organisations-api.d.ts +26 -0
- package/dist/esm/apis/organisations-api.js +41 -0
- package/dist/esm/apis/permissions-api.d.ts +17 -0
- package/dist/esm/apis/permissions-api.js +23 -0
- package/dist/esm/apis/processors-api.d.ts +56 -0
- package/dist/esm/apis/processors-api.js +97 -0
- package/dist/esm/apis/turn-api.d.ts +7 -0
- package/dist/esm/apis/turn-api.js +8 -0
- package/dist/esm/apis/users-api.d.ts +8 -0
- package/dist/esm/apis/users-api.js +9 -0
- package/dist/esm/auth/auth-profile.d.ts +45 -0
- package/dist/esm/auth/auth-profile.js +68 -0
- package/dist/esm/auth/auth-store.d.ts +14 -0
- package/dist/esm/auth/build-auth.d.ts +38 -0
- package/dist/esm/auth/build-auth.js +92 -0
- package/dist/esm/auth/cookie-auth.d.ts +91 -0
- package/dist/esm/auth/cookie-auth.js +196 -0
- package/dist/esm/auth/doover-auth.d.ts +52 -0
- package/dist/esm/auth/doover-auth.js +28 -0
- package/dist/esm/auth/doover-token-auth.d.ts +39 -0
- package/dist/esm/auth/doover-token-auth.js +217 -0
- package/dist/esm/auth/errors.d.ts +3 -0
- package/dist/esm/auth/errors.js +6 -0
- package/dist/esm/auth/index.d.ts +10 -0
- package/dist/esm/auth/index.js +6 -0
- package/dist/esm/auth/jwt.d.ts +6 -0
- package/dist/esm/auth/jwt.js +26 -0
- package/dist/esm/client/capabilities.d.ts +10 -0
- package/dist/esm/client/capabilities.js +42 -0
- package/dist/esm/client/data-client.d.ts +107 -0
- package/dist/esm/client/doover-client.d.ts +48 -0
- package/dist/esm/client/doover-client.js +96 -0
- package/dist/esm/client/errors.d.ts +32 -0
- package/dist/esm/client/errors.js +64 -0
- package/dist/esm/client/index.d.ts +6 -0
- package/dist/esm/client/index.js +3 -0
- package/dist/esm/client/local-agent-client.d.ts +65 -0
- package/dist/esm/client/local-agent-client.js +225 -0
- package/dist/esm/client/multiplex-client.d.ts +165 -0
- package/dist/esm/client/multiplex-client.js +842 -0
- package/dist/esm/client/multiplex-gateway.d.ts +49 -0
- package/dist/esm/client/multiplex-gateway.js +110 -0
- package/dist/esm/client/multiplex-merge.d.ts +12 -0
- package/dist/esm/client/multiplex-merge.js +38 -0
- package/dist/esm/client/network-status.d.ts +17 -0
- package/dist/esm/client/network-status.js +66 -0
- package/dist/esm/client/offline-cache.d.ts +167 -0
- package/dist/esm/client/offline-cache.js +769 -0
- package/dist/esm/client/provenance.d.ts +60 -0
- package/dist/esm/client/provenance.js +108 -0
- package/dist/esm/client/request-options.d.ts +23 -0
- package/dist/esm/client/request-options.js +23 -0
- package/dist/esm/client/singleton.d.ts +26 -0
- package/dist/esm/client/singleton.js +54 -0
- package/dist/esm/client/stats.d.ts +79 -0
- package/dist/esm/client/stats.js +155 -0
- package/dist/esm/client/status-tracker.d.ts +24 -0
- package/dist/esm/client/status-tracker.js +86 -0
- package/dist/esm/gateway/gateway-client.d.ts +86 -0
- package/dist/esm/gateway/gateway-client.js +463 -0
- package/dist/esm/gateway/index.d.ts +3 -0
- package/dist/esm/gateway/index.js +1 -0
- package/dist/esm/gateway/types.d.ts +142 -0
- package/dist/esm/http/errors.d.ts +19 -0
- package/dist/esm/http/errors.js +22 -0
- package/dist/esm/http/index.d.ts +3 -0
- package/dist/esm/http/index.js +2 -0
- package/dist/esm/http/rest-client.d.ts +64 -0
- package/dist/esm/http/rest-client.js +181 -0
- package/dist/esm/index.d.ts +64 -0
- package/dist/esm/index.js +38 -0
- package/dist/esm/node/config-manager.d.ts +34 -0
- package/dist/esm/node/config-manager.js +140 -0
- package/dist/esm/node/index.d.ts +1 -0
- package/dist/esm/node/index.js +1 -0
- package/dist/esm/package.json +1 -0
- package/dist/esm/react/context.d.ts +23 -0
- package/dist/esm/react/context.js +28 -0
- package/dist/esm/react/index.d.ts +38 -0
- package/dist/esm/react/index.js +21 -0
- package/dist/esm/react/messageRangeStore.d.ts +93 -0
- package/dist/esm/react/messageRangeStore.js +140 -0
- package/dist/esm/react/sharedQueryClient.d.ts +21 -0
- package/dist/esm/react/sharedQueryClient.js +35 -0
- package/dist/esm/react/useAgentChannel.d.ts +8 -0
- package/dist/esm/react/useAgentChannel.js +9 -0
- package/dist/esm/react/useAgentConnections.d.ts +8 -0
- package/dist/esm/react/useAgentConnections.js +20 -0
- package/dist/esm/react/useAgentTokenState.d.ts +70 -0
- package/dist/esm/react/useAgentTokenState.js +127 -0
- package/dist/esm/react/useChannelAggregate.d.ts +64 -0
- package/dist/esm/react/useChannelAggregate.js +77 -0
- package/dist/esm/react/useChannelMessage.d.ts +45 -0
- package/dist/esm/react/useChannelMessage.js +79 -0
- package/dist/esm/react/useChannelMessages.d.ts +83 -0
- package/dist/esm/react/useChannelMessages.js +214 -0
- package/dist/esm/react/useChannelSubscription.d.ts +27 -0
- package/dist/esm/react/useChannelSubscription.js +30 -0
- package/dist/esm/react/useClientStatus.d.ts +10 -0
- package/dist/esm/react/useClientStatus.js +19 -0
- package/dist/esm/react/useConnectionState.d.ts +26 -0
- package/dist/esm/react/useConnectionState.js +45 -0
- package/dist/esm/react/useDeviceMap.d.ts +109 -0
- package/dist/esm/react/useDeviceMap.js +59 -0
- package/dist/esm/react/useInvocationLogs.d.ts +23 -0
- package/dist/esm/react/useInvocationLogs.js +37 -0
- package/dist/esm/react/useMultiAgentAggregates.d.ts +38 -0
- package/dist/esm/react/useMultiAgentAggregates.js +104 -0
- package/dist/esm/react/useMultiAgentChannelMessages.d.ts +79 -0
- package/dist/esm/react/useMultiAgentChannelMessages.js +169 -0
- package/dist/esm/react/useOfflineStatus.d.ts +8 -0
- package/dist/esm/react/useOfflineStatus.js +37 -0
- package/dist/esm/react/useSendMessage.d.ts +16 -0
- package/dist/esm/react/useSendMessage.js +26 -0
- package/dist/esm/react/useSendRpc.d.ts +68 -0
- package/dist/esm/react/useSendRpc.js +164 -0
- package/dist/esm/react/useTurnCredentials.d.ts +12 -0
- package/dist/esm/react/useTurnCredentials.js +22 -0
- package/dist/esm/react/useUpdateAggregate.d.ts +27 -0
- package/dist/esm/react/useUpdateAggregate.js +39 -0
- package/dist/esm/react/useUpdateMessage.d.ts +38 -0
- package/dist/esm/react/useUpdateMessage.js +36 -0
- package/dist/esm/refine/index.d.ts +72 -0
- package/dist/esm/refine/index.js +215 -0
- package/dist/esm/rpc/errors.d.ts +10 -0
- package/dist/esm/rpc/errors.js +19 -0
- package/dist/esm/rpc/index.d.ts +3 -0
- package/dist/esm/rpc/index.js +2 -0
- package/dist/esm/rpc/rpc-dispatcher.d.ts +41 -0
- package/dist/esm/rpc/rpc-dispatcher.js +141 -0
- package/dist/esm/types/audit.d.ts +53 -0
- package/dist/esm/types/audit.js +11 -0
- package/dist/esm/types/batch.d.ts +85 -0
- package/dist/esm/types/batch.js +42 -0
- package/dist/esm/types/common.d.ts +250 -0
- package/dist/esm/types/connection.d.ts +72 -0
- package/dist/esm/types/connection.js +7 -0
- package/dist/esm/types/index.d.ts +9 -0
- package/dist/esm/types/openapi.d.ts +195 -0
- package/dist/esm/types/provenance.d.ts +45 -0
- package/dist/esm/types/viewer.d.ts +122 -0
- package/dist/esm/utils/snowflake.d.ts +21 -0
- package/dist/esm/utils/snowflake.js +33 -0
- package/dist/esm/viewer/doover-data-provider.d.ts +90 -0
- package/dist/esm/viewer/doover-data-provider.js +189 -0
- package/dist/esm/viewer/path-parsing.d.ts +5 -0
- package/dist/esm/viewer/path-parsing.js +35 -0
- package/dist/gateway/gateway-client.d.ts +5 -5
- package/dist/gateway/gateway-client.js +5 -5
- package/dist/gateway/index.d.ts +3 -0
- package/dist/gateway/index.js +5 -0
- package/dist/gateway/types.d.ts +1 -1
- package/dist/http/index.d.ts +3 -0
- package/dist/http/index.js +9 -0
- package/dist/http/rest-client.d.ts +5 -3
- package/dist/http/rest-client.js +2 -2
- package/dist/index.d.ts +64 -62
- package/dist/index.js +92 -89
- package/dist/node/config-manager.d.ts +2 -2
- package/dist/node/config-manager.js +5 -5
- package/dist/node/index.d.ts +1 -1
- package/dist/node/index.js +2 -2
- package/dist/react/context.d.ts +1 -1
- package/dist/react/index.d.ts +38 -38
- package/dist/react/index.js +59 -59
- package/dist/react/messageRangeStore.d.ts +1 -1
- package/dist/react/useAgentChannel.d.ts +3 -3
- package/dist/react/useAgentChannel.js +2 -2
- package/dist/react/useAgentConnections.d.ts +1 -1
- package/dist/react/useAgentConnections.js +2 -2
- package/dist/react/useAgentTokenState.d.ts +3 -3
- package/dist/react/useAgentTokenState.js +8 -8
- package/dist/react/useChannelAggregate.d.ts +3 -3
- package/dist/react/useChannelAggregate.js +8 -8
- package/dist/react/useChannelMessage.d.ts +2 -2
- package/dist/react/useChannelMessage.js +4 -4
- package/dist/react/useChannelMessages.d.ts +3 -3
- package/dist/react/useChannelMessages.js +10 -10
- package/dist/react/useChannelSubscription.d.ts +2 -2
- package/dist/react/useChannelSubscription.js +2 -2
- package/dist/react/useClientStatus.d.ts +1 -1
- package/dist/react/useClientStatus.js +2 -2
- package/dist/react/useConnectionState.js +2 -2
- package/dist/react/useDeviceMap.js +2 -2
- package/dist/react/useInvocationLogs.d.ts +1 -1
- package/dist/react/useInvocationLogs.js +2 -2
- package/dist/react/useMultiAgentAggregates.d.ts +1 -1
- package/dist/react/useMultiAgentAggregates.js +5 -5
- package/dist/react/useMultiAgentChannelMessages.d.ts +1 -1
- package/dist/react/useMultiAgentChannelMessages.js +2 -2
- package/dist/react/useOfflineStatus.d.ts +2 -2
- package/dist/react/useOfflineStatus.js +31 -17
- package/dist/react/useSendMessage.d.ts +2 -2
- package/dist/react/useSendMessage.js +2 -2
- package/dist/react/useSendRpc.d.ts +2 -2
- package/dist/react/useSendRpc.js +2 -2
- package/dist/react/useTurnCredentials.d.ts +2 -2
- package/dist/react/useTurnCredentials.js +2 -2
- package/dist/react/useUpdateAggregate.d.ts +3 -3
- package/dist/react/useUpdateAggregate.js +4 -4
- package/dist/react/useUpdateMessage.d.ts +2 -2
- package/dist/react/useUpdateMessage.js +2 -2
- package/dist/refine/index.d.ts +1 -1
- package/dist/rpc/errors.d.ts +1 -1
- package/dist/rpc/index.d.ts +3 -0
- package/dist/rpc/index.js +7 -0
- package/dist/rpc/rpc-dispatcher.d.ts +4 -4
- package/dist/rpc/rpc-dispatcher.js +2 -2
- package/dist/types/common.d.ts +1 -1
- package/dist/types/index.d.ts +9 -0
- package/dist/types/index.js +2 -0
- package/dist/types/openapi.d.ts +1 -1
- package/dist/types/viewer.d.ts +2 -2
- package/dist/viewer/doover-data-provider.d.ts +10 -10
- package/dist/viewer/doover-data-provider.js +25 -25
- package/dist/viewer/path-parsing.d.ts +1 -1
- package/package.json +795 -8
- package/dist/test/api-args.test.js +0 -48
- package/dist/test/api-overloads.test.d.ts +0 -9
- package/dist/test/api-overloads.test.js +0 -330
- package/dist/test/apis.test.js +0 -408
- package/dist/test/auth.test.js +0 -708
- package/dist/test/batch-apis.test.js +0 -183
- package/dist/test/capabilities.test.js +0 -27
- package/dist/test/config-manager.test.js +0 -160
- package/dist/test/data-client-errors.test.js +0 -24
- package/dist/test/data-client-shape.test.js +0 -28
- package/dist/test/doover-client-dataclient.test.d.ts +0 -1
- package/dist/test/doover-client-dataclient.test.js +0 -58
- package/dist/test/doover-client-provenance.test.d.ts +0 -1
- package/dist/test/doover-client-provenance.test.js +0 -32
- package/dist/test/doover-client.test.d.ts +0 -1
- package/dist/test/doover-client.test.js +0 -42
- package/dist/test/doover-data-provider.test.d.ts +0 -1
- package/dist/test/doover-data-provider.test.js +0 -657
- package/dist/test/exports.test.d.ts +0 -1
- package/dist/test/exports.test.js +0 -80
- package/dist/test/gateway-client.test.d.ts +0 -1
- package/dist/test/gateway-client.test.js +0 -474
- package/dist/test/gateway-provenance.test.d.ts +0 -1
- package/dist/test/gateway-provenance.test.js +0 -29
- package/dist/test/gateway-subscriptions.test.d.ts +0 -1
- package/dist/test/gateway-subscriptions.test.js +0 -95
- package/dist/test/helpers.d.ts +0 -32
- package/dist/test/helpers.js +0 -115
- package/dist/test/local-agent-client.test.d.ts +0 -1
- package/dist/test/local-agent-client.test.js +0 -202
- package/dist/test/message-range-store.test.d.ts +0 -1
- package/dist/test/message-range-store.test.js +0 -183
- package/dist/test/multiplex-capabilities.test.d.ts +0 -1
- package/dist/test/multiplex-capabilities.test.js +0 -37
- package/dist/test/multiplex-conflicts.test.d.ts +0 -1
- package/dist/test/multiplex-conflicts.test.js +0 -35
- package/dist/test/multiplex-gateway.test.d.ts +0 -1
- package/dist/test/multiplex-gateway.test.js +0 -103
- package/dist/test/multiplex-merge.test.d.ts +0 -1
- package/dist/test/multiplex-merge.test.js +0 -19
- package/dist/test/multiplex-noncore.test.d.ts +0 -1
- package/dist/test/multiplex-noncore.test.js +0 -82
- package/dist/test/multiplex-passthrough.test.d.ts +0 -1
- package/dist/test/multiplex-passthrough.test.js +0 -35
- package/dist/test/multiplex-reads.test.d.ts +0 -1
- package/dist/test/multiplex-reads.test.js +0 -87
- package/dist/test/multiplex-registry.test.d.ts +0 -1
- package/dist/test/multiplex-registry.test.js +0 -81
- package/dist/test/multiplex-routing.test.d.ts +0 -1
- package/dist/test/multiplex-routing.test.js +0 -45
- package/dist/test/multiplex-status.test.d.ts +0 -1
- package/dist/test/multiplex-status.test.js +0 -63
- package/dist/test/multiplex-writes.test.d.ts +0 -1
- package/dist/test/multiplex-writes.test.js +0 -93
- package/dist/test/offline-cache.test.d.ts +0 -1
- package/dist/test/offline-cache.test.js +0 -289
- package/dist/test/provenance-regression.test.d.ts +0 -1
- package/dist/test/provenance-regression.test.js +0 -45
- package/dist/test/provenance-stamper.test.d.ts +0 -1
- package/dist/test/provenance-stamper.test.js +0 -41
- package/dist/test/provenance-type.test.d.ts +0 -1
- package/dist/test/provenance-type.test.js +0 -15
- package/dist/test/react-channel-messages-forward.test.d.ts +0 -1
- package/dist/test/react-channel-messages-forward.test.js +0 -139
- package/dist/test/react-channel-messages-range.test.d.ts +0 -1
- package/dist/test/react-channel-messages-range.test.js +0 -109
- package/dist/test/react-client-status.test.d.ts +0 -1
- package/dist/test/react-client-status.test.js +0 -35
- package/dist/test/react-dataclient.test.d.ts +0 -1
- package/dist/test/react-dataclient.test.js +0 -28
- package/dist/test/react-exports.test.d.ts +0 -1
- package/dist/test/react-exports.test.js +0 -46
- package/dist/test/react-multiagent-messages.test.d.ts +0 -1
- package/dist/test/react-multiagent-messages.test.js +0 -113
- package/dist/test/react-sources-option.test.d.ts +0 -1
- package/dist/test/react-sources-option.test.js +0 -41
- package/dist/test/react.test.d.ts +0 -1
- package/dist/test/react.test.js +0 -482
- package/dist/test/refine.test.d.ts +0 -1
- package/dist/test/refine.test.js +0 -71
- package/dist/test/rest-client.test.d.ts +0 -1
- package/dist/test/rest-client.test.js +0 -197
- package/dist/test/rpc-dispatcher.test.d.ts +0 -1
- package/dist/test/rpc-dispatcher.test.js +0 -251
- package/dist/test/singleton.test.d.ts +0 -1
- package/dist/test/singleton.test.js +0 -62
- package/dist/test/stats-rpc.test.d.ts +0 -1
- package/dist/test/stats-rpc.test.js +0 -69
- package/dist/test/status-tracker.test.d.ts +0 -1
- package/dist/test/status-tracker.test.js +0 -85
- package/dist/test/users-api.test.d.ts +0 -1
- package/dist/test/users-api.test.js +0 -19
- package/dist/test/utils.test.d.ts +0 -1
- package/dist/test/utils.test.js +0 -64
- /package/dist/{test/api-args.test.d.ts → esm/auth/auth-store.js} +0 -0
- /package/dist/{test/apis.test.d.ts → esm/client/data-client.js} +0 -0
- /package/dist/{test/auth.test.d.ts → esm/gateway/types.js} +0 -0
- /package/dist/{test/batch-apis.test.d.ts → esm/types/common.js} +0 -0
- /package/dist/{test/capabilities.test.d.ts → esm/types/index.js} +0 -0
- /package/dist/{test/config-manager.test.d.ts → esm/types/openapi.js} +0 -0
- /package/dist/{test/data-client-errors.test.d.ts → esm/types/provenance.js} +0 -0
- /package/dist/{test/data-client-shape.test.d.ts → esm/types/viewer.js} +0 -0
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
import { DooverAuth } from "./doover-auth.js";
|
|
2
|
+
import { DooverAuthError } from "./errors.js";
|
|
3
|
+
import { decodeTokenExpiry } from "./jwt.js";
|
|
4
|
+
/** Buffer in milliseconds before expiry at which we trigger a refresh (30 s). */
|
|
5
|
+
const REFRESH_BUFFER_MS = 30000;
|
|
6
|
+
export class DooverTokenAuth extends DooverAuth {
|
|
7
|
+
constructor(options) {
|
|
8
|
+
super();
|
|
9
|
+
this.refreshInFlight = null;
|
|
10
|
+
this.authInvalid = false;
|
|
11
|
+
this.token = options.token ?? null;
|
|
12
|
+
this.tokenExpires = this.resolveExpiry(options.tokenExpires, options.token ?? null);
|
|
13
|
+
this.refreshToken = options.refreshToken ?? null;
|
|
14
|
+
this.refreshTokenId = options.refreshTokenId ?? null;
|
|
15
|
+
this.authServerUrl = options.authServerUrl ?? null;
|
|
16
|
+
this.authServerClientId = options.authServerClientId ?? null;
|
|
17
|
+
this.fetchImpl = options.fetchImpl ?? fetch;
|
|
18
|
+
}
|
|
19
|
+
// ------------------------------------------------------------------
|
|
20
|
+
// DooverAuth interface
|
|
21
|
+
// ------------------------------------------------------------------
|
|
22
|
+
async getHttpHeaders() {
|
|
23
|
+
if (!this.token) {
|
|
24
|
+
return {};
|
|
25
|
+
}
|
|
26
|
+
return { Authorization: `Bearer ${this.token}` };
|
|
27
|
+
}
|
|
28
|
+
getFetchCredentials() {
|
|
29
|
+
return "omit";
|
|
30
|
+
}
|
|
31
|
+
async prepareWebSocket(url, canUseHeaders) {
|
|
32
|
+
if (!this.token) {
|
|
33
|
+
return { url };
|
|
34
|
+
}
|
|
35
|
+
if (canUseHeaders) {
|
|
36
|
+
return {
|
|
37
|
+
url,
|
|
38
|
+
headers: { Authorization: `Bearer ${this.token}` },
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
// Append token as a query parameter for browser-style WebSocket.
|
|
42
|
+
const parsed = new URL(url);
|
|
43
|
+
parsed.searchParams.set("token", this.token);
|
|
44
|
+
return { url: parsed.toString() };
|
|
45
|
+
}
|
|
46
|
+
setToken(token, tokenExpires) {
|
|
47
|
+
this.token = token;
|
|
48
|
+
this.tokenExpires = this.resolveExpiry(tokenExpires, token);
|
|
49
|
+
if (token) {
|
|
50
|
+
this.authInvalid = false;
|
|
51
|
+
}
|
|
52
|
+
this.persistToProfile();
|
|
53
|
+
}
|
|
54
|
+
setRefreshToken(refreshToken) {
|
|
55
|
+
this.refreshToken = refreshToken;
|
|
56
|
+
if (refreshToken) {
|
|
57
|
+
this.authInvalid = false;
|
|
58
|
+
}
|
|
59
|
+
this.persistToProfile();
|
|
60
|
+
}
|
|
61
|
+
async ensureReady() {
|
|
62
|
+
if (this.authInvalid) {
|
|
63
|
+
throw new DooverAuthError("Authentication is invalid; sign in again");
|
|
64
|
+
}
|
|
65
|
+
if (!this.needsRefresh()) {
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
// Deduplicate concurrent refresh attempts.
|
|
69
|
+
if (!this.refreshInFlight) {
|
|
70
|
+
this.refreshInFlight = this.refresh().finally(() => {
|
|
71
|
+
this.refreshInFlight = null;
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
return this.refreshInFlight;
|
|
75
|
+
}
|
|
76
|
+
async handleUnauthorized() {
|
|
77
|
+
if (this.authInvalid) {
|
|
78
|
+
return false;
|
|
79
|
+
}
|
|
80
|
+
if (!this.refreshInFlight) {
|
|
81
|
+
this.refreshInFlight = this.refresh().finally(() => {
|
|
82
|
+
this.refreshInFlight = null;
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
try {
|
|
86
|
+
await this.refreshInFlight;
|
|
87
|
+
return true;
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
return false;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
// ------------------------------------------------------------------
|
|
94
|
+
// Profile attachment override — load refresh metadata from profile
|
|
95
|
+
// ------------------------------------------------------------------
|
|
96
|
+
attachProfile(profile, configManager) {
|
|
97
|
+
super.attachProfile(profile, configManager);
|
|
98
|
+
// Back-fill fields from the profile where not already set.
|
|
99
|
+
if (!this.token && profile.token) {
|
|
100
|
+
this.token = profile.token;
|
|
101
|
+
}
|
|
102
|
+
if (!this.tokenExpires && profile.tokenExpires) {
|
|
103
|
+
this.tokenExpires = new Date(profile.tokenExpires);
|
|
104
|
+
}
|
|
105
|
+
if (!this.tokenExpires && this.token) {
|
|
106
|
+
this.tokenExpires = decodeTokenExpiry(this.token);
|
|
107
|
+
}
|
|
108
|
+
if (!this.refreshToken && profile.refreshToken) {
|
|
109
|
+
this.refreshToken = profile.refreshToken;
|
|
110
|
+
}
|
|
111
|
+
if (!this.refreshTokenId && profile.refreshTokenId) {
|
|
112
|
+
this.refreshTokenId = profile.refreshTokenId;
|
|
113
|
+
}
|
|
114
|
+
if (!this.authServerUrl && profile.authServerUrl) {
|
|
115
|
+
this.authServerUrl = profile.authServerUrl;
|
|
116
|
+
}
|
|
117
|
+
if (!this.authServerClientId && profile.authServerClientId) {
|
|
118
|
+
this.authServerClientId = profile.authServerClientId;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
// ------------------------------------------------------------------
|
|
122
|
+
// Internal
|
|
123
|
+
// ------------------------------------------------------------------
|
|
124
|
+
needsRefresh() {
|
|
125
|
+
if (!this.token) {
|
|
126
|
+
return true;
|
|
127
|
+
}
|
|
128
|
+
if (!this.tokenExpires) {
|
|
129
|
+
return false;
|
|
130
|
+
}
|
|
131
|
+
return this.tokenExpires.getTime() - Date.now() < REFRESH_BUFFER_MS;
|
|
132
|
+
}
|
|
133
|
+
async refresh() {
|
|
134
|
+
if (!this.authServerUrl ||
|
|
135
|
+
!this.refreshToken ||
|
|
136
|
+
!this.authServerClientId) {
|
|
137
|
+
this.markAuthInvalid();
|
|
138
|
+
throw new DooverAuthError("Cannot refresh token: missing authServerUrl, refreshToken, or authServerClientId");
|
|
139
|
+
}
|
|
140
|
+
const url = new URL(`${this.authServerUrl}/oauth2/token`);
|
|
141
|
+
url.searchParams.set("grant_type", "refresh_token");
|
|
142
|
+
if (this.token) {
|
|
143
|
+
url.searchParams.set("access_token", this.token);
|
|
144
|
+
}
|
|
145
|
+
url.searchParams.set("refresh_token", this.refreshToken);
|
|
146
|
+
url.searchParams.set("client_id", this.authServerClientId);
|
|
147
|
+
let response;
|
|
148
|
+
try {
|
|
149
|
+
response = await this.fetchImpl(url.toString(), {
|
|
150
|
+
method: "POST",
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
catch (err) {
|
|
154
|
+
throw new DooverAuthError(`Token refresh request failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
155
|
+
}
|
|
156
|
+
if (!response.ok) {
|
|
157
|
+
if (response.status >= 400 && response.status < 500) {
|
|
158
|
+
this.markAuthInvalid();
|
|
159
|
+
}
|
|
160
|
+
throw new DooverAuthError(`Token refresh failed with status ${response.status}`);
|
|
161
|
+
}
|
|
162
|
+
const body = (await response.json());
|
|
163
|
+
if (!body.access_token) {
|
|
164
|
+
this.markAuthInvalid();
|
|
165
|
+
throw new DooverAuthError("Token refresh response did not contain an access_token");
|
|
166
|
+
}
|
|
167
|
+
this.authInvalid = false;
|
|
168
|
+
this.token = body.access_token;
|
|
169
|
+
this.tokenExpires =
|
|
170
|
+
typeof body.expires_in === "number"
|
|
171
|
+
? new Date(Date.now() + body.expires_in * 1000)
|
|
172
|
+
: decodeTokenExpiry(body.access_token);
|
|
173
|
+
if (body.refresh_token) {
|
|
174
|
+
this.refreshToken = body.refresh_token;
|
|
175
|
+
}
|
|
176
|
+
// Persist back to profile / config manager.
|
|
177
|
+
this.persistToProfile();
|
|
178
|
+
}
|
|
179
|
+
persistToProfile() {
|
|
180
|
+
if (!this.profile) {
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
this.profile.token = this.token;
|
|
184
|
+
this.profile.tokenExpires = this.tokenExpires
|
|
185
|
+
? this.tokenExpires.toISOString()
|
|
186
|
+
: null;
|
|
187
|
+
this.profile.refreshToken = this.refreshToken;
|
|
188
|
+
if (this.configManager) {
|
|
189
|
+
try {
|
|
190
|
+
this.configManager.create(this.profile);
|
|
191
|
+
this.configManager.write();
|
|
192
|
+
}
|
|
193
|
+
catch (err) {
|
|
194
|
+
throw new DooverAuthError(`Failed to persist refreshed token: ${err instanceof Error ? err.message : String(err)}`);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
markAuthInvalid() {
|
|
199
|
+
this.authInvalid = true;
|
|
200
|
+
this.token = null;
|
|
201
|
+
this.tokenExpires = null;
|
|
202
|
+
this.refreshToken = null;
|
|
203
|
+
this.persistToProfile();
|
|
204
|
+
}
|
|
205
|
+
resolveExpiry(explicit, token) {
|
|
206
|
+
if (explicit instanceof Date) {
|
|
207
|
+
return explicit;
|
|
208
|
+
}
|
|
209
|
+
if (typeof explicit === "number") {
|
|
210
|
+
return new Date(explicit);
|
|
211
|
+
}
|
|
212
|
+
if (token) {
|
|
213
|
+
return decodeTokenExpiry(token);
|
|
214
|
+
}
|
|
215
|
+
return null;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export { DooverAuth } from "./doover-auth.js";
|
|
2
|
+
export { CookieAuth } from "./cookie-auth.js";
|
|
3
|
+
export type { CookieAuthOptions } from "./cookie-auth.js";
|
|
4
|
+
export { DooverTokenAuth } from "./doover-token-auth.js";
|
|
5
|
+
export { AuthProfile } from "./auth-profile.js";
|
|
6
|
+
export type { AuthProfileData } from "./auth-profile.js";
|
|
7
|
+
export type { AuthProfileStore } from "./auth-store.js";
|
|
8
|
+
export { DooverAuthError } from "./errors.js";
|
|
9
|
+
export { buildAuth } from "./build-auth.js";
|
|
10
|
+
export type { AuthConfig } from "./build-auth.js";
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { DooverAuth } from "./doover-auth.js";
|
|
2
|
+
export { CookieAuth } from "./cookie-auth.js";
|
|
3
|
+
export { DooverTokenAuth } from "./doover-token-auth.js";
|
|
4
|
+
export { AuthProfile } from "./auth-profile.js";
|
|
5
|
+
export { DooverAuthError } from "./errors.js";
|
|
6
|
+
export { buildAuth } from "./build-auth.js";
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Decode the `exp` claim from a JWT without verifying the signature.
|
|
3
|
+
* Returns the expiry as a `Date`, or `null` if the token has no `exp` claim
|
|
4
|
+
* or cannot be decoded.
|
|
5
|
+
*/
|
|
6
|
+
export function decodeTokenExpiry(token) {
|
|
7
|
+
try {
|
|
8
|
+
const parts = token.split(".");
|
|
9
|
+
if (parts.length < 2) {
|
|
10
|
+
return null;
|
|
11
|
+
}
|
|
12
|
+
// Base64url → Base64 → decode
|
|
13
|
+
const base64 = parts[1].replace(/-/g, "+").replace(/_/g, "/");
|
|
14
|
+
const json = typeof atob === "function"
|
|
15
|
+
? atob(base64)
|
|
16
|
+
: Buffer.from(base64, "base64").toString("utf-8");
|
|
17
|
+
const payload = JSON.parse(json);
|
|
18
|
+
if (typeof payload.exp !== "number") {
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
return new Date(payload.exp * 1000);
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One capability per distinct endpoint-or-ability across the full `DataClient`
|
|
3
|
+
* surface. A backend advertises exactly what it can do; callers gate calls on
|
|
4
|
+
* these and an unsupported call throws `UnsupportedCapabilityError`.
|
|
5
|
+
*
|
|
6
|
+
* String-literal union (not a TS enum) so values serialise cleanly and can
|
|
7
|
+
* appear in error messages / debug UIs verbatim.
|
|
8
|
+
*/
|
|
9
|
+
export type Capability = "agents.list" | "agents.multiAgentMessages" | "agents.multiAgentAggregates" | "agents.tokenRead" | "agents.tokenManage" | "channels.list" | "channels.get" | "channels.create" | "channels.archive" | "channels.dataSeries" | "aggregates.get" | "aggregates.put" | "aggregates.patch" | "aggregates.attachment" | "messages.list" | "messages.listHistorical" | "messages.get" | "messages.post" | "messages.put" | "messages.delete" | "messages.attachment" | "messages.timeseries" | "messages.invocationLogs" | "gateway.subscribe" | "gateway.realtime" | "gateway.oneShot" | "rpc.send" | "alarms.read" | "alarms.write" | "connections.read" | "connections.write" | "notifications.read" | "notifications.write" | "permissions.read" | "permissions.write" | "processors.read" | "processors.write" | "turn.credentials" | "users.me";
|
|
10
|
+
export declare const ALL_CAPABILITIES: readonly Capability[];
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
export const ALL_CAPABILITIES = [
|
|
2
|
+
"agents.list",
|
|
3
|
+
"agents.multiAgentMessages",
|
|
4
|
+
"agents.multiAgentAggregates",
|
|
5
|
+
"agents.tokenRead",
|
|
6
|
+
"agents.tokenManage",
|
|
7
|
+
"channels.list",
|
|
8
|
+
"channels.get",
|
|
9
|
+
"channels.create",
|
|
10
|
+
"channels.archive",
|
|
11
|
+
"channels.dataSeries",
|
|
12
|
+
"aggregates.get",
|
|
13
|
+
"aggregates.put",
|
|
14
|
+
"aggregates.patch",
|
|
15
|
+
"aggregates.attachment",
|
|
16
|
+
"messages.list",
|
|
17
|
+
"messages.listHistorical",
|
|
18
|
+
"messages.get",
|
|
19
|
+
"messages.post",
|
|
20
|
+
"messages.put",
|
|
21
|
+
"messages.delete",
|
|
22
|
+
"messages.attachment",
|
|
23
|
+
"messages.timeseries",
|
|
24
|
+
"messages.invocationLogs",
|
|
25
|
+
"gateway.subscribe",
|
|
26
|
+
"gateway.realtime",
|
|
27
|
+
"gateway.oneShot",
|
|
28
|
+
"rpc.send",
|
|
29
|
+
"alarms.read",
|
|
30
|
+
"alarms.write",
|
|
31
|
+
"connections.read",
|
|
32
|
+
"connections.write",
|
|
33
|
+
"notifications.read",
|
|
34
|
+
"notifications.write",
|
|
35
|
+
"permissions.read",
|
|
36
|
+
"permissions.write",
|
|
37
|
+
"processors.read",
|
|
38
|
+
"processors.write",
|
|
39
|
+
"turn.credentials",
|
|
40
|
+
"users.me",
|
|
41
|
+
];
|
|
42
|
+
void true;
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import type { NetworkStatusSource } from "./network-status.js";
|
|
2
|
+
import type { AgentsApi } from "../apis/agents-api.js";
|
|
3
|
+
import type { AggregatesApi } from "../apis/aggregates-api.js";
|
|
4
|
+
import type { AlarmsApi } from "../apis/alarms-api.js";
|
|
5
|
+
import type { ChannelsApi } from "../apis/channels-api.js";
|
|
6
|
+
import type { ConnectionsApi } from "../apis/connections-api.js";
|
|
7
|
+
import type { MessagesApi } from "../apis/messages-api.js";
|
|
8
|
+
import type { NotificationsApi } from "../apis/notifications-api.js";
|
|
9
|
+
import type { PermissionsApi } from "../apis/permissions-api.js";
|
|
10
|
+
import type { ProcessorsApi } from "../apis/processors-api.js";
|
|
11
|
+
import type { TurnApi } from "../apis/turn-api.js";
|
|
12
|
+
import type { UsersApi } from "../apis/users-api.js";
|
|
13
|
+
import type { GatewayClient } from "../gateway/gateway-client.js";
|
|
14
|
+
import type { RpcDispatcher } from "../rpc/rpc-dispatcher.js";
|
|
15
|
+
import type { Capability } from "./capabilities.js";
|
|
16
|
+
/**
|
|
17
|
+
* Public structural shape of each concrete subclient — `Pick<Class, keyof Class>`
|
|
18
|
+
* yields just the public members as a plain object type (no nominal/private-member
|
|
19
|
+
* coupling), so a non-`DooverClient` implementation can satisfy it structurally.
|
|
20
|
+
*/
|
|
21
|
+
export type AgentsApiLike = Pick<AgentsApi, keyof AgentsApi>;
|
|
22
|
+
export type AggregatesApiLike = Pick<AggregatesApi, keyof AggregatesApi>;
|
|
23
|
+
export type AlarmsApiLike = Pick<AlarmsApi, keyof AlarmsApi>;
|
|
24
|
+
export type ChannelsApiLike = Pick<ChannelsApi, keyof ChannelsApi>;
|
|
25
|
+
export type ConnectionsApiLike = Pick<ConnectionsApi, keyof ConnectionsApi>;
|
|
26
|
+
export type MessagesApiLike = Pick<MessagesApi, keyof MessagesApi>;
|
|
27
|
+
export type NotificationsApiLike = Pick<NotificationsApi, keyof NotificationsApi>;
|
|
28
|
+
export type PermissionsApiLike = Pick<PermissionsApi, keyof PermissionsApi>;
|
|
29
|
+
export type ProcessorsApiLike = Pick<ProcessorsApi, keyof ProcessorsApi>;
|
|
30
|
+
export type TurnApiLike = Pick<TurnApi, keyof TurnApi>;
|
|
31
|
+
export type UsersApiLike = Pick<UsersApi, keyof UsersApi>;
|
|
32
|
+
export type GatewayClientLike = Pick<GatewayClient, keyof GatewayClient>;
|
|
33
|
+
export type RpcDispatcherLike = Pick<RpcDispatcher, keyof RpcDispatcher>;
|
|
34
|
+
/** Which agents a `DataClient` can serve. */
|
|
35
|
+
export type AgentScope =
|
|
36
|
+
/** Serves every agent (the cloud). Routing treats this as a wildcard. */
|
|
37
|
+
{
|
|
38
|
+
mode: "all";
|
|
39
|
+
}
|
|
40
|
+
/** Serves exactly these agent ids (a local device agent → typically one id). */
|
|
41
|
+
| {
|
|
42
|
+
mode: "list";
|
|
43
|
+
agentIds: string[];
|
|
44
|
+
};
|
|
45
|
+
export type DataClientConnectionState = "connected" | "connecting" | "disconnected" | "degraded" | "error";
|
|
46
|
+
export interface DataClientStatus {
|
|
47
|
+
/** This client's id ("cloud", "local:…", "multiplex", …). */
|
|
48
|
+
clientId: string;
|
|
49
|
+
/** True when the realtime link is up. Mirrors `isConnected()`. */
|
|
50
|
+
connected: boolean;
|
|
51
|
+
state: DataClientConnectionState;
|
|
52
|
+
/** Gateway session, when applicable. */
|
|
53
|
+
session?: {
|
|
54
|
+
id: string;
|
|
55
|
+
} | null;
|
|
56
|
+
/** Last lifecycle event seen ("init" | "open" | "ready" | "close" | "error" | …). */
|
|
57
|
+
lastEvent?: string;
|
|
58
|
+
/** Round-trip latency estimate in ms, if measured. */
|
|
59
|
+
latencyMs?: number | null;
|
|
60
|
+
/** Last error message, if the last event was an error. */
|
|
61
|
+
lastError?: string;
|
|
62
|
+
/** Best-effort agent scope at snapshot time ("unknown" before first resolution). */
|
|
63
|
+
agentScope: AgentScope | "unknown";
|
|
64
|
+
/** When this snapshot was taken (epoch ms). */
|
|
65
|
+
at: number;
|
|
66
|
+
/** Per-member statuses — present only for `MultiplexClient`. */
|
|
67
|
+
members?: Array<{
|
|
68
|
+
sourceId: string;
|
|
69
|
+
label?: string;
|
|
70
|
+
status: DataClientStatus;
|
|
71
|
+
}>;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* The capability-aware data-access contract. `DooverClient`, `LocalAgentClient`
|
|
75
|
+
* and `MultiplexClient` all implement it. Deliberately excludes `DooverClient`'s
|
|
76
|
+
* `auth`/`rest`/`stats`/`viewer` (construction/internals/legacy). May be widened
|
|
77
|
+
* later; the invariant is that `DooverClient` always satisfies it.
|
|
78
|
+
*/
|
|
79
|
+
export interface DataClient {
|
|
80
|
+
/** Optional platform source; React hooks otherwise use browser network status. */
|
|
81
|
+
readonly networkStatus?: NetworkStatusSource;
|
|
82
|
+
readonly agents: AgentsApiLike;
|
|
83
|
+
readonly channels: ChannelsApiLike;
|
|
84
|
+
readonly messages: MessagesApiLike;
|
|
85
|
+
readonly aggregates: AggregatesApiLike;
|
|
86
|
+
readonly alarms: AlarmsApiLike;
|
|
87
|
+
readonly connections: ConnectionsApiLike;
|
|
88
|
+
readonly notifications: NotificationsApiLike;
|
|
89
|
+
readonly permissions: PermissionsApiLike;
|
|
90
|
+
readonly processors: ProcessorsApiLike;
|
|
91
|
+
readonly turn: TurnApiLike;
|
|
92
|
+
readonly users: UsersApiLike;
|
|
93
|
+
readonly gateway: GatewayClientLike;
|
|
94
|
+
readonly rpc: RpcDispatcherLike;
|
|
95
|
+
getCapabilities(): ReadonlySet<Capability>;
|
|
96
|
+
/** Convenience: `getCapabilities().has(cap)`. */
|
|
97
|
+
supports(cap: Capability): boolean;
|
|
98
|
+
/** True when the client's realtime link is up (multiplex: all members with `gateway.subscribe`). */
|
|
99
|
+
isConnected(): boolean;
|
|
100
|
+
getStatus(): DataClientStatus;
|
|
101
|
+
/** Subscribe to status changes; returns an idempotent unsubscribe fn. */
|
|
102
|
+
onStatusChange(listener: (status: DataClientStatus) => void): () => void;
|
|
103
|
+
/** Which agents this client can serve. Cloud → `{ mode: "all" }` with no round-trip. */
|
|
104
|
+
getAgentScope(): Promise<AgentScope>;
|
|
105
|
+
/** Synchronous best-effort snapshot; `"unknown"` until the first resolution. */
|
|
106
|
+
getKnownAgentScope(): AgentScope | "unknown";
|
|
107
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { type NetworkStatusSource } from "./network-status.js";
|
|
2
|
+
import { OrganisationsApi } from "../apis/organisations-api.js";
|
|
3
|
+
import type { DooverAuth } from "../auth/doover-auth.js";
|
|
4
|
+
import { RestClient, type DooverClientConfig } from "../http/rest-client.js";
|
|
5
|
+
import { DooverDataProvider } from "../viewer/doover-data-provider.js";
|
|
6
|
+
import { type Capability } from "./capabilities.js";
|
|
7
|
+
import type { AgentsApiLike, AggregatesApiLike, AlarmsApiLike, ChannelsApiLike, ConnectionsApiLike, DataClient, DataClientStatus, AgentScope, GatewayClientLike, MessagesApiLike, NotificationsApiLike, PermissionsApiLike, ProcessorsApiLike, RpcDispatcherLike, TurnApiLike, UsersApiLike } from "./data-client.js";
|
|
8
|
+
import { DooverStatsCollector, type DooverStatsSnapshot } from "./stats.js";
|
|
9
|
+
export declare class DooverClient implements DataClient {
|
|
10
|
+
readonly networkStatus: NetworkStatusSource;
|
|
11
|
+
readonly auth: DooverAuth;
|
|
12
|
+
readonly rest: RestClient;
|
|
13
|
+
readonly viewer: DooverDataProvider;
|
|
14
|
+
readonly users: UsersApiLike;
|
|
15
|
+
readonly channels: ChannelsApiLike;
|
|
16
|
+
readonly messages: MessagesApiLike;
|
|
17
|
+
readonly aggregates: AggregatesApiLike;
|
|
18
|
+
readonly alarms: AlarmsApiLike;
|
|
19
|
+
readonly connections: ConnectionsApiLike;
|
|
20
|
+
readonly notifications: NotificationsApiLike;
|
|
21
|
+
readonly organisations: OrganisationsApi;
|
|
22
|
+
readonly permissions: PermissionsApiLike;
|
|
23
|
+
readonly processors: ProcessorsApiLike;
|
|
24
|
+
readonly turn: TurnApiLike;
|
|
25
|
+
readonly agents: AgentsApiLike;
|
|
26
|
+
readonly gateway: GatewayClientLike;
|
|
27
|
+
readonly rpc: RpcDispatcherLike;
|
|
28
|
+
readonly stats: DooverStatsCollector;
|
|
29
|
+
private readonly identity;
|
|
30
|
+
private readonly statusTracker;
|
|
31
|
+
/** Underlying concrete gateway (the public `gateway` is the same object,
|
|
32
|
+
* typed as the structural `GatewayClientLike`). */
|
|
33
|
+
private readonly gatewayImpl;
|
|
34
|
+
/** Underlying concrete RPC dispatcher (the public `rpc` is the same object,
|
|
35
|
+
* typed as the structural `RpcDispatcherLike`). */
|
|
36
|
+
private readonly rpcImpl;
|
|
37
|
+
constructor(config: DooverClientConfig);
|
|
38
|
+
enableStats(): void;
|
|
39
|
+
disableStats(): void;
|
|
40
|
+
getStats(): DooverStatsSnapshot;
|
|
41
|
+
getCapabilities(): ReadonlySet<Capability>;
|
|
42
|
+
supports(cap: Capability): boolean;
|
|
43
|
+
getAgentScope(): Promise<AgentScope>;
|
|
44
|
+
getKnownAgentScope(): AgentScope | "unknown";
|
|
45
|
+
isConnected(): boolean;
|
|
46
|
+
getStatus(): DataClientStatus;
|
|
47
|
+
onStatusChange(listener: (status: DataClientStatus) => void): () => void;
|
|
48
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { browserNetworkStatus } from "./network-status.js";
|
|
2
|
+
import { AgentsApi } from "../apis/agents-api.js";
|
|
3
|
+
import { AggregatesApi } from "../apis/aggregates-api.js";
|
|
4
|
+
import { AlarmsApi } from "../apis/alarms-api.js";
|
|
5
|
+
import { ChannelsApi } from "../apis/channels-api.js";
|
|
6
|
+
import { ConnectionsApi } from "../apis/connections-api.js";
|
|
7
|
+
import { MessagesApi } from "../apis/messages-api.js";
|
|
8
|
+
import { NotificationsApi } from "../apis/notifications-api.js";
|
|
9
|
+
import { OrganisationsApi } from "../apis/organisations-api.js";
|
|
10
|
+
import { PermissionsApi } from "../apis/permissions-api.js";
|
|
11
|
+
import { ProcessorsApi } from "../apis/processors-api.js";
|
|
12
|
+
import { TurnApi } from "../apis/turn-api.js";
|
|
13
|
+
import { UsersApi } from "../apis/users-api.js";
|
|
14
|
+
import { buildAuth } from "../auth/build-auth.js";
|
|
15
|
+
import { GatewayClient } from "../gateway/gateway-client.js";
|
|
16
|
+
import { RestClient } from "../http/rest-client.js";
|
|
17
|
+
import { RpcDispatcher } from "../rpc/rpc-dispatcher.js";
|
|
18
|
+
import { DooverDataProvider } from "../viewer/doover-data-provider.js";
|
|
19
|
+
import { ALL_CAPABILITIES } from "./capabilities.js";
|
|
20
|
+
import { ProvenanceStamper, wrapSubclient } from "./provenance.js";
|
|
21
|
+
import { ClientStatusTracker } from "./status-tracker.js";
|
|
22
|
+
import { DooverStatsCollector } from "./stats.js";
|
|
23
|
+
const ALL_CAPS_SET = new Set(ALL_CAPABILITIES);
|
|
24
|
+
export class DooverClient {
|
|
25
|
+
constructor(config) {
|
|
26
|
+
this.networkStatus = config.networkStatus ?? browserNetworkStatus;
|
|
27
|
+
this.auth = buildAuth({
|
|
28
|
+
auth: config.auth,
|
|
29
|
+
profile: config.profile,
|
|
30
|
+
configManager: config.configManager,
|
|
31
|
+
token: config.token,
|
|
32
|
+
tokenExpires: config.tokenExpires,
|
|
33
|
+
refreshToken: config.refreshToken,
|
|
34
|
+
refreshTokenId: config.refreshTokenId,
|
|
35
|
+
authServerUrl: config.authServerUrl,
|
|
36
|
+
authServerClientId: config.authServerClientId,
|
|
37
|
+
fetchImpl: config.fetchImpl,
|
|
38
|
+
});
|
|
39
|
+
this.identity = {
|
|
40
|
+
id: config.sourceId ?? "cloud",
|
|
41
|
+
kind: "cloud",
|
|
42
|
+
...(config.sourceLabel ? { label: config.sourceLabel } : {}),
|
|
43
|
+
meta: {
|
|
44
|
+
dataRestUrl: config.dataRestUrl,
|
|
45
|
+
controlApiUrl: config.controlApiUrl,
|
|
46
|
+
...(config.organisationId ? { organisationId: config.organisationId } : {}),
|
|
47
|
+
},
|
|
48
|
+
};
|
|
49
|
+
const stamper = new ProvenanceStamper(this.identity);
|
|
50
|
+
this.rest = new RestClient(config, this.auth);
|
|
51
|
+
this.gatewayImpl = new GatewayClient(config, this.auth);
|
|
52
|
+
this.gatewayImpl.setProvenanceHook((value, ctx) => stamper.stampGatewayEvent(value, ctx));
|
|
53
|
+
this.gateway = this.gatewayImpl;
|
|
54
|
+
this.viewer = new DooverDataProvider({
|
|
55
|
+
rest: this.rest,
|
|
56
|
+
gateway: this.gatewayImpl,
|
|
57
|
+
controlApiUrl: config.controlApiUrl,
|
|
58
|
+
});
|
|
59
|
+
this.users = wrapSubclient(new UsersApi(this.rest, config.controlApiUrl), "users", stamper);
|
|
60
|
+
this.channels = wrapSubclient(new ChannelsApi(this.rest), "channels", stamper);
|
|
61
|
+
this.messages = wrapSubclient(new MessagesApi(this.rest), "messages", stamper);
|
|
62
|
+
this.aggregates = wrapSubclient(new AggregatesApi(this.rest), "aggregates", stamper);
|
|
63
|
+
this.alarms = wrapSubclient(new AlarmsApi(this.rest), "alarms", stamper);
|
|
64
|
+
this.connections = wrapSubclient(new ConnectionsApi(this.rest), "connections", stamper);
|
|
65
|
+
this.notifications = wrapSubclient(new NotificationsApi(this.rest), "notifications", stamper);
|
|
66
|
+
this.organisations = wrapSubclient(new OrganisationsApi(this.rest, config.controlApiUrl), "organisations", stamper);
|
|
67
|
+
this.permissions = wrapSubclient(new PermissionsApi(this.rest), "permissions", stamper);
|
|
68
|
+
this.processors = wrapSubclient(new ProcessorsApi(this.rest), "processors", stamper);
|
|
69
|
+
this.turn = wrapSubclient(new TurnApi(this.rest), "turn", stamper);
|
|
70
|
+
this.agents = wrapSubclient(new AgentsApi(this.rest, config.controlApiUrl), "agents", stamper);
|
|
71
|
+
// RpcDispatcher needs the concrete MessagesApi (it calls postMessage internally);
|
|
72
|
+
// give it an *unwrapped* one so stamping happens once at the public boundary.
|
|
73
|
+
this.rpcImpl = new RpcDispatcher(this.gatewayImpl, new MessagesApi(this.rest));
|
|
74
|
+
this.rpc = this.rpcImpl;
|
|
75
|
+
this.stats = new DooverStatsCollector();
|
|
76
|
+
this.rest.setStats(this.stats);
|
|
77
|
+
this.gatewayImpl.setStats(this.stats);
|
|
78
|
+
this.rpcImpl.setStats(this.stats);
|
|
79
|
+
this.statusTracker = new ClientStatusTracker(this.identity.id, this.gateway, () => this.getKnownAgentScope());
|
|
80
|
+
}
|
|
81
|
+
enableStats() { this.stats.setEnabled(true); }
|
|
82
|
+
disableStats() { this.stats.setEnabled(false); }
|
|
83
|
+
getStats() { return this.stats.snapshot(); }
|
|
84
|
+
// --- DataClient: capabilities ---
|
|
85
|
+
getCapabilities() { return ALL_CAPS_SET; }
|
|
86
|
+
supports(cap) { return ALL_CAPS_SET.has(cap); }
|
|
87
|
+
// --- DataClient: agent scope (cloud serves every agent) ---
|
|
88
|
+
getAgentScope() { return Promise.resolve({ mode: "all" }); }
|
|
89
|
+
getKnownAgentScope() { return { mode: "all" }; }
|
|
90
|
+
// --- DataClient: status ---
|
|
91
|
+
isConnected() { return this.gateway.isConnected(); }
|
|
92
|
+
getStatus() { return this.statusTracker.getStatus(); }
|
|
93
|
+
onStatusChange(listener) {
|
|
94
|
+
return this.statusTracker.onChange(listener);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { Capability } from "./capabilities.js";
|
|
2
|
+
import { DooverApiError } from "../http/errors.js";
|
|
3
|
+
/**
|
|
4
|
+
* Thrown when a `DataClient` method is called whose backing capability the
|
|
5
|
+
* client does not advertise. Extends `DooverApiError` so existing
|
|
6
|
+
* `instanceof DooverApiError` error handling catches it; the HTTP-ish fields
|
|
7
|
+
* are placeholders since no request was made.
|
|
8
|
+
*/
|
|
9
|
+
export declare class UnsupportedCapabilityError extends DooverApiError {
|
|
10
|
+
readonly capability: Capability;
|
|
11
|
+
readonly clientId?: string;
|
|
12
|
+
constructor(capability: Capability, clientId?: string);
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Thrown by `MultiplexClient` when a write cannot be routed to a single
|
|
16
|
+
* member — more than one enabled member owns the targeted agent and has the
|
|
17
|
+
* write capability, and the call was not `sources`-scoped to one of them.
|
|
18
|
+
*/
|
|
19
|
+
export declare class AmbiguousWriteError extends DooverApiError {
|
|
20
|
+
readonly capability: Capability;
|
|
21
|
+
readonly candidateSourceIds: string[];
|
|
22
|
+
constructor(capability: Capability, candidateSourceIds: string[]);
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Thrown by offline-aware clients when a network-only operation is attempted
|
|
26
|
+
* while offline, or when an offline read has no usable cached value.
|
|
27
|
+
*/
|
|
28
|
+
export declare class DooverOfflineError extends DooverApiError {
|
|
29
|
+
readonly operation: string;
|
|
30
|
+
readonly cacheKey?: string;
|
|
31
|
+
constructor(operation: string, message?: string, cacheKey?: string);
|
|
32
|
+
}
|