source: frontend/node_modules/webpack-dev-middleware/dist/utils/compatibleAPI.js

Last change on this file was 9af201e, checked in by MBK <marija.karapandzova@…>, 12 days ago

Fix frontend appearance

  • Property mode set to 100644
File size: 6.0 KB
Line 
1"use strict";
2
3/** @typedef {import("../index.js").IncomingMessage} IncomingMessage */
4
5/** @typedef {import("../index.js").ServerResponse} ServerResponse */
6
7/**
8 * @typedef {Object} ExpectedRequest
9 * @property {(name: string) => string | undefined} get
10 */
11
12/**
13 * @typedef {Object} ExpectedResponse
14 * @property {(name: string) => string | string[] | undefined} get
15 * @property {(name: string, value: number | string | string[]) => void} set
16 * @property {(status: number) => void} status
17 * @property {(data: any) => void} send
18 */
19
20/**
21 * @template {ServerResponse} Response
22 * @param {Response} res
23 * @returns {string[]}
24 */
25function getHeaderNames(res) {
26 if (typeof res.getHeaderNames !== "function") {
27 // @ts-ignore
28 // eslint-disable-next-line no-underscore-dangle
29 return Object.keys(res._headers || {});
30 }
31
32 return res.getHeaderNames();
33}
34/**
35 * @template {IncomingMessage} Request
36 * @param {Request} req
37 * @param {string} name
38 * @returns {string | undefined}
39 */
40
41
42function getHeaderFromRequest(req, name) {
43 // Express API
44 if (typeof
45 /** @type {Request & ExpectedRequest} */
46 req.get === "function") {
47 return (
48 /** @type {Request & ExpectedRequest} */
49 req.get(name)
50 );
51 } // Node.js API
52 // @ts-ignore
53
54
55 return req.headers[name];
56}
57/**
58 * @template {ServerResponse} Response
59 * @param {Response} res
60 * @param {string} name
61 * @returns {number | string | string[] | undefined}
62 */
63
64
65function getHeaderFromResponse(res, name) {
66 // Express API
67 if (typeof
68 /** @type {Response & ExpectedResponse} */
69 res.get === "function") {
70 return (
71 /** @type {Response & ExpectedResponse} */
72 res.get(name)
73 );
74 } // Node.js API
75
76
77 return res.getHeader(name);
78}
79/**
80 * @template {ServerResponse} Response
81 * @param {Response} res
82 * @param {string} name
83 * @param {number | string | string[]} value
84 * @returns {void}
85 */
86
87
88function setHeaderForResponse(res, name, value) {
89 // Express API
90 if (typeof
91 /** @type {Response & ExpectedResponse} */
92 res.set === "function") {
93 /** @type {Response & ExpectedResponse} */
94 res.set(name, typeof value === "number" ? String(value) : value);
95 return;
96 } // Node.js API
97
98
99 res.setHeader(name, value);
100}
101/**
102 * @template {ServerResponse} Response
103 * @param {Response} res
104 * @param {number} code
105 */
106
107
108function setStatusCode(res, code) {
109 if (typeof
110 /** @type {Response & ExpectedResponse} */
111 res.status === "function") {
112 /** @type {Response & ExpectedResponse} */
113 res.status(code);
114 return;
115 } // eslint-disable-next-line no-param-reassign
116
117
118 res.statusCode = code;
119}
120/**
121 * @template {IncomingMessage} Request
122 * @template {ServerResponse} Response
123 * @param {Request} req
124 * @param {Response} res
125 * @param {string | Buffer | import("fs").ReadStream} bufferOtStream
126 * @param {number} byteLength
127 */
128
129
130function send(req, res, bufferOtStream, byteLength) {
131 if (typeof
132 /** @type {import("fs").ReadStream} */
133 bufferOtStream.pipe === "function") {
134 setHeaderForResponse(res, "Content-Length", byteLength);
135
136 if (req.method === "HEAD") {
137 res.end();
138 return;
139 }
140 /** @type {import("fs").ReadStream} */
141
142
143 bufferOtStream.pipe(res);
144 return;
145 }
146
147 if (typeof
148 /** @type {Response & ExpectedResponse} */
149 res.send === "function") {
150 /** @type {Response & ExpectedResponse} */
151 res.send(bufferOtStream);
152 return;
153 } // Only Node.js API used
154
155
156 res.setHeader("Content-Length", byteLength);
157
158 if (req.method === "HEAD") {
159 res.end();
160 } else {
161 res.end(bufferOtStream);
162 }
163}
164/**
165 * @template {ServerResponse} Response
166 * @param {Response} res
167 */
168
169
170function clearHeadersForResponse(res) {
171 const headers = getHeaderNames(res);
172
173 for (let i = 0; i < headers.length; i++) {
174 res.removeHeader(headers[i]);
175 }
176}
177
178const matchHtmlRegExp = /["'&<>]/;
179/**
180 * @param {string} string raw HTML
181 * @returns {string} escaped HTML
182 */
183
184function escapeHtml(string) {
185 const str = `${string}`;
186 const match = matchHtmlRegExp.exec(str);
187
188 if (!match) {
189 return str;
190 }
191
192 let escape;
193 let html = "";
194 let index = 0;
195 let lastIndex = 0;
196
197 for (({
198 index
199 } = match); index < str.length; index++) {
200 switch (str.charCodeAt(index)) {
201 // "
202 case 34:
203 escape = "&quot;";
204 break;
205 // &
206
207 case 38:
208 escape = "&amp;";
209 break;
210 // '
211
212 case 39:
213 escape = "&#39;";
214 break;
215 // <
216
217 case 60:
218 escape = "&lt;";
219 break;
220 // >
221
222 case 62:
223 escape = "&gt;";
224 break;
225
226 default:
227 // eslint-disable-next-line no-continue
228 continue;
229 }
230
231 if (lastIndex !== index) {
232 html += str.substring(lastIndex, index);
233 }
234
235 lastIndex = index + 1;
236 html += escape;
237 }
238
239 return lastIndex !== index ? html + str.substring(lastIndex, index) : html;
240}
241/** @type {Record<number, string>} */
242
243
244const statuses = {
245 400: "Bad Request",
246 403: "Forbidden",
247 404: "Not Found",
248 416: "Range Not Satisfiable",
249 500: "Internal Server Error"
250};
251/**
252 * @template {IncomingMessage} Request
253 * @template {ServerResponse} Response
254 * @param {Request} req response
255 * @param {Response} res response
256 * @param {number} status status
257 * @returns {void}
258 */
259
260function sendError(req, res, status) {
261 const content = statuses[status] || String(status);
262 const document = `<!DOCTYPE html>
263<html lang="en">
264<head>
265<meta charset="utf-8">
266<title>Error</title>
267</head>
268<body>
269<pre>${escapeHtml(content)}</pre>
270</body>
271</html>`; // Clear existing headers
272
273 clearHeadersForResponse(res); // Send basic response
274
275 setStatusCode(res, status);
276 setHeaderForResponse(res, "Content-Type", "text/html; charset=utf-8");
277 setHeaderForResponse(res, "Content-Security-Policy", "default-src 'none'");
278 setHeaderForResponse(res, "X-Content-Type-Options", "nosniff");
279 const byteLength = Buffer.byteLength(document);
280 setHeaderForResponse(res, "Content-Length", byteLength);
281 res.end(document);
282}
283
284module.exports = {
285 getHeaderNames,
286 getHeaderFromRequest,
287 getHeaderFromResponse,
288 setHeaderForResponse,
289 setStatusCode,
290 send,
291 sendError
292};
Note: See TracBrowser for help on using the repository browser.