Something went wrong. Try again.
[READ-ONLY] Mirror of https://github.com/FoxxMD/multi-scrobbler. Scrobble plays from multiple sources to multiple clients docs.multi-scrobbler.app
deezer docker jellyfin koito lastfm listenbrainz maloja mopidy mpris music music-assistant plex scrobble self-hosted spotify subsonic tautulli youtube-music
Something went wrong. Try again.
TypeScript
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485import type { Response } from 'superagent';
export interface SubsonicResponseCommon { status: 'failed' | 'ok' version: string type: string, serverVersion: string openSubsonic: boolean error?: { code: number, message: string } [key: string]: any}
export interface SubsonicResponseBody<T extends SubsonicResponseCommon = SubsonicResponseCommon> { "subsonic-response": T}
export interface SubsonicResponse extends Response { body: SubsonicResponseBody}
export interface SubsonicNowPlayingResponse extends SubsonicResponseCommon { nowPlaying: { entry?: EntryData[] }}
export interface OpenSubsonicExtension { name: string, versions: number[]}
export interface OpenSubsonicExtensionsResponse extends SubsonicResponseCommon { openSubsonicExtensions: OpenSubsonicExtension[]}
export type SubsonicPlaybackState = 'playing' | 'paused' | 'stopped' | 'starting' | string;
export interface PlaybackReportData { /** * State is only provided by the server if the playback report extension is implemented by the server and used by the active client (see https://opensubsonic.netlify.app/docs/extensions/playbackreport/) * */ state?: SubsonicPlaybackState, /** * PositionMs is only provided by the server if the playback report extension is implemented by the server and used by the active client (see https://opensubsonic.netlify.app/docs/extensions/playbackreport/) * */ positionMs?: number}
export interface EntryData extends PlaybackReportData { id: string, title: string, album?: string, artist: string, /** * Length of track in seconds * */ duration: number, /** * When track began playing relative to now * * Returned as *whole* minutes so it isn't very accurate * */ minutesAgo: number, playerId: string, username: string,}
export const asSubsonicResponseCommon = (obj: unknown): obj is SubsonicResponseCommon => { return obj !== null && typeof obj === 'object' && 'status' in obj;}
export const asSubsonicResponseBody = (obj: unknown): obj is SubsonicResponseBody => { return obj !== null && typeof obj === 'object' && 'subsonic-response' in obj;}
export const getSubsonicResponse = (resp: Response): SubsonicResponseCommon | undefined => { if(asSubsonicResponseBody(resp.body) && asSubsonicResponseCommon(resp.body['subsonic-response'])) { return resp.body['subsonic-response']; } return undefined;}