import * as cheerio from "cheerio";
import { CheerioAPI } from "cheerio";
import z$1, { z } from "zod";
import { ParseIngredientOptions } from "parse-ingredient";

//#region src/logger.d.ts
declare enum LogLevel {
  VERBOSE = 0,
  DEBUG = 1,
  INFO = 2,
  WARN = 3,
  ERROR = 4,
}
declare class Logger {
  private context;
  private logLevel;
  constructor(context: string, logLevel?: LogLevel);
  verbose(...args: unknown[]): void;
  debug(...args: unknown[]): void;
  log(...args: unknown[]): void;
  info(...args: unknown[]): void;
  warn(...args: unknown[]): void;
  error(...args: unknown[]): void;
}
//#endregion
//#region src/abstract-plugin.d.ts
declare abstract class AbstractPlugin {
  readonly $: CheerioAPI;
  /** The name of the plugin */
  abstract name: string;
  /** The priority of the plugin */
  abstract priority: number;
  constructor($: CheerioAPI);
}
//#endregion
//#region src/schemas/recipe.schema.d.ts
/**
 * Current schema version for recipe objects.
 * Increment this when making breaking changes to the schema.
 *
 * Version history:
 * - 1.0.0: Initial schema version
 */
declare const RECIPE_SCHEMA_VERSION: "1.0.0";
/**
 * Schema for a parsed ingredient from the parse-ingredient library.
 * This represents the structured data extracted from an ingredient string.
 * @see https://github.com/jakeboone02/parse-ingredient
 */
declare const ParsedIngredientSchema: z.ZodObject<{
  quantity: z.ZodNullable<z.ZodNumber>;
  quantity2: z.ZodNullable<z.ZodNumber>;
  unitOfMeasureID: z.ZodNullable<z.ZodString>;
  unitOfMeasure: z.ZodNullable<z.ZodString>;
  description: z.ZodString;
  isGroupHeader: z.ZodBoolean;
}, z.core.$strip>;
/**
 * Schema for a single ingredient item
 */
declare const IngredientItemSchema: z.ZodObject<{
  value: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
  parsed: z.ZodNullable<z.ZodOptional<z.ZodObject<{
    quantity: z.ZodNullable<z.ZodNumber>;
    quantity2: z.ZodNullable<z.ZodNumber>;
    unitOfMeasureID: z.ZodNullable<z.ZodString>;
    unitOfMeasure: z.ZodNullable<z.ZodString>;
    description: z.ZodString;
    isGroupHeader: z.ZodBoolean;
  }, z.core.$strip>>>;
}, z.core.$strip>;
/**
 * Schema for a group of ingredients
 */
declare const IngredientGroupSchema: z.ZodObject<{
  name: z.ZodNullable<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>>;
  items: z.ZodArray<z.ZodObject<{
    value: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
    parsed: z.ZodNullable<z.ZodOptional<z.ZodObject<{
      quantity: z.ZodNullable<z.ZodNumber>;
      quantity2: z.ZodNullable<z.ZodNumber>;
      unitOfMeasureID: z.ZodNullable<z.ZodString>;
      unitOfMeasure: z.ZodNullable<z.ZodString>;
      description: z.ZodString;
      isGroupHeader: z.ZodBoolean;
    }, z.core.$strip>>>;
  }, z.core.$strip>>;
}, z.core.$strip>;
/**
 * Schema for all recipe ingredients
 * Must have at least one group with at least one ingredient
 */
declare const IngredientsSchema: z.ZodArray<z.ZodObject<{
  name: z.ZodNullable<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>>;
  items: z.ZodArray<z.ZodObject<{
    value: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
    parsed: z.ZodNullable<z.ZodOptional<z.ZodObject<{
      quantity: z.ZodNullable<z.ZodNumber>;
      quantity2: z.ZodNullable<z.ZodNumber>;
      unitOfMeasureID: z.ZodNullable<z.ZodString>;
      unitOfMeasure: z.ZodNullable<z.ZodString>;
      description: z.ZodString;
      isGroupHeader: z.ZodBoolean;
    }, z.core.$strip>>>;
  }, z.core.$strip>>;
}, z.core.$strip>>;
/**
 * Schema for a single instruction step
 */
declare const InstructionItemSchema: z.ZodObject<{
  value: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
}, z.core.$strip>;
/**
 * Schema for a group of instruction steps
 */
declare const InstructionGroupSchema: z.ZodObject<{
  name: z.ZodNullable<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>>;
  items: z.ZodArray<z.ZodObject<{
    value: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
  }, z.core.$strip>>;
}, z.core.$strip>;
/**
 * Schema for all recipe instructions
 * Must have at least one group with at least one step
 */
declare const InstructionsSchema: z.ZodArray<z.ZodObject<{
  name: z.ZodNullable<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>>;
  items: z.ZodArray<z.ZodObject<{
    value: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
  }, z.core.$strip>>;
}, z.core.$strip>>;
/**
 * Schema for a link object
 */
declare const LinkSchema: z.ZodObject<{
  href: z.ZodURL;
  text: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
}, z.core.$strip>;
/**
 * Base RecipeObject schema without cross-field validations.
 * Use this schema when you need to extend the recipe object with custom fields.
 *
 * @example
 * ```ts
 * import { RecipeObjectBaseSchema, applyRecipeValidations } from 'recipe-scrapers-js'
 *
 * const MyCustomRecipeSchema = RecipeObjectBaseSchema.extend({
 *   customField: z.string(),
 * })
 *
 * // Apply the standard recipe validations
 * const MyValidatedRecipeSchema = applyRecipeValidations(MyCustomRecipeSchema)
 * ```
 */
declare const RecipeObjectBaseSchema: z.ZodObject<{
  schemaVersion: z.ZodDefault<z.ZodLiteral<"1.0.0">>;
  host: z.ZodCustomStringFormat<"hostname">;
  title: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
  author: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
  ingredients: z.ZodArray<z.ZodObject<{
    name: z.ZodNullable<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>>;
    items: z.ZodArray<z.ZodObject<{
      value: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
      parsed: z.ZodNullable<z.ZodOptional<z.ZodObject<{
        quantity: z.ZodNullable<z.ZodNumber>;
        quantity2: z.ZodNullable<z.ZodNumber>;
        unitOfMeasureID: z.ZodNullable<z.ZodString>;
        unitOfMeasure: z.ZodNullable<z.ZodString>;
        description: z.ZodString;
        isGroupHeader: z.ZodBoolean;
      }, z.core.$strip>>>;
    }, z.core.$strip>>;
  }, z.core.$strip>>;
  instructions: z.ZodArray<z.ZodObject<{
    name: z.ZodNullable<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>>;
    items: z.ZodArray<z.ZodObject<{
      value: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
    }, z.core.$strip>>;
  }, z.core.$strip>>;
  canonicalUrl: z.ZodURL;
  image: z.ZodURL;
  totalTime: z.ZodNullable<z.ZodInt>;
  cookTime: z.ZodNullable<z.ZodInt>;
  prepTime: z.ZodNullable<z.ZodInt>;
  ratings: z.ZodDefault<z.ZodNumber>;
  ratingsCount: z.ZodDefault<z.ZodInt>;
  yields: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
  description: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
  language: z.ZodDefault<z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>>>;
  siteName: z.ZodNullable<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>>;
  cookingMethod: z.ZodNullable<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>>;
  category: z.ZodDefault<z.ZodArray<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>>>;
  cuisine: z.ZodDefault<z.ZodArray<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>>>;
  keywords: z.ZodDefault<z.ZodArray<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>>>;
  dietaryRestrictions: z.ZodDefault<z.ZodArray<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>>>;
  equipment: z.ZodDefault<z.ZodArray<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>>>;
  links: z.ZodOptional<z.ZodArray<z.ZodObject<{
    href: z.ZodURL;
    text: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
  }, z.core.$strip>>>;
  nutrients: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodString>>;
  reviews: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodString>>;
}, z.core.$strip>;
/**
 * Applies recipe-specific transformations and validations to a schema.
 * Use this when extending RecipeObjectBaseSchema with custom fields.
 *
 * @param schema - A Zod object schema that includes
 * all RecipeObjectBaseSchema fields
 * @returns A schema with transforms and field validations applied
 *
 * @example
 * ```ts
 * const CustomSchema = RecipeObjectBaseSchema.extend({
 *   tags: z.array(z.string()),
 * })
 *
 * const ValidatedCustomSchema = applyRecipeValidations(CustomSchema)
 * ```
 */
declare function applyRecipeValidations<T extends z.infer<typeof RecipeObjectBaseSchema>>(schema: z.ZodType<T>): z.ZodPipe<z.ZodType<T, unknown, z.core.$ZodTypeInternals<T, unknown>>, z.ZodTransform<Awaited<T>, T>>;
/**
 * Strict RecipeObject schema with all validations enforced.
 * This is the standard schema used by recipe scrapers.
 *
 * For custom extensions, use RecipeObjectBaseSchema.extend() and then
 * apply validations with applyRecipeValidations().
 */
declare const RecipeObjectSchema: z.ZodPipe<z.ZodType<{
  schemaVersion: "1.0.0";
  host: string;
  title: string;
  author: string;
  ingredients: {
    name: string | null;
    items: {
      value: string;
      parsed?: {
        quantity: number | null;
        quantity2: number | null;
        unitOfMeasureID: string | null;
        unitOfMeasure: string | null;
        description: string;
        isGroupHeader: boolean;
      } | null | undefined;
    }[];
  }[];
  instructions: {
    name: string | null;
    items: {
      value: string;
    }[];
  }[];
  canonicalUrl: string;
  image: string;
  totalTime: number | null;
  cookTime: number | null;
  prepTime: number | null;
  ratings: number;
  ratingsCount: number;
  yields: string;
  description: string;
  language: string;
  siteName: string | null;
  cookingMethod: string | null;
  category: string[];
  cuisine: string[];
  keywords: string[];
  dietaryRestrictions: string[];
  equipment: string[];
  nutrients: Record<string, string>;
  reviews: Record<string, string>;
  links?: {
    href: string;
    text: string;
  }[] | undefined;
}, unknown, z.core.$ZodTypeInternals<{
  schemaVersion: "1.0.0";
  host: string;
  title: string;
  author: string;
  ingredients: {
    name: string | null;
    items: {
      value: string;
      parsed?: {
        quantity: number | null;
        quantity2: number | null;
        unitOfMeasureID: string | null;
        unitOfMeasure: string | null;
        description: string;
        isGroupHeader: boolean;
      } | null | undefined;
    }[];
  }[];
  instructions: {
    name: string | null;
    items: {
      value: string;
    }[];
  }[];
  canonicalUrl: string;
  image: string;
  totalTime: number | null;
  cookTime: number | null;
  prepTime: number | null;
  ratings: number;
  ratingsCount: number;
  yields: string;
  description: string;
  language: string;
  siteName: string | null;
  cookingMethod: string | null;
  category: string[];
  cuisine: string[];
  keywords: string[];
  dietaryRestrictions: string[];
  equipment: string[];
  nutrients: Record<string, string>;
  reviews: Record<string, string>;
  links?: {
    href: string;
    text: string;
  }[] | undefined;
}, unknown>>, z.ZodTransform<{
  schemaVersion: "1.0.0";
  host: string;
  title: string;
  author: string;
  ingredients: {
    name: string | null;
    items: {
      value: string;
      parsed?: {
        quantity: number | null;
        quantity2: number | null;
        unitOfMeasureID: string | null;
        unitOfMeasure: string | null;
        description: string;
        isGroupHeader: boolean;
      } | null | undefined;
    }[];
  }[];
  instructions: {
    name: string | null;
    items: {
      value: string;
    }[];
  }[];
  canonicalUrl: string;
  image: string;
  totalTime: number | null;
  cookTime: number | null;
  prepTime: number | null;
  ratings: number;
  ratingsCount: number;
  yields: string;
  description: string;
  language: string;
  siteName: string | null;
  cookingMethod: string | null;
  category: string[];
  cuisine: string[];
  keywords: string[];
  dietaryRestrictions: string[];
  equipment: string[];
  nutrients: Record<string, string>;
  reviews: Record<string, string>;
  links?: {
    href: string;
    text: string;
  }[] | undefined;
}, {
  schemaVersion: "1.0.0";
  host: string;
  title: string;
  author: string;
  ingredients: {
    name: string | null;
    items: {
      value: string;
      parsed?: {
        quantity: number | null;
        quantity2: number | null;
        unitOfMeasureID: string | null;
        unitOfMeasure: string | null;
        description: string;
        isGroupHeader: boolean;
      } | null | undefined;
    }[];
  }[];
  instructions: {
    name: string | null;
    items: {
      value: string;
    }[];
  }[];
  canonicalUrl: string;
  image: string;
  totalTime: number | null;
  cookTime: number | null;
  prepTime: number | null;
  ratings: number;
  ratingsCount: number;
  yields: string;
  description: string;
  language: string;
  siteName: string | null;
  cookingMethod: string | null;
  category: string[];
  cuisine: string[];
  keywords: string[];
  dietaryRestrictions: string[];
  equipment: string[];
  nutrients: Record<string, string>;
  reviews: Record<string, string>;
  links?: {
    href: string;
    text: string;
  }[] | undefined;
}>>;
//#endregion
//#region src/types/recipe.interface.d.ts
type List = Set<string>;
/**
 * Parsed ingredient data from the parse-ingredient library
 */
type ParsedIngredient = z.infer<typeof ParsedIngredientSchema>;
/**
 * A single ingredient item
 */
type IngredientItem = z.infer<typeof IngredientItemSchema>;
/**
 * A group of ingredients with an optional group name
 */
type IngredientGroup = z.infer<typeof IngredientGroupSchema>;
/**
 * All recipe ingredients as an array of groups
 */
type Ingredients = IngredientGroup[];
/**
 * A single instruction step
 */
type InstructionItem = z.infer<typeof InstructionItemSchema>;
/**
 * A group of instruction steps with an optional group name
 */
type InstructionGroup = z.infer<typeof InstructionGroupSchema>;
/**
 * All recipe instructions as an array of groups
 */
type Instructions = InstructionGroup[];
/**
 * The complete recipe object
 */
type RecipeObject = z.infer<typeof RecipeObjectSchema>;
/**
 * A link with href and display text
 */
type Link = z.infer<typeof LinkSchema>;
interface RecipeData {
  /**
   * The host name of the website the Scraper class is for.
   * @example 'bbcgoodfood.com'
   */
  host: string;
  /**
   * The website name, as defined in the page's HTML.
   * @default null
   */
  siteName: string | null;
  /**
   * The author of the recipe. This is typically a person's name
   * but can sometimes be an organization or the name of the website
   * the recipe came from. If the recipe does not explicitly define an author,
   * this should return the name of the website.
   * @example 'Good Food team'
   */
  author: string;
  /**
   * The title of the recipe, usually a short sentence or phrase.
   */
  title: string;
  /**
   * The URL to the main image associated with the recipe,
   * usually a photograph of the completed recipe.
   */
  image: string;
  /**
   * The canonical URL for the scraped recipe.
   * The canonical URL is the direct URL (defined by the website) at which the
   * recipe can be found. This URL will generally not contain any query
   * parameters or fragments, except those required to load the recipe.
   */
  canonicalUrl: string;
  /**
   * The language of the recipe page, as defined within the page's HTML.
   * This is typically a two-letter BCP 47 language code, such as 'en' for
   * English or 'de' for German, but may also include the dialect or
   * variation, such as 'en-US' for American English.
   *
   * The language code is based on BCP 47 standards.
   * For a comprehensive list of BCP 47 language codes,
   * refer to this GitHub Gist:
   * @ref https://gist.github.com/typpo/b2b828a35e683b9bf8db91b5404f1bd1
   *
   * @default 'en'
   */
  language: string;
  /**
   * An list of all links found in the page HTML defined within an anchor
   * `<a>` element.
   * Only present when `linksEnabled` option is set to `true`.
   */
  links?: Link[];
  /**
   * A description of the recipe. This is normally a sentence or short
   * paragraph describing the recipe. Often the website defines the
   * description, but sometimes it has to be inferred from the page content.
   */
  description: string;
  /**
   * The ingredients needed to make the recipe.
   *
   * This is an array of ingredient groups, where each group has a name
   * (e.g., "For the sauce", "For the dough") and a list of ingredient items.
   * When there are no groups, the group name is null.
   *
   * @example
   * [
   *   {
   *     name: 'For the sauce',
   *     items: [
   *       { value: '2 tablespoons olive oil' },
   *       { value: '1 onion, chopped' },
   *     ]
   *   }
   * ]
   */
  ingredients: Ingredients;
  /**
   * A list of instructions for preparing the recipe.
   * This is usually a step-by-step guide on how to make the recipe.
   *
   * This is an array of instruction groups, where each group has a name
   * (e.g., "For the sauce", "For assembly") and a list of instruction steps.
   * When there are no groups, the group name is null.
   *
   * @example
   * [
   *   {
   *     name: 'For the dough',
   *     items: [
   *       { value: 'Mix flour and water.' },
   *       { value: 'Knead for 10 minutes.' },
   *     ]
   *   }
   * ]
   */
  instructions: Instructions;
  /**
   * The category or categories that the recipe belongs to.
   * This can contain a mix of cuisine type (for example, country names),
   * mealtime (breakfast/dinner/etc) and dietary properties (gluten-free,
   * vegetarian). The value is defined by the website, so it may overlap with
   * other fields (e.g. `cuisine`).
   * @default Set()
   * @example ['Italian', 'Vegetarian', 'Dinner']
   */
  category: List;
  /**
   * The number of items or servings the recipe will make,
   * including the quantity and unit of the yield.
   * @example '4 servings', '6 items', '12 cookies'.
   */
  yields: string;
  /**
   * The total time (in minutes) required to complete the recipe.
   * @example 45
   */
  totalTime: number | null;
  /**
   * The time (in minutes) to cook the recipe, excluding any time
   * to prepare the ingredients.
   * @default null
   * @example 30
   */
  cookTime: number | null;
  /**
   * The time (in minutes) to prepare the ingredients for the recipe.
   * @default null
   * @example 15
   */
  prepTime: number | null;
  /**
   * A list of cuisines that the recipe belongs to.
   * This is a `Set` of strings representing the cuisine types.
   * @example ['Italian', 'Vegetarian']
   */
  cuisine: List;
  /**
   * The method of cooking the recipe.
   * @default null
   */
  cookingMethod: string | null;
  /**
   * The recipe rating. When available, this is usually the average
   * of all the ratings given to the recipe on the website.
   * @example 4.5
   */
  ratings: number;
  /**
   * The total number of ratings contributed to the recipes rating.
   * @example 150
   */
  ratingsCount: number;
  /**
   * A list of cooking equipment needed for the recipe.
   * @default Set()
   * @example ['Mixing Bowl', 'Whisk', 'Baking Tray']
   */
  equipment: List;
  /**
   * Reviews of the recipe from the website.
   * The keys of the `Map` are the reviewer's name
   * and the values are the review text.
   * @default Map()
   */
  reviews: Map<string, string>;
  /**
   * The nutrition information for the recipe.
   * Each nutrition entry is usually given per unit of yield,
   * i.e. per servings, or per item.
   * The keys of the `Map` are the nutrients (including calories)
   * and the values are the amount of that nutrient, including the unit.
   * @default Map()
   * @example
   * {
   *   calories: '389 calories',
   *   fatContent: '19 grams fat',
   *   // ...
   * }
   */
  nutrients: Map<string, string>;
  /**
   * The dietary restrictions specified by the recipe.
   * @default Set()
   * @example ['Vegan Diet', 'Vegetarian Diet']
   */
  dietaryRestrictions: List;
  /**
   * A list of keywords associated with a recipe.
   * @example ['easy', 'quick', 'dinner']
   */
  keywords: List;
}
/**
 * The fields of a recipe that can be extracted by scraping the HTML.
 * The 'host' field is omitted because it is a static field
 * that is not scraped.
 */
type RecipeFields = Omit<RecipeData, 'host'>;
/**
 * The fields that aren't required for a recipe to be valid.
 */
type OptionalRecipeFields = Pick<RecipeFields, 'siteName' | 'category' | 'cookTime' | 'prepTime' | 'totalTime' | 'cuisine' | 'cookingMethod' | 'ratings' | 'ratingsCount' | 'equipment' | 'reviews' | 'nutrients' | 'dietaryRestrictions' | 'keywords' | 'links'>;
//#endregion
//#region src/abstract-extractor-plugin.d.ts
declare abstract class ExtractorPlugin extends AbstractPlugin {
  /** Whether this plugin can extract the given field */
  abstract supports(field: keyof RecipeFields): boolean;
  /**
   * Extracts the field from the cheerio root.
   * @param field The field to extract
   * @returns The extracted field value
   */
  abstract extract<Key extends keyof RecipeFields>(field: Key): RecipeFields[Key] | Promise<RecipeFields[Key]>;
}
//#endregion
//#region src/abstract-postprocessor-plugin.d.ts
declare abstract class PostProcessorPlugin {
  /** The name of the plugin */
  abstract name: string;
  /** The priority of the plugin */
  abstract priority: number;
  abstract shouldProcess<Key extends keyof RecipeFields>(field: Key): boolean;
  abstract process<T>(field: keyof RecipeFields, value: T): T | Promise<T>;
}
//#endregion
//#region src/plugin-manager.d.ts
declare class PluginManager {
  private extractorPlugins;
  private postProcessorPlugins;
  constructor(baseExtractors: ExtractorPlugin[], basePostProcessors: PostProcessorPlugin[], extraExtractors?: ExtractorPlugin[], extraPostProcessors?: PostProcessorPlugin[]);
  getExtractors(): ExtractorPlugin[];
  getPostProcessors(): PostProcessorPlugin[];
}
//#endregion
//#region src/recipe-extractor.d.ts
declare class RecipeExtractor {
  private plugins;
  private readonly scraperName;
  private readonly options;
  private readonly logger;
  constructor(plugins: ExtractorPlugin[], scraperName: string, options?: {
    logLevel?: LogLevel;
  });
  private getContext;
  extract<Key extends keyof RecipeFields>(field: Key, extractor?: (prevValue: RecipeFields[Key] | undefined) => RecipeFields[Key] | Promise<RecipeFields[Key]>): Promise<RecipeFields[Key]>;
}
//#endregion
//#region src/types/scraper.interface.d.ts
interface ScraperOptions {
  /**
   * Additional extractors to be used by the scraper.
   * These extractors will be added to the default set of extractors.
   * Extractors are applied according to their priority.
   * Higher priority extractors will run first.
   * @default []
   */
  extraExtractors?: ExtractorPlugin[];
  /**
   * Additional post-processors to be used by the scraper.
   * These post-processors will be added to the default set of post-processors.
   * Post-processors are applied after all extractors have run.
   * Post-processors are also applied according to their priority.
   * Higher priority post-processors will run first.
   * @default []
   */
  extraPostProcessors?: PostProcessorPlugin[];
  /**
   * Whether link scraping is enabled.
   * @default false
   */
  linksEnabled?: boolean;
  /**
   * Logging level for the scraper.
   * This controls the verbosity of logs produced by the scraper.
   * @default LogLevel.Warn
   */
  logLevel?: LogLevel;
  /**
   * Enable ingredient parsing using the parse-ingredient library.
   * When enabled, each ingredient item will include a `parsed` field
   * containing structured data (quantity, unit, description, etc.).
   *
   * Can be set to `true` to enable with default options, or pass
   * an options object to customize parsing behavior.
   *
   * @see https://github.com/jakeboone02/parse-ingredient
   * @default false
   *
   * @example
   * // Enable with defaults
   * { parseIngredients: true }
   *
   * @example
   * // Enable with custom options
   * { parseIngredients: { normalizeUOM: true } }
   */
  parseIngredients?: boolean | ParseIngredientOptions;
}
//#endregion
//#region src/abstract-scraper.d.ts
declare abstract class AbstractScraper {
  protected readonly html: string;
  protected readonly url: string;
  protected readonly options: ScraperOptions;
  protected readonly logger: Logger;
  protected readonly pluginManager: PluginManager;
  protected readonly recipeExtractor: RecipeExtractor;
  readonly $: cheerio.CheerioAPI;
  recipeData: RecipeData | null;
  constructor(html: string, url: string, options?: ScraperOptions);
  /**
   * Site-specific extractors (implemented by subclasses)
   * Each extractor is a function that takes the previous value
   * returned by the extractor chain (if any) and returns the field value.
   */
  abstract extractors: { [K in keyof RecipeFields]?: (prevValue: RecipeFields[K] | undefined) => RecipeFields[K] | Promise<RecipeFields[K]> };
  /**
   * Main extraction method - tries site-specific first, then plugins,
   * then applies post-processing.
   */
  extract<Key extends keyof RecipeFields>(field: Key): Promise<RecipeFields[Key]>;
  /**
   * Static method to get the host of the scraper.
   * This should be implemented by subclasses to return the specific host.
   */
  static host(): string;
  /*****************************************************************************
   * Default implementations for common fields that can be overridden
   * by subclasses.
   ****************************************************************************/
  canonicalUrl(): RecipeFields['canonicalUrl'];
  language(): RecipeFields['language'];
  links(): RecipeFields['links'];
  /**
   * Scrape's the recipe and caches the data.
   */
  scrape(): Promise<RecipeData>;
  /**
   * Converts the scraper's data into a JSON-serializable object.
   * Note: schemaVersion is added during validation by parse() or safeParse().
   */
  toRecipeObject(): Promise<Omit<RecipeObject, 'schemaVersion'>>;
  /**
   * Get the Zod schema to use for validation.
   * Subclasses can override to provide custom schemas.
   */
  protected getSchema(): z$1.ZodPipe<z$1.ZodType<{
    schemaVersion: "1.0.0";
    host: string;
    title: string;
    author: string;
    ingredients: {
      name: string | null;
      items: {
        value: string;
        parsed?: {
          quantity: number | null;
          quantity2: number | null;
          unitOfMeasureID: string | null;
          unitOfMeasure: string | null;
          description: string;
          isGroupHeader: boolean;
        } | null | undefined;
      }[];
    }[];
    instructions: {
      name: string | null;
      items: {
        value: string;
      }[];
    }[];
    canonicalUrl: string;
    image: string;
    totalTime: number | null;
    cookTime: number | null;
    prepTime: number | null;
    ratings: number;
    ratingsCount: number;
    yields: string;
    description: string;
    language: string;
    siteName: string | null;
    cookingMethod: string | null;
    category: string[];
    cuisine: string[];
    keywords: string[];
    dietaryRestrictions: string[];
    equipment: string[];
    nutrients: Record<string, string>;
    reviews: Record<string, string>;
    links?: {
      href: string;
      text: string;
    }[] | undefined;
  }, unknown, z$1.core.$ZodTypeInternals<{
    schemaVersion: "1.0.0";
    host: string;
    title: string;
    author: string;
    ingredients: {
      name: string | null;
      items: {
        value: string;
        parsed?: {
          quantity: number | null;
          quantity2: number | null;
          unitOfMeasureID: string | null;
          unitOfMeasure: string | null;
          description: string;
          isGroupHeader: boolean;
        } | null | undefined;
      }[];
    }[];
    instructions: {
      name: string | null;
      items: {
        value: string;
      }[];
    }[];
    canonicalUrl: string;
    image: string;
    totalTime: number | null;
    cookTime: number | null;
    prepTime: number | null;
    ratings: number;
    ratingsCount: number;
    yields: string;
    description: string;
    language: string;
    siteName: string | null;
    cookingMethod: string | null;
    category: string[];
    cuisine: string[];
    keywords: string[];
    dietaryRestrictions: string[];
    equipment: string[];
    nutrients: Record<string, string>;
    reviews: Record<string, string>;
    links?: {
      href: string;
      text: string;
    }[] | undefined;
  }, unknown>>, z$1.ZodTransform<{
    schemaVersion: "1.0.0";
    host: string;
    title: string;
    author: string;
    ingredients: {
      name: string | null;
      items: {
        value: string;
        parsed?: {
          quantity: number | null;
          quantity2: number | null;
          unitOfMeasureID: string | null;
          unitOfMeasure: string | null;
          description: string;
          isGroupHeader: boolean;
        } | null | undefined;
      }[];
    }[];
    instructions: {
      name: string | null;
      items: {
        value: string;
      }[];
    }[];
    canonicalUrl: string;
    image: string;
    totalTime: number | null;
    cookTime: number | null;
    prepTime: number | null;
    ratings: number;
    ratingsCount: number;
    yields: string;
    description: string;
    language: string;
    siteName: string | null;
    cookingMethod: string | null;
    category: string[];
    cuisine: string[];
    keywords: string[];
    dietaryRestrictions: string[];
    equipment: string[];
    nutrients: Record<string, string>;
    reviews: Record<string, string>;
    links?: {
      href: string;
      text: string;
    }[] | undefined;
  }, {
    schemaVersion: "1.0.0";
    host: string;
    title: string;
    author: string;
    ingredients: {
      name: string | null;
      items: {
        value: string;
        parsed?: {
          quantity: number | null;
          quantity2: number | null;
          unitOfMeasureID: string | null;
          unitOfMeasure: string | null;
          description: string;
          isGroupHeader: boolean;
        } | null | undefined;
      }[];
    }[];
    instructions: {
      name: string | null;
      items: {
        value: string;
      }[];
    }[];
    canonicalUrl: string;
    image: string;
    totalTime: number | null;
    cookTime: number | null;
    prepTime: number | null;
    ratings: number;
    ratingsCount: number;
    yields: string;
    description: string;
    language: string;
    siteName: string | null;
    cookingMethod: string | null;
    category: string[];
    cuisine: string[];
    keywords: string[];
    dietaryRestrictions: string[];
    equipment: string[];
    nutrients: Record<string, string>;
    reviews: Record<string, string>;
    links?: {
      href: string;
      text: string;
    }[] | undefined;
  }>>;
  /**
   * Extract and validate recipe data.
   * Throws ZodError if validation fails.
   *
   * @returns Validated recipe object
   * @throws {ZodError} If validation fails
   */
  parse(): Promise<RecipeObject>;
  /**
   * Extract and validate recipe data without throwing.
   * Returns a result object indicating success or failure.
   *
   * @returns Result object with either data or error
   */
  safeParse(): Promise<z$1.ZodSafeParseResult<RecipeObject>>;
}
//#endregion
//#region src/scrapers/allrecipes.d.ts
declare class AllRecipes extends AbstractScraper {
  static host(): string;
  extractors: {};
}
//#endregion
//#region src/scrapers/_index.d.ts
/**
 * A map of all scrapers.
 */
declare const scrapers: {
  readonly [x: string]: typeof AllRecipes;
};
//#endregion
//#region src/index.d.ts
/**
 * Returns a scraper class for the given URL, if implemented.
 */
declare function getScraper(url: string): typeof AllRecipes;
//#endregion
export { ExtractorPlugin, IngredientGroup, IngredientGroupSchema, IngredientItem, IngredientItemSchema, Ingredients, IngredientsSchema, InstructionGroup, InstructionGroupSchema, InstructionItem, InstructionItemSchema, Instructions, InstructionsSchema, Link, LinkSchema, List, LogLevel, Logger, OptionalRecipeFields, ParsedIngredient, ParsedIngredientSchema, PostProcessorPlugin, RECIPE_SCHEMA_VERSION, RecipeData, RecipeFields, RecipeObject, RecipeObjectBaseSchema, RecipeObjectSchema, ScraperOptions, applyRecipeValidations, getScraper, scrapers };