Skip to content

Commit

Permalink
feat: add response mutator option to config and update .gitignore to …
Browse files Browse the repository at this point in the history
…exclude aide files
  • Loading branch information
areknoster committed Aug 20, 2024
1 parent c4185aa commit c2a668d
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@
# vendor/

.DS_Store
.aider*
8 changes: 8 additions & 0 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ type config struct {
namingScheme NamingScheme
requestSanitizer RequestSanitizer
requestValidator RequestValidator
responseMutator ResponseMutator
parentHTTPClient *http.Client
}

Expand Down Expand Up @@ -50,6 +51,13 @@ func WithRequestValidator(v RequestValidator) Option {
}
}

// WithResponseMutator allows user to set the response mutator.
func WithResponseMutator(m ResponseMutator) Option {
return func(cfg *config) {
cfg.responseMutator = m

Check warning on line 57 in client.go

View check run for this annotation

Codecov / codecov/patch

client.go#L55-L57

Added lines #L55 - L57 were not covered by tests
}
}

// returns caller directory, assuming the caller is 2 levels up
func callerDir() string {
_, filePath, _, _ := runtime.Caller(3)
Expand Down
61 changes: 61 additions & 0 deletions response_mutator.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package hypert

import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"strconv"
)

// ResponseMutator is an interface for types that can modify HTTP responses.
type ResponseMutator interface {
MutateResponse(resp *http.Response) (*http.Response, error)
}

// JSONResponseMutator is a ResponseMutator that modifies JSON responses.
type JSONResponseMutator[T any] func(T) (T, error)

// Ensure JSONResponseMutator implements ResponseMutator
var _ ResponseMutator = JSONResponseMutator[any](nil)

// MutateResponse implements the ResponseMutator interface for JSONResponseMutator.
func (m JSONResponseMutator[T]) MutateResponse(resp *http.Response) (mutatedResp *http.Response, err error) {
defer func() {
if r := recover(); r != nil {
err = fmt.Errorf("panic in JSONResponseMutator: %v", r)

Check warning on line 27 in response_mutator.go

View check run for this annotation

Codecov / codecov/patch

response_mutator.go#L24-L27

Added lines #L24 - L27 were not covered by tests
}
}()

if resp.Header.Get("Content-Type") != "application/json" {
return resp, nil

Check warning on line 32 in response_mutator.go

View check run for this annotation

Codecov / codecov/patch

response_mutator.go#L31-L32

Added lines #L31 - L32 were not covered by tests
}

body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("read response body: %w", err)

Check warning on line 37 in response_mutator.go

View check run for this annotation

Codecov / codecov/patch

response_mutator.go#L35-L37

Added lines #L35 - L37 were not covered by tests
}
defer resp.Body.Close()

Check warning on line 39 in response_mutator.go

View check run for this annotation

Codecov / codecov/patch

response_mutator.go#L39

Added line #L39 was not covered by tests

var data T
if err := json.Unmarshal(body, &data); err != nil {
return nil, fmt.Errorf("unmarshal JSON: %w", err)

Check warning on line 43 in response_mutator.go

View check run for this annotation

Codecov / codecov/patch

response_mutator.go#L41-L43

Added lines #L41 - L43 were not covered by tests
}

mutatedData, err := m(data)
if err != nil {
return nil, fmt.Errorf("mutate JSON: %w", err)

Check warning on line 48 in response_mutator.go

View check run for this annotation

Codecov / codecov/patch

response_mutator.go#L46-L48

Added lines #L46 - L48 were not covered by tests
}

mutatedBody, err := json.Marshal(mutatedData)
if err != nil {
return nil, fmt.Errorf("marshal mutated JSON: %w", err)

Check warning on line 53 in response_mutator.go

View check run for this annotation

Codecov / codecov/patch

response_mutator.go#L51-L53

Added lines #L51 - L53 were not covered by tests
}

resp.Body = io.NopCloser(bytes.NewReader(mutatedBody))
resp.ContentLength = int64(len(mutatedBody))
resp.Header.Set("Content-Length", strconv.Itoa(len(mutatedBody)))

Check warning on line 58 in response_mutator.go

View check run for this annotation

Codecov / codecov/patch

response_mutator.go#L56-L58

Added lines #L56 - L58 were not covered by tests

return resp, nil

Check warning on line 60 in response_mutator.go

View check run for this annotation

Codecov / codecov/patch

response_mutator.go#L60

Added line #L60 was not covered by tests
}

0 comments on commit c2a668d

Please sign in to comment.