From 8668cc2ca6ec1460354da4994471e34496e951e7 Mon Sep 17 00:00:00 2001 From: speakeasybot Date: Wed, 31 Jan 2024 15:07:20 +0000 Subject: [PATCH] ci: regenerated with OpenAPI Doc 0.0.3, Speakeasy CLI 1.158.0 --- .speakeasy/gen.lock | 29 +- README.md | 32 ++ RELEASES.md | 12 +- docs/models/errors/getpinerrors.md | 10 + docs/models/errors/getpinresponsebody.md | 11 + docs/models/errors/gettokenerrors.md | 10 + docs/models/errors/gettokenresponsebody.md | 11 + .../operations/getlibrariesdirectory.md | 46 +-- .../models/operations/getlibrarieslocation.md | 9 + docs/models/operations/getpinrequest.md | 9 + docs/models/operations/getpinresponse.md | 11 + docs/models/operations/getpinresponsebody.md | 21 + docs/models/operations/gettokenrequest.md | 9 + docs/models/operations/gettokenresponse.md | 10 + docs/models/operations/location.md | 16 +- docs/sdks/plex/README.md | 5 + docs/sdks/tv/README.md | 101 +++++ gen.yaml | 2 +- package-lock.json | 4 +- package.json | 2 +- src/lib/config.ts | 6 +- src/models/errors/getpin.ts | 144 +++++++ src/models/errors/gettoken.ts | 144 +++++++ src/models/errors/index.ts | 2 + src/models/operations/getlibraries.ts | 18 +- src/models/operations/getpin.ts | 384 ++++++++++++++++++ src/models/operations/gettoken.ts | 115 ++++++ src/models/operations/index.ts | 2 + src/sdk/plex.ts | 27 ++ src/sdk/sdk.ts | 6 + src/sdk/tv.ts | 204 ++++++++++ 31 files changed, 1363 insertions(+), 49 deletions(-) create mode 100644 docs/models/errors/getpinerrors.md create mode 100644 docs/models/errors/getpinresponsebody.md create mode 100644 docs/models/errors/gettokenerrors.md create mode 100644 docs/models/errors/gettokenresponsebody.md create mode 100644 docs/models/operations/getlibrarieslocation.md create mode 100644 docs/models/operations/getpinrequest.md create mode 100644 docs/models/operations/getpinresponse.md create mode 100644 docs/models/operations/getpinresponsebody.md create mode 100644 docs/models/operations/gettokenrequest.md create mode 100644 docs/models/operations/gettokenresponse.md create mode 100644 docs/sdks/plex/README.md create mode 100644 docs/sdks/tv/README.md create mode 100644 src/models/errors/getpin.ts create mode 100644 src/models/errors/gettoken.ts create mode 100644 src/models/operations/getpin.ts create mode 100644 src/models/operations/gettoken.ts create mode 100644 src/sdk/plex.ts create mode 100644 src/sdk/tv.ts diff --git a/.speakeasy/gen.lock b/.speakeasy/gen.lock index 57fa6f31..bccc2521 100755 --- a/.speakeasy/gen.lock +++ b/.speakeasy/gen.lock @@ -1,12 +1,12 @@ lockVersion: 2.0.0 id: 16f22cbf-f23f-4419-8924-3a4b06381947 management: - docChecksum: 95d4ac4070b7f9db42126fc81b258e02 + docChecksum: 94439465ae5d544f0e52b00719af05ee docVersion: 0.0.3 speakeasyVersion: internal - generationVersion: 2.237.3 - releaseVersion: 0.5.3 - configChecksum: 86bdd2d91c582938b3f3e2587f792c5c + generationVersion: 2.239.4 + releaseVersion: 0.6.0 + configChecksum: 42a58e9ba53ecd70c05120ba0c5c2d36 repoURL: https://github.com/LukeHagar/plexjs.git repoSubDirectory: . installationURL: https://github.com/LukeHagar/plexjs @@ -18,6 +18,7 @@ features: flattening: 2.81.1 globalSecurity: 2.82.2 globalServerURLs: 2.82.1 + methodServerURLs: 2.82.1 nameOverrides: 2.81.1 unions: 2.85.0 generatedFiles: @@ -29,6 +30,8 @@ generatedFiles: - src/sdk/search.ts - src/sdk/library.ts - src/sdk/log.ts + - src/sdk/tv.ts + - src/sdk/plex.ts - src/sdk/playlists.ts - src/sdk/security.ts - src/sdk/sessions.ts @@ -95,6 +98,8 @@ generatedFiles: - src/models/operations/logline.ts - src/models/operations/logmultiline.ts - src/models/operations/enablepapertrail.ts + - src/models/operations/getpin.ts + - src/models/operations/gettoken.ts - src/models/operations/createplaylist.ts - src/models/operations/getplaylists.ts - src/models/operations/getplaylist.ts @@ -150,6 +155,8 @@ generatedFiles: - src/models/errors/logline.ts - src/models/errors/logmultiline.ts - src/models/errors/enablepapertrail.ts + - src/models/errors/getpin.ts + - src/models/errors/gettoken.ts - src/models/errors/createplaylist.ts - src/models/errors/getplaylists.ts - src/models/errors/getplaylist.ts @@ -283,7 +290,7 @@ generatedFiles: - docs/models/operations/getrecentlyaddedmediacontainer.md - docs/models/operations/getrecentlyaddedresponsebody.md - docs/models/operations/getrecentlyaddedresponse.md - - docs/models/operations/location.md + - docs/models/operations/getlibrarieslocation.md - docs/models/operations/getlibrariesdirectory.md - docs/models/operations/getlibrariesmediacontainer.md - docs/models/operations/getlibrariesresponsebody.md @@ -358,6 +365,12 @@ generatedFiles: - docs/models/operations/loglineresponse.md - docs/models/operations/logmultilineresponse.md - docs/models/operations/enablepapertrailresponse.md + - docs/models/operations/getpinrequest.md + - docs/models/operations/location.md + - docs/models/operations/getpinresponsebody.md + - docs/models/operations/getpinresponse.md + - docs/models/operations/gettokenrequest.md + - docs/models/operations/gettokenresponse.md - docs/models/operations/queryparamtype.md - docs/models/operations/smart.md - docs/models/operations/createplaylistrequest.md @@ -515,6 +528,10 @@ generatedFiles: - docs/models/errors/logmultilineresponsebody.md - docs/models/errors/enablepapertrailerrors.md - docs/models/errors/enablepapertrailresponsebody.md + - docs/models/errors/getpinerrors.md + - docs/models/errors/getpinresponsebody.md + - docs/models/errors/gettokenerrors.md + - docs/models/errors/gettokenresponsebody.md - docs/models/errors/createplaylisterrors.md - docs/models/errors/createplaylistresponsebody.md - docs/models/errors/getplaylistserrors.md @@ -565,6 +582,8 @@ generatedFiles: - docs/sdks/search/README.md - docs/sdks/library/README.md - docs/sdks/log/README.md + - docs/sdks/plex/README.md + - docs/sdks/tv/README.md - docs/sdks/playlists/README.md - docs/sdks/security/README.md - docs/sdks/sessions/README.md diff --git a/README.md b/README.md index a2a4985c..0f45dee1 100644 --- a/README.md +++ b/README.md @@ -111,6 +111,12 @@ run(); * [logMultiLine](docs/sdks/log/README.md#logmultiline) - Logging a multi-line message * [enablePaperTrail](docs/sdks/log/README.md#enablepapertrail) - Enabling Papertrail + +### [plex.tv](docs/sdks/tv/README.md) + +* [getPin](docs/sdks/tv/README.md#getpin) - Get a Pin +* [getToken](docs/sdks/tv/README.md#gettoken) - Get Access Token + ### [playlists](docs/sdks/playlists/README.md) * [createPlaylist](docs/sdks/playlists/README.md#createplaylist) - Create a Playlist @@ -250,6 +256,32 @@ async function run() { run(); +``` +### Override Server URL Per-Operation + +The server URL can also be overridden on a per-operation basis, provided a server list was specified for the operation. For example: + +```typescript +import { PlexAPI } from "@lukehagar/plexjs"; + +async function run() { + const sdk = new PlexAPI({ + accessToken: "", + }); + + const xPlexClientIdentifier = "string"; + const strong = false; + + const result = await sdk.plex.tv.getPin(xPlexClientIdentifier, strong, { + serverURL: "https://plex.tv/api/v2", + }); + + // Handle the result + console.log(result); +} + +run(); + ``` diff --git a/RELEASES.md b/RELEASES.md index dfcd641d..7ef16b4a 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -148,4 +148,14 @@ Based on: ### Generated - [typescript v0.5.3] . ### Releases -- [NPM v0.5.3] https://www.npmjs.com/package/@lukehagar/plexjs/v/0.5.3 - . \ No newline at end of file +- [NPM v0.5.3] https://www.npmjs.com/package/@lukehagar/plexjs/v/0.5.3 - . + +## 2024-01-31 15:05:58 +### Changes +Based on: +- OpenAPI Doc 0.0.3 +- Speakeasy CLI 1.158.0 (2.239.4) https://github.com/speakeasy-api/speakeasy +### Generated +- [typescript v0.6.0] . +### Releases +- [NPM v0.6.0] https://www.npmjs.com/package/@lukehagar/plexjs/v/0.6.0 - . \ No newline at end of file diff --git a/docs/models/errors/getpinerrors.md b/docs/models/errors/getpinerrors.md new file mode 100644 index 00000000..d62b1d72 --- /dev/null +++ b/docs/models/errors/getpinerrors.md @@ -0,0 +1,10 @@ +# GetPinErrors + + +## Fields + +| Field | Type | Required | Description | Example | +| ----------------------------------- | ----------------------------------- | ----------------------------------- | ----------------------------------- | ----------------------------------- | +| `code` | *number* | :heavy_minus_sign: | N/A | 1000 | +| `message` | *string* | :heavy_minus_sign: | N/A | X-Plex-Client-Identifier is missing | +| `status` | *number* | :heavy_minus_sign: | N/A | 400 | \ No newline at end of file diff --git a/docs/models/errors/getpinresponsebody.md b/docs/models/errors/getpinresponsebody.md new file mode 100644 index 00000000..1bba39f3 --- /dev/null +++ b/docs/models/errors/getpinresponsebody.md @@ -0,0 +1,11 @@ +# GetPinResponseBody + +X-Plex-Client-Identifier is missing + + +## Fields + +| Field | Type | Required | Description | +| --------------------------------------------------------------------- | --------------------------------------------------------------------- | --------------------------------------------------------------------- | --------------------------------------------------------------------- | +| `errors` | [errors.GetPinErrors](../../models/errors/getpinerrors.md)[] | :heavy_minus_sign: | N/A | +| `rawResponse` | [Response](https://developer.mozilla.org/en-US/docs/Web/API/Response) | :heavy_minus_sign: | Raw HTTP response; suitable for custom response parsing | \ No newline at end of file diff --git a/docs/models/errors/gettokenerrors.md b/docs/models/errors/gettokenerrors.md new file mode 100644 index 00000000..a8a7ae04 --- /dev/null +++ b/docs/models/errors/gettokenerrors.md @@ -0,0 +1,10 @@ +# GetTokenErrors + + +## Fields + +| Field | Type | Required | Description | Example | +| ----------------------------------- | ----------------------------------- | ----------------------------------- | ----------------------------------- | ----------------------------------- | +| `code` | *number* | :heavy_minus_sign: | N/A | 1000 | +| `message` | *string* | :heavy_minus_sign: | N/A | X-Plex-Client-Identifier is missing | +| `status` | *number* | :heavy_minus_sign: | N/A | 400 | \ No newline at end of file diff --git a/docs/models/errors/gettokenresponsebody.md b/docs/models/errors/gettokenresponsebody.md new file mode 100644 index 00000000..6b5ff178 --- /dev/null +++ b/docs/models/errors/gettokenresponsebody.md @@ -0,0 +1,11 @@ +# GetTokenResponseBody + +X-Plex-Client-Identifier is missing + + +## Fields + +| Field | Type | Required | Description | +| --------------------------------------------------------------------- | --------------------------------------------------------------------- | --------------------------------------------------------------------- | --------------------------------------------------------------------- | +| `errors` | [errors.GetTokenErrors](../../models/errors/gettokenerrors.md)[] | :heavy_minus_sign: | N/A | +| `rawResponse` | [Response](https://developer.mozilla.org/en-US/docs/Web/API/Response) | :heavy_minus_sign: | Raw HTTP response; suitable for custom response parsing | \ No newline at end of file diff --git a/docs/models/operations/getlibrariesdirectory.md b/docs/models/operations/getlibrariesdirectory.md index 0948252c..210cf964 100644 --- a/docs/models/operations/getlibrariesdirectory.md +++ b/docs/models/operations/getlibrariesdirectory.md @@ -3,26 +3,26 @@ ## Fields -| Field | Type | Required | Description | Example | -| ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | -| `allowSync` | *boolean* | :heavy_minus_sign: | N/A | true | -| `art` | *string* | :heavy_minus_sign: | N/A | /:/resources/movie-fanart.jpg | -| `composite` | *string* | :heavy_minus_sign: | N/A | /library/sections/1/composite/1705615584 | -| `filters` | *boolean* | :heavy_minus_sign: | N/A | true | -| `refreshing` | *boolean* | :heavy_minus_sign: | N/A | false | -| `thumb` | *string* | :heavy_minus_sign: | N/A | /:/resources/movie.png | -| `key` | *string* | :heavy_minus_sign: | N/A | 1 | -| `type` | *string* | :heavy_minus_sign: | N/A | movie | -| `title` | *string* | :heavy_minus_sign: | N/A | Movies | -| `agent` | *string* | :heavy_minus_sign: | N/A | tv.plex.agents.movie | -| `scanner` | *string* | :heavy_minus_sign: | N/A | Plex Movie | -| `language` | *string* | :heavy_minus_sign: | N/A | en-US | -| `uuid` | *string* | :heavy_minus_sign: | N/A | 322a231a-b7f7-49f5-920f-14c61199cd30 | -| `updatedAt` | *number* | :heavy_minus_sign: | N/A | 1705615634 | -| `createdAt` | *number* | :heavy_minus_sign: | N/A | 1654131312 | -| `scannedAt` | *number* | :heavy_minus_sign: | N/A | 1705615584 | -| `content` | *boolean* | :heavy_minus_sign: | N/A | true | -| `directory` | *boolean* | :heavy_minus_sign: | N/A | true | -| `contentChangedAt` | *number* | :heavy_minus_sign: | N/A | 3192854 | -| `hidden` | *number* | :heavy_minus_sign: | N/A | 0 | -| `location` | [operations.Location](../../models/operations/location.md)[] | :heavy_minus_sign: | N/A | [{"id":1,"path":"/movies"}] | \ No newline at end of file +| Field | Type | Required | Description | Example | +| ------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------ | +| `allowSync` | *boolean* | :heavy_minus_sign: | N/A | true | +| `art` | *string* | :heavy_minus_sign: | N/A | /:/resources/movie-fanart.jpg | +| `composite` | *string* | :heavy_minus_sign: | N/A | /library/sections/1/composite/1705615584 | +| `filters` | *boolean* | :heavy_minus_sign: | N/A | true | +| `refreshing` | *boolean* | :heavy_minus_sign: | N/A | false | +| `thumb` | *string* | :heavy_minus_sign: | N/A | /:/resources/movie.png | +| `key` | *string* | :heavy_minus_sign: | N/A | 1 | +| `type` | *string* | :heavy_minus_sign: | N/A | movie | +| `title` | *string* | :heavy_minus_sign: | N/A | Movies | +| `agent` | *string* | :heavy_minus_sign: | N/A | tv.plex.agents.movie | +| `scanner` | *string* | :heavy_minus_sign: | N/A | Plex Movie | +| `language` | *string* | :heavy_minus_sign: | N/A | en-US | +| `uuid` | *string* | :heavy_minus_sign: | N/A | 322a231a-b7f7-49f5-920f-14c61199cd30 | +| `updatedAt` | *number* | :heavy_minus_sign: | N/A | 1705615634 | +| `createdAt` | *number* | :heavy_minus_sign: | N/A | 1654131312 | +| `scannedAt` | *number* | :heavy_minus_sign: | N/A | 1705615584 | +| `content` | *boolean* | :heavy_minus_sign: | N/A | true | +| `directory` | *boolean* | :heavy_minus_sign: | N/A | true | +| `contentChangedAt` | *number* | :heavy_minus_sign: | N/A | 3192854 | +| `hidden` | *number* | :heavy_minus_sign: | N/A | 0 | +| `location` | [operations.GetLibrariesLocation](../../models/operations/getlibrarieslocation.md)[] | :heavy_minus_sign: | N/A | [{"id":1,"path":"/movies"}] | \ No newline at end of file diff --git a/docs/models/operations/getlibrarieslocation.md b/docs/models/operations/getlibrarieslocation.md new file mode 100644 index 00000000..fadf69ee --- /dev/null +++ b/docs/models/operations/getlibrarieslocation.md @@ -0,0 +1,9 @@ +# GetLibrariesLocation + + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------ | ------------------ | ------------------ | ------------------ | ------------------ | +| `id` | *number* | :heavy_minus_sign: | N/A | 1 | +| `path` | *string* | :heavy_minus_sign: | N/A | /movies | \ No newline at end of file diff --git a/docs/models/operations/getpinrequest.md b/docs/models/operations/getpinrequest.md new file mode 100644 index 00000000..0c59ab6e --- /dev/null +++ b/docs/models/operations/getpinrequest.md @@ -0,0 +1,9 @@ +# GetPinRequest + + +## Fields + +| Field | Type | Required | Description | +| ----------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | +| `xPlexClientIdentifier` | *string* | :heavy_check_mark: | Plex Authentication Token | +| `strong` | *boolean* | :heavy_minus_sign: | Determines the kind of code returned by the API call
Strong codes are used for Pin authentication flows
Non-Strong codes are used for `Plex.tv/link`
| \ No newline at end of file diff --git a/docs/models/operations/getpinresponse.md b/docs/models/operations/getpinresponse.md new file mode 100644 index 00000000..a23b08ea --- /dev/null +++ b/docs/models/operations/getpinresponse.md @@ -0,0 +1,11 @@ +# GetPinResponse + + +## Fields + +| Field | Type | Required | Description | +| ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------ | +| `contentType` | *string* | :heavy_check_mark: | HTTP response content type for this operation | +| `statusCode` | *number* | :heavy_check_mark: | HTTP response status code for this operation | +| `rawResponse` | [Response](https://developer.mozilla.org/en-US/docs/Web/API/Response) | :heavy_check_mark: | Raw HTTP response; suitable for custom response parsing | +| `object` | [operations.GetPinResponseBody](../../models/operations/getpinresponsebody.md) | :heavy_minus_sign: | The Pin | \ No newline at end of file diff --git a/docs/models/operations/getpinresponsebody.md b/docs/models/operations/getpinresponsebody.md new file mode 100644 index 00000000..5b9c40c3 --- /dev/null +++ b/docs/models/operations/getpinresponsebody.md @@ -0,0 +1,21 @@ +# GetPinResponseBody + +The Pin + + +## Fields + +| Field | Type | Required | Description | Example | +| --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `id` | *number* | :heavy_minus_sign: | PinID for use with authentication | 1272322473 | +| `code` | *string* | :heavy_minus_sign: | N/A | 3patfx1a78ukcbr7x0n9bl26t | +| `product` | *string* | :heavy_minus_sign: | N/A | Plex Web | +| `trusted` | *boolean* | :heavy_minus_sign: | N/A | | +| `qr` | *string* | :heavy_minus_sign: | a link to a QR code hosted on plex.tv
The QR code redirects to the relevant `plex.tv/link` authentication page
Which then prompts the user for the 4 Digit Link Pin
| https://plex.tv/api/v2/pins/qr/3patfx1a78ukcbr7x0n9bl26t | +| `clientIdentifier` | *string* | :heavy_minus_sign: | N/A | Postman | +| `location` | [operations.Location](../../models/operations/location.md) | :heavy_minus_sign: | N/A | | +| `expiresIn` | *number* | :heavy_minus_sign: | N/A | 1800 | +| `createdAt` | [Date](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date) | :heavy_minus_sign: | N/A | 2023-04-12 17:00:03 +0000 UTC | +| `expiresAt` | [Date](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date) | :heavy_minus_sign: | N/A | 2023-04-12 17:30:03 +0000 UTC | +| `authToken` | *string* | :heavy_minus_sign: | N/A | | +| `newRegistration` | *string* | :heavy_minus_sign: | N/A | | \ No newline at end of file diff --git a/docs/models/operations/gettokenrequest.md b/docs/models/operations/gettokenrequest.md new file mode 100644 index 00000000..98011d0c --- /dev/null +++ b/docs/models/operations/gettokenrequest.md @@ -0,0 +1,9 @@ +# GetTokenRequest + + +## Fields + +| Field | Type | Required | Description | +| ----------------------------------------- | ----------------------------------------- | ----------------------------------------- | ----------------------------------------- | +| `pinID` | *string* | :heavy_check_mark: | The PinID to retrieve an access token for | +| `xPlexClientIdentifier` | *string* | :heavy_check_mark: | Plex Authentication Token | \ No newline at end of file diff --git a/docs/models/operations/gettokenresponse.md b/docs/models/operations/gettokenresponse.md new file mode 100644 index 00000000..cfcf6168 --- /dev/null +++ b/docs/models/operations/gettokenresponse.md @@ -0,0 +1,10 @@ +# GetTokenResponse + + +## Fields + +| Field | Type | Required | Description | +| --------------------------------------------------------------------- | --------------------------------------------------------------------- | --------------------------------------------------------------------- | --------------------------------------------------------------------- | +| `contentType` | *string* | :heavy_check_mark: | HTTP response content type for this operation | +| `statusCode` | *number* | :heavy_check_mark: | HTTP response status code for this operation | +| `rawResponse` | [Response](https://developer.mozilla.org/en-US/docs/Web/API/Response) | :heavy_check_mark: | Raw HTTP response; suitable for custom response parsing | \ No newline at end of file diff --git a/docs/models/operations/location.md b/docs/models/operations/location.md index be58c5b9..f71233f6 100644 --- a/docs/models/operations/location.md +++ b/docs/models/operations/location.md @@ -3,7 +3,15 @@ ## Fields -| Field | Type | Required | Description | Example | -| ------------------ | ------------------ | ------------------ | ------------------ | ------------------ | -| `id` | *number* | :heavy_minus_sign: | N/A | 1 | -| `path` | *string* | :heavy_minus_sign: | N/A | /movies | \ No newline at end of file +| Field | Type | Required | Description | Example | +| ---------------------------- | ---------------------------- | ---------------------------- | ---------------------------- | ---------------------------- | +| `code` | *string* | :heavy_minus_sign: | N/A | US | +| `europeanUnionMember` | *boolean* | :heavy_minus_sign: | N/A | | +| `continentCode` | *string* | :heavy_minus_sign: | N/A | NA | +| `country` | *string* | :heavy_minus_sign: | N/A | United States | +| `city` | *string* | :heavy_minus_sign: | N/A | Austin | +| `timeZone` | *string* | :heavy_minus_sign: | N/A | America/Chicago | +| `postalCode` | *number* | :heavy_minus_sign: | N/A | 78732 | +| `inPrivacyRestrictedCountry` | *boolean* | :heavy_minus_sign: | N/A | | +| `subdivisions` | *string* | :heavy_minus_sign: | N/A | Texas | +| `coordinates` | *string* | :heavy_minus_sign: | N/A | 30.3768 -97.8935 | \ No newline at end of file diff --git a/docs/sdks/plex/README.md b/docs/sdks/plex/README.md new file mode 100644 index 00000000..b5da55df --- /dev/null +++ b/docs/sdks/plex/README.md @@ -0,0 +1,5 @@ +# Plex +(*plex*) + +### Available Operations + diff --git a/docs/sdks/tv/README.md b/docs/sdks/tv/README.md new file mode 100644 index 00000000..03a8f5c1 --- /dev/null +++ b/docs/sdks/tv/README.md @@ -0,0 +1,101 @@ +# Tv +(*plex.tv*) + +### Available Operations + +* [getPin](#getpin) - Get a Pin +* [getToken](#gettoken) - Get Access Token + +## getPin + +Retrieve a Pin from Plex.tv for authentication flows + +### Example Usage + +```typescript +import { PlexAPI } from "@lukehagar/plexjs"; + +async function run() { + const sdk = new PlexAPI({ + accessToken: "", + }); + + const xPlexClientIdentifier = "string"; + const strong = false; + + const result = await sdk.plex.tv.getPin(xPlexClientIdentifier, strong); + + // Handle the result + console.log(result) +} + +run(); +``` + +### Parameters + +| Parameter | Type | Required | Description | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `xPlexClientIdentifier` | *string* | :heavy_check_mark: | Plex Authentication Token | +| `strong` | *boolean* | :heavy_minus_sign: | Determines the kind of code returned by the API call
Strong codes are used for Pin authentication flows
Non-Strong codes are used for `Plex.tv/link`
| +| `options` | RequestOptions | :heavy_minus_sign: | Used to set various options for making HTTP requests. | +| `options.fetchOptions` | [RequestInit](https://developer.mozilla.org/en-US/docs/Web/API/Request/Request#options) | :heavy_minus_sign: | Options that are passed to the underlying HTTP request. This can be used to inject extra headers for examples. All `Request` options, except `method` and `body`, are allowed. | +| `options.serverURL` | *string* | :heavy_minus_sign: | An optional server URL to use. | + + +### Response + +**Promise<[operations.GetPinResponse](../../models/operations/getpinresponse.md)>** +### Errors + +| Error Object | Status Code | Content Type | +| ------------------------- | ------------------------- | ------------------------- | +| errors.GetPinResponseBody | 400 | application/json | +| errors.SDKError | 4xx-5xx | */* | + +## getToken + +Retrieve an Access Token from Plex.tv after the Pin has already been authenticated + +### Example Usage + +```typescript +import { PlexAPI } from "@lukehagar/plexjs"; + +async function run() { + const sdk = new PlexAPI({ + accessToken: "", + }); + + const pinID = "string"; + const xPlexClientIdentifier = "string"; + + const result = await sdk.plex.tv.getToken(pinID, xPlexClientIdentifier); + + // Handle the result + console.log(result) +} + +run(); +``` + +### Parameters + +| Parameter | Type | Required | Description | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `pinID` | *string* | :heavy_check_mark: | The PinID to retrieve an access token for | +| `xPlexClientIdentifier` | *string* | :heavy_check_mark: | Plex Authentication Token | +| `options` | RequestOptions | :heavy_minus_sign: | Used to set various options for making HTTP requests. | +| `options.fetchOptions` | [RequestInit](https://developer.mozilla.org/en-US/docs/Web/API/Request/Request#options) | :heavy_minus_sign: | Options that are passed to the underlying HTTP request. This can be used to inject extra headers for examples. All `Request` options, except `method` and `body`, are allowed. | +| `options.serverURL` | *string* | :heavy_minus_sign: | An optional server URL to use. | + + +### Response + +**Promise<[operations.GetTokenResponse](../../models/operations/gettokenresponse.md)>** +### Errors + +| Error Object | Status Code | Content Type | +| --------------------------- | --------------------------- | --------------------------- | +| errors.GetTokenResponseBody | 400 | application/json | +| errors.SDKError | 4xx-5xx | */* | diff --git a/gen.yaml b/gen.yaml index 2efe4e1e..1d23055e 100755 --- a/gen.yaml +++ b/gen.yaml @@ -8,7 +8,7 @@ generation: fixes: nameResolutionDec2023: false typescript: - version: 0.5.3 + version: 0.6.0 author: LukeHagar clientServerStatusCodesAsErrors: true flattenGlobalSecurity: true diff --git a/package-lock.json b/package-lock.json index ab178d75..214f3644 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@lukehagar/plexjs", - "version": "0.5.3", + "version": "0.6.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@lukehagar/plexjs", - "version": "0.5.3", + "version": "0.6.0", "dependencies": { "decimal.js": "^10.4.3", "jsonpath": "^1.1.1" diff --git a/package.json b/package.json index ccea1c2e..e9f50138 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "type": "commonjs", "name": "@lukehagar/plexjs", - "version": "0.5.3", + "version": "0.6.0", "author": "LukeHagar", "main": "./index.js", "sideEffects": false, diff --git a/src/lib/config.ts b/src/lib/config.ts index 5dac8846..f06cd9d6 100644 --- a/src/lib/config.ts +++ b/src/lib/config.ts @@ -79,7 +79,7 @@ export function serverURLFromOptions(options: SDKOptions): URL { export const SDK_METADATA = Object.freeze({ language: "typescript", openapiDocVersion: "0.0.3", - sdkVersion: "0.5.3", - genVersion: "2.237.3", - userAgent: "speakeasy-sdk/typescript 0.5.3 2.237.3 0.0.3 @lukehagar/plexjs", + sdkVersion: "0.6.0", + genVersion: "2.239.4", + userAgent: "speakeasy-sdk/typescript 0.6.0 2.239.4 0.0.3 @lukehagar/plexjs", }); diff --git a/src/models/errors/getpin.ts b/src/models/errors/getpin.ts new file mode 100644 index 00000000..f1925776 --- /dev/null +++ b/src/models/errors/getpin.ts @@ -0,0 +1,144 @@ +/* + * Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + */ + +import { z } from "zod"; + +export type GetPinErrors = { + code?: number | undefined; + message?: string | undefined; + status?: number | undefined; +}; + +/** + * X-Plex-Client-Identifier is missing + */ +export type GetPinResponseBodyData = { + errors?: Array | undefined; + /** + * Raw HTTP response; suitable for custom response parsing + */ + rawResponse?: Response | undefined; +}; + +/** + * X-Plex-Client-Identifier is missing + */ +export class GetPinResponseBody extends Error { + errors?: Array | undefined; + /** + * Raw HTTP response; suitable for custom response parsing + */ + rawResponse?: Response | undefined; + + /** The original data that was passed to this error instance. */ + data$: GetPinResponseBodyData; + + constructor(err: GetPinResponseBodyData) { + super(""); + this.data$ = err; + + if (err.errors != null) { + this.errors = err.errors; + } + if (err.rawResponse != null) { + this.rawResponse = err.rawResponse; + } + + const msg = "message" in err && typeof err.message === "string" ? err.message : ""; + const { rawResponse, ...data } = err; + const content = JSON.stringify(data); + this.message = [msg, content].filter(Boolean).join("\n"); + + this.name = "GetPinResponseBody"; + } +} + +/** @internal */ +export namespace GetPinErrors$ { + export type Inbound = { + code?: number | undefined; + message?: string | undefined; + status?: number | undefined; + }; + + export const inboundSchema: z.ZodType = z + .object({ + code: z.number().optional(), + message: z.string().optional(), + status: z.number().optional(), + }) + .transform((v) => { + return { + ...(v.code === undefined ? null : { code: v.code }), + ...(v.message === undefined ? null : { message: v.message }), + ...(v.status === undefined ? null : { status: v.status }), + }; + }); + + export type Outbound = { + code?: number | undefined; + message?: string | undefined; + status?: number | undefined; + }; + + export const outboundSchema: z.ZodType = z + .object({ + code: z.number().optional(), + message: z.string().optional(), + status: z.number().optional(), + }) + .transform((v) => { + return { + ...(v.code === undefined ? null : { code: v.code }), + ...(v.message === undefined ? null : { message: v.message }), + ...(v.status === undefined ? null : { status: v.status }), + }; + }); +} + +/** @internal */ +export namespace GetPinResponseBody$ { + export type Inbound = { + errors?: Array | undefined; + RawResponse?: Response | undefined; + }; + + export const inboundSchema: z.ZodType = z + .object({ + errors: z.array(z.lazy(() => GetPinErrors$.inboundSchema)).optional(), + RawResponse: z.instanceof(Response).optional(), + }) + .transform((v) => { + return new GetPinResponseBody({ + ...(v.errors === undefined ? null : { errors: v.errors }), + ...(v.RawResponse === undefined ? null : { rawResponse: v.RawResponse }), + }); + }); + export type Outbound = { + errors?: Array | undefined; + RawResponse?: never | undefined; + }; + + export const outboundSchema: z.ZodType = z + .instanceof(GetPinResponseBody) + .transform((v) => v.data$) + .pipe( + z + .object({ + errors: z.array(z.lazy(() => GetPinErrors$.outboundSchema)).optional(), + rawResponse: z + .instanceof(Response) + .transform(() => { + throw new Error("Response cannot be serialized"); + }) + .optional(), + }) + .transform((v) => { + return { + ...(v.errors === undefined ? null : { errors: v.errors }), + ...(v.rawResponse === undefined ? null : { RawResponse: v.rawResponse }), + }; + }) + ); +} diff --git a/src/models/errors/gettoken.ts b/src/models/errors/gettoken.ts new file mode 100644 index 00000000..339c2b22 --- /dev/null +++ b/src/models/errors/gettoken.ts @@ -0,0 +1,144 @@ +/* + * Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + */ + +import { z } from "zod"; + +export type GetTokenErrors = { + code?: number | undefined; + message?: string | undefined; + status?: number | undefined; +}; + +/** + * X-Plex-Client-Identifier is missing + */ +export type GetTokenResponseBodyData = { + errors?: Array | undefined; + /** + * Raw HTTP response; suitable for custom response parsing + */ + rawResponse?: Response | undefined; +}; + +/** + * X-Plex-Client-Identifier is missing + */ +export class GetTokenResponseBody extends Error { + errors?: Array | undefined; + /** + * Raw HTTP response; suitable for custom response parsing + */ + rawResponse?: Response | undefined; + + /** The original data that was passed to this error instance. */ + data$: GetTokenResponseBodyData; + + constructor(err: GetTokenResponseBodyData) { + super(""); + this.data$ = err; + + if (err.errors != null) { + this.errors = err.errors; + } + if (err.rawResponse != null) { + this.rawResponse = err.rawResponse; + } + + const msg = "message" in err && typeof err.message === "string" ? err.message : ""; + const { rawResponse, ...data } = err; + const content = JSON.stringify(data); + this.message = [msg, content].filter(Boolean).join("\n"); + + this.name = "GetTokenResponseBody"; + } +} + +/** @internal */ +export namespace GetTokenErrors$ { + export type Inbound = { + code?: number | undefined; + message?: string | undefined; + status?: number | undefined; + }; + + export const inboundSchema: z.ZodType = z + .object({ + code: z.number().optional(), + message: z.string().optional(), + status: z.number().optional(), + }) + .transform((v) => { + return { + ...(v.code === undefined ? null : { code: v.code }), + ...(v.message === undefined ? null : { message: v.message }), + ...(v.status === undefined ? null : { status: v.status }), + }; + }); + + export type Outbound = { + code?: number | undefined; + message?: string | undefined; + status?: number | undefined; + }; + + export const outboundSchema: z.ZodType = z + .object({ + code: z.number().optional(), + message: z.string().optional(), + status: z.number().optional(), + }) + .transform((v) => { + return { + ...(v.code === undefined ? null : { code: v.code }), + ...(v.message === undefined ? null : { message: v.message }), + ...(v.status === undefined ? null : { status: v.status }), + }; + }); +} + +/** @internal */ +export namespace GetTokenResponseBody$ { + export type Inbound = { + errors?: Array | undefined; + RawResponse?: Response | undefined; + }; + + export const inboundSchema: z.ZodType = z + .object({ + errors: z.array(z.lazy(() => GetTokenErrors$.inboundSchema)).optional(), + RawResponse: z.instanceof(Response).optional(), + }) + .transform((v) => { + return new GetTokenResponseBody({ + ...(v.errors === undefined ? null : { errors: v.errors }), + ...(v.RawResponse === undefined ? null : { rawResponse: v.RawResponse }), + }); + }); + export type Outbound = { + errors?: Array | undefined; + RawResponse?: never | undefined; + }; + + export const outboundSchema: z.ZodType = z + .instanceof(GetTokenResponseBody) + .transform((v) => v.data$) + .pipe( + z + .object({ + errors: z.array(z.lazy(() => GetTokenErrors$.outboundSchema)).optional(), + rawResponse: z + .instanceof(Response) + .transform(() => { + throw new Error("Response cannot be serialized"); + }) + .optional(), + }) + .transform((v) => { + return { + ...(v.errors === undefined ? null : { errors: v.errors }), + ...(v.rawResponse === undefined ? null : { RawResponse: v.rawResponse }), + }; + }) + ); +} diff --git a/src/models/errors/index.ts b/src/models/errors/index.ts index 6c5f73c8..16425452 100644 --- a/src/models/errors/index.ts +++ b/src/models/errors/index.ts @@ -23,6 +23,7 @@ export * from "./getmetadata"; export * from "./getmetadatachildren"; export * from "./getmyplexaccount"; export * from "./getondeck"; +export * from "./getpin"; export * from "./getplaylist"; export * from "./getplaylistcontents"; export * from "./getplaylists"; @@ -38,6 +39,7 @@ export * from "./getsessionhistory"; export * from "./getsessions"; export * from "./getsourceconnectioninformation"; export * from "./gettimeline"; +export * from "./gettoken"; export * from "./gettranscodesessions"; export * from "./gettransienttoken"; export * from "./getupdatestatus"; diff --git a/src/models/operations/getlibraries.ts b/src/models/operations/getlibraries.ts index 1a481f78..112a5870 100644 --- a/src/models/operations/getlibraries.ts +++ b/src/models/operations/getlibraries.ts @@ -4,7 +4,7 @@ import { z } from "zod"; -export type Location = { +export type GetLibrariesLocation = { id?: number | undefined; path?: string | undefined; }; @@ -30,7 +30,7 @@ export type GetLibrariesDirectory = { directory?: boolean | undefined; contentChangedAt?: number | undefined; hidden?: number | undefined; - location?: Array | undefined; + location?: Array | undefined; }; export type GetLibrariesMediaContainer = { @@ -67,13 +67,13 @@ export type GetLibrariesResponse = { }; /** @internal */ -export namespace Location$ { +export namespace GetLibrariesLocation$ { export type Inbound = { id?: number | undefined; path?: string | undefined; }; - export const inboundSchema: z.ZodType = z + export const inboundSchema: z.ZodType = z .object({ id: z.number().int().optional(), path: z.string().optional(), @@ -90,7 +90,7 @@ export namespace Location$ { path?: string | undefined; }; - export const outboundSchema: z.ZodType = z + export const outboundSchema: z.ZodType = z .object({ id: z.number().int().optional(), path: z.string().optional(), @@ -126,7 +126,7 @@ export namespace GetLibrariesDirectory$ { directory?: boolean | undefined; contentChangedAt?: number | undefined; hidden?: number | undefined; - Location?: Array | undefined; + Location?: Array | undefined; }; export const inboundSchema: z.ZodType = z @@ -151,7 +151,7 @@ export namespace GetLibrariesDirectory$ { directory: z.boolean().optional(), contentChangedAt: z.number().int().optional(), hidden: z.number().int().optional(), - Location: z.array(z.lazy(() => Location$.inboundSchema)).optional(), + Location: z.array(z.lazy(() => GetLibrariesLocation$.inboundSchema)).optional(), }) .transform((v) => { return { @@ -202,7 +202,7 @@ export namespace GetLibrariesDirectory$ { directory?: boolean | undefined; contentChangedAt?: number | undefined; hidden?: number | undefined; - Location?: Array | undefined; + Location?: Array | undefined; }; export const outboundSchema: z.ZodType = z @@ -227,7 +227,7 @@ export namespace GetLibrariesDirectory$ { directory: z.boolean().optional(), contentChangedAt: z.number().int().optional(), hidden: z.number().int().optional(), - location: z.array(z.lazy(() => Location$.outboundSchema)).optional(), + location: z.array(z.lazy(() => GetLibrariesLocation$.outboundSchema)).optional(), }) .transform((v) => { return { diff --git a/src/models/operations/getpin.ts b/src/models/operations/getpin.ts new file mode 100644 index 00000000..86bf446e --- /dev/null +++ b/src/models/operations/getpin.ts @@ -0,0 +1,384 @@ +/* + * Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + */ + +import { z } from "zod"; + +export const GetPinServerList = ["https://plex.tv/api/v2"] as const; + +export type GetPinRequest = { + /** + * Plex Authentication Token + */ + xPlexClientIdentifier: string; + /** + * Determines the kind of code returned by the API call + * + * @remarks + * Strong codes are used for Pin authentication flows + * Non-Strong codes are used for `Plex.tv/link` + * + */ + strong?: boolean | undefined; +}; + +export type Location = { + code?: string | undefined; + europeanUnionMember?: boolean | undefined; + continentCode?: string | undefined; + country?: string | undefined; + city?: string | undefined; + timeZone?: string | undefined; + postalCode?: number | undefined; + inPrivacyRestrictedCountry?: boolean | undefined; + subdivisions?: string | undefined; + coordinates?: string | undefined; +}; + +/** + * The Pin + */ +export type GetPinResponseBody = { + /** + * PinID for use with authentication + */ + id?: number | undefined; + code?: string | undefined; + product?: string | undefined; + trusted?: boolean | undefined; + /** + * a link to a QR code hosted on plex.tv + * + * @remarks + * The QR code redirects to the relevant `plex.tv/link` authentication page + * Which then prompts the user for the 4 Digit Link Pin + * + */ + qr?: string | undefined; + clientIdentifier?: string | undefined; + location?: Location | undefined; + expiresIn?: number | undefined; + createdAt?: Date | undefined; + expiresAt?: Date | undefined; + authToken?: string | undefined; + newRegistration?: string | undefined; +}; + +export type GetPinResponse = { + /** + * HTTP response content type for this operation + */ + contentType: string; + /** + * HTTP response status code for this operation + */ + statusCode: number; + /** + * Raw HTTP response; suitable for custom response parsing + */ + rawResponse: Response; + /** + * The Pin + */ + object?: GetPinResponseBody | undefined; +}; + +/** @internal */ +export namespace GetPinRequest$ { + export type Inbound = { + "X-Plex-Client-Identifier": string; + strong?: boolean | undefined; + }; + + export const inboundSchema: z.ZodType = z + .object({ + "X-Plex-Client-Identifier": z.string(), + strong: z.boolean().default(false), + }) + .transform((v) => { + return { + xPlexClientIdentifier: v["X-Plex-Client-Identifier"], + ...(v.strong === undefined ? null : { strong: v.strong }), + }; + }); + + export type Outbound = { + "X-Plex-Client-Identifier": string; + strong: boolean; + }; + + export const outboundSchema: z.ZodType = z + .object({ + xPlexClientIdentifier: z.string(), + strong: z.boolean().default(false), + }) + .transform((v) => { + return { + "X-Plex-Client-Identifier": v.xPlexClientIdentifier, + strong: v.strong, + }; + }); +} + +/** @internal */ +export namespace Location$ { + export type Inbound = { + code?: string | undefined; + european_union_member?: boolean | undefined; + continent_code?: string | undefined; + country?: string | undefined; + city?: string | undefined; + time_zone?: string | undefined; + postal_code?: number | undefined; + in_privacy_restricted_country?: boolean | undefined; + subdivisions?: string | undefined; + coordinates?: string | undefined; + }; + + export const inboundSchema: z.ZodType = z + .object({ + code: z.string().optional(), + european_union_member: z.boolean().optional(), + continent_code: z.string().optional(), + country: z.string().optional(), + city: z.string().optional(), + time_zone: z.string().optional(), + postal_code: z.number().optional(), + in_privacy_restricted_country: z.boolean().optional(), + subdivisions: z.string().optional(), + coordinates: z.string().optional(), + }) + .transform((v) => { + return { + ...(v.code === undefined ? null : { code: v.code }), + ...(v.european_union_member === undefined + ? null + : { europeanUnionMember: v.european_union_member }), + ...(v.continent_code === undefined ? null : { continentCode: v.continent_code }), + ...(v.country === undefined ? null : { country: v.country }), + ...(v.city === undefined ? null : { city: v.city }), + ...(v.time_zone === undefined ? null : { timeZone: v.time_zone }), + ...(v.postal_code === undefined ? null : { postalCode: v.postal_code }), + ...(v.in_privacy_restricted_country === undefined + ? null + : { inPrivacyRestrictedCountry: v.in_privacy_restricted_country }), + ...(v.subdivisions === undefined ? null : { subdivisions: v.subdivisions }), + ...(v.coordinates === undefined ? null : { coordinates: v.coordinates }), + }; + }); + + export type Outbound = { + code?: string | undefined; + european_union_member?: boolean | undefined; + continent_code?: string | undefined; + country?: string | undefined; + city?: string | undefined; + time_zone?: string | undefined; + postal_code?: number | undefined; + in_privacy_restricted_country?: boolean | undefined; + subdivisions?: string | undefined; + coordinates?: string | undefined; + }; + + export const outboundSchema: z.ZodType = z + .object({ + code: z.string().optional(), + europeanUnionMember: z.boolean().optional(), + continentCode: z.string().optional(), + country: z.string().optional(), + city: z.string().optional(), + timeZone: z.string().optional(), + postalCode: z.number().optional(), + inPrivacyRestrictedCountry: z.boolean().optional(), + subdivisions: z.string().optional(), + coordinates: z.string().optional(), + }) + .transform((v) => { + return { + ...(v.code === undefined ? null : { code: v.code }), + ...(v.europeanUnionMember === undefined + ? null + : { european_union_member: v.europeanUnionMember }), + ...(v.continentCode === undefined ? null : { continent_code: v.continentCode }), + ...(v.country === undefined ? null : { country: v.country }), + ...(v.city === undefined ? null : { city: v.city }), + ...(v.timeZone === undefined ? null : { time_zone: v.timeZone }), + ...(v.postalCode === undefined ? null : { postal_code: v.postalCode }), + ...(v.inPrivacyRestrictedCountry === undefined + ? null + : { in_privacy_restricted_country: v.inPrivacyRestrictedCountry }), + ...(v.subdivisions === undefined ? null : { subdivisions: v.subdivisions }), + ...(v.coordinates === undefined ? null : { coordinates: v.coordinates }), + }; + }); +} + +/** @internal */ +export namespace GetPinResponseBody$ { + export type Inbound = { + id?: number | undefined; + code?: string | undefined; + product?: string | undefined; + trusted?: boolean | undefined; + qr?: string | undefined; + clientIdentifier?: string | undefined; + location?: Location$.Inbound | undefined; + expiresIn?: number | undefined; + createdAt?: string | undefined; + expiresAt?: string | undefined; + authToken?: string | undefined; + newRegistration?: string | undefined; + }; + + export const inboundSchema: z.ZodType = z + .object({ + id: z.number().optional(), + code: z.string().optional(), + product: z.string().optional(), + trusted: z.boolean().optional(), + qr: z.string().optional(), + clientIdentifier: z.string().optional(), + location: z.lazy(() => Location$.inboundSchema).optional(), + expiresIn: z.number().optional(), + createdAt: z + .string() + .datetime({ offset: true }) + .transform((v) => new Date(v)) + .optional(), + expiresAt: z + .string() + .datetime({ offset: true }) + .transform((v) => new Date(v)) + .optional(), + authToken: z.string().optional(), + newRegistration: z.string().optional(), + }) + .transform((v) => { + return { + ...(v.id === undefined ? null : { id: v.id }), + ...(v.code === undefined ? null : { code: v.code }), + ...(v.product === undefined ? null : { product: v.product }), + ...(v.trusted === undefined ? null : { trusted: v.trusted }), + ...(v.qr === undefined ? null : { qr: v.qr }), + ...(v.clientIdentifier === undefined + ? null + : { clientIdentifier: v.clientIdentifier }), + ...(v.location === undefined ? null : { location: v.location }), + ...(v.expiresIn === undefined ? null : { expiresIn: v.expiresIn }), + ...(v.createdAt === undefined ? null : { createdAt: v.createdAt }), + ...(v.expiresAt === undefined ? null : { expiresAt: v.expiresAt }), + ...(v.authToken === undefined ? null : { authToken: v.authToken }), + ...(v.newRegistration === undefined + ? null + : { newRegistration: v.newRegistration }), + }; + }); + + export type Outbound = { + id?: number | undefined; + code?: string | undefined; + product?: string | undefined; + trusted?: boolean | undefined; + qr?: string | undefined; + clientIdentifier?: string | undefined; + location?: Location$.Outbound | undefined; + expiresIn?: number | undefined; + createdAt?: string | undefined; + expiresAt?: string | undefined; + authToken?: string | undefined; + newRegistration?: string | undefined; + }; + + export const outboundSchema: z.ZodType = z + .object({ + id: z.number().optional(), + code: z.string().optional(), + product: z.string().optional(), + trusted: z.boolean().optional(), + qr: z.string().optional(), + clientIdentifier: z.string().optional(), + location: z.lazy(() => Location$.outboundSchema).optional(), + expiresIn: z.number().optional(), + createdAt: z + .date() + .transform((v) => v.toISOString()) + .optional(), + expiresAt: z + .date() + .transform((v) => v.toISOString()) + .optional(), + authToken: z.string().optional(), + newRegistration: z.string().optional(), + }) + .transform((v) => { + return { + ...(v.id === undefined ? null : { id: v.id }), + ...(v.code === undefined ? null : { code: v.code }), + ...(v.product === undefined ? null : { product: v.product }), + ...(v.trusted === undefined ? null : { trusted: v.trusted }), + ...(v.qr === undefined ? null : { qr: v.qr }), + ...(v.clientIdentifier === undefined + ? null + : { clientIdentifier: v.clientIdentifier }), + ...(v.location === undefined ? null : { location: v.location }), + ...(v.expiresIn === undefined ? null : { expiresIn: v.expiresIn }), + ...(v.createdAt === undefined ? null : { createdAt: v.createdAt }), + ...(v.expiresAt === undefined ? null : { expiresAt: v.expiresAt }), + ...(v.authToken === undefined ? null : { authToken: v.authToken }), + ...(v.newRegistration === undefined + ? null + : { newRegistration: v.newRegistration }), + }; + }); +} + +/** @internal */ +export namespace GetPinResponse$ { + export type Inbound = { + ContentType: string; + StatusCode: number; + RawResponse: Response; + object?: GetPinResponseBody$.Inbound | undefined; + }; + + export const inboundSchema: z.ZodType = z + .object({ + ContentType: z.string(), + StatusCode: z.number().int(), + RawResponse: z.instanceof(Response), + object: z.lazy(() => GetPinResponseBody$.inboundSchema).optional(), + }) + .transform((v) => { + return { + contentType: v.ContentType, + statusCode: v.StatusCode, + rawResponse: v.RawResponse, + ...(v.object === undefined ? null : { object: v.object }), + }; + }); + + export type Outbound = { + ContentType: string; + StatusCode: number; + RawResponse: never; + object?: GetPinResponseBody$.Outbound | undefined; + }; + + export const outboundSchema: z.ZodType = z + .object({ + contentType: z.string(), + statusCode: z.number().int(), + rawResponse: z.instanceof(Response).transform(() => { + throw new Error("Response cannot be serialized"); + }), + object: z.lazy(() => GetPinResponseBody$.outboundSchema).optional(), + }) + .transform((v) => { + return { + ContentType: v.contentType, + StatusCode: v.statusCode, + RawResponse: v.rawResponse, + ...(v.object === undefined ? null : { object: v.object }), + }; + }); +} diff --git a/src/models/operations/gettoken.ts b/src/models/operations/gettoken.ts new file mode 100644 index 00000000..6f067617 --- /dev/null +++ b/src/models/operations/gettoken.ts @@ -0,0 +1,115 @@ +/* + * Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + */ + +import { z } from "zod"; + +export const GetTokenServerList = ["https://plex.tv/api/v2"] as const; + +export type GetTokenRequest = { + /** + * The PinID to retrieve an access token for + */ + pinID: string; + /** + * Plex Authentication Token + */ + xPlexClientIdentifier: string; +}; + +export type GetTokenResponse = { + /** + * HTTP response content type for this operation + */ + contentType: string; + /** + * HTTP response status code for this operation + */ + statusCode: number; + /** + * Raw HTTP response; suitable for custom response parsing + */ + rawResponse: Response; +}; + +/** @internal */ +export namespace GetTokenRequest$ { + export type Inbound = { + pinID: string; + "X-Plex-Client-Identifier": string; + }; + + export const inboundSchema: z.ZodType = z + .object({ + pinID: z.string(), + "X-Plex-Client-Identifier": z.string(), + }) + .transform((v) => { + return { + pinID: v.pinID, + xPlexClientIdentifier: v["X-Plex-Client-Identifier"], + }; + }); + + export type Outbound = { + pinID: string; + "X-Plex-Client-Identifier": string; + }; + + export const outboundSchema: z.ZodType = z + .object({ + pinID: z.string(), + xPlexClientIdentifier: z.string(), + }) + .transform((v) => { + return { + pinID: v.pinID, + "X-Plex-Client-Identifier": v.xPlexClientIdentifier, + }; + }); +} + +/** @internal */ +export namespace GetTokenResponse$ { + export type Inbound = { + ContentType: string; + StatusCode: number; + RawResponse: Response; + }; + + export const inboundSchema: z.ZodType = z + .object({ + ContentType: z.string(), + StatusCode: z.number().int(), + RawResponse: z.instanceof(Response), + }) + .transform((v) => { + return { + contentType: v.ContentType, + statusCode: v.StatusCode, + rawResponse: v.RawResponse, + }; + }); + + export type Outbound = { + ContentType: string; + StatusCode: number; + RawResponse: never; + }; + + export const outboundSchema: z.ZodType = z + .object({ + contentType: z.string(), + statusCode: z.number().int(), + rawResponse: z.instanceof(Response).transform(() => { + throw new Error("Response cannot be serialized"); + }), + }) + .transform((v) => { + return { + ContentType: v.contentType, + StatusCode: v.statusCode, + RawResponse: v.rawResponse, + }; + }); +} diff --git a/src/models/operations/index.ts b/src/models/operations/index.ts index 27697114..6bc46e08 100644 --- a/src/models/operations/index.ts +++ b/src/models/operations/index.ts @@ -24,6 +24,7 @@ export * from "./getmetadata"; export * from "./getmetadatachildren"; export * from "./getmyplexaccount"; export * from "./getondeck"; +export * from "./getpin"; export * from "./getplaylist"; export * from "./getplaylistcontents"; export * from "./getplaylists"; @@ -39,6 +40,7 @@ export * from "./getsessionhistory"; export * from "./getsessions"; export * from "./getsourceconnectioninformation"; export * from "./gettimeline"; +export * from "./gettoken"; export * from "./gettranscodesessions"; export * from "./gettransienttoken"; export * from "./getupdatestatus"; diff --git a/src/sdk/plex.ts b/src/sdk/plex.ts new file mode 100644 index 00000000..ccc4b23d --- /dev/null +++ b/src/sdk/plex.ts @@ -0,0 +1,27 @@ +/* + * Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + */ + +import { SDKOptions, serverURLFromOptions } from "../lib/config"; +import { HTTPClient } from "../lib/http"; +import { ClientSDK } from "../lib/sdks"; +import { Tv } from "./tv"; + +export class Plex extends ClientSDK { + private readonly options$: SDKOptions; + + constructor(options: SDKOptions = {}) { + super({ + client: options.httpClient || new HTTPClient(), + baseURL: serverURLFromOptions(options), + }); + + this.options$ = options; + void this.options$; + } + + private _tv?: Tv; + get tv() { + return (this._tv ??= new Tv(this.options$)); + } +} diff --git a/src/sdk/sdk.ts b/src/sdk/sdk.ts index c0460ca6..45ed16d4 100644 --- a/src/sdk/sdk.ts +++ b/src/sdk/sdk.ts @@ -12,6 +12,7 @@ import { Library } from "./library"; import { Log } from "./log"; import { Media } from "./media"; import { Playlists } from "./playlists"; +import { Plex } from "./plex"; import { Search } from "./search"; import { Security } from "./security"; import { Server } from "./server"; @@ -72,6 +73,11 @@ export class PlexAPI extends ClientSDK { return (this._log ??= new Log(this.options$)); } + private _plex?: Plex; + get plex() { + return (this._plex ??= new Plex(this.options$)); + } + private _playlists?: Playlists; get playlists() { return (this._playlists ??= new Playlists(this.options$)); diff --git a/src/sdk/tv.ts b/src/sdk/tv.ts new file mode 100644 index 00000000..445438f6 --- /dev/null +++ b/src/sdk/tv.ts @@ -0,0 +1,204 @@ +/* + * Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + */ + +import { SDK_METADATA, SDKOptions, serverURLFromOptions } from "../lib/config"; +import * as enc$ from "../lib/encodings"; +import { HTTPClient } from "../lib/http"; +import { ClientSDK, RequestOptions } from "../lib/sdks"; +import * as errors from "../models/errors"; +import * as operations from "../models/operations"; + +export class Tv extends ClientSDK { + private readonly options$: SDKOptions; + + constructor(options: SDKOptions = {}) { + super({ + client: options.httpClient || new HTTPClient(), + baseURL: serverURLFromOptions(options), + }); + + this.options$ = options; + void this.options$; + } + /** + * Get a Pin + * + * @remarks + * Retrieve a Pin from Plex.tv for authentication flows + */ + async getPin( + xPlexClientIdentifier: string, + strong?: boolean | undefined, + options?: RequestOptions & { serverURL?: string } + ): Promise { + const input$: operations.GetPinRequest = { + xPlexClientIdentifier: xPlexClientIdentifier, + strong: strong, + }; + const headers$ = new Headers(); + headers$.set("user-agent", SDK_METADATA.userAgent); + headers$.set("Accept", "application/json"); + + const payload$ = operations.GetPinRequest$.outboundSchema.parse(input$); + const body$ = null; + + const path$ = this.templateURLComponent("/pins")(); + + const query$ = [ + enc$.encodeForm("strong", payload$.strong, { explode: true, charEncoding: "percent" }), + ] + .filter(Boolean) + .join("&"); + + headers$.set( + "X-Plex-Client-Identifier", + enc$.encodeSimple("X-Plex-Client-Identifier", payload$["X-Plex-Client-Identifier"], { + explode: false, + charEncoding: "none", + }) + ); + const baseURL$ = + options?.serverURL || + this.templateURLComponent(operations.GetPinServerList[0], { + charEncoding: "percent", + })(); + + let security$; + if (typeof this.options$.accessToken === "function") { + security$ = { accessToken: await this.options$.accessToken() }; + } else if (this.options$.accessToken) { + security$ = { accessToken: this.options$.accessToken }; + } else { + security$ = {}; + } + const securitySettings$ = this.resolveGlobalSecurity(security$); + + const response = await this.fetch$( + { + security: securitySettings$, + method: "POST", + baseURL: baseURL$, + path: path$, + headers: headers$, + query: query$, + body: body$, + }, + options + ); + + const responseFields$ = { + ContentType: response.headers.get("content-type") ?? "application/octet-stream", + StatusCode: response.status, + RawResponse: response, + }; + + if (this.matchResponse(response, 200, "application/json")) { + const responseBody = await response.json(); + const result = operations.GetPinResponse$.inboundSchema.parse({ + ...responseFields$, + object: responseBody, + }); + return result; + } else if (this.matchResponse(response, 400, "application/json")) { + const responseBody = await response.json(); + const result = errors.GetPinResponseBody$.inboundSchema.parse({ + ...responseFields$, + ...responseBody, + }); + throw result; + } else { + const responseBody = await response.text(); + throw new errors.SDKError("Unexpected API response", response, responseBody); + } + } + + /** + * Get Access Token + * + * @remarks + * Retrieve an Access Token from Plex.tv after the Pin has already been authenticated + */ + async getToken( + pinID: string, + xPlexClientIdentifier: string, + options?: RequestOptions & { serverURL?: string } + ): Promise { + const input$: operations.GetTokenRequest = { + pinID: pinID, + xPlexClientIdentifier: xPlexClientIdentifier, + }; + const headers$ = new Headers(); + headers$.set("user-agent", SDK_METADATA.userAgent); + headers$.set("Accept", "application/json"); + + const payload$ = operations.GetTokenRequest$.outboundSchema.parse(input$); + const body$ = null; + + const pathParams$ = { + pinID: enc$.encodeSimple("pinID", payload$.pinID, { + explode: false, + charEncoding: "percent", + }), + }; + + const path$ = this.templateURLComponent("/pins/{pinID}")(pathParams$); + + headers$.set( + "X-Plex-Client-Identifier", + enc$.encodeSimple("X-Plex-Client-Identifier", payload$["X-Plex-Client-Identifier"], { + explode: false, + charEncoding: "none", + }) + ); + const baseURL$ = + options?.serverURL || + this.templateURLComponent(operations.GetTokenServerList[0], { + charEncoding: "percent", + })(); + + let security$; + if (typeof this.options$.accessToken === "function") { + security$ = { accessToken: await this.options$.accessToken() }; + } else if (this.options$.accessToken) { + security$ = { accessToken: this.options$.accessToken }; + } else { + security$ = {}; + } + const securitySettings$ = this.resolveGlobalSecurity(security$); + + const response = await this.fetch$( + { + security: securitySettings$, + method: "GET", + baseURL: baseURL$, + path: path$, + headers: headers$, + body: body$, + }, + options + ); + + const responseFields$ = { + ContentType: response.headers.get("content-type") ?? "application/octet-stream", + StatusCode: response.status, + RawResponse: response, + }; + + if (this.matchStatusCode(response, 200)) { + // fallthrough + } else if (this.matchResponse(response, 400, "application/json")) { + const responseBody = await response.json(); + const result = errors.GetTokenResponseBody$.inboundSchema.parse({ + ...responseFields$, + ...responseBody, + }); + throw result; + } else { + const responseBody = await response.text(); + throw new errors.SDKError("Unexpected API response", response, responseBody); + } + + return operations.GetTokenResponse$.inboundSchema.parse(responseFields$); + } +}