@stemy/backend 2.9.7 → 3.0.1
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/bundles/stemy-backend.umd.js +344 -228
- package/bundles/stemy-backend.umd.js.map +1 -1
- package/bundles/stemy-backend.umd.min.js +1 -1
- package/bundles/stemy-backend.umd.min.js.map +1 -1
- package/common-types.d.ts +7 -5
- package/esm2015/common-types.js +1 -1
- package/esm2015/public_api.js +4 -16
- package/esm2015/rest-controllers/assets.controller.js +4 -2
- package/esm2015/services/assets.js +23 -1
- package/esm2015/services/entities/asset.js +17 -24
- package/esm2015/services/entities/lazy-asset.js +5 -5
- package/esm2015/services/entities/temp-asset.js +65 -0
- package/esm2015/services/job-manager.js +50 -80
- package/esm2015/utils.js +70 -4
- package/fesm2015/stemy-backend.js +244 -143
- package/fesm2015/stemy-backend.js.map +1 -1
- package/package.json +2 -3
- package/public_api.d.ts +1 -1
- package/services/assets.d.ts +1 -0
- package/services/entities/asset.d.ts +2 -2
- package/services/entities/lazy-asset.d.ts +1 -1
- package/services/entities/temp-asset.d.ts +20 -0
- package/services/job-manager.d.ts +11 -13
- package/stemy-backend.metadata.json +1 -1
- package/utils.d.ts +37 -1
|
@@ -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
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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
|
-
|
|
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$
|
|
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,68 @@ 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["FgDefault"] = "\u001B[38m";
|
|
665
|
+
ConsoleColor["BgBlack"] = "\u001B[40m";
|
|
666
|
+
ConsoleColor["BgRed"] = "\u001B[41m";
|
|
667
|
+
ConsoleColor["BgGreen"] = "\u001B[42m";
|
|
668
|
+
ConsoleColor["BgYellow"] = "\u001B[43m";
|
|
669
|
+
ConsoleColor["BgBlue"] = "\u001B[44m";
|
|
670
|
+
ConsoleColor["BgMagenta"] = "\u001B[45m";
|
|
671
|
+
ConsoleColor["BgCyan"] = "\u001B[46m";
|
|
672
|
+
ConsoleColor["BgWhite"] = "\u001B[47m";
|
|
673
|
+
ConsoleColor["BgDefault"] = "\u001B[48m";
|
|
674
|
+
})(ConsoleColor || (ConsoleColor = {}));
|
|
675
|
+
const defaultColors = {
|
|
676
|
+
keyColor: ConsoleColor.FgWhite,
|
|
677
|
+
numberColor: ConsoleColor.FgBlue,
|
|
678
|
+
stringColor: ConsoleColor.FgYellow,
|
|
679
|
+
trueColor: ConsoleColor.FgGreen,
|
|
680
|
+
falseColor: ConsoleColor.FgRed,
|
|
681
|
+
nullColor: ConsoleColor.BgMagenta
|
|
682
|
+
};
|
|
683
|
+
function jsonHighlight(input, colorOptions) {
|
|
684
|
+
const colors = Object.assign({}, defaultColors, colorOptions);
|
|
685
|
+
const json = (isString(input) ? input : JSON.stringify(input, null, 2)).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
|
|
686
|
+
return json.replace(/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+]?\d+)?)/g, (match) => {
|
|
687
|
+
let color = colors.numberColor;
|
|
688
|
+
if (/^"/.test(match)) {
|
|
689
|
+
if (/:$/.test(match)) {
|
|
690
|
+
color = colors.keyColor;
|
|
691
|
+
}
|
|
692
|
+
else {
|
|
693
|
+
color = colors.stringColor;
|
|
694
|
+
match = '"' + match.substr(1, match.length - 2) + '"';
|
|
695
|
+
}
|
|
696
|
+
}
|
|
697
|
+
else {
|
|
698
|
+
color = /true/.test(match)
|
|
699
|
+
? colors.trueColor
|
|
700
|
+
: /false/.test(match)
|
|
701
|
+
? colors.falseColor
|
|
702
|
+
: /null/.test(match)
|
|
703
|
+
? colors.nullColor
|
|
704
|
+
: color;
|
|
705
|
+
}
|
|
706
|
+
return `${color}${match}${ConsoleColor.Reset}`;
|
|
707
|
+
});
|
|
643
708
|
}
|
|
644
709
|
|
|
645
710
|
var __decorate$x = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
@@ -750,7 +815,7 @@ var __decorate$w = (this && this.__decorate) || function (decorators, target, ke
|
|
|
750
815
|
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
816
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
752
817
|
};
|
|
753
|
-
var __awaiter$
|
|
818
|
+
var __awaiter$v = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
754
819
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
755
820
|
return new (P || (P = Promise))(function (resolve, reject) {
|
|
756
821
|
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
@@ -786,7 +851,7 @@ let AssetProcessor = AssetProcessor_1 = class AssetProcessor {
|
|
|
786
851
|
}
|
|
787
852
|
static fileTypeFromBuffer(buffer) {
|
|
788
853
|
var _a;
|
|
789
|
-
return __awaiter$
|
|
854
|
+
return __awaiter$v(this, void 0, void 0, function* () {
|
|
790
855
|
const type = ((_a = yield fromBuffer(buffer)) !== null && _a !== void 0 ? _a : { ext: "txt", mime: "text/plain" });
|
|
791
856
|
if (AssetProcessor_1.checkTextFileType(type)) {
|
|
792
857
|
return AssetProcessor_1.fixTextFileType(type, buffer);
|
|
@@ -813,7 +878,7 @@ let AssetProcessor = AssetProcessor_1 = class AssetProcessor {
|
|
|
813
878
|
return imageTypes.indexOf(contentType) >= 0;
|
|
814
879
|
}
|
|
815
880
|
static copyImageMeta(buffer, metadata, fileType) {
|
|
816
|
-
return __awaiter$
|
|
881
|
+
return __awaiter$v(this, void 0, void 0, function* () {
|
|
817
882
|
if (fileType.mime === "image/svg+xml") {
|
|
818
883
|
const match = /<svg([^<>]+)>/gi.exec(buffer.toString("utf8"));
|
|
819
884
|
if (match && match.length > 1) {
|
|
@@ -852,7 +917,7 @@ let AssetProcessor = AssetProcessor_1 = class AssetProcessor {
|
|
|
852
917
|
});
|
|
853
918
|
}
|
|
854
919
|
process(buffer, metadata, fileType) {
|
|
855
|
-
return __awaiter$
|
|
920
|
+
return __awaiter$v(this, void 0, void 0, function* () {
|
|
856
921
|
if (AssetProcessor_1.isImage(fileType.mime)) {
|
|
857
922
|
buffer = yield AssetProcessor_1.copyImageMeta(buffer, metadata, fileType);
|
|
858
923
|
}
|
|
@@ -929,7 +994,7 @@ var __decorate$u = (this && this.__decorate) || function (decorators, target, ke
|
|
|
929
994
|
var __metadata$o = (this && this.__metadata) || function (k, v) {
|
|
930
995
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
931
996
|
};
|
|
932
|
-
var __awaiter$
|
|
997
|
+
var __awaiter$u = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
933
998
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
934
999
|
return new (P || (P = Promise))(function (resolve, reject) {
|
|
935
1000
|
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
@@ -955,7 +1020,7 @@ let MongoConnector = class MongoConnector {
|
|
|
955
1020
|
return this.fsBucket;
|
|
956
1021
|
}
|
|
957
1022
|
connect() {
|
|
958
|
-
return __awaiter$
|
|
1023
|
+
return __awaiter$u(this, void 0, void 0, function* () {
|
|
959
1024
|
if (this.db)
|
|
960
1025
|
return this.db;
|
|
961
1026
|
this.conn = (yield connect(this.configuration.resolve("mongoUri"), {
|
|
@@ -976,7 +1041,7 @@ MongoConnector = __decorate$u([
|
|
|
976
1041
|
__metadata$o("design:paramtypes", [Configuration])
|
|
977
1042
|
], MongoConnector);
|
|
978
1043
|
|
|
979
|
-
var __awaiter$
|
|
1044
|
+
var __awaiter$t = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
980
1045
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
981
1046
|
return new (P || (P = Promise))(function (resolve, reject) {
|
|
982
1047
|
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
@@ -998,7 +1063,7 @@ class BaseEntity {
|
|
|
998
1063
|
return this.collection.updateOne({ _id: this.mId }, { $set: this.toJSON() });
|
|
999
1064
|
}
|
|
1000
1065
|
load() {
|
|
1001
|
-
return __awaiter$
|
|
1066
|
+
return __awaiter$t(this, void 0, void 0, function* () {
|
|
1002
1067
|
const res = yield this.collection.findOne({ _id: this.mId });
|
|
1003
1068
|
this.deleted = !res;
|
|
1004
1069
|
this.data = res || {};
|
|
@@ -1013,7 +1078,7 @@ class BaseEntity {
|
|
|
1013
1078
|
}
|
|
1014
1079
|
}
|
|
1015
1080
|
|
|
1016
|
-
var __awaiter$
|
|
1081
|
+
var __awaiter$s = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
1017
1082
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
1018
1083
|
return new (P || (P = Promise))(function (resolve, reject) {
|
|
1019
1084
|
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
@@ -1054,13 +1119,14 @@ class Asset extends BaseEntity {
|
|
|
1054
1119
|
};
|
|
1055
1120
|
}
|
|
1056
1121
|
static toImage(stream, meta, params) {
|
|
1057
|
-
return __awaiter$
|
|
1122
|
+
return __awaiter$s(this, void 0, void 0, function* () {
|
|
1058
1123
|
params = params || {};
|
|
1059
1124
|
// Get default crop info
|
|
1060
1125
|
const crop = Asset.toCropRegion(meta.crop);
|
|
1061
|
-
// Return
|
|
1062
|
-
if (Object.keys(params).length == 0 && !crop)
|
|
1126
|
+
// Return the stream if there is no params and no default crop exists
|
|
1127
|
+
if ((meta === null || meta === void 0 ? void 0 : meta.extension) === "svg" || (Object.keys(params).length == 0 && !crop)) {
|
|
1063
1128
|
return stream;
|
|
1129
|
+
}
|
|
1064
1130
|
// Parse params
|
|
1065
1131
|
params.rotation = isNaN(params.rotation) ? 0 : Math.round(params.rotation / 90) * 90;
|
|
1066
1132
|
params.canvasScaleX = isNaN(params.canvasScaleX) ? 1 : Number(params.canvasScaleX);
|
|
@@ -1075,51 +1141,43 @@ class Asset extends BaseEntity {
|
|
|
1075
1141
|
const cropBefore = Asset.toCropRegion(params.cropBefore || (params.crop ? meta.cropBefore : null));
|
|
1076
1142
|
const cropAfter = Asset.toCropRegion(params.cropAfter || (params.crop ? meta.cropAfter : null));
|
|
1077
1143
|
// Get metadata
|
|
1078
|
-
|
|
1079
|
-
let width =
|
|
1080
|
-
let height = imgMeta.height;
|
|
1144
|
+
let img = sharp$2(buffer);
|
|
1145
|
+
let { width, height } = yield img.metadata();
|
|
1081
1146
|
// Crop before resize
|
|
1082
1147
|
if (cropBefore) {
|
|
1083
|
-
buffer = yield sharp$2(buffer)
|
|
1084
|
-
.extract(cropBefore)
|
|
1085
|
-
.toBuffer();
|
|
1086
1148
|
width = cropBefore.width;
|
|
1087
1149
|
height = cropBefore.height;
|
|
1150
|
+
img = img.extract(cropBefore);
|
|
1088
1151
|
}
|
|
1089
1152
|
else if (crop) {
|
|
1090
|
-
buffer = yield sharp$2(buffer)
|
|
1091
|
-
.extract(crop)
|
|
1092
|
-
.toBuffer();
|
|
1093
1153
|
width = crop.width;
|
|
1094
1154
|
height = crop.height;
|
|
1155
|
+
img = img.extract(crop);
|
|
1095
1156
|
}
|
|
1096
1157
|
// Resize canvas
|
|
1097
|
-
|
|
1158
|
+
const canvasScaleX = (meta === null || meta === void 0 ? void 0 : meta.canvasScaleX) || 1;
|
|
1159
|
+
const canvasScaleY = (meta === null || meta === void 0 ? void 0 : meta.canvasScaleY) || 1;
|
|
1160
|
+
if (params.canvasScaleX !== canvasScaleX || params.canvasScaleY !== canvasScaleY) {
|
|
1098
1161
|
width = Math.round(width * params.canvasScaleX);
|
|
1099
1162
|
height = Math.round(height * params.canvasScaleY);
|
|
1100
|
-
|
|
1101
|
-
.resize({ width, height, background: "#00000000", fit: "contain" })
|
|
1102
|
-
.toBuffer();
|
|
1163
|
+
img = img.resize({ width, height, background: "#00000000", fit: "contain" });
|
|
1103
1164
|
}
|
|
1104
1165
|
// Resize image
|
|
1105
1166
|
if (params.scaleX !== 1 || params.scaleY !== 1) {
|
|
1106
1167
|
width = Math.round(width * params.scaleX);
|
|
1107
1168
|
height = Math.round(height * params.scaleY);
|
|
1108
|
-
|
|
1109
|
-
.resize({ width, height, background: "#00000000", fit: "fill" })
|
|
1110
|
-
.toBuffer();
|
|
1169
|
+
img = img.resize({ width, height, background: "#00000000", fit: "fill" });
|
|
1111
1170
|
}
|
|
1112
1171
|
// Crop after resize
|
|
1113
1172
|
if (cropAfter) {
|
|
1114
|
-
|
|
1115
|
-
.extract(cropAfter)
|
|
1116
|
-
.toBuffer();
|
|
1173
|
+
img = img.extract(cropAfter);
|
|
1117
1174
|
}
|
|
1118
1175
|
// Rotate
|
|
1119
1176
|
if (params.rotation !== 0) {
|
|
1120
|
-
buffer = yield
|
|
1177
|
+
buffer = yield img.toBuffer();
|
|
1178
|
+
img = sharp$2(buffer).rotate(params.rotation);
|
|
1121
1179
|
}
|
|
1122
|
-
return bufferToStream(
|
|
1180
|
+
return bufferToStream(yield img.toBuffer());
|
|
1123
1181
|
}
|
|
1124
1182
|
catch (e) {
|
|
1125
1183
|
console.log("Asset image conversion error", e);
|
|
@@ -1140,7 +1198,7 @@ class Asset extends BaseEntity {
|
|
|
1140
1198
|
return this.bucket.openDownloadStream(this.mId);
|
|
1141
1199
|
}
|
|
1142
1200
|
unlink() {
|
|
1143
|
-
return __awaiter$
|
|
1201
|
+
return __awaiter$s(this, void 0, void 0, function* () {
|
|
1144
1202
|
return deleteFromBucket(this.bucket, this.mId);
|
|
1145
1203
|
});
|
|
1146
1204
|
}
|
|
@@ -1148,7 +1206,7 @@ class Asset extends BaseEntity {
|
|
|
1148
1206
|
return streamToBuffer(this.stream);
|
|
1149
1207
|
}
|
|
1150
1208
|
download(metadata) {
|
|
1151
|
-
return __awaiter$
|
|
1209
|
+
return __awaiter$s(this, void 0, void 0, function* () {
|
|
1152
1210
|
metadata = Object.assign(this.metadata, metadata || {});
|
|
1153
1211
|
metadata.downloadCount = isNaN(metadata.downloadCount) || !metadata.firstDownload
|
|
1154
1212
|
? 1
|
|
@@ -1160,17 +1218,79 @@ class Asset extends BaseEntity {
|
|
|
1160
1218
|
});
|
|
1161
1219
|
}
|
|
1162
1220
|
getImage(params = null) {
|
|
1163
|
-
return __awaiter$
|
|
1221
|
+
return __awaiter$s(this, void 0, void 0, function* () {
|
|
1164
1222
|
return Asset.toImage(this.stream, this.metadata, params);
|
|
1165
1223
|
});
|
|
1166
1224
|
}
|
|
1167
1225
|
downloadImage(params, metadata) {
|
|
1168
|
-
return __awaiter$
|
|
1226
|
+
return __awaiter$s(this, void 0, void 0, function* () {
|
|
1169
1227
|
return Asset.toImage(yield this.download(metadata), this.metadata, params);
|
|
1170
1228
|
});
|
|
1171
1229
|
}
|
|
1172
1230
|
}
|
|
1173
1231
|
|
|
1232
|
+
var __awaiter$r = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
1233
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
1234
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
1235
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
1236
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
1237
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
1238
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
1239
|
+
});
|
|
1240
|
+
};
|
|
1241
|
+
class TempAsset {
|
|
1242
|
+
constructor(buffer, filename, contentType, metadata) {
|
|
1243
|
+
this.buffer = buffer;
|
|
1244
|
+
this.filename = filename;
|
|
1245
|
+
this.contentType = contentType;
|
|
1246
|
+
this.metadata = metadata;
|
|
1247
|
+
this.id = new ObjectId().toHexString();
|
|
1248
|
+
}
|
|
1249
|
+
get stream() {
|
|
1250
|
+
return bufferToStream(this.buffer);
|
|
1251
|
+
}
|
|
1252
|
+
unlink() {
|
|
1253
|
+
return __awaiter$r(this, void 0, void 0, function* () {
|
|
1254
|
+
throw new Error(`Temp asset '${this.id}' can not be removed!`);
|
|
1255
|
+
});
|
|
1256
|
+
}
|
|
1257
|
+
getBuffer() {
|
|
1258
|
+
return __awaiter$r(this, void 0, void 0, function* () {
|
|
1259
|
+
return this.buffer;
|
|
1260
|
+
});
|
|
1261
|
+
}
|
|
1262
|
+
download(metadata) {
|
|
1263
|
+
return __awaiter$r(this, void 0, void 0, function* () {
|
|
1264
|
+
return this.stream;
|
|
1265
|
+
});
|
|
1266
|
+
}
|
|
1267
|
+
downloadImage(params, metadata) {
|
|
1268
|
+
Object.assign(this.metadata, metadata || {});
|
|
1269
|
+
return Asset.toImage(this.stream, this.metadata, params);
|
|
1270
|
+
}
|
|
1271
|
+
getImage(params) {
|
|
1272
|
+
return this.downloadImage(params);
|
|
1273
|
+
}
|
|
1274
|
+
save() {
|
|
1275
|
+
return __awaiter$r(this, void 0, void 0, function* () {
|
|
1276
|
+
return this;
|
|
1277
|
+
});
|
|
1278
|
+
}
|
|
1279
|
+
load() {
|
|
1280
|
+
return __awaiter$r(this, void 0, void 0, function* () {
|
|
1281
|
+
return this;
|
|
1282
|
+
});
|
|
1283
|
+
}
|
|
1284
|
+
toJSON() {
|
|
1285
|
+
return {
|
|
1286
|
+
id: this.id,
|
|
1287
|
+
filename: this.filename,
|
|
1288
|
+
contentType: this.contentType,
|
|
1289
|
+
metadata: this.metadata
|
|
1290
|
+
};
|
|
1291
|
+
}
|
|
1292
|
+
}
|
|
1293
|
+
|
|
1174
1294
|
var __decorate$t = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
1175
1295
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1176
1296
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -1238,6 +1358,27 @@ let Assets = class Assets {
|
|
|
1238
1358
|
return this.writeBuffer(buffer, metadata);
|
|
1239
1359
|
});
|
|
1240
1360
|
}
|
|
1361
|
+
download(url, contentType = null) {
|
|
1362
|
+
return __awaiter$q(this, void 0, void 0, function* () {
|
|
1363
|
+
let buffer = (yield axios({ url, responseType: "arraybuffer" })).data;
|
|
1364
|
+
let fileType = { ext: "", mime: contentType };
|
|
1365
|
+
try {
|
|
1366
|
+
fileType = yield AssetProcessor.fileTypeFromBuffer(buffer);
|
|
1367
|
+
}
|
|
1368
|
+
catch (e) {
|
|
1369
|
+
if (!fileType.mime) {
|
|
1370
|
+
throw `Can't determine mime type`;
|
|
1371
|
+
}
|
|
1372
|
+
console.log(`Can't determine mime type`, e);
|
|
1373
|
+
}
|
|
1374
|
+
const metadata = {
|
|
1375
|
+
filename: url,
|
|
1376
|
+
extension: (fileType.ext || "").trim()
|
|
1377
|
+
};
|
|
1378
|
+
buffer = yield this.assetProcessor.process(buffer, metadata, fileType);
|
|
1379
|
+
return new TempAsset(buffer, url, fileType.mime, metadata);
|
|
1380
|
+
});
|
|
1381
|
+
}
|
|
1241
1382
|
read(id) {
|
|
1242
1383
|
return __awaiter$q(this, void 0, void 0, function* () {
|
|
1243
1384
|
return !id ? null : this.find({ _id: new ObjectId(id) });
|
|
@@ -1355,7 +1496,7 @@ class LazyAsset extends BaseEntity {
|
|
|
1355
1496
|
this.progresses.get(this.progressId).then(p => {
|
|
1356
1497
|
p === null || p === void 0 ? void 0 : p.cancel();
|
|
1357
1498
|
});
|
|
1358
|
-
this.startWorkingOnAsset().then(() => {
|
|
1499
|
+
this.startWorkingOnAsset(false).then(() => {
|
|
1359
1500
|
console.log(`Started working on lazy asset: ${this.id}`);
|
|
1360
1501
|
}).catch(reason => {
|
|
1361
1502
|
console.log(`Can't start working on lazy asset: ${this.id}\nReason: ${reason}`);
|
|
@@ -1374,7 +1515,7 @@ class LazyAsset extends BaseEntity {
|
|
|
1374
1515
|
yield this.progresses.waitToFinish(this.progressId);
|
|
1375
1516
|
return this.loadAsset();
|
|
1376
1517
|
}
|
|
1377
|
-
yield this.startWorkingOnAsset();
|
|
1518
|
+
yield this.startWorkingOnAsset(true);
|
|
1378
1519
|
return this.loadAsset();
|
|
1379
1520
|
});
|
|
1380
1521
|
}
|
|
@@ -1385,12 +1526,12 @@ class LazyAsset extends BaseEntity {
|
|
|
1385
1526
|
return asset;
|
|
1386
1527
|
});
|
|
1387
1528
|
}
|
|
1388
|
-
startWorkingOnAsset() {
|
|
1529
|
+
startWorkingOnAsset(fromLoad) {
|
|
1389
1530
|
return __awaiter$p(this, void 0, void 0, function* () {
|
|
1390
1531
|
this.data.progressId = (yield this.progresses.create()).id;
|
|
1391
1532
|
this.data.assetId = null;
|
|
1392
1533
|
yield this.save();
|
|
1393
|
-
yield this.jobMan.enqueueWithName(this.data.jobName, Object.assign(Object.assign({}, this.data.jobParams), { lazyId: this.id }));
|
|
1534
|
+
yield this.jobMan.enqueueWithName(this.data.jobName, Object.assign(Object.assign({}, this.data.jobParams), { lazyId: this.id, fromLoad }));
|
|
1394
1535
|
});
|
|
1395
1536
|
}
|
|
1396
1537
|
}
|
|
@@ -1416,15 +1557,15 @@ var __awaiter$o = (this && this.__awaiter) || function (thisArg, _arguments, P,
|
|
|
1416
1557
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
1417
1558
|
});
|
|
1418
1559
|
};
|
|
1419
|
-
const IORedis = ioredis;
|
|
1420
1560
|
let JobManager = class JobManager {
|
|
1421
1561
|
constructor(config, container, jobTypes) {
|
|
1422
1562
|
this.config = config;
|
|
1423
1563
|
this.container = container;
|
|
1424
1564
|
this.jobTypes = jobTypes || [];
|
|
1425
1565
|
this.jobs = this.jobTypes.reduce((res, jobType) => {
|
|
1426
|
-
res[getConstructorName(jobType)] = {
|
|
1427
|
-
|
|
1566
|
+
res[getConstructorName(jobType)] = (jobParams) => {
|
|
1567
|
+
const job = this.resolveJobInstance(jobType, jobParams);
|
|
1568
|
+
return job.process();
|
|
1428
1569
|
};
|
|
1429
1570
|
return res;
|
|
1430
1571
|
}, {});
|
|
@@ -1442,31 +1583,25 @@ let JobManager = class JobManager {
|
|
|
1442
1583
|
return instance.process();
|
|
1443
1584
|
});
|
|
1444
1585
|
}
|
|
1445
|
-
enqueueWithName(name, params = {}
|
|
1586
|
+
enqueueWithName(name, params = {}) {
|
|
1446
1587
|
return __awaiter$o(this, void 0, void 0, function* () {
|
|
1447
1588
|
const jobName = yield this.tryResolveFromName(name, params);
|
|
1448
|
-
|
|
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]);
|
|
1589
|
+
return this.sendToWorkers(jobName, params);
|
|
1455
1590
|
});
|
|
1456
1591
|
}
|
|
1457
|
-
|
|
1592
|
+
enqueue(jobType, params = {}) {
|
|
1458
1593
|
return __awaiter$o(this, void 0, void 0, function* () {
|
|
1459
1594
|
const jobName = yield this.tryResolveAndConnect(jobType, params);
|
|
1460
|
-
|
|
1595
|
+
return this.sendToWorkers(jobName, params);
|
|
1461
1596
|
});
|
|
1462
1597
|
}
|
|
1463
|
-
|
|
1598
|
+
sendToWorkers(jobName, params) {
|
|
1464
1599
|
return __awaiter$o(this, void 0, void 0, function* () {
|
|
1465
|
-
const
|
|
1466
|
-
yield
|
|
1600
|
+
const publisher = yield this.scheduler;
|
|
1601
|
+
yield publisher.send([jobName, JSON.stringify(params), new ObjectId().toHexString()]);
|
|
1467
1602
|
});
|
|
1468
1603
|
}
|
|
1469
|
-
schedule(minute, hour, dayOfMonth, month, dayOfWeek, jobType, params = {}
|
|
1604
|
+
schedule(minute, hour, dayOfMonth, month, dayOfWeek, jobType, params = {}) {
|
|
1470
1605
|
const expression = [minute, hour, dayOfMonth, month, dayOfWeek].map(t => {
|
|
1471
1606
|
if (isObject(t)) {
|
|
1472
1607
|
const range = t;
|
|
@@ -1483,19 +1618,38 @@ let JobManager = class JobManager {
|
|
|
1483
1618
|
return null;
|
|
1484
1619
|
}
|
|
1485
1620
|
return schedule(expression, () => {
|
|
1486
|
-
this.enqueue(jobType, params
|
|
1621
|
+
this.enqueue(jobType, params).catch(e => {
|
|
1487
1622
|
console.log(`Can't enqueue job: '${jobName}' because: ${e}`);
|
|
1488
1623
|
});
|
|
1489
1624
|
});
|
|
1490
1625
|
}
|
|
1491
1626
|
startProcessing() {
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1627
|
+
const host = this.config.resolve("zmqRemoteHost");
|
|
1628
|
+
this.worker = socket("pull");
|
|
1629
|
+
this.worker.connect(host);
|
|
1630
|
+
this.worker.on("message", (name, args, uniqueId) => __awaiter$o(this, void 0, void 0, function* () {
|
|
1631
|
+
try {
|
|
1632
|
+
const jobName = name.toString("utf8");
|
|
1633
|
+
const jobParams = JSON.parse(args.toString("utf8"));
|
|
1634
|
+
const timerId = uniqueId === null || uniqueId === void 0 ? void 0 : uniqueId.toString("utf8");
|
|
1635
|
+
const jobNameLog = `\x1b[36m"${jobName}"\x1b[0m`;
|
|
1636
|
+
const jobArgsLog = `\n${jsonHighlight(jobParams)}`;
|
|
1637
|
+
console.time(timerId);
|
|
1638
|
+
console.timeLog(timerId, `Started working on background job: ${jobNameLog} with args: ${jobArgsLog}\n\n`);
|
|
1639
|
+
try {
|
|
1640
|
+
yield Promise.race([this.jobs[jobName](jobParams), promiseTimeout(15000, true)]);
|
|
1641
|
+
console.timeLog(timerId, `Finished working on background job: ${jobNameLog}\n\n`);
|
|
1642
|
+
}
|
|
1643
|
+
catch (e) {
|
|
1644
|
+
console.timeLog(timerId, `Background job failed: ${jobNameLog}\n${e.message}\n\n`);
|
|
1645
|
+
}
|
|
1646
|
+
console.timeEnd(timerId);
|
|
1647
|
+
}
|
|
1648
|
+
catch (e) {
|
|
1649
|
+
console.log(`Failed to start job: ${e.message}`);
|
|
1650
|
+
}
|
|
1651
|
+
}));
|
|
1652
|
+
console.log(`Waiting for jobs at: ${host}`);
|
|
1499
1653
|
}
|
|
1500
1654
|
tryResolve(jobType, params) {
|
|
1501
1655
|
const jobName = getConstructorName(jobType);
|
|
@@ -1510,47 +1664,6 @@ let JobManager = class JobManager {
|
|
|
1510
1664
|
}
|
|
1511
1665
|
return jobName;
|
|
1512
1666
|
}
|
|
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
1667
|
tryResolveFromName(jobName, params) {
|
|
1555
1668
|
const jobType = this.jobTypes.find(type => {
|
|
1556
1669
|
return getConstructorName(type) == jobName;
|
|
@@ -1562,10 +1675,14 @@ let JobManager = class JobManager {
|
|
|
1562
1675
|
}
|
|
1563
1676
|
tryResolveAndConnect(jobType, params) {
|
|
1564
1677
|
return __awaiter$o(this, void 0, void 0, function* () {
|
|
1565
|
-
this.
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1678
|
+
this.scheduler = this.scheduler || new Promise((resolve) => __awaiter$o(this, void 0, void 0, function* () {
|
|
1679
|
+
const port = this.config.resolve("zmqPort");
|
|
1680
|
+
const publisher = socket("push");
|
|
1681
|
+
yield publisher.bind(`tcp://0.0.0.0:${port}`);
|
|
1682
|
+
console.log(`Publisher bound to port: ${port}`);
|
|
1683
|
+
resolve(publisher);
|
|
1684
|
+
}));
|
|
1685
|
+
return this.tryResolve(jobType, params);
|
|
1569
1686
|
});
|
|
1570
1687
|
}
|
|
1571
1688
|
resolveJobInstance(jobType, params) {
|
|
@@ -1576,12 +1693,6 @@ let JobManager = class JobManager {
|
|
|
1576
1693
|
container.register(jobType, jobType);
|
|
1577
1694
|
return container.resolve(jobType);
|
|
1578
1695
|
}
|
|
1579
|
-
toPerformFunction(jobType) {
|
|
1580
|
-
return (jobParams) => {
|
|
1581
|
-
const job = this.resolveJobInstance(jobType, jobParams);
|
|
1582
|
-
return job.process();
|
|
1583
|
-
};
|
|
1584
|
-
}
|
|
1585
1696
|
};
|
|
1586
1697
|
JobManager = __decorate$s([
|
|
1587
1698
|
injectable(),
|
|
@@ -2903,7 +3014,9 @@ let AssetsController = class AssetsController {
|
|
|
2903
3014
|
getImageRotation(id, params, res, rotation = 0) {
|
|
2904
3015
|
return __awaiter$7(this, void 0, void 0, function* () {
|
|
2905
3016
|
const asset = yield this.getAsset("Image", id, params.lazy, res);
|
|
2906
|
-
|
|
3017
|
+
if (rotation !== 0) {
|
|
3018
|
+
params.rotation = params.rotation || rotation;
|
|
3019
|
+
}
|
|
2907
3020
|
return asset.downloadImage(params);
|
|
2908
3021
|
});
|
|
2909
3022
|
}
|
|
@@ -3714,20 +3827,8 @@ function createServices() {
|
|
|
3714
3827
|
new Parameter("mongoPassword", null),
|
|
3715
3828
|
new Parameter("nodeEnv", "development"),
|
|
3716
3829
|
new Parameter("appPort", 80),
|
|
3717
|
-
new Parameter("
|
|
3718
|
-
new Parameter("
|
|
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"]),
|
|
3830
|
+
new Parameter("zmqPort", 3000),
|
|
3831
|
+
new Parameter("zmqRemoteHost", "tcp://127.0.0.1:3000"),
|
|
3731
3832
|
new Parameter("isWorker", false),
|
|
3732
3833
|
new Parameter("mainEndpoint", ""),
|
|
3733
3834
|
new Parameter("idChars", "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"),
|
|
@@ -3933,5 +4034,5 @@ function setupBackend(config, providers, parent) {
|
|
|
3933
4034
|
* Generated bundle index. Do not edit.
|
|
3934
4035
|
*/
|
|
3935
4036
|
|
|
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 };
|
|
4037
|
+
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
4038
|
//# sourceMappingURL=stemy-backend.js.map
|