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..0dea62d --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.terraform +.terraform* +*.tfstate* +.DS_Store diff --git a/README.md b/README.md new file mode 100644 index 0000000..8f74d74 --- /dev/null +++ b/README.md @@ -0,0 +1,83 @@ +# PlexAPI + +
+ + + +
+ + + +To install this provider, copy and paste this code into your Terraform configuration. Then, run `terraform init`. + +```hcl +terraform { + required_providers { + PlexAPI = { + source = "LukeHagar/PlexAPI" + version = "0.1.0" + } + } +} + +provider "PlexAPI" { + # Configuration options +} +``` + + + + +### Testing the provider locally + +Should you want to validate a change locally, the `--debug` flag allows you to execute the provider against a terraform instance locally. + +This also allows for debuggers (e.g. delve) to be attached to the provider. + +### Example + +```sh +go run main.go --debug +# Copy the TF_REATTACH_PROVIDERS env var +# In a new terminal +cd examples/your-example +TF_REATTACH_PROVIDERS=... terraform init +TF_REATTACH_PROVIDERS=... terraform apply +``` + + + + + + + + + +Terraform allows you to use local provider builds by setting a `dev_overrides` block in a configuration file called `.terraformrc`. This block overrides all other configured installation methods. + +Terraform searches for the `.terraformrc` file in your home directory and applies any configuration settings you set. + +``` +provider_installation { + + dev_overrides { + "registry.terraform.io/LukeHagar/plex-api" = "" + } + + # For all other providers, install them directly from their origin provider + # registries as normal. If you omit this, Terraform will _only_ use + # the dev_overrides block, and so no other providers will be available. + direct {} +} +``` + +Your `` may vary depending on how your Go environment variables are configured. Execute `go env GOBIN` to set it, then set the `` to the value returned. If nothing is returned, set it to the default location, `$HOME/go/bin`. + +Note: To use the dev_overrides, please ensure you run `go build` in this folder. You must have a binary available for terraform to find. + +### Contributions + +While we value open-source contributions to this SDK, this library is generated programmatically. +Feel free to open a PR or a Github issue as a proof of concept and we'll do our best to include it in a future release! + +### SDK Created by [Speakeasy](https://docs.speakeasyapi.dev/docs/using-speakeasy/client-sdks) diff --git a/RELEASES.md b/RELEASES.md new file mode 100644 index 0000000..5fc6d40 --- /dev/null +++ b/RELEASES.md @@ -0,0 +1,9 @@ + + +## 2023-12-25 01:08:19 +### Changes +Based on: +- OpenAPI Doc 0.0.3 +- Speakeasy CLI 1.129.1 (2.223.3) https://github.com/speakeasy-api/speakeasy +### Generated +- [terraform v0.1.0] . \ No newline at end of file diff --git a/USAGE.md b/USAGE.md new file mode 100644 index 0000000..8e707bb --- /dev/null +++ b/USAGE.md @@ -0,0 +1,10 @@ + +```sh +go run main.go --debug +# Copy the TF_REATTACH_PROVIDERS env var +# In a new terminal +cd examples/your-example +TF_REATTACH_PROVIDERS=... terraform init +TF_REATTACH_PROVIDERS=... terraform apply +``` + \ No newline at end of file diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 0000000..2c0a76c --- /dev/null +++ b/docs/index.md @@ -0,0 +1,36 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "repo Provider" +subcategory: "" +description: |- + An Open API Spec for interacting with Plex.tv and Plex Servers +--- + +# repo Provider + +An Open API Spec for interacting with Plex.tv and Plex Servers + +## Example Usage + +```terraform +terraform { + required_providers { + PlexAPI = { + source = "LukeHagar/PlexAPI" + version = "0.1.0" + } + } +} + +provider "PlexAPI" { + # Configuration options +} +``` + + +## Schema + +### Optional + +- `access_token` (String, Sensitive) +- `server_url` (String) Server URL (defaults to http://10.10.10.47:32400) diff --git a/examples/README.md b/examples/README.md new file mode 100644 index 0000000..f87f5c1 --- /dev/null +++ b/examples/README.md @@ -0,0 +1 @@ +# TODO \ No newline at end of file diff --git a/examples/provider/provider.tf b/examples/provider/provider.tf new file mode 100644 index 0000000..c196368 --- /dev/null +++ b/examples/provider/provider.tf @@ -0,0 +1,12 @@ +terraform { + required_providers { + PlexAPI = { + source = "LukeHagar/PlexAPI" + version = "0.1.0" + } + } +} + +provider "PlexAPI" { + # Configuration options +} \ No newline at end of file diff --git a/files.gen b/files.gen new file mode 100644 index 0000000..843ce28 --- /dev/null +++ b/files.gen @@ -0,0 +1,128 @@ +internal/sdk/server.go +internal/sdk/media.go +internal/sdk/activities.go +internal/sdk/butler.go +internal/sdk/hubs.go +internal/sdk/search.go +internal/sdk/library.go +internal/sdk/log.go +internal/sdk/playlists.go +internal/sdk/security.go +internal/sdk/sessions.go +internal/sdk/updater.go +internal/sdk/video.go +internal/sdk/sdk.go +examples/README.md +go.mod +go.sum +internal/planmodifiers/boolplanmodifier/suppress_diff.go +internal/planmodifiers/float64planmodifier/suppress_diff.go +internal/planmodifiers/int64planmodifier/suppress_diff.go +internal/planmodifiers/listplanmodifier/suppress_diff.go +internal/planmodifiers/mapplanmodifier/suppress_diff.go +internal/planmodifiers/numberplanmodifier/suppress_diff.go +internal/planmodifiers/objectplanmodifier/suppress_diff.go +internal/planmodifiers/setplanmodifier/suppress_diff.go +internal/planmodifiers/stringplanmodifier/suppress_diff.go +internal/planmodifiers/utils/state_check.go +internal/provider/reflect/diags.go +internal/provider/reflect/doc.go +internal/provider/reflect/generic_attr_value.go +internal/provider/reflect/helpers.go +internal/provider/reflect/interfaces.go +internal/provider/reflect/into.go +internal/provider/reflect/map.go +internal/provider/reflect/number.go +internal/provider/reflect/options.go +internal/provider/reflect/outof.go +internal/provider/reflect/pointer.go +internal/provider/reflect/primitive.go +internal/provider/reflect/slice.go +internal/provider/reflect/struct.go +internal/provider/utils.go +internal/sdk/pkg/models/sdkerrors/sdkerror.go +internal/sdk/pkg/types/bigint.go +internal/sdk/pkg/types/date.go +internal/sdk/pkg/types/datetime.go +internal/sdk/pkg/types/decimal.go +internal/sdk/pkg/types/pointers.go +internal/sdk/pkg/utils/contenttype.go +internal/sdk/pkg/utils/form.go +internal/sdk/pkg/utils/headers.go +internal/sdk/pkg/utils/json.go +internal/sdk/pkg/utils/pathparams.go +internal/sdk/pkg/utils/queryparams.go +internal/sdk/pkg/utils/requestbody.go +internal/sdk/pkg/utils/retries.go +internal/sdk/pkg/utils/security.go +internal/sdk/pkg/utils/utils.go +internal/validators/DateValidator.go +internal/validators/ExactlyOneChild.go +internal/validators/JSONParseValidator.go +internal/validators/RFC3339Validator.go +main.go +terraform-registry-manifest.json +tools/tools.go +internal/sdk/pkg/models/operations/getservercapabilities.go +internal/sdk/pkg/models/operations/getserverpreferences.go +internal/sdk/pkg/models/operations/getavailableclients.go +internal/sdk/pkg/models/operations/getdevices.go +internal/sdk/pkg/models/operations/getserveridentity.go +internal/sdk/pkg/models/operations/getmyplexaccount.go +internal/sdk/pkg/models/operations/getresizedphoto.go +internal/sdk/pkg/models/operations/getserverlist.go +internal/sdk/pkg/models/operations/markplayed.go +internal/sdk/pkg/models/operations/markunplayed.go +internal/sdk/pkg/models/operations/updateplayprogress.go +internal/sdk/pkg/models/operations/getserveractivities.go +internal/sdk/pkg/models/operations/cancelserveractivities.go +internal/sdk/pkg/models/operations/getbutlertasks.go +internal/sdk/pkg/models/operations/startalltasks.go +internal/sdk/pkg/models/operations/stopalltasks.go +internal/sdk/pkg/models/operations/starttask.go +internal/sdk/pkg/models/operations/stoptask.go +internal/sdk/pkg/models/operations/getglobalhubs.go +internal/sdk/pkg/models/operations/getlibraryhubs.go +internal/sdk/pkg/models/operations/performsearch.go +internal/sdk/pkg/models/operations/performvoicesearch.go +internal/sdk/pkg/models/operations/getsearchresults.go +internal/sdk/pkg/models/operations/getfilehash.go +internal/sdk/pkg/models/operations/getrecentlyadded.go +internal/sdk/pkg/models/operations/getlibraries.go +internal/sdk/pkg/models/operations/getlibrary.go +internal/sdk/pkg/models/operations/deletelibrary.go +internal/sdk/pkg/models/operations/getlibraryitems.go +internal/sdk/pkg/models/operations/refreshlibrary.go +internal/sdk/pkg/models/operations/getlatestlibraryitems.go +internal/sdk/pkg/models/operations/getcommonlibraryitems.go +internal/sdk/pkg/models/operations/getmetadata.go +internal/sdk/pkg/models/operations/getmetadatachildren.go +internal/sdk/pkg/models/operations/getondeck.go +internal/sdk/pkg/models/operations/logline.go +internal/sdk/pkg/models/operations/logmultiline.go +internal/sdk/pkg/models/operations/enablepapertrail.go +internal/sdk/pkg/models/operations/createplaylist.go +internal/sdk/pkg/models/operations/getplaylists.go +internal/sdk/pkg/models/operations/getplaylist.go +internal/sdk/pkg/models/operations/deleteplaylist.go +internal/sdk/pkg/models/operations/updateplaylist.go +internal/sdk/pkg/models/operations/getplaylistcontents.go +internal/sdk/pkg/models/operations/clearplaylistcontents.go +internal/sdk/pkg/models/operations/addplaylistcontents.go +internal/sdk/pkg/models/operations/uploadplaylist.go +internal/sdk/pkg/models/operations/gettransienttoken.go +internal/sdk/pkg/models/operations/getsourceconnectioninformation.go +internal/sdk/pkg/models/operations/getsessions.go +internal/sdk/pkg/models/operations/getsessionhistory.go +internal/sdk/pkg/models/operations/gettranscodesessions.go +internal/sdk/pkg/models/operations/stoptranscodesession.go +internal/sdk/pkg/models/operations/getupdatestatus.go +internal/sdk/pkg/models/operations/checkforupdates.go +internal/sdk/pkg/models/operations/applyupdates.go +internal/sdk/pkg/models/operations/startuniversaltranscode.go +internal/sdk/pkg/models/operations/gettimeline.go +internal/sdk/pkg/models/shared/security.go +USAGE.md +internal/provider/provider.go +examples/provider/provider.tf +.gitattributes \ No newline at end of file diff --git a/gen.yaml b/gen.yaml index 26bc6cd..19cb1ee 100644 --- a/gen.yaml +++ b/gen.yaml @@ -1,16 +1,28 @@ configVersion: 1.0.0 +management: + docChecksum: 550154cf1b4d0c237436fb18c418b5db + docVersion: 0.0.3 + speakeasyVersion: 1.129.1 + generationVersion: 2.223.3 generation: comments: {} sdkClassName: Plex-API - repoURL: https://github.com/speakeasy-sdks/Personal-sample-sdk-9.git + repoURL: https://github.com/LukeHagar/plexterraform.git maintainOpenAPIOrder: true usageSnippets: optionalPropertyRendering: withExample - useClassNamesForArrayFields: true fixes: nameResolutionDec2023: false + useClassNamesForArrayFields: true +features: + terraform: + constsAndDefaults: 0.1.2 + core: 3.6.3 + globalSecurity: 2.81.2 + globalServerURLs: 2.82.1 + nameOverrides: 2.81.1 terraform: - version: 0.0.1 + version: 0.1.0 author: LukeHagar imports: option: openapi @@ -23,3 +35,5 @@ terraform: inputModelSuffix: input outputModelSuffix: output packageName: PlexAPI + published: true + repoSubDirectory: . diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..4e3a71d --- /dev/null +++ b/go.mod @@ -0,0 +1,65 @@ +module github.com/LukeHagar/terraform-provider-PlexAPI + +go 1.18 + +require ( + github.com/cenkalti/backoff/v4 v4.2.0 + github.com/ericlagergren/decimal v0.0.0-20221120152707-495c53812d05 + github.com/hashicorp/terraform-plugin-framework v1.3.5 + github.com/hashicorp/terraform-plugin-go v0.18.0 +) + +require ( + github.com/Masterminds/goutils v1.1.1 // indirect + github.com/Masterminds/semver/v3 v3.1.1 // indirect + github.com/Masterminds/sprig/v3 v3.2.2 // indirect + github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect + github.com/armon/go-radix v1.0.0 // indirect + github.com/bgentry/speakeasy v0.1.0 // indirect + github.com/fatih/color v1.13.0 // indirect + github.com/golang/protobuf v1.5.3 // indirect + github.com/google/uuid v1.3.0 // indirect + github.com/hashicorp/errwrap v1.1.0 // indirect + github.com/hashicorp/go-checkpoint v0.5.0 // indirect + github.com/hashicorp/go-cleanhttp v0.5.2 // indirect + github.com/hashicorp/go-hclog v1.5.0 // indirect + github.com/hashicorp/go-multierror v1.1.1 // indirect + github.com/hashicorp/go-plugin v1.4.10 // indirect + github.com/hashicorp/go-uuid v1.0.3 // indirect + github.com/hashicorp/go-version v1.6.0 // indirect + github.com/hashicorp/hc-install v0.4.0 // indirect + github.com/hashicorp/terraform-exec v0.17.2 // indirect + github.com/hashicorp/terraform-json v0.14.0 // indirect + github.com/hashicorp/terraform-plugin-log v0.9.0 // indirect + github.com/hashicorp/terraform-registry-address v0.2.1 // indirect + github.com/hashicorp/terraform-svchost v0.1.1 // indirect + github.com/huandu/xstrings v1.3.2 // indirect + github.com/imdario/mergo v0.3.13 // indirect + github.com/mattn/go-colorable v0.1.12 // indirect + github.com/mattn/go-isatty v0.0.14 // indirect + github.com/mitchellh/cli v1.1.4 // indirect + github.com/mitchellh/copystructure v1.2.0 // indirect + github.com/mitchellh/go-testing-interface v1.14.1 // indirect + github.com/mitchellh/reflectwalk v1.0.2 // indirect + github.com/oklog/run v1.0.0 // indirect + github.com/posener/complete v1.2.3 // indirect + github.com/russross/blackfriday v1.6.0 // indirect + github.com/shopspring/decimal v1.3.1 // indirect + github.com/spf13/cast v1.5.0 // indirect + github.com/vmihailenco/msgpack/v5 v5.3.5 // indirect + github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect + github.com/zclconf/go-cty v1.13.1 // indirect + golang.org/x/crypto v0.10.0 // indirect + golang.org/x/net v0.11.0 // indirect + golang.org/x/sys v0.9.0 // indirect + golang.org/x/text v0.10.0 // indirect + google.golang.org/grpc v1.56.1 // indirect + google.golang.org/protobuf v1.31.0 // indirect +) + +require ( + github.com/hashicorp/terraform-plugin-docs v0.13.0 + github.com/hashicorp/terraform-plugin-framework-validators v0.10.0 + github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d // indirect + google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..3638012 --- /dev/null +++ b/go.sum @@ -0,0 +1,266 @@ +github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= +github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= +github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= +github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc= +github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= +github.com/Masterminds/sprig/v3 v3.2.0/go.mod h1:tWhwTbUTndesPNeF0C900vKoq283u6zp4APT9vaF3SI= +github.com/Masterminds/sprig/v3 v3.2.2 h1:17jRggJu518dr3QaafizSXOjKYp94wKfABxUmyxvxX8= +github.com/Masterminds/sprig/v3 v3.2.2/go.mod h1:UoaO7Yp8KlPnJIYWTFkMaqPUYKTfGFPhxNuwnnxkKlk= +github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= +github.com/Microsoft/go-winio v0.4.16 h1:FtSW/jqD+l4ba5iPBj9CODVtgfYAD8w2wS923g/cFDk= +github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0= +github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7 h1:YoJbenK9C67SkzkDfmQuVln04ygHj3vjZfd9FL+GmQQ= +github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7/go.mod h1:z4/9nQmJSSwwds7ejkxaJwO37dru3geImFUdJlaLzQo= +github.com/acomagu/bufpipe v1.0.3 h1:fxAGrHZTgQ9w5QqVItgzwj235/uYZYgbXitB+dLupOk= +github.com/acomagu/bufpipe v1.0.3/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4= +github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= +github.com/apparentlymart/go-textseg v1.0.0/go.mod h1:z96Txxhf3xSFMPmb5X/1W05FF/Nj9VFpLOpjS5yuumk= +github.com/apparentlymart/go-textseg/v13 v13.0.0 h1:Y+KvPE1NYz0xl601PVImeQfFyEy6iT90AvPUL1NNfNw= +github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkEghdlcqw7yxLeM89kiTRPUo= +github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI= +github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= +github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY= +github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +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/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg= +github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= +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= +github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= +github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= +github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= +github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE= +github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= +github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4= +github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E= +github.com/go-git/go-billy/v5 v5.2.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0= +github.com/go-git/go-billy/v5 v5.3.1 h1:CPiOUAzKtMRvolEKw+bG1PLRpT7D3LIs3/3ey4Aiu34= +github.com/go-git/go-billy/v5 v5.3.1/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0= +github.com/go-git/go-git-fixtures/v4 v4.2.1/go.mod h1:K8zd3kDUAykwTdDCr+I0per6Y6vMiRR/nnVTBtavnB0= +github.com/go-git/go-git/v5 v5.4.2 h1:BXyZu9t0VkbiHtqrsvdq39UDhGJTl1h55VW6CSC4aY4= +github.com/go-git/go-git/v5 v5.4.2/go.mod h1:gQ1kArt6d+n+BGd+/B/I74HwRTLhth2+zti4ihgckDc= +github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= +github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-checkpoint v0.5.0 h1:MFYpPZCnQqQTE18jFwSII6eUQrD/oxMFp3mlgcqk5mU= +github.com/hashicorp/go-checkpoint v0.5.0/go.mod h1:7nfLNL10NsxqO4iWuW6tWW0HjZuDrwkBuEQsVcpCOgg= +github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= +github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= +github.com/hashicorp/go-hclog v1.5.0 h1:bI2ocEMgcVlz55Oj1xZNBsVi900c7II+fWDyV9o+13c= +github.com/hashicorp/go-hclog v1.5.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= +github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= +github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= +github.com/hashicorp/go-plugin v1.4.10 h1:xUbmA4jC6Dq163/fWcp8P3JuHilrHHMLNRxzGQJ9hNk= +github.com/hashicorp/go-plugin v1.4.10/go.mod h1:6/1TEzT0eQznvI/gV2CM29DLSkAK/e58mUWKVsPaph0= +github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= +github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-version v1.5.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek= +github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/hc-install v0.4.0 h1:cZkRFr1WVa0Ty6x5fTvL1TuO1flul231rWkGH92oYYk= +github.com/hashicorp/hc-install v0.4.0/go.mod h1:5d155H8EC5ewegao9A4PUTMNPZaq+TbOzkJJZ4vrXeI= +github.com/hashicorp/terraform-exec v0.17.2 h1:EU7i3Fh7vDUI9nNRdMATCEfnm9axzTnad8zszYZ73Go= +github.com/hashicorp/terraform-exec v0.17.2/go.mod h1:tuIbsL2l4MlwwIZx9HPM+LOV9vVyEfBYu2GsO1uH3/8= +github.com/hashicorp/terraform-json v0.14.0 h1:sh9iZ1Y8IFJLx+xQiKHGud6/TSUCM0N8e17dKDpqV7s= +github.com/hashicorp/terraform-json v0.14.0/go.mod h1:5A9HIWPkk4e5aeeXIBbkcOvaZbIYnAIkEyqP2pNSckM= +github.com/hashicorp/terraform-plugin-docs v0.13.0 h1:6e+VIWsVGb6jYJewfzq2ok2smPzZrt1Wlm9koLeKazY= +github.com/hashicorp/terraform-plugin-docs v0.13.0/go.mod h1:W0oCmHAjIlTHBbvtppWHe8fLfZ2BznQbuv8+UD8OucQ= +github.com/hashicorp/terraform-plugin-framework v1.3.5 h1:FJ6s3CVWVAxlhiF/jhy6hzs4AnPHiflsp9KgzTGl1wo= +github.com/hashicorp/terraform-plugin-framework v1.3.5/go.mod h1:2gGDpWiTI0irr9NSTLFAKlTi6KwGti3AoU19rFqU30o= +github.com/hashicorp/terraform-plugin-framework-validators v0.10.0 h1:4L0tmy/8esP6OcvocVymw52lY0HyQ5OxB7VNl7k4bS0= +github.com/hashicorp/terraform-plugin-framework-validators v0.10.0/go.mod h1:qdQJCdimB9JeX2YwOpItEu+IrfoJjWQ5PhLpAOMDQAE= +github.com/hashicorp/terraform-plugin-go v0.18.0 h1:IwTkOS9cOW1ehLd/rG0y+u/TGLK9y6fGoBjXVUquzpE= +github.com/hashicorp/terraform-plugin-go v0.18.0/go.mod h1:l7VK+2u5Kf2y+A+742GX0ouLut3gttudmvMgN0PA74Y= +github.com/hashicorp/terraform-plugin-log v0.9.0 h1:i7hOA+vdAItN1/7UrfBqBwvYPQ9TFvymaRGZED3FCV0= +github.com/hashicorp/terraform-plugin-log v0.9.0/go.mod h1:rKL8egZQ/eXSyDqzLUuwUYLVdlYeamldAHSxjUFADow= +github.com/hashicorp/terraform-registry-address v0.2.1 h1:QuTf6oJ1+WSflJw6WYOHhLgwUiQ0FrROpHPYFtwTYWM= +github.com/hashicorp/terraform-registry-address v0.2.1/go.mod h1:BSE9fIFzp0qWsJUUyGquo4ldV9k2n+psif6NYkBRS3Y= +github.com/hashicorp/terraform-svchost v0.1.1 h1:EZZimZ1GxdqFRinZ1tpJwVxxt49xc/S52uzrw4x0jKQ= +github.com/hashicorp/terraform-svchost v0.1.1/go.mod h1:mNsjQfZyf/Jhz35v6/0LWcv26+X7JPS+buii2c9/ctc= +github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d h1:kJCB4vdITiW1eC1vq2e6IsrXKrZit1bv/TDYFGMp4BQ= +github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= +github.com/huandu/xstrings v1.3.1/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= +github.com/huandu/xstrings v1.3.2 h1:L18LIDzqlW6xN2rEkpdV8+oL/IXWJ1APd+vsdYy4Wdw= +github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= +github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= +github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= +github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk= +github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg= +github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= +github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= +github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4= +github.com/jhump/protoreflect v1.6.0 h1:h5jfMVslIg6l29nsMs0D8Wj17RDVdNYti0vDN/PZZoE= +github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 h1:DowS9hvgyYSX4TO5NpyC606/Z4SxnNYbT+WX27or6Ck= +github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= +github.com/matryer/is v1.2.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlWXA= +github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40= +github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= +github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mitchellh/cli v1.1.4 h1:qj8czE26AU4PbiaPXK5uVmMSM+V5BYsFBiM9HhGRLUA= +github.com/mitchellh/cli v1.1.4/go.mod h1:vTLESy5mRhKOs9KDp0/RATawxP1UqBmdrpVRMnpcvKQ= +github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= +github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= +github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= +github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU= +github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8= +github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= +github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= +github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw= +github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= +github.com/posener/complete v1.2.3 h1:NP0eAhjcjImqslEwo/1hq7gpajME0fTLTezBKDqfXqo= +github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= +github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k= +github.com/russross/blackfriday v1.6.0 h1:KqfZb0pUVN2lYqZUYRddxF4OR8ZMURnJIG5Y3VRLtww= +github.com/russross/blackfriday v1.6.0/go.mod h1:ti0ldHuxg49ri4ksnFxlkCfN+hvslNlmVHqNRXXJNAY= +github.com/sebdah/goldie v1.0.0/go.mod h1:jXP4hmWywNEwZzhMuv2ccnqTSFpuq8iyQhtQdkkZBH4= +github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= +github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= +github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= +github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8= +github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= +github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= +github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w= +github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.2 h1:4jaiDzPyXQvSd7D0EjG45355tLlV3VOECpq10pLC+8s= +github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= +github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= +github.com/vmihailenco/msgpack/v4 v4.3.12/go.mod h1:gborTTJjAo/GWTqqRjrLCn9pgNN+NXzzngzBKDPIqw4= +github.com/vmihailenco/msgpack/v5 v5.3.5 h1:5gO0H1iULLWGhs2H5tbAHIZTV8/cYafcFOr9znI5mJU= +github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc= +github.com/vmihailenco/tagparser v0.1.1/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI= +github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= +github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= +github.com/xanzy/ssh-agent v0.3.0 h1:wUMzuKtKilRgBAD1sUb8gOwwRr2FGoBVumcjoOACClI= +github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0= +github.com/zclconf/go-cty v1.2.0/go.mod h1:hOPWgoHbaTUnI5k4D2ld+GRpFJSCe6bCM7m1q/N4PQ8= +github.com/zclconf/go-cty v1.10.0/go.mod h1:vVKLxnk3puL4qRAv72AO+W99LUD4da90g3uUAzyuvAk= +github.com/zclconf/go-cty v1.13.1 h1:0a6bRwuiSHtAmqCqNOE+c2oHgepv0ctoxU4FUe43kwc= +github.com/zclconf/go-cty v1.13.1/go.mod h1:YKQzy/7pZ7iq2jNFzy5go57xdxdWoLLpaEp4u238AE0= +github.com/zclconf/go-cty-debug v0.0.0-20191215020915-b22d67c1ba0b/go.mod h1:ZRKQfBXbGkpdV6QMzT3rU1kSTAnfu1dO8dPKjYprgj8= +golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20200414173820-0848c9571904/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= +golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= +golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM= +golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I= +golang.org/x/net v0.0.0-20180811021610-c39426892332/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210326060303-6b1517762897/go.mod h1:uSPa2vr4CLtc/ILN5odXGNXS6mhrKVzTaCXzk9m6W3k= +golang.org/x/net v0.11.0 h1:Gi2tvZIJyBtO9SDr1q9h5hEQCp/4L2RQ+ar0qjx2oNU= +golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210502180810-71e4cd670f79/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s= +golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58= +golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 h1:KpwkzHKEF7B9Zxg18WzOa7djJ+Ha5DzthMyZYQfEn2A= +google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU= +google.golang.org/grpc v1.56.1 h1:z0dNfjIl0VpaZ9iSVjA6daGatAYwPGstTjt5vkRMFkQ= +google.golang.org/grpc v1.56.1/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= +google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= +gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/internal/planmodifiers/boolplanmodifier/suppress_diff.go b/internal/planmodifiers/boolplanmodifier/suppress_diff.go new file mode 100644 index 0000000..78e4482 --- /dev/null +++ b/internal/planmodifiers/boolplanmodifier/suppress_diff.go @@ -0,0 +1,47 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package boolplanmodifier + +import ( + "context" + "github.com/LukeHagar/terraform-provider-PlexAPI/internal/planmodifiers/utils" + + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" +) + +// SuppressDiff returns a plan modifier that propagates a state value into the planned value, when it is Known, and the Plan Value is Unknown +func SuppressDiff() planmodifier.Bool { + return suppressDiff{} +} + +// suppressDiff implements the plan modifier. +type suppressDiff struct{} + +// Description returns a human-readable description of the plan modifier. +func (m suppressDiff) Description(_ context.Context) string { + return "Once set, the value of this attribute in state will not change." +} + +// MarkdownDescription returns a markdown description of the plan modifier. +func (m suppressDiff) MarkdownDescription(_ context.Context) string { + return "Once set, the value of this attribute in state will not change." +} + +// PlanModifyBool implements the plan modification logic. +func (m suppressDiff) PlanModifyBool(ctx context.Context, req planmodifier.BoolRequest, resp *planmodifier.BoolResponse) { + // Do nothing if there is a known planned value. + if !req.PlanValue.IsUnknown() { + return + } + + // Do nothing if there is an unknown configuration value + if req.ConfigValue.IsUnknown() { + return + } + + if utils.IsAllStateUnknown(ctx, req.State) { + return + } + + resp.PlanValue = req.StateValue +} diff --git a/internal/planmodifiers/float64planmodifier/suppress_diff.go b/internal/planmodifiers/float64planmodifier/suppress_diff.go new file mode 100644 index 0000000..7219cfe --- /dev/null +++ b/internal/planmodifiers/float64planmodifier/suppress_diff.go @@ -0,0 +1,47 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package float64planmodifier + +import ( + "context" + "github.com/LukeHagar/terraform-provider-PlexAPI/internal/planmodifiers/utils" + + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" +) + +// SuppressDiff returns a plan modifier that propagates a state value into the planned value, when it is Known, and the Plan Value is Unknown +func SuppressDiff() planmodifier.Float64 { + return suppressDiff{} +} + +// suppressDiff implements the plan modifier. +type suppressDiff struct{} + +// Description returns a human-readable description of the plan modifier. +func (m suppressDiff) Description(_ context.Context) string { + return "Once set, the value of this attribute in state will not change." +} + +// MarkdownDescription returns a markdown description of the plan modifier. +func (m suppressDiff) MarkdownDescription(_ context.Context) string { + return "Once set, the value of this attribute in state will not change." +} + +// PlanModifyFloat64 implements the plan modification logic. +func (m suppressDiff) PlanModifyFloat64(ctx context.Context, req planmodifier.Float64Request, resp *planmodifier.Float64Response) { + // Do nothing if there is a known planned value. + if !req.PlanValue.IsUnknown() { + return + } + + // Do nothing if there is an unknown configuration value + if req.ConfigValue.IsUnknown() { + return + } + + if utils.IsAllStateUnknown(ctx, req.State) { + return + } + + resp.PlanValue = req.StateValue +} diff --git a/internal/planmodifiers/int64planmodifier/suppress_diff.go b/internal/planmodifiers/int64planmodifier/suppress_diff.go new file mode 100644 index 0000000..cb5f786 --- /dev/null +++ b/internal/planmodifiers/int64planmodifier/suppress_diff.go @@ -0,0 +1,47 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package int64planmodifier + +import ( + "context" + "github.com/LukeHagar/terraform-provider-PlexAPI/internal/planmodifiers/utils" + + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" +) + +// SuppressDiff returns a plan modifier that propagates a state value into the planned value, when it is Known, and the Plan Value is Unknown +func SuppressDiff() planmodifier.Int64 { + return suppressDiff{} +} + +// suppressDiff implements the plan modifier. +type suppressDiff struct{} + +// Description returns a human-readable description of the plan modifier. +func (m suppressDiff) Description(_ context.Context) string { + return "Once set, the value of this attribute in state will not change." +} + +// MarkdownDescription returns a markdown description of the plan modifier. +func (m suppressDiff) MarkdownDescription(_ context.Context) string { + return "Once set, the value of this attribute in state will not change." +} + +// PlanModifyInt64 implements the plan modification logic. +func (m suppressDiff) PlanModifyInt64(ctx context.Context, req planmodifier.Int64Request, resp *planmodifier.Int64Response) { + // Do nothing if there is a known planned value. + if !req.PlanValue.IsUnknown() { + return + } + + // Do nothing if there is an unknown configuration value + if req.ConfigValue.IsUnknown() { + return + } + + if utils.IsAllStateUnknown(ctx, req.State) { + return + } + + resp.PlanValue = req.StateValue +} diff --git a/internal/planmodifiers/listplanmodifier/suppress_diff.go b/internal/planmodifiers/listplanmodifier/suppress_diff.go new file mode 100644 index 0000000..eab51d5 --- /dev/null +++ b/internal/planmodifiers/listplanmodifier/suppress_diff.go @@ -0,0 +1,47 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package listplanmodifier + +import ( + "context" + "github.com/LukeHagar/terraform-provider-PlexAPI/internal/planmodifiers/utils" + + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" +) + +// SuppressDiff returns a plan modifier that propagates a state value into the planned value, when it is Known, and the Plan Value is Unknown +func SuppressDiff() planmodifier.List { + return suppressDiff{} +} + +// suppressDiff implements the plan modifier. +type suppressDiff struct{} + +// Description returns a human-readable description of the plan modifier. +func (m suppressDiff) Description(_ context.Context) string { + return "Once set, the value of this attribute in state will not change." +} + +// MarkdownDescription returns a markdown description of the plan modifier. +func (m suppressDiff) MarkdownDescription(_ context.Context) string { + return "Once set, the value of this attribute in state will not change." +} + +// PlanModifyList implements the plan modification logic. +func (m suppressDiff) PlanModifyList(ctx context.Context, req planmodifier.ListRequest, resp *planmodifier.ListResponse) { + // Do nothing if there is a known planned value. + if !req.PlanValue.IsUnknown() { + return + } + + // Do nothing if there is an unknown configuration value + if req.ConfigValue.IsUnknown() { + return + } + + if utils.IsAllStateUnknown(ctx, req.State) { + return + } + + resp.PlanValue = req.StateValue +} diff --git a/internal/planmodifiers/mapplanmodifier/suppress_diff.go b/internal/planmodifiers/mapplanmodifier/suppress_diff.go new file mode 100644 index 0000000..e73f146 --- /dev/null +++ b/internal/planmodifiers/mapplanmodifier/suppress_diff.go @@ -0,0 +1,47 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package mapplanmodifier + +import ( + "context" + "github.com/LukeHagar/terraform-provider-PlexAPI/internal/planmodifiers/utils" + + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" +) + +// SuppressDiff returns a plan modifier that propagates a state value into the planned value, when it is Known, and the Plan Value is Unknown +func SuppressDiff() planmodifier.Map { + return suppressDiff{} +} + +// suppressDiff implements the plan modifier. +type suppressDiff struct{} + +// Description returns a human-readable description of the plan modifier. +func (m suppressDiff) Description(_ context.Context) string { + return "Once set, the value of this attribute in state will not change." +} + +// MarkdownDescription returns a markdown description of the plan modifier. +func (m suppressDiff) MarkdownDescription(_ context.Context) string { + return "Once set, the value of this attribute in state will not change." +} + +// PlanModifyMap implements the plan modification logic. +func (m suppressDiff) PlanModifyMap(ctx context.Context, req planmodifier.MapRequest, resp *planmodifier.MapResponse) { + // Do nothing if there is a known planned value. + if !req.PlanValue.IsUnknown() { + return + } + + // Do nothing if there is an unknown configuration value + if req.ConfigValue.IsUnknown() { + return + } + + if utils.IsAllStateUnknown(ctx, req.State) { + return + } + + resp.PlanValue = req.StateValue +} diff --git a/internal/planmodifiers/numberplanmodifier/suppress_diff.go b/internal/planmodifiers/numberplanmodifier/suppress_diff.go new file mode 100644 index 0000000..d13e559 --- /dev/null +++ b/internal/planmodifiers/numberplanmodifier/suppress_diff.go @@ -0,0 +1,47 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package numberplanmodifier + +import ( + "context" + "github.com/LukeHagar/terraform-provider-PlexAPI/internal/planmodifiers/utils" + + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" +) + +// SuppressDiff returns a plan modifier that propagates a state value into the planned value, when it is Known, and the Plan Value is Unknown +func SuppressDiff() planmodifier.Number { + return suppressDiff{} +} + +// suppressDiff implements the plan modifier. +type suppressDiff struct{} + +// Description returns a human-readable description of the plan modifier. +func (m suppressDiff) Description(_ context.Context) string { + return "Once set, the value of this attribute in state will not change." +} + +// MarkdownDescription returns a markdown description of the plan modifier. +func (m suppressDiff) MarkdownDescription(_ context.Context) string { + return "Once set, the value of this attribute in state will not change." +} + +// PlanModifyNumber implements the plan modification logic. +func (m suppressDiff) PlanModifyNumber(ctx context.Context, req planmodifier.NumberRequest, resp *planmodifier.NumberResponse) { + // Do nothing if there is a known planned value. + if !req.PlanValue.IsUnknown() { + return + } + + // Do nothing if there is an unknown configuration value + if req.ConfigValue.IsUnknown() { + return + } + + if utils.IsAllStateUnknown(ctx, req.State) { + return + } + + resp.PlanValue = req.StateValue +} diff --git a/internal/planmodifiers/objectplanmodifier/suppress_diff.go b/internal/planmodifiers/objectplanmodifier/suppress_diff.go new file mode 100644 index 0000000..3b388de --- /dev/null +++ b/internal/planmodifiers/objectplanmodifier/suppress_diff.go @@ -0,0 +1,47 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package objectplanmodifier + +import ( + "context" + "github.com/LukeHagar/terraform-provider-PlexAPI/internal/planmodifiers/utils" + + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" +) + +// SuppressDiff returns a plan modifier that propagates a state value into the planned value, when it is Known, and the Plan Value is Unknown +func SuppressDiff() planmodifier.Object { + return suppressDiff{} +} + +// suppressDiff implements the plan modifier. +type suppressDiff struct{} + +// Description returns a human-readable description of the plan modifier. +func (m suppressDiff) Description(_ context.Context) string { + return "Once set, the value of this attribute in state will not change." +} + +// MarkdownDescription returns a markdown description of the plan modifier. +func (m suppressDiff) MarkdownDescription(_ context.Context) string { + return "Once set, the value of this attribute in state will not change." +} + +// PlanModifyObject implements the plan modification logic. +func (m suppressDiff) PlanModifyObject(ctx context.Context, req planmodifier.ObjectRequest, resp *planmodifier.ObjectResponse) { + // Do nothing if there is a known planned value. + if !req.PlanValue.IsUnknown() { + return + } + + // Do nothing if there is an unknown configuration value + if req.ConfigValue.IsUnknown() { + return + } + + if utils.IsAllStateUnknown(ctx, req.State) { + return + } + + resp.PlanValue = req.StateValue +} diff --git a/internal/planmodifiers/setplanmodifier/suppress_diff.go b/internal/planmodifiers/setplanmodifier/suppress_diff.go new file mode 100644 index 0000000..00dbedc --- /dev/null +++ b/internal/planmodifiers/setplanmodifier/suppress_diff.go @@ -0,0 +1,47 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package setplanmodifier + +import ( + "context" + "github.com/LukeHagar/terraform-provider-PlexAPI/internal/planmodifiers/utils" + + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" +) + +// SuppressDiff returns a plan modifier that propagates a state value into the planned value, when it is Known, and the Plan Value is Unknown +func SuppressDiff() planmodifier.Set { + return suppressDiff{} +} + +// suppressDiff implements the plan modifier. +type suppressDiff struct{} + +// Description returns a human-readable description of the plan modifier. +func (m suppressDiff) Description(_ context.Context) string { + return "Once set, the value of this attribute in state will not change." +} + +// MarkdownDescription returns a markdown description of the plan modifier. +func (m suppressDiff) MarkdownDescription(_ context.Context) string { + return "Once set, the value of this attribute in state will not change." +} + +// PlanModifySet implements the plan modification logic. +func (m suppressDiff) PlanModifySet(ctx context.Context, req planmodifier.SetRequest, resp *planmodifier.SetResponse) { + // Do nothing if there is a known planned value. + if !req.PlanValue.IsUnknown() { + return + } + + // Do nothing if there is an unknown configuration value + if req.ConfigValue.IsUnknown() { + return + } + + if utils.IsAllStateUnknown(ctx, req.State) { + return + } + + resp.PlanValue = req.StateValue +} diff --git a/internal/planmodifiers/stringplanmodifier/suppress_diff.go b/internal/planmodifiers/stringplanmodifier/suppress_diff.go new file mode 100644 index 0000000..71ec8b7 --- /dev/null +++ b/internal/planmodifiers/stringplanmodifier/suppress_diff.go @@ -0,0 +1,47 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package stringplanmodifier + +import ( + "context" + "github.com/LukeHagar/terraform-provider-PlexAPI/internal/planmodifiers/utils" + + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" +) + +// SuppressDiff returns a plan modifier that propagates a state value into the planned value, when it is Known, and the Plan Value is Unknown +func SuppressDiff() planmodifier.String { + return suppressDiff{} +} + +// suppressDiff implements the plan modifier. +type suppressDiff struct{} + +// Description returns a human-readable description of the plan modifier. +func (m suppressDiff) Description(_ context.Context) string { + return "Once set, the value of this attribute in state will not change." +} + +// MarkdownDescription returns a markdown description of the plan modifier. +func (m suppressDiff) MarkdownDescription(_ context.Context) string { + return "Once set, the value of this attribute in state will not change." +} + +// PlanModifyString implements the plan modification logic. +func (m suppressDiff) PlanModifyString(ctx context.Context, req planmodifier.StringRequest, resp *planmodifier.StringResponse) { + // Do nothing if there is a known planned value. + if !req.PlanValue.IsUnknown() { + return + } + + // Do nothing if there is an unknown configuration value + if req.ConfigValue.IsUnknown() { + return + } + + if utils.IsAllStateUnknown(ctx, req.State) { + return + } + + resp.PlanValue = req.StateValue +} diff --git a/internal/planmodifiers/utils/state_check.go b/internal/planmodifiers/utils/state_check.go new file mode 100644 index 0000000..66d9150 --- /dev/null +++ b/internal/planmodifiers/utils/state_check.go @@ -0,0 +1,25 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package utils + +import ( + "context" + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/tfsdk" +) + +func IsAllStateUnknown(ctx context.Context, state tfsdk.State) bool { + attrs := state.Schema.GetAttributes() + anyFound := false + for k, _ := range attrs { + attrValue := new(attr.Value) + state.GetAttribute(ctx, path.Root(k), attrValue) + if attrValue != nil && !(*attrValue).IsUnknown() && !(*attrValue).IsNull() { + anyFound = true + break + } + } + + return !anyFound +} diff --git a/internal/provider/provider.go b/internal/provider/provider.go new file mode 100644 index 0000000..831e52a --- /dev/null +++ b/internal/provider/provider.go @@ -0,0 +1,98 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package provider + +import ( + "context" + "github.com/LukeHagar/terraform-provider-PlexAPI/internal/sdk" + "github.com/LukeHagar/terraform-provider-PlexAPI/internal/sdk/pkg/models/shared" + + "github.com/hashicorp/terraform-plugin-framework/datasource" + "github.com/hashicorp/terraform-plugin-framework/provider" + "github.com/hashicorp/terraform-plugin-framework/provider/schema" + "github.com/hashicorp/terraform-plugin-framework/resource" + "github.com/hashicorp/terraform-plugin-framework/types" +) + +var _ provider.Provider = &PlexAPIProvider{} + +type PlexAPIProvider struct { + // version is set to the provider version on release, "dev" when the + // provider is built and ran locally, and "test" when running acceptance + // testing. + version string +} + +// PlexAPIProviderModel describes the provider data model. +type PlexAPIProviderModel struct { + ServerURL types.String `tfsdk:"server_url"` + AccessToken types.String `tfsdk:"access_token"` +} + +func (p *PlexAPIProvider) Metadata(ctx context.Context, req provider.MetadataRequest, resp *provider.MetadataResponse) { + resp.TypeName = "PlexAPI" + resp.Version = p.version +} + +func (p *PlexAPIProvider) Schema(ctx context.Context, req provider.SchemaRequest, resp *provider.SchemaResponse) { + resp.Schema = schema.Schema{ + Description: `An Open API Spec for interacting with Plex.tv and Plex Servers`, + Attributes: map[string]schema.Attribute{ + "server_url": schema.StringAttribute{ + MarkdownDescription: "Server URL (defaults to http://10.10.10.47:32400)", + Optional: true, + Required: false, + }, + "access_token": schema.StringAttribute{ + Optional: true, + Sensitive: true, + }, + }, + } +} + +func (p *PlexAPIProvider) Configure(ctx context.Context, req provider.ConfigureRequest, resp *provider.ConfigureResponse) { + var data PlexAPIProviderModel + + resp.Diagnostics.Append(req.Config.Get(ctx, &data)...) + + if resp.Diagnostics.HasError() { + return + } + + ServerURL := data.ServerURL.ValueString() + + if ServerURL == "" { + ServerURL = "http://10.10.10.47:32400" + } + + accessToken := data.AccessToken.ValueString() + security := shared.Security{ + AccessToken: accessToken, + } + + opts := []sdk.SDKOption{ + sdk.WithServerURL(ServerURL), + sdk.WithSecurity(security), + } + client := sdk.New(opts...) + + resp.DataSourceData = client + resp.ResourceData = client +} + +func (p *PlexAPIProvider) Resources(ctx context.Context) []func() resource.Resource { + return []func() resource.Resource{} +} + +func (p *PlexAPIProvider) DataSources(ctx context.Context) []func() datasource.DataSource { + return []func() datasource.DataSource{} +} + +func New(version string) func() provider.Provider { + return func() provider.Provider { + return &PlexAPIProvider{ + version: version, + } + } +} diff --git a/internal/provider/reflect/diags.go b/internal/provider/reflect/diags.go new file mode 100644 index 0000000..a91bba9 --- /dev/null +++ b/internal/provider/reflect/diags.go @@ -0,0 +1,115 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package reflect + +import ( + "fmt" + "reflect" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +func toTerraform5ValueErrorDiag(err error, path path.Path) diag.DiagnosticWithPath { + return diag.NewAttributeErrorDiagnostic( + path, + "Value Conversion Error", + "An unexpected error was encountered trying to convert into a Terraform value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), + ) +} + +func toTerraformValueErrorDiag(err error, path path.Path) diag.DiagnosticWithPath { + return diag.NewAttributeErrorDiagnostic( + path, + "Value Conversion Error", + "An unexpected error was encountered trying to convert the Attribute value into a Terraform value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), + ) +} + +func validateValueErrorDiag(err error, path path.Path) diag.DiagnosticWithPath { + return diag.NewAttributeErrorDiagnostic( + path, + "Value Conversion Error", + "An unexpected error was encountered trying to validate the Terraform value type. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), + ) +} + +func valueFromTerraformErrorDiag(err error, path path.Path) diag.DiagnosticWithPath { + return diag.NewAttributeErrorDiagnostic( + path, + "Value Conversion Error", + "An unexpected error was encountered trying to convert the Terraform value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), + ) +} + +type DiagIntoIncompatibleType struct { + Val tftypes.Value + TargetType reflect.Type + Err error +} + +func (d DiagIntoIncompatibleType) Severity() diag.Severity { + return diag.SeverityError +} + +func (d DiagIntoIncompatibleType) Summary() string { + return "Value Conversion Error" +} + +func (d DiagIntoIncompatibleType) Detail() string { + return fmt.Sprintf("An unexpected error was encountered trying to convert %T into %s. This is always an error in the provider. Please report the following to the provider developer:\n\n%s", d.Val, d.TargetType, d.Err.Error()) +} + +func (d DiagIntoIncompatibleType) Equal(o diag.Diagnostic) bool { + od, ok := o.(DiagIntoIncompatibleType) + if !ok { + return false + } + if !d.Val.Equal(od.Val) { + return false + } + if d.TargetType != od.TargetType { + return false + } + if d.Err.Error() != od.Err.Error() { + return false + } + return true +} + +type DiagNewAttributeValueIntoWrongType struct { + ValType reflect.Type + TargetType reflect.Type + SchemaType attr.Type +} + +func (d DiagNewAttributeValueIntoWrongType) Severity() diag.Severity { + return diag.SeverityError +} + +func (d DiagNewAttributeValueIntoWrongType) Summary() string { + return "Value Conversion Error" +} + +func (d DiagNewAttributeValueIntoWrongType) Detail() string { + return fmt.Sprintf("An unexpected error was encountered trying to convert into a Terraform value. This is always an error in the provider. Please report the following to the provider developer:\n\nCannot use attr.Value %s, only %s is supported because %T is the type in the schema", d.TargetType, d.ValType, d.SchemaType) +} + +func (d DiagNewAttributeValueIntoWrongType) Equal(o diag.Diagnostic) bool { + od, ok := o.(DiagNewAttributeValueIntoWrongType) + if !ok { + return false + } + if d.ValType != od.ValType { + return false + } + if d.TargetType != od.TargetType { + return false + } + if !d.SchemaType.Equal(od.SchemaType) { + return false + } + return true +} diff --git a/internal/provider/reflect/doc.go b/internal/provider/reflect/doc.go new file mode 100644 index 0000000..ec91111 --- /dev/null +++ b/internal/provider/reflect/doc.go @@ -0,0 +1,9 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +// Package reflect is a forked version of https://github.com/hashicorp/terraform-plugin-framework/tree/main/internal/reflect +// that has been modified to support speakeasy's terraform generator. +// In particular, behaviour differs in that it is intended to support merging Terraform State and Terraform Plan structures +// into a single data structure, with Known Plan values overriding State values. This allows for code to be written +// that drives API calls from a single point of truth. +// Fork Commit hash is 99f28445b60580b6e39afda88a4bb469461f9bbb +package reflect diff --git a/internal/provider/reflect/generic_attr_value.go b/internal/provider/reflect/generic_attr_value.go new file mode 100644 index 0000000..430ce2f --- /dev/null +++ b/internal/provider/reflect/generic_attr_value.go @@ -0,0 +1,14 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package reflect + +import ( + "context" + "reflect" + + "github.com/hashicorp/terraform-plugin-framework/attr" +) + +func IsGenericAttrValue(ctx context.Context, target interface{}) bool { + return reflect.TypeOf((*attr.Value)(nil)) == reflect.TypeOf(target) +} diff --git a/internal/provider/reflect/helpers.go b/internal/provider/reflect/helpers.go new file mode 100644 index 0000000..82b9515 --- /dev/null +++ b/internal/provider/reflect/helpers.go @@ -0,0 +1,98 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package reflect + +import ( + "context" + "fmt" + "reflect" + "regexp" + "strings" + + "github.com/hashicorp/terraform-plugin-framework/path" +) + +// trueReflectValue returns the reflect.Value for `in` after derefencing all +// the pointers and unwrapping all the interfaces. It's the concrete value +// beneath it all. +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 +} + +// commaSeparatedString returns an English joining of the strings in `in`, +// using "and" and commas as appropriate. +func commaSeparatedString(in []string) string { + switch len(in) { + case 0: + return "" + case 1: + return in[0] + case 2: + return strings.Join(in, " and ") + default: + in[len(in)-1] = "and " + in[len(in)-1] + return strings.Join(in, ", ") + } +} + +// getStructTags returns a map of Terraform field names to their position in +// the tags of the struct `in`. `in` must be a struct. +func getStructTags(_ context.Context, in reflect.Value, path path.Path) (map[string]int, error) { + tags := map[string]int{} + typ := trueReflectValue(in).Type() + if typ.Kind() != reflect.Struct { + return nil, fmt.Errorf("%s: can't get struct tags of %s, is not a struct", path, in.Type()) + } + for i := 0; i < typ.NumField(); i++ { + field := typ.Field(i) + if field.PkgPath != "" { + // skip unexported fields + continue + } + tag := field.Tag.Get(`tfsdk`) + if tag == "-" { + // skip explicitly excluded fields + continue + } + if tag == "" { + return nil, fmt.Errorf(`%s: need a struct tag for "tfsdk" on %s`, path, field.Name) + } + path := path.AtName(tag) + if !isValidFieldName(tag) { + return nil, fmt.Errorf("%s: invalid field name, must only use lowercase letters, underscores, and numbers, and must start with a letter", path) + } + if other, ok := tags[tag]; ok { + return nil, fmt.Errorf("%s: can't use field name for both %s and %s", path, typ.Field(other).Name, field.Name) + } + tags[tag] = i + } + return tags, nil +} + +// isValidFieldName returns true if `name` can be used as a field name in a +// Terraform resource or data source. +func isValidFieldName(name string) bool { + re := regexp.MustCompile("^[a-z][a-z0-9_]*$") + return re.MatchString(name) +} + +// canBeNil returns true if `target`'s type can hold a nil value +func canBeNil(target reflect.Value) bool { + switch target.Kind() { + case reflect.Ptr, reflect.Slice, reflect.Map, reflect.Interface: + // these types can all hold nils + return true + default: + // nothing else can be set to nil + return false + } +} diff --git a/internal/provider/reflect/interfaces.go b/internal/provider/reflect/interfaces.go new file mode 100644 index 0000000..364ff86 --- /dev/null +++ b/internal/provider/reflect/interfaces.go @@ -0,0 +1,353 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package reflect + +import ( + "context" + "fmt" + "reflect" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/attr/xattr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// Unknownable is an interface for types that can be explicitly set to known or +// unknown. +type Unknownable interface { + SetUnknown(context.Context, bool) error + SetValue(context.Context, interface{}) error + GetUnknown(context.Context) bool + GetValue(context.Context) interface{} +} + +// NewUnknownable creates a zero value of `target` (or the concrete type it's +// referencing, if it's a pointer) and calls its SetUnknown method. +// +// It is meant to be called through Into, not directly. +func NewUnknownable(ctx context.Context, typ attr.Type, val tftypes.Value, target reflect.Value, opts Options, path path.Path) (reflect.Value, diag.Diagnostics) { + var diags diag.Diagnostics + receiver := pointerSafeZeroValue(ctx, target) + method := receiver.MethodByName("SetUnknown") + if !method.IsValid() { + err := fmt.Errorf("cannot find SetUnknown method on type %s", receiver.Type().String()) + diags.AddAttributeError( + path, + "Value Conversion Error", + "An unexpected error was encountered trying to convert value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), + ) + return target, diags + } + results := method.Call([]reflect.Value{ + reflect.ValueOf(ctx), + reflect.ValueOf(!val.IsKnown()), + }) + err := results[0].Interface() + if err != nil { + var underlyingErr error + switch e := err.(type) { + case error: + underlyingErr = e + default: + underlyingErr = fmt.Errorf("unknown error type %T: %v", e, e) + } + underlyingErr = fmt.Errorf("reflection error: %w", underlyingErr) + diags.AddAttributeError( + path, + "Value Conversion Error", + "An unexpected error was encountered trying to convert into a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+underlyingErr.Error(), + ) + return target, diags + } + return receiver, diags +} + +// FromUnknownable creates an attr.Value from the data in an Unknownable. +// +// It is meant to be called through FromValue, not directly. +func FromUnknownable(ctx context.Context, typ attr.Type, val Unknownable, path path.Path) (attr.Value, diag.Diagnostics) { + var diags diag.Diagnostics + + if val.GetUnknown(ctx) { + tfVal := tftypes.NewValue(typ.TerraformType(ctx), tftypes.UnknownValue) + + if typeWithValidate, ok := typ.(xattr.TypeWithValidate); ok { + diags.Append(typeWithValidate.Validate(ctx, tfVal, path)...) + + if diags.HasError() { + return nil, diags + } + } + + res, err := typ.ValueFromTerraform(ctx, tfVal) + if err != nil { + return nil, append(diags, valueFromTerraformErrorDiag(err, path)) + } + return res, nil + } + err := tftypes.ValidateValue(typ.TerraformType(ctx), val.GetValue(ctx)) + if err != nil { + return nil, append(diags, validateValueErrorDiag(err, path)) + } + + tfVal := tftypes.NewValue(typ.TerraformType(ctx), val.GetValue(ctx)) + + if typeWithValidate, ok := typ.(xattr.TypeWithValidate); ok { + diags.Append(typeWithValidate.Validate(ctx, tfVal, path)...) + + if diags.HasError() { + return nil, diags + } + } + + res, err := typ.ValueFromTerraform(ctx, tfVal) + if err != nil { + return nil, append(diags, valueFromTerraformErrorDiag(err, path)) + } + return res, nil +} + +// Nullable is an interface for types that can be explicitly set to null. +type Nullable interface { + SetNull(context.Context, bool) error + SetValue(context.Context, interface{}) error + GetNull(context.Context) bool + GetValue(context.Context) interface{} +} + +// NewNullable creates a zero value of `target` (or the concrete type it's +// referencing, if it's a pointer) and calls its SetNull method. +// +// It is meant to be called through Into, not directly. +func NewNullable(ctx context.Context, typ attr.Type, val tftypes.Value, target reflect.Value, opts Options, path path.Path) (reflect.Value, diag.Diagnostics) { + var diags diag.Diagnostics + receiver := pointerSafeZeroValue(ctx, target) + method := receiver.MethodByName("SetNull") + if !method.IsValid() { + err := fmt.Errorf("cannot find SetNull method on type %s", receiver.Type().String()) + diags.AddAttributeError( + path, + "Value Conversion Error", + "An unexpected error was encountered trying to convert value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), + ) + return target, diags + } + results := method.Call([]reflect.Value{ + reflect.ValueOf(ctx), + reflect.ValueOf(val.IsNull()), + }) + err := results[0].Interface() + if err != nil { + var underlyingErr error + switch e := err.(type) { + case error: + underlyingErr = e + default: + underlyingErr = fmt.Errorf("unknown error type: %T", e) + } + underlyingErr = fmt.Errorf("reflection error: %w", underlyingErr) + diags.AddAttributeError( + path, + "Value Conversion Error", + "An unexpected error was encountered trying to convert into a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+underlyingErr.Error(), + ) + return target, diags + } + return receiver, diags +} + +// FromNullable creates an attr.Value from the data in a Nullable. +// +// It is meant to be called through FromValue, not directly. +func FromNullable(ctx context.Context, typ attr.Type, val Nullable, path path.Path) (attr.Value, diag.Diagnostics) { + var diags diag.Diagnostics + + if val.GetNull(ctx) { + tfVal := tftypes.NewValue(typ.TerraformType(ctx), nil) + + if typeWithValidate, ok := typ.(xattr.TypeWithValidate); ok { + diags.Append(typeWithValidate.Validate(ctx, tfVal, path)...) + + if diags.HasError() { + return nil, diags + } + } + + res, err := typ.ValueFromTerraform(ctx, tfVal) + if err != nil { + return nil, append(diags, valueFromTerraformErrorDiag(err, path)) + } + return res, nil + } + err := tftypes.ValidateValue(typ.TerraformType(ctx), val.GetValue(ctx)) + if err != nil { + return nil, append(diags, validateValueErrorDiag(err, path)) + } + + tfVal := tftypes.NewValue(typ.TerraformType(ctx), val.GetValue(ctx)) + + if typeWithValidate, ok := typ.(xattr.TypeWithValidate); ok { + diags.Append(typeWithValidate.Validate(ctx, tfVal, path)...) + + if diags.HasError() { + return nil, diags + } + } + + res, err := typ.ValueFromTerraform(ctx, tfVal) + if err != nil { + return nil, append(diags, valueFromTerraformErrorDiag(err, path)) + } + return res, diags +} + +// NewValueConverter creates a zero value of `target` (or the concrete type +// it's referencing, if it's a pointer) and calls its FromTerraform5Value +// method. +// +// It is meant to be called through Into, not directly. +func NewValueConverter(ctx context.Context, typ attr.Type, val tftypes.Value, target reflect.Value, opts Options, path path.Path) (reflect.Value, diag.Diagnostics) { + var diags diag.Diagnostics + receiver := pointerSafeZeroValue(ctx, target) + method := receiver.MethodByName("FromTerraform5Value") + if !method.IsValid() { + err := fmt.Errorf("could not find FromTerraform5Type method on type %s", receiver.Type().String()) + diags.AddAttributeError( + path, + "Value Conversion Error", + "An unexpected error was encountered trying to convert into a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), + ) + return target, diags + } + results := method.Call([]reflect.Value{reflect.ValueOf(val)}) + err := results[0].Interface() + if err != nil { + var underlyingErr error + switch e := err.(type) { + case error: + underlyingErr = e + default: + underlyingErr = fmt.Errorf("unknown error type: %T", e) + } + underlyingErr = fmt.Errorf("reflection error: %w", underlyingErr) + diags.AddAttributeError( + path, + "Value Conversion Error", + "An unexpected error was encountered trying to convert into a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+underlyingErr.Error(), + ) + return target, diags + } + return receiver, diags +} + +// FromValueCreator creates an attr.Value from the data in a +// tftypes.ValueCreator, calling its ToTerraform5Value method and converting +// the result to an attr.Value using `typ`. +// +// It is meant to be called from FromValue, not directly. +func FromValueCreator(ctx context.Context, typ attr.Type, val tftypes.ValueCreator, path path.Path) (attr.Value, diag.Diagnostics) { + var diags diag.Diagnostics + raw, err := val.ToTerraform5Value() + if err != nil { + return nil, append(diags, toTerraform5ValueErrorDiag(err, path)) + } + err = tftypes.ValidateValue(typ.TerraformType(ctx), raw) + if err != nil { + return nil, append(diags, validateValueErrorDiag(err, path)) + } + tfVal := tftypes.NewValue(typ.TerraformType(ctx), raw) + + if typeWithValidate, ok := typ.(xattr.TypeWithValidate); ok { + diags.Append(typeWithValidate.Validate(ctx, tfVal, path)...) + + if diags.HasError() { + return nil, diags + } + } + + res, err := typ.ValueFromTerraform(ctx, tfVal) + if err != nil { + return nil, append(diags, valueFromTerraformErrorDiag(err, path)) + } + return res, diags +} + +// NewAttributeValue creates a new reflect.Value by calling the +// ValueFromTerraform method on `typ`. It will return an error if the returned +// `attr.Value` is not the same type as `target`. +// +// It is meant to be called through Into, not directly. +func NewAttributeValue(ctx context.Context, typ attr.Type, val tftypes.Value, target reflect.Value, opts Options, path path.Path) (reflect.Value, diag.Diagnostics) { + var diags diag.Diagnostics + + if typeWithValidate, ok := typ.(xattr.TypeWithValidate); ok { + diags.Append(typeWithValidate.Validate(ctx, val, path)...) + + if diags.HasError() { + return target, diags + } + } + + res, err := typ.ValueFromTerraform(ctx, val) + if err != nil { + return target, append(diags, valueFromTerraformErrorDiag(err, path)) + } + if reflect.TypeOf(res) != target.Type() { + diags.Append(diag.WithPath(path, DiagNewAttributeValueIntoWrongType{ + ValType: reflect.TypeOf(res), + TargetType: target.Type(), + SchemaType: typ, + })) + return target, diags + } + return reflect.ValueOf(res), diags +} + +// FromAttributeValue creates an attr.Value from an attr.Value. It just returns +// the attr.Value it is passed or an error if there is an unexpected mismatch +// between the attr.Type and attr.Value. +// +// It is meant to be called through FromValue, not directly. +func FromAttributeValue(ctx context.Context, typ attr.Type, val attr.Value, path path.Path) (attr.Value, diag.Diagnostics) { + var diags diag.Diagnostics + + // Since the reflection logic is a generic Go type implementation with + // user input, it is possible to get into awkward situations where + // the logic is expecting a certain type while a value may not be + // compatible. This check will ensure the framework raises its own + // error is there is a mismatch, rather than a terraform-plugin-go + // error or worse a panic. + // + // If this validation causes major issues, another option is to + // validate via tftypes.Type for both the type and value type. + if !typ.Equal(val.Type(ctx)) { + diags.AddAttributeError( + path, + "Value Conversion Error", + "An unexpected error was encountered while verifying an attribute value matched its expected type to prevent unexpected behavior or panics. "+ + "This is always an error in the provider. Please report the following to the provider developer:\n\n"+ + fmt.Sprintf("Expected type: %s\n", typ)+ + fmt.Sprintf("Value type: %s\n", val.Type(ctx))+ + fmt.Sprintf("Path: %s", path), + ) + + return nil, diags + } + + if typeWithValidate, ok := typ.(xattr.TypeWithValidate); ok { + tfVal, err := val.ToTerraformValue(ctx) + if err != nil { + return val, append(diags, toTerraformValueErrorDiag(err, path)) + } + + diags.Append(typeWithValidate.Validate(ctx, tfVal, path)...) + + if diags.HasError() { + return val, diags + } + } + + return val, diags +} diff --git a/internal/provider/reflect/into.go b/internal/provider/reflect/into.go new file mode 100644 index 0000000..c53d1be --- /dev/null +++ b/internal/provider/reflect/into.go @@ -0,0 +1,216 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package reflect + +import ( + "context" + "fmt" + "math/big" + "reflect" + + "github.com/hashicorp/terraform-plugin-go/tftypes" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/path" +) + +// Into uses the data in `val` to populate `target`, using the reflection +// package to recursively reflect into structs and slices. If `target` is an +// attr.Value, its assignment method will be used instead of reflecting. If +// `target` is a tftypes.ValueConverter, the FromTerraformValue method will be +// used instead of using reflection. Primitives are set using the val.As +// method. Structs use reflection: each exported struct field must have a +// "tfsdk" tag with the name of the field in the tftypes.Value, and all fields +// in the tftypes.Value must have a corresponding property in the struct. Into +// will be called for each struct field. Slices will have Into called for each +// element. +func Into(ctx context.Context, typ attr.Type, val tftypes.Value, target interface{}, opts Options, path path.Path) diag.Diagnostics { + var diags diag.Diagnostics + + v := reflect.ValueOf(target) + if v.Kind() != reflect.Ptr { + err := fmt.Errorf("target must be a pointer, got %T, which is a %s", target, v.Kind()) + diags.AddAttributeError( + path, + "Value Conversion Error", + fmt.Sprintf("An unexpected error was encountered trying to convert the value. This is always an error in the provider. Please report the following to the provider developer:\n\nPath: %s\nError: %s", path.String(), err.Error()), + ) + return diags + } + result, diags := BuildValue(ctx, typ, val, v.Elem(), opts, path) + if diags.HasError() { + return diags + } + v.Elem().Set(result) + return diags +} + +// BuildValue constructs a reflect.Value of the same type as `target`, +// populated with the data in `val`. It will defensively instantiate new values +// to set, making it safe for use with pointer types which may be nil. It tries +// to give consumers the ability to override its default behaviors wherever +// possible. +func BuildValue(ctx context.Context, typ attr.Type, val tftypes.Value, target reflect.Value, opts Options, path path.Path) (reflect.Value, diag.Diagnostics) { + var diags diag.Diagnostics + + // if this isn't a valid reflect.Value, bail before we accidentally + // panic + if !target.IsValid() { + err := fmt.Errorf("invalid target") + diags.AddAttributeError( + path, + "Value Conversion Error", + "An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), + ) + return target, diags + } + + // ------------------------- + // -- Fork Start ----------- + // ------------------------- + + if !val.IsKnown() { + return target, diags + } + + // ------------------------- + // -- Fork End - ----------- + // ------------------------- + + // if this is an attr.Value, build the type from that + if target.Type().Implements(reflect.TypeOf((*attr.Value)(nil)).Elem()) { + return NewAttributeValue(ctx, typ, val, target, opts, path) + } + // if this tells tftypes how to build an instance of it out of a + // tftypes.Value, well, that's what we want, so do that instead of our + // default logic. + if target.Type().Implements(reflect.TypeOf((*tftypes.ValueConverter)(nil)).Elem()) { + return NewValueConverter(ctx, typ, val, target, opts, path) + } + // if this can explicitly be set to unknown, do that + if target.Type().Implements(reflect.TypeOf((*Unknownable)(nil)).Elem()) { + res, unknownableDiags := NewUnknownable(ctx, typ, val, target, opts, path) + diags.Append(unknownableDiags...) + if diags.HasError() { + return target, diags + } + target = res + // only return if it's unknown; we want to call SetUnknown + // either way, but if the value is unknown, there's nothing + // else to do, so bail + if !val.IsKnown() { + return target, nil + } + } + // if this can explicitly be set to null, do that + if target.Type().Implements(reflect.TypeOf((*Nullable)(nil)).Elem()) { + res, nullableDiags := NewNullable(ctx, typ, val, target, opts, path) + diags.Append(nullableDiags...) + if diags.HasError() { + return target, diags + } + target = res + // only return if it's null; we want to call SetNull either + // way, but if the value is null, there's nothing else to do, + // so bail + if val.IsNull() { + return target, nil + } + } + // ------------------------- + // -- Fork Start ----------- + // ------------------------- + //if !val.IsKnown() { + // // we already handled unknown the only ways we can + // // we checked that target doesn't have a SetUnknown method we + // // can call + // // we checked that target isn't an attr.Value + // // all that's left to us now is to set it as an empty value or + // // throw an error, depending on what's in opts + // if !opts.UnhandledUnknownAsEmpty { + // diags.AddAttributeError( + // path, + // "Value Conversion Error", + // "An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ + // "Received unknown value, however the target type cannot handle unknown values. Use the corresponding `types` package type or a custom type that handles unknown values.\n\n"+ + // fmt.Sprintf("Path: %s\nTarget Type: %s\nSuggested Type: %s", path.String(), target.Type(), reflect.TypeOf(typ.ValueType(ctx))), + // ) + // return target, diags + // } + // // we want to set unhandled unknowns to the empty value + // return reflect.Zero(target.Type()), diags + //} + // ------------------------- + // -- Fork End - ----------- + // ------------------------- + + if val.IsNull() { + // we already handled null the only ways we can + // we checked that target doesn't have a SetNull method we can + // call + // we checked that target isn't an attr.Value + // all that's left to us now is to set it as an empty value or + // throw an error, depending on what's in opts + if canBeNil(target) || opts.UnhandledNullAsEmpty { + return reflect.Zero(target.Type()), nil + } + + diags.AddAttributeError( + path, + "Value Conversion Error", + "An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ + "Received null value, however the target type cannot handle null values. Use the corresponding `types` package type, a pointer type or a custom type that handles null values.\n\n"+ + fmt.Sprintf("Path: %s\nTarget Type: %s\nSuggested `types` Type: %s\nSuggested Pointer Type: *%s", path.String(), target.Type(), reflect.TypeOf(typ.ValueType(ctx)), target.Type()), + ) + + return target, diags + } + // *big.Float and *big.Int are technically pointers, but we want them + // handled as numbers + if target.Type() == reflect.TypeOf(big.NewFloat(0)) || target.Type() == reflect.TypeOf(big.NewInt(0)) { + return Number(ctx, typ, val, target, opts, path) + } + switch target.Kind() { + case reflect.Struct: + val, valDiags := Struct(ctx, typ, val, target, opts, path) + diags.Append(valDiags...) + return val, diags + case reflect.Bool, reflect.String: + val, valDiags := Primitive(ctx, typ, val, target, path) + diags.Append(valDiags...) + return val, diags + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, + reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, + reflect.Uint32, reflect.Uint64, reflect.Float32, reflect.Float64: + // numbers are the wooooorst and need their own special handling + // because we can't just hand them off to tftypes and also + // because we can't just make people use *big.Floats, because a + // nil *big.Float will crash everything if we don't handle it + // as a special case, so let's just special case numbers and + // let people use the types they want + val, valDiags := Number(ctx, typ, val, target, opts, path) + diags.Append(valDiags...) + return val, diags + case reflect.Slice: + val, valDiags := reflectSlice(ctx, typ, val, target, opts, path) + diags.Append(valDiags...) + return val, diags + case reflect.Map: + val, valDiags := Map(ctx, typ, val, target, opts, path) + diags.Append(valDiags...) + return val, diags + case reflect.Ptr: + val, valDiags := Pointer(ctx, typ, val, target, opts, path) + diags.Append(valDiags...) + return val, diags + default: + err := fmt.Errorf("don't know how to reflect %s into %s", val.Type(), target.Type()) + diags.AddAttributeError( + path, + "Value Conversion Error", + "An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), + ) + return target, diags + } +} diff --git a/internal/provider/reflect/map.go b/internal/provider/reflect/map.go new file mode 100644 index 0000000..3310d42 --- /dev/null +++ b/internal/provider/reflect/map.go @@ -0,0 +1,188 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package reflect + +import ( + "context" + "fmt" + "reflect" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/attr/xattr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// Map creates a map value that matches the type of `target`, and populates it +// with the contents of `val`. +func Map(ctx context.Context, typ attr.Type, val tftypes.Value, target reflect.Value, opts Options, path path.Path) (reflect.Value, diag.Diagnostics) { + var diags diag.Diagnostics + underlyingValue := trueReflectValue(target) + + // this only works with maps, so check that out first + if underlyingValue.Kind() != reflect.Map { + diags.Append(diag.WithPath(path, DiagIntoIncompatibleType{ + Val: val, + TargetType: target.Type(), + Err: fmt.Errorf("expected a map type, got %s", target.Type()), + })) + return target, diags + } + if !val.Type().Is(tftypes.Map{}) { + diags.Append(diag.WithPath(path, DiagIntoIncompatibleType{ + Val: val, + TargetType: target.Type(), + Err: fmt.Errorf("cannot reflect %s into a map, must be a map", val.Type().String()), + })) + return target, diags + } + elemTyper, ok := typ.(attr.TypeWithElementType) + if !ok { + diags.Append(diag.WithPath(path, DiagIntoIncompatibleType{ + Val: val, + TargetType: target.Type(), + Err: fmt.Errorf("cannot reflect map using type information provided by %T, %T must be an attr.TypeWithElementType", typ, typ), + })) + return target, diags + } + + // we need our value to become a map of values so we can iterate over + // them and handle them individually + values := map[string]tftypes.Value{} + err := val.As(&values) + if err != nil { + diags.Append(diag.WithPath(path, DiagIntoIncompatibleType{ + Val: val, + TargetType: target.Type(), + Err: err, + })) + return target, diags + } + + // we need to know the type the slice is wrapping + elemType := underlyingValue.Type().Elem() + elemAttrType := elemTyper.ElementType() + + // we want an empty version of the map + m := reflect.MakeMapWithSize(underlyingValue.Type(), len(values)) + + // go over each of the values passed in, create a Go value of the right + // type for them, and add it to our new map + for key, value := range values { + // create a new Go value of the type that can go in the map + targetValue := reflect.Zero(elemType) + + // update our path so we can have nice errors + path := path.AtMapKey(key) + + // reflect the value into our new target + result, elemDiags := BuildValue(ctx, elemAttrType, value, targetValue, opts, path) + diags.Append(elemDiags...) + + if diags.HasError() { + return target, diags + } + + m.SetMapIndex(reflect.ValueOf(key), result) + } + + return m, diags +} + +// FromMap returns an attr.Value representing the data contained in `val`. +// `val` must be a map type with keys that are a string type. The attr.Value +// will be of the type produced by `typ`. +// +// It is meant to be called through FromValue, not directly. +func FromMap(ctx context.Context, typ attr.TypeWithElementType, val reflect.Value, path path.Path) (attr.Value, diag.Diagnostics) { + var diags diag.Diagnostics + tfType := typ.TerraformType(ctx) + + if val.IsNil() { + tfVal := tftypes.NewValue(tfType, nil) + + if typeWithValidate, ok := typ.(xattr.TypeWithValidate); ok { + diags.Append(typeWithValidate.Validate(ctx, tfVal, path)...) + + if diags.HasError() { + return nil, diags + } + } + + attrVal, err := typ.ValueFromTerraform(ctx, tfVal) + + if err != nil { + diags.AddAttributeError( + path, + "Value Conversion Error", + "An unexpected error was encountered trying to convert from map value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), + ) + return nil, diags + } + + return attrVal, diags + } + + elemType := typ.ElementType() + tfElems := map[string]tftypes.Value{} + for _, key := range val.MapKeys() { + if key.Kind() != reflect.String { + err := fmt.Errorf("map keys must be strings, got %s", key.Type()) + diags.AddAttributeError( + path, + "Value Conversion Error", + "An unexpected error was encountered trying to convert into a Terraform value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), + ) + return nil, diags + } + val, valDiags := FromValue(ctx, elemType, val.MapIndex(key).Interface(), path.AtMapKey(key.String())) + diags.Append(valDiags...) + + if diags.HasError() { + return nil, diags + } + tfVal, err := val.ToTerraformValue(ctx) + if err != nil { + return nil, append(diags, toTerraformValueErrorDiag(err, path)) + } + + if typeWithValidate, ok := elemType.(xattr.TypeWithValidate); ok { + diags.Append(typeWithValidate.Validate(ctx, tfVal, path.AtMapKey(key.String()))...) + + if diags.HasError() { + return nil, diags + } + } + + tfElems[key.String()] = tfVal + } + + err := tftypes.ValidateValue(tfType, tfElems) + if err != nil { + return nil, append(diags, validateValueErrorDiag(err, path)) + } + + tfVal := tftypes.NewValue(tfType, tfElems) + + if typeWithValidate, ok := typ.(xattr.TypeWithValidate); ok { + diags.Append(typeWithValidate.Validate(ctx, tfVal, path)...) + + if diags.HasError() { + return nil, diags + } + } + + attrVal, err := typ.ValueFromTerraform(ctx, tfVal) + + if err != nil { + diags.AddAttributeError( + path, + "Value Conversion Error", + "An unexpected error was encountered trying to convert to map value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), + ) + return nil, diags + } + + return attrVal, diags +} diff --git a/internal/provider/reflect/number.go b/internal/provider/reflect/number.go new file mode 100644 index 0000000..37eef21 --- /dev/null +++ b/internal/provider/reflect/number.go @@ -0,0 +1,374 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package reflect + +import ( + "context" + "fmt" + "math" + "math/big" + "reflect" + "strconv" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/attr/xattr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// Number creates a *big.Float and populates it with the data in `val`. It then +// gets converted to the type of `target`, as long as `target` is a valid +// number type (any of the built-in int, uint, or float types, *big.Float, and +// *big.Int). +// +// Number will loudly fail when a number cannot be losslessly represented using +// the requested type, unless opts.AllowRoundingNumbers is set to true. This +// setting is mildly dangerous, because Terraform does not like when you round +// things, as a general rule of thumb. +// +// It is meant to be called through Into, not directly. +func Number(ctx context.Context, typ attr.Type, val tftypes.Value, target reflect.Value, opts Options, path path.Path) (reflect.Value, diag.Diagnostics) { + var diags diag.Diagnostics + result := big.NewFloat(0) + err := val.As(&result) + if err != nil { + diags.Append(diag.WithPath(path, DiagIntoIncompatibleType{ + Err: err, + TargetType: target.Type(), + Val: val, + })) + return target, diags + } + roundingError := fmt.Errorf("cannot store %s in %s", result.String(), target.Type()) + roundingErrorDiag := diag.NewAttributeErrorDiagnostic( + path, + "Value Conversion Error", + "An unexpected error was encountered trying to convert to number. This is always an error in the provider. Please report the following to the provider developer:\n\n"+roundingError.Error(), + ) + + switch target.Type() { + case reflect.TypeOf(big.NewFloat(0)): + return reflect.ValueOf(result), diags + case reflect.TypeOf(big.NewInt(0)): + intResult, acc := result.Int(nil) + if acc != big.Exact && !opts.AllowRoundingNumbers { + return reflect.ValueOf(result), append(diags, roundingErrorDiag) + } + return reflect.ValueOf(intResult), diags + } + switch target.Kind() { + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, + reflect.Int64: + intResult, acc := result.Int64() + if acc != big.Exact && !opts.AllowRoundingNumbers { + return target, append(diags, roundingErrorDiag) + } + switch target.Kind() { + case reflect.Int: + if strconv.IntSize == 32 && intResult > math.MaxInt32 { + if !opts.AllowRoundingNumbers { + return target, append(diags, roundingErrorDiag) + } + intResult = math.MaxInt32 + } + if strconv.IntSize == 32 && intResult < math.MinInt32 { + if !opts.AllowRoundingNumbers { + return target, append(diags, roundingErrorDiag) + } + intResult = math.MinInt32 + } + return reflect.ValueOf(int(intResult)), diags + case reflect.Int8: + if intResult > math.MaxInt8 { + if !opts.AllowRoundingNumbers { + return target, append(diags, roundingErrorDiag) + } + intResult = math.MaxInt8 + } + if intResult < math.MinInt8 { + if !opts.AllowRoundingNumbers { + return target, append(diags, roundingErrorDiag) + } + intResult = math.MinInt8 + } + return reflect.ValueOf(int8(intResult)), diags + case reflect.Int16: + if intResult > math.MaxInt16 { + if !opts.AllowRoundingNumbers { + return target, append(diags, roundingErrorDiag) + } + intResult = math.MaxInt16 + } + if intResult < math.MinInt16 { + if !opts.AllowRoundingNumbers { + return target, append(diags, roundingErrorDiag) + } + intResult = math.MinInt16 + } + return reflect.ValueOf(int16(intResult)), diags + case reflect.Int32: + if intResult > math.MaxInt32 { + if !opts.AllowRoundingNumbers { + return target, append(diags, roundingErrorDiag) + } + intResult = math.MaxInt32 + } + if intResult < math.MinInt32 { + if !opts.AllowRoundingNumbers { + return target, append(diags, roundingErrorDiag) + } + intResult = math.MinInt32 + } + return reflect.ValueOf(int32(intResult)), diags + case reflect.Int64: + return reflect.ValueOf(intResult), diags + } + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, + reflect.Uint64: + uintResult, acc := result.Uint64() + if acc != big.Exact && !opts.AllowRoundingNumbers { + return target, append(diags, roundingErrorDiag) + } + switch target.Kind() { + case reflect.Uint: + if strconv.IntSize == 32 && uintResult > math.MaxUint32 { + if !opts.AllowRoundingNumbers { + return target, append(diags, roundingErrorDiag) + } + uintResult = math.MaxUint32 + } + return reflect.ValueOf(uint(uintResult)), diags + case reflect.Uint8: + if uintResult > math.MaxUint8 { + if !opts.AllowRoundingNumbers { + return target, append(diags, roundingErrorDiag) + } + uintResult = math.MaxUint8 + } + return reflect.ValueOf(uint8(uintResult)), diags + case reflect.Uint16: + if uintResult > math.MaxUint16 { + if !opts.AllowRoundingNumbers { + return target, append(diags, roundingErrorDiag) + } + uintResult = math.MaxUint16 + } + return reflect.ValueOf(uint16(uintResult)), diags + case reflect.Uint32: + if uintResult > math.MaxUint32 { + if !opts.AllowRoundingNumbers { + return target, append(diags, roundingErrorDiag) + } + uintResult = math.MaxUint32 + } + return reflect.ValueOf(uint32(uintResult)), diags + case reflect.Uint64: + return reflect.ValueOf(uintResult), diags + } + case reflect.Float32: + floatResult, acc := result.Float32() + if acc != big.Exact && !opts.AllowRoundingNumbers { + return target, append(diags, roundingErrorDiag) + } else if acc == big.Above { + floatResult = math.MaxFloat32 + } else if acc == big.Below { + floatResult = math.SmallestNonzeroFloat32 + } else if acc != big.Exact { + err := fmt.Errorf("unsure how to round %s and %f", acc, floatResult) + diags.AddAttributeError( + path, + "Value Conversion Error", + "An unexpected error was encountered trying to convert to number. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), + ) + return target, diags + } + return reflect.ValueOf(floatResult), diags + case reflect.Float64: + floatResult, acc := result.Float64() + if acc != big.Exact && !opts.AllowRoundingNumbers { + return target, append(diags, roundingErrorDiag) + } + if acc == big.Above { + if floatResult == math.Inf(1) || floatResult == math.MaxFloat64 { + floatResult = math.MaxFloat64 + } else if floatResult == 0.0 || floatResult == math.SmallestNonzeroFloat64 { + floatResult = -math.SmallestNonzeroFloat64 + } else { + err := fmt.Errorf("not sure how to round %s and %f", acc, floatResult) + diags.AddAttributeError( + path, + "Value Conversion Error", + "An unexpected error was encountered trying to convert to number. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), + ) + return target, diags + } + } else if acc == big.Below { + if floatResult == math.Inf(-1) || floatResult == -math.MaxFloat64 { + floatResult = -math.MaxFloat64 + } else if floatResult == 0.0 || floatResult == -math.SmallestNonzeroFloat64 { + floatResult = math.SmallestNonzeroFloat64 + } else { + err := fmt.Errorf("not sure how to round %s and %f", acc, floatResult) + diags.AddAttributeError( + path, + "Value Conversion Error", + "An unexpected error was encountered trying to convert to number. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), + ) + return target, diags + } + } else if acc != big.Exact { + err := fmt.Errorf("not sure how to round %s and %f", acc, floatResult) + diags.AddAttributeError( + path, + "Value Conversion Error", + "An unexpected error was encountered trying to convert to number. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), + ) + return target, diags + } + return reflect.ValueOf(floatResult), diags + } + err = fmt.Errorf("cannot convert number to %s", target.Type()) + diags.AddAttributeError( + path, + "Value Conversion Error", + "An unexpected error was encountered trying to convert to number. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), + ) + return target, diags +} + +// FromInt creates an attr.Value using `typ` from an int64. +// +// It is meant to be called through FromValue, not directly. +func FromInt(ctx context.Context, typ attr.Type, val int64, path path.Path) (attr.Value, diag.Diagnostics) { + var diags diag.Diagnostics + err := tftypes.ValidateValue(tftypes.Number, val) + if err != nil { + return nil, append(diags, validateValueErrorDiag(err, path)) + } + tfNum := tftypes.NewValue(tftypes.Number, val) + + if typeWithValidate, ok := typ.(xattr.TypeWithValidate); ok { + diags.Append(typeWithValidate.Validate(ctx, tfNum, path)...) + + if diags.HasError() { + return nil, diags + } + } + + num, err := typ.ValueFromTerraform(ctx, tfNum) + if err != nil { + return nil, append(diags, valueFromTerraformErrorDiag(err, path)) + } + + return num, diags +} + +// FromUint creates an attr.Value using `typ` from a uint64. +// +// It is meant to be called through FromValue, not directly. +func FromUint(ctx context.Context, typ attr.Type, val uint64, path path.Path) (attr.Value, diag.Diagnostics) { + var diags diag.Diagnostics + err := tftypes.ValidateValue(tftypes.Number, val) + if err != nil { + return nil, append(diags, validateValueErrorDiag(err, path)) + } + tfNum := tftypes.NewValue(tftypes.Number, val) + + if typeWithValidate, ok := typ.(xattr.TypeWithValidate); ok { + diags.Append(typeWithValidate.Validate(ctx, tfNum, path)...) + + if diags.HasError() { + return nil, diags + } + } + + num, err := typ.ValueFromTerraform(ctx, tfNum) + if err != nil { + return nil, append(diags, valueFromTerraformErrorDiag(err, path)) + } + + return num, diags +} + +// FromFloat creates an attr.Value using `typ` from a float64. +// +// It is meant to be called through FromValue, not directly. +func FromFloat(ctx context.Context, typ attr.Type, val float64, path path.Path) (attr.Value, diag.Diagnostics) { + var diags diag.Diagnostics + err := tftypes.ValidateValue(tftypes.Number, val) + if err != nil { + return nil, append(diags, validateValueErrorDiag(err, path)) + } + tfNum := tftypes.NewValue(tftypes.Number, val) + + if typeWithValidate, ok := typ.(xattr.TypeWithValidate); ok { + diags.Append(typeWithValidate.Validate(ctx, tfNum, path)...) + + if diags.HasError() { + return nil, diags + } + } + + num, err := typ.ValueFromTerraform(ctx, tfNum) + if err != nil { + return nil, append(diags, valueFromTerraformErrorDiag(err, path)) + } + + return num, diags +} + +// FromBigFloat creates an attr.Value using `typ` from a *big.Float. +// +// It is meant to be called through FromValue, not directly. +func FromBigFloat(ctx context.Context, typ attr.Type, val *big.Float, path path.Path) (attr.Value, diag.Diagnostics) { + var diags diag.Diagnostics + err := tftypes.ValidateValue(tftypes.Number, val) + if err != nil { + return nil, append(diags, validateValueErrorDiag(err, path)) + } + tfNum := tftypes.NewValue(tftypes.Number, val) + + if typeWithValidate, ok := typ.(xattr.TypeWithValidate); ok { + diags.Append(typeWithValidate.Validate(ctx, tfNum, path)...) + + if diags.HasError() { + return nil, diags + } + } + + num, err := typ.ValueFromTerraform(ctx, tfNum) + if err != nil { + return nil, append(diags, valueFromTerraformErrorDiag(err, path)) + } + + return num, diags +} + +// FromBigInt creates an attr.Value using `typ` from a *big.Int. +// +// It is meant to be called through FromValue, not directly. +func FromBigInt(ctx context.Context, typ attr.Type, val *big.Int, path path.Path) (attr.Value, diag.Diagnostics) { + var diags diag.Diagnostics + fl := big.NewFloat(0).SetInt(val) + err := tftypes.ValidateValue(tftypes.Number, fl) + if err != nil { + return nil, append(diags, validateValueErrorDiag(err, path)) + } + tfNum := tftypes.NewValue(tftypes.Number, fl) + + if typeWithValidate, ok := typ.(xattr.TypeWithValidate); ok { + diags.Append(typeWithValidate.Validate(ctx, tfNum, path)...) + + if diags.HasError() { + return nil, diags + } + } + + num, err := typ.ValueFromTerraform(ctx, tfNum) + if err != nil { + return nil, append(diags, valueFromTerraformErrorDiag(err, path)) + } + + return num, diags +} diff --git a/internal/provider/reflect/options.go b/internal/provider/reflect/options.go new file mode 100644 index 0000000..490c5f1 --- /dev/null +++ b/internal/provider/reflect/options.go @@ -0,0 +1,22 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package reflect + +// Options provides configuration settings for how the reflection behavior +// works, letting callers tweak different behaviors based on their needs. +type Options struct { + // UnhandledNullAsEmpty controls whether null values should be + // translated into empty values without provider interaction, or if + // they must be explicitly handled. + UnhandledNullAsEmpty bool + + // UnhandledUnknownAsEmpty controls whether null values should be + // translated into empty values without provider interaction, or if + // they must be explicitly handled. + UnhandledUnknownAsEmpty bool + + // AllowRoundingNumbers silently rounds numbers that don't fit + // perfectly in the types they're being stored in, rather than + // returning errors. Numbers will always be rounded towards 0. + AllowRoundingNumbers bool +} diff --git a/internal/provider/reflect/outof.go b/internal/provider/reflect/outof.go new file mode 100644 index 0000000..7852781 --- /dev/null +++ b/internal/provider/reflect/outof.go @@ -0,0 +1,94 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package reflect + +import ( + "context" + "fmt" + "math/big" + "reflect" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// FromValue is the inverse of Into, taking a Go value (`val`) and transforming it +// into an attr.Value using the attr.Type supplied. `val` will first be +// transformed into a tftypes.Value, then passed to `typ`'s ValueFromTerraform +// method. +func FromValue(ctx context.Context, typ attr.Type, val interface{}, path path.Path) (attr.Value, diag.Diagnostics) { + var diags diag.Diagnostics + + if v, ok := val.(attr.Value); ok { + return FromAttributeValue(ctx, typ, v, path) + } + if v, ok := val.(tftypes.ValueCreator); ok { + return FromValueCreator(ctx, typ, v, path) + } + if v, ok := val.(Unknownable); ok { + return FromUnknownable(ctx, typ, v, path) + } + if v, ok := val.(Nullable); ok { + return FromNullable(ctx, typ, v, path) + } + if bf, ok := val.(*big.Float); ok { + return FromBigFloat(ctx, typ, bf, path) + } + if bi, ok := val.(*big.Int); ok { + return FromBigInt(ctx, typ, bi, path) + } + value := reflect.ValueOf(val) + kind := value.Kind() + switch kind { + case reflect.Struct: + t, ok := typ.(attr.TypeWithAttributeTypes) + if !ok { + err := fmt.Errorf("cannot use type %T as schema type %T; %T must be an attr.TypeWithAttributeTypes to hold %T", val, typ, typ, val) + diags.AddAttributeError( + path, + "Value Conversion Error", + "An unexpected error was encountered trying to convert from value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), + ) + return nil, diags + } + return FromStruct(ctx, t, value, path) + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, + reflect.Int64: + return FromInt(ctx, typ, value.Int(), path) + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, + reflect.Uint64: + return FromUint(ctx, typ, value.Uint(), path) + case reflect.Float32, reflect.Float64: + return FromFloat(ctx, typ, value.Float(), path) + case reflect.Bool: + return FromBool(ctx, typ, value.Bool(), path) + case reflect.String: + return FromString(ctx, typ, value.String(), path) + case reflect.Slice: + return FromSlice(ctx, typ, value, path) + case reflect.Map: + t, ok := typ.(attr.TypeWithElementType) + if !ok { + err := fmt.Errorf("cannot use type %T as schema type %T; %T must be an attr.TypeWithElementType to hold %T", val, typ, typ, val) + diags.AddAttributeError( + path, + "Value Conversion Error", + "An unexpected error was encountered trying to convert from value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), + ) + return nil, diags + } + return FromMap(ctx, t, value, path) + case reflect.Ptr: + return FromPointer(ctx, typ, value, path) + default: + err := fmt.Errorf("cannot construct attr.Type from %T (%s)", val, kind) + diags.AddAttributeError( + path, + "Value Conversion Error", + "An unexpected error was encountered trying to convert from value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), + ) + return nil, diags + } +} diff --git a/internal/provider/reflect/pointer.go b/internal/provider/reflect/pointer.go new file mode 100644 index 0000000..e02c9eb --- /dev/null +++ b/internal/provider/reflect/pointer.go @@ -0,0 +1,126 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package reflect + +import ( + "context" + "fmt" + "reflect" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/attr/xattr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// Pointer builds a new zero value of the concrete type that `target` +// references, populates it with BuildValue, and takes a pointer to it. +// +// It is meant to be called through Into, not directly. +func Pointer(ctx context.Context, typ attr.Type, val tftypes.Value, target reflect.Value, opts Options, path path.Path) (reflect.Value, diag.Diagnostics) { + var diags diag.Diagnostics + + if target.Kind() != reflect.Ptr { + diags.Append(diag.WithPath(path, DiagIntoIncompatibleType{ + Val: val, + TargetType: target.Type(), + Err: fmt.Errorf("cannot dereference pointer, not a pointer, is a %s (%s)", target.Type(), target.Kind()), + })) + return target, diags + } + // we may have gotten a nil pointer, so we need to create our own that + // we can set + // FORK START + pointer := target + if target.IsNil() { + pointer = reflect.New(target.Type().Elem()) + } + // FORK END + // build out whatever the pointer is pointing to + pointed, pointedDiags := BuildValue(ctx, typ, val, pointer.Elem(), opts, path) + diags.Append(pointedDiags...) + + if diags.HasError() { + return target, diags + } + // to be able to set the pointer to our new pointer, we need to create + // a pointer to the pointer + pointerPointer := reflect.New(pointer.Type()) + // we set the pointer we created on the pointer to the pointer + pointerPointer.Elem().Set(pointer) + // then it's settable, so we can now set the concrete value we created + // on the pointer + pointerPointer.Elem().Elem().Set(pointed) + // return the pointer we created + return pointerPointer.Elem(), diags +} + +// create a zero value of concrete type underlying any number of pointers, then +// wrap it in that number of pointers again. The end result is to wind up with +// the same exact type, except now you can be sure it's pointing to actual data +// and will not give you a nil pointer dereference panic unexpectedly. +func pointerSafeZeroValue(_ context.Context, target reflect.Value) reflect.Value { + pointer := target.Type() + var pointers int + for pointer.Kind() == reflect.Ptr { + pointer = pointer.Elem() + pointers++ + } + receiver := reflect.Zero(pointer) + for i := 0; i < pointers; i++ { + newReceiver := reflect.New(receiver.Type()) + newReceiver.Elem().Set(receiver) + receiver = newReceiver + } + return receiver +} + +// FromPointer turns a pointer into an attr.Value using `typ`. If the pointer +// is nil, the attr.Value will use its null representation. If it is not nil, +// it will recurse into FromValue to find the attr.Value of the type the value +// the pointer is referencing. +// +// It is meant to be called through FromValue, not directly. +func FromPointer(ctx context.Context, typ attr.Type, value reflect.Value, path path.Path) (attr.Value, diag.Diagnostics) { + var diags diag.Diagnostics + + if value.Kind() != reflect.Ptr { + err := fmt.Errorf("cannot use type %s as a pointer", value.Type()) + diags.AddAttributeError( + path, + "Value Conversion Error", + "An unexpected error was encountered trying to convert from pointer value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), + ) + return nil, diags + } + if value.IsNil() { + tfVal := tftypes.NewValue(typ.TerraformType(ctx), nil) + + if typeWithValidate, ok := typ.(xattr.TypeWithValidate); ok { + diags.Append(typeWithValidate.Validate(ctx, tfVal, path)...) + + if diags.HasError() { + return nil, diags + } + } + + attrVal, err := typ.ValueFromTerraform(ctx, tfVal) + + if err != nil { + diags.AddAttributeError( + path, + "Value Conversion Error", + "An unexpected error was encountered trying to convert from pointer value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), + ) + return nil, diags + } + + return attrVal, diags + } + + attrVal, attrValDiags := FromValue(ctx, typ, value.Elem().Interface(), path) + diags.Append(attrValDiags...) + + return attrVal, diags +} diff --git a/internal/provider/reflect/primitive.go b/internal/provider/reflect/primitive.go new file mode 100644 index 0000000..3113c39 --- /dev/null +++ b/internal/provider/reflect/primitive.go @@ -0,0 +1,111 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package reflect + +import ( + "context" + "errors" + "reflect" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/attr/xattr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// Primitive builds a string or boolean, depending on the type of `target`, and +// populates it with the data in `val`. +// +// It is meant to be called through `Into`, not directly. +func Primitive(ctx context.Context, typ attr.Type, val tftypes.Value, target reflect.Value, path path.Path) (reflect.Value, diag.Diagnostics) { + var diags diag.Diagnostics + + switch target.Kind() { + case reflect.Bool: + var b bool + err := val.As(&b) + if err != nil { + diags.Append(diag.WithPath(path, DiagIntoIncompatibleType{ + Val: val, + TargetType: target.Type(), + Err: err, + })) + return target, diags + } + return reflect.ValueOf(b).Convert(target.Type()), nil + case reflect.String: + var s string + err := val.As(&s) + if err != nil { + diags.Append(diag.WithPath(path, DiagIntoIncompatibleType{ + Val: val, + TargetType: target.Type(), + Err: err, + })) + return target, diags + } + return reflect.ValueOf(s).Convert(target.Type()), nil + default: + diags.Append(diag.WithPath(path, DiagIntoIncompatibleType{ + Val: val, + TargetType: target.Type(), + Err: errors.New("unknown type"), + })) + return target, diags + } +} + +// FromString returns an attr.Value as produced by `typ` from a string. +// +// It is meant to be called through FromValue, not directly. +func FromString(ctx context.Context, typ attr.Type, val string, path path.Path) (attr.Value, diag.Diagnostics) { + var diags diag.Diagnostics + err := tftypes.ValidateValue(tftypes.String, val) + if err != nil { + return nil, append(diags, validateValueErrorDiag(err, path)) + } + tfStr := tftypes.NewValue(tftypes.String, val) + + if typeWithValidate, ok := typ.(xattr.TypeWithValidate); ok { + diags.Append(typeWithValidate.Validate(ctx, tfStr, path)...) + + if diags.HasError() { + return nil, diags + } + } + + str, err := typ.ValueFromTerraform(ctx, tfStr) + if err != nil { + return nil, append(diags, valueFromTerraformErrorDiag(err, path)) + } + + return str, diags +} + +// FromBool returns an attr.Value as produced by `typ` from a bool. +// +// It is meant to be called through FromValue, not directly. +func FromBool(ctx context.Context, typ attr.Type, val bool, path path.Path) (attr.Value, diag.Diagnostics) { + var diags diag.Diagnostics + err := tftypes.ValidateValue(tftypes.Bool, val) + if err != nil { + return nil, append(diags, validateValueErrorDiag(err, path)) + } + tfBool := tftypes.NewValue(tftypes.Bool, val) + + if typeWithValidate, ok := typ.(xattr.TypeWithValidate); ok { + diags.Append(typeWithValidate.Validate(ctx, tfBool, path)...) + + if diags.HasError() { + return nil, diags + } + } + + b, err := typ.ValueFromTerraform(ctx, tfBool) + if err != nil { + return nil, append(diags, valueFromTerraformErrorDiag(err, path)) + } + + return b, diags +} diff --git a/internal/provider/reflect/slice.go b/internal/provider/reflect/slice.go new file mode 100644 index 0000000..b91f729 --- /dev/null +++ b/internal/provider/reflect/slice.go @@ -0,0 +1,214 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package reflect + +import ( + "context" + "fmt" + "reflect" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/attr/xattr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// build a slice of elements, matching the type of `target`, and fill it with +// the data in `val`. +func reflectSlice(ctx context.Context, typ attr.Type, val tftypes.Value, target reflect.Value, opts Options, path path.Path) (reflect.Value, diag.Diagnostics) { + var diags diag.Diagnostics + + // this only works with slices, so check that out first + if target.Kind() != reflect.Slice { + diags.Append(diag.WithPath(path, DiagIntoIncompatibleType{ + Val: val, + TargetType: target.Type(), + Err: fmt.Errorf("expected a slice type, got %s", target.Type()), + })) + return target, diags + } + // TODO: check that the val is a list or set or tuple + elemTyper, ok := typ.(attr.TypeWithElementType) + if !ok { + diags.Append(diag.WithPath(path, DiagIntoIncompatibleType{ + Val: val, + TargetType: target.Type(), + Err: fmt.Errorf("cannot reflect %s using type information provided by %T, %T must be an attr.TypeWithElementType", val.Type(), typ, typ), + })) + return target, diags + } + + // we need our value to become a list of values so we can iterate over + // them and handle them individually + var values []tftypes.Value + err := val.As(&values) + if err != nil { + diags.Append(diag.WithPath(path, DiagIntoIncompatibleType{ + Val: val, + TargetType: target.Type(), + Err: err, + })) + return target, diags + } + + // we need to know the type the slice is wrapping + elemType := target.Type().Elem() + elemAttrType := elemTyper.ElementType() + + // we want an empty version of the slice + slice := reflect.MakeSlice(target.Type(), 0, len(values)) + + // go over each of the values passed in, create a Go value of the right + // type for them, and add it to our new slice + for pos, value := range values { + // create a new Go value of the type that can go in the slice + targetValue := reflect.Zero(elemType) + + // update our path so we can have nice errors + valPath := path.AtListIndex(pos) + + if typ.TerraformType(ctx).Is(tftypes.Set{}) { + attrVal, err := elemAttrType.ValueFromTerraform(ctx, value) + + if err != nil { + diags.AddAttributeError( + path, + "Value Conversion Error", + "An unexpected error was encountered trying to convert to slice value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), + ) + return target, diags + } + + valPath = path.AtSetValue(attrVal) + } + + // reflect the value into our new target + val, valDiags := BuildValue(ctx, elemAttrType, value, targetValue, opts, valPath) + diags.Append(valDiags...) + + if diags.HasError() { + return target, diags + } + + // add the new target to our slice + slice = reflect.Append(slice, val) + } + + return slice, diags +} + +// FromSlice returns an attr.Value as produced by `typ` using the data in +// `val`. `val` must be a slice. `typ` must be an attr.TypeWithElementType or +// attr.TypeWithElementTypes. If the slice is nil, the representation of null +// for `typ` will be returned. Otherwise, FromSlice will recurse into FromValue +// for each element in the slice, using the element type or types defined on +// `typ` to construct values for them. +// +// It is meant to be called through FromValue, not directly. +func FromSlice(ctx context.Context, typ attr.Type, val reflect.Value, path path.Path) (attr.Value, diag.Diagnostics) { + var diags diag.Diagnostics + + // TODO: support tuples, which are attr.TypeWithElementTypes + tfType := typ.TerraformType(ctx) + + if val.IsNil() { + tfVal := tftypes.NewValue(tfType, nil) + + if typeWithValidate, ok := typ.(xattr.TypeWithValidate); ok { + diags.Append(typeWithValidate.Validate(ctx, tfVal, path)...) + + if diags.HasError() { + return nil, diags + } + } + + attrVal, err := typ.ValueFromTerraform(ctx, tfVal) + + if err != nil { + diags.AddAttributeError( + path, + "Value Conversion Error", + "An unexpected error was encountered trying to convert from slice value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), + ) + return nil, diags + } + + return attrVal, diags + } + + t, ok := typ.(attr.TypeWithElementType) + if !ok { + err := fmt.Errorf("cannot use type %T as schema type %T; %T must be an attr.TypeWithElementType to hold %T", val, typ, typ, val) + diags.AddAttributeError( + path, + "Value Conversion Error", + "An unexpected error was encountered trying to convert from slice value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), + ) + return nil, diags + } + + elemType := t.ElementType() + tfElems := make([]tftypes.Value, 0, val.Len()) + for i := 0; i < val.Len(); i++ { + // The underlying reflect.Slice is fetched by Index(). For set types, + // the path is value-based instead of index-based. Since there is only + // the index until the value is retrieved, this will pass the + // technically incorrect index-based path at first for framework + // debugging purposes, then correct the path afterwards. + valPath := path.AtListIndex(i) + + val, valDiags := FromValue(ctx, elemType, val.Index(i).Interface(), valPath) + diags.Append(valDiags...) + + if diags.HasError() { + return nil, diags + } + + tfVal, err := val.ToTerraformValue(ctx) + if err != nil { + return nil, append(diags, toTerraformValueErrorDiag(err, path)) + } + + if tfType.Is(tftypes.Set{}) { + valPath = path.AtSetValue(val) + } + + if typeWithValidate, ok := elemType.(xattr.TypeWithValidate); ok { + diags.Append(typeWithValidate.Validate(ctx, tfVal, valPath)...) + if diags.HasError() { + return nil, diags + } + } + + tfElems = append(tfElems, tfVal) + } + + err := tftypes.ValidateValue(tfType, tfElems) + if err != nil { + return nil, append(diags, validateValueErrorDiag(err, path)) + } + + tfVal := tftypes.NewValue(tfType, tfElems) + + if typeWithValidate, ok := typ.(xattr.TypeWithValidate); ok { + diags.Append(typeWithValidate.Validate(ctx, tfVal, path)...) + + if diags.HasError() { + return nil, diags + } + } + + attrVal, err := typ.ValueFromTerraform(ctx, tfVal) + + if err != nil { + diags.AddAttributeError( + path, + "Value Conversion Error", + "An unexpected error was encountered trying to convert from slice value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), + ) + return nil, diags + } + + return attrVal, diags +} diff --git a/internal/provider/reflect/struct.go b/internal/provider/reflect/struct.go new file mode 100644 index 0000000..b670228 --- /dev/null +++ b/internal/provider/reflect/struct.go @@ -0,0 +1,266 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package reflect + +import ( + "context" + "fmt" + "reflect" + "strings" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/attr/xattr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// Struct builds a new struct using the data in `object`, as long as `object` +// is a `tftypes.Object`. It will take the struct type from `target`, which +// must be a struct type. +// +// The properties on `target` must be tagged with a "tfsdk" label containing +// the field name to map to that property. Every property must be tagged, and +// every property must be present in the type of `object`, and all the +// attributes in the type of `object` must have a corresponding property. +// Properties that don't map to object attributes must have a `tfsdk:"-"` tag, +// explicitly defining them as not part of the object. This is to catch typos +// and other mistakes early. +// +// Struct is meant to be called from Into, not directly. +func Struct(ctx context.Context, typ attr.Type, object tftypes.Value, target reflect.Value, opts Options, path path.Path) (reflect.Value, diag.Diagnostics) { + var diags diag.Diagnostics + + // this only works with object values, so make sure that constraint is + // met + if target.Kind() != reflect.Struct { + diags.Append(diag.WithPath(path, DiagIntoIncompatibleType{ + Val: object, + TargetType: target.Type(), + Err: fmt.Errorf("expected a struct type, got %s", target.Type()), + })) + return target, diags + } + if !object.Type().Is(tftypes.Object{}) { + diags.Append(diag.WithPath(path, DiagIntoIncompatibleType{ + Val: object, + TargetType: target.Type(), + Err: fmt.Errorf("cannot reflect %s into a struct, must be an object", object.Type().String()), + })) + return target, diags + } + attrsType, ok := typ.(attr.TypeWithAttributeTypes) + if !ok { + diags.Append(diag.WithPath(path, DiagIntoIncompatibleType{ + Val: object, + TargetType: target.Type(), + Err: fmt.Errorf("cannot reflect object using type information provided by %T, %T must be an attr.TypeWithAttributeTypes", typ, typ), + })) + return target, diags + } + + // collect a map of fields that are in the object passed in + var objectFields map[string]tftypes.Value + err := object.As(&objectFields) + if err != nil { + diags.Append(diag.WithPath(path, DiagIntoIncompatibleType{ + Val: object, + TargetType: target.Type(), + Err: err, + })) + return target, diags + } + + // collect a map of fields that are defined in the tags of the struct + // passed in + targetFields, err := getStructTags(ctx, target, path) + if err != nil { + diags.Append(diag.WithPath(path, DiagIntoIncompatibleType{ + Val: object, + TargetType: target.Type(), + Err: fmt.Errorf("error retrieving field names from struct tags: %w", err), + })) + return target, diags + } + + // we require an exact, 1:1 match of these fields to avoid typos + // leading to surprises, so let's ensure they have the exact same + // fields defined + var objectMissing, targetMissing []string + for field := range targetFields { + if _, ok := objectFields[field]; !ok { + objectMissing = append(objectMissing, field) + } + } + for field := range objectFields { + if _, ok := targetFields[field]; !ok { + targetMissing = append(targetMissing, field) + } + } + if len(objectMissing) > 0 || len(targetMissing) > 0 { + var missing []string + if len(objectMissing) > 0 { + missing = append(missing, fmt.Sprintf("Struct defines fields not found in object: %s.", commaSeparatedString(objectMissing))) + } + if len(targetMissing) > 0 { + missing = append(missing, fmt.Sprintf("Object defines fields not found in struct: %s.", commaSeparatedString(targetMissing))) + } + diags.Append(diag.WithPath(path, DiagIntoIncompatibleType{ + Val: object, + TargetType: target.Type(), + Err: fmt.Errorf("mismatch between struct and object: %s", strings.Join(missing, " ")), + })) + return target, diags + } + + attrTypes := attrsType.AttributeTypes() + + // now that we know they match perfectly, fill the struct with the + // values in the object + // Fork start + //result := reflect.New(target.Type()).Elem() + var result reflect.Value + if target.CanSet() { + result = target + } else { + result = reflect.New(target.Type()).Elem() + } + // Fork End + for field, structFieldPos := range targetFields { + attrType, ok := attrTypes[field] + if !ok { + diags.Append(diag.WithPath(path, DiagIntoIncompatibleType{ + Val: object, + TargetType: target.Type(), + Err: fmt.Errorf("could not find type information for attribute in supplied attr.Type %T", typ), + })) + return target, diags + } + structField := result.Field(structFieldPos) + fieldVal, fieldValDiags := BuildValue(ctx, attrType, objectFields[field], structField, opts, path.AtName(field)) + diags.Append(fieldValDiags...) + + if diags.HasError() { + return target, diags + } + structField.Set(fieldVal) + } + return result, diags +} + +// FromStruct builds an attr.Value as produced by `typ` from the data in `val`. +// `val` must be a struct type, and must have all its properties tagged and be +// a 1:1 match with the attributes reported by `typ`. FromStruct will recurse +// into FromValue for each attribute, using the type of the attribute as +// reported by `typ`. +// +// It is meant to be called through FromValue, not directly. +func FromStruct(ctx context.Context, typ attr.TypeWithAttributeTypes, val reflect.Value, path path.Path) (attr.Value, diag.Diagnostics) { + var diags diag.Diagnostics + objTypes := map[string]tftypes.Type{} + objValues := map[string]tftypes.Value{} + + // collect a map of fields that are defined in the tags of the struct + // passed in + targetFields, err := getStructTags(ctx, val, path) + if err != nil { + err = fmt.Errorf("error retrieving field names from struct tags: %w", err) + diags.AddAttributeError( + path, + "Value Conversion Error", + "An unexpected error was encountered trying to convert from struct value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), + ) + return nil, diags + } + + attrTypes := typ.AttributeTypes() + + var objectMissing, structMissing []string + + for field := range targetFields { + if _, ok := attrTypes[field]; !ok { + objectMissing = append(objectMissing, field) + } + } + + for attrName, attrType := range attrTypes { + if attrType == nil { + objectMissing = append(objectMissing, attrName) + } + + if _, ok := targetFields[attrName]; !ok { + structMissing = append(structMissing, attrName) + } + } + + if len(objectMissing) > 0 || len(structMissing) > 0 { + missing := make([]string, 0, len(objectMissing)+len(structMissing)) + + if len(objectMissing) > 0 { + missing = append(missing, fmt.Sprintf("Struct defines fields not found in object: %s.", commaSeparatedString(objectMissing))) + } + + if len(structMissing) > 0 { + missing = append(missing, fmt.Sprintf("Object defines fields not found in struct: %s.", commaSeparatedString(structMissing))) + } + + diags.AddAttributeError( + path, + "Value Conversion Error", + "An unexpected error was encountered trying to convert from struct into an object. "+ + "This is always an error in the provider. Please report the following to the provider developer:\n\n"+ + fmt.Sprintf("Mismatch between struct and object type: %s\n", strings.Join(missing, " "))+ + fmt.Sprintf("Struct: %s\n", val.Type())+ + fmt.Sprintf("Object type: %s", typ), + ) + + return nil, diags + } + + for name, fieldNo := range targetFields { + path := path.AtName(name) + fieldValue := val.Field(fieldNo) + + attrVal, attrValDiags := FromValue(ctx, attrTypes[name], fieldValue.Interface(), path) + diags.Append(attrValDiags...) + + if diags.HasError() { + return nil, diags + } + + tfObjVal, err := attrVal.ToTerraformValue(ctx) + if err != nil { + return nil, append(diags, toTerraformValueErrorDiag(err, path)) + } + + if typeWithValidate, ok := typ.(xattr.TypeWithValidate); ok { + diags.Append(typeWithValidate.Validate(ctx, tfObjVal, path)...) + + if diags.HasError() { + return nil, diags + } + } + + objValues[name] = tfObjVal + objTypes[name] = tfObjVal.Type() + } + + tfVal := tftypes.NewValue(tftypes.Object{ + AttributeTypes: objTypes, + }, objValues) + + if typeWithValidate, ok := typ.(xattr.TypeWithValidate); ok { + diags.Append(typeWithValidate.Validate(ctx, tfVal, path)...) + + if diags.HasError() { + return nil, diags + } + } + + ret, err := typ.ValueFromTerraform(ctx, tfVal) + if err != nil { + return nil, append(diags, valueFromTerraformErrorDiag(err, path)) + } + + return ret, diags +} diff --git a/internal/provider/utils.go b/internal/provider/utils.go new file mode 100644 index 0000000..eabd0e3 --- /dev/null +++ b/internal/provider/utils.go @@ -0,0 +1,84 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package provider + +import ( + "context" + "encoding/json" + "fmt" + tfReflect "github.com/LukeHagar/terraform-provider-PlexAPI/internal/provider/reflect" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/resource" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + "net/http" + "net/http/httputil" + "reflect" +) + +func debugResponse(response *http.Response) string { + dumpReq, err := httputil.DumpRequest(response.Request, true) + if err != nil { + dumpReq, err = httputil.DumpRequest(response.Request, false) + if err != nil { + return err.Error() + } + } + dumpRes, err := httputil.DumpResponse(response, true) + if err != nil { + dumpRes, err = httputil.DumpResponse(response, false) + if err != nil { + return err.Error() + } + } + return fmt.Sprintf("**Request**:\n%s\n**Response**:\n%s", string(dumpReq), string(dumpRes)) +} + +func reflectJSONKey(data any, key string) reflect.Value { + jsonIfied, err := json.Marshal(data) + if err != nil { + panic(fmt.Errorf("failed to marshal data: %w", err)) + } + var jsonMap map[string]interface{} + err = json.Unmarshal(jsonIfied, &jsonMap) + if err != nil { + panic(fmt.Errorf("failed to unmarshal data: %w", err)) + } + return reflect.ValueOf(jsonMap[key]) +} + +func merge(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse, target interface{}) { + var plan types.Object + var state types.Object + + resp.Diagnostics.Append(req.State.Get(ctx, &state)...) + if resp.Diagnostics.HasError() { + return + } + resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) + if resp.Diagnostics.HasError() { + return + } + + resp.Diagnostics.Append(state.As(ctx, target, basetypes.ObjectAsOptions{ + UnhandledNullAsEmpty: true, + UnhandledUnknownAsEmpty: true, + })...) + if resp.Diagnostics.HasError() { + return + } + + // we need a tftypes.Value for this Object to be able to use it with + // our reflection code + obj := types.ObjectType{AttrTypes: plan.AttributeTypes(ctx)} + val, err := plan.ToTerraformValue(ctx) + if err != nil { + resp.Diagnostics.Append(diag.NewErrorDiagnostic("Object Conversion Error", "An unexpected error was encountered trying to convert object. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error())) + return + } + resp.Diagnostics.Append(tfReflect.Into(ctx, obj, val, target, tfReflect.Options{ + UnhandledNullAsEmpty: true, + UnhandledUnknownAsEmpty: true, + }, path.Empty())...) +} diff --git a/internal/sdk/activities.go b/internal/sdk/activities.go new file mode 100644 index 0000000..f67c663 --- /dev/null +++ b/internal/sdk/activities.go @@ -0,0 +1,161 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package sdk + +import ( + "bytes" + "context" + "fmt" + "github.com/LukeHagar/terraform-provider-PlexAPI/internal/sdk/pkg/models/operations" + "github.com/LukeHagar/terraform-provider-PlexAPI/internal/sdk/pkg/models/sdkerrors" + "github.com/LukeHagar/terraform-provider-PlexAPI/internal/sdk/pkg/utils" + "io" + "net/http" + "strings" +) + +// Activities are awesome. They provide a way to monitor and control asynchronous operations on the server. In order to receive real-time updates for activities, a client would normally subscribe via either EventSource or Websocket endpoints. +// Activities are associated with HTTP replies via a special `X-Plex-Activity` header which contains the UUID of the activity. +// Activities are optional cancellable. If cancellable, they may be cancelled via the `DELETE` endpoint. Other details: +// - They can contain a `progress` (from 0 to 100) marking the percent completion of the activity. +// - They must contain an `type` which is used by clients to distinguish the specific activity. +// - They may contain a `Context` object with attributes which associate the activity with various specific entities (items, libraries, etc.) +// - The may contain a `Response` object which attributes which represent the result of the asynchronous operation. +type Activities struct { + sdkConfiguration sdkConfiguration +} + +func newActivities(sdkConfig sdkConfiguration) *Activities { + return &Activities{ + sdkConfiguration: sdkConfig, + } +} + +// GetServerActivities - Get Server Activities +// Get Server Activities +func (s *Activities) GetServerActivities(ctx context.Context) (*operations.GetServerActivitiesResponse, error) { + baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) + url := strings.TrimSuffix(baseURL, "/") + "/activities" + + req, err := http.NewRequestWithContext(ctx, "GET", url, 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) + + client := s.sdkConfiguration.SecurityClient + + httpRes, err := client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %w", err) + } + if httpRes == nil { + return nil, fmt.Errorf("error sending request: no response") + } + + 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)) + + contentType := httpRes.Header.Get("Content-Type") + + res := &operations.GetServerActivitiesResponse{ + StatusCode: httpRes.StatusCode, + ContentType: contentType, + RawResponse: httpRes, + } + switch { + case httpRes.StatusCode == 200: + switch { + case utils.MatchContentType(contentType, `application/json`): + var out operations.GetServerActivitiesResponseBody + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + res.TwoHundredApplicationJSONObject = &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", contentType), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 400: + case httpRes.StatusCode == 401: + switch { + case utils.MatchContentType(contentType, `application/json`): + var out operations.GetServerActivitiesActivitiesResponseBody + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + res.FourHundredAndOneApplicationJSONObject = &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", contentType), httpRes.StatusCode, string(rawBody), httpRes) + } + } + + return res, nil +} + +// CancelServerActivities - Cancel Server Activities +// Cancel Server Activities +func (s *Activities) CancelServerActivities(ctx context.Context, request operations.CancelServerActivitiesRequest) (*operations.CancelServerActivitiesResponse, error) { + baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) + url, err := utils.GenerateURL(ctx, baseURL, "/activities/{activityUUID}", request, nil) + if err != nil { + return nil, fmt.Errorf("error generating URL: %w", err) + } + + req, err := http.NewRequestWithContext(ctx, "DELETE", url, 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) + + client := s.sdkConfiguration.SecurityClient + + httpRes, err := client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %w", err) + } + if httpRes == nil { + return nil, fmt.Errorf("error sending request: no response") + } + + 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)) + + contentType := httpRes.Header.Get("Content-Type") + + res := &operations.CancelServerActivitiesResponse{ + StatusCode: httpRes.StatusCode, + ContentType: contentType, + RawResponse: httpRes, + } + switch { + case httpRes.StatusCode == 200: + fallthrough + case httpRes.StatusCode == 400: + case httpRes.StatusCode == 401: + switch { + case utils.MatchContentType(contentType, `application/json`): + var out operations.CancelServerActivitiesResponseBody + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + res.Object = &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", contentType), httpRes.StatusCode, string(rawBody), httpRes) + } + } + + return res, nil +} diff --git a/internal/sdk/butler.go b/internal/sdk/butler.go new file mode 100644 index 0000000..e3e3217 --- /dev/null +++ b/internal/sdk/butler.go @@ -0,0 +1,344 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package sdk + +import ( + "bytes" + "context" + "fmt" + "github.com/LukeHagar/terraform-provider-PlexAPI/internal/sdk/pkg/models/operations" + "github.com/LukeHagar/terraform-provider-PlexAPI/internal/sdk/pkg/models/sdkerrors" + "github.com/LukeHagar/terraform-provider-PlexAPI/internal/sdk/pkg/utils" + "io" + "net/http" + "strings" +) + +// Butler is the task manager of the Plex Media Server Ecosystem. +type Butler struct { + sdkConfiguration sdkConfiguration +} + +func newButler(sdkConfig sdkConfiguration) *Butler { + return &Butler{ + sdkConfiguration: sdkConfig, + } +} + +// GetButlerTasks - Get Butler tasks +// Returns a list of butler tasks +func (s *Butler) GetButlerTasks(ctx context.Context) (*operations.GetButlerTasksResponse, error) { + baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) + url := strings.TrimSuffix(baseURL, "/") + "/butler" + + req, err := http.NewRequestWithContext(ctx, "GET", url, 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) + + client := s.sdkConfiguration.SecurityClient + + httpRes, err := client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %w", err) + } + if httpRes == nil { + return nil, fmt.Errorf("error sending request: no response") + } + + 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)) + + contentType := httpRes.Header.Get("Content-Type") + + res := &operations.GetButlerTasksResponse{ + StatusCode: httpRes.StatusCode, + ContentType: contentType, + RawResponse: httpRes, + } + switch { + case httpRes.StatusCode == 200: + switch { + case utils.MatchContentType(contentType, `application/json`): + var out operations.GetButlerTasksResponseBody + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + res.TwoHundredApplicationJSONObject = &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", contentType), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 400: + case httpRes.StatusCode == 401: + switch { + case utils.MatchContentType(contentType, `application/json`): + var out operations.GetButlerTasksButlerResponseBody + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + res.FourHundredAndOneApplicationJSONObject = &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", contentType), httpRes.StatusCode, string(rawBody), httpRes) + } + } + + return res, nil +} + +// StartAllTasks - Start all Butler tasks +// This endpoint will attempt to start all Butler tasks that are enabled in the settings. Butler tasks normally run automatically during a time window configured on the server's Settings page but can be manually started using this endpoint. Tasks will run with the following criteria: +// 1. Any tasks not scheduled to run on the current day will be skipped. +// 2. If a task is configured to run at a random time during the configured window and we are outside that window, the task will start immediately. +// 3. If a task is configured to run at a random time during the configured window and we are within that window, the task will be scheduled at a random time within the window. +// 4. If we are outside the configured window, the task will start immediately. +func (s *Butler) StartAllTasks(ctx context.Context) (*operations.StartAllTasksResponse, error) { + baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) + url := strings.TrimSuffix(baseURL, "/") + "/butler" + + req, err := http.NewRequestWithContext(ctx, "POST", url, 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) + + client := s.sdkConfiguration.SecurityClient + + httpRes, err := client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %w", err) + } + if httpRes == nil { + return nil, fmt.Errorf("error sending request: no response") + } + + 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)) + + contentType := httpRes.Header.Get("Content-Type") + + res := &operations.StartAllTasksResponse{ + StatusCode: httpRes.StatusCode, + ContentType: contentType, + RawResponse: httpRes, + } + switch { + case httpRes.StatusCode == 200: + fallthrough + case httpRes.StatusCode == 400: + case httpRes.StatusCode == 401: + switch { + case utils.MatchContentType(contentType, `application/json`): + var out operations.StartAllTasksResponseBody + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + res.Object = &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", contentType), httpRes.StatusCode, string(rawBody), httpRes) + } + } + + return res, nil +} + +// StopAllTasks - Stop all Butler tasks +// This endpoint will stop all currently running tasks and remove any scheduled tasks from the queue. +func (s *Butler) StopAllTasks(ctx context.Context) (*operations.StopAllTasksResponse, error) { + baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) + url := strings.TrimSuffix(baseURL, "/") + "/butler" + + req, err := http.NewRequestWithContext(ctx, "DELETE", url, 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) + + client := s.sdkConfiguration.SecurityClient + + httpRes, err := client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %w", err) + } + if httpRes == nil { + return nil, fmt.Errorf("error sending request: no response") + } + + 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)) + + contentType := httpRes.Header.Get("Content-Type") + + res := &operations.StopAllTasksResponse{ + StatusCode: httpRes.StatusCode, + ContentType: contentType, + RawResponse: httpRes, + } + switch { + case httpRes.StatusCode == 200: + fallthrough + case httpRes.StatusCode == 400: + case httpRes.StatusCode == 401: + switch { + case utils.MatchContentType(contentType, `application/json`): + var out operations.StopAllTasksResponseBody + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + res.Object = &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", contentType), httpRes.StatusCode, string(rawBody), httpRes) + } + } + + return res, nil +} + +// StartTask - Start a single Butler task +// This endpoint will attempt to start a single Butler task that is enabled in the settings. Butler tasks normally run automatically during a time window configured on the server's Settings page but can be manually started using this endpoint. Tasks will run with the following criteria: +// 1. Any tasks not scheduled to run on the current day will be skipped. +// 2. If a task is configured to run at a random time during the configured window and we are outside that window, the task will start immediately. +// 3. If a task is configured to run at a random time during the configured window and we are within that window, the task will be scheduled at a random time within the window. +// 4. If we are outside the configured window, the task will start immediately. +func (s *Butler) StartTask(ctx context.Context, request operations.StartTaskRequest) (*operations.StartTaskResponse, error) { + baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) + url, err := utils.GenerateURL(ctx, baseURL, "/butler/{taskName}", request, nil) + if err != nil { + return nil, fmt.Errorf("error generating URL: %w", err) + } + + req, err := http.NewRequestWithContext(ctx, "POST", url, 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) + + client := s.sdkConfiguration.SecurityClient + + httpRes, err := client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %w", err) + } + if httpRes == nil { + return nil, fmt.Errorf("error sending request: no response") + } + + 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)) + + contentType := httpRes.Header.Get("Content-Type") + + res := &operations.StartTaskResponse{ + StatusCode: httpRes.StatusCode, + ContentType: contentType, + RawResponse: httpRes, + } + switch { + case httpRes.StatusCode == 200: + fallthrough + case httpRes.StatusCode == 202: + fallthrough + case httpRes.StatusCode == 400: + case httpRes.StatusCode == 401: + switch { + case utils.MatchContentType(contentType, `application/json`): + var out operations.StartTaskResponseBody + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + res.Object = &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", contentType), httpRes.StatusCode, string(rawBody), httpRes) + } + } + + return res, nil +} + +// StopTask - Stop a single Butler task +// This endpoint will stop a currently running task by name, or remove it from the list of scheduled tasks if it exists. See the section above for a list of task names for this endpoint. +func (s *Butler) StopTask(ctx context.Context, request operations.StopTaskRequest) (*operations.StopTaskResponse, error) { + baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) + url, err := utils.GenerateURL(ctx, baseURL, "/butler/{taskName}", request, nil) + if err != nil { + return nil, fmt.Errorf("error generating URL: %w", err) + } + + req, err := http.NewRequestWithContext(ctx, "DELETE", url, 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) + + client := s.sdkConfiguration.SecurityClient + + httpRes, err := client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %w", err) + } + if httpRes == nil { + return nil, fmt.Errorf("error sending request: no response") + } + + 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)) + + contentType := httpRes.Header.Get("Content-Type") + + res := &operations.StopTaskResponse{ + StatusCode: httpRes.StatusCode, + ContentType: contentType, + RawResponse: httpRes, + } + switch { + case httpRes.StatusCode == 200: + fallthrough + case httpRes.StatusCode == 400: + fallthrough + case httpRes.StatusCode == 404: + case httpRes.StatusCode == 401: + switch { + case utils.MatchContentType(contentType, `application/json`): + var out operations.StopTaskResponseBody + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + res.Object = &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", contentType), httpRes.StatusCode, string(rawBody), httpRes) + } + } + + return res, nil +} diff --git a/internal/sdk/hubs.go b/internal/sdk/hubs.go new file mode 100644 index 0000000..2d867a1 --- /dev/null +++ b/internal/sdk/hubs.go @@ -0,0 +1,153 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package sdk + +import ( + "bytes" + "context" + "fmt" + "github.com/LukeHagar/terraform-provider-PlexAPI/internal/sdk/pkg/models/operations" + "github.com/LukeHagar/terraform-provider-PlexAPI/internal/sdk/pkg/models/sdkerrors" + "github.com/LukeHagar/terraform-provider-PlexAPI/internal/sdk/pkg/utils" + "io" + "net/http" + "strings" +) + +// Hubs are a structured two-dimensional container for media, generally represented by multiple horizontal rows. +type Hubs struct { + sdkConfiguration sdkConfiguration +} + +func newHubs(sdkConfig sdkConfiguration) *Hubs { + return &Hubs{ + sdkConfiguration: sdkConfig, + } +} + +// GetGlobalHubs - Get Global Hubs +// Get Global Hubs filtered by the parameters provided. +func (s *Hubs) GetGlobalHubs(ctx context.Context, request operations.GetGlobalHubsRequest) (*operations.GetGlobalHubsResponse, error) { + baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) + url := strings.TrimSuffix(baseURL, "/") + "/hubs" + + req, err := http.NewRequestWithContext(ctx, "GET", url, 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) + } + + client := s.sdkConfiguration.SecurityClient + + httpRes, err := client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %w", err) + } + if httpRes == nil { + return nil, fmt.Errorf("error sending request: no response") + } + + 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)) + + contentType := httpRes.Header.Get("Content-Type") + + res := &operations.GetGlobalHubsResponse{ + StatusCode: httpRes.StatusCode, + ContentType: contentType, + RawResponse: httpRes, + } + switch { + case httpRes.StatusCode == 200: + fallthrough + case httpRes.StatusCode == 400: + case httpRes.StatusCode == 401: + switch { + case utils.MatchContentType(contentType, `application/json`): + var out operations.GetGlobalHubsResponseBody + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + res.Object = &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", contentType), httpRes.StatusCode, string(rawBody), httpRes) + } + } + + return res, nil +} + +// GetLibraryHubs - Get library specific hubs +// This endpoint will return a list of library specific hubs +func (s *Hubs) GetLibraryHubs(ctx context.Context, request operations.GetLibraryHubsRequest) (*operations.GetLibraryHubsResponse, error) { + baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) + url, err := utils.GenerateURL(ctx, baseURL, "/hubs/sections/{sectionId}", request, nil) + if err != nil { + return nil, fmt.Errorf("error generating URL: %w", err) + } + + req, err := http.NewRequestWithContext(ctx, "GET", url, 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) + } + + client := s.sdkConfiguration.SecurityClient + + httpRes, err := client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %w", err) + } + if httpRes == nil { + return nil, fmt.Errorf("error sending request: no response") + } + + 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)) + + contentType := httpRes.Header.Get("Content-Type") + + res := &operations.GetLibraryHubsResponse{ + StatusCode: httpRes.StatusCode, + ContentType: contentType, + RawResponse: httpRes, + } + switch { + case httpRes.StatusCode == 200: + fallthrough + case httpRes.StatusCode == 400: + case httpRes.StatusCode == 401: + switch { + case utils.MatchContentType(contentType, `application/json`): + var out operations.GetLibraryHubsResponseBody + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + res.Object = &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", contentType), httpRes.StatusCode, string(rawBody), httpRes) + } + } + + return res, nil +} diff --git a/internal/sdk/library.go b/internal/sdk/library.go new file mode 100644 index 0000000..7f9e372 --- /dev/null +++ b/internal/sdk/library.go @@ -0,0 +1,814 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package sdk + +import ( + "bytes" + "context" + "fmt" + "github.com/LukeHagar/terraform-provider-PlexAPI/internal/sdk/pkg/models/operations" + "github.com/LukeHagar/terraform-provider-PlexAPI/internal/sdk/pkg/models/sdkerrors" + "github.com/LukeHagar/terraform-provider-PlexAPI/internal/sdk/pkg/utils" + "io" + "net/http" + "strings" +) + +// Library - API Calls interacting with Plex Media Server Libraries +type Library struct { + sdkConfiguration sdkConfiguration +} + +func newLibrary(sdkConfig sdkConfiguration) *Library { + return &Library{ + sdkConfiguration: sdkConfig, + } +} + +// GetFileHash - Get Hash Value +// This resource returns hash values for local files +func (s *Library) GetFileHash(ctx context.Context, request operations.GetFileHashRequest) (*operations.GetFileHashResponse, error) { + baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) + url := strings.TrimSuffix(baseURL, "/") + "/library/hashes" + + req, err := http.NewRequestWithContext(ctx, "GET", url, 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) + } + + client := s.sdkConfiguration.SecurityClient + + httpRes, err := client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %w", err) + } + if httpRes == nil { + return nil, fmt.Errorf("error sending request: no response") + } + + 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)) + + contentType := httpRes.Header.Get("Content-Type") + + res := &operations.GetFileHashResponse{ + StatusCode: httpRes.StatusCode, + ContentType: contentType, + RawResponse: httpRes, + } + switch { + case httpRes.StatusCode == 200: + fallthrough + case httpRes.StatusCode == 400: + case httpRes.StatusCode == 401: + switch { + case utils.MatchContentType(contentType, `application/json`): + var out operations.GetFileHashResponseBody + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + res.Object = &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", contentType), httpRes.StatusCode, string(rawBody), httpRes) + } + } + + return res, nil +} + +// GetRecentlyAdded - Get Recently Added +// This endpoint will return the recently added content. +func (s *Library) GetRecentlyAdded(ctx context.Context) (*operations.GetRecentlyAddedResponse, error) { + baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) + url := strings.TrimSuffix(baseURL, "/") + "/library/recentlyAdded" + + req, err := http.NewRequestWithContext(ctx, "GET", url, 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) + + client := s.sdkConfiguration.SecurityClient + + httpRes, err := client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %w", err) + } + if httpRes == nil { + return nil, fmt.Errorf("error sending request: no response") + } + + 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)) + + contentType := httpRes.Header.Get("Content-Type") + + res := &operations.GetRecentlyAddedResponse{ + StatusCode: httpRes.StatusCode, + ContentType: contentType, + RawResponse: httpRes, + } + switch { + case httpRes.StatusCode == 200: + switch { + case utils.MatchContentType(contentType, `application/json`): + var out operations.GetRecentlyAddedResponseBody + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + res.TwoHundredApplicationJSONObject = &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", contentType), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 400: + case httpRes.StatusCode == 401: + switch { + case utils.MatchContentType(contentType, `application/json`): + var out operations.GetRecentlyAddedLibraryResponseBody + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + res.FourHundredAndOneApplicationJSONObject = &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", contentType), httpRes.StatusCode, string(rawBody), httpRes) + } + } + + return res, nil +} + +// GetLibraries - Get All Libraries +// A library section (commonly referred to as just a library) is a collection of media. +// Libraries are typed, and depending on their type provide either a flat or a hierarchical view of the media. +// For example, a music library has an artist > albums > tracks structure, whereas a movie library is flat. +// +// Libraries have features beyond just being a collection of media; for starters, they include information about supported types, filters and sorts. +// This allows a client to provide a rich interface around the media (e.g. allow sorting movies by release year). +func (s *Library) GetLibraries(ctx context.Context) (*operations.GetLibrariesResponse, error) { + baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) + url := strings.TrimSuffix(baseURL, "/") + "/library/sections" + + req, err := http.NewRequestWithContext(ctx, "GET", url, 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) + + client := s.sdkConfiguration.SecurityClient + + httpRes, err := client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %w", err) + } + if httpRes == nil { + return nil, fmt.Errorf("error sending request: no response") + } + + 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)) + + contentType := httpRes.Header.Get("Content-Type") + + res := &operations.GetLibrariesResponse{ + StatusCode: httpRes.StatusCode, + ContentType: contentType, + RawResponse: httpRes, + } + switch { + case httpRes.StatusCode == 200: + fallthrough + case httpRes.StatusCode == 400: + case httpRes.StatusCode == 401: + switch { + case utils.MatchContentType(contentType, `application/json`): + var out operations.GetLibrariesResponseBody + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + res.Object = &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", contentType), httpRes.StatusCode, string(rawBody), httpRes) + } + } + + return res, nil +} + +// GetLibrary - Get Library Details +// Returns details for the library. This can be thought of as an interstitial endpoint because it contains information about the library, rather than content itself. These details are: +// +// - A list of `Directory` objects: These used to be used by clients to build a menuing system. There are four flavors of directory found here: +// - Primary: (e.g. all, On Deck) These are still used in some clients to provide "shortcuts" to subsets of media. However, with the exception of On Deck, all of them can be created by media queries, and the desire is to allow these to be customized by users. +// - Secondary: These are marked with `secondary="1"` and were used by old clients to provide nested menus allowing for primative (but structured) navigation. +// - Special: There is a By Folder entry which allows browsing the media by the underlying filesystem structure, and there's a completely obsolete entry marked `search="1"` which used to be used to allow clients to build search dialogs on the fly. +// +// - A list of `Type` objects: These represent the types of things found in this library, and for each one, a list of `Filter` and `Sort` objects. These can be used to build rich controls around a grid of media to allow filtering and organizing. Note that these filters and sorts are optional, and without them, the client won't render any filtering controls. The `Type` object contains: +// - `key`: This provides the root endpoint returning the actual media list for the type. +// - `type`: This is the metadata type for the type (if a standard Plex type). +// - `title`: The title for for the content of this type (e.g. "Movies"). +// +// - Each `Filter` object contains a description of the filter. Note that it is not an exhaustive list of the full media query language, but an inportant subset useful for top-level API. +// - `filter`: This represents the filter name used for the filter, which can be used to construct complex media queries with. +// - `filterType`: This is either `string`, `integer`, or `boolean`, and describes the type of values used for the filter. +// - `key`: This provides the endpoint where the possible range of values for the filter can be retrieved (e.g. for a "Genre" filter, it returns a list of all the genres in the library). This will include a `type` argument that matches the metadata type of the Type element. +// - `title`: The title for the filter. +// +// - Each `Sort` object contains a description of the sort field. +// - `defaultDirection`: Can be either `asc` or `desc`, and specifies the default direction for the sort field (e.g. titles default to alphabetically ascending). +// - `descKey` and `key`: Contains the parameters passed to the `sort=...` media query for each direction of the sort. +// - `title`: The title of the field. +func (s *Library) GetLibrary(ctx context.Context, request operations.GetLibraryRequest) (*operations.GetLibraryResponse, error) { + baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) + url, err := utils.GenerateURL(ctx, baseURL, "/library/sections/{sectionId}", request, nil) + if err != nil { + return nil, fmt.Errorf("error generating URL: %w", err) + } + + req, err := http.NewRequestWithContext(ctx, "GET", url, 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) + } + + client := s.sdkConfiguration.SecurityClient + + httpRes, err := client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %w", err) + } + if httpRes == nil { + return nil, fmt.Errorf("error sending request: no response") + } + + 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)) + + contentType := httpRes.Header.Get("Content-Type") + + res := &operations.GetLibraryResponse{ + StatusCode: httpRes.StatusCode, + ContentType: contentType, + RawResponse: httpRes, + } + switch { + case httpRes.StatusCode == 200: + fallthrough + case httpRes.StatusCode == 400: + case httpRes.StatusCode == 401: + switch { + case utils.MatchContentType(contentType, `application/json`): + var out operations.GetLibraryResponseBody + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + res.Object = &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", contentType), httpRes.StatusCode, string(rawBody), httpRes) + } + } + + return res, nil +} + +// DeleteLibrary - Delete Library Section +// Delate a library using a specific section +func (s *Library) DeleteLibrary(ctx context.Context, request operations.DeleteLibraryRequest) (*operations.DeleteLibraryResponse, error) { + baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) + url, err := utils.GenerateURL(ctx, baseURL, "/library/sections/{sectionId}", request, nil) + if err != nil { + return nil, fmt.Errorf("error generating URL: %w", err) + } + + req, err := http.NewRequestWithContext(ctx, "DELETE", url, 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) + + client := s.sdkConfiguration.SecurityClient + + httpRes, err := client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %w", err) + } + if httpRes == nil { + return nil, fmt.Errorf("error sending request: no response") + } + + 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)) + + contentType := httpRes.Header.Get("Content-Type") + + res := &operations.DeleteLibraryResponse{ + StatusCode: httpRes.StatusCode, + ContentType: contentType, + RawResponse: httpRes, + } + switch { + case httpRes.StatusCode == 200: + fallthrough + case httpRes.StatusCode == 400: + case httpRes.StatusCode == 401: + switch { + case utils.MatchContentType(contentType, `application/json`): + var out operations.DeleteLibraryResponseBody + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + res.Object = &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", contentType), httpRes.StatusCode, string(rawBody), httpRes) + } + } + + return res, nil +} + +// GetLibraryItems - Get Library Items +// This endpoint will return a list of library items filtered by the filter and type provided +func (s *Library) GetLibraryItems(ctx context.Context, request operations.GetLibraryItemsRequest) (*operations.GetLibraryItemsResponse, error) { + baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) + url, err := utils.GenerateURL(ctx, baseURL, "/library/sections/{sectionId}/all", request, nil) + if err != nil { + return nil, fmt.Errorf("error generating URL: %w", err) + } + + req, err := http.NewRequestWithContext(ctx, "GET", url, 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) + } + + client := s.sdkConfiguration.SecurityClient + + httpRes, err := client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %w", err) + } + if httpRes == nil { + return nil, fmt.Errorf("error sending request: no response") + } + + 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)) + + contentType := httpRes.Header.Get("Content-Type") + + res := &operations.GetLibraryItemsResponse{ + StatusCode: httpRes.StatusCode, + ContentType: contentType, + RawResponse: httpRes, + } + switch { + case httpRes.StatusCode == 200: + fallthrough + case httpRes.StatusCode == 400: + case httpRes.StatusCode == 401: + switch { + case utils.MatchContentType(contentType, `application/json`): + var out operations.GetLibraryItemsResponseBody + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + res.Object = &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", contentType), httpRes.StatusCode, string(rawBody), httpRes) + } + } + + return res, nil +} + +// RefreshLibrary - Refresh Library +// This endpoint Refreshes the library. +func (s *Library) RefreshLibrary(ctx context.Context, request operations.RefreshLibraryRequest) (*operations.RefreshLibraryResponse, error) { + baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) + url, err := utils.GenerateURL(ctx, baseURL, "/library/sections/{sectionId}/refresh", request, nil) + if err != nil { + return nil, fmt.Errorf("error generating URL: %w", err) + } + + req, err := http.NewRequestWithContext(ctx, "GET", url, 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) + + client := s.sdkConfiguration.SecurityClient + + httpRes, err := client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %w", err) + } + if httpRes == nil { + return nil, fmt.Errorf("error sending request: no response") + } + + 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)) + + contentType := httpRes.Header.Get("Content-Type") + + res := &operations.RefreshLibraryResponse{ + StatusCode: httpRes.StatusCode, + ContentType: contentType, + RawResponse: httpRes, + } + switch { + case httpRes.StatusCode == 200: + fallthrough + case httpRes.StatusCode == 400: + case httpRes.StatusCode == 401: + switch { + case utils.MatchContentType(contentType, `application/json`): + var out operations.RefreshLibraryResponseBody + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + res.Object = &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", contentType), httpRes.StatusCode, string(rawBody), httpRes) + } + } + + return res, nil +} + +// GetLatestLibraryItems - Get Latest Library Items +// This endpoint will return a list of the latest library items filtered by the filter and type provided +func (s *Library) GetLatestLibraryItems(ctx context.Context, request operations.GetLatestLibraryItemsRequest) (*operations.GetLatestLibraryItemsResponse, error) { + baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) + url, err := utils.GenerateURL(ctx, baseURL, "/library/sections/{sectionId}/latest", request, nil) + if err != nil { + return nil, fmt.Errorf("error generating URL: %w", err) + } + + req, err := http.NewRequestWithContext(ctx, "GET", url, 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) + } + + client := s.sdkConfiguration.SecurityClient + + httpRes, err := client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %w", err) + } + if httpRes == nil { + return nil, fmt.Errorf("error sending request: no response") + } + + 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)) + + contentType := httpRes.Header.Get("Content-Type") + + res := &operations.GetLatestLibraryItemsResponse{ + StatusCode: httpRes.StatusCode, + ContentType: contentType, + RawResponse: httpRes, + } + switch { + case httpRes.StatusCode == 200: + fallthrough + case httpRes.StatusCode == 400: + case httpRes.StatusCode == 401: + switch { + case utils.MatchContentType(contentType, `application/json`): + var out operations.GetLatestLibraryItemsResponseBody + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + res.Object = &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", contentType), httpRes.StatusCode, string(rawBody), httpRes) + } + } + + return res, nil +} + +// GetCommonLibraryItems - Get Common Library Items +// Represents a "Common" item. It contains only the common attributes of the items selected by the provided filter +func (s *Library) GetCommonLibraryItems(ctx context.Context, request operations.GetCommonLibraryItemsRequest) (*operations.GetCommonLibraryItemsResponse, error) { + baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) + url, err := utils.GenerateURL(ctx, baseURL, "/library/sections/{sectionId}/common", request, nil) + if err != nil { + return nil, fmt.Errorf("error generating URL: %w", err) + } + + req, err := http.NewRequestWithContext(ctx, "GET", url, 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) + } + + client := s.sdkConfiguration.SecurityClient + + httpRes, err := client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %w", err) + } + if httpRes == nil { + return nil, fmt.Errorf("error sending request: no response") + } + + 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)) + + contentType := httpRes.Header.Get("Content-Type") + + res := &operations.GetCommonLibraryItemsResponse{ + StatusCode: httpRes.StatusCode, + ContentType: contentType, + RawResponse: httpRes, + } + switch { + case httpRes.StatusCode == 200: + fallthrough + case httpRes.StatusCode == 400: + fallthrough + case httpRes.StatusCode == 404: + case httpRes.StatusCode == 401: + switch { + case utils.MatchContentType(contentType, `application/json`): + var out operations.GetCommonLibraryItemsResponseBody + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + res.Object = &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", contentType), httpRes.StatusCode, string(rawBody), httpRes) + } + } + + return res, nil +} + +// GetMetadata - Get Items Metadata +// This endpoint will return the metadata of a library item specified with the ratingKey. +func (s *Library) GetMetadata(ctx context.Context, request operations.GetMetadataRequest) (*operations.GetMetadataResponse, error) { + baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) + url, err := utils.GenerateURL(ctx, baseURL, "/library/metadata/{ratingKey}", request, nil) + if err != nil { + return nil, fmt.Errorf("error generating URL: %w", err) + } + + req, err := http.NewRequestWithContext(ctx, "GET", url, 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) + + client := s.sdkConfiguration.SecurityClient + + httpRes, err := client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %w", err) + } + if httpRes == nil { + return nil, fmt.Errorf("error sending request: no response") + } + + 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)) + + contentType := httpRes.Header.Get("Content-Type") + + res := &operations.GetMetadataResponse{ + StatusCode: httpRes.StatusCode, + ContentType: contentType, + RawResponse: httpRes, + } + switch { + case httpRes.StatusCode == 200: + fallthrough + case httpRes.StatusCode == 400: + case httpRes.StatusCode == 401: + switch { + case utils.MatchContentType(contentType, `application/json`): + var out operations.GetMetadataResponseBody + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + res.Object = &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", contentType), httpRes.StatusCode, string(rawBody), httpRes) + } + } + + return res, nil +} + +// GetMetadataChildren - Get Items Children +// This endpoint will return the children of of a library item specified with the ratingKey. +func (s *Library) GetMetadataChildren(ctx context.Context, request operations.GetMetadataChildrenRequest) (*operations.GetMetadataChildrenResponse, error) { + baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) + url, err := utils.GenerateURL(ctx, baseURL, "/library/metadata/{ratingKey}/children", request, nil) + if err != nil { + return nil, fmt.Errorf("error generating URL: %w", err) + } + + req, err := http.NewRequestWithContext(ctx, "GET", url, 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) + + client := s.sdkConfiguration.SecurityClient + + httpRes, err := client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %w", err) + } + if httpRes == nil { + return nil, fmt.Errorf("error sending request: no response") + } + + 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)) + + contentType := httpRes.Header.Get("Content-Type") + + res := &operations.GetMetadataChildrenResponse{ + StatusCode: httpRes.StatusCode, + ContentType: contentType, + RawResponse: httpRes, + } + switch { + case httpRes.StatusCode == 200: + fallthrough + case httpRes.StatusCode == 400: + case httpRes.StatusCode == 401: + switch { + case utils.MatchContentType(contentType, `application/json`): + var out operations.GetMetadataChildrenResponseBody + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + res.Object = &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", contentType), httpRes.StatusCode, string(rawBody), httpRes) + } + } + + return res, nil +} + +// GetOnDeck - Get On Deck +// This endpoint will return the on deck content. +func (s *Library) GetOnDeck(ctx context.Context) (*operations.GetOnDeckResponse, error) { + baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) + url := strings.TrimSuffix(baseURL, "/") + "/library/onDeck" + + req, err := http.NewRequestWithContext(ctx, "GET", url, 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) + + client := s.sdkConfiguration.SecurityClient + + httpRes, err := client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %w", err) + } + if httpRes == nil { + return nil, fmt.Errorf("error sending request: no response") + } + + 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)) + + contentType := httpRes.Header.Get("Content-Type") + + res := &operations.GetOnDeckResponse{ + StatusCode: httpRes.StatusCode, + ContentType: contentType, + RawResponse: httpRes, + } + switch { + case httpRes.StatusCode == 200: + switch { + case utils.MatchContentType(contentType, `application/json`): + var out operations.GetOnDeckResponseBody + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + res.TwoHundredApplicationJSONObject = &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", contentType), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 400: + case httpRes.StatusCode == 401: + switch { + case utils.MatchContentType(contentType, `application/json`): + var out operations.GetOnDeckLibraryResponseBody + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + res.FourHundredAndOneApplicationJSONObject = &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", contentType), httpRes.StatusCode, string(rawBody), httpRes) + } + } + + return res, nil +} diff --git a/internal/sdk/log.go b/internal/sdk/log.go new file mode 100644 index 0000000..5ceafa9 --- /dev/null +++ b/internal/sdk/log.go @@ -0,0 +1,206 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package sdk + +import ( + "bytes" + "context" + "fmt" + "github.com/LukeHagar/terraform-provider-PlexAPI/internal/sdk/pkg/models/operations" + "github.com/LukeHagar/terraform-provider-PlexAPI/internal/sdk/pkg/models/sdkerrors" + "github.com/LukeHagar/terraform-provider-PlexAPI/internal/sdk/pkg/utils" + "io" + "net/http" + "strings" +) + +// Log - Submit logs to the Log Handler for Plex Media Server +type Log struct { + sdkConfiguration sdkConfiguration +} + +func newLog(sdkConfig sdkConfiguration) *Log { + return &Log{ + sdkConfiguration: sdkConfig, + } +} + +// LogLine - Logging a single line message. +// This endpoint will write a single-line log message, including a level and source to the main Plex Media Server log. +func (s *Log) LogLine(ctx context.Context, request operations.LogLineRequest) (*operations.LogLineResponse, error) { + baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) + url := strings.TrimSuffix(baseURL, "/") + "/log" + + req, err := http.NewRequestWithContext(ctx, "GET", url, 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) + } + + client := s.sdkConfiguration.SecurityClient + + httpRes, err := client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %w", err) + } + if httpRes == nil { + return nil, fmt.Errorf("error sending request: no response") + } + + 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)) + + contentType := httpRes.Header.Get("Content-Type") + + res := &operations.LogLineResponse{ + StatusCode: httpRes.StatusCode, + ContentType: contentType, + RawResponse: httpRes, + } + switch { + case httpRes.StatusCode == 200: + fallthrough + case httpRes.StatusCode == 400: + case httpRes.StatusCode == 401: + switch { + case utils.MatchContentType(contentType, `application/json`): + var out operations.LogLineResponseBody + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + res.Object = &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", contentType), httpRes.StatusCode, string(rawBody), httpRes) + } + } + + return res, nil +} + +// LogMultiLine - Logging a multi-line message +// This endpoint will write multiple lines to the main Plex Media Server log in a single request. It takes a set of query strings as would normally sent to the above GET endpoint as a linefeed-separated block of POST data. The parameters for each query string match as above. +func (s *Log) LogMultiLine(ctx context.Context) (*operations.LogMultiLineResponse, error) { + baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) + url := strings.TrimSuffix(baseURL, "/") + "/log" + + req, err := http.NewRequestWithContext(ctx, "POST", url, 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) + + client := s.sdkConfiguration.SecurityClient + + httpRes, err := client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %w", err) + } + if httpRes == nil { + return nil, fmt.Errorf("error sending request: no response") + } + + 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)) + + contentType := httpRes.Header.Get("Content-Type") + + res := &operations.LogMultiLineResponse{ + StatusCode: httpRes.StatusCode, + ContentType: contentType, + RawResponse: httpRes, + } + switch { + case httpRes.StatusCode == 200: + fallthrough + case httpRes.StatusCode == 400: + case httpRes.StatusCode == 401: + switch { + case utils.MatchContentType(contentType, `application/json`): + var out operations.LogMultiLineResponseBody + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + res.Object = &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", contentType), httpRes.StatusCode, string(rawBody), httpRes) + } + } + + return res, nil +} + +// EnablePaperTrail - Enabling Papertrail +// This endpoint will enable all Plex Media Serverlogs to be sent to the Papertrail networked logging site for a period of time. +func (s *Log) EnablePaperTrail(ctx context.Context) (*operations.EnablePaperTrailResponse, error) { + baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) + url := strings.TrimSuffix(baseURL, "/") + "/log/networked" + + req, err := http.NewRequestWithContext(ctx, "GET", url, 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) + + client := s.sdkConfiguration.SecurityClient + + httpRes, err := client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %w", err) + } + if httpRes == nil { + return nil, fmt.Errorf("error sending request: no response") + } + + 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)) + + contentType := httpRes.Header.Get("Content-Type") + + res := &operations.EnablePaperTrailResponse{ + StatusCode: httpRes.StatusCode, + ContentType: contentType, + RawResponse: httpRes, + } + switch { + case httpRes.StatusCode == 200: + fallthrough + case httpRes.StatusCode == 400: + fallthrough + case httpRes.StatusCode == 403: + case httpRes.StatusCode == 401: + switch { + case utils.MatchContentType(contentType, `application/json`): + var out operations.EnablePaperTrailResponseBody + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + res.Object = &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", contentType), httpRes.StatusCode, string(rawBody), httpRes) + } + } + + return res, nil +} diff --git a/internal/sdk/media.go b/internal/sdk/media.go new file mode 100644 index 0000000..4252b23 --- /dev/null +++ b/internal/sdk/media.go @@ -0,0 +1,212 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package sdk + +import ( + "bytes" + "context" + "fmt" + "github.com/LukeHagar/terraform-provider-PlexAPI/internal/sdk/pkg/models/operations" + "github.com/LukeHagar/terraform-provider-PlexAPI/internal/sdk/pkg/models/sdkerrors" + "github.com/LukeHagar/terraform-provider-PlexAPI/internal/sdk/pkg/utils" + "io" + "net/http" + "strings" +) + +// Media - API Calls interacting with Plex Media Server Media +type Media struct { + sdkConfiguration sdkConfiguration +} + +func newMedia(sdkConfig sdkConfiguration) *Media { + return &Media{ + sdkConfiguration: sdkConfig, + } +} + +// MarkPlayed - Mark Media Played +// This will mark the provided media key as Played. +func (s *Media) MarkPlayed(ctx context.Context, request operations.MarkPlayedRequest) (*operations.MarkPlayedResponse, error) { + baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) + url := strings.TrimSuffix(baseURL, "/") + "/:/scrobble" + + req, err := http.NewRequestWithContext(ctx, "GET", url, 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) + } + + client := s.sdkConfiguration.SecurityClient + + httpRes, err := client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %w", err) + } + if httpRes == nil { + return nil, fmt.Errorf("error sending request: no response") + } + + 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)) + + contentType := httpRes.Header.Get("Content-Type") + + res := &operations.MarkPlayedResponse{ + StatusCode: httpRes.StatusCode, + ContentType: contentType, + RawResponse: httpRes, + } + switch { + case httpRes.StatusCode == 200: + fallthrough + case httpRes.StatusCode == 400: + case httpRes.StatusCode == 401: + switch { + case utils.MatchContentType(contentType, `application/json`): + var out operations.MarkPlayedResponseBody + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + res.Object = &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", contentType), httpRes.StatusCode, string(rawBody), httpRes) + } + } + + return res, nil +} + +// MarkUnplayed - Mark Media Unplayed +// This will mark the provided media key as Unplayed. +func (s *Media) MarkUnplayed(ctx context.Context, request operations.MarkUnplayedRequest) (*operations.MarkUnplayedResponse, error) { + baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) + url := strings.TrimSuffix(baseURL, "/") + "/:/unscrobble" + + req, err := http.NewRequestWithContext(ctx, "GET", url, 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) + } + + client := s.sdkConfiguration.SecurityClient + + httpRes, err := client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %w", err) + } + if httpRes == nil { + return nil, fmt.Errorf("error sending request: no response") + } + + 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)) + + contentType := httpRes.Header.Get("Content-Type") + + res := &operations.MarkUnplayedResponse{ + StatusCode: httpRes.StatusCode, + ContentType: contentType, + RawResponse: httpRes, + } + switch { + case httpRes.StatusCode == 200: + fallthrough + case httpRes.StatusCode == 400: + case httpRes.StatusCode == 401: + switch { + case utils.MatchContentType(contentType, `application/json`): + var out operations.MarkUnplayedResponseBody + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + res.Object = &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", contentType), httpRes.StatusCode, string(rawBody), httpRes) + } + } + + return res, nil +} + +// UpdatePlayProgress - Update Media Play Progress +// This API command can be used to update the play progress of a media item. +func (s *Media) UpdatePlayProgress(ctx context.Context, request operations.UpdatePlayProgressRequest) (*operations.UpdatePlayProgressResponse, error) { + baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) + url := strings.TrimSuffix(baseURL, "/") + "/:/progress" + + req, err := http.NewRequestWithContext(ctx, "POST", url, 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) + } + + client := s.sdkConfiguration.SecurityClient + + httpRes, err := client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %w", err) + } + if httpRes == nil { + return nil, fmt.Errorf("error sending request: no response") + } + + 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)) + + contentType := httpRes.Header.Get("Content-Type") + + res := &operations.UpdatePlayProgressResponse{ + StatusCode: httpRes.StatusCode, + ContentType: contentType, + RawResponse: httpRes, + } + switch { + case httpRes.StatusCode == 200: + fallthrough + case httpRes.StatusCode == 400: + case httpRes.StatusCode == 401: + switch { + case utils.MatchContentType(contentType, `application/json`): + var out operations.UpdatePlayProgressResponseBody + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + res.Object = &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", contentType), httpRes.StatusCode, string(rawBody), httpRes) + } + } + + return res, nil +} diff --git a/internal/sdk/pkg/models/operations/addplaylistcontents.go b/internal/sdk/pkg/models/operations/addplaylistcontents.go new file mode 100644 index 0000000..7c841d3 --- /dev/null +++ b/internal/sdk/pkg/models/operations/addplaylistcontents.go @@ -0,0 +1,115 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package operations + +import ( + "net/http" +) + +type AddPlaylistContentsRequest struct { + // the ID of the playlist + PlaylistID float64 `pathParam:"style=simple,explode=false,name=playlistID"` + // the content URI for the playlist + URI string `queryParam:"style=form,explode=true,name=uri"` + // the play queue to add to a playlist + PlayQueueID float64 `queryParam:"style=form,explode=true,name=playQueueID"` +} + +func (o *AddPlaylistContentsRequest) GetPlaylistID() float64 { + if o == nil { + return 0.0 + } + return o.PlaylistID +} + +func (o *AddPlaylistContentsRequest) GetURI() string { + if o == nil { + return "" + } + return o.URI +} + +func (o *AddPlaylistContentsRequest) GetPlayQueueID() float64 { + if o == nil { + return 0.0 + } + return o.PlayQueueID +} + +type AddPlaylistContentsErrors struct { + Code *float64 `json:"code,omitempty"` + Message *string `json:"message,omitempty"` + Status *float64 `json:"status,omitempty"` +} + +func (o *AddPlaylistContentsErrors) GetCode() *float64 { + if o == nil { + return nil + } + return o.Code +} + +func (o *AddPlaylistContentsErrors) GetMessage() *string { + if o == nil { + return nil + } + return o.Message +} + +func (o *AddPlaylistContentsErrors) GetStatus() *float64 { + if o == nil { + return nil + } + return o.Status +} + +// AddPlaylistContentsResponseBody - Unauthorized - Returned if the X-Plex-Token is missing from the header or query. +type AddPlaylistContentsResponseBody struct { + Errors []AddPlaylistContentsErrors `json:"errors,omitempty"` +} + +func (o *AddPlaylistContentsResponseBody) GetErrors() []AddPlaylistContentsErrors { + if o == nil { + return nil + } + return o.Errors +} + +type AddPlaylistContentsResponse struct { + // HTTP response content type for this operation + ContentType string + // HTTP response status code for this operation + StatusCode int + // Raw HTTP response; suitable for custom response parsing + RawResponse *http.Response + // Unauthorized - Returned if the X-Plex-Token is missing from the header or query. + Object *AddPlaylistContentsResponseBody +} + +func (o *AddPlaylistContentsResponse) GetContentType() string { + if o == nil { + return "" + } + return o.ContentType +} + +func (o *AddPlaylistContentsResponse) GetStatusCode() int { + if o == nil { + return 0 + } + return o.StatusCode +} + +func (o *AddPlaylistContentsResponse) GetRawResponse() *http.Response { + if o == nil { + return nil + } + return o.RawResponse +} + +func (o *AddPlaylistContentsResponse) GetObject() *AddPlaylistContentsResponseBody { + if o == nil { + return nil + } + return o.Object +} diff --git a/internal/sdk/pkg/models/operations/applyupdates.go b/internal/sdk/pkg/models/operations/applyupdates.go new file mode 100644 index 0000000..c406738 --- /dev/null +++ b/internal/sdk/pkg/models/operations/applyupdates.go @@ -0,0 +1,164 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package operations + +import ( + "encoding/json" + "fmt" + "net/http" +) + +// Tonight - Indicate that you want the update to run during the next Butler execution. Omitting this or setting it to false indicates that the update should install +type Tonight int64 + +const ( + TonightZero Tonight = 0 + TonightOne Tonight = 1 +) + +func (e Tonight) ToPointer() *Tonight { + return &e +} + +func (e *Tonight) UnmarshalJSON(data []byte) error { + var v int64 + if err := json.Unmarshal(data, &v); err != nil { + return err + } + switch v { + case 0: + fallthrough + case 1: + *e = Tonight(v) + return nil + default: + return fmt.Errorf("invalid value for Tonight: %v", v) + } +} + +// Skip - Indicate that the latest version should be marked as skipped. The entry for this version will have the `state` set to `skipped`. +type Skip int64 + +const ( + SkipZero Skip = 0 + SkipOne Skip = 1 +) + +func (e Skip) ToPointer() *Skip { + return &e +} + +func (e *Skip) UnmarshalJSON(data []byte) error { + var v int64 + if err := json.Unmarshal(data, &v); err != nil { + return err + } + switch v { + case 0: + fallthrough + case 1: + *e = Skip(v) + return nil + default: + return fmt.Errorf("invalid value for Skip: %v", v) + } +} + +type ApplyUpdatesRequest struct { + // Indicate that you want the update to run during the next Butler execution. Omitting this or setting it to false indicates that the update should install + Tonight *Tonight `queryParam:"style=form,explode=true,name=tonight"` + // Indicate that the latest version should be marked as skipped. The entry for this version will have the `state` set to `skipped`. + Skip *Skip `queryParam:"style=form,explode=true,name=skip"` +} + +func (o *ApplyUpdatesRequest) GetTonight() *Tonight { + if o == nil { + return nil + } + return o.Tonight +} + +func (o *ApplyUpdatesRequest) GetSkip() *Skip { + if o == nil { + return nil + } + return o.Skip +} + +type ApplyUpdatesErrors struct { + Code *float64 `json:"code,omitempty"` + Message *string `json:"message,omitempty"` + Status *float64 `json:"status,omitempty"` +} + +func (o *ApplyUpdatesErrors) GetCode() *float64 { + if o == nil { + return nil + } + return o.Code +} + +func (o *ApplyUpdatesErrors) GetMessage() *string { + if o == nil { + return nil + } + return o.Message +} + +func (o *ApplyUpdatesErrors) GetStatus() *float64 { + if o == nil { + return nil + } + return o.Status +} + +// ApplyUpdatesResponseBody - Unauthorized - Returned if the X-Plex-Token is missing from the header or query. +type ApplyUpdatesResponseBody struct { + Errors []ApplyUpdatesErrors `json:"errors,omitempty"` +} + +func (o *ApplyUpdatesResponseBody) GetErrors() []ApplyUpdatesErrors { + if o == nil { + return nil + } + return o.Errors +} + +type ApplyUpdatesResponse struct { + // HTTP response content type for this operation + ContentType string + // HTTP response status code for this operation + StatusCode int + // Raw HTTP response; suitable for custom response parsing + RawResponse *http.Response + // Unauthorized - Returned if the X-Plex-Token is missing from the header or query. + Object *ApplyUpdatesResponseBody +} + +func (o *ApplyUpdatesResponse) GetContentType() string { + if o == nil { + return "" + } + return o.ContentType +} + +func (o *ApplyUpdatesResponse) GetStatusCode() int { + if o == nil { + return 0 + } + return o.StatusCode +} + +func (o *ApplyUpdatesResponse) GetRawResponse() *http.Response { + if o == nil { + return nil + } + return o.RawResponse +} + +func (o *ApplyUpdatesResponse) GetObject() *ApplyUpdatesResponseBody { + if o == nil { + return nil + } + return o.Object +} diff --git a/internal/sdk/pkg/models/operations/cancelserveractivities.go b/internal/sdk/pkg/models/operations/cancelserveractivities.go new file mode 100644 index 0000000..fd56074 --- /dev/null +++ b/internal/sdk/pkg/models/operations/cancelserveractivities.go @@ -0,0 +1,97 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package operations + +import ( + "net/http" +) + +type CancelServerActivitiesRequest struct { + // The UUID of the activity to cancel. + ActivityUUID string `pathParam:"style=simple,explode=false,name=activityUUID"` +} + +func (o *CancelServerActivitiesRequest) GetActivityUUID() string { + if o == nil { + return "" + } + return o.ActivityUUID +} + +type CancelServerActivitiesErrors struct { + Code *float64 `json:"code,omitempty"` + Message *string `json:"message,omitempty"` + Status *float64 `json:"status,omitempty"` +} + +func (o *CancelServerActivitiesErrors) GetCode() *float64 { + if o == nil { + return nil + } + return o.Code +} + +func (o *CancelServerActivitiesErrors) GetMessage() *string { + if o == nil { + return nil + } + return o.Message +} + +func (o *CancelServerActivitiesErrors) GetStatus() *float64 { + if o == nil { + return nil + } + return o.Status +} + +// CancelServerActivitiesResponseBody - Unauthorized - Returned if the X-Plex-Token is missing from the header or query. +type CancelServerActivitiesResponseBody struct { + Errors []CancelServerActivitiesErrors `json:"errors,omitempty"` +} + +func (o *CancelServerActivitiesResponseBody) GetErrors() []CancelServerActivitiesErrors { + if o == nil { + return nil + } + return o.Errors +} + +type CancelServerActivitiesResponse struct { + // HTTP response content type for this operation + ContentType string + // HTTP response status code for this operation + StatusCode int + // Raw HTTP response; suitable for custom response parsing + RawResponse *http.Response + // Unauthorized - Returned if the X-Plex-Token is missing from the header or query. + Object *CancelServerActivitiesResponseBody +} + +func (o *CancelServerActivitiesResponse) GetContentType() string { + if o == nil { + return "" + } + return o.ContentType +} + +func (o *CancelServerActivitiesResponse) GetStatusCode() int { + if o == nil { + return 0 + } + return o.StatusCode +} + +func (o *CancelServerActivitiesResponse) GetRawResponse() *http.Response { + if o == nil { + return nil + } + return o.RawResponse +} + +func (o *CancelServerActivitiesResponse) GetObject() *CancelServerActivitiesResponseBody { + if o == nil { + return nil + } + return o.Object +} diff --git a/internal/sdk/pkg/models/operations/checkforupdates.go b/internal/sdk/pkg/models/operations/checkforupdates.go new file mode 100644 index 0000000..3609613 --- /dev/null +++ b/internal/sdk/pkg/models/operations/checkforupdates.go @@ -0,0 +1,127 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package operations + +import ( + "encoding/json" + "fmt" + "net/http" +) + +// Download - Indicate that you want to start download any updates found. +type Download int64 + +const ( + DownloadZero Download = 0 + DownloadOne Download = 1 +) + +func (e Download) ToPointer() *Download { + return &e +} + +func (e *Download) UnmarshalJSON(data []byte) error { + var v int64 + if err := json.Unmarshal(data, &v); err != nil { + return err + } + switch v { + case 0: + fallthrough + case 1: + *e = Download(v) + return nil + default: + return fmt.Errorf("invalid value for Download: %v", v) + } +} + +type CheckForUpdatesRequest struct { + // Indicate that you want to start download any updates found. + Download *Download `queryParam:"style=form,explode=true,name=download"` +} + +func (o *CheckForUpdatesRequest) GetDownload() *Download { + if o == nil { + return nil + } + return o.Download +} + +type CheckForUpdatesErrors struct { + Code *float64 `json:"code,omitempty"` + Message *string `json:"message,omitempty"` + Status *float64 `json:"status,omitempty"` +} + +func (o *CheckForUpdatesErrors) GetCode() *float64 { + if o == nil { + return nil + } + return o.Code +} + +func (o *CheckForUpdatesErrors) GetMessage() *string { + if o == nil { + return nil + } + return o.Message +} + +func (o *CheckForUpdatesErrors) GetStatus() *float64 { + if o == nil { + return nil + } + return o.Status +} + +// CheckForUpdatesResponseBody - Unauthorized - Returned if the X-Plex-Token is missing from the header or query. +type CheckForUpdatesResponseBody struct { + Errors []CheckForUpdatesErrors `json:"errors,omitempty"` +} + +func (o *CheckForUpdatesResponseBody) GetErrors() []CheckForUpdatesErrors { + if o == nil { + return nil + } + return o.Errors +} + +type CheckForUpdatesResponse struct { + // HTTP response content type for this operation + ContentType string + // HTTP response status code for this operation + StatusCode int + // Raw HTTP response; suitable for custom response parsing + RawResponse *http.Response + // Unauthorized - Returned if the X-Plex-Token is missing from the header or query. + Object *CheckForUpdatesResponseBody +} + +func (o *CheckForUpdatesResponse) GetContentType() string { + if o == nil { + return "" + } + return o.ContentType +} + +func (o *CheckForUpdatesResponse) GetStatusCode() int { + if o == nil { + return 0 + } + return o.StatusCode +} + +func (o *CheckForUpdatesResponse) GetRawResponse() *http.Response { + if o == nil { + return nil + } + return o.RawResponse +} + +func (o *CheckForUpdatesResponse) GetObject() *CheckForUpdatesResponseBody { + if o == nil { + return nil + } + return o.Object +} diff --git a/internal/sdk/pkg/models/operations/clearplaylistcontents.go b/internal/sdk/pkg/models/operations/clearplaylistcontents.go new file mode 100644 index 0000000..4302d99 --- /dev/null +++ b/internal/sdk/pkg/models/operations/clearplaylistcontents.go @@ -0,0 +1,97 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package operations + +import ( + "net/http" +) + +type ClearPlaylistContentsRequest struct { + // the ID of the playlist + PlaylistID float64 `pathParam:"style=simple,explode=false,name=playlistID"` +} + +func (o *ClearPlaylistContentsRequest) GetPlaylistID() float64 { + if o == nil { + return 0.0 + } + return o.PlaylistID +} + +type ClearPlaylistContentsErrors struct { + Code *float64 `json:"code,omitempty"` + Message *string `json:"message,omitempty"` + Status *float64 `json:"status,omitempty"` +} + +func (o *ClearPlaylistContentsErrors) GetCode() *float64 { + if o == nil { + return nil + } + return o.Code +} + +func (o *ClearPlaylistContentsErrors) GetMessage() *string { + if o == nil { + return nil + } + return o.Message +} + +func (o *ClearPlaylistContentsErrors) GetStatus() *float64 { + if o == nil { + return nil + } + return o.Status +} + +// ClearPlaylistContentsResponseBody - Unauthorized - Returned if the X-Plex-Token is missing from the header or query. +type ClearPlaylistContentsResponseBody struct { + Errors []ClearPlaylistContentsErrors `json:"errors,omitempty"` +} + +func (o *ClearPlaylistContentsResponseBody) GetErrors() []ClearPlaylistContentsErrors { + if o == nil { + return nil + } + return o.Errors +} + +type ClearPlaylistContentsResponse struct { + // HTTP response content type for this operation + ContentType string + // HTTP response status code for this operation + StatusCode int + // Raw HTTP response; suitable for custom response parsing + RawResponse *http.Response + // Unauthorized - Returned if the X-Plex-Token is missing from the header or query. + Object *ClearPlaylistContentsResponseBody +} + +func (o *ClearPlaylistContentsResponse) GetContentType() string { + if o == nil { + return "" + } + return o.ContentType +} + +func (o *ClearPlaylistContentsResponse) GetStatusCode() int { + if o == nil { + return 0 + } + return o.StatusCode +} + +func (o *ClearPlaylistContentsResponse) GetRawResponse() *http.Response { + if o == nil { + return nil + } + return o.RawResponse +} + +func (o *ClearPlaylistContentsResponse) GetObject() *ClearPlaylistContentsResponseBody { + if o == nil { + return nil + } + return o.Object +} diff --git a/internal/sdk/pkg/models/operations/createplaylist.go b/internal/sdk/pkg/models/operations/createplaylist.go new file mode 100644 index 0000000..d372f13 --- /dev/null +++ b/internal/sdk/pkg/models/operations/createplaylist.go @@ -0,0 +1,194 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package operations + +import ( + "encoding/json" + "fmt" + "net/http" +) + +// Type - type of playlist to create +type Type string + +const ( + TypeAudio Type = "audio" + TypeVideo Type = "video" + TypePhoto Type = "photo" +) + +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 "audio": + fallthrough + case "video": + fallthrough + case "photo": + *e = Type(v) + return nil + default: + return fmt.Errorf("invalid value for Type: %v", v) + } +} + +// Smart - whether the playlist is smart or not +type Smart int64 + +const ( + SmartZero Smart = 0 + SmartOne Smart = 1 +) + +func (e Smart) ToPointer() *Smart { + return &e +} + +func (e *Smart) UnmarshalJSON(data []byte) error { + var v int64 + if err := json.Unmarshal(data, &v); err != nil { + return err + } + switch v { + case 0: + fallthrough + case 1: + *e = Smart(v) + return nil + default: + return fmt.Errorf("invalid value for Smart: %v", v) + } +} + +type CreatePlaylistRequest struct { + // name of the playlist + Title string `queryParam:"style=form,explode=true,name=title"` + // type of playlist to create + Type Type `queryParam:"style=form,explode=true,name=type"` + // whether the playlist is smart or not + Smart Smart `queryParam:"style=form,explode=true,name=smart"` + // the content URI for the playlist + URI *string `queryParam:"style=form,explode=true,name=uri"` + // the play queue to copy to a playlist + PlayQueueID *float64 `queryParam:"style=form,explode=true,name=playQueueID"` +} + +func (o *CreatePlaylistRequest) GetTitle() string { + if o == nil { + return "" + } + return o.Title +} + +func (o *CreatePlaylistRequest) GetType() Type { + if o == nil { + return Type("") + } + return o.Type +} + +func (o *CreatePlaylistRequest) GetSmart() Smart { + if o == nil { + return Smart(0) + } + return o.Smart +} + +func (o *CreatePlaylistRequest) GetURI() *string { + if o == nil { + return nil + } + return o.URI +} + +func (o *CreatePlaylistRequest) GetPlayQueueID() *float64 { + if o == nil { + return nil + } + return o.PlayQueueID +} + +type CreatePlaylistErrors struct { + Code *float64 `json:"code,omitempty"` + Message *string `json:"message,omitempty"` + Status *float64 `json:"status,omitempty"` +} + +func (o *CreatePlaylistErrors) GetCode() *float64 { + if o == nil { + return nil + } + return o.Code +} + +func (o *CreatePlaylistErrors) GetMessage() *string { + if o == nil { + return nil + } + return o.Message +} + +func (o *CreatePlaylistErrors) GetStatus() *float64 { + if o == nil { + return nil + } + return o.Status +} + +// CreatePlaylistResponseBody - Unauthorized - Returned if the X-Plex-Token is missing from the header or query. +type CreatePlaylistResponseBody struct { + Errors []CreatePlaylistErrors `json:"errors,omitempty"` +} + +func (o *CreatePlaylistResponseBody) GetErrors() []CreatePlaylistErrors { + if o == nil { + return nil + } + return o.Errors +} + +type CreatePlaylistResponse struct { + // HTTP response content type for this operation + ContentType string + // HTTP response status code for this operation + StatusCode int + // Raw HTTP response; suitable for custom response parsing + RawResponse *http.Response + // Unauthorized - Returned if the X-Plex-Token is missing from the header or query. + Object *CreatePlaylistResponseBody +} + +func (o *CreatePlaylistResponse) GetContentType() string { + if o == nil { + return "" + } + return o.ContentType +} + +func (o *CreatePlaylistResponse) GetStatusCode() int { + if o == nil { + return 0 + } + return o.StatusCode +} + +func (o *CreatePlaylistResponse) GetRawResponse() *http.Response { + if o == nil { + return nil + } + return o.RawResponse +} + +func (o *CreatePlaylistResponse) GetObject() *CreatePlaylistResponseBody { + if o == nil { + return nil + } + return o.Object +} diff --git a/internal/sdk/pkg/models/operations/deletelibrary.go b/internal/sdk/pkg/models/operations/deletelibrary.go new file mode 100644 index 0000000..ce4c810 --- /dev/null +++ b/internal/sdk/pkg/models/operations/deletelibrary.go @@ -0,0 +1,97 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package operations + +import ( + "net/http" +) + +type DeleteLibraryRequest struct { + // the Id of the library to query + SectionID float64 `pathParam:"style=simple,explode=false,name=sectionId"` +} + +func (o *DeleteLibraryRequest) GetSectionID() float64 { + if o == nil { + return 0.0 + } + return o.SectionID +} + +type DeleteLibraryErrors struct { + Code *float64 `json:"code,omitempty"` + Message *string `json:"message,omitempty"` + Status *float64 `json:"status,omitempty"` +} + +func (o *DeleteLibraryErrors) GetCode() *float64 { + if o == nil { + return nil + } + return o.Code +} + +func (o *DeleteLibraryErrors) GetMessage() *string { + if o == nil { + return nil + } + return o.Message +} + +func (o *DeleteLibraryErrors) GetStatus() *float64 { + if o == nil { + return nil + } + return o.Status +} + +// DeleteLibraryResponseBody - Unauthorized - Returned if the X-Plex-Token is missing from the header or query. +type DeleteLibraryResponseBody struct { + Errors []DeleteLibraryErrors `json:"errors,omitempty"` +} + +func (o *DeleteLibraryResponseBody) GetErrors() []DeleteLibraryErrors { + if o == nil { + return nil + } + return o.Errors +} + +type DeleteLibraryResponse struct { + // HTTP response content type for this operation + ContentType string + // HTTP response status code for this operation + StatusCode int + // Raw HTTP response; suitable for custom response parsing + RawResponse *http.Response + // Unauthorized - Returned if the X-Plex-Token is missing from the header or query. + Object *DeleteLibraryResponseBody +} + +func (o *DeleteLibraryResponse) GetContentType() string { + if o == nil { + return "" + } + return o.ContentType +} + +func (o *DeleteLibraryResponse) GetStatusCode() int { + if o == nil { + return 0 + } + return o.StatusCode +} + +func (o *DeleteLibraryResponse) GetRawResponse() *http.Response { + if o == nil { + return nil + } + return o.RawResponse +} + +func (o *DeleteLibraryResponse) GetObject() *DeleteLibraryResponseBody { + if o == nil { + return nil + } + return o.Object +} diff --git a/internal/sdk/pkg/models/operations/deleteplaylist.go b/internal/sdk/pkg/models/operations/deleteplaylist.go new file mode 100644 index 0000000..085ac77 --- /dev/null +++ b/internal/sdk/pkg/models/operations/deleteplaylist.go @@ -0,0 +1,97 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package operations + +import ( + "net/http" +) + +type DeletePlaylistRequest struct { + // the ID of the playlist + PlaylistID float64 `pathParam:"style=simple,explode=false,name=playlistID"` +} + +func (o *DeletePlaylistRequest) GetPlaylistID() float64 { + if o == nil { + return 0.0 + } + return o.PlaylistID +} + +type DeletePlaylistErrors struct { + Code *float64 `json:"code,omitempty"` + Message *string `json:"message,omitempty"` + Status *float64 `json:"status,omitempty"` +} + +func (o *DeletePlaylistErrors) GetCode() *float64 { + if o == nil { + return nil + } + return o.Code +} + +func (o *DeletePlaylistErrors) GetMessage() *string { + if o == nil { + return nil + } + return o.Message +} + +func (o *DeletePlaylistErrors) GetStatus() *float64 { + if o == nil { + return nil + } + return o.Status +} + +// DeletePlaylistResponseBody - Unauthorized - Returned if the X-Plex-Token is missing from the header or query. +type DeletePlaylistResponseBody struct { + Errors []DeletePlaylistErrors `json:"errors,omitempty"` +} + +func (o *DeletePlaylistResponseBody) GetErrors() []DeletePlaylistErrors { + if o == nil { + return nil + } + return o.Errors +} + +type DeletePlaylistResponse struct { + // HTTP response content type for this operation + ContentType string + // HTTP response status code for this operation + StatusCode int + // Raw HTTP response; suitable for custom response parsing + RawResponse *http.Response + // Unauthorized - Returned if the X-Plex-Token is missing from the header or query. + Object *DeletePlaylistResponseBody +} + +func (o *DeletePlaylistResponse) GetContentType() string { + if o == nil { + return "" + } + return o.ContentType +} + +func (o *DeletePlaylistResponse) GetStatusCode() int { + if o == nil { + return 0 + } + return o.StatusCode +} + +func (o *DeletePlaylistResponse) GetRawResponse() *http.Response { + if o == nil { + return nil + } + return o.RawResponse +} + +func (o *DeletePlaylistResponse) GetObject() *DeletePlaylistResponseBody { + if o == nil { + return nil + } + return o.Object +} diff --git a/internal/sdk/pkg/models/operations/enablepapertrail.go b/internal/sdk/pkg/models/operations/enablepapertrail.go new file mode 100644 index 0000000..4dceac8 --- /dev/null +++ b/internal/sdk/pkg/models/operations/enablepapertrail.go @@ -0,0 +1,85 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package operations + +import ( + "net/http" +) + +type EnablePaperTrailErrors struct { + Code *float64 `json:"code,omitempty"` + Message *string `json:"message,omitempty"` + Status *float64 `json:"status,omitempty"` +} + +func (o *EnablePaperTrailErrors) GetCode() *float64 { + if o == nil { + return nil + } + return o.Code +} + +func (o *EnablePaperTrailErrors) GetMessage() *string { + if o == nil { + return nil + } + return o.Message +} + +func (o *EnablePaperTrailErrors) GetStatus() *float64 { + if o == nil { + return nil + } + return o.Status +} + +// EnablePaperTrailResponseBody - Unauthorized - Returned if the X-Plex-Token is missing from the header or query. +type EnablePaperTrailResponseBody struct { + Errors []EnablePaperTrailErrors `json:"errors,omitempty"` +} + +func (o *EnablePaperTrailResponseBody) GetErrors() []EnablePaperTrailErrors { + if o == nil { + return nil + } + return o.Errors +} + +type EnablePaperTrailResponse struct { + // HTTP response content type for this operation + ContentType string + // HTTP response status code for this operation + StatusCode int + // Raw HTTP response; suitable for custom response parsing + RawResponse *http.Response + // Unauthorized - Returned if the X-Plex-Token is missing from the header or query. + Object *EnablePaperTrailResponseBody +} + +func (o *EnablePaperTrailResponse) GetContentType() string { + if o == nil { + return "" + } + return o.ContentType +} + +func (o *EnablePaperTrailResponse) GetStatusCode() int { + if o == nil { + return 0 + } + return o.StatusCode +} + +func (o *EnablePaperTrailResponse) GetRawResponse() *http.Response { + if o == nil { + return nil + } + return o.RawResponse +} + +func (o *EnablePaperTrailResponse) GetObject() *EnablePaperTrailResponseBody { + if o == nil { + return nil + } + return o.Object +} diff --git a/internal/sdk/pkg/models/operations/getavailableclients.go b/internal/sdk/pkg/models/operations/getavailableclients.go new file mode 100644 index 0000000..5811a22 --- /dev/null +++ b/internal/sdk/pkg/models/operations/getavailableclients.go @@ -0,0 +1,215 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package operations + +import ( + "net/http" +) + +type GetAvailableClientsErrors struct { + Code *float64 `json:"code,omitempty"` + Message *string `json:"message,omitempty"` + Status *float64 `json:"status,omitempty"` +} + +func (o *GetAvailableClientsErrors) GetCode() *float64 { + if o == nil { + return nil + } + return o.Code +} + +func (o *GetAvailableClientsErrors) GetMessage() *string { + if o == nil { + return nil + } + return o.Message +} + +func (o *GetAvailableClientsErrors) GetStatus() *float64 { + if o == nil { + return nil + } + return o.Status +} + +// GetAvailableClientsResponseBody - Unauthorized - Returned if the X-Plex-Token is missing from the header or query. +type GetAvailableClientsResponseBody struct { + Errors []GetAvailableClientsErrors `json:"errors,omitempty"` +} + +func (o *GetAvailableClientsResponseBody) GetErrors() []GetAvailableClientsErrors { + if o == nil { + return nil + } + return o.Errors +} + +type Server struct { + Name *string `json:"name,omitempty"` + Host *string `json:"host,omitempty"` + Address *string `json:"address,omitempty"` + Port *float64 `json:"port,omitempty"` + MachineIdentifier *string `json:"machineIdentifier,omitempty"` + Version *string `json:"version,omitempty"` + Protocol *string `json:"protocol,omitempty"` + Product *string `json:"product,omitempty"` + DeviceClass *string `json:"deviceClass,omitempty"` + ProtocolVersion *float64 `json:"protocolVersion,omitempty"` + ProtocolCapabilities *string `json:"protocolCapabilities,omitempty"` +} + +func (o *Server) GetName() *string { + if o == nil { + return nil + } + return o.Name +} + +func (o *Server) GetHost() *string { + if o == nil { + return nil + } + return o.Host +} + +func (o *Server) GetAddress() *string { + if o == nil { + return nil + } + return o.Address +} + +func (o *Server) GetPort() *float64 { + if o == nil { + return nil + } + return o.Port +} + +func (o *Server) GetMachineIdentifier() *string { + if o == nil { + return nil + } + return o.MachineIdentifier +} + +func (o *Server) GetVersion() *string { + if o == nil { + return nil + } + return o.Version +} + +func (o *Server) GetProtocol() *string { + if o == nil { + return nil + } + return o.Protocol +} + +func (o *Server) GetProduct() *string { + if o == nil { + return nil + } + return o.Product +} + +func (o *Server) GetDeviceClass() *string { + if o == nil { + return nil + } + return o.DeviceClass +} + +func (o *Server) GetProtocolVersion() *float64 { + if o == nil { + return nil + } + return o.ProtocolVersion +} + +func (o *Server) GetProtocolCapabilities() *string { + if o == nil { + return nil + } + return o.ProtocolCapabilities +} + +type GetAvailableClientsMediaContainer struct { + Size *float64 `json:"size,omitempty"` + Server []Server `json:"Server,omitempty"` +} + +func (o *GetAvailableClientsMediaContainer) GetSize() *float64 { + if o == nil { + return nil + } + return o.Size +} + +func (o *GetAvailableClientsMediaContainer) GetServer() []Server { + if o == nil { + return nil + } + return o.Server +} + +type ResponseBody struct { + MediaContainer *GetAvailableClientsMediaContainer `json:"MediaContainer,omitempty"` +} + +func (o *ResponseBody) GetMediaContainer() *GetAvailableClientsMediaContainer { + if o == nil { + return nil + } + return o.MediaContainer +} + +type GetAvailableClientsResponse struct { + // HTTP response content type for this operation + ContentType string + // HTTP response status code for this operation + StatusCode int + // Raw HTTP response; suitable for custom response parsing + RawResponse *http.Response + // Available Clients + ResponseBodies []ResponseBody + // Unauthorized - Returned if the X-Plex-Token is missing from the header or query. + Object *GetAvailableClientsResponseBody +} + +func (o *GetAvailableClientsResponse) GetContentType() string { + if o == nil { + return "" + } + return o.ContentType +} + +func (o *GetAvailableClientsResponse) GetStatusCode() int { + if o == nil { + return 0 + } + return o.StatusCode +} + +func (o *GetAvailableClientsResponse) GetRawResponse() *http.Response { + if o == nil { + return nil + } + return o.RawResponse +} + +func (o *GetAvailableClientsResponse) GetResponseBodies() []ResponseBody { + if o == nil { + return nil + } + return o.ResponseBodies +} + +func (o *GetAvailableClientsResponse) GetObject() *GetAvailableClientsResponseBody { + if o == nil { + return nil + } + return o.Object +} diff --git a/internal/sdk/pkg/models/operations/getbutlertasks.go b/internal/sdk/pkg/models/operations/getbutlertasks.go new file mode 100644 index 0000000..dcf8933 --- /dev/null +++ b/internal/sdk/pkg/models/operations/getbutlertasks.go @@ -0,0 +1,168 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package operations + +import ( + "net/http" +) + +type GetButlerTasksErrors struct { + Code *float64 `json:"code,omitempty"` + Message *string `json:"message,omitempty"` + Status *float64 `json:"status,omitempty"` +} + +func (o *GetButlerTasksErrors) GetCode() *float64 { + if o == nil { + return nil + } + return o.Code +} + +func (o *GetButlerTasksErrors) GetMessage() *string { + if o == nil { + return nil + } + return o.Message +} + +func (o *GetButlerTasksErrors) GetStatus() *float64 { + if o == nil { + return nil + } + return o.Status +} + +// GetButlerTasksButlerResponseBody - Unauthorized - Returned if the X-Plex-Token is missing from the header or query. +type GetButlerTasksButlerResponseBody struct { + Errors []GetButlerTasksErrors `json:"errors,omitempty"` +} + +func (o *GetButlerTasksButlerResponseBody) GetErrors() []GetButlerTasksErrors { + if o == nil { + return nil + } + return o.Errors +} + +type ButlerTask struct { + Name *string `json:"name,omitempty"` + Interval *float64 `json:"interval,omitempty"` + ScheduleRandomized *bool `json:"scheduleRandomized,omitempty"` + Enabled *bool `json:"enabled,omitempty"` + Title *string `json:"title,omitempty"` + Description *string `json:"description,omitempty"` +} + +func (o *ButlerTask) GetName() *string { + if o == nil { + return nil + } + return o.Name +} + +func (o *ButlerTask) GetInterval() *float64 { + if o == nil { + return nil + } + return o.Interval +} + +func (o *ButlerTask) GetScheduleRandomized() *bool { + if o == nil { + return nil + } + return o.ScheduleRandomized +} + +func (o *ButlerTask) GetEnabled() *bool { + if o == nil { + return nil + } + return o.Enabled +} + +func (o *ButlerTask) GetTitle() *string { + if o == nil { + return nil + } + return o.Title +} + +func (o *ButlerTask) GetDescription() *string { + if o == nil { + return nil + } + return o.Description +} + +type ButlerTasks struct { + ButlerTask []ButlerTask `json:"ButlerTask,omitempty"` +} + +func (o *ButlerTasks) GetButlerTask() []ButlerTask { + if o == nil { + return nil + } + return o.ButlerTask +} + +// GetButlerTasksResponseBody - All butler tasks +type GetButlerTasksResponseBody struct { + ButlerTasks *ButlerTasks `json:"ButlerTasks,omitempty"` +} + +func (o *GetButlerTasksResponseBody) GetButlerTasks() *ButlerTasks { + if o == nil { + return nil + } + return o.ButlerTasks +} + +type GetButlerTasksResponse struct { + // HTTP response content type for this operation + ContentType string + // HTTP response status code for this operation + StatusCode int + // Raw HTTP response; suitable for custom response parsing + RawResponse *http.Response + // All butler tasks + TwoHundredApplicationJSONObject *GetButlerTasksResponseBody + // Unauthorized - Returned if the X-Plex-Token is missing from the header or query. + FourHundredAndOneApplicationJSONObject *GetButlerTasksButlerResponseBody +} + +func (o *GetButlerTasksResponse) GetContentType() string { + if o == nil { + return "" + } + return o.ContentType +} + +func (o *GetButlerTasksResponse) GetStatusCode() int { + if o == nil { + return 0 + } + return o.StatusCode +} + +func (o *GetButlerTasksResponse) GetRawResponse() *http.Response { + if o == nil { + return nil + } + return o.RawResponse +} + +func (o *GetButlerTasksResponse) GetTwoHundredApplicationJSONObject() *GetButlerTasksResponseBody { + if o == nil { + return nil + } + return o.TwoHundredApplicationJSONObject +} + +func (o *GetButlerTasksResponse) GetFourHundredAndOneApplicationJSONObject() *GetButlerTasksButlerResponseBody { + if o == nil { + return nil + } + return o.FourHundredAndOneApplicationJSONObject +} diff --git a/internal/sdk/pkg/models/operations/getcommonlibraryitems.go b/internal/sdk/pkg/models/operations/getcommonlibraryitems.go new file mode 100644 index 0000000..1d2f9ea --- /dev/null +++ b/internal/sdk/pkg/models/operations/getcommonlibraryitems.go @@ -0,0 +1,115 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package operations + +import ( + "net/http" +) + +type GetCommonLibraryItemsRequest struct { + // the Id of the library to query + SectionID float64 `pathParam:"style=simple,explode=false,name=sectionId"` + // item type + Type float64 `queryParam:"style=form,explode=true,name=type"` + // the filter parameter + Filter *string `queryParam:"style=form,explode=true,name=filter"` +} + +func (o *GetCommonLibraryItemsRequest) GetSectionID() float64 { + if o == nil { + return 0.0 + } + return o.SectionID +} + +func (o *GetCommonLibraryItemsRequest) GetType() float64 { + if o == nil { + return 0.0 + } + return o.Type +} + +func (o *GetCommonLibraryItemsRequest) GetFilter() *string { + if o == nil { + return nil + } + return o.Filter +} + +type GetCommonLibraryItemsErrors struct { + Code *float64 `json:"code,omitempty"` + Message *string `json:"message,omitempty"` + Status *float64 `json:"status,omitempty"` +} + +func (o *GetCommonLibraryItemsErrors) GetCode() *float64 { + if o == nil { + return nil + } + return o.Code +} + +func (o *GetCommonLibraryItemsErrors) GetMessage() *string { + if o == nil { + return nil + } + return o.Message +} + +func (o *GetCommonLibraryItemsErrors) GetStatus() *float64 { + if o == nil { + return nil + } + return o.Status +} + +// GetCommonLibraryItemsResponseBody - Unauthorized - Returned if the X-Plex-Token is missing from the header or query. +type GetCommonLibraryItemsResponseBody struct { + Errors []GetCommonLibraryItemsErrors `json:"errors,omitempty"` +} + +func (o *GetCommonLibraryItemsResponseBody) GetErrors() []GetCommonLibraryItemsErrors { + if o == nil { + return nil + } + return o.Errors +} + +type GetCommonLibraryItemsResponse struct { + // HTTP response content type for this operation + ContentType string + // HTTP response status code for this operation + StatusCode int + // Raw HTTP response; suitable for custom response parsing + RawResponse *http.Response + // Unauthorized - Returned if the X-Plex-Token is missing from the header or query. + Object *GetCommonLibraryItemsResponseBody +} + +func (o *GetCommonLibraryItemsResponse) GetContentType() string { + if o == nil { + return "" + } + return o.ContentType +} + +func (o *GetCommonLibraryItemsResponse) GetStatusCode() int { + if o == nil { + return 0 + } + return o.StatusCode +} + +func (o *GetCommonLibraryItemsResponse) GetRawResponse() *http.Response { + if o == nil { + return nil + } + return o.RawResponse +} + +func (o *GetCommonLibraryItemsResponse) GetObject() *GetCommonLibraryItemsResponseBody { + if o == nil { + return nil + } + return o.Object +} diff --git a/internal/sdk/pkg/models/operations/getdevices.go b/internal/sdk/pkg/models/operations/getdevices.go new file mode 100644 index 0000000..6cb8d0a --- /dev/null +++ b/internal/sdk/pkg/models/operations/getdevices.go @@ -0,0 +1,176 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package operations + +import ( + "net/http" +) + +type GetDevicesErrors struct { + Code *float64 `json:"code,omitempty"` + Message *string `json:"message,omitempty"` + Status *float64 `json:"status,omitempty"` +} + +func (o *GetDevicesErrors) GetCode() *float64 { + if o == nil { + return nil + } + return o.Code +} + +func (o *GetDevicesErrors) GetMessage() *string { + if o == nil { + return nil + } + return o.Message +} + +func (o *GetDevicesErrors) GetStatus() *float64 { + if o == nil { + return nil + } + return o.Status +} + +// GetDevicesServerResponseBody - Unauthorized - Returned if the X-Plex-Token is missing from the header or query. +type GetDevicesServerResponseBody struct { + Errors []GetDevicesErrors `json:"errors,omitempty"` +} + +func (o *GetDevicesServerResponseBody) GetErrors() []GetDevicesErrors { + if o == nil { + return nil + } + return o.Errors +} + +type Device struct { + ID *float64 `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Platform *string `json:"platform,omitempty"` + ClientIdentifier *string `json:"clientIdentifier,omitempty"` + CreatedAt *float64 `json:"createdAt,omitempty"` +} + +func (o *Device) GetID() *float64 { + if o == nil { + return nil + } + return o.ID +} + +func (o *Device) GetName() *string { + if o == nil { + return nil + } + return o.Name +} + +func (o *Device) GetPlatform() *string { + if o == nil { + return nil + } + return o.Platform +} + +func (o *Device) GetClientIdentifier() *string { + if o == nil { + return nil + } + return o.ClientIdentifier +} + +func (o *Device) GetCreatedAt() *float64 { + if o == nil { + return nil + } + return o.CreatedAt +} + +type GetDevicesMediaContainer struct { + Size *float64 `json:"size,omitempty"` + Identifier *string `json:"identifier,omitempty"` + Device []Device `json:"Device,omitempty"` +} + +func (o *GetDevicesMediaContainer) GetSize() *float64 { + if o == nil { + return nil + } + return o.Size +} + +func (o *GetDevicesMediaContainer) GetIdentifier() *string { + if o == nil { + return nil + } + return o.Identifier +} + +func (o *GetDevicesMediaContainer) GetDevice() []Device { + if o == nil { + return nil + } + return o.Device +} + +// GetDevicesResponseBody - Devices +type GetDevicesResponseBody struct { + MediaContainer *GetDevicesMediaContainer `json:"MediaContainer,omitempty"` +} + +func (o *GetDevicesResponseBody) GetMediaContainer() *GetDevicesMediaContainer { + if o == nil { + return nil + } + return o.MediaContainer +} + +type GetDevicesResponse struct { + // HTTP response content type for this operation + ContentType string + // HTTP response status code for this operation + StatusCode int + // Raw HTTP response; suitable for custom response parsing + RawResponse *http.Response + // Devices + TwoHundredApplicationJSONObject *GetDevicesResponseBody + // Unauthorized - Returned if the X-Plex-Token is missing from the header or query. + FourHundredAndOneApplicationJSONObject *GetDevicesServerResponseBody +} + +func (o *GetDevicesResponse) GetContentType() string { + if o == nil { + return "" + } + return o.ContentType +} + +func (o *GetDevicesResponse) GetStatusCode() int { + if o == nil { + return 0 + } + return o.StatusCode +} + +func (o *GetDevicesResponse) GetRawResponse() *http.Response { + if o == nil { + return nil + } + return o.RawResponse +} + +func (o *GetDevicesResponse) GetTwoHundredApplicationJSONObject() *GetDevicesResponseBody { + if o == nil { + return nil + } + return o.TwoHundredApplicationJSONObject +} + +func (o *GetDevicesResponse) GetFourHundredAndOneApplicationJSONObject() *GetDevicesServerResponseBody { + if o == nil { + return nil + } + return o.FourHundredAndOneApplicationJSONObject +} diff --git a/internal/sdk/pkg/models/operations/getfilehash.go b/internal/sdk/pkg/models/operations/getfilehash.go new file mode 100644 index 0000000..443d21c --- /dev/null +++ b/internal/sdk/pkg/models/operations/getfilehash.go @@ -0,0 +1,106 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package operations + +import ( + "net/http" +) + +type GetFileHashRequest struct { + // This is the path to the local file, must be prefixed by `file://` + URL string `queryParam:"style=form,explode=true,name=url"` + // Item type + Type *float64 `queryParam:"style=form,explode=true,name=type"` +} + +func (o *GetFileHashRequest) GetURL() string { + if o == nil { + return "" + } + return o.URL +} + +func (o *GetFileHashRequest) GetType() *float64 { + if o == nil { + return nil + } + return o.Type +} + +type GetFileHashErrors struct { + Code *float64 `json:"code,omitempty"` + Message *string `json:"message,omitempty"` + Status *float64 `json:"status,omitempty"` +} + +func (o *GetFileHashErrors) GetCode() *float64 { + if o == nil { + return nil + } + return o.Code +} + +func (o *GetFileHashErrors) GetMessage() *string { + if o == nil { + return nil + } + return o.Message +} + +func (o *GetFileHashErrors) GetStatus() *float64 { + if o == nil { + return nil + } + return o.Status +} + +// GetFileHashResponseBody - Unauthorized - Returned if the X-Plex-Token is missing from the header or query. +type GetFileHashResponseBody struct { + Errors []GetFileHashErrors `json:"errors,omitempty"` +} + +func (o *GetFileHashResponseBody) GetErrors() []GetFileHashErrors { + if o == nil { + return nil + } + return o.Errors +} + +type GetFileHashResponse struct { + // HTTP response content type for this operation + ContentType string + // HTTP response status code for this operation + StatusCode int + // Raw HTTP response; suitable for custom response parsing + RawResponse *http.Response + // Unauthorized - Returned if the X-Plex-Token is missing from the header or query. + Object *GetFileHashResponseBody +} + +func (o *GetFileHashResponse) GetContentType() string { + if o == nil { + return "" + } + return o.ContentType +} + +func (o *GetFileHashResponse) GetStatusCode() int { + if o == nil { + return 0 + } + return o.StatusCode +} + +func (o *GetFileHashResponse) GetRawResponse() *http.Response { + if o == nil { + return nil + } + return o.RawResponse +} + +func (o *GetFileHashResponse) GetObject() *GetFileHashResponseBody { + if o == nil { + return nil + } + return o.Object +} diff --git a/internal/sdk/pkg/models/operations/getglobalhubs.go b/internal/sdk/pkg/models/operations/getglobalhubs.go new file mode 100644 index 0000000..7e6d046 --- /dev/null +++ b/internal/sdk/pkg/models/operations/getglobalhubs.go @@ -0,0 +1,136 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package operations + +import ( + "encoding/json" + "fmt" + "net/http" +) + +// OnlyTransient - Only return hubs which are "transient", meaning those which are prone to changing after media playback or addition (e.g. On Deck, or Recently Added). +type OnlyTransient int64 + +const ( + OnlyTransientZero OnlyTransient = 0 + OnlyTransientOne OnlyTransient = 1 +) + +func (e OnlyTransient) ToPointer() *OnlyTransient { + return &e +} + +func (e *OnlyTransient) UnmarshalJSON(data []byte) error { + var v int64 + if err := json.Unmarshal(data, &v); err != nil { + return err + } + switch v { + case 0: + fallthrough + case 1: + *e = OnlyTransient(v) + return nil + default: + return fmt.Errorf("invalid value for OnlyTransient: %v", v) + } +} + +type GetGlobalHubsRequest struct { + // The number of items to return with each hub. + Count *float64 `queryParam:"style=form,explode=true,name=count"` + // Only return hubs which are "transient", meaning those which are prone to changing after media playback or addition (e.g. On Deck, or Recently Added). + OnlyTransient *OnlyTransient `queryParam:"style=form,explode=true,name=onlyTransient"` +} + +func (o *GetGlobalHubsRequest) GetCount() *float64 { + if o == nil { + return nil + } + return o.Count +} + +func (o *GetGlobalHubsRequest) GetOnlyTransient() *OnlyTransient { + if o == nil { + return nil + } + return o.OnlyTransient +} + +type GetGlobalHubsErrors struct { + Code *float64 `json:"code,omitempty"` + Message *string `json:"message,omitempty"` + Status *float64 `json:"status,omitempty"` +} + +func (o *GetGlobalHubsErrors) GetCode() *float64 { + if o == nil { + return nil + } + return o.Code +} + +func (o *GetGlobalHubsErrors) GetMessage() *string { + if o == nil { + return nil + } + return o.Message +} + +func (o *GetGlobalHubsErrors) GetStatus() *float64 { + if o == nil { + return nil + } + return o.Status +} + +// GetGlobalHubsResponseBody - Unauthorized - Returned if the X-Plex-Token is missing from the header or query. +type GetGlobalHubsResponseBody struct { + Errors []GetGlobalHubsErrors `json:"errors,omitempty"` +} + +func (o *GetGlobalHubsResponseBody) GetErrors() []GetGlobalHubsErrors { + if o == nil { + return nil + } + return o.Errors +} + +type GetGlobalHubsResponse struct { + // HTTP response content type for this operation + ContentType string + // HTTP response status code for this operation + StatusCode int + // Raw HTTP response; suitable for custom response parsing + RawResponse *http.Response + // Unauthorized - Returned if the X-Plex-Token is missing from the header or query. + Object *GetGlobalHubsResponseBody +} + +func (o *GetGlobalHubsResponse) GetContentType() string { + if o == nil { + return "" + } + return o.ContentType +} + +func (o *GetGlobalHubsResponse) GetStatusCode() int { + if o == nil { + return 0 + } + return o.StatusCode +} + +func (o *GetGlobalHubsResponse) GetRawResponse() *http.Response { + if o == nil { + return nil + } + return o.RawResponse +} + +func (o *GetGlobalHubsResponse) GetObject() *GetGlobalHubsResponseBody { + if o == nil { + return nil + } + return o.Object +} diff --git a/internal/sdk/pkg/models/operations/getlatestlibraryitems.go b/internal/sdk/pkg/models/operations/getlatestlibraryitems.go new file mode 100644 index 0000000..5ba6524 --- /dev/null +++ b/internal/sdk/pkg/models/operations/getlatestlibraryitems.go @@ -0,0 +1,115 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package operations + +import ( + "net/http" +) + +type GetLatestLibraryItemsRequest struct { + // the Id of the library to query + SectionID float64 `pathParam:"style=simple,explode=false,name=sectionId"` + // item type + Type float64 `queryParam:"style=form,explode=true,name=type"` + // the filter parameter + Filter *string `queryParam:"style=form,explode=true,name=filter"` +} + +func (o *GetLatestLibraryItemsRequest) GetSectionID() float64 { + if o == nil { + return 0.0 + } + return o.SectionID +} + +func (o *GetLatestLibraryItemsRequest) GetType() float64 { + if o == nil { + return 0.0 + } + return o.Type +} + +func (o *GetLatestLibraryItemsRequest) GetFilter() *string { + if o == nil { + return nil + } + return o.Filter +} + +type GetLatestLibraryItemsErrors struct { + Code *float64 `json:"code,omitempty"` + Message *string `json:"message,omitempty"` + Status *float64 `json:"status,omitempty"` +} + +func (o *GetLatestLibraryItemsErrors) GetCode() *float64 { + if o == nil { + return nil + } + return o.Code +} + +func (o *GetLatestLibraryItemsErrors) GetMessage() *string { + if o == nil { + return nil + } + return o.Message +} + +func (o *GetLatestLibraryItemsErrors) GetStatus() *float64 { + if o == nil { + return nil + } + return o.Status +} + +// GetLatestLibraryItemsResponseBody - Unauthorized - Returned if the X-Plex-Token is missing from the header or query. +type GetLatestLibraryItemsResponseBody struct { + Errors []GetLatestLibraryItemsErrors `json:"errors,omitempty"` +} + +func (o *GetLatestLibraryItemsResponseBody) GetErrors() []GetLatestLibraryItemsErrors { + if o == nil { + return nil + } + return o.Errors +} + +type GetLatestLibraryItemsResponse struct { + // HTTP response content type for this operation + ContentType string + // HTTP response status code for this operation + StatusCode int + // Raw HTTP response; suitable for custom response parsing + RawResponse *http.Response + // Unauthorized - Returned if the X-Plex-Token is missing from the header or query. + Object *GetLatestLibraryItemsResponseBody +} + +func (o *GetLatestLibraryItemsResponse) GetContentType() string { + if o == nil { + return "" + } + return o.ContentType +} + +func (o *GetLatestLibraryItemsResponse) GetStatusCode() int { + if o == nil { + return 0 + } + return o.StatusCode +} + +func (o *GetLatestLibraryItemsResponse) GetRawResponse() *http.Response { + if o == nil { + return nil + } + return o.RawResponse +} + +func (o *GetLatestLibraryItemsResponse) GetObject() *GetLatestLibraryItemsResponseBody { + if o == nil { + return nil + } + return o.Object +} diff --git a/internal/sdk/pkg/models/operations/getlibraries.go b/internal/sdk/pkg/models/operations/getlibraries.go new file mode 100644 index 0000000..807bfc1 --- /dev/null +++ b/internal/sdk/pkg/models/operations/getlibraries.go @@ -0,0 +1,85 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package operations + +import ( + "net/http" +) + +type GetLibrariesErrors struct { + Code *float64 `json:"code,omitempty"` + Message *string `json:"message,omitempty"` + Status *float64 `json:"status,omitempty"` +} + +func (o *GetLibrariesErrors) GetCode() *float64 { + if o == nil { + return nil + } + return o.Code +} + +func (o *GetLibrariesErrors) GetMessage() *string { + if o == nil { + return nil + } + return o.Message +} + +func (o *GetLibrariesErrors) GetStatus() *float64 { + if o == nil { + return nil + } + return o.Status +} + +// GetLibrariesResponseBody - Unauthorized - Returned if the X-Plex-Token is missing from the header or query. +type GetLibrariesResponseBody struct { + Errors []GetLibrariesErrors `json:"errors,omitempty"` +} + +func (o *GetLibrariesResponseBody) GetErrors() []GetLibrariesErrors { + if o == nil { + return nil + } + return o.Errors +} + +type GetLibrariesResponse struct { + // HTTP response content type for this operation + ContentType string + // HTTP response status code for this operation + StatusCode int + // Raw HTTP response; suitable for custom response parsing + RawResponse *http.Response + // Unauthorized - Returned if the X-Plex-Token is missing from the header or query. + Object *GetLibrariesResponseBody +} + +func (o *GetLibrariesResponse) GetContentType() string { + if o == nil { + return "" + } + return o.ContentType +} + +func (o *GetLibrariesResponse) GetStatusCode() int { + if o == nil { + return 0 + } + return o.StatusCode +} + +func (o *GetLibrariesResponse) GetRawResponse() *http.Response { + if o == nil { + return nil + } + return o.RawResponse +} + +func (o *GetLibrariesResponse) GetObject() *GetLibrariesResponseBody { + if o == nil { + return nil + } + return o.Object +} diff --git a/internal/sdk/pkg/models/operations/getlibrary.go b/internal/sdk/pkg/models/operations/getlibrary.go new file mode 100644 index 0000000..5b492cb --- /dev/null +++ b/internal/sdk/pkg/models/operations/getlibrary.go @@ -0,0 +1,151 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package operations + +import ( + "encoding/json" + "fmt" + "github.com/LukeHagar/terraform-provider-PlexAPI/internal/sdk/pkg/utils" + "net/http" +) + +// IncludeDetails - Whether or not to include details for a section (types, filters, and sorts). +// Only exists for backwards compatibility, media providers other than the server libraries have it on always. +type IncludeDetails int64 + +const ( + IncludeDetailsZero IncludeDetails = 0 + IncludeDetailsOne IncludeDetails = 1 +) + +func (e IncludeDetails) ToPointer() *IncludeDetails { + return &e +} + +func (e *IncludeDetails) UnmarshalJSON(data []byte) error { + var v int64 + if err := json.Unmarshal(data, &v); err != nil { + return err + } + switch v { + case 0: + fallthrough + case 1: + *e = IncludeDetails(v) + return nil + default: + return fmt.Errorf("invalid value for IncludeDetails: %v", v) + } +} + +type GetLibraryRequest struct { + // the Id of the library to query + SectionID float64 `pathParam:"style=simple,explode=false,name=sectionId"` + // Whether or not to include details for a section (types, filters, and sorts). + // Only exists for backwards compatibility, media providers other than the server libraries have it on always. + // + IncludeDetails *IncludeDetails `default:"0" queryParam:"style=form,explode=true,name=includeDetails"` +} + +func (g GetLibraryRequest) MarshalJSON() ([]byte, error) { + return utils.MarshalJSON(g, "", false) +} + +func (g *GetLibraryRequest) UnmarshalJSON(data []byte) error { + if err := utils.UnmarshalJSON(data, &g, "", false, false); err != nil { + return err + } + return nil +} + +func (o *GetLibraryRequest) GetSectionID() float64 { + if o == nil { + return 0.0 + } + return o.SectionID +} + +func (o *GetLibraryRequest) GetIncludeDetails() *IncludeDetails { + if o == nil { + return nil + } + return o.IncludeDetails +} + +type GetLibraryErrors struct { + Code *float64 `json:"code,omitempty"` + Message *string `json:"message,omitempty"` + Status *float64 `json:"status,omitempty"` +} + +func (o *GetLibraryErrors) GetCode() *float64 { + if o == nil { + return nil + } + return o.Code +} + +func (o *GetLibraryErrors) GetMessage() *string { + if o == nil { + return nil + } + return o.Message +} + +func (o *GetLibraryErrors) GetStatus() *float64 { + if o == nil { + return nil + } + return o.Status +} + +// GetLibraryResponseBody - Unauthorized - Returned if the X-Plex-Token is missing from the header or query. +type GetLibraryResponseBody struct { + Errors []GetLibraryErrors `json:"errors,omitempty"` +} + +func (o *GetLibraryResponseBody) GetErrors() []GetLibraryErrors { + if o == nil { + return nil + } + return o.Errors +} + +type GetLibraryResponse struct { + // HTTP response content type for this operation + ContentType string + // HTTP response status code for this operation + StatusCode int + // Raw HTTP response; suitable for custom response parsing + RawResponse *http.Response + // Unauthorized - Returned if the X-Plex-Token is missing from the header or query. + Object *GetLibraryResponseBody +} + +func (o *GetLibraryResponse) GetContentType() string { + if o == nil { + return "" + } + return o.ContentType +} + +func (o *GetLibraryResponse) GetStatusCode() int { + if o == nil { + return 0 + } + return o.StatusCode +} + +func (o *GetLibraryResponse) GetRawResponse() *http.Response { + if o == nil { + return nil + } + return o.RawResponse +} + +func (o *GetLibraryResponse) GetObject() *GetLibraryResponseBody { + if o == nil { + return nil + } + return o.Object +} diff --git a/internal/sdk/pkg/models/operations/getlibraryhubs.go b/internal/sdk/pkg/models/operations/getlibraryhubs.go new file mode 100644 index 0000000..1d90d29 --- /dev/null +++ b/internal/sdk/pkg/models/operations/getlibraryhubs.go @@ -0,0 +1,145 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package operations + +import ( + "encoding/json" + "fmt" + "net/http" +) + +// QueryParamOnlyTransient - Only return hubs which are "transient", meaning those which are prone to changing after media playback or addition (e.g. On Deck, or Recently Added). +type QueryParamOnlyTransient int64 + +const ( + QueryParamOnlyTransientZero QueryParamOnlyTransient = 0 + QueryParamOnlyTransientOne QueryParamOnlyTransient = 1 +) + +func (e QueryParamOnlyTransient) ToPointer() *QueryParamOnlyTransient { + return &e +} + +func (e *QueryParamOnlyTransient) UnmarshalJSON(data []byte) error { + var v int64 + if err := json.Unmarshal(data, &v); err != nil { + return err + } + switch v { + case 0: + fallthrough + case 1: + *e = QueryParamOnlyTransient(v) + return nil + default: + return fmt.Errorf("invalid value for QueryParamOnlyTransient: %v", v) + } +} + +type GetLibraryHubsRequest struct { + // the Id of the library to query + SectionID float64 `pathParam:"style=simple,explode=false,name=sectionId"` + // The number of items to return with each hub. + Count *float64 `queryParam:"style=form,explode=true,name=count"` + // Only return hubs which are "transient", meaning those which are prone to changing after media playback or addition (e.g. On Deck, or Recently Added). + OnlyTransient *QueryParamOnlyTransient `queryParam:"style=form,explode=true,name=onlyTransient"` +} + +func (o *GetLibraryHubsRequest) GetSectionID() float64 { + if o == nil { + return 0.0 + } + return o.SectionID +} + +func (o *GetLibraryHubsRequest) GetCount() *float64 { + if o == nil { + return nil + } + return o.Count +} + +func (o *GetLibraryHubsRequest) GetOnlyTransient() *QueryParamOnlyTransient { + if o == nil { + return nil + } + return o.OnlyTransient +} + +type GetLibraryHubsErrors struct { + Code *float64 `json:"code,omitempty"` + Message *string `json:"message,omitempty"` + Status *float64 `json:"status,omitempty"` +} + +func (o *GetLibraryHubsErrors) GetCode() *float64 { + if o == nil { + return nil + } + return o.Code +} + +func (o *GetLibraryHubsErrors) GetMessage() *string { + if o == nil { + return nil + } + return o.Message +} + +func (o *GetLibraryHubsErrors) GetStatus() *float64 { + if o == nil { + return nil + } + return o.Status +} + +// GetLibraryHubsResponseBody - Unauthorized - Returned if the X-Plex-Token is missing from the header or query. +type GetLibraryHubsResponseBody struct { + Errors []GetLibraryHubsErrors `json:"errors,omitempty"` +} + +func (o *GetLibraryHubsResponseBody) GetErrors() []GetLibraryHubsErrors { + if o == nil { + return nil + } + return o.Errors +} + +type GetLibraryHubsResponse struct { + // HTTP response content type for this operation + ContentType string + // HTTP response status code for this operation + StatusCode int + // Raw HTTP response; suitable for custom response parsing + RawResponse *http.Response + // Unauthorized - Returned if the X-Plex-Token is missing from the header or query. + Object *GetLibraryHubsResponseBody +} + +func (o *GetLibraryHubsResponse) GetContentType() string { + if o == nil { + return "" + } + return o.ContentType +} + +func (o *GetLibraryHubsResponse) GetStatusCode() int { + if o == nil { + return 0 + } + return o.StatusCode +} + +func (o *GetLibraryHubsResponse) GetRawResponse() *http.Response { + if o == nil { + return nil + } + return o.RawResponse +} + +func (o *GetLibraryHubsResponse) GetObject() *GetLibraryHubsResponseBody { + if o == nil { + return nil + } + return o.Object +} diff --git a/internal/sdk/pkg/models/operations/getlibraryitems.go b/internal/sdk/pkg/models/operations/getlibraryitems.go new file mode 100644 index 0000000..326add3 --- /dev/null +++ b/internal/sdk/pkg/models/operations/getlibraryitems.go @@ -0,0 +1,115 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package operations + +import ( + "net/http" +) + +type GetLibraryItemsRequest struct { + // the Id of the library to query + SectionID float64 `pathParam:"style=simple,explode=false,name=sectionId"` + // item type + Type *float64 `queryParam:"style=form,explode=true,name=type"` + // the filter parameter + Filter *string `queryParam:"style=form,explode=true,name=filter"` +} + +func (o *GetLibraryItemsRequest) GetSectionID() float64 { + if o == nil { + return 0.0 + } + return o.SectionID +} + +func (o *GetLibraryItemsRequest) GetType() *float64 { + if o == nil { + return nil + } + return o.Type +} + +func (o *GetLibraryItemsRequest) GetFilter() *string { + if o == nil { + return nil + } + return o.Filter +} + +type GetLibraryItemsErrors struct { + Code *float64 `json:"code,omitempty"` + Message *string `json:"message,omitempty"` + Status *float64 `json:"status,omitempty"` +} + +func (o *GetLibraryItemsErrors) GetCode() *float64 { + if o == nil { + return nil + } + return o.Code +} + +func (o *GetLibraryItemsErrors) GetMessage() *string { + if o == nil { + return nil + } + return o.Message +} + +func (o *GetLibraryItemsErrors) GetStatus() *float64 { + if o == nil { + return nil + } + return o.Status +} + +// GetLibraryItemsResponseBody - Unauthorized - Returned if the X-Plex-Token is missing from the header or query. +type GetLibraryItemsResponseBody struct { + Errors []GetLibraryItemsErrors `json:"errors,omitempty"` +} + +func (o *GetLibraryItemsResponseBody) GetErrors() []GetLibraryItemsErrors { + if o == nil { + return nil + } + return o.Errors +} + +type GetLibraryItemsResponse struct { + // HTTP response content type for this operation + ContentType string + // HTTP response status code for this operation + StatusCode int + // Raw HTTP response; suitable for custom response parsing + RawResponse *http.Response + // Unauthorized - Returned if the X-Plex-Token is missing from the header or query. + Object *GetLibraryItemsResponseBody +} + +func (o *GetLibraryItemsResponse) GetContentType() string { + if o == nil { + return "" + } + return o.ContentType +} + +func (o *GetLibraryItemsResponse) GetStatusCode() int { + if o == nil { + return 0 + } + return o.StatusCode +} + +func (o *GetLibraryItemsResponse) GetRawResponse() *http.Response { + if o == nil { + return nil + } + return o.RawResponse +} + +func (o *GetLibraryItemsResponse) GetObject() *GetLibraryItemsResponseBody { + if o == nil { + return nil + } + return o.Object +} diff --git a/internal/sdk/pkg/models/operations/getmetadata.go b/internal/sdk/pkg/models/operations/getmetadata.go new file mode 100644 index 0000000..a7adf45 --- /dev/null +++ b/internal/sdk/pkg/models/operations/getmetadata.go @@ -0,0 +1,97 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package operations + +import ( + "net/http" +) + +type GetMetadataRequest struct { + // the id of the library item to return the children of. + RatingKey float64 `pathParam:"style=simple,explode=false,name=ratingKey"` +} + +func (o *GetMetadataRequest) GetRatingKey() float64 { + if o == nil { + return 0.0 + } + return o.RatingKey +} + +type GetMetadataErrors struct { + Code *float64 `json:"code,omitempty"` + Message *string `json:"message,omitempty"` + Status *float64 `json:"status,omitempty"` +} + +func (o *GetMetadataErrors) GetCode() *float64 { + if o == nil { + return nil + } + return o.Code +} + +func (o *GetMetadataErrors) GetMessage() *string { + if o == nil { + return nil + } + return o.Message +} + +func (o *GetMetadataErrors) GetStatus() *float64 { + if o == nil { + return nil + } + return o.Status +} + +// GetMetadataResponseBody - Unauthorized - Returned if the X-Plex-Token is missing from the header or query. +type GetMetadataResponseBody struct { + Errors []GetMetadataErrors `json:"errors,omitempty"` +} + +func (o *GetMetadataResponseBody) GetErrors() []GetMetadataErrors { + if o == nil { + return nil + } + return o.Errors +} + +type GetMetadataResponse struct { + // HTTP response content type for this operation + ContentType string + // HTTP response status code for this operation + StatusCode int + // Raw HTTP response; suitable for custom response parsing + RawResponse *http.Response + // Unauthorized - Returned if the X-Plex-Token is missing from the header or query. + Object *GetMetadataResponseBody +} + +func (o *GetMetadataResponse) GetContentType() string { + if o == nil { + return "" + } + return o.ContentType +} + +func (o *GetMetadataResponse) GetStatusCode() int { + if o == nil { + return 0 + } + return o.StatusCode +} + +func (o *GetMetadataResponse) GetRawResponse() *http.Response { + if o == nil { + return nil + } + return o.RawResponse +} + +func (o *GetMetadataResponse) GetObject() *GetMetadataResponseBody { + if o == nil { + return nil + } + return o.Object +} diff --git a/internal/sdk/pkg/models/operations/getmetadatachildren.go b/internal/sdk/pkg/models/operations/getmetadatachildren.go new file mode 100644 index 0000000..059ff61 --- /dev/null +++ b/internal/sdk/pkg/models/operations/getmetadatachildren.go @@ -0,0 +1,97 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package operations + +import ( + "net/http" +) + +type GetMetadataChildrenRequest struct { + // the id of the library item to return the children of. + RatingKey float64 `pathParam:"style=simple,explode=false,name=ratingKey"` +} + +func (o *GetMetadataChildrenRequest) GetRatingKey() float64 { + if o == nil { + return 0.0 + } + return o.RatingKey +} + +type GetMetadataChildrenErrors struct { + Code *float64 `json:"code,omitempty"` + Message *string `json:"message,omitempty"` + Status *float64 `json:"status,omitempty"` +} + +func (o *GetMetadataChildrenErrors) GetCode() *float64 { + if o == nil { + return nil + } + return o.Code +} + +func (o *GetMetadataChildrenErrors) GetMessage() *string { + if o == nil { + return nil + } + return o.Message +} + +func (o *GetMetadataChildrenErrors) GetStatus() *float64 { + if o == nil { + return nil + } + return o.Status +} + +// GetMetadataChildrenResponseBody - Unauthorized - Returned if the X-Plex-Token is missing from the header or query. +type GetMetadataChildrenResponseBody struct { + Errors []GetMetadataChildrenErrors `json:"errors,omitempty"` +} + +func (o *GetMetadataChildrenResponseBody) GetErrors() []GetMetadataChildrenErrors { + if o == nil { + return nil + } + return o.Errors +} + +type GetMetadataChildrenResponse struct { + // HTTP response content type for this operation + ContentType string + // HTTP response status code for this operation + StatusCode int + // Raw HTTP response; suitable for custom response parsing + RawResponse *http.Response + // Unauthorized - Returned if the X-Plex-Token is missing from the header or query. + Object *GetMetadataChildrenResponseBody +} + +func (o *GetMetadataChildrenResponse) GetContentType() string { + if o == nil { + return "" + } + return o.ContentType +} + +func (o *GetMetadataChildrenResponse) GetStatusCode() int { + if o == nil { + return 0 + } + return o.StatusCode +} + +func (o *GetMetadataChildrenResponse) GetRawResponse() *http.Response { + if o == nil { + return nil + } + return o.RawResponse +} + +func (o *GetMetadataChildrenResponse) GetObject() *GetMetadataChildrenResponseBody { + if o == nil { + return nil + } + return o.Object +} diff --git a/internal/sdk/pkg/models/operations/getmyplexaccount.go b/internal/sdk/pkg/models/operations/getmyplexaccount.go new file mode 100644 index 0000000..ea6c7ca --- /dev/null +++ b/internal/sdk/pkg/models/operations/getmyplexaccount.go @@ -0,0 +1,205 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package operations + +import ( + "net/http" +) + +type GetMyPlexAccountErrors struct { + Code *float64 `json:"code,omitempty"` + Message *string `json:"message,omitempty"` + Status *float64 `json:"status,omitempty"` +} + +func (o *GetMyPlexAccountErrors) GetCode() *float64 { + if o == nil { + return nil + } + return o.Code +} + +func (o *GetMyPlexAccountErrors) GetMessage() *string { + if o == nil { + return nil + } + return o.Message +} + +func (o *GetMyPlexAccountErrors) GetStatus() *float64 { + if o == nil { + return nil + } + return o.Status +} + +// GetMyPlexAccountServerResponseBody - Unauthorized - Returned if the X-Plex-Token is missing from the header or query. +type GetMyPlexAccountServerResponseBody struct { + Errors []GetMyPlexAccountErrors `json:"errors,omitempty"` +} + +func (o *GetMyPlexAccountServerResponseBody) GetErrors() []GetMyPlexAccountErrors { + if o == nil { + return nil + } + return o.Errors +} + +type MyPlex struct { + AuthToken *string `json:"authToken,omitempty"` + Username *string `json:"username,omitempty"` + MappingState *string `json:"mappingState,omitempty"` + MappingError *string `json:"mappingError,omitempty"` + SignInState *string `json:"signInState,omitempty"` + PublicAddress *string `json:"publicAddress,omitempty"` + PublicPort *float64 `json:"publicPort,omitempty"` + PrivateAddress *string `json:"privateAddress,omitempty"` + PrivatePort *float64 `json:"privatePort,omitempty"` + SubscriptionFeatures *string `json:"subscriptionFeatures,omitempty"` + SubscriptionActive *bool `json:"subscriptionActive,omitempty"` + SubscriptionState *string `json:"subscriptionState,omitempty"` +} + +func (o *MyPlex) GetAuthToken() *string { + if o == nil { + return nil + } + return o.AuthToken +} + +func (o *MyPlex) GetUsername() *string { + if o == nil { + return nil + } + return o.Username +} + +func (o *MyPlex) GetMappingState() *string { + if o == nil { + return nil + } + return o.MappingState +} + +func (o *MyPlex) GetMappingError() *string { + if o == nil { + return nil + } + return o.MappingError +} + +func (o *MyPlex) GetSignInState() *string { + if o == nil { + return nil + } + return o.SignInState +} + +func (o *MyPlex) GetPublicAddress() *string { + if o == nil { + return nil + } + return o.PublicAddress +} + +func (o *MyPlex) GetPublicPort() *float64 { + if o == nil { + return nil + } + return o.PublicPort +} + +func (o *MyPlex) GetPrivateAddress() *string { + if o == nil { + return nil + } + return o.PrivateAddress +} + +func (o *MyPlex) GetPrivatePort() *float64 { + if o == nil { + return nil + } + return o.PrivatePort +} + +func (o *MyPlex) GetSubscriptionFeatures() *string { + if o == nil { + return nil + } + return o.SubscriptionFeatures +} + +func (o *MyPlex) GetSubscriptionActive() *bool { + if o == nil { + return nil + } + return o.SubscriptionActive +} + +func (o *MyPlex) GetSubscriptionState() *string { + if o == nil { + return nil + } + return o.SubscriptionState +} + +// GetMyPlexAccountResponseBody - MyPlex Account +type GetMyPlexAccountResponseBody struct { + MyPlex *MyPlex `json:"MyPlex,omitempty"` +} + +func (o *GetMyPlexAccountResponseBody) GetMyPlex() *MyPlex { + if o == nil { + return nil + } + return o.MyPlex +} + +type GetMyPlexAccountResponse struct { + // HTTP response content type for this operation + ContentType string + // HTTP response status code for this operation + StatusCode int + // Raw HTTP response; suitable for custom response parsing + RawResponse *http.Response + // MyPlex Account + TwoHundredApplicationJSONObject *GetMyPlexAccountResponseBody + // Unauthorized - Returned if the X-Plex-Token is missing from the header or query. + FourHundredAndOneApplicationJSONObject *GetMyPlexAccountServerResponseBody +} + +func (o *GetMyPlexAccountResponse) GetContentType() string { + if o == nil { + return "" + } + return o.ContentType +} + +func (o *GetMyPlexAccountResponse) GetStatusCode() int { + if o == nil { + return 0 + } + return o.StatusCode +} + +func (o *GetMyPlexAccountResponse) GetRawResponse() *http.Response { + if o == nil { + return nil + } + return o.RawResponse +} + +func (o *GetMyPlexAccountResponse) GetTwoHundredApplicationJSONObject() *GetMyPlexAccountResponseBody { + if o == nil { + return nil + } + return o.TwoHundredApplicationJSONObject +} + +func (o *GetMyPlexAccountResponse) GetFourHundredAndOneApplicationJSONObject() *GetMyPlexAccountServerResponseBody { + if o == nil { + return nil + } + return o.FourHundredAndOneApplicationJSONObject +} diff --git a/internal/sdk/pkg/models/operations/getondeck.go b/internal/sdk/pkg/models/operations/getondeck.go new file mode 100644 index 0000000..a6edac4 --- /dev/null +++ b/internal/sdk/pkg/models/operations/getondeck.go @@ -0,0 +1,865 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package operations + +import ( + "github.com/LukeHagar/terraform-provider-PlexAPI/internal/sdk/pkg/utils" + "net/http" + "time" +) + +type GetOnDeckErrors struct { + Code *float64 `json:"code,omitempty"` + Message *string `json:"message,omitempty"` + Status *float64 `json:"status,omitempty"` +} + +func (o *GetOnDeckErrors) GetCode() *float64 { + if o == nil { + return nil + } + return o.Code +} + +func (o *GetOnDeckErrors) GetMessage() *string { + if o == nil { + return nil + } + return o.Message +} + +func (o *GetOnDeckErrors) GetStatus() *float64 { + if o == nil { + return nil + } + return o.Status +} + +// GetOnDeckLibraryResponseBody - Unauthorized - Returned if the X-Plex-Token is missing from the header or query. +type GetOnDeckLibraryResponseBody struct { + Errors []GetOnDeckErrors `json:"errors,omitempty"` +} + +func (o *GetOnDeckLibraryResponseBody) GetErrors() []GetOnDeckErrors { + if o == nil { + return nil + } + return o.Errors +} + +type Stream struct { + ID *float64 `json:"id,omitempty"` + StreamType *float64 `json:"streamType,omitempty"` + Default *bool `json:"default,omitempty"` + Codec *string `json:"codec,omitempty"` + Index *float64 `json:"index,omitempty"` + Bitrate *float64 `json:"bitrate,omitempty"` + Language *string `json:"language,omitempty"` + LanguageTag *string `json:"languageTag,omitempty"` + LanguageCode *string `json:"languageCode,omitempty"` + BitDepth *float64 `json:"bitDepth,omitempty"` + ChromaLocation *string `json:"chromaLocation,omitempty"` + ChromaSubsampling *string `json:"chromaSubsampling,omitempty"` + CodedHeight *float64 `json:"codedHeight,omitempty"` + CodedWidth *float64 `json:"codedWidth,omitempty"` + ColorRange *string `json:"colorRange,omitempty"` + FrameRate *float64 `json:"frameRate,omitempty"` + Height *float64 `json:"height,omitempty"` + Level *float64 `json:"level,omitempty"` + Profile *string `json:"profile,omitempty"` + RefFrames *float64 `json:"refFrames,omitempty"` + Width *float64 `json:"width,omitempty"` + DisplayTitle *string `json:"displayTitle,omitempty"` + ExtendedDisplayTitle *string `json:"extendedDisplayTitle,omitempty"` +} + +func (o *Stream) GetID() *float64 { + if o == nil { + return nil + } + return o.ID +} + +func (o *Stream) GetStreamType() *float64 { + if o == nil { + return nil + } + return o.StreamType +} + +func (o *Stream) GetDefault() *bool { + if o == nil { + return nil + } + return o.Default +} + +func (o *Stream) GetCodec() *string { + if o == nil { + return nil + } + return o.Codec +} + +func (o *Stream) GetIndex() *float64 { + if o == nil { + return nil + } + return o.Index +} + +func (o *Stream) GetBitrate() *float64 { + if o == nil { + return nil + } + return o.Bitrate +} + +func (o *Stream) GetLanguage() *string { + if o == nil { + return nil + } + return o.Language +} + +func (o *Stream) GetLanguageTag() *string { + if o == nil { + return nil + } + return o.LanguageTag +} + +func (o *Stream) GetLanguageCode() *string { + if o == nil { + return nil + } + return o.LanguageCode +} + +func (o *Stream) GetBitDepth() *float64 { + if o == nil { + return nil + } + return o.BitDepth +} + +func (o *Stream) GetChromaLocation() *string { + if o == nil { + return nil + } + return o.ChromaLocation +} + +func (o *Stream) GetChromaSubsampling() *string { + if o == nil { + return nil + } + return o.ChromaSubsampling +} + +func (o *Stream) GetCodedHeight() *float64 { + if o == nil { + return nil + } + return o.CodedHeight +} + +func (o *Stream) GetCodedWidth() *float64 { + if o == nil { + return nil + } + return o.CodedWidth +} + +func (o *Stream) GetColorRange() *string { + if o == nil { + return nil + } + return o.ColorRange +} + +func (o *Stream) GetFrameRate() *float64 { + if o == nil { + return nil + } + return o.FrameRate +} + +func (o *Stream) GetHeight() *float64 { + if o == nil { + return nil + } + return o.Height +} + +func (o *Stream) GetLevel() *float64 { + if o == nil { + return nil + } + return o.Level +} + +func (o *Stream) GetProfile() *string { + if o == nil { + return nil + } + return o.Profile +} + +func (o *Stream) GetRefFrames() *float64 { + if o == nil { + return nil + } + return o.RefFrames +} + +func (o *Stream) GetWidth() *float64 { + if o == nil { + return nil + } + return o.Width +} + +func (o *Stream) GetDisplayTitle() *string { + if o == nil { + return nil + } + return o.DisplayTitle +} + +func (o *Stream) GetExtendedDisplayTitle() *string { + if o == nil { + return nil + } + return o.ExtendedDisplayTitle +} + +type GetOnDeckPart struct { + ID *float64 `json:"id,omitempty"` + Key *string `json:"key,omitempty"` + Duration *float64 `json:"duration,omitempty"` + File *string `json:"file,omitempty"` + Size *float64 `json:"size,omitempty"` + AudioProfile *string `json:"audioProfile,omitempty"` + Container *string `json:"container,omitempty"` + VideoProfile *string `json:"videoProfile,omitempty"` + Stream []Stream `json:"Stream,omitempty"` +} + +func (o *GetOnDeckPart) GetID() *float64 { + if o == nil { + return nil + } + return o.ID +} + +func (o *GetOnDeckPart) GetKey() *string { + if o == nil { + return nil + } + return o.Key +} + +func (o *GetOnDeckPart) GetDuration() *float64 { + if o == nil { + return nil + } + return o.Duration +} + +func (o *GetOnDeckPart) GetFile() *string { + if o == nil { + return nil + } + return o.File +} + +func (o *GetOnDeckPart) GetSize() *float64 { + if o == nil { + return nil + } + return o.Size +} + +func (o *GetOnDeckPart) GetAudioProfile() *string { + if o == nil { + return nil + } + return o.AudioProfile +} + +func (o *GetOnDeckPart) GetContainer() *string { + if o == nil { + return nil + } + return o.Container +} + +func (o *GetOnDeckPart) GetVideoProfile() *string { + if o == nil { + return nil + } + return o.VideoProfile +} + +func (o *GetOnDeckPart) GetStream() []Stream { + if o == nil { + return nil + } + return o.Stream +} + +type GetOnDeckMedia struct { + ID *float64 `json:"id,omitempty"` + Duration *float64 `json:"duration,omitempty"` + Bitrate *float64 `json:"bitrate,omitempty"` + Width *float64 `json:"width,omitempty"` + Height *float64 `json:"height,omitempty"` + AspectRatio *float64 `json:"aspectRatio,omitempty"` + AudioChannels *float64 `json:"audioChannels,omitempty"` + AudioCodec *string `json:"audioCodec,omitempty"` + VideoCodec *string `json:"videoCodec,omitempty"` + VideoResolution *string `json:"videoResolution,omitempty"` + Container *string `json:"container,omitempty"` + VideoFrameRate *string `json:"videoFrameRate,omitempty"` + AudioProfile *string `json:"audioProfile,omitempty"` + VideoProfile *string `json:"videoProfile,omitempty"` + Part []GetOnDeckPart `json:"Part,omitempty"` +} + +func (o *GetOnDeckMedia) GetID() *float64 { + if o == nil { + return nil + } + return o.ID +} + +func (o *GetOnDeckMedia) GetDuration() *float64 { + if o == nil { + return nil + } + return o.Duration +} + +func (o *GetOnDeckMedia) GetBitrate() *float64 { + if o == nil { + return nil + } + return o.Bitrate +} + +func (o *GetOnDeckMedia) GetWidth() *float64 { + if o == nil { + return nil + } + return o.Width +} + +func (o *GetOnDeckMedia) GetHeight() *float64 { + if o == nil { + return nil + } + return o.Height +} + +func (o *GetOnDeckMedia) GetAspectRatio() *float64 { + if o == nil { + return nil + } + return o.AspectRatio +} + +func (o *GetOnDeckMedia) GetAudioChannels() *float64 { + if o == nil { + return nil + } + return o.AudioChannels +} + +func (o *GetOnDeckMedia) GetAudioCodec() *string { + if o == nil { + return nil + } + return o.AudioCodec +} + +func (o *GetOnDeckMedia) GetVideoCodec() *string { + if o == nil { + return nil + } + return o.VideoCodec +} + +func (o *GetOnDeckMedia) GetVideoResolution() *string { + if o == nil { + return nil + } + return o.VideoResolution +} + +func (o *GetOnDeckMedia) GetContainer() *string { + if o == nil { + return nil + } + return o.Container +} + +func (o *GetOnDeckMedia) GetVideoFrameRate() *string { + if o == nil { + return nil + } + return o.VideoFrameRate +} + +func (o *GetOnDeckMedia) GetAudioProfile() *string { + if o == nil { + return nil + } + return o.AudioProfile +} + +func (o *GetOnDeckMedia) GetVideoProfile() *string { + if o == nil { + return nil + } + return o.VideoProfile +} + +func (o *GetOnDeckMedia) GetPart() []GetOnDeckPart { + if o == nil { + return nil + } + return o.Part +} + +type Guids struct { + ID *string `json:"id,omitempty"` +} + +func (o *Guids) GetID() *string { + if o == nil { + return nil + } + return o.ID +} + +type GetOnDeckMetadata struct { + AllowSync *bool `json:"allowSync,omitempty"` + LibrarySectionID *float64 `json:"librarySectionID,omitempty"` + LibrarySectionTitle *string `json:"librarySectionTitle,omitempty"` + LibrarySectionUUID *string `json:"librarySectionUUID,omitempty"` + RatingKey *float64 `json:"ratingKey,omitempty"` + Key *string `json:"key,omitempty"` + ParentRatingKey *float64 `json:"parentRatingKey,omitempty"` + GrandparentRatingKey *float64 `json:"grandparentRatingKey,omitempty"` + GUID *string `json:"guid,omitempty"` + ParentGUID *string `json:"parentGuid,omitempty"` + GrandparentGUID *string `json:"grandparentGuid,omitempty"` + Type *string `json:"type,omitempty"` + Title *string `json:"title,omitempty"` + GrandparentKey *string `json:"grandparentKey,omitempty"` + ParentKey *string `json:"parentKey,omitempty"` + LibrarySectionKey *string `json:"librarySectionKey,omitempty"` + GrandparentTitle *string `json:"grandparentTitle,omitempty"` + ParentTitle *string `json:"parentTitle,omitempty"` + ContentRating *string `json:"contentRating,omitempty"` + Summary *string `json:"summary,omitempty"` + Index *float64 `json:"index,omitempty"` + ParentIndex *float64 `json:"parentIndex,omitempty"` + LastViewedAt *float64 `json:"lastViewedAt,omitempty"` + Year *float64 `json:"year,omitempty"` + Thumb *string `json:"thumb,omitempty"` + Art *string `json:"art,omitempty"` + ParentThumb *string `json:"parentThumb,omitempty"` + GrandparentThumb *string `json:"grandparentThumb,omitempty"` + GrandparentArt *string `json:"grandparentArt,omitempty"` + GrandparentTheme *string `json:"grandparentTheme,omitempty"` + Duration *float64 `json:"duration,omitempty"` + OriginallyAvailableAt *time.Time `json:"originallyAvailableAt,omitempty"` + AddedAt *float64 `json:"addedAt,omitempty"` + UpdatedAt *float64 `json:"updatedAt,omitempty"` + Media []GetOnDeckMedia `json:"Media,omitempty"` + Guids []Guids `json:"Guid,omitempty"` +} + +func (g GetOnDeckMetadata) MarshalJSON() ([]byte, error) { + return utils.MarshalJSON(g, "", false) +} + +func (g *GetOnDeckMetadata) UnmarshalJSON(data []byte) error { + if err := utils.UnmarshalJSON(data, &g, "", false, false); err != nil { + return err + } + return nil +} + +func (o *GetOnDeckMetadata) GetAllowSync() *bool { + if o == nil { + return nil + } + return o.AllowSync +} + +func (o *GetOnDeckMetadata) GetLibrarySectionID() *float64 { + if o == nil { + return nil + } + return o.LibrarySectionID +} + +func (o *GetOnDeckMetadata) GetLibrarySectionTitle() *string { + if o == nil { + return nil + } + return o.LibrarySectionTitle +} + +func (o *GetOnDeckMetadata) GetLibrarySectionUUID() *string { + if o == nil { + return nil + } + return o.LibrarySectionUUID +} + +func (o *GetOnDeckMetadata) GetRatingKey() *float64 { + if o == nil { + return nil + } + return o.RatingKey +} + +func (o *GetOnDeckMetadata) GetKey() *string { + if o == nil { + return nil + } + return o.Key +} + +func (o *GetOnDeckMetadata) GetParentRatingKey() *float64 { + if o == nil { + return nil + } + return o.ParentRatingKey +} + +func (o *GetOnDeckMetadata) GetGrandparentRatingKey() *float64 { + if o == nil { + return nil + } + return o.GrandparentRatingKey +} + +func (o *GetOnDeckMetadata) GetGUID() *string { + if o == nil { + return nil + } + return o.GUID +} + +func (o *GetOnDeckMetadata) GetParentGUID() *string { + if o == nil { + return nil + } + return o.ParentGUID +} + +func (o *GetOnDeckMetadata) GetGrandparentGUID() *string { + if o == nil { + return nil + } + return o.GrandparentGUID +} + +func (o *GetOnDeckMetadata) GetType() *string { + if o == nil { + return nil + } + return o.Type +} + +func (o *GetOnDeckMetadata) GetTitle() *string { + if o == nil { + return nil + } + return o.Title +} + +func (o *GetOnDeckMetadata) GetGrandparentKey() *string { + if o == nil { + return nil + } + return o.GrandparentKey +} + +func (o *GetOnDeckMetadata) GetParentKey() *string { + if o == nil { + return nil + } + return o.ParentKey +} + +func (o *GetOnDeckMetadata) GetLibrarySectionKey() *string { + if o == nil { + return nil + } + return o.LibrarySectionKey +} + +func (o *GetOnDeckMetadata) GetGrandparentTitle() *string { + if o == nil { + return nil + } + return o.GrandparentTitle +} + +func (o *GetOnDeckMetadata) GetParentTitle() *string { + if o == nil { + return nil + } + return o.ParentTitle +} + +func (o *GetOnDeckMetadata) GetContentRating() *string { + if o == nil { + return nil + } + return o.ContentRating +} + +func (o *GetOnDeckMetadata) GetSummary() *string { + if o == nil { + return nil + } + return o.Summary +} + +func (o *GetOnDeckMetadata) GetIndex() *float64 { + if o == nil { + return nil + } + return o.Index +} + +func (o *GetOnDeckMetadata) GetParentIndex() *float64 { + if o == nil { + return nil + } + return o.ParentIndex +} + +func (o *GetOnDeckMetadata) GetLastViewedAt() *float64 { + if o == nil { + return nil + } + return o.LastViewedAt +} + +func (o *GetOnDeckMetadata) GetYear() *float64 { + if o == nil { + return nil + } + return o.Year +} + +func (o *GetOnDeckMetadata) GetThumb() *string { + if o == nil { + return nil + } + return o.Thumb +} + +func (o *GetOnDeckMetadata) GetArt() *string { + if o == nil { + return nil + } + return o.Art +} + +func (o *GetOnDeckMetadata) GetParentThumb() *string { + if o == nil { + return nil + } + return o.ParentThumb +} + +func (o *GetOnDeckMetadata) GetGrandparentThumb() *string { + if o == nil { + return nil + } + return o.GrandparentThumb +} + +func (o *GetOnDeckMetadata) GetGrandparentArt() *string { + if o == nil { + return nil + } + return o.GrandparentArt +} + +func (o *GetOnDeckMetadata) GetGrandparentTheme() *string { + if o == nil { + return nil + } + return o.GrandparentTheme +} + +func (o *GetOnDeckMetadata) GetDuration() *float64 { + if o == nil { + return nil + } + return o.Duration +} + +func (o *GetOnDeckMetadata) GetOriginallyAvailableAt() *time.Time { + if o == nil { + return nil + } + return o.OriginallyAvailableAt +} + +func (o *GetOnDeckMetadata) GetAddedAt() *float64 { + if o == nil { + return nil + } + return o.AddedAt +} + +func (o *GetOnDeckMetadata) GetUpdatedAt() *float64 { + if o == nil { + return nil + } + return o.UpdatedAt +} + +func (o *GetOnDeckMetadata) GetMedia() []GetOnDeckMedia { + if o == nil { + return nil + } + return o.Media +} + +func (o *GetOnDeckMetadata) GetGuids() []Guids { + if o == nil { + return nil + } + return o.Guids +} + +type GetOnDeckMediaContainer struct { + Size *float64 `json:"size,omitempty"` + AllowSync *bool `json:"allowSync,omitempty"` + Identifier *string `json:"identifier,omitempty"` + MediaTagPrefix *string `json:"mediaTagPrefix,omitempty"` + MediaTagVersion *float64 `json:"mediaTagVersion,omitempty"` + MixedParents *bool `json:"mixedParents,omitempty"` + Metadata []GetOnDeckMetadata `json:"Metadata,omitempty"` +} + +func (o *GetOnDeckMediaContainer) GetSize() *float64 { + if o == nil { + return nil + } + return o.Size +} + +func (o *GetOnDeckMediaContainer) GetAllowSync() *bool { + if o == nil { + return nil + } + return o.AllowSync +} + +func (o *GetOnDeckMediaContainer) GetIdentifier() *string { + if o == nil { + return nil + } + return o.Identifier +} + +func (o *GetOnDeckMediaContainer) GetMediaTagPrefix() *string { + if o == nil { + return nil + } + return o.MediaTagPrefix +} + +func (o *GetOnDeckMediaContainer) GetMediaTagVersion() *float64 { + if o == nil { + return nil + } + return o.MediaTagVersion +} + +func (o *GetOnDeckMediaContainer) GetMixedParents() *bool { + if o == nil { + return nil + } + return o.MixedParents +} + +func (o *GetOnDeckMediaContainer) GetMetadata() []GetOnDeckMetadata { + if o == nil { + return nil + } + return o.Metadata +} + +// GetOnDeckResponseBody - The on Deck content +type GetOnDeckResponseBody struct { + MediaContainer *GetOnDeckMediaContainer `json:"MediaContainer,omitempty"` +} + +func (o *GetOnDeckResponseBody) GetMediaContainer() *GetOnDeckMediaContainer { + if o == nil { + return nil + } + return o.MediaContainer +} + +type GetOnDeckResponse struct { + // HTTP response content type for this operation + ContentType string + // HTTP response status code for this operation + StatusCode int + // Raw HTTP response; suitable for custom response parsing + RawResponse *http.Response + // The on Deck content + TwoHundredApplicationJSONObject *GetOnDeckResponseBody + // Unauthorized - Returned if the X-Plex-Token is missing from the header or query. + FourHundredAndOneApplicationJSONObject *GetOnDeckLibraryResponseBody +} + +func (o *GetOnDeckResponse) GetContentType() string { + if o == nil { + return "" + } + return o.ContentType +} + +func (o *GetOnDeckResponse) GetStatusCode() int { + if o == nil { + return 0 + } + return o.StatusCode +} + +func (o *GetOnDeckResponse) GetRawResponse() *http.Response { + if o == nil { + return nil + } + return o.RawResponse +} + +func (o *GetOnDeckResponse) GetTwoHundredApplicationJSONObject() *GetOnDeckResponseBody { + if o == nil { + return nil + } + return o.TwoHundredApplicationJSONObject +} + +func (o *GetOnDeckResponse) GetFourHundredAndOneApplicationJSONObject() *GetOnDeckLibraryResponseBody { + if o == nil { + return nil + } + return o.FourHundredAndOneApplicationJSONObject +} diff --git a/internal/sdk/pkg/models/operations/getplaylist.go b/internal/sdk/pkg/models/operations/getplaylist.go new file mode 100644 index 0000000..cc27ed9 --- /dev/null +++ b/internal/sdk/pkg/models/operations/getplaylist.go @@ -0,0 +1,97 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package operations + +import ( + "net/http" +) + +type GetPlaylistRequest struct { + // the ID of the playlist + PlaylistID float64 `pathParam:"style=simple,explode=false,name=playlistID"` +} + +func (o *GetPlaylistRequest) GetPlaylistID() float64 { + if o == nil { + return 0.0 + } + return o.PlaylistID +} + +type GetPlaylistErrors struct { + Code *float64 `json:"code,omitempty"` + Message *string `json:"message,omitempty"` + Status *float64 `json:"status,omitempty"` +} + +func (o *GetPlaylistErrors) GetCode() *float64 { + if o == nil { + return nil + } + return o.Code +} + +func (o *GetPlaylistErrors) GetMessage() *string { + if o == nil { + return nil + } + return o.Message +} + +func (o *GetPlaylistErrors) GetStatus() *float64 { + if o == nil { + return nil + } + return o.Status +} + +// GetPlaylistResponseBody - Unauthorized - Returned if the X-Plex-Token is missing from the header or query. +type GetPlaylistResponseBody struct { + Errors []GetPlaylistErrors `json:"errors,omitempty"` +} + +func (o *GetPlaylistResponseBody) GetErrors() []GetPlaylistErrors { + if o == nil { + return nil + } + return o.Errors +} + +type GetPlaylistResponse struct { + // HTTP response content type for this operation + ContentType string + // HTTP response status code for this operation + StatusCode int + // Raw HTTP response; suitable for custom response parsing + RawResponse *http.Response + // Unauthorized - Returned if the X-Plex-Token is missing from the header or query. + Object *GetPlaylistResponseBody +} + +func (o *GetPlaylistResponse) GetContentType() string { + if o == nil { + return "" + } + return o.ContentType +} + +func (o *GetPlaylistResponse) GetStatusCode() int { + if o == nil { + return 0 + } + return o.StatusCode +} + +func (o *GetPlaylistResponse) GetRawResponse() *http.Response { + if o == nil { + return nil + } + return o.RawResponse +} + +func (o *GetPlaylistResponse) GetObject() *GetPlaylistResponseBody { + if o == nil { + return nil + } + return o.Object +} diff --git a/internal/sdk/pkg/models/operations/getplaylistcontents.go b/internal/sdk/pkg/models/operations/getplaylistcontents.go new file mode 100644 index 0000000..70de683 --- /dev/null +++ b/internal/sdk/pkg/models/operations/getplaylistcontents.go @@ -0,0 +1,106 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package operations + +import ( + "net/http" +) + +type GetPlaylistContentsRequest struct { + // the ID of the playlist + PlaylistID float64 `pathParam:"style=simple,explode=false,name=playlistID"` + // the metadata type of the item to return + Type float64 `queryParam:"style=form,explode=true,name=type"` +} + +func (o *GetPlaylistContentsRequest) GetPlaylistID() float64 { + if o == nil { + return 0.0 + } + return o.PlaylistID +} + +func (o *GetPlaylistContentsRequest) GetType() float64 { + if o == nil { + return 0.0 + } + return o.Type +} + +type GetPlaylistContentsErrors struct { + Code *float64 `json:"code,omitempty"` + Message *string `json:"message,omitempty"` + Status *float64 `json:"status,omitempty"` +} + +func (o *GetPlaylistContentsErrors) GetCode() *float64 { + if o == nil { + return nil + } + return o.Code +} + +func (o *GetPlaylistContentsErrors) GetMessage() *string { + if o == nil { + return nil + } + return o.Message +} + +func (o *GetPlaylistContentsErrors) GetStatus() *float64 { + if o == nil { + return nil + } + return o.Status +} + +// GetPlaylistContentsResponseBody - Unauthorized - Returned if the X-Plex-Token is missing from the header or query. +type GetPlaylistContentsResponseBody struct { + Errors []GetPlaylistContentsErrors `json:"errors,omitempty"` +} + +func (o *GetPlaylistContentsResponseBody) GetErrors() []GetPlaylistContentsErrors { + if o == nil { + return nil + } + return o.Errors +} + +type GetPlaylistContentsResponse struct { + // HTTP response content type for this operation + ContentType string + // HTTP response status code for this operation + StatusCode int + // Raw HTTP response; suitable for custom response parsing + RawResponse *http.Response + // Unauthorized - Returned if the X-Plex-Token is missing from the header or query. + Object *GetPlaylistContentsResponseBody +} + +func (o *GetPlaylistContentsResponse) GetContentType() string { + if o == nil { + return "" + } + return o.ContentType +} + +func (o *GetPlaylistContentsResponse) GetStatusCode() int { + if o == nil { + return 0 + } + return o.StatusCode +} + +func (o *GetPlaylistContentsResponse) GetRawResponse() *http.Response { + if o == nil { + return nil + } + return o.RawResponse +} + +func (o *GetPlaylistContentsResponse) GetObject() *GetPlaylistContentsResponseBody { + if o == nil { + return nil + } + return o.Object +} diff --git a/internal/sdk/pkg/models/operations/getplaylists.go b/internal/sdk/pkg/models/operations/getplaylists.go new file mode 100644 index 0000000..26ce26b --- /dev/null +++ b/internal/sdk/pkg/models/operations/getplaylists.go @@ -0,0 +1,167 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package operations + +import ( + "encoding/json" + "fmt" + "net/http" +) + +// PlaylistType - limit to a type of playlist. +type PlaylistType string + +const ( + PlaylistTypeAudio PlaylistType = "audio" + PlaylistTypeVideo PlaylistType = "video" + PlaylistTypePhoto PlaylistType = "photo" +) + +func (e PlaylistType) ToPointer() *PlaylistType { + return &e +} + +func (e *PlaylistType) UnmarshalJSON(data []byte) error { + var v string + if err := json.Unmarshal(data, &v); err != nil { + return err + } + switch v { + case "audio": + fallthrough + case "video": + fallthrough + case "photo": + *e = PlaylistType(v) + return nil + default: + return fmt.Errorf("invalid value for PlaylistType: %v", v) + } +} + +// QueryParamSmart - type of playlists to return (default is all). +type QueryParamSmart int64 + +const ( + QueryParamSmartZero QueryParamSmart = 0 + QueryParamSmartOne QueryParamSmart = 1 +) + +func (e QueryParamSmart) ToPointer() *QueryParamSmart { + return &e +} + +func (e *QueryParamSmart) UnmarshalJSON(data []byte) error { + var v int64 + if err := json.Unmarshal(data, &v); err != nil { + return err + } + switch v { + case 0: + fallthrough + case 1: + *e = QueryParamSmart(v) + return nil + default: + return fmt.Errorf("invalid value for QueryParamSmart: %v", v) + } +} + +type GetPlaylistsRequest struct { + // limit to a type of playlist. + PlaylistType *PlaylistType `queryParam:"style=form,explode=true,name=playlistType"` + // type of playlists to return (default is all). + Smart *QueryParamSmart `queryParam:"style=form,explode=true,name=smart"` +} + +func (o *GetPlaylistsRequest) GetPlaylistType() *PlaylistType { + if o == nil { + return nil + } + return o.PlaylistType +} + +func (o *GetPlaylistsRequest) GetSmart() *QueryParamSmart { + if o == nil { + return nil + } + return o.Smart +} + +type GetPlaylistsErrors struct { + Code *float64 `json:"code,omitempty"` + Message *string `json:"message,omitempty"` + Status *float64 `json:"status,omitempty"` +} + +func (o *GetPlaylistsErrors) GetCode() *float64 { + if o == nil { + return nil + } + return o.Code +} + +func (o *GetPlaylistsErrors) GetMessage() *string { + if o == nil { + return nil + } + return o.Message +} + +func (o *GetPlaylistsErrors) GetStatus() *float64 { + if o == nil { + return nil + } + return o.Status +} + +// GetPlaylistsResponseBody - Unauthorized - Returned if the X-Plex-Token is missing from the header or query. +type GetPlaylistsResponseBody struct { + Errors []GetPlaylistsErrors `json:"errors,omitempty"` +} + +func (o *GetPlaylistsResponseBody) GetErrors() []GetPlaylistsErrors { + if o == nil { + return nil + } + return o.Errors +} + +type GetPlaylistsResponse struct { + // HTTP response content type for this operation + ContentType string + // HTTP response status code for this operation + StatusCode int + // Raw HTTP response; suitable for custom response parsing + RawResponse *http.Response + // Unauthorized - Returned if the X-Plex-Token is missing from the header or query. + Object *GetPlaylistsResponseBody +} + +func (o *GetPlaylistsResponse) GetContentType() string { + if o == nil { + return "" + } + return o.ContentType +} + +func (o *GetPlaylistsResponse) GetStatusCode() int { + if o == nil { + return 0 + } + return o.StatusCode +} + +func (o *GetPlaylistsResponse) GetRawResponse() *http.Response { + if o == nil { + return nil + } + return o.RawResponse +} + +func (o *GetPlaylistsResponse) GetObject() *GetPlaylistsResponseBody { + if o == nil { + return nil + } + return o.Object +} diff --git a/internal/sdk/pkg/models/operations/getrecentlyadded.go b/internal/sdk/pkg/models/operations/getrecentlyadded.go new file mode 100644 index 0000000..607ae3a --- /dev/null +++ b/internal/sdk/pkg/models/operations/getrecentlyadded.go @@ -0,0 +1,706 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package operations + +import ( + "github.com/LukeHagar/terraform-provider-PlexAPI/internal/sdk/pkg/utils" + "net/http" + "time" +) + +type GetRecentlyAddedErrors struct { + Code *float64 `json:"code,omitempty"` + Message *string `json:"message,omitempty"` + Status *float64 `json:"status,omitempty"` +} + +func (o *GetRecentlyAddedErrors) GetCode() *float64 { + if o == nil { + return nil + } + return o.Code +} + +func (o *GetRecentlyAddedErrors) GetMessage() *string { + if o == nil { + return nil + } + return o.Message +} + +func (o *GetRecentlyAddedErrors) GetStatus() *float64 { + if o == nil { + return nil + } + return o.Status +} + +// GetRecentlyAddedLibraryResponseBody - Unauthorized - Returned if the X-Plex-Token is missing from the header or query. +type GetRecentlyAddedLibraryResponseBody struct { + Errors []GetRecentlyAddedErrors `json:"errors,omitempty"` +} + +func (o *GetRecentlyAddedLibraryResponseBody) GetErrors() []GetRecentlyAddedErrors { + if o == nil { + return nil + } + return o.Errors +} + +type Part struct { + ID *float64 `json:"id,omitempty"` + Key *string `json:"key,omitempty"` + Duration *float64 `json:"duration,omitempty"` + File *string `json:"file,omitempty"` + Size *float64 `json:"size,omitempty"` + Container *string `json:"container,omitempty"` + Has64bitOffsets *bool `json:"has64bitOffsets,omitempty"` + HasThumbnail *float64 `json:"hasThumbnail,omitempty"` + OptimizedForStreaming *bool `json:"optimizedForStreaming,omitempty"` + VideoProfile *string `json:"videoProfile,omitempty"` +} + +func (o *Part) GetID() *float64 { + if o == nil { + return nil + } + return o.ID +} + +func (o *Part) GetKey() *string { + if o == nil { + return nil + } + return o.Key +} + +func (o *Part) GetDuration() *float64 { + if o == nil { + return nil + } + return o.Duration +} + +func (o *Part) GetFile() *string { + if o == nil { + return nil + } + return o.File +} + +func (o *Part) GetSize() *float64 { + if o == nil { + return nil + } + return o.Size +} + +func (o *Part) GetContainer() *string { + if o == nil { + return nil + } + return o.Container +} + +func (o *Part) GetHas64bitOffsets() *bool { + if o == nil { + return nil + } + return o.Has64bitOffsets +} + +func (o *Part) GetHasThumbnail() *float64 { + if o == nil { + return nil + } + return o.HasThumbnail +} + +func (o *Part) GetOptimizedForStreaming() *bool { + if o == nil { + return nil + } + return o.OptimizedForStreaming +} + +func (o *Part) GetVideoProfile() *string { + if o == nil { + return nil + } + return o.VideoProfile +} + +type Media struct { + ID *float64 `json:"id,omitempty"` + Duration *float64 `json:"duration,omitempty"` + Bitrate *float64 `json:"bitrate,omitempty"` + Width *float64 `json:"width,omitempty"` + Height *float64 `json:"height,omitempty"` + AspectRatio *float64 `json:"aspectRatio,omitempty"` + AudioChannels *float64 `json:"audioChannels,omitempty"` + AudioCodec *string `json:"audioCodec,omitempty"` + VideoCodec *string `json:"videoCodec,omitempty"` + VideoResolution *float64 `json:"videoResolution,omitempty"` + Container *string `json:"container,omitempty"` + VideoFrameRate *string `json:"videoFrameRate,omitempty"` + OptimizedForStreaming *float64 `json:"optimizedForStreaming,omitempty"` + Has64bitOffsets *bool `json:"has64bitOffsets,omitempty"` + VideoProfile *string `json:"videoProfile,omitempty"` + Part []Part `json:"Part,omitempty"` +} + +func (o *Media) GetID() *float64 { + if o == nil { + return nil + } + return o.ID +} + +func (o *Media) GetDuration() *float64 { + if o == nil { + return nil + } + return o.Duration +} + +func (o *Media) GetBitrate() *float64 { + if o == nil { + return nil + } + return o.Bitrate +} + +func (o *Media) GetWidth() *float64 { + if o == nil { + return nil + } + return o.Width +} + +func (o *Media) GetHeight() *float64 { + if o == nil { + return nil + } + return o.Height +} + +func (o *Media) GetAspectRatio() *float64 { + if o == nil { + return nil + } + return o.AspectRatio +} + +func (o *Media) GetAudioChannels() *float64 { + if o == nil { + return nil + } + return o.AudioChannels +} + +func (o *Media) GetAudioCodec() *string { + if o == nil { + return nil + } + return o.AudioCodec +} + +func (o *Media) GetVideoCodec() *string { + if o == nil { + return nil + } + return o.VideoCodec +} + +func (o *Media) GetVideoResolution() *float64 { + if o == nil { + return nil + } + return o.VideoResolution +} + +func (o *Media) GetContainer() *string { + if o == nil { + return nil + } + return o.Container +} + +func (o *Media) GetVideoFrameRate() *string { + if o == nil { + return nil + } + return o.VideoFrameRate +} + +func (o *Media) GetOptimizedForStreaming() *float64 { + if o == nil { + return nil + } + return o.OptimizedForStreaming +} + +func (o *Media) GetHas64bitOffsets() *bool { + if o == nil { + return nil + } + return o.Has64bitOffsets +} + +func (o *Media) GetVideoProfile() *string { + if o == nil { + return nil + } + return o.VideoProfile +} + +func (o *Media) GetPart() []Part { + if o == nil { + return nil + } + return o.Part +} + +type Genre struct { + Tag *string `json:"tag,omitempty"` +} + +func (o *Genre) GetTag() *string { + if o == nil { + return nil + } + return o.Tag +} + +type Director struct { + Tag *string `json:"tag,omitempty"` +} + +func (o *Director) GetTag() *string { + if o == nil { + return nil + } + return o.Tag +} + +type Writer struct { + Tag *string `json:"tag,omitempty"` +} + +func (o *Writer) GetTag() *string { + if o == nil { + return nil + } + return o.Tag +} + +type Country struct { + Tag *string `json:"tag,omitempty"` +} + +func (o *Country) GetTag() *string { + if o == nil { + return nil + } + return o.Tag +} + +type Role struct { + Tag *string `json:"tag,omitempty"` +} + +func (o *Role) GetTag() *string { + if o == nil { + return nil + } + return o.Tag +} + +type Metadata struct { + AllowSync *bool `json:"allowSync,omitempty"` + LibrarySectionID *float64 `json:"librarySectionID,omitempty"` + LibrarySectionTitle *string `json:"librarySectionTitle,omitempty"` + LibrarySectionUUID *string `json:"librarySectionUUID,omitempty"` + RatingKey *float64 `json:"ratingKey,omitempty"` + Key *string `json:"key,omitempty"` + GUID *string `json:"guid,omitempty"` + Studio *string `json:"studio,omitempty"` + Type *string `json:"type,omitempty"` + Title *string `json:"title,omitempty"` + ContentRating *string `json:"contentRating,omitempty"` + Summary *string `json:"summary,omitempty"` + Rating *float64 `json:"rating,omitempty"` + AudienceRating *float64 `json:"audienceRating,omitempty"` + Year *float64 `json:"year,omitempty"` + Tagline *string `json:"tagline,omitempty"` + Thumb *string `json:"thumb,omitempty"` + Art *string `json:"art,omitempty"` + Duration *float64 `json:"duration,omitempty"` + OriginallyAvailableAt *time.Time `json:"originallyAvailableAt,omitempty"` + AddedAt *float64 `json:"addedAt,omitempty"` + UpdatedAt *float64 `json:"updatedAt,omitempty"` + AudienceRatingImage *string `json:"audienceRatingImage,omitempty"` + ChapterSource *string `json:"chapterSource,omitempty"` + PrimaryExtraKey *string `json:"primaryExtraKey,omitempty"` + RatingImage *string `json:"ratingImage,omitempty"` + Media []Media `json:"Media,omitempty"` + Genre []Genre `json:"Genre,omitempty"` + Director []Director `json:"Director,omitempty"` + Writer []Writer `json:"Writer,omitempty"` + Country []Country `json:"Country,omitempty"` + Role []Role `json:"Role,omitempty"` +} + +func (m Metadata) MarshalJSON() ([]byte, error) { + return utils.MarshalJSON(m, "", false) +} + +func (m *Metadata) UnmarshalJSON(data []byte) error { + if err := utils.UnmarshalJSON(data, &m, "", false, false); err != nil { + return err + } + return nil +} + +func (o *Metadata) GetAllowSync() *bool { + if o == nil { + return nil + } + return o.AllowSync +} + +func (o *Metadata) GetLibrarySectionID() *float64 { + if o == nil { + return nil + } + return o.LibrarySectionID +} + +func (o *Metadata) GetLibrarySectionTitle() *string { + if o == nil { + return nil + } + return o.LibrarySectionTitle +} + +func (o *Metadata) GetLibrarySectionUUID() *string { + if o == nil { + return nil + } + return o.LibrarySectionUUID +} + +func (o *Metadata) GetRatingKey() *float64 { + if o == nil { + return nil + } + return o.RatingKey +} + +func (o *Metadata) GetKey() *string { + if o == nil { + return nil + } + return o.Key +} + +func (o *Metadata) GetGUID() *string { + if o == nil { + return nil + } + return o.GUID +} + +func (o *Metadata) GetStudio() *string { + if o == nil { + return nil + } + return o.Studio +} + +func (o *Metadata) GetType() *string { + if o == nil { + return nil + } + return o.Type +} + +func (o *Metadata) GetTitle() *string { + if o == nil { + return nil + } + return o.Title +} + +func (o *Metadata) GetContentRating() *string { + if o == nil { + return nil + } + return o.ContentRating +} + +func (o *Metadata) GetSummary() *string { + if o == nil { + return nil + } + return o.Summary +} + +func (o *Metadata) GetRating() *float64 { + if o == nil { + return nil + } + return o.Rating +} + +func (o *Metadata) GetAudienceRating() *float64 { + if o == nil { + return nil + } + return o.AudienceRating +} + +func (o *Metadata) GetYear() *float64 { + if o == nil { + return nil + } + return o.Year +} + +func (o *Metadata) GetTagline() *string { + if o == nil { + return nil + } + return o.Tagline +} + +func (o *Metadata) GetThumb() *string { + if o == nil { + return nil + } + return o.Thumb +} + +func (o *Metadata) GetArt() *string { + if o == nil { + return nil + } + return o.Art +} + +func (o *Metadata) GetDuration() *float64 { + if o == nil { + return nil + } + return o.Duration +} + +func (o *Metadata) GetOriginallyAvailableAt() *time.Time { + if o == nil { + return nil + } + return o.OriginallyAvailableAt +} + +func (o *Metadata) GetAddedAt() *float64 { + if o == nil { + return nil + } + return o.AddedAt +} + +func (o *Metadata) GetUpdatedAt() *float64 { + if o == nil { + return nil + } + return o.UpdatedAt +} + +func (o *Metadata) GetAudienceRatingImage() *string { + if o == nil { + return nil + } + return o.AudienceRatingImage +} + +func (o *Metadata) GetChapterSource() *string { + if o == nil { + return nil + } + return o.ChapterSource +} + +func (o *Metadata) GetPrimaryExtraKey() *string { + if o == nil { + return nil + } + return o.PrimaryExtraKey +} + +func (o *Metadata) GetRatingImage() *string { + if o == nil { + return nil + } + return o.RatingImage +} + +func (o *Metadata) GetMedia() []Media { + if o == nil { + return nil + } + return o.Media +} + +func (o *Metadata) GetGenre() []Genre { + if o == nil { + return nil + } + return o.Genre +} + +func (o *Metadata) GetDirector() []Director { + if o == nil { + return nil + } + return o.Director +} + +func (o *Metadata) GetWriter() []Writer { + if o == nil { + return nil + } + return o.Writer +} + +func (o *Metadata) GetCountry() []Country { + if o == nil { + return nil + } + return o.Country +} + +func (o *Metadata) GetRole() []Role { + if o == nil { + return nil + } + return o.Role +} + +type GetRecentlyAddedMediaContainer struct { + Size *float64 `json:"size,omitempty"` + AllowSync *bool `json:"allowSync,omitempty"` + Identifier *string `json:"identifier,omitempty"` + MediaTagPrefix *string `json:"mediaTagPrefix,omitempty"` + MediaTagVersion *float64 `json:"mediaTagVersion,omitempty"` + MixedParents *bool `json:"mixedParents,omitempty"` + Metadata []Metadata `json:"Metadata,omitempty"` +} + +func (o *GetRecentlyAddedMediaContainer) GetSize() *float64 { + if o == nil { + return nil + } + return o.Size +} + +func (o *GetRecentlyAddedMediaContainer) GetAllowSync() *bool { + if o == nil { + return nil + } + return o.AllowSync +} + +func (o *GetRecentlyAddedMediaContainer) GetIdentifier() *string { + if o == nil { + return nil + } + return o.Identifier +} + +func (o *GetRecentlyAddedMediaContainer) GetMediaTagPrefix() *string { + if o == nil { + return nil + } + return o.MediaTagPrefix +} + +func (o *GetRecentlyAddedMediaContainer) GetMediaTagVersion() *float64 { + if o == nil { + return nil + } + return o.MediaTagVersion +} + +func (o *GetRecentlyAddedMediaContainer) GetMixedParents() *bool { + if o == nil { + return nil + } + return o.MixedParents +} + +func (o *GetRecentlyAddedMediaContainer) GetMetadata() []Metadata { + if o == nil { + return nil + } + return o.Metadata +} + +// GetRecentlyAddedResponseBody - The recently added content +type GetRecentlyAddedResponseBody struct { + MediaContainer *GetRecentlyAddedMediaContainer `json:"MediaContainer,omitempty"` +} + +func (o *GetRecentlyAddedResponseBody) GetMediaContainer() *GetRecentlyAddedMediaContainer { + if o == nil { + return nil + } + return o.MediaContainer +} + +type GetRecentlyAddedResponse struct { + // HTTP response content type for this operation + ContentType string + // HTTP response status code for this operation + StatusCode int + // Raw HTTP response; suitable for custom response parsing + RawResponse *http.Response + // The recently added content + TwoHundredApplicationJSONObject *GetRecentlyAddedResponseBody + // Unauthorized - Returned if the X-Plex-Token is missing from the header or query. + FourHundredAndOneApplicationJSONObject *GetRecentlyAddedLibraryResponseBody +} + +func (o *GetRecentlyAddedResponse) GetContentType() string { + if o == nil { + return "" + } + return o.ContentType +} + +func (o *GetRecentlyAddedResponse) GetStatusCode() int { + if o == nil { + return 0 + } + return o.StatusCode +} + +func (o *GetRecentlyAddedResponse) GetRawResponse() *http.Response { + if o == nil { + return nil + } + return o.RawResponse +} + +func (o *GetRecentlyAddedResponse) GetTwoHundredApplicationJSONObject() *GetRecentlyAddedResponseBody { + if o == nil { + return nil + } + return o.TwoHundredApplicationJSONObject +} + +func (o *GetRecentlyAddedResponse) GetFourHundredAndOneApplicationJSONObject() *GetRecentlyAddedLibraryResponseBody { + if o == nil { + return nil + } + return o.FourHundredAndOneApplicationJSONObject +} diff --git a/internal/sdk/pkg/models/operations/getresizedphoto.go b/internal/sdk/pkg/models/operations/getresizedphoto.go new file mode 100644 index 0000000..edcfd96 --- /dev/null +++ b/internal/sdk/pkg/models/operations/getresizedphoto.go @@ -0,0 +1,221 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package operations + +import ( + "encoding/json" + "fmt" + "github.com/LukeHagar/terraform-provider-PlexAPI/internal/sdk/pkg/utils" + "net/http" +) + +// MinSize - images are always scaled proportionally. A value of '1' in minSize will make the smaller native dimension the dimension resized against. +type MinSize int64 + +const ( + MinSizeZero MinSize = 0 + MinSizeOne MinSize = 1 +) + +func (e MinSize) ToPointer() *MinSize { + return &e +} + +func (e *MinSize) UnmarshalJSON(data []byte) error { + var v int64 + if err := json.Unmarshal(data, &v); err != nil { + return err + } + switch v { + case 0: + fallthrough + case 1: + *e = MinSize(v) + return nil + default: + return fmt.Errorf("invalid value for MinSize: %v", v) + } +} + +// Upscale - allow images to be resized beyond native dimensions. +type Upscale int64 + +const ( + UpscaleZero Upscale = 0 + UpscaleOne Upscale = 1 +) + +func (e Upscale) ToPointer() *Upscale { + return &e +} + +func (e *Upscale) UnmarshalJSON(data []byte) error { + var v int64 + if err := json.Unmarshal(data, &v); err != nil { + return err + } + switch v { + case 0: + fallthrough + case 1: + *e = Upscale(v) + return nil + default: + return fmt.Errorf("invalid value for Upscale: %v", v) + } +} + +type GetResizedPhotoRequest struct { + // The width for the resized photo + Width float64 `queryParam:"style=form,explode=true,name=width"` + // The height for the resized photo + Height float64 `queryParam:"style=form,explode=true,name=height"` + // The opacity for the resized photo + Opacity int64 `default:"100" queryParam:"style=form,explode=true,name=opacity"` + // The width for the resized photo + Blur float64 `queryParam:"style=form,explode=true,name=blur"` + // images are always scaled proportionally. A value of '1' in minSize will make the smaller native dimension the dimension resized against. + MinSize MinSize `queryParam:"style=form,explode=true,name=minSize"` + // allow images to be resized beyond native dimensions. + Upscale Upscale `queryParam:"style=form,explode=true,name=upscale"` + // path to image within Plex + URL string `queryParam:"style=form,explode=true,name=url"` +} + +func (g GetResizedPhotoRequest) MarshalJSON() ([]byte, error) { + return utils.MarshalJSON(g, "", false) +} + +func (g *GetResizedPhotoRequest) UnmarshalJSON(data []byte) error { + if err := utils.UnmarshalJSON(data, &g, "", false, false); err != nil { + return err + } + return nil +} + +func (o *GetResizedPhotoRequest) GetWidth() float64 { + if o == nil { + return 0.0 + } + return o.Width +} + +func (o *GetResizedPhotoRequest) GetHeight() float64 { + if o == nil { + return 0.0 + } + return o.Height +} + +func (o *GetResizedPhotoRequest) GetOpacity() int64 { + if o == nil { + return 0 + } + return o.Opacity +} + +func (o *GetResizedPhotoRequest) GetBlur() float64 { + if o == nil { + return 0.0 + } + return o.Blur +} + +func (o *GetResizedPhotoRequest) GetMinSize() MinSize { + if o == nil { + return MinSize(0) + } + return o.MinSize +} + +func (o *GetResizedPhotoRequest) GetUpscale() Upscale { + if o == nil { + return Upscale(0) + } + return o.Upscale +} + +func (o *GetResizedPhotoRequest) GetURL() string { + if o == nil { + return "" + } + return o.URL +} + +type GetResizedPhotoErrors struct { + Code *float64 `json:"code,omitempty"` + Message *string `json:"message,omitempty"` + Status *float64 `json:"status,omitempty"` +} + +func (o *GetResizedPhotoErrors) GetCode() *float64 { + if o == nil { + return nil + } + return o.Code +} + +func (o *GetResizedPhotoErrors) GetMessage() *string { + if o == nil { + return nil + } + return o.Message +} + +func (o *GetResizedPhotoErrors) GetStatus() *float64 { + if o == nil { + return nil + } + return o.Status +} + +// GetResizedPhotoResponseBody - Unauthorized - Returned if the X-Plex-Token is missing from the header or query. +type GetResizedPhotoResponseBody struct { + Errors []GetResizedPhotoErrors `json:"errors,omitempty"` +} + +func (o *GetResizedPhotoResponseBody) GetErrors() []GetResizedPhotoErrors { + if o == nil { + return nil + } + return o.Errors +} + +type GetResizedPhotoResponse struct { + // HTTP response content type for this operation + ContentType string + // HTTP response status code for this operation + StatusCode int + // Raw HTTP response; suitable for custom response parsing + RawResponse *http.Response + // Unauthorized - Returned if the X-Plex-Token is missing from the header or query. + Object *GetResizedPhotoResponseBody +} + +func (o *GetResizedPhotoResponse) GetContentType() string { + if o == nil { + return "" + } + return o.ContentType +} + +func (o *GetResizedPhotoResponse) GetStatusCode() int { + if o == nil { + return 0 + } + return o.StatusCode +} + +func (o *GetResizedPhotoResponse) GetRawResponse() *http.Response { + if o == nil { + return nil + } + return o.RawResponse +} + +func (o *GetResizedPhotoResponse) GetObject() *GetResizedPhotoResponseBody { + if o == nil { + return nil + } + return o.Object +} diff --git a/internal/sdk/pkg/models/operations/getsearchresults.go b/internal/sdk/pkg/models/operations/getsearchresults.go new file mode 100644 index 0000000..10718c9 --- /dev/null +++ b/internal/sdk/pkg/models/operations/getsearchresults.go @@ -0,0 +1,729 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package operations + +import ( + "github.com/LukeHagar/terraform-provider-PlexAPI/internal/sdk/pkg/utils" + "net/http" + "time" +) + +type GetSearchResultsRequest struct { + // The search query string to use + Query string `queryParam:"style=form,explode=true,name=query"` +} + +func (o *GetSearchResultsRequest) GetQuery() string { + if o == nil { + return "" + } + return o.Query +} + +type GetSearchResultsErrors struct { + Code *float64 `json:"code,omitempty"` + Message *string `json:"message,omitempty"` + Status *float64 `json:"status,omitempty"` +} + +func (o *GetSearchResultsErrors) GetCode() *float64 { + if o == nil { + return nil + } + return o.Code +} + +func (o *GetSearchResultsErrors) GetMessage() *string { + if o == nil { + return nil + } + return o.Message +} + +func (o *GetSearchResultsErrors) GetStatus() *float64 { + if o == nil { + return nil + } + return o.Status +} + +// GetSearchResultsSearchResponseBody - Unauthorized - Returned if the X-Plex-Token is missing from the header or query. +type GetSearchResultsSearchResponseBody struct { + Errors []GetSearchResultsErrors `json:"errors,omitempty"` +} + +func (o *GetSearchResultsSearchResponseBody) GetErrors() []GetSearchResultsErrors { + if o == nil { + return nil + } + return o.Errors +} + +type GetSearchResultsPart struct { + ID *float64 `json:"id,omitempty"` + Key *string `json:"key,omitempty"` + Duration *float64 `json:"duration,omitempty"` + File *string `json:"file,omitempty"` + Size *float64 `json:"size,omitempty"` + AudioProfile *string `json:"audioProfile,omitempty"` + Container *string `json:"container,omitempty"` + VideoProfile *string `json:"videoProfile,omitempty"` +} + +func (o *GetSearchResultsPart) GetID() *float64 { + if o == nil { + return nil + } + return o.ID +} + +func (o *GetSearchResultsPart) GetKey() *string { + if o == nil { + return nil + } + return o.Key +} + +func (o *GetSearchResultsPart) GetDuration() *float64 { + if o == nil { + return nil + } + return o.Duration +} + +func (o *GetSearchResultsPart) GetFile() *string { + if o == nil { + return nil + } + return o.File +} + +func (o *GetSearchResultsPart) GetSize() *float64 { + if o == nil { + return nil + } + return o.Size +} + +func (o *GetSearchResultsPart) GetAudioProfile() *string { + if o == nil { + return nil + } + return o.AudioProfile +} + +func (o *GetSearchResultsPart) GetContainer() *string { + if o == nil { + return nil + } + return o.Container +} + +func (o *GetSearchResultsPart) GetVideoProfile() *string { + if o == nil { + return nil + } + return o.VideoProfile +} + +type GetSearchResultsMedia struct { + ID *float64 `json:"id,omitempty"` + Duration *float64 `json:"duration,omitempty"` + Bitrate *float64 `json:"bitrate,omitempty"` + Width *float64 `json:"width,omitempty"` + Height *float64 `json:"height,omitempty"` + AspectRatio *float64 `json:"aspectRatio,omitempty"` + AudioChannels *float64 `json:"audioChannels,omitempty"` + AudioCodec *string `json:"audioCodec,omitempty"` + VideoCodec *string `json:"videoCodec,omitempty"` + VideoResolution *float64 `json:"videoResolution,omitempty"` + Container *string `json:"container,omitempty"` + VideoFrameRate *string `json:"videoFrameRate,omitempty"` + AudioProfile *string `json:"audioProfile,omitempty"` + VideoProfile *string `json:"videoProfile,omitempty"` + Part []GetSearchResultsPart `json:"Part,omitempty"` +} + +func (o *GetSearchResultsMedia) GetID() *float64 { + if o == nil { + return nil + } + return o.ID +} + +func (o *GetSearchResultsMedia) GetDuration() *float64 { + if o == nil { + return nil + } + return o.Duration +} + +func (o *GetSearchResultsMedia) GetBitrate() *float64 { + if o == nil { + return nil + } + return o.Bitrate +} + +func (o *GetSearchResultsMedia) GetWidth() *float64 { + if o == nil { + return nil + } + return o.Width +} + +func (o *GetSearchResultsMedia) GetHeight() *float64 { + if o == nil { + return nil + } + return o.Height +} + +func (o *GetSearchResultsMedia) GetAspectRatio() *float64 { + if o == nil { + return nil + } + return o.AspectRatio +} + +func (o *GetSearchResultsMedia) GetAudioChannels() *float64 { + if o == nil { + return nil + } + return o.AudioChannels +} + +func (o *GetSearchResultsMedia) GetAudioCodec() *string { + if o == nil { + return nil + } + return o.AudioCodec +} + +func (o *GetSearchResultsMedia) GetVideoCodec() *string { + if o == nil { + return nil + } + return o.VideoCodec +} + +func (o *GetSearchResultsMedia) GetVideoResolution() *float64 { + if o == nil { + return nil + } + return o.VideoResolution +} + +func (o *GetSearchResultsMedia) GetContainer() *string { + if o == nil { + return nil + } + return o.Container +} + +func (o *GetSearchResultsMedia) GetVideoFrameRate() *string { + if o == nil { + return nil + } + return o.VideoFrameRate +} + +func (o *GetSearchResultsMedia) GetAudioProfile() *string { + if o == nil { + return nil + } + return o.AudioProfile +} + +func (o *GetSearchResultsMedia) GetVideoProfile() *string { + if o == nil { + return nil + } + return o.VideoProfile +} + +func (o *GetSearchResultsMedia) GetPart() []GetSearchResultsPart { + if o == nil { + return nil + } + return o.Part +} + +type GetSearchResultsGenre struct { + Tag *string `json:"tag,omitempty"` +} + +func (o *GetSearchResultsGenre) GetTag() *string { + if o == nil { + return nil + } + return o.Tag +} + +type GetSearchResultsDirector struct { + Tag *string `json:"tag,omitempty"` +} + +func (o *GetSearchResultsDirector) GetTag() *string { + if o == nil { + return nil + } + return o.Tag +} + +type GetSearchResultsWriter struct { + Tag *string `json:"tag,omitempty"` +} + +func (o *GetSearchResultsWriter) GetTag() *string { + if o == nil { + return nil + } + return o.Tag +} + +type GetSearchResultsCountry struct { + Tag *string `json:"tag,omitempty"` +} + +func (o *GetSearchResultsCountry) GetTag() *string { + if o == nil { + return nil + } + return o.Tag +} + +type GetSearchResultsRole struct { + Tag *string `json:"tag,omitempty"` +} + +func (o *GetSearchResultsRole) GetTag() *string { + if o == nil { + return nil + } + return o.Tag +} + +type GetSearchResultsMetadata struct { + AllowSync *bool `json:"allowSync,omitempty"` + LibrarySectionID *float64 `json:"librarySectionID,omitempty"` + LibrarySectionTitle *string `json:"librarySectionTitle,omitempty"` + LibrarySectionUUID *string `json:"librarySectionUUID,omitempty"` + Personal *bool `json:"personal,omitempty"` + SourceTitle *string `json:"sourceTitle,omitempty"` + RatingKey *float64 `json:"ratingKey,omitempty"` + Key *string `json:"key,omitempty"` + GUID *string `json:"guid,omitempty"` + Studio *string `json:"studio,omitempty"` + Type *string `json:"type,omitempty"` + Title *string `json:"title,omitempty"` + ContentRating *string `json:"contentRating,omitempty"` + Summary *string `json:"summary,omitempty"` + Rating *float64 `json:"rating,omitempty"` + AudienceRating *float64 `json:"audienceRating,omitempty"` + Year *float64 `json:"year,omitempty"` + Tagline *string `json:"tagline,omitempty"` + Thumb *string `json:"thumb,omitempty"` + Art *string `json:"art,omitempty"` + Duration *float64 `json:"duration,omitempty"` + OriginallyAvailableAt *time.Time `json:"originallyAvailableAt,omitempty"` + AddedAt *float64 `json:"addedAt,omitempty"` + UpdatedAt *float64 `json:"updatedAt,omitempty"` + AudienceRatingImage *string `json:"audienceRatingImage,omitempty"` + ChapterSource *string `json:"chapterSource,omitempty"` + PrimaryExtraKey *string `json:"primaryExtraKey,omitempty"` + RatingImage *string `json:"ratingImage,omitempty"` + Media []GetSearchResultsMedia `json:"Media,omitempty"` + Genre []GetSearchResultsGenre `json:"Genre,omitempty"` + Director []GetSearchResultsDirector `json:"Director,omitempty"` + Writer []GetSearchResultsWriter `json:"Writer,omitempty"` + Country []GetSearchResultsCountry `json:"Country,omitempty"` + Role []GetSearchResultsRole `json:"Role,omitempty"` +} + +func (g GetSearchResultsMetadata) MarshalJSON() ([]byte, error) { + return utils.MarshalJSON(g, "", false) +} + +func (g *GetSearchResultsMetadata) UnmarshalJSON(data []byte) error { + if err := utils.UnmarshalJSON(data, &g, "", false, false); err != nil { + return err + } + return nil +} + +func (o *GetSearchResultsMetadata) GetAllowSync() *bool { + if o == nil { + return nil + } + return o.AllowSync +} + +func (o *GetSearchResultsMetadata) GetLibrarySectionID() *float64 { + if o == nil { + return nil + } + return o.LibrarySectionID +} + +func (o *GetSearchResultsMetadata) GetLibrarySectionTitle() *string { + if o == nil { + return nil + } + return o.LibrarySectionTitle +} + +func (o *GetSearchResultsMetadata) GetLibrarySectionUUID() *string { + if o == nil { + return nil + } + return o.LibrarySectionUUID +} + +func (o *GetSearchResultsMetadata) GetPersonal() *bool { + if o == nil { + return nil + } + return o.Personal +} + +func (o *GetSearchResultsMetadata) GetSourceTitle() *string { + if o == nil { + return nil + } + return o.SourceTitle +} + +func (o *GetSearchResultsMetadata) GetRatingKey() *float64 { + if o == nil { + return nil + } + return o.RatingKey +} + +func (o *GetSearchResultsMetadata) GetKey() *string { + if o == nil { + return nil + } + return o.Key +} + +func (o *GetSearchResultsMetadata) GetGUID() *string { + if o == nil { + return nil + } + return o.GUID +} + +func (o *GetSearchResultsMetadata) GetStudio() *string { + if o == nil { + return nil + } + return o.Studio +} + +func (o *GetSearchResultsMetadata) GetType() *string { + if o == nil { + return nil + } + return o.Type +} + +func (o *GetSearchResultsMetadata) GetTitle() *string { + if o == nil { + return nil + } + return o.Title +} + +func (o *GetSearchResultsMetadata) GetContentRating() *string { + if o == nil { + return nil + } + return o.ContentRating +} + +func (o *GetSearchResultsMetadata) GetSummary() *string { + if o == nil { + return nil + } + return o.Summary +} + +func (o *GetSearchResultsMetadata) GetRating() *float64 { + if o == nil { + return nil + } + return o.Rating +} + +func (o *GetSearchResultsMetadata) GetAudienceRating() *float64 { + if o == nil { + return nil + } + return o.AudienceRating +} + +func (o *GetSearchResultsMetadata) GetYear() *float64 { + if o == nil { + return nil + } + return o.Year +} + +func (o *GetSearchResultsMetadata) GetTagline() *string { + if o == nil { + return nil + } + return o.Tagline +} + +func (o *GetSearchResultsMetadata) GetThumb() *string { + if o == nil { + return nil + } + return o.Thumb +} + +func (o *GetSearchResultsMetadata) GetArt() *string { + if o == nil { + return nil + } + return o.Art +} + +func (o *GetSearchResultsMetadata) GetDuration() *float64 { + if o == nil { + return nil + } + return o.Duration +} + +func (o *GetSearchResultsMetadata) GetOriginallyAvailableAt() *time.Time { + if o == nil { + return nil + } + return o.OriginallyAvailableAt +} + +func (o *GetSearchResultsMetadata) GetAddedAt() *float64 { + if o == nil { + return nil + } + return o.AddedAt +} + +func (o *GetSearchResultsMetadata) GetUpdatedAt() *float64 { + if o == nil { + return nil + } + return o.UpdatedAt +} + +func (o *GetSearchResultsMetadata) GetAudienceRatingImage() *string { + if o == nil { + return nil + } + return o.AudienceRatingImage +} + +func (o *GetSearchResultsMetadata) GetChapterSource() *string { + if o == nil { + return nil + } + return o.ChapterSource +} + +func (o *GetSearchResultsMetadata) GetPrimaryExtraKey() *string { + if o == nil { + return nil + } + return o.PrimaryExtraKey +} + +func (o *GetSearchResultsMetadata) GetRatingImage() *string { + if o == nil { + return nil + } + return o.RatingImage +} + +func (o *GetSearchResultsMetadata) GetMedia() []GetSearchResultsMedia { + if o == nil { + return nil + } + return o.Media +} + +func (o *GetSearchResultsMetadata) GetGenre() []GetSearchResultsGenre { + if o == nil { + return nil + } + return o.Genre +} + +func (o *GetSearchResultsMetadata) GetDirector() []GetSearchResultsDirector { + if o == nil { + return nil + } + return o.Director +} + +func (o *GetSearchResultsMetadata) GetWriter() []GetSearchResultsWriter { + if o == nil { + return nil + } + return o.Writer +} + +func (o *GetSearchResultsMetadata) GetCountry() []GetSearchResultsCountry { + if o == nil { + return nil + } + return o.Country +} + +func (o *GetSearchResultsMetadata) GetRole() []GetSearchResultsRole { + if o == nil { + return nil + } + return o.Role +} + +type Provider struct { + Key *string `json:"key,omitempty"` + Title *string `json:"title,omitempty"` + Type *string `json:"type,omitempty"` +} + +func (o *Provider) GetKey() *string { + if o == nil { + return nil + } + return o.Key +} + +func (o *Provider) GetTitle() *string { + if o == nil { + return nil + } + return o.Title +} + +func (o *Provider) GetType() *string { + if o == nil { + return nil + } + return o.Type +} + +type GetSearchResultsMediaContainer struct { + Size *float64 `json:"size,omitempty"` + Identifier *string `json:"identifier,omitempty"` + MediaTagPrefix *string `json:"mediaTagPrefix,omitempty"` + MediaTagVersion *float64 `json:"mediaTagVersion,omitempty"` + Metadata []GetSearchResultsMetadata `json:"Metadata,omitempty"` + Provider []Provider `json:"Provider,omitempty"` +} + +func (o *GetSearchResultsMediaContainer) GetSize() *float64 { + if o == nil { + return nil + } + return o.Size +} + +func (o *GetSearchResultsMediaContainer) GetIdentifier() *string { + if o == nil { + return nil + } + return o.Identifier +} + +func (o *GetSearchResultsMediaContainer) GetMediaTagPrefix() *string { + if o == nil { + return nil + } + return o.MediaTagPrefix +} + +func (o *GetSearchResultsMediaContainer) GetMediaTagVersion() *float64 { + if o == nil { + return nil + } + return o.MediaTagVersion +} + +func (o *GetSearchResultsMediaContainer) GetMetadata() []GetSearchResultsMetadata { + if o == nil { + return nil + } + return o.Metadata +} + +func (o *GetSearchResultsMediaContainer) GetProvider() []Provider { + if o == nil { + return nil + } + return o.Provider +} + +// GetSearchResultsResponseBody - Search Results +type GetSearchResultsResponseBody struct { + MediaContainer *GetSearchResultsMediaContainer `json:"MediaContainer,omitempty"` +} + +func (o *GetSearchResultsResponseBody) GetMediaContainer() *GetSearchResultsMediaContainer { + if o == nil { + return nil + } + return o.MediaContainer +} + +type GetSearchResultsResponse struct { + // HTTP response content type for this operation + ContentType string + // HTTP response status code for this operation + StatusCode int + // Raw HTTP response; suitable for custom response parsing + RawResponse *http.Response + // Search Results + TwoHundredApplicationJSONObject *GetSearchResultsResponseBody + // Unauthorized - Returned if the X-Plex-Token is missing from the header or query. + FourHundredAndOneApplicationJSONObject *GetSearchResultsSearchResponseBody +} + +func (o *GetSearchResultsResponse) GetContentType() string { + if o == nil { + return "" + } + return o.ContentType +} + +func (o *GetSearchResultsResponse) GetStatusCode() int { + if o == nil { + return 0 + } + return o.StatusCode +} + +func (o *GetSearchResultsResponse) GetRawResponse() *http.Response { + if o == nil { + return nil + } + return o.RawResponse +} + +func (o *GetSearchResultsResponse) GetTwoHundredApplicationJSONObject() *GetSearchResultsResponseBody { + if o == nil { + return nil + } + return o.TwoHundredApplicationJSONObject +} + +func (o *GetSearchResultsResponse) GetFourHundredAndOneApplicationJSONObject() *GetSearchResultsSearchResponseBody { + if o == nil { + return nil + } + return o.FourHundredAndOneApplicationJSONObject +} diff --git a/internal/sdk/pkg/models/operations/getserveractivities.go b/internal/sdk/pkg/models/operations/getserveractivities.go new file mode 100644 index 0000000..30460b1 --- /dev/null +++ b/internal/sdk/pkg/models/operations/getserveractivities.go @@ -0,0 +1,203 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package operations + +import ( + "net/http" +) + +type GetServerActivitiesErrors struct { + Code *float64 `json:"code,omitempty"` + Message *string `json:"message,omitempty"` + Status *float64 `json:"status,omitempty"` +} + +func (o *GetServerActivitiesErrors) GetCode() *float64 { + if o == nil { + return nil + } + return o.Code +} + +func (o *GetServerActivitiesErrors) GetMessage() *string { + if o == nil { + return nil + } + return o.Message +} + +func (o *GetServerActivitiesErrors) GetStatus() *float64 { + if o == nil { + return nil + } + return o.Status +} + +// GetServerActivitiesActivitiesResponseBody - Unauthorized - Returned if the X-Plex-Token is missing from the header or query. +type GetServerActivitiesActivitiesResponseBody struct { + Errors []GetServerActivitiesErrors `json:"errors,omitempty"` +} + +func (o *GetServerActivitiesActivitiesResponseBody) GetErrors() []GetServerActivitiesErrors { + if o == nil { + return nil + } + return o.Errors +} + +type Context struct { + LibrarySectionID *string `json:"librarySectionID,omitempty"` +} + +func (o *Context) GetLibrarySectionID() *string { + if o == nil { + return nil + } + return o.LibrarySectionID +} + +type Activity struct { + UUID *string `json:"uuid,omitempty"` + Type *string `json:"type,omitempty"` + Cancellable *bool `json:"cancellable,omitempty"` + UserID *float64 `json:"userID,omitempty"` + Title *string `json:"title,omitempty"` + Subtitle *string `json:"subtitle,omitempty"` + Progress *float64 `json:"progress,omitempty"` + Context *Context `json:"Context,omitempty"` +} + +func (o *Activity) GetUUID() *string { + if o == nil { + return nil + } + return o.UUID +} + +func (o *Activity) GetType() *string { + if o == nil { + return nil + } + return o.Type +} + +func (o *Activity) GetCancellable() *bool { + if o == nil { + return nil + } + return o.Cancellable +} + +func (o *Activity) GetUserID() *float64 { + if o == nil { + return nil + } + return o.UserID +} + +func (o *Activity) GetTitle() *string { + if o == nil { + return nil + } + return o.Title +} + +func (o *Activity) GetSubtitle() *string { + if o == nil { + return nil + } + return o.Subtitle +} + +func (o *Activity) GetProgress() *float64 { + if o == nil { + return nil + } + return o.Progress +} + +func (o *Activity) GetContext() *Context { + if o == nil { + return nil + } + return o.Context +} + +type GetServerActivitiesMediaContainer struct { + Size *float64 `json:"size,omitempty"` + Activity []Activity `json:"Activity,omitempty"` +} + +func (o *GetServerActivitiesMediaContainer) GetSize() *float64 { + if o == nil { + return nil + } + return o.Size +} + +func (o *GetServerActivitiesMediaContainer) GetActivity() []Activity { + if o == nil { + return nil + } + return o.Activity +} + +// GetServerActivitiesResponseBody - The Server Activities +type GetServerActivitiesResponseBody struct { + MediaContainer *GetServerActivitiesMediaContainer `json:"MediaContainer,omitempty"` +} + +func (o *GetServerActivitiesResponseBody) GetMediaContainer() *GetServerActivitiesMediaContainer { + if o == nil { + return nil + } + return o.MediaContainer +} + +type GetServerActivitiesResponse struct { + // HTTP response content type for this operation + ContentType string + // HTTP response status code for this operation + StatusCode int + // Raw HTTP response; suitable for custom response parsing + RawResponse *http.Response + // The Server Activities + TwoHundredApplicationJSONObject *GetServerActivitiesResponseBody + // Unauthorized - Returned if the X-Plex-Token is missing from the header or query. + FourHundredAndOneApplicationJSONObject *GetServerActivitiesActivitiesResponseBody +} + +func (o *GetServerActivitiesResponse) GetContentType() string { + if o == nil { + return "" + } + return o.ContentType +} + +func (o *GetServerActivitiesResponse) GetStatusCode() int { + if o == nil { + return 0 + } + return o.StatusCode +} + +func (o *GetServerActivitiesResponse) GetRawResponse() *http.Response { + if o == nil { + return nil + } + return o.RawResponse +} + +func (o *GetServerActivitiesResponse) GetTwoHundredApplicationJSONObject() *GetServerActivitiesResponseBody { + if o == nil { + return nil + } + return o.TwoHundredApplicationJSONObject +} + +func (o *GetServerActivitiesResponse) GetFourHundredAndOneApplicationJSONObject() *GetServerActivitiesActivitiesResponseBody { + if o == nil { + return nil + } + return o.FourHundredAndOneApplicationJSONObject +} diff --git a/internal/sdk/pkg/models/operations/getservercapabilities.go b/internal/sdk/pkg/models/operations/getservercapabilities.go new file mode 100644 index 0000000..4335a4c --- /dev/null +++ b/internal/sdk/pkg/models/operations/getservercapabilities.go @@ -0,0 +1,544 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package operations + +import ( + "net/http" +) + +type Errors struct { + Code *float64 `json:"code,omitempty"` + Message *string `json:"message,omitempty"` + Status *float64 `json:"status,omitempty"` +} + +func (o *Errors) GetCode() *float64 { + if o == nil { + return nil + } + return o.Code +} + +func (o *Errors) GetMessage() *string { + if o == nil { + return nil + } + return o.Message +} + +func (o *Errors) GetStatus() *float64 { + if o == nil { + return nil + } + return o.Status +} + +// GetServerCapabilitiesServerResponseBody - Unauthorized - Returned if the X-Plex-Token is missing from the header or query. +type GetServerCapabilitiesServerResponseBody struct { + Errors []Errors `json:"errors,omitempty"` +} + +func (o *GetServerCapabilitiesServerResponseBody) GetErrors() []Errors { + if o == nil { + return nil + } + return o.Errors +} + +type Directory struct { + Count *float64 `json:"count,omitempty"` + Key *string `json:"key,omitempty"` + Title *string `json:"title,omitempty"` +} + +func (o *Directory) GetCount() *float64 { + if o == nil { + return nil + } + return o.Count +} + +func (o *Directory) GetKey() *string { + if o == nil { + return nil + } + return o.Key +} + +func (o *Directory) GetTitle() *string { + if o == nil { + return nil + } + return o.Title +} + +type MediaContainer struct { + Size *float64 `json:"size,omitempty"` + AllowCameraUpload *bool `json:"allowCameraUpload,omitempty"` + AllowChannelAccess *bool `json:"allowChannelAccess,omitempty"` + AllowMediaDeletion *bool `json:"allowMediaDeletion,omitempty"` + AllowSharing *bool `json:"allowSharing,omitempty"` + AllowSync *bool `json:"allowSync,omitempty"` + AllowTuners *bool `json:"allowTuners,omitempty"` + BackgroundProcessing *bool `json:"backgroundProcessing,omitempty"` + Certificate *bool `json:"certificate,omitempty"` + CompanionProxy *bool `json:"companionProxy,omitempty"` + CountryCode *string `json:"countryCode,omitempty"` + Diagnostics *string `json:"diagnostics,omitempty"` + EventStream *bool `json:"eventStream,omitempty"` + FriendlyName *string `json:"friendlyName,omitempty"` + HubSearch *bool `json:"hubSearch,omitempty"` + ItemClusters *bool `json:"itemClusters,omitempty"` + Livetv *float64 `json:"livetv,omitempty"` + MachineIdentifier *string `json:"machineIdentifier,omitempty"` + MediaProviders *bool `json:"mediaProviders,omitempty"` + Multiuser *bool `json:"multiuser,omitempty"` + MusicAnalysis *float64 `json:"musicAnalysis,omitempty"` + MyPlex *bool `json:"myPlex,omitempty"` + MyPlexMappingState *string `json:"myPlexMappingState,omitempty"` + MyPlexSigninState *string `json:"myPlexSigninState,omitempty"` + MyPlexSubscription *bool `json:"myPlexSubscription,omitempty"` + MyPlexUsername *string `json:"myPlexUsername,omitempty"` + OfflineTranscode *float64 `json:"offlineTranscode,omitempty"` + OwnerFeatures *string `json:"ownerFeatures,omitempty"` + PhotoAutoTag *bool `json:"photoAutoTag,omitempty"` + Platform *string `json:"platform,omitempty"` + PlatformVersion *string `json:"platformVersion,omitempty"` + PluginHost *bool `json:"pluginHost,omitempty"` + PushNotifications *bool `json:"pushNotifications,omitempty"` + ReadOnlyLibraries *bool `json:"readOnlyLibraries,omitempty"` + StreamingBrainABRVersion *float64 `json:"streamingBrainABRVersion,omitempty"` + StreamingBrainVersion *float64 `json:"streamingBrainVersion,omitempty"` + Sync *bool `json:"sync,omitempty"` + TranscoderActiveVideoSessions *float64 `json:"transcoderActiveVideoSessions,omitempty"` + TranscoderAudio *bool `json:"transcoderAudio,omitempty"` + TranscoderLyrics *bool `json:"transcoderLyrics,omitempty"` + TranscoderPhoto *bool `json:"transcoderPhoto,omitempty"` + TranscoderSubtitles *bool `json:"transcoderSubtitles,omitempty"` + TranscoderVideo *bool `json:"transcoderVideo,omitempty"` + TranscoderVideoBitrates *string `json:"transcoderVideoBitrates,omitempty"` + TranscoderVideoQualities *string `json:"transcoderVideoQualities,omitempty"` + TranscoderVideoResolutions *string `json:"transcoderVideoResolutions,omitempty"` + UpdatedAt *float64 `json:"updatedAt,omitempty"` + Updater *bool `json:"updater,omitempty"` + Version *string `json:"version,omitempty"` + VoiceSearch *bool `json:"voiceSearch,omitempty"` + Directory []Directory `json:"Directory,omitempty"` +} + +func (o *MediaContainer) GetSize() *float64 { + if o == nil { + return nil + } + return o.Size +} + +func (o *MediaContainer) GetAllowCameraUpload() *bool { + if o == nil { + return nil + } + return o.AllowCameraUpload +} + +func (o *MediaContainer) GetAllowChannelAccess() *bool { + if o == nil { + return nil + } + return o.AllowChannelAccess +} + +func (o *MediaContainer) GetAllowMediaDeletion() *bool { + if o == nil { + return nil + } + return o.AllowMediaDeletion +} + +func (o *MediaContainer) GetAllowSharing() *bool { + if o == nil { + return nil + } + return o.AllowSharing +} + +func (o *MediaContainer) GetAllowSync() *bool { + if o == nil { + return nil + } + return o.AllowSync +} + +func (o *MediaContainer) GetAllowTuners() *bool { + if o == nil { + return nil + } + return o.AllowTuners +} + +func (o *MediaContainer) GetBackgroundProcessing() *bool { + if o == nil { + return nil + } + return o.BackgroundProcessing +} + +func (o *MediaContainer) GetCertificate() *bool { + if o == nil { + return nil + } + return o.Certificate +} + +func (o *MediaContainer) GetCompanionProxy() *bool { + if o == nil { + return nil + } + return o.CompanionProxy +} + +func (o *MediaContainer) GetCountryCode() *string { + if o == nil { + return nil + } + return o.CountryCode +} + +func (o *MediaContainer) GetDiagnostics() *string { + if o == nil { + return nil + } + return o.Diagnostics +} + +func (o *MediaContainer) GetEventStream() *bool { + if o == nil { + return nil + } + return o.EventStream +} + +func (o *MediaContainer) GetFriendlyName() *string { + if o == nil { + return nil + } + return o.FriendlyName +} + +func (o *MediaContainer) GetHubSearch() *bool { + if o == nil { + return nil + } + return o.HubSearch +} + +func (o *MediaContainer) GetItemClusters() *bool { + if o == nil { + return nil + } + return o.ItemClusters +} + +func (o *MediaContainer) GetLivetv() *float64 { + if o == nil { + return nil + } + return o.Livetv +} + +func (o *MediaContainer) GetMachineIdentifier() *string { + if o == nil { + return nil + } + return o.MachineIdentifier +} + +func (o *MediaContainer) GetMediaProviders() *bool { + if o == nil { + return nil + } + return o.MediaProviders +} + +func (o *MediaContainer) GetMultiuser() *bool { + if o == nil { + return nil + } + return o.Multiuser +} + +func (o *MediaContainer) GetMusicAnalysis() *float64 { + if o == nil { + return nil + } + return o.MusicAnalysis +} + +func (o *MediaContainer) GetMyPlex() *bool { + if o == nil { + return nil + } + return o.MyPlex +} + +func (o *MediaContainer) GetMyPlexMappingState() *string { + if o == nil { + return nil + } + return o.MyPlexMappingState +} + +func (o *MediaContainer) GetMyPlexSigninState() *string { + if o == nil { + return nil + } + return o.MyPlexSigninState +} + +func (o *MediaContainer) GetMyPlexSubscription() *bool { + if o == nil { + return nil + } + return o.MyPlexSubscription +} + +func (o *MediaContainer) GetMyPlexUsername() *string { + if o == nil { + return nil + } + return o.MyPlexUsername +} + +func (o *MediaContainer) GetOfflineTranscode() *float64 { + if o == nil { + return nil + } + return o.OfflineTranscode +} + +func (o *MediaContainer) GetOwnerFeatures() *string { + if o == nil { + return nil + } + return o.OwnerFeatures +} + +func (o *MediaContainer) GetPhotoAutoTag() *bool { + if o == nil { + return nil + } + return o.PhotoAutoTag +} + +func (o *MediaContainer) GetPlatform() *string { + if o == nil { + return nil + } + return o.Platform +} + +func (o *MediaContainer) GetPlatformVersion() *string { + if o == nil { + return nil + } + return o.PlatformVersion +} + +func (o *MediaContainer) GetPluginHost() *bool { + if o == nil { + return nil + } + return o.PluginHost +} + +func (o *MediaContainer) GetPushNotifications() *bool { + if o == nil { + return nil + } + return o.PushNotifications +} + +func (o *MediaContainer) GetReadOnlyLibraries() *bool { + if o == nil { + return nil + } + return o.ReadOnlyLibraries +} + +func (o *MediaContainer) GetStreamingBrainABRVersion() *float64 { + if o == nil { + return nil + } + return o.StreamingBrainABRVersion +} + +func (o *MediaContainer) GetStreamingBrainVersion() *float64 { + if o == nil { + return nil + } + return o.StreamingBrainVersion +} + +func (o *MediaContainer) GetSync() *bool { + if o == nil { + return nil + } + return o.Sync +} + +func (o *MediaContainer) GetTranscoderActiveVideoSessions() *float64 { + if o == nil { + return nil + } + return o.TranscoderActiveVideoSessions +} + +func (o *MediaContainer) GetTranscoderAudio() *bool { + if o == nil { + return nil + } + return o.TranscoderAudio +} + +func (o *MediaContainer) GetTranscoderLyrics() *bool { + if o == nil { + return nil + } + return o.TranscoderLyrics +} + +func (o *MediaContainer) GetTranscoderPhoto() *bool { + if o == nil { + return nil + } + return o.TranscoderPhoto +} + +func (o *MediaContainer) GetTranscoderSubtitles() *bool { + if o == nil { + return nil + } + return o.TranscoderSubtitles +} + +func (o *MediaContainer) GetTranscoderVideo() *bool { + if o == nil { + return nil + } + return o.TranscoderVideo +} + +func (o *MediaContainer) GetTranscoderVideoBitrates() *string { + if o == nil { + return nil + } + return o.TranscoderVideoBitrates +} + +func (o *MediaContainer) GetTranscoderVideoQualities() *string { + if o == nil { + return nil + } + return o.TranscoderVideoQualities +} + +func (o *MediaContainer) GetTranscoderVideoResolutions() *string { + if o == nil { + return nil + } + return o.TranscoderVideoResolutions +} + +func (o *MediaContainer) GetUpdatedAt() *float64 { + if o == nil { + return nil + } + return o.UpdatedAt +} + +func (o *MediaContainer) GetUpdater() *bool { + if o == nil { + return nil + } + return o.Updater +} + +func (o *MediaContainer) GetVersion() *string { + if o == nil { + return nil + } + return o.Version +} + +func (o *MediaContainer) GetVoiceSearch() *bool { + if o == nil { + return nil + } + return o.VoiceSearch +} + +func (o *MediaContainer) GetDirectory() []Directory { + if o == nil { + return nil + } + return o.Directory +} + +// GetServerCapabilitiesResponseBody - The Server Capabilities +type GetServerCapabilitiesResponseBody struct { + MediaContainer *MediaContainer `json:"MediaContainer,omitempty"` +} + +func (o *GetServerCapabilitiesResponseBody) GetMediaContainer() *MediaContainer { + if o == nil { + return nil + } + return o.MediaContainer +} + +type GetServerCapabilitiesResponse struct { + // HTTP response content type for this operation + ContentType string + // HTTP response status code for this operation + StatusCode int + // Raw HTTP response; suitable for custom response parsing + RawResponse *http.Response + // The Server Capabilities + TwoHundredApplicationJSONObject *GetServerCapabilitiesResponseBody + // Unauthorized - Returned if the X-Plex-Token is missing from the header or query. + FourHundredAndOneApplicationJSONObject *GetServerCapabilitiesServerResponseBody +} + +func (o *GetServerCapabilitiesResponse) GetContentType() string { + if o == nil { + return "" + } + return o.ContentType +} + +func (o *GetServerCapabilitiesResponse) GetStatusCode() int { + if o == nil { + return 0 + } + return o.StatusCode +} + +func (o *GetServerCapabilitiesResponse) GetRawResponse() *http.Response { + if o == nil { + return nil + } + return o.RawResponse +} + +func (o *GetServerCapabilitiesResponse) GetTwoHundredApplicationJSONObject() *GetServerCapabilitiesResponseBody { + if o == nil { + return nil + } + return o.TwoHundredApplicationJSONObject +} + +func (o *GetServerCapabilitiesResponse) GetFourHundredAndOneApplicationJSONObject() *GetServerCapabilitiesServerResponseBody { + if o == nil { + return nil + } + return o.FourHundredAndOneApplicationJSONObject +} diff --git a/internal/sdk/pkg/models/operations/getserveridentity.go b/internal/sdk/pkg/models/operations/getserveridentity.go new file mode 100644 index 0000000..5746da8 --- /dev/null +++ b/internal/sdk/pkg/models/operations/getserveridentity.go @@ -0,0 +1,141 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package operations + +import ( + "net/http" +) + +type GetServerIdentityErrors struct { + Code *float64 `json:"code,omitempty"` + Message *string `json:"message,omitempty"` + Status *float64 `json:"status,omitempty"` +} + +func (o *GetServerIdentityErrors) GetCode() *float64 { + if o == nil { + return nil + } + return o.Code +} + +func (o *GetServerIdentityErrors) GetMessage() *string { + if o == nil { + return nil + } + return o.Message +} + +func (o *GetServerIdentityErrors) GetStatus() *float64 { + if o == nil { + return nil + } + return o.Status +} + +// GetServerIdentityServerResponseBody - Unauthorized - Returned if the X-Plex-Token is missing from the header or query. +type GetServerIdentityServerResponseBody struct { + Errors []GetServerIdentityErrors `json:"errors,omitempty"` +} + +func (o *GetServerIdentityServerResponseBody) GetErrors() []GetServerIdentityErrors { + if o == nil { + return nil + } + return o.Errors +} + +type GetServerIdentityMediaContainer struct { + Size *float64 `json:"size,omitempty"` + Claimed *bool `json:"claimed,omitempty"` + MachineIdentifier *string `json:"machineIdentifier,omitempty"` + Version *string `json:"version,omitempty"` +} + +func (o *GetServerIdentityMediaContainer) GetSize() *float64 { + if o == nil { + return nil + } + return o.Size +} + +func (o *GetServerIdentityMediaContainer) GetClaimed() *bool { + if o == nil { + return nil + } + return o.Claimed +} + +func (o *GetServerIdentityMediaContainer) GetMachineIdentifier() *string { + if o == nil { + return nil + } + return o.MachineIdentifier +} + +func (o *GetServerIdentityMediaContainer) GetVersion() *string { + if o == nil { + return nil + } + return o.Version +} + +// GetServerIdentityResponseBody - The Transcode Sessions +type GetServerIdentityResponseBody struct { + MediaContainer *GetServerIdentityMediaContainer `json:"MediaContainer,omitempty"` +} + +func (o *GetServerIdentityResponseBody) GetMediaContainer() *GetServerIdentityMediaContainer { + if o == nil { + return nil + } + return o.MediaContainer +} + +type GetServerIdentityResponse struct { + // HTTP response content type for this operation + ContentType string + // HTTP response status code for this operation + StatusCode int + // Raw HTTP response; suitable for custom response parsing + RawResponse *http.Response + // The Transcode Sessions + TwoHundredApplicationJSONObject *GetServerIdentityResponseBody + // Unauthorized - Returned if the X-Plex-Token is missing from the header or query. + FourHundredAndOneApplicationJSONObject *GetServerIdentityServerResponseBody +} + +func (o *GetServerIdentityResponse) GetContentType() string { + if o == nil { + return "" + } + return o.ContentType +} + +func (o *GetServerIdentityResponse) GetStatusCode() int { + if o == nil { + return 0 + } + return o.StatusCode +} + +func (o *GetServerIdentityResponse) GetRawResponse() *http.Response { + if o == nil { + return nil + } + return o.RawResponse +} + +func (o *GetServerIdentityResponse) GetTwoHundredApplicationJSONObject() *GetServerIdentityResponseBody { + if o == nil { + return nil + } + return o.TwoHundredApplicationJSONObject +} + +func (o *GetServerIdentityResponse) GetFourHundredAndOneApplicationJSONObject() *GetServerIdentityServerResponseBody { + if o == nil { + return nil + } + return o.FourHundredAndOneApplicationJSONObject +} diff --git a/internal/sdk/pkg/models/operations/getserverlist.go b/internal/sdk/pkg/models/operations/getserverlist.go new file mode 100644 index 0000000..4a3656a --- /dev/null +++ b/internal/sdk/pkg/models/operations/getserverlist.go @@ -0,0 +1,176 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package operations + +import ( + "net/http" +) + +type GetServerListErrors struct { + Code *float64 `json:"code,omitempty"` + Message *string `json:"message,omitempty"` + Status *float64 `json:"status,omitempty"` +} + +func (o *GetServerListErrors) GetCode() *float64 { + if o == nil { + return nil + } + return o.Code +} + +func (o *GetServerListErrors) GetMessage() *string { + if o == nil { + return nil + } + return o.Message +} + +func (o *GetServerListErrors) GetStatus() *float64 { + if o == nil { + return nil + } + return o.Status +} + +// GetServerListServerResponseBody - Unauthorized - Returned if the X-Plex-Token is missing from the header or query. +type GetServerListServerResponseBody struct { + Errors []GetServerListErrors `json:"errors,omitempty"` +} + +func (o *GetServerListServerResponseBody) GetErrors() []GetServerListErrors { + if o == nil { + return nil + } + return o.Errors +} + +type GetServerListServer struct { + Name *string `json:"name,omitempty"` + Host *string `json:"host,omitempty"` + Address *string `json:"address,omitempty"` + Port *float64 `json:"port,omitempty"` + MachineIdentifier *string `json:"machineIdentifier,omitempty"` + Version *string `json:"version,omitempty"` +} + +func (o *GetServerListServer) GetName() *string { + if o == nil { + return nil + } + return o.Name +} + +func (o *GetServerListServer) GetHost() *string { + if o == nil { + return nil + } + return o.Host +} + +func (o *GetServerListServer) GetAddress() *string { + if o == nil { + return nil + } + return o.Address +} + +func (o *GetServerListServer) GetPort() *float64 { + if o == nil { + return nil + } + return o.Port +} + +func (o *GetServerListServer) GetMachineIdentifier() *string { + if o == nil { + return nil + } + return o.MachineIdentifier +} + +func (o *GetServerListServer) GetVersion() *string { + if o == nil { + return nil + } + return o.Version +} + +type GetServerListMediaContainer struct { + Size *float64 `json:"size,omitempty"` + Server []GetServerListServer `json:"Server,omitempty"` +} + +func (o *GetServerListMediaContainer) GetSize() *float64 { + if o == nil { + return nil + } + return o.Size +} + +func (o *GetServerListMediaContainer) GetServer() []GetServerListServer { + if o == nil { + return nil + } + return o.Server +} + +// GetServerListResponseBody - List of Servers +type GetServerListResponseBody struct { + MediaContainer *GetServerListMediaContainer `json:"MediaContainer,omitempty"` +} + +func (o *GetServerListResponseBody) GetMediaContainer() *GetServerListMediaContainer { + if o == nil { + return nil + } + return o.MediaContainer +} + +type GetServerListResponse struct { + // HTTP response content type for this operation + ContentType string + // HTTP response status code for this operation + StatusCode int + // Raw HTTP response; suitable for custom response parsing + RawResponse *http.Response + // List of Servers + TwoHundredApplicationJSONObject *GetServerListResponseBody + // Unauthorized - Returned if the X-Plex-Token is missing from the header or query. + FourHundredAndOneApplicationJSONObject *GetServerListServerResponseBody +} + +func (o *GetServerListResponse) GetContentType() string { + if o == nil { + return "" + } + return o.ContentType +} + +func (o *GetServerListResponse) GetStatusCode() int { + if o == nil { + return 0 + } + return o.StatusCode +} + +func (o *GetServerListResponse) GetRawResponse() *http.Response { + if o == nil { + return nil + } + return o.RawResponse +} + +func (o *GetServerListResponse) GetTwoHundredApplicationJSONObject() *GetServerListResponseBody { + if o == nil { + return nil + } + return o.TwoHundredApplicationJSONObject +} + +func (o *GetServerListResponse) GetFourHundredAndOneApplicationJSONObject() *GetServerListServerResponseBody { + if o == nil { + return nil + } + return o.FourHundredAndOneApplicationJSONObject +} diff --git a/internal/sdk/pkg/models/operations/getserverpreferences.go b/internal/sdk/pkg/models/operations/getserverpreferences.go new file mode 100644 index 0000000..53fd480 --- /dev/null +++ b/internal/sdk/pkg/models/operations/getserverpreferences.go @@ -0,0 +1,85 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package operations + +import ( + "net/http" +) + +type GetServerPreferencesErrors struct { + Code *float64 `json:"code,omitempty"` + Message *string `json:"message,omitempty"` + Status *float64 `json:"status,omitempty"` +} + +func (o *GetServerPreferencesErrors) GetCode() *float64 { + if o == nil { + return nil + } + return o.Code +} + +func (o *GetServerPreferencesErrors) GetMessage() *string { + if o == nil { + return nil + } + return o.Message +} + +func (o *GetServerPreferencesErrors) GetStatus() *float64 { + if o == nil { + return nil + } + return o.Status +} + +// GetServerPreferencesResponseBody - Unauthorized - Returned if the X-Plex-Token is missing from the header or query. +type GetServerPreferencesResponseBody struct { + Errors []GetServerPreferencesErrors `json:"errors,omitempty"` +} + +func (o *GetServerPreferencesResponseBody) GetErrors() []GetServerPreferencesErrors { + if o == nil { + return nil + } + return o.Errors +} + +type GetServerPreferencesResponse struct { + // HTTP response content type for this operation + ContentType string + // HTTP response status code for this operation + StatusCode int + // Raw HTTP response; suitable for custom response parsing + RawResponse *http.Response + // Unauthorized - Returned if the X-Plex-Token is missing from the header or query. + Object *GetServerPreferencesResponseBody +} + +func (o *GetServerPreferencesResponse) GetContentType() string { + if o == nil { + return "" + } + return o.ContentType +} + +func (o *GetServerPreferencesResponse) GetStatusCode() int { + if o == nil { + return 0 + } + return o.StatusCode +} + +func (o *GetServerPreferencesResponse) GetRawResponse() *http.Response { + if o == nil { + return nil + } + return o.RawResponse +} + +func (o *GetServerPreferencesResponse) GetObject() *GetServerPreferencesResponseBody { + if o == nil { + return nil + } + return o.Object +} diff --git a/internal/sdk/pkg/models/operations/getsessionhistory.go b/internal/sdk/pkg/models/operations/getsessionhistory.go new file mode 100644 index 0000000..cbcf268 --- /dev/null +++ b/internal/sdk/pkg/models/operations/getsessionhistory.go @@ -0,0 +1,85 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package operations + +import ( + "net/http" +) + +type GetSessionHistoryErrors struct { + Code *float64 `json:"code,omitempty"` + Message *string `json:"message,omitempty"` + Status *float64 `json:"status,omitempty"` +} + +func (o *GetSessionHistoryErrors) GetCode() *float64 { + if o == nil { + return nil + } + return o.Code +} + +func (o *GetSessionHistoryErrors) GetMessage() *string { + if o == nil { + return nil + } + return o.Message +} + +func (o *GetSessionHistoryErrors) GetStatus() *float64 { + if o == nil { + return nil + } + return o.Status +} + +// GetSessionHistoryResponseBody - Unauthorized - Returned if the X-Plex-Token is missing from the header or query. +type GetSessionHistoryResponseBody struct { + Errors []GetSessionHistoryErrors `json:"errors,omitempty"` +} + +func (o *GetSessionHistoryResponseBody) GetErrors() []GetSessionHistoryErrors { + if o == nil { + return nil + } + return o.Errors +} + +type GetSessionHistoryResponse struct { + // HTTP response content type for this operation + ContentType string + // HTTP response status code for this operation + StatusCode int + // Raw HTTP response; suitable for custom response parsing + RawResponse *http.Response + // Unauthorized - Returned if the X-Plex-Token is missing from the header or query. + Object *GetSessionHistoryResponseBody +} + +func (o *GetSessionHistoryResponse) GetContentType() string { + if o == nil { + return "" + } + return o.ContentType +} + +func (o *GetSessionHistoryResponse) GetStatusCode() int { + if o == nil { + return 0 + } + return o.StatusCode +} + +func (o *GetSessionHistoryResponse) GetRawResponse() *http.Response { + if o == nil { + return nil + } + return o.RawResponse +} + +func (o *GetSessionHistoryResponse) GetObject() *GetSessionHistoryResponseBody { + if o == nil { + return nil + } + return o.Object +} diff --git a/internal/sdk/pkg/models/operations/getsessions.go b/internal/sdk/pkg/models/operations/getsessions.go new file mode 100644 index 0000000..90fa0b6 --- /dev/null +++ b/internal/sdk/pkg/models/operations/getsessions.go @@ -0,0 +1,85 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package operations + +import ( + "net/http" +) + +type GetSessionsErrors struct { + Code *float64 `json:"code,omitempty"` + Message *string `json:"message,omitempty"` + Status *float64 `json:"status,omitempty"` +} + +func (o *GetSessionsErrors) GetCode() *float64 { + if o == nil { + return nil + } + return o.Code +} + +func (o *GetSessionsErrors) GetMessage() *string { + if o == nil { + return nil + } + return o.Message +} + +func (o *GetSessionsErrors) GetStatus() *float64 { + if o == nil { + return nil + } + return o.Status +} + +// GetSessionsResponseBody - Unauthorized - Returned if the X-Plex-Token is missing from the header or query. +type GetSessionsResponseBody struct { + Errors []GetSessionsErrors `json:"errors,omitempty"` +} + +func (o *GetSessionsResponseBody) GetErrors() []GetSessionsErrors { + if o == nil { + return nil + } + return o.Errors +} + +type GetSessionsResponse struct { + // HTTP response content type for this operation + ContentType string + // HTTP response status code for this operation + StatusCode int + // Raw HTTP response; suitable for custom response parsing + RawResponse *http.Response + // Unauthorized - Returned if the X-Plex-Token is missing from the header or query. + Object *GetSessionsResponseBody +} + +func (o *GetSessionsResponse) GetContentType() string { + if o == nil { + return "" + } + return o.ContentType +} + +func (o *GetSessionsResponse) GetStatusCode() int { + if o == nil { + return 0 + } + return o.StatusCode +} + +func (o *GetSessionsResponse) GetRawResponse() *http.Response { + if o == nil { + return nil + } + return o.RawResponse +} + +func (o *GetSessionsResponse) GetObject() *GetSessionsResponseBody { + if o == nil { + return nil + } + return o.Object +} diff --git a/internal/sdk/pkg/models/operations/getsourceconnectioninformation.go b/internal/sdk/pkg/models/operations/getsourceconnectioninformation.go new file mode 100644 index 0000000..3be97e7 --- /dev/null +++ b/internal/sdk/pkg/models/operations/getsourceconnectioninformation.go @@ -0,0 +1,97 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package operations + +import ( + "net/http" +) + +type GetSourceConnectionInformationRequest struct { + // The source identifier with an included prefix. + Source string `queryParam:"style=form,explode=true,name=source"` +} + +func (o *GetSourceConnectionInformationRequest) GetSource() string { + if o == nil { + return "" + } + return o.Source +} + +type GetSourceConnectionInformationErrors struct { + Code *float64 `json:"code,omitempty"` + Message *string `json:"message,omitempty"` + Status *float64 `json:"status,omitempty"` +} + +func (o *GetSourceConnectionInformationErrors) GetCode() *float64 { + if o == nil { + return nil + } + return o.Code +} + +func (o *GetSourceConnectionInformationErrors) GetMessage() *string { + if o == nil { + return nil + } + return o.Message +} + +func (o *GetSourceConnectionInformationErrors) GetStatus() *float64 { + if o == nil { + return nil + } + return o.Status +} + +// GetSourceConnectionInformationResponseBody - Unauthorized - Returned if the X-Plex-Token is missing from the header or query. +type GetSourceConnectionInformationResponseBody struct { + Errors []GetSourceConnectionInformationErrors `json:"errors,omitempty"` +} + +func (o *GetSourceConnectionInformationResponseBody) GetErrors() []GetSourceConnectionInformationErrors { + if o == nil { + return nil + } + return o.Errors +} + +type GetSourceConnectionInformationResponse struct { + // HTTP response content type for this operation + ContentType string + // HTTP response status code for this operation + StatusCode int + // Raw HTTP response; suitable for custom response parsing + RawResponse *http.Response + // Unauthorized - Returned if the X-Plex-Token is missing from the header or query. + Object *GetSourceConnectionInformationResponseBody +} + +func (o *GetSourceConnectionInformationResponse) GetContentType() string { + if o == nil { + return "" + } + return o.ContentType +} + +func (o *GetSourceConnectionInformationResponse) GetStatusCode() int { + if o == nil { + return 0 + } + return o.StatusCode +} + +func (o *GetSourceConnectionInformationResponse) GetRawResponse() *http.Response { + if o == nil { + return nil + } + return o.RawResponse +} + +func (o *GetSourceConnectionInformationResponse) GetObject() *GetSourceConnectionInformationResponseBody { + if o == nil { + return nil + } + return o.Object +} diff --git a/internal/sdk/pkg/models/operations/gettimeline.go b/internal/sdk/pkg/models/operations/gettimeline.go new file mode 100644 index 0000000..5d55e5f --- /dev/null +++ b/internal/sdk/pkg/models/operations/gettimeline.go @@ -0,0 +1,211 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package operations + +import ( + "encoding/json" + "fmt" + "net/http" +) + +// State - The state of the media item +type State string + +const ( + StatePlaying State = "playing" + StatePaused State = "paused" + StateStopped State = "stopped" +) + +func (e State) ToPointer() *State { + return &e +} + +func (e *State) UnmarshalJSON(data []byte) error { + var v string + if err := json.Unmarshal(data, &v); err != nil { + return err + } + switch v { + case "playing": + fallthrough + case "paused": + fallthrough + case "stopped": + *e = State(v) + return nil + default: + return fmt.Errorf("invalid value for State: %v", v) + } +} + +type GetTimelineRequest struct { + // The rating key of the media item + RatingKey float64 `queryParam:"style=form,explode=true,name=ratingKey"` + // The key of the media item to get the timeline for + Key string `queryParam:"style=form,explode=true,name=key"` + // The state of the media item + State State `queryParam:"style=form,explode=true,name=state"` + // Whether the media item has MDE + HasMDE float64 `queryParam:"style=form,explode=true,name=hasMDE"` + // The time of the media item + Time float64 `queryParam:"style=form,explode=true,name=time"` + // The duration of the media item + Duration float64 `queryParam:"style=form,explode=true,name=duration"` + // The context of the media item + Context string `queryParam:"style=form,explode=true,name=context"` + // The play queue item ID of the media item + PlayQueueItemID float64 `queryParam:"style=form,explode=true,name=playQueueItemID"` + // The playback time of the media item + PlayBackTime float64 `queryParam:"style=form,explode=true,name=playBackTime"` + // The row of the media item + Row float64 `queryParam:"style=form,explode=true,name=row"` +} + +func (o *GetTimelineRequest) GetRatingKey() float64 { + if o == nil { + return 0.0 + } + return o.RatingKey +} + +func (o *GetTimelineRequest) GetKey() string { + if o == nil { + return "" + } + return o.Key +} + +func (o *GetTimelineRequest) GetState() State { + if o == nil { + return State("") + } + return o.State +} + +func (o *GetTimelineRequest) GetHasMDE() float64 { + if o == nil { + return 0.0 + } + return o.HasMDE +} + +func (o *GetTimelineRequest) GetTime() float64 { + if o == nil { + return 0.0 + } + return o.Time +} + +func (o *GetTimelineRequest) GetDuration() float64 { + if o == nil { + return 0.0 + } + return o.Duration +} + +func (o *GetTimelineRequest) GetContext() string { + if o == nil { + return "" + } + return o.Context +} + +func (o *GetTimelineRequest) GetPlayQueueItemID() float64 { + if o == nil { + return 0.0 + } + return o.PlayQueueItemID +} + +func (o *GetTimelineRequest) GetPlayBackTime() float64 { + if o == nil { + return 0.0 + } + return o.PlayBackTime +} + +func (o *GetTimelineRequest) GetRow() float64 { + if o == nil { + return 0.0 + } + return o.Row +} + +type GetTimelineErrors struct { + Code *float64 `json:"code,omitempty"` + Message *string `json:"message,omitempty"` + Status *float64 `json:"status,omitempty"` +} + +func (o *GetTimelineErrors) GetCode() *float64 { + if o == nil { + return nil + } + return o.Code +} + +func (o *GetTimelineErrors) GetMessage() *string { + if o == nil { + return nil + } + return o.Message +} + +func (o *GetTimelineErrors) GetStatus() *float64 { + if o == nil { + return nil + } + return o.Status +} + +// GetTimelineResponseBody - Unauthorized - Returned if the X-Plex-Token is missing from the header or query. +type GetTimelineResponseBody struct { + Errors []GetTimelineErrors `json:"errors,omitempty"` +} + +func (o *GetTimelineResponseBody) GetErrors() []GetTimelineErrors { + if o == nil { + return nil + } + return o.Errors +} + +type GetTimelineResponse struct { + // HTTP response content type for this operation + ContentType string + // HTTP response status code for this operation + StatusCode int + // Raw HTTP response; suitable for custom response parsing + RawResponse *http.Response + // Unauthorized - Returned if the X-Plex-Token is missing from the header or query. + Object *GetTimelineResponseBody +} + +func (o *GetTimelineResponse) GetContentType() string { + if o == nil { + return "" + } + return o.ContentType +} + +func (o *GetTimelineResponse) GetStatusCode() int { + if o == nil { + return 0 + } + return o.StatusCode +} + +func (o *GetTimelineResponse) GetRawResponse() *http.Response { + if o == nil { + return nil + } + return o.RawResponse +} + +func (o *GetTimelineResponse) GetObject() *GetTimelineResponseBody { + if o == nil { + return nil + } + return o.Object +} diff --git a/internal/sdk/pkg/models/operations/gettranscodesessions.go b/internal/sdk/pkg/models/operations/gettranscodesessions.go new file mode 100644 index 0000000..8898974 --- /dev/null +++ b/internal/sdk/pkg/models/operations/gettranscodesessions.go @@ -0,0 +1,304 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package operations + +import ( + "net/http" +) + +type GetTranscodeSessionsErrors struct { + Code *float64 `json:"code,omitempty"` + Message *string `json:"message,omitempty"` + Status *float64 `json:"status,omitempty"` +} + +func (o *GetTranscodeSessionsErrors) GetCode() *float64 { + if o == nil { + return nil + } + return o.Code +} + +func (o *GetTranscodeSessionsErrors) GetMessage() *string { + if o == nil { + return nil + } + return o.Message +} + +func (o *GetTranscodeSessionsErrors) GetStatus() *float64 { + if o == nil { + return nil + } + return o.Status +} + +// GetTranscodeSessionsSessionsResponseBody - Unauthorized - Returned if the X-Plex-Token is missing from the header or query. +type GetTranscodeSessionsSessionsResponseBody struct { + Errors []GetTranscodeSessionsErrors `json:"errors,omitempty"` +} + +func (o *GetTranscodeSessionsSessionsResponseBody) GetErrors() []GetTranscodeSessionsErrors { + if o == nil { + return nil + } + return o.Errors +} + +type TranscodeSession struct { + Key *string `json:"key,omitempty"` + Throttled *bool `json:"throttled,omitempty"` + Complete *bool `json:"complete,omitempty"` + Progress *float64 `json:"progress,omitempty"` + Size *float64 `json:"size,omitempty"` + Speed *float64 `json:"speed,omitempty"` + Error *bool `json:"error,omitempty"` + Duration *float64 `json:"duration,omitempty"` + Context *string `json:"context,omitempty"` + SourceVideoCodec *string `json:"sourceVideoCodec,omitempty"` + SourceAudioCodec *string `json:"sourceAudioCodec,omitempty"` + VideoDecision *string `json:"videoDecision,omitempty"` + AudioDecision *string `json:"audioDecision,omitempty"` + Protocol *string `json:"protocol,omitempty"` + Container *string `json:"container,omitempty"` + VideoCodec *string `json:"videoCodec,omitempty"` + AudioCodec *string `json:"audioCodec,omitempty"` + AudioChannels *float64 `json:"audioChannels,omitempty"` + TranscodeHwRequested *bool `json:"transcodeHwRequested,omitempty"` + TimeStamp *float64 `json:"timeStamp,omitempty"` + MaxOffsetAvailable *float64 `json:"maxOffsetAvailable,omitempty"` + MinOffsetAvailable *float64 `json:"minOffsetAvailable,omitempty"` +} + +func (o *TranscodeSession) GetKey() *string { + if o == nil { + return nil + } + return o.Key +} + +func (o *TranscodeSession) GetThrottled() *bool { + if o == nil { + return nil + } + return o.Throttled +} + +func (o *TranscodeSession) GetComplete() *bool { + if o == nil { + return nil + } + return o.Complete +} + +func (o *TranscodeSession) GetProgress() *float64 { + if o == nil { + return nil + } + return o.Progress +} + +func (o *TranscodeSession) GetSize() *float64 { + if o == nil { + return nil + } + return o.Size +} + +func (o *TranscodeSession) GetSpeed() *float64 { + if o == nil { + return nil + } + return o.Speed +} + +func (o *TranscodeSession) GetError() *bool { + if o == nil { + return nil + } + return o.Error +} + +func (o *TranscodeSession) GetDuration() *float64 { + if o == nil { + return nil + } + return o.Duration +} + +func (o *TranscodeSession) GetContext() *string { + if o == nil { + return nil + } + return o.Context +} + +func (o *TranscodeSession) GetSourceVideoCodec() *string { + if o == nil { + return nil + } + return o.SourceVideoCodec +} + +func (o *TranscodeSession) GetSourceAudioCodec() *string { + if o == nil { + return nil + } + return o.SourceAudioCodec +} + +func (o *TranscodeSession) GetVideoDecision() *string { + if o == nil { + return nil + } + return o.VideoDecision +} + +func (o *TranscodeSession) GetAudioDecision() *string { + if o == nil { + return nil + } + return o.AudioDecision +} + +func (o *TranscodeSession) GetProtocol() *string { + if o == nil { + return nil + } + return o.Protocol +} + +func (o *TranscodeSession) GetContainer() *string { + if o == nil { + return nil + } + return o.Container +} + +func (o *TranscodeSession) GetVideoCodec() *string { + if o == nil { + return nil + } + return o.VideoCodec +} + +func (o *TranscodeSession) GetAudioCodec() *string { + if o == nil { + return nil + } + return o.AudioCodec +} + +func (o *TranscodeSession) GetAudioChannels() *float64 { + if o == nil { + return nil + } + return o.AudioChannels +} + +func (o *TranscodeSession) GetTranscodeHwRequested() *bool { + if o == nil { + return nil + } + return o.TranscodeHwRequested +} + +func (o *TranscodeSession) GetTimeStamp() *float64 { + if o == nil { + return nil + } + return o.TimeStamp +} + +func (o *TranscodeSession) GetMaxOffsetAvailable() *float64 { + if o == nil { + return nil + } + return o.MaxOffsetAvailable +} + +func (o *TranscodeSession) GetMinOffsetAvailable() *float64 { + if o == nil { + return nil + } + return o.MinOffsetAvailable +} + +type GetTranscodeSessionsMediaContainer struct { + Size *float64 `json:"size,omitempty"` + TranscodeSession []TranscodeSession `json:"TranscodeSession,omitempty"` +} + +func (o *GetTranscodeSessionsMediaContainer) GetSize() *float64 { + if o == nil { + return nil + } + return o.Size +} + +func (o *GetTranscodeSessionsMediaContainer) GetTranscodeSession() []TranscodeSession { + if o == nil { + return nil + } + return o.TranscodeSession +} + +// GetTranscodeSessionsResponseBody - The Transcode Sessions +type GetTranscodeSessionsResponseBody struct { + MediaContainer *GetTranscodeSessionsMediaContainer `json:"MediaContainer,omitempty"` +} + +func (o *GetTranscodeSessionsResponseBody) GetMediaContainer() *GetTranscodeSessionsMediaContainer { + if o == nil { + return nil + } + return o.MediaContainer +} + +type GetTranscodeSessionsResponse struct { + // HTTP response content type for this operation + ContentType string + // HTTP response status code for this operation + StatusCode int + // Raw HTTP response; suitable for custom response parsing + RawResponse *http.Response + // The Transcode Sessions + TwoHundredApplicationJSONObject *GetTranscodeSessionsResponseBody + // Unauthorized - Returned if the X-Plex-Token is missing from the header or query. + FourHundredAndOneApplicationJSONObject *GetTranscodeSessionsSessionsResponseBody +} + +func (o *GetTranscodeSessionsResponse) GetContentType() string { + if o == nil { + return "" + } + return o.ContentType +} + +func (o *GetTranscodeSessionsResponse) GetStatusCode() int { + if o == nil { + return 0 + } + return o.StatusCode +} + +func (o *GetTranscodeSessionsResponse) GetRawResponse() *http.Response { + if o == nil { + return nil + } + return o.RawResponse +} + +func (o *GetTranscodeSessionsResponse) GetTwoHundredApplicationJSONObject() *GetTranscodeSessionsResponseBody { + if o == nil { + return nil + } + return o.TwoHundredApplicationJSONObject +} + +func (o *GetTranscodeSessionsResponse) GetFourHundredAndOneApplicationJSONObject() *GetTranscodeSessionsSessionsResponseBody { + if o == nil { + return nil + } + return o.FourHundredAndOneApplicationJSONObject +} diff --git a/internal/sdk/pkg/models/operations/gettransienttoken.go b/internal/sdk/pkg/models/operations/gettransienttoken.go new file mode 100644 index 0000000..b033f80 --- /dev/null +++ b/internal/sdk/pkg/models/operations/gettransienttoken.go @@ -0,0 +1,158 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package operations + +import ( + "encoding/json" + "fmt" + "net/http" +) + +// QueryParamType - `delegation` - This is the only supported `type` parameter. +type QueryParamType string + +const ( + QueryParamTypeDelegation QueryParamType = "delegation" +) + +func (e QueryParamType) ToPointer() *QueryParamType { + return &e +} + +func (e *QueryParamType) UnmarshalJSON(data []byte) error { + var v string + if err := json.Unmarshal(data, &v); err != nil { + return err + } + switch v { + case "delegation": + *e = QueryParamType(v) + return nil + default: + return fmt.Errorf("invalid value for QueryParamType: %v", v) + } +} + +// Scope - `all` - This is the only supported `scope` parameter. +type Scope string + +const ( + ScopeAll Scope = "all" +) + +func (e Scope) ToPointer() *Scope { + return &e +} + +func (e *Scope) UnmarshalJSON(data []byte) error { + var v string + if err := json.Unmarshal(data, &v); err != nil { + return err + } + switch v { + case "all": + *e = Scope(v) + return nil + default: + return fmt.Errorf("invalid value for Scope: %v", v) + } +} + +type GetTransientTokenRequest struct { + // `delegation` - This is the only supported `type` parameter. + Type QueryParamType `queryParam:"style=form,explode=true,name=type"` + // `all` - This is the only supported `scope` parameter. + Scope Scope `queryParam:"style=form,explode=true,name=scope"` +} + +func (o *GetTransientTokenRequest) GetType() QueryParamType { + if o == nil { + return QueryParamType("") + } + return o.Type +} + +func (o *GetTransientTokenRequest) GetScope() Scope { + if o == nil { + return Scope("") + } + return o.Scope +} + +type GetTransientTokenErrors struct { + Code *float64 `json:"code,omitempty"` + Message *string `json:"message,omitempty"` + Status *float64 `json:"status,omitempty"` +} + +func (o *GetTransientTokenErrors) GetCode() *float64 { + if o == nil { + return nil + } + return o.Code +} + +func (o *GetTransientTokenErrors) GetMessage() *string { + if o == nil { + return nil + } + return o.Message +} + +func (o *GetTransientTokenErrors) GetStatus() *float64 { + if o == nil { + return nil + } + return o.Status +} + +// GetTransientTokenResponseBody - Unauthorized - Returned if the X-Plex-Token is missing from the header or query. +type GetTransientTokenResponseBody struct { + Errors []GetTransientTokenErrors `json:"errors,omitempty"` +} + +func (o *GetTransientTokenResponseBody) GetErrors() []GetTransientTokenErrors { + if o == nil { + return nil + } + return o.Errors +} + +type GetTransientTokenResponse struct { + // HTTP response content type for this operation + ContentType string + // HTTP response status code for this operation + StatusCode int + // Raw HTTP response; suitable for custom response parsing + RawResponse *http.Response + // Unauthorized - Returned if the X-Plex-Token is missing from the header or query. + Object *GetTransientTokenResponseBody +} + +func (o *GetTransientTokenResponse) GetContentType() string { + if o == nil { + return "" + } + return o.ContentType +} + +func (o *GetTransientTokenResponse) GetStatusCode() int { + if o == nil { + return 0 + } + return o.StatusCode +} + +func (o *GetTransientTokenResponse) GetRawResponse() *http.Response { + if o == nil { + return nil + } + return o.RawResponse +} + +func (o *GetTransientTokenResponse) GetObject() *GetTransientTokenResponseBody { + if o == nil { + return nil + } + return o.Object +} diff --git a/internal/sdk/pkg/models/operations/getupdatestatus.go b/internal/sdk/pkg/models/operations/getupdatestatus.go new file mode 100644 index 0000000..455dd47 --- /dev/null +++ b/internal/sdk/pkg/models/operations/getupdatestatus.go @@ -0,0 +1,85 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package operations + +import ( + "net/http" +) + +type GetUpdateStatusErrors struct { + Code *float64 `json:"code,omitempty"` + Message *string `json:"message,omitempty"` + Status *float64 `json:"status,omitempty"` +} + +func (o *GetUpdateStatusErrors) GetCode() *float64 { + if o == nil { + return nil + } + return o.Code +} + +func (o *GetUpdateStatusErrors) GetMessage() *string { + if o == nil { + return nil + } + return o.Message +} + +func (o *GetUpdateStatusErrors) GetStatus() *float64 { + if o == nil { + return nil + } + return o.Status +} + +// GetUpdateStatusResponseBody - Unauthorized - Returned if the X-Plex-Token is missing from the header or query. +type GetUpdateStatusResponseBody struct { + Errors []GetUpdateStatusErrors `json:"errors,omitempty"` +} + +func (o *GetUpdateStatusResponseBody) GetErrors() []GetUpdateStatusErrors { + if o == nil { + return nil + } + return o.Errors +} + +type GetUpdateStatusResponse struct { + // HTTP response content type for this operation + ContentType string + // HTTP response status code for this operation + StatusCode int + // Raw HTTP response; suitable for custom response parsing + RawResponse *http.Response + // Unauthorized - Returned if the X-Plex-Token is missing from the header or query. + Object *GetUpdateStatusResponseBody +} + +func (o *GetUpdateStatusResponse) GetContentType() string { + if o == nil { + return "" + } + return o.ContentType +} + +func (o *GetUpdateStatusResponse) GetStatusCode() int { + if o == nil { + return 0 + } + return o.StatusCode +} + +func (o *GetUpdateStatusResponse) GetRawResponse() *http.Response { + if o == nil { + return nil + } + return o.RawResponse +} + +func (o *GetUpdateStatusResponse) GetObject() *GetUpdateStatusResponseBody { + if o == nil { + return nil + } + return o.Object +} diff --git a/internal/sdk/pkg/models/operations/logline.go b/internal/sdk/pkg/models/operations/logline.go new file mode 100644 index 0000000..a0b1ef5 --- /dev/null +++ b/internal/sdk/pkg/models/operations/logline.go @@ -0,0 +1,165 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package operations + +import ( + "encoding/json" + "fmt" + "net/http" +) + +// Level - An integer log level to write to the PMS log with. +// 0: Error +// 1: Warning +// 2: Info +// 3: Debug +// 4: Verbose +type Level int64 + +const ( + LevelZero Level = 0 + LevelOne Level = 1 + LevelTwo Level = 2 + LevelThree Level = 3 + LevelFour Level = 4 +) + +func (e Level) ToPointer() *Level { + return &e +} + +func (e *Level) UnmarshalJSON(data []byte) error { + var v int64 + if err := json.Unmarshal(data, &v); err != nil { + return err + } + switch v { + case 0: + fallthrough + case 1: + fallthrough + case 2: + fallthrough + case 3: + fallthrough + case 4: + *e = Level(v) + return nil + default: + return fmt.Errorf("invalid value for Level: %v", v) + } +} + +type LogLineRequest struct { + // An integer log level to write to the PMS log with. + // 0: Error + // 1: Warning + // 2: Info + // 3: Debug + // 4: Verbose + // + Level Level `queryParam:"style=form,explode=true,name=level"` + // The text of the message to write to the log. + Message string `queryParam:"style=form,explode=true,name=message"` + // a string indicating the source of the message. + Source string `queryParam:"style=form,explode=true,name=source"` +} + +func (o *LogLineRequest) GetLevel() Level { + if o == nil { + return Level(0) + } + return o.Level +} + +func (o *LogLineRequest) GetMessage() string { + if o == nil { + return "" + } + return o.Message +} + +func (o *LogLineRequest) GetSource() string { + if o == nil { + return "" + } + return o.Source +} + +type LogLineErrors struct { + Code *float64 `json:"code,omitempty"` + Message *string `json:"message,omitempty"` + Status *float64 `json:"status,omitempty"` +} + +func (o *LogLineErrors) GetCode() *float64 { + if o == nil { + return nil + } + return o.Code +} + +func (o *LogLineErrors) GetMessage() *string { + if o == nil { + return nil + } + return o.Message +} + +func (o *LogLineErrors) GetStatus() *float64 { + if o == nil { + return nil + } + return o.Status +} + +// LogLineResponseBody - Unauthorized - Returned if the X-Plex-Token is missing from the header or query. +type LogLineResponseBody struct { + Errors []LogLineErrors `json:"errors,omitempty"` +} + +func (o *LogLineResponseBody) GetErrors() []LogLineErrors { + if o == nil { + return nil + } + return o.Errors +} + +type LogLineResponse struct { + // HTTP response content type for this operation + ContentType string + // HTTP response status code for this operation + StatusCode int + // Raw HTTP response; suitable for custom response parsing + RawResponse *http.Response + // Unauthorized - Returned if the X-Plex-Token is missing from the header or query. + Object *LogLineResponseBody +} + +func (o *LogLineResponse) GetContentType() string { + if o == nil { + return "" + } + return o.ContentType +} + +func (o *LogLineResponse) GetStatusCode() int { + if o == nil { + return 0 + } + return o.StatusCode +} + +func (o *LogLineResponse) GetRawResponse() *http.Response { + if o == nil { + return nil + } + return o.RawResponse +} + +func (o *LogLineResponse) GetObject() *LogLineResponseBody { + if o == nil { + return nil + } + return o.Object +} diff --git a/internal/sdk/pkg/models/operations/logmultiline.go b/internal/sdk/pkg/models/operations/logmultiline.go new file mode 100644 index 0000000..b66ffef --- /dev/null +++ b/internal/sdk/pkg/models/operations/logmultiline.go @@ -0,0 +1,85 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package operations + +import ( + "net/http" +) + +type LogMultiLineErrors struct { + Code *float64 `json:"code,omitempty"` + Message *string `json:"message,omitempty"` + Status *float64 `json:"status,omitempty"` +} + +func (o *LogMultiLineErrors) GetCode() *float64 { + if o == nil { + return nil + } + return o.Code +} + +func (o *LogMultiLineErrors) GetMessage() *string { + if o == nil { + return nil + } + return o.Message +} + +func (o *LogMultiLineErrors) GetStatus() *float64 { + if o == nil { + return nil + } + return o.Status +} + +// LogMultiLineResponseBody - Unauthorized - Returned if the X-Plex-Token is missing from the header or query. +type LogMultiLineResponseBody struct { + Errors []LogMultiLineErrors `json:"errors,omitempty"` +} + +func (o *LogMultiLineResponseBody) GetErrors() []LogMultiLineErrors { + if o == nil { + return nil + } + return o.Errors +} + +type LogMultiLineResponse struct { + // HTTP response content type for this operation + ContentType string + // HTTP response status code for this operation + StatusCode int + // Raw HTTP response; suitable for custom response parsing + RawResponse *http.Response + // Unauthorized - Returned if the X-Plex-Token is missing from the header or query. + Object *LogMultiLineResponseBody +} + +func (o *LogMultiLineResponse) GetContentType() string { + if o == nil { + return "" + } + return o.ContentType +} + +func (o *LogMultiLineResponse) GetStatusCode() int { + if o == nil { + return 0 + } + return o.StatusCode +} + +func (o *LogMultiLineResponse) GetRawResponse() *http.Response { + if o == nil { + return nil + } + return o.RawResponse +} + +func (o *LogMultiLineResponse) GetObject() *LogMultiLineResponseBody { + if o == nil { + return nil + } + return o.Object +} diff --git a/internal/sdk/pkg/models/operations/markplayed.go b/internal/sdk/pkg/models/operations/markplayed.go new file mode 100644 index 0000000..298208e --- /dev/null +++ b/internal/sdk/pkg/models/operations/markplayed.go @@ -0,0 +1,97 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package operations + +import ( + "net/http" +) + +type MarkPlayedRequest struct { + // The media key to mark as played + Key float64 `queryParam:"style=form,explode=true,name=key"` +} + +func (o *MarkPlayedRequest) GetKey() float64 { + if o == nil { + return 0.0 + } + return o.Key +} + +type MarkPlayedErrors struct { + Code *float64 `json:"code,omitempty"` + Message *string `json:"message,omitempty"` + Status *float64 `json:"status,omitempty"` +} + +func (o *MarkPlayedErrors) GetCode() *float64 { + if o == nil { + return nil + } + return o.Code +} + +func (o *MarkPlayedErrors) GetMessage() *string { + if o == nil { + return nil + } + return o.Message +} + +func (o *MarkPlayedErrors) GetStatus() *float64 { + if o == nil { + return nil + } + return o.Status +} + +// MarkPlayedResponseBody - Unauthorized - Returned if the X-Plex-Token is missing from the header or query. +type MarkPlayedResponseBody struct { + Errors []MarkPlayedErrors `json:"errors,omitempty"` +} + +func (o *MarkPlayedResponseBody) GetErrors() []MarkPlayedErrors { + if o == nil { + return nil + } + return o.Errors +} + +type MarkPlayedResponse struct { + // HTTP response content type for this operation + ContentType string + // HTTP response status code for this operation + StatusCode int + // Raw HTTP response; suitable for custom response parsing + RawResponse *http.Response + // Unauthorized - Returned if the X-Plex-Token is missing from the header or query. + Object *MarkPlayedResponseBody +} + +func (o *MarkPlayedResponse) GetContentType() string { + if o == nil { + return "" + } + return o.ContentType +} + +func (o *MarkPlayedResponse) GetStatusCode() int { + if o == nil { + return 0 + } + return o.StatusCode +} + +func (o *MarkPlayedResponse) GetRawResponse() *http.Response { + if o == nil { + return nil + } + return o.RawResponse +} + +func (o *MarkPlayedResponse) GetObject() *MarkPlayedResponseBody { + if o == nil { + return nil + } + return o.Object +} diff --git a/internal/sdk/pkg/models/operations/markunplayed.go b/internal/sdk/pkg/models/operations/markunplayed.go new file mode 100644 index 0000000..f247bbb --- /dev/null +++ b/internal/sdk/pkg/models/operations/markunplayed.go @@ -0,0 +1,97 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package operations + +import ( + "net/http" +) + +type MarkUnplayedRequest struct { + // The media key to mark as Unplayed + Key float64 `queryParam:"style=form,explode=true,name=key"` +} + +func (o *MarkUnplayedRequest) GetKey() float64 { + if o == nil { + return 0.0 + } + return o.Key +} + +type MarkUnplayedErrors struct { + Code *float64 `json:"code,omitempty"` + Message *string `json:"message,omitempty"` + Status *float64 `json:"status,omitempty"` +} + +func (o *MarkUnplayedErrors) GetCode() *float64 { + if o == nil { + return nil + } + return o.Code +} + +func (o *MarkUnplayedErrors) GetMessage() *string { + if o == nil { + return nil + } + return o.Message +} + +func (o *MarkUnplayedErrors) GetStatus() *float64 { + if o == nil { + return nil + } + return o.Status +} + +// MarkUnplayedResponseBody - Unauthorized - Returned if the X-Plex-Token is missing from the header or query. +type MarkUnplayedResponseBody struct { + Errors []MarkUnplayedErrors `json:"errors,omitempty"` +} + +func (o *MarkUnplayedResponseBody) GetErrors() []MarkUnplayedErrors { + if o == nil { + return nil + } + return o.Errors +} + +type MarkUnplayedResponse struct { + // HTTP response content type for this operation + ContentType string + // HTTP response status code for this operation + StatusCode int + // Raw HTTP response; suitable for custom response parsing + RawResponse *http.Response + // Unauthorized - Returned if the X-Plex-Token is missing from the header or query. + Object *MarkUnplayedResponseBody +} + +func (o *MarkUnplayedResponse) GetContentType() string { + if o == nil { + return "" + } + return o.ContentType +} + +func (o *MarkUnplayedResponse) GetStatusCode() int { + if o == nil { + return 0 + } + return o.StatusCode +} + +func (o *MarkUnplayedResponse) GetRawResponse() *http.Response { + if o == nil { + return nil + } + return o.RawResponse +} + +func (o *MarkUnplayedResponse) GetObject() *MarkUnplayedResponseBody { + if o == nil { + return nil + } + return o.Object +} diff --git a/internal/sdk/pkg/models/operations/performsearch.go b/internal/sdk/pkg/models/operations/performsearch.go new file mode 100644 index 0000000..b067197 --- /dev/null +++ b/internal/sdk/pkg/models/operations/performsearch.go @@ -0,0 +1,127 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package operations + +import ( + "github.com/LukeHagar/terraform-provider-PlexAPI/internal/sdk/pkg/utils" + "net/http" +) + +type PerformSearchRequest struct { + // The query term + Query string `queryParam:"style=form,explode=true,name=query"` + // This gives context to the search, and can result in re-ordering of search result hubs + SectionID *float64 `queryParam:"style=form,explode=true,name=sectionId"` + // The number of items to return per hub + Limit *float64 `default:"3" queryParam:"style=form,explode=true,name=limit"` +} + +func (p PerformSearchRequest) MarshalJSON() ([]byte, error) { + return utils.MarshalJSON(p, "", false) +} + +func (p *PerformSearchRequest) UnmarshalJSON(data []byte) error { + if err := utils.UnmarshalJSON(data, &p, "", false, false); err != nil { + return err + } + return nil +} + +func (o *PerformSearchRequest) GetQuery() string { + if o == nil { + return "" + } + return o.Query +} + +func (o *PerformSearchRequest) GetSectionID() *float64 { + if o == nil { + return nil + } + return o.SectionID +} + +func (o *PerformSearchRequest) GetLimit() *float64 { + if o == nil { + return nil + } + return o.Limit +} + +type PerformSearchErrors struct { + Code *float64 `json:"code,omitempty"` + Message *string `json:"message,omitempty"` + Status *float64 `json:"status,omitempty"` +} + +func (o *PerformSearchErrors) GetCode() *float64 { + if o == nil { + return nil + } + return o.Code +} + +func (o *PerformSearchErrors) GetMessage() *string { + if o == nil { + return nil + } + return o.Message +} + +func (o *PerformSearchErrors) GetStatus() *float64 { + if o == nil { + return nil + } + return o.Status +} + +// PerformSearchResponseBody - Unauthorized - Returned if the X-Plex-Token is missing from the header or query. +type PerformSearchResponseBody struct { + Errors []PerformSearchErrors `json:"errors,omitempty"` +} + +func (o *PerformSearchResponseBody) GetErrors() []PerformSearchErrors { + if o == nil { + return nil + } + return o.Errors +} + +type PerformSearchResponse struct { + // HTTP response content type for this operation + ContentType string + // HTTP response status code for this operation + StatusCode int + // Raw HTTP response; suitable for custom response parsing + RawResponse *http.Response + // Unauthorized - Returned if the X-Plex-Token is missing from the header or query. + Object *PerformSearchResponseBody +} + +func (o *PerformSearchResponse) GetContentType() string { + if o == nil { + return "" + } + return o.ContentType +} + +func (o *PerformSearchResponse) GetStatusCode() int { + if o == nil { + return 0 + } + return o.StatusCode +} + +func (o *PerformSearchResponse) GetRawResponse() *http.Response { + if o == nil { + return nil + } + return o.RawResponse +} + +func (o *PerformSearchResponse) GetObject() *PerformSearchResponseBody { + if o == nil { + return nil + } + return o.Object +} diff --git a/internal/sdk/pkg/models/operations/performvoicesearch.go b/internal/sdk/pkg/models/operations/performvoicesearch.go new file mode 100644 index 0000000..08b731b --- /dev/null +++ b/internal/sdk/pkg/models/operations/performvoicesearch.go @@ -0,0 +1,127 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package operations + +import ( + "github.com/LukeHagar/terraform-provider-PlexAPI/internal/sdk/pkg/utils" + "net/http" +) + +type PerformVoiceSearchRequest struct { + // The query term + Query string `queryParam:"style=form,explode=true,name=query"` + // This gives context to the search, and can result in re-ordering of search result hubs + SectionID *float64 `queryParam:"style=form,explode=true,name=sectionId"` + // The number of items to return per hub + Limit *float64 `default:"3" queryParam:"style=form,explode=true,name=limit"` +} + +func (p PerformVoiceSearchRequest) MarshalJSON() ([]byte, error) { + return utils.MarshalJSON(p, "", false) +} + +func (p *PerformVoiceSearchRequest) UnmarshalJSON(data []byte) error { + if err := utils.UnmarshalJSON(data, &p, "", false, false); err != nil { + return err + } + return nil +} + +func (o *PerformVoiceSearchRequest) GetQuery() string { + if o == nil { + return "" + } + return o.Query +} + +func (o *PerformVoiceSearchRequest) GetSectionID() *float64 { + if o == nil { + return nil + } + return o.SectionID +} + +func (o *PerformVoiceSearchRequest) GetLimit() *float64 { + if o == nil { + return nil + } + return o.Limit +} + +type PerformVoiceSearchErrors struct { + Code *float64 `json:"code,omitempty"` + Message *string `json:"message,omitempty"` + Status *float64 `json:"status,omitempty"` +} + +func (o *PerformVoiceSearchErrors) GetCode() *float64 { + if o == nil { + return nil + } + return o.Code +} + +func (o *PerformVoiceSearchErrors) GetMessage() *string { + if o == nil { + return nil + } + return o.Message +} + +func (o *PerformVoiceSearchErrors) GetStatus() *float64 { + if o == nil { + return nil + } + return o.Status +} + +// PerformVoiceSearchResponseBody - Unauthorized - Returned if the X-Plex-Token is missing from the header or query. +type PerformVoiceSearchResponseBody struct { + Errors []PerformVoiceSearchErrors `json:"errors,omitempty"` +} + +func (o *PerformVoiceSearchResponseBody) GetErrors() []PerformVoiceSearchErrors { + if o == nil { + return nil + } + return o.Errors +} + +type PerformVoiceSearchResponse struct { + // HTTP response content type for this operation + ContentType string + // HTTP response status code for this operation + StatusCode int + // Raw HTTP response; suitable for custom response parsing + RawResponse *http.Response + // Unauthorized - Returned if the X-Plex-Token is missing from the header or query. + Object *PerformVoiceSearchResponseBody +} + +func (o *PerformVoiceSearchResponse) GetContentType() string { + if o == nil { + return "" + } + return o.ContentType +} + +func (o *PerformVoiceSearchResponse) GetStatusCode() int { + if o == nil { + return 0 + } + return o.StatusCode +} + +func (o *PerformVoiceSearchResponse) GetRawResponse() *http.Response { + if o == nil { + return nil + } + return o.RawResponse +} + +func (o *PerformVoiceSearchResponse) GetObject() *PerformVoiceSearchResponseBody { + if o == nil { + return nil + } + return o.Object +} diff --git a/internal/sdk/pkg/models/operations/refreshlibrary.go b/internal/sdk/pkg/models/operations/refreshlibrary.go new file mode 100644 index 0000000..b2c8113 --- /dev/null +++ b/internal/sdk/pkg/models/operations/refreshlibrary.go @@ -0,0 +1,97 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package operations + +import ( + "net/http" +) + +type RefreshLibraryRequest struct { + // the Id of the library to refresh + SectionID float64 `pathParam:"style=simple,explode=false,name=sectionId"` +} + +func (o *RefreshLibraryRequest) GetSectionID() float64 { + if o == nil { + return 0.0 + } + return o.SectionID +} + +type RefreshLibraryErrors struct { + Code *float64 `json:"code,omitempty"` + Message *string `json:"message,omitempty"` + Status *float64 `json:"status,omitempty"` +} + +func (o *RefreshLibraryErrors) GetCode() *float64 { + if o == nil { + return nil + } + return o.Code +} + +func (o *RefreshLibraryErrors) GetMessage() *string { + if o == nil { + return nil + } + return o.Message +} + +func (o *RefreshLibraryErrors) GetStatus() *float64 { + if o == nil { + return nil + } + return o.Status +} + +// RefreshLibraryResponseBody - Unauthorized - Returned if the X-Plex-Token is missing from the header or query. +type RefreshLibraryResponseBody struct { + Errors []RefreshLibraryErrors `json:"errors,omitempty"` +} + +func (o *RefreshLibraryResponseBody) GetErrors() []RefreshLibraryErrors { + if o == nil { + return nil + } + return o.Errors +} + +type RefreshLibraryResponse struct { + // HTTP response content type for this operation + ContentType string + // HTTP response status code for this operation + StatusCode int + // Raw HTTP response; suitable for custom response parsing + RawResponse *http.Response + // Unauthorized - Returned if the X-Plex-Token is missing from the header or query. + Object *RefreshLibraryResponseBody +} + +func (o *RefreshLibraryResponse) GetContentType() string { + if o == nil { + return "" + } + return o.ContentType +} + +func (o *RefreshLibraryResponse) GetStatusCode() int { + if o == nil { + return 0 + } + return o.StatusCode +} + +func (o *RefreshLibraryResponse) GetRawResponse() *http.Response { + if o == nil { + return nil + } + return o.RawResponse +} + +func (o *RefreshLibraryResponse) GetObject() *RefreshLibraryResponseBody { + if o == nil { + return nil + } + return o.Object +} diff --git a/internal/sdk/pkg/models/operations/startalltasks.go b/internal/sdk/pkg/models/operations/startalltasks.go new file mode 100644 index 0000000..65438a8 --- /dev/null +++ b/internal/sdk/pkg/models/operations/startalltasks.go @@ -0,0 +1,85 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package operations + +import ( + "net/http" +) + +type StartAllTasksErrors struct { + Code *float64 `json:"code,omitempty"` + Message *string `json:"message,omitempty"` + Status *float64 `json:"status,omitempty"` +} + +func (o *StartAllTasksErrors) GetCode() *float64 { + if o == nil { + return nil + } + return o.Code +} + +func (o *StartAllTasksErrors) GetMessage() *string { + if o == nil { + return nil + } + return o.Message +} + +func (o *StartAllTasksErrors) GetStatus() *float64 { + if o == nil { + return nil + } + return o.Status +} + +// StartAllTasksResponseBody - Unauthorized - Returned if the X-Plex-Token is missing from the header or query. +type StartAllTasksResponseBody struct { + Errors []StartAllTasksErrors `json:"errors,omitempty"` +} + +func (o *StartAllTasksResponseBody) GetErrors() []StartAllTasksErrors { + if o == nil { + return nil + } + return o.Errors +} + +type StartAllTasksResponse struct { + // HTTP response content type for this operation + ContentType string + // HTTP response status code for this operation + StatusCode int + // Raw HTTP response; suitable for custom response parsing + RawResponse *http.Response + // Unauthorized - Returned if the X-Plex-Token is missing from the header or query. + Object *StartAllTasksResponseBody +} + +func (o *StartAllTasksResponse) GetContentType() string { + if o == nil { + return "" + } + return o.ContentType +} + +func (o *StartAllTasksResponse) GetStatusCode() int { + if o == nil { + return 0 + } + return o.StatusCode +} + +func (o *StartAllTasksResponse) GetRawResponse() *http.Response { + if o == nil { + return nil + } + return o.RawResponse +} + +func (o *StartAllTasksResponse) GetObject() *StartAllTasksResponseBody { + if o == nil { + return nil + } + return o.Object +} diff --git a/internal/sdk/pkg/models/operations/starttask.go b/internal/sdk/pkg/models/operations/starttask.go new file mode 100644 index 0000000..53c0fe6 --- /dev/null +++ b/internal/sdk/pkg/models/operations/starttask.go @@ -0,0 +1,163 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package operations + +import ( + "encoding/json" + "fmt" + "net/http" +) + +// TaskName - the name of the task to be started. +type TaskName string + +const ( + TaskNameBackupDatabase TaskName = "BackupDatabase" + TaskNameBuildGracenoteCollections TaskName = "BuildGracenoteCollections" + TaskNameCheckForUpdates TaskName = "CheckForUpdates" + TaskNameCleanOldBundles TaskName = "CleanOldBundles" + TaskNameCleanOldCacheFiles TaskName = "CleanOldCacheFiles" + TaskNameDeepMediaAnalysis TaskName = "DeepMediaAnalysis" + TaskNameGenerateAutoTags TaskName = "GenerateAutoTags" + TaskNameGenerateChapterThumbs TaskName = "GenerateChapterThumbs" + TaskNameGenerateMediaIndexFiles TaskName = "GenerateMediaIndexFiles" + TaskNameOptimizeDatabase TaskName = "OptimizeDatabase" + TaskNameRefreshLibraries TaskName = "RefreshLibraries" + TaskNameRefreshLocalMedia TaskName = "RefreshLocalMedia" + TaskNameRefreshPeriodicMetadata TaskName = "RefreshPeriodicMetadata" + TaskNameUpgradeMediaAnalysis TaskName = "UpgradeMediaAnalysis" +) + +func (e TaskName) ToPointer() *TaskName { + return &e +} + +func (e *TaskName) UnmarshalJSON(data []byte) error { + var v string + if err := json.Unmarshal(data, &v); err != nil { + return err + } + switch v { + case "BackupDatabase": + fallthrough + case "BuildGracenoteCollections": + fallthrough + case "CheckForUpdates": + fallthrough + case "CleanOldBundles": + fallthrough + case "CleanOldCacheFiles": + fallthrough + case "DeepMediaAnalysis": + fallthrough + case "GenerateAutoTags": + fallthrough + case "GenerateChapterThumbs": + fallthrough + case "GenerateMediaIndexFiles": + fallthrough + case "OptimizeDatabase": + fallthrough + case "RefreshLibraries": + fallthrough + case "RefreshLocalMedia": + fallthrough + case "RefreshPeriodicMetadata": + fallthrough + case "UpgradeMediaAnalysis": + *e = TaskName(v) + return nil + default: + return fmt.Errorf("invalid value for TaskName: %v", v) + } +} + +type StartTaskRequest struct { + // the name of the task to be started. + TaskName TaskName `pathParam:"style=simple,explode=false,name=taskName"` +} + +func (o *StartTaskRequest) GetTaskName() TaskName { + if o == nil { + return TaskName("") + } + return o.TaskName +} + +type StartTaskErrors struct { + Code *float64 `json:"code,omitempty"` + Message *string `json:"message,omitempty"` + Status *float64 `json:"status,omitempty"` +} + +func (o *StartTaskErrors) GetCode() *float64 { + if o == nil { + return nil + } + return o.Code +} + +func (o *StartTaskErrors) GetMessage() *string { + if o == nil { + return nil + } + return o.Message +} + +func (o *StartTaskErrors) GetStatus() *float64 { + if o == nil { + return nil + } + return o.Status +} + +// StartTaskResponseBody - Unauthorized - Returned if the X-Plex-Token is missing from the header or query. +type StartTaskResponseBody struct { + Errors []StartTaskErrors `json:"errors,omitempty"` +} + +func (o *StartTaskResponseBody) GetErrors() []StartTaskErrors { + if o == nil { + return nil + } + return o.Errors +} + +type StartTaskResponse struct { + // HTTP response content type for this operation + ContentType string + // HTTP response status code for this operation + StatusCode int + // Raw HTTP response; suitable for custom response parsing + RawResponse *http.Response + // Unauthorized - Returned if the X-Plex-Token is missing from the header or query. + Object *StartTaskResponseBody +} + +func (o *StartTaskResponse) GetContentType() string { + if o == nil { + return "" + } + return o.ContentType +} + +func (o *StartTaskResponse) GetStatusCode() int { + if o == nil { + return 0 + } + return o.StatusCode +} + +func (o *StartTaskResponse) GetRawResponse() *http.Response { + if o == nil { + return nil + } + return o.RawResponse +} + +func (o *StartTaskResponse) GetObject() *StartTaskResponseBody { + if o == nil { + return nil + } + return o.Object +} diff --git a/internal/sdk/pkg/models/operations/startuniversaltranscode.go b/internal/sdk/pkg/models/operations/startuniversaltranscode.go new file mode 100644 index 0000000..2dab151 --- /dev/null +++ b/internal/sdk/pkg/models/operations/startuniversaltranscode.go @@ -0,0 +1,232 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package operations + +import ( + "net/http" +) + +type StartUniversalTranscodeRequest struct { + // Whether the media item has MDE + HasMDE float64 `queryParam:"style=form,explode=true,name=hasMDE"` + // The path to the media item to transcode + Path string `queryParam:"style=form,explode=true,name=path"` + // The index of the media item to transcode + MediaIndex float64 `queryParam:"style=form,explode=true,name=mediaIndex"` + // The index of the part to transcode + PartIndex float64 `queryParam:"style=form,explode=true,name=partIndex"` + // The protocol to use for the transcode session + Protocol string `queryParam:"style=form,explode=true,name=protocol"` + // Whether to use fast seek or not + FastSeek *float64 `queryParam:"style=form,explode=true,name=fastSeek"` + // Whether to use direct play or not + DirectPlay *float64 `queryParam:"style=form,explode=true,name=directPlay"` + // Whether to use direct stream or not + DirectStream *float64 `queryParam:"style=form,explode=true,name=directStream"` + // The size of the subtitles + SubtitleSize *float64 `queryParam:"style=form,explode=true,name=subtitleSize"` + // The subtitles + Subtites *string `queryParam:"style=form,explode=true,name=subtites"` + // The audio boost + AudioBoost *float64 `queryParam:"style=form,explode=true,name=audioBoost"` + // The location of the transcode session + Location *string `queryParam:"style=form,explode=true,name=location"` + // The size of the media buffer + MediaBufferSize *float64 `queryParam:"style=form,explode=true,name=mediaBufferSize"` + // The session ID + Session *string `queryParam:"style=form,explode=true,name=session"` + // Whether to add a debug overlay or not + AddDebugOverlay *float64 `queryParam:"style=form,explode=true,name=addDebugOverlay"` + // Whether to auto adjust quality or not + AutoAdjustQuality *float64 `queryParam:"style=form,explode=true,name=autoAdjustQuality"` +} + +func (o *StartUniversalTranscodeRequest) GetHasMDE() float64 { + if o == nil { + return 0.0 + } + return o.HasMDE +} + +func (o *StartUniversalTranscodeRequest) GetPath() string { + if o == nil { + return "" + } + return o.Path +} + +func (o *StartUniversalTranscodeRequest) GetMediaIndex() float64 { + if o == nil { + return 0.0 + } + return o.MediaIndex +} + +func (o *StartUniversalTranscodeRequest) GetPartIndex() float64 { + if o == nil { + return 0.0 + } + return o.PartIndex +} + +func (o *StartUniversalTranscodeRequest) GetProtocol() string { + if o == nil { + return "" + } + return o.Protocol +} + +func (o *StartUniversalTranscodeRequest) GetFastSeek() *float64 { + if o == nil { + return nil + } + return o.FastSeek +} + +func (o *StartUniversalTranscodeRequest) GetDirectPlay() *float64 { + if o == nil { + return nil + } + return o.DirectPlay +} + +func (o *StartUniversalTranscodeRequest) GetDirectStream() *float64 { + if o == nil { + return nil + } + return o.DirectStream +} + +func (o *StartUniversalTranscodeRequest) GetSubtitleSize() *float64 { + if o == nil { + return nil + } + return o.SubtitleSize +} + +func (o *StartUniversalTranscodeRequest) GetSubtites() *string { + if o == nil { + return nil + } + return o.Subtites +} + +func (o *StartUniversalTranscodeRequest) GetAudioBoost() *float64 { + if o == nil { + return nil + } + return o.AudioBoost +} + +func (o *StartUniversalTranscodeRequest) GetLocation() *string { + if o == nil { + return nil + } + return o.Location +} + +func (o *StartUniversalTranscodeRequest) GetMediaBufferSize() *float64 { + if o == nil { + return nil + } + return o.MediaBufferSize +} + +func (o *StartUniversalTranscodeRequest) GetSession() *string { + if o == nil { + return nil + } + return o.Session +} + +func (o *StartUniversalTranscodeRequest) GetAddDebugOverlay() *float64 { + if o == nil { + return nil + } + return o.AddDebugOverlay +} + +func (o *StartUniversalTranscodeRequest) GetAutoAdjustQuality() *float64 { + if o == nil { + return nil + } + return o.AutoAdjustQuality +} + +type StartUniversalTranscodeErrors struct { + Code *float64 `json:"code,omitempty"` + Message *string `json:"message,omitempty"` + Status *float64 `json:"status,omitempty"` +} + +func (o *StartUniversalTranscodeErrors) GetCode() *float64 { + if o == nil { + return nil + } + return o.Code +} + +func (o *StartUniversalTranscodeErrors) GetMessage() *string { + if o == nil { + return nil + } + return o.Message +} + +func (o *StartUniversalTranscodeErrors) GetStatus() *float64 { + if o == nil { + return nil + } + return o.Status +} + +// StartUniversalTranscodeResponseBody - Unauthorized - Returned if the X-Plex-Token is missing from the header or query. +type StartUniversalTranscodeResponseBody struct { + Errors []StartUniversalTranscodeErrors `json:"errors,omitempty"` +} + +func (o *StartUniversalTranscodeResponseBody) GetErrors() []StartUniversalTranscodeErrors { + if o == nil { + return nil + } + return o.Errors +} + +type StartUniversalTranscodeResponse struct { + // HTTP response content type for this operation + ContentType string + // HTTP response status code for this operation + StatusCode int + // Raw HTTP response; suitable for custom response parsing + RawResponse *http.Response + // Unauthorized - Returned if the X-Plex-Token is missing from the header or query. + Object *StartUniversalTranscodeResponseBody +} + +func (o *StartUniversalTranscodeResponse) GetContentType() string { + if o == nil { + return "" + } + return o.ContentType +} + +func (o *StartUniversalTranscodeResponse) GetStatusCode() int { + if o == nil { + return 0 + } + return o.StatusCode +} + +func (o *StartUniversalTranscodeResponse) GetRawResponse() *http.Response { + if o == nil { + return nil + } + return o.RawResponse +} + +func (o *StartUniversalTranscodeResponse) GetObject() *StartUniversalTranscodeResponseBody { + if o == nil { + return nil + } + return o.Object +} diff --git a/internal/sdk/pkg/models/operations/stopalltasks.go b/internal/sdk/pkg/models/operations/stopalltasks.go new file mode 100644 index 0000000..b8f9178 --- /dev/null +++ b/internal/sdk/pkg/models/operations/stopalltasks.go @@ -0,0 +1,85 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package operations + +import ( + "net/http" +) + +type StopAllTasksErrors struct { + Code *float64 `json:"code,omitempty"` + Message *string `json:"message,omitempty"` + Status *float64 `json:"status,omitempty"` +} + +func (o *StopAllTasksErrors) GetCode() *float64 { + if o == nil { + return nil + } + return o.Code +} + +func (o *StopAllTasksErrors) GetMessage() *string { + if o == nil { + return nil + } + return o.Message +} + +func (o *StopAllTasksErrors) GetStatus() *float64 { + if o == nil { + return nil + } + return o.Status +} + +// StopAllTasksResponseBody - Unauthorized - Returned if the X-Plex-Token is missing from the header or query. +type StopAllTasksResponseBody struct { + Errors []StopAllTasksErrors `json:"errors,omitempty"` +} + +func (o *StopAllTasksResponseBody) GetErrors() []StopAllTasksErrors { + if o == nil { + return nil + } + return o.Errors +} + +type StopAllTasksResponse struct { + // HTTP response content type for this operation + ContentType string + // HTTP response status code for this operation + StatusCode int + // Raw HTTP response; suitable for custom response parsing + RawResponse *http.Response + // Unauthorized - Returned if the X-Plex-Token is missing from the header or query. + Object *StopAllTasksResponseBody +} + +func (o *StopAllTasksResponse) GetContentType() string { + if o == nil { + return "" + } + return o.ContentType +} + +func (o *StopAllTasksResponse) GetStatusCode() int { + if o == nil { + return 0 + } + return o.StatusCode +} + +func (o *StopAllTasksResponse) GetRawResponse() *http.Response { + if o == nil { + return nil + } + return o.RawResponse +} + +func (o *StopAllTasksResponse) GetObject() *StopAllTasksResponseBody { + if o == nil { + return nil + } + return o.Object +} diff --git a/internal/sdk/pkg/models/operations/stoptask.go b/internal/sdk/pkg/models/operations/stoptask.go new file mode 100644 index 0000000..a2faa4d --- /dev/null +++ b/internal/sdk/pkg/models/operations/stoptask.go @@ -0,0 +1,163 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package operations + +import ( + "encoding/json" + "fmt" + "net/http" +) + +// PathParamTaskName - The name of the task to be started. +type PathParamTaskName string + +const ( + PathParamTaskNameBackupDatabase PathParamTaskName = "BackupDatabase" + PathParamTaskNameBuildGracenoteCollections PathParamTaskName = "BuildGracenoteCollections" + PathParamTaskNameCheckForUpdates PathParamTaskName = "CheckForUpdates" + PathParamTaskNameCleanOldBundles PathParamTaskName = "CleanOldBundles" + PathParamTaskNameCleanOldCacheFiles PathParamTaskName = "CleanOldCacheFiles" + PathParamTaskNameDeepMediaAnalysis PathParamTaskName = "DeepMediaAnalysis" + PathParamTaskNameGenerateAutoTags PathParamTaskName = "GenerateAutoTags" + PathParamTaskNameGenerateChapterThumbs PathParamTaskName = "GenerateChapterThumbs" + PathParamTaskNameGenerateMediaIndexFiles PathParamTaskName = "GenerateMediaIndexFiles" + PathParamTaskNameOptimizeDatabase PathParamTaskName = "OptimizeDatabase" + PathParamTaskNameRefreshLibraries PathParamTaskName = "RefreshLibraries" + PathParamTaskNameRefreshLocalMedia PathParamTaskName = "RefreshLocalMedia" + PathParamTaskNameRefreshPeriodicMetadata PathParamTaskName = "RefreshPeriodicMetadata" + PathParamTaskNameUpgradeMediaAnalysis PathParamTaskName = "UpgradeMediaAnalysis" +) + +func (e PathParamTaskName) ToPointer() *PathParamTaskName { + return &e +} + +func (e *PathParamTaskName) UnmarshalJSON(data []byte) error { + var v string + if err := json.Unmarshal(data, &v); err != nil { + return err + } + switch v { + case "BackupDatabase": + fallthrough + case "BuildGracenoteCollections": + fallthrough + case "CheckForUpdates": + fallthrough + case "CleanOldBundles": + fallthrough + case "CleanOldCacheFiles": + fallthrough + case "DeepMediaAnalysis": + fallthrough + case "GenerateAutoTags": + fallthrough + case "GenerateChapterThumbs": + fallthrough + case "GenerateMediaIndexFiles": + fallthrough + case "OptimizeDatabase": + fallthrough + case "RefreshLibraries": + fallthrough + case "RefreshLocalMedia": + fallthrough + case "RefreshPeriodicMetadata": + fallthrough + case "UpgradeMediaAnalysis": + *e = PathParamTaskName(v) + return nil + default: + return fmt.Errorf("invalid value for PathParamTaskName: %v", v) + } +} + +type StopTaskRequest struct { + // The name of the task to be started. + TaskName PathParamTaskName `pathParam:"style=simple,explode=false,name=taskName"` +} + +func (o *StopTaskRequest) GetTaskName() PathParamTaskName { + if o == nil { + return PathParamTaskName("") + } + return o.TaskName +} + +type StopTaskErrors struct { + Code *float64 `json:"code,omitempty"` + Message *string `json:"message,omitempty"` + Status *float64 `json:"status,omitempty"` +} + +func (o *StopTaskErrors) GetCode() *float64 { + if o == nil { + return nil + } + return o.Code +} + +func (o *StopTaskErrors) GetMessage() *string { + if o == nil { + return nil + } + return o.Message +} + +func (o *StopTaskErrors) GetStatus() *float64 { + if o == nil { + return nil + } + return o.Status +} + +// StopTaskResponseBody - Unauthorized - Returned if the X-Plex-Token is missing from the header or query. +type StopTaskResponseBody struct { + Errors []StopTaskErrors `json:"errors,omitempty"` +} + +func (o *StopTaskResponseBody) GetErrors() []StopTaskErrors { + if o == nil { + return nil + } + return o.Errors +} + +type StopTaskResponse struct { + // HTTP response content type for this operation + ContentType string + // HTTP response status code for this operation + StatusCode int + // Raw HTTP response; suitable for custom response parsing + RawResponse *http.Response + // Unauthorized - Returned if the X-Plex-Token is missing from the header or query. + Object *StopTaskResponseBody +} + +func (o *StopTaskResponse) GetContentType() string { + if o == nil { + return "" + } + return o.ContentType +} + +func (o *StopTaskResponse) GetStatusCode() int { + if o == nil { + return 0 + } + return o.StatusCode +} + +func (o *StopTaskResponse) GetRawResponse() *http.Response { + if o == nil { + return nil + } + return o.RawResponse +} + +func (o *StopTaskResponse) GetObject() *StopTaskResponseBody { + if o == nil { + return nil + } + return o.Object +} diff --git a/internal/sdk/pkg/models/operations/stoptranscodesession.go b/internal/sdk/pkg/models/operations/stoptranscodesession.go new file mode 100644 index 0000000..60de4b0 --- /dev/null +++ b/internal/sdk/pkg/models/operations/stoptranscodesession.go @@ -0,0 +1,97 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package operations + +import ( + "net/http" +) + +type StopTranscodeSessionRequest struct { + // the Key of the transcode session to stop + SessionKey string `pathParam:"style=simple,explode=false,name=sessionKey"` +} + +func (o *StopTranscodeSessionRequest) GetSessionKey() string { + if o == nil { + return "" + } + return o.SessionKey +} + +type StopTranscodeSessionErrors struct { + Code *float64 `json:"code,omitempty"` + Message *string `json:"message,omitempty"` + Status *float64 `json:"status,omitempty"` +} + +func (o *StopTranscodeSessionErrors) GetCode() *float64 { + if o == nil { + return nil + } + return o.Code +} + +func (o *StopTranscodeSessionErrors) GetMessage() *string { + if o == nil { + return nil + } + return o.Message +} + +func (o *StopTranscodeSessionErrors) GetStatus() *float64 { + if o == nil { + return nil + } + return o.Status +} + +// StopTranscodeSessionResponseBody - Unauthorized - Returned if the X-Plex-Token is missing from the header or query. +type StopTranscodeSessionResponseBody struct { + Errors []StopTranscodeSessionErrors `json:"errors,omitempty"` +} + +func (o *StopTranscodeSessionResponseBody) GetErrors() []StopTranscodeSessionErrors { + if o == nil { + return nil + } + return o.Errors +} + +type StopTranscodeSessionResponse struct { + // HTTP response content type for this operation + ContentType string + // HTTP response status code for this operation + StatusCode int + // Raw HTTP response; suitable for custom response parsing + RawResponse *http.Response + // Unauthorized - Returned if the X-Plex-Token is missing from the header or query. + Object *StopTranscodeSessionResponseBody +} + +func (o *StopTranscodeSessionResponse) GetContentType() string { + if o == nil { + return "" + } + return o.ContentType +} + +func (o *StopTranscodeSessionResponse) GetStatusCode() int { + if o == nil { + return 0 + } + return o.StatusCode +} + +func (o *StopTranscodeSessionResponse) GetRawResponse() *http.Response { + if o == nil { + return nil + } + return o.RawResponse +} + +func (o *StopTranscodeSessionResponse) GetObject() *StopTranscodeSessionResponseBody { + if o == nil { + return nil + } + return o.Object +} diff --git a/internal/sdk/pkg/models/operations/updateplaylist.go b/internal/sdk/pkg/models/operations/updateplaylist.go new file mode 100644 index 0000000..4e7030f --- /dev/null +++ b/internal/sdk/pkg/models/operations/updateplaylist.go @@ -0,0 +1,97 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package operations + +import ( + "net/http" +) + +type UpdatePlaylistRequest struct { + // the ID of the playlist + PlaylistID float64 `pathParam:"style=simple,explode=false,name=playlistID"` +} + +func (o *UpdatePlaylistRequest) GetPlaylistID() float64 { + if o == nil { + return 0.0 + } + return o.PlaylistID +} + +type UpdatePlaylistErrors struct { + Code *float64 `json:"code,omitempty"` + Message *string `json:"message,omitempty"` + Status *float64 `json:"status,omitempty"` +} + +func (o *UpdatePlaylistErrors) GetCode() *float64 { + if o == nil { + return nil + } + return o.Code +} + +func (o *UpdatePlaylistErrors) GetMessage() *string { + if o == nil { + return nil + } + return o.Message +} + +func (o *UpdatePlaylistErrors) GetStatus() *float64 { + if o == nil { + return nil + } + return o.Status +} + +// UpdatePlaylistResponseBody - Unauthorized - Returned if the X-Plex-Token is missing from the header or query. +type UpdatePlaylistResponseBody struct { + Errors []UpdatePlaylistErrors `json:"errors,omitempty"` +} + +func (o *UpdatePlaylistResponseBody) GetErrors() []UpdatePlaylistErrors { + if o == nil { + return nil + } + return o.Errors +} + +type UpdatePlaylistResponse struct { + // HTTP response content type for this operation + ContentType string + // HTTP response status code for this operation + StatusCode int + // Raw HTTP response; suitable for custom response parsing + RawResponse *http.Response + // Unauthorized - Returned if the X-Plex-Token is missing from the header or query. + Object *UpdatePlaylistResponseBody +} + +func (o *UpdatePlaylistResponse) GetContentType() string { + if o == nil { + return "" + } + return o.ContentType +} + +func (o *UpdatePlaylistResponse) GetStatusCode() int { + if o == nil { + return 0 + } + return o.StatusCode +} + +func (o *UpdatePlaylistResponse) GetRawResponse() *http.Response { + if o == nil { + return nil + } + return o.RawResponse +} + +func (o *UpdatePlaylistResponse) GetObject() *UpdatePlaylistResponseBody { + if o == nil { + return nil + } + return o.Object +} diff --git a/internal/sdk/pkg/models/operations/updateplayprogress.go b/internal/sdk/pkg/models/operations/updateplayprogress.go new file mode 100644 index 0000000..86b3368 --- /dev/null +++ b/internal/sdk/pkg/models/operations/updateplayprogress.go @@ -0,0 +1,115 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package operations + +import ( + "net/http" +) + +type UpdatePlayProgressRequest struct { + // the media key + Key string `queryParam:"style=form,explode=true,name=key"` + // The time, in milliseconds, used to set the media playback progress. + Time float64 `queryParam:"style=form,explode=true,name=time"` + // The playback state of the media item. + State string `queryParam:"style=form,explode=true,name=state"` +} + +func (o *UpdatePlayProgressRequest) GetKey() string { + if o == nil { + return "" + } + return o.Key +} + +func (o *UpdatePlayProgressRequest) GetTime() float64 { + if o == nil { + return 0.0 + } + return o.Time +} + +func (o *UpdatePlayProgressRequest) GetState() string { + if o == nil { + return "" + } + return o.State +} + +type UpdatePlayProgressErrors struct { + Code *float64 `json:"code,omitempty"` + Message *string `json:"message,omitempty"` + Status *float64 `json:"status,omitempty"` +} + +func (o *UpdatePlayProgressErrors) GetCode() *float64 { + if o == nil { + return nil + } + return o.Code +} + +func (o *UpdatePlayProgressErrors) GetMessage() *string { + if o == nil { + return nil + } + return o.Message +} + +func (o *UpdatePlayProgressErrors) GetStatus() *float64 { + if o == nil { + return nil + } + return o.Status +} + +// UpdatePlayProgressResponseBody - Unauthorized - Returned if the X-Plex-Token is missing from the header or query. +type UpdatePlayProgressResponseBody struct { + Errors []UpdatePlayProgressErrors `json:"errors,omitempty"` +} + +func (o *UpdatePlayProgressResponseBody) GetErrors() []UpdatePlayProgressErrors { + if o == nil { + return nil + } + return o.Errors +} + +type UpdatePlayProgressResponse struct { + // HTTP response content type for this operation + ContentType string + // HTTP response status code for this operation + StatusCode int + // Raw HTTP response; suitable for custom response parsing + RawResponse *http.Response + // Unauthorized - Returned if the X-Plex-Token is missing from the header or query. + Object *UpdatePlayProgressResponseBody +} + +func (o *UpdatePlayProgressResponse) GetContentType() string { + if o == nil { + return "" + } + return o.ContentType +} + +func (o *UpdatePlayProgressResponse) GetStatusCode() int { + if o == nil { + return 0 + } + return o.StatusCode +} + +func (o *UpdatePlayProgressResponse) GetRawResponse() *http.Response { + if o == nil { + return nil + } + return o.RawResponse +} + +func (o *UpdatePlayProgressResponse) GetObject() *UpdatePlayProgressResponseBody { + if o == nil { + return nil + } + return o.Object +} diff --git a/internal/sdk/pkg/models/operations/uploadplaylist.go b/internal/sdk/pkg/models/operations/uploadplaylist.go new file mode 100644 index 0000000..30c1254 --- /dev/null +++ b/internal/sdk/pkg/models/operations/uploadplaylist.go @@ -0,0 +1,145 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package operations + +import ( + "encoding/json" + "fmt" + "net/http" +) + +// Force - force overwriting of duplicate playlists. By default, a playlist file uploaded with the same path will overwrite the existing playlist. +// The `force` argument is used to disable overwriting. If the `force` argument is set to 0, a new playlist will be created suffixed with the date and time that the duplicate was uploaded. +type Force int64 + +const ( + ForceZero Force = 0 + ForceOne Force = 1 +) + +func (e Force) ToPointer() *Force { + return &e +} + +func (e *Force) UnmarshalJSON(data []byte) error { + var v int64 + if err := json.Unmarshal(data, &v); err != nil { + return err + } + switch v { + case 0: + fallthrough + case 1: + *e = Force(v) + return nil + default: + return fmt.Errorf("invalid value for Force: %v", v) + } +} + +type UploadPlaylistRequest struct { + // absolute path to a directory on the server where m3u files are stored, or the absolute path to a playlist file on the server. + // If the `path` argument is a directory, that path will be scanned for playlist files to be processed. + // Each file in that directory creates a separate playlist, with a name based on the filename of the file that created it. + // The GUID of each playlist is based on the filename. + // If the `path` argument is a file, that file will be used to create a new playlist, with the name based on the filename of the file that created it. + // The GUID of each playlist is based on the filename. + // + Path string `queryParam:"style=form,explode=true,name=path"` + // force overwriting of duplicate playlists. By default, a playlist file uploaded with the same path will overwrite the existing playlist. + // The `force` argument is used to disable overwriting. If the `force` argument is set to 0, a new playlist will be created suffixed with the date and time that the duplicate was uploaded. + // + Force Force `queryParam:"style=form,explode=true,name=force"` +} + +func (o *UploadPlaylistRequest) GetPath() string { + if o == nil { + return "" + } + return o.Path +} + +func (o *UploadPlaylistRequest) GetForce() Force { + if o == nil { + return Force(0) + } + return o.Force +} + +type UploadPlaylistErrors struct { + Code *float64 `json:"code,omitempty"` + Message *string `json:"message,omitempty"` + Status *float64 `json:"status,omitempty"` +} + +func (o *UploadPlaylistErrors) GetCode() *float64 { + if o == nil { + return nil + } + return o.Code +} + +func (o *UploadPlaylistErrors) GetMessage() *string { + if o == nil { + return nil + } + return o.Message +} + +func (o *UploadPlaylistErrors) GetStatus() *float64 { + if o == nil { + return nil + } + return o.Status +} + +// UploadPlaylistResponseBody - Unauthorized - Returned if the X-Plex-Token is missing from the header or query. +type UploadPlaylistResponseBody struct { + Errors []UploadPlaylistErrors `json:"errors,omitempty"` +} + +func (o *UploadPlaylistResponseBody) GetErrors() []UploadPlaylistErrors { + if o == nil { + return nil + } + return o.Errors +} + +type UploadPlaylistResponse struct { + // HTTP response content type for this operation + ContentType string + // HTTP response status code for this operation + StatusCode int + // Raw HTTP response; suitable for custom response parsing + RawResponse *http.Response + // Unauthorized - Returned if the X-Plex-Token is missing from the header or query. + Object *UploadPlaylistResponseBody +} + +func (o *UploadPlaylistResponse) GetContentType() string { + if o == nil { + return "" + } + return o.ContentType +} + +func (o *UploadPlaylistResponse) GetStatusCode() int { + if o == nil { + return 0 + } + return o.StatusCode +} + +func (o *UploadPlaylistResponse) GetRawResponse() *http.Response { + if o == nil { + return nil + } + return o.RawResponse +} + +func (o *UploadPlaylistResponse) GetObject() *UploadPlaylistResponseBody { + if o == nil { + return nil + } + return o.Object +} diff --git a/internal/sdk/pkg/models/sdkerrors/sdkerror.go b/internal/sdk/pkg/models/sdkerrors/sdkerror.go new file mode 100644 index 0000000..5c1affd --- /dev/null +++ b/internal/sdk/pkg/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/internal/sdk/pkg/models/shared/security.go b/internal/sdk/pkg/models/shared/security.go new file mode 100644 index 0000000..0e8d0cc --- /dev/null +++ b/internal/sdk/pkg/models/shared/security.go @@ -0,0 +1,14 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package shared + +type Security struct { + AccessToken string `security:"scheme,type=apiKey,subtype=header,name=X-Plex-Token"` +} + +func (o *Security) GetAccessToken() string { + if o == nil { + return "" + } + return o.AccessToken +} diff --git a/internal/sdk/pkg/types/bigint.go b/internal/sdk/pkg/types/bigint.go new file mode 100644 index 0000000..afd0cd2 --- /dev/null +++ b/internal/sdk/pkg/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/internal/sdk/pkg/types/date.go b/internal/sdk/pkg/types/date.go new file mode 100644 index 0000000..c4648fa --- /dev/null +++ b/internal/sdk/pkg/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/internal/sdk/pkg/types/datetime.go b/internal/sdk/pkg/types/datetime.go new file mode 100644 index 0000000..0529b25 --- /dev/null +++ b/internal/sdk/pkg/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/internal/sdk/pkg/types/decimal.go b/internal/sdk/pkg/types/decimal.go new file mode 100644 index 0000000..a42284b --- /dev/null +++ b/internal/sdk/pkg/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/internal/sdk/pkg/types/pointers.go b/internal/sdk/pkg/types/pointers.go new file mode 100644 index 0000000..4f15e99 --- /dev/null +++ b/internal/sdk/pkg/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/internal/sdk/pkg/utils/contenttype.go b/internal/sdk/pkg/utils/contenttype.go new file mode 100644 index 0000000..8ed13e2 --- /dev/null +++ b/internal/sdk/pkg/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/sdk/pkg/utils/form.go b/internal/sdk/pkg/utils/form.go new file mode 100644 index 0000000..d5091c4 --- /dev/null +++ b/internal/sdk/pkg/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/LukeHagar/terraform-provider-PlexAPI/internal/sdk/pkg/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/sdk/pkg/utils/headers.go b/internal/sdk/pkg/utils/headers.go new file mode 100644 index 0000000..0837022 --- /dev/null +++ b/internal/sdk/pkg/utils/headers.go @@ -0,0 +1,102 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package utils + +import ( + "context" + "fmt" + "net/http" + "reflect" + "strings" +) + +func PopulateHeaders(ctx context.Context, req *http.Request, headers interface{}) { + headerParamsStructType := reflect.TypeOf(headers) + headerParamsValType := reflect.ValueOf(headers) + + for i := 0; i < headerParamsStructType.NumField(); i++ { + fieldType := headerParamsStructType.Field(i) + valType := headerParamsValType.Field(i) + + tag := parseParamTag(headerParamTagKey, fieldType, "simple", false) + if tag == nil { + continue + } + + value := serializeHeader(fieldType.Type, valType, tag.Explode) + if value != "" { + req.Header.Add(tag.ParamName, value) + } + } +} + +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/sdk/pkg/utils/json.go b/internal/sdk/pkg/utils/json.go new file mode 100644 index 0000000..a328e88 --- /dev/null +++ b/internal/sdk/pkg/utils/json.go @@ -0,0 +1,596 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package utils + +import ( + "bytes" + "encoding/json" + "fmt" + "math/big" + "reflect" + "strings" + "time" + "unsafe" + + "github.com/LukeHagar/terraform-provider-PlexAPI/internal/sdk/pkg/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.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(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(`"%s"`, 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.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/sdk/pkg/utils/pathparams.go b/internal/sdk/pkg/utils/pathparams.go new file mode 100644 index 0000000..688d21a --- /dev/null +++ b/internal/sdk/pkg/utils/pathparams.go @@ -0,0 +1,145 @@ +// 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/LukeHagar/terraform-provider-PlexAPI/internal/sdk/pkg/types" +) + +func GenerateURL(ctx context.Context, serverURL, path string, pathParams interface{}, globals map[string]map[string]map[string]interface{}) (string, error) { + uri := strings.TrimSuffix(serverURL, "/") + path + + pathParamsStructType := reflect.TypeOf(pathParams) + pathParamsValType := reflect.ValueOf(pathParams) + + parsedParameters := map[string]string{} + + for i := 0; i < pathParamsStructType.NumField(); i++ { + fieldType := pathParamsStructType.Field(i) + valType := pathParamsValType.Field(i) + + requestTag := getRequestTag(fieldType) + if requestTag != nil { + continue + } + + ppTag := parseParamTag(pathParamTagKey, fieldType, "simple", false) + if ppTag == nil { + continue + } + + valType = populateFromGlobals(fieldType, valType, "pathParam", globals) + + if ppTag.Serialization != "" { + vals, err := populateSerializedParams(ppTag, fieldType.Type, valType) + if err != nil { + return "", err + } + for k, v := range vals { + parsedParameters[k] = url.PathEscape(v) + } + } else { + // TODO: support other styles + switch ppTag.Style { + case "simple": + simpleParams := getSimplePathParams(ctx, ppTag.ParamName, fieldType.Type, valType, ppTag.Explode) + for k, v := range simpleParams { + parsedParameters[k] = v + } + } + } + } + + // TODO should we handle the case where there are no matching path params? + return ReplaceParameters(uri, parsedParameters), nil +} + +func getSimplePathParams(ctx context.Context, 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/sdk/pkg/utils/queryparams.go b/internal/sdk/pkg/utils/queryparams.go new file mode 100644 index 0000000..0e94bce --- /dev/null +++ b/internal/sdk/pkg/utils/queryparams.go @@ -0,0 +1,178 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package utils + +import ( + "context" + "encoding/json" + "fmt" + "net/http" + "net/url" + "reflect" +) + +func PopulateQueryParams(ctx context.Context, req *http.Request, queryParams interface{}, globals map[string]map[string]map[string]interface{}) error { + queryParamsStructType := reflect.TypeOf(queryParams) + queryParamsValType := reflect.ValueOf(queryParams) + + values := url.Values{} + + for i := 0; i < queryParamsStructType.NumField(); i++ { + fieldType := queryParamsStructType.Field(i) + valType := queryParamsValType.Field(i) + + requestTag := getRequestTag(fieldType) + if requestTag != nil { + continue + } + + qpTag := parseQueryParamTag(fieldType) + if qpTag == nil { + continue + } + + valType = populateFromGlobals(fieldType, valType, "queryParam", globals) + + if qpTag.Serialization != "" { + vals, err := populateSerializedParams(qpTag, fieldType.Type, valType) + if err != nil { + return err + } + for k, v := range vals { + values.Add(k, v) + } + } else { + switch qpTag.Style { + case "deepObject": + vals := populateDeepObjectParams(req, qpTag, fieldType.Type, valType) + for k, v := range vals { + for _, vv := range v { + values.Add(k, vv) + } + } + case "form": + vals := populateFormParams(req, qpTag, fieldType.Type, valType, ",") + for k, v := range vals { + for _, vv := range v { + values.Add(k, vv) + } + } + case "pipeDelimited": + vals := populateFormParams(req, qpTag, fieldType.Type, valType, "|") + for k, v := range vals { + for _, vv := range v { + values.Add(k, vv) + } + } + default: + return fmt.Errorf("unsupported style: %s", qpTag.Style) + } + } + } + + req.URL.RawQuery = values.Encode() + + return 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(req *http.Request, 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(req *http.Request, 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/sdk/pkg/utils/requestbody.go b/internal/sdk/pkg/utils/requestbody.go new file mode 100644 index 0000000..950f39a --- /dev/null +++ b/internal/sdk/pkg/utils/requestbody.go @@ -0,0 +1,396 @@ +// 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(ctx context.Context, 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/sdk/pkg/utils/retries.go b/internal/sdk/pkg/utils/retries.go new file mode 100644 index 0000000..ff39d0d --- /dev/null +++ b/internal/sdk/pkg/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/sdk/pkg/utils/security.go b/internal/sdk/pkg/utils/security.go new file mode 100644 index 0000000..fa5eff7 --- /dev/null +++ b/internal/sdk/pkg/utils/security.go @@ -0,0 +1,298 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package utils + +import ( + "context" + "encoding/base64" + "fmt" + "net/http" + "reflect" + "strings" +) + +type HTTPClient interface { + Do(req *http.Request) (*http.Response, error) +} + +const ( + securityTagKey = "security" +) + +type securityTag struct { + Option bool + Scheme bool + Name string + Type string + SubType string +} + +type securityConfig struct { + headers map[string]string + queryParams map[string]string +} + +type SecurityClient struct { + HTTPClient + security func(ctx context.Context) (interface{}, error) +} + +func newSecurityClient(client HTTPClient, security func(ctx context.Context) (interface{}, error)) *SecurityClient { + return &SecurityClient{ + HTTPClient: client, + security: security, + } +} + +func (c *SecurityClient) Do(req *http.Request) (*http.Response, error) { + securityCtx, err := c.security(req.Context()) + if err != nil { + return nil, err + } + + ctx := securityConfig{ + headers: make(map[string]string), + queryParams: make(map[string]string), + } + parseSecurityStruct(&ctx, securityCtx) + + for k, v := range ctx.headers { + req.Header.Set(k, v) + } + + queryParams := req.URL.Query() + + for k, v := range ctx.queryParams { + queryParams.Add(k, v) + } + + req.URL.RawQuery = queryParams.Encode() + + return c.HTTPClient.Do(req) +} + +func ConfigureSecurityClient(c HTTPClient, security func(ctx context.Context) (interface{}, error)) *SecurityClient { + return newSecurityClient(c, security) +} + +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 +} + +func parseSecurityStruct(c *securityConfig, security interface{}) { + securityValType := trueReflectValue(reflect.ValueOf(security)) + securityStructType := securityValType.Type() + + if isNil(securityStructType, securityValType) { + return + } + + 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(c, 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(c, secTag, security) + } else { + parseSecurityScheme(c, secTag, valType.Interface()) + } + } + } + } +} + +func handleSecurityOption(c *securityConfig, option interface{}) error { + optionValType := trueReflectValue(reflect.ValueOf(option)) + optionStructType := optionValType.Type() + + if isNil(optionStructType, optionValType) { + return nil + } + + for i := 0; i < optionStructType.NumField(); i++ { + fieldType := optionStructType.Field(i) + valType := optionValType.Field(i) + + secTag := parseSecurityTag(fieldType) + if secTag != nil && secTag.Scheme { + parseSecurityScheme(c, secTag, valType.Interface()) + } + } + + return nil +} + +func parseSecurityScheme(client *securityConfig, 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(client, 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(client, schemeTag, secTag, valType.Interface()) + } + } else { + parseSecuritySchemeValue(client, schemeTag, schemeTag, schemeVal.Interface()) + } +} + +func parseSecuritySchemeValue(client *securityConfig, schemeTag *securityTag, secTag *securityTag, val interface{}) { + switch schemeTag.Type { + case "apiKey": + switch schemeTag.SubType { + case "header": + client.headers[secTag.Name] = valToString(val) + case "query": + client.queryParams[secTag.Name] = valToString(val) + case "cookie": + client.headers["Cookie"] = fmt.Sprintf("%s=%s", secTag.Name, valToString(val)) + default: + panic("not supported") + } + case "openIdConnect": + client.headers[secTag.Name] = valToString(val) + case "oauth2": + client.headers[secTag.Name] = valToString(val) + case "http": + switch schemeTag.SubType { + case "bearer": + client.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(client *securityConfig, 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() + } + } + + client.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, + } +} diff --git a/internal/sdk/pkg/utils/utils.go b/internal/sdk/pkg/utils/utils.go new file mode 100644 index 0000000..8c8161a --- /dev/null +++ b/internal/sdk/pkg/utils/utils.go @@ -0,0 +1,162 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package utils + +import ( + "fmt" + "io" + "math/big" + "reflect" + "regexp" + "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 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 map[string]map[string]map[string]interface{}) reflect.Value { + if globals != nil && fieldType.Type.Kind() == reflect.Ptr { + parameters, ok := globals["parameters"] + if ok { + paramsOfType, ok := parameters[paramType] + if ok { + globalVal, ok := paramsOfType[fieldType.Name] + if ok { + if reflect.TypeOf(globalVal).Kind() == fieldType.Type.Elem().Kind() && valType.IsNil() { + valType = reflect.ValueOf(&globalVal) + } + } + } + } + } + + return valType +} + +func isNil(typ reflect.Type, val reflect.Value) bool { + if typ.Kind() == reflect.Ptr || typ.Kind() == reflect.Map || typ.Kind() == reflect.Slice || typ.Kind() == reflect.Interface { + return val.IsNil() + } + + return false +} diff --git a/internal/sdk/playlists.go b/internal/sdk/playlists.go new file mode 100644 index 0000000..9a37dd5 --- /dev/null +++ b/internal/sdk/playlists.go @@ -0,0 +1,596 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package sdk + +import ( + "bytes" + "context" + "fmt" + "github.com/LukeHagar/terraform-provider-PlexAPI/internal/sdk/pkg/models/operations" + "github.com/LukeHagar/terraform-provider-PlexAPI/internal/sdk/pkg/models/sdkerrors" + "github.com/LukeHagar/terraform-provider-PlexAPI/internal/sdk/pkg/utils" + "io" + "net/http" + "strings" +) + +// Playlists are ordered collections of media. They can be dumb (just a list of media) or smart (based on a media query, such as "all albums from 2017"). +// They can be organized in (optionally nesting) folders. +// Retrieving a playlist, or its items, will trigger a refresh of its metadata. +// This may cause the duration and number of items to change. +type Playlists struct { + sdkConfiguration sdkConfiguration +} + +func newPlaylists(sdkConfig sdkConfiguration) *Playlists { + return &Playlists{ + sdkConfiguration: sdkConfig, + } +} + +// CreatePlaylist - Create a Playlist +// Create a new playlist. By default the playlist is blank. To create a playlist along with a first item, pass: +// - `uri` - The content URI for what we're playing (e.g. `library://...`). +// - `playQueueID` - To create a playlist from an existing play queue. +func (s *Playlists) CreatePlaylist(ctx context.Context, request operations.CreatePlaylistRequest) (*operations.CreatePlaylistResponse, error) { + baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) + url := strings.TrimSuffix(baseURL, "/") + "/playlists" + + req, err := http.NewRequestWithContext(ctx, "POST", url, 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) + } + + client := s.sdkConfiguration.SecurityClient + + httpRes, err := client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %w", err) + } + if httpRes == nil { + return nil, fmt.Errorf("error sending request: no response") + } + + 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)) + + contentType := httpRes.Header.Get("Content-Type") + + res := &operations.CreatePlaylistResponse{ + StatusCode: httpRes.StatusCode, + ContentType: contentType, + RawResponse: httpRes, + } + switch { + case httpRes.StatusCode == 200: + fallthrough + case httpRes.StatusCode == 400: + case httpRes.StatusCode == 401: + switch { + case utils.MatchContentType(contentType, `application/json`): + var out operations.CreatePlaylistResponseBody + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + res.Object = &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", contentType), httpRes.StatusCode, string(rawBody), httpRes) + } + } + + return res, nil +} + +// GetPlaylists - Get All Playlists +// Get All Playlists given the specified filters. +func (s *Playlists) GetPlaylists(ctx context.Context, request operations.GetPlaylistsRequest) (*operations.GetPlaylistsResponse, error) { + baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) + url := strings.TrimSuffix(baseURL, "/") + "/playlists/all" + + req, err := http.NewRequestWithContext(ctx, "GET", url, 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) + } + + client := s.sdkConfiguration.SecurityClient + + httpRes, err := client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %w", err) + } + if httpRes == nil { + return nil, fmt.Errorf("error sending request: no response") + } + + 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)) + + contentType := httpRes.Header.Get("Content-Type") + + res := &operations.GetPlaylistsResponse{ + StatusCode: httpRes.StatusCode, + ContentType: contentType, + RawResponse: httpRes, + } + switch { + case httpRes.StatusCode == 200: + fallthrough + case httpRes.StatusCode == 400: + case httpRes.StatusCode == 401: + switch { + case utils.MatchContentType(contentType, `application/json`): + var out operations.GetPlaylistsResponseBody + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + res.Object = &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", contentType), httpRes.StatusCode, string(rawBody), httpRes) + } + } + + return res, nil +} + +// GetPlaylist - Retrieve Playlist +// Gets detailed metadata for a playlist. A playlist for many purposes (rating, editing metadata, tagging), can be treated like a regular metadata item: +// Smart playlist details contain the `content` attribute. This is the content URI for the generator. This can then be parsed by a client to provide smart playlist editing. +func (s *Playlists) GetPlaylist(ctx context.Context, request operations.GetPlaylistRequest) (*operations.GetPlaylistResponse, error) { + baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) + url, err := utils.GenerateURL(ctx, baseURL, "/playlists/{playlistID}", request, nil) + if err != nil { + return nil, fmt.Errorf("error generating URL: %w", err) + } + + req, err := http.NewRequestWithContext(ctx, "GET", url, 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) + + client := s.sdkConfiguration.SecurityClient + + httpRes, err := client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %w", err) + } + if httpRes == nil { + return nil, fmt.Errorf("error sending request: no response") + } + + 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)) + + contentType := httpRes.Header.Get("Content-Type") + + res := &operations.GetPlaylistResponse{ + StatusCode: httpRes.StatusCode, + ContentType: contentType, + RawResponse: httpRes, + } + switch { + case httpRes.StatusCode == 200: + fallthrough + case httpRes.StatusCode == 400: + case httpRes.StatusCode == 401: + switch { + case utils.MatchContentType(contentType, `application/json`): + var out operations.GetPlaylistResponseBody + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + res.Object = &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", contentType), httpRes.StatusCode, string(rawBody), httpRes) + } + } + + return res, nil +} + +// DeletePlaylist - Deletes a Playlist +// This endpoint will delete a playlist +func (s *Playlists) DeletePlaylist(ctx context.Context, request operations.DeletePlaylistRequest) (*operations.DeletePlaylistResponse, error) { + baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) + url, err := utils.GenerateURL(ctx, baseURL, "/playlists/{playlistID}", request, nil) + if err != nil { + return nil, fmt.Errorf("error generating URL: %w", err) + } + + req, err := http.NewRequestWithContext(ctx, "DELETE", url, 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) + + client := s.sdkConfiguration.SecurityClient + + httpRes, err := client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %w", err) + } + if httpRes == nil { + return nil, fmt.Errorf("error sending request: no response") + } + + 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)) + + contentType := httpRes.Header.Get("Content-Type") + + res := &operations.DeletePlaylistResponse{ + StatusCode: httpRes.StatusCode, + ContentType: contentType, + RawResponse: httpRes, + } + switch { + case httpRes.StatusCode == 200: + fallthrough + case httpRes.StatusCode == 400: + case httpRes.StatusCode == 401: + switch { + case utils.MatchContentType(contentType, `application/json`): + var out operations.DeletePlaylistResponseBody + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + res.Object = &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", contentType), httpRes.StatusCode, string(rawBody), httpRes) + } + } + + return res, nil +} + +// UpdatePlaylist - Update a Playlist +// From PMS version 1.9.1 clients can also edit playlist metadata using this endpoint as they would via `PUT /library/metadata/{playlistID}` +func (s *Playlists) UpdatePlaylist(ctx context.Context, request operations.UpdatePlaylistRequest) (*operations.UpdatePlaylistResponse, error) { + baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) + url, err := utils.GenerateURL(ctx, baseURL, "/playlists/{playlistID}", request, nil) + if err != nil { + return nil, fmt.Errorf("error generating URL: %w", err) + } + + req, err := http.NewRequestWithContext(ctx, "PUT", url, 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) + + client := s.sdkConfiguration.SecurityClient + + httpRes, err := client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %w", err) + } + if httpRes == nil { + return nil, fmt.Errorf("error sending request: no response") + } + + 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)) + + contentType := httpRes.Header.Get("Content-Type") + + res := &operations.UpdatePlaylistResponse{ + StatusCode: httpRes.StatusCode, + ContentType: contentType, + RawResponse: httpRes, + } + switch { + case httpRes.StatusCode == 200: + fallthrough + case httpRes.StatusCode == 400: + case httpRes.StatusCode == 401: + switch { + case utils.MatchContentType(contentType, `application/json`): + var out operations.UpdatePlaylistResponseBody + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + res.Object = &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", contentType), httpRes.StatusCode, string(rawBody), httpRes) + } + } + + return res, nil +} + +// GetPlaylistContents - Retrieve Playlist Contents +// Gets the contents of a playlist. Should be paged by clients via standard mechanisms. +// By default leaves are returned (e.g. episodes, movies). In order to return other types you can use the `type` parameter. +// For example, you could use this to display a list of recently added albums vis a smart playlist. +// Note that for dumb playlists, items have a `playlistItemID` attribute which is used for deleting or moving items. +func (s *Playlists) GetPlaylistContents(ctx context.Context, request operations.GetPlaylistContentsRequest) (*operations.GetPlaylistContentsResponse, error) { + baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) + url, err := utils.GenerateURL(ctx, baseURL, "/playlists/{playlistID}/items", request, nil) + if err != nil { + return nil, fmt.Errorf("error generating URL: %w", err) + } + + req, err := http.NewRequestWithContext(ctx, "GET", url, 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) + } + + client := s.sdkConfiguration.SecurityClient + + httpRes, err := client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %w", err) + } + if httpRes == nil { + return nil, fmt.Errorf("error sending request: no response") + } + + 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)) + + contentType := httpRes.Header.Get("Content-Type") + + res := &operations.GetPlaylistContentsResponse{ + StatusCode: httpRes.StatusCode, + ContentType: contentType, + RawResponse: httpRes, + } + switch { + case httpRes.StatusCode == 200: + fallthrough + case httpRes.StatusCode == 400: + case httpRes.StatusCode == 401: + switch { + case utils.MatchContentType(contentType, `application/json`): + var out operations.GetPlaylistContentsResponseBody + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + res.Object = &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", contentType), httpRes.StatusCode, string(rawBody), httpRes) + } + } + + return res, nil +} + +// ClearPlaylistContents - Delete Playlist Contents +// Clears a playlist, only works with dumb playlists. Returns the playlist. +func (s *Playlists) ClearPlaylistContents(ctx context.Context, request operations.ClearPlaylistContentsRequest) (*operations.ClearPlaylistContentsResponse, error) { + baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) + url, err := utils.GenerateURL(ctx, baseURL, "/playlists/{playlistID}/items", request, nil) + if err != nil { + return nil, fmt.Errorf("error generating URL: %w", err) + } + + req, err := http.NewRequestWithContext(ctx, "DELETE", url, 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) + + client := s.sdkConfiguration.SecurityClient + + httpRes, err := client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %w", err) + } + if httpRes == nil { + return nil, fmt.Errorf("error sending request: no response") + } + + 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)) + + contentType := httpRes.Header.Get("Content-Type") + + res := &operations.ClearPlaylistContentsResponse{ + StatusCode: httpRes.StatusCode, + ContentType: contentType, + RawResponse: httpRes, + } + switch { + case httpRes.StatusCode == 200: + fallthrough + case httpRes.StatusCode == 400: + case httpRes.StatusCode == 401: + switch { + case utils.MatchContentType(contentType, `application/json`): + var out operations.ClearPlaylistContentsResponseBody + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + res.Object = &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", contentType), httpRes.StatusCode, string(rawBody), httpRes) + } + } + + return res, nil +} + +// AddPlaylistContents - Adding to a Playlist +// Adds a generator to a playlist, same parameters as the POST above. With a dumb playlist, this adds the specified items to the playlist. +// With a smart playlist, passing a new `uri` parameter replaces the rules for the playlist. Returns the playlist. +func (s *Playlists) AddPlaylistContents(ctx context.Context, request operations.AddPlaylistContentsRequest) (*operations.AddPlaylistContentsResponse, error) { + baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) + url, err := utils.GenerateURL(ctx, baseURL, "/playlists/{playlistID}/items", request, nil) + if err != nil { + return nil, fmt.Errorf("error generating URL: %w", err) + } + + req, err := http.NewRequestWithContext(ctx, "PUT", url, 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) + } + + client := s.sdkConfiguration.SecurityClient + + httpRes, err := client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %w", err) + } + if httpRes == nil { + return nil, fmt.Errorf("error sending request: no response") + } + + 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)) + + contentType := httpRes.Header.Get("Content-Type") + + res := &operations.AddPlaylistContentsResponse{ + StatusCode: httpRes.StatusCode, + ContentType: contentType, + RawResponse: httpRes, + } + switch { + case httpRes.StatusCode == 200: + fallthrough + case httpRes.StatusCode == 400: + case httpRes.StatusCode == 401: + switch { + case utils.MatchContentType(contentType, `application/json`): + var out operations.AddPlaylistContentsResponseBody + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + res.Object = &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", contentType), httpRes.StatusCode, string(rawBody), httpRes) + } + } + + return res, nil +} + +// UploadPlaylist - Upload Playlist +// Imports m3u playlists by passing a path on the server to scan for m3u-formatted playlist files, or a path to a single playlist file. +func (s *Playlists) UploadPlaylist(ctx context.Context, request operations.UploadPlaylistRequest) (*operations.UploadPlaylistResponse, error) { + baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) + url := strings.TrimSuffix(baseURL, "/") + "/playlists/upload" + + req, err := http.NewRequestWithContext(ctx, "POST", url, 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) + } + + client := s.sdkConfiguration.SecurityClient + + httpRes, err := client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %w", err) + } + if httpRes == nil { + return nil, fmt.Errorf("error sending request: no response") + } + + 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)) + + contentType := httpRes.Header.Get("Content-Type") + + res := &operations.UploadPlaylistResponse{ + StatusCode: httpRes.StatusCode, + ContentType: contentType, + RawResponse: httpRes, + } + switch { + case httpRes.StatusCode == 200: + fallthrough + case httpRes.StatusCode == 400: + case httpRes.StatusCode == 401: + switch { + case utils.MatchContentType(contentType, `application/json`): + var out operations.UploadPlaylistResponseBody + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + res.Object = &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", contentType), httpRes.StatusCode, string(rawBody), httpRes) + } + } + + return res, nil +} diff --git a/internal/sdk/sdk.go b/internal/sdk/sdk.go new file mode 100644 index 0000000..14cd4e4 --- /dev/null +++ b/internal/sdk/sdk.go @@ -0,0 +1,320 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package sdk + +import ( + "context" + "encoding/json" + "fmt" + "github.com/LukeHagar/terraform-provider-PlexAPI/internal/sdk/pkg/models/shared" + "github.com/LukeHagar/terraform-provider-PlexAPI/internal/sdk/pkg/utils" + "net/http" + "time" +) + +// ServerList contains the list of servers available to the SDK +var ServerList = []string{ + // The full address of your Plex Server + "http://10.10.10.47:32400", + // The full address of your Plex Server + "{protocol}://{ip}:{port}", +} + +// 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 { + DefaultClient HTTPClient + SecurityClient HTTPClient + Security func(context.Context) (interface{}, error) + ServerURL string + ServerIndex int + ServerDefaults []map[string]string + Language string + OpenAPIDocVersion string + SDKVersion string + GenVersion string + UserAgent string + RetryConfig *utils.RetryConfig +} + +func (c *sdkConfiguration) GetServerDetails() (string, map[string]string) { + if c.ServerURL != "" { + return c.ServerURL, nil + } + + return ServerList[c.ServerIndex], c.ServerDefaults[c.ServerIndex] +} + +// PlexAPI - Plex-API: A Plex Media Server API Map +// An Open API Spec for interacting with Plex.tv and Plex Servers +type PlexAPI struct { + // Operations against the Plex Media Server System. + // + Server *Server + // API Calls interacting with Plex Media Server Media + // + Media *Media + // Activities are awesome. They provide a way to monitor and control asynchronous operations on the server. In order to receive real-time updates for activities, a client would normally subscribe via either EventSource or Websocket endpoints. + // Activities are associated with HTTP replies via a special `X-Plex-Activity` header which contains the UUID of the activity. + // Activities are optional cancellable. If cancellable, they may be cancelled via the `DELETE` endpoint. Other details: + // - They can contain a `progress` (from 0 to 100) marking the percent completion of the activity. + // - They must contain an `type` which is used by clients to distinguish the specific activity. + // - They may contain a `Context` object with attributes which associate the activity with various specific entities (items, libraries, etc.) + // - The may contain a `Response` object which attributes which represent the result of the asynchronous operation. + // + Activities *Activities + // Butler is the task manager of the Plex Media Server Ecosystem. + // + Butler *Butler + // Hubs are a structured two-dimensional container for media, generally represented by multiple horizontal rows. + // + Hubs *Hubs + // API Calls that perform search operations with Plex Media Server + // + Search *Search + // API Calls interacting with Plex Media Server Libraries + // + Library *Library + // Submit logs to the Log Handler for Plex Media Server + // + Log *Log + // Playlists are ordered collections of media. They can be dumb (just a list of media) or smart (based on a media query, such as "all albums from 2017"). + // They can be organized in (optionally nesting) folders. + // Retrieving a playlist, or its items, will trigger a refresh of its metadata. + // This may cause the duration and number of items to change. + // + Playlists *Playlists + // API Calls against Security for Plex Media Server + // + Security *Security + // API Calls that perform search operations with Plex Media Server Sessions + // + Sessions *Sessions + // This describes the API for searching and applying updates to the Plex Media Server. + // Updates to the status can be observed via the Event API. + // + Updater *Updater + // API Calls that perform operations with Plex Media Server Videos + // + Video *Video + + sdkConfiguration sdkConfiguration +} + +type SDKOption func(*PlexAPI) + +// WithServerURL allows the overriding of the default server URL +func WithServerURL(serverURL string) SDKOption { + return func(sdk *PlexAPI) { + 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 *PlexAPI) { + 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 *PlexAPI) { + if serverIndex < 0 || serverIndex >= len(ServerList) { + panic(fmt.Errorf("server index %d out of range", serverIndex)) + } + + sdk.sdkConfiguration.ServerIndex = serverIndex + } +} + +// ServerProtocol - The protocol to use when connecting to your plex server. +type ServerProtocol string + +const ( + ServerProtocolHTTP ServerProtocol = "http" + ServerProtocolHTTPS ServerProtocol = "https" +) + +func (e ServerProtocol) ToPointer() *ServerProtocol { + return &e +} + +func (e *ServerProtocol) UnmarshalJSON(data []byte) error { + var v string + if err := json.Unmarshal(data, &v); err != nil { + return err + } + switch v { + case "http": + fallthrough + case "https": + *e = ServerProtocol(v) + return nil + default: + return fmt.Errorf("invalid value for ServerProtocol: %v", v) + } +} + +// WithProtocol allows setting the protocol variable for url substitution +func WithProtocol(protocol ServerProtocol) SDKOption { + return func(sdk *PlexAPI) { + for idx := range sdk.sdkConfiguration.ServerDefaults { + if _, ok := sdk.sdkConfiguration.ServerDefaults[idx]["protocol"]; !ok { + continue + } + + sdk.sdkConfiguration.ServerDefaults[idx]["protocol"] = fmt.Sprintf("%v", protocol) + } + } +} + +// WithIP allows setting the ip variable for url substitution +func WithIP(ip string) SDKOption { + return func(sdk *PlexAPI) { + for idx := range sdk.sdkConfiguration.ServerDefaults { + if _, ok := sdk.sdkConfiguration.ServerDefaults[idx]["ip"]; !ok { + continue + } + + sdk.sdkConfiguration.ServerDefaults[idx]["ip"] = fmt.Sprintf("%v", ip) + } + } +} + +// WithPort allows setting the port variable for url substitution +func WithPort(port string) SDKOption { + return func(sdk *PlexAPI) { + for idx := range sdk.sdkConfiguration.ServerDefaults { + if _, ok := sdk.sdkConfiguration.ServerDefaults[idx]["port"]; !ok { + continue + } + + sdk.sdkConfiguration.ServerDefaults[idx]["port"] = fmt.Sprintf("%v", port) + } + } +} + +// WithClient allows the overriding of the default HTTP client used by the SDK +func WithClient(client HTTPClient) SDKOption { + return func(sdk *PlexAPI) { + sdk.sdkConfiguration.DefaultClient = 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(security shared.Security) SDKOption { + return func(sdk *PlexAPI) { + 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) (shared.Security, error)) SDKOption { + return func(sdk *PlexAPI) { + sdk.sdkConfiguration.Security = func(ctx context.Context) (interface{}, error) { + return security(ctx) + } + } +} + +func WithRetryConfig(retryConfig utils.RetryConfig) SDKOption { + return func(sdk *PlexAPI) { + sdk.sdkConfiguration.RetryConfig = &retryConfig + } +} + +// New creates a new instance of the SDK with the provided options +func New(opts ...SDKOption) *PlexAPI { + sdk := &PlexAPI{ + sdkConfiguration: sdkConfiguration{ + Language: "go", + OpenAPIDocVersion: "0.0.3", + SDKVersion: "0.1.0", + GenVersion: "2.223.3", + UserAgent: "speakeasy-sdk/go 0.1.0 2.223.3 0.0.3 PlexAPI", + ServerDefaults: []map[string]string{ + {}, + { + "protocol": "http", + "ip": "10.10.10.47", + "port": "32400", + }, + }, + }, + } + for _, opt := range opts { + opt(sdk) + } + + // Use WithClient to override the default client if you would like to customize the timeout + if sdk.sdkConfiguration.DefaultClient == nil { + sdk.sdkConfiguration.DefaultClient = &http.Client{Timeout: 60 * time.Second} + } + if sdk.sdkConfiguration.SecurityClient == nil { + if sdk.sdkConfiguration.Security != nil { + sdk.sdkConfiguration.SecurityClient = utils.ConfigureSecurityClient(sdk.sdkConfiguration.DefaultClient, sdk.sdkConfiguration.Security) + } else { + sdk.sdkConfiguration.SecurityClient = sdk.sdkConfiguration.DefaultClient + } + } + + sdk.Server = newServer(sdk.sdkConfiguration) + + sdk.Media = newMedia(sdk.sdkConfiguration) + + sdk.Activities = newActivities(sdk.sdkConfiguration) + + sdk.Butler = newButler(sdk.sdkConfiguration) + + sdk.Hubs = newHubs(sdk.sdkConfiguration) + + sdk.Search = newSearch(sdk.sdkConfiguration) + + sdk.Library = newLibrary(sdk.sdkConfiguration) + + sdk.Log = newLog(sdk.sdkConfiguration) + + sdk.Playlists = newPlaylists(sdk.sdkConfiguration) + + sdk.Security = newSecurity(sdk.sdkConfiguration) + + sdk.Sessions = newSessions(sdk.sdkConfiguration) + + sdk.Updater = newUpdater(sdk.sdkConfiguration) + + sdk.Video = newVideo(sdk.sdkConfiguration) + + return sdk +} diff --git a/internal/sdk/search.go b/internal/sdk/search.go new file mode 100644 index 0000000..79a959c --- /dev/null +++ b/internal/sdk/search.go @@ -0,0 +1,237 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package sdk + +import ( + "bytes" + "context" + "fmt" + "github.com/LukeHagar/terraform-provider-PlexAPI/internal/sdk/pkg/models/operations" + "github.com/LukeHagar/terraform-provider-PlexAPI/internal/sdk/pkg/models/sdkerrors" + "github.com/LukeHagar/terraform-provider-PlexAPI/internal/sdk/pkg/utils" + "io" + "net/http" + "strings" +) + +// Search - API Calls that perform search operations with Plex Media Server +type Search struct { + sdkConfiguration sdkConfiguration +} + +func newSearch(sdkConfig sdkConfiguration) *Search { + return &Search{ + sdkConfiguration: sdkConfig, + } +} + +// PerformSearch - Perform a search +// This endpoint performs a search across all library sections, or a single section, and returns matches as hubs, split up by type. It performs spell checking, looks for partial matches, and orders the hubs based on quality of results. In addition, based on matches, it will return other related matches (e.g. for a genre match, it may return movies in that genre, or for an actor match, movies with that actor). +// +// In the response's items, the following extra attributes are returned to further describe or disambiguate the result: +// +// - `reason`: The reason for the result, if not because of a direct search term match; can be either: +// - `section`: There are multiple identical results from different sections. +// - `originalTitle`: There was a search term match from the original title field (sometimes those can be very different or in a foreign language). +// - ``: If the reason for the result is due to a result in another hub, the source hub identifier is returned. For example, if the search is for "dylan" then Bob Dylan may be returned as an artist result, an a few of his albums returned as album results with a reason code of `artist` (the identifier of that particular hub). Or if the search is for "arnold", there might be movie results returned with a reason of `actor` +// +// - `reasonTitle`: The string associated with the reason code. For a section reason, it'll be the section name; For a hub identifier, it'll be a string associated with the match (e.g. `Arnold Schwarzenegger` for movies which were returned because the search was for "arnold"). +// - `reasonID`: The ID of the item associated with the reason for the result. This might be a section ID, a tag ID, an artist ID, or a show ID. +// +// This request is intended to be very fast, and called as the user types. +func (s *Search) PerformSearch(ctx context.Context, request operations.PerformSearchRequest) (*operations.PerformSearchResponse, error) { + baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) + url := strings.TrimSuffix(baseURL, "/") + "/hubs/search" + + req, err := http.NewRequestWithContext(ctx, "GET", url, 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) + } + + client := s.sdkConfiguration.SecurityClient + + httpRes, err := client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %w", err) + } + if httpRes == nil { + return nil, fmt.Errorf("error sending request: no response") + } + + 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)) + + contentType := httpRes.Header.Get("Content-Type") + + res := &operations.PerformSearchResponse{ + StatusCode: httpRes.StatusCode, + ContentType: contentType, + RawResponse: httpRes, + } + switch { + case httpRes.StatusCode == 200: + fallthrough + case httpRes.StatusCode == 400: + case httpRes.StatusCode == 401: + switch { + case utils.MatchContentType(contentType, `application/json`): + var out operations.PerformSearchResponseBody + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + res.Object = &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", contentType), httpRes.StatusCode, string(rawBody), httpRes) + } + } + + return res, nil +} + +// PerformVoiceSearch - Perform a voice search +// This endpoint performs a search specifically tailored towards voice or other imprecise input which may work badly with the substring and spell-checking heuristics used by the `/hubs/search` endpoint. +// It uses a [Levenshtein distance](https://en.wikipedia.org/wiki/Levenshtein_distance) heuristic to search titles, and as such is much slower than the other search endpoint. +// Whenever possible, clients should limit the search to the appropriate type. +// Results, as well as their containing per-type hubs, contain a `distance` attribute which can be used to judge result quality. +func (s *Search) PerformVoiceSearch(ctx context.Context, request operations.PerformVoiceSearchRequest) (*operations.PerformVoiceSearchResponse, error) { + baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) + url := strings.TrimSuffix(baseURL, "/") + "/hubs/search/voice" + + req, err := http.NewRequestWithContext(ctx, "GET", url, 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) + } + + client := s.sdkConfiguration.SecurityClient + + httpRes, err := client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %w", err) + } + if httpRes == nil { + return nil, fmt.Errorf("error sending request: no response") + } + + 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)) + + contentType := httpRes.Header.Get("Content-Type") + + res := &operations.PerformVoiceSearchResponse{ + StatusCode: httpRes.StatusCode, + ContentType: contentType, + RawResponse: httpRes, + } + switch { + case httpRes.StatusCode == 200: + fallthrough + case httpRes.StatusCode == 400: + case httpRes.StatusCode == 401: + switch { + case utils.MatchContentType(contentType, `application/json`): + var out operations.PerformVoiceSearchResponseBody + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + res.Object = &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", contentType), httpRes.StatusCode, string(rawBody), httpRes) + } + } + + return res, nil +} + +// GetSearchResults - Get Search Results +// This will search the database for the string provided. +func (s *Search) GetSearchResults(ctx context.Context, request operations.GetSearchResultsRequest) (*operations.GetSearchResultsResponse, error) { + baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) + url := strings.TrimSuffix(baseURL, "/") + "/search" + + req, err := http.NewRequestWithContext(ctx, "GET", url, 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) + } + + client := s.sdkConfiguration.SecurityClient + + httpRes, err := client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %w", err) + } + if httpRes == nil { + return nil, fmt.Errorf("error sending request: no response") + } + + 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)) + + contentType := httpRes.Header.Get("Content-Type") + + res := &operations.GetSearchResultsResponse{ + StatusCode: httpRes.StatusCode, + ContentType: contentType, + RawResponse: httpRes, + } + switch { + case httpRes.StatusCode == 200: + switch { + case utils.MatchContentType(contentType, `application/json`): + var out operations.GetSearchResultsResponseBody + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + res.TwoHundredApplicationJSONObject = &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", contentType), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 400: + case httpRes.StatusCode == 401: + switch { + case utils.MatchContentType(contentType, `application/json`): + var out operations.GetSearchResultsSearchResponseBody + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + res.FourHundredAndOneApplicationJSONObject = &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", contentType), httpRes.StatusCode, string(rawBody), httpRes) + } + } + + return res, nil +} diff --git a/internal/sdk/security.go b/internal/sdk/security.go new file mode 100644 index 0000000..c8f55fc --- /dev/null +++ b/internal/sdk/security.go @@ -0,0 +1,151 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package sdk + +import ( + "bytes" + "context" + "fmt" + "github.com/LukeHagar/terraform-provider-PlexAPI/internal/sdk/pkg/models/operations" + "github.com/LukeHagar/terraform-provider-PlexAPI/internal/sdk/pkg/models/sdkerrors" + "github.com/LukeHagar/terraform-provider-PlexAPI/internal/sdk/pkg/utils" + "io" + "net/http" + "strings" +) + +// Security - API Calls against Security for Plex Media Server +type Security struct { + sdkConfiguration sdkConfiguration +} + +func newSecurity(sdkConfig sdkConfiguration) *Security { + return &Security{ + sdkConfiguration: sdkConfig, + } +} + +// GetTransientToken - Get a Transient Token. +// This endpoint provides the caller with a temporary token with the same access level as the caller's token. These tokens are valid for up to 48 hours and are destroyed if the server instance is restarted. +func (s *Security) GetTransientToken(ctx context.Context, request operations.GetTransientTokenRequest) (*operations.GetTransientTokenResponse, error) { + baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) + url := strings.TrimSuffix(baseURL, "/") + "/security/token" + + req, err := http.NewRequestWithContext(ctx, "GET", url, 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) + } + + client := s.sdkConfiguration.SecurityClient + + httpRes, err := client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %w", err) + } + if httpRes == nil { + return nil, fmt.Errorf("error sending request: no response") + } + + 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)) + + contentType := httpRes.Header.Get("Content-Type") + + res := &operations.GetTransientTokenResponse{ + StatusCode: httpRes.StatusCode, + ContentType: contentType, + RawResponse: httpRes, + } + switch { + case httpRes.StatusCode == 200: + fallthrough + case httpRes.StatusCode == 400: + case httpRes.StatusCode == 401: + switch { + case utils.MatchContentType(contentType, `application/json`): + var out operations.GetTransientTokenResponseBody + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + res.Object = &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", contentType), httpRes.StatusCode, string(rawBody), httpRes) + } + } + + return res, nil +} + +// GetSourceConnectionInformation - Get Source Connection Information +// If a caller requires connection details and a transient token for a source that is known to the server, for example a cloud media provider or shared PMS, then this endpoint can be called. This endpoint is only accessible with either an admin token or a valid transient token generated from an admin token. +// Note: requires Plex Media Server >= 1.15.4. +func (s *Security) GetSourceConnectionInformation(ctx context.Context, request operations.GetSourceConnectionInformationRequest) (*operations.GetSourceConnectionInformationResponse, error) { + baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) + url := strings.TrimSuffix(baseURL, "/") + "/security/resources" + + req, err := http.NewRequestWithContext(ctx, "GET", url, 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) + } + + client := s.sdkConfiguration.SecurityClient + + httpRes, err := client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %w", err) + } + if httpRes == nil { + return nil, fmt.Errorf("error sending request: no response") + } + + 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)) + + contentType := httpRes.Header.Get("Content-Type") + + res := &operations.GetSourceConnectionInformationResponse{ + StatusCode: httpRes.StatusCode, + ContentType: contentType, + RawResponse: httpRes, + } + switch { + case httpRes.StatusCode == 200: + fallthrough + case httpRes.StatusCode == 400: + case httpRes.StatusCode == 401: + switch { + case utils.MatchContentType(contentType, `application/json`): + var out operations.GetSourceConnectionInformationResponseBody + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + res.Object = &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", contentType), httpRes.StatusCode, string(rawBody), httpRes) + } + } + + return res, nil +} diff --git a/internal/sdk/server.go b/internal/sdk/server.go new file mode 100644 index 0000000..215dbd6 --- /dev/null +++ b/internal/sdk/server.go @@ -0,0 +1,554 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package sdk + +import ( + "bytes" + "context" + "fmt" + "github.com/LukeHagar/terraform-provider-PlexAPI/internal/sdk/pkg/models/operations" + "github.com/LukeHagar/terraform-provider-PlexAPI/internal/sdk/pkg/models/sdkerrors" + "github.com/LukeHagar/terraform-provider-PlexAPI/internal/sdk/pkg/utils" + "io" + "net/http" + "strings" +) + +// Server - Operations against the Plex Media Server System. +type Server struct { + sdkConfiguration sdkConfiguration +} + +func newServer(sdkConfig sdkConfiguration) *Server { + return &Server{ + sdkConfiguration: sdkConfig, + } +} + +// GetServerCapabilities - Server Capabilities +// Server Capabilities +func (s *Server) GetServerCapabilities(ctx context.Context) (*operations.GetServerCapabilitiesResponse, error) { + baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) + url := strings.TrimSuffix(baseURL, "/") + "/" + + req, err := http.NewRequestWithContext(ctx, "GET", url, 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) + + client := s.sdkConfiguration.SecurityClient + + httpRes, err := client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %w", err) + } + if httpRes == nil { + return nil, fmt.Errorf("error sending request: no response") + } + + 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)) + + contentType := httpRes.Header.Get("Content-Type") + + res := &operations.GetServerCapabilitiesResponse{ + StatusCode: httpRes.StatusCode, + ContentType: contentType, + RawResponse: httpRes, + } + switch { + case httpRes.StatusCode == 200: + switch { + case utils.MatchContentType(contentType, `application/json`): + var out operations.GetServerCapabilitiesResponseBody + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + res.TwoHundredApplicationJSONObject = &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", contentType), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 400: + case httpRes.StatusCode == 401: + switch { + case utils.MatchContentType(contentType, `application/json`): + var out operations.GetServerCapabilitiesServerResponseBody + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + res.FourHundredAndOneApplicationJSONObject = &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", contentType), httpRes.StatusCode, string(rawBody), httpRes) + } + } + + return res, nil +} + +// GetServerPreferences - Get Server Preferences +// Get Server Preferences +func (s *Server) GetServerPreferences(ctx context.Context) (*operations.GetServerPreferencesResponse, error) { + baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) + url := strings.TrimSuffix(baseURL, "/") + "/:/prefs" + + req, err := http.NewRequestWithContext(ctx, "GET", url, 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) + + client := s.sdkConfiguration.SecurityClient + + httpRes, err := client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %w", err) + } + if httpRes == nil { + return nil, fmt.Errorf("error sending request: no response") + } + + 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)) + + contentType := httpRes.Header.Get("Content-Type") + + res := &operations.GetServerPreferencesResponse{ + StatusCode: httpRes.StatusCode, + ContentType: contentType, + RawResponse: httpRes, + } + switch { + case httpRes.StatusCode == 200: + fallthrough + case httpRes.StatusCode == 400: + case httpRes.StatusCode == 401: + switch { + case utils.MatchContentType(contentType, `application/json`): + var out operations.GetServerPreferencesResponseBody + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + res.Object = &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", contentType), httpRes.StatusCode, string(rawBody), httpRes) + } + } + + return res, nil +} + +// GetAvailableClients - Get Available Clients +// Get Available Clients +func (s *Server) GetAvailableClients(ctx context.Context) (*operations.GetAvailableClientsResponse, error) { + baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) + url := strings.TrimSuffix(baseURL, "/") + "/clients" + + req, err := http.NewRequestWithContext(ctx, "GET", url, 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) + + client := s.sdkConfiguration.SecurityClient + + httpRes, err := client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %w", err) + } + if httpRes == nil { + return nil, fmt.Errorf("error sending request: no response") + } + + 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)) + + contentType := httpRes.Header.Get("Content-Type") + + res := &operations.GetAvailableClientsResponse{ + StatusCode: httpRes.StatusCode, + ContentType: contentType, + RawResponse: httpRes, + } + switch { + case httpRes.StatusCode == 200: + switch { + case utils.MatchContentType(contentType, `application/json`): + var out []operations.ResponseBody + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + res.ResponseBodies = out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", contentType), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 400: + case httpRes.StatusCode == 401: + switch { + case utils.MatchContentType(contentType, `application/json`): + var out operations.GetAvailableClientsResponseBody + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + res.Object = &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", contentType), httpRes.StatusCode, string(rawBody), httpRes) + } + } + + return res, nil +} + +// GetDevices - Get Devices +// Get Devices +func (s *Server) GetDevices(ctx context.Context) (*operations.GetDevicesResponse, error) { + baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) + url := strings.TrimSuffix(baseURL, "/") + "/devices" + + req, err := http.NewRequestWithContext(ctx, "GET", url, 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) + + client := s.sdkConfiguration.SecurityClient + + httpRes, err := client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %w", err) + } + if httpRes == nil { + return nil, fmt.Errorf("error sending request: no response") + } + + 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)) + + contentType := httpRes.Header.Get("Content-Type") + + res := &operations.GetDevicesResponse{ + StatusCode: httpRes.StatusCode, + ContentType: contentType, + RawResponse: httpRes, + } + switch { + case httpRes.StatusCode == 200: + switch { + case utils.MatchContentType(contentType, `application/json`): + var out operations.GetDevicesResponseBody + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + res.TwoHundredApplicationJSONObject = &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", contentType), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 400: + case httpRes.StatusCode == 401: + switch { + case utils.MatchContentType(contentType, `application/json`): + var out operations.GetDevicesServerResponseBody + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + res.FourHundredAndOneApplicationJSONObject = &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", contentType), httpRes.StatusCode, string(rawBody), httpRes) + } + } + + return res, nil +} + +// GetServerIdentity - Get Server Identity +// Get Server Identity +func (s *Server) GetServerIdentity(ctx context.Context) (*operations.GetServerIdentityResponse, error) { + baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) + url := strings.TrimSuffix(baseURL, "/") + "/identity" + + req, err := http.NewRequestWithContext(ctx, "GET", url, 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) + + client := s.sdkConfiguration.SecurityClient + + httpRes, err := client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %w", err) + } + if httpRes == nil { + return nil, fmt.Errorf("error sending request: no response") + } + + 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)) + + contentType := httpRes.Header.Get("Content-Type") + + res := &operations.GetServerIdentityResponse{ + StatusCode: httpRes.StatusCode, + ContentType: contentType, + RawResponse: httpRes, + } + switch { + case httpRes.StatusCode == 200: + switch { + case utils.MatchContentType(contentType, `application/json`): + var out operations.GetServerIdentityResponseBody + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + res.TwoHundredApplicationJSONObject = &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", contentType), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 400: + case httpRes.StatusCode == 401: + switch { + case utils.MatchContentType(contentType, `application/json`): + var out operations.GetServerIdentityServerResponseBody + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + res.FourHundredAndOneApplicationJSONObject = &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", contentType), httpRes.StatusCode, string(rawBody), httpRes) + } + } + + return res, nil +} + +// GetMyPlexAccount - Get MyPlex Account +// Returns MyPlex Account Information +func (s *Server) GetMyPlexAccount(ctx context.Context) (*operations.GetMyPlexAccountResponse, error) { + baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) + url := strings.TrimSuffix(baseURL, "/") + "/myplex/account" + + req, err := http.NewRequestWithContext(ctx, "GET", url, 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) + + client := s.sdkConfiguration.SecurityClient + + httpRes, err := client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %w", err) + } + if httpRes == nil { + return nil, fmt.Errorf("error sending request: no response") + } + + 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)) + + contentType := httpRes.Header.Get("Content-Type") + + res := &operations.GetMyPlexAccountResponse{ + StatusCode: httpRes.StatusCode, + ContentType: contentType, + RawResponse: httpRes, + } + switch { + case httpRes.StatusCode == 200: + switch { + case utils.MatchContentType(contentType, `application/json`): + var out operations.GetMyPlexAccountResponseBody + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + res.TwoHundredApplicationJSONObject = &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", contentType), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 400: + case httpRes.StatusCode == 401: + switch { + case utils.MatchContentType(contentType, `application/json`): + var out operations.GetMyPlexAccountServerResponseBody + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + res.FourHundredAndOneApplicationJSONObject = &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", contentType), httpRes.StatusCode, string(rawBody), httpRes) + } + } + + return res, nil +} + +// GetResizedPhoto - Get a Resized Photo +// Plex's Photo transcoder is used throughout the service to serve images at specified sizes. +func (s *Server) GetResizedPhoto(ctx context.Context, request operations.GetResizedPhotoRequest) (*operations.GetResizedPhotoResponse, error) { + baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) + url := strings.TrimSuffix(baseURL, "/") + "/photo/:/transcode" + + req, err := http.NewRequestWithContext(ctx, "GET", url, 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) + } + + client := s.sdkConfiguration.SecurityClient + + httpRes, err := client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %w", err) + } + if httpRes == nil { + return nil, fmt.Errorf("error sending request: no response") + } + + 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)) + + contentType := httpRes.Header.Get("Content-Type") + + res := &operations.GetResizedPhotoResponse{ + StatusCode: httpRes.StatusCode, + ContentType: contentType, + RawResponse: httpRes, + } + switch { + case httpRes.StatusCode == 200: + fallthrough + case httpRes.StatusCode == 400: + case httpRes.StatusCode == 401: + switch { + case utils.MatchContentType(contentType, `application/json`): + var out operations.GetResizedPhotoResponseBody + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + res.Object = &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", contentType), httpRes.StatusCode, string(rawBody), httpRes) + } + } + + return res, nil +} + +// GetServerList - Get Server List +// Get Server List +func (s *Server) GetServerList(ctx context.Context) (*operations.GetServerListResponse, error) { + baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) + url := strings.TrimSuffix(baseURL, "/") + "/servers" + + req, err := http.NewRequestWithContext(ctx, "GET", url, 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) + + client := s.sdkConfiguration.SecurityClient + + httpRes, err := client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %w", err) + } + if httpRes == nil { + return nil, fmt.Errorf("error sending request: no response") + } + + 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)) + + contentType := httpRes.Header.Get("Content-Type") + + res := &operations.GetServerListResponse{ + StatusCode: httpRes.StatusCode, + ContentType: contentType, + RawResponse: httpRes, + } + switch { + case httpRes.StatusCode == 200: + switch { + case utils.MatchContentType(contentType, `application/json`): + var out operations.GetServerListResponseBody + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + res.TwoHundredApplicationJSONObject = &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", contentType), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 400: + case httpRes.StatusCode == 401: + switch { + case utils.MatchContentType(contentType, `application/json`): + var out operations.GetServerListServerResponseBody + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + res.FourHundredAndOneApplicationJSONObject = &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", contentType), httpRes.StatusCode, string(rawBody), httpRes) + } + } + + return res, nil +} diff --git a/internal/sdk/sessions.go b/internal/sdk/sessions.go new file mode 100644 index 0000000..d8e6072 --- /dev/null +++ b/internal/sdk/sessions.go @@ -0,0 +1,271 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package sdk + +import ( + "bytes" + "context" + "fmt" + "github.com/LukeHagar/terraform-provider-PlexAPI/internal/sdk/pkg/models/operations" + "github.com/LukeHagar/terraform-provider-PlexAPI/internal/sdk/pkg/models/sdkerrors" + "github.com/LukeHagar/terraform-provider-PlexAPI/internal/sdk/pkg/utils" + "io" + "net/http" + "strings" +) + +// Sessions - API Calls that perform search operations with Plex Media Server Sessions +type Sessions struct { + sdkConfiguration sdkConfiguration +} + +func newSessions(sdkConfig sdkConfiguration) *Sessions { + return &Sessions{ + sdkConfiguration: sdkConfig, + } +} + +// GetSessions - Get Active Sessions +// This will retrieve the "Now Playing" Information of the PMS. +func (s *Sessions) GetSessions(ctx context.Context) (*operations.GetSessionsResponse, error) { + baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) + url := strings.TrimSuffix(baseURL, "/") + "/status/sessions" + + req, err := http.NewRequestWithContext(ctx, "GET", url, 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) + + client := s.sdkConfiguration.SecurityClient + + httpRes, err := client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %w", err) + } + if httpRes == nil { + return nil, fmt.Errorf("error sending request: no response") + } + + 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)) + + contentType := httpRes.Header.Get("Content-Type") + + res := &operations.GetSessionsResponse{ + StatusCode: httpRes.StatusCode, + ContentType: contentType, + RawResponse: httpRes, + } + switch { + case httpRes.StatusCode == 200: + fallthrough + case httpRes.StatusCode == 400: + case httpRes.StatusCode == 401: + switch { + case utils.MatchContentType(contentType, `application/json`): + var out operations.GetSessionsResponseBody + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + res.Object = &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", contentType), httpRes.StatusCode, string(rawBody), httpRes) + } + } + + return res, nil +} + +// GetSessionHistory - Get Session History +// This will Retrieve a listing of all history views. +func (s *Sessions) GetSessionHistory(ctx context.Context) (*operations.GetSessionHistoryResponse, error) { + baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) + url := strings.TrimSuffix(baseURL, "/") + "/status/sessions/history/all" + + req, err := http.NewRequestWithContext(ctx, "GET", url, 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) + + client := s.sdkConfiguration.SecurityClient + + httpRes, err := client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %w", err) + } + if httpRes == nil { + return nil, fmt.Errorf("error sending request: no response") + } + + 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)) + + contentType := httpRes.Header.Get("Content-Type") + + res := &operations.GetSessionHistoryResponse{ + StatusCode: httpRes.StatusCode, + ContentType: contentType, + RawResponse: httpRes, + } + switch { + case httpRes.StatusCode == 200: + fallthrough + case httpRes.StatusCode == 400: + case httpRes.StatusCode == 401: + switch { + case utils.MatchContentType(contentType, `application/json`): + var out operations.GetSessionHistoryResponseBody + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + res.Object = &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", contentType), httpRes.StatusCode, string(rawBody), httpRes) + } + } + + return res, nil +} + +// GetTranscodeSessions - Get Transcode Sessions +// Get Transcode Sessions +func (s *Sessions) GetTranscodeSessions(ctx context.Context) (*operations.GetTranscodeSessionsResponse, error) { + baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) + url := strings.TrimSuffix(baseURL, "/") + "/transcode/sessions" + + req, err := http.NewRequestWithContext(ctx, "GET", url, 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) + + client := s.sdkConfiguration.SecurityClient + + httpRes, err := client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %w", err) + } + if httpRes == nil { + return nil, fmt.Errorf("error sending request: no response") + } + + 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)) + + contentType := httpRes.Header.Get("Content-Type") + + res := &operations.GetTranscodeSessionsResponse{ + StatusCode: httpRes.StatusCode, + ContentType: contentType, + RawResponse: httpRes, + } + switch { + case httpRes.StatusCode == 200: + switch { + case utils.MatchContentType(contentType, `application/json`): + var out operations.GetTranscodeSessionsResponseBody + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + res.TwoHundredApplicationJSONObject = &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", contentType), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 400: + case httpRes.StatusCode == 401: + switch { + case utils.MatchContentType(contentType, `application/json`): + var out operations.GetTranscodeSessionsSessionsResponseBody + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + res.FourHundredAndOneApplicationJSONObject = &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", contentType), httpRes.StatusCode, string(rawBody), httpRes) + } + } + + return res, nil +} + +// StopTranscodeSession - Stop a Transcode Session +// Stop a Transcode Session +func (s *Sessions) StopTranscodeSession(ctx context.Context, request operations.StopTranscodeSessionRequest) (*operations.StopTranscodeSessionResponse, error) { + baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) + url, err := utils.GenerateURL(ctx, baseURL, "/transcode/sessions/{sessionKey}", request, nil) + if err != nil { + return nil, fmt.Errorf("error generating URL: %w", err) + } + + req, err := http.NewRequestWithContext(ctx, "DELETE", url, 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) + + client := s.sdkConfiguration.SecurityClient + + httpRes, err := client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %w", err) + } + if httpRes == nil { + return nil, fmt.Errorf("error sending request: no response") + } + + 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)) + + contentType := httpRes.Header.Get("Content-Type") + + res := &operations.StopTranscodeSessionResponse{ + StatusCode: httpRes.StatusCode, + ContentType: contentType, + RawResponse: httpRes, + } + switch { + case httpRes.StatusCode == 200: + fallthrough + case httpRes.StatusCode == 400: + case httpRes.StatusCode == 401: + switch { + case utils.MatchContentType(contentType, `application/json`): + var out operations.StopTranscodeSessionResponseBody + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + res.Object = &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", contentType), httpRes.StatusCode, string(rawBody), httpRes) + } + } + + return res, nil +} diff --git a/internal/sdk/updater.go b/internal/sdk/updater.go new file mode 100644 index 0000000..3b3cd05 --- /dev/null +++ b/internal/sdk/updater.go @@ -0,0 +1,211 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package sdk + +import ( + "bytes" + "context" + "fmt" + "github.com/LukeHagar/terraform-provider-PlexAPI/internal/sdk/pkg/models/operations" + "github.com/LukeHagar/terraform-provider-PlexAPI/internal/sdk/pkg/models/sdkerrors" + "github.com/LukeHagar/terraform-provider-PlexAPI/internal/sdk/pkg/utils" + "io" + "net/http" + "strings" +) + +// Updater - This describes the API for searching and applying updates to the Plex Media Server. +// Updates to the status can be observed via the Event API. +type Updater struct { + sdkConfiguration sdkConfiguration +} + +func newUpdater(sdkConfig sdkConfiguration) *Updater { + return &Updater{ + sdkConfiguration: sdkConfig, + } +} + +// GetUpdateStatus - Querying status of updates +// Querying status of updates +func (s *Updater) GetUpdateStatus(ctx context.Context) (*operations.GetUpdateStatusResponse, error) { + baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) + url := strings.TrimSuffix(baseURL, "/") + "/updater/status" + + req, err := http.NewRequestWithContext(ctx, "GET", url, 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) + + client := s.sdkConfiguration.SecurityClient + + httpRes, err := client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %w", err) + } + if httpRes == nil { + return nil, fmt.Errorf("error sending request: no response") + } + + 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)) + + contentType := httpRes.Header.Get("Content-Type") + + res := &operations.GetUpdateStatusResponse{ + StatusCode: httpRes.StatusCode, + ContentType: contentType, + RawResponse: httpRes, + } + switch { + case httpRes.StatusCode == 200: + fallthrough + case httpRes.StatusCode == 400: + case httpRes.StatusCode == 401: + switch { + case utils.MatchContentType(contentType, `application/json`): + var out operations.GetUpdateStatusResponseBody + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + res.Object = &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", contentType), httpRes.StatusCode, string(rawBody), httpRes) + } + } + + return res, nil +} + +// CheckForUpdates - Checking for updates +// Checking for updates +func (s *Updater) CheckForUpdates(ctx context.Context, request operations.CheckForUpdatesRequest) (*operations.CheckForUpdatesResponse, error) { + baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) + url := strings.TrimSuffix(baseURL, "/") + "/updater/check" + + req, err := http.NewRequestWithContext(ctx, "PUT", url, 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) + } + + client := s.sdkConfiguration.SecurityClient + + httpRes, err := client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %w", err) + } + if httpRes == nil { + return nil, fmt.Errorf("error sending request: no response") + } + + 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)) + + contentType := httpRes.Header.Get("Content-Type") + + res := &operations.CheckForUpdatesResponse{ + StatusCode: httpRes.StatusCode, + ContentType: contentType, + RawResponse: httpRes, + } + switch { + case httpRes.StatusCode == 200: + fallthrough + case httpRes.StatusCode == 400: + case httpRes.StatusCode == 401: + switch { + case utils.MatchContentType(contentType, `application/json`): + var out operations.CheckForUpdatesResponseBody + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + res.Object = &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", contentType), httpRes.StatusCode, string(rawBody), httpRes) + } + } + + return res, nil +} + +// ApplyUpdates - Apply Updates +// Note that these two parameters are effectively mutually exclusive. The `tonight` parameter takes precedence and `skip` will be ignored if `tonight` is also passed +func (s *Updater) ApplyUpdates(ctx context.Context, request operations.ApplyUpdatesRequest) (*operations.ApplyUpdatesResponse, error) { + baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) + url := strings.TrimSuffix(baseURL, "/") + "/updater/apply" + + req, err := http.NewRequestWithContext(ctx, "PUT", url, 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) + } + + client := s.sdkConfiguration.SecurityClient + + httpRes, err := client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %w", err) + } + if httpRes == nil { + return nil, fmt.Errorf("error sending request: no response") + } + + 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)) + + contentType := httpRes.Header.Get("Content-Type") + + res := &operations.ApplyUpdatesResponse{ + StatusCode: httpRes.StatusCode, + ContentType: contentType, + RawResponse: httpRes, + } + switch { + case httpRes.StatusCode == 200: + fallthrough + case httpRes.StatusCode == 400: + fallthrough + case httpRes.StatusCode == 500: + case httpRes.StatusCode == 401: + switch { + case utils.MatchContentType(contentType, `application/json`): + var out operations.ApplyUpdatesResponseBody + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + res.Object = &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", contentType), httpRes.StatusCode, string(rawBody), httpRes) + } + } + + return res, nil +} diff --git a/internal/sdk/video.go b/internal/sdk/video.go new file mode 100644 index 0000000..0274f1f --- /dev/null +++ b/internal/sdk/video.go @@ -0,0 +1,150 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package sdk + +import ( + "bytes" + "context" + "fmt" + "github.com/LukeHagar/terraform-provider-PlexAPI/internal/sdk/pkg/models/operations" + "github.com/LukeHagar/terraform-provider-PlexAPI/internal/sdk/pkg/models/sdkerrors" + "github.com/LukeHagar/terraform-provider-PlexAPI/internal/sdk/pkg/utils" + "io" + "net/http" + "strings" +) + +// Video - API Calls that perform operations with Plex Media Server Videos +type Video struct { + sdkConfiguration sdkConfiguration +} + +func newVideo(sdkConfig sdkConfiguration) *Video { + return &Video{ + sdkConfiguration: sdkConfig, + } +} + +// StartUniversalTranscode - Start Universal Transcode +// Begin a Universal Transcode Session +func (s *Video) StartUniversalTranscode(ctx context.Context, request operations.StartUniversalTranscodeRequest) (*operations.StartUniversalTranscodeResponse, error) { + baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) + url := strings.TrimSuffix(baseURL, "/") + "/video/:/transcode/universal/start.mpd" + + req, err := http.NewRequestWithContext(ctx, "GET", url, 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) + } + + client := s.sdkConfiguration.SecurityClient + + httpRes, err := client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %w", err) + } + if httpRes == nil { + return nil, fmt.Errorf("error sending request: no response") + } + + 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)) + + contentType := httpRes.Header.Get("Content-Type") + + res := &operations.StartUniversalTranscodeResponse{ + StatusCode: httpRes.StatusCode, + ContentType: contentType, + RawResponse: httpRes, + } + switch { + case httpRes.StatusCode == 200: + fallthrough + case httpRes.StatusCode == 400: + case httpRes.StatusCode == 401: + switch { + case utils.MatchContentType(contentType, `application/json`): + var out operations.StartUniversalTranscodeResponseBody + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + res.Object = &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", contentType), httpRes.StatusCode, string(rawBody), httpRes) + } + } + + return res, nil +} + +// GetTimeline - Get the timeline for a media item +// Get the timeline for a media item +func (s *Video) GetTimeline(ctx context.Context, request operations.GetTimelineRequest) (*operations.GetTimelineResponse, error) { + baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) + url := strings.TrimSuffix(baseURL, "/") + "/:/timeline" + + req, err := http.NewRequestWithContext(ctx, "GET", url, 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) + } + + client := s.sdkConfiguration.SecurityClient + + httpRes, err := client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %w", err) + } + if httpRes == nil { + return nil, fmt.Errorf("error sending request: no response") + } + + 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)) + + contentType := httpRes.Header.Get("Content-Type") + + res := &operations.GetTimelineResponse{ + StatusCode: httpRes.StatusCode, + ContentType: contentType, + RawResponse: httpRes, + } + switch { + case httpRes.StatusCode == 200: + fallthrough + case httpRes.StatusCode == 400: + case httpRes.StatusCode == 401: + switch { + case utils.MatchContentType(contentType, `application/json`): + var out operations.GetTimelineResponseBody + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + res.Object = &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", contentType), httpRes.StatusCode, string(rawBody), httpRes) + } + } + + return res, nil +} diff --git a/internal/validators/DateValidator.go b/internal/validators/DateValidator.go new file mode 100644 index 0000000..fcafac5 --- /dev/null +++ b/internal/validators/DateValidator.go @@ -0,0 +1,50 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package validators + +import ( + "context" + "github.com/LukeHagar/terraform-provider-PlexAPI/internal/sdk/pkg/types" + "github.com/hashicorp/terraform-plugin-framework-validators/helpers/validatordiag" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" +) + +var _ validator.String = DateValidator{} + +type DateValidator struct { +} + +func (validator DateValidator) Description(ctx context.Context) string { + return "value must be a string in YYYY-MM-DD format" +} + +func (validator DateValidator) MarkdownDescription(ctx context.Context) string { + return validator.Description(ctx) +} + +func (validator DateValidator) ValidateString(ctx context.Context, req validator.StringRequest, resp *validator.StringResponse) { + // Only validate the attribute configuration value if it is known. + if req.ConfigValue.IsNull() || req.ConfigValue.IsUnknown() { + return + } + + if _, err := types.NewDateFromString(req.ConfigValue.ValueString()); err != nil { + resp.Diagnostics.Append(validatordiag.InvalidAttributeTypeDiagnostic( + req.Path, + validator.MarkdownDescription(ctx), + req.ConfigValue.ValueString(), + )) + return + } +} + +// IsDate returns an AttributeValidator which ensures that any configured +// attribute value: +// +// - Is a String. +// - Is in YYYY-MM-DD Format. +// +// Null (unconfigured) and unknown (known after apply) values are skipped. +func IsValidDate() validator.String { + return DateValidator{} +} diff --git a/internal/validators/ExactlyOneChild.go b/internal/validators/ExactlyOneChild.go new file mode 100644 index 0000000..5741558 --- /dev/null +++ b/internal/validators/ExactlyOneChild.go @@ -0,0 +1,53 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package validators + +import ( + "context" + "github.com/hashicorp/terraform-plugin-framework-validators/helpers/validatordiag" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" +) + +var _ validator.Object = exactlyOneChild{} + +// exactlyOneChild validates if the provided value is of type string and can be parsed as JSON. +type exactlyOneChild struct { +} + +func (validator exactlyOneChild) ValidateObject(ctx context.Context, req validator.ObjectRequest, resp *validator.ObjectResponse) { + // Only validate the attribute configuration value if it is known. + if req.ConfigValue.IsNull() || req.ConfigValue.IsUnknown() { + return + } + defined := make(map[string]bool) + count := 0 + for key, attr := range req.ConfigValue.Attributes() { + if attr.IsUnknown() || attr.IsNull() { + continue + } + defined[key] = true + count++ + } + if count != 1 { + resp.Diagnostics.Append(validatordiag.InvalidAttributeTypeDiagnostic( + req.Path, + validator.MarkdownDescription(ctx), + req.ConfigValue.String(), + )) + } +} + +func (validator exactlyOneChild) Description(ctx context.Context) string { + return "value must have exactly one child attribute defined" +} + +func (validator exactlyOneChild) MarkdownDescription(ctx context.Context) string { + return validator.Description(ctx) +} + +// ExactlyOneChild returns an AttributeValidator which ensures that any configured +// attribute object has only one child attribute. +// Null (unconfigured) and unknown values are skipped. +func ExactlyOneChild() validator.Object { + return exactlyOneChild{} +} diff --git a/internal/validators/JSONParseValidator.go b/internal/validators/JSONParseValidator.go new file mode 100644 index 0000000..3a341e1 --- /dev/null +++ b/internal/validators/JSONParseValidator.go @@ -0,0 +1,51 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package validators + +import ( + "context" + "encoding/json" + "github.com/hashicorp/terraform-plugin-framework-validators/helpers/validatordiag" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" +) + +var _ validator.String = JSONParseValidator{} + +// JSONParseValidator validates if the provided value is of type string and can be parsed as JSON. +type JSONParseValidator struct { +} + +func (validator JSONParseValidator) Description(ctx context.Context) string { + return "value must be parsable as JSON" +} + +func (validator JSONParseValidator) MarkdownDescription(ctx context.Context) string { + return validator.Description(ctx) +} + +func (validator JSONParseValidator) ValidateString(ctx context.Context, req validator.StringRequest, resp *validator.StringResponse) { + // Only validate the attribute configuration value if it is known. + if req.ConfigValue.IsNull() || req.ConfigValue.IsUnknown() { + return + } + + if !json.Valid([]byte(req.ConfigValue.ValueString())) { + resp.Diagnostics.Append(validatordiag.InvalidAttributeTypeDiagnostic( + req.Path, + validator.MarkdownDescription(ctx), + req.ConfigValue.ValueString(), + )) + return + } +} + +// IsValidJSON returns an AttributeValidator which ensures that any configured +// attribute value: +// +// - Is a String. +// - Is considered valid JSON. +// +// Null (unconfigured) and unknown (known after apply) values are skipped. +func IsValidJSON() validator.String { + return JSONParseValidator{} +} diff --git a/internal/validators/RFC3339Validator.go b/internal/validators/RFC3339Validator.go new file mode 100644 index 0000000..ad3d715 --- /dev/null +++ b/internal/validators/RFC3339Validator.go @@ -0,0 +1,50 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package validators + +import ( + "context" + "time" + + "github.com/hashicorp/terraform-plugin-framework-validators/helpers/validatordiag" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" +) + +var _ validator.String = RFC3339TimeValidator{} + +type RFC3339TimeValidator struct{} + +func (validator RFC3339TimeValidator) Description(ctx context.Context) string { + return "value must be a string in RFC3339 format" +} + +func (validator RFC3339TimeValidator) MarkdownDescription(ctx context.Context) string { + return validator.Description(ctx) +} + +func (validator RFC3339TimeValidator) ValidateString(ctx context.Context, req validator.StringRequest, resp *validator.StringResponse) { + // Only validate the attribute configuration value if it is known. + if req.ConfigValue.IsNull() || req.ConfigValue.IsUnknown() { + return + } + + if _, err := time.Parse(time.RFC3339Nano, req.ConfigValue.ValueString()); err != nil { + resp.Diagnostics.Append(validatordiag.InvalidAttributeTypeDiagnostic( + req.Path, + validator.MarkdownDescription(ctx), + req.ConfigValue.ValueString(), + )) + return + } +} + +// IsRFC3339 returns an AttributeValidator which ensures that any configured +// attribute value: +// +// - Is a String. +// - Is in RFC3339Nano Format. +// +// Null (unconfigured) and unknown (known after apply) values are skipped. +func IsRFC3339() validator.String { + return RFC3339TimeValidator{} +} diff --git a/main.go b/main.go new file mode 100644 index 0000000..5a62de3 --- /dev/null +++ b/main.go @@ -0,0 +1,42 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package main + +import ( + "context" + "flag" + "log" + + "github.com/LukeHagar/terraform-provider-PlexAPI/internal/provider" + "github.com/hashicorp/terraform-plugin-framework/providerserver" +) + +// Run "go generate" to generate the docs for the registry/website on each regeneration of the provider. + +// Run the docs generation tool, check its repository for more information on how it works and how docs +// can be customized. +//go:generate go run github.com/hashicorp/terraform-plugin-docs/cmd/tfplugindocs + +var ( + // these will be set by the goreleaser configuration + // to appropriate values for the compiled binary + version string = "dev" +) + +func main() { + var debug bool + + flag.BoolVar(&debug, "debug", false, "set to true to run the provider with support for debuggers like delve") + flag.Parse() + + opts := providerserver.ServeOpts{ + Address: "registry.terraform.io/LukeHagar/plex-api", + Debug: debug, + } + + err := providerserver.Serve(context.Background(), provider.New(version), opts) + + if err != nil { + log.Fatal(err.Error()) + } +} diff --git a/terraform-registry-manifest.json b/terraform-registry-manifest.json new file mode 100644 index 0000000..fec2a56 --- /dev/null +++ b/terraform-registry-manifest.json @@ -0,0 +1,6 @@ +{ + "version": 1, + "metadata": { + "protocol_versions": ["6.0"] + } +} diff --git a/tools/tools.go b/tools/tools.go new file mode 100644 index 0000000..4f42a8c --- /dev/null +++ b/tools/tools.go @@ -0,0 +1,10 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +//go:build tools + +package tools + +import ( + // Documentation generation + _ "github.com/hashicorp/terraform-plugin-docs/cmd/tfplugindocs" +)