Repository navigation
A big maintenance release. Requires Node 24, upgrades every dependency, turns on strict null types, finishes PlexClient, and fixes a batch of bugs that were silently returning wrong data. Everything landed in #60, which also rolled in #61, #62 and #63.
Upgrading from v7
Node.js 24 or newer is required.
Types are strict. strictNullChecks is on, so fields Plex can leave out are typed T | undefined. Expect new compile errors where code assumed a value was always there. PlexServer.query() and MyPlexAccount.query() return unknown unless you pass a type argument.
Positional arguments became options objects:
// v7
await account.device('Living Room');
await resource.connect(true, 10_000);
await device.connect(10_000);
await queue.removeItem(item, false);
await movie.updateProgress(90_000, 'paused');
await client.seekTo(1000, 'video');
client.proxyThroughServer(true, server);
// v8
await account.device({ name: 'Living Room' }); // or { clientIdentifier }
await resource.connect({ ssl: true, timeout: 10_000 });
await device.connect({ timeout: 10_000 });
await queue.removeItem(item, { refresh: false });
await movie.updateProgress({ time: 90_000, state: 'paused' });
await client.seekTo(1000, { type: 'video' });
client.proxyThroughServer({ server });Other changes that may need code updates:
- Music sections list artists by default.
MusicSectionisLibrarySection<Artist>, soall(),get(),search(),recentlyAdded()andcollections()returnArtistunless you pass alibtype. onDeck()returnsLibrarySearchItem[]on a generic section,Episode[]on shows andTrack[]on music.MusicSection.stations()returnsPlaylist[].- Audio
artandthumbare server paths. UseartUrl/thumbUrlfor URLs with a token. - plex.tv devices come from the JSON API.
MyPlexDevice.idis a number,connectionsis always an array, andMyPlexDeviceno longer extendsPlexObject. - Collection items need a
type. Passing plain{ ratingKey }objects tocreateCollection()throwsBadRequestinstead of guessing the section type.
Full list of breaking changes
- PlexClient: Commands take
{ type }instead of a positionalmtypeand resolve tovoid.proxyThroughServer({ enabled, server }),query({ path, method, headers }),timelines({ wait })andisPlayingMedia({ includePaused })take options objects.isPlayingMedia()defaultsincludePausedto true and checks every timeline.createPlayQueue()uses the server the items came from._baseurl,_token,_serverand_proxyThroughServerare replaced bybaseurl,serverandisProxied.PlexOptionsis nowPlexClientOptions.ClientTimelineleaves missing values undefined instead of0or''. - Connections:
MyPlexResource.connect(ssl, timeout)andMyPlexDevice.connect(timeout)areconnect({ timeout }). - MyPlexDevice: No longer extends
PlexObjectand is built from(account, data)with plex.tv's v2 device JSON.idis a number.version,productVersion,vendor,screenDensityandtokenare optional.connectionsis always an array. - Options objects:
updateProgress(),updateTimeline(),PlayQueue.removeItem()andMyPlexAccount.device({ name } | { clientIdentifier }). - Library:
MusicSectionisLibrarySection<Artist>.onDeck()returnsLibrarySearchItem[](Episode[]for shows,Track[]for music).MusicSection.stations()returnsPlaylist[]. Regular collection items need atype. - Types:
query()onPlexServerandMyPlexAccountreturnsunknownby default.PartialPlexObject.delete()resolves tovoid.- Fields Plex omits are optional across Media, MediaPart, streams, Video, Movie, Show, Season, Episode, Collections, LibrarySection, Hub and SearchResult.
PlexObject.keyis optional andparentis aWeakRef<PlexObject>.thumbUrl,artUrlandresourceFilepathcan returnundefined. - Show and Episode
originallyAvailableAtare optional instead of anInvalid Date. PlaylistaddedAt/updatedAtare optional. CollectionsaddedAt/updatedAtareDates.playQueueSelectedMetadataItemIDis a string. MarkerandChapterno longer extendMediaTag.Video.uploadPoster()requiresurlorfile.
- plex.tv:
MyPlexServerSectionsResponseis replaced byMyPlexServerResponseandPLEXSERVERSpoints at the v2 endpoint. XML responses fromMyPlexAccount.query()no longer wrap attributes in$, so theMyPlexUser,MyPlexInviteandMyPlexServerSharedata types are flat. - Alerts:
AlertListener._wsis a standardWebSocket, and connection errors carry the socket event as theircause.
New
setPlexHeaders({ product, version, identifier, ... })so Plex lists your app under its own name and client identifier instead of PlexAPI.PlexClientis a typed API: navigation, playback, streams, parameters,playMedia(),createPlayQueue()andtimelines(). It works directly or through the server proxy, and handles players that answer in XML or plain text.connectClient()onMyPlexResourceandMyPlexDeviceconnects to a player instead of a server.createPlayQueue()on collections and photo albums.- Fields that appear in real payloads were never loaded before and are now. Examples: Media
container,videoResolutionandaudioProfile; AudioStreamgainOffsetandcanNormalizeLoudness; slugs, audience ratings andnetworkon videos;contentChangedAton library sections.
Fixes
- Every
AudioStreamvalue (channels,samplingRate,gain,loudness, ...) was alwaysundefined. season.reload()andsection.reload()wiped every field, includingratingKeyandkey.- Music sections built
Trackobjects for artist rows, andonDeck()built shows from episode rows. Collections.create()in a music section made an empty artist collection, and playlist dates landed in 1970.Episode.section()was flaky depending on garbage collection.PlayQueue.removeItem()andclear()kept stale totals.PlexClient.playMedia()could play the wrong queue item and never sent the server address, port, type or token.MusicSection.stations()always returnedundefined.PlexServer.url()andPlexClient.url()dropped existing query params when adding the token.MyPlexDevice.delete()threw for accounts created withnew MyPlexAccount().- Importing a model module such as
audio.tsbefore the package index built the item class map too early, so track lookups quietly fell back to the section's class. - Devices get their per-device tokens again. plex.tv's
devices.xmlhad stopped sending them. - Show and episode air dates were an
Invalid Datewhen Plex had none, and media flags such asoptimizedForStreamingwere1instead oftrue.
Dependencies
Runtime dependencies go from seven to four: fast-xml-parser, jose, ofetch and uint8array-extras.
wsis replaced by Node's built-inWebSocket.@ctrl/mac-addressis replaced bynode:os, so client identifiers stay the same.type-festis dropped.xml2jsis replaced byfast-xml-parser, which only handles the plex.tv endpoints that have no JSON version (friends, invites, shared servers) and players that answer in XML.
Every other response is requested and parsed as JSON.
Full changelog: v7.1.0...v8.0.0