soustack 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +38 -8
- package/dist/cli/index.js +175 -13
- package/dist/cli/index.js.map +1 -1
- package/dist/index.d.mts +44 -1
- package/dist/index.d.ts +44 -1
- package/dist/index.js +187 -13
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +187 -14
- package/dist/index.mjs.map +1 -1
- package/package.json +5 -4
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/parser.ts","../src/schema.json","../src/validator.ts","../src/parsers/ingredient.ts","../src/converters/ingredient.ts","../src/converters/yield.ts","../src/parsers/duration.ts","../src/fromSchemaOrg.ts","../src/converters/toSchemaOrg.ts","../src/scraper/fetch.ts","../src/scraper/extractors/utils.ts","../src/scraper/extractors/jsonld.ts","../src/scraper/extractors/microdata.ts","../src/scraper/extractors/index.ts","../src/scraper/index.ts","../src/parsers/yield.ts"],"names":["Ajv","addFormats","parseIngredientLine","convertIngredients","value","convertInstructions","convertTime","result","load","NUMBER_WORDS","parseYield","formatYield"],"mappings":"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","file":"index.js","sourcesContent":["import { \r\n Recipe, \r\n Ingredient, \r\n IngredientItem, \r\n Instruction, \r\n InstructionItem,\r\n Scaling \r\n} from './types';\r\n\r\n// --- Output Types ---\r\n\r\n/**\r\n * A \"Computed Recipe\" is the result of running the parser.\r\n * It is flat, strict, and ready for the UI to render.\r\n */\r\nexport interface ComputedRecipe {\r\n metadata: {\r\n targetYield: number;\r\n baseYield: number;\r\n multiplier: number;\r\n };\r\n ingredients: ComputedIngredient[];\r\n instructions: ComputedInstruction[];\r\n timing: {\r\n active: number;\r\n passive: number;\r\n total: number;\r\n };\r\n}\r\n\r\nexport interface ComputedIngredient {\r\n id: string;\r\n name: string;\r\n amount: number;\r\n unit: string | null;\r\n text: string; // \"500g Bread Flour\"\r\n notes?: string;\r\n}\r\n\r\nexport interface ComputedInstruction {\r\n id: string;\r\n text: string;\r\n durationMinutes: number;\r\n type: 'active' | 'passive';\r\n}\r\n\r\n// --- Main Logic ---\r\n\r\nexport function scaleRecipe(recipe: Recipe, targetYieldAmount: number): ComputedRecipe {\r\n // 1. Calculate Multiplier\r\n const baseYield = recipe.yield?.amount || 1;\r\n const multiplier = targetYieldAmount / baseYield;\r\n\r\n // 2. Flatten Ingredients (handle subsections)\r\n const flatIngredients = flattenIngredients(recipe.ingredients);\r\n\r\n // 3. Two-Pass Ingredient Scaling\r\n // Pass 1: Scale Independent items (Linear, Fixed, Discrete)\r\n // Pass 2: Scale Dependent items (Baker's %, Proportional)\r\n const scaledIngredientsMap = new Map<string, ComputedIngredient>();\r\n\r\n // --- PASS 1 ---\r\n flatIngredients.forEach(ing => {\r\n if (isIndependent(ing.scaling?.type)) {\r\n const computed = calculateIngredient(ing, multiplier, 0); // Reference unused here\r\n scaledIngredientsMap.set(ing.id || ing.item, computed);\r\n }\r\n });\r\n\r\n // --- PASS 2 ---\r\n flatIngredients.forEach(ing => {\r\n if (!isIndependent(ing.scaling?.type)) {\r\n // Find the reference ingredient's NEW weight\r\n let referenceValue = 0;\r\n if (ing.scaling?.type === 'bakers_percentage' && ing.scaling.referenceId) {\r\n const refIng = scaledIngredientsMap.get(ing.scaling.referenceId);\r\n if (refIng) referenceValue = refIng.amount;\r\n } else {\r\n // Fallback for Proportional: Use generic multiplier if no ref logic defined\r\n referenceValue = multiplier; \r\n }\r\n \r\n const computed = calculateIngredient(ing, multiplier, referenceValue);\r\n scaledIngredientsMap.set(ing.id || ing.item, computed);\r\n }\r\n });\r\n\r\n // 4. Scale Instructions (Timing)\r\n const flatInstructions = flattenInstructions(recipe.instructions);\r\n const computedInstructions = flatInstructions.map(inst => \r\n calculateInstruction(inst, multiplier)\r\n );\r\n\r\n // 5. Aggregate Time\r\n const timing = computedInstructions.reduce(\r\n (acc, step) => {\r\n if (step.type === 'active') acc.active += step.durationMinutes;\r\n else acc.passive += step.durationMinutes;\r\n acc.total += step.durationMinutes;\r\n return acc;\r\n },\r\n { active: 0, passive: 0, total: 0 }\r\n );\r\n\r\n return {\r\n metadata: {\r\n targetYield: targetYieldAmount,\r\n baseYield,\r\n multiplier\r\n },\r\n ingredients: Array.from(scaledIngredientsMap.values()),\r\n instructions: computedInstructions,\r\n timing\r\n };\r\n}\r\n\r\n// --- Helper Functions ---\r\n\r\nfunction isIndependent(type?: string): boolean {\r\n return !type || type === 'linear' || type === 'fixed' || type === 'discrete';\r\n}\r\n\r\nfunction calculateIngredient(\r\n ing: Ingredient, \r\n multiplier: number, \r\n referenceValue: number\r\n): ComputedIngredient {\r\n const baseAmount = ing.quantity?.amount || 0;\r\n const type = ing.scaling?.type || 'linear';\r\n let newAmount = baseAmount;\r\n\r\n switch (type) {\r\n case 'linear':\r\n newAmount = baseAmount * multiplier;\r\n break;\r\n \r\n case 'fixed':\r\n newAmount = baseAmount;\r\n break;\r\n\r\n case 'discrete':\r\n // e.g., Eggs. Round to nearest step (default 1)\r\n const raw = baseAmount * multiplier;\r\n const step = (ing.scaling as any).roundTo || 1; \r\n newAmount = Math.round(raw / step) * step;\r\n // Handle min/max constraints\r\n break;\r\n\r\n case 'bakers_percentage':\r\n // Formula: NewAmount = ReferenceNewAmount * OriginalRatio\r\n // If explicit factor provided (e.g. 0.02 for 2% salt):\r\n // NewAmount = ReferenceNewAmount * Factor\r\n \r\n // Calculate original ratio if not provided? \r\n // Ideally, factor is implicit: (OldAmount / OldRefAmount). \r\n // But for simplicity here, we assume the relationship holds true to the Ref.\r\n \r\n // If we used the Reference Value from Pass 1 (e.g., 1000g flour),\r\n // We need the *Original* Ratio.\r\n // NOTE: In a real app, you calculate the original ratio from the unscaled recipe first.\r\n // For this snippet, let's assume 'factor' exists or we derive it.\r\n \r\n // Simpler approach for v0.1: Re-calculate the ratio dynamically\r\n // But we passed in 'referenceValue' (The NEW amount of flour).\r\n // We need the OLD amount of flour to get the ratio.\r\n // *Simplification*: Just treat it like linear scaling relative to the ref? \r\n // Actually, Baker's % is linear to the flour.\r\n // Ratio = BaseAmount / BaseRefAmount (need lookup).\r\n // Let's rely on standard scaling: If flour doubled, salt doubles.\r\n // Baker's % is mostly useful if you change the RATIO (e.g., \"Make 75% hydration dough\").\r\n // If we are just scaling yield, Baker's % behaves exactly like Linear.\r\n \r\n newAmount = baseAmount * multiplier; \r\n break;\r\n }\r\n\r\n // Apply formatted text\r\n const unit = ing.quantity?.unit || '';\r\n // Extract ingredient name: use ing.name if available, otherwise strip quantity from ing.item\r\n const ingredientName = ing.name || extractNameFromItem(ing.item);\r\n const text = `${parseFloat(newAmount.toFixed(2))}${unit ? ' ' + unit : ''} ${ingredientName}`;\r\n\r\n return {\r\n id: ing.id || ing.item,\r\n name: ingredientName,\r\n amount: newAmount,\r\n unit: ing.quantity?.unit || null,\r\n text,\r\n notes: ing.notes\r\n };\r\n}\r\n\r\n/**\r\n * Extracts the ingredient name from an item string by removing the leading quantity.\r\n * Example: \"900g Bread Flour\" -> \"Bread Flour\"\r\n */\r\nfunction extractNameFromItem(item: string): string {\r\n // Match pattern: optional number, optional decimal, optional unit, then the name\r\n // Examples: \"900g Bread Flour\", \"2 cups flour\", \"100g Whole Wheat Flour\"\r\n const match = item.match(/^\\s*\\d+(?:\\.\\d+)?\\s*\\w*\\s*(.+)$/);\r\n return match ? match[1].trim() : item;\r\n}\r\n\r\nfunction calculateInstruction(inst: Instruction, multiplier: number): ComputedInstruction {\r\n const baseDuration = inst.timing?.duration || 0;\r\n const scalingType = inst.timing?.scaling || 'fixed'; // Default steps to fixed (baking time doesn't usually double)\r\n let newDuration = baseDuration;\r\n\r\n if (scalingType === 'linear') {\r\n newDuration = baseDuration * multiplier;\r\n } else if (scalingType === 'sqrt') {\r\n // Physics approximation for heating larger volumes\r\n newDuration = baseDuration * Math.sqrt(multiplier);\r\n }\r\n\r\n return {\r\n id: inst.id || 'step',\r\n text: inst.text,\r\n durationMinutes: Math.ceil(newDuration),\r\n type: inst.timing?.type || 'active'\r\n };\r\n}\r\n\r\n// --- Flattening Helpers ---\r\n\r\nfunction flattenIngredients(items: IngredientItem[]): Ingredient[] {\r\n const result: Ingredient[] = [];\r\n items.forEach(item => {\r\n if (typeof item === 'string') {\r\n // Basic string support (no scaling possible)\r\n result.push({ item, quantity: { amount: 0, unit: null }, scaling: { type: 'fixed' } });\r\n } else if ('subsection' in item) {\r\n result.push(...flattenIngredients(item.items));\r\n } else {\r\n result.push(item);\r\n }\r\n });\r\n return result;\r\n}\r\n\r\nfunction flattenInstructions(items: InstructionItem[]): Instruction[] {\r\n const result: Instruction[] = [];\r\n items.forEach(item => {\r\n if (typeof item === 'string') {\r\n result.push({ text: item, timing: { duration: 0, type: 'active' } as any });\r\n } else if ('subsection' in item) {\r\n result.push(...flattenInstructions(item.items));\r\n } else {\r\n result.push(item);\r\n }\r\n });\r\n return result;\r\n}","{\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"http://soustack.org/schema/v0.1\",\n \"title\": \"Soustack Recipe Schema v0.1\",\n \"description\": \"A portable, scalable, interoperable recipe format.\",\n \"type\": \"object\",\n \"required\": [\"name\", \"ingredients\", \"instructions\"],\n \"properties\": {\n \"id\": {\n \"type\": \"string\",\n \"description\": \"Unique identifier (slug or UUID)\"\n },\n \"name\": {\n \"type\": \"string\",\n \"description\": \"The title of the recipe\"\n },\n \"version\": {\n \"type\": \"string\",\n \"pattern\": \"^\\\\d+\\\\.\\\\d+\\\\.\\\\d+$\",\n \"description\": \"Semantic versioning (e.g., 1.0.0)\"\n },\n \"description\": {\n \"type\": \"string\"\n },\n \"category\": {\n \"type\": \"string\",\n \"examples\": [\"Main Course\", \"Dessert\"]\n },\n \"tags\": {\n \"type\": \"array\",\n \"items\": { \"type\": \"string\" }\n },\n \"image\": {\n \"type\": \"string\",\n \"format\": \"uri\"\n },\n \"dateAdded\": {\n \"type\": \"string\",\n \"format\": \"date-time\"\n },\n \"source\": {\n \"type\": \"object\",\n \"properties\": {\n \"author\": { \"type\": \"string\" },\n \"url\": { \"type\": \"string\", \"format\": \"uri\" },\n \"name\": { \"type\": \"string\" },\n \"adapted\": { \"type\": \"boolean\" }\n }\n },\n \"yield\": {\n \"$ref\": \"#/definitions/yield\"\n },\n \"time\": {\n \"$ref\": \"#/definitions/time\"\n },\n \"equipment\": {\n \"type\": \"array\",\n \"items\": { \"$ref\": \"#/definitions/equipment\" }\n },\n \"ingredients\": {\n \"type\": \"array\",\n \"items\": {\n \"anyOf\": [\n { \"type\": \"string\" },\n { \"$ref\": \"#/definitions/ingredient\" },\n { \"$ref\": \"#/definitions/ingredientSubsection\" }\n ]\n }\n },\n \"instructions\": {\n \"type\": \"array\",\n \"items\": {\n \"anyOf\": [\n { \"type\": \"string\" },\n { \"$ref\": \"#/definitions/instruction\" },\n { \"$ref\": \"#/definitions/instructionSubsection\" }\n ]\n }\n },\n \"storage\": {\n \"$ref\": \"#/definitions/storage\"\n },\n \"substitutions\": {\n \"type\": \"array\",\n \"items\": { \"$ref\": \"#/definitions/substitution\" }\n }\n },\n \"definitions\": {\n \"yield\": {\n \"type\": \"object\",\n \"required\": [\"amount\", \"unit\"],\n \"properties\": {\n \"amount\": { \"type\": \"number\" },\n \"unit\": { \"type\": \"string\" },\n \"servings\": { \"type\": \"number\" },\n \"description\": { \"type\": \"string\" }\n }\n },\n \"time\": {\n \"oneOf\": [\n {\n \"type\": \"object\",\n \"properties\": {\n \"prep\": { \"type\": \"number\" },\n \"active\": { \"type\": \"number\" },\n \"passive\": { \"type\": \"number\" },\n \"total\": { \"type\": \"number\" }\n }\n },\n {\n \"type\": \"object\",\n \"properties\": {\n \"prepTime\": { \"type\": \"string\" },\n \"cookTime\": { \"type\": \"string\" }\n }\n }\n ]\n },\n \"quantity\": {\n \"type\": \"object\",\n \"required\": [\"amount\"],\n \"properties\": {\n \"amount\": { \"type\": \"number\" },\n \"unit\": { \"type\": [\"string\", \"null\"] }\n }\n },\n \"scaling\": {\n \"type\": \"object\",\n \"required\": [\"type\"],\n \"properties\": {\n \"type\": {\n \"type\": \"string\",\n \"enum\": [\"linear\", \"discrete\", \"proportional\", \"fixed\", \"bakers_percentage\"]\n },\n \"factor\": { \"type\": \"number\" },\n \"referenceId\": { \"type\": \"string\" },\n \"roundTo\": { \"type\": \"number\" },\n \"min\": { \"type\": \"number\" },\n \"max\": { \"type\": \"number\" }\n },\n \"if\": {\n \"properties\": { \"type\": { \"const\": \"bakers_percentage\" } }\n },\n \"then\": {\n \"required\": [\"referenceId\"]\n }\n },\n \"ingredient\": {\n \"type\": \"object\",\n \"required\": [\"item\"],\n \"properties\": {\n \"id\": { \"type\": \"string\" },\n \"item\": { \"type\": \"string\" },\n \"quantity\": { \"$ref\": \"#/definitions/quantity\" },\n \"name\": { \"type\": \"string\" },\n \"aisle\": { \"type\": \"string\" },\n \"prep\": { \"type\": \"string\" },\n \"prepAction\": { \"type\": \"string\" },\n \"prepTime\": { \"type\": \"number\" },\n \"destination\": { \"type\": \"string\" },\n \"scaling\": { \"$ref\": \"#/definitions/scaling\" },\n \"critical\": { \"type\": \"boolean\" },\n \"optional\": { \"type\": \"boolean\" },\n \"notes\": { \"type\": \"string\" }\n }\n },\n \"ingredientSubsection\": {\n \"type\": \"object\",\n \"required\": [\"subsection\", \"items\"],\n \"properties\": {\n \"subsection\": { \"type\": \"string\" },\n \"items\": {\n \"type\": \"array\",\n \"items\": { \"$ref\": \"#/definitions/ingredient\" }\n }\n }\n },\n \"equipment\": {\n \"type\": \"object\",\n \"required\": [\"name\"],\n \"properties\": {\n \"id\": { \"type\": \"string\" },\n \"name\": { \"type\": \"string\" },\n \"required\": { \"type\": \"boolean\" },\n \"label\": { \"type\": \"string\" },\n \"capacity\": { \"$ref\": \"#/definitions/quantity\" },\n \"scalingLimit\": { \"type\": \"number\" },\n \"alternatives\": {\n \"type\": \"array\",\n \"items\": { \"type\": \"string\" }\n }\n }\n },\n \"instruction\": {\n \"type\": \"object\",\n \"required\": [\"text\"],\n \"properties\": {\n \"id\": { \"type\": \"string\" },\n \"text\": { \"type\": \"string\" },\n \"destination\": { \"type\": \"string\" },\n \"dependsOn\": {\n \"type\": \"array\",\n \"items\": { \"type\": \"string\" }\n },\n \"inputs\": {\n \"type\": \"array\",\n \"items\": { \"type\": \"string\" }\n },\n \"timing\": {\n \"type\": \"object\",\n \"required\": [\"duration\", \"type\"],\n \"properties\": {\n \"duration\": { \"type\": \"number\" },\n \"type\": { \"type\": \"string\", \"enum\": [\"active\", \"passive\"] },\n \"scaling\": { \"type\": \"string\", \"enum\": [\"linear\", \"fixed\", \"sqrt\"] }\n }\n }\n }\n },\n \"instructionSubsection\": {\n \"type\": \"object\",\n \"required\": [\"subsection\", \"items\"],\n \"properties\": {\n \"subsection\": { \"type\": \"string\" },\n \"items\": {\n \"type\": \"array\",\n \"items\": {\n \"anyOf\": [\n { \"type\": \"string\" },\n { \"$ref\": \"#/definitions/instruction\" }\n ]\n }\n }\n }\n },\n \"storage\": {\n \"type\": \"object\",\n \"properties\": {\n \"roomTemp\": { \"$ref\": \"#/definitions/storageMethod\" },\n \"refrigerated\": { \"$ref\": \"#/definitions/storageMethod\" },\n \"frozen\": {\n \"allOf\": [\n { \"$ref\": \"#/definitions/storageMethod\" },\n {\n \"type\": \"object\",\n \"properties\": { \"thawing\": { \"type\": \"string\" } }\n }\n ]\n },\n \"reheating\": { \"type\": \"string\" },\n \"makeAhead\": {\n \"type\": \"array\",\n \"items\": {\n \"allOf\": [\n { \"$ref\": \"#/definitions/storageMethod\" },\n {\n \"type\": \"object\",\n \"required\": [\"component\", \"storage\"],\n \"properties\": {\n \"component\": { \"type\": \"string\" },\n \"storage\": { \"type\": \"string\", \"enum\": [\"roomTemp\", \"refrigerated\", \"frozen\"] }\n }\n }\n ]\n }\n }\n }\n },\n \"storageMethod\": {\n \"type\": \"object\",\n \"required\": [\"duration\"],\n \"properties\": {\n \"duration\": { \"type\": \"string\", \"pattern\": \"^P\" },\n \"method\": { \"type\": \"string\" },\n \"notes\": { \"type\": \"string\" }\n }\n },\n \"substitution\": {\n \"type\": \"object\",\n \"required\": [\"ingredient\"],\n \"properties\": {\n \"ingredient\": { \"type\": \"string\" },\n \"critical\": { \"type\": \"boolean\" },\n \"notes\": { \"type\": \"string\" },\n \"alternatives\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"object\",\n \"required\": [\"name\", \"ratio\"],\n \"properties\": {\n \"name\": { \"type\": \"string\" },\n \"ratio\": { \"type\": \"string\" },\n \"notes\": { \"type\": \"string\" },\n \"impact\": { \"type\": \"string\" },\n \"dietary\": {\n \"type\": \"array\",\n \"items\": { \"type\": \"string\" }\n }\n }\n }\n }\n }\n }\n }\n}","import Ajv from \"ajv\";\r\nimport addFormats from \"ajv-formats\"; // <--- Import this\r\nimport schema from \"./schema.json\";\r\nimport { Recipe } from \"./types\";\r\n\r\nconst ajv = new Ajv();\r\naddFormats(ajv); // <--- Enable formats like date-time, uri, email\r\n\r\nconst validate = ajv.compile(schema);\r\n\r\nexport function validateRecipe(data: any): data is Recipe {\r\n const isValid = validate(data);\r\n if (!isValid) {\r\n throw new Error(JSON.stringify(validate.errors, null, 2));\r\n }\r\n return true;\r\n}","import { ParsedIngredient, Scaling } from '../types';\r\n\r\ntype QuantityShape = { amount: number | null; unit: string | null };\r\n\r\ninterface QuantityExtraction {\r\n amount: number | null;\r\n unit: string | null;\r\n remainder: string;\r\n notes: string[];\r\n descriptor?: string;\r\n originalAmount: number | null;\r\n}\r\n\r\ninterface ParentheticalExtraction {\r\n cleaned: string;\r\n measurement?: QuantityShape;\r\n notes: string[];\r\n optional: boolean;\r\n}\r\n\r\ninterface VagueQuantityResult {\r\n remainder: string;\r\n note: string;\r\n}\r\n\r\ninterface FlavorExtractionResult {\r\n cleaned: string;\r\n notes: string[];\r\n}\r\n\r\ninterface PurposeExtractionResult {\r\n cleaned: string;\r\n notes: string[];\r\n}\r\n\r\ninterface JuiceExtractionResult {\r\n cleaned: string;\r\n note: string;\r\n}\r\n\r\nconst FRACTION_DECIMALS: Record<string, number> = {\r\n '½': 0.5,\r\n '⅓': 1 / 3,\r\n '⅔': 2 / 3,\r\n '¼': 0.25,\r\n '¾': 0.75,\r\n '⅕': 0.2,\r\n '⅖': 0.4,\r\n '⅗': 0.6,\r\n '⅘': 0.8,\r\n '⅙': 1 / 6,\r\n '⅚': 5 / 6,\r\n '⅛': 0.125,\r\n '⅜': 0.375,\r\n '⅝': 0.625,\r\n '⅞': 0.875\r\n};\r\n\r\nconst NUMBER_WORDS: Record<string, number> = {\r\n zero: 0,\r\n one: 1,\r\n two: 2,\r\n three: 3,\r\n four: 4,\r\n five: 5,\r\n six: 6,\r\n seven: 7,\r\n eight: 8,\r\n nine: 9,\r\n ten: 10,\r\n eleven: 11,\r\n twelve: 12,\r\n thirteen: 13,\r\n fourteen: 14,\r\n fifteen: 15,\r\n sixteen: 16,\r\n seventeen: 17,\r\n eighteen: 18,\r\n nineteen: 19,\r\n twenty: 20,\r\n thirty: 30,\r\n forty: 40,\r\n fifty: 50,\r\n sixty: 60,\r\n seventy: 70,\r\n eighty: 80,\r\n ninety: 90,\r\n hundred: 100,\r\n half: 0.5,\r\n quarter: 0.25\r\n};\r\n\r\nconst UNIT_SYNONYMS: Record<string, string> = {\r\n cup: 'cup',\r\n cups: 'cup',\r\n c: 'cup',\r\n tbsp: 'tbsp',\r\n tablespoon: 'tbsp',\r\n tablespoons: 'tbsp',\r\n tbs: 'tbsp',\r\n tsp: 'tsp',\r\n teaspoon: 'tsp',\r\n teaspoons: 'tsp',\r\n t: 'tsp',\r\n gram: 'g',\r\n grams: 'g',\r\n g: 'g',\r\n kilogram: 'kg',\r\n kilograms: 'kg',\r\n kg: 'kg',\r\n milliliter: 'ml',\r\n milliliters: 'ml',\r\n ml: 'ml',\r\n liter: 'l',\r\n liters: 'l',\r\n l: 'l',\r\n ounce: 'oz',\r\n ounces: 'oz',\r\n oz: 'oz',\r\n pound: 'lb',\r\n pounds: 'lb',\r\n lb: 'lb',\r\n lbs: 'lb',\r\n pint: 'pint',\r\n pints: 'pint',\r\n quart: 'quart',\r\n quarts: 'quart',\r\n stick: 'stick',\r\n sticks: 'stick',\r\n dash: 'dash',\r\n pinches: 'pinch',\r\n pinch: 'pinch'\r\n};\r\n\r\nconst PREP_PHRASES = [\r\n 'diced',\r\n 'finely diced',\r\n 'roughly diced',\r\n 'minced',\r\n 'finely minced',\r\n 'chopped',\r\n 'finely chopped',\r\n 'roughly chopped',\r\n 'sliced',\r\n 'thinly sliced',\r\n 'thickly sliced',\r\n 'grated',\r\n 'finely grated',\r\n 'zested',\r\n 'sifted',\r\n 'softened',\r\n 'at room temperature',\r\n 'room temperature',\r\n 'room temp',\r\n 'melted',\r\n 'toasted',\r\n 'drained',\r\n 'drained and rinsed',\r\n 'beaten',\r\n 'divided',\r\n 'cut into cubes',\r\n 'cut into pieces',\r\n 'cut into strips',\r\n 'cut into chunks',\r\n 'cut into bite-size pieces'\r\n].map(value => value.toLowerCase());\r\n\r\nconst COUNT_DESCRIPTORS = new Set([\r\n 'clove',\r\n 'cloves',\r\n 'can',\r\n 'cans',\r\n 'stick',\r\n 'sticks',\r\n 'sprig',\r\n 'sprigs',\r\n 'bunch',\r\n 'bunches',\r\n 'slice',\r\n 'slices',\r\n 'package',\r\n 'packages'\r\n]);\r\n\r\nconst DESCRIPTOR_NOTE_SET = new Set(['can', 'cans', 'jar', 'jars', 'package', 'packages', 'bottle', 'bottles']);\r\n\r\nconst WEIGHT_PRIORITY_UNITS = new Set(['g', 'kg', 'oz', 'lb', 'ml', 'l']);\r\n\r\nconst SPICE_KEYWORDS = [\r\n 'salt',\r\n 'pepper',\r\n 'paprika',\r\n 'cumin',\r\n 'coriander',\r\n 'turmeric',\r\n 'chili powder',\r\n 'garlic powder',\r\n 'onion powder',\r\n 'cayenne',\r\n 'cinnamon',\r\n 'nutmeg',\r\n 'allspice',\r\n 'ginger',\r\n 'oregano',\r\n 'thyme',\r\n 'rosemary',\r\n 'basil',\r\n 'sage',\r\n 'clove',\r\n 'spice',\r\n 'seasoning'\r\n];\r\n\r\nconst PURPOSE_KEYWORDS = ['frying', 'greasing', 'drizzling', 'garnish', 'serving', 'brushing'];\r\n\r\nconst RANGE_REGEX =\r\n /^((?:\\d+\\s+)?\\d+\\/\\d+|\\d+\\/\\d+|\\d+(?:\\.\\d+)?)(?:\\s*(?:-|to)\\s*((?:\\d+\\s+)?\\d+\\/\\d+|\\d+\\/\\d+|\\d+(?:\\.\\d+)?))/i;\r\nconst NUMBER_REGEX = /^((?:\\d+\\s+)?\\d+\\/\\d+|\\d+\\/\\d+|\\d+(?:\\.\\d+)?)/i;\r\n\r\nconst QUALIFIER_REGEX = /^(about|around|approximately|approx\\.?|roughly)\\s+/i;\r\n\r\nconst FLAVOR_NOTE_REGEX = /\\b(to taste|as needed|as necessary)\\b/gi;\r\n\r\nconst VAGUE_QUANTITY_PATTERNS: { regex: RegExp; note: string }[] = [\r\n { regex: /^(a\\s+pinch|pinch)\\b/i, note: 'a pinch' },\r\n { regex: /^(a\\s+handful|handful)\\b/i, note: 'a handful' },\r\n { regex: /^(a\\s+dash|dash)\\b/i, note: 'a dash' },\r\n { regex: /^(a\\s+sprinkle|sprinkle)\\b/i, note: 'a sprinkle' },\r\n { regex: /^(some)\\b/i, note: 'some' },\r\n { regex: /^(few\\s+sprigs)/i, note: 'few sprigs' },\r\n { regex: /^(a\\s+few|few)\\b/i, note: 'a few' },\r\n { regex: /^(several)\\b/i, note: 'several' }\r\n];\r\n\r\nconst JUICE_PREFIXES = ['juice of', 'zest of'];\r\n\r\nexport function normalizeIngredientInput(input: string): string {\r\n if (!input) return '';\r\n let result = input.replace(/\\u00A0/g, ' ').trim();\r\n result = replaceDashes(result);\r\n result = replaceUnicodeFractions(result);\r\n result = replaceNumberWords(result);\r\n result = result.replace(/\\s+/g, ' ').trim();\r\n return result;\r\n}\r\n\r\nexport function parseIngredient(text: string): ParsedIngredient {\r\n const original = text ?? '';\r\n const normalized = normalizeIngredientInput(original);\r\n if (!normalized) {\r\n return {\r\n item: original,\r\n scaling: { type: 'linear' }\r\n };\r\n }\r\n\r\n let working = normalized;\r\n const notes: string[] = [];\r\n let optional = false;\r\n\r\n if (/\\boptional\\b/i.test(working)) {\r\n optional = true;\r\n working = working.replace(/\\(?\\s*optional\\s*\\)?/gi, '').trim();\r\n working = working.replace(/\\(\\s*\\)/g, ' ').trim();\r\n }\r\n\r\n const flavorExtraction = extractFlavorNotes(working);\r\n working = flavorExtraction.cleaned;\r\n notes.push(...flavorExtraction.notes);\r\n\r\n const parenthetical = extractParentheticals(working);\r\n working = parenthetical.cleaned;\r\n notes.push(...parenthetical.notes);\r\n optional = optional || parenthetical.optional;\r\n\r\n const purposeExtraction = extractPurposeNotes(working);\r\n working = purposeExtraction.cleaned;\r\n notes.push(...purposeExtraction.notes);\r\n\r\n const juiceExtraction = extractJuicePhrase(working);\r\n if (juiceExtraction) {\r\n working = juiceExtraction.cleaned;\r\n notes.push(juiceExtraction.note);\r\n }\r\n\r\n const vagueQuantity = extractVagueQuantity(working);\r\n\r\n let quantityResult: QuantityExtraction;\r\n if (vagueQuantity) {\r\n notes.push(vagueQuantity.note);\r\n quantityResult = {\r\n amount: null,\r\n unit: null,\r\n descriptor: undefined,\r\n remainder: vagueQuantity.remainder,\r\n notes: [],\r\n originalAmount: null\r\n };\r\n } else {\r\n quantityResult = extractQuantity(working);\r\n }\r\n\r\n working = quantityResult.remainder;\r\n\r\n const { quantity, usedParenthetical } = mergeQuantities(quantityResult, parenthetical.measurement);\r\n if (\r\n usedParenthetical &&\r\n quantityResult.originalAmount !== null &&\r\n quantityResult.originalAmount > 1 &&\r\n quantityResult.descriptor &&\r\n DESCRIPTOR_NOTE_SET.has(quantityResult.descriptor.toLowerCase())\r\n ) {\r\n notes.push(formatCountNote(quantityResult.originalAmount, quantityResult.descriptor));\r\n }\r\n\r\n notes.push(...quantityResult.notes);\r\n\r\n working = working.replace(/^[,.\\s-]+/, '').trim();\r\n working = working.replace(/^of\\s+/i, '').trim();\r\n\r\n if (\r\n quantityResult.descriptor &&\r\n /^cans?$/i.test(quantityResult.descriptor) &&\r\n working &&\r\n !/^canned\\b/i.test(working)\r\n ) {\r\n working = `canned ${working}`.trim();\r\n }\r\n\r\n const nameExtraction = extractNameAndPrep(working);\r\n notes.push(...nameExtraction.notes);\r\n\r\n const name = nameExtraction.name || undefined;\r\n\r\n const scaling = inferScaling(\r\n name,\r\n quantity.unit,\r\n quantity.amount,\r\n notes,\r\n quantityResult.descriptor\r\n );\r\n\r\n const mergedNotes = formatNotes(notes);\r\n\r\n const parsed: ParsedIngredient = {\r\n item: original,\r\n quantity,\r\n ...(name ? { name } : {}),\r\n ...(nameExtraction.prep ? { prep: nameExtraction.prep } : {}),\r\n ...(optional ? { optional: true } : {}),\r\n scaling\r\n };\r\n\r\n if (mergedNotes) {\r\n parsed.notes = mergedNotes;\r\n }\r\n\r\n return parsed;\r\n}\r\n\r\nexport function parseIngredientLine(text: string): ParsedIngredient {\r\n return parseIngredient(text);\r\n}\r\n\r\nexport function parseIngredients(texts: string[]): ParsedIngredient[] {\r\n if (!Array.isArray(texts)) return [];\r\n return texts\r\n .map(item => (typeof item === 'string' ? item : String(item ?? '')))\r\n .map(entry => parseIngredient(entry));\r\n}\r\n\r\nfunction replaceDashes(value: string): string {\r\n return value.replace(/[\\u2012\\u2013\\u2014\\u2212]/g, '-');\r\n}\r\n\r\nfunction replaceUnicodeFractions(value: string): string {\r\n return value.replace(/(\\d+)?(?:\\s+)?([½⅓⅔¼¾⅕⅖⅗⅘⅙⅚⅛⅜⅝⅞])/g, (_match, whole, fraction) => {\r\n const fractionValue = FRACTION_DECIMALS[fraction];\r\n if (fractionValue === undefined) return _match;\r\n const base = whole ? parseInt(whole, 10) : 0;\r\n const combined = base + fractionValue;\r\n return formatDecimal(combined);\r\n });\r\n}\r\n\r\nfunction replaceNumberWords(value: string): string {\r\n return value.replace(\r\n /\\b(zero|one|two|three|four|five|six|seven|eight|nine|ten|eleven|twelve|thirteen|fourteen|fifteen|sixteen|seventeen|eighteen|nineteen|twenty|thirty|forty|fifty|sixty|seventy|eighty|ninety|hundred|half|quarter)(?:-(one|two|three|four|five|six|seven|eight|nine))?\\b/gi,\r\n (match, word, hyphenPart) => {\r\n const lower = word.toLowerCase();\r\n const baseValue = NUMBER_WORDS[lower];\r\n if (baseValue === undefined) return match;\r\n if (!hyphenPart) {\r\n return formatDecimal(baseValue);\r\n }\r\n const hyphenValue = NUMBER_WORDS[hyphenPart.toLowerCase()];\r\n if (hyphenValue === undefined) {\r\n return formatDecimal(baseValue);\r\n }\r\n return formatDecimal(baseValue + hyphenValue);\r\n }\r\n );\r\n}\r\n\r\nfunction formatDecimal(value: number): string {\r\n if (Number.isInteger(value)) {\r\n return value.toString();\r\n }\r\n return parseFloat(value.toFixed(3)).toString().replace(/\\.0+$/, '');\r\n}\r\n\r\nfunction extractFlavorNotes(value: string): FlavorExtractionResult {\r\n const notes: string[] = [];\r\n const cleaned = value.replace(FLAVOR_NOTE_REGEX, (_, phrase) => {\r\n notes.push(phrase.toLowerCase());\r\n return '';\r\n });\r\n\r\n return {\r\n cleaned: cleaned.replace(/\\s+/g, ' ').trim(),\r\n notes\r\n };\r\n}\r\n\r\nfunction extractPurposeNotes(value: string): PurposeExtractionResult {\r\n const notes: string[] = [];\r\n let working = value.trim();\r\n\r\n let match = working.match(/\\bfor\\s+(frying|greasing|drizzling|garnish|serving|brushing)\\b\\.?$/i);\r\n if (match) {\r\n notes.push(`for ${match[1].toLowerCase()}`);\r\n working = working.slice(0, match.index).trim();\r\n }\r\n\r\n return { cleaned: working, notes };\r\n}\r\n\r\nfunction extractJuicePhrase(value: string): JuiceExtractionResult | undefined {\r\n const lower = value.toLowerCase();\r\n for (const prefix of JUICE_PREFIXES) {\r\n if (lower.startsWith(prefix)) {\r\n const remainder = value.slice(prefix.length).trim();\r\n if (!remainder) break;\r\n const cleanedSource = remainder.replace(/^of\\s+/i, '').trim();\r\n if (!cleanedSource) break;\r\n const sourceForName = cleanedSource\r\n .replace(\r\n /^(?:\\d+(?:\\.\\d+)?|\\d+\\s+\\d+\\/\\d+|\\d+\\/\\d+|one|two|three|four|five|six|seven|eight|nine|ten|a|an)\\s+/i,\r\n ''\r\n )\r\n .replace(/^(?:large|small|medium)\\s+/i, '')\r\n .trim();\r\n const baseName = sourceForName || cleanedSource;\r\n const singular = singularize(baseName);\r\n const suffix = prefix.startsWith('zest') ? 'zest' : 'juice';\r\n return {\r\n cleaned: `${singular} ${suffix}`.trim(),\r\n note: `from ${cleanedSource}`\r\n };\r\n }\r\n }\r\n return undefined;\r\n}\r\n\r\nfunction extractVagueQuantity(value: string): VagueQuantityResult | undefined {\r\n for (const pattern of VAGUE_QUANTITY_PATTERNS) {\r\n const match = value.match(pattern.regex);\r\n if (match) {\r\n let remainder = value.slice(match[0].length).trim();\r\n remainder = remainder.replace(/^of\\s+/i, '').trim();\r\n return {\r\n remainder,\r\n note: pattern.note\r\n };\r\n }\r\n }\r\n return undefined;\r\n}\r\n\r\nfunction extractParentheticals(value: string): ParentheticalExtraction {\r\n let optional = false;\r\n let measurement: QuantityShape | undefined;\r\n const notes: string[] = [];\r\n\r\n const cleaned = value.replace(/\\(([^)]+)\\)/g, (_match, group) => {\r\n const trimmed = String(group).trim();\r\n if (!trimmed) return '';\r\n if (/optional/i.test(trimmed)) {\r\n optional = true;\r\n return '';\r\n }\r\n const maybeMeasurement = parseMeasurement(trimmed);\r\n if (maybeMeasurement && !measurement) {\r\n measurement = maybeMeasurement;\r\n return '';\r\n }\r\n notes.push(trimmed);\r\n return '';\r\n });\r\n\r\n return {\r\n cleaned: cleaned.replace(/\\s+/g, ' ').trim(),\r\n measurement,\r\n notes,\r\n optional\r\n };\r\n}\r\n\r\nfunction parseMeasurement(value: string): QuantityShape | undefined {\r\n const stripped = value.replace(/^(about|around|approximately|approx\\.?|roughly)\\s+/i, '').trim();\r\n const match = stripped.match(\r\n /^((?:\\d+\\s+)?\\d+\\/\\d+|\\d+\\/\\d+|\\d+(?:\\.\\d+)?)(?:\\s*)([a-zA-Z]+)?$/\r\n );\r\n if (!match) return undefined;\r\n const amount = parseNumber(match[1]);\r\n if (amount === null) return undefined;\r\n const unit = match[2] ? normalizeUnit(match[2]) ?? match[2].toLowerCase() : null;\r\n return { amount, unit };\r\n}\r\n\r\nfunction extractQuantity(value: string): QuantityExtraction {\r\n let working = value.trim();\r\n const notes: string[] = [];\r\n let amount: number | null = null;\r\n let originalAmount: number | null = null;\r\n let unit: string | null = null;\r\n let descriptor: string | undefined;\r\n\r\n while (QUALIFIER_REGEX.test(working)) {\r\n working = working.replace(QUALIFIER_REGEX, '').trim();\r\n }\r\n\r\n const rangeMatch = working.match(RANGE_REGEX);\r\n if (rangeMatch) {\r\n amount = parseNumber(rangeMatch[1]);\r\n originalAmount = amount;\r\n const rangeText = rangeMatch[0].trim();\r\n const afterRange = working.slice(rangeMatch[0].length).trim();\r\n const descriptorMatch = afterRange.match(/^([a-zA-Z]+)/);\r\n if (descriptorMatch && COUNT_DESCRIPTORS.has(descriptorMatch[1].toLowerCase())) {\r\n notes.push(`${rangeText} ${descriptorMatch[1]}`);\r\n } else {\r\n notes.push(rangeText);\r\n }\r\n working = afterRange;\r\n } else {\r\n const numberMatch = working.match(NUMBER_REGEX);\r\n if (numberMatch) {\r\n amount = parseNumber(numberMatch[1]);\r\n originalAmount = amount;\r\n working = working.slice(numberMatch[0].length).trim();\r\n }\r\n }\r\n\r\n if (working) {\r\n const unitMatch = working.match(/^([a-zA-Z]+)\\b/);\r\n if (unitMatch) {\r\n const normalized = normalizeUnit(unitMatch[1]);\r\n if (normalized) {\r\n unit = normalized;\r\n working = working.slice(unitMatch[0].length).trim();\r\n } else if (COUNT_DESCRIPTORS.has(unitMatch[1].toLowerCase())) {\r\n descriptor = unitMatch[1];\r\n working = working.slice(unitMatch[0].length).trim();\r\n }\r\n }\r\n }\r\n\r\n return {\r\n amount,\r\n unit,\r\n descriptor,\r\n remainder: working.trim(),\r\n notes,\r\n originalAmount\r\n };\r\n}\r\n\r\nfunction parseNumber(value: string): number | null {\r\n const trimmed = value.trim();\r\n if (!trimmed) return null;\r\n if (/^\\d+\\s+\\d+\\/\\d+$/.test(trimmed)) {\r\n const [whole, fraction] = trimmed.split(/\\s+/);\r\n return parseInt(whole, 10) + parseFraction(fraction);\r\n }\r\n if (/^\\d+\\/\\d+$/.test(trimmed)) {\r\n return parseFraction(trimmed);\r\n }\r\n const parsed = Number(trimmed);\r\n return Number.isNaN(parsed) ? null : parsed;\r\n}\r\n\r\nfunction parseFraction(value: string): number {\r\n const [numerator, denominator] = value.split('/').map(Number);\r\n if (!denominator) return numerator;\r\n return numerator / denominator;\r\n}\r\n\r\nfunction normalizeUnit(raw: string): string | null {\r\n const lower = raw.toLowerCase();\r\n if (UNIT_SYNONYMS[lower]) {\r\n return UNIT_SYNONYMS[lower];\r\n }\r\n if (raw === 'T') return 'tbsp';\r\n if (raw === 't') return 'tsp';\r\n if (raw === 'C') return 'cup';\r\n return null;\r\n}\r\n\r\nfunction mergeQuantities(\r\n extracted: QuantityExtraction,\r\n measurement?: QuantityShape\r\n): { quantity: QuantityShape; usedParenthetical: boolean } {\r\n const quantity: QuantityShape = {\r\n amount: extracted.amount ?? null,\r\n unit: extracted.unit ?? null\r\n };\r\n\r\n if (!measurement) {\r\n return { quantity, usedParenthetical: false };\r\n }\r\n\r\n const measurementUnit = measurement.unit?.toLowerCase() ?? null;\r\n const shouldPrefer =\r\n !quantity.unit ||\r\n (measurementUnit !== null && WEIGHT_PRIORITY_UNITS.has(measurementUnit));\r\n\r\n if (shouldPrefer) {\r\n return {\r\n quantity: {\r\n amount: measurement.amount,\r\n unit: measurement.unit ?? null\r\n },\r\n usedParenthetical: true\r\n };\r\n }\r\n\r\n return { quantity, usedParenthetical: false };\r\n}\r\n\r\nfunction extractNameAndPrep(value: string): {\r\n name?: string;\r\n prep?: string;\r\n notes: string[];\r\n} {\r\n let working = value.trim();\r\n const notes: string[] = [];\r\n let prep: string | undefined;\r\n\r\n const lastComma = working.lastIndexOf(',');\r\n if (lastComma >= 0) {\r\n const trailing = working.slice(lastComma + 1).trim();\r\n if (isPrepPhrase(trailing)) {\r\n prep = trailing;\r\n working = working.slice(0, lastComma).trim();\r\n }\r\n }\r\n\r\n working = working.replace(/^[,.\\s-]+/, '').trim();\r\n working = working.replace(/^of\\s+/i, '').trim();\r\n\r\n if (!working) {\r\n return { name: undefined, prep, notes };\r\n }\r\n\r\n let name = cleanupIngredientName(working);\r\n\r\n return {\r\n name: name || undefined,\r\n prep,\r\n notes\r\n };\r\n}\r\n\r\nfunction cleanupIngredientName(value: string): string {\r\n let result = value.trim();\r\n\r\n if (/^cans?\\b/i.test(result)) {\r\n result = result.replace(/^cans?\\b/i, 'canned').trim();\r\n }\r\n\r\n let changed = true;\r\n while (changed) {\r\n changed = false;\r\n if (/^of\\s+/i.test(result)) {\r\n result = result.replace(/^of\\s+/i, '').trim();\r\n changed = true;\r\n continue;\r\n }\r\n const match = result.match(/^(clove|cloves|sprig|sprigs|bunch|bunches|stick|sticks|slice|slices)\\b/i);\r\n if (match) {\r\n result = result.slice(match[0].length).trim();\r\n changed = true;\r\n }\r\n }\r\n\r\n return result;\r\n}\r\n\r\nfunction isPrepPhrase(value: string): boolean {\r\n const normalized = value.toLowerCase();\r\n return PREP_PHRASES.includes(normalized);\r\n}\r\n\r\nfunction inferScaling(\r\n name: string | undefined,\r\n unit: string | null,\r\n amount: number | null,\r\n notes: string[],\r\n descriptor?: string\r\n): Scaling {\r\n const lowerName = name?.toLowerCase() ?? '';\r\n const normalizedNotes = notes.map(note => note.toLowerCase());\r\n const descriptorLower = descriptor?.toLowerCase();\r\n\r\n if (\r\n lowerName.includes('egg') ||\r\n descriptorLower === 'clove' ||\r\n descriptorLower === 'cloves' ||\r\n normalizedNotes.some(note => note.includes('clove'))\r\n ) {\r\n return { type: 'discrete', roundTo: 1 };\r\n }\r\n\r\n if (descriptorLower === 'stick' || descriptorLower === 'sticks') {\r\n return { type: 'discrete', roundTo: 1 };\r\n }\r\n\r\n if (normalizedNotes.some(note => PURPOSE_KEYWORDS.some(keyword => note.includes(keyword)))) {\r\n return { type: 'fixed' };\r\n }\r\n\r\n const isSpice = SPICE_KEYWORDS.some(keyword => lowerName.includes(keyword));\r\n const smallUnit = unit ? ['tsp', 'tbsp', 'dash', 'pinch'].includes(unit) : false;\r\n if (\r\n normalizedNotes.some(note => note.includes('to taste')) ||\r\n (isSpice && (smallUnit || (amount !== null && amount <= 1)))\r\n ) {\r\n return { type: 'proportional', factor: 0.7 };\r\n }\r\n\r\n return { type: 'linear' };\r\n}\r\n\r\nfunction formatNotes(notes: string[]): string | undefined {\r\n const cleaned = Array.from(\r\n new Set(\r\n notes\r\n .map(note => note.trim())\r\n .filter(Boolean)\r\n )\r\n );\r\n return cleaned.length ? cleaned.join('; ') : undefined;\r\n}\r\n\r\nfunction formatCountNote(amount: number, descriptor: string): string {\r\n const lower = descriptor.toLowerCase();\r\n const singular = lower.endsWith('s') ? lower.slice(0, -1) : lower;\r\n const word =\r\n amount === 1\r\n ? singular\r\n : singular.endsWith('ch') || singular.endsWith('sh') || singular.endsWith('s') || singular.endsWith('x') || singular.endsWith('z')\r\n ? `${singular}es`\r\n : singular.endsWith('y') && !/[aeiou]y$/.test(singular)\r\n ? `${singular.slice(0, -1)}ies`\r\n : `${singular}s`;\r\n return `${formatDecimal(amount)} ${word}`;\r\n}\r\n\r\nfunction singularize(value: string): string {\r\n const trimmed = value.trim();\r\n if (trimmed.endsWith('ies')) {\r\n return `${trimmed.slice(0, -3)}y`;\r\n }\r\n if (/(ches|shes|sses|xes|zes)$/i.test(trimmed)) {\r\n return trimmed.slice(0, -2);\r\n }\r\n if (trimmed.endsWith('s')) {\r\n return trimmed.slice(0, -1);\r\n }\r\n return trimmed;\r\n}\r\n","import { Ingredient, ParsedIngredient, Quantity } from '../types';\r\nimport { parseIngredient } from '../parsers/ingredient';\r\n\r\nexport function parseIngredientLine(line: string): Ingredient {\r\n const parsed = parseIngredient(line);\r\n\r\n const ingredient: Ingredient = {\r\n item: parsed.item,\r\n scaling: parsed.scaling ?? { type: 'linear' }\r\n };\r\n\r\n if (parsed.name) {\r\n ingredient.name = parsed.name;\r\n }\r\n\r\n if (parsed.prep) {\r\n ingredient.prep = parsed.prep;\r\n }\r\n\r\n if (parsed.optional) {\r\n ingredient.optional = true;\r\n }\r\n\r\n if (parsed.notes) {\r\n ingredient.notes = parsed.notes;\r\n }\r\n\r\n const quantity = buildQuantity(parsed.quantity);\r\n if (quantity) {\r\n ingredient.quantity = quantity;\r\n }\r\n\r\n return ingredient;\r\n}\r\n\r\nfunction buildQuantity(\r\n parsedQuantity: ParsedIngredient['quantity']\r\n): Quantity | undefined {\r\n if (!parsedQuantity) {\r\n return undefined;\r\n }\r\n\r\n if (parsedQuantity.amount === null || Number.isNaN(parsedQuantity.amount)) {\r\n return undefined;\r\n }\r\n\r\n return {\r\n amount: parsedQuantity.amount,\r\n unit: parsedQuantity.unit ?? null\r\n };\r\n}\r\n","import { Yield } from '../types';\r\n\r\nexport function parseYield(value: unknown): Yield | undefined {\r\n if (value === undefined || value === null) {\r\n return undefined;\r\n }\r\n\r\n if (typeof value === 'number') {\r\n return {\r\n amount: value,\r\n unit: 'servings'\r\n };\r\n }\r\n\r\n if (Array.isArray(value)) {\r\n return parseYield(value[0]);\r\n }\r\n\r\n if (typeof value === 'object') {\r\n const maybeYield = value as Record<string, any>;\r\n if (typeof maybeYield.amount === 'number') {\r\n return {\r\n amount: maybeYield.amount,\r\n unit: typeof maybeYield.unit === 'string' ? maybeYield.unit : 'servings',\r\n description:\r\n typeof maybeYield.description === 'string'\r\n ? maybeYield.description\r\n : undefined\r\n };\r\n }\r\n }\r\n\r\n if (typeof value === 'string') {\r\n const trimmed = value.trim();\r\n const match = trimmed.match(/(\\d+(?:\\.\\d+)?)/);\r\n if (match) {\r\n const amount = parseFloat(match[1]);\r\n const unit = trimmed.slice(match.index! + match[1].length).trim();\r\n return {\r\n amount,\r\n unit: unit || 'servings',\r\n description: trimmed\r\n };\r\n }\r\n }\r\n\r\n return undefined;\r\n}\r\n\r\nexport function formatYield(yieldValue?: Yield): string | undefined {\r\n if (!yieldValue) return undefined;\r\n if (!yieldValue.amount && !yieldValue.unit) {\r\n return undefined;\r\n }\r\n\r\n const amount = yieldValue.amount ?? '';\r\n const unit = yieldValue.unit ? ` ${yieldValue.unit}` : '';\r\n return `${amount}${unit}`.trim() || yieldValue.description;\r\n}\r\n","const ISO_DURATION_REGEX =\r\n /^P(?:(\\d+(?:\\.\\d+)?)D)?(?:T(?:(\\d+(?:\\.\\d+)?)H)?(?:(\\d+(?:\\.\\d+)?)M)?(?:(\\d+(?:\\.\\d+)?)S)?)?$/i;\r\n\r\nconst HUMAN_OVERNIGHT = 8 * 60; // 8 hours\r\n\r\nfunction isFiniteNumber(value: unknown): value is number {\r\n return typeof value === 'number' && Number.isFinite(value);\r\n}\r\n\r\nexport function parseDuration(iso: string): number | null;\r\nexport function parseDuration(iso: string | null | undefined): number | null;\r\nexport function parseDuration(iso: string | null | undefined): number | null {\r\n if (!iso || typeof iso !== 'string') return null;\r\n\r\n const trimmed = iso.trim();\r\n if (!trimmed) return null;\r\n\r\n const match = trimmed.match(ISO_DURATION_REGEX);\r\n if (!match) return null;\r\n\r\n const [, daysRaw, hoursRaw, minutesRaw, secondsRaw] = match;\r\n\r\n if (!daysRaw && !hoursRaw && !minutesRaw && !secondsRaw) {\r\n return null;\r\n }\r\n\r\n let total = 0;\r\n if (daysRaw) total += parseFloat(daysRaw) * 24 * 60;\r\n if (hoursRaw) total += parseFloat(hoursRaw) * 60;\r\n if (minutesRaw) total += parseFloat(minutesRaw);\r\n if (secondsRaw) total += Math.ceil(parseFloat(secondsRaw) / 60);\r\n\r\n return Math.round(total);\r\n}\r\n\r\nexport function formatDuration(minutes: number): string;\r\nexport function formatDuration(minutes: number | null | undefined): string;\r\nexport function formatDuration(minutes: number | null | undefined): string {\r\n if (!isFiniteNumber(minutes) || minutes <= 0) {\r\n return 'PT0M';\r\n }\r\n\r\n const rounded = Math.round(minutes);\r\n const days = Math.floor(rounded / (24 * 60));\r\n const afterDays = rounded % (24 * 60);\r\n const hours = Math.floor(afterDays / 60);\r\n const mins = afterDays % 60;\r\n\r\n let result = 'P';\r\n\r\n if (days > 0) {\r\n result += `${days}D`;\r\n }\r\n\r\n if (hours > 0 || mins > 0) {\r\n result += 'T';\r\n if (hours > 0) {\r\n result += `${hours}H`;\r\n }\r\n if (mins > 0) {\r\n result += `${mins}M`;\r\n }\r\n }\r\n\r\n if (result === 'P') {\r\n return 'PT0M';\r\n }\r\n\r\n return result;\r\n}\r\n\r\nexport function parseHumanDuration(text: string): number | null;\r\nexport function parseHumanDuration(text: string | null | undefined): number | null;\r\nexport function parseHumanDuration(text: string | null | undefined): number | null {\r\n if (!text || typeof text !== 'string') return null;\r\n\r\n const normalized = text.toLowerCase().trim();\r\n if (!normalized) return null;\r\n\r\n if (normalized === 'overnight') {\r\n return HUMAN_OVERNIGHT;\r\n }\r\n\r\n let total = 0;\r\n\r\n const hourRegex = /(\\d+(?:\\.\\d+)?)\\s*(?:hours?|hrs?|hr|h)\\b/g;\r\n let hourMatch: RegExpExecArray | null;\r\n while ((hourMatch = hourRegex.exec(normalized)) !== null) {\r\n total += parseFloat(hourMatch[1]) * 60;\r\n }\r\n\r\n const minuteRegex = /(\\d+(?:\\.\\d+)?)\\s*(?:minutes?|mins?|min|m)\\b/g;\r\n let minuteMatch: RegExpExecArray | null;\r\n while ((minuteMatch = minuteRegex.exec(normalized)) !== null) {\r\n total += parseFloat(minuteMatch[1]);\r\n }\r\n\r\n if (total <= 0) {\r\n return null;\r\n }\r\n\r\n return Math.round(total);\r\n}\r\n\r\nexport function smartParseDuration(input: string): number | null;\r\nexport function smartParseDuration(input: string | null | undefined): number | null;\r\nexport function smartParseDuration(input: string | null | undefined): number | null {\r\n const iso = parseDuration(input);\r\n if (iso !== null) {\r\n return iso;\r\n }\r\n return parseHumanDuration(input);\r\n}\r\n","import {\n IngredientItem,\n Instruction,\n InstructionItem,\n Recipe,\n Source,\n StructuredTime\n} from './types';\nimport { parseIngredientLine } from './converters/ingredient';\nimport { parseYield } from './converters/yield';\nimport { smartParseDuration } from './parsers/duration';\nimport {\n HowToSection,\n HowToStep,\n SchemaOrgImage,\n SchemaOrgPersonOrOrganization,\n SchemaOrgRecipe\n} from './types/schemaOrg';\n\nexport function fromSchemaOrg(input: unknown): Recipe | null {\n const recipeNode = extractRecipeNode(input);\n if (!recipeNode) {\n return null;\n }\n\n const ingredients = convertIngredients(recipeNode.recipeIngredient);\n const instructions = convertInstructions(recipeNode.recipeInstructions);\n const time = convertTime(recipeNode);\n const recipeYield = parseYield(recipeNode.recipeYield);\n const tags = collectTags(recipeNode.recipeCuisine, recipeNode.keywords);\n const category = extractFirst(recipeNode.recipeCategory);\n const image = convertImage(recipeNode.image);\n const source = convertSource(recipeNode);\n const nutrition =\n recipeNode.nutrition && typeof recipeNode.nutrition === 'object'\n ? recipeNode.nutrition\n : undefined;\n\n return {\n name: recipeNode.name.trim(),\n description: recipeNode.description?.trim() || undefined,\n image,\n category,\n tags: tags.length ? tags : undefined,\n source,\n dateAdded: recipeNode.datePublished || undefined,\n dateModified: recipeNode.dateModified || undefined,\n yield: recipeYield,\n time,\n ingredients,\n instructions,\n nutrition\n };\n}\n\nfunction extractRecipeNode(input: unknown): SchemaOrgRecipe | null {\n if (!input) return null;\n\n if (Array.isArray(input)) {\n for (const entry of input) {\n const found = extractRecipeNode(entry);\n if (found) {\n return found;\n }\n }\n return null;\n }\n\n if (typeof input !== 'object') {\n return null;\n }\n\n const record = input as Partial<SchemaOrgRecipe> & { [key: string]: unknown };\n\n if (record['@graph']) {\n const fromGraph = extractRecipeNode(record['@graph']);\n if (fromGraph) {\n return fromGraph;\n }\n }\n\n if (!hasRecipeType(record['@type'])) {\n return null;\n }\n\n if (!isValidName(record.name)) {\n return null;\n }\n\n return record as SchemaOrgRecipe;\n}\n\nfunction hasRecipeType(value: SchemaOrgRecipe['@type']): boolean {\n if (!value) return false;\n const types = Array.isArray(value) ? value : [value];\n return types.some(\n entry => typeof entry === 'string' && entry.toLowerCase() === 'recipe'\n );\n}\n\nfunction isValidName(name: unknown): name is string {\n return typeof name === 'string' && Boolean(name.trim());\n}\n\nfunction convertIngredients(\n value: SchemaOrgRecipe['recipeIngredient']\n): IngredientItem[] {\n if (!value) return [];\n const normalized = Array.isArray(value) ? value : [value];\n return normalized\n .map(item => (typeof item === 'string' ? item.trim() : ''))\n .filter(Boolean)\n .map(line => parseIngredientLine(line));\n}\n\nfunction convertInstructions(\n value: SchemaOrgRecipe['recipeInstructions']\n): InstructionItem[] {\n if (!value) return [];\n const normalized = Array.isArray(value) ? value : [value];\n const result: InstructionItem[] = [];\n\n for (const entry of normalized) {\n if (!entry) continue;\n\n if (typeof entry === 'string') {\n const text = entry.trim();\n if (text) {\n result.push(text);\n }\n continue;\n }\n\n if (isHowToSection(entry)) {\n const subsectionItems = extractSectionItems(entry.itemListElement);\n if (subsectionItems.length) {\n result.push({\n subsection: entry.name?.trim() || 'Section',\n items: subsectionItems\n });\n }\n continue;\n }\n\n if (isHowToStep(entry)) {\n const text = extractInstructionText(entry);\n if (text) {\n result.push(text);\n }\n }\n }\n\n return result;\n}\n\nfunction extractSectionItems(\n items: Array<string | HowToStep | HowToSection> = []\n): Array<string | Instruction> {\n const result: Array<string | Instruction> = [];\n\n for (const item of items) {\n if (!item) continue;\n\n if (typeof item === 'string') {\n const text = item.trim();\n if (text) {\n result.push(text);\n }\n continue;\n }\n\n if (isHowToStep(item)) {\n const text = extractInstructionText(item);\n if (text) {\n result.push(text);\n }\n continue;\n }\n\n if (isHowToSection(item)) {\n result.push(...extractSectionItems(item.itemListElement));\n }\n }\n\n return result;\n}\n\nfunction extractInstructionText(value: HowToStep): string | undefined {\n const text = typeof value.text === 'string' ? value.text : value.name;\n return typeof text === 'string' ? text.trim() || undefined : undefined;\n}\n\nfunction isHowToStep(value: unknown): value is HowToStep {\n return (\n Boolean(value) &&\n typeof value === 'object' &&\n (value as HowToStep)['@type'] === 'HowToStep'\n );\n}\n\nfunction isHowToSection(value: unknown): value is HowToSection {\n return (\n Boolean(value) &&\n typeof value === 'object' &&\n (value as HowToSection)['@type'] === 'HowToSection' &&\n Array.isArray((value as HowToSection).itemListElement)\n );\n}\n\nfunction convertTime(recipe: SchemaOrgRecipe): StructuredTime | undefined {\n const prep = smartParseDuration(recipe.prepTime ?? '');\n const cook = smartParseDuration(recipe.cookTime ?? '');\n const total = smartParseDuration(recipe.totalTime ?? '');\n\n const structured: StructuredTime = {};\n if (prep !== null && prep !== undefined) structured.prep = prep;\n if (cook !== null && cook !== undefined) structured.active = cook;\n if (total !== null && total !== undefined) structured.total = total;\n\n return Object.keys(structured).length ? structured : undefined;\n}\n\nfunction collectTags(cuisine: unknown, keywords: unknown): string[] {\n const tags = new Set<string>();\n flattenStrings(cuisine).forEach(tag => tags.add(tag));\n if (typeof keywords === 'string') {\n splitKeywords(keywords).forEach(tag => tags.add(tag));\n } else {\n flattenStrings(keywords).forEach(tag => tags.add(tag));\n }\n return Array.from(tags);\n}\n\nfunction splitKeywords(value: string): string[] {\n return value\n .split(/[,|]/)\n .map(part => part.trim())\n .filter(Boolean);\n}\n\nfunction flattenStrings(value: unknown): string[] {\n if (!value) return [];\n if (typeof value === 'string') return [value.trim()].filter(Boolean);\n if (Array.isArray(value)) {\n return value\n .map(item => (typeof item === 'string' ? item.trim() : ''))\n .filter(Boolean);\n }\n return [];\n}\n\nfunction extractFirst(value: unknown): string | undefined {\n const arr = flattenStrings(value);\n return arr.length ? arr[0] : undefined;\n}\n\nfunction convertImage(value: SchemaOrgImage | undefined): string | undefined {\n if (!value) return undefined;\n\n if (typeof value === 'string') {\n return value;\n }\n\n if (Array.isArray(value)) {\n for (const item of value) {\n const url = typeof item === 'string' ? item : extractImageUrl(item);\n if (url) return url;\n }\n return undefined;\n }\n\n return extractImageUrl(value);\n}\n\nfunction extractImageUrl(value: unknown): string | undefined {\n if (!value || typeof value !== 'object') return undefined;\n const record = value as { url?: unknown; contentUrl?: unknown };\n const candidate =\n typeof record.url === 'string'\n ? record.url\n : typeof record.contentUrl === 'string'\n ? record.contentUrl\n : undefined;\n return candidate?.trim() || undefined;\n}\n\nfunction convertSource(recipe: SchemaOrgRecipe): Source | undefined {\n const author = extractEntityName(recipe.author);\n const publisher = extractEntityName(recipe.publisher);\n const url = (recipe.url || recipe.mainEntityOfPage)?.trim();\n\n const source: Source = {};\n if (author) source.author = author;\n if (publisher) source.name = publisher;\n if (url) source.url = url;\n\n return Object.keys(source).length ? source : undefined;\n}\n\nfunction extractEntityName(\n value:\n | SchemaOrgPersonOrOrganization\n | SchemaOrgPersonOrOrganization[]\n | string\n | string[]\n | undefined\n): string | undefined {\n if (!value) return undefined;\n\n if (typeof value === 'string') {\n const trimmed = value.trim();\n return trimmed || undefined;\n }\n\n if (Array.isArray(value)) {\n for (const entry of value) {\n const name = extractEntityName(entry as any);\n if (name) {\n return name;\n }\n }\n return undefined;\n }\n\n if (typeof value === 'object' && typeof value.name === 'string') {\n const trimmed = value.name.trim();\n return trimmed || undefined;\n }\n\n return undefined;\n}","import { IngredientItem, InstructionItem, Recipe, StructuredTime, Time } from '../types';\r\nimport { formatDuration } from '../parsers/duration';\r\nimport { formatYield } from './yield';\r\nimport { HowToSection, HowToStep, SchemaOrgRecipe } from '../types/schemaOrg';\r\n\r\ntype SchemaOrgInstruction = HowToStep | HowToSection;\r\n\r\nexport function convertBasicMetadata(recipe: Recipe): Partial<SchemaOrgRecipe> {\r\n return cleanOutput({\r\n '@context': 'https://schema.org',\r\n '@type': 'Recipe',\r\n name: recipe.name,\r\n description: recipe.description,\r\n image: recipe.image,\r\n url: recipe.source?.url,\r\n datePublished: recipe.dateAdded,\r\n dateModified: recipe.dateModified\r\n });\r\n}\r\n\r\nexport function convertIngredients(ingredients: IngredientItem[] = []): string[] {\r\n const result: string[] = [];\r\n\r\n ingredients.forEach(ingredient => {\r\n if (!ingredient) {\r\n return;\r\n }\r\n\r\n if (typeof ingredient === 'string') {\r\n const value = ingredient.trim();\r\n if (value) {\r\n result.push(value);\r\n }\r\n return;\r\n }\r\n\r\n if ('subsection' in ingredient) {\r\n ingredient.items.forEach(item => {\r\n if (!item) {\r\n return;\r\n }\r\n if (typeof item === 'string') {\r\n const value = item.trim();\r\n if (value) {\r\n result.push(value);\r\n }\r\n } else if (item.item) {\r\n const value = item.item.trim();\r\n if (value) {\r\n result.push(value);\r\n }\r\n }\r\n });\r\n return;\r\n }\r\n\r\n const value = ingredient.item?.trim();\r\n if (value) {\r\n result.push(value);\r\n }\r\n });\r\n\r\n return result;\r\n}\r\n\r\nexport function convertInstructions(\r\n instructions: InstructionItem[] = []\r\n): SchemaOrgInstruction[] {\r\n return instructions\r\n .map(entry => convertInstruction(entry))\r\n .filter((value): value is SchemaOrgInstruction => Boolean(value));\r\n}\r\n\r\nfunction convertInstruction(entry: InstructionItem): SchemaOrgInstruction | null {\r\n if (!entry) {\r\n return null;\r\n }\r\n\r\n if (typeof entry === 'string') {\r\n return createHowToStep(entry);\r\n }\r\n\r\n if ('subsection' in entry) {\r\n const steps = entry.items\r\n .map(item => (typeof item === 'string' ? createHowToStep(item) : createHowToStep(item.text)))\r\n .filter((step): step is HowToStep => Boolean(step));\r\n\r\n if (!steps.length) {\r\n return null;\r\n }\r\n\r\n return {\r\n '@type': 'HowToSection',\r\n name: entry.subsection,\r\n itemListElement: steps\r\n };\r\n }\r\n\r\n if ('text' in entry) {\r\n return createHowToStep(entry.text);\r\n }\r\n\r\n return createHowToStep(String(entry));\r\n}\r\n\r\nfunction createHowToStep(text?: string): HowToStep | null {\r\n if (!text) return null;\r\n const trimmed = text.trim();\r\n if (!trimmed) return null;\r\n return {\r\n '@type': 'HowToStep',\r\n text: trimmed\r\n };\r\n}\r\n\r\nexport function convertTime(time?: Time): Partial<SchemaOrgRecipe> {\r\n if (!time) {\r\n return {};\r\n }\r\n\r\n if (isStructuredTime(time)) {\r\n const result: Partial<SchemaOrgRecipe> = {};\r\n if (time.prep !== undefined) {\r\n result.prepTime = formatDuration(time.prep);\r\n }\r\n if (time.active !== undefined) {\r\n result.cookTime = formatDuration(time.active);\r\n }\r\n if (time.total !== undefined) {\r\n result.totalTime = formatDuration(time.total);\r\n }\r\n return result;\r\n }\r\n\r\n const result: Partial<SchemaOrgRecipe> = {};\r\n if (time.prepTime) {\r\n result.prepTime = time.prepTime;\r\n }\r\n if (time.cookTime) {\r\n result.cookTime = time.cookTime;\r\n }\r\n return result;\r\n}\r\n\r\nexport function convertYield(yld?: Recipe['yield']): string | undefined {\r\n if (!yld) {\r\n return undefined;\r\n }\r\n return formatYield(yld);\r\n}\r\n\r\nexport function convertAuthor(\r\n source?: Recipe['source']\r\n): Partial<SchemaOrgRecipe> {\r\n if (!source) {\r\n return {};\r\n }\r\n\r\n const result: Partial<SchemaOrgRecipe> = {};\r\n\r\n if (source.author) {\r\n result.author = {\r\n '@type': 'Person',\r\n name: source.author\r\n };\r\n }\r\n\r\n if (source.name) {\r\n result.publisher = {\r\n '@type': 'Organization',\r\n name: source.name\r\n };\r\n }\r\n\r\n if (source.url) {\r\n result.url = source.url;\r\n }\r\n\r\n return result;\r\n}\r\n\r\nexport function convertCategoryTags(\r\n category?: string,\r\n tags?: string[]\r\n): Partial<SchemaOrgRecipe> {\r\n const result: Partial<SchemaOrgRecipe> = {};\r\n\r\n if (category) {\r\n result.recipeCategory = category;\r\n }\r\n\r\n if (tags && tags.length > 0) {\r\n result.keywords = tags.filter(Boolean).join(', ');\r\n }\r\n\r\n return result;\r\n}\r\n\r\nexport function convertNutrition(\r\n nutrition?: Recipe['nutrition']\r\n): SchemaOrgRecipe['nutrition'] {\r\n if (!nutrition) {\r\n return undefined;\r\n }\r\n\r\n return {\r\n ...nutrition,\r\n '@type': 'NutritionInformation'\r\n };\r\n}\r\n\r\nexport function cleanOutput<T extends Record<string, unknown>>(obj: T): T {\r\n return Object.fromEntries(\r\n Object.entries(obj).filter(([, value]) => value !== undefined)\r\n ) as T;\r\n}\r\n\r\nexport function toSchemaOrg(recipe: Recipe): SchemaOrgRecipe {\r\n const base = convertBasicMetadata(recipe);\r\n const ingredients = convertIngredients(recipe.ingredients);\r\n const instructions = convertInstructions(recipe.instructions);\r\n const nutrition = convertNutrition(recipe.nutrition);\r\n\r\n return cleanOutput({\r\n ...base,\r\n recipeIngredient: ingredients.length ? ingredients : undefined,\r\n recipeInstructions: instructions.length ? instructions : undefined,\r\n recipeYield: convertYield(recipe.yield),\r\n ...convertTime(recipe.time),\r\n ...convertAuthor(recipe.source),\r\n ...convertCategoryTags(recipe.category, recipe.tags),\r\n nutrition\r\n }) as SchemaOrgRecipe;\r\n}\r\n\r\nfunction isStructuredTime(time: Time): time is StructuredTime {\r\n return (\r\n typeof (time as StructuredTime).prep !== 'undefined' ||\r\n typeof (time as StructuredTime).active !== 'undefined' ||\r\n typeof (time as StructuredTime).passive !== 'undefined' ||\r\n typeof (time as StructuredTime).total !== 'undefined'\r\n );\r\n}\r\n","import type { RequestInit } from 'node-fetch';\r\nimport type { FetchOptions } from './types';\r\n\r\nconst DEFAULT_USER_AGENTS = [\r\n 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',\r\n 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',\r\n 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:121.0) Gecko/20100101 Firefox/121.0'\r\n];\r\n\r\ntype FetchFn = typeof import('node-fetch')['default'];\r\n\r\nlet fetchImpl: Promise<FetchFn> | null = null;\r\n\r\nasync function ensureFetch(): Promise<FetchFn> {\r\n if (!fetchImpl) {\r\n fetchImpl = import('node-fetch').then(mod => mod.default as FetchFn);\r\n }\r\n return fetchImpl;\r\n}\r\n\r\nfunction chooseUserAgent(provided?: string): string {\r\n if (provided) return provided;\r\n const index = Math.floor(Math.random() * DEFAULT_USER_AGENTS.length);\r\n return DEFAULT_USER_AGENTS[index];\r\n}\r\n\r\nfunction isClientError(error: Error & { status?: number }): boolean {\r\n if (typeof error.status === 'number') {\r\n return error.status >= 400 && error.status < 500;\r\n }\r\n return error.message.includes('HTTP 4');\r\n}\r\n\r\nasync function wait(ms: number) {\r\n return new Promise(resolve => setTimeout(resolve, ms));\r\n}\r\n\r\nexport async function fetchPage(url: string, options: FetchOptions = {}): Promise<string> {\r\n const {\r\n timeout = 10_000,\r\n userAgent,\r\n maxRetries = 2\r\n } = options;\r\n\r\n let lastError: Error | null = null;\r\n\r\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\r\n const controller = new AbortController();\r\n const timeoutId = setTimeout(() => controller.abort(), timeout);\r\n\r\n try {\r\n const fetch = await ensureFetch();\r\n const headers = {\r\n 'User-Agent': chooseUserAgent(userAgent),\r\n Accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',\r\n 'Accept-Language': 'en-US,en;q=0.5'\r\n };\r\n\r\n const response = await fetch(url, {\r\n headers,\r\n signal: controller.signal,\r\n redirect: 'follow'\r\n } as RequestInit);\r\n\r\n clearTimeout(timeoutId);\r\n\r\n if (!response.ok) {\r\n const error: Error & { status?: number } = new Error(\r\n `HTTP ${response.status}: ${response.statusText}`\r\n );\r\n error.status = response.status;\r\n throw error;\r\n }\r\n\r\n return await response.text();\r\n } catch (err) {\r\n clearTimeout(timeoutId);\r\n\r\n lastError = err instanceof Error ? err : new Error(String(err));\r\n\r\n if (isClientError(lastError)) {\r\n throw lastError;\r\n }\r\n\r\n if (attempt < maxRetries) {\r\n await wait(1000 * (attempt + 1));\r\n continue;\r\n }\r\n }\r\n }\r\n\r\n throw lastError ?? new Error('Failed to fetch page');\r\n}\r\n\r\nexport { FetchOptions };\r\n","import type { SchemaOrgRecipe } from '../types';\n\nconst RECIPE_TYPES = new Set([\n 'recipe',\n 'https://schema.org/recipe',\n 'http://schema.org/recipe'\n]);\n\nexport function isRecipeNode(value: unknown): value is SchemaOrgRecipe {\n if (!value || typeof value !== 'object') {\n return false;\n }\n\n const type = (value as Record<string, unknown>)['@type'];\n\n if (typeof type === 'string') {\n return RECIPE_TYPES.has(type.toLowerCase());\n }\n\n if (Array.isArray(type)) {\n return type.some(\n entry => typeof entry === 'string' && RECIPE_TYPES.has(entry.toLowerCase())\n );\n }\n\n return false;\n}\n\nexport function safeJsonParse<T = unknown>(content: string): T | null {\n try {\n return JSON.parse(content) as T;\n } catch {\n return null;\n }\n}\n\nexport function normalizeText(value: string | undefined | null): string | undefined {\n if (!value) return undefined;\n const trimmed = value.replace(/\\s+/g, ' ').trim();\n return trimmed || undefined;\n}\n","import { load } from 'cheerio';\nimport type { SchemaOrgRecipe } from '../types';\nimport { isRecipeNode, safeJsonParse } from './utils';\n\ntype JsonLdPayload = Record<string, unknown> | Array<Record<string, unknown>>;\n\nexport function extractJsonLd(html: string): SchemaOrgRecipe | null {\n const $ = load(html);\n const scripts = $('script[type=\"application/ld+json\"]');\n const candidates: SchemaOrgRecipe[] = [];\n\n scripts.each((_, element) => {\n const content = $(element).html();\n if (!content) return;\n\n const parsed = safeJsonParse<JsonLdPayload>(content);\n if (!parsed) return;\n\n collectCandidates(parsed, candidates);\n });\n\n return candidates[0] ?? null;\n}\n\nfunction collectCandidates(payload: unknown, bucket: SchemaOrgRecipe[]) {\n if (!payload) return;\n\n if (Array.isArray(payload)) {\n payload.forEach(entry => collectCandidates(entry, bucket));\n return;\n }\n\n if (typeof payload !== 'object') {\n return;\n }\n\n if (isRecipeNode(payload)) {\n bucket.push(payload);\n return;\n }\n\n const graph = (payload as Record<string, unknown>)['@graph'];\n if (Array.isArray(graph)) {\n graph.forEach(entry => collectCandidates(entry, bucket));\n }\n}\n","import { load, type CheerioAPI, type Cheerio } from 'cheerio';\r\nimport type { SchemaOrgRecipe } from '../types';\r\nimport { normalizeText } from './utils';\r\n\r\nconst SIMPLE_PROPS = [\r\n 'name',\r\n 'description',\r\n 'image',\r\n 'recipeYield',\r\n 'prepTime',\r\n 'cookTime',\r\n 'totalTime'\r\n] as const;\r\n\r\nexport function extractMicrodata(html: string): SchemaOrgRecipe | null {\r\n const $ = load(html);\r\n const recipeEl = $('[itemscope][itemtype*=\"schema.org/Recipe\"]').first();\r\n\r\n if (!recipeEl.length) {\r\n return null;\r\n }\r\n\r\n const recipe: SchemaOrgRecipe = {\r\n '@type': 'Recipe'\r\n };\r\n\r\n SIMPLE_PROPS.forEach(prop => {\r\n const value = findPropertyValue($, recipeEl, prop);\r\n if (value) {\r\n recipe[prop] = value;\r\n }\r\n });\r\n\r\n const ingredients: string[] = [];\r\n recipeEl.find('[itemprop=\"recipeIngredient\"]').each((_, el) => {\r\n const text = normalizeText($(el).attr('content') || $(el).text());\r\n if (text) ingredients.push(text);\r\n });\r\n\r\n if (ingredients.length) {\r\n recipe.recipeIngredient = ingredients;\r\n }\r\n\r\n const instructions: string[] = [];\r\n recipeEl.find('[itemprop=\"recipeInstructions\"]').each((_, el) => {\r\n const text =\r\n normalizeText($(el).attr('content')) ||\r\n normalizeText($(el).find('[itemprop=\"text\"]').first().text()) ||\r\n normalizeText($(el).text());\r\n if (text) instructions.push(text);\r\n });\r\n\r\n if (instructions.length) {\r\n recipe.recipeInstructions = instructions;\r\n }\r\n\r\n if (recipe.name || ingredients.length) {\r\n return recipe;\r\n }\r\n\r\n return null;\r\n}\r\n\r\nfunction findPropertyValue($: CheerioAPI, context: Cheerio<any>, prop: string): string | undefined {\r\n const node = context.find(`[itemprop=\"${prop}\"]`).first();\r\n if (!node.length) return undefined;\r\n\r\n return (\r\n normalizeText(node.attr('content')) ||\r\n normalizeText(node.attr('href')) ||\r\n normalizeText(node.attr('src')) ||\r\n normalizeText(node.text())\r\n );\r\n}\r\n","import type { ExtractionResult } from '../types';\nimport { extractJsonLd } from './jsonld';\nimport { extractMicrodata } from './microdata';\n\nexport function extractRecipe(html: string): ExtractionResult {\n const jsonLdRecipe = extractJsonLd(html);\n if (jsonLdRecipe) {\n return { recipe: jsonLdRecipe, source: 'jsonld' };\n }\n\n const microdataRecipe = extractMicrodata(html);\n if (microdataRecipe) {\n return { recipe: microdataRecipe, source: 'microdata' };\n }\n\n return { recipe: null, source: null };\n}\n","import { fromSchemaOrg } from '../fromSchemaOrg';\nimport type { Recipe } from '../types';\nimport { fetchPage } from './fetch';\nimport { extractRecipe } from './extractors';\nimport type { ScrapeRecipeOptions } from './types';\n\nexport async function scrapeRecipe(url: string, options: ScrapeRecipeOptions = {}): Promise<Recipe> {\n const html = await fetchPage(url, options);\n const { recipe } = extractRecipe(html);\n\n if (!recipe) {\n throw new Error('No Schema.org recipe data found in page');\n }\n\n const soustackRecipe = fromSchemaOrg(recipe);\n if (!soustackRecipe) {\n throw new Error('Schema.org data did not include a valid recipe');\n }\n\n return soustackRecipe;\n}\n","import { ParsedYield } from '../types';\r\n\r\nconst RANGE_PATTERN = /^(\\d+)(?:\\s*(?:[-–—]|to)\\s*)(\\d+)\\s+(.+)$/i;\r\nconst MAKES_PREFIX = /^(makes?|yields?)\\s*:?\\s*(.+)$/i;\r\nconst APPROX_PREFIX = /^(about|around|approximately|approx\\.?|roughly)\\s+/i;\r\nconst SERVING_UNITS = ['servings', 'serving', 'portions', 'portion', 'people', 'persons'];\r\nconst DEFAULT_DOZEN_UNIT = 'cookies';\r\n\r\nconst NUMBER_WORDS: Record<string, number> = {\r\n a: 1,\r\n an: 1,\r\n one: 1,\r\n two: 2,\r\n three: 3,\r\n four: 4,\r\n five: 5,\r\n six: 6,\r\n seven: 7,\r\n eight: 8,\r\n nine: 9,\r\n ten: 10,\r\n eleven: 11,\r\n twelve: 12\r\n};\r\n\r\nexport function normalizeYield(text: string): string {\r\n if (!text || typeof text !== 'string') return '';\r\n return text\r\n .normalize('NFKC')\r\n .replace(/\\u00A0/g, ' ')\r\n .replace(/[–—−]/g, '-')\r\n .trim()\r\n .replace(/\\s+/g, ' ');\r\n}\r\n\r\nexport function parseYield(text: string): ParsedYield | null {\r\n const normalized = normalizeYield(text);\r\n if (!normalized) return null;\r\n\r\n const { main, paren } = extractParenthetical(normalized);\r\n const core = parseYieldCore(main, normalized);\r\n if (!core) return null;\r\n\r\n const servingsFromParen = paren ? extractServingsFromParen(paren) : null;\r\n if (servingsFromParen !== null) {\r\n core.servings = servingsFromParen;\r\n core.description = normalized;\r\n }\r\n\r\n if (core.servings === undefined) {\r\n const inferred = inferServings(core.amount, core.unit);\r\n if (inferred !== undefined) {\r\n core.servings = inferred;\r\n }\r\n }\r\n\r\n return core;\r\n}\r\n\r\nexport function formatYield(value: ParsedYield): string {\r\n if (value.description) {\r\n return value.description;\r\n }\r\n\r\n if (value.servings && value.unit === 'servings') {\r\n return `Serves ${value.amount}`;\r\n }\r\n\r\n let result = `${value.amount} ${value.unit}`.trim();\r\n if (value.servings && value.unit !== 'servings') {\r\n result += ` (${value.servings} servings)`;\r\n }\r\n\r\n return result;\r\n}\r\n\r\nfunction parseYieldCore(text: string, original: string): ParsedYield | null {\r\n return (\r\n parseServesPattern(text, original) ??\r\n parseMakesPattern(text, original) ??\r\n parseRangePattern(text, original) ??\r\n parseNumberUnitPattern(text, original) ??\r\n parsePlainNumberPattern(text)\r\n );\r\n}\r\n\r\nfunction parseServesPattern(text: string, original: string): ParsedYield | null {\r\n const patterns = [\r\n /^serves?\\s*[:\\-]?\\s*(\\d+)(?:\\s*(?:[-–—]|to)\\s*(\\d+))?/i,\r\n /^servings?\\s*[:\\-]?\\s*(\\d+)(?:\\s*(?:[-–—]|to)\\s*(\\d+))?/i,\r\n /^serving\\s*[:\\-]?\\s*(\\d+)(?:\\s*(?:[-–—]|to)\\s*(\\d+))?/i,\r\n /^makes?\\s*[:\\-]?\\s*(\\d+)(?:\\s*(?:[-–—]|to)\\s*(\\d+))?\\s+servings?$/i,\r\n /^(\\d+)\\s+servings?$/i\r\n ];\r\n\r\n for (const regex of patterns) {\r\n const match = text.match(regex);\r\n if (!match) continue;\r\n const amount = parseInt(match[1], 10);\r\n if (Number.isNaN(amount)) continue;\r\n const result: ParsedYield = {\r\n amount,\r\n unit: 'servings',\r\n servings: amount\r\n };\r\n if (match[2]) {\r\n result.description = original;\r\n }\r\n return result;\r\n }\r\n\r\n return null;\r\n}\r\n\r\nfunction parseMakesPattern(text: string, original: string): ParsedYield | null {\r\n const match = text.match(MAKES_PREFIX);\r\n if (!match) return null;\r\n const remainder = match[2].trim();\r\n if (!remainder) return null;\r\n\r\n const servingsMatch = remainder.match(/^(\\d+)(?:\\s*(?:[-–—]|to)\\s*(\\d+))?\\s+servings?$/i);\r\n if (servingsMatch) {\r\n const amount = parseInt(servingsMatch[1], 10);\r\n const result: ParsedYield = {\r\n amount,\r\n unit: 'servings',\r\n servings: amount\r\n };\r\n if (servingsMatch[2]) {\r\n result.description = original;\r\n }\r\n return result;\r\n }\r\n\r\n return (\r\n parseRangePattern(remainder, original) ??\r\n parseNumberUnitPattern(remainder, original) ??\r\n parsePlainNumberPattern(remainder)\r\n );\r\n}\r\n\r\nfunction parseRangePattern(text: string, descriptionSource: string): ParsedYield | null {\r\n const match = text.match(RANGE_PATTERN);\r\n if (!match) return null;\r\n const amount = parseInt(match[1], 10);\r\n const unit = cleanupUnit(match[3]);\r\n if (!unit) return null;\r\n const result: ParsedYield = {\r\n amount,\r\n unit,\r\n description: descriptionSource\r\n };\r\n return result;\r\n}\r\n\r\nfunction parseNumberUnitPattern(text: string, descriptionSource: string): ParsedYield | null {\r\n if (!text) return null;\r\n const { value, approximate } = stripApproximation(text);\r\n if (!value) return null;\r\n\r\n const dozenResult = handleDozen(value);\r\n if (dozenResult) {\r\n const unit = cleanupUnit(dozenResult.remainder || DEFAULT_DOZEN_UNIT);\r\n const parsed: ParsedYield = {\r\n amount: dozenResult.amount,\r\n unit\r\n };\r\n if (approximate) {\r\n parsed.description = descriptionSource;\r\n }\r\n return parsed;\r\n }\r\n\r\n const numericMatch = value.match(/^(\\d+(?:\\.\\d+)?)\\s+(.+)$/);\r\n if (numericMatch) {\r\n const amount = parseFloat(numericMatch[1]);\r\n if (!Number.isNaN(amount)) {\r\n const unit = cleanupUnit(numericMatch[2]);\r\n if (unit) {\r\n const parsed: ParsedYield = { amount, unit };\r\n if (approximate) {\r\n parsed.description = descriptionSource;\r\n }\r\n return parsed;\r\n }\r\n }\r\n }\r\n\r\n const wordMatch = value.match(/^([a-zA-Z]+)\\s+(.+)$/);\r\n if (wordMatch) {\r\n const amount = wordToNumber(wordMatch[1]);\r\n if (amount !== null) {\r\n const unit = cleanupUnit(wordMatch[2]);\r\n if (unit) {\r\n const parsed: ParsedYield = { amount, unit };\r\n if (approximate) {\r\n parsed.description = descriptionSource;\r\n }\r\n return parsed;\r\n }\r\n }\r\n }\r\n\r\n return null;\r\n}\r\n\r\nfunction parsePlainNumberPattern(text: string): ParsedYield | null {\r\n const match = text.match(/^(\\d+)$/);\r\n if (!match) return null;\r\n const amount = parseInt(match[1], 10);\r\n if (Number.isNaN(amount)) return null;\r\n return {\r\n amount,\r\n unit: 'servings',\r\n servings: amount\r\n };\r\n}\r\n\r\nfunction stripApproximation(value: string): { value: string; approximate: boolean } {\r\n const match = value.match(APPROX_PREFIX);\r\n if (!match) {\r\n return { value: value.trim(), approximate: false };\r\n }\r\n const stripped = value.slice(match[0].length).trim();\r\n return { value: stripped, approximate: true };\r\n}\r\n\r\nfunction handleDozen(text: string): { amount: number; remainder: string } | null {\r\n const match = text.match(\r\n /^((?:\\d+(?:\\.\\d+)?)|(?:one|two|three|four|five|six|seven|eight|nine|ten|eleven|twelve|a|an|half))\\s+dozens?\\b(.*)$/i\r\n );\r\n if (!match) return null;\r\n const token = match[1].toLowerCase();\r\n let multiplier: number | null = null;\r\n if (token === 'half') {\r\n multiplier = 0.5;\r\n } else if (!Number.isNaN(Number(token))) {\r\n multiplier = parseFloat(token);\r\n } else {\r\n multiplier = wordToNumber(token);\r\n }\r\n if (multiplier === null) return null;\r\n const amount = multiplier * 12;\r\n return {\r\n amount,\r\n remainder: match[2].trim()\r\n };\r\n}\r\n\r\nfunction cleanupUnit(value: string): string {\r\n let unit = value.trim();\r\n unit = unit.replace(/^[,.-]+/, '').trim();\r\n unit = unit.replace(/[.,]+$/, '').trim();\r\n unit = unit.replace(/^of\\s+/i, '').trim();\r\n return unit;\r\n}\r\n\r\nfunction extractParenthetical(text: string): { main: string; paren: string | null } {\r\n const match = text.match(/^(.+?)\\s*\\(([^)]+)\\)\\s*$/);\r\n if (!match) {\r\n return { main: text, paren: null };\r\n }\r\n return {\r\n main: match[1].trim(),\r\n paren: match[2].trim()\r\n };\r\n}\r\n\r\nfunction extractServingsFromParen(text: string): number | null {\r\n const match = text.match(/(\\d+)/);\r\n if (!match) return null;\r\n const value = parseInt(match[1], 10);\r\n return Number.isNaN(value) ? null : value;\r\n}\r\n\r\nfunction inferServings(amount: number, unit: string): number | undefined {\r\n if (SERVING_UNITS.includes(unit.toLowerCase())) {\r\n return amount;\r\n }\r\n return undefined;\r\n}\r\n\r\nfunction wordToNumber(word: string): number | null {\r\n const normalized = word.toLowerCase();\r\n if (NUMBER_WORDS.hasOwnProperty(normalized)) {\r\n return NUMBER_WORDS[normalized];\r\n }\r\n return null;\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/parser.ts","../src/schema.json","../src/validator.ts","../src/parsers/ingredient.ts","../src/converters/ingredient.ts","../src/converters/yield.ts","../src/parsers/duration.ts","../src/fromSchemaOrg.ts","../src/converters/toSchemaOrg.ts","../src/scraper/fetch.ts","../src/scraper/extractors/utils.ts","../src/scraper/extractors/jsonld.ts","../src/scraper/extractors/microdata.ts","../src/scraper/extractors/browser.ts","../src/scraper/extractors/index.ts","../src/scraper/index.ts","../src/parsers/yield.ts"],"names":["Ajv","addFormats","parseIngredientLine","convertIngredients","value","convertInstructions","convertTime","result","isBrowser","load","SIMPLE_PROPS","collectCandidates","findPropertyValue","NUMBER_WORDS","parseYield","formatYield"],"mappings":"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","file":"index.js","sourcesContent":["import { \r\n Recipe, \r\n Ingredient, \r\n IngredientItem, \r\n Instruction, \r\n InstructionItem,\r\n Scaling \r\n} from './types';\r\n\r\n// --- Output Types ---\r\n\r\n/**\r\n * A \"Computed Recipe\" is the result of running the parser.\r\n * It is flat, strict, and ready for the UI to render.\r\n */\r\nexport interface ComputedRecipe {\r\n metadata: {\r\n targetYield: number;\r\n baseYield: number;\r\n multiplier: number;\r\n };\r\n ingredients: ComputedIngredient[];\r\n instructions: ComputedInstruction[];\r\n timing: {\r\n active: number;\r\n passive: number;\r\n total: number;\r\n };\r\n}\r\n\r\nexport interface ComputedIngredient {\r\n id: string;\r\n name: string;\r\n amount: number;\r\n unit: string | null;\r\n text: string; // \"500g Bread Flour\"\r\n notes?: string;\r\n}\r\n\r\nexport interface ComputedInstruction {\r\n id: string;\r\n text: string;\r\n durationMinutes: number;\r\n type: 'active' | 'passive';\r\n}\r\n\r\n// --- Main Logic ---\r\n\r\nexport function scaleRecipe(recipe: Recipe, targetYieldAmount: number): ComputedRecipe {\r\n // 1. Calculate Multiplier\r\n const baseYield = recipe.yield?.amount || 1;\r\n const multiplier = targetYieldAmount / baseYield;\r\n\r\n // 2. Flatten Ingredients (handle subsections)\r\n const flatIngredients = flattenIngredients(recipe.ingredients);\r\n\r\n // 3. Two-Pass Ingredient Scaling\r\n // Pass 1: Scale Independent items (Linear, Fixed, Discrete)\r\n // Pass 2: Scale Dependent items (Baker's %, Proportional)\r\n const scaledIngredientsMap = new Map<string, ComputedIngredient>();\r\n\r\n // --- PASS 1 ---\r\n flatIngredients.forEach(ing => {\r\n if (isIndependent(ing.scaling?.type)) {\r\n const computed = calculateIngredient(ing, multiplier, 0); // Reference unused here\r\n scaledIngredientsMap.set(ing.id || ing.item, computed);\r\n }\r\n });\r\n\r\n // --- PASS 2 ---\r\n flatIngredients.forEach(ing => {\r\n if (!isIndependent(ing.scaling?.type)) {\r\n // Find the reference ingredient's NEW weight\r\n let referenceValue = 0;\r\n if (ing.scaling?.type === 'bakers_percentage' && ing.scaling.referenceId) {\r\n const refIng = scaledIngredientsMap.get(ing.scaling.referenceId);\r\n if (refIng) referenceValue = refIng.amount;\r\n } else {\r\n // Fallback for Proportional: Use generic multiplier if no ref logic defined\r\n referenceValue = multiplier; \r\n }\r\n \r\n const computed = calculateIngredient(ing, multiplier, referenceValue);\r\n scaledIngredientsMap.set(ing.id || ing.item, computed);\r\n }\r\n });\r\n\r\n // 4. Scale Instructions (Timing)\r\n const flatInstructions = flattenInstructions(recipe.instructions);\r\n const computedInstructions = flatInstructions.map(inst => \r\n calculateInstruction(inst, multiplier)\r\n );\r\n\r\n // 5. Aggregate Time\r\n const timing = computedInstructions.reduce(\r\n (acc, step) => {\r\n if (step.type === 'active') acc.active += step.durationMinutes;\r\n else acc.passive += step.durationMinutes;\r\n acc.total += step.durationMinutes;\r\n return acc;\r\n },\r\n { active: 0, passive: 0, total: 0 }\r\n );\r\n\r\n return {\r\n metadata: {\r\n targetYield: targetYieldAmount,\r\n baseYield,\r\n multiplier\r\n },\r\n ingredients: Array.from(scaledIngredientsMap.values()),\r\n instructions: computedInstructions,\r\n timing\r\n };\r\n}\r\n\r\n// --- Helper Functions ---\r\n\r\nfunction isIndependent(type?: string): boolean {\r\n return !type || type === 'linear' || type === 'fixed' || type === 'discrete';\r\n}\r\n\r\nfunction calculateIngredient(\r\n ing: Ingredient, \r\n multiplier: number, \r\n referenceValue: number\r\n): ComputedIngredient {\r\n const baseAmount = ing.quantity?.amount || 0;\r\n const type = ing.scaling?.type || 'linear';\r\n let newAmount = baseAmount;\r\n\r\n switch (type) {\r\n case 'linear':\r\n newAmount = baseAmount * multiplier;\r\n break;\r\n \r\n case 'fixed':\r\n newAmount = baseAmount;\r\n break;\r\n\r\n case 'discrete':\r\n // e.g., Eggs. Round to nearest step (default 1)\r\n const raw = baseAmount * multiplier;\r\n const step = (ing.scaling as any).roundTo || 1; \r\n newAmount = Math.round(raw / step) * step;\r\n // Handle min/max constraints\r\n break;\r\n\r\n case 'bakers_percentage':\r\n // Formula: NewAmount = ReferenceNewAmount * OriginalRatio\r\n // If explicit factor provided (e.g. 0.02 for 2% salt):\r\n // NewAmount = ReferenceNewAmount * Factor\r\n \r\n // Calculate original ratio if not provided? \r\n // Ideally, factor is implicit: (OldAmount / OldRefAmount). \r\n // But for simplicity here, we assume the relationship holds true to the Ref.\r\n \r\n // If we used the Reference Value from Pass 1 (e.g., 1000g flour),\r\n // We need the *Original* Ratio.\r\n // NOTE: In a real app, you calculate the original ratio from the unscaled recipe first.\r\n // For this snippet, let's assume 'factor' exists or we derive it.\r\n \r\n // Simpler approach for v0.1: Re-calculate the ratio dynamically\r\n // But we passed in 'referenceValue' (The NEW amount of flour).\r\n // We need the OLD amount of flour to get the ratio.\r\n // *Simplification*: Just treat it like linear scaling relative to the ref? \r\n // Actually, Baker's % is linear to the flour.\r\n // Ratio = BaseAmount / BaseRefAmount (need lookup).\r\n // Let's rely on standard scaling: If flour doubled, salt doubles.\r\n // Baker's % is mostly useful if you change the RATIO (e.g., \"Make 75% hydration dough\").\r\n // If we are just scaling yield, Baker's % behaves exactly like Linear.\r\n \r\n newAmount = baseAmount * multiplier; \r\n break;\r\n }\r\n\r\n // Apply formatted text\r\n const unit = ing.quantity?.unit || '';\r\n // Extract ingredient name: use ing.name if available, otherwise strip quantity from ing.item\r\n const ingredientName = ing.name || extractNameFromItem(ing.item);\r\n const text = `${parseFloat(newAmount.toFixed(2))}${unit ? ' ' + unit : ''} ${ingredientName}`;\r\n\r\n return {\r\n id: ing.id || ing.item,\r\n name: ingredientName,\r\n amount: newAmount,\r\n unit: ing.quantity?.unit || null,\r\n text,\r\n notes: ing.notes\r\n };\r\n}\r\n\r\n/**\r\n * Extracts the ingredient name from an item string by removing the leading quantity.\r\n * Example: \"900g Bread Flour\" -> \"Bread Flour\"\r\n */\r\nfunction extractNameFromItem(item: string): string {\r\n // Match pattern: optional number, optional decimal, optional unit, then the name\r\n // Examples: \"900g Bread Flour\", \"2 cups flour\", \"100g Whole Wheat Flour\"\r\n const match = item.match(/^\\s*\\d+(?:\\.\\d+)?\\s*\\w*\\s*(.+)$/);\r\n return match ? match[1].trim() : item;\r\n}\r\n\r\nfunction calculateInstruction(inst: Instruction, multiplier: number): ComputedInstruction {\r\n const baseDuration = inst.timing?.duration || 0;\r\n const scalingType = inst.timing?.scaling || 'fixed'; // Default steps to fixed (baking time doesn't usually double)\r\n let newDuration = baseDuration;\r\n\r\n if (scalingType === 'linear') {\r\n newDuration = baseDuration * multiplier;\r\n } else if (scalingType === 'sqrt') {\r\n // Physics approximation for heating larger volumes\r\n newDuration = baseDuration * Math.sqrt(multiplier);\r\n }\r\n\r\n return {\r\n id: inst.id || 'step',\r\n text: inst.text,\r\n durationMinutes: Math.ceil(newDuration),\r\n type: inst.timing?.type || 'active'\r\n };\r\n}\r\n\r\n// --- Flattening Helpers ---\r\n\r\nfunction flattenIngredients(items: IngredientItem[]): Ingredient[] {\r\n const result: Ingredient[] = [];\r\n items.forEach(item => {\r\n if (typeof item === 'string') {\r\n // Basic string support (no scaling possible)\r\n result.push({ item, quantity: { amount: 0, unit: null }, scaling: { type: 'fixed' } });\r\n } else if ('subsection' in item) {\r\n result.push(...flattenIngredients(item.items));\r\n } else {\r\n result.push(item);\r\n }\r\n });\r\n return result;\r\n}\r\n\r\nfunction flattenInstructions(items: InstructionItem[]): Instruction[] {\r\n const result: Instruction[] = [];\r\n items.forEach(item => {\r\n if (typeof item === 'string') {\r\n result.push({ text: item, timing: { duration: 0, type: 'active' } as any });\r\n } else if ('subsection' in item) {\r\n result.push(...flattenInstructions(item.items));\r\n } else {\r\n result.push(item);\r\n }\r\n });\r\n return result;\r\n}","{\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"http://soustack.org/schema/v0.1\",\n \"title\": \"Soustack Recipe Schema v0.1\",\n \"description\": \"A portable, scalable, interoperable recipe format.\",\n \"type\": \"object\",\n \"required\": [\"name\", \"ingredients\", \"instructions\"],\n \"properties\": {\n \"id\": {\n \"type\": \"string\",\n \"description\": \"Unique identifier (slug or UUID)\"\n },\n \"name\": {\n \"type\": \"string\",\n \"description\": \"The title of the recipe\"\n },\n \"version\": {\n \"type\": \"string\",\n \"pattern\": \"^\\\\d+\\\\.\\\\d+\\\\.\\\\d+$\",\n \"description\": \"Semantic versioning (e.g., 1.0.0)\"\n },\n \"description\": {\n \"type\": \"string\"\n },\n \"category\": {\n \"type\": \"string\",\n \"examples\": [\"Main Course\", \"Dessert\"]\n },\n \"tags\": {\n \"type\": \"array\",\n \"items\": { \"type\": \"string\" }\n },\n \"image\": {\n \"type\": \"string\",\n \"format\": \"uri\"\n },\n \"dateAdded\": {\n \"type\": \"string\",\n \"format\": \"date-time\"\n },\n \"source\": {\n \"type\": \"object\",\n \"properties\": {\n \"author\": { \"type\": \"string\" },\n \"url\": { \"type\": \"string\", \"format\": \"uri\" },\n \"name\": { \"type\": \"string\" },\n \"adapted\": { \"type\": \"boolean\" }\n }\n },\n \"yield\": {\n \"$ref\": \"#/definitions/yield\"\n },\n \"time\": {\n \"$ref\": \"#/definitions/time\"\n },\n \"equipment\": {\n \"type\": \"array\",\n \"items\": { \"$ref\": \"#/definitions/equipment\" }\n },\n \"ingredients\": {\n \"type\": \"array\",\n \"items\": {\n \"anyOf\": [\n { \"type\": \"string\" },\n { \"$ref\": \"#/definitions/ingredient\" },\n { \"$ref\": \"#/definitions/ingredientSubsection\" }\n ]\n }\n },\n \"instructions\": {\n \"type\": \"array\",\n \"items\": {\n \"anyOf\": [\n { \"type\": \"string\" },\n { \"$ref\": \"#/definitions/instruction\" },\n { \"$ref\": \"#/definitions/instructionSubsection\" }\n ]\n }\n },\n \"storage\": {\n \"$ref\": \"#/definitions/storage\"\n },\n \"substitutions\": {\n \"type\": \"array\",\n \"items\": { \"$ref\": \"#/definitions/substitution\" }\n }\n },\n \"definitions\": {\n \"yield\": {\n \"type\": \"object\",\n \"required\": [\"amount\", \"unit\"],\n \"properties\": {\n \"amount\": { \"type\": \"number\" },\n \"unit\": { \"type\": \"string\" },\n \"servings\": { \"type\": \"number\" },\n \"description\": { \"type\": \"string\" }\n }\n },\n \"time\": {\n \"oneOf\": [\n {\n \"type\": \"object\",\n \"properties\": {\n \"prep\": { \"type\": \"number\" },\n \"active\": { \"type\": \"number\" },\n \"passive\": { \"type\": \"number\" },\n \"total\": { \"type\": \"number\" }\n }\n },\n {\n \"type\": \"object\",\n \"properties\": {\n \"prepTime\": { \"type\": \"string\" },\n \"cookTime\": { \"type\": \"string\" }\n }\n }\n ]\n },\n \"quantity\": {\n \"type\": \"object\",\n \"required\": [\"amount\"],\n \"properties\": {\n \"amount\": { \"type\": \"number\" },\n \"unit\": { \"type\": [\"string\", \"null\"] }\n }\n },\n \"scaling\": {\n \"type\": \"object\",\n \"required\": [\"type\"],\n \"properties\": {\n \"type\": {\n \"type\": \"string\",\n \"enum\": [\"linear\", \"discrete\", \"proportional\", \"fixed\", \"bakers_percentage\"]\n },\n \"factor\": { \"type\": \"number\" },\n \"referenceId\": { \"type\": \"string\" },\n \"roundTo\": { \"type\": \"number\" },\n \"min\": { \"type\": \"number\" },\n \"max\": { \"type\": \"number\" }\n },\n \"if\": {\n \"properties\": { \"type\": { \"const\": \"bakers_percentage\" } }\n },\n \"then\": {\n \"required\": [\"referenceId\"]\n }\n },\n \"ingredient\": {\n \"type\": \"object\",\n \"required\": [\"item\"],\n \"properties\": {\n \"id\": { \"type\": \"string\" },\n \"item\": { \"type\": \"string\" },\n \"quantity\": { \"$ref\": \"#/definitions/quantity\" },\n \"name\": { \"type\": \"string\" },\n \"aisle\": { \"type\": \"string\" },\n \"prep\": { \"type\": \"string\" },\n \"prepAction\": { \"type\": \"string\" },\n \"prepTime\": { \"type\": \"number\" },\n \"destination\": { \"type\": \"string\" },\n \"scaling\": { \"$ref\": \"#/definitions/scaling\" },\n \"critical\": { \"type\": \"boolean\" },\n \"optional\": { \"type\": \"boolean\" },\n \"notes\": { \"type\": \"string\" }\n }\n },\n \"ingredientSubsection\": {\n \"type\": \"object\",\n \"required\": [\"subsection\", \"items\"],\n \"properties\": {\n \"subsection\": { \"type\": \"string\" },\n \"items\": {\n \"type\": \"array\",\n \"items\": { \"$ref\": \"#/definitions/ingredient\" }\n }\n }\n },\n \"equipment\": {\n \"type\": \"object\",\n \"required\": [\"name\"],\n \"properties\": {\n \"id\": { \"type\": \"string\" },\n \"name\": { \"type\": \"string\" },\n \"required\": { \"type\": \"boolean\" },\n \"label\": { \"type\": \"string\" },\n \"capacity\": { \"$ref\": \"#/definitions/quantity\" },\n \"scalingLimit\": { \"type\": \"number\" },\n \"alternatives\": {\n \"type\": \"array\",\n \"items\": { \"type\": \"string\" }\n }\n }\n },\n \"instruction\": {\n \"type\": \"object\",\n \"required\": [\"text\"],\n \"properties\": {\n \"id\": { \"type\": \"string\" },\n \"text\": { \"type\": \"string\" },\n \"destination\": { \"type\": \"string\" },\n \"dependsOn\": {\n \"type\": \"array\",\n \"items\": { \"type\": \"string\" }\n },\n \"inputs\": {\n \"type\": \"array\",\n \"items\": { \"type\": \"string\" }\n },\n \"timing\": {\n \"type\": \"object\",\n \"required\": [\"duration\", \"type\"],\n \"properties\": {\n \"duration\": { \"type\": \"number\" },\n \"type\": { \"type\": \"string\", \"enum\": [\"active\", \"passive\"] },\n \"scaling\": { \"type\": \"string\", \"enum\": [\"linear\", \"fixed\", \"sqrt\"] }\n }\n }\n }\n },\n \"instructionSubsection\": {\n \"type\": \"object\",\n \"required\": [\"subsection\", \"items\"],\n \"properties\": {\n \"subsection\": { \"type\": \"string\" },\n \"items\": {\n \"type\": \"array\",\n \"items\": {\n \"anyOf\": [\n { \"type\": \"string\" },\n { \"$ref\": \"#/definitions/instruction\" }\n ]\n }\n }\n }\n },\n \"storage\": {\n \"type\": \"object\",\n \"properties\": {\n \"roomTemp\": { \"$ref\": \"#/definitions/storageMethod\" },\n \"refrigerated\": { \"$ref\": \"#/definitions/storageMethod\" },\n \"frozen\": {\n \"allOf\": [\n { \"$ref\": \"#/definitions/storageMethod\" },\n {\n \"type\": \"object\",\n \"properties\": { \"thawing\": { \"type\": \"string\" } }\n }\n ]\n },\n \"reheating\": { \"type\": \"string\" },\n \"makeAhead\": {\n \"type\": \"array\",\n \"items\": {\n \"allOf\": [\n { \"$ref\": \"#/definitions/storageMethod\" },\n {\n \"type\": \"object\",\n \"required\": [\"component\", \"storage\"],\n \"properties\": {\n \"component\": { \"type\": \"string\" },\n \"storage\": { \"type\": \"string\", \"enum\": [\"roomTemp\", \"refrigerated\", \"frozen\"] }\n }\n }\n ]\n }\n }\n }\n },\n \"storageMethod\": {\n \"type\": \"object\",\n \"required\": [\"duration\"],\n \"properties\": {\n \"duration\": { \"type\": \"string\", \"pattern\": \"^P\" },\n \"method\": { \"type\": \"string\" },\n \"notes\": { \"type\": \"string\" }\n }\n },\n \"substitution\": {\n \"type\": \"object\",\n \"required\": [\"ingredient\"],\n \"properties\": {\n \"ingredient\": { \"type\": \"string\" },\n \"critical\": { \"type\": \"boolean\" },\n \"notes\": { \"type\": \"string\" },\n \"alternatives\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"object\",\n \"required\": [\"name\", \"ratio\"],\n \"properties\": {\n \"name\": { \"type\": \"string\" },\n \"ratio\": { \"type\": \"string\" },\n \"notes\": { \"type\": \"string\" },\n \"impact\": { \"type\": \"string\" },\n \"dietary\": {\n \"type\": \"array\",\n \"items\": { \"type\": \"string\" }\n }\n }\n }\n }\n }\n }\n }\n}","import Ajv from \"ajv\";\r\nimport addFormats from \"ajv-formats\"; // <--- Import this\r\nimport schema from \"./schema.json\";\r\nimport { Recipe } from \"./types\";\r\n\r\nconst ajv = new Ajv();\r\naddFormats(ajv); // <--- Enable formats like date-time, uri, email\r\n\r\nconst validate = ajv.compile(schema);\r\n\r\nexport function validateRecipe(data: any): data is Recipe {\r\n const isValid = validate(data);\r\n if (!isValid) {\r\n throw new Error(JSON.stringify(validate.errors, null, 2));\r\n }\r\n return true;\r\n}","import { ParsedIngredient, Scaling } from '../types';\r\n\r\ntype QuantityShape = { amount: number | null; unit: string | null };\r\n\r\ninterface QuantityExtraction {\r\n amount: number | null;\r\n unit: string | null;\r\n remainder: string;\r\n notes: string[];\r\n descriptor?: string;\r\n originalAmount: number | null;\r\n}\r\n\r\ninterface ParentheticalExtraction {\r\n cleaned: string;\r\n measurement?: QuantityShape;\r\n notes: string[];\r\n optional: boolean;\r\n}\r\n\r\ninterface VagueQuantityResult {\r\n remainder: string;\r\n note: string;\r\n}\r\n\r\ninterface FlavorExtractionResult {\r\n cleaned: string;\r\n notes: string[];\r\n}\r\n\r\ninterface PurposeExtractionResult {\r\n cleaned: string;\r\n notes: string[];\r\n}\r\n\r\ninterface JuiceExtractionResult {\r\n cleaned: string;\r\n note: string;\r\n}\r\n\r\nconst FRACTION_DECIMALS: Record<string, number> = {\r\n '½': 0.5,\r\n '⅓': 1 / 3,\r\n '⅔': 2 / 3,\r\n '¼': 0.25,\r\n '¾': 0.75,\r\n '⅕': 0.2,\r\n '⅖': 0.4,\r\n '⅗': 0.6,\r\n '⅘': 0.8,\r\n '⅙': 1 / 6,\r\n '⅚': 5 / 6,\r\n '⅛': 0.125,\r\n '⅜': 0.375,\r\n '⅝': 0.625,\r\n '⅞': 0.875\r\n};\r\n\r\nconst NUMBER_WORDS: Record<string, number> = {\r\n zero: 0,\r\n one: 1,\r\n two: 2,\r\n three: 3,\r\n four: 4,\r\n five: 5,\r\n six: 6,\r\n seven: 7,\r\n eight: 8,\r\n nine: 9,\r\n ten: 10,\r\n eleven: 11,\r\n twelve: 12,\r\n thirteen: 13,\r\n fourteen: 14,\r\n fifteen: 15,\r\n sixteen: 16,\r\n seventeen: 17,\r\n eighteen: 18,\r\n nineteen: 19,\r\n twenty: 20,\r\n thirty: 30,\r\n forty: 40,\r\n fifty: 50,\r\n sixty: 60,\r\n seventy: 70,\r\n eighty: 80,\r\n ninety: 90,\r\n hundred: 100,\r\n half: 0.5,\r\n quarter: 0.25\r\n};\r\n\r\nconst UNIT_SYNONYMS: Record<string, string> = {\r\n cup: 'cup',\r\n cups: 'cup',\r\n c: 'cup',\r\n tbsp: 'tbsp',\r\n tablespoon: 'tbsp',\r\n tablespoons: 'tbsp',\r\n tbs: 'tbsp',\r\n tsp: 'tsp',\r\n teaspoon: 'tsp',\r\n teaspoons: 'tsp',\r\n t: 'tsp',\r\n gram: 'g',\r\n grams: 'g',\r\n g: 'g',\r\n kilogram: 'kg',\r\n kilograms: 'kg',\r\n kg: 'kg',\r\n milliliter: 'ml',\r\n milliliters: 'ml',\r\n ml: 'ml',\r\n liter: 'l',\r\n liters: 'l',\r\n l: 'l',\r\n ounce: 'oz',\r\n ounces: 'oz',\r\n oz: 'oz',\r\n pound: 'lb',\r\n pounds: 'lb',\r\n lb: 'lb',\r\n lbs: 'lb',\r\n pint: 'pint',\r\n pints: 'pint',\r\n quart: 'quart',\r\n quarts: 'quart',\r\n stick: 'stick',\r\n sticks: 'stick',\r\n dash: 'dash',\r\n pinches: 'pinch',\r\n pinch: 'pinch'\r\n};\r\n\r\nconst PREP_PHRASES = [\r\n 'diced',\r\n 'finely diced',\r\n 'roughly diced',\r\n 'minced',\r\n 'finely minced',\r\n 'chopped',\r\n 'finely chopped',\r\n 'roughly chopped',\r\n 'sliced',\r\n 'thinly sliced',\r\n 'thickly sliced',\r\n 'grated',\r\n 'finely grated',\r\n 'zested',\r\n 'sifted',\r\n 'softened',\r\n 'at room temperature',\r\n 'room temperature',\r\n 'room temp',\r\n 'melted',\r\n 'toasted',\r\n 'drained',\r\n 'drained and rinsed',\r\n 'beaten',\r\n 'divided',\r\n 'cut into cubes',\r\n 'cut into pieces',\r\n 'cut into strips',\r\n 'cut into chunks',\r\n 'cut into bite-size pieces'\r\n].map(value => value.toLowerCase());\r\n\r\nconst COUNT_DESCRIPTORS = new Set([\r\n 'clove',\r\n 'cloves',\r\n 'can',\r\n 'cans',\r\n 'stick',\r\n 'sticks',\r\n 'sprig',\r\n 'sprigs',\r\n 'bunch',\r\n 'bunches',\r\n 'slice',\r\n 'slices',\r\n 'package',\r\n 'packages'\r\n]);\r\n\r\nconst DESCRIPTOR_NOTE_SET = new Set(['can', 'cans', 'jar', 'jars', 'package', 'packages', 'bottle', 'bottles']);\r\n\r\nconst WEIGHT_PRIORITY_UNITS = new Set(['g', 'kg', 'oz', 'lb', 'ml', 'l']);\r\n\r\nconst SPICE_KEYWORDS = [\r\n 'salt',\r\n 'pepper',\r\n 'paprika',\r\n 'cumin',\r\n 'coriander',\r\n 'turmeric',\r\n 'chili powder',\r\n 'garlic powder',\r\n 'onion powder',\r\n 'cayenne',\r\n 'cinnamon',\r\n 'nutmeg',\r\n 'allspice',\r\n 'ginger',\r\n 'oregano',\r\n 'thyme',\r\n 'rosemary',\r\n 'basil',\r\n 'sage',\r\n 'clove',\r\n 'spice',\r\n 'seasoning'\r\n];\r\n\r\nconst PURPOSE_KEYWORDS = ['frying', 'greasing', 'drizzling', 'garnish', 'serving', 'brushing'];\r\n\r\nconst RANGE_REGEX =\r\n /^((?:\\d+\\s+)?\\d+\\/\\d+|\\d+\\/\\d+|\\d+(?:\\.\\d+)?)(?:\\s*(?:-|to)\\s*((?:\\d+\\s+)?\\d+\\/\\d+|\\d+\\/\\d+|\\d+(?:\\.\\d+)?))/i;\r\nconst NUMBER_REGEX = /^((?:\\d+\\s+)?\\d+\\/\\d+|\\d+\\/\\d+|\\d+(?:\\.\\d+)?)/i;\r\n\r\nconst QUALIFIER_REGEX = /^(about|around|approximately|approx\\.?|roughly)\\s+/i;\r\n\r\nconst FLAVOR_NOTE_REGEX = /\\b(to taste|as needed|as necessary)\\b/gi;\r\n\r\nconst VAGUE_QUANTITY_PATTERNS: { regex: RegExp; note: string }[] = [\r\n { regex: /^(a\\s+pinch|pinch)\\b/i, note: 'a pinch' },\r\n { regex: /^(a\\s+handful|handful)\\b/i, note: 'a handful' },\r\n { regex: /^(a\\s+dash|dash)\\b/i, note: 'a dash' },\r\n { regex: /^(a\\s+sprinkle|sprinkle)\\b/i, note: 'a sprinkle' },\r\n { regex: /^(some)\\b/i, note: 'some' },\r\n { regex: /^(few\\s+sprigs)/i, note: 'few sprigs' },\r\n { regex: /^(a\\s+few|few)\\b/i, note: 'a few' },\r\n { regex: /^(several)\\b/i, note: 'several' }\r\n];\r\n\r\nconst JUICE_PREFIXES = ['juice of', 'zest of'];\r\n\r\nexport function normalizeIngredientInput(input: string): string {\r\n if (!input) return '';\r\n let result = input.replace(/\\u00A0/g, ' ').trim();\r\n result = replaceDashes(result);\r\n result = replaceUnicodeFractions(result);\r\n result = replaceNumberWords(result);\r\n result = result.replace(/\\s+/g, ' ').trim();\r\n return result;\r\n}\r\n\r\nexport function parseIngredient(text: string): ParsedIngredient {\r\n const original = text ?? '';\r\n const normalized = normalizeIngredientInput(original);\r\n if (!normalized) {\r\n return {\r\n item: original,\r\n scaling: { type: 'linear' }\r\n };\r\n }\r\n\r\n let working = normalized;\r\n const notes: string[] = [];\r\n let optional = false;\r\n\r\n if (/\\boptional\\b/i.test(working)) {\r\n optional = true;\r\n working = working.replace(/\\(?\\s*optional\\s*\\)?/gi, '').trim();\r\n working = working.replace(/\\(\\s*\\)/g, ' ').trim();\r\n }\r\n\r\n const flavorExtraction = extractFlavorNotes(working);\r\n working = flavorExtraction.cleaned;\r\n notes.push(...flavorExtraction.notes);\r\n\r\n const parenthetical = extractParentheticals(working);\r\n working = parenthetical.cleaned;\r\n notes.push(...parenthetical.notes);\r\n optional = optional || parenthetical.optional;\r\n\r\n const purposeExtraction = extractPurposeNotes(working);\r\n working = purposeExtraction.cleaned;\r\n notes.push(...purposeExtraction.notes);\r\n\r\n const juiceExtraction = extractJuicePhrase(working);\r\n if (juiceExtraction) {\r\n working = juiceExtraction.cleaned;\r\n notes.push(juiceExtraction.note);\r\n }\r\n\r\n const vagueQuantity = extractVagueQuantity(working);\r\n\r\n let quantityResult: QuantityExtraction;\r\n if (vagueQuantity) {\r\n notes.push(vagueQuantity.note);\r\n quantityResult = {\r\n amount: null,\r\n unit: null,\r\n descriptor: undefined,\r\n remainder: vagueQuantity.remainder,\r\n notes: [],\r\n originalAmount: null\r\n };\r\n } else {\r\n quantityResult = extractQuantity(working);\r\n }\r\n\r\n working = quantityResult.remainder;\r\n\r\n const { quantity, usedParenthetical } = mergeQuantities(quantityResult, parenthetical.measurement);\r\n if (\r\n usedParenthetical &&\r\n quantityResult.originalAmount !== null &&\r\n quantityResult.originalAmount > 1 &&\r\n quantityResult.descriptor &&\r\n DESCRIPTOR_NOTE_SET.has(quantityResult.descriptor.toLowerCase())\r\n ) {\r\n notes.push(formatCountNote(quantityResult.originalAmount, quantityResult.descriptor));\r\n }\r\n\r\n notes.push(...quantityResult.notes);\r\n\r\n working = working.replace(/^[,.\\s-]+/, '').trim();\r\n working = working.replace(/^of\\s+/i, '').trim();\r\n\r\n if (\r\n quantityResult.descriptor &&\r\n /^cans?$/i.test(quantityResult.descriptor) &&\r\n working &&\r\n !/^canned\\b/i.test(working)\r\n ) {\r\n working = `canned ${working}`.trim();\r\n }\r\n\r\n const nameExtraction = extractNameAndPrep(working);\r\n notes.push(...nameExtraction.notes);\r\n\r\n const name = nameExtraction.name || undefined;\r\n\r\n const scaling = inferScaling(\r\n name,\r\n quantity.unit,\r\n quantity.amount,\r\n notes,\r\n quantityResult.descriptor\r\n );\r\n\r\n const mergedNotes = formatNotes(notes);\r\n\r\n const parsed: ParsedIngredient = {\r\n item: original,\r\n quantity,\r\n ...(name ? { name } : {}),\r\n ...(nameExtraction.prep ? { prep: nameExtraction.prep } : {}),\r\n ...(optional ? { optional: true } : {}),\r\n scaling\r\n };\r\n\r\n if (mergedNotes) {\r\n parsed.notes = mergedNotes;\r\n }\r\n\r\n return parsed;\r\n}\r\n\r\nexport function parseIngredientLine(text: string): ParsedIngredient {\r\n return parseIngredient(text);\r\n}\r\n\r\nexport function parseIngredients(texts: string[]): ParsedIngredient[] {\r\n if (!Array.isArray(texts)) return [];\r\n return texts\r\n .map(item => (typeof item === 'string' ? item : String(item ?? '')))\r\n .map(entry => parseIngredient(entry));\r\n}\r\n\r\nfunction replaceDashes(value: string): string {\r\n return value.replace(/[\\u2012\\u2013\\u2014\\u2212]/g, '-');\r\n}\r\n\r\nfunction replaceUnicodeFractions(value: string): string {\r\n return value.replace(/(\\d+)?(?:\\s+)?([½⅓⅔¼¾⅕⅖⅗⅘⅙⅚⅛⅜⅝⅞])/g, (_match, whole, fraction) => {\r\n const fractionValue = FRACTION_DECIMALS[fraction];\r\n if (fractionValue === undefined) return _match;\r\n const base = whole ? parseInt(whole, 10) : 0;\r\n const combined = base + fractionValue;\r\n return formatDecimal(combined);\r\n });\r\n}\r\n\r\nfunction replaceNumberWords(value: string): string {\r\n return value.replace(\r\n /\\b(zero|one|two|three|four|five|six|seven|eight|nine|ten|eleven|twelve|thirteen|fourteen|fifteen|sixteen|seventeen|eighteen|nineteen|twenty|thirty|forty|fifty|sixty|seventy|eighty|ninety|hundred|half|quarter)(?:-(one|two|three|four|five|six|seven|eight|nine))?\\b/gi,\r\n (match, word, hyphenPart) => {\r\n const lower = word.toLowerCase();\r\n const baseValue = NUMBER_WORDS[lower];\r\n if (baseValue === undefined) return match;\r\n if (!hyphenPart) {\r\n return formatDecimal(baseValue);\r\n }\r\n const hyphenValue = NUMBER_WORDS[hyphenPart.toLowerCase()];\r\n if (hyphenValue === undefined) {\r\n return formatDecimal(baseValue);\r\n }\r\n return formatDecimal(baseValue + hyphenValue);\r\n }\r\n );\r\n}\r\n\r\nfunction formatDecimal(value: number): string {\r\n if (Number.isInteger(value)) {\r\n return value.toString();\r\n }\r\n return parseFloat(value.toFixed(3)).toString().replace(/\\.0+$/, '');\r\n}\r\n\r\nfunction extractFlavorNotes(value: string): FlavorExtractionResult {\r\n const notes: string[] = [];\r\n const cleaned = value.replace(FLAVOR_NOTE_REGEX, (_, phrase) => {\r\n notes.push(phrase.toLowerCase());\r\n return '';\r\n });\r\n\r\n return {\r\n cleaned: cleaned.replace(/\\s+/g, ' ').trim(),\r\n notes\r\n };\r\n}\r\n\r\nfunction extractPurposeNotes(value: string): PurposeExtractionResult {\r\n const notes: string[] = [];\r\n let working = value.trim();\r\n\r\n let match = working.match(/\\bfor\\s+(frying|greasing|drizzling|garnish|serving|brushing)\\b\\.?$/i);\r\n if (match) {\r\n notes.push(`for ${match[1].toLowerCase()}`);\r\n working = working.slice(0, match.index).trim();\r\n }\r\n\r\n return { cleaned: working, notes };\r\n}\r\n\r\nfunction extractJuicePhrase(value: string): JuiceExtractionResult | undefined {\r\n const lower = value.toLowerCase();\r\n for (const prefix of JUICE_PREFIXES) {\r\n if (lower.startsWith(prefix)) {\r\n const remainder = value.slice(prefix.length).trim();\r\n if (!remainder) break;\r\n const cleanedSource = remainder.replace(/^of\\s+/i, '').trim();\r\n if (!cleanedSource) break;\r\n const sourceForName = cleanedSource\r\n .replace(\r\n /^(?:\\d+(?:\\.\\d+)?|\\d+\\s+\\d+\\/\\d+|\\d+\\/\\d+|one|two|three|four|five|six|seven|eight|nine|ten|a|an)\\s+/i,\r\n ''\r\n )\r\n .replace(/^(?:large|small|medium)\\s+/i, '')\r\n .trim();\r\n const baseName = sourceForName || cleanedSource;\r\n const singular = singularize(baseName);\r\n const suffix = prefix.startsWith('zest') ? 'zest' : 'juice';\r\n return {\r\n cleaned: `${singular} ${suffix}`.trim(),\r\n note: `from ${cleanedSource}`\r\n };\r\n }\r\n }\r\n return undefined;\r\n}\r\n\r\nfunction extractVagueQuantity(value: string): VagueQuantityResult | undefined {\r\n for (const pattern of VAGUE_QUANTITY_PATTERNS) {\r\n const match = value.match(pattern.regex);\r\n if (match) {\r\n let remainder = value.slice(match[0].length).trim();\r\n remainder = remainder.replace(/^of\\s+/i, '').trim();\r\n return {\r\n remainder,\r\n note: pattern.note\r\n };\r\n }\r\n }\r\n return undefined;\r\n}\r\n\r\nfunction extractParentheticals(value: string): ParentheticalExtraction {\r\n let optional = false;\r\n let measurement: QuantityShape | undefined;\r\n const notes: string[] = [];\r\n\r\n const cleaned = value.replace(/\\(([^)]+)\\)/g, (_match, group) => {\r\n const trimmed = String(group).trim();\r\n if (!trimmed) return '';\r\n if (/optional/i.test(trimmed)) {\r\n optional = true;\r\n return '';\r\n }\r\n const maybeMeasurement = parseMeasurement(trimmed);\r\n if (maybeMeasurement && !measurement) {\r\n measurement = maybeMeasurement;\r\n return '';\r\n }\r\n notes.push(trimmed);\r\n return '';\r\n });\r\n\r\n return {\r\n cleaned: cleaned.replace(/\\s+/g, ' ').trim(),\r\n measurement,\r\n notes,\r\n optional\r\n };\r\n}\r\n\r\nfunction parseMeasurement(value: string): QuantityShape | undefined {\r\n const stripped = value.replace(/^(about|around|approximately|approx\\.?|roughly)\\s+/i, '').trim();\r\n const match = stripped.match(\r\n /^((?:\\d+\\s+)?\\d+\\/\\d+|\\d+\\/\\d+|\\d+(?:\\.\\d+)?)(?:\\s*)([a-zA-Z]+)?$/\r\n );\r\n if (!match) return undefined;\r\n const amount = parseNumber(match[1]);\r\n if (amount === null) return undefined;\r\n const unit = match[2] ? normalizeUnit(match[2]) ?? match[2].toLowerCase() : null;\r\n return { amount, unit };\r\n}\r\n\r\nfunction extractQuantity(value: string): QuantityExtraction {\r\n let working = value.trim();\r\n const notes: string[] = [];\r\n let amount: number | null = null;\r\n let originalAmount: number | null = null;\r\n let unit: string | null = null;\r\n let descriptor: string | undefined;\r\n\r\n while (QUALIFIER_REGEX.test(working)) {\r\n working = working.replace(QUALIFIER_REGEX, '').trim();\r\n }\r\n\r\n const rangeMatch = working.match(RANGE_REGEX);\r\n if (rangeMatch) {\r\n amount = parseNumber(rangeMatch[1]);\r\n originalAmount = amount;\r\n const rangeText = rangeMatch[0].trim();\r\n const afterRange = working.slice(rangeMatch[0].length).trim();\r\n const descriptorMatch = afterRange.match(/^([a-zA-Z]+)/);\r\n if (descriptorMatch && COUNT_DESCRIPTORS.has(descriptorMatch[1].toLowerCase())) {\r\n notes.push(`${rangeText} ${descriptorMatch[1]}`);\r\n } else {\r\n notes.push(rangeText);\r\n }\r\n working = afterRange;\r\n } else {\r\n const numberMatch = working.match(NUMBER_REGEX);\r\n if (numberMatch) {\r\n amount = parseNumber(numberMatch[1]);\r\n originalAmount = amount;\r\n working = working.slice(numberMatch[0].length).trim();\r\n }\r\n }\r\n\r\n if (working) {\r\n const unitMatch = working.match(/^([a-zA-Z]+)\\b/);\r\n if (unitMatch) {\r\n const normalized = normalizeUnit(unitMatch[1]);\r\n if (normalized) {\r\n unit = normalized;\r\n working = working.slice(unitMatch[0].length).trim();\r\n } else if (COUNT_DESCRIPTORS.has(unitMatch[1].toLowerCase())) {\r\n descriptor = unitMatch[1];\r\n working = working.slice(unitMatch[0].length).trim();\r\n }\r\n }\r\n }\r\n\r\n return {\r\n amount,\r\n unit,\r\n descriptor,\r\n remainder: working.trim(),\r\n notes,\r\n originalAmount\r\n };\r\n}\r\n\r\nfunction parseNumber(value: string): number | null {\r\n const trimmed = value.trim();\r\n if (!trimmed) return null;\r\n if (/^\\d+\\s+\\d+\\/\\d+$/.test(trimmed)) {\r\n const [whole, fraction] = trimmed.split(/\\s+/);\r\n return parseInt(whole, 10) + parseFraction(fraction);\r\n }\r\n if (/^\\d+\\/\\d+$/.test(trimmed)) {\r\n return parseFraction(trimmed);\r\n }\r\n const parsed = Number(trimmed);\r\n return Number.isNaN(parsed) ? null : parsed;\r\n}\r\n\r\nfunction parseFraction(value: string): number {\r\n const [numerator, denominator] = value.split('/').map(Number);\r\n if (!denominator) return numerator;\r\n return numerator / denominator;\r\n}\r\n\r\nfunction normalizeUnit(raw: string): string | null {\r\n const lower = raw.toLowerCase();\r\n if (UNIT_SYNONYMS[lower]) {\r\n return UNIT_SYNONYMS[lower];\r\n }\r\n if (raw === 'T') return 'tbsp';\r\n if (raw === 't') return 'tsp';\r\n if (raw === 'C') return 'cup';\r\n return null;\r\n}\r\n\r\nfunction mergeQuantities(\r\n extracted: QuantityExtraction,\r\n measurement?: QuantityShape\r\n): { quantity: QuantityShape; usedParenthetical: boolean } {\r\n const quantity: QuantityShape = {\r\n amount: extracted.amount ?? null,\r\n unit: extracted.unit ?? null\r\n };\r\n\r\n if (!measurement) {\r\n return { quantity, usedParenthetical: false };\r\n }\r\n\r\n const measurementUnit = measurement.unit?.toLowerCase() ?? null;\r\n const shouldPrefer =\r\n !quantity.unit ||\r\n (measurementUnit !== null && WEIGHT_PRIORITY_UNITS.has(measurementUnit));\r\n\r\n if (shouldPrefer) {\r\n return {\r\n quantity: {\r\n amount: measurement.amount,\r\n unit: measurement.unit ?? null\r\n },\r\n usedParenthetical: true\r\n };\r\n }\r\n\r\n return { quantity, usedParenthetical: false };\r\n}\r\n\r\nfunction extractNameAndPrep(value: string): {\r\n name?: string;\r\n prep?: string;\r\n notes: string[];\r\n} {\r\n let working = value.trim();\r\n const notes: string[] = [];\r\n let prep: string | undefined;\r\n\r\n const lastComma = working.lastIndexOf(',');\r\n if (lastComma >= 0) {\r\n const trailing = working.slice(lastComma + 1).trim();\r\n if (isPrepPhrase(trailing)) {\r\n prep = trailing;\r\n working = working.slice(0, lastComma).trim();\r\n }\r\n }\r\n\r\n working = working.replace(/^[,.\\s-]+/, '').trim();\r\n working = working.replace(/^of\\s+/i, '').trim();\r\n\r\n if (!working) {\r\n return { name: undefined, prep, notes };\r\n }\r\n\r\n let name = cleanupIngredientName(working);\r\n\r\n return {\r\n name: name || undefined,\r\n prep,\r\n notes\r\n };\r\n}\r\n\r\nfunction cleanupIngredientName(value: string): string {\r\n let result = value.trim();\r\n\r\n if (/^cans?\\b/i.test(result)) {\r\n result = result.replace(/^cans?\\b/i, 'canned').trim();\r\n }\r\n\r\n let changed = true;\r\n while (changed) {\r\n changed = false;\r\n if (/^of\\s+/i.test(result)) {\r\n result = result.replace(/^of\\s+/i, '').trim();\r\n changed = true;\r\n continue;\r\n }\r\n const match = result.match(/^(clove|cloves|sprig|sprigs|bunch|bunches|stick|sticks|slice|slices)\\b/i);\r\n if (match) {\r\n result = result.slice(match[0].length).trim();\r\n changed = true;\r\n }\r\n }\r\n\r\n return result;\r\n}\r\n\r\nfunction isPrepPhrase(value: string): boolean {\r\n const normalized = value.toLowerCase();\r\n return PREP_PHRASES.includes(normalized);\r\n}\r\n\r\nfunction inferScaling(\r\n name: string | undefined,\r\n unit: string | null,\r\n amount: number | null,\r\n notes: string[],\r\n descriptor?: string\r\n): Scaling {\r\n const lowerName = name?.toLowerCase() ?? '';\r\n const normalizedNotes = notes.map(note => note.toLowerCase());\r\n const descriptorLower = descriptor?.toLowerCase();\r\n\r\n if (\r\n lowerName.includes('egg') ||\r\n descriptorLower === 'clove' ||\r\n descriptorLower === 'cloves' ||\r\n normalizedNotes.some(note => note.includes('clove'))\r\n ) {\r\n return { type: 'discrete', roundTo: 1 };\r\n }\r\n\r\n if (descriptorLower === 'stick' || descriptorLower === 'sticks') {\r\n return { type: 'discrete', roundTo: 1 };\r\n }\r\n\r\n if (normalizedNotes.some(note => PURPOSE_KEYWORDS.some(keyword => note.includes(keyword)))) {\r\n return { type: 'fixed' };\r\n }\r\n\r\n const isSpice = SPICE_KEYWORDS.some(keyword => lowerName.includes(keyword));\r\n const smallUnit = unit ? ['tsp', 'tbsp', 'dash', 'pinch'].includes(unit) : false;\r\n if (\r\n normalizedNotes.some(note => note.includes('to taste')) ||\r\n (isSpice && (smallUnit || (amount !== null && amount <= 1)))\r\n ) {\r\n return { type: 'proportional', factor: 0.7 };\r\n }\r\n\r\n return { type: 'linear' };\r\n}\r\n\r\nfunction formatNotes(notes: string[]): string | undefined {\r\n const cleaned = Array.from(\r\n new Set(\r\n notes\r\n .map(note => note.trim())\r\n .filter(Boolean)\r\n )\r\n );\r\n return cleaned.length ? cleaned.join('; ') : undefined;\r\n}\r\n\r\nfunction formatCountNote(amount: number, descriptor: string): string {\r\n const lower = descriptor.toLowerCase();\r\n const singular = lower.endsWith('s') ? lower.slice(0, -1) : lower;\r\n const word =\r\n amount === 1\r\n ? singular\r\n : singular.endsWith('ch') || singular.endsWith('sh') || singular.endsWith('s') || singular.endsWith('x') || singular.endsWith('z')\r\n ? `${singular}es`\r\n : singular.endsWith('y') && !/[aeiou]y$/.test(singular)\r\n ? `${singular.slice(0, -1)}ies`\r\n : `${singular}s`;\r\n return `${formatDecimal(amount)} ${word}`;\r\n}\r\n\r\nfunction singularize(value: string): string {\r\n const trimmed = value.trim();\r\n if (trimmed.endsWith('ies')) {\r\n return `${trimmed.slice(0, -3)}y`;\r\n }\r\n if (/(ches|shes|sses|xes|zes)$/i.test(trimmed)) {\r\n return trimmed.slice(0, -2);\r\n }\r\n if (trimmed.endsWith('s')) {\r\n return trimmed.slice(0, -1);\r\n }\r\n return trimmed;\r\n}\r\n","import { Ingredient, ParsedIngredient, Quantity } from '../types';\r\nimport { parseIngredient } from '../parsers/ingredient';\r\n\r\nexport function parseIngredientLine(line: string): Ingredient {\r\n const parsed = parseIngredient(line);\r\n\r\n const ingredient: Ingredient = {\r\n item: parsed.item,\r\n scaling: parsed.scaling ?? { type: 'linear' }\r\n };\r\n\r\n if (parsed.name) {\r\n ingredient.name = parsed.name;\r\n }\r\n\r\n if (parsed.prep) {\r\n ingredient.prep = parsed.prep;\r\n }\r\n\r\n if (parsed.optional) {\r\n ingredient.optional = true;\r\n }\r\n\r\n if (parsed.notes) {\r\n ingredient.notes = parsed.notes;\r\n }\r\n\r\n const quantity = buildQuantity(parsed.quantity);\r\n if (quantity) {\r\n ingredient.quantity = quantity;\r\n }\r\n\r\n return ingredient;\r\n}\r\n\r\nfunction buildQuantity(\r\n parsedQuantity: ParsedIngredient['quantity']\r\n): Quantity | undefined {\r\n if (!parsedQuantity) {\r\n return undefined;\r\n }\r\n\r\n if (parsedQuantity.amount === null || Number.isNaN(parsedQuantity.amount)) {\r\n return undefined;\r\n }\r\n\r\n return {\r\n amount: parsedQuantity.amount,\r\n unit: parsedQuantity.unit ?? null\r\n };\r\n}\r\n","import { Yield } from '../types';\r\n\r\nexport function parseYield(value: unknown): Yield | undefined {\r\n if (value === undefined || value === null) {\r\n return undefined;\r\n }\r\n\r\n if (typeof value === 'number') {\r\n return {\r\n amount: value,\r\n unit: 'servings'\r\n };\r\n }\r\n\r\n if (Array.isArray(value)) {\r\n return parseYield(value[0]);\r\n }\r\n\r\n if (typeof value === 'object') {\r\n const maybeYield = value as Record<string, any>;\r\n if (typeof maybeYield.amount === 'number') {\r\n return {\r\n amount: maybeYield.amount,\r\n unit: typeof maybeYield.unit === 'string' ? maybeYield.unit : 'servings',\r\n description:\r\n typeof maybeYield.description === 'string'\r\n ? maybeYield.description\r\n : undefined\r\n };\r\n }\r\n }\r\n\r\n if (typeof value === 'string') {\r\n const trimmed = value.trim();\r\n const match = trimmed.match(/(\\d+(?:\\.\\d+)?)/);\r\n if (match) {\r\n const amount = parseFloat(match[1]);\r\n const unit = trimmed.slice(match.index! + match[1].length).trim();\r\n return {\r\n amount,\r\n unit: unit || 'servings',\r\n description: trimmed\r\n };\r\n }\r\n }\r\n\r\n return undefined;\r\n}\r\n\r\nexport function formatYield(yieldValue?: Yield): string | undefined {\r\n if (!yieldValue) return undefined;\r\n if (!yieldValue.amount && !yieldValue.unit) {\r\n return undefined;\r\n }\r\n\r\n const amount = yieldValue.amount ?? '';\r\n const unit = yieldValue.unit ? ` ${yieldValue.unit}` : '';\r\n return `${amount}${unit}`.trim() || yieldValue.description;\r\n}\r\n","const ISO_DURATION_REGEX =\r\n /^P(?:(\\d+(?:\\.\\d+)?)D)?(?:T(?:(\\d+(?:\\.\\d+)?)H)?(?:(\\d+(?:\\.\\d+)?)M)?(?:(\\d+(?:\\.\\d+)?)S)?)?$/i;\r\n\r\nconst HUMAN_OVERNIGHT = 8 * 60; // 8 hours\r\n\r\nfunction isFiniteNumber(value: unknown): value is number {\r\n return typeof value === 'number' && Number.isFinite(value);\r\n}\r\n\r\nexport function parseDuration(iso: string): number | null;\r\nexport function parseDuration(iso: string | null | undefined): number | null;\r\nexport function parseDuration(iso: string | null | undefined): number | null {\r\n if (!iso || typeof iso !== 'string') return null;\r\n\r\n const trimmed = iso.trim();\r\n if (!trimmed) return null;\r\n\r\n const match = trimmed.match(ISO_DURATION_REGEX);\r\n if (!match) return null;\r\n\r\n const [, daysRaw, hoursRaw, minutesRaw, secondsRaw] = match;\r\n\r\n if (!daysRaw && !hoursRaw && !minutesRaw && !secondsRaw) {\r\n return null;\r\n }\r\n\r\n let total = 0;\r\n if (daysRaw) total += parseFloat(daysRaw) * 24 * 60;\r\n if (hoursRaw) total += parseFloat(hoursRaw) * 60;\r\n if (minutesRaw) total += parseFloat(minutesRaw);\r\n if (secondsRaw) total += Math.ceil(parseFloat(secondsRaw) / 60);\r\n\r\n return Math.round(total);\r\n}\r\n\r\nexport function formatDuration(minutes: number): string;\r\nexport function formatDuration(minutes: number | null | undefined): string;\r\nexport function formatDuration(minutes: number | null | undefined): string {\r\n if (!isFiniteNumber(minutes) || minutes <= 0) {\r\n return 'PT0M';\r\n }\r\n\r\n const rounded = Math.round(minutes);\r\n const days = Math.floor(rounded / (24 * 60));\r\n const afterDays = rounded % (24 * 60);\r\n const hours = Math.floor(afterDays / 60);\r\n const mins = afterDays % 60;\r\n\r\n let result = 'P';\r\n\r\n if (days > 0) {\r\n result += `${days}D`;\r\n }\r\n\r\n if (hours > 0 || mins > 0) {\r\n result += 'T';\r\n if (hours > 0) {\r\n result += `${hours}H`;\r\n }\r\n if (mins > 0) {\r\n result += `${mins}M`;\r\n }\r\n }\r\n\r\n if (result === 'P') {\r\n return 'PT0M';\r\n }\r\n\r\n return result;\r\n}\r\n\r\nexport function parseHumanDuration(text: string): number | null;\r\nexport function parseHumanDuration(text: string | null | undefined): number | null;\r\nexport function parseHumanDuration(text: string | null | undefined): number | null {\r\n if (!text || typeof text !== 'string') return null;\r\n\r\n const normalized = text.toLowerCase().trim();\r\n if (!normalized) return null;\r\n\r\n if (normalized === 'overnight') {\r\n return HUMAN_OVERNIGHT;\r\n }\r\n\r\n let total = 0;\r\n\r\n const hourRegex = /(\\d+(?:\\.\\d+)?)\\s*(?:hours?|hrs?|hr|h)\\b/g;\r\n let hourMatch: RegExpExecArray | null;\r\n while ((hourMatch = hourRegex.exec(normalized)) !== null) {\r\n total += parseFloat(hourMatch[1]) * 60;\r\n }\r\n\r\n const minuteRegex = /(\\d+(?:\\.\\d+)?)\\s*(?:minutes?|mins?|min|m)\\b/g;\r\n let minuteMatch: RegExpExecArray | null;\r\n while ((minuteMatch = minuteRegex.exec(normalized)) !== null) {\r\n total += parseFloat(minuteMatch[1]);\r\n }\r\n\r\n if (total <= 0) {\r\n return null;\r\n }\r\n\r\n return Math.round(total);\r\n}\r\n\r\nexport function smartParseDuration(input: string): number | null;\r\nexport function smartParseDuration(input: string | null | undefined): number | null;\r\nexport function smartParseDuration(input: string | null | undefined): number | null {\r\n const iso = parseDuration(input);\r\n if (iso !== null) {\r\n return iso;\r\n }\r\n return parseHumanDuration(input);\r\n}\r\n","import {\r\n IngredientItem,\r\n Instruction,\r\n InstructionItem,\r\n Recipe,\r\n Source,\r\n StructuredTime\r\n} from './types';\r\nimport { parseIngredientLine } from './converters/ingredient';\r\nimport { parseYield } from './converters/yield';\r\nimport { smartParseDuration } from './parsers/duration';\r\nimport {\r\n HowToSection,\r\n HowToStep,\r\n SchemaOrgImage,\r\n SchemaOrgPersonOrOrganization,\r\n SchemaOrgRecipe\r\n} from './types/schemaOrg';\r\n\r\nexport function fromSchemaOrg(input: unknown): Recipe | null {\r\n const recipeNode = extractRecipeNode(input);\r\n if (!recipeNode) {\r\n return null;\r\n }\r\n\r\n const ingredients = convertIngredients(recipeNode.recipeIngredient);\r\n const instructions = convertInstructions(recipeNode.recipeInstructions);\r\n const time = convertTime(recipeNode);\r\n const recipeYield = parseYield(recipeNode.recipeYield);\r\n const tags = collectTags(recipeNode.recipeCuisine, recipeNode.keywords);\r\n const category = extractFirst(recipeNode.recipeCategory);\r\n const image = convertImage(recipeNode.image);\r\n const source = convertSource(recipeNode);\r\n const nutrition =\r\n recipeNode.nutrition && typeof recipeNode.nutrition === 'object'\r\n ? recipeNode.nutrition\r\n : undefined;\r\n\r\n return {\r\n name: recipeNode.name.trim(),\r\n description: recipeNode.description?.trim() || undefined,\r\n image,\r\n category,\r\n tags: tags.length ? tags : undefined,\r\n source,\r\n dateAdded: recipeNode.datePublished || undefined,\r\n dateModified: recipeNode.dateModified || undefined,\r\n yield: recipeYield,\r\n time,\r\n ingredients,\r\n instructions,\r\n nutrition\r\n };\r\n}\r\n\r\nfunction extractRecipeNode(input: unknown): SchemaOrgRecipe | null {\r\n if (!input) return null;\r\n\r\n if (Array.isArray(input)) {\r\n for (const entry of input) {\r\n const found = extractRecipeNode(entry);\r\n if (found) {\r\n return found;\r\n }\r\n }\r\n return null;\r\n }\r\n\r\n if (typeof input !== 'object') {\r\n return null;\r\n }\r\n\r\n const record = input as Partial<SchemaOrgRecipe> & { [key: string]: unknown };\r\n\r\n if (record['@graph']) {\r\n const fromGraph = extractRecipeNode(record['@graph']);\r\n if (fromGraph) {\r\n return fromGraph;\r\n }\r\n }\r\n\r\n if (!hasRecipeType(record['@type'])) {\r\n return null;\r\n }\r\n\r\n if (!isValidName(record.name)) {\r\n return null;\r\n }\r\n\r\n return record as SchemaOrgRecipe;\r\n}\r\n\r\nfunction hasRecipeType(value: SchemaOrgRecipe['@type']): boolean {\r\n if (!value) return false;\r\n const types = Array.isArray(value) ? value : [value];\r\n // #region agent log\r\n fetch('http://127.0.0.1:7243/ingest/7225c3b5-9ac2-4c94-b561-807ca9003b66',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'fromSchemaOrg.ts:95',message:'hasRecipeType check',data:{types,typesLower:types.map(t=>typeof t==='string'?t.toLowerCase():t),isMatch:types.some(e=>typeof e==='string'&&e.toLowerCase()==='recipe')},timestamp:Date.now(),sessionId:'debug-session',runId:'run1',hypothesisId:'A'})}).catch(()=>{});\r\n // #endregion\r\n return types.some(\r\n entry => typeof entry === 'string' && entry.toLowerCase() === 'recipe'\r\n );\r\n}\r\n\r\nfunction isValidName(name: unknown): name is string {\r\n return typeof name === 'string' && Boolean(name.trim());\r\n}\r\n\r\nfunction convertIngredients(\r\n value: SchemaOrgRecipe['recipeIngredient']\r\n): IngredientItem[] {\r\n if (!value) return [];\r\n const normalized = Array.isArray(value) ? value : [value];\r\n return normalized\r\n .map(item => (typeof item === 'string' ? item.trim() : ''))\r\n .filter(Boolean)\r\n .map(line => parseIngredientLine(line));\r\n}\r\n\r\nfunction convertInstructions(\r\n value: SchemaOrgRecipe['recipeInstructions']\r\n): InstructionItem[] {\r\n if (!value) return [];\r\n const normalized = Array.isArray(value) ? value : [value];\r\n const result: InstructionItem[] = [];\r\n\r\n for (const entry of normalized) {\r\n if (!entry) continue;\r\n\r\n if (typeof entry === 'string') {\r\n const text = entry.trim();\r\n if (text) {\r\n result.push(text);\r\n }\r\n continue;\r\n }\r\n\r\n if (isHowToSection(entry)) {\r\n const subsectionItems = extractSectionItems(entry.itemListElement);\r\n if (subsectionItems.length) {\r\n result.push({\r\n subsection: entry.name?.trim() || 'Section',\r\n items: subsectionItems\r\n });\r\n }\r\n continue;\r\n }\r\n\r\n if (isHowToStep(entry)) {\r\n const text = extractInstructionText(entry);\r\n if (text) {\r\n result.push(text);\r\n }\r\n }\r\n }\r\n\r\n return result;\r\n}\r\n\r\nfunction extractSectionItems(\r\n items: Array<string | HowToStep | HowToSection> = []\r\n): Array<string | Instruction> {\r\n const result: Array<string | Instruction> = [];\r\n\r\n for (const item of items) {\r\n if (!item) continue;\r\n\r\n if (typeof item === 'string') {\r\n const text = item.trim();\r\n if (text) {\r\n result.push(text);\r\n }\r\n continue;\r\n }\r\n\r\n if (isHowToStep(item)) {\r\n const text = extractInstructionText(item);\r\n if (text) {\r\n result.push(text);\r\n }\r\n continue;\r\n }\r\n\r\n if (isHowToSection(item)) {\r\n result.push(...extractSectionItems(item.itemListElement));\r\n }\r\n }\r\n\r\n return result;\r\n}\r\n\r\nfunction extractInstructionText(value: HowToStep): string | undefined {\r\n const text = typeof value.text === 'string' ? value.text : value.name;\r\n return typeof text === 'string' ? text.trim() || undefined : undefined;\r\n}\r\n\r\nfunction isHowToStep(value: unknown): value is HowToStep {\r\n return (\r\n Boolean(value) &&\r\n typeof value === 'object' &&\r\n (value as HowToStep)['@type'] === 'HowToStep'\r\n );\r\n}\r\n\r\nfunction isHowToSection(value: unknown): value is HowToSection {\r\n return (\r\n Boolean(value) &&\r\n typeof value === 'object' &&\r\n (value as HowToSection)['@type'] === 'HowToSection' &&\r\n Array.isArray((value as HowToSection).itemListElement)\r\n );\r\n}\r\n\r\nfunction convertTime(recipe: SchemaOrgRecipe): StructuredTime | undefined {\r\n const prep = smartParseDuration(recipe.prepTime ?? '');\r\n const cook = smartParseDuration(recipe.cookTime ?? '');\r\n const total = smartParseDuration(recipe.totalTime ?? '');\r\n\r\n const structured: StructuredTime = {};\r\n if (prep !== null && prep !== undefined) structured.prep = prep;\r\n if (cook !== null && cook !== undefined) structured.active = cook;\r\n if (total !== null && total !== undefined) structured.total = total;\r\n\r\n return Object.keys(structured).length ? structured : undefined;\r\n}\r\n\r\nfunction collectTags(cuisine: unknown, keywords: unknown): string[] {\r\n const tags = new Set<string>();\r\n flattenStrings(cuisine).forEach(tag => tags.add(tag));\r\n if (typeof keywords === 'string') {\r\n splitKeywords(keywords).forEach(tag => tags.add(tag));\r\n } else {\r\n flattenStrings(keywords).forEach(tag => tags.add(tag));\r\n }\r\n return Array.from(tags);\r\n}\r\n\r\nfunction splitKeywords(value: string): string[] {\r\n return value\r\n .split(/[,|]/)\r\n .map(part => part.trim())\r\n .filter(Boolean);\r\n}\r\n\r\nfunction flattenStrings(value: unknown): string[] {\r\n if (!value) return [];\r\n if (typeof value === 'string') return [value.trim()].filter(Boolean);\r\n if (Array.isArray(value)) {\r\n return value\r\n .map(item => (typeof item === 'string' ? item.trim() : ''))\r\n .filter(Boolean);\r\n }\r\n return [];\r\n}\r\n\r\nfunction extractFirst(value: unknown): string | undefined {\r\n const arr = flattenStrings(value);\r\n return arr.length ? arr[0] : undefined;\r\n}\r\n\r\nfunction convertImage(value: SchemaOrgImage | undefined): string | undefined {\r\n if (!value) return undefined;\r\n\r\n if (typeof value === 'string') {\r\n return value;\r\n }\r\n\r\n if (Array.isArray(value)) {\r\n for (const item of value) {\r\n const url = typeof item === 'string' ? item : extractImageUrl(item);\r\n if (url) return url;\r\n }\r\n return undefined;\r\n }\r\n\r\n return extractImageUrl(value);\r\n}\r\n\r\nfunction extractImageUrl(value: unknown): string | undefined {\r\n if (!value || typeof value !== 'object') return undefined;\r\n const record = value as { url?: unknown; contentUrl?: unknown };\r\n const candidate =\r\n typeof record.url === 'string'\r\n ? record.url\r\n : typeof record.contentUrl === 'string'\r\n ? record.contentUrl\r\n : undefined;\r\n return candidate?.trim() || undefined;\r\n}\r\n\r\nfunction convertSource(recipe: SchemaOrgRecipe): Source | undefined {\r\n const author = extractEntityName(recipe.author);\r\n const publisher = extractEntityName(recipe.publisher);\r\n const url = (recipe.url || recipe.mainEntityOfPage)?.trim();\r\n\r\n const source: Source = {};\r\n if (author) source.author = author;\r\n if (publisher) source.name = publisher;\r\n if (url) source.url = url;\r\n\r\n return Object.keys(source).length ? source : undefined;\r\n}\r\n\r\nfunction extractEntityName(\r\n value:\r\n | SchemaOrgPersonOrOrganization\r\n | SchemaOrgPersonOrOrganization[]\r\n | string\r\n | string[]\r\n | undefined\r\n): string | undefined {\r\n if (!value) return undefined;\r\n\r\n if (typeof value === 'string') {\r\n const trimmed = value.trim();\r\n return trimmed || undefined;\r\n }\r\n\r\n if (Array.isArray(value)) {\r\n for (const entry of value) {\r\n const name = extractEntityName(entry as any);\r\n if (name) {\r\n return name;\r\n }\r\n }\r\n return undefined;\r\n }\r\n\r\n if (typeof value === 'object' && typeof value.name === 'string') {\r\n const trimmed = value.name.trim();\r\n return trimmed || undefined;\r\n }\r\n\r\n return undefined;\r\n}","import { IngredientItem, InstructionItem, Recipe, StructuredTime, Time } from '../types';\r\nimport { formatDuration } from '../parsers/duration';\r\nimport { formatYield } from './yield';\r\nimport { HowToSection, HowToStep, SchemaOrgRecipe } from '../types/schemaOrg';\r\n\r\ntype SchemaOrgInstruction = HowToStep | HowToSection;\r\n\r\nexport function convertBasicMetadata(recipe: Recipe): Partial<SchemaOrgRecipe> {\r\n return cleanOutput({\r\n '@context': 'https://schema.org',\r\n '@type': 'Recipe',\r\n name: recipe.name,\r\n description: recipe.description,\r\n image: recipe.image,\r\n url: recipe.source?.url,\r\n datePublished: recipe.dateAdded,\r\n dateModified: recipe.dateModified\r\n });\r\n}\r\n\r\nexport function convertIngredients(ingredients: IngredientItem[] = []): string[] {\r\n const result: string[] = [];\r\n\r\n ingredients.forEach(ingredient => {\r\n if (!ingredient) {\r\n return;\r\n }\r\n\r\n if (typeof ingredient === 'string') {\r\n const value = ingredient.trim();\r\n if (value) {\r\n result.push(value);\r\n }\r\n return;\r\n }\r\n\r\n if ('subsection' in ingredient) {\r\n ingredient.items.forEach(item => {\r\n if (!item) {\r\n return;\r\n }\r\n if (typeof item === 'string') {\r\n const value = item.trim();\r\n if (value) {\r\n result.push(value);\r\n }\r\n } else if (item.item) {\r\n const value = item.item.trim();\r\n if (value) {\r\n result.push(value);\r\n }\r\n }\r\n });\r\n return;\r\n }\r\n\r\n const value = ingredient.item?.trim();\r\n if (value) {\r\n result.push(value);\r\n }\r\n });\r\n\r\n return result;\r\n}\r\n\r\nexport function convertInstructions(\r\n instructions: InstructionItem[] = []\r\n): SchemaOrgInstruction[] {\r\n return instructions\r\n .map(entry => convertInstruction(entry))\r\n .filter((value): value is SchemaOrgInstruction => Boolean(value));\r\n}\r\n\r\nfunction convertInstruction(entry: InstructionItem): SchemaOrgInstruction | null {\r\n if (!entry) {\r\n return null;\r\n }\r\n\r\n if (typeof entry === 'string') {\r\n return createHowToStep(entry);\r\n }\r\n\r\n if ('subsection' in entry) {\r\n const steps = entry.items\r\n .map(item => (typeof item === 'string' ? createHowToStep(item) : createHowToStep(item.text)))\r\n .filter((step): step is HowToStep => Boolean(step));\r\n\r\n if (!steps.length) {\r\n return null;\r\n }\r\n\r\n return {\r\n '@type': 'HowToSection',\r\n name: entry.subsection,\r\n itemListElement: steps\r\n };\r\n }\r\n\r\n if ('text' in entry) {\r\n return createHowToStep(entry.text);\r\n }\r\n\r\n return createHowToStep(String(entry));\r\n}\r\n\r\nfunction createHowToStep(text?: string): HowToStep | null {\r\n if (!text) return null;\r\n const trimmed = text.trim();\r\n if (!trimmed) return null;\r\n return {\r\n '@type': 'HowToStep',\r\n text: trimmed\r\n };\r\n}\r\n\r\nexport function convertTime(time?: Time): Partial<SchemaOrgRecipe> {\r\n if (!time) {\r\n return {};\r\n }\r\n\r\n if (isStructuredTime(time)) {\r\n const result: Partial<SchemaOrgRecipe> = {};\r\n if (time.prep !== undefined) {\r\n result.prepTime = formatDuration(time.prep);\r\n }\r\n if (time.active !== undefined) {\r\n result.cookTime = formatDuration(time.active);\r\n }\r\n if (time.total !== undefined) {\r\n result.totalTime = formatDuration(time.total);\r\n }\r\n return result;\r\n }\r\n\r\n const result: Partial<SchemaOrgRecipe> = {};\r\n if (time.prepTime) {\r\n result.prepTime = time.prepTime;\r\n }\r\n if (time.cookTime) {\r\n result.cookTime = time.cookTime;\r\n }\r\n return result;\r\n}\r\n\r\nexport function convertYield(yld?: Recipe['yield']): string | undefined {\r\n if (!yld) {\r\n return undefined;\r\n }\r\n return formatYield(yld);\r\n}\r\n\r\nexport function convertAuthor(\r\n source?: Recipe['source']\r\n): Partial<SchemaOrgRecipe> {\r\n if (!source) {\r\n return {};\r\n }\r\n\r\n const result: Partial<SchemaOrgRecipe> = {};\r\n\r\n if (source.author) {\r\n result.author = {\r\n '@type': 'Person',\r\n name: source.author\r\n };\r\n }\r\n\r\n if (source.name) {\r\n result.publisher = {\r\n '@type': 'Organization',\r\n name: source.name\r\n };\r\n }\r\n\r\n if (source.url) {\r\n result.url = source.url;\r\n }\r\n\r\n return result;\r\n}\r\n\r\nexport function convertCategoryTags(\r\n category?: string,\r\n tags?: string[]\r\n): Partial<SchemaOrgRecipe> {\r\n const result: Partial<SchemaOrgRecipe> = {};\r\n\r\n if (category) {\r\n result.recipeCategory = category;\r\n }\r\n\r\n if (tags && tags.length > 0) {\r\n result.keywords = tags.filter(Boolean).join(', ');\r\n }\r\n\r\n return result;\r\n}\r\n\r\nexport function convertNutrition(\r\n nutrition?: Recipe['nutrition']\r\n): SchemaOrgRecipe['nutrition'] {\r\n if (!nutrition) {\r\n return undefined;\r\n }\r\n\r\n return {\r\n ...nutrition,\r\n '@type': 'NutritionInformation'\r\n };\r\n}\r\n\r\nexport function cleanOutput<T extends Record<string, unknown>>(obj: T): T {\r\n return Object.fromEntries(\r\n Object.entries(obj).filter(([, value]) => value !== undefined)\r\n ) as T;\r\n}\r\n\r\nexport function toSchemaOrg(recipe: Recipe): SchemaOrgRecipe {\r\n const base = convertBasicMetadata(recipe);\r\n const ingredients = convertIngredients(recipe.ingredients);\r\n const instructions = convertInstructions(recipe.instructions);\r\n const nutrition = convertNutrition(recipe.nutrition);\r\n\r\n return cleanOutput({\r\n ...base,\r\n recipeIngredient: ingredients.length ? ingredients : undefined,\r\n recipeInstructions: instructions.length ? instructions : undefined,\r\n recipeYield: convertYield(recipe.yield),\r\n ...convertTime(recipe.time),\r\n ...convertAuthor(recipe.source),\r\n ...convertCategoryTags(recipe.category, recipe.tags),\r\n nutrition\r\n }) as SchemaOrgRecipe;\r\n}\r\n\r\nfunction isStructuredTime(time: Time): time is StructuredTime {\r\n return (\r\n typeof (time as StructuredTime).prep !== 'undefined' ||\r\n typeof (time as StructuredTime).active !== 'undefined' ||\r\n typeof (time as StructuredTime).passive !== 'undefined' ||\r\n typeof (time as StructuredTime).total !== 'undefined'\r\n );\r\n}\r\n","import type { FetchImplementation, FetchOptions, FetchRequestInit } from './types';\r\n\r\nconst DEFAULT_USER_AGENTS = [\r\n 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',\r\n 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',\r\n 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:121.0) Gecko/20100101 Firefox/121.0'\r\n];\r\n\r\nfunction chooseUserAgent(provided?: string): string {\r\n if (provided) return provided;\r\n const index = Math.floor(Math.random() * DEFAULT_USER_AGENTS.length);\r\n return DEFAULT_USER_AGENTS[index];\r\n}\r\n\r\nfunction resolveFetch(fetchFn?: FetchImplementation): FetchImplementation {\r\n if (fetchFn) {\r\n return fetchFn;\r\n }\r\n\r\n const globalFetch = (globalThis as { fetch?: FetchImplementation }).fetch;\r\n if (!globalFetch) {\r\n throw new Error(\r\n 'A global fetch implementation is not available. Provide window.fetch in browsers or upgrade to Node 18+.'\r\n );\r\n }\r\n\r\n return globalFetch;\r\n}\r\n\r\nfunction isBrowserEnvironment(): boolean {\r\n return typeof (globalThis as { document?: unknown }).document !== 'undefined';\r\n}\r\n\r\nfunction isClientError(error: Error & { status?: number }): boolean {\r\n if (typeof error.status === 'number') {\r\n return error.status >= 400 && error.status < 500;\r\n }\r\n return error.message.includes('HTTP 4');\r\n}\r\n\r\nasync function wait(ms: number) {\r\n return new Promise(resolve => setTimeout(resolve, ms));\r\n}\r\n\r\nexport async function fetchPage(url: string, options: FetchOptions = {}): Promise<string> {\r\n const {\r\n timeout = 10_000,\r\n userAgent,\r\n maxRetries = 2,\r\n fetchFn\r\n } = options;\r\n\r\n let lastError: Error | null = null;\r\n const resolvedFetch = resolveFetch(fetchFn);\r\n const isBrowser = isBrowserEnvironment();\r\n\r\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\r\n const controller = new AbortController();\r\n const timeoutId = setTimeout(() => controller.abort(), timeout);\r\n\r\n try {\r\n const headers: Record<string, string> = {\r\n Accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',\r\n 'Accept-Language': 'en-US,en;q=0.5'\r\n };\r\n\r\n if (!isBrowser) {\r\n headers['User-Agent'] = chooseUserAgent(userAgent);\r\n }\r\n\r\n const requestInit: FetchRequestInit = {\r\n headers,\r\n signal: controller.signal,\r\n redirect: 'follow'\r\n };\r\n\r\n const response = await resolvedFetch(url, requestInit);\r\n\r\n clearTimeout(timeoutId);\r\n // #region agent log\r\n if (response && (typeof process === 'undefined' || process.env.NODE_ENV !== 'test')) {\r\n try {\r\n const globalFetch = typeof globalThis !== 'undefined' && typeof globalThis.fetch !== 'undefined' ? globalThis.fetch : null;\r\n if (globalFetch) {\r\n globalFetch('http://127.0.0.1:7243/ingest/7225c3b5-9ac2-4c94-b561-807ca9003b66',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'scraper/fetch.ts:63',message:'fetch response',data:{url,status:response.status,statusText:response.statusText,ok:response.ok,isNYTimes:url.includes('nytimes.com')},timestamp:Date.now(),sessionId:'debug-session',runId:'run1',hypothesisId:'B'})}).catch(()=>{});\r\n }\r\n } catch {}\r\n }\r\n // #endregion\r\n\r\n if (!response.ok) {\r\n const error: Error & { status?: number } = new Error(\r\n `HTTP ${response.status}: ${response.statusText}`\r\n );\r\n error.status = response.status;\r\n throw error;\r\n }\r\n\r\n const html = await response.text();\r\n // #region agent log\r\n if (typeof process === 'undefined' || process.env.NODE_ENV !== 'test') {\r\n try {\r\n const globalFetch = typeof globalThis !== 'undefined' && typeof globalThis.fetch !== 'undefined' ? globalThis.fetch : null;\r\n if (globalFetch) {\r\n globalFetch('http://127.0.0.1:7243/ingest/7225c3b5-9ac2-4c94-b561-807ca9003b66',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'scraper/fetch.ts:75',message:'HTML received',data:{htmlLength:html.length,hasLoginPage:html.toLowerCase().includes('login')||html.toLowerCase().includes('sign in'),hasRecipeData:html.includes('application/ld+json')||html.includes('schema.org/Recipe')},timestamp:Date.now(),sessionId:'debug-session',runId:'run1',hypothesisId:'B,D'})}).catch(()=>{});\r\n }\r\n } catch {}\r\n }\r\n // #endregion\r\n return html;\r\n } catch (err) {\r\n clearTimeout(timeoutId);\r\n\r\n lastError = err instanceof Error ? err : new Error(String(err));\r\n\r\n if (isClientError(lastError)) {\r\n throw lastError;\r\n }\r\n\r\n if (attempt < maxRetries) {\r\n await wait(1000 * (attempt + 1));\r\n continue;\r\n }\r\n }\r\n }\r\n\r\n throw lastError ?? new Error('Failed to fetch page');\r\n}\r\n\r\nexport { FetchOptions };\r\n","import type { SchemaOrgRecipe } from '../types';\r\n\r\nconst RECIPE_TYPES = new Set([\r\n 'recipe',\r\n 'https://schema.org/recipe',\r\n 'http://schema.org/recipe'\r\n]);\r\n\r\nexport function isRecipeNode(value: unknown): value is SchemaOrgRecipe {\r\n if (!value || typeof value !== 'object') {\r\n return false;\r\n }\r\n\r\n const type = (value as Record<string, unknown>)['@type'];\r\n // #region agent log\r\n fetch('http://127.0.0.1:7243/ingest/7225c3b5-9ac2-4c94-b561-807ca9003b66',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'scraper/extractors/utils.ts:14',message:'isRecipeNode check',data:{type,typeLower:typeof type==='string'?type.toLowerCase():Array.isArray(type)?type.map(t=>typeof t==='string'?t.toLowerCase():t):undefined,isMatch:typeof type==='string'?RECIPE_TYPES.has(type.toLowerCase()):Array.isArray(type)?type.some(e=>typeof e==='string'&&RECIPE_TYPES.has(e.toLowerCase())):false},timestamp:Date.now(),sessionId:'debug-session',runId:'run1',hypothesisId:'A'})}).catch(()=>{});\r\n // #endregion\r\n\r\n if (typeof type === 'string') {\r\n return RECIPE_TYPES.has(type.toLowerCase());\r\n }\r\n\r\n if (Array.isArray(type)) {\r\n return type.some(\r\n entry => typeof entry === 'string' && RECIPE_TYPES.has(entry.toLowerCase())\r\n );\r\n }\r\n\r\n return false;\r\n}\r\n\r\nexport function safeJsonParse<T = unknown>(content: string): T | null {\r\n try {\r\n return JSON.parse(content) as T;\r\n } catch {\r\n return null;\r\n }\r\n}\r\n\r\nexport function normalizeText(value: string | undefined | null): string | undefined {\r\n if (!value) return undefined;\r\n const trimmed = value.replace(/\\s+/g, ' ').trim();\r\n return trimmed || undefined;\r\n}\r\n","import { load } from 'cheerio';\r\nimport type { SchemaOrgRecipe } from '../types';\r\nimport { isRecipeNode, safeJsonParse } from './utils';\r\n\r\ntype JsonLdPayload = Record<string, unknown> | Array<Record<string, unknown>>;\r\n\r\nexport function extractJsonLd(html: string): SchemaOrgRecipe | null {\r\n const $ = load(html);\r\n const scripts = $('script[type=\"application/ld+json\"]');\r\n // #region agent log\r\n fetch('http://127.0.0.1:7243/ingest/7225c3b5-9ac2-4c94-b561-807ca9003b66',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'scraper/extractors/jsonld.ts:8',message:'JSON-LD scripts found',data:{scriptCount:scripts.length},timestamp:Date.now(),sessionId:'debug-session',runId:'run1',hypothesisId:'C,D'})}).catch(()=>{});\r\n // #endregion\r\n const candidates: SchemaOrgRecipe[] = [];\r\n\r\n scripts.each((_, element) => {\r\n const content = $(element).html();\r\n if (!content) return;\r\n\r\n const parsed = safeJsonParse<JsonLdPayload>(content);\r\n if (!parsed) return;\r\n // #region agent log\r\n fetch('http://127.0.0.1:7243/ingest/7225c3b5-9ac2-4c94-b561-807ca9003b66',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'scraper/extractors/jsonld.ts:18',message:'JSON-LD parsed',data:{hasGraph:!!(parsed&&typeof parsed==='object'&&'@graph' in parsed),type:(parsed&&typeof parsed==='object'&&'@type' in parsed)?(parsed as any)['@type']:undefined},timestamp:Date.now(),sessionId:'debug-session',runId:'run1',hypothesisId:'A,C'})}).catch(()=>{});\r\n // #endregion\r\n\r\n collectCandidates(parsed, candidates);\r\n });\r\n // #region agent log\r\n fetch('http://127.0.0.1:7243/ingest/7225c3b5-9ac2-4c94-b561-807ca9003b66',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'scraper/extractors/jsonld.ts:22',message:'JSON-LD candidates',data:{candidateCount:candidates.length,candidateTypes:candidates.map(c=>c['@type'])},timestamp:Date.now(),sessionId:'debug-session',runId:'run1',hypothesisId:'A,C'})}).catch(()=>{});\r\n // #endregion\r\n\r\n return candidates[0] ?? null;\r\n}\r\n\r\nfunction collectCandidates(payload: unknown, bucket: SchemaOrgRecipe[]) {\r\n if (!payload) return;\r\n\r\n if (Array.isArray(payload)) {\r\n payload.forEach(entry => collectCandidates(entry, bucket));\r\n return;\r\n }\r\n\r\n if (typeof payload !== 'object') {\r\n return;\r\n }\r\n\r\n if (isRecipeNode(payload)) {\r\n bucket.push(payload);\r\n return;\r\n }\r\n\r\n const graph = (payload as Record<string, unknown>)['@graph'];\r\n if (Array.isArray(graph)) {\r\n graph.forEach(entry => collectCandidates(entry, bucket));\r\n }\r\n}\r\n","import { load, type CheerioAPI, type Cheerio } from 'cheerio';\r\nimport type { SchemaOrgRecipe } from '../types';\r\nimport { normalizeText } from './utils';\r\n\r\nconst SIMPLE_PROPS = [\r\n 'name',\r\n 'description',\r\n 'image',\r\n 'recipeYield',\r\n 'prepTime',\r\n 'cookTime',\r\n 'totalTime'\r\n] as const;\r\n\r\nexport function extractMicrodata(html: string): SchemaOrgRecipe | null {\r\n const $ = load(html);\r\n const recipeEl = $('[itemscope][itemtype*=\"schema.org/Recipe\"]').first();\r\n\r\n if (!recipeEl.length) {\r\n return null;\r\n }\r\n\r\n const recipe: SchemaOrgRecipe = {\r\n '@type': 'Recipe'\r\n };\r\n\r\n SIMPLE_PROPS.forEach(prop => {\r\n const value = findPropertyValue($, recipeEl, prop);\r\n if (value) {\r\n recipe[prop] = value;\r\n }\r\n });\r\n\r\n const ingredients: string[] = [];\r\n recipeEl.find('[itemprop=\"recipeIngredient\"]').each((_, el) => {\r\n const text = normalizeText($(el).attr('content') || $(el).text());\r\n if (text) ingredients.push(text);\r\n });\r\n\r\n if (ingredients.length) {\r\n recipe.recipeIngredient = ingredients;\r\n }\r\n\r\n const instructions: string[] = [];\r\n recipeEl.find('[itemprop=\"recipeInstructions\"]').each((_, el) => {\r\n const text =\r\n normalizeText($(el).attr('content')) ||\r\n normalizeText($(el).find('[itemprop=\"text\"]').first().text()) ||\r\n normalizeText($(el).text());\r\n if (text) instructions.push(text);\r\n });\r\n\r\n if (instructions.length) {\r\n recipe.recipeInstructions = instructions;\r\n }\r\n\r\n if (recipe.name || ingredients.length) {\r\n return recipe;\r\n }\r\n\r\n return null;\r\n}\r\n\r\nfunction findPropertyValue($: CheerioAPI, context: Cheerio<any>, prop: string): string | undefined {\r\n const node = context.find(`[itemprop=\"${prop}\"]`).first();\r\n if (!node.length) return undefined;\r\n\r\n return (\r\n normalizeText(node.attr('content')) ||\r\n normalizeText(node.attr('href')) ||\r\n normalizeText(node.attr('src')) ||\r\n normalizeText(node.text())\r\n );\r\n}\r\n","import type { ExtractionResult, SchemaOrgRecipe } from '../types';\r\nimport { isRecipeNode, safeJsonParse, normalizeText } from './utils';\r\n\r\ntype JsonLdPayload = Record<string, unknown> | Array<Record<string, unknown>>;\r\n\r\nconst SIMPLE_PROPS = ['name', 'description', 'image', 'recipeYield', 'prepTime', 'cookTime', 'totalTime'] as const;\r\n\r\nexport function extractRecipeBrowser(html: string): ExtractionResult {\r\n // Extract JSON-LD\r\n const jsonLdRecipe = extractJsonLdBrowser(html);\r\n if (jsonLdRecipe) {\r\n return { recipe: jsonLdRecipe, source: 'jsonld' };\r\n }\r\n\r\n // Extract Microdata\r\n const microdataRecipe = extractMicrodataBrowser(html);\r\n if (microdataRecipe) {\r\n return { recipe: microdataRecipe, source: 'microdata' };\r\n }\r\n\r\n return { recipe: null, source: null };\r\n}\r\n\r\nfunction extractJsonLdBrowser(html: string): SchemaOrgRecipe | null {\r\n if (typeof (globalThis as any).DOMParser === 'undefined') {\r\n return null;\r\n }\r\n\r\n const parser = new (globalThis as any).DOMParser();\r\n const doc = parser.parseFromString(html, 'text/html');\r\n const scripts = doc.querySelectorAll('script[type=\"application/ld+json\"]');\r\n const candidates: SchemaOrgRecipe[] = [];\r\n\r\n scripts.forEach((script: Element) => {\r\n const content = script.textContent;\r\n if (!content) return;\r\n\r\n const parsed = safeJsonParse<JsonLdPayload>(content);\r\n if (!parsed) return;\r\n\r\n collectCandidates(parsed, candidates);\r\n });\r\n\r\n return candidates[0] ?? null;\r\n}\r\n\r\nfunction extractMicrodataBrowser(html: string): SchemaOrgRecipe | null {\r\n if (typeof (globalThis as any).DOMParser === 'undefined') {\r\n return null;\r\n }\r\n\r\n const parser = new (globalThis as any).DOMParser();\r\n const doc = parser.parseFromString(html, 'text/html');\r\n const recipeEl = doc.querySelector('[itemscope][itemtype*=\"schema.org/Recipe\"]');\r\n\r\n if (!recipeEl) {\r\n return null;\r\n }\r\n\r\n const recipe: SchemaOrgRecipe = {\r\n '@type': 'Recipe'\r\n };\r\n\r\n SIMPLE_PROPS.forEach(prop => {\r\n const value = findPropertyValue(recipeEl, prop);\r\n if (value) {\r\n recipe[prop] = value;\r\n }\r\n });\r\n\r\n const ingredients: string[] = [];\r\n recipeEl.querySelectorAll('[itemprop=\"recipeIngredient\"]').forEach((el: Element) => {\r\n const text = normalizeText(\r\n (el as any).getAttribute('content') || el.textContent || undefined\r\n );\r\n if (text) ingredients.push(text);\r\n });\r\n\r\n if (ingredients.length) {\r\n recipe.recipeIngredient = ingredients;\r\n }\r\n\r\n const instructions: string[] = [];\r\n recipeEl.querySelectorAll('[itemprop=\"recipeInstructions\"]').forEach((el: Element) => {\r\n const text =\r\n normalizeText((el as any).getAttribute('content')) ||\r\n normalizeText(el.querySelector('[itemprop=\"text\"]')?.textContent || undefined) ||\r\n normalizeText(el.textContent || undefined);\r\n if (text) instructions.push(text);\r\n });\r\n\r\n if (instructions.length) {\r\n recipe.recipeInstructions = instructions;\r\n }\r\n\r\n if (recipe.name || ingredients.length) {\r\n return recipe;\r\n }\r\n\r\n return null;\r\n}\r\n\r\nfunction findPropertyValue(context: Element, prop: string): string | undefined {\r\n const node = context.querySelector(`[itemprop=\"${prop}\"]`);\r\n if (!node) return undefined;\r\n\r\n return (\r\n normalizeText((node as any).getAttribute('content')) ||\r\n normalizeText((node as any).getAttribute('href')) ||\r\n normalizeText((node as any).getAttribute('src')) ||\r\n normalizeText(node.textContent || undefined)\r\n );\r\n}\r\n\r\nfunction collectCandidates(payload: unknown, bucket: SchemaOrgRecipe[]) {\r\n if (!payload) return;\r\n\r\n if (Array.isArray(payload)) {\r\n payload.forEach(entry => collectCandidates(entry, bucket));\r\n return;\r\n }\r\n\r\n if (typeof payload !== 'object') {\r\n return;\r\n }\r\n\r\n if (isRecipeNode(payload)) {\r\n bucket.push(payload);\r\n return;\r\n }\r\n\r\n const graph = (payload as Record<string, unknown>)['@graph'];\r\n if (Array.isArray(graph)) {\r\n graph.forEach(entry => collectCandidates(entry, bucket));\r\n }\r\n}\r\n\r\n","import type { ExtractionResult } from '../types';\r\nimport { extractJsonLd } from './jsonld';\r\nimport { extractMicrodata } from './microdata';\r\nimport { extractRecipeBrowser } from './browser';\r\n\r\nfunction isBrowser(): boolean {\r\n try {\r\n // Check if we're in a browser environment with DOMParser\r\n return typeof (globalThis as any).DOMParser !== 'undefined';\r\n } catch {\r\n return false;\r\n }\r\n}\r\n\r\nexport function extractRecipe(html: string): ExtractionResult {\r\n // Use browser-compatible extraction if DOMParser is available\r\n if (isBrowser()) {\r\n return extractRecipeBrowser(html);\r\n }\r\n \r\n // Fallback to cheerio-based extraction for Node.js\r\n const jsonLdRecipe = extractJsonLd(html);\r\n // #region agent log\r\n fetch('http://127.0.0.1:7243/ingest/7225c3b5-9ac2-4c94-b561-807ca9003b66',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'scraper/extractors/index.ts:6',message:'JSON-LD extraction result',data:{hasJsonLd:!!jsonLdRecipe},timestamp:Date.now(),sessionId:'debug-session',runId:'run1',hypothesisId:'C,D'})}).catch(()=>{});\r\n // #endregion\r\n if (jsonLdRecipe) {\r\n return { recipe: jsonLdRecipe, source: 'jsonld' };\r\n }\r\n\r\n const microdataRecipe = extractMicrodata(html);\r\n // #region agent log\r\n fetch('http://127.0.0.1:7243/ingest/7225c3b5-9ac2-4c94-b561-807ca9003b66',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'scraper/extractors/index.ts:12',message:'Microdata extraction result',data:{hasMicrodata:!!microdataRecipe},timestamp:Date.now(),sessionId:'debug-session',runId:'run1',hypothesisId:'D'})}).catch(()=>{});\r\n // #endregion\r\n if (microdataRecipe) {\r\n return { recipe: microdataRecipe, source: 'microdata' };\r\n }\r\n\r\n return { recipe: null, source: null };\r\n}\r\n","import { fromSchemaOrg } from '../fromSchemaOrg';\r\nimport type { Recipe } from '../types';\r\nimport { fetchPage } from './fetch';\r\nimport { extractRecipe } from './extractors';\r\nimport type { ScrapeRecipeOptions } from './types';\r\n\r\n/**\r\n * Scrapes a recipe from a URL (Node.js only).\r\n * \r\n * ⚠️ Not available in browser environments due to CORS restrictions.\r\n * For browser usage, fetch the HTML yourself and use extractRecipeFromHTML().\r\n * \r\n * @param url - The URL of the recipe page to scrape\r\n * @param options - Fetch options (timeout, userAgent, maxRetries)\r\n * @returns A Soustack recipe object\r\n * @throws Error if no recipe is found\r\n */\r\nexport async function scrapeRecipe(url: string, options: ScrapeRecipeOptions = {}): Promise<Recipe> {\r\n // #region agent log\r\n fetch('http://127.0.0.1:7243/ingest/7225c3b5-9ac2-4c94-b561-807ca9003b66',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'scraper/index.ts:7',message:'scrapeRecipe entry',data:{url,hasOptions:!!options},timestamp:Date.now(),sessionId:'debug-session',runId:'run1',hypothesisId:'A,B,C,D,E'})}).catch(()=>{});\r\n // #endregion\r\n const html = await fetchPage(url, options);\r\n // #region agent log\r\n fetch('http://127.0.0.1:7243/ingest/7225c3b5-9ac2-4c94-b561-807ca9003b66',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'scraper/index.ts:9',message:'HTML fetched',data:{htmlLength:html?.length,htmlPreview:html?.substring(0,200)},timestamp:Date.now(),sessionId:'debug-session',runId:'run1',hypothesisId:'B'})}).catch(()=>{});\r\n // #endregion\r\n const { recipe } = extractRecipe(html);\r\n // #region agent log\r\n fetch('http://127.0.0.1:7243/ingest/7225c3b5-9ac2-4c94-b561-807ca9003b66',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'scraper/index.ts:11',message:'extractRecipe result',data:{hasRecipe:!!recipe,recipeType:recipe?.['@type'],recipeName:recipe?.name},timestamp:Date.now(),sessionId:'debug-session',runId:'run1',hypothesisId:'A,C,D'})}).catch(()=>{});\r\n // #endregion\r\n\r\n if (!recipe) {\r\n throw new Error('No Schema.org recipe data found in page');\r\n }\r\n\r\n const soustackRecipe = fromSchemaOrg(recipe);\r\n // #region agent log\r\n fetch('http://127.0.0.1:7243/ingest/7225c3b5-9ac2-4c94-b561-807ca9003b66',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'scraper/index.ts:17',message:'fromSchemaOrg result',data:{hasSoustackRecipe:!!soustackRecipe,soustackRecipeName:soustackRecipe?.name},timestamp:Date.now(),sessionId:'debug-session',runId:'run1',hypothesisId:'A'})}).catch(()=>{});\r\n // #endregion\r\n if (!soustackRecipe) {\r\n throw new Error('Schema.org data did not include a valid recipe');\r\n }\r\n\r\n return soustackRecipe;\r\n}\r\n\r\n/**\r\n * Extracts a recipe from HTML string (browser and Node.js compatible).\r\n * \r\n * This function works in both environments and doesn't require network access.\r\n * Perfect for browser usage where you fetch HTML yourself (with cookies/session).\r\n * \r\n * @example\r\n * ```ts\r\n * // In browser:\r\n * const response = await fetch('https://example.com/recipe');\r\n * const html = await response.text();\r\n * const recipe = extractRecipeFromHTML(html);\r\n * ```\r\n * \r\n * @param html - The HTML string containing Schema.org recipe data\r\n * @returns A Soustack recipe object\r\n * @throws Error if no recipe is found\r\n */\r\nexport function extractRecipeFromHTML(html: string): Recipe {\r\n const { recipe } = extractRecipe(html);\r\n\r\n if (!recipe) {\r\n throw new Error('No Schema.org recipe data found in HTML');\r\n }\r\n\r\n const soustackRecipe = fromSchemaOrg(recipe);\r\n if (!soustackRecipe) {\r\n throw new Error('Schema.org data did not include a valid recipe');\r\n }\r\n\r\n return soustackRecipe;\r\n}\r\n","import { ParsedYield } from '../types';\r\n\r\nconst RANGE_PATTERN = /^(\\d+)(?:\\s*(?:[-–—]|to)\\s*)(\\d+)\\s+(.+)$/i;\r\nconst MAKES_PREFIX = /^(makes?|yields?)\\s*:?\\s*(.+)$/i;\r\nconst APPROX_PREFIX = /^(about|around|approximately|approx\\.?|roughly)\\s+/i;\r\nconst SERVING_UNITS = ['servings', 'serving', 'portions', 'portion', 'people', 'persons'];\r\nconst DEFAULT_DOZEN_UNIT = 'cookies';\r\n\r\nconst NUMBER_WORDS: Record<string, number> = {\r\n a: 1,\r\n an: 1,\r\n one: 1,\r\n two: 2,\r\n three: 3,\r\n four: 4,\r\n five: 5,\r\n six: 6,\r\n seven: 7,\r\n eight: 8,\r\n nine: 9,\r\n ten: 10,\r\n eleven: 11,\r\n twelve: 12\r\n};\r\n\r\nexport function normalizeYield(text: string): string {\r\n if (!text || typeof text !== 'string') return '';\r\n return text\r\n .normalize('NFKC')\r\n .replace(/\\u00A0/g, ' ')\r\n .replace(/[–—−]/g, '-')\r\n .trim()\r\n .replace(/\\s+/g, ' ');\r\n}\r\n\r\nexport function parseYield(text: string): ParsedYield | null {\r\n const normalized = normalizeYield(text);\r\n if (!normalized) return null;\r\n\r\n const { main, paren } = extractParenthetical(normalized);\r\n const core = parseYieldCore(main, normalized);\r\n if (!core) return null;\r\n\r\n const servingsFromParen = paren ? extractServingsFromParen(paren) : null;\r\n if (servingsFromParen !== null) {\r\n core.servings = servingsFromParen;\r\n core.description = normalized;\r\n }\r\n\r\n if (core.servings === undefined) {\r\n const inferred = inferServings(core.amount, core.unit);\r\n if (inferred !== undefined) {\r\n core.servings = inferred;\r\n }\r\n }\r\n\r\n return core;\r\n}\r\n\r\nexport function formatYield(value: ParsedYield): string {\r\n if (value.description) {\r\n return value.description;\r\n }\r\n\r\n if (value.servings && value.unit === 'servings') {\r\n return `Serves ${value.amount}`;\r\n }\r\n\r\n let result = `${value.amount} ${value.unit}`.trim();\r\n if (value.servings && value.unit !== 'servings') {\r\n result += ` (${value.servings} servings)`;\r\n }\r\n\r\n return result;\r\n}\r\n\r\nfunction parseYieldCore(text: string, original: string): ParsedYield | null {\r\n return (\r\n parseServesPattern(text, original) ??\r\n parseMakesPattern(text, original) ??\r\n parseRangePattern(text, original) ??\r\n parseNumberUnitPattern(text, original) ??\r\n parsePlainNumberPattern(text)\r\n );\r\n}\r\n\r\nfunction parseServesPattern(text: string, original: string): ParsedYield | null {\r\n const patterns = [\r\n /^serves?\\s*[:\\-]?\\s*(\\d+)(?:\\s*(?:[-–—]|to)\\s*(\\d+))?/i,\r\n /^servings?\\s*[:\\-]?\\s*(\\d+)(?:\\s*(?:[-–—]|to)\\s*(\\d+))?/i,\r\n /^serving\\s*[:\\-]?\\s*(\\d+)(?:\\s*(?:[-–—]|to)\\s*(\\d+))?/i,\r\n /^makes?\\s*[:\\-]?\\s*(\\d+)(?:\\s*(?:[-–—]|to)\\s*(\\d+))?\\s+servings?$/i,\r\n /^(\\d+)\\s+servings?$/i\r\n ];\r\n\r\n for (const regex of patterns) {\r\n const match = text.match(regex);\r\n if (!match) continue;\r\n const amount = parseInt(match[1], 10);\r\n if (Number.isNaN(amount)) continue;\r\n const result: ParsedYield = {\r\n amount,\r\n unit: 'servings',\r\n servings: amount\r\n };\r\n if (match[2]) {\r\n result.description = original;\r\n }\r\n return result;\r\n }\r\n\r\n return null;\r\n}\r\n\r\nfunction parseMakesPattern(text: string, original: string): ParsedYield | null {\r\n const match = text.match(MAKES_PREFIX);\r\n if (!match) return null;\r\n const remainder = match[2].trim();\r\n if (!remainder) return null;\r\n\r\n const servingsMatch = remainder.match(/^(\\d+)(?:\\s*(?:[-–—]|to)\\s*(\\d+))?\\s+servings?$/i);\r\n if (servingsMatch) {\r\n const amount = parseInt(servingsMatch[1], 10);\r\n const result: ParsedYield = {\r\n amount,\r\n unit: 'servings',\r\n servings: amount\r\n };\r\n if (servingsMatch[2]) {\r\n result.description = original;\r\n }\r\n return result;\r\n }\r\n\r\n return (\r\n parseRangePattern(remainder, original) ??\r\n parseNumberUnitPattern(remainder, original) ??\r\n parsePlainNumberPattern(remainder)\r\n );\r\n}\r\n\r\nfunction parseRangePattern(text: string, descriptionSource: string): ParsedYield | null {\r\n const match = text.match(RANGE_PATTERN);\r\n if (!match) return null;\r\n const amount = parseInt(match[1], 10);\r\n const unit = cleanupUnit(match[3]);\r\n if (!unit) return null;\r\n const result: ParsedYield = {\r\n amount,\r\n unit,\r\n description: descriptionSource\r\n };\r\n return result;\r\n}\r\n\r\nfunction parseNumberUnitPattern(text: string, descriptionSource: string): ParsedYield | null {\r\n if (!text) return null;\r\n const { value, approximate } = stripApproximation(text);\r\n if (!value) return null;\r\n\r\n const dozenResult = handleDozen(value);\r\n if (dozenResult) {\r\n const unit = cleanupUnit(dozenResult.remainder || DEFAULT_DOZEN_UNIT);\r\n const parsed: ParsedYield = {\r\n amount: dozenResult.amount,\r\n unit\r\n };\r\n if (approximate) {\r\n parsed.description = descriptionSource;\r\n }\r\n return parsed;\r\n }\r\n\r\n const numericMatch = value.match(/^(\\d+(?:\\.\\d+)?)\\s+(.+)$/);\r\n if (numericMatch) {\r\n const amount = parseFloat(numericMatch[1]);\r\n if (!Number.isNaN(amount)) {\r\n const unit = cleanupUnit(numericMatch[2]);\r\n if (unit) {\r\n const parsed: ParsedYield = { amount, unit };\r\n if (approximate) {\r\n parsed.description = descriptionSource;\r\n }\r\n return parsed;\r\n }\r\n }\r\n }\r\n\r\n const wordMatch = value.match(/^([a-zA-Z]+)\\s+(.+)$/);\r\n if (wordMatch) {\r\n const amount = wordToNumber(wordMatch[1]);\r\n if (amount !== null) {\r\n const unit = cleanupUnit(wordMatch[2]);\r\n if (unit) {\r\n const parsed: ParsedYield = { amount, unit };\r\n if (approximate) {\r\n parsed.description = descriptionSource;\r\n }\r\n return parsed;\r\n }\r\n }\r\n }\r\n\r\n return null;\r\n}\r\n\r\nfunction parsePlainNumberPattern(text: string): ParsedYield | null {\r\n const match = text.match(/^(\\d+)$/);\r\n if (!match) return null;\r\n const amount = parseInt(match[1], 10);\r\n if (Number.isNaN(amount)) return null;\r\n return {\r\n amount,\r\n unit: 'servings',\r\n servings: amount\r\n };\r\n}\r\n\r\nfunction stripApproximation(value: string): { value: string; approximate: boolean } {\r\n const match = value.match(APPROX_PREFIX);\r\n if (!match) {\r\n return { value: value.trim(), approximate: false };\r\n }\r\n const stripped = value.slice(match[0].length).trim();\r\n return { value: stripped, approximate: true };\r\n}\r\n\r\nfunction handleDozen(text: string): { amount: number; remainder: string } | null {\r\n const match = text.match(\r\n /^((?:\\d+(?:\\.\\d+)?)|(?:one|two|three|four|five|six|seven|eight|nine|ten|eleven|twelve|a|an|half))\\s+dozens?\\b(.*)$/i\r\n );\r\n if (!match) return null;\r\n const token = match[1].toLowerCase();\r\n let multiplier: number | null = null;\r\n if (token === 'half') {\r\n multiplier = 0.5;\r\n } else if (!Number.isNaN(Number(token))) {\r\n multiplier = parseFloat(token);\r\n } else {\r\n multiplier = wordToNumber(token);\r\n }\r\n if (multiplier === null) return null;\r\n const amount = multiplier * 12;\r\n return {\r\n amount,\r\n remainder: match[2].trim()\r\n };\r\n}\r\n\r\nfunction cleanupUnit(value: string): string {\r\n let unit = value.trim();\r\n unit = unit.replace(/^[,.-]+/, '').trim();\r\n unit = unit.replace(/[.,]+$/, '').trim();\r\n unit = unit.replace(/^of\\s+/i, '').trim();\r\n return unit;\r\n}\r\n\r\nfunction extractParenthetical(text: string): { main: string; paren: string | null } {\r\n const match = text.match(/^(.+?)\\s*\\(([^)]+)\\)\\s*$/);\r\n if (!match) {\r\n return { main: text, paren: null };\r\n }\r\n return {\r\n main: match[1].trim(),\r\n paren: match[2].trim()\r\n };\r\n}\r\n\r\nfunction extractServingsFromParen(text: string): number | null {\r\n const match = text.match(/(\\d+)/);\r\n if (!match) return null;\r\n const value = parseInt(match[1], 10);\r\n return Number.isNaN(value) ? null : value;\r\n}\r\n\r\nfunction inferServings(amount: number, unit: string): number | undefined {\r\n if (SERVING_UNITS.includes(unit.toLowerCase())) {\r\n return amount;\r\n }\r\n return undefined;\r\n}\r\n\r\nfunction wordToNumber(word: string): number | null {\r\n const normalized = word.toLowerCase();\r\n if (NUMBER_WORDS.hasOwnProperty(normalized)) {\r\n return NUMBER_WORDS[normalized];\r\n }\r\n return null;\r\n}\r\n"]}
|