LukeHagar / plex-api-spec

An open source Plex Media Server API Specification
MIT License
37 stars 11 forks source link

Allow interaction with providers #13

Open chrishoage opened 7 months ago

chrishoage commented 7 months ago

Providers from Plex (Tidal Music Integration, Watchlist) expose an almost identical API as Plex Servers.

However restrictions in the schema prevent these sdks from using a provider as an input.

For example one can set up an instance like so:

const discoverProvider = new PlexAPI({ accessToken: "TOKEN", serverURL: "https://discover.provider.plex.tv" });

However trying to interact with the watchlist library section ID ends up with an error

> await discoverProvider.library.getLibraryItems("watchlist")
Uncaught SDKValidationError: Input validation failed
    at Object.parse (file:///home/chris/.cache/deno/npm/registry.npmjs.org/@lukehagar/plexjs/0.13.2/lib/schemas.js:43:19)
    at Library.getLibraryItems (file:///home/chris/.cache/deno/npm/registry.npmjs.org/@lukehagar/plexjs/0.13.2/sdk/library.js:512:35)
    at <anonymous>:1:41

Looking the schema, the input is restricted to a number. Taking a peek at the code relaxing this to be a number or string should allow reading these provider libraries, which otherwise return the same API shape

Would it be possible to update the schema to allow for this possibility?

LukeHagar commented 6 months ago

Fantastic observation! I just updated the specification to reflect both values as possible.

LukeHagar commented 6 months ago

The various SDKs should be regenerated shortly, please let me know if things work as you would expect.

LukeHagar commented 6 months ago

I would note that documenting the provider API is also something I would like to do, so if we want to create a list of the valid provider server endpoints, and what methods exactly the support that would be a great thing to include.

LukeHagar commented 6 months ago

Circling back around here, this change will have to wait for a feature to be implemented in the SDK package, I'm reverting this change for now.

chrishoage commented 6 months ago

No problem I'll keep an eye on this issue to see.

Thank you!

LukeHagar commented 5 months ago

This is tentatively resolved in the newest release. Can you pull it down and validate it?

chrishoage commented 5 months ago

So I noticed I had some user error in my original example

getLibraryItems appears to require two parameters, and I was only supplying one in my example code above. However I think the original issue was still an issue.

I updated my example to await watch.library.getLibraryItems("watchlist", "all") and I got a different error, but this time an error on the response.

It appears that this error is about the type of ibrarySectionID - similarly expecting a number and getting a string.

> try { await watch.library.getLibraryItems("watchlist", "all") } catch (e) { console.log(e.pretty()) }
Response validation failed
┌ 1 issue found:
│ • [<root>.object.MediaContainer.librarySectionID]: Expected number, received string (invalid_type)
│     Want: number
│      Got: string
└─*
LukeHagar commented 5 months ago

Can you confirm you updated the package? The newest NPM release should fix the type issue

chrishoage commented 5 months ago

Yes, I can confirm I updated the package.

The type issue before was the getLibraryItems argument.

As I mentioned in my previous comment the issue now is the response shape, not the input validation.

https://github.com/LukeHagar/plexjs/blob/main/src/models/getlibraryitemsop.ts#L207

LukeHagar commented 5 months ago

Understood, I just updated the value to a type array Package should be regenerated and published soon

chrishoage commented 5 months ago

I noticed version 18 was published today. I can confirm everything works!

I tested using the following in Deno and I get the expected response back. Thank you!

import { PlexAPI } from "npm:@lukehagar/plexjs@0.18";
let watch = new PlexAPI({ accessToken: "TOKEN", serverURL: "https://discover.provider.plex.tv" })
let watchlist = await watch.library.getLibraryItems("watchlist", "all")
console.log(watchlist.object.mediaContainer.metadata.length)