Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,24 @@ import { swagger } from "@elysiajs/swagger";
import { swaggerConfig, welcomeMessage } from "./utils/app.config";
import { commentRoutes } from "./routes/comment.routes";
import { ShutdownHandler } from "./utils/shutdown-handler";
import { blogImageRoutes } from "./routes/blogImage.routes";
import { reactionRoutes } from './routes/reaction.routes';

const PORT = Number(process.env.PORT) || 5454;

const app = new Elysia()
.use(swagger(swaggerConfig))
.get("/", () => welcomeMessage)
.use(commentRoutes)
.use(blogImageRoutes)
.use(reactionRoutes)
.listen(5454);
.listen(PORT);

console.log(
`🦊 Elysia is running at ${app.server?.hostname}:${app.server?.port}`
);
console.log('Comments API: http://localhost:5454/comments - Done by JuanBap');
console.log('Reactions API: http://localhost:5454/reactions - Done by Ivan140826');
console.log(`Comments API: http://localhost:${PORT}/comments - Done by JuanBap`);
console.log(`Reactions API: http://localhost:${PORT}/reactions - Done by Ivan140826`);
console.log(`Blog Images API: http://localhost:${PORT}/blog-image - Done by Arkan56`);
//Shutdown of the server in a appropiate way
ShutdownHandler.setupSignalHandlers(app);
136 changes: 136 additions & 0 deletions src/routes/blogImage.routes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
import { Elysia } from 'elysia';
import { CreateBlogImageSchema, UpdateBlogImageSchema, BlogImageParamsSchema } from '../schemas/blogImage.schemas';
import { ResponseHelpers } from '../utils/response.helpers';
import { SupabaseAdaapter } from '../repositories/supabase.adapter';
import { IDatabase } from '../repositories/database.interface';

const TABLE = 'blog-image';
const db: IDatabase = SupabaseAdaapter.getInstance();

export const blogImageRoutes = new Elysia({ prefix: '/blog-image' })

// GET /blog-image - Get all blog images
.get('/', async () => {
try {
const response = await db.getAll(TABLE, { column: 'id', asc: true });
if (response.error) {
return ResponseHelpers.serverError(response.error);
}
const blogImages = response.data;
return ResponseHelpers.ok(
blogImages,
"Blog Images retrieved successfully",
blogImages.length
);
} catch (error) {
return ResponseHelpers.serverError("Failed to retrieve blog images");
}
})

// GET /blog-image/:id - Get a specific blog image
.get('/:id', async ({ params: { id } }) => {
try {
const blogImageId = parseInt(id);
const response = await db.getBy(TABLE, { id: blogImageId });
if (response.error) {
return ResponseHelpers.serverError(response.error);
}
const blogImages = response.data?.[0] || null;

if (!blogImages) {
return ResponseHelpers.notFound('Blog Image not found');
}

return ResponseHelpers.ok(blogImages, "Blog Image retrieved successfully");
} catch (error) {
return ResponseHelpers.serverError("Failed to retrieve blog image");
}
}, {
params: BlogImageParamsSchema
})

// GET /blog-image/blog/:blog_id - Get blog images for a specific blog
.get('/blog/:blog_id', async ({ params: { blog_id } }) => {
try {
const blogId = parseInt(blog_id);
const response = await db.getBy(TABLE, { blog_id: blogId }, { column: 'id', asc: true });
if (response.error) {
return ResponseHelpers.serverError(response.error);
}
const blogImages = response.data?.[0] || null;

if (!blogImages) {
return ResponseHelpers.notFound('Blog images not found');
}

return ResponseHelpers.ok(
blogImages,
`blog images for blog ${blogId} retrieved successfully`,
blogImages.length
);
} catch (error) {
return ResponseHelpers.serverError("Failed to retrieve blog images");
}
})

// POST /blog-image - Create a new blog image
.post('/', async ({ body }) => {
try {
const response = await db.insert(TABLE, body);
if (response.error) {
return ResponseHelpers.serverError(response.error);
}
const newBlogImage = response.data;
return ResponseHelpers.created(newBlogImage, "Blog Image created successfully");
} catch (error) {
return ResponseHelpers.serverError("Failed to create blog image");
}
}, {
body: CreateBlogImageSchema
})

// PUT /blog-image/:id - Update a blog image
.put('/:id', async ({ params: { id }, body }) => {
try {
const blogImageId = parseInt(id);
const response = await db.updateBy(TABLE, { id: blogImageId }, body);
if (response.error) {
return ResponseHelpers.serverError(response.error);
}

const updatedBlogImage = response.data?.[0] || null;;

if (!updatedBlogImage) {
return ResponseHelpers.notFound('Blog Image not found');
}

return ResponseHelpers.ok(updatedBlogImage, "Blog Image updated successfully");
} catch (error) {
return ResponseHelpers.serverError("Failed to update comment");
}
}, {
params: BlogImageParamsSchema,
body: UpdateBlogImageSchema
})

// DELETE /blog-image/:id - Delete a blog image
.delete('/:id', async ({ params: { id } }) => {
try {
const blogImageId = parseInt(id);
const response = await db.delete(TABLE, { id: blogImageId });
if (response.error) {
return ResponseHelpers.serverError(response.error);
}
const deletedBlogImage = response.data?.[0] || null;

if (!deletedBlogImage) {
return ResponseHelpers.notFound('Blog Image not found');
}

return ResponseHelpers.ok(deletedBlogImage, "Blog Image deleted successfully");
} catch (error) {
return ResponseHelpers.serverError("Failed to delete blog image");
}
}, {
params: BlogImageParamsSchema
});
37 changes: 37 additions & 0 deletions src/schemas/blogImage.schemas.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import {t} from "elysia";

// Schema for creating a new blog image
export const CreateBlogImageSchema = t.Object({
blog_id: t.Number({ minimum: 1 }),
url: t.String({
format: "uri",
description: "URL must be a valid URI"
}),
alt: t.Optional(t.String({
minLength: 1,
maxLength: 255,
description: "Alt text must be between 1-255 characters long"
}))
});

// Schema for updating a blog image
export const UpdateBlogImageSchema = t.Object({
url: t.Optional(t.String({
format: "uri",
description: "URL must be a valid URI"
})),
alt: t.Optional(t.String({
minLength: 1,
maxLength: 255,
description: "Alt text must be between 1-255 characters long"
}))
});

// Schema for deleting and retrieving a blog image (GET, DELETE http methods)
export const BlogImageParamsSchema = t.Object({
id: t.String({
// Regular expression for validating only numeric types
pattern: "^[0-9]+$",
description: "Blog Image ID must be numeric"
})
});
17 changes: 17 additions & 0 deletions src/types/blogImage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
export interface BlogImage {
id: number;
blog_id: number;
url: string;
alt: string;
}

export interface CreateBlogImageRequest {
blog_id: number;
url: string;
alt?: string;
}

export interface UpdateBlogImageRequest {
url?: string;
alt?: string;
}