aboutsummaryrefslogtreecommitdiff
path: root/internal/adminpb
diff options
context:
space:
mode:
authorXe Iaso <me@xeiaso.net>2024-02-12 04:32:43 -0800
committerXe Iaso <me@xeiaso.net>2024-02-12 04:32:43 -0800
commite02b9ef3ee4394db1a387b146aa5faeea95efa3a (patch)
treee5b6f2c7c21dda6a5e4ea1617e10e3437c93979c /internal/adminpb
parent0eb26108f65b68aa4e99786f7f7a0b28cd356f72 (diff)
downloadxesite-e02b9ef3ee4394db1a387b146aa5faeea95efa3a.tar.xz
xesite-e02b9ef3ee4394db1a387b146aa5faeea95efa3a.zip
cmd/patreon-saasproxy: use twirp/protobuf instead of yolo json
Signed-off-by: Xe Iaso <me@xeiaso.net>
Diffstat (limited to 'internal/adminpb')
-rw-r--r--internal/adminpb/generate.go5
-rw-r--r--internal/adminpb/internal.pb.go201
-rw-r--r--internal/adminpb/internal.proto22
-rw-r--r--internal/adminpb/internal.twirp.go1607
4 files changed, 1835 insertions, 0 deletions
diff --git a/internal/adminpb/generate.go b/internal/adminpb/generate.go
new file mode 100644
index 0000000..29a5216
--- /dev/null
+++ b/internal/adminpb/generate.go
@@ -0,0 +1,5 @@
+package adminpb
+
+func init() {}
+
+//go:generate protoc --proto_path=. --proto_path=../../pb --go_out=. --go_opt=paths=source_relative --twirp_out=. --twirp_opt=paths=source_relative internal.proto
diff --git a/internal/adminpb/internal.pb.go b/internal/adminpb/internal.pb.go
new file mode 100644
index 0000000..fc47e2b
--- /dev/null
+++ b/internal/adminpb/internal.pb.go
@@ -0,0 +1,201 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// protoc-gen-go v1.32.0
+// protoc v4.24.4
+// source: internal.proto
+
+package adminpb
+
+import (
+ protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+ protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+ emptypb "google.golang.org/protobuf/types/known/emptypb"
+ timestamppb "google.golang.org/protobuf/types/known/timestamppb"
+ reflect "reflect"
+ sync "sync"
+ pb "xeiaso.net/v4/pb"
+)
+
+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 PatreonToken struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ AccessToken string `protobuf:"bytes,1,opt,name=access_token,json=accessToken,proto3" json:"access_token,omitempty"`
+ TokenType string `protobuf:"bytes,2,opt,name=token_type,json=tokenType,proto3" json:"token_type,omitempty"`
+ RefreshToken string `protobuf:"bytes,3,opt,name=refresh_token,json=refreshToken,proto3" json:"refresh_token,omitempty"`
+ Expiry *timestamppb.Timestamp `protobuf:"bytes,4,opt,name=expiry,proto3" json:"expiry,omitempty"`
+}
+
+func (x *PatreonToken) Reset() {
+ *x = PatreonToken{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_internal_proto_msgTypes[0]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *PatreonToken) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*PatreonToken) ProtoMessage() {}
+
+func (x *PatreonToken) ProtoReflect() protoreflect.Message {
+ mi := &file_internal_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 PatreonToken.ProtoReflect.Descriptor instead.
+func (*PatreonToken) Descriptor() ([]byte, []int) {
+ return file_internal_proto_rawDescGZIP(), []int{0}
+}
+
+func (x *PatreonToken) GetAccessToken() string {
+ if x != nil {
+ return x.AccessToken
+ }
+ return ""
+}
+
+func (x *PatreonToken) GetTokenType() string {
+ if x != nil {
+ return x.TokenType
+ }
+ return ""
+}
+
+func (x *PatreonToken) GetRefreshToken() string {
+ if x != nil {
+ return x.RefreshToken
+ }
+ return ""
+}
+
+func (x *PatreonToken) GetExpiry() *timestamppb.Timestamp {
+ if x != nil {
+ return x.Expiry
+ }
+ return nil
+}
+
+var File_internal_proto protoreflect.FileDescriptor
+
+var file_internal_proto_rawDesc = []byte{
+ 0x0a, 0x0e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+ 0x12, 0x13, 0x78, 0x65, 0x69, 0x61, 0x73, 0x6f, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x69, 0x6e, 0x74,
+ 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72,
+ 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 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, 0x1a, 0x0c, 0x78, 0x65, 0x73, 0x69, 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74,
+ 0x6f, 0x22, 0xa9, 0x01, 0x0a, 0x0c, 0x50, 0x61, 0x74, 0x72, 0x65, 0x6f, 0x6e, 0x54, 0x6f, 0x6b,
+ 0x65, 0x6e, 0x12, 0x21, 0x0a, 0x0c, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x74, 0x6f, 0x6b,
+ 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73,
+ 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x74,
+ 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x6f, 0x6b, 0x65, 0x6e,
+ 0x54, 0x79, 0x70, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x5f,
+ 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, 0x66,
+ 0x72, 0x65, 0x73, 0x68, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x32, 0x0a, 0x06, 0x65, 0x78, 0x70,
+ 0x69, 0x72, 0x79, 0x18, 0x04, 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, 0x06, 0x65, 0x78, 0x70, 0x69, 0x72, 0x79, 0x32, 0x50, 0x0a,
+ 0x07, 0x50, 0x61, 0x74, 0x72, 0x65, 0x6f, 0x6e, 0x12, 0x45, 0x0a, 0x08, 0x47, 0x65, 0x74, 0x54,
+ 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72,
+ 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x21, 0x2e, 0x78,
+ 0x65, 0x69, 0x61, 0x73, 0x6f, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e,
+ 0x61, 0x6c, 0x2e, 0x50, 0x61, 0x74, 0x72, 0x65, 0x6f, 0x6e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x32,
+ 0x41, 0x0a, 0x05, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x12, 0x38, 0x0a, 0x07, 0x52, 0x65, 0x62, 0x75,
+ 0x69, 0x6c, 0x64, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f,
+ 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x15, 0x2e, 0x78, 0x65,
+ 0x69, 0x61, 0x73, 0x6f, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x49, 0x6e,
+ 0x66, 0x6f, 0x42, 0x20, 0x5a, 0x1e, 0x78, 0x65, 0x69, 0x61, 0x73, 0x6f, 0x2e, 0x6e, 0x65, 0x74,
+ 0x2f, 0x76, 0x34, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x61, 0x64, 0x6d,
+ 0x69, 0x6e, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+}
+
+var (
+ file_internal_proto_rawDescOnce sync.Once
+ file_internal_proto_rawDescData = file_internal_proto_rawDesc
+)
+
+func file_internal_proto_rawDescGZIP() []byte {
+ file_internal_proto_rawDescOnce.Do(func() {
+ file_internal_proto_rawDescData = protoimpl.X.CompressGZIP(file_internal_proto_rawDescData)
+ })
+ return file_internal_proto_rawDescData
+}
+
+var file_internal_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
+var file_internal_proto_goTypes = []interface{}{
+ (*PatreonToken)(nil), // 0: xeiaso.net.internal.PatreonToken
+ (*timestamppb.Timestamp)(nil), // 1: google.protobuf.Timestamp
+ (*emptypb.Empty)(nil), // 2: google.protobuf.Empty
+ (*pb.BuildInfo)(nil), // 3: xeiaso.net.BuildInfo
+}
+var file_internal_proto_depIdxs = []int32{
+ 1, // 0: xeiaso.net.internal.PatreonToken.expiry:type_name -> google.protobuf.Timestamp
+ 2, // 1: xeiaso.net.internal.Patreon.GetToken:input_type -> google.protobuf.Empty
+ 2, // 2: xeiaso.net.internal.Admin.Rebuild:input_type -> google.protobuf.Empty
+ 0, // 3: xeiaso.net.internal.Patreon.GetToken:output_type -> xeiaso.net.internal.PatreonToken
+ 3, // 4: xeiaso.net.internal.Admin.Rebuild:output_type -> xeiaso.net.BuildInfo
+ 3, // [3:5] is the sub-list for method output_type
+ 1, // [1:3] is the sub-list for method input_type
+ 1, // [1:1] is the sub-list for extension type_name
+ 1, // [1:1] is the sub-list for extension extendee
+ 0, // [0:1] is the sub-list for field type_name
+}
+
+func init() { file_internal_proto_init() }
+func file_internal_proto_init() {
+ if File_internal_proto != nil {
+ return
+ }
+ if !protoimpl.UnsafeEnabled {
+ file_internal_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*PatreonToken); 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_internal_proto_rawDesc,
+ NumEnums: 0,
+ NumMessages: 1,
+ NumExtensions: 0,
+ NumServices: 2,
+ },
+ GoTypes: file_internal_proto_goTypes,
+ DependencyIndexes: file_internal_proto_depIdxs,
+ MessageInfos: file_internal_proto_msgTypes,
+ }.Build()
+ File_internal_proto = out.File
+ file_internal_proto_rawDesc = nil
+ file_internal_proto_goTypes = nil
+ file_internal_proto_depIdxs = nil
+}
diff --git a/internal/adminpb/internal.proto b/internal/adminpb/internal.proto
new file mode 100644
index 0000000..a0755ff
--- /dev/null
+++ b/internal/adminpb/internal.proto
@@ -0,0 +1,22 @@
+syntax = "proto3";
+package xeiaso.net.internal.admin;
+option go_package = "xeiaso.net/v4/internal/adminpb";
+
+import "google/protobuf/empty.proto";
+import "google/protobuf/timestamp.proto";
+import "xesite.proto";
+
+service Patreon {
+ rpc GetToken (google.protobuf.Empty) returns (PatreonToken);
+}
+
+message PatreonToken {
+ string access_token = 1;
+ string token_type = 2;
+ string refresh_token = 3;
+ google.protobuf.Timestamp expiry = 4;
+}
+
+service Admin {
+ rpc Rebuild(google.protobuf.Empty) returns (xeiaso.net.BuildInfo);
+} \ No newline at end of file
diff --git a/internal/adminpb/internal.twirp.go b/internal/adminpb/internal.twirp.go
new file mode 100644
index 0000000..3ad3281
--- /dev/null
+++ b/internal/adminpb/internal.twirp.go
@@ -0,0 +1,1607 @@
+// Code generated by protoc-gen-twirp v8.1.3, DO NOT EDIT.
+// source: internal.proto
+
+package adminpb
+
+import context "context"
+import fmt "fmt"
+import http "net/http"
+import io "io"
+import json "encoding/json"
+import strconv "strconv"
+import strings "strings"
+
+import protojson "google.golang.org/protobuf/encoding/protojson"
+import proto "google.golang.org/protobuf/proto"
+import twirp "github.com/twitchtv/twirp"
+import ctxsetters "github.com/twitchtv/twirp/ctxsetters"
+
+import google_protobuf "google.golang.org/protobuf/types/known/emptypb"
+import xeiaso_net "xeiaso.net/v4/pb"
+
+import bytes "bytes"
+import errors "errors"
+import path "path"
+import url "net/url"
+
+// Version compatibility assertion.
+// If the constant is not defined in the package, that likely means
+// the package needs to be updated to work with this generated code.
+// See https://twitchtv.github.io/twirp/docs/version_matrix.html
+const _ = twirp.TwirpPackageMinVersion_8_1_0
+
+// =================
+// Patreon Interface
+// =================
+
+type Patreon interface {
+ GetToken(context.Context, *google_protobuf.Empty) (*PatreonToken, error)
+}
+
+// =======================
+// Patreon Protobuf Client
+// =======================
+
+type patreonProtobufClient struct {
+ client HTTPClient
+ urls [1]string
+ interceptor twirp.Interceptor
+ opts twirp.ClientOptions
+}
+
+// NewPatreonProtobufClient creates a Protobuf client that implements the Patreon interface.
+// It communicates using Protobuf and can be configured with a custom HTTPClient.
+func NewPatreonProtobufClient(baseURL string, client HTTPClient, opts ...twirp.ClientOption) Patreon {
+ if c, ok := client.(*http.Client); ok {
+ client = withoutRedirects(c)
+ }
+
+ clientOpts := twirp.ClientOptions{}
+ for _, o := range opts {
+ o(&clientOpts)
+ }
+
+ // Using ReadOpt allows backwards and forwards compatibility with new options in the future
+ literalURLs := false
+ _ = clientOpts.ReadOpt("literalURLs", &literalURLs)
+ var pathPrefix string
+ if ok := clientOpts.ReadOpt("pathPrefix", &pathPrefix); !ok {
+ pathPrefix = "/twirp" // default prefix
+ }
+
+ // Build method URLs: <baseURL>[<prefix>]/<package>.<Service>/<Method>
+ serviceURL := sanitizeBaseURL(baseURL)
+ serviceURL += baseServicePath(pathPrefix, "xeiaso.net.internal", "Patreon")
+ urls := [1]string{
+ serviceURL + "GetToken",
+ }
+
+ return &patreonProtobufClient{
+ client: client,
+ urls: urls,
+ interceptor: twirp.ChainInterceptors(clientOpts.Interceptors...),
+ opts: clientOpts,
+ }
+}
+
+func (c *patreonProtobufClient) GetToken(ctx context.Context, in *google_protobuf.Empty) (*PatreonToken, error) {
+ ctx = ctxsetters.WithPackageName(ctx, "xeiaso.net.internal")
+ ctx = ctxsetters.WithServiceName(ctx, "Patreon")
+ ctx = ctxsetters.WithMethodName(ctx, "GetToken")
+ caller := c.callGetToken
+ if c.interceptor != nil {
+ caller = func(ctx context.Context, req *google_protobuf.Empty) (*PatreonToken, error) {
+ resp, err := c.interceptor(
+ func(ctx context.Context, req interface{}) (interface{}, error) {
+ typedReq, ok := req.(*google_protobuf.Empty)
+ if !ok {
+ return nil, twirp.InternalError("failed type assertion req.(*google_protobuf.Empty) when calling interceptor")
+ }
+ return c.callGetToken(ctx, typedReq)
+ },
+ )(ctx, req)
+ if resp != nil {
+ typedResp, ok := resp.(*PatreonToken)
+ if !ok {
+ return nil, twirp.InternalError("failed type assertion resp.(*PatreonToken) when calling interceptor")
+ }
+ return typedResp, err
+ }
+ return nil, err
+ }
+ }
+ return caller(ctx, in)
+}
+
+func (c *patreonProtobufClient) callGetToken(ctx context.Context, in *google_protobuf.Empty) (*PatreonToken, error) {
+ out := new(PatreonToken)
+ ctx, err := doProtobufRequest(ctx, c.client, c.opts.Hooks, c.urls[0], in, out)
+ if err != nil {
+ twerr, ok := err.(twirp.Error)
+ if !ok {
+ twerr = twirp.InternalErrorWith(err)
+ }
+ callClientError(ctx, c.opts.Hooks, twerr)
+ return nil, err
+ }
+
+ callClientResponseReceived(ctx, c.opts.Hooks)
+
+ return out, nil
+}
+
+// ===================
+// Patreon JSON Client
+// ===================
+
+type patreonJSONClient struct {
+ client HTTPClient
+ urls [1]string
+ interceptor twirp.Interceptor
+ opts twirp.ClientOptions
+}
+
+// NewPatreonJSONClient creates a JSON client that implements the Patreon interface.
+// It communicates using JSON and can be configured with a custom HTTPClient.
+func NewPatreonJSONClient(baseURL string, client HTTPClient, opts ...twirp.ClientOption) Patreon {
+ if c, ok := client.(*http.Client); ok {
+ client = withoutRedirects(c)
+ }
+
+ clientOpts := twirp.ClientOptions{}
+ for _, o := range opts {
+ o(&clientOpts)
+ }
+
+ // Using ReadOpt allows backwards and forwards compatibility with new options in the future
+ literalURLs := false
+ _ = clientOpts.ReadOpt("literalURLs", &literalURLs)
+ var pathPrefix string
+ if ok := clientOpts.ReadOpt("pathPrefix", &pathPrefix); !ok {
+ pathPrefix = "/twirp" // default prefix
+ }
+
+ // Build method URLs: <baseURL>[<prefix>]/<package>.<Service>/<Method>
+ serviceURL := sanitizeBaseURL(baseURL)
+ serviceURL += baseServicePath(pathPrefix, "xeiaso.net.internal", "Patreon")
+ urls := [1]string{
+ serviceURL + "GetToken",
+ }
+
+ return &patreonJSONClient{
+ client: client,
+ urls: urls,
+ interceptor: twirp.ChainInterceptors(clientOpts.Interceptors...),
+ opts: clientOpts,
+ }
+}
+
+func (c *patreonJSONClient) GetToken(ctx context.Context, in *google_protobuf.Empty) (*PatreonToken, error) {
+ ctx = ctxsetters.WithPackageName(ctx, "xeiaso.net.internal")
+ ctx = ctxsetters.WithServiceName(ctx, "Patreon")
+ ctx = ctxsetters.WithMethodName(ctx, "GetToken")
+ caller := c.callGetToken
+ if c.interceptor != nil {
+ caller = func(ctx context.Context, req *google_protobuf.Empty) (*PatreonToken, error) {
+ resp, err := c.interceptor(
+ func(ctx context.Context, req interface{}) (interface{}, error) {
+ typedReq, ok := req.(*google_protobuf.Empty)
+ if !ok {
+ return nil, twirp.InternalError("failed type assertion req.(*google_protobuf.Empty) when calling interceptor")
+ }
+ return c.callGetToken(ctx, typedReq)
+ },
+ )(ctx, req)
+ if resp != nil {
+ typedResp, ok := resp.(*PatreonToken)
+ if !ok {
+ return nil, twirp.InternalError("failed type assertion resp.(*PatreonToken) when calling interceptor")
+ }
+ return typedResp, err
+ }
+ return nil, err
+ }
+ }
+ return caller(ctx, in)
+}
+
+func (c *patreonJSONClient) callGetToken(ctx context.Context, in *google_protobuf.Empty) (*PatreonToken, error) {
+ out := new(PatreonToken)
+ ctx, err := doJSONRequest(ctx, c.client, c.opts.Hooks, c.urls[0], in, out)
+ if err != nil {
+ twerr, ok := err.(twirp.Error)
+ if !ok {
+ twerr = twirp.InternalErrorWith(err)
+ }
+ callClientError(ctx, c.opts.Hooks, twerr)
+ return nil, err
+ }
+
+ callClientResponseReceived(ctx, c.opts.Hooks)
+
+ return out, nil
+}
+
+// ======================
+// Patreon Server Handler
+// ======================
+
+type patreonServer struct {
+ Patreon
+ interceptor twirp.Interceptor
+ hooks *twirp.ServerHooks
+ pathPrefix string // prefix for routing
+ jsonSkipDefaults bool // do not include unpopulated fields (default values) in the response
+ jsonCamelCase bool // JSON fields are serialized as lowerCamelCase rather than keeping the original proto names
+}
+
+// NewPatreonServer builds a TwirpServer that can be used as an http.Handler to handle
+// HTTP requests that are routed to the right method in the provided svc implementation.
+// The opts are twirp.ServerOption modifiers, for example twirp.WithServerHooks(hooks).
+func NewPatreonServer(svc Patreon, opts ...interface{}) TwirpServer {
+ serverOpts := newServerOpts(opts)
+
+ // Using ReadOpt allows backwards and forwards compatibility with new options in the future
+ jsonSkipDefaults := false
+ _ = serverOpts.ReadOpt("jsonSkipDefaults", &jsonSkipDefaults)
+ jsonCamelCase := false
+ _ = serverOpts.ReadOpt("jsonCamelCase", &jsonCamelCase)
+ var pathPrefix string
+ if ok := serverOpts.ReadOpt("pathPrefix", &pathPrefix); !ok {
+ pathPrefix = "/twirp" // default prefix
+ }
+
+ return &patreonServer{
+ Patreon: svc,
+ hooks: serverOpts.Hooks,
+ interceptor: twirp.ChainInterceptors(serverOpts.Interceptors...),
+ pathPrefix: pathPrefix,
+ jsonSkipDefaults: jsonSkipDefaults,
+ jsonCamelCase: jsonCamelCase,
+ }
+}
+
+// writeError writes an HTTP response with a valid Twirp error format, and triggers hooks.
+// If err is not a twirp.Error, it will get wrapped with twirp.InternalErrorWith(err)
+func (s *patreonServer) writeError(ctx context.Context, resp http.ResponseWriter, err error) {
+ writeError(ctx, resp, err, s.hooks)
+}
+
+// handleRequestBodyError is used to handle error when the twirp server cannot read request
+func (s *patreonServer) handleRequestBodyError(ctx context.Context, resp http.ResponseWriter, msg string, err error) {
+ if context.Canceled == ctx.Err() {
+ s.writeError(ctx, resp, twirp.NewError(twirp.Canceled, "failed to read request: context canceled"))
+ return
+ }
+ if context.DeadlineExceeded == ctx.Err() {
+ s.writeError(ctx, resp, twirp.NewError(twirp.DeadlineExceeded, "failed to read request: deadline exceeded"))
+ return
+ }
+ s.writeError(ctx, resp, twirp.WrapError(malformedRequestError(msg), err))
+}
+
+// PatreonPathPrefix is a convenience constant that may identify URL paths.
+// Should be used with caution, it only matches routes generated by Twirp Go clients,
+// with the default "/twirp" prefix and default CamelCase service and method names.
+// More info: https://twitchtv.github.io/twirp/docs/routing.html
+const PatreonPathPrefix = "/twirp/xeiaso.net.internal.Patreon/"
+
+func (s *patreonServer) ServeHTTP(resp http.ResponseWriter, req *http.Request) {
+ ctx := req.Context()
+ ctx = ctxsetters.WithPackageName(ctx, "xeiaso.net.internal")
+ ctx = ctxsetters.WithServiceName(ctx, "Patreon")
+ ctx = ctxsetters.WithResponseWriter(ctx, resp)
+
+ var err error
+ ctx, err = callRequestReceived(ctx, s.hooks)
+ if err != nil {
+ s.writeError(ctx, resp, err)
+ return
+ }
+
+ if req.Method != "POST" {
+ msg := fmt.Sprintf("unsupported method %q (only POST is allowed)", req.Method)
+ s.writeError(ctx, resp, badRouteError(msg, req.Method, req.URL.Path))
+ return
+ }
+
+ // Verify path format: [<prefix>]/<package>.<Service>/<Method>
+ prefix, pkgService, method := parseTwirpPath(req.URL.Path)
+ if pkgService != "xeiaso.net.internal.Patreon" {
+ msg := fmt.Sprintf("no handler for path %q", req.URL.Path)
+ s.writeError(ctx, resp, badRouteError(msg, req.Method, req.URL.Path))
+ return
+ }
+ if prefix != s.pathPrefix {
+ msg := fmt.Sprintf("invalid path prefix %q, expected %q, on path %q", prefix, s.pathPrefix, req.URL.Path)
+ s.writeError(ctx, resp, badRouteError(msg, req.Method, req.URL.Path))
+ return
+ }
+
+ switch method {
+ case "GetToken":
+ s.serveGetToken(ctx, resp, req)
+ return
+ default:
+ msg := fmt.Sprintf("no handler for path %q", req.URL.Path)
+ s.writeError(ctx, resp, badRouteError(msg, req.Method, req.URL.Path))
+ return
+ }
+}
+
+func (s *patreonServer) serveGetToken(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
+ header := req.Header.Get("Content-Type")
+ i := strings.Index(header, ";")
+ if i == -1 {
+ i = len(header)
+ }
+ switch strings.TrimSpace(strings.ToLower(header[:i])) {
+ case "application/json":
+ s.serveGetTokenJSON(ctx, resp, req)
+ case "application/protobuf":
+ s.serveGetTokenProtobuf(ctx, resp, req)
+ default:
+ msg := fmt.Sprintf("unexpected Content-Type: %q", req.Header.Get("Content-Type"))
+ twerr := badRouteError(msg, req.Method, req.URL.Path)
+ s.writeError(ctx, resp, twerr)
+ }
+}
+
+func (s *patreonServer) serveGetTokenJSON(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
+ var err error
+ ctx = ctxsetters.WithMethodName(ctx, "GetToken")
+ ctx, err = callRequestRouted(ctx, s.hooks)
+ if err != nil {
+ s.writeError(ctx, resp, err)
+ return
+ }
+
+ d := json.NewDecoder(req.Body)
+ rawReqBody := json.RawMessage{}
+ if err := d.Decode(&rawReqBody); err != nil {
+ s.handleRequestBodyError(ctx, resp, "the json request could not be decoded", err)
+ return
+ }
+ reqContent := new(google_protobuf.Empty)
+ unmarshaler := protojson.UnmarshalOptions{DiscardUnknown: true}
+ if err = unmarshaler.Unmarshal(rawReqBody, reqContent); err != nil {
+ s.handleRequestBodyError(ctx, resp, "the json request could not be decoded", err)
+ return
+ }
+
+ handler := s.Patreon.GetToken
+ if s.interceptor != nil {
+ handler = func(ctx context.Context, req *google_protobuf.Empty) (*PatreonToken, error) {
+ resp, err := s.interceptor(
+ func(ctx context.Context, req interface{}) (interface{}, error) {
+ typedReq, ok := req.(*google_protobuf.Empty)
+ if !ok {
+ return nil, twirp.InternalError("failed type assertion req.(*google_protobuf.Empty) when calling interceptor")
+ }
+ return s.Patreon.GetToken(ctx, typedReq)
+ },
+ )(ctx, req)
+ if resp != nil {
+ typedResp, ok := resp.(*PatreonToken)
+ if !ok {
+ return nil, twirp.InternalError("failed type assertion resp.(*PatreonToken) when calling interceptor")
+ }
+ return typedResp, err
+ }
+ return nil, err
+ }
+ }
+
+ // Call service method
+ var respContent *PatreonToken
+ func() {
+ defer ensurePanicResponses(ctx, resp, s.hooks)
+ respContent, err = handler(ctx, reqContent)
+ }()
+
+ if err != nil {
+ s.writeError(ctx, resp, err)
+ return
+ }
+ if respContent == nil {
+ s.writeError(ctx, resp, twirp.InternalError("received a nil *PatreonToken and nil error while calling GetToken. nil responses are not supported"))
+ return
+ }
+
+ ctx = callResponsePrepared(ctx, s.hooks)
+
+ marshaler := &protojson.MarshalOptions{UseProtoNames: !s.jsonCamelCase, EmitUnpopulated: !s.jsonSkipDefaults}
+ respBytes, err := marshaler.Marshal(respContent)
+ if err != nil {
+ s.writeError(ctx, resp, wrapInternal(err, "failed to marshal json response"))
+ return
+ }
+
+ ctx = ctxsetters.WithStatusCode(ctx, http.StatusOK)
+ resp.Header().Set("Content-Type", "application/json")
+ resp.Header().Set("Content-Length", strconv.Itoa(len(respBytes)))
+ resp.WriteHeader(http.StatusOK)
+
+ if n, err := resp.Write(respBytes); err != nil {
+ msg := fmt.Sprintf("failed to write response, %d of %d bytes written: %s", n, len(respBytes), err.Error())
+ twerr := twirp.NewError(twirp.Unknown, msg)
+ ctx = callError(ctx, s.hooks, twerr)
+ }
+ callResponseSent(ctx, s.hooks)
+}
+
+func (s *patreonServer) serveGetTokenProtobuf(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
+ var err error
+ ctx = ctxsetters.WithMethodName(ctx, "GetToken")
+ ctx, err = callRequestRouted(ctx, s.hooks)
+ if err != nil {
+ s.writeError(ctx, resp, err)
+ return
+ }
+
+ buf, err := io.ReadAll(req.Body)
+ if err != nil {
+ s.handleRequestBodyError(ctx, resp, "failed to read request body", err)
+ return
+ }
+ reqContent := new(google_protobuf.Empty)
+ if err = proto.Unmarshal(buf, reqContent); err != nil {
+ s.writeError(ctx, resp, malformedRequestError("the protobuf request could not be decoded"))
+ return
+ }
+
+ handler := s.Patreon.GetToken
+ if s.interceptor != nil {
+ handler = func(ctx context.Context, req *google_protobuf.Empty) (*PatreonToken, error) {
+ resp, err := s.interceptor(
+ func(ctx context.Context, req interface{}) (interface{}, error) {
+ typedReq, ok := req.(*google_protobuf.Empty)
+ if !ok {
+ return nil, twirp.InternalError("failed type assertion req.(*google_protobuf.Empty) when calling interceptor")
+ }
+ return s.Patreon.GetToken(ctx, typedReq)
+ },
+ )(ctx, req)
+ if resp != nil {
+ typedResp, ok := resp.(*PatreonToken)
+ if !ok {
+ return nil, twirp.InternalError("failed type assertion resp.(*PatreonToken) when calling interceptor")
+ }
+ return typedResp, err
+ }
+ return nil, err
+ }
+ }
+
+ // Call service method
+ var respContent *PatreonToken
+ func() {
+ defer ensurePanicResponses(ctx, resp, s.hooks)
+ respContent, err = handler(ctx, reqContent)
+ }()
+
+ if err != nil {
+ s.writeError(ctx, resp, err)
+ return
+ }
+ if respContent == nil {
+ s.writeError(ctx, resp, twirp.InternalError("received a nil *PatreonToken and nil error while calling GetToken. nil responses are not supported"))
+ return
+ }
+
+ ctx = callResponsePrepared(ctx, s.hooks)
+
+ respBytes, err := proto.Marshal(respContent)
+ if err != nil {
+ s.writeError(ctx, resp, wrapInternal(err, "failed to marshal proto response"))
+ return
+ }
+
+ ctx = ctxsetters.WithStatusCode(ctx, http.StatusOK)
+ resp.Header().Set("Content-Type", "application/protobuf")
+ resp.Header().Set("Content-Length", strconv.Itoa(len(respBytes)))
+ resp.WriteHeader(http.StatusOK)
+ if n, err := resp.Write(respBytes); err != nil {
+ msg := fmt.Sprintf("failed to write response, %d of %d bytes written: %s", n, len(respBytes), err.Error())
+ twerr := twirp.NewError(twirp.Unknown, msg)
+ ctx = callError(ctx, s.hooks, twerr)
+ }
+ callResponseSent(ctx, s.hooks)
+}
+
+func (s *patreonServer) ServiceDescriptor() ([]byte, int) {
+ return twirpFileDescriptor0, 0
+}
+
+func (s *patreonServer) ProtocGenTwirpVersion() string {
+ return "v8.1.3"
+}
+
+// PathPrefix returns the base service path, in the form: "/<prefix>/<package>.<Service>/"
+// that is everything in a Twirp route except for the <Method>. This can be used for routing,
+// for example to identify the requests that are targeted to this service in a mux.
+func (s *patreonServer) PathPrefix() string {
+ return baseServicePath(s.pathPrefix, "xeiaso.net.internal", "Patreon")
+}
+
+// ===============
+// Admin Interface
+// ===============
+
+type Admin interface {
+ Rebuild(context.Context, *google_protobuf.Empty) (*xeiaso_net.BuildInfo, error)
+}
+
+// =====================
+// Admin Protobuf Client
+// =====================
+
+type adminProtobufClient struct {
+ client HTTPClient
+ urls [1]string
+ interceptor twirp.Interceptor
+ opts twirp.ClientOptions
+}
+
+// NewAdminProtobufClient creates a Protobuf client that implements the Admin interface.
+// It communicates using Protobuf and can be configured with a custom HTTPClient.
+func NewAdminProtobufClient(baseURL string, client HTTPClient, opts ...twirp.ClientOption) Admin {
+ if c, ok := client.(*http.Client); ok {
+ client = withoutRedirects(c)
+ }
+
+ clientOpts := twirp.ClientOptions{}
+ for _, o := range opts {
+ o(&clientOpts)
+ }
+
+ // Using ReadOpt allows backwards and forwards compatibility with new options in the future
+ literalURLs := false
+ _ = clientOpts.ReadOpt("literalURLs", &literalURLs)
+ var pathPrefix string
+ if ok := clientOpts.ReadOpt("pathPrefix", &pathPrefix); !ok {
+ pathPrefix = "/twirp" // default prefix
+ }
+
+ // Build method URLs: <baseURL>[<prefix>]/<package>.<Service>/<Method>
+ serviceURL := sanitizeBaseURL(baseURL)
+ serviceURL += baseServicePath(pathPrefix, "xeiaso.net.internal", "Admin")
+ urls := [1]string{
+ serviceURL + "Rebuild",
+ }
+
+ return &adminProtobufClient{
+ client: client,
+ urls: urls,
+ interceptor: twirp.ChainInterceptors(clientOpts.Interceptors...),
+ opts: clientOpts,
+ }
+}
+
+func (c *adminProtobufClient) Rebuild(ctx context.Context, in *google_protobuf.Empty) (*xeiaso_net.BuildInfo, error) {
+ ctx = ctxsetters.WithPackageName(ctx, "xeiaso.net.internal")
+ ctx = ctxsetters.WithServiceName(ctx, "Admin")
+ ctx = ctxsetters.WithMethodName(ctx, "Rebuild")
+ caller := c.callRebuild
+ if c.interceptor != nil {
+ caller = func(ctx context.Context, req *google_protobuf.Empty) (*xeiaso_net.BuildInfo, error) {
+ resp, err := c.interceptor(
+ func(ctx context.Context, req interface{}) (interface{}, error) {
+ typedReq, ok := req.(*google_protobuf.Empty)
+ if !ok {
+ return nil, twirp.InternalError("failed type assertion req.(*google_protobuf.Empty) when calling interceptor")
+ }
+ return c.callRebuild(ctx, typedReq)
+ },
+ )(ctx, req)
+ if resp != nil {
+ typedResp, ok := resp.(*xeiaso_net.BuildInfo)
+ if !ok {
+ return nil, twirp.InternalError("failed type assertion resp.(*xeiaso_net.BuildInfo) when calling interceptor")
+ }
+ return typedResp, err
+ }
+ return nil, err
+ }
+ }
+ return caller(ctx, in)
+}
+
+func (c *adminProtobufClient) callRebuild(ctx context.Context, in *google_protobuf.Empty) (*xeiaso_net.BuildInfo, error) {
+ out := new(xeiaso_net.BuildInfo)
+ ctx, err := doProtobufRequest(ctx, c.client, c.opts.Hooks, c.urls[0], in, out)
+ if err != nil {
+ twerr, ok := err.(twirp.Error)
+ if !ok {
+ twerr = twirp.InternalErrorWith(err)
+ }
+ callClientError(ctx, c.opts.Hooks, twerr)
+ return nil, err
+ }
+
+ callClientResponseReceived(ctx, c.opts.Hooks)
+
+ return out, nil
+}
+
+// =================
+// Admin JSON Client
+// =================
+
+type adminJSONClient struct {
+ client HTTPClient
+ urls [1]string
+ interceptor twirp.Interceptor
+ opts twirp.ClientOptions
+}
+
+// NewAdminJSONClient creates a JSON client that implements the Admin interface.
+// It communicates using JSON and can be configured with a custom HTTPClient.
+func NewAdminJSONClient(baseURL string, client HTTPClient, opts ...twirp.ClientOption) Admin {
+ if c, ok := client.(*http.Client); ok {
+ client = withoutRedirects(c)
+ }
+
+ clientOpts := twirp.ClientOptions{}
+ for _, o := range opts {
+ o(&clientOpts)
+ }
+
+ // Using ReadOpt allows backwards and forwards compatibility with new options in the future
+ literalURLs := false
+ _ = clientOpts.ReadOpt("literalURLs", &literalURLs)
+ var pathPrefix string
+ if ok := clientOpts.ReadOpt("pathPrefix", &pathPrefix); !ok {
+ pathPrefix = "/twirp" // default prefix
+ }
+
+ // Build method URLs: <baseURL>[<prefix>]/<package>.<Service>/<Method>
+ serviceURL := sanitizeBaseURL(baseURL)
+ serviceURL += baseServicePath(pathPrefix, "xeiaso.net.internal", "Admin")
+ urls := [1]string{
+ serviceURL + "Rebuild",
+ }
+
+ return &adminJSONClient{
+ client: client,
+ urls: urls,
+ interceptor: twirp.ChainInterceptors(clientOpts.Interceptors...),
+ opts: clientOpts,
+ }
+}
+
+func (c *adminJSONClient) Rebuild(ctx context.Context, in *google_protobuf.Empty) (*xeiaso_net.BuildInfo, error) {
+ ctx = ctxsetters.WithPackageName(ctx, "xeiaso.net.internal")
+ ctx = ctxsetters.WithServiceName(ctx, "Admin")
+ ctx = ctxsetters.WithMethodName(ctx, "Rebuild")
+ caller := c.callRebuild
+ if c.interceptor != nil {
+ caller = func(ctx context.Context, req *google_protobuf.Empty) (*xeiaso_net.BuildInfo, error) {
+ resp, err := c.interceptor(
+ func(ctx context.Context, req interface{}) (interface{}, error) {
+ typedReq, ok := req.(*google_protobuf.Empty)
+ if !ok {
+ return nil, twirp.InternalError("failed type assertion req.(*google_protobuf.Empty) when calling interceptor")
+ }
+ return c.callRebuild(ctx, typedReq)
+ },
+ )(ctx, req)
+ if resp != nil {
+ typedResp, ok := resp.(*xeiaso_net.BuildInfo)
+ if !ok {
+ return nil, twirp.InternalError("failed type assertion resp.(*xeiaso_net.BuildInfo) when calling interceptor")
+ }
+ return typedResp, err
+ }
+ return nil, err
+ }
+ }
+ return caller(ctx, in)
+}
+
+func (c *adminJSONClient) callRebuild(ctx context.Context, in *google_protobuf.Empty) (*xeiaso_net.BuildInfo, error) {
+ out := new(xeiaso_net.BuildInfo)
+ ctx, err := doJSONRequest(ctx, c.client, c.opts.Hooks, c.urls[0], in, out)
+ if err != nil {
+ twerr, ok := err.(twirp.Error)
+ if !ok {
+ twerr = twirp.InternalErrorWith(err)
+ }
+ callClientError(ctx, c.opts.Hooks, twerr)
+ return nil, err
+ }
+
+ callClientResponseReceived(ctx, c.opts.Hooks)
+
+ return out, nil
+}
+
+// ====================
+// Admin Server Handler
+// ====================
+
+type adminServer struct {