Spaces:
Sleeping
Sleeping
Commit
·
e13a8b7
1
Parent(s):
11378b9
feat(meals): add seeder
Browse files- src/common/enums/meal-type.enum.ts +5 -2
- src/common/models/meal.model.ts +1 -1
- src/resources/meals.json +0 -0
- src/seeder/helpers/db-store.ts +5 -0
- src/seeder/helpers/load-meals-dataset.ts +30 -0
- src/seeder/seed.ts +8 -2
- src/seeder/seeders/8-ingredients.seeder.ts +21 -0
- src/seeder/seeders/9-meals.seeder.ts +35 -0
src/common/enums/meal-type.enum.ts
CHANGED
@@ -1,6 +1,9 @@
|
|
1 |
export enum MealType {
|
2 |
BREAKFAST = "breakfast",
|
3 |
-
LUNCH = "lunch",
|
4 |
-
SNACKS = "snacks",
|
5 |
DINNER = "dinner",
|
|
|
|
|
|
|
|
|
|
|
6 |
}
|
|
|
1 |
export enum MealType {
|
2 |
BREAKFAST = "breakfast",
|
|
|
|
|
3 |
DINNER = "dinner",
|
4 |
+
SNACKS = "snacks",
|
5 |
+
DRINKS_BEVERAGES = 'drinks beverages',
|
6 |
+
CUSINES = 'cusines',
|
7 |
+
LUNCH = "lunch",
|
8 |
+
BREAKFAST_DINNER= "breakfast, dinner"
|
9 |
}
|
src/common/models/meal.model.ts
CHANGED
@@ -4,7 +4,7 @@ import { MealType } from "@common/enums/meal-type.enum";
|
|
4 |
export interface IMeal {
|
5 |
name: string;
|
6 |
created_at: Date;
|
7 |
-
ingredients: [
|
8 |
calories: number;
|
9 |
carbs: number;
|
10 |
proteins: number;
|
|
|
4 |
export interface IMeal {
|
5 |
name: string;
|
6 |
created_at: Date;
|
7 |
+
ingredients: string[];
|
8 |
calories: number;
|
9 |
carbs: number;
|
10 |
proteins: number;
|
src/resources/meals.json
ADDED
The diff for this file is too large to render.
See raw diff
|
|
src/seeder/helpers/db-store.ts
CHANGED
@@ -1,13 +1,18 @@
|
|
1 |
import { IExerciseCSV } from './load-exercises-dataset';
|
|
|
2 |
|
3 |
export const dbStore: {
|
4 |
dbConnected: boolean;
|
5 |
excerisesDataset: IExerciseCSV[];
|
6 |
musclesDataset: IExerciseCSV['target'][];
|
7 |
equipmentsDataset: IExerciseCSV['equipment'][];
|
|
|
|
|
8 |
} = {
|
9 |
dbConnected: false,
|
10 |
excerisesDataset: [],
|
11 |
musclesDataset: [],
|
12 |
equipmentsDataset: [],
|
|
|
|
|
13 |
}
|
|
|
1 |
import { IExerciseCSV } from './load-exercises-dataset';
|
2 |
+
import { IMealJson } from './load-meals-dataset';
|
3 |
|
4 |
export const dbStore: {
|
5 |
dbConnected: boolean;
|
6 |
excerisesDataset: IExerciseCSV[];
|
7 |
musclesDataset: IExerciseCSV['target'][];
|
8 |
equipmentsDataset: IExerciseCSV['equipment'][];
|
9 |
+
mealsDataset: IMealJson[];
|
10 |
+
ingredientsNames: string[];
|
11 |
} = {
|
12 |
dbConnected: false,
|
13 |
excerisesDataset: [],
|
14 |
musclesDataset: [],
|
15 |
equipmentsDataset: [],
|
16 |
+
mealsDataset: [],
|
17 |
+
ingredientsNames: [],
|
18 |
}
|
src/seeder/helpers/load-meals-dataset.ts
ADDED
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import * as path from "path";
|
2 |
+
const fs = require('fs')
|
3 |
+
|
4 |
+
export interface IMealJson {
|
5 |
+
Name: string;
|
6 |
+
RecipeIngredientParts: string[];
|
7 |
+
Calories: number;
|
8 |
+
CarbohydrateContent: number;
|
9 |
+
ProteinContent: number;
|
10 |
+
FatContent: number;
|
11 |
+
Images: string[];
|
12 |
+
type: string;
|
13 |
+
}
|
14 |
+
|
15 |
+
const filePath = path.join(__dirname, '../../resources/meals.json');
|
16 |
+
|
17 |
+
export const loadMealsDataset = (): IMealJson[] => {
|
18 |
+
let data: IMealJson[] = JSON.parse(fs.readFileSync(filePath, 'utf8'));
|
19 |
+
|
20 |
+
// remove duplicates by name
|
21 |
+
const uniqueNames = new Set(data.map(e => e.Name));
|
22 |
+
data = data.filter(e => {
|
23 |
+
const found = uniqueNames.has(e.Name)
|
24 |
+
uniqueNames.delete(e.Name);
|
25 |
+
return found;
|
26 |
+
});
|
27 |
+
|
28 |
+
console.log(`Loaded ${data.length} meals from dataset`)
|
29 |
+
return data;
|
30 |
+
}
|
src/seeder/seed.ts
CHANGED
@@ -11,15 +11,21 @@ import * as glob from "glob";
|
|
11 |
import path from "path";
|
12 |
import { loadExercisesDataset } from "./helpers/load-exercises-dataset";
|
13 |
import { dbStore } from "./helpers/db-store";
|
|
|
14 |
|
15 |
const loadDatasets = async() => {
|
16 |
const exercisesDataset = await loadExercisesDataset();
|
|
|
17 |
const musclesDataset = Array.from(new Set(exercisesDataset.map((exercise) => exercise.target)));
|
18 |
-
const equipmentsDataset = Array.from(new Set(exercisesDataset.map((exercise) => exercise.equipment)))
|
|
|
|
|
19 |
|
20 |
dbStore.excerisesDataset = exercisesDataset;
|
21 |
dbStore.musclesDataset = musclesDataset;
|
22 |
dbStore.equipmentsDataset = equipmentsDataset;
|
|
|
|
|
23 |
}
|
24 |
|
25 |
const main = async () => {
|
@@ -44,7 +50,7 @@ const main = async () => {
|
|
44 |
return true;
|
45 |
}
|
46 |
|
47 |
-
return seederNames.
|
48 |
})
|
49 |
.sort();
|
50 |
|
|
|
11 |
import path from "path";
|
12 |
import { loadExercisesDataset } from "./helpers/load-exercises-dataset";
|
13 |
import { dbStore } from "./helpers/db-store";
|
14 |
+
import { loadMealsDataset } from "./helpers/load-meals-dataset";
|
15 |
|
16 |
const loadDatasets = async() => {
|
17 |
const exercisesDataset = await loadExercisesDataset();
|
18 |
+
const mealsDataset = loadMealsDataset();
|
19 |
const musclesDataset = Array.from(new Set(exercisesDataset.map((exercise) => exercise.target)));
|
20 |
+
const equipmentsDataset = Array.from(new Set(exercisesDataset.map((exercise) => exercise.equipment)));
|
21 |
+
const ingredientsArrays = mealsDataset.map(m=>m.RecipeIngredientParts);
|
22 |
+
const ingredientsNames = Array.from(new Set(ingredientsArrays.flat()))
|
23 |
|
24 |
dbStore.excerisesDataset = exercisesDataset;
|
25 |
dbStore.musclesDataset = musclesDataset;
|
26 |
dbStore.equipmentsDataset = equipmentsDataset;
|
27 |
+
dbStore.mealsDataset = mealsDataset;
|
28 |
+
dbStore.ingredientsNames = ingredientsNames;
|
29 |
}
|
30 |
|
31 |
const main = async () => {
|
|
|
50 |
return true;
|
51 |
}
|
52 |
|
53 |
+
return seederNames.some(name => path.basename(file).includes(name));
|
54 |
})
|
55 |
.sort();
|
56 |
|
src/seeder/seeders/8-ingredients.seeder.ts
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import { seederWrapper } from "seeder/helpers/seeder-wrapper";
|
2 |
+
import { dbStore } from "seeder/helpers/db-store";
|
3 |
+
import { IIngredient, Ingredient } from "@common/models/ingredient.model";
|
4 |
+
import { faker } from '@faker-js/faker';
|
5 |
+
|
6 |
+
export default seederWrapper(Ingredient, async () => {
|
7 |
+
const data = await Promise.all(dbStore.ingredientsNames.map(async (ingredientName) => ({
|
8 |
+
name: ingredientName,
|
9 |
+
serving_size: faker.number.int({ min: 5, max: 20 }),
|
10 |
+
servings_count: faker.number.int({ min: 1, max: 5 }),
|
11 |
+
serving_size_unit: "unknown",
|
12 |
+
servings_count_unit: "unknown",
|
13 |
+
calories: faker.number.int({ min: 10, max: 20 }),
|
14 |
+
carbs: faker.number.int({ min: 10, max: 20 }),
|
15 |
+
proteins: faker.number.int({ min: 10, max: 20 }),
|
16 |
+
fats: faker.number.int({ min: 10, max: 20 }),
|
17 |
+
} satisfies Partial<IIngredient>)));
|
18 |
+
|
19 |
+
await Ingredient.insertMany(data);
|
20 |
+
});
|
21 |
+
|
src/seeder/seeders/9-meals.seeder.ts
ADDED
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import { seederWrapper } from "seeder/helpers/seeder-wrapper";
|
2 |
+
import { IMeal, Meal } from "@common/models/meal.model";
|
3 |
+
import { dbStore } from "seeder/helpers/db-store";
|
4 |
+
import { MealType } from "@common/enums/meal-type.enum";
|
5 |
+
import { Ingredient } from "@common/models/ingredient.model";
|
6 |
+
|
7 |
+
export default seederWrapper(Meal, async () => {
|
8 |
+
console.log('fetching ingredients ids...')
|
9 |
+
const ingredientsIds = await Promise.all(
|
10 |
+
dbStore.ingredientsNames.map(
|
11 |
+
async name => {
|
12 |
+
const ing = await Ingredient.findOne(({name}));
|
13 |
+
return {
|
14 |
+
name,
|
15 |
+
_id: ing._id
|
16 |
+
}
|
17 |
+
}
|
18 |
+
)
|
19 |
+
)
|
20 |
+
|
21 |
+
console.log('preping meals data...')
|
22 |
+
const data = await Promise.all(dbStore.mealsDataset.map(async (mealJson) => ({
|
23 |
+
name: mealJson.Name,
|
24 |
+
ingredients: mealJson.RecipeIngredientParts.map(name => ingredientsIds.find(i => i.name === name)._id),
|
25 |
+
calories: mealJson.Calories,
|
26 |
+
carbs: mealJson.CarbohydrateContent,
|
27 |
+
proteins: mealJson.ProteinContent,
|
28 |
+
fats: mealJson.FatContent,
|
29 |
+
type: mealJson.type?.toLowerCase() as MealType,
|
30 |
+
} satisfies Partial<IMeal>)));
|
31 |
+
|
32 |
+
console.log('inserting meals...')
|
33 |
+
await Meal.insertMany(data);
|
34 |
+
});
|
35 |
+
|