From b0be83784a1c6cbbd57bf8dc5b88fd2961011d72 Mon Sep 17 00:00:00 2001 From: Diana Chukhrai Date: Wed, 18 Mar 2026 13:49:32 +0100 Subject: [PATCH] Tasks 1 and 2 are complete --- package-lock.json | 1 - task-1/cocktail.js | 80 +++++- task-1/output/margarita.md | 27 +++ task-1/output/martini.md | 387 ++++++++++++++++++++++++++++++ task-2/post-cli/package-lock.json | 3 +- task-2/post-cli/src/services.js | 99 +++++++- 6 files changed, 586 insertions(+), 11 deletions(-) create mode 100644 task-1/output/margarita.md create mode 100644 task-1/output/martini.md diff --git a/package-lock.json b/package-lock.json index 65aa212..da4f394 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7,7 +7,6 @@ "": { "name": "core-assignment-week-10", "version": "1.0.0", - "hasInstallScript": true, "license": "CC BY-NC-SA 4.0", "dependencies": { "@inquirer/prompts": "^7.0.0", diff --git a/task-1/cocktail.js b/task-1/cocktail.js index 6fd5a62..3f784db 100644 --- a/task-1/cocktail.js +++ b/task-1/cocktail.js @@ -1,14 +1,77 @@ // API documentation: https://www.thecocktaildb.com/api.php -import path from 'path'; +import path from "path"; +import fsPromises from "node:fs/promises"; -const BASE_URL = 'https://www.thecocktaildb.com/api/json/v1/1'; +const BASE_URL = "https://www.thecocktaildb.com/api/json/v1/1"; // Add helper functions as needed here +function getAlcoString(strAlcoholic) { + if (strAlcoholic === "Alcoholic") { + return "Yes"; + } else { + return "No"; + } +} + +function generateMarkdown(data) { + const drinks = data.drinks; + let markdown = "# Cocktail Recipes"; + for (const drink of drinks) { + markdown += generateDrinkMarkdown(drink); + } + return markdown; +} + +function getIngredients(drink) { + let ingredients = ""; + + for (let i = 1; i <= 15; i++) { + const ingredient = drink["strIngredient" + i]; + const measure = (drink["strMeasure" + i] ?? "").trim(); + + if (!ingredient) break; + if (measure) { + ingredients += `- ${measure} ${ingredient}\n`; + } else { + ingredients += `- ${ingredient}\n`; + } + } + + return ingredients; +} + +function generateDrinkMarkdown(drink) { + return ` + + +## ${drink.strDrink} + +![${drink.strDrink}](${drink.strDrinkThumb}/medium) + +**Category**: ${drink.strCategory} + +**Alcoholic**: ${getAlcoString(drink.strAlcoholic)} + +### Ingredients + +${getIngredients(drink)} + + +### Instructions + +${drink.strInstructions} + +Serve in: ${drink.strGlass} + + +`; +} + export async function main() { if (process.argv.length < 3) { - console.error('Please provide a cocktail name as a command line argument.'); + console.error("Please provide a cocktail name as a command line argument."); return; } @@ -20,10 +83,21 @@ export async function main() { try { // 1. Fetch data from the API at the given URL + + const responce = await fetch(url); + if (!responce.ok) { + throw new Error("not ok" + responce.status); + } + const data = await responce.json(); + console.log(JSON.stringify(data.drinks[0], null, 2)); // 2. Generate markdown content to match the examples + const str = generateMarkdown(data); + // 3. Write the generated content to a markdown file as given by outPath + await fsPromises.writeFile(outPath, str); } catch (error) { // 4. Handle errors + console.error("No cocktails found with that name."); } } diff --git a/task-1/output/margarita.md b/task-1/output/margarita.md new file mode 100644 index 0000000..ee3bfeb --- /dev/null +++ b/task-1/output/margarita.md @@ -0,0 +1,27 @@ +# Cocktail Recipes + + +## Margarita + +![Margarita](https://www.thecocktaildb.com/images/media/drink/5noda61589575158.jpg/medium) + +**Category**: Ordinary Drink + +**Alcoholic**: Yes + +### Ingredients + +- 1 1/2 oz Tequila +- 1/2 oz Triple sec +- 1 oz Lime juice +- Salt + + + +### Instructions + +Rub the rim of the glass. + +Serve in: Cocktail glass + + diff --git a/task-1/output/martini.md b/task-1/output/martini.md new file mode 100644 index 0000000..e06803f --- /dev/null +++ b/task-1/output/martini.md @@ -0,0 +1,387 @@ +# Cocktail Recipes + + +## Martini + + ![Martini](https://www.thecocktaildb.com/images/media/drink/71t8581504353095.jpg/medium) + +**Category**: Cocktail + +**Alcoholic** Yes + +### Ingredients + +- 1 2/3 oz Gin +- 1/3 oz Dry Vermouth +- 1 Olive + + + +### Instructions + +Straight: Pour all ingredients into mixing glass with ice cubes. Stir well. Strain in chilled martini cocktail glass. Squeeze oil from lemon peel onto the drink, or garnish with olive. + +Serve in: Cocktail glass + + + + + +## Dry Martini + + ![Dry Martini](https://www.thecocktaildb.com/images/media/drink/6ck9yi1589574317.jpg/medium) + +**Category**: Cocktail + +**Alcoholic** Yes + +### Ingredients + +- 1 2/3 oz Gin +- 1/3 oz Dry Vermouth +- 1 Olive + + + +### Instructions + +Straight: Pour all ingredients into mixing glass with ice cubes. Stir well. Strain in chilled martini cocktail glass. Squeeze oil from lemon peel onto the drink, or garnish with olive. + +Serve in: Cocktail glass + + + + + +## Kiwi Martini + + ![Kiwi Martini](https://www.thecocktaildb.com/images/media/drink/bmxmyq1630407098.jpg/medium) + +**Category**: Cocktail + +**Alcoholic** Yes + +### Ingredients + +- 1/2 Kiwi +- 1 tsp Sugar Syrup +- 1 1/2 oz Vodka +- Garnish with Kiwi + + + +### Instructions + +The kiwi martini is a very fun vodka cocktail and it is one of the best drinks that makes use of fresh fruit. Though there are a few recipes floating around, this is one of the easiest and it is an absolutely delightful green martini to drink. + +For this recipe, you'll simply muddle slices of kiwi with simple syrup, then shake it with vodka. It's a drink that anyone can mix up in minutes and a perfect cocktail to show off your favorite vodka. + +Serve in: Cocktail glass + + + + + +## Vodka Martini + + ![Vodka Martini](https://www.thecocktaildb.com/images/media/drink/qyxrqw1439906528.jpg/medium) + +**Category**: Ordinary Drink + +**Alcoholic** Yes + +### Ingredients + +- 1 1/2 oz Vodka +- 3/4 oz Dry Vermouth +- 1 Olive + + + +### Instructions + +Shake the vodka and vermouth together with a number of ice cubes, strain into a cocktail glass, add the olive and serve. + +Serve in: Cocktail glass + + + + + +## Dirty Martini + + ![Dirty Martini](https://www.thecocktaildb.com/images/media/drink/vcyvpq1485083300.jpg/medium) + +**Category**: Cocktail + +**Alcoholic** Yes + +### Ingredients + +- 70ml/2fl oz Vodka +- 1 tbsp Dry Vermouth +- 2 tbsp Olive Brine +- 1 wedge Lemon +- 1 Olive + + + +### Instructions + +Pour the vodka, dry vermouth and olive brine into a cocktail shaker with a handful of ice and shake well. +Rub the rim of a martini glass with the wedge of lemon. +Strain the contents of the cocktail shaker into the glass and add the olive. +A dirty Martini contains a splash of olive brine or olive juice and is typically garnished with an olive. + +Serve in: Cocktail glass + + + + + +## Abbey Martini + + ![Abbey Martini](https://www.thecocktaildb.com/images/media/drink/2mcozt1504817403.jpg/medium) + +**Category**: Cocktail + +**Alcoholic** Yes + +### Ingredients + +- 2 shots Gin +- 1 shot Sweet Vermouth +- 1 shot Orange Juice +- 3 dashes Angostura Bitters + + + +### Instructions + +Put all ingredients into a shaker and mix, then strain contents into a chilled cocktail glass. + +Serve in: Cocktail glass + + + + + +## French Martini + + ![French Martini](https://www.thecocktaildb.com/images/media/drink/clth721504373134.jpg/medium) + +**Category**: Cocktail + +**Alcoholic** Yes + +### Ingredients + +- 4.5 cl Vodka +- 1.5 cl Raspberry Liqueur +- 1.5 cl pineapple juice + + + +### Instructions + +Pour all ingredients into shaker with ice cubes. Shake well and strain into a chilled cocktail glass. Squeeze oil from lemon peel onto the drink. + +Serve in: Cocktail glass + + + + + +## Bellini Martini + + ![Bellini Martini](https://www.thecocktaildb.com/images/media/drink/3h9wv51504389379.jpg/medium) + +**Category**: Ordinary Drink + +**Alcoholic** Yes + +### Ingredients + +- 8 cubes Ice +- 3 oz Vodka +- 1.5 oz Peach nectar +- 1.5 oz Peach schnapps +- 1 Lemon peel + + + +### Instructions + +Add ice cubes to shaker. +Add vodka. +Add peach schnapps. +Add peach nectar. +Shake. +Strain into glass. +Add lemon twist peel. + +Serve in: Cocktail glass + + + + + +## Espresso Martini + + ![Espresso Martini](https://www.thecocktaildb.com/images/media/drink/n0sx531504372951.jpg/medium) + +**Category**: Cocktail + +**Alcoholic** Yes + +### Ingredients + +- 5 cl Vodka +- 1 cl Kahlua +- 1 dash Sugar syrup + + + +### Instructions + +Pour ingredients into shaker filled with ice, shake vigorously, and strain into chilled martini glass + +Serve in: Cocktail glass + + + + + +## Pornstar Martini + + ![Pornstar Martini](https://www.thecocktaildb.com/images/media/drink/xjhjdf1630406071.jpg/medium) + +**Category**: Cocktail + +**Alcoholic** Yes + +### Ingredients + +- 3 cl Vodka +- 3 cl Passoa +- 1 cl Passion fruit juice +- 1 cl Lime +- 1 shot Prosecco + + + +### Instructions + +Straight: Pour all ingredients into mixing glass with ice cubes. Shake well. Strain in chilled martini cocktail glass. Cut passion fruit in half and use as garnish. Pour prosecco into a chilled shot glass and serve alongside the martini. + +Serve in: Cocktail glass + + + + + +## Cosmopolitan Martini + + ![Cosmopolitan Martini](https://www.thecocktaildb.com/images/media/drink/upxxpq1439907580.jpg/medium) + +**Category**: Cocktail + +**Alcoholic** Yes + +### Ingredients + +- 1/2 oz Cointreau +- 1 oz Vodka +- Juice of 1/2 Lime +- 1 splash Cranberry juice + + + +### Instructions + +Pour all ingredients in mixing glass half filled with ice, shake and strain into chilled Martini glass. + +Serve in: Cocktail Glass + + + + + +## Salted Toffee Martini + + ![Salted Toffee Martini](https://www.thecocktaildb.com/images/media/drink/3s6mlr1509551211.jpg/medium) + +**Category**: Cocktail + +**Alcoholic** Yes + +### Ingredients + +- 50 ml Gin +- 30 ml Chocolate liqueur +- 15 ml Amaretto +- Garnish Chocolate Sauce +- Grated Salted Chocolate + + + +### Instructions + +Add ice, toffee gin, chocolate liqueur and Amaretto to a cocktail shaker and shake vigorously. +Pour the chocolate syrup into a saucer and dip the top of a martini glass into the sauce. Grate some of the Willie\'s sea salt chocolate into another saucer and dip the coated glass, so the flakes stick to the sauce, creating a chocolate rim! +Pour the contents of the shaker into your chocolatey glass and sprinkle with more grated chocolate - enjoy! + +Serve in: Cocktail glass + + + + + +## Passion Fruit Martini + + ![Passion Fruit Martini](https://www.thecocktaildb.com/images/media/drink/6trfve1582473527.jpg/medium) + +**Category**: Cocktail + +**Alcoholic** Yes + +### Ingredients + +- 1 shot Vodka +- 1/2 shot Sugar Syrup +- Full Glass Passion fruit juice + + + +### Instructions + +Pour all ingredients into a glass and stir. Garnish with half a passion fruit piece. + +Serve in: Cocktail glass + + + + + +## Ziemes Martini Apfelsaft + + ![Ziemes Martini Apfelsaft](https://www.thecocktaildb.com/images/media/drink/xnzr2p1485619687.jpg/medium) + +**Category**: Ordinary Drink + +**Alcoholic** Yes + +### Ingredients + +- 4 cl Vermouth +- 16 cl Apple juice + + + +### Instructions + +Serve without ice. At least the juice shold have room temperature. + +Serve in: Collins Glass + + diff --git a/task-2/post-cli/package-lock.json b/task-2/post-cli/package-lock.json index 8c03ed4..776be27 100644 --- a/task-2/post-cli/package-lock.json +++ b/task-2/post-cli/package-lock.json @@ -7,8 +7,7 @@ "": { "name": "post-central-cli", "version": "1.0.0", - "hasInstallScript": true, - "license": "ISC", + "license": "CC BY-NC-SA 4.0", "dependencies": { "@inquirer/prompts": "^7.0.0", "chalk": "^5.6.2", diff --git a/task-2/post-cli/src/services.js b/task-2/post-cli/src/services.js index 2601f57..4bc48d6 100644 --- a/task-2/post-cli/src/services.js +++ b/task-2/post-cli/src/services.js @@ -1,5 +1,5 @@ // Change base URL for API requests to the local IP of the Post Central API server -const BASE_URL = 'http://localhost:3000'; +const BASE_URL = "http://localhost:3000"; // ============================================================================ // AUTH TOKEN - Stored after login/register, sent with every request @@ -37,7 +37,7 @@ const getHello = async () => { const response = await fetch(`${BASE_URL}/posts/hello`); if (!response.ok) { throw new Error( - `Failed to get hello: HTTP ${response.status} ${response.statusText}` + `Failed to get hello: HTTP ${response.status} ${response.statusText}`, ); } return await response.json(); @@ -54,6 +54,18 @@ const getHello = async () => { */ const getMe = async () => { // TODO + const response = await fetch(`${BASE_URL}/users/me`, { + headers: { + Authorization: `Bearer ${getToken()}`, + }, + }); + + if (!response.ok) { + throw new Error( + `Failed to get hello: HTTP ${response.status} ${response.statusText}`, + ); + } + return await response.json(); }; // ============================================================================ @@ -68,15 +80,15 @@ const getMe = async () => { */ const createUser = async (name, password) => { const response = await fetch(`${BASE_URL}/users/register`, { - method: 'POST', + method: "POST", headers: { - 'Content-Type': 'application/json', + "Content-Type": "application/json", }, body: JSON.stringify({ name, password }), }); if (!response.ok) { throw new Error( - `Failed to create user: HTTP ${response.status} ${response.statusText}` + `Failed to create user: HTTP ${response.status} ${response.statusText}`, ); } return await response.json(); @@ -90,6 +102,19 @@ const createUser = async (name, password) => { */ const loginUser = async (name, password) => { // TODO + const response = await fetch(`${BASE_URL}/users/login`, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ name, password }), + }); + if (!response.ok) { + throw new Error( + `Failed to login: HTTP ${response.status} ${response.statusText}`, + ); + } + return await response.json(); }; // ============================================================================ @@ -104,6 +129,21 @@ const loginUser = async (name, password) => { */ const createPost = async (text) => { // TODO + const response = await fetch(`${BASE_URL}/posts`, { + method: "POST", + headers: { + "Content-Type": "application/json", + Authorization: `Bearer ${getToken()}`, + }, + + body: JSON.stringify({ text }), + }); + if (!response.ok) { + throw new Error( + `Failed to create post: HTTP ${response.status} ${response.statusText}`, + ); + } + return await response.json(); }; /** @@ -113,6 +153,18 @@ const createPost = async (text) => { */ const getPosts = async () => { // TODO + const response = await fetch(`${BASE_URL}/posts/me`, { + headers: { + Authorization: `Bearer ${getToken()}`, + }, + }); + + if (!response.ok) { + throw new Error( + `Failed to get post: HTTP ${response.status} ${response.statusText}`, + ); + } + return await response.json(); }; /** @@ -123,6 +175,21 @@ const getPosts = async () => { */ const updatePost = async (id, text) => { // TODO + const response = await fetch(`${BASE_URL}/posts/${id}`, { + method: "PUT", + headers: { + "Content-Type": "application/json", + Authorization: `Bearer ${getToken()}`, + }, + + body: JSON.stringify({ text }), + }); + if (!response.ok) { + throw new Error( + `Failed to update post: HTTP ${response.status} ${response.statusText}`, + ); + } + return await response.json(); }; /** @@ -132,6 +199,17 @@ const updatePost = async (id, text) => { */ const deleteUser = async () => { // TODO + const response = await fetch(`${BASE_URL}/users/me`, { + method: "DELETE", + headers: { + Authorization: `Bearer ${getToken()}`, + }, + }); + if (!response.ok) { + throw new Error( + `Failed to delete post: HTTP ${response.status} ${response.statusText}`, + ); + } }; /** @@ -141,6 +219,17 @@ const deleteUser = async () => { */ const deletePost = async (id) => { // TODO + const response = await fetch(`${BASE_URL}/posts/${id}`, { + method: "DELETE", + headers: { + Authorization: `Bearer ${getToken()}`, + }, + }); + if (!response.ok) { + throw new Error( + `Failed to delete post: HTTP ${response.status} ${response.statusText}`, + ); + } }; // ============================================================================