import { EventEmitter } from '../../stencil-public-runtime'; import { AuthStatus, EoErrorDetail, EoFeedbackDetail } from '../../models/types'; import { ResolvedTheme, ThemePreference } from '../../utils/theme'; type ButtonSize = 'sm' | 'md' | 'lg'; type Placement = 'right' | 'left'; type Variant = 'floating' | 'inline'; /** * LOCKED PUBLIC API SURFACE — DO NOT EXTEND WITHOUT BRAND APPROVAL. * * The visual customization the partner is allowed to perform is exhausted by * three typed enum props (buttonSize / placement / variant) and zero CSS knobs. * * Specifically: NO @Prop here may accept a logo, brand colour, custom asset * URL, theme object, class name, inline style, or anything that lets the * partner alter the rendered EvidenceOne brand. The trigger label text * ("Consultar EvidenceOne") and the header logo are runtime-verified by * src/utils/integrity.ts and the widget refuses to authenticate on mismatch. */ export declare class EvidenceOneChat { apiKey: string; apiUrl: string; doctorEmail: string; doctorName: string; doctorCrm: string; doctorPhone: string; doctorSpecialty?: string; /** * Opaque partner token for `partner_gateway` partners. When present, the * server resolves the doctor profile from the partner's gateway and the * doctor-* props are not required. */ partnerToken?: string; /** * Optional generic lookup value (id, email, name — the partner decides) that * keys a `{lookup}`-templated gateway URL on the server. Only meaningful in * `partner_gateway` mode alongside `partnerToken`. */ partnerLookup?: string; newSession: boolean; buttonSize: ButtonSize; placement: Placement; variant: Variant; /** * Color scheme of the widget. Reactive — the host may flip it at any time. * 'auto' follows the page's `prefers-color-scheme` live. */ theme: ThemePreference; isOpen: boolean; authStatus: AuthStatus; /** Bumped whenever a fresh session is requested — child eo-chat @Watch-es this to reset. */ resetKey: number; /** True if brand integrity verification failed at mount. Render-blocks the trigger and short-circuits auth. */ integrityFailed: boolean; /** Concrete theme applied as data-theme on .eo-scope — resolved from the `theme` prop. */ resolvedTheme: ResolvedTheme; /** True while POST /partner/consent is in flight after "Continuar". */ consentSaving: boolean; /** True when the last accept attempt failed — eo-consent shows the banner. */ consentError: boolean; eoReady: EventEmitter<{ sessionId: string; }>; eoError: EventEmitter; /** Emitted when the partner session is blocked because the doctor profile is incomplete. */ eoBlocked: EventEmitter<{ missing: string[]; }>; eoClose: EventEmitter; /** * Emitted when the user votes an answer útil/não útil. Frontend-only: no * network call is made — this event is the seam for future backend wiring * (spec §3.3, backlogged). */ eoFeedback: EventEmitter; el: HTMLElement; private authService; private chatService; private consentService; private cachedDoctorData; /** Element that triggered drawer open — focus returns here on close. */ private triggerEl; /** Ref to the rendered trigger button or pill — used for integrity check on its label. */ private triggerRef; /** Live media query behind theme='auto' — subscribed only while auto is active. */ private darkMql; connectedCallback(): void; componentWillLoad(): void; componentDidLoad(): Promise; disconnectedCallback(): void; /** * Rebuild services if the partner reactively updates apiKey/apiUrl * (common in framework wrappers that swap endpoints between staging/prod). */ onApiPropChange(): void; onDoctorPropChange(): void; onPartnerTokenChange(): void; onThemeChange(): void; onConsentAccept(e: CustomEvent<{ comms: boolean; }>): void; onConsentCancel(): void; onMessageFeedback(e: CustomEvent<{ messageIndex: number; vote: 'up' | 'down'; }>): void; /** * Transport-level validation: the widget can only function with an api-key and * api-url. Doctor-profile completeness is NOT checked here — an incomplete * profile must still build services so the drawer can open and show the * "Cadastro incompleto" blocked state (see missingDoctorFields / resolveSession). */ private validateProps; /** * Required doctor-* fields that are missing/empty (client_provided mode only). * In partner_gateway mode the server resolves the profile, so completeness is * decided server-side (422 PROFILE_INCOMPLETE) and this returns []. Field names * match the server's `missing` payload so client- and server-driven blocks agree. */ private missingDoctorFields; private buildServices; private cacheDoctorData; /** Defensive enum normalization — Stencil passes raw attribute strings, so unknown values fall back to default. */ private normalizedSize; private normalizedPlacement; private normalizedVariant; /** Drawer side is bound to placement only when floating; inline always opens a right-side drawer. */ private drawerSide; /** * Resolve the `theme` prop into `resolvedTheme` and keep the * prefers-color-scheme subscription in sync: attached only while * theme='auto', so explicit light/dark never react to OS changes. */ private applyTheme; private attachSystemThemeListener; private detachSystemThemeListener; private onSystemThemeChange; private verifyBrandIntegrity; /** * Marks a brand-locked element as untranslatable. The label text is * hash-verified at mount, and page translators (Chrome/Edge/Google) rewrite * dynamically-inserted nodes — which the lock cannot distinguish from * tampering. They honor translate="no" + .notranslate; Stencil's JSX typings * lack the standard `translate` attribute, so it is set here in the ref * callback — same task as DOM insertion, ahead of any translator's * MutationObserver microtask. */ private protectFromTranslators; private handleTriggerClick; private openDrawer; /** * Resolve (or re-resolve) the partner session for the open drawer. Runs on * every open and on retry, so the completeness gate is re-checked each time. */ private resolveSession; /** * Resolve a partner session. `blocked` (422 PROFILE_INCOMPLETE) is a distinct * outcome from `error` — it surfaces the block state and the `eoBlocked` event * instead of a generic auth failure. */ private attemptAuth; private identityPayload; private handleRetry; private finishRetry; /** * Present the consent screen with a clean slate — stale error/saving flags * from an earlier presentation (including a late accept-failure that landed * after the drawer was dismissed) must not leak into this one. */ private enterConsent; /** * Single close path (X, backdrop, Cancelar). Dismissing during consent is a * refusal: logged fire-and-forget — a failed log must never trap the user in * the modal (spec §2.4). Consent stays `required` in AuthService memory, so * reopening on the same page shows the opt-in again until the server records * an accept. */ private handleDrawerClose; private declineConsent; /** * Chat hit 403 CONSENT_REQUIRED (server enforcement, stale local state). * The token stays — it is valid; only consent is missing (spec §2.5). The * in-memory consent flips to required so the cached-token reopen path keeps * gating, and the screen swaps to the opt-in. */ private handleConsentRequired; private handleConsentAccept; private handleNewSession; render(): any; } export {};