@francofantomius/jellyfin 0.4.0 → 0.4.2

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/dist/index.d.cts CHANGED
@@ -306,10 +306,11 @@ interface AudioStreamOptions {
306
306
  transcodingContainer?: string;
307
307
  audioCodec?: string;
308
308
  deviceId?: string;
309
+ mediaSourceId?: string;
309
310
  /**
310
- * Whether to include the api_key token in the URL query parameters.
311
+ * Whether to include the authentication token in the URL query parameters (ApiKey, api_key, X-Emby-Token).
311
312
  * Defaults to true for HTML5 <audio> tag compatibility.
312
- * If false, callers are expected to provide Authorization headers.
313
+ * Set to false when providing modern Authorization headers to avoid conflicting authentication credentials in Jellyfin 12+.
313
314
  */
314
315
  useQueryToken?: boolean;
315
316
  }
@@ -320,10 +321,11 @@ interface AudioHlsStreamOptions {
320
321
  audioCodec?: string;
321
322
  segmentLength?: number;
322
323
  deviceId?: string;
324
+ mediaSourceId?: string;
323
325
  /**
324
- * Whether to include the api_key token in the URL query parameters.
326
+ * Whether to include the authentication token in the URL query parameters (ApiKey, api_key, X-Emby-Token).
325
327
  * Defaults to true for legacy compatibility.
326
- * If false, players (e.g. hls.js) should be configured with Authorization headers via xhrSetup.
328
+ * Set to false when players (e.g. hls.js) are configured with Authorization headers via xhrSetup to prevent 401s from conflicting auth methods in Jellyfin 12+.
327
329
  */
328
330
  useQueryToken?: boolean;
329
331
  }
@@ -1146,8 +1148,11 @@ declare class MediaModule {
1146
1148
  /**
1147
1149
  * Returns authentication headers for media streaming requests (e.g., configuring hls.js xhrSetup).
1148
1150
  * Crucial for Jellyfin 12+ servers where query-based auth (?api_key=) is disabled.
1151
+ * Pass { legacy: false } to only send Authorization and avoid conflicting headers or reverse-proxy CORS rejections.
1149
1152
  */
1150
- getStreamHeaders(): Record<string, string>;
1153
+ getStreamHeaders(options?: {
1154
+ legacy?: boolean;
1155
+ }): Record<string, string>;
1151
1156
  }
1152
1157
 
1153
1158
  declare class LyricsModule {
@@ -1933,4 +1938,5 @@ declare class JellyfinAuthError extends JellyfinApiError {
1933
1938
  constructor(message?: string, status?: number, endpoint?: string);
1934
1939
  }
1935
1940
 
1936
- export { AUDIO_QUALITY_PRESETS, type ArtworkUrlOptions, type AudioHlsStreamOptions, type AudioQualityOption, type AudioQualityPresetKey, type AudioStreamOptions, AuthModule, type AuthenticationResult, type BaseItemDto, COMMON_SEARCH_FIELDS, type CacheAdapter, type CacheRecord, type ChapterImageOptions, type ChapterInfoDto, ChaptersModule, type ClientCapabilities, type ClientEventListener, type ClientEventType, type ClientInfo, CollectionsModule, type CreateCollectionOptions, type CreatePlaylistDto, type CreatePlaylistOptions, type DisplayPreferencesDto, DisplayPreferencesModule, type DownloadItemOptions, type DownloadProgress, type DownloadRecord, type DownloadUrlOptions, FavoritesModule, type GeneralCommandDto, type GeneralCommandType, GenresModule, type GetAlbumsOptions, type GetArtistsOptions, type GetCollectionItemsOptions, type GetCollectionsOptions, type GetDisplayPreferencesOptions, type GetEpisodesOptions, type GetGenresOptions, type GetLatestMediaOptions, type GetMediaSegmentsOptions, type GetMoviesOptions, type GetNextUpOptions, type GetResumeItemsOptions, type GetSeasonsOptions, type GetSeriesOptions, type GetSessionsOptions, type GetSongsOptions, type GetStudiosOptions, type GetVideosOptions, HttpTransport, IndexedDBCacheAdapter, type IntroCreditsMarkers, type ItemsResponse, JellyfinApiError, JellyfinAuthError, JellyfinClient, type JellyfinClientOptions, JellyfinError, LatestModule, type LibraryChangedData, LibraryModule, LocalStorageAdapter, type LyricLine, type LyricsDto, LyricsModule, type MarkerRange, MediaModule, type MediaSegmentDto, type MediaSegmentType, type MediaSourceInfo, type MediaStreamInfo, MemoryCacheAdapter, MemoryStorage, NextUpModule, OfflineStorageManager, type PlayCommandType, type PlaybackInfoOptions, type PlaybackInfoResponse, PlaybackModule, PlaylistsModule, type PlaystateCommand, type PublicSystemInfo, QuickConnectModule, type QuickConnectPollOptions, type QuickConnectResult, type QuickConnectState, type RemotePlayOptions, type RequestOptions, ResumeModule, SearchModule, type SearchOptions, type SessionInfoDto, type SessionMessageOptions, type SessionPlayState, SessionsModule, type StopActiveEncodingOptions, type StorageAdapter, type SubtitleTrackInfo, type SubtitleUrlOptions, type SystemInfo, SystemModule, type ThumbnailLookupOptions, type ThumbnailLookupResult, TranscodeModule, type TrickplayInfoDto, type TrickplayManifestInfo, type TrickplayManifestTile, TrickplayModule, type TrickplayStreamOptions, type UpdateDisplayPreferencesOptions, type UpdatePlaylistOptions, type UserDataChangedData, type UserDto, type UserItemDataDto, VIDEO_QUALITY_PRESETS, type VideoHlsStreamOptions, type VideoQualityOption, type VideoQualityPresetKey, type VideoStreamOptions, type WebSocketEventListener, type WebSocketInboundMessage, type WebSocketMessageType, WebSocketModule, type WebSocketModuleOptions, buildAuthHeader, cleanUrl, fetchWithCache, formatBitrate, generateDeviceId, getAudioQualityList, getDefaultStorage, getVideoQualityList, isV12OrHigher, isVersionAtLeast, parseSemVer, resolveAudioQuality, resolveVideoQuality };
1941
+ export { AUDIO_QUALITY_PRESETS, AuthModule, COMMON_SEARCH_FIELDS, ChaptersModule, CollectionsModule, DisplayPreferencesModule, FavoritesModule, GenresModule, HttpTransport, IndexedDBCacheAdapter, JellyfinApiError, JellyfinAuthError, JellyfinClient, JellyfinError, LatestModule, LibraryModule, LocalStorageAdapter, LyricsModule, MediaModule, MemoryCacheAdapter, MemoryStorage, NextUpModule, OfflineStorageManager, PlaybackModule, PlaylistsModule, QuickConnectModule, ResumeModule, SearchModule, SessionsModule, SystemModule, TranscodeModule, TrickplayModule, VIDEO_QUALITY_PRESETS, WebSocketModule, buildAuthHeader, cleanUrl, fetchWithCache, formatBitrate, generateDeviceId, getAudioQualityList, getDefaultStorage, getVideoQualityList, isV12OrHigher, isVersionAtLeast, parseSemVer, resolveAudioQuality, resolveVideoQuality };
1942
+ export type { ArtworkUrlOptions, AudioHlsStreamOptions, AudioQualityOption, AudioQualityPresetKey, AudioStreamOptions, AuthenticationResult, BaseItemDto, CacheAdapter, CacheRecord, ChapterImageOptions, ChapterInfoDto, ClientCapabilities, ClientEventListener, ClientEventType, ClientInfo, CreateCollectionOptions, CreatePlaylistDto, CreatePlaylistOptions, DisplayPreferencesDto, DownloadItemOptions, DownloadProgress, DownloadRecord, DownloadUrlOptions, GeneralCommandDto, GeneralCommandType, GetAlbumsOptions, GetArtistsOptions, GetCollectionItemsOptions, GetCollectionsOptions, GetDisplayPreferencesOptions, GetEpisodesOptions, GetGenresOptions, GetLatestMediaOptions, GetMediaSegmentsOptions, GetMoviesOptions, GetNextUpOptions, GetResumeItemsOptions, GetSeasonsOptions, GetSeriesOptions, GetSessionsOptions, GetSongsOptions, GetStudiosOptions, GetVideosOptions, IntroCreditsMarkers, ItemsResponse, JellyfinClientOptions, LibraryChangedData, LyricLine, LyricsDto, MarkerRange, MediaSegmentDto, MediaSegmentType, MediaSourceInfo, MediaStreamInfo, PlayCommandType, PlaybackInfoOptions, PlaybackInfoResponse, PlaystateCommand, PublicSystemInfo, QuickConnectPollOptions, QuickConnectResult, QuickConnectState, RemotePlayOptions, RequestOptions, SearchOptions, SessionInfoDto, SessionMessageOptions, SessionPlayState, StopActiveEncodingOptions, StorageAdapter, SubtitleTrackInfo, SubtitleUrlOptions, SystemInfo, ThumbnailLookupOptions, ThumbnailLookupResult, TrickplayInfoDto, TrickplayManifestInfo, TrickplayManifestTile, TrickplayStreamOptions, UpdateDisplayPreferencesOptions, UpdatePlaylistOptions, UserDataChangedData, UserDto, UserItemDataDto, VideoHlsStreamOptions, VideoQualityOption, VideoQualityPresetKey, VideoStreamOptions, WebSocketEventListener, WebSocketInboundMessage, WebSocketMessageType, WebSocketModuleOptions };
package/dist/index.d.ts CHANGED
@@ -306,10 +306,11 @@ interface AudioStreamOptions {
306
306
  transcodingContainer?: string;
307
307
  audioCodec?: string;
308
308
  deviceId?: string;
309
+ mediaSourceId?: string;
309
310
  /**
310
- * Whether to include the api_key token in the URL query parameters.
311
+ * Whether to include the authentication token in the URL query parameters (ApiKey, api_key, X-Emby-Token).
311
312
  * Defaults to true for HTML5 <audio> tag compatibility.
312
- * If false, callers are expected to provide Authorization headers.
313
+ * Set to false when providing modern Authorization headers to avoid conflicting authentication credentials in Jellyfin 12+.
313
314
  */
314
315
  useQueryToken?: boolean;
315
316
  }
@@ -320,10 +321,11 @@ interface AudioHlsStreamOptions {
320
321
  audioCodec?: string;
321
322
  segmentLength?: number;
322
323
  deviceId?: string;
324
+ mediaSourceId?: string;
323
325
  /**
324
- * Whether to include the api_key token in the URL query parameters.
326
+ * Whether to include the authentication token in the URL query parameters (ApiKey, api_key, X-Emby-Token).
325
327
  * Defaults to true for legacy compatibility.
326
- * If false, players (e.g. hls.js) should be configured with Authorization headers via xhrSetup.
328
+ * Set to false when players (e.g. hls.js) are configured with Authorization headers via xhrSetup to prevent 401s from conflicting auth methods in Jellyfin 12+.
327
329
  */
328
330
  useQueryToken?: boolean;
329
331
  }
@@ -1146,8 +1148,11 @@ declare class MediaModule {
1146
1148
  /**
1147
1149
  * Returns authentication headers for media streaming requests (e.g., configuring hls.js xhrSetup).
1148
1150
  * Crucial for Jellyfin 12+ servers where query-based auth (?api_key=) is disabled.
1151
+ * Pass { legacy: false } to only send Authorization and avoid conflicting headers or reverse-proxy CORS rejections.
1149
1152
  */
1150
- getStreamHeaders(): Record<string, string>;
1153
+ getStreamHeaders(options?: {
1154
+ legacy?: boolean;
1155
+ }): Record<string, string>;
1151
1156
  }
1152
1157
 
1153
1158
  declare class LyricsModule {
@@ -1933,4 +1938,5 @@ declare class JellyfinAuthError extends JellyfinApiError {
1933
1938
  constructor(message?: string, status?: number, endpoint?: string);
1934
1939
  }
1935
1940
 
1936
- export { AUDIO_QUALITY_PRESETS, type ArtworkUrlOptions, type AudioHlsStreamOptions, type AudioQualityOption, type AudioQualityPresetKey, type AudioStreamOptions, AuthModule, type AuthenticationResult, type BaseItemDto, COMMON_SEARCH_FIELDS, type CacheAdapter, type CacheRecord, type ChapterImageOptions, type ChapterInfoDto, ChaptersModule, type ClientCapabilities, type ClientEventListener, type ClientEventType, type ClientInfo, CollectionsModule, type CreateCollectionOptions, type CreatePlaylistDto, type CreatePlaylistOptions, type DisplayPreferencesDto, DisplayPreferencesModule, type DownloadItemOptions, type DownloadProgress, type DownloadRecord, type DownloadUrlOptions, FavoritesModule, type GeneralCommandDto, type GeneralCommandType, GenresModule, type GetAlbumsOptions, type GetArtistsOptions, type GetCollectionItemsOptions, type GetCollectionsOptions, type GetDisplayPreferencesOptions, type GetEpisodesOptions, type GetGenresOptions, type GetLatestMediaOptions, type GetMediaSegmentsOptions, type GetMoviesOptions, type GetNextUpOptions, type GetResumeItemsOptions, type GetSeasonsOptions, type GetSeriesOptions, type GetSessionsOptions, type GetSongsOptions, type GetStudiosOptions, type GetVideosOptions, HttpTransport, IndexedDBCacheAdapter, type IntroCreditsMarkers, type ItemsResponse, JellyfinApiError, JellyfinAuthError, JellyfinClient, type JellyfinClientOptions, JellyfinError, LatestModule, type LibraryChangedData, LibraryModule, LocalStorageAdapter, type LyricLine, type LyricsDto, LyricsModule, type MarkerRange, MediaModule, type MediaSegmentDto, type MediaSegmentType, type MediaSourceInfo, type MediaStreamInfo, MemoryCacheAdapter, MemoryStorage, NextUpModule, OfflineStorageManager, type PlayCommandType, type PlaybackInfoOptions, type PlaybackInfoResponse, PlaybackModule, PlaylistsModule, type PlaystateCommand, type PublicSystemInfo, QuickConnectModule, type QuickConnectPollOptions, type QuickConnectResult, type QuickConnectState, type RemotePlayOptions, type RequestOptions, ResumeModule, SearchModule, type SearchOptions, type SessionInfoDto, type SessionMessageOptions, type SessionPlayState, SessionsModule, type StopActiveEncodingOptions, type StorageAdapter, type SubtitleTrackInfo, type SubtitleUrlOptions, type SystemInfo, SystemModule, type ThumbnailLookupOptions, type ThumbnailLookupResult, TranscodeModule, type TrickplayInfoDto, type TrickplayManifestInfo, type TrickplayManifestTile, TrickplayModule, type TrickplayStreamOptions, type UpdateDisplayPreferencesOptions, type UpdatePlaylistOptions, type UserDataChangedData, type UserDto, type UserItemDataDto, VIDEO_QUALITY_PRESETS, type VideoHlsStreamOptions, type VideoQualityOption, type VideoQualityPresetKey, type VideoStreamOptions, type WebSocketEventListener, type WebSocketInboundMessage, type WebSocketMessageType, WebSocketModule, type WebSocketModuleOptions, buildAuthHeader, cleanUrl, fetchWithCache, formatBitrate, generateDeviceId, getAudioQualityList, getDefaultStorage, getVideoQualityList, isV12OrHigher, isVersionAtLeast, parseSemVer, resolveAudioQuality, resolveVideoQuality };
1941
+ export { AUDIO_QUALITY_PRESETS, AuthModule, COMMON_SEARCH_FIELDS, ChaptersModule, CollectionsModule, DisplayPreferencesModule, FavoritesModule, GenresModule, HttpTransport, IndexedDBCacheAdapter, JellyfinApiError, JellyfinAuthError, JellyfinClient, JellyfinError, LatestModule, LibraryModule, LocalStorageAdapter, LyricsModule, MediaModule, MemoryCacheAdapter, MemoryStorage, NextUpModule, OfflineStorageManager, PlaybackModule, PlaylistsModule, QuickConnectModule, ResumeModule, SearchModule, SessionsModule, SystemModule, TranscodeModule, TrickplayModule, VIDEO_QUALITY_PRESETS, WebSocketModule, buildAuthHeader, cleanUrl, fetchWithCache, formatBitrate, generateDeviceId, getAudioQualityList, getDefaultStorage, getVideoQualityList, isV12OrHigher, isVersionAtLeast, parseSemVer, resolveAudioQuality, resolveVideoQuality };
1942
+ export type { ArtworkUrlOptions, AudioHlsStreamOptions, AudioQualityOption, AudioQualityPresetKey, AudioStreamOptions, AuthenticationResult, BaseItemDto, CacheAdapter, CacheRecord, ChapterImageOptions, ChapterInfoDto, ClientCapabilities, ClientEventListener, ClientEventType, ClientInfo, CreateCollectionOptions, CreatePlaylistDto, CreatePlaylistOptions, DisplayPreferencesDto, DownloadItemOptions, DownloadProgress, DownloadRecord, DownloadUrlOptions, GeneralCommandDto, GeneralCommandType, GetAlbumsOptions, GetArtistsOptions, GetCollectionItemsOptions, GetCollectionsOptions, GetDisplayPreferencesOptions, GetEpisodesOptions, GetGenresOptions, GetLatestMediaOptions, GetMediaSegmentsOptions, GetMoviesOptions, GetNextUpOptions, GetResumeItemsOptions, GetSeasonsOptions, GetSeriesOptions, GetSessionsOptions, GetSongsOptions, GetStudiosOptions, GetVideosOptions, IntroCreditsMarkers, ItemsResponse, JellyfinClientOptions, LibraryChangedData, LyricLine, LyricsDto, MarkerRange, MediaSegmentDto, MediaSegmentType, MediaSourceInfo, MediaStreamInfo, PlayCommandType, PlaybackInfoOptions, PlaybackInfoResponse, PlaystateCommand, PublicSystemInfo, QuickConnectPollOptions, QuickConnectResult, QuickConnectState, RemotePlayOptions, RequestOptions, SearchOptions, SessionInfoDto, SessionMessageOptions, SessionPlayState, StopActiveEncodingOptions, StorageAdapter, SubtitleTrackInfo, SubtitleUrlOptions, SystemInfo, ThumbnailLookupOptions, ThumbnailLookupResult, TrickplayInfoDto, TrickplayManifestInfo, TrickplayManifestTile, TrickplayStreamOptions, UpdateDisplayPreferencesOptions, UpdatePlaylistOptions, UserDataChangedData, UserDto, UserItemDataDto, VideoHlsStreamOptions, VideoQualityOption, VideoQualityPresetKey, VideoStreamOptions, WebSocketEventListener, WebSocketInboundMessage, WebSocketMessageType, WebSocketModuleOptions };
package/dist/index.js CHANGED
@@ -25,7 +25,10 @@ var JellyfinAuthError = class extends JellyfinApiError {
25
25
  // src/http.ts
26
26
  function cleanUrl(url) {
27
27
  if (!url) return "";
28
- let cleaned = url.trim().replace(/\/+$/, "");
28
+ let cleaned = url.trim();
29
+ while (cleaned.endsWith("/")) {
30
+ cleaned = cleaned.slice(0, -1);
31
+ }
29
32
  if (!/^https?:\/\//i.test(cleaned)) {
30
33
  cleaned = "https://" + cleaned;
31
34
  }
@@ -1186,6 +1189,7 @@ var MediaModule = class {
1186
1189
  const qualityResolved = resolveAudioQuality(options.quality);
1187
1190
  const maxStreamingBitrate = options.maxStreamingBitrate ?? qualityResolved.maxStreamingBitrate;
1188
1191
  const {
1192
+ mediaSourceId,
1189
1193
  static: isStatic = false,
1190
1194
  startTimeTicks = 0,
1191
1195
  container = "opus,mp3|mp3,aac,m4a,m4b,flac,wav,ogg",
@@ -1196,12 +1200,14 @@ var MediaModule = class {
1196
1200
  const endpoint = isStatic ? `/Audio/${itemId}/stream` : `/Audio/${itemId}/universal`;
1197
1201
  const url = new URL(`${serverUrl}${endpoint}`);
1198
1202
  if (token && useQueryToken) {
1203
+ url.searchParams.append("ApiKey", token);
1199
1204
  url.searchParams.append("api_key", token);
1200
1205
  url.searchParams.append("X-Emby-Token", token);
1201
1206
  }
1202
1207
  if (userId) url.searchParams.append("UserId", userId);
1203
1208
  const targetDeviceId = options.deviceId !== void 0 ? options.deviceId : clientInfo.deviceId;
1204
1209
  if (targetDeviceId) url.searchParams.append("DeviceId", targetDeviceId);
1210
+ if (mediaSourceId) url.searchParams.append("MediaSourceId", mediaSourceId);
1205
1211
  if (isStatic) {
1206
1212
  url.searchParams.append("static", "true");
1207
1213
  } else {
@@ -1232,6 +1238,7 @@ var MediaModule = class {
1232
1238
  const qualityResolved = resolveAudioQuality(options.quality);
1233
1239
  const maxStreamingBitrate = options.maxStreamingBitrate ?? qualityResolved.maxStreamingBitrate;
1234
1240
  const {
1241
+ mediaSourceId,
1235
1242
  startTimeTicks = 0,
1236
1243
  audioCodec = "aac,mp3",
1237
1244
  segmentLength = 3,
@@ -1239,13 +1246,16 @@ var MediaModule = class {
1239
1246
  } = options;
1240
1247
  const url = new URL(`${serverUrl}/Audio/${itemId}/master.m3u8`);
1241
1248
  if (token && useQueryToken) {
1249
+ url.searchParams.append("ApiKey", token);
1242
1250
  url.searchParams.append("api_key", token);
1243
1251
  url.searchParams.append("X-Emby-Token", token);
1244
1252
  }
1245
1253
  if (userId) url.searchParams.append("UserId", userId);
1246
1254
  const targetDeviceId = options.deviceId !== void 0 ? options.deviceId : clientInfo.deviceId;
1247
1255
  if (targetDeviceId) url.searchParams.append("DeviceId", targetDeviceId);
1248
- url.searchParams.append("MediaSourceId", itemId);
1256
+ if (mediaSourceId) {
1257
+ url.searchParams.append("MediaSourceId", mediaSourceId);
1258
+ }
1249
1259
  url.searchParams.append("AudioCodec", audioCodec);
1250
1260
  url.searchParams.append("TranscodingContainer", "ts");
1251
1261
  url.searchParams.append("TranscodingProtocol", "hls");
@@ -1291,6 +1301,7 @@ var MediaModule = class {
1291
1301
  const endpoint = container && !container.includes(",") ? `/Videos/${itemId}/stream.${container}` : `/Videos/${itemId}/stream`;
1292
1302
  const url = new URL(`${serverUrl}${endpoint}`);
1293
1303
  if (token && useQueryToken) {
1304
+ url.searchParams.append("ApiKey", token);
1294
1305
  url.searchParams.append("api_key", token);
1295
1306
  url.searchParams.append("X-Emby-Token", token);
1296
1307
  }
@@ -1356,6 +1367,7 @@ var MediaModule = class {
1356
1367
  } = options;
1357
1368
  const url = new URL(`${serverUrl}/Videos/${itemId}/master.m3u8`);
1358
1369
  if (token && useQueryToken) {
1370
+ url.searchParams.append("ApiKey", token);
1359
1371
  url.searchParams.append("api_key", token);
1360
1372
  url.searchParams.append("X-Emby-Token", token);
1361
1373
  }
@@ -1398,6 +1410,7 @@ var MediaModule = class {
1398
1410
  const sourceId = mediaSourceId || itemId;
1399
1411
  const url = new URL(`${serverUrl}/Videos/${itemId}/${sourceId}/Subtitles/${subtitleStreamIndex}/Stream.${format}`);
1400
1412
  if (token && useQueryToken) {
1413
+ url.searchParams.append("ApiKey", token);
1401
1414
  url.searchParams.append("api_key", token);
1402
1415
  }
1403
1416
  if (startTimeTicks > 0) {
@@ -1471,6 +1484,7 @@ var MediaModule = class {
1471
1484
  if (!serverUrl || !itemId) return "";
1472
1485
  const url = new URL(`${serverUrl}/Items/${itemId}/Download`);
1473
1486
  if (token && useQueryToken) {
1487
+ url.searchParams.append("ApiKey", token);
1474
1488
  url.searchParams.append("api_key", token);
1475
1489
  }
1476
1490
  if (filename) {
@@ -1517,13 +1531,17 @@ var MediaModule = class {
1517
1531
  /**
1518
1532
  * Returns authentication headers for media streaming requests (e.g., configuring hls.js xhrSetup).
1519
1533
  * Crucial for Jellyfin 12+ servers where query-based auth (?api_key=) is disabled.
1534
+ * Pass { legacy: false } to only send Authorization and avoid conflicting headers or reverse-proxy CORS rejections.
1520
1535
  */
1521
- getStreamHeaders() {
1536
+ getStreamHeaders(options = {}) {
1522
1537
  const authHeader = this.http.getAuthHeader();
1523
- return {
1524
- Authorization: authHeader,
1525
- "X-Emby-Authorization": authHeader
1538
+ const headers = {
1539
+ Authorization: authHeader
1526
1540
  };
1541
+ if (options.legacy ?? true) {
1542
+ headers["X-Emby-Authorization"] = authHeader;
1543
+ }
1544
+ return headers;
1527
1545
  }
1528
1546
  };
1529
1547
 
@@ -1660,7 +1678,7 @@ var OfflineStorageManager = class {
1660
1678
  request.onerror = () => resolve(null);
1661
1679
  });
1662
1680
  } catch (err) {
1663
- console.warn(`[Jellyfin Offline] getDownloadedRecord error for ${id}:`, err);
1681
+ console.warn("[Jellyfin Offline] getDownloadedRecord error for %s:", id, err);
1664
1682
  return null;
1665
1683
  }
1666
1684
  }
@@ -2415,7 +2433,7 @@ var WebSocketModule = class {
2415
2433
  try {
2416
2434
  listener(...args);
2417
2435
  } catch (e) {
2418
- console.error(`[Jellyfin SDK] WebSocket listener error on '${event}':`, e);
2436
+ console.error("[Jellyfin SDK] WebSocket listener error on '%s':", event, e);
2419
2437
  }
2420
2438
  });
2421
2439
  }
@@ -2855,6 +2873,7 @@ var TrickplayModule = class {
2855
2873
  const { mediaSourceId, useQueryToken = true } = options;
2856
2874
  const url = new URL(`${serverUrl}/Videos/${itemId}/Trickplay/${width}/tiles.m3u8`);
2857
2875
  if (token && useQueryToken) {
2876
+ url.searchParams.append("ApiKey", token);
2858
2877
  url.searchParams.append("api_key", token);
2859
2878
  url.searchParams.append("X-Emby-Token", token);
2860
2879
  }
@@ -2873,6 +2892,7 @@ var TrickplayModule = class {
2873
2892
  const { mediaSourceId, useQueryToken = true } = options;
2874
2893
  const url = new URL(`${serverUrl}/Videos/${itemId}/Trickplay/${width}/${index}.jpg`);
2875
2894
  if (token && useQueryToken) {
2895
+ url.searchParams.append("ApiKey", token);
2876
2896
  url.searchParams.append("api_key", token);
2877
2897
  url.searchParams.append("X-Emby-Token", token);
2878
2898
  }
@@ -3063,6 +3083,7 @@ var ChaptersModule = class {
3063
3083
  } = options;
3064
3084
  const url = new URL(`${serverUrl}/Items/${itemId}/Images/Chapter/${chapterIndex}`);
3065
3085
  if (token && useQueryToken) {
3086
+ url.searchParams.append("ApiKey", token);
3066
3087
  url.searchParams.append("api_key", token);
3067
3088
  url.searchParams.append("X-Emby-Token", token);
3068
3089
  }
@@ -3747,7 +3768,7 @@ var JellyfinClient = class {
3747
3768
  this.cache = new MemoryCacheAdapter();
3748
3769
  this.clientInfo = {
3749
3770
  name: options.clientInfo?.name || "@francofantomius/jellyfin",
3750
- version: options.clientInfo?.version || "0.4.0",
3771
+ version: options.clientInfo?.version || "0.4.2",
3751
3772
  device: options.clientInfo?.device || (typeof window !== "undefined" ? "Web Browser" : "Node.js"),
3752
3773
  deviceId: options.clientInfo?.deviceId || generateDeviceId()
3753
3774
  };
@@ -3869,7 +3890,7 @@ var JellyfinClient = class {
3869
3890
  try {
3870
3891
  fn(...args);
3871
3892
  } catch (e) {
3872
- console.error(`[Jellyfin SDK] Event handler error on '${event}':`, e);
3893
+ console.error("[Jellyfin SDK] Event handler error on '%s':", event, e);
3873
3894
  }
3874
3895
  });
3875
3896
  }