UNPKG

13.5 kBPlain TextView Raw
1import * as http from 'http';
2import {
3 Clients,
4 CompiledFiles,
5 FileContentsResult,
6 CustomHTTPHeaders,
7 HTTPHeaders
8} from '../index.d.ts';
9import { getJavaScriptFileContents } from './languages/javascript.ts';
10import { getTypeScriptFileContents } from './languages/typescript.ts';
11import { getAssemblyScriptFileContents } from './languages/assemblyscript.ts';
12import { getWasmFileContents } from './languages/wasm.ts';
13import { getWatFileContents } from './languages/wat.ts';
14import {
15 getFileContents,
16 getCustomHTTPHeadersFromFile,
17 getCustomHTTPHeadersForURL
18} from './utilities.ts';
19import * as mime from 'mime';
20
21export async function createHTTPServer(params: {
22 wsPort: number;
23 watchFiles: boolean;
24 jsTarget: string;
25 clients: Clients;
26 compiledFiles: CompiledFiles;
27 disableSpa: boolean;
28 customHTTPHeadersFilePath: string | undefined;
29}): Promise<Readonly<http.Server>> {
30
31 const customHTTPHeaders: Readonly<CustomHTTPHeaders> = params.customHTTPHeadersFilePath === undefined ? {} : await getCustomHTTPHeadersFromFile(params.customHTTPHeadersFilePath);
32
33 return http.createServer(async (req: Readonly<http.IncomingMessage>, res: http.ServerResponse) => {
34
35 try {
36 if (req.url === undefined) {
37 throw new Error('The URL of the request is not defined');
38 }
39
40 const fileExtension: string = req.url.slice(req.url.lastIndexOf('.') + 1);
41
42 if (fileExtension === '/') {
43
44 await handleIndex({
45 compiledFiles: params.compiledFiles,
46 watchFiles: params.watchFiles,
47 clients: params.clients,
48 disableSpa: params.disableSpa,
49 res,
50 customHTTPHeaders
51 });
52
53 return;
54 }
55
56 if (fileExtension === 'js') {
57
58 await handleJavaScript({
59 url: `.${req.url}`,
60 compiledFiles: params.compiledFiles,
61 watchFiles: params.watchFiles,
62 clients: params.clients,
63 jsTarget: params.jsTarget,
64 wsPort: params.wsPort,
65 disableSpa: params.disableSpa,
66 res,
67 customHTTPHeaders
68 });
69
70 return;
71 }
72
73 if (fileExtension === 'mjs') {
74
75 await handleJavaScript({
76 url: `.${req.url}`,
77 compiledFiles: params.compiledFiles,
78 watchFiles: params.watchFiles,
79 clients: params.clients,
80 jsTarget: params.jsTarget,
81 wsPort: params.wsPort,
82 disableSpa: params.disableSpa,
83 res,
84 customHTTPHeaders
85 });
86
87 return;
88 }
89
90 if (fileExtension === 'ts') {
91
92 await handleTypeScript({
93 url: `.${req.url}`,
94 compiledFiles: params.compiledFiles,
95 watchFiles: params.watchFiles,
96 clients: params.clients,
97 jsTarget: params.jsTarget,
98 wsPort: params.wsPort,
99 disableSpa: params.disableSpa,
100 res,
101 customHTTPHeaders
102 });
103
104 return;
105 }
106
107 if (fileExtension === 'as') {
108
109 await handleAssemblyScript({
110 url: `.${req.url}`,
111 compiledFiles: params.compiledFiles,
112 watchFiles: params.watchFiles,
113 clients: params.clients,
114 jsTarget: params.jsTarget,
115 wsPort: params.wsPort,
116 disableSpa: params.disableSpa,
117 res,
118 customHTTPHeaders
119 });
120
121 return;
122 }
123
124 if (fileExtension === 'wasm') {
125 await handleWasm({
126 url: `.${req.url}`,
127 compiledFiles: params.compiledFiles,
128 watchFiles: params.watchFiles,
129 clients: params.clients,
130 jsTarget: params.jsTarget,
131 wsPort: params.wsPort,
132 disableSpa: params.disableSpa,
133 res,
134 customHTTPHeaders
135 });
136
137 return;
138 }
139
140 if (fileExtension === 'wat') {
141 await handleWat({
142 url: `.${req.url}`,
143 compiledFiles: params.compiledFiles,
144 watchFiles: params.watchFiles,
145 clients: params.clients,
146 jsTarget: params.jsTarget,
147 wsPort: params.wsPort,
148 disableSpa: params.disableSpa,
149 res,
150 customHTTPHeaders
151 });
152
153 return;
154 }
155
156 await handleGeneric({
157 url: `.${req.url}`,
158 compiledFiles: params.compiledFiles,
159 watchFiles: params.watchFiles,
160 clients: params.clients,
161 disableSpa: params.disableSpa,
162 res,
163 customHTTPHeaders
164 });
165 }
166 catch(error) {
167 console.log(error);
168 }
169 });
170}
171
172async function handleIndex(params: {
173 compiledFiles: CompiledFiles;
174 watchFiles: boolean;
175 clients: Clients;
176 disableSpa: boolean;
177 res: http.ServerResponse;
178 customHTTPHeaders: Readonly<CustomHTTPHeaders>;
179}): Promise<void> {
180
181 const url: string = './index.html';
182
183 const indexFileContentsResult: Readonly<FileContentsResult> = await getFileContents({
184 url,
185 compiledFiles: params.compiledFiles,
186 watchFiles: params.watchFiles,
187 clients: params.clients,
188 disableSpa: params.disableSpa,
189 transformer: 'NOT_SET'
190 });
191
192 const httpHeaders: Readonly<HTTPHeaders> = getCustomHTTPHeadersForURL({
193 customHTTPHeaders: params.customHTTPHeaders,
194 defaultHTTPHeaders: {
195 'Content-Type': 'text/html'
196 },
197 url
198 });
199
200 await sendResponse({
201 res: params.res,
202 fileContentsResult: indexFileContentsResult,
203 headers: httpHeaders
204 });
205}
206
207async function handleGeneric(params: {
208 url: string;
209 compiledFiles: CompiledFiles;
210 watchFiles: boolean;
211 clients: Clients;
212 disableSpa: boolean;
213 res: http.ServerResponse;
214 customHTTPHeaders: Readonly<CustomHTTPHeaders>;
215}): Promise<void> {
216
217 const genericFileContentsResult: Readonly<FileContentsResult> = await getFileContents({
218 url: params.url,
219 compiledFiles: params.compiledFiles,
220 watchFiles: params.watchFiles,
221 clients: params.clients,
222 disableSpa: params.disableSpa,
223 transformer: 'NOT_SET'
224 });
225
226 const mimeType: string | null = mime.getType(params.url);
227
228 const httpHeaders: Readonly<HTTPHeaders> = getCustomHTTPHeadersForURL({
229 customHTTPHeaders: params.customHTTPHeaders,
230 defaultHTTPHeaders: mimeType ? {
231 'Content-Type': mimeType
232 } : {},
233 url: params.url
234 });
235
236 await sendResponse({
237 res: params.res,
238 fileContentsResult: genericFileContentsResult,
239 headers: httpHeaders
240 });
241}
242
243async function handleJavaScript(params: {
244 url: string;
245 compiledFiles: CompiledFiles;
246 watchFiles: boolean;
247 clients: Clients;
248 jsTarget: string;
249 wsPort: number;
250 disableSpa: boolean;
251 res: http.ServerResponse;
252 customHTTPHeaders: Readonly<CustomHTTPHeaders>;
253}): Promise<void> {
254 const javaScriptFileContentsResult: Readonly<FileContentsResult> = await getJavaScriptFileContents({
255 url: params.url,
256 compiledFiles: params.compiledFiles,
257 watchFiles: params.watchFiles,
258 clients: params.clients,
259 jsTarget: params.jsTarget,
260 wsPort: params.wsPort,
261 disableSpa: params.disableSpa
262 });
263
264 const httpHeaders: Readonly<HTTPHeaders> = getCustomHTTPHeadersForURL({
265 customHTTPHeaders: params.customHTTPHeaders,
266 defaultHTTPHeaders: {
267 'Content-Type': 'application/javascript'
268 },
269 url: params.url
270 });
271
272 await sendResponse({
273 res: params.res,
274 fileContentsResult: javaScriptFileContentsResult,
275 headers: httpHeaders
276 });
277}
278
279async function handleTypeScript(params: {
280 url: string;
281 compiledFiles: CompiledFiles;
282 watchFiles: boolean;
283 clients: Clients;
284 jsTarget: string;
285 wsPort: number;
286 disableSpa: boolean;
287 res: http.ServerResponse;
288 customHTTPHeaders: Readonly<CustomHTTPHeaders>;
289}): Promise<void> {
290 const typeScriptFileContentsResult: Readonly<FileContentsResult> = await getTypeScriptFileContents({
291 url: params.url,
292 compiledFiles: params.compiledFiles,
293 watchFiles: params.watchFiles,
294 clients: params.clients,
295 jsTarget: params.jsTarget,
296 wsPort: params.wsPort,
297 disableSpa: params.disableSpa
298 });
299
300 const httpHeaders: Readonly<HTTPHeaders> = getCustomHTTPHeadersForURL({
301 customHTTPHeaders: params.customHTTPHeaders,
302 defaultHTTPHeaders: {
303 'Content-Type': 'application/javascript'
304 },
305 url: params.url
306 });
307
308 await sendResponse({
309 res: params.res,
310 fileContentsResult: typeScriptFileContentsResult,
311 headers: httpHeaders
312 });
313}
314
315async function handleAssemblyScript(params: {
316 url: string;
317 compiledFiles: CompiledFiles;
318 watchFiles: boolean;
319 clients: Clients;
320 jsTarget: string;
321 wsPort: number;
322 disableSpa: boolean;
323 res: http.ServerResponse;
324 customHTTPHeaders: Readonly<CustomHTTPHeaders>;
325}): Promise<void> {
326 const assemblyScriptFileContentsResult: Readonly<FileContentsResult> = await getAssemblyScriptFileContents({
327 url: params.url,
328 compiledFiles: params.compiledFiles,
329 watchFiles: params.watchFiles,
330 clients: params.clients,
331 jsTarget: params.jsTarget,
332 wsPort: params.wsPort,
333 disableSpa: params.disableSpa
334 });
335
336 const httpHeaders: Readonly<HTTPHeaders> = getCustomHTTPHeadersForURL({
337 customHTTPHeaders: params.customHTTPHeaders,
338 defaultHTTPHeaders: {
339 'Content-Type': 'application/javascript'
340 },
341 url: params.url
342 });
343
344 await sendResponse({
345 res: params.res,
346 fileContentsResult: assemblyScriptFileContentsResult,
347 headers: httpHeaders
348 });
349}
350
351async function handleWasm(params: {
352 url: string;
353 compiledFiles: CompiledFiles;
354 watchFiles: boolean;
355 clients: Clients;
356 jsTarget: string;
357 wsPort: number;
358 disableSpa: boolean;
359 res: http.ServerResponse;
360 customHTTPHeaders: Readonly<CustomHTTPHeaders>;
361}): Promise<void> {
362 const wasmFileContentsResult: Readonly<FileContentsResult> = await getWasmFileContents({
363 url: params.url,
364 compiledFiles: params.compiledFiles,
365 watchFiles: params.watchFiles,
366 clients: params.clients,
367 jsTarget: params.jsTarget,
368 wsPort: params.wsPort,
369 disableSpa: params.disableSpa
370 });
371
372 const httpHeaders: Readonly<HTTPHeaders> = getCustomHTTPHeadersForURL({
373 customHTTPHeaders: params.customHTTPHeaders,
374 defaultHTTPHeaders: {
375 'Content-Type': 'application/javascript'
376 },
377 url: params.url
378 });
379
380 await sendResponse({
381 res: params.res,
382 fileContentsResult: wasmFileContentsResult,
383 headers: httpHeaders
384 });
385}
386
387async function handleWat(params: {
388 url: string;
389 compiledFiles: CompiledFiles;
390 watchFiles: boolean;
391 clients: Clients;
392 jsTarget: string;
393 wsPort: number;
394 disableSpa: boolean;
395 res: http.ServerResponse;
396 customHTTPHeaders: Readonly<CustomHTTPHeaders>;
397}): Promise<void> {
398 const watFileContentsResult: Readonly<FileContentsResult> = await getWatFileContents({
399 url: params.url,
400 compiledFiles: params.compiledFiles,
401 watchFiles: params.watchFiles,
402 clients: params.clients,
403 jsTarget: params.jsTarget,
404 wsPort: params.wsPort,
405 disableSpa: params.disableSpa
406 });
407
408 const httpHeaders: Readonly<HTTPHeaders> = getCustomHTTPHeadersForURL({
409 customHTTPHeaders: params.customHTTPHeaders,
410 defaultHTTPHeaders: {
411 'Content-Type': 'application/javascript'
412 },
413 url: params.url
414 });
415
416 await sendResponse({
417 res: params.res,
418 fileContentsResult: watFileContentsResult,
419 headers: httpHeaders
420 });
421}
422
423async function sendResponse(params: {
424 res: http.ServerResponse;
425 fileContentsResult: Readonly<FileContentsResult>;
426 headers: {
427 [key: string]: string;
428 };
429}): Promise<void> {
430 if (params.fileContentsResult === 'FILE_NOT_FOUND') {
431 params.res.statusCode = 404;
432 params.res.end();
433 }
434 else {
435 Object.entries(params.headers).forEach((headerEntry) => {
436 const key: string = headerEntry[0];
437 const value: string = headerEntry[1];
438
439 params.res.setHeader(key, value);
440 });
441
442 params.res.end(params.fileContentsResult.fileContents);
443 }
444}
\No newline at end of file