@vanomarb/animap 1.0.0 → 1.0.1
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 +2 -1
- package/package.json +1 -1
- package/src/client.js +8 -3
- package/src/index.d.ts +22 -3
package/README.md
CHANGED
|
@@ -117,7 +117,7 @@ await client.toSeries('kitsu:44607', 7, { target: 'tvdb' });
|
|
|
117
117
|
// { provider, id, season, episode, span, source, confidence } | null
|
|
118
118
|
await client.fromSeries('tt8948436', 1, 85); // [{ entry, ids, episode, source, confidence }]
|
|
119
119
|
await client.series('tvdb:342329', { season: 1 }); // { series, title, images, seasons: [{ season, length, rows, issues }] }
|
|
120
|
-
await client.search('soul land', { limit: 5 }); // EntrySummary[]
|
|
120
|
+
await client.search('soul land', { limit: 5 }); // EntrySummary[]; { live: false } = cached only
|
|
121
121
|
await client.issues({ entry: 'kitsu:44607', type: 'count' }); // { results: Issue[], next }
|
|
122
122
|
await client.history('anilist:129347'); // Revision[], newest first
|
|
123
123
|
```
|
|
@@ -149,6 +149,7 @@ await client.titleEpisodes('tt8948436', { season: 1 });
|
|
|
149
149
|
// { season: 1, seasons: [1, 0], episodes: [{ season, episode, name, overview, released, thumbnail, runtime, rating, mapped }] }
|
|
150
150
|
await client.titles({ q: 'soul land', type: 'series', genre: 'Action', sort: 'popular', limit: 24 });
|
|
151
151
|
// { results: TitleSummary[], total, next } — pass `next` back as `cursor`
|
|
152
|
+
await client.titles({ q: 'tmdb:76572', live: false }); // an id is a lookup; live: false = server cache only, no upstream call
|
|
152
153
|
await client.trending({ limit: 12 }); // TitleSummary[]
|
|
153
154
|
await client.activity({ limit: 20 }); // recent mapping edits
|
|
154
155
|
await client.stats(); // { titles, entries, mappedEpisodes, ranges, sources, importedAt }
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vanomarb/animap",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "AniMap client: map Kitsu, MAL, AniList and AniDB entries to TVDB, TMDB and IMDb seasons and episodes, read titles and episodes, and enrich them in-process with your own TMDB, TVDB and Fanart.tv keys.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.js",
|
package/src/client.js
CHANGED
|
@@ -256,11 +256,13 @@ export class Client {
|
|
|
256
256
|
}
|
|
257
257
|
|
|
258
258
|
/** Entry search by title, alias or id. Returns EntrySummary[]. */
|
|
259
|
-
|
|
259
|
+
/** `live: false`: the server answers from its cache only, with no upstream call. */
|
|
260
|
+
async search(query, { limit, live } = {}) {
|
|
260
261
|
if (typeof query !== 'string' || !query.trim()) throw new ClientError('invalid_argument', 'search() needs a non-empty query');
|
|
261
262
|
optionalInt(limit, 'limit', 1);
|
|
262
263
|
const params = new URLSearchParams({ q: query.trim() });
|
|
263
264
|
if (limit !== undefined) params.set('limit', String(limit));
|
|
265
|
+
if (live === false) params.set('live', '0');
|
|
264
266
|
const body = await this.#cached(`search:${params}`, () => this.#request('GET', `/v1/search?${params}`));
|
|
265
267
|
return body.results ?? [];
|
|
266
268
|
}
|
|
@@ -356,7 +358,7 @@ export class Client {
|
|
|
356
358
|
* Browse or search titles. `q` matches names, aliases and any id.
|
|
357
359
|
* Returns { results: TitleSummary[], total, next }; pass `next` back as `cursor`.
|
|
358
360
|
*/
|
|
359
|
-
async titles({ q, type, format, year, genre, mapped, issues, sort, cursor, limit } = {}) {
|
|
361
|
+
async titles({ q, type, format, year, genre, mapped, issues, sort, cursor, limit, live } = {}) {
|
|
360
362
|
optionalInt(year, 'year', 0);
|
|
361
363
|
optionalInt(limit, 'limit', 1);
|
|
362
364
|
const params = new URLSearchParams();
|
|
@@ -364,6 +366,7 @@ export class Client {
|
|
|
364
366
|
if (v !== undefined && v !== null && v !== '') params.set(k, String(v).trim());
|
|
365
367
|
}
|
|
366
368
|
if (issues) params.set('issues', '1');
|
|
369
|
+
if (live === false) params.set('live', '0');
|
|
367
370
|
const qs = params.toString() ? `?${params}` : '';
|
|
368
371
|
return this.#cached(`titles:${qs}`, () => this.#request('GET', `/v1/titles${qs}`));
|
|
369
372
|
}
|
|
@@ -439,7 +442,9 @@ export class Client {
|
|
|
439
442
|
const core = this.#core;
|
|
440
443
|
const cached = await core.providerCache.get('title', server.id, core.sig);
|
|
441
444
|
if (cached) return { sources: cached, errors: [] };
|
|
442
|
-
|
|
445
|
+
// Recommendations resolve from the server's cache only: a similar title nobody has
|
|
446
|
+
// opened yet is left out rather than resolved live, eight times per title.
|
|
447
|
+
const findTitle = async (ref) => (await this.titles({ q: ref, limit: 1, live: false })).results?.[0] ?? null;
|
|
443
448
|
const { sources, errors } = await fetchSources(server, core.keys, { fetch: core.fetch, findTitle, signal });
|
|
444
449
|
this.#report(errors);
|
|
445
450
|
if (!errors.some(isTransient) && !errors.some((e) => e.code === 'aborted')) {
|
package/src/index.d.ts
CHANGED
|
@@ -48,6 +48,9 @@ export interface Images {
|
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
export type EntrySummary = Omit<Entry, 'ranges'> & {
|
|
51
|
+
names: Names;
|
|
52
|
+
/** On search() results: the Cinemeta-format id of the entry's title, null when none is cached. */
|
|
53
|
+
titleId?: string | null;
|
|
51
54
|
rangeCount: number;
|
|
52
55
|
issueCount: number;
|
|
53
56
|
/** Targets the entry has effective ranges for, in the order tvdb, tmdb, imdb. */
|
|
@@ -151,11 +154,23 @@ export interface TitleSeason {
|
|
|
151
154
|
poster: string | null;
|
|
152
155
|
}
|
|
153
156
|
|
|
157
|
+
/** A title's name in three forms; each null when unknown. */
|
|
158
|
+
export interface Names {
|
|
159
|
+
/** English only (the `name` rule). */
|
|
160
|
+
english: string | null;
|
|
161
|
+
/** Kitsu's romanisation (en_jp, en_cn or en_kr). */
|
|
162
|
+
romaji: string | null;
|
|
163
|
+
/** ja_jp, zh_cn or ko_kr. */
|
|
164
|
+
native: string | null;
|
|
165
|
+
}
|
|
166
|
+
|
|
154
167
|
export interface TitleSummary {
|
|
155
|
-
/** Cinemeta-format id: "tt…", else "kitsu:<id>", "tmdb:<id>", "tvdb:<id>"
|
|
168
|
+
/** Cinemeta-format id: "tt…", else "kitsu:<id>", "tmdb:<id>", "tvdb:<id>", then "mal:", "anilist:" or "anidb:". */
|
|
156
169
|
id: string;
|
|
157
170
|
type: TitleType;
|
|
171
|
+
/** names.english, else names.romaji. */
|
|
158
172
|
name: string | null;
|
|
173
|
+
names: Names;
|
|
159
174
|
year: string | null;
|
|
160
175
|
format: Format;
|
|
161
176
|
poster: string | null;
|
|
@@ -173,7 +188,9 @@ export interface Title {
|
|
|
173
188
|
id: string;
|
|
174
189
|
type: TitleType;
|
|
175
190
|
ids: Record<SeriesProvider | AnimeProvider, string | null>;
|
|
191
|
+
/** names.english, else names.romaji. */
|
|
176
192
|
name: string | null;
|
|
193
|
+
names: Names;
|
|
177
194
|
originalName: string | null;
|
|
178
195
|
description: string | null;
|
|
179
196
|
genres: string[];
|
|
@@ -223,7 +240,7 @@ export interface TitleEpisodes {
|
|
|
223
240
|
}
|
|
224
241
|
|
|
225
242
|
export interface TitlesQuery {
|
|
226
|
-
/** Names
|
|
243
|
+
/** Names and aliases; an id (tt…, tmdb:N, kitsu:N, …) is a lookup of that id. */
|
|
227
244
|
q?: string;
|
|
228
245
|
type?: TitleType;
|
|
229
246
|
format?: Format;
|
|
@@ -236,6 +253,8 @@ export interface TitlesQuery {
|
|
|
236
253
|
/** `next` from the previous page. */
|
|
237
254
|
cursor?: string;
|
|
238
255
|
limit?: number;
|
|
256
|
+
/** false: the server answers from its cache only, with no upstream call. */
|
|
257
|
+
live?: boolean;
|
|
239
258
|
}
|
|
240
259
|
|
|
241
260
|
export interface TitlesPage {
|
|
@@ -567,7 +586,7 @@ export class Client {
|
|
|
567
586
|
/** Every mapped entry of a series ("tvdb:342329"), grouped by season. */
|
|
568
587
|
series(ref: string, options?: { season?: number }): Promise<SeriesResponse>;
|
|
569
588
|
/** Entry search by title, alias or id. */
|
|
570
|
-
search(query: string, options?: { limit?: number }): Promise<EntrySummary[]>;
|
|
589
|
+
search(query: string, options?: { limit?: number; /** false: the server's cache only, no upstream call. */ live?: boolean }): Promise<EntrySummary[]>;
|
|
571
590
|
/** Mapping issues, optionally for one entry and one type. */
|
|
572
591
|
issues(options?: { type?: Issue['type']; entry?: string; cursor?: string; limit?: number }): Promise<{ results: Issue[]; next: string | null }>;
|
|
573
592
|
/** Edit history of an entry, newest first. */
|