Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Image Service - Minor refinements #2558

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 23 additions & 29 deletions packages/images/src/adapter.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
const cloudinary = require('cloudinary');
const util = require('util');

function uploadStream(stream, options) {
return new Promise((resolve, reject) => {
const cloudinaryStream = cloudinary.v2.uploader.upload_stream(options, (error, result) => {
if (error) {
return reject(error);
}
resolve(result);
});
const uploader = {
delete: util.promisify(cloudinary.v2.uploader.destroy),
uploadStream: util.promisify(cloudinary.v2.uploader.upload_stream),
};

stream.pipe(cloudinaryStream);
});
async function uploadStream(stream, options) {
const cloudinaryStream = await uploader.uploadStream(options);
stream.pipe(cloudinaryStream);
}

module.exports = class CloudinaryAdapter {
Expand All @@ -27,21 +25,23 @@ module.exports = class CloudinaryAdapter {
/**
* Params: { stream, filename, mimetype, encoding, id }
*/
save({ stream, filename, id }) {
async save({ stream, filename, id }) {
// Push to cloudinary
return uploadStream(stream, {
const result = await uploadStream(stream, {
public_id: id,
folder: this.folder,
// Auth
api_key: this.apiKey,
api_secret: this.apiSecret,
cloud_name: this.cloudName,
}).then(result => ({
});

return {
// Return the relevant data for the File api
id,
filename,
_meta: result,
}));
};
}

/**
Expand All @@ -50,20 +50,12 @@ module.exports = class CloudinaryAdapter {
* @param options Delete options passed to cloudinary.
* For available options refer to the [Cloudinary destroy API](https://cloudinary.com/documentation/image_upload_api_reference#destroy_method).
*/
delete(file, options = {}) {
return new Promise((resolve, reject) => {
if (file) {
cloudinary.v2.uploader.destroy(file.id, options, (error, result) => {
if (error) {
reject(error);
} else {
resolve(result);
}
});
} else {
reject(new Error("Missing required argument 'file'."));
}
});
async delete(file, options = {}) {
if (!file) {
throw new Error('Missing required argument \'file\'.');
}

return uploader.destroy(file.id, options);
}

publicUrl({ _meta: { secure_url } = {} } = {}) {
Expand All @@ -76,10 +68,12 @@ module.exports = class CloudinaryAdapter {
}

const { prettyName, ...transformation } = options;

// No formatting options provided, return the publicUrl field
if (!Object.keys(transformation).length) {
if (Object.keys(transformation).length === 0) {
return this.publicUrl({ _meta });
}

const { public_id, format } = _meta;

// Docs: https://github.com/cloudinary/cloudinary_npm/blob/439586eac73cee7f2803cf19f885e98f237183b3/src/utils.coffee#L472 (LOL)
Expand Down
28 changes: 14 additions & 14 deletions packages/images/src/service.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ export class ImageService {

this.app.get('/image/:filename', async (req, res) => {
const { filename } = req.params;
const [id, format] = filename.split('.');
const { name: id, ext: format } = nodePath.parse(filename);

if (!id || !format) {
return res.status(404).send('Not Found (Invalid Filename)');
Expand All @@ -93,10 +93,10 @@ export class ImageService {
return res.status(404).send('Not Found (No Matching Image)');
}

const originalPath = nodePath.join(this.sourcePath, `${id}.${data.format}`);
const originalPath = nodePath.join(this.sourcePath, `${id}${data.format}`);
const resizeOptions = processResizeOptions(req.query);

if (!resizeOptions && format === data.format) {
if (!resizeOptions && format === `.${data.format}`) {
return res.sendFile(originalPath);
}

Expand All @@ -114,7 +114,7 @@ export class ImageService {
suffix = `-${hash}`;
}

let transformedFilename = nodePath.join(this.transformsPath, `${id}${suffix}.${format}`);
let transformedFilename = nodePath.join(this.transformsPath, `${id}${suffix}${format}`);

if (!(await fs.exists(transformedFilename))) {
try {
Expand All @@ -129,7 +129,7 @@ export class ImageService {
}
}

res.sendFile(transformedFilename);
return res.sendFile(transformedFilename);
});

this.app.get('/image/:id/meta', async (req, res) => {
Expand All @@ -148,18 +148,18 @@ export class ImageService {
});
}
getSrc(id, { format, resize = {} }) {
let url = `${this.protocol}://${this.host}:${this.port}/image/${id}.${format}`;

const url = `${this.protocol}://${this.host}:${this.port}/image/${id}.${format}`;
const searchParams = new URLSearchParams();
for (let key in resize) {
searchParams.set(key, resize[key]);
}

const stringifiedSearchParams = searchParams.toString();
if (stringifiedSearchParams) {
url += `?${stringifiedSearchParams}`;
for (const [param, value] of Object.entries(resize)) {
searchParams.set(param, value);
}
return url;

const queryString = searchParams.toString();

return queryString
? `${url}?${queryString}`
: url;
}
async uploadImage({ stream, originalname }) {
const id = uuid();
Expand Down