@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/index.js CHANGED
@@ -1,4 +1,242 @@
1
- "use strict";var h=require("./ApiError.js"),_=require("./Server.js"),g=require("./Jwt-CDdbxwvH.js"),k=require("crypto"),Q=require("util"),v=require("./Memcached.js"),E=require("./jsonBody.js"),$=require("stream"),H=require("./urlencodedBody.js"),R=require("./multipartBody.js"),U=require("./readConfig.js"),V=require("./readConfigSync.js"),P=require("./cookieParse.js"),W=require("./cookieString.js"),y=require("./staticBody.js"),X=require("fs"),B=require("path"),S=require("easy-ash"),z=require("querystring"),C=require("xml-js"),G=require("os");require("reflect-metadata"),require("dns"),require("uWebSockets.js"),require("formidable");function O(o){var t=Object.create(null);return o&&Object.keys(o).forEach(function(e){if(e!=="default"){var s=Object.getOwnPropertyDescriptor(o,e);Object.defineProperty(t,e,s.get?s:{enumerable:!0,get:function(){return o[e]}})}}),t.default=o,Object.freeze(t)}var M=O(X),Y=O(B),Z=O(G);const{subtle:N}=k.webcrypto;class ee{constructor(t,e){this.algorithm="SHA-256",this.secret=t,this.algorithm=e?.algorithm||this.algorithm,this.algorithm=this.algorithm.replace("-","").replace("SHA","SHA-")}async verify(t){if(!t)return!1;const e=t.split(".");return await this.signString(`${e[0]}.${e[1]}`)===e[2]}async sign(t){const e=g.toBase64url({alg:this.algorithm.replace("-","").replace("SHA","HS"),typ:"JWT"}),s=g.toBase64url(t),i=await this.signString(`${e}.${s}`);return`${e}.${s}.${i}`}decode(t){const e=(t||"").split("."),s=g.fromBase64url(e[0]),i=g.fromBase64url(e[1]);return{head:s,body:i}}async signString(t){const e=new Q.TextEncoder,s=await N.importKey("raw",e.encode(this.secret),{name:"HMAC",hash:{name:this.algorithm}},!1,["sign","verify"]);return g.urlEncode(Buffer.from(await N.sign("HMAC",s,e.encode(t))).toString("base64"))}}const te=o=>{const t=(o||"").split("."),e=g.fromBase64url(t[0]),s=g.fromBase64url(t[1]);return{head:e,body:s}},j=o=>new Promise((t,e)=>{se(o,s=>t(s),()=>{e(new h.ApiError({message:"Can`t parse request",code:1,statusCode:404}))})});function se(o,t,e){let s=Buffer.from([]);o.onData((i,n)=>{s=Buffer.concat([s,Buffer.from(i)]),n&&t(s)}),o.onAborted(e)}const A=(o,t,e=!0)=>{o.onAborted(()=>new h.ApiError({message:"Connection aborted",code:1,statusCode:404}));const s=new $.PassThrough;return s.headers={},t.forEach((i,n)=>s.headers[i]=n),o.onData((i,n)=>{s.write(Buffer.from(Buffer.from(i))),e&&s.resume(),n&&s.end()}),s},oe=(o,t={})=>{for(const e of o){const s=Y.resolve(e);Object.assign(t,JSON.parse(M.readFileSync(s).toString()))}return t};class ie{constructor(t,e,s,i){this.res=t,this.req=e,this.context=s,this.entry=i}async request(t={}){this.res.onAborted(()=>{console.log("Abort is SSR handler")});const e=this.req.getQuery(),s=this.req.getUrl()+(e?`?${e}`:""),i=y.getExt(s);if(y.extensions.includes(i)){await y.staticBody(this.res,this.req,"./dist/client");return}const n={hostname:this.req.getHeader("host"),protocol:this.req.getHeader("x-forwarded-proto")||"http",url:this.req.getUrl(),cookies:P.cookieParse(this.req.getHeader("cookie")),ip:this.req.getHeader("x-forwarded-for")?.split(/,\s+/)?.[0],memcache:null,statusCode:200,headers:{},responseHeaders:{"content-type":"text/html; charset=utf-8"}};this.req.forEach((c,m)=>n.headers[c]=m);const a=`${n.protocol}://${n.hostname}${n.url}`;let r,d=null;this.context.memcached&&(d=await this.context.memcached.getPage(a)),d?(r=d.data.toString(),n.headers=d.headers):({html:r}=await this.entry(s,{manifest:this.context.manifest,res:this.res,req:this.req,context:n}),n.statusCode===200&&this.context.memcached&&await this.context.memcached.setPage(a,n.headers,r,n.memcache)),this.res.writeStatus(_.codeToStatus(n.statusCode)),Object.keys(n.headers).map(c=>this.res.writeHeader(c,n.headers[c])),this.res.end(r)}}const ne=async(o,t,e)=>(await o.poolQuery({sql:`
1
+ 'use strict';
2
+
3
+ var ApiError = require('./ApiError.js');
4
+ var Server = require('./Server.js');
5
+ var Jwt = require('./Jwt-B4QZ2Ypb.js');
6
+ var crypto = require('crypto');
7
+ var util = require('util');
8
+ var Memcached = require('./Memcached.js');
9
+ var jsonBody = require('./jsonBody.js');
10
+ var stream$1 = require('stream');
11
+ var urlencodedBody = require('./urlencodedBody.js');
12
+ var multipartBody = require('./multipartBody.js');
13
+ var readConfig = require('./readConfig.js');
14
+ var readConfigSync = require('./readConfigSync.js');
15
+ var cookieParse = require('./cookieParse.js');
16
+ var cookieString = require('./cookieString.js');
17
+ var staticBody = require('./staticBody.js');
18
+ var fs = require('fs');
19
+ var path = require('path');
20
+ var easyAsh = require('easy-ash');
21
+ var querystring = require('querystring');
22
+ var xmljs = require('xml-js');
23
+ var os = require('os');
24
+ require('reflect-metadata');
25
+ require('dns');
26
+ require('uWebSockets.js');
27
+ require('formidable');
28
+
29
+ function _interopNamespaceDefault(e) {
30
+ var n = Object.create(null);
31
+ if (e) {
32
+ Object.keys(e).forEach(function (k) {
33
+ if (k !== 'default') {
34
+ var d = Object.getOwnPropertyDescriptor(e, k);
35
+ Object.defineProperty(n, k, d.get ? d : {
36
+ enumerable: true,
37
+ get: function () { return e[k]; }
38
+ });
39
+ }
40
+ });
41
+ }
42
+ n.default = e;
43
+ return Object.freeze(n);
44
+ }
45
+
46
+ var fs__namespace = /*#__PURE__*/_interopNamespaceDefault(fs);
47
+ var path__namespace = /*#__PURE__*/_interopNamespaceDefault(path);
48
+ var os__namespace = /*#__PURE__*/_interopNamespaceDefault(os);
49
+
50
+ const { subtle } = crypto.webcrypto;
51
+ class AsyncJwt {
52
+ /**
53
+ * @constructor
54
+ * @param secret
55
+ * @param opt addition options
56
+ */
57
+ constructor(secret, opt) {
58
+ this.algorithm = "SHA-256";
59
+ this.secret = secret;
60
+ this.algorithm = opt?.algorithm || this.algorithm;
61
+ this.algorithm = this.algorithm.replace("-", "").replace("SHA", "SHA-");
62
+ }
63
+ /**
64
+ * Verify jwt token
65
+ * @param jwt token
66
+ * @returns is token valid
67
+ */
68
+ async verify(jwt) {
69
+ if (!jwt) {
70
+ return false;
71
+ }
72
+ const parts = jwt.split(".");
73
+ const signature = await this.signString(`${parts[0]}.${parts[1]}`);
74
+ return signature === parts[2];
75
+ }
76
+ /**
77
+ * Get token
78
+ * @param data - user data
79
+ * @returns jwt
80
+ */
81
+ async sign(data) {
82
+ const head = Jwt.toBase64url({
83
+ alg: this.algorithm.replace("-", "").replace("SHA", "HS"),
84
+ typ: "JWT"
85
+ });
86
+ const body = Jwt.toBase64url(data);
87
+ const signature = await this.signString(`${head}.${body}`);
88
+ return `${head}.${body}.${signature}`;
89
+ }
90
+ /**
91
+ * Decode token
92
+ * @param jwt - jwt token
93
+ * @returns {head, body}
94
+ */
95
+ decode(jwt) {
96
+ const parts = (jwt || "").split(".");
97
+ const head = Jwt.fromBase64url(parts[0]);
98
+ const body = Jwt.fromBase64url(parts[1]);
99
+ return { head, body };
100
+ }
101
+ /**
102
+ * Sign
103
+ * @param str input string
104
+ * @returns base64 sign
105
+ * @private
106
+ */
107
+ async signString(str) {
108
+ const enc = new util.TextEncoder();
109
+ const key = await subtle.importKey(
110
+ "raw",
111
+ enc.encode(this.secret),
112
+ {
113
+ name: "HMAC",
114
+ hash: {
115
+ name: this.algorithm
116
+ }
117
+ },
118
+ false,
119
+ ["sign", "verify"]
120
+ );
121
+ return Jwt.urlEncode(Buffer.from(await subtle.sign(
122
+ "HMAC",
123
+ key,
124
+ enc.encode(str)
125
+ )).toString("base64"));
126
+ }
127
+ }
128
+
129
+ const jwtDecode = (jwt) => {
130
+ const parts = (jwt || "").split(".");
131
+ const head = Jwt.fromBase64url(parts[0]);
132
+ const body = Jwt.fromBase64url(parts[1]);
133
+ return { head, body };
134
+ };
135
+
136
+ const rawBody = (res) => new Promise((resolve, reject) => {
137
+ readRaw(res, (obj) => resolve(obj), () => {
138
+ reject(new ApiError.ApiError({ message: "Can`t parse request", code: 1, statusCode: 404 }));
139
+ });
140
+ });
141
+ function readRaw(res, cb, err) {
142
+ let buffer = Buffer.from([]);
143
+ res.onData((ab, isLast) => {
144
+ buffer = Buffer.concat([buffer, Buffer.from(ab)]);
145
+ isLast && cb(buffer);
146
+ });
147
+ res.onAborted(err);
148
+ }
149
+
150
+ const streamBody = (res, req, resume = true) => {
151
+ res.onAborted(() => new ApiError.ApiError({ message: "Connection aborted", code: 1, statusCode: 404 }));
152
+ const stream = new stream$1.PassThrough();
153
+ stream.headers = {};
154
+ req.forEach((key, val) => stream.headers[key] = val);
155
+ res.onData((chunk, isLast) => {
156
+ stream.write(Buffer.from(Buffer.from(chunk)));
157
+ resume && stream.resume();
158
+ isLast && stream.end();
159
+ });
160
+ return stream;
161
+ };
162
+
163
+ const readJsonConfigsSync = (configs, input = {}) => {
164
+ for (const config of configs) {
165
+ const filePath = path__namespace.resolve(config);
166
+ Object.assign(input, JSON.parse(fs__namespace.readFileSync(filePath).toString()));
167
+ }
168
+ return input;
169
+ };
170
+
171
+ class Ssr {
172
+ /**
173
+ * @constructor
174
+ * @param res response
175
+ * @param req request
176
+ * @param context params
177
+ * @param entry - entry point function
178
+ */
179
+ constructor(res, req, context, entry) {
180
+ this.res = res;
181
+ this.req = req;
182
+ this.context = context;
183
+ this.entry = entry;
184
+ }
185
+ /**
186
+ * @param request addition request params
187
+ */
188
+ async request(request = {}) {
189
+ this.res.onAborted(() => {
190
+ console.log("Abort is SSR handler");
191
+ });
192
+ const query = this.req.getQuery();
193
+ const url = this.req.getUrl() + (query ? `?${query}` : "");
194
+ const extension = staticBody.getExt(url);
195
+ if (staticBody.extensions.includes(extension)) {
196
+ await staticBody.staticBody(this.res, this.req, "./dist/client");
197
+ return;
198
+ }
199
+ const contextSsr = {
200
+ hostname: this.req.getHeader("host"),
201
+ protocol: this.req.getHeader("x-forwarded-proto") || "http",
202
+ url: this.req.getUrl(),
203
+ cookies: cookieParse.cookieParse(this.req.getHeader("cookie")),
204
+ ip: this.req.getHeader("x-forwarded-for")?.split(/,\s+/)?.[0],
205
+ memcache: null,
206
+ statusCode: 200,
207
+ headers: {},
208
+ responseHeaders: {
209
+ "content-type": "text/html; charset=utf-8"
210
+ }
211
+ };
212
+ this.req.forEach((key2, value) => contextSsr.headers[key2] = value);
213
+ const key = `${contextSsr.protocol}://${contextSsr.hostname}${contextSsr.url}`;
214
+ let html, page = null;
215
+ if (this.context.memcached) {
216
+ page = await this.context.memcached.getPage(key);
217
+ }
218
+ if (page) {
219
+ html = page.data.toString();
220
+ contextSsr.headers = page.headers;
221
+ } else {
222
+ ({ html } = await this.entry(url, {
223
+ manifest: this.context.manifest,
224
+ res: this.res,
225
+ req: this.req,
226
+ context: contextSsr
227
+ }));
228
+ if (contextSsr.statusCode === 200 && this.context.memcached) {
229
+ await this.context.memcached.setPage(key, contextSsr.headers, html, contextSsr.memcache);
230
+ }
231
+ }
232
+ this.res.writeStatus(Server.codeToStatus(contextSsr.statusCode));
233
+ Object.keys(contextSsr.headers).map((key2) => this.res.writeHeader(key2, contextSsr.headers[key2]));
234
+ this.res.end(html);
235
+ }
236
+ }
237
+
238
+ const selectRouteController = async (db, name, subaction) => {
239
+ return (await db.poolQuery({ sql: `
2
240
  SELECT c.id AS controller_id,
3
241
  c.name AS controller_name,
4
242
  c.is_active AS controller_is_active,
@@ -17,7 +255,10 @@
17
255
  INNER JOIN app_subactions s ON s.app_controllers_id = c.id
18
256
  LEFT JOIN app_actions a ON a.id = s.app_actions_id
19
257
  WHERE c.name = :name AND s.name = :subaction
20
- `,namedPlaceholders:!0},{name:t,subaction:e}))?.[0],re=async o=>(await o.poolQuery(`
258
+ `, namedPlaceholders: true }, { name, subaction }))?.[0];
259
+ };
260
+ const selectAll = async (db) => {
261
+ const rows = await db.poolQuery(`
21
262
  SELECT c.id AS controller_id,
22
263
  c.name AS controller_name,
23
264
  c.is_active AS controller_is_active,
@@ -35,7 +276,113 @@
35
276
  FROM app_controllers c
36
277
  INNER JOIN app_subactions s ON s.app_controllers_id = c.id
37
278
  LEFT JOIN app_actions a ON a.id = s.app_actions_id;
38
- `)).reduce((t,e)=>(t[`${e.controller_name}::${e.subaction_name}`]=e,t),{}),ae=async(o,t,e,s,i="",n=3600)=>{const a=`${i}::routes::controllers`,r=`${t}::${e}`,d=await s.getValue(a);if(d){const c=JSON.parse(d.toString());return(c||{}).hasOwnProperty(r)?c[r]:void 0}else{const c=await re(o);return await s.setValue(a,Buffer.from(JSON.stringify(c)),n),(c||{}).hasOwnProperty(r)?c[r]:void 0}},D=async(o,t,e,s,i,n="",a=3600)=>{let r;if(i&&i.isClient()&&i.isConnectedServers()?r=await ae(o,e,s,i,n,a):r=await ne(o,e,s),!r)throw new h.ApiError({statusCode:404,code:11,message:`Controller ${e} not found in site schema`});const d=(r?.action_method||"").split(",").map(c=>c.trim());if(r.controller_is_active!==1)throw new h.ApiError({statusCode:404,code:11,message:`Controller ${e} not active in site schema`});if(!r.action_id)throw new h.ApiError({statusCode:404,code:11,message:"Action not found in site schema"});if(r.action_is_active!==1)throw new h.ApiError({statusCode:404,code:11,message:`Action ${r.action_name} not active in site schema`});if(!r.subaction_id)throw new h.ApiError({statusCode:404,code:11,message:`Subaction ${s} not found in site schema`});if(r.subaction_is_active!==1)throw new h.ApiError({statusCode:404,code:11,message:`Subaction ${s} not active in site schema`});if(r.subaction_is_check_method!==0&&r.action_method!=="any"&&!d.includes(t))throw new h.ApiError({statusCode:404,code:11,message:`Controller ${e} action ${r.action_name} allow only ${r.action_method} method`});return{controller:{id:+r.controller_id,name:r.controller_name,isActive:!!r.controller_is_active,isSitemap:!!r.controller_is_sitemap},action:{id:+r.action_id,name:r.action_name,isActive:!!r.action_is_active,method:r.action_method},subaction:{id:+r.subaction_id,name:r.subaction_name,isPermission:!!r.subaction_is_permission,isCheckMethod:!!r.subaction_is_check_method,isLog:!!r.subaction_is_log,isActive:!!r.subaction_is_active,isSync:!1}}},ce=async o=>{const t={},e={};return(await o.poolQuery(`
279
+ `);
280
+ return rows.reduce((ac, row) => {
281
+ ac[`${row.controller_name}::${row.subaction_name}`] = row;
282
+ return ac;
283
+ }, {});
284
+ };
285
+ const selectRouteControllerMemcached = async (db, name, subaction, memcached, memcachedPrefix = "", expires = 3600) => {
286
+ const key = `${memcachedPrefix}::routes::controllers`;
287
+ const index = `${name}::${subaction}`;
288
+ const schema = await memcached.getValue(key);
289
+ if (schema) {
290
+ const json = JSON.parse(schema.toString());
291
+ return (json || {}).hasOwnProperty(index) ? json[index] : void 0;
292
+ } else {
293
+ const all = await selectAll(db);
294
+ await memcached.setValue(key, Buffer.from(JSON.stringify(all)), expires);
295
+ return (all || {}).hasOwnProperty(index) ? all[index] : void 0;
296
+ }
297
+ };
298
+ const selectControllerParams = async (db, method, name, subaction, memcached, memcachedPrefix = "", expires = 3600) => {
299
+ let row;
300
+ if (memcached && memcached.isClient() && memcached.isConnectedServers()) {
301
+ row = await selectRouteControllerMemcached(db, name, subaction, memcached, memcachedPrefix, expires);
302
+ } else {
303
+ row = await selectRouteController(db, name, subaction);
304
+ }
305
+ if (!row) {
306
+ throw new ApiError.ApiError({
307
+ statusCode: 404,
308
+ code: 11,
309
+ message: `Controller ${name} not found in site schema`
310
+ });
311
+ }
312
+ const allowMethods = (row?.action_method || "").split(",").map((method2) => method2.trim());
313
+ if (row.controller_is_active !== 1) {
314
+ throw new ApiError.ApiError({
315
+ statusCode: 404,
316
+ code: 11,
317
+ message: `Controller ${name} not active in site schema`
318
+ });
319
+ }
320
+ if (!row.action_id) {
321
+ throw new ApiError.ApiError({
322
+ statusCode: 404,
323
+ code: 11,
324
+ message: `Action not found in site schema`
325
+ });
326
+ }
327
+ if (row.action_is_active !== 1) {
328
+ throw new ApiError.ApiError({
329
+ statusCode: 404,
330
+ code: 11,
331
+ message: `Action ${row.action_name} not active in site schema`
332
+ });
333
+ }
334
+ if (!row.subaction_id) {
335
+ throw new ApiError.ApiError({
336
+ statusCode: 404,
337
+ code: 11,
338
+ message: `Subaction ${subaction} not found in site schema`
339
+ });
340
+ }
341
+ if (row.subaction_is_active !== 1) {
342
+ throw new ApiError.ApiError({
343
+ statusCode: 404,
344
+ code: 11,
345
+ message: `Subaction ${subaction} not active in site schema`
346
+ });
347
+ }
348
+ if (row.subaction_is_check_method !== 0) {
349
+ if (row.action_method !== "any" && !allowMethods.includes(method)) {
350
+ throw new ApiError.ApiError({
351
+ statusCode: 404,
352
+ code: 11,
353
+ message: `Controller ${name} action ${row.action_name} allow only ${row.action_method} method`
354
+ });
355
+ }
356
+ }
357
+ return {
358
+ controller: {
359
+ id: +row.controller_id,
360
+ name: row.controller_name,
361
+ isActive: !!row.controller_is_active,
362
+ isSitemap: !!row.controller_is_sitemap
363
+ },
364
+ action: {
365
+ id: +row.action_id,
366
+ name: row.action_name,
367
+ isActive: !!row.action_is_active,
368
+ method: row.action_method
369
+ },
370
+ subaction: {
371
+ id: +row.subaction_id,
372
+ name: row.subaction_name,
373
+ isPermission: !!row.subaction_is_permission,
374
+ isCheckMethod: !!row.subaction_is_check_method,
375
+ isLog: !!row.subaction_is_log,
376
+ isActive: !!row.subaction_is_active,
377
+ isSync: false
378
+ }
379
+ };
380
+ };
381
+
382
+ const selectControllersSchema = async (pool) => {
383
+ const actions = {};
384
+ const controllers = {};
385
+ const rows = await pool.poolQuery(`
39
386
  SELECT c.id AS controller_id,
40
387
  c.name AS controller_name,
41
388
  c.is_active AS controller_is_active,
@@ -54,4 +401,1126 @@
54
401
  FROM app_controllers c
55
402
  INNER JOIN app_subactions s ON s.app_controllers_id = c.id
56
403
  LEFT JOIN app_actions a ON a.id = s.app_actions_id;
57
- `)).forEach(s=>{t[s.action_name]={id:s.action_id,name:s.action_name,isActive:!!s.action_is_active,method:s.action_method},e[s.controller_name]=e[s.controller_name]||{id:s.controller_id,name:s.controller_name,isActive:!!s.controller_is_active,isSitemap:!!s.controller_is_sitemap,subactions:[]},e[s.controller_name].subactions.push({id:s.subaction_id,action:s.action_name,name:s.subaction_name,isPermission:!!s.subaction_is_permission,isCheckMethod:!!s.subaction_is_check_method,isLog:!!s.subaction_is_log,isActive:!!s.subaction_is_active,isSync:!!s.subaction_is_sync})}),{controllers:Object.values(e),actions:Object.values(t)}},J=(o,t,e,s)=>{let i=o.controllers.find(d=>d.name===e);if(!i)throw new h.ApiError({statusCode:404,code:11,message:`Controller ${e} not found is site schema`});if(i=Object.assign({isActive:!0,isSitemap:!1},i),!i.isActive)throw new h.ApiError({statusCode:404,code:11,message:`Controller ${e} not active is site schema`});let n=i.subactions.find(d=>d.name===s);if(!n)throw new h.ApiError({statusCode:404,code:11,message:`Subaction ${s} not found is site schema`});if(n=Object.assign({isPermission:!1,isCheckMethod:!1,isLog:!1,isActive:!0},n),!n.isActive)throw new h.ApiError({statusCode:404,code:11,message:`Subaction ${s} not active is site schema`});let a=o.actions.find(d=>d.name===n.action);if(!a)throw new h.ApiError({statusCode:404,code:11,message:"Action not found is site schema"});if(a=Object.assign({isActive:!0,method:"any"},a),!a.isActive)throw new h.ApiError({statusCode:404,code:11,message:`Action ${a.name} not active is site schema`});const r=(a?.method||"").split(",").map(d=>d.trim());if(n.isCheckMethod&&a.method!=="any"&&!r.includes(t))throw new h.ApiError({statusCode:404,code:11,message:`Controller ${e} action ${a.name} allow only ${a.method} method`});return{controller:{id:i.id,name:i.name,isActive:i.isActive,isSitemap:i.isSitemap},subaction:{id:n.id,name:n.name,isPermission:n.isPermission,isCheckMethod:n.isCheckMethod,isLog:n.isLog,isActive:n.isActive,isSync:!!n.isSync},action:{id:a.id,name:a.name,isActive:a.isActive,method:a.method}}};class he{constructor(t,e,s){this.defaultRequest={lang:"ru"},this.defaultResponse={statusCode:200,headers:{"content-type":"application/json"},body:{}},this.defaultControllerSubaction={controller:"Index",subaction:"index"},this.res=t,this.req=e,this.res.onAborted(()=>new h.ApiError({message:"The connection was close",code:1,statusCode:404})),this.context=s}setDefaultRequest(t){return Object.assign(this.defaultRequest,t),this}async request(t={}){let e={};try{const s=this.req.getQuery(),i=Object.assign({},this.defaultRequest,t,z.parse(this.req.getQuery()));this.contextWeb={config:this.context.config,db:this.context.db,method:this.req.getMethod(),cookies:this.req.cookies,hostname:this.req.getHeader("host"),protocol:this.req.getHeader("x-forwarded-proto")||"http",url:this.req.getUrl()+(s?`?${s}`:""),headers:{},stack:this.context.stack||{},getRequest:()=>i},this.memcachedKey=`${this.contextWeb.protocol}://${this.contextWeb.hostname}${this.contextWeb.url}`,this.req.forEach((c,m)=>this.contextWeb.headers[c]=m);const n=this.contextWeb.headers["content-type"]||"application/json";if(i.controller&&i.subaction&&this.context.schema&&(this.route=this.findRoute(i.controller),Object.defineProperty(this.contextWeb,"$route",{enumerable:!1,configurable:!1,writable:!1,value:this.route}),Object.assign(this.contextWeb,J(this.context.schema,this.contextWeb.method,this.route.name,i.subaction)),this.contextWeb.subaction.isSync)){["get","head"].includes(this.contextWeb.method)||Object.defineProperty(this.contextWeb,"$stream",{enumerable:!1,configurable:!1,writable:!1,value:A(this.res,this.req,!1)});const c=this.importControllerSync(i.controller),m=new c;if(this.injectContext(m),i.subaction in m)e=await m[i.subaction]();else throw new h.ApiError({statusCode:404,code:13,message:`Method ${i.subaction} not found in ${i.controller} route`});e=Object.assign({},this.defaultResponse,e),this.success(e);return}if(["get","head"].includes(this.contextWeb.method)&&this.contextWeb?.stack?.memcached instanceof v.Memcached){const c=this.contextWeb.stack.memcached;if(c.isConnectedServers()){const m=await c.getPage(this.memcachedKey);if(m){const{data:b,headers:x}=m;this.success({body:b.toString(),headers:x,statusCode:200})}}}if(i.controller=i.controller||this.defaultControllerSubaction.controller,i.subaction=i.subaction||this.defaultControllerSubaction.subaction,!["get","head"].includes(this.contextWeb.method))if(n.indexOf("application/json")!==-1||n.indexOf("text/json")!==-1)Object.assign(i,await E.jsonBody(this.res));else if(n.indexOf("multipart/form-data")!==-1)Object.assign(i,await R.multipartBody(this.res,this.req)),Object.defineProperty(this.contextWeb,"$files",{enumerable:!1,configurable:!1,writable:!1,value:i.files});else if(n.indexOf("application/x-www-form-urlencoded")!==-1)Object.assign(i,await H.urlencodedBody(this.res));else if(n.indexOf("application/xml")!==-1||n.indexOf("text/xml")!==-1){const c=(await j(this.res)).toString(),m=C.xml2js(c,{compact:!0,cdataKey:"_value",textKey:"_value"});Object.assign(i,m||{})}else n.indexOf("stream")!==-1?Object.defineProperty(this.contextWeb,"$stream",{enumerable:!1,configurable:!1,writable:!1,value:A(this.res,this.req,!1)}):n.indexOf("binary")!==-1?await new Promise(c=>{const m=A(this.res,this.req),b=Z.tmpdir(),x="./body_"+k.randomBytes(32).toString("hex"),u=B.resolve(b,x),p=M.createWriteStream(u);m.pipe(p),Object.defineProperty(this.contextWeb,"$files",{enumerable:!1,configurable:!1,writable:!1,value:{body:{path:u}}}),m.on("end",()=>c(!0))}):Object.defineProperty(this.contextWeb,"$body",{enumerable:!1,configurable:!1,writable:!1,value:await j(this.res)});this.route=this.findRoute(i.controller),Object.assign(this.contextWeb,this.context.schema?J(this.context.schema,this.contextWeb.method,this.route.name,i.subaction):await D(this.contextWeb.db.home,this.contextWeb.method,this.route.name,i.subaction,this.context.stack?.memcached,this.context.stack?.memcachedPrefix,this.context.stack?.memcachedExpiry)),Object.defineProperty(this.contextWeb,"$route",{enumerable:!1,configurable:!1,writable:!1,value:this.route});const a=await this.importController(i.controller),r=new a;this.injectContext(r);const d=await this.initComponent(r);if(typeof d>"u")if(i.subaction in r)e=await r[i.subaction]();else throw new h.ApiError({statusCode:404,code:13,message:`Method ${i.subaction} not found in ${i.controller} route`});else e=d;e=Object.assign({},this.defaultResponse,e),this.success(e)}catch(s){this.error(s)}}async importController(t){let e=this.route.component.default||this.route.component;if(S.isClass(e)||(e=(await this.route.component()).default),typeof e!="function")throw new h.ApiError({statusCode:404,code:12,message:`Class not found for ${t} route`});return e}importControllerSync(t){const e=this.route.component.default||this.route.component;if(typeof e!="function")throw new h.ApiError({statusCode:404,code:12,message:`Class not found for ${t} route`});return e}findRoute(t){const e=this.context.routes.filter(s=>s.name===t&&(s.method===this.contextWeb.method||s.method==="any"||Array.isArray(s.method)&&s.method.includes(this.contextWeb.method)||typeof s.method>"u"))?.[0];if(!e)throw new h.ApiError({statusCode:404,code:11,message:`Route ${t} not found`});return e}injectContext(t){"$inject"in t&&t.$inject(this.contextWeb)}async initComponent(t){const e=[...new Set(["init",...t.$inits||[]])];for(const s of e)if(t[s]){const i=await t[s]();if(i)return i}}success(t){const e=t.body instanceof $.Stream,s=t.body instanceof Uint8Array,i=t.statusCode||200,n=_.codeToStatus(i),a=!s&&!e&&S.isObject(t.body)?JSON.stringify(t.body):t.body;!e&&["get","head"].includes(this.contextWeb.method)&&i===200&&t.memcache&&this.contextWeb?.stack?.memcached instanceof v.Memcached&&this.contextWeb.stack.memcached.setPage(this.memcachedKey,t.headers,a,t.memcache).then(),e?this.res.cork(()=>{this.res.writeStatus(n),this.writeHeaders(t.headers),a.on("data",r=>{this.res.write(r)}).on("end",()=>{this.res.end()})}):this.res.cork(()=>{this.res.writeStatus(n),this.writeHeaders(t.headers),this.res.end(a)})}error(t){const e=t instanceof h.ApiError&&t.getData()instanceof $.Stream;let s=_.codeToStatus(404),i=this.defaultResponse.headers,n=t.message;if(t instanceof h.ApiError){const a={isError:!0,code:t.getCode(),error:t.getMessage()};s=_.codeToStatus(t.getStatusCode()),i=t.getHeaders()||this.defaultResponse.headers,e?n=t.getData():n=S.isObject(t.getData())&&Object.keys(t.getData()).length>0?JSON.stringify(t.getData()):JSON.stringify(a)}e?this.res.cork(()=>{this.res.writeStatus(s),this.writeHeaders(i),n.on("data",a=>{this.res.write(a)}).on("end",()=>{this.res.end()})}):this.res.cork(()=>{this.res.writeStatus(s),this.writeHeaders(i),this.res.end(n)})}writeHeaders(t){Object.entries(t).forEach(([e,s])=>{Array.isArray(s)?s.forEach(i=>this.res.writeHeader(e,i)):this.res.writeHeader(e,s)})}}const de=async(o,t,e={})=>{const s=async a=>{let r;return"init"in a&&(r=await a.init()),r},i=(a,r)=>{"$inject"in a&&a.$inject(r)};t=Object.assign({config:{},getRequest:()=>e,method:"get",...e.controller&&e.subaction&&t.db?.home?await D(t.db.home,t.method||"get",e.controller,e.subaction):{},cookies:{},hostname:t.config?.server?.development?.host,protocol:"http",headers:{}},t);const n=new o;if(i(n,t),await s(n))throw new h.ApiError({statusCode:404,code:13,message:"init method response value"});return n},T={compact:!0,ignoreComment:!0,spaces:4};class ue{constructor(){this.responseHeaders={}}setCookieHeader(t,e,s={}){return W.cookieString(t,e,s)}success(t={},e){return{headers:Object.assign({"content-type":"application/json"},this.responseHeaders,e?.headers||{}),body:{isError:!1,data:t},memcache:e?.memcache||null,statusCode:e?.statusCode||200}}error(t){const e=t,s=e.code?e.code:0,i=e.message?e.message:"Api request error",n=e.statusCode?e.statusCode:404,a=e.data?e.data:{},r=e.response?{status:e.response.status,headers:e.response.headers,config:{url:e.response.url,method:e.response.method,params:e.response.params,headers:e.response.headers},data:e.response.data}:{};return{headers:Object.assign({"content-type":"application/json"},e.headers),body:{isError:!0,error:i,code:s,data:a,stack:process.env.NODE_ENV!=="production"?e.stack:"",response:process.env.NODE_ENV!=="production"?r:{}},statusCode:n}}successXml(t={},e){const s={_declaration:{_attributes:{version:"1.0",encoding:"utf-8"}}},i=this.success(t,e);return{headers:Object.assign({"content-type":"application/xml"},this.responseHeaders,e?.headers||{}),body:C.js2xml(Object.assign(s,{body:{...i.body}}),T),memcache:i.memcache}}errorXml(t){const e=t,s={_declaration:{_attributes:{version:"1.0",encoding:"utf-8"}}},i=this.error(e);return{headers:Object.assign({"content-type":"application/xml"},e.headers),body:C.js2xml(Object.assign(s,{body:{...i.body}}),T),statusCode:i.statusCode}}async $create(t,...e){const s=new t(...e);"$inject"in s&&s.$inject({method:this.$context.method,getRequest:this.$context.getRequest,config:this.$context.config,db:this.$context.db,stack:this.$context.stack,headers:this.$context.headers,cookies:this.$context.cookies,controller:this.$context.controller,action:this.$context.action,subaction:this.$context.subaction,setResponseHeader:(n,a)=>this.setResponseHeader(n,a),setCookieHeader:this.setCookieHeader});const i=["init",...s.$inits||[]];for(const n of i)s[n]&&await s[n]();return s}async $createAll(t){return Promise.all(t.map(e=>this.$create(...e)))}$inject(t){this.$context=t}getContext(){return this.$context}getRequest(){return this.$context.getRequest()}getBody(){return this.$context.$body||Buffer.from("")}getFiles(){return this.$context.$files||{}}getStream(){return this.$context.$stream||new $.PassThrough().end()}getConfig(){return this.$context.config}getMethod(){return this.$context.method}getCookies(){return this.$context.cookies}getHostname(){return this.$context.hostname}getUrl(){return this.$context.url}getProtocol(){return this.$context.protocol}getDb(){return this.$context.db}getHeaders(){return this.$context.headers}getController(){return this.$context.controller}getAction(){return this.$context.action}getSubaction(){return this.$context.subaction}getHome(){return this.getDb().home}getPool(t="home"){return this.getDb()[t]}getStack(){return this.$context.stack}setResponseHeader(t,e){this.responseHeaders.hasOwnProperty(t)?(this.responseHeaders[t]=Array.isArray(this.responseHeaders[t])?this.responseHeaders[t]:[this.responseHeaders[t]],this.responseHeaders[t].push(e)):this.responseHeaders[t]=e}}class le{async $create(t,...e){const s=new t(...e);return"$inject"in s&&s.$inject({method:this.$context.method,getRequest:this.$context.getRequest,config:this.$context.config,db:this.$context.db,stack:this.$context.stack,headers:this.$context.headers,cookies:this.$context.cookies,controller:this.$context.controller,action:this.$context.action,subaction:this.$context.subaction,setResponseHeader:this.$context.setResponseHeader,setCookieHeader:this.$context.setCookieHeader}),"init"in s&&await s.init(),s}async $createAll(t){return Promise.all(t.map(e=>this.$create(...e)))}$inject(t){this.$context=t}getContext(){return this.$context}getRequest(){return this.$context.getRequest()}getConfig(){return this.$context.config}getMethod(){return this.$context.method}getHeaders(){return this.$context.headers}getCookies(){return this.$context.cookies}getController(){return this.$context.controller}getAction(){return this.$context.action}getSubaction(){return this.$context.subaction}getDb(){return this.$context.db}getHome(){return this.$context.db.home}getPool(t="home"){return this.getDb()[t]}getStack(){return this.$context.stack}setResponseHeader(t,e){return this.$context.setResponseHeader(t,e)}setCookieHeader(t,e,s={}){return this.$context.setCookieHeader(t,e,s)}}const f=Symbol("arguments"),I=Symbol("connections"),q=Symbol("response"),L=Symbol("init"),F=Symbol("logger"),me=o=>o.charAt(0).toUpperCase()+o.slice(1);function fe(o,t={}){const e=Reflect.ownKeys(o),s=Reflect.ownKeys(t),i=Symbol("isa");function n(a){for(const r of e)Object.defineProperty(a.prototype,r,{value:o[r]});return Object.defineProperty(a.prototype,i,{value:!0}),a}for(const a of s)Object.defineProperty(n,a,{value:t[a],enumerable:t.propertyIsEnumerable(a)});return Object.defineProperty(n,Symbol.hasInstance,{value:a=>!!a[i]}),n}const l=(o,t,e,s,i,n)=>{const a=Reflect.getOwnMetadata(o,t,e)||{};a[s]={type:i,params:n},Reflect.defineMetadata(o,a,t,e)};function pe(){return function(o,t,e){l(f,o,t,e,"request")}}function be(){return function(o,t,e){l(f,o,t,e,"context")}}function ge(){return function(o,t,e){l(f,o,t,e,"config")}}function _e(){return function(o,t,e){l(f,o,t,e,"method")}}function ye(){return function(o,t,e){l(f,o,t,e,"cookies")}}function xe(){return function(o,t,e){l(f,o,t,e,"hostname")}}function we(){return function(o,t,e){l(f,o,t,e,"url")}}function $e(){return function(o,t,e){l(f,o,t,e,"protocol")}}function Se(){return function(o,t,e){l(f,o,t,e,"db")}}function Ae(){return function(o,t,e){l(f,o,t,e,"headers")}}function ve(){return function(o,t,e){l(f,o,t,e,"controller")}}function Ce(){return function(o,t,e){l(f,o,t,e,"action")}}function Oe(){return function(o,t,e){l(f,o,t,e,"subaction")}}function je(){return function(o,t,e){l(f,o,t,e,"body")}}function qe(){return function(o,t,e){l(f,o,t,e,"stream")}}function ke(){return function(o,t,e){l(f,o,t,e,"home")}}function Ee(o="home"){return function(t,e,s){l(f,t,e,s,"pool",o)}}function He(o="home"){return function(t,e,s){l(I,t,e,s,"connection",o)}}function Re(o={}){return function(t,e,s){l(q,t,e,0,"json",o)}}function Pe(o={}){return function(t,e,s){l(q,t,e,0,"xml",o)}}function We(o){return function(t,e,s){l(F,t,e,o,"logger",o)}}function Be(o){return function(t,e,s){const i={format:"json"},n=s.value;s.value=async function(){o&&Object.assign(i,await o.apply(this)||{});const a=[],r=[],d=Reflect.getOwnMetadata(f,t,e)||{},c=Reflect.getOwnMetadata(I,t,e)||{},m=Reflect.getOwnMetadata(F,t,e)||{},b=Reflect.getOwnMetadata(q,t,e)?.[0]||{type:"json",params:{}},x=Reflect.getOwnMetadata(L,t,e)?.[0]||{type:"",params:{}};for(const u in d){if(!d.hasOwnProperty(u))continue;const p=`get${me(d[u].type)}`;a[+u]=this[p](d[u].params)}for(const u in c)c.hasOwnProperty(u)&&(c[u].type,a[+u]=await this.getDb()[c[u].params].getConnection(),r.push(a[+u]));try{let u=await n.apply(this,a),p;if(Array.isArray(u)&&([u,p]=u),x.type!=="init")return i.format==="xml"||b.type==="xml"?this.successXml(u,Object.assign(b.params,p||{})):this.success(u,Object.assign(b.params,p||{}))}catch(u){await Promise.all([...r.map(w=>w.rollback())]);let p;i.format==="xml"||b.type==="xml"?p=this.errorXml(u):p=this.error(u);for(const w in m){if(!m.hasOwnProperty(w))continue;const K=m[w].params;await this[K].error(u,{response:S.omit(p?.body||{},["stack"])})}return p}finally{await Promise.all([...r.map(u=>u.release())])}}}}function Me(){return function(o,t,e){l(L,o,t,0,"init"),e.value,"$inits"in o||Object.defineProperty(o,"$inits",{value:[]}),o.$inits.push(t)}}const Ne={cookieParse:P.cookieParse,cookieString:W.cookieString,jsonBody:E.jsonBody,rawBody:j,streamBody:A,urlencodedBody:H.urlencodedBody,multipartBody:R.multipartBody,readConfig:U.readConfig,readConfigSync:V.readConfigSync,staticBody:y.staticBody,extensions:y.extensions,getExt:y.getExt,jwtDecode:te,readJsonConfigsSync:oe};exports.ApiError=h.ApiError,exports.Server=_.Server,exports.codeToStatus=_.codeToStatus,exports.Jwt=g.Jwt,exports.Memcached=v.Memcached,exports.AsyncJwt=ee,exports.Controller=ue,exports.Model=le,exports.Ssr=ie,exports.Web=he,exports.action=Ce,exports.body=je,exports.config=ge,exports.connection=He,exports.context=be,exports.controller=ve,exports.cookies=ye,exports.db=Se,exports.headers=Ae,exports.helpers=Ne,exports.home=ke,exports.hostname=xe,exports.http=Be,exports.init=Me,exports.json=Re,exports.logerror=We,exports.method=_e,exports.mixin=fe,exports.mount=de,exports.pool=Ee,exports.protocol=$e,exports.request=pe,exports.selectControllersSchema=ce,exports.stream=qe,exports.subaction=Oe,exports.url=we,exports.xml=Pe;
404
+ `);
405
+ rows.forEach((row) => {
406
+ actions[row.action_name] = {
407
+ id: row.action_id,
408
+ name: row.action_name,
409
+ isActive: !!row.action_is_active,
410
+ method: row.action_method
411
+ };
412
+ controllers[row.controller_name] = controllers[row.controller_name] || {
413
+ id: row.controller_id,
414
+ name: row.controller_name,
415
+ isActive: !!row.controller_is_active,
416
+ isSitemap: !!row.controller_is_sitemap,
417
+ subactions: []
418
+ };
419
+ controllers[row.controller_name].subactions.push({
420
+ id: row.subaction_id,
421
+ action: row.action_name,
422
+ name: row.subaction_name,
423
+ isPermission: !!row.subaction_is_permission,
424
+ isCheckMethod: !!row.subaction_is_check_method,
425
+ isLog: !!row.subaction_is_log,
426
+ isActive: !!row.subaction_is_active,
427
+ isSync: !!row.subaction_is_sync
428
+ });
429
+ });
430
+ return {
431
+ controllers: Object.values(controllers),
432
+ actions: Object.values(actions)
433
+ };
434
+ };
435
+ const schemaControllerParams = (schema, method, name, subaction) => {
436
+ let controllerRow = schema.controllers.find((row) => row.name === name);
437
+ if (!controllerRow) {
438
+ throw new ApiError.ApiError({
439
+ statusCode: 404,
440
+ code: 11,
441
+ message: `Controller ${name} not found is site schema`
442
+ });
443
+ }
444
+ controllerRow = Object.assign({
445
+ isActive: true,
446
+ isSitemap: false
447
+ }, controllerRow);
448
+ if (!controllerRow.isActive) {
449
+ throw new ApiError.ApiError({
450
+ statusCode: 404,
451
+ code: 11,
452
+ message: `Controller ${name} not active is site schema`
453
+ });
454
+ }
455
+ let subactionRow = controllerRow.subactions.find((row) => row.name === subaction);
456
+ if (!subactionRow) {
457
+ throw new ApiError.ApiError({
458
+ statusCode: 404,
459
+ code: 11,
460
+ message: `Subaction ${subaction} not found is site schema`
461
+ });
462
+ }
463
+ subactionRow = Object.assign({
464
+ isPermission: false,
465
+ isCheckMethod: false,
466
+ isLog: false,
467
+ isActive: true
468
+ }, subactionRow);
469
+ if (!subactionRow.isActive) {
470
+ throw new ApiError.ApiError({
471
+ statusCode: 404,
472
+ code: 11,
473
+ message: `Subaction ${subaction} not active is site schema`
474
+ });
475
+ }
476
+ let actionRow = schema.actions.find((row) => row.name === subactionRow.action);
477
+ if (!actionRow) {
478
+ throw new ApiError.ApiError({
479
+ statusCode: 404,
480
+ code: 11,
481
+ message: `Action not found is site schema`
482
+ });
483
+ }
484
+ actionRow = Object.assign({
485
+ isActive: true,
486
+ method: "any"
487
+ }, actionRow);
488
+ if (!actionRow.isActive) {
489
+ throw new ApiError.ApiError({
490
+ statusCode: 404,
491
+ code: 11,
492
+ message: `Action ${actionRow.name} not active is site schema`
493
+ });
494
+ }
495
+ const allowMethods = (actionRow?.method || "").split(",").map((method2) => method2.trim());
496
+ if (subactionRow.isCheckMethod) {
497
+ if (actionRow.method !== "any" && !allowMethods.includes(method)) {
498
+ throw new ApiError.ApiError({
499
+ statusCode: 404,
500
+ code: 11,
501
+ message: `Controller ${name} action ${actionRow.name} allow only ${actionRow.method} method`
502
+ });
503
+ }
504
+ }
505
+ return {
506
+ controller: {
507
+ id: controllerRow.id,
508
+ name: controllerRow.name,
509
+ isActive: controllerRow.isActive,
510
+ isSitemap: controllerRow.isSitemap
511
+ },
512
+ subaction: {
513
+ id: subactionRow.id,
514
+ name: subactionRow.name,
515
+ isPermission: subactionRow.isPermission,
516
+ isCheckMethod: subactionRow.isCheckMethod,
517
+ isLog: subactionRow.isLog,
518
+ isActive: subactionRow.isActive,
519
+ isSync: !!subactionRow.isSync
520
+ },
521
+ action: {
522
+ id: actionRow.id,
523
+ name: actionRow.name,
524
+ isActive: actionRow.isActive,
525
+ method: actionRow.method
526
+ }
527
+ };
528
+ };
529
+
530
+ class Web {
531
+ constructor(res, req, context) {
532
+ this.defaultRequest = {
533
+ lang: "ru"
534
+ };
535
+ this.defaultResponse = {
536
+ statusCode: 200,
537
+ headers: { "content-type": "application/json" },
538
+ body: {}
539
+ };
540
+ this.defaultControllerSubaction = {
541
+ controller: "Index",
542
+ subaction: "index"
543
+ };
544
+ this.res = res;
545
+ this.req = req;
546
+ this.res.onAborted(() => new ApiError.ApiError({ message: "The connection was close", code: 1, statusCode: 404 }));
547
+ this.context = context;
548
+ }
549
+ setDefaultRequest(params) {
550
+ Object.assign(this.defaultRequest, params);
551
+ return this;
552
+ }
553
+ async request(input = {}) {
554
+ let response = {};
555
+ try {
556
+ const query = this.req.getQuery();
557
+ const request = Object.assign(
558
+ {},
559
+ this.defaultRequest,
560
+ input,
561
+ querystring.parse(this.req.getQuery())
562
+ );
563
+ this.contextWeb = {
564
+ config: this.context.config,
565
+ db: this.context.db,
566
+ method: this.req.getMethod(),
567
+ cookies: this.req.cookies,
568
+ hostname: this.req.getHeader("host"),
569
+ protocol: this.req.getHeader("x-forwarded-proto") || "http",
570
+ url: this.req.getUrl() + (query ? `?${query}` : ""),
571
+ headers: {},
572
+ stack: this.context.stack || {},
573
+ getRequest: () => request
574
+ };
575
+ this.memcachedKey = `${this.contextWeb.protocol}://${this.contextWeb.hostname}${this.contextWeb.url}`;
576
+ this.req.forEach((key, value) => this.contextWeb.headers[key] = value);
577
+ const type = this.contextWeb.headers["content-type"] || "application/json";
578
+ if (request.controller && request.subaction && this.context.schema) {
579
+ this.route = this.findRoute(request.controller);
580
+ Object.defineProperty(this.contextWeb, "$route", {
581
+ enumerable: false,
582
+ configurable: false,
583
+ writable: false,
584
+ value: this.route
585
+ });
586
+ Object.assign(
587
+ this.contextWeb,
588
+ schemaControllerParams(
589
+ this.context.schema,
590
+ this.contextWeb.method,
591
+ this.route.name,
592
+ // Определяет контроллер
593
+ request.subaction
594
+ )
595
+ );
596
+ if (this.contextWeb.subaction.isSync) {
597
+ if (!["get", "head"].includes(this.contextWeb.method)) {
598
+ Object.defineProperty(this.contextWeb, "$stream", {
599
+ enumerable: false,
600
+ configurable: false,
601
+ writable: false,
602
+ value: streamBody(this.res, this.req, false)
603
+ });
604
+ }
605
+ const controllerClass2 = this.importControllerSync(request.controller);
606
+ const controller2 = new controllerClass2();
607
+ this.injectContext(controller2);
608
+ if (request.subaction in controller2) {
609
+ response = await controller2[request.subaction]();
610
+ } else {
611
+ throw new ApiError.ApiError(
612
+ {
613
+ statusCode: 404,
614
+ code: 13,
615
+ message: `Method ${request.subaction} not found in ${request.controller} route`
616
+ }
617
+ );
618
+ }
619
+ response = Object.assign({}, this.defaultResponse, response);
620
+ this.success(response);
621
+ return;
622
+ }
623
+ }
624
+ if (["get", "head"].includes(this.contextWeb.method) && this.contextWeb?.stack?.memcached instanceof Memcached.Memcached) {
625
+ const memcached = this.contextWeb.stack.memcached;
626
+ if (memcached.isConnectedServers()) {
627
+ const cache = await memcached.getPage(this.memcachedKey);
628
+ if (cache) {
629
+ const { data, headers } = cache;
630
+ this.success({
631
+ body: data.toString(),
632
+ headers,
633
+ statusCode: 200
634
+ });
635
+ }
636
+ }
637
+ }
638
+ request.controller = request.controller || this.defaultControllerSubaction.controller;
639
+ request.subaction = request.subaction || this.defaultControllerSubaction.subaction;
640
+ if (!["get", "head"].includes(this.contextWeb.method)) {
641
+ if (type.indexOf("application/json") !== -1 || type.indexOf("text/json") !== -1) {
642
+ Object.assign(request, await jsonBody.jsonBody(this.res));
643
+ } else if (type.indexOf("multipart/form-data") !== -1) {
644
+ Object.assign(request, await multipartBody.multipartBody(this.res, this.req));
645
+ Object.defineProperty(this.contextWeb, "$files", {
646
+ enumerable: false,
647
+ configurable: false,
648
+ writable: false,
649
+ value: request.files
650
+ });
651
+ } else if (type.indexOf("application/x-www-form-urlencoded") !== -1) {
652
+ Object.assign(request, await urlencodedBody.urlencodedBody(this.res));
653
+ } else if (type.indexOf("application/xml") !== -1 || type.indexOf("text/xml") !== -1) {
654
+ const raw = (await rawBody(this.res)).toString();
655
+ const records = xmljs.xml2js(raw, { compact: true, cdataKey: "_value", textKey: "_value" });
656
+ Object.assign(request, records || {});
657
+ } else if (type.indexOf("stream") !== -1) {
658
+ Object.defineProperty(this.contextWeb, "$stream", {
659
+ enumerable: false,
660
+ configurable: false,
661
+ writable: false,
662
+ value: streamBody(this.res, this.req, false)
663
+ });
664
+ } else if (type.indexOf("binary") !== -1) {
665
+ await new Promise((resolve) => {
666
+ const stream = streamBody(this.res, this.req);
667
+ const temp = os__namespace.tmpdir();
668
+ const name = "./body_" + crypto.randomBytes(32).toString("hex");
669
+ const pathToFile = path.resolve(temp, name);
670
+ const writer = fs__namespace.createWriteStream(pathToFile);
671
+ stream.pipe(writer);
672
+ Object.defineProperty(this.contextWeb, "$files", {
673
+ enumerable: false,
674
+ configurable: false,
675
+ writable: false,
676
+ value: { body: { path: pathToFile } }
677
+ });
678
+ stream.on("end", () => resolve(true));
679
+ });
680
+ } else {
681
+ Object.defineProperty(this.contextWeb, "$body", {
682
+ enumerable: false,
683
+ configurable: false,
684
+ writable: false,
685
+ value: await rawBody(this.res)
686
+ });
687
+ }
688
+ }
689
+ this.route = this.findRoute(request.controller);
690
+ Object.assign(
691
+ this.contextWeb,
692
+ this.context.schema ? schemaControllerParams(
693
+ this.context.schema,
694
+ this.contextWeb.method,
695
+ this.route.name,
696
+ // Определяет контроллер
697
+ request.subaction
698
+ ) : await selectControllerParams(
699
+ this.contextWeb.db.home,
700
+ this.contextWeb.method,
701
+ this.route.name,
702
+ request.subaction,
703
+ this.context.stack?.memcached,
704
+ this.context.stack?.memcachedPrefix,
705
+ this.context.stack?.memcachedExpiry
706
+ )
707
+ );
708
+ Object.defineProperty(this.contextWeb, "$route", {
709
+ enumerable: false,
710
+ configurable: false,
711
+ writable: false,
712
+ value: this.route
713
+ });
714
+ const controllerClass = await this.importController(request.controller);
715
+ const controller = new controllerClass();
716
+ this.injectContext(controller);
717
+ const initResponse = await this.initComponent(controller);
718
+ if (typeof initResponse === "undefined") {
719
+ if (request.subaction in controller) {
720
+ response = await controller[request.subaction]();
721
+ } else {
722
+ throw new ApiError.ApiError(
723
+ {
724
+ statusCode: 404,
725
+ code: 13,
726
+ message: `Method ${request.subaction} not found in ${request.controller} route`
727
+ }
728
+ );
729
+ }
730
+ } else {
731
+ response = initResponse;
732
+ }
733
+ response = Object.assign({}, this.defaultResponse, response);
734
+ this.success(response);
735
+ } catch (e) {
736
+ this.error(e);
737
+ }
738
+ }
739
+ /**
740
+ * Import controller class
741
+ */
742
+ async importController(controllerName) {
743
+ let controllerClass = this.route.component.default || this.route.component;
744
+ if (!easyAsh.isClass(controllerClass)) {
745
+ controllerClass = (await this.route.component()).default;
746
+ }
747
+ if (typeof controllerClass !== "function") {
748
+ throw new ApiError.ApiError(
749
+ {
750
+ statusCode: 404,
751
+ code: 12,
752
+ message: `Class not found for ${controllerName} route`
753
+ }
754
+ );
755
+ }
756
+ return controllerClass;
757
+ }
758
+ /**
759
+ * Sync controller
760
+ */
761
+ importControllerSync(controllerName) {
762
+ const controllerClass = this.route.component.default || this.route.component;
763
+ if (typeof controllerClass !== "function") {
764
+ throw new ApiError.ApiError(
765
+ {
766
+ statusCode: 404,
767
+ code: 12,
768
+ message: `Class not found for ${controllerName} route`
769
+ }
770
+ );
771
+ }
772
+ return controllerClass;
773
+ }
774
+ /**
775
+ * Find route in api routers
776
+ */
777
+ findRoute(controllerName) {
778
+ const route = this.context.routes.filter(
779
+ (v) => v.name === controllerName && (v.method === this.contextWeb.method || v.method === "any" || Array.isArray(v.method) && v.method.includes(this.contextWeb.method) || typeof v.method === "undefined")
780
+ )?.[0];
781
+ if (!route) {
782
+ throw new ApiError.ApiError(
783
+ {
784
+ statusCode: 404,
785
+ code: 11,
786
+ message: `Route ${controllerName} not found`
787
+ }
788
+ );
789
+ }
790
+ return route;
791
+ }
792
+ injectContext(obj) {
793
+ if ("$inject" in obj) {
794
+ obj.$inject(this.contextWeb);
795
+ }
796
+ }
797
+ async initComponent(obj) {
798
+ const inits = [.../* @__PURE__ */ new Set(["init", ...obj.$inits || []])];
799
+ for (const method of inits) {
800
+ if (obj[method]) {
801
+ const out = await obj[method]();
802
+ if (out) {
803
+ return out;
804
+ }
805
+ }
806
+ }
807
+ }
808
+ success(response) {
809
+ const isStream = response.body instanceof stream$1.Stream;
810
+ const isBuffer = response.body instanceof Uint8Array;
811
+ const code = response.statusCode || 200;
812
+ const status = Server.codeToStatus(code);
813
+ const body = !isBuffer && !isStream && easyAsh.isObject(response.body) ? JSON.stringify(response.body) : response.body;
814
+ if (!isStream && ["get", "head"].includes(this.contextWeb.method) && code === 200 && response.memcache && this.contextWeb?.stack?.memcached instanceof Memcached.Memcached) {
815
+ const memcached = this.contextWeb.stack.memcached;
816
+ memcached.setPage(this.memcachedKey, response.headers, body, response.memcache).then();
817
+ }
818
+ if (!isStream) {
819
+ this.res.cork(() => {
820
+ this.res.writeStatus(status);
821
+ this.writeHeaders(response.headers);
822
+ this.res.end(body);
823
+ });
824
+ } else {
825
+ this.res.cork(() => {
826
+ this.res.writeStatus(status);
827
+ this.writeHeaders(response.headers);
828
+ body.on("data", (chunk) => {
829
+ this.res.write(chunk);
830
+ }).on("end", () => {
831
+ this.res.end();
832
+ });
833
+ });
834
+ }
835
+ }
836
+ /**
837
+ * Error response
838
+ */
839
+ error(e) {
840
+ const isStream = e instanceof ApiError.ApiError && e.getData() instanceof stream$1.Stream;
841
+ let status = Server.codeToStatus(404), headers = this.defaultResponse.headers, body = e.message;
842
+ if (e instanceof ApiError.ApiError) {
843
+ const data = { isError: true, code: e.getCode(), error: e.getMessage() };
844
+ status = Server.codeToStatus(e.getStatusCode());
845
+ headers = e.getHeaders() || this.defaultResponse.headers;
846
+ if (isStream) {
847
+ body = e.getData();
848
+ } else {
849
+ body = easyAsh.isObject(e.getData()) && Object.keys(e.getData()).length > 0 ? JSON.stringify(e.getData()) : JSON.stringify(data);
850
+ }
851
+ }
852
+ if (!isStream) {
853
+ this.res.cork(() => {
854
+ this.res.writeStatus(status);
855
+ this.writeHeaders(headers);
856
+ this.res.end(body);
857
+ });
858
+ } else {
859
+ this.res.cork(() => {
860
+ this.res.writeStatus(status);
861
+ this.writeHeaders(headers);
862
+ body.on("data", (chunk) => {
863
+ this.res.write(chunk);
864
+ }).on("end", () => {
865
+ this.res.end();
866
+ });
867
+ });
868
+ }
869
+ }
870
+ writeHeaders(headers) {
871
+ Object.entries(headers).forEach(([key, value]) => {
872
+ if (Array.isArray(value)) {
873
+ value.forEach((v) => this.res.writeHeader(key, v));
874
+ } else {
875
+ this.res.writeHeader(key, value);
876
+ }
877
+ });
878
+ }
879
+ }
880
+
881
+ const mountWithContext = async ($class, $context, request = {}) => {
882
+ const initComponent = async (obj2) => {
883
+ let out;
884
+ if ("init" in obj2) {
885
+ out = await obj2.init();
886
+ }
887
+ return out;
888
+ };
889
+ const injectContext = (obj2, $context2) => {
890
+ if ("$inject" in obj2) {
891
+ obj2.$inject($context2);
892
+ }
893
+ };
894
+ $context = Object.assign({
895
+ config: {},
896
+ getRequest: () => request,
897
+ method: "get",
898
+ ...request.controller && request.subaction && $context.db?.home ? await selectControllerParams(
899
+ $context.db.home,
900
+ $context.method || "get",
901
+ request.controller,
902
+ request.subaction
903
+ ) : {},
904
+ cookies: {},
905
+ hostname: $context.config?.server?.development?.host,
906
+ protocol: "http",
907
+ headers: {}
908
+ }, $context);
909
+ const obj = new $class();
910
+ injectContext(obj, $context);
911
+ const initResponse = await initComponent(obj);
912
+ if (initResponse) {
913
+ throw new ApiError.ApiError(
914
+ {
915
+ statusCode: 404,
916
+ code: 13,
917
+ message: `init method response value`
918
+ }
919
+ );
920
+ }
921
+ return obj;
922
+ };
923
+
924
+ const xmlOptions = { compact: true, ignoreComment: true, spaces: 4 };
925
+ class Controller {
926
+ constructor() {
927
+ // Addition headers that can be add in any place
928
+ this.responseHeaders = {};
929
+ }
930
+ /**
931
+ * Set cookies
932
+ * @param name
933
+ * @param value
934
+ * @param options
935
+ */
936
+ setCookieHeader(name, value, options = {}) {
937
+ return cookieString.cookieString(name, value, options);
938
+ }
939
+ /**
940
+ * Success request
941
+ * @param data response params
942
+ * @param options
943
+ * @returns
944
+ */
945
+ success(data = {}, options) {
946
+ return {
947
+ headers: Object.assign({ "content-type": "application/json" }, this.responseHeaders, options?.headers || {}),
948
+ body: {
949
+ isError: false,
950
+ data
951
+ },
952
+ memcache: options?.memcache || null,
953
+ statusCode: options?.statusCode || 200
954
+ };
955
+ }
956
+ /**
957
+ * Error response
958
+ * @param err
959
+ */
960
+ error(err) {
961
+ const e = err;
962
+ const code = e.code ? e.code : 0;
963
+ const message = e.message ? e.message : "Api request error";
964
+ const statusCode = e.statusCode ? e.statusCode : 404;
965
+ const data = e.data ? e.data : {};
966
+ const response = e.response ? {
967
+ // @ts-ignore
968
+ status: e.response.status,
969
+ // @ts-ignore
970
+ headers: e.response.headers,
971
+ config: {
972
+ // @ts-ignore
973
+ url: e.response.url,
974
+ // @ts-ignore
975
+ method: e.response.method,
976
+ // @ts-ignore
977
+ params: e.response.params,
978
+ // @ts-ignore
979
+ headers: e.response.headers
980
+ },
981
+ // @ts-ignore
982
+ data: e.response.data
983
+ } : {};
984
+ const headers = Object.assign({ "content-type": "application/json" }, e.headers);
985
+ return {
986
+ headers,
987
+ body: {
988
+ isError: true,
989
+ error: message,
990
+ code,
991
+ data,
992
+ stack: process.env.NODE_ENV !== "production" ? e.stack : "",
993
+ response: process.env.NODE_ENV !== "production" ? response : {}
994
+ },
995
+ statusCode
996
+ };
997
+ }
998
+ /**
999
+ * Xml response
1000
+ * @param data response params
1001
+ * @param options addition options
1002
+ */
1003
+ successXml(data = {}, options) {
1004
+ const defaultXml = {
1005
+ _declaration: {
1006
+ _attributes: {
1007
+ version: "1.0",
1008
+ encoding: "utf-8"
1009
+ }
1010
+ }
1011
+ };
1012
+ const response = this.success(data, options);
1013
+ return {
1014
+ headers: Object.assign({ "content-type": "application/xml" }, this.responseHeaders, options?.headers || {}),
1015
+ body: xmljs.js2xml(Object.assign(defaultXml, { body: { ...response.body } }), xmlOptions),
1016
+ memcache: response.memcache
1017
+ };
1018
+ }
1019
+ /**
1020
+ * Error xml response
1021
+ * @param err error object
1022
+ */
1023
+ errorXml(err) {
1024
+ const e = err;
1025
+ const defaultXml = {
1026
+ _declaration: {
1027
+ _attributes: {
1028
+ version: "1.0",
1029
+ encoding: "utf-8"
1030
+ }
1031
+ }
1032
+ };
1033
+ const response = this.error(e);
1034
+ const headers = Object.assign({ "content-type": "application/xml" }, e.headers);
1035
+ return {
1036
+ headers,
1037
+ body: xmljs.js2xml(Object.assign(defaultXml, { body: { ...response.body } }), xmlOptions),
1038
+ statusCode: response.statusCode
1039
+ };
1040
+ }
1041
+ // Create model
1042
+ async $create(model, ...args) {
1043
+ const obj = new model(...args);
1044
+ if ("$inject" in obj) {
1045
+ obj.$inject({
1046
+ method: this.$context.method,
1047
+ getRequest: this.$context.getRequest,
1048
+ config: this.$context.config,
1049
+ db: this.$context.db,
1050
+ stack: this.$context.stack,
1051
+ headers: this.$context.headers,
1052
+ cookies: this.$context.cookies,
1053
+ controller: this.$context.controller,
1054
+ action: this.$context.action,
1055
+ subaction: this.$context.subaction,
1056
+ setResponseHeader: (key, value) => this.setResponseHeader(key, value),
1057
+ setCookieHeader: this.setCookieHeader
1058
+ });
1059
+ }
1060
+ const inits = ["init", ...obj.$inits || []];
1061
+ for (const method of inits) {
1062
+ if (obj[method]) {
1063
+ await obj[method]();
1064
+ }
1065
+ }
1066
+ return obj;
1067
+ }
1068
+ // Create group of libs
1069
+ async $createAll(models) {
1070
+ return Promise.all(models.map((params) => this.$create(...params)));
1071
+ }
1072
+ /**
1073
+ * Inject app context
1074
+ * @param context
1075
+ */
1076
+ $inject(context) {
1077
+ this.$context = context;
1078
+ }
1079
+ getContext() {
1080
+ return this.$context;
1081
+ }
1082
+ getRequest() {
1083
+ return this.$context.getRequest();
1084
+ }
1085
+ getBody() {
1086
+ return this.$context["$body"] || Buffer.from("");
1087
+ }
1088
+ getFiles() {
1089
+ return this.$context["$files"] || {};
1090
+ }
1091
+ getStream() {
1092
+ return this.$context["$stream"] || new stream$1.PassThrough().end();
1093
+ }
1094
+ getConfig() {
1095
+ return this.$context.config;
1096
+ }
1097
+ getMethod() {
1098
+ return this.$context.method;
1099
+ }
1100
+ getCookies() {
1101
+ return this.$context.cookies;
1102
+ }
1103
+ getHostname() {
1104
+ return this.$context.hostname;
1105
+ }
1106
+ getUrl() {
1107
+ return this.$context.url;
1108
+ }
1109
+ getProtocol() {
1110
+ return this.$context.protocol;
1111
+ }
1112
+ getDb() {
1113
+ return this.$context.db;
1114
+ }
1115
+ getHeaders() {
1116
+ return this.$context.headers;
1117
+ }
1118
+ getController() {
1119
+ return this.$context.controller;
1120
+ }
1121
+ getAction() {
1122
+ return this.$context.action;
1123
+ }
1124
+ getSubaction() {
1125
+ return this.$context.subaction;
1126
+ }
1127
+ getHome() {
1128
+ return this.getDb().home;
1129
+ }
1130
+ getPool(key = "home") {
1131
+ return this.getDb()[key];
1132
+ }
1133
+ getStack() {
1134
+ return this.$context.stack;
1135
+ }
1136
+ setResponseHeader(key, value) {
1137
+ if (this.responseHeaders.hasOwnProperty(key)) {
1138
+ this.responseHeaders[key] = Array.isArray(this.responseHeaders[key]) ? this.responseHeaders[key] : [this.responseHeaders[key]];
1139
+ this.responseHeaders[key].push(value);
1140
+ } else {
1141
+ this.responseHeaders[key] = value;
1142
+ }
1143
+ }
1144
+ }
1145
+
1146
+ class Model {
1147
+ /**
1148
+ * Create model
1149
+ * @param model
1150
+ * @param args
1151
+ */
1152
+ async $create(model, ...args) {
1153
+ const obj = new model(...args);
1154
+ if ("$inject" in obj) {
1155
+ obj.$inject({
1156
+ method: this.$context.method,
1157
+ getRequest: this.$context.getRequest,
1158
+ config: this.$context.config,
1159
+ db: this.$context.db,
1160
+ stack: this.$context.stack,
1161
+ headers: this.$context.headers,
1162
+ cookies: this.$context.cookies,
1163
+ controller: this.$context.controller,
1164
+ action: this.$context.action,
1165
+ subaction: this.$context.subaction,
1166
+ setResponseHeader: this.$context.setResponseHeader,
1167
+ setCookieHeader: this.$context.setCookieHeader
1168
+ });
1169
+ }
1170
+ if ("init" in obj) {
1171
+ await obj.init();
1172
+ }
1173
+ return obj;
1174
+ }
1175
+ // Create group of libs
1176
+ async $createAll(models) {
1177
+ return Promise.all(models.map((params) => this.$create(...params)));
1178
+ }
1179
+ /**
1180
+ * Inject app context
1181
+ * @param context
1182
+ */
1183
+ $inject(context) {
1184
+ this.$context = context;
1185
+ }
1186
+ getContext() {
1187
+ return this.$context;
1188
+ }
1189
+ getRequest() {
1190
+ return this.$context.getRequest();
1191
+ }
1192
+ getConfig() {
1193
+ return this.$context.config;
1194
+ }
1195
+ getMethod() {
1196
+ return this.$context.method;
1197
+ }
1198
+ getHeaders() {
1199
+ return this.$context.headers;
1200
+ }
1201
+ getCookies() {
1202
+ return this.$context.cookies;
1203
+ }
1204
+ getController() {
1205
+ return this.$context.controller;
1206
+ }
1207
+ getAction() {
1208
+ return this.$context.action;
1209
+ }
1210
+ getSubaction() {
1211
+ return this.$context.subaction;
1212
+ }
1213
+ getDb() {
1214
+ return this.$context.db;
1215
+ }
1216
+ getHome() {
1217
+ return this.$context.db.home;
1218
+ }
1219
+ getPool(key = "home") {
1220
+ return this.getDb()[key];
1221
+ }
1222
+ getStack() {
1223
+ return this.$context.stack;
1224
+ }
1225
+ setResponseHeader(key, value) {
1226
+ return this.$context.setResponseHeader(key, value);
1227
+ }
1228
+ setCookieHeader(name, value, options = {}) {
1229
+ return this.$context.setCookieHeader(name, value, options);
1230
+ }
1231
+ }
1232
+
1233
+ const argumentsSubactionsKey = Symbol("arguments");
1234
+ const argumentsConnectionsKey = Symbol("connections");
1235
+ const responseSubactionsKey = Symbol("response");
1236
+ const responseInitKey = Symbol("init");
1237
+ const responseLoggerKey = Symbol("logger");
1238
+ const upperCaseFirstLetter = (str) => str.charAt(0).toUpperCase() + str.slice(1);
1239
+ function mixin(behaviour, sharedBehaviour = {}) {
1240
+ const instanceKeys = Reflect.ownKeys(behaviour);
1241
+ const sharedKeys = Reflect.ownKeys(sharedBehaviour);
1242
+ const typeTag = Symbol("isa");
1243
+ function _mixin(clazz) {
1244
+ for (const property of instanceKeys) {
1245
+ Object.defineProperty(clazz.prototype, property, { value: behaviour[property] });
1246
+ }
1247
+ Object.defineProperty(clazz.prototype, typeTag, { value: true });
1248
+ return clazz;
1249
+ }
1250
+ for (const property of sharedKeys) {
1251
+ Object.defineProperty(_mixin, property, {
1252
+ //@ts-ignore
1253
+ value: sharedBehaviour[property],
1254
+ enumerable: sharedBehaviour.propertyIsEnumerable(property)
1255
+ });
1256
+ }
1257
+ Object.defineProperty(_mixin, Symbol.hasInstance, {
1258
+ value: (i) => !!i[typeTag]
1259
+ });
1260
+ return _mixin;
1261
+ }
1262
+ const defineMetadataArgument = (key, target, propertyKey, parameterIndex, argumentType, params) => {
1263
+ const existingArguments = Reflect.getOwnMetadata(
1264
+ key,
1265
+ target,
1266
+ propertyKey
1267
+ ) || {};
1268
+ existingArguments[parameterIndex] = {
1269
+ type: argumentType,
1270
+ params
1271
+ };
1272
+ Reflect.defineMetadata(key, existingArguments, target, propertyKey);
1273
+ };
1274
+ function request() {
1275
+ return function(target, propertyKey, parameterIndex) {
1276
+ defineMetadataArgument(argumentsSubactionsKey, target, propertyKey, parameterIndex, "request");
1277
+ };
1278
+ }
1279
+ function context() {
1280
+ return function(target, propertyKey, parameterIndex) {
1281
+ defineMetadataArgument(argumentsSubactionsKey, target, propertyKey, parameterIndex, "context");
1282
+ };
1283
+ }
1284
+ function config() {
1285
+ return function(target, propertyKey, parameterIndex) {
1286
+ defineMetadataArgument(argumentsSubactionsKey, target, propertyKey, parameterIndex, "config");
1287
+ };
1288
+ }
1289
+ function method() {
1290
+ return function(target, propertyKey, parameterIndex) {
1291
+ defineMetadataArgument(argumentsSubactionsKey, target, propertyKey, parameterIndex, "method");
1292
+ };
1293
+ }
1294
+ function cookies() {
1295
+ return function(target, propertyKey, parameterIndex) {
1296
+ defineMetadataArgument(argumentsSubactionsKey, target, propertyKey, parameterIndex, "cookies");
1297
+ };
1298
+ }
1299
+ function hostname() {
1300
+ return function(target, propertyKey, parameterIndex) {
1301
+ defineMetadataArgument(argumentsSubactionsKey, target, propertyKey, parameterIndex, "hostname");
1302
+ };
1303
+ }
1304
+ function url() {
1305
+ return function(target, propertyKey, parameterIndex) {
1306
+ defineMetadataArgument(argumentsSubactionsKey, target, propertyKey, parameterIndex, "url");
1307
+ };
1308
+ }
1309
+ function protocol() {
1310
+ return function(target, propertyKey, parameterIndex) {
1311
+ defineMetadataArgument(argumentsSubactionsKey, target, propertyKey, parameterIndex, "protocol");
1312
+ };
1313
+ }
1314
+ function db() {
1315
+ return function(target, propertyKey, parameterIndex) {
1316
+ defineMetadataArgument(argumentsSubactionsKey, target, propertyKey, parameterIndex, "db");
1317
+ };
1318
+ }
1319
+ function headers() {
1320
+ return function(target, propertyKey, parameterIndex) {
1321
+ defineMetadataArgument(argumentsSubactionsKey, target, propertyKey, parameterIndex, "headers");
1322
+ };
1323
+ }
1324
+ function controller() {
1325
+ return function(target, propertyKey, parameterIndex) {
1326
+ defineMetadataArgument(argumentsSubactionsKey, target, propertyKey, parameterIndex, "controller");
1327
+ };
1328
+ }
1329
+ function action() {
1330
+ return function(target, propertyKey, parameterIndex) {
1331
+ defineMetadataArgument(argumentsSubactionsKey, target, propertyKey, parameterIndex, "action");
1332
+ };
1333
+ }
1334
+ function subaction() {
1335
+ return function(target, propertyKey, parameterIndex) {
1336
+ defineMetadataArgument(argumentsSubactionsKey, target, propertyKey, parameterIndex, "subaction");
1337
+ };
1338
+ }
1339
+ function body() {
1340
+ return function(target, propertyKey, parameterIndex) {
1341
+ defineMetadataArgument(argumentsSubactionsKey, target, propertyKey, parameterIndex, "body");
1342
+ };
1343
+ }
1344
+ function stream() {
1345
+ return function(target, propertyKey, parameterIndex) {
1346
+ defineMetadataArgument(argumentsSubactionsKey, target, propertyKey, parameterIndex, "stream");
1347
+ };
1348
+ }
1349
+ function home() {
1350
+ return function(target, propertyKey, parameterIndex) {
1351
+ defineMetadataArgument(argumentsSubactionsKey, target, propertyKey, parameterIndex, "home");
1352
+ };
1353
+ }
1354
+ function pool(name = "home") {
1355
+ return function(target, propertyKey, parameterIndex) {
1356
+ defineMetadataArgument(argumentsSubactionsKey, target, propertyKey, parameterIndex, "pool", name);
1357
+ };
1358
+ }
1359
+ function connection(name = "home") {
1360
+ return function(target, propertyKey, parameterIndex) {
1361
+ defineMetadataArgument(argumentsConnectionsKey, target, propertyKey, parameterIndex, "connection", name);
1362
+ };
1363
+ }
1364
+ function json(opt = {}) {
1365
+ return function(target, propertyKey, descriptor) {
1366
+ defineMetadataArgument(responseSubactionsKey, target, propertyKey, 0, "json", opt);
1367
+ };
1368
+ }
1369
+ function xml(opt = {}) {
1370
+ return function(target, propertyKey, descriptor) {
1371
+ defineMetadataArgument(responseSubactionsKey, target, propertyKey, 0, "xml", opt);
1372
+ };
1373
+ }
1374
+ function logerror(name) {
1375
+ return function(target, propertyKey, descriptor) {
1376
+ defineMetadataArgument(responseLoggerKey, target, propertyKey, name, "logger", name);
1377
+ };
1378
+ }
1379
+ function http(beforeCreate) {
1380
+ return function(target, propertyKey, descriptor) {
1381
+ const opts = {
1382
+ format: "json"
1383
+ };
1384
+ const method2 = descriptor.value;
1385
+ descriptor.value = async function() {
1386
+ if (beforeCreate) {
1387
+ Object.assign(opts, await beforeCreate.apply(this) || {});
1388
+ }
1389
+ const args = [];
1390
+ const connections = [];
1391
+ const existingArguments = Reflect.getOwnMetadata(
1392
+ argumentsSubactionsKey,
1393
+ target,
1394
+ propertyKey
1395
+ ) || {};
1396
+ const existingConnections = Reflect.getOwnMetadata(
1397
+ argumentsConnectionsKey,
1398
+ target,
1399
+ propertyKey
1400
+ ) || {};
1401
+ const existingLoggers = Reflect.getOwnMetadata(
1402
+ responseLoggerKey,
1403
+ target,
1404
+ propertyKey
1405
+ ) || {};
1406
+ const response = Reflect.getOwnMetadata(
1407
+ responseSubactionsKey,
1408
+ target,
1409
+ propertyKey
1410
+ )?.[0] || { type: "json", params: {} };
1411
+ const responseInit = Reflect.getOwnMetadata(
1412
+ responseInitKey,
1413
+ target,
1414
+ propertyKey
1415
+ )?.[0] || { type: "", params: {} };
1416
+ for (const key in existingArguments) {
1417
+ if (!existingArguments.hasOwnProperty(key)) {
1418
+ continue;
1419
+ }
1420
+ const getterName = `get${upperCaseFirstLetter(existingArguments[key].type)}`;
1421
+ args[+key] = this[getterName](existingArguments[key].params);
1422
+ }
1423
+ for (const key in existingConnections) {
1424
+ if (!existingConnections.hasOwnProperty(key)) {
1425
+ continue;
1426
+ }
1427
+ existingConnections[key].type;
1428
+ args[+key] = await this.getDb()[existingConnections[key].params].getConnection();
1429
+ connections.push(args[+key]);
1430
+ }
1431
+ try {
1432
+ let out = await method2.apply(this, args), opt;
1433
+ Array.isArray(out) && ([out, opt] = out);
1434
+ if (responseInit.type !== "init") {
1435
+ if (opts.format === "xml" || response.type === "xml") {
1436
+ return this.successXml(out, Object.assign(response.params, opt || {}));
1437
+ }
1438
+ return this.success(out, Object.assign(response.params, opt || {}));
1439
+ }
1440
+ } catch (e) {
1441
+ await Promise.all([...connections.map((connection2) => connection2.rollback())]);
1442
+ let output;
1443
+ if (opts.format === "xml" || response.type === "xml") {
1444
+ output = this.errorXml(e);
1445
+ } else {
1446
+ output = this.error(e);
1447
+ }
1448
+ for (const key in existingLoggers) {
1449
+ if (!existingLoggers.hasOwnProperty(key)) {
1450
+ continue;
1451
+ }
1452
+ const logger = existingLoggers[key].params;
1453
+ await this[logger].error(e, { response: easyAsh.omit(output?.body || {}, ["stack"]) });
1454
+ }
1455
+ return output;
1456
+ } finally {
1457
+ await Promise.all([...connections.map((connection2) => connection2.release())]);
1458
+ }
1459
+ };
1460
+ };
1461
+ }
1462
+ function init() {
1463
+ return function(target, propertyKey, descriptor) {
1464
+ defineMetadataArgument(responseInitKey, target, propertyKey, 0, "init");
1465
+ descriptor.value;
1466
+ if (!("$inits" in target)) {
1467
+ Object.defineProperty(target, "$inits", { value: [] });
1468
+ }
1469
+ target.$inits.push(propertyKey);
1470
+ };
1471
+ }
1472
+
1473
+ const helpers = {
1474
+ cookieParse: cookieParse.cookieParse,
1475
+ cookieString: cookieString.cookieString,
1476
+ jsonBody: jsonBody.jsonBody,
1477
+ rawBody,
1478
+ streamBody,
1479
+ urlencodedBody: urlencodedBody.urlencodedBody,
1480
+ multipartBody: multipartBody.multipartBody,
1481
+ readConfig: readConfig.readConfig,
1482
+ readConfigSync: readConfigSync.readConfigSync,
1483
+ staticBody: staticBody.staticBody,
1484
+ extensions: staticBody.extensions,
1485
+ getExt: staticBody.getExt,
1486
+ jwtDecode,
1487
+ readJsonConfigsSync
1488
+ };
1489
+
1490
+ exports.ApiError = ApiError.ApiError;
1491
+ exports.Server = Server.Server;
1492
+ exports.codeToStatus = Server.codeToStatus;
1493
+ exports.Jwt = Jwt.Jwt;
1494
+ exports.Memcached = Memcached.Memcached;
1495
+ exports.AsyncJwt = AsyncJwt;
1496
+ exports.Controller = Controller;
1497
+ exports.Model = Model;
1498
+ exports.Ssr = Ssr;
1499
+ exports.Web = Web;
1500
+ exports.action = action;
1501
+ exports.body = body;
1502
+ exports.config = config;
1503
+ exports.connection = connection;
1504
+ exports.context = context;
1505
+ exports.controller = controller;
1506
+ exports.cookies = cookies;
1507
+ exports.db = db;
1508
+ exports.headers = headers;
1509
+ exports.helpers = helpers;
1510
+ exports.home = home;
1511
+ exports.hostname = hostname;
1512
+ exports.http = http;
1513
+ exports.init = init;
1514
+ exports.json = json;
1515
+ exports.logerror = logerror;
1516
+ exports.method = method;
1517
+ exports.mixin = mixin;
1518
+ exports.mount = mountWithContext;
1519
+ exports.pool = pool;
1520
+ exports.protocol = protocol;
1521
+ exports.request = request;
1522
+ exports.selectControllersSchema = selectControllersSchema;
1523
+ exports.stream = stream;
1524
+ exports.subaction = subaction;
1525
+ exports.url = url;
1526
+ exports.xml = xml;