@stemy/backend 2.9.6 → 3.0.0

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.
@@ -23,9 +23,8 @@ import sharp_ from 'sharp';
23
23
  import axios from 'axios';
24
24
  import { GridFSBucket } from 'mongodb';
25
25
  import dotenv from 'dotenv';
26
- import { Queue, Worker, Scheduler } from 'node-resque';
27
26
  import { validate, schedule } from 'node-cron';
28
- import ioredis from 'ioredis';
27
+ import { socket } from 'zeromq';
29
28
  import socket_io_client from 'socket.io-client';
30
29
  import { createServer } from 'http';
31
30
  import express_, { static as static$1 } from 'express';
@@ -36,7 +35,7 @@ import * as Handlebars from 'handlebars';
36
35
  import { compare } from 'bcrypt';
37
36
  import moment from 'moment';
38
37
 
39
- var __awaiter$v = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
38
+ var __awaiter$w = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
40
39
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
41
40
  return new (P || (P = Promise))(function (resolve, reject) {
42
41
  function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
@@ -238,7 +237,7 @@ function hydratePopulated(modelType, json) {
238
237
  return object;
239
238
  }
240
239
  function paginateAggregations(model, aggregations, params, metaProjection = {}) {
241
- return __awaiter$v(this, void 0, void 0, function* () {
240
+ return __awaiter$w(this, void 0, void 0, function* () {
242
241
  const sortField = !isString(params.sort) || !params.sort ? null : (params.sort.startsWith("-") ? params.sort.substr(1) : params.sort);
243
242
  const sortAggregation = !sortField ? [] : [{
244
243
  $sort: { [sortField]: sortField == params.sort ? 1 : -1 }
@@ -337,7 +336,7 @@ function readFile(path) {
337
336
  });
338
337
  }
339
338
  function readAndDeleteFile(path, timeout = 5000) {
340
- return __awaiter$v(this, void 0, void 0, function* () {
339
+ return __awaiter$w(this, void 0, void 0, function* () {
341
340
  const data = yield readFile(path);
342
341
  setTimeout(() => {
343
342
  unlink(path, () => {
@@ -347,7 +346,7 @@ function readAndDeleteFile(path, timeout = 5000) {
347
346
  });
348
347
  }
349
348
  function writeFile(path, data) {
350
- return __awaiter$v(this, void 0, void 0, function* () {
349
+ return __awaiter$w(this, void 0, void 0, function* () {
351
350
  yield mkdirRecursive(dirname(path));
352
351
  return new Promise((res, rej) => {
353
352
  writeFile$1(path, data, err => {
@@ -363,10 +362,14 @@ function writeFile(path, data) {
363
362
  function valueToPromise(value) {
364
363
  return value instanceof Promise ? value : Promise.resolve(value);
365
364
  }
366
- function promiseTimeout(timeout = 1000) {
367
- return new Promise((resolve) => {
365
+ function promiseTimeout(timeout = 1000, error = false) {
366
+ return new Promise((resolve, reject) => {
368
367
  setTimeout(() => {
369
- resolve();
368
+ if (error) {
369
+ reject(`Timeout exceeded: ${timeout}ms`);
370
+ return;
371
+ }
372
+ resolve(`Timeout: ${timeout}ms`);
370
373
  }, timeout);
371
374
  });
372
375
  }
@@ -426,7 +429,7 @@ function ResolveEntity(model, extraCheck) {
426
429
  const paramName = modelName.toLowerCase();
427
430
  return createParamDecorator({
428
431
  required: false,
429
- value: (action) => __awaiter$v(this, void 0, void 0, function* () {
432
+ value: (action) => __awaiter$w(this, void 0, void 0, function* () {
430
433
  const req = action.request;
431
434
  const token = req.header(`x-${paramName}-token`);
432
435
  const id = req.params[`${paramName}Id`];
@@ -640,6 +643,66 @@ function runCommand(scriptPath, expectedCode = 0) {
640
643
  console.error(data.toString());
641
644
  });
642
645
  });
646
+ }
647
+ var ConsoleColor;
648
+ (function (ConsoleColor) {
649
+ ConsoleColor["Reset"] = "\u001B[0m";
650
+ ConsoleColor["Bright"] = "\u001B[1m";
651
+ ConsoleColor["Dim"] = "\u001B[2m";
652
+ ConsoleColor["Underscore"] = "\u001B[4m";
653
+ ConsoleColor["Blink"] = "\u001B[5m";
654
+ ConsoleColor["Reverse"] = "\u001B[7m";
655
+ ConsoleColor["Hidden"] = "\u001B[8m";
656
+ ConsoleColor["FgBlack"] = "\u001B[30m";
657
+ ConsoleColor["FgRed"] = "\u001B[31m";
658
+ ConsoleColor["FgGreen"] = "\u001B[32m";
659
+ ConsoleColor["FgYellow"] = "\u001B[33m";
660
+ ConsoleColor["FgBlue"] = "\u001B[34m";
661
+ ConsoleColor["FgMagenta"] = "\u001B[35m";
662
+ ConsoleColor["FgCyan"] = "\u001B[36m";
663
+ ConsoleColor["FgWhite"] = "\u001B[37m";
664
+ ConsoleColor["BgBlack"] = "\u001B[40m";
665
+ ConsoleColor["BgRed"] = "\u001B[41m";
666
+ ConsoleColor["BgGreen"] = "\u001B[42m";
667
+ ConsoleColor["BgYellow"] = "\u001B[43m";
668
+ ConsoleColor["BgBlue"] = "\u001B[44m";
669
+ ConsoleColor["BgMagenta"] = "\u001B[45m";
670
+ ConsoleColor["BgCyan"] = "\u001B[46m";
671
+ ConsoleColor["BgWhite"] = "\u001B[47m";
672
+ })(ConsoleColor || (ConsoleColor = {}));
673
+ const defaultColors = {
674
+ keyColor: ConsoleColor.Dim,
675
+ numberColor: ConsoleColor.FgBlue,
676
+ stringColor: ConsoleColor.FgCyan,
677
+ trueColor: ConsoleColor.FgGreen,
678
+ falseColor: ConsoleColor.FgRed,
679
+ nullColor: ConsoleColor.BgMagenta
680
+ };
681
+ function jsonHighlight(input, colorOptions) {
682
+ const colors = Object.assign({}, defaultColors, colorOptions);
683
+ const json = (isString(input) ? input : JSON.stringify(input, null, 2)).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
684
+ return json.replace(/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+]?\d+)?)/g, (match) => {
685
+ let color = colors.numberColor;
686
+ if (/^"/.test(match)) {
687
+ if (/:$/.test(match)) {
688
+ color = colors.keyColor;
689
+ }
690
+ else {
691
+ color = colors.stringColor;
692
+ match = '"' + match.substr(1, match.length - 2) + '"';
693
+ }
694
+ }
695
+ else {
696
+ color = /true/.test(match)
697
+ ? colors.trueColor
698
+ : /false/.test(match)
699
+ ? colors.falseColor
700
+ : /null/.test(match)
701
+ ? colors.nullColor
702
+ : color;
703
+ }
704
+ return `${color}${match}${ConsoleColor.Reset}`;
705
+ });
643
706
  }
644
707
 
645
708
  var __decorate$x = (this && this.__decorate) || function (decorators, target, key, desc) {
@@ -750,7 +813,7 @@ var __decorate$w = (this && this.__decorate) || function (decorators, target, ke
750
813
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
751
814
  return c > 3 && r && Object.defineProperty(target, key, r), r;
752
815
  };
753
- var __awaiter$u = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
816
+ var __awaiter$v = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
754
817
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
755
818
  return new (P || (P = Promise))(function (resolve, reject) {
756
819
  function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
@@ -786,7 +849,7 @@ let AssetProcessor = AssetProcessor_1 = class AssetProcessor {
786
849
  }
787
850
  static fileTypeFromBuffer(buffer) {
788
851
  var _a;
789
- return __awaiter$u(this, void 0, void 0, function* () {
852
+ return __awaiter$v(this, void 0, void 0, function* () {
790
853
  const type = ((_a = yield fromBuffer(buffer)) !== null && _a !== void 0 ? _a : { ext: "txt", mime: "text/plain" });
791
854
  if (AssetProcessor_1.checkTextFileType(type)) {
792
855
  return AssetProcessor_1.fixTextFileType(type, buffer);
@@ -813,9 +876,9 @@ let AssetProcessor = AssetProcessor_1 = class AssetProcessor {
813
876
  return imageTypes.indexOf(contentType) >= 0;
814
877
  }
815
878
  static copyImageMeta(buffer, metadata, fileType) {
816
- return __awaiter$u(this, void 0, void 0, function* () {
879
+ return __awaiter$v(this, void 0, void 0, function* () {
817
880
  if (fileType.mime === "image/svg+xml") {
818
- const match = /<svg(.+)>/gi.exec(buffer.toString("utf8"));
881
+ const match = /<svg([^<>]+)>/gi.exec(buffer.toString("utf8"));
819
882
  if (match && match.length > 1) {
820
883
  const attrs = match[1].match(/([a-z]+)="([^"]+)"/gi);
821
884
  attrs.forEach(attr => {
@@ -852,7 +915,7 @@ let AssetProcessor = AssetProcessor_1 = class AssetProcessor {
852
915
  });
853
916
  }
854
917
  process(buffer, metadata, fileType) {
855
- return __awaiter$u(this, void 0, void 0, function* () {
918
+ return __awaiter$v(this, void 0, void 0, function* () {
856
919
  if (AssetProcessor_1.isImage(fileType.mime)) {
857
920
  buffer = yield AssetProcessor_1.copyImageMeta(buffer, metadata, fileType);
858
921
  }
@@ -929,7 +992,7 @@ var __decorate$u = (this && this.__decorate) || function (decorators, target, ke
929
992
  var __metadata$o = (this && this.__metadata) || function (k, v) {
930
993
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
931
994
  };
932
- var __awaiter$t = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
995
+ var __awaiter$u = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
933
996
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
934
997
  return new (P || (P = Promise))(function (resolve, reject) {
935
998
  function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
@@ -955,7 +1018,7 @@ let MongoConnector = class MongoConnector {
955
1018
  return this.fsBucket;
956
1019
  }
957
1020
  connect() {
958
- return __awaiter$t(this, void 0, void 0, function* () {
1021
+ return __awaiter$u(this, void 0, void 0, function* () {
959
1022
  if (this.db)
960
1023
  return this.db;
961
1024
  this.conn = (yield connect(this.configuration.resolve("mongoUri"), {
@@ -976,7 +1039,7 @@ MongoConnector = __decorate$u([
976
1039
  __metadata$o("design:paramtypes", [Configuration])
977
1040
  ], MongoConnector);
978
1041
 
979
- var __awaiter$s = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
1042
+ var __awaiter$t = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
980
1043
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
981
1044
  return new (P || (P = Promise))(function (resolve, reject) {
982
1045
  function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
@@ -998,7 +1061,7 @@ class BaseEntity {
998
1061
  return this.collection.updateOne({ _id: this.mId }, { $set: this.toJSON() });
999
1062
  }
1000
1063
  load() {
1001
- return __awaiter$s(this, void 0, void 0, function* () {
1064
+ return __awaiter$t(this, void 0, void 0, function* () {
1002
1065
  const res = yield this.collection.findOne({ _id: this.mId });
1003
1066
  this.deleted = !res;
1004
1067
  this.data = res || {};
@@ -1013,7 +1076,7 @@ class BaseEntity {
1013
1076
  }
1014
1077
  }
1015
1078
 
1016
- var __awaiter$r = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
1079
+ var __awaiter$s = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
1017
1080
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
1018
1081
  return new (P || (P = Promise))(function (resolve, reject) {
1019
1082
  function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
@@ -1054,13 +1117,14 @@ class Asset extends BaseEntity {
1054
1117
  };
1055
1118
  }
1056
1119
  static toImage(stream, meta, params) {
1057
- return __awaiter$r(this, void 0, void 0, function* () {
1120
+ return __awaiter$s(this, void 0, void 0, function* () {
1058
1121
  params = params || {};
1059
1122
  // Get default crop info
1060
1123
  const crop = Asset.toCropRegion(meta.crop);
1061
- // Return back the stream if there is no params and no default crop exists
1062
- if (Object.keys(params).length == 0 && !crop)
1124
+ // Return the stream if there is no params and no default crop exists
1125
+ if ((meta === null || meta === void 0 ? void 0 : meta.extension) === "svg" || (Object.keys(params).length == 0 && !crop)) {
1063
1126
  return stream;
1127
+ }
1064
1128
  // Parse params
1065
1129
  params.rotation = isNaN(params.rotation) ? 0 : Math.round(params.rotation / 90) * 90;
1066
1130
  params.canvasScaleX = isNaN(params.canvasScaleX) ? 1 : Number(params.canvasScaleX);
@@ -1075,51 +1139,43 @@ class Asset extends BaseEntity {
1075
1139
  const cropBefore = Asset.toCropRegion(params.cropBefore || (params.crop ? meta.cropBefore : null));
1076
1140
  const cropAfter = Asset.toCropRegion(params.cropAfter || (params.crop ? meta.cropAfter : null));
1077
1141
  // Get metadata
1078
- const imgMeta = yield sharp$2(buffer).metadata();
1079
- let width = imgMeta.width;
1080
- let height = imgMeta.height;
1142
+ let img = sharp$2(buffer);
1143
+ let { width, height } = yield img.metadata();
1081
1144
  // Crop before resize
1082
1145
  if (cropBefore) {
1083
- buffer = yield sharp$2(buffer)
1084
- .extract(cropBefore)
1085
- .toBuffer();
1086
1146
  width = cropBefore.width;
1087
1147
  height = cropBefore.height;
1148
+ img = img.extract(cropBefore);
1088
1149
  }
1089
1150
  else if (crop) {
1090
- buffer = yield sharp$2(buffer)
1091
- .extract(crop)
1092
- .toBuffer();
1093
1151
  width = crop.width;
1094
1152
  height = crop.height;
1153
+ img = img.extract(crop);
1095
1154
  }
1096
1155
  // Resize canvas
1097
- if (params.canvasScaleX !== 1 || params.canvasScaleY !== 1) {
1156
+ const canvasScaleX = (meta === null || meta === void 0 ? void 0 : meta.canvasScaleX) || 1;
1157
+ const canvasScaleY = (meta === null || meta === void 0 ? void 0 : meta.canvasScaleY) || 1;
1158
+ if (params.canvasScaleX !== canvasScaleX || params.canvasScaleY !== canvasScaleY) {
1098
1159
  width = Math.round(width * params.canvasScaleX);
1099
1160
  height = Math.round(height * params.canvasScaleY);
1100
- buffer = yield sharp$2(buffer)
1101
- .resize({ width, height, background: "#00000000", fit: "contain" })
1102
- .toBuffer();
1161
+ img = img.resize({ width, height, background: "#00000000", fit: "contain" });
1103
1162
  }
1104
1163
  // Resize image
1105
1164
  if (params.scaleX !== 1 || params.scaleY !== 1) {
1106
1165
  width = Math.round(width * params.scaleX);
1107
1166
  height = Math.round(height * params.scaleY);
1108
- buffer = yield sharp$2(buffer)
1109
- .resize({ width, height, background: "#00000000", fit: "fill" })
1110
- .toBuffer();
1167
+ img = img.resize({ width, height, background: "#00000000", fit: "fill" });
1111
1168
  }
1112
1169
  // Crop after resize
1113
1170
  if (cropAfter) {
1114
- buffer = yield sharp$2(buffer)
1115
- .extract(cropAfter)
1116
- .toBuffer();
1171
+ img = img.extract(cropAfter);
1117
1172
  }
1118
1173
  // Rotate
1119
1174
  if (params.rotation !== 0) {
1120
- buffer = yield sharp$2(buffer).rotate(params.rotation).toBuffer();
1175
+ buffer = yield img.toBuffer();
1176
+ img = sharp$2(buffer).rotate(params.rotation);
1121
1177
  }
1122
- return bufferToStream(buffer);
1178
+ return bufferToStream(yield img.toBuffer());
1123
1179
  }
1124
1180
  catch (e) {
1125
1181
  console.log("Asset image conversion error", e);
@@ -1140,7 +1196,7 @@ class Asset extends BaseEntity {
1140
1196
  return this.bucket.openDownloadStream(this.mId);
1141
1197
  }
1142
1198
  unlink() {
1143
- return __awaiter$r(this, void 0, void 0, function* () {
1199
+ return __awaiter$s(this, void 0, void 0, function* () {
1144
1200
  return deleteFromBucket(this.bucket, this.mId);
1145
1201
  });
1146
1202
  }
@@ -1148,7 +1204,7 @@ class Asset extends BaseEntity {
1148
1204
  return streamToBuffer(this.stream);
1149
1205
  }
1150
1206
  download(metadata) {
1151
- return __awaiter$r(this, void 0, void 0, function* () {
1207
+ return __awaiter$s(this, void 0, void 0, function* () {
1152
1208
  metadata = Object.assign(this.metadata, metadata || {});
1153
1209
  metadata.downloadCount = isNaN(metadata.downloadCount) || !metadata.firstDownload
1154
1210
  ? 1
@@ -1160,17 +1216,79 @@ class Asset extends BaseEntity {
1160
1216
  });
1161
1217
  }
1162
1218
  getImage(params = null) {
1163
- return __awaiter$r(this, void 0, void 0, function* () {
1219
+ return __awaiter$s(this, void 0, void 0, function* () {
1164
1220
  return Asset.toImage(this.stream, this.metadata, params);
1165
1221
  });
1166
1222
  }
1167
1223
  downloadImage(params, metadata) {
1168
- return __awaiter$r(this, void 0, void 0, function* () {
1224
+ return __awaiter$s(this, void 0, void 0, function* () {
1169
1225
  return Asset.toImage(yield this.download(metadata), this.metadata, params);
1170
1226
  });
1171
1227
  }
1172
1228
  }
1173
1229
 
1230
+ var __awaiter$r = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
1231
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
1232
+ return new (P || (P = Promise))(function (resolve, reject) {
1233
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
1234
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
1235
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
1236
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
1237
+ });
1238
+ };
1239
+ class TempAsset {
1240
+ constructor(buffer, filename, contentType, metadata) {
1241
+ this.buffer = buffer;
1242
+ this.filename = filename;
1243
+ this.contentType = contentType;
1244
+ this.metadata = metadata;
1245
+ this.id = new ObjectId().toHexString();
1246
+ }
1247
+ get stream() {
1248
+ return bufferToStream(this.buffer);
1249
+ }
1250
+ unlink() {
1251
+ return __awaiter$r(this, void 0, void 0, function* () {
1252
+ throw new Error(`Temp asset '${this.id}' can not be removed!`);
1253
+ });
1254
+ }
1255
+ getBuffer() {
1256
+ return __awaiter$r(this, void 0, void 0, function* () {
1257
+ return this.buffer;
1258
+ });
1259
+ }
1260
+ download(metadata) {
1261
+ return __awaiter$r(this, void 0, void 0, function* () {
1262
+ return this.stream;
1263
+ });
1264
+ }
1265
+ downloadImage(params, metadata) {
1266
+ Object.assign(this.metadata, metadata || {});
1267
+ return Asset.toImage(this.stream, this.metadata, params);
1268
+ }
1269
+ getImage(params) {
1270
+ return this.downloadImage(params);
1271
+ }
1272
+ save() {
1273
+ return __awaiter$r(this, void 0, void 0, function* () {
1274
+ return this;
1275
+ });
1276
+ }
1277
+ load() {
1278
+ return __awaiter$r(this, void 0, void 0, function* () {
1279
+ return this;
1280
+ });
1281
+ }
1282
+ toJSON() {
1283
+ return {
1284
+ id: this.id,
1285
+ filename: this.filename,
1286
+ contentType: this.contentType,
1287
+ metadata: this.metadata
1288
+ };
1289
+ }
1290
+ }
1291
+
1174
1292
  var __decorate$t = (this && this.__decorate) || function (decorators, target, key, desc) {
1175
1293
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1176
1294
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -1238,6 +1356,27 @@ let Assets = class Assets {
1238
1356
  return this.writeBuffer(buffer, metadata);
1239
1357
  });
1240
1358
  }
1359
+ download(url, contentType = null) {
1360
+ return __awaiter$q(this, void 0, void 0, function* () {
1361
+ let buffer = (yield axios({ url, responseType: "arraybuffer" })).data;
1362
+ let fileType = { ext: "", mime: contentType };
1363
+ try {
1364
+ fileType = yield AssetProcessor.fileTypeFromBuffer(buffer);
1365
+ }
1366
+ catch (e) {
1367
+ if (!fileType.mime) {
1368
+ throw `Can't determine mime type`;
1369
+ }
1370
+ console.log(`Can't determine mime type`, e);
1371
+ }
1372
+ const metadata = {
1373
+ filename: url,
1374
+ extension: (fileType.ext || "").trim()
1375
+ };
1376
+ buffer = yield this.assetProcessor.process(buffer, metadata, fileType);
1377
+ return new TempAsset(buffer, url, fileType.mime, metadata);
1378
+ });
1379
+ }
1241
1380
  read(id) {
1242
1381
  return __awaiter$q(this, void 0, void 0, function* () {
1243
1382
  return !id ? null : this.find({ _id: new ObjectId(id) });
@@ -1416,15 +1555,15 @@ var __awaiter$o = (this && this.__awaiter) || function (thisArg, _arguments, P,
1416
1555
  step((generator = generator.apply(thisArg, _arguments || [])).next());
1417
1556
  });
1418
1557
  };
1419
- const IORedis = ioredis;
1420
1558
  let JobManager = class JobManager {
1421
1559
  constructor(config, container, jobTypes) {
1422
1560
  this.config = config;
1423
1561
  this.container = container;
1424
1562
  this.jobTypes = jobTypes || [];
1425
1563
  this.jobs = this.jobTypes.reduce((res, jobType) => {
1426
- res[getConstructorName(jobType)] = {
1427
- perform: this.toPerformFunction(jobType)
1564
+ res[getConstructorName(jobType)] = (jobParams) => {
1565
+ const job = this.resolveJobInstance(jobType, jobParams);
1566
+ return job.process();
1428
1567
  };
1429
1568
  return res;
1430
1569
  }, {});
@@ -1442,31 +1581,25 @@ let JobManager = class JobManager {
1442
1581
  return instance.process();
1443
1582
  });
1444
1583
  }
1445
- enqueueWithName(name, params = {}, que = "main") {
1584
+ enqueueWithName(name, params = {}) {
1446
1585
  return __awaiter$o(this, void 0, void 0, function* () {
1447
1586
  const jobName = yield this.tryResolveFromName(name, params);
1448
- yield this.queue.enqueue(que, jobName, [params]);
1449
- });
1450
- }
1451
- enqueue(jobType, params = {}, que = "main") {
1452
- return __awaiter$o(this, void 0, void 0, function* () {
1453
- const jobName = yield this.tryResolveAndConnect(jobType, params);
1454
- yield this.queue.enqueue(que, jobName, [params]);
1587
+ return this.sendToWorkers(jobName, params);
1455
1588
  });
1456
1589
  }
1457
- enqueueAt(timestamp, jobType, params = {}, que = "main") {
1590
+ enqueue(jobType, params = {}) {
1458
1591
  return __awaiter$o(this, void 0, void 0, function* () {
1459
1592
  const jobName = yield this.tryResolveAndConnect(jobType, params);
1460
- yield this.queue.enqueueAt(timestamp, que, jobName, [params]);
1593
+ return this.sendToWorkers(jobName, params);
1461
1594
  });
1462
1595
  }
1463
- enqueueIn(time, jobType, params = {}, que = "main") {
1596
+ sendToWorkers(jobName, params) {
1464
1597
  return __awaiter$o(this, void 0, void 0, function* () {
1465
- const jobName = yield this.tryResolveAndConnect(jobType, params);
1466
- yield this.queue.enqueueIn(time, que, jobName, [params]);
1598
+ const publisher = yield this.scheduler;
1599
+ yield publisher.send([jobName, JSON.stringify(params), new ObjectId().toHexString()]);
1467
1600
  });
1468
1601
  }
1469
- schedule(minute, hour, dayOfMonth, month, dayOfWeek, jobType, params = {}, que = "main") {
1602
+ schedule(minute, hour, dayOfMonth, month, dayOfWeek, jobType, params = {}) {
1470
1603
  const expression = [minute, hour, dayOfMonth, month, dayOfWeek].map(t => {
1471
1604
  if (isObject(t)) {
1472
1605
  const range = t;
@@ -1483,19 +1616,38 @@ let JobManager = class JobManager {
1483
1616
  return null;
1484
1617
  }
1485
1618
  return schedule(expression, () => {
1486
- this.enqueue(jobType, params, que).catch(e => {
1619
+ this.enqueue(jobType, params).catch(e => {
1487
1620
  console.log(`Can't enqueue job: '${jobName}' because: ${e}`);
1488
1621
  });
1489
1622
  });
1490
1623
  }
1491
1624
  startProcessing() {
1492
- return __awaiter$o(this, void 0, void 0, function* () {
1493
- this.initialize();
1494
- yield this.worker.connect();
1495
- yield this.worker.start();
1496
- yield this.scheduler.connect();
1497
- yield this.scheduler.start();
1498
- });
1625
+ const host = this.config.resolve("zmqRemoteHost");
1626
+ this.worker = socket("pull");
1627
+ this.worker.connect(host);
1628
+ this.worker.on("message", (name, args, uniqueId) => __awaiter$o(this, void 0, void 0, function* () {
1629
+ try {
1630
+ const jobName = name.toString("utf8");
1631
+ const jobParams = JSON.parse(args.toString("utf8"));
1632
+ const timerId = uniqueId === null || uniqueId === void 0 ? void 0 : uniqueId.toString("utf8");
1633
+ const jobNameLog = `\x1b[36m"${jobName}"\x1b[0m`;
1634
+ const jobArgsLog = `\n${jsonHighlight(jobParams)}\n`;
1635
+ console.time(timerId);
1636
+ console.timeLog(timerId, `Started working on background job: ${jobNameLog} with args: ${jobArgsLog}`);
1637
+ try {
1638
+ yield Promise.race([this.jobs[jobName](jobParams), promiseTimeout(15000, true)]);
1639
+ console.timeLog(timerId, `Finished working on background job: ${jobNameLog} with args: ${jobArgsLog}`);
1640
+ }
1641
+ catch (e) {
1642
+ console.timeLog(timerId, `Background job failed: ${jobNameLog} with args: ${jobArgsLog}${e.message}\n\n`);
1643
+ }
1644
+ console.timeEnd(timerId);
1645
+ }
1646
+ catch (e) {
1647
+ console.log(`Failed to start job: ${e.message}`);
1648
+ }
1649
+ }));
1650
+ console.log(`Waiting for jobs at: ${host}`);
1499
1651
  }
1500
1652
  tryResolve(jobType, params) {
1501
1653
  const jobName = getConstructorName(jobType);
@@ -1510,47 +1662,6 @@ let JobManager = class JobManager {
1510
1662
  }
1511
1663
  return jobName;
1512
1664
  }
1513
- initialize() {
1514
- if (this.queue)
1515
- return;
1516
- const config = this.config;
1517
- const options = { password: config.resolve("redisPassword") };
1518
- const sentinels = config.resolve("redisSentinels");
1519
- const redis = !sentinels
1520
- ? null
1521
- : new IORedis({
1522
- sentinels,
1523
- name: config.resolve("redisCluster"),
1524
- });
1525
- const connection = {
1526
- pkg: "ioredis",
1527
- host: config.resolve("redisHost"),
1528
- password: options.password,
1529
- port: config.resolve("redisPort"),
1530
- namespace: config.resolve("redisNamespace"),
1531
- redis,
1532
- options
1533
- };
1534
- const queues = config.resolve("workQueues");
1535
- this.queue = new Queue({ connection }, this.jobs);
1536
- this.worker = new Worker({ connection, queues }, this.jobs);
1537
- this.worker.on("job", (queue, job) => {
1538
- console.log(`working job ${queue} ${JSON.stringify(job)}`);
1539
- });
1540
- this.worker.on("reEnqueue", (queue, job, plugin) => {
1541
- console.log(`reEnqueue job (${plugin}) ${queue} ${JSON.stringify(job)}`);
1542
- });
1543
- this.worker.on("success", (queue, job, result, duration) => {
1544
- console.log(`job success ${queue} ${JSON.stringify(job)} >> ${result} (${duration}ms)`);
1545
- });
1546
- this.worker.on("failure", (queue, job, failure, duration) => {
1547
- console.log(`job failure ${queue} ${JSON.stringify(job)} >> ${failure} (${duration}ms)`);
1548
- });
1549
- this.worker.on("error", (error, queue, job) => {
1550
- console.log(`error ${queue} ${JSON.stringify(job)} >> ${error}`);
1551
- });
1552
- this.scheduler = new Scheduler({ connection }, this.jobs);
1553
- }
1554
1665
  tryResolveFromName(jobName, params) {
1555
1666
  const jobType = this.jobTypes.find(type => {
1556
1667
  return getConstructorName(type) == jobName;
@@ -1562,10 +1673,14 @@ let JobManager = class JobManager {
1562
1673
  }
1563
1674
  tryResolveAndConnect(jobType, params) {
1564
1675
  return __awaiter$o(this, void 0, void 0, function* () {
1565
- this.initialize();
1566
- const jobName = this.tryResolve(jobType, params);
1567
- yield this.queue.connect();
1568
- return jobName;
1676
+ this.scheduler = this.scheduler || new Promise((resolve) => __awaiter$o(this, void 0, void 0, function* () {
1677
+ const port = this.config.resolve("zmqPort");
1678
+ const publisher = socket("push");
1679
+ yield publisher.bind(`tcp://0.0.0.0:${port}`);
1680
+ console.log(`Publisher bound to port: ${port}`);
1681
+ resolve(publisher);
1682
+ }));
1683
+ return this.tryResolve(jobType, params);
1569
1684
  });
1570
1685
  }
1571
1686
  resolveJobInstance(jobType, params) {
@@ -1576,12 +1691,6 @@ let JobManager = class JobManager {
1576
1691
  container.register(jobType, jobType);
1577
1692
  return container.resolve(jobType);
1578
1693
  }
1579
- toPerformFunction(jobType) {
1580
- return (jobParams) => {
1581
- const job = this.resolveJobInstance(jobType, jobParams);
1582
- return job.process();
1583
- };
1584
- }
1585
1694
  };
1586
1695
  JobManager = __decorate$s([
1587
1696
  injectable(),
@@ -2903,7 +3012,9 @@ let AssetsController = class AssetsController {
2903
3012
  getImageRotation(id, params, res, rotation = 0) {
2904
3013
  return __awaiter$7(this, void 0, void 0, function* () {
2905
3014
  const asset = yield this.getAsset("Image", id, params.lazy, res);
2906
- params.rotation = params.rotation || rotation;
3015
+ if (rotation !== 0) {
3016
+ params.rotation = params.rotation || rotation;
3017
+ }
2907
3018
  return asset.downloadImage(params);
2908
3019
  });
2909
3020
  }
@@ -3714,20 +3825,8 @@ function createServices() {
3714
3825
  new Parameter("mongoPassword", null),
3715
3826
  new Parameter("nodeEnv", "development"),
3716
3827
  new Parameter("appPort", 80),
3717
- new Parameter("redisHost", "127.0.0.1"),
3718
- new Parameter("redisPort", 6379),
3719
- new Parameter("redisPassword", "123456"),
3720
- new Parameter("redisNamespace", "resque"),
3721
- new Parameter("redisCluster", "mymaster"),
3722
- new Parameter("redisSentinels", null, value => {
3723
- if (!value)
3724
- return null;
3725
- return value.split(", ").map(item => {
3726
- const values = item.split(":");
3727
- return { host: values[0], port: Number(values[1]) };
3728
- });
3729
- }),
3730
- new Parameter("workQueues", ["main"]),
3828
+ new Parameter("zmqPort", 3000),
3829
+ new Parameter("zmqRemoteHost", "tcp://127.0.0.1:3000"),
3731
3830
  new Parameter("isWorker", false),
3732
3831
  new Parameter("mainEndpoint", ""),
3733
3832
  new Parameter("idChars", "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"),
@@ -3933,5 +4032,5 @@ function setupBackend(config, providers, parent) {
3933
4032
  * Generated bundle index. Do not edit.
3934
4033
  */
3935
4034
 
3936
- export { AssetProcessor, AssetResolver, Assets, AuthController, BackendProvider, Cache, CacheProcessor, Configuration, DI_CONTAINER, EXPRESS, EndpointProvider, ErrorHandlerMiddleware, FIXTURE, Fixtures, Gallery, GalleryCache, GalleryController, HTTP_SERVER, IdGenerator, IsFile, IsObjectId, JOB, JobManager, LanguageMiddleware, LazyAssetGenerator, LazyAssets, MailSender, MemoryCache, MongoConnector, PARAMETER, Parameter, Progresses, ResolveEntity, SOCKET_SERVER, TemplateRenderer, TranslationProvider, Translator, Type, UserManager, assign, broadcast, bufferToStream, convertValue, copy, copyStream, createServices, createTransformer, deleteFile, deleteFromBucket, filter, firstItem, getConstructorName, getExtension, getFileName, getFunctionParams, getType, getValue, groupBy, hydratePopulated, idToString, injectServices, isArray, isBoolean, isConstructor, isDate, isDefined, isFunction, isInterface, isNullOrUndefined, isObject, isPrimitive, isString, isType, lastItem, lcFirst, lookupPipelines, md5, mkdirRecursive, multiSubscription, observableFromFunction, padLeft, padRight, paginate, paginateAggregations, promiseTimeout, proxyFunction, proxyFunctions, rand, random, readAndDeleteFile, readFile, runCommand, setupBackend, streamToBuffer, ucFirst, valueToPromise, writeFile };
4035
+ export { AssetProcessor, AssetResolver, Assets, AuthController, BackendProvider, Cache, CacheProcessor, Configuration, ConsoleColor, DI_CONTAINER, EXPRESS, EndpointProvider, ErrorHandlerMiddleware, FIXTURE, Fixtures, Gallery, GalleryCache, GalleryController, HTTP_SERVER, IdGenerator, IsFile, IsObjectId, JOB, JobManager, LanguageMiddleware, LazyAssetGenerator, LazyAssets, MailSender, MemoryCache, MongoConnector, PARAMETER, Parameter, Progresses, ResolveEntity, SOCKET_SERVER, TemplateRenderer, TranslationProvider, Translator, Type, UserManager, assign, broadcast, bufferToStream, convertValue, copy, copyStream, createServices, createTransformer, deleteFile, deleteFromBucket, filter, firstItem, getConstructorName, getExtension, getFileName, getFunctionParams, getType, getValue, groupBy, hydratePopulated, idToString, injectServices, isArray, isBoolean, isConstructor, isDate, isDefined, isFunction, isInterface, isNullOrUndefined, isObject, isPrimitive, isString, isType, jsonHighlight, lastItem, lcFirst, lookupPipelines, md5, mkdirRecursive, multiSubscription, observableFromFunction, padLeft, padRight, paginate, paginateAggregations, promiseTimeout, proxyFunction, proxyFunctions, rand, random, readAndDeleteFile, readFile, runCommand, setupBackend, streamToBuffer, ucFirst, valueToPromise, writeFile };
3937
4036
  //# sourceMappingURL=stemy-backend.js.map