Introduction: The Need for Manual Recipe Entry

Welcome back! So far, you have set up your Express app with TypeScript, designed your database models using Prisma, and learned how to safely reset your database. Now, let’s take the next step: adding recipes to your app.

While it’s possible to add recipes automatically or through an API, sometimes you need a simple way to enter recipes by hand. This is especially useful for testing, quick data entry, or when you want to add a recipe that you found or created yourself. In this lesson, you’ll learn how to build a TypeScript script that lets you add recipes directly from the command line. This script will prompt you for the recipe name, ingredients, and steps, then save everything to your database using Prisma.

By the end of this lesson, you’ll be able to run a script, enter a new recipe, and see it appear in your app’s database. This is a practical tool that will help you test and grow your cooking app.

Quick Recall: Models and Database Access

Before we dive in, let’s quickly remind ourselves of the key models and how we interact with the database. You’ve already created Recipe and Ingredient models using Prisma. These models are connected by a many-to-many relationship, which means a recipe can have many ingredients, and an ingredient can belong to many recipes.

Here’s a quick reminder of what these models look like in your Prisma schema:

model Ingredient {
  id      Int      @id @default(autoincrement())
  name    String
  recipes RecipeIngredient[]
}

model Recipe {
  id          Int      @id @default(autoincrement())
  name        String
  steps       String
  ingredients RecipeIngredient[]
  reviews     Review[]
}

model RecipeIngredient {
  recipeId     Int
  ingredientId Int
  recipe       Recipe     @relation(fields: [recipeId], references: [id])
  ingredient   Ingredient @relation(fields: [ingredientId], references: [id])

  @@id([recipeId, ingredientId])
}

You interact with your database using the Prisma Client. This allows you to create, find, and link records in your database using TypeScript.

Preparing the Script Environment

To create a script that can add recipes, you need to make sure it can access your Prisma client and models. This means importing the Prisma client and any other necessary modules.

Here’s how you set up your script environment in TypeScript:

#!/usr/bin/env tsx
import inquirer from "inquirer";
import { prisma } from "../cooking_helper/src/db";
  • The first line (#!/usr/bin/env tsx) allows you to run the script directly from the command line if you have tsx installed.
  • inquirer is a popular package for interactive command-line prompts.
  • The Prisma client is imported from your project’s database module.

With this setup, your script can interact with your database and prompt the user for input.

Collecting Recipe Information from the User

Now, let’s build the part of the script that asks the user for recipe details. We want to collect three things: the recipe name, a list of ingredients, and the steps.

We’ll use inquirer to prompt the user for each piece of information, validate their input, and collect the data.

Prompting for the Recipe Name

We start by asking for the recipe name using inquirer:

const { name } = await inquirer.prompt<{ name: string }>([
  { type: "input", name: "name", message: "🍽️ Recipe name:" }
]);
const recipeName = name.trim();
if (!recipeName) {
  console.log("❌ Recipe name is required.");
  return;
}
  • inquirer.prompt displays a prompt and waits for the user to type something.
  • .trim() removes any extra spaces from the beginning or end.
  • If the user doesn’t enter a name, we print an error and stop.
Prompting for Ingredients

Next, we ask for ingredients, one per line. The user can press Enter on an empty line to finish:

async function promptIngredients() {
  const items: string[] = [];
  for (;;) {
    const { item } = await inquirer.prompt<{ item: string }>([
      { type: "input", name: "item", message: "> Enter ingredient (blank to finish):" }
    ]);
    const trimmed = item.trim();
    if (!trimmed) break;
    items.push(trimmed);
  }
  return items;
}
  • We use a loop to keep asking for ingredients until the user enters a blank line.
  • Each ingredient is added to a list.
Prompting for Steps

Finally, we ask for the steps. The user can type as many lines as they want and type END on a line by itself to finish:

async function promptSteps() {
  console.log("Enter steps. Type END on a line by itself to finish.");
  const lines: string[] = [];
  for (;;) {
    const { line } = await inquirer.prompt<{ line: string }>([
      { type: "input", name: "line", message: "" }
    ]);
    if (line.trim().toUpperCase() === "END") break;
    lines.push(line);
  }
  return lines.join("\n");
}
  • This function collects each line of the steps until the user types END.
  • All lines are joined together into a single string.
Example Output

Here’s what it looks like when you run this part of the script:

🍽️ Recipe name: Chocolate Chip Cookies
> Enter ingredient (blank to finish): flour
> Enter ingredient (blank to finish): sugar
> Enter ingredient (blank to finish): chocolate chips
> Enter ingredient (blank to finish): 
Enter steps. Type END on a line by itself to finish.
Mix all ingredients.
Bake at 350F for 12 minutes.
END
Saving the Recipe and Ingredients
Example Output

If everything works, you’ll see:

✅ Recipe 'Chocolate Chip Cookies' added successfully with 3 ingredients.
Summary And What’s Next

In this lesson, you learned how to build a TypeScript script that lets you add recipes manually to your cooking app’s database. You saw how to:

  • Set up your script to access the Prisma client and database models
  • Prompt the user for recipe details and validate their input using inquirer
  • Create or reuse ingredients and link them to a new recipe
  • Save everything to the database and confirm success

This script is a practical tool for quickly adding recipes, testing your app, or entering your own creations. Now that you understand how it works, you’re ready to try it yourself in the practice exercises. Focus on running the script, entering different recipes, and checking your database to see the results. This hands-on practice will help you get comfortable with both TypeScript scripting and database operations in your Express app. Good luck!

Sign up
Join the 1M+ learners on CodeSignal
Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal