import {z} from 'zod' export type GetApiV14PersonArgs = {page?: number | undefined, limit?: number | undefined, selectFields?: (Array<'id' | 'name' | 'enName' | 'photo' | 'sex' | 'growth' | 'birthday' | 'death' | 'age' | 'birthPlace' | 'deathPlace' | 'spouses' | 'countAwards' | 'profession' | 'facts' | 'movies' | 'updatedAt' | 'createdAt'>) | undefined, notNullFields?: (Array<'id' | 'name' | 'enName' | 'photo' | 'sex' | 'growth' | 'birthday' | 'death' | 'age' | 'birthPlace.value' | 'deathPlace.value' | 'spouses.id' | 'spouses.name' | 'spouses.divorced' | 'spouses.divorcedReason' | 'spouses.sex' | 'spouses.children' | 'spouses.relation' | 'countAwards' | 'profession.value' | 'facts.value' | 'movies.id' | 'movies.name' | 'movies.alternativeName' | 'movies.rating' | 'movies.general' | 'movies.description' | 'movies.enProfession' | 'updatedAt' | 'createdAt'>) | undefined, sortField?: (Array<'id' | 'name' | 'enName' | 'photo' | 'sex' | 'growth' | 'birthday' | 'death' | 'age' | 'birthPlace.value' | 'deathPlace.value' | 'spouses.id' | 'spouses.name' | 'spouses.divorced' | 'spouses.divorcedReason' | 'spouses.sex' | 'spouses.children' | 'spouses.relation' | 'countAwards' | 'profession.value' | 'facts.value' | 'movies.id' | 'movies.name' | 'movies.alternativeName' | 'movies.rating' | 'movies.general' | 'movies.description' | 'movies.enProfession' | 'updatedAt' | 'createdAt'>) | undefined, sortType?: Array | undefined, id?: (Array | null) | undefined, 'movies.id'?: (Array | null) | undefined, sex?: (Array<'Женский' | 'Мужской'> | null) | undefined, growth?: (Array | null) | undefined, birthday?: (Array | null) | undefined, death?: (Array | null) | undefined, age?: (Array | null) | undefined, 'birthPlace.value'?: (Array | null) | undefined, 'deathPlace.value'?: (Array | null) | undefined, 'spouses.id'?: (Array | null) | undefined, 'spouses.divorced'?: (string | null) | undefined, 'spouses.sex'?: (Array<'Женский' | 'Мужской'> | null) | undefined, countAwards?: (Array | null) | undefined, 'profession.value'?: (Array<'Актер' | 'Актер дубляжа' | 'Актриса' | 'Актриса дубляжа' | 'В титрах не указаны' | 'Группа: Хроника' | 'Группа: играют самих себя' | 'Директор фильма' | 'Звукорежиссер' | 'Композитор' | 'Монтажер' | 'Озвучка' | 'Оператор' | 'Переводчик' | 'Продюсер' | 'Режиссер' | 'Режиссер дубляжа' | 'Сценарист' | 'Художник'> | null) | undefined, 'movies.rating'?: (Array | null) | undefined, 'movies.enProfession'?: (Array<'actor' | 'cameo' | 'composer' | 'design' | 'director' | 'director_ussr' | 'editor' | 'group_cameo' | 'group_uncredited' | 'operator' | 'producer' | 'sound_designer' | 'translator' | 'uncredited' | 'voice_director' | 'voiceover' | 'writer'> | null) | undefined, updatedAt?: (Array | null) | undefined, createdAt?: (Array | null) | undefined}; export type GetApiV14PersonOptions = {baseUrl?: string | undefined, XAPIKEY?: string | undefined, fetch?: typeof fetch | undefined}; export const birthPlace = z.object({value: z.string().optional()}); export const deathPlace = z.object({value: z.string().optional()}); export const spouses = z.object({id: z.number().optional(), name: z.string().optional(), divorced: z.boolean().optional(), divorcedReason: z.string().optional(), sex: z.string().optional(), children: z.number().optional(), relation: z.string().optional()}); export const profession = z.object({value: z.string().optional()}); export const factInPerson = z.object({value: z.string().optional()}); export const movieInPerson = z.object({id: z.number(), name: z.string().nullable().optional(), alternativeName: z.string().nullable().optional(), rating: z.number().nullable().optional(), general: z.boolean().nullable().optional(), description: z.string().nullable().optional(), enProfession: z.string().nullable().optional()}); export const person = z.object({id: z.number(), name: z.string().nullable().optional(), enName: z.string().nullable().optional(), photo: z.string().nullable().optional(), sex: z.string().nullable().optional(), growth: z.number().nullable().optional(), birthday: z.string().nullable().optional(), death: z.string().nullable().optional(), age: z.number().nullable().optional(), birthPlace: z.array(birthPlace).optional(), deathPlace: z.array(deathPlace).optional(), spouses: spouses.optional(), countAwards: z.number().optional(), profession: z.array(profession).optional(), facts: z.array(factInPerson).optional(), movies: z.array(movieInPerson).optional(), updatedAt: z.string(), createdAt: z.string()}); export const personDocsResponseDtoV14 = z.object({docs: z.array(person), total: z.number(), limit: z.number(), page: z.number(), pages: z.number()}); export const validateResponse = async ( schema: { readonly '~standard': { readonly validate: (value: unknown) => ({ readonly value: Output; readonly issues?: undefined } | { readonly issues: ReadonlyArray<{ readonly message: string; readonly path?: ReadonlyArray | undefined }> }) | Promise<{ readonly value: Output; readonly issues?: undefined } | { readonly issues: ReadonlyArray<{ readonly message: string; readonly path?: ReadonlyArray | undefined }> }> } }, value: unknown ): Promise => { const result = await schema['~standard'].validate(value) if (result.issues !== undefined) { const detail = result.issues .map(({ message, path }) => path?.length ? `${path.map((segment) => String(typeof segment === 'object' ? segment.key : segment)).join('.')}: ${message}` : message ) .join('; ') throw new Error(`Response does not match the schema: ${detail}`, { cause: { issues: result.issues } }) } return result.value }; /** * Универсальный поиск с фильтрами * * GET /v1.4/person */ export const getApiV14Person = async (args: GetApiV14PersonArgs, options?: GetApiV14PersonOptions) => { const {baseUrl = "https://api.kinopoisk.dev", fetch: fetchFn = fetch, XAPIKEY} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('accept', "application/json") if (args.page != null) query.append("page", String(args.page)) if (args.limit != null) query.append("limit", String(args.limit)) for (const item of args.selectFields ?? []) query.append("selectFields", String(item)) for (const item of args.notNullFields ?? []) query.append("notNullFields", String(item)) for (const item of args.sortField ?? []) query.append("sortField", String(item)) for (const item of args.sortType ?? []) query.append("sortType", String(item)) for (const item of args.id ?? []) query.append("id", String(item)) for (const item of args['movies.id'] ?? []) query.append("movies.id", String(item)) for (const item of args.sex ?? []) query.append("sex", String(item)) for (const item of args.growth ?? []) query.append("growth", String(item)) for (const item of args.birthday ?? []) query.append("birthday", String(item)) for (const item of args.death ?? []) query.append("death", String(item)) for (const item of args.age ?? []) query.append("age", String(item)) for (const item of args['birthPlace.value'] ?? []) query.append("birthPlace.value", String(item)) for (const item of args['deathPlace.value'] ?? []) query.append("deathPlace.value", String(item)) for (const item of args['spouses.id'] ?? []) query.append("spouses.id", String(item)) if (args['spouses.divorced'] != null) query.append("spouses.divorced", String(args['spouses.divorced'])) for (const item of args['spouses.sex'] ?? []) query.append("spouses.sex", String(item)) for (const item of args.countAwards ?? []) query.append("countAwards", String(item)) for (const item of args['profession.value'] ?? []) query.append("profession.value", String(item)) for (const item of args['movies.rating'] ?? []) query.append("movies.rating", String(item)) for (const item of args['movies.enProfession'] ?? []) query.append("movies.enProfession", String(item)) for (const item of args.updatedAt ?? []) query.append("updatedAt", String(item)) for (const item of args.createdAt ?? []) query.append("createdAt", String(item)) if (XAPIKEY !== undefined) headers.set("X-API-KEY", XAPIKEY) const url = `${baseUrl.replace(/\/+$/, '')}/v1.4/person${query.size > 0 ? `?${query}` : ''}` const res = await fetchFn(url, {method: "GET", headers}) if (!res.ok) throw new Error(`Request failed with status ${res.status}`, {cause: {status: res.status, body: await res.text()}}) return validateResponse(personDocsResponseDtoV14, await res.json()) };