import {z} from 'zod' export type GetApiBrandIdPageAuditsPageAuditIdArgs = {brand_id: number, page_audit_id: string}; export type GetApiBrandIdPageAuditsPageAuditIdOptions = {baseUrl?: string | undefined, HTTPBearer?: string | undefined, fetch?: typeof fetch | undefined}; export const pageTestCheckResult = z.object({section: z.enum(["access_controls", "content_delivery", "content_quality"]), check_id: z.enum(["robots_txt_present", "robots_txt_critical_allowed", "robots_txt_explicit_allow", "network_bots_allowed", "network_bot_blocking_explicit", "page_works_without_js", "page_loads_in_under_5s", "meaningful_title_and_description", "missing_javascript", "substantial_image_content", "mostly_video_content", "page_length_ok", "chatgpt_prerendered_content"]), check_outcome: z.enum(["passed", "failed", "skipped"]), detail: z.string().nullable().optional(), help_text: z.string().nullable().optional(), check_score: z.number().int(), check_description: z.string()}); export const userAgent = z.object({identifier: z.string(), sample_user_agent: z.string(), owner: z.enum(["Google", "Bing", "Perplexity", "OpenAI", "Amazon", "Apple", "CommonCrawl", "DuckDuckGo", "Anthropic", "Meta"]), purposes: z.array(z.enum(["Search Indexing", "Training Data Collection", "Retrieval", "Other"])), critical: z.boolean().optional(), collects_training_data: z.boolean()}); export const assistant = z.object({name: z.string(), does_training: z.boolean(), does_retrieval: z.boolean(), does_search_indexing: z.boolean(), can_cite: z.boolean(), search_agents: z.array(userAgent).optional(), retrieval_agents: z.array(userAgent).optional(), training_agents: z.array(userAgent).optional()}); export const assistantStatus = z.object({assistant: assistant, trainable: z.enum(["ok", "failed", "not_applicable", "unknown"]), findable: z.enum(["ok", "failed", "not_applicable", "unknown"]), retrievable: z.enum(["ok", "failed", "not_applicable", "unknown"]), sample_title: z.string().nullable(), sample_description: z.string().nullable(), sample_final_url: z.string().nullable(), can_retrieve: z.boolean(), retrieval_response_time: z.number().nullable(), retrieval_block_reason: z.string().nullable()}); export const screenshotVsPage = z.object({screenshot_is_representative: z.boolean(), difference_explanation: z.string().nullable().optional(), missing_content_from_markdown: z.array(z.string()).optional(), importance_of_missing_content: z.enum(["critical", "important", "minor", "irrelevant"]).optional()}); export const intentVsPage = z.object({intent_of_page: z.string().nullable().optional(), markdown_respresents_intent: z.boolean(), difference_explanation: z.string().nullable().optional()}); export const questionAnswer = z.object({question: z.string(), answer: z.string(), rationale: z.string()}); export const pageTestResult = z.object({version: z.union([z.literal(1), z.literal(2)]).optional(), checks: z.array(pageTestCheckResult).optional(), visitor_preview_image_url: z.string().nullable().optional(), ai_preview_markdown: z.string().nullable().optional(), title: z.string().nullable().optional(), description: z.string().nullable().optional(), final_url: z.string().nullable().optional(), assistant_statuses: z.array(assistantStatus).optional(), screenshot_vs_page: screenshotVsPage.nullable().optional(), intent_vs_page: intentVsPage.nullable().optional(), key_question_answers: z.array(questionAnswer).optional(), access_controls_score: z.number().int().nullable(), content_delivery_score: z.number().int().nullable(), content_quality_score: z.number().int().nullable(), access_controls_succeeded: z.number().int(), content_delivery_succeeded: z.number().int(), content_quality_succeeded: z.number().int(), access_controls_failed: z.number().int(), content_delivery_failed: z.number().int(), content_quality_failed: z.number().int(), access_controls_total: z.number().int(), content_delivery_total: z.number().int(), content_quality_total: z.number().int()}); export const pageTestResponse = z.object({url: z.string(), status: z.enum(["pending", "running", "completed", "failed"]), result: pageTestResult.nullable(), created_at: z.string(), updated_at: z.string()}); 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 Page Audit * * GET /{brand_id}/page-audits/{page_audit_id} */ export const getApiBrandIdPageAuditsPageAuditId = async (args: GetApiBrandIdPageAuditsPageAuditIdArgs, options?: GetApiBrandIdPageAuditsPageAuditIdOptions) => { const {baseUrl = "https://api.scrunchai.com/v1", fetch: fetchFn = fetch, HTTPBearer} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('accept', "application/json") if (HTTPBearer !== undefined) headers.set('authorization', `Bearer ${HTTPBearer}`) const url = `${baseUrl.replace(/\/+$/, '')}/${encodeURIComponent(String(args.brand_id))}/page-audits/${encodeURIComponent(String(args.page_audit_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(pageTestResponse, await res.json()) };