@ctrl/plex 3.10.0 → 3.12.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.
@@ -1,4 +1,4 @@
1
- import { URLSearchParams } from 'url';
1
+ import { URLSearchParams } from 'node:url';
2
2
  import { PartialPlexObject } from './base/partialPlexObject.js';
3
3
  import { PlexObject } from './base/plexObject.js';
4
4
  import { Album, Artist, Track } from './audio.js';
@@ -8,7 +8,8 @@ import { Playlist } from './playlist.js';
8
8
  import { searchType } from './search.js';
9
9
  import { Movie, Show } from './video.js';
10
10
  export class Library {
11
- static { this.key = '/library'; }
11
+ server;
12
+ static key = '/library';
12
13
  constructor(server, data) {
13
14
  this.server = server;
14
15
  this._loadData(data);
@@ -35,9 +36,9 @@ export class Library {
35
36
  }
36
37
  async section(title) {
37
38
  const sections = await this.sections();
38
- const section = sections.find(s => s.title.toLowerCase() === title.toLowerCase());
39
+ const section = sections.find(s => s.title?.toLowerCase() === title.toLowerCase());
39
40
  if (!section) {
40
- const avilableSections = sections.map(s => s.title).join(', ');
41
+ const avilableSections = sections.map(s => s.title || 'Unknown').join(', ');
41
42
  throw new Error(`Invalid library section: ${title}. Available: ${avilableSections}`);
42
43
  }
43
44
  return section;
@@ -205,7 +206,7 @@ export class Library {
205
206
  language,
206
207
  ...extra,
207
208
  });
208
- const url = '/library/sections?' + search.toString();
209
+ const url = `/library/sections?${search.toString()}`;
209
210
  return this.server.query(url, 'post');
210
211
  }
211
212
  /**
@@ -275,9 +276,10 @@ export class Library {
275
276
  * Base class for a single library section.
276
277
  */
277
278
  export class LibrarySection extends PlexObject {
278
- static { this.ALLOWED_FILTERS = []; }
279
- static { this.ALLOWED_SORT = []; }
280
- static { this.BOOLEAN_FILTERS = ['unwatched', 'duplicate']; }
279
+ static ALLOWED_FILTERS = [];
280
+ static ALLOWED_SORT = [];
281
+ static BOOLEAN_FILTERS = ['unwatched', 'duplicate'];
282
+ SECTION_TYPE;
281
283
  async all(sort = '') {
282
284
  let sortStr = '';
283
285
  if (sort) {
@@ -573,14 +575,8 @@ export class LibrarySection extends PlexObject {
573
575
  }
574
576
  }
575
577
  export class MovieSection extends LibrarySection {
576
- constructor() {
577
- super(...arguments);
578
- this.METADATA_TYPE = 'movie';
579
- this.CONTENT_TYPE = 'video';
580
- this.SECTION_TYPE = Movie;
581
- }
582
- static { this.TYPE = 'movie'; }
583
- static { this.ALLOWED_FILTERS = [
578
+ static TYPE = 'movie';
579
+ static ALLOWED_FILTERS = [
584
580
  'unwatched',
585
581
  'duplicate',
586
582
  'year',
@@ -602,8 +598,8 @@ export class MovieSection extends LibrarySection {
602
598
  'lastViewedAt',
603
599
  'viewCount',
604
600
  'addedAt',
605
- ]; }
606
- static { this.ALLOWED_SORT = [
601
+ ];
602
+ static ALLOWED_SORT = [
607
603
  'addedAt',
608
604
  'originallyAvailableAt',
609
605
  'lastViewedAt',
@@ -611,18 +607,15 @@ export class MovieSection extends LibrarySection {
611
607
  'rating',
612
608
  'mediaHeight',
613
609
  'duration',
614
- ]; }
615
- static { this.TAG = 'Directory'; }
610
+ ];
611
+ static TAG = 'Directory';
612
+ METADATA_TYPE = 'movie';
613
+ CONTENT_TYPE = 'video';
614
+ SECTION_TYPE = Movie;
616
615
  }
617
616
  export class ShowSection extends LibrarySection {
618
- constructor() {
619
- super(...arguments);
620
- this.METADATA_TYPE = 'episode';
621
- this.CONTENT_TYPE = 'video';
622
- this.SECTION_TYPE = Show;
623
- }
624
- static { this.TYPE = 'show'; }
625
- static { this.ALLOWED_FILTERS = [
617
+ static TYPE = 'show';
618
+ static ALLOWED_FILTERS = [
626
619
  'unwatched',
627
620
  'year',
628
621
  'genre',
@@ -648,16 +641,19 @@ export class ShowSection extends LibrarySection {
648
641
  'episode.userRating',
649
642
  'episode.viewCount',
650
643
  'episode.lastViewedAt',
651
- ]; }
652
- static { this.ALLOWED_SORT = [
644
+ ];
645
+ static ALLOWED_SORT = [
653
646
  'addedAt',
654
647
  'lastViewedAt',
655
648
  'originallyAvailableAt',
656
649
  'titleSort',
657
650
  'rating',
658
651
  'unwatched',
659
- ]; }
660
- static { this.TAG = 'Directory'; }
652
+ ];
653
+ static TAG = 'Directory';
654
+ METADATA_TYPE = 'episode';
655
+ CONTENT_TYPE = 'video';
656
+ SECTION_TYPE = Show;
661
657
  // TODO: figure out how to return episode objects
662
658
  // /**
663
659
  // * Search for an episode. See :func:`~plexapi.library.LibrarySection.search` for usage.
@@ -675,14 +671,11 @@ export class ShowSection extends LibrarySection {
675
671
  }
676
672
  }
677
673
  export class MusicSection extends LibrarySection {
678
- constructor() {
679
- super(...arguments);
680
- this.METADATA_TYPE = 'track';
681
- this.CONTENT_TYPE = 'audio';
682
- this.SECTION_TYPE = Track;
683
- }
684
- static { this.TYPE = 'artist'; }
685
- static { this.TAG = 'Directory'; }
674
+ static TYPE = 'artist';
675
+ static TAG = 'Directory';
676
+ METADATA_TYPE = 'track';
677
+ CONTENT_TYPE = 'audio';
678
+ SECTION_TYPE = Track;
686
679
  /** Returns a list of Album objects in this section. */
687
680
  async albums() {
688
681
  const key = `/library/sections/${this.key}/albums`;
@@ -736,7 +729,7 @@ export class MusicSection extends LibrarySection {
736
729
  }
737
730
  /** Represents a single Hub (or category) in the PlexServer search */
738
731
  export class Hub extends PlexObject {
739
- static { this.TAG = 'Hub'; }
732
+ static TAG = 'Hub';
740
733
  _loadData(data) {
741
734
  this.hubIdentifier = data.hubIdentifier;
742
735
  this.size = data.size;
@@ -766,11 +759,8 @@ export class Folder extends PlexObject {
766
759
  }
767
760
  }
768
761
  export class Collections extends PartialPlexObject {
769
- constructor() {
770
- super(...arguments);
771
- this.TYPE = 'collection';
772
- }
773
- static { this.TAG = 'Directory'; }
762
+ static TAG = 'Directory';
763
+ TYPE = 'collection';
774
764
  // Alias for childCount
775
765
  get size() {
776
766
  return this.childCount;
@@ -809,7 +799,7 @@ export class Collections extends PartialPlexObject {
809
799
  }
810
800
  }
811
801
  export class FilterChoice extends PlexObject {
812
- static { this.TAG = 'Directory'; }
802
+ static TAG = 'Directory';
813
803
  _loadData(data) {
814
804
  this.key = data.key;
815
805
  this.title = data.title;
@@ -818,7 +808,7 @@ export class FilterChoice extends PlexObject {
818
808
  }
819
809
  }
820
810
  export class FilteringType extends PlexObject {
821
- static { this.TAG = 'Type'; }
811
+ static TAG = 'Type';
822
812
  _loadData(data) {
823
813
  this.active = data.active;
824
814
  this.fields = findItems(data, undefined, FilteringField);
@@ -833,7 +823,7 @@ export class FilteringType extends PlexObject {
833
823
  * Represents a single Filter object for a {@link FilteringType}
834
824
  */
835
825
  export class FilteringFilter extends PlexObject {
836
- static { this.TAG = 'Filter'; }
826
+ static TAG = 'Filter';
837
827
  _loadData(data) {
838
828
  this.filter = data.filter;
839
829
  this.filterType = data.filterType;
@@ -846,7 +836,7 @@ export class FilteringFilter extends PlexObject {
846
836
  * Represents a single Sort object for a {@link FilteringType}
847
837
  */
848
838
  export class FilteringSort extends PlexObject {
849
- static { this.TAG = 'Sort'; }
839
+ static TAG = 'Sort';
850
840
  _loadData(data) {
851
841
  this.active = data.active;
852
842
  this.activeDirection = data.activeDirection;
@@ -862,7 +852,7 @@ export class FilteringSort extends PlexObject {
862
852
  * Represents a single Field object for a {@link FilteringType}
863
853
  */
864
854
  export class FilteringField extends PlexObject {
865
- static { this.TAG = 'Field'; }
855
+ static TAG = 'Field';
866
856
  _loadData(data) {
867
857
  this.key = data.key;
868
858
  this.title = data.title;
@@ -874,7 +864,7 @@ export class FilteringField extends PlexObject {
874
864
  * Represents a single FieldType for library filtering.
875
865
  */
876
866
  export class FilteringFieldType extends PlexObject {
877
- static { this.TAG = 'FieldType'; }
867
+ static TAG = 'FieldType';
878
868
  _loadData(data) {
879
869
  this.type = data.type;
880
870
  this.operators = findItems(data, undefined, FilteringOperator);
@@ -884,7 +874,7 @@ export class FilteringFieldType extends PlexObject {
884
874
  * Represents a single FilterChoice for library filtering.
885
875
  */
886
876
  export class FilteringOperator extends PlexObject {
887
- static { this.TAG = 'Operator'; }
877
+ static TAG = 'Operator';
888
878
  _loadData(data) {
889
879
  this.key = data.key;
890
880
  this.type = data.type;
package/dist/src/media.js CHANGED
@@ -5,6 +5,7 @@ import { PlexObject } from './base/plexObject.js';
5
5
  * the construct used for things such as Country, Director, Genre, etc.
6
6
  */
7
7
  class MediaTag extends PlexObject {
8
+ static TAG;
8
9
  // async items(): Promise<any[]> {
9
10
  // if (!this.key) {
10
11
  // throw new Error(`Key is not defined for this tag: ${this.tag}`);
@@ -19,7 +20,7 @@ class MediaTag extends PlexObject {
19
20
  }
20
21
  }
21
22
  export class Media extends PlexObject {
22
- static { this.TAG = 'Media'; }
23
+ static TAG = 'Media';
23
24
  _loadData(data) {
24
25
  this.aspectRatio = data.aspectRatio;
25
26
  this.audioChannels = data.audioChannels;
@@ -39,7 +40,7 @@ export class Media extends PlexObject {
39
40
  }
40
41
  }
41
42
  export class MediaPart extends PlexObject {
42
- static { this.TAG = 'Part'; }
43
+ static TAG = 'Part';
43
44
  /**
44
45
  * Set the selected {@link AudioStream} for this MediaPart.
45
46
  * @param stream Audio stream or stream ID to set as selected.
@@ -49,7 +50,7 @@ export class MediaPart extends PlexObject {
49
50
  const params = new URLSearchParams({ allParts: '1' });
50
51
  const streamId = typeof stream === 'number' ? stream : stream.id;
51
52
  params.set('audioStreamID', streamId.toString());
52
- await this.server.query(key + '?' + params.toString(), 'put');
53
+ await this.server.query(`${key}?${params.toString()}`, 'put');
53
54
  return this;
54
55
  }
55
56
  /**
@@ -61,7 +62,7 @@ export class MediaPart extends PlexObject {
61
62
  const params = new URLSearchParams({ allParts: '1' });
62
63
  const streamId = typeof stream === 'number' ? stream : stream.id;
63
64
  params.set('subtitleStreamID', streamId.toString());
64
- await this.server.query(key + '?' + params.toString(), 'put');
65
+ await this.server.query(`${key}?${params.toString()}`, 'put');
65
66
  return this;
66
67
  }
67
68
  /**
@@ -97,7 +98,7 @@ export class MediaPart extends PlexObject {
97
98
  }
98
99
  }
99
100
  export class MediaPartStream extends PlexObject {
100
- static { this.TAG = 'Stream'; }
101
+ static TAG = 'Stream';
101
102
  _loadData(data) {
102
103
  this.id = data.id;
103
104
  this.codec = data.codec;
@@ -112,8 +113,8 @@ export class MediaPartStream extends PlexObject {
112
113
  * Represents a single Subtitle stream within a {@link MediaPart}.
113
114
  */
114
115
  export class SubtitleStream extends MediaPartStream {
115
- static { this.TAG = 'Stream'; }
116
- static { this.STREAMTYPE = 3; }
116
+ static TAG = 'Stream';
117
+ static STREAMTYPE = 3;
117
118
  /**
118
119
  * Sets this subtitle stream as the selected subtitle stream.
119
120
  * Alias for `MediaPart.setSelectedSubtitleStream`.
@@ -129,102 +130,78 @@ export class SubtitleStream extends MediaPartStream {
129
130
  super._loadData(data);
130
131
  this.canAutoSync = Boolean(data.canAutoSync); // Use !! for boolean casting from potential string/number
131
132
  this.container = data.container;
132
- this.forced = Boolean(parseInt(data.forced ?? '0', 10));
133
+ this.forced = Boolean(Number.parseInt(data.forced ?? '0', 10));
133
134
  this.format = data.format;
134
135
  this.headerCompression = data.headerCompression;
135
- this.hearingImpaired = Boolean(parseInt(data.hearingImpaired ?? '0', 10));
136
+ this.hearingImpaired = Boolean(Number.parseInt(data.hearingImpaired ?? '0', 10));
136
137
  this.perfectMatch = Boolean(data.perfectMatch);
137
138
  this.providerTitle = data.providerTitle;
138
- this.score = data.score ? parseInt(data.score, 10) : undefined;
139
+ this.score = data.score ? Number.parseInt(data.score, 10) : undefined;
139
140
  this.sourceKey = data.sourceKey;
140
141
  this.transient = data.transient;
141
- this.userID = data.userID ? parseInt(data.userID, 10) : undefined;
142
+ this.userID = data.userID ? Number.parseInt(data.userID, 10) : undefined;
142
143
  }
143
144
  }
144
145
  /**
145
146
  * Represents a single Lyric stream within a {@link MediaPart}.
146
147
  */
147
148
  export class LyricStream extends MediaPartStream {
148
- static { this.TAG = 'Stream'; }
149
- static { this.STREAMTYPE = 4; }
149
+ static TAG = 'Stream';
150
+ static STREAMTYPE = 4;
150
151
  _loadData(data) {
151
152
  super._loadData(data);
152
153
  this.format = data.format;
153
- this.minLines = data.minLines ? parseInt(data.minLines, 10) : undefined;
154
+ this.minLines = data.minLines ? Number.parseInt(data.minLines, 10) : undefined;
154
155
  this.provider = data.provider;
155
- this.timed = Boolean(parseInt(data.timed ?? '0', 10));
156
+ this.timed = Boolean(Number.parseInt(data.timed ?? '0', 10));
156
157
  }
157
158
  }
158
159
  /**
159
160
  * Represents a single Role (actor/actress) media tag.
160
161
  */
161
162
  export class Role extends MediaTag {
162
- constructor() {
163
- super(...arguments);
164
- this.FILTER = 'role';
165
- }
166
- static { this.TAG = 'Role'; }
163
+ static TAG = 'Role';
164
+ FILTER = 'role';
167
165
  }
168
166
  /**
169
167
  * Represents a single Genre media tag.
170
168
  */
171
169
  export class Genre extends MediaTag {
172
- constructor() {
173
- super(...arguments);
174
- this.FILTER = 'genre';
175
- }
176
- static { this.TAG = 'Genre'; }
170
+ static TAG = 'Genre';
171
+ FILTER = 'genre';
177
172
  }
178
173
  /**
179
174
  * Represents a single Country media tag.
180
175
  */
181
176
  export class Country extends MediaTag {
182
- constructor() {
183
- super(...arguments);
184
- this.FILTER = 'country';
185
- }
186
- static { this.TAG = 'Country'; }
177
+ static TAG = 'Country';
178
+ FILTER = 'country';
187
179
  }
188
180
  /**
189
181
  * Represents a single Writer media tag.
190
182
  */
191
183
  export class Writer extends MediaTag {
192
- constructor() {
193
- super(...arguments);
194
- this.FILTER = 'writer';
195
- }
196
- static { this.TAG = 'Writer'; }
184
+ static TAG = 'Writer';
185
+ FILTER = 'writer';
197
186
  }
198
187
  /**
199
188
  * Represents a single Director media tag.
200
189
  */
201
190
  export class Director extends MediaTag {
202
- constructor() {
203
- super(...arguments);
204
- this.FILTER = 'director';
205
- }
206
- static { this.TAG = 'Director'; }
191
+ static TAG = 'Director';
192
+ FILTER = 'director';
207
193
  }
208
194
  export class Similar extends MediaTag {
209
- constructor() {
210
- super(...arguments);
211
- this.FILTER = 'similar';
212
- }
213
- static { this.TAG = 'Similar'; }
195
+ static TAG = 'Similar';
196
+ FILTER = 'similar';
214
197
  }
215
198
  export class Producer extends MediaTag {
216
- constructor() {
217
- super(...arguments);
218
- this.FILTER = 'producer';
219
- }
220
- static { this.TAG = 'Producer'; }
199
+ static TAG = 'Producer';
200
+ FILTER = 'producer';
221
201
  }
222
202
  export class Marker extends MediaTag {
223
- constructor() {
224
- super(...arguments);
225
- this.FILTER = 'marker';
226
- }
227
- static { this.TAG = 'Marker'; }
203
+ static TAG = 'Marker';
204
+ FILTER = 'marker';
228
205
  _loadData(data) {
229
206
  this.type = data.type;
230
207
  this.startTimeOffset = data.startTimeOffset;
@@ -235,11 +212,8 @@ export class Marker extends MediaTag {
235
212
  * Represents a single Chapter media tag.
236
213
  */
237
214
  export class Chapter extends MediaTag {
238
- constructor() {
239
- super(...arguments);
240
- this.FILTER = 'chapter';
241
- }
242
- static { this.TAG = 'Chapter'; }
215
+ static TAG = 'Chapter';
216
+ FILTER = 'chapter';
243
217
  _loadData(data) {
244
218
  this.startTimeOffset = data.startTimeOffset;
245
219
  this.endTimeOffset = data.endTimeOffset;
@@ -250,46 +224,31 @@ export class Chapter extends MediaTag {
250
224
  * Represents a single Collection media tag.
251
225
  */
252
226
  export class Collection extends MediaTag {
253
- constructor() {
254
- super(...arguments);
255
- this.FILTER = 'collection';
256
- }
257
- static { this.TAG = 'Collection'; }
227
+ static TAG = 'Collection';
228
+ FILTER = 'collection';
258
229
  }
259
230
  /** Represents a single Label media tag. */
260
231
  export class Label extends MediaTag {
261
- constructor() {
262
- super(...arguments);
263
- this.FILTER = 'label';
264
- }
265
- static { this.TAG = 'Label'; }
232
+ static TAG = 'Label';
233
+ FILTER = 'label';
266
234
  }
267
235
  /** Represents a single Style media tag. */
268
236
  export class Style extends MediaTag {
269
- constructor() {
270
- super(...arguments);
271
- this.FILTER = 'style';
272
- }
273
- static { this.TAG = 'Style'; }
237
+ static TAG = 'Style';
238
+ FILTER = 'style';
274
239
  }
275
240
  /** Represents a single Format media tag. */
276
241
  export class Format extends MediaTag {
277
- constructor() {
278
- super(...arguments);
279
- this.FILTER = 'format';
280
- }
281
- static { this.TAG = 'Format'; }
242
+ static TAG = 'Format';
243
+ FILTER = 'format';
282
244
  }
283
245
  /** Represents a single Subformat media tag. */
284
246
  export class Subformat extends MediaTag {
285
- constructor() {
286
- super(...arguments);
287
- this.FILTER = 'subformat';
288
- }
289
- static { this.TAG = 'Subformat'; }
247
+ static TAG = 'Subformat';
248
+ FILTER = 'subformat';
290
249
  }
291
250
  export class Optimized extends PlexObject {
292
- static { this.TAG = 'Item'; }
251
+ static TAG = 'Item';
293
252
  // TODO: Implement items()
294
253
  /**
295
254
  * Remove this Optimized item.
@@ -332,13 +291,13 @@ class GuidTag extends PlexObject {
332
291
  }
333
292
  }
334
293
  export class Guid extends GuidTag {
335
- static { this.TAG = 'Guid'; }
294
+ static TAG = 'Guid';
336
295
  }
337
296
  /**
338
297
  * Represents a single Rating media tag.
339
298
  */
340
299
  export class Rating extends PlexObject {
341
- static { this.TAG = 'Rating'; }
300
+ static TAG = 'Rating';
342
301
  _loadData(data) {
343
302
  this.image = data.image;
344
303
  this.type = data.type;
@@ -380,26 +339,61 @@ class BaseResource extends PlexObject {
380
339
  * Represents a single Art object.
381
340
  */
382
341
  export class Art extends BaseResource {
383
- static { this.TAG = 'Art'; }
342
+ static TAG = 'Art';
384
343
  }
385
344
  /**
386
345
  * Represents a single Poster object.
387
346
  */
388
347
  export class Poster extends BaseResource {
389
- static { this.TAG = 'Photo'; }
348
+ static TAG = 'Photo';
390
349
  }
391
350
  /**
392
351
  * Represents a single Theme object.
393
352
  */
394
353
  export class Theme extends BaseResource {
395
- static { this.TAG = 'Theme'; }
354
+ static TAG = 'Theme';
396
355
  }
397
356
  /**
398
357
  * Represents a single Audio stream within a {@link MediaPart}.
399
358
  */
400
359
  export class AudioStream extends MediaPartStream {
401
- static { this.TAG = 'Stream'; }
402
- static { this.STREAMTYPE = 2; }
360
+ static TAG = 'Stream';
361
+ static STREAMTYPE = 2;
362
+ /** The audio channel layout of the audio stream (ex: 5.1(side)). */
363
+ audioChannelLayout;
364
+ /** The bit depth of the audio stream (ex: 16). */
365
+ bitDepth;
366
+ /** The bitrate mode of the audio stream (ex: cbr). */
367
+ bitrateMode;
368
+ /** The number of audio channels of the audio stream (ex: 6). */
369
+ channels;
370
+ /** The duration of audio stream in milliseconds. */
371
+ duration;
372
+ /** The profile of the audio stream. */
373
+ profile;
374
+ /** The sampling rate of the audio stream (ex: 48000) */
375
+ samplingRate;
376
+ /** The stream identifier of the audio stream. */
377
+ streamIdentifier;
378
+ // Track only attributes
379
+ /** The gain for the album. */
380
+ albumGain;
381
+ /** The peak for the album. */
382
+ albumPeak;
383
+ /** The range for the album. */
384
+ albumRange;
385
+ /** The end ramp for the track. */
386
+ endRamp;
387
+ /** The gain for the track. */
388
+ gain;
389
+ /** The loudness for the track. */
390
+ loudness;
391
+ /** The lra for the track. */
392
+ lra;
393
+ /** The peak for the track. */
394
+ peak;
395
+ /** The start ramp for the track. */
396
+ startRamp;
403
397
  /**
404
398
  * Sets this audio stream as the selected audio stream.
405
399
  * Alias for {@link MediaPart.setSelectedAudioStream}.
@@ -414,29 +408,31 @@ export class AudioStream extends MediaPartStream {
414
408
  _loadData(data) {
415
409
  super._loadData(data);
416
410
  this.audioChannelLayout = data.audioChannelLayout;
417
- this.bitDepth = data.bitDepth ? parseInt(data.bitDepth, 10) : undefined;
411
+ this.bitDepth = data.bitDepth ? Number.parseInt(data.bitDepth, 10) : undefined;
418
412
  this.bitrateMode = data.bitrateMode;
419
- this.channels = data.channels ? parseInt(data.channels, 10) : undefined;
420
- this.duration = data.duration ? parseInt(data.duration, 10) : undefined;
413
+ this.channels = data.channels ? Number.parseInt(data.channels, 10) : undefined;
414
+ this.duration = data.duration ? Number.parseInt(data.duration, 10) : undefined;
421
415
  this.profile = data.profile;
422
- this.samplingRate = data.samplingRate ? parseInt(data.samplingRate, 10) : undefined;
423
- this.streamIdentifier = data.streamIdentifier ? parseInt(data.streamIdentifier, 10) : undefined;
424
- this.visualImpaired = Boolean(parseInt(data.visualImpaired ?? '0', 10));
416
+ this.samplingRate = data.samplingRate ? Number.parseInt(data.samplingRate, 10) : undefined;
417
+ this.streamIdentifier = data.streamIdentifier
418
+ ? Number.parseInt(data.streamIdentifier, 10)
419
+ : undefined;
420
+ this.visualImpaired = Boolean(Number.parseInt(data.visualImpaired ?? '0', 10));
425
421
  // Track only attributes
426
- this.albumGain = data.albumGain ? parseFloat(data.albumGain) : undefined;
427
- this.albumPeak = data.albumPeak ? parseFloat(data.albumPeak) : undefined;
428
- this.albumRange = data.albumRange ? parseFloat(data.albumRange) : undefined;
422
+ this.albumGain = data.albumGain ? Number.parseFloat(data.albumGain) : undefined;
423
+ this.albumPeak = data.albumPeak ? Number.parseFloat(data.albumPeak) : undefined;
424
+ this.albumRange = data.albumRange ? Number.parseFloat(data.albumRange) : undefined;
429
425
  this.endRamp = data.endRamp;
430
- this.gain = data.gain ? parseFloat(data.gain) : undefined;
431
- this.loudness = data.loudness ? parseFloat(data.loudness) : undefined;
432
- this.lra = data.lra ? parseFloat(data.lra) : undefined;
433
- this.peak = data.peak ? parseFloat(data.peak) : undefined;
426
+ this.gain = data.gain ? Number.parseFloat(data.gain) : undefined;
427
+ this.loudness = data.loudness ? Number.parseFloat(data.loudness) : undefined;
428
+ this.lra = data.lra ? Number.parseFloat(data.lra) : undefined;
429
+ this.peak = data.peak ? Number.parseFloat(data.peak) : undefined;
434
430
  this.startRamp = data.startRamp;
435
431
  }
436
432
  }
437
433
  /** Represents a single Image media tag. */
438
434
  export class Image extends PlexObject {
439
- static { this.TAG = 'Image'; }
435
+ static TAG = 'Image';
440
436
  _loadData(data) {
441
437
  this.alt = data.alt;
442
438
  this.type = data.type;
@@ -446,7 +442,7 @@ export class Image extends PlexObject {
446
442
  }
447
443
  /** Represents a single Field. */
448
444
  export class Field extends PlexObject {
449
- static { this.TAG = 'Field'; }
445
+ static TAG = 'Field';
450
446
  _loadData(data) {
451
447
  // Convert potential string '1' or '0' to boolean
452
448
  this.locked = data.locked === '1' || data.locked === true;
@@ -455,9 +451,6 @@ export class Field extends PlexObject {
455
451
  }
456
452
  /** Represents a single Mood media tag. */
457
453
  export class Mood extends MediaTag {
458
- constructor() {
459
- super(...arguments);
460
- this.FILTER = 'mood';
461
- }
462
- static { this.TAG = 'Mood'; }
454
+ static TAG = 'Mood';
455
+ FILTER = 'mood';
463
456
  }