healthy-meals-core 0.0.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.
Files changed (83) hide show
  1. package/dist/bmr.d.ts +3 -0
  2. package/dist/bmr.js +14 -0
  3. package/dist/dailyMealPlanGenerator.d.ts +3 -0
  4. package/dist/dailyMealPlanGenerator.js +211 -0
  5. package/dist/data/detailed-recipes-bs.json +417 -0
  6. package/dist/data/detailed-recipes.json +744 -0
  7. package/dist/foodConversion.d.ts +55 -0
  8. package/dist/foodConversion.js +200 -0
  9. package/dist/index.d.ts +12 -0
  10. package/dist/index.js +27 -0
  11. package/dist/planner.d.ts +2 -0
  12. package/dist/planner.js +24 -0
  13. package/dist/recipeBasedMealPlanGenerator.d.ts +17 -0
  14. package/dist/recipeBasedMealPlanGenerator.js +255 -0
  15. package/dist/recipeService.d.ts +28 -0
  16. package/dist/recipeService.js +136 -0
  17. package/dist/rules/cholesterol.d.ts +2 -0
  18. package/dist/rules/cholesterol.js +7 -0
  19. package/dist/rules/diabetes.d.ts +2 -0
  20. package/dist/rules/diabetes.js +7 -0
  21. package/dist/rules/fattyLiver.d.ts +2 -0
  22. package/dist/rules/fattyLiver.js +7 -0
  23. package/dist/rules/index.d.ts +7 -0
  24. package/dist/rules/index.js +47 -0
  25. package/dist/rules/lowCarb.d.ts +2 -0
  26. package/dist/rules/lowCarb.js +7 -0
  27. package/dist/rules/triglycerides.d.ts +2 -0
  28. package/dist/rules/triglycerides.js +7 -0
  29. package/dist/src/bmr.d.ts +3 -0
  30. package/dist/src/bmr.js +13 -0
  31. package/dist/src/dailyMealPlanGenerator.d.ts +3 -0
  32. package/dist/src/dailyMealPlanGenerator.js +210 -0
  33. package/dist/src/foodConversion.d.ts +55 -0
  34. package/dist/src/foodConversion.js +199 -0
  35. package/dist/src/index.d.ts +12 -0
  36. package/dist/src/index.js +27 -0
  37. package/dist/src/planner.d.ts +2 -0
  38. package/dist/src/planner.js +23 -0
  39. package/dist/src/recipeBasedMealPlanGenerator.d.ts +17 -0
  40. package/dist/src/recipeBasedMealPlanGenerator.js +254 -0
  41. package/dist/src/recipeService.d.ts +28 -0
  42. package/dist/src/recipeService.js +136 -0
  43. package/dist/src/rules/cholesterol.d.ts +2 -0
  44. package/dist/src/rules/cholesterol.js +6 -0
  45. package/dist/src/rules/diabetes.d.ts +2 -0
  46. package/dist/src/rules/diabetes.js +6 -0
  47. package/dist/src/rules/fattyLiver.d.ts +2 -0
  48. package/dist/src/rules/fattyLiver.js +6 -0
  49. package/dist/src/rules/index.d.ts +7 -0
  50. package/dist/src/rules/index.js +46 -0
  51. package/dist/src/rules/lowCarb.d.ts +2 -0
  52. package/dist/src/rules/lowCarb.js +6 -0
  53. package/dist/src/rules/triglycerides.d.ts +2 -0
  54. package/dist/src/rules/triglycerides.js +6 -0
  55. package/dist/src/types/firestore.d.ts +100 -0
  56. package/dist/src/types/firestore.js +2 -0
  57. package/dist/src/types/openfoodfacts.d.ts +113 -0
  58. package/dist/src/types/openfoodfacts.js +3 -0
  59. package/dist/src/types/recipe.d.ts +36 -0
  60. package/dist/src/types/recipe.js +2 -0
  61. package/dist/src/types.d.ts +24 -0
  62. package/dist/src/types.js +2 -0
  63. package/dist/src/variety.d.ts +17 -0
  64. package/dist/src/variety.js +129 -0
  65. package/dist/src/weeklyMealPlanGenerator.d.ts +3 -0
  66. package/dist/src/weeklyMealPlanGenerator.js +468 -0
  67. package/dist/src/weeklyPlanner.d.ts +12 -0
  68. package/dist/src/weeklyPlanner.js +31 -0
  69. package/dist/types/firestore.d.ts +100 -0
  70. package/dist/types/firestore.js +2 -0
  71. package/dist/types/openfoodfacts.d.ts +113 -0
  72. package/dist/types/openfoodfacts.js +3 -0
  73. package/dist/types/recipe.d.ts +36 -0
  74. package/dist/types/recipe.js +2 -0
  75. package/dist/types.d.ts +24 -0
  76. package/dist/types.js +2 -0
  77. package/dist/variety.d.ts +17 -0
  78. package/dist/variety.js +130 -0
  79. package/dist/weeklyMealPlanGenerator.d.ts +3 -0
  80. package/dist/weeklyMealPlanGenerator.js +469 -0
  81. package/dist/weeklyPlanner.d.ts +12 -0
  82. package/dist/weeklyPlanner.js +32 -0
  83. package/package.json +66 -0
@@ -0,0 +1,469 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateWeeklyMealPlan = void 0;
4
+ const foodConversion_1 = require("./foodConversion");
5
+ // Extended mock food data for weekly variety
6
+ const mockFoods = {
7
+ // Breakfast foods
8
+ oatmeal: {
9
+ id: 'oatmeal',
10
+ name: 'Oatmeal',
11
+ brand: 'Generic',
12
+ nutritionPer100g: { calories: 379, protein: 13.2, carbs: 66.3, fat: 6.9 },
13
+ servingSize: 40,
14
+ unit: 'g'
15
+ },
16
+ banana: {
17
+ id: 'banana',
18
+ name: 'Banana',
19
+ brand: 'Generic',
20
+ nutritionPer100g: { calories: 89, protein: 1.1, carbs: 22.8, fat: 0.3 },
21
+ servingSize: 118,
22
+ unit: 'g'
23
+ },
24
+ eggs: {
25
+ id: 'eggs',
26
+ name: 'Eggs',
27
+ brand: 'Generic',
28
+ nutritionPer100g: { calories: 155, protein: 13, carbs: 1.1, fat: 11 },
29
+ servingSize: 100,
30
+ unit: 'g'
31
+ },
32
+ yogurt: {
33
+ id: 'yogurt',
34
+ name: 'Greek Yogurt',
35
+ brand: 'Generic',
36
+ nutritionPer100g: { calories: 59, protein: 10, carbs: 3.6, fat: 0.4 },
37
+ servingSize: 170,
38
+ unit: 'g'
39
+ },
40
+ berries: {
41
+ id: 'berries',
42
+ name: 'Mixed Berries',
43
+ brand: 'Generic',
44
+ nutritionPer100g: { calories: 57, protein: 0.7, carbs: 14.5, fat: 0.3 },
45
+ servingSize: 100,
46
+ unit: 'g'
47
+ },
48
+ avocado_toast: {
49
+ id: 'avocado_toast',
50
+ name: 'Avocado Toast',
51
+ brand: 'Generic',
52
+ nutritionPer100g: { calories: 160, protein: 2, carbs: 9, fat: 15 },
53
+ servingSize: 150,
54
+ unit: 'g'
55
+ },
56
+ smoothie: {
57
+ id: 'smoothie',
58
+ name: 'Protein Smoothie',
59
+ brand: 'Generic',
60
+ nutritionPer100g: { calories: 150, protein: 20, carbs: 15, fat: 3 },
61
+ servingSize: 300,
62
+ unit: 'ml'
63
+ },
64
+ // Lunch proteins
65
+ chicken: {
66
+ id: 'chicken',
67
+ name: 'Chicken Breast',
68
+ brand: 'Generic',
69
+ nutritionPer100g: { calories: 165, protein: 31, carbs: 0, fat: 3.6 },
70
+ servingSize: 100,
71
+ unit: 'g'
72
+ },
73
+ salmon: {
74
+ id: 'salmon',
75
+ name: 'Salmon',
76
+ brand: 'Generic',
77
+ nutritionPer100g: { calories: 206, protein: 22, carbs: 0, fat: 13 },
78
+ servingSize: 100,
79
+ unit: 'g'
80
+ },
81
+ turkey: {
82
+ id: 'turkey',
83
+ name: 'Turkey Breast',
84
+ brand: 'Generic',
85
+ nutritionPer100g: { calories: 135, protein: 30, carbs: 0, fat: 1 },
86
+ servingSize: 100,
87
+ unit: 'g'
88
+ },
89
+ tuna: {
90
+ id: 'tuna',
91
+ name: 'Tuna',
92
+ brand: 'Generic',
93
+ nutritionPer100g: { calories: 144, protein: 30, carbs: 0, fat: 1 },
94
+ servingSize: 100,
95
+ unit: 'g'
96
+ },
97
+ tofu: {
98
+ id: 'tofu',
99
+ name: 'Tofu',
100
+ brand: 'Generic',
101
+ nutritionPer100g: { calories: 76, protein: 8, carbs: 1.9, fat: 4.8 },
102
+ servingSize: 150,
103
+ unit: 'g'
104
+ },
105
+ lentils: {
106
+ id: 'lentils',
107
+ name: 'Lentils',
108
+ brand: 'Generic',
109
+ nutritionPer100g: { calories: 116, protein: 9, carbs: 20, fat: 0.4 },
110
+ servingSize: 200,
111
+ unit: 'g'
112
+ },
113
+ quinoa: {
114
+ id: 'quinoa',
115
+ name: 'Quinoa',
116
+ brand: 'Generic',
117
+ nutritionPer100g: { calories: 120, protein: 4.4, carbs: 22, fat: 1.9 },
118
+ servingSize: 185,
119
+ unit: 'g'
120
+ },
121
+ // Carbs
122
+ rice: {
123
+ id: 'rice',
124
+ name: 'Brown Rice',
125
+ brand: 'Generic',
126
+ nutritionPer100g: { calories: 111, protein: 2.6, carbs: 23, fat: 0.9 },
127
+ servingSize: 185,
128
+ unit: 'g'
129
+ },
130
+ pasta: {
131
+ id: 'pasta',
132
+ name: 'Whole Wheat Pasta',
133
+ brand: 'Generic',
134
+ nutritionPer100g: { calories: 124, protein: 5, carbs: 25, fat: 1.1 },
135
+ servingSize: 140,
136
+ unit: 'g'
137
+ },
138
+ sweet_potato: {
139
+ id: 'sweet_potato',
140
+ name: 'Sweet Potato',
141
+ brand: 'Generic',
142
+ nutritionPer100g: { calories: 86, protein: 1.6, carbs: 20, fat: 0.1 },
143
+ servingSize: 200,
144
+ unit: 'g'
145
+ },
146
+ bread: {
147
+ id: 'bread',
148
+ name: 'Whole Wheat Bread',
149
+ brand: 'Generic',
150
+ nutritionPer100g: { calories: 247, protein: 13, carbs: 41, fat: 3.5 },
151
+ servingSize: 45,
152
+ unit: 'g'
153
+ },
154
+ // Vegetables
155
+ broccoli: {
156
+ id: 'broccoli',
157
+ name: 'Broccoli',
158
+ brand: 'Generic',
159
+ nutritionPer100g: { calories: 34, protein: 2.8, carbs: 7, fat: 0.4 },
160
+ servingSize: 91,
161
+ unit: 'g'
162
+ },
163
+ spinach: {
164
+ id: 'spinach',
165
+ name: 'Spinach',
166
+ brand: 'Generic',
167
+ nutritionPer100g: { calories: 23, protein: 2.9, carbs: 3.6, fat: 0.4 },
168
+ servingSize: 30,
169
+ unit: 'g'
170
+ },
171
+ carrots: {
172
+ id: 'carrots',
173
+ name: 'Carrots',
174
+ brand: 'Generic',
175
+ nutritionPer100g: { calories: 41, protein: 0.9, carbs: 9.6, fat: 0.2 },
176
+ servingSize: 100,
177
+ unit: 'g'
178
+ },
179
+ bell_peppers: {
180
+ id: 'bell_peppers',
181
+ name: 'Bell Peppers',
182
+ brand: 'Generic',
183
+ nutritionPer100g: { calories: 31, protein: 1, carbs: 7, fat: 0.3 },
184
+ servingSize: 120,
185
+ unit: 'g'
186
+ },
187
+ zucchini: {
188
+ id: 'zucchini',
189
+ name: 'Zucchini',
190
+ brand: 'Generic',
191
+ nutritionPer100g: { calories: 17, protein: 1.2, carbs: 3.1, fat: 0.3 },
192
+ servingSize: 200,
193
+ unit: 'g'
194
+ },
195
+ // Snacks
196
+ apple: {
197
+ id: 'apple',
198
+ name: 'Apple',
199
+ brand: 'Generic',
200
+ nutritionPer100g: { calories: 52, protein: 0.3, carbs: 13.8, fat: 0.2 },
201
+ servingSize: 182,
202
+ unit: 'g'
203
+ },
204
+ almonds: {
205
+ id: 'almonds',
206
+ name: 'Almonds',
207
+ brand: 'Generic',
208
+ nutritionPer100g: { calories: 579, protein: 21.2, carbs: 21.6, fat: 49.9 },
209
+ servingSize: 28,
210
+ unit: 'g'
211
+ },
212
+ walnuts: {
213
+ id: 'walnuts',
214
+ name: 'Walnuts',
215
+ brand: 'Generic',
216
+ nutritionPer100g: { calories: 654, protein: 15.2, carbs: 13.7, fat: 65.2 },
217
+ servingSize: 28,
218
+ unit: 'g'
219
+ },
220
+ orange: {
221
+ id: 'orange',
222
+ name: 'Orange',
223
+ brand: 'Generic',
224
+ nutritionPer100g: { calories: 47, protein: 0.9, carbs: 11.8, fat: 0.1 },
225
+ servingSize: 154,
226
+ unit: 'g'
227
+ }
228
+ };
229
+ function calculateDailyNeeds(profile) {
230
+ const age = profile.age || 30;
231
+ const height = profile.height || 170;
232
+ const weight = profile.weight || 70;
233
+ const gender = profile.gender || 'male';
234
+ const activityLevel = profile.activityLevel || 'moderately_active';
235
+ const bmr = gender === 'male'
236
+ ? 88.362 + (13.397 * weight) + (4.799 * height) - (5.677 * age)
237
+ : 447.593 + (9.247 * weight) + (3.098 * height) - (4.330 * age);
238
+ const activityMultipliers = {
239
+ sedentary: 1.2,
240
+ lightly_active: 1.375,
241
+ moderately_active: 1.55,
242
+ very_active: 1.725,
243
+ extremely_active: 1.9
244
+ };
245
+ const tdee = bmr * (activityMultipliers[activityLevel] || 1.2);
246
+ let dailyCalories = tdee;
247
+ if (profile.healthGoals?.includes('weight_loss')) {
248
+ dailyCalories -= 500;
249
+ }
250
+ else if (profile.healthGoals?.includes('weight_gain')) {
251
+ dailyCalories += 500;
252
+ }
253
+ return {
254
+ calories: Math.round(Math.max(dailyCalories, 1200)),
255
+ protein: Math.round(Math.max(dailyCalories * 0.3 / 4, 50)),
256
+ carbs: Math.round(Math.max(dailyCalories * 0.4 / 4, 100)),
257
+ fat: Math.round(Math.max(dailyCalories * 0.3 / 9, 30))
258
+ };
259
+ }
260
+ function createMeal(name, type, foods) {
261
+ const meal = (0, foodConversion_1.createMealFromFoodItems)(name, type, foods.map(({ food, amount, unit }, index) => ({
262
+ food: food,
263
+ amount,
264
+ unit
265
+ })));
266
+ return {
267
+ ...meal,
268
+ instructions: [`Prepare ${name} according to recipe`],
269
+ };
270
+ }
271
+ // Weekly meal plan templates
272
+ const weeklyMealTemplates = {
273
+ breakfast: [
274
+ { name: 'Oatmeal with Banana', foods: [
275
+ { food: mockFoods.oatmeal, amount: 50, unit: 'g' },
276
+ { food: mockFoods.banana, amount: 100, unit: 'g' }
277
+ ] },
278
+ { name: 'Greek Yogurt with Berries', foods: [
279
+ { food: mockFoods.yogurt, amount: 170, unit: 'g' },
280
+ { food: mockFoods.berries, amount: 100, unit: 'g' }
281
+ ] },
282
+ { name: 'Scrambled Eggs', foods: [
283
+ { food: mockFoods.eggs, amount: 100, unit: 'g' },
284
+ { food: mockFoods.spinach, amount: 50, unit: 'g' }
285
+ ] },
286
+ { name: 'Avocado Toast', foods: [
287
+ { food: mockFoods.avocado_toast, amount: 150, unit: 'g' }
288
+ ] },
289
+ { name: 'Protein Smoothie', foods: [
290
+ { food: mockFoods.smoothie, amount: 300, unit: 'ml' },
291
+ { food: mockFoods.berries, amount: 50, unit: 'g' }
292
+ ] },
293
+ { name: 'Oatmeal with Berries', foods: [
294
+ { food: mockFoods.oatmeal, amount: 50, unit: 'g' },
295
+ { food: mockFoods.berries, amount: 100, unit: 'g' }
296
+ ] },
297
+ { name: 'Yogurt Parfait', foods: [
298
+ { food: mockFoods.yogurt, amount: 170, unit: 'g' },
299
+ { food: mockFoods.banana, amount: 80, unit: 'g' },
300
+ { food: mockFoods.almonds, amount: 15, unit: 'g' }
301
+ ] }
302
+ ],
303
+ lunch: [
304
+ { name: 'Chicken Salad', foods: [
305
+ { food: mockFoods.chicken, amount: 150, unit: 'g' },
306
+ { food: mockFoods.spinach, amount: 100, unit: 'g' },
307
+ { food: mockFoods.carrots, amount: 80, unit: 'g' }
308
+ ] },
309
+ { name: 'Salmon with Quinoa', foods: [
310
+ { food: mockFoods.salmon, amount: 120, unit: 'g' },
311
+ { food: mockFoods.quinoa, amount: 150, unit: 'g' },
312
+ { food: mockFoods.broccoli, amount: 100, unit: 'g' }
313
+ ] },
314
+ { name: 'Turkey Wrap', foods: [
315
+ { food: mockFoods.turkey, amount: 100, unit: 'g' },
316
+ { food: mockFoods.bread, amount: 90, unit: 'g' },
317
+ { food: mockFoods.bell_peppers, amount: 80, unit: 'g' }
318
+ ] },
319
+ { name: 'Tuna Salad', foods: [
320
+ { food: mockFoods.tuna, amount: 100, unit: 'g' },
321
+ { food: mockFoods.spinach, amount: 100, unit: 'g' },
322
+ { food: mockFoods.sweet_potato, amount: 150, unit: 'g' }
323
+ ] },
324
+ { name: 'Tofu Stir Fry', foods: [
325
+ { food: mockFoods.tofu, amount: 150, unit: 'g' },
326
+ { food: mockFoods.bell_peppers, amount: 100, unit: 'g' },
327
+ { food: mockFoods.rice, amount: 150, unit: 'g' }
328
+ ] },
329
+ { name: 'Lentil Bowl', foods: [
330
+ { food: mockFoods.lentils, amount: 200, unit: 'g' },
331
+ { food: mockFoods.carrots, amount: 100, unit: 'g' },
332
+ { food: mockFoods.spinach, amount: 80, unit: 'g' }
333
+ ] },
334
+ { name: 'Chicken Pasta', foods: [
335
+ { food: mockFoods.chicken, amount: 120, unit: 'g' },
336
+ { food: mockFoods.pasta, amount: 140, unit: 'g' },
337
+ { food: mockFoods.zucchini, amount: 150, unit: 'g' }
338
+ ] }
339
+ ],
340
+ dinner: [
341
+ { name: 'Salmon with Sweet Potato', foods: [
342
+ { food: mockFoods.salmon, amount: 150, unit: 'g' },
343
+ { food: mockFoods.sweet_potato, amount: 200, unit: 'g' },
344
+ { food: mockFoods.broccoli, amount: 100, unit: 'g' }
345
+ ] },
346
+ { name: 'Chicken with Rice', foods: [
347
+ { food: mockFoods.chicken, amount: 150, unit: 'g' },
348
+ { food: mockFoods.rice, amount: 150, unit: 'g' },
349
+ { food: mockFoods.bell_peppers, amount: 120, unit: 'g' }
350
+ ] },
351
+ { name: 'Turkey with Quinoa', foods: [
352
+ { food: mockFoods.turkey, amount: 150, unit: 'g' },
353
+ { food: mockFoods.quinoa, amount: 150, unit: 'g' },
354
+ { food: mockFoods.zucchini, amount: 150, unit: 'g' }
355
+ ] },
356
+ { name: 'Tofu Curry', foods: [
357
+ { food: mockFoods.tofu, amount: 150, unit: 'g' },
358
+ { food: mockFoods.rice, amount: 150, unit: 'g' },
359
+ { food: mockFoods.spinach, amount: 100, unit: 'g' }
360
+ ] },
361
+ { name: 'Lentil Stew', foods: [
362
+ { food: mockFoods.lentils, amount: 200, unit: 'g' },
363
+ { food: mockFoods.carrots, amount: 100, unit: 'g' },
364
+ { food: mockFoods.sweet_potato, amount: 150, unit: 'g' }
365
+ ] },
366
+ { name: 'Tuna with Pasta', foods: [
367
+ { food: mockFoods.tuna, amount: 120, unit: 'g' },
368
+ { food: mockFoods.pasta, amount: 140, unit: 'g' },
369
+ { food: mockFoods.broccoli, amount: 100, unit: 'g' }
370
+ ] },
371
+ { name: 'Chicken Stir Fry', foods: [
372
+ { food: mockFoods.chicken, amount: 150, unit: 'g' },
373
+ { food: mockFoods.rice, amount: 150, unit: 'g' },
374
+ { food: mockFoods.bell_peppers, amount: 100, unit: 'g' },
375
+ { food: mockFoods.carrots, amount: 80, unit: 'g' }
376
+ ] }
377
+ ],
378
+ snack: [
379
+ { name: 'Apple with Almonds', foods: [
380
+ { food: mockFoods.apple, amount: 150, unit: 'g' },
381
+ { food: mockFoods.almonds, amount: 20, unit: 'g' }
382
+ ] },
383
+ { name: 'Greek Yogurt', foods: [
384
+ { food: mockFoods.yogurt, amount: 170, unit: 'g' }
385
+ ] },
386
+ { name: 'Orange with Walnuts', foods: [
387
+ { food: mockFoods.orange, amount: 150, unit: 'g' },
388
+ { food: mockFoods.walnuts, amount: 20, unit: 'g' }
389
+ ] },
390
+ { name: 'Berries', foods: [
391
+ { food: mockFoods.berries, amount: 150, unit: 'g' }
392
+ ] },
393
+ { name: 'Banana with Almonds', foods: [
394
+ { food: mockFoods.banana, amount: 118, unit: 'g' },
395
+ { food: mockFoods.almonds, amount: 15, unit: 'g' }
396
+ ] },
397
+ { name: 'Carrots with Almonds', foods: [
398
+ { food: mockFoods.carrots, amount: 100, unit: 'g' },
399
+ { food: mockFoods.almonds, amount: 15, unit: 'g' }
400
+ ] },
401
+ { name: 'Apple', foods: [
402
+ { food: mockFoods.apple, amount: 182, unit: 'g' }
403
+ ] }
404
+ ]
405
+ };
406
+ function generateWeeklyMealPlan(profile, userId) {
407
+ const needs = calculateDailyNeeds(profile);
408
+ const isVegetarian = profile.dietaryRestrictions?.includes('vegetarian');
409
+ const isVegan = profile.dietaryRestrictions?.includes('vegan');
410
+ const allMeals = [];
411
+ const daysOfWeek = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'];
412
+ daysOfWeek.forEach((day, dayIndex) => {
413
+ // Filter meal templates based on dietary restrictions
414
+ const getFilteredMeals = (mealType) => {
415
+ return weeklyMealTemplates[mealType].filter(template => {
416
+ if (isVegan) {
417
+ return !template.foods.some(f => ['chicken', 'salmon', 'turkey', 'tuna', 'eggs', 'yogurt'].includes(f.food.id));
418
+ }
419
+ if (isVegetarian) {
420
+ return !template.foods.some(f => ['chicken', 'salmon', 'turkey', 'tuna'].includes(f.food.id));
421
+ }
422
+ return true;
423
+ });
424
+ };
425
+ // Select meals for each day with variety
426
+ const breakfastOptions = getFilteredMeals('breakfast');
427
+ const lunchOptions = getFilteredMeals('lunch');
428
+ const dinnerOptions = getFilteredMeals('dinner');
429
+ const snackOptions = getFilteredMeals('snack');
430
+ const breakfast = createMeal(`${day} - ${breakfastOptions[dayIndex % breakfastOptions.length].name}`, 'breakfast', breakfastOptions[dayIndex % breakfastOptions.length].foods);
431
+ const lunch = createMeal(`${day} - ${lunchOptions[dayIndex % lunchOptions.length].name}`, 'lunch', lunchOptions[dayIndex % lunchOptions.length].foods);
432
+ const dinner = createMeal(`${day} - ${dinnerOptions[dayIndex % dinnerOptions.length].name}`, 'dinner', dinnerOptions[dayIndex % dinnerOptions.length].foods);
433
+ const snack = createMeal(`${day} - ${snackOptions[dayIndex % snackOptions.length].name}`, 'snack', snackOptions[dayIndex % snackOptions.length].foods);
434
+ allMeals.push(breakfast, lunch, dinner, snack);
435
+ });
436
+ const totalNutrition = allMeals.reduce((total, meal) => ({
437
+ calories: total.calories + (meal.nutrition?.calories || 0),
438
+ protein: Math.round((total.protein + (meal.nutrition?.protein || 0)) * 10) / 10,
439
+ carbs: total.carbs + (meal.nutrition?.carbs || 0),
440
+ fat: total.fat + (meal.nutrition?.fat || 0)
441
+ }), { calories: 0, protein: 0, carbs: 0, fat: 0 });
442
+ const startDate = new Date();
443
+ const endDate = new Date();
444
+ endDate.setDate(startDate.getDate() + 6);
445
+ return {
446
+ id: `weekly-plan-${Date.now()}`,
447
+ userId: userId,
448
+ name: `Weekly Meal Plan - ${startDate.toLocaleDateString()} to ${endDate.toLocaleDateString()}`,
449
+ description: `Personalized 7-day meal plan with variety and balanced nutrition (${Math.round(totalNutrition.calories / 7)} cal/day avg)`,
450
+ startDate: startDate.toISOString().split('T')[0],
451
+ endDate: endDate.toISOString().split('T')[0],
452
+ dailyPlans: [],
453
+ meals: allMeals,
454
+ totalCalories: totalNutrition.calories,
455
+ totalProtein: totalNutrition.protein,
456
+ totalCarbs: totalNutrition.carbs,
457
+ totalFat: totalNutrition.fat,
458
+ uid: userId,
459
+ goals: {
460
+ dailyCalories: Math.round(totalNutrition.calories / 7),
461
+ proteinPercentage: 25,
462
+ carbsPercentage: 45,
463
+ fatPercentage: 30,
464
+ },
465
+ createdAt: new Date(),
466
+ updatedAt: new Date()
467
+ };
468
+ }
469
+ exports.generateWeeklyMealPlan = generateWeeklyMealPlan;
@@ -0,0 +1,12 @@
1
+ import { Recipe, UserProfile } from './types';
2
+ export interface DailyMealPlan {
3
+ date: string;
4
+ dailyCalories: number;
5
+ meals: Recipe[];
6
+ }
7
+ export interface WeeklyMealPlan {
8
+ weekCalories: number;
9
+ days: DailyMealPlan[];
10
+ diversityScore?: number;
11
+ }
12
+ export declare function generateWeeklyPlan(profile: UserProfile, recipes: Recipe[]): WeeklyMealPlan;
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateWeeklyPlan = void 0;
4
+ const bmr_1 = require("./bmr");
5
+ const rules_1 = require("./rules");
6
+ const variety_1 = require("./variety");
7
+ function generateWeeklyPlan(profile, recipes) {
8
+ const targetCalories = Math.round((0, bmr_1.calculateTDEE)(profile));
9
+ const filtered = (0, rules_1.applyHealthRules)(recipes, profile.conditions);
10
+ const days = [];
11
+ let weekTotal = 0;
12
+ let allWeekMeals = [];
13
+ const daysOfWeek = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'];
14
+ for (let i = 0; i < 7; i++) {
15
+ const dailyMeals = (0, variety_1.selectDiverseMeals)(filtered, targetCalories, allWeekMeals);
16
+ const dailyTotal = dailyMeals.reduce((sum, m) => sum + m.calories, 0);
17
+ days.push({
18
+ date: daysOfWeek[i],
19
+ dailyCalories: dailyTotal,
20
+ meals: dailyMeals
21
+ });
22
+ weekTotal += dailyTotal;
23
+ allWeekMeals.push(...dailyMeals);
24
+ }
25
+ const weekScore = (0, variety_1.scoreMealPlan)(allWeekMeals);
26
+ return {
27
+ weekCalories: weekTotal,
28
+ days,
29
+ diversityScore: weekScore.overallScore
30
+ };
31
+ }
32
+ exports.generateWeeklyPlan = generateWeeklyPlan;
package/package.json ADDED
@@ -0,0 +1,66 @@
1
+ {
2
+ "name": "healthy-meals-core",
3
+ "version": "0.0.2",
4
+ "main": "dist/index.js",
5
+ "types": "dist/index.d.ts",
6
+ "exports": {
7
+ ".": {
8
+ "types": "./dist/index.d.ts",
9
+ "default": "./dist/index.js"
10
+ },
11
+ "./types": {
12
+ "types": "./dist/types.d.ts",
13
+ "default": "./dist/types.js"
14
+ },
15
+ "./types/*": {
16
+ "types": "./dist/types/*.d.ts",
17
+ "default": "./dist/types/*.js"
18
+ },
19
+ "./bmr": {
20
+ "types": "./dist/bmr.d.ts",
21
+ "default": "./dist/bmr.js"
22
+ },
23
+ "./planner": {
24
+ "types": "./dist/planner.d.ts",
25
+ "default": "./dist/planner.js"
26
+ },
27
+ "./rules": {
28
+ "types": "./dist/rules/index.d.ts",
29
+ "default": "./dist/rules/index.js"
30
+ },
31
+ "./weeklyPlanner": {
32
+ "types": "./dist/weeklyPlanner.d.ts",
33
+ "default": "./dist/weeklyPlanner.js"
34
+ },
35
+ "./variety": {
36
+ "types": "./dist/variety.d.ts",
37
+ "default": "./dist/variety.js"
38
+ },
39
+ "./dailyMealPlanGenerator": {
40
+ "types": "./dist/dailyMealPlanGenerator.d.ts",
41
+ "default": "./dist/dailyMealPlanGenerator.js"
42
+ },
43
+ "./weeklyMealPlanGenerator": {
44
+ "types": "./dist/weeklyMealPlanGenerator.d.ts",
45
+ "default": "./dist/weeklyMealPlanGenerator.js"
46
+ },
47
+ "./foodConversion": {
48
+ "types": "./dist/foodConversion.d.ts",
49
+ "default": "./dist/foodConversion.js"
50
+ }
51
+ },
52
+ "scripts": {
53
+ "build": "npx tsc",
54
+ "dev": "tsc --watch",
55
+ "prepublishOnly": "npm run build"
56
+ },
57
+ "files": [
58
+ "dist/**/*"
59
+ ],
60
+ "publishConfig": {
61
+ "access": "public"
62
+ },
63
+ "devDependencies": {
64
+ "typescript": "^4.9.5"
65
+ }
66
+ }