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,72 @@
|
|
|
1
|
+
import type { RestClient } from "../http/rest-client.js";
|
|
2
|
+
export type RefineRecord = Record<string, unknown> & {
|
|
3
|
+
id?: string | number;
|
|
4
|
+
};
|
|
5
|
+
export type RefineMeta = Record<string, unknown> | undefined;
|
|
6
|
+
export interface RefinePagination {
|
|
7
|
+
currentPage?: number;
|
|
8
|
+
pageSize?: number;
|
|
9
|
+
}
|
|
10
|
+
export interface RefineSorter {
|
|
11
|
+
field: string;
|
|
12
|
+
order?: "asc" | "desc";
|
|
13
|
+
}
|
|
14
|
+
export interface RefineCrudFilter {
|
|
15
|
+
field: string;
|
|
16
|
+
operator: string;
|
|
17
|
+
value: unknown;
|
|
18
|
+
}
|
|
19
|
+
export interface RefineGetListParams {
|
|
20
|
+
resource: string;
|
|
21
|
+
pagination?: RefinePagination;
|
|
22
|
+
sorters?: RefineSorter[];
|
|
23
|
+
filters?: RefineCrudFilter[];
|
|
24
|
+
meta?: RefineMeta;
|
|
25
|
+
}
|
|
26
|
+
export interface RefineOneParams {
|
|
27
|
+
resource: string;
|
|
28
|
+
id: string | number;
|
|
29
|
+
meta?: RefineMeta;
|
|
30
|
+
}
|
|
31
|
+
export interface RefineMutationParams {
|
|
32
|
+
resource: string;
|
|
33
|
+
id?: string | number;
|
|
34
|
+
variables?: unknown;
|
|
35
|
+
meta?: RefineMeta;
|
|
36
|
+
}
|
|
37
|
+
export interface RefineCustomParams {
|
|
38
|
+
url: string;
|
|
39
|
+
method: string;
|
|
40
|
+
headers?: Record<string, string>;
|
|
41
|
+
payload?: unknown;
|
|
42
|
+
meta?: RefineMeta;
|
|
43
|
+
}
|
|
44
|
+
export interface RefineDataProviderLike {
|
|
45
|
+
getOne: (params: RefineOneParams) => Promise<{
|
|
46
|
+
data: unknown;
|
|
47
|
+
}>;
|
|
48
|
+
getList: <TData extends RefineRecord = RefineRecord>(params: RefineGetListParams) => Promise<{
|
|
49
|
+
data: TData[];
|
|
50
|
+
total: number;
|
|
51
|
+
}>;
|
|
52
|
+
create: (params: RefineMutationParams) => Promise<{
|
|
53
|
+
data: unknown;
|
|
54
|
+
}>;
|
|
55
|
+
update: (params: RefineMutationParams & {
|
|
56
|
+
id: string | number;
|
|
57
|
+
}) => Promise<{
|
|
58
|
+
data: unknown;
|
|
59
|
+
}>;
|
|
60
|
+
deleteOne: (params: RefineOneParams) => Promise<{
|
|
61
|
+
data: unknown;
|
|
62
|
+
}>;
|
|
63
|
+
custom: (params: RefineCustomParams) => Promise<{
|
|
64
|
+
data: unknown;
|
|
65
|
+
}>;
|
|
66
|
+
getApiUrl: () => string;
|
|
67
|
+
}
|
|
68
|
+
export interface CreateRefineDataProviderOptions {
|
|
69
|
+
baseUrl?: string;
|
|
70
|
+
}
|
|
71
|
+
export declare function createRefineDataProvider(rest: RestClient, options?: CreateRefineDataProviderOptions): RefineDataProviderLike;
|
|
72
|
+
export declare function getApiPath(resource: string, meta?: RefineMeta): string;
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
export function createRefineDataProvider(rest, options = {}) {
|
|
2
|
+
const baseUrl = options.baseUrl ?? rest.config.controlApiUrl;
|
|
3
|
+
return {
|
|
4
|
+
getOne: async ({ resource, id, meta }) => {
|
|
5
|
+
const data = await rest.request({
|
|
6
|
+
path: `/${getApiPath(resource, meta)}/${id}/`,
|
|
7
|
+
headers: getMetaHeaders(meta),
|
|
8
|
+
baseUrl,
|
|
9
|
+
});
|
|
10
|
+
return { data };
|
|
11
|
+
},
|
|
12
|
+
getList: async ({ resource, pagination, sorters, filters, meta, }) => {
|
|
13
|
+
const data = await rest.request({
|
|
14
|
+
path: `/${getApiPath(resource, meta)}/`,
|
|
15
|
+
query: buildListQuery({ pagination, sorters, filters, meta }),
|
|
16
|
+
headers: getMetaHeaders(meta),
|
|
17
|
+
baseUrl,
|
|
18
|
+
});
|
|
19
|
+
return {
|
|
20
|
+
data: data.results,
|
|
21
|
+
total: data.count,
|
|
22
|
+
};
|
|
23
|
+
},
|
|
24
|
+
create: async ({ resource, variables, meta }) => {
|
|
25
|
+
const mergedMeta = isRecord(variables) ? { ...meta, ...variables } : meta;
|
|
26
|
+
const data = await rest.request({
|
|
27
|
+
path: `/${getApiPath(resource, mergedMeta)}/`,
|
|
28
|
+
method: "POST",
|
|
29
|
+
body: prepareVariables(variables, meta),
|
|
30
|
+
headers: getMetaHeaders(meta),
|
|
31
|
+
baseUrl,
|
|
32
|
+
});
|
|
33
|
+
return { data };
|
|
34
|
+
},
|
|
35
|
+
update: async ({ resource, id, variables, meta }) => {
|
|
36
|
+
const data = await rest.request({
|
|
37
|
+
path: `/${getApiPath(resource, meta)}/${id}/`,
|
|
38
|
+
method: "PATCH",
|
|
39
|
+
body: prepareVariables(variables, meta),
|
|
40
|
+
headers: getMetaHeaders(meta),
|
|
41
|
+
baseUrl,
|
|
42
|
+
});
|
|
43
|
+
return { data };
|
|
44
|
+
},
|
|
45
|
+
deleteOne: async ({ resource, id, meta }) => {
|
|
46
|
+
const data = await rest.request({
|
|
47
|
+
path: `/${getApiPath(resource, meta)}/${id}/`,
|
|
48
|
+
method: "DELETE",
|
|
49
|
+
headers: getMetaHeaders(meta),
|
|
50
|
+
baseUrl,
|
|
51
|
+
});
|
|
52
|
+
return { data: data ?? null };
|
|
53
|
+
},
|
|
54
|
+
custom: async ({ url, method, headers, payload, meta }) => {
|
|
55
|
+
const { path, query } = splitCustomUrl(url);
|
|
56
|
+
const data = await rest.request({
|
|
57
|
+
path,
|
|
58
|
+
method,
|
|
59
|
+
headers: { ...headers, ...getMetaHeaders(meta) },
|
|
60
|
+
body: payload == null ? undefined : payload,
|
|
61
|
+
query,
|
|
62
|
+
baseUrl,
|
|
63
|
+
});
|
|
64
|
+
return { data };
|
|
65
|
+
},
|
|
66
|
+
getApiUrl: () => baseUrl,
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
function getMetaHeaders(meta) {
|
|
70
|
+
if (!meta?.organisation)
|
|
71
|
+
return undefined;
|
|
72
|
+
return { "X-Doover-Organisation": String(idValue(meta.organisation)) };
|
|
73
|
+
}
|
|
74
|
+
export function getApiPath(resource, meta) {
|
|
75
|
+
const apiPath = meta?.api_path;
|
|
76
|
+
if (apiPath !== undefined) {
|
|
77
|
+
const paths = typeof apiPath === "string" ? [apiPath] : apiPath;
|
|
78
|
+
if (Array.isArray(paths)) {
|
|
79
|
+
for (const path of paths) {
|
|
80
|
+
if (typeof path !== "string")
|
|
81
|
+
continue;
|
|
82
|
+
try {
|
|
83
|
+
return fillApiPath(path, meta);
|
|
84
|
+
}
|
|
85
|
+
catch (err) {
|
|
86
|
+
if (paths.length === 1)
|
|
87
|
+
throw err;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return resource;
|
|
93
|
+
}
|
|
94
|
+
function fillApiPath(path, meta) {
|
|
95
|
+
let apiPath = path;
|
|
96
|
+
const matches = [...apiPath.matchAll(/:([^/]+)/g)].map((m) => m[1]);
|
|
97
|
+
for (const match of matches) {
|
|
98
|
+
const value = lookupPathParam(match, meta);
|
|
99
|
+
if (value === undefined) {
|
|
100
|
+
throw new Error(`Missing value for ${match} in meta`);
|
|
101
|
+
}
|
|
102
|
+
apiPath = apiPath.replace(`:${match}`, String(value));
|
|
103
|
+
}
|
|
104
|
+
return apiPath;
|
|
105
|
+
}
|
|
106
|
+
function lookupPathParam(match, meta) {
|
|
107
|
+
if (!meta)
|
|
108
|
+
return undefined;
|
|
109
|
+
if (match in meta && meta[match] !== undefined)
|
|
110
|
+
return idValue(meta[match]);
|
|
111
|
+
const withoutId = match.replace(/id$/i, "");
|
|
112
|
+
if (withoutId in meta && meta[withoutId] !== undefined) {
|
|
113
|
+
return idValue(meta[withoutId]);
|
|
114
|
+
}
|
|
115
|
+
return undefined;
|
|
116
|
+
}
|
|
117
|
+
function idValue(value) {
|
|
118
|
+
return isRecord(value) && "id" in value ? value.id : value;
|
|
119
|
+
}
|
|
120
|
+
function buildListQuery({ pagination, sorters, filters, meta, }) {
|
|
121
|
+
const query = {};
|
|
122
|
+
if (pagination) {
|
|
123
|
+
query.page = pagination.currentPage ?? 1;
|
|
124
|
+
if (pagination.pageSize)
|
|
125
|
+
query.per_page = pagination.pageSize;
|
|
126
|
+
}
|
|
127
|
+
if (sorters && sorters.length > 0) {
|
|
128
|
+
query.ordering = `${sorters[0].order === "desc" ? "-" : ""}${sorters[0].field}`;
|
|
129
|
+
}
|
|
130
|
+
let hasArchivedFilter = false;
|
|
131
|
+
for (const filter of filters ?? []) {
|
|
132
|
+
if (!filter.field || !filter.operator)
|
|
133
|
+
continue;
|
|
134
|
+
if (filter.operator === "contains" && filter.field === "search") {
|
|
135
|
+
query.search = String(filter.value ?? "");
|
|
136
|
+
continue;
|
|
137
|
+
}
|
|
138
|
+
if (filter.field === "archived" || filter.field === "device_archived") {
|
|
139
|
+
hasArchivedFilter = hasArchivedFilter || filter.field === "archived";
|
|
140
|
+
if (filter.operator === "eq" || filter.operator === "in") {
|
|
141
|
+
query[filter.field] =
|
|
142
|
+
filter.value === "__all__" ? "" : String(filter.value ?? "");
|
|
143
|
+
}
|
|
144
|
+
continue;
|
|
145
|
+
}
|
|
146
|
+
if (filter.operator === "contains") {
|
|
147
|
+
query[`${filter.field}__icontains`] = String(filter.value ?? "");
|
|
148
|
+
}
|
|
149
|
+
else if (filter.operator === "containss") {
|
|
150
|
+
query[`${filter.field}__contains`] = String(filter.value ?? "");
|
|
151
|
+
}
|
|
152
|
+
else if (filter.operator === "eq" || filter.operator === "in") {
|
|
153
|
+
query[filter.field] = String(filter.value ?? "");
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
if (meta?.canArchive === true && !hasArchivedFilter) {
|
|
157
|
+
query.archived = "false";
|
|
158
|
+
}
|
|
159
|
+
return query;
|
|
160
|
+
}
|
|
161
|
+
function prepareVariables(variables, meta) {
|
|
162
|
+
if (!isRecord(variables))
|
|
163
|
+
return variables;
|
|
164
|
+
const next = { ...variables };
|
|
165
|
+
const renameFields = isRecord(meta?.renameFields) ? meta.renameFields : null;
|
|
166
|
+
if (renameFields) {
|
|
167
|
+
for (const [from, to] of Object.entries(renameFields)) {
|
|
168
|
+
if (typeof to !== "string")
|
|
169
|
+
continue;
|
|
170
|
+
const value = next[from];
|
|
171
|
+
const mapped = Array.isArray(value)
|
|
172
|
+
? value.map((item) => idValue(item))
|
|
173
|
+
: idValue(value);
|
|
174
|
+
next[from] = mapped;
|
|
175
|
+
next[to] = mapped;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
if (Object.values(next).some(isFileLike)) {
|
|
179
|
+
const formData = new FormData();
|
|
180
|
+
for (const [key, value] of Object.entries(next)) {
|
|
181
|
+
if (value == null)
|
|
182
|
+
continue;
|
|
183
|
+
if (isFileLike(value)) {
|
|
184
|
+
formData.append(key, value);
|
|
185
|
+
}
|
|
186
|
+
else if (typeof value === "object") {
|
|
187
|
+
formData.append(key, JSON.stringify(value));
|
|
188
|
+
}
|
|
189
|
+
else {
|
|
190
|
+
formData.append(key, String(value));
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
return formData;
|
|
194
|
+
}
|
|
195
|
+
return next;
|
|
196
|
+
}
|
|
197
|
+
function splitCustomUrl(url) {
|
|
198
|
+
const [rawPath, rawQuery] = url.replace(/^\//, "").split("?", 2);
|
|
199
|
+
const path = `/${rawPath.replace(/\/?$/, "/")}`;
|
|
200
|
+
if (!rawQuery)
|
|
201
|
+
return { path, query: undefined };
|
|
202
|
+
const params = new URLSearchParams(rawQuery);
|
|
203
|
+
const query = {};
|
|
204
|
+
for (const key of new Set(params.keys())) {
|
|
205
|
+
const values = params.getAll(key);
|
|
206
|
+
query[key] = values.length > 1 ? values : values[0] ?? "";
|
|
207
|
+
}
|
|
208
|
+
return { path, query };
|
|
209
|
+
}
|
|
210
|
+
function isRecord(value) {
|
|
211
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
212
|
+
}
|
|
213
|
+
function isFileLike(value) {
|
|
214
|
+
return typeof File !== "undefined" && value instanceof File;
|
|
215
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { RpcRequest, RpcStatus } from "../types/common.js";
|
|
2
|
+
export declare class DooverRpcError extends Error {
|
|
3
|
+
readonly status: RpcStatus<unknown> & {
|
|
4
|
+
code: "error";
|
|
5
|
+
};
|
|
6
|
+
readonly request: RpcRequest;
|
|
7
|
+
constructor(status: RpcStatus<unknown> & {
|
|
8
|
+
code: "error";
|
|
9
|
+
}, request: RpcRequest);
|
|
10
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export class DooverRpcError extends Error {
|
|
2
|
+
constructor(status, request) {
|
|
3
|
+
const text = typeof status.message === "string"
|
|
4
|
+
? status.message
|
|
5
|
+
: (() => {
|
|
6
|
+
try {
|
|
7
|
+
return JSON.stringify(status.message);
|
|
8
|
+
}
|
|
9
|
+
catch {
|
|
10
|
+
return "Unknown RPC error";
|
|
11
|
+
}
|
|
12
|
+
})();
|
|
13
|
+
super(text);
|
|
14
|
+
this.name = "DooverRpcError";
|
|
15
|
+
this.status = status;
|
|
16
|
+
this.request = request;
|
|
17
|
+
Object.setPrototypeOf(this, DooverRpcError.prototype);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { MessagesApi } from "../apis/messages-api.js";
|
|
2
|
+
import type { DooverStatsCollector } from "../client/stats.js";
|
|
3
|
+
import type { GatewayClient } from "../gateway/gateway-client.js";
|
|
4
|
+
import type { RpcRequest, RpcStatus } from "../types/common.js";
|
|
5
|
+
export interface SendRpcOptions<TPending = undefined> {
|
|
6
|
+
onStatus?: (status: RpcStatus<TPending>) => void;
|
|
7
|
+
signal?: AbortSignal;
|
|
8
|
+
/**
|
|
9
|
+
* How long to wait to hear from the device at all. A healthy device answers
|
|
10
|
+
* within seconds however long the work then takes, so keep this short and
|
|
11
|
+
* use `pendingTimeoutMs` for the work itself.
|
|
12
|
+
*/
|
|
13
|
+
timeoutMs?: number;
|
|
14
|
+
/**
|
|
15
|
+
* How long the command may then stay in flight once the device has answered
|
|
16
|
+
* it — acknowledged it, or reported progress. Re-armed on every subsequent
|
|
17
|
+
* status update, so a device that keeps reporting keeps its command alive,
|
|
18
|
+
* while one that answers and then dies still fails. Without this, a handler
|
|
19
|
+
* that legitimately runs longer than `timeoutMs` is killed mid-flight.
|
|
20
|
+
*/
|
|
21
|
+
pendingTimeoutMs?: number;
|
|
22
|
+
}
|
|
23
|
+
interface ChannelIdentifierLike {
|
|
24
|
+
agentId: string;
|
|
25
|
+
channelName: string;
|
|
26
|
+
}
|
|
27
|
+
export declare class RpcDispatcher {
|
|
28
|
+
private readonly gateway;
|
|
29
|
+
private readonly messages;
|
|
30
|
+
private pending;
|
|
31
|
+
private channelRefs;
|
|
32
|
+
private stats;
|
|
33
|
+
constructor(gateway: GatewayClient, messages: MessagesApi);
|
|
34
|
+
setStats(collector: DooverStatsCollector | null): void;
|
|
35
|
+
send<TReq = object, TRes = object, TPending = undefined>(channel: ChannelIdentifierLike, request: RpcRequest<TReq>, options?: SendRpcOptions<TPending>): Promise<TRes>;
|
|
36
|
+
private acquireChannel;
|
|
37
|
+
private releaseChannel;
|
|
38
|
+
private route;
|
|
39
|
+
private settle;
|
|
40
|
+
}
|
|
41
|
+
export {};
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import { DooverRpcError } from "./errors.js";
|
|
2
|
+
/** Whether the device has answered this command, rather than only received it. */
|
|
3
|
+
function hasDeviceAnswered(status) {
|
|
4
|
+
return status.code === "acknowledged" || status.code === "pending";
|
|
5
|
+
}
|
|
6
|
+
function isRpcMessageData(data) {
|
|
7
|
+
return (typeof data === "object" &&
|
|
8
|
+
data !== null &&
|
|
9
|
+
"status" in data &&
|
|
10
|
+
"method" in data &&
|
|
11
|
+
"request" in data);
|
|
12
|
+
}
|
|
13
|
+
export class RpcDispatcher {
|
|
14
|
+
constructor(gateway, messages) {
|
|
15
|
+
this.gateway = gateway;
|
|
16
|
+
this.messages = messages;
|
|
17
|
+
this.pending = new Map();
|
|
18
|
+
this.channelRefs = new Map();
|
|
19
|
+
this.stats = null;
|
|
20
|
+
}
|
|
21
|
+
setStats(collector) {
|
|
22
|
+
this.stats = collector;
|
|
23
|
+
}
|
|
24
|
+
send(channel, request, options) {
|
|
25
|
+
return new Promise((resolve, reject) => {
|
|
26
|
+
const channelRef = {
|
|
27
|
+
agent_id: channel.agentId,
|
|
28
|
+
name: channel.channelName,
|
|
29
|
+
};
|
|
30
|
+
const channelKey = `${channelRef.agent_id}/${channelRef.name}`;
|
|
31
|
+
this.acquireChannel(channelKey, channelRef);
|
|
32
|
+
const startedAt = this.stats?.recordRpcStart() ?? null;
|
|
33
|
+
this.messages
|
|
34
|
+
.postMessage(channel.agentId, channel.channelName, {
|
|
35
|
+
data: {
|
|
36
|
+
type: "rpc",
|
|
37
|
+
...request,
|
|
38
|
+
},
|
|
39
|
+
})
|
|
40
|
+
.then((message) => {
|
|
41
|
+
const pending = {
|
|
42
|
+
resolve: resolve,
|
|
43
|
+
reject,
|
|
44
|
+
onStatus: options?.onStatus,
|
|
45
|
+
request: request,
|
|
46
|
+
channelKey,
|
|
47
|
+
channel: channelRef,
|
|
48
|
+
startedAt,
|
|
49
|
+
pendingTimeoutMs: options?.pendingTimeoutMs,
|
|
50
|
+
};
|
|
51
|
+
if (options?.signal) {
|
|
52
|
+
const onAbort = () => this.settle(message.id, "abort", undefined, options.signal?.reason);
|
|
53
|
+
if (options.signal.aborted) {
|
|
54
|
+
this.releaseChannel(channelKey);
|
|
55
|
+
this.stats?.recordRpcEnd(startedAt, "abort");
|
|
56
|
+
reject(options.signal.reason ?? new Error("Aborted"));
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
options.signal.addEventListener("abort", onAbort);
|
|
60
|
+
pending.signal = options.signal;
|
|
61
|
+
pending.abortListener = onAbort;
|
|
62
|
+
}
|
|
63
|
+
if (options?.timeoutMs !== undefined) {
|
|
64
|
+
pending.timer = setTimeout(() => {
|
|
65
|
+
this.settle(message.id, "timeout", undefined, new Error("RPC timed out"));
|
|
66
|
+
}, options.timeoutMs);
|
|
67
|
+
}
|
|
68
|
+
this.pending.set(message.id, pending);
|
|
69
|
+
})
|
|
70
|
+
.catch((err) => {
|
|
71
|
+
// postMessage failed before we registered pending — release and reject.
|
|
72
|
+
this.releaseChannel(channelKey);
|
|
73
|
+
this.stats?.recordRpcEnd(startedAt, "error");
|
|
74
|
+
reject(err);
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
acquireChannel(channelKey, channelRef) {
|
|
79
|
+
const existing = this.channelRefs.get(channelKey);
|
|
80
|
+
if (existing) {
|
|
81
|
+
existing.refCount += 1;
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
const handlers = {
|
|
85
|
+
onMessageUpdate: (msg, requestData) => this.route(msg, requestData),
|
|
86
|
+
};
|
|
87
|
+
const unsubscribe = this.gateway.subscribeToChannel(channelRef, handlers);
|
|
88
|
+
this.channelRefs.set(channelKey, { unsubscribe, refCount: 1 });
|
|
89
|
+
}
|
|
90
|
+
releaseChannel(channelKey) {
|
|
91
|
+
const entry = this.channelRefs.get(channelKey);
|
|
92
|
+
if (!entry)
|
|
93
|
+
return;
|
|
94
|
+
entry.refCount -= 1;
|
|
95
|
+
if (entry.refCount <= 0) {
|
|
96
|
+
entry.unsubscribe();
|
|
97
|
+
this.channelRefs.delete(channelKey);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
route(msg, _requestData) {
|
|
101
|
+
const pending = this.pending.get(msg.id);
|
|
102
|
+
if (!pending)
|
|
103
|
+
return;
|
|
104
|
+
if (!isRpcMessageData(msg.data))
|
|
105
|
+
return;
|
|
106
|
+
const status = msg.data.status;
|
|
107
|
+
pending.onStatus?.(status);
|
|
108
|
+
if (status.code === "success") {
|
|
109
|
+
this.settle(msg.id, "success", msg.data.response);
|
|
110
|
+
}
|
|
111
|
+
else if (status.code === "error") {
|
|
112
|
+
this.settle(msg.id, "error", undefined, new DooverRpcError(status, pending.request));
|
|
113
|
+
}
|
|
114
|
+
else if (hasDeviceAnswered(status) && pending.pendingTimeoutMs !== undefined) {
|
|
115
|
+
// The device is alive and working: swap the "no response" deadline for
|
|
116
|
+
// the pending budget, and re-arm it on every report that follows.
|
|
117
|
+
if (pending.timer)
|
|
118
|
+
clearTimeout(pending.timer);
|
|
119
|
+
pending.timer = setTimeout(() => {
|
|
120
|
+
this.settle(msg.id, "timeout", undefined, new Error("Device stopped reporting progress"));
|
|
121
|
+
}, pending.pendingTimeoutMs);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
settle(messageId, outcome, response, rejection) {
|
|
125
|
+
const pending = this.pending.get(messageId);
|
|
126
|
+
if (!pending)
|
|
127
|
+
return;
|
|
128
|
+
this.pending.delete(messageId);
|
|
129
|
+
if (pending.timer)
|
|
130
|
+
clearTimeout(pending.timer);
|
|
131
|
+
if (pending.signal && pending.abortListener) {
|
|
132
|
+
pending.signal.removeEventListener("abort", pending.abortListener);
|
|
133
|
+
}
|
|
134
|
+
this.releaseChannel(pending.channelKey);
|
|
135
|
+
this.stats?.recordRpcEnd(pending.startedAt, outcome);
|
|
136
|
+
if (outcome === "success")
|
|
137
|
+
pending.resolve(response);
|
|
138
|
+
else
|
|
139
|
+
pending.reject(rejection);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Audit event types — mirror of the records doover-control writes to the
|
|
3
|
+
* `dv-audit` channel (see ``doover-control/doover_control/events/audit.py``
|
|
4
|
+
* for the source of truth).
|
|
5
|
+
*
|
|
6
|
+
* Each record is read back via the standard channel-messages APIs: it lands
|
|
7
|
+
* inside a ``MessageStructure<AuditEvent>`` envelope (with ``id``, ``timestamp``,
|
|
8
|
+
* ``channel``, etc.), and the record itself is on ``message.data``.
|
|
9
|
+
*/
|
|
10
|
+
/** Channel name on which audit records live in doover-data. */
|
|
11
|
+
export declare const DV_AUDIT_CHANNEL = "dv-audit";
|
|
12
|
+
/** The role this party plays in the record. */
|
|
13
|
+
export type AuditEntityType = "device" | "user" | "organisation" | "Tunnel" | "ApplicationInstallation" | "SolutionInstallation" | "ApplicationDeployment" | "ObjectGroup" | "PendingUser" | "User" | "fusionauth" | "system";
|
|
14
|
+
export interface AuditEntity {
|
|
15
|
+
type: AuditEntityType;
|
|
16
|
+
/** Stringified id (User pk, Device pk, FA UUID, etc.). May be absent for `system`. */
|
|
17
|
+
id?: string;
|
|
18
|
+
/** Display name. May be an email for users / pending invites. */
|
|
19
|
+
name?: string;
|
|
20
|
+
}
|
|
21
|
+
export interface AuditOrganisation {
|
|
22
|
+
id: string;
|
|
23
|
+
name: string;
|
|
24
|
+
}
|
|
25
|
+
export interface AuditRequestContext {
|
|
26
|
+
ip_address?: string;
|
|
27
|
+
user_agent?: string;
|
|
28
|
+
}
|
|
29
|
+
/** Origin system for the event. */
|
|
30
|
+
export type AuditSource = "control" | "auth" | "data" | "tunnels";
|
|
31
|
+
/**
|
|
32
|
+
* String-literal union of every wired audit action — kept in lock-step with
|
|
33
|
+
* ``doover_control/events/types.py``'s ``EventType`` enum. Future event types
|
|
34
|
+
* declared in Python but not yet emitted are intentionally included so the
|
|
35
|
+
* frontend mapping (icons, labels) can be filled in ahead of the wire-up.
|
|
36
|
+
*/
|
|
37
|
+
export type AuditAction = "user.logged_in" | "user.login.failed" | "user.signed_up" | "user.created" | "user.updated" | "user.deleted" | "user.deactivated" | "user.reactivated" | "user.password_changed" | "user.password_reset" | "user.password_breached" | "user.mfa_changed" | "user.email_verified" | "user.email_changed" | "user.idp_linked" | "user.idp_unlinked" | "user.token_revoked" | "user.invited" | "user.removed" | "user.role_changed" | "app.installed" | "app.deployed" | "app.config_changed" | "app.uninstalled" | "solution.config_changed" | "group.created" | "group.edited" | "group.deleted" | "device.created" | "device.updated" | "device.config_changed" | "device.archived" | "device.unarchived" | "device.deleted" | "device.opened" | "tunnel.created" | "tunnel.deleted" | "tunnel.opened" | "tunnel.closed" | "tunnel.accessed" | "notification.sent" | "report.created" | "command.received";
|
|
38
|
+
/**
|
|
39
|
+
* The audit record payload as written by ``publish_audit`` — i.e. what you
|
|
40
|
+
* find on ``MessageStructure<AuditEvent>.data`` after reading the channel.
|
|
41
|
+
*
|
|
42
|
+
* The doover-data ``MessageStructure`` envelope provides ``id`` (snowflake)
|
|
43
|
+
* and ``timestamp`` (epoch ms) for ordering; this struct is the body only.
|
|
44
|
+
*/
|
|
45
|
+
export interface AuditEvent {
|
|
46
|
+
action: AuditAction;
|
|
47
|
+
actor: AuditEntity | null;
|
|
48
|
+
subject: AuditEntity | null;
|
|
49
|
+
organisation: AuditOrganisation | null;
|
|
50
|
+
source: AuditSource;
|
|
51
|
+
metadata: Record<string, unknown>;
|
|
52
|
+
request_context: AuditRequestContext | null;
|
|
53
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Audit event types — mirror of the records doover-control writes to the
|
|
3
|
+
* `dv-audit` channel (see ``doover-control/doover_control/events/audit.py``
|
|
4
|
+
* for the source of truth).
|
|
5
|
+
*
|
|
6
|
+
* Each record is read back via the standard channel-messages APIs: it lands
|
|
7
|
+
* inside a ``MessageStructure<AuditEvent>`` envelope (with ``id``, ``timestamp``,
|
|
8
|
+
* ``channel``, etc.), and the record itself is on ``message.data``.
|
|
9
|
+
*/
|
|
10
|
+
/** Channel name on which audit records live in doover-data. */
|
|
11
|
+
export const DV_AUDIT_CHANNEL = "dv-audit";
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared types for the bounded batch mutation endpoints.
|
|
3
|
+
*
|
|
4
|
+
* The data API exposes cross-agent batch mutations at `/agents/aggregates`
|
|
5
|
+
* and `/agents/messages`. Every item carries its own `agent_id` and
|
|
6
|
+
* `channel_name`, each is authorised independently, and the batch can
|
|
7
|
+
* partially succeed — results come back in request order and callers should
|
|
8
|
+
* retry only the failed entries.
|
|
9
|
+
*
|
|
10
|
+
* See `docs/batch-aggregate-updates.md` in channels-rest for the contract.
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Server-enforced ceiling on items per batch request. Exceeding it is a 400,
|
|
14
|
+
* so callers must chunk. `chunkBatchItems` does this for you.
|
|
15
|
+
*/
|
|
16
|
+
export declare const MAX_BATCH_ITEMS = 50;
|
|
17
|
+
/** A single merge-patch against one agent's channel aggregate. */
|
|
18
|
+
export interface BatchAggregateUpdateItem {
|
|
19
|
+
agent_id: string;
|
|
20
|
+
channel_name: string;
|
|
21
|
+
/** Merge patch. `null` at a leaf clears that key. */
|
|
22
|
+
data: Record<string, unknown>;
|
|
23
|
+
/**
|
|
24
|
+
* Dot-paths to replace outright rather than merge into. Mirrors the
|
|
25
|
+
* `replace` query parameter on the single-aggregate PATCH.
|
|
26
|
+
*/
|
|
27
|
+
replace?: string[];
|
|
28
|
+
/** Skip aggregate hooks (alarms, SNS fan-out, websocket publish). */
|
|
29
|
+
suppress_hooks?: boolean;
|
|
30
|
+
}
|
|
31
|
+
export interface BatchCreateMessageItem {
|
|
32
|
+
agent_id: string;
|
|
33
|
+
channel_name: string;
|
|
34
|
+
/**
|
|
35
|
+
* Supplying a stable ID makes create retries idempotent. Without one the
|
|
36
|
+
* server generates an ID and a lost response can duplicate the message.
|
|
37
|
+
*/
|
|
38
|
+
message_id?: string;
|
|
39
|
+
data: unknown;
|
|
40
|
+
/** Message timestamp, ms since epoch. Defaults to server receipt time. */
|
|
41
|
+
ts?: number;
|
|
42
|
+
/** Time-to-live in seconds. */
|
|
43
|
+
ttl?: number;
|
|
44
|
+
}
|
|
45
|
+
export interface BatchUpdateMessageItem {
|
|
46
|
+
agent_id: string;
|
|
47
|
+
channel_name: string;
|
|
48
|
+
message_id: string;
|
|
49
|
+
data: unknown;
|
|
50
|
+
}
|
|
51
|
+
export interface BatchDeleteMessageItem {
|
|
52
|
+
agent_id: string;
|
|
53
|
+
channel_name: string;
|
|
54
|
+
message_id: string;
|
|
55
|
+
}
|
|
56
|
+
/** Per-item outcome. `error` is present only when `success` is false. */
|
|
57
|
+
export interface BatchResultItem {
|
|
58
|
+
agent_id: string;
|
|
59
|
+
channel_name: string;
|
|
60
|
+
success: boolean;
|
|
61
|
+
error?: string;
|
|
62
|
+
}
|
|
63
|
+
export interface BatchMessageResultItem extends BatchResultItem {
|
|
64
|
+
/** Present for creates — the server-generated ID when none was supplied. */
|
|
65
|
+
message_id?: string;
|
|
66
|
+
}
|
|
67
|
+
export interface BatchResponse<TItem extends BatchResultItem = BatchResultItem> {
|
|
68
|
+
/** Results in request order, one per submitted item. */
|
|
69
|
+
items: TItem[];
|
|
70
|
+
count: number;
|
|
71
|
+
succeeded: number;
|
|
72
|
+
failed: number;
|
|
73
|
+
}
|
|
74
|
+
export type BatchAggregateResponse = BatchResponse<BatchResultItem>;
|
|
75
|
+
export type BatchMessageResponse = BatchResponse<BatchMessageResultItem>;
|
|
76
|
+
/**
|
|
77
|
+
* Split `items` into server-acceptable chunks. Returns `[]` for an empty
|
|
78
|
+
* input, since an empty batch is a 400 rather than a no-op.
|
|
79
|
+
*/
|
|
80
|
+
export declare function chunkBatchItems<T>(items: T[], size?: number): T[][];
|
|
81
|
+
/**
|
|
82
|
+
* Merge several batch responses into one, as if the whole set had been sent
|
|
83
|
+
* in a single request. Useful after chunking.
|
|
84
|
+
*/
|
|
85
|
+
export declare function mergeBatchResponses<TItem extends BatchResultItem>(responses: BatchResponse<TItem>[]): BatchResponse<TItem>;
|