mirror of
https://github.com/strapi/strapi.git
synced 2025-11-11 07:39:16 +00:00
Merge branch 'master' into chore/graphql-use-graphql-scalars
This commit is contained in:
commit
3a4372b397
@ -5,7 +5,7 @@
|
|||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"private": true,
|
"private": true,
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.16.7",
|
"@babel/core": "7.18.10",
|
||||||
"@babel/plugin-proposal-class-properties": "7.16.7",
|
"@babel/plugin-proposal-class-properties": "7.16.7",
|
||||||
"@babel/plugin-proposal-decorators": "7.16.7",
|
"@babel/plugin-proposal-decorators": "7.16.7",
|
||||||
"@babel/plugin-proposal-export-default-from": "7.16.7",
|
"@babel/plugin-proposal-export-default-from": "7.16.7",
|
||||||
@ -22,7 +22,7 @@
|
|||||||
"@babel/plugin-transform-parameters": "7.16.7",
|
"@babel/plugin-transform-parameters": "7.16.7",
|
||||||
"@babel/plugin-transform-shorthand-properties": "7.16.7",
|
"@babel/plugin-transform-shorthand-properties": "7.16.7",
|
||||||
"@babel/plugin-transform-spread": "7.16.7",
|
"@babel/plugin-transform-spread": "7.16.7",
|
||||||
"@babel/preset-env": "7.16.11",
|
"@babel/preset-env": "7.18.10",
|
||||||
"@babel/preset-typescript": "7.16.7",
|
"@babel/preset-typescript": "7.16.7",
|
||||||
"@storybook/addon-actions": "6.4.10",
|
"@storybook/addon-actions": "6.4.10",
|
||||||
"@storybook/addon-essentials": "6.4.10",
|
"@storybook/addon-essentials": "6.4.10",
|
||||||
|
|||||||
@ -37,12 +37,12 @@
|
|||||||
"test:front:watch:ce": "cross-env IS_EE=false jest --config ./jest.config.front.js --watchAll"
|
"test:front:watch:ce": "cross-env IS_EE=false jest --config ./jest.config.front.js --watchAll"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/core": "7.16.7",
|
"@babel/core": "7.18.10",
|
||||||
"@babel/plugin-transform-runtime": "7.16.7",
|
"@babel/plugin-transform-runtime": "7.18.10",
|
||||||
"@babel/polyfill": "7.12.1",
|
"@babel/polyfill": "7.12.1",
|
||||||
"@babel/preset-env": "7.16.7",
|
"@babel/preset-env": "7.18.10",
|
||||||
"@babel/preset-react": "7.18.6",
|
"@babel/preset-react": "7.18.6",
|
||||||
"@babel/runtime": "7.16.7",
|
"@babel/runtime": "7.18.9",
|
||||||
"@casl/ability": "^5.4.3",
|
"@casl/ability": "^5.4.3",
|
||||||
"@fingerprintjs/fingerprintjs": "3.3.3",
|
"@fingerprintjs/fingerprintjs": "3.3.3",
|
||||||
"@fortawesome/fontawesome-free": "^5.15.3",
|
"@fortawesome/fontawesome-free": "^5.15.3",
|
||||||
|
|||||||
@ -60,14 +60,14 @@
|
|||||||
"whatwg-fetch": "^3.6.2"
|
"whatwg-fetch": "^3.6.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "7.16.7",
|
"@babel/core": "7.18.10",
|
||||||
"@babel/plugin-proposal-class-properties": "7.16.7",
|
"@babel/plugin-proposal-class-properties": "7.16.7",
|
||||||
"@babel/plugin-proposal-export-default-from": "7.18.6",
|
"@babel/plugin-proposal-export-default-from": "7.18.6",
|
||||||
"@babel/plugin-proposal-function-bind": "7.18.8",
|
"@babel/plugin-proposal-function-bind": "7.18.8",
|
||||||
"@babel/plugin-transform-runtime": "7.16.7",
|
"@babel/plugin-transform-runtime": "7.18.10",
|
||||||
"@babel/preset-env": "7.16.7",
|
"@babel/preset-env": "7.18.10",
|
||||||
"@babel/preset-react": "7.18.6",
|
"@babel/preset-react": "7.18.6",
|
||||||
"@babel/runtime": "7.16.7",
|
"@babel/runtime": "7.18.9",
|
||||||
"@storybook/addon-actions": "6.4.10",
|
"@storybook/addon-actions": "6.4.10",
|
||||||
"@storybook/addon-essentials": "6.5.9",
|
"@storybook/addon-essentials": "6.5.9",
|
||||||
"@storybook/addon-links": "6.5.9",
|
"@storybook/addon-links": "6.5.9",
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const uploadService = require('../upload')({});
|
const uploadService = require('../../upload')({});
|
||||||
|
|
||||||
describe('Upload service', () => {
|
describe('Upload service', () => {
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
BIN
packages/core/upload/server/services/__tests__/upload/image.png
Normal file
BIN
packages/core/upload/server/services/__tests__/upload/image.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.5 KiB |
@ -0,0 +1,89 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const path = require('path');
|
||||||
|
const fs = require('fs');
|
||||||
|
const fse = require('fs-extra');
|
||||||
|
const _ = require('lodash');
|
||||||
|
const uploadService = require('../../upload')({});
|
||||||
|
|
||||||
|
const testFilePath = path.join(__dirname, './image.png');
|
||||||
|
const tmpWorkingDirectory = path.join(__dirname, './tmp');
|
||||||
|
|
||||||
|
function mockUploadProvider(uploadFunc, props) {
|
||||||
|
const { responsiveDimensions = false } = props || {};
|
||||||
|
|
||||||
|
const default_config = {
|
||||||
|
plugin: {
|
||||||
|
upload: {
|
||||||
|
breakpoints: {
|
||||||
|
large: 1000,
|
||||||
|
medium: 750,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
global.strapi = {
|
||||||
|
config: {
|
||||||
|
get: (path, defaultValue) => _.get(default_config, path, defaultValue),
|
||||||
|
},
|
||||||
|
plugins: {
|
||||||
|
upload: {
|
||||||
|
services: {
|
||||||
|
provider: {
|
||||||
|
upload: uploadFunc,
|
||||||
|
},
|
||||||
|
upload: {
|
||||||
|
getSettings: () => ({ responsiveDimensions }),
|
||||||
|
},
|
||||||
|
'image-manipulation': require('../../image-manipulation')(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const getFileData = () => ({
|
||||||
|
alternativeText: 'image.png',
|
||||||
|
caption: 'image.png',
|
||||||
|
ext: '.png',
|
||||||
|
folder: null,
|
||||||
|
folderPath: '/',
|
||||||
|
getStream: () => fs.createReadStream(testFilePath),
|
||||||
|
hash: 'image_d9b4f84424',
|
||||||
|
height: 1000,
|
||||||
|
size: 4,
|
||||||
|
width: 1500,
|
||||||
|
tmpWorkingDirectory,
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Upload image', () => {
|
||||||
|
beforeAll(async () => {
|
||||||
|
// Create tmp directory if it does not exist
|
||||||
|
await fse.mkdir(tmpWorkingDirectory);
|
||||||
|
});
|
||||||
|
|
||||||
|
afterAll(async () => {
|
||||||
|
// Remove tmp directory
|
||||||
|
await fse.remove(tmpWorkingDirectory);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Upload with thubmnail', async () => {
|
||||||
|
let fileData = getFileData();
|
||||||
|
const upload = jest.fn();
|
||||||
|
mockUploadProvider(upload);
|
||||||
|
|
||||||
|
await uploadService.uploadImage(fileData);
|
||||||
|
expect(upload).toHaveBeenCalledTimes(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Upload with responsive formats', async () => {
|
||||||
|
let fileData = getFileData();
|
||||||
|
const upload = jest.fn();
|
||||||
|
mockUploadProvider(upload, { responsiveDimensions: true });
|
||||||
|
|
||||||
|
await uploadService.uploadImage(fileData);
|
||||||
|
// 1 for the original image, 1 for thumbnail, 2 for the responsive formats
|
||||||
|
expect(upload).toHaveBeenCalledTimes(4);
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -159,50 +159,74 @@ module.exports = ({ strapi }) => ({
|
|||||||
return uploadedFiles;
|
return uploadedFiles;
|
||||||
},
|
},
|
||||||
|
|
||||||
async uploadFileAndPersist(fileData, { user } = {}) {
|
/**
|
||||||
const config = strapi.config.get('plugin.upload');
|
* When uploading an image, an additional thubmnail is generated.
|
||||||
|
* Also, if there are responsive formats defined, another set of images will be generated too.
|
||||||
|
*
|
||||||
|
* @param {*} fileData
|
||||||
|
*/
|
||||||
|
async uploadImage(fileData) {
|
||||||
const {
|
const {
|
||||||
getDimensions,
|
getDimensions,
|
||||||
generateThumbnail,
|
generateThumbnail,
|
||||||
generateResponsiveFormats,
|
generateResponsiveFormats,
|
||||||
isImage,
|
|
||||||
isOptimizableImage,
|
isOptimizableImage,
|
||||||
} = getService('image-manipulation');
|
} = getService('image-manipulation');
|
||||||
|
|
||||||
|
// Store width and height of the original image
|
||||||
|
const { width, height } = await getDimensions(fileData);
|
||||||
|
|
||||||
|
// Make sure this is assigned before calling upload
|
||||||
|
// That way it can mutate the width and height
|
||||||
|
_.assign(fileData, {
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Upload image
|
||||||
await getService('provider').upload(fileData);
|
await getService('provider').upload(fileData);
|
||||||
|
|
||||||
if (await isImage(fileData)) {
|
// Generate thumbnail and responsive formats
|
||||||
if (await isOptimizableImage(fileData)) {
|
if (await isOptimizableImage(fileData)) {
|
||||||
const thumbnailFile = await generateThumbnail(fileData);
|
const thumbnailFile = await generateThumbnail(fileData);
|
||||||
if (thumbnailFile) {
|
if (thumbnailFile) {
|
||||||
await getService('provider').upload(thumbnailFile);
|
await getService('provider').upload(thumbnailFile);
|
||||||
_.set(fileData, 'formats.thumbnail', thumbnailFile);
|
_.set(fileData, 'formats.thumbnail', thumbnailFile);
|
||||||
}
|
|
||||||
|
|
||||||
const formats = await generateResponsiveFormats(fileData);
|
|
||||||
if (Array.isArray(formats) && formats.length > 0) {
|
|
||||||
for (const format of formats) {
|
|
||||||
if (!format) continue;
|
|
||||||
|
|
||||||
const { key, file } = format;
|
|
||||||
|
|
||||||
await getService('provider').upload(file);
|
|
||||||
|
|
||||||
_.set(fileData, ['formats', key], file);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const { width, height } = await getDimensions(fileData);
|
const formats = await generateResponsiveFormats(fileData);
|
||||||
|
if (Array.isArray(formats) && formats.length > 0) {
|
||||||
|
for (const format of formats) {
|
||||||
|
if (!format) continue;
|
||||||
|
|
||||||
_.assign(fileData, {
|
const { key, file } = format;
|
||||||
width,
|
|
||||||
height,
|
await getService('provider').upload(file);
|
||||||
});
|
|
||||||
|
_.set(fileData, ['formats', key], file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Upload a file. If it is an image it will generate a thumbnail
|
||||||
|
* and responsive formats (if enabled).
|
||||||
|
*/
|
||||||
|
async uploadFileAndPersist(fileData, { user } = {}) {
|
||||||
|
const config = strapi.config.get('plugin.upload');
|
||||||
|
|
||||||
|
const { isImage } = getService('image-manipulation');
|
||||||
|
|
||||||
|
if (await isImage(fileData)) {
|
||||||
|
await this.uploadImage(fileData);
|
||||||
|
} else {
|
||||||
|
await getService('provider').upload(fileData);
|
||||||
}
|
}
|
||||||
|
|
||||||
_.set(fileData, 'provider', config.provider);
|
_.set(fileData, 'provider', config.provider);
|
||||||
|
|
||||||
|
// Persist file(s)
|
||||||
return this.add(fileData, { user });
|
return this.add(fileData, { user });
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -230,9 +254,7 @@ module.exports = ({ strapi }) => ({
|
|||||||
async replace(id, { data, file }, { user } = {}) {
|
async replace(id, { data, file }, { user } = {}) {
|
||||||
const config = strapi.config.get('plugin.upload');
|
const config = strapi.config.get('plugin.upload');
|
||||||
|
|
||||||
const { getDimensions, generateThumbnail, generateResponsiveFormats } = getService(
|
const { isImage } = getService('image-manipulation');
|
||||||
'image-manipulation'
|
|
||||||
);
|
|
||||||
|
|
||||||
const dbFile = await this.findOne(id);
|
const dbFile = await this.findOne(id);
|
||||||
if (!dbFile) {
|
if (!dbFile) {
|
||||||
@ -267,42 +289,15 @@ module.exports = ({ strapi }) => ({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
await getService('provider').upload(fileData);
|
|
||||||
|
|
||||||
// clear old formats
|
// clear old formats
|
||||||
_.set(fileData, 'formats', {});
|
_.set(fileData, 'formats', {});
|
||||||
|
|
||||||
const { isImage, isOptimizableImage } = getService('image-manipulation');
|
|
||||||
|
|
||||||
if (await isImage(fileData)) {
|
if (await isImage(fileData)) {
|
||||||
if (await isOptimizableImage(fileData)) {
|
await this.uploadImage(fileData);
|
||||||
const thumbnailFile = await generateThumbnail(fileData);
|
} else {
|
||||||
if (thumbnailFile) {
|
await getService('provider').upload(fileData);
|
||||||
await getService('provider').upload(thumbnailFile);
|
|
||||||
_.set(fileData, 'formats.thumbnail', thumbnailFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
const formats = await generateResponsiveFormats(fileData);
|
|
||||||
if (Array.isArray(formats) && formats.length > 0) {
|
|
||||||
for (const format of formats) {
|
|
||||||
if (!format) continue;
|
|
||||||
|
|
||||||
const { key, file } = format;
|
|
||||||
|
|
||||||
await getService('provider').upload(file);
|
|
||||||
|
|
||||||
_.set(fileData, ['formats', key], file);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const { width, height } = await getDimensions(fileData);
|
|
||||||
|
|
||||||
_.assign(fileData, {
|
|
||||||
width,
|
|
||||||
height,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_.set(fileData, 'provider', config.provider);
|
_.set(fileData, 'provider', config.provider);
|
||||||
} finally {
|
} finally {
|
||||||
// delete temporary folder
|
// delete temporary folder
|
||||||
|
|||||||
@ -19,15 +19,15 @@
|
|||||||
],
|
],
|
||||||
"main": "lib/index.js",
|
"main": "lib/index.js",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/cli": "7.16.7",
|
"@babel/cli": "7.18.10",
|
||||||
"@babel/core": "7.16.7",
|
"@babel/core": "7.18.10",
|
||||||
"@babel/generator": "7.18.7",
|
"@babel/generator": "7.18.7",
|
||||||
"@babel/parser": "7.18.6",
|
"@babel/parser": "7.18.10",
|
||||||
"@babel/plugin-syntax-dynamic-import": "7.8.3",
|
"@babel/plugin-syntax-dynamic-import": "7.8.3",
|
||||||
"@babel/plugin-transform-modules-commonjs": "7.18.6",
|
"@babel/plugin-transform-modules-commonjs": "7.18.6",
|
||||||
"@babel/plugin-transform-runtime": "7.16.7",
|
"@babel/plugin-transform-runtime": "7.18.10",
|
||||||
"@babel/preset-env": "7.16.7",
|
"@babel/preset-env": "7.18.10",
|
||||||
"@babel/template": "7.16.7",
|
"@babel/template": "7.18.10",
|
||||||
"reselect": "4.0.0",
|
"reselect": "4.0.0",
|
||||||
"resolve": "1.20.0"
|
"resolve": "1.20.0"
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user