@stemy/backend 5.0.6 → 5.0.8
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/esm2020/public_api.mjs +11 -21
- package/esm2020/services/backend-provider.mjs +52 -9
- package/esm2020/services/configuration.mjs +1 -1
- package/esm2020/services/entities/lazy-asset.mjs +4 -3
- package/esm2020/services/job-manager.mjs +12 -17
- package/esm2020/services/lazy-assets.mjs +5 -3
- package/esm2020/utils.mjs +40 -14
- package/fesm2015/stemy-backend.mjs +286 -233
- package/fesm2015/stemy-backend.mjs.map +1 -1
- package/fesm2020/stemy-backend.mjs +282 -231
- package/fesm2020/stemy-backend.mjs.map +1 -1
- package/package.json +4 -4
- package/public_api.d.ts +1 -1
- package/services/backend-provider.d.ts +13 -4
- package/services/job-manager.d.ts +3 -2
- package/services/lazy-assets.d.ts +1 -1
- package/utils.d.ts +4 -0
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { dirname, basename, join, resolve } from 'path';
|
|
2
|
-
import bodyParser from 'body-parser';
|
|
3
2
|
import webToken from 'jsonwebtoken';
|
|
4
3
|
import { injectable, scoped, Lifecycle, singleton, injectAll, inject, isFactoryProvider, container } from 'tsyringe';
|
|
5
4
|
import { HttpError, getMetadataArgsStorage, Authorized, Post, UploadedFile, Body, Get, Param, QueryParam, Res, QueryParams, Controller, UnauthorizedError, CurrentUser, Header, BadRequestError, Middleware, createParamDecorator, useContainer, useExpressServer } from 'routing-controllers';
|
|
@@ -10,6 +9,7 @@ import sharp_ from 'sharp';
|
|
|
10
9
|
import { ObjectId as ObjectId$1 } from 'bson';
|
|
11
10
|
import axios from 'axios';
|
|
12
11
|
import { mkdir, unlink, readFile as readFile$1, writeFile as writeFile$1, lstat, readdir, access, constants, lstatSync, readFileSync, existsSync } from 'fs';
|
|
12
|
+
import { gzip, gunzip } from 'zlib';
|
|
13
13
|
import { fileURLToPath } from 'url';
|
|
14
14
|
import { exec } from 'child_process';
|
|
15
15
|
import { createHash } from 'crypto';
|
|
@@ -24,15 +24,16 @@ import cron from 'node-cron';
|
|
|
24
24
|
import { socket } from 'zeromq';
|
|
25
25
|
import { filter as filter$1, map, first, timeout } from 'rxjs/operators';
|
|
26
26
|
import { createServer } from 'http';
|
|
27
|
-
import express_ from 'express';
|
|
28
27
|
import { Server } from 'socket.io';
|
|
29
|
-
import
|
|
30
|
-
import
|
|
31
|
-
import * as Handlebars from 'handlebars';
|
|
28
|
+
import express_ from 'express';
|
|
29
|
+
import bodyParser from 'body-parser';
|
|
32
30
|
import { routingControllersToSpec, OpenAPI, getStatusCode } from 'routing-controllers-openapi';
|
|
33
31
|
import { defaultMetadataStorage } from 'class-transformer/cjs/storage';
|
|
34
32
|
import { validationMetadatasToSchemas } from 'class-validator-jsonschema';
|
|
35
33
|
import { ValidatorConstraint, ValidationTypes, Min, Max, IsOptional, IsBoolean } from 'class-validator';
|
|
34
|
+
import { v4 } from 'uuid';
|
|
35
|
+
import { createTransport } from 'nodemailer';
|
|
36
|
+
import * as Handlebars from 'handlebars';
|
|
36
37
|
import { CommandsAddon, AnsiCodes } from '@stemy/terminal-commands-addon';
|
|
37
38
|
import { compare } from 'bcrypt';
|
|
38
39
|
import moment from 'moment';
|
|
@@ -591,6 +592,28 @@ function padRight(value, count = 3, padWith = "0") {
|
|
|
591
592
|
function camelCaseToDash(str) {
|
|
592
593
|
return str.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase();
|
|
593
594
|
}
|
|
595
|
+
function gzipPromised(data, opts) {
|
|
596
|
+
return new Promise((resolve, reject) => {
|
|
597
|
+
gzip(data, opts, (err, result) => {
|
|
598
|
+
if (err) {
|
|
599
|
+
reject(err);
|
|
600
|
+
return;
|
|
601
|
+
}
|
|
602
|
+
resolve(result.toString("base64"));
|
|
603
|
+
});
|
|
604
|
+
});
|
|
605
|
+
}
|
|
606
|
+
function gunzipPromised(data, opts) {
|
|
607
|
+
return new Promise((resolve, reject) => {
|
|
608
|
+
gunzip(Buffer.from(data, "base64"), opts, (err, result) => {
|
|
609
|
+
if (err) {
|
|
610
|
+
reject(err);
|
|
611
|
+
return;
|
|
612
|
+
}
|
|
613
|
+
resolve(result.toString("utf8"));
|
|
614
|
+
});
|
|
615
|
+
});
|
|
616
|
+
}
|
|
594
617
|
function deleteFromBucket(bucket, fileId) {
|
|
595
618
|
return new Promise(((resolve, reject) => {
|
|
596
619
|
bucket.delete(fileId, error => {
|
|
@@ -607,20 +630,22 @@ function deleteFromBucket(bucket, fileId) {
|
|
|
607
630
|
}));
|
|
608
631
|
}
|
|
609
632
|
const defaultPredicate = () => true;
|
|
610
|
-
function copyRecursive(target, source, predicate) {
|
|
611
|
-
predicate = predicate || defaultPredicate;
|
|
633
|
+
function copyRecursive(target, source, predicate, copies) {
|
|
612
634
|
if (isPrimitive(source) || isDate(source) || isFunction(source))
|
|
613
635
|
return source;
|
|
636
|
+
if (copies.has(source))
|
|
637
|
+
return copies.get(source);
|
|
614
638
|
if (isArray(source)) {
|
|
615
639
|
target = isArray(target) ? Array.from(target) : [];
|
|
616
640
|
source.forEach((item, index) => {
|
|
617
641
|
if (!predicate(item, index, target, source))
|
|
618
642
|
return;
|
|
619
643
|
if (target.length > index)
|
|
620
|
-
target[index] = copyRecursive(target[index], item, predicate);
|
|
644
|
+
target[index] = copyRecursive(target[index], item, predicate, copies);
|
|
621
645
|
else
|
|
622
|
-
target.push(copyRecursive(null, item, predicate));
|
|
646
|
+
target.push(copyRecursive(null, item, predicate, copies));
|
|
623
647
|
});
|
|
648
|
+
copies.set(source, target);
|
|
624
649
|
return target;
|
|
625
650
|
}
|
|
626
651
|
if (isBuffer(source))
|
|
@@ -644,24 +669,25 @@ function copyRecursive(target, source, predicate) {
|
|
|
644
669
|
else {
|
|
645
670
|
target = Object.assign({}, target || {});
|
|
646
671
|
}
|
|
672
|
+
// Set to copies to prevent circular references
|
|
673
|
+
copies.set(source, target);
|
|
647
674
|
// Copy map entries
|
|
648
675
|
if (target instanceof Map) {
|
|
649
676
|
if (source instanceof Map) {
|
|
650
677
|
for (let [key, value] of source.entries()) {
|
|
651
678
|
if (!predicate(value, key, target, source))
|
|
652
679
|
continue;
|
|
653
|
-
target.set(key, !shouldCopy(key, value) ? value : copyRecursive(target.get(key), value, predicate));
|
|
680
|
+
target.set(key, !shouldCopy(key, value) ? value : copyRecursive(target.get(key), value, predicate, copies));
|
|
654
681
|
}
|
|
655
682
|
}
|
|
656
683
|
return target;
|
|
657
684
|
}
|
|
658
685
|
// Copy object members
|
|
659
686
|
let keys = Object.keys(source);
|
|
660
|
-
|
|
661
|
-
if (!predicate(source[key], key,
|
|
662
|
-
return
|
|
663
|
-
|
|
664
|
-
return result;
|
|
687
|
+
keys.forEach(key => {
|
|
688
|
+
if (!predicate(source[key], key, target, source))
|
|
689
|
+
return;
|
|
690
|
+
target[key] = !shouldCopy(key, source[key]) ? source[key] : copyRecursive(target[key], source[key], predicate, copies);
|
|
665
691
|
}, target);
|
|
666
692
|
// Copy object properties
|
|
667
693
|
const descriptors = Object.getOwnPropertyDescriptors(source);
|
|
@@ -672,13 +698,13 @@ function copyRecursive(target, source, predicate) {
|
|
|
672
698
|
return target;
|
|
673
699
|
}
|
|
674
700
|
function filter(obj, predicate) {
|
|
675
|
-
return copyRecursive(null, obj, predicate);
|
|
701
|
+
return copyRecursive(null, obj, predicate || defaultPredicate, new Map());
|
|
676
702
|
}
|
|
677
703
|
function copy(obj) {
|
|
678
|
-
return copyRecursive(null, obj);
|
|
704
|
+
return copyRecursive(null, obj, defaultPredicate, new Map());
|
|
679
705
|
}
|
|
680
706
|
function assign(target, source, predicate) {
|
|
681
|
-
return copyRecursive(target, source, predicate);
|
|
707
|
+
return copyRecursive(target, source, predicate, new Map());
|
|
682
708
|
}
|
|
683
709
|
function md5(data) {
|
|
684
710
|
if (isObject(data)) {
|
|
@@ -1234,7 +1260,8 @@ class LazyAsset extends BaseEntity {
|
|
|
1234
1260
|
this.data.progressId = (await this.progresses.create()).id;
|
|
1235
1261
|
this.data.assetId = null;
|
|
1236
1262
|
await this.save();
|
|
1237
|
-
|
|
1263
|
+
const jobParams = JSON.parse(await gunzipPromised(this.data.jobParams));
|
|
1264
|
+
await this.progresses.jobMan.enqueueWithName(this.data.jobName, { ...jobParams, lazyId: this.id, fromLoad });
|
|
1238
1265
|
}
|
|
1239
1266
|
}
|
|
1240
1267
|
|
|
@@ -1279,7 +1306,7 @@ let JobManager = class JobManager {
|
|
|
1279
1306
|
return res;
|
|
1280
1307
|
}, {});
|
|
1281
1308
|
this.messages = new Subject();
|
|
1282
|
-
this.processing =
|
|
1309
|
+
this.processing = null;
|
|
1283
1310
|
this.maxTimeout = this.config.resolve("jobTimeout");
|
|
1284
1311
|
}
|
|
1285
1312
|
on(message, cb) {
|
|
@@ -1326,22 +1353,15 @@ let JobManager = class JobManager {
|
|
|
1326
1353
|
});
|
|
1327
1354
|
});
|
|
1328
1355
|
}
|
|
1329
|
-
async
|
|
1330
|
-
if (this.processing)
|
|
1331
|
-
return null;
|
|
1332
|
-
this.processing = true;
|
|
1333
|
-
if (!this.config.resolve("isWorker")) {
|
|
1334
|
-
this.logger.log("job-manager", colorize(`Processing can not be started because this is NOT a worker process!`, ConsoleColor.FgRed));
|
|
1335
|
-
return null;
|
|
1336
|
-
}
|
|
1356
|
+
async initProcessing() {
|
|
1337
1357
|
const host = this.config.resolve("zmqRemoteHost");
|
|
1338
1358
|
const pushHost = `${host}:${this.config.resolve("zmqBackPort")}`;
|
|
1339
1359
|
this.workerPush = socket("push");
|
|
1340
|
-
|
|
1360
|
+
this.workerPush.connect(pushHost);
|
|
1341
1361
|
this.logger.log("job-manager", `Worker producer connected to: ${pushHost}`);
|
|
1342
1362
|
const pullHost = `${host}:${this.config.resolve("zmqPort")}`;
|
|
1343
1363
|
this.workerPull = socket("pull");
|
|
1344
|
-
|
|
1364
|
+
this.workerPull.connect(pullHost);
|
|
1345
1365
|
this.logger.log("job-manager", `Worker consumer connected to: ${pullHost}`);
|
|
1346
1366
|
this.workerPull.on("message", async (name, args, uniqId) => {
|
|
1347
1367
|
try {
|
|
@@ -1364,6 +1384,10 @@ let JobManager = class JobManager {
|
|
|
1364
1384
|
}
|
|
1365
1385
|
});
|
|
1366
1386
|
}
|
|
1387
|
+
startProcessing() {
|
|
1388
|
+
this.processing = this.processing || this.initProcessing();
|
|
1389
|
+
return this.processing;
|
|
1390
|
+
}
|
|
1367
1391
|
tryResolve(jobType, params) {
|
|
1368
1392
|
const jobName = getConstructorName(jobType);
|
|
1369
1393
|
if (!this.jobs[jobName]) {
|
|
@@ -1421,15 +1445,13 @@ let JobManager = class JobManager {
|
|
|
1421
1445
|
return container.resolve(jobType);
|
|
1422
1446
|
}
|
|
1423
1447
|
async sendToWorkers(jobName, params) {
|
|
1424
|
-
const publisher = await this.apiPush;
|
|
1425
1448
|
const uniqueId = new ObjectId$1().toHexString();
|
|
1426
|
-
|
|
1449
|
+
this.apiPush.send([jobName, JSON.stringify(params), uniqueId]);
|
|
1427
1450
|
return uniqueId;
|
|
1428
1451
|
}
|
|
1429
1452
|
};
|
|
1430
1453
|
JobManager = __decorate([
|
|
1431
|
-
|
|
1432
|
-
scoped(Lifecycle.ContainerScoped),
|
|
1454
|
+
singleton(),
|
|
1433
1455
|
__param(2, inject(DI_CONTAINER)),
|
|
1434
1456
|
__param(3, injectAll(JOB)),
|
|
1435
1457
|
__metadata("design:paramtypes", [Configuration,
|
|
@@ -1701,8 +1723,9 @@ let LazyAssets = class LazyAssets {
|
|
|
1701
1723
|
this.jobMan = jobMan;
|
|
1702
1724
|
this.collection = connector.database.collection("lazyassets");
|
|
1703
1725
|
}
|
|
1704
|
-
async create(jobType,
|
|
1705
|
-
const jobName = this.jobMan.tryResolve(jobType, { ...
|
|
1726
|
+
async create(jobType, jobParamsObj = {}, jobQue = "main") {
|
|
1727
|
+
const jobName = this.jobMan.tryResolve(jobType, { ...jobParamsObj, lazyId: "" });
|
|
1728
|
+
const jobParams = await gzipPromised(JSON.stringify(jobParamsObj));
|
|
1706
1729
|
const data = {
|
|
1707
1730
|
jobName,
|
|
1708
1731
|
jobParams,
|
|
@@ -1769,12 +1792,182 @@ AssetResolver = __decorate([
|
|
|
1769
1792
|
__metadata("design:paramtypes", [Assets, LazyAssets])
|
|
1770
1793
|
], AssetResolver);
|
|
1771
1794
|
|
|
1795
|
+
function checkValue(multi, value) {
|
|
1796
|
+
if (multi) {
|
|
1797
|
+
return Array.isArray(value) && value.every(v => {
|
|
1798
|
+
try {
|
|
1799
|
+
const id = new ObjectId$1(v);
|
|
1800
|
+
return id instanceof ObjectId$1;
|
|
1801
|
+
}
|
|
1802
|
+
catch (e) {
|
|
1803
|
+
return false;
|
|
1804
|
+
}
|
|
1805
|
+
});
|
|
1806
|
+
}
|
|
1807
|
+
if (null === value)
|
|
1808
|
+
return true;
|
|
1809
|
+
try {
|
|
1810
|
+
const id = new ObjectId$1(value);
|
|
1811
|
+
return id instanceof ObjectId$1;
|
|
1812
|
+
}
|
|
1813
|
+
catch (e) {
|
|
1814
|
+
return false;
|
|
1815
|
+
}
|
|
1816
|
+
}
|
|
1817
|
+
let IsFile = class IsFile {
|
|
1818
|
+
validate(value, validationArguments) {
|
|
1819
|
+
const [multi] = (validationArguments.constraints || []);
|
|
1820
|
+
return checkValue(multi, value);
|
|
1821
|
+
}
|
|
1822
|
+
};
|
|
1823
|
+
IsFile = __decorate([
|
|
1824
|
+
ValidatorConstraint()
|
|
1825
|
+
], IsFile);
|
|
1826
|
+
let IsObjectId = class IsObjectId {
|
|
1827
|
+
validate(value, validationArguments) {
|
|
1828
|
+
const [_, multi] = (validationArguments.constraints || []);
|
|
1829
|
+
return checkValue(multi, value);
|
|
1830
|
+
}
|
|
1831
|
+
};
|
|
1832
|
+
IsObjectId = __decorate([
|
|
1833
|
+
ValidatorConstraint()
|
|
1834
|
+
], IsObjectId);
|
|
1835
|
+
|
|
1836
|
+
let OpenApi = class OpenApi {
|
|
1837
|
+
constructor(container, customValidation) {
|
|
1838
|
+
this.container = container;
|
|
1839
|
+
this.customValidation = customValidation;
|
|
1840
|
+
this.docs = null;
|
|
1841
|
+
}
|
|
1842
|
+
get apiDocs() {
|
|
1843
|
+
if (!this.docs)
|
|
1844
|
+
this.docs = this.createApiDocs();
|
|
1845
|
+
return this.docs;
|
|
1846
|
+
}
|
|
1847
|
+
get apiDocsStr() {
|
|
1848
|
+
if (!this.docsStr)
|
|
1849
|
+
this.docsStr = JSON.stringify(this.apiDocs);
|
|
1850
|
+
return this.docsStr;
|
|
1851
|
+
}
|
|
1852
|
+
async schemaToExample(src, req) {
|
|
1853
|
+
const maybeRef = src;
|
|
1854
|
+
if (maybeRef.$ref) {
|
|
1855
|
+
const schemas = this.apiDocs.components.schemas;
|
|
1856
|
+
const schema = maybeRef.$ref
|
|
1857
|
+
.replace("#/components/schemas/", "")
|
|
1858
|
+
.replace("#/definitions/", "");
|
|
1859
|
+
return this.schemaToExample(schemas[schema], req);
|
|
1860
|
+
}
|
|
1861
|
+
let schema = src;
|
|
1862
|
+
if (schema.oneOf) {
|
|
1863
|
+
schema = Object.assign({}, schema, schema.oneOf[0]);
|
|
1864
|
+
}
|
|
1865
|
+
if (schema.type === "object") {
|
|
1866
|
+
const result = {};
|
|
1867
|
+
await Promise.all(Object.keys(schema.properties).map(async (key) => {
|
|
1868
|
+
result[key] = await this.schemaToExample(schema.properties[key], req);
|
|
1869
|
+
}));
|
|
1870
|
+
return result;
|
|
1871
|
+
}
|
|
1872
|
+
if (schema.type === "array") {
|
|
1873
|
+
return [await this.schemaToExample(schema.items, req)];
|
|
1874
|
+
}
|
|
1875
|
+
if (schema.type === "string") {
|
|
1876
|
+
if (isDefined(schema.default)) {
|
|
1877
|
+
if (isFunction(schema.default)) {
|
|
1878
|
+
return schema.default(this.container);
|
|
1879
|
+
}
|
|
1880
|
+
return schema.default;
|
|
1881
|
+
}
|
|
1882
|
+
if (schema.format == "date") {
|
|
1883
|
+
return new Date().toISOString().substr(0, 10);
|
|
1884
|
+
}
|
|
1885
|
+
if (schema.format == "date-time") {
|
|
1886
|
+
return new Date().toISOString();
|
|
1887
|
+
}
|
|
1888
|
+
if (schema.enum) {
|
|
1889
|
+
return schema.enum[0];
|
|
1890
|
+
}
|
|
1891
|
+
return "string";
|
|
1892
|
+
}
|
|
1893
|
+
if (schema.type === "number") {
|
|
1894
|
+
return schema.default ?? 0;
|
|
1895
|
+
}
|
|
1896
|
+
else if (schema.type === "boolean") {
|
|
1897
|
+
return schema.default ?? false;
|
|
1898
|
+
}
|
|
1899
|
+
else {
|
|
1900
|
+
return schema.default ?? null;
|
|
1901
|
+
}
|
|
1902
|
+
}
|
|
1903
|
+
createApiDocs() {
|
|
1904
|
+
const storage = getMetadataArgsStorage();
|
|
1905
|
+
const docs = routingControllersToSpec(storage);
|
|
1906
|
+
docs.basePath = "/api/";
|
|
1907
|
+
docs.definitions = validationMetadatasToSchemas({
|
|
1908
|
+
classTransformerMetadataStorage: defaultMetadataStorage,
|
|
1909
|
+
additionalConverters: {
|
|
1910
|
+
[ValidationTypes.CUSTOM_VALIDATION]: (meta, options) => {
|
|
1911
|
+
const res = isFunction(this.customValidation) ? this.customValidation(meta, options) : this.customValidation;
|
|
1912
|
+
if (isObject(res))
|
|
1913
|
+
return res;
|
|
1914
|
+
const constraints = meta.constraints || [];
|
|
1915
|
+
if (meta.constraintCls === IsFile) {
|
|
1916
|
+
return {
|
|
1917
|
+
multi: constraints[0] || false,
|
|
1918
|
+
type: "file"
|
|
1919
|
+
};
|
|
1920
|
+
}
|
|
1921
|
+
if (meta.constraintCls === IsObjectId) {
|
|
1922
|
+
return {
|
|
1923
|
+
endpoint: constraints[0] || false,
|
|
1924
|
+
multi: constraints[1] || false,
|
|
1925
|
+
type: "list"
|
|
1926
|
+
};
|
|
1927
|
+
}
|
|
1928
|
+
return null;
|
|
1929
|
+
}
|
|
1930
|
+
}
|
|
1931
|
+
});
|
|
1932
|
+
docs.components.schemas = docs.definitions;
|
|
1933
|
+
return docs;
|
|
1934
|
+
}
|
|
1935
|
+
};
|
|
1936
|
+
OpenApi = __decorate([
|
|
1937
|
+
singleton(),
|
|
1938
|
+
__param(0, inject(DI_CONTAINER)),
|
|
1939
|
+
__param(1, inject(OPENAPI_VALIDATION)),
|
|
1940
|
+
__metadata("design:paramtypes", [Object, Object])
|
|
1941
|
+
], OpenApi);
|
|
1942
|
+
|
|
1943
|
+
let Fixtures = class Fixtures {
|
|
1944
|
+
constructor(fixtures) {
|
|
1945
|
+
this.fixtures = fixtures;
|
|
1946
|
+
}
|
|
1947
|
+
async load(output) {
|
|
1948
|
+
if (!this.fixtures)
|
|
1949
|
+
return;
|
|
1950
|
+
output = output || {
|
|
1951
|
+
write: console.log,
|
|
1952
|
+
writeln: t => console.log(t + "\n")
|
|
1953
|
+
};
|
|
1954
|
+
for (let fixture of this.fixtures) {
|
|
1955
|
+
await fixture.load(output);
|
|
1956
|
+
}
|
|
1957
|
+
}
|
|
1958
|
+
};
|
|
1959
|
+
Fixtures = __decorate([
|
|
1960
|
+
injectable(),
|
|
1961
|
+
scoped(Lifecycle.ContainerScoped),
|
|
1962
|
+
__param(0, injectAll(FIXTURE)),
|
|
1963
|
+
__metadata("design:paramtypes", [Array])
|
|
1964
|
+
], Fixtures);
|
|
1965
|
+
|
|
1772
1966
|
const express = express_;
|
|
1773
1967
|
let BackendProvider = class BackendProvider {
|
|
1774
|
-
constructor() {
|
|
1775
|
-
this.
|
|
1776
|
-
this.
|
|
1777
|
-
this.server = createServer(this.express);
|
|
1968
|
+
constructor(config, container) {
|
|
1969
|
+
this.config = config;
|
|
1970
|
+
this.container = container;
|
|
1778
1971
|
}
|
|
1779
1972
|
get io() {
|
|
1780
1973
|
this.ioServer = this.ioServer || new Server(this.server, {
|
|
@@ -1789,10 +1982,48 @@ let BackendProvider = class BackendProvider {
|
|
|
1789
1982
|
});
|
|
1790
1983
|
return this.ioServer;
|
|
1791
1984
|
}
|
|
1985
|
+
get express() {
|
|
1986
|
+
if (!this.expressApp) {
|
|
1987
|
+
this.expressApp = express();
|
|
1988
|
+
this.expressApp.set("trust proxy", true);
|
|
1989
|
+
this.expressApp.use(bodyParser.json({
|
|
1990
|
+
limit: this.config.resolve("jsonLimit")
|
|
1991
|
+
}));
|
|
1992
|
+
this.expressApp.get("/api-docs", (req, res) => {
|
|
1993
|
+
this.openApi = this.openApi || this.container.get(OpenApi);
|
|
1994
|
+
res.header("Content-Type", "application/json")
|
|
1995
|
+
.status(200)
|
|
1996
|
+
.end(this.openApi.apiDocsStr);
|
|
1997
|
+
});
|
|
1998
|
+
}
|
|
1999
|
+
return this.expressApp;
|
|
2000
|
+
}
|
|
2001
|
+
get server() {
|
|
2002
|
+
this.httpServer = this.httpServer || createServer(this.express);
|
|
2003
|
+
return this.httpServer;
|
|
2004
|
+
}
|
|
2005
|
+
async quickStart() {
|
|
2006
|
+
const port = this.config.resolve("appPort");
|
|
2007
|
+
const isWorker = this.config.resolve("isWorker");
|
|
2008
|
+
if (isWorker || this.config.resolve("startWorker")) {
|
|
2009
|
+
await this.container.resolve(JobManager).startProcessing();
|
|
2010
|
+
if (isWorker) {
|
|
2011
|
+
return;
|
|
2012
|
+
}
|
|
2013
|
+
}
|
|
2014
|
+
if (this.config.resolve("fixtures")) {
|
|
2015
|
+
const fixtures = this.container.resolve(Fixtures);
|
|
2016
|
+
await fixtures.load();
|
|
2017
|
+
}
|
|
2018
|
+
return new Promise(resolve => {
|
|
2019
|
+
this.server.listen(port, () => resolve(`Service listening on port ${port}!`));
|
|
2020
|
+
});
|
|
2021
|
+
}
|
|
1792
2022
|
};
|
|
1793
2023
|
BackendProvider = __decorate([
|
|
1794
2024
|
singleton(),
|
|
1795
|
-
|
|
2025
|
+
__param(1, inject(DI_CONTAINER)),
|
|
2026
|
+
__metadata("design:paramtypes", [Configuration, Object])
|
|
1796
2027
|
], BackendProvider);
|
|
1797
2028
|
|
|
1798
2029
|
let CacheProcessor = class CacheProcessor {
|
|
@@ -1878,29 +2109,6 @@ EndpointProvider = __decorate([
|
|
|
1878
2109
|
scoped(Lifecycle.ContainerScoped)
|
|
1879
2110
|
], EndpointProvider);
|
|
1880
2111
|
|
|
1881
|
-
let Fixtures = class Fixtures {
|
|
1882
|
-
constructor(fixtures) {
|
|
1883
|
-
this.fixtures = fixtures;
|
|
1884
|
-
}
|
|
1885
|
-
async load(output) {
|
|
1886
|
-
if (!this.fixtures)
|
|
1887
|
-
return;
|
|
1888
|
-
output = output || {
|
|
1889
|
-
write: console.log,
|
|
1890
|
-
writeln: t => console.log(t + "\n")
|
|
1891
|
-
};
|
|
1892
|
-
for (let fixture of this.fixtures) {
|
|
1893
|
-
await fixture.load(output);
|
|
1894
|
-
}
|
|
1895
|
-
}
|
|
1896
|
-
};
|
|
1897
|
-
Fixtures = __decorate([
|
|
1898
|
-
injectable(),
|
|
1899
|
-
scoped(Lifecycle.ContainerScoped),
|
|
1900
|
-
__param(0, injectAll(FIXTURE)),
|
|
1901
|
-
__metadata("design:paramtypes", [Array])
|
|
1902
|
-
], Fixtures);
|
|
1903
|
-
|
|
1904
2112
|
const sharp$1 = sharp_;
|
|
1905
2113
|
const bigSize = 1500;
|
|
1906
2114
|
const thumbSize = 250;
|
|
@@ -2346,154 +2554,6 @@ MemoryCache = __decorate([
|
|
|
2346
2554
|
__metadata("design:paramtypes", [Cache])
|
|
2347
2555
|
], MemoryCache);
|
|
2348
2556
|
|
|
2349
|
-
function checkValue(multi, value) {
|
|
2350
|
-
if (multi) {
|
|
2351
|
-
return Array.isArray(value) && value.every(v => {
|
|
2352
|
-
try {
|
|
2353
|
-
const id = new ObjectId$1(v);
|
|
2354
|
-
return id instanceof ObjectId$1;
|
|
2355
|
-
}
|
|
2356
|
-
catch (e) {
|
|
2357
|
-
return false;
|
|
2358
|
-
}
|
|
2359
|
-
});
|
|
2360
|
-
}
|
|
2361
|
-
if (null === value)
|
|
2362
|
-
return true;
|
|
2363
|
-
try {
|
|
2364
|
-
const id = new ObjectId$1(value);
|
|
2365
|
-
return id instanceof ObjectId$1;
|
|
2366
|
-
}
|
|
2367
|
-
catch (e) {
|
|
2368
|
-
return false;
|
|
2369
|
-
}
|
|
2370
|
-
}
|
|
2371
|
-
let IsFile = class IsFile {
|
|
2372
|
-
validate(value, validationArguments) {
|
|
2373
|
-
const [multi] = (validationArguments.constraints || []);
|
|
2374
|
-
return checkValue(multi, value);
|
|
2375
|
-
}
|
|
2376
|
-
};
|
|
2377
|
-
IsFile = __decorate([
|
|
2378
|
-
ValidatorConstraint()
|
|
2379
|
-
], IsFile);
|
|
2380
|
-
let IsObjectId = class IsObjectId {
|
|
2381
|
-
validate(value, validationArguments) {
|
|
2382
|
-
const [_, multi] = (validationArguments.constraints || []);
|
|
2383
|
-
return checkValue(multi, value);
|
|
2384
|
-
}
|
|
2385
|
-
};
|
|
2386
|
-
IsObjectId = __decorate([
|
|
2387
|
-
ValidatorConstraint()
|
|
2388
|
-
], IsObjectId);
|
|
2389
|
-
|
|
2390
|
-
let OpenApi = class OpenApi {
|
|
2391
|
-
constructor(container, customValidation) {
|
|
2392
|
-
this.container = container;
|
|
2393
|
-
this.customValidation = customValidation;
|
|
2394
|
-
this.docs = null;
|
|
2395
|
-
}
|
|
2396
|
-
get apiDocs() {
|
|
2397
|
-
if (!this.docs)
|
|
2398
|
-
this.docs = this.createApiDocs();
|
|
2399
|
-
return this.docs;
|
|
2400
|
-
}
|
|
2401
|
-
get apiDocsStr() {
|
|
2402
|
-
if (!this.docsStr)
|
|
2403
|
-
this.docsStr = JSON.stringify(this.apiDocs);
|
|
2404
|
-
return this.docsStr;
|
|
2405
|
-
}
|
|
2406
|
-
async schemaToExample(src, req) {
|
|
2407
|
-
const maybeRef = src;
|
|
2408
|
-
if (maybeRef.$ref) {
|
|
2409
|
-
const schemas = this.apiDocs.components.schemas;
|
|
2410
|
-
const schema = maybeRef.$ref
|
|
2411
|
-
.replace("#/components/schemas/", "")
|
|
2412
|
-
.replace("#/definitions/", "");
|
|
2413
|
-
return this.schemaToExample(schemas[schema], req);
|
|
2414
|
-
}
|
|
2415
|
-
let schema = src;
|
|
2416
|
-
if (schema.oneOf) {
|
|
2417
|
-
schema = Object.assign({}, schema, schema.oneOf[0]);
|
|
2418
|
-
}
|
|
2419
|
-
if (schema.type === "object") {
|
|
2420
|
-
const result = {};
|
|
2421
|
-
await Promise.all(Object.keys(schema.properties).map(async (key) => {
|
|
2422
|
-
result[key] = await this.schemaToExample(schema.properties[key], req);
|
|
2423
|
-
}));
|
|
2424
|
-
return result;
|
|
2425
|
-
}
|
|
2426
|
-
if (schema.type === "array") {
|
|
2427
|
-
return [await this.schemaToExample(schema.items, req)];
|
|
2428
|
-
}
|
|
2429
|
-
if (schema.type === "string") {
|
|
2430
|
-
if (isDefined(schema.default)) {
|
|
2431
|
-
if (isFunction(schema.default)) {
|
|
2432
|
-
return schema.default(this.container);
|
|
2433
|
-
}
|
|
2434
|
-
return schema.default;
|
|
2435
|
-
}
|
|
2436
|
-
if (schema.format == "date") {
|
|
2437
|
-
return new Date().toISOString().substr(0, 10);
|
|
2438
|
-
}
|
|
2439
|
-
if (schema.format == "date-time") {
|
|
2440
|
-
return new Date().toISOString();
|
|
2441
|
-
}
|
|
2442
|
-
if (schema.enum) {
|
|
2443
|
-
return schema.enum[0];
|
|
2444
|
-
}
|
|
2445
|
-
return "string";
|
|
2446
|
-
}
|
|
2447
|
-
if (schema.type === "number") {
|
|
2448
|
-
return schema.default ?? 0;
|
|
2449
|
-
}
|
|
2450
|
-
else if (schema.type === "boolean") {
|
|
2451
|
-
return schema.default ?? false;
|
|
2452
|
-
}
|
|
2453
|
-
else {
|
|
2454
|
-
return schema.default ?? null;
|
|
2455
|
-
}
|
|
2456
|
-
}
|
|
2457
|
-
createApiDocs() {
|
|
2458
|
-
const storage = getMetadataArgsStorage();
|
|
2459
|
-
const docs = routingControllersToSpec(storage);
|
|
2460
|
-
docs.basePath = "/api/";
|
|
2461
|
-
docs.definitions = validationMetadatasToSchemas({
|
|
2462
|
-
classTransformerMetadataStorage: defaultMetadataStorage,
|
|
2463
|
-
additionalConverters: {
|
|
2464
|
-
[ValidationTypes.CUSTOM_VALIDATION]: (meta, options) => {
|
|
2465
|
-
const res = isFunction(this.customValidation) ? this.customValidation(meta, options) : this.customValidation;
|
|
2466
|
-
if (isObject(res))
|
|
2467
|
-
return res;
|
|
2468
|
-
const constraints = meta.constraints || [];
|
|
2469
|
-
if (meta.constraintCls === IsFile) {
|
|
2470
|
-
return {
|
|
2471
|
-
multi: constraints[0] || false,
|
|
2472
|
-
type: "file"
|
|
2473
|
-
};
|
|
2474
|
-
}
|
|
2475
|
-
if (meta.constraintCls === IsObjectId) {
|
|
2476
|
-
return {
|
|
2477
|
-
endpoint: constraints[0] || false,
|
|
2478
|
-
multi: constraints[1] || false,
|
|
2479
|
-
type: "list"
|
|
2480
|
-
};
|
|
2481
|
-
}
|
|
2482
|
-
return null;
|
|
2483
|
-
}
|
|
2484
|
-
}
|
|
2485
|
-
});
|
|
2486
|
-
docs.components.schemas = docs.definitions;
|
|
2487
|
-
return docs;
|
|
2488
|
-
}
|
|
2489
|
-
};
|
|
2490
|
-
OpenApi = __decorate([
|
|
2491
|
-
singleton(),
|
|
2492
|
-
__param(0, inject(DI_CONTAINER)),
|
|
2493
|
-
__param(1, inject(OPENAPI_VALIDATION)),
|
|
2494
|
-
__metadata("design:paramtypes", [Object, Object])
|
|
2495
|
-
], OpenApi);
|
|
2496
|
-
|
|
2497
2557
|
let TerminalManager = class TerminalManager {
|
|
2498
2558
|
constructor(logger, config, commands) {
|
|
2499
2559
|
this.logger = logger;
|
|
@@ -4091,6 +4151,8 @@ function createServices() {
|
|
|
4091
4151
|
new Parameter("zmqBackPort", 3100),
|
|
4092
4152
|
new Parameter("zmqRemoteHost", "tcp://127.0.0.1"),
|
|
4093
4153
|
new Parameter("isWorker", false),
|
|
4154
|
+
new Parameter("startWorker", false),
|
|
4155
|
+
new Parameter("fixtures", true),
|
|
4094
4156
|
new Parameter("mainEndpoint", ""),
|
|
4095
4157
|
new Parameter("idChars", "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"),
|
|
4096
4158
|
new Parameter("idSeparator", "-"),
|
|
@@ -4296,28 +4358,17 @@ async function setupBackend(config, providers, parent) {
|
|
|
4296
4358
|
const configuration = diContainer.resolve(Configuration);
|
|
4297
4359
|
const bp = diContainer.resolve(BackendProvider);
|
|
4298
4360
|
if (config.restOptions) {
|
|
4299
|
-
bp.express.use(bodyParser.json({
|
|
4300
|
-
limit: configuration.hasParam("jsonLimit")
|
|
4301
|
-
? configuration.resolve("jsonLimit")
|
|
4302
|
-
: "250mb"
|
|
4303
|
-
}));
|
|
4304
4361
|
useContainer(diContainer);
|
|
4305
4362
|
useExpressServer(bp.express, restOptions);
|
|
4306
|
-
|
|
4307
|
-
|
|
4308
|
-
|
|
4309
|
-
|
|
4310
|
-
|
|
4311
|
-
|
|
4312
|
-
|
|
4363
|
+
}
|
|
4364
|
+
if (config.socketOptions) {
|
|
4365
|
+
diContainer.register(SOCKET_CONTROLLERS, {
|
|
4366
|
+
useValue: new SocketControllers({
|
|
4367
|
+
io: bp.io,
|
|
4368
|
+
...socketOptions,
|
|
4369
|
+
})
|
|
4313
4370
|
});
|
|
4314
4371
|
}
|
|
4315
|
-
diContainer.register(SOCKET_CONTROLLERS, {
|
|
4316
|
-
useValue: new SocketControllers({
|
|
4317
|
-
io: bp.io,
|
|
4318
|
-
...socketOptions,
|
|
4319
|
-
})
|
|
4320
|
-
});
|
|
4321
4372
|
// Connect to mongo if necessary
|
|
4322
4373
|
if (configuration.hasParam("mongoUri") && configuration.resolve("mongoUri")) {
|
|
4323
4374
|
console.log("Connecting to MongoDB...");
|
|
@@ -4333,5 +4384,5 @@ async function setupBackend(config, providers, parent) {
|
|
|
4333
4384
|
* Generated bundle index. Do not edit.
|
|
4334
4385
|
*/
|
|
4335
4386
|
|
|
4336
|
-
export { AssetImageParams, AssetProcessor, AssetResolver, Assets, AuthController, BackendProvider, BaseDoc, Cache, CacheProcessor, Configuration, ConsoleColor, DI_CONTAINER, DocumentArray, EXPRESS, EndpointProvider, ErrorHandlerMiddleware, FIXTURE, Fixtures, Gallery, GalleryCache, GalleryController, HTTP_SERVER, IdGenerator, IsDocumented, IsFile, IsObjectId, JOB, JobManager, JsonResponse, LanguageMiddleware, LazyAssetGenerator, LazyAssets, Logger, MailSender, MemoryCache, MongoConnector, OPENAPI_VALIDATION, OpenApi, PARAMETER, Parameter, PrimitiveArray, Progresses, ResolveEntity, ResponseType, SOCKET_CONTROLLERS, SOCKET_SERVER, TERMINAL_COMMAND, TemplateRenderer, TerminalManager, TokenGenerator, TranslationProvider, Translator, Type, UserManager, assign, broadcast, bufferToStream, camelCaseToDash, colorize, convertValue, copy, copyStream, createIdString, createServices, createTransformer, deleteFile, deleteFromBucket, fileTypeFromBuffer, fileTypeFromStream, filter, firstItem, flatten, getConstructorName, getDirName, getExtension, getFileName, getFunctionParams, getType, getValue, groupBy, hydratePopulated, idToString, injectServices, isArray, isBoolean, isBuffer, isConstructor, isDate, isDefined, isFunction, isInterface, isNullOrUndefined, isObject, isObjectId, isPrimitive, isString, isType, jsonHighlight, lastItem, lcFirst, letsLookupStage, lookupStages, matchField, matchFieldStages, matchStage, md5, mkdirRecursive, multiSubscription, observableFromFunction, padLeft, padRight, paginate, paginateAggregations, prepareUrl, prepareUrlEmpty, prepareUrlSlash, projectStage, promiseTimeout, rand, random, readAndDeleteFile, readFile, regexEscape, regroup, replaceSpecialChars, resolveUser, runCommand, service, setupBackend, streamToBuffer, toImage, ucFirst, uniqueItems, unwindStage, valueToPromise, wrapError, writeFile };
|
|
4387
|
+
export { AssetImageParams, AssetProcessor, AssetResolver, Assets, AuthController, BackendProvider, BaseDoc, Cache, CacheProcessor, Configuration, ConsoleColor, DI_CONTAINER, DocumentArray, EXPRESS, EndpointProvider, ErrorHandlerMiddleware, FIXTURE, Fixtures, Gallery, GalleryCache, GalleryController, HTTP_SERVER, IdGenerator, IsDocumented, IsFile, IsObjectId, JOB, JobManager, JsonResponse, LanguageMiddleware, LazyAssetGenerator, LazyAssets, Logger, MailSender, MemoryCache, MongoConnector, OPENAPI_VALIDATION, OpenApi, PARAMETER, Parameter, PrimitiveArray, Progresses, ResolveEntity, ResponseType, SOCKET_CONTROLLERS, SOCKET_SERVER, TERMINAL_COMMAND, TemplateRenderer, TerminalManager, TokenGenerator, TranslationProvider, Translator, Type, UserManager, assign, broadcast, bufferToStream, camelCaseToDash, colorize, convertValue, copy, copyStream, createIdString, createServices, createTransformer, deleteFile, deleteFromBucket, fileTypeFromBuffer, fileTypeFromStream, filter, firstItem, flatten, getConstructorName, getDirName, getExtension, getFileName, getFunctionParams, getType, getValue, groupBy, gunzipPromised, gzipPromised, hydratePopulated, idToString, injectServices, isArray, isBoolean, isBuffer, isConstructor, isDate, isDefined, isFunction, isInterface, isNullOrUndefined, isObject, isObjectId, isPrimitive, isString, isType, jsonHighlight, lastItem, lcFirst, letsLookupStage, lookupStages, matchField, matchFieldStages, matchStage, md5, mkdirRecursive, multiSubscription, observableFromFunction, padLeft, padRight, paginate, paginateAggregations, prepareUrl, prepareUrlEmpty, prepareUrlSlash, projectStage, promiseTimeout, rand, random, readAndDeleteFile, readFile, regexEscape, regroup, replaceSpecialChars, resolveUser, runCommand, service, setupBackend, streamToBuffer, toImage, ucFirst, uniqueItems, unwindStage, valueToPromise, wrapError, writeFile };
|
|
4337
4388
|
//# sourceMappingURL=stemy-backend.mjs.map
|