First Commit
This commit is contained in:
commit
6bcac29211
25
database.ts
Normal file
25
database.ts
Normal 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
77
index.html
Normal 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
28
index.ts
Normal 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
9
package.json
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"scripts": {
|
||||
"dev": "bun --hot run index.ts"
|
||||
},
|
||||
"dependencies": {},
|
||||
"devDependencies": {
|
||||
"@types/bun": "^1.0.8"
|
||||
}
|
||||
}
|
77
routes.ts
Normal file
77
routes.ts
Normal 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("/"));
|
||||
});
|
||||
}
|
Loading…
Reference in New Issue
Block a user