141 lines
3.8 KiB
TypeScript
Raw Normal View History

2023-04-13 08:45:44 +02:00
import { pipeline } from 'stream';
import fs, { ReadStream } from 'fs';
import path from 'path';
import fse from 'fs-extra';
2023-06-26 17:24:32 +02:00
import * as utils from '@strapi/utils';
2023-04-13 08:45:44 +02:00
interface File {
name: string;
alternativeText?: string;
caption?: string;
width?: number;
height?: number;
formats?: Record<string, unknown>;
hash: string;
ext?: string;
mime: string;
size: number;
url: string;
previewUrl?: string;
path?: string;
provider?: string;
provider_metadata?: Record<string, unknown>;
stream?: ReadStream;
buffer?: Buffer;
}
const { PayloadTooLargeError } = utils.errors;
const { kbytesToBytes, bytesToHumanReadable } = utils.file;
2022-02-15 14:20:25 +01:00
const UPLOADS_FOLDER_NAME = 'uploads';
2023-04-13 08:45:44 +02:00
interface InitOptions {
sizeLimit?: number;
}
interface CheckFileSizeOptions {
sizeLimit?: number;
}
export default {
2023-04-13 08:45:44 +02:00
init({ sizeLimit: providerOptionsSizeLimit }: InitOptions = {}) {
// TODO V5: remove providerOptions sizeLimit
if (providerOptionsSizeLimit) {
process.emitWarning(
2023-04-13 08:45:44 +02:00
'[deprecated] In future versions, "sizeLimit" argument will be ignored from upload.config.providerOptions. Move it to upload.config'
);
}
2022-02-15 14:20:25 +01:00
// Ensure uploads folder exists
2022-03-14 17:54:35 +01:00
const uploadPath = path.resolve(strapi.dirs.static.public, UPLOADS_FOLDER_NAME);
if (!fse.pathExistsSync(uploadPath)) {
throw new Error(
`The upload folder (${uploadPath}) doesn't exist or is not accessible. Please make sure it exists.`
);
}
2018-02-20 17:10:25 +01:00
return {
2023-04-13 08:45:44 +02:00
checkFileSize(file: File, options: CheckFileSizeOptions) {
const { sizeLimit } = options ?? {};
// TODO V5: remove providerOptions sizeLimit
if (providerOptionsSizeLimit) {
2022-09-23 14:44:20 +02:00
if (kbytesToBytes(file.size) > providerOptionsSizeLimit)
throw new PayloadTooLargeError(
`${file.name} exceeds size limit of ${bytesToHumanReadable(
providerOptionsSizeLimit
)}.`
);
} else if (sizeLimit) {
2022-09-23 14:44:20 +02:00
if (kbytesToBytes(file.size) > sizeLimit)
throw new PayloadTooLargeError(
`${file.name} exceeds size limit of ${bytesToHumanReadable(sizeLimit)}.`
);
}
},
2023-04-13 08:45:44 +02:00
uploadStream(file: File): Promise<void> {
if (!file.stream) {
return Promise.reject(new Error('Missing file stream'));
}
const { stream } = file;
2022-01-04 19:21:05 +01:00
return new Promise((resolve, reject) => {
pipeline(
2023-04-13 08:45:44 +02:00
stream,
fs.createWriteStream(path.join(uploadPath, `${file.hash}${file.ext}`)),
2022-08-08 23:33:39 +02:00
(err) => {
2022-01-04 19:21:05 +01:00
if (err) {
return reject(err);
}
file.url = `/${UPLOADS_FOLDER_NAME}/${file.hash}${file.ext}`;
2022-01-04 19:21:05 +01:00
resolve();
}
);
});
},
2023-04-13 08:45:44 +02:00
upload(file: File): Promise<void> {
if (!file.buffer) {
return Promise.reject(new Error('Missing file buffer'));
}
const { buffer } = file;
2018-02-20 15:57:34 +01:00
return new Promise((resolve, reject) => {
2018-02-21 17:18:33 +01:00
// write file in public/assets folder
2023-04-13 08:45:44 +02:00
fs.writeFile(path.join(uploadPath, `${file.hash}${file.ext}`), buffer, (err) => {
2022-02-15 14:20:25 +01:00
if (err) {
return reject(err);
}
2018-02-20 15:57:34 +01:00
file.url = `/${UPLOADS_FOLDER_NAME}/${file.hash}${file.ext}`;
2018-02-20 15:57:34 +01:00
2022-02-15 14:20:25 +01:00
resolve();
});
2018-02-20 15:57:34 +01:00
});
},
2023-04-13 08:45:44 +02:00
delete(file: File): Promise<string | void> {
2018-02-20 15:57:34 +01:00
return new Promise((resolve, reject) => {
2022-02-21 11:59:30 +01:00
const filePath = path.join(uploadPath, `${file.hash}${file.ext}`);
2018-02-23 14:57:58 +01:00
if (!fs.existsSync(filePath)) {
2023-04-13 08:45:44 +02:00
resolve("File doesn't exist");
return;
2018-02-23 14:57:58 +01:00
}
2018-02-21 17:18:33 +01:00
// remove file from public/assets folder
2022-08-08 23:33:39 +02:00
fs.unlink(filePath, (err) => {
2018-02-20 15:57:34 +01:00
if (err) {
return reject(err);
}
resolve();
});
});
},
2018-02-20 15:57:34 +01:00
};
},
2018-02-20 15:57:34 +01:00
};