@ublitzjs/core 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ (The MIT License)
2
+
3
+ Copyright (c) 2025-2026 Daniel Dyryl <diril656@gmail.com>
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ 'Software'), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package/README.md CHANGED
@@ -10,12 +10,14 @@ On NPM you can find such packages: (with @ublitzjs/ organization)
10
10
  - static (send files)
11
11
  - payload (handling POST-like requests)
12
12
  - router (OpenAPI-like router for simple orientation)
13
- - openapi
13
+ - openapi
14
14
  - preprocess (Code preprocessing + templating framework)
15
15
  - asyncapi
16
16
  - testing (coming soon)
17
17
  - auth (coming soon)
18
18
 
19
+ The ones having version < 1.0.0 are unstable.
20
+
19
21
  # Installation
20
22
 
21
23
  ```ps1
@@ -1,5 +1,8 @@
1
1
  "use strict";
2
2
 
3
+ /**
4
+ * Yes, I have just deprecated the whole category. It will be completely removed in 2.0.0. When is it coming? Who knows
5
+ * */
3
6
  Object.defineProperty(exports, "__esModule", {
4
7
  value: true
5
8
  });
@@ -10,19 +13,16 @@ exports.notFoundConstructor = notFoundConstructor;
10
13
  exports.seeOtherMethods = seeOtherMethods;
11
14
  exports.tooLargeBody = tooLargeBody;
12
15
  var _index = require("./index.js");
13
- var c405Message = (0, _index.toAB)("Method is not allowed");
14
- var allowHeader = (0, _index.toAB)("Allow");
15
- var checkHeader = (0, _index.toAB)("content-length");
16
- var checkMessage = (0, _index.toAB)("Content-Length is required to be > 0 and to be an integer");
17
16
  /**
18
- * If something wrong is to content-length, sends 411 code and throws error with a "cause" == { CL : string}, sets res.finished = true
17
+ * @deprecated
18
+ * uWS actually checks content-length by itself
19
19
  */
20
20
  function checkContentLength(res, req) {
21
- var header = req.getHeader(checkHeader);
21
+ var header = req.getHeader("content-length");
22
22
  var CL;
23
23
  if (!header || !Number.isInteger(CL = Number(header))) {
24
24
  res.finished = true;
25
- res.cork(() => res.writeStatus(c411).end(checkMessage));
25
+ res.cork(() => res.writeStatus("411").end("Content-Length is required to be > 0 and to be an integer"));
26
26
  throw new Error("Wrong content-length", {
27
27
  cause: {
28
28
  CL: header
@@ -32,26 +32,27 @@ function checkContentLength(res, req) {
32
32
  return CL;
33
33
  }
34
34
  /**
35
- * sends http 400 and throws an Error with "causeForYou", sets res.finished = true
35
+ * @deprecated
36
+ * This function throws, so it is slow.
36
37
  */
37
38
  function badRequest(res, error, causeForYou) {
38
39
  res.finished = true;
39
- if (!res.aborted) res.cork(() => res.writeStatus(c400).end((0, _index.toAB)(error)));
40
+ if (!res.aborted) res.cork(() => res.writeStatus("400").end((0, _index.toAB)(error)));
40
41
  throw new Error("Bad request", {
41
42
  cause: causeForYou
42
43
  });
43
44
  }
44
45
  /**
45
- * sends http 413, but doesn't throw an Error, sets res.finished = true
46
+ * @deprecated
47
+ * These are 2 lines of code.
46
48
  */
47
49
  function tooLargeBody(res, limit) {
48
- var message = (0, _index.toAB)("Body is too large. Limit in bytes - " + limit);
49
- if (!res.aborted) res.cork(() => res.writeStatus(c413).end(message));
50
+ if (!res.aborted) res.cork(() => res.writeStatus("413").end("Body is too large. Limit in bytes - " + limit));
50
51
  res.finished = true;
51
52
  }
52
53
  /**
53
- * Constructs function, which sends http 405 and sets http Allow header with all methods you passed.
54
- * It ignores "ws" and replaces "del" on "DELETE"
54
+ * @deprecated
55
+ * use "typedAllowHeader" instead
55
56
  */
56
57
  function seeOtherMethods(methodsArr) {
57
58
  if (new Set(methodsArr).size != methodsArr.length) throw new Error("the methods repeat");
@@ -68,32 +69,38 @@ function seeOtherMethods(methodsArr) {
68
69
  }
69
70
  }
70
71
  var methods = (0, _index.toAB)(arr.join(", "));
71
- return res => res.writeStatus(c405).writeHeader(allowHeader, methods).end(c405Message);
72
+ return res => res.writeStatus("405").writeHeader("Allow", methods).end("Method is not allowed");
72
73
  }
73
74
  /**
74
- * Constructs the function, which sets 404 http code and sends the message you have specified
75
+ * @deprecated
76
+ * This is 1-2 lines of code
75
77
  */
76
78
  function notFoundConstructor(message = "Not found") {
77
79
  var mes = (0, _index.toAB)(message);
78
- return res => res.writeStatus(c404).end(mes, true);
80
+ return res => res.writeStatus("404").end(mes, true);
79
81
  }
80
82
  /**
83
+ * @deprecated
81
84
  * code: required content length
82
85
  */
83
86
  var c411 = exports.c411 = (0, _index.toAB)("411");
84
87
  /**
88
+ * @deprecated
85
89
  * code: bad request
86
90
  */
87
91
  var c400 = exports.c400 = (0, _index.toAB)("400");
88
92
  /**
93
+ * @deprecated
89
94
  * code: payload too large
90
95
  */
91
96
  var c413 = exports.c413 = (0, _index.toAB)("413");
92
97
  /**
98
+ * @deprecated
93
99
  * code: method not allowed
94
100
  */
95
101
  var c405 = exports.c405 = (0, _index.toAB)("405");
96
102
  /**
103
+ * @deprecated
97
104
  * code: not found
98
105
  */
99
106
  var c404 = exports.c404 = (0, _index.toAB)("404");
@@ -3,10 +3,13 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.HeadersMap = exports.CSPDirs = void 0;
6
+ exports.helmentHeaders = exports.HeadersMap = exports.CSPDirs = void 0;
7
+ exports.parseRange = parseRange;
7
8
  exports.setCSP = setCSP;
9
+ exports.staticHeaders = staticHeaders;
10
+ exports.typedAllowHeader = typedAllowHeader;
8
11
  var _index = require("./index.js");
9
- var helmetHeaders = {
12
+ var helmentHeaders = exports.helmentHeaders = {
10
13
  "X-Content-Type-Options": "nosniff",
11
14
  "X-DNS-Prefetch-Control": "off",
12
15
  "X-Frame-Options": "DENY",
@@ -17,14 +20,41 @@ var helmetHeaders = {
17
20
  "Cross-Origin-Opener-Policy": "same-origin",
18
21
  "Cross-Origin-Embedder-Policy": "require-corp",
19
22
  "Origin-Agent-Cluster": "?1"
20
- //"Content-Security-Policy-Report-Only":"",
21
- //"Strict-Transport-Security":`max-age=${60 * 60 * 24 * 365}; includeSubDomains`,
22
23
  };
23
24
  /**
24
- * A map containing all headers as ArrayBuffers, so speed remains. There are several use cases of it:
25
- * 1) Don't define them in requests ( post(res){new HeadersMap({...headers}).prepare().toRes(res)} ). This is slow. Define maps BEFORE actual usage.
26
- * 2) You can pass them in LightMethod or HeavyMethod in shared property (but handle it manually)
27
- * 3) Don't define them before writing status on request. uWebSockets.js after first written header considers response as successful and puts "200" code automatically. Set headers AFTER validation in class controllers (handler function) and after writing status (or don't write it at all. It will be 200).
25
+ * This function is created as a replacement for "HeadersMap" (which became deprecated in 1.1.0).
26
+ * The most overhead when sending request doesn't come from utf16 -> utf8 conversion, but from many subsequent res.writeHeader, which is JS->C++ switch.
27
+ * To reduce an amount of calling headers, you can use manual string concatenation and HTTP header separator - CRLF.
28
+ * @notice this function doesn't create completely ready data to send. Look a the example below
29
+ * @notice2 its return-type LIES. In fact it is just a concatenated string, but TS lies just for LSP help for the second param and, as a result, last header, value to which should be written in res.writeHeader
30
+ * @example
31
+ * //if all headers don't change
32
+ * var headers = staticHeaders({
33
+ * "Content-Type": "text/plain"
34
+ * }, "Etag") // However "Etag" doesn't have value yet
35
+ * * var littleFasterHeaders = Buffer.from(headers)
36
+ * server.get("/", (res)=>{
37
+ * // we put ETag's value to the right. This way we can combine static + dynamic headers in one single call
38
+ * res.writeHeader(littleFasterHeaders, 'W/"' + 123 + '"')
39
+ * res.end("ok")
40
+ *
41
+ * // underneath this is the same (gain speed but lose TypeScript. Not bad if your head is a compiler)
42
+ * res.writeHeader("Content-Type: text/plain\r\nETag", 'W/"' + 123 + '"')
43
+ * // you can make right side look same as well
44
+ * res.writeHeader<string>("Content-Type", 'text/plain\r\nETag: W/"' + 123 + '"')
45
+ * })
46
+ *
47
+ * */
48
+ function staticHeaders(headers, likelyDynamicHeader) {
49
+ var result = "";
50
+ for (var key in headers) {
51
+ result += key + ": " + headers[key] + "\r\n";
52
+ }
53
+ return result += likelyDynamicHeader;
54
+ }
55
+ /**
56
+ * @deprecated because using ArrayBuffers vs strings in headers doesn't bring much benefit, as it turned out after some benchmarks (+ it uses Map class, so that's even slower). It is going to be removed in 2.0.0. When is it coming? Who knows.
57
+ * And YES, I removed description of it. Stick to "staticHeaders" or CRLF manipulations
28
58
  */
29
59
  class HeadersMap extends Map {
30
60
  currentHeaders;
@@ -69,7 +99,7 @@ class HeadersMap extends Map {
69
99
  * @example
70
100
  * new HeadersMap({...HeadersMap.baseObj, "ownHeader":"hello world"}).remove("X-Download-Options")
71
101
  */
72
- static baseObj = helmetHeaders;
102
+ static baseObj = helmentHeaders;
73
103
  /**
74
104
  * this is same as "toRes", but it uses HeadersMap.baseObj
75
105
  */
@@ -94,8 +124,6 @@ function setCSP(mainCSP, ...remove) {
94
124
  * Usual CSP directories. If you want more dirs:
95
125
  * 1) I will put more in soon
96
126
  * 2) use string concatenation (use BASE)
97
- * @example
98
- * new HeadersMap({...HeadersMap.baseObj, "Content-Security-Policy":setCSP({...CSPDirs}) + " your-dir: 'self';"})
99
127
  */
100
128
  var CSPDirs = exports.CSPDirs = {
101
129
  "default-src": ["'self'"],
@@ -115,4 +143,64 @@ var CSPDirs = exports.CSPDirs = {
115
143
  "trusted-types": ["'none'"],
116
144
  "worker-src": ["'self'"],
117
145
  "media-src": ["'self'"]
118
- };
146
+ };
147
+ var badRange = {
148
+ ok: false,
149
+ code: "400"
150
+ };
151
+ /**
152
+ * "Range" http header requires validation, so here you get it
153
+ * @example
154
+ * var data = Buffer.allocUnsafe(1024*1024)
155
+ * server.get("/largeData", (res, req)=>{
156
+ * var range = req.getHeader("range")
157
+ * if(!range) return res.end(data)
158
+ * // so parseRange might modify "range" to suit requirements + check if header is right
159
+ * var parsedRange = parseRange(range, data.length - 1, 64*1024)
160
+ * // might be
161
+ * if(!parsedRange.ok) return res.writeStatus(parsedRange.code).end("bad")
162
+ * })
163
+ * */
164
+ function parseRange(range, maxEnd, maxChunk) {
165
+ if (range.length == 7 || range.slice(0, 6) != "bytes=") return badRange;
166
+ var dash = range.indexOf("-", 6);
167
+ if (dash == -1) return badRange;
168
+ var start = dash == 6 ? undefined : Number(range.slice(6, dash));
169
+ if (Number.isNaN(start)) return badRange;
170
+ var end = range.length == dash + 1 ? undefined : Number(range.slice(dash + 1));
171
+ if (Number.isNaN(end)) return badRange;
172
+ if (end === undefined) {
173
+ end = maxChunk ? Math.min(start + maxChunk, maxEnd) : maxEnd;
174
+ } else if (start === undefined) {
175
+ start = maxEnd - end;
176
+ end = maxEnd;
177
+ }
178
+ if (start >= end || start >= maxEnd) return {
179
+ ok: false,
180
+ code: "416"
181
+ };
182
+ return {
183
+ ok: true,
184
+ start: start,
185
+ end
186
+ };
187
+ }
188
+ /**
189
+ * This function takes methods that you registered on an endpoint and formats them to suit "Allow" header.
190
+ * */
191
+ function typedAllowHeader(methodsArr) {
192
+ if (new Set(methodsArr).size != methodsArr.length) throw new Error("the methods repeat");
193
+ var arr = [];
194
+ loop: for (var method of methodsArr) {
195
+ switch (method) {
196
+ case "ws":
197
+ continue loop;
198
+ case "del":
199
+ arr.push("DELETE");
200
+ break;
201
+ default:
202
+ arr.push(method.toUpperCase());
203
+ }
204
+ }
205
+ return arr.join(", ");
206
+ }
package/dist/cjs/index.js CHANGED
@@ -47,7 +47,12 @@ _uWebSockets.DeclarativeResponse.prototype.writeHeaders = function (headers) {
47
47
  };
48
48
  /**
49
49
  * function to effortlessly mark response as aborted AND to attach an event emitter, so that you can easily scale the handler. If you don't need event emitter and only some res.aborted - set it by yourself (no overkill for the handler)
50
+ * If some utility expect import("@ublitzjs/core").HttpResponse, it means that they response to first go through this registerAbort
50
51
  * @param res
52
+ * @example
53
+ * console.log(Boolean(res.emitter)) // false
54
+ * registerAbort(res)
55
+ * console.log(Boolean(res.emitter)) // true
51
56
  */
52
57
  function registerAbort(res) {
53
58
  if (typeof res.aborted === "boolean") throw new Error("abort already registered");
@@ -92,7 +97,7 @@ function extendApp(app, ...rest) {
92
97
  return app;
93
98
  }
94
99
  /**
95
- * conversion to ArrayBuffer ('cause transferring strings to uWS is really slow)
100
+ * @deprecated this conversion to arrayBuffer is not really necessary. You just have Buffer.from(""). Slicing that is rarely needed, and even if it is, that takes 4 lines of code
96
101
  */
97
102
  function toAB(data) {
98
103
  var NodeBuf = data instanceof _nodeBuffer.Buffer ? data : _nodeBuffer.Buffer.from(data);
@@ -1,43 +1,44 @@
1
1
  "use strict";
2
+ /**
3
+ * Yes, I have just deprecated the whole category. It will be completely removed in 2.0.0. When is it coming? Who knows
4
+ * */
2
5
  import { toAB } from "./index.js";
3
- var c405Message = toAB("Method is not allowed");
4
- var allowHeader = toAB("Allow");
5
- var checkHeader = toAB("content-length");
6
- var checkMessage = toAB("Content-Length is required to be > 0 and to be an integer");
7
6
  /**
8
- * If something wrong is to content-length, sends 411 code and throws error with a "cause" == { CL : string}, sets res.finished = true
7
+ * @deprecated
8
+ * uWS actually checks content-length by itself
9
9
  */
10
10
  export function checkContentLength(res, req) {
11
- var header = req.getHeader(checkHeader);
11
+ var header = req.getHeader("content-length");
12
12
  var CL;
13
13
  if (!header || !Number.isInteger(CL = Number(header))) {
14
14
  res.finished = true;
15
- res.cork(() => res.writeStatus(c411).end(checkMessage));
15
+ res.cork(() => res.writeStatus("411").end("Content-Length is required to be > 0 and to be an integer"));
16
16
  throw new Error("Wrong content-length", { cause: { CL: header } });
17
17
  }
18
18
  return CL;
19
19
  }
20
20
  /**
21
- * sends http 400 and throws an Error with "causeForYou", sets res.finished = true
21
+ * @deprecated
22
+ * This function throws, so it is slow.
22
23
  */
23
24
  export function badRequest(res, error, causeForYou) {
24
25
  res.finished = true;
25
26
  if (!res.aborted)
26
- res.cork(() => res.writeStatus(c400).end(toAB(error)));
27
+ res.cork(() => res.writeStatus("400").end(toAB(error)));
27
28
  throw new Error("Bad request", { cause: causeForYou });
28
29
  }
29
30
  /**
30
- * sends http 413, but doesn't throw an Error, sets res.finished = true
31
+ * @deprecated
32
+ * These are 2 lines of code.
31
33
  */
32
34
  export function tooLargeBody(res, limit) {
33
- var message = toAB("Body is too large. Limit in bytes - " + limit);
34
35
  if (!res.aborted)
35
- res.cork(() => res.writeStatus(c413).end(message));
36
+ res.cork(() => res.writeStatus("413").end("Body is too large. Limit in bytes - " + limit));
36
37
  res.finished = true;
37
38
  }
38
39
  /**
39
- * Constructs function, which sends http 405 and sets http Allow header with all methods you passed.
40
- * It ignores "ws" and replaces "del" on "DELETE"
40
+ * @deprecated
41
+ * use "typedAllowHeader" instead
41
42
  */
42
43
  export function seeOtherMethods(methodsArr) {
43
44
  if (new Set(methodsArr).size != methodsArr.length)
@@ -53,32 +54,38 @@ export function seeOtherMethods(methodsArr) {
53
54
  }
54
55
  }
55
56
  var methods = toAB(arr.join(", "));
56
- return (res) => res.writeStatus(c405).writeHeader(allowHeader, methods).end(c405Message);
57
+ return (res) => res.writeStatus("405").writeHeader("Allow", methods).end("Method is not allowed");
57
58
  }
58
59
  /**
59
- * Constructs the function, which sets 404 http code and sends the message you have specified
60
+ * @deprecated
61
+ * This is 1-2 lines of code
60
62
  */
61
63
  export function notFoundConstructor(message = "Not found") {
62
64
  var mes = toAB(message);
63
- return (res) => res.writeStatus(c404).end(mes, true);
65
+ return (res) => res.writeStatus("404").end(mes, true);
64
66
  }
65
67
  /**
68
+ * @deprecated
66
69
  * code: required content length
67
70
  */
68
71
  export var c411 = toAB("411");
69
72
  /**
73
+ * @deprecated
70
74
  * code: bad request
71
75
  */
72
76
  export var c400 = toAB("400");
73
77
  /**
78
+ * @deprecated
74
79
  * code: payload too large
75
80
  */
76
81
  export var c413 = toAB("413");
77
82
  /**
83
+ * @deprecated
78
84
  * code: method not allowed
79
85
  */
80
86
  export var c405 = toAB("405");
81
87
  /**
88
+ * @deprecated
82
89
  * code: not found
83
90
  */
84
91
  export var c404 = toAB("404");
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  import { toAB } from "./index.js";
3
- var helmetHeaders = {
3
+ export var helmentHeaders = {
4
4
  "X-Content-Type-Options": "nosniff",
5
5
  "X-DNS-Prefetch-Control": "off",
6
6
  "X-Frame-Options": "DENY",
@@ -11,14 +11,41 @@ var helmetHeaders = {
11
11
  "Cross-Origin-Opener-Policy": "same-origin",
12
12
  "Cross-Origin-Embedder-Policy": "require-corp",
13
13
  "Origin-Agent-Cluster": "?1",
14
- //"Content-Security-Policy-Report-Only":"",
15
- //"Strict-Transport-Security":`max-age=${60 * 60 * 24 * 365}; includeSubDomains`,
16
14
  };
17
15
  /**
18
- * A map containing all headers as ArrayBuffers, so speed remains. There are several use cases of it:
19
- * 1) Don't define them in requests ( post(res){new HeadersMap({...headers}).prepare().toRes(res)} ). This is slow. Define maps BEFORE actual usage.
20
- * 2) You can pass them in LightMethod or HeavyMethod in shared property (but handle it manually)
21
- * 3) Don't define them before writing status on request. uWebSockets.js after first written header considers response as successful and puts "200" code automatically. Set headers AFTER validation in class controllers (handler function) and after writing status (or don't write it at all. It will be 200).
16
+ * This function is created as a replacement for "HeadersMap" (which became deprecated in 1.1.0).
17
+ * The most overhead when sending request doesn't come from utf16 -> utf8 conversion, but from many subsequent res.writeHeader, which is JS->C++ switch.
18
+ * To reduce an amount of calling headers, you can use manual string concatenation and HTTP header separator - CRLF.
19
+ * @notice this function doesn't create completely ready data to send. Look a the example below
20
+ * @notice2 its return-type LIES. In fact it is just a concatenated string, but TS lies just for LSP help for the second param and, as a result, last header, value to which should be written in res.writeHeader
21
+ * @example
22
+ * //if all headers don't change
23
+ * var headers = staticHeaders({
24
+ * "Content-Type": "text/plain"
25
+ * }, "Etag") // However "Etag" doesn't have value yet
26
+ * * var littleFasterHeaders = Buffer.from(headers)
27
+ * server.get("/", (res)=>{
28
+ * // we put ETag's value to the right. This way we can combine static + dynamic headers in one single call
29
+ * res.writeHeader(littleFasterHeaders, 'W/"' + 123 + '"')
30
+ * res.end("ok")
31
+ *
32
+ * // underneath this is the same (gain speed but lose TypeScript. Not bad if your head is a compiler)
33
+ * res.writeHeader("Content-Type: text/plain\r\nETag", 'W/"' + 123 + '"')
34
+ * // you can make right side look same as well
35
+ * res.writeHeader<string>("Content-Type", 'text/plain\r\nETag: W/"' + 123 + '"')
36
+ * })
37
+ *
38
+ * */
39
+ export function staticHeaders(headers, likelyDynamicHeader) {
40
+ var result = "";
41
+ for (var key in headers) {
42
+ result += key + ": " + headers[key] + "\r\n";
43
+ }
44
+ return (result += likelyDynamicHeader);
45
+ }
46
+ /**
47
+ * @deprecated because using ArrayBuffers vs strings in headers doesn't bring much benefit, as it turned out after some benchmarks (+ it uses Map class, so that's even slower). It is going to be removed in 2.0.0. When is it coming? Who knows.
48
+ * And YES, I removed description of it. Stick to "staticHeaders" or CRLF manipulations
22
49
  */
23
50
  export class HeadersMap extends Map {
24
51
  currentHeaders;
@@ -68,7 +95,7 @@ export class HeadersMap extends Map {
68
95
  * @example
69
96
  * new HeadersMap({...HeadersMap.baseObj, "ownHeader":"hello world"}).remove("X-Download-Options")
70
97
  */
71
- static baseObj = helmetHeaders;
98
+ static baseObj = helmentHeaders;
72
99
  /**
73
100
  * this is same as "toRes", but it uses HeadersMap.baseObj
74
101
  */
@@ -95,8 +122,6 @@ export function setCSP(mainCSP, ...remove) {
95
122
  * Usual CSP directories. If you want more dirs:
96
123
  * 1) I will put more in soon
97
124
  * 2) use string concatenation (use BASE)
98
- * @example
99
- * new HeadersMap({...HeadersMap.baseObj, "Content-Security-Policy":setCSP({...CSPDirs}) + " your-dir: 'self';"})
100
125
  */
101
126
  export var CSPDirs = {
102
127
  "default-src": ["'self'"],
@@ -117,3 +142,58 @@ export var CSPDirs = {
117
142
  "worker-src": ["'self'"],
118
143
  "media-src": ["'self'"],
119
144
  };
145
+ var badRange = { ok: false, code: "400" };
146
+ /**
147
+ * "Range" http header requires validation, so here you get it
148
+ * @example
149
+ * var data = Buffer.allocUnsafe(1024*1024)
150
+ * server.get("/largeData", (res, req)=>{
151
+ * var range = req.getHeader("range")
152
+ * if(!range) return res.end(data)
153
+ * // so parseRange might modify "range" to suit requirements + check if header is right
154
+ * var parsedRange = parseRange(range, data.length - 1, 64*1024)
155
+ * // might be
156
+ * if(!parsedRange.ok) return res.writeStatus(parsedRange.code).end("bad")
157
+ * })
158
+ * */
159
+ export function parseRange(range, maxEnd, maxChunk) {
160
+ if (range.length == 7 || range.slice(0, 6) != "bytes=")
161
+ return badRange;
162
+ var dash = range.indexOf("-", 6);
163
+ if (dash == -1)
164
+ return badRange;
165
+ var start = dash == 6 ? undefined : Number(range.slice(6, dash));
166
+ if (Number.isNaN(start))
167
+ return badRange;
168
+ var end = range.length == dash + 1 ? undefined : Number(range.slice(dash + 1));
169
+ if (Number.isNaN(end))
170
+ return badRange;
171
+ if (end === undefined) {
172
+ end = maxChunk ? Math.min(start + maxChunk, maxEnd) : maxEnd;
173
+ }
174
+ else if (start === undefined) {
175
+ start = maxEnd - end;
176
+ end = maxEnd;
177
+ }
178
+ if (start >= end || start >= maxEnd)
179
+ return { ok: false, code: "416" };
180
+ return { ok: true, start: start, end };
181
+ }
182
+ /**
183
+ * This function takes methods that you registered on an endpoint and formats them to suit "Allow" header.
184
+ * */
185
+ export function typedAllowHeader(methodsArr) {
186
+ if (new Set(methodsArr).size != methodsArr.length)
187
+ throw new Error("the methods repeat");
188
+ var arr = [];
189
+ loop: for (var method of methodsArr) {
190
+ switch (method) {
191
+ case "ws": continue loop;
192
+ case "del":
193
+ arr.push("DELETE");
194
+ break;
195
+ default: arr.push(method.toUpperCase());
196
+ }
197
+ }
198
+ return arr.join(", ");
199
+ }
package/dist/esm/index.js CHANGED
@@ -9,7 +9,12 @@ uWS.DeclarativeResponse.prototype.writeHeaders = function (headers) {
9
9
  };
10
10
  /**
11
11
  * function to effortlessly mark response as aborted AND to attach an event emitter, so that you can easily scale the handler. If you don't need event emitter and only some res.aborted - set it by yourself (no overkill for the handler)
12
+ * If some utility expect import("@ublitzjs/core").HttpResponse, it means that they response to first go through this registerAbort
12
13
  * @param res
14
+ * @example
15
+ * console.log(Boolean(res.emitter)) // false
16
+ * registerAbort(res)
17
+ * console.log(Boolean(res.emitter)) // true
13
18
  */
14
19
  export function registerAbort(res) {
15
20
  if (typeof res.aborted === "boolean")
@@ -57,7 +62,7 @@ export function extendApp(app, ...rest) {
57
62
  return app;
58
63
  }
59
64
  /**
60
- * conversion to ArrayBuffer ('cause transferring strings to uWS is really slow)
65
+ * @deprecated this conversion to arrayBuffer is not really necessary. You just have Buffer.from(""). Slicing that is rarely needed, and even if it is, that takes 4 lines of code
61
66
  */
62
67
  export function toAB(data) {
63
68
  var NodeBuf = data instanceof Buffer ? data : Buffer.from(data);
@@ -1,43 +1,52 @@
1
1
  import type { HttpResponse as uwsHttpResponse } from "uWebSockets.js";
2
2
  import type { HttpRequest, HttpMethods } from "./index.ts";
3
3
  /**
4
- * If something wrong is to content-length, sends 411 code and throws error with a "cause" == { CL : string}, sets res.finished = true
4
+ * @deprecated
5
+ * uWS actually checks content-length by itself
5
6
  */
6
7
  export declare function checkContentLength(res: uwsHttpResponse, req: HttpRequest): number;
7
8
  /**
8
- * sends http 400 and throws an Error with "causeForYou", sets res.finished = true
9
+ * @deprecated
10
+ * This function throws, so it is slow.
9
11
  */
10
12
  export declare function badRequest(res: uwsHttpResponse, error: string, causeForYou: string): void;
11
13
  /**
12
- * sends http 413, but doesn't throw an Error, sets res.finished = true
14
+ * @deprecated
15
+ * These are 2 lines of code.
13
16
  */
14
17
  export declare function tooLargeBody(res: uwsHttpResponse, limit: number): void;
15
18
  /**
16
- * Constructs function, which sends http 405 and sets http Allow header with all methods you passed.
17
- * It ignores "ws" and replaces "del" on "DELETE"
19
+ * @deprecated
20
+ * use "typedAllowHeader" instead
18
21
  */
19
22
  export declare function seeOtherMethods(methodsArr: HttpMethods[]): (res: uwsHttpResponse, req: any) => any;
20
23
  /**
21
- * Constructs the function, which sets 404 http code and sends the message you have specified
24
+ * @deprecated
25
+ * This is 1-2 lines of code
22
26
  */
23
27
  export declare function notFoundConstructor(message?: string): (res: uwsHttpResponse, req: any) => any;
24
28
  /**
29
+ * @deprecated
25
30
  * code: required content length
26
31
  */
27
32
  export declare var c411: ArrayBuffer;
28
33
  /**
34
+ * @deprecated
29
35
  * code: bad request
30
36
  */
31
37
  export declare var c400: ArrayBuffer;
32
38
  /**
39
+ * @deprecated
33
40
  * code: payload too large
34
41
  */
35
42
  export declare var c413: ArrayBuffer;
36
43
  /**
44
+ * @deprecated
37
45
  * code: method not allowed
38
46
  */
39
47
  export declare var c405: ArrayBuffer;
40
48
  /**
49
+ * @deprecated
41
50
  * code: not found
42
51
  */
43
52
  export declare var c404: ArrayBuffer;