structured
This commit is contained in:
parent
9f706092a7
commit
443b19c7c0
7 changed files with 143 additions and 47 deletions
72
src/api/index.ts
Normal file
72
src/api/index.ts
Normal file
|
|
@ -0,0 +1,72 @@
|
||||||
|
import { Elysia, t } from "elysia";
|
||||||
|
|
||||||
|
import { betterAuthView } from "../lib/auth/auth-view";
|
||||||
|
import { getAuthConfig, getBaseConfig } from "../lib/utils/env";
|
||||||
|
import { router } from "./routes";
|
||||||
|
|
||||||
|
const baseConfig = getBaseConfig();
|
||||||
|
const authConfig = getAuthConfig();
|
||||||
|
|
||||||
|
export const api = new Elysia({
|
||||||
|
name: baseConfig.SERVICE_NAME,
|
||||||
|
prefix: "/api",
|
||||||
|
detail: {
|
||||||
|
summary: `Get status`,
|
||||||
|
description: `Get status for ${baseConfig.SERVICE_NAME}`,
|
||||||
|
externalDocs: {
|
||||||
|
description: "Auth API",
|
||||||
|
url: `${authConfig.BETTER_AUTH_URL}/docs`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.all("/auth/*", betterAuthView)
|
||||||
|
.use(router)
|
||||||
|
.get(
|
||||||
|
"",
|
||||||
|
() => {
|
||||||
|
return {
|
||||||
|
message: `Server is running`,
|
||||||
|
success: true,
|
||||||
|
name: baseConfig.SERVICE_NAME,
|
||||||
|
status: "active",
|
||||||
|
docs: {
|
||||||
|
default: "/api/docs",
|
||||||
|
auth: "/api/auth/docs",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
{
|
||||||
|
response: {
|
||||||
|
200: t.Object(
|
||||||
|
{
|
||||||
|
message: t.String({ default: `Server is running` }),
|
||||||
|
success: t.Boolean({ default: true }),
|
||||||
|
name: t.String({ default: baseConfig.SERVICE_NAME }),
|
||||||
|
status: t.String({ default: `active` }),
|
||||||
|
docs: t.Object({
|
||||||
|
default: t.String({ default: "/api/docs" }),
|
||||||
|
auth: t.String({ default: "/api/auth/docs" }),
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "Success",
|
||||||
|
}
|
||||||
|
),
|
||||||
|
404: t.Object(
|
||||||
|
{
|
||||||
|
message: t.String({ default: `Not found` }),
|
||||||
|
success: t.Boolean({ default: false }),
|
||||||
|
name: t.String({ default: baseConfig.SERVICE_NAME }),
|
||||||
|
status: t.String({ default: `active` }),
|
||||||
|
docs: t.Object({
|
||||||
|
default: t.String({ default: "/api/docs" }),
|
||||||
|
auth: t.String({ default: "/api/auth/docs" }),
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "Not found",
|
||||||
|
}
|
||||||
|
),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
6
src/api/routes/index.ts
Normal file
6
src/api/routes/index.ts
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
|
||||||
|
import { Elysia, t } from "elysia";
|
||||||
|
import { noteRouter } from "./note/note.route";
|
||||||
|
|
||||||
|
|
||||||
|
export const router = new Elysia().use(noteRouter)
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import { and, eq, notExists } from "drizzle-orm";
|
import { and, eq, notExists } from "drizzle-orm";
|
||||||
import { db } from "../../db";
|
import { db } from "../../../db";
|
||||||
import { note } from "../../db/schema/note";
|
import { note } from "../../../db/schema/note";
|
||||||
import { CreateNote } from "./note.model";
|
import { CreateNote } from "./note.model";
|
||||||
|
|
||||||
export class NoteController {
|
export class NoteController {
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import { createSelectSchema } from "drizzle-typebox";
|
import { createSelectSchema } from "drizzle-typebox";
|
||||||
import { t } from "elysia";
|
import { t } from "elysia";
|
||||||
import { note } from "../../db/schema/note";
|
import { note } from "../../../db/schema/note";
|
||||||
import { InferInsertModel, InferSelectModel } from "drizzle-orm";
|
import { InferInsertModel, InferSelectModel } from "drizzle-orm";
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
import { Elysia, error, t } from "elysia";
|
import { Elysia, error, t } from "elysia";
|
||||||
import { createNoteSchema, NoteSchema, successDeleteNoteResponse, successGetNoteResponse } from "./note.model";
|
import { createNoteSchema, NoteSchema, successDeleteNoteResponse, successGetNoteResponse } from "./note.model";
|
||||||
import { NoteController } from "./note.controller";
|
import { NoteController } from "./note.controller";
|
||||||
import { userMiddleware } from "../../middlewares/auth-middleware";
|
import { userMiddleware } from "../../../middlewares/auth-middleware";
|
||||||
import { commonResponses } from "../../lib/utils/common";
|
import { commonResponses } from "../../../lib/utils/common";
|
||||||
|
|
||||||
export const noteRouter = new Elysia({
|
export const noteRouter = new Elysia({
|
||||||
prefix: "/note",
|
prefix: "/note",
|
||||||
|
|
@ -18,6 +18,15 @@ export const noteRouter = new Elysia({
|
||||||
note: NoteSchema,
|
note: NoteSchema,
|
||||||
})
|
})
|
||||||
.derive(({ request }) => userMiddleware(request))
|
.derive(({ request }) => userMiddleware(request))
|
||||||
|
.onError(({ error, code, }) => {
|
||||||
|
console.error(error);
|
||||||
|
return {
|
||||||
|
message: "",
|
||||||
|
success: false,
|
||||||
|
data: null,
|
||||||
|
error: code.toString()
|
||||||
|
};
|
||||||
|
})
|
||||||
.get(
|
.get(
|
||||||
"",
|
"",
|
||||||
async ({ note, user, query}) => {
|
async ({ note, user, query}) => {
|
||||||
61
src/index.ts
61
src/index.ts
|
|
@ -2,30 +2,47 @@ import { Elysia } from "elysia";
|
||||||
import { swagger } from "@elysiajs/swagger";
|
import { swagger } from "@elysiajs/swagger";
|
||||||
import { opentelemetry } from "@elysiajs/opentelemetry";
|
import { opentelemetry } from "@elysiajs/opentelemetry";
|
||||||
import { serverTiming } from "@elysiajs/server-timing";
|
import { serverTiming } from "@elysiajs/server-timing";
|
||||||
import { cors } from '@elysiajs/cors'
|
import { cors } from "@elysiajs/cors";
|
||||||
import { noteRouter } from "./api/note/note.route";
|
|
||||||
import { betterAuthView } from "./lib/auth/auth-view";
|
|
||||||
import { getBaseConfig, validateEnv } from "./lib/utils/env";
|
import { getBaseConfig, validateEnv } from "./lib/utils/env";
|
||||||
|
import { api } from "./api";
|
||||||
|
|
||||||
const baseConfig = getBaseConfig()
|
const baseConfig = getBaseConfig();
|
||||||
|
|
||||||
const app = new Elysia()
|
|
||||||
.use(cors())
|
|
||||||
.use(opentelemetry({
|
|
||||||
"serviceName": baseConfig.SERVICE_NAME
|
|
||||||
}))
|
|
||||||
.use(swagger({
|
|
||||||
path: "/docs",
|
|
||||||
}))
|
|
||||||
.use(serverTiming())
|
|
||||||
.onError(({ error, code }) => {
|
|
||||||
if (code === "NOT_FOUND") return "Not Found :(";
|
|
||||||
console.error(error);
|
|
||||||
})
|
|
||||||
.all("/api/auth/*", betterAuthView)
|
|
||||||
.use(noteRouter)
|
|
||||||
.get("/", () => `${baseConfig.SERVICE_NAME} Server is Running`)
|
|
||||||
|
|
||||||
validateEnv();
|
validateEnv();
|
||||||
|
const app = new Elysia()
|
||||||
|
.use(cors())
|
||||||
|
.use(
|
||||||
|
opentelemetry({
|
||||||
|
serviceName: baseConfig.SERVICE_NAME,
|
||||||
|
})
|
||||||
|
)
|
||||||
|
.use(serverTiming())
|
||||||
|
.use(
|
||||||
|
swagger({
|
||||||
|
path: "/api/docs",
|
||||||
|
documentation: {
|
||||||
|
info: {
|
||||||
|
title: baseConfig.SERVICE_NAME,
|
||||||
|
version: "0.0.1",
|
||||||
|
description: `API docs for ${baseConfig.SERVICE_NAME}`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
)
|
||||||
|
.onError(({ error, code }) => {
|
||||||
|
if (code === "NOT_FOUND")
|
||||||
|
return {
|
||||||
|
message: `Not Found`,
|
||||||
|
success: false,
|
||||||
|
name: baseConfig.SERVICE_NAME,
|
||||||
|
status: "active",
|
||||||
|
docs: {
|
||||||
|
default: "/api/docs",
|
||||||
|
auth: "/api/auth/docs",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
console.error(error);
|
||||||
|
})
|
||||||
|
.use(api);
|
||||||
app.listen(baseConfig.PORT);
|
app.listen(baseConfig.PORT);
|
||||||
console.log(`Server is running on: http://127.0.0.1:${baseConfig.PORT}`)
|
console.log(`Server is running on: http://127.0.0.1:${baseConfig.PORT}`);
|
||||||
|
|
|
||||||
|
|
@ -5,10 +5,8 @@ export const commonResponses = {
|
||||||
{
|
{
|
||||||
data: t.Null(),
|
data: t.Null(),
|
||||||
success: t.Boolean({ default: false }),
|
success: t.Boolean({ default: false }),
|
||||||
message: t.String({ default: "Bad Request" }),
|
message: t.String({ default: "" }),
|
||||||
error: t.String({
|
error: t.Number({ default: 400 }),
|
||||||
default: "Missing parameters, or invalid parameters.",
|
|
||||||
}),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
description:
|
description:
|
||||||
|
|
@ -19,10 +17,8 @@ export const commonResponses = {
|
||||||
{
|
{
|
||||||
data: t.Null(),
|
data: t.Null(),
|
||||||
success: t.Boolean({ default: false }),
|
success: t.Boolean({ default: false }),
|
||||||
message: t.String({ default: "Unauthorized" }),
|
message: t.String({ default: "" }),
|
||||||
error: t.String({
|
error: t.Number({ default: 401 }),
|
||||||
default: "User needs to sign in to access this resource",
|
|
||||||
}),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
description: "Unauthorized. Due to missing or invalid authentication.",
|
description: "Unauthorized. Due to missing or invalid authentication.",
|
||||||
|
|
@ -32,10 +28,8 @@ export const commonResponses = {
|
||||||
{
|
{
|
||||||
data: t.Null(),
|
data: t.Null(),
|
||||||
success: t.Boolean({ default: false }),
|
success: t.Boolean({ default: false }),
|
||||||
message: t.String({ default: "Forbidden" }),
|
message: t.String({ default: "" }),
|
||||||
error: t.String({
|
error: t.Number({ default: 403 }),
|
||||||
default: "User does not have permission to access this resource",
|
|
||||||
}),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
description:
|
description:
|
||||||
|
|
@ -46,8 +40,8 @@ export const commonResponses = {
|
||||||
{
|
{
|
||||||
data: t.Null(),
|
data: t.Null(),
|
||||||
success: t.Boolean({ default: false }),
|
success: t.Boolean({ default: false }),
|
||||||
message: t.String({ default: "Not Found" }),
|
message: t.String({ default: "" }),
|
||||||
error: t.String({ default: "Requested resource has not found" }),
|
error: t.Number({ default: 404 }),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
description: "Not Found. The requested resource was not found.",
|
description: "Not Found. The requested resource was not found.",
|
||||||
|
|
@ -57,10 +51,8 @@ export const commonResponses = {
|
||||||
{
|
{
|
||||||
data: t.Null(),
|
data: t.Null(),
|
||||||
success: t.Boolean({ default: false }),
|
success: t.Boolean({ default: false }),
|
||||||
message: t.String({ default: "Too Many Requests" }),
|
message: t.String({ default: "" }),
|
||||||
error: t.String({
|
error: t.Number({ default: 429 }),
|
||||||
default: "RUser has exceeded the rate limit. Try again later.",
|
|
||||||
}),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
description:
|
description:
|
||||||
|
|
@ -71,8 +63,8 @@ export const commonResponses = {
|
||||||
{
|
{
|
||||||
data: t.Null(),
|
data: t.Null(),
|
||||||
success: t.Boolean({ default: false }),
|
success: t.Boolean({ default: false }),
|
||||||
message: t.String({ default: "Internal Server Error" }),
|
message: t.String({ default: "" }),
|
||||||
error: t.String({ default: "Server faced an error" }),
|
error: t.Number({ default: 500 }),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
description:
|
description:
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue