export interface SeoEditorVariable { name: string; label: string; example: string; } export interface SeoEditorTaxonomy { slug: string; label: string; hierarchical: boolean; restBase: string; /** The meta key of the primary term, empty for flat taxonomies. */ primaryKey: string; } export interface SeoEditorKeys { title: string; description: string; focusKeywords: string; robots: string; advancedRobots: string; canonical: string; breadcrumbTitle: string; pillar: string; ogTitle: string; ogDescription: string; ogImage: string; ogImageId: string; ogOverlay: string; twTitle: string; twDescription: string; twImage: string; twImageId: string; twCustom: string; score: string; excludeSitemap: string; brand: string; gtin: string; mpn: string; isbn: string; condition: string; availability: string; schema: string; schemaCustom: string; /** An author's own profiles: Facebook, X username, the others a line each. */ authorFacebook: string; authorX: string; authorProfiles: string; } /** What WooCommerce already knows about the product, shown as placeholders. */ export interface SeoEditorProduct { brand: string; gtin: string; /** The saved type and price: a variable product's price lives in its variations. */ type: string; price: string; reviews: number; /** The category a product falls into when none is picked. */ defaultCategory: number; /** The taxonomy brands are picked in, empty without one. */ brandTaxonomy: string; } /** The catalog fix from the product screen, with what the agent charges per topic. */ export interface SeoEditorCatalogFix { creditsPerTopic: number; } /** "Fix with AI" in place, with what the agent charges for a page's snippet and for its content. */ export interface SeoEditorPostFix { credits: number; contentCredits: number; /** What a set of internal link suggestions costs, and a FAQ written from the page. */ linksCredits: number; faqCredits: number; /** A slug change on a published post redirects the old address, so the fix may take it. */ autoRedirects: boolean; } /** The AI buttons spend the merchant's credits: who may press them, and what already ran here today. */ export interface SeoEditorAi { /** The user holds "AI with credits". */ allowed: boolean; /** The actions that spent credits on this post today (see lib/ai-runs). */ ranToday: string[]; } /** The screen the panel sits on: the block editor, or a classic form. */ export type SeoEditorScreen = 'block' | 'classic' | 'term' | 'user'; /** What the panel edits. */ export type SeoEditorObject = 'post' | 'term' | 'user'; /** What Recomaze_Seo_Editor hands to the panel in window.recomazeSeoEditor. */ export interface SeoEditorEnv { screen: SeoEditorScreen; object: SeoEditorObject; /** Post type, taxonomy, or "user". */ type: string; /** Singular label of the type: "Product", "Category", "Author". */ typeLabel: string; siteName: string; siteUrl: string; /** The post's language from Polylang or WPML, empty without one. */ language?: string; /** The site's locale: the analysis falls back on it when the text does not tell. */ siteLanguage?: string; /** The taxonomy the settings pick for the primary term, empty for the first with terms. */ primaryTaxonomy?: string; /** Brand taxonomies: hierarchical, but never where an item is filed. */ brandTaxonomies?: string[]; /** The user may see Search Console data: the "What people searched for" ideas. */ searchIdeas?: boolean; /** The plugin's admin page, where the Copilot lives. */ appUrl: string; /** A published post's changed slug leaves a redirect behind. */ autoRedirects: boolean; /** Advanced → Redirect is offered: the module is on and the user may use it. */ postRedirects?: boolean; separator: string; templates: { title: string; description: string }; /** The site-wide robots limits a page without its own prints. */ robotsLimits?: Record; /** The card X shows, from Titles & meta: summary_large_image or summary. */ twitterCard?: string; noindexByDefault: boolean; variables: SeoEditorVariable[]; robotsTokens: string[]; /** The schema.org business types Local SEO offers, for the schema forms. */ businessTypes: string[]; /** Taxonomies of the post type; empty for terms and users. */ taxonomies: SeoEditorTaxonomy[]; outputEnabled: boolean; conflicts: string[]; /** The meta keys this object carries; the panel shows a field only for those. */ fields: string[]; keys: SeoEditorKeys; /** The object being edited; classic screens also get its saved fields, having no editor store to read. */ objectId: number; objectLink: string; objectSlug: string; initialMeta: Record | null; product: SeoEditorProduct | null; /** Set on products the user may edit: the title and description rewrite from the panel. */ catalogFix: SeoEditorCatalogFix | null; /** Set on posts the user may edit: the snippet written by the agent into the panel's fields. */ postFix: SeoEditorPostFix | null; ai?: SeoEditorAi; /** The schema type posts of this kind get from Titles & meta, "none" for the WebPage alone. */ schemaDefault: string; /** Custom fields Titles & meta adds to the analysis: meta key => what the post holds in it. */ analyzeFields: Record; } export const seoEditorEnv: SeoEditorEnv | undefined = ( window as unknown as { recomazeSeoEditor?: SeoEditorEnv } ).recomazeSeoEditor;