import {z} from 'zod' export type GetApiV1CategoriesArgs = {key: string, locale?: string | undefined, type?: ('featured' | 'emoji' | 'trending') | undefined, contentfilter?: ('off' | 'low' | 'medium' | 'high') | undefined, anon_id?: string | undefined}; export type GetApiV1CategoriesOptions = {baseUrl?: string | undefined, fetch?: typeof fetch | undefined}; export const categoryObject = z.object({searchterm: z.string(), path: z.string(), image: z.string(), name: z.string()}); export const categoriesResult = z.object({tags: z.array(categoryObject)}); 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 a json object containing a list of GIF categories associated with the provided type. Each category will include a corresponding search URL to be used if the user clicks on the category. The search URL will include the apikey, anonymous id, and locale that were used on the original call to the categories endpoint. * * GET /v1/categories */ export const getApiV1Categories = async (args: GetApiV1CategoriesArgs, options?: GetApiV1CategoriesOptions) => { const {baseUrl = "https://g.tenor.com", fetch: fetchFn = fetch} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('accept', "application/json") if (args.key != null) query.append("key", String(args.key)) if (args.locale != null) query.append("locale", String(args.locale)) if (args.type != null) query.append("type", String(args.type)) if (args.contentfilter != null) query.append("contentfilter", String(args.contentfilter)) if (args.anon_id != null) query.append("anon_id", String(args.anon_id)) const url = `${baseUrl.replace(/\/+$/, '')}/v1/categories${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(categoriesResult, await res.json()) };