First Commit

This commit is contained in:
Caleb Braaten 2024-04-03 18:18:32 -07:00
commit 6bcac29211
5 changed files with 216 additions and 0 deletions

25
database.ts Normal file
View File

@ -0,0 +1,25 @@
import { Database } from "bun:sqlite";
// all of these do the same thing
const db = new Database("mydb.sqlite");
createTable();
function createTable() {
db.run(`
CREATE TABLE IF NOT EXISTS images (
id INTEGER PRIMARY KEY AUTOINCREMENT,
image BLOB,
type TEXT
);
`);
}
export const query_getImages = db.query(`SELECT id, type FROM images`);
export const query_getImage = db.query(
`SELECT image, type FROM images WHERE id = $id`,
);
export const query_saveImage = db.query(
`INSERT INTO images (image, type) VALUES ($image, $type) RETURNING id`,
);

77
index.html Normal file
View File

@ -0,0 +1,77 @@
<!DOCTYPE >
<html>
<head>
<title>Image Uploader</title>
<style>
body {
margin-top: 50px;
margin-bottom: 50px;
text-align: center;
}
form {
display: flex;
gap: 20px;
flex-direction: column;
align-items: center;
}
#image-container {
display: flex;
flex-wrap: wrap;
justify-content: center;
}
img {
width: 200px;
height: 200px;
object-fit: cover;
margin: 10px;
}
</style>
</head>
<body>
<h1>Image Uploader</h1>
<form action="/upload" method="post" enctype="multipart/form-data">
<img id="filePreview" src="https://via.placeholder.com/200" />
<input id="fileInput" type="file" name="image" accept="image/*" />
<input type="submit" value="Upload" />
</form>
<div id="image-container">
<!-- Images will be displayed here -->
</div>
</body>
<script>
// Preview Image Logic
const imageInput = document.getElementById("fileInput");
const imagePreview = document.getElementById("filePreview");
imageInput.addEventListener("change", function () {
const file = this.files[0];
if (file) {
const reader = new FileReader();
reader.onload = function () {
imagePreview.src = reader.result;
};
reader.readAsDataURL(file);
}
});
</script>
<script>
// Fetch Uploaded Images Logic
fetch("/images")
.then((response) => response.json())
.then(({ images }) => {
console.log(images);
const imageContainer =
document.getElementById("image-container");
images.forEach((image) => {
let extension = image.type.split("/")[1];
const img = document.createElement("img");
img.src = `/image/${image.id}.${extension}`;
imageContainer.appendChild(img);
});
});
</script>
</html>

28
index.ts Normal file
View File

@ -0,0 +1,28 @@
import { getImages, getImage, saveImage } from "./routes";
const server = Bun.serve({
port: 8080,
async fetch(req) {
const path = new URL(req.url).pathname;
// send back the image paths uploaded
if (path === "/images") {
return await getImages(req);
}
// send back the image that was uploaded
if (path.split("/")[1] === "image") {
return await getImage(req);
}
// receive image upload fromt the client
if (req.method === "POST" && path === "/upload") {
return await saveImage(req);
}
// default to sending back the web app
return new Response(Bun.file("./index.html"));
},
});
console.log(`Listening on ${server.url}`);

9
package.json Normal file
View File

@ -0,0 +1,9 @@
{
"scripts": {
"dev": "bun --hot run index.ts"
},
"dependencies": {},
"devDependencies": {
"@types/bun": "^1.0.8"
}
}

77
routes.ts Normal file
View File

@ -0,0 +1,77 @@
import { query_getImages, query_getImage, query_saveImage } from "./database";
export function getImages(req: Request): Promise<Response> {
return new Promise(async (resolve, reject) => {
let images = query_getImages.all();
if (!images) {
const ErrorResponse = new Response("No Images Found", { status: 404 });
resolve(ErrorResponse);
}
const imageList = await query_getImages.all();
console.log("imageList:", imageList);
const response = Response.json({ images: imageList });
resolve(response);
});
}
export function getImage(req: Request): Promise<Response> {
return new Promise(async (resolve, reject) => {
const path = new URL(req.url).pathname;
const entity = path.split("/")[2]; // images/1.png
const imageID = entity.split(".")[0]; //1
let image: any = query_getImage.get(imageID); // DB Call
if (!image) {
const ErrorResponse = new Response("No Images Found", { status: 404 });
reject(ErrorResponse);
}
// Send image as response
const base64Image = image.image;
const buffer = Buffer.from(base64Image, "base64");
let response = new Response(new Blob([buffer]), {
headers: { "Content-Type": image.type },
});
resolve(response);
});
}
export function saveImage(req: Request): Promise<Response> {
const allowedFileTypes = ["image/png", "image/jpeg", "image/gif"];
return new Promise(async (resolve, reject) => {
const formdata = await req.formData();
const image: Blob = formdata.get("image");
if (!image || allowedFileTypes.includes(image.type) === false) {
const ErrorResponse = new Response("Did not recieve valid image", {
status: 400,
});
resolve(ErrorResponse);
}
// Transform image to storage format
let buffer = await image.arrayBuffer();
let base64Image = Buffer.from(buffer).toString("base64");
// Save image to DB
query_saveImage.get(base64Image, image.type);
// buffer = Buffer.from(base64Image, "base64");
// // Testing getImage Logic as Well
// let response = new Response(new Blob([buffer]), {
// headers: { "Content-Type": image.type },
// });
// resolve(response);
// Return Redirect(App Logic)
resolve(Response.redirect("/"));
});
}