@minimaltech/node-infra
Version:
Minimal Technology NodeJS Infrastructure - Loopback 4 Framework
386 lines • 17.8 kB
JavaScript
;
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
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;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var __param = (this && this.__param) || function (paramIndex, decorator) {
return function (target, key) { decorator(target, key, paramIndex); }
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __asyncValues = (this && this.__asyncValues) || function (o) {
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
var m = o[Symbol.asyncIterator], i;
return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
var StaticAssetController_1;
Object.defineProperty(exports, "__esModule", { value: true });
exports.StaticAssetController = void 0;
const applications_1 = require("../../../base/applications");
const helpers_1 = require("../../../helpers");
const utilities_1 = require("../../../utilities");
const core_1 = require("@loopback/core");
const rest_1 = require("@loopback/rest");
const multer_1 = __importDefault(require("multer"));
const common_1 = require("../common");
let StaticAssetController = StaticAssetController_1 = class StaticAssetController {
constructor(application, response) {
this.application = application;
this.response = response;
this.logger = helpers_1.LoggerFactory.getLogger([StaticAssetController_1.name]);
this.temporaryStorage = multer_1.default.memoryStorage();
}
createBucket(bucketName) {
const minioInstance = this.application.getSync(common_1.ResourceAssetKeys.MINIO_INSTANCE);
return minioInstance.createBucket({ name: bucketName });
}
removeBucket(bucketName) {
const minioInstance = this.application.getSync(common_1.ResourceAssetKeys.MINIO_INSTANCE);
return minioInstance.removeBucket({ name: bucketName });
}
getBucket(bucketName) {
const minioInstance = this.application.getSync(common_1.ResourceAssetKeys.MINIO_INSTANCE);
return minioInstance.getBucket({ name: bucketName });
}
getBuckets() {
const minioInstance = this.application.getSync(common_1.ResourceAssetKeys.MINIO_INSTANCE);
return minioInstance.getBuckets();
}
uploadObject(request, bucketName, folderPath) {
const minioInstance = this.application.getSync(common_1.ResourceAssetKeys.MINIO_INSTANCE);
return new Promise((resolve, reject) => {
const extractor = (0, multer_1.default)({ storage: this.temporaryStorage }).array('files');
extractor(request, this.response, error => {
if (error) {
this.logger.error('[uploadObject] Fail to upload files! Error: %s', error);
reject(error);
}
if (folderPath) {
// Removes leading and trailing slashes
folderPath = folderPath.replace(/^\/|\/$/g, '');
}
const files = request.files;
const modifiedFiles = files.map(file => (Object.assign(Object.assign({}, file), { originalname: folderPath ? `${folderPath}/${file.originalname}` : file.originalname })));
minioInstance
.upload({ bucket: bucketName, files: modifiedFiles })
.then(rs => {
resolve(rs);
})
.catch(reject);
});
});
}
downloadObject(bucketName, objectName) {
const minioInstance = this.application.getSync(common_1.ResourceAssetKeys.MINIO_INSTANCE);
return new Promise(() => {
minioInstance.getStat({ bucket: bucketName, name: objectName }).then(fileStat => {
const { size, metaData } = fileStat;
this.response.set(Object.assign(Object.assign({}, metaData), { 'Content-Length': size, 'Content-Disposition': `attachment; filename=${objectName}` }));
minioInstance
.getFile({
bucket: bucketName,
name: objectName,
})
.then(stream => {
stream.pipe(this.response);
stream.on('end', () => {
this.response.end();
});
})
.catch(error => {
this.logger.error('[downloadObject] Error: %s', error);
throw (0, utilities_1.getError)({
message: `[downloadObject] Cannot download ${objectName}! Error while streaming data to client!`,
statusCode: 500,
});
});
});
});
}
getStaticObject(bucketName, objectName) {
const minioInstance = this.application.getSync(common_1.ResourceAssetKeys.MINIO_INSTANCE);
return new Promise(() => {
minioInstance.getStat({ bucket: bucketName, name: objectName }).then(fileStat => {
const { size, metaData } = fileStat;
this.response.writeHead(206, Object.assign(Object.assign({}, metaData), { 'Content-Type': 'application/octet-stream', 'Content-Length': size }));
minioInstance
.getFile({
bucket: bucketName,
name: objectName,
})
.then(stream => {
stream.pipe(this.response);
})
.catch(error => {
this.logger.error('[getStaticObject] Error: %s', error);
throw (0, utilities_1.getError)({
message: `[getStaticObject] Cannot stream ${objectName}! Error while streaming data to client!`,
statusCode: 500,
});
});
});
});
}
/**
* This method fetches the whole file from minio and streams it to the client.
* It's meant to be used for using file caching on browser.
* For other use cases, use `getStaticObject` instead.
*
* NOTE: By the time this method was written, Google Chrome cannot cache content
* if the response status code is 206 (Partial Content). So, we use 200 instead.
*/
fetchWholeFile(bucketName, objectName, cacheTime) {
return __awaiter(this, void 0, void 0, function* () {
var _a, e_1, _b, _c;
var _d;
const minioInstance = this.application.getSync(common_1.ResourceAssetKeys.MINIO_INSTANCE);
try {
const fileStat = yield minioInstance.getStat({
bucket: bucketName,
name: objectName,
});
const { size, metaData, lastModified } = fileStat;
const fileStream = yield minioInstance.getFile({
bucket: bucketName,
name: objectName,
});
const buffers = [];
try {
for (var _e = true, fileStream_1 = __asyncValues(fileStream), fileStream_1_1; fileStream_1_1 = yield fileStream_1.next(), _a = fileStream_1_1.done, !_a; _e = true) {
_c = fileStream_1_1.value;
_e = false;
const buffer = _c;
buffers.push(buffer);
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (!_e && !_a && (_b = fileStream_1.return)) yield _b.call(fileStream_1);
}
finally { if (e_1) throw e_1.error; }
}
const file = Buffer.concat(buffers);
this.response.writeHead(200, Object.assign(Object.assign({}, metaData), { 'Content-Length': size, 'Content-Type': (_d = metaData['content-type']) !== null && _d !== void 0 ? _d : metaData['mimetype'], 'Cache-Control': `private, max-age=${cacheTime !== null && cacheTime !== void 0 ? cacheTime : 60 * 60}`, 'Last-Modified': lastModified.toUTCString() }));
this.response.end(file);
}
catch (error) {
this.logger.error('[getWholeFile] Error %o', error);
throw (0, utilities_1.getError)({
statusCode: 500,
message: 'Error while fetching file',
});
}
});
}
deleteObjects(bucketName, payload, folderPath) {
return __awaiter(this, void 0, void 0, function* () {
const { objectNames } = payload;
const minioInstance = this.application.getSync(common_1.ResourceAssetKeys.MINIO_INSTANCE);
let deletingObjects = objectNames;
if (folderPath) {
folderPath = folderPath.replace(/^\/|\/$/g, '');
deletingObjects = objectNames.map(objectName => `${folderPath}/${objectName}`);
}
try {
yield minioInstance.client.removeObjects(bucketName, deletingObjects);
this.response.status(200).send({
message: 'Object deleted successfully',
});
}
catch (error) {
this.logger.error('[deleteObject] Error %o', error);
throw (0, utilities_1.getError)({
statusCode: 500,
message: 'Error while deleting object',
});
}
});
}
};
exports.StaticAssetController = StaticAssetController;
__decorate([
(0, rest_1.post)('/buckets/{bucket_name}', {
responses: {
'200': {
description: 'Create minio bucket with name',
content: { 'application/json': {} },
},
},
}),
__param(0, rest_1.param.path.string('bucket_name')),
__metadata("design:type", Function),
__metadata("design:paramtypes", [String]),
__metadata("design:returntype", void 0)
], StaticAssetController.prototype, "createBucket", null);
__decorate([
(0, rest_1.del)('/buckets/{bucket_name}', {
responses: {
'200': {
description: 'Delete minio bucket by name',
content: { 'application/json': {} },
},
},
}),
__param(0, rest_1.param.path.string('bucket_name')),
__metadata("design:type", Function),
__metadata("design:paramtypes", [String]),
__metadata("design:returntype", void 0)
], StaticAssetController.prototype, "removeBucket", null);
__decorate([
(0, rest_1.get)('/buckets/{bucket_name}', {
responses: {
'200': {
description: 'Get minio bucket by name',
content: { 'application/json': {} },
},
},
}),
__param(0, rest_1.param.path.string('bucket_name')),
__metadata("design:type", Function),
__metadata("design:paramtypes", [String]),
__metadata("design:returntype", void 0)
], StaticAssetController.prototype, "getBucket", null);
__decorate([
(0, rest_1.get)('/buckets', {
responses: {
'200': {
description: 'Get minio bucket by name',
content: { 'application/json': {} },
},
},
}),
__metadata("design:type", Function),
__metadata("design:paramtypes", []),
__metadata("design:returntype", void 0)
], StaticAssetController.prototype, "getBuckets", null);
__decorate([
(0, rest_1.post)('/buckets/{bucket_name}/upload', {
responses: {
'200': {
description: 'Upload files to bucket',
content: { 'application/json': {} },
},
},
}),
__param(0, (0, rest_1.requestBody)({
description: 'Upload files to minio',
required: true,
content: {
'multipart/form-data': {
'x-parser': 'stream',
schema: {
type: 'object',
properties: {
files: {
type: 'array',
items: {
type: 'string',
format: 'binary',
},
},
},
},
},
},
})),
__param(1, rest_1.param.path.string('bucket_name')),
__param(2, rest_1.param.query.string('folder_path')),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object, String, String]),
__metadata("design:returntype", void 0)
], StaticAssetController.prototype, "uploadObject", null);
__decorate([
(0, rest_1.get)('/{bucket_name}/{object_name}/download'),
__param(0, rest_1.param.path.string('bucket_name')),
__param(1, rest_1.param.path.string('object_name')),
__metadata("design:type", Function),
__metadata("design:paramtypes", [String, String]),
__metadata("design:returntype", void 0)
], StaticAssetController.prototype, "downloadObject", null);
__decorate([
(0, rest_1.get)('/{bucket_name}/{object_name}'),
__param(0, rest_1.param.path.string('bucket_name')),
__param(1, rest_1.param.path.string('object_name')),
__metadata("design:type", Function),
__metadata("design:paramtypes", [String, String]),
__metadata("design:returntype", void 0)
], StaticAssetController.prototype, "getStaticObject", null);
__decorate([
(0, rest_1.get)('/{bucket_name}/{object_name}/file'),
__param(0, rest_1.param.path.string('bucket_name')),
__param(1, rest_1.param.path.string('object_name')),
__param(2, rest_1.param.query.number('cache_time', { required: false })),
__metadata("design:type", Function),
__metadata("design:paramtypes", [String, String, Number]),
__metadata("design:returntype", Promise)
], StaticAssetController.prototype, "fetchWholeFile", null);
__decorate([
(0, rest_1.del)('/{bucket_name}/', {
description: 'Delete multiple objects from bucket',
responses: {
'200': {
description: 'Delete object',
content: {
'application/json': {
schema: {
type: 'object',
properties: {
message: {
type: 'string',
},
},
},
},
},
},
},
}),
__param(0, rest_1.param.path.string('bucket_name', { required: true })),
__param(1, (0, rest_1.requestBody)({
required: true,
content: {
'application/json': {
schema: {
type: 'object',
properties: {
objectNames: {
type: 'array',
items: {
type: 'string',
},
},
},
},
},
},
})),
__param(2, rest_1.param.query.string('folder_path', { required: false })),
__metadata("design:type", Function),
__metadata("design:paramtypes", [String, Object, String]),
__metadata("design:returntype", Promise)
], StaticAssetController.prototype, "deleteObjects", null);
exports.StaticAssetController = StaticAssetController = StaticAssetController_1 = __decorate([
(0, rest_1.api)({ basePath: '/static-assets' }),
__param(0, (0, core_1.inject)(core_1.CoreBindings.APPLICATION_INSTANCE)),
__param(1, (0, core_1.inject)(rest_1.RestBindings.Http.RESPONSE)),
__metadata("design:paramtypes", [applications_1.BaseApplication, Object])
], StaticAssetController);
//# sourceMappingURL=asset.controller.js.map