import {z} from 'zod' export type GetApiMeOndemandPagesArgs = {direction?: ('asc' | 'desc') | undefined, filter?: ('film' | 'series') | undefined, page?: number | undefined, per_page?: number | undefined, sort?: ('added' | 'alphabetical' | 'date' | 'modified_time' | 'name' | 'publish.time' | 'rating') | undefined}; export type GetApiMeOndemandPagesOptions = {baseUrl?: string | undefined, oauth2?: string | undefined, fetch?: typeof fetch | undefined}; export const picture = z.object({active: z.boolean(), link: z.string().optional(), resource_key: z.string(), sizes: z.array(z.object({height: z.number().nullable(), link: z.string(), link_with_play_button: z.string().optional(), width: z.number()})), type: z.enum(["caution", "custom", "default"]), uri: z.string()}); export const category = z.object({icon: picture.optional(), last_video_featured_time: z.string(), link: z.string(), metadata: z.object({connections: z.object({channels: z.object({options: z.array(z.string()), total: z.number(), uri: z.string()}), groups: z.object({options: z.array(z.string()), total: z.number(), uri: z.string()}), users: z.object({options: z.array(z.string()), total: z.number(), uri: z.string()}), videos: z.object({options: z.array(z.string()), total: z.number(), uri: z.string()})}), interactions: z.object({follow: z.object({added: z.boolean(), added_time: z.string().nullable(), uri: z.string()})})}), name: z.string(), parent: z.object({link: z.string(), name: z.string(), uri: z.string()}).nullable(), pictures: picture, resource_key: z.string(), subcategories: z.array(z.object({link: z.string(), name: z.string(), uri: z.string()})).optional(), top_level: z.boolean(), uri: z.string()}); export const embedSettings = z.object({buttons: z.object({embed: z.boolean(), fullscreen: z.boolean(), hd: z.boolean(), like: z.boolean(), scaling: z.boolean(), share: z.boolean(), watchlater: z.boolean()}), color: z.string(), logos: z.object({custom: z.object({active: z.boolean(), link: z.string(), sticky: z.boolean()}), vimeo: z.boolean()}), playbar: z.boolean(), speed: z.boolean(), title: z.object({name: z.enum(["hide", "show", "user"]), owner: z.enum(["hide", "show", "user"]), portrait: z.enum(["hide", "show", "user"])}), uri: z.string().optional(), volume: z.boolean()}); export const user = z.object({account: z.enum(["basic", "business", "live_business", "live_premium", "live_pro", "plus", "pro", "pro_unlimited", "producer"]), bio: z.string().nullable(), content_filter: z.array(z.string()).optional(), created_time: z.string(), email: z.string().optional(), link: z.string(), location: z.string().nullable(), metadata: z.object({connections: z.object({albums: z.object({options: z.array(z.string()), total: z.number(), uri: z.string()}), appearances: z.object({options: z.array(z.string()), total: z.number(), uri: z.string()}), block: z.object({options: z.array(z.string()), total: z.number(), uri: z.string()}), categories: z.object({options: z.array(z.string()), total: z.number(), uri: z.string()}), channels: z.object({options: z.array(z.string()), total: z.number(), uri: z.string()}), feed: z.object({options: z.array(z.string()), uri: z.string()}), folders: z.object({options: z.array(z.string()), total: z.number(), uri: z.string()}), followers: z.object({options: z.array(z.string()), total: z.number(), uri: z.string()}), following: z.object({options: z.array(z.string()), total: z.number(), uri: z.string()}), groups: z.object({options: z.array(z.string()), total: z.number(), uri: z.string()}), likes: z.object({options: z.array(z.string()), total: z.number(), uri: z.string()}), moderated_channels: z.object({options: z.array(z.string()), total: z.number(), uri: z.string()}), pictures: z.object({options: z.array(z.string()), total: z.number(), uri: z.string()}), portfolios: z.object({options: z.array(z.string()), total: z.number(), uri: z.string()}), recommended_channels: z.object({options: z.array(z.string()), total: z.number(), uri: z.string()}), recommended_users: z.object({options: z.array(z.string()), total: z.number(), uri: z.string()}), shared: z.object({options: z.array(z.string()), total: z.number(), uri: z.string()}), videos: z.object({options: z.array(z.string()), total: z.number(), uri: z.string()}), watched_videos: z.object({options: z.array(z.string()), total: z.number(), uri: z.string()}), watchlater: z.object({options: z.array(z.string()), total: z.number(), uri: z.string()})}), interactions: z.object({add_privacy_user: z.object({options: z.array(z.string()).optional(), uri: z.string().optional()}).optional(), block: z.object({added: z.boolean(), added_time: z.string().nullable(), options: z.array(z.string()), uri: z.string()}), follow: z.object({added: z.boolean(), options: z.array(z.string()), uri: z.string()}), report: z.object({options: z.array(z.string()), reason: z.array(z.string()), uri: z.string()})})}), name: z.string(), pictures: picture, preferences: z.object({videos: z.object({privacy: z.object({add: z.boolean().optional(), comments: z.enum(["anybody", "contacts", "nobody"]).optional(), download: z.boolean().optional(), embed: z.enum(["private", "public", "whitelist"]).optional(), view: z.enum(["anybody", "contacts", "disable", "nobody", "password", "unlisted", "users"]).optional()}).optional()}).optional()}).optional(), resource_key: z.string(), upload_quota: z.object({lifetime: z.object({free: z.number().nullable(), max: z.number().nullable(), used: z.number().nullable()}), periodic: z.object({free: z.number().nullable(), max: z.number().nullable(), reset_date: z.string().nullable(), used: z.number().nullable()}), space: z.object({free: z.number(), max: z.number().nullable(), showing: z.enum(["lifetime", "periodic"]), used: z.number()})}), uri: z.string(), websites: z.array(z.object({description: z.string().nullable(), link: z.string(), name: z.string().nullable()}))}); export const project = z.object({created_time: z.string(), metadata: z.object({connections: z.object({videos: z.object({options: z.array(z.string()), total: z.number(), uri: z.string()})})}), modified_time: z.string(), name: z.string(), resource_key: z.string(), uri: z.string(), user: user}); export const tag = z.object({canonical: z.string(), metadata: z.object({connections: z.object({videos: z.object({options: z.array(z.string()), total: z.number(), uri: z.string()})})}), name: z.string(), resource_key: z.string(), uri: z.string()}); export const video = z.object({categories: z.array(category), content_rating: z.array(z.string()), context: z.object({action: z.enum(["Added to", "Appearance by", "Liked by", "Uploaded by"]), resource: z.object({}).nullable(), resource_type: z.string()}), created_time: z.string(), description: z.string().nullable(), duration: z.number(), embed: embedSettings, height: z.number(), language: z.string().nullable(), last_user_action_event_date: z.string().nullable().optional(), license: z.enum(["by", "by-nc", "by-nc-nd", "by-nc-sa", "by-nd", "by-sa", "cc0"]), link: z.string(), metadata: z.object({connections: z.object({available_albums: z.object({options: z.array(z.string()), total: z.number(), uri: z.string()}), available_channels: z.object({options: z.array(z.string()), total: z.number(), uri: z.string()}), comments: z.object({options: z.array(z.string()), total: z.number(), uri: z.string()}), credits: z.object({options: z.array(z.string()).optional(), total: z.number().optional(), uri: z.string().optional()}).nullable(), likes: z.object({options: z.array(z.string()), total: z.number(), uri: z.string()}), ondemand: z.object({options: z.array(z.string()), resource_key: z.string(), uri: z.string()}), pictures: z.object({options: z.array(z.string()), total: z.number(), uri: z.string()}), playback: z.object({options: z.array(z.string()), uri: z.string()}), recommendations: z.object({options: z.array(z.string()).optional(), uri: z.string().optional()}).nullable(), related: z.object({options: z.array(z.string()).optional(), uri: z.string().optional()}).nullable(), season: z.object({name: z.string(), options: z.array(z.string()), uri: z.string()}), texttracks: z.object({options: z.array(z.string()), total: z.number(), uri: z.string()}), trailer: z.object({options: z.array(z.string()), resource_key: z.string(), uri: z.string()}), users_with_access: z.object({options: z.array(z.string()), total: z.number(), uri: z.string()}), versions: z.object({current_uri: z.string().optional(), options: z.array(z.string()), resource_key: z.string().optional(), total: z.number(), uri: z.string()})}), interactions: z.object({buy: z.object({currency: z.string().nullable(), display_price: z.string().nullable(), download: z.enum(["available", "purchased", "restricted", "unavailable"]), drm: z.boolean(), link: z.string().nullable(), price: z.number().nullable(), purchase_time: z.string().nullable(), stream: z.enum(["available", "purchased", "restricted", "unavailable"]), uri: z.string().nullable()}).nullable(), channel: z.object({options: z.array(z.string()), uri: z.string()}).nullable(), like: z.object({added: z.boolean(), added_time: z.string(), options: z.array(z.string()), uri: z.string()}), rent: z.object({currency: z.string().nullable(), display_price: z.string().nullable(), drm: z.boolean(), expires_time: z.string().nullable(), link: z.string().nullable(), price: z.number().nullable(), purchase_time: z.string().nullable(), stream: z.enum(["available", "purchased", "restricted", "unavailable"]), uri: z.string().nullable()}).nullable(), report: z.object({options: z.array(z.string()), reason: z.array(z.string()), uri: z.string()}), subscribe: z.object({drm: z.boolean().optional(), expires_time: z.string().optional(), purchase_time: z.string().optional(), stream: z.string().optional()}).nullable().optional(), watched: z.object({added: z.boolean(), added_time: z.string(), options: z.array(z.string()), uri: z.string()}), watchlater: z.object({added: z.boolean(), added_time: z.string(), options: z.array(z.string()), uri: z.string()})})}), modified_time: z.string(), name: z.string(), parent_folder: project.nullable().optional(), password: z.string().optional(), pictures: picture, privacy: z.object({add: z.boolean(), comments: z.enum(["anybody", "contacts", "nobody"]), download: z.boolean(), embed: z.enum(["private", "public"]), view: z.enum(["anybody", "contacts", "disable", "nobody", "password", "unlisted", "users"])}), release_time: z.string(), resource_key: z.string(), spatial: z.object({director_timeline: z.array(z.object({pitch: z.number().optional(), roll: z.number().optional(), time_code: z.number().optional(), yaw: z.number().optional()})), field_of_view: z.number().nullable(), projection: z.enum(["cubical", "cylindrical", "dome", "equirectangular", "pyramid"]).nullable(), stereo_format: z.enum(["left-right", "mono", "top-bottom"]).nullable()}), stats: z.object({plays: z.number().nullable()}), status: z.enum(["available", "quota_exceeded", "total_cap_exceeded", "transcode_starting", "transcoding", "transcoding_error", "unavailable", "uploading", "uploading_error"]).nullable(), tags: z.array(tag), transcode: z.object({status: z.enum(["complete", "error", "in_progress"]).optional()}).nullable(), type: z.enum(["live", "stock", "video"]), upload: z.object({approach: z.enum(["post", "pull", "streaming", "tus"]).optional(), complete_uri: z.string().optional(), form: z.string().optional(), link: z.string().optional(), redirect_url: z.string().optional(), size: z.number().optional(), status: z.enum(["complete", "error", "in_progress"]), upload_link: z.string().optional()}).nullable(), uri: z.string(), user: user.nullable(), width: z.number()}); export const onDemandGenre = z.object({canonical: z.string(), interactions: z.object({page: z.object({added: z.boolean(), options: z.array(z.string()), uri: z.string()})}), link: z.string(), metadata: z.object({connections: z.object({pages: z.object({options: z.array(z.string()), uri: z.string()})})}), name: z.string(), uri: z.string()}); export const purchaseInteraction = z.object({buy: z.object({drm: z.boolean().optional()}).nullable().optional(), rent: z.object({}).nullable().optional(), subscribe: z.object({drm: z.boolean().optional(), expires_time: z.string().nullable().optional(), link: z.string().nullable().optional(), purchase_time: z.string().nullable().optional(), stream: z.enum(["available", "purchased", "restricted", "unavailable"]).optional(), uri: z.string().nullable().optional()}).nullable().optional()}); export const onDemandPage = z.object({background: picture.nullable(), colors: z.object({primary: z.string(), secondary: z.string()}), content_rating: z.array(z.string()), created_time: z.string().optional(), description: z.string().nullable(), domain_link: z.string().nullable(), episodes: z.object({buy: z.object({active: z.boolean(), price: z.number().nullable()}), rent: z.object({active: z.boolean(), period: z.enum(["1 day", "1 month", "1 week", "1 year", "2 day", "24 hour", "3 day", "3 month", "30 day", "48 hour", "6 month", "60 day", "7 day", "72 hour"]).nullable(), price: z.number().nullable()})}), film: video.optional(), genres: z.array(onDemandGenre), link: z.string(), metadata: z.object({connections: z.object({metadata: z.object({connections: z.object({comments: z.object({options: z.array(z.string()), total: z.number(), uri: z.string()}), genres: z.object({options: z.array(z.string()), total: z.number(), uri: z.string()}), likes: z.object({options: z.array(z.string()), total: z.number(), uri: z.string()}), pictures: z.object({options: z.array(z.string()), total: z.number(), uri: z.string()}), seasons: z.object({options: z.array(z.string()), total: z.number(), uri: z.string()}), videos: z.object({extra_total: z.number(), main_total: z.number(), options: z.array(z.string()), total: z.number(), uri: z.string(), viewable_total: z.number()})})})}), interactions: purchaseInteraction}), modified_time: z.string().optional(), name: z.string(), pictures: picture.nullable(), preorder: z.object({active: z.boolean(), cancel_time: z.string(), publish_time: z.string(), time: z.string()}), published: z.object({enabled: z.boolean(), time: z.string()}), rating: z.number().nullable(), resource_key: z.string(), sku: z.string().nullable().optional(), subscription: z.object({active: z.boolean(), link: z.string().nullable(), period: z.string().optional(), price: z.object({})}).nullable(), theme: z.string(), thumbnail: picture.nullable(), trailer: video.nullable(), type: z.enum(["film", "series"]), uri: z.string(), user: user.nullable()}); export const getApiMeOndemandPagesResponse = z.array(onDemandPage); 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 all the On Demand pages of a user * * GET /me/ondemand/pages */ export const getApiMeOndemandPages = async (args: GetApiMeOndemandPagesArgs, options?: GetApiMeOndemandPagesOptions) => { const {baseUrl = "https://api.vimeo.com", fetch: fetchFn = fetch, oauth2} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('accept', "application/vnd.vimeo.ondemand.page+json") if (args.direction != null) query.append("direction", String(args.direction)) if (args.filter != null) query.append("filter", String(args.filter)) if (args.page != null) query.append("page", String(args.page)) if (args.per_page != null) query.append("per_page", String(args.per_page)) if (args.sort != null) query.append("sort", String(args.sort)) if (oauth2 !== undefined) headers.set('authorization', `Bearer ${oauth2}`) const url = `${baseUrl.replace(/\/+$/, '')}/me/ondemand/pages${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(getApiMeOndemandPagesResponse, await res.json()) };