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 }