import type { Component } from 'vue';
import type { Schema } from 'effect';
import { Effect } from 'effect';
import type { Fetch } from 'fx-fetch';
import type { Environment } from '../../../vendor/cel-js/lib/index.js';
import type { EventChannel, OperationDescriptor, TriggerValue } from '../../../share/event-bus.js';
type CelEvaluator = <T>(expression: string, context?: Record<string, unknown>) => Effect.Effect<T, any>;
type AnySchema = Schema.Schema<any, any, never>;
type SchemaFactory = (configure: (env: Environment) => void) => AnySchema;
/**
 * Capabilities a button-migration function may need from the host. Mirrors the
 * form / table hosts' `MigrationContext` so cross-host migrations share one
 * signature; extend additively rather than introducing a parallel context.
 */
export type MigrationContext = Readonly<{
    $cel: <T>(expression: string, context?: Record<string, unknown>) => Effect.Effect<T, unknown>;
}>;
/**
 * Migrates a value of a *source* button schema to this entry's schema. Lives on
 * the *target* (newer / replacement) entry. The target is picked by one of two
 * rules: (a) same `type` with a strictly newer `compatibilityDate`; (b) an
 * explicit `migrateFrom` declaration on the target naming this source. Failures
 * surface to the host as a toast — see `actions/config.vue`'s migrate handler.
 */
export type MigrateFn = (prev: unknown, ctx: MigrationContext) => Effect.Effect<unknown, Error>;
/**
 * Identifies a button entry by `(type, compatibilityDate)`. Used for both
 * `migrateFrom` declarations and the cross-type form of `supersededBy`.
 *
 * Migration declarations only ever live on the *new* (target) code — old
 * folders are never modified to announce that they have been superseded.
 */
export type MigrateSource = Readonly<{
    type: string;
    compatibilityDate: string;
}>;
export type ButtonMetadata = Readonly<{
    name: string;
    icon: string;
    drillable?: boolean;
    operations?: ReadonlyArray<OperationDescriptor>;
    deprecated?: string;
}>;
export type ButtonEntry = Readonly<{
    type: string;
    compatibilityDate: string;
    metadata: ButtonMetadata;
    schema: SchemaFactory;
    config: Component;
    runtime: Component;
    /** True when this button type is deprecated — explicit flag, newer date, or `migrateFrom`. */
    deprecated: boolean;
    /** Migration guidance shown in the inspector when `deprecated`. */
    deprecationNote?: string;
    /**
     * Identifies the entry that supersedes this one. Same `type` for the
     * date-versioned rule; a different `type` for declared cross-type migrations.
     * Absent for entries deprecated only via a free-text `metadata.deprecated`.
     */
    supersededBy?: MigrateSource;
    /** Migration from a recognized source schema to this entry's schema. */
    migrate?: MigrateFn;
    /** Source schemas this entry accepts migration from. See module field. */
    migrateFrom?: ReadonlyArray<MigrateSource>;
}>;
export declare const BUTTONS: ReadonlyArray<ButtonEntry>;
/**
 * Finds the entry that declared `(type, compatibilityDate)` as a `migrateFrom`
 * source. Use when a stored button's identity no longer matches any registry
 * entry (the old folder was removed) — a present return means the value is
 * still migratable via the target's `migrate`.
 *
 * For sources whose folder was kept (the usual case — see "never delete a
 * superseded block folder"), the entry itself is in `BUTTONS`, tagged
 * `deprecated`/`supersededBy`; reach the target via
 * `findButton(supersededBy.type, …)` instead.
 */
export declare function findMigrationTarget(type: string, compatibilityDate: string): ButtonEntry | undefined;
export declare function allButtonSchemas(configure: (env: Environment) => void): ReadonlyArray<AnySchema>;
export declare function findButton(type: string, compatibilityDate: string): ButtonEntry | undefined;
export type ItemMetadata = Readonly<{
    name: string;
    icon: string;
}>;
export type ItemEntry = Readonly<{
    type: string;
    compatibilityDate: string;
    metadata: ItemMetadata;
    schema: SchemaFactory;
    config: Component;
    runtime: Component;
}>;
export declare const ITEMS: ReadonlyArray<ItemEntry>;
export declare function allItemSchemas(configure: (env: Environment) => void): ReadonlyArray<AnySchema>;
export declare function findItem(type: string, compatibilityDate: string): ItemEntry | undefined;
export declare function interpolateMarkdown(source: string, $cel: CelEvaluator, context?: Record<string, unknown>): string;
type ToastStyle = 'success' | 'error' | 'warning' | 'info';
/**
 * Post-completion behaviour shared by the HTTP-request buttons. Once the
 * request finishes, `resultExpression` classifies the outcome into one of the
 * four `ToastStyle`s (default `success`); that single result then both styles
 * the toast and selects which trigger list runs.
 */
export type HttpRequestOutcome = {
    /** Toast message expression, evaluated against `json`. No toast when absent. */
    messageExpression?: string;
    /** Result classifier, evaluated against `json`. Defaults to `success`. */
    resultExpression?: string;
    /** Bubbling channel for the result-keyed trigger lists. */
    channel?: EventChannel;
    /** Trigger lists keyed by result — the one matching the result runs. */
    triggers?: Partial<Record<ToastStyle, ReadonlyArray<TriggerValue>>>;
};
export declare function executeHttpRequest(expression: string, $cel: CelEvaluator, outcome?: HttpRequestOutcome): Effect.Effect<unknown, any, Fetch.Fetch>;
/**
 * Batch sibling of {@link executeHttpRequest}. The expression evaluates to a
 * list of `HttpRequestBuilder`s, sent strictly one-by-one behind a live
 * progress dialog. Each response is judged individually:
 *
 *   - `resultExpression` (per response) is evaluated against that one response
 *     body `json`, returning a `bool` — `true` means the response succeeded.
 *     Absent ⇒ any non-erroring response counts as a success.
 *   - `continueOnError` — when false (default) the first failure (a transport
 *     error or a `resultExpression` that returned false) stops the batch. When
 *     true, the loop carries on past failures.
 *
 * The dialog always shows a Stop button; the loop polls `handle.isCancelled`
 * between requests and stops the remaining ones (already-sent requests stand).
 *
 * The dialog never closes on its own — `handle.finish` flips it to a closeable
 * state and the user dismisses it. The post-completion `messageExpression` (if
 * any) is evaluated once against `jsons` — the list of **succeeded** response
 * bodies — and shown as a toast, styled `success` when nothing failed and
 * `error` otherwise.
 *
 * `markdown`, if given, is the dialog body: localized markdown re-interpolated
 * after every request against the live counters `total` / `succeeded` /
 * `failure`, so the message tracks progress.
 */
export type HttpRequestBatchOutcome = {
    /** Toast message expression, evaluated once against `jsons`. No toast when absent. */
    messageExpression?: string;
    /** Per-response success predicate, evaluated against `json`. Absent ⇒ always succeeds. */
    resultExpression?: string;
    continueOnError?: boolean;
    markdown?: string;
};
export declare function executeHttpRequestBatch(expression: string, $cel: CelEvaluator, outcome?: HttpRequestBatchOutcome): Effect.Effect<unknown, any, Fetch.Fetch>;
export {};
