- Implemented Home component with user authentication and loading states. - Created Welcome component for unauthenticated users with a sign-in option. - Developed Dashboard component to display user's habits and progress. - Added functionality for habit management, including adding, updating, and deleting habits. - Integrated HabitChart and HabitHistory components for visual representation of habits. - Introduced sharing functionality for progress via Discord integration. feat: establish Discord sharing configuration and routes - Added DiscordSharingConfig type and readDiscordSharingConfig function for environment variable management. - Created sharing contracts for input validation and data structure. - Implemented sharing routes for previewing and sending progress images to Discord. - Added tests for sharing routes to ensure authentication and proper error handling.
30 lines
1.4 KiB
TypeScript
30 lines
1.4 KiB
TypeScript
import { createHabitRoutes } from "./habits/routes";
|
|
import { ApiError } from "./habits/service";
|
|
import { Hono } from "hono";
|
|
import { sql } from "drizzle-orm";
|
|
import { createAuth, type AppDatabase, type AuthEnv } from "./auth";
|
|
import type { AuthConfig } from "./auth/config";
|
|
import type { FetchDiscord } from "./auth/discord";
|
|
import { createSharingRoutes, type DiscordFetch } from "./sharing/routes";
|
|
import type { DiscordSharingConfig } from "./sharing/config";
|
|
|
|
export function createApi(db: AppDatabase, config: AuthConfig, request?: FetchDiscord, now?: () => number, discordRequest?: DiscordFetch, sharingConfig: DiscordSharingConfig = { token: "", channelId: "" }) {
|
|
const app = new Hono<AuthEnv>();
|
|
const auth = createAuth(db, config, request, now);
|
|
app.get("/api/health", c => {
|
|
db.get(sql`SELECT 1`);
|
|
return c.json({ status: "ok" });
|
|
});
|
|
app.route("/api/auth", auth.routes);
|
|
app.get("/api/me", auth.requireAuth, c => c.json(c.get("user")));
|
|
app.route("/api", createHabitRoutes(db, auth, now ?? Date.now));
|
|
app.route("/api/sharing", createSharingRoutes(db, auth, sharingConfig, now ?? Date.now, discordRequest));
|
|
app.notFound(c => c.json({ error: "Not found" }, 404));
|
|
app.onError((_error, c) => {
|
|
c.header("Cache-Control", "no-store");
|
|
if (_error instanceof ApiError) return c.json({ error: _error.message }, _error.status);
|
|
return c.json({ error: "Internal server error" }, 500);
|
|
});
|
|
return app;
|
|
}
|