@ctrl/plex 3.6.1 → 3.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -8
- package/dist/src/audio.d.ts +295 -0
- package/dist/src/audio.js +578 -0
- package/dist/src/audio.types.d.ts +106 -0
- package/dist/src/audio.types.js +1 -0
- package/dist/src/base/partialPlexObject.d.ts +2 -1
- package/dist/src/client.js +1 -1
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.js +1 -0
- package/dist/src/library.d.ts +51 -13
- package/dist/src/library.js +73 -8
- package/dist/src/media.d.ts +45 -0
- package/dist/src/media.js +59 -0
- package/dist/src/myplex.js +4 -0
- package/dist/src/playlist.d.ts +3 -3
- package/dist/src/server.js +1 -1
- package/dist/src/video.d.ts +0 -1
- package/package.json +43 -26
package/README.md
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
# @ctrl/plex
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/@ctrl/plex)
|
|
4
|
-
[](https://codecov.io/gh/scttcper/plex)
|
|
5
4
|
|
|
6
|
-
> A TypeScript [Plex](https://www.plex.tv/) API client based on [pkkid/python-plexapi](https://github.com/
|
|
5
|
+
> A TypeScript [Plex](https://www.plex.tv/) API client using [ofetch](https://github.com/unjs/ofetch) based on [pkkid/python-plexapi](https://github.com/pushingkarmaorg/python-plexapi)
|
|
7
6
|
|
|
8
7
|
### Install
|
|
9
8
|
|
|
@@ -13,11 +12,12 @@ npm install @ctrl/plex
|
|
|
13
12
|
|
|
14
13
|
### Docs
|
|
15
14
|
|
|
16
|
-
https://ctrl-plex.vercel.app
|
|
15
|
+
https://ctrl-plex.vercel.app
|
|
17
16
|
|
|
18
17
|
### Use
|
|
19
18
|
|
|
20
19
|
Create a plex connection
|
|
20
|
+
|
|
21
21
|
```ts
|
|
22
22
|
import { MyPlexAccount } from '@ctrl/plex';
|
|
23
23
|
|
|
@@ -28,6 +28,7 @@ const library = await plex.library();
|
|
|
28
28
|
```
|
|
29
29
|
|
|
30
30
|
###### Example 1: List all unwatched movies.
|
|
31
|
+
|
|
31
32
|
```ts
|
|
32
33
|
import { MovieSection } from '@ctrl/plex';
|
|
33
34
|
|
|
@@ -38,6 +39,7 @@ const results = await section.search({ unwatched: true });
|
|
|
38
39
|
```
|
|
39
40
|
|
|
40
41
|
###### Example 2: Search for a list of movies containing a title
|
|
42
|
+
|
|
41
43
|
```ts
|
|
42
44
|
const library = await plex.library();
|
|
43
45
|
const section = await library.section<MovieSection>('Movies');
|
|
@@ -45,6 +47,7 @@ const results = await section.search({ title: 'Rush Hour' });
|
|
|
45
47
|
```
|
|
46
48
|
|
|
47
49
|
###### Example 3: List all content containing a specific query
|
|
50
|
+
|
|
48
51
|
```ts
|
|
49
52
|
const results = await plex.search('Arnold');
|
|
50
53
|
// Each hub represents a single Hub (or category) in the PlexServer search (movie, actor, etc)
|
|
@@ -55,6 +58,7 @@ for (const hub of results) {
|
|
|
55
58
|
```
|
|
56
59
|
|
|
57
60
|
###### Example 4: List all episodes of a tv show.
|
|
61
|
+
|
|
58
62
|
```ts
|
|
59
63
|
import { ShowSection } from '@ctrl/plex';
|
|
60
64
|
|
|
@@ -66,7 +70,8 @@ const episodes = await results[0].episodes();
|
|
|
66
70
|
```
|
|
67
71
|
|
|
68
72
|
### Differences from python plex client
|
|
69
|
-
|
|
73
|
+
|
|
74
|
+
JS is a different language and some methods of the api were not possible.
|
|
70
75
|
Chaining functions with requests must be awaited mostly individually. Constructors in JS don't typically make requests
|
|
71
76
|
and accessing properties normally cannot make requests either.
|
|
72
77
|
|
|
@@ -99,13 +104,13 @@ Post testing, remove plex server from account. Warning this is destructive. Do n
|
|
|
99
104
|
npm run test-cleanup
|
|
100
105
|
```
|
|
101
106
|
|
|
102
|
-
|
|
103
107
|
### Running tests locally (mostly for myself)
|
|
104
108
|
|
|
105
109
|
get a claim token from https://www.plex.tv/claim/
|
|
106
110
|
export PLEX_CLAIM_TOKEN=claim-token
|
|
107
111
|
|
|
108
|
-
|
|
112
|
+
Start plex container for testing. Replace `/Users/scooper/gh/plex` with the path to this repo's directory.
|
|
113
|
+
|
|
109
114
|
```console
|
|
110
115
|
docker run -d \
|
|
111
116
|
--name=plex \
|
|
@@ -134,11 +139,13 @@ docker run -d \
|
|
|
134
139
|
```
|
|
135
140
|
|
|
136
141
|
Pull latest plex container if needed
|
|
142
|
+
|
|
137
143
|
```console
|
|
138
144
|
docker pull lscr.io/linuxserver/plex:latest
|
|
139
145
|
```
|
|
140
146
|
|
|
141
|
-
bootstrap plex server with test media
|
|
147
|
+
bootstrap plex server with test media. This assumes you have set the `PLEX_PASSWORD` and `PLEX_USERNAME` environment variables.
|
|
148
|
+
|
|
142
149
|
```console
|
|
143
|
-
|
|
150
|
+
npx tsx scripts/bootstraptest.ts --no-docker --server-name=orbstack --password=$PLEX_PASSWORD --username=$PLEX_USERNAME
|
|
144
151
|
```
|
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
import { PartialPlexObject } from './base/partialPlexObject.js';
|
|
2
|
+
import { PlexObject } from './base/plexObject.js';
|
|
3
|
+
import type { AlbumData, ArtistData, TrackData } from './audio.types.js';
|
|
4
|
+
import { Chapter, Collection, Country, Field, Format, Genre, Guid, Image, Label, Media, Mood, Similar, Style, Subformat } from './media.js';
|
|
5
|
+
import type { PlexServer } from './server.js';
|
|
6
|
+
/**
|
|
7
|
+
* Base class for all audio objects including Artist, Album, and Track.
|
|
8
|
+
*/
|
|
9
|
+
export declare class Audio extends PartialPlexObject {
|
|
10
|
+
/** Default metadata type for audio sync items. */
|
|
11
|
+
static METADATA_TYPE: string;
|
|
12
|
+
/** Hardcoded list type for filtering. */
|
|
13
|
+
get listType(): 'audio';
|
|
14
|
+
addedAt?: Date;
|
|
15
|
+
art?: string;
|
|
16
|
+
artBlurHash?: string;
|
|
17
|
+
/** Sonic distance from a seed item, used in sonically similar results. */
|
|
18
|
+
distance?: number;
|
|
19
|
+
guid?: string;
|
|
20
|
+
/** Plex index number (often the track number for tracks). */
|
|
21
|
+
index?: number;
|
|
22
|
+
lastRatedAt?: Date;
|
|
23
|
+
lastViewedAt?: Date;
|
|
24
|
+
/** Key of the library section this item belongs to. */
|
|
25
|
+
librarySectionKey?: string;
|
|
26
|
+
/** Title of the library section this item belongs to. */
|
|
27
|
+
librarySectionTitle?: string;
|
|
28
|
+
/** Plex music analysis version (1 indicates sonic analysis complete). */
|
|
29
|
+
musicAnalysisVersion?: number;
|
|
30
|
+
summary?: string;
|
|
31
|
+
thumb?: string;
|
|
32
|
+
thumbBlurHash?: string;
|
|
33
|
+
/** Title used for sorting (defaults to title). */
|
|
34
|
+
titleSort?: string;
|
|
35
|
+
updatedAt?: Date;
|
|
36
|
+
/** User rating (0.0-10.0). */
|
|
37
|
+
userRating?: number;
|
|
38
|
+
/** Count of times the item was played. */
|
|
39
|
+
viewCount?: number;
|
|
40
|
+
/** Store the raw data from the Plex API for lazy loading related items. */
|
|
41
|
+
protected _data?: any;
|
|
42
|
+
/** List of field objects. */
|
|
43
|
+
fields?: Field[];
|
|
44
|
+
/** List of image objects. */
|
|
45
|
+
images?: Image[];
|
|
46
|
+
/** List of mood objects. */
|
|
47
|
+
moods?: Mood[];
|
|
48
|
+
/**
|
|
49
|
+
* @protected Should not be called directly. Use `server.fetchItem()`.
|
|
50
|
+
* Initializes a new instance of the Audio class.
|
|
51
|
+
* @param server The PlexServer instance used for communication.
|
|
52
|
+
* @param data The raw data object received from the Plex API.
|
|
53
|
+
* @param initpath The path used to fetch this item initially.
|
|
54
|
+
*/
|
|
55
|
+
constructor(server: PlexServer, data: any, initpath: string | undefined, parent: PlexObject | undefined);
|
|
56
|
+
/**
|
|
57
|
+
* Returns the full URL for a given part (like a media stream) relative to the item's key.
|
|
58
|
+
* Includes the authentication token.
|
|
59
|
+
* @param part The relative path or resource identifier.
|
|
60
|
+
* @returns The full URL string including the server address and token, or undefined if part is empty.
|
|
61
|
+
*/
|
|
62
|
+
url(part: string): string | undefined;
|
|
63
|
+
/** Indicates if the audio item has undergone sonic analysis. */
|
|
64
|
+
get hasSonicAnalysis(): boolean;
|
|
65
|
+
/**
|
|
66
|
+
* Fetches a list of sonically similar audio items from the Plex server.
|
|
67
|
+
* The returned items will be instances of the same class as the current item
|
|
68
|
+
* (e.g., calling `sonicallySimilar` on a `Track` instance returns `Track[]`).
|
|
69
|
+
* @param limit Maximum number of similar items to return. Server default is 50.
|
|
70
|
+
* @param maxDistance Maximum sonic distance (0.0 - 1.0) between items. Server default is 0.25.
|
|
71
|
+
* @param options Optional additional filters to apply to the results.
|
|
72
|
+
* @returns A promise resolving to an array of sonically similar Audio items.
|
|
73
|
+
*/
|
|
74
|
+
sonicallySimilar(limit?: number, maxDistance?: number, options?: Record<string, string | number>): Promise<Audio[]>;
|
|
75
|
+
/**
|
|
76
|
+
* Provides a default title for Sync operations based on the item's title.
|
|
77
|
+
* @returns The item's title, or undefined if the title is not set.
|
|
78
|
+
* @protected
|
|
79
|
+
*/
|
|
80
|
+
protected _defaultSyncTitle(): string | undefined;
|
|
81
|
+
/**
|
|
82
|
+
* Populates the object's properties from the provided Plex API data.
|
|
83
|
+
* This method is called by the constructor and _loadFullData.
|
|
84
|
+
* @param data The raw data object from the Plex API.
|
|
85
|
+
* @protected
|
|
86
|
+
*/
|
|
87
|
+
protected _loadData(data: Record<string, any>): void;
|
|
88
|
+
/**
|
|
89
|
+
* Overrides `PartialPlexObject._loadFullData` to apply Audio-specific attributes
|
|
90
|
+
* after fetching the full item data.
|
|
91
|
+
* @param data The raw data object representing the full item from the Plex API.
|
|
92
|
+
* @protected
|
|
93
|
+
*/
|
|
94
|
+
protected _loadFullData(data: any): void;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Represents a single Track.
|
|
98
|
+
*/
|
|
99
|
+
export declare class Track extends Audio {
|
|
100
|
+
static TAG: string;
|
|
101
|
+
static TYPE: string;
|
|
102
|
+
audienceRating?: number;
|
|
103
|
+
chapterSource?: string;
|
|
104
|
+
duration?: number;
|
|
105
|
+
grandparentArt?: string;
|
|
106
|
+
grandparentGuid?: string;
|
|
107
|
+
grandparentKey?: string;
|
|
108
|
+
grandparentRatingKey?: number;
|
|
109
|
+
grandparentTheme?: string;
|
|
110
|
+
grandparentThumb?: string;
|
|
111
|
+
grandparentTitle?: string;
|
|
112
|
+
originalTitle?: string;
|
|
113
|
+
parentGuid?: string;
|
|
114
|
+
parentIndex?: number;
|
|
115
|
+
parentKey?: string;
|
|
116
|
+
parentRatingKey?: number;
|
|
117
|
+
parentThumb?: string;
|
|
118
|
+
parentTitle?: string;
|
|
119
|
+
primaryExtraKey?: string;
|
|
120
|
+
rating?: number;
|
|
121
|
+
skipCount?: number;
|
|
122
|
+
sourceURI?: string;
|
|
123
|
+
viewOffset?: number;
|
|
124
|
+
chapters?: Chapter[];
|
|
125
|
+
collections?: Collection[];
|
|
126
|
+
genres?: Genre[];
|
|
127
|
+
guids?: Guid[];
|
|
128
|
+
labels?: Label[];
|
|
129
|
+
media?: Media[];
|
|
130
|
+
constructor(server: PlexServer, data: any, initpath: string | undefined, parent: PlexObject | undefined);
|
|
131
|
+
/**
|
|
132
|
+
* @returns List of file paths where the track is found on disk.
|
|
133
|
+
*/
|
|
134
|
+
get locations(): string[];
|
|
135
|
+
/**
|
|
136
|
+
* @returns The track number.
|
|
137
|
+
*/
|
|
138
|
+
get trackNumber(): number | undefined;
|
|
139
|
+
/**
|
|
140
|
+
* @returns A filename for use in download.
|
|
141
|
+
*/
|
|
142
|
+
prettyfilename(): string;
|
|
143
|
+
/**
|
|
144
|
+
* Return the track's Album.
|
|
145
|
+
*/
|
|
146
|
+
album(): Promise<Album>;
|
|
147
|
+
/**
|
|
148
|
+
* Return the track's Artist.
|
|
149
|
+
*/
|
|
150
|
+
artist(): Promise<Artist>;
|
|
151
|
+
/**
|
|
152
|
+
* @returns Default title for a new syncItem.
|
|
153
|
+
*/
|
|
154
|
+
_defaultSyncTitle(): string;
|
|
155
|
+
/**
|
|
156
|
+
* Returns the Plex Web URL pointing to the album details page for this track.
|
|
157
|
+
*/
|
|
158
|
+
getWebURL(base?: string): string;
|
|
159
|
+
/**
|
|
160
|
+
* Returns a sonic adventure from the current track to the specified track.
|
|
161
|
+
* @param to The target track for the sonic adventure.
|
|
162
|
+
*/
|
|
163
|
+
sonicAdventure(to: Track): Promise<Track[]>;
|
|
164
|
+
/**
|
|
165
|
+
* Populates the object's properties from the provided Plex API data,
|
|
166
|
+
* overriding the base Audio class method to add Track-specific attributes.
|
|
167
|
+
* @param data The raw data object from the Plex API.
|
|
168
|
+
* @protected
|
|
169
|
+
*/
|
|
170
|
+
_loadData(data: TrackData): void;
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Represents a single Artist.
|
|
174
|
+
*/
|
|
175
|
+
export declare class Artist extends Audio {
|
|
176
|
+
static TAG: string;
|
|
177
|
+
static TYPE: string;
|
|
178
|
+
albumSort?: number;
|
|
179
|
+
audienceRating?: number;
|
|
180
|
+
rating?: number;
|
|
181
|
+
theme?: string;
|
|
182
|
+
countries?: Country[];
|
|
183
|
+
genres?: Genre[];
|
|
184
|
+
guids?: Guid[];
|
|
185
|
+
labels?: Label[];
|
|
186
|
+
similar?: Similar[];
|
|
187
|
+
styles?: Style[];
|
|
188
|
+
collections?: Collection[];
|
|
189
|
+
get locations(): string[];
|
|
190
|
+
constructor(server: PlexServer, data: any, initpath?: string, parent?: PlexObject);
|
|
191
|
+
/**
|
|
192
|
+
* Returns a list of Album objects by the artist.
|
|
193
|
+
* @param options Additional search options.
|
|
194
|
+
*/
|
|
195
|
+
albums(options?: Record<string, unknown>): Promise<Album[]>;
|
|
196
|
+
/**
|
|
197
|
+
* Returns the Album that matches the specified title for this artist.
|
|
198
|
+
* Case-insensitive exact match on title.
|
|
199
|
+
*/
|
|
200
|
+
album(title: string): Promise<Album | undefined>;
|
|
201
|
+
/**
|
|
202
|
+
* Returns the Track that matches the specified criteria.
|
|
203
|
+
* @param title Title of the track.
|
|
204
|
+
* @param album Album name (required if title not specified).
|
|
205
|
+
* @param track Track number (required if title not specified).
|
|
206
|
+
*/
|
|
207
|
+
track(args: {
|
|
208
|
+
title: string;
|
|
209
|
+
} | {
|
|
210
|
+
album: string;
|
|
211
|
+
track: number;
|
|
212
|
+
}): Promise<Track | undefined>;
|
|
213
|
+
/**
|
|
214
|
+
* Returns a list of Track objects by the artist.
|
|
215
|
+
* @param options Additional fetch options.
|
|
216
|
+
*/
|
|
217
|
+
tracks(options?: Record<string, string | number>): Promise<Track[]>;
|
|
218
|
+
/** Alias of track(). */
|
|
219
|
+
get(args: {
|
|
220
|
+
title: string;
|
|
221
|
+
} | {
|
|
222
|
+
album: string;
|
|
223
|
+
track: number;
|
|
224
|
+
}): Promise<Track | undefined>;
|
|
225
|
+
popularTracks(): Promise<Track[]>;
|
|
226
|
+
/**
|
|
227
|
+
* Load attribute values from Plex XML response.
|
|
228
|
+
* @protected
|
|
229
|
+
*/
|
|
230
|
+
_loadData(data: ArtistData): void;
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Represents a single Album.
|
|
234
|
+
*/
|
|
235
|
+
export declare class Album extends Audio {
|
|
236
|
+
static TAG: string;
|
|
237
|
+
static TYPE: string;
|
|
238
|
+
audienceRating?: number;
|
|
239
|
+
collections?: Collection[];
|
|
240
|
+
formats?: Format[];
|
|
241
|
+
genres?: Genre[];
|
|
242
|
+
guids?: Guid[];
|
|
243
|
+
labels?: Label[];
|
|
244
|
+
leafCount?: number;
|
|
245
|
+
loudnessAnalysisVersion?: number;
|
|
246
|
+
originallyAvailableAt?: Date;
|
|
247
|
+
/**
|
|
248
|
+
* Artist GUID
|
|
249
|
+
*/
|
|
250
|
+
parentGuid?: string;
|
|
251
|
+
/**
|
|
252
|
+
* Artist Key
|
|
253
|
+
*/
|
|
254
|
+
parentKey?: string;
|
|
255
|
+
/**
|
|
256
|
+
* Artist Rating Key
|
|
257
|
+
*/
|
|
258
|
+
parentRatingKey?: number;
|
|
259
|
+
/**
|
|
260
|
+
* Artist Theme
|
|
261
|
+
*/
|
|
262
|
+
parentTheme?: string;
|
|
263
|
+
/**
|
|
264
|
+
* Artist Thumb
|
|
265
|
+
*/
|
|
266
|
+
parentThumb?: string;
|
|
267
|
+
/**
|
|
268
|
+
* Artist Title
|
|
269
|
+
*/
|
|
270
|
+
parentTitle?: string;
|
|
271
|
+
rating?: number;
|
|
272
|
+
studio?: string;
|
|
273
|
+
styles?: Style[];
|
|
274
|
+
subformats?: Subformat[];
|
|
275
|
+
viewedLeafCount?: number;
|
|
276
|
+
constructor(server: PlexServer, data: any, initpath: string | undefined, parent: PlexObject | undefined);
|
|
277
|
+
/**
|
|
278
|
+
* Returns a list of Track objects in the album.
|
|
279
|
+
* @param options Additional fetch options.
|
|
280
|
+
*/
|
|
281
|
+
tracks(options?: Record<string, string | number>): Promise<Track[]>;
|
|
282
|
+
/**
|
|
283
|
+
* Return the album's Artist.
|
|
284
|
+
*/
|
|
285
|
+
artist(): Promise<Artist>;
|
|
286
|
+
/**
|
|
287
|
+
* Returns the default title for a sync item.
|
|
288
|
+
*/
|
|
289
|
+
_defaultSyncTitle(): string;
|
|
290
|
+
/**
|
|
291
|
+
* Load attribute values from Plex XML response.
|
|
292
|
+
* @protected
|
|
293
|
+
*/
|
|
294
|
+
_loadData(data: AlbumData): void;
|
|
295
|
+
}
|