@redseat/api 0.3.6 → 0.3.11
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/CLAUDE.md +1 -1
- package/README.md +137 -132
- package/{AGENTS.md → agents.md} +275 -275
- package/client.md +670 -670
- package/dist/client.d.ts +4 -1
- package/dist/client.js +9 -0
- package/dist/interfaces.d.ts +181 -0
- package/dist/library.d.ts +42 -2
- package/dist/library.js +54 -0
- package/dist/sse-types.d.ts +28 -1
- package/encryption.md +533 -533
- package/firebase.md +602 -602
- package/libraries.md +207 -20
- package/package.json +49 -49
- package/server.md +538 -398
- package/test.md +291 -291
package/dist/client.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { Method, AxiosRequestConfig } from 'axios';
|
|
|
2
2
|
import { Observable } from 'rxjs';
|
|
3
3
|
import { IToken } from './auth.js';
|
|
4
4
|
import { IServer } from './interfaces.js';
|
|
5
|
-
import { SSEConnectionState, SSEConnectionOptions, SSEConnectionError, SSELibraryEvent, SSELibraryStatusEvent, SSEMediasEvent, SSEUploadProgressEvent, SSEConvertProgressEvent, SSEEpisodesEvent, SSESeriesEvent, SSEMoviesEvent, SSEPeopleEvent, SSETagsEvent, SSEBackupsEvent, SSEBackupFilesEvent, SSEMediaRatingEvent, SSEMediaProgressEvent, SSEPlayersListEvent } from './sse-types.js';
|
|
5
|
+
import { SSEConnectionState, SSEConnectionOptions, SSEConnectionError, SSELibraryEvent, SSELibraryStatusEvent, SSEMediasEvent, SSEUploadProgressEvent, SSEConvertProgressEvent, SSEEpisodesEvent, SSESeriesEvent, SSEMoviesEvent, SSEPeopleEvent, SSETagsEvent, SSEBackupsEvent, SSEBackupFilesEvent, SSEMediaRatingEvent, SSEMediaProgressEvent, SSEPlayersListEvent, SSEWatchedEvent, SSEUnwatchedEvent, SSERequestProcessingEvent } from './sse-types.js';
|
|
6
6
|
export interface ClientOptions {
|
|
7
7
|
server: IServer;
|
|
8
8
|
getIdToken: () => Promise<string>;
|
|
@@ -45,6 +45,9 @@ export declare class RedseatClient {
|
|
|
45
45
|
readonly mediaRating$: Observable<SSEMediaRatingEvent>;
|
|
46
46
|
readonly mediaProgress$: Observable<SSEMediaProgressEvent>;
|
|
47
47
|
readonly playersList$: Observable<SSEPlayersListEvent>;
|
|
48
|
+
readonly watched$: Observable<SSEWatchedEvent>;
|
|
49
|
+
readonly unwatched$: Observable<SSEUnwatchedEvent>;
|
|
50
|
+
readonly requestProcessing$: Observable<SSERequestProcessingEvent>;
|
|
48
51
|
/**
|
|
49
52
|
* Creates a typed observable for a specific SSE event type.
|
|
50
53
|
* Unwraps the nested data structure from the server (e.g., {uploadProgress: {...}} -> {...})
|
package/dist/client.js
CHANGED
|
@@ -17,6 +17,12 @@ export class RedseatClient {
|
|
|
17
17
|
'library-status': 'libraryStatus',
|
|
18
18
|
'backups-files': 'backupsFiles',
|
|
19
19
|
'players-list': 'Players',
|
|
20
|
+
'episodes': 'episodes',
|
|
21
|
+
'series': 'series',
|
|
22
|
+
'movies': 'movies',
|
|
23
|
+
'people': 'people',
|
|
24
|
+
'tags': 'tags',
|
|
25
|
+
'request_processing': 'requestProcessing',
|
|
20
26
|
};
|
|
21
27
|
const wrapperKey = wrapperMap[eventName];
|
|
22
28
|
return this._sseEvents.pipe(filter((event) => event.event === eventName), map(event => {
|
|
@@ -55,6 +61,9 @@ export class RedseatClient {
|
|
|
55
61
|
this.mediaRating$ = this.createEventStream('media_rating');
|
|
56
62
|
this.mediaProgress$ = this.createEventStream('media_progress');
|
|
57
63
|
this.playersList$ = this.createEventStream('players-list');
|
|
64
|
+
this.watched$ = this.createEventStream('watched');
|
|
65
|
+
this.unwatched$ = this.createEventStream('unwatched');
|
|
66
|
+
this.requestProcessing$ = this.createEventStream('request_processing');
|
|
58
67
|
this.server = options.server;
|
|
59
68
|
this.redseatUrl = options.redseatUrl;
|
|
60
69
|
this.getIdToken = options.getIdToken;
|
package/dist/interfaces.d.ts
CHANGED
|
@@ -483,40 +483,191 @@ export declare enum RsSort {
|
|
|
483
483
|
Name = "name",
|
|
484
484
|
Size = "size"
|
|
485
485
|
}
|
|
486
|
+
/**
|
|
487
|
+
* Media type for history/watched tracking.
|
|
488
|
+
* Used to categorize watched entries and view progress.
|
|
489
|
+
*/
|
|
486
490
|
export type MediaType = 'episode' | 'movie' | 'book' | 'song' | 'media';
|
|
491
|
+
/**
|
|
492
|
+
* Watch history entry - returned from GET /users/me/history.
|
|
493
|
+
*
|
|
494
|
+
* ## External ID Format
|
|
495
|
+
*
|
|
496
|
+
* Watch history uses **external IDs** (from providers like IMDb, Trakt, TMDb) rather than
|
|
497
|
+
* local database IDs. This design enables:
|
|
498
|
+
* - **Cross-server portability**: History syncs across different Redseat servers
|
|
499
|
+
* - **External service synchronization**: Seamless sync with Trakt, Plex, etc.
|
|
500
|
+
* - **Library independence**: History is global, not tied to a specific library
|
|
501
|
+
*
|
|
502
|
+
* ### ID Format: `provider:value`
|
|
503
|
+
*
|
|
504
|
+
* Examples:
|
|
505
|
+
* - `imdb:tt1234567` - IMDb ID for movies/episodes
|
|
506
|
+
* - `trakt:123456` - Trakt ID
|
|
507
|
+
* - `tmdb:550` - TMDb ID
|
|
508
|
+
* - `tvdb:12345` - TVDB ID for series/episodes
|
|
509
|
+
* - `redseat:abc123` - Local fallback when no external ID is available
|
|
510
|
+
*
|
|
511
|
+
* When marking content as watched via library endpoints (e.g., `setMovieWatched`),
|
|
512
|
+
* the server automatically resolves the local ID to an external ID.
|
|
513
|
+
*/
|
|
487
514
|
export interface IWatched {
|
|
515
|
+
/** Content type (episode, movie, etc.) */
|
|
488
516
|
type: MediaType;
|
|
517
|
+
/**
|
|
518
|
+
* External ID in format `provider:value` (e.g., `imdb:tt1234567`).
|
|
519
|
+
* See interface documentation for details on the ID format.
|
|
520
|
+
*/
|
|
489
521
|
id: string;
|
|
522
|
+
/** User reference (for admin queries) */
|
|
490
523
|
userRef?: string;
|
|
524
|
+
/** Timestamp when content was watched (unix milliseconds) */
|
|
491
525
|
date: number;
|
|
526
|
+
/** Timestamp when entry was last modified (unix milliseconds) */
|
|
492
527
|
modified: number;
|
|
493
528
|
}
|
|
529
|
+
/**
|
|
530
|
+
* Unwatched event data - emitted via SSE when content is removed from watch history.
|
|
531
|
+
*
|
|
532
|
+
* Unlike IWatched which has a single `id`, this uses `ids[]` array containing
|
|
533
|
+
* all possible external IDs (imdb, trakt, tmdb, local) so clients can match
|
|
534
|
+
* against any provider they have cached.
|
|
535
|
+
*
|
|
536
|
+
* This is a user-scoped event - not library-scoped.
|
|
537
|
+
*/
|
|
538
|
+
export interface IUnwatched {
|
|
539
|
+
/** Content type (episode, movie, etc.) */
|
|
540
|
+
type: MediaType;
|
|
541
|
+
/**
|
|
542
|
+
* All possible external IDs for this content.
|
|
543
|
+
* Format: `provider:value`
|
|
544
|
+
* Examples: ["imdb:tt0111161", "trakt:481", "tmdb:278"]
|
|
545
|
+
*/
|
|
546
|
+
ids: string[];
|
|
547
|
+
/** User reference */
|
|
548
|
+
userRef?: string;
|
|
549
|
+
/** Timestamp when entry was removed (unix milliseconds) */
|
|
550
|
+
modified: number;
|
|
551
|
+
}
|
|
552
|
+
/**
|
|
553
|
+
* Request body for adding to watch history via POST /users/me/history.
|
|
554
|
+
*
|
|
555
|
+
* ## External ID Requirement
|
|
556
|
+
*
|
|
557
|
+
* When using the direct history endpoint, you must provide an external ID.
|
|
558
|
+
* The ID format is `provider:value`:
|
|
559
|
+
* - `imdb:tt1234567` - IMDb ID
|
|
560
|
+
* - `trakt:123456` - Trakt ID
|
|
561
|
+
* - `tmdb:550` - TMDb ID
|
|
562
|
+
* - `tvdb:12345` - TVDB ID
|
|
563
|
+
*
|
|
564
|
+
* **Tip**: For easier usage, prefer the library-specific endpoints
|
|
565
|
+
* (`setMovieWatched`, `setEpisodeWatched`) which automatically resolve IDs.
|
|
566
|
+
*
|
|
567
|
+
* @example
|
|
568
|
+
* ```typescript
|
|
569
|
+
* // Direct history endpoint - requires external ID
|
|
570
|
+
* await serverApi.addToHistory({
|
|
571
|
+
* type: 'movie',
|
|
572
|
+
* id: 'imdb:tt0111161', // The Shawshank Redemption
|
|
573
|
+
* date: Date.now()
|
|
574
|
+
* });
|
|
575
|
+
*
|
|
576
|
+
* // Library endpoint - uses local ID, server resolves to external
|
|
577
|
+
* await libraryApi.setMovieWatched('local-movie-id', Date.now());
|
|
578
|
+
* ```
|
|
579
|
+
*/
|
|
494
580
|
export interface IWatchedForAdd {
|
|
581
|
+
/** Content type (episode, movie, etc.) */
|
|
495
582
|
type: MediaType;
|
|
583
|
+
/**
|
|
584
|
+
* External ID in format `provider:value` (e.g., `imdb:tt1234567`).
|
|
585
|
+
* See interface documentation for details on the ID format.
|
|
586
|
+
*/
|
|
496
587
|
id: string;
|
|
588
|
+
/** Timestamp when content was watched (unix milliseconds) */
|
|
497
589
|
date: number;
|
|
498
590
|
}
|
|
591
|
+
/**
|
|
592
|
+
* View progress entry - returned from GET /users/me/history/progress/:id.
|
|
593
|
+
*
|
|
594
|
+
* Tracks playback position for resumable viewing.
|
|
595
|
+
* Uses the same external ID format as watch history.
|
|
596
|
+
*/
|
|
499
597
|
export interface IViewProgress {
|
|
598
|
+
/** Content type (episode, movie, etc.) */
|
|
500
599
|
type: MediaType;
|
|
600
|
+
/**
|
|
601
|
+
* External ID in format `provider:value` (e.g., `imdb:tt1234567`).
|
|
602
|
+
*/
|
|
501
603
|
id: string;
|
|
604
|
+
/** User reference */
|
|
502
605
|
userRef: string;
|
|
606
|
+
/** Playback progress in milliseconds */
|
|
503
607
|
progress: number;
|
|
608
|
+
/** Parent ID for episodes (series external ID) */
|
|
504
609
|
parent?: string;
|
|
610
|
+
/** Timestamp when progress was last modified (unix milliseconds) */
|
|
505
611
|
modified: number;
|
|
506
612
|
}
|
|
613
|
+
/**
|
|
614
|
+
* Request body for updating view progress via POST /users/me/history/progress.
|
|
615
|
+
*
|
|
616
|
+
* Uses external IDs in format `provider:value` (e.g., `imdb:tt1234567`).
|
|
617
|
+
*
|
|
618
|
+
* @example
|
|
619
|
+
* ```typescript
|
|
620
|
+
* await serverApi.addProgress({
|
|
621
|
+
* type: 'movie',
|
|
622
|
+
* id: 'imdb:tt0111161',
|
|
623
|
+
* progress: 3600000 // 1 hour in milliseconds
|
|
624
|
+
* });
|
|
625
|
+
* ```
|
|
626
|
+
*/
|
|
507
627
|
export interface IViewProgressForAdd {
|
|
628
|
+
/** Content type (episode, movie, etc.) */
|
|
508
629
|
type: MediaType;
|
|
630
|
+
/**
|
|
631
|
+
* External ID in format `provider:value` (e.g., `imdb:tt1234567`).
|
|
632
|
+
*/
|
|
509
633
|
id: string;
|
|
634
|
+
/** Parent ID for episodes (series external ID) */
|
|
510
635
|
parent?: string;
|
|
636
|
+
/** Playback progress in milliseconds */
|
|
511
637
|
progress: number;
|
|
512
638
|
}
|
|
639
|
+
/**
|
|
640
|
+
* Query parameters for GET /users/me/history.
|
|
641
|
+
*
|
|
642
|
+
* @example
|
|
643
|
+
* ```typescript
|
|
644
|
+
* // Get recent movie history
|
|
645
|
+
* const history = await serverApi.getHistory({
|
|
646
|
+
* types: ['movie'],
|
|
647
|
+
* order: SqlOrder.DESC,
|
|
648
|
+
* after: Date.now() - 86400000 * 30 // Last 30 days
|
|
649
|
+
* });
|
|
650
|
+
*
|
|
651
|
+
* // Check if specific content was watched
|
|
652
|
+
* const watched = await serverApi.getHistory({
|
|
653
|
+
* id: 'imdb:tt0111161'
|
|
654
|
+
* });
|
|
655
|
+
* ```
|
|
656
|
+
*/
|
|
513
657
|
export interface HistoryQuery {
|
|
658
|
+
/** Sort field */
|
|
514
659
|
sort?: RsSort;
|
|
660
|
+
/** Sort direction */
|
|
515
661
|
order?: SqlOrder;
|
|
662
|
+
/** Filter entries watched before this timestamp (unix ms) */
|
|
516
663
|
before?: number;
|
|
664
|
+
/** Filter entries watched after this timestamp (unix ms) */
|
|
517
665
|
after?: number;
|
|
666
|
+
/** Filter by content types */
|
|
518
667
|
types?: MediaType[];
|
|
668
|
+
/** Filter by specific external ID */
|
|
519
669
|
id?: string;
|
|
670
|
+
/** Pagination key for next page */
|
|
520
671
|
pageKey?: number;
|
|
521
672
|
}
|
|
522
673
|
export type MovieSort = 'modified' | 'added' | 'created' | 'name' | 'digitalairdate';
|
|
@@ -580,6 +731,8 @@ export interface RsRequest {
|
|
|
580
731
|
size?: number;
|
|
581
732
|
filename?: string;
|
|
582
733
|
status: RsRequestStatus;
|
|
734
|
+
pluginName?: string;
|
|
735
|
+
pluginId?: string;
|
|
583
736
|
permanent: boolean;
|
|
584
737
|
instant?: boolean;
|
|
585
738
|
jsonBody?: any;
|
|
@@ -617,3 +770,31 @@ export interface RsGroupDownload {
|
|
|
617
770
|
groupMime?: string;
|
|
618
771
|
requests: RsRequest[];
|
|
619
772
|
}
|
|
773
|
+
/**
|
|
774
|
+
* Request processing status from plugin-based download/processing.
|
|
775
|
+
* Tracks progress of downloads, file processing, etc.
|
|
776
|
+
*/
|
|
777
|
+
export interface IRsRequestProcessing {
|
|
778
|
+
/** Internal nanoid */
|
|
779
|
+
id: string;
|
|
780
|
+
/** Plugin's processing ID */
|
|
781
|
+
processingId: string;
|
|
782
|
+
/** Plugin handling the request */
|
|
783
|
+
pluginId: string;
|
|
784
|
+
/** Progress 0-100 */
|
|
785
|
+
progress: number;
|
|
786
|
+
/** Status: "pending" | "processing" | "paused" | "finished" | "error" */
|
|
787
|
+
status: string;
|
|
788
|
+
/** Error message if status is "error" */
|
|
789
|
+
error?: string;
|
|
790
|
+
/** UTC timestamp (ms) for estimated completion */
|
|
791
|
+
eta?: number;
|
|
792
|
+
/** Reference to media being processed */
|
|
793
|
+
mediaRef?: string;
|
|
794
|
+
/** The original request */
|
|
795
|
+
originalRequest?: RsRequest;
|
|
796
|
+
/** Last modified timestamp */
|
|
797
|
+
modified: number;
|
|
798
|
+
/** Creation timestamp */
|
|
799
|
+
added: number;
|
|
800
|
+
}
|
package/dist/library.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Observable } from 'rxjs';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import type { AxiosResponse } from 'axios';
|
|
3
|
+
import { IFile, ITag, IPerson, ISerie, IMovie, MediaRequest, IEpisode, ExternalImage, IBackupFile, ILibrary, SerieInMedia, DeletedQuery, RsDeleted, MovieSort, RsSort, SqlOrder, RsRequest, DetectedFaceResult, UnassignFaceResponse, RsGroupDownload, IViewProgress, IWatched, IRsRequestProcessing } from './interfaces.js';
|
|
4
|
+
import { SSEMediasEvent, SSEUploadProgressEvent, SSEConvertProgressEvent, SSEEpisodesEvent, SSESeriesEvent, SSEMoviesEvent, SSEPeopleEvent, SSETagsEvent, SSELibraryStatusEvent, SSEMediaRatingEvent, SSEMediaProgressEvent, SSERequestProcessingEvent } from './sse-types.js';
|
|
4
5
|
import { EncryptFileOptions, EncryptedFile } from './encryption.js';
|
|
5
6
|
export interface MediaForUpdate {
|
|
6
7
|
name?: string;
|
|
@@ -87,6 +88,7 @@ export interface LibraryHttpClient {
|
|
|
87
88
|
readonly libraryStatus$?: Observable<SSELibraryStatusEvent>;
|
|
88
89
|
readonly mediaRating$?: Observable<SSEMediaRatingEvent>;
|
|
89
90
|
readonly mediaProgress$?: Observable<SSEMediaProgressEvent>;
|
|
91
|
+
readonly requestProcessing$?: Observable<SSERequestProcessingEvent>;
|
|
90
92
|
}
|
|
91
93
|
export declare class LibraryApi {
|
|
92
94
|
private client;
|
|
@@ -106,6 +108,7 @@ export declare class LibraryApi {
|
|
|
106
108
|
readonly libraryStatus$: Observable<SSELibraryStatusEvent>;
|
|
107
109
|
readonly mediaRating$: Observable<SSEMediaRatingEvent>;
|
|
108
110
|
readonly mediaProgress$: Observable<SSEMediaProgressEvent>;
|
|
111
|
+
readonly requestProcessing$: Observable<SSERequestProcessingEvent>;
|
|
109
112
|
constructor(client: LibraryHttpClient, libraryId: string, library: ILibrary);
|
|
110
113
|
/**
|
|
111
114
|
* Creates a library-filtered stream from a client stream.
|
|
@@ -253,6 +256,43 @@ export declare class LibraryApi {
|
|
|
253
256
|
checkRequestInstant(request: RsRequest): Promise<{
|
|
254
257
|
instant: boolean;
|
|
255
258
|
}>;
|
|
259
|
+
/**
|
|
260
|
+
* Process an unprocessed RsRequest and return the processed result.
|
|
261
|
+
* Takes a raw request and runs it through the server's plugin processing pipeline.
|
|
262
|
+
* @param request - The unprocessed request to process
|
|
263
|
+
* @returns The processed request with updated status and metadata
|
|
264
|
+
*/
|
|
265
|
+
processRequest(request: RsRequest): Promise<RsRequest>;
|
|
266
|
+
/**
|
|
267
|
+
* Process a request and return the raw HTTP stream response.
|
|
268
|
+
* Use this to stream content directly without processing the full response.
|
|
269
|
+
* @param request - The request to process and stream
|
|
270
|
+
* @returns Raw axios response with stream data - use response.data for the stream
|
|
271
|
+
*/
|
|
272
|
+
processRequestStream(request: RsRequest): Promise<AxiosResponse>;
|
|
273
|
+
/**
|
|
274
|
+
* Add a request to the processing queue.
|
|
275
|
+
* @param request - The request to add for processing
|
|
276
|
+
* @param mediaRef - Optional media reference to associate with the processing
|
|
277
|
+
* @returns The created request processing entry
|
|
278
|
+
*/
|
|
279
|
+
addRequest(request: RsRequest, mediaRef?: string): Promise<IRsRequestProcessing>;
|
|
280
|
+
/**
|
|
281
|
+
* List all active request processings for this library.
|
|
282
|
+
* @returns Array of request processing entries
|
|
283
|
+
*/
|
|
284
|
+
listRequestProcessing(): Promise<IRsRequestProcessing[]>;
|
|
285
|
+
/**
|
|
286
|
+
* Pause a request processing task.
|
|
287
|
+
* @param processingId - The ID of the processing task to pause
|
|
288
|
+
* @returns The updated request processing entry with status "paused"
|
|
289
|
+
*/
|
|
290
|
+
pauseRequestProcessing(processingId: string): Promise<IRsRequestProcessing>;
|
|
291
|
+
/**
|
|
292
|
+
* Delete/remove a request processing task.
|
|
293
|
+
* @param processingId - The ID of the processing task to delete
|
|
294
|
+
*/
|
|
295
|
+
deleteRequestProcessing(processingId: string): Promise<void>;
|
|
256
296
|
/**
|
|
257
297
|
* Get a share token for a request URL.
|
|
258
298
|
* The token can be used to stream/download the resource without authentication.
|
package/dist/library.js
CHANGED
|
@@ -19,6 +19,7 @@ export class LibraryApi {
|
|
|
19
19
|
this.libraryStatus$ = this.createLibraryFilteredStream(client.libraryStatus$);
|
|
20
20
|
this.mediaRating$ = this.createLibraryFilteredStream(client.mediaRating$);
|
|
21
21
|
this.mediaProgress$ = this.createLibraryFilteredStream(client.mediaProgress$);
|
|
22
|
+
this.requestProcessing$ = this.createLibraryFilteredStream(client.requestProcessing$);
|
|
22
23
|
}
|
|
23
24
|
/**
|
|
24
25
|
* Creates a library-filtered stream from a client stream.
|
|
@@ -525,6 +526,59 @@ export class LibraryApi {
|
|
|
525
526
|
const res = await this.client.post(this.getUrl('/plugins/requests/check-instant'), request);
|
|
526
527
|
return res.data;
|
|
527
528
|
}
|
|
529
|
+
/**
|
|
530
|
+
* Process an unprocessed RsRequest and return the processed result.
|
|
531
|
+
* Takes a raw request and runs it through the server's plugin processing pipeline.
|
|
532
|
+
* @param request - The unprocessed request to process
|
|
533
|
+
* @returns The processed request with updated status and metadata
|
|
534
|
+
*/
|
|
535
|
+
async processRequest(request) {
|
|
536
|
+
const res = await this.client.post(this.getUrl('/plugins/requests/process'), request);
|
|
537
|
+
return res.data;
|
|
538
|
+
}
|
|
539
|
+
/**
|
|
540
|
+
* Process a request and return the raw HTTP stream response.
|
|
541
|
+
* Use this to stream content directly without processing the full response.
|
|
542
|
+
* @param request - The request to process and stream
|
|
543
|
+
* @returns Raw axios response with stream data - use response.data for the stream
|
|
544
|
+
*/
|
|
545
|
+
async processRequestStream(request) {
|
|
546
|
+
return this.client.post(this.getUrl('/plugins/requests/process/stream'), request, { responseType: 'stream' });
|
|
547
|
+
}
|
|
548
|
+
/**
|
|
549
|
+
* Add a request to the processing queue.
|
|
550
|
+
* @param request - The request to add for processing
|
|
551
|
+
* @param mediaRef - Optional media reference to associate with the processing
|
|
552
|
+
* @returns The created request processing entry
|
|
553
|
+
*/
|
|
554
|
+
async addRequest(request, mediaRef) {
|
|
555
|
+
const res = await this.client.post(this.getUrl('/plugins/requests/add'), { request, mediaRef });
|
|
556
|
+
return res.data;
|
|
557
|
+
}
|
|
558
|
+
/**
|
|
559
|
+
* List all active request processings for this library.
|
|
560
|
+
* @returns Array of request processing entries
|
|
561
|
+
*/
|
|
562
|
+
async listRequestProcessing() {
|
|
563
|
+
const res = await this.client.get(this.getUrl('/plugins/requests/processing'));
|
|
564
|
+
return res.data;
|
|
565
|
+
}
|
|
566
|
+
/**
|
|
567
|
+
* Pause a request processing task.
|
|
568
|
+
* @param processingId - The ID of the processing task to pause
|
|
569
|
+
* @returns The updated request processing entry with status "paused"
|
|
570
|
+
*/
|
|
571
|
+
async pauseRequestProcessing(processingId) {
|
|
572
|
+
const res = await this.client.post(this.getUrl(`/plugins/requests/processing/${processingId}/pause`));
|
|
573
|
+
return res.data;
|
|
574
|
+
}
|
|
575
|
+
/**
|
|
576
|
+
* Delete/remove a request processing task.
|
|
577
|
+
* @param processingId - The ID of the processing task to delete
|
|
578
|
+
*/
|
|
579
|
+
async deleteRequestProcessing(processingId) {
|
|
580
|
+
await this.client.delete(this.getUrl(`/plugins/requests/processing/${processingId}`));
|
|
581
|
+
}
|
|
528
582
|
/**
|
|
529
583
|
* Get a share token for a request URL.
|
|
530
584
|
* The token can be used to stream/download the resource without authentication.
|
package/dist/sse-types.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ILibrary, IFile, IEpisode, ISerie, IMovie, IPerson, ITag, IBackup } from './interfaces.js';
|
|
1
|
+
import { ILibrary, IFile, IEpisode, ISerie, IMovie, IPerson, ITag, IBackup, IWatched, IUnwatched, IRsRequestProcessing } from './interfaces.js';
|
|
2
2
|
export type ElementAction = 'Added' | 'Updated' | 'Deleted';
|
|
3
3
|
export type SSEConnectionState = 'disconnected' | 'connecting' | 'connected' | 'reconnecting' | 'error';
|
|
4
4
|
export interface SSEConnectionOptions {
|
|
@@ -134,6 +134,30 @@ export interface SSEPlayersListEvent {
|
|
|
134
134
|
userRef: string;
|
|
135
135
|
players: SSEPlayerEvent[];
|
|
136
136
|
}
|
|
137
|
+
/**
|
|
138
|
+
* SSE event emitted when content is marked as watched.
|
|
139
|
+
* This is a user-scoped event - not library-scoped.
|
|
140
|
+
* Uses external IDs (e.g., "imdb:tt0111161").
|
|
141
|
+
*/
|
|
142
|
+
export type SSEWatchedEvent = IWatched;
|
|
143
|
+
/**
|
|
144
|
+
* SSE event emitted when content is removed from watch history.
|
|
145
|
+
* Contains all possible external IDs so clients can match against any cached ID.
|
|
146
|
+
* This is a user-scoped event - not library-scoped.
|
|
147
|
+
*/
|
|
148
|
+
export type SSEUnwatchedEvent = IUnwatched;
|
|
149
|
+
/**
|
|
150
|
+
* SSE event for request processing status updates.
|
|
151
|
+
* Tracks plugin-based request processing (downloads, file processing, etc.).
|
|
152
|
+
* This is a library-scoped event.
|
|
153
|
+
*/
|
|
154
|
+
export interface SSERequestProcessingEvent {
|
|
155
|
+
library: string;
|
|
156
|
+
processings: {
|
|
157
|
+
action: ElementAction;
|
|
158
|
+
processing: IRsRequestProcessing;
|
|
159
|
+
}[];
|
|
160
|
+
}
|
|
137
161
|
export interface SSEEventMap {
|
|
138
162
|
'library': SSELibraryEvent;
|
|
139
163
|
'library-status': SSELibraryStatusEvent;
|
|
@@ -150,6 +174,9 @@ export interface SSEEventMap {
|
|
|
150
174
|
'media_rating': SSEMediaRatingEvent;
|
|
151
175
|
'media_progress': SSEMediaProgressEvent;
|
|
152
176
|
'players-list': SSEPlayersListEvent;
|
|
177
|
+
'watched': SSEWatchedEvent;
|
|
178
|
+
'unwatched': SSEUnwatchedEvent;
|
|
179
|
+
'request_processing': SSERequestProcessingEvent;
|
|
153
180
|
}
|
|
154
181
|
export type SSEEventName = keyof SSEEventMap;
|
|
155
182
|
export interface SSEEvent<T extends SSEEventName = SSEEventName> {
|