@ctrl/plex 1.5.3 → 2.0.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.
Files changed (68) hide show
  1. package/README.md +3 -2
  2. package/dist/src/alert.d.ts +12 -0
  3. package/dist/src/alert.js +29 -0
  4. package/dist/src/alert.types.d.ts +59 -0
  5. package/dist/src/alert.types.js +1 -0
  6. package/dist/{base → src/base}/partialPlexObject.d.ts +18 -12
  7. package/dist/{base → src/base}/partialPlexObject.js +29 -23
  8. package/dist/{base → src/base}/playable.d.ts +2 -2
  9. package/dist/src/base/playable.js +8 -0
  10. package/dist/{base → src/base}/plexObject.d.ts +8 -1
  11. package/dist/{base → src/base}/plexObject.js +21 -18
  12. package/dist/{baseFunctionality.d.ts → src/baseFunctionality.d.ts} +17 -1
  13. package/dist/{baseFunctionality.js → src/baseFunctionality.js} +7 -15
  14. package/dist/{client.d.ts → src/client.d.ts} +2 -2
  15. package/dist/{client.js → src/client.js} +12 -20
  16. package/dist/src/client.types.js +1 -0
  17. package/dist/src/config.js +35 -0
  18. package/dist/src/exceptions.d.ts +20 -0
  19. package/dist/src/exceptions.js +40 -0
  20. package/dist/src/index.d.ts +12 -0
  21. package/dist/src/index.js +11 -0
  22. package/dist/{library.d.ts → src/library.d.ts} +207 -21
  23. package/dist/{library.js → src/library.js} +348 -132
  24. package/dist/{library.types.d.ts → src/library.types.d.ts} +59 -1
  25. package/dist/src/library.types.js +1 -0
  26. package/dist/{media.d.ts → src/media.d.ts} +16 -4
  27. package/dist/{media.js → src/media.js} +42 -49
  28. package/dist/src/media.types.d.ts +7 -0
  29. package/dist/src/media.types.js +1 -0
  30. package/dist/{myplex.d.ts → src/myplex.d.ts} +16 -6
  31. package/dist/{myplex.js → src/myplex.js} +71 -57
  32. package/dist/src/myplex.types.js +10 -0
  33. package/dist/src/playlist.d.ts +75 -0
  34. package/dist/src/playlist.js +142 -0
  35. package/dist/src/playlist.types.d.ts +17 -0
  36. package/dist/src/playlist.types.js +1 -0
  37. package/dist/{search.d.ts → src/search.d.ts} +4 -3
  38. package/dist/{search.js → src/search.js} +13 -19
  39. package/dist/src/search.types.js +1 -0
  40. package/dist/{server.d.ts → src/server.d.ts} +22 -10
  41. package/dist/{server.js → src/server.js} +65 -50
  42. package/dist/src/server.types.js +1 -0
  43. package/dist/src/settings.d.ts +79 -0
  44. package/dist/src/settings.js +160 -0
  45. package/dist/{util.d.ts → src/util.d.ts} +2 -1
  46. package/dist/{util.js → src/util.js} +8 -12
  47. package/dist/{video.d.ts → src/video.d.ts} +38 -60
  48. package/dist/{video.js → src/video.js} +109 -92
  49. package/dist/{video.types.d.ts → src/video.types.d.ts} +1 -1
  50. package/dist/src/video.types.js +6 -0
  51. package/package.json +46 -44
  52. package/dist/base/playable.js +0 -12
  53. package/dist/client.types.js +0 -2
  54. package/dist/config.js +0 -41
  55. package/dist/index.d.ts +0 -8
  56. package/dist/index.js +0 -23
  57. package/dist/library.types.js +0 -2
  58. package/dist/myplex.types.js +0 -13
  59. package/dist/playlist.d.ts +0 -7
  60. package/dist/playlist.js +0 -19
  61. package/dist/search.types.js +0 -2
  62. package/dist/server.types.js +0 -2
  63. package/dist/video.types.js +0 -9
  64. /package/dist/{client.types.d.ts → src/client.types.d.ts} +0 -0
  65. /package/dist/{config.d.ts → src/config.d.ts} +0 -0
  66. /package/dist/{myplex.types.d.ts → src/myplex.types.d.ts} +0 -0
  67. /package/dist/{search.types.d.ts → src/search.types.d.ts} +0 -0
  68. /package/dist/{server.types.d.ts → src/server.types.d.ts} +0 -0
@@ -1,4 +1,4 @@
1
- import { ChapterSource, MediaTagData } from './video.types';
1
+ import { ChapterSource, MarkerData, MediaTagData } from './video.types.js';
2
2
  export interface LibraryRootResponse {
3
3
  size: number;
4
4
  allowSync: boolean;
@@ -107,6 +107,9 @@ export interface MovieData {
107
107
  Role?: MediaTag[];
108
108
  Similar?: MediaTagData[];
109
109
  Producer?: MediaTagData[];
110
+ Extras?: ExtrasData[];
111
+ Guid?: Guid[];
112
+ Marker?: MarkerData[];
110
113
  }
111
114
  export interface MediaTag {
112
115
  tag: string;
@@ -118,6 +121,9 @@ export interface Media {
118
121
  videoProfile: string;
119
122
  Part: Part[];
120
123
  }
124
+ export interface Guid {
125
+ id: string;
126
+ }
121
127
  export interface Part {
122
128
  id: number;
123
129
  key: string;
@@ -189,3 +195,55 @@ export interface CollectionData {
189
195
  maxYear: string;
190
196
  minYear: string;
191
197
  }
198
+ export interface ExtrasData {
199
+ ratingKey: string;
200
+ key: string;
201
+ guid: string;
202
+ type: string;
203
+ title: string;
204
+ titleSort: string;
205
+ summary: string;
206
+ index: number;
207
+ thumb: string;
208
+ subtype: string;
209
+ duration: number;
210
+ addedAt: number;
211
+ extraType: number;
212
+ Media: ExtrasMedia[];
213
+ }
214
+ export interface ExtrasMedia {
215
+ id: number;
216
+ duration: number;
217
+ bitrate: number;
218
+ width: number;
219
+ height: number;
220
+ aspectRatio: number;
221
+ audioCodec: string;
222
+ videoCodec: string;
223
+ videoResolution: string;
224
+ container: string;
225
+ optimizedForStreaming: number;
226
+ protocol: string;
227
+ premium: boolean;
228
+ Part: Array<{
229
+ id: number;
230
+ duration: number;
231
+ container: string;
232
+ key: string;
233
+ Stream: ExtrasStream[];
234
+ }>;
235
+ }
236
+ interface ExtrasStream {
237
+ id: number;
238
+ streamType: number;
239
+ codec: string;
240
+ index: number;
241
+ bitrate?: number;
242
+ height?: number;
243
+ width?: number;
244
+ displayTitle: string;
245
+ extendedDisplayTitle: string;
246
+ selected?: boolean;
247
+ channels?: number;
248
+ }
249
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -1,5 +1,5 @@
1
- import { PlexObject } from './base/plexObject';
2
- import { ChapterData, MarkerData, MediaData, MediaPartData, MediaPartStreamData } from './video.types';
1
+ import { PlexObject } from './base/plexObject.js';
2
+ import { ChapterData, MarkerData, MediaData, MediaPartData, MediaPartStreamData } from './video.types.js';
3
3
  /**
4
4
  * Base class for media tags used for filtering and searching your library
5
5
  * items or navigating the metadata of media items in your library. Tags are
@@ -67,7 +67,6 @@ export declare class MediaPart extends PlexObject {
67
67
  file: string;
68
68
  id: number;
69
69
  indexes: string;
70
- key: string;
71
70
  size: number;
72
71
  optimizedForStreaming: boolean;
73
72
  syncItemId: string;
@@ -134,7 +133,7 @@ export declare class Producer extends MediaTag {
134
133
  export declare class Marker extends MediaTag {
135
134
  static TAG: "Marker";
136
135
  FILTER: "marker";
137
- type: 'intro';
136
+ type: 'intro' | 'credits';
138
137
  startTimeOffset: number;
139
138
  endTimeOffset: number;
140
139
  protected _loadData(data: MarkerData): void;
@@ -167,4 +166,17 @@ export declare class Optimized extends PlexObject {
167
166
  targetTagID: any;
168
167
  protected _loadData(data: any): void;
169
168
  }
169
+ /**
170
+ * Base class for guid tags used only for Guids, as they contain only a string identifier
171
+ */
172
+ declare class GuidTag extends PlexObject {
173
+ /**
174
+ * The guid for external metadata sources (e.g. IMDB, TMDB, TVDB). ex - imdb://tt3222784
175
+ */
176
+ id: string;
177
+ protected _loadData(data: any): void;
178
+ }
179
+ export declare class Guid extends GuidTag {
180
+ static TAG: "Guid";
181
+ }
170
182
  export {};
@@ -1,13 +1,10 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Optimized = exports.Collection = exports.Chapter = exports.Marker = exports.Producer = exports.Similar = exports.Director = exports.Writer = exports.Country = exports.Genre = exports.Role = exports.MediaPartStream = exports.MediaPart = exports.Media = void 0;
4
- const plexObject_1 = require("./base/plexObject");
1
+ import { PlexObject } from './base/plexObject.js';
5
2
  /**
6
3
  * Base class for media tags used for filtering and searching your library
7
4
  * items or navigating the metadata of media items in your library. Tags are
8
5
  * the construct used for things such as Country, Director, Genre, etc.
9
6
  */
10
- class MediaTag extends plexObject_1.PlexObject {
7
+ class MediaTag extends PlexObject {
11
8
  // async items(): Promise<any[]> {
12
9
  // if (!this.key) {
13
10
  // throw new Error(`Key is not defined for this tag: ${this.tag}`);
@@ -21,7 +18,8 @@ class MediaTag extends plexObject_1.PlexObject {
21
18
  this.tag = data.tag;
22
19
  }
23
20
  }
24
- class Media extends plexObject_1.PlexObject {
21
+ export class Media extends PlexObject {
22
+ static { this.TAG = 'Media'; }
25
23
  _loadData(data) {
26
24
  this.aspectRatio = data.aspectRatio;
27
25
  this.audioChannels = data.audioChannels;
@@ -40,11 +38,9 @@ class Media extends plexObject_1.PlexObject {
40
38
  this.parts = data.Part.map(part => new MediaPart(this.server, part, undefined, this));
41
39
  }
42
40
  }
43
- exports.Media = Media;
44
- Media.TAG = 'Media';
45
- class MediaPart extends plexObject_1.PlexObject {
41
+ export class MediaPart extends PlexObject {
42
+ static { this.TAG = 'Part'; }
46
43
  _loadData(data) {
47
- var _a, _b;
48
44
  this.container = data.container;
49
45
  this.duration = data.duration;
50
46
  this.file = data.file;
@@ -55,12 +51,11 @@ class MediaPart extends plexObject_1.PlexObject {
55
51
  this.videoProfile = data.videoProfile;
56
52
  this.exists = data.exists;
57
53
  this.streams =
58
- (_b = (_a = data.Stream) === null || _a === void 0 ? void 0 : _a.map(stream => new MediaPartStream(this.server, stream, undefined, this))) !== null && _b !== void 0 ? _b : [];
54
+ data.Stream?.map(stream => new MediaPartStream(this.server, stream, undefined, this)) ?? [];
59
55
  }
60
56
  }
61
- exports.MediaPart = MediaPart;
62
- MediaPart.TAG = 'Part';
63
- class MediaPartStream extends plexObject_1.PlexObject {
57
+ export class MediaPartStream extends PlexObject {
58
+ static { this.TAG = 'Stream'; }
64
59
  _loadData(data) {
65
60
  this.id = data.id;
66
61
  this.codec = data.codec;
@@ -71,120 +66,109 @@ class MediaPartStream extends plexObject_1.PlexObject {
71
66
  this.streamType = data.streamType;
72
67
  }
73
68
  }
74
- exports.MediaPartStream = MediaPartStream;
75
- MediaPartStream.TAG = 'Stream';
76
69
  /**
77
70
  * Represents a single Role (actor/actress) media tag.
78
71
  */
79
- class Role extends MediaTag {
72
+ export class Role extends MediaTag {
80
73
  constructor() {
81
74
  super(...arguments);
82
75
  this.FILTER = 'role';
83
76
  }
77
+ static { this.TAG = 'Role'; }
84
78
  }
85
- exports.Role = Role;
86
- Role.TAG = 'Role';
87
79
  /**
88
80
  * Represents a single Genre media tag.
89
81
  */
90
- class Genre extends MediaTag {
82
+ export class Genre extends MediaTag {
91
83
  constructor() {
92
84
  super(...arguments);
93
85
  this.FILTER = 'genre';
94
86
  }
87
+ static { this.TAG = 'Genre'; }
95
88
  }
96
- exports.Genre = Genre;
97
- Genre.TAG = 'Genre';
98
89
  /**
99
90
  * Represents a single Country media tag.
100
91
  */
101
- class Country extends MediaTag {
92
+ export class Country extends MediaTag {
102
93
  constructor() {
103
94
  super(...arguments);
104
95
  this.FILTER = 'country';
105
96
  }
97
+ static { this.TAG = 'Country'; }
106
98
  }
107
- exports.Country = Country;
108
- Country.TAG = 'Country';
109
99
  /**
110
100
  * Represents a single Writer media tag.
111
101
  */
112
- class Writer extends MediaTag {
102
+ export class Writer extends MediaTag {
113
103
  constructor() {
114
104
  super(...arguments);
115
105
  this.FILTER = 'writer';
116
106
  }
107
+ static { this.TAG = 'Writer'; }
117
108
  }
118
- exports.Writer = Writer;
119
- Writer.TAG = 'Writer';
120
109
  /**
121
110
  * Represents a single Director media tag.
122
111
  */
123
- class Director extends MediaTag {
112
+ export class Director extends MediaTag {
124
113
  constructor() {
125
114
  super(...arguments);
126
115
  this.FILTER = 'director';
127
116
  }
117
+ static { this.TAG = 'Director'; }
128
118
  }
129
- exports.Director = Director;
130
- Director.TAG = 'Director';
131
- class Similar extends MediaTag {
119
+ export class Similar extends MediaTag {
132
120
  constructor() {
133
121
  super(...arguments);
134
122
  this.FILTER = 'similar';
135
123
  }
124
+ static { this.TAG = 'Similar'; }
136
125
  }
137
- exports.Similar = Similar;
138
- Similar.TAG = 'Similar';
139
- class Producer extends MediaTag {
126
+ export class Producer extends MediaTag {
140
127
  constructor() {
141
128
  super(...arguments);
142
129
  this.FILTER = 'producer';
143
130
  }
131
+ static { this.TAG = 'Producer'; }
144
132
  }
145
- exports.Producer = Producer;
146
- Producer.TAG = 'Producer';
147
- class Marker extends MediaTag {
133
+ export class Marker extends MediaTag {
148
134
  constructor() {
149
135
  super(...arguments);
150
136
  this.FILTER = 'marker';
151
137
  }
138
+ static { this.TAG = 'Marker'; }
152
139
  _loadData(data) {
153
140
  this.type = data.type;
154
141
  this.startTimeOffset = data.startTimeOffset;
155
142
  this.endTimeOffset = data.endTimeOffset;
156
143
  }
157
144
  }
158
- exports.Marker = Marker;
159
- Marker.TAG = 'Marker';
160
145
  /**
161
146
  * Represents a single Chapter media tag.
162
147
  */
163
- class Chapter extends MediaTag {
148
+ export class Chapter extends MediaTag {
164
149
  constructor() {
165
150
  super(...arguments);
166
151
  this.FILTER = 'chapter';
167
152
  }
153
+ static { this.TAG = 'Chapter'; }
168
154
  _loadData(data) {
169
155
  this.startTimeOffset = data.startTimeOffset;
170
156
  this.endTimeOffset = data.endTimeOffset;
171
157
  this.thumb = data.thumb;
172
158
  }
173
159
  }
174
- exports.Chapter = Chapter;
175
- Chapter.TAG = 'Chapter';
176
160
  /**
177
161
  * Represents a single Collection media tag.
178
162
  */
179
- class Collection extends MediaTag {
163
+ export class Collection extends MediaTag {
180
164
  constructor() {
181
165
  super(...arguments);
182
166
  this.FILTER = 'collection';
183
167
  }
168
+ static { this.TAG = 'Collection'; }
184
169
  }
185
- exports.Collection = Collection;
186
- Collection.TAG = 'Collection';
187
- class Optimized extends plexObject_1.PlexObject {
170
+ export class Optimized extends PlexObject {
171
+ static { this.TAG = 'Item'; }
188
172
  _loadData(data) {
189
173
  this.id = data.id;
190
174
  this.composite = data.composite;
@@ -194,5 +178,14 @@ class Optimized extends plexObject_1.PlexObject {
194
178
  this.targetTagID = data.targetTagID;
195
179
  }
196
180
  }
197
- exports.Optimized = Optimized;
198
- Optimized.TAG = 'Item';
181
+ /**
182
+ * Base class for guid tags used only for Guids, as they contain only a string identifier
183
+ */
184
+ class GuidTag extends PlexObject {
185
+ _loadData(data) {
186
+ this.id = data.id;
187
+ }
188
+ }
189
+ export class Guid extends GuidTag {
190
+ static { this.TAG = 'Guid'; }
191
+ }
@@ -0,0 +1,7 @@
1
+ export interface SearchResultData {
2
+ guid: string;
3
+ name: string;
4
+ score: number;
5
+ year: number;
6
+ lifespanEnded: boolean;
7
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -1,6 +1,6 @@
1
- import { ResourcesResponse, Connection, Device } from './myplex.types';
2
- import { PlexServer } from './server';
3
- import { PlexObject } from './base/plexObject';
1
+ import { PlexObject } from './base/plexObject.js';
2
+ import { Connection, Device, ResourcesResponse } from './myplex.types.js';
3
+ import { PlexServer } from './server.js';
4
4
  /**
5
5
  * MyPlex account and profile information. This object represents the data found Account on
6
6
  * the myplex.tv servers at the url https://plex.tv/users/account. You may create this object
@@ -10,9 +10,9 @@ import { PlexObject } from './base/plexObject';
10
10
  */
11
11
  export declare class MyPlexAccount {
12
12
  private readonly baseUrl;
13
- username?: string | undefined;
13
+ username?: string;
14
14
  private readonly password?;
15
- token?: string | undefined;
15
+ token?: string;
16
16
  private readonly timeout;
17
17
  private readonly server?;
18
18
  static key: string;
@@ -82,7 +82,7 @@ export declare class MyPlexAccount {
82
82
  * @param timeout timeout in seconds on initial connect to myplex
83
83
  * @param server not often available
84
84
  */
85
- constructor(baseUrl?: string | null, username?: string | undefined, password?: string | undefined, token?: string | undefined, timeout?: number, server?: PlexServer | undefined);
85
+ constructor(baseUrl?: string | null, username?: string, password?: string, token?: string, timeout?: number, server?: PlexServer);
86
86
  /**
87
87
  * Returns a new :class:`~server.PlexServer` or :class:`~client.PlexClient` object.
88
88
  * Often times there is more than one address specified for a server or client.
@@ -96,6 +96,11 @@ export declare class MyPlexAccount {
96
96
  */
97
97
  resource(name: string): Promise<MyPlexResource>;
98
98
  resources(): Promise<MyPlexResource[]>;
99
+ /**
100
+ * @param name Name to match against.
101
+ * @param clientId clientIdentifier to match against.
102
+ */
103
+ device(name?: string, clientId?: string): Promise<MyPlexDevice>;
99
104
  /**
100
105
  * Returns a list of all :class:`~plexapi.myplex.MyPlexDevice` objects connected to the server.
101
106
  */
@@ -218,5 +223,10 @@ export declare class MyPlexDevice extends PlexObject {
218
223
  lastSeenAt: Date;
219
224
  /** List of connection URIs for the device. */
220
225
  connections?: string[];
226
+ connect(): Promise<PlexServer>;
227
+ /**
228
+ * Remove this device from your account
229
+ */
230
+ delete(): Promise<void>;
221
231
  protected _loadData(data: Device): void;
222
232
  }
@@ -1,16 +1,10 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.MyPlexDevice = exports.ResourceConnection = exports.MyPlexResource = exports.MyPlexAccount = void 0;
7
- const got_1 = __importDefault(require("got"));
8
- const url_1 = require("url");
9
- const p_any_1 = __importDefault(require("p-any"));
10
- const config_1 = require("./config");
11
- const server_1 = require("./server");
12
- const plexObject_1 = require("./base/plexObject");
13
- const xml2js_1 = require("xml2js");
1
+ import { URL, URLSearchParams } from 'url';
2
+ import got from 'got';
3
+ import pAny from 'p-any';
4
+ import { parseStringPromise } from 'xml2js';
5
+ import { PlexObject } from './base/plexObject.js';
6
+ import { BASE_HEADERS, TIMEOUT } from './config.js';
7
+ import { PlexServer } from './server.js';
14
8
  /**
15
9
  * MyPlex account and profile information. This object represents the data found Account on
16
10
  * the myplex.tv servers at the url https://plex.tv/users/account. You may create this object
@@ -18,7 +12,8 @@ const xml2js_1 = require("xml2js");
18
12
  * method provided at :class:`~plexapi.server.PlexServer.myPlexAccount()` which will create
19
13
  * and return this object.
20
14
  */
21
- class MyPlexAccount {
15
+ export class MyPlexAccount {
16
+ static { this.key = 'https://plex.tv/api/v2/user'; }
22
17
  /**
23
18
  *
24
19
  * @param username Your MyPlex username
@@ -28,7 +23,7 @@ class MyPlexAccount {
28
23
  * @param timeout timeout in seconds on initial connect to myplex
29
24
  * @param server not often available
30
25
  */
31
- constructor(baseUrl = null, username, password, token, timeout = config_1.TIMEOUT, server) {
26
+ constructor(baseUrl = null, username, password, token, timeout = TIMEOUT, server) {
32
27
  this.baseUrl = baseUrl;
33
28
  this.username = username;
34
29
  this.password = password;
@@ -94,6 +89,18 @@ class MyPlexAccount {
94
89
  const data = await this.query(MyPlexResource.key);
95
90
  return data.map(device => new MyPlexResource(this, device, this.baseUrl));
96
91
  }
92
+ /**
93
+ * @param name Name to match against.
94
+ * @param clientId clientIdentifier to match against.
95
+ */
96
+ async device(name = '', clientId) {
97
+ const devices = await this.devices();
98
+ const device = devices.find(device => device.name?.toLowerCase() === name.toLowerCase() || device.clientIdentifier === clientId);
99
+ if (!device) {
100
+ throw new Error('Unable to find device');
101
+ }
102
+ return device;
103
+ }
97
104
  /**
98
105
  * Returns a list of all :class:`~plexapi.myplex.MyPlexDevice` objects connected to the server.
99
106
  */
@@ -117,18 +124,18 @@ class MyPlexAccount {
117
124
  const credentials = Buffer.from(`${username}:${password}`).toString('base64');
118
125
  requestHeaders.Authorization = `Basic ${credentials}`;
119
126
  }
120
- const promise = got_1.default({
127
+ const promise = got({
121
128
  method,
122
- url: new url_1.URL(url),
129
+ url: new URL(url),
123
130
  headers: requestHeaders,
124
- timeout: timeout !== null && timeout !== void 0 ? timeout : config_1.TIMEOUT,
125
- username,
126
- password,
127
- retry: 0,
131
+ timeout: { request: timeout ?? TIMEOUT },
132
+ ...(username ? { username } : {}),
133
+ ...(password ? { password } : {}),
134
+ retry: { limit: 0 },
128
135
  });
129
136
  if (url.includes('xml')) {
130
137
  const res = await promise;
131
- const xml = await xml2js_1.parseStringPromise(res.body);
138
+ const xml = await parseStringPromise(res.body);
132
139
  return xml;
133
140
  }
134
141
  const res = await promise.json();
@@ -141,29 +148,29 @@ class MyPlexAccount {
141
148
  */
142
149
  async claimToken() {
143
150
  const url = 'https://plex.tv/api/claim/token.json';
144
- const response = await this.query(url, 'get', undefined, config_1.TIMEOUT);
151
+ const response = await this.query(url, 'get', undefined, TIMEOUT);
145
152
  return response.token;
146
153
  }
147
154
  /**
148
155
  * @param token pass token from claimToken
149
156
  */
150
157
  async claimServer(token) {
151
- const params = new url_1.URLSearchParams({
158
+ const params = new URLSearchParams({
152
159
  token,
153
- ...config_1.BASE_HEADERS,
160
+ ...BASE_HEADERS,
154
161
  });
155
162
  const url = `${this.baseUrl}/myplex/claim?${params.toString()}`;
156
- return got_1.default({
163
+ return got({
157
164
  method: 'POST',
158
165
  url,
159
- timeout: config_1.TIMEOUT,
166
+ timeout: { request: TIMEOUT },
160
167
  headers: this._headers(),
161
- retry: 0,
168
+ retry: { limit: 0 },
162
169
  });
163
170
  }
164
171
  _headers() {
165
172
  const headers = {
166
- ...config_1.BASE_HEADERS,
173
+ ...BASE_HEADERS,
167
174
  'Content-type': 'application/json',
168
175
  };
169
176
  if (this.token) {
@@ -176,7 +183,6 @@ class MyPlexAccount {
176
183
  return data.user;
177
184
  }
178
185
  _loadData(user) {
179
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
180
186
  // Attempt to prevent token from being logged accidentally
181
187
  Object.defineProperty(this, 'token', {
182
188
  enumerable: false,
@@ -194,21 +200,19 @@ class MyPlexAccount {
194
200
  this.username = user.username;
195
201
  this.title = user.title;
196
202
  this.locale = user.locale;
197
- this.mailingListStatus = (_a = user.mailingListStatus) !== null && _a !== void 0 ? _a : 'inactive';
203
+ this.mailingListStatus = user.mailingListStatus ?? 'inactive';
198
204
  this.mailingListActive = user.mailingListActive;
199
205
  this.queueEmail = user.queueEmail;
200
206
  this.thumb = user.thumb;
201
207
  this.scrobbleTypes = user.scrobbleTypes;
202
208
  this.restricted = user.restricted;
203
- this.subscriptionActive = (_c = (_b = user.subscription) === null || _b === void 0 ? void 0 : _b.active) !== null && _c !== void 0 ? _c : null;
204
- this.subscriptionStatus = (_f = (_e = (_d = user.subscription) === null || _d === void 0 ? void 0 : _d.status) === null || _e === void 0 ? void 0 : _e.toLowerCase()) !== null && _f !== void 0 ? _f : 'inactive';
205
- this.subscriptionPlan = (_h = (_g = user.subscription) === null || _g === void 0 ? void 0 : _g.plan) !== null && _h !== void 0 ? _h : null;
206
- this.subscriptionFeatures = (_k = (_j = user.subscription) === null || _j === void 0 ? void 0 : _j.features) !== null && _k !== void 0 ? _k : [];
209
+ this.subscriptionActive = user.subscription?.active ?? null;
210
+ this.subscriptionStatus = user.subscription?.status?.toLowerCase() ?? 'inactive';
211
+ this.subscriptionPlan = user.subscription?.plan ?? null;
212
+ this.subscriptionFeatures = user.subscription?.features ?? [];
207
213
  this.entitlements = user.entitlements;
208
214
  }
209
215
  }
210
- exports.MyPlexAccount = MyPlexAccount;
211
- MyPlexAccount.key = 'https://plex.tv/api/v2/user';
212
216
  /**
213
217
  * Connects to the specified cls with url and token
214
218
  */
@@ -221,7 +225,8 @@ async function connect(cls, url, token, timeout) {
221
225
  * This object represents resources connected to your Plex server that can provide
222
226
  * content such as Plex Media Servers, iPhone or Android clients, etc.
223
227
  */
224
- class MyPlexResource {
228
+ export class MyPlexResource {
229
+ static { this.key = 'https://plex.tv/api/v2/resources?includeHttps=1&includeRelay=1'; }
225
230
  constructor(account, data, baseUrl = null) {
226
231
  this.account = account;
227
232
  this.baseUrl = baseUrl;
@@ -255,19 +260,18 @@ class MyPlexResource {
255
260
  // TODO: switch between PlexServer and PlexClient
256
261
  // Try connecting to all known resource connections in parellel, but
257
262
  // only return the first server (in order) that provides a response.
258
- const promises = attemptUrls.map(async (url) => connect((...args) => new server_1.PlexServer(...args), url, this.accessToken, timeout));
259
- const result = await p_any_1.default(promises);
263
+ const promises = attemptUrls.map(async (url) => connect((...args) => new PlexServer(...args), url, this.accessToken, timeout));
264
+ const result = await pAny(promises);
260
265
  return result;
261
266
  }
262
267
  /** Remove this device from your account */
263
268
  async delete() {
264
- const key = `https://plex.tv/api/servers/${this.clientIdentifier}?X-Plex-Client-Identifier=${config_1.BASE_HEADERS['X-Plex-Client-Identifier']}&X-Plex-Token=${this.accessToken}`;
265
- await got_1.default.delete(key, { retry: 0 });
269
+ const key = `https://plex.tv/api/servers/${this.clientIdentifier}?X-Plex-Client-Identifier=${BASE_HEADERS['X-Plex-Client-Identifier']}&X-Plex-Token=${this.accessToken}`;
270
+ await got.delete(key, { retry: { limit: 0 } });
266
271
  }
267
272
  _loadData(data) {
268
- var _a, _b, _c;
269
273
  this.name = data.name;
270
- this.accessToken = (_a = data.accessToken) !== null && _a !== void 0 ? _a : '';
274
+ this.accessToken = data.accessToken ?? '';
271
275
  this.owned = data.owned;
272
276
  this.clientIdentifier = data.clientIdentifier;
273
277
  this.createdAt = new Date(data.createdAt);
@@ -282,12 +286,10 @@ class MyPlexResource {
282
286
  this.product = data.product;
283
287
  this.productVersion = data.productVersion;
284
288
  this.connections =
285
- (_c = (_b = data.connections) === null || _b === void 0 ? void 0 : _b.map(connection => new ResourceConnection(connection))) !== null && _c !== void 0 ? _c : [];
289
+ data.connections?.map(connection => new ResourceConnection(connection)) ?? [];
286
290
  }
287
291
  }
288
- exports.MyPlexResource = MyPlexResource;
289
- MyPlexResource.key = 'https://plex.tv/api/v2/resources?includeHttps=1&includeRelay=1';
290
- class ResourceConnection {
292
+ export class ResourceConnection {
291
293
  constructor(data) {
292
294
  this.TAG = 'Connection';
293
295
  this._loadData(data);
@@ -301,16 +303,31 @@ class ResourceConnection {
301
303
  this.httpuri = `http://${data.address}:${data.port}`;
302
304
  }
303
305
  }
304
- exports.ResourceConnection = ResourceConnection;
305
306
  /**
306
307
  * This object represents resources connected to your Plex server that provide
307
308
  * playback ability from your Plex Server, iPhone or Android clients, Plex Web,
308
309
  * this API, etc. The raw xml for the data presented here can be found at:
309
310
  * https://plex.tv/devices.xml
310
311
  */
311
- class MyPlexDevice extends plexObject_1.PlexObject {
312
+ export class MyPlexDevice extends PlexObject {
313
+ static { this.TAG = 'Device'; }
314
+ static { this.key = 'https://plex.tv/devices.xml'; }
315
+ async connect() {
316
+ // TODO: switch between PlexServer and PlexClient
317
+ // Try connecting to all known resource connections in parellel, but
318
+ // only return the first server (in order) that provides a response.
319
+ const promises = (this.connections ?? []).map(async (url) => connect((...args) => new PlexServer(...args), url, this.token));
320
+ const result = await pAny(promises);
321
+ return result;
322
+ }
323
+ /**
324
+ * Remove this device from your account
325
+ */
326
+ async delete() {
327
+ const key = `https://plex.tv/devices/${this.id}.xml`;
328
+ await this.server.query(key, 'delete');
329
+ }
312
330
  _loadData(data) {
313
- var _a;
314
331
  this.name = data.$.name;
315
332
  this.publicAddress = data.$.publicAddress;
316
333
  this.product = data.$.product;
@@ -332,11 +349,8 @@ class MyPlexDevice extends plexObject_1.PlexObject {
332
349
  });
333
350
  this.screenResolution = data.$.screenResolution;
334
351
  this.screenDensity = data.$.screenDensity;
335
- this.createdAt = new Date(data.$.createdAt);
336
- this.lastSeenAt = new Date(data.$.lastSeenAt);
337
- this.connections = (_a = data.Connection) === null || _a === void 0 ? void 0 : _a.map(connection => connection.$.uri);
352
+ this.createdAt = new Date(parseInt(data.$.createdAt, 10));
353
+ this.lastSeenAt = new Date(parseInt(data.$.lastSeenAt, 10));
354
+ this.connections = data.Connection?.map(connection => connection.$.uri);
338
355
  }
339
356
  }
340
- exports.MyPlexDevice = MyPlexDevice;
341
- MyPlexDevice.TAG = 'Device';
342
- MyPlexDevice.key = 'https://plex.tv/devices.xml';
@@ -0,0 +1,10 @@
1
+ export var Status;
2
+ (function (Status) {
3
+ Status["Online"] = "online";
4
+ Status["Offline"] = "offline";
5
+ })(Status || (Status = {}));
6
+ export var Protocol;
7
+ (function (Protocol) {
8
+ Protocol["HTTP"] = "http";
9
+ Protocol["HTTPS"] = "https";
10
+ })(Protocol || (Protocol = {}));