If anyone needs that, here is the solution that I implemented (based on strapi upload plugin code)
It works well in Strapi v4
const { Readable } = require("stream");
const getServiceUpload = (name) => {
return strapi.plugin("upload").service(name);
};
const uploadAndLinkDocument = async (buffer, {filename, extension, mimeType, refId, ref, field, user}) => {
const config = strapi.config.get("plugin.upload");
// add generated document
const entity = {
name,
hash: filename,
ext: extension,
mime: mimeType,
size: buffer.length,
provider: config.provider,
};
if (refId) {
entity.related = [
{
id: refId,
__type: ref,
__pivot: { field },
},
];
}
entity.getStream = () => Readable.from(buffer);
await getServiceUpload("provider").upload(entity);
const fileValues = { ...entity };
if (user) {
// created_by has a foreign key on admin_users. Here our user is a regular user, so it fails.
// uncomment this only if the user you pass to the function is a strapi admin.
/*fileValues[UPDATED_BY_ATTRIBUTE] = user.id;
fileValues[CREATED_BY_ATTRIBUTE] = user.id;*/
}
const res = await strapi
.query("plugin::upload.file")
.create({ data: fileValues });
return res;
};
ref is strapi reference to a model, like “api::model.model”
Hope this helps