mirror of
https://github.com/strapi/strapi.git
synced 2025-06-27 00:41:25 +00:00
chore: migrate media-library initial setup (#21375)
* chore: migrate and create config files for the migration * chore: migrate test utils to TS * chore: fix the typo * chore: fix eslint errors * chore: fix prettier error
This commit is contained in:
parent
55534e9466
commit
c7b2b2abcc
@ -7,7 +7,7 @@ As of September 2024 (and until this document is updated), only the v4.x.x and v
|
|||||||
**Note**: The v4.x.x LTS version will only receive high/critical severity fixes until April 2026. Any Medium/Low severity issues will not be fixed unless specific exceptions are made.
|
**Note**: The v4.x.x LTS version will only receive high/critical severity fixes until April 2026. Any Medium/Low severity issues will not be fixed unless specific exceptions are made.
|
||||||
|
|
||||||
| Version | Release Tag | Support Starts | Support Ends | Security Updates Until | Notes |
|
| Version | Release Tag | Support Starts | Support Ends | Security Updates Until | Notes |
|
||||||
|---------|-------------|----------------|----------------|------------------------|--------------------------------|
|
| ------- | ----------- | -------------- | -------------- | ---------------------- | ------------------------------ |
|
||||||
| 5.x.x | GA / Stable | September 2024 | Further Notice | Further Notice | LTS |
|
| 5.x.x | GA / Stable | September 2024 | Further Notice | Further Notice | LTS |
|
||||||
| 5.x.x | RC | N/A | September 2024 | N/A | Not Supported |
|
| 5.x.x | RC | N/A | September 2024 | N/A | Not Supported |
|
||||||
| 5.x.x | Beta | N/A | N/A | N/A | Not Supported |
|
| 5.x.x | Beta | N/A | N/A | N/A | Not Supported |
|
||||||
|
12
packages/core/upload/admin/.eslintrc
Normal file
12
packages/core/upload/admin/.eslintrc
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"root": true,
|
||||||
|
"overrides": [
|
||||||
|
{
|
||||||
|
"files": ["**/*.js", "**/*.jsx"],
|
||||||
|
"extends": ["custom/front"],
|
||||||
|
"rules": {
|
||||||
|
"import/extensions": "off"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@ -1,8 +1,7 @@
|
|||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
|
|
||||||
import { useQueryParams } from '@strapi/admin/strapi-admin';
|
import { useQueryParams } from '@strapi/admin/strapi-admin';
|
||||||
import { Loader } from '@strapi/design-system';
|
import { CrumbSimpleMenu, Loader, MenuItem } from '@strapi/design-system';
|
||||||
import { CrumbSimpleMenu, MenuItem } from '@strapi/design-system';
|
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { useIntl } from 'react-intl';
|
import { useIntl } from 'react-intl';
|
||||||
import { NavLink, useLocation } from 'react-router-dom';
|
import { NavLink, useLocation } from 'react-router-dom';
|
||||||
|
@ -19,7 +19,7 @@ const ComponentFixture = ({ to, ...props }) => {
|
|||||||
<FolderCard
|
<FolderCard
|
||||||
id={ID_FIXTURE}
|
id={ID_FIXTURE}
|
||||||
ariaLabel="Folder 1"
|
ariaLabel="Folder 1"
|
||||||
startAction={<></>}
|
startAction={null}
|
||||||
onClick={() => {}}
|
onClick={() => {}}
|
||||||
to={to}
|
to={to}
|
||||||
{...props}
|
{...props}
|
||||||
|
@ -5,7 +5,12 @@ import set from 'lodash/set';
|
|||||||
import { ON_CHANGE, SET_LOADED } from './actionTypes';
|
import { ON_CHANGE, SET_LOADED } from './actionTypes';
|
||||||
import { init, initialState } from './init';
|
import { init, initialState } from './init';
|
||||||
|
|
||||||
const reducer = (state = initialState, action) =>
|
const reducer = (
|
||||||
|
state = initialState,
|
||||||
|
action = {
|
||||||
|
type: '',
|
||||||
|
}
|
||||||
|
) =>
|
||||||
// eslint-disable-next-line consistent-return
|
// eslint-disable-next-line consistent-return
|
||||||
produce(state, (draftState) => {
|
produce(state, (draftState) => {
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
|
@ -6,6 +6,7 @@ import getTrad from './getTrad';
|
|||||||
export const urlSchema = yup.object().shape({
|
export const urlSchema = yup.object().shape({
|
||||||
urls: yup.string().test({
|
urls: yup.string().test({
|
||||||
name: 'isUrlValid',
|
name: 'isUrlValid',
|
||||||
|
// eslint-disable-next-line no-template-curly-in-string
|
||||||
message: '${path}',
|
message: '${path}',
|
||||||
test(values = '') {
|
test(values = '') {
|
||||||
const urls = values.split(/\r?\n/);
|
const urls = values.split(/\r?\n/);
|
||||||
|
@ -1,6 +1,13 @@
|
|||||||
import { rest } from 'msw';
|
import { rest } from 'msw';
|
||||||
import qs from 'qs';
|
import qs from 'qs';
|
||||||
|
|
||||||
|
// Define the expected structure of your query parameters
|
||||||
|
interface CustomQuery extends qs.ParsedQs {
|
||||||
|
filters?: {
|
||||||
|
$and?: Array<{ parent: { id: string } }>;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
const handlers = [
|
const handlers = [
|
||||||
rest.get('/upload/configuration', async (req, res, ctx) => {
|
rest.get('/upload/configuration', async (req, res, ctx) => {
|
||||||
return res(
|
return res(
|
||||||
@ -48,7 +55,7 @@ const handlers = [
|
|||||||
);
|
);
|
||||||
}),
|
}),
|
||||||
rest.get('/upload/folders', async (req, res, ctx) => {
|
rest.get('/upload/folders', async (req, res, ctx) => {
|
||||||
const query = qs.parse(req.url.search.slice(1));
|
const query: CustomQuery = qs.parse(req.url.search.slice(1));
|
||||||
|
|
||||||
if (query._q) {
|
if (query._q) {
|
||||||
return res(
|
return res(
|
||||||
@ -183,13 +190,13 @@ const handlers = [
|
|||||||
}),
|
}),
|
||||||
|
|
||||||
rest.get('*/an-image.png', (req, res, ctx) =>
|
rest.get('*/an-image.png', (req, res, ctx) =>
|
||||||
res(ctx.set('Content-Type', 'image/png'), ctx.body())
|
res(ctx.set('Content-Type', 'image/png'), ctx.body('Successful response'))
|
||||||
),
|
),
|
||||||
rest.get('*/a-pdf.pdf', (req, res, ctx) =>
|
rest.get('*/a-pdf.pdf', (req, res, ctx) =>
|
||||||
res(ctx.set('Content-Type', 'application/pdf'), ctx.body())
|
res(ctx.set('Content-Type', 'application/pdf'), ctx.body('Successful response'))
|
||||||
),
|
),
|
||||||
rest.get('*/a-video.mp4', (req, res, ctx) =>
|
rest.get('*/a-video.mp4', (req, res, ctx) =>
|
||||||
res(ctx.set('Content-Type', 'video/mp4'), ctx.body())
|
res(ctx.set('Content-Type', 'video/mp4'), ctx.body('Successful response'))
|
||||||
),
|
),
|
||||||
rest.get('*/not-working-like-cors.lutin', (req, res, ctx) => res(ctx.json({}))),
|
rest.get('*/not-working-like-cors.lutin', (req, res, ctx) => res(ctx.json({}))),
|
||||||
rest.get('*/some-where-not-existing.jpg', (req, res) => res.networkError('Failed to fetch')),
|
rest.get('*/some-where-not-existing.jpg', (req, res) => res.networkError('Failed to fetch')),
|
10
packages/core/upload/admin/tsconfig.build.json
Normal file
10
packages/core/upload/admin/tsconfig.build.json
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"extends": "tsconfig/client.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"rootDir": "../",
|
||||||
|
"baseUrl": ".",
|
||||||
|
"outDir": "./dist"
|
||||||
|
},
|
||||||
|
"include": ["./src", "../shared", "../package.json"],
|
||||||
|
"exclude": ["**/__mocks__", "./src/**/tests", "**/*.test.*"]
|
||||||
|
}
|
11
packages/core/upload/admin/tsconfig.json
Normal file
11
packages/core/upload/admin/tsconfig.json
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"extends": "tsconfig/client.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"rootDir": "../",
|
||||||
|
"baseUrl": ".",
|
||||||
|
"paths": {
|
||||||
|
"@tests/*": ["./tests/*"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"include": ["../package.json", "./src", "../shared", "./tests"]
|
||||||
|
}
|
@ -6,5 +6,5 @@ module.exports = {
|
|||||||
moduleNameMapper: {
|
moduleNameMapper: {
|
||||||
'^@tests/(.*)$': '<rootDir>/admin/tests/$1',
|
'^@tests/(.*)$': '<rootDir>/admin/tests/$1',
|
||||||
},
|
},
|
||||||
setupFilesAfterEnv: ['./admin/tests/setup.js'],
|
setupFilesAfterEnv: ['./admin/tests/setup.ts'],
|
||||||
};
|
};
|
||||||
|
@ -1,8 +0,0 @@
|
|||||||
{
|
|
||||||
"compilerOptions": {
|
|
||||||
"baseUrl": ".",
|
|
||||||
"paths": {
|
|
||||||
"@tests/*": ["./admin/tests/*"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -17,11 +17,19 @@
|
|||||||
],
|
],
|
||||||
"exports": {
|
"exports": {
|
||||||
"./strapi-admin": {
|
"./strapi-admin": {
|
||||||
|
"types": "./dist/admin/src/index.d.ts",
|
||||||
"source": "./admin/src/index.js",
|
"source": "./admin/src/index.js",
|
||||||
"import": "./dist/admin/index.mjs",
|
"import": "./dist/admin/index.mjs",
|
||||||
"require": "./dist/admin/index.js",
|
"require": "./dist/admin/index.js",
|
||||||
"default": "./dist/admin/index.js"
|
"default": "./dist/admin/index.js"
|
||||||
},
|
},
|
||||||
|
"./_internal/shared": {
|
||||||
|
"types": "./dist/shared/index.d.ts",
|
||||||
|
"source": "./shared/index.ts",
|
||||||
|
"import": "./dist/shared/index.mjs",
|
||||||
|
"require": "./dist/shared/index.js",
|
||||||
|
"default": "./dist/shared/index.js"
|
||||||
|
},
|
||||||
"./strapi-server": {
|
"./strapi-server": {
|
||||||
"types": "./dist/server/src/index.d.ts",
|
"types": "./dist/server/src/index.d.ts",
|
||||||
"source": "./server/src/index.ts",
|
"source": "./server/src/index.ts",
|
||||||
@ -41,6 +49,9 @@
|
|||||||
"lint": "run -T eslint .",
|
"lint": "run -T eslint .",
|
||||||
"test:front": "run -T cross-env IS_EE=true jest --config ./jest.config.front.js",
|
"test:front": "run -T cross-env IS_EE=true jest --config ./jest.config.front.js",
|
||||||
"test:unit": "run -T jest",
|
"test:unit": "run -T jest",
|
||||||
|
"test:ts:back": "run -T tsc --noEmit -p server/tsconfig.json",
|
||||||
|
"test:ts:front": "run -T tsc -p admin/tsconfig.json",
|
||||||
|
"test:front:watch": "run -T cross-env IS_EE=true jest --config ./jest.config.front.js --watch",
|
||||||
"test:unit:watch": "run -T jest --watch",
|
"test:unit:watch": "run -T jest --watch",
|
||||||
"watch": "pack-up watch"
|
"watch": "pack-up watch"
|
||||||
},
|
},
|
||||||
|
@ -3,9 +3,11 @@ import { Config, defineConfig } from '@strapi/pack-up';
|
|||||||
const config: Config = defineConfig({
|
const config: Config = defineConfig({
|
||||||
bundles: [
|
bundles: [
|
||||||
{
|
{
|
||||||
source: './admin/src/index.js',
|
types: './dist/admin/src/index.d.ts',
|
||||||
|
source: './admin/src/index.js', // TODO: change it with the .ts file
|
||||||
import: './dist/admin/index.mjs',
|
import: './dist/admin/index.mjs',
|
||||||
require: './dist/admin/index.js',
|
require: './dist/admin/index.js',
|
||||||
|
tsconfig: './admin/tsconfig.build.json',
|
||||||
runtime: 'web',
|
runtime: 'web',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -25,6 +25,7 @@ export async function bootstrap({ strapi }: { strapi: Core.Strapi }) {
|
|||||||
config &&
|
config &&
|
||||||
Object.keys(defaultValue).every((key) => Object.prototype.hasOwnProperty.call(config, key))
|
Object.keys(defaultValue).every((key) => Object.prototype.hasOwnProperty.call(config, key))
|
||||||
) {
|
) {
|
||||||
|
// eslint-disable-next-line no-continue
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ const validateStructureMoveManyFoldersFilesSchema = yup
|
|||||||
|
|
||||||
const validateDuplicatesMoveManyFoldersFilesSchema = yup
|
const validateDuplicatesMoveManyFoldersFilesSchema = yup
|
||||||
.object()
|
.object()
|
||||||
.test('are-folders-unique', 'some folders already exist', async function (value) {
|
.test('are-folders-unique', 'some folders already exist', async function areFoldersUnique(value) {
|
||||||
const { folderIds, destinationFolderId } = value;
|
const { folderIds, destinationFolderId } = value;
|
||||||
if (isEmpty(folderIds)) return true;
|
if (isEmpty(folderIds)) return true;
|
||||||
|
|
||||||
@ -58,7 +58,7 @@ const validateMoveFoldersNotInsideThemselvesSchema = yup
|
|||||||
.test(
|
.test(
|
||||||
'dont-move-inside-self',
|
'dont-move-inside-self',
|
||||||
'folders cannot be moved inside themselves or one of its children',
|
'folders cannot be moved inside themselves or one of its children',
|
||||||
async function (value) {
|
async function validateMoveFoldersNotInsideThemselves(value) {
|
||||||
const { folderIds, destinationFolderId } = value;
|
const { folderIds, destinationFolderId } = value;
|
||||||
if (destinationFolderId === null || isEmpty(folderIds)) return true;
|
if (destinationFolderId === null || isEmpty(folderIds)) return true;
|
||||||
|
|
||||||
|
@ -47,7 +47,7 @@ const getFileData = (filePath: string) => ({
|
|||||||
alternativeText: 'image.png',
|
alternativeText: 'image.png',
|
||||||
caption: 'image.png',
|
caption: 'image.png',
|
||||||
ext: '.png',
|
ext: '.png',
|
||||||
folder: null,
|
folder: undefined,
|
||||||
folderPath: '/',
|
folderPath: '/',
|
||||||
filepath: filePath,
|
filepath: filePath,
|
||||||
getStream: () => fs.createReadStream(filePath),
|
getStream: () => fs.createReadStream(filePath),
|
||||||
@ -56,6 +56,7 @@ const getFileData = (filePath: string) => ({
|
|||||||
size: 4,
|
size: 4,
|
||||||
width: 1500,
|
width: 1500,
|
||||||
tmpWorkingDirectory,
|
tmpWorkingDirectory,
|
||||||
|
name: 'image.png',
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Upload image', () => {
|
describe('Upload image', () => {
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
|
import type { UID } from '@strapi/types';
|
||||||
import { signEntityMedia } from '../utils';
|
import { signEntityMedia } from '../utils';
|
||||||
import { getService } from '../../../utils';
|
import { getService } from '../../../utils';
|
||||||
|
|
||||||
jest.mock('../../../utils');
|
jest.mock('../../../utils');
|
||||||
|
|
||||||
describe('Upload | extensions | entity-manager', () => {
|
describe('Upload | extensions | entity-manager', () => {
|
||||||
const modelUID = 'model';
|
const modelUID = 'model' as UID.Schema;
|
||||||
const componentUID = 'component';
|
const componentUID = 'component';
|
||||||
|
|
||||||
const models = {
|
const models = {
|
||||||
@ -71,6 +72,18 @@ describe('Upload | extensions | entity-manager', () => {
|
|||||||
spySignFileUrls = jest.fn();
|
spySignFileUrls = jest.fn();
|
||||||
jest.mocked(getService).mockImplementation(() => ({
|
jest.mocked(getService).mockImplementation(() => ({
|
||||||
signFileUrls: spySignFileUrls,
|
signFileUrls: spySignFileUrls,
|
||||||
|
getFolderPath: jest.fn(),
|
||||||
|
deleteByIds: jest.fn(),
|
||||||
|
computeMetrics: jest.fn().mockResolvedValue({
|
||||||
|
assetNumber: 0,
|
||||||
|
folderNumber: 0,
|
||||||
|
averageDepth: 0,
|
||||||
|
maxDepth: 0,
|
||||||
|
averageDeviationDepth: 0,
|
||||||
|
}),
|
||||||
|
sendMetrics: jest.fn().mockResolvedValue(undefined),
|
||||||
|
ensureWeeklyStoredCronSchedule: jest.fn().mockResolvedValue(undefined),
|
||||||
|
registerCron: jest.fn().mockResolvedValue(undefined),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
global.strapi = {
|
global.strapi = {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user