diff --git a/New_APIs/Heroku API/README.md b/New_APIs/Heroku API/README.md new file mode 100644 index 0000000..d9d3600 --- /dev/null +++ b/New_APIs/Heroku API/README.md @@ -0,0 +1,15 @@ +# Heroku API + +## Description + +A basic API built using Node.js and Express to interact with the Heroku platform. It allows users to deploy applications, scale dynos, and retrieve logs programmatically. + +## Installation + +To install the required packages, run: + +```bash +npm install express +npm install axios +npm install nodemon +npm install diff --git a/New_APIs/Heroku API/manifest.json b/New_APIs/Heroku API/manifest.json new file mode 100644 index 0000000..4d3b3ad --- /dev/null +++ b/New_APIs/Heroku API/manifest.json @@ -0,0 +1,15 @@ +{ + "short_name": "HerokuAPI", + "name": "Heroku API", + "icons": [ + { + "src": "icon.png", + "type": "image/png", + "sizes": "512x512" + } + ], + "start_url": "/index.html", + "display": "standalone", + "theme_color": "#000000", + "background_color": "#ffffff" +} diff --git a/New_APIs/Heroku API/package.json b/New_APIs/Heroku API/package.json new file mode 100644 index 0000000..99eed8c --- /dev/null +++ b/New_APIs/Heroku API/package.json @@ -0,0 +1,20 @@ +{ + "name": "heroku-api", + "version": "1.0.0", + "description": "A simple API to interact with Heroku platform for deployments, scaling, and logs.", + "main": "src/index.js", + "scripts": { + "start": "node src/index.js", + "dev": "nodemon src/index.js" + }, + "author": "", + "license": "ISC", + "dependencies": { + "axios": "^0.27.2", + "express": "^4.18.2" + }, + "devDependencies": { + "nodemon": "^2.0.22" + } + } + \ No newline at end of file diff --git a/New_APIs/Heroku API/packet-lock.json b/New_APIs/Heroku API/packet-lock.json new file mode 100644 index 0000000..82dcfb6 --- /dev/null +++ b/New_APIs/Heroku API/packet-lock.json @@ -0,0 +1,20 @@ +{ + "name": "heroku-api", + "version": "1.0.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "heroku-api", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "axios": "^0.27.2", + "express": "^4.18.2", + "nodemon": "^2.0.22" + } + }, + // Other dependencies + } + } + \ No newline at end of file diff --git a/New_APIs/Heroku API/public/index.html b/New_APIs/Heroku API/public/index.html new file mode 100644 index 0000000..e704c49 --- /dev/null +++ b/New_APIs/Heroku API/public/index.html @@ -0,0 +1,62 @@ + + + + + + + Heroku API + + +

Heroku API

+
+

Deploy

+ + + +

Scale

+ + + + +

Logs

+ + + +
+ + + + diff --git a/New_APIs/Heroku API/public/styles.css b/New_APIs/Heroku API/public/styles.css new file mode 100644 index 0000000..748b3b1 --- /dev/null +++ b/New_APIs/Heroku API/public/styles.css @@ -0,0 +1,76 @@ +body { + font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; + margin: 0; + padding: 0; + display: flex; + flex-direction: column; + align-items: center; + background: linear-gradient(135deg, #f06, #00f); + color: #fff; +} + +h1 { + margin-top: 30px; + font-size: 2.5em; +} + +h2 { + margin-top: 20px; + font-size: 1.8em; +} + +#app { + margin-top: 20px; + width: 90%; + max-width: 600px; + background-color: rgba(255, 255, 255, 0.8); + color: #333; + padding: 20px; + border-radius: 10px; + box-shadow: 0 0 20px rgba(0, 0, 0, 0.1); +} + +input, button, select { + margin: 10px 0; + padding: 12px; + width: 100%; + box-sizing: border-box; + border-radius: 5px; + border: 1px solid #ddd; + font-size: 1em; +} + +button { + background-color: #007BFF; + color: #fff; + border: none; + cursor: pointer; + transition: background-color 0.3s ease; +} + +button:hover { + background-color: #0056b3; +} + +ul { + list-style-type: none; + padding: 0; + margin-top: 20px; + background: rgba(255, 255, 255, 0.9); + color: #333; + padding: 20px; + border-radius: 8px; + box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); +} + +li { + margin: 10px 0; + padding: 10px; + background-color: rgba(233, 233, 233, 0.9); + border-radius: 5px; + border: 1px solid #ccc; +} + +input::placeholder, select::placeholder { + color: #aaa; +} diff --git a/New_APIs/Heroku API/src/index.js b/New_APIs/Heroku API/src/index.js new file mode 100644 index 0000000..fe61581 --- /dev/null +++ b/New_APIs/Heroku API/src/index.js @@ -0,0 +1,59 @@ +const express = require('express'); +const axios = require('axios'); +const path = require('path'); +const app = express(); +const PORT = process.env.PORT || 3000; + +app.use(express.json()); +app.use(express.static(path.join(__dirname, '../public'))); + +const HEROKU_API_KEY = 'your_heroku_api_key'; + +const headers = { + 'Authorization': `Bearer ${HEROKU_API_KEY}`, + 'Accept': 'application/vnd.heroku+json; version=3', + 'Content-Type': 'application/json' +}; + +app.post('/deploy', async (req, res) => { + const { app_name, source_url } = req.body; + const url = `https://api.heroku.com/apps/${app_name}/builds`; + const payload = { source_blob: { url: source_url } }; + + try { + const response = await axios.post(url, payload, { headers }); + res.json(response.data); + } catch (error) { + res.status(error.response.status).json(error.response.data); + } +}); + +app.post('/scale', async (req, res) => { + const { app_name, dyno_type, quantity } = req.body; + const url = `https://api.heroku.com/apps/${app_name}/formation`; + const payload = { updates: [{ type: dyno_type, quantity }] }; + + try { + const response = await axios.patch(url, payload, { headers }); + res.json(response.data); + } catch (error) { + res.status(error.response.status).json(error.response.data); + } +}); + +app.get('/logs', async (req, res) => { + const { app_name } = req.query; + const url = `https://api.heroku.com/apps/${app_name}/log-sessions`; + const payload = { dyno: 'web', lines: 100, source: 'app', tail: true }; + + try { + const response = await axios.post(url, payload, { headers }); + res.json(response.data); + } catch (error) { + res.status(error.response.status).json(error.response.data); + } +}); + +app.listen(PORT, () => { + console.log(`Server is running on port ${PORT}`); +});