/**
 * CSS Selector AST root.
 * Contains list of CSS rules (separated by a comma in the input CSS selector string).
 * Generated by {@link AstFactory.selector ast.selector}.
 */
export interface AstSelector {
    type: 'Selector';
    /**
     * List of CSS rules. Every rule contains conditions. Selector is considered matched once at least one rule matches.
     */
    rules: AstRule[];
}
/**
 * A single CSS rule that contains match conditions.
 * Can nest another rule with or without a combinator (i.e. `"div > span"`).
 * Generated by {@link AstFactory.rule ast.rule}.
 */
export interface AstRule {
    type: 'Rule';
    /** Items of a CSS rule. Can be tag, ids, class names, pseudo-classes and pseudo-elements. */
    items: (AstTagName | AstWildcardTag | AstId | AstClassName | AstAttribute | AstPseudoClass | AstPseudoElement)[];
    /** Rule combinator which was used to nest this rule (i.e. `">"` in case of `"div > span"` if the current rule is `"span"`). */
    combinator?: string;
    /** Nested rule if specified (i.e. `"div > span"`). */
    nestedRule?: AstRule;
}
/**
 * Named tag, i.e. `"div"`. Part of CSS Qualified Names.
 * Generated by {@link AstFactory.tagName ast.tagName}.
 * @see https://developer.mozilla.org/en-US/docs/Web/CSS/Type_selectors
 * @see https://drafts.csswg.org/css-namespaces-3/#css-qnames
 */
export interface AstTagName {
    type: 'TagName';
    /** Tag name, i.e. `"div"`. */
    name: string;
    /** Namespace according to https://www.w3.org/TR/css3-namespace/. */
    namespace?: AstNamespaceName | AstWildcardNamespace | AstNoNamespace;
}
/**
 * ID condition. Matches by id attribute value.
 * Generated by {@link AstFactory.id ast.id}.
 * https://developer.mozilla.org/en-US/docs/Web/CSS/ID_selectors
 * @example "#root"
 */
export interface AstId {
    type: 'Id';
    /** ID name. I.e. `#root` -> `"root"`. */
    name: string;
}
/**
 * Class name condition. Matches by class attribute value.
 * Generated by {@link AstFactory.className ast.className}.
 * https://developer.mozilla.org/en-US/docs/Web/CSS/ID_selectors
 * @example ".user"
 */
export interface AstClassName {
    type: 'ClassName';
    /** ID name. I.e. `.user` -> `"user"`. */
    name: string;
}
/**
 * Wildcard tag (universal selector): `*`.
 * Generated by {@link AstFactory.wildcardTag ast.wildcardTag}.
 * @see https://developer.mozilla.org/en-US/docs/Web/CSS/Universal_selectors
 * @see https://drafts.csswg.org/css-namespaces-3/#css-qnames
 */
export interface AstWildcardTag {
    type: 'WildcardTag';
    /** Namespace according to https://www.w3.org/TR/css3-namespace/. */
    namespace?: AstNamespaceName | AstWildcardNamespace | AstNoNamespace;
}
/**
 * Named namespace declaration (i.e. `ns|div`).
 * Generated by {@link AstFactory.namespaceName ast.namespaceName}.
 * @see https://drafts.csswg.org/css-namespaces-3/#css-qnames
 */
export interface AstNamespaceName {
    type: 'NamespaceName';
    /** Namespace name (i.e. `"ns"` in case of `"ns|div"`). "*/
    name: string;
}
/**
 * Wildcard namespace (universal selector): `*`.
 * Generated by {@link AstFactory.wildcardNamespace ast.wildcardNamespace}.
 * @see https://developer.mozilla.org/en-US/docs/Web/CSS/Universal_selectors
 * @see https://drafts.csswg.org/css-namespaces-3/#css-qnames
 */
export interface AstWildcardNamespace {
    type: 'WildcardNamespace';
}
/**
 * Explicit no-namespace declaration (i.e. `|div`).
 * Generated by {@link AstFactory.noNamespace ast.noNamespace}.
 * @see https://drafts.csswg.org/css-namespaces-3/#css-qnames
 */
export interface AstNoNamespace {
    type: 'NoNamespace';
}
/**
 * Attribute selector.
 * Generated by {@link AstFactory.attribute ast.attribute}.
 * @example "[role='button' i]"
 */
export interface AstAttribute {
    type: 'Attribute';
    /** Attribute name (i.e. `"href"` in case if `"[href]"`). */
    name: string;
    /** Namespace according to https://drafts.csswg.org/selectors/#attrnmsp. */
    namespace?: AstNamespaceName | AstWildcardNamespace | AstNoNamespace;
    /** Comparison operator (i.e. `"|="` in case if `"[role|=button]"`). */
    operator?: string;
    /** Comparison value (i.e. `"button"` in case if `"[role=button]"`). */
    value?: AstString | AstSubstitution;
    /** Comparison case sensitivity modifier (i.e. `"i"` in case if `"[role='button' i]"`). */
    caseSensitivityModifier?: string;
}
/**
 * Pseudo-class selector.
 * Generated by {@link AstFactory.pseudoClass ast.pseudoClass}.
 * @see https://developer.mozilla.org/en-US/docs/Learn/CSS/Building_blocks/Selectors/Pseudo-classes_and_pseudo-elements
 * @example ":lang(en)"
 */
export interface AstPseudoClass {
    type: 'PseudoClass';
    /** Pseudo-class name (i.e. `"hover"` in case of `":hover"`). */
    name: string;
    /** Pseudo-class value (i.e. `"en"` in case of `":lang(en)"`). */
    argument?: AstSubstitution | AstSelector | AstString | AstFormula | AstFormulaOfSelector;
}
/**
 * Pseudo-class selector.
 * Generated by {@link AstFactory.pseudoElement ast.pseudoElement}.
 * @see https://developer.mozilla.org/en-US/docs/Learn/CSS/Building_blocks/Selectors/Pseudo-classes_and_pseudo-elements
 * @example "::before"
 */
export interface AstPseudoElement {
    type: 'PseudoElement';
    /** Pseudo-element name (i.e. `"before"` in case of `"::before"`). */
    name: string;
    /** Pseudo-element value (i.e. `"foo"` in case of `"::part(foo)"`). */
    argument?: AstSubstitution | AstString | AstSelector;
}
/**
 * String value. Can be used as attribute value of pseudo-class string value.
 * For instance `:lang(en)` -> `{type: 'AstPseudoClass'..., argument: {type: 'String', value: 'en'}}`.
 * Generated by {@link AstFactory.string ast.string}.
 */
export interface AstString {
    type: 'String';
    /** The actual string value. */
    value: string;
}
/**
 * Pseudo-class formula value. `a` is multiplier of `n` and `b` us added on top. Formula: `an + b`.
 * For instance `:nth-child(2n + 1)` -> `{type: 'AstPseudoClass'..., argument: {type: 'Formula', a: 2, b: 1}}`.
 * Generated by {@link AstFactory.formula ast.formula}.
 * @see https://developer.mozilla.org/en-US/docs/Web/CSS/:nth-child#functional_notation
 */
export interface AstFormula {
    type: 'Formula';
    /** Multiplier of `n`. */
    a: number;
    /** Constant added to `a*n`. */
    b: number;
}
/**
 * Pseudo-class formula of selector value. `a` is multiplier of `n` and `b` us added on top. Formula: `an + b`.
 * Formula is followed by `of` keyword and then goes a CSS selector.
 * For instance `:nth-child(2n + 1 of div)` ->
 * `{type: 'AstPseudoClass'..., argument: {type: 'FormulaOfSelector', a: 2, b: 1, selector: {type: 'Selector', rules: [{type: 'Rule', items: [{type: 'TagName', name: 'div'}]}]}}}`.
 * Generated by {@link AstFactory.formulaOfSelector ast.formulaOfSelector}.
 * @see https://developer.mozilla.org/en-US/docs/Web/CSS/:nth-child#functional_notation
 */
export interface AstFormulaOfSelector {
    type: 'FormulaOfSelector';
    /** Multiplier of `n`. */
    a: number;
    /** Constant added to `a*n`. */
    b: number;
    /** Selector that goes after formula (i.e. `"div -> span"` in case of `":nth-child(2n + 1 of div > span)"` */
    selector: AstRule;
}
/**
 * Substitution is not part of CSS spec, but rather a useful extension on top of CSS if you need to pass variables.
 * Generated by {@link AstFactory.substitution ast.substitution}.
 */
export interface AstSubstitution {
    type: 'Substitution';
    /** Substitution name (i.e. "var" in case of `"[role=$var]"` or `":lang($var)"`). */
    name: string;
}
/** One of pseudo-class argument types. */
export type AstPseudoClassArgument = AstSubstitution | AstSelector | AstString | AstFormula | AstFormulaOfSelector;
/** One of pseudo-element argument types. */
export type AstPseudoElementArgument = AstSubstitution | AstString | AstSelector;
/** One of CSS AST entity types. */
export type AstEntity = AstSelector | AstRule | AstTagName | AstWildcardTag | AstId | AstClassName | AstNamespaceName | AstWildcardNamespace | AstNoNamespace | AstSubstitution | AstString | AstFormula | AstFormulaOfSelector | AstPseudoClass | AstAttribute | AstPseudoElement;
type UnionToIntersection<T> = (T extends any ? (x: T) => any : never) extends (x: infer R) => any ? R : never;
type ToAstFactory<T> = UnionToIntersection<T extends {
    type: infer Type;
} ? Type extends string ? {
    [K in Uncapitalize<Type>]: {} extends Omit<T, 'type'> ? (props?: {
        [PK in keyof Omit<T, 'type'>]: Omit<T, 'type'>[PK];
    }) => T : (props: {
        [PK in keyof Omit<T, 'type'>]: Omit<T, 'type'>[PK];
    }) => T;
} & {
    [K in `is${Type}`]: (entity: unknown) => entity is T;
} : never : never>;
/** @internal */
type AstFactoryBase = {
    [K in keyof ToAstFactory<AstEntity>]: ToAstFactory<AstEntity>[K];
};
/**
 * AST structure generators and matchers.
 * For instance, `ast.selector({rules: [...]})` creates AstSelector and `ast.isSelector(...)` checks if
 * AstSelector was specified.
 *
 * @example
 *
 * // Represents CSS selector: ns|div#user-34.user.user-active[role="button"]:lang(en)::before > *
 * const selector = ast.selector({
 *     rules: [
 *         ast.rule({
 *             items: [
 *                 ast.tagName({name: 'div', namespace: ast.namespaceName({name: 'ns'})}),
 *                 ast.id({name: 'user-34'}),
 *                 ast.className({name: 'user'}),
 *                 ast.className({name: 'user-active'}),
 *                 ast.attribute({
 *                     name: 'role',
 *                     operator: '=',
 *                     value: ast.string({value: 'button'})
 *                 }),
 *                 ast.pseudoClass({
 *                     name: 'lang',
 *                     argument: ast.string({value: 'en'})
 *                 }),
 *                 ast.pseudoElement({name: 'before'})
 *             ],
 *             nestedRule: ast.rule({combinator: '>', items: [ast.wildcardTag()]})
 *         })
 *     ]
 * });
 * console.log(ast.isSelector(selector)); // prints true
 * console.log(ast.isRule(selector)); // prints false
 */
export interface AstFactory extends AstFactoryBase {
}
/**
 * AST structure generators and matchers.
 * For instance, `ast.selector({rules: [...]})` creates AstSelector and `ast.isSelector(...)` checks if
 * AstSelector was specified.
 *
 * @example
 *
 * // Represents CSS selector: ns|div#user-34.user.user-active[role="button"]:lang(en)::before > *
 * const selector = ast.selector({
 *     rules: [
 *         ast.rule({
 *             items: [
 *                 ast.tagName({name: 'div', namespace: ast.namespaceName({name: 'ns'})}),
 *                 ast.id({name: 'user-34'}),
 *                 ast.className({name: 'user'}),
 *                 ast.className({name: 'user-active'}),
 *                 ast.attribute({
 *                     name: 'role',
 *                     operator: '=',
 *                     value: ast.string({value: 'button'})
 *                 }),
 *                 ast.pseudoClass({
 *                     name: 'lang',
 *                     argument: ast.string({value: 'en'})
 *                 }),
 *                 ast.pseudoElement({name: 'before'})
 *             ],
 *             nestedRule: ast.rule({combinator: '>', items: [ast.wildcardTag()]})
 *         })
 *     ]
 * });
 * console.log(ast.isSelector(selector)); // prints true
 * console.log(ast.isRule(selector)); // prints false
 */
export declare const ast: AstFactory;
export {};
