76 lines
2.8 KiB
TypeScript
76 lines
2.8 KiB
TypeScript
import { parsePartialDate } from "@sttracker/plugin-sdk/partial-date";
|
|
import type { SourceRecord, Status, WorkHint } from "@sttracker/plugin-sdk/types";
|
|
import type { ApiEntry } from "./api.ts";
|
|
|
|
export const STATE_MAP: Record<string, Status> = {
|
|
considering: "planned",
|
|
plan_to_read: "planned",
|
|
reading: "in_progress",
|
|
rereading: "in_progress",
|
|
paused: "paused",
|
|
dropped: "dropped",
|
|
completed: "completed",
|
|
};
|
|
|
|
export function mapState(s: string | null | undefined): Status {
|
|
return s != null && Object.hasOwn(STATE_MAP, s) ? STATE_MAP[s]! : "none";
|
|
}
|
|
|
|
function hint(e: ApiEntry): WorkHint {
|
|
const s = e.series;
|
|
const externalIds: Record<string, string> = { mangabaka: String(e.series_id) };
|
|
const add = (ns: string, v: { id?: number | string | null } | null | undefined) => {
|
|
if (v?.id != null && v.id !== "") externalIds[ns] = String(v.id);
|
|
};
|
|
add("anilist_manga", s?.source?.anilist);
|
|
add("mal_manga", s?.source?.my_anime_list);
|
|
add("mangaupdates", s?.source?.manga_updates);
|
|
add("kitsu_manga", s?.source?.kitsu);
|
|
return {
|
|
title: s?.title ?? `MangaBaka series ${e.series_id}`,
|
|
mediaType: s?.type === "comic" ? "comic" : "manga",
|
|
...(s?.year != null ? { year: s.year } : {}),
|
|
externalIds,
|
|
};
|
|
}
|
|
|
|
export function mapEntry(e: ApiEntry): SourceRecord[] {
|
|
const work = hint(e);
|
|
const key = `series:${e.series_id}`;
|
|
const merged = e.series?.state === "merged" && e.series.merged_with != null;
|
|
const entry: SourceRecord = {
|
|
kind: "entry",
|
|
key,
|
|
raw: e,
|
|
work,
|
|
entry: {
|
|
status: mapState(e.state),
|
|
...(e.rating !== undefined ? { rating: e.rating } : {}),
|
|
...(e.note !== undefined ? { notes: e.note } : {}),
|
|
},
|
|
...(merged ? { mergedIntoKey: `series:${e.series!.merged_with}` } : {}),
|
|
};
|
|
const progress: Record<string, number> = {};
|
|
if (e.progress_chapter != null) progress.chapter = e.progress_chapter;
|
|
if (e.progress_volume != null) progress.volume = e.progress_volume;
|
|
const started = parsePartialDate(e.start_date);
|
|
const finished = parsePartialDate(e.finish_date);
|
|
if (Object.keys(progress).length === 0 && !started && !finished) return [entry];
|
|
const engagement: SourceRecord = {
|
|
kind: "engagement",
|
|
key: `progress:${e.series_id}`,
|
|
raw: e,
|
|
work,
|
|
engagement: { progress, startedAt: started, finishedAt: finished },
|
|
};
|
|
return [entry, engagement];
|
|
}
|
|
|
|
export function mapDeletion(seriesId: number): SourceRecord[] {
|
|
const work: WorkHint = { title: `MangaBaka series ${seriesId}`, mediaType: "manga", externalIds: { mangabaka: String(seriesId) } };
|
|
return [
|
|
{ kind: "entry", key: `series:${seriesId}`, raw: { series_id: seriesId }, work, entry: {}, deleted: true },
|
|
{ kind: "engagement", key: `progress:${seriesId}`, raw: { series_id: seriesId }, work, engagement: {}, deleted: true },
|
|
];
|
|
}
|