diff --git a/access_codes.go b/access_codes.go index 6ce5abb..62b1fec 100644 --- a/access_codes.go +++ b/access_codes.go @@ -9,67 +9,67 @@ import ( ) type AccessCodesCreateRequest struct { - DeviceId string `json:"device_id"` - Name *string `json:"name,omitempty"` - StartsAt *string `json:"starts_at,omitempty"` - EndsAt *string `json:"ends_at,omitempty"` - Code *string `json:"code,omitempty"` - Sync *bool `json:"sync,omitempty"` - AttemptForOfflineDevice *bool `json:"attempt_for_offline_device,omitempty"` - CommonCodeKey *string `json:"common_code_key,omitempty"` - PreferNativeScheduling *bool `json:"prefer_native_scheduling,omitempty"` - UseBackupAccessCodePool *bool `json:"use_backup_access_code_pool,omitempty"` - AllowExternalModification *bool `json:"allow_external_modification,omitempty"` - IsExternalModificationAllowed *bool `json:"is_external_modification_allowed,omitempty"` - UseOfflineAccessCode *bool `json:"use_offline_access_code,omitempty"` - IsOfflineAccessCode *bool `json:"is_offline_access_code,omitempty"` - IsOneTimeUse *bool `json:"is_one_time_use,omitempty"` - MaxTimeRounding *MaxTimeRounding `json:"max_time_rounding,omitempty"` + DeviceId string `json:"device_id" url:"device_id"` + Name *string `json:"name,omitempty" url:"name,omitempty"` + StartsAt *string `json:"starts_at,omitempty" url:"starts_at,omitempty"` + EndsAt *string `json:"ends_at,omitempty" url:"ends_at,omitempty"` + Code *string `json:"code,omitempty" url:"code,omitempty"` + Sync *bool `json:"sync,omitempty" url:"sync,omitempty"` + AttemptForOfflineDevice *bool `json:"attempt_for_offline_device,omitempty" url:"attempt_for_offline_device,omitempty"` + CommonCodeKey *string `json:"common_code_key,omitempty" url:"common_code_key,omitempty"` + PreferNativeScheduling *bool `json:"prefer_native_scheduling,omitempty" url:"prefer_native_scheduling,omitempty"` + UseBackupAccessCodePool *bool `json:"use_backup_access_code_pool,omitempty" url:"use_backup_access_code_pool,omitempty"` + AllowExternalModification *bool `json:"allow_external_modification,omitempty" url:"allow_external_modification,omitempty"` + IsExternalModificationAllowed *bool `json:"is_external_modification_allowed,omitempty" url:"is_external_modification_allowed,omitempty"` + UseOfflineAccessCode *bool `json:"use_offline_access_code,omitempty" url:"use_offline_access_code,omitempty"` + IsOfflineAccessCode *bool `json:"is_offline_access_code,omitempty" url:"is_offline_access_code,omitempty"` + IsOneTimeUse *bool `json:"is_one_time_use,omitempty" url:"is_one_time_use,omitempty"` + MaxTimeRounding *MaxTimeRounding `json:"max_time_rounding,omitempty" url:"max_time_rounding,omitempty"` } type AccessCodesCreateMultipleRequest struct { - DeviceIds []string `json:"device_ids,omitempty"` - BehaviorWhenCodeCannotBeShared *AccessCodesCreateMultipleRequestBehaviorWhenCodeCannotBeShared `json:"behavior_when_code_cannot_be_shared,omitempty"` - PreferredCodeLength *float64 `json:"preferred_code_length,omitempty"` - Name *string `json:"name,omitempty"` - StartsAt *string `json:"starts_at,omitempty"` - EndsAt *string `json:"ends_at,omitempty"` - Code *string `json:"code,omitempty"` - AttemptForOfflineDevice *bool `json:"attempt_for_offline_device,omitempty"` - PreferNativeScheduling *bool `json:"prefer_native_scheduling,omitempty"` - UseBackupAccessCodePool *bool `json:"use_backup_access_code_pool,omitempty"` - AllowExternalModification *bool `json:"allow_external_modification,omitempty"` - IsExternalModificationAllowed *bool `json:"is_external_modification_allowed,omitempty"` - UseOfflineAccessCode *bool `json:"use_offline_access_code,omitempty"` - IsOfflineAccessCode *bool `json:"is_offline_access_code,omitempty"` - IsOneTimeUse *bool `json:"is_one_time_use,omitempty"` - MaxTimeRounding *MaxTimeRounding `json:"max_time_rounding,omitempty"` + DeviceIds []string `json:"device_ids,omitempty" url:"device_ids,omitempty"` + BehaviorWhenCodeCannotBeShared *AccessCodesCreateMultipleRequestBehaviorWhenCodeCannotBeShared `json:"behavior_when_code_cannot_be_shared,omitempty" url:"behavior_when_code_cannot_be_shared,omitempty"` + PreferredCodeLength *float64 `json:"preferred_code_length,omitempty" url:"preferred_code_length,omitempty"` + Name *string `json:"name,omitempty" url:"name,omitempty"` + StartsAt *string `json:"starts_at,omitempty" url:"starts_at,omitempty"` + EndsAt *string `json:"ends_at,omitempty" url:"ends_at,omitempty"` + Code *string `json:"code,omitempty" url:"code,omitempty"` + AttemptForOfflineDevice *bool `json:"attempt_for_offline_device,omitempty" url:"attempt_for_offline_device,omitempty"` + PreferNativeScheduling *bool `json:"prefer_native_scheduling,omitempty" url:"prefer_native_scheduling,omitempty"` + UseBackupAccessCodePool *bool `json:"use_backup_access_code_pool,omitempty" url:"use_backup_access_code_pool,omitempty"` + AllowExternalModification *bool `json:"allow_external_modification,omitempty" url:"allow_external_modification,omitempty"` + IsExternalModificationAllowed *bool `json:"is_external_modification_allowed,omitempty" url:"is_external_modification_allowed,omitempty"` + UseOfflineAccessCode *bool `json:"use_offline_access_code,omitempty" url:"use_offline_access_code,omitempty"` + IsOfflineAccessCode *bool `json:"is_offline_access_code,omitempty" url:"is_offline_access_code,omitempty"` + IsOneTimeUse *bool `json:"is_one_time_use,omitempty" url:"is_one_time_use,omitempty"` + MaxTimeRounding *MaxTimeRounding `json:"max_time_rounding,omitempty" url:"max_time_rounding,omitempty"` } type AccessCodesDeleteRequest struct { - DeviceId *string `json:"device_id,omitempty"` - AccessCodeId string `json:"access_code_id"` - Sync *bool `json:"sync,omitempty"` + DeviceId *string `json:"device_id,omitempty" url:"device_id,omitempty"` + AccessCodeId string `json:"access_code_id" url:"access_code_id"` + Sync *bool `json:"sync,omitempty" url:"sync,omitempty"` } type AccessCodesGenerateCodeRequest struct { - DeviceId string `json:"device_id"` + DeviceId string `json:"device_id" url:"device_id"` } type AccessCodesGetRequest struct { - DeviceId *string `json:"device_id,omitempty"` - AccessCodeId *string `json:"access_code_id,omitempty"` - Code *string `json:"code,omitempty"` + DeviceId *string `json:"device_id,omitempty" url:"device_id,omitempty"` + AccessCodeId *string `json:"access_code_id,omitempty" url:"access_code_id,omitempty"` + Code *string `json:"code,omitempty" url:"code,omitempty"` } type AccessCodesListRequest struct { - DeviceId string `json:"device_id"` - AccessCodeIds []string `json:"access_code_ids,omitempty"` - UserIdentifierKey *string `json:"user_identifier_key,omitempty"` + DeviceId string `json:"device_id" url:"device_id"` + AccessCodeIds []string `json:"access_code_ids,omitempty" url:"access_code_ids,omitempty"` + UserIdentifierKey *string `json:"user_identifier_key,omitempty" url:"user_identifier_key,omitempty"` } type AccessCodesPullBackupAccessCodeRequest struct { - AccessCodeId string `json:"access_code_id"` + AccessCodeId string `json:"access_code_id" url:"access_code_id"` } type AccessCodesCreateMultipleRequestBehaviorWhenCodeCannotBeShared string @@ -95,8 +95,8 @@ func (a AccessCodesCreateMultipleRequestBehaviorWhenCodeCannotBeShared) Ptr() *A } type AccessCodesCreateMultipleResponse struct { - AccessCodes []*AccessCode `json:"access_codes,omitempty"` - Ok bool `json:"ok"` + AccessCodes []*AccessCode `json:"access_codes,omitempty" url:"access_codes,omitempty"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -125,9 +125,9 @@ func (a *AccessCodesCreateMultipleResponse) String() string { } type AccessCodesCreateResponse struct { - ActionAttempt *ActionAttempt `json:"action_attempt,omitempty"` - AccessCode *AccessCode `json:"access_code,omitempty"` - Ok bool `json:"ok"` + ActionAttempt *ActionAttempt `json:"action_attempt,omitempty" url:"action_attempt,omitempty"` + AccessCode *AccessCode `json:"access_code,omitempty" url:"access_code,omitempty"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -156,8 +156,8 @@ func (a *AccessCodesCreateResponse) String() string { } type AccessCodesDeleteResponse struct { - ActionAttempt *ActionAttempt `json:"action_attempt,omitempty"` - Ok bool `json:"ok"` + ActionAttempt *ActionAttempt `json:"action_attempt,omitempty" url:"action_attempt,omitempty"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -186,8 +186,8 @@ func (a *AccessCodesDeleteResponse) String() string { } type AccessCodesGenerateCodeResponse struct { - GeneratedCode *AccessCode `json:"generated_code,omitempty"` - Ok bool `json:"ok"` + GeneratedCode *AccessCode `json:"generated_code,omitempty" url:"generated_code,omitempty"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -216,8 +216,8 @@ func (a *AccessCodesGenerateCodeResponse) String() string { } type AccessCodesGetResponse struct { - AccessCode *AccessCode `json:"access_code,omitempty"` - Ok bool `json:"ok"` + AccessCode *AccessCode `json:"access_code,omitempty" url:"access_code,omitempty"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -246,8 +246,8 @@ func (a *AccessCodesGetResponse) String() string { } type AccessCodesListResponse struct { - AccessCodes []*AccessCode `json:"access_codes,omitempty"` - Ok bool `json:"ok"` + AccessCodes []*AccessCode `json:"access_codes,omitempty" url:"access_codes,omitempty"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -276,8 +276,8 @@ func (a *AccessCodesListResponse) String() string { } type AccessCodesPullBackupAccessCodeResponse struct { - BackupAccessCode *AccessCode `json:"backup_access_code,omitempty"` - Ok bool `json:"ok"` + BackupAccessCode *AccessCode `json:"backup_access_code,omitempty" url:"backup_access_code,omitempty"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -328,8 +328,8 @@ func (a AccessCodesUpdateRequestType) Ptr() *AccessCodesUpdateRequestType { } type AccessCodesUpdateResponse struct { - ActionAttempt *ActionAttempt `json:"action_attempt,omitempty"` - Ok bool `json:"ok"` + ActionAttempt *ActionAttempt `json:"action_attempt,omitempty" url:"action_attempt,omitempty"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -358,22 +358,22 @@ func (a *AccessCodesUpdateResponse) String() string { } type AccessCodesUpdateRequest struct { - Name *string `json:"name,omitempty"` - StartsAt *string `json:"starts_at,omitempty"` - EndsAt *string `json:"ends_at,omitempty"` - Code *string `json:"code,omitempty"` - Sync *bool `json:"sync,omitempty"` - AttemptForOfflineDevice *bool `json:"attempt_for_offline_device,omitempty"` - PreferNativeScheduling *bool `json:"prefer_native_scheduling,omitempty"` - UseBackupAccessCodePool *bool `json:"use_backup_access_code_pool,omitempty"` - AllowExternalModification *bool `json:"allow_external_modification,omitempty"` - IsExternalModificationAllowed *bool `json:"is_external_modification_allowed,omitempty"` - UseOfflineAccessCode *bool `json:"use_offline_access_code,omitempty"` - IsOfflineAccessCode *bool `json:"is_offline_access_code,omitempty"` - IsOneTimeUse *bool `json:"is_one_time_use,omitempty"` - MaxTimeRounding *MaxTimeRounding `json:"max_time_rounding,omitempty"` - AccessCodeId string `json:"access_code_id"` - DeviceId *string `json:"device_id,omitempty"` - Type *AccessCodesUpdateRequestType `json:"type,omitempty"` - IsManaged *bool `json:"is_managed,omitempty"` + Name *string `json:"name,omitempty" url:"name,omitempty"` + StartsAt *string `json:"starts_at,omitempty" url:"starts_at,omitempty"` + EndsAt *string `json:"ends_at,omitempty" url:"ends_at,omitempty"` + Code *string `json:"code,omitempty" url:"code,omitempty"` + Sync *bool `json:"sync,omitempty" url:"sync,omitempty"` + AttemptForOfflineDevice *bool `json:"attempt_for_offline_device,omitempty" url:"attempt_for_offline_device,omitempty"` + PreferNativeScheduling *bool `json:"prefer_native_scheduling,omitempty" url:"prefer_native_scheduling,omitempty"` + UseBackupAccessCodePool *bool `json:"use_backup_access_code_pool,omitempty" url:"use_backup_access_code_pool,omitempty"` + AllowExternalModification *bool `json:"allow_external_modification,omitempty" url:"allow_external_modification,omitempty"` + IsExternalModificationAllowed *bool `json:"is_external_modification_allowed,omitempty" url:"is_external_modification_allowed,omitempty"` + UseOfflineAccessCode *bool `json:"use_offline_access_code,omitempty" url:"use_offline_access_code,omitempty"` + IsOfflineAccessCode *bool `json:"is_offline_access_code,omitempty" url:"is_offline_access_code,omitempty"` + IsOneTimeUse *bool `json:"is_one_time_use,omitempty" url:"is_one_time_use,omitempty"` + MaxTimeRounding *MaxTimeRounding `json:"max_time_rounding,omitempty" url:"max_time_rounding,omitempty"` + AccessCodeId string `json:"access_code_id" url:"access_code_id"` + DeviceId *string `json:"device_id,omitempty" url:"device_id,omitempty"` + Type *AccessCodesUpdateRequestType `json:"type,omitempty" url:"type,omitempty"` + IsManaged *bool `json:"is_managed,omitempty" url:"is_managed,omitempty"` } diff --git a/accesscodes/client/client.go b/accesscodes/client/client.go index e6bc886..bc48843 100644 --- a/accesscodes/client/client.go +++ b/accesscodes/client/client.go @@ -11,6 +11,7 @@ import ( simulate "github.com/seamapi/go/accesscodes/simulate" unmanaged "github.com/seamapi/go/accesscodes/unmanaged" core "github.com/seamapi/go/core" + option "github.com/seamapi/go/option" io "io" http "net/http" ) @@ -24,27 +25,40 @@ type Client struct { Unmanaged *unmanaged.Client } -func NewClient(opts ...core.ClientOption) *Client { - options := core.NewClientOptions() - for _, opt := range opts { - opt(options) - } +func NewClient(opts ...option.RequestOption) *Client { + options := core.NewRequestOptions(opts...) return &Client{ - baseURL: options.BaseURL, - caller: core.NewCaller(options.HTTPClient), + baseURL: options.BaseURL, + caller: core.NewCaller( + &core.CallerParams{ + Client: options.HTTPClient, + MaxAttempts: options.MaxAttempts, + }, + ), header: options.ToHeader(), Simulate: simulate.NewClient(opts...), Unmanaged: unmanaged.NewClient(opts...), } } -func (c *Client) Create(ctx context.Context, request *seamapigo.AccessCodesCreateRequest) (*seamapigo.AccessCode, error) { +func (c *Client) Create( + ctx context.Context, + request *seamapigo.AccessCodesCreateRequest, + opts ...option.RequestOption, +) (*seamapigo.AccessCode, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "access_codes/create" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -77,7 +91,9 @@ func (c *Client) Create(ctx context.Context, request *seamapigo.AccessCodesCreat &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -88,13 +104,24 @@ func (c *Client) Create(ctx context.Context, request *seamapigo.AccessCodesCreat return response.AccessCode, nil } -func (c *Client) CreateMultiple(ctx context.Context, request *seamapigo.AccessCodesCreateMultipleRequest) ([]*seamapigo.AccessCode, error) { +func (c *Client) CreateMultiple( + ctx context.Context, + request *seamapigo.AccessCodesCreateMultipleRequest, + opts ...option.RequestOption, +) ([]*seamapigo.AccessCode, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "access_codes/create_multiple" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -127,7 +154,9 @@ func (c *Client) CreateMultiple(ctx context.Context, request *seamapigo.AccessCo &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -138,13 +167,24 @@ func (c *Client) CreateMultiple(ctx context.Context, request *seamapigo.AccessCo return response.AccessCodes, nil } -func (c *Client) Delete(ctx context.Context, request *seamapigo.AccessCodesDeleteRequest) (*seamapigo.ActionAttempt, error) { +func (c *Client) Delete( + ctx context.Context, + request *seamapigo.AccessCodesDeleteRequest, + opts ...option.RequestOption, +) (*seamapigo.ActionAttempt, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "access_codes/delete" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -177,7 +217,9 @@ func (c *Client) Delete(ctx context.Context, request *seamapigo.AccessCodesDelet &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -188,13 +230,24 @@ func (c *Client) Delete(ctx context.Context, request *seamapigo.AccessCodesDelet return response.ActionAttempt, nil } -func (c *Client) GenerateCode(ctx context.Context, request *seamapigo.AccessCodesGenerateCodeRequest) (*seamapigo.AccessCode, error) { +func (c *Client) GenerateCode( + ctx context.Context, + request *seamapigo.AccessCodesGenerateCodeRequest, + opts ...option.RequestOption, +) (*seamapigo.AccessCode, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "access_codes/generate_code" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -227,7 +280,9 @@ func (c *Client) GenerateCode(ctx context.Context, request *seamapigo.AccessCode &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -238,13 +293,24 @@ func (c *Client) GenerateCode(ctx context.Context, request *seamapigo.AccessCode return response.GeneratedCode, nil } -func (c *Client) Get(ctx context.Context, request *seamapigo.AccessCodesGetRequest) (*seamapigo.AccessCode, error) { +func (c *Client) Get( + ctx context.Context, + request *seamapigo.AccessCodesGetRequest, + opts ...option.RequestOption, +) (*seamapigo.AccessCode, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "access_codes/get" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -277,7 +343,9 @@ func (c *Client) Get(ctx context.Context, request *seamapigo.AccessCodesGetReque &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -288,13 +356,24 @@ func (c *Client) Get(ctx context.Context, request *seamapigo.AccessCodesGetReque return response.AccessCode, nil } -func (c *Client) List(ctx context.Context, request *seamapigo.AccessCodesListRequest) ([]*seamapigo.AccessCode, error) { +func (c *Client) List( + ctx context.Context, + request *seamapigo.AccessCodesListRequest, + opts ...option.RequestOption, +) ([]*seamapigo.AccessCode, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "access_codes/list" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -327,7 +406,9 @@ func (c *Client) List(ctx context.Context, request *seamapigo.AccessCodesListReq &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -338,13 +419,24 @@ func (c *Client) List(ctx context.Context, request *seamapigo.AccessCodesListReq return response.AccessCodes, nil } -func (c *Client) PullBackupAccessCode(ctx context.Context, request *seamapigo.AccessCodesPullBackupAccessCodeRequest) (*seamapigo.AccessCode, error) { +func (c *Client) PullBackupAccessCode( + ctx context.Context, + request *seamapigo.AccessCodesPullBackupAccessCodeRequest, + opts ...option.RequestOption, +) (*seamapigo.AccessCode, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "access_codes/pull_backup_access_code" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -377,7 +469,9 @@ func (c *Client) PullBackupAccessCode(ctx context.Context, request *seamapigo.Ac &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -388,13 +482,24 @@ func (c *Client) PullBackupAccessCode(ctx context.Context, request *seamapigo.Ac return response.BackupAccessCode, nil } -func (c *Client) Update(ctx context.Context, request *seamapigo.AccessCodesUpdateRequest) (*seamapigo.ActionAttempt, error) { +func (c *Client) Update( + ctx context.Context, + request *seamapigo.AccessCodesUpdateRequest, + opts ...option.RequestOption, +) (*seamapigo.ActionAttempt, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "access_codes/update" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -427,7 +532,9 @@ func (c *Client) Update(ctx context.Context, request *seamapigo.AccessCodesUpdat &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, diff --git a/accesscodes/simulate.go b/accesscodes/simulate.go index df1fe6a..36cfdb8 100644 --- a/accesscodes/simulate.go +++ b/accesscodes/simulate.go @@ -10,14 +10,14 @@ import ( ) type SimulateCreateUnmanagedAccessCodeRequest struct { - DeviceId string `json:"device_id"` - Name string `json:"name"` - Code string `json:"code"` + DeviceId string `json:"device_id" url:"device_id"` + Name string `json:"name" url:"name"` + Code string `json:"code" url:"code"` } type SimulateCreateUnmanagedAccessCodeResponse struct { - AccessCode *seamapigo.UnmanagedAccessCode `json:"access_code,omitempty"` - Ok bool `json:"ok"` + AccessCode *seamapigo.UnmanagedAccessCode `json:"access_code,omitempty" url:"access_code,omitempty"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } diff --git a/accesscodes/simulate/client.go b/accesscodes/simulate/client.go index 17113be..1f63afc 100644 --- a/accesscodes/simulate/client.go +++ b/accesscodes/simulate/client.go @@ -10,6 +10,7 @@ import ( seamapigo "github.com/seamapi/go" accesscodes "github.com/seamapi/go/accesscodes" core "github.com/seamapi/go/core" + option "github.com/seamapi/go/option" io "io" http "net/http" ) @@ -20,25 +21,38 @@ type Client struct { header http.Header } -func NewClient(opts ...core.ClientOption) *Client { - options := core.NewClientOptions() - for _, opt := range opts { - opt(options) - } +func NewClient(opts ...option.RequestOption) *Client { + options := core.NewRequestOptions(opts...) return &Client{ baseURL: options.BaseURL, - caller: core.NewCaller(options.HTTPClient), - header: options.ToHeader(), + caller: core.NewCaller( + &core.CallerParams{ + Client: options.HTTPClient, + MaxAttempts: options.MaxAttempts, + }, + ), + header: options.ToHeader(), } } -func (c *Client) CreateUnmanagedAccessCode(ctx context.Context, request *accesscodes.SimulateCreateUnmanagedAccessCodeRequest) (*seamapigo.UnmanagedAccessCode, error) { +func (c *Client) CreateUnmanagedAccessCode( + ctx context.Context, + request *accesscodes.SimulateCreateUnmanagedAccessCodeRequest, + opts ...option.RequestOption, +) (*seamapigo.UnmanagedAccessCode, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "access_codes/simulate/create_unmanaged_access_code" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -71,7 +85,9 @@ func (c *Client) CreateUnmanagedAccessCode(ctx context.Context, request *accessc &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, diff --git a/accesscodes/unmanaged.go b/accesscodes/unmanaged.go index 051b063..d77e623 100644 --- a/accesscodes/unmanaged.go +++ b/accesscodes/unmanaged.go @@ -10,31 +10,31 @@ import ( ) type UnmanagedConvertToManagedRequest struct { - AccessCodeId string `json:"access_code_id"` - IsExternalModificationAllowed *bool `json:"is_external_modification_allowed,omitempty"` - AllowExternalModification *bool `json:"allow_external_modification,omitempty"` - Force *bool `json:"force,omitempty"` - Sync *bool `json:"sync,omitempty"` + AccessCodeId string `json:"access_code_id" url:"access_code_id"` + IsExternalModificationAllowed *bool `json:"is_external_modification_allowed,omitempty" url:"is_external_modification_allowed,omitempty"` + AllowExternalModification *bool `json:"allow_external_modification,omitempty" url:"allow_external_modification,omitempty"` + Force *bool `json:"force,omitempty" url:"force,omitempty"` + Sync *bool `json:"sync,omitempty" url:"sync,omitempty"` } type UnmanagedDeleteRequest struct { - AccessCodeId string `json:"access_code_id"` - Sync *bool `json:"sync,omitempty"` + AccessCodeId string `json:"access_code_id" url:"access_code_id"` + Sync *bool `json:"sync,omitempty" url:"sync,omitempty"` } type UnmanagedGetRequest struct { - DeviceId *string `json:"device_id,omitempty"` - AccessCodeId *string `json:"access_code_id,omitempty"` - Code *string `json:"code,omitempty"` + DeviceId *string `json:"device_id,omitempty" url:"device_id,omitempty"` + AccessCodeId *string `json:"access_code_id,omitempty" url:"access_code_id,omitempty"` + Code *string `json:"code,omitempty" url:"code,omitempty"` } type UnmanagedListRequest struct { - DeviceId string `json:"device_id"` - UserIdentifierKey *string `json:"user_identifier_key,omitempty"` + DeviceId string `json:"device_id" url:"device_id"` + UserIdentifierKey *string `json:"user_identifier_key,omitempty" url:"user_identifier_key,omitempty"` } type UnmanagedConvertToManagedResponse struct { - Ok bool `json:"ok"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -63,8 +63,8 @@ func (u *UnmanagedConvertToManagedResponse) String() string { } type UnmanagedDeleteResponse struct { - ActionAttempt *seamapigo.ActionAttempt `json:"action_attempt,omitempty"` - Ok bool `json:"ok"` + ActionAttempt *seamapigo.ActionAttempt `json:"action_attempt,omitempty" url:"action_attempt,omitempty"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -93,8 +93,8 @@ func (u *UnmanagedDeleteResponse) String() string { } type UnmanagedGetResponse struct { - AccessCode *seamapigo.UnmanagedAccessCode `json:"access_code,omitempty"` - Ok bool `json:"ok"` + AccessCode *seamapigo.UnmanagedAccessCode `json:"access_code,omitempty" url:"access_code,omitempty"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -123,8 +123,8 @@ func (u *UnmanagedGetResponse) String() string { } type UnmanagedListResponse struct { - AccessCodes []*seamapigo.UnmanagedAccessCode `json:"access_codes,omitempty"` - Ok bool `json:"ok"` + AccessCodes []*seamapigo.UnmanagedAccessCode `json:"access_codes,omitempty" url:"access_codes,omitempty"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -153,7 +153,7 @@ func (u *UnmanagedListResponse) String() string { } type UnmanagedUpdateResponse struct { - Ok bool `json:"ok"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -182,9 +182,9 @@ func (u *UnmanagedUpdateResponse) String() string { } type UnmanagedUpdateRequest struct { - AccessCodeId string `json:"access_code_id"` - IsManaged bool `json:"is_managed"` - AllowExternalModification *bool `json:"allow_external_modification,omitempty"` - IsExternalModificationAllowed *bool `json:"is_external_modification_allowed,omitempty"` - Force *bool `json:"force,omitempty"` + AccessCodeId string `json:"access_code_id" url:"access_code_id"` + IsManaged bool `json:"is_managed" url:"is_managed"` + AllowExternalModification *bool `json:"allow_external_modification,omitempty" url:"allow_external_modification,omitempty"` + IsExternalModificationAllowed *bool `json:"is_external_modification_allowed,omitempty" url:"is_external_modification_allowed,omitempty"` + Force *bool `json:"force,omitempty" url:"force,omitempty"` } diff --git a/accesscodes/unmanaged/client.go b/accesscodes/unmanaged/client.go index e240e80..cf07567 100644 --- a/accesscodes/unmanaged/client.go +++ b/accesscodes/unmanaged/client.go @@ -10,6 +10,7 @@ import ( seamapigo "github.com/seamapi/go" accesscodes "github.com/seamapi/go/accesscodes" core "github.com/seamapi/go/core" + option "github.com/seamapi/go/option" io "io" http "net/http" ) @@ -20,25 +21,38 @@ type Client struct { header http.Header } -func NewClient(opts ...core.ClientOption) *Client { - options := core.NewClientOptions() - for _, opt := range opts { - opt(options) - } +func NewClient(opts ...option.RequestOption) *Client { + options := core.NewRequestOptions(opts...) return &Client{ baseURL: options.BaseURL, - caller: core.NewCaller(options.HTTPClient), - header: options.ToHeader(), + caller: core.NewCaller( + &core.CallerParams{ + Client: options.HTTPClient, + MaxAttempts: options.MaxAttempts, + }, + ), + header: options.ToHeader(), } } -func (c *Client) ConvertToManaged(ctx context.Context, request *accesscodes.UnmanagedConvertToManagedRequest) (*accesscodes.UnmanagedConvertToManagedResponse, error) { +func (c *Client) ConvertToManaged( + ctx context.Context, + request *accesscodes.UnmanagedConvertToManagedRequest, + opts ...option.RequestOption, +) (*accesscodes.UnmanagedConvertToManagedResponse, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "access_codes/unmanaged/convert_to_managed" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -71,7 +85,9 @@ func (c *Client) ConvertToManaged(ctx context.Context, request *accesscodes.Unma &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -82,13 +98,24 @@ func (c *Client) ConvertToManaged(ctx context.Context, request *accesscodes.Unma return response, nil } -func (c *Client) Delete(ctx context.Context, request *accesscodes.UnmanagedDeleteRequest) (*seamapigo.ActionAttempt, error) { +func (c *Client) Delete( + ctx context.Context, + request *accesscodes.UnmanagedDeleteRequest, + opts ...option.RequestOption, +) (*seamapigo.ActionAttempt, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "access_codes/unmanaged/delete" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -121,7 +148,9 @@ func (c *Client) Delete(ctx context.Context, request *accesscodes.UnmanagedDelet &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -132,13 +161,24 @@ func (c *Client) Delete(ctx context.Context, request *accesscodes.UnmanagedDelet return response.ActionAttempt, nil } -func (c *Client) Get(ctx context.Context, request *accesscodes.UnmanagedGetRequest) (*seamapigo.UnmanagedAccessCode, error) { +func (c *Client) Get( + ctx context.Context, + request *accesscodes.UnmanagedGetRequest, + opts ...option.RequestOption, +) (*seamapigo.UnmanagedAccessCode, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "access_codes/unmanaged/get" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -171,7 +211,9 @@ func (c *Client) Get(ctx context.Context, request *accesscodes.UnmanagedGetReque &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -182,13 +224,24 @@ func (c *Client) Get(ctx context.Context, request *accesscodes.UnmanagedGetReque return response.AccessCode, nil } -func (c *Client) List(ctx context.Context, request *accesscodes.UnmanagedListRequest) ([]*seamapigo.UnmanagedAccessCode, error) { +func (c *Client) List( + ctx context.Context, + request *accesscodes.UnmanagedListRequest, + opts ...option.RequestOption, +) ([]*seamapigo.UnmanagedAccessCode, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "access_codes/unmanaged/list" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -221,7 +274,9 @@ func (c *Client) List(ctx context.Context, request *accesscodes.UnmanagedListReq &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -232,13 +287,24 @@ func (c *Client) List(ctx context.Context, request *accesscodes.UnmanagedListReq return response.AccessCodes, nil } -func (c *Client) Update(ctx context.Context, request *accesscodes.UnmanagedUpdateRequest) (*accesscodes.UnmanagedUpdateResponse, error) { +func (c *Client) Update( + ctx context.Context, + request *accesscodes.UnmanagedUpdateRequest, + opts ...option.RequestOption, +) (*accesscodes.UnmanagedUpdateResponse, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "access_codes/unmanaged/update" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -271,7 +337,9 @@ func (c *Client) Update(ctx context.Context, request *accesscodes.UnmanagedUpdat &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, diff --git a/acs/access_groups.go b/acs/access_groups.go index 010a252..41d920c 100644 --- a/acs/access_groups.go +++ b/acs/access_groups.go @@ -10,30 +10,30 @@ import ( ) type AccessGroupsAddUserRequest struct { - AcsAccessGroupId string `json:"acs_access_group_id"` - AcsUserId string `json:"acs_user_id"` + AcsAccessGroupId string `json:"acs_access_group_id" url:"acs_access_group_id"` + AcsUserId string `json:"acs_user_id" url:"acs_user_id"` } type AccessGroupsGetRequest struct { - AcsAccessGroupId string `json:"acs_access_group_id"` + AcsAccessGroupId string `json:"acs_access_group_id" url:"acs_access_group_id"` } type AccessGroupsListRequest struct { - AcsSystemId *string `json:"acs_system_id,omitempty"` - AcsUserId *string `json:"acs_user_id,omitempty"` + AcsSystemId *string `json:"acs_system_id,omitempty" url:"acs_system_id,omitempty"` + AcsUserId *string `json:"acs_user_id,omitempty" url:"acs_user_id,omitempty"` } type AccessGroupsListUsersRequest struct { - AcsAccessGroupId string `json:"acs_access_group_id"` + AcsAccessGroupId string `json:"acs_access_group_id" url:"acs_access_group_id"` } type AccessGroupsRemoveUserRequest struct { - AcsAccessGroupId string `json:"acs_access_group_id"` - AcsUserId string `json:"acs_user_id"` + AcsAccessGroupId string `json:"acs_access_group_id" url:"acs_access_group_id"` + AcsUserId string `json:"acs_user_id" url:"acs_user_id"` } type AccessGroupsAddUserResponse struct { - Ok bool `json:"ok"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -62,8 +62,8 @@ func (a *AccessGroupsAddUserResponse) String() string { } type AccessGroupsGetResponse struct { - AcsAccessGroup *seamapigo.AcsAccessGroup `json:"acs_access_group,omitempty"` - Ok bool `json:"ok"` + AcsAccessGroup *seamapigo.AcsAccessGroup `json:"acs_access_group,omitempty" url:"acs_access_group,omitempty"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -92,8 +92,8 @@ func (a *AccessGroupsGetResponse) String() string { } type AccessGroupsListResponse struct { - AcsAccessGroups []*seamapigo.AcsAccessGroup `json:"acs_access_groups,omitempty"` - Ok bool `json:"ok"` + AcsAccessGroups []*seamapigo.AcsAccessGroup `json:"acs_access_groups,omitempty" url:"acs_access_groups,omitempty"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -122,8 +122,8 @@ func (a *AccessGroupsListResponse) String() string { } type AccessGroupsListUsersResponse struct { - AcsUsers []*seamapigo.AcsUser `json:"acs_users,omitempty"` - Ok bool `json:"ok"` + AcsUsers []*seamapigo.AcsUser `json:"acs_users,omitempty" url:"acs_users,omitempty"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -152,7 +152,7 @@ func (a *AccessGroupsListUsersResponse) String() string { } type AccessGroupsRemoveUserResponse struct { - Ok bool `json:"ok"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } diff --git a/acs/accessgroups/client.go b/acs/accessgroups/client.go index ad8b5e5..3bee1d1 100644 --- a/acs/accessgroups/client.go +++ b/acs/accessgroups/client.go @@ -10,6 +10,7 @@ import ( seamapigo "github.com/seamapi/go" acs "github.com/seamapi/go/acs" core "github.com/seamapi/go/core" + option "github.com/seamapi/go/option" io "io" http "net/http" ) @@ -20,25 +21,38 @@ type Client struct { header http.Header } -func NewClient(opts ...core.ClientOption) *Client { - options := core.NewClientOptions() - for _, opt := range opts { - opt(options) - } +func NewClient(opts ...option.RequestOption) *Client { + options := core.NewRequestOptions(opts...) return &Client{ baseURL: options.BaseURL, - caller: core.NewCaller(options.HTTPClient), - header: options.ToHeader(), + caller: core.NewCaller( + &core.CallerParams{ + Client: options.HTTPClient, + MaxAttempts: options.MaxAttempts, + }, + ), + header: options.ToHeader(), } } -func (c *Client) AddUser(ctx context.Context, request *acs.AccessGroupsAddUserRequest) (*acs.AccessGroupsAddUserResponse, error) { +func (c *Client) AddUser( + ctx context.Context, + request *acs.AccessGroupsAddUserRequest, + opts ...option.RequestOption, +) (*acs.AccessGroupsAddUserResponse, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "acs/access_groups/add_user" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -71,7 +85,9 @@ func (c *Client) AddUser(ctx context.Context, request *acs.AccessGroupsAddUserRe &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -82,13 +98,24 @@ func (c *Client) AddUser(ctx context.Context, request *acs.AccessGroupsAddUserRe return response, nil } -func (c *Client) Get(ctx context.Context, request *acs.AccessGroupsGetRequest) (*acs.AccessGroupsGetResponse, error) { +func (c *Client) Get( + ctx context.Context, + request *acs.AccessGroupsGetRequest, + opts ...option.RequestOption, +) (*acs.AccessGroupsGetResponse, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "acs/access_groups/get" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -121,7 +148,9 @@ func (c *Client) Get(ctx context.Context, request *acs.AccessGroupsGetRequest) ( &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -132,13 +161,24 @@ func (c *Client) Get(ctx context.Context, request *acs.AccessGroupsGetRequest) ( return response, nil } -func (c *Client) List(ctx context.Context, request *acs.AccessGroupsListRequest) (*acs.AccessGroupsListResponse, error) { +func (c *Client) List( + ctx context.Context, + request *acs.AccessGroupsListRequest, + opts ...option.RequestOption, +) (*acs.AccessGroupsListResponse, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "acs/access_groups/list" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -171,7 +211,9 @@ func (c *Client) List(ctx context.Context, request *acs.AccessGroupsListRequest) &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -182,13 +224,24 @@ func (c *Client) List(ctx context.Context, request *acs.AccessGroupsListRequest) return response, nil } -func (c *Client) ListUsers(ctx context.Context, request *acs.AccessGroupsListUsersRequest) (*acs.AccessGroupsListUsersResponse, error) { +func (c *Client) ListUsers( + ctx context.Context, + request *acs.AccessGroupsListUsersRequest, + opts ...option.RequestOption, +) (*acs.AccessGroupsListUsersResponse, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "acs/access_groups/list_users" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -221,7 +274,9 @@ func (c *Client) ListUsers(ctx context.Context, request *acs.AccessGroupsListUse &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -232,13 +287,24 @@ func (c *Client) ListUsers(ctx context.Context, request *acs.AccessGroupsListUse return response, nil } -func (c *Client) RemoveUser(ctx context.Context, request *acs.AccessGroupsRemoveUserRequest) (*acs.AccessGroupsRemoveUserResponse, error) { +func (c *Client) RemoveUser( + ctx context.Context, + request *acs.AccessGroupsRemoveUserRequest, + opts ...option.RequestOption, +) (*acs.AccessGroupsRemoveUserResponse, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "acs/access_groups/remove_user" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -271,7 +337,9 @@ func (c *Client) RemoveUser(ctx context.Context, request *acs.AccessGroupsRemove &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, diff --git a/acs/client/client.go b/acs/client/client.go index bff55de..688be3b 100644 --- a/acs/client/client.go +++ b/acs/client/client.go @@ -11,6 +11,7 @@ import ( systems "github.com/seamapi/go/acs/systems" users "github.com/seamapi/go/acs/users" core "github.com/seamapi/go/core" + option "github.com/seamapi/go/option" http "net/http" ) @@ -28,14 +29,16 @@ type Client struct { Users *users.Client } -func NewClient(opts ...core.ClientOption) *Client { - options := core.NewClientOptions() - for _, opt := range opts { - opt(options) - } +func NewClient(opts ...option.RequestOption) *Client { + options := core.NewRequestOptions(opts...) return &Client{ - baseURL: options.BaseURL, - caller: core.NewCaller(options.HTTPClient), + baseURL: options.BaseURL, + caller: core.NewCaller( + &core.CallerParams{ + Client: options.HTTPClient, + MaxAttempts: options.MaxAttempts, + }, + ), header: options.ToHeader(), AccessGroups: accessgroups.NewClient(opts...), CredentialPools: credentialpools.NewClient(opts...), diff --git a/acs/credential_pools.go b/acs/credential_pools.go index 559a8a8..5571a83 100644 --- a/acs/credential_pools.go +++ b/acs/credential_pools.go @@ -9,12 +9,12 @@ import ( ) type CredentialPoolsListRequest struct { - AcsSystemId string `json:"acs_system_id"` + AcsSystemId string `json:"acs_system_id" url:"acs_system_id"` } type CredentialPoolsListResponse struct { - AcsCredentialPools []*CredentialPoolsListResponseAcsCredentialPoolsItem `json:"acs_credential_pools,omitempty"` - Ok bool `json:"ok"` + AcsCredentialPools []*CredentialPoolsListResponseAcsCredentialPoolsItem `json:"acs_credential_pools,omitempty" url:"acs_credential_pools,omitempty"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } diff --git a/acs/credential_provisioning_automations.go b/acs/credential_provisioning_automations.go index 1caadeb..9bab443 100644 --- a/acs/credential_provisioning_automations.go +++ b/acs/credential_provisioning_automations.go @@ -9,16 +9,16 @@ import ( ) type CredentialProvisioningAutomationsLaunchRequest struct { - UserIdentityId string `json:"user_identity_id"` - CredentialManagerAcsSystemId string `json:"credential_manager_acs_system_id"` - AcsCredentialPoolId *string `json:"acs_credential_pool_id,omitempty"` - CreateCredentialManagerUser *bool `json:"create_credential_manager_user,omitempty"` - CredentialManagerAcsUserId *string `json:"credential_manager_acs_user_id,omitempty"` + UserIdentityId string `json:"user_identity_id" url:"user_identity_id"` + CredentialManagerAcsSystemId string `json:"credential_manager_acs_system_id" url:"credential_manager_acs_system_id"` + AcsCredentialPoolId *string `json:"acs_credential_pool_id,omitempty" url:"acs_credential_pool_id,omitempty"` + CreateCredentialManagerUser *bool `json:"create_credential_manager_user,omitempty" url:"create_credential_manager_user,omitempty"` + CredentialManagerAcsUserId *string `json:"credential_manager_acs_user_id,omitempty" url:"credential_manager_acs_user_id,omitempty"` } type CredentialProvisioningAutomationsLaunchResponse struct { - AcsCredentialProvisioningAutomation *CredentialProvisioningAutomationsLaunchResponseAcsCredentialProvisioningAutomation `json:"acs_credential_provisioning_automation,omitempty"` - Ok bool `json:"ok"` + AcsCredentialProvisioningAutomation *CredentialProvisioningAutomationsLaunchResponseAcsCredentialProvisioningAutomation `json:"acs_credential_provisioning_automation,omitempty" url:"acs_credential_provisioning_automation,omitempty"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } diff --git a/acs/credentialpools/client.go b/acs/credentialpools/client.go index 3f1f9d7..4fca7d0 100644 --- a/acs/credentialpools/client.go +++ b/acs/credentialpools/client.go @@ -10,6 +10,7 @@ import ( seamapigo "github.com/seamapi/go" acs "github.com/seamapi/go/acs" core "github.com/seamapi/go/core" + option "github.com/seamapi/go/option" io "io" http "net/http" ) @@ -20,25 +21,38 @@ type Client struct { header http.Header } -func NewClient(opts ...core.ClientOption) *Client { - options := core.NewClientOptions() - for _, opt := range opts { - opt(options) - } +func NewClient(opts ...option.RequestOption) *Client { + options := core.NewRequestOptions(opts...) return &Client{ baseURL: options.BaseURL, - caller: core.NewCaller(options.HTTPClient), - header: options.ToHeader(), + caller: core.NewCaller( + &core.CallerParams{ + Client: options.HTTPClient, + MaxAttempts: options.MaxAttempts, + }, + ), + header: options.ToHeader(), } } -func (c *Client) List(ctx context.Context, request *acs.CredentialPoolsListRequest) (*acs.CredentialPoolsListResponse, error) { +func (c *Client) List( + ctx context.Context, + request *acs.CredentialPoolsListRequest, + opts ...option.RequestOption, +) (*acs.CredentialPoolsListResponse, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "acs/credential_pools/list" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -71,7 +85,9 @@ func (c *Client) List(ctx context.Context, request *acs.CredentialPoolsListReque &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, diff --git a/acs/credentialprovisioningautomations/client.go b/acs/credentialprovisioningautomations/client.go index 403ab50..5784e64 100644 --- a/acs/credentialprovisioningautomations/client.go +++ b/acs/credentialprovisioningautomations/client.go @@ -10,6 +10,7 @@ import ( seamapigo "github.com/seamapi/go" acs "github.com/seamapi/go/acs" core "github.com/seamapi/go/core" + option "github.com/seamapi/go/option" io "io" http "net/http" ) @@ -20,25 +21,38 @@ type Client struct { header http.Header } -func NewClient(opts ...core.ClientOption) *Client { - options := core.NewClientOptions() - for _, opt := range opts { - opt(options) - } +func NewClient(opts ...option.RequestOption) *Client { + options := core.NewRequestOptions(opts...) return &Client{ baseURL: options.BaseURL, - caller: core.NewCaller(options.HTTPClient), - header: options.ToHeader(), + caller: core.NewCaller( + &core.CallerParams{ + Client: options.HTTPClient, + MaxAttempts: options.MaxAttempts, + }, + ), + header: options.ToHeader(), } } -func (c *Client) Launch(ctx context.Context, request *acs.CredentialProvisioningAutomationsLaunchRequest) (*acs.CredentialProvisioningAutomationsLaunchResponse, error) { +func (c *Client) Launch( + ctx context.Context, + request *acs.CredentialProvisioningAutomationsLaunchRequest, + opts ...option.RequestOption, +) (*acs.CredentialProvisioningAutomationsLaunchResponse, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "acs/credential_provisioning_automations/launch" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -71,7 +85,9 @@ func (c *Client) Launch(ctx context.Context, request *acs.CredentialProvisioning &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, diff --git a/acs/credentials.go b/acs/credentials.go index 042efe9..c02b275 100644 --- a/acs/credentials.go +++ b/acs/credentials.go @@ -6,35 +6,64 @@ import ( json "encoding/json" fmt "fmt" core "github.com/seamapi/go/core" + time "time" ) type CredentialsAssignRequest struct { - AcsUserId string `json:"acs_user_id"` - AcsCredentialId string `json:"acs_credential_id"` + AcsUserId string `json:"acs_user_id" url:"acs_user_id"` + AcsCredentialId string `json:"acs_credential_id" url:"acs_credential_id"` } type CredentialsCreateRequest struct { - AcsUserId string `json:"acs_user_id"` - AccessMethod CredentialsCreateRequestAccessMethod `json:"access_method,omitempty"` - Code *string `json:"code,omitempty"` - IsMultiPhoneSyncCredential *bool `json:"is_multi_phone_sync_credential,omitempty"` - ExternalType *CredentialsCreateRequestExternalType `json:"external_type,omitempty"` - VisionlineMetadata *CredentialsCreateRequestVisionlineMetadata `json:"visionline_metadata,omitempty"` - StartsAt *string `json:"starts_at,omitempty"` - EndsAt *string `json:"ends_at,omitempty"` + AcsUserId string `json:"acs_user_id" url:"acs_user_id"` + AccessMethod CredentialsCreateRequestAccessMethod `json:"access_method,omitempty" url:"access_method,omitempty"` + Code *string `json:"code,omitempty" url:"code,omitempty"` + IsMultiPhoneSyncCredential *bool `json:"is_multi_phone_sync_credential,omitempty" url:"is_multi_phone_sync_credential,omitempty"` + ExternalType *string `json:"external_type,omitempty" url:"external_type,omitempty"` + VisionlineMetadata *CredentialsCreateRequestVisionlineMetadata `json:"visionline_metadata,omitempty" url:"visionline_metadata,omitempty"` + StartsAt *time.Time `json:"starts_at,omitempty" url:"starts_at,omitempty"` + EndsAt *time.Time `json:"ends_at,omitempty" url:"ends_at,omitempty"` +} + +func (c *CredentialsCreateRequest) UnmarshalJSON(data []byte) error { + type unmarshaler CredentialsCreateRequest + var body unmarshaler + if err := json.Unmarshal(data, &body); err != nil { + return err + } + *c = CredentialsCreateRequest(body) + return nil +} + +func (c *CredentialsCreateRequest) MarshalJSON() ([]byte, error) { + type embed CredentialsCreateRequest + var marshaler = struct { + embed + StartsAt *core.DateTime `json:"starts_at,omitempty"` + EndsAt *core.DateTime `json:"ends_at,omitempty"` + }{ + embed: embed(*c), + StartsAt: core.NewOptionalDateTime(c.StartsAt), + EndsAt: core.NewOptionalDateTime(c.EndsAt), + } + return json.Marshal(marshaler) } type CredentialsDeleteRequest struct { - AcsCredentialId string `json:"acs_credential_id"` + AcsCredentialId string `json:"acs_credential_id" url:"acs_credential_id"` } type CredentialsGetRequest struct { - AcsCredentialId string `json:"acs_credential_id"` + AcsCredentialId string `json:"acs_credential_id" url:"acs_credential_id"` +} + +type CredentialsListRequest struct { + IsMultiPhoneSyncCredential *bool `json:"is_multi_phone_sync_credential,omitempty" url:"is_multi_phone_sync_credential,omitempty"` } type CredentialsAssignResponse struct { - AcsCredential *CredentialsAssignResponseAcsCredential `json:"acs_credential,omitempty"` - Ok bool `json:"ok"` + AcsCredential *CredentialsAssignResponseAcsCredential `json:"acs_credential,omitempty" url:"acs_credential,omitempty"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -87,39 +116,11 @@ func (c CredentialsCreateRequestAccessMethod) Ptr() *CredentialsCreateRequestAcc return &c } -type CredentialsCreateRequestExternalType string - -const ( - CredentialsCreateRequestExternalTypePtiCard CredentialsCreateRequestExternalType = "pti_card" - CredentialsCreateRequestExternalTypeBrivoCredential CredentialsCreateRequestExternalType = "brivo_credential" - CredentialsCreateRequestExternalTypeHidCredential CredentialsCreateRequestExternalType = "hid_credential" - CredentialsCreateRequestExternalTypeVisionlineCard CredentialsCreateRequestExternalType = "visionline_card" -) - -func NewCredentialsCreateRequestExternalTypeFromString(s string) (CredentialsCreateRequestExternalType, error) { - switch s { - case "pti_card": - return CredentialsCreateRequestExternalTypePtiCard, nil - case "brivo_credential": - return CredentialsCreateRequestExternalTypeBrivoCredential, nil - case "hid_credential": - return CredentialsCreateRequestExternalTypeHidCredential, nil - case "visionline_card": - return CredentialsCreateRequestExternalTypeVisionlineCard, nil - } - var t CredentialsCreateRequestExternalType - return "", fmt.Errorf("%s is not a valid %T", s, t) -} - -func (c CredentialsCreateRequestExternalType) Ptr() *CredentialsCreateRequestExternalType { - return &c -} - type CredentialsCreateRequestVisionlineMetadata struct { - AssaAbloyCredentialServiceMobileEndpointId *string `json:"assa_abloy_credential_service_mobile_endpoint_id,omitempty"` - CardFormat *CredentialsCreateRequestVisionlineMetadataCardFormat `json:"card_format,omitempty"` - IsOverrideKey *bool `json:"is_override_key,omitempty"` - JoinerAcsCredentialIds []string `json:"joiner_acs_credential_ids,omitempty"` + AssaAbloyCredentialServiceMobileEndpointId *string `json:"assa_abloy_credential_service_mobile_endpoint_id,omitempty" url:"assa_abloy_credential_service_mobile_endpoint_id,omitempty"` + CardFormat *CredentialsCreateRequestVisionlineMetadataCardFormat `json:"card_format,omitempty" url:"card_format,omitempty"` + IsOverrideKey *bool `json:"is_override_key,omitempty" url:"is_override_key,omitempty"` + JoinerAcsCredentialIds []string `json:"joiner_acs_credential_ids,omitempty" url:"joiner_acs_credential_ids,omitempty"` _rawJSON json.RawMessage } @@ -148,8 +149,8 @@ func (c *CredentialsCreateRequestVisionlineMetadata) String() string { } type CredentialsCreateResponse struct { - AcsCredential *CredentialsCreateResponseAcsCredential `json:"acs_credential,omitempty"` - Ok bool `json:"ok"` + AcsCredential *CredentialsCreateResponseAcsCredential `json:"acs_credential,omitempty" url:"acs_credential,omitempty"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -178,7 +179,7 @@ func (c *CredentialsCreateResponse) String() string { } type CredentialsDeleteResponse struct { - Ok bool `json:"ok"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -207,8 +208,8 @@ func (c *CredentialsDeleteResponse) String() string { } type CredentialsGetResponse struct { - AcsCredential *CredentialsGetResponseAcsCredential `json:"acs_credential,omitempty"` - Ok bool `json:"ok"` + AcsCredential *CredentialsGetResponseAcsCredential `json:"acs_credential,omitempty" url:"acs_credential,omitempty"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -236,98 +237,9 @@ func (c *CredentialsGetResponse) String() string { return fmt.Sprintf("%#v", c) } -type CredentialsListRequest struct { - typeName string - CredentialsListRequestZero *CredentialsListRequestZero - CredentialsListRequestOne *CredentialsListRequestOne - CredentialsListRequestTwo *CredentialsListRequestTwo - CredentialsListRequestUserIdentityId *CredentialsListRequestUserIdentityId -} - -func NewCredentialsListRequestFromCredentialsListRequestZero(value *CredentialsListRequestZero) *CredentialsListRequest { - return &CredentialsListRequest{typeName: "credentialsListRequestZero", CredentialsListRequestZero: value} -} - -func NewCredentialsListRequestFromCredentialsListRequestOne(value *CredentialsListRequestOne) *CredentialsListRequest { - return &CredentialsListRequest{typeName: "credentialsListRequestOne", CredentialsListRequestOne: value} -} - -func NewCredentialsListRequestFromCredentialsListRequestTwo(value *CredentialsListRequestTwo) *CredentialsListRequest { - return &CredentialsListRequest{typeName: "credentialsListRequestTwo", CredentialsListRequestTwo: value} -} - -func NewCredentialsListRequestFromCredentialsListRequestUserIdentityId(value *CredentialsListRequestUserIdentityId) *CredentialsListRequest { - return &CredentialsListRequest{typeName: "credentialsListRequestUserIdentityId", CredentialsListRequestUserIdentityId: value} -} - -func (c *CredentialsListRequest) UnmarshalJSON(data []byte) error { - valueCredentialsListRequestZero := new(CredentialsListRequestZero) - if err := json.Unmarshal(data, &valueCredentialsListRequestZero); err == nil { - c.typeName = "credentialsListRequestZero" - c.CredentialsListRequestZero = valueCredentialsListRequestZero - return nil - } - valueCredentialsListRequestOne := new(CredentialsListRequestOne) - if err := json.Unmarshal(data, &valueCredentialsListRequestOne); err == nil { - c.typeName = "credentialsListRequestOne" - c.CredentialsListRequestOne = valueCredentialsListRequestOne - return nil - } - valueCredentialsListRequestTwo := new(CredentialsListRequestTwo) - if err := json.Unmarshal(data, &valueCredentialsListRequestTwo); err == nil { - c.typeName = "credentialsListRequestTwo" - c.CredentialsListRequestTwo = valueCredentialsListRequestTwo - return nil - } - valueCredentialsListRequestUserIdentityId := new(CredentialsListRequestUserIdentityId) - if err := json.Unmarshal(data, &valueCredentialsListRequestUserIdentityId); err == nil { - c.typeName = "credentialsListRequestUserIdentityId" - c.CredentialsListRequestUserIdentityId = valueCredentialsListRequestUserIdentityId - return nil - } - return fmt.Errorf("%s cannot be deserialized as a %T", data, c) -} - -func (c CredentialsListRequest) MarshalJSON() ([]byte, error) { - switch c.typeName { - default: - return nil, fmt.Errorf("invalid type %s in %T", c.typeName, c) - case "credentialsListRequestZero": - return json.Marshal(c.CredentialsListRequestZero) - case "credentialsListRequestOne": - return json.Marshal(c.CredentialsListRequestOne) - case "credentialsListRequestTwo": - return json.Marshal(c.CredentialsListRequestTwo) - case "credentialsListRequestUserIdentityId": - return json.Marshal(c.CredentialsListRequestUserIdentityId) - } -} - -type CredentialsListRequestVisitor interface { - VisitCredentialsListRequestZero(*CredentialsListRequestZero) error - VisitCredentialsListRequestOne(*CredentialsListRequestOne) error - VisitCredentialsListRequestTwo(*CredentialsListRequestTwo) error - VisitCredentialsListRequestUserIdentityId(*CredentialsListRequestUserIdentityId) error -} - -func (c *CredentialsListRequest) Accept(visitor CredentialsListRequestVisitor) error { - switch c.typeName { - default: - return fmt.Errorf("invalid type %s in %T", c.typeName, c) - case "credentialsListRequestZero": - return visitor.VisitCredentialsListRequestZero(c.CredentialsListRequestZero) - case "credentialsListRequestOne": - return visitor.VisitCredentialsListRequestOne(c.CredentialsListRequestOne) - case "credentialsListRequestTwo": - return visitor.VisitCredentialsListRequestTwo(c.CredentialsListRequestTwo) - case "credentialsListRequestUserIdentityId": - return visitor.VisitCredentialsListRequestUserIdentityId(c.CredentialsListRequestUserIdentityId) - } -} - type CredentialsListResponse struct { - AcsCredentials []*CredentialsListResponseAcsCredentialsItem `json:"acs_credentials,omitempty"` - Ok bool `json:"ok"` + AcsCredentials []*CredentialsListResponseAcsCredentialsItem `json:"acs_credentials,omitempty" url:"acs_credentials,omitempty"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -356,8 +268,8 @@ func (c *CredentialsListResponse) String() string { } type CredentialsUnassignResponse struct { - AcsCredential *CredentialsUnassignResponseAcsCredential `json:"acs_credential,omitempty"` - Ok bool `json:"ok"` + AcsCredential *CredentialsUnassignResponseAcsCredential `json:"acs_credential,omitempty" url:"acs_credential,omitempty"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -386,8 +298,8 @@ func (c *CredentialsUnassignResponse) String() string { } type CredentialsUpdateResponse struct { - AcsCredential *CredentialsUpdateResponseAcsCredential `json:"acs_credential,omitempty"` - Ok bool `json:"ok"` + AcsCredential *CredentialsUpdateResponseAcsCredential `json:"acs_credential,omitempty" url:"acs_credential,omitempty"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -416,11 +328,11 @@ func (c *CredentialsUpdateResponse) String() string { } type CredentialsUnassignRequest struct { - AcsUserId string `json:"acs_user_id"` - AcsCredentialId string `json:"acs_credential_id"` + AcsUserId string `json:"acs_user_id" url:"acs_user_id"` + AcsCredentialId string `json:"acs_credential_id" url:"acs_credential_id"` } type CredentialsUpdateRequest struct { - AcsCredentialId string `json:"acs_credential_id"` - Code string `json:"code"` + AcsCredentialId string `json:"acs_credential_id" url:"acs_credential_id"` + Code string `json:"code" url:"code"` } diff --git a/acs/credentials/client.go b/acs/credentials/client.go index 0fb5d47..7eb37e4 100644 --- a/acs/credentials/client.go +++ b/acs/credentials/client.go @@ -10,6 +10,7 @@ import ( seamapigo "github.com/seamapi/go" acs "github.com/seamapi/go/acs" core "github.com/seamapi/go/core" + option "github.com/seamapi/go/option" io "io" http "net/http" ) @@ -20,25 +21,38 @@ type Client struct { header http.Header } -func NewClient(opts ...core.ClientOption) *Client { - options := core.NewClientOptions() - for _, opt := range opts { - opt(options) - } +func NewClient(opts ...option.RequestOption) *Client { + options := core.NewRequestOptions(opts...) return &Client{ baseURL: options.BaseURL, - caller: core.NewCaller(options.HTTPClient), - header: options.ToHeader(), + caller: core.NewCaller( + &core.CallerParams{ + Client: options.HTTPClient, + MaxAttempts: options.MaxAttempts, + }, + ), + header: options.ToHeader(), } } -func (c *Client) Assign(ctx context.Context, request *acs.CredentialsAssignRequest) (*acs.CredentialsAssignResponse, error) { +func (c *Client) Assign( + ctx context.Context, + request *acs.CredentialsAssignRequest, + opts ...option.RequestOption, +) (*acs.CredentialsAssignResponse, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "acs/credentials/assign" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -71,7 +85,9 @@ func (c *Client) Assign(ctx context.Context, request *acs.CredentialsAssignReque &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -82,13 +98,24 @@ func (c *Client) Assign(ctx context.Context, request *acs.CredentialsAssignReque return response, nil } -func (c *Client) Create(ctx context.Context, request *acs.CredentialsCreateRequest) (*acs.CredentialsCreateResponse, error) { +func (c *Client) Create( + ctx context.Context, + request *acs.CredentialsCreateRequest, + opts ...option.RequestOption, +) (*acs.CredentialsCreateResponse, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "acs/credentials/create" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -121,7 +148,9 @@ func (c *Client) Create(ctx context.Context, request *acs.CredentialsCreateReque &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -132,13 +161,24 @@ func (c *Client) Create(ctx context.Context, request *acs.CredentialsCreateReque return response, nil } -func (c *Client) Delete(ctx context.Context, request *acs.CredentialsDeleteRequest) (*acs.CredentialsDeleteResponse, error) { +func (c *Client) Delete( + ctx context.Context, + request *acs.CredentialsDeleteRequest, + opts ...option.RequestOption, +) (*acs.CredentialsDeleteResponse, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "acs/credentials/delete" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -171,7 +211,9 @@ func (c *Client) Delete(ctx context.Context, request *acs.CredentialsDeleteReque &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -182,13 +224,24 @@ func (c *Client) Delete(ctx context.Context, request *acs.CredentialsDeleteReque return response, nil } -func (c *Client) Get(ctx context.Context, request *acs.CredentialsGetRequest) (*acs.CredentialsGetResponse, error) { +func (c *Client) Get( + ctx context.Context, + request *acs.CredentialsGetRequest, + opts ...option.RequestOption, +) (*acs.CredentialsGetResponse, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "acs/credentials/get" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -221,7 +274,9 @@ func (c *Client) Get(ctx context.Context, request *acs.CredentialsGetRequest) (* &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -232,13 +287,24 @@ func (c *Client) Get(ctx context.Context, request *acs.CredentialsGetRequest) (* return response, nil } -func (c *Client) List(ctx context.Context, request *acs.CredentialsListRequest) (*acs.CredentialsListResponse, error) { +func (c *Client) List( + ctx context.Context, + request *acs.CredentialsListRequest, + opts ...option.RequestOption, +) (*acs.CredentialsListResponse, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "acs/credentials/list" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -271,7 +337,9 @@ func (c *Client) List(ctx context.Context, request *acs.CredentialsListRequest) &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -282,13 +350,24 @@ func (c *Client) List(ctx context.Context, request *acs.CredentialsListRequest) return response, nil } -func (c *Client) Unassign(ctx context.Context, request *acs.CredentialsUnassignRequest) (*acs.CredentialsUnassignResponse, error) { +func (c *Client) Unassign( + ctx context.Context, + request *acs.CredentialsUnassignRequest, + opts ...option.RequestOption, +) (*acs.CredentialsUnassignResponse, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "acs/credentials/unassign" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -321,7 +400,9 @@ func (c *Client) Unassign(ctx context.Context, request *acs.CredentialsUnassignR &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -332,13 +413,24 @@ func (c *Client) Unassign(ctx context.Context, request *acs.CredentialsUnassignR return response, nil } -func (c *Client) Update(ctx context.Context, request *acs.CredentialsUpdateRequest) (*acs.CredentialsUpdateResponse, error) { +func (c *Client) Update( + ctx context.Context, + request *acs.CredentialsUpdateRequest, + opts ...option.RequestOption, +) (*acs.CredentialsUpdateResponse, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "acs/credentials/update" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -371,7 +463,9 @@ func (c *Client) Update(ctx context.Context, request *acs.CredentialsUpdateReque &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, diff --git a/acs/entrances.go b/acs/entrances.go index e6edb8d..3782590 100644 --- a/acs/entrances.go +++ b/acs/entrances.go @@ -9,27 +9,27 @@ import ( ) type EntrancesGetRequest struct { - AcsEntranceId string `json:"acs_entrance_id"` + AcsEntranceId string `json:"acs_entrance_id" url:"acs_entrance_id"` } type EntrancesGrantAccessRequest struct { - AcsEntranceId string `json:"acs_entrance_id"` - AcsUserId string `json:"acs_user_id"` + AcsEntranceId string `json:"acs_entrance_id" url:"acs_entrance_id"` + AcsUserId string `json:"acs_user_id" url:"acs_user_id"` } type EntrancesListRequest struct { - AcsSystemId *string `json:"acs_system_id,omitempty"` - AcsCredentialId *string `json:"acs_credential_id,omitempty"` + AcsSystemId *string `json:"acs_system_id,omitempty" url:"acs_system_id,omitempty"` + AcsCredentialId *string `json:"acs_credential_id,omitempty" url:"acs_credential_id,omitempty"` } type EntrancesListCredentialsWithAccessRequest struct { - AcsEntranceId string `json:"acs_entrance_id"` - IncludeIf []string `json:"include_if,omitempty"` + AcsEntranceId string `json:"acs_entrance_id" url:"acs_entrance_id"` + IncludeIf []string `json:"include_if,omitempty" url:"include_if,omitempty"` } type EntrancesGetResponse struct { - AcsEntrance *EntrancesGetResponseAcsEntrance `json:"acs_entrance,omitempty"` - Ok bool `json:"ok"` + AcsEntrance *EntrancesGetResponseAcsEntrance `json:"acs_entrance,omitempty" url:"acs_entrance,omitempty"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -58,7 +58,7 @@ func (e *EntrancesGetResponse) String() string { } type EntrancesGrantAccessResponse struct { - Ok bool `json:"ok"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -87,8 +87,8 @@ func (e *EntrancesGrantAccessResponse) String() string { } type EntrancesListCredentialsWithAccessResponse struct { - AcsCredentials []*EntrancesListCredentialsWithAccessResponseAcsCredentialsItem `json:"acs_credentials,omitempty"` - Ok bool `json:"ok"` + AcsCredentials []*EntrancesListCredentialsWithAccessResponseAcsCredentialsItem `json:"acs_credentials,omitempty" url:"acs_credentials,omitempty"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -117,8 +117,8 @@ func (e *EntrancesListCredentialsWithAccessResponse) String() string { } type EntrancesListResponse struct { - AcsEntrances []*EntrancesListResponseAcsEntrancesItem `json:"acs_entrances,omitempty"` - Ok bool `json:"ok"` + AcsEntrances []*EntrancesListResponseAcsEntrancesItem `json:"acs_entrances,omitempty" url:"acs_entrances,omitempty"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } diff --git a/acs/entrances/client.go b/acs/entrances/client.go index ea34707..030030e 100644 --- a/acs/entrances/client.go +++ b/acs/entrances/client.go @@ -10,6 +10,7 @@ import ( seamapigo "github.com/seamapi/go" acs "github.com/seamapi/go/acs" core "github.com/seamapi/go/core" + option "github.com/seamapi/go/option" io "io" http "net/http" ) @@ -20,25 +21,38 @@ type Client struct { header http.Header } -func NewClient(opts ...core.ClientOption) *Client { - options := core.NewClientOptions() - for _, opt := range opts { - opt(options) - } +func NewClient(opts ...option.RequestOption) *Client { + options := core.NewRequestOptions(opts...) return &Client{ baseURL: options.BaseURL, - caller: core.NewCaller(options.HTTPClient), - header: options.ToHeader(), + caller: core.NewCaller( + &core.CallerParams{ + Client: options.HTTPClient, + MaxAttempts: options.MaxAttempts, + }, + ), + header: options.ToHeader(), } } -func (c *Client) Get(ctx context.Context, request *acs.EntrancesGetRequest) (*acs.EntrancesGetResponse, error) { +func (c *Client) Get( + ctx context.Context, + request *acs.EntrancesGetRequest, + opts ...option.RequestOption, +) (*acs.EntrancesGetResponse, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "acs/entrances/get" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -71,7 +85,9 @@ func (c *Client) Get(ctx context.Context, request *acs.EntrancesGetRequest) (*ac &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -82,13 +98,24 @@ func (c *Client) Get(ctx context.Context, request *acs.EntrancesGetRequest) (*ac return response, nil } -func (c *Client) GrantAccess(ctx context.Context, request *acs.EntrancesGrantAccessRequest) (*acs.EntrancesGrantAccessResponse, error) { +func (c *Client) GrantAccess( + ctx context.Context, + request *acs.EntrancesGrantAccessRequest, + opts ...option.RequestOption, +) (*acs.EntrancesGrantAccessResponse, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "acs/entrances/grant_access" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -121,7 +148,9 @@ func (c *Client) GrantAccess(ctx context.Context, request *acs.EntrancesGrantAcc &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -132,13 +161,24 @@ func (c *Client) GrantAccess(ctx context.Context, request *acs.EntrancesGrantAcc return response, nil } -func (c *Client) List(ctx context.Context, request *acs.EntrancesListRequest) (*acs.EntrancesListResponse, error) { +func (c *Client) List( + ctx context.Context, + request *acs.EntrancesListRequest, + opts ...option.RequestOption, +) (*acs.EntrancesListResponse, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "acs/entrances/list" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -171,7 +211,9 @@ func (c *Client) List(ctx context.Context, request *acs.EntrancesListRequest) (* &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -182,13 +224,24 @@ func (c *Client) List(ctx context.Context, request *acs.EntrancesListRequest) (* return response, nil } -func (c *Client) ListCredentialsWithAccess(ctx context.Context, request *acs.EntrancesListCredentialsWithAccessRequest) (*acs.EntrancesListCredentialsWithAccessResponse, error) { +func (c *Client) ListCredentialsWithAccess( + ctx context.Context, + request *acs.EntrancesListCredentialsWithAccessRequest, + opts ...option.RequestOption, +) (*acs.EntrancesListCredentialsWithAccessResponse, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "acs/entrances/list_credentials_with_access" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -221,7 +274,9 @@ func (c *Client) ListCredentialsWithAccess(ctx context.Context, request *acs.Ent &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, diff --git a/acs/systems.go b/acs/systems.go index 459dff6..6cda956 100644 --- a/acs/systems.go +++ b/acs/systems.go @@ -10,16 +10,16 @@ import ( ) type SystemsGetRequest struct { - AcsSystemId string `json:"acs_system_id"` + AcsSystemId string `json:"acs_system_id" url:"acs_system_id"` } type SystemsListRequest struct { - ConnectedAccountId *string `json:"connected_account_id,omitempty"` + ConnectedAccountId *string `json:"connected_account_id,omitempty" url:"connected_account_id,omitempty"` } type SystemsGetResponse struct { - AcsSystem *seamapigo.AcsSystem `json:"acs_system,omitempty"` - Ok bool `json:"ok"` + AcsSystem *seamapigo.AcsSystem `json:"acs_system,omitempty" url:"acs_system,omitempty"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -48,8 +48,8 @@ func (s *SystemsGetResponse) String() string { } type SystemsListResponse struct { - AcsSystems []*seamapigo.AcsSystem `json:"acs_systems,omitempty"` - Ok bool `json:"ok"` + AcsSystems []*seamapigo.AcsSystem `json:"acs_systems,omitempty" url:"acs_systems,omitempty"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } diff --git a/acs/systems/client.go b/acs/systems/client.go index f7d5b16..45a9d14 100644 --- a/acs/systems/client.go +++ b/acs/systems/client.go @@ -10,6 +10,7 @@ import ( seamapigo "github.com/seamapi/go" acs "github.com/seamapi/go/acs" core "github.com/seamapi/go/core" + option "github.com/seamapi/go/option" io "io" http "net/http" ) @@ -20,25 +21,38 @@ type Client struct { header http.Header } -func NewClient(opts ...core.ClientOption) *Client { - options := core.NewClientOptions() - for _, opt := range opts { - opt(options) - } +func NewClient(opts ...option.RequestOption) *Client { + options := core.NewRequestOptions(opts...) return &Client{ baseURL: options.BaseURL, - caller: core.NewCaller(options.HTTPClient), - header: options.ToHeader(), + caller: core.NewCaller( + &core.CallerParams{ + Client: options.HTTPClient, + MaxAttempts: options.MaxAttempts, + }, + ), + header: options.ToHeader(), } } -func (c *Client) Get(ctx context.Context, request *acs.SystemsGetRequest) (*acs.SystemsGetResponse, error) { +func (c *Client) Get( + ctx context.Context, + request *acs.SystemsGetRequest, + opts ...option.RequestOption, +) (*acs.SystemsGetResponse, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "acs/systems/get" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -71,7 +85,9 @@ func (c *Client) Get(ctx context.Context, request *acs.SystemsGetRequest) (*acs. &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -82,13 +98,24 @@ func (c *Client) Get(ctx context.Context, request *acs.SystemsGetRequest) (*acs. return response, nil } -func (c *Client) List(ctx context.Context, request *acs.SystemsListRequest) (*acs.SystemsListResponse, error) { +func (c *Client) List( + ctx context.Context, + request *acs.SystemsListRequest, + opts ...option.RequestOption, +) (*acs.SystemsListResponse, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "acs/systems/list" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -121,7 +148,9 @@ func (c *Client) List(ctx context.Context, request *acs.SystemsListRequest) (*ac &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, diff --git a/acs/types.go b/acs/types.go index 6530a35..e2fa740 100644 --- a/acs/types.go +++ b/acs/types.go @@ -10,12 +10,12 @@ import ( ) type CredentialPoolsListResponseAcsCredentialPoolsItem struct { - AcsCredentialPoolId string `json:"acs_credential_pool_id"` - AcsSystemId string `json:"acs_system_id"` - DisplayName string `json:"display_name"` - ExternalTypeDisplayName string `json:"external_type_display_name"` - CreatedAt time.Time `json:"created_at"` - WorkspaceId string `json:"workspace_id"` + AcsCredentialPoolId string `json:"acs_credential_pool_id" url:"acs_credential_pool_id"` + AcsSystemId string `json:"acs_system_id" url:"acs_system_id"` + DisplayName string `json:"display_name" url:"display_name"` + ExternalTypeDisplayName string `json:"external_type_display_name" url:"external_type_display_name"` + CreatedAt time.Time `json:"created_at" url:"created_at"` + WorkspaceId string `json:"workspace_id" url:"workspace_id"` externalType string _rawJSON json.RawMessage @@ -26,12 +26,18 @@ func (c *CredentialPoolsListResponseAcsCredentialPoolsItem) ExternalType() strin } func (c *CredentialPoolsListResponseAcsCredentialPoolsItem) UnmarshalJSON(data []byte) error { - type unmarshaler CredentialPoolsListResponseAcsCredentialPoolsItem - var value unmarshaler - if err := json.Unmarshal(data, &value); err != nil { + type embed CredentialPoolsListResponseAcsCredentialPoolsItem + var unmarshaler = struct { + embed + CreatedAt *core.DateTime `json:"created_at"` + }{ + embed: embed(*c), + } + if err := json.Unmarshal(data, &unmarshaler); err != nil { return err } - *c = CredentialPoolsListResponseAcsCredentialPoolsItem(value) + *c = CredentialPoolsListResponseAcsCredentialPoolsItem(unmarshaler.embed) + c.CreatedAt = unmarshaler.CreatedAt.Time() c.externalType = "hid_part_number" c._rawJSON = json.RawMessage(data) return nil @@ -41,9 +47,11 @@ func (c *CredentialPoolsListResponseAcsCredentialPoolsItem) MarshalJSON() ([]byt type embed CredentialPoolsListResponseAcsCredentialPoolsItem var marshaler = struct { embed - ExternalType string `json:"external_type"` + CreatedAt *core.DateTime `json:"created_at"` + ExternalType string `json:"external_type"` }{ embed: embed(*c), + CreatedAt: core.NewDateTime(c.CreatedAt), ExternalType: "hid_part_number", } return json.Marshal(marshaler) @@ -62,26 +70,44 @@ func (c *CredentialPoolsListResponseAcsCredentialPoolsItem) String() string { } type CredentialProvisioningAutomationsLaunchResponseAcsCredentialProvisioningAutomation struct { - AcsCredentialProvisioningAutomationId string `json:"acs_credential_provisioning_automation_id"` - CredentialManagerAcsSystemId string `json:"credential_manager_acs_system_id"` - UserIdentityId string `json:"user_identity_id"` - CreatedAt time.Time `json:"created_at"` - WorkspaceId string `json:"workspace_id"` + AcsCredentialProvisioningAutomationId string `json:"acs_credential_provisioning_automation_id" url:"acs_credential_provisioning_automation_id"` + CredentialManagerAcsSystemId string `json:"credential_manager_acs_system_id" url:"credential_manager_acs_system_id"` + UserIdentityId string `json:"user_identity_id" url:"user_identity_id"` + CreatedAt time.Time `json:"created_at" url:"created_at"` + WorkspaceId string `json:"workspace_id" url:"workspace_id"` _rawJSON json.RawMessage } func (c *CredentialProvisioningAutomationsLaunchResponseAcsCredentialProvisioningAutomation) UnmarshalJSON(data []byte) error { - type unmarshaler CredentialProvisioningAutomationsLaunchResponseAcsCredentialProvisioningAutomation - var value unmarshaler - if err := json.Unmarshal(data, &value); err != nil { + type embed CredentialProvisioningAutomationsLaunchResponseAcsCredentialProvisioningAutomation + var unmarshaler = struct { + embed + CreatedAt *core.DateTime `json:"created_at"` + }{ + embed: embed(*c), + } + if err := json.Unmarshal(data, &unmarshaler); err != nil { return err } - *c = CredentialProvisioningAutomationsLaunchResponseAcsCredentialProvisioningAutomation(value) + *c = CredentialProvisioningAutomationsLaunchResponseAcsCredentialProvisioningAutomation(unmarshaler.embed) + c.CreatedAt = unmarshaler.CreatedAt.Time() c._rawJSON = json.RawMessage(data) return nil } +func (c *CredentialProvisioningAutomationsLaunchResponseAcsCredentialProvisioningAutomation) MarshalJSON() ([]byte, error) { + type embed CredentialProvisioningAutomationsLaunchResponseAcsCredentialProvisioningAutomation + var marshaler = struct { + embed + CreatedAt *core.DateTime `json:"created_at"` + }{ + embed: embed(*c), + CreatedAt: core.NewDateTime(c.CreatedAt), + } + return json.Marshal(marshaler) +} + func (c *CredentialProvisioningAutomationsLaunchResponseAcsCredentialProvisioningAutomation) String() string { if len(c._rawJSON) > 0 { if value, err := core.StringifyJSON(c._rawJSON); err == nil { @@ -95,39 +121,57 @@ func (c *CredentialProvisioningAutomationsLaunchResponseAcsCredentialProvisionin } type CredentialsAssignResponseAcsCredential struct { - AcsCredentialId string `json:"acs_credential_id"` - AcsUserId *string `json:"acs_user_id,omitempty"` - AcsCredentialPoolId *string `json:"acs_credential_pool_id,omitempty"` - AcsSystemId string `json:"acs_system_id"` - ParentAcsCredentialId *string `json:"parent_acs_credential_id,omitempty"` - DisplayName string `json:"display_name"` - Code *string `json:"code,omitempty"` - AccessMethod CredentialsAssignResponseAcsCredentialAccessMethod `json:"access_method,omitempty"` - ExternalType *CredentialsAssignResponseAcsCredentialExternalType `json:"external_type,omitempty"` - ExternalTypeDisplayName *string `json:"external_type_display_name,omitempty"` - CreatedAt time.Time `json:"created_at"` - WorkspaceId string `json:"workspace_id"` - StartsAt *string `json:"starts_at,omitempty"` - EndsAt *string `json:"ends_at,omitempty"` - Errors []*CredentialsAssignResponseAcsCredentialErrorsItem `json:"errors,omitempty"` - Warnings []*CredentialsAssignResponseAcsCredentialWarningsItem `json:"warnings,omitempty"` - IsMultiPhoneSyncCredential *bool `json:"is_multi_phone_sync_credential,omitempty"` - VisionlineMetadata *CredentialsAssignResponseAcsCredentialVisionlineMetadata `json:"visionline_metadata,omitempty"` + AcsCredentialId string `json:"acs_credential_id" url:"acs_credential_id"` + AcsUserId *string `json:"acs_user_id,omitempty" url:"acs_user_id,omitempty"` + AcsCredentialPoolId *string `json:"acs_credential_pool_id,omitempty" url:"acs_credential_pool_id,omitempty"` + AcsSystemId string `json:"acs_system_id" url:"acs_system_id"` + ParentAcsCredentialId *string `json:"parent_acs_credential_id,omitempty" url:"parent_acs_credential_id,omitempty"` + DisplayName string `json:"display_name" url:"display_name"` + Code *string `json:"code,omitempty" url:"code,omitempty"` + AccessMethod CredentialsAssignResponseAcsCredentialAccessMethod `json:"access_method,omitempty" url:"access_method,omitempty"` + ExternalType *CredentialsAssignResponseAcsCredentialExternalType `json:"external_type,omitempty" url:"external_type,omitempty"` + ExternalTypeDisplayName *string `json:"external_type_display_name,omitempty" url:"external_type_display_name,omitempty"` + CreatedAt time.Time `json:"created_at" url:"created_at"` + WorkspaceId string `json:"workspace_id" url:"workspace_id"` + StartsAt *string `json:"starts_at,omitempty" url:"starts_at,omitempty"` + EndsAt *string `json:"ends_at,omitempty" url:"ends_at,omitempty"` + Errors []*CredentialsAssignResponseAcsCredentialErrorsItem `json:"errors,omitempty" url:"errors,omitempty"` + Warnings []*CredentialsAssignResponseAcsCredentialWarningsItem `json:"warnings,omitempty" url:"warnings,omitempty"` + IsMultiPhoneSyncCredential *bool `json:"is_multi_phone_sync_credential,omitempty" url:"is_multi_phone_sync_credential,omitempty"` + VisionlineMetadata *CredentialsAssignResponseAcsCredentialVisionlineMetadata `json:"visionline_metadata,omitempty" url:"visionline_metadata,omitempty"` _rawJSON json.RawMessage } func (c *CredentialsAssignResponseAcsCredential) UnmarshalJSON(data []byte) error { - type unmarshaler CredentialsAssignResponseAcsCredential - var value unmarshaler - if err := json.Unmarshal(data, &value); err != nil { + type embed CredentialsAssignResponseAcsCredential + var unmarshaler = struct { + embed + CreatedAt *core.DateTime `json:"created_at"` + }{ + embed: embed(*c), + } + if err := json.Unmarshal(data, &unmarshaler); err != nil { return err } - *c = CredentialsAssignResponseAcsCredential(value) + *c = CredentialsAssignResponseAcsCredential(unmarshaler.embed) + c.CreatedAt = unmarshaler.CreatedAt.Time() c._rawJSON = json.RawMessage(data) return nil } +func (c *CredentialsAssignResponseAcsCredential) MarshalJSON() ([]byte, error) { + type embed CredentialsAssignResponseAcsCredential + var marshaler = struct { + embed + CreatedAt *core.DateTime `json:"created_at"` + }{ + embed: embed(*c), + CreatedAt: core.NewDateTime(c.CreatedAt), + } + return json.Marshal(marshaler) +} + func (c *CredentialsAssignResponseAcsCredential) String() string { if len(c._rawJSON) > 0 { if value, err := core.StringifyJSON(c._rawJSON); err == nil { @@ -166,8 +210,8 @@ func (c CredentialsAssignResponseAcsCredentialAccessMethod) Ptr() *CredentialsAs } type CredentialsAssignResponseAcsCredentialErrorsItem struct { - ErrorCode string `json:"error_code"` - Message string `json:"message"` + ErrorCode string `json:"error_code" url:"error_code"` + Message string `json:"message" url:"message"` _rawJSON json.RawMessage } @@ -224,9 +268,9 @@ func (c CredentialsAssignResponseAcsCredentialExternalType) Ptr() *CredentialsAs } type CredentialsAssignResponseAcsCredentialVisionlineMetadata struct { - JoinerAcsCredentialIds []string `json:"joiner_acs_credential_ids,omitempty"` - GuestAcsEntranceIds []string `json:"guest_acs_entrance_ids,omitempty"` - CommonAcsEntranceIds []string `json:"common_acs_entrance_ids,omitempty"` + JoinerAcsCredentialIds []string `json:"joiner_acs_credential_ids,omitempty" url:"joiner_acs_credential_ids,omitempty"` + GuestAcsEntranceIds []string `json:"guest_acs_entrance_ids,omitempty" url:"guest_acs_entrance_ids,omitempty"` + CommonAcsEntranceIds []string `json:"common_acs_entrance_ids,omitempty" url:"common_acs_entrance_ids,omitempty"` _rawJSON json.RawMessage } @@ -255,8 +299,8 @@ func (c *CredentialsAssignResponseAcsCredentialVisionlineMetadata) String() stri } type CredentialsAssignResponseAcsCredentialWarningsItem struct { - WarningCode string `json:"warning_code"` - Message string `json:"message"` + WarningCode string `json:"warning_code" url:"warning_code"` + Message string `json:"message" url:"message"` _rawJSON json.RawMessage } @@ -307,39 +351,57 @@ func (c CredentialsCreateRequestVisionlineMetadataCardFormat) Ptr() *Credentials } type CredentialsCreateResponseAcsCredential struct { - AcsCredentialId string `json:"acs_credential_id"` - AcsUserId *string `json:"acs_user_id,omitempty"` - AcsCredentialPoolId *string `json:"acs_credential_pool_id,omitempty"` - AcsSystemId string `json:"acs_system_id"` - ParentAcsCredentialId *string `json:"parent_acs_credential_id,omitempty"` - DisplayName string `json:"display_name"` - Code *string `json:"code,omitempty"` - AccessMethod CredentialsCreateResponseAcsCredentialAccessMethod `json:"access_method,omitempty"` - ExternalType *CredentialsCreateResponseAcsCredentialExternalType `json:"external_type,omitempty"` - ExternalTypeDisplayName *string `json:"external_type_display_name,omitempty"` - CreatedAt time.Time `json:"created_at"` - WorkspaceId string `json:"workspace_id"` - StartsAt *string `json:"starts_at,omitempty"` - EndsAt *string `json:"ends_at,omitempty"` - Errors []*CredentialsCreateResponseAcsCredentialErrorsItem `json:"errors,omitempty"` - Warnings []*CredentialsCreateResponseAcsCredentialWarningsItem `json:"warnings,omitempty"` - IsMultiPhoneSyncCredential *bool `json:"is_multi_phone_sync_credential,omitempty"` - VisionlineMetadata *CredentialsCreateResponseAcsCredentialVisionlineMetadata `json:"visionline_metadata,omitempty"` + AcsCredentialId string `json:"acs_credential_id" url:"acs_credential_id"` + AcsUserId *string `json:"acs_user_id,omitempty" url:"acs_user_id,omitempty"` + AcsCredentialPoolId *string `json:"acs_credential_pool_id,omitempty" url:"acs_credential_pool_id,omitempty"` + AcsSystemId string `json:"acs_system_id" url:"acs_system_id"` + ParentAcsCredentialId *string `json:"parent_acs_credential_id,omitempty" url:"parent_acs_credential_id,omitempty"` + DisplayName string `json:"display_name" url:"display_name"` + Code *string `json:"code,omitempty" url:"code,omitempty"` + AccessMethod CredentialsCreateResponseAcsCredentialAccessMethod `json:"access_method,omitempty" url:"access_method,omitempty"` + ExternalType *CredentialsCreateResponseAcsCredentialExternalType `json:"external_type,omitempty" url:"external_type,omitempty"` + ExternalTypeDisplayName *string `json:"external_type_display_name,omitempty" url:"external_type_display_name,omitempty"` + CreatedAt time.Time `json:"created_at" url:"created_at"` + WorkspaceId string `json:"workspace_id" url:"workspace_id"` + StartsAt *string `json:"starts_at,omitempty" url:"starts_at,omitempty"` + EndsAt *string `json:"ends_at,omitempty" url:"ends_at,omitempty"` + Errors []*CredentialsCreateResponseAcsCredentialErrorsItem `json:"errors,omitempty" url:"errors,omitempty"` + Warnings []*CredentialsCreateResponseAcsCredentialWarningsItem `json:"warnings,omitempty" url:"warnings,omitempty"` + IsMultiPhoneSyncCredential *bool `json:"is_multi_phone_sync_credential,omitempty" url:"is_multi_phone_sync_credential,omitempty"` + VisionlineMetadata *CredentialsCreateResponseAcsCredentialVisionlineMetadata `json:"visionline_metadata,omitempty" url:"visionline_metadata,omitempty"` _rawJSON json.RawMessage } func (c *CredentialsCreateResponseAcsCredential) UnmarshalJSON(data []byte) error { - type unmarshaler CredentialsCreateResponseAcsCredential - var value unmarshaler - if err := json.Unmarshal(data, &value); err != nil { + type embed CredentialsCreateResponseAcsCredential + var unmarshaler = struct { + embed + CreatedAt *core.DateTime `json:"created_at"` + }{ + embed: embed(*c), + } + if err := json.Unmarshal(data, &unmarshaler); err != nil { return err } - *c = CredentialsCreateResponseAcsCredential(value) + *c = CredentialsCreateResponseAcsCredential(unmarshaler.embed) + c.CreatedAt = unmarshaler.CreatedAt.Time() c._rawJSON = json.RawMessage(data) return nil } +func (c *CredentialsCreateResponseAcsCredential) MarshalJSON() ([]byte, error) { + type embed CredentialsCreateResponseAcsCredential + var marshaler = struct { + embed + CreatedAt *core.DateTime `json:"created_at"` + }{ + embed: embed(*c), + CreatedAt: core.NewDateTime(c.CreatedAt), + } + return json.Marshal(marshaler) +} + func (c *CredentialsCreateResponseAcsCredential) String() string { if len(c._rawJSON) > 0 { if value, err := core.StringifyJSON(c._rawJSON); err == nil { @@ -378,8 +440,8 @@ func (c CredentialsCreateResponseAcsCredentialAccessMethod) Ptr() *CredentialsCr } type CredentialsCreateResponseAcsCredentialErrorsItem struct { - ErrorCode string `json:"error_code"` - Message string `json:"message"` + ErrorCode string `json:"error_code" url:"error_code"` + Message string `json:"message" url:"message"` _rawJSON json.RawMessage } @@ -436,9 +498,9 @@ func (c CredentialsCreateResponseAcsCredentialExternalType) Ptr() *CredentialsCr } type CredentialsCreateResponseAcsCredentialVisionlineMetadata struct { - JoinerAcsCredentialIds []string `json:"joiner_acs_credential_ids,omitempty"` - GuestAcsEntranceIds []string `json:"guest_acs_entrance_ids,omitempty"` - CommonAcsEntranceIds []string `json:"common_acs_entrance_ids,omitempty"` + JoinerAcsCredentialIds []string `json:"joiner_acs_credential_ids,omitempty" url:"joiner_acs_credential_ids,omitempty"` + GuestAcsEntranceIds []string `json:"guest_acs_entrance_ids,omitempty" url:"guest_acs_entrance_ids,omitempty"` + CommonAcsEntranceIds []string `json:"common_acs_entrance_ids,omitempty" url:"common_acs_entrance_ids,omitempty"` _rawJSON json.RawMessage } @@ -467,8 +529,8 @@ func (c *CredentialsCreateResponseAcsCredentialVisionlineMetadata) String() stri } type CredentialsCreateResponseAcsCredentialWarningsItem struct { - WarningCode string `json:"warning_code"` - Message string `json:"message"` + WarningCode string `json:"warning_code" url:"warning_code"` + Message string `json:"message" url:"message"` _rawJSON json.RawMessage } @@ -497,39 +559,57 @@ func (c *CredentialsCreateResponseAcsCredentialWarningsItem) String() string { } type CredentialsGetResponseAcsCredential struct { - AcsCredentialId string `json:"acs_credential_id"` - AcsUserId *string `json:"acs_user_id,omitempty"` - AcsCredentialPoolId *string `json:"acs_credential_pool_id,omitempty"` - AcsSystemId string `json:"acs_system_id"` - ParentAcsCredentialId *string `json:"parent_acs_credential_id,omitempty"` - DisplayName string `json:"display_name"` - Code *string `json:"code,omitempty"` - AccessMethod CredentialsGetResponseAcsCredentialAccessMethod `json:"access_method,omitempty"` - ExternalType *CredentialsGetResponseAcsCredentialExternalType `json:"external_type,omitempty"` - ExternalTypeDisplayName *string `json:"external_type_display_name,omitempty"` - CreatedAt time.Time `json:"created_at"` - WorkspaceId string `json:"workspace_id"` - StartsAt *string `json:"starts_at,omitempty"` - EndsAt *string `json:"ends_at,omitempty"` - Errors []*CredentialsGetResponseAcsCredentialErrorsItem `json:"errors,omitempty"` - Warnings []*CredentialsGetResponseAcsCredentialWarningsItem `json:"warnings,omitempty"` - IsMultiPhoneSyncCredential *bool `json:"is_multi_phone_sync_credential,omitempty"` - VisionlineMetadata *CredentialsGetResponseAcsCredentialVisionlineMetadata `json:"visionline_metadata,omitempty"` + AcsCredentialId string `json:"acs_credential_id" url:"acs_credential_id"` + AcsUserId *string `json:"acs_user_id,omitempty" url:"acs_user_id,omitempty"` + AcsCredentialPoolId *string `json:"acs_credential_pool_id,omitempty" url:"acs_credential_pool_id,omitempty"` + AcsSystemId string `json:"acs_system_id" url:"acs_system_id"` + ParentAcsCredentialId *string `json:"parent_acs_credential_id,omitempty" url:"parent_acs_credential_id,omitempty"` + DisplayName string `json:"display_name" url:"display_name"` + Code *string `json:"code,omitempty" url:"code,omitempty"` + AccessMethod CredentialsGetResponseAcsCredentialAccessMethod `json:"access_method,omitempty" url:"access_method,omitempty"` + ExternalType *CredentialsGetResponseAcsCredentialExternalType `json:"external_type,omitempty" url:"external_type,omitempty"` + ExternalTypeDisplayName *string `json:"external_type_display_name,omitempty" url:"external_type_display_name,omitempty"` + CreatedAt time.Time `json:"created_at" url:"created_at"` + WorkspaceId string `json:"workspace_id" url:"workspace_id"` + StartsAt *string `json:"starts_at,omitempty" url:"starts_at,omitempty"` + EndsAt *string `json:"ends_at,omitempty" url:"ends_at,omitempty"` + Errors []*CredentialsGetResponseAcsCredentialErrorsItem `json:"errors,omitempty" url:"errors,omitempty"` + Warnings []*CredentialsGetResponseAcsCredentialWarningsItem `json:"warnings,omitempty" url:"warnings,omitempty"` + IsMultiPhoneSyncCredential *bool `json:"is_multi_phone_sync_credential,omitempty" url:"is_multi_phone_sync_credential,omitempty"` + VisionlineMetadata *CredentialsGetResponseAcsCredentialVisionlineMetadata `json:"visionline_metadata,omitempty" url:"visionline_metadata,omitempty"` _rawJSON json.RawMessage } func (c *CredentialsGetResponseAcsCredential) UnmarshalJSON(data []byte) error { - type unmarshaler CredentialsGetResponseAcsCredential - var value unmarshaler - if err := json.Unmarshal(data, &value); err != nil { + type embed CredentialsGetResponseAcsCredential + var unmarshaler = struct { + embed + CreatedAt *core.DateTime `json:"created_at"` + }{ + embed: embed(*c), + } + if err := json.Unmarshal(data, &unmarshaler); err != nil { return err } - *c = CredentialsGetResponseAcsCredential(value) + *c = CredentialsGetResponseAcsCredential(unmarshaler.embed) + c.CreatedAt = unmarshaler.CreatedAt.Time() c._rawJSON = json.RawMessage(data) return nil } +func (c *CredentialsGetResponseAcsCredential) MarshalJSON() ([]byte, error) { + type embed CredentialsGetResponseAcsCredential + var marshaler = struct { + embed + CreatedAt *core.DateTime `json:"created_at"` + }{ + embed: embed(*c), + CreatedAt: core.NewDateTime(c.CreatedAt), + } + return json.Marshal(marshaler) +} + func (c *CredentialsGetResponseAcsCredential) String() string { if len(c._rawJSON) > 0 { if value, err := core.StringifyJSON(c._rawJSON); err == nil { @@ -568,8 +648,8 @@ func (c CredentialsGetResponseAcsCredentialAccessMethod) Ptr() *CredentialsGetRe } type CredentialsGetResponseAcsCredentialErrorsItem struct { - ErrorCode string `json:"error_code"` - Message string `json:"message"` + ErrorCode string `json:"error_code" url:"error_code"` + Message string `json:"message" url:"message"` _rawJSON json.RawMessage } @@ -626,9 +706,9 @@ func (c CredentialsGetResponseAcsCredentialExternalType) Ptr() *CredentialsGetRe } type CredentialsGetResponseAcsCredentialVisionlineMetadata struct { - JoinerAcsCredentialIds []string `json:"joiner_acs_credential_ids,omitempty"` - GuestAcsEntranceIds []string `json:"guest_acs_entrance_ids,omitempty"` - CommonAcsEntranceIds []string `json:"common_acs_entrance_ids,omitempty"` + JoinerAcsCredentialIds []string `json:"joiner_acs_credential_ids,omitempty" url:"joiner_acs_credential_ids,omitempty"` + GuestAcsEntranceIds []string `json:"guest_acs_entrance_ids,omitempty" url:"guest_acs_entrance_ids,omitempty"` + CommonAcsEntranceIds []string `json:"common_acs_entrance_ids,omitempty" url:"common_acs_entrance_ids,omitempty"` _rawJSON json.RawMessage } @@ -657,8 +737,8 @@ func (c *CredentialsGetResponseAcsCredentialVisionlineMetadata) String() string } type CredentialsGetResponseAcsCredentialWarningsItem struct { - WarningCode string `json:"warning_code"` - Message string `json:"message"` + WarningCode string `json:"warning_code" url:"warning_code"` + Message string `json:"message" url:"message"` _rawJSON json.RawMessage } @@ -686,155 +766,56 @@ func (c *CredentialsGetResponseAcsCredentialWarningsItem) String() string { return fmt.Sprintf("%#v", c) } -type CredentialsListRequestOne struct { - AcsSystemId string `json:"acs_system_id"` - - _rawJSON json.RawMessage -} - -func (c *CredentialsListRequestOne) UnmarshalJSON(data []byte) error { - type unmarshaler CredentialsListRequestOne - var value unmarshaler - if err := json.Unmarshal(data, &value); err != nil { - return err - } - *c = CredentialsListRequestOne(value) - c._rawJSON = json.RawMessage(data) - return nil -} - -func (c *CredentialsListRequestOne) String() string { - if len(c._rawJSON) > 0 { - if value, err := core.StringifyJSON(c._rawJSON); err == nil { - return value - } - } - if value, err := core.StringifyJSON(c); err == nil { - return value - } - return fmt.Sprintf("%#v", c) -} - -type CredentialsListRequestTwo struct { - AcsUserId string `json:"acs_user_id"` - AcsSystemId string `json:"acs_system_id"` - - _rawJSON json.RawMessage -} - -func (c *CredentialsListRequestTwo) UnmarshalJSON(data []byte) error { - type unmarshaler CredentialsListRequestTwo - var value unmarshaler - if err := json.Unmarshal(data, &value); err != nil { - return err - } - *c = CredentialsListRequestTwo(value) - c._rawJSON = json.RawMessage(data) - return nil -} - -func (c *CredentialsListRequestTwo) String() string { - if len(c._rawJSON) > 0 { - if value, err := core.StringifyJSON(c._rawJSON); err == nil { - return value - } - } - if value, err := core.StringifyJSON(c); err == nil { - return value - } - return fmt.Sprintf("%#v", c) -} - -type CredentialsListRequestUserIdentityId struct { - UserIdentityId string `json:"user_identity_id"` +type CredentialsListResponseAcsCredentialsItem struct { + AcsCredentialId string `json:"acs_credential_id" url:"acs_credential_id"` + AcsUserId *string `json:"acs_user_id,omitempty" url:"acs_user_id,omitempty"` + AcsCredentialPoolId *string `json:"acs_credential_pool_id,omitempty" url:"acs_credential_pool_id,omitempty"` + AcsSystemId string `json:"acs_system_id" url:"acs_system_id"` + ParentAcsCredentialId *string `json:"parent_acs_credential_id,omitempty" url:"parent_acs_credential_id,omitempty"` + DisplayName string `json:"display_name" url:"display_name"` + Code *string `json:"code,omitempty" url:"code,omitempty"` + AccessMethod CredentialsListResponseAcsCredentialsItemAccessMethod `json:"access_method,omitempty" url:"access_method,omitempty"` + ExternalType *CredentialsListResponseAcsCredentialsItemExternalType `json:"external_type,omitempty" url:"external_type,omitempty"` + ExternalTypeDisplayName *string `json:"external_type_display_name,omitempty" url:"external_type_display_name,omitempty"` + CreatedAt time.Time `json:"created_at" url:"created_at"` + WorkspaceId string `json:"workspace_id" url:"workspace_id"` + StartsAt *string `json:"starts_at,omitempty" url:"starts_at,omitempty"` + EndsAt *string `json:"ends_at,omitempty" url:"ends_at,omitempty"` + Errors []*CredentialsListResponseAcsCredentialsItemErrorsItem `json:"errors,omitempty" url:"errors,omitempty"` + Warnings []*CredentialsListResponseAcsCredentialsItemWarningsItem `json:"warnings,omitempty" url:"warnings,omitempty"` + IsMultiPhoneSyncCredential *bool `json:"is_multi_phone_sync_credential,omitempty" url:"is_multi_phone_sync_credential,omitempty"` + VisionlineMetadata *CredentialsListResponseAcsCredentialsItemVisionlineMetadata `json:"visionline_metadata,omitempty" url:"visionline_metadata,omitempty"` _rawJSON json.RawMessage } -func (c *CredentialsListRequestUserIdentityId) UnmarshalJSON(data []byte) error { - type unmarshaler CredentialsListRequestUserIdentityId - var value unmarshaler - if err := json.Unmarshal(data, &value); err != nil { - return err - } - *c = CredentialsListRequestUserIdentityId(value) - c._rawJSON = json.RawMessage(data) - return nil -} - -func (c *CredentialsListRequestUserIdentityId) String() string { - if len(c._rawJSON) > 0 { - if value, err := core.StringifyJSON(c._rawJSON); err == nil { - return value - } - } - if value, err := core.StringifyJSON(c); err == nil { - return value +func (c *CredentialsListResponseAcsCredentialsItem) UnmarshalJSON(data []byte) error { + type embed CredentialsListResponseAcsCredentialsItem + var unmarshaler = struct { + embed + CreatedAt *core.DateTime `json:"created_at"` + }{ + embed: embed(*c), } - return fmt.Sprintf("%#v", c) -} - -type CredentialsListRequestZero struct { - AcsUserId string `json:"acs_user_id"` - - _rawJSON json.RawMessage -} - -func (c *CredentialsListRequestZero) UnmarshalJSON(data []byte) error { - type unmarshaler CredentialsListRequestZero - var value unmarshaler - if err := json.Unmarshal(data, &value); err != nil { + if err := json.Unmarshal(data, &unmarshaler); err != nil { return err } - *c = CredentialsListRequestZero(value) + *c = CredentialsListResponseAcsCredentialsItem(unmarshaler.embed) + c.CreatedAt = unmarshaler.CreatedAt.Time() c._rawJSON = json.RawMessage(data) return nil } -func (c *CredentialsListRequestZero) String() string { - if len(c._rawJSON) > 0 { - if value, err := core.StringifyJSON(c._rawJSON); err == nil { - return value - } - } - if value, err := core.StringifyJSON(c); err == nil { - return value - } - return fmt.Sprintf("%#v", c) -} - -type CredentialsListResponseAcsCredentialsItem struct { - AcsCredentialId string `json:"acs_credential_id"` - AcsUserId *string `json:"acs_user_id,omitempty"` - AcsCredentialPoolId *string `json:"acs_credential_pool_id,omitempty"` - AcsSystemId string `json:"acs_system_id"` - ParentAcsCredentialId *string `json:"parent_acs_credential_id,omitempty"` - DisplayName string `json:"display_name"` - Code *string `json:"code,omitempty"` - AccessMethod CredentialsListResponseAcsCredentialsItemAccessMethod `json:"access_method,omitempty"` - ExternalType *CredentialsListResponseAcsCredentialsItemExternalType `json:"external_type,omitempty"` - ExternalTypeDisplayName *string `json:"external_type_display_name,omitempty"` - CreatedAt time.Time `json:"created_at"` - WorkspaceId string `json:"workspace_id"` - StartsAt *string `json:"starts_at,omitempty"` - EndsAt *string `json:"ends_at,omitempty"` - Errors []*CredentialsListResponseAcsCredentialsItemErrorsItem `json:"errors,omitempty"` - Warnings []*CredentialsListResponseAcsCredentialsItemWarningsItem `json:"warnings,omitempty"` - IsMultiPhoneSyncCredential *bool `json:"is_multi_phone_sync_credential,omitempty"` - VisionlineMetadata *CredentialsListResponseAcsCredentialsItemVisionlineMetadata `json:"visionline_metadata,omitempty"` - - _rawJSON json.RawMessage -} - -func (c *CredentialsListResponseAcsCredentialsItem) UnmarshalJSON(data []byte) error { - type unmarshaler CredentialsListResponseAcsCredentialsItem - var value unmarshaler - if err := json.Unmarshal(data, &value); err != nil { - return err +func (c *CredentialsListResponseAcsCredentialsItem) MarshalJSON() ([]byte, error) { + type embed CredentialsListResponseAcsCredentialsItem + var marshaler = struct { + embed + CreatedAt *core.DateTime `json:"created_at"` + }{ + embed: embed(*c), + CreatedAt: core.NewDateTime(c.CreatedAt), } - *c = CredentialsListResponseAcsCredentialsItem(value) - c._rawJSON = json.RawMessage(data) - return nil + return json.Marshal(marshaler) } func (c *CredentialsListResponseAcsCredentialsItem) String() string { @@ -875,8 +856,8 @@ func (c CredentialsListResponseAcsCredentialsItemAccessMethod) Ptr() *Credential } type CredentialsListResponseAcsCredentialsItemErrorsItem struct { - ErrorCode string `json:"error_code"` - Message string `json:"message"` + ErrorCode string `json:"error_code" url:"error_code"` + Message string `json:"message" url:"message"` _rawJSON json.RawMessage } @@ -933,9 +914,9 @@ func (c CredentialsListResponseAcsCredentialsItemExternalType) Ptr() *Credential } type CredentialsListResponseAcsCredentialsItemVisionlineMetadata struct { - JoinerAcsCredentialIds []string `json:"joiner_acs_credential_ids,omitempty"` - GuestAcsEntranceIds []string `json:"guest_acs_entrance_ids,omitempty"` - CommonAcsEntranceIds []string `json:"common_acs_entrance_ids,omitempty"` + JoinerAcsCredentialIds []string `json:"joiner_acs_credential_ids,omitempty" url:"joiner_acs_credential_ids,omitempty"` + GuestAcsEntranceIds []string `json:"guest_acs_entrance_ids,omitempty" url:"guest_acs_entrance_ids,omitempty"` + CommonAcsEntranceIds []string `json:"common_acs_entrance_ids,omitempty" url:"common_acs_entrance_ids,omitempty"` _rawJSON json.RawMessage } @@ -964,8 +945,8 @@ func (c *CredentialsListResponseAcsCredentialsItemVisionlineMetadata) String() s } type CredentialsListResponseAcsCredentialsItemWarningsItem struct { - WarningCode string `json:"warning_code"` - Message string `json:"message"` + WarningCode string `json:"warning_code" url:"warning_code"` + Message string `json:"message" url:"message"` _rawJSON json.RawMessage } @@ -994,39 +975,57 @@ func (c *CredentialsListResponseAcsCredentialsItemWarningsItem) String() string } type CredentialsUnassignResponseAcsCredential struct { - AcsCredentialId string `json:"acs_credential_id"` - AcsUserId *string `json:"acs_user_id,omitempty"` - AcsCredentialPoolId *string `json:"acs_credential_pool_id,omitempty"` - AcsSystemId string `json:"acs_system_id"` - ParentAcsCredentialId *string `json:"parent_acs_credential_id,omitempty"` - DisplayName string `json:"display_name"` - Code *string `json:"code,omitempty"` - AccessMethod CredentialsUnassignResponseAcsCredentialAccessMethod `json:"access_method,omitempty"` - ExternalType *CredentialsUnassignResponseAcsCredentialExternalType `json:"external_type,omitempty"` - ExternalTypeDisplayName *string `json:"external_type_display_name,omitempty"` - CreatedAt time.Time `json:"created_at"` - WorkspaceId string `json:"workspace_id"` - StartsAt *string `json:"starts_at,omitempty"` - EndsAt *string `json:"ends_at,omitempty"` - Errors []*CredentialsUnassignResponseAcsCredentialErrorsItem `json:"errors,omitempty"` - Warnings []*CredentialsUnassignResponseAcsCredentialWarningsItem `json:"warnings,omitempty"` - IsMultiPhoneSyncCredential *bool `json:"is_multi_phone_sync_credential,omitempty"` - VisionlineMetadata *CredentialsUnassignResponseAcsCredentialVisionlineMetadata `json:"visionline_metadata,omitempty"` + AcsCredentialId string `json:"acs_credential_id" url:"acs_credential_id"` + AcsUserId *string `json:"acs_user_id,omitempty" url:"acs_user_id,omitempty"` + AcsCredentialPoolId *string `json:"acs_credential_pool_id,omitempty" url:"acs_credential_pool_id,omitempty"` + AcsSystemId string `json:"acs_system_id" url:"acs_system_id"` + ParentAcsCredentialId *string `json:"parent_acs_credential_id,omitempty" url:"parent_acs_credential_id,omitempty"` + DisplayName string `json:"display_name" url:"display_name"` + Code *string `json:"code,omitempty" url:"code,omitempty"` + AccessMethod CredentialsUnassignResponseAcsCredentialAccessMethod `json:"access_method,omitempty" url:"access_method,omitempty"` + ExternalType *CredentialsUnassignResponseAcsCredentialExternalType `json:"external_type,omitempty" url:"external_type,omitempty"` + ExternalTypeDisplayName *string `json:"external_type_display_name,omitempty" url:"external_type_display_name,omitempty"` + CreatedAt time.Time `json:"created_at" url:"created_at"` + WorkspaceId string `json:"workspace_id" url:"workspace_id"` + StartsAt *string `json:"starts_at,omitempty" url:"starts_at,omitempty"` + EndsAt *string `json:"ends_at,omitempty" url:"ends_at,omitempty"` + Errors []*CredentialsUnassignResponseAcsCredentialErrorsItem `json:"errors,omitempty" url:"errors,omitempty"` + Warnings []*CredentialsUnassignResponseAcsCredentialWarningsItem `json:"warnings,omitempty" url:"warnings,omitempty"` + IsMultiPhoneSyncCredential *bool `json:"is_multi_phone_sync_credential,omitempty" url:"is_multi_phone_sync_credential,omitempty"` + VisionlineMetadata *CredentialsUnassignResponseAcsCredentialVisionlineMetadata `json:"visionline_metadata,omitempty" url:"visionline_metadata,omitempty"` _rawJSON json.RawMessage } func (c *CredentialsUnassignResponseAcsCredential) UnmarshalJSON(data []byte) error { - type unmarshaler CredentialsUnassignResponseAcsCredential - var value unmarshaler - if err := json.Unmarshal(data, &value); err != nil { + type embed CredentialsUnassignResponseAcsCredential + var unmarshaler = struct { + embed + CreatedAt *core.DateTime `json:"created_at"` + }{ + embed: embed(*c), + } + if err := json.Unmarshal(data, &unmarshaler); err != nil { return err } - *c = CredentialsUnassignResponseAcsCredential(value) + *c = CredentialsUnassignResponseAcsCredential(unmarshaler.embed) + c.CreatedAt = unmarshaler.CreatedAt.Time() c._rawJSON = json.RawMessage(data) return nil } +func (c *CredentialsUnassignResponseAcsCredential) MarshalJSON() ([]byte, error) { + type embed CredentialsUnassignResponseAcsCredential + var marshaler = struct { + embed + CreatedAt *core.DateTime `json:"created_at"` + }{ + embed: embed(*c), + CreatedAt: core.NewDateTime(c.CreatedAt), + } + return json.Marshal(marshaler) +} + func (c *CredentialsUnassignResponseAcsCredential) String() string { if len(c._rawJSON) > 0 { if value, err := core.StringifyJSON(c._rawJSON); err == nil { @@ -1065,8 +1064,8 @@ func (c CredentialsUnassignResponseAcsCredentialAccessMethod) Ptr() *Credentials } type CredentialsUnassignResponseAcsCredentialErrorsItem struct { - ErrorCode string `json:"error_code"` - Message string `json:"message"` + ErrorCode string `json:"error_code" url:"error_code"` + Message string `json:"message" url:"message"` _rawJSON json.RawMessage } @@ -1123,9 +1122,9 @@ func (c CredentialsUnassignResponseAcsCredentialExternalType) Ptr() *Credentials } type CredentialsUnassignResponseAcsCredentialVisionlineMetadata struct { - JoinerAcsCredentialIds []string `json:"joiner_acs_credential_ids,omitempty"` - GuestAcsEntranceIds []string `json:"guest_acs_entrance_ids,omitempty"` - CommonAcsEntranceIds []string `json:"common_acs_entrance_ids,omitempty"` + JoinerAcsCredentialIds []string `json:"joiner_acs_credential_ids,omitempty" url:"joiner_acs_credential_ids,omitempty"` + GuestAcsEntranceIds []string `json:"guest_acs_entrance_ids,omitempty" url:"guest_acs_entrance_ids,omitempty"` + CommonAcsEntranceIds []string `json:"common_acs_entrance_ids,omitempty" url:"common_acs_entrance_ids,omitempty"` _rawJSON json.RawMessage } @@ -1154,8 +1153,8 @@ func (c *CredentialsUnassignResponseAcsCredentialVisionlineMetadata) String() st } type CredentialsUnassignResponseAcsCredentialWarningsItem struct { - WarningCode string `json:"warning_code"` - Message string `json:"message"` + WarningCode string `json:"warning_code" url:"warning_code"` + Message string `json:"message" url:"message"` _rawJSON json.RawMessage } @@ -1184,39 +1183,57 @@ func (c *CredentialsUnassignResponseAcsCredentialWarningsItem) String() string { } type CredentialsUpdateResponseAcsCredential struct { - AcsCredentialId string `json:"acs_credential_id"` - AcsUserId *string `json:"acs_user_id,omitempty"` - AcsCredentialPoolId *string `json:"acs_credential_pool_id,omitempty"` - AcsSystemId string `json:"acs_system_id"` - ParentAcsCredentialId *string `json:"parent_acs_credential_id,omitempty"` - DisplayName string `json:"display_name"` - Code *string `json:"code,omitempty"` - AccessMethod CredentialsUpdateResponseAcsCredentialAccessMethod `json:"access_method,omitempty"` - ExternalType *CredentialsUpdateResponseAcsCredentialExternalType `json:"external_type,omitempty"` - ExternalTypeDisplayName *string `json:"external_type_display_name,omitempty"` - CreatedAt time.Time `json:"created_at"` - WorkspaceId string `json:"workspace_id"` - StartsAt *string `json:"starts_at,omitempty"` - EndsAt *string `json:"ends_at,omitempty"` - Errors []*CredentialsUpdateResponseAcsCredentialErrorsItem `json:"errors,omitempty"` - Warnings []*CredentialsUpdateResponseAcsCredentialWarningsItem `json:"warnings,omitempty"` - IsMultiPhoneSyncCredential *bool `json:"is_multi_phone_sync_credential,omitempty"` - VisionlineMetadata *CredentialsUpdateResponseAcsCredentialVisionlineMetadata `json:"visionline_metadata,omitempty"` + AcsCredentialId string `json:"acs_credential_id" url:"acs_credential_id"` + AcsUserId *string `json:"acs_user_id,omitempty" url:"acs_user_id,omitempty"` + AcsCredentialPoolId *string `json:"acs_credential_pool_id,omitempty" url:"acs_credential_pool_id,omitempty"` + AcsSystemId string `json:"acs_system_id" url:"acs_system_id"` + ParentAcsCredentialId *string `json:"parent_acs_credential_id,omitempty" url:"parent_acs_credential_id,omitempty"` + DisplayName string `json:"display_name" url:"display_name"` + Code *string `json:"code,omitempty" url:"code,omitempty"` + AccessMethod CredentialsUpdateResponseAcsCredentialAccessMethod `json:"access_method,omitempty" url:"access_method,omitempty"` + ExternalType *CredentialsUpdateResponseAcsCredentialExternalType `json:"external_type,omitempty" url:"external_type,omitempty"` + ExternalTypeDisplayName *string `json:"external_type_display_name,omitempty" url:"external_type_display_name,omitempty"` + CreatedAt time.Time `json:"created_at" url:"created_at"` + WorkspaceId string `json:"workspace_id" url:"workspace_id"` + StartsAt *string `json:"starts_at,omitempty" url:"starts_at,omitempty"` + EndsAt *string `json:"ends_at,omitempty" url:"ends_at,omitempty"` + Errors []*CredentialsUpdateResponseAcsCredentialErrorsItem `json:"errors,omitempty" url:"errors,omitempty"` + Warnings []*CredentialsUpdateResponseAcsCredentialWarningsItem `json:"warnings,omitempty" url:"warnings,omitempty"` + IsMultiPhoneSyncCredential *bool `json:"is_multi_phone_sync_credential,omitempty" url:"is_multi_phone_sync_credential,omitempty"` + VisionlineMetadata *CredentialsUpdateResponseAcsCredentialVisionlineMetadata `json:"visionline_metadata,omitempty" url:"visionline_metadata,omitempty"` _rawJSON json.RawMessage } func (c *CredentialsUpdateResponseAcsCredential) UnmarshalJSON(data []byte) error { - type unmarshaler CredentialsUpdateResponseAcsCredential - var value unmarshaler - if err := json.Unmarshal(data, &value); err != nil { + type embed CredentialsUpdateResponseAcsCredential + var unmarshaler = struct { + embed + CreatedAt *core.DateTime `json:"created_at"` + }{ + embed: embed(*c), + } + if err := json.Unmarshal(data, &unmarshaler); err != nil { return err } - *c = CredentialsUpdateResponseAcsCredential(value) + *c = CredentialsUpdateResponseAcsCredential(unmarshaler.embed) + c.CreatedAt = unmarshaler.CreatedAt.Time() c._rawJSON = json.RawMessage(data) return nil } +func (c *CredentialsUpdateResponseAcsCredential) MarshalJSON() ([]byte, error) { + type embed CredentialsUpdateResponseAcsCredential + var marshaler = struct { + embed + CreatedAt *core.DateTime `json:"created_at"` + }{ + embed: embed(*c), + CreatedAt: core.NewDateTime(c.CreatedAt), + } + return json.Marshal(marshaler) +} + func (c *CredentialsUpdateResponseAcsCredential) String() string { if len(c._rawJSON) > 0 { if value, err := core.StringifyJSON(c._rawJSON); err == nil { @@ -1255,8 +1272,8 @@ func (c CredentialsUpdateResponseAcsCredentialAccessMethod) Ptr() *CredentialsUp } type CredentialsUpdateResponseAcsCredentialErrorsItem struct { - ErrorCode string `json:"error_code"` - Message string `json:"message"` + ErrorCode string `json:"error_code" url:"error_code"` + Message string `json:"message" url:"message"` _rawJSON json.RawMessage } @@ -1313,9 +1330,9 @@ func (c CredentialsUpdateResponseAcsCredentialExternalType) Ptr() *CredentialsUp } type CredentialsUpdateResponseAcsCredentialVisionlineMetadata struct { - JoinerAcsCredentialIds []string `json:"joiner_acs_credential_ids,omitempty"` - GuestAcsEntranceIds []string `json:"guest_acs_entrance_ids,omitempty"` - CommonAcsEntranceIds []string `json:"common_acs_entrance_ids,omitempty"` + JoinerAcsCredentialIds []string `json:"joiner_acs_credential_ids,omitempty" url:"joiner_acs_credential_ids,omitempty"` + GuestAcsEntranceIds []string `json:"guest_acs_entrance_ids,omitempty" url:"guest_acs_entrance_ids,omitempty"` + CommonAcsEntranceIds []string `json:"common_acs_entrance_ids,omitempty" url:"common_acs_entrance_ids,omitempty"` _rawJSON json.RawMessage } @@ -1344,8 +1361,8 @@ func (c *CredentialsUpdateResponseAcsCredentialVisionlineMetadata) String() stri } type CredentialsUpdateResponseAcsCredentialWarningsItem struct { - WarningCode string `json:"warning_code"` - Message string `json:"message"` + WarningCode string `json:"warning_code" url:"warning_code"` + Message string `json:"message" url:"message"` _rawJSON json.RawMessage } @@ -1374,26 +1391,44 @@ func (c *CredentialsUpdateResponseAcsCredentialWarningsItem) String() string { } type EntrancesGetResponseAcsEntrance struct { - AcsEntranceId string `json:"acs_entrance_id"` - DisplayName string `json:"display_name"` - AcsSystemId string `json:"acs_system_id"` - CreatedAt time.Time `json:"created_at"` - VisionlineMetadata *EntrancesGetResponseAcsEntranceVisionlineMetadata `json:"visionline_metadata,omitempty"` + AcsEntranceId string `json:"acs_entrance_id" url:"acs_entrance_id"` + DisplayName string `json:"display_name" url:"display_name"` + AcsSystemId string `json:"acs_system_id" url:"acs_system_id"` + CreatedAt time.Time `json:"created_at" url:"created_at"` + VisionlineMetadata *EntrancesGetResponseAcsEntranceVisionlineMetadata `json:"visionline_metadata,omitempty" url:"visionline_metadata,omitempty"` _rawJSON json.RawMessage } func (e *EntrancesGetResponseAcsEntrance) UnmarshalJSON(data []byte) error { - type unmarshaler EntrancesGetResponseAcsEntrance - var value unmarshaler - if err := json.Unmarshal(data, &value); err != nil { + type embed EntrancesGetResponseAcsEntrance + var unmarshaler = struct { + embed + CreatedAt *core.DateTime `json:"created_at"` + }{ + embed: embed(*e), + } + if err := json.Unmarshal(data, &unmarshaler); err != nil { return err } - *e = EntrancesGetResponseAcsEntrance(value) + *e = EntrancesGetResponseAcsEntrance(unmarshaler.embed) + e.CreatedAt = unmarshaler.CreatedAt.Time() e._rawJSON = json.RawMessage(data) return nil } +func (e *EntrancesGetResponseAcsEntrance) MarshalJSON() ([]byte, error) { + type embed EntrancesGetResponseAcsEntrance + var marshaler = struct { + embed + CreatedAt *core.DateTime `json:"created_at"` + }{ + embed: embed(*e), + CreatedAt: core.NewDateTime(e.CreatedAt), + } + return json.Marshal(marshaler) +} + func (e *EntrancesGetResponseAcsEntrance) String() string { if len(e._rawJSON) > 0 { if value, err := core.StringifyJSON(e._rawJSON); err == nil { @@ -1407,9 +1442,9 @@ func (e *EntrancesGetResponseAcsEntrance) String() string { } type EntrancesGetResponseAcsEntranceVisionlineMetadata struct { - DoorName string `json:"door_name"` - DoorCategory EntrancesGetResponseAcsEntranceVisionlineMetadataDoorCategory `json:"door_category,omitempty"` - Profiles []*EntrancesGetResponseAcsEntranceVisionlineMetadataProfilesItem `json:"profiles,omitempty"` + DoorName string `json:"door_name" url:"door_name"` + DoorCategory EntrancesGetResponseAcsEntranceVisionlineMetadataDoorCategory `json:"door_category,omitempty" url:"door_category,omitempty"` + Profiles []*EntrancesGetResponseAcsEntranceVisionlineMetadataProfilesItem `json:"profiles,omitempty" url:"profiles,omitempty"` _rawJSON json.RawMessage } @@ -1469,8 +1504,8 @@ func (e EntrancesGetResponseAcsEntranceVisionlineMetadataDoorCategory) Ptr() *En } type EntrancesGetResponseAcsEntranceVisionlineMetadataProfilesItem struct { - VisionlineDoorProfileId string `json:"visionline_door_profile_id"` - VisionlineDoorProfileType EntrancesGetResponseAcsEntranceVisionlineMetadataProfilesItemVisionlineDoorProfileType `json:"visionline_door_profile_type,omitempty"` + VisionlineDoorProfileId string `json:"visionline_door_profile_id" url:"visionline_door_profile_id"` + VisionlineDoorProfileType EntrancesGetResponseAcsEntranceVisionlineMetadataProfilesItemVisionlineDoorProfileType `json:"visionline_door_profile_type,omitempty" url:"visionline_door_profile_type,omitempty"` _rawJSON json.RawMessage } @@ -1524,39 +1559,57 @@ func (e EntrancesGetResponseAcsEntranceVisionlineMetadataProfilesItemVisionlineD } type EntrancesListCredentialsWithAccessResponseAcsCredentialsItem struct { - AcsCredentialId string `json:"acs_credential_id"` - AcsUserId *string `json:"acs_user_id,omitempty"` - AcsCredentialPoolId *string `json:"acs_credential_pool_id,omitempty"` - AcsSystemId string `json:"acs_system_id"` - ParentAcsCredentialId *string `json:"parent_acs_credential_id,omitempty"` - DisplayName string `json:"display_name"` - Code *string `json:"code,omitempty"` - AccessMethod EntrancesListCredentialsWithAccessResponseAcsCredentialsItemAccessMethod `json:"access_method,omitempty"` - ExternalType *EntrancesListCredentialsWithAccessResponseAcsCredentialsItemExternalType `json:"external_type,omitempty"` - ExternalTypeDisplayName *string `json:"external_type_display_name,omitempty"` - CreatedAt time.Time `json:"created_at"` - WorkspaceId string `json:"workspace_id"` - StartsAt *string `json:"starts_at,omitempty"` - EndsAt *string `json:"ends_at,omitempty"` - Errors []*EntrancesListCredentialsWithAccessResponseAcsCredentialsItemErrorsItem `json:"errors,omitempty"` - Warnings []*EntrancesListCredentialsWithAccessResponseAcsCredentialsItemWarningsItem `json:"warnings,omitempty"` - IsMultiPhoneSyncCredential *bool `json:"is_multi_phone_sync_credential,omitempty"` - VisionlineMetadata *EntrancesListCredentialsWithAccessResponseAcsCredentialsItemVisionlineMetadata `json:"visionline_metadata,omitempty"` + AcsCredentialId string `json:"acs_credential_id" url:"acs_credential_id"` + AcsUserId *string `json:"acs_user_id,omitempty" url:"acs_user_id,omitempty"` + AcsCredentialPoolId *string `json:"acs_credential_pool_id,omitempty" url:"acs_credential_pool_id,omitempty"` + AcsSystemId string `json:"acs_system_id" url:"acs_system_id"` + ParentAcsCredentialId *string `json:"parent_acs_credential_id,omitempty" url:"parent_acs_credential_id,omitempty"` + DisplayName string `json:"display_name" url:"display_name"` + Code *string `json:"code,omitempty" url:"code,omitempty"` + AccessMethod EntrancesListCredentialsWithAccessResponseAcsCredentialsItemAccessMethod `json:"access_method,omitempty" url:"access_method,omitempty"` + ExternalType *EntrancesListCredentialsWithAccessResponseAcsCredentialsItemExternalType `json:"external_type,omitempty" url:"external_type,omitempty"` + ExternalTypeDisplayName *string `json:"external_type_display_name,omitempty" url:"external_type_display_name,omitempty"` + CreatedAt time.Time `json:"created_at" url:"created_at"` + WorkspaceId string `json:"workspace_id" url:"workspace_id"` + StartsAt *string `json:"starts_at,omitempty" url:"starts_at,omitempty"` + EndsAt *string `json:"ends_at,omitempty" url:"ends_at,omitempty"` + Errors []*EntrancesListCredentialsWithAccessResponseAcsCredentialsItemErrorsItem `json:"errors,omitempty" url:"errors,omitempty"` + Warnings []*EntrancesListCredentialsWithAccessResponseAcsCredentialsItemWarningsItem `json:"warnings,omitempty" url:"warnings,omitempty"` + IsMultiPhoneSyncCredential *bool `json:"is_multi_phone_sync_credential,omitempty" url:"is_multi_phone_sync_credential,omitempty"` + VisionlineMetadata *EntrancesListCredentialsWithAccessResponseAcsCredentialsItemVisionlineMetadata `json:"visionline_metadata,omitempty" url:"visionline_metadata,omitempty"` _rawJSON json.RawMessage } func (e *EntrancesListCredentialsWithAccessResponseAcsCredentialsItem) UnmarshalJSON(data []byte) error { - type unmarshaler EntrancesListCredentialsWithAccessResponseAcsCredentialsItem - var value unmarshaler - if err := json.Unmarshal(data, &value); err != nil { + type embed EntrancesListCredentialsWithAccessResponseAcsCredentialsItem + var unmarshaler = struct { + embed + CreatedAt *core.DateTime `json:"created_at"` + }{ + embed: embed(*e), + } + if err := json.Unmarshal(data, &unmarshaler); err != nil { return err } - *e = EntrancesListCredentialsWithAccessResponseAcsCredentialsItem(value) + *e = EntrancesListCredentialsWithAccessResponseAcsCredentialsItem(unmarshaler.embed) + e.CreatedAt = unmarshaler.CreatedAt.Time() e._rawJSON = json.RawMessage(data) return nil } +func (e *EntrancesListCredentialsWithAccessResponseAcsCredentialsItem) MarshalJSON() ([]byte, error) { + type embed EntrancesListCredentialsWithAccessResponseAcsCredentialsItem + var marshaler = struct { + embed + CreatedAt *core.DateTime `json:"created_at"` + }{ + embed: embed(*e), + CreatedAt: core.NewDateTime(e.CreatedAt), + } + return json.Marshal(marshaler) +} + func (e *EntrancesListCredentialsWithAccessResponseAcsCredentialsItem) String() string { if len(e._rawJSON) > 0 { if value, err := core.StringifyJSON(e._rawJSON); err == nil { @@ -1595,8 +1648,8 @@ func (e EntrancesListCredentialsWithAccessResponseAcsCredentialsItemAccessMethod } type EntrancesListCredentialsWithAccessResponseAcsCredentialsItemErrorsItem struct { - ErrorCode string `json:"error_code"` - Message string `json:"message"` + ErrorCode string `json:"error_code" url:"error_code"` + Message string `json:"message" url:"message"` _rawJSON json.RawMessage } @@ -1653,9 +1706,9 @@ func (e EntrancesListCredentialsWithAccessResponseAcsCredentialsItemExternalType } type EntrancesListCredentialsWithAccessResponseAcsCredentialsItemVisionlineMetadata struct { - JoinerAcsCredentialIds []string `json:"joiner_acs_credential_ids,omitempty"` - GuestAcsEntranceIds []string `json:"guest_acs_entrance_ids,omitempty"` - CommonAcsEntranceIds []string `json:"common_acs_entrance_ids,omitempty"` + JoinerAcsCredentialIds []string `json:"joiner_acs_credential_ids,omitempty" url:"joiner_acs_credential_ids,omitempty"` + GuestAcsEntranceIds []string `json:"guest_acs_entrance_ids,omitempty" url:"guest_acs_entrance_ids,omitempty"` + CommonAcsEntranceIds []string `json:"common_acs_entrance_ids,omitempty" url:"common_acs_entrance_ids,omitempty"` _rawJSON json.RawMessage } @@ -1684,8 +1737,8 @@ func (e *EntrancesListCredentialsWithAccessResponseAcsCredentialsItemVisionlineM } type EntrancesListCredentialsWithAccessResponseAcsCredentialsItemWarningsItem struct { - WarningCode string `json:"warning_code"` - Message string `json:"message"` + WarningCode string `json:"warning_code" url:"warning_code"` + Message string `json:"message" url:"message"` _rawJSON json.RawMessage } @@ -1714,26 +1767,44 @@ func (e *EntrancesListCredentialsWithAccessResponseAcsCredentialsItemWarningsIte } type EntrancesListResponseAcsEntrancesItem struct { - AcsEntranceId string `json:"acs_entrance_id"` - DisplayName string `json:"display_name"` - AcsSystemId string `json:"acs_system_id"` - CreatedAt time.Time `json:"created_at"` - VisionlineMetadata *EntrancesListResponseAcsEntrancesItemVisionlineMetadata `json:"visionline_metadata,omitempty"` + AcsEntranceId string `json:"acs_entrance_id" url:"acs_entrance_id"` + DisplayName string `json:"display_name" url:"display_name"` + AcsSystemId string `json:"acs_system_id" url:"acs_system_id"` + CreatedAt time.Time `json:"created_at" url:"created_at"` + VisionlineMetadata *EntrancesListResponseAcsEntrancesItemVisionlineMetadata `json:"visionline_metadata,omitempty" url:"visionline_metadata,omitempty"` _rawJSON json.RawMessage } func (e *EntrancesListResponseAcsEntrancesItem) UnmarshalJSON(data []byte) error { - type unmarshaler EntrancesListResponseAcsEntrancesItem - var value unmarshaler - if err := json.Unmarshal(data, &value); err != nil { + type embed EntrancesListResponseAcsEntrancesItem + var unmarshaler = struct { + embed + CreatedAt *core.DateTime `json:"created_at"` + }{ + embed: embed(*e), + } + if err := json.Unmarshal(data, &unmarshaler); err != nil { return err } - *e = EntrancesListResponseAcsEntrancesItem(value) + *e = EntrancesListResponseAcsEntrancesItem(unmarshaler.embed) + e.CreatedAt = unmarshaler.CreatedAt.Time() e._rawJSON = json.RawMessage(data) return nil } +func (e *EntrancesListResponseAcsEntrancesItem) MarshalJSON() ([]byte, error) { + type embed EntrancesListResponseAcsEntrancesItem + var marshaler = struct { + embed + CreatedAt *core.DateTime `json:"created_at"` + }{ + embed: embed(*e), + CreatedAt: core.NewDateTime(e.CreatedAt), + } + return json.Marshal(marshaler) +} + func (e *EntrancesListResponseAcsEntrancesItem) String() string { if len(e._rawJSON) > 0 { if value, err := core.StringifyJSON(e._rawJSON); err == nil { @@ -1747,9 +1818,9 @@ func (e *EntrancesListResponseAcsEntrancesItem) String() string { } type EntrancesListResponseAcsEntrancesItemVisionlineMetadata struct { - DoorName string `json:"door_name"` - DoorCategory EntrancesListResponseAcsEntrancesItemVisionlineMetadataDoorCategory `json:"door_category,omitempty"` - Profiles []*EntrancesListResponseAcsEntrancesItemVisionlineMetadataProfilesItem `json:"profiles,omitempty"` + DoorName string `json:"door_name" url:"door_name"` + DoorCategory EntrancesListResponseAcsEntrancesItemVisionlineMetadataDoorCategory `json:"door_category,omitempty" url:"door_category,omitempty"` + Profiles []*EntrancesListResponseAcsEntrancesItemVisionlineMetadataProfilesItem `json:"profiles,omitempty" url:"profiles,omitempty"` _rawJSON json.RawMessage } @@ -1809,8 +1880,8 @@ func (e EntrancesListResponseAcsEntrancesItemVisionlineMetadataDoorCategory) Ptr } type EntrancesListResponseAcsEntrancesItemVisionlineMetadataProfilesItem struct { - VisionlineDoorProfileId string `json:"visionline_door_profile_id"` - VisionlineDoorProfileType EntrancesListResponseAcsEntrancesItemVisionlineMetadataProfilesItemVisionlineDoorProfileType `json:"visionline_door_profile_type,omitempty"` + VisionlineDoorProfileId string `json:"visionline_door_profile_id" url:"visionline_door_profile_id"` + VisionlineDoorProfileType EntrancesListResponseAcsEntrancesItemVisionlineMetadataProfilesItemVisionlineDoorProfileType `json:"visionline_door_profile_type,omitempty" url:"visionline_door_profile_type,omitempty"` _rawJSON json.RawMessage } @@ -1864,26 +1935,44 @@ func (e EntrancesListResponseAcsEntrancesItemVisionlineMetadataProfilesItemVisio } type UsersListAccessibleEntrancesResponseAcsEntrancesItem struct { - AcsEntranceId string `json:"acs_entrance_id"` - DisplayName string `json:"display_name"` - AcsSystemId string `json:"acs_system_id"` - CreatedAt time.Time `json:"created_at"` - VisionlineMetadata *UsersListAccessibleEntrancesResponseAcsEntrancesItemVisionlineMetadata `json:"visionline_metadata,omitempty"` + AcsEntranceId string `json:"acs_entrance_id" url:"acs_entrance_id"` + DisplayName string `json:"display_name" url:"display_name"` + AcsSystemId string `json:"acs_system_id" url:"acs_system_id"` + CreatedAt time.Time `json:"created_at" url:"created_at"` + VisionlineMetadata *UsersListAccessibleEntrancesResponseAcsEntrancesItemVisionlineMetadata `json:"visionline_metadata,omitempty" url:"visionline_metadata,omitempty"` _rawJSON json.RawMessage } func (u *UsersListAccessibleEntrancesResponseAcsEntrancesItem) UnmarshalJSON(data []byte) error { - type unmarshaler UsersListAccessibleEntrancesResponseAcsEntrancesItem - var value unmarshaler - if err := json.Unmarshal(data, &value); err != nil { + type embed UsersListAccessibleEntrancesResponseAcsEntrancesItem + var unmarshaler = struct { + embed + CreatedAt *core.DateTime `json:"created_at"` + }{ + embed: embed(*u), + } + if err := json.Unmarshal(data, &unmarshaler); err != nil { return err } - *u = UsersListAccessibleEntrancesResponseAcsEntrancesItem(value) + *u = UsersListAccessibleEntrancesResponseAcsEntrancesItem(unmarshaler.embed) + u.CreatedAt = unmarshaler.CreatedAt.Time() u._rawJSON = json.RawMessage(data) return nil } +func (u *UsersListAccessibleEntrancesResponseAcsEntrancesItem) MarshalJSON() ([]byte, error) { + type embed UsersListAccessibleEntrancesResponseAcsEntrancesItem + var marshaler = struct { + embed + CreatedAt *core.DateTime `json:"created_at"` + }{ + embed: embed(*u), + CreatedAt: core.NewDateTime(u.CreatedAt), + } + return json.Marshal(marshaler) +} + func (u *UsersListAccessibleEntrancesResponseAcsEntrancesItem) String() string { if len(u._rawJSON) > 0 { if value, err := core.StringifyJSON(u._rawJSON); err == nil { @@ -1897,9 +1986,9 @@ func (u *UsersListAccessibleEntrancesResponseAcsEntrancesItem) String() string { } type UsersListAccessibleEntrancesResponseAcsEntrancesItemVisionlineMetadata struct { - DoorName string `json:"door_name"` - DoorCategory UsersListAccessibleEntrancesResponseAcsEntrancesItemVisionlineMetadataDoorCategory `json:"door_category,omitempty"` - Profiles []*UsersListAccessibleEntrancesResponseAcsEntrancesItemVisionlineMetadataProfilesItem `json:"profiles,omitempty"` + DoorName string `json:"door_name" url:"door_name"` + DoorCategory UsersListAccessibleEntrancesResponseAcsEntrancesItemVisionlineMetadataDoorCategory `json:"door_category,omitempty" url:"door_category,omitempty"` + Profiles []*UsersListAccessibleEntrancesResponseAcsEntrancesItemVisionlineMetadataProfilesItem `json:"profiles,omitempty" url:"profiles,omitempty"` _rawJSON json.RawMessage } @@ -1959,8 +2048,8 @@ func (u UsersListAccessibleEntrancesResponseAcsEntrancesItemVisionlineMetadataDo } type UsersListAccessibleEntrancesResponseAcsEntrancesItemVisionlineMetadataProfilesItem struct { - VisionlineDoorProfileId string `json:"visionline_door_profile_id"` - VisionlineDoorProfileType UsersListAccessibleEntrancesResponseAcsEntrancesItemVisionlineMetadataProfilesItemVisionlineDoorProfileType `json:"visionline_door_profile_type,omitempty"` + VisionlineDoorProfileId string `json:"visionline_door_profile_id" url:"visionline_door_profile_id"` + VisionlineDoorProfileType UsersListAccessibleEntrancesResponseAcsEntrancesItemVisionlineMetadataProfilesItemVisionlineDoorProfileType `json:"visionline_door_profile_type,omitempty" url:"visionline_door_profile_type,omitempty"` _rawJSON json.RawMessage } diff --git a/acs/users.go b/acs/users.go index c65594b..cb06c7a 100644 --- a/acs/users.go +++ b/acs/users.go @@ -11,56 +11,56 @@ import ( ) type UsersAddToAccessGroupRequest struct { - AcsUserId string `json:"acs_user_id"` - AcsAccessGroupId string `json:"acs_access_group_id"` + AcsUserId string `json:"acs_user_id" url:"acs_user_id"` + AcsAccessGroupId string `json:"acs_access_group_id" url:"acs_access_group_id"` } type UsersCreateRequest struct { - AcsSystemId string `json:"acs_system_id"` - AcsAccessGroupIds []string `json:"acs_access_group_ids,omitempty"` - UserIdentityId *string `json:"user_identity_id,omitempty"` - AccessSchedule *UsersCreateRequestAccessSchedule `json:"access_schedule,omitempty"` - FullName *string `json:"full_name,omitempty"` + AcsSystemId string `json:"acs_system_id" url:"acs_system_id"` + AcsAccessGroupIds []string `json:"acs_access_group_ids,omitempty" url:"acs_access_group_ids,omitempty"` + UserIdentityId *string `json:"user_identity_id,omitempty" url:"user_identity_id,omitempty"` + AccessSchedule *UsersCreateRequestAccessSchedule `json:"access_schedule,omitempty" url:"access_schedule,omitempty"` + FullName *string `json:"full_name,omitempty" url:"full_name,omitempty"` // Deprecated: use email_address. - Email *string `json:"email,omitempty"` - PhoneNumber *string `json:"phone_number,omitempty"` - EmailAddress *string `json:"email_address,omitempty"` + Email *string `json:"email,omitempty" url:"email,omitempty"` + PhoneNumber *string `json:"phone_number,omitempty" url:"phone_number,omitempty"` + EmailAddress *string `json:"email_address,omitempty" url:"email_address,omitempty"` } type UsersDeleteRequest struct { - AcsUserId string `json:"acs_user_id"` + AcsUserId string `json:"acs_user_id" url:"acs_user_id"` } type UsersGetRequest struct { - AcsUserId string `json:"acs_user_id"` + AcsUserId string `json:"acs_user_id" url:"acs_user_id"` } type UsersListRequest struct { - UserIdentityId *string `json:"user_identity_id,omitempty"` - UserIdentityPhoneNumber *string `json:"user_identity_phone_number,omitempty"` - UserIdentityEmailAddress *string `json:"user_identity_email_address,omitempty"` - AcsSystemId *string `json:"acs_system_id,omitempty"` + UserIdentityId *string `json:"user_identity_id,omitempty" url:"user_identity_id,omitempty"` + UserIdentityPhoneNumber *string `json:"user_identity_phone_number,omitempty" url:"user_identity_phone_number,omitempty"` + UserIdentityEmailAddress *string `json:"user_identity_email_address,omitempty" url:"user_identity_email_address,omitempty"` + AcsSystemId *string `json:"acs_system_id,omitempty" url:"acs_system_id,omitempty"` } type UsersListAccessibleEntrancesRequest struct { - AcsUserId string `json:"acs_user_id"` + AcsUserId string `json:"acs_user_id" url:"acs_user_id"` } type UsersRemoveFromAccessGroupRequest struct { - AcsUserId string `json:"acs_user_id"` - AcsAccessGroupId string `json:"acs_access_group_id"` + AcsUserId string `json:"acs_user_id" url:"acs_user_id"` + AcsAccessGroupId string `json:"acs_access_group_id" url:"acs_access_group_id"` } type UsersRevokeAccessToAllEntrancesRequest struct { - AcsUserId string `json:"acs_user_id"` + AcsUserId string `json:"acs_user_id" url:"acs_user_id"` } type UsersSuspendRequest struct { - AcsUserId string `json:"acs_user_id"` + AcsUserId string `json:"acs_user_id" url:"acs_user_id"` } type UsersAddToAccessGroupResponse struct { - Ok bool `json:"ok"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -89,23 +89,45 @@ func (u *UsersAddToAccessGroupResponse) String() string { } type UsersCreateRequestAccessSchedule struct { - StartsAt time.Time `json:"starts_at"` - EndsAt time.Time `json:"ends_at"` + StartsAt time.Time `json:"starts_at" url:"starts_at"` + EndsAt time.Time `json:"ends_at" url:"ends_at"` _rawJSON json.RawMessage } func (u *UsersCreateRequestAccessSchedule) UnmarshalJSON(data []byte) error { - type unmarshaler UsersCreateRequestAccessSchedule - var value unmarshaler - if err := json.Unmarshal(data, &value); err != nil { + type embed UsersCreateRequestAccessSchedule + var unmarshaler = struct { + embed + StartsAt *core.DateTime `json:"starts_at"` + EndsAt *core.DateTime `json:"ends_at"` + }{ + embed: embed(*u), + } + if err := json.Unmarshal(data, &unmarshaler); err != nil { return err } - *u = UsersCreateRequestAccessSchedule(value) + *u = UsersCreateRequestAccessSchedule(unmarshaler.embed) + u.StartsAt = unmarshaler.StartsAt.Time() + u.EndsAt = unmarshaler.EndsAt.Time() u._rawJSON = json.RawMessage(data) return nil } +func (u *UsersCreateRequestAccessSchedule) MarshalJSON() ([]byte, error) { + type embed UsersCreateRequestAccessSchedule + var marshaler = struct { + embed + StartsAt *core.DateTime `json:"starts_at"` + EndsAt *core.DateTime `json:"ends_at"` + }{ + embed: embed(*u), + StartsAt: core.NewDateTime(u.StartsAt), + EndsAt: core.NewDateTime(u.EndsAt), + } + return json.Marshal(marshaler) +} + func (u *UsersCreateRequestAccessSchedule) String() string { if len(u._rawJSON) > 0 { if value, err := core.StringifyJSON(u._rawJSON); err == nil { @@ -119,8 +141,8 @@ func (u *UsersCreateRequestAccessSchedule) String() string { } type UsersCreateResponse struct { - AcsUser *seamapigo.AcsUser `json:"acs_user,omitempty"` - Ok bool `json:"ok"` + AcsUser *seamapigo.AcsUser `json:"acs_user,omitempty" url:"acs_user,omitempty"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -149,7 +171,7 @@ func (u *UsersCreateResponse) String() string { } type UsersDeleteResponse struct { - Ok bool `json:"ok"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -178,8 +200,8 @@ func (u *UsersDeleteResponse) String() string { } type UsersGetResponse struct { - AcsUser *seamapigo.AcsUser `json:"acs_user,omitempty"` - Ok bool `json:"ok"` + AcsUser *seamapigo.AcsUser `json:"acs_user,omitempty" url:"acs_user,omitempty"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -208,8 +230,8 @@ func (u *UsersGetResponse) String() string { } type UsersListAccessibleEntrancesResponse struct { - AcsEntrances []*UsersListAccessibleEntrancesResponseAcsEntrancesItem `json:"acs_entrances,omitempty"` - Ok bool `json:"ok"` + AcsEntrances []*UsersListAccessibleEntrancesResponseAcsEntrancesItem `json:"acs_entrances,omitempty" url:"acs_entrances,omitempty"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -238,8 +260,8 @@ func (u *UsersListAccessibleEntrancesResponse) String() string { } type UsersListResponse struct { - AcsUsers []*seamapigo.AcsUser `json:"acs_users,omitempty"` - Ok bool `json:"ok"` + AcsUsers []*seamapigo.AcsUser `json:"acs_users,omitempty" url:"acs_users,omitempty"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -268,7 +290,7 @@ func (u *UsersListResponse) String() string { } type UsersRemoveFromAccessGroupResponse struct { - Ok bool `json:"ok"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -297,7 +319,7 @@ func (u *UsersRemoveFromAccessGroupResponse) String() string { } type UsersRevokeAccessToAllEntrancesResponse struct { - Ok bool `json:"ok"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -326,7 +348,7 @@ func (u *UsersRevokeAccessToAllEntrancesResponse) String() string { } type UsersSuspendResponse struct { - Ok bool `json:"ok"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -355,7 +377,7 @@ func (u *UsersSuspendResponse) String() string { } type UsersUnsuspendResponse struct { - Ok bool `json:"ok"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -384,23 +406,45 @@ func (u *UsersUnsuspendResponse) String() string { } type UsersUpdateRequestAccessSchedule struct { - StartsAt time.Time `json:"starts_at"` - EndsAt time.Time `json:"ends_at"` + StartsAt time.Time `json:"starts_at" url:"starts_at"` + EndsAt time.Time `json:"ends_at" url:"ends_at"` _rawJSON json.RawMessage } func (u *UsersUpdateRequestAccessSchedule) UnmarshalJSON(data []byte) error { - type unmarshaler UsersUpdateRequestAccessSchedule - var value unmarshaler - if err := json.Unmarshal(data, &value); err != nil { + type embed UsersUpdateRequestAccessSchedule + var unmarshaler = struct { + embed + StartsAt *core.DateTime `json:"starts_at"` + EndsAt *core.DateTime `json:"ends_at"` + }{ + embed: embed(*u), + } + if err := json.Unmarshal(data, &unmarshaler); err != nil { return err } - *u = UsersUpdateRequestAccessSchedule(value) + *u = UsersUpdateRequestAccessSchedule(unmarshaler.embed) + u.StartsAt = unmarshaler.StartsAt.Time() + u.EndsAt = unmarshaler.EndsAt.Time() u._rawJSON = json.RawMessage(data) return nil } +func (u *UsersUpdateRequestAccessSchedule) MarshalJSON() ([]byte, error) { + type embed UsersUpdateRequestAccessSchedule + var marshaler = struct { + embed + StartsAt *core.DateTime `json:"starts_at"` + EndsAt *core.DateTime `json:"ends_at"` + }{ + embed: embed(*u), + StartsAt: core.NewDateTime(u.StartsAt), + EndsAt: core.NewDateTime(u.EndsAt), + } + return json.Marshal(marshaler) +} + func (u *UsersUpdateRequestAccessSchedule) String() string { if len(u._rawJSON) > 0 { if value, err := core.StringifyJSON(u._rawJSON); err == nil { @@ -414,7 +458,7 @@ func (u *UsersUpdateRequestAccessSchedule) String() string { } type UsersUpdateResponse struct { - Ok bool `json:"ok"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -443,16 +487,16 @@ func (u *UsersUpdateResponse) String() string { } type UsersUnsuspendRequest struct { - AcsUserId string `json:"acs_user_id"` + AcsUserId string `json:"acs_user_id" url:"acs_user_id"` } type UsersUpdateRequest struct { - AccessSchedule *UsersUpdateRequestAccessSchedule `json:"access_schedule,omitempty"` - AcsUserId string `json:"acs_user_id"` - FullName *string `json:"full_name,omitempty"` + AccessSchedule *UsersUpdateRequestAccessSchedule `json:"access_schedule,omitempty" url:"access_schedule,omitempty"` + AcsUserId string `json:"acs_user_id" url:"acs_user_id"` + FullName *string `json:"full_name,omitempty" url:"full_name,omitempty"` // Deprecated: use email_address. - Email *string `json:"email,omitempty"` - PhoneNumber *string `json:"phone_number,omitempty"` - EmailAddress *string `json:"email_address,omitempty"` - HidAcsSystemId *string `json:"hid_acs_system_id,omitempty"` + Email *string `json:"email,omitempty" url:"email,omitempty"` + PhoneNumber *string `json:"phone_number,omitempty" url:"phone_number,omitempty"` + EmailAddress *string `json:"email_address,omitempty" url:"email_address,omitempty"` + HidAcsSystemId *string `json:"hid_acs_system_id,omitempty" url:"hid_acs_system_id,omitempty"` } diff --git a/acs/users/client.go b/acs/users/client.go index c7e7996..c058ef9 100644 --- a/acs/users/client.go +++ b/acs/users/client.go @@ -10,6 +10,7 @@ import ( seamapigo "github.com/seamapi/go" acs "github.com/seamapi/go/acs" core "github.com/seamapi/go/core" + option "github.com/seamapi/go/option" io "io" http "net/http" ) @@ -20,25 +21,38 @@ type Client struct { header http.Header } -func NewClient(opts ...core.ClientOption) *Client { - options := core.NewClientOptions() - for _, opt := range opts { - opt(options) - } +func NewClient(opts ...option.RequestOption) *Client { + options := core.NewRequestOptions(opts...) return &Client{ baseURL: options.BaseURL, - caller: core.NewCaller(options.HTTPClient), - header: options.ToHeader(), + caller: core.NewCaller( + &core.CallerParams{ + Client: options.HTTPClient, + MaxAttempts: options.MaxAttempts, + }, + ), + header: options.ToHeader(), } } -func (c *Client) AddToAccessGroup(ctx context.Context, request *acs.UsersAddToAccessGroupRequest) (*acs.UsersAddToAccessGroupResponse, error) { +func (c *Client) AddToAccessGroup( + ctx context.Context, + request *acs.UsersAddToAccessGroupRequest, + opts ...option.RequestOption, +) (*acs.UsersAddToAccessGroupResponse, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "acs/users/add_to_access_group" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -71,7 +85,9 @@ func (c *Client) AddToAccessGroup(ctx context.Context, request *acs.UsersAddToAc &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -82,13 +98,24 @@ func (c *Client) AddToAccessGroup(ctx context.Context, request *acs.UsersAddToAc return response, nil } -func (c *Client) Create(ctx context.Context, request *acs.UsersCreateRequest) (*acs.UsersCreateResponse, error) { +func (c *Client) Create( + ctx context.Context, + request *acs.UsersCreateRequest, + opts ...option.RequestOption, +) (*acs.UsersCreateResponse, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "acs/users/create" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -121,7 +148,9 @@ func (c *Client) Create(ctx context.Context, request *acs.UsersCreateRequest) (* &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -132,13 +161,24 @@ func (c *Client) Create(ctx context.Context, request *acs.UsersCreateRequest) (* return response, nil } -func (c *Client) Delete(ctx context.Context, request *acs.UsersDeleteRequest) (*acs.UsersDeleteResponse, error) { +func (c *Client) Delete( + ctx context.Context, + request *acs.UsersDeleteRequest, + opts ...option.RequestOption, +) (*acs.UsersDeleteResponse, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "acs/users/delete" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -171,7 +211,9 @@ func (c *Client) Delete(ctx context.Context, request *acs.UsersDeleteRequest) (* &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -182,13 +224,24 @@ func (c *Client) Delete(ctx context.Context, request *acs.UsersDeleteRequest) (* return response, nil } -func (c *Client) Get(ctx context.Context, request *acs.UsersGetRequest) (*acs.UsersGetResponse, error) { +func (c *Client) Get( + ctx context.Context, + request *acs.UsersGetRequest, + opts ...option.RequestOption, +) (*acs.UsersGetResponse, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "acs/users/get" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -221,7 +274,9 @@ func (c *Client) Get(ctx context.Context, request *acs.UsersGetRequest) (*acs.Us &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -232,13 +287,24 @@ func (c *Client) Get(ctx context.Context, request *acs.UsersGetRequest) (*acs.Us return response, nil } -func (c *Client) List(ctx context.Context, request *acs.UsersListRequest) (*acs.UsersListResponse, error) { +func (c *Client) List( + ctx context.Context, + request *acs.UsersListRequest, + opts ...option.RequestOption, +) (*acs.UsersListResponse, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "acs/users/list" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -271,7 +337,9 @@ func (c *Client) List(ctx context.Context, request *acs.UsersListRequest) (*acs. &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -282,13 +350,24 @@ func (c *Client) List(ctx context.Context, request *acs.UsersListRequest) (*acs. return response, nil } -func (c *Client) ListAccessibleEntrances(ctx context.Context, request *acs.UsersListAccessibleEntrancesRequest) (*acs.UsersListAccessibleEntrancesResponse, error) { +func (c *Client) ListAccessibleEntrances( + ctx context.Context, + request *acs.UsersListAccessibleEntrancesRequest, + opts ...option.RequestOption, +) (*acs.UsersListAccessibleEntrancesResponse, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "acs/users/list_accessible_entrances" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -321,7 +400,9 @@ func (c *Client) ListAccessibleEntrances(ctx context.Context, request *acs.Users &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -332,13 +413,24 @@ func (c *Client) ListAccessibleEntrances(ctx context.Context, request *acs.Users return response, nil } -func (c *Client) RemoveFromAccessGroup(ctx context.Context, request *acs.UsersRemoveFromAccessGroupRequest) (*acs.UsersRemoveFromAccessGroupResponse, error) { +func (c *Client) RemoveFromAccessGroup( + ctx context.Context, + request *acs.UsersRemoveFromAccessGroupRequest, + opts ...option.RequestOption, +) (*acs.UsersRemoveFromAccessGroupResponse, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "acs/users/remove_from_access_group" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -371,7 +463,9 @@ func (c *Client) RemoveFromAccessGroup(ctx context.Context, request *acs.UsersRe &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -382,13 +476,24 @@ func (c *Client) RemoveFromAccessGroup(ctx context.Context, request *acs.UsersRe return response, nil } -func (c *Client) RevokeAccessToAllEntrances(ctx context.Context, request *acs.UsersRevokeAccessToAllEntrancesRequest) (*acs.UsersRevokeAccessToAllEntrancesResponse, error) { +func (c *Client) RevokeAccessToAllEntrances( + ctx context.Context, + request *acs.UsersRevokeAccessToAllEntrancesRequest, + opts ...option.RequestOption, +) (*acs.UsersRevokeAccessToAllEntrancesResponse, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "acs/users/revoke_access_to_all_entrances" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -421,7 +526,9 @@ func (c *Client) RevokeAccessToAllEntrances(ctx context.Context, request *acs.Us &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -432,13 +539,24 @@ func (c *Client) RevokeAccessToAllEntrances(ctx context.Context, request *acs.Us return response, nil } -func (c *Client) Suspend(ctx context.Context, request *acs.UsersSuspendRequest) (*acs.UsersSuspendResponse, error) { +func (c *Client) Suspend( + ctx context.Context, + request *acs.UsersSuspendRequest, + opts ...option.RequestOption, +) (*acs.UsersSuspendResponse, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "acs/users/suspend" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -471,7 +589,9 @@ func (c *Client) Suspend(ctx context.Context, request *acs.UsersSuspendRequest) &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -482,13 +602,24 @@ func (c *Client) Suspend(ctx context.Context, request *acs.UsersSuspendRequest) return response, nil } -func (c *Client) Unsuspend(ctx context.Context, request *acs.UsersUnsuspendRequest) (*acs.UsersUnsuspendResponse, error) { +func (c *Client) Unsuspend( + ctx context.Context, + request *acs.UsersUnsuspendRequest, + opts ...option.RequestOption, +) (*acs.UsersUnsuspendResponse, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "acs/users/unsuspend" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -521,7 +652,9 @@ func (c *Client) Unsuspend(ctx context.Context, request *acs.UsersUnsuspendReque &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -532,13 +665,24 @@ func (c *Client) Unsuspend(ctx context.Context, request *acs.UsersUnsuspendReque return response, nil } -func (c *Client) Update(ctx context.Context, request *acs.UsersUpdateRequest) (*acs.UsersUpdateResponse, error) { +func (c *Client) Update( + ctx context.Context, + request *acs.UsersUpdateRequest, + opts ...option.RequestOption, +) (*acs.UsersUpdateResponse, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "acs/users/update" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -571,7 +715,9 @@ func (c *Client) Update(ctx context.Context, request *acs.UsersUpdateRequest) (* &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, diff --git a/action_attempts.go b/action_attempts.go index 4b07bf7..6ddf25c 100644 --- a/action_attempts.go +++ b/action_attempts.go @@ -9,16 +9,16 @@ import ( ) type ActionAttemptsGetRequest struct { - ActionAttemptId string `json:"action_attempt_id"` + ActionAttemptId string `json:"action_attempt_id" url:"action_attempt_id"` } type ActionAttemptsListRequest struct { - ActionAttemptIds []string `json:"action_attempt_ids,omitempty"` + ActionAttemptIds []string `json:"action_attempt_ids,omitempty" url:"action_attempt_ids,omitempty"` } type ActionAttemptsGetResponse struct { - ActionAttempt *ActionAttempt `json:"action_attempt,omitempty"` - Ok bool `json:"ok"` + ActionAttempt *ActionAttempt `json:"action_attempt,omitempty" url:"action_attempt,omitempty"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -47,8 +47,8 @@ func (a *ActionAttemptsGetResponse) String() string { } type ActionAttemptsListResponse struct { - ActionAttempts []*ActionAttempt `json:"action_attempts,omitempty"` - Ok bool `json:"ok"` + ActionAttempts []*ActionAttempt `json:"action_attempts,omitempty" url:"action_attempts,omitempty"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } diff --git a/actionattempts/client.go b/actionattempts/client.go index 49ee52d..e97f94f 100644 --- a/actionattempts/client.go +++ b/actionattempts/client.go @@ -9,6 +9,7 @@ import ( errors "errors" seamapigo "github.com/seamapi/go" core "github.com/seamapi/go/core" + option "github.com/seamapi/go/option" io "io" http "net/http" ) @@ -19,25 +20,38 @@ type Client struct { header http.Header } -func NewClient(opts ...core.ClientOption) *Client { - options := core.NewClientOptions() - for _, opt := range opts { - opt(options) - } +func NewClient(opts ...option.RequestOption) *Client { + options := core.NewRequestOptions(opts...) return &Client{ baseURL: options.BaseURL, - caller: core.NewCaller(options.HTTPClient), - header: options.ToHeader(), + caller: core.NewCaller( + &core.CallerParams{ + Client: options.HTTPClient, + MaxAttempts: options.MaxAttempts, + }, + ), + header: options.ToHeader(), } } -func (c *Client) Get(ctx context.Context, request *seamapigo.ActionAttemptsGetRequest) (*seamapigo.ActionAttempt, error) { +func (c *Client) Get( + ctx context.Context, + request *seamapigo.ActionAttemptsGetRequest, + opts ...option.RequestOption, +) (*seamapigo.ActionAttempt, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "action_attempts/get" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -70,7 +84,9 @@ func (c *Client) Get(ctx context.Context, request *seamapigo.ActionAttemptsGetRe &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -81,13 +97,24 @@ func (c *Client) Get(ctx context.Context, request *seamapigo.ActionAttemptsGetRe return response.ActionAttempt, nil } -func (c *Client) List(ctx context.Context, request *seamapigo.ActionAttemptsListRequest) ([]*seamapigo.ActionAttempt, error) { +func (c *Client) List( + ctx context.Context, + request *seamapigo.ActionAttemptsListRequest, + opts ...option.RequestOption, +) ([]*seamapigo.ActionAttempt, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "action_attempts/list" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -120,7 +147,9 @@ func (c *Client) List(ctx context.Context, request *seamapigo.ActionAttemptsList &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, diff --git a/client/client.go b/client/client.go index b5bfb19..fc73f8b 100644 --- a/client/client.go +++ b/client/client.go @@ -16,6 +16,7 @@ import ( locks "github.com/seamapi/go/locks" networks "github.com/seamapi/go/networks" noisesensorsclient "github.com/seamapi/go/noisesensors/client" + option "github.com/seamapi/go/option" phonesclient "github.com/seamapi/go/phones/client" thermostatsclient "github.com/seamapi/go/thermostats/client" useridentitiesclient "github.com/seamapi/go/useridentities/client" @@ -48,14 +49,16 @@ type Client struct { NoiseSensors *noisesensorsclient.Client } -func NewClient(opts ...core.ClientOption) *Client { - options := core.NewClientOptions() - for _, opt := range opts { - opt(options) - } +func NewClient(opts ...option.RequestOption) *Client { + options := core.NewRequestOptions(opts...) return &Client{ - baseURL: options.BaseURL, - caller: core.NewCaller(options.HTTPClient), + baseURL: options.BaseURL, + caller: core.NewCaller( + &core.CallerParams{ + Client: options.HTTPClient, + MaxAttempts: options.MaxAttempts, + }, + ), header: options.ToHeader(), AccessCodes: accesscodesclient.NewClient(opts...), ActionAttempts: actionattempts.NewClient(opts...), diff --git a/client/client_test.go b/client/client_test.go index a0fa36e..ade5d0a 100644 --- a/client/client_test.go +++ b/client/client_test.go @@ -1,11 +1,13 @@ +// This file was auto-generated by Fern from our API Definition. + package client import ( - "net/http" - "testing" - "time" - - "github.com/stretchr/testify/assert" + option "github.com/seamapi/go/option" + assert "github.com/stretchr/testify/assert" + http "net/http" + testing "testing" + time "time" ) func TestNewClient(t *testing.T) { @@ -16,7 +18,7 @@ func TestNewClient(t *testing.T) { t.Run("base url", func(t *testing.T) { c := NewClient( - WithBaseURL("test.co"), + option.WithBaseURL("test.co"), ) assert.Equal(t, "test.co", c.baseURL) }) @@ -26,7 +28,7 @@ func TestNewClient(t *testing.T) { Timeout: 5 * time.Second, } c := NewClient( - WithHTTPClient(httpClient), + option.WithHTTPClient(httpClient), ) assert.Empty(t, c.baseURL) }) @@ -35,7 +37,7 @@ func TestNewClient(t *testing.T) { header := make(http.Header) header.Set("X-API-Tenancy", "test") c := NewClient( - WithHTTPHeader(header), + option.WithHTTPHeader(header), ) assert.Empty(t, c.baseURL) assert.Equal(t, "test", c.header.Get("X-API-Tenancy")) diff --git a/client/options.go b/client/options.go index 49a702f..51904e2 100644 --- a/client/options.go +++ b/client/options.go @@ -4,57 +4,47 @@ package client import ( core "github.com/seamapi/go/core" + option "github.com/seamapi/go/option" http "net/http" ) -// WithBaseURL sets the client's base URL, overriding the -// default environment, if any. -func WithBaseURL(baseURL string) core.ClientOption { - return func(opts *core.ClientOptions) { - opts.BaseURL = baseURL - } +// WithBaseURL sets the base URL, overriding the default +// environment, if any. +func WithBaseURL(baseURL string) *core.BaseURLOption { + return option.WithBaseURL(baseURL) } -// WithHTTPClient uses the given HTTPClient to issue all HTTP requests. -func WithHTTPClient(httpClient core.HTTPClient) core.ClientOption { - return func(opts *core.ClientOptions) { - opts.HTTPClient = httpClient - } +// WithHTTPClient uses the given HTTPClient to issue the request. +func WithHTTPClient(httpClient core.HTTPClient) *core.HTTPClientOption { + return option.WithHTTPClient(httpClient) } -// WithHTTPHeader adds the given http.Header to all requests -// issued by the client. -func WithHTTPHeader(httpHeader http.Header) core.ClientOption { - return func(opts *core.ClientOptions) { - // Clone the headers so they can't be modified after the option call. - opts.HTTPHeader = httpHeader.Clone() - } +// WithHTTPHeader adds the given http.Header to the request. +func WithHTTPHeader(httpHeader http.Header) *core.HTTPHeaderOption { + return option.WithHTTPHeader(httpHeader) } -// WithApiKey sets the 'Authorization: Bearer ' header on every request. -func WithApiKey(apiKey string) core.ClientOption { - return func(opts *core.ClientOptions) { - opts.ApiKey = apiKey - } +// WithMaxAttempts configures the maximum number of retry attempts. +func WithMaxAttempts(attempts uint) *core.MaxAttemptsOption { + return option.WithMaxAttempts(attempts) } -// WithSeamWorkspace sets the seamWorkspace header on every request. -func WithSeamWorkspace(seamWorkspace string) core.ClientOption { - return func(opts *core.ClientOptions) { - opts.SeamWorkspace = seamWorkspace - } +// WithApiKey sets the 'Authorization: Bearer ' request header. +func WithApiKey(apiKey string) *core.ApiKeyOption { + return option.WithApiKey(apiKey) } -// WithSeamClientSessionToken sets the seamClientSessionToken header on every request. -func WithSeamClientSessionToken(seamClientSessionToken string) core.ClientOption { - return func(opts *core.ClientOptions) { - opts.SeamClientSessionToken = seamClientSessionToken - } +// WithSeamWorkspace sets the seamWorkspace request header. +func WithSeamWorkspace(seamWorkspace string) *core.SeamWorkspaceOption { + return option.WithSeamWorkspace(seamWorkspace) } -// WithClientSessionToken sets the clientSessionToken header on every request. -func WithClientSessionToken(clientSessionToken string) core.ClientOption { - return func(opts *core.ClientOptions) { - opts.ClientSessionToken = clientSessionToken - } +// WithSeamClientSessionToken sets the seamClientSessionToken request header. +func WithSeamClientSessionToken(seamClientSessionToken string) *core.SeamClientSessionTokenOption { + return option.WithSeamClientSessionToken(seamClientSessionToken) +} + +// WithClientSessionToken sets the clientSessionToken request header. +func WithClientSessionToken(clientSessionToken string) *core.ClientSessionTokenOption { + return option.WithClientSessionToken(clientSessionToken) } diff --git a/client_sessions.go b/client_sessions.go index 4b0f42b..5c7142c 100644 --- a/client_sessions.go +++ b/client_sessions.go @@ -10,52 +10,97 @@ import ( ) type ClientSessionsCreateRequest struct { - UserIdentifierKey *string `json:"user_identifier_key,omitempty"` - ConnectWebviewIds []string `json:"connect_webview_ids,omitempty"` - ConnectedAccountIds []string `json:"connected_account_ids,omitempty"` - UserIdentityIds []string `json:"user_identity_ids,omitempty"` - ExpiresAt *time.Time `json:"expires_at,omitempty"` + UserIdentifierKey *string `json:"user_identifier_key,omitempty" url:"user_identifier_key,omitempty"` + ConnectWebviewIds []string `json:"connect_webview_ids,omitempty" url:"connect_webview_ids,omitempty"` + ConnectedAccountIds []string `json:"connected_account_ids,omitempty" url:"connected_account_ids,omitempty"` + UserIdentityIds []string `json:"user_identity_ids,omitempty" url:"user_identity_ids,omitempty"` + ExpiresAt *time.Time `json:"expires_at,omitempty" url:"expires_at,omitempty"` +} + +func (c *ClientSessionsCreateRequest) UnmarshalJSON(data []byte) error { + type unmarshaler ClientSessionsCreateRequest + var body unmarshaler + if err := json.Unmarshal(data, &body); err != nil { + return err + } + *c = ClientSessionsCreateRequest(body) + return nil +} + +func (c *ClientSessionsCreateRequest) MarshalJSON() ([]byte, error) { + type embed ClientSessionsCreateRequest + var marshaler = struct { + embed + ExpiresAt *core.DateTime `json:"expires_at,omitempty"` + }{ + embed: embed(*c), + ExpiresAt: core.NewOptionalDateTime(c.ExpiresAt), + } + return json.Marshal(marshaler) } type ClientSessionsDeleteRequest struct { - ClientSessionId string `json:"client_session_id"` + ClientSessionId string `json:"client_session_id" url:"client_session_id"` } type ClientSessionsGetRequest struct { - ClientSessionId *string `json:"client_session_id,omitempty"` - UserIdentifierKey *string `json:"user_identifier_key,omitempty"` + ClientSessionId *string `json:"client_session_id,omitempty" url:"client_session_id,omitempty"` + UserIdentifierKey *string `json:"user_identifier_key,omitempty" url:"user_identifier_key,omitempty"` } type ClientSessionsGetOrCreateRequest struct { - UserIdentifierKey *string `json:"user_identifier_key,omitempty"` - ConnectWebviewIds []string `json:"connect_webview_ids,omitempty"` - ConnectedAccountIds []string `json:"connected_account_ids,omitempty"` - UserIdentityIds []string `json:"user_identity_ids,omitempty"` - ExpiresAt *time.Time `json:"expires_at,omitempty"` + UserIdentifierKey *string `json:"user_identifier_key,omitempty" url:"user_identifier_key,omitempty"` + ConnectWebviewIds []string `json:"connect_webview_ids,omitempty" url:"connect_webview_ids,omitempty"` + ConnectedAccountIds []string `json:"connected_account_ids,omitempty" url:"connected_account_ids,omitempty"` + UserIdentityIds []string `json:"user_identity_ids,omitempty" url:"user_identity_ids,omitempty"` + ExpiresAt *time.Time `json:"expires_at,omitempty" url:"expires_at,omitempty"` +} + +func (c *ClientSessionsGetOrCreateRequest) UnmarshalJSON(data []byte) error { + type unmarshaler ClientSessionsGetOrCreateRequest + var body unmarshaler + if err := json.Unmarshal(data, &body); err != nil { + return err + } + *c = ClientSessionsGetOrCreateRequest(body) + return nil +} + +func (c *ClientSessionsGetOrCreateRequest) MarshalJSON() ([]byte, error) { + type embed ClientSessionsGetOrCreateRequest + var marshaler = struct { + embed + ExpiresAt *core.DateTime `json:"expires_at,omitempty"` + }{ + embed: embed(*c), + ExpiresAt: core.NewOptionalDateTime(c.ExpiresAt), + } + return json.Marshal(marshaler) } type ClientSessionsGrantAccessRequest struct { - ClientSessionId *string `json:"client_session_id,omitempty"` - UserIdentifierKey *string `json:"user_identifier_key,omitempty"` - ConnectedAccountIds []string `json:"connected_account_ids,omitempty"` - ConnectWebviewIds []string `json:"connect_webview_ids,omitempty"` - UserIdentityIds []string `json:"user_identity_ids,omitempty"` + ClientSessionId *string `json:"client_session_id,omitempty" url:"client_session_id,omitempty"` + UserIdentifierKey *string `json:"user_identifier_key,omitempty" url:"user_identifier_key,omitempty"` + ConnectedAccountIds []string `json:"connected_account_ids,omitempty" url:"connected_account_ids,omitempty"` + ConnectWebviewIds []string `json:"connect_webview_ids,omitempty" url:"connect_webview_ids,omitempty"` + UserIdentityIds []string `json:"user_identity_ids,omitempty" url:"user_identity_ids,omitempty"` } type ClientSessionsListRequest struct { - ClientSessionId *string `json:"client_session_id,omitempty"` - UserIdentifierKey *string `json:"user_identifier_key,omitempty"` - ConnectWebviewId *string `json:"connect_webview_id,omitempty"` - WithoutUserIdentifierKey *bool `json:"without_user_identifier_key,omitempty"` + ClientSessionId *string `json:"client_session_id,omitempty" url:"client_session_id,omitempty"` + UserIdentifierKey *string `json:"user_identifier_key,omitempty" url:"user_identifier_key,omitempty"` + ConnectWebviewId *string `json:"connect_webview_id,omitempty" url:"connect_webview_id,omitempty"` + WithoutUserIdentifierKey *bool `json:"without_user_identifier_key,omitempty" url:"without_user_identifier_key,omitempty"` + UserIdentityId *string `json:"user_identity_id,omitempty" url:"user_identity_id,omitempty"` } type ClientSessionsRevokeRequest struct { - ClientSessionId string `json:"client_session_id"` + ClientSessionId string `json:"client_session_id" url:"client_session_id"` } type ClientSessionsCreateResponse struct { - ClientSession *ClientSession `json:"client_session,omitempty"` - Ok bool `json:"ok"` + ClientSession *ClientSession `json:"client_session,omitempty" url:"client_session,omitempty"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -84,7 +129,7 @@ func (c *ClientSessionsCreateResponse) String() string { } type ClientSessionsDeleteResponse struct { - Ok bool `json:"ok"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -113,8 +158,8 @@ func (c *ClientSessionsDeleteResponse) String() string { } type ClientSessionsGetOrCreateResponse struct { - ClientSession *ClientSession `json:"client_session,omitempty"` - Ok bool `json:"ok"` + ClientSession *ClientSession `json:"client_session,omitempty" url:"client_session,omitempty"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -143,8 +188,8 @@ func (c *ClientSessionsGetOrCreateResponse) String() string { } type ClientSessionsGetResponse struct { - ClientSession *ClientSession `json:"client_session,omitempty"` - Ok bool `json:"ok"` + ClientSession *ClientSession `json:"client_session,omitempty" url:"client_session,omitempty"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -173,8 +218,8 @@ func (c *ClientSessionsGetResponse) String() string { } type ClientSessionsGrantAccessResponse struct { - ClientSession *ClientSession `json:"client_session,omitempty"` - Ok bool `json:"ok"` + ClientSession *ClientSession `json:"client_session,omitempty" url:"client_session,omitempty"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -203,8 +248,8 @@ func (c *ClientSessionsGrantAccessResponse) String() string { } type ClientSessionsListResponse struct { - ClientSessions []*ClientSession `json:"client_sessions,omitempty"` - Ok bool `json:"ok"` + ClientSessions []*ClientSession `json:"client_sessions,omitempty" url:"client_sessions,omitempty"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -233,7 +278,7 @@ func (c *ClientSessionsListResponse) String() string { } type ClientSessionsRevokeResponse struct { - Ok bool `json:"ok"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } diff --git a/clientsessions/client.go b/clientsessions/client.go index c0bbe95..4f2bd2e 100644 --- a/clientsessions/client.go +++ b/clientsessions/client.go @@ -9,6 +9,7 @@ import ( errors "errors" seamapigo "github.com/seamapi/go" core "github.com/seamapi/go/core" + option "github.com/seamapi/go/option" io "io" http "net/http" ) @@ -19,25 +20,38 @@ type Client struct { header http.Header } -func NewClient(opts ...core.ClientOption) *Client { - options := core.NewClientOptions() - for _, opt := range opts { - opt(options) - } +func NewClient(opts ...option.RequestOption) *Client { + options := core.NewRequestOptions(opts...) return &Client{ baseURL: options.BaseURL, - caller: core.NewCaller(options.HTTPClient), - header: options.ToHeader(), + caller: core.NewCaller( + &core.CallerParams{ + Client: options.HTTPClient, + MaxAttempts: options.MaxAttempts, + }, + ), + header: options.ToHeader(), } } -func (c *Client) Create(ctx context.Context, request *seamapigo.ClientSessionsCreateRequest) (*seamapigo.ClientSession, error) { +func (c *Client) Create( + ctx context.Context, + request *seamapigo.ClientSessionsCreateRequest, + opts ...option.RequestOption, +) (*seamapigo.ClientSession, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "client_sessions/create" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -70,7 +84,9 @@ func (c *Client) Create(ctx context.Context, request *seamapigo.ClientSessionsCr &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -81,13 +97,24 @@ func (c *Client) Create(ctx context.Context, request *seamapigo.ClientSessionsCr return response.ClientSession, nil } -func (c *Client) Delete(ctx context.Context, request *seamapigo.ClientSessionsDeleteRequest) (*seamapigo.ClientSessionsDeleteResponse, error) { +func (c *Client) Delete( + ctx context.Context, + request *seamapigo.ClientSessionsDeleteRequest, + opts ...option.RequestOption, +) (*seamapigo.ClientSessionsDeleteResponse, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "client_sessions/delete" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -120,7 +147,9 @@ func (c *Client) Delete(ctx context.Context, request *seamapigo.ClientSessionsDe &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -131,13 +160,24 @@ func (c *Client) Delete(ctx context.Context, request *seamapigo.ClientSessionsDe return response, nil } -func (c *Client) Get(ctx context.Context, request *seamapigo.ClientSessionsGetRequest) (*seamapigo.ClientSession, error) { +func (c *Client) Get( + ctx context.Context, + request *seamapigo.ClientSessionsGetRequest, + opts ...option.RequestOption, +) (*seamapigo.ClientSession, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "client_sessions/get" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -170,7 +210,9 @@ func (c *Client) Get(ctx context.Context, request *seamapigo.ClientSessionsGetRe &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -181,13 +223,24 @@ func (c *Client) Get(ctx context.Context, request *seamapigo.ClientSessionsGetRe return response.ClientSession, nil } -func (c *Client) GetOrCreate(ctx context.Context, request *seamapigo.ClientSessionsGetOrCreateRequest) (*seamapigo.ClientSession, error) { +func (c *Client) GetOrCreate( + ctx context.Context, + request *seamapigo.ClientSessionsGetOrCreateRequest, + opts ...option.RequestOption, +) (*seamapigo.ClientSession, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "client_sessions/get_or_create" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -220,7 +273,9 @@ func (c *Client) GetOrCreate(ctx context.Context, request *seamapigo.ClientSessi &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -231,13 +286,24 @@ func (c *Client) GetOrCreate(ctx context.Context, request *seamapigo.ClientSessi return response.ClientSession, nil } -func (c *Client) GrantAccess(ctx context.Context, request *seamapigo.ClientSessionsGrantAccessRequest) (*seamapigo.ClientSessionsGrantAccessResponse, error) { +func (c *Client) GrantAccess( + ctx context.Context, + request *seamapigo.ClientSessionsGrantAccessRequest, + opts ...option.RequestOption, +) (*seamapigo.ClientSessionsGrantAccessResponse, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "client_sessions/grant_access" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -270,7 +336,9 @@ func (c *Client) GrantAccess(ctx context.Context, request *seamapigo.ClientSessi &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -281,13 +349,24 @@ func (c *Client) GrantAccess(ctx context.Context, request *seamapigo.ClientSessi return response, nil } -func (c *Client) List(ctx context.Context, request *seamapigo.ClientSessionsListRequest) ([]*seamapigo.ClientSession, error) { +func (c *Client) List( + ctx context.Context, + request *seamapigo.ClientSessionsListRequest, + opts ...option.RequestOption, +) ([]*seamapigo.ClientSession, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "client_sessions/list" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -320,7 +399,9 @@ func (c *Client) List(ctx context.Context, request *seamapigo.ClientSessionsList &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -331,13 +412,24 @@ func (c *Client) List(ctx context.Context, request *seamapigo.ClientSessionsList return response.ClientSessions, nil } -func (c *Client) Revoke(ctx context.Context, request *seamapigo.ClientSessionsRevokeRequest) (*seamapigo.ClientSessionsRevokeResponse, error) { +func (c *Client) Revoke( + ctx context.Context, + request *seamapigo.ClientSessionsRevokeRequest, + opts ...option.RequestOption, +) (*seamapigo.ClientSessionsRevokeResponse, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "client_sessions/revoke" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -370,7 +462,9 @@ func (c *Client) Revoke(ctx context.Context, request *seamapigo.ClientSessionsRe &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, diff --git a/connect_webviews.go b/connect_webviews.go index daaf216..a80ee5a 100644 --- a/connect_webviews.go +++ b/connect_webviews.go @@ -9,28 +9,28 @@ import ( ) type ConnectWebviewsCreateRequest struct { - DeviceSelectionMode *SelectionMode `json:"device_selection_mode,omitempty"` - CustomRedirectUrl *string `json:"custom_redirect_url,omitempty"` - CustomRedirectFailureUrl *string `json:"custom_redirect_failure_url,omitempty"` - AcceptedProviders []AcceptedProvider `json:"accepted_providers,omitempty"` - ProviderCategory *ProviderCategory `json:"provider_category,omitempty"` - CustomMetadata map[string]*ConnectWebviewsCreateRequestCustomMetadataValue `json:"custom_metadata,omitempty"` - AutomaticallyManageNewDevices *bool `json:"automatically_manage_new_devices,omitempty"` - WaitForDeviceCreation *bool `json:"wait_for_device_creation,omitempty"` + DeviceSelectionMode *SelectionMode `json:"device_selection_mode,omitempty" url:"device_selection_mode,omitempty"` + CustomRedirectUrl *string `json:"custom_redirect_url,omitempty" url:"custom_redirect_url,omitempty"` + CustomRedirectFailureUrl *string `json:"custom_redirect_failure_url,omitempty" url:"custom_redirect_failure_url,omitempty"` + AcceptedProviders []AcceptedProvider `json:"accepted_providers,omitempty" url:"accepted_providers,omitempty"` + ProviderCategory *ProviderCategory `json:"provider_category,omitempty" url:"provider_category,omitempty"` + CustomMetadata map[string]*ConnectWebviewsCreateRequestCustomMetadataValue `json:"custom_metadata,omitempty" url:"custom_metadata,omitempty"` + AutomaticallyManageNewDevices *bool `json:"automatically_manage_new_devices,omitempty" url:"automatically_manage_new_devices,omitempty"` + WaitForDeviceCreation *bool `json:"wait_for_device_creation,omitempty" url:"wait_for_device_creation,omitempty"` } type ConnectWebviewsDeleteRequest struct { - ConnectWebviewId string `json:"connect_webview_id"` + ConnectWebviewId string `json:"connect_webview_id" url:"connect_webview_id"` } type ConnectWebviewsGetRequest struct { - ConnectWebviewId string `json:"connect_webview_id"` + ConnectWebviewId string `json:"connect_webview_id" url:"connect_webview_id"` } type ConnectWebviewsListRequest struct { - UserIdentifierKey *string `json:"user_identifier_key,omitempty"` + UserIdentifierKey *string `json:"user_identifier_key,omitempty" url:"user_identifier_key,omitempty"` // Returns devices where the webview's custom_metadata contains all of the provided key/value pairs. - CustomMetadataHas map[string]*ConnectWebviewsListRequestCustomMetadataHasValue `json:"custom_metadata_has,omitempty"` + CustomMetadataHas map[string]*ConnectWebviewsListRequestCustomMetadataHasValue `json:"custom_metadata_has,omitempty" url:"custom_metadata_has,omitempty"` } type AcceptedProvider string @@ -240,8 +240,8 @@ func (c *ConnectWebviewsCreateRequestCustomMetadataValue) Accept(visitor Connect } type ConnectWebviewsCreateResponse struct { - ConnectWebview *ConnectWebview `json:"connect_webview,omitempty"` - Ok bool `json:"ok"` + ConnectWebview *ConnectWebview `json:"connect_webview,omitempty" url:"connect_webview,omitempty"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -270,7 +270,7 @@ func (c *ConnectWebviewsCreateResponse) String() string { } type ConnectWebviewsDeleteResponse struct { - Ok bool `json:"ok"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -299,8 +299,8 @@ func (c *ConnectWebviewsDeleteResponse) String() string { } type ConnectWebviewsGetResponse struct { - ConnectWebview *ConnectWebview `json:"connect_webview,omitempty"` - Ok bool `json:"ok"` + ConnectWebview *ConnectWebview `json:"connect_webview,omitempty" url:"connect_webview,omitempty"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -402,8 +402,8 @@ func (c *ConnectWebviewsListRequestCustomMetadataHasValue) Accept(visitor Connec } type ConnectWebviewsListResponse struct { - ConnectWebviews []*ConnectWebview `json:"connect_webviews,omitempty"` - Ok bool `json:"ok"` + ConnectWebviews []*ConnectWebview `json:"connect_webviews,omitempty" url:"connect_webviews,omitempty"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -432,6 +432,6 @@ func (c *ConnectWebviewsListResponse) String() string { } type ConnectWebviewsViewRequest struct { - ConnectWebviewId string `json:"-"` - AuthToken string `json:"-"` + ConnectWebviewId string `json:"-" url:"connect_webview_id"` + AuthToken string `json:"-" url:"auth_token"` } diff --git a/connected_accounts.go b/connected_accounts.go index 8179f08..1cfdff8 100644 --- a/connected_accounts.go +++ b/connected_accounts.go @@ -9,17 +9,17 @@ import ( ) type ConnectedAccountsDeleteRequest struct { - ConnectedAccountId string `json:"connected_account_id"` - Sync *bool `json:"sync,omitempty"` + ConnectedAccountId string `json:"connected_account_id" url:"connected_account_id"` + Sync *bool `json:"sync,omitempty" url:"sync,omitempty"` } type ConnectedAccountsListRequest struct { // Returns devices where the account's custom_metadata contains all of the provided key/value pairs. - CustomMetadataHas map[string]*ConnectedAccountsListRequestCustomMetadataHasValue `json:"custom_metadata_has,omitempty"` + CustomMetadataHas map[string]*ConnectedAccountsListRequestCustomMetadataHasValue `json:"custom_metadata_has,omitempty" url:"custom_metadata_has,omitempty"` } type ConnectedAccountsDeleteResponse struct { - Ok bool `json:"ok"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -105,8 +105,8 @@ func (c *ConnectedAccountsGetRequest) Accept(visitor ConnectedAccountsGetRequest } type ConnectedAccountsGetResponse struct { - ConnectedAccount *ConnectedAccount `json:"connected_account,omitempty"` - Ok bool `json:"ok"` + ConnectedAccount *ConnectedAccount `json:"connected_account,omitempty" url:"connected_account,omitempty"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -208,8 +208,8 @@ func (c *ConnectedAccountsListRequestCustomMetadataHasValue) Accept(visitor Conn } type ConnectedAccountsListResponse struct { - ConnectedAccounts []*ConnectedAccount `json:"connected_accounts,omitempty"` - Ok bool `json:"ok"` + ConnectedAccounts []*ConnectedAccount `json:"connected_accounts,omitempty" url:"connected_accounts,omitempty"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -311,8 +311,8 @@ func (c *ConnectedAccountsUpdateRequestCustomMetadataValue) Accept(visitor Conne } type ConnectedAccountsUpdateResponse struct { - ConnectedAccount *ConnectedAccount `json:"connected_account,omitempty"` - Ok bool `json:"ok"` + ConnectedAccount *ConnectedAccount `json:"connected_account,omitempty" url:"connected_account,omitempty"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -341,7 +341,7 @@ func (c *ConnectedAccountsUpdateResponse) String() string { } type ConnectedAccountsUpdateRequest struct { - ConnectedAccountId string `json:"connected_account_id"` - AutomaticallyManageNewDevices *bool `json:"automatically_manage_new_devices,omitempty"` - CustomMetadata map[string]*ConnectedAccountsUpdateRequestCustomMetadataValue `json:"custom_metadata,omitempty"` + ConnectedAccountId string `json:"connected_account_id" url:"connected_account_id"` + AutomaticallyManageNewDevices *bool `json:"automatically_manage_new_devices,omitempty" url:"automatically_manage_new_devices,omitempty"` + CustomMetadata map[string]*ConnectedAccountsUpdateRequestCustomMetadataValue `json:"custom_metadata,omitempty" url:"custom_metadata,omitempty"` } diff --git a/connectedaccounts/client.go b/connectedaccounts/client.go index e8f1f84..edf4be7 100644 --- a/connectedaccounts/client.go +++ b/connectedaccounts/client.go @@ -9,6 +9,7 @@ import ( errors "errors" seamapigo "github.com/seamapi/go" core "github.com/seamapi/go/core" + option "github.com/seamapi/go/option" io "io" http "net/http" ) @@ -19,25 +20,38 @@ type Client struct { header http.Header } -func NewClient(opts ...core.ClientOption) *Client { - options := core.NewClientOptions() - for _, opt := range opts { - opt(options) - } +func NewClient(opts ...option.RequestOption) *Client { + options := core.NewRequestOptions(opts...) return &Client{ baseURL: options.BaseURL, - caller: core.NewCaller(options.HTTPClient), - header: options.ToHeader(), + caller: core.NewCaller( + &core.CallerParams{ + Client: options.HTTPClient, + MaxAttempts: options.MaxAttempts, + }, + ), + header: options.ToHeader(), } } -func (c *Client) Delete(ctx context.Context, request *seamapigo.ConnectedAccountsDeleteRequest) (*seamapigo.ConnectedAccountsDeleteResponse, error) { +func (c *Client) Delete( + ctx context.Context, + request *seamapigo.ConnectedAccountsDeleteRequest, + opts ...option.RequestOption, +) (*seamapigo.ConnectedAccountsDeleteResponse, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "connected_accounts/delete" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -70,7 +84,9 @@ func (c *Client) Delete(ctx context.Context, request *seamapigo.ConnectedAccount &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -81,13 +97,24 @@ func (c *Client) Delete(ctx context.Context, request *seamapigo.ConnectedAccount return response, nil } -func (c *Client) Get(ctx context.Context, request *seamapigo.ConnectedAccountsGetRequest) (*seamapigo.ConnectedAccount, error) { +func (c *Client) Get( + ctx context.Context, + request *seamapigo.ConnectedAccountsGetRequest, + opts ...option.RequestOption, +) (*seamapigo.ConnectedAccount, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "connected_accounts/get" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -120,7 +147,9 @@ func (c *Client) Get(ctx context.Context, request *seamapigo.ConnectedAccountsGe &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -131,13 +160,24 @@ func (c *Client) Get(ctx context.Context, request *seamapigo.ConnectedAccountsGe return response.ConnectedAccount, nil } -func (c *Client) List(ctx context.Context, request *seamapigo.ConnectedAccountsListRequest) ([]*seamapigo.ConnectedAccount, error) { +func (c *Client) List( + ctx context.Context, + request *seamapigo.ConnectedAccountsListRequest, + opts ...option.RequestOption, +) ([]*seamapigo.ConnectedAccount, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "connected_accounts/list" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -170,7 +210,9 @@ func (c *Client) List(ctx context.Context, request *seamapigo.ConnectedAccountsL &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -181,13 +223,24 @@ func (c *Client) List(ctx context.Context, request *seamapigo.ConnectedAccountsL return response.ConnectedAccounts, nil } -func (c *Client) Update(ctx context.Context, request *seamapigo.ConnectedAccountsUpdateRequest) (*seamapigo.ConnectedAccount, error) { +func (c *Client) Update( + ctx context.Context, + request *seamapigo.ConnectedAccountsUpdateRequest, + opts ...option.RequestOption, +) (*seamapigo.ConnectedAccount, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "connected_accounts/update" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -220,7 +273,9 @@ func (c *Client) Update(ctx context.Context, request *seamapigo.ConnectedAccount &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, diff --git a/connectwebviews/client.go b/connectwebviews/client.go index 9cc88f6..94fc55f 100644 --- a/connectwebviews/client.go +++ b/connectwebviews/client.go @@ -7,12 +7,11 @@ import ( context "context" json "encoding/json" errors "errors" - fmt "fmt" seamapigo "github.com/seamapi/go" core "github.com/seamapi/go/core" + option "github.com/seamapi/go/option" io "io" http "net/http" - url "net/url" ) type Client struct { @@ -21,25 +20,38 @@ type Client struct { header http.Header } -func NewClient(opts ...core.ClientOption) *Client { - options := core.NewClientOptions() - for _, opt := range opts { - opt(options) - } +func NewClient(opts ...option.RequestOption) *Client { + options := core.NewRequestOptions(opts...) return &Client{ baseURL: options.BaseURL, - caller: core.NewCaller(options.HTTPClient), - header: options.ToHeader(), + caller: core.NewCaller( + &core.CallerParams{ + Client: options.HTTPClient, + MaxAttempts: options.MaxAttempts, + }, + ), + header: options.ToHeader(), } } -func (c *Client) Create(ctx context.Context, request *seamapigo.ConnectWebviewsCreateRequest) (*seamapigo.ConnectWebview, error) { +func (c *Client) Create( + ctx context.Context, + request *seamapigo.ConnectWebviewsCreateRequest, + opts ...option.RequestOption, +) (*seamapigo.ConnectWebview, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "connect_webviews/create" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -72,7 +84,9 @@ func (c *Client) Create(ctx context.Context, request *seamapigo.ConnectWebviewsC &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -83,13 +97,24 @@ func (c *Client) Create(ctx context.Context, request *seamapigo.ConnectWebviewsC return response.ConnectWebview, nil } -func (c *Client) Delete(ctx context.Context, request *seamapigo.ConnectWebviewsDeleteRequest) (*seamapigo.ConnectWebviewsDeleteResponse, error) { +func (c *Client) Delete( + ctx context.Context, + request *seamapigo.ConnectWebviewsDeleteRequest, + opts ...option.RequestOption, +) (*seamapigo.ConnectWebviewsDeleteResponse, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "connect_webviews/delete" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -122,7 +147,9 @@ func (c *Client) Delete(ctx context.Context, request *seamapigo.ConnectWebviewsD &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -133,13 +160,24 @@ func (c *Client) Delete(ctx context.Context, request *seamapigo.ConnectWebviewsD return response, nil } -func (c *Client) Get(ctx context.Context, request *seamapigo.ConnectWebviewsGetRequest) (*seamapigo.ConnectWebview, error) { +func (c *Client) Get( + ctx context.Context, + request *seamapigo.ConnectWebviewsGetRequest, + opts ...option.RequestOption, +) (*seamapigo.ConnectWebview, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "connect_webviews/get" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -172,7 +210,9 @@ func (c *Client) Get(ctx context.Context, request *seamapigo.ConnectWebviewsGetR &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -183,13 +223,24 @@ func (c *Client) Get(ctx context.Context, request *seamapigo.ConnectWebviewsGetR return response.ConnectWebview, nil } -func (c *Client) List(ctx context.Context, request *seamapigo.ConnectWebviewsListRequest) ([]*seamapigo.ConnectWebview, error) { +func (c *Client) List( + ctx context.Context, + request *seamapigo.ConnectWebviewsListRequest, + opts ...option.RequestOption, +) ([]*seamapigo.ConnectWebview, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "connect_webviews/list" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -222,7 +273,9 @@ func (c *Client) List(ctx context.Context, request *seamapigo.ConnectWebviewsLis &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -233,20 +286,32 @@ func (c *Client) List(ctx context.Context, request *seamapigo.ConnectWebviewsLis return response.ConnectWebviews, nil } -func (c *Client) View(ctx context.Context, request *seamapigo.ConnectWebviewsViewRequest) error { +func (c *Client) View( + ctx context.Context, + request *seamapigo.ConnectWebviewsViewRequest, + opts ...option.RequestOption, +) error { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "connect_webviews/view" - queryParams := make(url.Values) - queryParams.Add("connect_webview_id", fmt.Sprintf("%v", request.ConnectWebviewId)) - queryParams.Add("auth_token", fmt.Sprintf("%v", request.AuthToken)) + queryParams, err := core.QueryValues(request) + if err != nil { + return err + } if len(queryParams) > 0 { endpointURL += "?" + queryParams.Encode() } + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -278,7 +343,9 @@ func (c *Client) View(ctx context.Context, request *seamapigo.ConnectWebviewsVie &core.CallParams{ URL: endpointURL, Method: http.MethodGet, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, ErrorDecoder: errorDecoder, }, ); err != nil { diff --git a/core/client_option.go b/core/client_option.go deleted file mode 100644 index 161c8ac..0000000 --- a/core/client_option.go +++ /dev/null @@ -1,55 +0,0 @@ -// This file was auto-generated by Fern from our API Definition. - -package core - -import ( - fmt "fmt" - http "net/http" -) - -// ClientOption adapts the behavior of the generated client. -type ClientOption func(*ClientOptions) - -// ClientOptions defines all of the possible client options. -// This type is primarily used by the generated code and is -// not meant to be used directly; use ClientOption instead. -type ClientOptions struct { - BaseURL string - HTTPClient HTTPClient - HTTPHeader http.Header - ApiKey string - SeamWorkspace string - SeamClientSessionToken string - ClientSessionToken string -} - -// NewClientOptions returns a new *ClientOptions value. -// This function is primarily used by the generated code and is -// not meant to be used directly; use ClientOption instead. -func NewClientOptions() *ClientOptions { - return &ClientOptions{ - HTTPClient: http.DefaultClient, - HTTPHeader: make(http.Header), - } -} - -// ToHeader maps the configured client options into a http.Header issued -// on every request. -func (c *ClientOptions) ToHeader() http.Header { - header := c.cloneHeader() - if c.ApiKey != "" { - header.Set("Authorization", "Bearer "+c.ApiKey) - } - header.Set("seam-workspace", fmt.Sprintf("%v", c.SeamWorkspace)) - header.Set("seam-client-session-token", fmt.Sprintf("%v", c.SeamClientSessionToken)) - header.Set("client-session-token", fmt.Sprintf("%v", c.ClientSessionToken)) - return header -} - -func (c *ClientOptions) cloneHeader() http.Header { - headers := c.HTTPHeader.Clone() - headers.Set("X-Fern-Language", "Go") - headers.Set("X-Fern-SDK-Name", "github.com/seamapi/go") - headers.Set("X-Fern-SDK-Version", "v0.2.10") - return headers -} diff --git a/core/core.go b/core/core.go index 10e757f..5277d13 100644 --- a/core/core.go +++ b/core/core.go @@ -22,6 +22,21 @@ type HTTPClient interface { Do(*http.Request) (*http.Response, error) } +// MergeHeaders merges the given headers together, where the right +// takes precedence over the left. +func MergeHeaders(left, right http.Header) http.Header { + for key, values := range right { + if len(values) > 1 { + left[key] = values + continue + } + if value := right.Get(key); value != "" { + left.Set(key, value) + } + } + return left +} + // WriteMultipartJSON writes the given value as a JSON part. // This is used to serialize non-primitive multipart properties // (i.e. lists, objects, etc). @@ -78,13 +93,29 @@ type ErrorDecoder func(statusCode int, body io.Reader) error // Caller calls APIs and deserializes their response, if any. type Caller struct { - client HTTPClient + client HTTPClient + retrier *Retrier +} + +// CallerParams represents the parameters used to constrcut a new *Caller. +type CallerParams struct { + Client HTTPClient + MaxAttempts uint } -// NewCaller returns a new *Caller backed by the given HTTP client. -func NewCaller(client HTTPClient) *Caller { +// NewCaller returns a new *Caller backed by the given parameters. +func NewCaller(params *CallerParams) *Caller { + var httpClient HTTPClient = http.DefaultClient + if params.Client != nil { + httpClient = params.Client + } + var retryOptions []RetryOption + if params.MaxAttempts > 0 { + retryOptions = append(retryOptions, WithMaxAttempts(params.MaxAttempts)) + } return &Caller{ - client: client, + client: httpClient, + retrier: NewRetrier(retryOptions...), } } @@ -92,7 +123,9 @@ func NewCaller(client HTTPClient) *Caller { type CallParams struct { URL string Method string + MaxAttempts uint Headers http.Header + Client HTTPClient Request interface{} Response interface{} ResponseIsOptional bool @@ -111,7 +144,23 @@ func (c *Caller) Call(ctx context.Context, params *CallParams) error { return err } - resp, err := c.client.Do(req) + client := c.client + if params.Client != nil { + // Use the HTTP client scoped to the request. + client = params.Client + } + + var retryOptions []RetryOption + if params.MaxAttempts > 0 { + retryOptions = append(retryOptions, WithMaxAttempts(params.MaxAttempts)) + } + + resp, err := c.retrier.Run( + client.Do, + req, + params.ErrorDecoder, + retryOptions..., + ) if err != nil { return err } diff --git a/core/core_test.go b/core/core_test.go index 70a59ed..f476f9e 100644 --- a/core/core_test.go +++ b/core/core_test.go @@ -113,7 +113,11 @@ func TestCall(t *testing.T) { server = newTestServer(t, test) client = server.Client() ) - caller := NewCaller(client) + caller := NewCaller( + &CallerParams{ + Client: client, + }, + ) var response *Response err := caller.Call( context.Background(), @@ -137,6 +141,68 @@ func TestCall(t *testing.T) { } } +func TestMergeHeaders(t *testing.T) { + t.Run("both empty", func(t *testing.T) { + merged := MergeHeaders(make(http.Header), make(http.Header)) + assert.Empty(t, merged) + }) + + t.Run("empty left", func(t *testing.T) { + left := make(http.Header) + + right := make(http.Header) + right.Set("X-API-Version", "0.0.1") + + merged := MergeHeaders(left, right) + assert.Equal(t, "0.0.1", merged.Get("X-API-Version")) + }) + + t.Run("empty right", func(t *testing.T) { + left := make(http.Header) + left.Set("X-API-Version", "0.0.1") + + right := make(http.Header) + + merged := MergeHeaders(left, right) + assert.Equal(t, "0.0.1", merged.Get("X-API-Version")) + }) + + t.Run("single value override", func(t *testing.T) { + left := make(http.Header) + left.Set("X-API-Version", "0.0.0") + + right := make(http.Header) + right.Set("X-API-Version", "0.0.1") + + merged := MergeHeaders(left, right) + assert.Equal(t, []string{"0.0.1"}, merged.Values("X-API-Version")) + }) + + t.Run("multiple value override", func(t *testing.T) { + left := make(http.Header) + left.Set("X-API-Versions", "0.0.0") + + right := make(http.Header) + right.Add("X-API-Versions", "0.0.1") + right.Add("X-API-Versions", "0.0.2") + + merged := MergeHeaders(left, right) + assert.Equal(t, []string{"0.0.1", "0.0.2"}, merged.Values("X-API-Versions")) + }) + + t.Run("disjoint merge", func(t *testing.T) { + left := make(http.Header) + left.Set("X-API-Tenancy", "test") + + right := make(http.Header) + right.Set("X-API-Version", "0.0.1") + + merged := MergeHeaders(left, right) + assert.Equal(t, []string{"test"}, merged.Values("X-API-Tenancy")) + assert.Equal(t, []string{"0.0.1"}, merged.Values("X-API-Version")) + }) +} + // newTestServer returns a new *httptest.Server configured with the // given test parameters. func newTestServer(t *testing.T, tc *TestCase) *httptest.Server { @@ -206,8 +272,7 @@ func newTestErrorDecoder(t *testing.T) func(int, io.Reader) error { apiError = NewAPIError(statusCode, errors.New(string(raw))) decoder = json.NewDecoder(bytes.NewReader(raw)) ) - switch statusCode { - case 404: + if statusCode == http.StatusNotFound { value := new(NotFoundError) value.APIError = apiError require.NoError(t, decoder.Decode(value)) diff --git a/core/query.go b/core/query.go new file mode 100644 index 0000000..479cbb2 --- /dev/null +++ b/core/query.go @@ -0,0 +1,219 @@ +package core + +import ( + "encoding/base64" + "fmt" + "net/url" + "reflect" + "strings" + "time" + + "github.com/google/uuid" +) + +var ( + bytesType = reflect.TypeOf([]byte{}) + queryEncoderType = reflect.TypeOf(new(QueryEncoder)).Elem() + timeType = reflect.TypeOf(time.Time{}) + uuidType = reflect.TypeOf(uuid.UUID{}) +) + +// QueryEncoder is an interface implemented by any type that wishes to encode +// itself into URL values in a non-standard way. +type QueryEncoder interface { + EncodeQueryValues(key string, v *url.Values) error +} + +// QueryValues encodes url.Values from request objects. +// +// Note: This type is inspired by Google's query encoding library, but +// supports far less customization and is tailored to fit this SDK's use case. +// +// Ref: https://github.com/google/go-querystring +func QueryValues(v interface{}) (url.Values, error) { + values := make(url.Values) + val := reflect.ValueOf(v) + for val.Kind() == reflect.Ptr { + if val.IsNil() { + return values, nil + } + val = val.Elem() + } + + if v == nil { + return values, nil + } + + if val.Kind() != reflect.Struct { + return nil, fmt.Errorf("query: Values() expects struct input. Got %v", val.Kind()) + } + + err := reflectValue(values, val, "") + return values, err +} + +// reflectValue populates the values parameter from the struct fields in val. +// Embedded structs are followed recursively (using the rules defined in the +// Values function documentation) breadth-first. +func reflectValue(values url.Values, val reflect.Value, scope string) error { + typ := val.Type() + for i := 0; i < typ.NumField(); i++ { + sf := typ.Field(i) + if sf.PkgPath != "" && !sf.Anonymous { + // Skip unexported fields. + continue + } + + sv := val.Field(i) + tag := sf.Tag.Get("url") + if tag == "" || tag == "-" { + continue + } + + name, opts := parseTag(tag) + if name == "" { + name = sf.Name + } + + if scope != "" { + name = scope + "[" + name + "]" + } + + if opts.Contains("omitempty") && isEmptyValue(sv) { + continue + } + + if sv.Type().Implements(queryEncoderType) { + // If sv is a nil pointer and the custom encoder is defined on a non-pointer + // method receiver, set sv to the zero value of the underlying type + if !reflect.Indirect(sv).IsValid() && sv.Type().Elem().Implements(queryEncoderType) { + sv = reflect.New(sv.Type().Elem()) + } + + m := sv.Interface().(QueryEncoder) + if err := m.EncodeQueryValues(name, &values); err != nil { + return err + } + continue + } + + // Recursively dereference pointers, but stop at nil pointers. + for sv.Kind() == reflect.Ptr { + if sv.IsNil() { + break + } + sv = sv.Elem() + } + + if sv.Type() == uuidType || sv.Type() == bytesType || sv.Type() == timeType { + values.Add(name, valueString(sv, opts, sf)) + continue + } + + if sv.Kind() == reflect.Slice || sv.Kind() == reflect.Array { + if sv.Len() == 0 { + // Skip if slice or array is empty. + continue + } + for i := 0; i < sv.Len(); i++ { + values.Add(name, valueString(sv.Index(i), opts, sf)) + } + continue + } + + if sv.Kind() == reflect.Struct { + if err := reflectValue(values, sv, name); err != nil { + return err + } + continue + } + + values.Add(name, valueString(sv, opts, sf)) + } + + return nil +} + +// valueString returns the string representation of a value. +func valueString(v reflect.Value, opts tagOptions, sf reflect.StructField) string { + for v.Kind() == reflect.Ptr { + if v.IsNil() { + return "" + } + v = v.Elem() + } + + if v.Type() == timeType { + t := v.Interface().(time.Time) + if format := sf.Tag.Get("format"); format == "date" { + return t.Format("2006-01-02") + } + return t.Format(time.RFC3339) + } + + if v.Type() == uuidType { + u := v.Interface().(uuid.UUID) + return u.String() + } + + if v.Type() == bytesType { + b := v.Interface().([]byte) + return base64.StdEncoding.EncodeToString(b) + } + + return fmt.Sprint(v.Interface()) +} + +// isEmptyValue checks if a value should be considered empty for the purposes +// of omitting fields with the "omitempty" option. +func isEmptyValue(v reflect.Value) bool { + type zeroable interface { + IsZero() bool + } + + if !v.IsNil() { + if z, ok := v.Interface().(zeroable); ok { + return z.IsZero() + } + } + + switch v.Kind() { + case reflect.Array, reflect.Map, reflect.Slice, reflect.String: + return v.Len() == 0 + case reflect.Bool: + return !v.Bool() + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return v.Int() == 0 + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + return v.Uint() == 0 + case reflect.Float32, reflect.Float64: + return v.Float() == 0 + case reflect.Interface, reflect.Ptr: + return v.IsNil() + case reflect.Invalid, reflect.Complex64, reflect.Complex128, reflect.Chan, reflect.Func, reflect.Struct, reflect.UnsafePointer: + return false + } + + return false +} + +// tagOptions is the string following a comma in a struct field's "url" tag, or +// the empty string. It does not include the leading comma. +type tagOptions []string + +// parseTag splits a struct field's url tag into its name and comma-separated +// options. +func parseTag(tag string) (string, tagOptions) { + s := strings.Split(tag, ",") + return s[0], s[1:] +} + +// Contains checks whether the tagOptions contains the specified option. +func (o tagOptions) Contains(option string) bool { + for _, s := range o { + if s == option { + return true + } + } + return false +} diff --git a/core/query_test.go b/core/query_test.go new file mode 100644 index 0000000..4f0d392 --- /dev/null +++ b/core/query_test.go @@ -0,0 +1,146 @@ +package core + +import ( + "testing" + "time" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestQueryValues(t *testing.T) { + t.Run("empty optional", func(t *testing.T) { + type nested struct { + Value *string `json:"value,omitempty" url:"value,omitempty"` + } + type example struct { + Nested *nested `json:"nested,omitempty" url:"nested,omitempty"` + } + + values, err := QueryValues(&example{}) + require.NoError(t, err) + assert.Empty(t, values) + }) + + t.Run("empty required", func(t *testing.T) { + type nested struct { + Value *string `json:"value,omitempty" url:"value,omitempty"` + } + type example struct { + Required string `json:"required" url:"required"` + Nested *nested `json:"nested,omitempty" url:"nested,omitempty"` + } + + values, err := QueryValues(&example{}) + require.NoError(t, err) + assert.Equal(t, "required=", values.Encode()) + }) + + t.Run("allow multiple", func(t *testing.T) { + type example struct { + Values []string `json:"values" url:"values"` + } + + values, err := QueryValues( + &example{ + Values: []string{"foo", "bar", "baz"}, + }, + ) + require.NoError(t, err) + assert.Equal(t, "values=foo&values=bar&values=baz", values.Encode()) + }) + + t.Run("nested object", func(t *testing.T) { + type nested struct { + Value *string `json:"value,omitempty" url:"value,omitempty"` + } + type example struct { + Required string `json:"required" url:"required"` + Nested *nested `json:"nested,omitempty" url:"nested,omitempty"` + } + + nestedValue := "nestedValue" + values, err := QueryValues( + &example{ + Required: "requiredValue", + Nested: &nested{ + Value: &nestedValue, + }, + }, + ) + require.NoError(t, err) + assert.Equal(t, "nested%5Bvalue%5D=nestedValue&required=requiredValue", values.Encode()) + }) + + t.Run("url unspecified", func(t *testing.T) { + type example struct { + Required string `json:"required" url:"required"` + NotFound string `json:"notFound"` + } + + values, err := QueryValues( + &example{ + Required: "requiredValue", + NotFound: "notFound", + }, + ) + require.NoError(t, err) + assert.Equal(t, "required=requiredValue", values.Encode()) + }) + + t.Run("url ignored", func(t *testing.T) { + type example struct { + Required string `json:"required" url:"required"` + NotFound string `json:"notFound" url:"-"` + } + + values, err := QueryValues( + &example{ + Required: "requiredValue", + NotFound: "notFound", + }, + ) + require.NoError(t, err) + assert.Equal(t, "required=requiredValue", values.Encode()) + }) + + t.Run("datetime", func(t *testing.T) { + type example struct { + DateTime time.Time `json:"dateTime" url:"dateTime"` + } + + values, err := QueryValues( + &example{ + DateTime: time.Date(1994, 3, 16, 12, 34, 56, 0, time.UTC), + }, + ) + require.NoError(t, err) + assert.Equal(t, "dateTime=1994-03-16T12%3A34%3A56Z", values.Encode()) + }) + + t.Run("date", func(t *testing.T) { + type example struct { + Date time.Time `json:"date" url:"date" format:"date"` + } + + values, err := QueryValues( + &example{ + Date: time.Date(1994, 3, 16, 12, 34, 56, 0, time.UTC), + }, + ) + require.NoError(t, err) + assert.Equal(t, "date=1994-03-16", values.Encode()) + }) + + t.Run("optional time", func(t *testing.T) { + type example struct { + Date *time.Time `json:"date,omitempty" url:"date,omitempty" format:"date"` + } + + values, err := QueryValues( + &example{}, + ) + require.NoError(t, err) + assert.Empty(t, values.Encode()) + }) +} diff --git a/core/request_option.go b/core/request_option.go new file mode 100644 index 0000000..0b46194 --- /dev/null +++ b/core/request_option.go @@ -0,0 +1,135 @@ +// This file was auto-generated by Fern from our API Definition. + +package core + +import ( + fmt "fmt" + http "net/http" +) + +// RequestOption adapts the behavior of the client or an individual request. +type RequestOption interface { + applyRequestOptions(*RequestOptions) +} + +// RequestOptions defines all of the possible request options. +// +// This type is primarily used by the generated code and is not meant +// to be used directly; use the option package instead. +type RequestOptions struct { + BaseURL string + HTTPClient HTTPClient + HTTPHeader http.Header + MaxAttempts uint + ApiKey string + SeamWorkspace string + SeamClientSessionToken string + ClientSessionToken string +} + +// NewRequestOptions returns a new *RequestOptions value. +// +// This function is primarily used by the generated code and is not meant +// to be used directly; use RequestOption instead. +func NewRequestOptions(opts ...RequestOption) *RequestOptions { + options := &RequestOptions{ + HTTPHeader: make(http.Header), + } + for _, opt := range opts { + opt.applyRequestOptions(options) + } + return options +} + +// ToHeader maps the configured request options into a http.Header used +// for the request(s). +func (r *RequestOptions) ToHeader() http.Header { + header := r.cloneHeader() + if r.ApiKey != "" { + header.Set("Authorization", "Bearer "+r.ApiKey) + } + header.Set("seam-workspace", fmt.Sprintf("%v", r.SeamWorkspace)) + header.Set("seam-client-session-token", fmt.Sprintf("%v", r.SeamClientSessionToken)) + header.Set("client-session-token", fmt.Sprintf("%v", r.ClientSessionToken)) + return header +} + +func (r *RequestOptions) cloneHeader() http.Header { + headers := r.HTTPHeader.Clone() + headers.Set("X-Fern-Language", "Go") + headers.Set("X-Fern-SDK-Name", "github.com/seamapi/go") + headers.Set("X-Fern-SDK-Version", "v0.2.13") + return headers +} + +// BaseURLOption implements the RequestOption interface. +type BaseURLOption struct { + BaseURL string +} + +func (b *BaseURLOption) applyRequestOptions(opts *RequestOptions) { + opts.BaseURL = b.BaseURL +} + +// HTTPClientOption implements the RequestOption interface. +type HTTPClientOption struct { + HTTPClient HTTPClient +} + +func (h *HTTPClientOption) applyRequestOptions(opts *RequestOptions) { + opts.HTTPClient = h.HTTPClient +} + +// HTTPHeaderOption implements the RequestOption interface. +type HTTPHeaderOption struct { + HTTPHeader http.Header +} + +func (h *HTTPHeaderOption) applyRequestOptions(opts *RequestOptions) { + opts.HTTPHeader = h.HTTPHeader +} + +// MaxAttemptsOption implements the RequestOption interface. +type MaxAttemptsOption struct { + MaxAttempts uint +} + +func (m *MaxAttemptsOption) applyRequestOptions(opts *RequestOptions) { + opts.MaxAttempts = m.MaxAttempts +} + +// ApiKeyOption implements the RequestOption interface. +type ApiKeyOption struct { + ApiKey string +} + +func (a *ApiKeyOption) applyRequestOptions(opts *RequestOptions) { + opts.ApiKey = a.ApiKey +} + +// SeamWorkspaceOption implements the RequestOption interface. +type SeamWorkspaceOption struct { + SeamWorkspace string +} + +func (s *SeamWorkspaceOption) applyRequestOptions(opts *RequestOptions) { + opts.SeamWorkspace = s.SeamWorkspace +} + +// SeamClientSessionTokenOption implements the RequestOption interface. +type SeamClientSessionTokenOption struct { + SeamClientSessionToken string +} + +func (s *SeamClientSessionTokenOption) applyRequestOptions(opts *RequestOptions) { + opts.SeamClientSessionToken = s.SeamClientSessionToken +} + +// ClientSessionTokenOption implements the RequestOption interface. +type ClientSessionTokenOption struct { + ClientSessionToken string +} + +func (c *ClientSessionTokenOption) applyRequestOptions(opts *RequestOptions) { + opts.ClientSessionToken = c.ClientSessionToken +} diff --git a/core/retrier.go b/core/retrier.go new file mode 100644 index 0000000..ea24916 --- /dev/null +++ b/core/retrier.go @@ -0,0 +1,166 @@ +package core + +import ( + "crypto/rand" + "math/big" + "net/http" + "time" +) + +const ( + defaultRetryAttempts = 2 + minRetryDelay = 500 * time.Millisecond + maxRetryDelay = 5000 * time.Millisecond +) + +// RetryOption adapts the behavior the *Retrier. +type RetryOption func(*retryOptions) + +// RetryFunc is a retriable HTTP function call (i.e. *http.Client.Do). +type RetryFunc func(*http.Request) (*http.Response, error) + +// WithMaxAttempts configures the maximum number of attempts +// of the *Retrier. +func WithMaxAttempts(attempts uint) RetryOption { + return func(opts *retryOptions) { + opts.attempts = attempts + } +} + +// Retrier retries failed requests a configurable number of times with an +// exponential back-off between each retry. +type Retrier struct { + attempts uint +} + +// NewRetrier constructs a new *Retrier with the given options, if any. +func NewRetrier(opts ...RetryOption) *Retrier { + options := new(retryOptions) + for _, opt := range opts { + opt(options) + } + attempts := uint(defaultRetryAttempts) + if options.attempts > 0 { + attempts = options.attempts + } + return &Retrier{ + attempts: attempts, + } +} + +// Run issues the request and, upon failure, retries the request if possible. +// +// The request will be retried as long as the request is deemed retriable and the +// number of retry attempts has not grown larger than the configured retry limit. +func (r *Retrier) Run( + fn RetryFunc, + request *http.Request, + errorDecoder ErrorDecoder, + opts ...RetryOption, +) (*http.Response, error) { + options := new(retryOptions) + for _, opt := range opts { + opt(options) + } + maxRetryAttempts := r.attempts + if options.attempts > 0 { + maxRetryAttempts = options.attempts + } + var ( + retryAttempt uint + previousError error + ) + return r.run( + fn, + request, + errorDecoder, + maxRetryAttempts, + retryAttempt, + previousError, + ) +} + +func (r *Retrier) run( + fn RetryFunc, + request *http.Request, + errorDecoder ErrorDecoder, + maxRetryAttempts uint, + retryAttempt uint, + previousError error, +) (*http.Response, error) { + if retryAttempt >= maxRetryAttempts { + return nil, previousError + } + + // If the call has been cancelled, don't issue the request. + if err := request.Context().Err(); err != nil { + return nil, err + } + + response, err := fn(request) + if err != nil { + return nil, err + } + + if r.shouldRetry(response) { + defer response.Body.Close() + + delay, err := r.retryDelay(retryAttempt) + if err != nil { + return nil, err + } + + time.Sleep(delay) + + return r.run( + fn, + request, + errorDecoder, + maxRetryAttempts, + retryAttempt+1, + decodeError(response, errorDecoder), + ) + } + + return response, nil +} + +// shouldRetry returns true if the request should be retried based on the given +// response status code. +func (r *Retrier) shouldRetry(response *http.Response) bool { + return response.StatusCode == http.StatusTooManyRequests || + response.StatusCode == http.StatusRequestTimeout || + response.StatusCode == http.StatusConflict || + response.StatusCode >= http.StatusInternalServerError +} + +// retryDelay calculates the delay time in milliseconds based on the retry attempt. +func (r *Retrier) retryDelay(retryAttempt uint) (time.Duration, error) { + // Apply exponential backoff. + delay := minRetryDelay + minRetryDelay*time.Duration(retryAttempt*retryAttempt) + + // Do not allow the number to exceed maxRetryDelay. + if delay > maxRetryDelay { + delay = maxRetryDelay + } + + // Apply some itter by randomizing the value in the range of 75%-100%. + max := big.NewInt(int64(delay / 4)) + jitter, err := rand.Int(rand.Reader, max) + if err != nil { + return 0, err + } + + delay -= time.Duration(jitter.Int64()) + + // Never sleep less than the base sleep seconds. + if delay < minRetryDelay { + delay = minRetryDelay + } + + return delay, nil +} + +type retryOptions struct { + attempts uint +} diff --git a/core/time.go b/core/time.go new file mode 100644 index 0000000..d009ab3 --- /dev/null +++ b/core/time.go @@ -0,0 +1,137 @@ +package core + +import ( + "encoding/json" + "time" +) + +const dateFormat = "2006-01-02" + +// DateTime wraps time.Time and adapts its JSON representation +// to conform to a RFC3339 date (e.g. 2006-01-02). +// +// Ref: https://ijmacd.github.io/rfc3339-iso8601 +type Date struct { + t *time.Time +} + +// NewDate returns a new *Date. If the given time.Time +// is nil, nil will be returned. +func NewDate(t time.Time) *Date { + return &Date{t: &t} +} + +// NewOptionalDate returns a new *Date. If the given time.Time +// is nil, nil will be returned. +func NewOptionalDate(t *time.Time) *Date { + if t == nil { + return nil + } + return &Date{t: t} +} + +// Time returns the Date's underlying time, if any. If the +// date is nil, the zero value is returned. +func (d *Date) Time() time.Time { + if d == nil || d.t == nil { + return time.Time{} + } + return *d.t +} + +// TimePtr returns a pointer to the Date's underlying time.Time, if any. +func (d *Date) TimePtr() *time.Time { + if d == nil || d.t == nil { + return nil + } + if d.t.IsZero() { + return nil + } + return d.t +} + +func (d *Date) MarshalJSON() ([]byte, error) { + if d == nil || d.t == nil { + return nil, nil + } + return json.Marshal(d.t.Format(dateFormat)) +} + +func (d *Date) UnmarshalJSON(data []byte) error { + var raw string + if err := json.Unmarshal(data, &raw); err != nil { + return err + } + + parsedTime, err := time.Parse(dateFormat, raw) + if err != nil { + return err + } + + *d = Date{t: &parsedTime} + return nil +} + +// DateTime wraps time.Time and adapts its JSON representation +// to conform to a RFC3339 date-time (e.g. 2017-07-21T17:32:28Z). +// +// Ref: https://ijmacd.github.io/rfc3339-iso8601 +type DateTime struct { + t *time.Time +} + +// NewDateTime returns a new *DateTime. +func NewDateTime(t time.Time) *DateTime { + return &DateTime{t: &t} +} + +// NewOptionalDateTime returns a new *DateTime. If the given time.Time +// is nil, nil will be returned. +func NewOptionalDateTime(t *time.Time) *DateTime { + if t == nil { + return nil + } + return &DateTime{t: t} +} + +// Time returns the DateTime's underlying time, if any. If the +// date-time is nil, the zero value is returned. +func (d *DateTime) Time() time.Time { + if d == nil || d.t == nil { + return time.Time{} + } + return *d.t +} + +// TimePtr returns a pointer to the DateTime's underlying time.Time, if any. +func (d *DateTime) TimePtr() *time.Time { + if d == nil || d.t == nil { + return nil + } + if d.t.IsZero() { + return nil + } + return d.t +} + +func (d *DateTime) MarshalJSON() ([]byte, error) { + if d == nil || d.t == nil { + return nil, nil + } + return json.Marshal(d.t.Format(time.RFC3339)) +} + +func (d *DateTime) UnmarshalJSON(data []byte) error { + var raw string + if err := json.Unmarshal(data, &raw); err != nil { + return err + } + + parsedTime, err := time.Parse(time.RFC3339, raw) + if err != nil { + return err + } + + *d = DateTime{t: &parsedTime} + return nil +} diff --git a/devices.go b/devices.go index 37aa7ff..854056d 100644 --- a/devices.go +++ b/devices.go @@ -10,35 +10,57 @@ import ( ) type DevicesDeleteRequest struct { - DeviceId string `json:"device_id"` + DeviceId string `json:"device_id" url:"device_id"` } type DevicesGetRequest struct { - DeviceId *string `json:"device_id,omitempty"` - Name *string `json:"name,omitempty"` + DeviceId *string `json:"device_id,omitempty" url:"device_id,omitempty"` + Name *string `json:"name,omitempty" url:"name,omitempty"` } type DevicesListRequest struct { // List all devices owned by this connected account - ConnectedAccountId *string `json:"connected_account_id,omitempty"` - ConnectedAccountIds []string `json:"connected_account_ids,omitempty"` - ConnectWebviewId *string `json:"connect_webview_id,omitempty"` - DeviceType *DeviceType `json:"device_type,omitempty"` - DeviceTypes []DeviceType `json:"device_types,omitempty"` - Manufacturer *Manufacturer `json:"manufacturer,omitempty"` - DeviceIds []string `json:"device_ids,omitempty"` - Limit *float64 `json:"limit,omitempty"` - CreatedBefore *time.Time `json:"created_before,omitempty"` - UserIdentifierKey *string `json:"user_identifier_key,omitempty"` - CustomMetadataHas map[string]*DevicesListRequestCustomMetadataHasValue `json:"custom_metadata_has,omitempty"` + ConnectedAccountId *string `json:"connected_account_id,omitempty" url:"connected_account_id,omitempty"` + ConnectedAccountIds []string `json:"connected_account_ids,omitempty" url:"connected_account_ids,omitempty"` + ConnectWebviewId *string `json:"connect_webview_id,omitempty" url:"connect_webview_id,omitempty"` + DeviceType *DeviceType `json:"device_type,omitempty" url:"device_type,omitempty"` + DeviceTypes []DeviceType `json:"device_types,omitempty" url:"device_types,omitempty"` + Manufacturer *Manufacturer `json:"manufacturer,omitempty" url:"manufacturer,omitempty"` + DeviceIds []string `json:"device_ids,omitempty" url:"device_ids,omitempty"` + Limit *float64 `json:"limit,omitempty" url:"limit,omitempty"` + CreatedBefore *time.Time `json:"created_before,omitempty" url:"created_before,omitempty"` + UserIdentifierKey *string `json:"user_identifier_key,omitempty" url:"user_identifier_key,omitempty"` + CustomMetadataHas map[string]*DevicesListRequestCustomMetadataHasValue `json:"custom_metadata_has,omitempty" url:"custom_metadata_has,omitempty"` +} + +func (d *DevicesListRequest) UnmarshalJSON(data []byte) error { + type unmarshaler DevicesListRequest + var body unmarshaler + if err := json.Unmarshal(data, &body); err != nil { + return err + } + *d = DevicesListRequest(body) + return nil +} + +func (d *DevicesListRequest) MarshalJSON() ([]byte, error) { + type embed DevicesListRequest + var marshaler = struct { + embed + CreatedBefore *core.DateTime `json:"created_before,omitempty"` + }{ + embed: embed(*d), + CreatedBefore: core.NewOptionalDateTime(d.CreatedBefore), + } + return json.Marshal(marshaler) } type DevicesListDeviceProvidersRequest struct { - ProviderCategory *ProviderCategory `json:"provider_category,omitempty"` + ProviderCategory *ProviderCategory `json:"provider_category,omitempty" url:"provider_category,omitempty"` } type DevicesDeleteResponse struct { - Ok bool `json:"ok"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -67,8 +89,8 @@ func (d *DevicesDeleteResponse) String() string { } type DevicesGetResponse struct { - Device *Device `json:"device,omitempty"` - Ok bool `json:"ok"` + Device *Device `json:"device,omitempty" url:"device,omitempty"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -97,8 +119,8 @@ func (d *DevicesGetResponse) String() string { } type DevicesListDeviceProvidersResponse struct { - DeviceProviders []*DeviceProvider `json:"device_providers,omitempty"` - Ok bool `json:"ok"` + DeviceProviders []*DeviceProvider `json:"device_providers,omitempty" url:"device_providers,omitempty"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -200,8 +222,8 @@ func (d *DevicesListRequestCustomMetadataHasValue) Accept(visitor DevicesListReq } type DevicesListResponse struct { - Devices []*Device `json:"devices,omitempty"` - Ok bool `json:"ok"` + Devices []*Device `json:"devices,omitempty" url:"devices,omitempty"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -303,7 +325,7 @@ func (d *DevicesUpdateRequestCustomMetadataValue) Accept(visitor DevicesUpdateRe } type DevicesUpdateRequestProperties struct { - Name *string `json:"name,omitempty"` + Name *string `json:"name,omitempty" url:"name,omitempty"` _rawJSON json.RawMessage } @@ -332,7 +354,7 @@ func (d *DevicesUpdateRequestProperties) String() string { } type DevicesUpdateResponse struct { - Ok bool `json:"ok"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -361,9 +383,9 @@ func (d *DevicesUpdateResponse) String() string { } type DevicesUpdateRequest struct { - DeviceId string `json:"device_id"` - Properties *DevicesUpdateRequestProperties `json:"properties,omitempty"` - Name *string `json:"name,omitempty"` - IsManaged *bool `json:"is_managed,omitempty"` - CustomMetadata map[string]*DevicesUpdateRequestCustomMetadataValue `json:"custom_metadata,omitempty"` + DeviceId string `json:"device_id" url:"device_id"` + Properties *DevicesUpdateRequestProperties `json:"properties,omitempty" url:"properties,omitempty"` + Name *string `json:"name,omitempty" url:"name,omitempty"` + IsManaged *bool `json:"is_managed,omitempty" url:"is_managed,omitempty"` + CustomMetadata map[string]*DevicesUpdateRequestCustomMetadataValue `json:"custom_metadata,omitempty" url:"custom_metadata,omitempty"` } diff --git a/devices/client/client.go b/devices/client/client.go index d76b84f..e10ce41 100644 --- a/devices/client/client.go +++ b/devices/client/client.go @@ -10,6 +10,7 @@ import ( seamapigo "github.com/seamapi/go" core "github.com/seamapi/go/core" unmanaged "github.com/seamapi/go/devices/unmanaged" + option "github.com/seamapi/go/option" io "io" http "net/http" ) @@ -22,26 +23,39 @@ type Client struct { Unmanaged *unmanaged.Client } -func NewClient(opts ...core.ClientOption) *Client { - options := core.NewClientOptions() - for _, opt := range opts { - opt(options) - } +func NewClient(opts ...option.RequestOption) *Client { + options := core.NewRequestOptions(opts...) return &Client{ - baseURL: options.BaseURL, - caller: core.NewCaller(options.HTTPClient), + baseURL: options.BaseURL, + caller: core.NewCaller( + &core.CallerParams{ + Client: options.HTTPClient, + MaxAttempts: options.MaxAttempts, + }, + ), header: options.ToHeader(), Unmanaged: unmanaged.NewClient(opts...), } } -func (c *Client) Delete(ctx context.Context, request *seamapigo.DevicesDeleteRequest) (*seamapigo.DevicesDeleteResponse, error) { +func (c *Client) Delete( + ctx context.Context, + request *seamapigo.DevicesDeleteRequest, + opts ...option.RequestOption, +) (*seamapigo.DevicesDeleteResponse, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "devices/delete" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -74,7 +88,9 @@ func (c *Client) Delete(ctx context.Context, request *seamapigo.DevicesDeleteReq &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -85,13 +101,24 @@ func (c *Client) Delete(ctx context.Context, request *seamapigo.DevicesDeleteReq return response, nil } -func (c *Client) Get(ctx context.Context, request *seamapigo.DevicesGetRequest) (*seamapigo.Device, error) { +func (c *Client) Get( + ctx context.Context, + request *seamapigo.DevicesGetRequest, + opts ...option.RequestOption, +) (*seamapigo.Device, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "devices/get" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -124,7 +151,9 @@ func (c *Client) Get(ctx context.Context, request *seamapigo.DevicesGetRequest) &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -135,13 +164,24 @@ func (c *Client) Get(ctx context.Context, request *seamapigo.DevicesGetRequest) return response.Device, nil } -func (c *Client) List(ctx context.Context, request *seamapigo.DevicesListRequest) ([]*seamapigo.Device, error) { +func (c *Client) List( + ctx context.Context, + request *seamapigo.DevicesListRequest, + opts ...option.RequestOption, +) ([]*seamapigo.Device, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "devices/list" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -174,7 +214,9 @@ func (c *Client) List(ctx context.Context, request *seamapigo.DevicesListRequest &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -185,13 +227,24 @@ func (c *Client) List(ctx context.Context, request *seamapigo.DevicesListRequest return response.Devices, nil } -func (c *Client) ListDeviceProviders(ctx context.Context, request *seamapigo.DevicesListDeviceProvidersRequest) ([]*seamapigo.DeviceProvider, error) { +func (c *Client) ListDeviceProviders( + ctx context.Context, + request *seamapigo.DevicesListDeviceProvidersRequest, + opts ...option.RequestOption, +) ([]*seamapigo.DeviceProvider, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "devices/list_device_providers" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -224,7 +277,9 @@ func (c *Client) ListDeviceProviders(ctx context.Context, request *seamapigo.Dev &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -235,13 +290,24 @@ func (c *Client) ListDeviceProviders(ctx context.Context, request *seamapigo.Dev return response.DeviceProviders, nil } -func (c *Client) Update(ctx context.Context, request *seamapigo.DevicesUpdateRequest) (*seamapigo.DevicesUpdateResponse, error) { +func (c *Client) Update( + ctx context.Context, + request *seamapigo.DevicesUpdateRequest, + opts ...option.RequestOption, +) (*seamapigo.DevicesUpdateResponse, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "devices/update" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -274,7 +340,9 @@ func (c *Client) Update(ctx context.Context, request *seamapigo.DevicesUpdateReq &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, diff --git a/devices/unmanaged.go b/devices/unmanaged.go index ba4bd7e..6be5f29 100644 --- a/devices/unmanaged.go +++ b/devices/unmanaged.go @@ -11,28 +11,50 @@ import ( ) type UnmanagedGetRequest struct { - DeviceId *string `json:"device_id,omitempty"` - Name *string `json:"name,omitempty"` + DeviceId *string `json:"device_id,omitempty" url:"device_id,omitempty"` + Name *string `json:"name,omitempty" url:"name,omitempty"` } type UnmanagedListRequest struct { // List all devices owned by this connected account - ConnectedAccountId *string `json:"connected_account_id,omitempty"` - ConnectedAccountIds []string `json:"connected_account_ids,omitempty"` - ConnectWebviewId *string `json:"connect_webview_id,omitempty"` - DeviceType *seamapigo.DeviceType `json:"device_type,omitempty"` - DeviceTypes []seamapigo.DeviceType `json:"device_types,omitempty"` - Manufacturer *seamapigo.Manufacturer `json:"manufacturer,omitempty"` - DeviceIds []string `json:"device_ids,omitempty"` - Limit *float64 `json:"limit,omitempty"` - CreatedBefore *time.Time `json:"created_before,omitempty"` - UserIdentifierKey *string `json:"user_identifier_key,omitempty"` - CustomMetadataHas map[string]*UnmanagedListRequestCustomMetadataHasValue `json:"custom_metadata_has,omitempty"` + ConnectedAccountId *string `json:"connected_account_id,omitempty" url:"connected_account_id,omitempty"` + ConnectedAccountIds []string `json:"connected_account_ids,omitempty" url:"connected_account_ids,omitempty"` + ConnectWebviewId *string `json:"connect_webview_id,omitempty" url:"connect_webview_id,omitempty"` + DeviceType *seamapigo.DeviceType `json:"device_type,omitempty" url:"device_type,omitempty"` + DeviceTypes []seamapigo.DeviceType `json:"device_types,omitempty" url:"device_types,omitempty"` + Manufacturer *seamapigo.Manufacturer `json:"manufacturer,omitempty" url:"manufacturer,omitempty"` + DeviceIds []string `json:"device_ids,omitempty" url:"device_ids,omitempty"` + Limit *float64 `json:"limit,omitempty" url:"limit,omitempty"` + CreatedBefore *time.Time `json:"created_before,omitempty" url:"created_before,omitempty"` + UserIdentifierKey *string `json:"user_identifier_key,omitempty" url:"user_identifier_key,omitempty"` + CustomMetadataHas map[string]*UnmanagedListRequestCustomMetadataHasValue `json:"custom_metadata_has,omitempty" url:"custom_metadata_has,omitempty"` +} + +func (u *UnmanagedListRequest) UnmarshalJSON(data []byte) error { + type unmarshaler UnmanagedListRequest + var body unmarshaler + if err := json.Unmarshal(data, &body); err != nil { + return err + } + *u = UnmanagedListRequest(body) + return nil +} + +func (u *UnmanagedListRequest) MarshalJSON() ([]byte, error) { + type embed UnmanagedListRequest + var marshaler = struct { + embed + CreatedBefore *core.DateTime `json:"created_before,omitempty"` + }{ + embed: embed(*u), + CreatedBefore: core.NewOptionalDateTime(u.CreatedBefore), + } + return json.Marshal(marshaler) } type UnmanagedGetResponse struct { - Device *seamapigo.UnmanagedDevice `json:"device,omitempty"` - Ok bool `json:"ok"` + Device *seamapigo.UnmanagedDevice `json:"device,omitempty" url:"device,omitempty"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -134,8 +156,8 @@ func (u *UnmanagedListRequestCustomMetadataHasValue) Accept(visitor UnmanagedLis } type UnmanagedListResponse struct { - Devices []*seamapigo.UnmanagedDevice `json:"devices,omitempty"` - Ok bool `json:"ok"` + Devices []*seamapigo.UnmanagedDevice `json:"devices,omitempty" url:"devices,omitempty"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -164,7 +186,7 @@ func (u *UnmanagedListResponse) String() string { } type UnmanagedUpdateResponse struct { - Ok bool `json:"ok"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -193,6 +215,6 @@ func (u *UnmanagedUpdateResponse) String() string { } type UnmanagedUpdateRequest struct { - DeviceId string `json:"device_id"` - IsManaged bool `json:"is_managed"` + DeviceId string `json:"device_id" url:"device_id"` + IsManaged bool `json:"is_managed" url:"is_managed"` } diff --git a/devices/unmanaged/client.go b/devices/unmanaged/client.go index 007ebfe..7bfc671 100644 --- a/devices/unmanaged/client.go +++ b/devices/unmanaged/client.go @@ -10,6 +10,7 @@ import ( seamapigo "github.com/seamapi/go" core "github.com/seamapi/go/core" devices "github.com/seamapi/go/devices" + option "github.com/seamapi/go/option" io "io" http "net/http" ) @@ -20,25 +21,38 @@ type Client struct { header http.Header } -func NewClient(opts ...core.ClientOption) *Client { - options := core.NewClientOptions() - for _, opt := range opts { - opt(options) - } +func NewClient(opts ...option.RequestOption) *Client { + options := core.NewRequestOptions(opts...) return &Client{ baseURL: options.BaseURL, - caller: core.NewCaller(options.HTTPClient), - header: options.ToHeader(), + caller: core.NewCaller( + &core.CallerParams{ + Client: options.HTTPClient, + MaxAttempts: options.MaxAttempts, + }, + ), + header: options.ToHeader(), } } -func (c *Client) Get(ctx context.Context, request *devices.UnmanagedGetRequest) (*seamapigo.UnmanagedDevice, error) { +func (c *Client) Get( + ctx context.Context, + request *devices.UnmanagedGetRequest, + opts ...option.RequestOption, +) (*seamapigo.UnmanagedDevice, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "devices/unmanaged/get" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -71,7 +85,9 @@ func (c *Client) Get(ctx context.Context, request *devices.UnmanagedGetRequest) &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -82,13 +98,24 @@ func (c *Client) Get(ctx context.Context, request *devices.UnmanagedGetRequest) return response.Device, nil } -func (c *Client) List(ctx context.Context, request *devices.UnmanagedListRequest) ([]*seamapigo.UnmanagedDevice, error) { +func (c *Client) List( + ctx context.Context, + request *devices.UnmanagedListRequest, + opts ...option.RequestOption, +) ([]*seamapigo.UnmanagedDevice, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "devices/unmanaged/list" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -121,7 +148,9 @@ func (c *Client) List(ctx context.Context, request *devices.UnmanagedListRequest &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -132,13 +161,24 @@ func (c *Client) List(ctx context.Context, request *devices.UnmanagedListRequest return response.Devices, nil } -func (c *Client) Update(ctx context.Context, request *devices.UnmanagedUpdateRequest) (*devices.UnmanagedUpdateResponse, error) { +func (c *Client) Update( + ctx context.Context, + request *devices.UnmanagedUpdateRequest, + opts ...option.RequestOption, +) (*devices.UnmanagedUpdateResponse, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "devices/unmanaged/update" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -171,7 +211,9 @@ func (c *Client) Update(ctx context.Context, request *devices.UnmanagedUpdateReq &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, diff --git a/environments.go b/environments.go index 1ffc580..3ce87a6 100644 --- a/environments.go +++ b/environments.go @@ -4,7 +4,7 @@ package api // Environments defines all of the API environments. // These values can be used with the WithBaseURL -// ClientOption to override the client's default environment, +// RequestOption to override the client's default environment, // if any. var Environments = struct { Default string diff --git a/events.go b/events.go index 54dabab..bf7fe60 100644 --- a/events.go +++ b/events.go @@ -10,27 +10,27 @@ import ( ) type EventsGetRequest struct { - EventId *string `json:"event_id,omitempty"` - EventType *string `json:"event_type,omitempty"` - DeviceId *string `json:"device_id,omitempty"` + EventId *string `json:"event_id,omitempty" url:"event_id,omitempty"` + EventType *string `json:"event_type,omitempty" url:"event_type,omitempty"` + DeviceId *string `json:"device_id,omitempty" url:"device_id,omitempty"` } type EventsListRequest struct { - Since *string `json:"since,omitempty"` - Between []*EventsListRequestBetweenItem `json:"between,omitempty"` - DeviceId *string `json:"device_id,omitempty"` - DeviceIds []string `json:"device_ids,omitempty"` - AccessCodeId *string `json:"access_code_id,omitempty"` - AccessCodeIds []string `json:"access_code_ids,omitempty"` - EventType *EventType `json:"event_type,omitempty"` - EventTypes []EventType `json:"event_types,omitempty"` - ConnectedAccountId *string `json:"connected_account_id,omitempty"` + Since *string `json:"since,omitempty" url:"since,omitempty"` + Between []*EventsListRequestBetweenItem `json:"between,omitempty" url:"between,omitempty"` + DeviceId *string `json:"device_id,omitempty" url:"device_id,omitempty"` + DeviceIds []string `json:"device_ids,omitempty" url:"device_ids,omitempty"` + AccessCodeId *string `json:"access_code_id,omitempty" url:"access_code_id,omitempty"` + AccessCodeIds []string `json:"access_code_ids,omitempty" url:"access_code_ids,omitempty"` + EventType *EventType `json:"event_type,omitempty" url:"event_type,omitempty"` + EventTypes []EventType `json:"event_types,omitempty" url:"event_types,omitempty"` + ConnectedAccountId *string `json:"connected_account_id,omitempty" url:"connected_account_id,omitempty"` } type EventsGetResponse struct { - Event *Event `json:"event,omitempty"` - Message *string `json:"message,omitempty"` - Ok bool `json:"ok"` + Event *Event `json:"event,omitempty" url:"event,omitempty"` + Message *string `json:"message,omitempty" url:"message,omitempty"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -79,10 +79,10 @@ func (e *EventsListRequestBetweenItem) UnmarshalJSON(data []byte) error { e.String = valueString return nil } - var valueDateTime time.Time + var valueDateTime *core.DateTime if err := json.Unmarshal(data, &valueDateTime); err == nil { e.typeName = "dateTime" - e.DateTime = valueDateTime + e.DateTime = valueDateTime.Time() return nil } return fmt.Errorf("%s cannot be deserialized as a %T", data, e) @@ -95,7 +95,7 @@ func (e EventsListRequestBetweenItem) MarshalJSON() ([]byte, error) { case "string": return json.Marshal(e.String) case "dateTime": - return json.Marshal(e.DateTime) + return json.Marshal(core.NewDateTime(e.DateTime)) } } @@ -116,9 +116,9 @@ func (e *EventsListRequestBetweenItem) Accept(visitor EventsListRequestBetweenIt } type EventsListResponse struct { - Events []*Event `json:"events,omitempty"` - Message *string `json:"message,omitempty"` - Ok bool `json:"ok"` + Events []*Event `json:"events,omitempty" url:"events,omitempty"` + Message *string `json:"message,omitempty" url:"message,omitempty"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } diff --git a/events/client.go b/events/client.go index 1420650..bd23455 100644 --- a/events/client.go +++ b/events/client.go @@ -9,6 +9,7 @@ import ( errors "errors" seamapigo "github.com/seamapi/go" core "github.com/seamapi/go/core" + option "github.com/seamapi/go/option" io "io" http "net/http" ) @@ -19,25 +20,38 @@ type Client struct { header http.Header } -func NewClient(opts ...core.ClientOption) *Client { - options := core.NewClientOptions() - for _, opt := range opts { - opt(options) - } +func NewClient(opts ...option.RequestOption) *Client { + options := core.NewRequestOptions(opts...) return &Client{ baseURL: options.BaseURL, - caller: core.NewCaller(options.HTTPClient), - header: options.ToHeader(), + caller: core.NewCaller( + &core.CallerParams{ + Client: options.HTTPClient, + MaxAttempts: options.MaxAttempts, + }, + ), + header: options.ToHeader(), } } -func (c *Client) Get(ctx context.Context, request *seamapigo.EventsGetRequest) (*seamapigo.Event, error) { +func (c *Client) Get( + ctx context.Context, + request *seamapigo.EventsGetRequest, + opts ...option.RequestOption, +) (*seamapigo.Event, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "events/get" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -70,7 +84,9 @@ func (c *Client) Get(ctx context.Context, request *seamapigo.EventsGetRequest) ( &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -81,13 +97,24 @@ func (c *Client) Get(ctx context.Context, request *seamapigo.EventsGetRequest) ( return response.Event, nil } -func (c *Client) List(ctx context.Context, request *seamapigo.EventsListRequest) ([]*seamapigo.Event, error) { +func (c *Client) List( + ctx context.Context, + request *seamapigo.EventsListRequest, + opts ...option.RequestOption, +) ([]*seamapigo.Event, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "events/list" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -120,7 +147,9 @@ func (c *Client) List(ctx context.Context, request *seamapigo.EventsListRequest) &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, diff --git a/go.mod b/go.mod index 15470df..30e9b4c 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module github.com/seamapi/go go 1.13 require ( + github.com/google/uuid v1.4.0 github.com/stretchr/testify v1.7.0 gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index fc3dd9e..b3766d4 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,7 @@ github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4= +github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= diff --git a/health.go b/health.go index d0500ed..f9a1d39 100644 --- a/health.go +++ b/health.go @@ -9,13 +9,13 @@ import ( ) type HealthGetServiceHealthRequest struct { - Service string `json:"service"` + Service string `json:"service" url:"service"` } type HealthGetHealthResponse struct { - Ok bool `json:"ok"` - LastServiceEvaluationAt *string `json:"last_service_evaluation_at,omitempty"` - ServiceHealthStatuses []*ServiceHealth `json:"service_health_statuses,omitempty"` + Ok bool `json:"ok" url:"ok"` + LastServiceEvaluationAt *string `json:"last_service_evaluation_at,omitempty" url:"last_service_evaluation_at,omitempty"` + ServiceHealthStatuses []*ServiceHealth `json:"service_health_statuses,omitempty" url:"service_health_statuses,omitempty"` msg string _rawJSON json.RawMessage @@ -26,12 +26,16 @@ func (h *HealthGetHealthResponse) Msg() string { } func (h *HealthGetHealthResponse) UnmarshalJSON(data []byte) error { - type unmarshaler HealthGetHealthResponse - var value unmarshaler - if err := json.Unmarshal(data, &value); err != nil { + type embed HealthGetHealthResponse + var unmarshaler = struct { + embed + }{ + embed: embed(*h), + } + if err := json.Unmarshal(data, &unmarshaler); err != nil { return err } - *h = HealthGetHealthResponse(value) + *h = HealthGetHealthResponse(unmarshaler.embed) h.msg = "I’m one with the Force. The Force is with me." h._rawJSON = json.RawMessage(data) return nil @@ -62,9 +66,9 @@ func (h *HealthGetHealthResponse) String() string { } type HealthGetServiceHealthResponse struct { - Ok bool `json:"ok"` - LastServiceEvaluationAt string `json:"last_service_evaluation_at"` - ServiceHealth *ServiceHealth `json:"service_health,omitempty"` + Ok bool `json:"ok" url:"ok"` + LastServiceEvaluationAt string `json:"last_service_evaluation_at" url:"last_service_evaluation_at"` + ServiceHealth *ServiceHealth `json:"service_health,omitempty" url:"service_health,omitempty"` _rawJSON json.RawMessage } diff --git a/health/client/client.go b/health/client/client.go index 56514e8..669c050 100644 --- a/health/client/client.go +++ b/health/client/client.go @@ -10,6 +10,7 @@ import ( seamapigo "github.com/seamapi/go" core "github.com/seamapi/go/core" service "github.com/seamapi/go/health/service" + option "github.com/seamapi/go/option" io "io" http "net/http" ) @@ -22,26 +23,38 @@ type Client struct { Service *service.Client } -func NewClient(opts ...core.ClientOption) *Client { - options := core.NewClientOptions() - for _, opt := range opts { - opt(options) - } +func NewClient(opts ...option.RequestOption) *Client { + options := core.NewRequestOptions(opts...) return &Client{ baseURL: options.BaseURL, - caller: core.NewCaller(options.HTTPClient), + caller: core.NewCaller( + &core.CallerParams{ + Client: options.HTTPClient, + MaxAttempts: options.MaxAttempts, + }, + ), header: options.ToHeader(), Service: service.NewClient(opts...), } } -func (c *Client) GetHealth(ctx context.Context) (*seamapigo.HealthGetHealthResponse, error) { +func (c *Client) GetHealth( + ctx context.Context, + opts ...option.RequestOption, +) (*seamapigo.HealthGetHealthResponse, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "health/get_health" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -74,7 +87,9 @@ func (c *Client) GetHealth(ctx context.Context) (*seamapigo.HealthGetHealthRespo &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Response: &response, ErrorDecoder: errorDecoder, }, @@ -84,13 +99,24 @@ func (c *Client) GetHealth(ctx context.Context) (*seamapigo.HealthGetHealthRespo return response, nil } -func (c *Client) GetServiceHealth(ctx context.Context, request *seamapigo.HealthGetServiceHealthRequest) (*seamapigo.HealthGetServiceHealthResponse, error) { +func (c *Client) GetServiceHealth( + ctx context.Context, + request *seamapigo.HealthGetServiceHealthRequest, + opts ...option.RequestOption, +) (*seamapigo.HealthGetServiceHealthResponse, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "health/get_service_health" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -123,7 +149,9 @@ func (c *Client) GetServiceHealth(ctx context.Context, request *seamapigo.Health &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, diff --git a/health/service.go b/health/service.go index 3d6a429..435c354 100644 --- a/health/service.go +++ b/health/service.go @@ -10,13 +10,13 @@ import ( ) type ServiceByServiceNameRequest struct { - ServiceName string `json:"service_name"` + ServiceName string `json:"service_name" url:"service_name"` } type ServiceByServiceNameResponse struct { - Ok bool `json:"ok"` - LastServiceEvaluationAt string `json:"last_service_evaluation_at"` - ServiceHealth *seamapigo.ServiceHealth `json:"service_health,omitempty"` + Ok bool `json:"ok" url:"ok"` + LastServiceEvaluationAt string `json:"last_service_evaluation_at" url:"last_service_evaluation_at"` + ServiceHealth *seamapigo.ServiceHealth `json:"service_health,omitempty" url:"service_health,omitempty"` _rawJSON json.RawMessage } diff --git a/health/service/client.go b/health/service/client.go index 92af547..6fdd990 100644 --- a/health/service/client.go +++ b/health/service/client.go @@ -10,6 +10,7 @@ import ( seamapigo "github.com/seamapi/go" core "github.com/seamapi/go/core" health "github.com/seamapi/go/health" + option "github.com/seamapi/go/option" io "io" http "net/http" ) @@ -20,25 +21,38 @@ type Client struct { header http.Header } -func NewClient(opts ...core.ClientOption) *Client { - options := core.NewClientOptions() - for _, opt := range opts { - opt(options) - } +func NewClient(opts ...option.RequestOption) *Client { + options := core.NewRequestOptions(opts...) return &Client{ baseURL: options.BaseURL, - caller: core.NewCaller(options.HTTPClient), - header: options.ToHeader(), + caller: core.NewCaller( + &core.CallerParams{ + Client: options.HTTPClient, + MaxAttempts: options.MaxAttempts, + }, + ), + header: options.ToHeader(), } } -func (c *Client) ByServiceName(ctx context.Context, request *health.ServiceByServiceNameRequest) (*health.ServiceByServiceNameResponse, error) { +func (c *Client) ByServiceName( + ctx context.Context, + request *health.ServiceByServiceNameRequest, + opts ...option.RequestOption, +) (*health.ServiceByServiceNameResponse, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "health/service/[service_name]" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -71,7 +85,9 @@ func (c *Client) ByServiceName(ctx context.Context, request *health.ServiceBySer &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, diff --git a/locks.go b/locks.go index 3e84c04..f226189 100644 --- a/locks.go +++ b/locks.go @@ -10,34 +10,56 @@ import ( ) type LocksGetRequest struct { - DeviceId *string `json:"device_id,omitempty"` - Name *string `json:"name,omitempty"` + DeviceId *string `json:"device_id,omitempty" url:"device_id,omitempty"` + Name *string `json:"name,omitempty" url:"name,omitempty"` } type LocksListRequest struct { // List all devices owned by this connected account - ConnectedAccountId *string `json:"connected_account_id,omitempty"` - ConnectedAccountIds []string `json:"connected_account_ids,omitempty"` - ConnectWebviewId *string `json:"connect_webview_id,omitempty"` - DeviceType *DeviceType `json:"device_type,omitempty"` - DeviceTypes []DeviceType `json:"device_types,omitempty"` - Manufacturer *Manufacturer `json:"manufacturer,omitempty"` - DeviceIds []string `json:"device_ids,omitempty"` - Limit *float64 `json:"limit,omitempty"` - CreatedBefore *time.Time `json:"created_before,omitempty"` - UserIdentifierKey *string `json:"user_identifier_key,omitempty"` - CustomMetadataHas map[string]*LocksListRequestCustomMetadataHasValue `json:"custom_metadata_has,omitempty"` + ConnectedAccountId *string `json:"connected_account_id,omitempty" url:"connected_account_id,omitempty"` + ConnectedAccountIds []string `json:"connected_account_ids,omitempty" url:"connected_account_ids,omitempty"` + ConnectWebviewId *string `json:"connect_webview_id,omitempty" url:"connect_webview_id,omitempty"` + DeviceType *DeviceType `json:"device_type,omitempty" url:"device_type,omitempty"` + DeviceTypes []DeviceType `json:"device_types,omitempty" url:"device_types,omitempty"` + Manufacturer *Manufacturer `json:"manufacturer,omitempty" url:"manufacturer,omitempty"` + DeviceIds []string `json:"device_ids,omitempty" url:"device_ids,omitempty"` + Limit *float64 `json:"limit,omitempty" url:"limit,omitempty"` + CreatedBefore *time.Time `json:"created_before,omitempty" url:"created_before,omitempty"` + UserIdentifierKey *string `json:"user_identifier_key,omitempty" url:"user_identifier_key,omitempty"` + CustomMetadataHas map[string]*LocksListRequestCustomMetadataHasValue `json:"custom_metadata_has,omitempty" url:"custom_metadata_has,omitempty"` +} + +func (l *LocksListRequest) UnmarshalJSON(data []byte) error { + type unmarshaler LocksListRequest + var body unmarshaler + if err := json.Unmarshal(data, &body); err != nil { + return err + } + *l = LocksListRequest(body) + return nil +} + +func (l *LocksListRequest) MarshalJSON() ([]byte, error) { + type embed LocksListRequest + var marshaler = struct { + embed + CreatedBefore *core.DateTime `json:"created_before,omitempty"` + }{ + embed: embed(*l), + CreatedBefore: core.NewOptionalDateTime(l.CreatedBefore), + } + return json.Marshal(marshaler) } type LocksLockDoorRequest struct { - DeviceId string `json:"device_id"` - Sync *bool `json:"sync,omitempty"` + DeviceId string `json:"device_id" url:"device_id"` + Sync *bool `json:"sync,omitempty" url:"sync,omitempty"` } type LocksGetResponse struct { - Lock *Device `json:"lock,omitempty"` - Device *Device `json:"device,omitempty"` - Ok bool `json:"ok"` + Lock *Device `json:"lock,omitempty" url:"lock,omitempty"` + Device *Device `json:"device,omitempty" url:"device,omitempty"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -139,9 +161,9 @@ func (l *LocksListRequestCustomMetadataHasValue) Accept(visitor LocksListRequest } type LocksListResponse struct { - Locks []*Device `json:"locks,omitempty"` - Devices []*Device `json:"devices,omitempty"` - Ok bool `json:"ok"` + Locks []*Device `json:"locks,omitempty" url:"locks,omitempty"` + Devices []*Device `json:"devices,omitempty" url:"devices,omitempty"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -170,8 +192,8 @@ func (l *LocksListResponse) String() string { } type LocksLockDoorResponse struct { - ActionAttempt *ActionAttempt `json:"action_attempt,omitempty"` - Ok bool `json:"ok"` + ActionAttempt *ActionAttempt `json:"action_attempt,omitempty" url:"action_attempt,omitempty"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -200,8 +222,8 @@ func (l *LocksLockDoorResponse) String() string { } type LocksUnlockDoorResponse struct { - ActionAttempt *ActionAttempt `json:"action_attempt,omitempty"` - Ok bool `json:"ok"` + ActionAttempt *ActionAttempt `json:"action_attempt,omitempty" url:"action_attempt,omitempty"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -230,6 +252,6 @@ func (l *LocksUnlockDoorResponse) String() string { } type LocksUnlockDoorRequest struct { - DeviceId string `json:"device_id"` - Sync *bool `json:"sync,omitempty"` + DeviceId string `json:"device_id" url:"device_id"` + Sync *bool `json:"sync,omitempty" url:"sync,omitempty"` } diff --git a/locks/client.go b/locks/client.go index 9d69208..1a046c0 100644 --- a/locks/client.go +++ b/locks/client.go @@ -9,6 +9,7 @@ import ( errors "errors" seamapigo "github.com/seamapi/go" core "github.com/seamapi/go/core" + option "github.com/seamapi/go/option" io "io" http "net/http" ) @@ -19,25 +20,38 @@ type Client struct { header http.Header } -func NewClient(opts ...core.ClientOption) *Client { - options := core.NewClientOptions() - for _, opt := range opts { - opt(options) - } +func NewClient(opts ...option.RequestOption) *Client { + options := core.NewRequestOptions(opts...) return &Client{ baseURL: options.BaseURL, - caller: core.NewCaller(options.HTTPClient), - header: options.ToHeader(), + caller: core.NewCaller( + &core.CallerParams{ + Client: options.HTTPClient, + MaxAttempts: options.MaxAttempts, + }, + ), + header: options.ToHeader(), } } -func (c *Client) Get(ctx context.Context, request *seamapigo.LocksGetRequest) (*seamapigo.Device, error) { +func (c *Client) Get( + ctx context.Context, + request *seamapigo.LocksGetRequest, + opts ...option.RequestOption, +) (*seamapigo.Device, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "locks/get" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -70,7 +84,9 @@ func (c *Client) Get(ctx context.Context, request *seamapigo.LocksGetRequest) (* &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -81,13 +97,24 @@ func (c *Client) Get(ctx context.Context, request *seamapigo.LocksGetRequest) (* return response.Device, nil } -func (c *Client) List(ctx context.Context, request *seamapigo.LocksListRequest) ([]*seamapigo.Device, error) { +func (c *Client) List( + ctx context.Context, + request *seamapigo.LocksListRequest, + opts ...option.RequestOption, +) ([]*seamapigo.Device, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "locks/list" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -120,7 +147,9 @@ func (c *Client) List(ctx context.Context, request *seamapigo.LocksListRequest) &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -131,13 +160,24 @@ func (c *Client) List(ctx context.Context, request *seamapigo.LocksListRequest) return response.Devices, nil } -func (c *Client) LockDoor(ctx context.Context, request *seamapigo.LocksLockDoorRequest) (*seamapigo.ActionAttempt, error) { +func (c *Client) LockDoor( + ctx context.Context, + request *seamapigo.LocksLockDoorRequest, + opts ...option.RequestOption, +) (*seamapigo.ActionAttempt, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "locks/lock_door" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -170,7 +210,9 @@ func (c *Client) LockDoor(ctx context.Context, request *seamapigo.LocksLockDoorR &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -181,13 +223,24 @@ func (c *Client) LockDoor(ctx context.Context, request *seamapigo.LocksLockDoorR return response.ActionAttempt, nil } -func (c *Client) UnlockDoor(ctx context.Context, request *seamapigo.LocksUnlockDoorRequest) (*seamapigo.ActionAttempt, error) { +func (c *Client) UnlockDoor( + ctx context.Context, + request *seamapigo.LocksUnlockDoorRequest, + opts ...option.RequestOption, +) (*seamapigo.ActionAttempt, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "locks/unlock_door" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -220,7 +273,9 @@ func (c *Client) UnlockDoor(ctx context.Context, request *seamapigo.LocksUnlockD &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, diff --git a/networks.go b/networks.go index f6af2e8..92a1c64 100644 --- a/networks.go +++ b/networks.go @@ -9,15 +9,15 @@ import ( ) type NetworksGetRequest struct { - NetworkId string `json:"network_id"` + NetworkId string `json:"network_id" url:"network_id"` } type NetworksListRequest struct { } type NetworksGetResponse struct { - Network *NetworksGetResponseNetwork `json:"network,omitempty"` - Ok bool `json:"ok"` + Network *NetworksGetResponseNetwork `json:"network,omitempty" url:"network,omitempty"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -46,8 +46,8 @@ func (n *NetworksGetResponse) String() string { } type NetworksListResponse struct { - Networks []*NetworksListResponseNetworksItem `json:"networks,omitempty"` - Ok bool `json:"ok"` + Networks []*NetworksListResponseNetworksItem `json:"networks,omitempty" url:"networks,omitempty"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } diff --git a/networks/client.go b/networks/client.go index 477a3e6..7e25e59 100644 --- a/networks/client.go +++ b/networks/client.go @@ -9,6 +9,7 @@ import ( errors "errors" seamapigo "github.com/seamapi/go" core "github.com/seamapi/go/core" + option "github.com/seamapi/go/option" io "io" http "net/http" ) @@ -19,25 +20,38 @@ type Client struct { header http.Header } -func NewClient(opts ...core.ClientOption) *Client { - options := core.NewClientOptions() - for _, opt := range opts { - opt(options) - } +func NewClient(opts ...option.RequestOption) *Client { + options := core.NewRequestOptions(opts...) return &Client{ baseURL: options.BaseURL, - caller: core.NewCaller(options.HTTPClient), - header: options.ToHeader(), + caller: core.NewCaller( + &core.CallerParams{ + Client: options.HTTPClient, + MaxAttempts: options.MaxAttempts, + }, + ), + header: options.ToHeader(), } } -func (c *Client) Get(ctx context.Context, request *seamapigo.NetworksGetRequest) (*seamapigo.NetworksGetResponse, error) { +func (c *Client) Get( + ctx context.Context, + request *seamapigo.NetworksGetRequest, + opts ...option.RequestOption, +) (*seamapigo.NetworksGetResponse, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "networks/get" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -70,7 +84,9 @@ func (c *Client) Get(ctx context.Context, request *seamapigo.NetworksGetRequest) &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -81,13 +97,24 @@ func (c *Client) Get(ctx context.Context, request *seamapigo.NetworksGetRequest) return response, nil } -func (c *Client) List(ctx context.Context, request *seamapigo.NetworksListRequest) (*seamapigo.NetworksListResponse, error) { +func (c *Client) List( + ctx context.Context, + request *seamapigo.NetworksListRequest, + opts ...option.RequestOption, +) (*seamapigo.NetworksListResponse, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "networks/list" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -120,7 +147,9 @@ func (c *Client) List(ctx context.Context, request *seamapigo.NetworksListReques &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, diff --git a/noisesensors/client/client.go b/noisesensors/client/client.go index 6b54977..de3232a 100644 --- a/noisesensors/client/client.go +++ b/noisesensors/client/client.go @@ -6,6 +6,7 @@ import ( core "github.com/seamapi/go/core" noisethresholds "github.com/seamapi/go/noisesensors/noisethresholds" simulate "github.com/seamapi/go/noisesensors/simulate" + option "github.com/seamapi/go/option" http "net/http" ) @@ -18,14 +19,16 @@ type Client struct { Simulate *simulate.Client } -func NewClient(opts ...core.ClientOption) *Client { - options := core.NewClientOptions() - for _, opt := range opts { - opt(options) - } +func NewClient(opts ...option.RequestOption) *Client { + options := core.NewRequestOptions(opts...) return &Client{ - baseURL: options.BaseURL, - caller: core.NewCaller(options.HTTPClient), + baseURL: options.BaseURL, + caller: core.NewCaller( + &core.CallerParams{ + Client: options.HTTPClient, + MaxAttempts: options.MaxAttempts, + }, + ), header: options.ToHeader(), NoiseThresholds: noisethresholds.NewClient(opts...), Simulate: simulate.NewClient(opts...), diff --git a/noisesensors/noise_thresholds.go b/noisesensors/noise_thresholds.go index 1b64d32..862cafd 100644 --- a/noisesensors/noise_thresholds.go +++ b/noisesensors/noise_thresholds.go @@ -10,34 +10,34 @@ import ( ) type NoiseThresholdsCreateRequest struct { - DeviceId string `json:"device_id"` - Sync *bool `json:"sync,omitempty"` - Name *string `json:"name,omitempty"` - StartsDailyAt string `json:"starts_daily_at"` - EndsDailyAt string `json:"ends_daily_at"` - NoiseThresholdDecibels *float64 `json:"noise_threshold_decibels,omitempty"` - NoiseThresholdNrs *float64 `json:"noise_threshold_nrs,omitempty"` + DeviceId string `json:"device_id" url:"device_id"` + Sync *bool `json:"sync,omitempty" url:"sync,omitempty"` + Name *string `json:"name,omitempty" url:"name,omitempty"` + StartsDailyAt string `json:"starts_daily_at" url:"starts_daily_at"` + EndsDailyAt string `json:"ends_daily_at" url:"ends_daily_at"` + NoiseThresholdDecibels *float64 `json:"noise_threshold_decibels,omitempty" url:"noise_threshold_decibels,omitempty"` + NoiseThresholdNrs *float64 `json:"noise_threshold_nrs,omitempty" url:"noise_threshold_nrs,omitempty"` } type NoiseThresholdsDeleteRequest struct { - NoiseThresholdId string `json:"noise_threshold_id"` - DeviceId string `json:"device_id"` - Sync *bool `json:"sync,omitempty"` + NoiseThresholdId string `json:"noise_threshold_id" url:"noise_threshold_id"` + DeviceId string `json:"device_id" url:"device_id"` + Sync *bool `json:"sync,omitempty" url:"sync,omitempty"` } type NoiseThresholdsGetRequest struct { - NoiseThresholdId string `json:"noise_threshold_id"` + NoiseThresholdId string `json:"noise_threshold_id" url:"noise_threshold_id"` } type NoiseThresholdsListRequest struct { - DeviceId string `json:"device_id"` - IsProgrammed *bool `json:"is_programmed,omitempty"` + DeviceId string `json:"device_id" url:"device_id"` + IsProgrammed *bool `json:"is_programmed,omitempty" url:"is_programmed,omitempty"` } type NoiseThresholdsCreateResponse struct { - ActionAttempt *seamapigo.ActionAttempt `json:"action_attempt,omitempty"` - NoiseThreshold *seamapigo.NoiseThreshold `json:"noise_threshold,omitempty"` - Ok bool `json:"ok"` + ActionAttempt *seamapigo.ActionAttempt `json:"action_attempt,omitempty" url:"action_attempt,omitempty"` + NoiseThreshold *seamapigo.NoiseThreshold `json:"noise_threshold,omitempty" url:"noise_threshold,omitempty"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -66,8 +66,8 @@ func (n *NoiseThresholdsCreateResponse) String() string { } type NoiseThresholdsDeleteResponse struct { - ActionAttempt *seamapigo.ActionAttempt `json:"action_attempt,omitempty"` - Ok bool `json:"ok"` + ActionAttempt *seamapigo.ActionAttempt `json:"action_attempt,omitempty" url:"action_attempt,omitempty"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -96,8 +96,8 @@ func (n *NoiseThresholdsDeleteResponse) String() string { } type NoiseThresholdsGetResponse struct { - NoiseThreshold *seamapigo.NoiseThreshold `json:"noise_threshold,omitempty"` - Ok bool `json:"ok"` + NoiseThreshold *seamapigo.NoiseThreshold `json:"noise_threshold,omitempty" url:"noise_threshold,omitempty"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -126,8 +126,8 @@ func (n *NoiseThresholdsGetResponse) String() string { } type NoiseThresholdsListResponse struct { - NoiseThresholds []*seamapigo.NoiseThreshold `json:"noise_thresholds,omitempty"` - Ok bool `json:"ok"` + NoiseThresholds []*seamapigo.NoiseThreshold `json:"noise_thresholds,omitempty" url:"noise_thresholds,omitempty"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -156,8 +156,8 @@ func (n *NoiseThresholdsListResponse) String() string { } type NoiseThresholdsUpdateResponse struct { - ActionAttempt *seamapigo.ActionAttempt `json:"action_attempt,omitempty"` - Ok bool `json:"ok"` + ActionAttempt *seamapigo.ActionAttempt `json:"action_attempt,omitempty" url:"action_attempt,omitempty"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -186,12 +186,12 @@ func (n *NoiseThresholdsUpdateResponse) String() string { } type NoiseThresholdsUpdateRequest struct { - NoiseThresholdId string `json:"noise_threshold_id"` - DeviceId string `json:"device_id"` - Sync *bool `json:"sync,omitempty"` - Name *string `json:"name,omitempty"` - StartsDailyAt *string `json:"starts_daily_at,omitempty"` - EndsDailyAt *string `json:"ends_daily_at,omitempty"` - NoiseThresholdDecibels *float64 `json:"noise_threshold_decibels,omitempty"` - NoiseThresholdNrs *float64 `json:"noise_threshold_nrs,omitempty"` + NoiseThresholdId string `json:"noise_threshold_id" url:"noise_threshold_id"` + DeviceId string `json:"device_id" url:"device_id"` + Sync *bool `json:"sync,omitempty" url:"sync,omitempty"` + Name *string `json:"name,omitempty" url:"name,omitempty"` + StartsDailyAt *string `json:"starts_daily_at,omitempty" url:"starts_daily_at,omitempty"` + EndsDailyAt *string `json:"ends_daily_at,omitempty" url:"ends_daily_at,omitempty"` + NoiseThresholdDecibels *float64 `json:"noise_threshold_decibels,omitempty" url:"noise_threshold_decibels,omitempty"` + NoiseThresholdNrs *float64 `json:"noise_threshold_nrs,omitempty" url:"noise_threshold_nrs,omitempty"` } diff --git a/noisesensors/noisethresholds/client.go b/noisesensors/noisethresholds/client.go index f05fb71..9767e4f 100644 --- a/noisesensors/noisethresholds/client.go +++ b/noisesensors/noisethresholds/client.go @@ -10,6 +10,7 @@ import ( seamapigo "github.com/seamapi/go" core "github.com/seamapi/go/core" noisesensors "github.com/seamapi/go/noisesensors" + option "github.com/seamapi/go/option" io "io" http "net/http" ) @@ -20,25 +21,38 @@ type Client struct { header http.Header } -func NewClient(opts ...core.ClientOption) *Client { - options := core.NewClientOptions() - for _, opt := range opts { - opt(options) - } +func NewClient(opts ...option.RequestOption) *Client { + options := core.NewRequestOptions(opts...) return &Client{ baseURL: options.BaseURL, - caller: core.NewCaller(options.HTTPClient), - header: options.ToHeader(), + caller: core.NewCaller( + &core.CallerParams{ + Client: options.HTTPClient, + MaxAttempts: options.MaxAttempts, + }, + ), + header: options.ToHeader(), } } -func (c *Client) Create(ctx context.Context, request *noisesensors.NoiseThresholdsCreateRequest) (*seamapigo.NoiseThreshold, error) { +func (c *Client) Create( + ctx context.Context, + request *noisesensors.NoiseThresholdsCreateRequest, + opts ...option.RequestOption, +) (*seamapigo.NoiseThreshold, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "noise_sensors/noise_thresholds/create" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -71,7 +85,9 @@ func (c *Client) Create(ctx context.Context, request *noisesensors.NoiseThreshol &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -82,13 +98,24 @@ func (c *Client) Create(ctx context.Context, request *noisesensors.NoiseThreshol return response.NoiseThreshold, nil } -func (c *Client) Delete(ctx context.Context, request *noisesensors.NoiseThresholdsDeleteRequest) (*seamapigo.ActionAttempt, error) { +func (c *Client) Delete( + ctx context.Context, + request *noisesensors.NoiseThresholdsDeleteRequest, + opts ...option.RequestOption, +) (*seamapigo.ActionAttempt, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "noise_sensors/noise_thresholds/delete" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -121,7 +148,9 @@ func (c *Client) Delete(ctx context.Context, request *noisesensors.NoiseThreshol &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -132,13 +161,24 @@ func (c *Client) Delete(ctx context.Context, request *noisesensors.NoiseThreshol return response.ActionAttempt, nil } -func (c *Client) Get(ctx context.Context, request *noisesensors.NoiseThresholdsGetRequest) (*seamapigo.NoiseThreshold, error) { +func (c *Client) Get( + ctx context.Context, + request *noisesensors.NoiseThresholdsGetRequest, + opts ...option.RequestOption, +) (*seamapigo.NoiseThreshold, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "noise_sensors/noise_thresholds/get" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -171,7 +211,9 @@ func (c *Client) Get(ctx context.Context, request *noisesensors.NoiseThresholdsG &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -182,13 +224,24 @@ func (c *Client) Get(ctx context.Context, request *noisesensors.NoiseThresholdsG return response.NoiseThreshold, nil } -func (c *Client) List(ctx context.Context, request *noisesensors.NoiseThresholdsListRequest) ([]*seamapigo.NoiseThreshold, error) { +func (c *Client) List( + ctx context.Context, + request *noisesensors.NoiseThresholdsListRequest, + opts ...option.RequestOption, +) ([]*seamapigo.NoiseThreshold, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "noise_sensors/noise_thresholds/list" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -221,7 +274,9 @@ func (c *Client) List(ctx context.Context, request *noisesensors.NoiseThresholds &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -232,13 +287,24 @@ func (c *Client) List(ctx context.Context, request *noisesensors.NoiseThresholds return response.NoiseThresholds, nil } -func (c *Client) Update(ctx context.Context, request *noisesensors.NoiseThresholdsUpdateRequest) (*seamapigo.ActionAttempt, error) { +func (c *Client) Update( + ctx context.Context, + request *noisesensors.NoiseThresholdsUpdateRequest, + opts ...option.RequestOption, +) (*seamapigo.ActionAttempt, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "noise_sensors/noise_thresholds/update" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -271,7 +337,9 @@ func (c *Client) Update(ctx context.Context, request *noisesensors.NoiseThreshol &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, diff --git a/noisesensors/simulate.go b/noisesensors/simulate.go index f81a8ae..5f06935 100644 --- a/noisesensors/simulate.go +++ b/noisesensors/simulate.go @@ -9,11 +9,11 @@ import ( ) type SimulateTriggerNoiseThresholdRequest struct { - DeviceId string `json:"device_id"` + DeviceId string `json:"device_id" url:"device_id"` } type SimulateTriggerNoiseThresholdResponse struct { - Ok bool `json:"ok"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } diff --git a/noisesensors/simulate/client.go b/noisesensors/simulate/client.go index 51cc294..009e725 100644 --- a/noisesensors/simulate/client.go +++ b/noisesensors/simulate/client.go @@ -10,6 +10,7 @@ import ( seamapigo "github.com/seamapi/go" core "github.com/seamapi/go/core" noisesensors "github.com/seamapi/go/noisesensors" + option "github.com/seamapi/go/option" io "io" http "net/http" ) @@ -20,25 +21,38 @@ type Client struct { header http.Header } -func NewClient(opts ...core.ClientOption) *Client { - options := core.NewClientOptions() - for _, opt := range opts { - opt(options) - } +func NewClient(opts ...option.RequestOption) *Client { + options := core.NewRequestOptions(opts...) return &Client{ baseURL: options.BaseURL, - caller: core.NewCaller(options.HTTPClient), - header: options.ToHeader(), + caller: core.NewCaller( + &core.CallerParams{ + Client: options.HTTPClient, + MaxAttempts: options.MaxAttempts, + }, + ), + header: options.ToHeader(), } } -func (c *Client) TriggerNoiseThreshold(ctx context.Context, request *noisesensors.SimulateTriggerNoiseThresholdRequest) (*noisesensors.SimulateTriggerNoiseThresholdResponse, error) { +func (c *Client) TriggerNoiseThreshold( + ctx context.Context, + request *noisesensors.SimulateTriggerNoiseThresholdRequest, + opts ...option.RequestOption, +) (*noisesensors.SimulateTriggerNoiseThresholdResponse, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "noise_sensors/simulate/trigger_noise_threshold" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -71,7 +85,9 @@ func (c *Client) TriggerNoiseThreshold(ctx context.Context, request *noisesensor &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, diff --git a/option/request_option.go b/option/request_option.go new file mode 100644 index 0000000..ad59428 --- /dev/null +++ b/option/request_option.go @@ -0,0 +1,69 @@ +// This file was auto-generated by Fern from our API Definition. + +package option + +import ( + core "github.com/seamapi/go/core" + http "net/http" +) + +// RequestOption adapts the behavior of an indivdual request. +type RequestOption = core.RequestOption + +// WithBaseURL sets the base URL, overriding the default +// environment, if any. +func WithBaseURL(baseURL string) *core.BaseURLOption { + return &core.BaseURLOption{ + BaseURL: baseURL, + } +} + +// WithHTTPClient uses the given HTTPClient to issue the request. +func WithHTTPClient(httpClient core.HTTPClient) *core.HTTPClientOption { + return &core.HTTPClientOption{ + HTTPClient: httpClient, + } +} + +// WithHTTPHeader adds the given http.Header to the request. +func WithHTTPHeader(httpHeader http.Header) *core.HTTPHeaderOption { + return &core.HTTPHeaderOption{ + // Clone the headers so they can't be modified after the option call. + HTTPHeader: httpHeader.Clone(), + } +} + +// WithMaxAttempts configures the maximum number of retry attempts. +func WithMaxAttempts(attempts uint) *core.MaxAttemptsOption { + return &core.MaxAttemptsOption{ + MaxAttempts: attempts, + } +} + +// WithApiKey sets the 'Authorization: Bearer ' request header. +func WithApiKey(apiKey string) *core.ApiKeyOption { + return &core.ApiKeyOption{ + ApiKey: apiKey, + } +} + +// WithSeamWorkspace sets the seamWorkspace request header. +func WithSeamWorkspace(seamWorkspace string) *core.SeamWorkspaceOption { + return &core.SeamWorkspaceOption{ + SeamWorkspace: seamWorkspace, + } +} + +// WithSeamClientSessionToken sets the seamClientSessionToken request header. +func WithSeamClientSessionToken(seamClientSessionToken string) *core.SeamClientSessionTokenOption { + return &core.SeamClientSessionTokenOption{ + SeamClientSessionToken: seamClientSessionToken, + } +} + +// WithClientSessionToken sets the clientSessionToken request header. +func WithClientSessionToken(clientSessionToken string) *core.ClientSessionTokenOption { + return &core.ClientSessionTokenOption{ + ClientSessionToken: clientSessionToken, + } +} diff --git a/phones.go b/phones.go index c7ddced..593e421 100644 --- a/phones.go +++ b/phones.go @@ -9,15 +9,15 @@ import ( ) type PhonesDeactivateRequest struct { - DeviceId string `json:"device_id"` + DeviceId string `json:"device_id" url:"device_id"` } type PhonesListRequest struct { - OwnerUserIdentityId *string `json:"owner_user_identity_id,omitempty"` + OwnerUserIdentityId *string `json:"owner_user_identity_id,omitempty" url:"owner_user_identity_id,omitempty"` } type PhonesDeactivateResponse struct { - Ok bool `json:"ok"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -46,8 +46,8 @@ func (p *PhonesDeactivateResponse) String() string { } type PhonesListResponse struct { - Phones []*Phone `json:"phones,omitempty"` - Ok bool `json:"ok"` + Phones []*Phone `json:"phones,omitempty" url:"phones,omitempty"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } diff --git a/phones/client/client.go b/phones/client/client.go index 66b5a47..8a7bff3 100644 --- a/phones/client/client.go +++ b/phones/client/client.go @@ -9,6 +9,7 @@ import ( errors "errors" seamapigo "github.com/seamapi/go" core "github.com/seamapi/go/core" + option "github.com/seamapi/go/option" simulate "github.com/seamapi/go/phones/simulate" io "io" http "net/http" @@ -22,26 +23,39 @@ type Client struct { Simulate *simulate.Client } -func NewClient(opts ...core.ClientOption) *Client { - options := core.NewClientOptions() - for _, opt := range opts { - opt(options) - } +func NewClient(opts ...option.RequestOption) *Client { + options := core.NewRequestOptions(opts...) return &Client{ - baseURL: options.BaseURL, - caller: core.NewCaller(options.HTTPClient), + baseURL: options.BaseURL, + caller: core.NewCaller( + &core.CallerParams{ + Client: options.HTTPClient, + MaxAttempts: options.MaxAttempts, + }, + ), header: options.ToHeader(), Simulate: simulate.NewClient(opts...), } } -func (c *Client) Deactivate(ctx context.Context, request *seamapigo.PhonesDeactivateRequest) (*seamapigo.PhonesDeactivateResponse, error) { +func (c *Client) Deactivate( + ctx context.Context, + request *seamapigo.PhonesDeactivateRequest, + opts ...option.RequestOption, +) (*seamapigo.PhonesDeactivateResponse, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "phones/deactivate" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -74,7 +88,9 @@ func (c *Client) Deactivate(ctx context.Context, request *seamapigo.PhonesDeacti &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -85,13 +101,24 @@ func (c *Client) Deactivate(ctx context.Context, request *seamapigo.PhonesDeacti return response, nil } -func (c *Client) List(ctx context.Context, request *seamapigo.PhonesListRequest) ([]*seamapigo.Phone, error) { +func (c *Client) List( + ctx context.Context, + request *seamapigo.PhonesListRequest, + opts ...option.RequestOption, +) ([]*seamapigo.Phone, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "phones/list" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -124,7 +151,9 @@ func (c *Client) List(ctx context.Context, request *seamapigo.PhonesListRequest) &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, diff --git a/phones/simulate.go b/phones/simulate.go index 1e53d2c..236da88 100644 --- a/phones/simulate.go +++ b/phones/simulate.go @@ -10,20 +10,20 @@ import ( ) type SimulateCreateSandboxPhoneRequest struct { - AssaAbloyCredentialServiceAcsSystemId string `json:"assa_abloy_credential_service_acs_system_id"` - CustomSdkInstallationId *string `json:"custom_sdk_installation_id,omitempty"` - UserIdentityId string `json:"user_identity_id"` - PhoneMetadata *SimulateCreateSandboxPhoneRequestPhoneMetadata `json:"phone_metadata,omitempty"` - AssaAbloyMetadata *SimulateCreateSandboxPhoneRequestAssaAbloyMetadata `json:"assa_abloy_metadata,omitempty"` + AssaAbloyCredentialServiceAcsSystemId string `json:"assa_abloy_credential_service_acs_system_id" url:"assa_abloy_credential_service_acs_system_id"` + CustomSdkInstallationId *string `json:"custom_sdk_installation_id,omitempty" url:"custom_sdk_installation_id,omitempty"` + UserIdentityId string `json:"user_identity_id" url:"user_identity_id"` + PhoneMetadata *SimulateCreateSandboxPhoneRequestPhoneMetadata `json:"phone_metadata,omitempty" url:"phone_metadata,omitempty"` + AssaAbloyMetadata *SimulateCreateSandboxPhoneRequestAssaAbloyMetadata `json:"assa_abloy_metadata,omitempty" url:"assa_abloy_metadata,omitempty"` } type SimulateCreateSandboxPhoneRequestAssaAbloyMetadata struct { - BleCapability *bool `json:"ble_capability,omitempty"` - HceCapability *bool `json:"hce_capability,omitempty"` - NfcCapability *bool `json:"nfc_capability,omitempty"` - ApplicationVersion *string `json:"application_version,omitempty"` - SeosAppletVersion *string `json:"seos_applet_version,omitempty"` - SeosTsmEndpointId *float64 `json:"seos_tsm_endpoint_id,omitempty"` + BleCapability *bool `json:"ble_capability,omitempty" url:"ble_capability,omitempty"` + HceCapability *bool `json:"hce_capability,omitempty" url:"hce_capability,omitempty"` + NfcCapability *bool `json:"nfc_capability,omitempty" url:"nfc_capability,omitempty"` + ApplicationVersion *string `json:"application_version,omitempty" url:"application_version,omitempty"` + SeosAppletVersion *string `json:"seos_applet_version,omitempty" url:"seos_applet_version,omitempty"` + SeosTsmEndpointId *float64 `json:"seos_tsm_endpoint_id,omitempty" url:"seos_tsm_endpoint_id,omitempty"` _rawJSON json.RawMessage } @@ -52,10 +52,10 @@ func (s *SimulateCreateSandboxPhoneRequestAssaAbloyMetadata) String() string { } type SimulateCreateSandboxPhoneRequestPhoneMetadata struct { - OperatingSystem *seamapigo.PhoneOperatingSystem `json:"operating_system,omitempty"` - OsVersion *string `json:"os_version,omitempty"` - DeviceManufacturer *string `json:"device_manufacturer,omitempty"` - DeviceModel *string `json:"device_model,omitempty"` + OperatingSystem *seamapigo.PhoneOperatingSystem `json:"operating_system,omitempty" url:"operating_system,omitempty"` + OsVersion *string `json:"os_version,omitempty" url:"os_version,omitempty"` + DeviceManufacturer *string `json:"device_manufacturer,omitempty" url:"device_manufacturer,omitempty"` + DeviceModel *string `json:"device_model,omitempty" url:"device_model,omitempty"` _rawJSON json.RawMessage } @@ -84,8 +84,8 @@ func (s *SimulateCreateSandboxPhoneRequestPhoneMetadata) String() string { } type SimulateCreateSandboxPhoneResponse struct { - Phone *seamapigo.Phone `json:"phone,omitempty"` - Ok bool `json:"ok"` + Phone *seamapigo.Phone `json:"phone,omitempty" url:"phone,omitempty"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } diff --git a/phones/simulate/client.go b/phones/simulate/client.go index deca55d..bda0cc3 100644 --- a/phones/simulate/client.go +++ b/phones/simulate/client.go @@ -9,6 +9,7 @@ import ( errors "errors" seamapigo "github.com/seamapi/go" core "github.com/seamapi/go/core" + option "github.com/seamapi/go/option" phones "github.com/seamapi/go/phones" io "io" http "net/http" @@ -20,25 +21,38 @@ type Client struct { header http.Header } -func NewClient(opts ...core.ClientOption) *Client { - options := core.NewClientOptions() - for _, opt := range opts { - opt(options) - } +func NewClient(opts ...option.RequestOption) *Client { + options := core.NewRequestOptions(opts...) return &Client{ baseURL: options.BaseURL, - caller: core.NewCaller(options.HTTPClient), - header: options.ToHeader(), + caller: core.NewCaller( + &core.CallerParams{ + Client: options.HTTPClient, + MaxAttempts: options.MaxAttempts, + }, + ), + header: options.ToHeader(), } } -func (c *Client) CreateSandboxPhone(ctx context.Context, request *phones.SimulateCreateSandboxPhoneRequest) (*seamapigo.Phone, error) { +func (c *Client) CreateSandboxPhone( + ctx context.Context, + request *phones.SimulateCreateSandboxPhoneRequest, + opts ...option.RequestOption, +) (*seamapigo.Phone, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "phones/simulate/create_sandbox_phone" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -71,7 +85,9 @@ func (c *Client) CreateSandboxPhone(ctx context.Context, request *phones.Simulat &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, diff --git a/pointer.go b/pointer.go index 82fb917..faaf462 100644 --- a/pointer.go +++ b/pointer.go @@ -1,6 +1,10 @@ package api -import "time" +import ( + "time" + + "github.com/google/uuid" +) // Bool returns a pointer to the given bool value. func Bool(b bool) *bool { @@ -97,7 +101,32 @@ func Uintptr(u uintptr) *uintptr { return &u } +// UUID returns a pointer to the given uuid.UUID value. +func UUID(u uuid.UUID) *uuid.UUID { + return &u +} + // Time returns a pointer to the given time.Time value. func Time(t time.Time) *time.Time { return &t } + +// MustParseDate attempts to parse the given string as a +// date time.Time, and panics upon failure. +func MustParseDate(date string) time.Time { + t, err := time.Parse("2006-01-02", date) + if err != nil { + panic(err) + } + return t +} + +// MustParseDateTime attempts to parse the given string as a +// datetime time.Time, and panics upon failure. +func MustParseDateTime(datetime string) time.Time { + t, err := time.Parse(time.RFC3339, datetime) + if err != nil { + panic(err) + } + return t +} diff --git a/thermostats.go b/thermostats.go index 8f3df00..f60d9e1 100644 --- a/thermostats.go +++ b/thermostats.go @@ -10,62 +10,84 @@ import ( ) type ThermostatsCoolRequest struct { - DeviceId string `json:"device_id"` - CoolingSetPointCelsius *float64 `json:"cooling_set_point_celsius,omitempty"` - CoolingSetPointFahrenheit *float64 `json:"cooling_set_point_fahrenheit,omitempty"` - Sync *bool `json:"sync,omitempty"` + DeviceId string `json:"device_id" url:"device_id"` + CoolingSetPointCelsius *float64 `json:"cooling_set_point_celsius,omitempty" url:"cooling_set_point_celsius,omitempty"` + CoolingSetPointFahrenheit *float64 `json:"cooling_set_point_fahrenheit,omitempty" url:"cooling_set_point_fahrenheit,omitempty"` + Sync *bool `json:"sync,omitempty" url:"sync,omitempty"` } type ThermostatsGetRequest struct { - DeviceId *string `json:"device_id,omitempty"` - Name *string `json:"name,omitempty"` + DeviceId *string `json:"device_id,omitempty" url:"device_id,omitempty"` + Name *string `json:"name,omitempty" url:"name,omitempty"` } type ThermostatsHeatRequest struct { - DeviceId string `json:"device_id"` - HeatingSetPointCelsius *float64 `json:"heating_set_point_celsius,omitempty"` - HeatingSetPointFahrenheit *float64 `json:"heating_set_point_fahrenheit,omitempty"` - Sync *bool `json:"sync,omitempty"` + DeviceId string `json:"device_id" url:"device_id"` + HeatingSetPointCelsius *float64 `json:"heating_set_point_celsius,omitempty" url:"heating_set_point_celsius,omitempty"` + HeatingSetPointFahrenheit *float64 `json:"heating_set_point_fahrenheit,omitempty" url:"heating_set_point_fahrenheit,omitempty"` + Sync *bool `json:"sync,omitempty" url:"sync,omitempty"` } type ThermostatsHeatCoolRequest struct { - DeviceId string `json:"device_id"` - HeatingSetPointCelsius *float64 `json:"heating_set_point_celsius,omitempty"` - HeatingSetPointFahrenheit *float64 `json:"heating_set_point_fahrenheit,omitempty"` - CoolingSetPointCelsius *float64 `json:"cooling_set_point_celsius,omitempty"` - CoolingSetPointFahrenheit *float64 `json:"cooling_set_point_fahrenheit,omitempty"` - Sync *bool `json:"sync,omitempty"` + DeviceId string `json:"device_id" url:"device_id"` + HeatingSetPointCelsius *float64 `json:"heating_set_point_celsius,omitempty" url:"heating_set_point_celsius,omitempty"` + HeatingSetPointFahrenheit *float64 `json:"heating_set_point_fahrenheit,omitempty" url:"heating_set_point_fahrenheit,omitempty"` + CoolingSetPointCelsius *float64 `json:"cooling_set_point_celsius,omitempty" url:"cooling_set_point_celsius,omitempty"` + CoolingSetPointFahrenheit *float64 `json:"cooling_set_point_fahrenheit,omitempty" url:"cooling_set_point_fahrenheit,omitempty"` + Sync *bool `json:"sync,omitempty" url:"sync,omitempty"` } type ThermostatsListRequest struct { // List all devices owned by this connected account - ConnectedAccountId *string `json:"connected_account_id,omitempty"` - ConnectedAccountIds []string `json:"connected_account_ids,omitempty"` - ConnectWebviewId *string `json:"connect_webview_id,omitempty"` - DeviceType *DeviceType `json:"device_type,omitempty"` - DeviceTypes []DeviceType `json:"device_types,omitempty"` - Manufacturer *Manufacturer `json:"manufacturer,omitempty"` - DeviceIds []string `json:"device_ids,omitempty"` - Limit *float64 `json:"limit,omitempty"` - CreatedBefore *time.Time `json:"created_before,omitempty"` - UserIdentifierKey *string `json:"user_identifier_key,omitempty"` - CustomMetadataHas map[string]*ThermostatsListRequestCustomMetadataHasValue `json:"custom_metadata_has,omitempty"` + ConnectedAccountId *string `json:"connected_account_id,omitempty" url:"connected_account_id,omitempty"` + ConnectedAccountIds []string `json:"connected_account_ids,omitempty" url:"connected_account_ids,omitempty"` + ConnectWebviewId *string `json:"connect_webview_id,omitempty" url:"connect_webview_id,omitempty"` + DeviceType *DeviceType `json:"device_type,omitempty" url:"device_type,omitempty"` + DeviceTypes []DeviceType `json:"device_types,omitempty" url:"device_types,omitempty"` + Manufacturer *Manufacturer `json:"manufacturer,omitempty" url:"manufacturer,omitempty"` + DeviceIds []string `json:"device_ids,omitempty" url:"device_ids,omitempty"` + Limit *float64 `json:"limit,omitempty" url:"limit,omitempty"` + CreatedBefore *time.Time `json:"created_before,omitempty" url:"created_before,omitempty"` + UserIdentifierKey *string `json:"user_identifier_key,omitempty" url:"user_identifier_key,omitempty"` + CustomMetadataHas map[string]*ThermostatsListRequestCustomMetadataHasValue `json:"custom_metadata_has,omitempty" url:"custom_metadata_has,omitempty"` +} + +func (t *ThermostatsListRequest) UnmarshalJSON(data []byte) error { + type unmarshaler ThermostatsListRequest + var body unmarshaler + if err := json.Unmarshal(data, &body); err != nil { + return err + } + *t = ThermostatsListRequest(body) + return nil +} + +func (t *ThermostatsListRequest) MarshalJSON() ([]byte, error) { + type embed ThermostatsListRequest + var marshaler = struct { + embed + CreatedBefore *core.DateTime `json:"created_before,omitempty"` + }{ + embed: embed(*t), + CreatedBefore: core.NewOptionalDateTime(t.CreatedBefore), + } + return json.Marshal(marshaler) } type ThermostatsOffRequest struct { - DeviceId string `json:"device_id"` - Sync *bool `json:"sync,omitempty"` + DeviceId string `json:"device_id" url:"device_id"` + Sync *bool `json:"sync,omitempty" url:"sync,omitempty"` } type ThermostatsSetFanModeRequest struct { - DeviceId string `json:"device_id"` - FanMode *FanMode `json:"fan_mode,omitempty"` - FanModeSetting *ThermostatsSetFanModeRequestFanModeSetting `json:"fan_mode_setting,omitempty"` - Sync *bool `json:"sync,omitempty"` + DeviceId string `json:"device_id" url:"device_id"` + FanMode *FanMode `json:"fan_mode,omitempty" url:"fan_mode,omitempty"` + FanModeSetting *ThermostatsSetFanModeRequestFanModeSetting `json:"fan_mode_setting,omitempty" url:"fan_mode_setting,omitempty"` + Sync *bool `json:"sync,omitempty" url:"sync,omitempty"` } type ThermostatsCoolResponse struct { - Ok bool `json:"ok"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -94,8 +116,8 @@ func (t *ThermostatsCoolResponse) String() string { } type ThermostatsGetResponse struct { - Thermostat *Device `json:"thermostat,omitempty"` - Ok bool `json:"ok"` + Thermostat *Device `json:"thermostat,omitempty" url:"thermostat,omitempty"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -124,7 +146,7 @@ func (t *ThermostatsGetResponse) String() string { } type ThermostatsHeatCoolResponse struct { - Ok bool `json:"ok"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -153,7 +175,7 @@ func (t *ThermostatsHeatCoolResponse) String() string { } type ThermostatsHeatResponse struct { - Ok bool `json:"ok"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -255,8 +277,8 @@ func (t *ThermostatsListRequestCustomMetadataHasValue) Accept(visitor Thermostat } type ThermostatsListResponse struct { - Thermostats []*Device `json:"thermostats,omitempty"` - Ok bool `json:"ok"` + Thermostats []*Device `json:"thermostats,omitempty" url:"thermostats,omitempty"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -285,7 +307,7 @@ func (t *ThermostatsListResponse) String() string { } type ThermostatsOffResponse struct { - Ok bool `json:"ok"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -336,7 +358,7 @@ func (t ThermostatsSetFanModeRequestFanModeSetting) Ptr() *ThermostatsSetFanMode } type ThermostatsSetFanModeResponse struct { - Ok bool `json:"ok"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -365,14 +387,14 @@ func (t *ThermostatsSetFanModeResponse) String() string { } type ThermostatsUpdateRequestDefaultClimateSetting struct { - AutomaticHeatingEnabled *bool `json:"automatic_heating_enabled,omitempty"` - AutomaticCoolingEnabled *bool `json:"automatic_cooling_enabled,omitempty"` - HvacModeSetting *ThermostatsUpdateRequestDefaultClimateSettingHvacModeSetting `json:"hvac_mode_setting,omitempty"` - CoolingSetPointCelsius *float64 `json:"cooling_set_point_celsius,omitempty"` - HeatingSetPointCelsius *float64 `json:"heating_set_point_celsius,omitempty"` - CoolingSetPointFahrenheit *float64 `json:"cooling_set_point_fahrenheit,omitempty"` - HeatingSetPointFahrenheit *float64 `json:"heating_set_point_fahrenheit,omitempty"` - ManualOverrideAllowed *bool `json:"manual_override_allowed,omitempty"` + AutomaticHeatingEnabled *bool `json:"automatic_heating_enabled,omitempty" url:"automatic_heating_enabled,omitempty"` + AutomaticCoolingEnabled *bool `json:"automatic_cooling_enabled,omitempty" url:"automatic_cooling_enabled,omitempty"` + HvacModeSetting *ThermostatsUpdateRequestDefaultClimateSettingHvacModeSetting `json:"hvac_mode_setting,omitempty" url:"hvac_mode_setting,omitempty"` + CoolingSetPointCelsius *float64 `json:"cooling_set_point_celsius,omitempty" url:"cooling_set_point_celsius,omitempty"` + HeatingSetPointCelsius *float64 `json:"heating_set_point_celsius,omitempty" url:"heating_set_point_celsius,omitempty"` + CoolingSetPointFahrenheit *float64 `json:"cooling_set_point_fahrenheit,omitempty" url:"cooling_set_point_fahrenheit,omitempty"` + HeatingSetPointFahrenheit *float64 `json:"heating_set_point_fahrenheit,omitempty" url:"heating_set_point_fahrenheit,omitempty"` + ManualOverrideAllowed *bool `json:"manual_override_allowed,omitempty" url:"manual_override_allowed,omitempty"` _rawJSON json.RawMessage } @@ -401,7 +423,7 @@ func (t *ThermostatsUpdateRequestDefaultClimateSetting) String() string { } type ThermostatsUpdateResponse struct { - Ok bool `json:"ok"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -430,6 +452,6 @@ func (t *ThermostatsUpdateResponse) String() string { } type ThermostatsUpdateRequest struct { - DeviceId string `json:"device_id"` - DefaultClimateSetting *ThermostatsUpdateRequestDefaultClimateSetting `json:"default_climate_setting,omitempty"` + DeviceId string `json:"device_id" url:"device_id"` + DefaultClimateSetting *ThermostatsUpdateRequestDefaultClimateSetting `json:"default_climate_setting,omitempty" url:"default_climate_setting,omitempty"` } diff --git a/thermostats/client/client.go b/thermostats/client/client.go index f0c1fa2..884ec78 100644 --- a/thermostats/client/client.go +++ b/thermostats/client/client.go @@ -9,6 +9,7 @@ import ( errors "errors" seamapigo "github.com/seamapi/go" core "github.com/seamapi/go/core" + option "github.com/seamapi/go/option" climatesettingschedules "github.com/seamapi/go/thermostats/climatesettingschedules" io "io" http "net/http" @@ -22,26 +23,39 @@ type Client struct { ClimateSettingSchedules *climatesettingschedules.Client } -func NewClient(opts ...core.ClientOption) *Client { - options := core.NewClientOptions() - for _, opt := range opts { - opt(options) - } +func NewClient(opts ...option.RequestOption) *Client { + options := core.NewRequestOptions(opts...) return &Client{ - baseURL: options.BaseURL, - caller: core.NewCaller(options.HTTPClient), + baseURL: options.BaseURL, + caller: core.NewCaller( + &core.CallerParams{ + Client: options.HTTPClient, + MaxAttempts: options.MaxAttempts, + }, + ), header: options.ToHeader(), ClimateSettingSchedules: climatesettingschedules.NewClient(opts...), } } -func (c *Client) Cool(ctx context.Context, request *seamapigo.ThermostatsCoolRequest) (*seamapigo.ThermostatsCoolResponse, error) { +func (c *Client) Cool( + ctx context.Context, + request *seamapigo.ThermostatsCoolRequest, + opts ...option.RequestOption, +) (*seamapigo.ThermostatsCoolResponse, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "thermostats/cool" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -74,7 +88,9 @@ func (c *Client) Cool(ctx context.Context, request *seamapigo.ThermostatsCoolReq &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -85,13 +101,24 @@ func (c *Client) Cool(ctx context.Context, request *seamapigo.ThermostatsCoolReq return response, nil } -func (c *Client) Get(ctx context.Context, request *seamapigo.ThermostatsGetRequest) (*seamapigo.Device, error) { +func (c *Client) Get( + ctx context.Context, + request *seamapigo.ThermostatsGetRequest, + opts ...option.RequestOption, +) (*seamapigo.Device, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "thermostats/get" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -124,7 +151,9 @@ func (c *Client) Get(ctx context.Context, request *seamapigo.ThermostatsGetReque &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -135,13 +164,24 @@ func (c *Client) Get(ctx context.Context, request *seamapigo.ThermostatsGetReque return response.Thermostat, nil } -func (c *Client) Heat(ctx context.Context, request *seamapigo.ThermostatsHeatRequest) (*seamapigo.ThermostatsHeatResponse, error) { +func (c *Client) Heat( + ctx context.Context, + request *seamapigo.ThermostatsHeatRequest, + opts ...option.RequestOption, +) (*seamapigo.ThermostatsHeatResponse, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "thermostats/heat" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -174,7 +214,9 @@ func (c *Client) Heat(ctx context.Context, request *seamapigo.ThermostatsHeatReq &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -185,13 +227,24 @@ func (c *Client) Heat(ctx context.Context, request *seamapigo.ThermostatsHeatReq return response, nil } -func (c *Client) HeatCool(ctx context.Context, request *seamapigo.ThermostatsHeatCoolRequest) (*seamapigo.ThermostatsHeatCoolResponse, error) { +func (c *Client) HeatCool( + ctx context.Context, + request *seamapigo.ThermostatsHeatCoolRequest, + opts ...option.RequestOption, +) (*seamapigo.ThermostatsHeatCoolResponse, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "thermostats/heat_cool" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -224,7 +277,9 @@ func (c *Client) HeatCool(ctx context.Context, request *seamapigo.ThermostatsHea &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -235,13 +290,24 @@ func (c *Client) HeatCool(ctx context.Context, request *seamapigo.ThermostatsHea return response, nil } -func (c *Client) List(ctx context.Context, request *seamapigo.ThermostatsListRequest) ([]*seamapigo.Device, error) { +func (c *Client) List( + ctx context.Context, + request *seamapigo.ThermostatsListRequest, + opts ...option.RequestOption, +) ([]*seamapigo.Device, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "thermostats/list" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -274,7 +340,9 @@ func (c *Client) List(ctx context.Context, request *seamapigo.ThermostatsListReq &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -285,13 +353,24 @@ func (c *Client) List(ctx context.Context, request *seamapigo.ThermostatsListReq return response.Thermostats, nil } -func (c *Client) Off(ctx context.Context, request *seamapigo.ThermostatsOffRequest) (*seamapigo.ThermostatsOffResponse, error) { +func (c *Client) Off( + ctx context.Context, + request *seamapigo.ThermostatsOffRequest, + opts ...option.RequestOption, +) (*seamapigo.ThermostatsOffResponse, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "thermostats/off" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -324,7 +403,9 @@ func (c *Client) Off(ctx context.Context, request *seamapigo.ThermostatsOffReque &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -335,13 +416,24 @@ func (c *Client) Off(ctx context.Context, request *seamapigo.ThermostatsOffReque return response, nil } -func (c *Client) SetFanMode(ctx context.Context, request *seamapigo.ThermostatsSetFanModeRequest) (*seamapigo.ThermostatsSetFanModeResponse, error) { +func (c *Client) SetFanMode( + ctx context.Context, + request *seamapigo.ThermostatsSetFanModeRequest, + opts ...option.RequestOption, +) (*seamapigo.ThermostatsSetFanModeResponse, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "thermostats/set_fan_mode" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -374,7 +466,9 @@ func (c *Client) SetFanMode(ctx context.Context, request *seamapigo.ThermostatsS &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -385,13 +479,24 @@ func (c *Client) SetFanMode(ctx context.Context, request *seamapigo.ThermostatsS return response, nil } -func (c *Client) Update(ctx context.Context, request *seamapigo.ThermostatsUpdateRequest) (*seamapigo.ThermostatsUpdateResponse, error) { +func (c *Client) Update( + ctx context.Context, + request *seamapigo.ThermostatsUpdateRequest, + opts ...option.RequestOption, +) (*seamapigo.ThermostatsUpdateResponse, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "thermostats/update" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -424,7 +529,9 @@ func (c *Client) Update(ctx context.Context, request *seamapigo.ThermostatsUpdat &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, diff --git a/thermostats/climate_setting_schedules.go b/thermostats/climate_setting_schedules.go index c78809d..a1b5dae 100644 --- a/thermostats/climate_setting_schedules.go +++ b/thermostats/climate_setting_schedules.go @@ -10,33 +10,33 @@ import ( ) type ClimateSettingSchedulesCreateRequest struct { - ScheduleType *string `json:"schedule_type,omitempty"` - DeviceId string `json:"device_id"` - Name *string `json:"name,omitempty"` - ScheduleStartsAt string `json:"schedule_starts_at"` - ScheduleEndsAt string `json:"schedule_ends_at"` - AutomaticHeatingEnabled *bool `json:"automatic_heating_enabled,omitempty"` - AutomaticCoolingEnabled *bool `json:"automatic_cooling_enabled,omitempty"` - HvacModeSetting *ClimateSettingSchedulesCreateRequestHvacModeSetting `json:"hvac_mode_setting,omitempty"` - CoolingSetPointCelsius *float64 `json:"cooling_set_point_celsius,omitempty"` - HeatingSetPointCelsius *float64 `json:"heating_set_point_celsius,omitempty"` - CoolingSetPointFahrenheit *float64 `json:"cooling_set_point_fahrenheit,omitempty"` - HeatingSetPointFahrenheit *float64 `json:"heating_set_point_fahrenheit,omitempty"` - ManualOverrideAllowed *bool `json:"manual_override_allowed,omitempty"` + ScheduleType *string `json:"schedule_type,omitempty" url:"schedule_type,omitempty"` + DeviceId string `json:"device_id" url:"device_id"` + Name *string `json:"name,omitempty" url:"name,omitempty"` + ScheduleStartsAt string `json:"schedule_starts_at" url:"schedule_starts_at"` + ScheduleEndsAt string `json:"schedule_ends_at" url:"schedule_ends_at"` + AutomaticHeatingEnabled *bool `json:"automatic_heating_enabled,omitempty" url:"automatic_heating_enabled,omitempty"` + AutomaticCoolingEnabled *bool `json:"automatic_cooling_enabled,omitempty" url:"automatic_cooling_enabled,omitempty"` + HvacModeSetting *ClimateSettingSchedulesCreateRequestHvacModeSetting `json:"hvac_mode_setting,omitempty" url:"hvac_mode_setting,omitempty"` + CoolingSetPointCelsius *float64 `json:"cooling_set_point_celsius,omitempty" url:"cooling_set_point_celsius,omitempty"` + HeatingSetPointCelsius *float64 `json:"heating_set_point_celsius,omitempty" url:"heating_set_point_celsius,omitempty"` + CoolingSetPointFahrenheit *float64 `json:"cooling_set_point_fahrenheit,omitempty" url:"cooling_set_point_fahrenheit,omitempty"` + HeatingSetPointFahrenheit *float64 `json:"heating_set_point_fahrenheit,omitempty" url:"heating_set_point_fahrenheit,omitempty"` + ManualOverrideAllowed *bool `json:"manual_override_allowed,omitempty" url:"manual_override_allowed,omitempty"` } type ClimateSettingSchedulesDeleteRequest struct { - ClimateSettingScheduleId string `json:"climate_setting_schedule_id"` + ClimateSettingScheduleId string `json:"climate_setting_schedule_id" url:"climate_setting_schedule_id"` } type ClimateSettingSchedulesGetRequest struct { - ClimateSettingScheduleId *string `json:"climate_setting_schedule_id,omitempty"` - DeviceId *string `json:"device_id,omitempty"` + ClimateSettingScheduleId *string `json:"climate_setting_schedule_id,omitempty" url:"climate_setting_schedule_id,omitempty"` + DeviceId *string `json:"device_id,omitempty" url:"device_id,omitempty"` } type ClimateSettingSchedulesListRequest struct { - DeviceId string `json:"device_id"` - UserIdentifierKey *string `json:"user_identifier_key,omitempty"` + DeviceId string `json:"device_id" url:"device_id"` + UserIdentifierKey *string `json:"user_identifier_key,omitempty" url:"user_identifier_key,omitempty"` } type ClimateSettingSchedulesCreateRequestHvacModeSetting string @@ -68,8 +68,8 @@ func (c ClimateSettingSchedulesCreateRequestHvacModeSetting) Ptr() *ClimateSetti } type ClimateSettingSchedulesCreateResponse struct { - ClimateSettingSchedule *seamapigo.ClimateSettingSchedule `json:"climate_setting_schedule,omitempty"` - Ok bool `json:"ok"` + ClimateSettingSchedule *seamapigo.ClimateSettingSchedule `json:"climate_setting_schedule,omitempty" url:"climate_setting_schedule,omitempty"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -98,7 +98,7 @@ func (c *ClimateSettingSchedulesCreateResponse) String() string { } type ClimateSettingSchedulesDeleteResponse struct { - Ok bool `json:"ok"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -127,8 +127,8 @@ func (c *ClimateSettingSchedulesDeleteResponse) String() string { } type ClimateSettingSchedulesGetResponse struct { - ClimateSettingSchedule *seamapigo.ClimateSettingSchedule `json:"climate_setting_schedule,omitempty"` - Ok bool `json:"ok"` + ClimateSettingSchedule *seamapigo.ClimateSettingSchedule `json:"climate_setting_schedule,omitempty" url:"climate_setting_schedule,omitempty"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -157,8 +157,8 @@ func (c *ClimateSettingSchedulesGetResponse) String() string { } type ClimateSettingSchedulesListResponse struct { - ClimateSettingSchedules []*seamapigo.ClimateSettingSchedule `json:"climate_setting_schedules,omitempty"` - Ok bool `json:"ok"` + ClimateSettingSchedules []*seamapigo.ClimateSettingSchedule `json:"climate_setting_schedules,omitempty" url:"climate_setting_schedules,omitempty"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -215,8 +215,8 @@ func (c ClimateSettingSchedulesUpdateRequestHvacModeSetting) Ptr() *ClimateSetti } type ClimateSettingSchedulesUpdateResponse struct { - ClimateSettingSchedule *seamapigo.ClimateSettingSchedule `json:"climate_setting_schedule,omitempty"` - Ok bool `json:"ok"` + ClimateSettingSchedule *seamapigo.ClimateSettingSchedule `json:"climate_setting_schedule,omitempty" url:"climate_setting_schedule,omitempty"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -245,17 +245,17 @@ func (c *ClimateSettingSchedulesUpdateResponse) String() string { } type ClimateSettingSchedulesUpdateRequest struct { - ClimateSettingScheduleId string `json:"climate_setting_schedule_id"` - ScheduleType *string `json:"schedule_type,omitempty"` - Name *string `json:"name,omitempty"` - ScheduleStartsAt *string `json:"schedule_starts_at,omitempty"` - ScheduleEndsAt *string `json:"schedule_ends_at,omitempty"` - AutomaticHeatingEnabled *bool `json:"automatic_heating_enabled,omitempty"` - AutomaticCoolingEnabled *bool `json:"automatic_cooling_enabled,omitempty"` - HvacModeSetting *ClimateSettingSchedulesUpdateRequestHvacModeSetting `json:"hvac_mode_setting,omitempty"` - CoolingSetPointCelsius *float64 `json:"cooling_set_point_celsius,omitempty"` - HeatingSetPointCelsius *float64 `json:"heating_set_point_celsius,omitempty"` - CoolingSetPointFahrenheit *float64 `json:"cooling_set_point_fahrenheit,omitempty"` - HeatingSetPointFahrenheit *float64 `json:"heating_set_point_fahrenheit,omitempty"` - ManualOverrideAllowed *bool `json:"manual_override_allowed,omitempty"` + ClimateSettingScheduleId string `json:"climate_setting_schedule_id" url:"climate_setting_schedule_id"` + ScheduleType *string `json:"schedule_type,omitempty" url:"schedule_type,omitempty"` + Name *string `json:"name,omitempty" url:"name,omitempty"` + ScheduleStartsAt *string `json:"schedule_starts_at,omitempty" url:"schedule_starts_at,omitempty"` + ScheduleEndsAt *string `json:"schedule_ends_at,omitempty" url:"schedule_ends_at,omitempty"` + AutomaticHeatingEnabled *bool `json:"automatic_heating_enabled,omitempty" url:"automatic_heating_enabled,omitempty"` + AutomaticCoolingEnabled *bool `json:"automatic_cooling_enabled,omitempty" url:"automatic_cooling_enabled,omitempty"` + HvacModeSetting *ClimateSettingSchedulesUpdateRequestHvacModeSetting `json:"hvac_mode_setting,omitempty" url:"hvac_mode_setting,omitempty"` + CoolingSetPointCelsius *float64 `json:"cooling_set_point_celsius,omitempty" url:"cooling_set_point_celsius,omitempty"` + HeatingSetPointCelsius *float64 `json:"heating_set_point_celsius,omitempty" url:"heating_set_point_celsius,omitempty"` + CoolingSetPointFahrenheit *float64 `json:"cooling_set_point_fahrenheit,omitempty" url:"cooling_set_point_fahrenheit,omitempty"` + HeatingSetPointFahrenheit *float64 `json:"heating_set_point_fahrenheit,omitempty" url:"heating_set_point_fahrenheit,omitempty"` + ManualOverrideAllowed *bool `json:"manual_override_allowed,omitempty" url:"manual_override_allowed,omitempty"` } diff --git a/thermostats/climatesettingschedules/client.go b/thermostats/climatesettingschedules/client.go index 66733ce..7eca25f 100644 --- a/thermostats/climatesettingschedules/client.go +++ b/thermostats/climatesettingschedules/client.go @@ -9,6 +9,7 @@ import ( errors "errors" seamapigo "github.com/seamapi/go" core "github.com/seamapi/go/core" + option "github.com/seamapi/go/option" thermostats "github.com/seamapi/go/thermostats" io "io" http "net/http" @@ -20,25 +21,38 @@ type Client struct { header http.Header } -func NewClient(opts ...core.ClientOption) *Client { - options := core.NewClientOptions() - for _, opt := range opts { - opt(options) - } +func NewClient(opts ...option.RequestOption) *Client { + options := core.NewRequestOptions(opts...) return &Client{ baseURL: options.BaseURL, - caller: core.NewCaller(options.HTTPClient), - header: options.ToHeader(), + caller: core.NewCaller( + &core.CallerParams{ + Client: options.HTTPClient, + MaxAttempts: options.MaxAttempts, + }, + ), + header: options.ToHeader(), } } -func (c *Client) Create(ctx context.Context, request *thermostats.ClimateSettingSchedulesCreateRequest) (*seamapigo.ClimateSettingSchedule, error) { +func (c *Client) Create( + ctx context.Context, + request *thermostats.ClimateSettingSchedulesCreateRequest, + opts ...option.RequestOption, +) (*seamapigo.ClimateSettingSchedule, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "thermostats/climate_setting_schedules/create" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -71,7 +85,9 @@ func (c *Client) Create(ctx context.Context, request *thermostats.ClimateSetting &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -82,13 +98,24 @@ func (c *Client) Create(ctx context.Context, request *thermostats.ClimateSetting return response.ClimateSettingSchedule, nil } -func (c *Client) Delete(ctx context.Context, request *thermostats.ClimateSettingSchedulesDeleteRequest) (*thermostats.ClimateSettingSchedulesDeleteResponse, error) { +func (c *Client) Delete( + ctx context.Context, + request *thermostats.ClimateSettingSchedulesDeleteRequest, + opts ...option.RequestOption, +) (*thermostats.ClimateSettingSchedulesDeleteResponse, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "thermostats/climate_setting_schedules/delete" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -121,7 +148,9 @@ func (c *Client) Delete(ctx context.Context, request *thermostats.ClimateSetting &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -132,13 +161,24 @@ func (c *Client) Delete(ctx context.Context, request *thermostats.ClimateSetting return response, nil } -func (c *Client) Get(ctx context.Context, request *thermostats.ClimateSettingSchedulesGetRequest) (*seamapigo.ClimateSettingSchedule, error) { +func (c *Client) Get( + ctx context.Context, + request *thermostats.ClimateSettingSchedulesGetRequest, + opts ...option.RequestOption, +) (*seamapigo.ClimateSettingSchedule, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "thermostats/climate_setting_schedules/get" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -171,7 +211,9 @@ func (c *Client) Get(ctx context.Context, request *thermostats.ClimateSettingSch &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -182,13 +224,24 @@ func (c *Client) Get(ctx context.Context, request *thermostats.ClimateSettingSch return response.ClimateSettingSchedule, nil } -func (c *Client) List(ctx context.Context, request *thermostats.ClimateSettingSchedulesListRequest) ([]*seamapigo.ClimateSettingSchedule, error) { +func (c *Client) List( + ctx context.Context, + request *thermostats.ClimateSettingSchedulesListRequest, + opts ...option.RequestOption, +) ([]*seamapigo.ClimateSettingSchedule, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "thermostats/climate_setting_schedules/list" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -221,7 +274,9 @@ func (c *Client) List(ctx context.Context, request *thermostats.ClimateSettingSc &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -232,13 +287,24 @@ func (c *Client) List(ctx context.Context, request *thermostats.ClimateSettingSc return response.ClimateSettingSchedules, nil } -func (c *Client) Update(ctx context.Context, request *thermostats.ClimateSettingSchedulesUpdateRequest) (*seamapigo.ClimateSettingSchedule, error) { +func (c *Client) Update( + ctx context.Context, + request *thermostats.ClimateSettingSchedulesUpdateRequest, + opts ...option.RequestOption, +) (*seamapigo.ClimateSettingSchedule, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "thermostats/climate_setting_schedules/update" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -271,7 +337,9 @@ func (c *Client) Update(ctx context.Context, request *thermostats.ClimateSetting &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, diff --git a/types.go b/types.go index 21f001f..591f72f 100644 --- a/types.go +++ b/types.go @@ -11,60 +11,86 @@ import ( type AccessCode struct { // Unique identifier for a group of access codes that share the same code. - CommonCodeKey *string `json:"common_code_key,omitempty"` + CommonCodeKey *string `json:"common_code_key,omitempty" url:"common_code_key,omitempty"` // Indicates whether the code is set on the device according to a preconfigured schedule. - IsScheduledOnDevice *bool `json:"is_scheduled_on_device,omitempty"` + IsScheduledOnDevice *bool `json:"is_scheduled_on_device,omitempty" url:"is_scheduled_on_device,omitempty"` // Nature of the access code. Values are "ongoing" for access codes that are active continuously until deactivated manually or "time_bound" for access codes that have a specific duration. - Type AccessCodeType `json:"type,omitempty"` + Type AccessCodeType `json:"type,omitempty" url:"type,omitempty"` // Indicates whether the access code is waiting for a code assignment. - IsWaitingForCodeAssignment *bool `json:"is_waiting_for_code_assignment,omitempty"` + IsWaitingForCodeAssignment *bool `json:"is_waiting_for_code_assignment,omitempty" url:"is_waiting_for_code_assignment,omitempty"` // Unique identifier for the access code. - AccessCodeId string `json:"access_code_id"` + AccessCodeId string `json:"access_code_id" url:"access_code_id"` // Unique identifier for the device associated with the access code. - DeviceId string `json:"device_id"` + DeviceId string `json:"device_id" url:"device_id"` // Name of the access code. Enables administrators and users to identify the access code easily, especially when there are numerous access codes. - Name *string `json:"name,omitempty"` + Name *string `json:"name,omitempty" url:"name,omitempty"` // Code used for access. Typically, a numeric or alphanumeric string. - Code *string `json:"code,omitempty"` + Code *string `json:"code,omitempty" url:"code,omitempty"` // Date and time at which the access code was created. - CreatedAt time.Time `json:"created_at"` - Errors interface{} `json:"errors,omitempty"` - Warnings interface{} `json:"warnings,omitempty"` + CreatedAt time.Time `json:"created_at" url:"created_at"` + Errors interface{} `json:"errors,omitempty" url:"errors,omitempty"` + Warnings interface{} `json:"warnings,omitempty" url:"warnings,omitempty"` // Indicates whether Seam manages the access code. - IsManaged bool `json:"is_managed"` + IsManaged bool `json:"is_managed" url:"is_managed"` // Date and time at which the time-bound access code becomes active. - StartsAt *time.Time `json:"starts_at,omitempty"` + StartsAt *time.Time `json:"starts_at,omitempty" url:"starts_at,omitempty"` // Date and time after which the time-bound access code becomes inactive. - EndsAt *time.Time `json:"ends_at,omitempty"` + EndsAt *time.Time `json:"ends_at,omitempty" url:"ends_at,omitempty"` // Current status of the access code within the operational lifecycle. Values are "setting," a transitional phase that indicates that the code is being configured or activated; "set", which indicates that the code is active and operational; "unset," which indicates a deactivated or unused state, either before activation or after deliberate deactivation; "removing," which indicates a transitional period in which the code is being deleted or made inactive; and "unknown," which indicates an indeterminate state, due to reasons such as system errors or incomplete data, that highlights a potential need for system review or troubleshooting. - Status AccessCodeStatus `json:"status,omitempty"` + Status AccessCodeStatus `json:"status,omitempty" url:"status,omitempty"` // Indicates whether a backup access code is available for use if the primary access code is lost or compromised. - IsBackupAccessCodeAvailable bool `json:"is_backup_access_code_available"` + IsBackupAccessCodeAvailable bool `json:"is_backup_access_code_available" url:"is_backup_access_code_available"` // Indicates whether the access code is a backup code. - IsBackup *bool `json:"is_backup,omitempty"` + IsBackup *bool `json:"is_backup,omitempty" url:"is_backup,omitempty"` // Identifier of the pulled backup access code. Used to associate the pulled backup access code with the original access code. - PulledBackupAccessCodeId *string `json:"pulled_backup_access_code_id,omitempty"` + PulledBackupAccessCodeId *string `json:"pulled_backup_access_code_id,omitempty" url:"pulled_backup_access_code_id,omitempty"` // Indicates whether changes to the access code from external sources are permitted. - IsExternalModificationAllowed bool `json:"is_external_modification_allowed"` + IsExternalModificationAllowed bool `json:"is_external_modification_allowed" url:"is_external_modification_allowed"` // Indicates whether the access code can only be used once. If "true," the code becomes invalid after the first use. - IsOneTimeUse bool `json:"is_one_time_use"` + IsOneTimeUse bool `json:"is_one_time_use" url:"is_one_time_use"` // Indicates whether the access code is intended for use in offline scenarios. If "true," this code can be created on a device without a network connection. - IsOfflineAccessCode bool `json:"is_offline_access_code"` + IsOfflineAccessCode bool `json:"is_offline_access_code" url:"is_offline_access_code"` _rawJSON json.RawMessage } func (a *AccessCode) UnmarshalJSON(data []byte) error { - type unmarshaler AccessCode - var value unmarshaler - if err := json.Unmarshal(data, &value); err != nil { + type embed AccessCode + var unmarshaler = struct { + embed + CreatedAt *core.DateTime `json:"created_at"` + StartsAt *core.DateTime `json:"starts_at,omitempty"` + EndsAt *core.DateTime `json:"ends_at,omitempty"` + }{ + embed: embed(*a), + } + if err := json.Unmarshal(data, &unmarshaler); err != nil { return err } - *a = AccessCode(value) + *a = AccessCode(unmarshaler.embed) + a.CreatedAt = unmarshaler.CreatedAt.Time() + a.StartsAt = unmarshaler.StartsAt.TimePtr() + a.EndsAt = unmarshaler.EndsAt.TimePtr() a._rawJSON = json.RawMessage(data) return nil } +func (a *AccessCode) MarshalJSON() ([]byte, error) { + type embed AccessCode + var marshaler = struct { + embed + CreatedAt *core.DateTime `json:"created_at"` + StartsAt *core.DateTime `json:"starts_at,omitempty"` + EndsAt *core.DateTime `json:"ends_at,omitempty"` + }{ + embed: embed(*a), + CreatedAt: core.NewDateTime(a.CreatedAt), + StartsAt: core.NewOptionalDateTime(a.StartsAt), + EndsAt: core.NewOptionalDateTime(a.EndsAt), + } + return json.Marshal(marshaler) +} + func (a *AccessCode) String() string { if len(a._rawJSON) > 0 { if value, err := core.StringifyJSON(a._rawJSON); err == nil { @@ -133,32 +159,50 @@ func (a AccessCodeType) Ptr() *AccessCodeType { } type AcsAccessGroup struct { - AcsAccessGroupId string `json:"acs_access_group_id"` - AcsSystemId string `json:"acs_system_id"` - WorkspaceId string `json:"workspace_id"` - Name string `json:"name"` + AcsAccessGroupId string `json:"acs_access_group_id" url:"acs_access_group_id"` + AcsSystemId string `json:"acs_system_id" url:"acs_system_id"` + WorkspaceId string `json:"workspace_id" url:"workspace_id"` + Name string `json:"name" url:"name"` // deprecated: use external_type - AccessGroupType AcsAccessGroupAccessGroupType `json:"access_group_type,omitempty"` + AccessGroupType AcsAccessGroupAccessGroupType `json:"access_group_type,omitempty" url:"access_group_type,omitempty"` // deprecated: use external_type_display_name - AccessGroupTypeDisplayName string `json:"access_group_type_display_name"` - ExternalType AcsAccessGroupExternalType `json:"external_type,omitempty"` - ExternalTypeDisplayName string `json:"external_type_display_name"` - CreatedAt time.Time `json:"created_at"` + AccessGroupTypeDisplayName string `json:"access_group_type_display_name" url:"access_group_type_display_name"` + ExternalType AcsAccessGroupExternalType `json:"external_type,omitempty" url:"external_type,omitempty"` + ExternalTypeDisplayName string `json:"external_type_display_name" url:"external_type_display_name"` + CreatedAt time.Time `json:"created_at" url:"created_at"` _rawJSON json.RawMessage } func (a *AcsAccessGroup) UnmarshalJSON(data []byte) error { - type unmarshaler AcsAccessGroup - var value unmarshaler - if err := json.Unmarshal(data, &value); err != nil { + type embed AcsAccessGroup + var unmarshaler = struct { + embed + CreatedAt *core.DateTime `json:"created_at"` + }{ + embed: embed(*a), + } + if err := json.Unmarshal(data, &unmarshaler); err != nil { return err } - *a = AcsAccessGroup(value) + *a = AcsAccessGroup(unmarshaler.embed) + a.CreatedAt = unmarshaler.CreatedAt.Time() a._rawJSON = json.RawMessage(data) return nil } +func (a *AcsAccessGroup) MarshalJSON() ([]byte, error) { + type embed AcsAccessGroup + var marshaler = struct { + embed + CreatedAt *core.DateTime `json:"created_at"` + }{ + embed: embed(*a), + CreatedAt: core.NewDateTime(a.CreatedAt), + } + return json.Marshal(marshaler) +} + func (a *AcsAccessGroup) String() string { if len(a._rawJSON) > 0 { if value, err := core.StringifyJSON(a._rawJSON); err == nil { @@ -229,32 +273,50 @@ func (a AcsAccessGroupExternalType) Ptr() *AcsAccessGroupExternalType { } type AcsSystem struct { - AcsSystemId string `json:"acs_system_id"` - ExternalType AcsSystemExternalType `json:"external_type,omitempty"` - ExternalTypeDisplayName string `json:"external_type_display_name"` + AcsSystemId string `json:"acs_system_id" url:"acs_system_id"` + ExternalType AcsSystemExternalType `json:"external_type,omitempty" url:"external_type,omitempty"` + ExternalTypeDisplayName string `json:"external_type_display_name" url:"external_type_display_name"` // deprecated: use external_type - SystemType AcsSystemSystemType `json:"system_type,omitempty"` + SystemType AcsSystemSystemType `json:"system_type,omitempty" url:"system_type,omitempty"` // deprecated: use external_type_display_name - SystemTypeDisplayName string `json:"system_type_display_name"` - Name string `json:"name"` - CreatedAt time.Time `json:"created_at"` - WorkspaceId string `json:"workspace_id"` - ConnectedAccountIds []string `json:"connected_account_ids,omitempty"` + SystemTypeDisplayName string `json:"system_type_display_name" url:"system_type_display_name"` + Name string `json:"name" url:"name"` + CreatedAt time.Time `json:"created_at" url:"created_at"` + WorkspaceId string `json:"workspace_id" url:"workspace_id"` + ConnectedAccountIds []string `json:"connected_account_ids,omitempty" url:"connected_account_ids,omitempty"` _rawJSON json.RawMessage } func (a *AcsSystem) UnmarshalJSON(data []byte) error { - type unmarshaler AcsSystem - var value unmarshaler - if err := json.Unmarshal(data, &value); err != nil { + type embed AcsSystem + var unmarshaler = struct { + embed + CreatedAt *core.DateTime `json:"created_at"` + }{ + embed: embed(*a), + } + if err := json.Unmarshal(data, &unmarshaler); err != nil { return err } - *a = AcsSystem(value) + *a = AcsSystem(unmarshaler.embed) + a.CreatedAt = unmarshaler.CreatedAt.Time() a._rawJSON = json.RawMessage(data) return nil } +func (a *AcsSystem) MarshalJSON() ([]byte, error) { + type embed AcsSystem + var marshaler = struct { + embed + CreatedAt *core.DateTime `json:"created_at"` + }{ + embed: embed(*a), + CreatedAt: core.NewDateTime(a.CreatedAt), + } + return json.Marshal(marshaler) +} + func (a *AcsSystem) String() string { if len(a._rawJSON) > 0 { if value, err := core.StringifyJSON(a._rawJSON); err == nil { @@ -343,39 +405,57 @@ func (a AcsSystemSystemType) Ptr() *AcsSystemSystemType { } type AcsUser struct { - AcsUserId string `json:"acs_user_id"` - AcsSystemId string `json:"acs_system_id"` - HidAcsSystemId *string `json:"hid_acs_system_id,omitempty"` - WorkspaceId string `json:"workspace_id"` - CreatedAt time.Time `json:"created_at"` - DisplayName string `json:"display_name"` - ExternalType *AcsUserExternalType `json:"external_type,omitempty"` - ExternalTypeDisplayName *string `json:"external_type_display_name,omitempty"` - IsSuspended bool `json:"is_suspended"` - AccessSchedule *AcsUserAccessSchedule `json:"access_schedule,omitempty"` - UserIdentityId *string `json:"user_identity_id,omitempty"` - UserIdentityEmailAddress *string `json:"user_identity_email_address,omitempty"` - UserIdentityPhoneNumber *string `json:"user_identity_phone_number,omitempty"` - FullName *string `json:"full_name,omitempty"` + AcsUserId string `json:"acs_user_id" url:"acs_user_id"` + AcsSystemId string `json:"acs_system_id" url:"acs_system_id"` + HidAcsSystemId *string `json:"hid_acs_system_id,omitempty" url:"hid_acs_system_id,omitempty"` + WorkspaceId string `json:"workspace_id" url:"workspace_id"` + CreatedAt time.Time `json:"created_at" url:"created_at"` + DisplayName string `json:"display_name" url:"display_name"` + ExternalType *AcsUserExternalType `json:"external_type,omitempty" url:"external_type,omitempty"` + ExternalTypeDisplayName *string `json:"external_type_display_name,omitempty" url:"external_type_display_name,omitempty"` + IsSuspended bool `json:"is_suspended" url:"is_suspended"` + AccessSchedule *AcsUserAccessSchedule `json:"access_schedule,omitempty" url:"access_schedule,omitempty"` + UserIdentityId *string `json:"user_identity_id,omitempty" url:"user_identity_id,omitempty"` + UserIdentityEmailAddress *string `json:"user_identity_email_address,omitempty" url:"user_identity_email_address,omitempty"` + UserIdentityPhoneNumber *string `json:"user_identity_phone_number,omitempty" url:"user_identity_phone_number,omitempty"` + FullName *string `json:"full_name,omitempty" url:"full_name,omitempty"` // Deprecated: use email_address. - Email *string `json:"email,omitempty"` - EmailAddress *string `json:"email_address,omitempty"` - PhoneNumber *string `json:"phone_number,omitempty"` + Email *string `json:"email,omitempty" url:"email,omitempty"` + EmailAddress *string `json:"email_address,omitempty" url:"email_address,omitempty"` + PhoneNumber *string `json:"phone_number,omitempty" url:"phone_number,omitempty"` _rawJSON json.RawMessage } func (a *AcsUser) UnmarshalJSON(data []byte) error { - type unmarshaler AcsUser - var value unmarshaler - if err := json.Unmarshal(data, &value); err != nil { + type embed AcsUser + var unmarshaler = struct { + embed + CreatedAt *core.DateTime `json:"created_at"` + }{ + embed: embed(*a), + } + if err := json.Unmarshal(data, &unmarshaler); err != nil { return err } - *a = AcsUser(value) + *a = AcsUser(unmarshaler.embed) + a.CreatedAt = unmarshaler.CreatedAt.Time() a._rawJSON = json.RawMessage(data) return nil } +func (a *AcsUser) MarshalJSON() ([]byte, error) { + type embed AcsUser + var marshaler = struct { + embed + CreatedAt *core.DateTime `json:"created_at"` + }{ + embed: embed(*a), + CreatedAt: core.NewDateTime(a.CreatedAt), + } + return json.Marshal(marshaler) +} + func (a *AcsUser) String() string { if len(a._rawJSON) > 0 { if value, err := core.StringifyJSON(a._rawJSON); err == nil { @@ -389,23 +469,45 @@ func (a *AcsUser) String() string { } type AcsUserAccessSchedule struct { - StartsAt time.Time `json:"starts_at"` - EndsAt time.Time `json:"ends_at"` + StartsAt time.Time `json:"starts_at" url:"starts_at"` + EndsAt time.Time `json:"ends_at" url:"ends_at"` _rawJSON json.RawMessage } func (a *AcsUserAccessSchedule) UnmarshalJSON(data []byte) error { - type unmarshaler AcsUserAccessSchedule - var value unmarshaler - if err := json.Unmarshal(data, &value); err != nil { + type embed AcsUserAccessSchedule + var unmarshaler = struct { + embed + StartsAt *core.DateTime `json:"starts_at"` + EndsAt *core.DateTime `json:"ends_at"` + }{ + embed: embed(*a), + } + if err := json.Unmarshal(data, &unmarshaler); err != nil { return err } - *a = AcsUserAccessSchedule(value) + *a = AcsUserAccessSchedule(unmarshaler.embed) + a.StartsAt = unmarshaler.StartsAt.Time() + a.EndsAt = unmarshaler.EndsAt.Time() a._rawJSON = json.RawMessage(data) return nil } +func (a *AcsUserAccessSchedule) MarshalJSON() ([]byte, error) { + type embed AcsUserAccessSchedule + var marshaler = struct { + embed + StartsAt *core.DateTime `json:"starts_at"` + EndsAt *core.DateTime `json:"ends_at"` + }{ + embed: embed(*a), + StartsAt: core.NewDateTime(a.StartsAt), + EndsAt: core.NewDateTime(a.EndsAt), + } + return json.Marshal(marshaler) +} + func (a *AcsUserAccessSchedule) String() string { if len(a._rawJSON) > 0 { if value, err := core.StringifyJSON(a._rawJSON); err == nil { @@ -550,10 +652,10 @@ func (a *ActionAttempt) Accept(visitor ActionAttemptVisitor) error { } type ActionAttemptError struct { - ActionType string `json:"action_type"` - ActionAttemptId string `json:"action_attempt_id"` - Result *string `json:"result,omitempty"` - Error *ActionAttemptErrorError `json:"error,omitempty"` + ActionType string `json:"action_type" url:"action_type"` + ActionAttemptId string `json:"action_attempt_id" url:"action_attempt_id"` + Result *string `json:"result,omitempty" url:"result,omitempty"` + Error *ActionAttemptErrorError `json:"error,omitempty" url:"error,omitempty"` _rawJSON json.RawMessage } @@ -582,8 +684,8 @@ func (a *ActionAttemptError) String() string { } type ActionAttemptErrorError struct { - Type string `json:"type"` - Message string `json:"message"` + Type string `json:"type" url:"type"` + Message string `json:"message" url:"message"` _rawJSON json.RawMessage } @@ -612,10 +714,10 @@ func (a *ActionAttemptErrorError) String() string { } type ActionAttemptPending struct { - ActionType string `json:"action_type"` - ActionAttemptId string `json:"action_attempt_id"` - Result *string `json:"result,omitempty"` - Error *string `json:"error,omitempty"` + ActionType string `json:"action_type" url:"action_type"` + ActionAttemptId string `json:"action_attempt_id" url:"action_attempt_id"` + Result *string `json:"result,omitempty" url:"result,omitempty"` + Error *string `json:"error,omitempty" url:"error,omitempty"` _rawJSON json.RawMessage } @@ -644,10 +746,10 @@ func (a *ActionAttemptPending) String() string { } type ActionAttemptSuccess struct { - ActionType string `json:"action_type"` - ActionAttemptId string `json:"action_attempt_id"` - Result interface{} `json:"result,omitempty"` - Error *string `json:"error,omitempty"` + ActionType string `json:"action_type" url:"action_type"` + ActionAttemptId string `json:"action_attempt_id" url:"action_attempt_id"` + Result interface{} `json:"result,omitempty" url:"result,omitempty"` + Error *string `json:"error,omitempty" url:"error,omitempty"` _rawJSON json.RawMessage } @@ -676,30 +778,48 @@ func (a *ActionAttemptSuccess) String() string { } type ClientSession struct { - ClientSessionId string `json:"client_session_id"` - UserIdentifierKey *string `json:"user_identifier_key,omitempty"` - CreatedAt time.Time `json:"created_at"` - Token string `json:"token"` - DeviceCount float64 `json:"device_count"` - ConnectedAccountIds []string `json:"connected_account_ids,omitempty"` - ConnectWebviewIds []string `json:"connect_webview_ids,omitempty"` - UserIdentityIds []string `json:"user_identity_ids,omitempty"` - WorkspaceId string `json:"workspace_id"` + ClientSessionId string `json:"client_session_id" url:"client_session_id"` + UserIdentifierKey *string `json:"user_identifier_key,omitempty" url:"user_identifier_key,omitempty"` + CreatedAt time.Time `json:"created_at" url:"created_at"` + Token string `json:"token" url:"token"` + DeviceCount float64 `json:"device_count" url:"device_count"` + ConnectedAccountIds []string `json:"connected_account_ids,omitempty" url:"connected_account_ids,omitempty"` + ConnectWebviewIds []string `json:"connect_webview_ids,omitempty" url:"connect_webview_ids,omitempty"` + UserIdentityIds []string `json:"user_identity_ids,omitempty" url:"user_identity_ids,omitempty"` + WorkspaceId string `json:"workspace_id" url:"workspace_id"` _rawJSON json.RawMessage } func (c *ClientSession) UnmarshalJSON(data []byte) error { - type unmarshaler ClientSession - var value unmarshaler - if err := json.Unmarshal(data, &value); err != nil { + type embed ClientSession + var unmarshaler = struct { + embed + CreatedAt *core.DateTime `json:"created_at"` + }{ + embed: embed(*c), + } + if err := json.Unmarshal(data, &unmarshaler); err != nil { return err } - *c = ClientSession(value) + *c = ClientSession(unmarshaler.embed) + c.CreatedAt = unmarshaler.CreatedAt.Time() c._rawJSON = json.RawMessage(data) return nil } +func (c *ClientSession) MarshalJSON() ([]byte, error) { + type embed ClientSession + var marshaler = struct { + embed + CreatedAt *core.DateTime `json:"created_at"` + }{ + embed: embed(*c), + CreatedAt: core.NewDateTime(c.CreatedAt), + } + return json.Marshal(marshaler) +} + func (c *ClientSession) String() string { if len(c._rawJSON) > 0 { if value, err := core.StringifyJSON(c._rawJSON); err == nil { @@ -713,21 +833,21 @@ func (c *ClientSession) String() string { } type ClimateSettingSchedule struct { - ClimateSettingScheduleId string `json:"climate_setting_schedule_id"` - DeviceId string `json:"device_id"` - Name *string `json:"name,omitempty"` - ScheduleStartsAt string `json:"schedule_starts_at"` - ScheduleEndsAt string `json:"schedule_ends_at"` - CreatedAt time.Time `json:"created_at"` - Errors interface{} `json:"errors,omitempty"` - AutomaticHeatingEnabled *bool `json:"automatic_heating_enabled,omitempty"` - AutomaticCoolingEnabled *bool `json:"automatic_cooling_enabled,omitempty"` - HvacModeSetting *ClimateSettingScheduleHvacModeSetting `json:"hvac_mode_setting,omitempty"` - CoolingSetPointCelsius *float64 `json:"cooling_set_point_celsius,omitempty"` - HeatingSetPointCelsius *float64 `json:"heating_set_point_celsius,omitempty"` - CoolingSetPointFahrenheit *float64 `json:"cooling_set_point_fahrenheit,omitempty"` - HeatingSetPointFahrenheit *float64 `json:"heating_set_point_fahrenheit,omitempty"` - ManualOverrideAllowed *bool `json:"manual_override_allowed,omitempty"` + ClimateSettingScheduleId string `json:"climate_setting_schedule_id" url:"climate_setting_schedule_id"` + DeviceId string `json:"device_id" url:"device_id"` + Name *string `json:"name,omitempty" url:"name,omitempty"` + ScheduleStartsAt string `json:"schedule_starts_at" url:"schedule_starts_at"` + ScheduleEndsAt string `json:"schedule_ends_at" url:"schedule_ends_at"` + CreatedAt time.Time `json:"created_at" url:"created_at"` + Errors interface{} `json:"errors,omitempty" url:"errors,omitempty"` + AutomaticHeatingEnabled *bool `json:"automatic_heating_enabled,omitempty" url:"automatic_heating_enabled,omitempty"` + AutomaticCoolingEnabled *bool `json:"automatic_cooling_enabled,omitempty" url:"automatic_cooling_enabled,omitempty"` + HvacModeSetting *ClimateSettingScheduleHvacModeSetting `json:"hvac_mode_setting,omitempty" url:"hvac_mode_setting,omitempty"` + CoolingSetPointCelsius *float64 `json:"cooling_set_point_celsius,omitempty" url:"cooling_set_point_celsius,omitempty"` + HeatingSetPointCelsius *float64 `json:"heating_set_point_celsius,omitempty" url:"heating_set_point_celsius,omitempty"` + CoolingSetPointFahrenheit *float64 `json:"cooling_set_point_fahrenheit,omitempty" url:"cooling_set_point_fahrenheit,omitempty"` + HeatingSetPointFahrenheit *float64 `json:"heating_set_point_fahrenheit,omitempty" url:"heating_set_point_fahrenheit,omitempty"` + ManualOverrideAllowed *bool `json:"manual_override_allowed,omitempty" url:"manual_override_allowed,omitempty"` scheduleType string _rawJSON json.RawMessage @@ -738,12 +858,18 @@ func (c *ClimateSettingSchedule) ScheduleType() string { } func (c *ClimateSettingSchedule) UnmarshalJSON(data []byte) error { - type unmarshaler ClimateSettingSchedule - var value unmarshaler - if err := json.Unmarshal(data, &value); err != nil { + type embed ClimateSettingSchedule + var unmarshaler = struct { + embed + CreatedAt *core.DateTime `json:"created_at"` + }{ + embed: embed(*c), + } + if err := json.Unmarshal(data, &unmarshaler); err != nil { return err } - *c = ClimateSettingSchedule(value) + *c = ClimateSettingSchedule(unmarshaler.embed) + c.CreatedAt = unmarshaler.CreatedAt.Time() c.scheduleType = "time_bound" c._rawJSON = json.RawMessage(data) return nil @@ -753,9 +879,11 @@ func (c *ClimateSettingSchedule) MarshalJSON() ([]byte, error) { type embed ClimateSettingSchedule var marshaler = struct { embed - ScheduleType string `json:"schedule_type"` + CreatedAt *core.DateTime `json:"created_at"` + ScheduleType string `json:"schedule_type"` }{ embed: embed(*c), + CreatedAt: core.NewDateTime(c.CreatedAt), ScheduleType: "time_bound", } return json.Marshal(marshaler) @@ -802,40 +930,62 @@ func (c ClimateSettingScheduleHvacModeSetting) Ptr() *ClimateSettingScheduleHvac } type ConnectWebview struct { - ConnectWebviewId string `json:"connect_webview_id"` - ConnectedAccountId *string `json:"connected_account_id,omitempty"` - Url string `json:"url"` - WorkspaceId string `json:"workspace_id"` - DeviceSelectionMode SelectionMode `json:"device_selection_mode,omitempty"` - AcceptedProviders []string `json:"accepted_providers,omitempty"` - AcceptedDevices []string `json:"accepted_devices,omitempty"` - AnyProviderAllowed bool `json:"any_provider_allowed"` - AnyDeviceAllowed bool `json:"any_device_allowed"` - CreatedAt time.Time `json:"created_at"` - LoginSuccessful bool `json:"login_successful"` - Status ConnectWebviewStatus `json:"status,omitempty"` - CustomRedirectUrl *string `json:"custom_redirect_url,omitempty"` - CustomRedirectFailureUrl *string `json:"custom_redirect_failure_url,omitempty"` - CustomMetadata map[string]*ConnectWebviewCustomMetadataValue `json:"custom_metadata,omitempty"` - AutomaticallyManageNewDevices bool `json:"automatically_manage_new_devices"` - WaitForDeviceCreation bool `json:"wait_for_device_creation"` - AuthorizedAt *time.Time `json:"authorized_at,omitempty"` - SelectedProvider *string `json:"selected_provider,omitempty"` + ConnectWebviewId string `json:"connect_webview_id" url:"connect_webview_id"` + ConnectedAccountId *string `json:"connected_account_id,omitempty" url:"connected_account_id,omitempty"` + Url string `json:"url" url:"url"` + WorkspaceId string `json:"workspace_id" url:"workspace_id"` + DeviceSelectionMode SelectionMode `json:"device_selection_mode,omitempty" url:"device_selection_mode,omitempty"` + AcceptedProviders []string `json:"accepted_providers,omitempty" url:"accepted_providers,omitempty"` + AcceptedDevices []string `json:"accepted_devices,omitempty" url:"accepted_devices,omitempty"` + AnyProviderAllowed bool `json:"any_provider_allowed" url:"any_provider_allowed"` + AnyDeviceAllowed bool `json:"any_device_allowed" url:"any_device_allowed"` + CreatedAt time.Time `json:"created_at" url:"created_at"` + LoginSuccessful bool `json:"login_successful" url:"login_successful"` + Status ConnectWebviewStatus `json:"status,omitempty" url:"status,omitempty"` + CustomRedirectUrl *string `json:"custom_redirect_url,omitempty" url:"custom_redirect_url,omitempty"` + CustomRedirectFailureUrl *string `json:"custom_redirect_failure_url,omitempty" url:"custom_redirect_failure_url,omitempty"` + CustomMetadata map[string]*ConnectWebviewCustomMetadataValue `json:"custom_metadata,omitempty" url:"custom_metadata,omitempty"` + AutomaticallyManageNewDevices bool `json:"automatically_manage_new_devices" url:"automatically_manage_new_devices"` + WaitForDeviceCreation bool `json:"wait_for_device_creation" url:"wait_for_device_creation"` + AuthorizedAt *time.Time `json:"authorized_at,omitempty" url:"authorized_at,omitempty"` + SelectedProvider *string `json:"selected_provider,omitempty" url:"selected_provider,omitempty"` _rawJSON json.RawMessage } func (c *ConnectWebview) UnmarshalJSON(data []byte) error { - type unmarshaler ConnectWebview - var value unmarshaler - if err := json.Unmarshal(data, &value); err != nil { + type embed ConnectWebview + var unmarshaler = struct { + embed + CreatedAt *core.DateTime `json:"created_at"` + AuthorizedAt *core.DateTime `json:"authorized_at,omitempty"` + }{ + embed: embed(*c), + } + if err := json.Unmarshal(data, &unmarshaler); err != nil { return err } - *c = ConnectWebview(value) + *c = ConnectWebview(unmarshaler.embed) + c.CreatedAt = unmarshaler.CreatedAt.Time() + c.AuthorizedAt = unmarshaler.AuthorizedAt.TimePtr() c._rawJSON = json.RawMessage(data) return nil } +func (c *ConnectWebview) MarshalJSON() ([]byte, error) { + type embed ConnectWebview + var marshaler = struct { + embed + CreatedAt *core.DateTime `json:"created_at"` + AuthorizedAt *core.DateTime `json:"authorized_at,omitempty"` + }{ + embed: embed(*c), + CreatedAt: core.NewDateTime(c.CreatedAt), + AuthorizedAt: core.NewOptionalDateTime(c.AuthorizedAt), + } + return json.Marshal(marshaler) +} + func (c *ConnectWebview) String() string { if len(c._rawJSON) > 0 { if value, err := core.StringifyJSON(c._rawJSON); err == nil { @@ -947,30 +1097,48 @@ func (c ConnectWebviewStatus) Ptr() *ConnectWebviewStatus { } type ConnectedAccount struct { - ConnectedAccountId *string `json:"connected_account_id,omitempty"` - CreatedAt *time.Time `json:"created_at,omitempty"` - UserIdentifier *ConnectedAccountUserIdentifier `json:"user_identifier,omitempty"` - AccountType *string `json:"account_type,omitempty"` - AccountTypeDisplayName string `json:"account_type_display_name"` - Errors interface{} `json:"errors,omitempty"` - Warnings interface{} `json:"warnings,omitempty"` - CustomMetadata map[string]*ConnectedAccountCustomMetadataValue `json:"custom_metadata,omitempty"` - AutomaticallyManageNewDevices bool `json:"automatically_manage_new_devices"` + ConnectedAccountId *string `json:"connected_account_id,omitempty" url:"connected_account_id,omitempty"` + CreatedAt *time.Time `json:"created_at,omitempty" url:"created_at,omitempty"` + UserIdentifier *ConnectedAccountUserIdentifier `json:"user_identifier,omitempty" url:"user_identifier,omitempty"` + AccountType *string `json:"account_type,omitempty" url:"account_type,omitempty"` + AccountTypeDisplayName string `json:"account_type_display_name" url:"account_type_display_name"` + Errors interface{} `json:"errors,omitempty" url:"errors,omitempty"` + Warnings interface{} `json:"warnings,omitempty" url:"warnings,omitempty"` + CustomMetadata map[string]*ConnectedAccountCustomMetadataValue `json:"custom_metadata,omitempty" url:"custom_metadata,omitempty"` + AutomaticallyManageNewDevices bool `json:"automatically_manage_new_devices" url:"automatically_manage_new_devices"` _rawJSON json.RawMessage } func (c *ConnectedAccount) UnmarshalJSON(data []byte) error { - type unmarshaler ConnectedAccount - var value unmarshaler - if err := json.Unmarshal(data, &value); err != nil { + type embed ConnectedAccount + var unmarshaler = struct { + embed + CreatedAt *core.DateTime `json:"created_at,omitempty"` + }{ + embed: embed(*c), + } + if err := json.Unmarshal(data, &unmarshaler); err != nil { return err } - *c = ConnectedAccount(value) + *c = ConnectedAccount(unmarshaler.embed) + c.CreatedAt = unmarshaler.CreatedAt.TimePtr() c._rawJSON = json.RawMessage(data) return nil } +func (c *ConnectedAccount) MarshalJSON() ([]byte, error) { + type embed ConnectedAccount + var marshaler = struct { + embed + CreatedAt *core.DateTime `json:"created_at,omitempty"` + }{ + embed: embed(*c), + CreatedAt: core.NewOptionalDateTime(c.CreatedAt), + } + return json.Marshal(marshaler) +} + func (c *ConnectedAccount) String() string { if len(c._rawJSON) > 0 { if value, err := core.StringifyJSON(c._rawJSON); err == nil { @@ -1057,11 +1225,11 @@ func (c *ConnectedAccountCustomMetadataValue) Accept(visitor ConnectedAccountCus } type ConnectedAccountUserIdentifier struct { - Username *string `json:"username,omitempty"` - ApiUrl *string `json:"api_url,omitempty"` - Email *string `json:"email,omitempty"` - Phone *string `json:"phone,omitempty"` - Exclusive *bool `json:"exclusive,omitempty"` + Username *string `json:"username,omitempty" url:"username,omitempty"` + ApiUrl *string `json:"api_url,omitempty" url:"api_url,omitempty"` + Email *string `json:"email,omitempty" url:"email,omitempty"` + Phone *string `json:"phone,omitempty" url:"phone,omitempty"` + Exclusive *bool `json:"exclusive,omitempty" url:"exclusive,omitempty"` _rawJSON json.RawMessage } @@ -1091,45 +1259,63 @@ func (c *ConnectedAccountUserIdentifier) String() string { type Device struct { // Unique identifier for the device. - DeviceId string `json:"device_id"` + DeviceId string `json:"device_id" url:"device_id"` // Type of the device. - DeviceType DeviceType `json:"device_type,omitempty"` + DeviceType DeviceType `json:"device_type,omitempty" url:"device_type,omitempty"` // Collection of capabilities that the device supports when connected to Seam. Values are "access_code," which indicates that the device can manage and utilize digital PIN codes for secure access; "lock," which indicates that the device controls a door locking mechanism, enabling the remote opening and closing of doors and other entry points; "noise_detection," which indicates that the device supports monitoring and responding to ambient noise levels; "thermostat," which indicates that the device can regulate and adjust indoor temperatures; and "battery," which indicates that the device can manage battery life and health. - CapabilitiesSupported []DeviceCapabilitiesSupportedItem `json:"capabilities_supported,omitempty"` + CapabilitiesSupported []DeviceCapabilitiesSupportedItem `json:"capabilities_supported,omitempty" url:"capabilities_supported,omitempty"` // Properties of the device. - Properties *DeviceProperties `json:"properties,omitempty"` + Properties *DeviceProperties `json:"properties,omitempty" url:"properties,omitempty"` // Location information for the device. - Location *DeviceLocation `json:"location,omitempty"` + Location *DeviceLocation `json:"location,omitempty" url:"location,omitempty"` // Unique identifier for the account associated with the device. - ConnectedAccountId string `json:"connected_account_id"` + ConnectedAccountId string `json:"connected_account_id" url:"connected_account_id"` // Unique identifier for the Seam workspace associated with the device. - WorkspaceId string `json:"workspace_id"` + WorkspaceId string `json:"workspace_id" url:"workspace_id"` // Array of errors associated with the device. Each error object within the array contains two fields: "error_code" and "message." "error_code" is a string that uniquely identifies the type of error, enabling quick recognition and categorization of the issue. "message" provides a more detailed description of the error, offering insights into the issue and potentially how to rectify it. - Errors []*DeviceErrorsItem `json:"errors,omitempty"` + Errors []*DeviceErrorsItem `json:"errors,omitempty" url:"errors,omitempty"` // Array of warnings associated with the device. Each warning object within the array contains two fields: "warning_code" and "message." "warning_code" is a string that uniquely identifies the type of warning, enabling quick recognition and categorization of the issue. "message" provides a more detailed description of the warning, offering insights into the issue and potentially how to rectify it. - Warnings []*DeviceWarningsItem `json:"warnings,omitempty"` + Warnings []*DeviceWarningsItem `json:"warnings,omitempty" url:"warnings,omitempty"` // Date and time at which the device object was created. - CreatedAt time.Time `json:"created_at"` + CreatedAt time.Time `json:"created_at" url:"created_at"` // Indicates whether Seam manages the device. - IsManaged bool `json:"is_managed"` - CustomMetadata map[string]*DeviceCustomMetadataValue `json:"custom_metadata,omitempty"` - CanRemotelyUnlock *bool `json:"can_remotely_unlock,omitempty"` - CanProgramOnlineAccessCodes *bool `json:"can_program_online_access_codes,omitempty"` + IsManaged bool `json:"is_managed" url:"is_managed"` + CustomMetadata map[string]*DeviceCustomMetadataValue `json:"custom_metadata,omitempty" url:"custom_metadata,omitempty"` + CanRemotelyUnlock *bool `json:"can_remotely_unlock,omitempty" url:"can_remotely_unlock,omitempty"` + CanProgramOnlineAccessCodes *bool `json:"can_program_online_access_codes,omitempty" url:"can_program_online_access_codes,omitempty"` _rawJSON json.RawMessage } func (d *Device) UnmarshalJSON(data []byte) error { - type unmarshaler Device - var value unmarshaler - if err := json.Unmarshal(data, &value); err != nil { + type embed Device + var unmarshaler = struct { + embed + CreatedAt *core.DateTime `json:"created_at"` + }{ + embed: embed(*d), + } + if err := json.Unmarshal(data, &unmarshaler); err != nil { return err } - *d = Device(value) + *d = Device(unmarshaler.embed) + d.CreatedAt = unmarshaler.CreatedAt.Time() d._rawJSON = json.RawMessage(data) return nil } +func (d *Device) MarshalJSON() ([]byte, error) { + type embed Device + var marshaler = struct { + embed + CreatedAt *core.DateTime `json:"created_at"` + }{ + embed: embed(*d), + CreatedAt: core.NewDateTime(d.CreatedAt), + } + return json.Marshal(marshaler) +} + func (d *Device) String() string { if len(d._rawJSON) > 0 { if value, err := core.StringifyJSON(d._rawJSON); err == nil { @@ -1250,8 +1436,8 @@ func (d *DeviceCustomMetadataValue) Accept(visitor DeviceCustomMetadataValueVisi } type DeviceErrorsItem struct { - ErrorCode string `json:"error_code"` - Message string `json:"message"` + ErrorCode string `json:"error_code" url:"error_code"` + Message string `json:"message" url:"message"` _rawJSON json.RawMessage } @@ -1282,9 +1468,9 @@ func (d *DeviceErrorsItem) String() string { // Location information for the device. type DeviceLocation struct { // Name of the device location. - LocationName *string `json:"location_name,omitempty"` + LocationName *string `json:"location_name,omitempty" url:"location_name,omitempty"` // Time zone of the device location. - Timezone *string `json:"timezone,omitempty"` + Timezone *string `json:"timezone,omitempty" url:"timezone,omitempty"` _rawJSON json.RawMessage } @@ -1315,68 +1501,68 @@ func (d *DeviceLocation) String() string { // Properties of the device. type DeviceProperties struct { // Indicates whether the device is online. - Online bool `json:"online"` + Online bool `json:"online" url:"online"` // Name of the device. Enables administrators and users to identify the device easily, especially when there are numerous devices. - Name string `json:"name"` - Model *DevicePropertiesModel `json:"model,omitempty"` + Name string `json:"name" url:"name"` + Model *DevicePropertiesModel `json:"model,omitempty" url:"model,omitempty"` // Indicates whether the device has direct power. - HasDirectPower *bool `json:"has_direct_power,omitempty"` + HasDirectPower *bool `json:"has_direct_power,omitempty" url:"has_direct_power,omitempty"` // Indicates the battery level of the device as a decimal value between 0 and 1, inclusive. - BatteryLevel *float64 `json:"battery_level,omitempty"` + BatteryLevel *float64 `json:"battery_level,omitempty" url:"battery_level,omitempty"` // Represents the current status of the battery charge level. Values are "critical," which indicates an extremely low level, suggesting imminent shutdown or an urgent need for charging; "low," which signifies that the battery is under the preferred threshold and should be charged soon; "good," which denotes a satisfactory charge level, adequate for normal use without the immediate need for recharging; and "full," which represents a battery that is fully charged, providing the maximum duration of usage. - Battery *DevicePropertiesBattery `json:"battery,omitempty"` + Battery *DevicePropertiesBattery `json:"battery,omitempty" url:"battery,omitempty"` // Manufacturer of the device. - Manufacturer *string `json:"manufacturer,omitempty"` + Manufacturer *string `json:"manufacturer,omitempty" url:"manufacturer,omitempty"` // Image URL for the device. - ImageUrl *string `json:"image_url,omitempty"` + ImageUrl *string `json:"image_url,omitempty" url:"image_url,omitempty"` // Alt text for the device image. - ImageAltText *string `json:"image_alt_text,omitempty"` + ImageAltText *string `json:"image_alt_text,omitempty" url:"image_alt_text,omitempty"` // Serial number of the device. - SerialNumber *string `json:"serial_number,omitempty"` + SerialNumber *string `json:"serial_number,omitempty" url:"serial_number,omitempty"` // Indicates whether it is currently possible to use online access codes for the device. - OnlineAccessCodesEnabled *bool `json:"online_access_codes_enabled,omitempty"` + OnlineAccessCodesEnabled *bool `json:"online_access_codes_enabled,omitempty" url:"online_access_codes_enabled,omitempty"` // Indicates whether it is currently possible to use offline access codes for the device. - OfflineAccessCodesEnabled *bool `json:"offline_access_codes_enabled,omitempty"` + OfflineAccessCodesEnabled *bool `json:"offline_access_codes_enabled,omitempty" url:"offline_access_codes_enabled,omitempty"` // Deprecated. Use model.accessory_keypad_supported. - SupportsAccessoryKeypad *bool `json:"supports_accessory_keypad,omitempty"` + SupportsAccessoryKeypad *bool `json:"supports_accessory_keypad,omitempty" url:"supports_accessory_keypad,omitempty"` // Deprecated. Use offline_access_codes_enabled. - SupportsOfflineAccessCodes *bool `json:"supports_offline_access_codes,omitempty"` - AssaAbloyCredentialServiceMetadata *DevicePropertiesAssaAbloyCredentialServiceMetadata `json:"assa_abloy_credential_service_metadata,omitempty"` - AugustMetadata *DevicePropertiesAugustMetadata `json:"august_metadata,omitempty"` - AvigilonAltaMetadata *DevicePropertiesAvigilonAltaMetadata `json:"avigilon_alta_metadata,omitempty"` - SchlageMetadata *DevicePropertiesSchlageMetadata `json:"schlage_metadata,omitempty"` - SmartthingsMetadata *DevicePropertiesSmartthingsMetadata `json:"smartthings_metadata,omitempty"` - LocklyMetadata *DevicePropertiesLocklyMetadata `json:"lockly_metadata,omitempty"` - NukiMetadata *DevicePropertiesNukiMetadata `json:"nuki_metadata,omitempty"` - KwiksetMetadata *DevicePropertiesKwiksetMetadata `json:"kwikset_metadata,omitempty"` - SaltoMetadata *DevicePropertiesSaltoMetadata `json:"salto_metadata,omitempty"` - GenieMetadata *DevicePropertiesGenieMetadata `json:"genie_metadata,omitempty"` - BrivoMetadata *DevicePropertiesBrivoMetadata `json:"brivo_metadata,omitempty"` - IglooMetadata *DevicePropertiesIglooMetadata `json:"igloo_metadata,omitempty"` - NoiseawareMetadata *DevicePropertiesNoiseawareMetadata `json:"noiseaware_metadata,omitempty"` - MinutMetadata *DevicePropertiesMinutMetadata `json:"minut_metadata,omitempty"` - FourSuitesMetadata *DevicePropertiesFourSuitesMetadata `json:"four_suites_metadata,omitempty"` - TwoNMetadata *DevicePropertiesTwoNMetadata `json:"two_n_metadata,omitempty"` - ControlbywebMetadata *DevicePropertiesControlbywebMetadata `json:"controlbyweb_metadata,omitempty"` - TtlockMetadata *DevicePropertiesTtlockMetadata `json:"ttlock_metadata,omitempty"` - SeamBridgeMetadata *DevicePropertiesSeamBridgeMetadata `json:"seam_bridge_metadata,omitempty"` - IgloohomeMetadata *DevicePropertiesIgloohomeMetadata `json:"igloohome_metadata,omitempty"` - NestMetadata *DevicePropertiesNestMetadata `json:"nest_metadata,omitempty"` - EcobeeMetadata *DevicePropertiesEcobeeMetadata `json:"ecobee_metadata,omitempty"` - HoneywellMetadata *DevicePropertiesHoneywellMetadata `json:"honeywell_metadata,omitempty"` - HubitatMetadata *DevicePropertiesHubitatMetadata `json:"hubitat_metadata,omitempty"` - DormakabaOracodeMetadata *DevicePropertiesDormakabaOracodeMetadata `json:"dormakaba_oracode_metadata,omitempty"` - WyzeMetadata *DevicePropertiesWyzeMetadata `json:"wyze_metadata,omitempty"` - TedeeMetadata *DevicePropertiesTedeeMetadata `json:"tedee_metadata,omitempty"` - ExperimentalSupportedCodeFromAccessCodesLengths []float64 `json:"_experimental_supported_code_from_access_codes_lengths,omitempty"` - CodeConstraints []*DevicePropertiesCodeConstraintsItem `json:"code_constraints,omitempty"` - SupportedCodeLengths []float64 `json:"supported_code_lengths,omitempty"` - MaxActiveCodesSupported *float64 `json:"max_active_codes_supported,omitempty"` - SupportsBackupAccessCodePool *bool `json:"supports_backup_access_code_pool,omitempty"` - HasNativeEntryEvents *bool `json:"has_native_entry_events,omitempty"` - Locked *bool `json:"locked,omitempty"` - KeypadBattery *DevicePropertiesKeypadBattery `json:"keypad_battery,omitempty"` - DoorOpen *bool `json:"door_open,omitempty"` + SupportsOfflineAccessCodes *bool `json:"supports_offline_access_codes,omitempty" url:"supports_offline_access_codes,omitempty"` + AssaAbloyCredentialServiceMetadata *DevicePropertiesAssaAbloyCredentialServiceMetadata `json:"assa_abloy_credential_service_metadata,omitempty" url:"assa_abloy_credential_service_metadata,omitempty"` + AugustMetadata *DevicePropertiesAugustMetadata `json:"august_metadata,omitempty" url:"august_metadata,omitempty"` + AvigilonAltaMetadata *DevicePropertiesAvigilonAltaMetadata `json:"avigilon_alta_metadata,omitempty" url:"avigilon_alta_metadata,omitempty"` + SchlageMetadata *DevicePropertiesSchlageMetadata `json:"schlage_metadata,omitempty" url:"schlage_metadata,omitempty"` + SmartthingsMetadata *DevicePropertiesSmartthingsMetadata `json:"smartthings_metadata,omitempty" url:"smartthings_metadata,omitempty"` + LocklyMetadata *DevicePropertiesLocklyMetadata `json:"lockly_metadata,omitempty" url:"lockly_metadata,omitempty"` + NukiMetadata *DevicePropertiesNukiMetadata `json:"nuki_metadata,omitempty" url:"nuki_metadata,omitempty"` + KwiksetMetadata *DevicePropertiesKwiksetMetadata `json:"kwikset_metadata,omitempty" url:"kwikset_metadata,omitempty"` + SaltoMetadata *DevicePropertiesSaltoMetadata `json:"salto_metadata,omitempty" url:"salto_metadata,omitempty"` + GenieMetadata *DevicePropertiesGenieMetadata `json:"genie_metadata,omitempty" url:"genie_metadata,omitempty"` + BrivoMetadata *DevicePropertiesBrivoMetadata `json:"brivo_metadata,omitempty" url:"brivo_metadata,omitempty"` + IglooMetadata *DevicePropertiesIglooMetadata `json:"igloo_metadata,omitempty" url:"igloo_metadata,omitempty"` + NoiseawareMetadata *DevicePropertiesNoiseawareMetadata `json:"noiseaware_metadata,omitempty" url:"noiseaware_metadata,omitempty"` + MinutMetadata *DevicePropertiesMinutMetadata `json:"minut_metadata,omitempty" url:"minut_metadata,omitempty"` + FourSuitesMetadata *DevicePropertiesFourSuitesMetadata `json:"four_suites_metadata,omitempty" url:"four_suites_metadata,omitempty"` + TwoNMetadata *DevicePropertiesTwoNMetadata `json:"two_n_metadata,omitempty" url:"two_n_metadata,omitempty"` + ControlbywebMetadata *DevicePropertiesControlbywebMetadata `json:"controlbyweb_metadata,omitempty" url:"controlbyweb_metadata,omitempty"` + TtlockMetadata *DevicePropertiesTtlockMetadata `json:"ttlock_metadata,omitempty" url:"ttlock_metadata,omitempty"` + SeamBridgeMetadata *DevicePropertiesSeamBridgeMetadata `json:"seam_bridge_metadata,omitempty" url:"seam_bridge_metadata,omitempty"` + IgloohomeMetadata *DevicePropertiesIgloohomeMetadata `json:"igloohome_metadata,omitempty" url:"igloohome_metadata,omitempty"` + NestMetadata *DevicePropertiesNestMetadata `json:"nest_metadata,omitempty" url:"nest_metadata,omitempty"` + EcobeeMetadata *DevicePropertiesEcobeeMetadata `json:"ecobee_metadata,omitempty" url:"ecobee_metadata,omitempty"` + HoneywellMetadata *DevicePropertiesHoneywellMetadata `json:"honeywell_metadata,omitempty" url:"honeywell_metadata,omitempty"` + HubitatMetadata *DevicePropertiesHubitatMetadata `json:"hubitat_metadata,omitempty" url:"hubitat_metadata,omitempty"` + DormakabaOracodeMetadata *DevicePropertiesDormakabaOracodeMetadata `json:"dormakaba_oracode_metadata,omitempty" url:"dormakaba_oracode_metadata,omitempty"` + WyzeMetadata *DevicePropertiesWyzeMetadata `json:"wyze_metadata,omitempty" url:"wyze_metadata,omitempty"` + TedeeMetadata *DevicePropertiesTedeeMetadata `json:"tedee_metadata,omitempty" url:"tedee_metadata,omitempty"` + ExperimentalSupportedCodeFromAccessCodesLengths []float64 `json:"_experimental_supported_code_from_access_codes_lengths,omitempty" url:"_experimental_supported_code_from_access_codes_lengths,omitempty"` + CodeConstraints []*DevicePropertiesCodeConstraintsItem `json:"code_constraints,omitempty" url:"code_constraints,omitempty"` + SupportedCodeLengths []float64 `json:"supported_code_lengths,omitempty" url:"supported_code_lengths,omitempty"` + MaxActiveCodesSupported *float64 `json:"max_active_codes_supported,omitempty" url:"max_active_codes_supported,omitempty"` + SupportsBackupAccessCodePool *bool `json:"supports_backup_access_code_pool,omitempty" url:"supports_backup_access_code_pool,omitempty"` + HasNativeEntryEvents *bool `json:"has_native_entry_events,omitempty" url:"has_native_entry_events,omitempty"` + Locked *bool `json:"locked,omitempty" url:"locked,omitempty"` + KeypadBattery *DevicePropertiesKeypadBattery `json:"keypad_battery,omitempty" url:"keypad_battery,omitempty"` + DoorOpen *bool `json:"door_open,omitempty" url:"door_open,omitempty"` _rawJSON json.RawMessage } @@ -1405,8 +1591,8 @@ func (d *DeviceProperties) String() string { } type DevicePropertiesAssaAbloyCredentialServiceMetadata struct { - HasActiveEndpoint bool `json:"has_active_endpoint"` - Endpoints []*DevicePropertiesAssaAbloyCredentialServiceMetadataEndpointsItem `json:"endpoints,omitempty"` + HasActiveEndpoint bool `json:"has_active_endpoint" url:"has_active_endpoint"` + Endpoints []*DevicePropertiesAssaAbloyCredentialServiceMetadataEndpointsItem `json:"endpoints,omitempty" url:"endpoints,omitempty"` _rawJSON json.RawMessage } @@ -1435,8 +1621,8 @@ func (d *DevicePropertiesAssaAbloyCredentialServiceMetadata) String() string { } type DevicePropertiesAssaAbloyCredentialServiceMetadataEndpointsItem struct { - EndpointId string `json:"endpoint_id"` - IsActive bool `json:"is_active"` + EndpointId string `json:"endpoint_id" url:"endpoint_id"` + IsActive bool `json:"is_active" url:"is_active"` _rawJSON json.RawMessage } @@ -1465,13 +1651,13 @@ func (d *DevicePropertiesAssaAbloyCredentialServiceMetadataEndpointsItem) String } type DevicePropertiesAugustMetadata struct { - LockId string `json:"lock_id"` - LockName string `json:"lock_name"` - HouseName string `json:"house_name"` - HasKeypad bool `json:"has_keypad"` - KeypadBatteryLevel *string `json:"keypad_battery_level,omitempty"` - Model *string `json:"model,omitempty"` - HouseId *string `json:"house_id,omitempty"` + LockId string `json:"lock_id" url:"lock_id"` + LockName string `json:"lock_name" url:"lock_name"` + HouseName string `json:"house_name" url:"house_name"` + HasKeypad bool `json:"has_keypad" url:"has_keypad"` + KeypadBatteryLevel *string `json:"keypad_battery_level,omitempty" url:"keypad_battery_level,omitempty"` + Model *string `json:"model,omitempty" url:"model,omitempty"` + HouseId *string `json:"house_id,omitempty" url:"house_id,omitempty"` _rawJSON json.RawMessage } @@ -1500,12 +1686,12 @@ func (d *DevicePropertiesAugustMetadata) String() string { } type DevicePropertiesAvigilonAltaMetadata struct { - EntryName string `json:"entry_name"` - OrgName string `json:"org_name"` - ZoneId float64 `json:"zone_id"` - ZoneName string `json:"zone_name"` - SiteId float64 `json:"site_id"` - SiteName string `json:"site_name"` + EntryName string `json:"entry_name" url:"entry_name"` + OrgName string `json:"org_name" url:"org_name"` + ZoneId float64 `json:"zone_id" url:"zone_id"` + ZoneName string `json:"zone_name" url:"zone_name"` + SiteId float64 `json:"site_id" url:"site_id"` + SiteName string `json:"site_name" url:"site_name"` _rawJSON json.RawMessage } @@ -1535,8 +1721,8 @@ func (d *DevicePropertiesAvigilonAltaMetadata) String() string { // Represents the current status of the battery charge level. Values are "critical," which indicates an extremely low level, suggesting imminent shutdown or an urgent need for charging; "low," which signifies that the battery is under the preferred threshold and should be charged soon; "good," which denotes a satisfactory charge level, adequate for normal use without the immediate need for recharging; and "full," which represents a battery that is fully charged, providing the maximum duration of usage. type DevicePropertiesBattery struct { - Level float64 `json:"level"` - Status DevicePropertiesBatteryStatus `json:"status,omitempty"` + Level float64 `json:"level" url:"level"` + Status DevicePropertiesBatteryStatus `json:"status,omitempty" url:"status,omitempty"` _rawJSON json.RawMessage } @@ -1593,7 +1779,7 @@ func (d DevicePropertiesBatteryStatus) Ptr() *DevicePropertiesBatteryStatus { } type DevicePropertiesBrivoMetadata struct { - DeviceName string `json:"device_name"` + DeviceName string `json:"device_name" url:"device_name"` _rawJSON json.RawMessage } @@ -1679,8 +1865,8 @@ func (d *DevicePropertiesCodeConstraintsItem) Accept(visitor DevicePropertiesCod } type DevicePropertiesCodeConstraintsItemMaxLength struct { - MinLength *float64 `json:"min_length,omitempty"` - MaxLength *float64 `json:"max_length,omitempty"` + MinLength *float64 `json:"min_length,omitempty" url:"min_length,omitempty"` + MaxLength *float64 `json:"max_length,omitempty" url:"max_length,omitempty"` constraintType string _rawJSON json.RawMessage @@ -1691,12 +1877,16 @@ func (d *DevicePropertiesCodeConstraintsItemMaxLength) ConstraintType() string { } func (d *DevicePropertiesCodeConstraintsItemMaxLength) UnmarshalJSON(data []byte) error { - type unmarshaler DevicePropertiesCodeConstraintsItemMaxLength - var value unmarshaler - if err := json.Unmarshal(data, &value); err != nil { + type embed DevicePropertiesCodeConstraintsItemMaxLength + var unmarshaler = struct { + embed + }{ + embed: embed(*d), + } + if err := json.Unmarshal(data, &unmarshaler); err != nil { return err } - *d = DevicePropertiesCodeConstraintsItemMaxLength(value) + *d = DevicePropertiesCodeConstraintsItemMaxLength(unmarshaler.embed) d.constraintType = "name_length" d._rawJSON = json.RawMessage(data) return nil @@ -1727,7 +1917,7 @@ func (d *DevicePropertiesCodeConstraintsItemMaxLength) String() string { } type DevicePropertiesCodeConstraintsItemZero struct { - ConstraintType DevicePropertiesCodeConstraintsItemZeroConstraintType `json:"constraint_type,omitempty"` + ConstraintType DevicePropertiesCodeConstraintsItemZeroConstraintType `json:"constraint_type,omitempty" url:"constraint_type,omitempty"` _rawJSON json.RawMessage } @@ -1796,9 +1986,9 @@ func (d DevicePropertiesCodeConstraintsItemZeroConstraintType) Ptr() *DeviceProp } type DevicePropertiesControlbywebMetadata struct { - DeviceId string `json:"device_id"` - DeviceName string `json:"device_name"` - RelayName *string `json:"relay_name,omitempty"` + DeviceId string `json:"device_id" url:"device_id"` + DeviceName string `json:"device_name" url:"device_name"` + RelayName *string `json:"relay_name,omitempty" url:"relay_name,omitempty"` _rawJSON json.RawMessage } @@ -1827,13 +2017,13 @@ func (d *DevicePropertiesControlbywebMetadata) String() string { } type DevicePropertiesDormakabaOracodeMetadata struct { - DoorId float64 `json:"door_id"` - DoorName string `json:"door_name"` - DeviceId *float64 `json:"device_id,omitempty"` - SiteId float64 `json:"site_id"` - SiteName string `json:"site_name"` - IanaTimezone *string `json:"iana_timezone,omitempty"` - PredefinedTimeSlots []*DevicePropertiesDormakabaOracodeMetadataPredefinedTimeSlotsItem `json:"predefined_time_slots,omitempty"` + DoorId float64 `json:"door_id" url:"door_id"` + DoorName string `json:"door_name" url:"door_name"` + DeviceId *float64 `json:"device_id,omitempty" url:"device_id,omitempty"` + SiteId float64 `json:"site_id" url:"site_id"` + SiteName string `json:"site_name" url:"site_name"` + IanaTimezone *string `json:"iana_timezone,omitempty" url:"iana_timezone,omitempty"` + PredefinedTimeSlots []*DevicePropertiesDormakabaOracodeMetadataPredefinedTimeSlotsItem `json:"predefined_time_slots,omitempty" url:"predefined_time_slots,omitempty"` _rawJSON json.RawMessage } @@ -1862,16 +2052,16 @@ func (d *DevicePropertiesDormakabaOracodeMetadata) String() string { } type DevicePropertiesDormakabaOracodeMetadataPredefinedTimeSlotsItem struct { - Name string `json:"name"` - Prefix float64 `json:"prefix"` - CheckInTime string `json:"check_in_time"` - CheckOutTime string `json:"check_out_time"` - Is24Hour bool `json:"is_24_hour"` - IsBiweeklyMode bool `json:"is_biweekly_mode"` - IsOneShot bool `json:"is_one_shot"` - IsMaster bool `json:"is_master"` - ExtDormakabaOracodeUserLevelPrefix float64 `json:"ext_dormakaba_oracode_user_level_prefix"` - DormakabaOracodeUserLevelId string `json:"dormakaba_oracode_user_level_id"` + Name string `json:"name" url:"name"` + Prefix float64 `json:"prefix" url:"prefix"` + CheckInTime string `json:"check_in_time" url:"check_in_time"` + CheckOutTime string `json:"check_out_time" url:"check_out_time"` + Is24Hour bool `json:"is_24_hour" url:"is_24_hour"` + IsBiweeklyMode bool `json:"is_biweekly_mode" url:"is_biweekly_mode"` + IsOneShot bool `json:"is_one_shot" url:"is_one_shot"` + IsMaster bool `json:"is_master" url:"is_master"` + ExtDormakabaOracodeUserLevelPrefix float64 `json:"ext_dormakaba_oracode_user_level_prefix" url:"ext_dormakaba_oracode_user_level_prefix"` + DormakabaOracodeUserLevelId string `json:"dormakaba_oracode_user_level_id" url:"dormakaba_oracode_user_level_id"` _rawJSON json.RawMessage } @@ -1900,8 +2090,8 @@ func (d *DevicePropertiesDormakabaOracodeMetadataPredefinedTimeSlotsItem) String } type DevicePropertiesEcobeeMetadata struct { - EcobeeDeviceId string `json:"ecobee_device_id"` - DeviceName string `json:"device_name"` + EcobeeDeviceId string `json:"ecobee_device_id" url:"ecobee_device_id"` + DeviceName string `json:"device_name" url:"device_name"` _rawJSON json.RawMessage } @@ -1930,9 +2120,9 @@ func (d *DevicePropertiesEcobeeMetadata) String() string { } type DevicePropertiesFourSuitesMetadata struct { - DeviceId float64 `json:"device_id"` - DeviceName string `json:"device_name"` - RecloseDelayInSeconds float64 `json:"reclose_delay_in_seconds"` + DeviceId float64 `json:"device_id" url:"device_id"` + DeviceName string `json:"device_name" url:"device_name"` + RecloseDelayInSeconds float64 `json:"reclose_delay_in_seconds" url:"reclose_delay_in_seconds"` _rawJSON json.RawMessage } @@ -1961,8 +2151,8 @@ func (d *DevicePropertiesFourSuitesMetadata) String() string { } type DevicePropertiesGenieMetadata struct { - DeviceName string `json:"device_name"` - DoorName string `json:"door_name"` + DeviceName string `json:"device_name" url:"device_name"` + DoorName string `json:"door_name" url:"door_name"` _rawJSON json.RawMessage } @@ -1991,8 +2181,8 @@ func (d *DevicePropertiesGenieMetadata) String() string { } type DevicePropertiesHoneywellMetadata struct { - HoneywellDeviceId string `json:"honeywell_device_id"` - DeviceName string `json:"device_name"` + HoneywellDeviceId string `json:"honeywell_device_id" url:"honeywell_device_id"` + DeviceName string `json:"device_name" url:"device_name"` _rawJSON json.RawMessage } @@ -2021,9 +2211,9 @@ func (d *DevicePropertiesHoneywellMetadata) String() string { } type DevicePropertiesHubitatMetadata struct { - DeviceId string `json:"device_id"` - DeviceName string `json:"device_name"` - DeviceLabel string `json:"device_label"` + DeviceId string `json:"device_id" url:"device_id"` + DeviceName string `json:"device_name" url:"device_name"` + DeviceLabel string `json:"device_label" url:"device_label"` _rawJSON json.RawMessage } @@ -2052,9 +2242,9 @@ func (d *DevicePropertiesHubitatMetadata) String() string { } type DevicePropertiesIglooMetadata struct { - DeviceId string `json:"device_id"` - BridgeId string `json:"bridge_id"` - Model *string `json:"model,omitempty"` + DeviceId string `json:"device_id" url:"device_id"` + BridgeId string `json:"bridge_id" url:"bridge_id"` + Model *string `json:"model,omitempty" url:"model,omitempty"` _rawJSON json.RawMessage } @@ -2083,10 +2273,10 @@ func (d *DevicePropertiesIglooMetadata) String() string { } type DevicePropertiesIgloohomeMetadata struct { - DeviceId string `json:"device_id"` - DeviceName string `json:"device_name"` - BridgeId *string `json:"bridge_id,omitempty"` - BridgeName *string `json:"bridge_name,omitempty"` + DeviceId string `json:"device_id" url:"device_id"` + DeviceName string `json:"device_name" url:"device_name"` + BridgeId *string `json:"bridge_id,omitempty" url:"bridge_id,omitempty"` + BridgeName *string `json:"bridge_name,omitempty" url:"bridge_name,omitempty"` _rawJSON json.RawMessage } @@ -2115,7 +2305,7 @@ func (d *DevicePropertiesIgloohomeMetadata) String() string { } type DevicePropertiesKeypadBattery struct { - Level float64 `json:"level"` + Level float64 `json:"level" url:"level"` _rawJSON json.RawMessage } @@ -2144,9 +2334,9 @@ func (d *DevicePropertiesKeypadBattery) String() string { } type DevicePropertiesKwiksetMetadata struct { - DeviceId string `json:"device_id"` - DeviceName string `json:"device_name"` - ModelNumber string `json:"model_number"` + DeviceId string `json:"device_id" url:"device_id"` + DeviceName string `json:"device_name" url:"device_name"` + ModelNumber string `json:"model_number" url:"model_number"` _rawJSON json.RawMessage } @@ -2175,9 +2365,9 @@ func (d *DevicePropertiesKwiksetMetadata) String() string { } type DevicePropertiesLocklyMetadata struct { - DeviceId string `json:"device_id"` - DeviceName string `json:"device_name"` - Model *string `json:"model,omitempty"` + DeviceId string `json:"device_id" url:"device_id"` + DeviceName string `json:"device_name" url:"device_name"` + Model *string `json:"model,omitempty" url:"model,omitempty"` _rawJSON json.RawMessage } @@ -2206,9 +2396,9 @@ func (d *DevicePropertiesLocklyMetadata) String() string { } type DevicePropertiesMinutMetadata struct { - DeviceId string `json:"device_id"` - DeviceName string `json:"device_name"` - LatestSensorValues *DevicePropertiesMinutMetadataLatestSensorValues `json:"latest_sensor_values,omitempty"` + DeviceId string `json:"device_id" url:"device_id"` + DeviceName string `json:"device_name" url:"device_name"` + LatestSensorValues *DevicePropertiesMinutMetadataLatestSensorValues `json:"latest_sensor_values,omitempty" url:"latest_sensor_values,omitempty"` _rawJSON json.RawMessage } @@ -2237,11 +2427,11 @@ func (d *DevicePropertiesMinutMetadata) String() string { } type DevicePropertiesMinutMetadataLatestSensorValues struct { - Temperature *DevicePropertiesMinutMetadataLatestSensorValuesTemperature `json:"temperature,omitempty"` - Sound *DevicePropertiesMinutMetadataLatestSensorValuesSound `json:"sound,omitempty"` - Humidity *DevicePropertiesMinutMetadataLatestSensorValuesHumidity `json:"humidity,omitempty"` - Pressure *DevicePropertiesMinutMetadataLatestSensorValuesPressure `json:"pressure,omitempty"` - AccelerometerZ *DevicePropertiesMinutMetadataLatestSensorValuesAccelerometerZ `json:"accelerometer_z,omitempty"` + Temperature *DevicePropertiesMinutMetadataLatestSensorValuesTemperature `json:"temperature,omitempty" url:"temperature,omitempty"` + Sound *DevicePropertiesMinutMetadataLatestSensorValuesSound `json:"sound,omitempty" url:"sound,omitempty"` + Humidity *DevicePropertiesMinutMetadataLatestSensorValuesHumidity `json:"humidity,omitempty" url:"humidity,omitempty"` + Pressure *DevicePropertiesMinutMetadataLatestSensorValuesPressure `json:"pressure,omitempty" url:"pressure,omitempty"` + AccelerometerZ *DevicePropertiesMinutMetadataLatestSensorValuesAccelerometerZ `json:"accelerometer_z,omitempty" url:"accelerometer_z,omitempty"` _rawJSON json.RawMessage } @@ -2270,8 +2460,8 @@ func (d *DevicePropertiesMinutMetadataLatestSensorValues) String() string { } type DevicePropertiesMinutMetadataLatestSensorValuesAccelerometerZ struct { - Time string `json:"time"` - Value float64 `json:"value"` + Time string `json:"time" url:"time"` + Value float64 `json:"value" url:"value"` _rawJSON json.RawMessage } @@ -2300,8 +2490,8 @@ func (d *DevicePropertiesMinutMetadataLatestSensorValuesAccelerometerZ) String() } type DevicePropertiesMinutMetadataLatestSensorValuesHumidity struct { - Time string `json:"time"` - Value float64 `json:"value"` + Time string `json:"time" url:"time"` + Value float64 `json:"value" url:"value"` _rawJSON json.RawMessage } @@ -2330,8 +2520,8 @@ func (d *DevicePropertiesMinutMetadataLatestSensorValuesHumidity) String() strin } type DevicePropertiesMinutMetadataLatestSensorValuesPressure struct { - Time string `json:"time"` - Value float64 `json:"value"` + Time string `json:"time" url:"time"` + Value float64 `json:"value" url:"value"` _rawJSON json.RawMessage } @@ -2360,8 +2550,8 @@ func (d *DevicePropertiesMinutMetadataLatestSensorValuesPressure) String() strin } type DevicePropertiesMinutMetadataLatestSensorValuesSound struct { - Time string `json:"time"` - Value float64 `json:"value"` + Time string `json:"time" url:"time"` + Value float64 `json:"value" url:"value"` _rawJSON json.RawMessage } @@ -2390,8 +2580,8 @@ func (d *DevicePropertiesMinutMetadataLatestSensorValuesSound) String() string { } type DevicePropertiesMinutMetadataLatestSensorValuesTemperature struct { - Time string `json:"time"` - Value float64 `json:"value"` + Time string `json:"time" url:"time"` + Value float64 `json:"value" url:"value"` _rawJSON json.RawMessage } @@ -2421,15 +2611,15 @@ func (d *DevicePropertiesMinutMetadataLatestSensorValuesTemperature) String() st type DevicePropertiesModel struct { // Display name of the device model. - DisplayName string `json:"display_name"` + DisplayName string `json:"display_name" url:"display_name"` // Display name that corresponds to the manufacturer-specific terminology for the device. - ManufacturerDisplayName string `json:"manufacturer_display_name"` + ManufacturerDisplayName string `json:"manufacturer_display_name" url:"manufacturer_display_name"` // Indicates whether the device supports offline access codes. - OfflineAccessCodesSupported *bool `json:"offline_access_codes_supported,omitempty"` + OfflineAccessCodesSupported *bool `json:"offline_access_codes_supported,omitempty" url:"offline_access_codes_supported,omitempty"` // Indicates whether the device supports online access codes. - OnlineAccessCodesSupported *bool `json:"online_access_codes_supported,omitempty"` + OnlineAccessCodesSupported *bool `json:"online_access_codes_supported,omitempty" url:"online_access_codes_supported,omitempty"` // Indicates whether the device supports an accessory keypad. - AccessoryKeypadSupported *bool `json:"accessory_keypad_supported,omitempty"` + AccessoryKeypadSupported *bool `json:"accessory_keypad_supported,omitempty" url:"accessory_keypad_supported,omitempty"` _rawJSON json.RawMessage } @@ -2458,9 +2648,9 @@ func (d *DevicePropertiesModel) String() string { } type DevicePropertiesNestMetadata struct { - NestDeviceId string `json:"nest_device_id"` - DeviceName string `json:"device_name"` - CustomName string `json:"custom_name"` + NestDeviceId string `json:"nest_device_id" url:"nest_device_id"` + DeviceName string `json:"device_name" url:"device_name"` + CustomName string `json:"custom_name" url:"custom_name"` _rawJSON json.RawMessage } @@ -2489,11 +2679,11 @@ func (d *DevicePropertiesNestMetadata) String() string { } type DevicePropertiesNoiseawareMetadata struct { - DeviceModel DevicePropertiesNoiseawareMetadataDeviceModel `json:"device_model,omitempty"` - NoiseLevelNrs float64 `json:"noise_level_nrs"` - NoiseLevelDecibel float64 `json:"noise_level_decibel"` - DeviceName string `json:"device_name"` - DeviceId string `json:"device_id"` + DeviceModel DevicePropertiesNoiseawareMetadataDeviceModel `json:"device_model,omitempty" url:"device_model,omitempty"` + NoiseLevelNrs float64 `json:"noise_level_nrs" url:"noise_level_nrs"` + NoiseLevelDecibel float64 `json:"noise_level_decibel" url:"noise_level_decibel"` + DeviceName string `json:"device_name" url:"device_name"` + DeviceId string `json:"device_id" url:"device_id"` _rawJSON json.RawMessage } @@ -2544,9 +2734,9 @@ func (d DevicePropertiesNoiseawareMetadataDeviceModel) Ptr() *DevicePropertiesNo } type DevicePropertiesNukiMetadata struct { - DeviceId string `json:"device_id"` - DeviceName string `json:"device_name"` - KeypadBatteryCritical *bool `json:"keypad_battery_critical,omitempty"` + DeviceId string `json:"device_id" url:"device_id"` + DeviceName string `json:"device_name" url:"device_name"` + KeypadBatteryCritical *bool `json:"keypad_battery_critical,omitempty" url:"keypad_battery_critical,omitempty"` _rawJSON json.RawMessage } @@ -2575,12 +2765,12 @@ func (d *DevicePropertiesNukiMetadata) String() string { } type DevicePropertiesSaltoMetadata struct { - LockId string `json:"lock_id"` - CustomerReference string `json:"customer_reference"` - LockType string `json:"lock_type"` - BatteryLevel string `json:"battery_level"` - LockedState string `json:"locked_state"` - Model *string `json:"model,omitempty"` + LockId string `json:"lock_id" url:"lock_id"` + CustomerReference string `json:"customer_reference" url:"customer_reference"` + LockType string `json:"lock_type" url:"lock_type"` + BatteryLevel string `json:"battery_level" url:"battery_level"` + LockedState string `json:"locked_state" url:"locked_state"` + Model *string `json:"model,omitempty" url:"model,omitempty"` _rawJSON json.RawMessage } @@ -2609,10 +2799,10 @@ func (d *DevicePropertiesSaltoMetadata) String() string { } type DevicePropertiesSchlageMetadata struct { - DeviceId string `json:"device_id"` - DeviceName string `json:"device_name"` - AccessCodeLength *float64 `json:"access_code_length,omitempty"` - Model *string `json:"model,omitempty"` + DeviceId string `json:"device_id" url:"device_id"` + DeviceName string `json:"device_name" url:"device_name"` + AccessCodeLength *float64 `json:"access_code_length,omitempty" url:"access_code_length,omitempty"` + Model *string `json:"model,omitempty" url:"model,omitempty"` _rawJSON json.RawMessage } @@ -2641,9 +2831,9 @@ func (d *DevicePropertiesSchlageMetadata) String() string { } type DevicePropertiesSeamBridgeMetadata struct { - UnlockMethod *DevicePropertiesSeamBridgeMetadataUnlockMethod `json:"unlock_method,omitempty"` - DeviceNum float64 `json:"device_num"` - Name string `json:"name"` + UnlockMethod *DevicePropertiesSeamBridgeMetadataUnlockMethod `json:"unlock_method,omitempty" url:"unlock_method,omitempty"` + DeviceNum float64 `json:"device_num" url:"device_num"` + Name string `json:"name" url:"name"` _rawJSON json.RawMessage } @@ -2694,10 +2884,10 @@ func (d DevicePropertiesSeamBridgeMetadataUnlockMethod) Ptr() *DevicePropertiesS } type DevicePropertiesSmartthingsMetadata struct { - DeviceId string `json:"device_id"` - DeviceName string `json:"device_name"` - Model *string `json:"model,omitempty"` - LocationId *string `json:"location_id,omitempty"` + DeviceId string `json:"device_id" url:"device_id"` + DeviceName string `json:"device_name" url:"device_name"` + Model *string `json:"model,omitempty" url:"model,omitempty"` + LocationId *string `json:"location_id,omitempty" url:"location_id,omitempty"` _rawJSON json.RawMessage } @@ -2726,12 +2916,12 @@ func (d *DevicePropertiesSmartthingsMetadata) String() string { } type DevicePropertiesTedeeMetadata struct { - DeviceId float64 `json:"device_id"` - SerialNumber string `json:"serial_number"` - DeviceName string `json:"device_name"` - DeviceModel string `json:"device_model"` - BridgeId float64 `json:"bridge_id"` - BridgeName string `json:"bridge_name"` + DeviceId float64 `json:"device_id" url:"device_id"` + SerialNumber string `json:"serial_number" url:"serial_number"` + DeviceName string `json:"device_name" url:"device_name"` + DeviceModel string `json:"device_model" url:"device_model"` + BridgeId float64 `json:"bridge_id" url:"bridge_id"` + BridgeName string `json:"bridge_name" url:"bridge_name"` _rawJSON json.RawMessage } @@ -2760,8 +2950,8 @@ func (d *DevicePropertiesTedeeMetadata) String() string { } type DevicePropertiesTtlockMetadata struct { - LockId float64 `json:"lock_id"` - LockAlias string `json:"lock_alias"` + LockId float64 `json:"lock_id" url:"lock_id"` + LockAlias string `json:"lock_alias" url:"lock_alias"` _rawJSON json.RawMessage } @@ -2790,8 +2980,8 @@ func (d *DevicePropertiesTtlockMetadata) String() string { } type DevicePropertiesTwoNMetadata struct { - DeviceId float64 `json:"device_id"` - DeviceName string `json:"device_name"` + DeviceId float64 `json:"device_id" url:"device_id"` + DeviceName string `json:"device_name" url:"device_name"` _rawJSON json.RawMessage } @@ -2820,12 +3010,12 @@ func (d *DevicePropertiesTwoNMetadata) String() string { } type DevicePropertiesWyzeMetadata struct { - DeviceId string `json:"device_id"` - DeviceName string `json:"device_name"` - ProductName string `json:"product_name"` - ProductType string `json:"product_type"` - ProductModel string `json:"product_model"` - DeviceInfoModel string `json:"device_info_model"` + DeviceId string `json:"device_id" url:"device_id"` + DeviceName string `json:"device_name" url:"device_name"` + ProductName string `json:"product_name" url:"product_name"` + ProductType string `json:"product_type" url:"product_type"` + ProductModel string `json:"product_model" url:"product_model"` + DeviceInfoModel string `json:"device_info_model" url:"device_info_model"` _rawJSON json.RawMessage } @@ -2854,10 +3044,10 @@ func (d *DevicePropertiesWyzeMetadata) String() string { } type DeviceProvider struct { - DeviceProviderName string `json:"device_provider_name"` - DisplayName string `json:"display_name"` - ImageUrl string `json:"image_url"` - ProviderCategories []DeviceProviderProviderCategoriesItem `json:"provider_categories,omitempty"` + DeviceProviderName string `json:"device_provider_name" url:"device_provider_name"` + DisplayName string `json:"display_name" url:"display_name"` + ImageUrl string `json:"image_url" url:"image_url"` + ProviderCategories []DeviceProviderProviderCategoriesItem `json:"provider_categories,omitempty" url:"provider_categories,omitempty"` _rawJSON json.RawMessage } @@ -2890,6 +3080,8 @@ type DeviceProviderProviderCategoriesItem string const ( DeviceProviderProviderCategoriesItemStable DeviceProviderProviderCategoriesItem = "stable" DeviceProviderProviderCategoriesItemConsumerSmartlocks DeviceProviderProviderCategoriesItem = "consumer_smartlocks" + DeviceProviderProviderCategoriesItemThermostats DeviceProviderProviderCategoriesItem = "thermostats" + DeviceProviderProviderCategoriesItemNoiseSensors DeviceProviderProviderCategoriesItem = "noise_sensors" ) func NewDeviceProviderProviderCategoriesItemFromString(s string) (DeviceProviderProviderCategoriesItem, error) { @@ -2898,6 +3090,10 @@ func NewDeviceProviderProviderCategoriesItemFromString(s string) (DeviceProvider return DeviceProviderProviderCategoriesItemStable, nil case "consumer_smartlocks": return DeviceProviderProviderCategoriesItemConsumerSmartlocks, nil + case "thermostats": + return DeviceProviderProviderCategoriesItemThermostats, nil + case "noise_sensors": + return DeviceProviderProviderCategoriesItemNoiseSensors, nil } var t DeviceProviderProviderCategoriesItem return "", fmt.Errorf("%s is not a valid %T", s, t) @@ -3017,8 +3213,8 @@ func (d DeviceType) Ptr() *DeviceType { } type DeviceWarningsItem struct { - WarningCode string `json:"warning_code"` - Message string `json:"message"` + WarningCode string `json:"warning_code" url:"warning_code"` + Message string `json:"message" url:"message"` _rawJSON json.RawMessage } @@ -3047,26 +3243,44 @@ func (d *DeviceWarningsItem) String() string { } type EnrollmentAutomation struct { - CredentialManagerAcsSystemId string `json:"credential_manager_acs_system_id"` - UserIdentityId string `json:"user_identity_id"` - CreatedAt time.Time `json:"created_at"` - WorkspaceId string `json:"workspace_id"` - EnrollmentAutomationId string `json:"enrollment_automation_id"` + CredentialManagerAcsSystemId string `json:"credential_manager_acs_system_id" url:"credential_manager_acs_system_id"` + UserIdentityId string `json:"user_identity_id" url:"user_identity_id"` + CreatedAt time.Time `json:"created_at" url:"created_at"` + WorkspaceId string `json:"workspace_id" url:"workspace_id"` + EnrollmentAutomationId string `json:"enrollment_automation_id" url:"enrollment_automation_id"` _rawJSON json.RawMessage } func (e *EnrollmentAutomation) UnmarshalJSON(data []byte) error { - type unmarshaler EnrollmentAutomation - var value unmarshaler - if err := json.Unmarshal(data, &value); err != nil { + type embed EnrollmentAutomation + var unmarshaler = struct { + embed + CreatedAt *core.DateTime `json:"created_at"` + }{ + embed: embed(*e), + } + if err := json.Unmarshal(data, &unmarshaler); err != nil { return err } - *e = EnrollmentAutomation(value) + *e = EnrollmentAutomation(unmarshaler.embed) + e.CreatedAt = unmarshaler.CreatedAt.Time() e._rawJSON = json.RawMessage(data) return nil } +func (e *EnrollmentAutomation) MarshalJSON() ([]byte, error) { + type embed EnrollmentAutomation + var marshaler = struct { + embed + CreatedAt *core.DateTime `json:"created_at"` + }{ + embed: embed(*e), + CreatedAt: core.NewDateTime(e.CreatedAt), + } + return json.Marshal(marshaler) +} + func (e *EnrollmentAutomation) String() string { if len(e._rawJSON) > 0 { if value, err := core.StringifyJSON(e._rawJSON); err == nil { @@ -3080,27 +3294,49 @@ func (e *EnrollmentAutomation) String() string { } type Event struct { - EventId string `json:"event_id"` - DeviceId *string `json:"device_id,omitempty"` - EventType string `json:"event_type"` - WorkspaceId string `json:"workspace_id"` - CreatedAt time.Time `json:"created_at"` - OccurredAt time.Time `json:"occurred_at"` + EventId string `json:"event_id" url:"event_id"` + DeviceId *string `json:"device_id,omitempty" url:"device_id,omitempty"` + EventType string `json:"event_type" url:"event_type"` + WorkspaceId string `json:"workspace_id" url:"workspace_id"` + CreatedAt time.Time `json:"created_at" url:"created_at"` + OccurredAt time.Time `json:"occurred_at" url:"occurred_at"` _rawJSON json.RawMessage } func (e *Event) UnmarshalJSON(data []byte) error { - type unmarshaler Event - var value unmarshaler - if err := json.Unmarshal(data, &value); err != nil { + type embed Event + var unmarshaler = struct { + embed + CreatedAt *core.DateTime `json:"created_at"` + OccurredAt *core.DateTime `json:"occurred_at"` + }{ + embed: embed(*e), + } + if err := json.Unmarshal(data, &unmarshaler); err != nil { return err } - *e = Event(value) + *e = Event(unmarshaler.embed) + e.CreatedAt = unmarshaler.CreatedAt.Time() + e.OccurredAt = unmarshaler.OccurredAt.Time() e._rawJSON = json.RawMessage(data) return nil } +func (e *Event) MarshalJSON() ([]byte, error) { + type embed Event + var marshaler = struct { + embed + CreatedAt *core.DateTime `json:"created_at"` + OccurredAt *core.DateTime `json:"occurred_at"` + }{ + embed: embed(*e), + CreatedAt: core.NewDateTime(e.CreatedAt), + OccurredAt: core.NewDateTime(e.OccurredAt), + } + return json.Marshal(marshaler) +} + func (e *Event) String() string { if len(e._rawJSON) > 0 { if value, err := core.StringifyJSON(e._rawJSON); err == nil { @@ -3474,13 +3710,13 @@ func (m MaxTimeRounding) Ptr() *MaxTimeRounding { } type NoiseThreshold struct { - NoiseThresholdId string `json:"noise_threshold_id"` - DeviceId string `json:"device_id"` - Name string `json:"name"` - NoiseThresholdNrs *float64 `json:"noise_threshold_nrs,omitempty"` - StartsDailyAt string `json:"starts_daily_at"` - EndsDailyAt string `json:"ends_daily_at"` - NoiseThresholdDecibels float64 `json:"noise_threshold_decibels"` + NoiseThresholdId string `json:"noise_threshold_id" url:"noise_threshold_id"` + DeviceId string `json:"device_id" url:"device_id"` + Name string `json:"name" url:"name"` + NoiseThresholdNrs *float64 `json:"noise_threshold_nrs,omitempty" url:"noise_threshold_nrs,omitempty"` + StartsDailyAt string `json:"starts_daily_at" url:"starts_daily_at"` + EndsDailyAt string `json:"ends_daily_at" url:"ends_daily_at"` + NoiseThresholdDecibels float64 `json:"noise_threshold_decibels" url:"noise_threshold_decibels"` _rawJSON json.RawMessage } @@ -3510,41 +3746,59 @@ func (n *NoiseThreshold) String() string { type Phone struct { // Unique identifier for the device. - DeviceId string `json:"device_id"` - DeviceType PhoneDeviceType `json:"device_type,omitempty"` + DeviceId string `json:"device_id" url:"device_id"` + DeviceType PhoneDeviceType `json:"device_type,omitempty" url:"device_type,omitempty"` // Collection of capabilities that the device supports when connected to Seam. Values are "access_code," which indicates that the device can manage and utilize digital PIN codes for secure access; "lock," which indicates that the device controls a door locking mechanism, enabling the remote opening and closing of doors and other entry points; "noise_detection," which indicates that the device supports monitoring and responding to ambient noise levels; "thermostat," which indicates that the device can regulate and adjust indoor temperatures; and "battery," which indicates that the device can manage battery life and health. - CapabilitiesSupported []PhoneCapabilitiesSupportedItem `json:"capabilities_supported,omitempty"` - Properties *PhoneProperties `json:"properties,omitempty"` + CapabilitiesSupported []PhoneCapabilitiesSupportedItem `json:"capabilities_supported,omitempty" url:"capabilities_supported,omitempty"` + Properties *PhoneProperties `json:"properties,omitempty" url:"properties,omitempty"` // Location information for the device. - Location *PhoneLocation `json:"location,omitempty"` + Location *PhoneLocation `json:"location,omitempty" url:"location,omitempty"` // Unique identifier for the Seam workspace associated with the device. - WorkspaceId string `json:"workspace_id"` + WorkspaceId string `json:"workspace_id" url:"workspace_id"` // Array of errors associated with the device. Each error object within the array contains two fields: "error_code" and "message." "error_code" is a string that uniquely identifies the type of error, enabling quick recognition and categorization of the issue. "message" provides a more detailed description of the error, offering insights into the issue and potentially how to rectify it. - Errors []*PhoneErrorsItem `json:"errors,omitempty"` + Errors []*PhoneErrorsItem `json:"errors,omitempty" url:"errors,omitempty"` // Array of warnings associated with the device. Each warning object within the array contains two fields: "warning_code" and "message." "warning_code" is a string that uniquely identifies the type of warning, enabling quick recognition and categorization of the issue. "message" provides a more detailed description of the warning, offering insights into the issue and potentially how to rectify it. - Warnings []*PhoneWarningsItem `json:"warnings,omitempty"` + Warnings []*PhoneWarningsItem `json:"warnings,omitempty" url:"warnings,omitempty"` // Date and time at which the device object was created. - CreatedAt time.Time `json:"created_at"` + CreatedAt time.Time `json:"created_at" url:"created_at"` // Indicates whether Seam manages the device. - IsManaged bool `json:"is_managed"` - CustomMetadata map[string]*PhoneCustomMetadataValue `json:"custom_metadata,omitempty"` - CanRemotelyUnlock *bool `json:"can_remotely_unlock,omitempty"` - CanProgramOnlineAccessCodes *bool `json:"can_program_online_access_codes,omitempty"` + IsManaged bool `json:"is_managed" url:"is_managed"` + CustomMetadata map[string]*PhoneCustomMetadataValue `json:"custom_metadata,omitempty" url:"custom_metadata,omitempty"` + CanRemotelyUnlock *bool `json:"can_remotely_unlock,omitempty" url:"can_remotely_unlock,omitempty"` + CanProgramOnlineAccessCodes *bool `json:"can_program_online_access_codes,omitempty" url:"can_program_online_access_codes,omitempty"` _rawJSON json.RawMessage } func (p *Phone) UnmarshalJSON(data []byte) error { - type unmarshaler Phone - var value unmarshaler - if err := json.Unmarshal(data, &value); err != nil { + type embed Phone + var unmarshaler = struct { + embed + CreatedAt *core.DateTime `json:"created_at"` + }{ + embed: embed(*p), + } + if err := json.Unmarshal(data, &unmarshaler); err != nil { return err } - *p = Phone(value) + *p = Phone(unmarshaler.embed) + p.CreatedAt = unmarshaler.CreatedAt.Time() p._rawJSON = json.RawMessage(data) return nil } +func (p *Phone) MarshalJSON() ([]byte, error) { + type embed Phone + var marshaler = struct { + embed + CreatedAt *core.DateTime `json:"created_at"` + }{ + embed: embed(*p), + CreatedAt: core.NewDateTime(p.CreatedAt), + } + return json.Marshal(marshaler) +} + func (p *Phone) String() string { if len(p._rawJSON) > 0 { if value, err := core.StringifyJSON(p._rawJSON); err == nil { @@ -3687,8 +3941,8 @@ func (p PhoneDeviceType) Ptr() *PhoneDeviceType { } type PhoneErrorsItem struct { - ErrorCode string `json:"error_code"` - Message string `json:"message"` + ErrorCode string `json:"error_code" url:"error_code"` + Message string `json:"message" url:"message"` _rawJSON json.RawMessage } @@ -3719,9 +3973,9 @@ func (p *PhoneErrorsItem) String() string { // Location information for the device. type PhoneLocation struct { // Name of the device location. - LocationName *string `json:"location_name,omitempty"` + LocationName *string `json:"location_name,omitempty" url:"location_name,omitempty"` // Time zone of the device location. - Timezone *string `json:"timezone,omitempty"` + Timezone *string `json:"timezone,omitempty" url:"timezone,omitempty"` _rawJSON json.RawMessage } @@ -3772,7 +4026,7 @@ func (p PhoneOperatingSystem) Ptr() *PhoneOperatingSystem { } type PhoneProperties struct { - AssaAbloyCredentialServiceMetadata *PhonePropertiesAssaAbloyCredentialServiceMetadata `json:"assa_abloy_credential_service_metadata,omitempty"` + AssaAbloyCredentialServiceMetadata *PhonePropertiesAssaAbloyCredentialServiceMetadata `json:"assa_abloy_credential_service_metadata,omitempty" url:"assa_abloy_credential_service_metadata,omitempty"` _rawJSON json.RawMessage } @@ -3801,8 +4055,8 @@ func (p *PhoneProperties) String() string { } type PhonePropertiesAssaAbloyCredentialServiceMetadata struct { - HasActiveEndpoint bool `json:"has_active_endpoint"` - Endpoints []*PhonePropertiesAssaAbloyCredentialServiceMetadataEndpointsItem `json:"endpoints,omitempty"` + HasActiveEndpoint bool `json:"has_active_endpoint" url:"has_active_endpoint"` + Endpoints []*PhonePropertiesAssaAbloyCredentialServiceMetadataEndpointsItem `json:"endpoints,omitempty" url:"endpoints,omitempty"` _rawJSON json.RawMessage } @@ -3831,8 +4085,8 @@ func (p *PhonePropertiesAssaAbloyCredentialServiceMetadata) String() string { } type PhonePropertiesAssaAbloyCredentialServiceMetadataEndpointsItem struct { - EndpointId string `json:"endpoint_id"` - IsActive bool `json:"is_active"` + EndpointId string `json:"endpoint_id" url:"endpoint_id"` + IsActive bool `json:"is_active" url:"is_active"` _rawJSON json.RawMessage } @@ -3861,8 +4115,8 @@ func (p *PhonePropertiesAssaAbloyCredentialServiceMetadataEndpointsItem) String( } type PhoneWarningsItem struct { - WarningCode string `json:"warning_code"` - Message string `json:"message"` + WarningCode string `json:"warning_code" url:"warning_code"` + Message string `json:"message" url:"message"` _rawJSON json.RawMessage } @@ -3938,9 +4192,9 @@ func (s SelectionMode) Ptr() *SelectionMode { } type ServiceHealth struct { - Service string `json:"service"` - Status ServiceHealthStatus `json:"status,omitempty"` - Description string `json:"description"` + Service string `json:"service" url:"service"` + Status ServiceHealthStatus `json:"status,omitempty" url:"status,omitempty"` + Description string `json:"description" url:"description"` _rawJSON json.RawMessage } @@ -3995,24 +4249,24 @@ func (s ServiceHealthStatus) Ptr() *ServiceHealthStatus { type UnmanagedAccessCode struct { // Nature of the access code. Values are "ongoing" for access codes that are active continuously until deactivated manually or "time_bound" for access codes that have a specific duration. - Type UnmanagedAccessCodeType `json:"type,omitempty"` + Type UnmanagedAccessCodeType `json:"type,omitempty" url:"type,omitempty"` // Unique identifier for the access code. - AccessCodeId string `json:"access_code_id"` + AccessCodeId string `json:"access_code_id" url:"access_code_id"` // Unique identifier for the device associated with the access code. - DeviceId string `json:"device_id"` + DeviceId string `json:"device_id" url:"device_id"` // Name of the access code. Enables administrators and users to identify the access code easily, especially when there are numerous access codes. - Name *string `json:"name,omitempty"` + Name *string `json:"name,omitempty" url:"name,omitempty"` // Code used for access. Typically, a numeric or alphanumeric string. - Code *string `json:"code,omitempty"` + Code *string `json:"code,omitempty" url:"code,omitempty"` // Date and time at which the access code was created. - CreatedAt time.Time `json:"created_at"` - Errors interface{} `json:"errors,omitempty"` - Warnings interface{} `json:"warnings,omitempty"` - IsManaged bool `json:"is_managed"` + CreatedAt time.Time `json:"created_at" url:"created_at"` + Errors interface{} `json:"errors,omitempty" url:"errors,omitempty"` + Warnings interface{} `json:"warnings,omitempty" url:"warnings,omitempty"` + IsManaged bool `json:"is_managed" url:"is_managed"` // Date and time at which the time-bound access code becomes active. - StartsAt *time.Time `json:"starts_at,omitempty"` + StartsAt *time.Time `json:"starts_at,omitempty" url:"starts_at,omitempty"` // Date and time after which the time-bound access code becomes inactive. - EndsAt *time.Time `json:"ends_at,omitempty"` + EndsAt *time.Time `json:"ends_at,omitempty" url:"ends_at,omitempty"` status string _rawJSON json.RawMessage @@ -4023,12 +4277,22 @@ func (u *UnmanagedAccessCode) Status() string { } func (u *UnmanagedAccessCode) UnmarshalJSON(data []byte) error { - type unmarshaler UnmanagedAccessCode - var value unmarshaler - if err := json.Unmarshal(data, &value); err != nil { + type embed UnmanagedAccessCode + var unmarshaler = struct { + embed + CreatedAt *core.DateTime `json:"created_at"` + StartsAt *core.DateTime `json:"starts_at,omitempty"` + EndsAt *core.DateTime `json:"ends_at,omitempty"` + }{ + embed: embed(*u), + } + if err := json.Unmarshal(data, &unmarshaler); err != nil { return err } - *u = UnmanagedAccessCode(value) + *u = UnmanagedAccessCode(unmarshaler.embed) + u.CreatedAt = unmarshaler.CreatedAt.Time() + u.StartsAt = unmarshaler.StartsAt.TimePtr() + u.EndsAt = unmarshaler.EndsAt.TimePtr() u.status = "set" u._rawJSON = json.RawMessage(data) return nil @@ -4038,10 +4302,16 @@ func (u *UnmanagedAccessCode) MarshalJSON() ([]byte, error) { type embed UnmanagedAccessCode var marshaler = struct { embed - Status string `json:"status"` + CreatedAt *core.DateTime `json:"created_at"` + StartsAt *core.DateTime `json:"starts_at,omitempty"` + EndsAt *core.DateTime `json:"ends_at,omitempty"` + Status string `json:"status"` }{ - embed: embed(*u), - Status: "set", + embed: embed(*u), + CreatedAt: core.NewDateTime(u.CreatedAt), + StartsAt: core.NewOptionalDateTime(u.StartsAt), + EndsAt: core.NewOptionalDateTime(u.EndsAt), + Status: "set", } return json.Marshal(marshaler) } @@ -4083,39 +4353,59 @@ func (u UnmanagedAccessCodeType) Ptr() *UnmanagedAccessCodeType { type UnmanagedDevice struct { // Unique identifier for the device. - DeviceId string `json:"device_id"` + DeviceId string `json:"device_id" url:"device_id"` // Type of the device. - DeviceType DeviceType `json:"device_type,omitempty"` + DeviceType DeviceType `json:"device_type,omitempty" url:"device_type,omitempty"` // Unique identifier for the account associated with the device. - ConnectedAccountId string `json:"connected_account_id"` + ConnectedAccountId string `json:"connected_account_id" url:"connected_account_id"` // Collection of capabilities that the device supports when connected to Seam. Values are "access_code," which indicates that the device can manage and utilize digital PIN codes for secure access; "lock," which indicates that the device controls a door locking mechanism, enabling the remote opening and closing of doors and other entry points; "noise_detection," which indicates that the device supports monitoring and responding to ambient noise levels; "thermostat," which indicates that the device can regulate and adjust indoor temperatures; and "battery," which indicates that the device can manage battery life and health. - CapabilitiesSupported []UnmanagedDeviceCapabilitiesSupportedItem `json:"capabilities_supported,omitempty"` + CapabilitiesSupported []UnmanagedDeviceCapabilitiesSupportedItem `json:"capabilities_supported,omitempty" url:"capabilities_supported,omitempty"` // Unique identifier for the Seam workspace associated with the device. - WorkspaceId string `json:"workspace_id"` + WorkspaceId string `json:"workspace_id" url:"workspace_id"` // Array of errors associated with the device. Each error object within the array contains two fields: "error_code" and "message." "error_code" is a string that uniquely identifies the type of error, enabling quick recognition and categorization of the issue. "message" provides a more detailed description of the error, offering insights into the issue and potentially how to rectify it. - Errors []*UnmanagedDeviceErrorsItem `json:"errors,omitempty"` + Errors []*UnmanagedDeviceErrorsItem `json:"errors,omitempty" url:"errors,omitempty"` // Array of warnings associated with the device. Each warning object within the array contains two fields: "warning_code" and "message." "warning_code" is a string that uniquely identifies the type of warning, enabling quick recognition and categorization of the issue. "message" provides a more detailed description of the warning, offering insights into the issue and potentially how to rectify it. - Warnings []*UnmanagedDeviceWarningsItem `json:"warnings,omitempty"` + Warnings []*UnmanagedDeviceWarningsItem `json:"warnings,omitempty" url:"warnings,omitempty"` // Date and time at which the device object was created. - CreatedAt time.Time `json:"created_at"` - IsManaged bool `json:"is_managed"` - Properties *UnmanagedDeviceProperties `json:"properties,omitempty"` - DeviceProvider *UnmanagedDeviceDeviceProvider `json:"device_provider,omitempty"` + CreatedAt time.Time `json:"created_at" url:"created_at"` + IsManaged bool `json:"is_managed" url:"is_managed"` + Properties *UnmanagedDeviceProperties `json:"properties,omitempty" url:"properties,omitempty"` + CanRemotelyUnlock *bool `json:"can_remotely_unlock,omitempty" url:"can_remotely_unlock,omitempty"` + CanProgramOnlineAccessCodes *bool `json:"can_program_online_access_codes,omitempty" url:"can_program_online_access_codes,omitempty"` + DeviceProvider *UnmanagedDeviceDeviceProvider `json:"device_provider,omitempty" url:"device_provider,omitempty"` _rawJSON json.RawMessage } func (u *UnmanagedDevice) UnmarshalJSON(data []byte) error { - type unmarshaler UnmanagedDevice - var value unmarshaler - if err := json.Unmarshal(data, &value); err != nil { + type embed UnmanagedDevice + var unmarshaler = struct { + embed + CreatedAt *core.DateTime `json:"created_at"` + }{ + embed: embed(*u), + } + if err := json.Unmarshal(data, &unmarshaler); err != nil { return err } - *u = UnmanagedDevice(value) + *u = UnmanagedDevice(unmarshaler.embed) + u.CreatedAt = unmarshaler.CreatedAt.Time() u._rawJSON = json.RawMessage(data) return nil } +func (u *UnmanagedDevice) MarshalJSON() ([]byte, error) { + type embed UnmanagedDevice + var marshaler = struct { + embed + CreatedAt *core.DateTime `json:"created_at"` + }{ + embed: embed(*u), + CreatedAt: core.NewDateTime(u.CreatedAt), + } + return json.Marshal(marshaler) +} + func (u *UnmanagedDevice) String() string { if len(u._rawJSON) > 0 { if value, err := core.StringifyJSON(u._rawJSON); err == nil { @@ -4163,7 +4453,7 @@ func (u UnmanagedDeviceCapabilitiesSupportedItem) Ptr() *UnmanagedDeviceCapabili } type UnmanagedDeviceDeviceProvider struct { - ProviderCategories interface{} `json:"provider_categories,omitempty"` + ProviderCategories interface{} `json:"provider_categories,omitempty" url:"provider_categories,omitempty"` _rawJSON json.RawMessage } @@ -4192,8 +4482,8 @@ func (u *UnmanagedDeviceDeviceProvider) String() string { } type UnmanagedDeviceErrorsItem struct { - ErrorCode string `json:"error_code"` - Message string `json:"message"` + ErrorCode string `json:"error_code" url:"error_code"` + Message string `json:"message" url:"message"` _rawJSON json.RawMessage } @@ -4223,24 +4513,24 @@ func (u *UnmanagedDeviceErrorsItem) String() string { type UnmanagedDeviceProperties struct { // Name of the device. Enables administrators and users to identify the device easily, especially when there are numerous devices. - Name string `json:"name"` + Name string `json:"name" url:"name"` // Indicates whether the device is online. - Online bool `json:"online"` + Online bool `json:"online" url:"online"` // Manufacturer of the device. - Manufacturer *string `json:"manufacturer,omitempty"` + Manufacturer *string `json:"manufacturer,omitempty" url:"manufacturer,omitempty"` // Image URL for the device. - ImageUrl *string `json:"image_url,omitempty"` + ImageUrl *string `json:"image_url,omitempty" url:"image_url,omitempty"` // Alt text for the device image. - ImageAltText *string `json:"image_alt_text,omitempty"` + ImageAltText *string `json:"image_alt_text,omitempty" url:"image_alt_text,omitempty"` // Indicates the battery level of the device as a decimal value between 0 and 1, inclusive. - BatteryLevel *float64 `json:"battery_level,omitempty"` + BatteryLevel *float64 `json:"battery_level,omitempty" url:"battery_level,omitempty"` // Represents the current status of the battery charge level. Values are "critical," which indicates an extremely low level, suggesting imminent shutdown or an urgent need for charging; "low," which signifies that the battery is under the preferred threshold and should be charged soon; "good," which denotes a satisfactory charge level, adequate for normal use without the immediate need for recharging; and "full," which represents a battery that is fully charged, providing the maximum duration of usage. - Battery *UnmanagedDevicePropertiesBattery `json:"battery,omitempty"` + Battery *UnmanagedDevicePropertiesBattery `json:"battery,omitempty" url:"battery,omitempty"` // Indicates whether it is currently possible to use online access codes for the device. - OnlineAccessCodesEnabled *bool `json:"online_access_codes_enabled,omitempty"` + OnlineAccessCodesEnabled *bool `json:"online_access_codes_enabled,omitempty" url:"online_access_codes_enabled,omitempty"` // Indicates whether it is currently possible to use offline access codes for the device. - OfflineAccessCodesEnabled *bool `json:"offline_access_codes_enabled,omitempty"` - Model *UnmanagedDevicePropertiesModel `json:"model,omitempty"` + OfflineAccessCodesEnabled *bool `json:"offline_access_codes_enabled,omitempty" url:"offline_access_codes_enabled,omitempty"` + Model *UnmanagedDevicePropertiesModel `json:"model,omitempty" url:"model,omitempty"` _rawJSON json.RawMessage } @@ -4270,8 +4560,8 @@ func (u *UnmanagedDeviceProperties) String() string { // Represents the current status of the battery charge level. Values are "critical," which indicates an extremely low level, suggesting imminent shutdown or an urgent need for charging; "low," which signifies that the battery is under the preferred threshold and should be charged soon; "good," which denotes a satisfactory charge level, adequate for normal use without the immediate need for recharging; and "full," which represents a battery that is fully charged, providing the maximum duration of usage. type UnmanagedDevicePropertiesBattery struct { - Level float64 `json:"level"` - Status UnmanagedDevicePropertiesBatteryStatus `json:"status,omitempty"` + Level float64 `json:"level" url:"level"` + Status UnmanagedDevicePropertiesBatteryStatus `json:"status,omitempty" url:"status,omitempty"` _rawJSON json.RawMessage } @@ -4329,15 +4619,15 @@ func (u UnmanagedDevicePropertiesBatteryStatus) Ptr() *UnmanagedDeviceProperties type UnmanagedDevicePropertiesModel struct { // Display name of the device model. - DisplayName string `json:"display_name"` + DisplayName string `json:"display_name" url:"display_name"` // Display name that corresponds to the manufacturer-specific terminology for the device. - ManufacturerDisplayName string `json:"manufacturer_display_name"` + ManufacturerDisplayName string `json:"manufacturer_display_name" url:"manufacturer_display_name"` // Indicates whether the device supports offline access codes. - OfflineAccessCodesSupported *bool `json:"offline_access_codes_supported,omitempty"` + OfflineAccessCodesSupported *bool `json:"offline_access_codes_supported,omitempty" url:"offline_access_codes_supported,omitempty"` // Indicates whether the device supports online access codes. - OnlineAccessCodesSupported *bool `json:"online_access_codes_supported,omitempty"` + OnlineAccessCodesSupported *bool `json:"online_access_codes_supported,omitempty" url:"online_access_codes_supported,omitempty"` // Indicates whether the device supports an accessory keypad. - AccessoryKeypadSupported *bool `json:"accessory_keypad_supported,omitempty"` + AccessoryKeypadSupported *bool `json:"accessory_keypad_supported,omitempty" url:"accessory_keypad_supported,omitempty"` _rawJSON json.RawMessage } @@ -4366,8 +4656,8 @@ func (u *UnmanagedDevicePropertiesModel) String() string { } type UnmanagedDeviceWarningsItem struct { - WarningCode string `json:"warning_code"` - Message string `json:"message"` + WarningCode string `json:"warning_code" url:"warning_code"` + Message string `json:"message" url:"message"` _rawJSON json.RawMessage } @@ -4396,10 +4686,10 @@ func (u *UnmanagedDeviceWarningsItem) String() string { } type Webhook struct { - WebhookId string `json:"webhook_id"` - Url string `json:"url"` - EventTypes []string `json:"event_types,omitempty"` - Secret *string `json:"secret,omitempty"` + WebhookId string `json:"webhook_id" url:"webhook_id"` + Url string `json:"url" url:"url"` + EventTypes []string `json:"event_types,omitempty" url:"event_types,omitempty"` + Secret *string `json:"secret,omitempty" url:"secret,omitempty"` _rawJSON json.RawMessage } @@ -4428,10 +4718,10 @@ func (w *Webhook) String() string { } type Workspace struct { - WorkspaceId string `json:"workspace_id"` - Name string `json:"name"` - IsSandbox bool `json:"is_sandbox"` - ConnectPartnerName *string `json:"connect_partner_name,omitempty"` + WorkspaceId string `json:"workspace_id" url:"workspace_id"` + Name string `json:"name" url:"name"` + IsSandbox bool `json:"is_sandbox" url:"is_sandbox"` + ConnectPartnerName *string `json:"connect_partner_name,omitempty" url:"connect_partner_name,omitempty"` _rawJSON json.RawMessage } @@ -4460,7 +4750,7 @@ func (w *Workspace) String() string { } type ConnectedAccountsGetRequestConnectedAccountId struct { - ConnectedAccountId string `json:"connected_account_id"` + ConnectedAccountId string `json:"connected_account_id" url:"connected_account_id"` _rawJSON json.RawMessage } @@ -4489,7 +4779,7 @@ func (c *ConnectedAccountsGetRequestConnectedAccountId) String() string { } type ConnectedAccountsGetRequestEmail struct { - Email string `json:"email"` + Email string `json:"email" url:"email"` _rawJSON json.RawMessage } @@ -4518,25 +4808,43 @@ func (c *ConnectedAccountsGetRequestEmail) String() string { } type NetworksGetResponseNetwork struct { - NetworkId string `json:"network_id"` - WorkspaceId string `json:"workspace_id"` - DisplayName string `json:"display_name"` - CreatedAt time.Time `json:"created_at"` + NetworkId string `json:"network_id" url:"network_id"` + WorkspaceId string `json:"workspace_id" url:"workspace_id"` + DisplayName string `json:"display_name" url:"display_name"` + CreatedAt time.Time `json:"created_at" url:"created_at"` _rawJSON json.RawMessage } func (n *NetworksGetResponseNetwork) UnmarshalJSON(data []byte) error { - type unmarshaler NetworksGetResponseNetwork - var value unmarshaler - if err := json.Unmarshal(data, &value); err != nil { + type embed NetworksGetResponseNetwork + var unmarshaler = struct { + embed + CreatedAt *core.DateTime `json:"created_at"` + }{ + embed: embed(*n), + } + if err := json.Unmarshal(data, &unmarshaler); err != nil { return err } - *n = NetworksGetResponseNetwork(value) + *n = NetworksGetResponseNetwork(unmarshaler.embed) + n.CreatedAt = unmarshaler.CreatedAt.Time() n._rawJSON = json.RawMessage(data) return nil } +func (n *NetworksGetResponseNetwork) MarshalJSON() ([]byte, error) { + type embed NetworksGetResponseNetwork + var marshaler = struct { + embed + CreatedAt *core.DateTime `json:"created_at"` + }{ + embed: embed(*n), + CreatedAt: core.NewDateTime(n.CreatedAt), + } + return json.Marshal(marshaler) +} + func (n *NetworksGetResponseNetwork) String() string { if len(n._rawJSON) > 0 { if value, err := core.StringifyJSON(n._rawJSON); err == nil { @@ -4550,25 +4858,43 @@ func (n *NetworksGetResponseNetwork) String() string { } type NetworksListResponseNetworksItem struct { - NetworkId string `json:"network_id"` - WorkspaceId string `json:"workspace_id"` - DisplayName string `json:"display_name"` - CreatedAt time.Time `json:"created_at"` + NetworkId string `json:"network_id" url:"network_id"` + WorkspaceId string `json:"workspace_id" url:"workspace_id"` + DisplayName string `json:"display_name" url:"display_name"` + CreatedAt time.Time `json:"created_at" url:"created_at"` _rawJSON json.RawMessage } func (n *NetworksListResponseNetworksItem) UnmarshalJSON(data []byte) error { - type unmarshaler NetworksListResponseNetworksItem - var value unmarshaler - if err := json.Unmarshal(data, &value); err != nil { + type embed NetworksListResponseNetworksItem + var unmarshaler = struct { + embed + CreatedAt *core.DateTime `json:"created_at"` + }{ + embed: embed(*n), + } + if err := json.Unmarshal(data, &unmarshaler); err != nil { return err } - *n = NetworksListResponseNetworksItem(value) + *n = NetworksListResponseNetworksItem(unmarshaler.embed) + n.CreatedAt = unmarshaler.CreatedAt.Time() n._rawJSON = json.RawMessage(data) return nil } +func (n *NetworksListResponseNetworksItem) MarshalJSON() ([]byte, error) { + type embed NetworksListResponseNetworksItem + var marshaler = struct { + embed + CreatedAt *core.DateTime `json:"created_at"` + }{ + embed: embed(*n), + CreatedAt: core.NewDateTime(n.CreatedAt), + } + return json.Marshal(marshaler) +} + func (n *NetworksListResponseNetworksItem) String() string { if len(n._rawJSON) > 0 { if value, err := core.StringifyJSON(n._rawJSON); err == nil { @@ -4610,29 +4936,47 @@ func (t ThermostatsUpdateRequestDefaultClimateSettingHvacModeSetting) Ptr() *The } type UserIdentitiesCreateResponseUserIdentity struct { - UserIdentityId string `json:"user_identity_id"` - UserIdentityKey *string `json:"user_identity_key,omitempty"` - EmailAddress *string `json:"email_address,omitempty"` - PhoneNumber *string `json:"phone_number,omitempty"` - DisplayName string `json:"display_name"` - FullName *string `json:"full_name,omitempty"` - CreatedAt time.Time `json:"created_at"` - WorkspaceId string `json:"workspace_id"` + UserIdentityId string `json:"user_identity_id" url:"user_identity_id"` + UserIdentityKey *string `json:"user_identity_key,omitempty" url:"user_identity_key,omitempty"` + EmailAddress *string `json:"email_address,omitempty" url:"email_address,omitempty"` + PhoneNumber *string `json:"phone_number,omitempty" url:"phone_number,omitempty"` + DisplayName string `json:"display_name" url:"display_name"` + FullName *string `json:"full_name,omitempty" url:"full_name,omitempty"` + CreatedAt time.Time `json:"created_at" url:"created_at"` + WorkspaceId string `json:"workspace_id" url:"workspace_id"` _rawJSON json.RawMessage } func (u *UserIdentitiesCreateResponseUserIdentity) UnmarshalJSON(data []byte) error { - type unmarshaler UserIdentitiesCreateResponseUserIdentity - var value unmarshaler - if err := json.Unmarshal(data, &value); err != nil { + type embed UserIdentitiesCreateResponseUserIdentity + var unmarshaler = struct { + embed + CreatedAt *core.DateTime `json:"created_at"` + }{ + embed: embed(*u), + } + if err := json.Unmarshal(data, &unmarshaler); err != nil { return err } - *u = UserIdentitiesCreateResponseUserIdentity(value) + *u = UserIdentitiesCreateResponseUserIdentity(unmarshaler.embed) + u.CreatedAt = unmarshaler.CreatedAt.Time() u._rawJSON = json.RawMessage(data) return nil } +func (u *UserIdentitiesCreateResponseUserIdentity) MarshalJSON() ([]byte, error) { + type embed UserIdentitiesCreateResponseUserIdentity + var marshaler = struct { + embed + CreatedAt *core.DateTime `json:"created_at"` + }{ + embed: embed(*u), + CreatedAt: core.NewDateTime(u.CreatedAt), + } + return json.Marshal(marshaler) +} + func (u *UserIdentitiesCreateResponseUserIdentity) String() string { if len(u._rawJSON) > 0 { if value, err := core.StringifyJSON(u._rawJSON); err == nil { @@ -4646,7 +4990,7 @@ func (u *UserIdentitiesCreateResponseUserIdentity) String() string { } type UserIdentitiesGetRequestUserIdentityId struct { - UserIdentityId string `json:"user_identity_id"` + UserIdentityId string `json:"user_identity_id" url:"user_identity_id"` _rawJSON json.RawMessage } @@ -4675,7 +5019,7 @@ func (u *UserIdentitiesGetRequestUserIdentityId) String() string { } type UserIdentitiesGetRequestUserIdentityKey struct { - UserIdentityKey string `json:"user_identity_key"` + UserIdentityKey string `json:"user_identity_key" url:"user_identity_key"` _rawJSON json.RawMessage } @@ -4704,29 +5048,47 @@ func (u *UserIdentitiesGetRequestUserIdentityKey) String() string { } type UserIdentitiesGetResponseUserIdentity struct { - UserIdentityId string `json:"user_identity_id"` - UserIdentityKey *string `json:"user_identity_key,omitempty"` - EmailAddress *string `json:"email_address,omitempty"` - PhoneNumber *string `json:"phone_number,omitempty"` - DisplayName string `json:"display_name"` - FullName *string `json:"full_name,omitempty"` - CreatedAt time.Time `json:"created_at"` - WorkspaceId string `json:"workspace_id"` + UserIdentityId string `json:"user_identity_id" url:"user_identity_id"` + UserIdentityKey *string `json:"user_identity_key,omitempty" url:"user_identity_key,omitempty"` + EmailAddress *string `json:"email_address,omitempty" url:"email_address,omitempty"` + PhoneNumber *string `json:"phone_number,omitempty" url:"phone_number,omitempty"` + DisplayName string `json:"display_name" url:"display_name"` + FullName *string `json:"full_name,omitempty" url:"full_name,omitempty"` + CreatedAt time.Time `json:"created_at" url:"created_at"` + WorkspaceId string `json:"workspace_id" url:"workspace_id"` _rawJSON json.RawMessage } func (u *UserIdentitiesGetResponseUserIdentity) UnmarshalJSON(data []byte) error { - type unmarshaler UserIdentitiesGetResponseUserIdentity - var value unmarshaler - if err := json.Unmarshal(data, &value); err != nil { + type embed UserIdentitiesGetResponseUserIdentity + var unmarshaler = struct { + embed + CreatedAt *core.DateTime `json:"created_at"` + }{ + embed: embed(*u), + } + if err := json.Unmarshal(data, &unmarshaler); err != nil { return err } - *u = UserIdentitiesGetResponseUserIdentity(value) + *u = UserIdentitiesGetResponseUserIdentity(unmarshaler.embed) + u.CreatedAt = unmarshaler.CreatedAt.Time() u._rawJSON = json.RawMessage(data) return nil } +func (u *UserIdentitiesGetResponseUserIdentity) MarshalJSON() ([]byte, error) { + type embed UserIdentitiesGetResponseUserIdentity + var marshaler = struct { + embed + CreatedAt *core.DateTime `json:"created_at"` + }{ + embed: embed(*u), + CreatedAt: core.NewDateTime(u.CreatedAt), + } + return json.Marshal(marshaler) +} + func (u *UserIdentitiesGetResponseUserIdentity) String() string { if len(u._rawJSON) > 0 { if value, err := core.StringifyJSON(u._rawJSON); err == nil { @@ -4740,29 +5102,47 @@ func (u *UserIdentitiesGetResponseUserIdentity) String() string { } type UserIdentitiesListResponseUserIdentitiesItem struct { - UserIdentityId string `json:"user_identity_id"` - UserIdentityKey *string `json:"user_identity_key,omitempty"` - EmailAddress *string `json:"email_address,omitempty"` - PhoneNumber *string `json:"phone_number,omitempty"` - DisplayName string `json:"display_name"` - FullName *string `json:"full_name,omitempty"` - CreatedAt time.Time `json:"created_at"` - WorkspaceId string `json:"workspace_id"` + UserIdentityId string `json:"user_identity_id" url:"user_identity_id"` + UserIdentityKey *string `json:"user_identity_key,omitempty" url:"user_identity_key,omitempty"` + EmailAddress *string `json:"email_address,omitempty" url:"email_address,omitempty"` + PhoneNumber *string `json:"phone_number,omitempty" url:"phone_number,omitempty"` + DisplayName string `json:"display_name" url:"display_name"` + FullName *string `json:"full_name,omitempty" url:"full_name,omitempty"` + CreatedAt time.Time `json:"created_at" url:"created_at"` + WorkspaceId string `json:"workspace_id" url:"workspace_id"` _rawJSON json.RawMessage } func (u *UserIdentitiesListResponseUserIdentitiesItem) UnmarshalJSON(data []byte) error { - type unmarshaler UserIdentitiesListResponseUserIdentitiesItem - var value unmarshaler - if err := json.Unmarshal(data, &value); err != nil { + type embed UserIdentitiesListResponseUserIdentitiesItem + var unmarshaler = struct { + embed + CreatedAt *core.DateTime `json:"created_at"` + }{ + embed: embed(*u), + } + if err := json.Unmarshal(data, &unmarshaler); err != nil { return err } - *u = UserIdentitiesListResponseUserIdentitiesItem(value) + *u = UserIdentitiesListResponseUserIdentitiesItem(unmarshaler.embed) + u.CreatedAt = unmarshaler.CreatedAt.Time() u._rawJSON = json.RawMessage(data) return nil } +func (u *UserIdentitiesListResponseUserIdentitiesItem) MarshalJSON() ([]byte, error) { + type embed UserIdentitiesListResponseUserIdentitiesItem + var marshaler = struct { + embed + CreatedAt *core.DateTime `json:"created_at"` + }{ + embed: embed(*u), + CreatedAt: core.NewDateTime(u.CreatedAt), + } + return json.Marshal(marshaler) +} + func (u *UserIdentitiesListResponseUserIdentitiesItem) String() string { if len(u._rawJSON) > 0 { if value, err := core.StringifyJSON(u._rawJSON); err == nil { diff --git a/user_identities.go b/user_identities.go index f5d726c..1dedc75 100644 --- a/user_identities.go +++ b/user_identities.go @@ -9,50 +9,54 @@ import ( ) type UserIdentitiesAddAcsUserRequest struct { - UserIdentityId string `json:"user_identity_id"` - AcsUserId string `json:"acs_user_id"` + UserIdentityId string `json:"user_identity_id" url:"user_identity_id"` + AcsUserId string `json:"acs_user_id" url:"acs_user_id"` } type UserIdentitiesCreateRequest struct { - UserIdentityKey *string `json:"user_identity_key,omitempty"` - EmailAddress *string `json:"email_address,omitempty"` - PhoneNumber *string `json:"phone_number,omitempty"` - FullName *string `json:"full_name,omitempty"` + UserIdentityKey *string `json:"user_identity_key,omitempty" url:"user_identity_key,omitempty"` + EmailAddress *string `json:"email_address,omitempty" url:"email_address,omitempty"` + PhoneNumber *string `json:"phone_number,omitempty" url:"phone_number,omitempty"` + FullName *string `json:"full_name,omitempty" url:"full_name,omitempty"` } type UserIdentitiesDeleteRequest struct { - UserIdentityId string `json:"user_identity_id"` + UserIdentityId string `json:"user_identity_id" url:"user_identity_id"` } type UserIdentitiesGrantAccessToDeviceRequest struct { - UserIdentityId string `json:"user_identity_id"` - DeviceId string `json:"device_id"` + UserIdentityId string `json:"user_identity_id" url:"user_identity_id"` + DeviceId string `json:"device_id" url:"device_id"` +} + +type UserIdentitiesListRequest struct { + CredentialManagerAcsSystemId *string `json:"credential_manager_acs_system_id,omitempty" url:"credential_manager_acs_system_id,omitempty"` } type UserIdentitiesListAccessibleDevicesRequest struct { - UserIdentityId string `json:"user_identity_id"` + UserIdentityId string `json:"user_identity_id" url:"user_identity_id"` } type UserIdentitiesListAcsSystemsRequest struct { - UserIdentityId string `json:"user_identity_id"` + UserIdentityId string `json:"user_identity_id" url:"user_identity_id"` } type UserIdentitiesListAcsUsersRequest struct { - UserIdentityId string `json:"user_identity_id"` + UserIdentityId string `json:"user_identity_id" url:"user_identity_id"` } type UserIdentitiesRemoveAcsUserRequest struct { - UserIdentityId string `json:"user_identity_id"` - AcsUserId string `json:"acs_user_id"` + UserIdentityId string `json:"user_identity_id" url:"user_identity_id"` + AcsUserId string `json:"acs_user_id" url:"acs_user_id"` } type UserIdentitiesRevokeAccessToDeviceRequest struct { - UserIdentityId string `json:"user_identity_id"` - DeviceId string `json:"device_id"` + UserIdentityId string `json:"user_identity_id" url:"user_identity_id"` + DeviceId string `json:"device_id" url:"device_id"` } type UserIdentitiesAddAcsUserResponse struct { - Ok bool `json:"ok"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -81,8 +85,8 @@ func (u *UserIdentitiesAddAcsUserResponse) String() string { } type UserIdentitiesCreateResponse struct { - UserIdentity *UserIdentitiesCreateResponseUserIdentity `json:"user_identity,omitempty"` - Ok bool `json:"ok"` + UserIdentity *UserIdentitiesCreateResponseUserIdentity `json:"user_identity,omitempty" url:"user_identity,omitempty"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -111,7 +115,7 @@ func (u *UserIdentitiesCreateResponse) String() string { } type UserIdentitiesDeleteResponse struct { - Ok bool `json:"ok"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -197,8 +201,8 @@ func (u *UserIdentitiesGetRequest) Accept(visitor UserIdentitiesGetRequestVisito } type UserIdentitiesGetResponse struct { - UserIdentity *UserIdentitiesGetResponseUserIdentity `json:"user_identity,omitempty"` - Ok bool `json:"ok"` + UserIdentity *UserIdentitiesGetResponseUserIdentity `json:"user_identity,omitempty" url:"user_identity,omitempty"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -227,7 +231,7 @@ func (u *UserIdentitiesGetResponse) String() string { } type UserIdentitiesGrantAccessToDeviceResponse struct { - Ok bool `json:"ok"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -256,8 +260,8 @@ func (u *UserIdentitiesGrantAccessToDeviceResponse) String() string { } type UserIdentitiesListAccessibleDevicesResponse struct { - AccessibleDevices []*Device `json:"accessible_devices,omitempty"` - Ok bool `json:"ok"` + AccessibleDevices []*Device `json:"accessible_devices,omitempty" url:"accessible_devices,omitempty"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -286,8 +290,8 @@ func (u *UserIdentitiesListAccessibleDevicesResponse) String() string { } type UserIdentitiesListAcsSystemsResponse struct { - AcsSystems []*AcsSystem `json:"acs_systems,omitempty"` - Ok bool `json:"ok"` + AcsSystems []*AcsSystem `json:"acs_systems,omitempty" url:"acs_systems,omitempty"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -316,8 +320,8 @@ func (u *UserIdentitiesListAcsSystemsResponse) String() string { } type UserIdentitiesListAcsUsersResponse struct { - AcsUsers []*AcsUser `json:"acs_users,omitempty"` - Ok bool `json:"ok"` + AcsUsers []*AcsUser `json:"acs_users,omitempty" url:"acs_users,omitempty"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -346,8 +350,8 @@ func (u *UserIdentitiesListAcsUsersResponse) String() string { } type UserIdentitiesListResponse struct { - UserIdentities []*UserIdentitiesListResponseUserIdentitiesItem `json:"user_identities,omitempty"` - Ok bool `json:"ok"` + UserIdentities []*UserIdentitiesListResponseUserIdentitiesItem `json:"user_identities,omitempty" url:"user_identities,omitempty"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -376,7 +380,7 @@ func (u *UserIdentitiesListResponse) String() string { } type UserIdentitiesRemoveAcsUserResponse struct { - Ok bool `json:"ok"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -405,7 +409,7 @@ func (u *UserIdentitiesRemoveAcsUserResponse) String() string { } type UserIdentitiesRevokeAccessToDeviceResponse struct { - Ok bool `json:"ok"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -434,7 +438,7 @@ func (u *UserIdentitiesRevokeAccessToDeviceResponse) String() string { } type UserIdentitiesUpdateResponse struct { - Ok bool `json:"ok"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -463,9 +467,9 @@ func (u *UserIdentitiesUpdateResponse) String() string { } type UserIdentitiesUpdateRequest struct { - UserIdentityId string `json:"user_identity_id"` - UserIdentityKey *string `json:"user_identity_key,omitempty"` - EmailAddress *string `json:"email_address,omitempty"` - PhoneNumber *string `json:"phone_number,omitempty"` - FullName *string `json:"full_name,omitempty"` + UserIdentityId string `json:"user_identity_id" url:"user_identity_id"` + UserIdentityKey *string `json:"user_identity_key,omitempty" url:"user_identity_key,omitempty"` + EmailAddress *string `json:"email_address,omitempty" url:"email_address,omitempty"` + PhoneNumber *string `json:"phone_number,omitempty" url:"phone_number,omitempty"` + FullName *string `json:"full_name,omitempty" url:"full_name,omitempty"` } diff --git a/useridentities/client/client.go b/useridentities/client/client.go index 1d24f2a..67d3be6 100644 --- a/useridentities/client/client.go +++ b/useridentities/client/client.go @@ -9,6 +9,7 @@ import ( errors "errors" seamapigo "github.com/seamapi/go" core "github.com/seamapi/go/core" + option "github.com/seamapi/go/option" enrollmentautomations "github.com/seamapi/go/useridentities/enrollmentautomations" io "io" http "net/http" @@ -22,26 +23,39 @@ type Client struct { EnrollmentAutomations *enrollmentautomations.Client } -func NewClient(opts ...core.ClientOption) *Client { - options := core.NewClientOptions() - for _, opt := range opts { - opt(options) - } +func NewClient(opts ...option.RequestOption) *Client { + options := core.NewRequestOptions(opts...) return &Client{ - baseURL: options.BaseURL, - caller: core.NewCaller(options.HTTPClient), + baseURL: options.BaseURL, + caller: core.NewCaller( + &core.CallerParams{ + Client: options.HTTPClient, + MaxAttempts: options.MaxAttempts, + }, + ), header: options.ToHeader(), EnrollmentAutomations: enrollmentautomations.NewClient(opts...), } } -func (c *Client) AddAcsUser(ctx context.Context, request *seamapigo.UserIdentitiesAddAcsUserRequest) (*seamapigo.UserIdentitiesAddAcsUserResponse, error) { +func (c *Client) AddAcsUser( + ctx context.Context, + request *seamapigo.UserIdentitiesAddAcsUserRequest, + opts ...option.RequestOption, +) (*seamapigo.UserIdentitiesAddAcsUserResponse, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "user_identities/add_acs_user" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -74,7 +88,9 @@ func (c *Client) AddAcsUser(ctx context.Context, request *seamapigo.UserIdentiti &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -85,13 +101,24 @@ func (c *Client) AddAcsUser(ctx context.Context, request *seamapigo.UserIdentiti return response, nil } -func (c *Client) Create(ctx context.Context, request *seamapigo.UserIdentitiesCreateRequest) (*seamapigo.UserIdentitiesCreateResponse, error) { +func (c *Client) Create( + ctx context.Context, + request *seamapigo.UserIdentitiesCreateRequest, + opts ...option.RequestOption, +) (*seamapigo.UserIdentitiesCreateResponse, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "user_identities/create" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -124,7 +151,9 @@ func (c *Client) Create(ctx context.Context, request *seamapigo.UserIdentitiesCr &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -135,13 +164,24 @@ func (c *Client) Create(ctx context.Context, request *seamapigo.UserIdentitiesCr return response, nil } -func (c *Client) Delete(ctx context.Context, request *seamapigo.UserIdentitiesDeleteRequest) (*seamapigo.UserIdentitiesDeleteResponse, error) { +func (c *Client) Delete( + ctx context.Context, + request *seamapigo.UserIdentitiesDeleteRequest, + opts ...option.RequestOption, +) (*seamapigo.UserIdentitiesDeleteResponse, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "user_identities/delete" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -174,7 +214,9 @@ func (c *Client) Delete(ctx context.Context, request *seamapigo.UserIdentitiesDe &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -185,13 +227,24 @@ func (c *Client) Delete(ctx context.Context, request *seamapigo.UserIdentitiesDe return response, nil } -func (c *Client) Get(ctx context.Context, request *seamapigo.UserIdentitiesGetRequest) (*seamapigo.UserIdentitiesGetResponse, error) { +func (c *Client) Get( + ctx context.Context, + request *seamapigo.UserIdentitiesGetRequest, + opts ...option.RequestOption, +) (*seamapigo.UserIdentitiesGetResponse, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "user_identities/get" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -224,7 +277,9 @@ func (c *Client) Get(ctx context.Context, request *seamapigo.UserIdentitiesGetRe &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -235,13 +290,24 @@ func (c *Client) Get(ctx context.Context, request *seamapigo.UserIdentitiesGetRe return response, nil } -func (c *Client) GrantAccessToDevice(ctx context.Context, request *seamapigo.UserIdentitiesGrantAccessToDeviceRequest) (*seamapigo.UserIdentitiesGrantAccessToDeviceResponse, error) { +func (c *Client) GrantAccessToDevice( + ctx context.Context, + request *seamapigo.UserIdentitiesGrantAccessToDeviceRequest, + opts ...option.RequestOption, +) (*seamapigo.UserIdentitiesGrantAccessToDeviceResponse, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "user_identities/grant_access_to_device" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -274,7 +340,9 @@ func (c *Client) GrantAccessToDevice(ctx context.Context, request *seamapigo.Use &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -285,13 +353,24 @@ func (c *Client) GrantAccessToDevice(ctx context.Context, request *seamapigo.Use return response, nil } -func (c *Client) List(ctx context.Context) ([]*seamapigo.UserIdentitiesListResponseUserIdentitiesItem, error) { +func (c *Client) List( + ctx context.Context, + request *seamapigo.UserIdentitiesListRequest, + opts ...option.RequestOption, +) ([]*seamapigo.UserIdentitiesListResponseUserIdentitiesItem, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "user_identities/list" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -324,7 +403,10 @@ func (c *Client) List(ctx context.Context) ([]*seamapigo.UserIdentitiesListRespo &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, + Request: request, Response: &response, ErrorDecoder: errorDecoder, }, @@ -334,13 +416,24 @@ func (c *Client) List(ctx context.Context) ([]*seamapigo.UserIdentitiesListRespo return response.UserIdentities, nil } -func (c *Client) ListAccessibleDevices(ctx context.Context, request *seamapigo.UserIdentitiesListAccessibleDevicesRequest) (*seamapigo.UserIdentitiesListAccessibleDevicesResponse, error) { +func (c *Client) ListAccessibleDevices( + ctx context.Context, + request *seamapigo.UserIdentitiesListAccessibleDevicesRequest, + opts ...option.RequestOption, +) (*seamapigo.UserIdentitiesListAccessibleDevicesResponse, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "user_identities/list_accessible_devices" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -373,7 +466,9 @@ func (c *Client) ListAccessibleDevices(ctx context.Context, request *seamapigo.U &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -384,13 +479,24 @@ func (c *Client) ListAccessibleDevices(ctx context.Context, request *seamapigo.U return response, nil } -func (c *Client) ListAcsSystems(ctx context.Context, request *seamapigo.UserIdentitiesListAcsSystemsRequest) (*seamapigo.UserIdentitiesListAcsSystemsResponse, error) { +func (c *Client) ListAcsSystems( + ctx context.Context, + request *seamapigo.UserIdentitiesListAcsSystemsRequest, + opts ...option.RequestOption, +) (*seamapigo.UserIdentitiesListAcsSystemsResponse, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "user_identities/list_acs_systems" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -423,7 +529,9 @@ func (c *Client) ListAcsSystems(ctx context.Context, request *seamapigo.UserIden &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -434,13 +542,24 @@ func (c *Client) ListAcsSystems(ctx context.Context, request *seamapigo.UserIden return response, nil } -func (c *Client) ListAcsUsers(ctx context.Context, request *seamapigo.UserIdentitiesListAcsUsersRequest) (*seamapigo.UserIdentitiesListAcsUsersResponse, error) { +func (c *Client) ListAcsUsers( + ctx context.Context, + request *seamapigo.UserIdentitiesListAcsUsersRequest, + opts ...option.RequestOption, +) (*seamapigo.UserIdentitiesListAcsUsersResponse, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "user_identities/list_acs_users" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -473,7 +592,9 @@ func (c *Client) ListAcsUsers(ctx context.Context, request *seamapigo.UserIdenti &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -484,13 +605,24 @@ func (c *Client) ListAcsUsers(ctx context.Context, request *seamapigo.UserIdenti return response, nil } -func (c *Client) RemoveAcsUser(ctx context.Context, request *seamapigo.UserIdentitiesRemoveAcsUserRequest) (*seamapigo.UserIdentitiesRemoveAcsUserResponse, error) { +func (c *Client) RemoveAcsUser( + ctx context.Context, + request *seamapigo.UserIdentitiesRemoveAcsUserRequest, + opts ...option.RequestOption, +) (*seamapigo.UserIdentitiesRemoveAcsUserResponse, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "user_identities/remove_acs_user" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -523,7 +655,9 @@ func (c *Client) RemoveAcsUser(ctx context.Context, request *seamapigo.UserIdent &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -534,13 +668,24 @@ func (c *Client) RemoveAcsUser(ctx context.Context, request *seamapigo.UserIdent return response, nil } -func (c *Client) RevokeAccessToDevice(ctx context.Context, request *seamapigo.UserIdentitiesRevokeAccessToDeviceRequest) (*seamapigo.UserIdentitiesRevokeAccessToDeviceResponse, error) { +func (c *Client) RevokeAccessToDevice( + ctx context.Context, + request *seamapigo.UserIdentitiesRevokeAccessToDeviceRequest, + opts ...option.RequestOption, +) (*seamapigo.UserIdentitiesRevokeAccessToDeviceResponse, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "user_identities/revoke_access_to_device" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -573,7 +718,9 @@ func (c *Client) RevokeAccessToDevice(ctx context.Context, request *seamapigo.Us &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -584,13 +731,24 @@ func (c *Client) RevokeAccessToDevice(ctx context.Context, request *seamapigo.Us return response, nil } -func (c *Client) Update(ctx context.Context, request *seamapigo.UserIdentitiesUpdateRequest) (*seamapigo.UserIdentitiesUpdateResponse, error) { +func (c *Client) Update( + ctx context.Context, + request *seamapigo.UserIdentitiesUpdateRequest, + opts ...option.RequestOption, +) (*seamapigo.UserIdentitiesUpdateResponse, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "user_identities/update" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -623,7 +781,9 @@ func (c *Client) Update(ctx context.Context, request *seamapigo.UserIdentitiesUp &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, diff --git a/useridentities/enrollment_automations.go b/useridentities/enrollment_automations.go index 9965c95..47ae147 100644 --- a/useridentities/enrollment_automations.go +++ b/useridentities/enrollment_automations.go @@ -10,27 +10,27 @@ import ( ) type EnrollmentAutomationsDeleteRequest struct { - EnrollmentAutomationId string `json:"enrollment_automation_id"` + EnrollmentAutomationId string `json:"enrollment_automation_id" url:"enrollment_automation_id"` } type EnrollmentAutomationsGetRequest struct { - EnrollmentAutomationId string `json:"enrollment_automation_id"` + EnrollmentAutomationId string `json:"enrollment_automation_id" url:"enrollment_automation_id"` } type EnrollmentAutomationsLaunchRequest struct { - UserIdentityId string `json:"user_identity_id"` - CredentialManagerAcsSystemId string `json:"credential_manager_acs_system_id"` - AcsCredentialPoolId *string `json:"acs_credential_pool_id,omitempty"` - CreateCredentialManagerUser *bool `json:"create_credential_manager_user,omitempty"` - CredentialManagerAcsUserId *string `json:"credential_manager_acs_user_id,omitempty"` + UserIdentityId string `json:"user_identity_id" url:"user_identity_id"` + CredentialManagerAcsSystemId string `json:"credential_manager_acs_system_id" url:"credential_manager_acs_system_id"` + AcsCredentialPoolId *string `json:"acs_credential_pool_id,omitempty" url:"acs_credential_pool_id,omitempty"` + CreateCredentialManagerUser *bool `json:"create_credential_manager_user,omitempty" url:"create_credential_manager_user,omitempty"` + CredentialManagerAcsUserId *string `json:"credential_manager_acs_user_id,omitempty" url:"credential_manager_acs_user_id,omitempty"` } type EnrollmentAutomationsListRequest struct { - UserIdentityId string `json:"user_identity_id"` + UserIdentityId string `json:"user_identity_id" url:"user_identity_id"` } type EnrollmentAutomationsDeleteResponse struct { - Ok bool `json:"ok"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -59,8 +59,8 @@ func (e *EnrollmentAutomationsDeleteResponse) String() string { } type EnrollmentAutomationsGetResponse struct { - EnrollmentAutomation *seamapigo.EnrollmentAutomation `json:"enrollment_automation,omitempty"` - Ok bool `json:"ok"` + EnrollmentAutomation *seamapigo.EnrollmentAutomation `json:"enrollment_automation,omitempty" url:"enrollment_automation,omitempty"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -89,8 +89,8 @@ func (e *EnrollmentAutomationsGetResponse) String() string { } type EnrollmentAutomationsLaunchResponse struct { - EnrollmentAutomation *EnrollmentAutomationsLaunchResponseEnrollmentAutomation `json:"enrollment_automation,omitempty"` - Ok bool `json:"ok"` + EnrollmentAutomation *EnrollmentAutomationsLaunchResponseEnrollmentAutomation `json:"enrollment_automation,omitempty" url:"enrollment_automation,omitempty"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -119,8 +119,8 @@ func (e *EnrollmentAutomationsLaunchResponse) String() string { } type EnrollmentAutomationsListResponse struct { - EnrollmentAutomations []*seamapigo.EnrollmentAutomation `json:"enrollment_automations,omitempty"` - Ok bool `json:"ok"` + EnrollmentAutomations []*seamapigo.EnrollmentAutomation `json:"enrollment_automations,omitempty" url:"enrollment_automations,omitempty"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } diff --git a/useridentities/enrollmentautomations/client.go b/useridentities/enrollmentautomations/client.go index 7579b90..586206a 100644 --- a/useridentities/enrollmentautomations/client.go +++ b/useridentities/enrollmentautomations/client.go @@ -9,6 +9,7 @@ import ( errors "errors" seamapigo "github.com/seamapi/go" core "github.com/seamapi/go/core" + option "github.com/seamapi/go/option" useridentities "github.com/seamapi/go/useridentities" io "io" http "net/http" @@ -20,25 +21,38 @@ type Client struct { header http.Header } -func NewClient(opts ...core.ClientOption) *Client { - options := core.NewClientOptions() - for _, opt := range opts { - opt(options) - } +func NewClient(opts ...option.RequestOption) *Client { + options := core.NewRequestOptions(opts...) return &Client{ baseURL: options.BaseURL, - caller: core.NewCaller(options.HTTPClient), - header: options.ToHeader(), + caller: core.NewCaller( + &core.CallerParams{ + Client: options.HTTPClient, + MaxAttempts: options.MaxAttempts, + }, + ), + header: options.ToHeader(), } } -func (c *Client) Delete(ctx context.Context, request *useridentities.EnrollmentAutomationsDeleteRequest) (*useridentities.EnrollmentAutomationsDeleteResponse, error) { +func (c *Client) Delete( + ctx context.Context, + request *useridentities.EnrollmentAutomationsDeleteRequest, + opts ...option.RequestOption, +) (*useridentities.EnrollmentAutomationsDeleteResponse, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "user_identities/enrollment_automations/delete" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -71,7 +85,9 @@ func (c *Client) Delete(ctx context.Context, request *useridentities.EnrollmentA &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -82,13 +98,24 @@ func (c *Client) Delete(ctx context.Context, request *useridentities.EnrollmentA return response, nil } -func (c *Client) Get(ctx context.Context, request *useridentities.EnrollmentAutomationsGetRequest) (*useridentities.EnrollmentAutomationsGetResponse, error) { +func (c *Client) Get( + ctx context.Context, + request *useridentities.EnrollmentAutomationsGetRequest, + opts ...option.RequestOption, +) (*useridentities.EnrollmentAutomationsGetResponse, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "user_identities/enrollment_automations/get" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -121,7 +148,9 @@ func (c *Client) Get(ctx context.Context, request *useridentities.EnrollmentAuto &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -132,13 +161,24 @@ func (c *Client) Get(ctx context.Context, request *useridentities.EnrollmentAuto return response, nil } -func (c *Client) Launch(ctx context.Context, request *useridentities.EnrollmentAutomationsLaunchRequest) (*useridentities.EnrollmentAutomationsLaunchResponse, error) { +func (c *Client) Launch( + ctx context.Context, + request *useridentities.EnrollmentAutomationsLaunchRequest, + opts ...option.RequestOption, +) (*useridentities.EnrollmentAutomationsLaunchResponse, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "user_identities/enrollment_automations/launch" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -171,7 +211,9 @@ func (c *Client) Launch(ctx context.Context, request *useridentities.EnrollmentA &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -182,13 +224,24 @@ func (c *Client) Launch(ctx context.Context, request *useridentities.EnrollmentA return response, nil } -func (c *Client) List(ctx context.Context, request *useridentities.EnrollmentAutomationsListRequest) (*useridentities.EnrollmentAutomationsListResponse, error) { +func (c *Client) List( + ctx context.Context, + request *useridentities.EnrollmentAutomationsListRequest, + opts ...option.RequestOption, +) (*useridentities.EnrollmentAutomationsListResponse, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "user_identities/enrollment_automations/list" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -221,7 +274,9 @@ func (c *Client) List(ctx context.Context, request *useridentities.EnrollmentAut &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, diff --git a/useridentities/types.go b/useridentities/types.go index 3fc211c..19a9f0a 100644 --- a/useridentities/types.go +++ b/useridentities/types.go @@ -10,27 +10,45 @@ import ( ) type EnrollmentAutomationsLaunchResponseEnrollmentAutomation struct { - AcsCredentialProvisioningAutomationId string `json:"acs_credential_provisioning_automation_id"` - CredentialManagerAcsSystemId string `json:"credential_manager_acs_system_id"` - UserIdentityId string `json:"user_identity_id"` - CreatedAt time.Time `json:"created_at"` - WorkspaceId string `json:"workspace_id"` - EnrollmentAutomationId string `json:"enrollment_automation_id"` + AcsCredentialProvisioningAutomationId string `json:"acs_credential_provisioning_automation_id" url:"acs_credential_provisioning_automation_id"` + CredentialManagerAcsSystemId string `json:"credential_manager_acs_system_id" url:"credential_manager_acs_system_id"` + UserIdentityId string `json:"user_identity_id" url:"user_identity_id"` + CreatedAt time.Time `json:"created_at" url:"created_at"` + WorkspaceId string `json:"workspace_id" url:"workspace_id"` + EnrollmentAutomationId string `json:"enrollment_automation_id" url:"enrollment_automation_id"` _rawJSON json.RawMessage } func (e *EnrollmentAutomationsLaunchResponseEnrollmentAutomation) UnmarshalJSON(data []byte) error { - type unmarshaler EnrollmentAutomationsLaunchResponseEnrollmentAutomation - var value unmarshaler - if err := json.Unmarshal(data, &value); err != nil { + type embed EnrollmentAutomationsLaunchResponseEnrollmentAutomation + var unmarshaler = struct { + embed + CreatedAt *core.DateTime `json:"created_at"` + }{ + embed: embed(*e), + } + if err := json.Unmarshal(data, &unmarshaler); err != nil { return err } - *e = EnrollmentAutomationsLaunchResponseEnrollmentAutomation(value) + *e = EnrollmentAutomationsLaunchResponseEnrollmentAutomation(unmarshaler.embed) + e.CreatedAt = unmarshaler.CreatedAt.Time() e._rawJSON = json.RawMessage(data) return nil } +func (e *EnrollmentAutomationsLaunchResponseEnrollmentAutomation) MarshalJSON() ([]byte, error) { + type embed EnrollmentAutomationsLaunchResponseEnrollmentAutomation + var marshaler = struct { + embed + CreatedAt *core.DateTime `json:"created_at"` + }{ + embed: embed(*e), + CreatedAt: core.NewDateTime(e.CreatedAt), + } + return json.Marshal(marshaler) +} + func (e *EnrollmentAutomationsLaunchResponseEnrollmentAutomation) String() string { if len(e._rawJSON) > 0 { if value, err := core.StringifyJSON(e._rawJSON); err == nil { diff --git a/webhooks.go b/webhooks.go index e588a98..d1ad36f 100644 --- a/webhooks.go +++ b/webhooks.go @@ -9,21 +9,21 @@ import ( ) type WebhooksCreateRequest struct { - Url string `json:"url"` - EventTypes []string `json:"event_types,omitempty"` + Url string `json:"url" url:"url"` + EventTypes []string `json:"event_types,omitempty" url:"event_types,omitempty"` } type WebhooksDeleteRequest struct { - WebhookId string `json:"webhook_id"` + WebhookId string `json:"webhook_id" url:"webhook_id"` } type WebhooksGetRequest struct { - WebhookId string `json:"webhook_id"` + WebhookId string `json:"webhook_id" url:"webhook_id"` } type WebhooksCreateResponse struct { - Webhook *Webhook `json:"webhook,omitempty"` - Ok bool `json:"ok"` + Webhook *Webhook `json:"webhook,omitempty" url:"webhook,omitempty"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -52,7 +52,7 @@ func (w *WebhooksCreateResponse) String() string { } type WebhooksDeleteResponse struct { - Ok bool `json:"ok"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -81,8 +81,8 @@ func (w *WebhooksDeleteResponse) String() string { } type WebhooksGetResponse struct { - Webhook *Webhook `json:"webhook,omitempty"` - Ok bool `json:"ok"` + Webhook *Webhook `json:"webhook,omitempty" url:"webhook,omitempty"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -111,8 +111,8 @@ func (w *WebhooksGetResponse) String() string { } type WebhooksListResponse struct { - Webhooks []*Webhook `json:"webhooks,omitempty"` - Ok bool `json:"ok"` + Webhooks []*Webhook `json:"webhooks,omitempty" url:"webhooks,omitempty"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -141,7 +141,7 @@ func (w *WebhooksListResponse) String() string { } type WebhooksUpdateResponse struct { - Ok bool `json:"ok"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -170,6 +170,6 @@ func (w *WebhooksUpdateResponse) String() string { } type WebhooksUpdateRequest struct { - WebhookId string `json:"webhook_id"` - EventTypes []string `json:"event_types,omitempty"` + WebhookId string `json:"webhook_id" url:"webhook_id"` + EventTypes []string `json:"event_types,omitempty" url:"event_types,omitempty"` } diff --git a/webhooks/client.go b/webhooks/client.go index c7add51..f7e9eb2 100644 --- a/webhooks/client.go +++ b/webhooks/client.go @@ -9,6 +9,7 @@ import ( errors "errors" seamapigo "github.com/seamapi/go" core "github.com/seamapi/go/core" + option "github.com/seamapi/go/option" io "io" http "net/http" ) @@ -19,25 +20,38 @@ type Client struct { header http.Header } -func NewClient(opts ...core.ClientOption) *Client { - options := core.NewClientOptions() - for _, opt := range opts { - opt(options) - } +func NewClient(opts ...option.RequestOption) *Client { + options := core.NewRequestOptions(opts...) return &Client{ baseURL: options.BaseURL, - caller: core.NewCaller(options.HTTPClient), - header: options.ToHeader(), + caller: core.NewCaller( + &core.CallerParams{ + Client: options.HTTPClient, + MaxAttempts: options.MaxAttempts, + }, + ), + header: options.ToHeader(), } } -func (c *Client) Create(ctx context.Context, request *seamapigo.WebhooksCreateRequest) (*seamapigo.Webhook, error) { +func (c *Client) Create( + ctx context.Context, + request *seamapigo.WebhooksCreateRequest, + opts ...option.RequestOption, +) (*seamapigo.Webhook, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "webhooks/create" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -70,7 +84,9 @@ func (c *Client) Create(ctx context.Context, request *seamapigo.WebhooksCreateRe &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -81,13 +97,24 @@ func (c *Client) Create(ctx context.Context, request *seamapigo.WebhooksCreateRe return response.Webhook, nil } -func (c *Client) Delete(ctx context.Context, request *seamapigo.WebhooksDeleteRequest) (*seamapigo.WebhooksDeleteResponse, error) { +func (c *Client) Delete( + ctx context.Context, + request *seamapigo.WebhooksDeleteRequest, + opts ...option.RequestOption, +) (*seamapigo.WebhooksDeleteResponse, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "webhooks/delete" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -120,7 +147,9 @@ func (c *Client) Delete(ctx context.Context, request *seamapigo.WebhooksDeleteRe &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -131,13 +160,24 @@ func (c *Client) Delete(ctx context.Context, request *seamapigo.WebhooksDeleteRe return response, nil } -func (c *Client) Get(ctx context.Context, request *seamapigo.WebhooksGetRequest) (*seamapigo.Webhook, error) { +func (c *Client) Get( + ctx context.Context, + request *seamapigo.WebhooksGetRequest, + opts ...option.RequestOption, +) (*seamapigo.Webhook, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "webhooks/get" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -170,7 +210,9 @@ func (c *Client) Get(ctx context.Context, request *seamapigo.WebhooksGetRequest) &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -181,13 +223,23 @@ func (c *Client) Get(ctx context.Context, request *seamapigo.WebhooksGetRequest) return response.Webhook, nil } -func (c *Client) List(ctx context.Context) ([]*seamapigo.Webhook, error) { +func (c *Client) List( + ctx context.Context, + opts ...option.RequestOption, +) ([]*seamapigo.Webhook, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "webhooks/list" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -220,7 +272,9 @@ func (c *Client) List(ctx context.Context) ([]*seamapigo.Webhook, error) { &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Response: &response, ErrorDecoder: errorDecoder, }, @@ -230,13 +284,24 @@ func (c *Client) List(ctx context.Context) ([]*seamapigo.Webhook, error) { return response.Webhooks, nil } -func (c *Client) Update(ctx context.Context, request *seamapigo.WebhooksUpdateRequest) (*seamapigo.WebhooksUpdateResponse, error) { +func (c *Client) Update( + ctx context.Context, + request *seamapigo.WebhooksUpdateRequest, + opts ...option.RequestOption, +) (*seamapigo.WebhooksUpdateResponse, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "webhooks/update" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -269,7 +334,9 @@ func (c *Client) Update(ctx context.Context, request *seamapigo.WebhooksUpdateRe &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, diff --git a/workspaces.go b/workspaces.go index 1655448..0abab6a 100644 --- a/workspaces.go +++ b/workspaces.go @@ -9,17 +9,17 @@ import ( ) type WorkspacesCreateRequest struct { - Name string `json:"name"` + Name string `json:"name" url:"name"` // The name shown inside the connect webview - ConnectPartnerName string `json:"connect_partner_name"` - IsSandbox *bool `json:"is_sandbox,omitempty"` - WebviewPrimaryButtonColor *string `json:"webview_primary_button_color,omitempty"` - WebviewLogoShape *WebviewLogoShape `json:"webview_logo_shape,omitempty"` + ConnectPartnerName string `json:"connect_partner_name" url:"connect_partner_name"` + IsSandbox *bool `json:"is_sandbox,omitempty" url:"is_sandbox,omitempty"` + WebviewPrimaryButtonColor *string `json:"webview_primary_button_color,omitempty" url:"webview_primary_button_color,omitempty"` + WebviewLogoShape *WebviewLogoShape `json:"webview_logo_shape,omitempty" url:"webview_logo_shape,omitempty"` } type WorkspacesCreateResponse struct { - Workspace *Workspace `json:"workspace,omitempty"` - Ok bool `json:"ok"` + Workspace *Workspace `json:"workspace,omitempty" url:"workspace,omitempty"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -48,8 +48,8 @@ func (w *WorkspacesCreateResponse) String() string { } type WorkspacesGetResponse struct { - Workspace *Workspace `json:"workspace,omitempty"` - Ok bool `json:"ok"` + Workspace *Workspace `json:"workspace,omitempty" url:"workspace,omitempty"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -78,8 +78,8 @@ func (w *WorkspacesGetResponse) String() string { } type WorkspacesListResponse struct { - Workspaces []*Workspace `json:"workspaces,omitempty"` - Ok bool `json:"ok"` + Workspaces []*Workspace `json:"workspaces,omitempty" url:"workspaces,omitempty"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } @@ -108,8 +108,8 @@ func (w *WorkspacesListResponse) String() string { } type WorkspacesResetSandboxResponse struct { - ActionAttempt *ActionAttempt `json:"action_attempt,omitempty"` - Ok bool `json:"ok"` + ActionAttempt *ActionAttempt `json:"action_attempt,omitempty" url:"action_attempt,omitempty"` + Ok bool `json:"ok" url:"ok"` _rawJSON json.RawMessage } diff --git a/workspaces/client.go b/workspaces/client.go index 6c74890..a418928 100644 --- a/workspaces/client.go +++ b/workspaces/client.go @@ -9,6 +9,7 @@ import ( errors "errors" seamapigo "github.com/seamapi/go" core "github.com/seamapi/go/core" + option "github.com/seamapi/go/option" io "io" http "net/http" ) @@ -19,25 +20,38 @@ type Client struct { header http.Header } -func NewClient(opts ...core.ClientOption) *Client { - options := core.NewClientOptions() - for _, opt := range opts { - opt(options) - } +func NewClient(opts ...option.RequestOption) *Client { + options := core.NewRequestOptions(opts...) return &Client{ baseURL: options.BaseURL, - caller: core.NewCaller(options.HTTPClient), - header: options.ToHeader(), + caller: core.NewCaller( + &core.CallerParams{ + Client: options.HTTPClient, + MaxAttempts: options.MaxAttempts, + }, + ), + header: options.ToHeader(), } } -func (c *Client) Create(ctx context.Context, request *seamapigo.WorkspacesCreateRequest) (*seamapigo.WorkspacesCreateResponse, error) { +func (c *Client) Create( + ctx context.Context, + request *seamapigo.WorkspacesCreateRequest, + opts ...option.RequestOption, +) (*seamapigo.WorkspacesCreateResponse, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "workspaces/create" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -70,7 +84,9 @@ func (c *Client) Create(ctx context.Context, request *seamapigo.WorkspacesCreate &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Request: request, Response: &response, ErrorDecoder: errorDecoder, @@ -81,13 +97,23 @@ func (c *Client) Create(ctx context.Context, request *seamapigo.WorkspacesCreate return response, nil } -func (c *Client) Get(ctx context.Context) (*seamapigo.Workspace, error) { +func (c *Client) Get( + ctx context.Context, + opts ...option.RequestOption, +) (*seamapigo.Workspace, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "workspaces/get" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -120,7 +146,9 @@ func (c *Client) Get(ctx context.Context) (*seamapigo.Workspace, error) { &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Response: &response, ErrorDecoder: errorDecoder, }, @@ -130,13 +158,23 @@ func (c *Client) Get(ctx context.Context) (*seamapigo.Workspace, error) { return response.Workspace, nil } -func (c *Client) List(ctx context.Context) ([]*seamapigo.Workspace, error) { +func (c *Client) List( + ctx context.Context, + opts ...option.RequestOption, +) ([]*seamapigo.Workspace, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "workspaces/list" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -169,7 +207,9 @@ func (c *Client) List(ctx context.Context) ([]*seamapigo.Workspace, error) { &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Response: &response, ErrorDecoder: errorDecoder, }, @@ -179,13 +219,23 @@ func (c *Client) List(ctx context.Context) ([]*seamapigo.Workspace, error) { return response.Workspaces, nil } -func (c *Client) ResetSandbox(ctx context.Context) (*seamapigo.ActionAttempt, error) { +func (c *Client) ResetSandbox( + ctx context.Context, + opts ...option.RequestOption, +) (*seamapigo.ActionAttempt, error) { + options := core.NewRequestOptions(opts...) + baseURL := "https://connect.getseam.com" if c.baseURL != "" { baseURL = c.baseURL } + if options.BaseURL != "" { + baseURL = options.BaseURL + } endpointURL := baseURL + "/" + "workspaces/reset_sandbox" + headers := core.MergeHeaders(c.header.Clone(), options.ToHeader()) + errorDecoder := func(statusCode int, body io.Reader) error { raw, err := io.ReadAll(body) if err != nil { @@ -218,7 +268,9 @@ func (c *Client) ResetSandbox(ctx context.Context) (*seamapigo.ActionAttempt, er &core.CallParams{ URL: endpointURL, Method: http.MethodPost, - Headers: c.header, + MaxAttempts: options.MaxAttempts, + Headers: headers, + Client: options.HTTPClient, Response: &response, ErrorDecoder: errorDecoder, },