mirror of
https://github.com/strapi/strapi.git
synced 2026-01-03 18:53:34 +00:00
migrate graphql upload to use streams + use fs-extra
This commit is contained in:
parent
186ebfd06e
commit
7cf2821451
@ -43,7 +43,7 @@
|
||||
"ci-info": "3.1.1",
|
||||
"commander": "7.1.0",
|
||||
"execa": "5.1.1",
|
||||
"fs-extra": "9.1.0",
|
||||
"fs-extra": "10.0.0",
|
||||
"inquirer": "8.2.0",
|
||||
"ora": "5.4.0"
|
||||
},
|
||||
|
||||
@ -72,7 +72,7 @@
|
||||
"fast-deep-equal": "3.1.3",
|
||||
"font-awesome": "^4.7.0",
|
||||
"formik": "^2.2.6",
|
||||
"fs-extra": "^9.1.0",
|
||||
"fs-extra": "10.0.0",
|
||||
"highlight.js": "^10.4.1",
|
||||
"history": "^4.9.0",
|
||||
"hoist-non-react-statics": "^3.3.0",
|
||||
|
||||
@ -31,7 +31,7 @@
|
||||
"@strapi/generators": "4.1.0",
|
||||
"@strapi/helper-plugin": "4.1.0",
|
||||
"@strapi/utils": "4.1.0",
|
||||
"fs-extra": "^9.1.0",
|
||||
"fs-extra": "10.0.0",
|
||||
"lodash": "4.17.21",
|
||||
"pluralize": "^8.0.0",
|
||||
"react": "^17.0.2",
|
||||
|
||||
@ -28,6 +28,7 @@
|
||||
"@strapi/utils": "4.1.0",
|
||||
"byte-size": "7.0.1",
|
||||
"cropperjs": "1.5.11",
|
||||
"fs-extra": "10.0.0",
|
||||
"immer": "9.0.6",
|
||||
"koa-range": "0.3.0",
|
||||
"koa-static": "5.0.0",
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
'use strict';
|
||||
|
||||
const fse = require('fs-extra');
|
||||
const _ = require('lodash');
|
||||
const { contentTypes: contentTypesUtils } = require('@strapi/utils');
|
||||
const { ApplicationError, NotFoundError, ForbiddenError } = require('@strapi/utils').errors;
|
||||
const rimraf = require('rimraf');
|
||||
const { getService } = require('../utils');
|
||||
const validateSettings = require('./validation/settings');
|
||||
const validateUploadBody = require('./validation/upload');
|
||||
@ -186,9 +186,9 @@ module.exports = {
|
||||
await (id ? this.replaceFile : this.uploadFiles)(ctx);
|
||||
} finally {
|
||||
if (Array.isArray(files)) {
|
||||
files.map(file => rimraf(file.path, () => {}));
|
||||
await Promise.all(files.map(file => fse.remove(file.path)));
|
||||
} else if (files.path) {
|
||||
rimraf(files.path, () => {});
|
||||
await fse.remove(files.path);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
'use strict';
|
||||
|
||||
const fse = require('fs-extra');
|
||||
const _ = require('lodash');
|
||||
const utils = require('@strapi/utils');
|
||||
const rimraf = require('rimraf');
|
||||
const { getService } = require('../utils');
|
||||
const validateSettings = require('./validation/settings');
|
||||
const validateUploadBody = require('./validation/upload');
|
||||
@ -138,9 +138,9 @@ module.exports = {
|
||||
await (id ? this.replaceFile : this.uploadFiles)(ctx);
|
||||
} finally {
|
||||
if (Array.isArray(files)) {
|
||||
files.map(file => rimraf(file.path, () => {}));
|
||||
await Promise.all(files.map(file => fse.remove(file.path)));
|
||||
} else if (files.path) {
|
||||
rimraf(files.path, () => {});
|
||||
await fse.remove(files.path);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@ -1,7 +1,9 @@
|
||||
'use strict';
|
||||
|
||||
const _ = require('lodash');
|
||||
const { streamToBuffer } = require('./utils/file');
|
||||
const path = require('path');
|
||||
const os = require('os');
|
||||
const fse = require('fs-extra');
|
||||
const { getStreamSize } = require('./utils/file');
|
||||
|
||||
const UPLOAD_MUTATION_NAME = 'upload';
|
||||
const MULTIPLE_UPLOAD_MUTATION_NAME = 'multipleUpload';
|
||||
@ -40,27 +42,23 @@ module.exports = ({ strapi }) => {
|
||||
* @param {object} metas
|
||||
* @return {Promise<object>}
|
||||
*/
|
||||
const formatFile = async (upload, extraInfo, metas) => {
|
||||
// ICI
|
||||
const formatFile = async (upload, extraInfo, metas, { tmpFolderPath }) => {
|
||||
const uploadService = getUploadService('upload');
|
||||
const { filename, mimetype, createReadStream } = await upload;
|
||||
|
||||
const readBuffer = await streamToBuffer(createReadStream());
|
||||
|
||||
const { buffer, info } = await optimize(readBuffer);
|
||||
|
||||
const uploadService = getUploadService('upload');
|
||||
|
||||
const fileInfo = uploadService.formatFileInfo(
|
||||
const currentFile = uploadService.formatFileInfo(
|
||||
{
|
||||
filename,
|
||||
type: mimetype,
|
||||
size: buffer.length,
|
||||
size: await getStreamSize(createReadStream()),
|
||||
},
|
||||
extraInfo || {},
|
||||
metas
|
||||
);
|
||||
currentFile.getStream = createReadStream;
|
||||
|
||||
return _.assign(fileInfo, info, { buffer });
|
||||
const newFile = await optimize(currentFile, { tmpFolderPath });
|
||||
return newFile;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -99,12 +97,29 @@ module.exports = ({ strapi }) => {
|
||||
},
|
||||
|
||||
async resolve(parent, args) {
|
||||
const { file: upload, info, ...fields } = args;
|
||||
// create temporary folder to store files for stream manipulation
|
||||
const tmpFolderPath = await fse.mkdtemp(path.join(os.tmpdir(), 'strapi-upload-'));
|
||||
let sanitizedEntity;
|
||||
|
||||
const file = await formatFile(upload, info, fields);
|
||||
const uploadedFile = await getUploadService('upload').uploadFileAndPersist(file);
|
||||
try {
|
||||
const { file: upload, info, ...fields } = args;
|
||||
|
||||
return toEntityResponse(uploadedFile, { args, resourceUID: fileTypeName });
|
||||
const file = await formatFile(upload, info, fields, { tmpFolderPath });
|
||||
const uploadedFile = await getUploadService('upload').uploadFileAndPersist(
|
||||
file,
|
||||
{},
|
||||
{ tmpFolderPath }
|
||||
);
|
||||
sanitizedEntity = await toEntityResponse(uploadedFile, {
|
||||
args,
|
||||
resourceUID: fileTypeName,
|
||||
});
|
||||
} finally {
|
||||
// delete temporary folder
|
||||
await fse.remove(tmpFolderPath);
|
||||
}
|
||||
|
||||
return sanitizedEntity;
|
||||
},
|
||||
});
|
||||
|
||||
@ -122,19 +137,32 @@ module.exports = ({ strapi }) => {
|
||||
},
|
||||
|
||||
async resolve(parent, args) {
|
||||
const { files: uploads, ...fields } = args;
|
||||
// create temporary folder to store files for stream manipulation
|
||||
const tmpFolderPath = await fse.mkdtemp(path.join(os.tmpdir(), 'strapi-upload-'));
|
||||
let sanitizedEntities = [];
|
||||
|
||||
const files = await Promise.all(uploads.map(upload => formatFile(upload, {}, fields)));
|
||||
try {
|
||||
const { files: uploads, ...fields } = args;
|
||||
|
||||
const uploadService = getUploadService('upload');
|
||||
const files = await Promise.all(
|
||||
uploads.map(upload => formatFile(upload, {}, fields, { tmpFolderPath }))
|
||||
);
|
||||
|
||||
const uploadedFiles = await Promise.all(
|
||||
files.map(file => uploadService.uploadFileAndPersist(file))
|
||||
);
|
||||
const uploadService = getUploadService('upload');
|
||||
|
||||
return uploadedFiles.map(file =>
|
||||
toEntityResponse(file, { args, resourceUID: fileTypeName })
|
||||
);
|
||||
const uploadedFiles = await Promise.all(
|
||||
files.map(file => uploadService.uploadFileAndPersist(file, {}, { tmpFolderPath }))
|
||||
);
|
||||
|
||||
sanitizedEntities = uploadedFiles.map(file =>
|
||||
toEntityResponse(file, { args, resourceUID: fileTypeName })
|
||||
);
|
||||
} finally {
|
||||
// delete temporary folder
|
||||
await fse.remove(tmpFolderPath);
|
||||
}
|
||||
|
||||
return sanitizedEntities;
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@ -6,12 +6,11 @@
|
||||
* @description: A set of functions similar to controller's actions to avoid code duplication.
|
||||
*/
|
||||
|
||||
const fs = require('fs');
|
||||
const os = require('os');
|
||||
const { mkdtemp } = require('fs').promises;
|
||||
const path = require('path');
|
||||
const crypto = require('crypto');
|
||||
const rimraf = require('rimraf');
|
||||
const fs = require('fs');
|
||||
const fse = require('fs-extra');
|
||||
const _ = require('lodash');
|
||||
const {
|
||||
sanitize,
|
||||
@ -109,7 +108,7 @@ module.exports = ({ strapi }) => ({
|
||||
|
||||
async upload({ data, files }, { user } = {}) {
|
||||
// create temporary folder to store files for stream manipulation
|
||||
const tmpFolderPath = await mkdtemp(path.join(os.tmpdir(), 'strapi-upload-'));
|
||||
const tmpFolderPath = await fse.mkdtemp(path.join(os.tmpdir(), 'strapi-upload-'));
|
||||
let uploadedFiles = [];
|
||||
|
||||
try {
|
||||
@ -129,7 +128,7 @@ module.exports = ({ strapi }) => ({
|
||||
);
|
||||
} finally {
|
||||
// delete temporary folder
|
||||
rimraf(tmpFolderPath, () => {});
|
||||
await fse.remove(tmpFolderPath);
|
||||
}
|
||||
|
||||
return uploadedFiles;
|
||||
|
||||
@ -17,7 +17,17 @@ const streamToBuffer = stream =>
|
||||
stream.on('error', reject);
|
||||
});
|
||||
|
||||
const getStreamSize = stream =>
|
||||
new Promise((resolve, reject) => {
|
||||
let size = 0;
|
||||
stream.on('data', chunk => (size += Buffer.byteLength(chunk)));
|
||||
stream.on('close', () => resolve(size));
|
||||
stream.on('error', reject);
|
||||
stream.resume();
|
||||
});
|
||||
|
||||
module.exports = {
|
||||
streamToBuffer,
|
||||
bytesToKbytes,
|
||||
getStreamSize,
|
||||
};
|
||||
|
||||
@ -39,7 +39,7 @@
|
||||
"@sentry/node": "6.3.0",
|
||||
"chalk": "^4.1.1",
|
||||
"execa": "^1.0.0",
|
||||
"fs-extra": "^9.1.0",
|
||||
"fs-extra": "10.0.0",
|
||||
"inquirer": "8.2.0",
|
||||
"lodash": "4.17.21",
|
||||
"node-fetch": "^2.6.1",
|
||||
|
||||
@ -28,7 +28,7 @@
|
||||
"@strapi/utils": "4.1.0",
|
||||
"bcryptjs": "2.4.3",
|
||||
"cheerio": "^1.0.0-rc.5",
|
||||
"fs-extra": "^9.1.0",
|
||||
"fs-extra": "10.0.0",
|
||||
"koa-static": "^5.0.0",
|
||||
"lodash": "4.17.21",
|
||||
"path-to-regexp": "6.2.0",
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user