import type { Options } from "./types";
type Require<T, Keys extends keyof T> = Pick<Required<T>, Keys> & Omit<T, Keys>;
export type Parser<T> = {
    /**
     * Convert a query string value into a state value.
     *
     * If the string value does not represent a valid state value,
     * the parser should return `null`. Throwing an error is also supported.
     */
    parse: (value: string) => T | null;
    /**
     * Render the state value into a query string value.
     */
    serialize?: (value: T) => string;
    /**
     * Check if two state values are equal.
     *
     * This is used when using the `clearOnDefault` value, to compare the default
     * value with the set value.
     *
     * It makes sense to provide this function when the state value is an object
     * or an array, as the default referential equality check will not work.
     */
    eq?: (a: T, b: T) => boolean;
};
export type ParserBuilder<T> = Required<Parser<T>> & Options & {
    /**
     * Set history type, shallow routing and scroll restoration options
     * at the hook declaration level.
     *
     * Note that you can override those options in individual calls to the
     * state updater function.
     */
    withOptions<This>(this: This, options: Options): This;
    /**
     * Specifying a default value makes the hook state non-nullable when the
     * query is missing from the URL: the default value is returned instead
     * of `null`.
     *
     * Setting the state to the default value¹ will clear the query string key
     * from the URL, unless `clearOnDefault` is set to `false`.
     *
     * Setting the state to `null` will always clear the query string key
     * from the URL, and return the default value.
     *
     * ¹: Equality is checked with the parser's `eq` function, or referential
     * equality if not provided.
     *
     * @param defaultValue
     *
     */
    withDefault(this: ParserBuilder<T>, defaultValue: NonNullable<T>): Omit<ParserBuilder<T>, "parseServerSide"> & {
        readonly defaultValue: NonNullable<T>;
        /**
         * Use the parser in Server Components
         *
         * `parse` is intended to be used only by the hook, but you can use this
         * method to hydrate query values on server-side rendered pages.
         * See the `server-side-parsing` demo for an example.
         *
         * Note that when multiple queries are presented to the parser
         * (eg: `/?a=1&a=2`), only the **first** will be parsed, to mimic the
         * behaviour of URLSearchParams:
         * https://url.spec.whatwg.org/#dom-urlsearchparams-get
         *
         * @param value as coming from page props
         * @throws Not implemented error - this is a placeholder method for future implementations. The parser should be used in the hook only.
         */
        parseServerSide(value: string | string[] | undefined): NonNullable<T>;
    };
    /**
     * Use the parser in Server Components
     *
     * `parse` is intended to be used only by the hook, but you can use this
     * method to hydrate query values on server-side rendered pages.
     * See the `server-side-parsing` demo for an example.
     *
     * Note that when multiple queries are presented to the parser
     * (eg: `/?a=1&a=2`), only the **first** will be parsed, to mimic the
     * behaviour of URLSearchParams:
     * https://url.spec.whatwg.org/#dom-urlsearchparams-get
     *
     * @param value as coming from page props
     * @throws Not implemented error - this is a placeholder method for future implementations. The parser should be used in the hook only.
     */
    parseServerSide(value: string | string[] | undefined): T | null;
};
/**
 * Wrap a set of parse/serialize functions into a builder pattern parser
 * you can pass to one of the hooks, making its default value type safe.
 */
export declare function createParser<T>(parser: Require<Parser<T>, "parse" | "serialize">): ParserBuilder<T>;
export declare const parseAsString: ParserBuilder<string>;
export declare const parseAsInteger: ParserBuilder<number>;
export declare const parseAsIndex: ParserBuilder<number>;
export declare const parseAsHex: ParserBuilder<number>;
export declare const parseAsFloat: ParserBuilder<number>;
export declare const parseAsBoolean: ParserBuilder<boolean>;
/**
 * Querystring encoded as the number of milliseconds since epoch,
 * and returned as a Date object.
 */
export declare const parseAsTimestamp: ParserBuilder<Date>;
/**
 * Querystring encoded as an ISO-8601 string (UTC),
 * and returned as a Date object.
 */
export declare const parseAsIsoDateTime: ParserBuilder<Date>;
/**
 * Querystring encoded as an ISO-8601 string (UTC)
 * without the time zone offset, and returned as
 * a Date object.
 *
 * The Date is parsed without the time zone offset,
 * making it at 00:00:00 UTC.
 */
export declare const parseAsIsoDate: ParserBuilder<Date>;
/**
 * String-based enums provide better type-safety for known sets of values.
 * You will need to pass the parseAsStringEnum function a list of your enum values
 * in order to validate the query string. Anything else will return `null`,
 * or your default value if specified.
 *
 * Example:
 * ```ts
 * enum Direction {
 *   up = 'UP',
 *   down = 'DOWN',
 *   left = 'LEFT',
 *   right = 'RIGHT'
 * }
 *
 * const [direction, setDirection] = useQueryState(
 *   'direction',
 *    parseAsStringEnum<Direction>(Object.values(Direction)) // pass a list of allowed values
 *      .withDefault(Direction.up)
 * )
 * ```
 *
 * Note: the query string value will be the value of the enum, not its name
 * (example above: `direction=UP`).
 *
 * @param validValues The values you want to accept
 */
export declare function parseAsStringEnum<Enum extends string>(validValues: Enum[]): ParserBuilder<Enum>;
/**
 * String-based literals provide better type-safety for known sets of values.
 * You will need to pass the parseAsStringLiteral function a list of your string values
 * in order to validate the query string. Anything else will return `null`,
 * or your default value if specified.
 *
 * Example:
 * ```ts
 * const colors = ["red", "green", "blue"] as const
 *
 * const [color, setColor] = useQueryState(
 *   'color',
 *    parseAsStringLiteral(colors) // pass a readonly list of allowed values
 *      .withDefault("red")
 * )
 * ```
 *
 * @param validValues The values you want to accept
 */
export declare function parseAsStringLiteral<Literal extends string>(validValues: readonly Literal[]): ParserBuilder<Literal>;
/**
 * Number-based literals provide better type-safety for known sets of values.
 * You will need to pass the parseAsNumberLiteral function a list of your number values
 * in order to validate the query string. Anything else will return `null`,
 * or your default value if specified.
 *
 * Example:
 * ```ts
 * const diceSides = [1, 2, 3, 4, 5, 6] as const
 *
 * const [side, setSide] = useQueryState(
 *   'side',
 *    parseAsNumberLiteral(diceSides) // pass a readonly list of allowed values
 *      .withDefault(4)
 * )
 * ```
 *
 * @param validValues The values you want to accept
 */
export declare function parseAsNumberLiteral<Literal extends number>(validValues: readonly Literal[]): ParserBuilder<Literal>;
/**
 * Encode any object shape into the querystring value as JSON.
 * Note: you may want to use `useQueryStates` for finer control over
 * multiple related query keys.
 *
 * @param runtimeParser Runtime parser (eg: Zod schema) to validate after JSON.parse
 */
export declare function parseAsJson<T>(runtimeParser: (value: unknown) => T): ParserBuilder<T>;
/**
 * A comma-separated list of items.
 * Items are URI-encoded for safety, so they may not look nice in the URL.
 *
 * @param itemParser Parser for each individual item in the array
 * @param separator The character to use to separate items (default ',')
 */
export declare function parseAsArrayOf<ItemType>(itemParser: Parser<ItemType>, separator?: string): ParserBuilder<ItemType[]>;
type inferSingleParserType<Parser> = Parser extends ParserBuilder<infer Value> & {
    defaultValue: infer Value;
} ? Value : Parser extends ParserBuilder<infer Value> ? Value | null : never;
type inferParserRecordType<Map extends Record<string, ParserBuilder<any>>> = {
    [Key in keyof Map]: inferSingleParserType<Map[Key]>;
} & {};
/**
 * Type helper to extract the underlying returned data type of a parser
 * or of an object describing multiple parsers and their associated keys.
 *
 * Usage:
 *
 * ```ts
 * import { type inferParserType } from 'nuqs' // or 'nuqs/server'
 *
 * const intNullable = parseAsInteger
 * const intNonNull = parseAsInteger.withDefault(0)
 *
 * inferParserType<typeof intNullable> // number | null
 * inferParserType<typeof intNonNull> // number
 *
 * const parsers = {
 *  a: parseAsInteger,
 *  b: parseAsBoolean.withDefault(false)
 * }
 *
 * inferParserType<typeof parsers>
 * // { a: number | null, b: boolean }
 * ```
 */
export type inferParserType<Input> = Input extends ParserBuilder<any> ? inferSingleParserType<Input> : Input extends Record<string, ParserBuilder<any>> ? inferParserRecordType<Input> : never;
export type ParserWithOptionalDefault<T> = ParserBuilder<T> & {
    defaultValue?: T;
};
export type ParserMap = Record<string, ParserWithOptionalDefault<any>>;
export {};
