-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathserver.ts
94 lines (82 loc) · 2.53 KB
/
server.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
import { loadDatabase, loadDatabaseWithUpdates } from './data/loadData.ts';
import { exists, parse, ServerRequest } from './deps.ts';
import { handleRequest } from './handleRequest.ts';
import { listenAndServe } from './listenAndServe.ts';
export type JsonDB = Record<string, unknown>;
export type RewriteRules = Record<string, string[]>;
const isString = (value: unknown) =>
typeof value === 'string' || value instanceof String;
export interface Options {
dbPathOrObject: string | JsonDB;
port: number;
watchDB: boolean;
rewriteRules: RewriteRules;
}
const defaultOptions: Options = {
dbPathOrObject: './db.json',
port: 8000,
watchDB: true,
rewriteRules: { yolo: ['profile', 'user'] },
};
export const jsonServer = async (options: Partial<Options>) => {
const { dbPathOrObject, port, watchDB, rewriteRules } = {
...defaultOptions,
...options,
};
let handler = (req: ServerRequest) => {
req.respond({ body: 'loading...' });
};
const server = listenAndServe({ port }, (req) => handler(req));
console.log(`JSON server is running on Port ${port}`);
const handleNewDb = (db: JsonDB) => {
handler = handleRequest(db, rewriteRules);
};
const aborter = new AbortController();
const { signal } = aborter;
const db = await loadDatabase(dbPathOrObject, { signal });
handleNewDb(db);
const run = async () => {
if (watchDB && isString(dbPathOrObject)) {
const dbPath = dbPathOrObject as string;
for await (const db of loadDatabaseWithUpdates<JsonDB>(dbPath, {
signal,
})) {
handleNewDb(db);
}
}
};
run();
return {
close: () => {
aborter.abort();
server.close();
console.log('Server was closed.');
},
};
};
export const parseArgs = async () => {
const parsedArgs = parse(Deno.args);
const dbPath = parsedArgs._[0]?.toString() || './db.json';
if (!(await exists(dbPath))) {
console.error(`Invalid database file: ${dbPath} was not found!`);
Deno.exit(1);
}
const watchDB = parsedArgs['watch'] || true;
const port = parsedArgs['port'] || 8000;
const testRun = parsedArgs['testRun'] || false;
return { dbPath, watchDB, port, testRun };
};
if (import.meta.main) {
console.clear();
const cliArgs = await parseArgs();
const server = await jsonServer({
dbPathOrObject: cliArgs.dbPath,
port: cliArgs.port,
watchDB: cliArgs.watchDB,
});
if (cliArgs.testRun) {
console.log('testRun flag detected, closing the server...');
await new Promise((resolve) => setTimeout(resolve, 1000));
server.close();
}
}