import * as vue from 'vue';
import { App, Ref, Component } from 'vue';

interface AppBaseContext {
    readonly appName: string;
    readonly blockName: string;
    readonly version: string;
    readonly scriptUrl: string;
    readonly imageBuckets: Record<string, string>;
    readonly globalDesign: Record<string, Record<string, unknown>>;
}
interface AppBaseData<C, D> {
    readonly content: C;
    readonly design: D;
    readonly defaults: Record<string, unknown>;
    readonly externalContent: ExternalContentData;
}
interface AppBaseState<C, D> {
    readonly context: AppBaseContext;
    readonly data: AppBaseData<C, D>;
}

interface GlobalColors {
    title?: Color;
    body?: Color;
    button?: Color;
    link?: Color;
    background?: Color;
}
interface GlobalFonts {
    title: string;
    body: string;
}
interface GlobalTextSize {
    title: number;
    subtitle: number;
    body: number;
}
interface GlobalButtonSize {
    small: number;
    medium: number;
    large: number;
}
type AppearanceEffectType = 'none' | 'fade-in' | 'fade-in-up';
interface GlobalLayout {
    maxWidth: number;
    tileMargin: number;
    appearanceEffect: AppearanceEffectType;
}
interface GlobalDesign {
    color?: GlobalColors;
    fontFamily?: GlobalFonts;
    textSize?: GlobalTextSize;
    buttonSize?: GlobalButtonSize;
    layout?: GlobalLayout;
    customCss?: string;
}

interface VueBaseProps<CONTENT, DESIGN> {
    init: (app: App<Element>, contextValue: AppBaseContext, contentValue: CONTENT, designValue: DESIGN, defaultsValue: Record<string, unknown>, externalContent: ExternalContentData, globalDesignValue: GlobalDesign) => void;
    update: (app: App<Element>, contentValue: CONTENT, designValue: DESIGN, defaultsValue: Record<string, unknown>, externalContent: ExternalContentData, globalDesignValue: GlobalDesign) => void;
    readonly context: Ref<AppBaseContext>;
    readonly content: Ref<CONTENT>;
    readonly design: Ref<DESIGN>;
    readonly defaults: Ref<Record<string, unknown>>;
    readonly site: Ref<SiteContent>;
    readonly category?: Ref<Category | undefined>;
    readonly globalDesign: Ref<GlobalDesign>;
}
declare function useVueBaseProps<CONTENT, DESIGN>(): VueBaseProps<CONTENT, DESIGN>;

interface InputBoxContent {
    hasContent: boolean;
    value: string;
}
declare function useInputboxElementContent<CONTENT>(elementName: string, externalContent?: Record<string, unknown>): {
    hasContent: boolean;
    value: string | undefined;
};

interface TextAreaContent {
    hasContent: boolean;
    value: string;
}
declare function useTextareaElementContent<CONTENT>(elementName: string, externalContent?: Record<string, unknown>): {
    hasContent: boolean;
    value: string | undefined;
};

interface ButtonContent {
    title: string;
    type: ActionLinkType;
    link?: string;
    email?: string;
    phone?: string;
    tileDivId?: string;
    pageId?: string;
    pageUrl?: string;
    hasTitle: boolean;
    hasLink: boolean;
    performAction: () => void;
}
declare function useButtonElementContent<CONTENT>(elementName: string, externalContent?: Record<string, unknown>): {
    title: string | undefined;
    type: ActionLinkType | undefined;
    link: string | undefined;
    email: string | undefined;
    phone: string | undefined;
    tileDivId: string | null;
    pageId: string | undefined;
    pageUrl: string | undefined;
    hasTitle: boolean;
    hasLink: boolean;
    performAction: (() => void) | undefined;
};

interface ImageContent {
    hasContent: boolean;
    lowResolutionMobileImage: string;
    highResolutionMobileImage: string;
    lowResolutionDesktopImage: string;
    highResolutionDesktopImage: string;
}
declare function useImageElementContent<CONTENT>(elementName: string, externalContent?: Record<string, unknown>): {
    hasContent: boolean;
    lowResolutionMobileImage: string;
    highResolutionMobileImage: string;
    lowResolutionDesktopImage: string;
    highResolutionDesktopImage: string;
};

interface ToggleContent {
    hasContent: boolean;
    value: boolean;
}
declare function useToggleElementContent<CONTENT>(elementName: string, externalContent?: Record<string, unknown>): {
    hasContent: boolean;
    value: boolean | undefined;
};

interface SelectBoxContent {
    hasContent: boolean;
    value: string;
}
declare function useSelectboxElementContent<CONTENT>(elementName: string, externalContent?: Record<string, unknown>): {
    hasContent: boolean;
    value: string | undefined;
};

declare function useMenuElementContent<CONTENT>(elementName: keyof CONTENT): {
    hasContent: boolean;
    items: {
        performAction: (() => void) | undefined;
        id: string;
        title?: string;
        type?: ActionLinkType;
        link?: string;
        email?: string;
        phone?: string;
        tileIdForScroll?: string;
        pageIdForNavigate?: string;
        showStoreCategories?: boolean;
        isSubmenuOpened?: boolean;
        categoryId?: number;
    }[];
};

declare function useNavigationMenuElementContent<CONTENT>(): {
    hasContent: boolean;
    items: {
        performAction: (() => void) | undefined;
        id: string;
        title?: string;
        type?: ActionLinkType;
        link?: string;
        email?: string;
        phone?: string;
        tileIdForScroll?: string;
        pageIdForNavigate?: string;
        showStoreCategories?: boolean;
        isSubmenuOpened?: boolean;
        categoryId?: number;
    }[];
};

interface Card {
    title: string;
    settings: Record<string, unknown>;
}
interface Deck {
    cards: Card[];
}
declare enum EditorTypes {
    INPUTBOX = "INPUTBOX",
    TEXTAREA = "TEXTAREA",
    BUTTON = "BUTTON",
    IMAGE = "IMAGE",
    TOGGLE = "TOGGLE",
    SELECTBOX = "SELECTBOX"
}
declare function useDeckElementContent<CONTENT>(elementName: keyof CONTENT): {
    hasContent: boolean;
    cards: Card[] | undefined;
    getReactiveRef: typeof getReactiveRef;
};
declare function getReactiveRef(card: Card | undefined, editorType: EditorTypes, contentElementName: string): {
    hasContent: boolean;
    lowResolutionMobileImage: string;
    highResolutionMobileImage: string;
    lowResolutionDesktopImage: string;
    highResolutionDesktopImage: string;
} | {
    hasContent: boolean;
    value: string | undefined;
} | {
    hasContent: boolean;
    value: boolean | undefined;
} | {
    title: string | undefined;
    type: ActionLinkType | undefined;
    link: string | undefined;
    email: string | undefined;
    phone: string | undefined;
    tileDivId: string | null;
    pageId: string | undefined;
    pageUrl: string | undefined;
    hasTitle: boolean;
    hasLink: boolean;
    performAction: (() => void) | undefined;
} | undefined;

declare function useLogoElementContent<CONTENT>(): {
    type: LogoType | undefined;
    text: string | undefined;
    image: {
        lowResolutionMobileImage: string;
        highResolutionMobileImage: string;
        lowResolutionDesktopImage: string;
        highResolutionDesktopImage: string;
    };
};

declare function useTextElementDesign<DESIGN>(elementName: keyof DESIGN): {
    font: string | undefined;
    size: number | GlobalTextSizeString | undefined;
    bold: boolean | undefined;
    italic: boolean | undefined;
    color: Color | GlobalColorsString | undefined;
    visible: boolean | undefined;
};

declare function useTextareaElementDesign<DESIGN>(elementName: keyof DESIGN): {
    font: string | undefined;
    size: number | GlobalTextSizeString | undefined;
    bold: boolean | undefined;
    italic: boolean | undefined;
    color: Color | GlobalColorsString | undefined;
    visible: boolean;
    whiteSpace: string;
};

declare function useButtonElementDesign<DESIGN>(elementName: keyof DESIGN): {
    appearance: ButtonAppearance | undefined;
    font: string | undefined;
    size: ButtonSize | undefined;
    style: ButtonStyle | undefined;
    color: Color | GlobalColorsString | undefined;
    visible: boolean | undefined;
};

declare function useImageElementDesign<DESIGN>(elementName: keyof DESIGN): {
    overlay: Overlay | undefined;
    visible: boolean | undefined;
};

declare function useToggleElementDesign<DESIGN>(elementName: keyof DESIGN): {
    enabled: boolean | undefined;
};

declare function useSelectboxElementDesign<DESIGN>(elementName: keyof DESIGN): {
    value: string | undefined;
};

declare function useBackgroundElementDesign<DESIGN>(elementName: keyof DESIGN): {
    background: Background | undefined;
};

declare function useLayoutElementDesign(): {
    layout: string | undefined;
};

declare function useLogoElementDesign<DESIGN>(): vue.ComputedRef<LogoDesignData>;

interface VueServerAppExtensions {
    init?: (app: App<Element>) => void;
    render?: <C, D>(app: App<Element>, context: AppBaseContext, data: AppBaseData<C, D>) => void;
}
interface VueRenderResult {
    readonly html: string;
    readonly state: unknown;
}
declare function createVueServerApp<C, D>(appComponent: Component, extensions?: VueServerAppExtensions): {
    init: () => {
        render: (context: AppBaseContext, data: AppBaseData<C, D>) => Promise<VueRenderResult>;
    };
};

interface VueClientAppExtensions {
    init?: (app: App<Element>) => void;
    mount?: <C, D, S extends AppBaseState<C, D>>(app: App<Element>, rootContainer: string, state: S) => void;
    update?: <C, D, S extends AppBaseState<C, D>>(app: App<Element>, state: S) => void;
    unmount?: (app: App<Element>) => void;
}
declare function createVueClientApp<C, D>(appComponent: Component, extensions?: VueClientAppExtensions): {
    init: () => {
        mount: <S extends AppBaseState<C, D>>(rootContainer: string, state: S) => void;
        update: <S extends AppBaseState<C, D>>(state: S) => void;
        unmount: () => void;
    };
};

interface InstantsiteTilePromise {
    add(callback: (id: string) => void): void;
}
interface InstantsiteJSAPI {
    /**
       * Retrieves the current site ID.
       *
       * @returns {number} The site ID.
       */
    getSiteId: () => number;
    /**
       * Retrieves the public token for a given app.
       *
       * @param {string} appId - The ID of the app.
       * @returns {string | undefined} The app's public token, or `undefined` if not found.
       */
    getAppPublicToken: (appId: string) => string | undefined;
    /**
       * Retrieves the public configuration for a given app.
       *
       * @param {string} appId - The ID of the app.
       * @returns {string | undefined} The app's public configuration, or `undefined` if not found.
       */
    getAppPublicConfig: (appId: string) => string | undefined;
    /**
       * An event that triggers when a tile is loaded.
       *
       * @type {InstantsiteTilePromise}
       *
       * @example
       * ```ts
       * const tileLoadedPromise = instantsiteJsApi?.onTileLoaded;
       *
       * tileLoadedPromise?.add((tileId) => {
       *     console.log('Tile loaded:', tileId);
       * });
       * ```
       */
    onTileLoaded: InstantsiteTilePromise;
    /**
       * An event that triggers when a tile is unloaded.
       *
       * @type {InstantsiteTilePromise}
       *
       * @example
       * ```ts
       * const tileUnloadedPromise = instantsiteJsApi?.onTileUnloaded;
       *
       * tileUnloadedPromise?.add((tileId) => {
       *     console.log('Tile unloaded:', tileId);
       * });
       * ```
       */
    onTileUnloaded: InstantsiteTilePromise;
    /**
       * Opens the search page with the specified keyword.
       *
       * @param {string | undefined} keyword - The keyword to search for.
       * @returns {void}
       */
    openSearchPage: (keyword: string | undefined) => void;
}

declare function useInstantsiteJsApi(): InstantsiteJSAPI | undefined;

// This definition file follows a somewhat unusual format. ESTree allows
// runtime type checks based on the `type` parameter. In order to explain this
// to typescript we want to use discriminated union types:
// https://github.com/Microsoft/TypeScript/pull/9163
//
// For ESTree this is a bit tricky because the high level interfaces like
// Node or Function are pulling double duty. We want to pass common fields down
// to the interfaces that extend them (like Identifier or
// ArrowFunctionExpression), but you can't extend a type union or enforce
// common fields on them. So we've split the high level interfaces into two
// types, a base type which passes down inherited fields, and a type union of
// all types which extend the base type. Only the type union is exported, and
// the union is how other types refer to the collection of inheriting types.
//
// This makes the definitions file here somewhat more difficult to maintain,
// but it has the notable advantage of making ESTree much easier to use as
// an end user.

interface BaseNodeWithoutComments {
    // Every leaf interface that extends BaseNode must specify a type property.
    // The type property should be a string literal. For example, Identifier
    // has: `type: "Identifier"`
    type: string;
    loc?: SourceLocation | null | undefined;
    range?: [number, number] | undefined;
}

interface BaseNode extends BaseNodeWithoutComments {
    leadingComments?: Comment[] | undefined;
    trailingComments?: Comment[] | undefined;
}

interface Comment extends BaseNodeWithoutComments {
    type: "Line" | "Block";
    value: string;
}

interface SourceLocation {
    source?: string | null | undefined;
    start: Position;
    end: Position;
}

interface Position {
    /** >= 1 */
    line: number;
    /** >= 0 */
    column: number;
}

interface BaseFunction extends BaseNode {
    params: Pattern[];
    generator?: boolean | undefined;
    async?: boolean | undefined;
    // The body is either BlockStatement or Expression because arrow functions
    // can have a body that's either. FunctionDeclarations and
    // FunctionExpressions have only BlockStatement bodies.
    body: BlockStatement | Expression;
}

type Statement =
    | ExpressionStatement
    | BlockStatement
    | StaticBlock
    | EmptyStatement
    | DebuggerStatement
    | WithStatement
    | ReturnStatement
    | LabeledStatement
    | BreakStatement
    | ContinueStatement
    | IfStatement
    | SwitchStatement
    | ThrowStatement
    | TryStatement
    | WhileStatement
    | DoWhileStatement
    | ForStatement
    | ForInStatement
    | ForOfStatement
    | Declaration;

interface BaseStatement extends BaseNode {}

interface EmptyStatement extends BaseStatement {
    type: "EmptyStatement";
}

interface BlockStatement extends BaseStatement {
    type: "BlockStatement";
    body: Statement[];
    innerComments?: Comment[] | undefined;
}

interface StaticBlock extends Omit<BlockStatement, "type"> {
    type: "StaticBlock";
}

interface ExpressionStatement extends BaseStatement {
    type: "ExpressionStatement";
    expression: Expression;
}

interface IfStatement extends BaseStatement {
    type: "IfStatement";
    test: Expression;
    consequent: Statement;
    alternate?: Statement | null | undefined;
}

interface LabeledStatement extends BaseStatement {
    type: "LabeledStatement";
    label: Identifier;
    body: Statement;
}

interface BreakStatement extends BaseStatement {
    type: "BreakStatement";
    label?: Identifier | null | undefined;
}

interface ContinueStatement extends BaseStatement {
    type: "ContinueStatement";
    label?: Identifier | null | undefined;
}

interface WithStatement extends BaseStatement {
    type: "WithStatement";
    object: Expression;
    body: Statement;
}

interface SwitchStatement extends BaseStatement {
    type: "SwitchStatement";
    discriminant: Expression;
    cases: SwitchCase[];
}

interface ReturnStatement extends BaseStatement {
    type: "ReturnStatement";
    argument?: Expression | null | undefined;
}

interface ThrowStatement extends BaseStatement {
    type: "ThrowStatement";
    argument: Expression;
}

interface TryStatement extends BaseStatement {
    type: "TryStatement";
    block: BlockStatement;
    handler?: CatchClause | null | undefined;
    finalizer?: BlockStatement | null | undefined;
}

interface WhileStatement extends BaseStatement {
    type: "WhileStatement";
    test: Expression;
    body: Statement;
}

interface DoWhileStatement extends BaseStatement {
    type: "DoWhileStatement";
    body: Statement;
    test: Expression;
}

interface ForStatement extends BaseStatement {
    type: "ForStatement";
    init?: VariableDeclaration | Expression | null | undefined;
    test?: Expression | null | undefined;
    update?: Expression | null | undefined;
    body: Statement;
}

interface BaseForXStatement extends BaseStatement {
    left: VariableDeclaration | Pattern;
    right: Expression;
    body: Statement;
}

interface ForInStatement extends BaseForXStatement {
    type: "ForInStatement";
}

interface DebuggerStatement extends BaseStatement {
    type: "DebuggerStatement";
}

type Declaration = FunctionDeclaration | VariableDeclaration | ClassDeclaration;

interface BaseDeclaration extends BaseStatement {}

interface MaybeNamedFunctionDeclaration extends BaseFunction, BaseDeclaration {
    type: "FunctionDeclaration";
    /** It is null when a function declaration is a part of the `export default function` statement */
    id: Identifier | null;
    body: BlockStatement;
}

interface FunctionDeclaration extends MaybeNamedFunctionDeclaration {
    id: Identifier;
}

interface VariableDeclaration extends BaseDeclaration {
    type: "VariableDeclaration";
    declarations: VariableDeclarator[];
    kind: "var" | "let" | "const";
}

interface VariableDeclarator extends BaseNode {
    type: "VariableDeclarator";
    id: Pattern;
    init?: Expression | null | undefined;
}

interface ExpressionMap {
    ArrayExpression: ArrayExpression;
    ArrowFunctionExpression: ArrowFunctionExpression;
    AssignmentExpression: AssignmentExpression;
    AwaitExpression: AwaitExpression;
    BinaryExpression: BinaryExpression;
    CallExpression: CallExpression;
    ChainExpression: ChainExpression;
    ClassExpression: ClassExpression;
    ConditionalExpression: ConditionalExpression;
    FunctionExpression: FunctionExpression;
    Identifier: Identifier;
    ImportExpression: ImportExpression;
    Literal: Literal;
    LogicalExpression: LogicalExpression;
    MemberExpression: MemberExpression;
    MetaProperty: MetaProperty;
    NewExpression: NewExpression;
    ObjectExpression: ObjectExpression;
    SequenceExpression: SequenceExpression;
    TaggedTemplateExpression: TaggedTemplateExpression;
    TemplateLiteral: TemplateLiteral;
    ThisExpression: ThisExpression;
    UnaryExpression: UnaryExpression;
    UpdateExpression: UpdateExpression;
    YieldExpression: YieldExpression;
}

type Expression = ExpressionMap[keyof ExpressionMap];

interface BaseExpression extends BaseNode {}

type ChainElement = SimpleCallExpression | MemberExpression;

interface ChainExpression extends BaseExpression {
    type: "ChainExpression";
    expression: ChainElement;
}

interface ThisExpression extends BaseExpression {
    type: "ThisExpression";
}

interface ArrayExpression extends BaseExpression {
    type: "ArrayExpression";
    elements: Array<Expression | SpreadElement | null>;
}

interface ObjectExpression extends BaseExpression {
    type: "ObjectExpression";
    properties: Array<Property | SpreadElement>;
}

interface PrivateIdentifier extends BaseNode {
    type: "PrivateIdentifier";
    name: string;
}

interface Property extends BaseNode {
    type: "Property";
    key: Expression | PrivateIdentifier;
    value: Expression | Pattern; // Could be an AssignmentProperty
    kind: "init" | "get" | "set";
    method: boolean;
    shorthand: boolean;
    computed: boolean;
}

interface PropertyDefinition extends BaseNode {
    type: "PropertyDefinition";
    key: Expression | PrivateIdentifier;
    value?: Expression | null | undefined;
    computed: boolean;
    static: boolean;
}

interface FunctionExpression extends BaseFunction, BaseExpression {
    id?: Identifier | null | undefined;
    type: "FunctionExpression";
    body: BlockStatement;
}

interface SequenceExpression extends BaseExpression {
    type: "SequenceExpression";
    expressions: Expression[];
}

interface UnaryExpression extends BaseExpression {
    type: "UnaryExpression";
    operator: UnaryOperator;
    prefix: true;
    argument: Expression;
}

interface BinaryExpression extends BaseExpression {
    type: "BinaryExpression";
    operator: BinaryOperator;
    left: Expression;
    right: Expression;
}

interface AssignmentExpression extends BaseExpression {
    type: "AssignmentExpression";
    operator: AssignmentOperator;
    left: Pattern | MemberExpression;
    right: Expression;
}

interface UpdateExpression extends BaseExpression {
    type: "UpdateExpression";
    operator: UpdateOperator;
    argument: Expression;
    prefix: boolean;
}

interface LogicalExpression extends BaseExpression {
    type: "LogicalExpression";
    operator: LogicalOperator;
    left: Expression;
    right: Expression;
}

interface ConditionalExpression extends BaseExpression {
    type: "ConditionalExpression";
    test: Expression;
    alternate: Expression;
    consequent: Expression;
}

interface BaseCallExpression extends BaseExpression {
    callee: Expression | Super;
    arguments: Array<Expression | SpreadElement>;
}
type CallExpression = SimpleCallExpression | NewExpression;

interface SimpleCallExpression extends BaseCallExpression {
    type: "CallExpression";
    optional: boolean;
}

interface NewExpression extends BaseCallExpression {
    type: "NewExpression";
}

interface MemberExpression extends BaseExpression, BasePattern {
    type: "MemberExpression";
    object: Expression | Super;
    property: Expression | PrivateIdentifier;
    computed: boolean;
    optional: boolean;
}

type Pattern = Identifier | ObjectPattern | ArrayPattern | RestElement | AssignmentPattern | MemberExpression;

interface BasePattern extends BaseNode {}

interface SwitchCase extends BaseNode {
    type: "SwitchCase";
    test?: Expression | null | undefined;
    consequent: Statement[];
}

interface CatchClause extends BaseNode {
    type: "CatchClause";
    param: Pattern | null;
    body: BlockStatement;
}

interface Identifier extends BaseNode, BaseExpression, BasePattern {
    type: "Identifier";
    name: string;
}

type Literal = SimpleLiteral | RegExpLiteral | BigIntLiteral;

interface SimpleLiteral extends BaseNode, BaseExpression {
    type: "Literal";
    value: string | boolean | number | null;
    raw?: string | undefined;
}

interface RegExpLiteral extends BaseNode, BaseExpression {
    type: "Literal";
    value?: RegExp | null | undefined;
    regex: {
        pattern: string;
        flags: string;
    };
    raw?: string | undefined;
}

interface BigIntLiteral extends BaseNode, BaseExpression {
    type: "Literal";
    value?: bigint | null | undefined;
    bigint: string;
    raw?: string | undefined;
}

type UnaryOperator = "-" | "+" | "!" | "~" | "typeof" | "void" | "delete";

type BinaryOperator =
    | "=="
    | "!="
    | "==="
    | "!=="
    | "<"
    | "<="
    | ">"
    | ">="
    | "<<"
    | ">>"
    | ">>>"
    | "+"
    | "-"
    | "*"
    | "/"
    | "%"
    | "**"
    | "|"
    | "^"
    | "&"
    | "in"
    | "instanceof";

type LogicalOperator = "||" | "&&" | "??";

type AssignmentOperator =
    | "="
    | "+="
    | "-="
    | "*="
    | "/="
    | "%="
    | "**="
    | "<<="
    | ">>="
    | ">>>="
    | "|="
    | "^="
    | "&="
    | "||="
    | "&&="
    | "??=";

type UpdateOperator = "++" | "--";

interface ForOfStatement extends BaseForXStatement {
    type: "ForOfStatement";
    await: boolean;
}

interface Super extends BaseNode {
    type: "Super";
}

interface SpreadElement extends BaseNode {
    type: "SpreadElement";
    argument: Expression;
}

interface ArrowFunctionExpression extends BaseExpression, BaseFunction {
    type: "ArrowFunctionExpression";
    expression: boolean;
    body: BlockStatement | Expression;
}

interface YieldExpression extends BaseExpression {
    type: "YieldExpression";
    argument?: Expression | null | undefined;
    delegate: boolean;
}

interface TemplateLiteral extends BaseExpression {
    type: "TemplateLiteral";
    quasis: TemplateElement[];
    expressions: Expression[];
}

interface TaggedTemplateExpression extends BaseExpression {
    type: "TaggedTemplateExpression";
    tag: Expression;
    quasi: TemplateLiteral;
}

interface TemplateElement extends BaseNode {
    type: "TemplateElement";
    tail: boolean;
    value: {
        /** It is null when the template literal is tagged and the text has an invalid escape (e.g. - tag`\unicode and \u{55}`) */
        cooked?: string | null | undefined;
        raw: string;
    };
}

interface AssignmentProperty extends Property {
    value: Pattern;
    kind: "init";
    method: boolean; // false
}

interface ObjectPattern extends BasePattern {
    type: "ObjectPattern";
    properties: Array<AssignmentProperty | RestElement>;
}

interface ArrayPattern extends BasePattern {
    type: "ArrayPattern";
    elements: Array<Pattern | null>;
}

interface RestElement extends BasePattern {
    type: "RestElement";
    argument: Pattern;
}

interface AssignmentPattern extends BasePattern {
    type: "AssignmentPattern";
    left: Pattern;
    right: Expression;
}
interface BaseClass extends BaseNode {
    superClass?: Expression | null | undefined;
    body: ClassBody;
}

interface ClassBody extends BaseNode {
    type: "ClassBody";
    body: Array<MethodDefinition | PropertyDefinition | StaticBlock>;
}

interface MethodDefinition extends BaseNode {
    type: "MethodDefinition";
    key: Expression | PrivateIdentifier;
    value: FunctionExpression;
    kind: "constructor" | "method" | "get" | "set";
    computed: boolean;
    static: boolean;
}

interface MaybeNamedClassDeclaration extends BaseClass, BaseDeclaration {
    type: "ClassDeclaration";
    /** It is null when a class declaration is a part of the `export default class` statement */
    id: Identifier | null;
}

interface ClassDeclaration extends MaybeNamedClassDeclaration {
    id: Identifier;
}

interface ClassExpression extends BaseClass, BaseExpression {
    type: "ClassExpression";
    id?: Identifier | null | undefined;
}

interface MetaProperty extends BaseExpression {
    type: "MetaProperty";
    meta: Identifier;
    property: Identifier;
}

interface ImportExpression extends BaseExpression {
    type: "ImportExpression";
    source: Expression;
}

interface AwaitExpression extends BaseExpression {
    type: "AwaitExpression";
    argument: Expression;
}

declare module 'estree' {
	export interface Decorator extends BaseNode {
		type: 'Decorator';
		expression: Expression;
	}
	interface PropertyDefinition {
		decorators: undefined[];
	}
	interface MethodDefinition {
		decorators: undefined[];
	}
	interface BaseClass {
		decorators: undefined[];
	}
}

// declare AbortSignal here for environments without DOM lib or @types/node
declare global {
	// eslint-disable-next-line @typescript-eslint/no-empty-object-type
	interface AbortSignal {}
}

interface TemplateStorefrontSection {
    /** Section layout identifier. When not provided, the section will use the default layout. */
    readonly id?: string;
    readonly type: 'store';
}

interface StorePageConfiguration {
    readonly sections: [TemplateStorefrontSection];
}

declare const CatalogLayoutSlot: {
    readonly PRODUCT_LIST: "CONTROLS";
    readonly BOTTOM_BAR: "FOOTER";
    readonly CUSTOM_SLOT: "CUSTOM_SLOT";
};
declare const CategoryLayoutSlot: {
    readonly CATEGORY_TITLE: "MAIN_TITLE";
    readonly PRODUCT_LIST: "CONTROLS";
    readonly BOTTOM_BAR: "FOOTER";
    readonly CUSTOM_SLOT: "CUSTOM_SLOT";
};
declare const ProductLayoutSlot: {
    readonly TOP_BAR: "TOP_BAR";
    readonly GALLERY: "GALLERY";
    readonly SIDEBAR: "SIDEBAR";
    readonly DESCRIPTION: "DESCRIPTION";
    readonly REVIEW_LIST: "REVIEW_LIST";
    readonly RELATED_PRODUCTS: "RELATED_PRODUCTS";
    readonly BOTTOM_BAR: "FOOTER";
    readonly CUSTOM_SLOT: "CUSTOM_SLOT";
};

export { CatalogLayoutSlot, CategoryLayoutSlot, EditorTypes, ProductLayoutSlot, createVueClientApp, createVueServerApp, useBackgroundElementDesign, useButtonElementContent, useButtonElementDesign, useDeckElementContent, useImageElementContent, useImageElementDesign, useInputboxElementContent, useInstantsiteJsApi, useLayoutElementDesign, useLogoElementContent, useLogoElementDesign, useMenuElementContent, useNavigationMenuElementContent, useSelectboxElementContent, useSelectboxElementDesign, useTextElementDesign, useTextareaElementContent, useTextareaElementDesign, useToggleElementContent, useToggleElementDesign, useVueBaseProps };
export type { ButtonContent, Card, Deck, ImageContent, InputBoxContent, SelectBoxContent, StorePageConfiguration, TextAreaContent, ToggleContent };
