From be0bca896c68ff478468cb91e17333e74925dbef Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Fri, 28 Aug 2026 01:18:25 +0000 Subject: [PATCH 1/3] feat(watchsync): sync device authorization proto from silo v0.13.2 Adds WatchSyncDeviceAuthorizationService and related watch-sync proto fields so prairie-server can build against the synced silo upstream. Co-authored-by: Jonah May --- .../plugin/v1/watch_sync_provider.pb.go | 1094 ++++++++++++++--- .../plugin/v1/watch_sync_provider_grpc.pb.go | 146 +++ pkg/pluginsdk/runtime/runtime.go | 38 + pkg/pluginsdk/runtime/serve_manifest.go | 43 +- .../runtime/watch_sync_provider_test.go | 20 +- .../plugin/v1/watch_sync_provider.proto | 121 +- 6 files changed, 1273 insertions(+), 189 deletions(-) diff --git a/pkg/pluginproto/prairie/plugin/v1/watch_sync_provider.pb.go b/pkg/pluginproto/prairie/plugin/v1/watch_sync_provider.pb.go index d62c0df..6393175 100644 --- a/pkg/pluginproto/prairie/plugin/v1/watch_sync_provider.pb.go +++ b/pkg/pluginproto/prairie/plugin/v1/watch_sync_provider.pb.go @@ -30,6 +30,7 @@ const ( WatchSyncAuthMethod_WATCH_SYNC_AUTH_METHOD_UNSPECIFIED WatchSyncAuthMethod = 0 WatchSyncAuthMethod_WATCH_SYNC_AUTH_METHOD_AUTHORIZATION_CODE WatchSyncAuthMethod = 1 WatchSyncAuthMethod_WATCH_SYNC_AUTH_METHOD_API_KEY WatchSyncAuthMethod = 2 + WatchSyncAuthMethod_WATCH_SYNC_AUTH_METHOD_DEVICE_CODE WatchSyncAuthMethod = 3 ) // Enum value maps for WatchSyncAuthMethod. @@ -38,11 +39,13 @@ var ( 0: "WATCH_SYNC_AUTH_METHOD_UNSPECIFIED", 1: "WATCH_SYNC_AUTH_METHOD_AUTHORIZATION_CODE", 2: "WATCH_SYNC_AUTH_METHOD_API_KEY", + 3: "WATCH_SYNC_AUTH_METHOD_DEVICE_CODE", } WatchSyncAuthMethod_value = map[string]int32{ "WATCH_SYNC_AUTH_METHOD_UNSPECIFIED": 0, "WATCH_SYNC_AUTH_METHOD_AUTHORIZATION_CODE": 1, "WATCH_SYNC_AUTH_METHOD_API_KEY": 2, + "WATCH_SYNC_AUTH_METHOD_DEVICE_CODE": 3, } ) @@ -125,9 +128,16 @@ func (WatchSyncMediaType) EnumDescriptor() ([]byte, []int) { type WatchSyncOperation int32 const ( - WatchSyncOperation_WATCH_SYNC_OPERATION_UNSPECIFIED WatchSyncOperation = 0 - WatchSyncOperation_WATCH_SYNC_OPERATION_MARK_WATCHED WatchSyncOperation = 1 - WatchSyncOperation_WATCH_SYNC_OPERATION_MARK_UNWATCHED WatchSyncOperation = 2 + WatchSyncOperation_WATCH_SYNC_OPERATION_UNSPECIFIED WatchSyncOperation = 0 + WatchSyncOperation_WATCH_SYNC_OPERATION_MARK_WATCHED WatchSyncOperation = 1 + WatchSyncOperation_WATCH_SYNC_OPERATION_MARK_UNWATCHED WatchSyncOperation = 2 + WatchSyncOperation_WATCH_SYNC_OPERATION_ADD_FAVORITE WatchSyncOperation = 3 + WatchSyncOperation_WATCH_SYNC_OPERATION_REMOVE_FAVORITE WatchSyncOperation = 4 + WatchSyncOperation_WATCH_SYNC_OPERATION_ADD_TO_WATCHLIST WatchSyncOperation = 5 + WatchSyncOperation_WATCH_SYNC_OPERATION_REMOVE_FROM_WATCHLIST WatchSyncOperation = 6 + WatchSyncOperation_WATCH_SYNC_OPERATION_SCROBBLE_START WatchSyncOperation = 7 + WatchSyncOperation_WATCH_SYNC_OPERATION_SCROBBLE_PAUSE WatchSyncOperation = 8 + WatchSyncOperation_WATCH_SYNC_OPERATION_SCROBBLE_STOP WatchSyncOperation = 9 ) // Enum value maps for WatchSyncOperation. @@ -136,11 +146,25 @@ var ( 0: "WATCH_SYNC_OPERATION_UNSPECIFIED", 1: "WATCH_SYNC_OPERATION_MARK_WATCHED", 2: "WATCH_SYNC_OPERATION_MARK_UNWATCHED", + 3: "WATCH_SYNC_OPERATION_ADD_FAVORITE", + 4: "WATCH_SYNC_OPERATION_REMOVE_FAVORITE", + 5: "WATCH_SYNC_OPERATION_ADD_TO_WATCHLIST", + 6: "WATCH_SYNC_OPERATION_REMOVE_FROM_WATCHLIST", + 7: "WATCH_SYNC_OPERATION_SCROBBLE_START", + 8: "WATCH_SYNC_OPERATION_SCROBBLE_PAUSE", + 9: "WATCH_SYNC_OPERATION_SCROBBLE_STOP", } WatchSyncOperation_value = map[string]int32{ - "WATCH_SYNC_OPERATION_UNSPECIFIED": 0, - "WATCH_SYNC_OPERATION_MARK_WATCHED": 1, - "WATCH_SYNC_OPERATION_MARK_UNWATCHED": 2, + "WATCH_SYNC_OPERATION_UNSPECIFIED": 0, + "WATCH_SYNC_OPERATION_MARK_WATCHED": 1, + "WATCH_SYNC_OPERATION_MARK_UNWATCHED": 2, + "WATCH_SYNC_OPERATION_ADD_FAVORITE": 3, + "WATCH_SYNC_OPERATION_REMOVE_FAVORITE": 4, + "WATCH_SYNC_OPERATION_ADD_TO_WATCHLIST": 5, + "WATCH_SYNC_OPERATION_REMOVE_FROM_WATCHLIST": 6, + "WATCH_SYNC_OPERATION_SCROBBLE_START": 7, + "WATCH_SYNC_OPERATION_SCROBBLE_PAUSE": 8, + "WATCH_SYNC_OPERATION_SCROBBLE_STOP": 9, } ) @@ -171,6 +195,116 @@ func (WatchSyncOperation) EnumDescriptor() ([]byte, []int) { return file_prairie_plugin_v1_watch_sync_provider_proto_rawDescGZIP(), []int{2} } +type WatchSyncRemoteStateKind int32 + +const ( + WatchSyncRemoteStateKind_WATCH_SYNC_REMOTE_STATE_KIND_UNSPECIFIED WatchSyncRemoteStateKind = 0 + WatchSyncRemoteStateKind_WATCH_SYNC_REMOTE_STATE_KIND_WATCHED WatchSyncRemoteStateKind = 1 + WatchSyncRemoteStateKind_WATCH_SYNC_REMOTE_STATE_KIND_PROGRESS WatchSyncRemoteStateKind = 2 + WatchSyncRemoteStateKind_WATCH_SYNC_REMOTE_STATE_KIND_FAVORITE WatchSyncRemoteStateKind = 3 + WatchSyncRemoteStateKind_WATCH_SYNC_REMOTE_STATE_KIND_WATCHLIST WatchSyncRemoteStateKind = 4 +) + +// Enum value maps for WatchSyncRemoteStateKind. +var ( + WatchSyncRemoteStateKind_name = map[int32]string{ + 0: "WATCH_SYNC_REMOTE_STATE_KIND_UNSPECIFIED", + 1: "WATCH_SYNC_REMOTE_STATE_KIND_WATCHED", + 2: "WATCH_SYNC_REMOTE_STATE_KIND_PROGRESS", + 3: "WATCH_SYNC_REMOTE_STATE_KIND_FAVORITE", + 4: "WATCH_SYNC_REMOTE_STATE_KIND_WATCHLIST", + } + WatchSyncRemoteStateKind_value = map[string]int32{ + "WATCH_SYNC_REMOTE_STATE_KIND_UNSPECIFIED": 0, + "WATCH_SYNC_REMOTE_STATE_KIND_WATCHED": 1, + "WATCH_SYNC_REMOTE_STATE_KIND_PROGRESS": 2, + "WATCH_SYNC_REMOTE_STATE_KIND_FAVORITE": 3, + "WATCH_SYNC_REMOTE_STATE_KIND_WATCHLIST": 4, + } +) + +func (x WatchSyncRemoteStateKind) Enum() *WatchSyncRemoteStateKind { + p := new(WatchSyncRemoteStateKind) + *p = x + return p +} + +func (x WatchSyncRemoteStateKind) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (WatchSyncRemoteStateKind) Descriptor() protoreflect.EnumDescriptor { + return file_prairie_plugin_v1_watch_sync_provider_proto_enumTypes[3].Descriptor() +} + +func (WatchSyncRemoteStateKind) Type() protoreflect.EnumType { + return &file_prairie_plugin_v1_watch_sync_provider_proto_enumTypes[3] +} + +func (x WatchSyncRemoteStateKind) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use WatchSyncRemoteStateKind.Descriptor instead. +func (WatchSyncRemoteStateKind) EnumDescriptor() ([]byte, []int) { + return file_prairie_plugin_v1_watch_sync_provider_proto_rawDescGZIP(), []int{3} +} + +type WatchSyncDeviceAuthorizationStatus int32 + +const ( + WatchSyncDeviceAuthorizationStatus_WATCH_SYNC_DEVICE_AUTHORIZATION_STATUS_UNSPECIFIED WatchSyncDeviceAuthorizationStatus = 0 + WatchSyncDeviceAuthorizationStatus_WATCH_SYNC_DEVICE_AUTHORIZATION_STATUS_PENDING WatchSyncDeviceAuthorizationStatus = 1 + WatchSyncDeviceAuthorizationStatus_WATCH_SYNC_DEVICE_AUTHORIZATION_STATUS_AUTHORIZED WatchSyncDeviceAuthorizationStatus = 2 + WatchSyncDeviceAuthorizationStatus_WATCH_SYNC_DEVICE_AUTHORIZATION_STATUS_DENIED WatchSyncDeviceAuthorizationStatus = 3 + WatchSyncDeviceAuthorizationStatus_WATCH_SYNC_DEVICE_AUTHORIZATION_STATUS_EXPIRED WatchSyncDeviceAuthorizationStatus = 4 +) + +// Enum value maps for WatchSyncDeviceAuthorizationStatus. +var ( + WatchSyncDeviceAuthorizationStatus_name = map[int32]string{ + 0: "WATCH_SYNC_DEVICE_AUTHORIZATION_STATUS_UNSPECIFIED", + 1: "WATCH_SYNC_DEVICE_AUTHORIZATION_STATUS_PENDING", + 2: "WATCH_SYNC_DEVICE_AUTHORIZATION_STATUS_AUTHORIZED", + 3: "WATCH_SYNC_DEVICE_AUTHORIZATION_STATUS_DENIED", + 4: "WATCH_SYNC_DEVICE_AUTHORIZATION_STATUS_EXPIRED", + } + WatchSyncDeviceAuthorizationStatus_value = map[string]int32{ + "WATCH_SYNC_DEVICE_AUTHORIZATION_STATUS_UNSPECIFIED": 0, + "WATCH_SYNC_DEVICE_AUTHORIZATION_STATUS_PENDING": 1, + "WATCH_SYNC_DEVICE_AUTHORIZATION_STATUS_AUTHORIZED": 2, + "WATCH_SYNC_DEVICE_AUTHORIZATION_STATUS_DENIED": 3, + "WATCH_SYNC_DEVICE_AUTHORIZATION_STATUS_EXPIRED": 4, + } +) + +func (x WatchSyncDeviceAuthorizationStatus) Enum() *WatchSyncDeviceAuthorizationStatus { + p := new(WatchSyncDeviceAuthorizationStatus) + *p = x + return p +} + +func (x WatchSyncDeviceAuthorizationStatus) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (WatchSyncDeviceAuthorizationStatus) Descriptor() protoreflect.EnumDescriptor { + return file_prairie_plugin_v1_watch_sync_provider_proto_enumTypes[4].Descriptor() +} + +func (WatchSyncDeviceAuthorizationStatus) Type() protoreflect.EnumType { + return &file_prairie_plugin_v1_watch_sync_provider_proto_enumTypes[4] +} + +func (x WatchSyncDeviceAuthorizationStatus) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use WatchSyncDeviceAuthorizationStatus.Descriptor instead. +func (WatchSyncDeviceAuthorizationStatus) EnumDescriptor() ([]byte, []int) { + return file_prairie_plugin_v1_watch_sync_provider_proto_rawDescGZIP(), []int{4} +} + type WatchSyncOrigin int32 const ( @@ -207,11 +341,11 @@ func (x WatchSyncOrigin) String() string { } func (WatchSyncOrigin) Descriptor() protoreflect.EnumDescriptor { - return file_prairie_plugin_v1_watch_sync_provider_proto_enumTypes[3].Descriptor() + return file_prairie_plugin_v1_watch_sync_provider_proto_enumTypes[5].Descriptor() } func (WatchSyncOrigin) Type() protoreflect.EnumType { - return &file_prairie_plugin_v1_watch_sync_provider_proto_enumTypes[3] + return &file_prairie_plugin_v1_watch_sync_provider_proto_enumTypes[5] } func (x WatchSyncOrigin) Number() protoreflect.EnumNumber { @@ -220,7 +354,7 @@ func (x WatchSyncOrigin) Number() protoreflect.EnumNumber { // Deprecated: Use WatchSyncOrigin.Descriptor instead. func (WatchSyncOrigin) EnumDescriptor() ([]byte, []int) { - return file_prairie_plugin_v1_watch_sync_provider_proto_rawDescGZIP(), []int{3} + return file_prairie_plugin_v1_watch_sync_provider_proto_rawDescGZIP(), []int{5} } type WatchSyncApplyStatus int32 @@ -262,11 +396,11 @@ func (x WatchSyncApplyStatus) String() string { } func (WatchSyncApplyStatus) Descriptor() protoreflect.EnumDescriptor { - return file_prairie_plugin_v1_watch_sync_provider_proto_enumTypes[4].Descriptor() + return file_prairie_plugin_v1_watch_sync_provider_proto_enumTypes[6].Descriptor() } func (WatchSyncApplyStatus) Type() protoreflect.EnumType { - return &file_prairie_plugin_v1_watch_sync_provider_proto_enumTypes[4] + return &file_prairie_plugin_v1_watch_sync_provider_proto_enumTypes[6] } func (x WatchSyncApplyStatus) Number() protoreflect.EnumNumber { @@ -275,7 +409,7 @@ func (x WatchSyncApplyStatus) Number() protoreflect.EnumNumber { // Deprecated: Use WatchSyncApplyStatus.Descriptor instead. func (WatchSyncApplyStatus) EnumDescriptor() ([]byte, []int) { - return file_prairie_plugin_v1_watch_sync_provider_proto_rawDescGZIP(), []int{4} + return file_prairie_plugin_v1_watch_sync_provider_proto_rawDescGZIP(), []int{6} } type WatchSyncFaultCode int32 @@ -323,11 +457,11 @@ func (x WatchSyncFaultCode) String() string { } func (WatchSyncFaultCode) Descriptor() protoreflect.EnumDescriptor { - return file_prairie_plugin_v1_watch_sync_provider_proto_enumTypes[5].Descriptor() + return file_prairie_plugin_v1_watch_sync_provider_proto_enumTypes[7].Descriptor() } func (WatchSyncFaultCode) Type() protoreflect.EnumType { - return &file_prairie_plugin_v1_watch_sync_provider_proto_enumTypes[5] + return &file_prairie_plugin_v1_watch_sync_provider_proto_enumTypes[7] } func (x WatchSyncFaultCode) Number() protoreflect.EnumNumber { @@ -336,7 +470,7 @@ func (x WatchSyncFaultCode) Number() protoreflect.EnumNumber { // Deprecated: Use WatchSyncFaultCode.Descriptor instead. func (WatchSyncFaultCode) EnumDescriptor() ([]byte, []int) { - return file_prairie_plugin_v1_watch_sync_provider_proto_rawDescGZIP(), []int{5} + return file_prairie_plugin_v1_watch_sync_provider_proto_rawDescGZIP(), []int{7} } type WatchSyncProviderDescriptor struct { @@ -349,8 +483,19 @@ type WatchSyncProviderDescriptor struct { SupportedMediaTypes []WatchSyncMediaType `protobuf:"varint,6,rep,packed,name=supported_media_types,json=supportedMediaTypes,proto3,enum=prairie.plugin.v1.WatchSyncMediaType" json:"supported_media_types,omitempty"` ExternalIdNamespaces []string `protobuf:"bytes,7,rep,name=external_id_namespaces,json=externalIdNamespaces,proto3" json:"external_id_namespaces,omitempty"` MaxBatchSize int32 `protobuf:"varint,8,opt,name=max_batch_size,json=maxBatchSize,proto3" json:"max_batch_size,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + ImportFavorites bool `protobuf:"varint,9,opt,name=import_favorites,json=importFavorites,proto3" json:"import_favorites,omitempty"` + ExportFavorites bool `protobuf:"varint,10,opt,name=export_favorites,json=exportFavorites,proto3" json:"export_favorites,omitempty"` + RemoveFavorites bool `protobuf:"varint,11,opt,name=remove_favorites,json=removeFavorites,proto3" json:"remove_favorites,omitempty"` + ImportWatchlist bool `protobuf:"varint,12,opt,name=import_watchlist,json=importWatchlist,proto3" json:"import_watchlist,omitempty"` + ExportWatchlist bool `protobuf:"varint,13,opt,name=export_watchlist,json=exportWatchlist,proto3" json:"export_watchlist,omitempty"` + RemoveWatchlist bool `protobuf:"varint,14,opt,name=remove_watchlist,json=removeWatchlist,proto3" json:"remove_watchlist,omitempty"` + // The order of WATCHLIST states returned by ListRemoteState is meaningful. + // WATCHLIST traversals must set complete_snapshot=true when this is enabled; + // an incremental subset cannot define positions relative to omitted items. + ProvidesWatchlistOrder bool `protobuf:"varint,15,opt,name=provides_watchlist_order,json=providesWatchlistOrder,proto3" json:"provides_watchlist_order,omitempty"` + ScrobblePlayback bool `protobuf:"varint,16,opt,name=scrobble_playback,json=scrobblePlayback,proto3" json:"scrobble_playback,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *WatchSyncProviderDescriptor) Reset() { @@ -439,6 +584,62 @@ func (x *WatchSyncProviderDescriptor) GetMaxBatchSize() int32 { return 0 } +func (x *WatchSyncProviderDescriptor) GetImportFavorites() bool { + if x != nil { + return x.ImportFavorites + } + return false +} + +func (x *WatchSyncProviderDescriptor) GetExportFavorites() bool { + if x != nil { + return x.ExportFavorites + } + return false +} + +func (x *WatchSyncProviderDescriptor) GetRemoveFavorites() bool { + if x != nil { + return x.RemoveFavorites + } + return false +} + +func (x *WatchSyncProviderDescriptor) GetImportWatchlist() bool { + if x != nil { + return x.ImportWatchlist + } + return false +} + +func (x *WatchSyncProviderDescriptor) GetExportWatchlist() bool { + if x != nil { + return x.ExportWatchlist + } + return false +} + +func (x *WatchSyncProviderDescriptor) GetRemoveWatchlist() bool { + if x != nil { + return x.RemoveWatchlist + } + return false +} + +func (x *WatchSyncProviderDescriptor) GetProvidesWatchlistOrder() bool { + if x != nil { + return x.ProvidesWatchlistOrder + } + return false +} + +func (x *WatchSyncProviderDescriptor) GetScrobblePlayback() bool { + if x != nil { + return x.ScrobblePlayback + } + return false +} + type WatchSyncProviderConfig struct { state protoimpl.MessageState `protogen:"open.v1"` Values map[string]string `protobuf:"bytes,1,rep,name=values,proto3" json:"values,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` @@ -1055,6 +1256,319 @@ func (x *WatchSyncExchangeAPIKeyRequest) GetApiKey() string { return "" } +type WatchSyncDeviceAuthorizationServiceStartRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + CapabilityId string `protobuf:"bytes,1,opt,name=capability_id,json=capabilityId,proto3" json:"capability_id,omitempty"` + ProviderConfig *WatchSyncProviderConfig `protobuf:"bytes,2,opt,name=provider_config,json=providerConfig,proto3" json:"provider_config,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *WatchSyncDeviceAuthorizationServiceStartRequest) Reset() { + *x = WatchSyncDeviceAuthorizationServiceStartRequest{} + mi := &file_prairie_plugin_v1_watch_sync_provider_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *WatchSyncDeviceAuthorizationServiceStartRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*WatchSyncDeviceAuthorizationServiceStartRequest) ProtoMessage() {} + +func (x *WatchSyncDeviceAuthorizationServiceStartRequest) ProtoReflect() protoreflect.Message { + mi := &file_prairie_plugin_v1_watch_sync_provider_proto_msgTypes[10] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use WatchSyncDeviceAuthorizationServiceStartRequest.ProtoReflect.Descriptor instead. +func (*WatchSyncDeviceAuthorizationServiceStartRequest) Descriptor() ([]byte, []int) { + return file_prairie_plugin_v1_watch_sync_provider_proto_rawDescGZIP(), []int{10} +} + +func (x *WatchSyncDeviceAuthorizationServiceStartRequest) GetCapabilityId() string { + if x != nil { + return x.CapabilityId + } + return "" +} + +func (x *WatchSyncDeviceAuthorizationServiceStartRequest) GetProviderConfig() *WatchSyncProviderConfig { + if x != nil { + return x.ProviderConfig + } + return nil +} + +type WatchSyncDeviceAuthorizationServiceStartResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + UserCode string `protobuf:"bytes,1,opt,name=user_code,json=userCode,proto3" json:"user_code,omitempty"` + VerificationUrl string `protobuf:"bytes,2,opt,name=verification_url,json=verificationUrl,proto3" json:"verification_url,omitempty"` + VerificationUrlComplete string `protobuf:"bytes,3,opt,name=verification_url_complete,json=verificationUrlComplete,proto3" json:"verification_url_complete,omitempty"` + // Plugin-defined flow data. The host encrypts it until authorization + // completes and never returns it through the public HTTP API. + ProviderState []byte `protobuf:"bytes,4,opt,name=provider_state,json=providerState,proto3" json:"provider_state,omitempty"` + PollingInterval *durationpb.Duration `protobuf:"bytes,5,opt,name=polling_interval,json=pollingInterval,proto3" json:"polling_interval,omitempty"` + ExpiresAt *timestamppb.Timestamp `protobuf:"bytes,6,opt,name=expires_at,json=expiresAt,proto3" json:"expires_at,omitempty"` + Fault *WatchSyncFault `protobuf:"bytes,7,opt,name=fault,proto3" json:"fault,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *WatchSyncDeviceAuthorizationServiceStartResponse) Reset() { + *x = WatchSyncDeviceAuthorizationServiceStartResponse{} + mi := &file_prairie_plugin_v1_watch_sync_provider_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *WatchSyncDeviceAuthorizationServiceStartResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*WatchSyncDeviceAuthorizationServiceStartResponse) ProtoMessage() {} + +func (x *WatchSyncDeviceAuthorizationServiceStartResponse) ProtoReflect() protoreflect.Message { + mi := &file_prairie_plugin_v1_watch_sync_provider_proto_msgTypes[11] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use WatchSyncDeviceAuthorizationServiceStartResponse.ProtoReflect.Descriptor instead. +func (*WatchSyncDeviceAuthorizationServiceStartResponse) Descriptor() ([]byte, []int) { + return file_prairie_plugin_v1_watch_sync_provider_proto_rawDescGZIP(), []int{11} +} + +func (x *WatchSyncDeviceAuthorizationServiceStartResponse) GetUserCode() string { + if x != nil { + return x.UserCode + } + return "" +} + +func (x *WatchSyncDeviceAuthorizationServiceStartResponse) GetVerificationUrl() string { + if x != nil { + return x.VerificationUrl + } + return "" +} + +func (x *WatchSyncDeviceAuthorizationServiceStartResponse) GetVerificationUrlComplete() string { + if x != nil { + return x.VerificationUrlComplete + } + return "" +} + +func (x *WatchSyncDeviceAuthorizationServiceStartResponse) GetProviderState() []byte { + if x != nil { + return x.ProviderState + } + return nil +} + +func (x *WatchSyncDeviceAuthorizationServiceStartResponse) GetPollingInterval() *durationpb.Duration { + if x != nil { + return x.PollingInterval + } + return nil +} + +func (x *WatchSyncDeviceAuthorizationServiceStartResponse) GetExpiresAt() *timestamppb.Timestamp { + if x != nil { + return x.ExpiresAt + } + return nil +} + +func (x *WatchSyncDeviceAuthorizationServiceStartResponse) GetFault() *WatchSyncFault { + if x != nil { + return x.Fault + } + return nil +} + +type WatchSyncDeviceAuthorizationServicePollRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + CapabilityId string `protobuf:"bytes,1,opt,name=capability_id,json=capabilityId,proto3" json:"capability_id,omitempty"` + ProviderConfig *WatchSyncProviderConfig `protobuf:"bytes,2,opt,name=provider_config,json=providerConfig,proto3" json:"provider_config,omitempty"` + ProviderState []byte `protobuf:"bytes,3,opt,name=provider_state,json=providerState,proto3" json:"provider_state,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *WatchSyncDeviceAuthorizationServicePollRequest) Reset() { + *x = WatchSyncDeviceAuthorizationServicePollRequest{} + mi := &file_prairie_plugin_v1_watch_sync_provider_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *WatchSyncDeviceAuthorizationServicePollRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*WatchSyncDeviceAuthorizationServicePollRequest) ProtoMessage() {} + +func (x *WatchSyncDeviceAuthorizationServicePollRequest) ProtoReflect() protoreflect.Message { + mi := &file_prairie_plugin_v1_watch_sync_provider_proto_msgTypes[12] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use WatchSyncDeviceAuthorizationServicePollRequest.ProtoReflect.Descriptor instead. +func (*WatchSyncDeviceAuthorizationServicePollRequest) Descriptor() ([]byte, []int) { + return file_prairie_plugin_v1_watch_sync_provider_proto_rawDescGZIP(), []int{12} +} + +func (x *WatchSyncDeviceAuthorizationServicePollRequest) GetCapabilityId() string { + if x != nil { + return x.CapabilityId + } + return "" +} + +func (x *WatchSyncDeviceAuthorizationServicePollRequest) GetProviderConfig() *WatchSyncProviderConfig { + if x != nil { + return x.ProviderConfig + } + return nil +} + +func (x *WatchSyncDeviceAuthorizationServicePollRequest) GetProviderState() []byte { + if x != nil { + return x.ProviderState + } + return nil +} + +type WatchSyncDeviceAuthorizationServicePollResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Status WatchSyncDeviceAuthorizationStatus `protobuf:"varint,1,opt,name=status,proto3,enum=prairie.plugin.v1.WatchSyncDeviceAuthorizationStatus" json:"status,omitempty"` + // Complete authoritative replacement when status is AUTHORIZED. The host + // persists it before consuming account or fault. + Credentials *WatchSyncCredentials `protobuf:"bytes,2,opt,name=credentials,proto3" json:"credentials,omitempty"` + Account *WatchSyncAccount `protobuf:"bytes,3,opt,name=account,proto3" json:"account,omitempty"` + // PENDING normally omits fault. DENIED and EXPIRED may use a safe, + // non-retryable fault. Connection-wide and transport failures use fault. + Fault *WatchSyncFault `protobuf:"bytes,4,opt,name=fault,proto3" json:"fault,omitempty"` + // A PENDING response may update host-private state and timing only for the + // same user challenge. The user_code and verification URLs returned by Start + // must remain valid through expires_at; if those instructions change, expire + // this flow and require a new Start call. + // + // Optional authoritative replacement for provider_state while PENDING. The + // host encrypts and uses it for the next poll. Presence is significant: an + // explicitly empty value clears the prior state, while omission retains it. + ProviderState []byte `protobuf:"bytes,5,opt,name=provider_state,json=providerState,proto3,oneof" json:"provider_state,omitempty"` + // Optional replacement polling interval while PENDING, for example after an + // OAuth device-flow slow_down response. + PollingInterval *durationpb.Duration `protobuf:"bytes,6,opt,name=polling_interval,json=pollingInterval,proto3" json:"polling_interval,omitempty"` + // Optional replacement expiry for the same user challenge. + ExpiresAt *timestamppb.Timestamp `protobuf:"bytes,7,opt,name=expires_at,json=expiresAt,proto3" json:"expires_at,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *WatchSyncDeviceAuthorizationServicePollResponse) Reset() { + *x = WatchSyncDeviceAuthorizationServicePollResponse{} + mi := &file_prairie_plugin_v1_watch_sync_provider_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *WatchSyncDeviceAuthorizationServicePollResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*WatchSyncDeviceAuthorizationServicePollResponse) ProtoMessage() {} + +func (x *WatchSyncDeviceAuthorizationServicePollResponse) ProtoReflect() protoreflect.Message { + mi := &file_prairie_plugin_v1_watch_sync_provider_proto_msgTypes[13] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use WatchSyncDeviceAuthorizationServicePollResponse.ProtoReflect.Descriptor instead. +func (*WatchSyncDeviceAuthorizationServicePollResponse) Descriptor() ([]byte, []int) { + return file_prairie_plugin_v1_watch_sync_provider_proto_rawDescGZIP(), []int{13} +} + +func (x *WatchSyncDeviceAuthorizationServicePollResponse) GetStatus() WatchSyncDeviceAuthorizationStatus { + if x != nil { + return x.Status + } + return WatchSyncDeviceAuthorizationStatus_WATCH_SYNC_DEVICE_AUTHORIZATION_STATUS_UNSPECIFIED +} + +func (x *WatchSyncDeviceAuthorizationServicePollResponse) GetCredentials() *WatchSyncCredentials { + if x != nil { + return x.Credentials + } + return nil +} + +func (x *WatchSyncDeviceAuthorizationServicePollResponse) GetAccount() *WatchSyncAccount { + if x != nil { + return x.Account + } + return nil +} + +func (x *WatchSyncDeviceAuthorizationServicePollResponse) GetFault() *WatchSyncFault { + if x != nil { + return x.Fault + } + return nil +} + +func (x *WatchSyncDeviceAuthorizationServicePollResponse) GetProviderState() []byte { + if x != nil { + return x.ProviderState + } + return nil +} + +func (x *WatchSyncDeviceAuthorizationServicePollResponse) GetPollingInterval() *durationpb.Duration { + if x != nil { + return x.PollingInterval + } + return nil +} + +func (x *WatchSyncDeviceAuthorizationServicePollResponse) GetExpiresAt() *timestamppb.Timestamp { + if x != nil { + return x.ExpiresAt + } + return nil +} + type WatchSyncRefreshCredentialsRequest struct { state protoimpl.MessageState `protogen:"open.v1"` Context *WatchSyncAuthenticatedContext `protobuf:"bytes,1,opt,name=context,proto3" json:"context,omitempty"` @@ -1064,7 +1578,7 @@ type WatchSyncRefreshCredentialsRequest struct { func (x *WatchSyncRefreshCredentialsRequest) Reset() { *x = WatchSyncRefreshCredentialsRequest{} - mi := &file_prairie_plugin_v1_watch_sync_provider_proto_msgTypes[10] + mi := &file_prairie_plugin_v1_watch_sync_provider_proto_msgTypes[14] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1076,7 +1590,7 @@ func (x *WatchSyncRefreshCredentialsRequest) String() string { func (*WatchSyncRefreshCredentialsRequest) ProtoMessage() {} func (x *WatchSyncRefreshCredentialsRequest) ProtoReflect() protoreflect.Message { - mi := &file_prairie_plugin_v1_watch_sync_provider_proto_msgTypes[10] + mi := &file_prairie_plugin_v1_watch_sync_provider_proto_msgTypes[14] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1089,7 +1603,7 @@ func (x *WatchSyncRefreshCredentialsRequest) ProtoReflect() protoreflect.Message // Deprecated: Use WatchSyncRefreshCredentialsRequest.ProtoReflect.Descriptor instead. func (*WatchSyncRefreshCredentialsRequest) Descriptor() ([]byte, []int) { - return file_prairie_plugin_v1_watch_sync_provider_proto_rawDescGZIP(), []int{10} + return file_prairie_plugin_v1_watch_sync_provider_proto_rawDescGZIP(), []int{14} } func (x *WatchSyncRefreshCredentialsRequest) GetContext() *WatchSyncAuthenticatedContext { @@ -1114,7 +1628,7 @@ type WatchSyncCredentialResponse struct { func (x *WatchSyncCredentialResponse) Reset() { *x = WatchSyncCredentialResponse{} - mi := &file_prairie_plugin_v1_watch_sync_provider_proto_msgTypes[11] + mi := &file_prairie_plugin_v1_watch_sync_provider_proto_msgTypes[15] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1126,7 +1640,7 @@ func (x *WatchSyncCredentialResponse) String() string { func (*WatchSyncCredentialResponse) ProtoMessage() {} func (x *WatchSyncCredentialResponse) ProtoReflect() protoreflect.Message { - mi := &file_prairie_plugin_v1_watch_sync_provider_proto_msgTypes[11] + mi := &file_prairie_plugin_v1_watch_sync_provider_proto_msgTypes[15] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1139,7 +1653,7 @@ func (x *WatchSyncCredentialResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use WatchSyncCredentialResponse.ProtoReflect.Descriptor instead. func (*WatchSyncCredentialResponse) Descriptor() ([]byte, []int) { - return file_prairie_plugin_v1_watch_sync_provider_proto_rawDescGZIP(), []int{11} + return file_prairie_plugin_v1_watch_sync_provider_proto_rawDescGZIP(), []int{15} } func (x *WatchSyncCredentialResponse) GetCredentials() *WatchSyncCredentials { @@ -1172,7 +1686,7 @@ type WatchSyncGetAccountRequest struct { func (x *WatchSyncGetAccountRequest) Reset() { *x = WatchSyncGetAccountRequest{} - mi := &file_prairie_plugin_v1_watch_sync_provider_proto_msgTypes[12] + mi := &file_prairie_plugin_v1_watch_sync_provider_proto_msgTypes[16] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1184,7 +1698,7 @@ func (x *WatchSyncGetAccountRequest) String() string { func (*WatchSyncGetAccountRequest) ProtoMessage() {} func (x *WatchSyncGetAccountRequest) ProtoReflect() protoreflect.Message { - mi := &file_prairie_plugin_v1_watch_sync_provider_proto_msgTypes[12] + mi := &file_prairie_plugin_v1_watch_sync_provider_proto_msgTypes[16] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1197,7 +1711,7 @@ func (x *WatchSyncGetAccountRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use WatchSyncGetAccountRequest.ProtoReflect.Descriptor instead. func (*WatchSyncGetAccountRequest) Descriptor() ([]byte, []int) { - return file_prairie_plugin_v1_watch_sync_provider_proto_rawDescGZIP(), []int{12} + return file_prairie_plugin_v1_watch_sync_provider_proto_rawDescGZIP(), []int{16} } func (x *WatchSyncGetAccountRequest) GetContext() *WatchSyncAuthenticatedContext { @@ -1217,7 +1731,7 @@ type WatchSyncGetAccountResponse struct { func (x *WatchSyncGetAccountResponse) Reset() { *x = WatchSyncGetAccountResponse{} - mi := &file_prairie_plugin_v1_watch_sync_provider_proto_msgTypes[13] + mi := &file_prairie_plugin_v1_watch_sync_provider_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1229,7 +1743,7 @@ func (x *WatchSyncGetAccountResponse) String() string { func (*WatchSyncGetAccountResponse) ProtoMessage() {} func (x *WatchSyncGetAccountResponse) ProtoReflect() protoreflect.Message { - mi := &file_prairie_plugin_v1_watch_sync_provider_proto_msgTypes[13] + mi := &file_prairie_plugin_v1_watch_sync_provider_proto_msgTypes[17] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1242,7 +1756,7 @@ func (x *WatchSyncGetAccountResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use WatchSyncGetAccountResponse.ProtoReflect.Descriptor instead. func (*WatchSyncGetAccountResponse) Descriptor() ([]byte, []int) { - return file_prairie_plugin_v1_watch_sync_provider_proto_rawDescGZIP(), []int{13} + return file_prairie_plugin_v1_watch_sync_provider_proto_rawDescGZIP(), []int{17} } func (x *WatchSyncGetAccountResponse) GetAccount() *WatchSyncAccount { @@ -1282,7 +1796,7 @@ type WatchSyncMedia struct { func (x *WatchSyncMedia) Reset() { *x = WatchSyncMedia{} - mi := &file_prairie_plugin_v1_watch_sync_provider_proto_msgTypes[14] + mi := &file_prairie_plugin_v1_watch_sync_provider_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1294,7 +1808,7 @@ func (x *WatchSyncMedia) String() string { func (*WatchSyncMedia) ProtoMessage() {} func (x *WatchSyncMedia) ProtoReflect() protoreflect.Message { - mi := &file_prairie_plugin_v1_watch_sync_provider_proto_msgTypes[14] + mi := &file_prairie_plugin_v1_watch_sync_provider_proto_msgTypes[18] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1307,7 +1821,7 @@ func (x *WatchSyncMedia) ProtoReflect() protoreflect.Message { // Deprecated: Use WatchSyncMedia.ProtoReflect.Descriptor instead. func (*WatchSyncMedia) Descriptor() ([]byte, []int) { - return file_prairie_plugin_v1_watch_sync_provider_proto_rawDescGZIP(), []int{14} + return file_prairie_plugin_v1_watch_sync_provider_proto_rawDescGZIP(), []int{18} } func (x *WatchSyncMedia) GetMediaItemId() string { @@ -1429,13 +1943,24 @@ type WatchSyncEvent struct { DurationSeconds float64 `protobuf:"fixed64,9,opt,name=duration_seconds,json=durationSeconds,proto3" json:"duration_seconds,omitempty"` CompletionPercent float64 `protobuf:"fixed64,10,opt,name=completion_percent,json=completionPercent,proto3" json:"completion_percent,omitempty"` PlayCount int32 `protobuf:"varint,11,opt,name=play_count,json=playCount,proto3" json:"play_count,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + // Optional zero-based position for list providers that accept explicit + // ordering. Providers may ignore it unless their API supports order writes. + ListPosition *int32 `protobuf:"varint,12,opt,name=list_position,json=listPosition,proto3,oneof" json:"list_position,omitempty"` + // Provider-native key previously returned by ListRemoteState. It lets a + // removal address the exact upstream record when external IDs are absent or + // no longer resolve. + ProviderItemKey string `protobuf:"bytes,13,opt,name=provider_item_key,json=providerItemKey,proto3" json:"provider_item_key,omitempty"` + // Authoritative host completion state for playback events. A history ID can + // exist for incomplete playback, and completion_percent may be below 100 + // when the host's configured watched threshold has been reached. + Completed bool `protobuf:"varint,14,opt,name=completed,proto3" json:"completed,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *WatchSyncEvent) Reset() { *x = WatchSyncEvent{} - mi := &file_prairie_plugin_v1_watch_sync_provider_proto_msgTypes[15] + mi := &file_prairie_plugin_v1_watch_sync_provider_proto_msgTypes[19] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1447,7 +1972,7 @@ func (x *WatchSyncEvent) String() string { func (*WatchSyncEvent) ProtoMessage() {} func (x *WatchSyncEvent) ProtoReflect() protoreflect.Message { - mi := &file_prairie_plugin_v1_watch_sync_provider_proto_msgTypes[15] + mi := &file_prairie_plugin_v1_watch_sync_provider_proto_msgTypes[19] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1460,7 +1985,7 @@ func (x *WatchSyncEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use WatchSyncEvent.ProtoReflect.Descriptor instead. func (*WatchSyncEvent) Descriptor() ([]byte, []int) { - return file_prairie_plugin_v1_watch_sync_provider_proto_rawDescGZIP(), []int{15} + return file_prairie_plugin_v1_watch_sync_provider_proto_rawDescGZIP(), []int{19} } func (x *WatchSyncEvent) GetEventId() string { @@ -1540,6 +2065,27 @@ func (x *WatchSyncEvent) GetPlayCount() int32 { return 0 } +func (x *WatchSyncEvent) GetListPosition() int32 { + if x != nil && x.ListPosition != nil { + return *x.ListPosition + } + return 0 +} + +func (x *WatchSyncEvent) GetProviderItemKey() string { + if x != nil { + return x.ProviderItemKey + } + return "" +} + +func (x *WatchSyncEvent) GetCompleted() bool { + if x != nil { + return x.Completed + } + return false +} + type WatchSyncApplyEventsRequest struct { state protoimpl.MessageState `protogen:"open.v1"` Context *WatchSyncAuthenticatedContext `protobuf:"bytes,1,opt,name=context,proto3" json:"context,omitempty"` @@ -1552,7 +2098,7 @@ type WatchSyncApplyEventsRequest struct { func (x *WatchSyncApplyEventsRequest) Reset() { *x = WatchSyncApplyEventsRequest{} - mi := &file_prairie_plugin_v1_watch_sync_provider_proto_msgTypes[16] + mi := &file_prairie_plugin_v1_watch_sync_provider_proto_msgTypes[20] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1564,7 +2110,7 @@ func (x *WatchSyncApplyEventsRequest) String() string { func (*WatchSyncApplyEventsRequest) ProtoMessage() {} func (x *WatchSyncApplyEventsRequest) ProtoReflect() protoreflect.Message { - mi := &file_prairie_plugin_v1_watch_sync_provider_proto_msgTypes[16] + mi := &file_prairie_plugin_v1_watch_sync_provider_proto_msgTypes[20] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1577,7 +2123,7 @@ func (x *WatchSyncApplyEventsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use WatchSyncApplyEventsRequest.ProtoReflect.Descriptor instead. func (*WatchSyncApplyEventsRequest) Descriptor() ([]byte, []int) { - return file_prairie_plugin_v1_watch_sync_provider_proto_rawDescGZIP(), []int{16} + return file_prairie_plugin_v1_watch_sync_provider_proto_rawDescGZIP(), []int{20} } func (x *WatchSyncApplyEventsRequest) GetContext() *WatchSyncAuthenticatedContext { @@ -1609,7 +2155,7 @@ type WatchSyncApplyResult struct { func (x *WatchSyncApplyResult) Reset() { *x = WatchSyncApplyResult{} - mi := &file_prairie_plugin_v1_watch_sync_provider_proto_msgTypes[17] + mi := &file_prairie_plugin_v1_watch_sync_provider_proto_msgTypes[21] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1621,7 +2167,7 @@ func (x *WatchSyncApplyResult) String() string { func (*WatchSyncApplyResult) ProtoMessage() {} func (x *WatchSyncApplyResult) ProtoReflect() protoreflect.Message { - mi := &file_prairie_plugin_v1_watch_sync_provider_proto_msgTypes[17] + mi := &file_prairie_plugin_v1_watch_sync_provider_proto_msgTypes[21] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1634,7 +2180,7 @@ func (x *WatchSyncApplyResult) ProtoReflect() protoreflect.Message { // Deprecated: Use WatchSyncApplyResult.ProtoReflect.Descriptor instead. func (*WatchSyncApplyResult) Descriptor() ([]byte, []int) { - return file_prairie_plugin_v1_watch_sync_provider_proto_rawDescGZIP(), []int{17} + return file_prairie_plugin_v1_watch_sync_provider_proto_rawDescGZIP(), []int{21} } func (x *WatchSyncApplyResult) GetEventId() string { @@ -1673,7 +2219,7 @@ type WatchSyncApplyEventsResponse struct { func (x *WatchSyncApplyEventsResponse) Reset() { *x = WatchSyncApplyEventsResponse{} - mi := &file_prairie_plugin_v1_watch_sync_provider_proto_msgTypes[18] + mi := &file_prairie_plugin_v1_watch_sync_provider_proto_msgTypes[22] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1685,7 +2231,7 @@ func (x *WatchSyncApplyEventsResponse) String() string { func (*WatchSyncApplyEventsResponse) ProtoMessage() {} func (x *WatchSyncApplyEventsResponse) ProtoReflect() protoreflect.Message { - mi := &file_prairie_plugin_v1_watch_sync_provider_proto_msgTypes[18] + mi := &file_prairie_plugin_v1_watch_sync_provider_proto_msgTypes[22] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1698,7 +2244,7 @@ func (x *WatchSyncApplyEventsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use WatchSyncApplyEventsResponse.ProtoReflect.Descriptor instead. func (*WatchSyncApplyEventsResponse) Descriptor() ([]byte, []int) { - return file_prairie_plugin_v1_watch_sync_provider_proto_rawDescGZIP(), []int{18} + return file_prairie_plugin_v1_watch_sync_provider_proto_rawDescGZIP(), []int{22} } func (x *WatchSyncApplyEventsResponse) GetResults() []*WatchSyncApplyResult { @@ -1734,14 +2280,17 @@ type WatchSyncListRemoteStateRequest struct { // after the traversal completes or fails. PageToken string `protobuf:"bytes,3,opt,name=page_token,json=pageToken,proto3" json:"page_token,omitempty"` // Requested maximum number of items. Plugins may return fewer. - PageSize int32 `protobuf:"varint,4,opt,name=page_size,json=pageSize,proto3" json:"page_size,omitempty"` + PageSize int32 `protobuf:"varint,4,opt,name=page_size,json=pageSize,proto3" json:"page_size,omitempty"` + // State families requested by the host. Empty means every family advertised + // by the descriptor, preserving compatibility with v0.12 hosts and plugins. + StateKinds []WatchSyncRemoteStateKind `protobuf:"varint,5,rep,packed,name=state_kinds,json=stateKinds,proto3,enum=prairie.plugin.v1.WatchSyncRemoteStateKind" json:"state_kinds,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } func (x *WatchSyncListRemoteStateRequest) Reset() { *x = WatchSyncListRemoteStateRequest{} - mi := &file_prairie_plugin_v1_watch_sync_provider_proto_msgTypes[19] + mi := &file_prairie_plugin_v1_watch_sync_provider_proto_msgTypes[23] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1753,7 +2302,7 @@ func (x *WatchSyncListRemoteStateRequest) String() string { func (*WatchSyncListRemoteStateRequest) ProtoMessage() {} func (x *WatchSyncListRemoteStateRequest) ProtoReflect() protoreflect.Message { - mi := &file_prairie_plugin_v1_watch_sync_provider_proto_msgTypes[19] + mi := &file_prairie_plugin_v1_watch_sync_provider_proto_msgTypes[23] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1766,7 +2315,7 @@ func (x *WatchSyncListRemoteStateRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use WatchSyncListRemoteStateRequest.ProtoReflect.Descriptor instead. func (*WatchSyncListRemoteStateRequest) Descriptor() ([]byte, []int) { - return file_prairie_plugin_v1_watch_sync_provider_proto_rawDescGZIP(), []int{19} + return file_prairie_plugin_v1_watch_sync_provider_proto_rawDescGZIP(), []int{23} } func (x *WatchSyncListRemoteStateRequest) GetContext() *WatchSyncAuthenticatedContext { @@ -1797,6 +2346,13 @@ func (x *WatchSyncListRemoteStateRequest) GetPageSize() int32 { return 0 } +func (x *WatchSyncListRemoteStateRequest) GetStateKinds() []WatchSyncRemoteStateKind { + if x != nil { + return x.StateKinds + } + return nil +} + type WatchSyncRemoteWatchedState struct { state protoimpl.MessageState `protogen:"open.v1"` // Number of completed plays known to the provider. Must be at least one when @@ -1810,7 +2366,7 @@ type WatchSyncRemoteWatchedState struct { func (x *WatchSyncRemoteWatchedState) Reset() { *x = WatchSyncRemoteWatchedState{} - mi := &file_prairie_plugin_v1_watch_sync_provider_proto_msgTypes[20] + mi := &file_prairie_plugin_v1_watch_sync_provider_proto_msgTypes[24] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1822,7 +2378,7 @@ func (x *WatchSyncRemoteWatchedState) String() string { func (*WatchSyncRemoteWatchedState) ProtoMessage() {} func (x *WatchSyncRemoteWatchedState) ProtoReflect() protoreflect.Message { - mi := &file_prairie_plugin_v1_watch_sync_provider_proto_msgTypes[20] + mi := &file_prairie_plugin_v1_watch_sync_provider_proto_msgTypes[24] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1835,7 +2391,7 @@ func (x *WatchSyncRemoteWatchedState) ProtoReflect() protoreflect.Message { // Deprecated: Use WatchSyncRemoteWatchedState.ProtoReflect.Descriptor instead. func (*WatchSyncRemoteWatchedState) Descriptor() ([]byte, []int) { - return file_prairie_plugin_v1_watch_sync_provider_proto_rawDescGZIP(), []int{20} + return file_prairie_plugin_v1_watch_sync_provider_proto_rawDescGZIP(), []int{24} } func (x *WatchSyncRemoteWatchedState) GetPlayCount() int32 { @@ -1864,7 +2420,7 @@ type WatchSyncRemoteProgressState struct { func (x *WatchSyncRemoteProgressState) Reset() { *x = WatchSyncRemoteProgressState{} - mi := &file_prairie_plugin_v1_watch_sync_provider_proto_msgTypes[21] + mi := &file_prairie_plugin_v1_watch_sync_provider_proto_msgTypes[25] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1876,7 +2432,7 @@ func (x *WatchSyncRemoteProgressState) String() string { func (*WatchSyncRemoteProgressState) ProtoMessage() {} func (x *WatchSyncRemoteProgressState) ProtoReflect() protoreflect.Message { - mi := &file_prairie_plugin_v1_watch_sync_provider_proto_msgTypes[21] + mi := &file_prairie_plugin_v1_watch_sync_provider_proto_msgTypes[25] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1889,7 +2445,7 @@ func (x *WatchSyncRemoteProgressState) ProtoReflect() protoreflect.Message { // Deprecated: Use WatchSyncRemoteProgressState.ProtoReflect.Descriptor instead. func (*WatchSyncRemoteProgressState) Descriptor() ([]byte, []int) { - return file_prairie_plugin_v1_watch_sync_provider_proto_rawDescGZIP(), []int{21} + return file_prairie_plugin_v1_watch_sync_provider_proto_rawDescGZIP(), []int{25} } func (x *WatchSyncRemoteProgressState) GetProgressPercent() float64 { @@ -1906,21 +2462,80 @@ func (x *WatchSyncRemoteProgressState) GetPausedAt() *timestamppb.Timestamp { return nil } +type WatchSyncRemoteListState struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Provider timestamp for when the item was added, when available. + ListedAt *timestamppb.Timestamp `protobuf:"bytes,1,opt,name=listed_at,json=listedAt,proto3" json:"listed_at,omitempty"` + // True is an explicit tombstone. It is meaningful for incremental + // traversals, where omitting an item is not a deletion. + Removed bool `protobuf:"varint,2,opt,name=removed,proto3" json:"removed,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *WatchSyncRemoteListState) Reset() { + *x = WatchSyncRemoteListState{} + mi := &file_prairie_plugin_v1_watch_sync_provider_proto_msgTypes[26] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *WatchSyncRemoteListState) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*WatchSyncRemoteListState) ProtoMessage() {} + +func (x *WatchSyncRemoteListState) ProtoReflect() protoreflect.Message { + mi := &file_prairie_plugin_v1_watch_sync_provider_proto_msgTypes[26] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use WatchSyncRemoteListState.ProtoReflect.Descriptor instead. +func (*WatchSyncRemoteListState) Descriptor() ([]byte, []int) { + return file_prairie_plugin_v1_watch_sync_provider_proto_rawDescGZIP(), []int{26} +} + +func (x *WatchSyncRemoteListState) GetListedAt() *timestamppb.Timestamp { + if x != nil { + return x.ListedAt + } + return nil +} + +func (x *WatchSyncRemoteListState) GetRemoved() bool { + if x != nil { + return x.Removed + } + return false +} + type WatchSyncRemoteState struct { state protoimpl.MessageState `protogen:"open.v1"` ProviderItemKey string `protobuf:"bytes,1,opt,name=provider_item_key,json=providerItemKey,proto3" json:"provider_item_key,omitempty"` - Media *WatchSyncMedia `protobuf:"bytes,2,opt,name=media,proto3" json:"media,omitempty"` + // Required except on an explicit favorite/watchlist tombstone whose + // provider_item_key identifies a record returned previously. + Media *WatchSyncMedia `protobuf:"bytes,2,opt,name=media,proto3" json:"media,omitempty"` // At least one typed state must be present. Both may be present when the // provider reports a completed play and a separate resume point. Watched *WatchSyncRemoteWatchedState `protobuf:"bytes,3,opt,name=watched,proto3" json:"watched,omitempty"` Progress *WatchSyncRemoteProgressState `protobuf:"bytes,4,opt,name=progress,proto3" json:"progress,omitempty"` + Favorite *WatchSyncRemoteListState `protobuf:"bytes,5,opt,name=favorite,proto3" json:"favorite,omitempty"` + Watchlist *WatchSyncRemoteListState `protobuf:"bytes,6,opt,name=watchlist,proto3" json:"watchlist,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } func (x *WatchSyncRemoteState) Reset() { *x = WatchSyncRemoteState{} - mi := &file_prairie_plugin_v1_watch_sync_provider_proto_msgTypes[22] + mi := &file_prairie_plugin_v1_watch_sync_provider_proto_msgTypes[27] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1932,7 +2547,7 @@ func (x *WatchSyncRemoteState) String() string { func (*WatchSyncRemoteState) ProtoMessage() {} func (x *WatchSyncRemoteState) ProtoReflect() protoreflect.Message { - mi := &file_prairie_plugin_v1_watch_sync_provider_proto_msgTypes[22] + mi := &file_prairie_plugin_v1_watch_sync_provider_proto_msgTypes[27] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1945,7 +2560,7 @@ func (x *WatchSyncRemoteState) ProtoReflect() protoreflect.Message { // Deprecated: Use WatchSyncRemoteState.ProtoReflect.Descriptor instead. func (*WatchSyncRemoteState) Descriptor() ([]byte, []int) { - return file_prairie_plugin_v1_watch_sync_provider_proto_rawDescGZIP(), []int{22} + return file_prairie_plugin_v1_watch_sync_provider_proto_rawDescGZIP(), []int{27} } func (x *WatchSyncRemoteState) GetProviderItemKey() string { @@ -1976,6 +2591,20 @@ func (x *WatchSyncRemoteState) GetProgress() *WatchSyncRemoteProgressState { return nil } +func (x *WatchSyncRemoteState) GetFavorite() *WatchSyncRemoteListState { + if x != nil { + return x.Favorite + } + return nil +} + +func (x *WatchSyncRemoteState) GetWatchlist() *WatchSyncRemoteListState { + if x != nil { + return x.Watchlist + } + return nil +} + type WatchSyncListRemoteStateResponse struct { state protoimpl.MessageState `protogen:"open.v1"` Items []*WatchSyncRemoteState `protobuf:"bytes,1,rep,name=items,proto3" json:"items,omitempty"` @@ -1987,7 +2616,9 @@ type WatchSyncListRemoteStateResponse struct { NextCursor string `protobuf:"bytes,3,opt,name=next_cursor,json=nextCursor,proto3" json:"next_cursor,omitempty"` // True when this traversal is an authoritative full snapshot. False means an // incremental delta, so an absent item must not be interpreted as deletion. - // The value must remain stable across every page in one traversal. + // The value must remain stable across every page in one traversal. A provider + // advertising provides_watchlist_order must set this true for WATCHLIST + // traversals so the returned order is unambiguous. CompleteSnapshot bool `protobuf:"varint,4,opt,name=complete_snapshot,json=completeSnapshot,proto3" json:"complete_snapshot,omitempty"` // Complete authoritative replacement. The host persists it before consuming // this page or fault; a persistence failure discards the page and cursor. @@ -2002,7 +2633,7 @@ type WatchSyncListRemoteStateResponse struct { func (x *WatchSyncListRemoteStateResponse) Reset() { *x = WatchSyncListRemoteStateResponse{} - mi := &file_prairie_plugin_v1_watch_sync_provider_proto_msgTypes[23] + mi := &file_prairie_plugin_v1_watch_sync_provider_proto_msgTypes[28] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2014,7 +2645,7 @@ func (x *WatchSyncListRemoteStateResponse) String() string { func (*WatchSyncListRemoteStateResponse) ProtoMessage() {} func (x *WatchSyncListRemoteStateResponse) ProtoReflect() protoreflect.Message { - mi := &file_prairie_plugin_v1_watch_sync_provider_proto_msgTypes[23] + mi := &file_prairie_plugin_v1_watch_sync_provider_proto_msgTypes[28] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2027,7 +2658,7 @@ func (x *WatchSyncListRemoteStateResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use WatchSyncListRemoteStateResponse.ProtoReflect.Descriptor instead. func (*WatchSyncListRemoteStateResponse) Descriptor() ([]byte, []int) { - return file_prairie_plugin_v1_watch_sync_provider_proto_rawDescGZIP(), []int{23} + return file_prairie_plugin_v1_watch_sync_provider_proto_rawDescGZIP(), []int{28} } func (x *WatchSyncListRemoteStateResponse) GetItems() []*WatchSyncRemoteState { @@ -2076,7 +2707,7 @@ var File_prairie_plugin_v1_watch_sync_provider_proto protoreflect.FileDescriptor const file_prairie_plugin_v1_watch_sync_provider_proto_rawDesc = "" + "\n" + - "+prairie/plugin/v1/watch_sync_provider.proto\x12\x11prairie.plugin.v1\x1a\x1egoogle/protobuf/duration.proto\x1a\x1cgoogle/protobuf/struct.proto\x1a\x1fgoogle/protobuf/timestamp.proto\"\xc1\x03\n" + + "+prairie/plugin/v1/watch_sync_provider.proto\x12\x11prairie.plugin.v1\x1a\x1egoogle/protobuf/duration.proto\x1a\x1cgoogle/protobuf/struct.proto\x1a\x1fgoogle/protobuf/timestamp.proto\"\xaa\x06\n" + "\x1bWatchSyncProviderDescriptor\x12I\n" + "\fauth_methods\x18\x01 \x03(\x0e2&.prairie.plugin.v1.WatchSyncAuthMethodR\vauthMethods\x12%\n" + "\x0eexport_watched\x18\x02 \x01(\bR\rexportWatched\x12)\n" + @@ -2085,7 +2716,16 @@ const file_prairie_plugin_v1_watch_sync_provider_proto_rawDesc = "" + "\x0fimport_progress\x18\x05 \x01(\bR\x0eimportProgress\x12Y\n" + "\x15supported_media_types\x18\x06 \x03(\x0e2%.prairie.plugin.v1.WatchSyncMediaTypeR\x13supportedMediaTypes\x124\n" + "\x16external_id_namespaces\x18\a \x03(\tR\x14externalIdNamespaces\x12$\n" + - "\x0emax_batch_size\x18\b \x01(\x05R\fmaxBatchSize\"\xc8\x02\n" + + "\x0emax_batch_size\x18\b \x01(\x05R\fmaxBatchSize\x12)\n" + + "\x10import_favorites\x18\t \x01(\bR\x0fimportFavorites\x12)\n" + + "\x10export_favorites\x18\n" + + " \x01(\bR\x0fexportFavorites\x12)\n" + + "\x10remove_favorites\x18\v \x01(\bR\x0fremoveFavorites\x12)\n" + + "\x10import_watchlist\x18\f \x01(\bR\x0fimportWatchlist\x12)\n" + + "\x10export_watchlist\x18\r \x01(\bR\x0fexportWatchlist\x12)\n" + + "\x10remove_watchlist\x18\x0e \x01(\bR\x0fremoveWatchlist\x128\n" + + "\x18provides_watchlist_order\x18\x0f \x01(\bR\x16providesWatchlistOrder\x12+\n" + + "\x11scrobble_playback\x18\x10 \x01(\bR\x10scrobblePlayback\"\xc8\x02\n" + "\x17WatchSyncProviderConfig\x12N\n" + "\x06values\x18\x01 \x03(\v26.prairie.plugin.v1.WatchSyncProviderConfig.ValuesEntryR\x06values\x12a\n" + "\rsecret_values\x18\x02 \x03(\v2<.prairie.plugin.v1.WatchSyncProviderConfig.SecretValuesEntryR\fsecretValues\x1a9\n" + @@ -2142,7 +2782,33 @@ const file_prairie_plugin_v1_watch_sync_provider_proto_rawDesc = "" + "\x1eWatchSyncExchangeAPIKeyRequest\x12#\n" + "\rcapability_id\x18\x01 \x01(\tR\fcapabilityId\x12S\n" + "\x0fprovider_config\x18\x02 \x01(\v2*.prairie.plugin.v1.WatchSyncProviderConfigR\x0eproviderConfig\x12\x17\n" + - "\aapi_key\x18\x03 \x01(\tR\x06apiKey\"p\n" + + "\aapi_key\x18\x03 \x01(\tR\x06apiKey\"\xab\x01\n" + + "/WatchSyncDeviceAuthorizationServiceStartRequest\x12#\n" + + "\rcapability_id\x18\x01 \x01(\tR\fcapabilityId\x12S\n" + + "\x0fprovider_config\x18\x02 \x01(\v2*.prairie.plugin.v1.WatchSyncProviderConfigR\x0eproviderConfig\"\x97\x03\n" + + "0WatchSyncDeviceAuthorizationServiceStartResponse\x12\x1b\n" + + "\tuser_code\x18\x01 \x01(\tR\buserCode\x12)\n" + + "\x10verification_url\x18\x02 \x01(\tR\x0fverificationUrl\x12:\n" + + "\x19verification_url_complete\x18\x03 \x01(\tR\x17verificationUrlComplete\x12%\n" + + "\x0eprovider_state\x18\x04 \x01(\fR\rproviderState\x12D\n" + + "\x10polling_interval\x18\x05 \x01(\v2\x19.google.protobuf.DurationR\x0fpollingInterval\x129\n" + + "\n" + + "expires_at\x18\x06 \x01(\v2\x1a.google.protobuf.TimestampR\texpiresAt\x127\n" + + "\x05fault\x18\a \x01(\v2!.prairie.plugin.v1.WatchSyncFaultR\x05fault\"\xd1\x01\n" + + ".WatchSyncDeviceAuthorizationServicePollRequest\x12#\n" + + "\rcapability_id\x18\x01 \x01(\tR\fcapabilityId\x12S\n" + + "\x0fprovider_config\x18\x02 \x01(\v2*.prairie.plugin.v1.WatchSyncProviderConfigR\x0eproviderConfig\x12%\n" + + "\x0eprovider_state\x18\x03 \x01(\fR\rproviderState\"\x83\x04\n" + + "/WatchSyncDeviceAuthorizationServicePollResponse\x12M\n" + + "\x06status\x18\x01 \x01(\x0e25.prairie.plugin.v1.WatchSyncDeviceAuthorizationStatusR\x06status\x12I\n" + + "\vcredentials\x18\x02 \x01(\v2'.prairie.plugin.v1.WatchSyncCredentialsR\vcredentials\x12=\n" + + "\aaccount\x18\x03 \x01(\v2#.prairie.plugin.v1.WatchSyncAccountR\aaccount\x127\n" + + "\x05fault\x18\x04 \x01(\v2!.prairie.plugin.v1.WatchSyncFaultR\x05fault\x12*\n" + + "\x0eprovider_state\x18\x05 \x01(\fH\x00R\rproviderState\x88\x01\x01\x12D\n" + + "\x10polling_interval\x18\x06 \x01(\v2\x19.google.protobuf.DurationR\x0fpollingInterval\x129\n" + + "\n" + + "expires_at\x18\a \x01(\v2\x1a.google.protobuf.TimestampR\texpiresAtB\x11\n" + + "\x0f_provider_state\"p\n" + "\"WatchSyncRefreshCredentialsRequest\x12J\n" + "\acontext\x18\x01 \x01(\v20.prairie.plugin.v1.WatchSyncAuthenticatedContextR\acontext\"\xe0\x01\n" + "\x1bWatchSyncCredentialResponse\x12I\n" + @@ -2178,7 +2844,7 @@ const file_prairie_plugin_v1_watch_sync_provider_proto_rawDesc = "" + "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\x1aD\n" + "\x16SeriesExternalIdsEntry\x12\x10\n" + "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + - "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\"\xa0\x04\n" + + "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\"\xa6\x05\n" + "\x0eWatchSyncEvent\x12\x19\n" + "\bevent_id\x18\x01 \x01(\tR\aeventId\x12C\n" + "\toperation\x18\x02 \x01(\x0e2%.prairie.plugin.v1.WatchSyncOperationR\toperation\x12:\n" + @@ -2193,7 +2859,11 @@ const file_prairie_plugin_v1_watch_sync_provider_proto_rawDesc = "" + "\x12completion_percent\x18\n" + " \x01(\x01R\x11completionPercent\x12\x1d\n" + "\n" + - "play_count\x18\v \x01(\x05R\tplayCount\"\xa4\x01\n" + + "play_count\x18\v \x01(\x05R\tplayCount\x12(\n" + + "\rlist_position\x18\f \x01(\x05H\x00R\flistPosition\x88\x01\x01\x12*\n" + + "\x11provider_item_key\x18\r \x01(\tR\x0fproviderItemKey\x12\x1c\n" + + "\tcompleted\x18\x0e \x01(\bR\tcompletedB\x10\n" + + "\x0e_list_position\"\xa4\x01\n" + "\x1bWatchSyncApplyEventsRequest\x12J\n" + "\acontext\x18\x01 \x01(\v20.prairie.plugin.v1.WatchSyncAuthenticatedContextR\acontext\x129\n" + "\x06events\x18\x02 \x03(\v2!.prairie.plugin.v1.WatchSyncEventR\x06events\"\xab\x01\n" + @@ -2204,25 +2874,32 @@ const file_prairie_plugin_v1_watch_sync_provider_proto_rawDesc = "" + "\x1cWatchSyncApplyEventsResponse\x12A\n" + "\aresults\x18\x01 \x03(\v2'.prairie.plugin.v1.WatchSyncApplyResultR\aresults\x12X\n" + "\x13updated_credentials\x18\x02 \x01(\v2'.prairie.plugin.v1.WatchSyncCredentialsR\x12updatedCredentials\x127\n" + - "\x05fault\x18\x03 \x01(\v2!.prairie.plugin.v1.WatchSyncFaultR\x05fault\"\xc1\x01\n" + + "\x05fault\x18\x03 \x01(\v2!.prairie.plugin.v1.WatchSyncFaultR\x05fault\"\x8f\x02\n" + "\x1fWatchSyncListRemoteStateRequest\x12J\n" + "\acontext\x18\x01 \x01(\v20.prairie.plugin.v1.WatchSyncAuthenticatedContextR\acontext\x12\x16\n" + "\x06cursor\x18\x02 \x01(\tR\x06cursor\x12\x1d\n" + "\n" + "page_token\x18\x03 \x01(\tR\tpageToken\x12\x1b\n" + - "\tpage_size\x18\x04 \x01(\x05R\bpageSize\"\x80\x01\n" + + "\tpage_size\x18\x04 \x01(\x05R\bpageSize\x12L\n" + + "\vstate_kinds\x18\x05 \x03(\x0e2+.prairie.plugin.v1.WatchSyncRemoteStateKindR\n" + + "stateKinds\"\x80\x01\n" + "\x1bWatchSyncRemoteWatchedState\x12\x1d\n" + "\n" + "play_count\x18\x01 \x01(\x05R\tplayCount\x12B\n" + "\x0flast_watched_at\x18\x02 \x01(\v2\x1a.google.protobuf.TimestampR\rlastWatchedAt\"\x82\x01\n" + "\x1cWatchSyncRemoteProgressState\x12)\n" + "\x10progress_percent\x18\x01 \x01(\x01R\x0fprogressPercent\x127\n" + - "\tpaused_at\x18\x02 \x01(\v2\x1a.google.protobuf.TimestampR\bpausedAt\"\x92\x02\n" + + "\tpaused_at\x18\x02 \x01(\v2\x1a.google.protobuf.TimestampR\bpausedAt\"m\n" + + "\x18WatchSyncRemoteListState\x127\n" + + "\tlisted_at\x18\x01 \x01(\v2\x1a.google.protobuf.TimestampR\blistedAt\x12\x18\n" + + "\aremoved\x18\x02 \x01(\bR\aremoved\"\xa6\x03\n" + "\x14WatchSyncRemoteState\x12*\n" + "\x11provider_item_key\x18\x01 \x01(\tR\x0fproviderItemKey\x127\n" + "\x05media\x18\x02 \x01(\v2!.prairie.plugin.v1.WatchSyncMediaR\x05media\x12H\n" + "\awatched\x18\x03 \x01(\v2..prairie.plugin.v1.WatchSyncRemoteWatchedStateR\awatched\x12K\n" + - "\bprogress\x18\x04 \x01(\v2/.prairie.plugin.v1.WatchSyncRemoteProgressStateR\bprogress\"\xea\x02\n" + + "\bprogress\x18\x04 \x01(\v2/.prairie.plugin.v1.WatchSyncRemoteProgressStateR\bprogress\x12G\n" + + "\bfavorite\x18\x05 \x01(\v2+.prairie.plugin.v1.WatchSyncRemoteListStateR\bfavorite\x12I\n" + + "\twatchlist\x18\x06 \x01(\v2+.prairie.plugin.v1.WatchSyncRemoteListStateR\twatchlist\"\xea\x02\n" + " WatchSyncListRemoteStateResponse\x12=\n" + "\x05items\x18\x01 \x03(\v2'.prairie.plugin.v1.WatchSyncRemoteStateR\x05items\x12&\n" + "\x0fnext_page_token\x18\x02 \x01(\tR\rnextPageToken\x12\x1f\n" + @@ -2230,19 +2907,39 @@ const file_prairie_plugin_v1_watch_sync_provider_proto_rawDesc = "" + "nextCursor\x12+\n" + "\x11complete_snapshot\x18\x04 \x01(\bR\x10completeSnapshot\x12X\n" + "\x13updated_credentials\x18\x05 \x01(\v2'.prairie.plugin.v1.WatchSyncCredentialsR\x12updatedCredentials\x127\n" + - "\x05fault\x18\x06 \x01(\v2!.prairie.plugin.v1.WatchSyncFaultR\x05fault*\x90\x01\n" + + "\x05fault\x18\x06 \x01(\v2!.prairie.plugin.v1.WatchSyncFaultR\x05fault*\xb8\x01\n" + "\x13WatchSyncAuthMethod\x12&\n" + "\"WATCH_SYNC_AUTH_METHOD_UNSPECIFIED\x10\x00\x12-\n" + ")WATCH_SYNC_AUTH_METHOD_AUTHORIZATION_CODE\x10\x01\x12\"\n" + - "\x1eWATCH_SYNC_AUTH_METHOD_API_KEY\x10\x02*\x7f\n" + + "\x1eWATCH_SYNC_AUTH_METHOD_API_KEY\x10\x02\x12&\n" + + "\"WATCH_SYNC_AUTH_METHOD_DEVICE_CODE\x10\x03*\x7f\n" + "\x12WatchSyncMediaType\x12%\n" + "!WATCH_SYNC_MEDIA_TYPE_UNSPECIFIED\x10\x00\x12\x1f\n" + "\x1bWATCH_SYNC_MEDIA_TYPE_MOVIE\x10\x01\x12!\n" + - "\x1dWATCH_SYNC_MEDIA_TYPE_EPISODE\x10\x02*\x8a\x01\n" + + "\x1dWATCH_SYNC_MEDIA_TYPE_EPISODE\x10\x02*\xb0\x03\n" + "\x12WatchSyncOperation\x12$\n" + " WATCH_SYNC_OPERATION_UNSPECIFIED\x10\x00\x12%\n" + "!WATCH_SYNC_OPERATION_MARK_WATCHED\x10\x01\x12'\n" + - "#WATCH_SYNC_OPERATION_MARK_UNWATCHED\x10\x02*\xa3\x01\n" + + "#WATCH_SYNC_OPERATION_MARK_UNWATCHED\x10\x02\x12%\n" + + "!WATCH_SYNC_OPERATION_ADD_FAVORITE\x10\x03\x12(\n" + + "$WATCH_SYNC_OPERATION_REMOVE_FAVORITE\x10\x04\x12)\n" + + "%WATCH_SYNC_OPERATION_ADD_TO_WATCHLIST\x10\x05\x12.\n" + + "*WATCH_SYNC_OPERATION_REMOVE_FROM_WATCHLIST\x10\x06\x12'\n" + + "#WATCH_SYNC_OPERATION_SCROBBLE_START\x10\a\x12'\n" + + "#WATCH_SYNC_OPERATION_SCROBBLE_PAUSE\x10\b\x12&\n" + + "\"WATCH_SYNC_OPERATION_SCROBBLE_STOP\x10\t*\xf4\x01\n" + + "\x18WatchSyncRemoteStateKind\x12,\n" + + "(WATCH_SYNC_REMOTE_STATE_KIND_UNSPECIFIED\x10\x00\x12(\n" + + "$WATCH_SYNC_REMOTE_STATE_KIND_WATCHED\x10\x01\x12)\n" + + "%WATCH_SYNC_REMOTE_STATE_KIND_PROGRESS\x10\x02\x12)\n" + + "%WATCH_SYNC_REMOTE_STATE_KIND_FAVORITE\x10\x03\x12*\n" + + "&WATCH_SYNC_REMOTE_STATE_KIND_WATCHLIST\x10\x04*\xae\x02\n" + + "\"WatchSyncDeviceAuthorizationStatus\x126\n" + + "2WATCH_SYNC_DEVICE_AUTHORIZATION_STATUS_UNSPECIFIED\x10\x00\x122\n" + + ".WATCH_SYNC_DEVICE_AUTHORIZATION_STATUS_PENDING\x10\x01\x125\n" + + "1WATCH_SYNC_DEVICE_AUTHORIZATION_STATUS_AUTHORIZED\x10\x02\x121\n" + + "-WATCH_SYNC_DEVICE_AUTHORIZATION_STATUS_DENIED\x10\x03\x122\n" + + ".WATCH_SYNC_DEVICE_AUTHORIZATION_STATUS_EXPIRED\x10\x04*\xa3\x01\n" + "\x0fWatchSyncOrigin\x12!\n" + "\x1dWATCH_SYNC_ORIGIN_UNSPECIFIED\x10\x00\x12)\n" + "%WATCH_SYNC_ORIGIN_PLAYBACK_COMPLETION\x10\x01\x12\x1c\n" + @@ -2270,7 +2967,10 @@ const file_prairie_plugin_v1_watch_sync_provider_proto_rawDesc = "" + "\n" + "GetAccount\x12-.prairie.plugin.v1.WatchSyncGetAccountRequest\x1a..prairie.plugin.v1.WatchSyncGetAccountResponse\x12n\n" + "\vApplyEvents\x12..prairie.plugin.v1.WatchSyncApplyEventsRequest\x1a/.prairie.plugin.v1.WatchSyncApplyEventsResponse\x12z\n" + - "\x0fListRemoteState\x122.prairie.plugin.v1.WatchSyncListRemoteStateRequest\x1a3.prairie.plugin.v1.WatchSyncListRemoteStateResponseBYZWgithub.com/prairie-server/prairie-plugin-sdk/pkg/pluginproto/prairie/plugin/v1;pluginv1b\x06proto3" + "\x0fListRemoteState\x122.prairie.plugin.v1.WatchSyncListRemoteStateRequest\x1a3.prairie.plugin.v1.WatchSyncListRemoteStateResponse2\xc8\x02\n" + + "#WatchSyncDeviceAuthorizationService\x12\x90\x01\n" + + "\x05Start\x12B.prairie.plugin.v1.WatchSyncDeviceAuthorizationServiceStartRequest\x1aC.prairie.plugin.v1.WatchSyncDeviceAuthorizationServiceStartResponse\x12\x8d\x01\n" + + "\x04Poll\x12A.prairie.plugin.v1.WatchSyncDeviceAuthorizationServicePollRequest\x1aB.prairie.plugin.v1.WatchSyncDeviceAuthorizationServicePollResponseBYZWgithub.com/prairie-server/prairie-plugin-sdk/pkg/pluginproto/prairie/plugin/v1;pluginv1b\x06proto3" var ( file_prairie_plugin_v1_watch_sync_provider_proto_rawDescOnce sync.Once @@ -2284,113 +2984,139 @@ func file_prairie_plugin_v1_watch_sync_provider_proto_rawDescGZIP() []byte { return file_prairie_plugin_v1_watch_sync_provider_proto_rawDescData } -var file_prairie_plugin_v1_watch_sync_provider_proto_enumTypes = make([]protoimpl.EnumInfo, 6) -var file_prairie_plugin_v1_watch_sync_provider_proto_msgTypes = make([]protoimpl.MessageInfo, 29) +var file_prairie_plugin_v1_watch_sync_provider_proto_enumTypes = make([]protoimpl.EnumInfo, 8) +var file_prairie_plugin_v1_watch_sync_provider_proto_msgTypes = make([]protoimpl.MessageInfo, 34) var file_prairie_plugin_v1_watch_sync_provider_proto_goTypes = []any{ - (WatchSyncAuthMethod)(0), // 0: prairie.plugin.v1.WatchSyncAuthMethod - (WatchSyncMediaType)(0), // 1: prairie.plugin.v1.WatchSyncMediaType - (WatchSyncOperation)(0), // 2: prairie.plugin.v1.WatchSyncOperation - (WatchSyncOrigin)(0), // 3: prairie.plugin.v1.WatchSyncOrigin - (WatchSyncApplyStatus)(0), // 4: prairie.plugin.v1.WatchSyncApplyStatus - (WatchSyncFaultCode)(0), // 5: prairie.plugin.v1.WatchSyncFaultCode - (*WatchSyncProviderDescriptor)(nil), // 6: prairie.plugin.v1.WatchSyncProviderDescriptor - (*WatchSyncProviderConfig)(nil), // 7: prairie.plugin.v1.WatchSyncProviderConfig - (*WatchSyncCredentials)(nil), // 8: prairie.plugin.v1.WatchSyncCredentials - (*WatchSyncAuthenticatedContext)(nil), // 9: prairie.plugin.v1.WatchSyncAuthenticatedContext - (*WatchSyncAccount)(nil), // 10: prairie.plugin.v1.WatchSyncAccount - (*WatchSyncFault)(nil), // 11: prairie.plugin.v1.WatchSyncFault - (*WatchSyncInitAuthorizeRequest)(nil), // 12: prairie.plugin.v1.WatchSyncInitAuthorizeRequest - (*WatchSyncInitAuthorizeResponse)(nil), // 13: prairie.plugin.v1.WatchSyncInitAuthorizeResponse - (*WatchSyncExchangeCodeRequest)(nil), // 14: prairie.plugin.v1.WatchSyncExchangeCodeRequest - (*WatchSyncExchangeAPIKeyRequest)(nil), // 15: prairie.plugin.v1.WatchSyncExchangeAPIKeyRequest - (*WatchSyncRefreshCredentialsRequest)(nil), // 16: prairie.plugin.v1.WatchSyncRefreshCredentialsRequest - (*WatchSyncCredentialResponse)(nil), // 17: prairie.plugin.v1.WatchSyncCredentialResponse - (*WatchSyncGetAccountRequest)(nil), // 18: prairie.plugin.v1.WatchSyncGetAccountRequest - (*WatchSyncGetAccountResponse)(nil), // 19: prairie.plugin.v1.WatchSyncGetAccountResponse - (*WatchSyncMedia)(nil), // 20: prairie.plugin.v1.WatchSyncMedia - (*WatchSyncEvent)(nil), // 21: prairie.plugin.v1.WatchSyncEvent - (*WatchSyncApplyEventsRequest)(nil), // 22: prairie.plugin.v1.WatchSyncApplyEventsRequest - (*WatchSyncApplyResult)(nil), // 23: prairie.plugin.v1.WatchSyncApplyResult - (*WatchSyncApplyEventsResponse)(nil), // 24: prairie.plugin.v1.WatchSyncApplyEventsResponse - (*WatchSyncListRemoteStateRequest)(nil), // 25: prairie.plugin.v1.WatchSyncListRemoteStateRequest - (*WatchSyncRemoteWatchedState)(nil), // 26: prairie.plugin.v1.WatchSyncRemoteWatchedState - (*WatchSyncRemoteProgressState)(nil), // 27: prairie.plugin.v1.WatchSyncRemoteProgressState - (*WatchSyncRemoteState)(nil), // 28: prairie.plugin.v1.WatchSyncRemoteState - (*WatchSyncListRemoteStateResponse)(nil), // 29: prairie.plugin.v1.WatchSyncListRemoteStateResponse - nil, // 30: prairie.plugin.v1.WatchSyncProviderConfig.ValuesEntry - nil, // 31: prairie.plugin.v1.WatchSyncProviderConfig.SecretValuesEntry - nil, // 32: prairie.plugin.v1.WatchSyncCredentials.SecretAttributesEntry - nil, // 33: prairie.plugin.v1.WatchSyncMedia.ExternalIdsEntry - nil, // 34: prairie.plugin.v1.WatchSyncMedia.SeriesExternalIdsEntry - (*timestamppb.Timestamp)(nil), // 35: google.protobuf.Timestamp - (*durationpb.Duration)(nil), // 36: google.protobuf.Duration - (*structpb.Struct)(nil), // 37: google.protobuf.Struct + (WatchSyncAuthMethod)(0), // 0: prairie.plugin.v1.WatchSyncAuthMethod + (WatchSyncMediaType)(0), // 1: prairie.plugin.v1.WatchSyncMediaType + (WatchSyncOperation)(0), // 2: prairie.plugin.v1.WatchSyncOperation + (WatchSyncRemoteStateKind)(0), // 3: prairie.plugin.v1.WatchSyncRemoteStateKind + (WatchSyncDeviceAuthorizationStatus)(0), // 4: prairie.plugin.v1.WatchSyncDeviceAuthorizationStatus + (WatchSyncOrigin)(0), // 5: prairie.plugin.v1.WatchSyncOrigin + (WatchSyncApplyStatus)(0), // 6: prairie.plugin.v1.WatchSyncApplyStatus + (WatchSyncFaultCode)(0), // 7: prairie.plugin.v1.WatchSyncFaultCode + (*WatchSyncProviderDescriptor)(nil), // 8: prairie.plugin.v1.WatchSyncProviderDescriptor + (*WatchSyncProviderConfig)(nil), // 9: prairie.plugin.v1.WatchSyncProviderConfig + (*WatchSyncCredentials)(nil), // 10: prairie.plugin.v1.WatchSyncCredentials + (*WatchSyncAuthenticatedContext)(nil), // 11: prairie.plugin.v1.WatchSyncAuthenticatedContext + (*WatchSyncAccount)(nil), // 12: prairie.plugin.v1.WatchSyncAccount + (*WatchSyncFault)(nil), // 13: prairie.plugin.v1.WatchSyncFault + (*WatchSyncInitAuthorizeRequest)(nil), // 14: prairie.plugin.v1.WatchSyncInitAuthorizeRequest + (*WatchSyncInitAuthorizeResponse)(nil), // 15: prairie.plugin.v1.WatchSyncInitAuthorizeResponse + (*WatchSyncExchangeCodeRequest)(nil), // 16: prairie.plugin.v1.WatchSyncExchangeCodeRequest + (*WatchSyncExchangeAPIKeyRequest)(nil), // 17: prairie.plugin.v1.WatchSyncExchangeAPIKeyRequest + (*WatchSyncDeviceAuthorizationServiceStartRequest)(nil), // 18: prairie.plugin.v1.WatchSyncDeviceAuthorizationServiceStartRequest + (*WatchSyncDeviceAuthorizationServiceStartResponse)(nil), // 19: prairie.plugin.v1.WatchSyncDeviceAuthorizationServiceStartResponse + (*WatchSyncDeviceAuthorizationServicePollRequest)(nil), // 20: prairie.plugin.v1.WatchSyncDeviceAuthorizationServicePollRequest + (*WatchSyncDeviceAuthorizationServicePollResponse)(nil), // 21: prairie.plugin.v1.WatchSyncDeviceAuthorizationServicePollResponse + (*WatchSyncRefreshCredentialsRequest)(nil), // 22: prairie.plugin.v1.WatchSyncRefreshCredentialsRequest + (*WatchSyncCredentialResponse)(nil), // 23: prairie.plugin.v1.WatchSyncCredentialResponse + (*WatchSyncGetAccountRequest)(nil), // 24: prairie.plugin.v1.WatchSyncGetAccountRequest + (*WatchSyncGetAccountResponse)(nil), // 25: prairie.plugin.v1.WatchSyncGetAccountResponse + (*WatchSyncMedia)(nil), // 26: prairie.plugin.v1.WatchSyncMedia + (*WatchSyncEvent)(nil), // 27: prairie.plugin.v1.WatchSyncEvent + (*WatchSyncApplyEventsRequest)(nil), // 28: prairie.plugin.v1.WatchSyncApplyEventsRequest + (*WatchSyncApplyResult)(nil), // 29: prairie.plugin.v1.WatchSyncApplyResult + (*WatchSyncApplyEventsResponse)(nil), // 30: prairie.plugin.v1.WatchSyncApplyEventsResponse + (*WatchSyncListRemoteStateRequest)(nil), // 31: prairie.plugin.v1.WatchSyncListRemoteStateRequest + (*WatchSyncRemoteWatchedState)(nil), // 32: prairie.plugin.v1.WatchSyncRemoteWatchedState + (*WatchSyncRemoteProgressState)(nil), // 33: prairie.plugin.v1.WatchSyncRemoteProgressState + (*WatchSyncRemoteListState)(nil), // 34: prairie.plugin.v1.WatchSyncRemoteListState + (*WatchSyncRemoteState)(nil), // 35: prairie.plugin.v1.WatchSyncRemoteState + (*WatchSyncListRemoteStateResponse)(nil), // 36: prairie.plugin.v1.WatchSyncListRemoteStateResponse + nil, // 37: prairie.plugin.v1.WatchSyncProviderConfig.ValuesEntry + nil, // 38: prairie.plugin.v1.WatchSyncProviderConfig.SecretValuesEntry + nil, // 39: prairie.plugin.v1.WatchSyncCredentials.SecretAttributesEntry + nil, // 40: prairie.plugin.v1.WatchSyncMedia.ExternalIdsEntry + nil, // 41: prairie.plugin.v1.WatchSyncMedia.SeriesExternalIdsEntry + (*timestamppb.Timestamp)(nil), // 42: google.protobuf.Timestamp + (*durationpb.Duration)(nil), // 43: google.protobuf.Duration + (*structpb.Struct)(nil), // 44: google.protobuf.Struct } var file_prairie_plugin_v1_watch_sync_provider_proto_depIdxs = []int32{ 0, // 0: prairie.plugin.v1.WatchSyncProviderDescriptor.auth_methods:type_name -> prairie.plugin.v1.WatchSyncAuthMethod 1, // 1: prairie.plugin.v1.WatchSyncProviderDescriptor.supported_media_types:type_name -> prairie.plugin.v1.WatchSyncMediaType - 30, // 2: prairie.plugin.v1.WatchSyncProviderConfig.values:type_name -> prairie.plugin.v1.WatchSyncProviderConfig.ValuesEntry - 31, // 3: prairie.plugin.v1.WatchSyncProviderConfig.secret_values:type_name -> prairie.plugin.v1.WatchSyncProviderConfig.SecretValuesEntry - 35, // 4: prairie.plugin.v1.WatchSyncCredentials.expires_at:type_name -> google.protobuf.Timestamp - 32, // 5: prairie.plugin.v1.WatchSyncCredentials.secret_attributes:type_name -> prairie.plugin.v1.WatchSyncCredentials.SecretAttributesEntry - 7, // 6: prairie.plugin.v1.WatchSyncAuthenticatedContext.provider_config:type_name -> prairie.plugin.v1.WatchSyncProviderConfig - 8, // 7: prairie.plugin.v1.WatchSyncAuthenticatedContext.credentials:type_name -> prairie.plugin.v1.WatchSyncCredentials - 5, // 8: prairie.plugin.v1.WatchSyncFault.code:type_name -> prairie.plugin.v1.WatchSyncFaultCode - 36, // 9: prairie.plugin.v1.WatchSyncFault.retry_after:type_name -> google.protobuf.Duration - 7, // 10: prairie.plugin.v1.WatchSyncInitAuthorizeRequest.provider_config:type_name -> prairie.plugin.v1.WatchSyncProviderConfig - 11, // 11: prairie.plugin.v1.WatchSyncInitAuthorizeResponse.fault:type_name -> prairie.plugin.v1.WatchSyncFault - 7, // 12: prairie.plugin.v1.WatchSyncExchangeCodeRequest.provider_config:type_name -> prairie.plugin.v1.WatchSyncProviderConfig - 7, // 13: prairie.plugin.v1.WatchSyncExchangeAPIKeyRequest.provider_config:type_name -> prairie.plugin.v1.WatchSyncProviderConfig - 9, // 14: prairie.plugin.v1.WatchSyncRefreshCredentialsRequest.context:type_name -> prairie.plugin.v1.WatchSyncAuthenticatedContext - 8, // 15: prairie.plugin.v1.WatchSyncCredentialResponse.credentials:type_name -> prairie.plugin.v1.WatchSyncCredentials - 10, // 16: prairie.plugin.v1.WatchSyncCredentialResponse.account:type_name -> prairie.plugin.v1.WatchSyncAccount - 11, // 17: prairie.plugin.v1.WatchSyncCredentialResponse.fault:type_name -> prairie.plugin.v1.WatchSyncFault - 9, // 18: prairie.plugin.v1.WatchSyncGetAccountRequest.context:type_name -> prairie.plugin.v1.WatchSyncAuthenticatedContext - 10, // 19: prairie.plugin.v1.WatchSyncGetAccountResponse.account:type_name -> prairie.plugin.v1.WatchSyncAccount - 11, // 20: prairie.plugin.v1.WatchSyncGetAccountResponse.fault:type_name -> prairie.plugin.v1.WatchSyncFault - 1, // 21: prairie.plugin.v1.WatchSyncMedia.media_type:type_name -> prairie.plugin.v1.WatchSyncMediaType - 33, // 22: prairie.plugin.v1.WatchSyncMedia.external_ids:type_name -> prairie.plugin.v1.WatchSyncMedia.ExternalIdsEntry - 34, // 23: prairie.plugin.v1.WatchSyncMedia.series_external_ids:type_name -> prairie.plugin.v1.WatchSyncMedia.SeriesExternalIdsEntry - 37, // 24: prairie.plugin.v1.WatchSyncMedia.metadata:type_name -> google.protobuf.Struct - 2, // 25: prairie.plugin.v1.WatchSyncEvent.operation:type_name -> prairie.plugin.v1.WatchSyncOperation - 3, // 26: prairie.plugin.v1.WatchSyncEvent.origin:type_name -> prairie.plugin.v1.WatchSyncOrigin - 35, // 27: prairie.plugin.v1.WatchSyncEvent.occurred_at:type_name -> google.protobuf.Timestamp - 20, // 28: prairie.plugin.v1.WatchSyncEvent.media:type_name -> prairie.plugin.v1.WatchSyncMedia - 9, // 29: prairie.plugin.v1.WatchSyncApplyEventsRequest.context:type_name -> prairie.plugin.v1.WatchSyncAuthenticatedContext - 21, // 30: prairie.plugin.v1.WatchSyncApplyEventsRequest.events:type_name -> prairie.plugin.v1.WatchSyncEvent - 4, // 31: prairie.plugin.v1.WatchSyncApplyResult.status:type_name -> prairie.plugin.v1.WatchSyncApplyStatus - 11, // 32: prairie.plugin.v1.WatchSyncApplyResult.fault:type_name -> prairie.plugin.v1.WatchSyncFault - 23, // 33: prairie.plugin.v1.WatchSyncApplyEventsResponse.results:type_name -> prairie.plugin.v1.WatchSyncApplyResult - 8, // 34: prairie.plugin.v1.WatchSyncApplyEventsResponse.updated_credentials:type_name -> prairie.plugin.v1.WatchSyncCredentials - 11, // 35: prairie.plugin.v1.WatchSyncApplyEventsResponse.fault:type_name -> prairie.plugin.v1.WatchSyncFault - 9, // 36: prairie.plugin.v1.WatchSyncListRemoteStateRequest.context:type_name -> prairie.plugin.v1.WatchSyncAuthenticatedContext - 35, // 37: prairie.plugin.v1.WatchSyncRemoteWatchedState.last_watched_at:type_name -> google.protobuf.Timestamp - 35, // 38: prairie.plugin.v1.WatchSyncRemoteProgressState.paused_at:type_name -> google.protobuf.Timestamp - 20, // 39: prairie.plugin.v1.WatchSyncRemoteState.media:type_name -> prairie.plugin.v1.WatchSyncMedia - 26, // 40: prairie.plugin.v1.WatchSyncRemoteState.watched:type_name -> prairie.plugin.v1.WatchSyncRemoteWatchedState - 27, // 41: prairie.plugin.v1.WatchSyncRemoteState.progress:type_name -> prairie.plugin.v1.WatchSyncRemoteProgressState - 28, // 42: prairie.plugin.v1.WatchSyncListRemoteStateResponse.items:type_name -> prairie.plugin.v1.WatchSyncRemoteState - 8, // 43: prairie.plugin.v1.WatchSyncListRemoteStateResponse.updated_credentials:type_name -> prairie.plugin.v1.WatchSyncCredentials - 11, // 44: prairie.plugin.v1.WatchSyncListRemoteStateResponse.fault:type_name -> prairie.plugin.v1.WatchSyncFault - 12, // 45: prairie.plugin.v1.WatchSyncProvider.InitAuthorize:input_type -> prairie.plugin.v1.WatchSyncInitAuthorizeRequest - 14, // 46: prairie.plugin.v1.WatchSyncProvider.ExchangeCode:input_type -> prairie.plugin.v1.WatchSyncExchangeCodeRequest - 15, // 47: prairie.plugin.v1.WatchSyncProvider.ExchangeAPIKey:input_type -> prairie.plugin.v1.WatchSyncExchangeAPIKeyRequest - 16, // 48: prairie.plugin.v1.WatchSyncProvider.RefreshCredentials:input_type -> prairie.plugin.v1.WatchSyncRefreshCredentialsRequest - 18, // 49: prairie.plugin.v1.WatchSyncProvider.GetAccount:input_type -> prairie.plugin.v1.WatchSyncGetAccountRequest - 22, // 50: prairie.plugin.v1.WatchSyncProvider.ApplyEvents:input_type -> prairie.plugin.v1.WatchSyncApplyEventsRequest - 25, // 51: prairie.plugin.v1.WatchSyncProvider.ListRemoteState:input_type -> prairie.plugin.v1.WatchSyncListRemoteStateRequest - 13, // 52: prairie.plugin.v1.WatchSyncProvider.InitAuthorize:output_type -> prairie.plugin.v1.WatchSyncInitAuthorizeResponse - 17, // 53: prairie.plugin.v1.WatchSyncProvider.ExchangeCode:output_type -> prairie.plugin.v1.WatchSyncCredentialResponse - 17, // 54: prairie.plugin.v1.WatchSyncProvider.ExchangeAPIKey:output_type -> prairie.plugin.v1.WatchSyncCredentialResponse - 17, // 55: prairie.plugin.v1.WatchSyncProvider.RefreshCredentials:output_type -> prairie.plugin.v1.WatchSyncCredentialResponse - 19, // 56: prairie.plugin.v1.WatchSyncProvider.GetAccount:output_type -> prairie.plugin.v1.WatchSyncGetAccountResponse - 24, // 57: prairie.plugin.v1.WatchSyncProvider.ApplyEvents:output_type -> prairie.plugin.v1.WatchSyncApplyEventsResponse - 29, // 58: prairie.plugin.v1.WatchSyncProvider.ListRemoteState:output_type -> prairie.plugin.v1.WatchSyncListRemoteStateResponse - 52, // [52:59] is the sub-list for method output_type - 45, // [45:52] is the sub-list for method input_type - 45, // [45:45] is the sub-list for extension type_name - 45, // [45:45] is the sub-list for extension extendee - 0, // [0:45] is the sub-list for field type_name + 37, // 2: prairie.plugin.v1.WatchSyncProviderConfig.values:type_name -> prairie.plugin.v1.WatchSyncProviderConfig.ValuesEntry + 38, // 3: prairie.plugin.v1.WatchSyncProviderConfig.secret_values:type_name -> prairie.plugin.v1.WatchSyncProviderConfig.SecretValuesEntry + 42, // 4: prairie.plugin.v1.WatchSyncCredentials.expires_at:type_name -> google.protobuf.Timestamp + 39, // 5: prairie.plugin.v1.WatchSyncCredentials.secret_attributes:type_name -> prairie.plugin.v1.WatchSyncCredentials.SecretAttributesEntry + 9, // 6: prairie.plugin.v1.WatchSyncAuthenticatedContext.provider_config:type_name -> prairie.plugin.v1.WatchSyncProviderConfig + 10, // 7: prairie.plugin.v1.WatchSyncAuthenticatedContext.credentials:type_name -> prairie.plugin.v1.WatchSyncCredentials + 7, // 8: prairie.plugin.v1.WatchSyncFault.code:type_name -> prairie.plugin.v1.WatchSyncFaultCode + 43, // 9: prairie.plugin.v1.WatchSyncFault.retry_after:type_name -> google.protobuf.Duration + 9, // 10: prairie.plugin.v1.WatchSyncInitAuthorizeRequest.provider_config:type_name -> prairie.plugin.v1.WatchSyncProviderConfig + 13, // 11: prairie.plugin.v1.WatchSyncInitAuthorizeResponse.fault:type_name -> prairie.plugin.v1.WatchSyncFault + 9, // 12: prairie.plugin.v1.WatchSyncExchangeCodeRequest.provider_config:type_name -> prairie.plugin.v1.WatchSyncProviderConfig + 9, // 13: prairie.plugin.v1.WatchSyncExchangeAPIKeyRequest.provider_config:type_name -> prairie.plugin.v1.WatchSyncProviderConfig + 9, // 14: prairie.plugin.v1.WatchSyncDeviceAuthorizationServiceStartRequest.provider_config:type_name -> prairie.plugin.v1.WatchSyncProviderConfig + 43, // 15: prairie.plugin.v1.WatchSyncDeviceAuthorizationServiceStartResponse.polling_interval:type_name -> google.protobuf.Duration + 42, // 16: prairie.plugin.v1.WatchSyncDeviceAuthorizationServiceStartResponse.expires_at:type_name -> google.protobuf.Timestamp + 13, // 17: prairie.plugin.v1.WatchSyncDeviceAuthorizationServiceStartResponse.fault:type_name -> prairie.plugin.v1.WatchSyncFault + 9, // 18: prairie.plugin.v1.WatchSyncDeviceAuthorizationServicePollRequest.provider_config:type_name -> prairie.plugin.v1.WatchSyncProviderConfig + 4, // 19: prairie.plugin.v1.WatchSyncDeviceAuthorizationServicePollResponse.status:type_name -> prairie.plugin.v1.WatchSyncDeviceAuthorizationStatus + 10, // 20: prairie.plugin.v1.WatchSyncDeviceAuthorizationServicePollResponse.credentials:type_name -> prairie.plugin.v1.WatchSyncCredentials + 12, // 21: prairie.plugin.v1.WatchSyncDeviceAuthorizationServicePollResponse.account:type_name -> prairie.plugin.v1.WatchSyncAccount + 13, // 22: prairie.plugin.v1.WatchSyncDeviceAuthorizationServicePollResponse.fault:type_name -> prairie.plugin.v1.WatchSyncFault + 43, // 23: prairie.plugin.v1.WatchSyncDeviceAuthorizationServicePollResponse.polling_interval:type_name -> google.protobuf.Duration + 42, // 24: prairie.plugin.v1.WatchSyncDeviceAuthorizationServicePollResponse.expires_at:type_name -> google.protobuf.Timestamp + 11, // 25: prairie.plugin.v1.WatchSyncRefreshCredentialsRequest.context:type_name -> prairie.plugin.v1.WatchSyncAuthenticatedContext + 10, // 26: prairie.plugin.v1.WatchSyncCredentialResponse.credentials:type_name -> prairie.plugin.v1.WatchSyncCredentials + 12, // 27: prairie.plugin.v1.WatchSyncCredentialResponse.account:type_name -> prairie.plugin.v1.WatchSyncAccount + 13, // 28: prairie.plugin.v1.WatchSyncCredentialResponse.fault:type_name -> prairie.plugin.v1.WatchSyncFault + 11, // 29: prairie.plugin.v1.WatchSyncGetAccountRequest.context:type_name -> prairie.plugin.v1.WatchSyncAuthenticatedContext + 12, // 30: prairie.plugin.v1.WatchSyncGetAccountResponse.account:type_name -> prairie.plugin.v1.WatchSyncAccount + 13, // 31: prairie.plugin.v1.WatchSyncGetAccountResponse.fault:type_name -> prairie.plugin.v1.WatchSyncFault + 1, // 32: prairie.plugin.v1.WatchSyncMedia.media_type:type_name -> prairie.plugin.v1.WatchSyncMediaType + 40, // 33: prairie.plugin.v1.WatchSyncMedia.external_ids:type_name -> prairie.plugin.v1.WatchSyncMedia.ExternalIdsEntry + 41, // 34: prairie.plugin.v1.WatchSyncMedia.series_external_ids:type_name -> prairie.plugin.v1.WatchSyncMedia.SeriesExternalIdsEntry + 44, // 35: prairie.plugin.v1.WatchSyncMedia.metadata:type_name -> google.protobuf.Struct + 2, // 36: prairie.plugin.v1.WatchSyncEvent.operation:type_name -> prairie.plugin.v1.WatchSyncOperation + 5, // 37: prairie.plugin.v1.WatchSyncEvent.origin:type_name -> prairie.plugin.v1.WatchSyncOrigin + 42, // 38: prairie.plugin.v1.WatchSyncEvent.occurred_at:type_name -> google.protobuf.Timestamp + 26, // 39: prairie.plugin.v1.WatchSyncEvent.media:type_name -> prairie.plugin.v1.WatchSyncMedia + 11, // 40: prairie.plugin.v1.WatchSyncApplyEventsRequest.context:type_name -> prairie.plugin.v1.WatchSyncAuthenticatedContext + 27, // 41: prairie.plugin.v1.WatchSyncApplyEventsRequest.events:type_name -> prairie.plugin.v1.WatchSyncEvent + 6, // 42: prairie.plugin.v1.WatchSyncApplyResult.status:type_name -> prairie.plugin.v1.WatchSyncApplyStatus + 13, // 43: prairie.plugin.v1.WatchSyncApplyResult.fault:type_name -> prairie.plugin.v1.WatchSyncFault + 29, // 44: prairie.plugin.v1.WatchSyncApplyEventsResponse.results:type_name -> prairie.plugin.v1.WatchSyncApplyResult + 10, // 45: prairie.plugin.v1.WatchSyncApplyEventsResponse.updated_credentials:type_name -> prairie.plugin.v1.WatchSyncCredentials + 13, // 46: prairie.plugin.v1.WatchSyncApplyEventsResponse.fault:type_name -> prairie.plugin.v1.WatchSyncFault + 11, // 47: prairie.plugin.v1.WatchSyncListRemoteStateRequest.context:type_name -> prairie.plugin.v1.WatchSyncAuthenticatedContext + 3, // 48: prairie.plugin.v1.WatchSyncListRemoteStateRequest.state_kinds:type_name -> prairie.plugin.v1.WatchSyncRemoteStateKind + 42, // 49: prairie.plugin.v1.WatchSyncRemoteWatchedState.last_watched_at:type_name -> google.protobuf.Timestamp + 42, // 50: prairie.plugin.v1.WatchSyncRemoteProgressState.paused_at:type_name -> google.protobuf.Timestamp + 42, // 51: prairie.plugin.v1.WatchSyncRemoteListState.listed_at:type_name -> google.protobuf.Timestamp + 26, // 52: prairie.plugin.v1.WatchSyncRemoteState.media:type_name -> prairie.plugin.v1.WatchSyncMedia + 32, // 53: prairie.plugin.v1.WatchSyncRemoteState.watched:type_name -> prairie.plugin.v1.WatchSyncRemoteWatchedState + 33, // 54: prairie.plugin.v1.WatchSyncRemoteState.progress:type_name -> prairie.plugin.v1.WatchSyncRemoteProgressState + 34, // 55: prairie.plugin.v1.WatchSyncRemoteState.favorite:type_name -> prairie.plugin.v1.WatchSyncRemoteListState + 34, // 56: prairie.plugin.v1.WatchSyncRemoteState.watchlist:type_name -> prairie.plugin.v1.WatchSyncRemoteListState + 35, // 57: prairie.plugin.v1.WatchSyncListRemoteStateResponse.items:type_name -> prairie.plugin.v1.WatchSyncRemoteState + 10, // 58: prairie.plugin.v1.WatchSyncListRemoteStateResponse.updated_credentials:type_name -> prairie.plugin.v1.WatchSyncCredentials + 13, // 59: prairie.plugin.v1.WatchSyncListRemoteStateResponse.fault:type_name -> prairie.plugin.v1.WatchSyncFault + 14, // 60: prairie.plugin.v1.WatchSyncProvider.InitAuthorize:input_type -> prairie.plugin.v1.WatchSyncInitAuthorizeRequest + 16, // 61: prairie.plugin.v1.WatchSyncProvider.ExchangeCode:input_type -> prairie.plugin.v1.WatchSyncExchangeCodeRequest + 17, // 62: prairie.plugin.v1.WatchSyncProvider.ExchangeAPIKey:input_type -> prairie.plugin.v1.WatchSyncExchangeAPIKeyRequest + 22, // 63: prairie.plugin.v1.WatchSyncProvider.RefreshCredentials:input_type -> prairie.plugin.v1.WatchSyncRefreshCredentialsRequest + 24, // 64: prairie.plugin.v1.WatchSyncProvider.GetAccount:input_type -> prairie.plugin.v1.WatchSyncGetAccountRequest + 28, // 65: prairie.plugin.v1.WatchSyncProvider.ApplyEvents:input_type -> prairie.plugin.v1.WatchSyncApplyEventsRequest + 31, // 66: prairie.plugin.v1.WatchSyncProvider.ListRemoteState:input_type -> prairie.plugin.v1.WatchSyncListRemoteStateRequest + 18, // 67: prairie.plugin.v1.WatchSyncDeviceAuthorizationService.Start:input_type -> prairie.plugin.v1.WatchSyncDeviceAuthorizationServiceStartRequest + 20, // 68: prairie.plugin.v1.WatchSyncDeviceAuthorizationService.Poll:input_type -> prairie.plugin.v1.WatchSyncDeviceAuthorizationServicePollRequest + 15, // 69: prairie.plugin.v1.WatchSyncProvider.InitAuthorize:output_type -> prairie.plugin.v1.WatchSyncInitAuthorizeResponse + 23, // 70: prairie.plugin.v1.WatchSyncProvider.ExchangeCode:output_type -> prairie.plugin.v1.WatchSyncCredentialResponse + 23, // 71: prairie.plugin.v1.WatchSyncProvider.ExchangeAPIKey:output_type -> prairie.plugin.v1.WatchSyncCredentialResponse + 23, // 72: prairie.plugin.v1.WatchSyncProvider.RefreshCredentials:output_type -> prairie.plugin.v1.WatchSyncCredentialResponse + 25, // 73: prairie.plugin.v1.WatchSyncProvider.GetAccount:output_type -> prairie.plugin.v1.WatchSyncGetAccountResponse + 30, // 74: prairie.plugin.v1.WatchSyncProvider.ApplyEvents:output_type -> prairie.plugin.v1.WatchSyncApplyEventsResponse + 36, // 75: prairie.plugin.v1.WatchSyncProvider.ListRemoteState:output_type -> prairie.plugin.v1.WatchSyncListRemoteStateResponse + 19, // 76: prairie.plugin.v1.WatchSyncDeviceAuthorizationService.Start:output_type -> prairie.plugin.v1.WatchSyncDeviceAuthorizationServiceStartResponse + 21, // 77: prairie.plugin.v1.WatchSyncDeviceAuthorizationService.Poll:output_type -> prairie.plugin.v1.WatchSyncDeviceAuthorizationServicePollResponse + 69, // [69:78] is the sub-list for method output_type + 60, // [60:69] is the sub-list for method input_type + 60, // [60:60] is the sub-list for extension type_name + 60, // [60:60] is the sub-list for extension extendee + 0, // [0:60] is the sub-list for field type_name } func init() { file_prairie_plugin_v1_watch_sync_provider_proto_init() } @@ -2398,15 +3124,17 @@ func file_prairie_plugin_v1_watch_sync_provider_proto_init() { if File_prairie_plugin_v1_watch_sync_provider_proto != nil { return } + file_prairie_plugin_v1_watch_sync_provider_proto_msgTypes[13].OneofWrappers = []any{} + file_prairie_plugin_v1_watch_sync_provider_proto_msgTypes[19].OneofWrappers = []any{} type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_prairie_plugin_v1_watch_sync_provider_proto_rawDesc), len(file_prairie_plugin_v1_watch_sync_provider_proto_rawDesc)), - NumEnums: 6, - NumMessages: 29, + NumEnums: 8, + NumMessages: 34, NumExtensions: 0, - NumServices: 1, + NumServices: 2, }, GoTypes: file_prairie_plugin_v1_watch_sync_provider_proto_goTypes, DependencyIndexes: file_prairie_plugin_v1_watch_sync_provider_proto_depIdxs, diff --git a/pkg/pluginproto/prairie/plugin/v1/watch_sync_provider_grpc.pb.go b/pkg/pluginproto/prairie/plugin/v1/watch_sync_provider_grpc.pb.go index 997c762..2146238 100644 --- a/pkg/pluginproto/prairie/plugin/v1/watch_sync_provider_grpc.pb.go +++ b/pkg/pluginproto/prairie/plugin/v1/watch_sync_provider_grpc.pb.go @@ -355,3 +355,149 @@ var WatchSyncProvider_ServiceDesc = grpc.ServiceDesc{ Streams: []grpc.StreamDesc{}, Metadata: "prairie/plugin/v1/watch_sync_provider.proto", } + +const ( + WatchSyncDeviceAuthorizationService_Start_FullMethodName = "/prairie.plugin.v1.WatchSyncDeviceAuthorizationService/Start" + WatchSyncDeviceAuthorizationService_Poll_FullMethodName = "/prairie.plugin.v1.WatchSyncDeviceAuthorizationService/Poll" +) + +// WatchSyncDeviceAuthorizationServiceClient is the client API for WatchSyncDeviceAuthorizationService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +// +// WatchSyncDeviceAuthorizationService is separate from WatchSyncProvider so adding +// device authorization does not add methods to the released v0.12 Go server +// interface. A plugin advertising DEVICE_CODE registers both services. +type WatchSyncDeviceAuthorizationServiceClient interface { + Start(ctx context.Context, in *WatchSyncDeviceAuthorizationServiceStartRequest, opts ...grpc.CallOption) (*WatchSyncDeviceAuthorizationServiceStartResponse, error) + Poll(ctx context.Context, in *WatchSyncDeviceAuthorizationServicePollRequest, opts ...grpc.CallOption) (*WatchSyncDeviceAuthorizationServicePollResponse, error) +} + +type watchSyncDeviceAuthorizationServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewWatchSyncDeviceAuthorizationServiceClient(cc grpc.ClientConnInterface) WatchSyncDeviceAuthorizationServiceClient { + return &watchSyncDeviceAuthorizationServiceClient{cc} +} + +func (c *watchSyncDeviceAuthorizationServiceClient) Start(ctx context.Context, in *WatchSyncDeviceAuthorizationServiceStartRequest, opts ...grpc.CallOption) (*WatchSyncDeviceAuthorizationServiceStartResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(WatchSyncDeviceAuthorizationServiceStartResponse) + err := c.cc.Invoke(ctx, WatchSyncDeviceAuthorizationService_Start_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *watchSyncDeviceAuthorizationServiceClient) Poll(ctx context.Context, in *WatchSyncDeviceAuthorizationServicePollRequest, opts ...grpc.CallOption) (*WatchSyncDeviceAuthorizationServicePollResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(WatchSyncDeviceAuthorizationServicePollResponse) + err := c.cc.Invoke(ctx, WatchSyncDeviceAuthorizationService_Poll_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +// WatchSyncDeviceAuthorizationServiceServer is the server API for WatchSyncDeviceAuthorizationService service. +// All implementations should embed UnimplementedWatchSyncDeviceAuthorizationServiceServer +// for forward compatibility. +// +// WatchSyncDeviceAuthorizationService is separate from WatchSyncProvider so adding +// device authorization does not add methods to the released v0.12 Go server +// interface. A plugin advertising DEVICE_CODE registers both services. +type WatchSyncDeviceAuthorizationServiceServer interface { + Start(context.Context, *WatchSyncDeviceAuthorizationServiceStartRequest) (*WatchSyncDeviceAuthorizationServiceStartResponse, error) + Poll(context.Context, *WatchSyncDeviceAuthorizationServicePollRequest) (*WatchSyncDeviceAuthorizationServicePollResponse, error) +} + +// UnimplementedWatchSyncDeviceAuthorizationServiceServer should be embedded to have +// forward compatible implementations. +// +// NOTE: this should be embedded by value instead of pointer to avoid a nil +// pointer dereference when methods are called. +type UnimplementedWatchSyncDeviceAuthorizationServiceServer struct{} + +func (UnimplementedWatchSyncDeviceAuthorizationServiceServer) Start(context.Context, *WatchSyncDeviceAuthorizationServiceStartRequest) (*WatchSyncDeviceAuthorizationServiceStartResponse, error) { + return nil, status.Error(codes.Unimplemented, "method Start not implemented") +} +func (UnimplementedWatchSyncDeviceAuthorizationServiceServer) Poll(context.Context, *WatchSyncDeviceAuthorizationServicePollRequest) (*WatchSyncDeviceAuthorizationServicePollResponse, error) { + return nil, status.Error(codes.Unimplemented, "method Poll not implemented") +} +func (UnimplementedWatchSyncDeviceAuthorizationServiceServer) testEmbeddedByValue() {} + +// UnsafeWatchSyncDeviceAuthorizationServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to WatchSyncDeviceAuthorizationServiceServer will +// result in compilation errors. +type UnsafeWatchSyncDeviceAuthorizationServiceServer interface { + mustEmbedUnimplementedWatchSyncDeviceAuthorizationServiceServer() +} + +func RegisterWatchSyncDeviceAuthorizationServiceServer(s grpc.ServiceRegistrar, srv WatchSyncDeviceAuthorizationServiceServer) { + // If the following call panics, it indicates UnimplementedWatchSyncDeviceAuthorizationServiceServer was + // embedded by pointer and is nil. This will cause panics if an + // unimplemented method is ever invoked, so we test this at initialization + // time to prevent it from happening at runtime later due to I/O. + if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { + t.testEmbeddedByValue() + } + s.RegisterService(&WatchSyncDeviceAuthorizationService_ServiceDesc, srv) +} + +func _WatchSyncDeviceAuthorizationService_Start_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(WatchSyncDeviceAuthorizationServiceStartRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(WatchSyncDeviceAuthorizationServiceServer).Start(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: WatchSyncDeviceAuthorizationService_Start_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(WatchSyncDeviceAuthorizationServiceServer).Start(ctx, req.(*WatchSyncDeviceAuthorizationServiceStartRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _WatchSyncDeviceAuthorizationService_Poll_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(WatchSyncDeviceAuthorizationServicePollRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(WatchSyncDeviceAuthorizationServiceServer).Poll(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: WatchSyncDeviceAuthorizationService_Poll_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(WatchSyncDeviceAuthorizationServiceServer).Poll(ctx, req.(*WatchSyncDeviceAuthorizationServicePollRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// WatchSyncDeviceAuthorizationService_ServiceDesc is the grpc.ServiceDesc for WatchSyncDeviceAuthorizationService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var WatchSyncDeviceAuthorizationService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "prairie.plugin.v1.WatchSyncDeviceAuthorizationService", + HandlerType: (*WatchSyncDeviceAuthorizationServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Start", + Handler: _WatchSyncDeviceAuthorizationService_Start_Handler, + }, + { + MethodName: "Poll", + Handler: _WatchSyncDeviceAuthorizationService_Poll_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "prairie/plugin/v1/watch_sync_provider.proto", +} diff --git a/pkg/pluginsdk/runtime/runtime.go b/pkg/pluginsdk/runtime/runtime.go index 1cdc0e2..016cf7c 100644 --- a/pkg/pluginsdk/runtime/runtime.go +++ b/pkg/pluginsdk/runtime/runtime.go @@ -70,6 +70,24 @@ func DefaultPluginSet(servers CapabilityServers) plugin.PluginSet { } } +// DefaultPluginSetWithWatchSyncDeviceAuthorization returns the default plugin +// set plus the separate device-authorization service. Keeping that server out +// of CapabilityServers preserves the released v0.12 unkeyed struct shape. +func DefaultPluginSetWithWatchSyncDeviceAuthorization( + servers CapabilityServers, + deviceAuthorization pluginv1.WatchSyncDeviceAuthorizationServiceServer, +) plugin.PluginSet { + if deviceAuthorization == nil { + return DefaultPluginSet(servers) + } + return plugin.PluginSet{ + PluginSetName: &grpcPluginWithWatchSyncDeviceAuthorization{ + GRPCPlugin: &GRPCPlugin{Servers: servers}, + deviceAuthorization: deviceAuthorization, + }, + } +} + func NewClient(conn *grpc.ClientConn) *Client { return &Client{conn: conn} } @@ -133,11 +151,31 @@ func (c *Client) WatchSyncProvider() pluginv1.WatchSyncProviderClient { return pluginv1.NewWatchSyncProviderClient(c.conn) } +func (c *Client) WatchSyncDeviceAuthorization() pluginv1.WatchSyncDeviceAuthorizationServiceClient { + return pluginv1.NewWatchSyncDeviceAuthorizationServiceClient(c.conn) +} + type GRPCPlugin struct { plugin.Plugin Servers CapabilityServers } +type grpcPluginWithWatchSyncDeviceAuthorization struct { + *GRPCPlugin + deviceAuthorization pluginv1.WatchSyncDeviceAuthorizationServiceServer +} + +func (p *grpcPluginWithWatchSyncDeviceAuthorization) GRPCServer( + broker *plugin.GRPCBroker, + server *grpc.Server, +) error { + if err := p.GRPCPlugin.GRPCServer(broker, server); err != nil { + return err + } + pluginv1.RegisterWatchSyncDeviceAuthorizationServiceServer(server, p.deviceAuthorization) + return nil +} + func (p *GRPCPlugin) GRPCServer(broker *plugin.GRPCBroker, server *grpc.Server) error { pluginHost.setBroker(broker) if p.Servers.Runtime == nil { diff --git a/pkg/pluginsdk/runtime/serve_manifest.go b/pkg/pluginsdk/runtime/serve_manifest.go index 25a39d8..93e812b 100644 --- a/pkg/pluginsdk/runtime/serve_manifest.go +++ b/pkg/pluginsdk/runtime/serve_manifest.go @@ -19,6 +19,24 @@ type manifestRuntime struct { manifest *pluginv1.PluginManifest } +type serveManifestOptions struct { + watchSyncDeviceAuthorization pluginv1.WatchSyncDeviceAuthorizationServiceServer +} + +// ServeManifestOption adds a service without changing the released +// CapabilityServers or ServeConfig struct layouts. +type ServeManifestOption func(*serveManifestOptions) + +// WithWatchSyncDeviceAuthorization registers the separate device-code service +// for a watch-sync provider that advertises DEVICE_CODE authentication. +func WithWatchSyncDeviceAuthorization( + server pluginv1.WatchSyncDeviceAuthorizationServiceServer, +) ServeManifestOption { + return func(options *serveManifestOptions) { + options.watchSyncDeviceAuthorization = server + } +} + func (s *manifestRuntime) GetManifest(context.Context, *pluginv1.GetManifestRequest) (*pluginv1.GetManifestResponse, error) { return &pluginv1.GetManifestResponse{Manifest: s.manifest}, nil } @@ -37,10 +55,33 @@ func (s *manifestRuntime) BindHostBroker(_ context.Context, req *pluginv1.BindHo // servers (the caller supplies only the non-Runtime servers). It never returns; // a fatal manifest error panics, matching a misbuilt plugin's old main(). func ServeManifest(manifestBytes []byte, version string, servers CapabilityServers) { + ServeManifestWithOptions(manifestBytes, version, servers) +} + +// ServeManifestWithOptions is the additive form of ServeManifest for services +// introduced after the released CapabilityServers shape. +func ServeManifestWithOptions( + manifestBytes []byte, + version string, + servers CapabilityServers, + options ...ServeManifestOption, +) { m, err := manifest.LoadWithChecksum(manifestBytes, version) if err != nil { panic(err) } servers.Runtime = &manifestRuntime{manifest: m} - Serve(ServeConfig{Servers: servers}) + var resolved serveManifestOptions + for _, option := range options { + if option != nil { + option(&resolved) + } + } + Serve(ServeConfig{ + Servers: servers, + Plugins: DefaultPluginSetWithWatchSyncDeviceAuthorization( + servers, + resolved.watchSyncDeviceAuthorization, + ), + }) } diff --git a/pkg/pluginsdk/runtime/watch_sync_provider_test.go b/pkg/pluginsdk/runtime/watch_sync_provider_test.go index 2274e3b..94b33ac 100644 --- a/pkg/pluginsdk/runtime/watch_sync_provider_test.go +++ b/pkg/pluginsdk/runtime/watch_sync_provider_test.go @@ -5,6 +5,7 @@ import ( pluginv1 "github.com/prairie-server/prairie-plugin-sdk/pkg/pluginproto/prairie/plugin/v1" runtime "github.com/prairie-server/prairie-plugin-sdk/pkg/pluginsdk/runtime" + "github.com/hashicorp/go-plugin" "google.golang.org/grpc" ) @@ -12,16 +13,27 @@ type stubWatchSyncProvider struct { pluginv1.UnimplementedWatchSyncProviderServer } -func TestGRPCServerRegistersWatchSyncProvider(t *testing.T) { - p := &runtime.GRPCPlugin{Servers: runtime.CapabilityServers{ +type stubWatchSyncDeviceAuthorization struct { + pluginv1.UnimplementedWatchSyncDeviceAuthorizationServiceServer +} + +func TestGRPCServerRegistersWatchSyncServices(t *testing.T) { + plugins := runtime.DefaultPluginSetWithWatchSyncDeviceAuthorization(runtime.CapabilityServers{ Runtime: stubRuntime{}, WatchSyncProvider: stubWatchSyncProvider{}, - }} + }, stubWatchSyncDeviceAuthorization{}) + p, ok := plugins[runtime.PluginSetName].(plugin.GRPCPlugin) + if !ok { + t.Fatalf("watch-sync plugin type = %T, want plugin.GRPCPlugin", plugins[runtime.PluginSetName]) + } srv := grpc.NewServer() if err := p.GRPCServer(nil, srv); err != nil { - t.Fatalf("GRPCServer with WatchSyncProvider = %v, want nil", err) + t.Fatalf("GRPCServer with watch-sync services = %v, want nil", err) } if _, ok := srv.GetServiceInfo()["prairie.plugin.v1.WatchSyncProvider"]; !ok { t.Fatalf("WatchSyncProvider service not registered; got %v", srv.GetServiceInfo()) } + if _, ok := srv.GetServiceInfo()["prairie.plugin.v1.WatchSyncDeviceAuthorizationService"]; !ok { + t.Fatalf("WatchSyncDeviceAuthorization service not registered; got %v", srv.GetServiceInfo()) + } } diff --git a/proto/prairie/plugin/v1/watch_sync_provider.proto b/proto/prairie/plugin/v1/watch_sync_provider.proto index 2ea4b97..be43519 100644 --- a/proto/prairie/plugin/v1/watch_sync_provider.proto +++ b/proto/prairie/plugin/v1/watch_sync_provider.proto @@ -22,10 +22,19 @@ service WatchSyncProvider { rpc ListRemoteState(WatchSyncListRemoteStateRequest) returns (WatchSyncListRemoteStateResponse); } +// WatchSyncDeviceAuthorizationService is separate from WatchSyncProvider so adding +// device authorization does not add methods to the released v0.12 Go server +// interface. A plugin advertising DEVICE_CODE registers both services. +service WatchSyncDeviceAuthorizationService { + rpc Start(WatchSyncDeviceAuthorizationServiceStartRequest) returns (WatchSyncDeviceAuthorizationServiceStartResponse); + rpc Poll(WatchSyncDeviceAuthorizationServicePollRequest) returns (WatchSyncDeviceAuthorizationServicePollResponse); +} + enum WatchSyncAuthMethod { WATCH_SYNC_AUTH_METHOD_UNSPECIFIED = 0; WATCH_SYNC_AUTH_METHOD_AUTHORIZATION_CODE = 1; WATCH_SYNC_AUTH_METHOD_API_KEY = 2; + WATCH_SYNC_AUTH_METHOD_DEVICE_CODE = 3; } enum WatchSyncMediaType { @@ -38,6 +47,29 @@ enum WatchSyncOperation { WATCH_SYNC_OPERATION_UNSPECIFIED = 0; WATCH_SYNC_OPERATION_MARK_WATCHED = 1; WATCH_SYNC_OPERATION_MARK_UNWATCHED = 2; + WATCH_SYNC_OPERATION_ADD_FAVORITE = 3; + WATCH_SYNC_OPERATION_REMOVE_FAVORITE = 4; + WATCH_SYNC_OPERATION_ADD_TO_WATCHLIST = 5; + WATCH_SYNC_OPERATION_REMOVE_FROM_WATCHLIST = 6; + WATCH_SYNC_OPERATION_SCROBBLE_START = 7; + WATCH_SYNC_OPERATION_SCROBBLE_PAUSE = 8; + WATCH_SYNC_OPERATION_SCROBBLE_STOP = 9; +} + +enum WatchSyncRemoteStateKind { + WATCH_SYNC_REMOTE_STATE_KIND_UNSPECIFIED = 0; + WATCH_SYNC_REMOTE_STATE_KIND_WATCHED = 1; + WATCH_SYNC_REMOTE_STATE_KIND_PROGRESS = 2; + WATCH_SYNC_REMOTE_STATE_KIND_FAVORITE = 3; + WATCH_SYNC_REMOTE_STATE_KIND_WATCHLIST = 4; +} + +enum WatchSyncDeviceAuthorizationStatus { + WATCH_SYNC_DEVICE_AUTHORIZATION_STATUS_UNSPECIFIED = 0; + WATCH_SYNC_DEVICE_AUTHORIZATION_STATUS_PENDING = 1; + WATCH_SYNC_DEVICE_AUTHORIZATION_STATUS_AUTHORIZED = 2; + WATCH_SYNC_DEVICE_AUTHORIZATION_STATUS_DENIED = 3; + WATCH_SYNC_DEVICE_AUTHORIZATION_STATUS_EXPIRED = 4; } enum WatchSyncOrigin { @@ -74,6 +106,17 @@ message WatchSyncProviderDescriptor { repeated WatchSyncMediaType supported_media_types = 6; repeated string external_id_namespaces = 7; int32 max_batch_size = 8; + bool import_favorites = 9; + bool export_favorites = 10; + bool remove_favorites = 11; + bool import_watchlist = 12; + bool export_watchlist = 13; + bool remove_watchlist = 14; + // The order of WATCHLIST states returned by ListRemoteState is meaningful. + // WATCHLIST traversals must set complete_snapshot=true when this is enabled; + // an incremental subset cannot define positions relative to omitted items. + bool provides_watchlist_order = 15; + bool scrobble_playback = 16; } message WatchSyncProviderConfig { @@ -157,6 +200,54 @@ message WatchSyncExchangeAPIKeyRequest { string api_key = 3; } +message WatchSyncDeviceAuthorizationServiceStartRequest { + string capability_id = 1; + WatchSyncProviderConfig provider_config = 2; +} + +message WatchSyncDeviceAuthorizationServiceStartResponse { + string user_code = 1; + string verification_url = 2; + string verification_url_complete = 3; + // Plugin-defined flow data. The host encrypts it until authorization + // completes and never returns it through the public HTTP API. + bytes provider_state = 4; + google.protobuf.Duration polling_interval = 5; + google.protobuf.Timestamp expires_at = 6; + WatchSyncFault fault = 7; +} + +message WatchSyncDeviceAuthorizationServicePollRequest { + string capability_id = 1; + WatchSyncProviderConfig provider_config = 2; + bytes provider_state = 3; +} + +message WatchSyncDeviceAuthorizationServicePollResponse { + WatchSyncDeviceAuthorizationStatus status = 1; + // Complete authoritative replacement when status is AUTHORIZED. The host + // persists it before consuming account or fault. + WatchSyncCredentials credentials = 2; + WatchSyncAccount account = 3; + // PENDING normally omits fault. DENIED and EXPIRED may use a safe, + // non-retryable fault. Connection-wide and transport failures use fault. + WatchSyncFault fault = 4; + // A PENDING response may update host-private state and timing only for the + // same user challenge. The user_code and verification URLs returned by Start + // must remain valid through expires_at; if those instructions change, expire + // this flow and require a new Start call. + // + // Optional authoritative replacement for provider_state while PENDING. The + // host encrypts and uses it for the next poll. Presence is significant: an + // explicitly empty value clears the prior state, while omission retains it. + optional bytes provider_state = 5; + // Optional replacement polling interval while PENDING, for example after an + // OAuth device-flow slow_down response. + google.protobuf.Duration polling_interval = 6; + // Optional replacement expiry for the same user challenge. + google.protobuf.Timestamp expires_at = 7; +} + message WatchSyncRefreshCredentialsRequest { WatchSyncAuthenticatedContext context = 1; } @@ -211,6 +302,17 @@ message WatchSyncEvent { double duration_seconds = 9; double completion_percent = 10; int32 play_count = 11; + // Optional zero-based position for list providers that accept explicit + // ordering. Providers may ignore it unless their API supports order writes. + optional int32 list_position = 12; + // Provider-native key previously returned by ListRemoteState. It lets a + // removal address the exact upstream record when external IDs are absent or + // no longer resolve. + string provider_item_key = 13; + // Authoritative host completion state for playback events. A history ID can + // exist for incomplete playback, and completion_percent may be below 100 + // when the host's configured watched threshold has been reached. + bool completed = 14; } message WatchSyncApplyEventsRequest { @@ -252,6 +354,9 @@ message WatchSyncListRemoteStateRequest { string page_token = 3; // Requested maximum number of items. Plugins may return fewer. int32 page_size = 4; + // State families requested by the host. Empty means every family advertised + // by the descriptor, preserving compatibility with v0.12 hosts and plugins. + repeated WatchSyncRemoteStateKind state_kinds = 5; } message WatchSyncRemoteWatchedState { @@ -269,13 +374,25 @@ message WatchSyncRemoteProgressState { google.protobuf.Timestamp paused_at = 2; } +message WatchSyncRemoteListState { + // Provider timestamp for when the item was added, when available. + google.protobuf.Timestamp listed_at = 1; + // True is an explicit tombstone. It is meaningful for incremental + // traversals, where omitting an item is not a deletion. + bool removed = 2; +} + message WatchSyncRemoteState { string provider_item_key = 1; + // Required except on an explicit favorite/watchlist tombstone whose + // provider_item_key identifies a record returned previously. WatchSyncMedia media = 2; // At least one typed state must be present. Both may be present when the // provider reports a completed play and a separate resume point. WatchSyncRemoteWatchedState watched = 3; WatchSyncRemoteProgressState progress = 4; + WatchSyncRemoteListState favorite = 5; + WatchSyncRemoteListState watchlist = 6; } message WatchSyncListRemoteStateResponse { @@ -288,7 +405,9 @@ message WatchSyncListRemoteStateResponse { string next_cursor = 3; // True when this traversal is an authoritative full snapshot. False means an // incremental delta, so an absent item must not be interpreted as deletion. - // The value must remain stable across every page in one traversal. + // The value must remain stable across every page in one traversal. A provider + // advertising provides_watchlist_order must set this true for WATCHLIST + // traversals so the returned order is unambiguous. bool complete_snapshot = 4; // Complete authoritative replacement. The host persists it before consuming // this page or fault; a persistence failure discards the page and cursor. From 24f248c01c1a90b403662cd2c9e4ec19f2e6570c Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Fri, 28 Aug 2026 01:21:49 +0000 Subject: [PATCH 2/3] fix: gofmt import order in watch_sync_provider_test Co-authored-by: Jonah May --- pkg/pluginsdk/runtime/watch_sync_provider_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/pluginsdk/runtime/watch_sync_provider_test.go b/pkg/pluginsdk/runtime/watch_sync_provider_test.go index 94b33ac..63bda64 100644 --- a/pkg/pluginsdk/runtime/watch_sync_provider_test.go +++ b/pkg/pluginsdk/runtime/watch_sync_provider_test.go @@ -3,9 +3,9 @@ package runtime_test import ( "testing" + "github.com/hashicorp/go-plugin" pluginv1 "github.com/prairie-server/prairie-plugin-sdk/pkg/pluginproto/prairie/plugin/v1" runtime "github.com/prairie-server/prairie-plugin-sdk/pkg/pluginsdk/runtime" - "github.com/hashicorp/go-plugin" "google.golang.org/grpc" ) From 0ba6e06f1438c199f9b91b7a421438c5520c836b Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Fri, 28 Aug 2026 01:23:08 +0000 Subject: [PATCH 3/3] fix: goimports local-prefix grouping in watch_sync test Co-authored-by: Jonah May --- pkg/pluginsdk/runtime/watch_sync_provider_test.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pkg/pluginsdk/runtime/watch_sync_provider_test.go b/pkg/pluginsdk/runtime/watch_sync_provider_test.go index 63bda64..56e532f 100644 --- a/pkg/pluginsdk/runtime/watch_sync_provider_test.go +++ b/pkg/pluginsdk/runtime/watch_sync_provider_test.go @@ -4,9 +4,10 @@ import ( "testing" "github.com/hashicorp/go-plugin" + "google.golang.org/grpc" + pluginv1 "github.com/prairie-server/prairie-plugin-sdk/pkg/pluginproto/prairie/plugin/v1" runtime "github.com/prairie-server/prairie-plugin-sdk/pkg/pluginsdk/runtime" - "google.golang.org/grpc" ) type stubWatchSyncProvider struct {