import {z} from 'zod' export type GetApiPersonsNameArgs = {name: string, userId?: (string | null) | undefined}; export type GetApiPersonsNameOptions = {baseUrl?: string | undefined, CustomAuthentication?: string | undefined, fetch?: typeof fetch | undefined}; export const video3DFormat = z.enum(["HalfSideBySide", "FullSideBySide", "FullTopAndBottom", "HalfTopAndBottom", "MVC"]); export const externalUrl = z.object({Name: z.string().nullable().optional(), Url: z.string().nullable().optional()}); export const mediaProtocol = z.enum(["File", "Http", "Rtmp", "Rtsp", "Udp", "Rtp", "Ftp"]); export const mediaSourceType = z.enum(["Default", "Grouping", "Placeholder"]); export const videoType = z.enum(["VideoFile", "Iso", "Dvd", "BluRay"]); export const isoType = z.enum(["Dvd", "BluRay"]); export const mediaStreamType = z.enum(["Audio", "Video", "Subtitle", "EmbeddedImage"]); export const subtitleDeliveryMethod = z.enum(["Encode", "Embed", "External", "Hls"]); export const mediaStream = z.object({Codec: z.string().nullable().optional(), CodecTag: z.string().nullable().optional(), Language: z.string().nullable().optional(), ColorRange: z.string().nullable().optional(), ColorSpace: z.string().nullable().optional(), ColorTransfer: z.string().nullable().optional(), ColorPrimaries: z.string().nullable().optional(), Comment: z.string().nullable().optional(), TimeBase: z.string().nullable().optional(), CodecTimeBase: z.string().nullable().optional(), Title: z.string().nullable().optional(), VideoRange: z.string().nullable().optional(), localizedUndefined: z.string().nullable().optional(), localizedDefault: z.string().nullable().optional(), localizedForced: z.string().nullable().optional(), DisplayTitle: z.string().nullable().optional(), NalLengthSize: z.string().nullable().optional(), IsInterlaced: z.boolean().optional(), IsAVC: z.boolean().nullable().optional(), ChannelLayout: z.string().nullable().optional(), BitRate: z.number().int().nullable().optional(), BitDepth: z.number().int().nullable().optional(), RefFrames: z.number().int().nullable().optional(), PacketLength: z.number().int().nullable().optional(), Channels: z.number().int().nullable().optional(), SampleRate: z.number().int().nullable().optional(), IsDefault: z.boolean().optional(), IsForced: z.boolean().optional(), Height: z.number().int().nullable().optional(), Width: z.number().int().nullable().optional(), AverageFrameRate: z.number().nullable().optional(), RealFrameRate: z.number().nullable().optional(), Profile: z.string().nullable().optional(), Type: mediaStreamType.optional(), AspectRatio: z.string().nullable().optional(), Index: z.number().int().optional(), Score: z.number().int().nullable().optional(), IsExternal: z.boolean().optional(), DeliveryMethod: subtitleDeliveryMethod.optional(), DeliveryUrl: z.string().nullable().optional(), IsExternalUrl: z.boolean().nullable().optional(), IsTextSubtitleStream: z.boolean().optional(), SupportsExternalStream: z.boolean().optional(), Path: z.string().nullable().optional(), PixelFormat: z.string().nullable().optional(), Level: z.number().nullable().optional(), IsAnamorphic: z.boolean().nullable().optional()}); export const mediaAttachment = z.object({Codec: z.string().nullable().optional(), CodecTag: z.string().nullable().optional(), Comment: z.string().nullable().optional(), Index: z.number().int().optional(), FileName: z.string().nullable().optional(), MimeType: z.string().nullable().optional(), DeliveryUrl: z.string().nullable().optional()}); export const transportStreamTimestamp = z.enum(["None", "Zero", "Valid"]); export const mediaSourceInfo = z.object({Protocol: mediaProtocol.optional(), Id: z.string().nullable().optional(), Path: z.string().nullable().optional(), EncoderPath: z.string().nullable().optional(), EncoderProtocol: mediaProtocol.optional(), Type: mediaSourceType.optional(), Container: z.string().nullable().optional(), Size: z.number().int().nullable().optional(), Name: z.string().nullable().optional(), IsRemote: z.boolean().optional(), ETag: z.string().nullable().optional(), RunTimeTicks: z.number().int().nullable().optional(), ReadAtNativeFramerate: z.boolean().optional(), IgnoreDts: z.boolean().optional(), IgnoreIndex: z.boolean().optional(), GenPtsInput: z.boolean().optional(), SupportsTranscoding: z.boolean().optional(), SupportsDirectStream: z.boolean().optional(), SupportsDirectPlay: z.boolean().optional(), IsInfiniteStream: z.boolean().optional(), RequiresOpening: z.boolean().optional(), OpenToken: z.string().nullable().optional(), RequiresClosing: z.boolean().optional(), LiveStreamId: z.string().nullable().optional(), BufferMs: z.number().int().nullable().optional(), RequiresLooping: z.boolean().optional(), SupportsProbing: z.boolean().optional(), VideoType: videoType.optional(), IsoType: isoType.optional(), Video3DFormat: video3DFormat.optional(), MediaStreams: z.array(mediaStream).nullable().optional(), MediaAttachments: z.array(mediaAttachment).nullable().optional(), Formats: z.array(z.string()).nullable().optional(), Bitrate: z.number().int().nullable().optional(), Timestamp: transportStreamTimestamp.optional(), RequiredHttpHeaders: z.record(z.string(), z.string()).nullable().optional(), TranscodingUrl: z.string().nullable().optional(), TranscodingSubProtocol: z.string().nullable().optional(), TranscodingContainer: z.string().nullable().optional(), AnalyzeDurationMs: z.number().int().nullable().optional(), DefaultAudioStreamIndex: z.number().int().nullable().optional(), DefaultSubtitleStreamIndex: z.number().int().nullable().optional()}); export const playAccess = z.enum(["Full", "None"]); export const mediaUrl = z.object({Url: z.string().nullable().optional(), Name: z.string().nullable().optional()}); export const baseItemPerson = z.object({Name: z.string().nullable().optional(), Id: z.string().nullable().optional(), Role: z.string().nullable().optional(), Type: z.string().nullable().optional(), PrimaryImageTag: z.string().nullable().optional(), ImageBlurHashes: z.object({Primary: z.record(z.string(), z.string()).optional(), Art: z.record(z.string(), z.string()).optional(), Backdrop: z.record(z.string(), z.string()).optional(), Banner: z.record(z.string(), z.string()).optional(), Logo: z.record(z.string(), z.string()).optional(), Thumb: z.record(z.string(), z.string()).optional(), Disc: z.record(z.string(), z.string()).optional(), Box: z.record(z.string(), z.string()).optional(), Screenshot: z.record(z.string(), z.string()).optional(), Menu: z.record(z.string(), z.string()).optional(), Chapter: z.record(z.string(), z.string()).optional(), BoxRear: z.record(z.string(), z.string()).optional(), Profile: z.record(z.string(), z.string()).optional()}).nullable().optional()}); export const nameGuidPair = z.object({Name: z.string().nullable().optional(), Id: z.string().optional()}); export const userItemDataDto = z.object({Rating: z.number().nullable().optional(), PlayedPercentage: z.number().nullable().optional(), UnplayedItemCount: z.number().int().nullable().optional(), PlaybackPositionTicks: z.number().int().optional(), PlayCount: z.number().int().optional(), IsFavorite: z.boolean().optional(), Likes: z.boolean().nullable().optional(), LastPlayedDate: z.string().nullable().optional(), Played: z.boolean().optional(), Key: z.string().nullable().optional(), ItemId: z.string().nullable().optional()}); export const dayOfWeek = z.enum(["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]); export const chapterInfo = z.object({StartPositionTicks: z.number().int().optional(), Name: z.string().nullable().optional(), ImagePath: z.string().nullable().optional(), ImageDateModified: z.string().optional(), ImageTag: z.string().nullable().optional()}); export const locationType = z.enum(["FileSystem", "Remote", "Virtual", "Offline"]); export const metadataField = z.enum(["Cast", "Genres", "ProductionLocations", "Studios", "Tags", "Name", "Overview", "Runtime", "OfficialRating"]); export const imageOrientation = z.enum(["TopLeft", "TopRight", "BottomRight", "BottomLeft", "LeftTop", "RightTop", "RightBottom", "LeftBottom"]); export const channelType = z.enum(["TV", "Radio"]); export const programAudio = z.enum(["Mono", "Stereo", "Dolby", "DolbyDigital", "Thx", "Atmos"]); export const baseItemDto: z.ZodType = z.object({Name: z.string().nullable().optional(), OriginalTitle: z.string().nullable().optional(), ServerId: z.string().nullable().optional(), Id: z.string().optional(), Etag: z.string().nullable().optional(), SourceType: z.string().nullable().optional(), PlaylistItemId: z.string().nullable().optional(), DateCreated: z.string().nullable().optional(), DateLastMediaAdded: z.string().nullable().optional(), ExtraType: z.string().nullable().optional(), AirsBeforeSeasonNumber: z.number().int().nullable().optional(), AirsAfterSeasonNumber: z.number().int().nullable().optional(), AirsBeforeEpisodeNumber: z.number().int().nullable().optional(), CanDelete: z.boolean().nullable().optional(), CanDownload: z.boolean().nullable().optional(), HasSubtitles: z.boolean().nullable().optional(), PreferredMetadataLanguage: z.string().nullable().optional(), PreferredMetadataCountryCode: z.string().nullable().optional(), SupportsSync: z.boolean().nullable().optional(), Container: z.string().nullable().optional(), SortName: z.string().nullable().optional(), ForcedSortName: z.string().nullable().optional(), Video3DFormat: video3DFormat.optional(), PremiereDate: z.string().nullable().optional(), ExternalUrls: z.array(externalUrl).nullable().optional(), MediaSources: z.array(mediaSourceInfo).nullable().optional(), CriticRating: z.number().nullable().optional(), ProductionLocations: z.array(z.string()).nullable().optional(), Path: z.string().nullable().optional(), EnableMediaSourceDisplay: z.boolean().nullable().optional(), OfficialRating: z.string().nullable().optional(), CustomRating: z.string().nullable().optional(), ChannelId: z.string().nullable().optional(), ChannelName: z.string().nullable().optional(), Overview: z.string().nullable().optional(), Taglines: z.array(z.string()).nullable().optional(), Genres: z.array(z.string()).nullable().optional(), CommunityRating: z.number().nullable().optional(), CumulativeRunTimeTicks: z.number().int().nullable().optional(), RunTimeTicks: z.number().int().nullable().optional(), PlayAccess: playAccess.optional(), AspectRatio: z.string().nullable().optional(), ProductionYear: z.number().int().nullable().optional(), IsPlaceHolder: z.boolean().nullable().optional(), Number: z.string().nullable().optional(), ChannelNumber: z.string().nullable().optional(), IndexNumber: z.number().int().nullable().optional(), IndexNumberEnd: z.number().int().nullable().optional(), ParentIndexNumber: z.number().int().nullable().optional(), RemoteTrailers: z.array(mediaUrl).nullable().optional(), ProviderIds: z.record(z.string(), z.string()).nullable().optional(), IsHD: z.boolean().nullable().optional(), IsFolder: z.boolean().nullable().optional(), ParentId: z.string().nullable().optional(), Type: z.string().nullable().optional(), People: z.array(baseItemPerson).nullable().optional(), Studios: z.array(nameGuidPair).nullable().optional(), GenreItems: z.array(nameGuidPair).nullable().optional(), ParentLogoItemId: z.string().nullable().optional(), ParentBackdropItemId: z.string().nullable().optional(), ParentBackdropImageTags: z.array(z.string()).nullable().optional(), LocalTrailerCount: z.number().int().nullable().optional(), UserData: userItemDataDto.optional(), RecursiveItemCount: z.number().int().nullable().optional(), ChildCount: z.number().int().nullable().optional(), SeriesName: z.string().nullable().optional(), SeriesId: z.string().nullable().optional(), SeasonId: z.string().nullable().optional(), SpecialFeatureCount: z.number().int().nullable().optional(), DisplayPreferencesId: z.string().nullable().optional(), Status: z.string().nullable().optional(), AirTime: z.string().nullable().optional(), AirDays: z.array(dayOfWeek).nullable().optional(), Tags: z.array(z.string()).nullable().optional(), PrimaryImageAspectRatio: z.number().nullable().optional(), Artists: z.array(z.string()).nullable().optional(), ArtistItems: z.array(nameGuidPair).nullable().optional(), Album: z.string().nullable().optional(), CollectionType: z.string().nullable().optional(), DisplayOrder: z.string().nullable().optional(), AlbumId: z.string().nullable().optional(), AlbumPrimaryImageTag: z.string().nullable().optional(), SeriesPrimaryImageTag: z.string().nullable().optional(), AlbumArtist: z.string().nullable().optional(), AlbumArtists: z.array(nameGuidPair).nullable().optional(), SeasonName: z.string().nullable().optional(), MediaStreams: z.array(mediaStream).nullable().optional(), VideoType: videoType.optional(), PartCount: z.number().int().nullable().optional(), MediaSourceCount: z.number().int().nullable().optional(), ImageTags: z.record(z.string(), z.string()).nullable().optional(), BackdropImageTags: z.array(z.string()).nullable().optional(), ScreenshotImageTags: z.array(z.string()).nullable().optional(), ParentLogoImageTag: z.string().nullable().optional(), ParentArtItemId: z.string().nullable().optional(), ParentArtImageTag: z.string().nullable().optional(), SeriesThumbImageTag: z.string().nullable().optional(), ImageBlurHashes: z.object({Primary: z.record(z.string(), z.string()).optional(), Art: z.record(z.string(), z.string()).optional(), Backdrop: z.record(z.string(), z.string()).optional(), Banner: z.record(z.string(), z.string()).optional(), Logo: z.record(z.string(), z.string()).optional(), Thumb: z.record(z.string(), z.string()).optional(), Disc: z.record(z.string(), z.string()).optional(), Box: z.record(z.string(), z.string()).optional(), Screenshot: z.record(z.string(), z.string()).optional(), Menu: z.record(z.string(), z.string()).optional(), Chapter: z.record(z.string(), z.string()).optional(), BoxRear: z.record(z.string(), z.string()).optional(), Profile: z.record(z.string(), z.string()).optional()}).nullable().optional(), SeriesStudio: z.string().nullable().optional(), ParentThumbItemId: z.string().nullable().optional(), ParentThumbImageTag: z.string().nullable().optional(), ParentPrimaryImageItemId: z.string().nullable().optional(), ParentPrimaryImageTag: z.string().nullable().optional(), Chapters: z.array(chapterInfo).nullable().optional(), LocationType: locationType.optional(), IsoType: isoType.optional(), MediaType: z.string().nullable().optional(), EndDate: z.string().nullable().optional(), LockedFields: z.array(metadataField).nullable().optional(), TrailerCount: z.number().int().nullable().optional(), MovieCount: z.number().int().nullable().optional(), SeriesCount: z.number().int().nullable().optional(), ProgramCount: z.number().int().nullable().optional(), EpisodeCount: z.number().int().nullable().optional(), SongCount: z.number().int().nullable().optional(), AlbumCount: z.number().int().nullable().optional(), ArtistCount: z.number().int().nullable().optional(), MusicVideoCount: z.number().int().nullable().optional(), LockData: z.boolean().nullable().optional(), Width: z.number().int().nullable().optional(), Height: z.number().int().nullable().optional(), CameraMake: z.string().nullable().optional(), CameraModel: z.string().nullable().optional(), Software: z.string().nullable().optional(), ExposureTime: z.number().nullable().optional(), FocalLength: z.number().nullable().optional(), ImageOrientation: imageOrientation.optional(), Aperture: z.number().nullable().optional(), ShutterSpeed: z.number().nullable().optional(), Latitude: z.number().nullable().optional(), Longitude: z.number().nullable().optional(), Altitude: z.number().nullable().optional(), IsoSpeedRating: z.number().int().nullable().optional(), SeriesTimerId: z.string().nullable().optional(), ProgramId: z.string().nullable().optional(), ChannelPrimaryImageTag: z.string().nullable().optional(), StartDate: z.string().nullable().optional(), CompletionPercentage: z.number().nullable().optional(), IsRepeat: z.boolean().nullable().optional(), EpisodeTitle: z.string().nullable().optional(), ChannelType: channelType.optional(), Audio: programAudio.optional(), IsMovie: z.boolean().nullable().optional(), IsSports: z.boolean().nullable().optional(), IsSeries: z.boolean().nullable().optional(), IsLive: z.boolean().nullable().optional(), IsNews: z.boolean().nullable().optional(), IsKids: z.boolean().nullable().optional(), IsPremiere: z.boolean().nullable().optional(), TimerId: z.string().nullable().optional(), CurrentProgram: z.lazy(() => baseItemDto.optional())}); 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 person by name. * * GET /Persons/{name} */ export const getApiPersonsName = async (args: GetApiPersonsNameArgs, options?: GetApiPersonsNameOptions) => { const {baseUrl = "http://localhost", fetch: fetchFn = fetch, CustomAuthentication} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('accept', "application/json") if (args.userId != null) query.append("userId", String(args.userId)) if (CustomAuthentication !== undefined) headers.set("X-Emby-Authorization", CustomAuthentication) const url = `${baseUrl.replace(/\/+$/, '')}/Persons/${encodeURIComponent(String(args.name))}${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(baseItemDto, await res.json()) };