client

package
v0.6.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 7, 2026 License: MIT Imports: 19 Imported by: 0

Documentation

Index

Constants

View Source
const (
	DefaultUserAgent = "go-api-sdk-apple/1.0.0"
	Version          = "1.0.0"
)

DefaultUserAgent is the default User-Agent header value for all requests.

View Source
const (
	DefaultBaseURL            = "https://appstoreconnect.apple.com"
	DefaultOAuthTokenEndpoint = "https://appleid.apple.com/auth/oauth2/v2/token"
	DefaultJWTAudience        = "appstoreconnect-v1"
)

The following constants are re-exported from the constants package so that existing code and tests in the client package can reference them without importing the constants package directly.

Variables

View Source
var (
	ErrNoNextPage      = fmt.Errorf("no next page available")
	ErrInvalidCursor   = fmt.Errorf("invalid pagination cursor")
	ErrAuthFailed      = fmt.Errorf("authentication failed")
	ErrRateLimited     = fmt.Errorf("rate limit exceeded")
	ErrInvalidResponse = fmt.Errorf("invalid response format")
)

Common error types

Functions

func HasNextPage

func HasNextPage(links *Links) bool

HasNextPage checks if there is a next page available.

func HasPrevPage

func HasPrevPage(links *Links) bool

HasPrevPage checks if there is a previous page available.

func LoadPrivateKeyFromEnv

func LoadPrivateKeyFromEnv() (any, error)

LoadPrivateKeyFromEnv loads a private key from the environment variable APPLE_PRIVATE_KEY_PATH

func LoadPrivateKeyFromFile

func LoadPrivateKeyFromFile(filePath string) (any, error)

LoadPrivateKeyFromFile loads a private key (RSA or ECDSA) from a PEM file

func ParsePrivateKey

func ParsePrivateKey(keyData []byte) (any, error)

ParsePrivateKey parses a private key (RSA or ECDSA) from PEM-encoded data

func ValidatePrivateKey

func ValidatePrivateKey(privateKey any) error

ValidatePrivateKey validates that the private key is suitable for JWT signing

Types

type APIError

type APIError struct {
	Description string
	Labels      []string
	Name        string
	StatusCode  int
}

APIError represents an error from the Apple Notary API. The Notary API returns errors as { "description": "...", "labels": [...], "name": "..." }.

func (*APIError) Error

func (e *APIError) Error() string

type APIKeyAuth

type APIKeyAuth struct {
	// contains filtered or unexported fields
}

APIKeyAuth implements simple API key authentication

func NewAPIKeyAuth

func NewAPIKeyAuth(apiKey, header string) *APIKeyAuth

NewAPIKeyAuth creates a new API key authentication provider

func (*APIKeyAuth) ApplyAuth

func (a *APIKeyAuth) ApplyAuth(req *resty.Request) error

ApplyAuth applies API key authentication to the request

type APIResponse

type APIResponse[T any] struct {
	Data  []T   `json:"data"`
	Meta  Meta  `json:"meta"`
	Links Links `json:"links"`
}

APIResponse represents the standard API response structure.

type AuthProvider

type AuthProvider interface {
	ApplyAuth(req *resty.Request) error
}

AuthProvider interface for different authentication methods

type Client

type Client interface {
	// NewRequest returns a RequestBuilder that the service layer uses to
	// construct a complete request — headers, body, query params, result
	// target — before executing it via Get/Post/Put/Patch/Delete/GetPaginated.
	// Auth, retry, and concurrency limiting are applied by the transport at
	// execution time.
	NewRequest(ctx context.Context) *RequestBuilder

	// QueryBuilder returns a new query parameter builder instance.
	// Use this to build complex query parameter sets before passing
	// them to SetQueryParams on the RequestBuilder.
	QueryBuilder() *QueryBuilder

	// GetLogger returns the configured zap logger instance.
	GetLogger() *zap.Logger
}

Client is the interface service implementations depend on. The Transport struct in this package satisfies this interface.

type ClientOption

type ClientOption func(*Transport) error

ClientOption is a function type for configuring the Transport.

func WithAudience

func WithAudience(audience string) ClientOption

WithAudience sets a custom JWT audience (default: "appstoreconnect-v1").

func WithAuth

func WithAuth(auth AuthProvider) ClientOption

WithAuth sets the authentication provider for the client.

func WithBaseURL

func WithBaseURL(urlStr string) ClientOption

WithBaseURL sets the base URL for API requests to a custom endpoint.

func WithClientCertificate

func WithClientCertificate(certFile, keyFile string) ClientOption

WithClientCertificate sets a client certificate for mutual TLS authentication.

func WithClientCertificateFromString

func WithClientCertificateFromString(certPEM, keyPEM string) ClientOption

WithClientCertificateFromString sets a client certificate from PEM-encoded strings.

func WithCustomAgent

func WithCustomAgent(customAgent string) ClientOption

WithCustomAgent allows appending a custom identifier to the default user agent. Format: "go-api-sdk-apple/1.0.0; <customAgent>"

func WithDebug

func WithDebug() ClientOption

WithDebug enables debug mode for the HTTP client.

func WithErrorHandler

func WithErrorHandler(handler *ErrorHandler) ClientOption

WithErrorHandler sets a custom error handler.

func WithGlobalHeader

func WithGlobalHeader(key, value string) ClientOption

WithGlobalHeader sets a global header that will be included in all requests.

func WithGlobalHeaders

func WithGlobalHeaders(headers map[string]string) ClientOption

WithGlobalHeaders sets multiple global headers at once.

func WithInsecureSkipVerify

func WithInsecureSkipVerify() ClientOption

WithInsecureSkipVerify disables TLS certificate verification (USE WITH CAUTION).

func WithLogger

func WithLogger(logger *zap.Logger) ClientOption

WithLogger can be used to configure a custom logger.

func WithMinTLSVersion

func WithMinTLSVersion(minVersion uint16) ClientOption

WithMinTLSVersion sets the minimum TLS version for connections.

func WithProxy

func WithProxy(proxyURL string) ClientOption

WithProxy sets an HTTP proxy for all requests.

func WithRetryCount

func WithRetryCount(retryCount int) ClientOption

WithRetryCount sets the maximum number of retries for failed requests.

func WithRetryMaxWaitTime

func WithRetryMaxWaitTime(maxWait time.Duration) ClientOption

WithRetryMaxWaitTime sets the maximum wait time between retry attempts.

func WithRetryWaitTime

func WithRetryWaitTime(retryWait time.Duration) ClientOption

WithRetryWaitTime sets the default wait time between retry attempts.

func WithRootCertificateFromString

func WithRootCertificateFromString(pemContent string) ClientOption

WithRootCertificateFromString adds a custom root CA certificate from PEM string.

func WithRootCertificates

func WithRootCertificates(pemFilePaths ...string) ClientOption

WithRootCertificates adds custom root CA certificates for server validation.

func WithTLSClientConfig

func WithTLSClientConfig(tlsConfig *tls.Config) ClientOption

WithTLSClientConfig sets custom TLS configuration.

func WithTimeout

func WithTimeout(timeout time.Duration) ClientOption

WithTimeout sets the timeout for all HTTP requests.

func WithTransport

func WithTransport(transport http.RoundTripper) ClientOption

WithTransport sets a custom HTTP transport (http.RoundTripper).

func WithUserAgent

func WithUserAgent(userAgent string) ClientOption

WithUserAgent sets a custom user agent string for all requests.

type ErrorHandler

type ErrorHandler struct {
	// contains filtered or unexported fields
}

ErrorHandler centralizes error handling for all API requests

func NewErrorHandler

func NewErrorHandler(logger *zap.Logger) *ErrorHandler

NewErrorHandler creates a new error handler

func (*ErrorHandler) HandleError

func (eh *ErrorHandler) HandleError(resp *resty.Response, errorResp *ErrorResponse) error

HandleError processes Notary API error responses and returns structured errors

type ErrorResponse

type ErrorResponse struct {
	Description string   `json:"description"`
	Labels      []string `json:"labels"`
	Name        string   `json:"name"`
}

ErrorResponse represents the error response structure returned by the Notary API

type JWTAuth

type JWTAuth struct {
	// contains filtered or unexported fields
}

JWTAuth implements direct JWT Bearer authentication for the Apple Notary API. The Notary API uses App Store Connect API keys — a signed JWT is used directly as a Bearer token without an OAuth token exchange step.

func NewJWTAuth

func NewJWTAuth(config JWTAuthConfig) *JWTAuth

NewJWTAuth creates a new direct JWT authentication provider

func (*JWTAuth) ApplyAuth

func (j *JWTAuth) ApplyAuth(req *resty.Request) error

ApplyAuth applies JWT Bearer authentication to the request

func (*JWTAuth) ForceRefresh

func (j *JWTAuth) ForceRefresh()

ForceRefresh forces a token refresh on the next request

type JWTAuthConfig

type JWTAuthConfig struct {
	KeyID      string
	IssuerID   string
	PrivateKey any    // Can be *rsa.PrivateKey or *ecdsa.PrivateKey
	Audience   string // Usually "appstoreconnect-v1"
}

JWTAuthConfig holds configuration for JWT authentication

type Links struct {
	Self  string `json:"self,omitempty"`
	First string `json:"first,omitempty"`
	Next  string `json:"next,omitempty"`
	Prev  string `json:"prev,omitempty"`
	Last  string `json:"last,omitempty"`
}

Links contains pagination navigation links matching Apple's API format.

type Meta

type Meta struct {
	Paging *Paging `json:"paging,omitempty"`
}

Meta contains pagination metadata matching Apple's API format.

type PaginationOptions

type PaginationOptions struct {
	Limit  int    `json:"limit,omitempty"`
	Cursor string `json:"cursor,omitempty"`
}

PaginationOptions represents common pagination parameters for Apple's API.

func (*PaginationOptions) AddToQueryBuilder

func (opts *PaginationOptions) AddToQueryBuilder(qb *QueryBuilder) *QueryBuilder

AddToQueryBuilder adds pagination options to a query builder.

type Paging

type Paging struct {
	Total      int    `json:"total,omitempty"`
	Limit      int    `json:"limit,omitempty"`
	NextCursor string `json:"nextCursor,omitempty"`
}

Paging contains pagination information matching Apple's API format.

type QueryBuilder

type QueryBuilder struct {
	// contains filtered or unexported fields
}

QueryBuilder provides a fluent interface for building query parameters.

func NewQueryBuilder

func NewQueryBuilder() *QueryBuilder

NewQueryBuilder creates a new query builder.

func (*QueryBuilder) AddBool

func (qb *QueryBuilder) AddBool(key string, value bool) *QueryBuilder

AddBool adds a boolean parameter.

func (*QueryBuilder) AddCustom

func (qb *QueryBuilder) AddCustom(key, value string) *QueryBuilder

AddCustom adds a custom parameter with any value.

func (*QueryBuilder) AddIfNotEmpty

func (qb *QueryBuilder) AddIfNotEmpty(key, value string) *QueryBuilder

AddIfNotEmpty adds a parameter only if the value is not empty.

func (*QueryBuilder) AddIfTrue

func (qb *QueryBuilder) AddIfTrue(condition bool, key, value string) *QueryBuilder

AddIfTrue adds a parameter only if the condition is true.

func (*QueryBuilder) AddInt

func (qb *QueryBuilder) AddInt(key string, value int) *QueryBuilder

AddInt adds an integer parameter if the value is greater than 0.

func (*QueryBuilder) AddInt64

func (qb *QueryBuilder) AddInt64(key string, value int64) *QueryBuilder

AddInt64 adds an int64 parameter if the value is greater than 0.

func (*QueryBuilder) AddIntSlice

func (qb *QueryBuilder) AddIntSlice(key string, values []int) *QueryBuilder

AddIntSlice adds an integer slice parameter as comma-separated values.

func (*QueryBuilder) AddString

func (qb *QueryBuilder) AddString(key, value string) *QueryBuilder

AddString adds a string parameter if the value is not empty.

func (*QueryBuilder) AddStringSlice

func (qb *QueryBuilder) AddStringSlice(key string, values []string) *QueryBuilder

AddStringSlice adds a string slice parameter as comma-separated values.

func (*QueryBuilder) AddTime

func (qb *QueryBuilder) AddTime(key string, value time.Time) *QueryBuilder

AddTime adds a time parameter in RFC3339 format if the time is not zero.

func (*QueryBuilder) Build

func (qb *QueryBuilder) Build() map[string]string

Build returns the final map of query parameters.

func (*QueryBuilder) BuildString

func (qb *QueryBuilder) BuildString() string

BuildString returns the query parameters as a URL-encoded string.

func (*QueryBuilder) Clear

func (qb *QueryBuilder) Clear() *QueryBuilder

Clear removes all parameters.

func (*QueryBuilder) Count

func (qb *QueryBuilder) Count() int

Count returns the number of parameters.

func (*QueryBuilder) Get

func (qb *QueryBuilder) Get(key string) string

Get retrieves a parameter value.

func (*QueryBuilder) Has

func (qb *QueryBuilder) Has(key string) bool

Has checks if a parameter exists.

func (*QueryBuilder) IsEmpty

func (qb *QueryBuilder) IsEmpty() bool

IsEmpty returns true if no parameters are set.

func (*QueryBuilder) Merge

func (qb *QueryBuilder) Merge(other map[string]string) *QueryBuilder

Merge merges parameters from another query builder or map.

func (*QueryBuilder) Remove

func (qb *QueryBuilder) Remove(key string) *QueryBuilder

Remove removes a parameter.

type RequestBuilder

type RequestBuilder struct {
	// contains filtered or unexported fields
}

RequestBuilder constructs a single API request. The service layer owns the full request shape — headers, body, query params, result target — before handing the completed request to the executor (transport) which handles auth, retry, and throttling.

Usage:

resp, err := s.client.NewRequest(ctx).
    SetHeader("Accept", constants.ApplicationJSON).
    SetHeader("Content-Type", constants.ApplicationJSON).
    SetBody(payload).
    SetResult(&result).
    Post(constants.EndpointSubmissions)

func NewMockRequestBuilder

func NewMockRequestBuilder(ctx context.Context, fn func(method, path string, result any) (*resty.Response, error)) *RequestBuilder

NewMockRequestBuilder returns a RequestBuilder suitable for unit tests. The fn callback receives the HTTP method, path, and result pointer and returns a pre-programmed response.

func NewMockRequestBuilderWithQueryCapture

func NewMockRequestBuilderWithQueryCapture(ctx context.Context, fn func(method, path string, result any) (*resty.Response, error), queryStore *map[string]string) *RequestBuilder

NewMockRequestBuilderWithQueryCapture returns a RequestBuilder suitable for unit tests that also captures query parameters into the provided map pointer.

func (*RequestBuilder) Delete

func (b *RequestBuilder) Delete(path string) (*resty.Response, error)

Delete executes the request as DELETE against path.

func (*RequestBuilder) Get

func (b *RequestBuilder) Get(path string) (*resty.Response, error)

Get executes the request as GET against path.

func (*RequestBuilder) GetBytes

func (b *RequestBuilder) GetBytes(path string) (*resty.Response, []byte, error)

GetBytes executes a GET request and returns raw response bytes without JSON unmarshaling. Use for binary responses such as files or exports.

func (*RequestBuilder) GetPaginated

func (b *RequestBuilder) GetPaginated(path string, mergePage func([]byte) error) (*resty.Response, error)

GetPaginated transparently fetches all pages of a cursor-based paginated endpoint, calling mergePage with each page's raw JSON response.

func (*RequestBuilder) Patch

func (b *RequestBuilder) Patch(path string) (*resty.Response, error)

Patch executes the request as PATCH against path.

func (*RequestBuilder) Post

func (b *RequestBuilder) Post(path string) (*resty.Response, error)

Post executes the request as POST against path.

func (*RequestBuilder) Put

func (b *RequestBuilder) Put(path string) (*resty.Response, error)

Put executes the request as PUT against path.

func (*RequestBuilder) SetBody

func (b *RequestBuilder) SetBody(body any) *RequestBuilder

SetBody sets the request body. Nil is ignored.

func (*RequestBuilder) SetHeader

func (b *RequestBuilder) SetHeader(key, value string) *RequestBuilder

SetHeader sets a request-level header. Empty values are ignored.

func (*RequestBuilder) SetMultipartFile

func (b *RequestBuilder) SetMultipartFile(fileField, fileName string, fileReader io.Reader, fileSize int64) *RequestBuilder

SetMultipartFile configures the request for a multipart file upload. Content-Type is managed automatically by resty.

func (*RequestBuilder) SetMultipartFormData

func (b *RequestBuilder) SetMultipartFormData(formFields map[string]string) *RequestBuilder

SetMultipartFormData adds additional form fields to a multipart request.

func (*RequestBuilder) SetQueryParam

func (b *RequestBuilder) SetQueryParam(key, value string) *RequestBuilder

SetQueryParam adds a URL query parameter. Empty values are ignored.

func (*RequestBuilder) SetQueryParams

func (b *RequestBuilder) SetQueryParams(params map[string]string) *RequestBuilder

SetQueryParams adds multiple URL query parameters in bulk. Empty values are ignored.

func (*RequestBuilder) SetResult

func (b *RequestBuilder) SetResult(result any) *RequestBuilder

SetResult sets the target for JSON unmarshaling of a successful response.

type Transport

type Transport struct {
	// contains filtered or unexported fields
}

Transport represents the main Apple Notary API transport layer.

func NewTransport

func NewTransport(keyID, issuerID string, privateKey any, options ...ClientOption) (*Transport, error)

NewTransport creates a new HTTP transport for the Apple Notary API. This is an internal function - users should use notary.NewClient() instead.

func NewTransportFromEnv

func NewTransportFromEnv(options ...ClientOption) (*Transport, error)

NewTransportFromEnv creates a transport using environment variables. Requires APPLE_KEY_ID and APPLE_ISSUER_ID plus exactly one of:

  • APPLE_PRIVATE_KEY_PEM — PEM-encoded private key supplied inline
  • APPLE_PRIVATE_KEY_PATH — path to a PEM private key file

func NewTransportFromFile

func NewTransportFromFile(keyID, issuerID, privateKeyPath string, options ...ClientOption) (*Transport, error)

NewTransportFromFile creates a transport using credentials from files.

func (*Transport) Close

func (t *Transport) Close() error

Close closes the HTTP client and cleans up resources.

func (*Transport) GetHTTPClient

func (t *Transport) GetHTTPClient() *resty.Client

GetHTTPClient returns the underlying HTTP client for testing purposes.

func (*Transport) GetLogger

func (t *Transport) GetLogger() *zap.Logger

GetLogger returns the configured logger.

func (*Transport) NewRequest

func (t *Transport) NewRequest(ctx context.Context) *RequestBuilder

NewRequest returns a new RequestBuilder for constructing API requests.

func (*Transport) QueryBuilder

func (t *Transport) QueryBuilder() *QueryBuilder

QueryBuilder returns a new query builder instance.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL