Add GetBuildScript API endpoint
ci/woodpecker/push/woodpecker Pipeline was successful Details

This commit is contained in:
Elara 2022-12-18 13:52:57 -08:00
parent 9c0d9d0a34
commit 964c45ffc4
4 changed files with 553 additions and 90 deletions

View File

@ -3,12 +3,17 @@ package main
import (
"context"
"fmt"
"os"
"path/filepath"
"strconv"
"strings"
"github.com/genjidb/genji"
"github.com/genjidb/genji/document"
"github.com/genjidb/genji/types"
"github.com/twitchtv/twirp"
"go.arsenm.dev/lure/internal/api"
"go.arsenm.dev/lure/internal/config"
"go.arsenm.dev/lure/internal/db"
)
@ -72,6 +77,27 @@ func (l lureWebAPI) GetPkg(ctx context.Context, req *api.GetPackageRequest) (*ap
return dbPkgToAPI(pkg), nil
}
func (l lureWebAPI) GetBuildScript(ctx context.Context, req *api.GetBuildScriptRequest) (*api.GetBuildScriptResponse, error) {
if strings.ContainsAny(req.Name, "./") || strings.ContainsAny(req.Repository, "./") {
return nil, twirp.NewError(twirp.InvalidArgument, "name and repository must not contain . or /")
}
scriptPath := filepath.Join(config.RepoDir, req.Repository, req.Name, "lure.sh")
_, err := os.Stat(scriptPath)
if os.IsNotExist(err) {
return nil, twirp.NewError(twirp.NotFound, "requested package not found")
} else if err != nil {
return nil, err
}
data, err := os.ReadFile(scriptPath)
if err != nil {
return nil, err
}
return &api.GetBuildScriptResponse{Script: string(data)}, nil
}
func dbPkgToAPI(pkg *db.Package) *api.Package {
return &api.Package{
Name: pkg.Name,

View File

@ -514,6 +514,108 @@ func (x *SearchResponse) GetPackages() []*Package {
return nil
}
type GetBuildScriptRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
Repository string `protobuf:"bytes,2,opt,name=repository,proto3" json:"repository,omitempty"`
}
func (x *GetBuildScriptRequest) Reset() {
*x = GetBuildScriptRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_lure_proto_msgTypes[5]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *GetBuildScriptRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*GetBuildScriptRequest) ProtoMessage() {}
func (x *GetBuildScriptRequest) ProtoReflect() protoreflect.Message {
mi := &file_lure_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 GetBuildScriptRequest.ProtoReflect.Descriptor instead.
func (*GetBuildScriptRequest) Descriptor() ([]byte, []int) {
return file_lure_proto_rawDescGZIP(), []int{5}
}
func (x *GetBuildScriptRequest) GetName() string {
if x != nil {
return x.Name
}
return ""
}
func (x *GetBuildScriptRequest) GetRepository() string {
if x != nil {
return x.Repository
}
return ""
}
type GetBuildScriptResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Script string `protobuf:"bytes,1,opt,name=script,proto3" json:"script,omitempty"`
}
func (x *GetBuildScriptResponse) Reset() {
*x = GetBuildScriptResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_lure_proto_msgTypes[6]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *GetBuildScriptResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*GetBuildScriptResponse) ProtoMessage() {}
func (x *GetBuildScriptResponse) ProtoReflect() protoreflect.Message {
mi := &file_lure_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 GetBuildScriptResponse.ProtoReflect.Descriptor instead.
func (*GetBuildScriptResponse) Descriptor() ([]byte, []int) {
return file_lure_proto_rawDescGZIP(), []int{6}
}
func (x *GetBuildScriptResponse) GetScript() string {
if x != nil {
return x.Script
}
return ""
}
var File_lure_proto protoreflect.FileDescriptor
var file_lure_proto_rawDesc = []byte{
@ -588,23 +690,36 @@ var file_lure_proto_rawDesc = []byte{
0x0e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
0x29, 0x0a, 0x08, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28,
0x0b, 0x32, 0x0d, 0x2e, 0x6c, 0x75, 0x72, 0x65, 0x2e, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65,
0x52, 0x08, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x73, 0x2a, 0x3e, 0x0a, 0x07, 0x53, 0x4f,
0x52, 0x54, 0x5f, 0x42, 0x59, 0x12, 0x0c, 0x0a, 0x08, 0x55, 0x4e, 0x53, 0x4f, 0x52, 0x54, 0x45,
0x44, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x41, 0x4d, 0x45, 0x10, 0x01, 0x12, 0x0e, 0x0a,
0x0a, 0x52, 0x45, 0x50, 0x4f, 0x53, 0x49, 0x54, 0x4f, 0x52, 0x59, 0x10, 0x02, 0x12, 0x0b, 0x0a,
0x07, 0x56, 0x45, 0x52, 0x53, 0x49, 0x4f, 0x4e, 0x10, 0x03, 0x2a, 0x42, 0x0a, 0x0b, 0x46, 0x49,
0x4c, 0x54, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x12, 0x0d, 0x0a, 0x09, 0x4e, 0x4f, 0x5f,
0x46, 0x49, 0x4c, 0x54, 0x45, 0x52, 0x10, 0x00, 0x12, 0x11, 0x0a, 0x0d, 0x49, 0x4e, 0x5f, 0x52,
0x45, 0x50, 0x4f, 0x53, 0x49, 0x54, 0x4f, 0x52, 0x59, 0x10, 0x01, 0x12, 0x11, 0x0a, 0x0d, 0x53,
0x55, 0x50, 0x50, 0x4f, 0x52, 0x54, 0x53, 0x5f, 0x41, 0x52, 0x43, 0x48, 0x10, 0x02, 0x32, 0x6c,
0x52, 0x08, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x73, 0x22, 0x4b, 0x0a, 0x15, 0x47, 0x65,
0x74, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x52, 0x65, 0x71, 0x75,
0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28,
0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73,
0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72, 0x65, 0x70,
0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x22, 0x30, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x42, 0x75,
0x69, 0x6c, 0x64, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28,
0x09, 0x52, 0x06, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x2a, 0x3e, 0x0a, 0x07, 0x53, 0x4f, 0x52,
0x54, 0x5f, 0x42, 0x59, 0x12, 0x0c, 0x0a, 0x08, 0x55, 0x4e, 0x53, 0x4f, 0x52, 0x54, 0x45, 0x44,
0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x41, 0x4d, 0x45, 0x10, 0x01, 0x12, 0x0e, 0x0a, 0x0a,
0x52, 0x45, 0x50, 0x4f, 0x53, 0x49, 0x54, 0x4f, 0x52, 0x59, 0x10, 0x02, 0x12, 0x0b, 0x0a, 0x07,
0x56, 0x45, 0x52, 0x53, 0x49, 0x4f, 0x4e, 0x10, 0x03, 0x2a, 0x42, 0x0a, 0x0b, 0x46, 0x49, 0x4c,
0x54, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x12, 0x0d, 0x0a, 0x09, 0x4e, 0x4f, 0x5f, 0x46,
0x49, 0x4c, 0x54, 0x45, 0x52, 0x10, 0x00, 0x12, 0x11, 0x0a, 0x0d, 0x49, 0x4e, 0x5f, 0x52, 0x45,
0x50, 0x4f, 0x53, 0x49, 0x54, 0x4f, 0x52, 0x59, 0x10, 0x01, 0x12, 0x11, 0x0a, 0x0d, 0x53, 0x55,
0x50, 0x50, 0x4f, 0x52, 0x54, 0x53, 0x5f, 0x41, 0x52, 0x43, 0x48, 0x10, 0x02, 0x32, 0xb9, 0x01,
0x0a, 0x03, 0x41, 0x50, 0x49, 0x12, 0x33, 0x0a, 0x06, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x12,
0x13, 0x2e, 0x6c, 0x75, 0x72, 0x65, 0x2e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x71,
0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x6c, 0x75, 0x72, 0x65, 0x2e, 0x53, 0x65, 0x61, 0x72,
0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x30, 0x0a, 0x06, 0x47, 0x65,
0x74, 0x50, 0x6b, 0x67, 0x12, 0x17, 0x2e, 0x6c, 0x75, 0x72, 0x65, 0x2e, 0x47, 0x65, 0x74, 0x50,
0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0d, 0x2e,
0x6c, 0x75, 0x72, 0x65, 0x2e, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x42, 0x08, 0x5a, 0x06,
0x2e, 0x2e, 0x2f, 0x61, 0x70, 0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x6c, 0x75, 0x72, 0x65, 0x2e, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x12, 0x4b, 0x0a, 0x0e,
0x47, 0x65, 0x74, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x12, 0x1b,
0x2e, 0x6c, 0x75, 0x72, 0x65, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x53, 0x63,
0x72, 0x69, 0x70, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x6c, 0x75,
0x72, 0x65, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x53, 0x63, 0x72, 0x69, 0x70,
0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x08, 0x5a, 0x06, 0x2e, 0x2e, 0x2f,
0x61, 0x70, 0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
@ -620,7 +735,7 @@ func file_lure_proto_rawDescGZIP() []byte {
}
var file_lure_proto_enumTypes = make([]protoimpl.EnumInfo, 2)
var file_lure_proto_msgTypes = make([]protoimpl.MessageInfo, 7)
var file_lure_proto_msgTypes = make([]protoimpl.MessageInfo, 9)
var file_lure_proto_goTypes = []interface{}{
(SORT_BY)(0), // 0: lure.SORT_BY
(FILTER_TYPE)(0), // 1: lure.FILTER_TYPE
@ -629,23 +744,27 @@ var file_lure_proto_goTypes = []interface{}{
(*Package)(nil), // 4: lure.Package
(*GetPackageRequest)(nil), // 5: lure.GetPackageRequest
(*SearchResponse)(nil), // 6: lure.SearchResponse
nil, // 7: lure.Package.DependsEntry
nil, // 8: lure.Package.BuildDependsEntry
(*GetBuildScriptRequest)(nil), // 7: lure.GetBuildScriptRequest
(*GetBuildScriptResponse)(nil), // 8: lure.GetBuildScriptResponse
nil, // 9: lure.Package.DependsEntry
nil, // 10: lure.Package.BuildDependsEntry
}
var file_lure_proto_depIdxs = []int32{
0, // 0: lure.SearchRequest.sort_by:type_name -> lure.SORT_BY
1, // 1: lure.SearchRequest.filter_type:type_name -> lure.FILTER_TYPE
7, // 2: lure.Package.depends:type_name -> lure.Package.DependsEntry
8, // 3: lure.Package.build_depends:type_name -> lure.Package.BuildDependsEntry
9, // 2: lure.Package.depends:type_name -> lure.Package.DependsEntry
10, // 3: lure.Package.build_depends:type_name -> lure.Package.BuildDependsEntry
4, // 4: lure.SearchResponse.packages:type_name -> lure.Package
3, // 5: lure.Package.DependsEntry.value:type_name -> lure.StringList
3, // 6: lure.Package.BuildDependsEntry.value:type_name -> lure.StringList
2, // 7: lure.API.Search:input_type -> lure.SearchRequest
5, // 8: lure.API.GetPkg:input_type -> lure.GetPackageRequest
6, // 9: lure.API.Search:output_type -> lure.SearchResponse
4, // 10: lure.API.GetPkg:output_type -> lure.Package
9, // [9:11] is the sub-list for method output_type
7, // [7:9] is the sub-list for method input_type
7, // 9: lure.API.GetBuildScript:input_type -> lure.GetBuildScriptRequest
6, // 10: lure.API.Search:output_type -> lure.SearchResponse
4, // 11: lure.API.GetPkg:output_type -> lure.Package
8, // 12: lure.API.GetBuildScript:output_type -> lure.GetBuildScriptResponse
10, // [10:13] is the sub-list for method output_type
7, // [7:10] is the sub-list for method input_type
7, // [7:7] is the sub-list for extension type_name
7, // [7:7] is the sub-list for extension extendee
0, // [0:7] is the sub-list for field type_name
@ -717,6 +836,30 @@ func file_lure_proto_init() {
return nil
}
}
file_lure_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*GetBuildScriptRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_lure_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*GetBuildScriptResponse); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
file_lure_proto_msgTypes[0].OneofWrappers = []interface{}{}
file_lure_proto_msgTypes[2].OneofWrappers = []interface{}{}
@ -726,7 +869,7 @@ func file_lure_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_lure_proto_rawDesc,
NumEnums: 2,
NumMessages: 7,
NumMessages: 9,
NumExtensions: 0,
NumServices: 1,
},

View File

@ -62,10 +62,21 @@ message SearchResponse {
repeated Package packages = 1;
}
message GetBuildScriptRequest {
string name = 1;
string repository = 2;
}
message GetBuildScriptResponse {
string script = 1;
}
// Web is the LURE Web service
service API {
// Search searches through LURE packages in the database
rpc Search(SearchRequest) returns (SearchResponse);
// GetPkg gets a single LURE package from the database
rpc GetPkg(GetPackageRequest) returns (Package);
// GetBuildScript returns the build script for the given package
rpc GetBuildScript(GetBuildScriptRequest) returns (GetBuildScriptResponse);
}

View File

@ -38,6 +38,9 @@ type API interface {
// GetPkg gets a single LURE package from the database
GetPkg(context.Context, *GetPackageRequest) (*Package, error)
// GetBuildScript returns the build script for the given package
GetBuildScript(context.Context, *GetBuildScriptRequest) (*GetBuildScriptResponse, error)
}
// ===================
@ -46,7 +49,7 @@ type API interface {
type aPIProtobufClient struct {
client HTTPClient
urls [2]string
urls [3]string
interceptor twirp.Interceptor
opts twirp.ClientOptions
}
@ -74,9 +77,10 @@ func NewAPIProtobufClient(baseURL string, client HTTPClient, opts ...twirp.Clien
// Build method URLs: <baseURL>[<prefix>]/<package>.<Service>/<Method>
serviceURL := sanitizeBaseURL(baseURL)
serviceURL += baseServicePath(pathPrefix, "lure", "API")
urls := [2]string{
urls := [3]string{
serviceURL + "Search",
serviceURL + "GetPkg",
serviceURL + "GetBuildScript",
}
return &aPIProtobufClient{
@ -179,13 +183,59 @@ func (c *aPIProtobufClient) callGetPkg(ctx context.Context, in *GetPackageReques
return out, nil
}
func (c *aPIProtobufClient) GetBuildScript(ctx context.Context, in *GetBuildScriptRequest) (*GetBuildScriptResponse, error) {
ctx = ctxsetters.WithPackageName(ctx, "lure")
ctx = ctxsetters.WithServiceName(ctx, "API")
ctx = ctxsetters.WithMethodName(ctx, "GetBuildScript")
caller := c.callGetBuildScript
if c.interceptor != nil {
caller = func(ctx context.Context, req *GetBuildScriptRequest) (*GetBuildScriptResponse, error) {
resp, err := c.interceptor(
func(ctx context.Context, req interface{}) (interface{}, error) {
typedReq, ok := req.(*GetBuildScriptRequest)
if !ok {
return nil, twirp.InternalError("failed type assertion req.(*GetBuildScriptRequest) when calling interceptor")
}
return c.callGetBuildScript(ctx, typedReq)
},
)(ctx, req)
if resp != nil {
typedResp, ok := resp.(*GetBuildScriptResponse)
if !ok {
return nil, twirp.InternalError("failed type assertion resp.(*GetBuildScriptResponse) when calling interceptor")
}
return typedResp, err
}
return nil, err
}
}
return caller(ctx, in)
}
func (c *aPIProtobufClient) callGetBuildScript(ctx context.Context, in *GetBuildScriptRequest) (*GetBuildScriptResponse, error) {
out := new(GetBuildScriptResponse)
ctx, err := doProtobufRequest(ctx, c.client, c.opts.Hooks, c.urls[2], 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
}
// ===============
// API JSON Client
// ===============
type aPIJSONClient struct {
client HTTPClient
urls [2]string
urls [3]string
interceptor twirp.Interceptor
opts twirp.ClientOptions
}
@ -213,9 +263,10 @@ func NewAPIJSONClient(baseURL string, client HTTPClient, opts ...twirp.ClientOpt
// Build method URLs: <baseURL>[<prefix>]/<package>.<Service>/<Method>
serviceURL := sanitizeBaseURL(baseURL)
serviceURL += baseServicePath(pathPrefix, "lure", "API")
urls := [2]string{
urls := [3]string{
serviceURL + "Search",
serviceURL + "GetPkg",
serviceURL + "GetBuildScript",
}
return &aPIJSONClient{
@ -318,6 +369,52 @@ func (c *aPIJSONClient) callGetPkg(ctx context.Context, in *GetPackageRequest) (
return out, nil
}
func (c *aPIJSONClient) GetBuildScript(ctx context.Context, in *GetBuildScriptRequest) (*GetBuildScriptResponse, error) {
ctx = ctxsetters.WithPackageName(ctx, "lure")
ctx = ctxsetters.WithServiceName(ctx, "API")
ctx = ctxsetters.WithMethodName(ctx, "GetBuildScript")
caller := c.callGetBuildScript
if c.interceptor != nil {
caller = func(ctx context.Context, req *GetBuildScriptRequest) (*GetBuildScriptResponse, error) {
resp, err := c.interceptor(
func(ctx context.Context, req interface{}) (interface{}, error) {
typedReq, ok := req.(*GetBuildScriptRequest)
if !ok {
return nil, twirp.InternalError("failed type assertion req.(*GetBuildScriptRequest) when calling interceptor")
}
return c.callGetBuildScript(ctx, typedReq)
},
)(ctx, req)
if resp != nil {
typedResp, ok := resp.(*GetBuildScriptResponse)
if !ok {
return nil, twirp.InternalError("failed type assertion resp.(*GetBuildScriptResponse) when calling interceptor")
}
return typedResp, err
}
return nil, err
}
}
return caller(ctx, in)
}
func (c *aPIJSONClient) callGetBuildScript(ctx context.Context, in *GetBuildScriptRequest) (*GetBuildScriptResponse, error) {
out := new(GetBuildScriptResponse)
ctx, err := doJSONRequest(ctx, c.client, c.opts.Hooks, c.urls[2], 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
}
// ==================
// API Server Handler
// ==================
@ -421,6 +518,9 @@ func (s *aPIServer) ServeHTTP(resp http.ResponseWriter, req *http.Request) {
case "GetPkg":
s.serveGetPkg(ctx, resp, req)
return
case "GetBuildScript":
s.serveGetBuildScript(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))
@ -788,6 +888,186 @@ func (s *aPIServer) serveGetPkgProtobuf(ctx context.Context, resp http.ResponseW
callResponseSent(ctx, s.hooks)
}
func (s *aPIServer) serveGetBuildScript(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.serveGetBuildScriptJSON(ctx, resp, req)
case "application/protobuf":
s.serveGetBuildScriptProtobuf(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 *aPIServer) serveGetBuildScriptJSON(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
var err error
ctx = ctxsetters.WithMethodName(ctx, "GetBuildScript")
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(GetBuildScriptRequest)
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.API.GetBuildScript
if s.interceptor != nil {
handler = func(ctx context.Context, req *GetBuildScriptRequest) (*GetBuildScriptResponse, error) {
resp, err := s.interceptor(
func(ctx context.Context, req interface{}) (interface{}, error) {
typedReq, ok := req.(*GetBuildScriptRequest)
if !ok {
return nil, twirp.InternalError("failed type assertion req.(*GetBuildScriptRequest) when calling interceptor")
}
return s.API.GetBuildScript(ctx, typedReq)
},
)(ctx, req)
if resp != nil {
typedResp, ok := resp.(*GetBuildScriptResponse)
if !ok {
return nil, twirp.InternalError("failed type assertion resp.(*GetBuildScriptResponse) when calling interceptor")
}
return typedResp, err
}
return nil, err
}
}
// Call service method
var respContent *GetBuildScriptResponse
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 *GetBuildScriptResponse and nil error while calling GetBuildScript. 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 *aPIServer) serveGetBuildScriptProtobuf(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
var err error
ctx = ctxsetters.WithMethodName(ctx, "GetBuildScript")
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(GetBuildScriptRequest)
if err = proto.Unmarshal(buf, reqContent); err != nil {
s.writeError(ctx, resp, malformedRequestError("the protobuf request could not be decoded"))
return
}
handler := s.API.GetBuildScript
if s.interceptor != nil {
handler = func(ctx context.Context, req *GetBuildScriptRequest) (*GetBuildScriptResponse, error) {
resp, err := s.interceptor(
func(ctx context.Context, req interface{}) (interface{}, error) {
typedReq, ok := req.(*GetBuildScriptRequest)
if !ok {
return nil, twirp.InternalError("failed type assertion req.(*GetBuildScriptRequest) when calling interceptor")
}
return s.API.GetBuildScript(ctx, typedReq)
},
)(ctx, req)
if resp != nil {
typedResp, ok := resp.(*GetBuildScriptResponse)
if !ok {
return nil, twirp.InternalError("failed type assertion resp.(*GetBuildScriptResponse) when calling interceptor")
}
return typedResp, err
}
return nil, err
}
}
// Call service method
var respContent *GetBuildScriptResponse
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 *GetBuildScriptResponse and nil error while calling GetBuildScript. 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 *aPIServer) ServiceDescriptor() ([]byte, int) {
return twirpFileDescriptor0, 0
}
@ -1369,52 +1649,55 @@ func callClientError(ctx context.Context, h *twirp.ClientHooks, err twirp.Error)
}
var twirpFileDescriptor0 = []byte{
// 738 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x54, 0x5f, 0x8f, 0xda, 0x46,
0x10, 0x3f, 0xe3, 0x03, 0xec, 0x31, 0x26, 0xbe, 0x6d, 0xa4, 0xba, 0xa8, 0x6a, 0x10, 0x6d, 0x11,
0xcd, 0x03, 0xad, 0x48, 0x1f, 0xaa, 0x56, 0xaa, 0x74, 0xee, 0xd1, 0x1c, 0xd2, 0x15, 0xe8, 0x42,
0x22, 0x5d, 0x5f, 0x2c, 0x63, 0x26, 0xdc, 0xea, 0x8c, 0xed, 0xec, 0x2e, 0x27, 0xf1, 0x0d, 0xf2,
0xf1, 0xfa, 0x21, 0xfa, 0x41, 0xaa, 0xf5, 0xda, 0xc4, 0x28, 0x6f, 0xed, 0x9b, 0x7f, 0x7f, 0x66,
0xd6, 0x33, 0x3b, 0x3b, 0x00, 0xc9, 0x81, 0xe3, 0x38, 0xe7, 0x99, 0xcc, 0xc8, 0xa5, 0xfa, 0x1e,
0xfc, 0x6d, 0x80, 0xbb, 0xc2, 0x88, 0xc7, 0x0f, 0x14, 0xdf, 0x1f, 0x50, 0x48, 0xf2, 0x1c, 0x9a,
0xef, 0x0f, 0xc8, 0x8f, 0xbe, 0xd1, 0x37, 0x46, 0x36, 0xd5, 0x40, 0xb1, 0x09, 0xdb, 0x33, 0xe9,
0x37, 0xfa, 0xc6, 0xc8, 0xa4, 0x1a, 0x90, 0x21, 0xb4, 0x45, 0xc6, 0x65, 0xb8, 0x39, 0xfa, 0x66,
0xdf, 0x18, 0x75, 0x27, 0xee, 0xb8, 0x38, 0x61, 0xb5, 0xa0, 0xeb, 0x30, 0xb8, 0xa7, 0x2d, 0xa5,
0x06, 0x47, 0x32, 0x01, 0xe7, 0x1d, 0x4b, 0x24, 0xf2, 0x50, 0x1e, 0x73, 0xf4, 0x2f, 0x0b, 0xef,
0x95, 0xf6, 0xfe, 0x3e, 0xbb, 0x5b, 0x4f, 0x69, 0xb8, 0xbe, 0x5f, 0x4e, 0x29, 0x68, 0xd7, 0xfa,
0x98, 0x23, 0x19, 0x42, 0xa7, 0x8c, 0x79, 0x8a, 0x92, 0x03, 0xfa, 0x4d, 0xf5, 0x3b, 0xb7, 0x17,
0xb4, 0xcc, 0xf4, 0x56, 0x91, 0x1f, 0x0c, 0x23, 0x78, 0x06, 0x6e, 0x58, 0x37, 0x0e, 0x86, 0x00,
0x2b, 0xc9, 0x59, 0xba, 0xbb, 0x63, 0x42, 0x12, 0x1f, 0xda, 0x98, 0x4a, 0xce, 0x50, 0xf8, 0x46,
0xdf, 0x1c, 0xd9, 0xb4, 0x82, 0x83, 0x7f, 0x9a, 0xd0, 0x5e, 0x46, 0xf1, 0x63, 0xb4, 0x43, 0x42,
0xe0, 0x32, 0x8d, 0xf6, 0x58, 0xd6, 0x5c, 0x7c, 0x93, 0xaf, 0x00, 0x38, 0xe6, 0x99, 0x60, 0x32,
0xe3, 0xc7, 0xa2, 0x6e, 0x9b, 0xd6, 0x18, 0x95, 0xf9, 0x09, 0xb9, 0x60, 0x59, 0x5a, 0x14, 0x6f,
0xd3, 0x0a, 0x2a, 0x85, 0x63, 0x82, 0x91, 0xd0, 0xa5, 0x9a, 0xb4, 0x82, 0xe4, 0x0b, 0x68, 0x62,
0x9e, 0xc5, 0x0f, 0x45, 0x35, 0xe6, 0xed, 0x05, 0xd5, 0xf0, 0x83, 0x61, 0x90, 0x6f, 0xc1, 0xd9,
0xa2, 0x88, 0x39, 0xcb, 0xa5, 0x4a, 0xd9, 0x2a, 0xca, 0x35, 0x68, 0x9d, 0x54, 0xb6, 0x17, 0x60,
0x3d, 0x64, 0x7b, 0xcc, 0xa3, 0x1d, 0xfa, 0xed, 0xc2, 0xd3, 0xa0, 0x27, 0x46, 0x19, 0xbe, 0x06,
0xd8, 0x47, 0x2c, 0x95, 0x11, 0x4b, 0x91, 0xfb, 0x56, 0x61, 0x31, 0x69, 0x8d, 0x53, 0xa6, 0x6f,
0xc0, 0x55, 0x77, 0xce, 0x24, 0xc6, 0xf2, 0xc0, 0x51, 0xf8, 0x76, 0xd1, 0x9b, 0x73, 0x92, 0xf4,
0xc0, 0x4a, 0x58, 0x8c, 0xa9, 0x40, 0xe1, 0x43, 0x61, 0x38, 0x61, 0xa5, 0xe5, 0x3c, 0x7b, 0x62,
0x5b, 0x14, 0xbe, 0xa3, 0xb5, 0x0a, 0x93, 0x2f, 0xc1, 0x8e, 0xb3, 0xf4, 0x5d, 0xc2, 0x62, 0x29,
0xfc, 0x4e, 0x21, 0x7e, 0x24, 0x54, 0x24, 0xc7, 0x3c, 0x89, 0x62, 0x14, 0xbe, 0xab, 0x23, 0x2b,
0x4c, 0x7e, 0x84, 0xf6, 0x16, 0x73, 0x4c, 0xb7, 0xc2, 0xef, 0xf6, 0xcd, 0x91, 0x33, 0xe9, 0xe9,
0x21, 0x29, 0xef, 0x69, 0x7c, 0xa3, 0xc5, 0x69, 0x2a, 0xf9, 0x91, 0x56, 0x56, 0x72, 0x03, 0xee,
0xe6, 0xc0, 0x92, 0x6d, 0x58, 0xc5, 0x3e, 0x2b, 0x62, 0x5f, 0x9c, 0xc7, 0x06, 0xca, 0x72, 0x96,
0xa0, 0xb3, 0xa9, 0x51, 0xbd, 0x3b, 0xe8, 0xd4, 0x55, 0xe2, 0x81, 0xf9, 0x88, 0xd5, 0x33, 0x50,
0x9f, 0x64, 0x08, 0x4d, 0x3d, 0x8b, 0x6a, 0x18, 0x9c, 0x89, 0x57, 0x0e, 0xfb, 0x69, 0xd8, 0xa8,
0x96, 0x7f, 0x6e, 0xfc, 0x64, 0xf4, 0xfe, 0x84, 0xab, 0x4f, 0x0e, 0xfc, 0x7f, 0x29, 0x03, 0x0b,
0x5a, 0x61, 0x31, 0x2e, 0x41, 0x17, 0x3a, 0x61, 0x6d, 0x2e, 0x02, 0x07, 0xec, 0xb0, 0x9a, 0x81,
0xc0, 0x05, 0x27, 0xfc, 0x78, 0xdb, 0x83, 0xd7, 0x70, 0xf5, 0x1a, 0x65, 0xd9, 0x84, 0xea, 0x91,
0xff, 0x87, 0x79, 0x1f, 0xfc, 0x02, 0xdd, 0x6a, 0x53, 0x88, 0x3c, 0x4b, 0x05, 0x92, 0xef, 0xc0,
0xca, 0x75, 0x5e, 0xfd, 0xb8, 0x9c, 0xea, 0xfd, 0x57, 0xa7, 0x9d, 0xe4, 0x97, 0xbf, 0x42, 0xbb,
0x5c, 0x0a, 0xa4, 0x03, 0xd6, 0x9b, 0xb9, 0x02, 0xd3, 0x1b, 0xef, 0x82, 0x58, 0x70, 0x39, 0xbf,
0xfe, 0x63, 0xea, 0x19, 0xa4, 0x0b, 0x40, 0xa7, 0xcb, 0xc5, 0x6a, 0xb6, 0x5e, 0xd0, 0x7b, 0xaf,
0x41, 0x1c, 0x68, 0xbf, 0x9d, 0xd2, 0xd5, 0x6c, 0x31, 0xf7, 0xcc, 0x97, 0x01, 0x38, 0xb5, 0x45,
0x41, 0x5c, 0xb0, 0xe7, 0x8b, 0x50, 0x33, 0xde, 0x05, 0xb9, 0x02, 0x77, 0x36, 0x0f, 0x6b, 0xd1,
0x86, 0xa2, 0x56, 0x6f, 0x96, 0xcb, 0x05, 0x5d, 0xaf, 0xc2, 0x6b, 0xfa, 0xdb, 0xad, 0xd7, 0x98,
0x24, 0x60, 0x5e, 0x2f, 0x67, 0xe4, 0x15, 0xb4, 0x74, 0x1d, 0xe4, 0xb3, 0xb2, 0xdb, 0xf5, 0xfd,
0xd7, 0x7b, 0x7e, 0x4e, 0x96, 0xa5, 0xfe, 0x00, 0x2d, 0xd5, 0xc5, 0xc7, 0x1d, 0xf9, 0x5c, 0xeb,
0x9f, 0xf4, 0xb4, 0x77, 0x5e, 0x7b, 0x60, 0xfd, 0xd5, 0x1a, 0x8f, 0xbf, 0x8f, 0x72, 0xb6, 0x69,
0x15, 0x0b, 0xf7, 0xd5, 0xbf, 0x01, 0x00, 0x00, 0xff, 0xff, 0x2b, 0xd4, 0x7c, 0x4f, 0x7e, 0x05,
0x00, 0x00,
// 791 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x55, 0xdd, 0x6e, 0xdb, 0x36,
0x14, 0x8e, 0xac, 0xf8, 0xef, 0xc8, 0x72, 0x1d, 0xae, 0xeb, 0x34, 0xaf, 0x58, 0x0d, 0x6f, 0x0b,
0xbc, 0x5e, 0x78, 0x85, 0xbb, 0x8b, 0x61, 0x03, 0x06, 0x44, 0x8b, 0x97, 0x18, 0xcd, 0x6c, 0x8f,
0x72, 0x0b, 0x64, 0x37, 0x82, 0x22, 0x9f, 0x26, 0x44, 0x14, 0x49, 0x25, 0xe9, 0x00, 0x7e, 0x83,
0xbe, 0xd2, 0xde, 0x62, 0x0f, 0xb1, 0x07, 0x19, 0x48, 0x4a, 0xae, 0xbc, 0xec, 0x6a, 0xbd, 0xd3,
0xf7, 0x73, 0x0e, 0xc9, 0x73, 0x0e, 0x29, 0x80, 0x64, 0xc3, 0x71, 0x9c, 0xf3, 0x4c, 0x66, 0xe4,
0x50, 0x7d, 0x0f, 0xff, 0xb2, 0xc0, 0x0d, 0x30, 0xe2, 0xf1, 0x0d, 0xc5, 0x77, 0x1b, 0x14, 0x92,
0x3c, 0x86, 0xfa, 0xbb, 0x0d, 0xf2, 0xad, 0x67, 0x0d, 0xac, 0x51, 0x9b, 0x1a, 0xa0, 0xd8, 0x84,
0xdd, 0x31, 0xe9, 0xd5, 0x06, 0xd6, 0xc8, 0xa6, 0x06, 0x90, 0x63, 0x68, 0x8a, 0x8c, 0xcb, 0xf0,
0x6a, 0xeb, 0xd9, 0x03, 0x6b, 0xd4, 0x9d, 0xb8, 0x63, 0xbd, 0x42, 0xb0, 0xa0, 0xab, 0xd0, 0xbf,
0xa4, 0x0d, 0xa5, 0xfa, 0x5b, 0x32, 0x01, 0xe7, 0x2d, 0x4b, 0x24, 0xf2, 0x50, 0x6e, 0x73, 0xf4,
0x0e, 0xb5, 0xf7, 0xc8, 0x78, 0x7f, 0x9d, 0x5d, 0xac, 0xa6, 0x34, 0x5c, 0x5d, 0x2e, 0xa7, 0x14,
0x8c, 0x6b, 0xb5, 0xcd, 0x91, 0x1c, 0x43, 0xa7, 0x88, 0xb9, 0x8f, 0x92, 0x0d, 0x7a, 0x75, 0xb5,
0x9d, 0xf3, 0x03, 0x5a, 0x64, 0x7a, 0xa3, 0xc8, 0xf7, 0x96, 0xe5, 0x3f, 0x02, 0x37, 0xac, 0x1a,
0x87, 0xc7, 0x00, 0x81, 0xe4, 0x2c, 0xbd, 0xbe, 0x60, 0x42, 0x12, 0x0f, 0x9a, 0x98, 0x4a, 0xce,
0x50, 0x78, 0xd6, 0xc0, 0x1e, 0xb5, 0x69, 0x09, 0x87, 0x7f, 0xd7, 0xa1, 0xb9, 0x8c, 0xe2, 0xdb,
0xe8, 0x1a, 0x09, 0x81, 0xc3, 0x34, 0xba, 0xc3, 0xe2, 0xcc, 0xfa, 0x9b, 0x7c, 0x09, 0xc0, 0x31,
0xcf, 0x04, 0x93, 0x19, 0xdf, 0xea, 0x73, 0xb7, 0x69, 0x85, 0x51, 0x99, 0xef, 0x91, 0x0b, 0x96,
0xa5, 0xfa, 0xf0, 0x6d, 0x5a, 0x42, 0xa5, 0x70, 0x4c, 0x30, 0x12, 0xe6, 0xa8, 0x36, 0x2d, 0x21,
0xf9, 0x1c, 0xea, 0x98, 0x67, 0xf1, 0x8d, 0x3e, 0x8d, 0x7d, 0x7e, 0x40, 0x0d, 0x7c, 0x6f, 0x59,
0xe4, 0x1b, 0x70, 0xd6, 0x28, 0x62, 0xce, 0x72, 0xa9, 0x52, 0x36, 0xf4, 0x71, 0x2d, 0x5a, 0x25,
0x95, 0xed, 0x19, 0xb4, 0x6e, 0xb2, 0x3b, 0xcc, 0xa3, 0x6b, 0xf4, 0x9a, 0xda, 0x53, 0xa3, 0x3b,
0x46, 0x19, 0xbe, 0x02, 0xb8, 0x8b, 0x58, 0x2a, 0x23, 0x96, 0x22, 0xf7, 0x5a, 0xda, 0x62, 0xd3,
0x0a, 0xa7, 0x4c, 0x5f, 0x83, 0xab, 0x7a, 0xce, 0x24, 0xc6, 0x72, 0xc3, 0x51, 0x78, 0x6d, 0x5d,
0x9b, 0x7d, 0x92, 0xf4, 0xa1, 0x95, 0xb0, 0x18, 0x53, 0x81, 0xc2, 0x03, 0x6d, 0xd8, 0x61, 0xa5,
0xe5, 0x3c, 0xbb, 0x67, 0x6b, 0x14, 0x9e, 0x63, 0xb4, 0x12, 0x93, 0xa7, 0xd0, 0x8e, 0xb3, 0xf4,
0x6d, 0xc2, 0x62, 0x29, 0xbc, 0x8e, 0x16, 0x3f, 0x10, 0x2a, 0x92, 0x63, 0x9e, 0x44, 0x31, 0x0a,
0xcf, 0x35, 0x91, 0x25, 0x26, 0xdf, 0x43, 0x73, 0x8d, 0x39, 0xa6, 0x6b, 0xe1, 0x75, 0x07, 0xf6,
0xc8, 0x99, 0xf4, 0xcd, 0x90, 0x14, 0x7d, 0x1a, 0x9f, 0x1a, 0x71, 0x9a, 0x4a, 0xbe, 0xa5, 0xa5,
0x95, 0x9c, 0x82, 0x7b, 0xb5, 0x61, 0xc9, 0x3a, 0x2c, 0x63, 0x1f, 0xe9, 0xd8, 0x67, 0xfb, 0xb1,
0xbe, 0xb2, 0xec, 0x25, 0xe8, 0x5c, 0x55, 0xa8, 0xfe, 0x05, 0x74, 0xaa, 0x2a, 0xe9, 0x81, 0x7d,
0x8b, 0xe5, 0x35, 0x50, 0x9f, 0xe4, 0x18, 0xea, 0x66, 0x16, 0xd5, 0x30, 0x38, 0x93, 0x5e, 0x31,
0xec, 0xbb, 0x61, 0xa3, 0x46, 0xfe, 0xb1, 0xf6, 0x83, 0xd5, 0xff, 0x1d, 0x8e, 0x1e, 0x2c, 0xf8,
0x71, 0x29, 0xfd, 0x16, 0x34, 0x42, 0x3d, 0x2e, 0x7e, 0x17, 0x3a, 0x61, 0x65, 0x2e, 0x7c, 0x07,
0xda, 0x61, 0x39, 0x03, 0xbe, 0x0b, 0x4e, 0xf8, 0xa1, 0xdb, 0xc3, 0x33, 0x38, 0x3a, 0x43, 0x59,
0x14, 0xa1, 0xbc, 0xe4, 0xff, 0x63, 0xde, 0x87, 0x3f, 0x41, 0xb7, 0x7c, 0x29, 0x44, 0x9e, 0xa5,
0x02, 0xc9, 0xb7, 0xd0, 0xca, 0x4d, 0x5e, 0x73, 0xb9, 0x9c, 0xf2, 0xfe, 0x97, 0xab, 0xed, 0xe4,
0xe1, 0x2b, 0xf8, 0xf4, 0x0c, 0xa5, 0xae, 0x48, 0xa0, 0xb7, 0xfd, 0x31, 0x3b, 0x79, 0x01, 0x4f,
0xfe, 0x9d, 0xac, 0xd8, 0xd1, 0x13, 0x68, 0x98, 0xaa, 0x14, 0xf9, 0x0a, 0xf4, 0xfc, 0x67, 0x68,
0x16, 0x6f, 0x12, 0xe9, 0x40, 0xeb, 0xf5, 0x5c, 0x81, 0xe9, 0x69, 0xef, 0x80, 0xb4, 0xe0, 0x70,
0x7e, 0xf2, 0xdb, 0xb4, 0x67, 0x91, 0x2e, 0x00, 0x9d, 0x2e, 0x17, 0xc1, 0x6c, 0xb5, 0xa0, 0x97,
0xbd, 0x1a, 0x71, 0xa0, 0xf9, 0x66, 0x4a, 0x83, 0xd9, 0x62, 0xde, 0xb3, 0x9f, 0xfb, 0xe0, 0x54,
0xde, 0x29, 0xe2, 0x42, 0x7b, 0xbe, 0x08, 0x0d, 0xd3, 0x3b, 0x20, 0x47, 0xe0, 0xce, 0xe6, 0x61,
0x25, 0xda, 0x52, 0x54, 0xf0, 0x7a, 0xb9, 0x5c, 0xd0, 0x55, 0x10, 0x9e, 0xd0, 0x5f, 0xce, 0x7b,
0xb5, 0xc9, 0x9f, 0x16, 0xd8, 0x27, 0xcb, 0x19, 0x79, 0x09, 0x0d, 0x53, 0x47, 0xf2, 0x49, 0xd1,
0xed, 0xea, 0xfb, 0xdb, 0x7f, 0xbc, 0x4f, 0x16, 0x07, 0x7b, 0x01, 0x0d, 0xd5, 0xc5, 0xdb, 0x6b,
0xf2, 0x99, 0xd1, 0x1f, 0xf4, 0xb4, 0xbf, 0x5f, 0x7b, 0xf2, 0x0a, 0xba, 0xfb, 0x45, 0x22, 0x5f,
0xec, 0x22, 0x1f, 0xf6, 0xa1, 0xff, 0xf4, 0xbf, 0x45, 0xb3, 0xbc, 0xdf, 0xfa, 0xa3, 0x31, 0x1e,
0x7f, 0x17, 0xe5, 0xec, 0xaa, 0xa1, 0xff, 0x1e, 0x2f, 0xff, 0x09, 0x00, 0x00, 0xff, 0xff, 0xed,
0x6c, 0xfc, 0x7a, 0x4b, 0x06, 0x00, 0x00,
}