UNPKG

lynx-framework

Version:

lynx is a NodeJS framework for Web Development, based on decorators and the async/await support.

456 lines (454 loc) 31.7 kB
"use strict"; var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; return extendStatics(d, b); }; return function (d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); 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 __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 __generator = (this && this.__generator) || function (thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (_) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; Object.defineProperty(exports, "__esModule", { value: true }); var typeorm_1 = require("typeorm"); var base_entity_1 = require("./base.entity"); var user_entity_1 = require("./user.entity"); var Jimp = require("jimp"); var uuid_1 = require("uuid"); var uuid = uuid_1.v4; var app_1 = require("../app"); var fs = require("fs"); var mime_types_1 = require("mime-types"); var Media = /** @class */ (function (_super) { __extends(Media, _super); function Media() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.hiddenFields = ["owner", "_children", "children", "parent"]; return _this; } Media_1 = Media; Object.defineProperty(Media.prototype, "isDirectory", { get: function () { return this.is_directory == 1; }, set: function (value) { if (value) { this.is_directory = 1; } else { this.is_directory = 0; } }, enumerable: false, configurable: true }); Object.defineProperty(Media.prototype, "children", { get: function () { return Media_1.find({ where: { parent: this } }); }, enumerable: false, configurable: true }); Media.prototype.remove = function () { return __awaiter(this, void 0, void 0, function () { var _i, _a, child, k; return __generator(this, function (_b) { switch (_b.label) { case 0: if (!this.isDirectory) return [3 /*break*/, 6]; _i = 0; return [4 /*yield*/, this.children]; case 1: _a = _b.sent(); _b.label = 2; case 2: if (!(_i < _a.length)) return [3 /*break*/, 5]; child = _a[_i]; return [4 /*yield*/, child.remove()]; case 3: _b.sent(); _b.label = 4; case 4: _i++; return [3 /*break*/, 2]; case 5: return [2 /*return*/, _super.prototype.remove.call(this)]; case 6: return [4 /*yield*/, _super.prototype.remove.call(this)]; case 7: k = _b.sent(); app_1.app.config.ufs.unlink(this.path, function () { }); return [2 /*return*/, k]; } }); }); }; /** * Create a cropped image starting of the current. * The image will be placed in the same directory as the original. * @param config: The configuration object containing the crop parameters * @return a promise with the new @type Media */ Media.prototype.resizeToNewEntity = function (config) { return __awaiter(this, void 0, void 0, function () { var cachedPath, img, newFileName, path, newMedia, stat; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, app_1.app.config.ufs.getToCache(this.fileName, app_1.app.config.cachePath)]; case 1: cachedPath = _a.sent(); return [4 /*yield*/, Jimp.read(cachedPath)]; case 2: img = _a.sent(); return [4 /*yield*/, img.rotate(config.rotate)]; case 3: img = _a.sent(); return [4 /*yield*/, img.resize(img.getWidth() * Math.round(config.scaleX), img.getHeight() * Math.round(config.scaleY))]; case 4: img = _a.sent(); return [4 /*yield*/, img.crop(Math.round(config.x), Math.round(config.y), Math.round(config.width), Math.round(config.height))]; case 5: img = _a.sent(); newFileName = uuid(); path = app_1.app.config.cachePath; return [4 /*yield*/, img.writeAsync(path + "/" + newFileName)]; case 6: _a.sent(); return [4 /*yield*/, app_1.app.config.ufs.uploadFileFromCache(newFileName, path)]; case 7: _a.sent(); newMedia = new Media_1(); newMedia.isDirectory = false; newMedia.originalName = copiedName(this.originalName); newMedia.mimetype = this.mimetype; return [4 /*yield*/, app_1.app.config.ufs.stat(newFileName)]; case 8: stat = _a.sent(); newMedia.size = stat.size; newMedia.fileName = newFileName; newMedia.path = newFileName; newMedia.owner = this.owner; newMedia.parent = this.parent; newMedia.width = config.width; newMedia.height = config.height; return [4 /*yield*/, newMedia.save()]; case 9: return [2 /*return*/, _a.sent()]; } }); }); }; /** * Generate a new MediaEntity from an uploaded file using the Multer library * @param uploadMedia the multer File * @param user the user performing the request (aka the onwer of the file) * @param directory the (optional) virtual parent directory */ Media.persist = function (uploadMedia, user, directory) { return __awaiter(this, void 0, void 0, function () { var m, cachedPath, img, e_1; return __generator(this, function (_a) { switch (_a.label) { case 0: m = new Media_1(); return [4 /*yield*/, app_1.app.config.ufs.uploadFile(uploadMedia)]; case 1: uploadMedia = _a.sent(); m.originalName = uploadMedia.originalname; m.isDirectory = false; m.mimetype = uploadMedia.mimetype; m.size = uploadMedia.size; m.fileName = uploadMedia.filename; m.path = uploadMedia.path; m.owner = user; if (directory) { m.parent = directory; } return [4 /*yield*/, app_1.app.config.ufs.getToCache(m.fileName, app_1.app.config.cachePath)]; case 2: cachedPath = _a.sent(); if (!m.mimetype.startsWith('image')) return [3 /*break*/, 6]; _a.label = 3; case 3: _a.trys.push([3, 5, , 6]); return [4 /*yield*/, Jimp.read(cachedPath)]; case 4: img = _a.sent(); m.width = img.getWidth(); m.height = img.getHeight(); return [3 /*break*/, 6]; case 5: e_1 = _a.sent(); console.log("Error obtaining the metadata of the image."); console.log("Image path: " + uploadMedia.path); console.error(e_1); return [3 /*break*/, 6]; case 6: return [2 /*return*/, m.save()]; } }); }); }; /** * Generate a new MediaEntity from a local temporary file * @param originalName the original name of the file * @param path the temporary path of the file * @param user the user perfrming the request (aka the owner of the file) * @param directory the (optional) virtual parent directory */ Media.persistTempFile = function (originalName, path, user, directory) { return __awaiter(this, void 0, void 0, function () { var m, _a, uploadedFile; return __generator(this, function (_b) { switch (_b.label) { case 0: m = new Media_1(); m.originalName = originalName; m.isDirectory = false; m.mimetype = mime_types_1.lookup(path) || ''; _a = m; return [4 /*yield*/, stat(path)]; case 1: _a.size = (_b.sent()).size; return [4 /*yield*/, app_1.app.config.ufs.uploadTempFile(path)]; case 2: uploadedFile = _b.sent(); m.fileName = uploadedFile.fileName; m.path = uploadedFile.path; m.owner = user; if (directory) { m.parent = directory; } return [2 /*return*/, m.save()]; } }); }); }; Media.mkdir = function (name, user, directory) { return __awaiter(this, void 0, void 0, function () { var names, prev, i, n, where, m; return __generator(this, function (_a) { switch (_a.label) { case 0: names = normalizePath(name).split("/"); prev = directory; i = 0; _a.label = 1; case 1: if (!(i < names.length)) return [3 /*break*/, 6]; n = names[i]; if (!prev) { prev = null; } where = { where: { originalName: n, is_directory: 1, parent: prev } }; return [4 /*yield*/, Media_1.findOne(where)]; case 2: m = _a.sent(); if (!!m) return [3 /*break*/, 4]; m = new Media_1(); m.originalName = n; m.isDirectory = true; if (user) { m.owner = user; } if (prev) { m.parent = prev; } return [4 /*yield*/, m.save()]; case 3: _a.sent(); _a.label = 4; case 4: prev = m; _a.label = 5; case 5: i++; return [3 /*break*/, 1]; case 6: return [2 /*return*/, prev]; } }); }); }; Media.getFolder = function (path) { return __awaiter(this, void 0, void 0, function () { var names, prev, _i, names_1, n; return __generator(this, function (_a) { switch (_a.label) { case 0: names = normalizePath(path).split("/"); prev = null; _i = 0, names_1 = names; _a.label = 1; case 1: if (!(_i < names_1.length)) return [3 /*break*/, 4]; n = names_1[_i]; return [4 /*yield*/, Media_1.findOne({ where: { originalName: n, is_directory: 1, parent: prev } })]; case 2: prev = _a.sent(); if (!prev) { return [2 /*return*/, prev]; } _a.label = 3; case 3: _i++; return [3 /*break*/, 1]; case 4: return [2 /*return*/, prev]; } }); }); }; Media.findBySlug = function (slug) { return Media_1.findOne({ where: { slug: slug, is_directory: 0 } }); }; Media.findBySlugOrId = function (key) { return Media_1.getRepository() .createQueryBuilder("m") .where("m.slug = :slug AND is_directory = 0", { slug: key }) .orWhere("m.id = :id AND is_directory = 0", { id: key }) .getOne(); }; Media.findOneWithParent = function (id) { return Media_1.findOne({ where: { id: id }, relations: ["parent"] }); }; var Media_1; __decorate([ typeorm_1.PrimaryGeneratedColumn(), __metadata("design:type", Number) ], Media.prototype, "id", void 0); __decorate([ typeorm_1.Column(), __metadata("design:type", String) ], Media.prototype, "originalName", void 0); __decorate([ typeorm_1.Column({ unique: true, default: null }), __metadata("design:type", String) ], Media.prototype, "slug", void 0); __decorate([ typeorm_1.Column({ type: "smallint", default: 0 }), __metadata("design:type", Number) ], Media.prototype, "is_directory", void 0); __decorate([ typeorm_1.Column({ nullable: true }), __metadata("design:type", String) ], Media.prototype, "mimetype", void 0); __decorate([ typeorm_1.Column({ nullable: true }), __metadata("design:type", Number) ], Media.prototype, "size", void 0); __decorate([ typeorm_1.Column({ nullable: true }), __metadata("design:type", String) ], Media.prototype, "fileName", void 0); __decorate([ typeorm_1.Column({ nullable: true }), __metadata("design:type", String) ], Media.prototype, "path", void 0); __decorate([ typeorm_1.ManyToOne(function (_) { return Media_1; }, function (media) { return media._children; }), __metadata("design:type", Media) ], Media.prototype, "parent", void 0); __decorate([ typeorm_1.OneToMany(function (_) { return Media_1; }, function (media) { return media.parent; }), __metadata("design:type", Array) ], Media.prototype, "_children", void 0); __decorate([ typeorm_1.ManyToOne(function (_) { return user_entity_1.default; }, function (user) { return user.media; }, { eager: true }), __metadata("design:type", user_entity_1.default) ], Media.prototype, "owner", void 0); __decorate([ typeorm_1.Column({ nullable: true }), __metadata("design:type", Number) ], Media.prototype, "width", void 0); __decorate([ typeorm_1.Column({ nullable: true }), __metadata("design:type", Number) ], Media.prototype, "height", void 0); Media = Media_1 = __decorate([ typeorm_1.Entity("media") ], Media); return Media; }(base_entity_1.default)); exports.default = Media; function normalizePath(path) { if (path.startsWith("/")) { path = path.substring(1); } if (path.endsWith("/")) { path = path.substring(0, path.length - 1); } return path; } function copiedName(name) { var index = name.lastIndexOf("."); if (index == -1) { return name + " 1"; } return name.substring(0, index) + " 1" + name.substring(index); } function stat(path) { return new Promise(function (ok, fail) { fs.stat(path, function (err, info) { if (err) { return fail(err); } ok(info); }); }); } //# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL2x5bngvZW50aXRpZXMvbWVkaWEuZW50aXR5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLG1DQU1pQjtBQUNqQiw2Q0FBdUM7QUFDdkMsNkNBQWlDO0FBQ2pDLDJCQUE2QjtBQUM3Qiw2QkFBMEI7QUFDMUIsSUFBTSxJQUFJLEdBQUcsU0FBRSxDQUFDO0FBQ2hCLDhCQUE2QjtBQUU3Qix1QkFBeUI7QUFDekIseUNBQW9DO0FBYXBDO0lBQW1DLHlCQUFVO0lBQTdDO1FBQUEscUVBb09DO1FBbk9HLGtCQUFZLEdBQUcsQ0FBQyxPQUFPLEVBQUUsV0FBVyxFQUFFLFVBQVUsRUFBRSxRQUFRLENBQUMsQ0FBQzs7SUFtT2hFLENBQUM7Y0FwT29CLEtBQUs7SUFVdEIsc0JBQUksOEJBQVc7YUFBZjtZQUNJLE9BQU8sSUFBSSxDQUFDLFlBQVksSUFBSSxDQUFDLENBQUM7UUFDbEMsQ0FBQzthQUVELFVBQWdCLEtBQWM7WUFDMUIsSUFBSSxLQUFLLEVBQUU7Z0JBQ1AsSUFBSSxDQUFDLFlBQVksR0FBRyxDQUFDLENBQUM7YUFDekI7aUJBQU07Z0JBQ0gsSUFBSSxDQUFDLFlBQVksR0FBRyxDQUFDLENBQUM7YUFDekI7UUFDTCxDQUFDOzs7T0FSQTtJQTZCRCxzQkFBSSwyQkFBUTthQUFaO1lBQ0ksT0FBTyxPQUFLLENBQUMsSUFBSSxDQUFDLEVBQUUsS0FBSyxFQUFFLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxFQUFFLENBQUMsQ0FBQztRQUNuRCxDQUFDOzs7T0FBQTtJQUVLLHNCQUFNLEdBQVo7Ozs7Ozs2QkFDUSxJQUFJLENBQUMsV0FBVyxFQUFoQix3QkFBZ0I7OEJBQ3FCO3dCQUFuQixxQkFBTSxJQUFJLENBQUMsUUFBUSxFQUFBOzt3QkFBbkIsS0FBQSxTQUFtQjs7OzZCQUFuQixDQUFBLGNBQW1CLENBQUE7d0JBQTVCLEtBQUs7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LElBQUksS0FBSyxJQUFJLENBQUMsQ0FBQyxFQUFFO1FBQ2IsT0FBTyxJQUFJLEdBQUcsSUFBSSxDQUFDO0tBQ3RCO0lBQ0QsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsRUFBRSxLQUFLLENBQUMsR0FBRyxJQUFJLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUNuRSxDQUFDO0FBR0QsU0FBUyxJQUFJLENBQUMsSUFBWTtJQUN0QixPQUFPLElBQUksT0FBTyxDQUFDLFVBQUMsRUFBRSxFQUFFLElBQUk7UUFDeEIsRUFBRSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsVUFBQyxHQUFHLEVBQUUsSUFBSTtZQUNwQixJQUFJLEdBQUcsRUFBRTtnQkFDTCxPQUFPLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQzthQUNwQjtZQUNELEVBQUUsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNiLENBQUMsQ0FBQyxDQUFDO0lBQ1AsQ0FBQyxDQUFDLENBQUM7QUFDUCxDQUFDIiwiZmlsZSI6ImVudGl0aWVzL21lZGlhLmVudGl0eS5qcyIsInNvdXJjZVJvb3QiOiIuLiJ9