// Generated by dts-bundle v0.7.3
// Dependencies for this module:
//   ../../@faker-js/faker

import { Faker } from "@faker-js/faker";
import { ChemicalElement } from "@faker-js/faker";
import { SexType } from "@faker-js/faker";
import { Currency as FakerCurrency } from "@faker-js/faker";
import { AirlineDefinition, AircraftType as FakerAircraftType } from '@faker-js/faker';

export const MockThis: <T>(schema: Schema, plugins?: MockThisPlugin[]) => IMockThisInstance<T>;

/**
    * @returns {boolean} A random boolean value.
    * @example true or false
    */
export const Bool: TypeFunc<boolean>;
/**
    * @param value - The value to return.
    * @returns {T} A function that returns the constant value.
    * @example 5
    */
export const Constant: <T>(value: T) => TypeFunc<T>;
/**
    * @param items - The array of items to choose from.
    * @returns {T} A function that returns a random item from the array.
    * @example
    * Random([1, 2, 3]); // 1 or 2 or 3
    */
export const Random: <T>(items: T[]) => TypeFunc<T>;
/**
    * @returns {string} A UUID string.
    * @example '3b241101-e2bb-4255-8caf-4136c566a962'
    */
export const Uuid: TypeFunc<string>;
/**
    * @param asyncCallback - The async callback function.
    * @returns {T} The resolved value of the promise returned from the callback.
    * @example
    * Async(async () => 5) // 5
    */
export const Async: <T>(asyncCallback: () => Promise<T>) => TypeFunc<Promise<T>>;
/**
    * @param enumType - The enum type.
    * @returns {T} A function that returns a random value from the enum.
    * @example
    * enum Colors { RED = "red", GREEN = "green", BLUE = "blue" }
    * EnumRandom(Colors); // 'red' or 'green' or 'blue'
    */
export const EnumRandom: <T extends Record<string, any>>(enumType: T) => TypeFunc<T[keyof T]>;
/**
    * Maps the result of a TypeFunc using the provided callback.
    * @param typeFunc - The TypeFunc.
    * @param mapCallback - The mapping callback function.
    * @returns {T} The mapped value.
    * @example
    * MapValue(Constant(5), x => x * 2)(blueprint); // 10
    */
export const MapValue: <T>(typeFunc: TypeFunc<T>, mapCallback: (value: T) => T) => TypeFunc<T>;
/**
    * Reduces the results of multiple TypeFuncs using the provided callback.
    * @param typeFuncs - The array of TypeFuncs.
    * @param reduceCallback - The reducing callback function.
    * @returns {T} The reduced value.
    * @example
    * ReduceValues([FirstName, LastName], ([firstName, lastName]) => `${firstName} ${lastName}`); // John Smith
    */
export const ReduceValues: <T>(typeFuncs: TypeFunc<any>[], reduceCallback: (values: any[]) => T) => TypeFunc<T>;
/**
    * Validates the result of a type function using the provided callback.
    * @param typeFunc - The type function.
    * @param validateCallback - The validation callback function.
    * @param retries - The number of retries.
    * @returns {T} The validated value.
    * @example
    * ValidatedValue(Number, num => num < 5); // 4
    */
export const ValidateValue: <T>(typeFunc: TypeFunc<T>, validateCallback: (value: T) => boolean, retries?: number) => TypeFunc<T>;
/**
    * Returns a subset of the provided array with a length between the specified min and max values. If no min or max values are provided, the entire array is returned.
    * @param array - The array to choose from.
    * @param min - The minimum length of the subset.
    * @param max - The maximum length of the subset.
    * @returns {T[]} Returns a subset of the items.
    * @example
    * SubsetOf([1, 2, 3, 4], 2) //[2, 4]
    */
export const SubsetOf: <T>(array: T[], min?: number, max?: number) => TypeFunc<any>;
export const NullChance: <T>(typeFunc: TypeFunc<T>, percentage: number) => TypeFunc<T | null>;
export const FakerFunc: <T>(fakerFunc: (faker: Faker) => T) => TypeFunc<T>;

/**
    * @example
    * Sequences can be useful when you want an even distribution of values.
    * @example
    * Sequence([1, 2, 3]); // 1 then 2 then 3 then repeat
    */
export const Sequence: <T>(sequence: T[]) => TypeFunc<T>;
/**
    * @example
    * Enum sequences can be useful when you want an even distribution of enum values.
    * @example
    * enum SequenceEnum { First, Second, Third }
    * Sequence(SequenceEnum); // SequenceEnum.First then SequenceEnum.Second then SequenceEnum.Third then repeat
    */
export const EnumSequence: <T extends Record<string, any>>(enumType: T) => TypeFunc<T[keyof T]>;
/**
    * A helper TypeFunc built over the Sequence type. Provides an incrementing integer id.
    * @example
    * Id(max?: number) // 0...10000; max defaults to 10000
    */
export const Id: (max?: number) => TypeFunc<number>;

/**
  * Creates a dependent TypeFunc that relies on other values.
  * @param deps - The dependencies.
  * @param depCallback - The callback function to generate the value based on dependencies.
  * @returns The return value of the callback.
  */
export const Dep: <T>(deps: string[], depCallback: (deps: Record<string, any>, generateValue: <V>(TypeFunc: TypeFunc<V>) => V) => T) => TypeFunc<T>;

/**
    * @returns {string} A random datetime string.
    * @example "2023-10-05T14:48:00.000Z"
    */
export const DateTime: TypeFunc<string>;
/**
    * @returns {string} A random past datetime string.
    * @example "2022-09-15T12:34:56.000Z"
    */
export const DateTimePast: TypeFunc<string>;
/**
    * @returns {string} A random future datetime string.
    * @example "2024-11-20T08:22:10.000Z"
    */
export const DateTimeFuture: TypeFunc<string>;
/**
    * @param {string | Date} start - The start date.
    * @param {string | Date} end - The end date.
    * @returns {string} A random datetime string between the start and end dates.
    * @example "2023-05-15T10:00:00.000Z"
    */
export const DateTimeBetween: (start: string | Date, end: string | Date) => TypeFunc<string>;
/**
    * Generates a random birthdate string.
    * @returns {string} A random birthdate string.
    * @example "1985-10-05T00:00:00.000Z"
    */
export const Birthdate: TypeFunc<string>;
/**
    * @param {TypeFunc<string>} dateTypeFunc - The datetime TypeFunc.
    * @param {string} format - The desired format.
    * @returns {string} A formatted datetime string.
    * @example "05-10-2023 14:48:00"
    */
export const FormatDateTime: (dateTypeFunc: TypeFunc<string>, format: string) => TypeFunc<string>;

/**
    * @returns {string} A random street address.
    * @example "123 Main St"
    */
export const Address: TypeFunc<string>;
/**
    * @returns {string} A random city name.
    * @example "Springfield"
    */
export const City: TypeFunc<string>;
/**
    * @returns {string} A random state name.
    * @example "California"
    */
export const State: TypeFunc<string>;
/**
    * @returns {string} A random zip code.
    * @example "90210"
    */
export const ZipCode: TypeFunc<string>;
/**
    * @returns {string} A random country name.
    * @example "United States"
    */
export const Country: TypeFunc<string>;
/**
    * @returns {string} A string representing random coordinates.
    * @example "37.7749, -122.4194"
    */
export const Coordinates: TypeFunc<string>;

/**
    * @returns {string} A random animal type.
    * @example "Dog"
    */
export const Animal: TypeFunc<string>;
/**
    * @returns {string} A random color.
    * @example "Blue"
    */
export const Color: TypeFunc<string>;
/**
    * @returns {ChemicalElement} A random chemical element.
    * @example
    * {
    *   symbol: "H",
    *   name: "Hydrogen",
    *   atomicNumber: 1
    * }
    */
export const Element: TypeFunc<ChemicalElement>;

/**
    * @returns {string} A random first name.
    * @example "John"
    */
export const FirstName: TypeFunc<string>;
export const SexSpecificFirstName: (sex: string | SexType) => TypeFunc<string>;
/**
    * @returns {string} A random last name.
    * @example "Doe"
    */
export const LastName: TypeFunc<string>;
/**
    * @returns {SexType} A random SexType. This can be used to keep other sex related data consistent.
    * @example SexType.Female
    */
export const Sex: TypeFunc<SexType>;
/**
    * @returns {string} A random phone number.
    * @example "(555) 123-4567"
    */
export const PhoneNumber: TypeFunc<string>;
/**
    * @returns {string} A random email address.
    * @example "john.doe@example.com"
    */
export const Email: TypeFunc<string>;
/**
    * @returns {string} A random social security number.
    * @example "123-45-6789"
    */
export const SocialSecurityNumber: TypeFunc<string>;
/**
    * @returns {string} A random job title.
    * @example "Global Accounts Engineer"
    */
export const JobTitle: TypeFunc<string>;
/**
    * @returns {string} A random job type.
    * @example "Assistant"
    */
export const JobType: TypeFunc<string>;
/**
    * @returns {string} A random job area.
    * @example "Engineering"
    */
export const JobArea: TypeFunc<string>;
/**
    * @returns {string} A random zodiac sign.
    * @example "Aries"
    */
export const ZodiacSign: TypeFunc<string>;

/**
    * @returns {number} A random integer between 0 and 100.
    * @example 42
    */
export const Integer: TypeFunc<number>;
/**
    * Generates a random integer between the specified min and max values.
    * @param min - The minimum value.
    * @param max - The maximum value.
    * @returns {number} A function that generates a random integer.
    * @example 10
    */
export const IntegerRange: (min: number, max: number) => TypeFunc<number>;
/**
    * @returns {number} A random decimal number between 0 and 100.
    * @example 42.42
    */
export const Decimal: TypeFunc<number>;
/**
    * Generates a random decimal number between the specified min and max values.
    * @param min - The minimum value.
    * @param max - The maximum value.
    * @returns {number} A function that generates a random decimal number.
    * @example 10.5
    */
export const DecimalRange: (min: number, max: number) => TypeFunc<number>;

/**
    * @returns {string} A random currency.
    * @example
    * {
    *   code: "USD",
    *   name: "United States Dollar",
    *   symbol: "$"
    * }
    */
export const Currency: TypeFunc<FakerCurrency>;
/**
    * @returns {string} A random dollar amount.
    * @example "$123.45"
    */
export const Dollar: TypeFunc<string>;
/**
    * @returns {string} A random euro amount.
    * @example "123.45 €"
    */
export const Euro: TypeFunc<string>;

/**
    * @returns {string} A random letter.
    * @example "z"
    */
export const Letter: TypeFunc<string>;
/**
    * @returns {string} A random word.
    * @example "lorem"
    */
export const Word: TypeFunc<string>;
/**
    * @returns {string} A random sentence.
    * @example "Lorem ipsum dolor sit amet."
    */
export const Sentence: TypeFunc<string>;
/**
    * @returns {string} A random paragraph.
    * @example "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."
    */
export const Paragraph: TypeFunc<string>;

/**
    * @returns {string} A URL.
    * @example 'http://www.terrible-idea.com'
    */
export const Url: TypeFunc<string>;
/**
    * @returns {string} An avatar URL.
    * @example 'https://avatars.githubusercontent.com/u/97165289'
    */
export const AvatarUrl: TypeFunc<string>;

/**
    * @returns {string} A vehicle name.
    * @example 'Toyota Corolla'
    */
export const Vehicle: TypeFunc<string>;
/**
    * @returns {string} A vehicle manufacturer.
    * @example 'Toyota'
    */
export const VehicleManufacturer: TypeFunc<string>;
/**
    * @returns {string} A vehicle model.
    * @example 'Corolla'
    */
export const VehicleModel: TypeFunc<string>;
/**
    * @returns {string} A vehicle type.
    * @example 'SUV'
    */
export const VehicleType: TypeFunc<string>;
/**
    * @returns {string} A vehicle fuel type.
    * @example 'Gasoline'
    */
export const VehicleFuelType: TypeFunc<string>;

/**
    * @returns {string} A random book title.
    * @example "The Great Gatsby"
    */
export const BookTitle: TypeFunc<string>;
/**
    * @returns {string} A random book author.
    * @example "F. Scott Fitzgerald"
    */
export const BookAuthor: TypeFunc<string>;
/**
    * @returns {string} A random book genre.
    * @example "Fiction"
    */
export const BookGenre: TypeFunc<string>;
/**
    * @returns {string} A random book publisher.
    * @example "Scribner"
    */
export const BookPublisher: TypeFunc<string>;
/**
    * @returns {string} A random book format.
    * @example "Hardcover"
    */
export const BookFormat: TypeFunc<string>;
/**
    * @returns {string} A random book series.
    * @example "Harry Potter"
    */
export const BookSeries: TypeFunc<string>;

/**
    * @returns {string} A random company name.
    * @example "Acme Corporation"
    */
export const CompanyName: TypeFunc<string>;
/**
    * @returns {string} A random company catch phrase.
    * @example "Innovate synergistic solutions"
    */
export const CatchPhrase: TypeFunc<string>;
/**
    * @returns {string} A random company catch phrase adjective.
    * @example "synergistic"
    */
export const CatchPhraseAdjective: TypeFunc<string>;
/**
    * @returns {string} A random company catch phrase descriptor.
    * @example "cutting-edge"
    */
export const CatchPhraseDescriptor: TypeFunc<string>;
/**
    * @returns {string} A random company catch phrase noun.
    * @example "solutions"
    */
export const CatchPhraseNoun: TypeFunc<string>;
/**
    * @returns {string} A random company buzz adjective.
    * @example "innovative"
    */
export const BuzzAdjective: TypeFunc<string>;
/**
    * @returns {string} A random company buzz noun.
    * @example "platform"
    */
export const BuzzNoun: TypeFunc<string>;
/**
    * @returns {string} A random company buzz phrase.
    * @example "empower seamless platforms"
    */
export const BuzzPhrase: TypeFunc<string>;
/**
    * @returns {string} A random company buzz verb.
    * @example "leverage"
    */
export const BuzzVerb: TypeFunc<string>;

/**
    * @returns {string} A random food adjective.
    * @example "spicy"
    */
export const FoodAdjective: TypeFunc<string>;
/**
    * @returns {string} A random food description.
    * @example "A delicious and savory dish."
    */
export const FoodDescription: TypeFunc<string>;
/**
    * @returns {string} A random food dish.
    * @example "Spaghetti Carbonara"
    */
export const FoodDish: TypeFunc<string>;
/**
    * @returns {string} A random food ethnic category.
    * @example "Italian"
    */
export const FoodEthnicCategory: TypeFunc<string>;
/**
    * @returns {string} A random fruit name.
    * @example "Apple"
    */
export const FoodFruit: TypeFunc<string>;
/**
    * @returns {string} A random food ingredient.
    * @example "Garlic"
    */
export const FoodIngredient: TypeFunc<string>;
/**
    * @returns {string} A random meat name.
    * @example "Chicken"
    */
export const FoodMeat: TypeFunc<string>;
/**
    * @returns {string} A random spice name.
    * @example "Cinnamon"
    */
export const FoodSpice: TypeFunc<string>;
/**
    * @returns {string} A random vegetable name.
    * @example "Carrot"
    */
export const FoodVegetable: TypeFunc<string>;

type ElementType<T> = Exclude<T extends (infer U)[] ? U : T, undefined | null>;
type Airline = ElementType<AirlineDefinition["airline"]>;
type Airplane = ElementType<AirlineDefinition["airplane"]>;
type Airport = ElementType<AirlineDefinition["airport"]>;
/**
    * @returns {FakerAircraftType} A random aircraft type.
    * @example
    * {
    *   model: "Boeing 737",
    *   manufacturer: "Boeing"
    * }
    */
export const AircraftType: TypeFunc<FakerAircraftType>;
/**
    * @returns {Airline} A random airline.
    * @example
    * {
    *   name: "Delta Air Lines",
    *   iataCode: "DL"
    * }
    */
export const Airline: TypeFunc<Airline>;
/**
    * @returns {Airplane} A random airplane.
    * @example
    * {
    *   model: "Airbus A320",
    *   manufacturer: "Airbus"
    * }
    */
export const Airplane: TypeFunc<Airplane>;
/**
    * @returns {Airport} A random airport.
    * @example
    * {
    *   name: "Los Angeles International Airport",
    *   iataCode: "LAX"
    * }
    */
export const Airport: TypeFunc<Airport>;
/**
    * @returns {string} A random flight number.
    */
export const FlightNumber: TypeFunc<string>;
/**
    * @returns {string} A random record locator.
    */
export const RecordLocator: TypeFunc<string>;
/**
    * @returns {string} A random seat number.
    */
export const Seat: TypeFunc<string>;
export {};

/**
    * @returns {string} A random music album.
    * @example "Abbey Road"
    */
export const MusicAlbum: TypeFunc<string>;
/**
    * @returns{string}  A random music artist.
    * @example "The Beatles"
    */
export const MusicArtist: TypeFunc<string>;
/**
    * @returns {string} A random music genre.
    * @example "Rock"
    */
export const MusicGenre: TypeFunc<string>;
/**
    * @returns {string} A random music song name.
    * @example "Hey Jude"
    */
export const MusicSong: TypeFunc<string>;

export type Schema = Record<string, any>;
export interface SchemaItem {
    property: string;
    generateValue: TypeFunc<any>;
    dependencies: string[];
}

export interface IMockThisInstance<T> {
    setTotal(min: number, max?: number): this;
    setArrayRange(min: number, max?: number): this;
    setRequired(required: string[]): this;
    setFormat<K extends keyof Formats>(key: K, value: Formats[K]): this;
    setFormats(formats: {
        [K in keyof Formats]?: Formats[K];
    }): this;
    setNullValueChance(chance: number): this;
    setUserDefinedBlueprint<V extends Record<string, any>>(blueprint: V): this;
    asObject(): Promise<T[]>;
    asJson(replacer?: (this: any, key: string, value: any) => any, space?: string | number): Promise<string>;
}
export class MockThisInstance<T> implements IMockThisInstance<T> {
    constructor(schemaTransformer: ISchemaTransformer, blueprintBuilder: IBlueprintBuilder, dataGenerator: IDataGenerator, pluginManager: IPluginManager, schema: Schema);
    setTotal(min: number, max?: number): this;
    setArrayRange(min: number, max?: number): this;
    setRequired(required: string[]): this;
    setFormat<K extends keyof Formats>(key: K, value: Formats[K]): this;
    setFormats(formats: {
        [K in keyof Formats]?: Formats[K];
    }): this;
    setNullValueChance(chance: number): this;
    setUserDefinedBlueprint<V extends Record<string, any>>(blueprint: V): this;
    asObject(): Promise<T[]>;
    asJson(replacer?: (this: any, key: string, value: any) => any, space?: string | number): Promise<string>;
}

export interface MockThisPlugin {
    registerMethods?: (instance: IMockThisInstance<any>, blueprintBuilder: IBlueprintBuilder) => void;
    beforeSchemaPrepared?: (blueprint: IBlueprint, schemaItems: Schema) => Schema;
    afterSchemaPrepared?: (blueprint: IBlueprint, schemaItems: SchemaItem[]) => SchemaItem[];
    afterDataGenerated?: (blueprint: IBlueprint, data: Schema[]) => Schema[];
}
export interface IPluginManager {
    registerMethods: (instance: IMockThisInstance<any>, blueprintBuilder: IBlueprintBuilder) => void;
    beforeSchemaPrepared: (blueprint: IBlueprint, schemaItems: Schema) => Schema;
    afterSchemaPrepared: (blueprint: IBlueprint, schemaItems: SchemaItem[]) => SchemaItem[];
    afterDataGenerated: (blueprint: IBlueprint, data: Schema[]) => Schema[];
}
export class PluginManager implements IPluginManager {
    constructor(plugins?: MockThisPlugin[]);
    registerMethods(instance: IMockThisInstance<any>, blueprintBuilder: IBlueprintBuilder): void;
    beforeSchemaPrepared(blueprint: IBlueprint, schema: Schema): Schema;
    afterSchemaPrepared(blueprint: IBlueprint, schemaItems: SchemaItem[]): SchemaItem[];
    afterDataGenerated(blueprint: IBlueprint, data: Schema[]): Schema[];
}

export type TypeFunc<T> = (blueprint: IBlueprint, deps?: Record<string, any>, property?: string) => T;
export type DepTypeFunc<T> = TypeFunc<T> & {
    deps: string[];
};

export interface IBlueprintBuilder {
    getBlueprint(): IBlueprint;
    setTotal(min: number, max?: number): void;
    setArrayRange(min: number, max?: number): void;
    setRequired(required: string[]): void;
    setFormat<K extends keyof Formats>(key: K, format: Formats[K]): void;
    setFormats(formats: {
        [K in keyof Formats]?: Formats[K];
    }): void;
    setNullValueChance(nullChance: number): void;
    setUserDefinedBlueprint<T extends Record<string, any>>(blueprint: T): void;
}
export class BlueprintBuilder implements IBlueprintBuilder {
    constructor();
    getBlueprint(): IBlueprint;
    setTotal(min: number, max?: number): void;
    setArrayRange(min: number, max?: number): void;
    setRequired(required: string[]): void;
    setFormat<K extends keyof Formats>(key: K, value: Formats[K]): void;
    setFormats(formats: {
        [K in keyof Formats]?: Formats[K];
    }): void;
    setNullValueChance(nullChance: number): void;
    setUserDefinedBlueprint<T extends Record<string, any>>(blueprint: T): void;
}

export interface IDataGenerator {
    generateRawData(schemaItems: SchemaItem[], blueprint: IBlueprint): Promise<Schema[]>;
}
export class DataGenerator implements IDataGenerator {
    constructor(keyExpander: IKeyExpander, schemaTransformer: ISchemaTransformer);
    generateRawData(schemaItems: SchemaItem[], blueprint: IBlueprint): Promise<Schema[]>;
}

export interface Stack {
    parent?: string | number;
    nodes: Schema;
}
export interface ISchemaTransformer {
    prepareSchema(schema: Schema, blueprint: IBlueprint): SchemaItem[];
    reconstructSchema(schemas: Schema[]): Schema[];
}
export class SchemaTransformer implements ISchemaTransformer {
    constructor();
    prepareSchema(schema: Schema, blueprint: IBlueprint): SchemaItem[];
    reconstructSchema(schemas: Schema[]): Schema[];
}

export interface MinMax {
    min: number;
    max: number;
}
export interface Formats {
    datetime?: string;
}
export interface IBlueprint {
    total: MinMax;
    arrayRange: MinMax;
    required: string[];
    formats: Formats;
    nullValueChance: number;
    userDefined: Record<string, any>;
    getRandomTotalLength: () => number;
    getRandomArrayLength(): number;
    getRandomArrayLength(min: number, max: number): number;
    shouldGenerateNullValue: (key: string) => boolean;
}
export class Blueprint implements IBlueprint {
    total: MinMax;
    required: string[];
    formats: Formats;
    arrayRange: MinMax;
    nullValueChance: number;
    userDefined: Record<string, any>;
    constructor();
    getRandomTotalLength(): number;
    getRandomArrayLength(min?: number, max?: number): number;
    shouldGenerateNullValue(key: string): boolean;
}

export interface IKeyExpander {
    expandKey(key: string, blueprint: IBlueprint): string[];
}
export class KeyExpander implements IKeyExpander {
    expandKey(key: string, blueprint: IBlueprint): string[];
}

