@jwn-js/common 2.0.21 → 2.0.24

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/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,56 @@ 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
  };
1128
+ if (["get", "head"].includes(this.contextWeb.method) && this.contextWeb?.stack?.memcached instanceof Memcached) {
1129
+ const memcached = this.contextWeb.stack.memcached;
1130
+ const cache = await memcached.getPage(this.contextWeb.url);
1131
+ if (cache) {
1132
+ const { data, headers } = cache;
1133
+ this.success({
1134
+ body: data.toString(),
1135
+ headers,
1136
+ statusCode: 200
1137
+ });
1138
+ }
1139
+ }
1120
1140
  this.req.forEach((key, value) => this.contextWeb.headers[key] = value);
1121
1141
  const type = this.contextWeb.headers["content-type"] || "application/json";
1122
- request = Object.assign({}, this.defaultRequest, request, querystring__default["default"].parse(this.req.getQuery()));
1142
+ if (request.controller && request.subaction && this.context.schema) {
1143
+ this.route = this.findRoute(request.controller);
1144
+ Object.assign(this.contextWeb, schemaControllerParams(this.context.schema, this.contextWeb.method, this.route.name, request.subaction));
1145
+ if (this.contextWeb.subaction.isSync) {
1146
+ if (!["get", "head"].includes(this.contextWeb.method)) {
1147
+ Object.defineProperty(this.contextWeb, "$stream", {
1148
+ enumerable: false,
1149
+ configurable: false,
1150
+ writable: false,
1151
+ value: streamBody(this.res, this.req)
1152
+ });
1153
+ }
1154
+ const controllerClass2 = this.importControllerSync(request.controller);
1155
+ const controller2 = new controllerClass2();
1156
+ this.injectContext(controller2);
1157
+ if (request.subaction in controller2) {
1158
+ response = await controller2[request.subaction]();
1159
+ } else {
1160
+ throw new ApiError.ApiError({
1161
+ statusCode: 404,
1162
+ code: 13,
1163
+ message: `Method ${request.subaction} not found in ${request.controller} route`
1164
+ });
1165
+ }
1166
+ response = Object.assign({}, this.defaultResponse, response);
1167
+ this.success(response);
1168
+ return;
1169
+ }
1170
+ }
1171
+ request.controller = request.controller || this.defaultControllerSubaction.controller;
1172
+ request.subaction = request.subaction || this.defaultControllerSubaction.subaction;
1123
1173
  if (type.indexOf("application/json") !== -1 || type.indexOf("text/json") !== -1) {
1124
1174
  Object.assign(request, await jsonBody(this.res, this.req));
1125
1175
  } else if (!["get", "head"].includes(this.contextWeb.method) && type.indexOf("multipart/form-data") !== -1) {
@@ -1130,12 +1180,12 @@ class Web {
1130
1180
  const raw = (await rawBody(this.res, this.req)).toString();
1131
1181
  const records = xmljs__default["default"].xml2js(raw, { compact: true, cdataKey: "_value", textKey: "_value" });
1132
1182
  Object.assign(request, records || {});
1133
- } else if (!["get", "head"].includes(this.contextWeb.method) && type.indexOf("application/octet-stream") !== -1) {
1183
+ } else if (!["get", "head"].includes(this.contextWeb.method) && type.indexOf("stream") !== -1) {
1134
1184
  Object.defineProperty(this.contextWeb, "$stream", {
1135
1185
  enumerable: false,
1136
1186
  configurable: false,
1137
1187
  writable: false,
1138
- value: await streamBody(this.res, this.req)
1188
+ value: streamBody(this.res, this.req)
1139
1189
  });
1140
1190
  } else {
1141
1191
  Object.defineProperty(this.contextWeb, "$body", {
@@ -1145,16 +1195,15 @@ class Web {
1145
1195
  value: await rawBody(this.res, this.req)
1146
1196
  });
1147
1197
  }
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));
1198
+ this.route = this.findRoute(request.controller);
1199
+ 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
1200
  Object.defineProperty(this.contextWeb, "$route", {
1151
1201
  enumerable: false,
1152
1202
  configurable: false,
1153
1203
  writable: false,
1154
1204
  value: this.route
1155
1205
  });
1156
- const controllerClass = await this.importController(request);
1157
- this.contextWeb.getRequest = () => request;
1206
+ const controllerClass = await this.importController(request.controller);
1158
1207
  const controller = new controllerClass();
1159
1208
  this.injectContext(controller);
1160
1209
  const initResponse = await this.initComponent(controller);
@@ -1177,7 +1226,7 @@ class Web {
1177
1226
  this.error(e);
1178
1227
  }
1179
1228
  }
1180
- async importController(request) {
1229
+ async importController(controllerName) {
1181
1230
  let controllerClass = this.route.component.default || this.route.component;
1182
1231
  if (!easyAsh.isClass(controllerClass)) {
1183
1232
  controllerClass = (await this.route.component()).default;
@@ -1186,18 +1235,29 @@ class Web {
1186
1235
  throw new ApiError.ApiError({
1187
1236
  statusCode: 404,
1188
1237
  code: 12,
1189
- message: `Class not found for ${request.controller} route`
1238
+ message: `Class not found for ${controllerName} route`
1190
1239
  });
1191
1240
  }
1192
1241
  return controllerClass;
1193
1242
  }
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];
1243
+ importControllerSync(controllerName) {
1244
+ const controllerClass = this.route.component.default || this.route.component;
1245
+ if (typeof controllerClass !== "function") {
1246
+ throw new ApiError.ApiError({
1247
+ statusCode: 404,
1248
+ code: 12,
1249
+ message: `Class not found for ${controllerName} route`
1250
+ });
1251
+ }
1252
+ return controllerClass;
1253
+ }
1254
+ findRoute(controllerName) {
1255
+ 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
1256
  if (!route) {
1197
1257
  throw new ApiError.ApiError({
1198
1258
  statusCode: 404,
1199
1259
  code: 11,
1200
- message: `Route ${request.controller} not found`
1260
+ message: `Route ${controllerName} not found`
1201
1261
  });
1202
1262
  }
1203
1263
  return route;
@@ -1219,8 +1279,13 @@ class Web {
1219
1279
  }
1220
1280
  }
1221
1281
  success(response) {
1222
- const status = codeToStatus(response.statusCode || 200);
1282
+ const code = response.statusCode || 200;
1283
+ const status = codeToStatus(code);
1223
1284
  const body = easyAsh.isObject(response.body) ? JSON.stringify(response.body) : response.body;
1285
+ if (["get", "head"].includes(this.contextWeb.method) && code === 200 && response.memcache && this.contextWeb?.stack?.memcached instanceof Memcached) {
1286
+ const memcached = this.contextWeb.stack.memcached;
1287
+ memcached.setPage(this.contextWeb.url, response.headers, body, response.memcache).then();
1288
+ }
1224
1289
  this.res.writeStatus(status);
1225
1290
  Object.entries(response.headers).map(([key, value]) => this.res.writeHeader(key, value));
1226
1291
  this.res.end(body);
@@ -1522,6 +1587,60 @@ class Model {
1522
1587
  }
1523
1588
  }
1524
1589
 
1590
+ const selectControllersSchema = async (pool) => {
1591
+ const actions = {};
1592
+ const controllers = {};
1593
+ const rows = await pool.poolQuery(`
1594
+ SELECT c.id AS controller_id,
1595
+ c.name AS controller_name,
1596
+ c.is_active AS controller_is_active,
1597
+ c.is_sitemap AS controller_is_sitemap,
1598
+ a.id AS action_id,
1599
+ a.name AS action_name,
1600
+ a.is_active AS action_is_active,
1601
+ a.method AS action_method,
1602
+ s.id AS subaction_id,
1603
+ s.name AS subaction_name,
1604
+ s.is_permission AS subaction_is_permission,
1605
+ s.is_check_method AS subaction_is_check_method,
1606
+ s.is_log AS subaction_is_log,
1607
+ s.is_active AS subaction_is_active,
1608
+ s.is_sync AS subaction_is_sync
1609
+ FROM app_controllers c
1610
+ INNER JOIN app_subactions s ON s.app_controllers_id = c.id
1611
+ LEFT JOIN app_actions a ON a.id = s.app_actions_id;
1612
+ `);
1613
+ rows.forEach((row) => {
1614
+ actions[row.action_name] = {
1615
+ id: row.action_id,
1616
+ name: row.action_name,
1617
+ isActive: !!row.action_is_active,
1618
+ method: row.action_method
1619
+ };
1620
+ controllers[row.controller_name] = controllers[row.controller_name] || {
1621
+ id: row.controller_id,
1622
+ name: row.controller_name,
1623
+ isActive: !!row.controller_is_active,
1624
+ isSitemap: !!row.controller_is_sitemap,
1625
+ subactions: []
1626
+ };
1627
+ controllers[row.controller_name].subactions.push({
1628
+ id: row.subaction_id,
1629
+ action: row.action_name,
1630
+ name: row.subaction_name,
1631
+ isPermission: !!row.subaction_is_permission,
1632
+ isCheckMethod: !!row.subaction_is_check_method,
1633
+ isLog: !!row.subaction_is_log,
1634
+ isActive: !!row.subaction_is_active,
1635
+ isSync: !!row.subaction_is_sync
1636
+ });
1637
+ });
1638
+ return {
1639
+ controllers: Object.values(controllers),
1640
+ actions: Object.values(actions)
1641
+ };
1642
+ };
1643
+
1525
1644
  const argumentsSubactionsKey = Symbol("arguments");
1526
1645
  const argumentsConnectionsKey = Symbol("connections");
1527
1646
  const responseSubactionsKey = Symbol("response");
@@ -1779,6 +1898,7 @@ exports.mount = mountWithContext;
1779
1898
  exports.pool = pool;
1780
1899
  exports.protocol = protocol;
1781
1900
  exports.request = request;
1901
+ exports.selectControllersSchema = selectControllersSchema;
1782
1902
  exports.stream = stream;
1783
1903
  exports.subaction = subaction;
1784
1904
  exports.url = url;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@jwn-js/common",
3
3
  "private": false,
4
- "version": "2.0.21",
4
+ "version": "2.0.24",
5
5
  "description": "@jwn-js/common package",
6
6
  "main": "./index.js",
7
7
  "types": "./index.d.ts",
@@ -43,7 +43,7 @@
43
43
  "zlib": "^1.0.5"
44
44
  },
45
45
  "dependencies": {
46
- "buildmsql": "^1.3.14",
46
+ "buildmsql": "^1.3.15",
47
47
  "easy-ash": "^1.1.7",
48
48
  "formidable": "2",
49
49
  "memjs": "^1.3.0",