@jwn-js/common 2.2.2 → 2.2.3

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.
Files changed (82) hide show
  1. package/ApiError.js +37 -1
  2. package/ApiError.mjs +35 -1
  3. package/Jwt-B4QZ2Ypb.js +80 -0
  4. package/Jwt-Be4GWrIO.js +75 -0
  5. package/Jwt.js +8 -1
  6. package/Jwt.mjs +2 -1
  7. package/Memcached.js +166 -9
  8. package/Memcached.mjs +164 -9
  9. package/Server.js +316 -1
  10. package/Server.mjs +313 -1
  11. package/cookieParse.js +25 -1
  12. package/cookieParse.mjs +23 -1
  13. package/cookieString.js +22 -1
  14. package/cookieString.mjs +20 -1
  15. package/docs/classes/ApiError.html +2 -2
  16. package/docs/classes/AsyncJwt.html +2 -2
  17. package/docs/classes/Controller.html +2 -2
  18. package/docs/classes/Jwt.html +2 -2
  19. package/docs/classes/Memcached.html +2 -2
  20. package/docs/classes/Model.html +2 -2
  21. package/docs/classes/Server.html +2 -2
  22. package/docs/classes/Ssr.html +2 -2
  23. package/docs/classes/Web.html +2 -2
  24. package/docs/functions/action.html +2 -2
  25. package/docs/functions/body.html +2 -2
  26. package/docs/functions/codeToStatus.html +2 -2
  27. package/docs/functions/config.html +2 -2
  28. package/docs/functions/connection.html +2 -2
  29. package/docs/functions/context.html +2 -2
  30. package/docs/functions/controller-1.html +2 -2
  31. package/docs/functions/cookies.html +2 -2
  32. package/docs/functions/db.html +2 -2
  33. package/docs/functions/headers.html +2 -2
  34. package/docs/functions/home.html +2 -2
  35. package/docs/functions/hostname.html +2 -2
  36. package/docs/functions/http.html +2 -2
  37. package/docs/functions/init.html +2 -2
  38. package/docs/functions/json.html +2 -2
  39. package/docs/functions/logerror.html +2 -2
  40. package/docs/functions/method.html +2 -2
  41. package/docs/functions/mixin.html +2 -2
  42. package/docs/functions/mount.html +2 -2
  43. package/docs/functions/pool.html +2 -2
  44. package/docs/functions/protocol.html +2 -2
  45. package/docs/functions/request.html +2 -2
  46. package/docs/functions/selectControllersSchema.html +1 -1
  47. package/docs/functions/stream.html +2 -2
  48. package/docs/functions/subaction.html +2 -2
  49. package/docs/functions/url.html +2 -2
  50. package/docs/functions/xml.html +2 -2
  51. package/docs/index.html +2 -2
  52. package/docs/interfaces/ApiErrorMessage.html +2 -2
  53. package/docs/interfaces/ContextSsr.html +2 -2
  54. package/docs/interfaces/ContextWeb.html +2 -2
  55. package/docs/interfaces/OptionsSsr.html +2 -2
  56. package/docs/interfaces/OptionsWeb.html +2 -2
  57. package/docs/interfaces/ResponseOptions.html +2 -2
  58. package/docs/interfaces/Route.html +2 -2
  59. package/docs/interfaces/Schema.html +2 -2
  60. package/docs/interfaces/ServerHandler.html +2 -2
  61. package/docs/interfaces/ServerOptions.html +2 -2
  62. package/docs/interfaces/ServerWebsocket.html +2 -2
  63. package/docs/modules.html +2 -2
  64. package/docs/types/ServerRoutes.html +1 -1
  65. package/docs/variables/helpers.html +2 -2
  66. package/index.js +1473 -4
  67. package/index.mjs +1417 -4
  68. package/jsonBody.js +25 -1
  69. package/jsonBody.mjs +23 -1
  70. package/multipartBody.js +42 -1
  71. package/multipartBody.mjs +40 -1
  72. package/package.json +1 -1
  73. package/readConfig.js +11 -1
  74. package/readConfig.mjs +9 -1
  75. package/readConfigSync.js +11 -1
  76. package/readConfigSync.mjs +9 -1
  77. package/staticBody.js +205 -1
  78. package/staticBody.mjs +200 -1
  79. package/urlencodedBody.js +26 -1
  80. package/urlencodedBody.mjs +24 -1
  81. package/Jwt-7tQL-rwa.js +0 -1
  82. package/Jwt-CDdbxwvH.js +0 -1
package/Server.js CHANGED
@@ -1 +1,316 @@
1
- "use strict";var l=require("dns"),p=require("uWebSockets.js"),d=require("./cookieParse.js");const c={100:"100 Continue",101:"101 Switching Protocols",200:"200 OK",201:"201 Created",202:"202 Accepted",203:"203 Non-Authoritative Information",204:"No Content",205:"205 Reset Content",206:"206 Partial Content",300:"300 Multiple Choices",301:"301 Moved Permanently",302:"302 Found",303:"303 See Other",304:"304 Not Modified",305:"305 Use Proxy",306:"306 (Unused)",307:"307 Temporary Redirect",400:"400 Bad Request",401:"401 Unauthorized",402:"402 Payment Required",403:"403 Forbidden",404:"404 Not Found",405:"405 Method Not Allowed",406:"406 Not Acceptable",407:"407 Proxy Authentication Required",408:"408 Request Timeout",409:"409 Conflict",410:"410 Gone",411:"411 Length Required",412:"412 Precondition Failed",413:"413 Request Entity Too Large",414:"414 Request-URI Too Long",415:"415 Unsupported Media Type",416:"416 Requested Range Not Satisfiable",417:"417 Expectation Failed",500:"500 Internal Server Error",501:"501 Not Implemented",502:"502 Bad Gateway",503:"503 Service Unavailable",504:"504 Gateway Timeout",505:"505 HTTP Version Not Supported"},m=a=>c.hasOwnProperty(a)?c[a]:`${a}`;class f{constructor(t){this._logLevel="info",this._socket=null,this._timeout=0,this._routes=[],this._host="localhost",this._port=3e3,this._mode="production",this._appOptions={},this._defaultRoute={method:"get",pattern:"/*",handler:(o,s,r)=>r()},this._routes=t.routes||this._routes,this._host=t.host||this._host,this._port=t.port||this._port,this._timeout=t.timeout||this._timeout,this._mode=t.mode||this._mode,this._appOptions=t.appOptions||this._appOptions,this._logLevel=t.logLevel||this._logLevel}getApp(){return this._app}app(){return this._protocol="http",this._app=p.App(this._appOptions),this}sslApp(){return this._protocol="https",this._app=p.SSLApp(this._appOptions),this}push(t){return this._routes.push(t),this}unshift(t){return this._routes.unshift(t),this}listen(t,o,s=()=>{}){if(typeof o=="number"?(this._port=o,this._host=t):typeof t=="number"?(typeof o=="function"&&(s=o),this._port=t):typeof t=="function"&&(s=t),!this._app)throw new Error("Create app or sslApp first");return this._lookup(this._host,r=>{for(let e of this._routes)switch(e=typeof e=="function"?{handler:e}:e,e=Object.assign({},this._defaultRoute,e),e.method){case"ws":this._app[e.method](e.pattern,e.behavior);break;default:const h=e;this._app[h.method](e.pattern,(n,i)=>{n.redirect=(u,_=307)=>this.constructor._redirect(n,i,u,_),i.cookies=d.cookieParse(i.getHeader("cookie")),Promise.race([this._abortTimeout(n,i),this._createHandler(n,i,h.handler)])})}this._app.listen(r,this._port,e=>{s(e),e?(this._socket=e,this._mode==="development"&&["info"].includes(this._logLevel)&&console.log(`Listening ${this._protocol}://${this._host}:${this._port}`)):["info","warn","error"].includes(this._logLevel)&&console.error(`Error start server on ${this._protocol}://${this._host}:${this._port}`)})}),this}async close(){if(this._socket){for(await p.us_listen_socket_close(this._socket);await new Promise(t=>setTimeout(t,50)),!(await this.socketPort()<0););this._socket=null}return this}async socketPort(){return this._socket?p.us_socket_local_port(this._socket):-1}_createHandler(t,o,s){return new Promise(async r=>{const e=()=>{clearTimeout(this._timeoutId),r()};try{const h=(i,u=307)=>{if(typeof i=="boolean"&&o.setYield(i),i instanceof Error)throw i;typeof i=="string"&&t.redirect(i,u),e()},n=s(t,o,h);n instanceof Promise&&h(await n)}catch(h){["info","warn","error"].includes(this._logLevel)&&console.error(h);const n=this._mode==="development"?h.message:"";t.cork(()=>{t.writeStatus("404 Not Found").end(n)}),e()}})}static _redirect(t,o,s,r=307){let e="307 Temporary Redirect";r===301&&(e="301 Moved Permanently"),t.cork(()=>{t.writeStatus(e).writeHeader("location",s).end()})}_abortTimeout(t,o){return new Promise(s=>{this._timeout&&!o.getHeader("x-no-timeout")&&(this._timeoutId=setTimeout(()=>{try{t.cork(()=>{t.writeStatus("408 Request Timeout").end(),s()})}catch{}},this._timeout))})}_lookup(t,o){l.lookup(this._host,(s,r)=>{s?["info","warn","error"].includes(this._logLevel)&&console.log(`${this._host} error: ${s.message}`):o(Buffer.from(r))})}}exports.Server=f,exports.codeToStatus=m;
1
+ 'use strict';
2
+
3
+ var dns = require('dns');
4
+ var uws = require('uWebSockets.js');
5
+ var cookieParse = require('./cookieParse.js');
6
+
7
+ const status = {
8
+ 100: "100 Continue",
9
+ 101: "101 Switching Protocols",
10
+ 200: "200 OK",
11
+ 201: "201 Created",
12
+ 202: "202 Accepted",
13
+ 203: "203 Non-Authoritative Information",
14
+ 204: "No Content",
15
+ 205: "205 Reset Content",
16
+ 206: "206 Partial Content",
17
+ 300: "300 Multiple Choices",
18
+ 301: "301 Moved Permanently",
19
+ 302: "302 Found",
20
+ 303: "303 See Other",
21
+ 304: "304 Not Modified",
22
+ 305: "305 Use Proxy",
23
+ 306: "306 (Unused)",
24
+ 307: "307 Temporary Redirect",
25
+ 400: "400 Bad Request",
26
+ 401: "401 Unauthorized",
27
+ 402: "402 Payment Required",
28
+ 403: "403 Forbidden",
29
+ 404: "404 Not Found",
30
+ 405: "405 Method Not Allowed",
31
+ 406: "406 Not Acceptable",
32
+ 407: "407 Proxy Authentication Required",
33
+ 408: "408 Request Timeout",
34
+ 409: "409 Conflict",
35
+ 410: "410 Gone",
36
+ 411: "411 Length Required",
37
+ 412: "412 Precondition Failed",
38
+ 413: "413 Request Entity Too Large",
39
+ 414: "414 Request-URI Too Long",
40
+ 415: "415 Unsupported Media Type",
41
+ 416: "416 Requested Range Not Satisfiable",
42
+ 417: "417 Expectation Failed",
43
+ 500: "500 Internal Server Error",
44
+ 501: "501 Not Implemented",
45
+ 502: "502 Bad Gateway",
46
+ 503: "503 Service Unavailable",
47
+ 504: "504 Gateway Timeout",
48
+ 505: "505 HTTP Version Not Supported"
49
+ };
50
+ const codeToStatus = (code) => {
51
+ return status.hasOwnProperty(code) ? status[code] : `${code}`;
52
+ };
53
+ class Server {
54
+ /**
55
+ * @constructor
56
+ * @param options
57
+ */
58
+ constructor(options) {
59
+ this._logLevel = "info";
60
+ /**
61
+ * Listen socket
62
+ * @private
63
+ */
64
+ this._socket = null;
65
+ /**
66
+ * Request timeout
67
+ * @private
68
+ */
69
+ this._timeout = 0;
70
+ this._routes = [];
71
+ this._host = "localhost";
72
+ this._port = 3e3;
73
+ this._mode = "production";
74
+ this._appOptions = {};
75
+ /**
76
+ * Default route options
77
+ * @private
78
+ */
79
+ this._defaultRoute = {
80
+ method: "get",
81
+ pattern: "/*",
82
+ handler: (res, req, next) => next()
83
+ };
84
+ this._routes = options.routes || this._routes;
85
+ this._host = options.host || this._host;
86
+ this._port = options.port || this._port;
87
+ this._timeout = options.timeout || this._timeout;
88
+ this._mode = options.mode || this._mode;
89
+ this._appOptions = options.appOptions || this._appOptions;
90
+ this._logLevel = options.logLevel || this._logLevel;
91
+ }
92
+ /**
93
+ * Get TemplatedApp instance
94
+ */
95
+ getApp() {
96
+ return this._app;
97
+ }
98
+ /**
99
+ * Create app (server http)
100
+ * @returns this
101
+ */
102
+ app() {
103
+ this._protocol = "http";
104
+ this._app = uws.App(this._appOptions);
105
+ return this;
106
+ }
107
+ /**
108
+ * Create sslApp
109
+ * @returns this
110
+ */
111
+ sslApp() {
112
+ this._protocol = "https";
113
+ this._app = uws.SSLApp(this._appOptions);
114
+ return this;
115
+ }
116
+ /**
117
+ * Push route
118
+ * @param route
119
+ * @returns this
120
+ */
121
+ push(route) {
122
+ this._routes.push(route);
123
+ return this;
124
+ }
125
+ /**
126
+ * unshift route
127
+ * @param route
128
+ * @returns this
129
+ */
130
+ unshift(route) {
131
+ this._routes.unshift(route);
132
+ return this;
133
+ }
134
+ listen(host, port, fn = () => {
135
+ }) {
136
+ if (typeof port === "number") {
137
+ this._port = port;
138
+ this._host = host;
139
+ } else if (typeof host === "number") {
140
+ if (typeof port === "function") {
141
+ fn = port;
142
+ }
143
+ this._port = host;
144
+ } else if (typeof host === "function") {
145
+ fn = host;
146
+ }
147
+ if (!this._app) {
148
+ throw new Error("Create app or sslApp first");
149
+ }
150
+ this._lookup(this._host, (ip) => {
151
+ for (let route of this._routes) {
152
+ route = typeof route === "function" ? { handler: route } : route;
153
+ route = Object.assign({}, this._defaultRoute, route);
154
+ switch (route.method) {
155
+ case "ws":
156
+ this._app[route.method](route.pattern, route.behavior);
157
+ break;
158
+ default:
159
+ const routeHandler = route;
160
+ this._app[routeHandler.method](
161
+ route.pattern,
162
+ (res, req) => {
163
+ res.redirect = (url, code = 307) => this.constructor._redirect(res, req, url, code);
164
+ req.cookies = cookieParse.cookieParse(req.getHeader("cookie"));
165
+ Promise.race([
166
+ this._abortTimeout(res, req),
167
+ this._createHandler(
168
+ res,
169
+ req,
170
+ routeHandler.handler
171
+ )
172
+ ]);
173
+ }
174
+ );
175
+ }
176
+ }
177
+ this._app.listen(ip, this._port, (listenSocket) => {
178
+ fn(listenSocket);
179
+ if (listenSocket) {
180
+ this._socket = listenSocket;
181
+ if (this._mode === "development") {
182
+ ["info"].includes(this._logLevel) && console.log(
183
+ `Listening ${this._protocol}://${this._host}:${this._port}`
184
+ );
185
+ }
186
+ } else {
187
+ ["info", "warn", "error"].includes(this._logLevel) && console.error(
188
+ `Error start server on ${this._protocol}://${this._host}:${this._port}`
189
+ );
190
+ }
191
+ });
192
+ });
193
+ return this;
194
+ }
195
+ /**
196
+ * Closes a uSockets listen socket.
197
+ */
198
+ async close() {
199
+ if (this._socket) {
200
+ await uws.us_listen_socket_close(this._socket);
201
+ while (true) {
202
+ await new Promise((resolve) => setTimeout(resolve, 50));
203
+ if (await this.socketPort() < 0) {
204
+ break;
205
+ }
206
+ }
207
+ this._socket = null;
208
+ }
209
+ return this;
210
+ }
211
+ /**
212
+ * Return socket port
213
+ */
214
+ async socketPort() {
215
+ if (!this._socket) {
216
+ return -1;
217
+ }
218
+ return uws.us_socket_local_port(this._socket);
219
+ }
220
+ /**
221
+ * Create decoration of handler
222
+ * @param res http response
223
+ * @param req http request
224
+ * @param fn handler
225
+ * @private
226
+ */
227
+ _createHandler(res, req, fn) {
228
+ return new Promise(async (resolve) => {
229
+ const end = () => {
230
+ clearTimeout(this._timeoutId);
231
+ resolve();
232
+ };
233
+ try {
234
+ const next = (param, code = 307) => {
235
+ if (typeof param === "boolean") {
236
+ req.setYield(param);
237
+ }
238
+ if (param instanceof Error) {
239
+ throw param;
240
+ }
241
+ if (typeof param === "string") {
242
+ res.redirect(param, code);
243
+ }
244
+ end();
245
+ };
246
+ const result = fn(res, req, next);
247
+ if (result instanceof Promise) {
248
+ next(await result);
249
+ }
250
+ } catch (e) {
251
+ ["info", "warn", "error"].includes(this._logLevel) && console.error(e);
252
+ const body = this._mode === "development" ? e.message : "";
253
+ res.cork(() => {
254
+ res.writeStatus("404 Not Found").end(body);
255
+ });
256
+ end();
257
+ }
258
+ });
259
+ }
260
+ /**
261
+ * Redirect request
262
+ * @param res
263
+ * @param req
264
+ * @param url string of url
265
+ * @param code redirect status code
266
+ * @private
267
+ */
268
+ static _redirect(res, req, url, code = 307) {
269
+ let status2 = "307 Temporary Redirect";
270
+ if (code === 301) {
271
+ status2 = "301 Moved Permanently";
272
+ }
273
+ res.cork(() => {
274
+ res.writeStatus(status2).writeHeader("location", url).end();
275
+ });
276
+ }
277
+ /**
278
+ * Abort request by timeout
279
+ * @private
280
+ */
281
+ _abortTimeout(res, req) {
282
+ return new Promise((resolve) => {
283
+ if (this._timeout && !req.getHeader("x-no-timeout")) {
284
+ this._timeoutId = setTimeout(() => {
285
+ try {
286
+ res.cork(() => {
287
+ res.writeStatus("408 Request Timeout").end();
288
+ resolve();
289
+ });
290
+ } catch (e) {
291
+ }
292
+ }, this._timeout);
293
+ }
294
+ });
295
+ }
296
+ /**
297
+ * lookup for host
298
+ * @param host
299
+ * @param resolve
300
+ * @private
301
+ */
302
+ _lookup(host, resolve) {
303
+ dns.lookup(this._host, (err, addresses) => {
304
+ if (err) {
305
+ ["info", "warn", "error"].includes(this._logLevel) && console.log(
306
+ `${this._host} error: ${err.message}`
307
+ );
308
+ } else {
309
+ resolve(Buffer.from(addresses));
310
+ }
311
+ });
312
+ }
313
+ }
314
+
315
+ exports.Server = Server;
316
+ exports.codeToStatus = codeToStatus;
package/Server.mjs CHANGED
@@ -1 +1,313 @@
1
- import l from"dns";import p from"uWebSockets.js";import{cookieParse as d}from"./cookieParse.mjs";const c={100:"100 Continue",101:"101 Switching Protocols",200:"200 OK",201:"201 Created",202:"202 Accepted",203:"203 Non-Authoritative Information",204:"No Content",205:"205 Reset Content",206:"206 Partial Content",300:"300 Multiple Choices",301:"301 Moved Permanently",302:"302 Found",303:"303 See Other",304:"304 Not Modified",305:"305 Use Proxy",306:"306 (Unused)",307:"307 Temporary Redirect",400:"400 Bad Request",401:"401 Unauthorized",402:"402 Payment Required",403:"403 Forbidden",404:"404 Not Found",405:"405 Method Not Allowed",406:"406 Not Acceptable",407:"407 Proxy Authentication Required",408:"408 Request Timeout",409:"409 Conflict",410:"410 Gone",411:"411 Length Required",412:"412 Precondition Failed",413:"413 Request Entity Too Large",414:"414 Request-URI Too Long",415:"415 Unsupported Media Type",416:"416 Requested Range Not Satisfiable",417:"417 Expectation Failed",500:"500 Internal Server Error",501:"501 Not Implemented",502:"502 Bad Gateway",503:"503 Service Unavailable",504:"504 Gateway Timeout",505:"505 HTTP Version Not Supported"},m=a=>c.hasOwnProperty(a)?c[a]:`${a}`;class f{constructor(t){this._logLevel="info",this._socket=null,this._timeout=0,this._routes=[],this._host="localhost",this._port=3e3,this._mode="production",this._appOptions={},this._defaultRoute={method:"get",pattern:"/*",handler:(o,s,r)=>r()},this._routes=t.routes||this._routes,this._host=t.host||this._host,this._port=t.port||this._port,this._timeout=t.timeout||this._timeout,this._mode=t.mode||this._mode,this._appOptions=t.appOptions||this._appOptions,this._logLevel=t.logLevel||this._logLevel}getApp(){return this._app}app(){return this._protocol="http",this._app=p.App(this._appOptions),this}sslApp(){return this._protocol="https",this._app=p.SSLApp(this._appOptions),this}push(t){return this._routes.push(t),this}unshift(t){return this._routes.unshift(t),this}listen(t,o,s=()=>{}){if(typeof o=="number"?(this._port=o,this._host=t):typeof t=="number"?(typeof o=="function"&&(s=o),this._port=t):typeof t=="function"&&(s=t),!this._app)throw new Error("Create app or sslApp first");return this._lookup(this._host,r=>{for(let e of this._routes)switch(e=typeof e=="function"?{handler:e}:e,e=Object.assign({},this._defaultRoute,e),e.method){case"ws":this._app[e.method](e.pattern,e.behavior);break;default:const h=e;this._app[h.method](e.pattern,(n,i)=>{n.redirect=(u,_=307)=>this.constructor._redirect(n,i,u,_),i.cookies=d(i.getHeader("cookie")),Promise.race([this._abortTimeout(n,i),this._createHandler(n,i,h.handler)])})}this._app.listen(r,this._port,e=>{s(e),e?(this._socket=e,this._mode==="development"&&["info"].includes(this._logLevel)&&console.log(`Listening ${this._protocol}://${this._host}:${this._port}`)):["info","warn","error"].includes(this._logLevel)&&console.error(`Error start server on ${this._protocol}://${this._host}:${this._port}`)})}),this}async close(){if(this._socket){for(await p.us_listen_socket_close(this._socket);await new Promise(t=>setTimeout(t,50)),!(await this.socketPort()<0););this._socket=null}return this}async socketPort(){return this._socket?p.us_socket_local_port(this._socket):-1}_createHandler(t,o,s){return new Promise(async r=>{const e=()=>{clearTimeout(this._timeoutId),r()};try{const h=(i,u=307)=>{if(typeof i=="boolean"&&o.setYield(i),i instanceof Error)throw i;typeof i=="string"&&t.redirect(i,u),e()},n=s(t,o,h);n instanceof Promise&&h(await n)}catch(h){["info","warn","error"].includes(this._logLevel)&&console.error(h);const n=this._mode==="development"?h.message:"";t.cork(()=>{t.writeStatus("404 Not Found").end(n)}),e()}})}static _redirect(t,o,s,r=307){let e="307 Temporary Redirect";r===301&&(e="301 Moved Permanently"),t.cork(()=>{t.writeStatus(e).writeHeader("location",s).end()})}_abortTimeout(t,o){return new Promise(s=>{this._timeout&&!o.getHeader("x-no-timeout")&&(this._timeoutId=setTimeout(()=>{try{t.cork(()=>{t.writeStatus("408 Request Timeout").end(),s()})}catch{}},this._timeout))})}_lookup(t,o){l.lookup(this._host,(s,r)=>{s?["info","warn","error"].includes(this._logLevel)&&console.log(`${this._host} error: ${s.message}`):o(Buffer.from(r))})}}export{f as Server,m as codeToStatus};
1
+ import dns from 'dns';
2
+ import uws from 'uWebSockets.js';
3
+ import { cookieParse } from './cookieParse.mjs';
4
+
5
+ const status = {
6
+ 100: "100 Continue",
7
+ 101: "101 Switching Protocols",
8
+ 200: "200 OK",
9
+ 201: "201 Created",
10
+ 202: "202 Accepted",
11
+ 203: "203 Non-Authoritative Information",
12
+ 204: "No Content",
13
+ 205: "205 Reset Content",
14
+ 206: "206 Partial Content",
15
+ 300: "300 Multiple Choices",
16
+ 301: "301 Moved Permanently",
17
+ 302: "302 Found",
18
+ 303: "303 See Other",
19
+ 304: "304 Not Modified",
20
+ 305: "305 Use Proxy",
21
+ 306: "306 (Unused)",
22
+ 307: "307 Temporary Redirect",
23
+ 400: "400 Bad Request",
24
+ 401: "401 Unauthorized",
25
+ 402: "402 Payment Required",
26
+ 403: "403 Forbidden",
27
+ 404: "404 Not Found",
28
+ 405: "405 Method Not Allowed",
29
+ 406: "406 Not Acceptable",
30
+ 407: "407 Proxy Authentication Required",
31
+ 408: "408 Request Timeout",
32
+ 409: "409 Conflict",
33
+ 410: "410 Gone",
34
+ 411: "411 Length Required",
35
+ 412: "412 Precondition Failed",
36
+ 413: "413 Request Entity Too Large",
37
+ 414: "414 Request-URI Too Long",
38
+ 415: "415 Unsupported Media Type",
39
+ 416: "416 Requested Range Not Satisfiable",
40
+ 417: "417 Expectation Failed",
41
+ 500: "500 Internal Server Error",
42
+ 501: "501 Not Implemented",
43
+ 502: "502 Bad Gateway",
44
+ 503: "503 Service Unavailable",
45
+ 504: "504 Gateway Timeout",
46
+ 505: "505 HTTP Version Not Supported"
47
+ };
48
+ const codeToStatus = (code) => {
49
+ return status.hasOwnProperty(code) ? status[code] : `${code}`;
50
+ };
51
+ class Server {
52
+ /**
53
+ * @constructor
54
+ * @param options
55
+ */
56
+ constructor(options) {
57
+ this._logLevel = "info";
58
+ /**
59
+ * Listen socket
60
+ * @private
61
+ */
62
+ this._socket = null;
63
+ /**
64
+ * Request timeout
65
+ * @private
66
+ */
67
+ this._timeout = 0;
68
+ this._routes = [];
69
+ this._host = "localhost";
70
+ this._port = 3e3;
71
+ this._mode = "production";
72
+ this._appOptions = {};
73
+ /**
74
+ * Default route options
75
+ * @private
76
+ */
77
+ this._defaultRoute = {
78
+ method: "get",
79
+ pattern: "/*",
80
+ handler: (res, req, next) => next()
81
+ };
82
+ this._routes = options.routes || this._routes;
83
+ this._host = options.host || this._host;
84
+ this._port = options.port || this._port;
85
+ this._timeout = options.timeout || this._timeout;
86
+ this._mode = options.mode || this._mode;
87
+ this._appOptions = options.appOptions || this._appOptions;
88
+ this._logLevel = options.logLevel || this._logLevel;
89
+ }
90
+ /**
91
+ * Get TemplatedApp instance
92
+ */
93
+ getApp() {
94
+ return this._app;
95
+ }
96
+ /**
97
+ * Create app (server http)
98
+ * @returns this
99
+ */
100
+ app() {
101
+ this._protocol = "http";
102
+ this._app = uws.App(this._appOptions);
103
+ return this;
104
+ }
105
+ /**
106
+ * Create sslApp
107
+ * @returns this
108
+ */
109
+ sslApp() {
110
+ this._protocol = "https";
111
+ this._app = uws.SSLApp(this._appOptions);
112
+ return this;
113
+ }
114
+ /**
115
+ * Push route
116
+ * @param route
117
+ * @returns this
118
+ */
119
+ push(route) {
120
+ this._routes.push(route);
121
+ return this;
122
+ }
123
+ /**
124
+ * unshift route
125
+ * @param route
126
+ * @returns this
127
+ */
128
+ unshift(route) {
129
+ this._routes.unshift(route);
130
+ return this;
131
+ }
132
+ listen(host, port, fn = () => {
133
+ }) {
134
+ if (typeof port === "number") {
135
+ this._port = port;
136
+ this._host = host;
137
+ } else if (typeof host === "number") {
138
+ if (typeof port === "function") {
139
+ fn = port;
140
+ }
141
+ this._port = host;
142
+ } else if (typeof host === "function") {
143
+ fn = host;
144
+ }
145
+ if (!this._app) {
146
+ throw new Error("Create app or sslApp first");
147
+ }
148
+ this._lookup(this._host, (ip) => {
149
+ for (let route of this._routes) {
150
+ route = typeof route === "function" ? { handler: route } : route;
151
+ route = Object.assign({}, this._defaultRoute, route);
152
+ switch (route.method) {
153
+ case "ws":
154
+ this._app[route.method](route.pattern, route.behavior);
155
+ break;
156
+ default:
157
+ const routeHandler = route;
158
+ this._app[routeHandler.method](
159
+ route.pattern,
160
+ (res, req) => {
161
+ res.redirect = (url, code = 307) => this.constructor._redirect(res, req, url, code);
162
+ req.cookies = cookieParse(req.getHeader("cookie"));
163
+ Promise.race([
164
+ this._abortTimeout(res, req),
165
+ this._createHandler(
166
+ res,
167
+ req,
168
+ routeHandler.handler
169
+ )
170
+ ]);
171
+ }
172
+ );
173
+ }
174
+ }
175
+ this._app.listen(ip, this._port, (listenSocket) => {
176
+ fn(listenSocket);
177
+ if (listenSocket) {
178
+ this._socket = listenSocket;
179
+ if (this._mode === "development") {
180
+ ["info"].includes(this._logLevel) && console.log(
181
+ `Listening ${this._protocol}://${this._host}:${this._port}`
182
+ );
183
+ }
184
+ } else {
185
+ ["info", "warn", "error"].includes(this._logLevel) && console.error(
186
+ `Error start server on ${this._protocol}://${this._host}:${this._port}`
187
+ );
188
+ }
189
+ });
190
+ });
191
+ return this;
192
+ }
193
+ /**
194
+ * Closes a uSockets listen socket.
195
+ */
196
+ async close() {
197
+ if (this._socket) {
198
+ await uws.us_listen_socket_close(this._socket);
199
+ while (true) {
200
+ await new Promise((resolve) => setTimeout(resolve, 50));
201
+ if (await this.socketPort() < 0) {
202
+ break;
203
+ }
204
+ }
205
+ this._socket = null;
206
+ }
207
+ return this;
208
+ }
209
+ /**
210
+ * Return socket port
211
+ */
212
+ async socketPort() {
213
+ if (!this._socket) {
214
+ return -1;
215
+ }
216
+ return uws.us_socket_local_port(this._socket);
217
+ }
218
+ /**
219
+ * Create decoration of handler
220
+ * @param res http response
221
+ * @param req http request
222
+ * @param fn handler
223
+ * @private
224
+ */
225
+ _createHandler(res, req, fn) {
226
+ return new Promise(async (resolve) => {
227
+ const end = () => {
228
+ clearTimeout(this._timeoutId);
229
+ resolve();
230
+ };
231
+ try {
232
+ const next = (param, code = 307) => {
233
+ if (typeof param === "boolean") {
234
+ req.setYield(param);
235
+ }
236
+ if (param instanceof Error) {
237
+ throw param;
238
+ }
239
+ if (typeof param === "string") {
240
+ res.redirect(param, code);
241
+ }
242
+ end();
243
+ };
244
+ const result = fn(res, req, next);
245
+ if (result instanceof Promise) {
246
+ next(await result);
247
+ }
248
+ } catch (e) {
249
+ ["info", "warn", "error"].includes(this._logLevel) && console.error(e);
250
+ const body = this._mode === "development" ? e.message : "";
251
+ res.cork(() => {
252
+ res.writeStatus("404 Not Found").end(body);
253
+ });
254
+ end();
255
+ }
256
+ });
257
+ }
258
+ /**
259
+ * Redirect request
260
+ * @param res
261
+ * @param req
262
+ * @param url string of url
263
+ * @param code redirect status code
264
+ * @private
265
+ */
266
+ static _redirect(res, req, url, code = 307) {
267
+ let status2 = "307 Temporary Redirect";
268
+ if (code === 301) {
269
+ status2 = "301 Moved Permanently";
270
+ }
271
+ res.cork(() => {
272
+ res.writeStatus(status2).writeHeader("location", url).end();
273
+ });
274
+ }
275
+ /**
276
+ * Abort request by timeout
277
+ * @private
278
+ */
279
+ _abortTimeout(res, req) {
280
+ return new Promise((resolve) => {
281
+ if (this._timeout && !req.getHeader("x-no-timeout")) {
282
+ this._timeoutId = setTimeout(() => {
283
+ try {
284
+ res.cork(() => {
285
+ res.writeStatus("408 Request Timeout").end();
286
+ resolve();
287
+ });
288
+ } catch (e) {
289
+ }
290
+ }, this._timeout);
291
+ }
292
+ });
293
+ }
294
+ /**
295
+ * lookup for host
296
+ * @param host
297
+ * @param resolve
298
+ * @private
299
+ */
300
+ _lookup(host, resolve) {
301
+ dns.lookup(this._host, (err, addresses) => {
302
+ if (err) {
303
+ ["info", "warn", "error"].includes(this._logLevel) && console.log(
304
+ `${this._host} error: ${err.message}`
305
+ );
306
+ } else {
307
+ resolve(Buffer.from(addresses));
308
+ }
309
+ });
310
+ }
311
+ }
312
+
313
+ export { Server, codeToStatus };
package/cookieParse.js CHANGED
@@ -1 +1,25 @@
1
- "use strict";const s=c=>c?c.split(/; */).reduce((r,e)=>{if(e==="")return r;const t=e.indexOf("="),o=t>0?e.slice(0,t):e;let n=t>0?e.slice(t+1):null;if(n!=null)try{n=decodeURIComponent(n)}catch{}return r[o]=n,r},{}):{};exports.cookieParse=s;
1
+ 'use strict';
2
+
3
+ const cookieParse = (str) => {
4
+ if (!str) {
5
+ return {};
6
+ }
7
+ return str.split(/; */).reduce((obj, str2) => {
8
+ if (str2 === "") {
9
+ return obj;
10
+ }
11
+ const eq = str2.indexOf("=");
12
+ const key = eq > 0 ? str2.slice(0, eq) : str2;
13
+ let val = eq > 0 ? str2.slice(eq + 1) : null;
14
+ if (val != null) {
15
+ try {
16
+ val = decodeURIComponent(val);
17
+ } catch (ex) {
18
+ }
19
+ }
20
+ obj[key] = val;
21
+ return obj;
22
+ }, {});
23
+ };
24
+
25
+ exports.cookieParse = cookieParse;
package/cookieParse.mjs CHANGED
@@ -1 +1,23 @@
1
- const c=l=>l?l.split(/; */).reduce((r,t)=>{if(t==="")return r;const e=t.indexOf("="),o=e>0?t.slice(0,e):t;let n=e>0?t.slice(e+1):null;if(n!=null)try{n=decodeURIComponent(n)}catch{}return r[o]=n,r},{}):{};export{c as cookieParse};
1
+ const cookieParse = (str) => {
2
+ if (!str) {
3
+ return {};
4
+ }
5
+ return str.split(/; */).reduce((obj, str2) => {
6
+ if (str2 === "") {
7
+ return obj;
8
+ }
9
+ const eq = str2.indexOf("=");
10
+ const key = eq > 0 ? str2.slice(0, eq) : str2;
11
+ let val = eq > 0 ? str2.slice(eq + 1) : null;
12
+ if (val != null) {
13
+ try {
14
+ val = decodeURIComponent(val);
15
+ } catch (ex) {
16
+ }
17
+ }
18
+ obj[key] = val;
19
+ return obj;
20
+ }, {});
21
+ };
22
+
23
+ export { cookieParse };