@ctrl/plex 3.7.0 → 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 +4 -5
- 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/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/video.d.ts +0 -1
- package/package.json +2 -2
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { Section } from '../library.js';
|
|
1
2
|
import { SearchResult } from '../search.js';
|
|
2
3
|
import { PlexObject } from './plexObject.js';
|
|
3
4
|
export declare abstract class PartialPlexObject extends PlexObject {
|
|
@@ -100,7 +101,7 @@ export declare abstract class PartialPlexObject extends PlexObject {
|
|
|
100
101
|
* @param mindate Min datetime to return results from.
|
|
101
102
|
*/
|
|
102
103
|
history(maxresults?: number, mindate?: Date): Promise<import("../server.types.js").HistoryMetadatum[]>;
|
|
103
|
-
section(): Promise<
|
|
104
|
+
section(): Promise<Section>;
|
|
104
105
|
/**
|
|
105
106
|
* Delete a media element. This has to be enabled under settings > server > library in plex webui.
|
|
106
107
|
*/
|
package/dist/src/index.d.ts
CHANGED
|
@@ -8,5 +8,6 @@ export * from './myplex.js';
|
|
|
8
8
|
export * from './playlist.js';
|
|
9
9
|
export * from './server.js';
|
|
10
10
|
export * from './video.js';
|
|
11
|
+
export * from './audio.js';
|
|
11
12
|
export { X_PLEX_IDENTIFIER } from './config.js';
|
|
12
13
|
export { SearchResult, Agent, SEARCHTYPES } from './search.js';
|
package/dist/src/index.js
CHANGED
|
@@ -7,5 +7,6 @@ export * from './myplex.js';
|
|
|
7
7
|
export * from './playlist.js';
|
|
8
8
|
export * from './server.js';
|
|
9
9
|
export * from './video.js';
|
|
10
|
+
export * from './audio.js';
|
|
10
11
|
export { X_PLEX_IDENTIFIER } from './config.js';
|
|
11
12
|
export { SearchResult, Agent, SEARCHTYPES } from './search.js';
|
package/dist/src/library.d.ts
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import type { Class } from 'type-fest';
|
|
2
2
|
import { PartialPlexObject } from './base/partialPlexObject.js';
|
|
3
3
|
import { PlexObject } from './base/plexObject.js';
|
|
4
|
+
import { Album, Artist, Track } from './audio.js';
|
|
4
5
|
import type { CollectionData, LibraryRootResponse, Location, SectionsDirectory } from './library.types.js';
|
|
5
6
|
import { Playlist } from './playlist.js';
|
|
6
7
|
import { type Agent, type SEARCHTYPES } from './search.js';
|
|
7
8
|
import type { SearchResult } from './search.types.js';
|
|
8
9
|
import type { PlexServer } from './server.js';
|
|
9
|
-
import { Movie, Show
|
|
10
|
-
export type Section = MovieSection | ShowSection;
|
|
10
|
+
import { Movie, Show } from './video.js';
|
|
11
|
+
export type Section = MovieSection | ShowSection | MusicSection;
|
|
11
12
|
export declare class Library {
|
|
12
13
|
private readonly server;
|
|
13
14
|
static key: string;
|
|
@@ -198,7 +199,7 @@ export declare class Library {
|
|
|
198
199
|
}
|
|
199
200
|
type Libtype = keyof typeof SEARCHTYPES;
|
|
200
201
|
interface SearchArgs {
|
|
201
|
-
[key: string]: number | string | boolean | string[]
|
|
202
|
+
[key: string]: number | string | boolean | string[] | Record<string, string | number | boolean>;
|
|
202
203
|
/** General string query to search for. Partial string matches are allowed. */
|
|
203
204
|
title: string;
|
|
204
205
|
/** A string of comma separated sort fields or a list of sort fields in the format ``column:dir``. */
|
|
@@ -221,11 +222,14 @@ interface SearchArgs {
|
|
|
221
222
|
* Return only results that have duplicates.
|
|
222
223
|
*/
|
|
223
224
|
duplicate: number;
|
|
225
|
+
/** Advanced filters object used by music searches. */
|
|
226
|
+
filters?: Record<string, string | number | boolean>;
|
|
224
227
|
}
|
|
228
|
+
export type SectionType = Movie | Show | Artist | Album | Track;
|
|
225
229
|
/**
|
|
226
230
|
* Base class for a single library section.
|
|
227
231
|
*/
|
|
228
|
-
export declare abstract class LibrarySection<
|
|
232
|
+
export declare abstract class LibrarySection<SType = SectionType> extends PlexObject {
|
|
229
233
|
static ALLOWED_FILTERS: string[];
|
|
230
234
|
static ALLOWED_SORT: string[];
|
|
231
235
|
static BOOLEAN_FILTERS: string[];
|
|
@@ -261,16 +265,16 @@ export declare abstract class LibrarySection<SectionVideoType = VideoType> exten
|
|
|
261
265
|
/** Unique id for this section (32258d7c-3e6c-4ac5-98ad-bad7a3b78c63) */
|
|
262
266
|
uuid: string;
|
|
263
267
|
CONTENT_TYPE: string;
|
|
264
|
-
readonly
|
|
268
|
+
readonly SECTION_TYPE: Class<SType>;
|
|
265
269
|
_filterTypes?: FilteringType[];
|
|
266
270
|
_fieldTypes?: FilteringFieldType[];
|
|
267
|
-
all(sort?: string): Promise<
|
|
271
|
+
all(sort?: string): Promise<SType[]>;
|
|
268
272
|
agents(): Promise<Agent[]>;
|
|
269
273
|
/**
|
|
270
274
|
* @param title Title of the item to return.
|
|
271
275
|
* @returns the media item with the specified title.
|
|
272
276
|
*/
|
|
273
|
-
get(title: string): Promise<
|
|
277
|
+
get(title: string): Promise<SType>;
|
|
274
278
|
/**
|
|
275
279
|
* Returns the media item with the specified external IMDB, TMDB, or TVDB ID.
|
|
276
280
|
* Note: This search uses a PlexAPI operator so performance may be slow. All items from the
|
|
@@ -296,7 +300,7 @@ export declare abstract class LibrarySection<SectionVideoType = VideoType> exten
|
|
|
296
300
|
* result2 = guidLookup['tmdb://1399']
|
|
297
301
|
* result3 = guidLookup['tvdb://121361']
|
|
298
302
|
*/
|
|
299
|
-
getGuid(guid: string): Promise<
|
|
303
|
+
getGuid(guid: string): Promise<SType>;
|
|
300
304
|
/**
|
|
301
305
|
* Returns the Plex Web URL for the library.
|
|
302
306
|
*
|
|
@@ -316,7 +320,7 @@ export declare abstract class LibrarySection<SectionVideoType = VideoType> exten
|
|
|
316
320
|
* TLDR: This is untested but seems to work. Use library section search when you can.
|
|
317
321
|
* @param args Search using a number of different attributes
|
|
318
322
|
*/
|
|
319
|
-
search<
|
|
323
|
+
search<C = SType>(args?: Partial<SearchArgs>, Cls?: Class<C>): Promise<C[]>;
|
|
320
324
|
/**
|
|
321
325
|
* Run an analysis on all of the items in this library section.
|
|
322
326
|
* See :func:`~plexapi.base.PlexPartialObject.analyze` for more details.
|
|
@@ -361,7 +365,7 @@ export declare abstract class LibrarySection<SectionVideoType = VideoType> exten
|
|
|
361
365
|
* Returns a list of playlists from this library section.
|
|
362
366
|
*/
|
|
363
367
|
playlists(): Promise<Playlist[]>;
|
|
364
|
-
collections(args?: Record<string, number | string | boolean>): Promise<Collections<
|
|
368
|
+
collections(args?: Record<string, number | string | boolean>): Promise<Collections<SType>[]>;
|
|
365
369
|
/**
|
|
366
370
|
* Returns a list of available Folders for this library section.
|
|
367
371
|
*/
|
|
@@ -405,7 +409,7 @@ export declare class MovieSection extends LibrarySection<Movie> {
|
|
|
405
409
|
static TAG: string;
|
|
406
410
|
METADATA_TYPE: string;
|
|
407
411
|
CONTENT_TYPE: string;
|
|
408
|
-
readonly
|
|
412
|
+
readonly SECTION_TYPE: typeof Movie;
|
|
409
413
|
}
|
|
410
414
|
export declare class ShowSection extends LibrarySection<Show> {
|
|
411
415
|
static TYPE: string;
|
|
@@ -414,7 +418,7 @@ export declare class ShowSection extends LibrarySection<Show> {
|
|
|
414
418
|
static TAG: string;
|
|
415
419
|
METADATA_TYPE: string;
|
|
416
420
|
CONTENT_TYPE: string;
|
|
417
|
-
readonly
|
|
421
|
+
readonly SECTION_TYPE: typeof Show;
|
|
418
422
|
/**
|
|
419
423
|
* Returns a list of recently added episodes from this library section.
|
|
420
424
|
*
|
|
@@ -422,6 +426,40 @@ export declare class ShowSection extends LibrarySection<Show> {
|
|
|
422
426
|
*/
|
|
423
427
|
recentlyAdded(args: any, libtype?: string, maxresults?: number): Promise<Show[]>;
|
|
424
428
|
}
|
|
429
|
+
export declare class MusicSection extends LibrarySection<Track> {
|
|
430
|
+
static TYPE: string;
|
|
431
|
+
static TAG: string;
|
|
432
|
+
METADATA_TYPE: string;
|
|
433
|
+
CONTENT_TYPE: string;
|
|
434
|
+
readonly SECTION_TYPE: typeof Track;
|
|
435
|
+
/** Returns a list of Album objects in this section. */
|
|
436
|
+
albums(): Promise<Album[]>;
|
|
437
|
+
/**
|
|
438
|
+
* Returns the music stations Hub for this section, if available.
|
|
439
|
+
* TODO: Investigate how to return actual station items (Playlists?) from the Hub.
|
|
440
|
+
*/
|
|
441
|
+
stations(): Promise<Hub | undefined>;
|
|
442
|
+
/** Search for an artist. */
|
|
443
|
+
searchArtists(args?: Partial<SearchArgs>): Promise<Artist[]>;
|
|
444
|
+
/** Search for an album. */
|
|
445
|
+
searchAlbums(args?: Partial<SearchArgs>): Promise<Album[]>;
|
|
446
|
+
/** Search for a track. */
|
|
447
|
+
searchTracks(args?: Partial<SearchArgs>): Promise<Track[]>;
|
|
448
|
+
/** Returns a list of recently added artists from this library section. */
|
|
449
|
+
recentlyAddedArtists(maxresults?: number): Promise<Artist[]>;
|
|
450
|
+
/** Returns a list of recently added albums from this library section. */
|
|
451
|
+
recentlyAddedAlbums(maxresults?: number): Promise<Album[]>;
|
|
452
|
+
/** Returns a list of recently added tracks from this library section. */
|
|
453
|
+
recentlyAddedTracks(maxresults?: number): Promise<Track[]>;
|
|
454
|
+
/**
|
|
455
|
+
* Returns a list of tracks from this library section that are part of a sonic adventure.
|
|
456
|
+
* IDs should be of a track; other IDs will return an empty list or an error.
|
|
457
|
+
* @param start The Track or ID of the first track in the sonic adventure.
|
|
458
|
+
* @param end The Track or ID of the last track in the sonic adventure.
|
|
459
|
+
* @returns A list of tracks that are part of a sonic adventure.
|
|
460
|
+
*/
|
|
461
|
+
sonicAdventure(start: Track | number, end: Track | number): Promise<Track[]>;
|
|
462
|
+
}
|
|
425
463
|
/** Represents a single Hub (or category) in the PlexServer search */
|
|
426
464
|
export declare class Hub extends PlexObject {
|
|
427
465
|
static TAG: string;
|
|
@@ -446,7 +484,7 @@ export declare class Folder extends PlexObject {
|
|
|
446
484
|
subfolders(): Promise<Folder[]>;
|
|
447
485
|
protected _loadData(data: any): void;
|
|
448
486
|
}
|
|
449
|
-
export declare class Collections<CollectionVideoType =
|
|
487
|
+
export declare class Collections<CollectionVideoType = SectionType> extends PartialPlexObject {
|
|
450
488
|
static TAG: string;
|
|
451
489
|
TYPE: string;
|
|
452
490
|
guid: string;
|
package/dist/src/library.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { URLSearchParams } from 'url';
|
|
2
2
|
import { PartialPlexObject } from './base/partialPlexObject.js';
|
|
3
3
|
import { PlexObject } from './base/plexObject.js';
|
|
4
|
+
import { Album, Artist, Track } from './audio.js';
|
|
4
5
|
import { fetchItem, fetchItems, findItems } from './baseFunctionality.js';
|
|
5
6
|
import { NotFound } from './exceptions.js';
|
|
6
7
|
import { Playlist } from './playlist.js';
|
|
@@ -19,8 +20,11 @@ export class Library {
|
|
|
19
20
|
const key = '/library/sections';
|
|
20
21
|
const elems = await this.server.query(key);
|
|
21
22
|
const sections = [];
|
|
23
|
+
if (!elems.MediaContainer.Directory) {
|
|
24
|
+
return sections;
|
|
25
|
+
}
|
|
22
26
|
for (const elem of elems.MediaContainer.Directory) {
|
|
23
|
-
for (const cls of [MovieSection, ShowSection]) {
|
|
27
|
+
for (const cls of [MovieSection, ShowSection, MusicSection]) {
|
|
24
28
|
if (cls.TYPE === elem.type) {
|
|
25
29
|
// eslint-disable-next-line new-cap
|
|
26
30
|
const instance = new cls(this.server, elem, key);
|
|
@@ -281,7 +285,7 @@ export class LibrarySection extends PlexObject {
|
|
|
281
285
|
sortStr = `?sort=${sort}`;
|
|
282
286
|
}
|
|
283
287
|
const key = `/library/sections/${this.key}/all${sortStr}`;
|
|
284
|
-
const items = await fetchItems(this.server, key, undefined, this.
|
|
288
|
+
const items = await fetchItems(this.server, key, undefined, this.SECTION_TYPE, this);
|
|
285
289
|
return items;
|
|
286
290
|
}
|
|
287
291
|
async agents() {
|
|
@@ -294,7 +298,7 @@ export class LibrarySection extends PlexObject {
|
|
|
294
298
|
async get(title) {
|
|
295
299
|
const key = `/library/sections/${this.key}/all?includeGuids=1&title=${title}`;
|
|
296
300
|
const data = await fetchItem(this.server, key, { title__iexact: title });
|
|
297
|
-
return new this.
|
|
301
|
+
return new this.SECTION_TYPE(this.server, data, key, this);
|
|
298
302
|
}
|
|
299
303
|
/**
|
|
300
304
|
* Returns the media item with the specified external IMDB, TMDB, or TVDB ID.
|
|
@@ -355,7 +359,7 @@ export class LibrarySection extends PlexObject {
|
|
|
355
359
|
* TLDR: This is untested but seems to work. Use library section search when you can.
|
|
356
360
|
* @param args Search using a number of different attributes
|
|
357
361
|
*/
|
|
358
|
-
async search(args = {}, Cls
|
|
362
|
+
async search(args = {}, Cls) {
|
|
359
363
|
const params = new URLSearchParams();
|
|
360
364
|
for (const [key, value] of Object.entries(args)) {
|
|
361
365
|
let strValue;
|
|
@@ -374,7 +378,8 @@ export class LibrarySection extends PlexObject {
|
|
|
374
378
|
params.append('type', searchType(args.libtype).toString());
|
|
375
379
|
}
|
|
376
380
|
const key = `/library/sections/${this.key}/all?${params.toString()}`;
|
|
377
|
-
const
|
|
381
|
+
const ClsToUse = Cls ?? this.SECTION_TYPE;
|
|
382
|
+
const data = await fetchItems(this.server, key, undefined, ClsToUse, this);
|
|
378
383
|
return data;
|
|
379
384
|
}
|
|
380
385
|
/**
|
|
@@ -467,7 +472,7 @@ export class LibrarySection extends PlexObject {
|
|
|
467
472
|
async collections(args = {}) {
|
|
468
473
|
const collections = await this.search({ ...args, libtype: 'collection' }, Collections);
|
|
469
474
|
collections.forEach(collection => {
|
|
470
|
-
collection.VIDEO_TYPE = this.
|
|
475
|
+
collection.VIDEO_TYPE = this.SECTION_TYPE;
|
|
471
476
|
});
|
|
472
477
|
return collections;
|
|
473
478
|
}
|
|
@@ -573,7 +578,7 @@ export class MovieSection extends LibrarySection {
|
|
|
573
578
|
super(...arguments);
|
|
574
579
|
this.METADATA_TYPE = 'movie';
|
|
575
580
|
this.CONTENT_TYPE = 'video';
|
|
576
|
-
this.
|
|
581
|
+
this.SECTION_TYPE = Movie;
|
|
577
582
|
}
|
|
578
583
|
static { this.TYPE = 'movie'; }
|
|
579
584
|
static { this.ALLOWED_FILTERS = [
|
|
@@ -615,7 +620,7 @@ export class ShowSection extends LibrarySection {
|
|
|
615
620
|
super(...arguments);
|
|
616
621
|
this.METADATA_TYPE = 'episode';
|
|
617
622
|
this.CONTENT_TYPE = 'video';
|
|
618
|
-
this.
|
|
623
|
+
this.SECTION_TYPE = Show;
|
|
619
624
|
}
|
|
620
625
|
static { this.TYPE = 'show'; }
|
|
621
626
|
static { this.ALLOWED_FILTERS = [
|
|
@@ -670,6 +675,66 @@ export class ShowSection extends LibrarySection {
|
|
|
670
675
|
return this.search({ libtype, maxresults, sort: 'episode.addedAt:desc', ...args });
|
|
671
676
|
}
|
|
672
677
|
}
|
|
678
|
+
export class MusicSection extends LibrarySection {
|
|
679
|
+
constructor() {
|
|
680
|
+
super(...arguments);
|
|
681
|
+
this.METADATA_TYPE = 'track';
|
|
682
|
+
this.CONTENT_TYPE = 'audio';
|
|
683
|
+
this.SECTION_TYPE = Track;
|
|
684
|
+
}
|
|
685
|
+
static { this.TYPE = 'artist'; }
|
|
686
|
+
static { this.TAG = 'Directory'; }
|
|
687
|
+
/** Returns a list of Album objects in this section. */
|
|
688
|
+
async albums() {
|
|
689
|
+
const key = `/library/sections/${this.key}/albums`;
|
|
690
|
+
return fetchItems(this.server, key, undefined, Album, this);
|
|
691
|
+
}
|
|
692
|
+
/**
|
|
693
|
+
* Returns the music stations Hub for this section, if available.
|
|
694
|
+
* TODO: Investigate how to return actual station items (Playlists?) from the Hub.
|
|
695
|
+
*/
|
|
696
|
+
async stations() {
|
|
697
|
+
const hubs = await this.hubs();
|
|
698
|
+
return hubs.find(hub => hub.hubIdentifier === 'hub.music.stations');
|
|
699
|
+
}
|
|
700
|
+
/** Search for an artist. */
|
|
701
|
+
async searchArtists(args = {}) {
|
|
702
|
+
return this.search({ ...args, libtype: 'artist' }, Artist);
|
|
703
|
+
}
|
|
704
|
+
/** Search for an album. */
|
|
705
|
+
async searchAlbums(args = {}) {
|
|
706
|
+
return this.search({ ...args, libtype: 'album' }, Album);
|
|
707
|
+
}
|
|
708
|
+
/** Search for a track. */
|
|
709
|
+
async searchTracks(args = {}) {
|
|
710
|
+
return this.search({ ...args, libtype: 'track' }, Track);
|
|
711
|
+
}
|
|
712
|
+
/** Returns a list of recently added artists from this library section. */
|
|
713
|
+
async recentlyAddedArtists(maxresults = 50) {
|
|
714
|
+
return this.search({ maxresults, sort: 'addedAt:desc', libtype: 'artist' }, Artist);
|
|
715
|
+
}
|
|
716
|
+
/** Returns a list of recently added albums from this library section. */
|
|
717
|
+
async recentlyAddedAlbums(maxresults = 50) {
|
|
718
|
+
return this.search({ maxresults, sort: 'addedAt:desc', libtype: 'album' }, Album);
|
|
719
|
+
}
|
|
720
|
+
/** Returns a list of recently added tracks from this library section. */
|
|
721
|
+
async recentlyAddedTracks(maxresults = 50) {
|
|
722
|
+
return this.search({ maxresults, sort: 'addedAt:desc', libtype: 'track' }, Track);
|
|
723
|
+
}
|
|
724
|
+
/**
|
|
725
|
+
* Returns a list of tracks from this library section that are part of a sonic adventure.
|
|
726
|
+
* IDs should be of a track; other IDs will return an empty list or an error.
|
|
727
|
+
* @param start The Track or ID of the first track in the sonic adventure.
|
|
728
|
+
* @param end The Track or ID of the last track in the sonic adventure.
|
|
729
|
+
* @returns A list of tracks that are part of a sonic adventure.
|
|
730
|
+
*/
|
|
731
|
+
async sonicAdventure(start, end) {
|
|
732
|
+
const startID = typeof start === 'number' ? start : start.ratingKey;
|
|
733
|
+
const endID = typeof end === 'number' ? end : end.ratingKey;
|
|
734
|
+
const key = `/library/sections/${this.key}/computePath?startID=${startID}&endID=${endID}`;
|
|
735
|
+
return fetchItems(this.server, key, undefined, Track, this);
|
|
736
|
+
}
|
|
737
|
+
}
|
|
673
738
|
/** Represents a single Hub (or category) in the PlexServer search */
|
|
674
739
|
export class Hub extends PlexObject {
|
|
675
740
|
static { this.TAG = 'Hub'; }
|
package/dist/src/media.d.ts
CHANGED
|
@@ -231,6 +231,26 @@ export declare class Collection extends MediaTag {
|
|
|
231
231
|
static TAG: "Collection";
|
|
232
232
|
FILTER: "collection";
|
|
233
233
|
}
|
|
234
|
+
/** Represents a single Label media tag. */
|
|
235
|
+
export declare class Label extends MediaTag {
|
|
236
|
+
static TAG: "Label";
|
|
237
|
+
FILTER: "label";
|
|
238
|
+
}
|
|
239
|
+
/** Represents a single Style media tag. */
|
|
240
|
+
export declare class Style extends MediaTag {
|
|
241
|
+
static TAG: "Style";
|
|
242
|
+
FILTER: "style";
|
|
243
|
+
}
|
|
244
|
+
/** Represents a single Format media tag. */
|
|
245
|
+
export declare class Format extends MediaTag {
|
|
246
|
+
static TAG: "Format";
|
|
247
|
+
FILTER: "format";
|
|
248
|
+
}
|
|
249
|
+
/** Represents a single Subformat media tag. */
|
|
250
|
+
export declare class Subformat extends MediaTag {
|
|
251
|
+
static TAG: "Subformat";
|
|
252
|
+
FILTER: "subformat";
|
|
253
|
+
}
|
|
234
254
|
export declare class Optimized extends PlexObject {
|
|
235
255
|
static TAG: string;
|
|
236
256
|
id: string;
|
|
@@ -380,4 +400,29 @@ export declare class AudioStream extends MediaPartStream {
|
|
|
380
400
|
setSelected(): Promise<void>;
|
|
381
401
|
protected _loadData(data: any): void;
|
|
382
402
|
}
|
|
403
|
+
/** Represents a single Image media tag. */
|
|
404
|
+
export declare class Image extends PlexObject {
|
|
405
|
+
static TAG: "Image";
|
|
406
|
+
/** The alt text for the image. */
|
|
407
|
+
alt?: string;
|
|
408
|
+
/** The type of image (e.g. coverPoster, background, snapshot). */
|
|
409
|
+
type?: string;
|
|
410
|
+
/** The API URL (/library/metadata/<ratingKey>/thumb/<thumbid>). */
|
|
411
|
+
url?: string;
|
|
412
|
+
protected _loadData(data: any): void;
|
|
413
|
+
}
|
|
414
|
+
/** Represents a single Field. */
|
|
415
|
+
export declare class Field extends PlexObject {
|
|
416
|
+
static TAG: "Field";
|
|
417
|
+
/** True if the field is locked. */
|
|
418
|
+
locked: boolean;
|
|
419
|
+
/** The name of the field. */
|
|
420
|
+
name: string;
|
|
421
|
+
protected _loadData(data: any): void;
|
|
422
|
+
}
|
|
423
|
+
/** Represents a single Mood media tag. */
|
|
424
|
+
export declare class Mood extends MediaTag {
|
|
425
|
+
static TAG: "Mood";
|
|
426
|
+
FILTER: "mood";
|
|
427
|
+
}
|
|
383
428
|
export {};
|
package/dist/src/media.js
CHANGED
|
@@ -256,6 +256,38 @@ export class Collection extends MediaTag {
|
|
|
256
256
|
}
|
|
257
257
|
static { this.TAG = 'Collection'; }
|
|
258
258
|
}
|
|
259
|
+
/** Represents a single Label media tag. */
|
|
260
|
+
export class Label extends MediaTag {
|
|
261
|
+
constructor() {
|
|
262
|
+
super(...arguments);
|
|
263
|
+
this.FILTER = 'label';
|
|
264
|
+
}
|
|
265
|
+
static { this.TAG = 'Label'; }
|
|
266
|
+
}
|
|
267
|
+
/** Represents a single Style media tag. */
|
|
268
|
+
export class Style extends MediaTag {
|
|
269
|
+
constructor() {
|
|
270
|
+
super(...arguments);
|
|
271
|
+
this.FILTER = 'style';
|
|
272
|
+
}
|
|
273
|
+
static { this.TAG = 'Style'; }
|
|
274
|
+
}
|
|
275
|
+
/** Represents a single Format media tag. */
|
|
276
|
+
export class Format extends MediaTag {
|
|
277
|
+
constructor() {
|
|
278
|
+
super(...arguments);
|
|
279
|
+
this.FILTER = 'format';
|
|
280
|
+
}
|
|
281
|
+
static { this.TAG = 'Format'; }
|
|
282
|
+
}
|
|
283
|
+
/** Represents a single Subformat media tag. */
|
|
284
|
+
export class Subformat extends MediaTag {
|
|
285
|
+
constructor() {
|
|
286
|
+
super(...arguments);
|
|
287
|
+
this.FILTER = 'subformat';
|
|
288
|
+
}
|
|
289
|
+
static { this.TAG = 'Subformat'; }
|
|
290
|
+
}
|
|
259
291
|
export class Optimized extends PlexObject {
|
|
260
292
|
static { this.TAG = 'Item'; }
|
|
261
293
|
// TODO: Implement items()
|
|
@@ -402,3 +434,30 @@ export class AudioStream extends MediaPartStream {
|
|
|
402
434
|
this.startRamp = data.startRamp;
|
|
403
435
|
}
|
|
404
436
|
}
|
|
437
|
+
/** Represents a single Image media tag. */
|
|
438
|
+
export class Image extends PlexObject {
|
|
439
|
+
static { this.TAG = 'Image'; }
|
|
440
|
+
_loadData(data) {
|
|
441
|
+
this.alt = data.alt;
|
|
442
|
+
this.type = data.type;
|
|
443
|
+
// Assuming server.url is needed to make this a complete URL
|
|
444
|
+
this.url = data.url ? this.server.url(data.url, true)?.toString() : undefined;
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
/** Represents a single Field. */
|
|
448
|
+
export class Field extends PlexObject {
|
|
449
|
+
static { this.TAG = 'Field'; }
|
|
450
|
+
_loadData(data) {
|
|
451
|
+
// Convert potential string '1' or '0' to boolean
|
|
452
|
+
this.locked = data.locked === '1' || data.locked === true;
|
|
453
|
+
this.name = data.name;
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
/** Represents a single Mood media tag. */
|
|
457
|
+
export class Mood extends MediaTag {
|
|
458
|
+
constructor() {
|
|
459
|
+
super(...arguments);
|
|
460
|
+
this.FILTER = 'mood';
|
|
461
|
+
}
|
|
462
|
+
static { this.TAG = 'Mood'; }
|
|
463
|
+
}
|
package/dist/src/myplex.js
CHANGED
|
@@ -110,12 +110,14 @@ export class MyPlexAccount {
|
|
|
110
110
|
if (this.token) {
|
|
111
111
|
Object.defineProperty(this, 'token', {
|
|
112
112
|
enumerable: false,
|
|
113
|
+
configurable: true,
|
|
113
114
|
value: this.token,
|
|
114
115
|
});
|
|
115
116
|
}
|
|
116
117
|
if (this.password) {
|
|
117
118
|
Object.defineProperty(this, 'password', {
|
|
118
119
|
enumerable: false,
|
|
120
|
+
configurable: true,
|
|
119
121
|
value: this.password,
|
|
120
122
|
});
|
|
121
123
|
}
|
|
@@ -249,6 +251,7 @@ export class MyPlexAccount {
|
|
|
249
251
|
// Attempt to prevent token from being logged accidentally
|
|
250
252
|
Object.defineProperty(this, 'token', {
|
|
251
253
|
enumerable: false,
|
|
254
|
+
configurable: true,
|
|
252
255
|
value: user.authToken,
|
|
253
256
|
});
|
|
254
257
|
this.authenticationToken = this.token;
|
|
@@ -406,6 +409,7 @@ export class MyPlexDevice extends PlexObject {
|
|
|
406
409
|
// Attempt to prevent token from being logged accidentally
|
|
407
410
|
Object.defineProperty(this, 'token', {
|
|
408
411
|
enumerable: false,
|
|
412
|
+
configurable: true,
|
|
409
413
|
value: data.$.token,
|
|
410
414
|
});
|
|
411
415
|
this.screenResolution = data.$.screenResolution;
|
package/dist/src/playlist.d.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { Playable } from './base/playable.js';
|
|
2
|
-
import type { Section } from './library.js';
|
|
2
|
+
import type { Section, SectionType } from './library.js';
|
|
3
3
|
import type { PlaylistResponse } from './playlist.types.js';
|
|
4
4
|
import type { PlexServer } from './server.js';
|
|
5
|
-
import { Episode, Movie
|
|
5
|
+
import { Episode, Movie } from './video.js';
|
|
6
6
|
interface CreateRegularPlaylistOptions {
|
|
7
7
|
/** True to create a smart playlist */
|
|
8
8
|
smart?: false;
|
|
9
9
|
/** Regular playlists only */
|
|
10
|
-
items?:
|
|
10
|
+
items?: SectionType[];
|
|
11
11
|
}
|
|
12
12
|
interface CreateSmartPlaylistOptions {
|
|
13
13
|
/** True to create a smart playlist */
|
package/dist/src/video.d.ts
CHANGED
|
@@ -3,7 +3,6 @@ import { Playable } from './base/playable.js';
|
|
|
3
3
|
import type { ExtrasData, FullShowData, MovieData, ShowData } from './library.types.js';
|
|
4
4
|
import { Chapter, Collection, Country, Director, Genre, Guid, Marker, Media, Poster, Producer, Rating, Role, Similar, Writer } from './media.js';
|
|
5
5
|
import type { ChapterSource, EpisodeMetadata, FullMovieResponse } from './video.types.js';
|
|
6
|
-
export type VideoType = Movie | Show;
|
|
7
6
|
declare abstract class Video extends Playable {
|
|
8
7
|
/** Datetime this item was added to the library. */
|
|
9
8
|
addedAt: Date;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ctrl/plex",
|
|
3
|
-
"version": "3.
|
|
4
|
-
"description": "plex api client in typescript",
|
|
3
|
+
"version": "3.8.0",
|
|
4
|
+
"description": "plex api client in typescript using ofetch",
|
|
5
5
|
"author": "Scott Cooper <scttcper@gmail.com>",
|
|
6
6
|
"publishConfig": {
|
|
7
7
|
"access": "public"
|