Skip to content
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

feat(api): updates #141

Merged
merged 1 commit into from
Oct 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 9 additions & 5 deletions account.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ func (r *AccountService) Update(ctx context.Context, accountToken string, body A
}

// List account configurations.
func (r *AccountService) List(ctx context.Context, query AccountListParams, opts ...option.RequestOption) (res *shared.Page[Account], err error) {
func (r *AccountService) List(ctx context.Context, query AccountListParams, opts ...option.RequestOption) (res *shared.CursorPage[Account], err error) {
var raw *http.Response
opts = append(r.Options, opts...)
opts = append([]option.RequestOption{option.WithResponseInto(&raw)}, opts...)
Expand All @@ -73,8 +73,8 @@ func (r *AccountService) List(ctx context.Context, query AccountListParams, opts
}

// List account configurations.
func (r *AccountService) ListAutoPaging(ctx context.Context, query AccountListParams, opts ...option.RequestOption) *shared.PageAutoPager[Account] {
return shared.NewPageAutoPager(r.List(ctx, query, opts...))
func (r *AccountService) ListAutoPaging(ctx context.Context, query AccountListParams, opts ...option.RequestOption) *shared.CursorPageAutoPager[Account] {
return shared.NewCursorPageAutoPager(r.List(ctx, query, opts...))
}

type Account struct {
Expand Down Expand Up @@ -283,10 +283,14 @@ type AccountListParams struct {
// Date string in RFC 3339 format. Only entries created before the specified date
// will be included. UTC time zone.
End param.Field[time.Time] `query:"end" format:"date-time"`
// Page (for pagination).
Page param.Field[int64] `query:"page"`
// A cursor representing an item's token before which a page of results should end.
// Used to retrieve the previous page of results before this item.
EndingBefore param.Field[string] `query:"ending_before"`
// Page size (for pagination).
PageSize param.Field[int64] `query:"page_size"`
// A cursor representing an item's token after which a page of results should
// begin. Used to retrieve the next page of results after this item.
StartingAfter param.Field[string] `query:"starting_after"`
}

// URLQuery serializes [AccountListParams]'s query parameters as `url.Values`.
Expand Down
9 changes: 5 additions & 4 deletions account_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,10 +89,11 @@ func TestAccountListWithOptionalParams(t *testing.T) {
option.WithAPIKey("APIKey"),
)
_, err := client.Accounts.List(context.TODO(), lithic.AccountListParams{
Begin: lithic.F(time.Now()),
End: lithic.F(time.Now()),
Page: lithic.F(int64(0)),
PageSize: lithic.F(int64(1)),
Begin: lithic.F(time.Now()),
End: lithic.F(time.Now()),
EndingBefore: lithic.F("string"),
PageSize: lithic.F(int64(1)),
StartingAfter: lithic.F("string"),
})
if err != nil {
var apierr *lithic.Error
Expand Down
8 changes: 4 additions & 4 deletions api.md

Large diffs are not rendered by default.

24 changes: 14 additions & 10 deletions authrule.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ func (r *AuthRuleService) Update(ctx context.Context, authRuleToken string, body
}

// Return all of the Auth Rules under the program.
func (r *AuthRuleService) List(ctx context.Context, query AuthRuleListParams, opts ...option.RequestOption) (res *shared.Page[AuthRule], err error) {
func (r *AuthRuleService) List(ctx context.Context, query AuthRuleListParams, opts ...option.RequestOption) (res *shared.CursorPage[AuthRule], err error) {
var raw *http.Response
opts = append(r.Options, opts...)
opts = append([]option.RequestOption{option.WithResponseInto(&raw)}, opts...)
Expand All @@ -79,8 +79,8 @@ func (r *AuthRuleService) List(ctx context.Context, query AuthRuleListParams, op
}

// Return all of the Auth Rules under the program.
func (r *AuthRuleService) ListAutoPaging(ctx context.Context, query AuthRuleListParams, opts ...option.RequestOption) *shared.PageAutoPager[AuthRule] {
return shared.NewPageAutoPager(r.List(ctx, query, opts...))
func (r *AuthRuleService) ListAutoPaging(ctx context.Context, query AuthRuleListParams, opts ...option.RequestOption) *shared.CursorPageAutoPager[AuthRule] {
return shared.NewCursorPageAutoPager(r.List(ctx, query, opts...))
}

// Applies an existing authorization rule (Auth Rule) to an program, account, or
Expand All @@ -103,7 +103,9 @@ func (r *AuthRuleService) Remove(ctx context.Context, body AuthRuleRemoveParams,

type AuthRule struct {
// Globally unique identifier.
Token string `json:"token" format:"uuid"`
Token string `json:"token,required" format:"uuid"`
// Indicates whether the Auth Rule is ACTIVE or INACTIVE
State AuthRuleState `json:"state,required"`
// Array of account_token(s) identifying the accounts that the Auth Rule applies
// to. Note that only this field or `card_tokens` can be provided for a given Auth
// Rule.
Expand All @@ -124,22 +126,20 @@ type AuthRule struct {
CardTokens []string `json:"card_tokens"`
// Boolean indicating whether the Auth Rule is applied at the program level.
ProgramLevel bool `json:"program_level"`
// Indicates whether the Auth Rule is ACTIVE or INACTIVE
State AuthRuleState `json:"state"`
JSON authRuleJSON
JSON authRuleJSON
}

// authRuleJSON contains the JSON metadata for the struct [AuthRule]
type authRuleJSON struct {
Token apijson.Field
State apijson.Field
AccountTokens apijson.Field
AllowedCountries apijson.Field
AllowedMcc apijson.Field
BlockedCountries apijson.Field
BlockedMcc apijson.Field
CardTokens apijson.Field
ProgramLevel apijson.Field
State apijson.Field
raw string
ExtraFields map[string]apijson.Field
}
Expand Down Expand Up @@ -244,10 +244,14 @@ func (r AuthRuleUpdateParams) MarshalJSON() (data []byte, err error) {
}

type AuthRuleListParams struct {
// Page (for pagination).
Page param.Field[int64] `query:"page"`
// A cursor representing an item's token before which a page of results should end.
// Used to retrieve the previous page of results before this item.
EndingBefore param.Field[string] `query:"ending_before"`
// Page size (for pagination).
PageSize param.Field[int64] `query:"page_size"`
// A cursor representing an item's token after which a page of results should
// begin. Used to retrieve the next page of results after this item.
StartingAfter param.Field[string] `query:"starting_after"`
}

// URLQuery serializes [AuthRuleListParams]'s query parameters as `url.Values`.
Expand Down
5 changes: 3 additions & 2 deletions authrule_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,9 @@ func TestAuthRuleListWithOptionalParams(t *testing.T) {
option.WithAPIKey("APIKey"),
)
_, err := client.AuthRules.List(context.TODO(), lithic.AuthRuleListParams{
Page: lithic.F(int64(0)),
PageSize: lithic.F(int64(1)),
EndingBefore: lithic.F("string"),
PageSize: lithic.F(int64(1)),
StartingAfter: lithic.F("string"),
})
if err != nil {
var apierr *lithic.Error
Expand Down
14 changes: 9 additions & 5 deletions card.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ func (r *CardService) Update(ctx context.Context, cardToken string, body CardUpd
}

// List cards.
func (r *CardService) List(ctx context.Context, query CardListParams, opts ...option.RequestOption) (res *shared.Page[Card], err error) {
func (r *CardService) List(ctx context.Context, query CardListParams, opts ...option.RequestOption) (res *shared.CursorPage[Card], err error) {
var raw *http.Response
opts = append(r.Options, opts...)
opts = append([]option.RequestOption{option.WithResponseInto(&raw)}, opts...)
Expand All @@ -85,8 +85,8 @@ func (r *CardService) List(ctx context.Context, query CardListParams, opts ...op
}

// List cards.
func (r *CardService) ListAutoPaging(ctx context.Context, query CardListParams, opts ...option.RequestOption) *shared.PageAutoPager[Card] {
return shared.NewPageAutoPager(r.List(ctx, query, opts...))
func (r *CardService) ListAutoPaging(ctx context.Context, query CardListParams, opts ...option.RequestOption) *shared.CursorPageAutoPager[Card] {
return shared.NewCursorPageAutoPager(r.List(ctx, query, opts...))
}

// Handling full card PANs and CVV codes requires that you comply with the Payment
Expand Down Expand Up @@ -720,10 +720,14 @@ type CardListParams struct {
// Date string in RFC 3339 format. Only entries created before the specified date
// will be included. UTC time zone.
End param.Field[time.Time] `query:"end" format:"date-time"`
// Page (for pagination).
Page param.Field[int64] `query:"page"`
// A cursor representing an item's token before which a page of results should end.
// Used to retrieve the previous page of results before this item.
EndingBefore param.Field[string] `query:"ending_before"`
// Page size (for pagination).
PageSize param.Field[int64] `query:"page_size"`
// A cursor representing an item's token after which a page of results should
// begin. Used to retrieve the next page of results after this item.
StartingAfter param.Field[string] `query:"starting_after"`
// Returns cards with the specified state.
State param.Field[CardListParamsState] `query:"state"`
}
Expand Down
13 changes: 7 additions & 6 deletions card_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,12 +136,13 @@ func TestCardListWithOptionalParams(t *testing.T) {
option.WithAPIKey("APIKey"),
)
_, err := client.Cards.List(context.TODO(), lithic.CardListParams{
AccountToken: lithic.F("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"),
Begin: lithic.F(time.Now()),
End: lithic.F(time.Now()),
Page: lithic.F(int64(0)),
PageSize: lithic.F(int64(1)),
State: lithic.F(lithic.CardListParamsStateOpen),
AccountToken: lithic.F("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"),
Begin: lithic.F(time.Now()),
End: lithic.F(time.Now()),
EndingBefore: lithic.F("string"),
PageSize: lithic.F(int64(1)),
StartingAfter: lithic.F("string"),
State: lithic.F(lithic.CardListParamsStateOpen),
})
if err != nil {
var apierr *lithic.Error
Expand Down
3 changes: 3 additions & 0 deletions eventsubscription.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,9 @@ func (r *EventSubscriptionService) Recover(ctx context.Context, eventSubscriptio

// Replays messages to the endpoint. Only messages that were created after `begin`
// will be sent. Messages that were previously sent to the endpoint are not resent.
// Message will be retried if endpoint responds with a non-2xx status code. See
// [Retry Schedule](https://docs.lithic.com/docs/events-api#retry-schedule) for
// details.
func (r *EventSubscriptionService) ReplayMissing(ctx context.Context, eventSubscriptionToken string, body EventSubscriptionReplayMissingParams, opts ...option.RequestOption) (err error) {
opts = append(r.Options[:], opts...)
opts = append([]option.RequestOption{option.WithHeader("Accept", "")}, opts...)
Expand Down
2 changes: 1 addition & 1 deletion internal/requestconfig/requestconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ func NewRequestConfig(ctx context.Context, method string, u string, body interfa
}
req.Header.Set("Idempotency-Key", "stainless-go-"+uuid.New().String())
req.Header.Set("Accept", "application/json")

req.Header.Set("X-Lithic-Pagination", "cursor")
for k, v := range getPlatformProperties() {
req.Header.Add(k, v)
}
Expand Down
101 changes: 0 additions & 101 deletions internal/shared/pagination.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
package shared

import (
"context"
"fmt"
"net/http"
"reflect"

Expand All @@ -13,105 +11,6 @@ import (
"github.com/lithic-com/lithic-go/option"
)

type Page[T any] struct {
Data []T `json:"data,required"`
// Page number.
Page int64 `json:"page,required"`
// Total number of entries.
TotalEntries int64 `json:"total_entries,required"`
// Total number of pages.
TotalPages int64 `json:"total_pages,required"`
JSON pageJSON
cfg *requestconfig.RequestConfig
res *http.Response
}

// pageJSON contains the JSON metadata for the struct [Page[T]]
type pageJSON struct {
Data apijson.Field
Page apijson.Field
TotalEntries apijson.Field
TotalPages apijson.Field
raw string
ExtraFields map[string]apijson.Field
}

func (r *Page[T]) UnmarshalJSON(data []byte) (err error) {
return apijson.UnmarshalRoot(data, r)
}

// NextPage returns the next page as defined by this pagination style. When there
// is no next page, this function will return a 'nil' for the page value, but will
// not return an error
func (r *Page[T]) GetNextPage() (res *Page[T], err error) {
currentPage := r.Page
if currentPage >= r.TotalPages {
return nil, nil
}
cfg := r.cfg.Clone(context.Background())
query := cfg.Request.URL.Query()
query.Set("page", fmt.Sprintf("%d", currentPage+1))
cfg.Request.URL.RawQuery = query.Encode()
var raw *http.Response
cfg.ResponseInto = &raw
cfg.ResponseBodyInto = &res
err = cfg.Execute()
if err != nil {
return nil, err
}
res.SetPageConfig(cfg, raw)
return res, nil
}

func (r *Page[T]) SetPageConfig(cfg *requestconfig.RequestConfig, res *http.Response) {
r.cfg = cfg
r.res = res
}

type PageAutoPager[T any] struct {
page *Page[T]
cur T
idx int
run int
err error
}

func NewPageAutoPager[T any](page *Page[T], err error) *PageAutoPager[T] {
return &PageAutoPager[T]{
page: page,
err: err,
}
}

func (r *PageAutoPager[T]) Next() bool {
if r.page == nil || len(r.page.Data) == 0 {
return false
}
if r.idx >= len(r.page.Data) {
r.idx = 0
r.page, r.err = r.page.GetNextPage()
if r.err != nil || r.page == nil || len(r.page.Data) == 0 {
return false
}
}
r.cur = r.page.Data[r.idx]
r.run += 1
r.idx += 1
return true
}

func (r *PageAutoPager[T]) Current() T {
return r.cur
}

func (r *PageAutoPager[T]) Err() error {
return r.err
}

func (r *PageAutoPager[T]) Index() int {
return r.run
}

type CursorPage[T any] struct {
Data []T `json:"data,required"`
HasMore bool `json:"has_more,required"`
Expand Down
14 changes: 9 additions & 5 deletions transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ func (r *TransactionService) Get(ctx context.Context, transactionToken string, o
}

// List card transactions.
func (r *TransactionService) List(ctx context.Context, query TransactionListParams, opts ...option.RequestOption) (res *shared.Page[Transaction], err error) {
func (r *TransactionService) List(ctx context.Context, query TransactionListParams, opts ...option.RequestOption) (res *shared.CursorPage[Transaction], err error) {
var raw *http.Response
opts = append(r.Options, opts...)
opts = append([]option.RequestOption{option.WithResponseInto(&raw)}, opts...)
Expand All @@ -62,8 +62,8 @@ func (r *TransactionService) List(ctx context.Context, query TransactionListPara
}

// List card transactions.
func (r *TransactionService) ListAutoPaging(ctx context.Context, query TransactionListParams, opts ...option.RequestOption) *shared.PageAutoPager[Transaction] {
return shared.NewPageAutoPager(r.List(ctx, query, opts...))
func (r *TransactionService) ListAutoPaging(ctx context.Context, query TransactionListParams, opts ...option.RequestOption) *shared.CursorPageAutoPager[Transaction] {
return shared.NewCursorPageAutoPager(r.List(ctx, query, opts...))
}

// Simulates an authorization request from the payment network as if it came from a
Expand Down Expand Up @@ -943,13 +943,17 @@ type TransactionListParams struct {
// Date string in RFC 3339 format. Only entries created before the specified date
// will be included. UTC time zone.
End param.Field[time.Time] `query:"end" format:"date-time"`
// Page (for pagination).
Page param.Field[int64] `query:"page"`
// A cursor representing an item's token before which a page of results should end.
// Used to retrieve the previous page of results before this item.
EndingBefore param.Field[string] `query:"ending_before"`
// Page size (for pagination).
PageSize param.Field[int64] `query:"page_size"`
// Filters for transactions using transaction result field. Can filter by
// `APPROVED`, and `DECLINED`.
Result param.Field[TransactionListParamsResult] `query:"result"`
// A cursor representing an item's token after which a page of results should
// begin. Used to retrieve the next page of results after this item.
StartingAfter param.Field[string] `query:"starting_after"`
}

// URLQuery serializes [TransactionListParams]'s query parameters as `url.Values`.
Expand Down
15 changes: 8 additions & 7 deletions transaction_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,14 @@ func TestTransactionListWithOptionalParams(t *testing.T) {
option.WithAPIKey("APIKey"),
)
_, err := client.Transactions.List(context.TODO(), lithic.TransactionListParams{
AccountToken: lithic.F("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"),
Begin: lithic.F(time.Now()),
CardToken: lithic.F("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"),
End: lithic.F(time.Now()),
Page: lithic.F(int64(0)),
PageSize: lithic.F(int64(1)),
Result: lithic.F(lithic.TransactionListParamsResultApproved),
AccountToken: lithic.F("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"),
Begin: lithic.F(time.Now()),
CardToken: lithic.F("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"),
End: lithic.F(time.Now()),
EndingBefore: lithic.F("string"),
PageSize: lithic.F(int64(1)),
Result: lithic.F(lithic.TransactionListParamsResultApproved),
StartingAfter: lithic.F("string"),
})
if err != nil {
var apierr *lithic.Error
Expand Down