-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
147 lines (132 loc) · 4.64 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
import { createServer } from 'http';
import fs from 'fs';
import drainBody from './drainBody.js';
import ensureAppFolder from './ensureAppFolder.js';
import ensureTypeFolder from './ensureTypeFolder.js';
import getNote from './getNote.js';
import setNote from './setNote.js';
import listNotes from './listNotes.js';
import deleteNote from './deleteNote.js';
import getNotes from './getNotes.js';
import deleteNotes from './deleteNotes.js';
createServer()
.listen(process.env.PORT, () => console.log(`http://localhost:${process.env.PORT}`))
.on('request', async (request, response) => {
console.log(request.method, request.url);
try {
const parts = request.url.slice('/'.length).split('/');
if (parts.length === 1 && parts[0] === '') {
parts.pop();
}
switch (parts.length) {
case 0: {
if (request.method === 'GET') {
response.setHeader('Content-Type', 'text/html');
response.end(await fs.promises.readFile('./index.html', 'utf-8'));
return;
}
throw new Error(`Invalid route ${request.method} ${request.url}`);
}
case 1: {
switch (parts[0]) {
case 'todo.html': {
response.setHeader('Content-Type', 'text/html');
response.end(await fs.promises.readFile('./todo.html', 'utf-8'));
return;
}
case 'todo.js': {
response.setHeader('Content-Type', 'application/javascript');
response.end(await fs.promises.readFile('./todo.js', 'utf-8'));
return;
}
case 'renderItem.js': {
response.setHeader('Content-Type', 'application/javascript');
response.end(await fs.promises.readFile('./renderItem.js', 'utf-8'));
return;
}
}
const [type] = parts;
if (!type) {
throw new Error(`Missing type, expected /type or /type?full: ${request.url}`);
}
switch (request.method) {
case 'GET': {
const [name, full] = type.split('?');
if (full && full !== 'full') {
throw new Error(`Invalid type, expected /type or /type?full: ${request.url}`);
}
await ensureAppFolder();
await ensureTypeFolder(name);
response.setHeader('Content-Type', 'application/json');
if (full) {
response.end(JSON.stringify(await getNotes(name)));
}
else {
response.end(JSON.stringify(await listNotes(name)));
}
return;
}
default: {
throw new Error(`Unsupported /type method: ${request.method}`);
}
}
}
case 2: {
const [type, id] = parts;
if (!type) {
throw new Error(`Missing type, expected /type/id: ${request.url}`);
}
if (!id) {
throw new Error(`Missing id, expected /type/id: ${request.url}`);
}
switch (request.method) {
case 'GET': {
await ensureAppFolder();
await ensureTypeFolder(type);
response.setHeader('Content-Type', 'application/json');
if (id.includes(',')) {
const ids = id.split(',');
response.end(JSON.stringify(await getNotes(type, ids)));
}
else {
response.end(JSON.stringify(await getNote(type, id)));
}
return;
}
case 'POST': {
const data = JSON.parse(await drainBody(request));
await ensureAppFolder();
await ensureTypeFolder(type);
await setNote(type, id, data);
response.end();
return;
}
case 'DELETE': {
await ensureAppFolder();
await ensureTypeFolder(type);
if (id.includes(',')) {
const ids = id.split(',');
await deleteNotes(type, ids);
}
else {
await deleteNote(type, id);
}
response.end();
return;
}
default: {
throw new Error(`Unsupported /type/id method: ${request.method}`);
}
}
}
default: {
throw new Error(`Invalid route - too many parts ${request.method} ${request.url}`);
}
}
}
catch (error) {
console.error(error);
response.statusCode = 400;
response.end(error.message);
}
});