From b070fee783de20f9cde5ab6b796358a4e6aaacc9 Mon Sep 17 00:00:00 2001 From: chronark Date: Sat, 11 May 2024 17:57:59 +0200 Subject: [PATCH] feat: run --- .gitattributes | 2 + .gitignore | 1 + .speakeasy/gen.lock | 2 +- USAGE.md | 33 + apis.go | 368 +++++ codeSamples.yaml | 66 +- docs/models/components/authorization.md | 10 + docs/models/components/code.md | 27 + docs/models/components/interval.md | 11 + docs/models/components/key.md | 23 + docs/models/components/permissions.md | 9 + docs/models/components/ratelimit.md | 13 + docs/models/components/refill.md | 12 + docs/models/components/security.md | 8 + docs/models/components/type.md | 14 + .../components/v1keysverifykeyrequest.md | 11 + .../v1keysverifykeyrequestratelimit.md | 8 + .../components/v1keysverifykeyresponse.md | 19 + .../v1keysverifykeyresponseratelimit.md | 12 + docs/models/operations/code.md | 23 + .../models/operations/createapirequestbody.md | 8 + .../operations/createapiresponsebody.md | 10 + .../models/operations/createkeyrequestbody.md | 20 + .../operations/createkeyresponsebody.md | 11 + .../models/operations/deleteapirequestbody.md | 8 + .../operations/deleteapiresponsebody.md | 9 + .../models/operations/deletekeyrequestbody.md | 8 + .../operations/deletekeyresponsebody.md | 9 + .../deprecatedcreatekeyratelimit.md | 13 + .../deprecatedcreatekeyrequestbody.md | 16 + .../deprecatedcreatekeyresponsebody.md | 11 + .../operations/deprecatedcreatekeytype.md | 14 + .../operations/deprecatedlistkeysrequest.md | 11 + .../deprecatedlistkeysresponsebody.md | 11 + .../deprecatedverifykeyratelimit.md | 12 + .../deprecatedverifykeyrequestbody.md | 9 + .../deprecatedverifykeyresponsebody.md | 20 + docs/models/operations/getapirequest.md | 8 + docs/models/operations/getapiresponsebody.md | 12 + docs/models/operations/getkeyrequest.md | 8 + .../operations/getverificationsrequest.md | 12 + .../getverificationsresponsebody.md | 10 + docs/models/operations/granularity.md | 10 + docs/models/operations/hash.md | 9 + docs/models/operations/interval.md | 11 + docs/models/operations/limitrequestbody.md | 15 + docs/models/operations/limitresponsebody.md | 11 + docs/models/operations/listkeysrequest.md | 11 + .../models/operations/listkeysresponsebody.md | 12 + docs/models/operations/op.md | 12 + docs/models/operations/ratelimit.md | 13 + docs/models/operations/refill.md | 11 + docs/models/operations/requestbody.md | 21 + docs/models/operations/resources.md | 11 + docs/models/operations/services.md | 12 + docs/models/operations/type.md | 14 + docs/models/operations/updatekeyinterval.md | 11 + docs/models/operations/updatekeyratelimit.md | 13 + docs/models/operations/updatekeyrefill.md | 11 + .../models/operations/updatekeyrequestbody.md | 16 + .../operations/updatekeyresponsebody.md | 9 + docs/models/operations/updatekeytype.md | 14 + .../operations/updateremainingrequestbody.md | 10 + .../operations/updateremainingresponsebody.md | 10 + .../operations/v1livenessresponsebody.md | 11 + .../v1migrationscreatekeysinterval.md | 11 + .../v1migrationscreatekeysratelimit.md | 13 + .../v1migrationscreatekeysrefill.md | 11 + .../v1migrationscreatekeysresponsebody.md | 10 + .../operations/v1migrationscreatekeystype.md | 14 + docs/models/operations/variant.md | 10 + docs/models/operations/verifications.md | 11 + docs/models/sdkerrors/code.md | 10 + docs/models/sdkerrors/errbadrequest.md | 10 + docs/models/sdkerrors/errconflict.md | 10 + docs/models/sdkerrors/errconflictcode.md | 10 + docs/models/sdkerrors/errconflicterror.md | 11 + docs/models/sdkerrors/errforbidden.md | 10 + docs/models/sdkerrors/errforbiddencode.md | 10 + docs/models/sdkerrors/errforbiddenerror.md | 11 + .../sdkerrors/errinternalservererror.md | 10 + .../sdkerrors/errinternalservererrorcode.md | 10 + .../sdkerrors/errinternalservererrorerror.md | 11 + docs/models/sdkerrors/errnotfound.md | 10 + docs/models/sdkerrors/errnotfoundcode.md | 10 + docs/models/sdkerrors/errnotfounderror.md | 11 + docs/models/sdkerrors/error.md | 11 + docs/models/sdkerrors/errtoomanyrequests.md | 10 + .../sdkerrors/errtoomanyrequestscode.md | 10 + .../sdkerrors/errtoomanyrequestserror.md | 11 + docs/models/sdkerrors/errunauthorized.md | 10 + docs/models/sdkerrors/errunauthorizedcode.md | 10 + docs/models/sdkerrors/errunauthorizederror.md | 11 + docs/sdks/apis/README.md | 122 ++ docs/sdks/keys/README.md | 462 ++++++ docs/sdks/liveness/README.md | 59 + docs/sdks/migrations/README.md | 93 ++ docs/sdks/ratelimits/README.md | 74 + docs/sdks/unkey/README.md | 315 +++++ go.mod | 8 + go.sum | 4 + internal/hooks/hooks.go | 144 ++ internal/hooks/registration.go | 13 + internal/utils/contenttype.go | 33 + internal/utils/form.go | 117 ++ internal/utils/headers.go | 125 ++ internal/utils/json.go | 670 +++++++++ internal/utils/pathparams.go | 173 +++ internal/utils/queryparams.go | 206 +++ internal/utils/requestbody.go | 409 ++++++ internal/utils/retries.go | 117 ++ internal/utils/security.go | 270 ++++ internal/utils/utils.go | 223 +++ keys.go | 1234 +++++++++++++++++ liveness.go | 193 +++ migrations.go | 199 +++ models/components/key.go | 296 ++++ models/components/security.go | 14 + models/components/v1keysverifykeyrequest.go | 86 ++ models/components/v1keysverifykeyresponse.go | 216 +++ models/operations/createapi.go | 28 + models/operations/createkey.go | 307 ++++ models/operations/deleteapi.go | 19 + models/operations/deletekey.go | 19 + models/operations/deprecatedcreatekey.go | 213 +++ models/operations/deprecatedlistkeys.go | 75 + models/operations/deprecatedverifykey.go | 221 +++ models/operations/getapi.go | 45 + models/operations/getkey.go | 14 + models/operations/getverifications.go | 140 ++ models/operations/limit.go | 171 +++ models/operations/listkeys.go | 84 ++ models/operations/updatekey.go | 216 +++ models/operations/updateremaining.go | 82 ++ models/operations/v1liveness.go | 72 + models/operations/v1migrationscreatekeys.go | 352 +++++ models/sdkerrors/errbadrequest.go | 84 ++ models/sdkerrors/errconflict.go | 84 ++ models/sdkerrors/errforbidden.go | 84 ++ models/sdkerrors/errinternalservererror.go | 84 ++ models/sdkerrors/errnotfound.go | 84 ++ models/sdkerrors/errtoomanyrequests.go | 84 ++ models/sdkerrors/errunauthorized.go | 84 ++ models/sdkerrors/sdkerror.go | 35 + ratelimits.go | 199 +++ types/bigint.go | 21 + types/date.go | 90 ++ types/datetime.go | 23 + types/decimal.go | 20 + types/pointers.go | 10 + unkey.go | 1053 ++++++++++++++ 151 files changed, 11435 insertions(+), 34 deletions(-) create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 USAGE.md create mode 100644 apis.go create mode 100644 docs/models/components/authorization.md create mode 100644 docs/models/components/code.md create mode 100644 docs/models/components/interval.md create mode 100644 docs/models/components/key.md create mode 100644 docs/models/components/permissions.md create mode 100644 docs/models/components/ratelimit.md create mode 100644 docs/models/components/refill.md create mode 100644 docs/models/components/security.md create mode 100644 docs/models/components/type.md create mode 100644 docs/models/components/v1keysverifykeyrequest.md create mode 100644 docs/models/components/v1keysverifykeyrequestratelimit.md create mode 100644 docs/models/components/v1keysverifykeyresponse.md create mode 100644 docs/models/components/v1keysverifykeyresponseratelimit.md create mode 100644 docs/models/operations/code.md create mode 100644 docs/models/operations/createapirequestbody.md create mode 100644 docs/models/operations/createapiresponsebody.md create mode 100644 docs/models/operations/createkeyrequestbody.md create mode 100644 docs/models/operations/createkeyresponsebody.md create mode 100644 docs/models/operations/deleteapirequestbody.md create mode 100644 docs/models/operations/deleteapiresponsebody.md create mode 100644 docs/models/operations/deletekeyrequestbody.md create mode 100644 docs/models/operations/deletekeyresponsebody.md create mode 100644 docs/models/operations/deprecatedcreatekeyratelimit.md create mode 100644 docs/models/operations/deprecatedcreatekeyrequestbody.md create mode 100644 docs/models/operations/deprecatedcreatekeyresponsebody.md create mode 100644 docs/models/operations/deprecatedcreatekeytype.md create mode 100644 docs/models/operations/deprecatedlistkeysrequest.md create mode 100644 docs/models/operations/deprecatedlistkeysresponsebody.md create mode 100644 docs/models/operations/deprecatedverifykeyratelimit.md create mode 100644 docs/models/operations/deprecatedverifykeyrequestbody.md create mode 100644 docs/models/operations/deprecatedverifykeyresponsebody.md create mode 100644 docs/models/operations/getapirequest.md create mode 100644 docs/models/operations/getapiresponsebody.md create mode 100644 docs/models/operations/getkeyrequest.md create mode 100644 docs/models/operations/getverificationsrequest.md create mode 100644 docs/models/operations/getverificationsresponsebody.md create mode 100644 docs/models/operations/granularity.md create mode 100644 docs/models/operations/hash.md create mode 100644 docs/models/operations/interval.md create mode 100644 docs/models/operations/limitrequestbody.md create mode 100644 docs/models/operations/limitresponsebody.md create mode 100644 docs/models/operations/listkeysrequest.md create mode 100644 docs/models/operations/listkeysresponsebody.md create mode 100644 docs/models/operations/op.md create mode 100644 docs/models/operations/ratelimit.md create mode 100644 docs/models/operations/refill.md create mode 100644 docs/models/operations/requestbody.md create mode 100644 docs/models/operations/resources.md create mode 100644 docs/models/operations/services.md create mode 100644 docs/models/operations/type.md create mode 100644 docs/models/operations/updatekeyinterval.md create mode 100644 docs/models/operations/updatekeyratelimit.md create mode 100644 docs/models/operations/updatekeyrefill.md create mode 100644 docs/models/operations/updatekeyrequestbody.md create mode 100644 docs/models/operations/updatekeyresponsebody.md create mode 100644 docs/models/operations/updatekeytype.md create mode 100644 docs/models/operations/updateremainingrequestbody.md create mode 100644 docs/models/operations/updateremainingresponsebody.md create mode 100644 docs/models/operations/v1livenessresponsebody.md create mode 100644 docs/models/operations/v1migrationscreatekeysinterval.md create mode 100644 docs/models/operations/v1migrationscreatekeysratelimit.md create mode 100644 docs/models/operations/v1migrationscreatekeysrefill.md create mode 100644 docs/models/operations/v1migrationscreatekeysresponsebody.md create mode 100644 docs/models/operations/v1migrationscreatekeystype.md create mode 100644 docs/models/operations/variant.md create mode 100644 docs/models/operations/verifications.md create mode 100644 docs/models/sdkerrors/code.md create mode 100644 docs/models/sdkerrors/errbadrequest.md create mode 100644 docs/models/sdkerrors/errconflict.md create mode 100644 docs/models/sdkerrors/errconflictcode.md create mode 100644 docs/models/sdkerrors/errconflicterror.md create mode 100644 docs/models/sdkerrors/errforbidden.md create mode 100644 docs/models/sdkerrors/errforbiddencode.md create mode 100644 docs/models/sdkerrors/errforbiddenerror.md create mode 100644 docs/models/sdkerrors/errinternalservererror.md create mode 100644 docs/models/sdkerrors/errinternalservererrorcode.md create mode 100644 docs/models/sdkerrors/errinternalservererrorerror.md create mode 100644 docs/models/sdkerrors/errnotfound.md create mode 100644 docs/models/sdkerrors/errnotfoundcode.md create mode 100644 docs/models/sdkerrors/errnotfounderror.md create mode 100644 docs/models/sdkerrors/error.md create mode 100644 docs/models/sdkerrors/errtoomanyrequests.md create mode 100644 docs/models/sdkerrors/errtoomanyrequestscode.md create mode 100644 docs/models/sdkerrors/errtoomanyrequestserror.md create mode 100644 docs/models/sdkerrors/errunauthorized.md create mode 100644 docs/models/sdkerrors/errunauthorizedcode.md create mode 100644 docs/models/sdkerrors/errunauthorizederror.md create mode 100644 docs/sdks/apis/README.md create mode 100644 docs/sdks/keys/README.md create mode 100644 docs/sdks/liveness/README.md create mode 100644 docs/sdks/migrations/README.md create mode 100644 docs/sdks/ratelimits/README.md create mode 100644 docs/sdks/unkey/README.md create mode 100644 go.mod create mode 100644 go.sum create mode 100644 internal/hooks/hooks.go create mode 100644 internal/hooks/registration.go create mode 100644 internal/utils/contenttype.go create mode 100644 internal/utils/form.go create mode 100644 internal/utils/headers.go create mode 100644 internal/utils/json.go create mode 100644 internal/utils/pathparams.go create mode 100644 internal/utils/queryparams.go create mode 100644 internal/utils/requestbody.go create mode 100644 internal/utils/retries.go create mode 100644 internal/utils/security.go create mode 100644 internal/utils/utils.go create mode 100644 keys.go create mode 100644 liveness.go create mode 100644 migrations.go create mode 100644 models/components/key.go create mode 100644 models/components/security.go create mode 100644 models/components/v1keysverifykeyrequest.go create mode 100644 models/components/v1keysverifykeyresponse.go create mode 100644 models/operations/createapi.go create mode 100644 models/operations/createkey.go create mode 100644 models/operations/deleteapi.go create mode 100644 models/operations/deletekey.go create mode 100644 models/operations/deprecatedcreatekey.go create mode 100644 models/operations/deprecatedlistkeys.go create mode 100644 models/operations/deprecatedverifykey.go create mode 100644 models/operations/getapi.go create mode 100644 models/operations/getkey.go create mode 100644 models/operations/getverifications.go create mode 100644 models/operations/limit.go create mode 100644 models/operations/listkeys.go create mode 100644 models/operations/updatekey.go create mode 100644 models/operations/updateremaining.go create mode 100644 models/operations/v1liveness.go create mode 100644 models/operations/v1migrationscreatekeys.go create mode 100644 models/sdkerrors/errbadrequest.go create mode 100644 models/sdkerrors/errconflict.go create mode 100644 models/sdkerrors/errforbidden.go create mode 100644 models/sdkerrors/errinternalservererror.go create mode 100644 models/sdkerrors/errnotfound.go create mode 100644 models/sdkerrors/errtoomanyrequests.go create mode 100644 models/sdkerrors/errunauthorized.go create mode 100644 models/sdkerrors/sdkerror.go create mode 100644 ratelimits.go create mode 100644 types/bigint.go create mode 100644 types/date.go create mode 100644 types/datetime.go create mode 100644 types/decimal.go create mode 100644 types/pointers.go create mode 100644 unkey.go diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..e6a9944 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# This allows generated code to be indexed correctly +*.go linguist-generated=false \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d3c2f59 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +# .gitignore diff --git a/.speakeasy/gen.lock b/.speakeasy/gen.lock index 020115b..e123e6b 100755 --- a/.speakeasy/gen.lock +++ b/.speakeasy/gen.lock @@ -1,5 +1,5 @@ lockVersion: 2.0.0 -id: 11283a56-f15d-4d3d-800a-2b51a30683a2 +id: 4fc4737a-135f-4840-8e6d-42a2b2a2884b management: docChecksum: a715ffbc95c5418289d86dc35921e0e8 docVersion: 1.0.0 diff --git a/USAGE.md b/USAGE.md new file mode 100644 index 0000000..05040c2 --- /dev/null +++ b/USAGE.md @@ -0,0 +1,33 @@ + +```go +package main + +import ( + "context" + unkeygo "github.com/unkeyed/unkey-go" + "github.com/unkeyed/unkey-go/models/components" + "github.com/unkeyed/unkey-go/models/operations" + "log" +) + +func main() { + s := unkeygo.New( + unkeygo.WithSecurity(""), + ) + + request := operations.CreateAPIRequestBody{ + Name: "my-api", + } + + ctx := context.Background() + res, err := s.CreateAPI(ctx, request) + if err != nil { + log.Fatal(err) + } + if res != nil { + // handle response + } +} + +``` + \ No newline at end of file diff --git a/apis.go b/apis.go new file mode 100644 index 0000000..3daa8ec --- /dev/null +++ b/apis.go @@ -0,0 +1,368 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package unkeygo + +import ( + "bytes" + "context" + "fmt" + "github.com/unkeyed/unkey-go/internal/hooks" + "github.com/unkeyed/unkey-go/internal/utils" + "github.com/unkeyed/unkey-go/models/operations" + "github.com/unkeyed/unkey-go/models/sdkerrors" + "io" + "net/http" + "net/url" +) + +type Apis struct { + sdkConfiguration sdkConfiguration +} + +func newApis(sdkConfig sdkConfiguration) *Apis { + return &Apis{ + sdkConfiguration: sdkConfig, + } +} + +func (s *Apis) GetAPI(ctx context.Context, request operations.GetAPIRequest) (*operations.GetAPIResponseBody, error) { + hookCtx := hooks.HookContext{ + Context: ctx, + OperationID: "getApi", + OAuth2Scopes: []string{}, + SecuritySource: s.sdkConfiguration.Security, + } + + baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) + opURL, err := url.JoinPath(baseURL, "/v1/apis.getApi") + if err != nil { + return nil, fmt.Errorf("error generating URL: %w", err) + } + + req, err := http.NewRequestWithContext(ctx, "GET", opURL, nil) + if err != nil { + return nil, fmt.Errorf("error creating request: %w", err) + } + req.Header.Set("Accept", "application/json") + req.Header.Set("User-Agent", s.sdkConfiguration.UserAgent) + + if err := utils.PopulateQueryParams(ctx, req, request, nil); err != nil { + return nil, fmt.Errorf("error populating query params: %w", err) + } + + if err := utils.PopulateSecurity(ctx, req, s.sdkConfiguration.Security); err != nil { + return nil, err + } + + req, err = s.sdkConfiguration.Hooks.BeforeRequest(hooks.BeforeRequestContext{HookContext: hookCtx}, req) + if err != nil { + return nil, err + } + + httpRes, err := s.sdkConfiguration.Client.Do(req) + if err != nil || httpRes == nil { + if err != nil { + err = fmt.Errorf("error sending request: %w", err) + } else { + err = fmt.Errorf("error sending request: no response") + } + + _, err = s.sdkConfiguration.Hooks.AfterError(hooks.AfterErrorContext{HookContext: hookCtx}, nil, err) + return nil, err + } else if utils.MatchStatusCodes([]string{"400", "401", "403", "404", "409", "429", "4XX", "500", "5XX"}, httpRes.StatusCode) { + _httpRes, err := s.sdkConfiguration.Hooks.AfterError(hooks.AfterErrorContext{HookContext: hookCtx}, httpRes, nil) + if err != nil { + return nil, err + } else if _httpRes != nil { + httpRes = _httpRes + } + } else { + httpRes, err = s.sdkConfiguration.Hooks.AfterSuccess(hooks.AfterSuccessContext{HookContext: hookCtx}, httpRes) + if err != nil { + return nil, err + } + } + + rawBody, err := io.ReadAll(httpRes.Body) + if err != nil { + return nil, fmt.Errorf("error reading response body: %w", err) + } + httpRes.Body.Close() + httpRes.Body = io.NopCloser(bytes.NewBuffer(rawBody)) + + switch { + case httpRes.StatusCode == 200: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out operations.GetAPIResponseBody + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return &out, nil + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 400: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrBadRequest + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 401: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrUnauthorized + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 403: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrForbidden + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 404: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrNotFound + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 409: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrConflict + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 429: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrTooManyRequests + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode >= 400 && httpRes.StatusCode < 500: + fallthrough + case httpRes.StatusCode >= 500 && httpRes.StatusCode < 600: + return nil, sdkerrors.NewSDKError("API error occurred", httpRes.StatusCode, string(rawBody), httpRes) + case httpRes.StatusCode == 500: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrInternalServerError + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + default: + return nil, sdkerrors.NewSDKError("unknown status code returned", httpRes.StatusCode, string(rawBody), httpRes) + } +} + +func (s *Apis) ListKeys(ctx context.Context, request operations.ListKeysRequest) (*operations.ListKeysResponseBody, error) { + hookCtx := hooks.HookContext{ + Context: ctx, + OperationID: "listKeys", + OAuth2Scopes: []string{}, + SecuritySource: s.sdkConfiguration.Security, + } + + baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) + opURL, err := url.JoinPath(baseURL, "/v1/apis.listKeys") + if err != nil { + return nil, fmt.Errorf("error generating URL: %w", err) + } + + req, err := http.NewRequestWithContext(ctx, "GET", opURL, nil) + if err != nil { + return nil, fmt.Errorf("error creating request: %w", err) + } + req.Header.Set("Accept", "application/json") + req.Header.Set("User-Agent", s.sdkConfiguration.UserAgent) + + if err := utils.PopulateQueryParams(ctx, req, request, nil); err != nil { + return nil, fmt.Errorf("error populating query params: %w", err) + } + + if err := utils.PopulateSecurity(ctx, req, s.sdkConfiguration.Security); err != nil { + return nil, err + } + + req, err = s.sdkConfiguration.Hooks.BeforeRequest(hooks.BeforeRequestContext{HookContext: hookCtx}, req) + if err != nil { + return nil, err + } + + httpRes, err := s.sdkConfiguration.Client.Do(req) + if err != nil || httpRes == nil { + if err != nil { + err = fmt.Errorf("error sending request: %w", err) + } else { + err = fmt.Errorf("error sending request: no response") + } + + _, err = s.sdkConfiguration.Hooks.AfterError(hooks.AfterErrorContext{HookContext: hookCtx}, nil, err) + return nil, err + } else if utils.MatchStatusCodes([]string{"400", "401", "403", "404", "409", "429", "4XX", "500", "5XX"}, httpRes.StatusCode) { + _httpRes, err := s.sdkConfiguration.Hooks.AfterError(hooks.AfterErrorContext{HookContext: hookCtx}, httpRes, nil) + if err != nil { + return nil, err + } else if _httpRes != nil { + httpRes = _httpRes + } + } else { + httpRes, err = s.sdkConfiguration.Hooks.AfterSuccess(hooks.AfterSuccessContext{HookContext: hookCtx}, httpRes) + if err != nil { + return nil, err + } + } + + rawBody, err := io.ReadAll(httpRes.Body) + if err != nil { + return nil, fmt.Errorf("error reading response body: %w", err) + } + httpRes.Body.Close() + httpRes.Body = io.NopCloser(bytes.NewBuffer(rawBody)) + + switch { + case httpRes.StatusCode == 200: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out operations.ListKeysResponseBody + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return &out, nil + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 400: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrBadRequest + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 401: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrUnauthorized + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 403: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrForbidden + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 404: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrNotFound + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 409: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrConflict + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 429: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrTooManyRequests + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode >= 400 && httpRes.StatusCode < 500: + fallthrough + case httpRes.StatusCode >= 500 && httpRes.StatusCode < 600: + return nil, sdkerrors.NewSDKError("API error occurred", httpRes.StatusCode, string(rawBody), httpRes) + case httpRes.StatusCode == 500: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrInternalServerError + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + default: + return nil, sdkerrors.NewSDKError("unknown status code returned", httpRes.StatusCode, string(rawBody), httpRes) + } +} diff --git a/codeSamples.yaml b/codeSamples.yaml index 9c8b120..d7fe323 100644 --- a/codeSamples.yaml +++ b/codeSamples.yaml @@ -3,48 +3,42 @@ info: title: CodeSamples overlay for go target version: 0.0.0 actions: - - target: $["paths"]["/v1/keys.createKey"]["post"] - update: - "x-codeSamples": - - "lang": "go" - "label": "createKey" - "source": "package main\n\nimport(\n\t\"github.com/unkeyed/unkey-go/models/components\"\n\tunkeygo \"github.com/unkeyed/unkey-go\"\n\t\"github.com/unkeyed/unkey-go/models/operations\"\n\t\"context\"\n\t\"log\"\n)\n\nfunc main() {\n s := unkeygo.New(\n unkeygo.WithSecurity(\"\"),\n )\n\n request := operations.CreateKeyRequestBody{\n APIID: \"api_123\",\n Name: unkeygo.String(\"my key\"),\n OwnerID: unkeygo.String(\"team_123\"),\n Meta: map[string]interface{}{\n \"billingTier\": \"PRO\",\n \"trialEnds\": \"2023-06-16T17:16:37.161Z\",\n },\n Roles: []string{\n \"admin\",\n \"finance\",\n },\n Expires: unkeygo.Int64(1623869797161),\n Remaining: unkeygo.Int64(1000),\n Refill: &operations.Refill{\n Interval: operations.IntervalDaily,\n Amount: 100,\n },\n Ratelimit: &operations.Ratelimit{\n Type: operations.TypeFast.ToPointer(),\n Limit: 10,\n RefillRate: 1,\n RefillInterval: 60,\n },\n Enabled: unkeygo.Bool(false),\n }\n \n ctx := context.Background()\n res, err := s.CreateKey(ctx, request)\n if err != nil {\n log.Fatal(err)\n }\n if res != nil {\n // handle response\n }\n}" - - target: $["paths"]["/v1/keys.updateRemaining"]["post"] + - target: $["paths"]["/v1/apis.createApi"]["post"] update: "x-codeSamples": - "lang": "go" - "label": "updateRemaining" - "source": "package main\n\nimport(\n\t\"github.com/unkeyed/unkey-go/models/components\"\n\tunkeygo \"github.com/unkeyed/unkey-go\"\n\t\"github.com/unkeyed/unkey-go/models/operations\"\n\t\"context\"\n\t\"log\"\n)\n\nfunc main() {\n s := unkeygo.New(\n unkeygo.WithSecurity(\"\"),\n )\n\n request := operations.UpdateRemainingRequestBody{\n KeyID: \"key_123\",\n Op: operations.OpSet,\n Value: unkeygo.Int64(1),\n }\n \n ctx := context.Background()\n res, err := s.UpdateRemaining(ctx, request)\n if err != nil {\n log.Fatal(err)\n }\n if res != nil {\n // handle response\n }\n}" - - target: $["paths"]["/v1/apis.getApi"]["get"] + "label": "createApi" + "source": "package main\n\nimport(\n\t\"github.com/unkeyed/unkey-go/models/components\"\n\tunkeygo \"github.com/unkeyed/unkey-go\"\n\t\"github.com/unkeyed/unkey-go/models/operations\"\n\t\"context\"\n\t\"log\"\n)\n\nfunc main() {\n s := unkeygo.New(\n unkeygo.WithSecurity(\"\"),\n )\n\n request := operations.CreateAPIRequestBody{\n Name: \"my-api\",\n }\n \n ctx := context.Background()\n res, err := s.CreateAPI(ctx, request)\n if err != nil {\n log.Fatal(err)\n }\n if res != nil {\n // handle response\n }\n}" + - target: $["paths"]["/v1/apis.deleteApi"]["post"] update: "x-codeSamples": - "lang": "go" - "label": "getApi" - "source": "package main\n\nimport(\n\t\"github.com/unkeyed/unkey-go/models/components\"\n\tunkeygo \"github.com/unkeyed/unkey-go\"\n\t\"github.com/unkeyed/unkey-go/models/operations\"\n\t\"context\"\n\t\"log\"\n)\n\nfunc main() {\n s := unkeygo.New(\n unkeygo.WithSecurity(\"\"),\n )\n\n request := operations.GetAPIRequest{\n APIID: \"api_1234\",\n }\n \n ctx := context.Background()\n res, err := s.GetAPI(ctx, request)\n if err != nil {\n log.Fatal(err)\n }\n if res != nil {\n // handle response\n }\n}" + "label": "deleteApi" + "source": "package main\n\nimport(\n\t\"github.com/unkeyed/unkey-go/models/components\"\n\tunkeygo \"github.com/unkeyed/unkey-go\"\n\t\"github.com/unkeyed/unkey-go/models/operations\"\n\t\"context\"\n\t\"log\"\n)\n\nfunc main() {\n s := unkeygo.New(\n unkeygo.WithSecurity(\"\"),\n )\n\n request := operations.DeleteAPIRequestBody{\n APIID: \"api_1234\",\n }\n \n ctx := context.Background()\n res, err := s.DeleteAPI(ctx, request)\n if err != nil {\n log.Fatal(err)\n }\n if res != nil {\n // handle response\n }\n}" - target: $["paths"]["/v1/keys/verify"]["post"] update: "x-codeSamples": - "lang": "go" "label": "verifyKey" "source": "package main\n\nimport(\n\t\"github.com/unkeyed/unkey-go/models/components\"\n\tunkeygo \"github.com/unkeyed/unkey-go\"\n\t\"github.com/unkeyed/unkey-go/models/operations\"\n\t\"context\"\n\t\"log\"\n)\n\nfunc main() {\n s := unkeygo.New(\n unkeygo.WithSecurity(\"\"),\n )\n\n request := operations.DeprecatedVerifyKeyRequestBody{\n APIID: unkeygo.String(\"api_1234\"),\n Key: \"sk_1234\",\n }\n \n ctx := context.Background()\n res, err := s.DeprecatedVerifyKey(ctx, request)\n if err != nil {\n log.Fatal(err)\n }\n if res != nil {\n // handle response\n }\n}" - - target: $["paths"]["/v1/keys"]["post"] + - target: $["paths"]["/v1/keys.verifyKey"]["post"] update: "x-codeSamples": - "lang": "go" - "label": "createKey" - "source": "package main\n\nimport(\n\t\"github.com/unkeyed/unkey-go/models/components\"\n\tunkeygo \"github.com/unkeyed/unkey-go\"\n\t\"github.com/unkeyed/unkey-go/models/operations\"\n\t\"context\"\n\t\"log\"\n)\n\nfunc main() {\n s := unkeygo.New(\n unkeygo.WithSecurity(\"\"),\n )\n\n request := operations.DeprecatedCreateKeyRequestBody{\n APIID: \"api_123\",\n Name: unkeygo.String(\"my key\"),\n OwnerID: unkeygo.String(\"team_123\"),\n Meta: map[string]interface{}{\n \"billingTier\": \"PRO\",\n \"trialEnds\": \"2023-06-16T17:16:37.161Z\",\n },\n Expires: unkeygo.Int64(1623869797161),\n Remaining: unkeygo.Int64(1000),\n Ratelimit: &operations.DeprecatedCreateKeyRatelimit{\n Type: operations.DeprecatedCreateKeyTypeFast.ToPointer(),\n Limit: 10,\n RefillRate: 1,\n RefillInterval: 60,\n },\n }\n \n ctx := context.Background()\n res, err := s.DeprecatedCreateKey(ctx, request)\n if err != nil {\n log.Fatal(err)\n }\n if res != nil {\n // handle response\n }\n}" - - target: $["paths"]["/v1/apis.createApi"]["post"] + "label": "verifyKey" + "source": "package main\n\nimport(\n\t\"github.com/unkeyed/unkey-go/models/components\"\n\tunkeygo \"github.com/unkeyed/unkey-go\"\n\t\"context\"\n\t\"log\"\n)\n\nfunc main() {\n s := unkeygo.New(\n unkeygo.WithSecurity(\"\"),\n )\n\n request := components.V1KeysVerifyKeyRequest{\n APIID: unkeygo.String(\"api_1234\"),\n Key: \"sk_1234\",\n Authorization: &components.Authorization{\n Permissions: &components.Permissions{},\n },\n }\n \n ctx := context.Background()\n res, err := s.VerifyKey(ctx, request)\n if err != nil {\n log.Fatal(err)\n }\n if res != nil {\n // handle response\n }\n}" + - target: $["paths"]["/v1/keys.updateRemaining"]["post"] update: "x-codeSamples": - "lang": "go" - "label": "createApi" - "source": "package main\n\nimport(\n\t\"github.com/unkeyed/unkey-go/models/components\"\n\tunkeygo \"github.com/unkeyed/unkey-go\"\n\t\"github.com/unkeyed/unkey-go/models/operations\"\n\t\"context\"\n\t\"log\"\n)\n\nfunc main() {\n s := unkeygo.New(\n unkeygo.WithSecurity(\"\"),\n )\n\n request := operations.CreateAPIRequestBody{\n Name: \"my-api\",\n }\n \n ctx := context.Background()\n res, err := s.CreateAPI(ctx, request)\n if err != nil {\n log.Fatal(err)\n }\n if res != nil {\n // handle response\n }\n}" - - target: $["paths"]["/v1/liveness"]["get"] + "label": "updateRemaining" + "source": "package main\n\nimport(\n\t\"github.com/unkeyed/unkey-go/models/components\"\n\tunkeygo \"github.com/unkeyed/unkey-go\"\n\t\"github.com/unkeyed/unkey-go/models/operations\"\n\t\"context\"\n\t\"log\"\n)\n\nfunc main() {\n s := unkeygo.New(\n unkeygo.WithSecurity(\"\"),\n )\n\n request := operations.UpdateRemainingRequestBody{\n KeyID: \"key_123\",\n Op: operations.OpSet,\n Value: unkeygo.Int64(1),\n }\n \n ctx := context.Background()\n res, err := s.UpdateRemaining(ctx, request)\n if err != nil {\n log.Fatal(err)\n }\n if res != nil {\n // handle response\n }\n}" + - target: $["paths"]["/v1/apis/{apiId}/keys"]["get"] update: "x-codeSamples": - "lang": "go" - "label": "liveness" - "source": "package main\n\nimport(\n\t\"github.com/unkeyed/unkey-go/models/components\"\n\tunkeygo \"github.com/unkeyed/unkey-go\"\n\t\"context\"\n\t\"log\"\n)\n\nfunc main() {\n s := unkeygo.New(\n unkeygo.WithSecurity(\"\"),\n )\n\n\n \n ctx := context.Background()\n res, err := s.V1Liveness(ctx)\n if err != nil {\n log.Fatal(err)\n }\n if res != nil {\n // handle response\n }\n}" + "label": "listKeys" + "source": "package main\n\nimport(\n\t\"github.com/unkeyed/unkey-go/models/components\"\n\tunkeygo \"github.com/unkeyed/unkey-go\"\n\t\"github.com/unkeyed/unkey-go/models/operations\"\n\t\"context\"\n\t\"log\"\n)\n\nfunc main() {\n s := unkeygo.New(\n unkeygo.WithSecurity(\"\"),\n )\n\n request := operations.DeprecatedListKeysRequest{\n APIID: \"api_1234\",\n Limit: unkeygo.Int64(100),\n }\n \n ctx := context.Background()\n res, err := s.DeprecatedListKeys(ctx, request)\n if err != nil {\n log.Fatal(err)\n }\n if res != nil {\n // handle response\n }\n}" - target: $["paths"]["/v1/keys.getKey"]["get"] update: "x-codeSamples": @@ -69,6 +63,12 @@ actions: - "lang": "go" "label": "getVerifications" "source": "package main\n\nimport(\n\t\"github.com/unkeyed/unkey-go/models/components\"\n\tunkeygo \"github.com/unkeyed/unkey-go\"\n\t\"github.com/unkeyed/unkey-go/models/operations\"\n\t\"context\"\n\t\"log\"\n)\n\nfunc main() {\n s := unkeygo.New(\n unkeygo.WithSecurity(\"\"),\n )\n\n request := operations.GetVerificationsRequest{\n KeyID: unkeygo.String(\"key_1234\"),\n OwnerID: unkeygo.String(\"chronark\"),\n Start: unkeygo.Int64(1620000000000),\n End: unkeygo.Int64(1620000000000),\n Granularity: operations.GranularityDay.ToPointer(),\n }\n \n ctx := context.Background()\n res, err := s.GetVerifications(ctx, request)\n if err != nil {\n log.Fatal(err)\n }\n if res != nil {\n // handle response\n }\n}" + - target: $["paths"]["/v1/apis.getApi"]["get"] + update: + "x-codeSamples": + - "lang": "go" + "label": "getApi" + "source": "package main\n\nimport(\n\t\"github.com/unkeyed/unkey-go/models/components\"\n\tunkeygo \"github.com/unkeyed/unkey-go\"\n\t\"github.com/unkeyed/unkey-go/models/operations\"\n\t\"context\"\n\t\"log\"\n)\n\nfunc main() {\n s := unkeygo.New(\n unkeygo.WithSecurity(\"\"),\n )\n\n request := operations.GetAPIRequest{\n APIID: \"api_1234\",\n }\n \n ctx := context.Background()\n res, err := s.GetAPI(ctx, request)\n if err != nil {\n log.Fatal(err)\n }\n if res != nil {\n // handle response\n }\n}" - target: $["paths"]["/v1/ratelimits.limit"]["post"] update: "x-codeSamples": @@ -81,27 +81,27 @@ actions: - "lang": "go" "label": "createKeys" "source": "package main\n\nimport(\n\t\"github.com/unkeyed/unkey-go/models/components\"\n\tunkeygo \"github.com/unkeyed/unkey-go\"\n\t\"github.com/unkeyed/unkey-go/models/operations\"\n\t\"context\"\n\t\"log\"\n)\n\nfunc main() {\n s := unkeygo.New(\n unkeygo.WithSecurity(\"\"),\n )\n\n request := []operations.RequestBody{\n operations.RequestBody{\n APIID: \"api_123\",\n Name: unkeygo.String(\"my key\"),\n Hash: operations.Hash{\n Value: \"\",\n Variant: operations.VariantSha256Base64,\n },\n Start: unkeygo.String(\"unkey_32kq\"),\n OwnerID: unkeygo.String(\"team_123\"),\n Meta: map[string]interface{}{\n \"billingTier\": \"PRO\",\n \"trialEnds\": \"2023-06-16T17:16:37.161Z\",\n },\n Roles: []string{\n \"admin\",\n \"finance\",\n },\n Expires: unkeygo.Int64(1623869797161),\n Remaining: unkeygo.Int64(1000),\n Refill: &operations.V1MigrationsCreateKeysRefill{\n Interval: operations.V1MigrationsCreateKeysIntervalDaily,\n Amount: 100,\n },\n Ratelimit: &operations.V1MigrationsCreateKeysRatelimit{\n Type: operations.V1MigrationsCreateKeysTypeFast.ToPointer(),\n Limit: 10,\n RefillRate: 1,\n RefillInterval: 60,\n },\n Enabled: unkeygo.Bool(false),\n },\n }\n \n ctx := context.Background()\n res, err := s.V1MigrationsCreateKeys(ctx, request)\n if err != nil {\n log.Fatal(err)\n }\n if res != nil {\n // handle response\n }\n}" - - target: $["paths"]["/v1/apis/{apiId}/keys"]["get"] + - target: $["paths"]["/v1/keys"]["post"] update: "x-codeSamples": - "lang": "go" - "label": "listKeys" - "source": "package main\n\nimport(\n\t\"github.com/unkeyed/unkey-go/models/components\"\n\tunkeygo \"github.com/unkeyed/unkey-go\"\n\t\"github.com/unkeyed/unkey-go/models/operations\"\n\t\"context\"\n\t\"log\"\n)\n\nfunc main() {\n s := unkeygo.New(\n unkeygo.WithSecurity(\"\"),\n )\n\n request := operations.DeprecatedListKeysRequest{\n APIID: \"api_1234\",\n Limit: unkeygo.Int64(100),\n }\n \n ctx := context.Background()\n res, err := s.DeprecatedListKeys(ctx, request)\n if err != nil {\n log.Fatal(err)\n }\n if res != nil {\n // handle response\n }\n}" - - target: $["paths"]["/v1/keys.verifyKey"]["post"] + "label": "createKey" + "source": "package main\n\nimport(\n\t\"github.com/unkeyed/unkey-go/models/components\"\n\tunkeygo \"github.com/unkeyed/unkey-go\"\n\t\"github.com/unkeyed/unkey-go/models/operations\"\n\t\"context\"\n\t\"log\"\n)\n\nfunc main() {\n s := unkeygo.New(\n unkeygo.WithSecurity(\"\"),\n )\n\n request := operations.DeprecatedCreateKeyRequestBody{\n APIID: \"api_123\",\n Name: unkeygo.String(\"my key\"),\n OwnerID: unkeygo.String(\"team_123\"),\n Meta: map[string]interface{}{\n \"billingTier\": \"PRO\",\n \"trialEnds\": \"2023-06-16T17:16:37.161Z\",\n },\n Expires: unkeygo.Int64(1623869797161),\n Remaining: unkeygo.Int64(1000),\n Ratelimit: &operations.DeprecatedCreateKeyRatelimit{\n Type: operations.DeprecatedCreateKeyTypeFast.ToPointer(),\n Limit: 10,\n RefillRate: 1,\n RefillInterval: 60,\n },\n }\n \n ctx := context.Background()\n res, err := s.DeprecatedCreateKey(ctx, request)\n if err != nil {\n log.Fatal(err)\n }\n if res != nil {\n // handle response\n }\n}" + - target: $["paths"]["/v1/liveness"]["get"] update: "x-codeSamples": - "lang": "go" - "label": "verifyKey" - "source": "package main\n\nimport(\n\t\"github.com/unkeyed/unkey-go/models/components\"\n\tunkeygo \"github.com/unkeyed/unkey-go\"\n\t\"context\"\n\t\"log\"\n)\n\nfunc main() {\n s := unkeygo.New(\n unkeygo.WithSecurity(\"\"),\n )\n\n request := components.V1KeysVerifyKeyRequest{\n APIID: unkeygo.String(\"api_1234\"),\n Key: \"sk_1234\",\n Authorization: &components.Authorization{\n Permissions: &components.Permissions{},\n },\n }\n \n ctx := context.Background()\n res, err := s.VerifyKey(ctx, request)\n if err != nil {\n log.Fatal(err)\n }\n if res != nil {\n // handle response\n }\n}" - - target: $["paths"]["/v1/apis.listKeys"]["get"] + "label": "liveness" + "source": "package main\n\nimport(\n\t\"github.com/unkeyed/unkey-go/models/components\"\n\tunkeygo \"github.com/unkeyed/unkey-go\"\n\t\"context\"\n\t\"log\"\n)\n\nfunc main() {\n s := unkeygo.New(\n unkeygo.WithSecurity(\"\"),\n )\n\n\n \n ctx := context.Background()\n res, err := s.V1Liveness(ctx)\n if err != nil {\n log.Fatal(err)\n }\n if res != nil {\n // handle response\n }\n}" + - target: $["paths"]["/v1/keys.createKey"]["post"] update: "x-codeSamples": - "lang": "go" - "label": "listKeys" - "source": "package main\n\nimport(\n\t\"github.com/unkeyed/unkey-go/models/components\"\n\tunkeygo \"github.com/unkeyed/unkey-go\"\n\t\"github.com/unkeyed/unkey-go/models/operations\"\n\t\"context\"\n\t\"log\"\n)\n\nfunc main() {\n s := unkeygo.New(\n unkeygo.WithSecurity(\"\"),\n )\n\n request := operations.ListKeysRequest{\n APIID: \"api_1234\",\n Limit: unkeygo.Int64(100),\n }\n \n ctx := context.Background()\n res, err := s.ListKeys(ctx, request)\n if err != nil {\n log.Fatal(err)\n }\n if res != nil {\n // handle response\n }\n}" - - target: $["paths"]["/v1/apis.deleteApi"]["post"] + "label": "createKey" + "source": "package main\n\nimport(\n\t\"github.com/unkeyed/unkey-go/models/components\"\n\tunkeygo \"github.com/unkeyed/unkey-go\"\n\t\"github.com/unkeyed/unkey-go/models/operations\"\n\t\"context\"\n\t\"log\"\n)\n\nfunc main() {\n s := unkeygo.New(\n unkeygo.WithSecurity(\"\"),\n )\n\n request := operations.CreateKeyRequestBody{\n APIID: \"api_123\",\n Name: unkeygo.String(\"my key\"),\n OwnerID: unkeygo.String(\"team_123\"),\n Meta: map[string]interface{}{\n \"billingTier\": \"PRO\",\n \"trialEnds\": \"2023-06-16T17:16:37.161Z\",\n },\n Roles: []string{\n \"admin\",\n \"finance\",\n },\n Expires: unkeygo.Int64(1623869797161),\n Remaining: unkeygo.Int64(1000),\n Refill: &operations.Refill{\n Interval: operations.IntervalDaily,\n Amount: 100,\n },\n Ratelimit: &operations.Ratelimit{\n Type: operations.TypeFast.ToPointer(),\n Limit: 10,\n RefillRate: 1,\n RefillInterval: 60,\n },\n Enabled: unkeygo.Bool(false),\n }\n \n ctx := context.Background()\n res, err := s.CreateKey(ctx, request)\n if err != nil {\n log.Fatal(err)\n }\n if res != nil {\n // handle response\n }\n}" + - target: $["paths"]["/v1/apis.listKeys"]["get"] update: "x-codeSamples": - "lang": "go" - "label": "deleteApi" - "source": "package main\n\nimport(\n\t\"github.com/unkeyed/unkey-go/models/components\"\n\tunkeygo \"github.com/unkeyed/unkey-go\"\n\t\"github.com/unkeyed/unkey-go/models/operations\"\n\t\"context\"\n\t\"log\"\n)\n\nfunc main() {\n s := unkeygo.New(\n unkeygo.WithSecurity(\"\"),\n )\n\n request := operations.DeleteAPIRequestBody{\n APIID: \"api_1234\",\n }\n \n ctx := context.Background()\n res, err := s.DeleteAPI(ctx, request)\n if err != nil {\n log.Fatal(err)\n }\n if res != nil {\n // handle response\n }\n}" + "label": "listKeys" + "source": "package main\n\nimport(\n\t\"github.com/unkeyed/unkey-go/models/components\"\n\tunkeygo \"github.com/unkeyed/unkey-go\"\n\t\"github.com/unkeyed/unkey-go/models/operations\"\n\t\"context\"\n\t\"log\"\n)\n\nfunc main() {\n s := unkeygo.New(\n unkeygo.WithSecurity(\"\"),\n )\n\n request := operations.ListKeysRequest{\n APIID: \"api_1234\",\n Limit: unkeygo.Int64(100),\n }\n \n ctx := context.Background()\n res, err := s.ListKeys(ctx, request)\n if err != nil {\n log.Fatal(err)\n }\n if res != nil {\n // handle response\n }\n}" diff --git a/docs/models/components/authorization.md b/docs/models/components/authorization.md new file mode 100644 index 0000000..7f948ff --- /dev/null +++ b/docs/models/components/authorization.md @@ -0,0 +1,10 @@ +# Authorization + +Perform RBAC checks + + +## Fields + +| Field | Type | Required | Description | Example | +| ---------------------------------------------------------------------------- | ---------------------------------------------------------------------------- | ---------------------------------------------------------------------------- | ---------------------------------------------------------------------------- | ---------------------------------------------------------------------------- | +| `Permissions` | [*components.Permissions](../../models/components/permissions.md) | :heavy_minus_sign: | A query for which permissions you require | {
"or": [
{
"and": [
"dns.record.read",
"dns.record.update"
]
},
"admin"
]
} | \ No newline at end of file diff --git a/docs/models/components/code.md b/docs/models/components/code.md new file mode 100644 index 0000000..a66e4a4 --- /dev/null +++ b/docs/models/components/code.md @@ -0,0 +1,27 @@ +# Code + +A machine readable code why the key is not valid. +Possible values are: +- VALID: the key is valid and you should proceed +- NOT_FOUND: the key does not exist or has expired +- FORBIDDEN: the key is not allowed to access the api +- USAGE_EXCEEDED: the key has exceeded its request limit +- RATE_LIMITED: the key has been ratelimited +- UNAUTHORIZED: the key is not authorized +- DISABLED: the key is disabled +- INSUFFICIENT_PERMISSIONS: you do not have the required permissions to perform this action + + + +## Values + +| Name | Value | +| ----------------------------- | ----------------------------- | +| `CodeValid` | VALID | +| `CodeNotFound` | NOT_FOUND | +| `CodeForbidden` | FORBIDDEN | +| `CodeUsageExceeded` | USAGE_EXCEEDED | +| `CodeRateLimited` | RATE_LIMITED | +| `CodeUnauthorized` | UNAUTHORIZED | +| `CodeDisabled` | DISABLED | +| `CodeInsufficientPermissions` | INSUFFICIENT_PERMISSIONS | \ No newline at end of file diff --git a/docs/models/components/interval.md b/docs/models/components/interval.md new file mode 100644 index 0000000..452959e --- /dev/null +++ b/docs/models/components/interval.md @@ -0,0 +1,11 @@ +# Interval + +Determines the rate at which verifications will be refilled. + + +## Values + +| Name | Value | +| ----------------- | ----------------- | +| `IntervalDaily` | daily | +| `IntervalMonthly` | monthly | \ No newline at end of file diff --git a/docs/models/components/key.md b/docs/models/components/key.md new file mode 100644 index 0000000..d45fd5a --- /dev/null +++ b/docs/models/components/key.md @@ -0,0 +1,23 @@ +# Key + + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `ID` | *string* | :heavy_check_mark: | The id of the key | key_1234 | +| `Start` | *string* | :heavy_check_mark: | The first few characters of the key to visually identify it | sk_5j1 | +| `WorkspaceID` | *string* | :heavy_check_mark: | The id of the workspace that owns the key | ws_1234 | +| `APIID` | **string* | :heavy_minus_sign: | The id of the api that this key is for | api_1234 | +| `Name` | **string* | :heavy_minus_sign: | The name of the key, give keys a name to easily identify their purpose | Customer X | +| `OwnerID` | **string* | :heavy_minus_sign: | The id of the tenant associated with this key. Use whatever reference you have in your system to identify the tenant. When verifying the key, we will send this field back to you, so you know who is accessing your API. | user_123 | +| `Meta` | map[string]*interface{}* | :heavy_minus_sign: | Any additional metadata you want to store with the key | {
"roles": [
"admin",
"user"
],
"stripeCustomerId": "cus_1234"
} | +| `CreatedAt` | **float64* | :heavy_minus_sign: | The unix timestamp in milliseconds when the key was created | 0 | +| `DeletedAt` | **float64* | :heavy_minus_sign: | The unix timestamp in milliseconds when the key was deleted. We don't delete the key outright, you can restore it later. | 0 | +| `Expires` | **float64* | :heavy_minus_sign: | The unix timestamp in milliseconds when the key will expire. If this field is null or undefined, the key is not expiring. | 0 | +| `Remaining` | **float64* | :heavy_minus_sign: | The number of requests that can be made with this key before it becomes invalid. If this field is null or undefined, the key has no request limit. | 1000 | +| `Refill` | [*components.Refill](../../models/components/refill.md) | :heavy_minus_sign: | Unkey allows you to refill remaining verifications on a key on a regular interval. | {
"interval": "daily",
"amount": 10
} | +| `Ratelimit` | [*components.Ratelimit](../../models/components/ratelimit.md) | :heavy_minus_sign: | Unkey comes with per-key ratelimiting out of the box. | {
"type": "fast",
"limit": 10,
"refillRate": 1,
"refillInterval": 60
} | +| `Roles` | []*string* | :heavy_minus_sign: | All roles this key belongs to | [
"admin",
"finance"
] | +| `Permissions` | []*string* | :heavy_minus_sign: | All permissions this key has | [
"domain.dns.create_record",
"finance.read_receipt"
] | +| `Enabled` | **bool* | :heavy_minus_sign: | Sets if key is enabled or disabled. Disabled keys are not valid. | true | \ No newline at end of file diff --git a/docs/models/components/permissions.md b/docs/models/components/permissions.md new file mode 100644 index 0000000..10b0762 --- /dev/null +++ b/docs/models/components/permissions.md @@ -0,0 +1,9 @@ +# Permissions + +A query for which permissions you require + + +## Fields + +| Field | Type | Required | Description | +| ----------- | ----------- | ----------- | ----------- | \ No newline at end of file diff --git a/docs/models/components/ratelimit.md b/docs/models/components/ratelimit.md new file mode 100644 index 0000000..5a50167 --- /dev/null +++ b/docs/models/components/ratelimit.md @@ -0,0 +1,13 @@ +# Ratelimit + +Unkey comes with per-key ratelimiting out of the box. + + +## Fields + +| Field | Type | Required | Description | +| -------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | +| `Type` | [*components.Type](../../models/components/type.md) | :heavy_minus_sign: | Fast ratelimiting doesn't add latency, while consistent ratelimiting is more accurate.

[Learn more](https://unkey.dev/docs/features/ratelimiting) | +| `Limit` | *int64* | :heavy_check_mark: | The total amount of burstable requests. | +| `RefillRate` | *int64* | :heavy_check_mark: | How many tokens to refill during each refillInterval. | +| `RefillInterval` | *int64* | :heavy_check_mark: | Determines the speed at which tokens are refilled, in milliseconds. | \ No newline at end of file diff --git a/docs/models/components/refill.md b/docs/models/components/refill.md new file mode 100644 index 0000000..74d1dea --- /dev/null +++ b/docs/models/components/refill.md @@ -0,0 +1,12 @@ +# Refill + +Unkey allows you to refill remaining verifications on a key on a regular interval. + + +## Fields + +| Field | Type | Required | Description | Example | +| ----------------------------------------------------------------- | ----------------------------------------------------------------- | ----------------------------------------------------------------- | ----------------------------------------------------------------- | ----------------------------------------------------------------- | +| `Interval` | [components.Interval](../../models/components/interval.md) | :heavy_check_mark: | Determines the rate at which verifications will be refilled. | daily | +| `Amount` | *int64* | :heavy_check_mark: | Resets `remaining` to this value every interval. | 100 | +| `LastRefillAt` | **float64* | :heavy_minus_sign: | The unix timestamp in miliseconds when the key was last refilled. | 100 | \ No newline at end of file diff --git a/docs/models/components/security.md b/docs/models/components/security.md new file mode 100644 index 0000000..bd7a7eb --- /dev/null +++ b/docs/models/components/security.md @@ -0,0 +1,8 @@ +# Security + + +## Fields + +| Field | Type | Required | Description | +| ------------------ | ------------------ | ------------------ | ------------------ | +| `BearerAuth` | **string* | :heavy_minus_sign: | N/A | \ No newline at end of file diff --git a/docs/models/components/type.md b/docs/models/components/type.md new file mode 100644 index 0000000..e06fa5d --- /dev/null +++ b/docs/models/components/type.md @@ -0,0 +1,14 @@ +# Type + +Fast ratelimiting doesn't add latency, while consistent ratelimiting is more accurate. + +Learn more + + + +## Values + +| Name | Value | +| ---------------- | ---------------- | +| `TypeFast` | fast | +| `TypeConsistent` | consistent | \ No newline at end of file diff --git a/docs/models/components/v1keysverifykeyrequest.md b/docs/models/components/v1keysverifykeyrequest.md new file mode 100644 index 0000000..479e180 --- /dev/null +++ b/docs/models/components/v1keysverifykeyrequest.md @@ -0,0 +1,11 @@ +# V1KeysVerifyKeyRequest + + +## Fields + +| Field | Type | Required | Description | Example | +| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `APIID` | **string* | :heavy_minus_sign: | The id of the api where the key belongs to. This is optional for now but will be required soon.
The key will be verified against the api's configuration. If the key does not belong to the api, the verification will fail. | api_1234 | +| `Key` | *string* | :heavy_check_mark: | The key to verify | sk_1234 | +| `Authorization` | [*components.Authorization](../../models/components/authorization.md) | :heavy_minus_sign: | Perform RBAC checks | | +| `Ratelimit` | [*components.V1KeysVerifyKeyRequestRatelimit](../../models/components/v1keysverifykeyrequestratelimit.md) | :heavy_minus_sign: | N/A | | \ No newline at end of file diff --git a/docs/models/components/v1keysverifykeyrequestratelimit.md b/docs/models/components/v1keysverifykeyrequestratelimit.md new file mode 100644 index 0000000..8cea3df --- /dev/null +++ b/docs/models/components/v1keysverifykeyrequestratelimit.md @@ -0,0 +1,8 @@ +# V1KeysVerifyKeyRequestRatelimit + + +## Fields + +| Field | Type | Required | Description | +| --------------------------------------------------------------------- | --------------------------------------------------------------------- | --------------------------------------------------------------------- | --------------------------------------------------------------------- | +| `Cost` | **int64* | :heavy_minus_sign: | Override how many tokens are deducted during the ratelimit operation. | \ No newline at end of file diff --git a/docs/models/components/v1keysverifykeyresponse.md b/docs/models/components/v1keysverifykeyresponse.md new file mode 100644 index 0000000..61fd136 --- /dev/null +++ b/docs/models/components/v1keysverifykeyresponse.md @@ -0,0 +1,19 @@ +# V1KeysVerifyKeyResponse + + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `KeyID` | **string* | :heavy_minus_sign: | The id of the key | key_1234 | +| `Valid` | *bool* | :heavy_check_mark: | Whether the key is valid or not.
A key could be invalid for a number of reasons, for example if it has expired, has no more verifications left or if it has been deleted. | true | +| `Name` | **string* | :heavy_minus_sign: | The name of the key, give keys a name to easily identifiy their purpose | Customer X | +| `OwnerID` | **string* | :heavy_minus_sign: | The id of the tenant associated with this key. Use whatever reference you have in your system to identify the tenant. When verifying the key, we will send this field back to you, so you know who is accessing your API. | user_123 | +| `Meta` | map[string]*interface{}* | :heavy_minus_sign: | Any additional metadata you want to store with the key | {
"roles": [
"admin",
"user"
],
"stripeCustomerId": "cus_1234"
} | +| `Expires` | **float64* | :heavy_minus_sign: | The unix timestamp in milliseconds when the key will expire. If this field is null or undefined, the key is not expiring. | 123 | +| `Ratelimit` | [*components.V1KeysVerifyKeyResponseRatelimit](../../models/components/v1keysverifykeyresponseratelimit.md) | :heavy_minus_sign: | The ratelimit configuration for this key. If this field is null or undefined, the key has no ratelimit. | {
"limit": 10,
"remaining": 9,
"reset": 3600000
} | +| `Remaining` | **float64* | :heavy_minus_sign: | The number of requests that can be made with this key before it becomes invalid. If this field is null or undefined, the key has no request limit. | 1000 | +| `Code` | [components.Code](../../models/components/code.md) | :heavy_check_mark: | A machine readable code why the key is not valid.
Possible values are:
- VALID: the key is valid and you should proceed
- NOT_FOUND: the key does not exist or has expired
- FORBIDDEN: the key is not allowed to access the api
- USAGE_EXCEEDED: the key has exceeded its request limit
- RATE_LIMITED: the key has been ratelimited
- UNAUTHORIZED: the key is not authorized
- DISABLED: the key is disabled
- INSUFFICIENT_PERMISSIONS: you do not have the required permissions to perform this action
| | +| `Enabled` | **bool* | :heavy_minus_sign: | Sets the key to be enabled or disabled. Disabled keys will not verify. | | +| `Permissions` | []*string* | :heavy_minus_sign: | A list of all the permissions this key is connected to. | [
"dns.record.update",
"dns.record.delete"
] | +| `Environment` | **string* | :heavy_minus_sign: | The environment of the key, this is what what you set when you crated the key | test | \ No newline at end of file diff --git a/docs/models/components/v1keysverifykeyresponseratelimit.md b/docs/models/components/v1keysverifykeyresponseratelimit.md new file mode 100644 index 0000000..73f6ef9 --- /dev/null +++ b/docs/models/components/v1keysverifykeyresponseratelimit.md @@ -0,0 +1,12 @@ +# V1KeysVerifyKeyResponseRatelimit + +The ratelimit configuration for this key. If this field is null or undefined, the key has no ratelimit. + + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | +| `Limit` | *float64* | :heavy_check_mark: | Maximum number of requests that can be made inside a window | 10 | +| `Remaining` | *float64* | :heavy_check_mark: | Remaining requests after this verification | 9 | +| `Reset` | *float64* | :heavy_check_mark: | Unix timestamp in milliseconds when the ratelimit will reset | 3600000 | \ No newline at end of file diff --git a/docs/models/operations/code.md b/docs/models/operations/code.md new file mode 100644 index 0000000..f096e21 --- /dev/null +++ b/docs/models/operations/code.md @@ -0,0 +1,23 @@ +# Code + +If the key is invalid this field will be set to the reason why it is invalid. +Possible values are: +- NOT_FOUND: the key does not exist or has expired +- FORBIDDEN: the key is not allowed to access the api +- USAGE_EXCEEDED: the key has exceeded its request limit +- RATE_LIMITED: the key has been ratelimited, +- INSUFFICIENT_PERMISSIONS: you do not have the required permissions to perform this action + + + +## Values + +| Name | Value | +| ----------------------------- | ----------------------------- | +| `CodeNotFound` | NOT_FOUND | +| `CodeForbidden` | FORBIDDEN | +| `CodeUsageExceeded` | USAGE_EXCEEDED | +| `CodeRateLimited` | RATE_LIMITED | +| `CodeUnauthorized` | UNAUTHORIZED | +| `CodeDisabled` | DISABLED | +| `CodeInsufficientPermissions` | INSUFFICIENT_PERMISSIONS | \ No newline at end of file diff --git a/docs/models/operations/createapirequestbody.md b/docs/models/operations/createapirequestbody.md new file mode 100644 index 0000000..ec9f77b --- /dev/null +++ b/docs/models/operations/createapirequestbody.md @@ -0,0 +1,8 @@ +# CreateAPIRequestBody + + +## Fields + +| Field | Type | Required | Description | Example | +| --------------------------------------------------- | --------------------------------------------------- | --------------------------------------------------- | --------------------------------------------------- | --------------------------------------------------- | +| `Name` | *string* | :heavy_check_mark: | The name for your API. This is not customer facing. | my-api | \ No newline at end of file diff --git a/docs/models/operations/createapiresponsebody.md b/docs/models/operations/createapiresponsebody.md new file mode 100644 index 0000000..1a708f2 --- /dev/null +++ b/docs/models/operations/createapiresponsebody.md @@ -0,0 +1,10 @@ +# CreateAPIResponseBody + +The configuration for an api + + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------ | ------------------ | ------------------ | ------------------ | ------------------ | +| `APIID` | *string* | :heavy_check_mark: | The id of the api | api_134 | \ No newline at end of file diff --git a/docs/models/operations/createkeyrequestbody.md b/docs/models/operations/createkeyrequestbody.md new file mode 100644 index 0000000..de42b13 --- /dev/null +++ b/docs/models/operations/createkeyrequestbody.md @@ -0,0 +1,20 @@ +# CreateKeyRequestBody + + +## Fields + +| Field | Type | Required | Description | Example | +| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `APIID` | *string* | :heavy_check_mark: | Choose an `API` where this key should be created. | api_123 | +| `Prefix` | **string* | :heavy_minus_sign: | To make it easier for your users to understand which product an api key belongs to, you can add prefix them.

For example Stripe famously prefixes their customer ids with cus_ or their api keys with sk_live_.

The underscore is automatically added if you are defining a prefix, for example: "prefix": "abc" will result in a key like abc_xxxxxxxxx
| | +| `Name` | **string* | :heavy_minus_sign: | The name for your Key. This is not customer facing. | my key | +| `ByteLength` | **int64* | :heavy_minus_sign: | The byte length used to generate your key determines its entropy as well as its length. Higher is better, but keys become longer and more annoying to handle. The default is 16 bytes, or 2^^128 possible combinations. | | +| `OwnerID` | **string* | :heavy_minus_sign: | Your user’s Id. This will provide a link between Unkey and your customer record.
When validating a key, we will return this back to you, so you can clearly identify your user from their api key. | team_123 | +| `Meta` | map[string]*interface{}* | :heavy_minus_sign: | This is a place for dynamic meta data, anything that feels useful for you should go here | {
"billingTier": "PRO",
"trialEnds": "2023-06-16T17:16:37.161Z"
} | +| `Roles` | []*string* | :heavy_minus_sign: | A list of roles that this key should have. If the role does not exist, an error is thrown | [
"admin",
"finance"
] | +| `Expires` | **int64* | :heavy_minus_sign: | You can auto expire keys by providing a unix timestamp in milliseconds. Once Keys expire they will automatically be disabled and are no longer valid unless you enable them again. | 1623869797161 | +| `Remaining` | **int64* | :heavy_minus_sign: | You can limit the number of requests a key can make. Once a key reaches 0 remaining requests, it will automatically be disabled and is no longer valid unless you update it.

[Learn more](https://unkey.dev/docs/features/remaining) | 1000 | +| `Refill` | [*operations.Refill](../../models/operations/refill.md) | :heavy_minus_sign: | Unkey enables you to refill verifications for each key at regular intervals. | {
"interval": "daily",
"amount": 100
} | +| `Ratelimit` | [*operations.Ratelimit](../../models/operations/ratelimit.md) | :heavy_minus_sign: | Unkey comes with per-key ratelimiting out of the box. | {
"type": "fast",
"limit": 10,
"refillRate": 1,
"refillInterval": 60
} | +| `Enabled` | **bool* | :heavy_minus_sign: | Sets if key is enabled or disabled. Disabled keys are not valid. | false | +| `Environment` | **string* | :heavy_minus_sign: | Environments allow you to divide your keyspace.

Some applications like Stripe, Clerk, WorkOS and others have a concept of "live" and "test" keys to
give the developer a way to develop their own application without the risk of modifying real world
resources.

When you set an environment, we will return it back to you when validating the key, so you can
handle it correctly.
| | \ No newline at end of file diff --git a/docs/models/operations/createkeyresponsebody.md b/docs/models/operations/createkeyresponsebody.md new file mode 100644 index 0000000..fc9d8a9 --- /dev/null +++ b/docs/models/operations/createkeyresponsebody.md @@ -0,0 +1,11 @@ +# CreateKeyResponseBody + +The configuration for an api + + +## Fields + +| Field | Type | Required | Description | Example | +| ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | +| `KeyID` | *string* | :heavy_check_mark: | The id of the key. This is not a secret and can be stored as a reference if you wish. You need the keyId to update or delete a key later. | key_123 | +| `Key` | *string* | :heavy_check_mark: | The newly created api key, do not store this on your own system but pass it along to your user. | prefix_xxxxxxxxx | \ No newline at end of file diff --git a/docs/models/operations/deleteapirequestbody.md b/docs/models/operations/deleteapirequestbody.md new file mode 100644 index 0000000..89cbc50 --- /dev/null +++ b/docs/models/operations/deleteapirequestbody.md @@ -0,0 +1,8 @@ +# DeleteAPIRequestBody + + +## Fields + +| Field | Type | Required | Description | Example | +| --------------------------- | --------------------------- | --------------------------- | --------------------------- | --------------------------- | +| `APIID` | *string* | :heavy_check_mark: | The id of the api to delete | api_1234 | \ No newline at end of file diff --git a/docs/models/operations/deleteapiresponsebody.md b/docs/models/operations/deleteapiresponsebody.md new file mode 100644 index 0000000..e711285 --- /dev/null +++ b/docs/models/operations/deleteapiresponsebody.md @@ -0,0 +1,9 @@ +# DeleteAPIResponseBody + +The api was successfully deleted, it may take up to 30s for this to take effect in all regions + + +## Fields + +| Field | Type | Required | Description | +| ----------- | ----------- | ----------- | ----------- | \ No newline at end of file diff --git a/docs/models/operations/deletekeyrequestbody.md b/docs/models/operations/deletekeyrequestbody.md new file mode 100644 index 0000000..2336360 --- /dev/null +++ b/docs/models/operations/deletekeyrequestbody.md @@ -0,0 +1,8 @@ +# DeleteKeyRequestBody + + +## Fields + +| Field | Type | Required | Description | Example | +| --------------------------- | --------------------------- | --------------------------- | --------------------------- | --------------------------- | +| `KeyID` | *string* | :heavy_check_mark: | The id of the key to revoke | key_1234 | \ No newline at end of file diff --git a/docs/models/operations/deletekeyresponsebody.md b/docs/models/operations/deletekeyresponsebody.md new file mode 100644 index 0000000..8399816 --- /dev/null +++ b/docs/models/operations/deletekeyresponsebody.md @@ -0,0 +1,9 @@ +# DeleteKeyResponseBody + +The key was successfully revoked, it may take up to 30s for this to take effect in all regions + + +## Fields + +| Field | Type | Required | Description | +| ----------- | ----------- | ----------- | ----------- | \ No newline at end of file diff --git a/docs/models/operations/deprecatedcreatekeyratelimit.md b/docs/models/operations/deprecatedcreatekeyratelimit.md new file mode 100644 index 0000000..d09aab3 --- /dev/null +++ b/docs/models/operations/deprecatedcreatekeyratelimit.md @@ -0,0 +1,13 @@ +# DeprecatedCreateKeyRatelimit + +Unkey comes with per-key ratelimiting out of the box. + + +## Fields + +| Field | Type | Required | Description | +| -------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | +| `Type` | [*operations.DeprecatedCreateKeyType](../../models/operations/deprecatedcreatekeytype.md) | :heavy_minus_sign: | Fast ratelimiting doesn't add latency, while consistent ratelimiting is more accurate.

[Learn more](https://unkey.dev/docs/features/ratelimiting) | +| `Limit` | *int64* | :heavy_check_mark: | The total amount of burstable requests. | +| `RefillRate` | *int64* | :heavy_check_mark: | How many tokens to refill during each refillInterval. | +| `RefillInterval` | *int64* | :heavy_check_mark: | Determines the speed at which tokens are refilled, in milliseconds. | \ No newline at end of file diff --git a/docs/models/operations/deprecatedcreatekeyrequestbody.md b/docs/models/operations/deprecatedcreatekeyrequestbody.md new file mode 100644 index 0000000..3bc3c30 --- /dev/null +++ b/docs/models/operations/deprecatedcreatekeyrequestbody.md @@ -0,0 +1,16 @@ +# DeprecatedCreateKeyRequestBody + + +## Fields + +| Field | Type | Required | Description | Example | +| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `APIID` | *string* | :heavy_check_mark: | Choose an `API` where this key should be created. | api_123 | +| `Prefix` | **string* | :heavy_minus_sign: | To make it easier for your users to understand which product an api key belongs to, you can add prefix them.

For example Stripe famously prefixes their customer ids with cus_ or their api keys with sk_live_.

The underscore is automatically added if you are defining a prefix, for example: "prefix": "abc" will result in a key like abc_xxxxxxxxx
| | +| `Name` | **string* | :heavy_minus_sign: | The name for your Key. This is not customer facing. | my key | +| `ByteLength` | **int64* | :heavy_minus_sign: | The byte length used to generate your key determines its entropy as well as its length. Higher is better, but keys become longer and more annoying to handle. The default is 16 bytes, or 2^^128 possible combinations. | | +| `OwnerID` | **string* | :heavy_minus_sign: | Your user’s Id. This will provide a link between Unkey and your customer record.
When validating a key, we will return this back to you, so you can clearly identify your user from their api key. | team_123 | +| `Meta` | map[string]*interface{}* | :heavy_minus_sign: | This is a place for dynamic meta data, anything that feels useful for you should go here | {
"billingTier": "PRO",
"trialEnds": "2023-06-16T17:16:37.161Z"
} | +| `Expires` | **int64* | :heavy_minus_sign: | You can auto expire keys by providing a unix timestamp in milliseconds. Once Keys expire they will automatically be disabled and are no longer valid unless you enable them again. | 1623869797161 | +| `Remaining` | **int64* | :heavy_minus_sign: | You can limit the number of requests a key can make. Once a key reaches 0 remaining requests, it will automatically be disabled and is no longer valid unless you update it.

[Learn more](https://unkey.dev/docs/features/remaining) | 1000 | +| `Ratelimit` | [*operations.DeprecatedCreateKeyRatelimit](../../models/operations/deprecatedcreatekeyratelimit.md) | :heavy_minus_sign: | Unkey comes with per-key ratelimiting out of the box. | {
"type": "fast",
"limit": 10,
"refillRate": 1,
"refillInterval": 60
} | \ No newline at end of file diff --git a/docs/models/operations/deprecatedcreatekeyresponsebody.md b/docs/models/operations/deprecatedcreatekeyresponsebody.md new file mode 100644 index 0000000..bf1ffd0 --- /dev/null +++ b/docs/models/operations/deprecatedcreatekeyresponsebody.md @@ -0,0 +1,11 @@ +# DeprecatedCreateKeyResponseBody + +The configuration for an api + + +## Fields + +| Field | Type | Required | Description | Example | +| ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | +| `KeyID` | *string* | :heavy_check_mark: | The id of the key. This is not a secret and can be stored as a reference if you wish. You need the keyId to update or delete a key later. | key_123 | +| `Key` | *string* | :heavy_check_mark: | The newly created api key, do not store this on your own system but pass it along to your user. | prefix_xxxxxxxxx | \ No newline at end of file diff --git a/docs/models/operations/deprecatedcreatekeytype.md b/docs/models/operations/deprecatedcreatekeytype.md new file mode 100644 index 0000000..284c6ae --- /dev/null +++ b/docs/models/operations/deprecatedcreatekeytype.md @@ -0,0 +1,14 @@ +# DeprecatedCreateKeyType + +Fast ratelimiting doesn't add latency, while consistent ratelimiting is more accurate. + +Learn more + + + +## Values + +| Name | Value | +| ----------------------------------- | ----------------------------------- | +| `DeprecatedCreateKeyTypeFast` | fast | +| `DeprecatedCreateKeyTypeConsistent` | consistent | \ No newline at end of file diff --git a/docs/models/operations/deprecatedlistkeysrequest.md b/docs/models/operations/deprecatedlistkeysrequest.md new file mode 100644 index 0000000..41f95ec --- /dev/null +++ b/docs/models/operations/deprecatedlistkeysrequest.md @@ -0,0 +1,11 @@ +# DeprecatedListKeysRequest + + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------ | ------------------ | ------------------ | ------------------ | ------------------ | +| `APIID` | *string* | :heavy_check_mark: | N/A | api_1234 | +| `Limit` | **int64* | :heavy_minus_sign: | N/A | 100 | +| `Offset` | **float64* | :heavy_minus_sign: | N/A | | +| `OwnerID` | **string* | :heavy_minus_sign: | N/A | | \ No newline at end of file diff --git a/docs/models/operations/deprecatedlistkeysresponsebody.md b/docs/models/operations/deprecatedlistkeysresponsebody.md new file mode 100644 index 0000000..7784e1b --- /dev/null +++ b/docs/models/operations/deprecatedlistkeysresponsebody.md @@ -0,0 +1,11 @@ +# DeprecatedListKeysResponseBody + +Keys belonging to the api + + +## Fields + +| Field | Type | Required | Description | +| -------------------------------------------------- | -------------------------------------------------- | -------------------------------------------------- | -------------------------------------------------- | +| `Keys` | [][components.Key](../../models/components/key.md) | :heavy_check_mark: | N/A | +| `Total` | *int64* | :heavy_check_mark: | The total number of keys for this api | \ No newline at end of file diff --git a/docs/models/operations/deprecatedverifykeyratelimit.md b/docs/models/operations/deprecatedverifykeyratelimit.md new file mode 100644 index 0000000..d915bbb --- /dev/null +++ b/docs/models/operations/deprecatedverifykeyratelimit.md @@ -0,0 +1,12 @@ +# DeprecatedVerifyKeyRatelimit + +The ratelimit configuration for this key. If this field is null or undefined, the key has no ratelimit. + + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | +| `Limit` | *float64* | :heavy_check_mark: | Maximum number of requests that can be made inside a window | 10 | +| `Remaining` | *float64* | :heavy_check_mark: | Remaining requests after this verification | 9 | +| `Reset` | *float64* | :heavy_check_mark: | Unix timestamp in milliseconds when the ratelimit will reset | 3600000 | \ No newline at end of file diff --git a/docs/models/operations/deprecatedverifykeyrequestbody.md b/docs/models/operations/deprecatedverifykeyrequestbody.md new file mode 100644 index 0000000..0223a81 --- /dev/null +++ b/docs/models/operations/deprecatedverifykeyrequestbody.md @@ -0,0 +1,9 @@ +# DeprecatedVerifyKeyRequestBody + + +## Fields + +| Field | Type | Required | Description | Example | +| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `APIID` | **string* | :heavy_minus_sign: | The id of the api where the key belongs to. This is optional for now but will be required soon.
The key will be verified against the api's configuration. If the key does not belong to the api, the verification will fail. | api_1234 | +| `Key` | *string* | :heavy_check_mark: | The key to verify | sk_1234 | \ No newline at end of file diff --git a/docs/models/operations/deprecatedverifykeyresponsebody.md b/docs/models/operations/deprecatedverifykeyresponsebody.md new file mode 100644 index 0000000..a7248fe --- /dev/null +++ b/docs/models/operations/deprecatedverifykeyresponsebody.md @@ -0,0 +1,20 @@ +# DeprecatedVerifyKeyResponseBody + +The verification result + + +## Fields + +| Field | Type | Required | Description | Example | +| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `KeyID` | **string* | :heavy_minus_sign: | The id of the key | key_1234 | +| `Valid` | *bool* | :heavy_check_mark: | Whether the key is valid or not.
A key could be invalid for a number of reasons, for example if it has expired, has no more verifications left or if it has been deleted. | true | +| `Name` | **string* | :heavy_minus_sign: | The name of the key, give keys a name to easily identifiy their purpose | Customer X | +| `OwnerID` | **string* | :heavy_minus_sign: | The id of the tenant associated with this key. Use whatever reference you have in your system to identify the tenant. When verifying the key, we will send this field back to you, so you know who is accessing your API. | user_123 | +| `Meta` | map[string]*interface{}* | :heavy_minus_sign: | Any additional metadata you want to store with the key | {
"roles": [
"admin",
"user"
],
"stripeCustomerId": "cus_1234"
} | +| `CreatedAt` | **float64* | :heavy_minus_sign: | The unix timestamp in milliseconds when the key was created | 0 | +| `DeletedAt` | **float64* | :heavy_minus_sign: | The unix timestamp in milliseconds when the key was deleted. We don't delete the key outright, you can restore it later. | 0 | +| `Expires` | **float64* | :heavy_minus_sign: | The unix timestamp in milliseconds when the key will expire. If this field is null or undefined, the key is not expiring. | 123 | +| `Ratelimit` | [*operations.DeprecatedVerifyKeyRatelimit](../../models/operations/deprecatedverifykeyratelimit.md) | :heavy_minus_sign: | The ratelimit configuration for this key. If this field is null or undefined, the key has no ratelimit. | {
"limit": 10,
"remaining": 9,
"reset": 3600000
} | +| `Remaining` | **float64* | :heavy_minus_sign: | The number of requests that can be made with this key before it becomes invalid. If this field is null or undefined, the key has no request limit. | 1000 | +| `Code` | [*operations.Code](../../models/operations/code.md) | :heavy_minus_sign: | If the key is invalid this field will be set to the reason why it is invalid.
Possible values are:
- NOT_FOUND: the key does not exist or has expired
- FORBIDDEN: the key is not allowed to access the api
- USAGE_EXCEEDED: the key has exceeded its request limit
- RATE_LIMITED: the key has been ratelimited,
- INSUFFICIENT_PERMISSIONS: you do not have the required permissions to perform this action
| NOT_FOUND | \ No newline at end of file diff --git a/docs/models/operations/getapirequest.md b/docs/models/operations/getapirequest.md new file mode 100644 index 0000000..083929e --- /dev/null +++ b/docs/models/operations/getapirequest.md @@ -0,0 +1,8 @@ +# GetAPIRequest + + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------ | ------------------ | ------------------ | ------------------ | ------------------ | +| `APIID` | *string* | :heavy_check_mark: | N/A | api_1234 | \ No newline at end of file diff --git a/docs/models/operations/getapiresponsebody.md b/docs/models/operations/getapiresponsebody.md new file mode 100644 index 0000000..6c391f5 --- /dev/null +++ b/docs/models/operations/getapiresponsebody.md @@ -0,0 +1,12 @@ +# GetAPIResponseBody + +The configuration for an api + + +## Fields + +| Field | Type | Required | Description | Example | +| ----------------------------------------------------------------------- | ----------------------------------------------------------------------- | ----------------------------------------------------------------------- | ----------------------------------------------------------------------- | ----------------------------------------------------------------------- | +| `ID` | *string* | :heavy_check_mark: | The id of the key | key_1234 | +| `WorkspaceID` | *string* | :heavy_check_mark: | The id of the workspace that owns the api | ws_1234 | +| `Name` | **string* | :heavy_minus_sign: | The name of the api. This is internal and your users will not see this. | Unkey - Production | \ No newline at end of file diff --git a/docs/models/operations/getkeyrequest.md b/docs/models/operations/getkeyrequest.md new file mode 100644 index 0000000..07227c6 --- /dev/null +++ b/docs/models/operations/getkeyrequest.md @@ -0,0 +1,8 @@ +# GetKeyRequest + + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------ | ------------------ | ------------------ | ------------------ | ------------------ | +| `KeyID` | *string* | :heavy_check_mark: | N/A | key_1234 | \ No newline at end of file diff --git a/docs/models/operations/getverificationsrequest.md b/docs/models/operations/getverificationsrequest.md new file mode 100644 index 0000000..54730d8 --- /dev/null +++ b/docs/models/operations/getverificationsrequest.md @@ -0,0 +1,12 @@ +# GetVerificationsRequest + + +## Fields + +| Field | Type | Required | Description | Example | +| ----------------------------------------------------------------------------- | ----------------------------------------------------------------------------- | ----------------------------------------------------------------------------- | ----------------------------------------------------------------------------- | ----------------------------------------------------------------------------- | +| `KeyID` | **string* | :heavy_minus_sign: | N/A | key_1234 | +| `OwnerID` | **string* | :heavy_minus_sign: | N/A | chronark | +| `Start` | **int64* | :heavy_minus_sign: | N/A | 1620000000000 | +| `End` | **int64* | :heavy_minus_sign: | N/A | 1620000000000 | +| `Granularity` | [*operations.Granularity](../../models/operations/granularity.md) | :heavy_minus_sign: | The granularity of the usage data to fetch, currently only `day` is supported | day | \ No newline at end of file diff --git a/docs/models/operations/getverificationsresponsebody.md b/docs/models/operations/getverificationsresponsebody.md new file mode 100644 index 0000000..74999bc --- /dev/null +++ b/docs/models/operations/getverificationsresponsebody.md @@ -0,0 +1,10 @@ +# GetVerificationsResponseBody + +Usage numbers over time + + +## Fields + +| Field | Type | Required | Description | +| ---------------------------------------------------------------------- | ---------------------------------------------------------------------- | ---------------------------------------------------------------------- | ---------------------------------------------------------------------- | +| `Verifications` | [][operations.Verifications](../../models/operations/verifications.md) | :heavy_check_mark: | N/A | \ No newline at end of file diff --git a/docs/models/operations/granularity.md b/docs/models/operations/granularity.md new file mode 100644 index 0000000..892e3b4 --- /dev/null +++ b/docs/models/operations/granularity.md @@ -0,0 +1,10 @@ +# Granularity + +The granularity of the usage data to fetch, currently only `day` is supported + + +## Values + +| Name | Value | +| ---------------- | ---------------- | +| `GranularityDay` | day | \ No newline at end of file diff --git a/docs/models/operations/hash.md b/docs/models/operations/hash.md new file mode 100644 index 0000000..2dd3176 --- /dev/null +++ b/docs/models/operations/hash.md @@ -0,0 +1,9 @@ +# Hash + + +## Fields + +| Field | Type | Required | Description | +| -------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | +| `Value` | *string* | :heavy_check_mark: | The hashed and encoded key | +| `Variant` | [operations.Variant](../../models/operations/variant.md) | :heavy_check_mark: | The algorithm for hashing and encoding, currently only sha256 and base64 are supported | \ No newline at end of file diff --git a/docs/models/operations/interval.md b/docs/models/operations/interval.md new file mode 100644 index 0000000..8b93fce --- /dev/null +++ b/docs/models/operations/interval.md @@ -0,0 +1,11 @@ +# Interval + +Unkey will automatically refill verifications at the set interval. + + +## Values + +| Name | Value | +| ----------------- | ----------------- | +| `IntervalDaily` | daily | +| `IntervalMonthly` | monthly | \ No newline at end of file diff --git a/docs/models/operations/limitrequestbody.md b/docs/models/operations/limitrequestbody.md new file mode 100644 index 0000000..bf85bdf --- /dev/null +++ b/docs/models/operations/limitrequestbody.md @@ -0,0 +1,15 @@ +# LimitRequestBody + + +## Fields + +| Field | Type | Required | Description | Example | +| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `Namespace` | **string* | :heavy_minus_sign: | Namespaces group different limits together for better analytics. You might have a namespace for your public API and one for internal tRPC routes. | email.outbound | +| `Identifier` | *string* | :heavy_check_mark: | Identifier of your user, this can be their userId, an email, an ip or anything else. | user_123 | +| `Limit` | *int64* | :heavy_check_mark: | How many requests may pass in a given window. | 10 | +| `Duration` | *int64* | :heavy_check_mark: | The window duration in milliseconds | 60000 | +| `Cost` | **int64* | :heavy_minus_sign: | Expensive requests may use up more tokens. You can specify a cost to the request here and we'll deduct this many tokens in the current window. If there are not enough tokens left, the request is denied. | 2 | +| `Async` | **bool* | :heavy_minus_sign: | Async will return a response immediately, lowering latency at the cost of accuracy. | | +| `Meta` | map[string]*interface{}* | :heavy_minus_sign: | Attach any metadata to this request | | +| `Resources` | [][operations.Resources](../../models/operations/resources.md) | :heavy_minus_sign: | Resources that are about to be accessed by the user | [
{
"type": "project",
"id": "p_123",
"name": "dub"
}
] | \ No newline at end of file diff --git a/docs/models/operations/limitresponsebody.md b/docs/models/operations/limitresponsebody.md new file mode 100644 index 0000000..5bf52c0 --- /dev/null +++ b/docs/models/operations/limitresponsebody.md @@ -0,0 +1,11 @@ +# LimitResponseBody + + +## Fields + +| Field | Type | Required | Description | Example | +| -------------------------------------------------------------------------- | -------------------------------------------------------------------------- | -------------------------------------------------------------------------- | -------------------------------------------------------------------------- | -------------------------------------------------------------------------- | +| `Success` | *bool* | :heavy_check_mark: | Returns true if the request should be processed, false if it was rejected. | true | +| `Limit` | *float64* | :heavy_check_mark: | How many requests are allowed within a window. | 10 | +| `Remaining` | *float64* | :heavy_check_mark: | How many requests can still be made in the current window. | 9 | +| `Reset` | *float64* | :heavy_check_mark: | A unix millisecond timestamp when the limits reset. | 1709804263654 | \ No newline at end of file diff --git a/docs/models/operations/listkeysrequest.md b/docs/models/operations/listkeysrequest.md new file mode 100644 index 0000000..7fd1b64 --- /dev/null +++ b/docs/models/operations/listkeysrequest.md @@ -0,0 +1,11 @@ +# ListKeysRequest + + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------ | ------------------ | ------------------ | ------------------ | ------------------ | +| `APIID` | *string* | :heavy_check_mark: | N/A | api_1234 | +| `Limit` | **int64* | :heavy_minus_sign: | N/A | 100 | +| `Cursor` | **string* | :heavy_minus_sign: | N/A | | +| `OwnerID` | **string* | :heavy_minus_sign: | N/A | | \ No newline at end of file diff --git a/docs/models/operations/listkeysresponsebody.md b/docs/models/operations/listkeysresponsebody.md new file mode 100644 index 0000000..7019bdd --- /dev/null +++ b/docs/models/operations/listkeysresponsebody.md @@ -0,0 +1,12 @@ +# ListKeysResponseBody + +The configuration for an api + + +## Fields + +| Field | Type | Required | Description | Example | +| --------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------- | +| `Keys` | [][components.Key](../../models/components/key.md) | :heavy_check_mark: | N/A | | +| `Cursor` | **string* | :heavy_minus_sign: | The cursor to use for the next page of results, if no cursor is returned, there are no more results | eyJrZXkiOiJrZXlfMTIzNCJ9 | +| `Total` | *int64* | :heavy_check_mark: | The total number of keys for this api | | \ No newline at end of file diff --git a/docs/models/operations/op.md b/docs/models/operations/op.md new file mode 100644 index 0000000..ea8776f --- /dev/null +++ b/docs/models/operations/op.md @@ -0,0 +1,12 @@ +# Op + +The operation you want to perform on the remaining count + + +## Values + +| Name | Value | +| ------------- | ------------- | +| `OpIncrement` | increment | +| `OpDecrement` | decrement | +| `OpSet` | set | \ No newline at end of file diff --git a/docs/models/operations/ratelimit.md b/docs/models/operations/ratelimit.md new file mode 100644 index 0000000..7caa3bf --- /dev/null +++ b/docs/models/operations/ratelimit.md @@ -0,0 +1,13 @@ +# Ratelimit + +Unkey comes with per-key ratelimiting out of the box. + + +## Fields + +| Field | Type | Required | Description | +| -------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | +| `Type` | [*operations.Type](../../models/operations/type.md) | :heavy_minus_sign: | Fast ratelimiting doesn't add latency, while consistent ratelimiting is more accurate.

[Learn more](https://unkey.dev/docs/features/ratelimiting) | +| `Limit` | *int64* | :heavy_check_mark: | The total amount of burstable requests. | +| `RefillRate` | *int64* | :heavy_check_mark: | How many tokens to refill during each refillInterval. | +| `RefillInterval` | *int64* | :heavy_check_mark: | Determines the speed at which tokens are refilled, in milliseconds. | \ No newline at end of file diff --git a/docs/models/operations/refill.md b/docs/models/operations/refill.md new file mode 100644 index 0000000..b94bf6e --- /dev/null +++ b/docs/models/operations/refill.md @@ -0,0 +1,11 @@ +# Refill + +Unkey enables you to refill verifications for each key at regular intervals. + + +## Fields + +| Field | Type | Required | Description | +| -------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- | +| `Interval` | [operations.Interval](../../models/operations/interval.md) | :heavy_check_mark: | Unkey will automatically refill verifications at the set interval. | +| `Amount` | *int64* | :heavy_check_mark: | The number of verifications to refill for each occurrence is determined individually for each key. | \ No newline at end of file diff --git a/docs/models/operations/requestbody.md b/docs/models/operations/requestbody.md new file mode 100644 index 0000000..006e79e --- /dev/null +++ b/docs/models/operations/requestbody.md @@ -0,0 +1,21 @@ +# RequestBody + + +## Fields + +| Field | Type | Required | Description | Example | +| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `APIID` | *string* | :heavy_check_mark: | Choose an `API` where this key should be created. | api_123 | +| `Prefix` | **string* | :heavy_minus_sign: | To make it easier for your users to understand which product an api key belongs to, you can add prefix them.

For example Stripe famously prefixes their customer ids with cus_ or their api keys with sk_live_.

The underscore is automatically added if you are defining a prefix, for example: "prefix": "abc" will result in a key like abc_xxxxxxxxx
| | +| `Name` | **string* | :heavy_minus_sign: | The name for your Key. This is not customer facing. | my key | +| `Hash` | [operations.Hash](../../models/operations/hash.md) | :heavy_check_mark: | N/A | | +| `Start` | **string* | :heavy_minus_sign: | The first 4 characters of the key. If a prefix is used, it should be the prefix plus 4 characters. | unkey_32kq | +| `OwnerID` | **string* | :heavy_minus_sign: | Your user’s Id. This will provide a link between Unkey and your customer record.
When validating a key, we will return this back to you, so you can clearly identify your user from their api key. | team_123 | +| `Meta` | map[string]*interface{}* | :heavy_minus_sign: | This is a place for dynamic meta data, anything that feels useful for you should go here | {
"billingTier": "PRO",
"trialEnds": "2023-06-16T17:16:37.161Z"
} | +| `Roles` | []*string* | :heavy_minus_sign: | A list of roles that this key should have. If the role does not exist, an error is thrown | [
"admin",
"finance"
] | +| `Expires` | **int64* | :heavy_minus_sign: | You can auto expire keys by providing a unix timestamp in milliseconds. Once Keys expire they will automatically be disabled and are no longer valid unless you enable them again. | 1623869797161 | +| `Remaining` | **int64* | :heavy_minus_sign: | You can limit the number of requests a key can make. Once a key reaches 0 remaining requests, it will automatically be disabled and is no longer valid unless you update it.

[Learn more](https://unkey.dev/docs/features/remaining) | 1000 | +| `Refill` | [*operations.V1MigrationsCreateKeysRefill](../../models/operations/v1migrationscreatekeysrefill.md) | :heavy_minus_sign: | Unkey enables you to refill verifications for each key at regular intervals. | {
"interval": "daily",
"amount": 100
} | +| `Ratelimit` | [*operations.V1MigrationsCreateKeysRatelimit](../../models/operations/v1migrationscreatekeysratelimit.md) | :heavy_minus_sign: | Unkey comes with per-key ratelimiting out of the box. | {
"type": "fast",
"limit": 10,
"refillRate": 1,
"refillInterval": 60
} | +| `Enabled` | **bool* | :heavy_minus_sign: | Sets if key is enabled or disabled. Disabled keys are not valid. | false | +| `Environment` | **string* | :heavy_minus_sign: | Environments allow you to divide your keyspace.

Some applications like Stripe, Clerk, WorkOS and others have a concept of "live" and "test" keys to
give the developer a way to develop their own application without the risk of modifying real world
resources.

When you set an environment, we will return it back to you when validating the key, so you can
handle it correctly.
| | \ No newline at end of file diff --git a/docs/models/operations/resources.md b/docs/models/operations/resources.md new file mode 100644 index 0000000..58a9bb2 --- /dev/null +++ b/docs/models/operations/resources.md @@ -0,0 +1,11 @@ +# Resources + + +## Fields + +| Field | Type | Required | Description | Example | +| --------------------------------------- | --------------------------------------- | --------------------------------------- | --------------------------------------- | --------------------------------------- | +| `Type` | *string* | :heavy_check_mark: | The type of resource | organization | +| `ID` | *string* | :heavy_check_mark: | The unique identifier for the resource | org_123 | +| `Name` | **string* | :heavy_minus_sign: | A human readable name for this resource | unkey | +| `Meta` | map[string]*interface{}* | :heavy_minus_sign: | Attach any metadata to this resources | | \ No newline at end of file diff --git a/docs/models/operations/services.md b/docs/models/operations/services.md new file mode 100644 index 0000000..200fc17 --- /dev/null +++ b/docs/models/operations/services.md @@ -0,0 +1,12 @@ +# Services + + +## Fields + +| Field | Type | Required | Description | Example | +| -------------------------------------------- | -------------------------------------------- | -------------------------------------------- | -------------------------------------------- | -------------------------------------------- | +| `Metrics` | *string* | :heavy_check_mark: | The name of the connected metrics service | AxiomMetrics | +| `Logger` | *string* | :heavy_check_mark: | The name of the connected logger service | AxiomLogger or ConsoleLogger | +| `Ratelimit` | *string* | :heavy_check_mark: | The name of the connected ratelimit service | | +| `Usagelimit` | *string* | :heavy_check_mark: | The name of the connected usagelimit service | | +| `Analytics` | *string* | :heavy_check_mark: | The name of the connected analytics service | | \ No newline at end of file diff --git a/docs/models/operations/type.md b/docs/models/operations/type.md new file mode 100644 index 0000000..e06fa5d --- /dev/null +++ b/docs/models/operations/type.md @@ -0,0 +1,14 @@ +# Type + +Fast ratelimiting doesn't add latency, while consistent ratelimiting is more accurate. + +Learn more + + + +## Values + +| Name | Value | +| ---------------- | ---------------- | +| `TypeFast` | fast | +| `TypeConsistent` | consistent | \ No newline at end of file diff --git a/docs/models/operations/updatekeyinterval.md b/docs/models/operations/updatekeyinterval.md new file mode 100644 index 0000000..ab87d91 --- /dev/null +++ b/docs/models/operations/updatekeyinterval.md @@ -0,0 +1,11 @@ +# UpdateKeyInterval + +Unkey will automatically refill verifications at the set interval. If null is used the refill functionality will be removed from the key. + + +## Values + +| Name | Value | +| -------------------------- | -------------------------- | +| `UpdateKeyIntervalDaily` | daily | +| `UpdateKeyIntervalMonthly` | monthly | \ No newline at end of file diff --git a/docs/models/operations/updatekeyratelimit.md b/docs/models/operations/updatekeyratelimit.md new file mode 100644 index 0000000..049e1ed --- /dev/null +++ b/docs/models/operations/updatekeyratelimit.md @@ -0,0 +1,13 @@ +# UpdateKeyRatelimit + +Unkey comes with per-key ratelimiting out of the box. Set `null` to disable. + + +## Fields + +| Field | Type | Required | Description | +| -------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | +| `Type` | [operations.UpdateKeyType](../../models/operations/updatekeytype.md) | :heavy_check_mark: | Fast ratelimiting doesn't add latency, while consistent ratelimiting is more accurate.

[Learn more](https://unkey.dev/docs/features/ratelimiting) | +| `Limit` | *int64* | :heavy_check_mark: | The total amount of burstable requests. | +| `RefillRate` | *int64* | :heavy_check_mark: | How many tokens to refill during each refillInterval. | +| `RefillInterval` | *int64* | :heavy_check_mark: | Determines the speed at which tokens are refilled, in milliseconds. | \ No newline at end of file diff --git a/docs/models/operations/updatekeyrefill.md b/docs/models/operations/updatekeyrefill.md new file mode 100644 index 0000000..e641c30 --- /dev/null +++ b/docs/models/operations/updatekeyrefill.md @@ -0,0 +1,11 @@ +# UpdateKeyRefill + +Unkey enables you to refill verifications for each key at regular intervals. + + +## Fields + +| Field | Type | Required | Description | +| ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | +| `Interval` | [operations.UpdateKeyInterval](../../models/operations/updatekeyinterval.md) | :heavy_check_mark: | Unkey will automatically refill verifications at the set interval. If null is used the refill functionality will be removed from the key. | +| `Amount` | *int64* | :heavy_check_mark: | The amount of verifications to refill for each occurrence is determined individually for each key. | \ No newline at end of file diff --git a/docs/models/operations/updatekeyrequestbody.md b/docs/models/operations/updatekeyrequestbody.md new file mode 100644 index 0000000..2939470 --- /dev/null +++ b/docs/models/operations/updatekeyrequestbody.md @@ -0,0 +1,16 @@ +# UpdateKeyRequestBody + + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `KeyID` | *string* | :heavy_check_mark: | The id of the key you want to modify | key_123 | +| `Name` | **string* | :heavy_minus_sign: | The name of the key | Customer X | +| `OwnerID` | **string* | :heavy_minus_sign: | The id of the tenant associated with this key. Use whatever reference you have in your system to identify the tenant. When verifying the key, we will send this field back to you, so you know who is accessing your API. | user_123 | +| `Meta` | map[string]*interface{}* | :heavy_minus_sign: | Any additional metadata you want to store with the key | {
"roles": [
"admin",
"user"
],
"stripeCustomerId": "cus_1234"
} | +| `Expires` | **float64* | :heavy_minus_sign: | The unix timestamp in milliseconds when the key will expire. If this field is null or undefined, the key is not expiring. | 0 | +| `Ratelimit` | [*operations.UpdateKeyRatelimit](../../models/operations/updatekeyratelimit.md) | :heavy_minus_sign: | Unkey comes with per-key ratelimiting out of the box. Set `null` to disable. | {
"type": "fast",
"limit": 10,
"refillRate": 1,
"refillInterval": 60
} | +| `Remaining` | **float64* | :heavy_minus_sign: | The number of requests that can be made with this key before it becomes invalid. Set `null` to disable. | 1000 | +| `Refill` | [*operations.UpdateKeyRefill](../../models/operations/updatekeyrefill.md) | :heavy_minus_sign: | Unkey enables you to refill verifications for each key at regular intervals. | {
"interval": "daily",
"amount": 100
} | +| `Enabled` | **bool* | :heavy_minus_sign: | Set if key is enabled or disabled. If disabled, the key cannot be used to verify. | true | \ No newline at end of file diff --git a/docs/models/operations/updatekeyresponsebody.md b/docs/models/operations/updatekeyresponsebody.md new file mode 100644 index 0000000..a647d6f --- /dev/null +++ b/docs/models/operations/updatekeyresponsebody.md @@ -0,0 +1,9 @@ +# UpdateKeyResponseBody + +The key was successfully updated, it may take up to 30s for this to take effect in all regions + + +## Fields + +| Field | Type | Required | Description | +| ----------- | ----------- | ----------- | ----------- | \ No newline at end of file diff --git a/docs/models/operations/updatekeytype.md b/docs/models/operations/updatekeytype.md new file mode 100644 index 0000000..4e2bfa4 --- /dev/null +++ b/docs/models/operations/updatekeytype.md @@ -0,0 +1,14 @@ +# UpdateKeyType + +Fast ratelimiting doesn't add latency, while consistent ratelimiting is more accurate. + +Learn more + + + +## Values + +| Name | Value | +| ------------------------- | ------------------------- | +| `UpdateKeyTypeFast` | fast | +| `UpdateKeyTypeConsistent` | consistent | \ No newline at end of file diff --git a/docs/models/operations/updateremainingrequestbody.md b/docs/models/operations/updateremainingrequestbody.md new file mode 100644 index 0000000..223b131 --- /dev/null +++ b/docs/models/operations/updateremainingrequestbody.md @@ -0,0 +1,10 @@ +# UpdateRemainingRequestBody + + +## Fields + +| Field | Type | Required | Description | Example | +| ----------------------------------------------------------------- | ----------------------------------------------------------------- | ----------------------------------------------------------------- | ----------------------------------------------------------------- | ----------------------------------------------------------------- | +| `KeyID` | *string* | :heavy_check_mark: | The id of the key you want to modify | key_123 | +| `Op` | [operations.Op](../../models/operations/op.md) | :heavy_check_mark: | The operation you want to perform on the remaining count | | +| `Value` | *int64* | :heavy_check_mark: | The value you want to set, add or subtract the remaining count by | 1 | \ No newline at end of file diff --git a/docs/models/operations/updateremainingresponsebody.md b/docs/models/operations/updateremainingresponsebody.md new file mode 100644 index 0000000..81c7032 --- /dev/null +++ b/docs/models/operations/updateremainingresponsebody.md @@ -0,0 +1,10 @@ +# UpdateRemainingResponseBody + +The configuration for an api + + +## Fields + +| Field | Type | Required | Description | Example | +| ---------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- | +| `Remaining` | *int64* | :heavy_check_mark: | The number of remaining requests for this key after updating it. `null` means unlimited. | 100 | \ No newline at end of file diff --git a/docs/models/operations/v1livenessresponsebody.md b/docs/models/operations/v1livenessresponsebody.md new file mode 100644 index 0000000..e51c2a8 --- /dev/null +++ b/docs/models/operations/v1livenessresponsebody.md @@ -0,0 +1,11 @@ +# V1LivenessResponseBody + +The configured services and their status + + +## Fields + +| Field | Type | Required | Description | +| ---------------------------------------------------------- | ---------------------------------------------------------- | ---------------------------------------------------------- | ---------------------------------------------------------- | +| `Status` | *string* | :heavy_check_mark: | The status of the server | +| `Services` | [operations.Services](../../models/operations/services.md) | :heavy_check_mark: | N/A | \ No newline at end of file diff --git a/docs/models/operations/v1migrationscreatekeysinterval.md b/docs/models/operations/v1migrationscreatekeysinterval.md new file mode 100644 index 0000000..7ec86d9 --- /dev/null +++ b/docs/models/operations/v1migrationscreatekeysinterval.md @@ -0,0 +1,11 @@ +# V1MigrationsCreateKeysInterval + +Unkey will automatically refill verifications at the set interval. + + +## Values + +| Name | Value | +| --------------------------------------- | --------------------------------------- | +| `V1MigrationsCreateKeysIntervalDaily` | daily | +| `V1MigrationsCreateKeysIntervalMonthly` | monthly | \ No newline at end of file diff --git a/docs/models/operations/v1migrationscreatekeysratelimit.md b/docs/models/operations/v1migrationscreatekeysratelimit.md new file mode 100644 index 0000000..cd5a254 --- /dev/null +++ b/docs/models/operations/v1migrationscreatekeysratelimit.md @@ -0,0 +1,13 @@ +# V1MigrationsCreateKeysRatelimit + +Unkey comes with per-key ratelimiting out of the box. + + +## Fields + +| Field | Type | Required | Description | +| -------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | +| `Type` | [*operations.V1MigrationsCreateKeysType](../../models/operations/v1migrationscreatekeystype.md) | :heavy_minus_sign: | Fast ratelimiting doesn't add latency, while consistent ratelimiting is more accurate.

[Learn more](https://unkey.dev/docs/features/ratelimiting) | +| `Limit` | *int64* | :heavy_check_mark: | The total amount of burstable requests. | +| `RefillRate` | *int64* | :heavy_check_mark: | How many tokens to refill during each refillInterval. | +| `RefillInterval` | *int64* | :heavy_check_mark: | Determines the speed at which tokens are refilled, in milliseconds. | \ No newline at end of file diff --git a/docs/models/operations/v1migrationscreatekeysrefill.md b/docs/models/operations/v1migrationscreatekeysrefill.md new file mode 100644 index 0000000..2f89e3e --- /dev/null +++ b/docs/models/operations/v1migrationscreatekeysrefill.md @@ -0,0 +1,11 @@ +# V1MigrationsCreateKeysRefill + +Unkey enables you to refill verifications for each key at regular intervals. + + +## Fields + +| Field | Type | Required | Description | +| ------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------ | +| `Interval` | [operations.V1MigrationsCreateKeysInterval](../../models/operations/v1migrationscreatekeysinterval.md) | :heavy_check_mark: | Unkey will automatically refill verifications at the set interval. | +| `Amount` | *int64* | :heavy_check_mark: | The number of verifications to refill for each occurrence is determined individually for each key. | \ No newline at end of file diff --git a/docs/models/operations/v1migrationscreatekeysresponsebody.md b/docs/models/operations/v1migrationscreatekeysresponsebody.md new file mode 100644 index 0000000..2f45349 --- /dev/null +++ b/docs/models/operations/v1migrationscreatekeysresponsebody.md @@ -0,0 +1,10 @@ +# V1MigrationsCreateKeysResponseBody + +The key ids of all created keys + + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | +| `KeyIds` | []*string* | :heavy_check_mark: | The ids of the keys. This is not a secret and can be stored as a reference if you wish. You need the keyId to update or delete a key later. | [
"key_123",
"key_456"
] | \ No newline at end of file diff --git a/docs/models/operations/v1migrationscreatekeystype.md b/docs/models/operations/v1migrationscreatekeystype.md new file mode 100644 index 0000000..fbc7b8d --- /dev/null +++ b/docs/models/operations/v1migrationscreatekeystype.md @@ -0,0 +1,14 @@ +# V1MigrationsCreateKeysType + +Fast ratelimiting doesn't add latency, while consistent ratelimiting is more accurate. + +Learn more + + + +## Values + +| Name | Value | +| -------------------------------------- | -------------------------------------- | +| `V1MigrationsCreateKeysTypeFast` | fast | +| `V1MigrationsCreateKeysTypeConsistent` | consistent | \ No newline at end of file diff --git a/docs/models/operations/variant.md b/docs/models/operations/variant.md new file mode 100644 index 0000000..f2cca3a --- /dev/null +++ b/docs/models/operations/variant.md @@ -0,0 +1,10 @@ +# Variant + +The algorithm for hashing and encoding, currently only sha256 and base64 are supported + + +## Values + +| Name | Value | +| --------------------- | --------------------- | +| `VariantSha256Base64` | sha256_base64 | \ No newline at end of file diff --git a/docs/models/operations/verifications.md b/docs/models/operations/verifications.md new file mode 100644 index 0000000..c4b5bab --- /dev/null +++ b/docs/models/operations/verifications.md @@ -0,0 +1,11 @@ +# Verifications + + +## Fields + +| Field | Type | Required | Description | Example | +| ---------------------------------------------------- | ---------------------------------------------------- | ---------------------------------------------------- | ---------------------------------------------------- | ---------------------------------------------------- | +| `Time` | *int64* | :heavy_check_mark: | The timestamp of the usage data | 1620000000000 | +| `Success` | *float64* | :heavy_check_mark: | The number of successful requests | 100 | +| `RateLimited` | *float64* | :heavy_check_mark: | The number of requests that were rate limited | 10 | +| `UsageExceeded` | *float64* | :heavy_check_mark: | The number of requests that exceeded the usage limit | 0 | \ No newline at end of file diff --git a/docs/models/sdkerrors/code.md b/docs/models/sdkerrors/code.md new file mode 100644 index 0000000..17172ec --- /dev/null +++ b/docs/models/sdkerrors/code.md @@ -0,0 +1,10 @@ +# Code + +A machine readable error code. + + +## Values + +| Name | Value | +| ---------------- | ---------------- | +| `CodeBadRequest` | BAD_REQUEST | \ No newline at end of file diff --git a/docs/models/sdkerrors/errbadrequest.md b/docs/models/sdkerrors/errbadrequest.md new file mode 100644 index 0000000..88118a9 --- /dev/null +++ b/docs/models/sdkerrors/errbadrequest.md @@ -0,0 +1,10 @@ +# ErrBadRequest + +The server cannot or will not process the request due to something that is perceived to be a client error (e.g., malformed request syntax, invalid request message framing, or deceptive request routing). + + +## Fields + +| Field | Type | Required | Description | +| -------------------------------------------------- | -------------------------------------------------- | -------------------------------------------------- | -------------------------------------------------- | +| `Error` | [sdkerrors.Error](../../models/sdkerrors/error.md) | :heavy_check_mark: | N/A | \ No newline at end of file diff --git a/docs/models/sdkerrors/errconflict.md b/docs/models/sdkerrors/errconflict.md new file mode 100644 index 0000000..21f3fbc --- /dev/null +++ b/docs/models/sdkerrors/errconflict.md @@ -0,0 +1,10 @@ +# ErrConflict + +This response is sent when a request conflicts with the current state of the server. + + +## Fields + +| Field | Type | Required | Description | +| ------------------------------------------------------------------------ | ------------------------------------------------------------------------ | ------------------------------------------------------------------------ | ------------------------------------------------------------------------ | +| `Error` | [sdkerrors.ErrConflictError](../../models/sdkerrors/errconflicterror.md) | :heavy_check_mark: | N/A | \ No newline at end of file diff --git a/docs/models/sdkerrors/errconflictcode.md b/docs/models/sdkerrors/errconflictcode.md new file mode 100644 index 0000000..e412f70 --- /dev/null +++ b/docs/models/sdkerrors/errconflictcode.md @@ -0,0 +1,10 @@ +# ErrConflictCode + +A machine readable error code. + + +## Values + +| Name | Value | +| ------------------------- | ------------------------- | +| `ErrConflictCodeConflict` | CONFLICT | \ No newline at end of file diff --git a/docs/models/sdkerrors/errconflicterror.md b/docs/models/sdkerrors/errconflicterror.md new file mode 100644 index 0000000..4819194 --- /dev/null +++ b/docs/models/sdkerrors/errconflicterror.md @@ -0,0 +1,11 @@ +# ErrConflictError + + +## Fields + +| Field | Type | Required | Description | Example | +| ---------------------------------------------------------------------- | ---------------------------------------------------------------------- | ---------------------------------------------------------------------- | ---------------------------------------------------------------------- | ---------------------------------------------------------------------- | +| `Code` | [sdkerrors.ErrConflictCode](../../models/sdkerrors/errconflictcode.md) | :heavy_check_mark: | A machine readable error code. | CONFLICT | +| `Docs` | *string* | :heavy_check_mark: | A link to our documentation with more details about this error code | https://unkey.dev/docs/api-reference/errors/code/CONFLICT | +| `Message` | *string* | :heavy_check_mark: | A human readable explanation of what went wrong | | +| `RequestID` | *string* | :heavy_check_mark: | Please always include the requestId in your error report | req_1234 | \ No newline at end of file diff --git a/docs/models/sdkerrors/errforbidden.md b/docs/models/sdkerrors/errforbidden.md new file mode 100644 index 0000000..1c5c3d0 --- /dev/null +++ b/docs/models/sdkerrors/errforbidden.md @@ -0,0 +1,10 @@ +# ErrForbidden + +The client does not have access rights to the content; that is, it is unauthorized, so the server is refusing to give the requested resource. Unlike 401 Unauthorized, the client's identity is known to the server. + + +## Fields + +| Field | Type | Required | Description | +| -------------------------------------------------------------------------- | -------------------------------------------------------------------------- | -------------------------------------------------------------------------- | -------------------------------------------------------------------------- | +| `Error` | [sdkerrors.ErrForbiddenError](../../models/sdkerrors/errforbiddenerror.md) | :heavy_check_mark: | N/A | \ No newline at end of file diff --git a/docs/models/sdkerrors/errforbiddencode.md b/docs/models/sdkerrors/errforbiddencode.md new file mode 100644 index 0000000..4c820de --- /dev/null +++ b/docs/models/sdkerrors/errforbiddencode.md @@ -0,0 +1,10 @@ +# ErrForbiddenCode + +A machine readable error code. + + +## Values + +| Name | Value | +| --------------------------- | --------------------------- | +| `ErrForbiddenCodeForbidden` | FORBIDDEN | \ No newline at end of file diff --git a/docs/models/sdkerrors/errforbiddenerror.md b/docs/models/sdkerrors/errforbiddenerror.md new file mode 100644 index 0000000..2913761 --- /dev/null +++ b/docs/models/sdkerrors/errforbiddenerror.md @@ -0,0 +1,11 @@ +# ErrForbiddenError + + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------------------------------------------------------------ | ------------------------------------------------------------------------ | ------------------------------------------------------------------------ | ------------------------------------------------------------------------ | ------------------------------------------------------------------------ | +| `Code` | [sdkerrors.ErrForbiddenCode](../../models/sdkerrors/errforbiddencode.md) | :heavy_check_mark: | A machine readable error code. | FORBIDDEN | +| `Docs` | *string* | :heavy_check_mark: | A link to our documentation with more details about this error code | https://unkey.dev/docs/api-reference/errors/code/FORBIDDEN | +| `Message` | *string* | :heavy_check_mark: | A human readable explanation of what went wrong | | +| `RequestID` | *string* | :heavy_check_mark: | Please always include the requestId in your error report | req_1234 | \ No newline at end of file diff --git a/docs/models/sdkerrors/errinternalservererror.md b/docs/models/sdkerrors/errinternalservererror.md new file mode 100644 index 0000000..c06da46 --- /dev/null +++ b/docs/models/sdkerrors/errinternalservererror.md @@ -0,0 +1,10 @@ +# ErrInternalServerError + +The server has encountered a situation it does not know how to handle. + + +## Fields + +| Field | Type | Required | Description | +| ---------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- | +| `Error` | [sdkerrors.ErrInternalServerErrorError](../../models/sdkerrors/errinternalservererrorerror.md) | :heavy_check_mark: | N/A | \ No newline at end of file diff --git a/docs/models/sdkerrors/errinternalservererrorcode.md b/docs/models/sdkerrors/errinternalservererrorcode.md new file mode 100644 index 0000000..e972713 --- /dev/null +++ b/docs/models/sdkerrors/errinternalservererrorcode.md @@ -0,0 +1,10 @@ +# ErrInternalServerErrorCode + +A machine readable error code. + + +## Values + +| Name | Value | +| ----------------------------------------------- | ----------------------------------------------- | +| `ErrInternalServerErrorCodeInternalServerError` | INTERNAL_SERVER_ERROR | \ No newline at end of file diff --git a/docs/models/sdkerrors/errinternalservererrorerror.md b/docs/models/sdkerrors/errinternalservererrorerror.md new file mode 100644 index 0000000..ada1282 --- /dev/null +++ b/docs/models/sdkerrors/errinternalservererrorerror.md @@ -0,0 +1,11 @@ +# ErrInternalServerErrorError + + +## Fields + +| Field | Type | Required | Description | Example | +| -------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------- | +| `Code` | [sdkerrors.ErrInternalServerErrorCode](../../models/sdkerrors/errinternalservererrorcode.md) | :heavy_check_mark: | A machine readable error code. | INTERNAL_SERVER_ERROR | +| `Docs` | *string* | :heavy_check_mark: | A link to our documentation with more details about this error code | https://unkey.dev/docs/api-reference/errors/code/INTERNAL_SERVER_ERROR | +| `Message` | *string* | :heavy_check_mark: | A human readable explanation of what went wrong | | +| `RequestID` | *string* | :heavy_check_mark: | Please always include the requestId in your error report | req_1234 | \ No newline at end of file diff --git a/docs/models/sdkerrors/errnotfound.md b/docs/models/sdkerrors/errnotfound.md new file mode 100644 index 0000000..ffcc666 --- /dev/null +++ b/docs/models/sdkerrors/errnotfound.md @@ -0,0 +1,10 @@ +# ErrNotFound + +The server cannot find the requested resource. In the browser, this means the URL is not recognized. In an API, this can also mean that the endpoint is valid but the resource itself does not exist. Servers may also send this response instead of 403 Forbidden to hide the existence of a resource from an unauthorized client. This response code is probably the most well known due to its frequent occurrence on the web. + + +## Fields + +| Field | Type | Required | Description | +| ------------------------------------------------------------------------ | ------------------------------------------------------------------------ | ------------------------------------------------------------------------ | ------------------------------------------------------------------------ | +| `Error` | [sdkerrors.ErrNotFoundError](../../models/sdkerrors/errnotfounderror.md) | :heavy_check_mark: | N/A | \ No newline at end of file diff --git a/docs/models/sdkerrors/errnotfoundcode.md b/docs/models/sdkerrors/errnotfoundcode.md new file mode 100644 index 0000000..922bd6b --- /dev/null +++ b/docs/models/sdkerrors/errnotfoundcode.md @@ -0,0 +1,10 @@ +# ErrNotFoundCode + +A machine readable error code. + + +## Values + +| Name | Value | +| ------------------------- | ------------------------- | +| `ErrNotFoundCodeNotFound` | NOT_FOUND | \ No newline at end of file diff --git a/docs/models/sdkerrors/errnotfounderror.md b/docs/models/sdkerrors/errnotfounderror.md new file mode 100644 index 0000000..6fd63cd --- /dev/null +++ b/docs/models/sdkerrors/errnotfounderror.md @@ -0,0 +1,11 @@ +# ErrNotFoundError + + +## Fields + +| Field | Type | Required | Description | Example | +| ---------------------------------------------------------------------- | ---------------------------------------------------------------------- | ---------------------------------------------------------------------- | ---------------------------------------------------------------------- | ---------------------------------------------------------------------- | +| `Code` | [sdkerrors.ErrNotFoundCode](../../models/sdkerrors/errnotfoundcode.md) | :heavy_check_mark: | A machine readable error code. | NOT_FOUND | +| `Docs` | *string* | :heavy_check_mark: | A link to our documentation with more details about this error code | https://unkey.dev/docs/api-reference/errors/code/NOT_FOUND | +| `Message` | *string* | :heavy_check_mark: | A human readable explanation of what went wrong | | +| `RequestID` | *string* | :heavy_check_mark: | Please always include the requestId in your error report | req_1234 | \ No newline at end of file diff --git a/docs/models/sdkerrors/error.md b/docs/models/sdkerrors/error.md new file mode 100644 index 0000000..55f7fd5 --- /dev/null +++ b/docs/models/sdkerrors/error.md @@ -0,0 +1,11 @@ +# Error + + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | +| `Code` | [sdkerrors.Code](../../models/sdkerrors/code.md) | :heavy_check_mark: | A machine readable error code. | BAD_REQUEST | +| `Docs` | *string* | :heavy_check_mark: | A link to our documentation with more details about this error code | https://unkey.dev/docs/api-reference/errors/code/BAD_REQUEST | +| `Message` | *string* | :heavy_check_mark: | A human readable explanation of what went wrong | | +| `RequestID` | *string* | :heavy_check_mark: | Please always include the requestId in your error report | req_1234 | \ No newline at end of file diff --git a/docs/models/sdkerrors/errtoomanyrequests.md b/docs/models/sdkerrors/errtoomanyrequests.md new file mode 100644 index 0000000..c32f473 --- /dev/null +++ b/docs/models/sdkerrors/errtoomanyrequests.md @@ -0,0 +1,10 @@ +# ErrTooManyRequests + +The user has sent too many requests in a given amount of time ("rate limiting") + + +## Fields + +| Field | Type | Required | Description | +| -------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | +| `Error` | [sdkerrors.ErrTooManyRequestsError](../../models/sdkerrors/errtoomanyrequestserror.md) | :heavy_check_mark: | N/A | \ No newline at end of file diff --git a/docs/models/sdkerrors/errtoomanyrequestscode.md b/docs/models/sdkerrors/errtoomanyrequestscode.md new file mode 100644 index 0000000..714a21c --- /dev/null +++ b/docs/models/sdkerrors/errtoomanyrequestscode.md @@ -0,0 +1,10 @@ +# ErrTooManyRequestsCode + +A machine readable error code. + + +## Values + +| Name | Value | +| --------------------------------------- | --------------------------------------- | +| `ErrTooManyRequestsCodeTooManyRequests` | TOO_MANY_REQUESTS | \ No newline at end of file diff --git a/docs/models/sdkerrors/errtoomanyrequestserror.md b/docs/models/sdkerrors/errtoomanyrequestserror.md new file mode 100644 index 0000000..edd0a2e --- /dev/null +++ b/docs/models/sdkerrors/errtoomanyrequestserror.md @@ -0,0 +1,11 @@ +# ErrTooManyRequestsError + + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------ | +| `Code` | [sdkerrors.ErrTooManyRequestsCode](../../models/sdkerrors/errtoomanyrequestscode.md) | :heavy_check_mark: | A machine readable error code. | TOO_MANY_REQUESTS | +| `Docs` | *string* | :heavy_check_mark: | A link to our documentation with more details about this error code | https://unkey.dev/docs/api-reference/errors/code/TOO_MANY_REQUESTS | +| `Message` | *string* | :heavy_check_mark: | A human readable explanation of what went wrong | | +| `RequestID` | *string* | :heavy_check_mark: | Please always include the requestId in your error report | req_1234 | \ No newline at end of file diff --git a/docs/models/sdkerrors/errunauthorized.md b/docs/models/sdkerrors/errunauthorized.md new file mode 100644 index 0000000..a31d9e6 --- /dev/null +++ b/docs/models/sdkerrors/errunauthorized.md @@ -0,0 +1,10 @@ +# ErrUnauthorized + +Although the HTTP standard specifies "unauthorized", semantically this response means "unauthenticated". That is, the client must authenticate itself to get the requested response. + + +## Fields + +| Field | Type | Required | Description | +| -------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | +| `Error` | [sdkerrors.ErrUnauthorizedError](../../models/sdkerrors/errunauthorizederror.md) | :heavy_check_mark: | N/A | \ No newline at end of file diff --git a/docs/models/sdkerrors/errunauthorizedcode.md b/docs/models/sdkerrors/errunauthorizedcode.md new file mode 100644 index 0000000..3b4c16b --- /dev/null +++ b/docs/models/sdkerrors/errunauthorizedcode.md @@ -0,0 +1,10 @@ +# ErrUnauthorizedCode + +A machine readable error code. + + +## Values + +| Name | Value | +| --------------------------------- | --------------------------------- | +| `ErrUnauthorizedCodeUnauthorized` | UNAUTHORIZED | \ No newline at end of file diff --git a/docs/models/sdkerrors/errunauthorizederror.md b/docs/models/sdkerrors/errunauthorizederror.md new file mode 100644 index 0000000..521b23f --- /dev/null +++ b/docs/models/sdkerrors/errunauthorizederror.md @@ -0,0 +1,11 @@ +# ErrUnauthorizedError + + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------ | +| `Code` | [sdkerrors.ErrUnauthorizedCode](../../models/sdkerrors/errunauthorizedcode.md) | :heavy_check_mark: | A machine readable error code. | UNAUTHORIZED | +| `Docs` | *string* | :heavy_check_mark: | A link to our documentation with more details about this error code | https://unkey.dev/docs/api-reference/errors/code/UNAUTHORIZED | +| `Message` | *string* | :heavy_check_mark: | A human readable explanation of what went wrong | | +| `RequestID` | *string* | :heavy_check_mark: | Please always include the requestId in your error report | req_1234 | \ No newline at end of file diff --git a/docs/sdks/apis/README.md b/docs/sdks/apis/README.md new file mode 100644 index 0000000..8294df9 --- /dev/null +++ b/docs/sdks/apis/README.md @@ -0,0 +1,122 @@ +# Apis +(*Apis*) + +### Available Operations + +* [GetAPI](#getapi) +* [ListKeys](#listkeys) + +## GetAPI + +### Example Usage + +```go +package main + +import( + "github.com/unkeyed/unkey-go/models/components" + unkeygo "github.com/unkeyed/unkey-go" + "github.com/unkeyed/unkey-go/models/operations" + "context" + "log" +) + +func main() { + s := unkeygo.New( + unkeygo.WithSecurity(""), + ) + + request := operations.GetAPIRequest{ + APIID: "api_1234", + } + + ctx := context.Background() + res, err := s.Apis.GetAPI(ctx, request) + if err != nil { + log.Fatal(err) + } + if res != nil { + // handle response + } +} +``` + +### Parameters + +| Parameter | Type | Required | Description | +| -------------------------------------------------------------------- | -------------------------------------------------------------------- | -------------------------------------------------------------------- | -------------------------------------------------------------------- | +| `ctx` | [context.Context](https://pkg.go.dev/context#Context) | :heavy_check_mark: | The context to use for the request. | +| `request` | [operations.GetAPIRequest](../../models/operations/getapirequest.md) | :heavy_check_mark: | The request object to use for the request. | + + +### Response + +**[*operations.GetAPIResponseBody](../../models/operations/getapiresponsebody.md), error** +| Error Object | Status Code | Content Type | +| -------------------------------- | -------------------------------- | -------------------------------- | +| sdkerrors.ErrBadRequest | 400 | application/json | +| sdkerrors.ErrUnauthorized | 401 | application/json | +| sdkerrors.ErrForbidden | 403 | application/json | +| sdkerrors.ErrNotFound | 404 | application/json | +| sdkerrors.ErrConflict | 409 | application/json | +| sdkerrors.ErrTooManyRequests | 429 | application/json | +| sdkerrors.ErrInternalServerError | 500 | application/json | +| sdkerrors.SDKError | 4xx-5xx | */* | + +## ListKeys + +### Example Usage + +```go +package main + +import( + "github.com/unkeyed/unkey-go/models/components" + unkeygo "github.com/unkeyed/unkey-go" + "github.com/unkeyed/unkey-go/models/operations" + "context" + "log" +) + +func main() { + s := unkeygo.New( + unkeygo.WithSecurity(""), + ) + + request := operations.ListKeysRequest{ + APIID: "api_1234", + Limit: unkeygo.Int64(100), + } + + ctx := context.Background() + res, err := s.Apis.ListKeys(ctx, request) + if err != nil { + log.Fatal(err) + } + if res != nil { + // handle response + } +} +``` + +### Parameters + +| Parameter | Type | Required | Description | +| ------------------------------------------------------------------------ | ------------------------------------------------------------------------ | ------------------------------------------------------------------------ | ------------------------------------------------------------------------ | +| `ctx` | [context.Context](https://pkg.go.dev/context#Context) | :heavy_check_mark: | The context to use for the request. | +| `request` | [operations.ListKeysRequest](../../models/operations/listkeysrequest.md) | :heavy_check_mark: | The request object to use for the request. | + + +### Response + +**[*operations.ListKeysResponseBody](../../models/operations/listkeysresponsebody.md), error** +| Error Object | Status Code | Content Type | +| -------------------------------- | -------------------------------- | -------------------------------- | +| sdkerrors.ErrBadRequest | 400 | application/json | +| sdkerrors.ErrUnauthorized | 401 | application/json | +| sdkerrors.ErrForbidden | 403 | application/json | +| sdkerrors.ErrNotFound | 404 | application/json | +| sdkerrors.ErrConflict | 409 | application/json | +| sdkerrors.ErrTooManyRequests | 429 | application/json | +| sdkerrors.ErrInternalServerError | 500 | application/json | +| sdkerrors.SDKError | 4xx-5xx | */* | diff --git a/docs/sdks/keys/README.md b/docs/sdks/keys/README.md new file mode 100644 index 0000000..7200b47 --- /dev/null +++ b/docs/sdks/keys/README.md @@ -0,0 +1,462 @@ +# Keys +(*Keys*) + +### Available Operations + +* [GetKey](#getkey) +* [DeleteKey](#deletekey) +* [CreateKey](#createkey) +* [VerifyKey](#verifykey) +* [UpdateKey](#updatekey) +* [UpdateRemaining](#updateremaining) +* [GetVerifications](#getverifications) + +## GetKey + +### Example Usage + +```go +package main + +import( + "github.com/unkeyed/unkey-go/models/components" + unkeygo "github.com/unkeyed/unkey-go" + "github.com/unkeyed/unkey-go/models/operations" + "context" + "log" +) + +func main() { + s := unkeygo.New( + unkeygo.WithSecurity(""), + ) + + request := operations.GetKeyRequest{ + KeyID: "key_1234", + } + + ctx := context.Background() + res, err := s.Keys.GetKey(ctx, request) + if err != nil { + log.Fatal(err) + } + if res != nil { + // handle response + } +} +``` + +### Parameters + +| Parameter | Type | Required | Description | +| -------------------------------------------------------------------- | -------------------------------------------------------------------- | -------------------------------------------------------------------- | -------------------------------------------------------------------- | +| `ctx` | [context.Context](https://pkg.go.dev/context#Context) | :heavy_check_mark: | The context to use for the request. | +| `request` | [operations.GetKeyRequest](../../models/operations/getkeyrequest.md) | :heavy_check_mark: | The request object to use for the request. | + + +### Response + +**[*components.Key](../../models/components/key.md), error** +| Error Object | Status Code | Content Type | +| -------------------------------- | -------------------------------- | -------------------------------- | +| sdkerrors.ErrBadRequest | 400 | application/json | +| sdkerrors.ErrUnauthorized | 401 | application/json | +| sdkerrors.ErrForbidden | 403 | application/json | +| sdkerrors.ErrNotFound | 404 | application/json | +| sdkerrors.ErrConflict | 409 | application/json | +| sdkerrors.ErrTooManyRequests | 429 | application/json | +| sdkerrors.ErrInternalServerError | 500 | application/json | +| sdkerrors.SDKError | 4xx-5xx | */* | + +## DeleteKey + +### Example Usage + +```go +package main + +import( + "github.com/unkeyed/unkey-go/models/components" + unkeygo "github.com/unkeyed/unkey-go" + "github.com/unkeyed/unkey-go/models/operations" + "context" + "log" +) + +func main() { + s := unkeygo.New( + unkeygo.WithSecurity(""), + ) + + request := operations.DeleteKeyRequestBody{ + KeyID: "key_1234", + } + + ctx := context.Background() + res, err := s.Keys.DeleteKey(ctx, request) + if err != nil { + log.Fatal(err) + } + if res != nil { + // handle response + } +} +``` + +### Parameters + +| Parameter | Type | Required | Description | +| ---------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- | +| `ctx` | [context.Context](https://pkg.go.dev/context#Context) | :heavy_check_mark: | The context to use for the request. | +| `request` | [operations.DeleteKeyRequestBody](../../models/operations/deletekeyrequestbody.md) | :heavy_check_mark: | The request object to use for the request. | + + +### Response + +**[*operations.DeleteKeyResponseBody](../../models/operations/deletekeyresponsebody.md), error** +| Error Object | Status Code | Content Type | +| -------------------------------- | -------------------------------- | -------------------------------- | +| sdkerrors.ErrBadRequest | 400 | application/json | +| sdkerrors.ErrUnauthorized | 401 | application/json | +| sdkerrors.ErrForbidden | 403 | application/json | +| sdkerrors.ErrNotFound | 404 | application/json | +| sdkerrors.ErrConflict | 409 | application/json | +| sdkerrors.ErrTooManyRequests | 429 | application/json | +| sdkerrors.ErrInternalServerError | 500 | application/json | +| sdkerrors.SDKError | 4xx-5xx | */* | + +## CreateKey + +### Example Usage + +```go +package main + +import( + "github.com/unkeyed/unkey-go/models/components" + unkeygo "github.com/unkeyed/unkey-go" + "github.com/unkeyed/unkey-go/models/operations" + "context" + "log" +) + +func main() { + s := unkeygo.New( + unkeygo.WithSecurity(""), + ) + + request := operations.CreateKeyRequestBody{ + APIID: "api_123", + Name: unkeygo.String("my key"), + OwnerID: unkeygo.String("team_123"), + Meta: map[string]interface{}{ + "billingTier": "PRO", + "trialEnds": "2023-06-16T17:16:37.161Z", + }, + Roles: []string{ + "admin", + "finance", + }, + Expires: unkeygo.Int64(1623869797161), + Remaining: unkeygo.Int64(1000), + Refill: &operations.Refill{ + Interval: operations.IntervalDaily, + Amount: 100, + }, + Ratelimit: &operations.Ratelimit{ + Type: operations.TypeFast.ToPointer(), + Limit: 10, + RefillRate: 1, + RefillInterval: 60, + }, + Enabled: unkeygo.Bool(false), + } + + ctx := context.Background() + res, err := s.Keys.CreateKey(ctx, request) + if err != nil { + log.Fatal(err) + } + if res != nil { + // handle response + } +} +``` + +### Parameters + +| Parameter | Type | Required | Description | +| ---------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- | +| `ctx` | [context.Context](https://pkg.go.dev/context#Context) | :heavy_check_mark: | The context to use for the request. | +| `request` | [operations.CreateKeyRequestBody](../../models/operations/createkeyrequestbody.md) | :heavy_check_mark: | The request object to use for the request. | + + +### Response + +**[*operations.CreateKeyResponseBody](../../models/operations/createkeyresponsebody.md), error** +| Error Object | Status Code | Content Type | +| -------------------------------- | -------------------------------- | -------------------------------- | +| sdkerrors.ErrBadRequest | 400 | application/json | +| sdkerrors.ErrUnauthorized | 401 | application/json | +| sdkerrors.ErrForbidden | 403 | application/json | +| sdkerrors.ErrNotFound | 404 | application/json | +| sdkerrors.ErrConflict | 409 | application/json | +| sdkerrors.ErrTooManyRequests | 429 | application/json | +| sdkerrors.ErrInternalServerError | 500 | application/json | +| sdkerrors.SDKError | 4xx-5xx | */* | + +## VerifyKey + +### Example Usage + +```go +package main + +import( + "github.com/unkeyed/unkey-go/models/components" + unkeygo "github.com/unkeyed/unkey-go" + "context" + "log" +) + +func main() { + s := unkeygo.New( + unkeygo.WithSecurity(""), + ) + + request := components.V1KeysVerifyKeyRequest{ + APIID: unkeygo.String("api_1234"), + Key: "sk_1234", + Authorization: &components.Authorization{ + Permissions: &components.Permissions{}, + }, + } + + ctx := context.Background() + res, err := s.Keys.VerifyKey(ctx, request) + if err != nil { + log.Fatal(err) + } + if res != nil { + // handle response + } +} +``` + +### Parameters + +| Parameter | Type | Required | Description | +| -------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | +| `ctx` | [context.Context](https://pkg.go.dev/context#Context) | :heavy_check_mark: | The context to use for the request. | +| `request` | [components.V1KeysVerifyKeyRequest](../../models/components/v1keysverifykeyrequest.md) | :heavy_check_mark: | The request object to use for the request. | + + +### Response + +**[*components.V1KeysVerifyKeyResponse](../../models/components/v1keysverifykeyresponse.md), error** +| Error Object | Status Code | Content Type | +| -------------------------------- | -------------------------------- | -------------------------------- | +| sdkerrors.ErrBadRequest | 400 | application/json | +| sdkerrors.ErrUnauthorized | 401 | application/json | +| sdkerrors.ErrForbidden | 403 | application/json | +| sdkerrors.ErrNotFound | 404 | application/json | +| sdkerrors.ErrConflict | 409 | application/json | +| sdkerrors.ErrTooManyRequests | 429 | application/json | +| sdkerrors.ErrInternalServerError | 500 | application/json | +| sdkerrors.SDKError | 4xx-5xx | */* | + +## UpdateKey + +### Example Usage + +```go +package main + +import( + "github.com/unkeyed/unkey-go/models/components" + unkeygo "github.com/unkeyed/unkey-go" + "github.com/unkeyed/unkey-go/models/operations" + "context" + "log" +) + +func main() { + s := unkeygo.New( + unkeygo.WithSecurity(""), + ) + + request := operations.UpdateKeyRequestBody{ + KeyID: "key_123", + Name: unkeygo.String("Customer X"), + OwnerID: unkeygo.String("user_123"), + Meta: map[string]interface{}{ + "roles": "", + "stripeCustomerId": "cus_1234", + }, + Expires: unkeygo.Float64(0), + Ratelimit: &operations.UpdateKeyRatelimit{ + Type: operations.UpdateKeyTypeFast, + Limit: 10, + RefillRate: 1, + RefillInterval: 60, + }, + Remaining: unkeygo.Float64(1000), + Refill: &operations.UpdateKeyRefill{ + Interval: operations.UpdateKeyIntervalDaily, + Amount: 100, + }, + Enabled: unkeygo.Bool(true), + } + + ctx := context.Background() + res, err := s.Keys.UpdateKey(ctx, request) + if err != nil { + log.Fatal(err) + } + if res != nil { + // handle response + } +} +``` + +### Parameters + +| Parameter | Type | Required | Description | +| ---------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- | +| `ctx` | [context.Context](https://pkg.go.dev/context#Context) | :heavy_check_mark: | The context to use for the request. | +| `request` | [operations.UpdateKeyRequestBody](../../models/operations/updatekeyrequestbody.md) | :heavy_check_mark: | The request object to use for the request. | + + +### Response + +**[*operations.UpdateKeyResponseBody](../../models/operations/updatekeyresponsebody.md), error** +| Error Object | Status Code | Content Type | +| -------------------------------- | -------------------------------- | -------------------------------- | +| sdkerrors.ErrBadRequest | 400 | application/json | +| sdkerrors.ErrUnauthorized | 401 | application/json | +| sdkerrors.ErrForbidden | 403 | application/json | +| sdkerrors.ErrNotFound | 404 | application/json | +| sdkerrors.ErrConflict | 409 | application/json | +| sdkerrors.ErrTooManyRequests | 429 | application/json | +| sdkerrors.ErrInternalServerError | 500 | application/json | +| sdkerrors.SDKError | 4xx-5xx | */* | + +## UpdateRemaining + +### Example Usage + +```go +package main + +import( + "github.com/unkeyed/unkey-go/models/components" + unkeygo "github.com/unkeyed/unkey-go" + "github.com/unkeyed/unkey-go/models/operations" + "context" + "log" +) + +func main() { + s := unkeygo.New( + unkeygo.WithSecurity(""), + ) + + request := operations.UpdateRemainingRequestBody{ + KeyID: "key_123", + Op: operations.OpSet, + Value: unkeygo.Int64(1), + } + + ctx := context.Background() + res, err := s.Keys.UpdateRemaining(ctx, request) + if err != nil { + log.Fatal(err) + } + if res != nil { + // handle response + } +} +``` + +### Parameters + +| Parameter | Type | Required | Description | +| ---------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- | +| `ctx` | [context.Context](https://pkg.go.dev/context#Context) | :heavy_check_mark: | The context to use for the request. | +| `request` | [operations.UpdateRemainingRequestBody](../../models/operations/updateremainingrequestbody.md) | :heavy_check_mark: | The request object to use for the request. | + + +### Response + +**[*operations.UpdateRemainingResponseBody](../../models/operations/updateremainingresponsebody.md), error** +| Error Object | Status Code | Content Type | +| -------------------------------- | -------------------------------- | -------------------------------- | +| sdkerrors.ErrBadRequest | 400 | application/json | +| sdkerrors.ErrUnauthorized | 401 | application/json | +| sdkerrors.ErrForbidden | 403 | application/json | +| sdkerrors.ErrNotFound | 404 | application/json | +| sdkerrors.ErrConflict | 409 | application/json | +| sdkerrors.ErrTooManyRequests | 429 | application/json | +| sdkerrors.ErrInternalServerError | 500 | application/json | +| sdkerrors.SDKError | 4xx-5xx | */* | + +## GetVerifications + +### Example Usage + +```go +package main + +import( + "github.com/unkeyed/unkey-go/models/components" + unkeygo "github.com/unkeyed/unkey-go" + "github.com/unkeyed/unkey-go/models/operations" + "context" + "log" +) + +func main() { + s := unkeygo.New( + unkeygo.WithSecurity(""), + ) + + request := operations.GetVerificationsRequest{ + KeyID: unkeygo.String("key_1234"), + OwnerID: unkeygo.String("chronark"), + Start: unkeygo.Int64(1620000000000), + End: unkeygo.Int64(1620000000000), + Granularity: operations.GranularityDay.ToPointer(), + } + + ctx := context.Background() + res, err := s.Keys.GetVerifications(ctx, request) + if err != nil { + log.Fatal(err) + } + if res != nil { + // handle response + } +} +``` + +### Parameters + +| Parameter | Type | Required | Description | +| ---------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- | +| `ctx` | [context.Context](https://pkg.go.dev/context#Context) | :heavy_check_mark: | The context to use for the request. | +| `request` | [operations.GetVerificationsRequest](../../models/operations/getverificationsrequest.md) | :heavy_check_mark: | The request object to use for the request. | + + +### Response + +**[*operations.GetVerificationsResponseBody](../../models/operations/getverificationsresponsebody.md), error** +| Error Object | Status Code | Content Type | +| -------------------------------- | -------------------------------- | -------------------------------- | +| sdkerrors.ErrBadRequest | 400 | application/json | +| sdkerrors.ErrUnauthorized | 401 | application/json | +| sdkerrors.ErrForbidden | 403 | application/json | +| sdkerrors.ErrNotFound | 404 | application/json | +| sdkerrors.ErrConflict | 409 | application/json | +| sdkerrors.ErrTooManyRequests | 429 | application/json | +| sdkerrors.ErrInternalServerError | 500 | application/json | +| sdkerrors.SDKError | 4xx-5xx | */* | diff --git a/docs/sdks/liveness/README.md b/docs/sdks/liveness/README.md new file mode 100644 index 0000000..1af45b5 --- /dev/null +++ b/docs/sdks/liveness/README.md @@ -0,0 +1,59 @@ +# Liveness +(*Liveness*) + +### Available Operations + +* [V1Liveness](#v1liveness) + +## V1Liveness + +### Example Usage + +```go +package main + +import( + "github.com/unkeyed/unkey-go/models/components" + unkeygo "github.com/unkeyed/unkey-go" + "context" + "log" +) + +func main() { + s := unkeygo.New( + unkeygo.WithSecurity(""), + ) + + + + ctx := context.Background() + res, err := s.Liveness.V1Liveness(ctx) + if err != nil { + log.Fatal(err) + } + if res != nil { + // handle response + } +} +``` + +### Parameters + +| Parameter | Type | Required | Description | +| ----------------------------------------------------- | ----------------------------------------------------- | ----------------------------------------------------- | ----------------------------------------------------- | +| `ctx` | [context.Context](https://pkg.go.dev/context#Context) | :heavy_check_mark: | The context to use for the request. | + + +### Response + +**[*operations.V1LivenessResponseBody](../../models/operations/v1livenessresponsebody.md), error** +| Error Object | Status Code | Content Type | +| -------------------------------- | -------------------------------- | -------------------------------- | +| sdkerrors.ErrBadRequest | 400 | application/json | +| sdkerrors.ErrUnauthorized | 401 | application/json | +| sdkerrors.ErrForbidden | 403 | application/json | +| sdkerrors.ErrNotFound | 404 | application/json | +| sdkerrors.ErrConflict | 409 | application/json | +| sdkerrors.ErrTooManyRequests | 429 | application/json | +| sdkerrors.ErrInternalServerError | 500 | application/json | +| sdkerrors.SDKError | 4xx-5xx | */* | diff --git a/docs/sdks/migrations/README.md b/docs/sdks/migrations/README.md new file mode 100644 index 0000000..d80e8d0 --- /dev/null +++ b/docs/sdks/migrations/README.md @@ -0,0 +1,93 @@ +# Migrations +(*Migrations*) + +### Available Operations + +* [V1MigrationsCreateKeys](#v1migrationscreatekeys) + +## V1MigrationsCreateKeys + +### Example Usage + +```go +package main + +import( + "github.com/unkeyed/unkey-go/models/components" + unkeygo "github.com/unkeyed/unkey-go" + "github.com/unkeyed/unkey-go/models/operations" + "context" + "log" +) + +func main() { + s := unkeygo.New( + unkeygo.WithSecurity(""), + ) + + request := []operations.RequestBody{ + operations.RequestBody{ + APIID: "api_123", + Name: unkeygo.String("my key"), + Hash: operations.Hash{ + Value: "", + Variant: operations.VariantSha256Base64, + }, + Start: unkeygo.String("unkey_32kq"), + OwnerID: unkeygo.String("team_123"), + Meta: map[string]interface{}{ + "billingTier": "PRO", + "trialEnds": "2023-06-16T17:16:37.161Z", + }, + Roles: []string{ + "admin", + "finance", + }, + Expires: unkeygo.Int64(1623869797161), + Remaining: unkeygo.Int64(1000), + Refill: &operations.V1MigrationsCreateKeysRefill{ + Interval: operations.V1MigrationsCreateKeysIntervalDaily, + Amount: 100, + }, + Ratelimit: &operations.V1MigrationsCreateKeysRatelimit{ + Type: operations.V1MigrationsCreateKeysTypeFast.ToPointer(), + Limit: 10, + RefillRate: 1, + RefillInterval: 60, + }, + Enabled: unkeygo.Bool(false), + }, + } + + ctx := context.Background() + res, err := s.Migrations.V1MigrationsCreateKeys(ctx, request) + if err != nil { + log.Fatal(err) + } + if res != nil { + // handle response + } +} +``` + +### Parameters + +| Parameter | Type | Required | Description | +| ----------------------------------------------------- | ----------------------------------------------------- | ----------------------------------------------------- | ----------------------------------------------------- | +| `ctx` | [context.Context](https://pkg.go.dev/context#Context) | :heavy_check_mark: | The context to use for the request. | +| `request` | [[]operations.RequestBody](../../.md) | :heavy_check_mark: | The request object to use for the request. | + + +### Response + +**[*operations.V1MigrationsCreateKeysResponseBody](../../models/operations/v1migrationscreatekeysresponsebody.md), error** +| Error Object | Status Code | Content Type | +| -------------------------------- | -------------------------------- | -------------------------------- | +| sdkerrors.ErrBadRequest | 400 | application/json | +| sdkerrors.ErrUnauthorized | 401 | application/json | +| sdkerrors.ErrForbidden | 403 | application/json | +| sdkerrors.ErrNotFound | 404 | application/json | +| sdkerrors.ErrConflict | 409 | application/json | +| sdkerrors.ErrTooManyRequests | 429 | application/json | +| sdkerrors.ErrInternalServerError | 500 | application/json | +| sdkerrors.SDKError | 4xx-5xx | */* | diff --git a/docs/sdks/ratelimits/README.md b/docs/sdks/ratelimits/README.md new file mode 100644 index 0000000..17987db --- /dev/null +++ b/docs/sdks/ratelimits/README.md @@ -0,0 +1,74 @@ +# Ratelimits +(*Ratelimits*) + +### Available Operations + +* [Limit](#limit) + +## Limit + +### Example Usage + +```go +package main + +import( + "github.com/unkeyed/unkey-go/models/components" + unkeygo "github.com/unkeyed/unkey-go" + "github.com/unkeyed/unkey-go/models/operations" + "context" + "log" +) + +func main() { + s := unkeygo.New( + unkeygo.WithSecurity(""), + ) + + request := operations.LimitRequestBody{ + Namespace: unkeygo.String("email.outbound"), + Identifier: "user_123", + Limit: 10, + Duration: 60000, + Cost: unkeygo.Int64(2), + Resources: []operations.Resources{ + operations.Resources{ + Type: "project", + ID: "p_123", + Name: unkeygo.String("dub"), + }, + }, + } + + ctx := context.Background() + res, err := s.Ratelimits.Limit(ctx, request) + if err != nil { + log.Fatal(err) + } + if res != nil { + // handle response + } +} +``` + +### Parameters + +| Parameter | Type | Required | Description | +| -------------------------------------------------------------------------- | -------------------------------------------------------------------------- | -------------------------------------------------------------------------- | -------------------------------------------------------------------------- | +| `ctx` | [context.Context](https://pkg.go.dev/context#Context) | :heavy_check_mark: | The context to use for the request. | +| `request` | [operations.LimitRequestBody](../../models/operations/limitrequestbody.md) | :heavy_check_mark: | The request object to use for the request. | + + +### Response + +**[*operations.LimitResponseBody](../../models/operations/limitresponsebody.md), error** +| Error Object | Status Code | Content Type | +| -------------------------------- | -------------------------------- | -------------------------------- | +| sdkerrors.ErrBadRequest | 400 | application/json | +| sdkerrors.ErrUnauthorized | 401 | application/json | +| sdkerrors.ErrForbidden | 403 | application/json | +| sdkerrors.ErrNotFound | 404 | application/json | +| sdkerrors.ErrConflict | 409 | application/json | +| sdkerrors.ErrTooManyRequests | 429 | application/json | +| sdkerrors.ErrInternalServerError | 500 | application/json | +| sdkerrors.SDKError | 4xx-5xx | */* | diff --git a/docs/sdks/unkey/README.md b/docs/sdks/unkey/README.md new file mode 100644 index 0000000..9676a9e --- /dev/null +++ b/docs/sdks/unkey/README.md @@ -0,0 +1,315 @@ +# Unkey SDK + + +## Overview + +### Available Operations + +* [CreateAPI](#createapi) +* [DeleteAPI](#deleteapi) +* [DeprecatedCreateKey](#deprecatedcreatekey) +* [~~DeprecatedVerifyKey~~](#deprecatedverifykey) - :warning: **Deprecated** +* [DeprecatedListKeys](#deprecatedlistkeys) + +## CreateAPI + +### Example Usage + +```go +package main + +import( + "github.com/unkeyed/unkey-go/models/components" + unkeygo "github.com/unkeyed/unkey-go" + "github.com/unkeyed/unkey-go/models/operations" + "context" + "log" +) + +func main() { + s := unkeygo.New( + unkeygo.WithSecurity(""), + ) + + request := operations.CreateAPIRequestBody{ + Name: "my-api", + } + + ctx := context.Background() + res, err := s.CreateAPI(ctx, request) + if err != nil { + log.Fatal(err) + } + if res != nil { + // handle response + } +} +``` + +### Parameters + +| Parameter | Type | Required | Description | +| ---------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- | +| `ctx` | [context.Context](https://pkg.go.dev/context#Context) | :heavy_check_mark: | The context to use for the request. | +| `request` | [operations.CreateAPIRequestBody](../../models/operations/createapirequestbody.md) | :heavy_check_mark: | The request object to use for the request. | + + +### Response + +**[*operations.CreateAPIResponseBody](../../models/operations/createapiresponsebody.md), error** +| Error Object | Status Code | Content Type | +| -------------------------------- | -------------------------------- | -------------------------------- | +| sdkerrors.ErrBadRequest | 400 | application/json | +| sdkerrors.ErrUnauthorized | 401 | application/json | +| sdkerrors.ErrForbidden | 403 | application/json | +| sdkerrors.ErrNotFound | 404 | application/json | +| sdkerrors.ErrConflict | 409 | application/json | +| sdkerrors.ErrTooManyRequests | 429 | application/json | +| sdkerrors.ErrInternalServerError | 500 | application/json | +| sdkerrors.SDKError | 4xx-5xx | */* | + +## DeleteAPI + +### Example Usage + +```go +package main + +import( + "github.com/unkeyed/unkey-go/models/components" + unkeygo "github.com/unkeyed/unkey-go" + "github.com/unkeyed/unkey-go/models/operations" + "context" + "log" +) + +func main() { + s := unkeygo.New( + unkeygo.WithSecurity(""), + ) + + request := operations.DeleteAPIRequestBody{ + APIID: "api_1234", + } + + ctx := context.Background() + res, err := s.DeleteAPI(ctx, request) + if err != nil { + log.Fatal(err) + } + if res != nil { + // handle response + } +} +``` + +### Parameters + +| Parameter | Type | Required | Description | +| ---------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- | +| `ctx` | [context.Context](https://pkg.go.dev/context#Context) | :heavy_check_mark: | The context to use for the request. | +| `request` | [operations.DeleteAPIRequestBody](../../models/operations/deleteapirequestbody.md) | :heavy_check_mark: | The request object to use for the request. | + + +### Response + +**[*operations.DeleteAPIResponseBody](../../models/operations/deleteapiresponsebody.md), error** +| Error Object | Status Code | Content Type | +| -------------------------------- | -------------------------------- | -------------------------------- | +| sdkerrors.ErrBadRequest | 400 | application/json | +| sdkerrors.ErrUnauthorized | 401 | application/json | +| sdkerrors.ErrForbidden | 403 | application/json | +| sdkerrors.ErrNotFound | 404 | application/json | +| sdkerrors.ErrConflict | 409 | application/json | +| sdkerrors.ErrTooManyRequests | 429 | application/json | +| sdkerrors.ErrInternalServerError | 500 | application/json | +| sdkerrors.SDKError | 4xx-5xx | */* | + +## DeprecatedCreateKey + +### Example Usage + +```go +package main + +import( + "github.com/unkeyed/unkey-go/models/components" + unkeygo "github.com/unkeyed/unkey-go" + "github.com/unkeyed/unkey-go/models/operations" + "context" + "log" +) + +func main() { + s := unkeygo.New( + unkeygo.WithSecurity(""), + ) + + request := operations.DeprecatedCreateKeyRequestBody{ + APIID: "api_123", + Name: unkeygo.String("my key"), + OwnerID: unkeygo.String("team_123"), + Meta: map[string]interface{}{ + "billingTier": "PRO", + "trialEnds": "2023-06-16T17:16:37.161Z", + }, + Expires: unkeygo.Int64(1623869797161), + Remaining: unkeygo.Int64(1000), + Ratelimit: &operations.DeprecatedCreateKeyRatelimit{ + Type: operations.DeprecatedCreateKeyTypeFast.ToPointer(), + Limit: 10, + RefillRate: 1, + RefillInterval: 60, + }, + } + + ctx := context.Background() + res, err := s.DeprecatedCreateKey(ctx, request) + if err != nil { + log.Fatal(err) + } + if res != nil { + // handle response + } +} +``` + +### Parameters + +| Parameter | Type | Required | Description | +| ------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------ | +| `ctx` | [context.Context](https://pkg.go.dev/context#Context) | :heavy_check_mark: | The context to use for the request. | +| `request` | [operations.DeprecatedCreateKeyRequestBody](../../models/operations/deprecatedcreatekeyrequestbody.md) | :heavy_check_mark: | The request object to use for the request. | + + +### Response + +**[*operations.DeprecatedCreateKeyResponseBody](../../models/operations/deprecatedcreatekeyresponsebody.md), error** +| Error Object | Status Code | Content Type | +| -------------------------------- | -------------------------------- | -------------------------------- | +| sdkerrors.ErrBadRequest | 400 | application/json | +| sdkerrors.ErrUnauthorized | 401 | application/json | +| sdkerrors.ErrForbidden | 403 | application/json | +| sdkerrors.ErrNotFound | 404 | application/json | +| sdkerrors.ErrConflict | 409 | application/json | +| sdkerrors.ErrTooManyRequests | 429 | application/json | +| sdkerrors.ErrInternalServerError | 500 | application/json | +| sdkerrors.SDKError | 4xx-5xx | */* | + +## ~~DeprecatedVerifyKey~~ + +> :warning: **DEPRECATED**: This will be removed in a future release, please migrate away from it as soon as possible. + +### Example Usage + +```go +package main + +import( + "github.com/unkeyed/unkey-go/models/components" + unkeygo "github.com/unkeyed/unkey-go" + "github.com/unkeyed/unkey-go/models/operations" + "context" + "log" +) + +func main() { + s := unkeygo.New( + unkeygo.WithSecurity(""), + ) + + request := operations.DeprecatedVerifyKeyRequestBody{ + APIID: unkeygo.String("api_1234"), + Key: "sk_1234", + } + + ctx := context.Background() + res, err := s.DeprecatedVerifyKey(ctx, request) + if err != nil { + log.Fatal(err) + } + if res != nil { + // handle response + } +} +``` + +### Parameters + +| Parameter | Type | Required | Description | +| ------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------ | +| `ctx` | [context.Context](https://pkg.go.dev/context#Context) | :heavy_check_mark: | The context to use for the request. | +| `request` | [operations.DeprecatedVerifyKeyRequestBody](../../models/operations/deprecatedverifykeyrequestbody.md) | :heavy_check_mark: | The request object to use for the request. | + + +### Response + +**[*operations.DeprecatedVerifyKeyResponseBody](../../models/operations/deprecatedverifykeyresponsebody.md), error** +| Error Object | Status Code | Content Type | +| -------------------------------- | -------------------------------- | -------------------------------- | +| sdkerrors.ErrBadRequest | 400 | application/json | +| sdkerrors.ErrUnauthorized | 401 | application/json | +| sdkerrors.ErrForbidden | 403 | application/json | +| sdkerrors.ErrNotFound | 404 | application/json | +| sdkerrors.ErrConflict | 409 | application/json | +| sdkerrors.ErrTooManyRequests | 429 | application/json | +| sdkerrors.ErrInternalServerError | 500 | application/json | +| sdkerrors.SDKError | 4xx-5xx | */* | + +## DeprecatedListKeys + +### Example Usage + +```go +package main + +import( + "github.com/unkeyed/unkey-go/models/components" + unkeygo "github.com/unkeyed/unkey-go" + "github.com/unkeyed/unkey-go/models/operations" + "context" + "log" +) + +func main() { + s := unkeygo.New( + unkeygo.WithSecurity(""), + ) + + request := operations.DeprecatedListKeysRequest{ + APIID: "api_1234", + Limit: unkeygo.Int64(100), + } + + ctx := context.Background() + res, err := s.DeprecatedListKeys(ctx, request) + if err != nil { + log.Fatal(err) + } + if res != nil { + // handle response + } +} +``` + +### Parameters + +| Parameter | Type | Required | Description | +| -------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------- | +| `ctx` | [context.Context](https://pkg.go.dev/context#Context) | :heavy_check_mark: | The context to use for the request. | +| `request` | [operations.DeprecatedListKeysRequest](../../models/operations/deprecatedlistkeysrequest.md) | :heavy_check_mark: | The request object to use for the request. | + + +### Response + +**[*operations.DeprecatedListKeysResponseBody](../../models/operations/deprecatedlistkeysresponsebody.md), error** +| Error Object | Status Code | Content Type | +| -------------------------------- | -------------------------------- | -------------------------------- | +| sdkerrors.ErrBadRequest | 400 | application/json | +| sdkerrors.ErrUnauthorized | 401 | application/json | +| sdkerrors.ErrForbidden | 403 | application/json | +| sdkerrors.ErrNotFound | 404 | application/json | +| sdkerrors.ErrConflict | 409 | application/json | +| sdkerrors.ErrTooManyRequests | 429 | application/json | +| sdkerrors.ErrInternalServerError | 500 | application/json | +| sdkerrors.SDKError | 4xx-5xx | */* | diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..ee5e9bf --- /dev/null +++ b/go.mod @@ -0,0 +1,8 @@ +module github.com/unkeyed/unkey-go + +go 1.20 + +require ( + github.com/cenkalti/backoff/v4 v4.2.0 + github.com/ericlagergren/decimal v0.0.0-20221120152707-495c53812d05 +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..f955779 --- /dev/null +++ b/go.sum @@ -0,0 +1,4 @@ +github.com/cenkalti/backoff/v4 v4.2.0 h1:HN5dHm3WBOgndBH6E8V0q2jIYIR3s9yglV8k/+MN3u4= +github.com/cenkalti/backoff/v4 v4.2.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= +github.com/ericlagergren/decimal v0.0.0-20221120152707-495c53812d05 h1:S92OBrGuLLZsyM5ybUzgc/mPjIYk2AZqufieooe98uw= +github.com/ericlagergren/decimal v0.0.0-20221120152707-495c53812d05/go.mod h1:M9R1FoZ3y//hwwnJtO51ypFGwm8ZfpxPT/ZLtO1mcgQ= diff --git a/internal/hooks/hooks.go b/internal/hooks/hooks.go new file mode 100644 index 0000000..ee97182 --- /dev/null +++ b/internal/hooks/hooks.go @@ -0,0 +1,144 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package hooks + +import ( + "context" + "errors" + "net/http" +) + +type FailEarly struct { + Cause error +} + +var _ error = (*FailEarly)(nil) + +func (f *FailEarly) Error() string { + return f.Cause.Error() +} + +// HTTPClient provides an interface for supplying the SDK with a custom HTTP client +type HTTPClient interface { + Do(req *http.Request) (*http.Response, error) +} + +type HookContext struct { + Context context.Context + OperationID string + OAuth2Scopes []string + SecuritySource func(context.Context) (interface{}, error) +} + +type BeforeRequestContext struct { + HookContext +} + +type AfterSuccessContext struct { + HookContext +} + +type AfterErrorContext struct { + HookContext +} + +// sdkInitHook is called when the SDK is initializing. The hook can modify and return a new baseURL and HTTP client to be used by the SDK. +type sdkInitHook interface { + SDKInit(baseURL string, client HTTPClient) (string, HTTPClient) +} + +// beforeRequestHook is called before the SDK sends a request. The hook can modify the request before it is sent or return an error to stop the request from being sent. +type beforeRequestHook interface { + BeforeRequest(hookCtx BeforeRequestContext, req *http.Request) (*http.Request, error) +} + +// afterSuccessHook is called after the SDK receives a response. The hook can modify the response before it is handled or return an error to stop the response from being handled. +type afterSuccessHook interface { + AfterSuccess(hookCtx AfterSuccessContext, res *http.Response) (*http.Response, error) +} + +// afterErrorHook is called after the SDK encounters an error, or a non-successful response. The hook can modify the response if available otherwise modify the error. +// All afterErrorHook hooks are called and returning an error won't stop the other hooks from being called. But if you want to stop the other hooks from being called, you can return a FailEarly error wrapping your error. +type afterErrorHook interface { + AfterError(hookCtx AfterErrorContext, res *http.Response, err error) (*http.Response, error) +} + +type Hooks struct { + sdkInitHooks []sdkInitHook + beforeRequestHook []beforeRequestHook + afterSuccessHook []afterSuccessHook + afterErrorHook []afterErrorHook +} + +func New() *Hooks { + h := &Hooks{ + sdkInitHooks: []sdkInitHook{}, + beforeRequestHook: []beforeRequestHook{}, + afterSuccessHook: []afterSuccessHook{}, + afterErrorHook: []afterErrorHook{}, + } + + initHooks(h) + + return h +} + +// registerSDKInitHook registers a hook to be used by the SDK for the initialization event. +func (h *Hooks) registerSDKInitHook(hook sdkInitHook) { + h.sdkInitHooks = append(h.sdkInitHooks, hook) +} + +// registerBeforeRequestHook registers a hook to be used by the SDK for the before request event. +func (h *Hooks) registerBeforeRequestHook(hook beforeRequestHook) { + h.beforeRequestHook = append(h.beforeRequestHook, hook) +} + +// registerAfterSuccessHook registers a hook to be used by the SDK for the after success event. +func (h *Hooks) registerAfterSuccessHook(hook afterSuccessHook) { + h.afterSuccessHook = append(h.afterSuccessHook, hook) +} + +// registerAfterErrorHook registers a hook to be used by the SDK for the after error event. +func (h *Hooks) registerAfterErrorHook(hook afterErrorHook) { + h.afterErrorHook = append(h.afterErrorHook, hook) +} + +func (h *Hooks) SDKInit(baseURL string, client HTTPClient) (string, HTTPClient) { + for _, hook := range h.sdkInitHooks { + baseURL, client = hook.SDKInit(baseURL, client) + } + return baseURL, client +} + +func (h *Hooks) BeforeRequest(hookCtx BeforeRequestContext, req *http.Request) (*http.Request, error) { + for _, hook := range h.beforeRequestHook { + var err error + req, err = hook.BeforeRequest(hookCtx, req) + if err != nil { + return req, err + } + } + return req, nil +} + +func (h *Hooks) AfterSuccess(hookCtx AfterSuccessContext, res *http.Response) (*http.Response, error) { + for _, hook := range h.afterSuccessHook { + var err error + res, err = hook.AfterSuccess(hookCtx, res) + if err != nil { + return res, err + } + } + return res, nil +} + +func (h *Hooks) AfterError(hookCtx AfterErrorContext, res *http.Response, err error) (*http.Response, error) { + for _, hook := range h.afterErrorHook { + res, err = hook.AfterError(hookCtx, res, err) + var fe *FailEarly + if errors.As(err, &fe) { + return nil, fe.Cause + } + } + return res, err +} diff --git a/internal/hooks/registration.go b/internal/hooks/registration.go new file mode 100644 index 0000000..690cca9 --- /dev/null +++ b/internal/hooks/registration.go @@ -0,0 +1,13 @@ +package hooks + +/* + * This file is only ever generated once on the first generation and then is free to be modified. + * Any hooks you wish to add should be registered in the InitHooks function. Feel free to define them + * in this file or in separate files in the hooks package. + */ + +func initHooks(h *Hooks) { + // Add hooks by calling h.register{SDKInit/BeforeRequest/AfterSuccess/AfterError}Hook + // with an instance of a hook that implements that specific Hook interface + // Hooks are registered per SDK instance, and are valid for the lifetime of the SDK instance +} diff --git a/internal/utils/contenttype.go b/internal/utils/contenttype.go new file mode 100644 index 0000000..8ed13e2 --- /dev/null +++ b/internal/utils/contenttype.go @@ -0,0 +1,33 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package utils + +import ( + "fmt" + "mime" + "strings" +) + +func MatchContentType(contentType string, pattern string) bool { + if contentType == pattern || pattern == "*" || pattern == "*/*" { + return true + } + + mediaType, _, err := mime.ParseMediaType(contentType) + if err != nil { + return false + } + + if mediaType == pattern { + return true + } + + parts := strings.Split(mediaType, "/") + if len(parts) == 2 { + if fmt.Sprintf("%s/*", parts[0]) == pattern || fmt.Sprintf("*/%s", parts[1]) == pattern { + return true + } + } + + return false +} diff --git a/internal/utils/form.go b/internal/utils/form.go new file mode 100644 index 0000000..da69a53 --- /dev/null +++ b/internal/utils/form.go @@ -0,0 +1,117 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package utils + +import ( + "fmt" + "math/big" + "net/url" + "reflect" + "strings" + "time" + + "github.com/ericlagergren/decimal" + + "github.com/unkeyed/unkey-go/types" +) + +func populateForm(paramName string, explode bool, objType reflect.Type, objValue reflect.Value, delimiter string, getFieldName func(reflect.StructField) string) url.Values { + + formValues := url.Values{} + + if isNil(objType, objValue) { + return formValues + } + + if objType.Kind() == reflect.Pointer { + objType = objType.Elem() + objValue = objValue.Elem() + } + + switch objType.Kind() { + case reflect.Struct: + switch objValue.Interface().(type) { + case time.Time: + formValues.Add(paramName, valToString(objValue.Interface())) + case types.Date: + formValues.Add(paramName, valToString(objValue.Interface())) + case big.Int: + formValues.Add(paramName, valToString(objValue.Interface())) + case decimal.Big: + formValues.Add(paramName, valToString(objValue.Interface())) + default: + var items []string + + for i := 0; i < objType.NumField(); i++ { + fieldType := objType.Field(i) + valType := objValue.Field(i) + + if isNil(fieldType.Type, valType) { + continue + } + + if valType.Kind() == reflect.Pointer { + valType = valType.Elem() + } + + fieldName := getFieldName(fieldType) + if fieldName == "" { + continue + } + + if explode { + formValues.Add(fieldName, valToString(valType.Interface())) + } else { + items = append(items, fmt.Sprintf("%s%s%s", fieldName, delimiter, valToString(valType.Interface()))) + } + } + + if len(items) > 0 { + formValues.Add(paramName, strings.Join(items, delimiter)) + } + } + case reflect.Map: + items := []string{} + + iter := objValue.MapRange() + for iter.Next() { + if explode { + formValues.Add(iter.Key().String(), valToString(iter.Value().Interface())) + } else { + items = append(items, fmt.Sprintf("%s%s%s", iter.Key().String(), delimiter, valToString(iter.Value().Interface()))) + } + } + + if len(items) > 0 { + formValues.Add(paramName, strings.Join(items, delimiter)) + } + case reflect.Slice, reflect.Array: + values := parseDelimitedArray(explode, objValue, delimiter) + for _, v := range values { + formValues.Add(paramName, v) + } + default: + formValues.Add(paramName, valToString(objValue.Interface())) + } + + return formValues +} + +func parseDelimitedArray(explode bool, objValue reflect.Value, delimiter string) []string { + values := []string{} + items := []string{} + + for i := 0; i < objValue.Len(); i++ { + if explode { + values = append(values, valToString(objValue.Index(i).Interface())) + } else { + items = append(items, valToString(objValue.Index(i).Interface())) + } + } + + if len(items) > 0 { + values = append(values, strings.Join(items, delimiter)) + } + + return values +} diff --git a/internal/utils/headers.go b/internal/utils/headers.go new file mode 100644 index 0000000..0249876 --- /dev/null +++ b/internal/utils/headers.go @@ -0,0 +1,125 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package utils + +import ( + "context" + "fmt" + "net/http" + "reflect" + "strings" +) + +func PopulateHeaders(_ context.Context, req *http.Request, headers interface{}, globals interface{}) { + globalsAlreadyPopulated := populateHeaders(headers, globals, req.Header, []string{}) + if globals != nil { + _ = populateHeaders(globals, nil, req.Header, globalsAlreadyPopulated) + } +} + +func populateHeaders(headers interface{}, globals interface{}, reqHeaders http.Header, skipFields []string) []string { + headerParamsStructType := reflect.TypeOf(headers) + headerParamsValType := reflect.ValueOf(headers) + + globalsAlreadyPopulated := []string{} + + for i := 0; i < headerParamsStructType.NumField(); i++ { + fieldType := headerParamsStructType.Field(i) + valType := headerParamsValType.Field(i) + + if contains(skipFields, fieldType.Name) { + continue + } + + if globals != nil { + var globalFound bool + fieldType, valType, globalFound = populateFromGlobals(fieldType, valType, headerParamTagKey, globals) + if globalFound { + globalsAlreadyPopulated = append(globalsAlreadyPopulated, fieldType.Name) + } + } + + tag := parseParamTag(headerParamTagKey, fieldType, "simple", false) + if tag == nil { + continue + } + + value := serializeHeader(fieldType.Type, valType, tag.Explode) + if value != "" { + reqHeaders.Add(tag.ParamName, value) + } + } + + return globalsAlreadyPopulated +} + +func serializeHeader(objType reflect.Type, objValue reflect.Value, explode bool) string { + if isNil(objType, objValue) { + return "" + } + + if objType.Kind() == reflect.Pointer { + objType = objType.Elem() + objValue = objValue.Elem() + } + + switch objType.Kind() { + case reflect.Struct: + items := []string{} + + for i := 0; i < objType.NumField(); i++ { + fieldType := objType.Field(i) + valType := objValue.Field(i) + + if isNil(fieldType.Type, valType) { + continue + } + + if fieldType.Type.Kind() == reflect.Pointer { + valType = valType.Elem() + } + + tag := parseParamTag(headerParamTagKey, fieldType, "simple", false) + if tag == nil { + continue + } + + fieldName := tag.ParamName + + if fieldName == "" { + continue + } + + if explode { + items = append(items, fmt.Sprintf("%s=%s", fieldName, valToString(valType.Interface()))) + } else { + items = append(items, fieldName, valToString(valType.Interface())) + } + } + + return strings.Join(items, ",") + case reflect.Map: + items := []string{} + + iter := objValue.MapRange() + for iter.Next() { + if explode { + items = append(items, fmt.Sprintf("%s=%s", iter.Key().String(), valToString(iter.Value().Interface()))) + } else { + items = append(items, iter.Key().String(), valToString(iter.Value().Interface())) + } + } + + return strings.Join(items, ",") + case reflect.Slice, reflect.Array: + items := []string{} + + for i := 0; i < objValue.Len(); i++ { + items = append(items, valToString(objValue.Index(i).Interface())) + } + + return strings.Join(items, ",") + default: + return valToString(objValue.Interface()) + } +} diff --git a/internal/utils/json.go b/internal/utils/json.go new file mode 100644 index 0000000..9aac25a --- /dev/null +++ b/internal/utils/json.go @@ -0,0 +1,670 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package utils + +import ( + "bytes" + "encoding/json" + "fmt" + "math/big" + "reflect" + "strconv" + "strings" + "time" + "unsafe" + + "github.com/unkeyed/unkey-go/types" + + "github.com/ericlagergren/decimal" +) + +func MarshalJSON(v interface{}, tag reflect.StructTag, topLevel bool) ([]byte, error) { + typ, val := dereferencePointers(reflect.TypeOf(v), reflect.ValueOf(v)) + + switch { + case isModelType(typ): + if topLevel { + return json.Marshal(v) + } + + if isNil(typ, val) { + return []byte("null"), nil + } + + out := map[string]json.RawMessage{} + + for i := 0; i < typ.NumField(); i++ { + field := typ.Field(i) + fieldVal := val.Field(i) + + fieldName := field.Name + + omitEmpty := false + jsonTag := field.Tag.Get("json") + if jsonTag != "" { + for _, tag := range strings.Split(jsonTag, ",") { + if tag == "omitempty" { + omitEmpty = true + } else { + fieldName = tag + } + } + } + + if isNil(field.Type, fieldVal) && field.Tag.Get("const") == "" { + if omitEmpty { + continue + } + } + + if !field.IsExported() && field.Tag.Get("const") == "" { + continue + } + + additionalProperties := field.Tag.Get("additionalProperties") + if fieldName == "-" && additionalProperties == "" { + continue + } + + if additionalProperties == "true" { + if isNil(field.Type, fieldVal) { + continue + } + fieldVal := trueReflectValue(fieldVal) + if fieldVal.Type().Kind() != reflect.Map { + return nil, fmt.Errorf("additionalProperties must be a map") + } + + for _, key := range fieldVal.MapKeys() { + r, err := marshalValue(fieldVal.MapIndex(key).Interface(), field.Tag) + if err != nil { + return nil, err + } + + out[key.String()] = r + } + + continue + } + + var fv interface{} + + if field.IsExported() { + fv = fieldVal.Interface() + } else { + pt := reflect.New(typ).Elem() + pt.Set(val) + + pf := pt.Field(i) + + fv = reflect.NewAt(pf.Type(), unsafe.Pointer(pf.UnsafeAddr())).Elem().Interface() + } + + r, err := marshalValue(fv, field.Tag) + if err != nil { + return nil, err + } + + out[fieldName] = r + } + + return json.Marshal(out) + default: + return marshalValue(v, tag) + } +} + +func UnmarshalJSON(b []byte, v interface{}, tag reflect.StructTag, topLevel bool, disallowUnknownFields bool) error { + if reflect.TypeOf(v).Kind() != reflect.Ptr { + return fmt.Errorf("v must be a pointer") + } + + typ, val := dereferencePointers(reflect.TypeOf(v), reflect.ValueOf(v)) + + switch { + case isModelType(typ): + if topLevel || bytes.Equal(b, []byte("null")) { + d := json.NewDecoder(bytes.NewReader(b)) + if disallowUnknownFields { + d.DisallowUnknownFields() + } + return d.Decode(v) + } + + var unmarhsaled map[string]json.RawMessage + + if err := json.Unmarshal(b, &unmarhsaled); err != nil { + return err + } + + var additionalPropertiesField *reflect.StructField + var additionalPropertiesValue *reflect.Value + + for i := 0; i < typ.NumField(); i++ { + field := typ.Field(i) + fieldVal := val.Field(i) + + fieldName := field.Name + + jsonTag := field.Tag.Get("json") + if jsonTag != "" { + for _, tag := range strings.Split(jsonTag, ",") { + if tag != "omitempty" { + fieldName = tag + } + } + } + + if field.Tag.Get("additionalProperties") == "true" { + additionalPropertiesField = &field + additionalPropertiesValue = &fieldVal + continue + } + + // If we receive a value for a const field ignore it but mark it as unmarshaled + if field.Tag.Get("const") != "" { + if r, ok := unmarhsaled[fieldName]; ok { + val := string(r) + if strings.HasPrefix(val, `"`) && strings.HasSuffix(val, `"`) { + val = val[1 : len(val)-1] + } + if val != field.Tag.Get("const") { + return fmt.Errorf("const field %s does not match expected value %s", fieldName, field.Tag.Get("const")) + } + + delete(unmarhsaled, fieldName) + } + } else if !field.IsExported() { + continue + } + + value, ok := unmarhsaled[fieldName] + if !ok { + defaultTag := field.Tag.Get("default") + if defaultTag != "" { + value = handleDefaultConstValue(defaultTag, fieldVal.Interface(), field.Tag) + ok = true + } + } else { + delete(unmarhsaled, fieldName) + } + + if ok { + if err := unmarshalValue(value, fieldVal, field.Tag, disallowUnknownFields); err != nil { + return err + } + } + } + + keys := make([]string, 0, len(unmarhsaled)) + for k := range unmarhsaled { + keys = append(keys, k) + } + + if len(keys) > 0 { + if disallowUnknownFields && (additionalPropertiesField == nil || additionalPropertiesValue == nil) { + return fmt.Errorf("unknown fields: %v", keys) + } + + if additionalPropertiesField != nil && additionalPropertiesValue != nil { + typeOfMap := additionalPropertiesField.Type + if additionalPropertiesValue.Type().Kind() == reflect.Interface { + typeOfMap = reflect.TypeOf(map[string]interface{}{}) + } else if additionalPropertiesValue.Type().Kind() != reflect.Map { + return fmt.Errorf("additionalProperties must be a map") + } + + mapValue := reflect.MakeMap(typeOfMap) + + for key, value := range unmarhsaled { + val := reflect.New(typeOfMap.Elem()) + + if err := unmarshalValue(value, val, additionalPropertiesField.Tag, disallowUnknownFields); err != nil { + return err + } + + if val.Elem().Type().String() == typeOfMap.Elem().String() { + mapValue.SetMapIndex(reflect.ValueOf(key), val.Elem()) + } else { + mapValue.SetMapIndex(reflect.ValueOf(key), trueReflectValue(val)) + } + + } + if additionalPropertiesValue.Type().Kind() == reflect.Interface { + additionalPropertiesValue.Set(mapValue) + } else { + additionalPropertiesValue.Set(mapValue) + } + } + } + default: + return unmarshalValue(b, reflect.ValueOf(v), tag, disallowUnknownFields) + } + + return nil +} + +func marshalValue(v interface{}, tag reflect.StructTag) (json.RawMessage, error) { + constTag := tag.Get("const") + if constTag != "" { + return handleDefaultConstValue(constTag, v, tag), nil + } + + if isNil(reflect.TypeOf(v), reflect.ValueOf(v)) { + defaultTag := tag.Get("default") + if defaultTag != "" { + return handleDefaultConstValue(defaultTag, v, tag), nil + } + + return []byte("null"), nil + } + + typ, val := dereferencePointers(reflect.TypeOf(v), reflect.ValueOf(v)) + switch typ.Kind() { + case reflect.Int64: + format := tag.Get("integer") + if format == "string" { + b := val.Interface().(int64) + return []byte(fmt.Sprintf(`"%d"`, b)), nil + } + case reflect.Float64: + format := tag.Get("number") + if format == "string" { + b := val.Interface().(float64) + return []byte(fmt.Sprintf(`"%g"`, b)), nil + } + case reflect.Map: + if isNil(typ, val) { + return []byte("null"), nil + } + + out := map[string]json.RawMessage{} + + for _, key := range val.MapKeys() { + itemVal := val.MapIndex(key) + + if isNil(itemVal.Type(), itemVal) { + out[key.String()] = []byte("null") + continue + } + + r, err := marshalValue(itemVal.Interface(), tag) + if err != nil { + return nil, err + } + + out[key.String()] = r + } + + return json.Marshal(out) + case reflect.Slice, reflect.Array: + if isNil(typ, val) { + return []byte("null"), nil + } + + out := []json.RawMessage{} + + for i := 0; i < val.Len(); i++ { + itemVal := val.Index(i) + + if isNil(itemVal.Type(), itemVal) { + out = append(out, []byte("null")) + continue + } + + r, err := marshalValue(itemVal.Interface(), tag) + if err != nil { + return nil, err + } + + out = append(out, r) + } + + return json.Marshal(out) + case reflect.Struct: + switch typ { + case reflect.TypeOf(time.Time{}): + return []byte(fmt.Sprintf(`"%s"`, val.Interface().(time.Time).Format(time.RFC3339Nano))), nil + case reflect.TypeOf(big.Int{}): + format := tag.Get("bigint") + if format == "string" { + b := val.Interface().(big.Int) + return []byte(fmt.Sprintf(`"%s"`, (&b).String())), nil + } + case reflect.TypeOf(decimal.Big{}): + format := tag.Get("decimal") + if format == "number" { + b := val.Interface().(decimal.Big) + f, ok := (&b).Float64() + if ok { + return []byte(b.String()), nil + } + + return []byte(fmt.Sprintf(`%f`, f)), nil + } + } + } + + return json.Marshal(v) +} + +func handleDefaultConstValue(tagValue string, val interface{}, tag reflect.StructTag) json.RawMessage { + if tagValue == "null" { + return []byte("null") + } + + typ := dereferenceTypePointer(reflect.TypeOf(val)) + switch typ { + case reflect.TypeOf(time.Time{}): + return []byte(fmt.Sprintf(`"%s"`, tagValue)) + case reflect.TypeOf(big.Int{}): + bigIntTag := tag.Get("bigint") + if bigIntTag == "string" { + return []byte(fmt.Sprintf(`"%s"`, tagValue)) + } + case reflect.TypeOf(int64(0)): + format := tag.Get("integer") + if format == "string" { + return []byte(fmt.Sprintf(`"%s"`, tagValue)) + } + case reflect.TypeOf(float64(0)): + format := tag.Get("number") + if format == "string" { + return []byte(fmt.Sprintf(`"%s"`, tagValue)) + } + case reflect.TypeOf(decimal.Big{}): + decimalTag := tag.Get("decimal") + if decimalTag != "number" { + return []byte(fmt.Sprintf(`"%s"`, tagValue)) + } + case reflect.TypeOf(types.Date{}): + return []byte(fmt.Sprintf(`"%s"`, tagValue)) + default: + if typ.Kind() == reflect.String { + return []byte(fmt.Sprintf("%q", tagValue)) + } + } + + return []byte(tagValue) +} + +func unmarshalValue(value json.RawMessage, v reflect.Value, tag reflect.StructTag, disallowUnknownFields bool) error { + if bytes.Equal(value, []byte("null")) { + if v.CanAddr() { + return json.Unmarshal(value, v.Addr().Interface()) + } else { + return json.Unmarshal(value, v.Interface()) + } + } + + typ := dereferenceTypePointer(v.Type()) + + switch typ.Kind() { + case reflect.Int64: + var b int64 + + format := tag.Get("integer") + if format == "string" { + var s string + if err := json.Unmarshal(value, &s); err != nil { + return err + } + + var err error + b, err = strconv.ParseInt(s, 10, 64) + if err != nil { + return fmt.Errorf("failed to parse string as int64: %w", err) + } + if v.Kind() == reflect.Ptr { + if v.IsNil() { + v.Set(reflect.New(typ)) + } + v = v.Elem() + } + + v.Set(reflect.ValueOf(b)) + return nil + } + case reflect.Float64: + var b float64 + + format := tag.Get("number") + if format == "string" { + var s string + if err := json.Unmarshal(value, &s); err != nil { + return err + } + + var err error + b, err = strconv.ParseFloat(s, 64) + if err != nil { + return fmt.Errorf("failed to parse string as float64: %w", err) + } + + if v.Kind() == reflect.Ptr { + if v.IsNil() { + v.Set(reflect.New(typ)) + } + v = v.Elem() + } + + v.Set(reflect.ValueOf(b)) + return nil + } + case reflect.Map: + if bytes.Equal(value, []byte("null")) || !isComplexValueType(dereferenceTypePointer(typ.Elem())) { + if v.CanAddr() { + return json.Unmarshal(value, v.Addr().Interface()) + } else { + return json.Unmarshal(value, v.Interface()) + } + } + + var unmarhsaled map[string]json.RawMessage + + if err := json.Unmarshal(value, &unmarhsaled); err != nil { + return err + } + + m := reflect.MakeMap(typ) + + for k, value := range unmarhsaled { + itemVal := reflect.New(typ.Elem()) + + if err := unmarshalValue(value, itemVal, tag, disallowUnknownFields); err != nil { + return err + } + + m.SetMapIndex(reflect.ValueOf(k), itemVal.Elem()) + } + + v.Set(m) + return nil + case reflect.Slice, reflect.Array: + if bytes.Equal(value, []byte("null")) || !isComplexValueType(dereferenceTypePointer(typ.Elem())) { + if v.CanAddr() { + return json.Unmarshal(value, v.Addr().Interface()) + } else { + return json.Unmarshal(value, v.Interface()) + } + } + + var unmarhsaled []json.RawMessage + + if err := json.Unmarshal(value, &unmarhsaled); err != nil { + return err + } + + arrVal := v + + for _, value := range unmarhsaled { + itemVal := reflect.New(typ.Elem()) + + if err := unmarshalValue(value, itemVal, tag, disallowUnknownFields); err != nil { + return err + } + + arrVal = reflect.Append(arrVal, itemVal.Elem()) + } + + v.Set(arrVal) + return nil + case reflect.Struct: + switch typ { + case reflect.TypeOf(time.Time{}): + var s string + if err := json.Unmarshal(value, &s); err != nil { + return err + } + + t, err := time.Parse(time.RFC3339Nano, s) + if err != nil { + return fmt.Errorf("failed to parse string as time.Time: %w", err) + } + + if v.Kind() == reflect.Ptr { + if v.IsNil() { + v.Set(reflect.New(typ)) + } + v = v.Elem() + } + + v.Set(reflect.ValueOf(t)) + return nil + case reflect.TypeOf(big.Int{}): + var b *big.Int + + format := tag.Get("bigint") + if format == "string" { + var s string + if err := json.Unmarshal(value, &s); err != nil { + return err + } + + var ok bool + b, ok = new(big.Int).SetString(s, 10) + if !ok { + return fmt.Errorf("failed to parse string as big.Int") + } + } else { + if err := json.Unmarshal(value, &b); err != nil { + return err + } + } + + if v.Kind() == reflect.Ptr && v.Elem().Kind() == reflect.Ptr { + v = v.Elem() + } + + v.Set(reflect.ValueOf(b)) + return nil + case reflect.TypeOf(decimal.Big{}): + var d *decimal.Big + format := tag.Get("decimal") + if format == "number" { + var ok bool + d, ok = new(decimal.Big).SetString(string(value)) + if !ok { + return fmt.Errorf("failed to parse number as decimal.Big") + } + } else { + if err := json.Unmarshal(value, &d); err != nil { + return err + } + } + + if v.Kind() == reflect.Ptr && v.Elem().Kind() == reflect.Ptr { + v = v.Elem() + } + + v.Set(reflect.ValueOf(d)) + return nil + case reflect.TypeOf(types.Date{}): + var s string + + if err := json.Unmarshal(value, &s); err != nil { + return err + } + + d, err := types.DateFromString(s) + if err != nil { + return fmt.Errorf("failed to parse string as types.Date: %w", err) + } + + if v.Kind() == reflect.Ptr { + if v.IsNil() { + v.Set(reflect.New(typ)) + } + v = v.Elem() + } + + v.Set(reflect.ValueOf(d)) + return nil + } + } + + var val interface{} + + if v.CanAddr() { + val = v.Addr().Interface() + } else { + val = v.Interface() + } + + d := json.NewDecoder(bytes.NewReader(value)) + if disallowUnknownFields { + d.DisallowUnknownFields() + } + return d.Decode(val) +} + +func dereferencePointers(typ reflect.Type, val reflect.Value) (reflect.Type, reflect.Value) { + if typ.Kind() == reflect.Ptr { + typ = typ.Elem() + val = val.Elem() + } else { + return typ, val + } + + return dereferencePointers(typ, val) +} + +func dereferenceTypePointer(typ reflect.Type) reflect.Type { + if typ.Kind() == reflect.Ptr { + typ = typ.Elem() + } else { + return typ + } + + return dereferenceTypePointer(typ) +} + +func isComplexValueType(typ reflect.Type) bool { + switch typ.Kind() { + case reflect.Struct: + switch typ { + case reflect.TypeOf(time.Time{}): + fallthrough + case reflect.TypeOf(big.Int{}): + fallthrough + case reflect.TypeOf(decimal.Big{}): + fallthrough + case reflect.TypeOf(types.Date{}): + return true + } + } + + return false +} + +func isModelType(typ reflect.Type) bool { + if isComplexValueType(typ) { + return false + } + + if typ.Kind() == reflect.Struct { + return true + } + + return false +} diff --git a/internal/utils/pathparams.go b/internal/utils/pathparams.go new file mode 100644 index 0000000..78f6f11 --- /dev/null +++ b/internal/utils/pathparams.go @@ -0,0 +1,173 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package utils + +import ( + "context" + "fmt" + "math/big" + "net/url" + "reflect" + "strings" + "time" + + "github.com/ericlagergren/decimal" + + "github.com/unkeyed/unkey-go/types" +) + +func GenerateURL(_ context.Context, serverURL, path string, pathParams interface{}, globals interface{}) (string, error) { + uri := strings.TrimSuffix(serverURL, "/") + path + + parsedParameters := map[string]string{} + + globalsAlreadyPopulated, err := populateParsedParameters(pathParams, globals, parsedParameters, []string{}) + if err != nil { + return "", err + } + + if globals != nil { + _, err = populateParsedParameters(globals, nil, parsedParameters, globalsAlreadyPopulated) + if err != nil { + return "", err + } + } + + // TODO should we handle the case where there are no matching path params? + return ReplaceParameters(uri, parsedParameters), nil +} + +func populateParsedParameters(pathParams interface{}, globals interface{}, parsedParameters map[string]string, skipFields []string) ([]string, error) { + pathParamsStructType := reflect.TypeOf(pathParams) + pathParamsValType := reflect.ValueOf(pathParams) + + globalsAlreadyPopulated := []string{} + + for i := 0; i < pathParamsStructType.NumField(); i++ { + fieldType := pathParamsStructType.Field(i) + valType := pathParamsValType.Field(i) + + if contains(skipFields, fieldType.Name) { + continue + } + + requestTag := getRequestTag(fieldType) + if requestTag != nil { + continue + } + + ppTag := parseParamTag(pathParamTagKey, fieldType, "simple", false) + if ppTag == nil { + continue + } + + if globals != nil { + var globalFound bool + fieldType, valType, globalFound = populateFromGlobals(fieldType, valType, pathParamTagKey, globals) + if globalFound { + globalsAlreadyPopulated = append(globalsAlreadyPopulated, fieldType.Name) + } + } + + if ppTag.Serialization != "" { + vals, err := populateSerializedParams(ppTag, fieldType.Type, valType) + if err != nil { + return nil, err + } + for k, v := range vals { + parsedParameters[k] = url.PathEscape(v) + } + } else { + // TODO: support other styles + switch ppTag.Style { + case "simple": + simpleParams := getSimplePathParams(ppTag.ParamName, fieldType.Type, valType, ppTag.Explode) + for k, v := range simpleParams { + parsedParameters[k] = v + } + } + } + } + + return globalsAlreadyPopulated, nil +} + +func getSimplePathParams(parentName string, objType reflect.Type, objValue reflect.Value, explode bool) map[string]string { + pathParams := make(map[string]string) + + if isNil(objType, objValue) { + return nil + } + + if objType.Kind() == reflect.Ptr { + objType = objType.Elem() + objValue = objValue.Elem() + } + + switch objType.Kind() { + case reflect.Array, reflect.Slice: + if objValue.Len() == 0 { + return nil + } + var ppVals []string + for i := 0; i < objValue.Len(); i++ { + ppVals = append(ppVals, valToString(objValue.Index(i).Interface())) + } + pathParams[parentName] = strings.Join(ppVals, ",") + case reflect.Map: + if objValue.Len() == 0 { + return nil + } + var ppVals []string + objMap := objValue.MapRange() + for objMap.Next() { + if explode { + ppVals = append(ppVals, fmt.Sprintf("%s=%s", objMap.Key().String(), valToString(objMap.Value().Interface()))) + } else { + ppVals = append(ppVals, fmt.Sprintf("%s,%s", objMap.Key().String(), valToString(objMap.Value().Interface()))) + } + } + pathParams[parentName] = strings.Join(ppVals, ",") + case reflect.Struct: + switch objValue.Interface().(type) { + case time.Time: + pathParams[parentName] = valToString(objValue.Interface()) + case types.Date: + pathParams[parentName] = valToString(objValue.Interface()) + case big.Int: + pathParams[parentName] = valToString(objValue.Interface()) + case decimal.Big: + pathParams[parentName] = valToString(objValue.Interface()) + default: + var ppVals []string + for i := 0; i < objType.NumField(); i++ { + fieldType := objType.Field(i) + valType := objValue.Field(i) + + ppTag := parseParamTag(pathParamTagKey, fieldType, "simple", explode) + if ppTag == nil { + continue + } + + if isNil(fieldType.Type, valType) { + continue + } + + if fieldType.Type.Kind() == reflect.Pointer { + valType = valType.Elem() + } + + if explode { + ppVals = append(ppVals, fmt.Sprintf("%s=%s", ppTag.ParamName, valToString(valType.Interface()))) + } else { + ppVals = append(ppVals, fmt.Sprintf("%s,%s", ppTag.ParamName, valToString(valType.Interface()))) + } + } + pathParams[parentName] = strings.Join(ppVals, ",") + } + default: + pathParams[parentName] = valToString(objValue.Interface()) + } + + return pathParams +} diff --git a/internal/utils/queryparams.go b/internal/utils/queryparams.go new file mode 100644 index 0000000..8d1bf47 --- /dev/null +++ b/internal/utils/queryparams.go @@ -0,0 +1,206 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package utils + +import ( + "context" + "encoding/json" + "fmt" + "net/http" + "net/url" + "reflect" +) + +func PopulateQueryParams(_ context.Context, req *http.Request, queryParams interface{}, globals interface{}) error { + values := url.Values{} + + globalsAlreadyPopulated, err := populateQueryParams(queryParams, globals, values, []string{}) + if err != nil { + return err + } + + if globals != nil { + _, err = populateQueryParams(globals, nil, values, globalsAlreadyPopulated) + if err != nil { + return err + } + } + + req.URL.RawQuery = values.Encode() + + return nil +} + +func populateQueryParams(queryParams interface{}, globals interface{}, values url.Values, skipFields []string) ([]string, error) { + queryParamsStructType := reflect.TypeOf(queryParams) + queryParamsValType := reflect.ValueOf(queryParams) + + globalsAlreadyPopulated := []string{} + + for i := 0; i < queryParamsStructType.NumField(); i++ { + fieldType := queryParamsStructType.Field(i) + valType := queryParamsValType.Field(i) + + if contains(skipFields, fieldType.Name) { + continue + } + + requestTag := getRequestTag(fieldType) + if requestTag != nil { + continue + } + + qpTag := parseQueryParamTag(fieldType) + if qpTag == nil { + continue + } + + if globals != nil { + var globalFound bool + fieldType, valType, globalFound = populateFromGlobals(fieldType, valType, queryParamTagKey, globals) + if globalFound { + globalsAlreadyPopulated = append(globalsAlreadyPopulated, fieldType.Name) + } + } + + if qpTag.Serialization != "" { + vals, err := populateSerializedParams(qpTag, fieldType.Type, valType) + if err != nil { + return nil, err + } + for k, v := range vals { + values.Add(k, v) + } + } else { + switch qpTag.Style { + case "deepObject": + vals := populateDeepObjectParams(qpTag, fieldType.Type, valType) + for k, v := range vals { + for _, vv := range v { + values.Add(k, vv) + } + } + case "form": + vals := populateFormParams(qpTag, fieldType.Type, valType, ",") + for k, v := range vals { + for _, vv := range v { + values.Add(k, vv) + } + } + case "pipeDelimited": + vals := populateFormParams(qpTag, fieldType.Type, valType, "|") + for k, v := range vals { + for _, vv := range v { + values.Add(k, vv) + } + } + default: + return nil, fmt.Errorf("unsupported style: %s", qpTag.Style) + } + } + } + + return globalsAlreadyPopulated, nil +} + +func populateSerializedParams(tag *paramTag, objType reflect.Type, objValue reflect.Value) (map[string]string, error) { + if isNil(objType, objValue) { + return nil, nil + } + + if objType.Kind() == reflect.Pointer { + objValue = objValue.Elem() + } + + values := map[string]string{} + + switch tag.Serialization { + case "json": + data, err := json.Marshal(objValue.Interface()) + if err != nil { + return nil, fmt.Errorf("error marshaling json: %v", err) + } + values[tag.ParamName] = string(data) + } + + return values, nil +} + +func populateDeepObjectParams(tag *paramTag, objType reflect.Type, objValue reflect.Value) url.Values { + values := url.Values{} + + if isNil(objType, objValue) { + return values + } + + if objType.Kind() == reflect.Pointer { + objType = objType.Elem() + objValue = objValue.Elem() + } + + switch objType.Kind() { + case reflect.Struct: + for i := 0; i < objType.NumField(); i++ { + fieldType := objType.Field(i) + valType := objValue.Field(i) + + if isNil(fieldType.Type, valType) { + continue + } + + if fieldType.Type.Kind() == reflect.Pointer { + valType = valType.Elem() + } + + qpTag := parseQueryParamTag(fieldType) + if qpTag == nil { + continue + } + + switch valType.Kind() { + case reflect.Array, reflect.Slice: + for i := 0; i < valType.Len(); i++ { + values.Add(fmt.Sprintf("%s[%s]", tag.ParamName, qpTag.ParamName), valToString(valType.Index(i).Interface())) + } + default: + values.Add(fmt.Sprintf("%s[%s]", tag.ParamName, qpTag.ParamName), valToString(valType.Interface())) + } + } + case reflect.Map: + iter := objValue.MapRange() + for iter.Next() { + switch iter.Value().Kind() { + case reflect.Array, reflect.Slice: + for i := 0; i < iter.Value().Len(); i++ { + values.Add(fmt.Sprintf("%s[%s]", tag.ParamName, iter.Key().String()), valToString(iter.Value().Index(i).Interface())) + } + default: + values.Add(fmt.Sprintf("%s[%s]", tag.ParamName, iter.Key().String()), valToString(iter.Value().Interface())) + } + } + } + + return values +} + +func populateFormParams(tag *paramTag, objType reflect.Type, objValue reflect.Value, delimiter string) url.Values { + return populateForm(tag.ParamName, tag.Explode, objType, objValue, delimiter, func(fieldType reflect.StructField) string { + qpTag := parseQueryParamTag(fieldType) + if qpTag == nil { + return "" + } + + return qpTag.ParamName + }) +} + +type paramTag struct { + Style string + Explode bool + ParamName string + Serialization string +} + +func parseQueryParamTag(field reflect.StructField) *paramTag { + return parseParamTag(queryParamTagKey, field, "form", true) +} diff --git a/internal/utils/requestbody.go b/internal/utils/requestbody.go new file mode 100644 index 0000000..cfb2ba6 --- /dev/null +++ b/internal/utils/requestbody.go @@ -0,0 +1,409 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package utils + +import ( + "bytes" + "context" + "fmt" + "io" + "mime/multipart" + "net/url" + "reflect" + "regexp" +) + +const ( + requestTagKey = "request" + multipartFormTagKey = "multipartForm" + formTagKey = "form" +) + +var ( + jsonEncodingRegex = regexp.MustCompile(`(application|text)\/.*?\+*json.*`) + multipartEncodingRegex = regexp.MustCompile(`multipart\/.*`) + urlEncodedEncodingRegex = regexp.MustCompile(`application\/x-www-form-urlencoded.*`) +) + +func SerializeRequestBody(_ context.Context, request interface{}, nullable, optional bool, requestFieldName, serializationMethod, tag string) (io.Reader, string, error) { + bodyReader, contentType, err := serializeRequestBody(request, nullable, optional, requestFieldName, serializationMethod, tag) + if err != nil { + return nil, "", fmt.Errorf("error serializing request body: %w", err) + } + + if bodyReader == nil && !optional { + return nil, "", fmt.Errorf("request body is required") + } + + return bodyReader, contentType, nil +} + +func serializeRequestBody(request interface{}, nullable, optional bool, requestFieldName, serializationMethod, tag string) (io.Reader, string, error) { + requestStructType := reflect.TypeOf(request) + requestValType := reflect.ValueOf(request) + + if isNil(requestStructType, requestValType) { + if !nullable && optional { + return nil, "", nil + } + + return serializeContentType(requestFieldName, SerializationMethodToContentType[serializationMethod], requestValType, tag) + } + + if requestStructType.Kind() == reflect.Pointer { + requestStructType = requestStructType.Elem() + requestValType = requestValType.Elem() + } + + if requestStructType.Kind() != reflect.Struct { + return serializeContentType(requestFieldName, SerializationMethodToContentType[serializationMethod], requestValType, tag) + } + + requestField, ok := requestStructType.FieldByName(requestFieldName) + + if ok { + tag := getRequestTag(requestField) + if tag != nil { + // request object (non-flattened) + requestVal := requestValType.FieldByName(requestFieldName) + if isNil(requestField.Type, requestVal) { + if !nullable && optional { + return nil, "", nil + } + + return serializeContentType(requestFieldName, tag.MediaType, requestVal, string(requestField.Tag)) + } + + return serializeContentType(requestFieldName, tag.MediaType, requestVal, string(requestField.Tag)) + } + } + + // flattened request object + return serializeContentType(requestFieldName, SerializationMethodToContentType[serializationMethod], reflect.ValueOf(request), tag) +} + +func serializeContentType(fieldName string, mediaType string, val reflect.Value, tag string) (*bytes.Buffer, string, error) { + buf := &bytes.Buffer{} + + if isNil(val.Type(), val) { + // TODO: what does a null mean for other content types? Just returning an empty buffer for now + if jsonEncodingRegex.MatchString(mediaType) { + if _, err := buf.Write([]byte("null")); err != nil { + return nil, "", err + } + } + + return buf, mediaType, nil + } + + switch { + case jsonEncodingRegex.MatchString(mediaType): + data, err := MarshalJSON(val.Interface(), reflect.StructTag(tag), true) + if err != nil { + return nil, "", err + } + + if _, err := buf.Write(data); err != nil { + return nil, "", err + } + case multipartEncodingRegex.MatchString(mediaType): + var err error + mediaType, err = encodeMultipartFormData(buf, val.Interface()) + if err != nil { + return nil, "", err + } + case urlEncodedEncodingRegex.MatchString(mediaType): + if err := encodeFormData(fieldName, buf, val.Interface()); err != nil { + return nil, "", err + } + default: + val = reflect.Indirect(val) + + switch { + case val.Type().Kind() == reflect.String: + if _, err := buf.WriteString(valToString(val.Interface())); err != nil { + return nil, "", err + } + case val.Type() == reflect.TypeOf([]byte(nil)): + if _, err := buf.Write(val.Bytes()); err != nil { + return nil, "", err + } + default: + return nil, "", fmt.Errorf("invalid request body type %s for mediaType %s", val.Type(), mediaType) + } + } + + return buf, mediaType, nil +} + +func encodeMultipartFormData(w io.Writer, data interface{}) (string, error) { + requestStructType := reflect.TypeOf(data) + requestValType := reflect.ValueOf(data) + + if requestStructType.Kind() == reflect.Pointer { + requestStructType = requestStructType.Elem() + requestValType = requestValType.Elem() + } + + writer := multipart.NewWriter(w) + + for i := 0; i < requestStructType.NumField(); i++ { + field := requestStructType.Field(i) + fieldType := field.Type + valType := requestValType.Field(i) + + if isNil(fieldType, valType) { + continue + } + + if fieldType.Kind() == reflect.Pointer { + fieldType = fieldType.Elem() + valType = valType.Elem() + } + + tag := parseMultipartFormTag(field) + if tag.File { + if err := encodeMultipartFormDataFile(writer, fieldType, valType); err != nil { + writer.Close() + return "", err + } + } else if tag.JSON { + jw, err := writer.CreateFormField(tag.Name) + if err != nil { + writer.Close() + return "", err + } + d, err := MarshalJSON(valType.Interface(), field.Tag, true) + if err != nil { + writer.Close() + return "", err + } + if _, err := jw.Write(d); err != nil { + writer.Close() + return "", err + } + } else { + switch fieldType.Kind() { + case reflect.Slice, reflect.Array: + values := parseDelimitedArray(true, valType, ",") + for _, v := range values { + if err := writer.WriteField(tag.Name+"[]", v); err != nil { + writer.Close() + return "", err + } + } + default: + if err := writer.WriteField(tag.Name, valToString(valType.Interface())); err != nil { + writer.Close() + return "", err + } + } + } + } + + if err := writer.Close(); err != nil { + return "", err + } + + return writer.FormDataContentType(), nil +} + +func encodeMultipartFormDataFile(w *multipart.Writer, fieldType reflect.Type, valType reflect.Value) error { + if fieldType.Kind() != reflect.Struct { + return fmt.Errorf("invalid type %s for multipart/form-data file", valType.Type()) + } + + var fieldName string + var fileName string + var content []byte + + for i := 0; i < fieldType.NumField(); i++ { + field := fieldType.Field(i) + val := valType.Field(i) + + tag := parseMultipartFormTag(field) + if !tag.Content && tag.Name == "" { + continue + } + + if tag.Content { + content = val.Bytes() + } else { + fieldName = tag.Name + fileName = val.String() + } + } + + if fieldName == "" || fileName == "" || content == nil { + return fmt.Errorf("invalid multipart/form-data file") + } + + fw, err := w.CreateFormFile(fieldName, fileName) + if err != nil { + return err + } + if _, err := fw.Write(content); err != nil { + return err + } + + return nil +} + +func encodeFormData(fieldName string, w io.Writer, data interface{}) error { + requestType := reflect.TypeOf(data) + requestValType := reflect.ValueOf(data) + + if requestType.Kind() == reflect.Pointer { + requestType = requestType.Elem() + requestValType = requestValType.Elem() + } + + dataValues := url.Values{} + + switch requestType.Kind() { + case reflect.Struct: + for i := 0; i < requestType.NumField(); i++ { + field := requestType.Field(i) + fieldType := field.Type + valType := requestValType.Field(i) + + if isNil(fieldType, valType) { + continue + } + + if fieldType.Kind() == reflect.Pointer { + fieldType = fieldType.Elem() + valType = valType.Elem() + } + + tag := parseFormTag(field) + if tag.JSON { + data, err := MarshalJSON(valType.Interface(), field.Tag, true) + if err != nil { + return err + } + dataValues.Set(tag.Name, string(data)) + } else { + switch tag.Style { + // TODO: support other styles + case "form": + values := populateForm(tag.Name, tag.Explode, fieldType, valType, ",", func(sf reflect.StructField) string { + tag := parseFormTag(field) + if tag == nil { + return "" + } + + return tag.Name + }) + for k, v := range values { + for _, vv := range v { + dataValues.Add(k, vv) + } + } + } + } + } + case reflect.Map: + for _, k := range requestValType.MapKeys() { + v := requestValType.MapIndex(k) + dataValues.Set(fmt.Sprintf("%v", k.Interface()), valToString(v.Interface())) + } + case reflect.Slice, reflect.Array: + for i := 0; i < requestValType.Len(); i++ { + v := requestValType.Index(i) + dataValues.Set(fieldName, valToString(v.Interface())) + } + } + + if _, err := w.Write([]byte(dataValues.Encode())); err != nil { + return err + } + + return nil +} + +type requestTag struct { + MediaType string +} + +func getRequestTag(field reflect.StructField) *requestTag { + // example `request:"mediaType=multipart/form-data"` + values := parseStructTag(requestTagKey, field) + if values == nil { + return nil + } + + tag := &requestTag{ + MediaType: "application/octet-stream", + } + + for k, v := range values { + switch k { + case "mediaType": + tag.MediaType = v + } + } + + return tag +} + +type multipartFormTag struct { + File bool + Content bool + JSON bool + Name string +} + +func parseMultipartFormTag(field reflect.StructField) *multipartFormTag { + // example `multipartForm:"name=file"` + values := parseStructTag(multipartFormTagKey, field) + + tag := &multipartFormTag{} + + for k, v := range values { + switch k { + case "file": + tag.File = v == "true" + case "content": + tag.Content = v == "true" + case "name": + tag.Name = v + case "json": + tag.JSON = v == "true" + } + } + + return tag +} + +type formTag struct { + Name string + JSON bool + Style string + Explode bool +} + +func parseFormTag(field reflect.StructField) *formTag { + // example `form:"name=propName,style=spaceDelimited,explode"` + values := parseStructTag(formTagKey, field) + + tag := &formTag{ + Style: "form", + Explode: true, + } + + for k, v := range values { + switch k { + case "name": + tag.Name = v + case "json": + tag.JSON = v == "true" + case "style": + tag.Style = v + case "explode": + tag.Explode = v == "true" + } + } + + return tag +} diff --git a/internal/utils/retries.go b/internal/utils/retries.go new file mode 100644 index 0000000..ff39d0d --- /dev/null +++ b/internal/utils/retries.go @@ -0,0 +1,117 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package utils + +import ( + "context" + "errors" + "fmt" + "net/http" + "net/url" + "strconv" + "strings" + "time" + + "github.com/cenkalti/backoff/v4" +) + +var errRequestFailed = errors.New("request failed") + +type BackoffStrategy struct { + InitialInterval int + MaxInterval int + Exponent float64 + MaxElapsedTime int +} + +type RetryConfig struct { + Strategy string + Backoff *BackoffStrategy + RetryConnectionErrors bool +} + +type Retries struct { + Config *RetryConfig + StatusCodes []string +} + +func Retry(ctx context.Context, r Retries, action func() (*http.Response, error)) (*http.Response, error) { + switch r.Config.Strategy { + case "backoff": + if r.Config.Backoff == nil { + return action() + } + + config := backoff.NewExponentialBackOff() + config.InitialInterval = time.Duration(r.Config.Backoff.InitialInterval) * time.Millisecond + config.MaxInterval = time.Duration(r.Config.Backoff.MaxInterval) * time.Millisecond + config.Multiplier = r.Config.Backoff.Exponent + config.MaxElapsedTime = time.Duration(r.Config.Backoff.MaxElapsedTime) * time.Millisecond + config.Reset() + + var resp *http.Response + + err := backoff.Retry(func() error { + if resp != nil { + resp.Body.Close() + } + + select { + case <-ctx.Done(): + return backoff.Permanent(ctx.Err()) + default: + } + + res, err := action() + if err != nil { + urlError := new(url.Error) + if errors.As(err, &urlError) { + if (urlError.Temporary() || urlError.Timeout()) && r.Config.RetryConnectionErrors { + return err + } + } + + return backoff.Permanent(err) + } + resp = res + if res == nil { + return fmt.Errorf("no response") + } + + for _, code := range r.StatusCodes { + if strings.Contains(strings.ToUpper(code), "X") { + codeRange, err := strconv.Atoi(code[:1]) + if err != nil { + continue + } + + s := res.StatusCode / 100 + + if s >= codeRange && s < codeRange+1 { + return errRequestFailed + } + } else { + parsedCode, err := strconv.Atoi(code) + if err != nil { + continue + } + + if res.StatusCode == parsedCode { + return errRequestFailed + } + } + } + + resp = res + + return nil + }, config) + if err != nil && !errors.Is(err, errRequestFailed) { + return nil, err + } + + return resp, nil + default: + return action() + } +} diff --git a/internal/utils/security.go b/internal/utils/security.go new file mode 100644 index 0000000..8023225 --- /dev/null +++ b/internal/utils/security.go @@ -0,0 +1,270 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package utils + +import ( + "context" + "encoding/base64" + "fmt" + "net/http" + "reflect" + "strings" +) + +const ( + securityTagKey = "security" +) + +type securityTag struct { + Option bool + Scheme bool + Name string + Type string + SubType string +} + +func PopulateSecurity(ctx context.Context, req *http.Request, securitySource func(context.Context) (interface{}, error)) error { + if securitySource == nil { + return nil + } + + security, err := securitySource(ctx) + if err != nil { + return err + } + + headers := make(map[string]string) + queryParams := make(map[string]string) + + securityValType := trueReflectValue(reflect.ValueOf(security)) + securityStructType := securityValType.Type() + + if isNil(securityStructType, securityValType) { + return nil + } + + if securityStructType.Kind() == reflect.Ptr { + securityStructType = securityStructType.Elem() + securityValType = securityValType.Elem() + } + + for i := 0; i < securityStructType.NumField(); i++ { + fieldType := securityStructType.Field(i) + valType := securityValType.Field(i) + + kind := valType.Kind() + + if isNil(fieldType.Type, valType) { + continue + } + + if fieldType.Type.Kind() == reflect.Pointer { + kind = valType.Elem().Kind() + } + + secTag := parseSecurityTag(fieldType) + if secTag != nil { + if secTag.Option { + handleSecurityOption(headers, queryParams, valType.Interface()) + } else if secTag.Scheme { + // Special case for basic auth which could be a flattened struct + if secTag.SubType == "basic" && kind != reflect.Struct { + parseSecurityScheme(headers, queryParams, secTag, security) + } else { + parseSecurityScheme(headers, queryParams, secTag, valType.Interface()) + } + } + } + } + + for key, value := range headers { + req.Header.Add(key, value) + } + + query := req.URL.Query() + for key, value := range queryParams { + query.Add(key, value) + } + req.URL.RawQuery = query.Encode() + + return nil +} + +func handleSecurityOption(headers, queryParams map[string]string, option interface{}) { + optionValType := trueReflectValue(reflect.ValueOf(option)) + optionStructType := optionValType.Type() + + if isNil(optionStructType, optionValType) { + return + } + + for i := 0; i < optionStructType.NumField(); i++ { + fieldType := optionStructType.Field(i) + valType := optionValType.Field(i) + + secTag := parseSecurityTag(fieldType) + if secTag != nil && secTag.Scheme { + parseSecurityScheme(headers, queryParams, secTag, valType.Interface()) + } + } +} + +func parseSecurityScheme(headers, queryParams map[string]string, schemeTag *securityTag, scheme interface{}) { + schemeVal := trueReflectValue(reflect.ValueOf(scheme)) + schemeType := schemeVal.Type() + + if isNil(schemeType, schemeVal) { + return + } + + if schemeType.Kind() == reflect.Struct { + if schemeTag.Type == "http" && schemeTag.SubType == "basic" { + handleBasicAuthScheme(headers, schemeVal.Interface()) + return + } + + for i := 0; i < schemeType.NumField(); i++ { + fieldType := schemeType.Field(i) + valType := schemeVal.Field(i) + + if isNil(fieldType.Type, valType) { + continue + } + + if fieldType.Type.Kind() == reflect.Ptr { + valType = valType.Elem() + } + + secTag := parseSecurityTag(fieldType) + if secTag == nil || secTag.Name == "" { + return + } + + parseSecuritySchemeValue(headers, queryParams, schemeTag, secTag, valType.Interface()) + } + } else { + parseSecuritySchemeValue(headers, queryParams, schemeTag, schemeTag, schemeVal.Interface()) + } +} + +func parseSecuritySchemeValue(headers, queryParams map[string]string, schemeTag *securityTag, secTag *securityTag, val interface{}) { + switch schemeTag.Type { + case "apiKey": + switch schemeTag.SubType { + case "header": + headers[secTag.Name] = valToString(val) + case "query": + queryParams[secTag.Name] = valToString(val) + case "cookie": + headers["Cookie"] = fmt.Sprintf("%s=%s", secTag.Name, valToString(val)) + default: + panic("not supported") + } + case "openIdConnect": + headers[secTag.Name] = prefixBearer(valToString(val)) + case "oauth2": + if schemeTag.SubType != "client_credentials" { + headers[secTag.Name] = prefixBearer(valToString(val)) + } + case "http": + switch schemeTag.SubType { + case "bearer": + headers[secTag.Name] = prefixBearer(valToString(val)) + default: + panic("not supported") + } + default: + panic("not supported") + } +} + +func prefixBearer(authHeaderValue string) string { + if strings.HasPrefix(strings.ToLower(authHeaderValue), "bearer ") { + return authHeaderValue + } + + return fmt.Sprintf("Bearer %s", authHeaderValue) +} + +func handleBasicAuthScheme(headers map[string]string, scheme interface{}) { + schemeStructType := reflect.TypeOf(scheme) + schemeValType := reflect.ValueOf(scheme) + + var username, password string + + for i := 0; i < schemeStructType.NumField(); i++ { + fieldType := schemeStructType.Field(i) + valType := schemeValType.Field(i) + + secTag := parseSecurityTag(fieldType) + if secTag == nil || secTag.Name == "" { + continue + } + + switch secTag.Name { + case "username": + username = valType.String() + case "password": + password = valType.String() + } + } + + headers["Authorization"] = fmt.Sprintf("Basic %s", base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("%s:%s", username, password)))) +} + +func parseSecurityTag(field reflect.StructField) *securityTag { + tag := field.Tag.Get(securityTagKey) + if tag == "" { + return nil + } + + option := false + scheme := false + name := "" + securityType := "" + securitySubType := "" + + options := strings.Split(tag, ",") + for _, optionConf := range options { + parts := strings.Split(optionConf, "=") + if len(parts) < 1 || len(parts) > 2 { + continue + } + + switch parts[0] { + case "name": + name = parts[1] + case "type": + securityType = parts[1] + case "subtype": + securitySubType = parts[1] + case "option": + option = true + case "scheme": + scheme = true + } + } + + // TODO: validate tag? + + return &securityTag{ + Option: option, + Scheme: scheme, + Name: name, + Type: securityType, + SubType: securitySubType, + } +} + +func trueReflectValue(val reflect.Value) reflect.Value { + kind := val.Type().Kind() + for kind == reflect.Interface || kind == reflect.Ptr { + innerVal := val.Elem() + if !innerVal.IsValid() { + break + } + val = innerVal + kind = val.Type().Kind() + } + return val +} diff --git a/internal/utils/utils.go b/internal/utils/utils.go new file mode 100644 index 0000000..a35dc9b --- /dev/null +++ b/internal/utils/utils.go @@ -0,0 +1,223 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package utils + +import ( + "fmt" + "io" + "math/big" + "reflect" + "regexp" + "strconv" + "strings" + "time" + + "github.com/ericlagergren/decimal" +) + +const ( + queryParamTagKey = "queryParam" + headerParamTagKey = "header" + pathParamTagKey = "pathParam" +) + +var ( + paramRegex = regexp.MustCompile(`({.*?})`) + SerializationMethodToContentType = map[string]string{ + "json": "application/json", + "form": "application/x-www-form-urlencoded", + "multipart": "multipart/form-data", + "raw": "application/octet-stream", + "string": "text/plain", + } +) + +func UnmarshalJsonFromResponseBody(body io.Reader, out interface{}, tag string) error { + data, err := io.ReadAll(body) + if err != nil { + return fmt.Errorf("error reading response body: %w", err) + } + if err := UnmarshalJSON(data, out, reflect.StructTag(tag), true, false); err != nil { + return fmt.Errorf("error unmarshalling json response body: %w", err) + } + + return nil +} + +func ReplaceParameters(stringWithParams string, params map[string]string) string { + if len(params) == 0 { + return stringWithParams + } + + return paramRegex.ReplaceAllStringFunc(stringWithParams, func(match string) string { + match = match[1 : len(match)-1] + return params[match] + }) +} + +func Contains(slice []string, item string) bool { + for _, s := range slice { + if s == item { + return true + } + } + return false +} + +func MatchStatusCodes(expectedCodes []string, statusCode int) bool { + for _, codeStr := range expectedCodes { + code, err := strconv.Atoi(codeStr) + if err == nil { + if code == statusCode { + return true + } + continue + } + + codeRange, err := strconv.Atoi(string(codeStr[0])) + if err != nil { + continue + } + + if statusCode >= (codeRange*100) && statusCode < ((codeRange+1)*100) { + return true + } + } + + return false +} + +func parseStructTag(tagKey string, field reflect.StructField) map[string]string { + tag := field.Tag.Get(tagKey) + if tag == "" { + return nil + } + + values := map[string]string{} + + options := strings.Split(tag, ",") + for _, optionConf := range options { + parts := strings.Split(optionConf, "=") + + switch len(parts) { + case 1: + // flag option + parts = append(parts, "true") + case 2: + // key=value option + default: + // invalid option + continue + } + + values[parts[0]] = parts[1] + } + + return values +} + +func parseParamTag(tagKey string, field reflect.StructField, defaultStyle string, defaultExplode bool) *paramTag { + // example `{tagKey}:"style=simple,explode=false,name=apiID"` + values := parseStructTag(tagKey, field) + if values == nil { + return nil + } + + tag := ¶mTag{ + Style: defaultStyle, + Explode: defaultExplode, + ParamName: strings.ToLower(field.Name), + } + + for k, v := range values { + switch k { + case "style": + tag.Style = v + case "explode": + tag.Explode = v == "true" + case "name": + tag.ParamName = v + case "serialization": + tag.Serialization = v + } + } + + return tag +} + +func valToString(val interface{}) string { + switch v := val.(type) { + case time.Time: + return v.Format(time.RFC3339Nano) + case big.Int: + return v.String() + case decimal.Big: + return v.String() + default: + return fmt.Sprintf("%v", v) + } +} + +func populateFromGlobals(fieldType reflect.StructField, valType reflect.Value, paramType string, globals interface{}) (reflect.StructField, reflect.Value, bool) { + if globals == nil { + return fieldType, valType, false + } + + globalsStruct := reflect.TypeOf(globals) + globalsStructVal := reflect.ValueOf(globals) + + globalsField, found := globalsStruct.FieldByName(fieldType.Name) + if !found { + return fieldType, valType, false + } + + if fieldType.Type.Kind() != reflect.Ptr || !valType.IsNil() { + return fieldType, valType, true + } + + globalsVal := globalsStructVal.FieldByName(fieldType.Name) + + if !globalsVal.IsValid() { + return fieldType, valType, false + } + + switch paramType { + case queryParamTagKey: + qpTag := parseQueryParamTag(globalsField) + if qpTag == nil { + return fieldType, valType, false + } + default: + tag := parseParamTag(paramType, fieldType, "simple", false) + if tag == nil { + return fieldType, valType, false + } + } + + return globalsField, globalsVal, true +} + +func isNil(typ reflect.Type, val reflect.Value) bool { + // `reflect.TypeOf(nil) == nil` so calling typ.Kind() will cause a nil pointer + // dereference panic. Catch it and return early. + // https://github.com/golang/go/issues/51649 + // https://github.com/golang/go/issues/54208 + if typ == nil { + return true + } + + if typ.Kind() == reflect.Ptr || typ.Kind() == reflect.Map || typ.Kind() == reflect.Slice || typ.Kind() == reflect.Interface { + return val.IsNil() + } + + return false +} + +func contains(arr []string, str string) bool { + for _, a := range arr { + if a == str { + return true + } + } + return false +} diff --git a/keys.go b/keys.go new file mode 100644 index 0000000..d3bee0b --- /dev/null +++ b/keys.go @@ -0,0 +1,1234 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package unkeygo + +import ( + "bytes" + "context" + "fmt" + "github.com/unkeyed/unkey-go/internal/hooks" + "github.com/unkeyed/unkey-go/internal/utils" + "github.com/unkeyed/unkey-go/models/components" + "github.com/unkeyed/unkey-go/models/operations" + "github.com/unkeyed/unkey-go/models/sdkerrors" + "io" + "net/http" + "net/url" +) + +type Keys struct { + sdkConfiguration sdkConfiguration +} + +func newKeys(sdkConfig sdkConfiguration) *Keys { + return &Keys{ + sdkConfiguration: sdkConfig, + } +} + +func (s *Keys) GetKey(ctx context.Context, request operations.GetKeyRequest) (*components.Key, error) { + hookCtx := hooks.HookContext{ + Context: ctx, + OperationID: "getKey", + OAuth2Scopes: []string{}, + SecuritySource: s.sdkConfiguration.Security, + } + + baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) + opURL, err := url.JoinPath(baseURL, "/v1/keys.getKey") + if err != nil { + return nil, fmt.Errorf("error generating URL: %w", err) + } + + req, err := http.NewRequestWithContext(ctx, "GET", opURL, nil) + if err != nil { + return nil, fmt.Errorf("error creating request: %w", err) + } + req.Header.Set("Accept", "application/json") + req.Header.Set("User-Agent", s.sdkConfiguration.UserAgent) + + if err := utils.PopulateQueryParams(ctx, req, request, nil); err != nil { + return nil, fmt.Errorf("error populating query params: %w", err) + } + + if err := utils.PopulateSecurity(ctx, req, s.sdkConfiguration.Security); err != nil { + return nil, err + } + + req, err = s.sdkConfiguration.Hooks.BeforeRequest(hooks.BeforeRequestContext{HookContext: hookCtx}, req) + if err != nil { + return nil, err + } + + httpRes, err := s.sdkConfiguration.Client.Do(req) + if err != nil || httpRes == nil { + if err != nil { + err = fmt.Errorf("error sending request: %w", err) + } else { + err = fmt.Errorf("error sending request: no response") + } + + _, err = s.sdkConfiguration.Hooks.AfterError(hooks.AfterErrorContext{HookContext: hookCtx}, nil, err) + return nil, err + } else if utils.MatchStatusCodes([]string{"400", "401", "403", "404", "409", "429", "4XX", "500", "5XX"}, httpRes.StatusCode) { + _httpRes, err := s.sdkConfiguration.Hooks.AfterError(hooks.AfterErrorContext{HookContext: hookCtx}, httpRes, nil) + if err != nil { + return nil, err + } else if _httpRes != nil { + httpRes = _httpRes + } + } else { + httpRes, err = s.sdkConfiguration.Hooks.AfterSuccess(hooks.AfterSuccessContext{HookContext: hookCtx}, httpRes) + if err != nil { + return nil, err + } + } + + rawBody, err := io.ReadAll(httpRes.Body) + if err != nil { + return nil, fmt.Errorf("error reading response body: %w", err) + } + httpRes.Body.Close() + httpRes.Body = io.NopCloser(bytes.NewBuffer(rawBody)) + + switch { + case httpRes.StatusCode == 200: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out components.Key + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return &out, nil + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 400: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrBadRequest + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 401: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrUnauthorized + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 403: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrForbidden + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 404: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrNotFound + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 409: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrConflict + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 429: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrTooManyRequests + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode >= 400 && httpRes.StatusCode < 500: + fallthrough + case httpRes.StatusCode >= 500 && httpRes.StatusCode < 600: + return nil, sdkerrors.NewSDKError("API error occurred", httpRes.StatusCode, string(rawBody), httpRes) + case httpRes.StatusCode == 500: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrInternalServerError + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + default: + return nil, sdkerrors.NewSDKError("unknown status code returned", httpRes.StatusCode, string(rawBody), httpRes) + } +} + +func (s *Keys) DeleteKey(ctx context.Context, request operations.DeleteKeyRequestBody) (*operations.DeleteKeyResponseBody, error) { + hookCtx := hooks.HookContext{ + Context: ctx, + OperationID: "deleteKey", + OAuth2Scopes: []string{}, + SecuritySource: s.sdkConfiguration.Security, + } + + baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) + opURL, err := url.JoinPath(baseURL, "/v1/keys.deleteKey") + if err != nil { + return nil, fmt.Errorf("error generating URL: %w", err) + } + + bodyReader, reqContentType, err := utils.SerializeRequestBody(ctx, request, false, false, "Request", "json", `request:"mediaType=application/json"`) + if err != nil { + return nil, err + } + + req, err := http.NewRequestWithContext(ctx, "POST", opURL, bodyReader) + if err != nil { + return nil, fmt.Errorf("error creating request: %w", err) + } + req.Header.Set("Accept", "application/json") + req.Header.Set("User-Agent", s.sdkConfiguration.UserAgent) + req.Header.Set("Content-Type", reqContentType) + + if err := utils.PopulateSecurity(ctx, req, s.sdkConfiguration.Security); err != nil { + return nil, err + } + + req, err = s.sdkConfiguration.Hooks.BeforeRequest(hooks.BeforeRequestContext{HookContext: hookCtx}, req) + if err != nil { + return nil, err + } + + httpRes, err := s.sdkConfiguration.Client.Do(req) + if err != nil || httpRes == nil { + if err != nil { + err = fmt.Errorf("error sending request: %w", err) + } else { + err = fmt.Errorf("error sending request: no response") + } + + _, err = s.sdkConfiguration.Hooks.AfterError(hooks.AfterErrorContext{HookContext: hookCtx}, nil, err) + return nil, err + } else if utils.MatchStatusCodes([]string{"400", "401", "403", "404", "409", "429", "4XX", "500", "5XX"}, httpRes.StatusCode) { + _httpRes, err := s.sdkConfiguration.Hooks.AfterError(hooks.AfterErrorContext{HookContext: hookCtx}, httpRes, nil) + if err != nil { + return nil, err + } else if _httpRes != nil { + httpRes = _httpRes + } + } else { + httpRes, err = s.sdkConfiguration.Hooks.AfterSuccess(hooks.AfterSuccessContext{HookContext: hookCtx}, httpRes) + if err != nil { + return nil, err + } + } + + rawBody, err := io.ReadAll(httpRes.Body) + if err != nil { + return nil, fmt.Errorf("error reading response body: %w", err) + } + httpRes.Body.Close() + httpRes.Body = io.NopCloser(bytes.NewBuffer(rawBody)) + + switch { + case httpRes.StatusCode == 200: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out operations.DeleteKeyResponseBody + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return &out, nil + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 400: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrBadRequest + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 401: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrUnauthorized + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 403: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrForbidden + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 404: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrNotFound + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 409: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrConflict + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 429: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrTooManyRequests + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode >= 400 && httpRes.StatusCode < 500: + fallthrough + case httpRes.StatusCode >= 500 && httpRes.StatusCode < 600: + return nil, sdkerrors.NewSDKError("API error occurred", httpRes.StatusCode, string(rawBody), httpRes) + case httpRes.StatusCode == 500: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrInternalServerError + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + default: + return nil, sdkerrors.NewSDKError("unknown status code returned", httpRes.StatusCode, string(rawBody), httpRes) + } +} + +func (s *Keys) CreateKey(ctx context.Context, request operations.CreateKeyRequestBody) (*operations.CreateKeyResponseBody, error) { + hookCtx := hooks.HookContext{ + Context: ctx, + OperationID: "createKey", + OAuth2Scopes: []string{}, + SecuritySource: s.sdkConfiguration.Security, + } + + baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) + opURL, err := url.JoinPath(baseURL, "/v1/keys.createKey") + if err != nil { + return nil, fmt.Errorf("error generating URL: %w", err) + } + + bodyReader, reqContentType, err := utils.SerializeRequestBody(ctx, request, false, false, "Request", "json", `request:"mediaType=application/json"`) + if err != nil { + return nil, err + } + + req, err := http.NewRequestWithContext(ctx, "POST", opURL, bodyReader) + if err != nil { + return nil, fmt.Errorf("error creating request: %w", err) + } + req.Header.Set("Accept", "application/json") + req.Header.Set("User-Agent", s.sdkConfiguration.UserAgent) + req.Header.Set("Content-Type", reqContentType) + + if err := utils.PopulateSecurity(ctx, req, s.sdkConfiguration.Security); err != nil { + return nil, err + } + + req, err = s.sdkConfiguration.Hooks.BeforeRequest(hooks.BeforeRequestContext{HookContext: hookCtx}, req) + if err != nil { + return nil, err + } + + httpRes, err := s.sdkConfiguration.Client.Do(req) + if err != nil || httpRes == nil { + if err != nil { + err = fmt.Errorf("error sending request: %w", err) + } else { + err = fmt.Errorf("error sending request: no response") + } + + _, err = s.sdkConfiguration.Hooks.AfterError(hooks.AfterErrorContext{HookContext: hookCtx}, nil, err) + return nil, err + } else if utils.MatchStatusCodes([]string{"400", "401", "403", "404", "409", "429", "4XX", "500", "5XX"}, httpRes.StatusCode) { + _httpRes, err := s.sdkConfiguration.Hooks.AfterError(hooks.AfterErrorContext{HookContext: hookCtx}, httpRes, nil) + if err != nil { + return nil, err + } else if _httpRes != nil { + httpRes = _httpRes + } + } else { + httpRes, err = s.sdkConfiguration.Hooks.AfterSuccess(hooks.AfterSuccessContext{HookContext: hookCtx}, httpRes) + if err != nil { + return nil, err + } + } + + rawBody, err := io.ReadAll(httpRes.Body) + if err != nil { + return nil, fmt.Errorf("error reading response body: %w", err) + } + httpRes.Body.Close() + httpRes.Body = io.NopCloser(bytes.NewBuffer(rawBody)) + + switch { + case httpRes.StatusCode == 200: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out operations.CreateKeyResponseBody + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return &out, nil + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 400: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrBadRequest + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 401: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrUnauthorized + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 403: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrForbidden + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 404: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrNotFound + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 409: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrConflict + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 429: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrTooManyRequests + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode >= 400 && httpRes.StatusCode < 500: + fallthrough + case httpRes.StatusCode >= 500 && httpRes.StatusCode < 600: + return nil, sdkerrors.NewSDKError("API error occurred", httpRes.StatusCode, string(rawBody), httpRes) + case httpRes.StatusCode == 500: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrInternalServerError + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + default: + return nil, sdkerrors.NewSDKError("unknown status code returned", httpRes.StatusCode, string(rawBody), httpRes) + } +} + +func (s *Keys) VerifyKey(ctx context.Context, request components.V1KeysVerifyKeyRequest) (*components.V1KeysVerifyKeyResponse, error) { + hookCtx := hooks.HookContext{ + Context: ctx, + OperationID: "verifyKey", + OAuth2Scopes: []string{}, + SecuritySource: s.sdkConfiguration.Security, + } + + baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) + opURL, err := url.JoinPath(baseURL, "/v1/keys.verifyKey") + if err != nil { + return nil, fmt.Errorf("error generating URL: %w", err) + } + + bodyReader, reqContentType, err := utils.SerializeRequestBody(ctx, request, false, false, "Request", "json", `request:"mediaType=application/json"`) + if err != nil { + return nil, err + } + + req, err := http.NewRequestWithContext(ctx, "POST", opURL, bodyReader) + if err != nil { + return nil, fmt.Errorf("error creating request: %w", err) + } + req.Header.Set("Accept", "application/json") + req.Header.Set("User-Agent", s.sdkConfiguration.UserAgent) + req.Header.Set("Content-Type", reqContentType) + + if err := utils.PopulateSecurity(ctx, req, s.sdkConfiguration.Security); err != nil { + return nil, err + } + + req, err = s.sdkConfiguration.Hooks.BeforeRequest(hooks.BeforeRequestContext{HookContext: hookCtx}, req) + if err != nil { + return nil, err + } + + httpRes, err := s.sdkConfiguration.Client.Do(req) + if err != nil || httpRes == nil { + if err != nil { + err = fmt.Errorf("error sending request: %w", err) + } else { + err = fmt.Errorf("error sending request: no response") + } + + _, err = s.sdkConfiguration.Hooks.AfterError(hooks.AfterErrorContext{HookContext: hookCtx}, nil, err) + return nil, err + } else if utils.MatchStatusCodes([]string{"400", "401", "403", "404", "409", "429", "4XX", "500", "5XX"}, httpRes.StatusCode) { + _httpRes, err := s.sdkConfiguration.Hooks.AfterError(hooks.AfterErrorContext{HookContext: hookCtx}, httpRes, nil) + if err != nil { + return nil, err + } else if _httpRes != nil { + httpRes = _httpRes + } + } else { + httpRes, err = s.sdkConfiguration.Hooks.AfterSuccess(hooks.AfterSuccessContext{HookContext: hookCtx}, httpRes) + if err != nil { + return nil, err + } + } + + rawBody, err := io.ReadAll(httpRes.Body) + if err != nil { + return nil, fmt.Errorf("error reading response body: %w", err) + } + httpRes.Body.Close() + httpRes.Body = io.NopCloser(bytes.NewBuffer(rawBody)) + + switch { + case httpRes.StatusCode == 200: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out components.V1KeysVerifyKeyResponse + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return &out, nil + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 400: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrBadRequest + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 401: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrUnauthorized + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 403: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrForbidden + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 404: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrNotFound + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 409: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrConflict + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 429: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrTooManyRequests + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode >= 400 && httpRes.StatusCode < 500: + fallthrough + case httpRes.StatusCode >= 500 && httpRes.StatusCode < 600: + return nil, sdkerrors.NewSDKError("API error occurred", httpRes.StatusCode, string(rawBody), httpRes) + case httpRes.StatusCode == 500: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrInternalServerError + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + default: + return nil, sdkerrors.NewSDKError("unknown status code returned", httpRes.StatusCode, string(rawBody), httpRes) + } +} + +func (s *Keys) UpdateKey(ctx context.Context, request operations.UpdateKeyRequestBody) (*operations.UpdateKeyResponseBody, error) { + hookCtx := hooks.HookContext{ + Context: ctx, + OperationID: "updateKey", + OAuth2Scopes: []string{}, + SecuritySource: s.sdkConfiguration.Security, + } + + baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) + opURL, err := url.JoinPath(baseURL, "/v1/keys.updateKey") + if err != nil { + return nil, fmt.Errorf("error generating URL: %w", err) + } + + bodyReader, reqContentType, err := utils.SerializeRequestBody(ctx, request, false, false, "Request", "json", `request:"mediaType=application/json"`) + if err != nil { + return nil, err + } + + req, err := http.NewRequestWithContext(ctx, "POST", opURL, bodyReader) + if err != nil { + return nil, fmt.Errorf("error creating request: %w", err) + } + req.Header.Set("Accept", "application/json") + req.Header.Set("User-Agent", s.sdkConfiguration.UserAgent) + req.Header.Set("Content-Type", reqContentType) + + if err := utils.PopulateSecurity(ctx, req, s.sdkConfiguration.Security); err != nil { + return nil, err + } + + req, err = s.sdkConfiguration.Hooks.BeforeRequest(hooks.BeforeRequestContext{HookContext: hookCtx}, req) + if err != nil { + return nil, err + } + + httpRes, err := s.sdkConfiguration.Client.Do(req) + if err != nil || httpRes == nil { + if err != nil { + err = fmt.Errorf("error sending request: %w", err) + } else { + err = fmt.Errorf("error sending request: no response") + } + + _, err = s.sdkConfiguration.Hooks.AfterError(hooks.AfterErrorContext{HookContext: hookCtx}, nil, err) + return nil, err + } else if utils.MatchStatusCodes([]string{"400", "401", "403", "404", "409", "429", "4XX", "500", "5XX"}, httpRes.StatusCode) { + _httpRes, err := s.sdkConfiguration.Hooks.AfterError(hooks.AfterErrorContext{HookContext: hookCtx}, httpRes, nil) + if err != nil { + return nil, err + } else if _httpRes != nil { + httpRes = _httpRes + } + } else { + httpRes, err = s.sdkConfiguration.Hooks.AfterSuccess(hooks.AfterSuccessContext{HookContext: hookCtx}, httpRes) + if err != nil { + return nil, err + } + } + + rawBody, err := io.ReadAll(httpRes.Body) + if err != nil { + return nil, fmt.Errorf("error reading response body: %w", err) + } + httpRes.Body.Close() + httpRes.Body = io.NopCloser(bytes.NewBuffer(rawBody)) + + switch { + case httpRes.StatusCode == 200: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out operations.UpdateKeyResponseBody + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return &out, nil + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 400: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrBadRequest + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 401: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrUnauthorized + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 403: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrForbidden + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 404: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrNotFound + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 409: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrConflict + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 429: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrTooManyRequests + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode >= 400 && httpRes.StatusCode < 500: + fallthrough + case httpRes.StatusCode >= 500 && httpRes.StatusCode < 600: + return nil, sdkerrors.NewSDKError("API error occurred", httpRes.StatusCode, string(rawBody), httpRes) + case httpRes.StatusCode == 500: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrInternalServerError + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + default: + return nil, sdkerrors.NewSDKError("unknown status code returned", httpRes.StatusCode, string(rawBody), httpRes) + } +} + +func (s *Keys) UpdateRemaining(ctx context.Context, request operations.UpdateRemainingRequestBody) (*operations.UpdateRemainingResponseBody, error) { + hookCtx := hooks.HookContext{ + Context: ctx, + OperationID: "updateRemaining", + OAuth2Scopes: []string{}, + SecuritySource: s.sdkConfiguration.Security, + } + + baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) + opURL, err := url.JoinPath(baseURL, "/v1/keys.updateRemaining") + if err != nil { + return nil, fmt.Errorf("error generating URL: %w", err) + } + + bodyReader, reqContentType, err := utils.SerializeRequestBody(ctx, request, false, false, "Request", "json", `request:"mediaType=application/json"`) + if err != nil { + return nil, err + } + + req, err := http.NewRequestWithContext(ctx, "POST", opURL, bodyReader) + if err != nil { + return nil, fmt.Errorf("error creating request: %w", err) + } + req.Header.Set("Accept", "application/json") + req.Header.Set("User-Agent", s.sdkConfiguration.UserAgent) + req.Header.Set("Content-Type", reqContentType) + + if err := utils.PopulateSecurity(ctx, req, s.sdkConfiguration.Security); err != nil { + return nil, err + } + + req, err = s.sdkConfiguration.Hooks.BeforeRequest(hooks.BeforeRequestContext{HookContext: hookCtx}, req) + if err != nil { + return nil, err + } + + httpRes, err := s.sdkConfiguration.Client.Do(req) + if err != nil || httpRes == nil { + if err != nil { + err = fmt.Errorf("error sending request: %w", err) + } else { + err = fmt.Errorf("error sending request: no response") + } + + _, err = s.sdkConfiguration.Hooks.AfterError(hooks.AfterErrorContext{HookContext: hookCtx}, nil, err) + return nil, err + } else if utils.MatchStatusCodes([]string{"400", "401", "403", "404", "409", "429", "4XX", "500", "5XX"}, httpRes.StatusCode) { + _httpRes, err := s.sdkConfiguration.Hooks.AfterError(hooks.AfterErrorContext{HookContext: hookCtx}, httpRes, nil) + if err != nil { + return nil, err + } else if _httpRes != nil { + httpRes = _httpRes + } + } else { + httpRes, err = s.sdkConfiguration.Hooks.AfterSuccess(hooks.AfterSuccessContext{HookContext: hookCtx}, httpRes) + if err != nil { + return nil, err + } + } + + rawBody, err := io.ReadAll(httpRes.Body) + if err != nil { + return nil, fmt.Errorf("error reading response body: %w", err) + } + httpRes.Body.Close() + httpRes.Body = io.NopCloser(bytes.NewBuffer(rawBody)) + + switch { + case httpRes.StatusCode == 200: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out operations.UpdateRemainingResponseBody + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return &out, nil + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 400: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrBadRequest + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 401: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrUnauthorized + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 403: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrForbidden + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 404: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrNotFound + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 409: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrConflict + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 429: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrTooManyRequests + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode >= 400 && httpRes.StatusCode < 500: + fallthrough + case httpRes.StatusCode >= 500 && httpRes.StatusCode < 600: + return nil, sdkerrors.NewSDKError("API error occurred", httpRes.StatusCode, string(rawBody), httpRes) + case httpRes.StatusCode == 500: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrInternalServerError + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + default: + return nil, sdkerrors.NewSDKError("unknown status code returned", httpRes.StatusCode, string(rawBody), httpRes) + } +} + +func (s *Keys) GetVerifications(ctx context.Context, request operations.GetVerificationsRequest) (*operations.GetVerificationsResponseBody, error) { + hookCtx := hooks.HookContext{ + Context: ctx, + OperationID: "getVerifications", + OAuth2Scopes: []string{}, + SecuritySource: s.sdkConfiguration.Security, + } + + baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) + opURL, err := url.JoinPath(baseURL, "/v1/keys.getVerifications") + if err != nil { + return nil, fmt.Errorf("error generating URL: %w", err) + } + + req, err := http.NewRequestWithContext(ctx, "GET", opURL, nil) + if err != nil { + return nil, fmt.Errorf("error creating request: %w", err) + } + req.Header.Set("Accept", "application/json") + req.Header.Set("User-Agent", s.sdkConfiguration.UserAgent) + + if err := utils.PopulateQueryParams(ctx, req, request, nil); err != nil { + return nil, fmt.Errorf("error populating query params: %w", err) + } + + if err := utils.PopulateSecurity(ctx, req, s.sdkConfiguration.Security); err != nil { + return nil, err + } + + req, err = s.sdkConfiguration.Hooks.BeforeRequest(hooks.BeforeRequestContext{HookContext: hookCtx}, req) + if err != nil { + return nil, err + } + + httpRes, err := s.sdkConfiguration.Client.Do(req) + if err != nil || httpRes == nil { + if err != nil { + err = fmt.Errorf("error sending request: %w", err) + } else { + err = fmt.Errorf("error sending request: no response") + } + + _, err = s.sdkConfiguration.Hooks.AfterError(hooks.AfterErrorContext{HookContext: hookCtx}, nil, err) + return nil, err + } else if utils.MatchStatusCodes([]string{"400", "401", "403", "404", "409", "429", "4XX", "500", "5XX"}, httpRes.StatusCode) { + _httpRes, err := s.sdkConfiguration.Hooks.AfterError(hooks.AfterErrorContext{HookContext: hookCtx}, httpRes, nil) + if err != nil { + return nil, err + } else if _httpRes != nil { + httpRes = _httpRes + } + } else { + httpRes, err = s.sdkConfiguration.Hooks.AfterSuccess(hooks.AfterSuccessContext{HookContext: hookCtx}, httpRes) + if err != nil { + return nil, err + } + } + + rawBody, err := io.ReadAll(httpRes.Body) + if err != nil { + return nil, fmt.Errorf("error reading response body: %w", err) + } + httpRes.Body.Close() + httpRes.Body = io.NopCloser(bytes.NewBuffer(rawBody)) + + switch { + case httpRes.StatusCode == 200: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out operations.GetVerificationsResponseBody + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return &out, nil + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 400: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrBadRequest + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 401: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrUnauthorized + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 403: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrForbidden + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 404: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrNotFound + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 409: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrConflict + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 429: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrTooManyRequests + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode >= 400 && httpRes.StatusCode < 500: + fallthrough + case httpRes.StatusCode >= 500 && httpRes.StatusCode < 600: + return nil, sdkerrors.NewSDKError("API error occurred", httpRes.StatusCode, string(rawBody), httpRes) + case httpRes.StatusCode == 500: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrInternalServerError + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + default: + return nil, sdkerrors.NewSDKError("unknown status code returned", httpRes.StatusCode, string(rawBody), httpRes) + } +} diff --git a/liveness.go b/liveness.go new file mode 100644 index 0000000..3849830 --- /dev/null +++ b/liveness.go @@ -0,0 +1,193 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package unkeygo + +import ( + "bytes" + "context" + "fmt" + "github.com/unkeyed/unkey-go/internal/hooks" + "github.com/unkeyed/unkey-go/internal/utils" + "github.com/unkeyed/unkey-go/models/operations" + "github.com/unkeyed/unkey-go/models/sdkerrors" + "io" + "net/http" + "net/url" +) + +type Liveness struct { + sdkConfiguration sdkConfiguration +} + +func newLiveness(sdkConfig sdkConfiguration) *Liveness { + return &Liveness{ + sdkConfiguration: sdkConfig, + } +} + +func (s *Liveness) V1Liveness(ctx context.Context) (*operations.V1LivenessResponseBody, error) { + hookCtx := hooks.HookContext{ + Context: ctx, + OperationID: "v1.liveness", + OAuth2Scopes: []string{}, + SecuritySource: s.sdkConfiguration.Security, + } + + baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) + opURL, err := url.JoinPath(baseURL, "/v1/liveness") + if err != nil { + return nil, fmt.Errorf("error generating URL: %w", err) + } + + req, err := http.NewRequestWithContext(ctx, "GET", opURL, nil) + if err != nil { + return nil, fmt.Errorf("error creating request: %w", err) + } + req.Header.Set("Accept", "application/json") + req.Header.Set("User-Agent", s.sdkConfiguration.UserAgent) + + if err := utils.PopulateSecurity(ctx, req, s.sdkConfiguration.Security); err != nil { + return nil, err + } + + req, err = s.sdkConfiguration.Hooks.BeforeRequest(hooks.BeforeRequestContext{HookContext: hookCtx}, req) + if err != nil { + return nil, err + } + + httpRes, err := s.sdkConfiguration.Client.Do(req) + if err != nil || httpRes == nil { + if err != nil { + err = fmt.Errorf("error sending request: %w", err) + } else { + err = fmt.Errorf("error sending request: no response") + } + + _, err = s.sdkConfiguration.Hooks.AfterError(hooks.AfterErrorContext{HookContext: hookCtx}, nil, err) + return nil, err + } else if utils.MatchStatusCodes([]string{"400", "401", "403", "404", "409", "429", "4XX", "500", "5XX"}, httpRes.StatusCode) { + _httpRes, err := s.sdkConfiguration.Hooks.AfterError(hooks.AfterErrorContext{HookContext: hookCtx}, httpRes, nil) + if err != nil { + return nil, err + } else if _httpRes != nil { + httpRes = _httpRes + } + } else { + httpRes, err = s.sdkConfiguration.Hooks.AfterSuccess(hooks.AfterSuccessContext{HookContext: hookCtx}, httpRes) + if err != nil { + return nil, err + } + } + + rawBody, err := io.ReadAll(httpRes.Body) + if err != nil { + return nil, fmt.Errorf("error reading response body: %w", err) + } + httpRes.Body.Close() + httpRes.Body = io.NopCloser(bytes.NewBuffer(rawBody)) + + switch { + case httpRes.StatusCode == 200: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out operations.V1LivenessResponseBody + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return &out, nil + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 400: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrBadRequest + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 401: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrUnauthorized + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 403: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrForbidden + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 404: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrNotFound + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 409: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrConflict + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 429: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrTooManyRequests + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode >= 400 && httpRes.StatusCode < 500: + fallthrough + case httpRes.StatusCode >= 500 && httpRes.StatusCode < 600: + return nil, sdkerrors.NewSDKError("API error occurred", httpRes.StatusCode, string(rawBody), httpRes) + case httpRes.StatusCode == 500: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrInternalServerError + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + default: + return nil, sdkerrors.NewSDKError("unknown status code returned", httpRes.StatusCode, string(rawBody), httpRes) + } +} diff --git a/migrations.go b/migrations.go new file mode 100644 index 0000000..1a0709e --- /dev/null +++ b/migrations.go @@ -0,0 +1,199 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package unkeygo + +import ( + "bytes" + "context" + "fmt" + "github.com/unkeyed/unkey-go/internal/hooks" + "github.com/unkeyed/unkey-go/internal/utils" + "github.com/unkeyed/unkey-go/models/operations" + "github.com/unkeyed/unkey-go/models/sdkerrors" + "io" + "net/http" + "net/url" +) + +type Migrations struct { + sdkConfiguration sdkConfiguration +} + +func newMigrations(sdkConfig sdkConfiguration) *Migrations { + return &Migrations{ + sdkConfiguration: sdkConfig, + } +} + +func (s *Migrations) V1MigrationsCreateKeys(ctx context.Context, request []operations.RequestBody) (*operations.V1MigrationsCreateKeysResponseBody, error) { + hookCtx := hooks.HookContext{ + Context: ctx, + OperationID: "v1.migrations.createKeys", + OAuth2Scopes: []string{}, + SecuritySource: s.sdkConfiguration.Security, + } + + baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) + opURL, err := url.JoinPath(baseURL, "/v1/migrations.createKeys") + if err != nil { + return nil, fmt.Errorf("error generating URL: %w", err) + } + + bodyReader, reqContentType, err := utils.SerializeRequestBody(ctx, request, false, false, "Request", "json", `request:"mediaType=application/json"`) + if err != nil { + return nil, err + } + + req, err := http.NewRequestWithContext(ctx, "POST", opURL, bodyReader) + if err != nil { + return nil, fmt.Errorf("error creating request: %w", err) + } + req.Header.Set("Accept", "application/json") + req.Header.Set("User-Agent", s.sdkConfiguration.UserAgent) + req.Header.Set("Content-Type", reqContentType) + + if err := utils.PopulateSecurity(ctx, req, s.sdkConfiguration.Security); err != nil { + return nil, err + } + + req, err = s.sdkConfiguration.Hooks.BeforeRequest(hooks.BeforeRequestContext{HookContext: hookCtx}, req) + if err != nil { + return nil, err + } + + httpRes, err := s.sdkConfiguration.Client.Do(req) + if err != nil || httpRes == nil { + if err != nil { + err = fmt.Errorf("error sending request: %w", err) + } else { + err = fmt.Errorf("error sending request: no response") + } + + _, err = s.sdkConfiguration.Hooks.AfterError(hooks.AfterErrorContext{HookContext: hookCtx}, nil, err) + return nil, err + } else if utils.MatchStatusCodes([]string{"400", "401", "403", "404", "409", "429", "4XX", "500", "5XX"}, httpRes.StatusCode) { + _httpRes, err := s.sdkConfiguration.Hooks.AfterError(hooks.AfterErrorContext{HookContext: hookCtx}, httpRes, nil) + if err != nil { + return nil, err + } else if _httpRes != nil { + httpRes = _httpRes + } + } else { + httpRes, err = s.sdkConfiguration.Hooks.AfterSuccess(hooks.AfterSuccessContext{HookContext: hookCtx}, httpRes) + if err != nil { + return nil, err + } + } + + rawBody, err := io.ReadAll(httpRes.Body) + if err != nil { + return nil, fmt.Errorf("error reading response body: %w", err) + } + httpRes.Body.Close() + httpRes.Body = io.NopCloser(bytes.NewBuffer(rawBody)) + + switch { + case httpRes.StatusCode == 200: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out operations.V1MigrationsCreateKeysResponseBody + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return &out, nil + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 400: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrBadRequest + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 401: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrUnauthorized + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 403: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrForbidden + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 404: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrNotFound + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 409: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrConflict + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 429: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrTooManyRequests + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode >= 400 && httpRes.StatusCode < 500: + fallthrough + case httpRes.StatusCode >= 500 && httpRes.StatusCode < 600: + return nil, sdkerrors.NewSDKError("API error occurred", httpRes.StatusCode, string(rawBody), httpRes) + case httpRes.StatusCode == 500: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrInternalServerError + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + default: + return nil, sdkerrors.NewSDKError("unknown status code returned", httpRes.StatusCode, string(rawBody), httpRes) + } +} diff --git a/models/components/key.go b/models/components/key.go new file mode 100644 index 0000000..c650bfd --- /dev/null +++ b/models/components/key.go @@ -0,0 +1,296 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package components + +import ( + "encoding/json" + "fmt" + "github.com/unkeyed/unkey-go/internal/utils" +) + +// Interval - Determines the rate at which verifications will be refilled. +type Interval string + +const ( + IntervalDaily Interval = "daily" + IntervalMonthly Interval = "monthly" +) + +func (e Interval) ToPointer() *Interval { + return &e +} + +func (e *Interval) UnmarshalJSON(data []byte) error { + var v string + if err := json.Unmarshal(data, &v); err != nil { + return err + } + switch v { + case "daily": + fallthrough + case "monthly": + *e = Interval(v) + return nil + default: + return fmt.Errorf("invalid value for Interval: %v", v) + } +} + +// Refill - Unkey allows you to refill remaining verifications on a key on a regular interval. +type Refill struct { + // Determines the rate at which verifications will be refilled. + Interval Interval `json:"interval"` + // Resets `remaining` to this value every interval. + Amount int64 `json:"amount"` + // The unix timestamp in miliseconds when the key was last refilled. + LastRefillAt *float64 `json:"lastRefillAt,omitempty"` +} + +func (o *Refill) GetInterval() Interval { + if o == nil { + return Interval("") + } + return o.Interval +} + +func (o *Refill) GetAmount() int64 { + if o == nil { + return 0 + } + return o.Amount +} + +func (o *Refill) GetLastRefillAt() *float64 { + if o == nil { + return nil + } + return o.LastRefillAt +} + +// Type - Fast ratelimiting doesn't add latency, while consistent ratelimiting is more accurate. +// +// https://unkey.dev/docs/features/ratelimiting - Learn more +type Type string + +const ( + TypeFast Type = "fast" + TypeConsistent Type = "consistent" +) + +func (e Type) ToPointer() *Type { + return &e +} + +func (e *Type) UnmarshalJSON(data []byte) error { + var v string + if err := json.Unmarshal(data, &v); err != nil { + return err + } + switch v { + case "fast": + fallthrough + case "consistent": + *e = Type(v) + return nil + default: + return fmt.Errorf("invalid value for Type: %v", v) + } +} + +// Ratelimit - Unkey comes with per-key ratelimiting out of the box. +type Ratelimit struct { + // Fast ratelimiting doesn't add latency, while consistent ratelimiting is more accurate. + Type *Type `default:"fast" json:"type"` + // The total amount of burstable requests. + Limit int64 `json:"limit"` + // How many tokens to refill during each refillInterval. + RefillRate int64 `json:"refillRate"` + // Determines the speed at which tokens are refilled, in milliseconds. + RefillInterval int64 `json:"refillInterval"` +} + +func (r Ratelimit) MarshalJSON() ([]byte, error) { + return utils.MarshalJSON(r, "", false) +} + +func (r *Ratelimit) UnmarshalJSON(data []byte) error { + if err := utils.UnmarshalJSON(data, &r, "", false, false); err != nil { + return err + } + return nil +} + +func (o *Ratelimit) GetType() *Type { + if o == nil { + return nil + } + return o.Type +} + +func (o *Ratelimit) GetLimit() int64 { + if o == nil { + return 0 + } + return o.Limit +} + +func (o *Ratelimit) GetRefillRate() int64 { + if o == nil { + return 0 + } + return o.RefillRate +} + +func (o *Ratelimit) GetRefillInterval() int64 { + if o == nil { + return 0 + } + return o.RefillInterval +} + +type Key struct { + // The id of the key + ID string `json:"id"` + // The first few characters of the key to visually identify it + Start string `json:"start"` + // The id of the workspace that owns the key + WorkspaceID string `json:"workspaceId"` + // The id of the api that this key is for + APIID *string `json:"apiId,omitempty"` + // The name of the key, give keys a name to easily identify their purpose + Name *string `json:"name,omitempty"` + // The id of the tenant associated with this key. Use whatever reference you have in your system to identify the tenant. When verifying the key, we will send this field back to you, so you know who is accessing your API. + OwnerID *string `json:"ownerId,omitempty"` + // Any additional metadata you want to store with the key + Meta map[string]interface{} `json:"meta,omitempty"` + // The unix timestamp in milliseconds when the key was created + CreatedAt *float64 `json:"createdAt,omitempty"` + // The unix timestamp in milliseconds when the key was deleted. We don't delete the key outright, you can restore it later. + DeletedAt *float64 `json:"deletedAt,omitempty"` + // The unix timestamp in milliseconds when the key will expire. If this field is null or undefined, the key is not expiring. + Expires *float64 `json:"expires,omitempty"` + // The number of requests that can be made with this key before it becomes invalid. If this field is null or undefined, the key has no request limit. + Remaining *float64 `json:"remaining,omitempty"` + // Unkey allows you to refill remaining verifications on a key on a regular interval. + Refill *Refill `json:"refill,omitempty"` + // Unkey comes with per-key ratelimiting out of the box. + Ratelimit *Ratelimit `json:"ratelimit,omitempty"` + // All roles this key belongs to + Roles []string `json:"roles,omitempty"` + // All permissions this key has + Permissions []string `json:"permissions,omitempty"` + // Sets if key is enabled or disabled. Disabled keys are not valid. + Enabled *bool `json:"enabled,omitempty"` +} + +func (o *Key) GetID() string { + if o == nil { + return "" + } + return o.ID +} + +func (o *Key) GetStart() string { + if o == nil { + return "" + } + return o.Start +} + +func (o *Key) GetWorkspaceID() string { + if o == nil { + return "" + } + return o.WorkspaceID +} + +func (o *Key) GetAPIID() *string { + if o == nil { + return nil + } + return o.APIID +} + +func (o *Key) GetName() *string { + if o == nil { + return nil + } + return o.Name +} + +func (o *Key) GetOwnerID() *string { + if o == nil { + return nil + } + return o.OwnerID +} + +func (o *Key) GetMeta() map[string]interface{} { + if o == nil { + return nil + } + return o.Meta +} + +func (o *Key) GetCreatedAt() *float64 { + if o == nil { + return nil + } + return o.CreatedAt +} + +func (o *Key) GetDeletedAt() *float64 { + if o == nil { + return nil + } + return o.DeletedAt +} + +func (o *Key) GetExpires() *float64 { + if o == nil { + return nil + } + return o.Expires +} + +func (o *Key) GetRemaining() *float64 { + if o == nil { + return nil + } + return o.Remaining +} + +func (o *Key) GetRefill() *Refill { + if o == nil { + return nil + } + return o.Refill +} + +func (o *Key) GetRatelimit() *Ratelimit { + if o == nil { + return nil + } + return o.Ratelimit +} + +func (o *Key) GetRoles() []string { + if o == nil { + return nil + } + return o.Roles +} + +func (o *Key) GetPermissions() []string { + if o == nil { + return nil + } + return o.Permissions +} + +func (o *Key) GetEnabled() *bool { + if o == nil { + return nil + } + return o.Enabled +} diff --git a/models/components/security.go b/models/components/security.go new file mode 100644 index 0000000..ee0481d --- /dev/null +++ b/models/components/security.go @@ -0,0 +1,14 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package components + +type Security struct { + BearerAuth *string `security:"scheme,type=http,subtype=bearer,name=Authorization"` +} + +func (o *Security) GetBearerAuth() *string { + if o == nil { + return nil + } + return o.BearerAuth +} diff --git a/models/components/v1keysverifykeyrequest.go b/models/components/v1keysverifykeyrequest.go new file mode 100644 index 0000000..dcbf9de --- /dev/null +++ b/models/components/v1keysverifykeyrequest.go @@ -0,0 +1,86 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package components + +import ( + "github.com/unkeyed/unkey-go/internal/utils" +) + +// Permissions - A query for which permissions you require +type Permissions struct { +} + +// Authorization - Perform RBAC checks +type Authorization struct { + // A query for which permissions you require + Permissions *Permissions `json:"permissions,omitempty"` +} + +func (o *Authorization) GetPermissions() *Permissions { + if o == nil { + return nil + } + return o.Permissions +} + +type V1KeysVerifyKeyRequestRatelimit struct { + // Override how many tokens are deducted during the ratelimit operation. + Cost *int64 `default:"1" json:"cost"` +} + +func (v V1KeysVerifyKeyRequestRatelimit) MarshalJSON() ([]byte, error) { + return utils.MarshalJSON(v, "", false) +} + +func (v *V1KeysVerifyKeyRequestRatelimit) UnmarshalJSON(data []byte) error { + if err := utils.UnmarshalJSON(data, &v, "", false, false); err != nil { + return err + } + return nil +} + +func (o *V1KeysVerifyKeyRequestRatelimit) GetCost() *int64 { + if o == nil { + return nil + } + return o.Cost +} + +type V1KeysVerifyKeyRequest struct { + // The id of the api where the key belongs to. This is optional for now but will be required soon. + // The key will be verified against the api's configuration. If the key does not belong to the api, the verification will fail. + APIID *string `json:"apiId,omitempty"` + // The key to verify + Key string `json:"key"` + // Perform RBAC checks + Authorization *Authorization `json:"authorization,omitempty"` + Ratelimit *V1KeysVerifyKeyRequestRatelimit `json:"ratelimit,omitempty"` +} + +func (o *V1KeysVerifyKeyRequest) GetAPIID() *string { + if o == nil { + return nil + } + return o.APIID +} + +func (o *V1KeysVerifyKeyRequest) GetKey() string { + if o == nil { + return "" + } + return o.Key +} + +func (o *V1KeysVerifyKeyRequest) GetAuthorization() *Authorization { + if o == nil { + return nil + } + return o.Authorization +} + +func (o *V1KeysVerifyKeyRequest) GetRatelimit() *V1KeysVerifyKeyRequestRatelimit { + if o == nil { + return nil + } + return o.Ratelimit +} diff --git a/models/components/v1keysverifykeyresponse.go b/models/components/v1keysverifykeyresponse.go new file mode 100644 index 0000000..7aba39a --- /dev/null +++ b/models/components/v1keysverifykeyresponse.go @@ -0,0 +1,216 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package components + +import ( + "encoding/json" + "fmt" +) + +// V1KeysVerifyKeyResponseRatelimit - The ratelimit configuration for this key. If this field is null or undefined, the key has no ratelimit. +type V1KeysVerifyKeyResponseRatelimit struct { + // Maximum number of requests that can be made inside a window + Limit float64 `json:"limit"` + // Remaining requests after this verification + Remaining float64 `json:"remaining"` + // Unix timestamp in milliseconds when the ratelimit will reset + Reset float64 `json:"reset"` +} + +func (o *V1KeysVerifyKeyResponseRatelimit) GetLimit() float64 { + if o == nil { + return 0.0 + } + return o.Limit +} + +func (o *V1KeysVerifyKeyResponseRatelimit) GetRemaining() float64 { + if o == nil { + return 0.0 + } + return o.Remaining +} + +func (o *V1KeysVerifyKeyResponseRatelimit) GetReset() float64 { + if o == nil { + return 0.0 + } + return o.Reset +} + +// Code - A machine readable code why the key is not valid. +// Possible values are: +// - VALID: the key is valid and you should proceed +// - NOT_FOUND: the key does not exist or has expired +// - FORBIDDEN: the key is not allowed to access the api +// - USAGE_EXCEEDED: the key has exceeded its request limit +// - RATE_LIMITED: the key has been ratelimited +// - UNAUTHORIZED: the key is not authorized +// - DISABLED: the key is disabled +// - INSUFFICIENT_PERMISSIONS: you do not have the required permissions to perform this action +type Code string + +const ( + CodeValid Code = "VALID" + CodeNotFound Code = "NOT_FOUND" + CodeForbidden Code = "FORBIDDEN" + CodeUsageExceeded Code = "USAGE_EXCEEDED" + CodeRateLimited Code = "RATE_LIMITED" + CodeUnauthorized Code = "UNAUTHORIZED" + CodeDisabled Code = "DISABLED" + CodeInsufficientPermissions Code = "INSUFFICIENT_PERMISSIONS" +) + +func (e Code) ToPointer() *Code { + return &e +} + +func (e *Code) UnmarshalJSON(data []byte) error { + var v string + if err := json.Unmarshal(data, &v); err != nil { + return err + } + switch v { + case "VALID": + fallthrough + case "NOT_FOUND": + fallthrough + case "FORBIDDEN": + fallthrough + case "USAGE_EXCEEDED": + fallthrough + case "RATE_LIMITED": + fallthrough + case "UNAUTHORIZED": + fallthrough + case "DISABLED": + fallthrough + case "INSUFFICIENT_PERMISSIONS": + *e = Code(v) + return nil + default: + return fmt.Errorf("invalid value for Code: %v", v) + } +} + +type V1KeysVerifyKeyResponse struct { + // The id of the key + KeyID *string `json:"keyId,omitempty"` + // Whether the key is valid or not. + // A key could be invalid for a number of reasons, for example if it has expired, has no more verifications left or if it has been deleted. + Valid bool `json:"valid"` + // The name of the key, give keys a name to easily identifiy their purpose + Name *string `json:"name,omitempty"` + // The id of the tenant associated with this key. Use whatever reference you have in your system to identify the tenant. When verifying the key, we will send this field back to you, so you know who is accessing your API. + OwnerID *string `json:"ownerId,omitempty"` + // Any additional metadata you want to store with the key + Meta map[string]interface{} `json:"meta,omitempty"` + // The unix timestamp in milliseconds when the key will expire. If this field is null or undefined, the key is not expiring. + Expires *float64 `json:"expires,omitempty"` + // The ratelimit configuration for this key. If this field is null or undefined, the key has no ratelimit. + Ratelimit *V1KeysVerifyKeyResponseRatelimit `json:"ratelimit,omitempty"` + // The number of requests that can be made with this key before it becomes invalid. If this field is null or undefined, the key has no request limit. + Remaining *float64 `json:"remaining,omitempty"` + // A machine readable code why the key is not valid. + // Possible values are: + // - VALID: the key is valid and you should proceed + // - NOT_FOUND: the key does not exist or has expired + // - FORBIDDEN: the key is not allowed to access the api + // - USAGE_EXCEEDED: the key has exceeded its request limit + // - RATE_LIMITED: the key has been ratelimited + // - UNAUTHORIZED: the key is not authorized + // - DISABLED: the key is disabled + // - INSUFFICIENT_PERMISSIONS: you do not have the required permissions to perform this action + // + Code Code `json:"code"` + // Sets the key to be enabled or disabled. Disabled keys will not verify. + Enabled *bool `json:"enabled,omitempty"` + // A list of all the permissions this key is connected to. + Permissions []string `json:"permissions,omitempty"` + // The environment of the key, this is what what you set when you crated the key + Environment *string `json:"environment,omitempty"` +} + +func (o *V1KeysVerifyKeyResponse) GetKeyID() *string { + if o == nil { + return nil + } + return o.KeyID +} + +func (o *V1KeysVerifyKeyResponse) GetValid() bool { + if o == nil { + return false + } + return o.Valid +} + +func (o *V1KeysVerifyKeyResponse) GetName() *string { + if o == nil { + return nil + } + return o.Name +} + +func (o *V1KeysVerifyKeyResponse) GetOwnerID() *string { + if o == nil { + return nil + } + return o.OwnerID +} + +func (o *V1KeysVerifyKeyResponse) GetMeta() map[string]interface{} { + if o == nil { + return nil + } + return o.Meta +} + +func (o *V1KeysVerifyKeyResponse) GetExpires() *float64 { + if o == nil { + return nil + } + return o.Expires +} + +func (o *V1KeysVerifyKeyResponse) GetRatelimit() *V1KeysVerifyKeyResponseRatelimit { + if o == nil { + return nil + } + return o.Ratelimit +} + +func (o *V1KeysVerifyKeyResponse) GetRemaining() *float64 { + if o == nil { + return nil + } + return o.Remaining +} + +func (o *V1KeysVerifyKeyResponse) GetCode() Code { + if o == nil { + return Code("") + } + return o.Code +} + +func (o *V1KeysVerifyKeyResponse) GetEnabled() *bool { + if o == nil { + return nil + } + return o.Enabled +} + +func (o *V1KeysVerifyKeyResponse) GetPermissions() []string { + if o == nil { + return nil + } + return o.Permissions +} + +func (o *V1KeysVerifyKeyResponse) GetEnvironment() *string { + if o == nil { + return nil + } + return o.Environment +} diff --git a/models/operations/createapi.go b/models/operations/createapi.go new file mode 100644 index 0000000..90a3d68 --- /dev/null +++ b/models/operations/createapi.go @@ -0,0 +1,28 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package operations + +type CreateAPIRequestBody struct { + // The name for your API. This is not customer facing. + Name string `json:"name"` +} + +func (o *CreateAPIRequestBody) GetName() string { + if o == nil { + return "" + } + return o.Name +} + +// CreateAPIResponseBody - The configuration for an api +type CreateAPIResponseBody struct { + // The id of the api + APIID string `json:"apiId"` +} + +func (o *CreateAPIResponseBody) GetAPIID() string { + if o == nil { + return "" + } + return o.APIID +} diff --git a/models/operations/createkey.go b/models/operations/createkey.go new file mode 100644 index 0000000..ec33bfc --- /dev/null +++ b/models/operations/createkey.go @@ -0,0 +1,307 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package operations + +import ( + "encoding/json" + "fmt" + "github.com/unkeyed/unkey-go/internal/utils" +) + +// Interval - Unkey will automatically refill verifications at the set interval. +type Interval string + +const ( + IntervalDaily Interval = "daily" + IntervalMonthly Interval = "monthly" +) + +func (e Interval) ToPointer() *Interval { + return &e +} + +func (e *Interval) UnmarshalJSON(data []byte) error { + var v string + if err := json.Unmarshal(data, &v); err != nil { + return err + } + switch v { + case "daily": + fallthrough + case "monthly": + *e = Interval(v) + return nil + default: + return fmt.Errorf("invalid value for Interval: %v", v) + } +} + +// Refill - Unkey enables you to refill verifications for each key at regular intervals. +type Refill struct { + // Unkey will automatically refill verifications at the set interval. + Interval Interval `json:"interval"` + // The number of verifications to refill for each occurrence is determined individually for each key. + Amount int64 `json:"amount"` +} + +func (o *Refill) GetInterval() Interval { + if o == nil { + return Interval("") + } + return o.Interval +} + +func (o *Refill) GetAmount() int64 { + if o == nil { + return 0 + } + return o.Amount +} + +// Type - Fast ratelimiting doesn't add latency, while consistent ratelimiting is more accurate. +// +// https://unkey.dev/docs/features/ratelimiting - Learn more +type Type string + +const ( + TypeFast Type = "fast" + TypeConsistent Type = "consistent" +) + +func (e Type) ToPointer() *Type { + return &e +} + +func (e *Type) UnmarshalJSON(data []byte) error { + var v string + if err := json.Unmarshal(data, &v); err != nil { + return err + } + switch v { + case "fast": + fallthrough + case "consistent": + *e = Type(v) + return nil + default: + return fmt.Errorf("invalid value for Type: %v", v) + } +} + +// Ratelimit - Unkey comes with per-key ratelimiting out of the box. +type Ratelimit struct { + // Fast ratelimiting doesn't add latency, while consistent ratelimiting is more accurate. + Type *Type `default:"fast" json:"type"` + // The total amount of burstable requests. + Limit int64 `json:"limit"` + // How many tokens to refill during each refillInterval. + RefillRate int64 `json:"refillRate"` + // Determines the speed at which tokens are refilled, in milliseconds. + RefillInterval int64 `json:"refillInterval"` +} + +func (r Ratelimit) MarshalJSON() ([]byte, error) { + return utils.MarshalJSON(r, "", false) +} + +func (r *Ratelimit) UnmarshalJSON(data []byte) error { + if err := utils.UnmarshalJSON(data, &r, "", false, false); err != nil { + return err + } + return nil +} + +func (o *Ratelimit) GetType() *Type { + if o == nil { + return nil + } + return o.Type +} + +func (o *Ratelimit) GetLimit() int64 { + if o == nil { + return 0 + } + return o.Limit +} + +func (o *Ratelimit) GetRefillRate() int64 { + if o == nil { + return 0 + } + return o.RefillRate +} + +func (o *Ratelimit) GetRefillInterval() int64 { + if o == nil { + return 0 + } + return o.RefillInterval +} + +type CreateKeyRequestBody struct { + // Choose an `API` where this key should be created. + APIID string `json:"apiId"` + // To make it easier for your users to understand which product an api key belongs to, you can add prefix them. + // + // For example Stripe famously prefixes their customer ids with cus_ or their api keys with sk_live_. + // + // The underscore is automatically added if you are defining a prefix, for example: "prefix": "abc" will result in a key like abc_xxxxxxxxx + // + Prefix *string `json:"prefix,omitempty"` + // The name for your Key. This is not customer facing. + Name *string `json:"name,omitempty"` + // The byte length used to generate your key determines its entropy as well as its length. Higher is better, but keys become longer and more annoying to handle. The default is 16 bytes, or 2^^128 possible combinations. + ByteLength *int64 `default:"16" json:"byteLength"` + // Your user’s Id. This will provide a link between Unkey and your customer record. + // When validating a key, we will return this back to you, so you can clearly identify your user from their api key. + OwnerID *string `json:"ownerId,omitempty"` + // This is a place for dynamic meta data, anything that feels useful for you should go here + Meta map[string]interface{} `json:"meta,omitempty"` + // A list of roles that this key should have. If the role does not exist, an error is thrown + Roles []string `json:"roles,omitempty"` + // You can auto expire keys by providing a unix timestamp in milliseconds. Once Keys expire they will automatically be disabled and are no longer valid unless you enable them again. + Expires *int64 `json:"expires,omitempty"` + // You can limit the number of requests a key can make. Once a key reaches 0 remaining requests, it will automatically be disabled and is no longer valid unless you update it. + Remaining *int64 `json:"remaining,omitempty"` + // Unkey enables you to refill verifications for each key at regular intervals. + Refill *Refill `json:"refill,omitempty"` + // Unkey comes with per-key ratelimiting out of the box. + Ratelimit *Ratelimit `json:"ratelimit,omitempty"` + // Sets if key is enabled or disabled. Disabled keys are not valid. + Enabled *bool `default:"true" json:"enabled"` + // Environments allow you to divide your keyspace. + // + // Some applications like Stripe, Clerk, WorkOS and others have a concept of "live" and "test" keys to + // give the developer a way to develop their own application without the risk of modifying real world + // resources. + // + // When you set an environment, we will return it back to you when validating the key, so you can + // handle it correctly. + // + Environment *string `json:"environment,omitempty"` +} + +func (c CreateKeyRequestBody) MarshalJSON() ([]byte, error) { + return utils.MarshalJSON(c, "", false) +} + +func (c *CreateKeyRequestBody) UnmarshalJSON(data []byte) error { + if err := utils.UnmarshalJSON(data, &c, "", false, false); err != nil { + return err + } + return nil +} + +func (o *CreateKeyRequestBody) GetAPIID() string { + if o == nil { + return "" + } + return o.APIID +} + +func (o *CreateKeyRequestBody) GetPrefix() *string { + if o == nil { + return nil + } + return o.Prefix +} + +func (o *CreateKeyRequestBody) GetName() *string { + if o == nil { + return nil + } + return o.Name +} + +func (o *CreateKeyRequestBody) GetByteLength() *int64 { + if o == nil { + return nil + } + return o.ByteLength +} + +func (o *CreateKeyRequestBody) GetOwnerID() *string { + if o == nil { + return nil + } + return o.OwnerID +} + +func (o *CreateKeyRequestBody) GetMeta() map[string]interface{} { + if o == nil { + return nil + } + return o.Meta +} + +func (o *CreateKeyRequestBody) GetRoles() []string { + if o == nil { + return nil + } + return o.Roles +} + +func (o *CreateKeyRequestBody) GetExpires() *int64 { + if o == nil { + return nil + } + return o.Expires +} + +func (o *CreateKeyRequestBody) GetRemaining() *int64 { + if o == nil { + return nil + } + return o.Remaining +} + +func (o *CreateKeyRequestBody) GetRefill() *Refill { + if o == nil { + return nil + } + return o.Refill +} + +func (o *CreateKeyRequestBody) GetRatelimit() *Ratelimit { + if o == nil { + return nil + } + return o.Ratelimit +} + +func (o *CreateKeyRequestBody) GetEnabled() *bool { + if o == nil { + return nil + } + return o.Enabled +} + +func (o *CreateKeyRequestBody) GetEnvironment() *string { + if o == nil { + return nil + } + return o.Environment +} + +// CreateKeyResponseBody - The configuration for an api +type CreateKeyResponseBody struct { + // The id of the key. This is not a secret and can be stored as a reference if you wish. You need the keyId to update or delete a key later. + KeyID string `json:"keyId"` + // The newly created api key, do not store this on your own system but pass it along to your user. + Key string `json:"key"` +} + +func (o *CreateKeyResponseBody) GetKeyID() string { + if o == nil { + return "" + } + return o.KeyID +} + +func (o *CreateKeyResponseBody) GetKey() string { + if o == nil { + return "" + } + return o.Key +} diff --git a/models/operations/deleteapi.go b/models/operations/deleteapi.go new file mode 100644 index 0000000..70fce4f --- /dev/null +++ b/models/operations/deleteapi.go @@ -0,0 +1,19 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package operations + +type DeleteAPIRequestBody struct { + // The id of the api to delete + APIID string `json:"apiId"` +} + +func (o *DeleteAPIRequestBody) GetAPIID() string { + if o == nil { + return "" + } + return o.APIID +} + +// DeleteAPIResponseBody - The api was successfully deleted, it may take up to 30s for this to take effect in all regions +type DeleteAPIResponseBody struct { +} diff --git a/models/operations/deletekey.go b/models/operations/deletekey.go new file mode 100644 index 0000000..3185276 --- /dev/null +++ b/models/operations/deletekey.go @@ -0,0 +1,19 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package operations + +type DeleteKeyRequestBody struct { + // The id of the key to revoke + KeyID string `json:"keyId"` +} + +func (o *DeleteKeyRequestBody) GetKeyID() string { + if o == nil { + return "" + } + return o.KeyID +} + +// DeleteKeyResponseBody - The key was successfully revoked, it may take up to 30s for this to take effect in all regions +type DeleteKeyResponseBody struct { +} diff --git a/models/operations/deprecatedcreatekey.go b/models/operations/deprecatedcreatekey.go new file mode 100644 index 0000000..28c2b95 --- /dev/null +++ b/models/operations/deprecatedcreatekey.go @@ -0,0 +1,213 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package operations + +import ( + "encoding/json" + "fmt" + "github.com/unkeyed/unkey-go/internal/utils" +) + +// DeprecatedCreateKeyType - Fast ratelimiting doesn't add latency, while consistent ratelimiting is more accurate. +// +// https://unkey.dev/docs/features/ratelimiting - Learn more +type DeprecatedCreateKeyType string + +const ( + DeprecatedCreateKeyTypeFast DeprecatedCreateKeyType = "fast" + DeprecatedCreateKeyTypeConsistent DeprecatedCreateKeyType = "consistent" +) + +func (e DeprecatedCreateKeyType) ToPointer() *DeprecatedCreateKeyType { + return &e +} + +func (e *DeprecatedCreateKeyType) UnmarshalJSON(data []byte) error { + var v string + if err := json.Unmarshal(data, &v); err != nil { + return err + } + switch v { + case "fast": + fallthrough + case "consistent": + *e = DeprecatedCreateKeyType(v) + return nil + default: + return fmt.Errorf("invalid value for DeprecatedCreateKeyType: %v", v) + } +} + +// DeprecatedCreateKeyRatelimit - Unkey comes with per-key ratelimiting out of the box. +type DeprecatedCreateKeyRatelimit struct { + // Fast ratelimiting doesn't add latency, while consistent ratelimiting is more accurate. + Type *DeprecatedCreateKeyType `default:"fast" json:"type"` + // The total amount of burstable requests. + Limit int64 `json:"limit"` + // How many tokens to refill during each refillInterval. + RefillRate int64 `json:"refillRate"` + // Determines the speed at which tokens are refilled, in milliseconds. + RefillInterval int64 `json:"refillInterval"` +} + +func (d DeprecatedCreateKeyRatelimit) MarshalJSON() ([]byte, error) { + return utils.MarshalJSON(d, "", false) +} + +func (d *DeprecatedCreateKeyRatelimit) UnmarshalJSON(data []byte) error { + if err := utils.UnmarshalJSON(data, &d, "", false, false); err != nil { + return err + } + return nil +} + +func (o *DeprecatedCreateKeyRatelimit) GetType() *DeprecatedCreateKeyType { + if o == nil { + return nil + } + return o.Type +} + +func (o *DeprecatedCreateKeyRatelimit) GetLimit() int64 { + if o == nil { + return 0 + } + return o.Limit +} + +func (o *DeprecatedCreateKeyRatelimit) GetRefillRate() int64 { + if o == nil { + return 0 + } + return o.RefillRate +} + +func (o *DeprecatedCreateKeyRatelimit) GetRefillInterval() int64 { + if o == nil { + return 0 + } + return o.RefillInterval +} + +type DeprecatedCreateKeyRequestBody struct { + // Choose an `API` where this key should be created. + APIID string `json:"apiId"` + // To make it easier for your users to understand which product an api key belongs to, you can add prefix them. + // + // For example Stripe famously prefixes their customer ids with cus_ or their api keys with sk_live_. + // + // The underscore is automatically added if you are defining a prefix, for example: "prefix": "abc" will result in a key like abc_xxxxxxxxx + // + Prefix *string `json:"prefix,omitempty"` + // The name for your Key. This is not customer facing. + Name *string `json:"name,omitempty"` + // The byte length used to generate your key determines its entropy as well as its length. Higher is better, but keys become longer and more annoying to handle. The default is 16 bytes, or 2^^128 possible combinations. + ByteLength *int64 `default:"16" json:"byteLength"` + // Your user’s Id. This will provide a link between Unkey and your customer record. + // When validating a key, we will return this back to you, so you can clearly identify your user from their api key. + OwnerID *string `json:"ownerId,omitempty"` + // This is a place for dynamic meta data, anything that feels useful for you should go here + Meta map[string]interface{} `json:"meta,omitempty"` + // You can auto expire keys by providing a unix timestamp in milliseconds. Once Keys expire they will automatically be disabled and are no longer valid unless you enable them again. + Expires *int64 `json:"expires,omitempty"` + // You can limit the number of requests a key can make. Once a key reaches 0 remaining requests, it will automatically be disabled and is no longer valid unless you update it. + Remaining *int64 `json:"remaining,omitempty"` + // Unkey comes with per-key ratelimiting out of the box. + Ratelimit *DeprecatedCreateKeyRatelimit `json:"ratelimit,omitempty"` +} + +func (d DeprecatedCreateKeyRequestBody) MarshalJSON() ([]byte, error) { + return utils.MarshalJSON(d, "", false) +} + +func (d *DeprecatedCreateKeyRequestBody) UnmarshalJSON(data []byte) error { + if err := utils.UnmarshalJSON(data, &d, "", false, false); err != nil { + return err + } + return nil +} + +func (o *DeprecatedCreateKeyRequestBody) GetAPIID() string { + if o == nil { + return "" + } + return o.APIID +} + +func (o *DeprecatedCreateKeyRequestBody) GetPrefix() *string { + if o == nil { + return nil + } + return o.Prefix +} + +func (o *DeprecatedCreateKeyRequestBody) GetName() *string { + if o == nil { + return nil + } + return o.Name +} + +func (o *DeprecatedCreateKeyRequestBody) GetByteLength() *int64 { + if o == nil { + return nil + } + return o.ByteLength +} + +func (o *DeprecatedCreateKeyRequestBody) GetOwnerID() *string { + if o == nil { + return nil + } + return o.OwnerID +} + +func (o *DeprecatedCreateKeyRequestBody) GetMeta() map[string]interface{} { + if o == nil { + return nil + } + return o.Meta +} + +func (o *DeprecatedCreateKeyRequestBody) GetExpires() *int64 { + if o == nil { + return nil + } + return o.Expires +} + +func (o *DeprecatedCreateKeyRequestBody) GetRemaining() *int64 { + if o == nil { + return nil + } + return o.Remaining +} + +func (o *DeprecatedCreateKeyRequestBody) GetRatelimit() *DeprecatedCreateKeyRatelimit { + if o == nil { + return nil + } + return o.Ratelimit +} + +// DeprecatedCreateKeyResponseBody - The configuration for an api +type DeprecatedCreateKeyResponseBody struct { + // The id of the key. This is not a secret and can be stored as a reference if you wish. You need the keyId to update or delete a key later. + KeyID string `json:"keyId"` + // The newly created api key, do not store this on your own system but pass it along to your user. + Key string `json:"key"` +} + +func (o *DeprecatedCreateKeyResponseBody) GetKeyID() string { + if o == nil { + return "" + } + return o.KeyID +} + +func (o *DeprecatedCreateKeyResponseBody) GetKey() string { + if o == nil { + return "" + } + return o.Key +} diff --git a/models/operations/deprecatedlistkeys.go b/models/operations/deprecatedlistkeys.go new file mode 100644 index 0000000..c958b50 --- /dev/null +++ b/models/operations/deprecatedlistkeys.go @@ -0,0 +1,75 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package operations + +import ( + "github.com/unkeyed/unkey-go/internal/utils" + "github.com/unkeyed/unkey-go/models/components" +) + +type DeprecatedListKeysRequest struct { + APIID string `pathParam:"style=simple,explode=false,name=apiId"` + Limit *int64 `default:"100" queryParam:"style=form,explode=true,name=limit"` + Offset *float64 `queryParam:"style=form,explode=true,name=offset"` + OwnerID *string `queryParam:"style=form,explode=true,name=ownerId"` +} + +func (d DeprecatedListKeysRequest) MarshalJSON() ([]byte, error) { + return utils.MarshalJSON(d, "", false) +} + +func (d *DeprecatedListKeysRequest) UnmarshalJSON(data []byte) error { + if err := utils.UnmarshalJSON(data, &d, "", false, false); err != nil { + return err + } + return nil +} + +func (o *DeprecatedListKeysRequest) GetAPIID() string { + if o == nil { + return "" + } + return o.APIID +} + +func (o *DeprecatedListKeysRequest) GetLimit() *int64 { + if o == nil { + return nil + } + return o.Limit +} + +func (o *DeprecatedListKeysRequest) GetOffset() *float64 { + if o == nil { + return nil + } + return o.Offset +} + +func (o *DeprecatedListKeysRequest) GetOwnerID() *string { + if o == nil { + return nil + } + return o.OwnerID +} + +// DeprecatedListKeysResponseBody - Keys belonging to the api +type DeprecatedListKeysResponseBody struct { + Keys []components.Key `json:"keys"` + // The total number of keys for this api + Total int64 `json:"total"` +} + +func (o *DeprecatedListKeysResponseBody) GetKeys() []components.Key { + if o == nil { + return []components.Key{} + } + return o.Keys +} + +func (o *DeprecatedListKeysResponseBody) GetTotal() int64 { + if o == nil { + return 0 + } + return o.Total +} diff --git a/models/operations/deprecatedverifykey.go b/models/operations/deprecatedverifykey.go new file mode 100644 index 0000000..caa61d1 --- /dev/null +++ b/models/operations/deprecatedverifykey.go @@ -0,0 +1,221 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package operations + +import ( + "encoding/json" + "fmt" +) + +type DeprecatedVerifyKeyRequestBody struct { + // The id of the api where the key belongs to. This is optional for now but will be required soon. + // The key will be verified against the api's configuration. If the key does not belong to the api, the verification will fail. + APIID *string `json:"apiId,omitempty"` + // The key to verify + Key string `json:"key"` +} + +func (o *DeprecatedVerifyKeyRequestBody) GetAPIID() *string { + if o == nil { + return nil + } + return o.APIID +} + +func (o *DeprecatedVerifyKeyRequestBody) GetKey() string { + if o == nil { + return "" + } + return o.Key +} + +// DeprecatedVerifyKeyRatelimit - The ratelimit configuration for this key. If this field is null or undefined, the key has no ratelimit. +type DeprecatedVerifyKeyRatelimit struct { + // Maximum number of requests that can be made inside a window + Limit float64 `json:"limit"` + // Remaining requests after this verification + Remaining float64 `json:"remaining"` + // Unix timestamp in milliseconds when the ratelimit will reset + Reset float64 `json:"reset"` +} + +func (o *DeprecatedVerifyKeyRatelimit) GetLimit() float64 { + if o == nil { + return 0.0 + } + return o.Limit +} + +func (o *DeprecatedVerifyKeyRatelimit) GetRemaining() float64 { + if o == nil { + return 0.0 + } + return o.Remaining +} + +func (o *DeprecatedVerifyKeyRatelimit) GetReset() float64 { + if o == nil { + return 0.0 + } + return o.Reset +} + +// Code - If the key is invalid this field will be set to the reason why it is invalid. +// Possible values are: +// - NOT_FOUND: the key does not exist or has expired +// - FORBIDDEN: the key is not allowed to access the api +// - USAGE_EXCEEDED: the key has exceeded its request limit +// - RATE_LIMITED: the key has been ratelimited, +// - INSUFFICIENT_PERMISSIONS: you do not have the required permissions to perform this action +type Code string + +const ( + CodeNotFound Code = "NOT_FOUND" + CodeForbidden Code = "FORBIDDEN" + CodeUsageExceeded Code = "USAGE_EXCEEDED" + CodeRateLimited Code = "RATE_LIMITED" + CodeUnauthorized Code = "UNAUTHORIZED" + CodeDisabled Code = "DISABLED" + CodeInsufficientPermissions Code = "INSUFFICIENT_PERMISSIONS" +) + +func (e Code) ToPointer() *Code { + return &e +} + +func (e *Code) UnmarshalJSON(data []byte) error { + var v string + if err := json.Unmarshal(data, &v); err != nil { + return err + } + switch v { + case "NOT_FOUND": + fallthrough + case "FORBIDDEN": + fallthrough + case "USAGE_EXCEEDED": + fallthrough + case "RATE_LIMITED": + fallthrough + case "UNAUTHORIZED": + fallthrough + case "DISABLED": + fallthrough + case "INSUFFICIENT_PERMISSIONS": + *e = Code(v) + return nil + default: + return fmt.Errorf("invalid value for Code: %v", v) + } +} + +// DeprecatedVerifyKeyResponseBody - The verification result +type DeprecatedVerifyKeyResponseBody struct { + // The id of the key + KeyID *string `json:"keyId,omitempty"` + // Whether the key is valid or not. + // A key could be invalid for a number of reasons, for example if it has expired, has no more verifications left or if it has been deleted. + Valid bool `json:"valid"` + // The name of the key, give keys a name to easily identifiy their purpose + Name *string `json:"name,omitempty"` + // The id of the tenant associated with this key. Use whatever reference you have in your system to identify the tenant. When verifying the key, we will send this field back to you, so you know who is accessing your API. + OwnerID *string `json:"ownerId,omitempty"` + // Any additional metadata you want to store with the key + Meta map[string]interface{} `json:"meta,omitempty"` + // The unix timestamp in milliseconds when the key was created + CreatedAt *float64 `json:"createdAt,omitempty"` + // The unix timestamp in milliseconds when the key was deleted. We don't delete the key outright, you can restore it later. + DeletedAt *float64 `json:"deletedAt,omitempty"` + // The unix timestamp in milliseconds when the key will expire. If this field is null or undefined, the key is not expiring. + Expires *float64 `json:"expires,omitempty"` + // The ratelimit configuration for this key. If this field is null or undefined, the key has no ratelimit. + Ratelimit *DeprecatedVerifyKeyRatelimit `json:"ratelimit,omitempty"` + // The number of requests that can be made with this key before it becomes invalid. If this field is null or undefined, the key has no request limit. + Remaining *float64 `json:"remaining,omitempty"` + // If the key is invalid this field will be set to the reason why it is invalid. + // Possible values are: + // - NOT_FOUND: the key does not exist or has expired + // - FORBIDDEN: the key is not allowed to access the api + // - USAGE_EXCEEDED: the key has exceeded its request limit + // - RATE_LIMITED: the key has been ratelimited, + // - INSUFFICIENT_PERMISSIONS: you do not have the required permissions to perform this action + // + Code *Code `json:"code,omitempty"` +} + +func (o *DeprecatedVerifyKeyResponseBody) GetKeyID() *string { + if o == nil { + return nil + } + return o.KeyID +} + +func (o *DeprecatedVerifyKeyResponseBody) GetValid() bool { + if o == nil { + return false + } + return o.Valid +} + +func (o *DeprecatedVerifyKeyResponseBody) GetName() *string { + if o == nil { + return nil + } + return o.Name +} + +func (o *DeprecatedVerifyKeyResponseBody) GetOwnerID() *string { + if o == nil { + return nil + } + return o.OwnerID +} + +func (o *DeprecatedVerifyKeyResponseBody) GetMeta() map[string]interface{} { + if o == nil { + return nil + } + return o.Meta +} + +func (o *DeprecatedVerifyKeyResponseBody) GetCreatedAt() *float64 { + if o == nil { + return nil + } + return o.CreatedAt +} + +func (o *DeprecatedVerifyKeyResponseBody) GetDeletedAt() *float64 { + if o == nil { + return nil + } + return o.DeletedAt +} + +func (o *DeprecatedVerifyKeyResponseBody) GetExpires() *float64 { + if o == nil { + return nil + } + return o.Expires +} + +func (o *DeprecatedVerifyKeyResponseBody) GetRatelimit() *DeprecatedVerifyKeyRatelimit { + if o == nil { + return nil + } + return o.Ratelimit +} + +func (o *DeprecatedVerifyKeyResponseBody) GetRemaining() *float64 { + if o == nil { + return nil + } + return o.Remaining +} + +func (o *DeprecatedVerifyKeyResponseBody) GetCode() *Code { + if o == nil { + return nil + } + return o.Code +} diff --git a/models/operations/getapi.go b/models/operations/getapi.go new file mode 100644 index 0000000..a7f9819 --- /dev/null +++ b/models/operations/getapi.go @@ -0,0 +1,45 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package operations + +type GetAPIRequest struct { + APIID string `queryParam:"style=form,explode=true,name=apiId"` +} + +func (o *GetAPIRequest) GetAPIID() string { + if o == nil { + return "" + } + return o.APIID +} + +// GetAPIResponseBody - The configuration for an api +type GetAPIResponseBody struct { + // The id of the key + ID string `json:"id"` + // The id of the workspace that owns the api + WorkspaceID string `json:"workspaceId"` + // The name of the api. This is internal and your users will not see this. + Name *string `json:"name,omitempty"` +} + +func (o *GetAPIResponseBody) GetID() string { + if o == nil { + return "" + } + return o.ID +} + +func (o *GetAPIResponseBody) GetWorkspaceID() string { + if o == nil { + return "" + } + return o.WorkspaceID +} + +func (o *GetAPIResponseBody) GetName() *string { + if o == nil { + return nil + } + return o.Name +} diff --git a/models/operations/getkey.go b/models/operations/getkey.go new file mode 100644 index 0000000..4f2a031 --- /dev/null +++ b/models/operations/getkey.go @@ -0,0 +1,14 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package operations + +type GetKeyRequest struct { + KeyID string `queryParam:"style=form,explode=true,name=keyId"` +} + +func (o *GetKeyRequest) GetKeyID() string { + if o == nil { + return "" + } + return o.KeyID +} diff --git a/models/operations/getverifications.go b/models/operations/getverifications.go new file mode 100644 index 0000000..ba5a918 --- /dev/null +++ b/models/operations/getverifications.go @@ -0,0 +1,140 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package operations + +import ( + "encoding/json" + "fmt" + "github.com/unkeyed/unkey-go/internal/utils" +) + +// Granularity - The granularity of the usage data to fetch, currently only `day` is supported +type Granularity string + +const ( + GranularityDay Granularity = "day" +) + +func (e Granularity) ToPointer() *Granularity { + return &e +} + +func (e *Granularity) UnmarshalJSON(data []byte) error { + var v string + if err := json.Unmarshal(data, &v); err != nil { + return err + } + switch v { + case "day": + *e = Granularity(v) + return nil + default: + return fmt.Errorf("invalid value for Granularity: %v", v) + } +} + +type GetVerificationsRequest struct { + KeyID *string `queryParam:"style=form,explode=true,name=keyId"` + OwnerID *string `queryParam:"style=form,explode=true,name=ownerId"` + Start *int64 `queryParam:"style=form,explode=true,name=start"` + End *int64 `queryParam:"style=form,explode=true,name=end"` + // The granularity of the usage data to fetch, currently only `day` is supported + Granularity *Granularity `default:"day" queryParam:"style=form,explode=true,name=granularity"` +} + +func (g GetVerificationsRequest) MarshalJSON() ([]byte, error) { + return utils.MarshalJSON(g, "", false) +} + +func (g *GetVerificationsRequest) UnmarshalJSON(data []byte) error { + if err := utils.UnmarshalJSON(data, &g, "", false, false); err != nil { + return err + } + return nil +} + +func (o *GetVerificationsRequest) GetKeyID() *string { + if o == nil { + return nil + } + return o.KeyID +} + +func (o *GetVerificationsRequest) GetOwnerID() *string { + if o == nil { + return nil + } + return o.OwnerID +} + +func (o *GetVerificationsRequest) GetStart() *int64 { + if o == nil { + return nil + } + return o.Start +} + +func (o *GetVerificationsRequest) GetEnd() *int64 { + if o == nil { + return nil + } + return o.End +} + +func (o *GetVerificationsRequest) GetGranularity() *Granularity { + if o == nil { + return nil + } + return o.Granularity +} + +type Verifications struct { + // The timestamp of the usage data + Time int64 `json:"time"` + // The number of successful requests + Success float64 `json:"success"` + // The number of requests that were rate limited + RateLimited float64 `json:"rateLimited"` + // The number of requests that exceeded the usage limit + UsageExceeded float64 `json:"usageExceeded"` +} + +func (o *Verifications) GetTime() int64 { + if o == nil { + return 0 + } + return o.Time +} + +func (o *Verifications) GetSuccess() float64 { + if o == nil { + return 0.0 + } + return o.Success +} + +func (o *Verifications) GetRateLimited() float64 { + if o == nil { + return 0.0 + } + return o.RateLimited +} + +func (o *Verifications) GetUsageExceeded() float64 { + if o == nil { + return 0.0 + } + return o.UsageExceeded +} + +// GetVerificationsResponseBody - Usage numbers over time +type GetVerificationsResponseBody struct { + Verifications []Verifications `json:"verifications"` +} + +func (o *GetVerificationsResponseBody) GetVerifications() []Verifications { + if o == nil { + return []Verifications{} + } + return o.Verifications +} diff --git a/models/operations/limit.go b/models/operations/limit.go new file mode 100644 index 0000000..c70e9e0 --- /dev/null +++ b/models/operations/limit.go @@ -0,0 +1,171 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package operations + +import ( + "github.com/unkeyed/unkey-go/internal/utils" +) + +type Resources struct { + // The type of resource + Type string `json:"type"` + // The unique identifier for the resource + ID string `json:"id"` + // A human readable name for this resource + Name *string `json:"name,omitempty"` + // Attach any metadata to this resources + Meta map[string]interface{} `json:"meta,omitempty"` +} + +func (o *Resources) GetType() string { + if o == nil { + return "" + } + return o.Type +} + +func (o *Resources) GetID() string { + if o == nil { + return "" + } + return o.ID +} + +func (o *Resources) GetName() *string { + if o == nil { + return nil + } + return o.Name +} + +func (o *Resources) GetMeta() map[string]interface{} { + if o == nil { + return nil + } + return o.Meta +} + +type LimitRequestBody struct { + // Namespaces group different limits together for better analytics. You might have a namespace for your public API and one for internal tRPC routes. + Namespace *string `default:"default" json:"namespace"` + // Identifier of your user, this can be their userId, an email, an ip or anything else. + Identifier string `json:"identifier"` + // How many requests may pass in a given window. + Limit int64 `json:"limit"` + // The window duration in milliseconds + Duration int64 `json:"duration"` + // Expensive requests may use up more tokens. You can specify a cost to the request here and we'll deduct this many tokens in the current window. If there are not enough tokens left, the request is denied. + Cost *int64 `default:"1" json:"cost"` + // Async will return a response immediately, lowering latency at the cost of accuracy. + Async *bool `default:"false" json:"async"` + // Attach any metadata to this request + Meta map[string]interface{} `json:"meta,omitempty"` + // Resources that are about to be accessed by the user + Resources []Resources `json:"resources,omitempty"` +} + +func (l LimitRequestBody) MarshalJSON() ([]byte, error) { + return utils.MarshalJSON(l, "", false) +} + +func (l *LimitRequestBody) UnmarshalJSON(data []byte) error { + if err := utils.UnmarshalJSON(data, &l, "", false, false); err != nil { + return err + } + return nil +} + +func (o *LimitRequestBody) GetNamespace() *string { + if o == nil { + return nil + } + return o.Namespace +} + +func (o *LimitRequestBody) GetIdentifier() string { + if o == nil { + return "" + } + return o.Identifier +} + +func (o *LimitRequestBody) GetLimit() int64 { + if o == nil { + return 0 + } + return o.Limit +} + +func (o *LimitRequestBody) GetDuration() int64 { + if o == nil { + return 0 + } + return o.Duration +} + +func (o *LimitRequestBody) GetCost() *int64 { + if o == nil { + return nil + } + return o.Cost +} + +func (o *LimitRequestBody) GetAsync() *bool { + if o == nil { + return nil + } + return o.Async +} + +func (o *LimitRequestBody) GetMeta() map[string]interface{} { + if o == nil { + return nil + } + return o.Meta +} + +func (o *LimitRequestBody) GetResources() []Resources { + if o == nil { + return nil + } + return o.Resources +} + +type LimitResponseBody struct { + // Returns true if the request should be processed, false if it was rejected. + Success bool `json:"success"` + // How many requests are allowed within a window. + Limit float64 `json:"limit"` + // How many requests can still be made in the current window. + Remaining float64 `json:"remaining"` + // A unix millisecond timestamp when the limits reset. + Reset float64 `json:"reset"` +} + +func (o *LimitResponseBody) GetSuccess() bool { + if o == nil { + return false + } + return o.Success +} + +func (o *LimitResponseBody) GetLimit() float64 { + if o == nil { + return 0.0 + } + return o.Limit +} + +func (o *LimitResponseBody) GetRemaining() float64 { + if o == nil { + return 0.0 + } + return o.Remaining +} + +func (o *LimitResponseBody) GetReset() float64 { + if o == nil { + return 0.0 + } + return o.Reset +} diff --git a/models/operations/listkeys.go b/models/operations/listkeys.go new file mode 100644 index 0000000..24a0d6b --- /dev/null +++ b/models/operations/listkeys.go @@ -0,0 +1,84 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package operations + +import ( + "github.com/unkeyed/unkey-go/internal/utils" + "github.com/unkeyed/unkey-go/models/components" +) + +type ListKeysRequest struct { + APIID string `queryParam:"style=form,explode=true,name=apiId"` + Limit *int64 `default:"100" queryParam:"style=form,explode=true,name=limit"` + Cursor *string `queryParam:"style=form,explode=true,name=cursor"` + OwnerID *string `queryParam:"style=form,explode=true,name=ownerId"` +} + +func (l ListKeysRequest) MarshalJSON() ([]byte, error) { + return utils.MarshalJSON(l, "", false) +} + +func (l *ListKeysRequest) UnmarshalJSON(data []byte) error { + if err := utils.UnmarshalJSON(data, &l, "", false, false); err != nil { + return err + } + return nil +} + +func (o *ListKeysRequest) GetAPIID() string { + if o == nil { + return "" + } + return o.APIID +} + +func (o *ListKeysRequest) GetLimit() *int64 { + if o == nil { + return nil + } + return o.Limit +} + +func (o *ListKeysRequest) GetCursor() *string { + if o == nil { + return nil + } + return o.Cursor +} + +func (o *ListKeysRequest) GetOwnerID() *string { + if o == nil { + return nil + } + return o.OwnerID +} + +// ListKeysResponseBody - The configuration for an api +type ListKeysResponseBody struct { + Keys []components.Key `json:"keys"` + // The cursor to use for the next page of results, if no cursor is returned, there are no more results + Cursor *string `json:"cursor,omitempty"` + // The total number of keys for this api + Total int64 `json:"total"` +} + +func (o *ListKeysResponseBody) GetKeys() []components.Key { + if o == nil { + return []components.Key{} + } + return o.Keys +} + +func (o *ListKeysResponseBody) GetCursor() *string { + if o == nil { + return nil + } + return o.Cursor +} + +func (o *ListKeysResponseBody) GetTotal() int64 { + if o == nil { + return 0 + } + return o.Total +} diff --git a/models/operations/updatekey.go b/models/operations/updatekey.go new file mode 100644 index 0000000..39ea661 --- /dev/null +++ b/models/operations/updatekey.go @@ -0,0 +1,216 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package operations + +import ( + "encoding/json" + "fmt" +) + +// UpdateKeyType - Fast ratelimiting doesn't add latency, while consistent ratelimiting is more accurate. +// +// https://unkey.dev/docs/features/ratelimiting - Learn more +type UpdateKeyType string + +const ( + UpdateKeyTypeFast UpdateKeyType = "fast" + UpdateKeyTypeConsistent UpdateKeyType = "consistent" +) + +func (e UpdateKeyType) ToPointer() *UpdateKeyType { + return &e +} + +func (e *UpdateKeyType) UnmarshalJSON(data []byte) error { + var v string + if err := json.Unmarshal(data, &v); err != nil { + return err + } + switch v { + case "fast": + fallthrough + case "consistent": + *e = UpdateKeyType(v) + return nil + default: + return fmt.Errorf("invalid value for UpdateKeyType: %v", v) + } +} + +// UpdateKeyRatelimit - Unkey comes with per-key ratelimiting out of the box. Set `null` to disable. +type UpdateKeyRatelimit struct { + // Fast ratelimiting doesn't add latency, while consistent ratelimiting is more accurate. + Type UpdateKeyType `json:"type"` + // The total amount of burstable requests. + Limit int64 `json:"limit"` + // How many tokens to refill during each refillInterval. + RefillRate int64 `json:"refillRate"` + // Determines the speed at which tokens are refilled, in milliseconds. + RefillInterval int64 `json:"refillInterval"` +} + +func (o *UpdateKeyRatelimit) GetType() UpdateKeyType { + if o == nil { + return UpdateKeyType("") + } + return o.Type +} + +func (o *UpdateKeyRatelimit) GetLimit() int64 { + if o == nil { + return 0 + } + return o.Limit +} + +func (o *UpdateKeyRatelimit) GetRefillRate() int64 { + if o == nil { + return 0 + } + return o.RefillRate +} + +func (o *UpdateKeyRatelimit) GetRefillInterval() int64 { + if o == nil { + return 0 + } + return o.RefillInterval +} + +// UpdateKeyInterval - Unkey will automatically refill verifications at the set interval. If null is used the refill functionality will be removed from the key. +type UpdateKeyInterval string + +const ( + UpdateKeyIntervalDaily UpdateKeyInterval = "daily" + UpdateKeyIntervalMonthly UpdateKeyInterval = "monthly" +) + +func (e UpdateKeyInterval) ToPointer() *UpdateKeyInterval { + return &e +} + +func (e *UpdateKeyInterval) UnmarshalJSON(data []byte) error { + var v string + if err := json.Unmarshal(data, &v); err != nil { + return err + } + switch v { + case "daily": + fallthrough + case "monthly": + *e = UpdateKeyInterval(v) + return nil + default: + return fmt.Errorf("invalid value for UpdateKeyInterval: %v", v) + } +} + +// UpdateKeyRefill - Unkey enables you to refill verifications for each key at regular intervals. +type UpdateKeyRefill struct { + // Unkey will automatically refill verifications at the set interval. If null is used the refill functionality will be removed from the key. + Interval UpdateKeyInterval `json:"interval"` + // The amount of verifications to refill for each occurrence is determined individually for each key. + Amount int64 `json:"amount"` +} + +func (o *UpdateKeyRefill) GetInterval() UpdateKeyInterval { + if o == nil { + return UpdateKeyInterval("") + } + return o.Interval +} + +func (o *UpdateKeyRefill) GetAmount() int64 { + if o == nil { + return 0 + } + return o.Amount +} + +type UpdateKeyRequestBody struct { + // The id of the key you want to modify + KeyID string `json:"keyId"` + // The name of the key + Name *string `json:"name,omitempty"` + // The id of the tenant associated with this key. Use whatever reference you have in your system to identify the tenant. When verifying the key, we will send this field back to you, so you know who is accessing your API. + OwnerID *string `json:"ownerId,omitempty"` + // Any additional metadata you want to store with the key + Meta map[string]interface{} `json:"meta,omitempty"` + // The unix timestamp in milliseconds when the key will expire. If this field is null or undefined, the key is not expiring. + Expires *float64 `json:"expires,omitempty"` + // Unkey comes with per-key ratelimiting out of the box. Set `null` to disable. + Ratelimit *UpdateKeyRatelimit `json:"ratelimit,omitempty"` + // The number of requests that can be made with this key before it becomes invalid. Set `null` to disable. + Remaining *float64 `json:"remaining,omitempty"` + // Unkey enables you to refill verifications for each key at regular intervals. + Refill *UpdateKeyRefill `json:"refill,omitempty"` + // Set if key is enabled or disabled. If disabled, the key cannot be used to verify. + Enabled *bool `json:"enabled,omitempty"` +} + +func (o *UpdateKeyRequestBody) GetKeyID() string { + if o == nil { + return "" + } + return o.KeyID +} + +func (o *UpdateKeyRequestBody) GetName() *string { + if o == nil { + return nil + } + return o.Name +} + +func (o *UpdateKeyRequestBody) GetOwnerID() *string { + if o == nil { + return nil + } + return o.OwnerID +} + +func (o *UpdateKeyRequestBody) GetMeta() map[string]interface{} { + if o == nil { + return nil + } + return o.Meta +} + +func (o *UpdateKeyRequestBody) GetExpires() *float64 { + if o == nil { + return nil + } + return o.Expires +} + +func (o *UpdateKeyRequestBody) GetRatelimit() *UpdateKeyRatelimit { + if o == nil { + return nil + } + return o.Ratelimit +} + +func (o *UpdateKeyRequestBody) GetRemaining() *float64 { + if o == nil { + return nil + } + return o.Remaining +} + +func (o *UpdateKeyRequestBody) GetRefill() *UpdateKeyRefill { + if o == nil { + return nil + } + return o.Refill +} + +func (o *UpdateKeyRequestBody) GetEnabled() *bool { + if o == nil { + return nil + } + return o.Enabled +} + +// UpdateKeyResponseBody - The key was successfully updated, it may take up to 30s for this to take effect in all regions +type UpdateKeyResponseBody struct { +} diff --git a/models/operations/updateremaining.go b/models/operations/updateremaining.go new file mode 100644 index 0000000..773aa6d --- /dev/null +++ b/models/operations/updateremaining.go @@ -0,0 +1,82 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package operations + +import ( + "encoding/json" + "fmt" +) + +// Op - The operation you want to perform on the remaining count +type Op string + +const ( + OpIncrement Op = "increment" + OpDecrement Op = "decrement" + OpSet Op = "set" +) + +func (e Op) ToPointer() *Op { + return &e +} + +func (e *Op) UnmarshalJSON(data []byte) error { + var v string + if err := json.Unmarshal(data, &v); err != nil { + return err + } + switch v { + case "increment": + fallthrough + case "decrement": + fallthrough + case "set": + *e = Op(v) + return nil + default: + return fmt.Errorf("invalid value for Op: %v", v) + } +} + +type UpdateRemainingRequestBody struct { + // The id of the key you want to modify + KeyID string `json:"keyId"` + // The operation you want to perform on the remaining count + Op Op `json:"op"` + // The value you want to set, add or subtract the remaining count by + Value *int64 `json:"value"` +} + +func (o *UpdateRemainingRequestBody) GetKeyID() string { + if o == nil { + return "" + } + return o.KeyID +} + +func (o *UpdateRemainingRequestBody) GetOp() Op { + if o == nil { + return Op("") + } + return o.Op +} + +func (o *UpdateRemainingRequestBody) GetValue() *int64 { + if o == nil { + return nil + } + return o.Value +} + +// UpdateRemainingResponseBody - The configuration for an api +type UpdateRemainingResponseBody struct { + // The number of remaining requests for this key after updating it. `null` means unlimited. + Remaining *int64 `json:"remaining"` +} + +func (o *UpdateRemainingResponseBody) GetRemaining() *int64 { + if o == nil { + return nil + } + return o.Remaining +} diff --git a/models/operations/v1liveness.go b/models/operations/v1liveness.go new file mode 100644 index 0000000..40f0e4c --- /dev/null +++ b/models/operations/v1liveness.go @@ -0,0 +1,72 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package operations + +type Services struct { + // The name of the connected metrics service + Metrics string `json:"metrics"` + // The name of the connected logger service + Logger string `json:"logger"` + // The name of the connected ratelimit service + Ratelimit string `json:"ratelimit"` + // The name of the connected usagelimit service + Usagelimit string `json:"usagelimit"` + // The name of the connected analytics service + Analytics string `json:"analytics"` +} + +func (o *Services) GetMetrics() string { + if o == nil { + return "" + } + return o.Metrics +} + +func (o *Services) GetLogger() string { + if o == nil { + return "" + } + return o.Logger +} + +func (o *Services) GetRatelimit() string { + if o == nil { + return "" + } + return o.Ratelimit +} + +func (o *Services) GetUsagelimit() string { + if o == nil { + return "" + } + return o.Usagelimit +} + +func (o *Services) GetAnalytics() string { + if o == nil { + return "" + } + return o.Analytics +} + +// V1LivenessResponseBody - The configured services and their status +type V1LivenessResponseBody struct { + // The status of the server + Status string `json:"status"` + Services Services `json:"services"` +} + +func (o *V1LivenessResponseBody) GetStatus() string { + if o == nil { + return "" + } + return o.Status +} + +func (o *V1LivenessResponseBody) GetServices() Services { + if o == nil { + return Services{} + } + return o.Services +} diff --git a/models/operations/v1migrationscreatekeys.go b/models/operations/v1migrationscreatekeys.go new file mode 100644 index 0000000..408b9b4 --- /dev/null +++ b/models/operations/v1migrationscreatekeys.go @@ -0,0 +1,352 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package operations + +import ( + "encoding/json" + "fmt" + "github.com/unkeyed/unkey-go/internal/utils" +) + +// Variant - The algorithm for hashing and encoding, currently only sha256 and base64 are supported +type Variant string + +const ( + VariantSha256Base64 Variant = "sha256_base64" +) + +func (e Variant) ToPointer() *Variant { + return &e +} + +func (e *Variant) UnmarshalJSON(data []byte) error { + var v string + if err := json.Unmarshal(data, &v); err != nil { + return err + } + switch v { + case "sha256_base64": + *e = Variant(v) + return nil + default: + return fmt.Errorf("invalid value for Variant: %v", v) + } +} + +type Hash struct { + // The hashed and encoded key + Value string `json:"value"` + // The algorithm for hashing and encoding, currently only sha256 and base64 are supported + Variant Variant `json:"variant"` +} + +func (o *Hash) GetValue() string { + if o == nil { + return "" + } + return o.Value +} + +func (o *Hash) GetVariant() Variant { + if o == nil { + return Variant("") + } + return o.Variant +} + +// V1MigrationsCreateKeysInterval - Unkey will automatically refill verifications at the set interval. +type V1MigrationsCreateKeysInterval string + +const ( + V1MigrationsCreateKeysIntervalDaily V1MigrationsCreateKeysInterval = "daily" + V1MigrationsCreateKeysIntervalMonthly V1MigrationsCreateKeysInterval = "monthly" +) + +func (e V1MigrationsCreateKeysInterval) ToPointer() *V1MigrationsCreateKeysInterval { + return &e +} + +func (e *V1MigrationsCreateKeysInterval) UnmarshalJSON(data []byte) error { + var v string + if err := json.Unmarshal(data, &v); err != nil { + return err + } + switch v { + case "daily": + fallthrough + case "monthly": + *e = V1MigrationsCreateKeysInterval(v) + return nil + default: + return fmt.Errorf("invalid value for V1MigrationsCreateKeysInterval: %v", v) + } +} + +// V1MigrationsCreateKeysRefill - Unkey enables you to refill verifications for each key at regular intervals. +type V1MigrationsCreateKeysRefill struct { + // Unkey will automatically refill verifications at the set interval. + Interval V1MigrationsCreateKeysInterval `json:"interval"` + // The number of verifications to refill for each occurrence is determined individually for each key. + Amount int64 `json:"amount"` +} + +func (o *V1MigrationsCreateKeysRefill) GetInterval() V1MigrationsCreateKeysInterval { + if o == nil { + return V1MigrationsCreateKeysInterval("") + } + return o.Interval +} + +func (o *V1MigrationsCreateKeysRefill) GetAmount() int64 { + if o == nil { + return 0 + } + return o.Amount +} + +// V1MigrationsCreateKeysType - Fast ratelimiting doesn't add latency, while consistent ratelimiting is more accurate. +// +// https://unkey.dev/docs/features/ratelimiting - Learn more +type V1MigrationsCreateKeysType string + +const ( + V1MigrationsCreateKeysTypeFast V1MigrationsCreateKeysType = "fast" + V1MigrationsCreateKeysTypeConsistent V1MigrationsCreateKeysType = "consistent" +) + +func (e V1MigrationsCreateKeysType) ToPointer() *V1MigrationsCreateKeysType { + return &e +} + +func (e *V1MigrationsCreateKeysType) UnmarshalJSON(data []byte) error { + var v string + if err := json.Unmarshal(data, &v); err != nil { + return err + } + switch v { + case "fast": + fallthrough + case "consistent": + *e = V1MigrationsCreateKeysType(v) + return nil + default: + return fmt.Errorf("invalid value for V1MigrationsCreateKeysType: %v", v) + } +} + +// V1MigrationsCreateKeysRatelimit - Unkey comes with per-key ratelimiting out of the box. +type V1MigrationsCreateKeysRatelimit struct { + // Fast ratelimiting doesn't add latency, while consistent ratelimiting is more accurate. + Type *V1MigrationsCreateKeysType `default:"fast" json:"type"` + // The total amount of burstable requests. + Limit int64 `json:"limit"` + // How many tokens to refill during each refillInterval. + RefillRate int64 `json:"refillRate"` + // Determines the speed at which tokens are refilled, in milliseconds. + RefillInterval int64 `json:"refillInterval"` +} + +func (v V1MigrationsCreateKeysRatelimit) MarshalJSON() ([]byte, error) { + return utils.MarshalJSON(v, "", false) +} + +func (v *V1MigrationsCreateKeysRatelimit) UnmarshalJSON(data []byte) error { + if err := utils.UnmarshalJSON(data, &v, "", false, false); err != nil { + return err + } + return nil +} + +func (o *V1MigrationsCreateKeysRatelimit) GetType() *V1MigrationsCreateKeysType { + if o == nil { + return nil + } + return o.Type +} + +func (o *V1MigrationsCreateKeysRatelimit) GetLimit() int64 { + if o == nil { + return 0 + } + return o.Limit +} + +func (o *V1MigrationsCreateKeysRatelimit) GetRefillRate() int64 { + if o == nil { + return 0 + } + return o.RefillRate +} + +func (o *V1MigrationsCreateKeysRatelimit) GetRefillInterval() int64 { + if o == nil { + return 0 + } + return o.RefillInterval +} + +type RequestBody struct { + // Choose an `API` where this key should be created. + APIID string `json:"apiId"` + // To make it easier for your users to understand which product an api key belongs to, you can add prefix them. + // + // For example Stripe famously prefixes their customer ids with cus_ or their api keys with sk_live_. + // + // The underscore is automatically added if you are defining a prefix, for example: "prefix": "abc" will result in a key like abc_xxxxxxxxx + // + Prefix *string `json:"prefix,omitempty"` + // The name for your Key. This is not customer facing. + Name *string `json:"name,omitempty"` + Hash Hash `json:"hash"` + // The first 4 characters of the key. If a prefix is used, it should be the prefix plus 4 characters. + Start *string `default:"" json:"start"` + // Your user’s Id. This will provide a link between Unkey and your customer record. + // When validating a key, we will return this back to you, so you can clearly identify your user from their api key. + OwnerID *string `json:"ownerId,omitempty"` + // This is a place for dynamic meta data, anything that feels useful for you should go here + Meta map[string]interface{} `json:"meta,omitempty"` + // A list of roles that this key should have. If the role does not exist, an error is thrown + Roles []string `json:"roles,omitempty"` + // You can auto expire keys by providing a unix timestamp in milliseconds. Once Keys expire they will automatically be disabled and are no longer valid unless you enable them again. + Expires *int64 `json:"expires,omitempty"` + // You can limit the number of requests a key can make. Once a key reaches 0 remaining requests, it will automatically be disabled and is no longer valid unless you update it. + Remaining *int64 `json:"remaining,omitempty"` + // Unkey enables you to refill verifications for each key at regular intervals. + Refill *V1MigrationsCreateKeysRefill `json:"refill,omitempty"` + // Unkey comes with per-key ratelimiting out of the box. + Ratelimit *V1MigrationsCreateKeysRatelimit `json:"ratelimit,omitempty"` + // Sets if key is enabled or disabled. Disabled keys are not valid. + Enabled *bool `default:"true" json:"enabled"` + // Environments allow you to divide your keyspace. + // + // Some applications like Stripe, Clerk, WorkOS and others have a concept of "live" and "test" keys to + // give the developer a way to develop their own application without the risk of modifying real world + // resources. + // + // When you set an environment, we will return it back to you when validating the key, so you can + // handle it correctly. + // + Environment *string `json:"environment,omitempty"` +} + +func (r RequestBody) MarshalJSON() ([]byte, error) { + return utils.MarshalJSON(r, "", false) +} + +func (r *RequestBody) UnmarshalJSON(data []byte) error { + if err := utils.UnmarshalJSON(data, &r, "", false, false); err != nil { + return err + } + return nil +} + +func (o *RequestBody) GetAPIID() string { + if o == nil { + return "" + } + return o.APIID +} + +func (o *RequestBody) GetPrefix() *string { + if o == nil { + return nil + } + return o.Prefix +} + +func (o *RequestBody) GetName() *string { + if o == nil { + return nil + } + return o.Name +} + +func (o *RequestBody) GetHash() Hash { + if o == nil { + return Hash{} + } + return o.Hash +} + +func (o *RequestBody) GetStart() *string { + if o == nil { + return nil + } + return o.Start +} + +func (o *RequestBody) GetOwnerID() *string { + if o == nil { + return nil + } + return o.OwnerID +} + +func (o *RequestBody) GetMeta() map[string]interface{} { + if o == nil { + return nil + } + return o.Meta +} + +func (o *RequestBody) GetRoles() []string { + if o == nil { + return nil + } + return o.Roles +} + +func (o *RequestBody) GetExpires() *int64 { + if o == nil { + return nil + } + return o.Expires +} + +func (o *RequestBody) GetRemaining() *int64 { + if o == nil { + return nil + } + return o.Remaining +} + +func (o *RequestBody) GetRefill() *V1MigrationsCreateKeysRefill { + if o == nil { + return nil + } + return o.Refill +} + +func (o *RequestBody) GetRatelimit() *V1MigrationsCreateKeysRatelimit { + if o == nil { + return nil + } + return o.Ratelimit +} + +func (o *RequestBody) GetEnabled() *bool { + if o == nil { + return nil + } + return o.Enabled +} + +func (o *RequestBody) GetEnvironment() *string { + if o == nil { + return nil + } + return o.Environment +} + +// V1MigrationsCreateKeysResponseBody - The key ids of all created keys +type V1MigrationsCreateKeysResponseBody struct { + // The ids of the keys. This is not a secret and can be stored as a reference if you wish. You need the keyId to update or delete a key later. + KeyIds []string `json:"keyIds"` +} + +func (o *V1MigrationsCreateKeysResponseBody) GetKeyIds() []string { + if o == nil { + return []string{} + } + return o.KeyIds +} diff --git a/models/sdkerrors/errbadrequest.go b/models/sdkerrors/errbadrequest.go new file mode 100644 index 0000000..15911fd --- /dev/null +++ b/models/sdkerrors/errbadrequest.go @@ -0,0 +1,84 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package sdkerrors + +import ( + "encoding/json" + "fmt" +) + +// Code - A machine readable error code. +type Code string + +const ( + CodeBadRequest Code = "BAD_REQUEST" +) + +func (e Code) ToPointer() *Code { + return &e +} + +func (e *Code) UnmarshalJSON(data []byte) error { + var v string + if err := json.Unmarshal(data, &v); err != nil { + return err + } + switch v { + case "BAD_REQUEST": + *e = Code(v) + return nil + default: + return fmt.Errorf("invalid value for Code: %v", v) + } +} + +type Error struct { + // A machine readable error code. + Code Code `json:"code"` + // A link to our documentation with more details about this error code + Docs string `json:"docs"` + // A human readable explanation of what went wrong + Message string `json:"message"` + // Please always include the requestId in your error report + RequestID string `json:"requestId"` +} + +func (o *Error) GetCode() Code { + if o == nil { + return Code("") + } + return o.Code +} + +func (o *Error) GetDocs() string { + if o == nil { + return "" + } + return o.Docs +} + +func (o *Error) GetMessage() string { + if o == nil { + return "" + } + return o.Message +} + +func (o *Error) GetRequestID() string { + if o == nil { + return "" + } + return o.RequestID +} + +// ErrBadRequest - The server cannot or will not process the request due to something that is perceived to be a client error (e.g., malformed request syntax, invalid request message framing, or deceptive request routing). +type ErrBadRequest struct { + Error_ Error `json:"error"` +} + +var _ error = &ErrBadRequest{} + +func (e *ErrBadRequest) Error() string { + data, _ := json.Marshal(e) + return string(data) +} diff --git a/models/sdkerrors/errconflict.go b/models/sdkerrors/errconflict.go new file mode 100644 index 0000000..d9c38a0 --- /dev/null +++ b/models/sdkerrors/errconflict.go @@ -0,0 +1,84 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package sdkerrors + +import ( + "encoding/json" + "fmt" +) + +// ErrConflictCode - A machine readable error code. +type ErrConflictCode string + +const ( + ErrConflictCodeConflict ErrConflictCode = "CONFLICT" +) + +func (e ErrConflictCode) ToPointer() *ErrConflictCode { + return &e +} + +func (e *ErrConflictCode) UnmarshalJSON(data []byte) error { + var v string + if err := json.Unmarshal(data, &v); err != nil { + return err + } + switch v { + case "CONFLICT": + *e = ErrConflictCode(v) + return nil + default: + return fmt.Errorf("invalid value for ErrConflictCode: %v", v) + } +} + +type ErrConflictError struct { + // A machine readable error code. + Code ErrConflictCode `json:"code"` + // A link to our documentation with more details about this error code + Docs string `json:"docs"` + // A human readable explanation of what went wrong + Message string `json:"message"` + // Please always include the requestId in your error report + RequestID string `json:"requestId"` +} + +func (o *ErrConflictError) GetCode() ErrConflictCode { + if o == nil { + return ErrConflictCode("") + } + return o.Code +} + +func (o *ErrConflictError) GetDocs() string { + if o == nil { + return "" + } + return o.Docs +} + +func (o *ErrConflictError) GetMessage() string { + if o == nil { + return "" + } + return o.Message +} + +func (o *ErrConflictError) GetRequestID() string { + if o == nil { + return "" + } + return o.RequestID +} + +// ErrConflict - This response is sent when a request conflicts with the current state of the server. +type ErrConflict struct { + Error_ ErrConflictError `json:"error"` +} + +var _ error = &ErrConflict{} + +func (e *ErrConflict) Error() string { + data, _ := json.Marshal(e) + return string(data) +} diff --git a/models/sdkerrors/errforbidden.go b/models/sdkerrors/errforbidden.go new file mode 100644 index 0000000..7e6d662 --- /dev/null +++ b/models/sdkerrors/errforbidden.go @@ -0,0 +1,84 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package sdkerrors + +import ( + "encoding/json" + "fmt" +) + +// ErrForbiddenCode - A machine readable error code. +type ErrForbiddenCode string + +const ( + ErrForbiddenCodeForbidden ErrForbiddenCode = "FORBIDDEN" +) + +func (e ErrForbiddenCode) ToPointer() *ErrForbiddenCode { + return &e +} + +func (e *ErrForbiddenCode) UnmarshalJSON(data []byte) error { + var v string + if err := json.Unmarshal(data, &v); err != nil { + return err + } + switch v { + case "FORBIDDEN": + *e = ErrForbiddenCode(v) + return nil + default: + return fmt.Errorf("invalid value for ErrForbiddenCode: %v", v) + } +} + +type ErrForbiddenError struct { + // A machine readable error code. + Code ErrForbiddenCode `json:"code"` + // A link to our documentation with more details about this error code + Docs string `json:"docs"` + // A human readable explanation of what went wrong + Message string `json:"message"` + // Please always include the requestId in your error report + RequestID string `json:"requestId"` +} + +func (o *ErrForbiddenError) GetCode() ErrForbiddenCode { + if o == nil { + return ErrForbiddenCode("") + } + return o.Code +} + +func (o *ErrForbiddenError) GetDocs() string { + if o == nil { + return "" + } + return o.Docs +} + +func (o *ErrForbiddenError) GetMessage() string { + if o == nil { + return "" + } + return o.Message +} + +func (o *ErrForbiddenError) GetRequestID() string { + if o == nil { + return "" + } + return o.RequestID +} + +// ErrForbidden - The client does not have access rights to the content; that is, it is unauthorized, so the server is refusing to give the requested resource. Unlike 401 Unauthorized, the client's identity is known to the server. +type ErrForbidden struct { + Error_ ErrForbiddenError `json:"error"` +} + +var _ error = &ErrForbidden{} + +func (e *ErrForbidden) Error() string { + data, _ := json.Marshal(e) + return string(data) +} diff --git a/models/sdkerrors/errinternalservererror.go b/models/sdkerrors/errinternalservererror.go new file mode 100644 index 0000000..98c1062 --- /dev/null +++ b/models/sdkerrors/errinternalservererror.go @@ -0,0 +1,84 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package sdkerrors + +import ( + "encoding/json" + "fmt" +) + +// ErrInternalServerErrorCode - A machine readable error code. +type ErrInternalServerErrorCode string + +const ( + ErrInternalServerErrorCodeInternalServerError ErrInternalServerErrorCode = "INTERNAL_SERVER_ERROR" +) + +func (e ErrInternalServerErrorCode) ToPointer() *ErrInternalServerErrorCode { + return &e +} + +func (e *ErrInternalServerErrorCode) UnmarshalJSON(data []byte) error { + var v string + if err := json.Unmarshal(data, &v); err != nil { + return err + } + switch v { + case "INTERNAL_SERVER_ERROR": + *e = ErrInternalServerErrorCode(v) + return nil + default: + return fmt.Errorf("invalid value for ErrInternalServerErrorCode: %v", v) + } +} + +type ErrInternalServerErrorError struct { + // A machine readable error code. + Code ErrInternalServerErrorCode `json:"code"` + // A link to our documentation with more details about this error code + Docs string `json:"docs"` + // A human readable explanation of what went wrong + Message string `json:"message"` + // Please always include the requestId in your error report + RequestID string `json:"requestId"` +} + +func (o *ErrInternalServerErrorError) GetCode() ErrInternalServerErrorCode { + if o == nil { + return ErrInternalServerErrorCode("") + } + return o.Code +} + +func (o *ErrInternalServerErrorError) GetDocs() string { + if o == nil { + return "" + } + return o.Docs +} + +func (o *ErrInternalServerErrorError) GetMessage() string { + if o == nil { + return "" + } + return o.Message +} + +func (o *ErrInternalServerErrorError) GetRequestID() string { + if o == nil { + return "" + } + return o.RequestID +} + +// ErrInternalServerError - The server has encountered a situation it does not know how to handle. +type ErrInternalServerError struct { + Error_ ErrInternalServerErrorError `json:"error"` +} + +var _ error = &ErrInternalServerError{} + +func (e *ErrInternalServerError) Error() string { + data, _ := json.Marshal(e) + return string(data) +} diff --git a/models/sdkerrors/errnotfound.go b/models/sdkerrors/errnotfound.go new file mode 100644 index 0000000..c654128 --- /dev/null +++ b/models/sdkerrors/errnotfound.go @@ -0,0 +1,84 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package sdkerrors + +import ( + "encoding/json" + "fmt" +) + +// ErrNotFoundCode - A machine readable error code. +type ErrNotFoundCode string + +const ( + ErrNotFoundCodeNotFound ErrNotFoundCode = "NOT_FOUND" +) + +func (e ErrNotFoundCode) ToPointer() *ErrNotFoundCode { + return &e +} + +func (e *ErrNotFoundCode) UnmarshalJSON(data []byte) error { + var v string + if err := json.Unmarshal(data, &v); err != nil { + return err + } + switch v { + case "NOT_FOUND": + *e = ErrNotFoundCode(v) + return nil + default: + return fmt.Errorf("invalid value for ErrNotFoundCode: %v", v) + } +} + +type ErrNotFoundError struct { + // A machine readable error code. + Code ErrNotFoundCode `json:"code"` + // A link to our documentation with more details about this error code + Docs string `json:"docs"` + // A human readable explanation of what went wrong + Message string `json:"message"` + // Please always include the requestId in your error report + RequestID string `json:"requestId"` +} + +func (o *ErrNotFoundError) GetCode() ErrNotFoundCode { + if o == nil { + return ErrNotFoundCode("") + } + return o.Code +} + +func (o *ErrNotFoundError) GetDocs() string { + if o == nil { + return "" + } + return o.Docs +} + +func (o *ErrNotFoundError) GetMessage() string { + if o == nil { + return "" + } + return o.Message +} + +func (o *ErrNotFoundError) GetRequestID() string { + if o == nil { + return "" + } + return o.RequestID +} + +// ErrNotFound - The server cannot find the requested resource. In the browser, this means the URL is not recognized. In an API, this can also mean that the endpoint is valid but the resource itself does not exist. Servers may also send this response instead of 403 Forbidden to hide the existence of a resource from an unauthorized client. This response code is probably the most well known due to its frequent occurrence on the web. +type ErrNotFound struct { + Error_ ErrNotFoundError `json:"error"` +} + +var _ error = &ErrNotFound{} + +func (e *ErrNotFound) Error() string { + data, _ := json.Marshal(e) + return string(data) +} diff --git a/models/sdkerrors/errtoomanyrequests.go b/models/sdkerrors/errtoomanyrequests.go new file mode 100644 index 0000000..12aede8 --- /dev/null +++ b/models/sdkerrors/errtoomanyrequests.go @@ -0,0 +1,84 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package sdkerrors + +import ( + "encoding/json" + "fmt" +) + +// ErrTooManyRequestsCode - A machine readable error code. +type ErrTooManyRequestsCode string + +const ( + ErrTooManyRequestsCodeTooManyRequests ErrTooManyRequestsCode = "TOO_MANY_REQUESTS" +) + +func (e ErrTooManyRequestsCode) ToPointer() *ErrTooManyRequestsCode { + return &e +} + +func (e *ErrTooManyRequestsCode) UnmarshalJSON(data []byte) error { + var v string + if err := json.Unmarshal(data, &v); err != nil { + return err + } + switch v { + case "TOO_MANY_REQUESTS": + *e = ErrTooManyRequestsCode(v) + return nil + default: + return fmt.Errorf("invalid value for ErrTooManyRequestsCode: %v", v) + } +} + +type ErrTooManyRequestsError struct { + // A machine readable error code. + Code ErrTooManyRequestsCode `json:"code"` + // A link to our documentation with more details about this error code + Docs string `json:"docs"` + // A human readable explanation of what went wrong + Message string `json:"message"` + // Please always include the requestId in your error report + RequestID string `json:"requestId"` +} + +func (o *ErrTooManyRequestsError) GetCode() ErrTooManyRequestsCode { + if o == nil { + return ErrTooManyRequestsCode("") + } + return o.Code +} + +func (o *ErrTooManyRequestsError) GetDocs() string { + if o == nil { + return "" + } + return o.Docs +} + +func (o *ErrTooManyRequestsError) GetMessage() string { + if o == nil { + return "" + } + return o.Message +} + +func (o *ErrTooManyRequestsError) GetRequestID() string { + if o == nil { + return "" + } + return o.RequestID +} + +// ErrTooManyRequests - The user has sent too many requests in a given amount of time ("rate limiting") +type ErrTooManyRequests struct { + Error_ ErrTooManyRequestsError `json:"error"` +} + +var _ error = &ErrTooManyRequests{} + +func (e *ErrTooManyRequests) Error() string { + data, _ := json.Marshal(e) + return string(data) +} diff --git a/models/sdkerrors/errunauthorized.go b/models/sdkerrors/errunauthorized.go new file mode 100644 index 0000000..cb76100 --- /dev/null +++ b/models/sdkerrors/errunauthorized.go @@ -0,0 +1,84 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package sdkerrors + +import ( + "encoding/json" + "fmt" +) + +// ErrUnauthorizedCode - A machine readable error code. +type ErrUnauthorizedCode string + +const ( + ErrUnauthorizedCodeUnauthorized ErrUnauthorizedCode = "UNAUTHORIZED" +) + +func (e ErrUnauthorizedCode) ToPointer() *ErrUnauthorizedCode { + return &e +} + +func (e *ErrUnauthorizedCode) UnmarshalJSON(data []byte) error { + var v string + if err := json.Unmarshal(data, &v); err != nil { + return err + } + switch v { + case "UNAUTHORIZED": + *e = ErrUnauthorizedCode(v) + return nil + default: + return fmt.Errorf("invalid value for ErrUnauthorizedCode: %v", v) + } +} + +type ErrUnauthorizedError struct { + // A machine readable error code. + Code ErrUnauthorizedCode `json:"code"` + // A link to our documentation with more details about this error code + Docs string `json:"docs"` + // A human readable explanation of what went wrong + Message string `json:"message"` + // Please always include the requestId in your error report + RequestID string `json:"requestId"` +} + +func (o *ErrUnauthorizedError) GetCode() ErrUnauthorizedCode { + if o == nil { + return ErrUnauthorizedCode("") + } + return o.Code +} + +func (o *ErrUnauthorizedError) GetDocs() string { + if o == nil { + return "" + } + return o.Docs +} + +func (o *ErrUnauthorizedError) GetMessage() string { + if o == nil { + return "" + } + return o.Message +} + +func (o *ErrUnauthorizedError) GetRequestID() string { + if o == nil { + return "" + } + return o.RequestID +} + +// ErrUnauthorized - Although the HTTP standard specifies "unauthorized", semantically this response means "unauthenticated". That is, the client must authenticate itself to get the requested response. +type ErrUnauthorized struct { + Error_ ErrUnauthorizedError `json:"error"` +} + +var _ error = &ErrUnauthorized{} + +func (e *ErrUnauthorized) Error() string { + data, _ := json.Marshal(e) + return string(data) +} diff --git a/models/sdkerrors/sdkerror.go b/models/sdkerrors/sdkerror.go new file mode 100644 index 0000000..5c1affd --- /dev/null +++ b/models/sdkerrors/sdkerror.go @@ -0,0 +1,35 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package sdkerrors + +import ( + "fmt" + "net/http" +) + +type SDKError struct { + Message string + StatusCode int + Body string + RawResponse *http.Response +} + +var _ error = &SDKError{} + +func NewSDKError(message string, statusCode int, body string, httpRes *http.Response) *SDKError { + return &SDKError{ + Message: message, + StatusCode: statusCode, + Body: body, + RawResponse: httpRes, + } +} + +func (e *SDKError) Error() string { + body := "" + if len(e.Body) > 0 { + body = fmt.Sprintf("\n%s", e.Body) + } + + return fmt.Sprintf("%s: Status %d%s", e.Message, e.StatusCode, body) +} diff --git a/ratelimits.go b/ratelimits.go new file mode 100644 index 0000000..71cd4d3 --- /dev/null +++ b/ratelimits.go @@ -0,0 +1,199 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package unkeygo + +import ( + "bytes" + "context" + "fmt" + "github.com/unkeyed/unkey-go/internal/hooks" + "github.com/unkeyed/unkey-go/internal/utils" + "github.com/unkeyed/unkey-go/models/operations" + "github.com/unkeyed/unkey-go/models/sdkerrors" + "io" + "net/http" + "net/url" +) + +type Ratelimits struct { + sdkConfiguration sdkConfiguration +} + +func newRatelimits(sdkConfig sdkConfiguration) *Ratelimits { + return &Ratelimits{ + sdkConfiguration: sdkConfig, + } +} + +func (s *Ratelimits) Limit(ctx context.Context, request operations.LimitRequestBody) (*operations.LimitResponseBody, error) { + hookCtx := hooks.HookContext{ + Context: ctx, + OperationID: "limit", + OAuth2Scopes: []string{}, + SecuritySource: s.sdkConfiguration.Security, + } + + baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) + opURL, err := url.JoinPath(baseURL, "/v1/ratelimits.limit") + if err != nil { + return nil, fmt.Errorf("error generating URL: %w", err) + } + + bodyReader, reqContentType, err := utils.SerializeRequestBody(ctx, request, false, false, "Request", "json", `request:"mediaType=application/json"`) + if err != nil { + return nil, err + } + + req, err := http.NewRequestWithContext(ctx, "POST", opURL, bodyReader) + if err != nil { + return nil, fmt.Errorf("error creating request: %w", err) + } + req.Header.Set("Accept", "application/json") + req.Header.Set("User-Agent", s.sdkConfiguration.UserAgent) + req.Header.Set("Content-Type", reqContentType) + + if err := utils.PopulateSecurity(ctx, req, s.sdkConfiguration.Security); err != nil { + return nil, err + } + + req, err = s.sdkConfiguration.Hooks.BeforeRequest(hooks.BeforeRequestContext{HookContext: hookCtx}, req) + if err != nil { + return nil, err + } + + httpRes, err := s.sdkConfiguration.Client.Do(req) + if err != nil || httpRes == nil { + if err != nil { + err = fmt.Errorf("error sending request: %w", err) + } else { + err = fmt.Errorf("error sending request: no response") + } + + _, err = s.sdkConfiguration.Hooks.AfterError(hooks.AfterErrorContext{HookContext: hookCtx}, nil, err) + return nil, err + } else if utils.MatchStatusCodes([]string{"400", "401", "403", "404", "409", "429", "4XX", "500", "5XX"}, httpRes.StatusCode) { + _httpRes, err := s.sdkConfiguration.Hooks.AfterError(hooks.AfterErrorContext{HookContext: hookCtx}, httpRes, nil) + if err != nil { + return nil, err + } else if _httpRes != nil { + httpRes = _httpRes + } + } else { + httpRes, err = s.sdkConfiguration.Hooks.AfterSuccess(hooks.AfterSuccessContext{HookContext: hookCtx}, httpRes) + if err != nil { + return nil, err + } + } + + rawBody, err := io.ReadAll(httpRes.Body) + if err != nil { + return nil, fmt.Errorf("error reading response body: %w", err) + } + httpRes.Body.Close() + httpRes.Body = io.NopCloser(bytes.NewBuffer(rawBody)) + + switch { + case httpRes.StatusCode == 200: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out operations.LimitResponseBody + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return &out, nil + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 400: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrBadRequest + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 401: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrUnauthorized + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 403: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrForbidden + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 404: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrNotFound + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 409: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrConflict + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 429: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrTooManyRequests + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode >= 400 && httpRes.StatusCode < 500: + fallthrough + case httpRes.StatusCode >= 500 && httpRes.StatusCode < 600: + return nil, sdkerrors.NewSDKError("API error occurred", httpRes.StatusCode, string(rawBody), httpRes) + case httpRes.StatusCode == 500: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrInternalServerError + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + default: + return nil, sdkerrors.NewSDKError("unknown status code returned", httpRes.StatusCode, string(rawBody), httpRes) + } +} diff --git a/types/bigint.go b/types/bigint.go new file mode 100644 index 0000000..afd0cd2 --- /dev/null +++ b/types/bigint.go @@ -0,0 +1,21 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package types + +import ( + "fmt" + "math/big" +) + +// MustNewBigIntFromString returns an instance of big.Int from a string +// The string is assumed to be base 10 and if it is not a valid big.Int +// then the function panics. +// Avoid using this function in production code. +func MustNewBigIntFromString(s string) *big.Int { + i, ok := new(big.Int).SetString(s, 10) + if !ok { + panic(fmt.Errorf("failed to parse string as big.Int")) + } + + return i +} diff --git a/types/date.go b/types/date.go new file mode 100644 index 0000000..c4648fa --- /dev/null +++ b/types/date.go @@ -0,0 +1,90 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package types + +import ( + "encoding/json" + "fmt" + "strings" + "time" +) + +// Date is a wrapper around time.Time that allows for JSON marshaling a date string formatted as "2006-01-02". +type Date struct { + time.Time +} + +var ( + _ json.Marshaler = &Date{} + _ json.Unmarshaler = &Date{} + _ fmt.Stringer = &Date{} +) + +// NewDate returns an instance of Date from a time.Time. +func NewDate(t time.Time) *Date { + d := DateFromTime(t) + return &d +} + +// DateFromTime returns a Date from a time.Time. +func DateFromTime(t time.Time) Date { + return Date{t} +} + +// NewDateFromString returns an instance of Date from a string formatted as "2006-01-02". +func NewDateFromString(str string) (*Date, error) { + d, err := DateFromString(str) + if err != nil { + return nil, err + } + + return &d, nil +} + +// DateFromString returns a Date from a string formatted as "2006-01-02". +func DateFromString(str string) (Date, error) { + var d Date + var err error + + d.Time, err = time.Parse("2006-01-02", str) + return d, err +} + +// MustNewDateFromString returns an instance of Date from a string formatted as "2006-01-02" or panics. +// Avoid using this function in production code. +func MustNewDateFromString(str string) *Date { + d := MustDateFromString(str) + return &d +} + +// MustDateFromString returns a Date from a string formatted as "2006-01-02" or panics. +// Avoid using this function in production code. +func MustDateFromString(str string) Date { + d, err := DateFromString(str) + if err != nil { + panic(err) + } + return d +} + +func (d Date) GetTime() time.Time { + return d.Time +} + +func (d Date) MarshalJSON() ([]byte, error) { + return []byte(fmt.Sprintf(`"%s"`, d.Time.Format("2006-01-02"))), nil +} + +func (d *Date) UnmarshalJSON(data []byte) error { + var err error + + str := string(data) + str = strings.Trim(str, `"`) + + d.Time, err = time.Parse("2006-01-02", str) + return err +} + +func (d Date) String() string { + return d.Time.Format("2006-01-02") +} diff --git a/types/datetime.go b/types/datetime.go new file mode 100644 index 0000000..0529b25 --- /dev/null +++ b/types/datetime.go @@ -0,0 +1,23 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package types + +import "time" + +// MustTimeFromString returns a time.Time from a string formatted as "2006-01-02T15:04:05Z07:00" or panics. +// Avoid using this function in production code. +func MustTimeFromString(str string) time.Time { + t, err := time.Parse(time.RFC3339, str) + if err != nil { + panic(err) + } + + return t +} + +// MustNewTimeFromString returns an instance of time.Time from a string formatted as "2006-01-02T15:04:05Z07:00" or panics. +// Avoid using this function in production code. +func MustNewTimeFromString(str string) *time.Time { + t := MustTimeFromString(str) + return &t +} diff --git a/types/decimal.go b/types/decimal.go new file mode 100644 index 0000000..a42284b --- /dev/null +++ b/types/decimal.go @@ -0,0 +1,20 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package types + +import ( + "fmt" + + "github.com/ericlagergren/decimal" +) + +// MustNewDecimalFromString returns an instance of Decimal from a string +// Avoid using this function in production code. +func MustNewDecimalFromString(s string) *decimal.Big { + d, ok := new(decimal.Big).SetString(s) + if !ok { + panic(fmt.Errorf("failed to parse string as decimal.Big")) + } + + return d +} diff --git a/types/pointers.go b/types/pointers.go new file mode 100644 index 0000000..4f15e99 --- /dev/null +++ b/types/pointers.go @@ -0,0 +1,10 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package types + +func String(s string) *string { return &s } +func Bool(b bool) *bool { return &b } +func Int(i int) *int { return &i } +func Int64(i int64) *int64 { return &i } +func Float32(f float32) *float32 { return &f } +func Float64(f float64) *float64 { return &f } diff --git a/unkey.go b/unkey.go new file mode 100644 index 0000000..653c82e --- /dev/null +++ b/unkey.go @@ -0,0 +1,1053 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package unkeygo + +import ( + "bytes" + "context" + "fmt" + "github.com/unkeyed/unkey-go/internal/hooks" + "github.com/unkeyed/unkey-go/internal/utils" + "github.com/unkeyed/unkey-go/models/components" + "github.com/unkeyed/unkey-go/models/operations" + "github.com/unkeyed/unkey-go/models/sdkerrors" + "io" + "net/http" + "net/url" + "time" +) + +// ServerList contains the list of servers available to the SDK +var ServerList = []string{ + // Production + "https://api.unkey.dev", +} + +// HTTPClient provides an interface for suplying the SDK with a custom HTTP client +type HTTPClient interface { + Do(req *http.Request) (*http.Response, error) +} + +// String provides a helper function to return a pointer to a string +func String(s string) *string { return &s } + +// Bool provides a helper function to return a pointer to a bool +func Bool(b bool) *bool { return &b } + +// Int provides a helper function to return a pointer to an int +func Int(i int) *int { return &i } + +// Int64 provides a helper function to return a pointer to an int64 +func Int64(i int64) *int64 { return &i } + +// Float32 provides a helper function to return a pointer to a float32 +func Float32(f float32) *float32 { return &f } + +// Float64 provides a helper function to return a pointer to a float64 +func Float64(f float64) *float64 { return &f } + +type sdkConfiguration struct { + Client HTTPClient + Security func(context.Context) (interface{}, error) + ServerURL string + ServerIndex int + Language string + OpenAPIDocVersion string + SDKVersion string + GenVersion string + UserAgent string + RetryConfig *utils.RetryConfig + Hooks *hooks.Hooks +} + +func (c *sdkConfiguration) GetServerDetails() (string, map[string]string) { + if c.ServerURL != "" { + return c.ServerURL, nil + } + + return ServerList[c.ServerIndex], nil +} + +type Unkey struct { + Liveness *Liveness + Keys *Keys + Apis *Apis + Ratelimits *Ratelimits + Migrations *Migrations + + sdkConfiguration sdkConfiguration +} + +type SDKOption func(*Unkey) + +// WithServerURL allows the overriding of the default server URL +func WithServerURL(serverURL string) SDKOption { + return func(sdk *Unkey) { + sdk.sdkConfiguration.ServerURL = serverURL + } +} + +// WithTemplatedServerURL allows the overriding of the default server URL with a templated URL populated with the provided parameters +func WithTemplatedServerURL(serverURL string, params map[string]string) SDKOption { + return func(sdk *Unkey) { + if params != nil { + serverURL = utils.ReplaceParameters(serverURL, params) + } + + sdk.sdkConfiguration.ServerURL = serverURL + } +} + +// WithServerIndex allows the overriding of the default server by index +func WithServerIndex(serverIndex int) SDKOption { + return func(sdk *Unkey) { + if serverIndex < 0 || serverIndex >= len(ServerList) { + panic(fmt.Errorf("server index %d out of range", serverIndex)) + } + + sdk.sdkConfiguration.ServerIndex = serverIndex + } +} + +// WithClient allows the overriding of the default HTTP client used by the SDK +func WithClient(client HTTPClient) SDKOption { + return func(sdk *Unkey) { + sdk.sdkConfiguration.Client = client + } +} + +func withSecurity(security interface{}) func(context.Context) (interface{}, error) { + return func(context.Context) (interface{}, error) { + return security, nil + } +} + +// WithSecurity configures the SDK to use the provided security details +func WithSecurity(bearerAuth string) SDKOption { + return func(sdk *Unkey) { + security := components.Security{BearerAuth: &bearerAuth} + sdk.sdkConfiguration.Security = withSecurity(&security) + } +} + +// WithSecuritySource configures the SDK to invoke the Security Source function on each method call to determine authentication +func WithSecuritySource(security func(context.Context) (components.Security, error)) SDKOption { + return func(sdk *Unkey) { + sdk.sdkConfiguration.Security = func(ctx context.Context) (interface{}, error) { + return security(ctx) + } + } +} + +func WithRetryConfig(retryConfig utils.RetryConfig) SDKOption { + return func(sdk *Unkey) { + sdk.sdkConfiguration.RetryConfig = &retryConfig + } +} + +// New creates a new instance of the SDK with the provided options +func New(opts ...SDKOption) *Unkey { + sdk := &Unkey{ + sdkConfiguration: sdkConfiguration{ + Language: "go", + OpenAPIDocVersion: "1.0.0", + SDKVersion: "0.1.2", + GenVersion: "2.326.3", + UserAgent: "speakeasy-sdk/go 0.1.2 2.326.3 1.0.0 github.com/unkeyed/unkey-go", + Hooks: hooks.New(), + }, + } + for _, opt := range opts { + opt(sdk) + } + + // Use WithClient to override the default client if you would like to customize the timeout + if sdk.sdkConfiguration.Client == nil { + sdk.sdkConfiguration.Client = &http.Client{Timeout: 60 * time.Second} + } + + currentServerURL, _ := sdk.sdkConfiguration.GetServerDetails() + serverURL := currentServerURL + serverURL, sdk.sdkConfiguration.Client = sdk.sdkConfiguration.Hooks.SDKInit(currentServerURL, sdk.sdkConfiguration.Client) + if serverURL != currentServerURL { + sdk.sdkConfiguration.ServerURL = serverURL + } + + sdk.Liveness = newLiveness(sdk.sdkConfiguration) + + sdk.Keys = newKeys(sdk.sdkConfiguration) + + sdk.Apis = newApis(sdk.sdkConfiguration) + + sdk.Ratelimits = newRatelimits(sdk.sdkConfiguration) + + sdk.Migrations = newMigrations(sdk.sdkConfiguration) + + return sdk +} + +func (s *Unkey) CreateAPI(ctx context.Context, request operations.CreateAPIRequestBody) (*operations.CreateAPIResponseBody, error) { + hookCtx := hooks.HookContext{ + Context: ctx, + OperationID: "createApi", + OAuth2Scopes: []string{}, + SecuritySource: s.sdkConfiguration.Security, + } + + baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) + opURL, err := url.JoinPath(baseURL, "/v1/apis.createApi") + if err != nil { + return nil, fmt.Errorf("error generating URL: %w", err) + } + + bodyReader, reqContentType, err := utils.SerializeRequestBody(ctx, request, false, false, "Request", "json", `request:"mediaType=application/json"`) + if err != nil { + return nil, err + } + + req, err := http.NewRequestWithContext(ctx, "POST", opURL, bodyReader) + if err != nil { + return nil, fmt.Errorf("error creating request: %w", err) + } + req.Header.Set("Accept", "application/json") + req.Header.Set("User-Agent", s.sdkConfiguration.UserAgent) + req.Header.Set("Content-Type", reqContentType) + + if err := utils.PopulateSecurity(ctx, req, s.sdkConfiguration.Security); err != nil { + return nil, err + } + + req, err = s.sdkConfiguration.Hooks.BeforeRequest(hooks.BeforeRequestContext{HookContext: hookCtx}, req) + if err != nil { + return nil, err + } + + httpRes, err := s.sdkConfiguration.Client.Do(req) + if err != nil || httpRes == nil { + if err != nil { + err = fmt.Errorf("error sending request: %w", err) + } else { + err = fmt.Errorf("error sending request: no response") + } + + _, err = s.sdkConfiguration.Hooks.AfterError(hooks.AfterErrorContext{HookContext: hookCtx}, nil, err) + return nil, err + } else if utils.MatchStatusCodes([]string{"400", "401", "403", "404", "409", "429", "4XX", "500", "5XX"}, httpRes.StatusCode) { + _httpRes, err := s.sdkConfiguration.Hooks.AfterError(hooks.AfterErrorContext{HookContext: hookCtx}, httpRes, nil) + if err != nil { + return nil, err + } else if _httpRes != nil { + httpRes = _httpRes + } + } else { + httpRes, err = s.sdkConfiguration.Hooks.AfterSuccess(hooks.AfterSuccessContext{HookContext: hookCtx}, httpRes) + if err != nil { + return nil, err + } + } + + rawBody, err := io.ReadAll(httpRes.Body) + if err != nil { + return nil, fmt.Errorf("error reading response body: %w", err) + } + httpRes.Body.Close() + httpRes.Body = io.NopCloser(bytes.NewBuffer(rawBody)) + + switch { + case httpRes.StatusCode == 200: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out operations.CreateAPIResponseBody + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return &out, nil + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 400: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrBadRequest + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 401: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrUnauthorized + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 403: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrForbidden + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 404: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrNotFound + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 409: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrConflict + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 429: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrTooManyRequests + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode >= 400 && httpRes.StatusCode < 500: + fallthrough + case httpRes.StatusCode >= 500 && httpRes.StatusCode < 600: + return nil, sdkerrors.NewSDKError("API error occurred", httpRes.StatusCode, string(rawBody), httpRes) + case httpRes.StatusCode == 500: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrInternalServerError + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + default: + return nil, sdkerrors.NewSDKError("unknown status code returned", httpRes.StatusCode, string(rawBody), httpRes) + } +} + +func (s *Unkey) DeleteAPI(ctx context.Context, request operations.DeleteAPIRequestBody) (*operations.DeleteAPIResponseBody, error) { + hookCtx := hooks.HookContext{ + Context: ctx, + OperationID: "deleteApi", + OAuth2Scopes: []string{}, + SecuritySource: s.sdkConfiguration.Security, + } + + baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) + opURL, err := url.JoinPath(baseURL, "/v1/apis.deleteApi") + if err != nil { + return nil, fmt.Errorf("error generating URL: %w", err) + } + + bodyReader, reqContentType, err := utils.SerializeRequestBody(ctx, request, false, false, "Request", "json", `request:"mediaType=application/json"`) + if err != nil { + return nil, err + } + + req, err := http.NewRequestWithContext(ctx, "POST", opURL, bodyReader) + if err != nil { + return nil, fmt.Errorf("error creating request: %w", err) + } + req.Header.Set("Accept", "application/json") + req.Header.Set("User-Agent", s.sdkConfiguration.UserAgent) + req.Header.Set("Content-Type", reqContentType) + + if err := utils.PopulateSecurity(ctx, req, s.sdkConfiguration.Security); err != nil { + return nil, err + } + + req, err = s.sdkConfiguration.Hooks.BeforeRequest(hooks.BeforeRequestContext{HookContext: hookCtx}, req) + if err != nil { + return nil, err + } + + httpRes, err := s.sdkConfiguration.Client.Do(req) + if err != nil || httpRes == nil { + if err != nil { + err = fmt.Errorf("error sending request: %w", err) + } else { + err = fmt.Errorf("error sending request: no response") + } + + _, err = s.sdkConfiguration.Hooks.AfterError(hooks.AfterErrorContext{HookContext: hookCtx}, nil, err) + return nil, err + } else if utils.MatchStatusCodes([]string{"400", "401", "403", "404", "409", "429", "4XX", "500", "5XX"}, httpRes.StatusCode) { + _httpRes, err := s.sdkConfiguration.Hooks.AfterError(hooks.AfterErrorContext{HookContext: hookCtx}, httpRes, nil) + if err != nil { + return nil, err + } else if _httpRes != nil { + httpRes = _httpRes + } + } else { + httpRes, err = s.sdkConfiguration.Hooks.AfterSuccess(hooks.AfterSuccessContext{HookContext: hookCtx}, httpRes) + if err != nil { + return nil, err + } + } + + rawBody, err := io.ReadAll(httpRes.Body) + if err != nil { + return nil, fmt.Errorf("error reading response body: %w", err) + } + httpRes.Body.Close() + httpRes.Body = io.NopCloser(bytes.NewBuffer(rawBody)) + + switch { + case httpRes.StatusCode == 200: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out operations.DeleteAPIResponseBody + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return &out, nil + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 400: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrBadRequest + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 401: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrUnauthorized + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 403: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrForbidden + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 404: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrNotFound + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 409: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrConflict + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 429: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrTooManyRequests + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode >= 400 && httpRes.StatusCode < 500: + fallthrough + case httpRes.StatusCode >= 500 && httpRes.StatusCode < 600: + return nil, sdkerrors.NewSDKError("API error occurred", httpRes.StatusCode, string(rawBody), httpRes) + case httpRes.StatusCode == 500: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrInternalServerError + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + default: + return nil, sdkerrors.NewSDKError("unknown status code returned", httpRes.StatusCode, string(rawBody), httpRes) + } +} + +func (s *Unkey) DeprecatedCreateKey(ctx context.Context, request operations.DeprecatedCreateKeyRequestBody) (*operations.DeprecatedCreateKeyResponseBody, error) { + hookCtx := hooks.HookContext{ + Context: ctx, + OperationID: "deprecated.createKey", + OAuth2Scopes: []string{}, + SecuritySource: s.sdkConfiguration.Security, + } + + baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) + opURL, err := url.JoinPath(baseURL, "/v1/keys") + if err != nil { + return nil, fmt.Errorf("error generating URL: %w", err) + } + + bodyReader, reqContentType, err := utils.SerializeRequestBody(ctx, request, false, false, "Request", "json", `request:"mediaType=application/json"`) + if err != nil { + return nil, err + } + + req, err := http.NewRequestWithContext(ctx, "POST", opURL, bodyReader) + if err != nil { + return nil, fmt.Errorf("error creating request: %w", err) + } + req.Header.Set("Accept", "application/json") + req.Header.Set("User-Agent", s.sdkConfiguration.UserAgent) + req.Header.Set("Content-Type", reqContentType) + + if err := utils.PopulateSecurity(ctx, req, s.sdkConfiguration.Security); err != nil { + return nil, err + } + + req, err = s.sdkConfiguration.Hooks.BeforeRequest(hooks.BeforeRequestContext{HookContext: hookCtx}, req) + if err != nil { + return nil, err + } + + httpRes, err := s.sdkConfiguration.Client.Do(req) + if err != nil || httpRes == nil { + if err != nil { + err = fmt.Errorf("error sending request: %w", err) + } else { + err = fmt.Errorf("error sending request: no response") + } + + _, err = s.sdkConfiguration.Hooks.AfterError(hooks.AfterErrorContext{HookContext: hookCtx}, nil, err) + return nil, err + } else if utils.MatchStatusCodes([]string{"400", "401", "403", "404", "409", "429", "4XX", "500", "5XX"}, httpRes.StatusCode) { + _httpRes, err := s.sdkConfiguration.Hooks.AfterError(hooks.AfterErrorContext{HookContext: hookCtx}, httpRes, nil) + if err != nil { + return nil, err + } else if _httpRes != nil { + httpRes = _httpRes + } + } else { + httpRes, err = s.sdkConfiguration.Hooks.AfterSuccess(hooks.AfterSuccessContext{HookContext: hookCtx}, httpRes) + if err != nil { + return nil, err + } + } + + rawBody, err := io.ReadAll(httpRes.Body) + if err != nil { + return nil, fmt.Errorf("error reading response body: %w", err) + } + httpRes.Body.Close() + httpRes.Body = io.NopCloser(bytes.NewBuffer(rawBody)) + + switch { + case httpRes.StatusCode == 200: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out operations.DeprecatedCreateKeyResponseBody + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return &out, nil + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 400: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrBadRequest + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 401: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrUnauthorized + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 403: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrForbidden + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 404: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrNotFound + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 409: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrConflict + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 429: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrTooManyRequests + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode >= 400 && httpRes.StatusCode < 500: + fallthrough + case httpRes.StatusCode >= 500 && httpRes.StatusCode < 600: + return nil, sdkerrors.NewSDKError("API error occurred", httpRes.StatusCode, string(rawBody), httpRes) + case httpRes.StatusCode == 500: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrInternalServerError + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + default: + return nil, sdkerrors.NewSDKError("unknown status code returned", httpRes.StatusCode, string(rawBody), httpRes) + } +} + +// DeprecatedVerifyKey +// +// Deprecated method: This will be removed in a future release, please migrate away from it as soon as possible. +func (s *Unkey) DeprecatedVerifyKey(ctx context.Context, request operations.DeprecatedVerifyKeyRequestBody) (*operations.DeprecatedVerifyKeyResponseBody, error) { + hookCtx := hooks.HookContext{ + Context: ctx, + OperationID: "deprecated.verifyKey", + OAuth2Scopes: []string{}, + SecuritySource: s.sdkConfiguration.Security, + } + + baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) + opURL, err := url.JoinPath(baseURL, "/v1/keys/verify") + if err != nil { + return nil, fmt.Errorf("error generating URL: %w", err) + } + + bodyReader, reqContentType, err := utils.SerializeRequestBody(ctx, request, false, false, "Request", "json", `request:"mediaType=application/json"`) + if err != nil { + return nil, err + } + + req, err := http.NewRequestWithContext(ctx, "POST", opURL, bodyReader) + if err != nil { + return nil, fmt.Errorf("error creating request: %w", err) + } + req.Header.Set("Accept", "application/json") + req.Header.Set("User-Agent", s.sdkConfiguration.UserAgent) + req.Header.Set("Content-Type", reqContentType) + + if err := utils.PopulateSecurity(ctx, req, s.sdkConfiguration.Security); err != nil { + return nil, err + } + + req, err = s.sdkConfiguration.Hooks.BeforeRequest(hooks.BeforeRequestContext{HookContext: hookCtx}, req) + if err != nil { + return nil, err + } + + httpRes, err := s.sdkConfiguration.Client.Do(req) + if err != nil || httpRes == nil { + if err != nil { + err = fmt.Errorf("error sending request: %w", err) + } else { + err = fmt.Errorf("error sending request: no response") + } + + _, err = s.sdkConfiguration.Hooks.AfterError(hooks.AfterErrorContext{HookContext: hookCtx}, nil, err) + return nil, err + } else if utils.MatchStatusCodes([]string{"400", "401", "403", "404", "409", "429", "4XX", "500", "5XX"}, httpRes.StatusCode) { + _httpRes, err := s.sdkConfiguration.Hooks.AfterError(hooks.AfterErrorContext{HookContext: hookCtx}, httpRes, nil) + if err != nil { + return nil, err + } else if _httpRes != nil { + httpRes = _httpRes + } + } else { + httpRes, err = s.sdkConfiguration.Hooks.AfterSuccess(hooks.AfterSuccessContext{HookContext: hookCtx}, httpRes) + if err != nil { + return nil, err + } + } + + rawBody, err := io.ReadAll(httpRes.Body) + if err != nil { + return nil, fmt.Errorf("error reading response body: %w", err) + } + httpRes.Body.Close() + httpRes.Body = io.NopCloser(bytes.NewBuffer(rawBody)) + + switch { + case httpRes.StatusCode == 200: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out operations.DeprecatedVerifyKeyResponseBody + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return &out, nil + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 400: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrBadRequest + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 401: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrUnauthorized + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 403: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrForbidden + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 404: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrNotFound + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 409: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrConflict + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 429: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrTooManyRequests + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode >= 400 && httpRes.StatusCode < 500: + fallthrough + case httpRes.StatusCode >= 500 && httpRes.StatusCode < 600: + return nil, sdkerrors.NewSDKError("API error occurred", httpRes.StatusCode, string(rawBody), httpRes) + case httpRes.StatusCode == 500: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrInternalServerError + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + default: + return nil, sdkerrors.NewSDKError("unknown status code returned", httpRes.StatusCode, string(rawBody), httpRes) + } +} + +func (s *Unkey) DeprecatedListKeys(ctx context.Context, request operations.DeprecatedListKeysRequest) (*operations.DeprecatedListKeysResponseBody, error) { + hookCtx := hooks.HookContext{ + Context: ctx, + OperationID: "deprecated.listKeys", + OAuth2Scopes: []string{}, + SecuritySource: s.sdkConfiguration.Security, + } + + baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) + opURL, err := utils.GenerateURL(ctx, baseURL, "/v1/apis/{apiId}/keys", request, nil) + if err != nil { + return nil, fmt.Errorf("error generating URL: %w", err) + } + + req, err := http.NewRequestWithContext(ctx, "GET", opURL, nil) + if err != nil { + return nil, fmt.Errorf("error creating request: %w", err) + } + req.Header.Set("Accept", "application/json") + req.Header.Set("User-Agent", s.sdkConfiguration.UserAgent) + + if err := utils.PopulateQueryParams(ctx, req, request, nil); err != nil { + return nil, fmt.Errorf("error populating query params: %w", err) + } + + if err := utils.PopulateSecurity(ctx, req, s.sdkConfiguration.Security); err != nil { + return nil, err + } + + req, err = s.sdkConfiguration.Hooks.BeforeRequest(hooks.BeforeRequestContext{HookContext: hookCtx}, req) + if err != nil { + return nil, err + } + + httpRes, err := s.sdkConfiguration.Client.Do(req) + if err != nil || httpRes == nil { + if err != nil { + err = fmt.Errorf("error sending request: %w", err) + } else { + err = fmt.Errorf("error sending request: no response") + } + + _, err = s.sdkConfiguration.Hooks.AfterError(hooks.AfterErrorContext{HookContext: hookCtx}, nil, err) + return nil, err + } else if utils.MatchStatusCodes([]string{"400", "401", "403", "404", "409", "429", "4XX", "500", "5XX"}, httpRes.StatusCode) { + _httpRes, err := s.sdkConfiguration.Hooks.AfterError(hooks.AfterErrorContext{HookContext: hookCtx}, httpRes, nil) + if err != nil { + return nil, err + } else if _httpRes != nil { + httpRes = _httpRes + } + } else { + httpRes, err = s.sdkConfiguration.Hooks.AfterSuccess(hooks.AfterSuccessContext{HookContext: hookCtx}, httpRes) + if err != nil { + return nil, err + } + } + + rawBody, err := io.ReadAll(httpRes.Body) + if err != nil { + return nil, fmt.Errorf("error reading response body: %w", err) + } + httpRes.Body.Close() + httpRes.Body = io.NopCloser(bytes.NewBuffer(rawBody)) + + switch { + case httpRes.StatusCode == 200: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out operations.DeprecatedListKeysResponseBody + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return &out, nil + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 400: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrBadRequest + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 401: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrUnauthorized + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 403: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrForbidden + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 404: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrNotFound + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 409: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrConflict + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 429: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrTooManyRequests + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode >= 400 && httpRes.StatusCode < 500: + fallthrough + case httpRes.StatusCode >= 500 && httpRes.StatusCode < 600: + return nil, sdkerrors.NewSDKError("API error occurred", httpRes.StatusCode, string(rawBody), httpRes) + case httpRes.StatusCode == 500: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.ErrInternalServerError + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + default: + return nil, sdkerrors.NewSDKError("unknown status code returned", httpRes.StatusCode, string(rawBody), httpRes) + } +}