131 lines
4.1 KiB
Zig
131 lines
4.1 KiB
Zig
const std = @import("std");
|
|
const httpz = @import(".deps/http.zig/src/httpz.zig");
|
|
const models = @import("db/models.zig");
|
|
const ztime = @import(".deps/time.zig");
|
|
|
|
const utils = @import("utils.zig");
|
|
|
|
const budget = @import("routes/budget.zig");
|
|
const auth = @import("routes/auth.zig");
|
|
const user = @import("routes/user.zig");
|
|
const trans = @import("routes/transactions.zig");
|
|
const dash = @import("routes/dashboard.zig");
|
|
const note = @import("routes/shared_note.zig");
|
|
|
|
const Db = @import("db/db.zig").Db;
|
|
|
|
var db: ?Db = null;
|
|
|
|
pub fn getDb() *Db {
|
|
return &db.?;
|
|
}
|
|
|
|
pub fn startHttpServer() !void {
|
|
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
|
const allocator = gpa.allocator();
|
|
|
|
// db = try Db.init(allocator, null);
|
|
// defer db.deinit();
|
|
var args = try std.process.argsWithAllocator(allocator);
|
|
|
|
// skip program name
|
|
_ = args.skip();
|
|
while (args.next()) |arg| {
|
|
if (std.mem.eql(u8, arg, "--db_path")) {
|
|
const path = args.next();
|
|
// std.debug.print("Got path: {any}", .{path});
|
|
if (path) |db_path| {
|
|
db = try Db.init(allocator, db_path, null);
|
|
} else {
|
|
std.log.err("Db path not provided after arg", .{});
|
|
return;
|
|
}
|
|
}
|
|
if (std.mem.eql(u8, arg, "--make-migration")) {
|
|
if (db == null) {
|
|
std.log.err("Cannot migrate, provide db path first", .{});
|
|
return;
|
|
}
|
|
try db.?.wipeAndMigrateDb();
|
|
}
|
|
}
|
|
|
|
if (db == null) {
|
|
db = try Db.init(allocator, null, null);
|
|
}
|
|
|
|
defer db.?.deinit();
|
|
|
|
var server = try httpz.Server().init(allocator, .{ .port = 8081 });
|
|
|
|
// overwrite the default notFound handler
|
|
server.notFound(notFound);
|
|
|
|
// overwrite the default error handler
|
|
server.errorHandler(errorHandler);
|
|
|
|
var router = server.router();
|
|
|
|
router.post("/auth/login", user.login);
|
|
router.post("/auth/signup", user.signup);
|
|
|
|
// router.get("/user/:id", user.getUser);
|
|
router.put("/user", user.putUser);
|
|
// router.delete("/user/:id", user.deleteUser);
|
|
|
|
router.get("/shared_notes/:limit", note.getSharedNotes);
|
|
router.put("/shared_notes", note.putSharedNote);
|
|
router.post("/shared_notes", note.postSharedNote);
|
|
|
|
// router.get("/budget/:id", budget.getBudget);
|
|
// router.put("/budget", budget.putBudget);
|
|
// router.post("/budget", budget.postBudget);
|
|
|
|
router.put("/budget_category", budget.putBudgetCategory);
|
|
router.post("/budget_category", budget.postBudgetCategory);
|
|
|
|
router.post("/transactions", trans.postTransaction);
|
|
router.put("/transactions", trans.putTransaction);
|
|
|
|
router.get("/dashboard", dash.getDashboard);
|
|
|
|
std.debug.print("Starting http server listening on port {}\n", .{8081});
|
|
// start the server in the current thread, blocking.
|
|
try server.listen();
|
|
}
|
|
|
|
fn notFound(_: *httpz.Request, res: *httpz.Response) !void {
|
|
res.status = 404;
|
|
|
|
// you can set the body directly to a []u8, but note that the memory
|
|
// must be valid beyond your handler. Use the res.arena if you need to allocate
|
|
// memory for the body.
|
|
res.body = "Not Found";
|
|
}
|
|
|
|
// note that the error handler return `void` and not `!void`
|
|
fn errorHandler(req: *httpz.Request, res: *httpz.Response, err: anyerror) void {
|
|
res.status = 500;
|
|
res.body = "Internal Server Error";
|
|
std.log.warn("httpz: unhandled exception for request: {s}\nErr: {}", .{ req.url.raw, err });
|
|
}
|
|
|
|
pub fn returnError(message: ?[]const u8, comptime statusCode: u16, res: *httpz.Response) void {
|
|
comptime {
|
|
if (statusCode > 500 or statusCode < 200) {
|
|
@compileError("Failed responses must have status codes between 200 and 500");
|
|
}
|
|
}
|
|
res.status = statusCode;
|
|
res.json(.{ .success = false, .message = message }, .{}) catch |err| {
|
|
std.log.warn("Couldnt create error body: {}", .{err});
|
|
res.body = "{ \"success\": false";
|
|
};
|
|
}
|
|
|
|
pub fn returnData(data: anytype, res: *httpz.Response) !void {
|
|
const body = utils.structConcatFields(data, .{ .success = true });
|
|
res.status = 200;
|
|
try res.json(body, .{});
|
|
}
|