Skip to content

luckyrantanplan/meal-planner

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

34 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

๐Ÿฝ๏ธ Meal Planner

A TypeScript library for planning recipes, meals, weekly menus, and generating grocery lists with ingredient normalization for French cuisine.

Features

  • Recipe Management โ€” Parse, store, and scale recipes by serving count
  • Ingredient Matching โ€” Fuzzy string matching to identify ingredients across recipes and store sections
  • French Language Support โ€” Automatic plural-to-singular normalization for French ingredient names
  • Weekly Meal Planning โ€” Organize meals into structured weekly plans with lunch and dinner
  • Shopping List Generation โ€” Aggregate ingredients across all meals into a consolidated, section-organized grocery list
  • Recipe Filtering โ€” Filter recipes by type (entrรฉe, plat, dessert, etc.)

Getting Started

Prerequisites

  • Node.js >= 18
  • npm >= 9

Installation

npm install

Build

npm run build

Run Tests

npm test

Lint

npm run lint

Web Frontend

Start the web server to access the meal planning UI in your browser:

npm run build
npm run serve

Then open http://localhost:3000. The web frontend provides:

  • ๐Ÿ“– Recipes โ€” Add, view, and delete recipes with ingredients
  • ๐Ÿ“… Meal Plan โ€” Assign recipes to lunch/dinner for each day of the week
  • ๐Ÿ›’ Shopping List โ€” Generate a consolidated grocery list from the current meal plan

Set a custom port with the PORT environment variable: PORT=8080 npm run serve

Usage

import {
  IngredientFinder,
  createWeeklyPlan,
  generateShoppingList,
  formatShoppingList,
  scaleRecipe,
} from 'meal-planner';

// Create an ingredient finder for fuzzy matching
const finder = new IngredientFinder([
  { name: 'carotte', rayon: 'lรฉgumes' },
  { name: 'pomme de terre', rayon: 'lรฉgumes' },
  { name: 'sel', rayon: 'condiments' },
]);

// Find the best match for a misspelled ingredient
console.log(finder.find('carottes')); // โ†’ 'carotte'

// Scale a recipe to different servings
const recipe = {
  id: '1',
  title: 'Gratin dauphinois',
  type: 'plat',
  person_count: 4,
  ingredients: [
    { name: 'pomme de terre', quantity: 800, unit: 'g' },
    { name: 'crรจme fraรฎche', quantity: 200, unit: 'ml' },
  ],
  instructions: 'ร‰plucher les pommes de terre...',
};
const scaled = scaleRecipe(recipe, 6); // Scale to 6 servings

// Generate a shopping list from a weekly plan
const plan = createWeeklyPlan(meals, 4);
const shoppingList = generateShoppingList(plan, courseIngredients);
console.log(formatShoppingList(shoppingList));

Project Structure

src/
โ”œโ”€โ”€ index.ts           # Public API exports
โ”œโ”€โ”€ types.ts           # TypeScript type definitions
โ”œโ”€โ”€ utils.ts           # Utility functions (name normalization, measurement parsing)
โ”œโ”€โ”€ ingredients.ts     # Ingredient finding, parsing, and merging
โ”œโ”€โ”€ recipes.ts         # Recipe parsing, scaling, and filtering
โ”œโ”€โ”€ meal-plan.ts       # Weekly meal planning and shopping list generation
โ”œโ”€โ”€ server.ts          # Express web server with REST API
โ”œโ”€โ”€ utils.test.ts      # Tests for utility functions
โ”œโ”€โ”€ ingredients.test.ts # Tests for ingredient logic
โ”œโ”€โ”€ recipes.test.ts    # Tests for recipe logic
โ”œโ”€โ”€ meal-plan.test.ts  # Tests for meal planning and shopping lists
โ””โ”€โ”€ server.test.ts     # Tests for the web server API
web/
โ””โ”€โ”€ index.html         # Single-page web frontend

Data Files

  • dico.json โ€” French plural-to-singular word dictionary used for ingredient name normalization
  • exampleMenu.js โ€” Sample menu data from the La Fabrique ร  Menus service
  • cliqual/ โ€” CIQUAL French food composition database (nutritional reference data)
  • createDict.js โ€” Script to regenerate dico.json from the DELA French dictionary XML

API Reference

normalizeName(name: string): string

Normalize a French ingredient name by converting plurals to singular form.

getMeasure(quantity: string | number): number

Parse a numeric quantity from a value that may contain HTML entities.

IngredientFinder

Class that matches ingredient names using exact or fuzzy string matching.

  • constructor(courseIngredients: CourseIngredient[]) โ€” Initialize with known ingredients
  • find(ingredient: string): string โ€” Find the best matching ingredient name

scaleRecipe(recipe: Recipe, targetServings: number): RecipeIngredient[]

Scale recipe ingredients to a different number of servings.

filterRecipesByType(recipes: Recipe[], type: string): Recipe[]

Filter recipes by type (case-insensitive, partial match).

createWeeklyPlan(meals: Meal[], personCount: number): WeeklyPlan

Create a structured weekly meal plan from a list of meals.

generateShoppingList(plan: WeeklyPlan, courseIngredients: CourseIngredient[]): ShoppingList

Generate a consolidated shopping list from a weekly meal plan.

formatShoppingList(shoppingList: ShoppingList): string

Format a shopping list as human-readable text organized by store section.

License

GPL-3.0 โ€” see LICENSE for details.

About

soft for recipes, meal, menus, grocery list and stock management

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors