Skip to content

Commit

Permalink
Cloud storage for assets #256
Browse files Browse the repository at this point in the history
  • Loading branch information
treoden committed Nov 2, 2023
1 parent 9c95f6b commit 0d0a6bf
Show file tree
Hide file tree
Showing 8 changed files with 118 additions and 55 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ module.exports = async (request, response, delegate, next) => {
for (const imageFile of imageFiles) {
// Create a block blob client object that points to the blob where the image will be uploaded
const path = requestedPath
? `${requestedPath}/${imageFile.originalname}`
: `${imageFile.originalname}`;
? `${requestedPath}/${imageFile.filename}`
: `${imageFile.filename}`;
const blobClient = containerClient.getBlockBlobClient(path);

// Upload the image file to the blob
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ export default function CategoryInfo({
return (
<div className="page-width">
<div className="mb-1 md:mb-2 category__general">
<img src={image.url} alt={name} className="category__image" />
{image && (
<img src={image.url} alt={name} className="category__image" />
)}
<div className="category__info">
<div>
<h1 className="category__name">{name}</h1>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,19 @@
width: 100%;
height: 100%;
object-fit: cover;
min-height: 200px;
}
.category__info {
.category__image + .category__info {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
padding: 50px;
}
.category__info {
color: black;
display: flex;
align-items: center;
padding: 50px;
}
}
Original file line number Diff line number Diff line change
@@ -1,52 +1,9 @@
const { mkdirSync } = require('fs');
const { join } = require('path');
const multer = require('multer');
const { CONSTANTS } = require('@evershop/evershop/src/lib/helpers');
const {
INVALID_PAYLOAD
} = require('@evershop/evershop/src/lib/util/httpStatus');
const { getConfig } = require('@evershop/evershop/src/lib/util/getConfig');
const { getMulter } = require('../../services/getMulter');

const storage = multer.diskStorage({
destination(request, file, cb) {
const path = join(
CONSTANTS.MEDIAPATH,
(request.params[0] || '').replace(/\s/g, '-')
);
mkdirSync(path, { recursive: true });
cb(null, path);
},
filename(request, file, cb) {
let filename = file.originalname.replace(/\s/g, '-');
// Adding a random string to the filename to avoid conflict, keep the original extension
// eslint-disable-next-line no-param-reassign
filename = `${Date.now()}-${Math.random()
.toString(36)
.substring(2, 15)}-${filename}`;

cb(null, filename);
}
});

function fileFilter(request, file, cb) {
// Only accept images
if (!/\.(jpe?g|png|gif|webp)$/i.test(file.originalname)) {
cb(null, false);
} else {
cb(null, true);
}
}

const fileStorate = getConfig('file_storage', 'local');
let upload;
// Only ask multer to save the files to disk if the file storage is local
if (fileStorate === 'local') {
// eslint-disable-next-line no-unused-vars
upload = multer({ storage, fileFilter });
} else {
// eslint-disable-next-line no-unused-vars
upload = multer({ fileFilter });
}
const upload = getMulter();

module.exports = (request, response, delegate, next) => {
const path = request.params[0] || '';
Expand Down
37 changes: 37 additions & 0 deletions packages/evershop/src/modules/cms/services/CustomMemoryStorage.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/* eslint-disable no-underscore-dangle */
/* eslint-disable no-param-reassign */
const concat = require('concat-stream');

function CustomMemoryStorage(opts) {
this.getFilename = opts.filename;
}

CustomMemoryStorage.prototype._handleFile = function _handleFile(
req,
file,
cb
) {
const filename = this.getFilename(file.originalname);
file.stream.pipe(
concat({ encoding: 'buffer' }, (data) => {
cb(null, {
buffer: data,
size: data.length,
filename
});
})
);
};

CustomMemoryStorage.prototype._removeFile = function _removeFile(
req,
file,
cb
) {
delete file.buffer;
cb(null);
};

module.exports = function (opts) {
return new CustomMemoryStorage(opts);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
const path = require('path');

module.exports.generateFileName = (originalname) => {
const extension = path.extname(originalname);
const name = path.basename(originalname, extension);
// Replace special characters and white spaces with a -
const fileName = name.replace(/[^a-z0-9]/gi, '-').toLowerCase();
return `${fileName}${extension}`;
};
55 changes: 55 additions & 0 deletions packages/evershop/src/modules/cms/services/getMulter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
const { mkdirSync } = require('fs');
const { join } = require('path');
const multer = require('multer');
const { getConfig } = require('@evershop/evershop/src/lib/util/getConfig');
const { CONSTANTS } = require('@evershop/evershop/src/lib/helpers');
const { generateFileName } = require('./generateFileName');
const customMemoryStorage = require('./CustomMemoryStorage');

const filename = (request, file, cb) => {
const fileName = generateFileName(file.originalname);
cb(null, fileName);
};

function fileFilter(request, file, cb) {
const allowedMimeTypes = getConfig('allowed_mime_types', [
'image/jpeg',
'image/png',
'image/gif',
'image/webp',
'image/avif',
'image/apng'
]);
// Only accept images
if (!allowedMimeTypes.includes(file.mimetype)) {
return cb(
new Error(
"Only 'image/jpeg', 'image/png', 'image/gif', 'image/webp', 'image/avif', 'image/apng' files are allowed"
)
);
} else {
return cb(null, true);
}
}
const diskStorage = multer.diskStorage({
destination(request, file, cb) {
const path = join(
CONSTANTS.MEDIAPATH,
(request.params[0] || '').replace(/\s/g, '-')
);
mkdirSync(path, { recursive: true });
cb(null, path);
},
filename
});

module.exports.getMulter = () => {
const storageProvider = getConfig('file_storage', 'local');

if (storageProvider === 'local') {
return multer({ storage: diskStorage, fileFilter });
} else {
const memoryStorage = customMemoryStorage({ filename: generateFileName });
return multer({ storage: memoryStorage, fileFilter });
}
};
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ module.exports = async (request, response, delegate, next) => {
// eslint-disable-next-line no-restricted-syntax
for (const imageFile of imageFiles) {
const fileName = requestedPath
? `${requestedPath}/${imageFile.originalname}`
: imageFile.originalname;
? `${requestedPath}/${imageFile.filename}`
: imageFile.filename;
const fileContent = imageFile.buffer;
const params = {
Bucket: bucketName,
Expand All @@ -41,12 +41,12 @@ module.exports = async (request, response, delegate, next) => {
const uploadResults = await Promise.all(uploadPromises);
uploadResults.forEach((result, index) => {
uploadedFiles.push({
name: imageFiles[index].originalname,
path: path.join(requestedPath, imageFiles[index].originalname),
name: imageFiles[index].filename,
path: path.join(requestedPath, imageFiles[index].filename),
size: imageFiles[index].size,
url: `https://${bucketName}.s3.amazonaws.com/${path.join(
requestedPath,
encodeURIComponent(imageFiles[index].originalname)
imageFiles[index].filename
)}`
});
});
Expand Down

0 comments on commit 0d0a6bf

Please sign in to comment.