Skip to content

chore: upgrade speakeasy version #969

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 13, 2025
Merged

chore: upgrade speakeasy version #969

merged 1 commit into from
Jun 13, 2025

Conversation

gfyrag
Copy link
Contributor

@gfyrag gfyrag commented Jun 13, 2025

No description provided.

@gfyrag gfyrag requested a review from a team as a code owner June 13, 2025 15:34
Copy link

coderabbitai bot commented Jun 13, 2025

Warning

Rate limit exceeded

@gfyrag has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 5 minutes and 5 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 23e465b and 50d18b6.

⛔ Files ignored due to path filters (7)
  • flake.lock is excluded by !**/*.lock, !**/*.lock
  • pkg/client/.devcontainer/devcontainer.json is excluded by !**/*.json
  • pkg/client/.speakeasy/gen.lock is excluded by !**/*.lock, !**/*.lock
  • pkg/client/.speakeasy/gen.yaml is excluded by !**/*.yaml
  • pkg/client/.speakeasy/workflow.lock is excluded by !**/*.lock, !**/*.lock
  • pkg/client/.speakeasy/workflow.yaml is excluded by !**/*.yaml
  • pkg/client/go.mod is excluded by !**/*.mod
📒 Files selected for processing (20)
  • flake.nix (1 hunks)
  • pkg/client/.gitignore (1 hunks)
  • pkg/client/docs/models/components/v2reverttransactionresponse.md (0 hunks)
  • pkg/client/docs/models/operations/v2reverttransactionresponse.md (1 hunks)
  • pkg/client/docs/sdks/v1/README.md (3 hunks)
  • pkg/client/docs/sdks/v2/README.md (9 hunks)
  • pkg/client/formance.go (5 hunks)
  • pkg/client/internal/config/sdkconfiguration.go (1 hunks)
  • pkg/client/internal/hooks/hooks.go (3 hunks)
  • pkg/client/internal/utils/json.go (2 hunks)
  • pkg/client/internal/utils/oauth2_credentials.go (1 hunks)
  • pkg/client/internal/utils/oauth2_sessions.go (1 hunks)
  • pkg/client/internal/utils/requestbody.go (3 hunks)
  • pkg/client/ledger.go (10 hunks)
  • pkg/client/models/components/v2bulkelementresult.go (1 hunks)
  • pkg/client/models/components/v2reverttransactionresponse.go (0 hunks)
  • pkg/client/models/operations/v2reverttransaction.go (2 hunks)
  • pkg/client/v1.go (82 hunks)
  • pkg/client/v2.go (103 hunks)
  • test/e2e/api_transactions_revert_test.go (3 hunks)

Walkthrough

This update introduces a significant internal refactor of the Go SDK's configuration and hooks handling, moving configuration logic to a new config.SDKConfiguration struct and separating hooks management. It also removes the V2RevertTransactionResponse model, updating all references and documentation to use V2CreateTransactionResponse instead. Additional improvements include OAuth2 credential/session management utilities, multipart file upload enhancements, and updated documentation and test code.

Changes

File(s) Change Summary
flake.nix Updated speakeasy tool version and SHA256 hashes for all platforms.
pkg/client/.gitignore Added ignore rules for .DS_Store, .speakeasy/temp, and .speakeasy/logs.
pkg/client/docs/models/components/v2reverttransactionresponse.md
pkg/client/models/components/v2reverttransactionresponse.go
Removed documentation and Go struct for V2RevertTransactionResponse.
pkg/client/docs/models/operations/v2reverttransactionresponse.md Updated operation documentation to reference V2CreateTransactionResponse.
pkg/client/docs/sdks/v1/README.md
pkg/client/docs/sdks/v2/README.md
Updated SDK example code: simplified payloads, removed duplicates, and fixed references to new transaction response model.
pkg/client/formance.go
pkg/client/ledger.go
pkg/client/v1.go
pkg/client/v2.go
Refactored to use new config.SDKConfiguration, separated hooks, updated constructors and method signatures, and improved hook context usage.
pkg/client/internal/config/sdkconfiguration.go Added new configuration struct and interface for SDK configuration management.
pkg/client/internal/hooks/hooks.go Extended HookContext with SDK and configuration fields, added interface assertions.
pkg/client/internal/utils/json.go Changed struct tag access from Get("default") to Lookup("default").
pkg/client/internal/utils/oauth2_credentials.go
pkg/client/internal/utils/oauth2_sessions.go
Added OAuth2 credential and session management utilities.
pkg/client/internal/utils/requestbody.go Improved multipart file upload: supports arrays and sets content type by file extension.
pkg/client/models/components/v2bulkelementresult.go Renamed function parameter to avoid using reserved keyword error.
pkg/client/models/operations/v2reverttransaction.go Renamed struct field and getter to use V2CreateTransactionResponse.
test/e2e/api_transactions_revert_test.go Updated tests to reference V2CreateTransactionResponse data.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant SDK (Formance)
    participant Config (SDKConfiguration)
    participant Hooks
    participant Ledger/V1/V2 Client
    participant HTTP

    User->>SDK (Formance): New()
    SDK (Formance)->>Config: Initialize SDKConfiguration
    SDK (Formance)->>Hooks: Initialize hooks
    SDK (Formance)->>Ledger/V1/V2 Client: Instantiate with Config and Hooks

    User->>Ledger/V1/V2 Client: API Call
    Ledger/V1/V2 Client->>Hooks: BeforeRequest(HookContext)
    Ledger/V1/V2 Client->>HTTP: Send Request
    HTTP-->>Ledger/V1/V2 Client: Response/Error
    alt Success
        Ledger/V1/V2 Client->>Hooks: AfterSuccess(HookContext)
    else Error
        Ledger/V1/V2 Client->>Hooks: AfterError(HookContext)
    end
    Ledger/V1/V2 Client-->>User: Return response/error
Loading

Possibly related PRs

Suggested reviewers

  • flemzord

Poem

In the warren of code, a rabbit hops,
Refactoring config, never stops.
Hooks now apart, credentials anew,
Reverts and responses, all shining through.
With hashes refreshed and docs in tow,
This patch makes the SDK ready to go!
🐇✨

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate Unit Tests
  • Create PR with Unit Tests
  • Commit Unit Tests in branch chore/upgrade-speakeasy
  • Post Copyable Unit Tests in Comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai auto-generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

codecov bot commented Jun 13, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 82.83%. Comparing base (23b6baf) to head (23e465b).
Report is 2 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #969      +/-   ##
==========================================
+ Coverage   82.82%   82.83%   +0.01%     
==========================================
  Files         142      142              
  Lines        8028     8028              
==========================================
+ Hits         6649     6650       +1     
  Misses       1054     1054              
+ Partials      325      324       -1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 9

🔭 Outside diff range comments (2)
pkg/client/docs/models/operations/v2reverttransactionresponse.md (1)

1-9: 🛠️ Refactor suggestion

Doc heading & filename still reference the removed type

The model V2RevertTransactionResponse no longer exists, yet the markdown title and the path keep the old name. This is likely to confuse users who search the docs.

-# V2RevertTransactionResponse
+# V2CreateTransactionResponse   <!-- or rename file accordingly -->

Consider renaming both the heading and the file itself (v2createtransactionresponse.md) to reflect the new type.

pkg/client/models/operations/v2reverttransaction.go (1)

70-88: 🛠️ Refactor suggestion

Struct name / field mismatch is confusing – align naming to avoid cognitive overhead

V2RevertTransactionResponse now embeds V2CreateTransactionResponse both as the field name and the getter.
Readers will wonder why a “revert” operation returns a “create” model.

Options:

  1. Rename the struct itself to V2RevertTransactionCreateResponse (or similar) if that truly reflects the API contract.
  2. Keep the struct name but rename the field to something neutral like TransactionResponse.
-type V2RevertTransactionResponse struct {
+type V2RevertTransactionResponse struct {
     HTTPMeta components.HTTPMetadata `json:"-"`
-    // OK
-    V2CreateTransactionResponse *components.V2CreateTransactionResponse
+    // OK – reverted transaction details
+    TransactionResponse *components.V2CreateTransactionResponse
 }

The accompanying getter should be updated accordingly.
This small rename prevents future misunderstandings and accidental misuse.

♻️ Duplicate comments (2)
pkg/client/v1.go (2)

20-31: Repeat of SDKConfiguration by-value copy

Same concern as in ledger.go: keep a pointer rather than copying.


59-67: Duplicate OAuth2Scopes

All generated operations repeat "ledger:read" twice. Please deduplicate globally in the code-generator template.

🧹 Nitpick comments (14)
pkg/client/.gitignore (1)

1-3: Consider consolidating ignore patterns in the repo-root .gitignore

The patterns are fine, but you already ignore .DS_Store and .speakeasy/* at the repository root. Duplicating rules in a nested .gitignore can make maintenance harder when the same pattern must be updated in multiple places.
If there’s no need for package-local exceptions, move these three lines to the root file and drop this per-package entry.

pkg/client/internal/utils/json.go (1)

189-194: Tag.Lookup is the right call – maybe DRY it up

Switching from Tag.Get to Tag.Lookup correctly distinguishes “tag absent” from “tag present with empty value”, fixing subtle default-value edge-cases.

You now have identical defaultTag, ok := tag.Lookup("default") blocks in two places; extracting a tiny helper (getDefault(tag) (string, bool)) would avoid duplication.

Also applies to: 260-264

pkg/client/internal/hooks/hooks.go (1)

28-30: Consider narrowing the SDK field’s type to a dedicated interface instead of any

Using the empty type alias any forfeits compile-time guarantees and invites misuse from outside packages.
If the SDK root already exposes a stable surface (e.g. a small set of methods such as DoRequest, Config(), etc.), export a minimal interface and store that here:

-	SDK              any
+	SDK              sdkroot.Interface // minimal behaviour contract

This keeps flexibility while still protecting consumers from accidental type assertions.
If total flexibility is really required, add a short doc-comment explaining why an unconstrained type is intentional.

pkg/client/internal/utils/requestbody.go (2)

172-183: Slice/array handling duplicates field names with [] suffix – verify server compatibility

Appending "[]" to fieldName when iterating over slices assumes the server expects the “Rails-style” array notation. Many back-ends simply accept repeated field names without the suffix.
Consider making this behaviour configurable or falling back to the plain name for better interoperability:

-					if err := encodeMultipartFormDataFile(writer, tag.Name+"[]", arrayVal.Type(), arrayVal); err != nil {
+					field := tag.Name
+					if tag.ArraySuffix { // hypothetical flag
+						field += "[]"
+					}
+					if err := encodeMultipartFormDataFile(writer, field, arrayVal.Type(), arrayVal); err != nil {
 						writer.Close()
 						return "", err
 					}

261-270: Content-type detection ok, but consider falling back to http.DetectContentType for streams without extensions

mime.TypeByExtension returns an empty string for unknown or missing extensions, at which point we default to application/octet-stream.
Using http.DetectContentType on the first 512 bytes can yield a more accurate MIME guess and improve downstream behaviour:

-	contentType := mime.TypeByExtension(filepath.Ext(fileName))
-	if contentType == "" {
-		contentType = "application/octet-stream"
-	}
+	contentType := mime.TypeByExtension(filepath.Ext(fileName))
+	if contentType == "" {
+		// Fallback: sniff the first 512 bytes
+		if seeker, ok := reader.(io.ReadSeeker); ok {
+			head := make([]byte, 512)
+			n, _ := seeker.Read(head)
+			_, _ = seeker.Seek(0, io.SeekStart)
+			contentType = http.DetectContentType(head[:n])
+		}
+		if contentType == "" {
+			contentType = "application/octet-stream"
+		}
+	}

This remains backwards-compatible while improving accuracy.

pkg/client/formance.go (2)

50-56: Consider embedding config.SDKConfiguration or exposing an accessor

formance.sdkConfiguration is now an unexported, value-typed field.
Down-stream code that previously accessed or mutated configuration directly will no longer compile, and because it is stored by value, any consumer retaining a reference to SDKConfiguration will get a copy, not a live view.

Options:

-type Formance struct {
-    SDKVersion string
-    Ledger     *Ledger
-    sdkConfiguration config.SDKConfiguration
-    hooks            *hooks.Hooks
-}
+type Formance struct {
+    SDKVersion string
+    Ledger     *Ledger
+    config.SDKConfiguration                // anonymous embed keeps previous API working
+    hooks *hooks.Hooks
+}

or alternatively expose an accessor (Config() *config.SDKConfiguration).
Helps backward compatibility and avoids accidental stale copies.


127-134: Avoid hard-coded, duplicated version literals

The SDK version appears twice ("0.8.0"), once for SDKVersion and again inside the User-Agent string. Duplicating literals tends to drift.

-    SDKVersion: "0.8.0",
-    sdkConfiguration: config.SDKConfiguration{
-        UserAgent:  "speakeasy-sdk/go 0.8.0 2.629.1 v2 github.com/formancehq/ledger/pkg/client",
+    SDKVersion: sdkVersion,
+    sdkConfiguration: config.SDKConfiguration{
+        UserAgent:  fmt.Sprintf("speakeasy-sdk/go %s 2.629.1 v2 github.com/formancehq/ledger/pkg/client", sdkVersion),

with

const sdkVersion = "0.8.0"

Reduces maintenance overhead.

pkg/client/ledger.go (2)

65-72: Duplicate scope strings

OAuth2Scopes is initialised with []string{"ledger:read", "ledger:read"} – the second entry is redundant.

-		OAuth2Scopes:     []string{"ledger:read", "ledger:read"},
+		OAuth2Scopes:     []string{"ledger:read"},

Small, but worth fixing before it leaks into analytics or auth-caching.


130-156: Nil-hook protection?

All hook invocations now use s.hooks. If a caller builds a Ledger manually and passes nil, these paths will panic.
Either:

  1. Document that hooks must be non-nil, or
  2. Short-circuit when s.hooks == nil.

Option 2 keeps the public surface more robust.

if s.hooks != nil {
    req, err = s.hooks.BeforeRequest(... )
}
pkg/client/v1.go (2)

125-151: Shadowing req inside retry lambda

req, err = s.hooks.BeforeRequest(...) re-assigns the captured variable.
While legal, it mutates the outer req for subsequent retries, which is fine but unnecessary.
Consider using a local r := req inside the lambda to avoid accidental coupling.


2553-2560: Circular references & GC-pressure

Passing rootSDK *Formance into every sub-client creates cycles (Formance → Ledger/V1 → rootSDK).
Go’s GC breaks cycles, but avoidable retention of large graphs (e.g., HTTP client pools) may increase memory.

If rootSDK is only needed for hooks, consider passing the minimal interface instead.

pkg/client/internal/utils/oauth2_sessions.go (1)

54-60: Document the expiration buffer logic.

The method adds a 60-second buffer when checking expiration, but this magic number isn't documented. This buffer helps prevent using tokens that are about to expire during request processing.

Add a comment explaining the buffer:

 // Returns true if the session is expired or within one minute of expiring.
 func (s oAuth2Session) isExpired() bool {
 	if s.expiresAt == nil {
 		return false
 	}
 
+	// Add 60-second buffer to prevent using tokens that might expire during request processing
 	return time.Now().Unix()+60 >= *s.expiresAt
 }
pkg/client/internal/utils/oauth2_credentials.go (2)

120-131: Replace MD5 with a more modern hash function.

While this hash is used for cache keys rather than security, MD5 is deprecated and shouldn't be used in new code. Consider using SHA-256 or xxhash for better performance and to avoid security scanner warnings.

+import (
+	"crypto/sha256"
+	// ... other imports
+)

 func (c oAuth2ClientCredentials) Hash() string {
 	if c.hash != nil {
 		return *c.hash
 	}
 
-	md5Checksum := md5.Sum([]byte(c.clientID + ":" + c.clientSecret))
-	md5ChecksumStr := hex.EncodeToString(md5Checksum[:])
+	sha256Checksum := sha256.Sum256([]byte(c.clientID + ":" + c.clientSecret))
+	sha256ChecksumStr := hex.EncodeToString(sha256Checksum[:])
 
-	c.hash = &md5ChecksumStr
+	c.hash = &sha256ChecksumStr
 
 	return *c.hash
 }

67-70: Update misleading "Unused" comments.

The comments state these methods are "Unused", but they are required to implement the OAuth2AuthorizationGrantor interface. These comments are misleading.

-// Unused, however required to implement OAuth2AuthorizationGrantor.
+// Returns an empty string as pre-authorized tokens don't need credential hashing.
 func (c OAuth2AccessTokenCredentials) Hash() string {
 	return ""
 }

-// Unused, however required to implement OAuth2AuthorizationGrantor.
+// Returns an empty string as pre-authorized tokens don't require a token endpoint.
 func (c OAuth2AccessTokenCredentials) TokenEndpoint() string {
 	return ""
 }

Also applies to: 82-85

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 66b6edd and 23e465b.

⛔ Files ignored due to path filters (7)
  • flake.lock is excluded by !**/*.lock, !**/*.lock
  • pkg/client/.devcontainer/devcontainer.json is excluded by !**/*.json
  • pkg/client/.speakeasy/gen.lock is excluded by !**/*.lock, !**/*.lock
  • pkg/client/.speakeasy/gen.yaml is excluded by !**/*.yaml
  • pkg/client/.speakeasy/workflow.lock is excluded by !**/*.lock, !**/*.lock
  • pkg/client/.speakeasy/workflow.yaml is excluded by !**/*.yaml
  • pkg/client/go.mod is excluded by !**/*.mod
📒 Files selected for processing (20)
  • flake.nix (1 hunks)
  • pkg/client/.gitignore (1 hunks)
  • pkg/client/docs/models/components/v2reverttransactionresponse.md (0 hunks)
  • pkg/client/docs/models/operations/v2reverttransactionresponse.md (1 hunks)
  • pkg/client/docs/sdks/v1/README.md (3 hunks)
  • pkg/client/docs/sdks/v2/README.md (9 hunks)
  • pkg/client/formance.go (5 hunks)
  • pkg/client/internal/config/sdkconfiguration.go (1 hunks)
  • pkg/client/internal/hooks/hooks.go (3 hunks)
  • pkg/client/internal/utils/json.go (2 hunks)
  • pkg/client/internal/utils/oauth2_credentials.go (1 hunks)
  • pkg/client/internal/utils/oauth2_sessions.go (1 hunks)
  • pkg/client/internal/utils/requestbody.go (3 hunks)
  • pkg/client/ledger.go (10 hunks)
  • pkg/client/models/components/v2bulkelementresult.go (1 hunks)
  • pkg/client/models/components/v2reverttransactionresponse.go (0 hunks)
  • pkg/client/models/operations/v2reverttransaction.go (2 hunks)
  • pkg/client/v1.go (82 hunks)
  • pkg/client/v2.go (103 hunks)
  • test/e2e/api_transactions_revert_test.go (3 hunks)
💤 Files with no reviewable changes (2)
  • pkg/client/docs/models/components/v2reverttransactionresponse.md
  • pkg/client/models/components/v2reverttransactionresponse.go
🧰 Additional context used
🧬 Code Graph Analysis (5)
pkg/client/models/operations/v2reverttransaction.go (1)
pkg/client/models/operations/v2createtransaction.go (1)
  • V2CreateTransactionResponse (62-66)
pkg/client/internal/hooks/hooks.go (1)
pkg/client/internal/config/sdkconfiguration.go (1)
  • SDKConfiguration (16-25)
pkg/client/internal/utils/oauth2_sessions.go (3)
pkg/client/internal/utils/oauth2_credentials.go (2)
  • OAuth2AuthorizationGrantor (27-40)
  • HTTPClient (20-22)
pkg/client/internal/config/sdkconfiguration.go (1)
  • HTTPClient (12-14)
pkg/client/internal/hooks/hooks.go (2)
  • HTTPClient (23-25)
  • New (82-101)
pkg/client/v1.go (4)
pkg/client/formance.go (1)
  • Formance (50-56)
pkg/client/internal/config/sdkconfiguration.go (1)
  • SDKConfiguration (16-25)
pkg/client/internal/hooks/hooks.go (5)
  • Hooks (70-75)
  • BeforeRequestContext (37-39)
  • HookContext (27-35)
  • AfterErrorContext (45-47)
  • AfterSuccessContext (41-43)
pkg/client/internal/utils/utils.go (1)
  • MatchStatusCodes (71-92)
pkg/client/internal/utils/oauth2_credentials.go (3)
pkg/client/internal/config/sdkconfiguration.go (1)
  • HTTPClient (12-14)
pkg/client/internal/hooks/hooks.go (1)
  • HTTPClient (23-25)
pkg/client/formance.go (1)
  • HTTPClient (25-27)
⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: Tests
  • GitHub Check: Dirty
🔇 Additional comments (13)
flake.nix (1)

36-36: speakeasyVersion bump LGTM – no issues spotted
Version string is updated consistently with the download URL below; no further action required.

pkg/client/models/components/v2bulkelementresult.go (1)

215-223: Parameter rename eliminates shadowing – good cleanup
Renaming the parameter from error to errorT avoids shadowing the predeclared error type and makes the code clearer. ✅

test/e2e/api_transactions_revert_test.go (1)

151-161: Test updates align with new response struct

All references now use V2CreateTransactionResponse, matching the SDK changes. Looks good and should compile cleanly.

Also applies to: 202-202, 236-236

pkg/client/docs/sdks/v1/README.md (1)

463-466: Documentation only – no functional impact detected.

pkg/client/formance.go (1)

151-156:

✅ Verification successful

Verify SDKInit return order matches assignment

The assignment expects SDKInit to return (string, HTTPClient):

serverURL, sdk.sdkConfiguration.Client = sdk.hooks.SDKInit(currentServerURL, sdk.sdkConfiguration.Client)

A silent swap (e.g. (HTTPClient, string)) will compile but break runtime behaviour (client holds URL, serverURL holds nil-interface).


🏁 Script executed:

#!/bin/bash
# Show the signature of SDKInit to ensure it returns (string, client)
rg -n "func .*SDKInit" -A 1 -B 0

Length of output: 637


No changes needed: SDKInit return signature matches assignment
Verified that SDKInit is declared as

func (h *Hooks) SDKInit(baseURL string, client HTTPClient) (string, HTTPClient)

which aligns with the assignment in pkg/client/formance.go.

pkg/client/v2.go (4)

20-32: LGTM!

The refactoring to separate hooks from SDK configuration and add a reference to the root SDK improves the architecture by following the separation of concerns principle.


126-134: Good defensive programming!

The additional checks for http.NoBody and req.GetBody != nil prevent potential runtime panics when dealing with requests that don't have a body or don't support body retrieval.


59-67: Good enhancement to HookContext!

The addition of SDK and SDKConfiguration fields to the HookContext provides hooks with more context for advanced use cases like logging, debugging, or conditional behavior based on SDK configuration. The implementation is consistent across all methods.


4160-4165:

✅ Verification successful

Verify the response type change is intentional.

The response type has been changed from V2RevertTransactionResponse to V2CreateTransactionResponse. This makes sense if the revert operation creates a compensating transaction, but please ensure this aligns with the API specification.

Run the following script to verify the removal of V2RevertTransactionResponse and check for any remaining references:


🏁 Script executed:

#!/bin/bash
# Description: Verify that V2RevertTransactionResponse has been completely removed and check API operation files

# Test 1: Search for any remaining references to V2RevertTransactionResponse
echo "Searching for V2RevertTransactionResponse references..."
rg "V2RevertTransactionResponse" -A 2

# Test 2: Check the operations file for RevertTransaction to see the expected response type
echo -e "\nChecking RevertTransaction operation definition..."
fd -e go "v2reverttransaction.go" --exec cat {}

# Test 3: Look for any test files that might need updating
echo -e "\nChecking test files for revert transaction tests..."
fd -e go -e "_test.go" --exec rg -l "RevertTransaction|V2RevertTransaction" {}

Length of output: 7073


Response type change confirmed.

The RevertTransaction operation now returns an operations.V2RevertTransactionResponse that wraps a components.V2CreateTransactionResponse. This update is applied consistently across the codebase:

  • pkg/client/models/operations/v2reverttransaction.go: V2RevertTransactionResponse struct embeds *components.V2CreateTransactionResponse
  • pkg/client/v2.go: Unmarshalling into components.V2CreateTransactionResponse and assigning to res.V2CreateTransactionResponse
  • Operation definition (v2reverttransaction.go) and README docs updated to reference the new wrapper type
  • Tests (e.g., test/e2e/api_transactions_revert_test.go) still use operations.V2RevertTransactionResponse and will operate against the embedded create-response payload

All references to a standalone revert-specific response have been replaced or wrapped. This aligns with the API behavior of creating a compensating transaction on revert.

pkg/client/ledger.go (1)

120-128: Retry body-copy guard LGTM

The additional req.Body != http.NoBody && req.GetBody != nil check prevents panics on GetBody access – nice defensive upgrade.

pkg/client/v1.go (1)

115-123: Retry body-copy guard acknowledged

Same positive remark as in ledger.go.

pkg/client/docs/sdks/v2/README.md (2)

1294-1294: LGTM! Response type updated correctly.

The change from V2RevertTransactionResponse to V2CreateTransactionResponse correctly reflects the removal of the V2RevertTransactionResponse model as mentioned in the PR summary.


437-441:

❌ Incorrect review comment

Confirm the bulk operation example change aligns with API updates.

The bulk operation example changed from RevertTransaction to DeleteMetadata. Please verify this is the intended replacement example following the removal of the V2RevertTransactionResponse model.


🏁 Script executed:

#!/bin/bash
# Description: Verify if there are other bulk operation types available that might be more appropriate

# Search for V2BulkElement types in the codebase
ast-grep --pattern 'type V2BulkElement$$$'

# Search for CreateV2BulkElement functions
rg 'CreateV2BulkElement' --type go

Length of output: 4300


🏁 Script executed:

#!/bin/bash
# Search for any occurrence of V2RevertTransactionResponse
rg -n 'RevertTransactionResponse'

# Search for a type declaration matching V2RevertTransactionResponse
rg -n 'type V2RevertTransactionResponse'

# List files in the components models directory related to revert transaction
ls pkg/client/models/components | grep -i revert

Length of output: 2320


RevertTransaction is still supported; DeleteMetadata is simply a different example

The V2RevertTransactionResponse type and the RevertTransaction bulk operation are still present in the v2 client (see pkg/client/models/operations/v2reverttransaction.go and pkg/client/v2.go). The README change didn’t remove revert support—it merely swaps in the DeleteMetadata example. No API removal has occurred, and the new snippet correctly illustrates the DELETE_METADATA bulk operation.

Likely an incorrect or invalid review comment.

Comment on lines +44 to +47
"x86_64-linux" = "632559a6bdc765ef42b81b8404fd0a3e5023919a0bb70ff7e40a8cc259545afd";
"aarch64-linux" = "c74c502df3a05a2d69e6b282886df23354a319d0510d2c1a21fcc124b7ad00efGOROOT";
"x86_64-darwin" = "8814be1fdd4eaf6dcc7fb251ede5693e1d3d4c8e03986f8d37bfd59e049698b9";
"aarch64-darwin" = "12c20fa485de4725c9730cb2e8936cab4b0961d0a956e9f4c45534371f2a6148";
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Malformed SHA256 for aarch64-linux will cause Nix build failures
c74c502df3a05a2d69e6b282886df23354a319d0510d2c1a21fcc124b7ad00efGOROOT is 71 chars and contains non-hex text (GOROOT). Nix will reject this derivation.

-        "aarch64-linux"  = "c74c502df3a05a2d69e6b282886df23354a319d0510d2c1a21fcc124b7ad00efGOROOT";
+        # TODO: replace with the correct 64-char hex digest for v1.563.0
+        "aarch64-linux"  = "<correct_sha256_here>";

Re-download the artifact and compute the hash:

nix hash file speakeasy_linux_arm64.zip
🤖 Prompt for AI Agents
In flake.nix around lines 44 to 47, the SHA256 hash for "aarch64-linux" is
malformed because it contains non-hex characters and is too long, causing Nix
build failures. Re-download the corresponding artifact for the aarch64-linux
platform and compute the correct SHA256 hash using the command `nix hash file
<filename>`. Replace the incorrect hash string with the newly computed valid
SHA256 hash.

Comment on lines +27 to +33
func (c *SDKConfiguration) GetServerDetails() (string, map[string]string) {
if c.ServerURL != "" {
return c.ServerURL, nil
}

return c.ServerList[c.ServerIndex], nil
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Potential panic when ServerList is empty or ServerIndex is out of bounds

GetServerDetails directly indexes ServerList[c.ServerIndex] without validating that
a) ServerList is non-nil and non-empty, and
b) ServerIndex is within range.

A malformed configuration would bring the entire SDK down at runtime.

-func (c *SDKConfiguration) GetServerDetails() (string, map[string]string) {
-	if c.ServerURL != "" {
-		return c.ServerURL, nil
-	}
-
-	return c.ServerList[c.ServerIndex], nil
+func (c *SDKConfiguration) GetServerDetails() (string, map[string]string) {
+	if c == nil {
+		return "", nil
+	}
+	if c.ServerURL != "" {
+		return c.ServerURL, nil
+	}
+	if c.ServerIndex < 0 || c.ServerIndex >= len(c.ServerList) {
+		return "", nil // or return first entry / explicit error
+	}
+	return c.ServerList[c.ServerIndex], nil
 }

Failing fast (returning an explicit error) would be even safer.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
func (c *SDKConfiguration) GetServerDetails() (string, map[string]string) {
if c.ServerURL != "" {
return c.ServerURL, nil
}
return c.ServerList[c.ServerIndex], nil
}
func (c *SDKConfiguration) GetServerDetails() (string, map[string]string) {
if c == nil {
return "", nil
}
if c.ServerURL != "" {
return c.ServerURL, nil
}
if c.ServerIndex < 0 || c.ServerIndex >= len(c.ServerList) {
return "", nil // or return first entry / explicit error
}
return c.ServerList[c.ServerIndex], nil
}
🤖 Prompt for AI Agents
In pkg/client/internal/config/sdkconfiguration.go around lines 27 to 33, the
method GetServerDetails risks panicking by directly indexing ServerList with
ServerIndex without checking if ServerList is non-nil and non-empty or if
ServerIndex is within bounds. Modify the method to validate that ServerList is
not nil or empty and that ServerIndex is a valid index before accessing it. If
these conditions are not met, return an explicit error or a safe default to fail
fast and avoid runtime panics.

Comment on lines +24 to 36
rootSDK *Formance
sdkConfiguration config.SDKConfiguration
hooks *hooks.Hooks
}

func newLedger(sdkConfig sdkConfiguration) *Ledger {
func newLedger(rootSDK *Formance, sdkConfig config.SDKConfiguration, hooks *hooks.Hooks) *Ledger {
return &Ledger{
rootSDK: rootSDK,
sdkConfiguration: sdkConfig,
V1: newV1(sdkConfig),
V2: newV2(sdkConfig),
hooks: hooks,
V1: newV1(rootSDK, sdkConfig, hooks),
V2: newV2(rootSDK, sdkConfig, hooks),
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Value-copying SDKConfiguration risks silent divergence

sdkConfiguration is stored by value in Ledger, V1, V2, etc.
Because the struct contains mutable pointer fields (e.g. *retry.Config, *time.Duration, custom HTTPClient), two copies may silently diverge if either party mutates a field at runtime (think per–request timeout overrides).

Prefer keeping a single shared pointer:

-	sdkConfiguration config.SDKConfiguration
+	sdkConfiguration *config.SDKConfiguration

and update call-sites accordingly.
This avoids accidental “copy-on-write” bugs and lowers the per-client copy cost.

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In pkg/client/ledger.go around lines 24 to 36, the sdkConfiguration field is
currently stored by value in Ledger and its subcomponents, which risks silent
divergence due to mutable pointer fields inside the struct. To fix this, change
sdkConfiguration to be a pointer type throughout Ledger, V1, and V2 structs and
constructors, and update all call-sites to pass and use a pointer to
SDKConfiguration instead of a value copy. This ensures a single shared
configuration instance is used, preventing accidental copy-on-write bugs and
reducing memory overhead.

@@ -748,7 +750,7 @@ func main() {

res, err := s.Ledger.V2.DeleteAccountMetadata(ctx, operations.V2DeleteAccountMetadataRequest{
Ledger: "ledger001",
Address: "96609 Cummings Canyon",
Address: "6753 S Washington Street",
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Verify the address format change is intentional.

The address parameter changed from "users:001" to "6753 S Washington Street". This appears to be changing from an account identifier format to a physical street address, which may not be the intended format for the API's address parameter.


🏁 Script executed:

#!/bin/bash
# Description: Check other examples of address parameter usage in the documentation to verify the expected format

# Search for other DeleteAccountMetadata examples or address parameter usage
rg -A 5 -B 5 'Address.*"users:' pkg/client/docs/

Length of output: 5443


Ensure Address uses the correct account identifier format

The Address field in all other V1 and V2 client examples is treated as an account identifier (e.g. "users:001"), not a postal address. Replacing it with "6753 S Washington Street" is inconsistent and likely incorrect. Please clarify and update:

  • pkg/client/docs/sdks/v2/README.md line 753:
    • If the API still expects an account ID, revert to "users:001".
    • If you’ve intentionally changed Address to accept postal addresses, update all examples and the API docs to reflect this new format.
🤖 Prompt for AI Agents
In pkg/client/docs/sdks/v2/README.md at line 753, the Address parameter was
changed from an account identifier format like "users:001" to a physical street
address "6753 S Washington Street". Verify the intended format for the Address
parameter in the API. If the API expects an account identifier, revert the
Address value back to the original format "users:001". If the change to a postal
address is intentional, update all related examples and API documentation
consistently to reflect this new format.

Comment on lines +131 to +148
for accessToken, session := range s.sessions {
if session == nil {
continue
}

if session.isExpired() {
go s.delete(accessToken)

continue
}

if session.containsScopes(scopes) {
return session, nil
}
}

return s.create(ctx, httpClient, scopes)
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix race condition in session iteration.

The getSessionContainingScopes method reads from the sessions map without holding the mutex, which can cause a race condition if another goroutine modifies the map concurrently.

Apply this diff to fix the race condition:

 func (s oauth2Sessions) getSessionContainingScopes(ctx context.Context, httpClient HTTPClient, scopes []string) (*oAuth2Session, error) {
+	s.sessionsMutex.Lock()
+	// Create a list of sessions to check to avoid holding the lock during the entire iteration
+	var sessionsToCheck []*oAuth2Session
+	var accessTokensToDelete []string
+	
 	for accessToken, session := range s.sessions {
 		if session == nil {
 			continue
 		}
 
 		if session.isExpired() {
-			go s.delete(accessToken)
-
+			accessTokensToDelete = append(accessTokensToDelete, accessToken)
 			continue
 		}
 
 		if session.containsScopes(scopes) {
-			return session, nil
+			s.sessionsMutex.Unlock()
+			return session, nil
 		}
 	}
+	s.sessionsMutex.Unlock()
+	
+	// Delete expired sessions outside the critical section
+	for _, accessToken := range accessTokensToDelete {
+		s.delete(accessToken)
+	}
 
 	return s.create(ctx, httpClient, scopes)
 }

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In pkg/client/internal/utils/oauth2_sessions.go around lines 131 to 148, the
method iterates over the sessions map without locking the mutex, causing a race
condition. To fix this, acquire a read lock on the mutex before iterating over
the sessions map and release it after the iteration completes. This ensures safe
concurrent access to the map while checking sessions.

Comment on lines +180 to +188
func (e oAuth2TokenEndpoint) deleteCredentialsSession(authorizationGrantor OAuth2AuthorizationGrantor) {
if authorizationGrantor == nil {
return
}

e.credentialSessionsMutex.Lock()
e.credentialSessions[authorizationGrantor.Hash()] = newOAuth2Sessions(authorizationGrantor)
e.credentialSessionsMutex.Unlock()
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Method name doesn't match its behavior.

The deleteCredentialsSession method doesn't actually delete the credentials session - it replaces it with a new empty session collection. This is misleading.

Consider either:

  1. Renaming the method to resetCredentialsSession or clearCredentialsSession to better reflect its behavior
  2. Actually deleting the entry from the map:
 func (e oAuth2TokenEndpoint) deleteCredentialsSession(authorizationGrantor OAuth2AuthorizationGrantor) {
 	if authorizationGrantor == nil {
 		return
 	}
 
 	e.credentialSessionsMutex.Lock()
-	e.credentialSessions[authorizationGrantor.Hash()] = newOAuth2Sessions(authorizationGrantor)
+	delete(e.credentialSessions, authorizationGrantor.Hash())
 	e.credentialSessionsMutex.Unlock()
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
func (e oAuth2TokenEndpoint) deleteCredentialsSession(authorizationGrantor OAuth2AuthorizationGrantor) {
if authorizationGrantor == nil {
return
}
e.credentialSessionsMutex.Lock()
e.credentialSessions[authorizationGrantor.Hash()] = newOAuth2Sessions(authorizationGrantor)
e.credentialSessionsMutex.Unlock()
}
func (e oAuth2TokenEndpoint) deleteCredentialsSession(authorizationGrantor OAuth2AuthorizationGrantor) {
if authorizationGrantor == nil {
return
}
e.credentialSessionsMutex.Lock()
delete(e.credentialSessions, authorizationGrantor.Hash())
e.credentialSessionsMutex.Unlock()
}
🤖 Prompt for AI Agents
In pkg/client/internal/utils/oauth2_sessions.go around lines 180 to 188, the
method named deleteCredentialsSession does not delete the session but replaces
it with a new empty session collection, which is misleading. To fix this, either
rename the method to resetCredentialsSession or clearCredentialsSession to
reflect its behavior accurately, or modify the method to actually delete the
entry from the credentialSessions map using the delete keyword with the
authorizationGrantor's hash as the key.

Comment on lines +173 to +175
if response.TokenType != "Bearer" {
return nil, fmt.Errorf("unexpected token type: %s", response.TokenType)
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Make token type check case-insensitive.

According to RFC 6749, the token_type value is case-insensitive. The current implementation might reject valid responses with different casing.

-if response.TokenType != "Bearer" {
+if strings.ToLower(response.TokenType) != "bearer" {
 	return nil, fmt.Errorf("unexpected token type: %s", response.TokenType)
 }
🤖 Prompt for AI Agents
In pkg/client/internal/utils/oauth2_credentials.go around lines 173 to 175, the
token type check is currently case-sensitive, which can incorrectly reject valid
token types with different casing. Modify the condition to compare the token
type in a case-insensitive manner by converting both values to the same case
(e.g., lowercase) before comparison.

Comment on lines +162 to +165
if httpResponse.StatusCode < 200 || httpResponse.StatusCode >= 300 {
httpResponseBody, _ := io.ReadAll(httpResponse.Body)
return nil, fmt.Errorf("unexpected status code: %d: %s", httpResponse.StatusCode, httpResponseBody)
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Improve error response handling.

The current implementation might include sensitive information or excessively long response bodies in error messages.

 if httpResponse.StatusCode < 200 || httpResponse.StatusCode >= 300 {
 	httpResponseBody, _ := io.ReadAll(httpResponse.Body)
-	return nil, fmt.Errorf("unexpected status code: %d: %s", httpResponse.StatusCode, httpResponseBody)
+	// Limit response body in error message to prevent logging sensitive data or excessive content
+	responseSnippet := string(httpResponseBody)
+	if len(responseSnippet) > 200 {
+		responseSnippet = responseSnippet[:200] + "..."
+	}
+	return nil, fmt.Errorf("token request failed with status %d: %s", httpResponse.StatusCode, responseSnippet)
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if httpResponse.StatusCode < 200 || httpResponse.StatusCode >= 300 {
httpResponseBody, _ := io.ReadAll(httpResponse.Body)
return nil, fmt.Errorf("unexpected status code: %d: %s", httpResponse.StatusCode, httpResponseBody)
}
if httpResponse.StatusCode < 200 || httpResponse.StatusCode >= 300 {
httpResponseBody, _ := io.ReadAll(httpResponse.Body)
// Limit response body in error message to prevent logging sensitive data or excessive content
responseSnippet := string(httpResponseBody)
if len(responseSnippet) > 200 {
responseSnippet = responseSnippet[:200] + "..."
}
return nil, fmt.Errorf("token request failed with status %d: %s", httpResponse.StatusCode, responseSnippet)
}
🤖 Prompt for AI Agents
In pkg/client/internal/utils/oauth2_credentials.go around lines 162 to 165, the
error handling returns the entire HTTP response body in the error message, which
may expose sensitive data or be too large. Modify the code to limit the size of
the response body included in the error message, for example by truncating it to
a reasonable length, and sanitize or omit any sensitive information before
including it in the error string.

Comment on lines +19 to +22
// HTTPClient provides an interface for supplying the SDK with a custom HTTP client
type HTTPClient interface {
Do(req *http.Request) (*http.Response, error)
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Avoid duplicating the HTTPClient interface.

The HTTPClient interface is already defined in pkg/client/internal/config/sdkconfiguration.go and pkg/client/internal/hooks/hooks.go. Consider importing it from a common location instead of redefining it here.


🏁 Script executed:

#!/bin/bash
# Description: Check if there's a common location for the HTTPClient interface or if refactoring is needed

# Find all HTTPClient interface definitions
ast-grep --pattern 'type HTTPClient interface {
  Do(req *http.Request) (*http.Response, error)
}'

# Check import relationships
rg -l "HTTPClient interface" --type go | xargs -I {} sh -c 'echo "=== {} ==="; head -20 {}'

Length of output: 2828


Consolidate HTTPClient interface definitions

The HTTPClient interface is currently defined in four places:

  • pkg/client/formance.go (package client)
  • pkg/client/internal/config/sdkconfiguration.go (package config)
  • pkg/client/internal/hooks/hooks.go (package hooks)
  • pkg/client/internal/utils/oauth2_credentials.go (package utils)

To avoid distinct, incompatible types with identical signatures, remove the local definition in pkg/client/internal/utils/oauth2_credentials.go and import the shared interface from the config package (github.com/formancehq/ledger/pkg/client/internal/config). For example:

-import (
-  // other imports
-)
-
-// HTTPClient provides an interface for supplying the SDK with a custom HTTP client
-type HTTPClient interface {
-  Do(req *http.Request) (*http.Response, error)
-}
+import (
+  "github.com/formancehq/ledger/pkg/client/internal/config"
+  // other imports
+)
+
+// HTTPClient aliases the shared interface from config
+type HTTPClient = config.HTTPClient

Additionally, update your Speakeasy generator template so that all generated code consistently references the same HTTPClient from the config package.

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In pkg/client/internal/utils/oauth2_credentials.go around lines 19 to 22, remove
the local definition of the HTTPClient interface to avoid duplication. Instead,
import the HTTPClient interface from the common config package at
github.com/formancehq/ledger/pkg/client/internal/config. Update the import
statements accordingly and replace all local references to HTTPClient with the
imported one. Also, ensure the Speakeasy generator template is updated to
consistently use the HTTPClient from the config package across all generated
code.

@gfyrag gfyrag force-pushed the chore/upgrade-speakeasy branch from 23e465b to 50d18b6 Compare June 13, 2025 15:43
@gfyrag gfyrag added this pull request to the merge queue Jun 13, 2025
Merged via the queue into main with commit 3539a1b Jun 13, 2025
8 checks passed
@gfyrag gfyrag deleted the chore/upgrade-speakeasy branch June 13, 2025 16:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants