@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.
- package/bundles/stemy-backend.umd.js +339 -225
- 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/asset-processor.js +2 -2
- package/esm2015/services/assets.js +23 -1
- package/esm2015/services/entities/asset.js +17 -24
- package/esm2015/services/entities/temp-asset.js +65 -0
- package/esm2015/services/job-manager.js +50 -80
- package/esm2015/utils.js +68 -4
- package/fesm2015/stemy-backend.js +239 -140
- 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/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 +35 -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,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$
|
|
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$
|
|
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$
|
|
879
|
+
return __awaiter$v(this, void 0, void 0, function* () {
|
|
817
880
|
if (fileType.mime === "image/svg+xml") {
|
|
818
|
-
const match = /<svg(
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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
|
|
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
|
-
|
|
1079
|
-
let 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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1115
|
-
.extract(cropAfter)
|
|
1116
|
-
.toBuffer();
|
|
1171
|
+
img = img.extract(cropAfter);
|
|
1117
1172
|
}
|
|
1118
1173
|
// Rotate
|
|
1119
1174
|
if (params.rotation !== 0) {
|
|
1120
|
-
buffer = yield
|
|
1175
|
+
buffer = yield img.toBuffer();
|
|
1176
|
+
img = sharp$2(buffer).rotate(params.rotation);
|
|
1121
1177
|
}
|
|
1122
|
-
return bufferToStream(
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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
|
-
|
|
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 = {}
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1593
|
+
return this.sendToWorkers(jobName, params);
|
|
1461
1594
|
});
|
|
1462
1595
|
}
|
|
1463
|
-
|
|
1596
|
+
sendToWorkers(jobName, params) {
|
|
1464
1597
|
return __awaiter$o(this, void 0, void 0, function* () {
|
|
1465
|
-
const
|
|
1466
|
-
yield
|
|
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 = {}
|
|
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
|
|
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
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
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.
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
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
|
-
|
|
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("
|
|
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"]),
|
|
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
|