@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/ApiError.js CHANGED
@@ -1 +1,37 @@
1
- "use strict";class a extends Error{constructor(t="",s=0,r=404){super();let e={};typeof t=="string"?(e.message=t,e.code=s,e.statusCode=r):e=t,this.statusCode=e.statusCode??404,this.code=e.code??0,this.message=e.message??"",this.data=e.data??{},this.headers=e.headers??{}}getMessage(){return this.message}getStatusCode(){return this.statusCode}getCode(){return this.code}getData(){return this.data}getHeaders(){return this.headers}}exports.ApiError=a;
1
+ 'use strict';
2
+
3
+ class ApiError extends Error {
4
+ constructor(params = "", code = 0, statusCode = 404) {
5
+ super();
6
+ let paramsObj = {};
7
+ if (typeof params === "string") {
8
+ paramsObj.message = params;
9
+ paramsObj.code = code;
10
+ paramsObj.statusCode = statusCode;
11
+ } else {
12
+ paramsObj = params;
13
+ }
14
+ this.statusCode = paramsObj.statusCode ?? 404;
15
+ this.code = paramsObj.code ?? 0;
16
+ this.message = paramsObj.message ?? "";
17
+ this.data = paramsObj.data ?? {};
18
+ this.headers = paramsObj.headers ?? {};
19
+ }
20
+ getMessage() {
21
+ return this.message;
22
+ }
23
+ getStatusCode() {
24
+ return this.statusCode;
25
+ }
26
+ getCode() {
27
+ return this.code;
28
+ }
29
+ getData() {
30
+ return this.data;
31
+ }
32
+ getHeaders() {
33
+ return this.headers;
34
+ }
35
+ }
36
+
37
+ exports.ApiError = ApiError;
package/ApiError.mjs CHANGED
@@ -1 +1,35 @@
1
- class a extends Error{constructor(t="",s=0,r=404){super();let e={};typeof t=="string"?(e.message=t,e.code=s,e.statusCode=r):e=t,this.statusCode=e.statusCode??404,this.code=e.code??0,this.message=e.message??"",this.data=e.data??{},this.headers=e.headers??{}}getMessage(){return this.message}getStatusCode(){return this.statusCode}getCode(){return this.code}getData(){return this.data}getHeaders(){return this.headers}}export{a as ApiError};
1
+ class ApiError extends Error {
2
+ constructor(params = "", code = 0, statusCode = 404) {
3
+ super();
4
+ let paramsObj = {};
5
+ if (typeof params === "string") {
6
+ paramsObj.message = params;
7
+ paramsObj.code = code;
8
+ paramsObj.statusCode = statusCode;
9
+ } else {
10
+ paramsObj = params;
11
+ }
12
+ this.statusCode = paramsObj.statusCode ?? 404;
13
+ this.code = paramsObj.code ?? 0;
14
+ this.message = paramsObj.message ?? "";
15
+ this.data = paramsObj.data ?? {};
16
+ this.headers = paramsObj.headers ?? {};
17
+ }
18
+ getMessage() {
19
+ return this.message;
20
+ }
21
+ getStatusCode() {
22
+ return this.statusCode;
23
+ }
24
+ getCode() {
25
+ return this.code;
26
+ }
27
+ getData() {
28
+ return this.data;
29
+ }
30
+ getHeaders() {
31
+ return this.headers;
32
+ }
33
+ }
34
+
35
+ export { ApiError };
@@ -0,0 +1,80 @@
1
+ 'use strict';
2
+
3
+ var crypto = require('crypto');
4
+
5
+ const urlEncode = (str) => {
6
+ return str.replace(/\+/ig, "-").replace(/\//ig, "_").replace(/=+$/, "");
7
+ };
8
+ const urlDecode = (str) => {
9
+ return str.replace(/-/ig, "+").replace(/_/ig, "/");
10
+ };
11
+ const toBase64url = (params) => {
12
+ return urlEncode(
13
+ Buffer.from(JSON.stringify(params)).toString("base64")
14
+ );
15
+ };
16
+ const fromBase64url = (str) => {
17
+ return JSON.parse(
18
+ Buffer.from(
19
+ urlDecode(str),
20
+ "base64"
21
+ ).toString()
22
+ );
23
+ };
24
+
25
+ class Jwt {
26
+ /**
27
+ * @constructor
28
+ * @param secret
29
+ * @param opt addition options
30
+ */
31
+ constructor(secret, opt) {
32
+ this.algorithm = "SHA256";
33
+ this.secret = secret;
34
+ this.algorithm = opt?.algorithm || this.algorithm;
35
+ this.algorithm = this.algorithm.replace("-", "");
36
+ }
37
+ /**
38
+ * Verify jwt token
39
+ * @param jwt token
40
+ * @returns is token valid
41
+ */
42
+ verify(jwt) {
43
+ if (!jwt) {
44
+ return false;
45
+ }
46
+ const parts = jwt.split(".");
47
+ const signature = urlEncode(crypto.createHmac(this.algorithm, this.secret).update(`${parts[0]}.${parts[1]}`).digest("base64"));
48
+ return signature === parts[2];
49
+ }
50
+ /**
51
+ * Get token
52
+ * @param data - user data
53
+ * @returns jwt
54
+ */
55
+ sign(data) {
56
+ const head = toBase64url({
57
+ alg: this.algorithm.replace("SHA", "HS"),
58
+ typ: "JWT"
59
+ });
60
+ const body = toBase64url(data);
61
+ const signature = urlEncode(crypto.createHmac(this.algorithm, this.secret).update(`${head}.${body}`).digest("base64"));
62
+ return `${head}.${body}.${signature}`;
63
+ }
64
+ /**
65
+ * Decode token
66
+ * @param jwt - jwt token
67
+ * @returns {head, body}
68
+ */
69
+ decode(jwt) {
70
+ const parts = (jwt || "").split(".");
71
+ const head = fromBase64url(parts[0]);
72
+ const body = fromBase64url(parts[1]);
73
+ return { head, body };
74
+ }
75
+ }
76
+
77
+ exports.Jwt = Jwt;
78
+ exports.fromBase64url = fromBase64url;
79
+ exports.toBase64url = toBase64url;
80
+ exports.urlEncode = urlEncode;
@@ -0,0 +1,75 @@
1
+ import crypto from 'crypto';
2
+
3
+ const urlEncode = (str) => {
4
+ return str.replace(/\+/ig, "-").replace(/\//ig, "_").replace(/=+$/, "");
5
+ };
6
+ const urlDecode = (str) => {
7
+ return str.replace(/-/ig, "+").replace(/_/ig, "/");
8
+ };
9
+ const toBase64url = (params) => {
10
+ return urlEncode(
11
+ Buffer.from(JSON.stringify(params)).toString("base64")
12
+ );
13
+ };
14
+ const fromBase64url = (str) => {
15
+ return JSON.parse(
16
+ Buffer.from(
17
+ urlDecode(str),
18
+ "base64"
19
+ ).toString()
20
+ );
21
+ };
22
+
23
+ class Jwt {
24
+ /**
25
+ * @constructor
26
+ * @param secret
27
+ * @param opt addition options
28
+ */
29
+ constructor(secret, opt) {
30
+ this.algorithm = "SHA256";
31
+ this.secret = secret;
32
+ this.algorithm = opt?.algorithm || this.algorithm;
33
+ this.algorithm = this.algorithm.replace("-", "");
34
+ }
35
+ /**
36
+ * Verify jwt token
37
+ * @param jwt token
38
+ * @returns is token valid
39
+ */
40
+ verify(jwt) {
41
+ if (!jwt) {
42
+ return false;
43
+ }
44
+ const parts = jwt.split(".");
45
+ const signature = urlEncode(crypto.createHmac(this.algorithm, this.secret).update(`${parts[0]}.${parts[1]}`).digest("base64"));
46
+ return signature === parts[2];
47
+ }
48
+ /**
49
+ * Get token
50
+ * @param data - user data
51
+ * @returns jwt
52
+ */
53
+ sign(data) {
54
+ const head = toBase64url({
55
+ alg: this.algorithm.replace("SHA", "HS"),
56
+ typ: "JWT"
57
+ });
58
+ const body = toBase64url(data);
59
+ const signature = urlEncode(crypto.createHmac(this.algorithm, this.secret).update(`${head}.${body}`).digest("base64"));
60
+ return `${head}.${body}.${signature}`;
61
+ }
62
+ /**
63
+ * Decode token
64
+ * @param jwt - jwt token
65
+ * @returns {head, body}
66
+ */
67
+ decode(jwt) {
68
+ const parts = (jwt || "").split(".");
69
+ const head = fromBase64url(parts[0]);
70
+ const body = fromBase64url(parts[1]);
71
+ return { head, body };
72
+ }
73
+ }
74
+
75
+ export { Jwt as J, fromBase64url as f, toBase64url as t, urlEncode as u };
package/Jwt.js CHANGED
@@ -1 +1,8 @@
1
- "use strict";require("crypto");var r=require("./Jwt-CDdbxwvH.js");exports.Jwt=r.Jwt;
1
+ 'use strict';
2
+
3
+ require('crypto');
4
+ var Jwt = require('./Jwt-B4QZ2Ypb.js');
5
+
6
+
7
+
8
+ exports.Jwt = Jwt.Jwt;
package/Jwt.mjs CHANGED
@@ -1 +1,2 @@
1
- import"crypto";import{J as m}from"./Jwt-7tQL-rwa.js";export{m as Jwt};
1
+ import 'crypto';
2
+ export { J as Jwt } from './Jwt-Be4GWrIO.js';
package/Memcached.js CHANGED
@@ -1,9 +1,166 @@
1
- "use strict";class u{constructor(t,e={"x-cache":"memcached-js"},s=160,r=0){this.prefix="",this.memjs=t,this.specialHeaders=e,this.maxKeyLength=s,this.debug=r,this.prefix=process.env.NODE_ENV!=="production"?"dev::":""}isClient(){return!!this.memjs}isConnectedServers(){if(!this.isClient())return!1;const t=this.memjs?.servers||[];for(const e of t)if(e.connected)return!0;return!1}async setValue(t,e,s){if((s||s===0)&&t.length<=this.maxKeyLength&&this.memjs)try{await this.memjs.set(`${this.prefix}${t}`,Buffer.from(e),{expires:s})}catch(r){this.debug&&console.log(r)}}async getValue(t){if(t.length<=this.maxKeyLength&&this.memjs)try{const e=await this.memjs.get(`${this.prefix}${t}`);return(typeof e=="object"?e?.value:e)||null}catch(e){this.debug&&console.log(e)}return null}async deleteValue(t){if(t.length<=this.maxKeyLength&&this.memjs)try{return this.memjs.delete(`${this.prefix}${t}`)}catch(e){this.debug&&console.log(e)}return!1}async setPage(t,e,s,r){if((r||r===0)&&t.length<=this.maxKeyLength&&this.memjs)try{e=this.objectKeysToLower(e),delete e["set-cookie"];const i=`EXTRACT_HEADERS\r
2
- `+Object.entries(e).map(h=>h.join(":")).join(`\r
3
- `)+`\r
4
- \r
5
- `,n=Buffer.concat([Buffer.from(i),Buffer.from(s)]),c=/^http/.test(t)?t:`${this.prefix}${t}`;await this.memjs.set(c,n,{expires:r})}catch(i){this.debug&&console.log(i)}}async getPage(t){if(t.length<=this.maxKeyLength&&this.memjs)try{let e={};const s=/^http/.test(t)?t:`${this.prefix}${t}`,r=await this.memjs.get(s),i=typeof r=="object"?r?.value:r;if(!i)return null;const n=Buffer.from(i),c=n.indexOf(Buffer.from(`EXTRACT_HEADERS\r
6
- `)),h=n.indexOf(Buffer.from(`\r
7
- \r
8
- `));if(c<0||h<0)return null;const o=n.subarray(c,h).toString().split(`\r
9
- `);o.shift(),o.map(m=>{const[f,l]=m.split(":");e[f]=l}),e=Object.assign(e,this.specialHeaders);const a=n.subarray(h+4);return{headers:e,data:a}}catch(e){this.debug&&console.log(e)}return null}objectKeysToLower(t){return Object.keys(t).reduce((e,s)=>(e[s.toLowerCase()]=t[s],e),{})}}exports.Memcached=u;
1
+ 'use strict';
2
+
3
+ class Memcached {
4
+ /**
5
+ * @constructor
6
+ * @param memjs - memjs Client instance
7
+ * @param specialHeaders - special headers
8
+ * @param maxKeyLength - max key length
9
+ * @param debug
10
+ */
11
+ constructor(memjs, specialHeaders = { "x-cache": "memcached-js" }, maxKeyLength = 160, debug = 0) {
12
+ this.prefix = "";
13
+ this.memjs = memjs;
14
+ this.specialHeaders = specialHeaders;
15
+ this.maxKeyLength = maxKeyLength;
16
+ this.debug = debug;
17
+ this.prefix = process.env.NODE_ENV !== "production" ? "dev::" : "";
18
+ }
19
+ /**
20
+ * Is Client exists
21
+ */
22
+ isClient() {
23
+ return !!this.memjs;
24
+ }
25
+ /**
26
+ * Is in client is one or more conected servers
27
+ */
28
+ isConnectedServers() {
29
+ if (!this.isClient()) {
30
+ return false;
31
+ }
32
+ const servers = this.memjs?.servers || [];
33
+ for (const server of servers) {
34
+ if (server.connected) {
35
+ return true;
36
+ }
37
+ }
38
+ return false;
39
+ }
40
+ /**
41
+ * Set value to memcache
42
+ * @param key string key
43
+ * @param value value
44
+ * @param expires expiers in second
45
+ */
46
+ async setValue(key, value, expires) {
47
+ if ((expires || expires === 0) && key.length <= this.maxKeyLength && this.memjs) {
48
+ try {
49
+ await this.memjs.set(`${this.prefix}${key}`, Buffer.from(value), { expires });
50
+ } catch (e) {
51
+ if (this.debug) {
52
+ console.log(e);
53
+ }
54
+ }
55
+ }
56
+ }
57
+ /**
58
+ * Get value from memory
59
+ * @param key string key
60
+ */
61
+ async getValue(key) {
62
+ if (key.length <= this.maxKeyLength && this.memjs) {
63
+ try {
64
+ const obj = await this.memjs.get(`${this.prefix}${key}`);
65
+ const result = typeof obj === "object" ? obj?.value : obj;
66
+ if (!result) {
67
+ return null;
68
+ }
69
+ return result;
70
+ } catch (e) {
71
+ if (this.debug) {
72
+ console.log(e);
73
+ }
74
+ }
75
+ }
76
+ return null;
77
+ }
78
+ /**
79
+ * Delete value
80
+ * @param key
81
+ */
82
+ async deleteValue(key) {
83
+ if (key.length <= this.maxKeyLength && this.memjs) {
84
+ try {
85
+ return this.memjs.delete(`${this.prefix}${key}`);
86
+ } catch (e) {
87
+ if (this.debug) {
88
+ console.log(e);
89
+ }
90
+ }
91
+ }
92
+ return false;
93
+ }
94
+ /**
95
+ * Set page to cache
96
+ * @param url https://yur.site.net
97
+ * @param headers
98
+ * @param data eny data string or Buffer
99
+ * @param expires
100
+ */
101
+ async setPage(url, headers, data, expires) {
102
+ if ((expires || expires === 0) && url.length <= this.maxKeyLength && this.memjs) {
103
+ try {
104
+ headers = this.objectKeysToLower(headers);
105
+ delete headers["set-cookie"];
106
+ const headersString = Object.entries(headers).map((v) => v.join(":")).join("\r\n");
107
+ const memjsHeaders = "EXTRACT_HEADERS\r\n" + headersString + "\r\n\r\n";
108
+ const toMamcache = Buffer.concat([Buffer.from(memjsHeaders), Buffer.from(data)]);
109
+ const key = /^http/.test(url) ? url : `${this.prefix}${url}`;
110
+ await this.memjs.set(key, toMamcache, { expires });
111
+ } catch (e) {
112
+ if (this.debug) {
113
+ console.log(e);
114
+ }
115
+ }
116
+ }
117
+ }
118
+ /**
119
+ * Get Page and headers
120
+ * @param url https://your.site.net
121
+ * @returns {data, headers}
122
+ */
123
+ async getPage(url) {
124
+ if (url.length <= this.maxKeyLength && this.memjs) {
125
+ try {
126
+ let headers = {};
127
+ const key = /^http/.test(url) ? url : `${this.prefix}${url}`;
128
+ const obj = await this.memjs.get(key);
129
+ const result = typeof obj === "object" ? obj?.value : obj;
130
+ if (!result) {
131
+ return null;
132
+ }
133
+ const memData = Buffer.from(result);
134
+ const start = memData.indexOf(Buffer.from("EXTRACT_HEADERS\r\n"));
135
+ const end = memData.indexOf(Buffer.from("\r\n\r\n"));
136
+ if (start < 0 || end < 0) {
137
+ return null;
138
+ }
139
+ const arr = memData.subarray(start, end).toString().split("\r\n");
140
+ arr.shift();
141
+ arr.map((row) => {
142
+ const [index, value] = row.split(":");
143
+ headers[index] = value;
144
+ });
145
+ headers = Object.assign(headers, this.specialHeaders);
146
+ const data = memData.subarray(end + 4);
147
+ return { headers, data };
148
+ } catch (e) {
149
+ if (this.debug) {
150
+ console.log(e);
151
+ }
152
+ }
153
+ }
154
+ return null;
155
+ }
156
+ /**
157
+ * Keys to lower case in Object
158
+ * @param o
159
+ * @private
160
+ */
161
+ objectKeysToLower(o) {
162
+ return Object.keys(o).reduce((c, k) => (c[k.toLowerCase()] = o[k], c), {});
163
+ }
164
+ }
165
+
166
+ exports.Memcached = Memcached;
package/Memcached.mjs CHANGED
@@ -1,9 +1,164 @@
1
- class u{constructor(t,e={"x-cache":"memcached-js"},s=160,r=0){this.prefix="",this.memjs=t,this.specialHeaders=e,this.maxKeyLength=s,this.debug=r,this.prefix=process.env.NODE_ENV!=="production"?"dev::":""}isClient(){return!!this.memjs}isConnectedServers(){if(!this.isClient())return!1;const t=this.memjs?.servers||[];for(const e of t)if(e.connected)return!0;return!1}async setValue(t,e,s){if((s||s===0)&&t.length<=this.maxKeyLength&&this.memjs)try{await this.memjs.set(`${this.prefix}${t}`,Buffer.from(e),{expires:s})}catch(r){this.debug&&console.log(r)}}async getValue(t){if(t.length<=this.maxKeyLength&&this.memjs)try{const e=await this.memjs.get(`${this.prefix}${t}`);return(typeof e=="object"?e?.value:e)||null}catch(e){this.debug&&console.log(e)}return null}async deleteValue(t){if(t.length<=this.maxKeyLength&&this.memjs)try{return this.memjs.delete(`${this.prefix}${t}`)}catch(e){this.debug&&console.log(e)}return!1}async setPage(t,e,s,r){if((r||r===0)&&t.length<=this.maxKeyLength&&this.memjs)try{e=this.objectKeysToLower(e),delete e["set-cookie"];const i=`EXTRACT_HEADERS\r
2
- `+Object.entries(e).map(h=>h.join(":")).join(`\r
3
- `)+`\r
4
- \r
5
- `,n=Buffer.concat([Buffer.from(i),Buffer.from(s)]),o=/^http/.test(t)?t:`${this.prefix}${t}`;await this.memjs.set(o,n,{expires:r})}catch(i){this.debug&&console.log(i)}}async getPage(t){if(t.length<=this.maxKeyLength&&this.memjs)try{let e={};const s=/^http/.test(t)?t:`${this.prefix}${t}`,r=await this.memjs.get(s),i=typeof r=="object"?r?.value:r;if(!i)return null;const n=Buffer.from(i),o=n.indexOf(Buffer.from(`EXTRACT_HEADERS\r
6
- `)),h=n.indexOf(Buffer.from(`\r
7
- \r
8
- `));if(o<0||h<0)return null;const c=n.subarray(o,h).toString().split(`\r
9
- `);c.shift(),c.map(m=>{const[f,l]=m.split(":");e[f]=l}),e=Object.assign(e,this.specialHeaders);const a=n.subarray(h+4);return{headers:e,data:a}}catch(e){this.debug&&console.log(e)}return null}objectKeysToLower(t){return Object.keys(t).reduce((e,s)=>(e[s.toLowerCase()]=t[s],e),{})}}export{u as Memcached};
1
+ class Memcached {
2
+ /**
3
+ * @constructor
4
+ * @param memjs - memjs Client instance
5
+ * @param specialHeaders - special headers
6
+ * @param maxKeyLength - max key length
7
+ * @param debug
8
+ */
9
+ constructor(memjs, specialHeaders = { "x-cache": "memcached-js" }, maxKeyLength = 160, debug = 0) {
10
+ this.prefix = "";
11
+ this.memjs = memjs;
12
+ this.specialHeaders = specialHeaders;
13
+ this.maxKeyLength = maxKeyLength;
14
+ this.debug = debug;
15
+ this.prefix = process.env.NODE_ENV !== "production" ? "dev::" : "";
16
+ }
17
+ /**
18
+ * Is Client exists
19
+ */
20
+ isClient() {
21
+ return !!this.memjs;
22
+ }
23
+ /**
24
+ * Is in client is one or more conected servers
25
+ */
26
+ isConnectedServers() {
27
+ if (!this.isClient()) {
28
+ return false;
29
+ }
30
+ const servers = this.memjs?.servers || [];
31
+ for (const server of servers) {
32
+ if (server.connected) {
33
+ return true;
34
+ }
35
+ }
36
+ return false;
37
+ }
38
+ /**
39
+ * Set value to memcache
40
+ * @param key string key
41
+ * @param value value
42
+ * @param expires expiers in second
43
+ */
44
+ async setValue(key, value, expires) {
45
+ if ((expires || expires === 0) && key.length <= this.maxKeyLength && this.memjs) {
46
+ try {
47
+ await this.memjs.set(`${this.prefix}${key}`, Buffer.from(value), { expires });
48
+ } catch (e) {
49
+ if (this.debug) {
50
+ console.log(e);
51
+ }
52
+ }
53
+ }
54
+ }
55
+ /**
56
+ * Get value from memory
57
+ * @param key string key
58
+ */
59
+ async getValue(key) {
60
+ if (key.length <= this.maxKeyLength && this.memjs) {
61
+ try {
62
+ const obj = await this.memjs.get(`${this.prefix}${key}`);
63
+ const result = typeof obj === "object" ? obj?.value : obj;
64
+ if (!result) {
65
+ return null;
66
+ }
67
+ return result;
68
+ } catch (e) {
69
+ if (this.debug) {
70
+ console.log(e);
71
+ }
72
+ }
73
+ }
74
+ return null;
75
+ }
76
+ /**
77
+ * Delete value
78
+ * @param key
79
+ */
80
+ async deleteValue(key) {
81
+ if (key.length <= this.maxKeyLength && this.memjs) {
82
+ try {
83
+ return this.memjs.delete(`${this.prefix}${key}`);
84
+ } catch (e) {
85
+ if (this.debug) {
86
+ console.log(e);
87
+ }
88
+ }
89
+ }
90
+ return false;
91
+ }
92
+ /**
93
+ * Set page to cache
94
+ * @param url https://yur.site.net
95
+ * @param headers
96
+ * @param data eny data string or Buffer
97
+ * @param expires
98
+ */
99
+ async setPage(url, headers, data, expires) {
100
+ if ((expires || expires === 0) && url.length <= this.maxKeyLength && this.memjs) {
101
+ try {
102
+ headers = this.objectKeysToLower(headers);
103
+ delete headers["set-cookie"];
104
+ const headersString = Object.entries(headers).map((v) => v.join(":")).join("\r\n");
105
+ const memjsHeaders = "EXTRACT_HEADERS\r\n" + headersString + "\r\n\r\n";
106
+ const toMamcache = Buffer.concat([Buffer.from(memjsHeaders), Buffer.from(data)]);
107
+ const key = /^http/.test(url) ? url : `${this.prefix}${url}`;
108
+ await this.memjs.set(key, toMamcache, { expires });
109
+ } catch (e) {
110
+ if (this.debug) {
111
+ console.log(e);
112
+ }
113
+ }
114
+ }
115
+ }
116
+ /**
117
+ * Get Page and headers
118
+ * @param url https://your.site.net
119
+ * @returns {data, headers}
120
+ */
121
+ async getPage(url) {
122
+ if (url.length <= this.maxKeyLength && this.memjs) {
123
+ try {
124
+ let headers = {};
125
+ const key = /^http/.test(url) ? url : `${this.prefix}${url}`;
126
+ const obj = await this.memjs.get(key);
127
+ const result = typeof obj === "object" ? obj?.value : obj;
128
+ if (!result) {
129
+ return null;
130
+ }
131
+ const memData = Buffer.from(result);
132
+ const start = memData.indexOf(Buffer.from("EXTRACT_HEADERS\r\n"));
133
+ const end = memData.indexOf(Buffer.from("\r\n\r\n"));
134
+ if (start < 0 || end < 0) {
135
+ return null;
136
+ }
137
+ const arr = memData.subarray(start, end).toString().split("\r\n");
138
+ arr.shift();
139
+ arr.map((row) => {
140
+ const [index, value] = row.split(":");
141
+ headers[index] = value;
142
+ });
143
+ headers = Object.assign(headers, this.specialHeaders);
144
+ const data = memData.subarray(end + 4);
145
+ return { headers, data };
146
+ } catch (e) {
147
+ if (this.debug) {
148
+ console.log(e);
149
+ }
150
+ }
151
+ }
152
+ return null;
153
+ }
154
+ /**
155
+ * Keys to lower case in Object
156
+ * @param o
157
+ * @private
158
+ */
159
+ objectKeysToLower(o) {
160
+ return Object.keys(o).reduce((c, k) => (c[k.toLowerCase()] = o[k], c), {});
161
+ }
162
+ }
163
+
164
+ export { Memcached };