@jwn-js/common 2.2.1 → 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.
- package/ApiError.js +37 -1
- package/ApiError.mjs +35 -1
- package/Jwt-B4QZ2Ypb.js +80 -0
- package/Jwt-Be4GWrIO.js +75 -0
- package/Jwt.js +8 -1
- package/Jwt.mjs +2 -1
- package/Memcached.js +166 -9
- package/Memcached.mjs +164 -9
- package/Server.js +316 -1
- package/Server.mjs +313 -1
- package/cookieParse.js +25 -1
- package/cookieParse.mjs +23 -1
- package/cookieString.js +22 -1
- package/cookieString.mjs +20 -1
- package/docs/classes/ApiError.html +2 -2
- package/docs/classes/AsyncJwt.html +2 -2
- package/docs/classes/Controller.html +2 -2
- package/docs/classes/Jwt.html +2 -2
- package/docs/classes/Memcached.html +2 -2
- package/docs/classes/Model.html +2 -2
- package/docs/classes/Server.html +2 -2
- package/docs/classes/Ssr.html +2 -2
- package/docs/classes/Web.html +2 -2
- package/docs/functions/action.html +2 -2
- package/docs/functions/body.html +2 -2
- package/docs/functions/codeToStatus.html +2 -2
- package/docs/functions/config.html +2 -2
- package/docs/functions/connection.html +2 -2
- package/docs/functions/context.html +2 -2
- package/docs/functions/controller-1.html +2 -2
- package/docs/functions/cookies.html +2 -2
- package/docs/functions/db.html +2 -2
- package/docs/functions/headers.html +2 -2
- package/docs/functions/home.html +2 -2
- package/docs/functions/hostname.html +2 -2
- package/docs/functions/http.html +2 -2
- package/docs/functions/init.html +2 -2
- package/docs/functions/json.html +2 -2
- package/docs/functions/logerror.html +2 -2
- package/docs/functions/method.html +2 -2
- package/docs/functions/mixin.html +2 -2
- package/docs/functions/mount.html +2 -2
- package/docs/functions/pool.html +2 -2
- package/docs/functions/protocol.html +2 -2
- package/docs/functions/request.html +2 -2
- package/docs/functions/selectControllersSchema.html +1 -1
- package/docs/functions/stream.html +2 -2
- package/docs/functions/subaction.html +2 -2
- package/docs/functions/url.html +2 -2
- package/docs/functions/xml.html +2 -2
- package/docs/index.html +2 -2
- package/docs/interfaces/ApiErrorMessage.html +2 -2
- package/docs/interfaces/ContextSsr.html +2 -2
- package/docs/interfaces/ContextWeb.html +2 -2
- package/docs/interfaces/OptionsSsr.html +2 -2
- package/docs/interfaces/OptionsWeb.html +2 -2
- package/docs/interfaces/ResponseOptions.html +2 -2
- package/docs/interfaces/Route.html +2 -2
- package/docs/interfaces/Schema.html +2 -2
- package/docs/interfaces/ServerHandler.html +2 -2
- package/docs/interfaces/ServerOptions.html +2 -2
- package/docs/interfaces/ServerWebsocket.html +2 -2
- package/docs/modules.html +2 -2
- package/docs/types/ServerRoutes.html +1 -1
- package/docs/variables/helpers.html +2 -2
- package/index.js +1473 -4
- package/index.mjs +1417 -4
- package/jsonBody.js +25 -1
- package/jsonBody.mjs +23 -1
- package/multipartBody.js +42 -1
- package/multipartBody.mjs +40 -1
- package/package.json +1 -1
- package/readConfig.js +11 -1
- package/readConfig.mjs +9 -1
- package/readConfigSync.js +11 -1
- package/readConfigSync.mjs +9 -1
- package/staticBody.js +205 -1
- package/staticBody.mjs +200 -1
- package/urlencodedBody.js +26 -1
- package/urlencodedBody.mjs +24 -1
- package/Jwt-7tQL-rwa.js +0 -1
- package/Jwt-CDdbxwvH.js +0 -1
package/index.js
CHANGED
|
@@ -1,4 +1,242 @@
|
|
|
1
|
-
|
|
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
|
|
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
|
-
`)
|
|
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(u=>u.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(u=>u.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(u=>u.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(u=>u.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"),d=B.resolve(b,x),p=M.createWriteStream(d);m.pipe(p),Object.defineProperty(this.contextWeb,"$files",{enumerable:!1,configurable:!1,writable:!1,value:{body:{path:d}}}),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 u=await this.initComponent(r);if(typeof u>"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=u;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.statusCode||200,i=_.codeToStatus(s),n=!e&&S.isObject(t.body)?JSON.stringify(t.body):t.body;!e&&["get","head"].includes(this.contextWeb.method)&&s===200&&t.memcache&&this.contextWeb?.stack?.memcached instanceof v.Memcached&&this.contextWeb.stack.memcached.setPage(this.memcachedKey,t.headers,n,t.memcache).then(),e?this.res.cork(()=>{this.res.writeStatus(i),this.writeHeaders(t.headers),n.on("data",a=>{this.res.write(a)}).on("end",()=>{this.res.end()})}):this.res.cork(()=>{this.res.writeStatus(i),this.writeHeaders(t.headers),this.res.end(n)})}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 ue=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 de{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/json"},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=[],u=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 d in u){if(!u.hasOwnProperty(d))continue;const p=`get${me(u[d].type)}`;a[+d]=this[p](u[d].params)}for(const d in c)c.hasOwnProperty(d)&&(c[d].type,a[+d]=await this.getDb()[c[d].params].getConnection(),r.push(a[+d]));try{let d=await n.apply(this,a),p;if(Array.isArray(d)&&([d,p]=d),x.type!=="init")return i.format==="xml"||b.type==="xml"?this.successXml(d,Object.assign(b.params,p||{})):this.success(d,Object.assign(b.params,p||{}))}catch(d){await Promise.all([...r.map(w=>w.rollback())]);let p;i.format==="xml"||b.type==="xml"?p=this.errorXml(d):p=this.error(d);for(const w in m){if(!m.hasOwnProperty(w))continue;const K=m[w].params;await this[K].error(d,{response:S.omit(p?.body||{},["stack"])})}return p}finally{await Promise.all([...r.map(d=>d.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=de,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=ue,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;
|