feat: actually running the server

This commit is contained in:
2025-11-10 21:33:30 +00:00
parent d4fc41c6bf
commit 4371b26423
15 changed files with 850 additions and 920 deletions

View File

@@ -1,16 +1,16 @@
import { z } from 'zod';
import dotenv from 'dotenv';
import { z } from "zod";
import dotenv from "dotenv";
dotenv.config();
dotenv.config({ quiet: true });
const envSchema = z.object({
PORT: z
.string()
.refine(
(port) => parseInt(port) > 0 && parseInt(port) < 65536,
"Invalid port number"
),
DATABASE_URL: z.string().min(10)
PORT: z
.string()
.refine(
(port) => parseInt(port) > 0 && parseInt(port) < 65536,
"Invalid port number",
),
DATABASE_URL: z.string().min(10),
});
type Env = z.infer<typeof envSchema>;

View File

@@ -0,0 +1,39 @@
import { ENV } from "./env";
import { signPetition } from "./routes/sign-petition";
const CORS_HEADERS = {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, OPTIONS",
"Access-Control-Allow-Headers": "Content-Type, Authorization",
};
const allowCors = async (_: Request): Promise<Response> => {
return new Response(null, { status: 200, headers: CORS_HEADERS });
};
type Handler = (req: Request) => Promise<Response>;
const withCors = (fn: Handler): Handler => {
return async (req) => {
const res = await fn(req);
for (const [header, value] of Object.entries(CORS_HEADERS)) {
res.headers.set(header, value);
}
return res;
};
};
const server = Bun.serve({
port: ENV.PORT,
routes: {
"/health": new Response("alive!"),
"/sign-petition": {
POST: withCors(signPetition),
OPTIONS: allowCors,
},
},
});
console.log(`server running on ${server.url}`);

View File

@@ -1,8 +1,9 @@
import { pgTable, text, uuid } from "drizzle-orm/pg-core";
import { pgTable, text, uuid, timestamp } from "drizzle-orm/pg-core";
export const signaturesTable = pgTable("signatures", {
id: uuid().primaryKey().defaultRandom(),
email: text().notNull(),
name: text(),
comment: text(),
id: uuid().primaryKey().defaultRandom(),
email: text().notNull(),
name: text(),
comment: text(),
createdAt: timestamp().defaultNow().notNull(),
});

View File

@@ -1,26 +1,29 @@
import type z from "zod";
import { insertSignature } from "../models";
import { signedPetitionSchema, signPetitionSchema } from 'types'
import { signedPetitionSchema, signPetitionSchema } from "types";
export const signPetition = async (req: Request): Promise<Response> => {
const body = await req.json()
const body = await req.json();
const validatedBody = signPetitionSchema.safeParse(body);
if (!validatedBody.success) {
return Response.json({ error: validatedBody.error }, { status: 400 });
}
const validatedBody = signPetitionSchema.safeParse(body);
if (!validatedBody.success) {
console.log(validatedBody.error);
return Response.json({ error: validatedBody.error }, { status: 400 });
}
const _insertedSignature = await insertSignature({
email: validatedBody.data.email,
name: validatedBody.data.name,
comment: validatedBody.data.comment,
})
const insertedSignature = await insertSignature({
email: validatedBody.data.email,
name: validatedBody.data.name,
comment: validatedBody.data.comment,
});
if (!_insertedSignature) {
return Response.json({ error: "inserting signature in database" }, { status: 500 });
}
if (!insertedSignature) {
return Response.json(
{ error: "inserting signature in database" },
{ status: 500 },
);
}
const insertedSignature = _insertedSignature satisfies z.infer<typeof signedPetitionSchema>
const parsedSignedSignature = signedPetitionSchema.parse(insertedSignature);
return Response.json(insertedSignature, { status: 200 });
}
return Response.json(parsedSignedSignature, { status: 200 });
};