diff --git a/projects/api/deno.json b/projects/api/deno.json index 7886d977..24468450 100644 --- a/projects/api/deno.json +++ b/projects/api/deno.json @@ -1,7 +1,7 @@ { "name": "@trakt/api", "exports": "./src/index.ts", - "version": "0.1.42", + "version": "0.1.43", "imports": { "@anatine/zod-openapi": "npm:@anatine/zod-openapi@^2.2.6", "@std/testing": "jsr:@std/testing@^1.0.5", diff --git a/projects/api/src/contracts/users/_internal/request/monthInReviewParamsSchema.ts b/projects/api/src/contracts/users/_internal/request/monthInReviewParamsSchema.ts new file mode 100644 index 00000000..41eac9d4 --- /dev/null +++ b/projects/api/src/contracts/users/_internal/request/monthInReviewParamsSchema.ts @@ -0,0 +1,6 @@ +import { z } from '../../../_internal/z.ts'; + +export const monthInReviewParamsSchema = z.object({ + year: z.number().int(), + month: z.number().int(), +}); diff --git a/projects/api/src/contracts/users/_internal/response/monthInReviewResponseSchema.ts b/projects/api/src/contracts/users/_internal/response/monthInReviewResponseSchema.ts new file mode 100644 index 00000000..ed943a99 --- /dev/null +++ b/projects/api/src/contracts/users/_internal/response/monthInReviewResponseSchema.ts @@ -0,0 +1,53 @@ +import { episodeResponseSchema } from '../../../_internal/response/episodeResponseSchema.ts'; +import { movieResponseSchema } from '../../../_internal/response/movieResponseSchema.ts'; +import { showResponseSchema } from '../../../_internal/response/showResponseSchema.ts'; +import { z } from '../../../_internal/z.ts'; + +const statsSchema = z.object({ + total: z.number(), + yearly: z.number(), + monthly: z.number(), + weekly: z.number(), + daily: z.number(), +}); + +const statsCategoriesSchema = z.object({ + minutes: statsSchema, + play_counts: statsSchema, + collected_counts: statsSchema, + ratings_counts: statsSchema, + comments_counts: statsSchema, + lists_counts: statsSchema, +}); + +const watchedEpisodeSchema = z.object({ + type: z.literal('episode'), + watched_at: z.string().datetime(), + episode: episodeResponseSchema, + show: showResponseSchema, +}); + +const watchedMovieSchema = z.object({ + type: z.literal('movie'), + watched_at: z.string().datetime(), + movie: movieResponseSchema, +}); + +const watchedItemSchema = z.discriminatedUnion('type', [ + watchedEpisodeSchema, + watchedMovieSchema, +]); + +export const monthInReviewResponseSchema = z.object({ + stats: z.object({ + all: statsCategoriesSchema, + shows: statsCategoriesSchema, + movies: statsCategoriesSchema, + }), + images: z.object({ + cover: z.string(), + story: z.string(), + }), + first_watched: watchedItemSchema, + last_watched: watchedItemSchema, +}); diff --git a/projects/api/src/contracts/users/index.ts b/projects/api/src/contracts/users/index.ts index 5fcb1ad6..66ba65ac 100644 --- a/projects/api/src/contracts/users/index.ts +++ b/projects/api/src/contracts/users/index.ts @@ -10,6 +10,7 @@ import { avatarRequestSchema } from './_internal/request/avatarRequestSchema.ts' import { commentOnTypeParamsSchema } from './_internal/request/commentOnTypeParamsSchema.ts'; import { commentsRequestSchema } from './_internal/request/commentsRequestSchema.ts'; import { commentTypeParamsSchema } from './_internal/request/commentTypeParamsSchema.ts'; +import { monthInReviewParamsSchema } from './_internal/request/monthInReviewParamsSchema.ts'; import { profileParamsSchema } from './_internal/request/profileParamsSchema.ts'; import { settingsRequestSchema } from './_internal/request/settingsRequestSchema.ts'; import { socialActivityParamsSchema } from './_internal/request/socialActivityParamsSchema.ts'; @@ -21,6 +22,7 @@ import { likedCommentResponseSchema, likedListResponseSchema, } from './_internal/response/likedItemResponseSchema.ts'; +import { monthInReviewResponseSchema } from './_internal/response/monthInReviewResponseSchema.ts'; import { settingsResponseSchema } from './_internal/response/settingsResponseSchema.ts'; import { socialActivityResponseSchema } from './_internal/response/socialActivityResponseSchema.ts'; import { userCommentResponseSchema } from './_internal/response/userCommentResponseSchema.ts'; @@ -183,6 +185,16 @@ const ENTITY_LEVEL = builder.router({ 200: friendResponseSchema.array(), }, }, + month_in_review: { + path: '/mir', + pathParams: profileParamsSchema + .merge(monthInReviewParamsSchema), + query: extendedMediaQuerySchema, + method: 'GET', + responses: { + 200: monthInReviewResponseSchema, + }, + }, }, { pathPrefix: '/:id', }); @@ -245,3 +257,6 @@ export type UserCommentResponse = z.infer; export type WatchingResponse = z.infer; export type AvatarRequest = z.infer; export type SettingsRequest = z.infer; + +export type MonthInReviewParams = z.infer; +export type MonthInReviewResponse = z.infer;