@jwn-js/common 2.0.20 → 2.0.23

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 (42) hide show
  1. package/ApiError.d.ts +47 -47
  2. package/Jwt.d.ts +36 -36
  3. package/LICENSE +21 -21
  4. package/Memcached.d.ts +64 -64
  5. package/README.md +20 -20
  6. package/Server.d.ts +139 -139
  7. package/cookieParse.d.ts +4 -4
  8. package/cookieString.d.ts +9 -9
  9. package/docs/assets/highlight.css +1 -1
  10. package/docs/assets/main.js +2 -2
  11. package/docs/assets/search.js +1 -1
  12. package/docs/assets/style.css +28 -2
  13. package/docs/classes/ApiError.html +8 -9
  14. package/docs/classes/AsyncJwt.html +4 -4
  15. package/docs/classes/Controller.html +7 -7
  16. package/docs/classes/Jwt.html +4 -4
  17. package/docs/classes/Memcached.html +8 -8
  18. package/docs/classes/Model.html +3 -3
  19. package/docs/classes/Server.html +9 -9
  20. package/docs/classes/Ssr.html +2 -2
  21. package/docs/classes/Web.html +4 -4
  22. package/docs/index.html +2 -2
  23. package/docs/interfaces/ApiErrorMessage.html +1 -1
  24. package/docs/interfaces/ContextSsr.html +9 -9
  25. package/docs/interfaces/ContextWeb.html +1 -1
  26. package/docs/interfaces/OptionsSsr.html +1 -1
  27. package/docs/interfaces/OptionsWeb.html +1 -1
  28. package/docs/interfaces/Route.html +1 -1
  29. package/docs/interfaces/Schema.html +1 -1
  30. package/docs/interfaces/ServerHandler.html +1 -1
  31. package/docs/interfaces/ServerOptions.html +1 -1
  32. package/docs/interfaces/ServerWebsocket.html +1 -1
  33. package/docs/modules.html +28 -28
  34. package/index.d.ts +917 -906
  35. package/index.js +122 -19
  36. package/jsonBody.d.ts +5 -5
  37. package/multipartBody.d.ts +27 -27
  38. package/package.json +3 -3
  39. package/readConfig.d.ts +4 -4
  40. package/readConfigSync.d.ts +4 -4
  41. package/staticBody.d.ts +17 -17
  42. package/urlencodedBody.d.ts +5 -5
package/index.js CHANGED
@@ -987,12 +987,13 @@ const selectControllerParams = async (db, method, name, subaction, memcached, me
987
987
  isPermission: !!row.subaction_is_permission,
988
988
  isCheckMethod: !!row.subaction_is_check_method,
989
989
  isLog: !!row.subaction_is_log,
990
- isActive: !!row.subaction_is_active
990
+ isActive: !!row.subaction_is_active,
991
+ isSync: false
991
992
  }
992
993
  };
993
994
  };
994
995
 
995
- const schemaControllerParams = async (schema, method, name, subaction) => {
996
+ const schemaControllerParams = (schema, method, name, subaction) => {
996
997
  let controllerRow = schema.controllers.find((row) => row.name === name);
997
998
  if (!controllerRow) {
998
999
  throw new ApiError.ApiError({
@@ -1075,7 +1076,8 @@ const schemaControllerParams = async (schema, method, name, subaction) => {
1075
1076
  isPermission: subactionRow.isPermission,
1076
1077
  isCheckMethod: subactionRow.isCheckMethod,
1077
1078
  isLog: subactionRow.isLog,
1078
- isActive: subactionRow.isActive
1079
+ isActive: subactionRow.isActive,
1080
+ isSync: !!subactionRow.isSync
1079
1081
  },
1080
1082
  action: {
1081
1083
  id: actionRow.id,
@@ -1089,8 +1091,6 @@ const schemaControllerParams = async (schema, method, name, subaction) => {
1089
1091
  class Web {
1090
1092
  constructor(res, req, context) {
1091
1093
  this.defaultRequest = {
1092
- controller: "Index",
1093
- subaction: "index",
1094
1094
  lang: "ru"
1095
1095
  };
1096
1096
  this.defaultResponse = {
@@ -1098,14 +1098,19 @@ class Web {
1098
1098
  headers: { "content-type": "application/json" },
1099
1099
  body: {}
1100
1100
  };
1101
+ this.defaultControllerSubaction = {
1102
+ controller: "Index",
1103
+ subaction: "index"
1104
+ };
1101
1105
  this.res = res;
1102
1106
  this.req = req;
1103
1107
  this.context = context;
1104
1108
  }
1105
- async request(request = {}) {
1109
+ async request(input = {}) {
1106
1110
  let response = {};
1107
1111
  try {
1108
1112
  const query = this.req.getQuery();
1113
+ const request = Object.assign({}, this.defaultRequest, input, querystring__default["default"].parse(this.req.getQuery()));
1109
1114
  this.contextWeb = {
1110
1115
  config: this.context.config,
1111
1116
  db: this.context.db,
@@ -1115,11 +1120,44 @@ class Web {
1115
1120
  protocol: this.req.getHeader("x-forwarded-proto") || "http",
1116
1121
  url: this.req.getUrl() + (query ? `?${query}` : ""),
1117
1122
  headers: {},
1118
- stack: this.context.stack || {}
1123
+ stack: this.context.stack || {},
1124
+ getRequest: () => request,
1125
+ req: this.req,
1126
+ res: this.res
1119
1127
  };
1120
1128
  this.req.forEach((key, value) => this.contextWeb.headers[key] = value);
1121
1129
  const type = this.contextWeb.headers["content-type"] || "application/json";
1122
- request = Object.assign({}, this.defaultRequest, request, querystring__default["default"].parse(this.req.getQuery()));
1130
+ if (request.controller && request.subaction && this.context.schema) {
1131
+ this.route = this.findRoute(request.controller);
1132
+ Object.assign(this.contextWeb, schemaControllerParams(this.context.schema, this.contextWeb.method, this.route.name, request.subaction));
1133
+ if (this.contextWeb.subaction.isSync) {
1134
+ if (!["get", "head"].includes(this.contextWeb.method)) {
1135
+ Object.defineProperty(this.contextWeb, "$stream", {
1136
+ enumerable: false,
1137
+ configurable: false,
1138
+ writable: false,
1139
+ value: streamBody(this.res, this.req)
1140
+ });
1141
+ }
1142
+ const controllerClass2 = this.importControllerSync(request.controller);
1143
+ const controller2 = new controllerClass2();
1144
+ this.injectContext(controller2);
1145
+ if (request.subaction in controller2) {
1146
+ response = await controller2[request.subaction]();
1147
+ } else {
1148
+ throw new ApiError.ApiError({
1149
+ statusCode: 404,
1150
+ code: 13,
1151
+ message: `Method ${request.subaction} not found in ${request.controller} route`
1152
+ });
1153
+ }
1154
+ response = Object.assign({}, this.defaultResponse, response);
1155
+ this.success(response);
1156
+ return;
1157
+ }
1158
+ }
1159
+ request.controller = request.controller || this.defaultControllerSubaction.controller;
1160
+ request.subaction = request.subaction || this.defaultControllerSubaction.subaction;
1123
1161
  if (type.indexOf("application/json") !== -1 || type.indexOf("text/json") !== -1) {
1124
1162
  Object.assign(request, await jsonBody(this.res, this.req));
1125
1163
  } else if (!["get", "head"].includes(this.contextWeb.method) && type.indexOf("multipart/form-data") !== -1) {
@@ -1130,12 +1168,12 @@ class Web {
1130
1168
  const raw = (await rawBody(this.res, this.req)).toString();
1131
1169
  const records = xmljs__default["default"].xml2js(raw, { compact: true, cdataKey: "_value", textKey: "_value" });
1132
1170
  Object.assign(request, records || {});
1133
- } else if (!["get", "head"].includes(this.contextWeb.method) && type.indexOf("application/octet-stream") !== -1) {
1171
+ } else if (!["get", "head"].includes(this.contextWeb.method) && type.indexOf("stream") !== -1) {
1134
1172
  Object.defineProperty(this.contextWeb, "$stream", {
1135
1173
  enumerable: false,
1136
1174
  configurable: false,
1137
1175
  writable: false,
1138
- value: await streamBody(this.res, this.req)
1176
+ value: streamBody(this.res, this.req)
1139
1177
  });
1140
1178
  } else {
1141
1179
  Object.defineProperty(this.contextWeb, "$body", {
@@ -1145,16 +1183,15 @@ class Web {
1145
1183
  value: await rawBody(this.res, this.req)
1146
1184
  });
1147
1185
  }
1148
- this.route = this.findRoute(request);
1149
- Object.assign(this.contextWeb, this.context.schema ? await schemaControllerParams(this.context.schema, this.contextWeb.method, this.route.name, request.subaction) : await selectControllerParams(this.contextWeb.db.home, this.contextWeb.method, this.route.name, request.subaction, this.context.stack?.memcached, this.context.stack?.memcachedPrefix, this.context.stack?.memcachedExpiry));
1186
+ this.route = this.findRoute(request.controller);
1187
+ Object.assign(this.contextWeb, this.context.schema ? schemaControllerParams(this.context.schema, this.contextWeb.method, this.route.name, request.subaction) : await selectControllerParams(this.contextWeb.db.home, this.contextWeb.method, this.route.name, request.subaction, this.context.stack?.memcached, this.context.stack?.memcachedPrefix, this.context.stack?.memcachedExpiry));
1150
1188
  Object.defineProperty(this.contextWeb, "$route", {
1151
1189
  enumerable: false,
1152
1190
  configurable: false,
1153
1191
  writable: false,
1154
1192
  value: this.route
1155
1193
  });
1156
- const controllerClass = await this.importController(request);
1157
- this.contextWeb.getRequest = () => request;
1194
+ const controllerClass = await this.importController(request.controller);
1158
1195
  const controller = new controllerClass();
1159
1196
  this.injectContext(controller);
1160
1197
  const initResponse = await this.initComponent(controller);
@@ -1177,7 +1214,7 @@ class Web {
1177
1214
  this.error(e);
1178
1215
  }
1179
1216
  }
1180
- async importController(request) {
1217
+ async importController(controllerName) {
1181
1218
  let controllerClass = this.route.component.default || this.route.component;
1182
1219
  if (!easyAsh.isClass(controllerClass)) {
1183
1220
  controllerClass = (await this.route.component()).default;
@@ -1186,18 +1223,29 @@ class Web {
1186
1223
  throw new ApiError.ApiError({
1187
1224
  statusCode: 404,
1188
1225
  code: 12,
1189
- message: `Class not found for ${request.controller} route`
1226
+ message: `Class not found for ${controllerName} route`
1190
1227
  });
1191
1228
  }
1192
1229
  return controllerClass;
1193
1230
  }
1194
- findRoute(request) {
1195
- const route = this.context.routes.filter((v) => v.name === request.controller && (v.method === this.contextWeb.method || v.method === "any" || Array.isArray(v.method) && v.method.includes(this.contextWeb.method) || typeof v.method === "undefined"))?.[0];
1231
+ importControllerSync(controllerName) {
1232
+ const controllerClass = this.route.component.default || this.route.component;
1233
+ if (typeof controllerClass !== "function") {
1234
+ throw new ApiError.ApiError({
1235
+ statusCode: 404,
1236
+ code: 12,
1237
+ message: `Class not found for ${controllerName} route`
1238
+ });
1239
+ }
1240
+ return controllerClass;
1241
+ }
1242
+ findRoute(controllerName) {
1243
+ const route = this.context.routes.filter((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"))?.[0];
1196
1244
  if (!route) {
1197
1245
  throw new ApiError.ApiError({
1198
1246
  statusCode: 404,
1199
1247
  code: 11,
1200
- message: `Route ${request.controller} not found`
1248
+ message: `Route ${controllerName} not found`
1201
1249
  });
1202
1250
  }
1203
1251
  return route;
@@ -1522,6 +1570,60 @@ class Model {
1522
1570
  }
1523
1571
  }
1524
1572
 
1573
+ const selectControllersSchema = async (pool) => {
1574
+ const actions = {};
1575
+ const controllers = {};
1576
+ const rows = await pool.poolQuery(`
1577
+ SELECT c.id AS controller_id,
1578
+ c.name AS controller_name,
1579
+ c.is_active AS controller_is_active,
1580
+ c.is_sitemap AS controller_is_sitemap,
1581
+ a.id AS action_id,
1582
+ a.name AS action_name,
1583
+ a.is_active AS action_is_active,
1584
+ a.method AS action_method,
1585
+ s.id AS subaction_id,
1586
+ s.name AS subaction_name,
1587
+ s.is_permission AS subaction_is_permission,
1588
+ s.is_check_method AS subaction_is_check_method,
1589
+ s.is_log AS subaction_is_log,
1590
+ s.is_active AS subaction_is_active,
1591
+ s.is_sync AS subaction_is_sync
1592
+ FROM app_controllers c
1593
+ INNER JOIN app_subactions s ON s.app_controllers_id = c.id
1594
+ LEFT JOIN app_actions a ON a.id = s.app_actions_id;
1595
+ `);
1596
+ rows.forEach((row) => {
1597
+ actions[row.action_name] = {
1598
+ id: row.action_id,
1599
+ name: row.action_name,
1600
+ isActive: !!row.action_is_active,
1601
+ method: row.action_method
1602
+ };
1603
+ controllers[row.controller_name] = controllers[row.controller_name] || {
1604
+ id: row.controller_id,
1605
+ name: row.controller_name,
1606
+ isActive: !!row.controller_is_active,
1607
+ isSitemap: !!row.controller_is_sitemap,
1608
+ subactions: []
1609
+ };
1610
+ controllers[row.controller_name].subactions.push({
1611
+ id: row.subaction_id,
1612
+ action: row.action_name,
1613
+ name: row.subaction_name,
1614
+ isPermission: !!row.subaction_is_permission,
1615
+ isCheckMethod: !!row.subaction_is_check_method,
1616
+ isLog: !!row.subaction_is_log,
1617
+ isActive: !!row.subaction_is_active,
1618
+ isSync: !!row.subaction_is_sync
1619
+ });
1620
+ });
1621
+ return {
1622
+ controllers: Object.values(controllers),
1623
+ actions: Object.values(actions)
1624
+ };
1625
+ };
1626
+
1525
1627
  const argumentsSubactionsKey = Symbol("arguments");
1526
1628
  const argumentsConnectionsKey = Symbol("connections");
1527
1629
  const responseSubactionsKey = Symbol("response");
@@ -1779,6 +1881,7 @@ exports.mount = mountWithContext;
1779
1881
  exports.pool = pool;
1780
1882
  exports.protocol = protocol;
1781
1883
  exports.request = request;
1884
+ exports.selectControllersSchema = selectControllersSchema;
1782
1885
  exports.stream = stream;
1783
1886
  exports.subaction = subaction;
1784
1887
  exports.url = url;
package/jsonBody.d.ts CHANGED
@@ -1,10 +1,10 @@
1
1
  import { HttpResponse, HttpRequest } from 'uWebSockets.js';
2
2
 
3
- /**
4
- * @description
5
- * Parser of json requests body
6
- * @throws {ApiError}
7
- */
3
+ /**
4
+ * @description
5
+ * Parser of json requests body
6
+ * @throws {ApiError}
7
+ */
8
8
  declare const jsonBody: (res: HttpResponse, req: HttpRequest) => Promise<any>;
9
9
 
10
10
  export { jsonBody };
@@ -1,33 +1,33 @@
1
1
  import { Options } from 'formidable';
2
2
  import { HttpResponse, HttpRequest } from 'uWebSockets.js';
3
3
 
4
- /**
5
- * @description
6
- * Parser of form urlencoded requests body
7
- * @throws {ApiError}
8
- *
9
- * formidable1
10
- * {
11
- * size: 3451,
12
- * path: 'C:\\Users\\PROFES~1\\AppData\\Local\\Temp\\upload_fa55df09b0f7fdb8fee94b87b7086573',
13
- * name: 'logo.png',
14
- * type: 'image/png',
15
- * mtime: '2021-12-28T16:21:06.006Z'
16
- * }
17
- *
18
- *
19
- * Migration to formidable2
20
- * {
21
- * size: 3451,
22
- * filepath: 'C:\\Users\\PROFES~1\\AppData\\Local\\Temp\\4707bbd7d7f6bb8e59f9f3a00',
23
- * newFilename: '4707bbd7d7f6bb8e59f9f3a00',
24
- * mimetype: 'image/png',
25
- * mtime: '2021-12-28T16:18:14.130Z',
26
- * originalFilename: 'logo.png'
27
- * }
28
- *
29
- *
30
- */
4
+ /**
5
+ * @description
6
+ * Parser of form urlencoded requests body
7
+ * @throws {ApiError}
8
+ *
9
+ * formidable1
10
+ * {
11
+ * size: 3451,
12
+ * path: 'C:\\Users\\PROFES~1\\AppData\\Local\\Temp\\upload_fa55df09b0f7fdb8fee94b87b7086573',
13
+ * name: 'logo.png',
14
+ * type: 'image/png',
15
+ * mtime: '2021-12-28T16:21:06.006Z'
16
+ * }
17
+ *
18
+ *
19
+ * Migration to formidable2
20
+ * {
21
+ * size: 3451,
22
+ * filepath: 'C:\\Users\\PROFES~1\\AppData\\Local\\Temp\\4707bbd7d7f6bb8e59f9f3a00',
23
+ * newFilename: '4707bbd7d7f6bb8e59f9f3a00',
24
+ * mimetype: 'image/png',
25
+ * mtime: '2021-12-28T16:18:14.130Z',
26
+ * originalFilename: 'logo.png'
27
+ * }
28
+ *
29
+ *
30
+ */
31
31
  declare const multipartBody: (res: HttpResponse, req: HttpRequest, options?: Options) => Promise<any>;
32
32
 
33
33
  export { multipartBody };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@jwn-js/common",
3
3
  "private": false,
4
- "version": "2.0.20",
4
+ "version": "2.0.23",
5
5
  "description": "@jwn-js/common package",
6
6
  "main": "./index.js",
7
7
  "types": "./index.d.ts",
@@ -27,7 +27,7 @@
27
27
  "@typescript-eslint/eslint-plugin": "^4.23.0",
28
28
  "@typescript-eslint/parser": "^4.26.1",
29
29
  "chalk": "^4.1.1",
30
- "esbuild": "^0.14.8",
30
+ "esbuild": "^0.14.39",
31
31
  "eslint": "^7.26.0",
32
32
  "fs-extra": "^10.0.0",
33
33
  "jest": "^27.4.5",
@@ -43,7 +43,7 @@
43
43
  "zlib": "^1.0.5"
44
44
  },
45
45
  "dependencies": {
46
- "buildmsql": "^1.3.9",
46
+ "buildmsql": "^1.3.15",
47
47
  "easy-ash": "^1.1.7",
48
48
  "formidable": "2",
49
49
  "memjs": "^1.3.0",
package/readConfig.d.ts CHANGED
@@ -1,7 +1,7 @@
1
- /**
2
- * @description
3
- * Read connect.json
4
- */
1
+ /**
2
+ * @description
3
+ * Read connect.json
4
+ */
5
5
  declare const readConfig: (jsonfile: string) => Promise<any>;
6
6
 
7
7
  export { readConfig };
@@ -1,7 +1,7 @@
1
- /**
2
- * @description
3
- * Read connect.json
4
- */
1
+ /**
2
+ * @description
3
+ * Read connect.json
4
+ */
5
5
  declare const readConfigSync: (jsonfile: string) => any;
6
6
 
7
7
  export { readConfigSync };
package/staticBody.d.ts CHANGED
@@ -1,22 +1,22 @@
1
1
  import { HttpResponse, HttpRequest } from 'uWebSockets.js';
2
2
 
3
- declare const exts: Record<string, string>;
4
- /**
5
- * approved extensions
6
- */
7
- declare const extensions: Array<string>;
8
- /**
9
- * Get extension from path
10
- * @param path
11
- * @return {string}
12
- */
13
- declare const getExt: (path: string) => string;
14
- /**
15
- * Reed static files
16
- * @param req
17
- * @param res
18
- * @param base
19
- */
3
+ declare const exts: Record<string, string>;
4
+ /**
5
+ * approved extensions
6
+ */
7
+ declare const extensions: Array<string>;
8
+ /**
9
+ * Get extension from path
10
+ * @param path
11
+ * @return {string}
12
+ */
13
+ declare const getExt: (path: string) => string;
14
+ /**
15
+ * Reed static files
16
+ * @param req
17
+ * @param res
18
+ * @param base
19
+ */
20
20
  declare function staticBody(res: HttpResponse, req: HttpRequest, base: string): Promise<void>;
21
21
 
22
22
  export { extensions, exts, getExt, staticBody };
@@ -1,10 +1,10 @@
1
1
  import { HttpResponse, HttpRequest } from 'uWebSockets.js';
2
2
 
3
- /**
4
- * @description
5
- * Parser of form urlencoded requests body
6
- * @throws {ApiError}
7
- */
3
+ /**
4
+ * @description
5
+ * Parser of form urlencoded requests body
6
+ * @throws {ApiError}
7
+ */
8
8
  declare const urlencodedBody: (res: HttpResponse, req: HttpRequest) => Promise<any>;
9
9
 
10
10
  export { urlencodedBody };