recipe
Recipe, cooking, food and nutrition capability pack: find recipes from the ingredients you already have (fromIngredients / pantry / what-can-I-make), full-text recipe search by...
recipe — Leumas2 domain adapter pack
Recipe / cooking / food & nutrition capability. Find what you can cook from a pantry, search and scale recipes, estimate calories and macros, build grocery lists, swap ingredients, match cocktails, and plan meals — all from a small built-in dataset. Pure JavaScript, zero npm dependencies (Node built-ins only).
Tools
| Tool | Input (one args object) | Returns | |
|---|---|---|---|
fromIngredients | { have:[...], limit?, diet? } | Recipes ranked by how many of their ingredients you already have, with missing lists. | |
search | { query, diet?, limit? } | Recipes matching name/cuisine/course/diet/tag. | |
getRecipe | { id } (or { recipe }) | Full recipe (ingredients + steps + timing). | |
scale | `{ recipe\ | id, servings }` | Ingredient quantities scaled to the target serving count. |
nutritionEstimate | { ingredients:[...] } | Total kcal + protein/carbs/fat, per-line breakdown, unknowns. | |
shoppingList | { recipes:[...], servings? } | One aggregated grocery list across several recipes. | |
substitute | { ingredient } | Swaps (vegan / gluten-free / dairy-free / allergy alternatives). | |
cocktail | { have:[...] } or { spirit } | Cocktails/mocktails matched by mixers you have, or by base spirit. | |
mealPlan | { days?, diet?, seed? } | Multi-day breakfast/lunch/dinner plan with rough per-day kcal. | |
listRecipes | { limit? } | Catalog of all recipes. | |
listIngredients | {} | The per-100g nutrition table. | |
randomRecipe | { diet?, seed? } | A random (optionally seeded) recipe. |
ingredients accept either objects ({ item, qty, unit }) or strings ("200g rice", "2 egg"). fromIngredients/cocktail take bare names (["egg","pasta","cheese"], ["rum","lime"]). Randomized tools (mealPlan, randomRecipe, cocktail by spirit) accept an optional numeric seed for reproducible output. Every tool takes ONE args object (an HTTP POST body maps 1:1).
Usage
import recipe from './index.js';
recipe.adapters.fromIngredients({ have: ['egg', 'pasta', 'bacon', 'cheese'] });
// → matches Spaghetti Carbonara at high coverage, lists what's missing
recipe.adapters.scale({ id: 'lentil-soup', servings: 8 }); // doubles a 4-serving recipe
recipe.adapters.nutritionEstimate({ ingredients: ['200g rice', '2 egg', '100g chicken breast'] });
recipe.adapters.shoppingList({ recipes: ['beef-tacos', 'chickpea-curry'] });
recipe.adapters.substitute({ ingredient: 'butter' }); // → olive oil, coconut oil, …
recipe.adapters.cocktail({ have: ['rum', 'lime', 'mint', 'sugar', 'soda'] }); // → Mojito
recipe.adapters.mealPlan({ days: 3, diet: 'vegan', seed: 7 });
Dataset (data/dataset.json)
- recipes — 12 recipes across cuisines/courses, each with ingredients (item/qty/unit) + steps.
- nutrition — ~40 ingredients with per-100g kcal + protein/carbs/fat + diet tags.
- cocktails — 12 drinks (incl. 2 mocktails) with spirit, ingredients, and method.
- substitutions — swap lists for 15 common ingredients.
- units — grams-per-unit (egg=50g, clove=5g, …) and ml-per-unit for gram/nutrition math.
DRY boundary
This is a new capability — nothing else in shared/engines/adapters/domain/ owns food/recipes. It deliberately does not overlap:
numbers— generic scalar/unit math. The gram/nutrition math here is food-specific (grams-per-egg,
kcal-per-100g) and only meaningful alongside recipes, so it lives here, not in numbers.
finance/invoice— money, not groceries.calendar/datetime— dates, not meal plans.nlp— general text;searchhere is a domain filter over the recipe set.
If a different product needs richer culinary data, extend data/dataset.json — keep the pack pure.
Not medical or dietary advice. Nutrition figures are rough estimates from a small built-in table.