import { type internalEvents } from "../helpers/consts.js";
import { type IsEmptyObject, type IsStringLiteral, type Simplify } from "../helpers/types.js";
import type * as z from "../helpers/validators/zod.js";
import { type CancelledEventPayload, type EventPayload, type FailureEventPayload, type FinishedEventPayload, type InvokedEventPayload, type ScheduledTimerEventPayload } from "../types.js";
/**
 * Declares the shape of an event schema we expect from the user. This may be
 * different to what a user is sending us depending on the supported library,
 * but this standard format is what we require as the end result.
 *
 * @internal
 */
export type StandardEventSchema = {
    name?: string;
    data?: Record<string, any>;
    user?: Record<string, any>;
};
/**
 * A helper type that declares a standardised custom part of the event schema.
 *
 * @public
 */
export type StandardEventSchemas = Record<string, StandardEventSchema>;
/**
 * Asserts that the given type `T` contains a mapping for all internal events.
 *
 * Usage of this ensures that we never forget about an internal event in schemas
 * when adding new ones.
 *
 * It also ensures that the mapped name is not the enum type, as this would
 * require a user to use the enum type to access the event schema to declare
 * triggers, where we want to allow them to use the string literal.
 *
 * @public
 */
export type AssertInternalEventPayloads<T extends Record<internalEvents, EventPayload>> = {
    [K in keyof T as `${K & string}`]: Simplify<Omit<T[K], "name"> & {
        name: `${K & string}`;
    }>;
};
/**
 * A string error used to highlight to a user that they have a clashing name
 * between the event name and the key of the event schema.
 */
type ClashingNameError = "Error: Omit 'name' from event schemas or make sure it matches the key.";
/**
 * Given a type T, check if any of the keys in T are a clashing name. If they
 * are, return the error type, otherwise return the original type.
 */
type CheckNever<T> = ClashingNameError extends T[keyof T] ? IsEmptyObject<T[keyof T]> extends true ? T : ClashingNameError : T;
/**
 * Given a type T, check if any of the keys in T are a clashing name. If they
 * are, return the error type for that key, otherwise return the original type.
 */
type PreventClashingNames<T> = CheckNever<{
    [K in keyof T]: T[K] extends {
        name: infer N;
    } ? N extends K ? T[K] : K extends `${string}*${string}` ? T[K] : ClashingNameError : T[K];
}>;
/**
 * A literal Zod schema, which is a Zod schema that has a literal string as the
 * event name. This can be used to create correct Zod schemas outside of the
 * `EventSchemas` class.
 *
 * @public
 */
export type LiteralZodEventSchema = z.ZodObject<{
    name: z.ZodLiteral<string>;
    data?: z.ValidZodValue;
    user?: z.ValidZodValue;
}>;
/**
 * An array of literal zod event schemas.
 *
 * @public
 */
export type LiteralZodEventSchemas = LiteralZodEventSchema[];
/**
 * A helper type that declares a standardised custom part of the event schema,
 * defined using Zod.
 *
 * @public
 */
export type ZodEventSchemas = Record<string, {
    data?: z.ValidZodValue;
    user?: z.ValidZodValue;
}>;
/**
 * A helper type that takes a union of Zod schemas and extracts the literal
 * matching event from the given schemas. Required when picking out types from
 * a union that require inference to work.
 *
 * @public
 */
export type PickLiterals<T> = {
    [K in keyof T]: Extract<T[K], {
        name: z.ZodLiteral<K>;
    }>;
};
/**
 * A helper type to extract the name from a given literal Zod schema.
 *
 * @public
 */
export type GetName<T> = T extends z.ZodObject<infer U> ? U extends {
    name: z.ZodLiteral<infer S extends string>;
} ? S : never : never;
/**
 * Given an input T, infer the shape of the Zod schema if that input is a Zod
 * object.
 *
 * @public
 */
export type InferZodShape<T> = T extends z.AnyZodObject ? T["shape"] : never;
/**
 * Given a set of literal Zod schemas, convert them into a record of Zod schemas
 * with the literal name as the key.
 *
 * @public
 */
export type LiteralToRecordZodSchemas<T> = PickLiterals<T extends LiteralZodEventSchemas ? {
    [I in keyof T as GetName<T[I]>]: InferZodShape<T[I]>;
} : T extends ZodEventSchemas ? T : never>;
/**
 * Given a set of Zod schemas in a record format, convert them into a standard
 * event schema format.
 *
 * @public
 */
export type ZodToStandardSchema<T extends ZodEventSchemas> = {
    [EventName in keyof T & string]: {
        [Key in keyof T[EventName] & string]: T[EventName][Key] extends z.ZodTypeAny ? z.infer<T[EventName][Key]> : T[EventName][Key];
    };
};
/**
 * A helper type to convert input schemas into the format expected by the
 * `EventSchemas` class, which ensures that each event contains all pieces of
 * information required.
 *
 * It purposefully uses slightly more complex (read: verbose) mapped types to
 * flatten the output and preserve comments.
 *
 * @public
 */
export type StandardEventSchemaToPayload<T> = {
    [K in keyof T & string]: AddName<Simplify<Omit<EventPayload, keyof T[K]> & T[K]>, K>;
};
/**
 * A helper type to add a given name to each object in a type if it doesn't
 * exist as a string literal.
 *
 * Use in this way ensures simpler types can enforce preserving comments.
 */
export type AddName<TObj, TDefaultName extends string> = TObj extends {
    name: string;
} ? IsStringLiteral<TObj["name"]> extends true ? TObj : Simplify<TObj & {
    name: TDefaultName;
}> : Simplify<TObj & {
    name: TDefaultName;
}>;
/**
 * A helper type to combine two event schemas together, ensuring the result is
 * as flat as possible and that we don't accidentally overwrite existing schemas
 * with a generic `string` key.
 *
 * @public
 */
export type Combine<TCurr extends Record<string, EventPayload>, TInc extends StandardEventSchemas> = IsStringLiteral<keyof TCurr & string> extends true ? Simplify<Omit<TCurr, keyof StandardEventSchemaToPayload<TInc>> & StandardEventSchemaToPayload<TInc>> : StandardEventSchemaToPayload<TInc>;
/**
 * Provide an `EventSchemas` class to type events, providing type safety when
 * sending events and running functions via Inngest.
 *
 * You can provide generated Inngest types, custom types, types using Zod, or
 * a combination of the above. See {@link EventSchemas} for more information.
 *
 * @example
 *
 * ```ts
 * export const inngest = new Inngest({
 *   id: "my-app",
 *   schemas: new EventSchemas().fromZod({
 *     "app/user.created": {
 *       data: z.object({
 *         id: z.string(),
 *         name: z.string(),
 *       }),
 *     },
 *   }),
 * });
 * ```
 *
 * @public
 */
export declare class EventSchemas<S extends Record<string, EventPayload> = AssertInternalEventPayloads<{
    [internalEvents.FunctionFailed]: FailureEventPayload;
    [internalEvents.FunctionFinished]: FinishedEventPayload;
    [internalEvents.FunctionInvoked]: InvokedEventPayload;
    [internalEvents.FunctionCancelled]: CancelledEventPayload;
    [internalEvents.ScheduledTimer]: ScheduledTimerEventPayload;
}>> {
    protected runtimeSchemas: Record<string, unknown>;
    private addRuntimeSchemas;
    /**
     * Use generated Inngest types to type events.
     */
    fromGenerated<T extends StandardEventSchemas>(): EventSchemas<Combine<S, T>>;
    /**
     * Use a `Record<>` type to type events.
     *
     * @example
     *
     * ```ts
     * export const inngest = new Inngest({
     *   id: "my-app",
     *   schemas: new EventSchemas().fromRecord<{
     *     "app/user.created": {
     *       data: {
     *         id: string;
     *         name: string;
     *       };
     *     };
     *   }>(),
     * });
     * ```
     */
    fromRecord<T extends StandardEventSchemas>(..._args: PreventClashingNames<T> extends ClashingNameError ? [ClashingNameError] : []): EventSchemas<Combine<S, T>>;
    /**
     * Use a union type to type events.
     *
     * @example
     *
     * ```ts
     * type AccountCreated = {
     *   name: "app/account.created";
     *   data: { org: string };
     *   user: { id: string };
     * };
     *
     * type AccountDeleted = {
     *   name: "app/account.deleted";
     *   data: { org: string };
     *   user: { id: string };
     * };
     *
     * type Events = AccountCreated | AccountDeleted;
     *
     * export const inngest = new Inngest({
     *   id: "my-app",
     *   schemas: new EventSchemas().fromUnion<Events>(),
     * });
     * ```
     */
    fromUnion<T extends {
        name: string;
    } & StandardEventSchema>(): EventSchemas<Combine<S, {
        [K in T["name"]]: Extract<T, {
            name: K;
        }>;
    }>>;
    /**
     * Use Zod to type events.
     *
     * @example
     *
     * ```ts
     * export const inngest = new Inngest({
     *   id: "my-app",
     *   schemas: new EventSchemas().fromZod({
     *     "app/user.created": {
     *       data: z.object({
     *         id: z.string(),
     *         name: z.string(),
     *       }),
     *     },
     *   }),
     * });
     * ```
     */
    fromZod<T extends ZodEventSchemas | LiteralZodEventSchemas>(schemas: T): EventSchemas<Combine<S, ZodToStandardSchema<T extends ZodEventSchemas ? T : LiteralToRecordZodSchemas<T>>>>;
}
export {};
//# sourceMappingURL=EventSchemas.d.ts.map