UNPKG

@coko/server

Version:

Reusable server for use by Coko's projects

136 lines 6.65 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.up = up; const path_1 = __importDefault(require("path")); const consumers_1 = require("stream/consumers"); const fs_extra_1 = __importDefault(require("fs-extra")); const mime_types_1 = __importDefault(require("mime-types")); const sharp_1 = __importDefault(require("sharp")); const lib_storage_1 = require("@aws-sdk/lib-storage"); const config_1 = __importDefault(require("../../../configManager/config")); const useTransaction_1 = __importDefault(require("../../useTransaction")); const file_model_1 = __importDefault(require("../file.model")); const filesystem_1 = require("../../../utils/filesystem"); const fileStorage_1 = __importDefault(require("../../../fileStorage")); /** * Some light duplication of code in this file, in order to keep it from being * a blocker for refactoring or other changes. * (eg. we made uploadFileHandler a private method, so it wouldn't be available here) */ const imageSizeConversionMapper = { tiff: { full: 'png', }, tif: { full: 'png', }, svg: { full: 'svg', }, png: { full: 'png', }, default: { full: 'jpeg', }, }; const getMetadata = async (fileBuffer) => { const originalImage = (0, sharp_1.default)(fileBuffer, { limitInputPixels: false }); const imageMetadata = await originalImage.metadata(); return imageMetadata; }; const sharpConversionFullFilePath = async (bufferData, tempFileDir, filenameWithoutExtension, format) => { await fs_extra_1.default.ensureDir(tempFileDir); const tempFullFilePath = path_1.default.join(tempFileDir, `${filenameWithoutExtension}_full.${imageSizeConversionMapper[format] ? imageSizeConversionMapper[format].full : imageSizeConversionMapper.default.full}`); await (0, sharp_1.default)(bufferData).toFile(tempFullFilePath); return tempFullFilePath; }; const uploadFileHandler = async (fileStream, filename, mimetype) => { const params = { Bucket: fileStorage_1.default.bucket, Key: filename, // file name you want to save as Body: fileStream, ContentType: mimetype, }; const upload = new lib_storage_1.Upload({ client: fileStorage_1.default.s3, params, }); // upload.on('httpUploadProgress', progress => { // console.log(progress) // }) const data = await upload.done(); const { Key } = data; return { key: Key }; }; async function up() { /** * If the app didn't use file storage before or after, this migration is unnecessary. * * If the app didn't use file storage before this migration, but started using * it after, this migration is unnecessary (new files will have a full quallity version). * * If the app used file storage before this migration, but stopped using it * before this migration, it is assumed that the files in file storage are * not used any more, so this migration will be skipped. * * There is an edge case where the app used file storage, stopped for a while, * in which period this migration ran, then started using it again, and the * files are still used. In this case this migration will need to be run manually. */ if (!config_1.default.get('fileStorage')) return; try { await (0, useTransaction_1.default)(async (trx) => { const files = await file_model_1.default.query(trx); const tempDir = filesystem_1.tempFolderPath; await fs_extra_1.default.ensureDir(tempDir); await Promise.all(files.map(async (file) => { const mimetype = mime_types_1.default.lookup(file.name); const fullStoredObject = file.storedObjects.find(storedObject => storedObject.type === 'full'); if (mimetype && mimetype.match(/^image\//) && !fullStoredObject) { const tempFileDir = path_1.default.join(tempDir, file.id); await fs_extra_1.default.ensureDir(tempFileDir); const originalStoredObject = file.storedObjects.find(storedObject => storedObject.type === 'original'); const filenameWithoutExtension = path_1.default.parse(originalStoredObject.key).name; const tempPath = path_1.default.join(tempFileDir, originalStoredObject.key); await fileStorage_1.default.download(originalStoredObject.key, tempPath); const format = originalStoredObject.extension; const bufferData = fs_extra_1.default.readFileSync(tempPath); const tempFullFilePath = await sharpConversionFullFilePath(bufferData, tempFileDir, filenameWithoutExtension, format); fs_extra_1.default.unlinkSync(tempPath); const fullImageStream = fs_extra_1.default.createReadStream(tempFullFilePath); const full = await uploadFileHandler(fs_extra_1.default.createReadStream(tempFullFilePath), path_1.default.basename(tempFullFilePath), mime_types_1.default.lookup(tempFullFilePath)); const fullFileBuffer = await (0, consumers_1.buffer)(fullImageStream); const { width: fWidth, height: fHeight, space: fSpace, density: fDensity, size: fSize, } = await getMetadata(fullFileBuffer); full.imageMetadata = { density: fDensity, height: fHeight, space: fSpace, width: fWidth, }; full.size = fSize; full.extension = path_1.default.extname(tempFullFilePath).slice(1); full.type = 'full'; full.mimetype = mime_types_1.default.lookup(tempFullFilePath); file.storedObjects.push(full); await file_model_1.default.query(trx).patchAndFetchById(file.id, { storedObjects: file.storedObjects, }); fs_extra_1.default.unlinkSync(tempFullFilePath); } })); await fs_extra_1.default.emptyDir(tempDir); return true; }); } catch (e) { throw new Error(`'File: Add full conversion image quality to stored objects migration failed!' ${e}`); } } //# sourceMappingURL=1698750314-add-full-quality-converted-object-to-storedobjects.js.map