import { aws_events, aws_events_targets, Stack } from "aws-cdk-lib";
import { Construct } from "constructs";
import { Integration, IntegrationCall } from "../integration";
import { RulePredicateFunction, Rule, PredicateRuleBase, ImportedRule, ScheduledEvent, IRule } from "./rule";
import type { Event } from "./types";
export declare const isEventBus: <EvntBus extends IEventBus<any>>(v: any) => v is EvntBus;
/**
 * Returns the {@link Event} type on the {@link EventBus}.
 */
export declare type EventBusEvent<B extends IEventBus<any>> = [B] extends [
    IEventBus<infer E>
] ? E : never;
export interface IEventBusFilterable<in Evnt extends Event> {
    /**
     * EventBus Rules can filter events using Functionless predicate functions.
     *
     * Equals
     *
     * ```ts
     * when(this, 'rule', (event) => event.source === "lambda")
     * ```
     *
     * Starts With (Prefix)
     *
     * ```ts
     * when(this, 'rule', (event) => event.id.startsWith("2022"))
     * ```
     *
     * Not
     *
     * ```ts
     * when(this, 'rule', (event) => event.source !== "dynamo")
     * ```
     *
     * Numeric Ranges
     *
     * ```ts
     * when(this, 'rule', (event) => event.detail.num >= 10 || event.detail.num > 100 && event.detail.num < 1000)
     * ```
     *
     * Presence
     *
     * ```ts
     * when(this, 'rule', (event) => !event.detail.optional)
     * ```
     *
     * Multiple Fields
     *
     * ```ts
     * when(this, 'rule', (event) => event.source === "lambda" && event['detail-type'] === "SUCCESS")
     * ```
     *
     * Array Includes
     *
     * ```ts
     * when(this, 'rule', (event) => event.detail.list.includes("someValue"))
     * ```
     *
     * Omitting the scope will use the bus as the scope.
     *
     * ```ts
     * when('rule', ...)
     * ```
     *
     * Unsupported by Event Bridge
     * * OR Logic between multiple fields
     * * AND logic between most logic on a single field (except for numeric ranges.)
     * * Multiple `!field.startsWith(...)` on a single field
     * * Any operation on an Array other than `includes` and presence (`event.detail.list === undefined`).
     * * Any string operation other than `===/==`, `!==/!=`, `startsWith`, and presence (`!==/=== undefined`).
     * * Math (`event.detail.num + 1 < 10`)
     * * Comparisons between fields (`event.detail.previous !== event.id`)
     *
     * Unsupported by Functionless:
     * * Variables from outside of the function scope
     *
     * @typeParam InEvnt - The type the {@link Rule} matches. Covariant of output {@link OutEvnt}.
     * @typeParam NewEvnt - The type the predicate narrows to, a sub-type of {@link InEvnt}.
     */
    when<InEvnt extends Evnt, NewEvnt extends InEvnt>(id: string, predicate: RulePredicateFunction<InEvnt, NewEvnt>): Rule<InEvnt, NewEvnt>;
    when<InEvnt extends Evnt, NewEvnt extends InEvnt>(scope: Construct, id: string, predicate: RulePredicateFunction<InEvnt, NewEvnt>): Rule<InEvnt, NewEvnt>;
}
/**
 * @typeParam Evnt - the union type of events that this EventBus can accept.
 *                   `Evnt` is the contravariant version of `OutEvnt` in that
 *                   the bus will accept any of `Evnt` while the EventBus can
 *                   emit any of `OutEvnt`.
 */
export interface IEventBus<in Evnt extends Event = Event> extends IEventBusFilterable<Evnt>, Integration<"EventBus", (event: PutEventInput<Evnt>, ...events: PutEventInput<Evnt>[]) => Promise<void>> {
    readonly resource: aws_events.IEventBus;
    readonly eventBusArn: string;
    readonly eventBusName: string;
    readonly __functionBrand: (event: PutEventInput<Evnt>, ...events: PutEventInput<Evnt>[]) => Promise<void>;
    /**
     * This static property identifies this class as an EventBus to the TypeScript plugin.
     */
    readonly functionlessKind: typeof EventBusBase.FunctionlessType;
    /**
     * Put one or more events on an Event Bus.
     */
    putEvents(event: PutEventInput<Evnt>, ...events: PutEventInput<Evnt>[]): Promise<void>;
    /**
     * Creates a rule that matches all events on the bus.
     *
     * When no scope or id are given, the bus is used as the scope and the id will be `all`.
     * The rule created will be a singleton.
     *
     * When scope and id are given, a new rule will be created each time.
     *
     * Like all functionless, a rule is only created when the rule is used with `.pipe` or the rule is retrieved using `.rule`.
     *
     * ```ts
     * const bus = new EventBus(scope, 'bus');
     * const func = new Function(scope, 'func', async (payload: {id: string}) => console.log(payload.id));
     *
     * bus
     *  .all()
     *  .map(event => ({id: event.id}))
     *  .pipe(func);
     * ```
     */
    all<OutEnvt extends Evnt>(): PredicateRuleBase<Evnt, OutEnvt>;
    all<OutEnvt extends Evnt>(scope: Construct, id: string): PredicateRuleBase<Evnt, OutEnvt>;
}
/**
 * @typeParam Evnt - the union type of events that this EventBus can accept.
 *                   `Evnt` is the contravariant version of `OutEvnt` in that
 *                   the bus will accept any of `Evnt` while the EventBus can
 *                   emit any of `OutEvnt`.
 * @typeParam OutEvnt - the union type of events that this EventBus will emit through rules.
 *                      `OutEvnt` is the covariant version of `Evnt` in that
 *                      the bus will emit any of `OutEvnt` while the EventBus can
 *                      can accept any of `Evnt`. This type parameter should be left
 *                      empty to be inferred. ex: `EventBus<Event<Detail1> | Event<Detail2>>`.
 */
declare abstract class EventBusBase<in Evnt extends Event, OutEvnt extends Evnt = Evnt> implements IEventBus<Evnt> {
    readonly resource: aws_events.IEventBus;
    /**
     * This static properties identifies this class as an EventBus to the TypeScript plugin.
     */
    static readonly FunctionlessType = "EventBus";
    readonly functionlessKind = "EventBus";
    readonly kind = "EventBus";
    readonly eventBusName: string;
    readonly eventBusArn: string;
    protected static singletonDefaultNode: string;
    private allRule;
    readonly putEvents: IntegrationCall<"EventBus.putEvents", IEventBus<Evnt>["putEvents"]>;
    readonly __functionBrand: (event: PutEventInput<Evnt>, ...events: PutEventInput<Evnt>[]) => Promise<void>;
    constructor(resource: aws_events.IEventBus);
    readonly eventBus: EventBusTargetIntegration<PutEventInput<Evnt>, aws_events_targets.EventBusProps | undefined>;
    /**
     * @inheritDoc
     *
     * @typeParam InEvnt - The type the {@link Rule} matches. Covariant of output {@link OutEvnt}.
     * @typeParam NewEvnt - The type the predicate narrows to, a sub-type of {@link InEvnt}.
     */
    when<InEvnt extends OutEvnt, NewEvnt extends InEvnt>(id: string, predicate: RulePredicateFunction<InEvnt, NewEvnt>): Rule<InEvnt, NewEvnt>;
    when<InEvnt extends OutEvnt, NewEvnt extends InEvnt>(scope: Construct, id: string, predicate: RulePredicateFunction<InEvnt, NewEvnt>): Rule<InEvnt, NewEvnt>;
    all(): PredicateRuleBase<Evnt, OutEvnt>;
    all(scope: Construct, id: string): PredicateRuleBase<Evnt, OutEvnt>;
}
export declare type PutEventInput<Evnt extends Event> = Partial<Evnt> & Pick<Evnt, "detail" | "source" | "detail-type"> & {
    "trace-header"?: string;
};
/**
 * A Functionless wrapper for a AWS CDK {@link aws_events.EventBus}.
 *
 * Wrap your {@link aws_events.EventBus} instance with this class,
 * specify a type to represent the events passing through the EventBus,
 * and then use the .when, .map and .pipe functions to express
 * EventBus Event Patterns and Targets Inputs with native TypeScript syntax.
 *
 * Filtering events and sending them to Lambda.
 *
 * ```ts
 * interface Payload {
 *    value: string;
 * }
 *
 * // An event with the payload
 * interface myEvent extends Event<Payload> {}
 *
 * // A function that expects the payload.
 * const myLambdaFunction = new functionless.Function<Payload, void>(this, 'myFunction', ...);
 *
 * // instantiate an aws_events.EventBus Construct
 * const awsBus = new aws_events.EventBus(this, "mybus");
 *
 * // Wrap the aws_events.EventBus with the functionless.EventBus
 * new functionless.EventBus<myEvent>(awsBus)
 *    // when the payload is equal to some value
 *    .when(this, 'rule1', event => event.detail.value === "some value")
 *    // grab the payload
 *    .map(event => event.detail)
 *    // send to the function
 *    .pipe(myLambdaFunction);
 * ```
 *
 * Forwarding to another Event Bus based on some predicate:
 *
 * ```ts
 * // Using an imported event bus
 * const anotherEventBus = aws_event.EventBus.fromEventBusArn(...);
 *
 * new functionless.EventBus<myEvent>(awsBus)
 *    // when the payload is equal to some value
 *    .when(this, 'rule2', event => event.detail.value === "some value")
 *    // send verbatim to the other event bus
 *    .pipe(anotherEventBus);
 * ```
 *
 * @typeParam Evnt - the union type of events that this EventBus can accept.
 *                   `Evnt` is the contravariant version of `OutEvnt` in that
 *                   the bus will accept any of `Evnt` while the EventBus can
 *                   emit any of `OutEvnt`.
 * @typeParam OutEvnt - the union type of events that this EventBus will emit through rules.
 *                      `OutEvnt` is the covariant version of `Evnt` in that
 *                      the bus will emit any of `OutEvnt` while the EventBus can
 *                      can accept any of `Evnt`. This type parameter should be left
 *                      empty to be inferred. ex: `EventBus<Event<Detail1> | Event<Detail2>>`.
 */
export declare class EventBus<in Evnt extends Event, out OutEvnt extends Evnt = Evnt> extends EventBusBase<Evnt, OutEvnt> {
    constructor(scope: Construct, id: string, props?: aws_events.EventBusProps);
    /**
     * Import an {@link aws_events.IEventBus} wrapped with Functionless abilities.
     *
     * @typeParam Evnt - the union of types which are expected on the default {@link EventBus}.
     */
    static fromBus<Evnt extends Event>(bus: aws_events.IEventBus): IEventBus<Evnt>;
    /**
     * Retrieves the default event bus as a singleton on the given stack or the stack of the given construct.
     *
     * Equivalent to doing
     * ```ts
     * const awsBus = aws_events.EventBus.fromEventBusName(Stack.of(scope), id, "default");
     * new functionless.EventBus.fromBus(awsBus);
     * ```
     *
     * @typeParam Evnt - the union of types which are expected on the default {@link EventBus}.
     */
    static default<Evnt extends Event>(stack: Stack): DefaultEventBus<Evnt>;
    static default<Evnt extends Event>(scope: Construct): DefaultEventBus<Evnt>;
    /**
     * Creates a schedule based event bus rule on the default bus.
     *
     * Always sends the {@link ScheduledEvent} event.
     *
     * ```ts
     * // every hour
     * const everyHour = EventBus.schedule(scope, 'cron', aws_events.Schedule.rate(Duration.hours(1)));
     *
     * const func = new Function(scope, 'func', async (payload: {id: string}) => console.log(payload.id));
     *
     * everyHour
     *    .map(event => ({id: event.id}))
     *    .pipe(func);
     * ```
     */
    static schedule(scope: Construct, id: string, schedule: aws_events.Schedule, props?: Omit<aws_events.RuleProps, "schedule" | "eventBus" | "eventPattern" | "targets">): ImportedRule<ScheduledEvent>;
}
/**
 * @typeParam Evnt - the union type of events that this EventBus can accept.
 *                   `Evnt` is the contravariant version of `OutEvnt` in that
 *                   the bus will accept any of `Evnt` while the EventBus can
 *                   emit any of `OutEvnt`.
 * @typeParam OutEvnt - the union type of events that this EventBus will emit through rules.
 *                      `OutEvnt` is the covariant version of `Evnt` in that
 *                      the bus will emit any of `OutEvnt` while the EventBus can
 *                      can accept any of `Evnt`. This type parameter should be left
 *                      empty to be inferred. ex: `EventBus<Event<Detail1> | Event<Detail2>>`.
 */
export declare class DefaultEventBus<in Evnt extends Event, out OutEvnt extends Evnt = Evnt> extends EventBusBase<Evnt, OutEvnt> {
    constructor(scope: Construct);
    /**
     * Creates a schedule based event bus rule on the default bus.
     *
     * Always sends the {@link ScheduledEvent} event.
     *
     * ```ts
     * const bus = EventBus.default(scope);
     * // every hour
     * const everyHour = bus.schedule(scope, 'cron', aws_events.Schedule.rate(Duration.hours(1)));
     *
     * const func = new Function(scope, 'func', async (payload: {id: string}) => console.log(payload.id));
     *
     * everyHour
     *    .map(event => ({id: event.id}))
     *    .pipe(func);
     * ```
     */
    schedule(scope: Construct, id: string, schedule: aws_events.Schedule, props?: Omit<aws_events.RuleProps, "schedule" | "eventBus" | "eventPattern" | "targets">): ImportedRule<ScheduledEvent>;
}
/**
 * Defines an integration that can be used in the `pipe` function of an {@link EventBus} (Rule or Transform).
 *
 * ```ts
 * const myEbIntegration = { // an Integration
 *    kind: 'myEbIntegration',
 *    eventBus: {
 *       target: (props, targetInput) => {
 *           // return a RuleTarget
 *       }
 *    }
 * }
 *
 * new EventBus().when("rule", () => true).pipe(myEbIntegration);
 * ```
 *
 * @typeParam - Payload - the type which the {@link Integration} expects as an input from {@link EventBus}.
 * @typeParam - Props - the optional properties the {@link Integration} accepts. Leave undefined to require no properties.
 */
export interface EventBusTargetIntegration<in Payload, in Props extends object | undefined = undefined> {
    /**
     * {@link EventBusTargetIntegration} does not make direct use of `P`. Typescript will ignore P when
     * doing type checking. By making the interface look like there is a property which is of type P,
     * typescript will consider P when type checking.
     *
     * This is useful for cases like {@link IRule.pipe} and {@link IEventTransform.pipe} which need to validate that
     * an integration implements the right EventBus integration.
     *
     * We use a function interface in order to satisfy the covariant relationship that we expect the super-P in as opposed to
     * returning sub-P.
     */
    __payloadBrand: (p: Payload) => void | Promise<void>;
}
export declare type IntegrationWithEventBus<Payload, Props extends object | undefined = undefined> = {
    eventBus: EventBusTargetIntegration<Payload, Props>;
};
/**
 * @typeParam - Payload - the type which the {@link Integration} expects as an input from {@link EventBus}.
 * @typeParam - Props - the optional properties the {@link Integration} accepts. Leave undefined to require no properties.
 */
export declare function makeEventBusIntegration<Payload, Props extends object | undefined = undefined>(integration: Omit<EventBusTargetIntegration<Payload, Props>, "__payloadBrand">): EventBusTargetIntegration<Payload, Props>;
export declare type DynamicProps<Props> = Props extends never ? never : [Props] extends [undefined] ? (props?: Props | undefined) => void : (props: Props) => void;
/**
 * Add a target to the run based on the configuration given.
 */
export declare function pipe<Evnt extends Event, Payload, Props extends object | undefined = undefined, Target extends aws_events.RuleTargetInput | undefined = aws_events.RuleTargetInput | undefined>(rule: IRule<Evnt>, integration: IntegrationWithEventBus<Payload, Props> | ((targetInput: Target) => aws_events.IRuleTarget), props: Props, targetInput: Target): void;
export declare const deploymentOnlyModule = true;
export {};
//# sourceMappingURL=event-bus.d.ts.map