-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.ts
127 lines (104 loc) · 3.34 KB
/
main.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
import { Application, Router } from "@oak/oak";
import { ROUTES } from "./constants.ts";
import helper from "./helpers.ts";
import { toOrdersWithProducts } from "./mappers.ts";
import { authMiddleware } from "./middlewares.ts";
import {
OrderRepository,
ProductRepository,
UserRepository,
} from "./repositories/mod.ts";
import { OrderService, UserService } from "./services/mod.ts";
import {
CreateOrderResponseData,
LoginResponseData,
OrderListResponseData,
SignupResponseData,
} from "./types/dto.ts";
import { ContextState } from "./types/request.ts";
import {
CreateOrderValidator,
LoginValidator,
SignupValidator,
} from "./validators.ts";
// Create All the dependencies on root level
const app = new Application();
const router = new Router<ContextState>();
const dbClient = await helper.getDBClient();
const userRepository = new UserRepository(dbClient);
const productRepository = new ProductRepository(dbClient);
const orderRepository = new OrderRepository(dbClient);
const userService = new UserService(userRepository);
const orderService = new OrderService(
orderRepository,
productRepository,
userRepository,
);
router.post(ROUTES.SIGNUP, async (context) => {
await helper.wrapError(context, async () => {
const { getEnv } = helper;
const body = await helper.getRequestBody(context);
const payload = SignupValidator.parse(body);
await userService.signup(payload.username, payload.password);
const redirect_url = `${getEnv("APP_URL")}:${getEnv(
"PORT",
)}${ROUTES.LOGIN}`;
helper.setAPIResponse<SignupResponseData>(context, {
success: true,
data: { redirect_url },
});
});
});
router.post(ROUTES.LOGIN, async (context) => {
await helper.wrapError(context, async () => {
const body = await helper.getRequestBody(context);
const payload = LoginValidator.parse(body);
const access_token = await userService.login(
payload.username,
payload.password,
);
helper.setAPIResponse<LoginResponseData>(context, {
success: true,
data: { access_token },
});
});
});
router.post(ROUTES.ORDER_CREATE, authMiddleware, async (context) => {
await helper.wrapError(context, async () => {
const body = await helper.getRequestBody(context);
const payload = CreateOrderValidator.parse(body);
const userId = context.state.user_id;
const result = await orderService.createOrder(userId, payload.items);
helper.setAPIResponse<CreateOrderResponseData>(context, {
success: true,
data: { order_id: result.id },
});
});
});
router.get(ROUTES.MY_ORDERS, authMiddleware, async (context) => {
await helper.wrapError(context, async () => {
const userId = context.state.user_id;
const orders = await orderService.getUserOrders(userId);
helper.setAPIResponse<OrderListResponseData>(context, {
success: true,
data: { orders: toOrdersWithProducts(orders) },
});
});
});
router.get(ROUTES.HEALTH, (context) => {
helper.setAPIResponse(context, {
success: true,
});
});
app.use(router.routes());
app.use(router.allowedMethods());
if (import.meta.main) {
const port = parseInt(helper.getEnv("PORT"));
app.addEventListener("listen", () =>
console.log(`Server listensing on PORT ${port}`),
);
await app.listen({ port });
app;
}
// Export for testing
export { dbClient, orderService, router, userService };