@ctrl/plex 3.0.0 → 3.2.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 CHANGED
@@ -98,3 +98,41 @@ Post testing, remove plex server from account. Warning this is destructive. Do n
98
98
  ```sh
99
99
  npm run test-cleanup
100
100
  ```
101
+
102
+
103
+ ### Running tests locally (mostly for myself)
104
+
105
+ get a claim token from https://www.plex.tv/claim/
106
+ export PLEX_CLAIM_TOKEN=claim-token
107
+
108
+ ```
109
+ docker run -d \
110
+ --name=plex \
111
+ --net=host \
112
+ -h orbstack \
113
+ -p 32400:32400/tcp \
114
+ -p 32400:32400 \
115
+ -p 1900:1900/udp \
116
+ -p 5353:5353/udp \
117
+ -p 8324:8324 \
118
+ -p 32410:32410/udp \
119
+ -p 32412:32412/udp \
120
+ -p 32413:32413/udp \
121
+ -p 32414:32414/udp \
122
+ -p 32469:32469 \
123
+ -e PUID=1000 \
124
+ -e PGID=1000 \
125
+ -e TZ=Etc/UTC \
126
+ -e VERSION=docker \
127
+ -e PLEX_CLAIM=$PLEX_CLAIM_TOKEN \
128
+ -v /Users/scooper/gh/plex/plex/media/db:/config \
129
+ -v /Users/scooper/gh/plex/plex/media/transcode:/transcode \
130
+ -v /Users/scooper/gh/plex/plex/media:/data \
131
+ --restart unless-stopped \
132
+ lscr.io/linuxserver/plex:latest
133
+ ```
134
+
135
+ bootstrap media
136
+ ```
137
+ NODE_OPTIONS="--loader ts-node/esm" node scripts/bootstraptest.ts --no-docker --server-name=orbstack`
138
+ ```
@@ -260,7 +260,7 @@ export declare abstract class LibrarySection<SectionVideoType = VideoType> exten
260
260
  readonly VIDEO_TYPE: Class<SectionVideoType>;
261
261
  _filterTypes?: FilteringType[];
262
262
  _fieldTypes?: FilteringFieldType[];
263
- all(sort?: string): Promise<any[]>;
263
+ all(sort?: string): Promise<SectionVideoType[]>;
264
264
  agents(): Promise<Agent[]>;
265
265
  /**
266
266
  * @param title Title of the item to return.
@@ -283,7 +283,7 @@ export class LibrarySection extends PlexObject {
283
283
  sortStr = `?sort=${sort}`;
284
284
  }
285
285
  const key = `/library/sections/${this.key}/all${sortStr}`;
286
- const items = await fetchItems(this.server, key);
286
+ const items = await fetchItems(this.server, key, undefined, this.VIDEO_TYPE, this);
287
287
  return items;
288
288
  }
289
289
  async agents() {
@@ -110,6 +110,7 @@ export interface MovieData {
110
110
  Extras?: ExtrasData[];
111
111
  Guid?: Guid[];
112
112
  Marker?: MarkerData[];
113
+ Rating?: MediaRating[];
113
114
  }
114
115
  export interface MediaTag {
115
116
  tag: string;
@@ -246,4 +247,15 @@ interface ExtrasStream {
246
247
  selected?: boolean;
247
248
  channels?: number;
248
249
  }
250
+ interface MediaRating {
251
+ image: string;
252
+ /**
253
+ * ex 8.3
254
+ */
255
+ value: number;
256
+ /**
257
+ * ex 'audience'
258
+ */
259
+ type: string;
260
+ }
249
261
  export {};
@@ -179,4 +179,25 @@ declare class GuidTag extends PlexObject {
179
179
  export declare class Guid extends GuidTag {
180
180
  static TAG: "Guid";
181
181
  }
182
+ /**
183
+ * Represents a single Rating media tag.
184
+ */
185
+ export declare class Rating extends PlexObject {
186
+ static TAG: "Rating";
187
+ /**
188
+ * The uri for the rating image
189
+ * (e.g. ``imdb://image.rating``, ``rottentomatoes://image.rating.ripe``,
190
+ * ``rottentomatoes://image.rating.upright``, ``themoviedb://image.rating``).
191
+ */
192
+ image: string;
193
+ /**
194
+ * The type of rating (e.g. audience or critic).
195
+ */
196
+ type: 'audience' | 'critic';
197
+ /**
198
+ * The rating value.
199
+ */
200
+ value: number;
201
+ protected _loadData(data: any): void;
202
+ }
182
203
  export {};
package/dist/src/media.js CHANGED
@@ -189,3 +189,14 @@ class GuidTag extends PlexObject {
189
189
  export class Guid extends GuidTag {
190
190
  static { this.TAG = 'Guid'; }
191
191
  }
192
+ /**
193
+ * Represents a single Rating media tag.
194
+ */
195
+ export class Rating extends PlexObject {
196
+ static { this.TAG = 'Rating'; }
197
+ _loadData(data) {
198
+ this.image = data.image;
199
+ this.type = data.type;
200
+ this.value = data.value;
201
+ }
202
+ }
@@ -2,7 +2,7 @@
2
2
  import { URL } from 'url';
3
3
  import { Playable } from './base/playable.js';
4
4
  import { ExtrasData, FullShowData, MovieData, ShowData } from './library.types.js';
5
- import { Chapter, Collection, Country, Director, Genre, Guid, Marker, Media, Producer, Role, Similar, Writer } from './media.js';
5
+ import { Chapter, Collection, Country, Director, Genre, Guid, Marker, Media, Producer, Rating, Role, Similar, Writer } from './media.js';
6
6
  import { ChapterSource, EpisodeMetadata, FullMovieResponse } from './video.types.js';
7
7
  export type VideoType = Movie | Show;
8
8
  declare abstract class Video extends Playable {
@@ -24,6 +24,14 @@ declare abstract class Video extends Playable {
24
24
  viewCount?: number;
25
25
  art?: string;
26
26
  grandparentArt?: string;
27
+ /**
28
+ * BlurHash string for artwork image.
29
+ */
30
+ artBlurHash?: string;
31
+ /**
32
+ * BlurHash string for thumbnail image.
33
+ */
34
+ thumbBlurHash?: string;
27
35
  /**
28
36
  * Returns True if this video is watched.
29
37
  */
@@ -95,6 +103,7 @@ export declare class Movie extends Video {
95
103
  media: Media[];
96
104
  guids: Guid[];
97
105
  markers: Marker[];
106
+ ratings?: Rating[];
98
107
  get actors(): Role[];
99
108
  locations(): Promise<string[]>;
100
109
  /**
package/dist/src/video.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { Playable } from './base/playable.js';
2
2
  import { fetchItem, fetchItems, findItems } from './baseFunctionality.js';
3
- import { Chapter, Collection, Country, Director, Genre, Guid, Marker, Media, Producer, Role, Similar, Writer, } from './media.js';
3
+ import { Chapter, Collection, Country, Director, Genre, Guid, Marker, Media, Producer, Rating, Role, Similar, Writer, } from './media.js';
4
4
  class Video extends Playable {
5
5
  constructor() {
6
6
  super(...arguments);
@@ -71,6 +71,9 @@ class Video extends Playable {
71
71
  this.titleSort = data.titleSort ?? this.title;
72
72
  this.viewCount = data.viewCount;
73
73
  this.playlistItemID = data.playlistItemID;
74
+ // todo: update one of them with this property
75
+ this.artBlurHash = data.artBlurHash;
76
+ this.thumbBlurHash = data.thumbBlurHash;
74
77
  }
75
78
  }
76
79
  /**
@@ -143,6 +146,7 @@ export class Movie extends Video {
143
146
  this.media = data.Media?.map(d => new Media(this.server, d, undefined, this)) ?? [];
144
147
  this.guids = data.Guid?.map(d => new Guid(this.server, d, undefined, this)) ?? [];
145
148
  this.markers = data.Marker?.map(d => new Marker(this.server, d, undefined, this)) ?? [];
149
+ this.ratings = data.Rating?.map(d => new Rating(this.server, d, undefined, this)) ?? [];
146
150
  }
147
151
  _loadFullData(data) {
148
152
  const metadata = data.Metadata[0];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ctrl/plex",
3
- "version": "3.0.0",
3
+ "version": "3.2.0",
4
4
  "description": "plex api client in typescript",
5
5
  "author": "Scott Cooper <scttcper@gmail.com>",
6
6
  "publishConfig": {
@@ -20,10 +20,10 @@
20
20
  "typescript"
21
21
  ],
22
22
  "scripts": {
23
- "lint": "pnpm run '/^(lint:biome|lint:eslint)$/'",
23
+ "lint": "npm run lint:biome && npm run lint:eslint",
24
24
  "lint:biome": "biome check .",
25
25
  "lint:eslint": "eslint --ext .ts,.tsx .",
26
- "lint:fix": "pnpm run '/^(lint:biome|lint:eslint):fix$/'",
26
+ "lint:fix": "npm run lint:biome:fix && npm run lint:eslint:fix",
27
27
  "lint:eslint:fix": "eslint --ext .ts,.tsx . --fix",
28
28
  "lint:biome:fix": "biome check . --apply",
29
29
  "prepare": "npm run build",
@@ -33,7 +33,6 @@
33
33
  "test:ci": "vitest run --coverage --reporter=default --reporter=junit --outputFile=./junit.xml",
34
34
  "bootstraptest": "node --loader ts-node/esm scripts/bootstraptest.ts",
35
35
  "teardowntest": "node --loader ts-node/esm scripts/teardowntest.ts",
36
- "claim-server": "node --loader ts-node/esm scripts/claim-server.ts",
37
36
  "add-media": "node --loader ts-node/esm scripts/add-media.ts",
38
37
  "test-cleanup": "node --loader ts-node/esm scripts/test-cleanup.ts"
39
38
  },
@@ -41,34 +40,34 @@
41
40
  "@ctrl/mac-address": "^3.0.3",
42
41
  "ofetch": "^1.3.4",
43
42
  "p-any": "^4.0.0",
44
- "type-fest": "^4.17.0",
43
+ "type-fest": "^4.18.1",
45
44
  "ws": "^8.17.0",
46
45
  "xml2js": "^0.6.2"
47
46
  },
48
47
  "devDependencies": {
49
- "@biomejs/biome": "1.7.1",
48
+ "@biomejs/biome": "1.7.2",
50
49
  "@ctrl/eslint-config-biome": "2.6.7",
51
50
  "@sindresorhus/tsconfig": "5.0.0",
52
- "@types/lodash": "4.17.0",
51
+ "@types/lodash": "4.17.1",
53
52
  "@types/micromatch": "4.0.7",
54
- "@types/node": "20.12.7",
53
+ "@types/node": "20.12.8",
55
54
  "@types/ws": "8.5.10",
56
55
  "@types/xml2js": "0.4.14",
57
56
  "@types/yargs": "17.0.32",
58
- "@vitest/coverage-v8": "1.5.2",
57
+ "@vitest/coverage-v8": "1.6.0",
59
58
  "delay": "6.0.0",
60
59
  "eslint": "8.57.0",
61
60
  "execa": "8.0.1",
62
61
  "glob": "10.3.12",
63
62
  "globby": "14.0.1",
64
63
  "lodash": "4.17.21",
65
- "make-dir": "4.0.0",
64
+ "make-dir": "5.0.0",
66
65
  "ora": "8.0.1",
67
66
  "p-retry": "6.2.0",
68
67
  "ts-node": "10.9.2",
69
68
  "typedoc": "0.25.13",
70
69
  "typescript": "5.4.5",
71
- "vitest": "1.5.2",
70
+ "vitest": "1.6.0",
72
71
  "yargs": "17.7.2"
73
72
  },
74
73
  "release": {