import {z} from 'zod' export type GetApiV1PublicAppsSlugConfigArgs = {slug: string}; export type GetApiV1PublicAppsSlugConfigOptions = {baseUrl?: string | undefined, fetch?: typeof fetch | undefined}; export const sectionConfig = z.object({section_id: z.string().optional(), type: z.string(), props: z.record(z.string(), z.unknown()).optional(), order: z.number().int().nullable().optional()}); export const pageMeta = z.object({title: z.string(), description: z.string().nullable().optional(), logo_url: z.string().nullable().optional(), favicon_url: z.string().nullable().optional(), indexable: z.boolean().nullable().optional()}); export const heroConfig = z.object({headline: z.string(), subheadline: z.string().nullable().optional(), background_type: z.enum(["image", "video", "gradient", "solid"]).optional(), background_url: z.string().nullable().optional(), background_color: z.string().nullable().optional(), text_color: z.string().optional(), logo_url: z.string().nullable().optional(), height: z.string().optional(), cta_label: z.string().nullable().optional(), cta_url: z.string().nullable().optional()}); export const themeConfig = z.object({primary_color: z.string().optional(), secondary_color: z.string().nullable().optional(), font_family: z.string().optional(), background_color: z.string().optional(), text_color: z.string().optional(), heading_font_family: z.string().nullable().optional(), surface_color: z.string().nullable().optional(), muted_color: z.string().nullable().optional(), border_color: z.string().nullable().optional(), border_radius: z.string().nullable().optional(), card_style: z.string().nullable().optional(), card_hover_effect: z.string().nullable().optional()}); export const structuredDataConfig = z.object({type: z.string().optional(), additional_properties: z.record(z.string(), z.unknown()).optional()}); export const sEOConfig = z.object({meta_title: z.string().max(60).nullable().optional(), meta_description: z.string().max(160).nullable().optional(), keywords: z.array(z.string()).optional(), og_image_url: z.string().nullable().optional(), og_image_alt: z.string().max(200).nullable().optional(), og_type: z.string().optional(), twitter_card: z.string().optional(), twitter_site: z.string().nullable().optional(), twitter_creator: z.string().nullable().optional(), robots: z.string().optional(), canonical_url: z.string().nullable().optional(), site_name: z.string().optional(), author: z.string().nullable().optional(), locale: z.string().optional(), logo_url: z.string().nullable().optional(), favicon_url: z.string().nullable().optional(), structured_data: structuredDataConfig.optional()}); export const statItem = z.object({label: z.string(), value: z.string()}); export const layoutConfig = z.object({mode: z.string().optional(), columns: z.number().int().gte(1).lte(6).optional(), gap: z.string().optional(), full_width: z.boolean().optional()}); export const fieldFormatType = z.enum(["text", "image", "date", "number", "url", "boolean", "array", "object"]); export const fieldFormatOptions = z.object({label: z.string().nullable().optional(), show_empty: z.boolean().optional(), truncate_chars: z.number().int().gte(1).nullable().optional(), width: z.number().int().gte(1).nullable().optional(), height: z.number().int().gte(1).nullable().optional(), lazy_load: z.boolean().optional(), aspect_ratio: z.string().nullable().optional(), object_fit: z.string().optional(), date_format: z.string().optional(), decimals: z.number().int().gte(0).nullable().optional(), prefix: z.string().nullable().optional(), suffix: z.string().nullable().optional(), open_in_new_tab: z.boolean().optional(), show_domain: z.boolean().optional(), true_label: z.string().optional(), false_label: z.string().optional(), separator: z.string().optional(), max_items: z.number().int().gte(1).nullable().optional()}); export const fieldConfig = z.object({format: fieldFormatType, format_options: fieldFormatOptions.optional()}); export const featuredGalleryConfigOutput = z.object({enabled: z.boolean().optional(), title: z.string().optional(), retriever_id: z.string().nullable().optional(), public_name: z.string().nullable().optional(), default_inputs: z.record(z.string(), z.unknown()).optional(), layout: layoutConfig.optional(), field_config: z.record(z.string(), fieldConfig).optional()}); export const markdownContent = z.object({title: z.string().min(1).max(200), content: z.string().min(1).max(50000)}); export const retrieverInputSchemaFieldType = z.enum(["string", "number", "integer", "float", "boolean", "object", "array", "date", "datetime", "text", "image", "audio", "video", "pdf", "excel", "document_reference"]); export const retrieverInputSchemaFieldOutput: z.ZodType = z.object({type: retrieverInputSchemaFieldType, default: z.unknown(), items: z.lazy(() => retrieverInputSchemaFieldOutput.nullable().optional()), properties: z.record(z.string(), z.lazy(() => retrieverInputSchemaFieldOutput)).nullable().optional(), examples: z.array(z.unknown()).nullable().optional(), description: z.string().nullable().optional(), enum: z.array(z.unknown()).nullable().optional(), required: z.boolean().nullable().optional()}).and(z.record(z.string(), z.unknown())); export const inputRenderingConfigOutput = z.object({field_name: z.string(), field_schema: retrieverInputSchemaFieldOutput, input_type: z.string().optional(), label: z.string(), placeholder: z.string().nullable().optional(), helper_text: z.string().nullable().optional(), suggestions: z.array(z.string()).nullable().optional(), required: z.boolean().optional(), order: z.number().int().gte(0).optional()}); export const resultCardProperties = z.object({layout: z.string().optional(), show_thumbnail: z.boolean().optional(), thumbnail_aspect_ratio: z.string().optional(), thumbnail_fit: z.string().optional(), show_score: z.boolean().optional(), truncate_title: z.number().int().gte(1).nullable().optional(), truncate_description: z.number().int().gte(1).nullable().optional(), field_order: z.array(z.string()).optional(), show_find_similar: z.boolean().optional(), card_click_action: z.string().optional(), thumbnail_field: z.string().nullable().optional(), title_field: z.string().nullable().optional(), card_fields: z.array(z.string()).nullable().optional(), modal_fields: z.array(z.string()).nullable().optional(), card_style: z.string().nullable().optional()}); export const componentsConfig = z.object({show_hero: z.boolean().optional(), show_search: z.boolean().optional(), show_filters: z.boolean().optional(), show_results_header: z.boolean().optional(), result_layout: z.string().optional(), result_card: resultCardProperties.nullable().optional()}); export const customCTA = z.object({label: z.string().min(1).max(50), markdown_content: z.string().min(1).max(50000)}); export const externalLink = z.object({name: z.string().min(1).max(100), url: z.string().min(1).max(2048)}); export const displayConfigOutput = z.object({title: z.string(), description: z.string().nullable().optional(), logo_url: z.string().nullable().optional(), icon_base64: z.string().max(300000).nullable().optional(), seo: sEOConfig.nullable().optional(), markdowns: z.array(markdownContent).optional(), theme: themeConfig.optional(), inputs: z.array(inputRenderingConfigOutput), layout: layoutConfig.optional(), exposed_fields: z.array(z.string()), components: componentsConfig.optional(), field_config: z.record(z.string(), fieldConfig).optional(), custom_cta: customCTA.nullable().optional(), external_links: z.array(externalLink).optional(), template_type: z.string().nullable().optional(), field_mappings: z.record(z.string(), z.string()).nullable().optional(), extensions: z.record(z.string(), z.unknown()).nullable().optional(), retriever_config: z.record(z.string(), z.unknown()).nullable().optional()}).and(z.record(z.string(), z.unknown())); export const pageTabOutput = z.object({tab_id: z.string(), label: z.string(), retriever_id: z.string().nullable().optional(), public_name: z.string().nullable().optional(), description: z.string().nullable().optional(), display_config: displayConfigOutput}); export const publicAppConfigResponse = z.object({slug: z.string(), template: z.string(), sections: z.array(sectionConfig).optional(), custom_html: z.string().nullable().optional(), bundle_url: z.string().nullable().optional(), meta: pageMeta, hero: heroConfig.nullable(), theme: themeConfig, seo: sEOConfig.nullable(), stats: z.array(statItem), featured_gallery: featuredGalleryConfigOutput.nullable(), tabs: z.array(pageTabOutput), is_active: z.boolean(), password_protected: z.boolean()}); 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 public App config * * GET /v1/public/apps/{slug}/config */ export const getApiV1PublicAppsSlugConfig = async (args: GetApiV1PublicAppsSlugConfigArgs, options?: GetApiV1PublicAppsSlugConfigOptions) => { const {baseUrl = "https://api.mixpeek.com", fetch: fetchFn = fetch} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('accept', "application/json") const url = `${baseUrl.replace(/\/+$/, '')}/v1/public/apps/${encodeURIComponent(String(args.slug))}/config${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(publicAppConfigResponse, await res.json()) };