From 174d18db22126a45114d1c84430c13d39d6b1693 Mon Sep 17 00:00:00 2001 From: logikonline Date: Fri, 13 Feb 2026 01:45:29 -0500 Subject: [PATCH] refactor(plugins): migrate external plugin manager to grpc/connect Replace manual HTTP/JSON RPC implementation with generated gRPC/Connect client, providing type-safe plugin communication. Code Generation: - Generate plugin.pb.go and pluginv1connect/plugin.connect.go from plugin.proto - Add generate-plugin-proto Makefile target - Delete hand-written types.go (replaced by generated code) ExternalPluginManager Refactoring: - Replace httpClient with pluginv1connect.PluginServiceClient - Use h2c (cleartext HTTP/2) transport for gRPC without TLS - Replace all manual callRPC/callRPCWithContext calls with typed Connect methods - Remove JSON serialization/deserialization code - Simplify error handling with native gRPC status codes Benefits: - Type safety: compile-time verification of request/response types - Protocol compatibility: standard gRPC wire format - Reduced code: ~100 lines of manual RPC code removed - Better errors: structured gRPC status codes instead of string parsing - Matches existing Actions runner pattern (Connect RPC over HTTP/2) This completes the plugin framework migration to production-grade RPC transport. --- Makefile | 6 + modules/plugins/external.go | 168 +-- modules/plugins/health.go | 9 +- modules/plugins/pluginv1/plugin.pb.go | 1214 +++++++++++++++++ modules/plugins/pluginv1/plugin.proto | 2 +- .../pluginv1connect/plugin.connect.go | 264 ++++ modules/plugins/pluginv1/types.go | 81 -- 7 files changed, 1552 insertions(+), 192 deletions(-) create mode 100644 modules/plugins/pluginv1/plugin.pb.go create mode 100644 modules/plugins/pluginv1/pluginv1connect/plugin.connect.go delete mode 100644 modules/plugins/pluginv1/types.go diff --git a/Makefile b/Makefile index 0cee9daded..27ecac4233 100644 --- a/Makefile +++ b/Makefile @@ -763,6 +763,12 @@ generate-go: $(TAGS_PREREQ) @echo "Running go generate..." @CC= GOOS= GOARCH= CGO_ENABLED=0 $(GO) generate -tags '$(TAGS)' ./... +.PHONY: generate-plugin-proto +generate-plugin-proto: + protoc --go_out=. --go_opt=paths=source_relative \ + --connect-go_out=. --connect-go_opt=paths=source_relative \ + modules/plugins/pluginv1/plugin.proto + .PHONY: security-check security-check: GOEXPERIMENT= go run $(GOVULNCHECK_PACKAGE) -show color ./... diff --git a/modules/plugins/external.go b/modules/plugins/external.go index 08e8edd9bf..9477f7bd30 100644 --- a/modules/plugins/external.go +++ b/modules/plugins/external.go @@ -4,12 +4,11 @@ package plugins import ( - "bytes" "context" - "errors" + "crypto/tls" "fmt" - "io" "maps" + "net" "net/http" "os" "os/exec" @@ -17,10 +16,13 @@ import ( "sync" "time" + "connectrpc.com/connect" + "golang.org/x/net/http2" + "code.gitcaddy.com/server/v3/modules/graceful" - "code.gitcaddy.com/server/v3/modules/json" "code.gitcaddy.com/server/v3/modules/log" pluginv1 "code.gitcaddy.com/server/v3/modules/plugins/pluginv1" + "code.gitcaddy.com/server/v3/modules/plugins/pluginv1/pluginv1connect" ) // PluginStatus represents the status of an external plugin @@ -35,14 +37,14 @@ const ( // ManagedPlugin tracks the state of an external plugin type ManagedPlugin struct { - config *ExternalPluginConfig - process *os.Process - status PluginStatus - lastSeen time.Time - manifest *pluginv1.PluginManifest - failCount int - httpClient *http.Client - mu sync.RWMutex + config *ExternalPluginConfig + process *os.Process + status PluginStatus + lastSeen time.Time + manifest *pluginv1.PluginManifest + failCount int + client pluginv1connect.PluginServiceClient + mu sync.RWMutex } // ExternalPluginManager manages external plugins (both managed and external mode) @@ -85,12 +87,23 @@ func (m *ExternalPluginManager) StartAll() error { continue } + address := cfg.Address + if address == "" { + log.Error("External plugin %s has no address configured", name) + continue + } + if !strings.HasPrefix(address, "http://") && !strings.HasPrefix(address, "https://") { + address = "http://" + address + } + mp := &ManagedPlugin{ config: cfg, status: PluginStatusStarting, - httpClient: &http.Client{ - Timeout: cfg.HealthTimeout, - }, + client: pluginv1connect.NewPluginServiceClient( + newH2CClient(cfg.HealthTimeout), + address, + connect.WithGRPC(), + ), } m.plugins[name] = mp @@ -127,7 +140,7 @@ func (m *ExternalPluginManager) StopAll() { for name, mp := range m.plugins { log.Info("Shutting down external plugin: %s", name) - // Send shutdown request + // Send shutdown request via Connect RPC m.shutdownPlugin(mp) // Kill managed process @@ -190,8 +203,13 @@ func (m *ExternalPluginManager) OnEvent(event *pluginv1.PluginEvent) { ctx, cancel := context.WithTimeout(m.ctx, 30*time.Second) defer cancel() - if err := m.callOnEvent(ctx, p, event); err != nil { + resp, err := p.client.OnEvent(ctx, connect.NewRequest(event)) + if err != nil { log.Error("Failed to dispatch event %s to plugin %s: %v", event.EventType, pluginName, err) + return + } + if resp.Msg.Error != "" { + log.Error("Plugin %s returned error for event %s: %s", pluginName, event.EventType, resp.Msg.Error) } }(name, mp) } @@ -210,22 +228,22 @@ func (m *ExternalPluginManager) HandleHTTP(method, path string, headers map[stri } for _, route := range mp.manifest.Routes { - if route.Method == method && matchRoute(route.Path, path) { + if route.Method == method && strings.HasPrefix(path, route.Path) { mp.mu.RUnlock() ctx, cancel := context.WithTimeout(m.ctx, 30*time.Second) defer cancel() - resp, err := m.callHandleHTTP(ctx, mp, &pluginv1.HTTPRequest{ + resp, err := mp.client.HandleHTTP(ctx, connect.NewRequest(&pluginv1.HTTPRequest{ Method: method, Path: path, Headers: headers, Body: body, - }) + })) if err != nil { return nil, fmt.Errorf("plugin %s HandleHTTP failed: %w", name, err) } - return resp, nil + return resp.Msg, nil } } mp.mu.RUnlock() @@ -276,107 +294,45 @@ func (m *ExternalPluginManager) startManagedPlugin(mp *ManagedPlugin) error { } func (m *ExternalPluginManager) initializePlugin(mp *ManagedPlugin) error { - req := &pluginv1.InitializeRequest{ + resp, err := mp.client.Initialize(m.ctx, connect.NewRequest(&pluginv1.InitializeRequest{ ServerVersion: "3.0.0", Config: map[string]string{}, + })) + if err != nil { + return fmt.Errorf("plugin Initialize RPC failed: %w", err) } - resp := &pluginv1.InitializeResponse{} - if err := m.callRPC(mp, "initialize", req, resp); err != nil { - return err - } - - if !resp.Success { - return fmt.Errorf("plugin initialization failed: %s", resp.Error) + if !resp.Msg.Success { + return fmt.Errorf("plugin initialization failed: %s", resp.Msg.Error) } mp.mu.Lock() - mp.manifest = resp.Manifest + mp.manifest = resp.Msg.Manifest mp.mu.Unlock() return nil } func (m *ExternalPluginManager) shutdownPlugin(mp *ManagedPlugin) { - req := &pluginv1.ShutdownRequest{Reason: "server shutdown"} - resp := &pluginv1.ShutdownResponse{} - if err := m.callRPC(mp, "shutdown", req, resp); err != nil { + _, err := mp.client.Shutdown(m.ctx, connect.NewRequest(&pluginv1.ShutdownRequest{ + Reason: "server shutdown", + })) + if err != nil { log.Warn("Plugin shutdown call failed: %v", err) } } -func (m *ExternalPluginManager) callOnEvent(ctx context.Context, mp *ManagedPlugin, event *pluginv1.PluginEvent) error { - resp := &pluginv1.EventResponse{} - if err := m.callRPCWithContext(ctx, mp, "on-event", event, resp); err != nil { - return err +// newH2CClient creates an HTTP client that supports cleartext HTTP/2 (h2c) +// for communicating with gRPC services without TLS. +func newH2CClient(timeout time.Duration) *http.Client { + return &http.Client{ + Timeout: timeout, + Transport: &http2.Transport{ + AllowHTTP: true, + DialTLSContext: func(ctx context.Context, network, addr string, _ *tls.Config) (net.Conn, error) { + var d net.Dialer + return d.DialContext(ctx, network, addr) + }, + }, } - if resp.Error != "" { - return fmt.Errorf("plugin event error: %s", resp.Error) - } - return nil -} - -func (m *ExternalPluginManager) callHandleHTTP(ctx context.Context, mp *ManagedPlugin, req *pluginv1.HTTPRequest) (*pluginv1.HTTPResponse, error) { - resp := &pluginv1.HTTPResponse{} - if err := m.callRPCWithContext(ctx, mp, "handle-http", req, resp); err != nil { - return nil, err - } - return resp, nil -} - -// callRPC makes a JSON-over-HTTP call to the plugin (simplified RPC) -func (m *ExternalPluginManager) callRPC(mp *ManagedPlugin, method string, req, resp any) error { - return m.callRPCWithContext(m.ctx, mp, method, req, resp) -} - -func (m *ExternalPluginManager) callRPCWithContext(ctx context.Context, mp *ManagedPlugin, method string, reqBody, respBody any) error { - address := mp.config.Address - if address == "" { - return errors.New("plugin has no address configured") - } - - // Ensure address has scheme - if !strings.HasPrefix(address, "http://") && !strings.HasPrefix(address, "https://") { - address = "http://" + address - } - - url := address + "/plugin/v1/" + method - - body, err := json.Marshal(reqBody) - if err != nil { - return fmt.Errorf("failed to marshal request: %w", err) - } - - httpReq, err := http.NewRequestWithContext(ctx, http.MethodPost, url, bytes.NewReader(body)) - if err != nil { - return fmt.Errorf("failed to create request: %w", err) - } - httpReq.Header.Set("Content-Type", "application/json") - - httpResp, err := mp.httpClient.Do(httpReq) - if err != nil { - return fmt.Errorf("RPC call to %s failed: %w", method, err) - } - defer httpResp.Body.Close() - - respData, err := io.ReadAll(httpResp.Body) - if err != nil { - return fmt.Errorf("failed to read response: %w", err) - } - - if httpResp.StatusCode != http.StatusOK { - return fmt.Errorf("RPC %s returned status %d: %s", method, httpResp.StatusCode, string(respData)) - } - - if err := json.Unmarshal(respData, respBody); err != nil { - return fmt.Errorf("failed to unmarshal response: %w", err) - } - - return nil -} - -// matchRoute checks if a URL path matches a route pattern (simple prefix matching) -func matchRoute(pattern, path string) bool { - // Simple prefix match for now - return strings.HasPrefix(path, pattern) } diff --git a/modules/plugins/health.go b/modules/plugins/health.go index f8db1bf117..4ea250f92d 100644 --- a/modules/plugins/health.go +++ b/modules/plugins/health.go @@ -8,6 +8,8 @@ import ( "maps" "time" + "connectrpc.com/connect" + "code.gitcaddy.com/server/v3/modules/graceful" "code.gitcaddy.com/server/v3/modules/log" pluginv1 "code.gitcaddy.com/server/v3/modules/plugins/pluginv1" @@ -59,8 +61,7 @@ func (m *ExternalPluginManager) checkPlugin(ctx context.Context, name string, mp healthCtx, cancel := context.WithTimeout(ctx, mp.config.HealthTimeout) defer cancel() - resp := &pluginv1.HealthCheckResponse{} - err := m.callRPCWithContext(healthCtx, mp, "health-check", &pluginv1.HealthCheckRequest{}, resp) + resp, err := mp.client.HealthCheck(healthCtx, connect.NewRequest(&pluginv1.HealthCheckRequest{})) mp.mu.Lock() defer mp.mu.Unlock() @@ -90,8 +91,8 @@ func (m *ExternalPluginManager) checkPlugin(ctx context.Context, name string, mp mp.status = PluginStatusOnline mp.lastSeen = time.Now() - if !resp.Healthy { - log.Warn("Plugin %s reports unhealthy: %s", name, resp.Status) + if !resp.Msg.Healthy { + log.Warn("Plugin %s reports unhealthy: %s", name, resp.Msg.Status) mp.status = PluginStatusError } diff --git a/modules/plugins/pluginv1/plugin.pb.go b/modules/plugins/pluginv1/plugin.pb.go new file mode 100644 index 0000000000..1de308b6ce --- /dev/null +++ b/modules/plugins/pluginv1/plugin.pb.go @@ -0,0 +1,1214 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.28.1 +// protoc v6.33.5 +// source: modules/plugins/pluginv1/plugin.proto + +package pluginv1 + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + structpb "google.golang.org/protobuf/types/known/structpb" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type InitializeRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ServerVersion string `protobuf:"bytes,1,opt,name=server_version,json=serverVersion,proto3" json:"server_version,omitempty"` + Config map[string]string `protobuf:"bytes,2,rep,name=config,proto3" json:"config,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *InitializeRequest) Reset() { + *x = InitializeRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_modules_plugins_pluginv1_plugin_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *InitializeRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*InitializeRequest) ProtoMessage() {} + +func (x *InitializeRequest) ProtoReflect() protoreflect.Message { + mi := &file_modules_plugins_pluginv1_plugin_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use InitializeRequest.ProtoReflect.Descriptor instead. +func (*InitializeRequest) Descriptor() ([]byte, []int) { + return file_modules_plugins_pluginv1_plugin_proto_rawDescGZIP(), []int{0} +} + +func (x *InitializeRequest) GetServerVersion() string { + if x != nil { + return x.ServerVersion + } + return "" +} + +func (x *InitializeRequest) GetConfig() map[string]string { + if x != nil { + return x.Config + } + return nil +} + +type InitializeResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Success bool `protobuf:"varint,1,opt,name=success,proto3" json:"success,omitempty"` + Error string `protobuf:"bytes,2,opt,name=error,proto3" json:"error,omitempty"` + Manifest *PluginManifest `protobuf:"bytes,3,opt,name=manifest,proto3" json:"manifest,omitempty"` +} + +func (x *InitializeResponse) Reset() { + *x = InitializeResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_modules_plugins_pluginv1_plugin_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *InitializeResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*InitializeResponse) ProtoMessage() {} + +func (x *InitializeResponse) ProtoReflect() protoreflect.Message { + mi := &file_modules_plugins_pluginv1_plugin_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use InitializeResponse.ProtoReflect.Descriptor instead. +func (*InitializeResponse) Descriptor() ([]byte, []int) { + return file_modules_plugins_pluginv1_plugin_proto_rawDescGZIP(), []int{1} +} + +func (x *InitializeResponse) GetSuccess() bool { + if x != nil { + return x.Success + } + return false +} + +func (x *InitializeResponse) GetError() string { + if x != nil { + return x.Error + } + return "" +} + +func (x *InitializeResponse) GetManifest() *PluginManifest { + if x != nil { + return x.Manifest + } + return nil +} + +type ShutdownRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Reason string `protobuf:"bytes,1,opt,name=reason,proto3" json:"reason,omitempty"` +} + +func (x *ShutdownRequest) Reset() { + *x = ShutdownRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_modules_plugins_pluginv1_plugin_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ShutdownRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ShutdownRequest) ProtoMessage() {} + +func (x *ShutdownRequest) ProtoReflect() protoreflect.Message { + mi := &file_modules_plugins_pluginv1_plugin_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ShutdownRequest.ProtoReflect.Descriptor instead. +func (*ShutdownRequest) Descriptor() ([]byte, []int) { + return file_modules_plugins_pluginv1_plugin_proto_rawDescGZIP(), []int{2} +} + +func (x *ShutdownRequest) GetReason() string { + if x != nil { + return x.Reason + } + return "" +} + +type ShutdownResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Success bool `protobuf:"varint,1,opt,name=success,proto3" json:"success,omitempty"` +} + +func (x *ShutdownResponse) Reset() { + *x = ShutdownResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_modules_plugins_pluginv1_plugin_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ShutdownResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ShutdownResponse) ProtoMessage() {} + +func (x *ShutdownResponse) ProtoReflect() protoreflect.Message { + mi := &file_modules_plugins_pluginv1_plugin_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ShutdownResponse.ProtoReflect.Descriptor instead. +func (*ShutdownResponse) Descriptor() ([]byte, []int) { + return file_modules_plugins_pluginv1_plugin_proto_rawDescGZIP(), []int{3} +} + +func (x *ShutdownResponse) GetSuccess() bool { + if x != nil { + return x.Success + } + return false +} + +type HealthCheckRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *HealthCheckRequest) Reset() { + *x = HealthCheckRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_modules_plugins_pluginv1_plugin_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *HealthCheckRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*HealthCheckRequest) ProtoMessage() {} + +func (x *HealthCheckRequest) ProtoReflect() protoreflect.Message { + mi := &file_modules_plugins_pluginv1_plugin_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use HealthCheckRequest.ProtoReflect.Descriptor instead. +func (*HealthCheckRequest) Descriptor() ([]byte, []int) { + return file_modules_plugins_pluginv1_plugin_proto_rawDescGZIP(), []int{4} +} + +type HealthCheckResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Healthy bool `protobuf:"varint,1,opt,name=healthy,proto3" json:"healthy,omitempty"` + Status string `protobuf:"bytes,2,opt,name=status,proto3" json:"status,omitempty"` + Details map[string]string `protobuf:"bytes,3,rep,name=details,proto3" json:"details,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *HealthCheckResponse) Reset() { + *x = HealthCheckResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_modules_plugins_pluginv1_plugin_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *HealthCheckResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*HealthCheckResponse) ProtoMessage() {} + +func (x *HealthCheckResponse) ProtoReflect() protoreflect.Message { + mi := &file_modules_plugins_pluginv1_plugin_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use HealthCheckResponse.ProtoReflect.Descriptor instead. +func (*HealthCheckResponse) Descriptor() ([]byte, []int) { + return file_modules_plugins_pluginv1_plugin_proto_rawDescGZIP(), []int{5} +} + +func (x *HealthCheckResponse) GetHealthy() bool { + if x != nil { + return x.Healthy + } + return false +} + +func (x *HealthCheckResponse) GetStatus() string { + if x != nil { + return x.Status + } + return "" +} + +func (x *HealthCheckResponse) GetDetails() map[string]string { + if x != nil { + return x.Details + } + return nil +} + +type GetManifestRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *GetManifestRequest) Reset() { + *x = GetManifestRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_modules_plugins_pluginv1_plugin_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetManifestRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetManifestRequest) ProtoMessage() {} + +func (x *GetManifestRequest) ProtoReflect() protoreflect.Message { + mi := &file_modules_plugins_pluginv1_plugin_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetManifestRequest.ProtoReflect.Descriptor instead. +func (*GetManifestRequest) Descriptor() ([]byte, []int) { + return file_modules_plugins_pluginv1_plugin_proto_rawDescGZIP(), []int{6} +} + +type PluginManifest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Version string `protobuf:"bytes,2,opt,name=version,proto3" json:"version,omitempty"` + Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"` + SubscribedEvents []string `protobuf:"bytes,4,rep,name=subscribed_events,json=subscribedEvents,proto3" json:"subscribed_events,omitempty"` + Routes []*PluginRoute `protobuf:"bytes,5,rep,name=routes,proto3" json:"routes,omitempty"` + RequiredPermissions []string `protobuf:"bytes,6,rep,name=required_permissions,json=requiredPermissions,proto3" json:"required_permissions,omitempty"` + LicenseTier string `protobuf:"bytes,7,opt,name=license_tier,json=licenseTier,proto3" json:"license_tier,omitempty"` +} + +func (x *PluginManifest) Reset() { + *x = PluginManifest{} + if protoimpl.UnsafeEnabled { + mi := &file_modules_plugins_pluginv1_plugin_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PluginManifest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PluginManifest) ProtoMessage() {} + +func (x *PluginManifest) ProtoReflect() protoreflect.Message { + mi := &file_modules_plugins_pluginv1_plugin_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PluginManifest.ProtoReflect.Descriptor instead. +func (*PluginManifest) Descriptor() ([]byte, []int) { + return file_modules_plugins_pluginv1_plugin_proto_rawDescGZIP(), []int{7} +} + +func (x *PluginManifest) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *PluginManifest) GetVersion() string { + if x != nil { + return x.Version + } + return "" +} + +func (x *PluginManifest) GetDescription() string { + if x != nil { + return x.Description + } + return "" +} + +func (x *PluginManifest) GetSubscribedEvents() []string { + if x != nil { + return x.SubscribedEvents + } + return nil +} + +func (x *PluginManifest) GetRoutes() []*PluginRoute { + if x != nil { + return x.Routes + } + return nil +} + +func (x *PluginManifest) GetRequiredPermissions() []string { + if x != nil { + return x.RequiredPermissions + } + return nil +} + +func (x *PluginManifest) GetLicenseTier() string { + if x != nil { + return x.LicenseTier + } + return "" +} + +type PluginRoute struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Method string `protobuf:"bytes,1,opt,name=method,proto3" json:"method,omitempty"` + Path string `protobuf:"bytes,2,opt,name=path,proto3" json:"path,omitempty"` + Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"` +} + +func (x *PluginRoute) Reset() { + *x = PluginRoute{} + if protoimpl.UnsafeEnabled { + mi := &file_modules_plugins_pluginv1_plugin_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PluginRoute) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PluginRoute) ProtoMessage() {} + +func (x *PluginRoute) ProtoReflect() protoreflect.Message { + mi := &file_modules_plugins_pluginv1_plugin_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PluginRoute.ProtoReflect.Descriptor instead. +func (*PluginRoute) Descriptor() ([]byte, []int) { + return file_modules_plugins_pluginv1_plugin_proto_rawDescGZIP(), []int{8} +} + +func (x *PluginRoute) GetMethod() string { + if x != nil { + return x.Method + } + return "" +} + +func (x *PluginRoute) GetPath() string { + if x != nil { + return x.Path + } + return "" +} + +func (x *PluginRoute) GetDescription() string { + if x != nil { + return x.Description + } + return "" +} + +type PluginEvent struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + EventType string `protobuf:"bytes,1,opt,name=event_type,json=eventType,proto3" json:"event_type,omitempty"` + Payload *structpb.Struct `protobuf:"bytes,2,opt,name=payload,proto3" json:"payload,omitempty"` + Timestamp *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=timestamp,proto3" json:"timestamp,omitempty"` + RepoId int64 `protobuf:"varint,4,opt,name=repo_id,json=repoId,proto3" json:"repo_id,omitempty"` + OrgId int64 `protobuf:"varint,5,opt,name=org_id,json=orgId,proto3" json:"org_id,omitempty"` +} + +func (x *PluginEvent) Reset() { + *x = PluginEvent{} + if protoimpl.UnsafeEnabled { + mi := &file_modules_plugins_pluginv1_plugin_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PluginEvent) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PluginEvent) ProtoMessage() {} + +func (x *PluginEvent) ProtoReflect() protoreflect.Message { + mi := &file_modules_plugins_pluginv1_plugin_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PluginEvent.ProtoReflect.Descriptor instead. +func (*PluginEvent) Descriptor() ([]byte, []int) { + return file_modules_plugins_pluginv1_plugin_proto_rawDescGZIP(), []int{9} +} + +func (x *PluginEvent) GetEventType() string { + if x != nil { + return x.EventType + } + return "" +} + +func (x *PluginEvent) GetPayload() *structpb.Struct { + if x != nil { + return x.Payload + } + return nil +} + +func (x *PluginEvent) GetTimestamp() *timestamppb.Timestamp { + if x != nil { + return x.Timestamp + } + return nil +} + +func (x *PluginEvent) GetRepoId() int64 { + if x != nil { + return x.RepoId + } + return 0 +} + +func (x *PluginEvent) GetOrgId() int64 { + if x != nil { + return x.OrgId + } + return 0 +} + +type EventResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Handled bool `protobuf:"varint,1,opt,name=handled,proto3" json:"handled,omitempty"` + Error string `protobuf:"bytes,2,opt,name=error,proto3" json:"error,omitempty"` +} + +func (x *EventResponse) Reset() { + *x = EventResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_modules_plugins_pluginv1_plugin_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *EventResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*EventResponse) ProtoMessage() {} + +func (x *EventResponse) ProtoReflect() protoreflect.Message { + mi := &file_modules_plugins_pluginv1_plugin_proto_msgTypes[10] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use EventResponse.ProtoReflect.Descriptor instead. +func (*EventResponse) Descriptor() ([]byte, []int) { + return file_modules_plugins_pluginv1_plugin_proto_rawDescGZIP(), []int{10} +} + +func (x *EventResponse) GetHandled() bool { + if x != nil { + return x.Handled + } + return false +} + +func (x *EventResponse) GetError() string { + if x != nil { + return x.Error + } + return "" +} + +type HTTPRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Method string `protobuf:"bytes,1,opt,name=method,proto3" json:"method,omitempty"` + Path string `protobuf:"bytes,2,opt,name=path,proto3" json:"path,omitempty"` + Headers map[string]string `protobuf:"bytes,3,rep,name=headers,proto3" json:"headers,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + Body []byte `protobuf:"bytes,4,opt,name=body,proto3" json:"body,omitempty"` + QueryParams map[string]string `protobuf:"bytes,5,rep,name=query_params,json=queryParams,proto3" json:"query_params,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *HTTPRequest) Reset() { + *x = HTTPRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_modules_plugins_pluginv1_plugin_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *HTTPRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*HTTPRequest) ProtoMessage() {} + +func (x *HTTPRequest) ProtoReflect() protoreflect.Message { + mi := &file_modules_plugins_pluginv1_plugin_proto_msgTypes[11] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use HTTPRequest.ProtoReflect.Descriptor instead. +func (*HTTPRequest) Descriptor() ([]byte, []int) { + return file_modules_plugins_pluginv1_plugin_proto_rawDescGZIP(), []int{11} +} + +func (x *HTTPRequest) GetMethod() string { + if x != nil { + return x.Method + } + return "" +} + +func (x *HTTPRequest) GetPath() string { + if x != nil { + return x.Path + } + return "" +} + +func (x *HTTPRequest) GetHeaders() map[string]string { + if x != nil { + return x.Headers + } + return nil +} + +func (x *HTTPRequest) GetBody() []byte { + if x != nil { + return x.Body + } + return nil +} + +func (x *HTTPRequest) GetQueryParams() map[string]string { + if x != nil { + return x.QueryParams + } + return nil +} + +type HTTPResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + StatusCode int32 `protobuf:"varint,1,opt,name=status_code,json=statusCode,proto3" json:"status_code,omitempty"` + Headers map[string]string `protobuf:"bytes,2,rep,name=headers,proto3" json:"headers,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + Body []byte `protobuf:"bytes,3,opt,name=body,proto3" json:"body,omitempty"` +} + +func (x *HTTPResponse) Reset() { + *x = HTTPResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_modules_plugins_pluginv1_plugin_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *HTTPResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*HTTPResponse) ProtoMessage() {} + +func (x *HTTPResponse) ProtoReflect() protoreflect.Message { + mi := &file_modules_plugins_pluginv1_plugin_proto_msgTypes[12] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use HTTPResponse.ProtoReflect.Descriptor instead. +func (*HTTPResponse) Descriptor() ([]byte, []int) { + return file_modules_plugins_pluginv1_plugin_proto_rawDescGZIP(), []int{12} +} + +func (x *HTTPResponse) GetStatusCode() int32 { + if x != nil { + return x.StatusCode + } + return 0 +} + +func (x *HTTPResponse) GetHeaders() map[string]string { + if x != nil { + return x.Headers + } + return nil +} + +func (x *HTTPResponse) GetBody() []byte { + if x != nil { + return x.Body + } + return nil +} + +var File_modules_plugins_pluginv1_plugin_proto protoreflect.FileDescriptor + +var file_modules_plugins_pluginv1_plugin_proto_rawDesc = []byte{ + 0x0a, 0x25, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x2f, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, + 0x73, 0x2f, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x76, 0x31, 0x2f, 0x70, 0x6c, 0x75, 0x67, 0x69, + 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x09, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, + 0x76, 0x31, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2f, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x22, 0xb7, 0x01, 0x0a, 0x11, 0x49, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x73, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0d, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x40, + 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, + 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x69, 0x74, 0x69, + 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x43, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x1a, 0x39, 0x0a, 0x0b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, + 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, + 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x7b, 0x0a, 0x12, 0x49, + 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x65, + 0x72, 0x72, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, + 0x72, 0x12, 0x35, 0x0a, 0x08, 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x31, 0x2e, + 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x52, 0x08, + 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x22, 0x29, 0x0a, 0x0f, 0x53, 0x68, 0x75, 0x74, + 0x64, 0x6f, 0x77, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x72, + 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x61, + 0x73, 0x6f, 0x6e, 0x22, 0x2c, 0x0a, 0x10, 0x53, 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x22, 0x14, 0x0a, 0x12, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0xca, 0x01, 0x0a, 0x13, 0x48, 0x65, 0x61, 0x6c, + 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x18, 0x0a, 0x07, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x07, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x12, 0x45, 0x0a, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x48, + 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x2e, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, + 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x1a, 0x3a, 0x0a, 0x0c, 0x44, 0x65, 0x74, 0x61, + 0x69, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x3a, 0x02, 0x38, 0x01, 0x22, 0x14, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x6e, 0x69, 0x66, + 0x65, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x93, 0x02, 0x0a, 0x0e, 0x50, + 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, + 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x20, 0x0a, 0x0b, 0x64, + 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2b, 0x0a, + 0x11, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x64, 0x5f, 0x65, 0x76, 0x65, 0x6e, + 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, + 0x69, 0x62, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x2e, 0x0a, 0x06, 0x72, 0x6f, + 0x75, 0x74, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x70, 0x6c, 0x75, + 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x52, 0x6f, 0x75, + 0x74, 0x65, 0x52, 0x06, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x12, 0x31, 0x0a, 0x14, 0x72, 0x65, + 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x5f, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, + 0x6e, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x13, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, + 0x65, 0x64, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x21, 0x0a, + 0x0c, 0x6c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x5f, 0x74, 0x69, 0x65, 0x72, 0x18, 0x07, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x54, 0x69, 0x65, 0x72, + 0x22, 0x5b, 0x0a, 0x0b, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x12, + 0x16, 0x0a, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x20, 0x0a, 0x0b, 0x64, + 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xc9, 0x01, + 0x0a, 0x0b, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1d, 0x0a, + 0x0a, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x09, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x31, 0x0a, 0x07, + 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, + 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, + 0x38, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, + 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x17, 0x0a, 0x07, 0x72, 0x65, 0x70, + 0x6f, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x72, 0x65, 0x70, 0x6f, + 0x49, 0x64, 0x12, 0x15, 0x0a, 0x06, 0x6f, 0x72, 0x67, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x03, 0x52, 0x05, 0x6f, 0x72, 0x67, 0x49, 0x64, 0x22, 0x3f, 0x0a, 0x0d, 0x45, 0x76, 0x65, + 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x68, 0x61, + 0x6e, 0x64, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x68, 0x61, 0x6e, + 0x64, 0x6c, 0x65, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x22, 0xd4, 0x02, 0x0a, 0x0b, 0x48, + 0x54, 0x54, 0x50, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x6d, 0x65, + 0x74, 0x68, 0x6f, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6d, 0x65, 0x74, 0x68, + 0x6f, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x3d, 0x0a, 0x07, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, + 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, + 0x2e, 0x76, 0x31, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, + 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x68, 0x65, + 0x61, 0x64, 0x65, 0x72, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x12, 0x4a, 0x0a, 0x0c, 0x71, 0x75, 0x65, + 0x72, 0x79, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x27, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x48, 0x54, 0x54, 0x50, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x61, 0x72, + 0x61, 0x6d, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0b, 0x71, 0x75, 0x65, 0x72, 0x79, 0x50, + 0x61, 0x72, 0x61, 0x6d, 0x73, 0x1a, 0x3a, 0x0a, 0x0c, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, + 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, + 0x01, 0x1a, 0x3e, 0x0a, 0x10, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, + 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, + 0x01, 0x22, 0xbf, 0x01, 0x0a, 0x0c, 0x48, 0x54, 0x54, 0x50, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x5f, 0x63, 0x6f, 0x64, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x43, + 0x6f, 0x64, 0x65, 0x12, 0x3e, 0x0a, 0x07, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x18, 0x02, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x31, + 0x2e, 0x48, 0x54, 0x54, 0x50, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x48, 0x65, + 0x61, 0x64, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x68, 0x65, 0x61, 0x64, + 0x65, 0x72, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x1a, 0x3a, 0x0a, 0x0c, 0x48, 0x65, 0x61, 0x64, 0x65, + 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, + 0x02, 0x38, 0x01, 0x32, 0xb2, 0x03, 0x0a, 0x0d, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x53, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x49, 0x0a, 0x0a, 0x49, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, + 0x69, 0x7a, 0x65, 0x12, 0x1c, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x31, 0x2e, + 0x49, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x1d, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, + 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x43, 0x0a, 0x08, 0x53, 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x12, 0x1a, 0x2e, 0x70, + 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, + 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, + 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4c, 0x0a, 0x0b, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, + 0x68, 0x65, 0x63, 0x6b, 0x12, 0x1d, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x31, + 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x31, 0x2e, + 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x47, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, + 0x73, 0x74, 0x12, 0x1d, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x47, + 0x65, 0x74, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x19, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6c, + 0x75, 0x67, 0x69, 0x6e, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x12, 0x3b, 0x0a, 0x07, + 0x4f, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x16, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, + 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x1a, + 0x18, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x76, 0x65, 0x6e, + 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3d, 0x0a, 0x0a, 0x48, 0x61, 0x6e, + 0x64, 0x6c, 0x65, 0x48, 0x54, 0x54, 0x50, 0x12, 0x16, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, + 0x2e, 0x76, 0x31, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x17, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x48, 0x54, 0x54, 0x50, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x3f, 0x5a, 0x3d, 0x63, 0x6f, 0x64, 0x65, + 0x2e, 0x67, 0x69, 0x74, 0x63, 0x61, 0x64, 0x64, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x2f, 0x76, 0x33, 0x2f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x2f, + 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x73, 0x2f, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x76, 0x31, + 0x3b, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x33, +} + +var ( + file_modules_plugins_pluginv1_plugin_proto_rawDescOnce sync.Once + file_modules_plugins_pluginv1_plugin_proto_rawDescData = file_modules_plugins_pluginv1_plugin_proto_rawDesc +) + +func file_modules_plugins_pluginv1_plugin_proto_rawDescGZIP() []byte { + file_modules_plugins_pluginv1_plugin_proto_rawDescOnce.Do(func() { + file_modules_plugins_pluginv1_plugin_proto_rawDescData = protoimpl.X.CompressGZIP(file_modules_plugins_pluginv1_plugin_proto_rawDescData) + }) + return file_modules_plugins_pluginv1_plugin_proto_rawDescData +} + +var file_modules_plugins_pluginv1_plugin_proto_msgTypes = make([]protoimpl.MessageInfo, 18) +var file_modules_plugins_pluginv1_plugin_proto_goTypes = []interface{}{ + (*InitializeRequest)(nil), // 0: plugin.v1.InitializeRequest + (*InitializeResponse)(nil), // 1: plugin.v1.InitializeResponse + (*ShutdownRequest)(nil), // 2: plugin.v1.ShutdownRequest + (*ShutdownResponse)(nil), // 3: plugin.v1.ShutdownResponse + (*HealthCheckRequest)(nil), // 4: plugin.v1.HealthCheckRequest + (*HealthCheckResponse)(nil), // 5: plugin.v1.HealthCheckResponse + (*GetManifestRequest)(nil), // 6: plugin.v1.GetManifestRequest + (*PluginManifest)(nil), // 7: plugin.v1.PluginManifest + (*PluginRoute)(nil), // 8: plugin.v1.PluginRoute + (*PluginEvent)(nil), // 9: plugin.v1.PluginEvent + (*EventResponse)(nil), // 10: plugin.v1.EventResponse + (*HTTPRequest)(nil), // 11: plugin.v1.HTTPRequest + (*HTTPResponse)(nil), // 12: plugin.v1.HTTPResponse + nil, // 13: plugin.v1.InitializeRequest.ConfigEntry + nil, // 14: plugin.v1.HealthCheckResponse.DetailsEntry + nil, // 15: plugin.v1.HTTPRequest.HeadersEntry + nil, // 16: plugin.v1.HTTPRequest.QueryParamsEntry + nil, // 17: plugin.v1.HTTPResponse.HeadersEntry + (*structpb.Struct)(nil), // 18: google.protobuf.Struct + (*timestamppb.Timestamp)(nil), // 19: google.protobuf.Timestamp +} +var file_modules_plugins_pluginv1_plugin_proto_depIdxs = []int32{ + 13, // 0: plugin.v1.InitializeRequest.config:type_name -> plugin.v1.InitializeRequest.ConfigEntry + 7, // 1: plugin.v1.InitializeResponse.manifest:type_name -> plugin.v1.PluginManifest + 14, // 2: plugin.v1.HealthCheckResponse.details:type_name -> plugin.v1.HealthCheckResponse.DetailsEntry + 8, // 3: plugin.v1.PluginManifest.routes:type_name -> plugin.v1.PluginRoute + 18, // 4: plugin.v1.PluginEvent.payload:type_name -> google.protobuf.Struct + 19, // 5: plugin.v1.PluginEvent.timestamp:type_name -> google.protobuf.Timestamp + 15, // 6: plugin.v1.HTTPRequest.headers:type_name -> plugin.v1.HTTPRequest.HeadersEntry + 16, // 7: plugin.v1.HTTPRequest.query_params:type_name -> plugin.v1.HTTPRequest.QueryParamsEntry + 17, // 8: plugin.v1.HTTPResponse.headers:type_name -> plugin.v1.HTTPResponse.HeadersEntry + 0, // 9: plugin.v1.PluginService.Initialize:input_type -> plugin.v1.InitializeRequest + 2, // 10: plugin.v1.PluginService.Shutdown:input_type -> plugin.v1.ShutdownRequest + 4, // 11: plugin.v1.PluginService.HealthCheck:input_type -> plugin.v1.HealthCheckRequest + 6, // 12: plugin.v1.PluginService.GetManifest:input_type -> plugin.v1.GetManifestRequest + 9, // 13: plugin.v1.PluginService.OnEvent:input_type -> plugin.v1.PluginEvent + 11, // 14: plugin.v1.PluginService.HandleHTTP:input_type -> plugin.v1.HTTPRequest + 1, // 15: plugin.v1.PluginService.Initialize:output_type -> plugin.v1.InitializeResponse + 3, // 16: plugin.v1.PluginService.Shutdown:output_type -> plugin.v1.ShutdownResponse + 5, // 17: plugin.v1.PluginService.HealthCheck:output_type -> plugin.v1.HealthCheckResponse + 7, // 18: plugin.v1.PluginService.GetManifest:output_type -> plugin.v1.PluginManifest + 10, // 19: plugin.v1.PluginService.OnEvent:output_type -> plugin.v1.EventResponse + 12, // 20: plugin.v1.PluginService.HandleHTTP:output_type -> plugin.v1.HTTPResponse + 15, // [15:21] is the sub-list for method output_type + 9, // [9:15] is the sub-list for method input_type + 9, // [9:9] is the sub-list for extension type_name + 9, // [9:9] is the sub-list for extension extendee + 0, // [0:9] is the sub-list for field type_name +} + +func init() { file_modules_plugins_pluginv1_plugin_proto_init() } +func file_modules_plugins_pluginv1_plugin_proto_init() { + if File_modules_plugins_pluginv1_plugin_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_modules_plugins_pluginv1_plugin_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*InitializeRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_modules_plugins_pluginv1_plugin_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*InitializeResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_modules_plugins_pluginv1_plugin_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ShutdownRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_modules_plugins_pluginv1_plugin_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ShutdownResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_modules_plugins_pluginv1_plugin_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*HealthCheckRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_modules_plugins_pluginv1_plugin_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*HealthCheckResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_modules_plugins_pluginv1_plugin_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetManifestRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_modules_plugins_pluginv1_plugin_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PluginManifest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_modules_plugins_pluginv1_plugin_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PluginRoute); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_modules_plugins_pluginv1_plugin_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PluginEvent); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_modules_plugins_pluginv1_plugin_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*EventResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_modules_plugins_pluginv1_plugin_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*HTTPRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_modules_plugins_pluginv1_plugin_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*HTTPResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_modules_plugins_pluginv1_plugin_proto_rawDesc, + NumEnums: 0, + NumMessages: 18, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_modules_plugins_pluginv1_plugin_proto_goTypes, + DependencyIndexes: file_modules_plugins_pluginv1_plugin_proto_depIdxs, + MessageInfos: file_modules_plugins_pluginv1_plugin_proto_msgTypes, + }.Build() + File_modules_plugins_pluginv1_plugin_proto = out.File + file_modules_plugins_pluginv1_plugin_proto_rawDesc = nil + file_modules_plugins_pluginv1_plugin_proto_goTypes = nil + file_modules_plugins_pluginv1_plugin_proto_depIdxs = nil +} diff --git a/modules/plugins/pluginv1/plugin.proto b/modules/plugins/pluginv1/plugin.proto index 69b9301966..8880d9e034 100644 --- a/modules/plugins/pluginv1/plugin.proto +++ b/modules/plugins/pluginv1/plugin.proto @@ -2,7 +2,7 @@ syntax = "proto3"; package plugin.v1; -option go_package = "code.gitcaddy.com/server/v3/modules/plugins/pluginv1"; +option go_package = "code.gitcaddy.com/server/v3/modules/plugins/pluginv1;pluginv1"; import "google/protobuf/struct.proto"; import "google/protobuf/timestamp.proto"; diff --git a/modules/plugins/pluginv1/pluginv1connect/plugin.connect.go b/modules/plugins/pluginv1/pluginv1connect/plugin.connect.go new file mode 100644 index 0000000000..2adae56ed7 --- /dev/null +++ b/modules/plugins/pluginv1/pluginv1connect/plugin.connect.go @@ -0,0 +1,264 @@ +// Code generated by protoc-gen-connect-go. DO NOT EDIT. +// +// Source: modules/plugins/pluginv1/plugin.proto + +package pluginv1connect + +import ( + pluginv1 "code.gitcaddy.com/server/v3/modules/plugins/pluginv1" + connect "connectrpc.com/connect" + context "context" + errors "errors" + http "net/http" + strings "strings" +) + +// This is a compile-time assertion to ensure that this generated file and the connect package are +// compatible. If you get a compiler error that this constant is not defined, this code was +// generated with a version of connect newer than the one compiled into your binary. You can fix the +// problem by either regenerating this code with an older version of connect or updating the connect +// version compiled into your binary. +const _ = connect.IsAtLeastVersion1_13_0 + +const ( + // PluginServiceName is the fully-qualified name of the PluginService service. + PluginServiceName = "plugin.v1.PluginService" +) + +// These constants are the fully-qualified names of the RPCs defined in this package. They're +// exposed at runtime as Spec.Procedure and as the final two segments of the HTTP route. +// +// Note that these are different from the fully-qualified method names used by +// google.golang.org/protobuf/reflect/protoreflect. To convert from these constants to +// reflection-formatted method names, remove the leading slash and convert the remaining slash to a +// period. +const ( + // PluginServiceInitializeProcedure is the fully-qualified name of the PluginService's Initialize + // RPC. + PluginServiceInitializeProcedure = "/plugin.v1.PluginService/Initialize" + // PluginServiceShutdownProcedure is the fully-qualified name of the PluginService's Shutdown RPC. + PluginServiceShutdownProcedure = "/plugin.v1.PluginService/Shutdown" + // PluginServiceHealthCheckProcedure is the fully-qualified name of the PluginService's HealthCheck + // RPC. + PluginServiceHealthCheckProcedure = "/plugin.v1.PluginService/HealthCheck" + // PluginServiceGetManifestProcedure is the fully-qualified name of the PluginService's GetManifest + // RPC. + PluginServiceGetManifestProcedure = "/plugin.v1.PluginService/GetManifest" + // PluginServiceOnEventProcedure is the fully-qualified name of the PluginService's OnEvent RPC. + PluginServiceOnEventProcedure = "/plugin.v1.PluginService/OnEvent" + // PluginServiceHandleHTTPProcedure is the fully-qualified name of the PluginService's HandleHTTP + // RPC. + PluginServiceHandleHTTPProcedure = "/plugin.v1.PluginService/HandleHTTP" +) + +// PluginServiceClient is a client for the plugin.v1.PluginService service. +type PluginServiceClient interface { + // Initialize is called when the server starts or the plugin is loaded + Initialize(context.Context, *connect.Request[pluginv1.InitializeRequest]) (*connect.Response[pluginv1.InitializeResponse], error) + // Shutdown is called when the server is shutting down + Shutdown(context.Context, *connect.Request[pluginv1.ShutdownRequest]) (*connect.Response[pluginv1.ShutdownResponse], error) + // HealthCheck checks if the plugin is healthy + HealthCheck(context.Context, *connect.Request[pluginv1.HealthCheckRequest]) (*connect.Response[pluginv1.HealthCheckResponse], error) + // GetManifest returns the plugin's manifest describing its capabilities + GetManifest(context.Context, *connect.Request[pluginv1.GetManifestRequest]) (*connect.Response[pluginv1.PluginManifest], error) + // OnEvent is called when an event the plugin is subscribed to occurs + OnEvent(context.Context, *connect.Request[pluginv1.PluginEvent]) (*connect.Response[pluginv1.EventResponse], error) + // HandleHTTP proxies an HTTP request to the plugin + HandleHTTP(context.Context, *connect.Request[pluginv1.HTTPRequest]) (*connect.Response[pluginv1.HTTPResponse], error) +} + +// NewPluginServiceClient constructs a client for the plugin.v1.PluginService service. By default, +// it uses the Connect protocol with the binary Protobuf Codec, asks for gzipped responses, and +// sends uncompressed requests. To use the gRPC or gRPC-Web protocols, supply the connect.WithGRPC() +// or connect.WithGRPCWeb() options. +// +// The URL supplied here should be the base URL for the Connect or gRPC server (for example, +// http://api.acme.com or https://acme.com/grpc). +func NewPluginServiceClient(httpClient connect.HTTPClient, baseURL string, opts ...connect.ClientOption) PluginServiceClient { + baseURL = strings.TrimRight(baseURL, "/") + pluginServiceMethods := pluginv1.File_modules_plugins_pluginv1_plugin_proto.Services().ByName("PluginService").Methods() + return &pluginServiceClient{ + initialize: connect.NewClient[pluginv1.InitializeRequest, pluginv1.InitializeResponse]( + httpClient, + baseURL+PluginServiceInitializeProcedure, + connect.WithSchema(pluginServiceMethods.ByName("Initialize")), + connect.WithClientOptions(opts...), + ), + shutdown: connect.NewClient[pluginv1.ShutdownRequest, pluginv1.ShutdownResponse]( + httpClient, + baseURL+PluginServiceShutdownProcedure, + connect.WithSchema(pluginServiceMethods.ByName("Shutdown")), + connect.WithClientOptions(opts...), + ), + healthCheck: connect.NewClient[pluginv1.HealthCheckRequest, pluginv1.HealthCheckResponse]( + httpClient, + baseURL+PluginServiceHealthCheckProcedure, + connect.WithSchema(pluginServiceMethods.ByName("HealthCheck")), + connect.WithClientOptions(opts...), + ), + getManifest: connect.NewClient[pluginv1.GetManifestRequest, pluginv1.PluginManifest]( + httpClient, + baseURL+PluginServiceGetManifestProcedure, + connect.WithSchema(pluginServiceMethods.ByName("GetManifest")), + connect.WithClientOptions(opts...), + ), + onEvent: connect.NewClient[pluginv1.PluginEvent, pluginv1.EventResponse]( + httpClient, + baseURL+PluginServiceOnEventProcedure, + connect.WithSchema(pluginServiceMethods.ByName("OnEvent")), + connect.WithClientOptions(opts...), + ), + handleHTTP: connect.NewClient[pluginv1.HTTPRequest, pluginv1.HTTPResponse]( + httpClient, + baseURL+PluginServiceHandleHTTPProcedure, + connect.WithSchema(pluginServiceMethods.ByName("HandleHTTP")), + connect.WithClientOptions(opts...), + ), + } +} + +// pluginServiceClient implements PluginServiceClient. +type pluginServiceClient struct { + initialize *connect.Client[pluginv1.InitializeRequest, pluginv1.InitializeResponse] + shutdown *connect.Client[pluginv1.ShutdownRequest, pluginv1.ShutdownResponse] + healthCheck *connect.Client[pluginv1.HealthCheckRequest, pluginv1.HealthCheckResponse] + getManifest *connect.Client[pluginv1.GetManifestRequest, pluginv1.PluginManifest] + onEvent *connect.Client[pluginv1.PluginEvent, pluginv1.EventResponse] + handleHTTP *connect.Client[pluginv1.HTTPRequest, pluginv1.HTTPResponse] +} + +// Initialize calls plugin.v1.PluginService.Initialize. +func (c *pluginServiceClient) Initialize(ctx context.Context, req *connect.Request[pluginv1.InitializeRequest]) (*connect.Response[pluginv1.InitializeResponse], error) { + return c.initialize.CallUnary(ctx, req) +} + +// Shutdown calls plugin.v1.PluginService.Shutdown. +func (c *pluginServiceClient) Shutdown(ctx context.Context, req *connect.Request[pluginv1.ShutdownRequest]) (*connect.Response[pluginv1.ShutdownResponse], error) { + return c.shutdown.CallUnary(ctx, req) +} + +// HealthCheck calls plugin.v1.PluginService.HealthCheck. +func (c *pluginServiceClient) HealthCheck(ctx context.Context, req *connect.Request[pluginv1.HealthCheckRequest]) (*connect.Response[pluginv1.HealthCheckResponse], error) { + return c.healthCheck.CallUnary(ctx, req) +} + +// GetManifest calls plugin.v1.PluginService.GetManifest. +func (c *pluginServiceClient) GetManifest(ctx context.Context, req *connect.Request[pluginv1.GetManifestRequest]) (*connect.Response[pluginv1.PluginManifest], error) { + return c.getManifest.CallUnary(ctx, req) +} + +// OnEvent calls plugin.v1.PluginService.OnEvent. +func (c *pluginServiceClient) OnEvent(ctx context.Context, req *connect.Request[pluginv1.PluginEvent]) (*connect.Response[pluginv1.EventResponse], error) { + return c.onEvent.CallUnary(ctx, req) +} + +// HandleHTTP calls plugin.v1.PluginService.HandleHTTP. +func (c *pluginServiceClient) HandleHTTP(ctx context.Context, req *connect.Request[pluginv1.HTTPRequest]) (*connect.Response[pluginv1.HTTPResponse], error) { + return c.handleHTTP.CallUnary(ctx, req) +} + +// PluginServiceHandler is an implementation of the plugin.v1.PluginService service. +type PluginServiceHandler interface { + // Initialize is called when the server starts or the plugin is loaded + Initialize(context.Context, *connect.Request[pluginv1.InitializeRequest]) (*connect.Response[pluginv1.InitializeResponse], error) + // Shutdown is called when the server is shutting down + Shutdown(context.Context, *connect.Request[pluginv1.ShutdownRequest]) (*connect.Response[pluginv1.ShutdownResponse], error) + // HealthCheck checks if the plugin is healthy + HealthCheck(context.Context, *connect.Request[pluginv1.HealthCheckRequest]) (*connect.Response[pluginv1.HealthCheckResponse], error) + // GetManifest returns the plugin's manifest describing its capabilities + GetManifest(context.Context, *connect.Request[pluginv1.GetManifestRequest]) (*connect.Response[pluginv1.PluginManifest], error) + // OnEvent is called when an event the plugin is subscribed to occurs + OnEvent(context.Context, *connect.Request[pluginv1.PluginEvent]) (*connect.Response[pluginv1.EventResponse], error) + // HandleHTTP proxies an HTTP request to the plugin + HandleHTTP(context.Context, *connect.Request[pluginv1.HTTPRequest]) (*connect.Response[pluginv1.HTTPResponse], error) +} + +// NewPluginServiceHandler builds an HTTP handler from the service implementation. It returns the +// path on which to mount the handler and the handler itself. +// +// By default, handlers support the Connect, gRPC, and gRPC-Web protocols with the binary Protobuf +// and JSON codecs. They also support gzip compression. +func NewPluginServiceHandler(svc PluginServiceHandler, opts ...connect.HandlerOption) (string, http.Handler) { + pluginServiceMethods := pluginv1.File_modules_plugins_pluginv1_plugin_proto.Services().ByName("PluginService").Methods() + pluginServiceInitializeHandler := connect.NewUnaryHandler( + PluginServiceInitializeProcedure, + svc.Initialize, + connect.WithSchema(pluginServiceMethods.ByName("Initialize")), + connect.WithHandlerOptions(opts...), + ) + pluginServiceShutdownHandler := connect.NewUnaryHandler( + PluginServiceShutdownProcedure, + svc.Shutdown, + connect.WithSchema(pluginServiceMethods.ByName("Shutdown")), + connect.WithHandlerOptions(opts...), + ) + pluginServiceHealthCheckHandler := connect.NewUnaryHandler( + PluginServiceHealthCheckProcedure, + svc.HealthCheck, + connect.WithSchema(pluginServiceMethods.ByName("HealthCheck")), + connect.WithHandlerOptions(opts...), + ) + pluginServiceGetManifestHandler := connect.NewUnaryHandler( + PluginServiceGetManifestProcedure, + svc.GetManifest, + connect.WithSchema(pluginServiceMethods.ByName("GetManifest")), + connect.WithHandlerOptions(opts...), + ) + pluginServiceOnEventHandler := connect.NewUnaryHandler( + PluginServiceOnEventProcedure, + svc.OnEvent, + connect.WithSchema(pluginServiceMethods.ByName("OnEvent")), + connect.WithHandlerOptions(opts...), + ) + pluginServiceHandleHTTPHandler := connect.NewUnaryHandler( + PluginServiceHandleHTTPProcedure, + svc.HandleHTTP, + connect.WithSchema(pluginServiceMethods.ByName("HandleHTTP")), + connect.WithHandlerOptions(opts...), + ) + return "/plugin.v1.PluginService/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + switch r.URL.Path { + case PluginServiceInitializeProcedure: + pluginServiceInitializeHandler.ServeHTTP(w, r) + case PluginServiceShutdownProcedure: + pluginServiceShutdownHandler.ServeHTTP(w, r) + case PluginServiceHealthCheckProcedure: + pluginServiceHealthCheckHandler.ServeHTTP(w, r) + case PluginServiceGetManifestProcedure: + pluginServiceGetManifestHandler.ServeHTTP(w, r) + case PluginServiceOnEventProcedure: + pluginServiceOnEventHandler.ServeHTTP(w, r) + case PluginServiceHandleHTTPProcedure: + pluginServiceHandleHTTPHandler.ServeHTTP(w, r) + default: + http.NotFound(w, r) + } + }) +} + +// UnimplementedPluginServiceHandler returns CodeUnimplemented from all methods. +type UnimplementedPluginServiceHandler struct{} + +func (UnimplementedPluginServiceHandler) Initialize(context.Context, *connect.Request[pluginv1.InitializeRequest]) (*connect.Response[pluginv1.InitializeResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("plugin.v1.PluginService.Initialize is not implemented")) +} + +func (UnimplementedPluginServiceHandler) Shutdown(context.Context, *connect.Request[pluginv1.ShutdownRequest]) (*connect.Response[pluginv1.ShutdownResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("plugin.v1.PluginService.Shutdown is not implemented")) +} + +func (UnimplementedPluginServiceHandler) HealthCheck(context.Context, *connect.Request[pluginv1.HealthCheckRequest]) (*connect.Response[pluginv1.HealthCheckResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("plugin.v1.PluginService.HealthCheck is not implemented")) +} + +func (UnimplementedPluginServiceHandler) GetManifest(context.Context, *connect.Request[pluginv1.GetManifestRequest]) (*connect.Response[pluginv1.PluginManifest], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("plugin.v1.PluginService.GetManifest is not implemented")) +} + +func (UnimplementedPluginServiceHandler) OnEvent(context.Context, *connect.Request[pluginv1.PluginEvent]) (*connect.Response[pluginv1.EventResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("plugin.v1.PluginService.OnEvent is not implemented")) +} + +func (UnimplementedPluginServiceHandler) HandleHTTP(context.Context, *connect.Request[pluginv1.HTTPRequest]) (*connect.Response[pluginv1.HTTPResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("plugin.v1.PluginService.HandleHTTP is not implemented")) +} diff --git a/modules/plugins/pluginv1/types.go b/modules/plugins/pluginv1/types.go deleted file mode 100644 index e18da5c78f..0000000000 --- a/modules/plugins/pluginv1/types.go +++ /dev/null @@ -1,81 +0,0 @@ -// Copyright 2026 MarketAlly. All rights reserved. -// SPDX-License-Identifier: MIT - -// Package pluginv1 defines the plugin service contract types. -// These types mirror the plugin.proto definitions and will be replaced -// by generated code when protoc-gen-go and protoc-gen-connect-go are run. -package pluginv1 - -import "time" - -type InitializeRequest struct { - ServerVersion string `json:"server_version"` - Config map[string]string `json:"config"` -} - -type InitializeResponse struct { - Success bool `json:"success"` - Error string `json:"error"` - Manifest *PluginManifest `json:"manifest"` -} - -type ShutdownRequest struct { - Reason string `json:"reason"` -} - -type ShutdownResponse struct { - Success bool `json:"success"` -} - -type HealthCheckRequest struct{} - -type HealthCheckResponse struct { - Healthy bool `json:"healthy"` - Status string `json:"status"` - Details map[string]string `json:"details"` -} - -type GetManifestRequest struct{} - -type PluginManifest struct { - Name string `json:"name"` - Version string `json:"version"` - Description string `json:"description"` - SubscribedEvents []string `json:"subscribed_events"` - Routes []PluginRoute `json:"routes"` - RequiredPermissions []string `json:"required_permissions"` - LicenseTier string `json:"license_tier"` -} - -type PluginRoute struct { - Method string `json:"method"` - Path string `json:"path"` - Description string `json:"description"` -} - -type PluginEvent struct { - EventType string `json:"event_type"` - Payload map[string]any `json:"payload"` - Timestamp time.Time `json:"timestamp"` - RepoID int64 `json:"repo_id"` - OrgID int64 `json:"org_id"` -} - -type EventResponse struct { - Handled bool `json:"handled"` - Error string `json:"error"` -} - -type HTTPRequest struct { - Method string `json:"method"` - Path string `json:"path"` - Headers map[string]string `json:"headers"` - Body []byte `json:"body"` - QueryParams map[string]string `json:"query_params"` -} - -type HTTPResponse struct { - StatusCode int `json:"status_code"` - Headers map[string]string `json:"headers"` - Body []byte `json:"body"` -}