remix-demo

react router (remix) demo

git clone https://9o.is/git/remix-demo.git

nutritionix.server.ts

(1856B)


      1 /*
      2 curl -X POST -H "Content-Type: application/json" -H "x-app-id: a12c6d80" -H "x-app-key: c492aa7a75ceb2b81a486a9f1416f42a" -d '{"query":"banana"}' "https://trackapi.nutritionix.com/v2/natural/nutrients"
      3 
      4  curl -H "x-app-id: a12c6d80" -H "x-app-key: c492aa7a75ceb2b81a486a9f1416f42a" "https://trackapi.nutritionix.com/v2/search/instant?query=banana"
      5 
      6 */
      7 
      8 import invariant from "tiny-invariant";
      9 
     10 interface Food {
     11   name: string;
     12   calories: number;
     13 }
     14 interface FoodSearch {
     15   food_name: string;
     16   nf_calories?: number;
     17 }
     18 
     19 interface InstantSearch {
     20   common?: FoodSearch[];
     21 }
     22 
     23 interface NutrientsSearch {
     24   foods: FoodSearch[];
     25 }
     26 
     27 const { NUTRITIONIX_APP_ID, NUTRITIONIX_APP_KEY } = process.env;
     28 const APP_ID = NUTRITIONIX_APP_ID;
     29 const APP_KEY = NUTRITIONIX_APP_KEY;
     30 
     31 invariant(typeof APP_ID === "string", "NUTRITIONIX_APP_ID env var not set");
     32 invariant(typeof APP_KEY === "string", "NUTRITIONIX_APP_KEY env var not set");
     33 
     34 const BASE_URL = "https://trackapi.nutritionix.com/v2";
     35 const headers = {
     36   "x-app-id": APP_ID,
     37   "x-app-key": APP_KEY,
     38 };
     39 
     40 export async function getFoodByName(query: string): Promise<Food | null> {
     41   const response = await fetch(`${BASE_URL}/natural/nutrients`, {
     42     method: "POST",
     43     headers: { ...headers, "Content-Type": "application/json" },
     44     body: JSON.stringify({ query }),
     45   });
     46 
     47   const result: NutrientsSearch = await response.json();
     48   const food = result.foods?.[0];
     49 
     50   if (!food) return null;
     51   return {
     52     name: food.food_name,
     53     calories: Math.round(food.nf_calories ?? 0),
     54   };
     55 }
     56 
     57 export async function searchFoodNames(query: string): Promise<string[]> {
     58   const response = await fetch(
     59     `${BASE_URL}/search/instant?query=${encodeURIComponent(query)}`,
     60     { headers }
     61   );
     62 
     63   const result: InstantSearch = await response.json();
     64   return !result.common ? [] : result.common.map((_) => _.food_name);
     65 }