-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
157 lines (123 loc) · 4.87 KB
/
index.js
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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
/*
* Title: Main File for Node MVC
* Description: Basic MVC server to deliver frontend data
* Author: Mohammad Mesbaul Haque
* Github link: https://github.com/mmesba
* Date: 06/02/2022
*/
// Dependencies.
const http = require('http');
const fs = require('fs');
const url = require('url');
const { StringDecoder } = require('string_decoder');
const helpers = require('./helpers');
const route = require('./route');
const { parseJsonObject } = require('./helpers');
const config = require('./environment');
const data = require('./data');
const users = require('./users')
// App object or Module scaffolding.
const app = {}
// main functions or objects.
app.createHttpServer = ()=>{
const createServer = http.createServer(app.reqResHandler);
createServer.listen(config.port || 3000, ()=>{
console.log('\x1b[31m%s\x1b[0m', 'MVC Server Listening...');
})
}
// Defining Request and Response Handler
app.reqResHandler = (req, res)=>{
// Handle and lookup request properties
const parsedUrl = url.parse(req.url, true);
const path = parsedUrl.pathname;
const trimmedPath = path.replace(/^\/+|\/+$/g, '');
const method = req.method.toLowerCase();
const queryStringObject = parsedUrl.query;
const headersObject = req.headers;
// Get the payload
let decoder = new StringDecoder('utf-8');
let buffer = '';
// Chose the handler this request should go to. If one is not found use the not found handler.
let chosenHandler =router[trimmedPath] !== undefined ? router[trimmedPath] : route.notFound;
req.on('data', (data)=>{
buffer +=decoder.write(data);
});
req.on('end', ()=>{
buffer += decoder.end();
// Construct the data object to send to the handler
let data = {
'trimmedPath' : trimmedPath,
'queryStringObject' : queryStringObject,
'method' : method,
'headers' : headersObject,
'payload' : helpers.parseJsonObject(buffer)
}
// Route the request to the handler specified in the router
// Chosen handler now holds the value of a function which will be called as users request.
chosenHandler(data, (statusCode, payload, contentType)=>{
// Determine the type of response (fallback to JSON)
contentType = typeof(contentType) === 'string' ? contentType : 'json';
// Use the status code called back by the handler, or default to 200
statusCode = typeof(statusCode) === 'number' ? statusCode : 200;
// Return the response parts that are content specific
let payloadString = '';
if(contentType === 'json'){
res.setHeader('Content-Type', 'Application/json')
payload = typeof(payload) === 'object' ? payload : {};
// Use the payload called back by the handler, or default to an empty object
payloadString = JSON.stringify(payload);
} if(contentType === 'html') {
res.setHeader('Content-Type', 'text/html');
payloadString = typeof(payload) === 'string' ? payload : '';
}
if(contentType === 'favicon') {
res.setHeader('Content-Type', 'image/x-icon');
payloadString = typeof(payload) === 'string' ? payload : '';
}
if(contentType === 'css') {
res.setHeader('Content-Type', 'text/css');
payloadString = typeof(payload) === 'string' ? payload : '';
}
if(contentType === 'png') {
res.setHeader('Content-Type', 'image/png');
payloadString = typeof(payload) === 'string' ? payload : '';
}
if(contentType === 'jpeg') {
res.setHeader('Content-Type', 'image/jpeg');
payloadString = typeof(payload) === 'string' ? payload : '';
}
if(contentType === 'plain') {
res.setHeader('Content-Type', 'text/plain');
payloadString = typeof(payload) === 'string' ? payload : '';
}
// Return the response parts that are common to all content types
res.writeHead(statusCode);
res.end(payloadString)
//return the final response
// Print conditionally
if (statusCode === 200) {
console.log('\x1b[32m%s\x1b[0m', method.toUpperCase()+'/'+trimmedPath+' '+statusCode);
} else {
console.log('\x1b[31m%s\x1b[0m', method.toUpperCase()+'/'+trimmedPath+' '+statusCode);
}
})
})
}
// Define some user endpoints
router = {
'' : route.index,
'/' : route.index,
'account/create' : 'route.accountCreate',
'account/edit' : 'route.accountEdit',
'account/deleted' : 'route.accountDeleted',
'session/create' : 'route.sessionCreate',
'session/deleted' : 'route.sessionDeleted',
'sample' : route.sample,
'api/user' : users.userHandler,
'favicon.ico' : route.favicon,
'public' : route.public
}
// Start the server
app.createHttpServer();
// export the module.