From 9a98381e85ec1abb6297303695a01bf5b0bb0806 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 25 Mar 2025 05:04:32 +0000 Subject: [PATCH 01/22] chore(docs): improve security documentation (#4) --- option/requestoption.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/option/requestoption.go b/option/requestoption.go index db9b540..880cf13 100644 --- a/option/requestoption.go +++ b/option/requestoption.go @@ -24,6 +24,8 @@ import ( type RequestOption = requestconfig.RequestOption // WithBaseURL returns a RequestOption that sets the BaseURL for the client. +// +// For security reasons, ensure that the base URL is trusted. func WithBaseURL(base string) RequestOption { u, err := url.Parse(base) if err != nil { From e478bcd482587882013395d08abd22df061b4d12 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 26 Mar 2025 04:30:55 +0000 Subject: [PATCH 02/22] chore: add request options to client tests (#6) --- client_test.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/client_test.go b/client_test.go index 8a4e459..ac0bbfc 100644 --- a/client_test.go +++ b/client_test.go @@ -26,6 +26,7 @@ func (t *closureTransport) RoundTrip(req *http.Request) (*http.Response, error) func TestUserAgentHeader(t *testing.T) { var userAgent string client := oxp.NewClient( + option.WithBearerToken("My Bearer Token"), option.WithHTTPClient(&http.Client{ Transport: &closureTransport{ fn: func(req *http.Request) (*http.Response, error) { @@ -46,6 +47,7 @@ func TestUserAgentHeader(t *testing.T) { func TestRetryAfter(t *testing.T) { retryCountHeaders := make([]string, 0) client := oxp.NewClient( + option.WithBearerToken("My Bearer Token"), option.WithHTTPClient(&http.Client{ Transport: &closureTransport{ fn: func(req *http.Request) (*http.Response, error) { @@ -79,6 +81,7 @@ func TestRetryAfter(t *testing.T) { func TestDeleteRetryCountHeader(t *testing.T) { retryCountHeaders := make([]string, 0) client := oxp.NewClient( + option.WithBearerToken("My Bearer Token"), option.WithHTTPClient(&http.Client{ Transport: &closureTransport{ fn: func(req *http.Request) (*http.Response, error) { @@ -108,6 +111,7 @@ func TestDeleteRetryCountHeader(t *testing.T) { func TestOverwriteRetryCountHeader(t *testing.T) { retryCountHeaders := make([]string, 0) client := oxp.NewClient( + option.WithBearerToken("My Bearer Token"), option.WithHTTPClient(&http.Client{ Transport: &closureTransport{ fn: func(req *http.Request) (*http.Response, error) { @@ -137,6 +141,7 @@ func TestOverwriteRetryCountHeader(t *testing.T) { func TestRetryAfterMs(t *testing.T) { attempts := 0 client := oxp.NewClient( + option.WithBearerToken("My Bearer Token"), option.WithHTTPClient(&http.Client{ Transport: &closureTransport{ fn: func(req *http.Request) (*http.Response, error) { @@ -162,6 +167,7 @@ func TestRetryAfterMs(t *testing.T) { func TestContextCancel(t *testing.T) { client := oxp.NewClient( + option.WithBearerToken("My Bearer Token"), option.WithHTTPClient(&http.Client{ Transport: &closureTransport{ fn: func(req *http.Request) (*http.Response, error) { @@ -181,6 +187,7 @@ func TestContextCancel(t *testing.T) { func TestContextCancelDelay(t *testing.T) { client := oxp.NewClient( + option.WithBearerToken("My Bearer Token"), option.WithHTTPClient(&http.Client{ Transport: &closureTransport{ fn: func(req *http.Request) (*http.Response, error) { @@ -208,6 +215,7 @@ func TestContextDeadline(t *testing.T) { go func() { client := oxp.NewClient( + option.WithBearerToken("My Bearer Token"), option.WithHTTPClient(&http.Client{ Transport: &closureTransport{ fn: func(req *http.Request) (*http.Response, error) { From e163f841e7943677016c18bd60f21de10a0eaa0e Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 26 Mar 2025 04:31:32 +0000 Subject: [PATCH 03/22] fix(test): return early after test failure (#7) --- usage_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/usage_test.go b/usage_test.go index c366a7c..12dc691 100644 --- a/usage_test.go +++ b/usage_test.go @@ -27,6 +27,7 @@ func TestUsage(t *testing.T) { tool, err := client.Tools.List(context.TODO(), oxp.ToolListParams{}) if err != nil { t.Error(err) + return } t.Logf("%+v\n", tool.Items) } From a327a76a39b0c7ea966e429d769f96cda6086c5d Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 27 Mar 2025 05:24:05 +0000 Subject: [PATCH 04/22] chore: fix typos (#8) --- internal/requestconfig/requestconfig.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/requestconfig/requestconfig.go b/internal/requestconfig/requestconfig.go index 93e10fe..17b9a57 100644 --- a/internal/requestconfig/requestconfig.go +++ b/internal/requestconfig/requestconfig.go @@ -241,7 +241,7 @@ func shouldRetry(req *http.Request, res *http.Response) bool { return true } - // If the header explictly wants a retry behavior, respect that over the + // If the header explicitly wants a retry behavior, respect that over the // http status code. if res.Header.Get("x-should-retry") == "true" { return true From ff74940482340fdfb9e2fdb05978af1a6da69425 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 27 Mar 2025 05:24:53 +0000 Subject: [PATCH 05/22] codegen metadata --- .stats.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.stats.yml b/.stats.yml index 3cca198..e5884e5 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,2 +1,4 @@ configured_endpoints: 3 openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/oxp%2Foxp-40d99ea9c623ae3faf290164274b8d9a85b078d85a71718afba833e7218502a8.yml +openapi_spec_hash: 0e452b918e63bb906a2886dfc2109a82 +config_hash: 4267724890db00da87d77d1a951b86f4 From 2f32d03bbadb69b873b8c57ac444b09d467d32dc Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 2 Apr 2025 10:16:59 +0000 Subject: [PATCH 06/22] fix: pluralize `list` response variables (#9) --- README.md | 8 ++++---- usage_test.go | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 5d77223..8fbeb11 100644 --- a/README.md +++ b/README.md @@ -52,11 +52,11 @@ func main() { client := oxp.NewClient( option.WithBearerToken("My Bearer Token"), // defaults to os.LookupEnv("OXP_API_KEY") ) - tool, err := client.Tools.List(context.TODO(), oxp.ToolListParams{}) + tools, err := client.Tools.List(context.TODO(), oxp.ToolListParams{}) if err != nil { panic(err.Error()) } - fmt.Printf("%+v\n", tool.Items) + fmt.Printf("%+v\n", tools.Items) } ``` @@ -250,7 +250,7 @@ you need to examine response headers, status codes, or other details. ```go // Create a variable to store the HTTP response var response *http.Response -tool, err := client.Tools.List( +tools, err := client.Tools.List( context.TODO(), oxp.ToolListParams{}, option.WithResponseInto(&response), @@ -258,7 +258,7 @@ tool, err := client.Tools.List( if err != nil { // handle error } -fmt.Printf("%+v\n", tool) +fmt.Printf("%+v\n", tools) fmt.Printf("Status Code: %d\n", response.StatusCode) fmt.Printf("Headers: %+#v\n", response.Header) diff --git a/usage_test.go b/usage_test.go index 12dc691..535d53a 100644 --- a/usage_test.go +++ b/usage_test.go @@ -24,10 +24,10 @@ func TestUsage(t *testing.T) { option.WithBaseURL(baseURL), option.WithBearerToken("My Bearer Token"), ) - tool, err := client.Tools.List(context.TODO(), oxp.ToolListParams{}) + tools, err := client.Tools.List(context.TODO(), oxp.ToolListParams{}) if err != nil { t.Error(err) return } - t.Logf("%+v\n", tool.Items) + t.Logf("%+v\n", tools.Items) } From 8edf5eced0206863e5ae85870a85cff7e548d087 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 3 Apr 2025 13:01:40 +0000 Subject: [PATCH 07/22] fix(client): return error on bad custom url instead of panic (#10) --- option/requestoption.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/option/requestoption.go b/option/requestoption.go index 880cf13..6a0b091 100644 --- a/option/requestoption.go +++ b/option/requestoption.go @@ -6,7 +6,6 @@ import ( "bytes" "fmt" "io" - "log" "net/http" "net/url" "strings" @@ -28,10 +27,11 @@ type RequestOption = requestconfig.RequestOption // For security reasons, ensure that the base URL is trusted. func WithBaseURL(base string) RequestOption { u, err := url.Parse(base) - if err != nil { - log.Fatalf("failed to parse BaseURL: %s\n", err) - } return requestconfig.RequestOptionFunc(func(r *requestconfig.RequestConfig) error { + if err != nil { + return fmt.Errorf("requestoption: WithBaseURL failed to parse url %s\n", err) + } + if u.Path != "" && !strings.HasSuffix(u.Path, "/") { u.Path += "/" } From b7b678c5f4d9c146dd23871c0662b9ef5403ad5b Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 8 Apr 2025 04:33:39 +0000 Subject: [PATCH 08/22] feat(client): support custom http clients (#11) --- internal/requestconfig/requestconfig.go | 10 +++++++++ option/requestoption.go | 29 ++++++++++++++++++++++--- 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/internal/requestconfig/requestconfig.go b/internal/requestconfig/requestconfig.go index 17b9a57..80a9c6f 100644 --- a/internal/requestconfig/requestconfig.go +++ b/internal/requestconfig/requestconfig.go @@ -192,6 +192,12 @@ func UseDefaultParam[T any](dst *param.Field[T], src *T) { } } +// This interface is primarily used to describe an [*http.Client], but also +// supports custom HTTP implementations. +type HTTPDoer interface { + Do(req *http.Request) (*http.Response, error) +} + // RequestConfig represents all the state related to one request. // // Editing the variables inside RequestConfig directly is unstable api. Prefer @@ -202,6 +208,7 @@ type RequestConfig struct { Context context.Context Request *http.Request BaseURL *url.URL + CustomHTTPDoer HTTPDoer HTTPClient *http.Client Middlewares []middleware BearerToken string @@ -399,6 +406,9 @@ func (cfg *RequestConfig) Execute() (err error) { } handler := cfg.HTTPClient.Do + if cfg.CustomHTTPDoer != nil { + handler = cfg.CustomHTTPDoer.Do + } for i := len(cfg.Middlewares) - 1; i >= 0; i -= 1 { handler = applyMiddleware(cfg.Middlewares[i], handler) } diff --git a/option/requestoption.go b/option/requestoption.go index 6a0b091..c1150c4 100644 --- a/option/requestoption.go +++ b/option/requestoption.go @@ -40,11 +40,34 @@ func WithBaseURL(base string) RequestOption { }) } -// WithHTTPClient returns a RequestOption that changes the underlying [http.Client] used to make this +// HTTPClient is primarily used to describe an [*http.Client], but also +// supports custom implementations. +// +// For bespoke implementations, prefer using an [*http.Client] with a +// custom transport. See [http.RoundTripper] for further information. +type HTTPClient interface { + Do(*http.Request) (*http.Response, error) +} + +// WithHTTPClient returns a RequestOption that changes the underlying http client used to make this // request, which by default is [http.DefaultClient]. -func WithHTTPClient(client *http.Client) RequestOption { +// +// For custom uses cases, it is recommended to provide an [*http.Client] with a custom +// [http.RoundTripper] as its transport, rather than directly implementing [HTTPClient]. +func WithHTTPClient(client HTTPClient) RequestOption { return requestconfig.RequestOptionFunc(func(r *requestconfig.RequestConfig) error { - r.HTTPClient = client + if client == nil { + return fmt.Errorf("requestoption: custom http client cannot be nil") + } + + if c, ok := client.(*http.Client); ok { + // Prefer the native client if possible. + r.HTTPClient = c + r.CustomHTTPDoer = nil + } else { + r.CustomHTTPDoer = client + } + return nil }) } From 825a88c183de7e804d22b0e0e34531bdddeefe03 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 10 Apr 2025 03:54:48 +0000 Subject: [PATCH 09/22] chore(internal): expand CI branch coverage --- .github/workflows/ci.yml | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a52ec3b..85bc971 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,18 +1,18 @@ name: CI on: push: - branches: - - main - pull_request: - branches: - - main - - next + branches-ignore: + - 'generated' + - 'codegen/**' + - 'integrated/**' + - 'preview-head/**' + - 'preview-base/**' + - 'preview/**' jobs: lint: name: lint runs-on: ubuntu-latest - steps: - uses: actions/checkout@v4 @@ -27,7 +27,6 @@ jobs: test: name: test runs-on: ubuntu-latest - steps: - uses: actions/checkout@v4 From 2f052f3bc440f8df016ec45fd2a324748e427267 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 10 Apr 2025 03:57:32 +0000 Subject: [PATCH 10/22] chore(internal): reduce CI branch coverage --- .github/workflows/ci.yml | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 85bc971..917696b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,19 +1,17 @@ name: CI on: push: - branches-ignore: - - 'generated' - - 'codegen/**' - - 'integrated/**' - - 'preview-head/**' - - 'preview-base/**' - - 'preview/**' + branches: + - main + pull_request: + branches: + - main + - next jobs: lint: name: lint runs-on: ubuntu-latest - steps: - uses: actions/checkout@v4 From 04176d5fae7f921179aac873854a2ee02fd09cf0 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 15 Apr 2025 03:53:30 +0000 Subject: [PATCH 11/22] docs: update documentation links to be more uniform --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 8fbeb11..007aaf2 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,8 @@ Go Reference -The Oxp Go library provides convenient access to [the Oxp REST -API](https://openexecprotocol.org) from applications written in Go. The full API of this library can be found in [api.md](api.md). +The Oxp Go library provides convenient access to the [Oxp REST API](https://openexecprotocol.org) +from applications written in Go. It is generated with [Stainless](https://www.stainless.com/). From 20574c517ada77d8e9cc532842090674609b704e Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 16 Apr 2025 03:22:58 +0000 Subject: [PATCH 12/22] chore(docs): document pre-request options --- internal/requestconfig/requestconfig.go | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/internal/requestconfig/requestconfig.go b/internal/requestconfig/requestconfig.go index 80a9c6f..e991014 100644 --- a/internal/requestconfig/requestconfig.go +++ b/internal/requestconfig/requestconfig.go @@ -589,16 +589,20 @@ func (cfg *RequestConfig) Apply(opts ...RequestOption) error { return nil } +// PreRequestOptions is used to collect all the options which need to be known before +// a call to [RequestConfig.ExecuteNewRequest], such as path parameters +// or global defaults. +// PreRequestOptions will return a [RequestConfig] with the options applied. +// +// Only request option functions of type [PreRequestOptionFunc] are applied. func PreRequestOptions(opts ...RequestOption) (RequestConfig, error) { cfg := RequestConfig{} for _, opt := range opts { - if _, ok := opt.(PreRequestOptionFunc); !ok { - continue - } - - err := opt.Apply(&cfg) - if err != nil { - return cfg, err + if opt, ok := opt.(PreRequestOptionFunc); ok { + err := opt.Apply(&cfg) + if err != nil { + return cfg, err + } } } return cfg, nil From da52f0027c05cc6be43fd7293589dfc7ebb14837 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 16 Apr 2025 03:26:31 +0000 Subject: [PATCH 13/22] feat(client): add support for reading base URL from environment variable --- client.go | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/client.go b/client.go index b217573..6af46ef 100644 --- a/client.go +++ b/client.go @@ -20,10 +20,13 @@ type Client struct { Tools *ToolService } -// DefaultClientOptions read from the environment (OXP_API_KEY). This should be -// used to initialize new clients. +// DefaultClientOptions read from the environment (OXP_API_KEY, OXP_BASE_URL). This +// should be used to initialize new clients. func DefaultClientOptions() []option.RequestOption { defaults := []option.RequestOption{option.WithEnvironmentProduction()} + if o, ok := os.LookupEnv("OXP_BASE_URL"); ok { + defaults = append(defaults, option.WithBaseURL(o)) + } if o, ok := os.LookupEnv("OXP_API_KEY"); ok { defaults = append(defaults, option.WithBearerToken(o)) } @@ -31,9 +34,9 @@ func DefaultClientOptions() []option.RequestOption { } // NewClient generates a new client with the default option read from the -// environment (OXP_API_KEY). The option passed in as arguments are applied after -// these default arguments, and all option will be passed down to the services and -// requests that this client makes. +// environment (OXP_API_KEY, OXP_BASE_URL). The option passed in as arguments are +// applied after these default arguments, and all option will be passed down to the +// services and requests that this client makes. func NewClient(opts ...option.RequestOption) (r *Client) { opts = append(DefaultClientOptions(), opts...) From 482d0dac6399b0e7816505e79db2336e7796f43c Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 23 Apr 2025 04:22:04 +0000 Subject: [PATCH 14/22] chore(ci): add timeout thresholds for CI jobs --- .github/workflows/ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 917696b..d22e236 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,6 +10,7 @@ on: jobs: lint: + timeout-minutes: 10 name: lint runs-on: ubuntu-latest steps: @@ -23,6 +24,7 @@ jobs: - name: Run lints run: ./scripts/lint test: + timeout-minutes: 10 name: test runs-on: ubuntu-latest steps: From d36116ef0fbe894a5e4e8b23e3c38a8524b4883d Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 24 Apr 2025 02:54:25 +0000 Subject: [PATCH 15/22] chore(internal): codegen related update --- .github/workflows/ci.yml | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d22e236..4b9fb4c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,18 +1,19 @@ name: CI on: push: - branches: - - main - pull_request: - branches: - - main - - next + branches-ignore: + - 'generated' + - 'codegen/**' + - 'integrated/**' + - 'stl-preview-head/**' + - 'stl-preview-base/**' jobs: lint: timeout-minutes: 10 name: lint - runs-on: ubuntu-latest + runs-on: depot-ubuntu-24.04 + steps: - uses: actions/checkout@v4 @@ -26,7 +27,7 @@ jobs: test: timeout-minutes: 10 name: test - runs-on: ubuntu-latest + runs-on: depot-ubuntu-24.04 steps: - uses: actions/checkout@v4 From 142cc659c7157b718fec883d9985c89d8076d2c7 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 24 Apr 2025 02:54:55 +0000 Subject: [PATCH 16/22] chore(ci): only use depot for staging repos --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4b9fb4c..7aa945e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,7 +12,7 @@ jobs: lint: timeout-minutes: 10 name: lint - runs-on: depot-ubuntu-24.04 + runs-on: ${{ github.repository == 'stainless-sdks/oxp-go' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }} steps: - uses: actions/checkout@v4 @@ -27,7 +27,7 @@ jobs: test: timeout-minutes: 10 name: test - runs-on: depot-ubuntu-24.04 + runs-on: ${{ github.repository == 'stainless-sdks/oxp-go' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }} steps: - uses: actions/checkout@v4 From 63aa3d57eb4c8ce13fa441d9e0f416ba8aee5f3e Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 29 Apr 2025 03:33:11 +0000 Subject: [PATCH 17/22] chore(internal): codegen related update --- tool.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tool.go b/tool.go index 223a8bb..070ba21 100644 --- a/tool.go +++ b/tool.go @@ -368,6 +368,10 @@ func init() { apijson.RegisterUnion( reflect.TypeOf((*ToolCallResponseResultObjectValueUnion)(nil)).Elem(), "", + apijson.UnionVariant{ + TypeFilter: gjson.JSON, + Type: reflect.TypeOf(ToolCallResponseResultObjectValueMap{}), + }, apijson.UnionVariant{ TypeFilter: gjson.JSON, Type: reflect.TypeOf(ToolCallResponseResultObjectValueArray{}), From 43b073417aa7257ab842d7ce7859f29f780905a1 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 30 Apr 2025 03:13:20 +0000 Subject: [PATCH 18/22] fix: handle empty bodies in WithJSONSet --- option/requestoption.go | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/option/requestoption.go b/option/requestoption.go index c1150c4..223ba71 100644 --- a/option/requestoption.go +++ b/option/requestoption.go @@ -169,17 +169,26 @@ func WithQueryDel(key string) RequestOption { // [sjson format]: https://github.com/tidwall/sjson func WithJSONSet(key string, value interface{}) RequestOption { return requestconfig.RequestOptionFunc(func(r *requestconfig.RequestConfig) (err error) { - if buffer, ok := r.Body.(*bytes.Buffer); ok { - b := buffer.Bytes() + var b []byte + + if r.Body == nil { + b, err = sjson.SetBytes(nil, key, value) + if err != nil { + return err + } + } else if buffer, ok := r.Body.(*bytes.Buffer); ok { + b = buffer.Bytes() b, err = sjson.SetBytes(b, key, value) if err != nil { return err } - r.Body = bytes.NewBuffer(b) return nil + } else { + return fmt.Errorf("cannot use WithJSONSet on a body that is not serialized as *bytes.Buffer") } - return fmt.Errorf("cannot use WithJSONSet on a body that is not serialized as *bytes.Buffer") + r.Body = bytes.NewBuffer(b) + return nil }) } From 3190e17794373f3889eb2c28c8c0f90de3fd3ac4 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 7 May 2025 05:11:04 +0000 Subject: [PATCH 19/22] fix(client): correctly update body in WithJSONSet --- option/requestoption.go | 1 - 1 file changed, 1 deletion(-) diff --git a/option/requestoption.go b/option/requestoption.go index 223ba71..58fba79 100644 --- a/option/requestoption.go +++ b/option/requestoption.go @@ -182,7 +182,6 @@ func WithJSONSet(key string, value interface{}) RequestOption { if err != nil { return err } - return nil } else { return fmt.Errorf("cannot use WithJSONSet on a body that is not serialized as *bytes.Buffer") } From 02e8b5fb02559a8c9add291312b9f9877cae7f53 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 7 May 2025 05:15:38 +0000 Subject: [PATCH 20/22] fix(client): clean up reader resources --- internal/requestconfig/requestconfig.go | 1 + 1 file changed, 1 insertion(+) diff --git a/internal/requestconfig/requestconfig.go b/internal/requestconfig/requestconfig.go index e991014..9ba86eb 100644 --- a/internal/requestconfig/requestconfig.go +++ b/internal/requestconfig/requestconfig.go @@ -508,6 +508,7 @@ func (cfg *RequestConfig) Execute() (err error) { } contents, err := io.ReadAll(res.Body) + res.Body.Close() if err != nil { return fmt.Errorf("error reading response body: %w", err) } From 3435e12d250ba62a5fb9d2fba16fe91e97b789e4 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 14 May 2025 03:45:07 +0000 Subject: [PATCH 21/22] feat(client): add support for endpoint-specific base URLs in python This also changes how `WithEnvironmentProduction()` and `WithBaseURL()` interact. Previously, `WithBaseURL()` would be overridden by `WithEnvironmentProduction()` if `WithEnvironmentProduction()` was later in the list of options; now, `WithBaseURL()` always takes precedence. --- internal/requestconfig/requestconfig.go | 23 ++++++++++++++++++++++- option/requestoption.go | 2 +- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/internal/requestconfig/requestconfig.go b/internal/requestconfig/requestconfig.go index 9ba86eb..a2d4e19 100644 --- a/internal/requestconfig/requestconfig.go +++ b/internal/requestconfig/requestconfig.go @@ -208,6 +208,9 @@ type RequestConfig struct { Context context.Context Request *http.Request BaseURL *url.URL + // DefaultBaseURL will be used if BaseURL is not explicitly overridden using + // WithBaseURL. + DefaultBaseURL *url.URL CustomHTTPDoer HTTPDoer HTTPClient *http.Client Middlewares []middleware @@ -374,7 +377,11 @@ func retryDelay(res *http.Response, retryCount int) time.Duration { func (cfg *RequestConfig) Execute() (err error) { if cfg.BaseURL == nil { - return fmt.Errorf("requestconfig: base url is not set") + if cfg.DefaultBaseURL != nil { + cfg.BaseURL = cfg.DefaultBaseURL + } else { + return fmt.Errorf("requestconfig: base url is not set") + } } cfg.Request.URL, err = cfg.BaseURL.Parse(strings.TrimLeft(cfg.Request.URL.String(), "/")) @@ -608,3 +615,17 @@ func PreRequestOptions(opts ...RequestOption) (RequestConfig, error) { } return cfg, nil } + +// WithDefaultBaseURL returns a RequestOption that sets the client's default Base URL. +// This is always overridden by setting a base URL with WithBaseURL. +// WithBaseURL should be used instead of WithDefaultBaseURL except in internal code. +func WithDefaultBaseURL(baseURL string) RequestOption { + u, err := url.Parse(baseURL) + return RequestOptionFunc(func(r *RequestConfig) error { + if err != nil { + return err + } + r.DefaultBaseURL = u + return nil + }) +} diff --git a/option/requestoption.go b/option/requestoption.go index 58fba79..a067e5e 100644 --- a/option/requestoption.go +++ b/option/requestoption.go @@ -262,7 +262,7 @@ func WithRequestTimeout(dur time.Duration) RequestOption { // environment to be the "production" environment. An environment specifies which base URL // to use by default. func WithEnvironmentProduction() RequestOption { - return WithBaseURL("https://api.arcade.dev/") + return requestconfig.WithDefaultBaseURL("https://api.arcade.dev/") } // WithBearerToken returns a RequestOption that sets the client setting "bearer_token". From 0ca3bc11965b81f4c0f7bed552494ea6e8cfc668 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 14 May 2025 03:45:26 +0000 Subject: [PATCH 22/22] release: 0.1.0 --- .release-please-manifest.json | 2 +- CHANGELOG.md | 39 +++++++++++++++++++++++++++++++++++ README.md | 2 +- internal/version.go | 2 +- 4 files changed, 42 insertions(+), 3 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index c7159c1..3d2ac0b 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.0.2" + ".": "0.1.0" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 95db213..00dbe6f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,44 @@ # Changelog +## 0.1.0 (2025-05-14) + +Full Changelog: [v0.0.2...v0.1.0](https://github.com/OpenExecProtocol/oxp-go/compare/v0.0.2...v0.1.0) + +### Features + +* **client:** add support for endpoint-specific base URLs in python ([3435e12](https://github.com/OpenExecProtocol/oxp-go/commit/3435e12d250ba62a5fb9d2fba16fe91e97b789e4)) +* **client:** add support for reading base URL from environment variable ([da52f00](https://github.com/OpenExecProtocol/oxp-go/commit/da52f0027c05cc6be43fd7293589dfc7ebb14837)) +* **client:** support custom http clients ([#11](https://github.com/OpenExecProtocol/oxp-go/issues/11)) ([b7b678c](https://github.com/OpenExecProtocol/oxp-go/commit/b7b678c5f4d9c146dd23871c0662b9ef5403ad5b)) + + +### Bug Fixes + +* **client:** clean up reader resources ([02e8b5f](https://github.com/OpenExecProtocol/oxp-go/commit/02e8b5fb02559a8c9add291312b9f9877cae7f53)) +* **client:** correctly update body in WithJSONSet ([3190e17](https://github.com/OpenExecProtocol/oxp-go/commit/3190e17794373f3889eb2c28c8c0f90de3fd3ac4)) +* **client:** return error on bad custom url instead of panic ([#10](https://github.com/OpenExecProtocol/oxp-go/issues/10)) ([8edf5ec](https://github.com/OpenExecProtocol/oxp-go/commit/8edf5eced0206863e5ae85870a85cff7e548d087)) +* handle empty bodies in WithJSONSet ([43b0734](https://github.com/OpenExecProtocol/oxp-go/commit/43b073417aa7257ab842d7ce7859f29f780905a1)) +* pluralize `list` response variables ([#9](https://github.com/OpenExecProtocol/oxp-go/issues/9)) ([2f32d03](https://github.com/OpenExecProtocol/oxp-go/commit/2f32d03bbadb69b873b8c57ac444b09d467d32dc)) +* **test:** return early after test failure ([#7](https://github.com/OpenExecProtocol/oxp-go/issues/7)) ([e163f84](https://github.com/OpenExecProtocol/oxp-go/commit/e163f841e7943677016c18bd60f21de10a0eaa0e)) + + +### Chores + +* add request options to client tests ([#6](https://github.com/OpenExecProtocol/oxp-go/issues/6)) ([e478bcd](https://github.com/OpenExecProtocol/oxp-go/commit/e478bcd482587882013395d08abd22df061b4d12)) +* **ci:** add timeout thresholds for CI jobs ([482d0da](https://github.com/OpenExecProtocol/oxp-go/commit/482d0dac6399b0e7816505e79db2336e7796f43c)) +* **ci:** only use depot for staging repos ([142cc65](https://github.com/OpenExecProtocol/oxp-go/commit/142cc659c7157b718fec883d9985c89d8076d2c7)) +* **docs:** document pre-request options ([20574c5](https://github.com/OpenExecProtocol/oxp-go/commit/20574c517ada77d8e9cc532842090674609b704e)) +* **docs:** improve security documentation ([#4](https://github.com/OpenExecProtocol/oxp-go/issues/4)) ([9a98381](https://github.com/OpenExecProtocol/oxp-go/commit/9a98381e85ec1abb6297303695a01bf5b0bb0806)) +* fix typos ([#8](https://github.com/OpenExecProtocol/oxp-go/issues/8)) ([a327a76](https://github.com/OpenExecProtocol/oxp-go/commit/a327a76a39b0c7ea966e429d769f96cda6086c5d)) +* **internal:** codegen related update ([63aa3d5](https://github.com/OpenExecProtocol/oxp-go/commit/63aa3d57eb4c8ce13fa441d9e0f416ba8aee5f3e)) +* **internal:** codegen related update ([d36116e](https://github.com/OpenExecProtocol/oxp-go/commit/d36116ef0fbe894a5e4e8b23e3c38a8524b4883d)) +* **internal:** expand CI branch coverage ([825a88c](https://github.com/OpenExecProtocol/oxp-go/commit/825a88c183de7e804d22b0e0e34531bdddeefe03)) +* **internal:** reduce CI branch coverage ([2f052f3](https://github.com/OpenExecProtocol/oxp-go/commit/2f052f3bc440f8df016ec45fd2a324748e427267)) + + +### Documentation + +* update documentation links to be more uniform ([04176d5](https://github.com/OpenExecProtocol/oxp-go/commit/04176d5fae7f921179aac873854a2ee02fd09cf0)) + ## 0.0.2 (2025-03-16) Full Changelog: [v0.0.1-alpha.0...v0.0.2](https://github.com/OpenExecProtocol/oxp-go/compare/v0.0.1-alpha.0...v0.0.2) diff --git a/README.md b/README.md index 007aaf2..1722ee7 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ Or to pin the version: ```sh -go get -u 'github.com/OpenExecProtocol/oxp-go@v0.0.2' +go get -u 'github.com/OpenExecProtocol/oxp-go@v0.1.0' ``` diff --git a/internal/version.go b/internal/version.go index 9b92696..02eac73 100644 --- a/internal/version.go +++ b/internal/version.go @@ -2,4 +2,4 @@ package internal -const PackageVersion = "0.0.2" // x-release-please-version +const PackageVersion = "0.1.0" // x-release-please-version