@stemy/backend 6.0.3 → 6.1.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/commands/clear.command.d.ts +6 -0
- package/commands/fixtures.command.d.ts +9 -0
- package/commands/move-assets.command.d.ts +10 -0
- package/common-types.d.ts +22 -12
- package/esm2022/commands/clear.command.mjs +15 -0
- package/esm2022/commands/fixtures.command.mjs +26 -0
- package/esm2022/commands/index.mjs +6 -4
- package/esm2022/commands/move-assets.command.mjs +45 -0
- package/esm2022/common-types.mjs +3 -3
- package/esm2022/public_api.mjs +18 -6
- package/esm2022/services/assets.mjs +46 -13
- package/esm2022/services/backend-provider.mjs +7 -1
- package/esm2022/services/cli-terminal.mjs +56 -0
- package/esm2022/services/configuration.mjs +11 -4
- package/esm2022/services/drivers/asset-fallback-driver.mjs +35 -0
- package/esm2022/services/drivers/asset-grid.driver.mjs +5 -7
- package/esm2022/services/drivers/asset-local.driver.mjs +19 -18
- package/esm2022/services/drivers/asset-storage-proxy.driver.mjs +48 -0
- package/esm2022/services/drivers/fallback-readable.mjs +34 -0
- package/esm2022/services/drivers/fallback-streams.mjs +34 -0
- package/esm2022/services/entities/asset.mjs +50 -15
- package/esm2022/services/entities/temp-asset.mjs +15 -3
- package/esm2022/services/terminal-manager.mjs +30 -16
- package/esm2022/socket-controllers/socket-terminal.mjs +89 -0
- package/esm2022/socket-controllers/terminal.controller.mjs +3 -3
- package/fesm2022/stemy-backend.mjs +423 -140
- package/fesm2022/stemy-backend.mjs.map +1 -1
- package/package.json +3 -2
- package/public_api.d.ts +2 -1
- package/services/assets.d.ts +13 -5
- package/services/cli-terminal.d.ts +18 -0
- package/services/configuration.d.ts +2 -0
- package/services/drivers/asset-fallback-driver.d.ts +11 -0
- package/services/drivers/asset-grid.driver.d.ts +4 -5
- package/services/drivers/asset-local.driver.d.ts +6 -6
- package/services/drivers/asset-storage-proxy.driver.d.ts +14 -0
- package/services/drivers/fallback-readable.d.ts +2 -0
- package/services/drivers/fallback-streams.d.ts +2 -0
- package/services/entities/asset.d.ts +8 -3
- package/services/entities/temp-asset.d.ts +6 -1
- package/services/terminal-manager.d.ts +3 -0
- package/socket-controllers/socket-terminal.d.ts +19 -0
- package/socket-controllers/terminal.controller.d.ts +2 -2
|
@@ -8,14 +8,14 @@ import { create } from 'fontkit';
|
|
|
8
8
|
import sharp_ from 'sharp';
|
|
9
9
|
import { ObjectId as ObjectId$1 } from 'bson';
|
|
10
10
|
import axios from 'axios';
|
|
11
|
-
import { mkdir, unlink, readFile as readFile$1, writeFile as writeFile$1, lstat, readdir, access, constants, lstatSync, readFileSync, existsSync, mkdirSync, createWriteStream, createReadStream } from 'fs';
|
|
11
|
+
import { mkdir, unlink, readFile as readFile$1, writeFile as writeFile$1, lstat, readdir, access, constants, lstatSync, readFileSync, existsSync, mkdirSync, createWriteStream, writeFileSync, createReadStream } from 'fs';
|
|
12
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';
|
|
16
16
|
import { Subscription, Observable, Subject, from, BehaviorSubject } from 'rxjs';
|
|
17
17
|
import { ObjectId } from 'mongodb';
|
|
18
|
-
import mongoose
|
|
18
|
+
import mongoose from 'mongoose';
|
|
19
19
|
import { Readable, PassThrough } from 'stream';
|
|
20
20
|
import fileType from 'file-type/core';
|
|
21
21
|
import dotenv from 'dotenv';
|
|
@@ -31,14 +31,16 @@ import { routingControllersToSpec, OpenAPI, getStatusCode } from 'routing-contro
|
|
|
31
31
|
import { defaultMetadataStorage } from 'class-transformer/cjs/storage';
|
|
32
32
|
import { validationMetadatasToSchemas } from 'class-validator-jsonschema';
|
|
33
33
|
import { ValidatorConstraint, ValidationTypes, Min, Max, IsOptional, IsBoolean } from 'class-validator';
|
|
34
|
+
import { CommandsAddon, AnsiCodes } from '@stemy/terminal-commands-addon';
|
|
35
|
+
import * as readline from 'readline';
|
|
34
36
|
import { v4 } from 'uuid';
|
|
35
37
|
import { createTransport } from 'nodemailer';
|
|
36
38
|
import * as Handlebars from 'handlebars';
|
|
37
|
-
import { CommandsAddon, AnsiCodes } from '@stemy/terminal-commands-addon';
|
|
38
39
|
import { compare } from 'bcrypt';
|
|
39
40
|
import moment from 'moment';
|
|
40
41
|
import { GridFSBucket } from 'mongodb/lib/gridfs';
|
|
41
|
-
import {
|
|
42
|
+
import { rm } from 'fs/promises';
|
|
43
|
+
import got from 'got';
|
|
42
44
|
import { getModelForClass } from '@typegoose/typegoose';
|
|
43
45
|
import { getValue as getValue$1, setValue } from 'mongoose/lib/utils';
|
|
44
46
|
|
|
@@ -55,8 +57,8 @@ const SOCKET_CONTROLLERS = Symbol.for("socket-controllers-token");
|
|
|
55
57
|
const PARAMETER = Symbol.for("parameter-token");
|
|
56
58
|
const DI_CONTAINER = Symbol.for("di-container-token");
|
|
57
59
|
const OPENAPI_VALIDATION = Symbol.for("openapi-validation-token");
|
|
58
|
-
const
|
|
59
|
-
const
|
|
60
|
+
const ASSET_LOCAL_DIR = Symbol.for('asset-local-dir');
|
|
61
|
+
const ASSET_DRIVER_FACTORIES = Symbol.for('assets-driver-factories');
|
|
60
62
|
class Parameter {
|
|
61
63
|
name;
|
|
62
64
|
defaultValue;
|
|
@@ -864,10 +866,12 @@ async function fileTypeFromBuffer(buffer) {
|
|
|
864
866
|
}
|
|
865
867
|
|
|
866
868
|
let Configuration = class Configuration {
|
|
869
|
+
isCli;
|
|
867
870
|
paramMap;
|
|
868
871
|
paramValues;
|
|
869
872
|
constructor(params) {
|
|
870
873
|
dotenv.config();
|
|
874
|
+
this.isCli = process.env.IS_CLI === 'true';
|
|
871
875
|
this.paramMap = {};
|
|
872
876
|
this.paramValues = {};
|
|
873
877
|
(params || []).forEach(param => this.add(param));
|
|
@@ -888,15 +892,15 @@ let Configuration = class Configuration {
|
|
|
888
892
|
const value = isFunction(param.resolver)
|
|
889
893
|
? param.resolver(envValue, helper)
|
|
890
894
|
: convertValue(envValue, getType(param.defaultValue));
|
|
891
|
-
|
|
895
|
+
this.log(colorize(`Processing param value`, ConsoleColor.FgYellow), colorize(param.name, ConsoleColor.FgGreen), colorize(envName, ConsoleColor.FgBlue), `"${envValue}"`, value);
|
|
892
896
|
return value;
|
|
893
897
|
}
|
|
894
898
|
else if (isFunction(param.resolver)) {
|
|
895
899
|
const value = param.resolver(param.defaultValue, helper);
|
|
896
|
-
|
|
900
|
+
this.log(colorize(`Processing default param value`, ConsoleColor.FgYellow), colorize(param.name, ConsoleColor.FgGreen), param.defaultValue, value);
|
|
897
901
|
return value;
|
|
898
902
|
}
|
|
899
|
-
|
|
903
|
+
this.log(colorize(`Using default param value`, ConsoleColor.FgYellow), colorize(param.name, ConsoleColor.FgGreen), param.defaultValue);
|
|
900
904
|
return param.defaultValue;
|
|
901
905
|
}
|
|
902
906
|
hasParam(name) {
|
|
@@ -918,6 +922,11 @@ let Configuration = class Configuration {
|
|
|
918
922
|
}
|
|
919
923
|
return this.paramValues[name];
|
|
920
924
|
}
|
|
925
|
+
log(...args) {
|
|
926
|
+
if (this.isCli)
|
|
927
|
+
return;
|
|
928
|
+
console.log(...args);
|
|
929
|
+
}
|
|
921
930
|
};
|
|
922
931
|
Configuration = __decorate([
|
|
923
932
|
singleton(),
|
|
@@ -989,10 +998,19 @@ class BaseEntity {
|
|
|
989
998
|
}
|
|
990
999
|
|
|
991
1000
|
class Asset extends BaseEntity {
|
|
992
|
-
|
|
1001
|
+
drivers;
|
|
993
1002
|
get filename() {
|
|
994
1003
|
return this.data.filename;
|
|
995
1004
|
}
|
|
1005
|
+
get streamId() {
|
|
1006
|
+
return this.data.streamId || this.oid;
|
|
1007
|
+
}
|
|
1008
|
+
get driverId() {
|
|
1009
|
+
return this.data.driverId;
|
|
1010
|
+
}
|
|
1011
|
+
get driver() {
|
|
1012
|
+
return this.drivers.getDriver(this.driverId || this.drivers.missingDriver);
|
|
1013
|
+
}
|
|
996
1014
|
get contentType() {
|
|
997
1015
|
return this.data.contentType;
|
|
998
1016
|
}
|
|
@@ -1000,26 +1018,20 @@ class Asset extends BaseEntity {
|
|
|
1000
1018
|
return this.data.metadata;
|
|
1001
1019
|
}
|
|
1002
1020
|
get stream() {
|
|
1003
|
-
return this.driver.openDownloadStream(this
|
|
1021
|
+
return this.driver.openDownloadStream(this);
|
|
1004
1022
|
}
|
|
1005
|
-
constructor(id, data, collection,
|
|
1023
|
+
constructor(id, data, collection, drivers) {
|
|
1006
1024
|
super(id, data, collection);
|
|
1007
|
-
this.
|
|
1025
|
+
this.drivers = drivers;
|
|
1008
1026
|
}
|
|
1009
1027
|
async unlink() {
|
|
1010
1028
|
try {
|
|
1011
|
-
await this.driver.delete(this
|
|
1012
|
-
await this.collection.deleteOne({ _id: this.oid });
|
|
1029
|
+
await this.driver.delete(this);
|
|
1013
1030
|
}
|
|
1014
1031
|
catch (error) {
|
|
1015
|
-
|
|
1016
|
-
if (error) {
|
|
1017
|
-
err = error.message || error || "";
|
|
1018
|
-
if (!isString(err) || !err.startsWith("FileNotFound")) {
|
|
1019
|
-
throw err;
|
|
1020
|
-
}
|
|
1021
|
-
}
|
|
1032
|
+
console.log("Failed to unlink", error?.message);
|
|
1022
1033
|
}
|
|
1034
|
+
await this.collection.deleteOne({ _id: this.oid });
|
|
1023
1035
|
return this.id;
|
|
1024
1036
|
}
|
|
1025
1037
|
async setMeta(metadata) {
|
|
@@ -1029,6 +1041,38 @@ class Asset extends BaseEntity {
|
|
|
1029
1041
|
getBuffer() {
|
|
1030
1042
|
return streamToBuffer(this.stream);
|
|
1031
1043
|
}
|
|
1044
|
+
async move(driverId) {
|
|
1045
|
+
const oldDriver = this.driver;
|
|
1046
|
+
const targetDriver = this.drivers.getDriver(driverId);
|
|
1047
|
+
if (targetDriver === oldDriver)
|
|
1048
|
+
return this;
|
|
1049
|
+
const oldAsset = new Asset(this.oid, this.data, this.collection, this.drivers);
|
|
1050
|
+
const streamId = await this.uploadTo(targetDriver);
|
|
1051
|
+
this.data = {
|
|
1052
|
+
...this.data,
|
|
1053
|
+
streamId,
|
|
1054
|
+
driverId,
|
|
1055
|
+
};
|
|
1056
|
+
await this.save();
|
|
1057
|
+
await oldDriver.delete(oldAsset);
|
|
1058
|
+
}
|
|
1059
|
+
uploadTo(driver) {
|
|
1060
|
+
return new Promise((resolve, reject) => {
|
|
1061
|
+
const uploaderStream = driver.openUploadStream(this.filename, {
|
|
1062
|
+
chunkSizeBytes: 1048576,
|
|
1063
|
+
contentType: this.contentType,
|
|
1064
|
+
extension: this.metadata.extension,
|
|
1065
|
+
metadata: this.metadata,
|
|
1066
|
+
});
|
|
1067
|
+
this.stream.pipe(uploaderStream)
|
|
1068
|
+
.on("error", error => {
|
|
1069
|
+
reject(error.message || error);
|
|
1070
|
+
})
|
|
1071
|
+
.on("finish", async () => {
|
|
1072
|
+
resolve(uploaderStream.id);
|
|
1073
|
+
});
|
|
1074
|
+
});
|
|
1075
|
+
}
|
|
1032
1076
|
async download(metadata) {
|
|
1033
1077
|
metadata = Object.assign(this.metadata, metadata || {});
|
|
1034
1078
|
metadata.downloadCount = isNaN(metadata.downloadCount) || !metadata.firstDownload
|
|
@@ -1052,16 +1096,25 @@ class TempAsset {
|
|
|
1052
1096
|
filename;
|
|
1053
1097
|
contentType;
|
|
1054
1098
|
metadata;
|
|
1055
|
-
id
|
|
1099
|
+
get id() {
|
|
1100
|
+
return this.oid.toHexString();
|
|
1101
|
+
}
|
|
1102
|
+
get streamId() {
|
|
1103
|
+
return this.oid;
|
|
1104
|
+
}
|
|
1105
|
+
get driverId() {
|
|
1106
|
+
return "temp";
|
|
1107
|
+
}
|
|
1056
1108
|
get stream() {
|
|
1057
1109
|
return bufferToStream(this.buffer);
|
|
1058
1110
|
}
|
|
1111
|
+
oid;
|
|
1059
1112
|
constructor(buffer, filename, contentType, metadata) {
|
|
1060
1113
|
this.buffer = buffer;
|
|
1061
1114
|
this.filename = filename;
|
|
1062
1115
|
this.contentType = contentType;
|
|
1063
1116
|
this.metadata = metadata;
|
|
1064
|
-
this.
|
|
1117
|
+
this.oid = new ObjectId$1();
|
|
1065
1118
|
}
|
|
1066
1119
|
async unlink() {
|
|
1067
1120
|
throw new Error(`Temp asset '${this.id}' can not be removed!`);
|
|
@@ -1072,6 +1125,9 @@ class TempAsset {
|
|
|
1072
1125
|
async getBuffer() {
|
|
1073
1126
|
return this.buffer;
|
|
1074
1127
|
}
|
|
1128
|
+
async move() {
|
|
1129
|
+
throw new Error(`Temp asset '${this.id}' can not be moved!`);
|
|
1130
|
+
}
|
|
1075
1131
|
async download(metadata) {
|
|
1076
1132
|
return this.stream;
|
|
1077
1133
|
}
|
|
@@ -1101,13 +1157,38 @@ class TempAsset {
|
|
|
1101
1157
|
let Assets = class Assets {
|
|
1102
1158
|
connector;
|
|
1103
1159
|
assetProcessor;
|
|
1104
|
-
|
|
1160
|
+
config;
|
|
1161
|
+
container;
|
|
1162
|
+
driverFactoryMap;
|
|
1105
1163
|
collection;
|
|
1106
|
-
|
|
1164
|
+
driverMap;
|
|
1165
|
+
mainDriver;
|
|
1166
|
+
missingDriver;
|
|
1167
|
+
drivers;
|
|
1168
|
+
constructor(connector, assetProcessor, config, container, driverFactoryMap) {
|
|
1107
1169
|
this.connector = connector;
|
|
1108
1170
|
this.assetProcessor = assetProcessor;
|
|
1109
|
-
this.
|
|
1171
|
+
this.config = config;
|
|
1172
|
+
this.container = container;
|
|
1173
|
+
this.driverFactoryMap = driverFactoryMap;
|
|
1110
1174
|
this.collection = connector.database?.collection("assets.metadata");
|
|
1175
|
+
this.driverMap = new Map();
|
|
1176
|
+
this.mainDriver = this.config.resolve("assetsMainDriver");
|
|
1177
|
+
this.missingDriver = this.config.resolve("assetsMissingDriver");
|
|
1178
|
+
this.drivers = Object.keys(driverFactoryMap);
|
|
1179
|
+
}
|
|
1180
|
+
getDriver(name) {
|
|
1181
|
+
if (!name) {
|
|
1182
|
+
throw new Error(`No name provider for asset driver!`);
|
|
1183
|
+
}
|
|
1184
|
+
if (!this.driverMap.has(name)) {
|
|
1185
|
+
const factory = this.driverFactoryMap[name];
|
|
1186
|
+
if (!factory) {
|
|
1187
|
+
throw new Error(`No asset driver factory found with name: '${name}'!`);
|
|
1188
|
+
}
|
|
1189
|
+
this.driverMap.set(name, factory(this.container));
|
|
1190
|
+
}
|
|
1191
|
+
return this.driverMap.get(name);
|
|
1111
1192
|
}
|
|
1112
1193
|
async write(stream, contentType = null, metadata = null) {
|
|
1113
1194
|
const uploadStream = copyStream(stream);
|
|
@@ -1176,7 +1257,7 @@ let Assets = class Assets {
|
|
|
1176
1257
|
}
|
|
1177
1258
|
async find(where) {
|
|
1178
1259
|
const data = await this.collection.findOne(where);
|
|
1179
|
-
return !data ? null : new Asset(data._id, data, this.collection, this
|
|
1260
|
+
return !data ? null : new Asset(data._id, data, this.collection, this);
|
|
1180
1261
|
}
|
|
1181
1262
|
async findMany(where) {
|
|
1182
1263
|
const cursor = this.collection.find(where);
|
|
@@ -1185,7 +1266,7 @@ let Assets = class Assets {
|
|
|
1185
1266
|
for (let item of items) {
|
|
1186
1267
|
if (!item)
|
|
1187
1268
|
continue;
|
|
1188
|
-
result.push(new Asset(item._id, item, this.collection, this
|
|
1269
|
+
result.push(new Asset(item._id, item, this.collection, this));
|
|
1189
1270
|
}
|
|
1190
1271
|
return result;
|
|
1191
1272
|
}
|
|
@@ -1209,10 +1290,13 @@ let Assets = class Assets {
|
|
|
1209
1290
|
metadata.filename = metadata.filename || new ObjectId$1().toHexString();
|
|
1210
1291
|
metadata.extension = (fileType.ext || "").trim();
|
|
1211
1292
|
return new Promise(((resolve, reject) => {
|
|
1212
|
-
const
|
|
1293
|
+
const driverId = this.mainDriver;
|
|
1294
|
+
const driver = this.getDriver(driverId);
|
|
1295
|
+
const uploaderStream = driver.openUploadStream(metadata.filename, {
|
|
1213
1296
|
chunkSizeBytes: 1048576,
|
|
1297
|
+
contentType: fileType.mime,
|
|
1298
|
+
extension: fileType.ext,
|
|
1214
1299
|
metadata,
|
|
1215
|
-
contentType: fileType.mime
|
|
1216
1300
|
});
|
|
1217
1301
|
stream.pipe(uploaderStream)
|
|
1218
1302
|
.on("error", error => {
|
|
@@ -1220,10 +1304,12 @@ let Assets = class Assets {
|
|
|
1220
1304
|
})
|
|
1221
1305
|
.on("finish", () => {
|
|
1222
1306
|
const asset = new Asset(uploaderStream.id, {
|
|
1307
|
+
streamId: uploaderStream.id,
|
|
1223
1308
|
filename: metadata.filename,
|
|
1224
1309
|
contentType,
|
|
1225
|
-
metadata
|
|
1226
|
-
|
|
1310
|
+
metadata,
|
|
1311
|
+
driverId
|
|
1312
|
+
}, this.collection, this);
|
|
1227
1313
|
asset.save().then(() => {
|
|
1228
1314
|
resolve(asset);
|
|
1229
1315
|
}, error => {
|
|
@@ -1236,9 +1322,11 @@ let Assets = class Assets {
|
|
|
1236
1322
|
Assets = __decorate([
|
|
1237
1323
|
injectable(),
|
|
1238
1324
|
scoped(Lifecycle.ContainerScoped),
|
|
1239
|
-
__param(
|
|
1325
|
+
__param(3, inject(DI_CONTAINER)),
|
|
1326
|
+
__param(4, inject(ASSET_DRIVER_FACTORIES)),
|
|
1240
1327
|
__metadata("design:paramtypes", [MongoConnector,
|
|
1241
|
-
AssetProcessor,
|
|
1328
|
+
AssetProcessor,
|
|
1329
|
+
Configuration, Object, Object])
|
|
1242
1330
|
], Assets);
|
|
1243
1331
|
|
|
1244
1332
|
class LazyAsset extends BaseEntity {
|
|
@@ -2086,6 +2174,154 @@ Fixtures = __decorate([
|
|
|
2086
2174
|
__metadata("design:paramtypes", [Object])
|
|
2087
2175
|
], Fixtures);
|
|
2088
2176
|
|
|
2177
|
+
class CliTerminal {
|
|
2178
|
+
callbacks = new Set();
|
|
2179
|
+
stdin = process.stdin;
|
|
2180
|
+
constructor() {
|
|
2181
|
+
// Set stdin to raw mode to get character-by-character data
|
|
2182
|
+
if (this.stdin.isTTY) {
|
|
2183
|
+
this.stdin.setRawMode(true);
|
|
2184
|
+
}
|
|
2185
|
+
this.clearScreen();
|
|
2186
|
+
this.stdin.setEncoding('utf8');
|
|
2187
|
+
this.stdin.on('data', this.handleInput);
|
|
2188
|
+
}
|
|
2189
|
+
clearScreen() {
|
|
2190
|
+
readline.cursorTo(process.stdout, 0, 0);
|
|
2191
|
+
readline.clearScreenDown(process.stdout);
|
|
2192
|
+
}
|
|
2193
|
+
handleInput = (data) => {
|
|
2194
|
+
const input = data.toString();
|
|
2195
|
+
// Standard "Ctrl+C" exit handling
|
|
2196
|
+
if (input === '\u0003') {
|
|
2197
|
+
this.clearScreen();
|
|
2198
|
+
this.dispose();
|
|
2199
|
+
}
|
|
2200
|
+
this.callbacks.forEach((cb) => cb(input));
|
|
2201
|
+
};
|
|
2202
|
+
/**
|
|
2203
|
+
* Registers a listener for data input.
|
|
2204
|
+
* Returns an IDisposable to unregister the listener.
|
|
2205
|
+
*/
|
|
2206
|
+
onData(cb) {
|
|
2207
|
+
this.callbacks.add(cb);
|
|
2208
|
+
return {
|
|
2209
|
+
dispose: () => this.callbacks.delete(cb),
|
|
2210
|
+
};
|
|
2211
|
+
}
|
|
2212
|
+
write(data) {
|
|
2213
|
+
process.stdout.write(data);
|
|
2214
|
+
}
|
|
2215
|
+
writeln(data) {
|
|
2216
|
+
process.stdout.write(data + '\n');
|
|
2217
|
+
}
|
|
2218
|
+
loadAddon(addon) {
|
|
2219
|
+
addon.activate(this);
|
|
2220
|
+
}
|
|
2221
|
+
dispose() {
|
|
2222
|
+
if (this.stdin.isTTY) {
|
|
2223
|
+
this.stdin.setRawMode(false);
|
|
2224
|
+
}
|
|
2225
|
+
this.stdin.removeListener('data', this.handleInput);
|
|
2226
|
+
this.stdin.pause();
|
|
2227
|
+
this.callbacks.clear();
|
|
2228
|
+
process.exit();
|
|
2229
|
+
}
|
|
2230
|
+
}
|
|
2231
|
+
|
|
2232
|
+
let TerminalManager = class TerminalManager {
|
|
2233
|
+
logger;
|
|
2234
|
+
config;
|
|
2235
|
+
cliTerminal;
|
|
2236
|
+
servicePassword;
|
|
2237
|
+
suggestions;
|
|
2238
|
+
commands;
|
|
2239
|
+
loggedOutCommands;
|
|
2240
|
+
loggedInCommands;
|
|
2241
|
+
constructor(logger, config, commands) {
|
|
2242
|
+
this.logger = logger;
|
|
2243
|
+
this.config = config;
|
|
2244
|
+
this.servicePassword = config.resolve("servicePassword");
|
|
2245
|
+
this.suggestions = {
|
|
2246
|
+
login: async (args) => {
|
|
2247
|
+
if (args.length > 2) {
|
|
2248
|
+
return null;
|
|
2249
|
+
}
|
|
2250
|
+
const input = `${args.at(1).label}`;
|
|
2251
|
+
return (!input) ? [] : [{
|
|
2252
|
+
id: input,
|
|
2253
|
+
label: input,
|
|
2254
|
+
masked: true
|
|
2255
|
+
}];
|
|
2256
|
+
},
|
|
2257
|
+
...commands.reduce((acc, command) => {
|
|
2258
|
+
command.name = camelCaseToDash(command.name || command.constructor.name || "");
|
|
2259
|
+
if (!command.name || !command.suggest)
|
|
2260
|
+
return acc;
|
|
2261
|
+
acc[command.name] = async (a, t) => command.suggest(a, t);
|
|
2262
|
+
return acc;
|
|
2263
|
+
}, {})
|
|
2264
|
+
};
|
|
2265
|
+
this.commands = commands.reduce((acc, command) => {
|
|
2266
|
+
if (!command.name)
|
|
2267
|
+
return acc;
|
|
2268
|
+
acc[command.name] = async (a, t, p) => command.execute(a, t, p);
|
|
2269
|
+
return acc;
|
|
2270
|
+
}, {});
|
|
2271
|
+
this.loggedOutCommands = ["login", "clear"];
|
|
2272
|
+
this.loggedInCommands = Object.keys(this.commands);
|
|
2273
|
+
this.loggedInCommands.push("logout");
|
|
2274
|
+
console.log(`Current service password is: ${colorize(this.servicePassword, ConsoleColor.FgGreen)}`);
|
|
2275
|
+
}
|
|
2276
|
+
runCli() {
|
|
2277
|
+
this.cliTerminal = new CliTerminal();
|
|
2278
|
+
this.loadAddons(this.cliTerminal);
|
|
2279
|
+
}
|
|
2280
|
+
loadAddons(terminal) {
|
|
2281
|
+
const isCli = terminal === this.cliTerminal;
|
|
2282
|
+
let loggedIn = isCli;
|
|
2283
|
+
const commands = isCli ? {
|
|
2284
|
+
logout: async () => {
|
|
2285
|
+
terminal.dispose();
|
|
2286
|
+
}
|
|
2287
|
+
} : {
|
|
2288
|
+
login: async (args, terminal) => {
|
|
2289
|
+
if (args.at(1).label === this.servicePassword) {
|
|
2290
|
+
loggedIn = true;
|
|
2291
|
+
terminal.writeln("Logged in as admin");
|
|
2292
|
+
}
|
|
2293
|
+
else {
|
|
2294
|
+
throw new Error("Invalid login");
|
|
2295
|
+
}
|
|
2296
|
+
},
|
|
2297
|
+
logout: async (args, terminal) => {
|
|
2298
|
+
loggedIn = false;
|
|
2299
|
+
terminal.writeln("Logged out");
|
|
2300
|
+
}
|
|
2301
|
+
};
|
|
2302
|
+
const addon = new CommandsAddon({
|
|
2303
|
+
commands: {
|
|
2304
|
+
...commands,
|
|
2305
|
+
...this.commands
|
|
2306
|
+
},
|
|
2307
|
+
suggestCommands: async () => {
|
|
2308
|
+
if (loggedIn) {
|
|
2309
|
+
return this.loggedInCommands;
|
|
2310
|
+
}
|
|
2311
|
+
return this.loggedOutCommands;
|
|
2312
|
+
},
|
|
2313
|
+
suggestions: this.suggestions
|
|
2314
|
+
});
|
|
2315
|
+
terminal.loadAddon(addon);
|
|
2316
|
+
}
|
|
2317
|
+
};
|
|
2318
|
+
TerminalManager = __decorate([
|
|
2319
|
+
singleton(),
|
|
2320
|
+
__param(2, injectAll(TERMINAL_COMMAND)),
|
|
2321
|
+
__metadata("design:paramtypes", [Logger,
|
|
2322
|
+
Configuration, Array])
|
|
2323
|
+
], TerminalManager);
|
|
2324
|
+
|
|
2089
2325
|
const express = express_;
|
|
2090
2326
|
let BackendProvider = class BackendProvider {
|
|
2091
2327
|
config;
|
|
@@ -2134,6 +2370,11 @@ let BackendProvider = class BackendProvider {
|
|
|
2134
2370
|
}
|
|
2135
2371
|
async quickStart() {
|
|
2136
2372
|
const port = this.config.resolve("appPort");
|
|
2373
|
+
const isCli = this.config.isCli;
|
|
2374
|
+
if (isCli) {
|
|
2375
|
+
this.container.resolve(TerminalManager).runCli();
|
|
2376
|
+
return `Running CLI mode`;
|
|
2377
|
+
}
|
|
2137
2378
|
const isWorker = this.config.resolve("isWorker");
|
|
2138
2379
|
if (isWorker || this.config.resolve("startWorker")) {
|
|
2139
2380
|
await this.container.resolve(JobManager).startProcessing();
|
|
@@ -2717,86 +2958,6 @@ MemoryCache = __decorate([
|
|
|
2717
2958
|
__metadata("design:paramtypes", [Cache])
|
|
2718
2959
|
], MemoryCache);
|
|
2719
2960
|
|
|
2720
|
-
let TerminalManager = class TerminalManager {
|
|
2721
|
-
logger;
|
|
2722
|
-
config;
|
|
2723
|
-
servicePassword;
|
|
2724
|
-
suggestions;
|
|
2725
|
-
commands;
|
|
2726
|
-
loggedOutCommands;
|
|
2727
|
-
loggedInCommands;
|
|
2728
|
-
constructor(logger, config, commands) {
|
|
2729
|
-
this.logger = logger;
|
|
2730
|
-
this.config = config;
|
|
2731
|
-
this.servicePassword = config.resolve("servicePassword");
|
|
2732
|
-
this.suggestions = {
|
|
2733
|
-
login: async (args) => {
|
|
2734
|
-
if (args.length > 2) {
|
|
2735
|
-
return null;
|
|
2736
|
-
}
|
|
2737
|
-
const input = `${args.at(1).label}`;
|
|
2738
|
-
return (!input) ? [] : [{
|
|
2739
|
-
id: input,
|
|
2740
|
-
label: input,
|
|
2741
|
-
masked: true
|
|
2742
|
-
}];
|
|
2743
|
-
},
|
|
2744
|
-
...commands.reduce((acc, command) => {
|
|
2745
|
-
command.name = camelCaseToDash(command.name || command.constructor.name || "");
|
|
2746
|
-
if (!command.name || !command.suggest)
|
|
2747
|
-
return acc;
|
|
2748
|
-
acc[command.name] = async (a, t) => command.suggest(a, t);
|
|
2749
|
-
return acc;
|
|
2750
|
-
}, {})
|
|
2751
|
-
};
|
|
2752
|
-
this.commands = commands.reduce((acc, command) => {
|
|
2753
|
-
if (!command.name)
|
|
2754
|
-
return acc;
|
|
2755
|
-
acc[command.name] = async (a, t) => command.execute(a, t);
|
|
2756
|
-
return acc;
|
|
2757
|
-
}, {});
|
|
2758
|
-
this.loggedOutCommands = ["login", "clear"];
|
|
2759
|
-
this.loggedInCommands = Object.keys(this.commands);
|
|
2760
|
-
this.loggedInCommands.push("logout");
|
|
2761
|
-
console.log(`Current service password is: ${colorize(this.servicePassword, ConsoleColor.FgGreen)}`);
|
|
2762
|
-
}
|
|
2763
|
-
loadAddons(terminal) {
|
|
2764
|
-
let loggedIn = false;
|
|
2765
|
-
const addon = new CommandsAddon({
|
|
2766
|
-
commands: {
|
|
2767
|
-
login: async (args, terminal) => {
|
|
2768
|
-
if (args.at(1).label === this.servicePassword) {
|
|
2769
|
-
loggedIn = true;
|
|
2770
|
-
terminal.writeln("Logged in as admin");
|
|
2771
|
-
}
|
|
2772
|
-
else {
|
|
2773
|
-
throw new Error("Invalid login");
|
|
2774
|
-
}
|
|
2775
|
-
},
|
|
2776
|
-
logout: async (args, terminal) => {
|
|
2777
|
-
loggedIn = false;
|
|
2778
|
-
terminal.writeln("Logged out");
|
|
2779
|
-
},
|
|
2780
|
-
...this.commands
|
|
2781
|
-
},
|
|
2782
|
-
suggestCommands: async () => {
|
|
2783
|
-
if (loggedIn) {
|
|
2784
|
-
return this.loggedInCommands;
|
|
2785
|
-
}
|
|
2786
|
-
return this.loggedOutCommands;
|
|
2787
|
-
},
|
|
2788
|
-
suggestions: this.suggestions
|
|
2789
|
-
});
|
|
2790
|
-
terminal.loadAddon(addon);
|
|
2791
|
-
}
|
|
2792
|
-
};
|
|
2793
|
-
TerminalManager = __decorate([
|
|
2794
|
-
singleton(),
|
|
2795
|
-
__param(2, injectAll(TERMINAL_COMMAND)),
|
|
2796
|
-
__metadata("design:paramtypes", [Logger,
|
|
2797
|
-
Configuration, Array])
|
|
2798
|
-
], TerminalManager);
|
|
2799
|
-
|
|
2800
2961
|
let TokenGenerator = class TokenGenerator {
|
|
2801
2962
|
chars;
|
|
2802
2963
|
constructor() {
|
|
@@ -3576,7 +3737,7 @@ ProgressController = __decorate([
|
|
|
3576
3737
|
__metadata("design:paramtypes", [Progresses, Server])
|
|
3577
3738
|
], ProgressController);
|
|
3578
3739
|
|
|
3579
|
-
class
|
|
3740
|
+
class SocketTerminal {
|
|
3580
3741
|
client;
|
|
3581
3742
|
addons;
|
|
3582
3743
|
files$;
|
|
@@ -3670,7 +3831,7 @@ let TerminalController = class TerminalController {
|
|
|
3670
3831
|
this.terminals = {};
|
|
3671
3832
|
}
|
|
3672
3833
|
async terminalInit(client) {
|
|
3673
|
-
const terminal = new
|
|
3834
|
+
const terminal = new SocketTerminal(client);
|
|
3674
3835
|
this.manager.loadAddons(terminal);
|
|
3675
3836
|
this.terminals[client.id] = terminal;
|
|
3676
3837
|
client.on("disconnect", () => terminal.dispose());
|
|
@@ -3989,9 +4150,50 @@ FixturesCommand = __decorate([
|
|
|
3989
4150
|
__metadata("design:paramtypes", [Fixtures])
|
|
3990
4151
|
], FixturesCommand);
|
|
3991
4152
|
|
|
4153
|
+
let MoveAssetsCommand = class MoveAssetsCommand {
|
|
4154
|
+
assets;
|
|
4155
|
+
name = "move-assets";
|
|
4156
|
+
constructor(assets) {
|
|
4157
|
+
this.assets = assets;
|
|
4158
|
+
}
|
|
4159
|
+
async execute(args, terminal, progress) {
|
|
4160
|
+
await promiseTimeout(1000);
|
|
4161
|
+
const from = `${args.at(1).id}`;
|
|
4162
|
+
const to = `${args.at(2).id}`;
|
|
4163
|
+
const assets = await this.assets.findMany(from === this.assets.missingDriver ? {
|
|
4164
|
+
$or: [
|
|
4165
|
+
{ driverId: from },
|
|
4166
|
+
{ driverId: { "$exists": false } }
|
|
4167
|
+
]
|
|
4168
|
+
} : { driverId: from });
|
|
4169
|
+
progress.setMax(assets.length);
|
|
4170
|
+
for (const asset of assets) {
|
|
4171
|
+
await asset.move(to);
|
|
4172
|
+
progress.advance();
|
|
4173
|
+
}
|
|
4174
|
+
terminal.writeln(colorize(`Assets successfully moved to: ${to}`, ConsoleColor.FgGreen));
|
|
4175
|
+
}
|
|
4176
|
+
async suggest(args) {
|
|
4177
|
+
if (args.length > 3) {
|
|
4178
|
+
return null;
|
|
4179
|
+
}
|
|
4180
|
+
// Replace regex special characters
|
|
4181
|
+
const prev = args.length === 3 ? args.at(1) : null;
|
|
4182
|
+
const id = regexEscape(args.search);
|
|
4183
|
+
const regex = new RegExp(id, "g");
|
|
4184
|
+
return this.assets.drivers.filter(d => d.match(regex) && (!prev || d !== prev.id));
|
|
4185
|
+
}
|
|
4186
|
+
};
|
|
4187
|
+
MoveAssetsCommand = __decorate([
|
|
4188
|
+
injectable(),
|
|
4189
|
+
scoped(Lifecycle.ContainerScoped),
|
|
4190
|
+
__metadata("design:paramtypes", [Assets])
|
|
4191
|
+
], MoveAssetsCommand);
|
|
4192
|
+
|
|
3992
4193
|
const commands = [
|
|
3993
4194
|
ClearCommand,
|
|
3994
|
-
FixturesCommand
|
|
4195
|
+
FixturesCommand,
|
|
4196
|
+
MoveAssetsCommand
|
|
3995
4197
|
];
|
|
3996
4198
|
|
|
3997
4199
|
let TtlFixture = class TtlFixture {
|
|
@@ -4018,20 +4220,18 @@ const fixtures = [
|
|
|
4018
4220
|
];
|
|
4019
4221
|
|
|
4020
4222
|
let AssetGridDriver = class AssetGridDriver {
|
|
4021
|
-
metaCollection;
|
|
4022
4223
|
bucket;
|
|
4023
4224
|
constructor(connector) {
|
|
4024
4225
|
this.bucket = new GridFSBucket(connector.database, { bucketName: 'assets' });
|
|
4025
|
-
this.metaCollection = "assets.files";
|
|
4026
4226
|
}
|
|
4027
4227
|
openUploadStream(filename, opts) {
|
|
4028
4228
|
return this.bucket.openUploadStream(filename, opts);
|
|
4029
4229
|
}
|
|
4030
|
-
openDownloadStream(
|
|
4031
|
-
return this.bucket.openDownloadStream(
|
|
4230
|
+
openDownloadStream(asset) {
|
|
4231
|
+
return this.bucket.openDownloadStream(asset.streamId);
|
|
4032
4232
|
}
|
|
4033
|
-
delete(
|
|
4034
|
-
return this.bucket.delete(
|
|
4233
|
+
delete(asset) {
|
|
4234
|
+
return this.bucket.delete(asset.streamId);
|
|
4035
4235
|
}
|
|
4036
4236
|
};
|
|
4037
4237
|
AssetGridDriver = __decorate([
|
|
@@ -4041,38 +4241,112 @@ AssetGridDriver = __decorate([
|
|
|
4041
4241
|
|
|
4042
4242
|
let AssetLocalDriver = class AssetLocalDriver {
|
|
4043
4243
|
dir;
|
|
4044
|
-
metaCollection;
|
|
4045
4244
|
constructor(dir) {
|
|
4046
4245
|
this.dir = dir;
|
|
4047
|
-
this.metaCollection = "assets.local";
|
|
4048
4246
|
}
|
|
4049
4247
|
openUploadStream(filename, opts) {
|
|
4050
|
-
const id = new
|
|
4248
|
+
const id = new ObjectId$1();
|
|
4051
4249
|
const dir = `${this.dir}/${id.toHexString()}`;
|
|
4052
4250
|
mkdirSync(dir, { recursive: true });
|
|
4053
|
-
const stream = createWriteStream(
|
|
4054
|
-
stream.id = id;
|
|
4251
|
+
const stream = createWriteStream(this.getPath(id, filename, opts.extension));
|
|
4055
4252
|
stream.done = false;
|
|
4056
4253
|
stream.on('finish', () => {
|
|
4057
|
-
|
|
4058
|
-
writeFile$2(`${dir}/metadata.json`, JSON.stringify(opts?.metadata || {}));
|
|
4254
|
+
stream.id = id;
|
|
4059
4255
|
stream.done = true;
|
|
4256
|
+
writeFileSync(`${dir}/metadata.json`, JSON.stringify(opts?.metadata || {}));
|
|
4060
4257
|
});
|
|
4061
4258
|
return stream;
|
|
4062
4259
|
}
|
|
4063
|
-
openDownloadStream(
|
|
4064
|
-
return createReadStream(
|
|
4260
|
+
openDownloadStream(asset) {
|
|
4261
|
+
return createReadStream(this.getPath(asset.streamId, asset.filename, asset.metadata.extension), { autoClose: true, emitClose: true });
|
|
4065
4262
|
}
|
|
4066
|
-
delete(
|
|
4067
|
-
return rm(
|
|
4263
|
+
delete(asset) {
|
|
4264
|
+
return rm(this.getPath(asset.streamId, asset.filename, asset.metadata.extension), { recursive: true, force: true });
|
|
4265
|
+
}
|
|
4266
|
+
getPath(id, name, ext) {
|
|
4267
|
+
return join(this.dir, id.toHexString(), `${name}.${ext}`);
|
|
4068
4268
|
}
|
|
4069
4269
|
};
|
|
4070
4270
|
AssetLocalDriver = __decorate([
|
|
4071
4271
|
injectable(),
|
|
4072
|
-
__param(0, inject(
|
|
4272
|
+
__param(0, inject(ASSET_LOCAL_DIR)),
|
|
4073
4273
|
__metadata("design:paramtypes", [String])
|
|
4074
4274
|
], AssetLocalDriver);
|
|
4075
4275
|
|
|
4276
|
+
function createFallbackReadable(primary, fallbackFactory) {
|
|
4277
|
+
const proxy = new PassThrough();
|
|
4278
|
+
let hasSwitched = false;
|
|
4279
|
+
const switchToFallback = () => {
|
|
4280
|
+
if (hasSwitched)
|
|
4281
|
+
return;
|
|
4282
|
+
hasSwitched = true;
|
|
4283
|
+
// 1. Cleanup the failing primary
|
|
4284
|
+
primary.unpipe(proxy);
|
|
4285
|
+
primary.destroy();
|
|
4286
|
+
// 2. Initialize and pipe the fallback
|
|
4287
|
+
const fallback = fallbackFactory();
|
|
4288
|
+
// On the fallback, we allow it to end the proxy naturally
|
|
4289
|
+
fallback.pipe(proxy);
|
|
4290
|
+
fallback.on('error', (err) => {
|
|
4291
|
+
proxy.emit('error', err); // If fallback fails too, it's a hard error
|
|
4292
|
+
});
|
|
4293
|
+
};
|
|
4294
|
+
// Pipe primary but prevent it from closing the proxy automatically
|
|
4295
|
+
primary.pipe(proxy, { end: false });
|
|
4296
|
+
primary.on('error', () => {
|
|
4297
|
+
switchToFallback();
|
|
4298
|
+
});
|
|
4299
|
+
// Handle the "Early End" case (e.g., stream closed before data finished)
|
|
4300
|
+
primary.on('end', () => {
|
|
4301
|
+
if (!hasSwitched) {
|
|
4302
|
+
// If we finished successfully without erroring, close the proxy
|
|
4303
|
+
proxy.end();
|
|
4304
|
+
}
|
|
4305
|
+
});
|
|
4306
|
+
return proxy;
|
|
4307
|
+
}
|
|
4308
|
+
|
|
4309
|
+
let AssetStorageProxyDriver = class AssetStorageProxyDriver {
|
|
4310
|
+
config;
|
|
4311
|
+
baseUrl;
|
|
4312
|
+
url;
|
|
4313
|
+
constructor(config) {
|
|
4314
|
+
this.config = config;
|
|
4315
|
+
this.baseUrl = this.config.resolve("storageProxyUri");
|
|
4316
|
+
this.url = this.baseUrl + this.config.resolve("storageProxyBucket");
|
|
4317
|
+
}
|
|
4318
|
+
openUploadStream(_, opts) {
|
|
4319
|
+
const id = new ObjectId$1();
|
|
4320
|
+
const stream = got.stream.put(this.getUrl(id, opts.extension), { headers: {
|
|
4321
|
+
'Content-Type': opts?.contentType || 'application/octet-stream'
|
|
4322
|
+
} });
|
|
4323
|
+
stream.done = false;
|
|
4324
|
+
stream.on('finish', () => {
|
|
4325
|
+
stream.id = id;
|
|
4326
|
+
stream.done = true;
|
|
4327
|
+
});
|
|
4328
|
+
return stream;
|
|
4329
|
+
}
|
|
4330
|
+
openDownloadStream(asset) {
|
|
4331
|
+
return createFallbackReadable(got.stream.get(this.getUrl(asset.streamId, asset.metadata.extension)), () => got.stream.get(this.getUrl(asset.streamId)));
|
|
4332
|
+
}
|
|
4333
|
+
async delete(asset) {
|
|
4334
|
+
try {
|
|
4335
|
+
await got.delete(this.getUrl(asset.streamId, asset.metadata.extension));
|
|
4336
|
+
}
|
|
4337
|
+
catch (e) {
|
|
4338
|
+
await got.delete(this.getUrl(asset.streamId));
|
|
4339
|
+
}
|
|
4340
|
+
}
|
|
4341
|
+
getUrl(id, ext) {
|
|
4342
|
+
return !ext ? `${this.url}/${id.toHexString()}` : `${this.url}/${id.toHexString()}.${ext}`;
|
|
4343
|
+
}
|
|
4344
|
+
};
|
|
4345
|
+
AssetStorageProxyDriver = __decorate([
|
|
4346
|
+
injectable(),
|
|
4347
|
+
__metadata("design:paramtypes", [Configuration])
|
|
4348
|
+
], AssetStorageProxyDriver);
|
|
4349
|
+
|
|
4076
4350
|
class BaseDoc {
|
|
4077
4351
|
_id;
|
|
4078
4352
|
/**
|
|
@@ -4450,6 +4724,10 @@ function createServices() {
|
|
|
4450
4724
|
new Parameter("mongoDb", "node-backend"),
|
|
4451
4725
|
new Parameter("mongoUser", null),
|
|
4452
4726
|
new Parameter("mongoPassword", null),
|
|
4727
|
+
new Parameter("storageProxyUri", "http://localhost:4500/files", prepareUrlSlash),
|
|
4728
|
+
new Parameter("storageProxyBucket", "something"),
|
|
4729
|
+
new Parameter("assetsMainDriver", "grid"),
|
|
4730
|
+
new Parameter("assetsMissingDriver", "grid"),
|
|
4453
4731
|
new Parameter("nodeEnv", "production"),
|
|
4454
4732
|
new Parameter("appPort", 80),
|
|
4455
4733
|
new Parameter("zmqPort", 3000),
|
|
@@ -4619,11 +4897,16 @@ async function setupBackend(config, providers, parent) {
|
|
|
4619
4897
|
diContainer.register(OPENAPI_VALIDATION, {
|
|
4620
4898
|
useValue: config.customValidation || (() => null)
|
|
4621
4899
|
});
|
|
4622
|
-
diContainer.register(
|
|
4900
|
+
diContainer.register(ASSET_LOCAL_DIR, {
|
|
4623
4901
|
useValue: config.assetLocalDir || "assets_files"
|
|
4624
4902
|
});
|
|
4625
|
-
diContainer.register(
|
|
4626
|
-
|
|
4903
|
+
diContainer.register(ASSET_DRIVER_FACTORIES, {
|
|
4904
|
+
useValue: {
|
|
4905
|
+
grid: container => container.resolve(AssetGridDriver),
|
|
4906
|
+
storageProxy: container => container.resolve(AssetStorageProxyDriver),
|
|
4907
|
+
local: container => container.resolve(AssetLocalDriver),
|
|
4908
|
+
...(config.assetDrivers || {}),
|
|
4909
|
+
}
|
|
4627
4910
|
});
|
|
4628
4911
|
diContainers.appContainer = diContainers.appContainer || diContainer;
|
|
4629
4912
|
// Authentication
|
|
@@ -4694,5 +4977,5 @@ async function setupBackend(config, providers, parent) {
|
|
|
4694
4977
|
* Generated bundle index. Do not edit.
|
|
4695
4978
|
*/
|
|
4696
4979
|
|
|
4697
|
-
export { AssetGridDriver, AssetImageParams, AssetLocalDriver, 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, 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 };
|
|
4980
|
+
export { AssetGridDriver, AssetImageParams, AssetLocalDriver, AssetProcessor, AssetResolver, AssetStorageProxyDriver, 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, 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 };
|
|
4698
4981
|
//# sourceMappingURL=stemy-backend.mjs.map
|