import { Actor } from '@devvit/shared-types/Actor.js';
import type { JSONObject } from '@devvit/shared-types/json.js';
import type { FormKey } from '@devvit/shared-types/useForm.js';
import type { BaseContext, Configuration, ContextAPIClients, CustomPostType, Form, FormFunction, FormOnSubmitEventHandler, FormToFormValues, IconName, MenuItem, MultiTriggerDefinition, ScheduledJobType, SettingsFormField, TriggerEvent, TriggerEventType, TriggerOnEventHandler } from '../types/index.js';
/**
 * Home for debug flags, settings, and other information. Any type removals
 * may cause type errors but not runtime errors.
 *
 * **Favor ContextDebugInfo since request-based state is preferred.**
 */
type DevvitDebug = {
    /**
     * Should debug block rendering in console.log according to the reified JSX/XML output. Example:
     *
     *     <hstack><text>hi world</text></hstack>
     *
     */
    emitSnapshots?: boolean | undefined;
    /**
     * Should console.log the state of the app after every event.
     *
     */
    emitState?: boolean | undefined;
};
export declare class Devvit extends Actor {
    #private;
    static debug: DevvitDebug;
    /**
     * To use certain APIs and features of Devvit, you must enable them using this function.
     *
     * @param config - The configuration object.
     * @param config.http - Enables the HTTP API.
     * @param config.redditAPI - Enables the Reddit API.
     * @param config.kvStore - Enables the Key Value Storage API.
     * @example
     * ```ts
     * Devvit.configure({
     *   http: true,
     *   redditAPI: true,
     *   kvStore: true,
     *   media: true
     * });
     * ```
     */
    static configure(config: Configuration): void;
    /**
     * Add a menu item to the Reddit UI.
     * @param menuItem - The menu item to add.
     * @param menuItem.label - The label of the menu item.
     * @example
     * ```ts
     * Devvit.addMenuItem({
     *   label: 'My Menu Item',
     *   location: 'subreddit',
     *   onPress: (event, context) => {
     *     const location = event.location;
     *     const targetId = event.targetId;
     *     context.ui.showToast(`You clicked on ${location} ${targetId}`);
     *   }
     * });
     * ```
     */
    static addMenuItem(menuItem: MenuItem): void;
    /**
     * Add a custom post type for your app.
     * @param customPostType - The custom post type to add.
     * @param customPostType.name - The name of the custom post type.
     * @param customPostType.description - An optional description.
     * @param customPostType.height - An optional parameter to set post height, defaults to 'regular'.
     * @param customPostType.render - A function or `Devvit.CustomPostComponent` that returns the UI for the custom post.
     * @example
     * ```ts
     * Devvit.addCustomPostType({
     *   name: 'Counter',
     *   description: 'A simple click counter post.',
     *   render: (context) => {
     *     const [counter, setCounter] = context.useState();
     *
     *     return (
     *       <vstack>
     *         <text>{counter}</text>
     *         <button onPress={() => setCounter(counter => counter + 1)}>Click me!</button>
     *       </vstack>
     *     );
     *   }
     * });
     * ```
     */
    static addCustomPostType(customPostType: CustomPostType): void;
    /**
     * Create a form that can be opened from menu items and custom posts.
     * @param form - The form or a function that returns the form.
     * @param onSubmit - The function to call when the form is submitted.
     * @returns A unique key for the form that can used with `ui.showForm`.
     */
    static createForm<const T extends Form | FormFunction>(form: T, onSubmit: FormOnSubmitEventHandler<FormToFormValues<T>>): FormKey;
    /**
     * Add a scheduled job type for your app. This will allow you to schedule jobs using the `scheduler` API.
     * @param job - The scheduled job type to add.
     * @param job.name - The name of the scheduled job type.
     * @param job.onRun - The function to call when the scheduled job is run.
     * @example
     * ```ts
     * Devvit.addSchedulerJob({
     *   name: 'checkNewPosts',
     *   onRun: async (event, context) => {
     *     const newPosts = await context.reddit.getNewPosts({ limit: 5 }).all();
     *     for (const post of newPosts) {
     *       if (post.title.includes('bad word')) {
     *         await post.remove();
     *       }
     *     }
     *   }
     * });
     *
     * Devvit.addMenuItem({
     *   label: 'Check for new posts',
     *   location: 'location',
     *   onPress: (event, context) => {
     *     const { scheduler } = context;
     *     const = await scheduler.runJob({
     *       name: 'checkNewPosts',
     *       when: new Date(Date.now() + 5000) // in 5 seconds
     *     });
     *   }
     * });
     * ```
     */
    static addSchedulerJob<T extends JSONObject | undefined>(job: ScheduledJobType<T>): void;
    /**
     * Add settings that can be configured to customize the behavior of your app. There are two levels of settings: App settings (scope: 'app') and
     * install settings (scope: 'installation' or unspecified scope). Install settings are meant to be configured by the user that installs your app.
     * This is a good place to add anything that a user might want to change to personalize the app (e.g. the default city to show the weather for or a
     * specific sport team that a subreddit follows). Note that these are good for subreddit level customization but not necessarily good for things
     * that might be different for two users in a subreddit (e.g. setting the default city to show the weather for is only useful at a sub level if
     * the sub is for a specific city or region). Install settings can be viewed and configured here: https://developers.reddit.com/r/subreddit-name/apps/app-name.
     * App settings can be accessed and consumed by all installations of the app. This is mainly useful for developer secrets/API keys that your
     * app needs to function. They can only be changed/viewed by you via the CLI (devvit settings set and devvit settings list). This ensures secrets
     * are persisted in an encrypted store and don't get committed in the source code. You should never paste your actual key into any fields passed into
     * Devvit.addSettings - this is merely where you state what your API key's name and description are. You will be able to set the actual value of the key via CLI.
     * Note: setting names must be unique across all settings.
     * @param fields - Fields for the app and installation settings.
     * @example
     * ```ts
     * Devvit.addSettings([
     *   {
     *     type: 'string',
     *     name: 'weather-api-key',
     *     label: 'My weather.com API key',
     *     scope: SettingScope.App,
     *     isSecret: true
     *   },
     *   {
     *     type: 'string',
     *     name: 'Default City',
     *     label: 'Default city to show the weather for by default',
     *     scope: SettingScope.Installation,
     *     onValidate: ({ value }) => {
     *       if (!isValidCity(value)) {
     *         return 'You must ender a valid city: ${validCities.join(", ")}';
     *       }
     *     }
     *   },
     *   {
     *     type: 'number',
     *     name: 'Default Forecast Window (in days)',
     *     label: 'The number of days to show for forecast for by default',
     *     scope: SettingScope.Installation,
     *     onValidate: ({ value }) => {
     *       if (value > 10 || value < 1) {
     *         return 'Forecast window must be from 1 to 10 days';
     *       }
     *     }
     *   },
     * ]);
     * ```
     */
    static addSettings(fields: SettingsFormField[]): void;
    /**
     * Add a trigger handler that will be invoked when the given event
     * occurs in a subreddit where the app is installed.
     *
     * @param triggerDefinition - The trigger definition.
     * @param triggerDefinition.event - The event to listen for.
     * @param triggerDefinition.events - The events to listen for.
     * @param triggerDefinition.onEvent - The function to call when the event happens.
     * @example
     * ```ts
     * Devvit.addTrigger({
     *   event: 'PostSubmit',
     *   async onEvent(event, context) {
     *     console.log("a new post was created!")
     *   }
     * });
     *
     * Devvit.addTrigger({
     *   events: ['PostSubmit', 'PostReport'],
     *   async onEvent(event, context){
     *     if (event.type === 'PostSubmit') {
     *       console.log("a new post was created!")
     *     } else if (event.type === 'PostReport') {
     *       console.log("a post was reported!")
     *     }
     *   }
     * });
     * ```
     */
    static addTrigger<T extends keyof TriggerEventType>(definition: {
        event: T;
        onEvent: TriggerOnEventHandler<TriggerEventType[T]>;
    }): typeof Devvit;
    static addTrigger<Event extends TriggerEvent>(triggerDefinition: MultiTriggerDefinition<Event>): typeof Devvit;
}
export declare namespace Devvit {
    type Fragment = JSX.Fragment;
    type ElementChildren = JSX.Element | JSX.Children | undefined;
    type StringChild = Fragment | string | number;
    type StringChildren = StringChild | (StringChild | StringChild[])[] | undefined;
    function createElement(type: Blocks.IntrinsicElementsType, props: {
        [key: string]: unknown;
    } | undefined, ...children: JSX.Children[]): BlockElement;
    /** The current app context of the event or render. */
    type Context = ContextAPIClients & BaseContext;
    type BlockComponentProps<P = {
        [key: string]: unknown;
    }> = P & {
        children?: JSX.Children;
    };
    type BlockComponent<P = {
        [key: string]: unknown;
    }> = (props: BlockComponentProps<P>, context: Context) => JSX.Element;
    type CustomPostComponent = (context: Context) => JSX.Element;
    namespace Blocks {
        interface IntrinsicElements {
            blocks: Devvit.Blocks.RootProps;
            hstack: Devvit.Blocks.StackProps;
            vstack: Devvit.Blocks.StackProps;
            zstack: Devvit.Blocks.StackProps;
            text: Devvit.Blocks.TextProps;
            button: Devvit.Blocks.ButtonProps;
            image: Devvit.Blocks.ImageProps;
            spacer: Devvit.Blocks.SpacerProps;
            icon: Devvit.Blocks.IconProps;
            avatar: Devvit.Blocks.AvatarProps;
            webview: Devvit.Blocks.WebViewProps;
        }
        type IntrinsicElementsType = keyof IntrinsicElements;
        type SizePixels = `${number}px`;
        type SizePercent = `${number}%`;
        type SizeString = SizePixels | SizePercent | number;
        type Alignment = `${VerticalAlignment}` | `${HorizontalAlignment}` | `${VerticalAlignment} ${HorizontalAlignment}` | `${HorizontalAlignment} ${VerticalAlignment}`;
        type AvatarBackground = 'light' | 'dark';
        type AvatarFacing = 'left' | 'right';
        type AvatarSize = 'xxsmall' | 'xsmall' | 'small' | 'medium' | 'large' | 'xlarge' | 'xxlarge' | 'xxxlarge';
        type ButtonAppearance = 'secondary' | 'primary' | 'plain' | 'bordered' | 'media' | 'destructive' | 'caution' | 'success';
        /**
         * Affects the button height.
         * small = 32px;
         * medium = 40px;
         * large = 48px;
         */
        type ButtonSize = 'small' | 'medium' | 'large';
        type ColorString = string;
        /**
         * thin = 1px;
         * thick = 2px;
         */
        type ContainerBorderWidth = Thickness;
        /**
         * small = 8px;
         * medium = 16px;
         * large = 24px;
         */
        type ContainerCornerRadius = 'none' | 'small' | 'medium' | 'large' | 'full';
        /**
         * small = 8px;
         * medium = 16px;
         * large = 32px;
         */
        type ContainerGap = 'none' | 'small' | 'medium' | 'large';
        /**
         * xsmall = 4px;
         * small = 8px;
         * medium = 16px;
         * large = 32px;
         */
        type ContainerPadding = 'none' | 'xsmall' | 'small' | 'medium' | 'large';
        type HorizontalAlignment = 'start' | 'center' | 'end';
        /**
         * xsmall = 12px;
         * small = 16px;
         * medium = 20px;
         * large = 24px;
         */
        type IconSize = 'xsmall' | 'small' | 'medium' | 'large';
        type ImageResizeMode = 'none' | 'fit' | 'fill' | 'cover' | 'scale-down';
        /**
         * xsmall = 4px;
         * small = 8px;
         * medium = 16px;
         * large = 32px;
         */
        type SpacerSize = 'xsmall' | 'small' | 'medium' | 'large';
        type SpacerShape = 'invisible' | 'thin' | 'square';
        /**
         * thin = 1px;
         * thick = 2px;
         */
        type TextOutline = Thickness;
        /**
         * xsmall = 10px;
         * small = 12px;
         * medium = 14px;
         * large = 16px;
         * xlarge = 18px;
         * xxlarge = 24px;
         */
        type TextSize = 'xsmall' | 'small' | 'medium' | 'large' | 'xlarge' | 'xxlarge';
        type TextStyle = 'body' | 'metadata' | 'heading';
        type TextWeight = 'regular' | 'bold';
        type TextOverflow = 'clip' | 'ellipsis';
        type Thickness = 'none' | 'thin' | 'thick';
        type VerticalAlignment = 'top' | 'middle' | 'bottom';
        type RootHeight = 'regular' | 'tall';
        type BaseProps = {
            width?: SizeString;
            height?: SizeString;
            minWidth?: SizeString;
            minHeight?: SizeString;
            maxWidth?: SizeString;
            maxHeight?: SizeString;
            grow?: boolean;
            /**
             * This optional field provides some efficiencies around re-ordering elements in a list.  Rather
             * Than re-rendering the entire list, the client can use the key to determine if the element has
             * changed.  In the example below, if a and b were swapped, the client would know to reuse the
             * existing elements from b, rather than re-creating an expensive tree of elements.
             *
             * Unlike id, key is local to the parent element.  This means that the same key can be used in different
             * parts of the tree without conflict.
             *
             *     <hstack>
             *         <text key="a">hi world</text>
             *         <hstack key="b">...deeply nested content...</hstack>
             *     </hstack>
             */
            key?: string;
            /**
             * This optional field provides a unique identifier for the element.  This is useful for ensuring
             * re-use of elements across renders.  See the `key` field for more information.  Unlike key, id
             * is global.  You cannot have two elements with the same id in the same tree.
             */
            id?: string;
        };
        type OnPressEventHandler = (data: JSONObject) => void | Promise<void>;
        type OnWebViewEventHandler = (message: JSONObject) => void | Promise<void>;
        type Actionable = {
            onPress?: OnPressEventHandler | undefined;
        };
        type WebViewActionable = {
            onMessage?: OnWebViewEventHandler | undefined;
        };
        type ActionHandlers = keyof (Actionable & WebViewActionable);
        type HasElementChildren = {
            children?: Devvit.ElementChildren;
        };
        type HasStringChildren = {
            children?: Devvit.StringChildren;
        };
        type RootProps = HasElementChildren & {
            height?: Devvit.Blocks.RootHeight | undefined;
        };
        type StackProps = BaseProps & HasElementChildren & Actionable & {
            reverse?: boolean | undefined;
            alignment?: Alignment;
            padding?: ContainerPadding | undefined;
            gap?: ContainerGap | undefined;
            border?: ContainerBorderWidth | undefined;
            borderColor?: ColorString | undefined;
            lightBorderColor?: ColorString | undefined;
            darkBorderColor?: ColorString | undefined;
            cornerRadius?: ContainerCornerRadius | undefined;
            backgroundColor?: ColorString | undefined;
            lightBackgroundColor?: ColorString | undefined;
            darkBackgroundColor?: ColorString | undefined;
        };
        type TextProps = BaseProps & HasStringChildren & Actionable & {
            size?: TextSize | undefined;
            weight?: TextWeight | undefined;
            color?: ColorString | undefined;
            lightColor?: ColorString | undefined;
            darkColor?: ColorString | undefined;
            alignment?: Alignment | undefined;
            outline?: TextOutline | undefined;
            style?: TextStyle | undefined;
            selectable?: boolean | undefined;
            wrap?: boolean | undefined;
            overflow?: TextOverflow | undefined;
        };
        type ButtonProps = BaseProps & HasStringChildren & Actionable & {
            icon?: IconName | undefined;
            size?: ButtonSize | undefined;
            appearance?: ButtonAppearance | undefined;
            textColor?: ColorString | undefined;
            lightTextColor?: ColorString | undefined;
            darkTextColor?: ColorString | undefined;
            disabled?: boolean | undefined;
        };
        type ImageProps = BaseProps & Actionable & {
            url: string;
            imageWidth: SizePixels | number;
            imageHeight: SizePixels | number;
            description?: string | undefined;
            resizeMode?: ImageResizeMode | undefined;
        };
        type SpacerProps = BaseProps & {
            size?: SpacerSize | undefined;
            shape?: SpacerShape | undefined;
        };
        type IconProps = BaseProps & HasStringChildren & Actionable & {
            name: IconName;
            color?: ColorString | undefined;
            lightColor?: ColorString | undefined;
            darkColor?: ColorString | undefined;
            size?: IconSize | undefined;
        };
        type AvatarProps = BaseProps & Actionable & {
            thingId: string;
            facing?: AvatarFacing | undefined;
            size?: AvatarSize | undefined;
            background?: AvatarBackground | undefined;
        };
        type WebViewProps = BaseProps & WebViewActionable & {
            url: string;
            state?: JSONObject;
        };
    }
}
export type BlockElement = {
    type: JSX.ComponentFunction | string | undefined;
    props: {
        [key: string]: unknown;
    } | undefined;
    children: JSX.Element[];
};
declare global {
    namespace JSX {
        interface IntrinsicElements extends Devvit.Blocks.IntrinsicElements {
        }
        type Fragment = Iterable<JSX.Element>;
        type SyncElement = BlockElement | JSX.Fragment | string | number | boolean | null;
        type Element = SyncElement | Promise<SyncElement>;
        type ElementChildrenAttribute = {
            children: {};
        };
        type Children = JSX.Element | JSX.Element[];
        type Props<T extends {} = {}> = T & {
            children?: Devvit.ElementChildren;
        };
        type ComponentFunction = (props: JSX.Props, context: Devvit.Context) => JSX.Element;
    }
}
export {};
//# sourceMappingURL=Devvit.d.ts.map