-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
41 changed files
with
651 additions
and
292 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
{ | ||
"name": "@echo-webkom/api", | ||
"version": "1.0.0", | ||
"scripts": { | ||
"dev": "pnpm with-env tsx --watch ./src/index.ts", | ||
"with-env": "dotenv -e ../../.env --" | ||
}, | ||
"dependencies": { | ||
"@echo-webkom/auth": "workspace:*", | ||
"@echo-webkom/db": "workspace:*", | ||
"@echo-webkom/email": "workspace:*", | ||
"@echo-webkom/lib": "workspace:*", | ||
"@echo-webkom/sanity": "workspace:*", | ||
"@hono/node-server": "1.13.0", | ||
"hono": "4.6.2", | ||
"zod": "3.23.8" | ||
}, | ||
"devDependencies": { | ||
"@echo-webkom/tsconfig": "workspace:*", | ||
"@types/node": "20.16.5", | ||
"dotenv-cli": "7.4.2", | ||
"tsx": "4.19.1", | ||
"typescript": "5.5.4", | ||
"vitest": "2.0.5" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import { Hono } from "hono"; | ||
import { cors } from "hono/cors"; | ||
import { logger } from "hono/logger"; | ||
|
||
import adminApp from "./services/admin"; | ||
import feedbackApp from "./services/feedback"; | ||
import happeningApp from "./services/happening"; | ||
import healthApp from "./services/health"; | ||
import shoppingApp from "./services/shopping-list"; | ||
|
||
const app = new Hono(); | ||
|
||
app.use(logger()); | ||
app.use(cors()); | ||
|
||
app.route("/", healthApp); | ||
app.route("/", adminApp); | ||
app.route("/", happeningApp); | ||
app.route("/", feedbackApp); | ||
app.route("/", shoppingApp); | ||
|
||
export default app; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import { serve } from "@hono/node-server"; | ||
|
||
import app from "./app"; | ||
|
||
const PORT = 8000; | ||
|
||
serve( | ||
{ | ||
fetch: app.fetch, | ||
port: PORT, | ||
}, | ||
(info) => { | ||
console.log(`Listening on http://localhost:${info.port}`); | ||
}, | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import { createMiddleware } from "hono/factory"; | ||
|
||
export const admin = () => { | ||
return createMiddleware(async (c, next) => { | ||
const bearerToken = c.req.header("Authorization"); | ||
|
||
if (bearerToken !== "Bearer admin") { | ||
return c.json({ error: "Unauthorized" }, 401); | ||
} | ||
|
||
return await next(); | ||
}); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
import { Hono } from "hono"; | ||
import { z } from "zod"; | ||
|
||
import { db } from "@echo-webkom/db"; | ||
import { comments } from "@echo-webkom/db/schemas"; | ||
|
||
import { admin } from "../middleware/admin"; | ||
import { parseJson } from "../utils/json"; | ||
|
||
const app = new Hono(); | ||
|
||
app.post("/admin/register", admin(), async (c) => { | ||
return c.text("Registered"); | ||
}); | ||
|
||
app.get("/admin/comments/:id", admin(), async (c) => { | ||
const { id } = c.req.param(); | ||
|
||
const comments = await db.query.comments.findMany({ | ||
where: (comment, { eq }) => eq(comment.postId, id), | ||
orderBy: (comment, { desc }) => [desc(comment.createdAt)], | ||
with: { | ||
user: { | ||
columns: { | ||
id: true, | ||
name: true, | ||
image: true, | ||
}, | ||
}, | ||
}, | ||
}); | ||
|
||
return c.json(comments); | ||
}); | ||
|
||
app.post("/admin/comments", admin(), async (c) => { | ||
const { ok, json } = await parseJson( | ||
c, | ||
z.object({ | ||
content: z.string(), | ||
postId: z.string(), | ||
userId: z.string(), | ||
parentCommentId: z.string().optional(), | ||
}), | ||
); | ||
|
||
if (!ok) { | ||
return c.json({ error: "Invalid data" }, 400); | ||
} | ||
|
||
const { content, postId, userId, parentCommentId } = json; | ||
|
||
await db.insert(comments).values({ | ||
content, | ||
postId, | ||
userId, | ||
parentCommentId, | ||
}); | ||
|
||
return c.json({ success: true }); | ||
}); | ||
|
||
export default app; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import { Hono } from "hono"; | ||
|
||
import { db } from "@echo-webkom/db"; | ||
|
||
import { admin } from "../middleware/admin"; | ||
|
||
const app = new Hono(); | ||
|
||
app.get("/feedbacks", admin(), async (c) => { | ||
const feedbacks = await db.query.siteFeedback.findMany({ | ||
orderBy: (row, { desc }) => [desc(row.createdAt)], | ||
}); | ||
|
||
return c.json(feedbacks); | ||
}); | ||
|
||
app.get("/feedback/:id", admin(), async (c) => { | ||
const { id } = c.req.param(); | ||
|
||
const feedback = await db.query.siteFeedback.findFirst({ | ||
where: (row, { eq }) => eq(row.id, id), | ||
}); | ||
|
||
return c.json(feedback); | ||
}); | ||
|
||
export default app; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
import { Hono } from "hono"; | ||
|
||
import { db } from "@echo-webkom/db"; | ||
|
||
import { admin } from "../middleware/admin"; | ||
|
||
const app = new Hono(); | ||
|
||
app.get("/happenings", async (c) => { | ||
const happenings = await db.query.happenings.findMany(); | ||
|
||
return c.json(happenings); | ||
}); | ||
|
||
app.get("/happening/:id", async (c) => { | ||
const { id } = c.req.param(); | ||
|
||
const happening = await db.query.happenings.findFirst({ | ||
where: (row, { eq }) => eq(row.id, id), | ||
}); | ||
|
||
if (!happening) { | ||
return c.json({ error: "Not found" }, 404); | ||
} | ||
|
||
return c.json(happening); | ||
}); | ||
|
||
app.get("/happening/:id/registrations/count", async (c) => { | ||
const { id } = c.req.param(); | ||
|
||
const spotRanges = await db.query.spotRanges.findMany({ | ||
where: (row, { eq }) => eq(row.happeningId, id), | ||
}); | ||
|
||
const reigstrations = await db.query.registrations.findMany({ | ||
where: (row, { eq }) => eq(row.happeningId, id), | ||
}); | ||
|
||
const max = spotRanges.reduce((acc, range) => acc + range.spots, 0); | ||
|
||
const grouped = reigstrations.reduce( | ||
(acc, registration) => { | ||
const { status } = registration; | ||
|
||
if (status === "waiting") { | ||
acc.waiting++; | ||
} else if (status === "registered") { | ||
acc.registered++; | ||
} | ||
|
||
return acc; | ||
}, | ||
{ | ||
waiting: 0, | ||
registered: 0, | ||
max, | ||
}, | ||
); | ||
|
||
return c.json(grouped); | ||
}); | ||
|
||
app.get("/happening/:id/registrations", admin(), async (c) => { | ||
const { id } = c.req.param(); | ||
|
||
const registrations = await db.query.registrations.findMany({ | ||
where: (row, { eq }) => eq(row.happeningId, id), | ||
with: { | ||
user: true, | ||
}, | ||
}); | ||
|
||
return c.json(registrations); | ||
}); | ||
|
||
app.get("/happening/:id/spot-ranges", admin(), async (c) => { | ||
const { id } = c.req.param(); | ||
|
||
const spotRanges = await db.query.spotRanges.findMany({ | ||
where: (row, { eq }) => eq(row.happeningId, id), | ||
}); | ||
|
||
return c.json(spotRanges); | ||
}); | ||
|
||
app.get("/happening/:id/questions", async (c) => { | ||
const { id } = c.req.param(); | ||
|
||
const questions = await db.query.questions.findMany({ | ||
where: (row, { eq }) => eq(row.happeningId, id), | ||
}); | ||
|
||
return c.json(questions); | ||
}); | ||
|
||
export default app; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import { Hono } from "hono"; | ||
|
||
const app = new Hono(); | ||
|
||
app.get("/", async (c) => { | ||
return c.text("OK"); | ||
}); | ||
|
||
export default app; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import { Hono } from "hono"; | ||
|
||
import { db } from "@echo-webkom/db"; | ||
|
||
const app = new Hono(); | ||
|
||
app.get("/shopping", async (c) => { | ||
const items = await db.query.shoppingListItems | ||
.findMany({ | ||
with: { likes: true, user: true }, | ||
}) | ||
.catch(() => { | ||
return []; | ||
}); | ||
|
||
return c.json(items); | ||
}); | ||
|
||
export default app; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import { Context } from "hono"; | ||
import { z } from "zod"; | ||
|
||
const parseData = <TSchema extends z.ZodSchema>( | ||
data: unknown, | ||
schema: TSchema, | ||
): z.infer<TSchema> => { | ||
try { | ||
return schema.parse(data); | ||
} catch (e) { | ||
throw new Error("Invalid data"); | ||
} | ||
}; | ||
|
||
export const parseJson = async <TSchema extends z.ZodSchema>( | ||
c: Context, | ||
schema: TSchema, | ||
): Promise< | ||
| { | ||
ok: true; | ||
json: z.infer<TSchema>; | ||
} | ||
| { | ||
ok: false; | ||
json?: undefined; | ||
} | ||
> => { | ||
try { | ||
const data = await c.req.json(); | ||
return { ok: true, json: parseData(data, schema) }; | ||
} catch (e) { | ||
return { ok: false }; | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
{ | ||
"compilerOptions": { | ||
"target": "ESNext", | ||
"module": "ESNext", | ||
"moduleResolution": "Bundler", | ||
"strict": true, | ||
"skipLibCheck": true, | ||
"types": ["node"], | ||
"jsx": "react-jsx", | ||
"jsxImportSource": "hono/jsx" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.