import type { AnyEventListener, ApiReferenceEvents, WorkspaceEventBus } from '@scalar/workspace-store/events';
import type { RequestFactory, VariablesStore } from '@scalar/workspace-store/request-example';
import type { OpenApiDocument } from '@scalar/workspace-store/schemas/v3.1/strict/openapi-document';
import type { OperationObject } from '@scalar/workspace-store/schemas/v3.1/strict/operation';
import type { Component, DefineComponent } from 'vue';
/** Shared fields present on every response body handler variant */
type ResponseBodyHandlerBase = {
    /** MIME type patterns this handler matches (exact or glob like "application/vnd.*+json") */
    mimeTypes: string[];
    /** Custom decoder: transform raw bytes into displayable data */
    decode?: (buffer: ArrayBuffer, contentType: string) => string | Blob | Promise<string | Blob>;
    /** Custom component for the preview view */
    previewComponent?: Component;
};
/**
 * Describes how a plugin handles a specific content type in the response body.
 *
 * The raw view is configured with either:
 * - `rawComponent`: A custom Vue component (receives `content` and `contentType` props).
 * - `language`: A CodeMirror language hint for the built-in raw renderer.
 *
 * These two options are mutually exclusive — providing `rawComponent` means the
 * built-in renderer is not used, so `language` would have no effect.
 */
export type ResponseBodyHandler = ResponseBodyHandlerBase & ({
    rawComponent: Component;
    language?: never;
} | {
    rawComponent?: never;
    language?: string;
});
/** A type representing the hooks that a client plugin can define */
type ClientPluginHooks = {
    beforeRequest: (payload: {
        /** Workspace-store request spec; mutable by pre-request scripts (headers, method). */
        requestBuilder: RequestFactory;
        document: OpenApiDocument;
        operation: OperationObject;
        variablesStore?: VariablesStore;
    }) => void | Promise<void>;
    responseReceived: (payload: {
        response: Response;
        /** Request builder object that was used to build the request. Mutating this object will not affect the request object. */
        requestBuilder: RequestFactory;
        /** Request object that was sent to the server. */
        request: Request;
        document: OpenApiDocument;
        operation: OperationObject;
        variablesStore?: VariablesStore;
    }) => void | Promise<void>;
};
/** A vue component which accepts the specified props */
type ClientPluginComponent<Props extends Record<string, unknown>, Emits extends Record<string, (...args: any[]) => void> = {}> = {
    component: DefineComponent<Props, {}, {}, {}, {}, {}, {}, Emits>;
    additionalProps?: Record<string, unknown>;
};
type ClientPluginComponents = {
    request: ClientPluginComponent<{
        operation?: OperationObject;
    }, {
        'operation:update:extension': (payload: ApiReferenceEvents['operation:update:extension']['payload']) => void;
    }>;
    response: ClientPluginComponent<{
        operation?: OperationObject;
    }>;
};
/**
 * ClientPlugin is used to extend the API Client with custom hooks and UI components.
 *
 * Example usage:
 *
 * const myPlugin: ClientPlugin = {
 *   hooks: {
 *     beforeRequest: ({ request }) => {
 *       request.headers.set('X-Custom-Header', 'foo');
 *       return { request };
 *     },
 *     responseReceived: async (response, operation) => {
 *       // Handle post-response logic
 *       const data = await response.json();
 *       console.log('Received:', data, 'for operation:', operation.operationId);
 *     }
 *   },
 *   components: {
 *     request: MyRequestComponent, // Custom Vue component for rendering the request section
 *     response: MyResponseComponent // Custom Vue component for rendering the response section
 *   },
 *   responseBody: [{
 *     mimeTypes: ['application/msgpack', 'application/x-msgpack'],
 *     decode: (buffer) => {
 *       const decoded = msgpack.decode(new Uint8Array(buffer));
 *       return JSON.stringify(decoded, null, 2);
 *     },
 *     language: 'json',
 *   }]
 * }
 */
/** Lifecycle hooks for app-level plugin concerns (analytics, logging, etc.) */
type ClientPluginLifecycle = {
    /** Called when the API client is initialized */
    onInit?: (context?: {
        config: Record<string, unknown>;
    }) => void;
    /** Called when the API client configuration changes */
    onConfigChange?: (context: {
        config: Record<string, unknown>;
    }) => void;
    /** Called when the API client is destroyed */
    onDestroy?: () => void;
};
export type ClientPlugin = {
    hooks?: Partial<ClientPluginHooks>;
    components?: Partial<ClientPluginComponents>;
    /** Lifecycle hooks for app-level concerns */
    lifecycle?: ClientPluginLifecycle;
    /**
     * Subscribe to every event on the bus. The framework wires this up to
     * `bus.onAny` and handles subscribe/unsubscribe automatically.
     *
     * The listener receives a single tagged-union argument `{ event, payload }`
     * where `event` is the discriminant. Narrowing on `event` automatically
     * narrows `payload` to the exact type for that event — no casts, no `as`
     * assertions, and no manual runtime type checks just to satisfy the
     * compiler. Destructuring in the parameter list works too.
     *
     * @example
     * on: ({ event, payload }) => {
     *   if (event === 'log:user-login') {
     *     // payload is narrowed to { uid: string; email?: string; teamUid: string }
     *     posthog.identify(payload.uid, { email: payload.email })
     *   }
     *
     *   if (event === 'operation:create:operation') {
     *     // payload is narrowed to the operation-create payload
     *     analytics.track('operation_created', payload)
     *   }
     * }
     */
    on?: AnyEventListener;
    /** Custom response body handlers for specific content types */
    responseBody?: ResponseBodyHandler[];
};
/**
 * Subscribes a single plugin's `on` listener to the given event bus via `onAny`.
 *
 * The plugin's `on` is passed straight through to `bus.onAny`, so it will
 * receive every event emitted on the bus as a `{ event, payload }` object.
 * Plugins without an `on` listener get a no-op unsubscribe.
 *
 * Returns an unsubscribe function. Call it when the plugin is torn down or
 * the bus is destroyed to remove the wildcard listener.
 *
 * @example
 * const unsubscribe = subscribePluginEvents(eventBus, plugin)
 * // later...
 * unsubscribe()
 */
export declare const subscribePluginEvents: (eventBus: WorkspaceEventBus, plugin: ClientPlugin) => (() => void);
/**
 * Maps hook names to their expected payload types.
 * This ensures type safety when executing hooks with their corresponding payloads.
 * Derived from the ClientPlugin hooks definition.
 */
type HookPayloadMap = {
    [K in keyof ClientPluginHooks]: Parameters<ClientPluginHooks[K]>[0];
};
/**
 * Execute any hook with type-safe payload handling.
 * The payload type is inferred from the hook name to ensure correct usage.
 */
export declare const executeHook: <K extends keyof HookPayloadMap>(payload: HookPayloadMap[K], hookName: K, plugins: ClientPlugin[]) => Promise<HookPayloadMap[K]>;
export {};
//# sourceMappingURL=client-plugins.d.ts.map