Can someone help me with instructions to set up a custom storage adapter in Ghost?
I am running a custom server created with ghost-cli with the latest version. I followed the instructions to a T from the ghost docs, but they are outdated and cause errors when booting the ghost server after updating the configuration. Furthermore, all of the custom adapters, including the recommended S3 one that can be installed via npm, are not working. I really think the best approach here is to just find a working solution and build from there, but even the most basic implementations fail satisfy javascript importing requirements.
Here is my storage adapter code:
const BaseAdapter = require("ghost-storage-base");
const AWS = require('aws-sdk');
const { v4: uuidv4 } = require('uuid');
const path = require('path');
const mime = require('mime-types');
class S3CustomAdapter extends BaseAdapter {
constructor(config) {
super();
this.s3 = new AWS.S3({
accessKeyId: config.key,
secretAccessKey: config.secret,
region: config.region,
});
this.bucket = config.bucket;
}
save(image) {
return new Promise((resolve, reject) => {
const fileName = `${uuidv4()}${path.extname(image.name)}`;
const params = {
Bucket: this.bucket,
Key: fileName,
Body: image.stream,
ContentType: mime.lookup(image.name),
ACL: 'public-read',
};
this.s3.upload(params, (err, data) => {
if (err) {
return reject(err);
}
resolve(data.Location);
});
});
}
exists(fileName) {
const params = {
Bucket: this.bucket,
Key: fileName,
};
return this.s3
.headObject(params)
.promise()
.then(() => true)
.catch((err) => {
if (err.code === 'NotFound') {
return false;
}
throw err;
});
}
serve() {
return (req, res, next) => {
const fileName = req.path.replace(/^\//, '');
const params = {
Bucket: this.bucket,
Key: fileName,
};
this.s3.getObject(params)
.createReadStream()
.on('error', (err) => {
if (err.code === 'NoSuchKey') {
return res.status(404).end();
}
next(err);
})
.pipe(res);
};
}
delete(fileName) {
const params = {
Bucket: this.bucket,
Key: fileName,
};
return this.s3
.deleteObject(params)
.promise()
.then(() => true)
.catch((err) => {
if (err.code === 'NoSuchKey') {
return false;
}
throw err;
});
}
read(fileName) {
const params = {
Bucket: this.bucket,
Key: fileName,
};
return this.s3
.getObject(params)
.promise()
.then((data) => data.Body)
.catch((err) => {
if (err.code === 'NoSuchKey') {
return null;
}
throw err;
});
}
}
module.exports = S3CustomAdapter;
If this is no longer supported I think it would be greatly appreciated it if the community were made aware.
Thanks!