tmdb-kit 1.1.0 → 1.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 +243 -79
- package/dist/cli.js +1068 -377
- package/dist/client.d.cts +13 -5
- package/dist/client.d.ts +13 -5
- package/dist/errors.d.cts +13 -1
- package/dist/errors.d.ts +13 -1
- package/dist/helpers/cache.d.cts +28 -0
- package/dist/helpers/cache.d.ts +28 -0
- package/dist/helpers/pagination.d.cts +35 -0
- package/dist/helpers/pagination.d.ts +35 -0
- package/dist/helpers/retry.d.cts +47 -0
- package/dist/helpers/retry.d.ts +47 -0
- package/dist/helpers/timeout.d.cts +20 -0
- package/dist/helpers/timeout.d.ts +20 -0
- package/dist/index.cjs +422 -54
- package/dist/index.cjs.map +18 -14
- package/dist/index.d.cts +7 -2
- package/dist/index.d.ts +7 -2
- package/dist/index.js +422 -54
- package/dist/index.js.map +18 -14
- package/dist/query.d.cts +14 -0
- package/dist/query.d.ts +14 -0
- package/dist/resources/configuration.d.cts +7 -7
- package/dist/resources/configuration.d.ts +7 -7
- package/dist/resources/movies.d.cts +3 -3
- package/dist/resources/movies.d.ts +3 -3
- package/dist/resources/tv.d.cts +9 -1
- package/dist/resources/tv.d.ts +9 -1
- package/dist/types.d.cts +100 -2
- package/dist/types.d.ts +100 -2
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -47,9 +47,11 @@ __export(exports_src, {
|
|
|
47
47
|
KNOWN_STILL_SIZES: () => KNOWN_STILL_SIZES,
|
|
48
48
|
TMDBClient: () => TMDBClient,
|
|
49
49
|
TMDBError: () => TMDBError,
|
|
50
|
+
TMDBHttpClient: () => TMDBHttpClient,
|
|
50
51
|
TMDBRateLimitError: () => TMDBRateLimitError,
|
|
51
52
|
TMDBRequestError: () => TMDBRequestError,
|
|
52
53
|
TMDBResponseError: () => TMDBResponseError,
|
|
54
|
+
TMDBTimeoutError: () => TMDBTimeoutError,
|
|
53
55
|
buildImageUrl: () => buildImageUrl,
|
|
54
56
|
createTMDB: () => createTMDB,
|
|
55
57
|
isKnownBackdropSize: () => isKnownBackdropSize,
|
|
@@ -63,7 +65,13 @@ __export(exports_src, {
|
|
|
63
65
|
isPerson: () => isPerson,
|
|
64
66
|
isPersonSearchResult: () => isPersonSearchResult,
|
|
65
67
|
isTV: () => isTV,
|
|
66
|
-
isTVSearchResult: () => isTVSearchResult
|
|
68
|
+
isTVSearchResult: () => isTVSearchResult,
|
|
69
|
+
paginate: () => paginate,
|
|
70
|
+
paginateItems: () => paginateItems,
|
|
71
|
+
retry: () => retry,
|
|
72
|
+
withMemoryCache: () => withMemoryCache,
|
|
73
|
+
withRetry: () => withRetry,
|
|
74
|
+
withTimeout: () => withTimeout
|
|
67
75
|
});
|
|
68
76
|
module.exports = __toCommonJS(exports_src);
|
|
69
77
|
|
|
@@ -82,6 +90,15 @@ class TMDBRequestError extends TMDBError {
|
|
|
82
90
|
}
|
|
83
91
|
}
|
|
84
92
|
|
|
93
|
+
class TMDBTimeoutError extends TMDBError {
|
|
94
|
+
timeoutMs;
|
|
95
|
+
constructor(timeoutMs, message = `TMDB request timed out after ${timeoutMs}ms`) {
|
|
96
|
+
super(message);
|
|
97
|
+
this.name = "TMDBTimeoutError";
|
|
98
|
+
this.timeoutMs = timeoutMs;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
85
102
|
class TMDBResponseError extends TMDBError {
|
|
86
103
|
body;
|
|
87
104
|
headers;
|
|
@@ -204,6 +221,19 @@ function toId(value, name) {
|
|
|
204
221
|
}
|
|
205
222
|
return String(value);
|
|
206
223
|
}
|
|
224
|
+
function toSeasonNumber(value) {
|
|
225
|
+
if (!Number.isInteger(value) || value < 0) {
|
|
226
|
+
throw new TMDBRequestError("seasonNumber must be a non-negative integer");
|
|
227
|
+
}
|
|
228
|
+
return String(value);
|
|
229
|
+
}
|
|
230
|
+
function toGroupId(value) {
|
|
231
|
+
const groupId = value.trim();
|
|
232
|
+
if (!/^[A-Za-z0-9_-]+$/.test(groupId)) {
|
|
233
|
+
throw new TMDBRequestError("groupId must be a non-empty identifier");
|
|
234
|
+
}
|
|
235
|
+
return groupId;
|
|
236
|
+
}
|
|
207
237
|
function toSearchQuery(value) {
|
|
208
238
|
const query = value.trim();
|
|
209
239
|
if (query.length === 0) {
|
|
@@ -337,23 +367,25 @@ class ConfigurationResource {
|
|
|
337
367
|
constructor(transport) {
|
|
338
368
|
this.#transport = transport;
|
|
339
369
|
}
|
|
340
|
-
details() {
|
|
341
|
-
return this.#transport.get("/configuration");
|
|
370
|
+
details(options = {}) {
|
|
371
|
+
return this.#transport.get("/configuration", { signal: options.signal });
|
|
342
372
|
}
|
|
343
|
-
countries() {
|
|
344
|
-
return this.#transport.get("/configuration/countries");
|
|
373
|
+
countries(options = {}) {
|
|
374
|
+
return this.#transport.get("/configuration/countries", { signal: options.signal });
|
|
345
375
|
}
|
|
346
|
-
jobs() {
|
|
347
|
-
return this.#transport.get("/configuration/jobs");
|
|
376
|
+
jobs(options = {}) {
|
|
377
|
+
return this.#transport.get("/configuration/jobs", { signal: options.signal });
|
|
348
378
|
}
|
|
349
|
-
languages() {
|
|
350
|
-
return this.#transport.get("/configuration/languages");
|
|
379
|
+
languages(options = {}) {
|
|
380
|
+
return this.#transport.get("/configuration/languages", { signal: options.signal });
|
|
351
381
|
}
|
|
352
|
-
primaryTranslations() {
|
|
353
|
-
return this.#transport.get("/configuration/primary_translations"
|
|
382
|
+
primaryTranslations(options = {}) {
|
|
383
|
+
return this.#transport.get("/configuration/primary_translations", {
|
|
384
|
+
signal: options.signal
|
|
385
|
+
});
|
|
354
386
|
}
|
|
355
|
-
timezones() {
|
|
356
|
-
return this.#transport.get("/configuration/timezones");
|
|
387
|
+
timezones(options = {}) {
|
|
388
|
+
return this.#transport.get("/configuration/timezones", { signal: options.signal });
|
|
357
389
|
}
|
|
358
390
|
}
|
|
359
391
|
|
|
@@ -367,14 +399,16 @@ class GenresResource {
|
|
|
367
399
|
return this.#transport.get("/genre/movie/list", {
|
|
368
400
|
query: withLanguage(this.#transport.defaults, {
|
|
369
401
|
language: options.language
|
|
370
|
-
})
|
|
402
|
+
}),
|
|
403
|
+
signal: options.signal
|
|
371
404
|
});
|
|
372
405
|
}
|
|
373
406
|
tv(options = {}) {
|
|
374
407
|
return this.#transport.get("/genre/tv/list", {
|
|
375
408
|
query: withLanguage(this.#transport.defaults, {
|
|
376
409
|
language: options.language
|
|
377
|
-
})
|
|
410
|
+
}),
|
|
411
|
+
signal: options.signal
|
|
378
412
|
});
|
|
379
413
|
}
|
|
380
414
|
}
|
|
@@ -403,22 +437,26 @@ class MoviesResource {
|
|
|
403
437
|
}
|
|
404
438
|
popular(options = {}) {
|
|
405
439
|
return this.#transport.get("/movie/popular", {
|
|
406
|
-
query: movieListQuery(this.#transport, options)
|
|
440
|
+
query: movieListQuery(this.#transport, options),
|
|
441
|
+
signal: options.signal
|
|
407
442
|
});
|
|
408
443
|
}
|
|
409
444
|
topRated(options = {}) {
|
|
410
445
|
return this.#transport.get("/movie/top_rated", {
|
|
411
|
-
query: movieListQuery(this.#transport, options)
|
|
446
|
+
query: movieListQuery(this.#transport, options),
|
|
447
|
+
signal: options.signal
|
|
412
448
|
});
|
|
413
449
|
}
|
|
414
450
|
nowPlaying(options = {}) {
|
|
415
451
|
return this.#transport.get("/movie/now_playing", {
|
|
416
|
-
query: movieListQuery(this.#transport, options)
|
|
452
|
+
query: movieListQuery(this.#transport, options),
|
|
453
|
+
signal: options.signal
|
|
417
454
|
});
|
|
418
455
|
}
|
|
419
456
|
upcoming(options = {}) {
|
|
420
457
|
return this.#transport.get("/movie/upcoming", {
|
|
421
|
-
query: movieListQuery(this.#transport, options)
|
|
458
|
+
query: movieListQuery(this.#transport, options),
|
|
459
|
+
signal: options.signal
|
|
422
460
|
});
|
|
423
461
|
}
|
|
424
462
|
details(movieId, options = {}) {
|
|
@@ -426,14 +464,16 @@ class MoviesResource {
|
|
|
426
464
|
query: withLanguage(this.#transport.defaults, {
|
|
427
465
|
append_to_response: toCommaList(options.appendToResponse),
|
|
428
466
|
language: options.language
|
|
429
|
-
})
|
|
467
|
+
}),
|
|
468
|
+
signal: options.signal
|
|
430
469
|
});
|
|
431
470
|
}
|
|
432
471
|
credits(movieId, options = {}) {
|
|
433
472
|
return this.#transport.get(`/movie/${toId(movieId, "movieId")}/credits`, {
|
|
434
473
|
query: withLanguage(this.#transport.defaults, {
|
|
435
474
|
language: options.language
|
|
436
|
-
})
|
|
475
|
+
}),
|
|
476
|
+
signal: options.signal
|
|
437
477
|
});
|
|
438
478
|
}
|
|
439
479
|
images(movieId, options = {}) {
|
|
@@ -441,24 +481,28 @@ class MoviesResource {
|
|
|
441
481
|
query: withLanguage(this.#transport.defaults, {
|
|
442
482
|
include_image_language: toCommaList(options.includeImageLanguage),
|
|
443
483
|
language: options.language
|
|
444
|
-
})
|
|
484
|
+
}),
|
|
485
|
+
signal: options.signal
|
|
445
486
|
});
|
|
446
487
|
}
|
|
447
488
|
recommendations(movieId, options = {}) {
|
|
448
489
|
return this.#transport.get(`/movie/${toId(movieId, "movieId")}/recommendations`, {
|
|
449
|
-
query: movieListQuery(this.#transport, options)
|
|
490
|
+
query: movieListQuery(this.#transport, options),
|
|
491
|
+
signal: options.signal
|
|
450
492
|
});
|
|
451
493
|
}
|
|
452
494
|
similar(movieId, options = {}) {
|
|
453
495
|
return this.#transport.get(`/movie/${toId(movieId, "movieId")}/similar`, {
|
|
454
|
-
query: movieListQuery(this.#transport, options)
|
|
496
|
+
query: movieListQuery(this.#transport, options),
|
|
497
|
+
signal: options.signal
|
|
455
498
|
});
|
|
456
499
|
}
|
|
457
500
|
videos(movieId, options = {}) {
|
|
458
501
|
return this.#transport.get(`/movie/${toId(movieId, "movieId")}/videos`, {
|
|
459
502
|
query: withLanguage(this.#transport.defaults, {
|
|
460
503
|
language: options.language
|
|
461
|
-
})
|
|
504
|
+
}),
|
|
505
|
+
signal: options.signal
|
|
462
506
|
});
|
|
463
507
|
}
|
|
464
508
|
}
|
|
@@ -478,21 +522,24 @@ class PeopleResource {
|
|
|
478
522
|
}
|
|
479
523
|
popular(options = {}) {
|
|
480
524
|
return this.#transport.get("/person/popular", {
|
|
481
|
-
query: peopleListQuery(this.#transport, options)
|
|
525
|
+
query: peopleListQuery(this.#transport, options),
|
|
526
|
+
signal: options.signal
|
|
482
527
|
});
|
|
483
528
|
}
|
|
484
529
|
details(personId, options = {}) {
|
|
485
530
|
return this.#transport.get(`/person/${toId(personId, "personId")}`, {
|
|
486
531
|
query: withLanguage(this.#transport.defaults, {
|
|
487
532
|
language: options.language
|
|
488
|
-
})
|
|
533
|
+
}),
|
|
534
|
+
signal: options.signal
|
|
489
535
|
});
|
|
490
536
|
}
|
|
491
537
|
combinedCredits(personId, options = {}) {
|
|
492
538
|
return this.#transport.get(`/person/${toId(personId, "personId")}/combined_credits`, {
|
|
493
539
|
query: withLanguage(this.#transport.defaults, {
|
|
494
540
|
language: options.language
|
|
495
|
-
})
|
|
541
|
+
}),
|
|
542
|
+
signal: options.signal
|
|
496
543
|
});
|
|
497
544
|
}
|
|
498
545
|
}
|
|
@@ -511,22 +558,26 @@ class SearchResource {
|
|
|
511
558
|
}
|
|
512
559
|
movies(query, options = {}) {
|
|
513
560
|
return this.#transport.get("/search/movie", {
|
|
514
|
-
query: movieSearchQuery(this.#transport, query, options)
|
|
561
|
+
query: movieSearchQuery(this.#transport, query, options),
|
|
562
|
+
signal: options.signal
|
|
515
563
|
});
|
|
516
564
|
}
|
|
517
565
|
tv(query, options = {}) {
|
|
518
566
|
return this.#transport.get("/search/tv", {
|
|
519
|
-
query: tvSearchQuery(this.#transport, query, options)
|
|
567
|
+
query: tvSearchQuery(this.#transport, query, options),
|
|
568
|
+
signal: options.signal
|
|
520
569
|
});
|
|
521
570
|
}
|
|
522
571
|
people(query, options = {}) {
|
|
523
572
|
return this.#transport.get("/search/person", {
|
|
524
|
-
query: commonSearchQuery(this.#transport, query, options)
|
|
573
|
+
query: commonSearchQuery(this.#transport, query, options),
|
|
574
|
+
signal: options.signal
|
|
525
575
|
});
|
|
526
576
|
}
|
|
527
577
|
async multi(query, options = {}) {
|
|
528
578
|
const response = await this.#transport.get("/search/multi", {
|
|
529
|
-
query: commonSearchQuery(this.#transport, query, options)
|
|
579
|
+
query: commonSearchQuery(this.#transport, query, options),
|
|
580
|
+
signal: options.signal
|
|
530
581
|
});
|
|
531
582
|
const excluded = options.exclude;
|
|
532
583
|
if (excluded === undefined || excluded.length === 0) {
|
|
@@ -580,7 +631,8 @@ class TrendingResource {
|
|
|
580
631
|
query: withLanguage(this.#transport.defaults, {
|
|
581
632
|
language: options.language,
|
|
582
633
|
page: options.page
|
|
583
|
-
})
|
|
634
|
+
}),
|
|
635
|
+
signal: options.signal
|
|
584
636
|
});
|
|
585
637
|
}
|
|
586
638
|
movies(timeWindow = "day", options = {}) {
|
|
@@ -588,7 +640,8 @@ class TrendingResource {
|
|
|
588
640
|
query: withLanguage(this.#transport.defaults, {
|
|
589
641
|
language: options.language,
|
|
590
642
|
page: options.page
|
|
591
|
-
})
|
|
643
|
+
}),
|
|
644
|
+
signal: options.signal
|
|
592
645
|
});
|
|
593
646
|
}
|
|
594
647
|
tv(timeWindow = "day", options = {}) {
|
|
@@ -596,7 +649,8 @@ class TrendingResource {
|
|
|
596
649
|
query: withLanguage(this.#transport.defaults, {
|
|
597
650
|
language: options.language,
|
|
598
651
|
page: options.page
|
|
599
|
-
})
|
|
652
|
+
}),
|
|
653
|
+
signal: options.signal
|
|
600
654
|
});
|
|
601
655
|
}
|
|
602
656
|
people(timeWindow = "day", options = {}) {
|
|
@@ -604,7 +658,8 @@ class TrendingResource {
|
|
|
604
658
|
query: withLanguage(this.#transport.defaults, {
|
|
605
659
|
language: options.language,
|
|
606
660
|
page: options.page
|
|
607
|
-
})
|
|
661
|
+
}),
|
|
662
|
+
signal: options.signal
|
|
608
663
|
});
|
|
609
664
|
}
|
|
610
665
|
}
|
|
@@ -617,22 +672,26 @@ class TVResource {
|
|
|
617
672
|
}
|
|
618
673
|
popular(options = {}) {
|
|
619
674
|
return this.#transport.get("/tv/popular", {
|
|
620
|
-
query: tvListQuery(this.#transport, options)
|
|
675
|
+
query: tvListQuery(this.#transport, options),
|
|
676
|
+
signal: options.signal
|
|
621
677
|
});
|
|
622
678
|
}
|
|
623
679
|
topRated(options = {}) {
|
|
624
680
|
return this.#transport.get("/tv/top_rated", {
|
|
625
|
-
query: tvListQuery(this.#transport, options)
|
|
681
|
+
query: tvListQuery(this.#transport, options),
|
|
682
|
+
signal: options.signal
|
|
626
683
|
});
|
|
627
684
|
}
|
|
628
685
|
airingToday(options = {}) {
|
|
629
686
|
return this.#transport.get("/tv/airing_today", {
|
|
630
|
-
query: tvListQuery(this.#transport, options)
|
|
687
|
+
query: tvListQuery(this.#transport, options),
|
|
688
|
+
signal: options.signal
|
|
631
689
|
});
|
|
632
690
|
}
|
|
633
691
|
onTheAir(options = {}) {
|
|
634
692
|
return this.#transport.get("/tv/on_the_air", {
|
|
635
|
-
query: tvListQuery(this.#transport, options)
|
|
693
|
+
query: tvListQuery(this.#transport, options),
|
|
694
|
+
signal: options.signal
|
|
636
695
|
});
|
|
637
696
|
}
|
|
638
697
|
details(seriesId, options = {}) {
|
|
@@ -640,14 +699,16 @@ class TVResource {
|
|
|
640
699
|
query: withLanguage(this.#transport.defaults, {
|
|
641
700
|
append_to_response: toCommaList(options.appendToResponse),
|
|
642
701
|
language: options.language
|
|
643
|
-
})
|
|
702
|
+
}),
|
|
703
|
+
signal: options.signal
|
|
644
704
|
});
|
|
645
705
|
}
|
|
646
706
|
credits(seriesId, options = {}) {
|
|
647
707
|
return this.#transport.get(`/tv/${toId(seriesId, "seriesId")}/credits`, {
|
|
648
708
|
query: withLanguage(this.#transport.defaults, {
|
|
649
709
|
language: options.language
|
|
650
|
-
})
|
|
710
|
+
}),
|
|
711
|
+
signal: options.signal
|
|
651
712
|
});
|
|
652
713
|
}
|
|
653
714
|
images(seriesId, options = {}) {
|
|
@@ -655,32 +716,103 @@ class TVResource {
|
|
|
655
716
|
query: withLanguage(this.#transport.defaults, {
|
|
656
717
|
include_image_language: toCommaList(options.includeImageLanguage),
|
|
657
718
|
language: options.language
|
|
658
|
-
})
|
|
719
|
+
}),
|
|
720
|
+
signal: options.signal
|
|
659
721
|
});
|
|
660
722
|
}
|
|
661
723
|
recommendations(seriesId, options = {}) {
|
|
662
724
|
return this.#transport.get(`/tv/${toId(seriesId, "seriesId")}/recommendations`, {
|
|
663
|
-
query: tvListQuery(this.#transport, options)
|
|
725
|
+
query: tvListQuery(this.#transport, options),
|
|
726
|
+
signal: options.signal
|
|
664
727
|
});
|
|
665
728
|
}
|
|
666
729
|
similar(seriesId, options = {}) {
|
|
667
730
|
return this.#transport.get(`/tv/${toId(seriesId, "seriesId")}/similar`, {
|
|
668
|
-
query: tvListQuery(this.#transport, options)
|
|
731
|
+
query: tvListQuery(this.#transport, options),
|
|
732
|
+
signal: options.signal
|
|
669
733
|
});
|
|
670
734
|
}
|
|
671
735
|
videos(seriesId, options = {}) {
|
|
672
736
|
return this.#transport.get(`/tv/${toId(seriesId, "seriesId")}/videos`, {
|
|
673
737
|
query: withLanguage(this.#transport.defaults, {
|
|
674
738
|
language: options.language
|
|
675
|
-
})
|
|
739
|
+
}),
|
|
740
|
+
signal: options.signal
|
|
676
741
|
});
|
|
677
742
|
}
|
|
678
743
|
seasonDetails(seriesId, seasonNumber, options = {}) {
|
|
679
|
-
return this.#transport.get(`/tv/${toId(seriesId, "seriesId")}/season/${
|
|
744
|
+
return this.#transport.get(`/tv/${toId(seriesId, "seriesId")}/season/${toSeasonNumber(seasonNumber)}`, {
|
|
680
745
|
query: withLanguage(this.#transport.defaults, {
|
|
681
746
|
append_to_response: toCommaList(options.appendToResponse),
|
|
682
747
|
language: options.language
|
|
683
|
-
})
|
|
748
|
+
}),
|
|
749
|
+
signal: options.signal
|
|
750
|
+
});
|
|
751
|
+
}
|
|
752
|
+
seasonCredits(seriesId, seasonNumber, options = {}) {
|
|
753
|
+
return this.#transport.get(`/tv/${toId(seriesId, "seriesId")}/season/${toSeasonNumber(seasonNumber)}/credits`, {
|
|
754
|
+
query: withLanguage(this.#transport.defaults, {
|
|
755
|
+
language: options.language
|
|
756
|
+
}),
|
|
757
|
+
signal: options.signal
|
|
758
|
+
});
|
|
759
|
+
}
|
|
760
|
+
seasonAggregateCredits(seriesId, seasonNumber, options = {}) {
|
|
761
|
+
return this.#transport.get(`/tv/${toId(seriesId, "seriesId")}/season/${toSeasonNumber(seasonNumber)}/aggregate_credits`, {
|
|
762
|
+
query: withLanguage(this.#transport.defaults, {
|
|
763
|
+
language: options.language
|
|
764
|
+
}),
|
|
765
|
+
signal: options.signal
|
|
766
|
+
});
|
|
767
|
+
}
|
|
768
|
+
seasonImages(seriesId, seasonNumber, options = {}) {
|
|
769
|
+
return this.#transport.get(`/tv/${toId(seriesId, "seriesId")}/season/${toSeasonNumber(seasonNumber)}/images`, {
|
|
770
|
+
query: withLanguage(this.#transport.defaults, {
|
|
771
|
+
include_image_language: toCommaList(options.includeImageLanguage),
|
|
772
|
+
language: options.language
|
|
773
|
+
}),
|
|
774
|
+
signal: options.signal
|
|
775
|
+
});
|
|
776
|
+
}
|
|
777
|
+
seasonVideos(seriesId, seasonNumber, options = {}) {
|
|
778
|
+
return this.#transport.get(`/tv/${toId(seriesId, "seriesId")}/season/${toSeasonNumber(seasonNumber)}/videos`, {
|
|
779
|
+
query: withLanguage(this.#transport.defaults, {
|
|
780
|
+
language: options.language
|
|
781
|
+
}),
|
|
782
|
+
signal: options.signal
|
|
783
|
+
});
|
|
784
|
+
}
|
|
785
|
+
episodeDetails(seriesId, seasonNumber, episodeNumber, options = {}) {
|
|
786
|
+
return this.#transport.get(`/tv/${toId(seriesId, "seriesId")}/season/${toSeasonNumber(seasonNumber)}/episode/${toId(episodeNumber, "episodeNumber")}`, {
|
|
787
|
+
query: withLanguage(this.#transport.defaults, {
|
|
788
|
+
append_to_response: toCommaList(options.appendToResponse),
|
|
789
|
+
language: options.language
|
|
790
|
+
}),
|
|
791
|
+
signal: options.signal
|
|
792
|
+
});
|
|
793
|
+
}
|
|
794
|
+
aggregateCredits(seriesId, options = {}) {
|
|
795
|
+
return this.#transport.get(`/tv/${toId(seriesId, "seriesId")}/aggregate_credits`, {
|
|
796
|
+
query: withLanguage(this.#transport.defaults, {
|
|
797
|
+
language: options.language
|
|
798
|
+
}),
|
|
799
|
+
signal: options.signal
|
|
800
|
+
});
|
|
801
|
+
}
|
|
802
|
+
episodeGroups(seriesId, options = {}) {
|
|
803
|
+
return this.#transport.get(`/tv/${toId(seriesId, "seriesId")}/episode_groups`, {
|
|
804
|
+
query: withLanguage(this.#transport.defaults, {
|
|
805
|
+
language: options.language
|
|
806
|
+
}),
|
|
807
|
+
signal: options.signal
|
|
808
|
+
});
|
|
809
|
+
}
|
|
810
|
+
episodeGroup(groupId, options = {}) {
|
|
811
|
+
return this.#transport.get(`/tv/episode_group/${toGroupId(groupId)}`, {
|
|
812
|
+
query: withLanguage(this.#transport.defaults, {
|
|
813
|
+
language: options.language
|
|
814
|
+
}),
|
|
815
|
+
signal: options.signal
|
|
684
816
|
});
|
|
685
817
|
}
|
|
686
818
|
}
|
|
@@ -703,13 +835,17 @@ class TMDBClient {
|
|
|
703
835
|
tv;
|
|
704
836
|
#transport;
|
|
705
837
|
constructor(options) {
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
838
|
+
let imageTransform = options.images?.transform;
|
|
839
|
+
if (options.transport === undefined) {
|
|
840
|
+
const builtInClient = new TMDBHttpClient(options);
|
|
841
|
+
this.#transport = builtInClient;
|
|
842
|
+
imageTransform = builtInClient.imageTransform;
|
|
843
|
+
} else {
|
|
844
|
+
this.#transport = options.transport;
|
|
845
|
+
}
|
|
710
846
|
this.configuration = new ConfigurationResource(this.#transport);
|
|
711
847
|
this.genres = new GenresResource(this.#transport);
|
|
712
|
-
this.images = new ImagesHelper(this.#transport,
|
|
848
|
+
this.images = new ImagesHelper(this.#transport, imageTransform);
|
|
713
849
|
this.movies = new MoviesResource(this.#transport);
|
|
714
850
|
this.people = new PeopleResource(this.#transport);
|
|
715
851
|
this.search = new SearchResource(this.#transport);
|
|
@@ -723,6 +859,238 @@ class TMDBClient {
|
|
|
723
859
|
function createTMDB(options) {
|
|
724
860
|
return new TMDBClient(options);
|
|
725
861
|
}
|
|
862
|
+
// src/helpers/cache.ts
|
|
863
|
+
function withMemoryCache(transport, options = {}) {
|
|
864
|
+
const ttlMs = options.ttlMs ?? 5 * 60000;
|
|
865
|
+
const maxEntries = options.maxEntries ?? 100;
|
|
866
|
+
if (!Number.isFinite(ttlMs) || ttlMs <= 0) {
|
|
867
|
+
throw new RangeError("ttlMs must be a positive number");
|
|
868
|
+
}
|
|
869
|
+
if (!Number.isInteger(maxEntries) || maxEntries < 1) {
|
|
870
|
+
throw new RangeError("maxEntries must be a positive integer");
|
|
871
|
+
}
|
|
872
|
+
const entries = new Map;
|
|
873
|
+
return {
|
|
874
|
+
...transport,
|
|
875
|
+
async get(path, requestOptions = {}) {
|
|
876
|
+
const key = cacheKey(path, requestOptions);
|
|
877
|
+
const cached = entries.get(key);
|
|
878
|
+
if (cached !== undefined) {
|
|
879
|
+
if (cached.expiresAt > Date.now()) {
|
|
880
|
+
entries.delete(key);
|
|
881
|
+
entries.set(key, cached);
|
|
882
|
+
return cached.value;
|
|
883
|
+
}
|
|
884
|
+
entries.delete(key);
|
|
885
|
+
}
|
|
886
|
+
const value = await transport.get(path, requestOptions);
|
|
887
|
+
entries.set(key, { expiresAt: Date.now() + ttlMs, value });
|
|
888
|
+
evictOverflow(entries, maxEntries);
|
|
889
|
+
return value;
|
|
890
|
+
},
|
|
891
|
+
clear() {
|
|
892
|
+
entries.clear();
|
|
893
|
+
}
|
|
894
|
+
};
|
|
895
|
+
}
|
|
896
|
+
function cacheKey(path, options) {
|
|
897
|
+
return `${path}?${serializeQuery(options.query)}|${serializeHeaders(options.headers)}`;
|
|
898
|
+
}
|
|
899
|
+
function serializeQuery(query) {
|
|
900
|
+
if (query === undefined) {
|
|
901
|
+
return "";
|
|
902
|
+
}
|
|
903
|
+
return Object.entries(query).filter(([, value]) => value !== undefined && value !== null).sort(([left], [right]) => left.localeCompare(right)).map(([key, value]) => `${key}=${Array.isArray(value) ? value.map(String).join(",") : String(value)}`).join("&");
|
|
904
|
+
}
|
|
905
|
+
function serializeHeaders(headers) {
|
|
906
|
+
if (headers === undefined) {
|
|
907
|
+
return "";
|
|
908
|
+
}
|
|
909
|
+
return [...new Headers(headers)].sort(([left], [right]) => left.localeCompare(right)).map(([key, value]) => `${key}:${value}`).join("|");
|
|
910
|
+
}
|
|
911
|
+
function evictOverflow(entries, maxEntries) {
|
|
912
|
+
while (entries.size > maxEntries) {
|
|
913
|
+
entries.delete(entries.keys().next().value);
|
|
914
|
+
}
|
|
915
|
+
}
|
|
916
|
+
// src/helpers/pagination.ts
|
|
917
|
+
async function* paginate(fetchPage, options = {}) {
|
|
918
|
+
const startPage = options.startPage ?? 1;
|
|
919
|
+
const endPage = options.endPage ?? 500;
|
|
920
|
+
assertPositiveInteger(startPage, "startPage");
|
|
921
|
+
assertPositiveInteger(endPage, "endPage");
|
|
922
|
+
for (let page = startPage;page <= endPage; page += 1) {
|
|
923
|
+
options.signal?.throwIfAborted();
|
|
924
|
+
const response = await fetchPage(page);
|
|
925
|
+
yield response;
|
|
926
|
+
if (response.results.length === 0 || page >= response.total_pages) {
|
|
927
|
+
return;
|
|
928
|
+
}
|
|
929
|
+
}
|
|
930
|
+
}
|
|
931
|
+
async function* paginateItems(fetchPage, options = {}) {
|
|
932
|
+
for await (const page of paginate(fetchPage, options)) {
|
|
933
|
+
yield* page.results;
|
|
934
|
+
}
|
|
935
|
+
}
|
|
936
|
+
function assertPositiveInteger(value, name) {
|
|
937
|
+
if (!Number.isInteger(value) || value < 1) {
|
|
938
|
+
throw new RangeError(`${name} must be a positive integer`);
|
|
939
|
+
}
|
|
940
|
+
}
|
|
941
|
+
// src/helpers/retry.ts
|
|
942
|
+
var MAX_RETRY_AFTER_MS = 60000;
|
|
943
|
+
async function retry(task, options = {}) {
|
|
944
|
+
const retries = options.retries ?? 2;
|
|
945
|
+
if (!Number.isInteger(retries) || retries < 0) {
|
|
946
|
+
throw new RangeError("retries must be a non-negative integer");
|
|
947
|
+
}
|
|
948
|
+
const retryOn = options.retryOn ?? shouldRetry;
|
|
949
|
+
const signal = options.signal;
|
|
950
|
+
if (signal?.aborted) {
|
|
951
|
+
throw signal.reason;
|
|
952
|
+
}
|
|
953
|
+
for (let attempt = 0;; attempt += 1) {
|
|
954
|
+
try {
|
|
955
|
+
return await task();
|
|
956
|
+
} catch (error) {
|
|
957
|
+
if (signal?.aborted) {
|
|
958
|
+
throw signal.reason;
|
|
959
|
+
}
|
|
960
|
+
if (attempt >= retries || !retryOn(error, attempt)) {
|
|
961
|
+
throw error;
|
|
962
|
+
}
|
|
963
|
+
const delayMs = retryDelay(error, attempt, options);
|
|
964
|
+
options.onRetry?.({ attempt, delayMs, error });
|
|
965
|
+
await sleep(delayMs, signal);
|
|
966
|
+
}
|
|
967
|
+
}
|
|
968
|
+
}
|
|
969
|
+
function withRetry(transport, options = {}) {
|
|
970
|
+
return {
|
|
971
|
+
...transport,
|
|
972
|
+
get(path, requestOptions) {
|
|
973
|
+
const { cleanup, signal } = combineSignals(options.signal, requestOptions?.signal);
|
|
974
|
+
const effectiveOptions = signal === undefined ? requestOptions : { ...requestOptions, signal };
|
|
975
|
+
return retry(() => transport.get(path, effectiveOptions), {
|
|
976
|
+
...options,
|
|
977
|
+
signal
|
|
978
|
+
}).finally(cleanup);
|
|
979
|
+
}
|
|
980
|
+
};
|
|
981
|
+
}
|
|
982
|
+
function shouldRetry(error) {
|
|
983
|
+
if (error instanceof TMDBRateLimitError) {
|
|
984
|
+
return true;
|
|
985
|
+
}
|
|
986
|
+
if (error instanceof TMDBResponseError) {
|
|
987
|
+
return error.isServerError || error.status === 408;
|
|
988
|
+
}
|
|
989
|
+
if (error instanceof TMDBTimeoutError) {
|
|
990
|
+
return false;
|
|
991
|
+
}
|
|
992
|
+
if (error instanceof TMDBRequestError) {
|
|
993
|
+
if (error.cause === undefined || error.cause instanceof TMDBTimeoutError) {
|
|
994
|
+
return false;
|
|
995
|
+
}
|
|
996
|
+
return !isAbortError(error.cause);
|
|
997
|
+
}
|
|
998
|
+
return false;
|
|
999
|
+
}
|
|
1000
|
+
function retryDelay(error, attempt, options) {
|
|
1001
|
+
const retryAfter = retryAfterMs(error);
|
|
1002
|
+
if (retryAfter !== undefined) {
|
|
1003
|
+
return Math.min(Math.max(retryAfter, 0), MAX_RETRY_AFTER_MS);
|
|
1004
|
+
}
|
|
1005
|
+
if (error instanceof TMDBRateLimitError) {
|
|
1006
|
+
return Math.min(Math.max(error.retryAfter * 1000, 0), MAX_RETRY_AFTER_MS);
|
|
1007
|
+
}
|
|
1008
|
+
const baseDelayMs = options.baseDelayMs ?? 250;
|
|
1009
|
+
const maxDelayMs = options.maxDelayMs ?? 1e4;
|
|
1010
|
+
const factor = options.factor ?? 2;
|
|
1011
|
+
const delay = Math.min(maxDelayMs, baseDelayMs * factor ** attempt);
|
|
1012
|
+
return options.jitter === false ? delay : Math.random() * delay;
|
|
1013
|
+
}
|
|
1014
|
+
function retryAfterMs(error) {
|
|
1015
|
+
if (!(error instanceof TMDBResponseError)) {
|
|
1016
|
+
return;
|
|
1017
|
+
}
|
|
1018
|
+
const header = error.headers.get("retry-after");
|
|
1019
|
+
if (header === null || header.trim() === "") {
|
|
1020
|
+
return;
|
|
1021
|
+
}
|
|
1022
|
+
return parseRetryAfter(header) * 1000;
|
|
1023
|
+
}
|
|
1024
|
+
function combineSignals(first, second) {
|
|
1025
|
+
if (first === undefined || second === undefined || first === second) {
|
|
1026
|
+
return { cleanup: noop, signal: first ?? second };
|
|
1027
|
+
}
|
|
1028
|
+
const controller = new AbortController;
|
|
1029
|
+
const onAbort = () => controller.abort((first.aborted ? first : second).reason);
|
|
1030
|
+
first.addEventListener("abort", onAbort, { once: true });
|
|
1031
|
+
second.addEventListener("abort", onAbort, { once: true });
|
|
1032
|
+
if (first.aborted || second.aborted) {
|
|
1033
|
+
onAbort();
|
|
1034
|
+
}
|
|
1035
|
+
return {
|
|
1036
|
+
cleanup() {
|
|
1037
|
+
first.removeEventListener("abort", onAbort);
|
|
1038
|
+
second.removeEventListener("abort", onAbort);
|
|
1039
|
+
},
|
|
1040
|
+
signal: controller.signal
|
|
1041
|
+
};
|
|
1042
|
+
}
|
|
1043
|
+
function noop() {}
|
|
1044
|
+
function isAbortError(error) {
|
|
1045
|
+
return typeof error === "object" && error !== null && "name" in error && error.name === "AbortError";
|
|
1046
|
+
}
|
|
1047
|
+
function sleep(ms, signal) {
|
|
1048
|
+
return new Promise((resolve, reject) => {
|
|
1049
|
+
const onAbort = () => {
|
|
1050
|
+
clearTimeout(timer);
|
|
1051
|
+
signal?.removeEventListener("abort", onAbort);
|
|
1052
|
+
reject(signal.reason);
|
|
1053
|
+
};
|
|
1054
|
+
const timer = setTimeout(() => {
|
|
1055
|
+
signal?.removeEventListener("abort", onAbort);
|
|
1056
|
+
resolve();
|
|
1057
|
+
}, ms);
|
|
1058
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
1059
|
+
if (signal?.aborted) {
|
|
1060
|
+
onAbort();
|
|
1061
|
+
}
|
|
1062
|
+
});
|
|
1063
|
+
}
|
|
1064
|
+
// src/helpers/timeout.ts
|
|
1065
|
+
async function withTimeout(timeoutMs, task, options = {}) {
|
|
1066
|
+
if (!Number.isFinite(timeoutMs) || timeoutMs <= 0) {
|
|
1067
|
+
throw new RangeError("timeoutMs must be a positive number");
|
|
1068
|
+
}
|
|
1069
|
+
const parent = options.signal;
|
|
1070
|
+
const controller = new AbortController;
|
|
1071
|
+
const timeoutError = new TMDBTimeoutError(timeoutMs, options.message);
|
|
1072
|
+
const onAbort = () => controller.abort(parent.reason);
|
|
1073
|
+
parent?.addEventListener("abort", onAbort, { once: true });
|
|
1074
|
+
if (parent?.aborted) {
|
|
1075
|
+
parent.removeEventListener("abort", onAbort);
|
|
1076
|
+
throw parent.reason;
|
|
1077
|
+
}
|
|
1078
|
+
const timer = setTimeout(() => controller.abort(timeoutError), timeoutMs);
|
|
1079
|
+
try {
|
|
1080
|
+
return await task(controller.signal);
|
|
1081
|
+
} catch (error) {
|
|
1082
|
+
if (controller.signal.reason === timeoutError) {
|
|
1083
|
+
throw timeoutError;
|
|
1084
|
+
}
|
|
1085
|
+
if (parent?.aborted) {
|
|
1086
|
+
throw parent.reason;
|
|
1087
|
+
}
|
|
1088
|
+
throw error;
|
|
1089
|
+
} finally {
|
|
1090
|
+
clearTimeout(timer);
|
|
1091
|
+
parent?.removeEventListener("abort", onAbort);
|
|
1092
|
+
}
|
|
1093
|
+
}
|
|
726
1094
|
// src/search-guards.ts
|
|
727
1095
|
function isMovieSearchResult(result) {
|
|
728
1096
|
return isObjectWithMediaType(result, "movie");
|
|
@@ -798,5 +1166,5 @@ function isKnownImageSize(value) {
|
|
|
798
1166
|
return KNOWN_IMAGE_SET.has(value);
|
|
799
1167
|
}
|
|
800
1168
|
|
|
801
|
-
//# debugId=
|
|
1169
|
+
//# debugId=D1FA66D9B94DF6A164756E2164756E21
|
|
802
1170
|
//# sourceMappingURL=index.cjs.map
|