import { ComponentType, AnchorHTMLAttributes, ReactNode, ErrorInfo, PropsWithChildren } from 'react'; import { FallbackProps } from 'react-error-boundary'; type AuthToken = string | undefined; interface Auth { /** * Which part of the request do we use to send the auth? * * @default 'header' */ in?: 'header' | 'query' | 'cookie'; /** * A unique identifier for the security scheme. * * Defined only when there are multiple security schemes whose `Auth` * shape would otherwise be identical. */ key?: string; /** * Header or query parameter name. * * @default 'Authorization' */ name?: string; scheme?: 'basic' | 'bearer'; type: 'apiKey' | 'http'; } interface SerializerOptions { /** * @default true */ explode: boolean; style: T; } type ArrayStyle = 'form' | 'spaceDelimited' | 'pipeDelimited'; type ObjectStyle = 'form' | 'deepObject'; type QuerySerializer = (query: Record) => string; type BodySerializer = (body: unknown) => unknown; type QuerySerializerOptionsObject = { allowReserved?: boolean; array?: Partial>; object?: Partial>; }; type QuerySerializerOptions = QuerySerializerOptionsObject & { /** * Per-parameter serialization overrides. When provided, these settings * override the global array/object settings for specific parameter names. */ parameters?: Record; }; type HttpMethod = 'connect' | 'delete' | 'get' | 'head' | 'options' | 'patch' | 'post' | 'put' | 'trace'; type Client$1 = { /** * Returns the final request URL. */ buildUrl: BuildUrlFn; getConfig: () => Config; request: RequestFn; setConfig: (config: Config) => Config; } & { [K in HttpMethod]: MethodFn; } & ([SseFn] extends [never] ? { sse?: never; } : { sse: { [K in HttpMethod]: SseFn; }; }); interface Config$1 { /** * Auth token or a function returning auth token. The resolved value will be * added to the request payload as defined by its `security` array. */ auth?: ((auth: Auth) => Promise | AuthToken) | AuthToken; /** * A function for serializing request body parameter. By default, * {@link JSON.stringify()} will be used. */ bodySerializer?: BodySerializer | null; /** * An object containing any HTTP headers that you want to pre-populate your * `Headers` object with. * * {@link https://developer.mozilla.org/docs/Web/API/Headers/Headers#init See more} */ headers?: RequestInit['headers'] | Record; /** * The request method. * * {@link https://developer.mozilla.org/docs/Web/API/fetch#method See more} */ method?: Uppercase; /** * A function for serializing request query parameters. By default, arrays * will be exploded in form style, objects will be exploded in deepObject * style, and reserved characters are percent-encoded. * * This method will have no effect if the native `paramsSerializer()` Axios * API function is used. * * {@link https://swagger.io/docs/specification/serialization/#query View examples} */ querySerializer?: QuerySerializer | QuerySerializerOptions; /** * A function validating request data. This is useful if you want to ensure * the request conforms to the desired shape, so it can be safely sent to * the server. */ requestValidator?: (data: unknown) => Promise; /** * A function transforming response data before it's returned. This is useful * for post-processing data, e.g., converting ISO strings into Date objects. */ responseTransformer?: (data: unknown) => Promise; /** * A function validating response data. This is useful if you want to ensure * the response conforms to the desired shape, so it can be safely passed to * the transformers and returned to the user. */ responseValidator?: (data: unknown) => Promise; } type ServerSentEventsOptions = Omit & Pick & { /** * Fetch API implementation. You can use this option to provide a custom * fetch instance. * * @default globalThis.fetch */ fetch?: typeof fetch; /** * Implementing clients can call request interceptors inside this hook. */ onRequest?: (url: string, init: RequestInit) => Promise; /** * Callback invoked when a network or parsing error occurs during streaming. * * This option applies only if the endpoint returns a stream of events. * * @param error The error that occurred. */ onSseError?: (error: unknown) => void; /** * Callback invoked when an event is streamed from the server. * * This option applies only if the endpoint returns a stream of events. * * @param event Event streamed from the server. * @returns Nothing (void). */ onSseEvent?: (event: StreamEvent) => void; serializedBody?: RequestInit['body']; /** * Default retry delay in milliseconds. * * This option applies only if the endpoint returns a stream of events. * * @default 3000 */ sseDefaultRetryDelay?: number; /** * Maximum number of retry attempts before giving up. */ sseMaxRetryAttempts?: number; /** * Maximum retry delay in milliseconds. * * Applies only when exponential backoff is used. * * This option applies only if the endpoint returns a stream of events. * * @default 30000 */ sseMaxRetryDelay?: number; /** * Optional sleep function for retry backoff. * * Defaults to using `setTimeout`. */ sseSleepFn?: (ms: number) => Promise; url: string; }; interface StreamEvent { data: TData; event?: string; id?: string; retry?: number; } type ServerSentEventsResult = { stream: AsyncGenerator ? TData[keyof TData] : TData, TReturn, TNext>; }; type ErrInterceptor = (error: Err, /** response may be undefined due to a network error where no response object is produced */ response: Res | undefined, /** request may be undefined, because error may be from building the request object itself */ request: Req | undefined, options: Options) => Err | Promise; type ReqInterceptor = (request: Req, options: Options) => Req | Promise; type ResInterceptor = (response: Res, request: Req, options: Options) => Res | Promise; declare class Interceptors { fns: Array; clear(): void; eject(id: number | Interceptor): void; exists(id: number | Interceptor): boolean; getInterceptorIndex(id: number | Interceptor): number; update(id: number | Interceptor, fn: Interceptor): number | Interceptor | false; use(fn: Interceptor): number; } interface Middleware { error: Interceptors>; request: Interceptors>; response: Interceptors>; } type ResponseStyle = 'data' | 'fields'; interface Config extends Omit, Config$1 { /** * Base URL for all requests made by this client. */ baseUrl?: T['baseUrl']; /** * Fetch API implementation. You can use this option to provide a custom * fetch instance. * * @default globalThis.fetch */ fetch?: typeof fetch; /** * Please don't use the Fetch client for Next.js applications. The `next` * options won't have any effect. * * Install {@link https://www.npmjs.com/package/@hey-api/client-next `@hey-api/client-next`} instead. */ next?: never; /** * Return the response data parsed in a specified format. By default, `auto` * will infer the appropriate method from the `Content-Type` response header. * You can override this behavior with any of the {@link Body} methods. * Select `stream` if you don't want to parse response data at all. * * @default 'auto' */ parseAs?: 'arrayBuffer' | 'auto' | 'blob' | 'formData' | 'json' | 'stream' | 'text'; /** * Should we return only data or multiple fields (data, error, response, etc.)? * * @default 'fields' */ responseStyle?: ResponseStyle; /** * Throw an error instead of returning it in the response? * * @default false */ throwOnError?: T['throwOnError']; } interface RequestOptions extends Config<{ responseStyle: TResponseStyle; throwOnError: ThrowOnError; }>, Pick, 'onRequest' | 'onSseError' | 'onSseEvent' | 'sseDefaultRetryDelay' | 'sseMaxRetryAttempts' | 'sseMaxRetryDelay'> { /** * Any body that you want to add to your request. * * {@link https://developer.mozilla.org/docs/Web/API/fetch#body} */ body?: unknown; path?: Record; query?: Record; /** * Security mechanism(s) to use for the request. */ security?: ReadonlyArray; url: Url; } interface ResolvedRequestOptions extends RequestOptions { headers: Headers; serializedBody?: string; } type RequestResult = ThrowOnError extends true ? Promise ? TData[keyof TData] : TData : { data: TData extends Record ? TData[keyof TData] : TData; request: Request; response: Response; }> : Promise ? TData[keyof TData] : TData) | undefined : ({ data: TData extends Record ? TData[keyof TData] : TData; error: undefined; } | { data: undefined; error: TError extends Record ? TError[keyof TError] : TError; }) & { /** request may be undefined, because error may be from building the request object itself */ request?: Request; /** response may be undefined, because error may be from building the request object itself or from a network error */ response?: Response; }>; interface ClientOptions$1 { baseUrl?: string; responseStyle?: ResponseStyle; throwOnError?: boolean; } type MethodFn = (options: Omit, 'method'>) => RequestResult; type SseFn = (options: Omit, 'method'>) => Promise>; type RequestFn = (options: Omit, 'method'> & Pick>, 'method'>) => RequestResult; type BuildUrlFn = ; query?: Record; url: string; }>(options: TData & Options) => string; type Client = Client$1 & { interceptors: Middleware; }; interface TDataShape { body?: unknown; headers?: unknown; path?: unknown; query?: unknown; url: string; } type OmitKeys = Pick>; type Options = OmitKeys, 'body' | 'path' | 'query' | 'url'> & ([TData] extends [never] ? unknown : Omit); type ClientOptions = { baseUrl: 'https://api.stage.tesouro.com' | 'https://api.sandbox.stage.tesouro.com' | 'https://api.stage.business-banking.app' | 'https://api.tesouro.com' | 'https://api.sandbox.tesouro.com' | 'https://api.business-banking.app' | (string & {}); }; type EmbeddedClient = Client; type ExtractLiterals = T extends string ? string extends T ? never : T : never; type BaseUrl = ExtractLiterals; type LinkComponentProps = AnchorHTMLAttributes & { children?: ReactNode; }; type LinkComponent = ComponentType; /** * The UI frameworks a widget's UI layer can render with. * * - `shadcn` — the shadcn/Tailwind implementation. This is the default and the * implicit fallback, so existing consumers that select nothing keep rendering * shadcn. * - `tecton` — the Tecton implementation. * * Declared as an `as const` object (not a TypeScript `enum`) per repo * convention. */ declare const UIFramework: { readonly Shadcn: "shadcn"; readonly Tecton: "tecton"; }; type UIFramework = (typeof UIFramework)[keyof typeof UIFramework]; /** * The implementation a widget renders with. * * - `native` — the Tesouro-native implementation. This is the default and the * implicit fallback, so consumers that select nothing keep rendering native. * - `monite` — the Monite SDK implementation. * * Declared as an `as const` object (not a TypeScript `enum`) per repo * convention. */ declare const Implementation: { readonly Native: "native"; readonly Monite: "monite"; }; type Implementation = (typeof Implementation)[keyof typeof Implementation]; /** * The settable fields of the widget config cascade. * * This is the type accepted by {@link setGlobalWidgetConfig} and all provider props. * It intentionally excludes `initResponse`, which is populated automatically by the * provider after a successful fetch and must never be set manually. * * The `null` vs `undefined` distinction on `widgetToken` and `organizationId` is intentional: * - `undefined` — not set at this level; inherit from the nearest ancestor or global store. * - `null` — explicitly cleared; downstream sees "no value" even if an ancestor had one * (e.g. after logout or deliberate de-scoping). * * @see {@link WidgetConfig} for the resolved output type (includes `initResponse`) * @see {@link RootWidgetProvider} * @see {@link WidgetProvider} * @see {@link setGlobalWidgetConfig} */ interface WidgetConfigInput { /** * Base URL of the Tesouro embedded API (e.g. `"https://api.tesouro.com"`). * * When omitted the nearest ancestor's `baseUrl` or the global store value is used. * Changing this recreates the underlying HTTP client so all subsequent requests * go to the new host. */ baseUrl?: BaseUrl; /** * Bearer token used to authenticate widget requests. * * Injected as `Authorization: Bearer ` on every outgoing request via an * interceptor on the scoped HTTP client. Token updates are picked up immediately * without recreating the client. * * - `string` — send this token on all requests from this level downward. * - `null` — explicitly cleared; no auth header is sent and fetching is suppressed. * - `undefined` — not set at this level; inherit from the nearest ancestor or global store. */ widgetToken?: string | null; /** * Organization ID forwarded as the `x-organization-id` request header. * * Passed through {@link EmbedApiProvider} context rather than the auth interceptor, * so individual data-access hooks can opt in per-request. * * - `string` — use this organization for downstream data requests. * - `null` — explicitly cleared; queries that require an org ID will be disabled. * - `undefined` — not set at this level; inherit from the nearest ancestor or global store. * * When `undefined` across the **whole** cascade (no prop, no ancestor, no global * value), the resolved org defaults to the loaded `initResponse.organizationId` * (see {@link WidgetConfig.initResponse}) once the widget-init fetch settles. This * is the lowest-priority fallback — any explicit `string` or `null` at any cascade * level wins, and an explicit `null` is preserved and never falls back. * * Only an **explicit** ancestor org is inherited. An ancestor's *init-derived* * default does not propagate into a descendant that owns its own fetch (its own * `baseUrl`/`widgetToken`); such a descendant defaults to its own * `initResponse.organizationId` instead, so it never sends an ancestor's org with * its own token. */ organizationId?: string | null; /** * Optional post-creation hook for the scoped HTTP client. * * Called once after the provider creates its scoped {@link EmbeddedClient} and * applies the built-in `Authorization: Bearer` interceptor. Receives the * fully-configured client and must return the client to be used for the lifetime of * this provider level — either the same instance (with additional interceptors * attached) or a new client entirely. * * **Order:** The built-in auth interceptor is always applied first. `configClient` * is called on top of it, so any interceptors you add here run after auth is set. * * **Any prop triggers a scoped client.** A {@link WidgetProvider} creates its own * scoped client whenever any prop is set — including `configClient` alone, without * `baseUrl` or `widgetToken`. Only a fully props-free pass-through provider skips * client creation and never calls this function. * * **Stability:** The function reference is included in the client creation memo's * dependency array. Passing an unstable (inline) function recreates the client on * every render. Stabilize with `useCallback` or define the function outside the * component. * * **Cascade:** Inherits from the nearest ancestor when `undefined`. A child * {@link WidgetProvider} that creates its own scoped client will use the resolved * `configClient` from the cascade unless it provides its own override. * * @example * ```tsx * const addLogging = useCallback( * (client: EmbeddedClient) => { * client.interceptors.request.use((req) => { * console.log('[widget]', req.method, req.url); * return req; * }); * return client; * }, * [], * ); * * * * * ``` */ configClient?: (client: EmbeddedClient) => EmbeddedClient; /** * Overrides the widget-gateway routing decision for the scoped HTTP client. * * Any caller reaching the Tesouro API with a widget token must route data * requests through the widget gateway: prefix the path with * `/api/widget-gateway/proxy` and carry the token as `X-Widget-Token`. The * provider applies both automatically per request when the request origin is * a known Tesouro API host (`WIDGET_GATEWAY_HOSTS`, derived from the * generated `ClientOptions['baseUrl']`); `/api/widget-gateway/*` paths (the * init round-trip) always pass through untouched. * * - `undefined` — decide from the request origin, as above. Inherits from * the nearest ancestor or global store like every other config field. * - `true` — always apply the rewrite, even for an unlisted base URL (e.g. a * custom domain in front of the gateway). * - `false` — never apply it. For hosts that route widget requests their own * way, such as a same-origin BFF whose `configClient` retargets every * request. * * Independent of {@link configClient}: a host that only adds a header keeps * the built-in routing, and the built-in interceptor runs before any * `configClient` interceptor. */ gatewayRouting?: boolean; /** * Component the embedded widgets should render in place of plain `` tags. * * Pass e.g. Next.js's `Link` to make in-app navigation use the host router. * Cascades like other config: provider prop > nearest ancestor > global store. * When no value is set anywhere, widgets fall back to a plain `` element. */ linkComponent?: LinkComponent; /** * Which UI framework the widget UI layer should render with. * * Lets a consuming context bind widgets to either the shadcn/Tailwind or the * Tecton implementation behind the same outward-facing API. The selection is * a presentation concern only — it cascades through the provider tree exactly * like {@link linkComponent} and is read by UI libraries via `useUIFramework`; * it never appears in any widget's feature-library or component props. * * - `'shadcn'` — the shadcn/Tailwind implementation. * - `'tecton'` — the Tecton implementation. * - `null` / `undefined` — not set at this level; inherit from the nearest * ancestor or global store, falling back to `shadcn` when unset everywhere. * `shadcn` is the implicit default, so existing consumers need no changes. */ uiFramework?: UIFramework | null; /** * Which implementation a widget renders with. * * Lets a consuming context bind widgets to either the Tesouro-native or the * Monite SDK implementation behind the same outward-facing API. It cascades * through the provider tree exactly like {@link linkComponent} and * {@link uiFramework} — provider prop > nearest ancestor > global store — and * is read via `useImplementation`. * * - `'native'` — the Tesouro-native implementation. * - `'monite'` — the Monite SDK implementation. * - `null` / `undefined` — not set at this level; inherit from the nearest * ancestor or global store, falling back to `native` when unset everywhere. * `native` is the implicit default, so existing consumers need no changes. */ implementation?: Implementation | null; } /** * Props shared by every analytics-owner-capable widget provider. * * Combines the full settable cascade ({@link WidgetConfigInput}) with the * analytics opt-out honored by analytics owners. Both {@link RootWidgetProvider} * and {@link WidgetProvider} build their public props on top of this; the latter * adds error-boundary props of its own. * * @see {@link WidgetConfigInput} for per-field cascade and `null` vs omitted semantics */ interface WidgetProviderBaseProps extends WidgetConfigInput { /** * Opt out of all analytics capture and prevent PostHog from loading. Default `true`. * * Honored only by an analytics **owner** — a {@link RootWidgetProvider} or a * standalone {@link WidgetProvider} with no parent provider. When `false`, * owner-bound `track` calls in this subtree become no-ops and the PostHog * installer is never dynamically imported for this owner's environment. * Setting it on a nested {@link WidgetProvider} is ignored in v1 (a one-time * `console.warn` is emitted to make the no-op discoverable). */ analytics?: boolean; } /** * Props for {@link WidgetProvider}. * * All fields are optional. When **all** are omitted the provider is a transparent * pass-through: no fetch is issued and all resolved values cascade unchanged from * the nearest ancestor. */ interface WidgetProviderProps extends WidgetProviderBaseProps { /** * Fallback rendered when a render-time exception is caught inside this * provider's subtree. Pass either a `ReactNode` (rendered directly) or a * render-prop receiving `{ error, resetErrorBoundary }` from * `react-error-boundary`. Default is a plain `role="alert"` div with * generic copy from `DEFAULT_LABELS.errorBoundaryFallback`. */ errorFallback?: ReactNode | ((props: FallbackProps) => ReactNode); /** * Called once when the boundary catches an error, before the fallback * renders. Use for telemetry / Sentry / partner logging. Exceptions * thrown from `onError` propagate per `react-error-boundary` semantics. */ onError?: (error: unknown, info: ErrorInfo) => void; /** * Accept surface shown when an ACTIVE user owes a new disclosure version. * Pass `` (no invite * credentials). Cascades like `linkComponent`. Omit on INVITED — that * path still uses invite-link `invitationToken`/`userId` on the host * landing page. WidgetProvider cannot import the widget itself (cycle). */ disclosuresAcceptance?: ReactNode; } /** * Public {@link WidgetProvider} — the integrator-facing provider. * * The workspace-internal provider additionally accepts a `widgetName` prop that * stamps analytics identity (`widget_name` + a per-mount `widget_instance_id`) * on everything emitted beneath it (EMBD-4190). That identity is set **only** by * widget feature libs, never by integrators: a spoofed `widget_name` or a forced * fresh `widget_instance_id` would corrupt correlation. * * `WidgetProviderProps` deliberately omits `widgetName`, so typed (TS) consumers * cannot pass it. This wrapper additionally strips any stray `widgetName` a * non-typed (JS) host might pass at runtime before delegating, so the internal * identity prop is unreachable from the published surface in every case — the * provider's declaration in the emitted types carries no `widgetName`. */ declare function WidgetProvider(props: PropsWithChildren): ReactNode; export { WidgetProvider };