mal api schema impl
This commit is contained in:
@@ -1,87 +1,81 @@
|
||||
/*
|
||||
import { z } from "zod";
|
||||
|
||||
query Parameters
|
||||
status
|
||||
string
|
||||
export const MalAnimeListStatusEnum = z.enum([
|
||||
"watching",
|
||||
"completed",
|
||||
"on_hold",
|
||||
"dropped",
|
||||
"plan_to_watch",
|
||||
]);
|
||||
export type MalAnimeListStatus = z.infer<typeof MalAnimeListStatusEnum>;
|
||||
|
||||
Filters returned anime list by these statuses.
|
||||
export const MalAnimeListSortEnum = z.enum([
|
||||
"list_score",
|
||||
"list_updated_at",
|
||||
"anime_title",
|
||||
"anime_start_date",
|
||||
"anime_id",
|
||||
]);
|
||||
export type MalAnimeListSort = z.infer<typeof MalAnimeListSortEnum>;
|
||||
|
||||
To return all anime, don't specify this field.
|
||||
const NumericQueryParamSchema = z
|
||||
.union([z.number(), z.string()])
|
||||
.transform((v) => (typeof v === "string" ? Number(v) : v));
|
||||
|
||||
Valid values:
|
||||
export const MalAnimeListQuerySchema = z
|
||||
.object({
|
||||
status: MalAnimeListStatusEnum.optional(),
|
||||
sort: MalAnimeListSortEnum.optional(),
|
||||
limit: NumericQueryParamSchema.pipe(
|
||||
z.number().int().min(1).max(1000),
|
||||
).optional(),
|
||||
offset: NumericQueryParamSchema.pipe(z.number().int().min(0)).optional(),
|
||||
})
|
||||
.strict();
|
||||
export type MalAnimeListQuery = z.infer<typeof MalAnimeListQuerySchema>;
|
||||
|
||||
watching
|
||||
completed
|
||||
on_hold
|
||||
dropped
|
||||
plan_to_watch
|
||||
export const MalAnimeEntry = z
|
||||
.object({
|
||||
id: z.number().int().positive(),
|
||||
title: z.string(),
|
||||
main_picture: z
|
||||
.object({
|
||||
medium: z.string(),
|
||||
large: z.string(),
|
||||
})
|
||||
.strict()
|
||||
.optional(),
|
||||
})
|
||||
.strict();
|
||||
|
||||
sort
|
||||
string
|
||||
export const MalAnimeListEntry = z
|
||||
.object({
|
||||
status: MalAnimeListStatusEnum,
|
||||
score: z.number().int().min(0).max(10),
|
||||
num_episodes_watched: z.number().int().min(0),
|
||||
is_rewatching: z.boolean(),
|
||||
updated_at: z.iso.datetime(),
|
||||
start_date: z.iso.date().optional(),
|
||||
finish_date: z.iso.date().optional(),
|
||||
})
|
||||
.strict();
|
||||
|
||||
Valid values:
|
||||
Value Order
|
||||
list_score Descending
|
||||
list_updated_at Descending
|
||||
anime_title Ascending
|
||||
anime_start_date Descending
|
||||
anime_id (Under Development) Ascending
|
||||
limit
|
||||
integer
|
||||
Default: 100
|
||||
|
||||
The maximum value is 1000.
|
||||
offset
|
||||
integer
|
||||
Default: 0
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
sample response
|
||||
|
||||
{
|
||||
"data": [
|
||||
{
|
||||
"node": {
|
||||
"id": 31646,
|
||||
"title": "3-gatsu no Lion",
|
||||
"main_picture": {
|
||||
"medium": "https://cdn.myanimelist.net/images/anime/3/82899.jpg",
|
||||
"large": "https://cdn.myanimelist.net/images/anime/3/82899l.jpg"
|
||||
}
|
||||
},
|
||||
"list_status": {
|
||||
"status": "watching",
|
||||
"score": 0,
|
||||
"num_episodes_watched": 2,
|
||||
"is_rewatching": false,
|
||||
"updated_at": "2025-07-17T00:57:26+00:00",
|
||||
"start_date": "2025-07-16"
|
||||
}
|
||||
},
|
||||
{
|
||||
"node": {
|
||||
"id": 38101,
|
||||
"title": "5-toubun no Hanayome",
|
||||
"main_picture": {
|
||||
"medium": "https://cdn.myanimelist.net/images/anime/1819/97947.jpg",
|
||||
"large": "https://cdn.myanimelist.net/images/anime/1819/97947l.jpg"
|
||||
}
|
||||
},
|
||||
"list_status": {
|
||||
"status": "completed",
|
||||
"score": 0,
|
||||
"num_episodes_watched": 12,
|
||||
"is_rewatching": false,
|
||||
"updated_at": "2019-06-02T09:12:42+00:00",
|
||||
"start_date": "2019-05-31",
|
||||
"finish_date": "2019-06-02"
|
||||
}
|
||||
}
|
||||
],
|
||||
"paging": {
|
||||
"next": "https://api.myanimelist.net/v2/users/CaZzzer/animelist?offset=2&fields=list_status&limit=2"
|
||||
}
|
||||
}
|
||||
*/
|
||||
export const MalAnimeListResponseSchema = z
|
||||
.object({
|
||||
data: z.array(
|
||||
z
|
||||
.object({
|
||||
node: MalAnimeEntry,
|
||||
list_status: MalAnimeListEntry,
|
||||
})
|
||||
.strict(),
|
||||
),
|
||||
paging: z
|
||||
.object({
|
||||
next: z.string().optional(),
|
||||
previous: z.string().optional(),
|
||||
})
|
||||
.strict(),
|
||||
})
|
||||
.strict();
|
||||
export type MalAnimeListResponse = z.infer<typeof MalAnimeListResponseSchema>;
|
||||
|
||||
Reference in New Issue
Block a user