import {z} from 'zod' export type GetApiV1VideosIdArgs = {id: string}; export type GetApiV1VideosIdOptions = {baseUrl?: string | undefined, BearerAuth?: string | undefined, fetch?: typeof fetch | undefined}; export const backgroundMusic = z.object({durationMs: z.number().gt(0), name: z.string().nullable(), url: z.string(), volume: z.number().gte(0).lte(1)}); export const chapter = z.object({description: z.string().max(5000), timestampSeconds: z.number().gte(0), title: z.string().min(1).max(255)}); export const exportStatus = z.object({downloadUrl: z.string().nullable(), exportId: z.string(), progress: z.number().gte(0).lte(100).nullable(), status: z.enum(["queued", "running", "completed", "failed"]), updatedAt: z.string()}); export const videoLinks = z.object({embedPage: z.string(), viewPage: z.string()}); export const videoCallToActionOutput = z.object({label: z.string().min(1).max(100), url: z.string()}); export const captionFontFamily = z.string().min(1); export const captionFontSize = z.number().gte(40).lte(200); export const captionFontWeight = z.number().gte(100).lte(1000); export const captionLinesPerBlock = z.number().int().gte(0).lte(3); export const captionPosition = z.object({x: z.number().gte(0).lte(1), y: z.number().gte(0).lte(1)}); export const captionStyle = z.discriminatedUnion("name", [z.object({activeWordTextColor: z.string().optional(), backgroundColor: z.string(), backgroundEnabled: z.boolean().optional(), backgroundPadding: z.number().gte(0).lte(1).optional(), highlightColor: z.string().optional(), highlightMode: z.enum(["text", "background", "fadeRest"]).optional(), name: z.literal("backdrop"), outlineColor: z.string().optional(), outlineEnabled: z.boolean().optional(), shadowColor: z.string().optional(), shadowEnabled: z.boolean().optional(), textCase: z.enum(["original", "uppercase", "lowercase"]).optional(), textColor: z.string(), wordLevelHighlights: z.boolean()}), z.object({backgroundColor: z.string().optional(), backgroundEnabled: z.boolean().optional(), backgroundPadding: z.number().gte(0).lte(1).optional(), highlightColor: z.string(), highlightMode: z.enum(["text", "background", "fadeRest"]).optional(), name: z.literal("highlight"), outlineColor: z.string().optional(), outlineEnabled: z.boolean().optional(), primaryTextColor: z.string(), secondaryTextColor: z.string(), shadowColor: z.string().optional(), shadowEnabled: z.boolean().optional(), textCase: z.enum(["original", "uppercase", "lowercase"]).optional(), wordLevelHighlights: z.boolean().optional()}), z.object({activeWordTextColor: z.string().optional(), backgroundColor: z.string().optional(), backgroundEnabled: z.boolean().optional(), backgroundPadding: z.number().gte(0).lte(1).optional(), highlightColor: z.string(), highlightMode: z.enum(["text", "background", "fadeRest"]).optional(), name: z.literal("mono"), outlineColor: z.string().optional(), outlineEnabled: z.boolean().optional(), shadowColor: z.string().optional(), shadowEnabled: z.boolean().optional(), textCase: z.enum(["original", "uppercase", "lowercase"]).optional(), textColor: z.string(), wordLevelHighlights: z.boolean().optional()}), z.object({activeWordTextColor: z.string().optional(), backgroundColor: z.string().optional(), backgroundEnabled: z.boolean().optional(), backgroundPadding: z.number().gte(0).lte(1).optional(), highlightColor: z.string().optional(), highlightMode: z.enum(["text", "background", "fadeRest"]).optional(), name: z.literal("cannes"), outlineColor: z.string().optional(), outlineEnabled: z.boolean().optional(), shadowColor: z.string(), shadowEnabled: z.boolean().optional(), textCase: z.enum(["original", "uppercase", "lowercase"]).optional(), textColor: z.string(), wordLevelHighlights: z.boolean().optional()}), z.object({activeWordTextColor: z.string().optional(), backgroundColor: z.string().optional(), backgroundEnabled: z.boolean().optional(), backgroundPadding: z.number().gte(0).lte(1).optional(), highlightColor: z.string().optional(), highlightMode: z.enum(["text", "background", "fadeRest"]).optional(), name: z.literal("classic"), outlineColor: z.string(), outlineEnabled: z.boolean().optional(), shadowColor: z.string().optional(), shadowEnabled: z.boolean().optional(), textCase: z.enum(["original", "uppercase", "lowercase"]).optional(), textColor: z.string(), wordLevelHighlights: z.boolean().optional()})]); export const cursorStyle = z.enum(["mac", "macTahoe", "macGoldenGate", "windows", "touch"]); export const cursorSettings = z.object({clickRipple: z.boolean(), hideWhenInactive: z.boolean(), returnToStart: z.boolean(), size: z.number().gte(0.5).lte(6), smoothing: z.boolean(), style: cursorStyle, tilt: z.boolean(), tiltStrength: z.number().gte(0).lte(2)}); export const transitionStyle = z.enum(["smooth", "hard_cut"]); export const videoEyeContact = z.object({cameras: z.number().int().gte(0).lte(9007199254740991), camerasReady: z.number().int().gte(0).lte(9007199254740991), enabled: z.boolean(), status: z.enum(["off", "processing", "ready", "failed"])}); export const overlayAnimationCurve = z.enum(["linear", "smooth", "natural", "slow_down", "accelerate", "elastic", "bounce", "overshoot", "impulse", "swing", "custom", "spring"]); export const overlayAnimationSpringOutput = z.object({damping: z.number().gte(1).lte(300), mass: z.number().gte(0.1).lte(10), stiffness: z.number().gte(1).lte(1000)}); export const overlayAnimationEasing = z.object({bezier: z.array(z.union([z.number().gte(0).lte(1), z.number(), z.number().gte(0).lte(1), z.number()])).optional(), curve: overlayAnimationCurve, intensity: z.number().gte(0).lte(1), spring: overlayAnimationSpringOutput.optional()}); export const overlayAnimationPreset = z.enum(["fade", "slide_up", "slide_down", "slide_left", "slide_right", "mask_up", "mask_down", "grow", "shrink", "blur", "blur_slide_up"]); export const overlayAnimationText = z.object({delayMs: z.number().int().gte(0).lte(2000), order: z.enum(["forward", "backward", "center", "edges", "random"]), smoothing: z.enum(["linear", "smooth", "natural", "slow_down", "accelerate", "elastic", "overshoot", "impulse", "swing"]), unit: z.enum(["letters", "words", "lines"])}); export const overlayAnimationSide = z.object({blur: z.number(), clip: z.boolean(), durationMs: z.number().int().gte(-9007199254740991).lte(9007199254740991), easing: overlayAnimationEasing, moveX: z.number(), moveY: z.number(), opacity: z.number(), preset: overlayAnimationPreset.nullable(), rotate: z.number(), scale: z.number(), text: overlayAnimationText.optional()}); export const overlayAnimation = z.object({intro: overlayAnimationSide.nullable(), motionBlur: z.boolean(), outro: overlayAnimationSide.nullable(), textIntro: overlayAnimationSide.nullable(), textOutro: overlayAnimationSide.nullable()}); export const keystrokeSettings = z.object({alignment: z.enum(["left", "center", "right"]), animation: overlayAnimation, colors: z.object({background: z.string(), keyBackground: z.string(), keyText: z.string()}), displayDurationMs: z.number().int().gte(300).lte(10000), enabled: z.boolean(), filter: z.enum(["shortcuts", "all"]), labels: z.enum(["mac", "windows"]).optional(), position: z.object({x: z.number().gte(0).lte(1), y: z.number().gte(0).lte(1)}), size: z.number().gte(0.5).lte(4), style: z.enum(["keycap", "pill"]), typing: z.enum(["keys", "words"]).optional()}); export const videoSettingsLinkScope = z.enum(["public", "private", "org", "password", "embedonly"]); export const videoSettings = z.object({allowedEmbedDomains: z.array(z.string()), callToAction: videoCallToActionOutput.nullable(), callToActionsHidden: z.boolean(), captionFontFamily: captionFontFamily, captionFontSize: captionFontSize, captionFontWeight: captionFontWeight, captionGrouping: z.enum(["chunked", "singleWord"]), captionLinesPerBlock: captionLinesPerBlock, captionPosition: captionPosition.nullable(), captionSize: z.enum(["small", "medium", "large"]), captionStyle: captionStyle, captionsDefaultEnabled: z.boolean(), commentEmailsEnabled: z.boolean(), commentsEnabled: z.boolean(), creatorEnabled: z.boolean(), cursor: cursorSettings, customThumbnailURL: z.string().nullable(), defaultClipTransition: transitionStyle, defaultPlaybackRate: z.number().gte(0.5).lte(2), downloadsEnabled: z.boolean(), eyeContact: videoEyeContact.optional(), keystrokes: keystrokeSettings.optional(), layoutAnimationStyle: z.enum(["gentlest", "gentle", "relaxed", "smooth", "moderate", "brisk", "focused", "snappy", "punchy", "snappiest", "custom"]), linkScope: videoSettingsLinkScope, microphoneVolume: z.number().gte(0).lte(2), motionBlur: z.boolean(), motionBlurAmount: z.number().optional(), publishDateEnabled: z.boolean(), rawDownloadsEnabled: z.boolean(), searchEngineIndexingEnabled: z.boolean(), secondaryCallToAction: videoCallToActionOutput.nullable(), shrinkCameraDuringZooms: z.boolean(), studioSound: z.boolean(), studioSoundLevel: z.enum(["off", "low", "high"]), subtitlesEnabled: z.boolean(), systemAudioVolume: z.number().gte(0).lte(2), thumbnailInpointMs: z.number().int().gte(0).lte(9007199254740991).nullable(), transcriptsEnabled: z.boolean(), viewCountEnabled: z.boolean(), workspaceCallToAction: videoCallToActionOutput.nullable(), workspaceSecondaryCallToAction: videoCallToActionOutput.nullable(), zoomAnimationStyle: z.enum(["gentlest", "gentle", "relaxed", "smooth", "moderate", "brisk", "focused", "snappy", "punchy", "snappiest", "custom"])}); export const thumbnailFormats = z.object({gif: z.string().optional(), jpg: z.string().optional(), mp4: z.string().optional(), webp: z.string().optional()}); export const thumbnails = z.object({large: thumbnailFormats.optional(), medium: thumbnailFormats.optional(), small: thumbnailFormats.optional(), xl: thumbnailFormats.optional()}); export const sentence = z.object({endSeconds: z.number().gte(0), startSeconds: z.number().gte(0), text: z.string()}); export const transcript = z.object({language: z.string().nullable(), sentences: z.array(sentence).nullable(), status: z.enum(["ready", "processing", "failed"]), text: z.string().nullable()}); export const videoDetail = z.object({aspectRatio: z.string(), autoRatio: z.boolean(), backgroundMusic: backgroundMusic.nullable(), chapters: z.array(chapter), clipIds: z.array(z.string()), createdAt: z.string(), description: z.string().max(5000), dimensions: z.object({height: z.number(), width: z.number()}), durationSeconds: z.number().gte(0), exports: z.array(exportStatus), id: z.string(), links: videoLinks, name: z.string().min(1).max(255), playlistIds: z.array(z.string()), settings: videoSettings, thumbnails: thumbnails, transcript: transcript, updatedAt: z.string(), views: z.number().int().gte(0).lte(9007199254740991)}); export const getApiV1VideosIdResponse = z.object({video: videoDetail}); 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 video information * * GET /v1/videos/{id} */ export const getApiV1VideosId = async (args: GetApiV1VideosIdArgs, options?: GetApiV1VideosIdOptions) => { const {baseUrl = "https://api.tella.com", fetch: fetchFn = fetch, BearerAuth} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('accept', "application/json") if (BearerAuth !== undefined) headers.set('authorization', `Bearer ${BearerAuth}`) const url = `${baseUrl.replace(/\/+$/, '')}/v1/videos/${encodeURIComponent(String(args.id))}${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(getApiV1VideosIdResponse, await res.json()) };